feat(currency_wars): complete systems, settlement Rank SS, damage report, camera and recovery fixes
This commit is contained in:
1 parent
c008243f11
commit
0995055296
78 files changed
+33840
-9525
No files matched your search
@@ -1,9 +1,14 @@
|
||||
package gameserver
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"math"
|
||||
"math/big"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"gac-hkrpg-go/internal/common"
|
||||
pb "gac-hkrpg-go/protocol/proto"
|
||||
@@ -45,10 +50,16 @@ func cwNodeTransitions(c *common.CurrencyWarsCatalog) ([]cwNodeTransition, error
|
||||
return r.Entries, nil
|
||||
}
|
||||
func cwStage(run *pb.MPIMAEMCEFH) (*pb.BEEFLEJAOCN, *pb.OHMDHKGAEMM) {
|
||||
if run == nil {
|
||||
return nil, nil
|
||||
}
|
||||
for _, c := range run.NAGDJGMMCBE {
|
||||
if c == nil {
|
||||
continue
|
||||
}
|
||||
if s := c.GetKLCPAAHDPJF(); s != nil {
|
||||
for _, n := range s.OOMMIIKPHBC {
|
||||
if n.SectionId == s.SectionId && n.DCAHJELNJNP == s.DCAHJELNJNP {
|
||||
if n != nil && n.SectionId == s.SectionId && n.DCAHJELNJNP == s.DCAHJELNJNP {
|
||||
return s, n.DisplayValue
|
||||
}
|
||||
}
|
||||
@@ -58,6 +69,102 @@ func cwStage(run *pb.MPIMAEMCEFH) (*pb.BEEFLEJAOCN, *pb.OHMDHKGAEMM) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func cwRollNodeOrbs(catalog *common.CurrencyWarsCatalog, run *pb.MPIMAEMCEFH, routeID, chapter, section, progress uint32) ([]uint32, error) {
|
||||
route, err := catalog.RouteNodes(routeID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
refNodes, err := common.LoadCurrencyWarsReferenceNodes(catalog)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var template common.CurrencyWarsReferenceNodeTemplate
|
||||
found := false
|
||||
for _, r := range route {
|
||||
if r.ChapterID == chapter && r.SectionID == section {
|
||||
t, err := refNodes.Template(r.NodeTemplateID)
|
||||
if err == nil {
|
||||
template = t
|
||||
found = true
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
if !found || len(template.ParamList) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
nodeDropsCat, err := common.LoadCurrencyWarsNodeDrops(catalog)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
dropKey := strconv.FormatUint(uint64(template.ParamList[0]), 10)
|
||||
drop, ok := nodeDropsCat.NodeDrops[dropKey]
|
||||
if !ok || len(drop.Weights) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
recipes, err := common.LoadCurrencyWarsOrbRecipes()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
supported := map[uint32]bool{}
|
||||
for _, recipe := range recipes.Recipes {
|
||||
if recipe.Status == "Implemented" && recipe.Engine == "Orb" {
|
||||
supported[recipe.ID] = true
|
||||
}
|
||||
}
|
||||
|
||||
type weightEntry struct {
|
||||
id uint32
|
||||
weight uint32
|
||||
}
|
||||
var entries []weightEntry
|
||||
var totalWeight uint32
|
||||
for k, w := range drop.Weights {
|
||||
id64, err := strconv.ParseUint(k, 10, 32)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
id := uint32(id64)
|
||||
if supported[id] && w > 0 {
|
||||
entries = append(entries, weightEntry{id: id, weight: w})
|
||||
totalWeight += w
|
||||
}
|
||||
}
|
||||
if totalWeight == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
sort.Slice(entries, func(i, j int) bool {
|
||||
return entries[i].id < entries[j].id
|
||||
})
|
||||
|
||||
percent := progress
|
||||
if percent > 100 {
|
||||
percent = 100
|
||||
}
|
||||
count := (drop.Rolls*percent + 99) / 100
|
||||
|
||||
var rolled []uint32
|
||||
for i := uint32(0); i < count; i++ {
|
||||
rBig, err := rand.Int(rand.Reader, big.NewInt(int64(totalWeight)))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
roll := uint32(rBig.Int64())
|
||||
for _, e := range entries {
|
||||
if roll < e.weight {
|
||||
rolled = append(rolled, e.id)
|
||||
break
|
||||
}
|
||||
roll -= e.weight
|
||||
}
|
||||
}
|
||||
return rolled, nil
|
||||
}
|
||||
|
||||
func finishCurrencyWarsBattle(s *Session, req *pb.PVEBattleResultCsReq, current *pb.SceneBattleInfo) error {
|
||||
if current == nil || req.BattleId != current.BattleId || req.StageId != current.StageId {
|
||||
return fmt.Errorf("CW battle identity differs")
|
||||
@@ -216,55 +323,67 @@ func finishCurrencyWarsBattle(s *Session, req *pb.PVEBattleResultCsReq, current
|
||||
loseHP(basicLoss, pb.DFIJIBKBEJL_DFIJIBKBEJL_FDKCPHMMFCD)
|
||||
loseHP(progressLoss, pb.DFIJIBKBEJL_DFIJIBKBEJL_IEGEHAKDEHA)
|
||||
loseHP(thresholdLoss, pb.DFIJIBKBEJL_DFIJIBKBEJL_KEOPICGMGPI)
|
||||
if player.GridFightLineupHp == 0 {
|
||||
return fmt.Errorf("CW defeat settlement requires terminal-run handler")
|
||||
}
|
||||
isDefeat := (player.GridFightLineupHp == 0)
|
||||
kind, err := catalog.NodeTypeName(node.CJCCMAACJDB)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, name := range rules.StreakNodes {
|
||||
if name == kind {
|
||||
if perfect {
|
||||
if player.GDAKCOICIDA == math.MaxUint32 {
|
||||
return fmt.Errorf("CW streak overflow")
|
||||
if isDefeat {
|
||||
player.GDAKCOICIDA = 0
|
||||
} else {
|
||||
for _, name := range rules.StreakNodes {
|
||||
if name == kind {
|
||||
if perfect {
|
||||
if player.GDAKCOICIDA == math.MaxUint32 {
|
||||
return fmt.Errorf("CW streak overflow")
|
||||
}
|
||||
player.GDAKCOICIDA++
|
||||
} else {
|
||||
player.GDAKCOICIDA = 0
|
||||
}
|
||||
player.GDAKCOICIDA++
|
||||
} else {
|
||||
player.GDAKCOICIDA = 0
|
||||
break
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
bonusFound := false
|
||||
var streakGold uint32
|
||||
for _, v := range rules.Victories {
|
||||
if v.Low <= player.GDAKCOICIDA && player.GDAKCOICIDA <= v.Up {
|
||||
if bonusFound {
|
||||
return fmt.Errorf("CW victory ranges overlap")
|
||||
if !isDefeat {
|
||||
bonusFound := false
|
||||
for _, v := range rules.Victories {
|
||||
if v.Low <= player.GDAKCOICIDA && player.GDAKCOICIDA <= v.Up {
|
||||
if bonusFound {
|
||||
return fmt.Errorf("CW victory ranges overlap")
|
||||
}
|
||||
bonusFound = true
|
||||
streakGold = v.Bonus
|
||||
}
|
||||
bonusFound = true
|
||||
streakGold = v.Bonus
|
||||
}
|
||||
}
|
||||
if !bonusFound {
|
||||
return fmt.Errorf("CW victory range missing")
|
||||
if !bonusFound {
|
||||
return fmt.Errorf("CW victory range missing")
|
||||
}
|
||||
}
|
||||
interest, err := catalog.BaseInterest(player.Gold, player.KNFOCCPOJEA)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
basicGold := node.PICMDONCKCO
|
||||
if isDefeat {
|
||||
basicGold = 0
|
||||
streakGold = 0
|
||||
}
|
||||
sum := uint64(player.Gold) + uint64(basicGold) + uint64(interest) + uint64(streakGold)
|
||||
if sum > math.MaxUint32 {
|
||||
sum = math.MaxUint32
|
||||
}
|
||||
player.Gold = uint32(sum)
|
||||
gain, err := catalog.IntegerRule("GridFight_GainExpWhenWaveEnd")
|
||||
if err != nil || gain < 0 || uint64(gain) > math.MaxUint32 {
|
||||
return fmt.Errorf("CW EXP gain rule invalid")
|
||||
var gain uint32
|
||||
if !isDefeat {
|
||||
g, err := catalog.BattleNodeExperience(run.IsOverlock, stage.DCAHJELNJNP, kind)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
gain = uint32(g)
|
||||
}
|
||||
plan, err := catalog.PlanBaseExperience(player.EHNJDIDABHD, player.GridFightCurLevelExp, uint32(gain), player.NDAINFLOLPJ)
|
||||
plan, err := catalog.PlanBaseExperience(player.EHNJDIDABHD, player.GridFightCurLevelExp, gain, player.NDAINFLOLPJ)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -276,12 +395,18 @@ func finishCurrencyWarsBattle(s *Session, req *pb.PVEBattleResultCsReq, current
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err = cwApplyBaseExperience(catalog, player, shop, uint32(gain)); err != nil {
|
||||
return err
|
||||
if gain > 0 {
|
||||
if err = cwApplyBaseExperience(catalog, player, shop, gain); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
var encounterUpdates []*pb.KFNCAIHIHCM
|
||||
if kind == "EliteBranch" {
|
||||
encounterUpdates, err = cwEncounterRewards(catalog, run, selectedBranch, progress, penalty.ThresholdPosition)
|
||||
runtime, err := cwBonfireRuntime(catalog, run)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if kind == "EliteBranch" && !isDefeat {
|
||||
encounterUpdates, err = cwEncounterRewards(catalog, run, selectedBranch, progress, penalty.ThresholdPosition, runtime)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -293,21 +418,39 @@ func finishCurrencyWarsBattle(s *Session, req *pb.PVEBattleResultCsReq, current
|
||||
}
|
||||
for _, role := range current.EIGMKOJOEEI.GridGameRoleList {
|
||||
total := float64(0)
|
||||
for _, stat := range req.Stt.APAGMJNECCN.DOGMMGLBJIJ {
|
||||
if stat.RoleId == role.RoleId && !math.IsNaN(stat.Damage) && !math.IsInf(stat.Damage, 0) && stat.Damage > 0 {
|
||||
total += stat.Damage
|
||||
if req.Stt != nil && req.Stt.APAGMJNECCN != nil {
|
||||
for _, stat := range req.Stt.APAGMJNECCN.DOGMMGLBJIJ {
|
||||
if (stat.RoleId == role.RoleId || stat.RoleId == role.AvatarId || stat.RoleId == role.UniqueId) && !math.IsNaN(stat.Damage) && !math.IsInf(stat.Damage, 0) && stat.Damage > 0 {
|
||||
total += stat.Damage
|
||||
}
|
||||
}
|
||||
}
|
||||
if total == 0 && req.Stt != nil {
|
||||
for _, ba := range req.Stt.BattleAvatarList {
|
||||
if (ba.Id == role.AvatarId || ba.Id == role.RoleId) && !math.IsNaN(ba.TotalDamage) && !math.IsInf(ba.TotalDamage, 0) && ba.TotalDamage > 0 {
|
||||
total += ba.TotalDamage
|
||||
}
|
||||
}
|
||||
}
|
||||
damage.EEGPILJDLBG = append(damage.EEGPILJDLBG, &pb.PLFKMENCDMM{RoleId: role.RoleId, RoleStar: role.RoleStar, TotalDamage: total, DIGNECHKINI: uint64(role.Pos) > uint64(frontMax)})
|
||||
}
|
||||
oldChapter, oldSection := stage.DCAHJELNJNP, stage.SectionId
|
||||
var nextNotify *pb.GridFightSyncUpdateResultScNotify
|
||||
if transition != nil {
|
||||
isFinalNode := false
|
||||
if isDefeat {
|
||||
// Terminal defeat: stage does not advance
|
||||
} else if transition != nil {
|
||||
stage.DCAHJELNJNP = nextLevel.DCAHJELNJNP
|
||||
stage.SectionId = nextLevel.SectionId
|
||||
stage.IMPNAHBCADN = proto.Clone(nextLevel.IMPNAHBCADN).(*pb.NCKOKDHNJDC)
|
||||
run.FMIGOKIDKJL = nextPending
|
||||
nextNotify = cwNotify(&pb.KFNCAIHIHCM{MNLCHEJKDHO: &pb.KFNCAIHIHCM_OOICHLAMNIG{OOICHLAMNIG: nextLevel}}, &pb.KFNCAIHIHCM{MNLCHEJKDHO: &pb.KFNCAIHIHCM_FMIGOKIDKJL{FMIGOKIDKJL: nextPending}})
|
||||
if stage.ANJBLBEOJND != nil && stage.ANJBLBEOJND.PIFNOKAMBLL != nil && stage.ANJBLBEOJND.PIFNOKAMBLL[cwDifficultySourceBranch] != 0 {
|
||||
diffUpdate, err := cwXaodevDifficulty(catalog, run, 0)
|
||||
if err == nil && diffUpdate != nil {
|
||||
nextNotify.GCPNIHHBGGD[0].JKPJFKCBIEM = append(nextNotify.GCPNIHHBGGD[0].JKPJFKCBIEM, diffUpdate)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// A battle has no pending action to allocate from. The persisted CAS
|
||||
// revision is monotonic and also backs Bonfire entry queue allocation.
|
||||
@@ -315,39 +458,167 @@ func finishCurrencyWarsBattle(s *Session, req *pb.PVEBattleResultCsReq, current
|
||||
return fmt.Errorf("CW settlement queue exhausted")
|
||||
}
|
||||
run.FMIGOKIDKJL = &pb.CHCHAJIANIM{QueuePosition: uint32(revision)}
|
||||
nextNotify, err = cwAdvanceRouteNode(catalog, run)
|
||||
nextNotify, err = cwAdvanceRouteNode(catalog, run, runtime)
|
||||
if err != nil {
|
||||
if strings.Contains(err.Error(), "no next node") {
|
||||
isFinalNode = true
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
// The allocation seed is not a Client pending action, so it must not
|
||||
// produce a synthetic FinishPendingAction notification.
|
||||
for _, group := range nextNotify.GCPNIHHBGGD {
|
||||
kept := group.JKPJFKCBIEM[:0]
|
||||
for _, update := range group.JKPJFKCBIEM {
|
||||
if update.GetPMFBIGLPJJA() != uint32(revision) {
|
||||
kept = append(kept, update)
|
||||
}
|
||||
}
|
||||
group.JKPJFKCBIEM = kept
|
||||
}
|
||||
}
|
||||
}
|
||||
if !isDefeat && !isFinalNode {
|
||||
runtime, err = cwApplyBonfireEnemyRules(catalog, run, runtime)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// The allocation seed is not a Client pending action, so it must not
|
||||
// produce a synthetic FinishPendingAction notification.
|
||||
for _, group := range nextNotify.GCPNIHHBGGD {
|
||||
kept := group.JKPJFKCBIEM[:0]
|
||||
for _, update := range group.JKPJFKCBIEM {
|
||||
if update.GetPMFBIGLPJJA() != uint32(revision) {
|
||||
kept = append(kept, update)
|
||||
}
|
||||
}
|
||||
group.JKPJFKCBIEM = kept
|
||||
if runtime.Rules["PetPalStarDown"] != 0 && stage.GetIMPNAHBCADN().GetMPOBBIPMNNJ() != nil {
|
||||
nextNotify.GCPNIHHBGGD = append(nextNotify.GCPNIHHBGGD, cwNotify(&pb.KFNCAIHIHCM{MNLCHEJKDHO: &pb.KFNCAIHIHCM_OOICHLAMNIG{OOICHLAMNIG: &pb.AINFNFIDGFF{DCAHJELNJNP: stage.DCAHJELNJNP, SectionId: stage.SectionId, IMPNAHBCADN: stage.IMPNAHBCADN}}}).GCPNIHHBGGD...)
|
||||
}
|
||||
}
|
||||
runtime, err := cwApplyBonfireEnemyRules(catalog, run, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
tbLayer := cwGetTrailblazeLayer(catalog, run)
|
||||
if tbLayer > 0 {
|
||||
if tbCat, err := common.LoadCurrencyWarsTrailblaze(); err == nil {
|
||||
income := tbCat.Income(tbLayer)
|
||||
runtime.Rules["TbPower"] += income
|
||||
PacketLog(fmt.Sprintf("CW_TRAILBLAZE_INCOME layer=%d income=%d total_power=%d", tbLayer, income, runtime.Rules["TbPower"]))
|
||||
}
|
||||
}
|
||||
if runtime.Rules["PetPalStarDown"] != 0 && stage.GetIMPNAHBCADN().GetMPOBBIPMNNJ() != nil {
|
||||
nextNotify.GCPNIHHBGGD = append(nextNotify.GCPNIHHBGGD, cwNotify(&pb.KFNCAIHIHCM{MNLCHEJKDHO: &pb.KFNCAIHIHCM_OOICHLAMNIG{OOICHLAMNIG: &pb.AINFNFIDGFF{DCAHJELNJNP: stage.DCAHJELNJNP, SectionId: stage.SectionId, IMPNAHBCADN: stage.IMPNAHBCADN}}}).GCPNIHHBGGD...)
|
||||
cwSyncTraitComponent(catalog, run, runtime)
|
||||
|
||||
var droppedOrbs []*pb.IBPDPCOGDEP
|
||||
var orbUpdates []*pb.KFNCAIHIHCM
|
||||
if !isDefeat {
|
||||
orbIDs, dropErr := cwRollNodeOrbs(catalog, run, stage.EMOHLJHPOPC, oldChapter, oldSection, progress)
|
||||
if dropErr != nil {
|
||||
PacketLog(fmt.Sprintf("CW_DROP_ORBS error: %v", dropErr))
|
||||
} else if len(orbIDs) > 0 {
|
||||
var orbBag *pb.DBONCGFHHDN
|
||||
for _, c := range run.NAGDJGMMCBE {
|
||||
if b := c.GetDBAGKJNPDOL(); b != nil {
|
||||
orbBag = b
|
||||
break
|
||||
}
|
||||
}
|
||||
if orbBag == nil {
|
||||
orbBag = &pb.DBONCGFHHDN{}
|
||||
run.NAGDJGMMCBE = append(run.NAGDJGMMCBE, &pb.GridFightGameInfo{
|
||||
LEOIAOFBBFA: &pb.GridFightGameInfo_DBAGKJNPDOL{
|
||||
DBAGKJNPDOL: orbBag,
|
||||
},
|
||||
})
|
||||
}
|
||||
for _, orbID := range orbIDs {
|
||||
uid, idErr := cwNextEntityID(run)
|
||||
if idErr != nil {
|
||||
break
|
||||
}
|
||||
orb := &pb.IBPDPCOGDEP{
|
||||
UniqueId: uid,
|
||||
LDBNOMPCOKK: orbID,
|
||||
}
|
||||
orbBag.MDKGCIKOMLI = append(orbBag.MDKGCIKOMLI, orb)
|
||||
droppedOrbs = append(droppedOrbs, orb)
|
||||
orbUpdates = append(orbUpdates, &pb.KFNCAIHIHCM{
|
||||
MNLCHEJKDHO: &pb.KFNCAIHIHCM_AFILIPBHMOO{
|
||||
AFILIPBHMOO: &pb.MMEDLCAENAL{
|
||||
UniqueId: uid,
|
||||
LDBNOMPCOKK: orbID,
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
PacketLog(fmt.Sprintf("CW_DROP_ORBS node=%d-%d dropped=%d", oldChapter, oldSection, len(droppedOrbs)))
|
||||
}
|
||||
}
|
||||
|
||||
player.GAJGBBFELEL = &pb.GMBMNFLMKPI{IBCPAKJAPFF: pb.KMJNPEMPNMC_KMJNPEMPNMC_AEINKINPAFL, LMICDNNABNM: pb.GGNKDLAHAGH_GGNKDLAHAGH_FHOHPFBDNOH}
|
||||
end := &pb.GridFightEndBattleStageNotify{DCAHJELNJNP: oldChapter, SectionId: oldSection, EMOHLJHPOPC: stage.EMOHLJHPOPC, HFLPDCJDIAC: progress, OAHFCPPIMLF: penalty.ThresholdPosition, CBHJKFNCDAD: perfect,
|
||||
JPKHBELGHCG: previousStreak, OCCOHKIMGCN: player.GDAKCOICIDA, CLFNPMGHMFC: basicGold, DMNILJEGICO: interest, OGLOCDMNNIM: streakGold, ODJEBDNBLLC: previousHP, PAGPKOKMDBK: player.GridFightLineupHp, LKCJAPIGEND: player.PPKKHHNEOHB, NKBIDLBLONC: damage, HMKOKACNHJH: hpChanges,
|
||||
AEOCOGHMEBG: &pb.GEEMFDBDMDH{PBMAHOJBAGG: uint32(gain), EDCLIPCEHAO: &pb.NFPLDMFCLHA{Level: previousLevel, Exp: previousExp, KDBMPKJKAKI: previousRow.LevelUpExp}, LHIAODNJIIC: &pb.NFPLDMFCLHA{Level: plan.Level, Exp: plan.Exp, KDBMPKJKAKI: row.LevelUpExp}}}
|
||||
if len(droppedOrbs) > 0 {
|
||||
var dropEntries []*pb.BCCONKJHDJL
|
||||
for _, orb := range droppedOrbs {
|
||||
dropEntries = append(dropEntries, &pb.BCCONKJHDJL{
|
||||
FKKGLFOHGGA: pb.MJJIFGINJAJ_MJJIFGINJAJ_ANMDMBGNOHL,
|
||||
FNLMKJLKLFH: orb.LDBNOMPCOKK,
|
||||
Num: 1,
|
||||
})
|
||||
}
|
||||
end.AFFFCONCDMG = map[uint32]*pb.GridFightDropInfo{
|
||||
0: {NMGIABHIJJB: dropEntries},
|
||||
}
|
||||
}
|
||||
|
||||
update := cwNotify(cwUnlock(), cwGoldSync(player.Gold), cwCapacitySync(player), &pb.KFNCAIHIHCM{MNLCHEJKDHO: &pb.KFNCAIHIHCM_GridFightLineupHp{GridFightLineupHp: &pb.FMJDDIHBELC{PPKKHHNEOHB: player.PPKKHHNEOHB, GridFightLineupHp: player.GridFightLineupHp}}}, &pb.KFNCAIHIHCM{MNLCHEJKDHO: &pb.KFNCAIHIHCM_PLPHEIBLPDL{PLPHEIBLPDL: &pb.PIHKLPJGEPM{Level: plan.Level, Exp: plan.Exp, HFMKLAPEKFA: player.NDAINFLOLPJ}}})
|
||||
update.GCPNIHHBGGD[0].JKPJFKCBIEM = append(update.GCPNIHHBGGD[0].JKPJFKCBIEM, encounterUpdates...)
|
||||
update.GCPNIHHBGGD[0].JKPJFKCBIEM = append(update.GCPNIHHBGGD[0].JKPJFKCBIEM, orbUpdates...)
|
||||
if tbCat, err := common.LoadCurrencyWarsTrailblaze(); err == nil && (tbLayer > 0 || runtime.Rules["TbOpened"] != 0) {
|
||||
update.GCPNIHHBGGD[0].JKPJFKCBIEM = append(update.GCPNIHHBGGD[0].JKPJFKCBIEM,
|
||||
&pb.KFNCAIHIHCM{
|
||||
MNLCHEJKDHO: &pb.KFNCAIHIHCM_HKHJJCMKKJE{
|
||||
HKHJJCMKKJE: &pb.JLKCBOIFJKC{
|
||||
TraitId: cwTrailblazeTrait,
|
||||
ENPLACDLJGA: cwTrailblazeTraitEffectProto(tbCat, runtime),
|
||||
},
|
||||
},
|
||||
},
|
||||
&pb.KFNCAIHIHCM{
|
||||
MNLCHEJKDHO: &pb.KFNCAIHIHCM_GOOCHGKBIPN{
|
||||
GOOCHGKBIPN: cwTrailblazeModifierProto(tbCat, runtime),
|
||||
},
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
if isDefeat || isFinalNode {
|
||||
reason := pb.PEIJNEFOCHI_PEIJNEFOCHI_JOJPGBCECLN
|
||||
if isDefeat {
|
||||
reason = pb.PEIJNEFOCHI_PEIJNEFOCHI_HIGMFLKHGNJ
|
||||
}
|
||||
keepWin, settle, termErr := currencyWarsTerminalSettlement(catalog, data, run, reason, !isDefeat, damage.EEGPILJDLBG)
|
||||
if termErr != nil {
|
||||
return termErr
|
||||
}
|
||||
data.DHFOFLFCLAH = nil
|
||||
if termErr = s.saveCurrencyWarsData(data, catalog); termErr != nil {
|
||||
return termErr
|
||||
}
|
||||
CURRENT_BATTLE.Delete(s.Token)
|
||||
s.currencyWarsOpen = false
|
||||
|
||||
if err = s.Send(update); err != nil {
|
||||
return err
|
||||
}
|
||||
if err = s.Send(end); err != nil {
|
||||
return err
|
||||
}
|
||||
if err = cwSend(s, keepWin); err != nil {
|
||||
return err
|
||||
}
|
||||
if err = cwSend(s, settle); err != nil {
|
||||
return err
|
||||
}
|
||||
PacketLog(fmt.Sprintf("CW_SETTLEMENT terminal victory=%v battle=%d progress=%d gold=%d node=%d-%d", !isDefeat, req.BattleId, progress, player.Gold, oldChapter, oldSection))
|
||||
return nil
|
||||
}
|
||||
|
||||
if err = s.saveCurrencyWarsDataWithRuntime(data, catalog, runtime); err != nil {
|
||||
return err
|
||||
}
|
||||
CURRENT_BATTLE.Delete(s.Token) // Duplicate uploads cannot award again.
|
||||
update := cwNotify(cwUnlock(), cwGoldSync(player.Gold), cwCapacitySync(player), &pb.KFNCAIHIHCM{MNLCHEJKDHO: &pb.KFNCAIHIHCM_GridFightLineupHp{GridFightLineupHp: &pb.FMJDDIHBELC{PPKKHHNEOHB: player.PPKKHHNEOHB, GridFightLineupHp: player.GridFightLineupHp}}}, &pb.KFNCAIHIHCM{MNLCHEJKDHO: &pb.KFNCAIHIHCM_PLPHEIBLPDL{PLPHEIBLPDL: &pb.PIHKLPJGEPM{Level: plan.Level, Exp: plan.Exp, HFMKLAPEKFA: player.NDAINFLOLPJ}}})
|
||||
update.GCPNIHHBGGD[0].JKPJFKCBIEM = append(update.GCPNIHHBGGD[0].JKPJFKCBIEM, encounterUpdates...)
|
||||
if err = s.Send(update); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user