Files
bd2/go/internal/server/world/field_buff_damage.go
T

85 lines
2.2 KiB
Go

package world
import (
"bd2server/internal/server/gamedata"
"bd2server/internal/server/player"
"fmt"
"math"
)
func (s *Service) AttachFieldBuffRuntime(root, version string) error {
d, e := gamedata.LoadFieldBuffDesign(root, version)
if e != nil {
return e
}
s.fieldBuffs = d
s.AttachFieldMonsterDamage(s.applyMonsterFieldDamage)
return nil
}
func (s *Service) applyMonsterFieldDamage(pack int, id uint64, identity string) ([][]byte, error) {
r, ok := s.fieldBuffs[id]
if !ok || (r.Type != 4 && r.Type != 5) || r.TargetType > 2 || math.IsNaN(r.Value) || math.IsInf(r.Value, 0) || r.Value < 0 {
return nil, fmt.Errorf("world: invalid damaging field buff")
}
if s.characters == nil || s.decks == nil {
return nil, fmt.Errorf("world: field health runtime unavailable")
}
entries := s.decks.CurrentFieldDeck()
indices := make([]uint64, 0, len(entries))
for _, entry := range entries {
indices = append(indices, entry.CharacterInvenIndex)
}
if r.TargetType == 0 {
party, e := s.ResolveStoryParty(pack, s.firstUnclearedQuestFor(pack))
if e != nil {
return nil, e
}
if len(party) > 0 && s.questDifficulty(pack) == 0 {
indices = []uint64{party[0].InvenIndex}
} else if s.decks.FieldControlType() == 0 || len(indices) == 0 {
indices = nil
for _, entry := range s.decks.CurrentDeck() {
indices = append(indices, entry.CharacterInvenIndex)
}
}
if len(indices) > 1 {
indices = indices[:1]
}
}
var response [][]byte
for _, index := range indices {
c, found := s.characters.Find(index)
if !found {
return nil, fmt.Errorf("world: field character missing")
}
hp, e := s.characters.CurrentHealth(c.InvenIndex)
if e != nil {
return nil, e
}
if hp == 0 && r.TargetType != 0 {
continue
}
damage := r.Value
if r.Type == 5 {
max, e := s.characters.MaxHealth(c.InvenIndex)
if e != nil {
return nil, e
}
damage = float64(max) * r.Value
}
remaining := uint64(0)
if damage < float64(hp) {
remaining = hp - uint64(damage)
}
if e = s.characters.SetCurrentHealth(c.InvenIndex, remaining); e != nil {
return nil, e
}
c.HP = remaining
response = append(response, player.CharacterWire(c))
if r.TargetType == 0 {
break
}
}
return response, nil
}