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
@@ -19,16 +19,19 @@ func currencyWarsAbandonRun(data *pb.GridFightGetDataScRsp) (uint32, bool) {
|
||||
return runID, true
|
||||
}
|
||||
|
||||
// currencyWarsQuitSettlement builds the ordered server notifications expected
|
||||
// before GridFightQuitSettleScRsp. All packet IDs and wire tags come from the
|
||||
// current generated protocol; values are copied from the saved run/catalog.
|
||||
func currencyWarsQuitSettlement(catalog *common.CurrencyWarsCatalog, run *pb.MPIMAEMCEFH) (*pb.GridFightSyncKeepWinCntNotify, *pb.GridFightSettleNotify, error) {
|
||||
func currencyWarsQuitSettlement(catalog *common.CurrencyWarsCatalog, data *pb.GridFightGetDataScRsp, run *pb.MPIMAEMCEFH) (*pb.GridFightSyncKeepWinCntNotify, *pb.GridFightSettleNotify, error) {
|
||||
return currencyWarsTerminalSettlement(catalog, data, run, pb.PEIJNEFOCHI_PEIJNEFOCHI_NOCIJDINKPJ, false, nil)
|
||||
}
|
||||
|
||||
// currencyWarsTerminalSettlement builds the ordered server notifications expected
|
||||
// when a run ends (quit, defeat, or victory).
|
||||
func currencyWarsTerminalSettlement(catalog *common.CurrencyWarsCatalog, data *pb.GridFightGetDataScRsp, run *pb.MPIMAEMCEFH, reason pb.PEIJNEFOCHI, isWon bool, damageList []*pb.PLFKMENCDMM) (*pb.GridFightSyncKeepWinCntNotify, *pb.GridFightSettleNotify, error) {
|
||||
if catalog == nil || run == nil || run.UniqueId == 0 {
|
||||
return nil, nil, fmt.Errorf("CW quit settlement is missing catalog or active run")
|
||||
return nil, nil, fmt.Errorf("CW settlement is missing catalog or active run")
|
||||
}
|
||||
player, team, _ := cwComponents(run)
|
||||
if player == nil || team == nil {
|
||||
return nil, nil, fmt.Errorf("CW quit settlement is missing player/team components")
|
||||
return nil, nil, fmt.Errorf("CW settlement is missing player/team components")
|
||||
}
|
||||
var stage *pb.BEEFLEJAOCN
|
||||
for _, component := range run.NAGDJGMMCBE {
|
||||
@@ -37,13 +40,13 @@ func currencyWarsQuitSettlement(catalog *common.CurrencyWarsCatalog, run *pb.MPI
|
||||
}
|
||||
if current := component.GetKLCPAAHDPJF(); current != nil {
|
||||
if stage != nil {
|
||||
return nil, nil, fmt.Errorf("CW quit settlement has duplicate stage components")
|
||||
return nil, nil, fmt.Errorf("CW settlement has duplicate stage components")
|
||||
}
|
||||
stage = current
|
||||
}
|
||||
}
|
||||
if stage == nil {
|
||||
return nil, nil, fmt.Errorf("CW quit settlement is missing the current stage component")
|
||||
return nil, nil, fmt.Errorf("CW settlement is missing the current stage component")
|
||||
}
|
||||
|
||||
avatarIDs := make([]uint32, 0, len(team.GridGameRoleList))
|
||||
@@ -72,22 +75,88 @@ func currencyWarsQuitSettlement(catalog *common.CurrencyWarsCatalog, run *pb.MPI
|
||||
return roles[i].UniqueId < roles[j].UniqueId
|
||||
})
|
||||
|
||||
var highestDivision common.CurrencyWarsDivision
|
||||
for _, division := range catalog.SeasonDivisions(catalog.ActiveSeasonID) {
|
||||
if division.DivisionLevel > highestDivision.DivisionLevel ||
|
||||
(division.DivisionLevel == highestDivision.DivisionLevel && division.Progress > highestDivision.Progress) {
|
||||
highestDivision = division
|
||||
// Rank calculation based on remaining HP percentage (GridFight_SettleRankHpConfig: [1, 40, 70])
|
||||
// Rank C = 0, Rank B = 1, Rank A = 2, Rank S = 3, Rank SS = 4
|
||||
var rankType uint32
|
||||
var divisionUp uint32
|
||||
if isWon && player.PPKKHHNEOHB > 0 && player.GridFightLineupHp > 0 {
|
||||
hpPercent := float64(player.GridFightLineupHp) / float64(player.PPKKHHNEOHB) * 100.0
|
||||
if hpPercent >= 100.0 || player.GridFightLineupHp >= player.PPKKHHNEOHB {
|
||||
rankType = 4 // Rank SS (flawless / 100% HP)
|
||||
divisionUp = 3
|
||||
} else if hpPercent >= 70.0 {
|
||||
rankType = 3 // Rank S
|
||||
divisionUp = 3
|
||||
} else if hpPercent >= 40.0 {
|
||||
rankType = 2 // Rank A
|
||||
divisionUp = 2
|
||||
} else {
|
||||
rankType = 1 // Rank B
|
||||
divisionUp = 1
|
||||
}
|
||||
} else {
|
||||
rankType = 0
|
||||
divisionUp = 0
|
||||
}
|
||||
|
||||
seasonDivisions := catalog.SeasonDivisions(catalog.ActiveSeasonID)
|
||||
curDivisionID := run.DivisionId
|
||||
newDivisionID := curDivisionID
|
||||
isPromotion := false
|
||||
if isWon && divisionUp > 0 && len(seasonDivisions) > 0 {
|
||||
curIdx := -1
|
||||
for i, d := range seasonDivisions {
|
||||
if d.ID == curDivisionID {
|
||||
curIdx = i
|
||||
break
|
||||
}
|
||||
}
|
||||
if curIdx >= 0 {
|
||||
targetIdx := curIdx + int(divisionUp)
|
||||
if targetIdx >= len(seasonDivisions) {
|
||||
targetIdx = len(seasonDivisions) - 1
|
||||
}
|
||||
newDivisionID = seasonDivisions[targetIdx].ID
|
||||
if seasonDivisions[targetIdx].DivisionLevel > seasonDivisions[curIdx].DivisionLevel {
|
||||
isPromotion = true
|
||||
}
|
||||
}
|
||||
}
|
||||
if highestDivision.ID == 0 {
|
||||
return nil, nil, fmt.Errorf("CW quit settlement has no active-season division data")
|
||||
|
||||
var equipmentList []*pb.IJDLENJJBHJ
|
||||
if bag := cwEquipmentBag(run); bag != nil {
|
||||
equipmentList = bag.GridFightEquipmentList
|
||||
}
|
||||
|
||||
var augments []*pb.PPGEBEBPMJC
|
||||
for _, component := range run.NAGDJGMMCBE {
|
||||
if component == nil {
|
||||
continue
|
||||
}
|
||||
if owned := component.GetLLDBOIANGDN(); owned != nil {
|
||||
augments = owned.SyncAugmentInfo
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
var teamValue uint32
|
||||
for _, r := range team.GridGameRoleList {
|
||||
if r != nil {
|
||||
teamValue += uint32(r.RoleStar) * 2
|
||||
}
|
||||
}
|
||||
|
||||
finish := &pb.OEDHMAHDECC{
|
||||
// GridFightSettleReason value 1 is Quit in the Client enum.
|
||||
Reason: pb.PEIJNEFOCHI_PEIJNEFOCHI_NOCIJDINKPJ,
|
||||
IsOverlock: run.IsOverlock,
|
||||
JLDDDLDNFEF: run.JLDDDLDNFEF,
|
||||
Reason: reason,
|
||||
IsOverlock: run.IsOverlock,
|
||||
JLDDDLDNFEF: run.JLDDDLDNFEF,
|
||||
LLJJCOOKANH: rankType,
|
||||
MBMJNEDIFFC: divisionUp,
|
||||
DBODGPBOIHC: isPromotion,
|
||||
EEGPILJDLBG: damageList,
|
||||
GridFightEquipmentList: equipmentList,
|
||||
SyncAugmentInfo: augments,
|
||||
AKEGLJLCFPH: teamValue,
|
||||
NDLIKNEKDLL: &pb.GOCIGPCDKDJ{
|
||||
LKCJAPIGEND: player.PPKKHHNEOHB,
|
||||
PAGPKOKMDBK: player.GridFightLineupHp,
|
||||
@@ -95,21 +164,72 @@ func currencyWarsQuitSettlement(catalog *common.CurrencyWarsCatalog, run *pb.MPI
|
||||
EMOHLJHPOPC: stage.EMOHLJHPOPC,
|
||||
AACGBEBGDPE: run.DivisionId,
|
||||
SectionId: stage.SectionId,
|
||||
FDGKBOIEHBD: player.NDAINFLOLPJ,
|
||||
FMEOHKHGMJM: []uint32{catalog.ActiveSeasonModule().ActivityModuleID},
|
||||
},
|
||||
PPJFPNMIFHL: &pb.GLPCEKMKLGG{GridFightAvatarList: avatarIDs},
|
||||
GridGameRoleList: roles,
|
||||
GridGameNpcList: team.GridGameNpcList,
|
||||
BossInfo: stage.BossInfo,
|
||||
CFFCNEDGCJJ: stage.CFFCNEDGCJJ,
|
||||
OAIGAGABCMK: stage.GridFightPortalBuffList,
|
||||
PPJFPNMIFHL: &pb.GLPCEKMKLGG{GridFightAvatarList: avatarIDs},
|
||||
GridGameRoleList: roles,
|
||||
GridGameNpcList: team.GridGameNpcList,
|
||||
BossInfo: stage.BossInfo,
|
||||
CFFCNEDGCJJ: stage.CFFCNEDGCJJ,
|
||||
OAIGAGABCMK: stage.GridFightPortalBuffList,
|
||||
GridFightTraitInfo: cwCalculateBoardTraits(catalog, run),
|
||||
}
|
||||
|
||||
return &pb.GridFightSyncKeepWinCntNotify{EHBLJGIENPI: player.GDAKCOICIDA}, &pb.GridFightSettleNotify{
|
||||
var weeklyScore, expBase, expExtra, totalExp uint32
|
||||
if scoreCatalog, err := common.LoadCurrencyWarsScore(catalog); err == nil {
|
||||
weeklyScore, expBase, expExtra = scoreCatalog.CalculateRunScore(run.DivisionId, run.IsOverlock, stage.DCAHJELNJNP, stage.SectionId, isWon)
|
||||
totalExp = expBase + expExtra
|
||||
}
|
||||
|
||||
var curSeasonExp, curTalentCoin uint32
|
||||
if data != nil && data.LFLCDNGALME != nil && data.LFLCDNGALME.HFPEJIDDDJG != nil {
|
||||
if data.LFLCDNGALME.HFPEJIDDDJG.Exp != nil {
|
||||
curSeasonExp = data.LFLCDNGALME.HFPEJIDDDJG.Exp.KEJGCDOGEDD
|
||||
}
|
||||
curTalentCoin = data.LFLCDNGALME.HFPEJIDDDJG.GEBGGMAGDJB
|
||||
}
|
||||
newSeasonExp := curSeasonExp + totalExp
|
||||
seasonLevel := (newSeasonExp / 800) + 1
|
||||
maxExp := catalog.ActiveSeasonModule().MaxRewardExp
|
||||
maxLevel := maxExp / 800
|
||||
if maxLevel == 0 {
|
||||
maxLevel = 60
|
||||
}
|
||||
if seasonLevel > maxLevel {
|
||||
seasonLevel = maxLevel
|
||||
}
|
||||
|
||||
cwRecordArchive(finish, catalog.ActiveSeasonID, catalog.ActiveSubSeasonID)
|
||||
|
||||
if data != nil && data.LFLCDNGALME != nil && data.LFLCDNGALME.HFPEJIDDDJG != nil {
|
||||
if data.LFLCDNGALME.HFPEJIDDDJG.Exp == nil {
|
||||
data.LFLCDNGALME.HFPEJIDDDJG.Exp = &pb.GLIFOLCEMIN{}
|
||||
}
|
||||
data.LFLCDNGALME.HFPEJIDDDJG.Exp.KEJGCDOGEDD = newSeasonExp
|
||||
if newDivisionID > data.LFLCDNGALME.HFPEJIDDDJG.DivisionId {
|
||||
data.LFLCDNGALME.HFPEJIDDDJG.DivisionId = newDivisionID
|
||||
}
|
||||
data.LFLCDNGALME.HFPEJIDDDJG.GDAKCOICIDA = player.GDAKCOICIDA
|
||||
}
|
||||
|
||||
settleNotify := &pb.GridFightSettleNotify{
|
||||
FLHOPMMEGAI: run.DivisionId,
|
||||
CDANKDNACJP: highestDivision.ID,
|
||||
NMCKJPEMACM: catalog.ActiveSeasonModule().MaxRewardExp,
|
||||
CDANKDNACJP: newDivisionID,
|
||||
NMCKJPEMACM: seasonLevel,
|
||||
EDHKHJAPMKA: weeklyScore,
|
||||
CGKNDIJMOCJ: expBase,
|
||||
MNNKKEPCPPL: expExtra,
|
||||
KEJGCDOGEDD: newSeasonExp,
|
||||
GEBGGMAGDJB: curTalentCoin,
|
||||
BFLLJJBHLDF: finish,
|
||||
}, nil
|
||||
}
|
||||
if data == nil {
|
||||
settleNotify.NMCKJPEMACM = catalog.ActiveSeasonModule().MaxRewardExp
|
||||
settleNotify.KEJGCDOGEDD = totalExp
|
||||
}
|
||||
|
||||
return &pb.GridFightSyncKeepWinCntNotify{EHBLJGIENPI: player.GDAKCOICIDA}, settleNotify, nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
@@ -143,7 +263,7 @@ func init() {
|
||||
return nil
|
||||
}
|
||||
runID := run.UniqueId
|
||||
keepWinCount, settlement, err := currencyWarsQuitSettlement(catalog, run)
|
||||
keepWinCount, settlement, err := currencyWarsQuitSettlement(catalog, data, run)
|
||||
if err != nil {
|
||||
PacketLog(fmt.Sprintf("CW_QUIT_SETTLE rejected run=%d reason=settlement_build_error error=%v", runID, err))
|
||||
return nil
|
||||
|
||||
Reference in new issue
Block a user