package model import "time" // ---- Buffs ---- type BuffType string const ( BuffRush BuffType = "rush" // +attack speed BuffRage BuffType = "rage" // +damage BuffShield BuffType = "shield" // -incoming damage BuffLuck BuffType = "luck" // x2.5 loot BuffResurrection BuffType = "resurrection" // revive on death BuffHeal BuffType = "heal" // +50% HP instantly BuffPowerPotion BuffType = "power_potion" // +150% damage BuffWarCry BuffType = "war_cry" // +100% attack speed ) // AllBuffTypes is the complete list of valid buff types. var AllBuffTypes = []BuffType{ BuffRush, BuffRage, BuffShield, BuffLuck, BuffResurrection, BuffHeal, BuffPowerPotion, BuffWarCry, } // ValidBuffType checks if a string is a valid buff type. func ValidBuffType(s string) (BuffType, bool) { bt := BuffType(s) for _, t := range AllBuffTypes { if t == bt { return bt, true } } return "", false } type Buff struct { ID int64 `json:"id"` Type BuffType `json:"type"` Name string `json:"name"` Duration time.Duration `json:"duration"` Magnitude float64 `json:"magnitude"` // effect strength (e.g., 0.3 = +30%) CooldownDuration time.Duration `json:"cooldownDuration"` } type ActiveBuff struct { Buff Buff `json:"buff"` AppliedAt time.Time `json:"appliedAt"` ExpiresAt time.Time `json:"expiresAt"` } // IsExpired returns true if the buff has expired relative to the given time. func (ab *ActiveBuff) IsExpired(now time.Time) bool { return now.After(ab.ExpiresAt) } // DefaultBuffs defines the base buff definitions. var DefaultBuffs = map[BuffType]Buff{ BuffRush: { Type: BuffRush, Name: "Rush", Duration: 5 * time.Minute, Magnitude: 0.5, // +50% movement CooldownDuration: 15 * time.Minute, }, BuffRage: { Type: BuffRage, Name: "Rage", Duration: 3 * time.Minute, Magnitude: 1.0, // +100% damage CooldownDuration: 10 * time.Minute, }, BuffShield: { Type: BuffShield, Name: "Shield", Duration: 5 * time.Minute, Magnitude: 0.5, // -50% incoming damage CooldownDuration: 12 * time.Minute, }, BuffLuck: { Type: BuffLuck, Name: "Luck", Duration: 30 * time.Minute, Magnitude: 1.5, // x2.5 loot CooldownDuration: 2 * time.Hour, }, BuffResurrection: { Type: BuffResurrection, Name: "Resurrection", Duration: 10 * time.Minute, Magnitude: 0.5, // revive with 50% HP CooldownDuration: 30 * time.Minute, }, BuffHeal: { Type: BuffHeal, Name: "Heal", Duration: 1 * time.Second, Magnitude: 0.5, // +50% HP (instant) CooldownDuration: 5 * time.Minute, }, BuffPowerPotion: { Type: BuffPowerPotion, Name: "Power Potion", Duration: 5 * time.Minute, Magnitude: 1.5, // +150% damage CooldownDuration: 20 * time.Minute, }, BuffWarCry: { Type: BuffWarCry, Name: "War Cry", Duration: 3 * time.Minute, Magnitude: 1.0, // +100% attack speed CooldownDuration: 10 * time.Minute, }, } // ---- Debuffs ---- type DebuffType string const ( DebuffPoison DebuffType = "poison" // -2% HP/sec DebuffFreeze DebuffType = "freeze" // -50% attack speed DebuffBurn DebuffType = "burn" // -3% HP/sec DebuffStun DebuffType = "stun" // no attacks for 2 sec DebuffSlow DebuffType = "slow" // -40% movement speed (not attack speed) DebuffWeaken DebuffType = "weaken" // -30% hero outgoing damage DebuffIceSlow DebuffType = "ice_slow" // -20% attack speed (Ice Guardian per spec §4.2) ) // AllDebuffTypes is the complete list of valid debuff types. var AllDebuffTypes = []DebuffType{ DebuffPoison, DebuffFreeze, DebuffBurn, DebuffStun, DebuffSlow, DebuffWeaken, DebuffIceSlow, } // ValidDebuffType checks if a string is a valid debuff type. func ValidDebuffType(s string) (DebuffType, bool) { dt := DebuffType(s) for _, t := range AllDebuffTypes { if t == dt { return dt, true } } return "", false } type Debuff struct { ID int64 `json:"id"` Type DebuffType `json:"type"` Name string `json:"name"` Duration time.Duration `json:"duration"` Magnitude float64 `json:"magnitude"` // effect strength } type ActiveDebuff struct { Debuff Debuff `json:"debuff"` AppliedAt time.Time `json:"appliedAt"` ExpiresAt time.Time `json:"expiresAt"` } // IsExpired returns true if the debuff has expired relative to the given time. func (ad *ActiveDebuff) IsExpired(now time.Time) bool { return now.After(ad.ExpiresAt) } // DefaultDebuffs defines the base debuff definitions. var DefaultDebuffs = map[DebuffType]Debuff{ DebuffPoison: { Type: DebuffPoison, Name: "Poison", Duration: 5 * time.Second, Magnitude: 0.02, // -2% HP/sec }, DebuffFreeze: { Type: DebuffFreeze, Name: "Freeze", Duration: 3 * time.Second, Magnitude: 0.50, // -50% attack speed }, DebuffBurn: { Type: DebuffBurn, Name: "Burn", Duration: 4 * time.Second, Magnitude: 0.03, // -3% HP/sec }, DebuffStun: { Type: DebuffStun, Name: "Stun", Duration: 2 * time.Second, Magnitude: 1.0, // no attacks }, DebuffSlow: { Type: DebuffSlow, Name: "Slow", Duration: 4 * time.Second, Magnitude: 0.40, // -40% movement }, DebuffWeaken: { Type: DebuffWeaken, Name: "Weaken", Duration: 5 * time.Second, Magnitude: 0.30, // -30% hero outgoing damage }, DebuffIceSlow: { Type: DebuffIceSlow, Name: "Ice Slow", Duration: 4 * time.Second, Magnitude: 0.20, // -20% attack speed (Ice Guardian spec §4.2) }, } // RemoveBuffType returns buffs without any active entry of the given type (e.g. consume Resurrection on manual revive). func RemoveBuffType(buff []ActiveBuff, remove BuffType) []ActiveBuff { var out []ActiveBuff for _, ab := range buff { if ab.Buff.Type != remove { out = append(out, ab) } } return out }