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.

131 lines
4.4 KiB
Go

package model
// EnemyType names an archetype family (legacy consts for tuning / combat branches).
type EnemyType string
const (
EnemyWolf EnemyType = "wolf"
EnemyBoar EnemyType = "boar"
EnemyZombie EnemyType = "zombie"
EnemySpider EnemyType = "spider"
EnemyOrc EnemyType = "orc"
EnemySkeletonArcher EnemyType = "skeleton_archer"
EnemyBattleLizard EnemyType = "battle_lizard"
EnemyFireDemon EnemyType = "fire_demon"
EnemyIceGuardian EnemyType = "ice_guardian"
EnemySkeletonKing EnemyType = "skeleton_king"
EnemyWaterElement EnemyType = "water_element"
EnemyForestWarden EnemyType = "forest_warden"
EnemyLightningTitan EnemyType = "lightning_titan"
)
type SpecialAbility string
const (
AbilityBurn SpecialAbility = "burn"
AbilitySlow SpecialAbility = "slow"
AbilityCritical SpecialAbility = "critical"
AbilityPoison SpecialAbility = "poison"
AbilityFreeze SpecialAbility = "freeze"
AbilityIceSlow SpecialAbility = "ice_slow"
AbilityStun SpecialAbility = "stun"
AbilityDodge SpecialAbility = "dodge"
AbilityRegen SpecialAbility = "regen"
AbilityBurst SpecialAbility = "burst"
AbilityChainLightning SpecialAbility = "chain_lightning"
AbilitySummon SpecialAbility = "summon"
)
// Enemy is a DB template row or a runtime-scaled instance.
// Slug is the unique `enemies.type` column (JSON "type" for API — visual key).
// Archetype groups templates for quests and some combat logic.
type Enemy struct {
ID int64 `json:"id"`
Slug string `json:"type"` // DB `type` — unique template key
Archetype string `json:"archetype"`
Biome string `json:"biome,omitempty"` // canonical world band id (e.g. meadow, forest)
Name string `json:"name"`
HP int `json:"hp"`
MaxHP int `json:"maxHp"`
Attack int `json:"attack"`
Defense int `json:"defense"`
Speed float64 `json:"speed"`
CritChance float64 `json:"critChance"`
MinLevel int `json:"minLevel"`
MaxLevel int `json:"maxLevel"`
BaseLevel int `json:"baseLevel"`
LevelVariance float64 `json:"levelVariance"`
MaxHeroLevelDiff int `json:"maxHeroLevelDiff"`
HPPerLevel float64 `json:"hpPerLevel"`
AttackPerLevel float64 `json:"attackPerLevel"`
DefensePerLevel float64 `json:"defensePerLevel"`
XPPerLevel float64 `json:"xpPerLevel"`
GoldPerLevel float64 `json:"goldPerLevel"`
Level int `json:"level,omitempty"`
XPReward int64 `json:"xpReward"`
GoldReward int64 `json:"goldReward"`
SpecialAbilities []SpecialAbility `json:"specialAbilities,omitempty"`
IsElite bool `json:"isElite"`
AttackCount int `json:"-"`
}
func (e *Enemy) IsAlive() bool {
return e.HP > 0
}
func (e *Enemy) HasAbility(a SpecialAbility) bool {
for _, ab := range e.SpecialAbilities {
if ab == a {
return true
}
}
return false
}
// EnemyTemplates is all rows loaded from DB (order undefined).
var EnemyTemplates []Enemy
var enemyTemplatesBySlug map[string]Enemy
// SetEnemyTemplates replaces global templates and rebuilds slug index.
func SetEnemyTemplates(next []Enemy) {
EnemyTemplates = next
m := make(map[string]Enemy, len(next))
for _, e := range next {
if e.Slug != "" {
m[e.Slug] = e
}
}
enemyTemplatesBySlug = m
}
// EnemyBySlug returns a template by DB `type` (slug).
func EnemyBySlug(slug string) (Enemy, bool) {
if enemyTemplatesBySlug == nil {
return Enemy{}, false
}
e, ok := enemyTemplatesBySlug[slug]
return e, ok
}
// TemplatesByArchetype returns templates with the given archetype.
func TemplatesByArchetype(archetype string) []Enemy {
var out []Enemy
for _, e := range EnemyTemplates {
if e.Archetype == archetype {
out = append(out, e)
}
}
return out
}
// FirstTemplateByArchetype returns one template for archetype-keyed logic (e.g. loot/sim).
func FirstTemplateByArchetype(archetype string) (Enemy, bool) {
for _, e := range EnemyTemplates {
if e.Archetype == archetype {
return e, true
}
}
return Enemy{}, false
}