From 63dabb9e5466235113c63bce8e557e10b4972b42 Mon Sep 17 00:00:00 2001 From: Sky Johnson Date: Mon, 25 Aug 2025 22:12:20 -0500 Subject: [PATCH] reimplement fight action flashes --- internal/actions/fight.go | 37 ++++++++++++++++++++++++++++++------- internal/routes/fight.go | 31 +++++++++++++++++++++++++++---- internal/routes/index.go | 2 +- templates/leftside.html | 1 - 4 files changed, 58 insertions(+), 13 deletions(-) diff --git a/internal/actions/fight.go b/internal/actions/fight.go index f41e75c..c969906 100644 --- a/internal/actions/fight.go +++ b/internal/actions/fight.go @@ -9,6 +9,7 @@ import ( "dk/internal/models/spells" "dk/internal/models/towns" "dk/internal/models/users" + "fmt" "math" "math/rand" ) @@ -17,6 +18,7 @@ type FightResult struct { FightUpdates map[string]any UserUpdates map[string]any LogAction func() error + ActionText string // Add this field Ended bool Victory bool Won bool @@ -55,7 +57,8 @@ func HandleAttack(fight *fights.Fight, user *users.User) *FightResult { monster, err := monsters.Find(fight.MonsterID) if err != nil { return &FightResult{ - LogAction: func() error { return fightlogs.AddAction(fight.ID, "Monster not found!") }, + LogAction: func() error { return fightlogs.AddAction(fight.ID, "Monster not found!") }, + ActionText: "Monster not found!", } } @@ -66,9 +69,13 @@ func HandleAttack(fight *fights.Fight, user *users.User) *FightResult { rawAttack := math.Ceil(rand.Float64()*(maxAttack-minAttack) + minAttack) tohit := rawAttack / (1.2 + math.Sqrt(attackPower)*0.05) + damageMultiplier := 1 + math.Pow(float64(user.Attack)/400, 0.6) + tohit *= damageMultiplier + // Critical hit - criticalRoll := rand.Intn(150) + 1 - if float64(criticalRoll) <= math.Sqrt(float64(user.Strength)) { + critChance := 85 * math.Pow(float64(user.Strength)/300, 0.6) + criticalRoll := rand.Float64() * 100 + if criticalRoll <= critChance { tohit *= 2 } @@ -92,14 +99,18 @@ func HandleAttack(fight *fights.Fight, user *users.User) *FightResult { finalDamage := int(damage) newMonsterHP := max(fight.MonsterHP-finalDamage, 0) + actionText := fmt.Sprintf("You attacked for %d damage!", finalDamage) + result := &FightResult{ FightUpdates: map[string]any{"monster_hp": newMonsterHP}, LogAction: func() error { return fightlogs.AddAttackHit(fight.ID, finalDamage) }, + ActionText: actionText, } // Check if monster defeated if newMonsterHP <= 0 { result.EndFightWithVictory(monster, user) + result.ActionText = actionText + " " + fmt.Sprintf("%s has been defeated!", monster.Name) result.LogAction = func() error { if err := fightlogs.AddAttackHit(fight.ID, finalDamage); err != nil { return err @@ -115,19 +126,24 @@ func HandleSpell(fight *fights.Fight, user *users.User, spellID int) *FightResul spell, err := spells.Find(spellID) if err != nil { return &FightResult{ - LogAction: func() error { return fightlogs.AddAction(fight.ID, "Spell not found!") }, + LogAction: func() error { return fightlogs.AddAction(fight.ID, "Spell not found!") }, + ActionText: "Spell not found!", } } if user.MP < spell.MP { + actionText := "Not enough MP to cast " + spell.Name + "!" return &FightResult{ - LogAction: func() error { return fightlogs.AddAction(fight.ID, "Not enough MP to cast "+spell.Name+"!") }, + LogAction: func() error { return fightlogs.AddAction(fight.ID, actionText) }, + ActionText: actionText, } } if !user.HasSpell(spellID) { + actionText := "You don't know that spell!" return &FightResult{ - LogAction: func() error { return fightlogs.AddAction(fight.ID, "You don't know that spell!") }, + LogAction: func() error { return fightlogs.AddAction(fight.ID, actionText) }, + ActionText: actionText, } } @@ -139,22 +155,26 @@ func HandleSpell(fight *fights.Fight, user *users.User, spellID int) *FightResul case spells.TypeHealing: newHP := min(user.HP+spell.Attribute, user.MaxHP) result.UserUpdates["hp"] = newHP + result.ActionText = fmt.Sprintf("You cast %s and healed %d HP!", spell.Name, spell.Attribute) result.LogAction = func() error { return fightlogs.AddSpellHeal(fight.ID, spell.Name, spell.Attribute) } case spells.TypeHurt: newMonsterHP := max(fight.MonsterHP-spell.Attribute, 0) result.FightUpdates = map[string]any{"monster_hp": newMonsterHP} + result.ActionText = fmt.Sprintf("You cast %s and dealt %d damage!", spell.Name, spell.Attribute) result.LogAction = func() error { return fightlogs.AddSpellHurt(fight.ID, spell.Name, spell.Attribute) } if newMonsterHP <= 0 { monster, err := monsters.Find(fight.MonsterID) if err == nil { result.EndFightWithVictory(monster, user) + result.ActionText += " " + fmt.Sprintf("%s has been defeated!", monster.Name) } } default: - result.LogAction = func() error { return fightlogs.AddAction(fight.ID, "You cast "+spell.Name+" but nothing happened!") } + result.ActionText = "You cast " + spell.Name + " but nothing happened!" + result.LogAction = func() error { return fightlogs.AddAction(fight.ID, result.ActionText) } } return result @@ -169,9 +189,11 @@ func HandleRun(fight *fights.Fight, user *users.User) *FightResult { "fight_id": 0, "currently": "Exploring", } + result.ActionText = "You successfully ran away!" result.LogAction = func() error { return fightlogs.AddRunSuccess(fight.ID) } result.Ended = true } else { + result.ActionText = "You failed to run away!" result.LogAction = func() error { return fightlogs.AddRunFail(fight.ID) } } @@ -213,6 +235,7 @@ func HandleMonsterAttack(fight *fights.Fight, user *users.User) *FightResult { result := &FightResult{ UserUpdates: map[string]any{"hp": newHP}, + ActionText: fmt.Sprintf("%s attacks for %d damage!", monster.Name, finalDamage), LogAction: func() error { return fightlogs.AddMonsterAttack(fight.ID, monster.Name, finalDamage) }, } diff --git a/internal/routes/fight.go b/internal/routes/fight.go index 451f41c..d40f28c 100644 --- a/internal/routes/fight.go +++ b/internal/routes/fight.go @@ -65,8 +65,10 @@ func showFight(ctx sushi.Ctx) { if fight.Turn == 0 { err := database.Transaction(func() error { return database.Update("fights", map[string]any{ - "first_strike": rand.Float32() < 0.5, - "turn": 1, + "first_strike": rand.Float32() < 0.5, + "turn": 1, + "monster_hp": monster.MaxHP, + "monster_max_hp": monster.MaxHP, }, "id", fight.ID) }) if err != nil { @@ -75,6 +77,8 @@ func showFight(ctx sushi.Ctx) { } fight.FirstStrike = rand.Float32() < 0.5 fight.Turn = 1 + fight.MonsterHP = monster.MaxHP + fight.MonsterMaxHP = monster.MaxHP } monHpPct := helpers.ClampPct(float64(fight.MonsterHP), float64(fight.MonsterMaxHP), 0, 100) @@ -133,14 +137,16 @@ func handleFightAction(ctx sushi.Ctx) { result = actions.HandleSpell(fight, user, spellID) } else { result = &actions.FightResult{ - LogAction: func() error { return fightlogs.AddAction(fight.ID, "Invalid spell!") }, + LogAction: func() error { return fightlogs.AddAction(fight.ID, "Invalid spell!") }, + ActionText: "Invalid spell!", } } case "run": result = actions.HandleRun(fight, user) default: result = &actions.FightResult{ - LogAction: func() error { return fightlogs.AddAction(fight.ID, "Invalid action!") }, + LogAction: func() error { return fightlogs.AddAction(fight.ID, "Invalid action!") }, + ActionText: "Invalid action!", } } @@ -151,6 +157,11 @@ func handleFightAction(ctx sushi.Ctx) { return } + // Flash player action + if result.ActionText != "" { + sess.SetFlash("action", result.ActionText) + } + // Handle fight end states if result.Ended { if result.Won { @@ -169,6 +180,13 @@ func handleFightAction(ctx sushi.Ctx) { // Monster attacks back if fight continues if fight.IsActive() && user.HP > 0 { + // Refresh user data after player action + user, err = users.Find(user.ID) + if err != nil { + ctx.SendError(500, "Failed to refresh user data") + return + } + monsterResult := actions.HandleMonsterAttack(fight, user) // Execute monster action @@ -178,6 +196,11 @@ func handleFightAction(ctx sushi.Ctx) { return } + // Flash monster action + if monsterResult.ActionText != "" { + sess.SetFlash("mon_action", monsterResult.ActionText) + } + // Check if monster action ended fight if monsterResult.Ended { if monsterResult.Won { diff --git a/internal/routes/index.go b/internal/routes/index.go index 5354fb0..f8d306f 100644 --- a/internal/routes/index.go +++ b/internal/routes/index.go @@ -95,7 +95,7 @@ func Explore(ctx sushi.Ctx) { func Teleport(ctx sushi.Ctx) { sess := ctx.GetCurrentSession() - id := ctx.Param("id").Int() + id := ctx.Param("to").Int() town, err := towns.Find(id) if err != nil { diff --git a/templates/leftside.html b/templates/leftside.html index 6749414..de1871c 100644 --- a/templates/leftside.html +++ b/templates/leftside.html @@ -28,7 +28,6 @@
Town Maps
{if #_towns > 0} - Teleport to: {for t in _towns} {if town != nil and t.Name == town.Name} {t.Name} (here)