You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
192 lines
5.7 KiB
Go
192 lines
5.7 KiB
Go
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
|
|
}
|