aboutsummaryrefslogtreecommitdiff
path: root/internal/game/cmd_trigger_combat.go
diff options
context:
space:
mode:
authorhistoria <[not public]>2026-07-01 22:30:31 -0400
committerhistoria <[not public]>2026-07-01 22:30:31 -0400
commitc14c2e403c75a913e1a6d962fb6fe64f013adae5 (patch)
tree75070293fe2535b594ac72e501cbf08a3f1146e0 /internal/game/cmd_trigger_combat.go
parent8eec7b75ff9c8c368b252373db45fb891732d2ca (diff)
downloadthehouseoficarus-c14c2e403c75a913e1a6d962fb6fe64f013adae5.tar.gz
fix: combat formulas and mob attack types (mobs switch attack styles if safespotting)
Diffstat (limited to 'internal/game/cmd_trigger_combat.go')
-rw-r--r--internal/game/cmd_trigger_combat.go34
1 files changed, 28 insertions, 6 deletions
diff --git a/internal/game/cmd_trigger_combat.go b/internal/game/cmd_trigger_combat.go
index cce9781..ecb4fbb 100644
--- a/internal/game/cmd_trigger_combat.go
+++ b/internal/game/cmd_trigger_combat.go
@@ -10,6 +10,14 @@ import (
"thehouseoficarus/internal/world"
)
+// scienceAttack resolves a player science-mod attack against a mob.
+//
+// Unlike melee/ranged (which roll the player's accuracy vs the mob's Defense),
+// science uses a symmetric science-vs-science model: both the attack roll and
+// the mob's defense roll use ScienceEffective, keyed off the player's Science
+// level and the mob's Science stat (plus ScienceDefense) respectively — the
+// mob's Defense stat is not involved. Science has no attack styles, so no style
+// bonus applies.
func (g *Game) scienceAttack(sess *net.Session, p *player.Player, mob *world.MobInstance, mod *ModDef) bool {
if p.Level(player.Science) < mod.Level {
sess.WriteLine(fmt.Sprintf("You need level %d science to trigger %s.", mod.Level, mod.Name))
@@ -24,17 +32,31 @@ func (g *Game) scienceAttack(sess *net.Session, p *player.Player, mob *world.Mob
equipSciBonus := g.totalScienceAttack(p)
effectiveScience := p.Level(player.Science) + g.techLevelBonus(p, "science") + g.buffLevelBonus(p, "science")
- attRoll := combat.EffectiveRoll(effectiveScience, 0, equipSciBonus)
+ attRoll := combat.AttackRoll(combat.ScienceEffective(effectiveScience), equipSciBonus)
- mobSciDef := mob.ScienceDefense
- defRoll := combat.EffectiveRoll(mob.Defense, 0, mobSciDef)
+ defRoll := combat.AttackRoll(combat.ScienceEffective(mob.Science), mob.ScienceDefense)
- if mob.Weakness == mod.Element {
- attRoll = attRoll * 13 / 10
+ if mob.Weakness == mod.Element && mob.WeaknessPercent > 0 {
+ attRoll = int(float64(attRoll) * (1.0 + float64(mob.WeaknessPercent)/100.0))
}
if combat.HitCheck(attRoll, defRoll) {
- dmg := combat.RollDamage(mod.MaxHit)
+ totals := g.playerEquipBonuses(p)
+ maxHit := mod.MaxHit
+ if totals.ScienceDamage > 0 {
+ maxHit = int(float64(maxHit) * (1.0 + float64(totals.ScienceDamage)/100.0))
+ }
+ // Weakness is an additive bonus computed off the mod's base MaxHit (not
+ // the science-damage-boosted maxHit), so equipment and weakness stack
+ // additively. With no science-damage gear this equals a ×(1+pct) boost,
+ // matching the multiplicative weakness applied to the attack roll above.
+ if mob.Weakness == mod.Element && mob.WeaknessPercent > 0 {
+ maxHit += int(float64(mod.MaxHit) * float64(mob.WeaknessPercent) / 100.0)
+ }
+ if maxHit < 1 {
+ maxHit = 1
+ }
+ dmg := combat.RollDamage(maxHit)
if dmg < 0 {
dmg = 0
}