reimplement fight action flashes
This commit is contained in:
parent
ef95b70eb9
commit
63dabb9e54
@ -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) },
|
||||
}
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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 {
|
||||
|
@ -28,7 +28,6 @@
|
||||
<section>
|
||||
<h5>Town Maps</h5>
|
||||
{if #_towns > 0}
|
||||
<i>Teleport to:</i>
|
||||
{for t in _towns}
|
||||
{if town != nil and t.Name == town.Name}
|
||||
<span>{t.Name} <i>(here)</i></span>
|
||||
|
Loading…
x
Reference in New Issue
Block a user