121 lines
3.9 KiB
Go
121 lines
3.9 KiB
Go
package gameserver
|
|
|
|
import (
|
|
"fmt"
|
|
"gac-hkrpg-go/internal/common"
|
|
pb "gac-hkrpg-go/protocol/proto"
|
|
"google.golang.org/protobuf/proto"
|
|
"maps"
|
|
"sort"
|
|
)
|
|
|
|
// Basic identical-role merge, following the captured remove/add sync. Existing
|
|
// equipment stays in the bag; only the retained role's attachment list moves.
|
|
// Switch-role groups and Spotlight star locks need their separately mapped rules.
|
|
func cwMergeRoles(c *common.CurrencyWarsCatalog, run *pb.MPIMAEMCEFH, preferred uint32) ([]*pb.ABPLALCHNFA, error) {
|
|
_, team, _ := cwComponents(run)
|
|
if team == nil {
|
|
return nil, fmt.Errorf("CW team missing")
|
|
}
|
|
rules, e := c.MergeRules()
|
|
if e != nil {
|
|
return nil, e
|
|
}
|
|
front, e := c.IntegerRule("GridFight_Front_AvatarMaxNum")
|
|
if e != nil {
|
|
return nil, e
|
|
}
|
|
back, e := c.IntegerRule("GridFight_Back_AvatarMaxNum")
|
|
if e != nil {
|
|
return nil, e
|
|
}
|
|
active := func(r *pb.CDEAABODKCP) bool { return r.Pos > 0 && uint64(r.Pos) <= uint64(front+back) }
|
|
better := func(a, b *pb.CDEAABODKCP) bool {
|
|
if active(a) != active(b) {
|
|
return active(a)
|
|
}
|
|
if len(a.PNJIPHJJONG) != len(b.PNJIPHJJONG) {
|
|
return len(a.PNJIPHJJONG) > len(b.PNJIPHJJONG)
|
|
}
|
|
return a.UniqueId < b.UniqueId
|
|
}
|
|
var groups []*pb.ABPLALCHNFA
|
|
for {
|
|
candidates := map[[2]uint32][]*pb.CDEAABODKCP{}
|
|
for _, r := range team.GridGameRoleList {
|
|
if r.RoleStar < rules.OrdinaryMaxStar {
|
|
key := [2]uint32{r.Id, r.RoleStar}
|
|
candidates[key] = append(candidates[key], r)
|
|
}
|
|
}
|
|
keys := make([][2]uint32, 0, len(candidates))
|
|
for k, v := range candidates {
|
|
if len(v) >= int(rules.Copies) {
|
|
keys = append(keys, k)
|
|
}
|
|
}
|
|
sort.Slice(keys, func(i, j int) bool {
|
|
if keys[i][1] != keys[j][1] {
|
|
return keys[i][1] < keys[j][1]
|
|
}
|
|
return keys[i][0] < keys[j][0]
|
|
})
|
|
var selected []*pb.CDEAABODKCP
|
|
for _, key := range keys {
|
|
if _, err := c.CapturedRoleVariant(key[0], key[1]+1); err != nil {
|
|
continue
|
|
}
|
|
selected = candidates[key]
|
|
sort.Slice(selected, func(i, j int) bool {
|
|
if (selected[i].UniqueId == preferred) != (selected[j].UniqueId == preferred) {
|
|
return selected[i].UniqueId == preferred
|
|
}
|
|
return better(selected[i], selected[j])
|
|
})
|
|
selected = selected[:int(rules.Copies)]
|
|
break
|
|
}
|
|
if len(selected) == 0 {
|
|
return groups, nil
|
|
}
|
|
sort.Slice(selected, func(i, j int) bool { return better(selected[i], selected[j]) })
|
|
anchor := selected[0]
|
|
for _, r := range selected {
|
|
if !maps.Equal(anchor.ConvertPropertyToFixpoint, r.ConvertPropertyToFixpoint) || !maps.Equal(anchor.BABNHPDGNGB, r.BABNHPDGNGB) || !maps.Equal(anchor.GridFightValueInitComponent, r.GridFightValueInitComponent) {
|
|
return nil, fmt.Errorf("CW merge role modifiers need an explicit transfer rule")
|
|
}
|
|
}
|
|
id, err := cwNextEntityID(run)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
merged := proto.Clone(anchor).(*pb.CDEAABODKCP)
|
|
merged.UniqueId = id
|
|
merged.RoleStar++
|
|
removed := map[uint32]bool{}
|
|
group := &pb.ABPLALCHNFA{GridUpdateSrc: pb.JJDFGMMMCMI_JJDFGMMMCMI_NJBMBFFLNGM}
|
|
for _, r := range selected {
|
|
removed[r.UniqueId] = true
|
|
group.JKPJFKCBIEM = append(group.JKPJFKCBIEM, &pb.KFNCAIHIHCM{MNLCHEJKDHO: &pb.KFNCAIHIHCM_HFCBOIOAECK{HFCBOIOAECK: r.UniqueId}})
|
|
}
|
|
kept := make([]*pb.CDEAABODKCP, 0, len(team.GridGameRoleList)-len(selected)+1)
|
|
for _, r := range team.GridGameRoleList {
|
|
if !removed[r.UniqueId] {
|
|
kept = append(kept, r)
|
|
}
|
|
}
|
|
team.GridGameRoleList = append(kept, merged)
|
|
group.JKPJFKCBIEM = append(group.JKPJFKCBIEM, &pb.KFNCAIHIHCM{MNLCHEJKDHO: &pb.KFNCAIHIHCM_PIDDDHKPDDM{PIDDDHKPDDM: proto.Clone(merged).(*pb.CDEAABODKCP)}})
|
|
if state := cwSpotlights(run); state != nil {
|
|
for _, binding := range state.FNNEPMAPOOF {
|
|
if removed[binding.MDNAGANGNKK] {
|
|
binding.MDNAGANGNKK = merged.UniqueId
|
|
group.JKPJFKCBIEM = append(group.JKPJFKCBIEM, &pb.KFNCAIHIHCM{MNLCHEJKDHO: &pb.KFNCAIHIHCM_OHHBBOGFDON{OHHBBOGFDON: proto.Clone(binding).(*pb.FMBACDOFCAL)}})
|
|
}
|
|
}
|
|
}
|
|
groups = append(groups, group)
|
|
preferred = id
|
|
}
|
|
}
|