diff options
| author | historia <[not public]> | 2026-06-09 05:59:20 -0400 |
|---|---|---|
| committer | historia <[not public]> | 2026-06-09 05:59:20 -0400 |
| commit | 9eb5ab1818b6b19501fd7209db1987c9e06cc919 (patch) | |
| tree | 76e046b0bf611dfe939a8c8f6507467de2e9e20f /internal/combat | |
| download | thehouseoficarus-9eb5ab1818b6b19501fd7209db1987c9e06cc919.tar.gz | |
first commit
Diffstat (limited to 'internal/combat')
| -rw-r--r-- | internal/combat/formulas.go | 52 | ||||
| -rw-r--r-- | internal/combat/state.go | 89 |
2 files changed, 141 insertions, 0 deletions
diff --git a/internal/combat/formulas.go b/internal/combat/formulas.go new file mode 100644 index 0000000..0b3248b --- /dev/null +++ b/internal/combat/formulas.go @@ -0,0 +1,52 @@ +package combat + +import "math/rand" + +func AttackRoll(attackLevel int, styleBonus int, equipBonus int) int { + return (attackLevel + styleBonus + 8) * (equipBonus + 64) +} + +func DefenseRoll(defenseLevel int, styleBonus int, equipBonus int) int { + return (defenseLevel + styleBonus + 8) * (equipBonus + 64) +} + +func HitCheck(attackRoll, defenseRoll int) bool { + if attackRoll > defenseRoll { + return true + } + if attackRoll < defenseRoll { + return false + } + return rand.Intn(2) == 1 +} + +func MaxHit(strengthLevel int, styleBonus int, equipBonus int) int { + effective := (strengthLevel + styleBonus + 8) * (equipBonus + 64) + hit := effective / 512 + if hit < 1 { + hit = 1 + } + return hit +} + +func RollDamage(maxHit int) int { + if maxHit <= 0 { + return 0 + } + return 1 + rand.Intn(maxHit) +} + +func AttackStyleBonus(style string) (attack, strength, defense int) { + switch style { + case "accurate": + return 3, 0, 0 + case "aggressive": + return 0, 3, 0 + case "defensive": + return 0, 0, 3 + case "balanced": + return 1, 1, 1 + default: + return 0, 0, 0 + } +} diff --git a/internal/combat/state.go b/internal/combat/state.go new file mode 100644 index 0000000..b0e7dfe --- /dev/null +++ b/internal/combat/state.go @@ -0,0 +1,89 @@ +package combat + +import "sync" + +type State struct { + PlayerName string + MobID string + MobAttacks int // attacks mob has made (3-hit flee rule) + PlayerDamage int // total damage player dealt this combat + Active bool +} + +var ( + mu sync.Mutex + combatants = make(map[string]*State) // player name -> state + mobTargets = make(map[string]string) // mob ID -> player name +) + +func EnterCombat(playerName, mobID string) { + mu.Lock() + defer mu.Unlock() + combatants[playerName] = &State{ + PlayerName: playerName, + MobID: mobID, + Active: true, + } + mobTargets[mobID] = playerName +} + +func LeaveCombat(playerName string) { + mu.Lock() + defer mu.Unlock() + state, ok := combatants[playerName] + if !ok { + return + } + delete(mobTargets, state.MobID) + delete(combatants, playerName) +} + +func GetCombat(playerName string) *State { + mu.Lock() + defer mu.Unlock() + return combatants[playerName] +} + +func IsMobInCombat(mobID string) bool { + mu.Lock() + defer mu.Unlock() + _, ok := mobTargets[mobID] + return ok +} + +func RecordMobAttack(playerName string) { + mu.Lock() + defer mu.Unlock() + if state, ok := combatants[playerName]; ok { + state.MobAttacks++ + } +} + +func CanFlee(playerName string) bool { + mu.Lock() + defer mu.Unlock() + state, ok := combatants[playerName] + if !ok { + return true + } + return state.MobAttacks >= 3 +} + +func RecordPlayerDamage(playerName string, dmg int) { + mu.Lock() + defer mu.Unlock() + if state, ok := combatants[playerName]; ok { + state.PlayerDamage += dmg + } +} + +func GetTotalDamage(playerName string) int { + mu.Lock() + defer mu.Unlock() + if state, ok := combatants[playerName]; ok { + d := state.PlayerDamage + state.PlayerDamage = 0 + return d + } + return 0 +} |
