Files

111 lines
3.7 KiB
Go

package gameserver
import (
"gac-hkrpg-go/internal/common"
goproto "gac-hkrpg-go/protocol/proto"
"google.golang.org/protobuf/proto"
)
// ChallengeTargetConfigRow.ChallengeTargetType, captured from this Client.
const challengeTargetTotalScore uint32 = 7
func tierceTargets(id, total uint32) []uint32 {
stage := getChallengeData().Tierce[id]
ids := append([]uint32(nil), stage.Targets...)
if stage.SpecialTarget != 0 {
ids = append(ids, stage.SpecialTarget)
}
var finished []uint32
for _, targetID := range ids {
r, ok := getChallengeData().TargetRules[targetID]
if ok && r.Type == challengeTargetTotalScore && total >= r.Param {
finished = append(finished, targetID)
}
}
return finished
}
func tierceBestRecord(saved *common.TierceProgress) (uint32, bool) {
var total uint32
allWon := true
for node := uint32(0); node < tierceNodeCount; node++ {
n, ok := saved.Nodes[node]
total += n.Score
if !ok || !n.Won {
allWon = false
}
}
return total, allWon
}
func tierceNodeResult(node uint32, n common.TierceNodeProgress, teams ...[]uint32) *goproto.PMMOFOBCINL {
result := &goproto.PMMOFOBCINL{}
if len(n.Result) > 0 && proto.Unmarshal(n.Result, result) == nil {
return result
}
// Imported confirmed scores have no historical equipment snapshot. Supply
// known team IDs and empty wrappers rather than inventing gear/stats.
result.Lineup = &goproto.GLLFJFJBIBC{}
if len(teams) > 0 {
for slot, id := range teams[0] {
result.Lineup.MNABNJOEHLF = append(result.Lineup.MNABNJOEHLF, &goproto.CLDOIEGCNLD{AvatarId: id, Slot: uint32(slot), AvatarType: uint32(goproto.AvatarType_AVATAR_FORMAL_TYPE), PAGPNOKLNOM: &goproto.ChallengeBossEquipmentInfo{}, OKCGHKDMFAM: &goproto.ChallengeBossAvatarRelicInfo{}})
}
}
result.FINOCEGDBDI = node
result.ScoreId = n.Score
if n.Won {
result.EndStatus = goproto.BattleEndStatus_BATTLE_END_WIN
}
return result
}
func saveTierceResult(s *Session, result *goproto.PMMOFOBCINL) error {
saved := s.JSON().TierceProgress[s.ChallengeRun.ID]
if saved.Nodes == nil {
saved.Nodes = map[uint32]common.TierceNodeProgress{}
}
node := result.FINOCEGDBDI
old, known := saved.Nodes[node]
won := result.EndStatus == goproto.BattleEndStatus_BATTLE_END_WIN
if !known || result.ScoreId > old.Score || (result.ScoreId == old.Score && won && !old.Won) {
raw, err := proto.Marshal(result)
if err != nil {
return err
}
saved.Nodes[node] = common.TierceNodeProgress{Score: result.ScoreId, Won: won, Result: raw}
}
return s.JSON().SavePersistentChecked()
}
func buildTierceGroup(id uint32, saved *common.TierceProgress) *goproto.ChallengeTierceGroup {
group := &goproto.ChallengeTierceGroup{ChallengeId: id}
if saved == nil {
return group
}
total, allWon := tierceBestRecord(saved)
group.Record = &goproto.ChallengeTierceRecord{TotalScore: total}
group.IsWin = allWon
if limit := getChallengeData().Tierce[id].ClearScore; limit != 0 && total < limit {
group.IsWin = false
}
if allWon {
group.FinishedTargetList = tierceTargets(id, total)
}
for node, team := range saved.Teams {
lineup := &goproto.CMOPLAHDEPN{FINOCEGDBDI: uint32(node)}
if node < len(saved.Buffs) {
lineup.BuffId = saved.Buffs[node]
}
for _, aid := range team {
lineup.TierceAvatarIdList = append(lineup.TierceAvatarIdList, &goproto.AvatarLineup{Id: aid, AvatarType: goproto.AvatarType_AVATAR_FORMAL_TYPE})
}
group.MOGEEAJCFNO = append(group.MOGEEAJCFNO, lineup)
}
for node := uint32(0); node < tierceNodeCount; node++ {
if n, ok := saved.Nodes[node]; ok {
var team []uint32
if int(node) < len(saved.Teams) {
team = saved.Teams[node]
}
group.HGKCEEOONGA = append(group.HGKCEEOONGA, tierceNodeResult(node, n, team))
}
}
return group
}