Files
GaCy-GO/internal/common/battle_servant_report.go

72 lines
2.3 KiB
Go

package common
import pb "gac-hkrpg-go/protocol/proto"
// BattleAvatarServantInfo is a separate native statistic, keyed by its owner's
// avatar_id. Never infer ownership from lineup position or the servant's ID.
func applyBattleServantStatistics(report *BattleReport, servants []*pb.BattleAvatarServantInfo) {
owners := make(map[uint32]*BattleAvatarReport, len(report.Avatars))
for _, avatar := range report.Avatars {
owners[avatar.AvatarID] = avatar
}
matched := false
seen := make(map[uint32]bool)
for _, servant := range servants {
if servant == nil || servant.AvatarId == 0 {
continue
}
owner := owners[servant.AvatarId]
if owner == nil || (servant.EntityId != 0 && seen[servant.EntityId]) {
continue
}
if servant.EntityId != 0 {
seen[servant.EntityId] = true
}
matched = true
damage := servant.TotalDamage
if damage == 0 {
damage = sumAttackDamageProperties(servant.AttackTypeDamage)
}
owner.TotalDamage += damage
owner.MemospriteDamage += damage
owner.TotalBreakDamage += servant.TotalBreakDamage
owner.TotalHeal += servant.TotalHeal
owner.TotalShield += servant.TotalShield
for _, pair := range []struct {
values []*pb.AttackDamageProperty
target map[string]float64
maximum bool
}{{servant.AttackTypeDamage, owner.AttackTypeDamage, false},
{servant.AttackTypeBreakDamage, owner.AttackTypeBreakDamage, false},
{servant.AttackTypeMaxDamage, owner.AttackTypeMaxDamage, true}} {
for _, value := range pair.values {
if value == nil || value.AttackType == "" {
continue
}
if pair.maximum {
pair.target[value.AttackType] = max(pair.target[value.AttackType], value.Damage)
} else {
pair.target[value.AttackType] += value.Damage
}
}
}
}
if !matched {
return
}
// Rebuild from attributed records; the earlier monster fallback can already
// include servant damage, so adding to that fallback would count it twice.
report.TeamTotalDamage, report.TeamTotalHeal, report.TeamTotalShield = 0, 0, 0
for _, avatar := range report.Avatars {
report.TeamTotalDamage += avatar.TotalDamage
report.TeamTotalHeal += avatar.TotalHeal
report.TeamTotalShield += avatar.TotalShield
}
for _, avatar := range report.Avatars {
avatar.DamagePercent = 0
if report.TeamTotalDamage > 0 {
avatar.DamagePercent = avatar.TotalDamage / report.TeamTotalDamage * 100
}
}
}