package combat import "time" // BuffDef defines a buff/debuff type. type BuffDef struct { ID uint32 Name string IsDebuff bool DamagePerTick int32 // for DoTs (debuff); heal per tick for HoTs (buff) StatModifier StatMod } // StatMod is a temporary stat modification from a buff. type StatMod struct { StrBonus int32 DexBonus int32 IntBonus int32 } // ActiveBuff is an active buff/debuff on an entity. type ActiveBuff struct { Def *BuffDef CasterID uint64 Remaining time.Duration TickInterval time.Duration NextTick time.Duration // time until next tick } // Tick advances the buff by dt. Returns damage/heal to apply this tick (0 if no tick). func (b *ActiveBuff) Tick(dt time.Duration) int32 { b.Remaining -= dt var tickValue int32 if b.TickInterval > 0 { b.NextTick -= dt if b.NextTick <= 0 { tickValue = b.Def.DamagePerTick b.NextTick += b.TickInterval } } return tickValue } // IsExpired returns true if the buff has no remaining duration. func (b *ActiveBuff) IsExpired() bool { return b.Remaining <= 0 } // BuffRegistry holds all buff/debuff definitions. type BuffRegistry struct { buffs map[uint32]*BuffDef } // NewBuffRegistry creates a registry with default buffs. func NewBuffRegistry() *BuffRegistry { r := &BuffRegistry{buffs: make(map[uint32]*BuffDef)} r.registerDefaults() return r } // Get returns a buff definition. func (r *BuffRegistry) Get(id uint32) *BuffDef { return r.buffs[id] } func (r *BuffRegistry) registerDefaults() { // Poison DoT (referenced by skill ID 5, effect Value=1) r.buffs[1] = &BuffDef{ ID: 1, Name: "Poison", IsDebuff: true, DamagePerTick: 8, } // Power Up buff (referenced by skill ID 6, effect Value=2) r.buffs[2] = &BuffDef{ ID: 2, Name: "Power Up", IsDebuff: false, StatModifier: StatMod{ StrBonus: 20, }, } }