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/spells"
|
||||||
"dk/internal/models/towns"
|
"dk/internal/models/towns"
|
||||||
"dk/internal/models/users"
|
"dk/internal/models/users"
|
||||||
|
"fmt"
|
||||||
"math"
|
"math"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
)
|
)
|
||||||
@ -17,6 +18,7 @@ type FightResult struct {
|
|||||||
FightUpdates map[string]any
|
FightUpdates map[string]any
|
||||||
UserUpdates map[string]any
|
UserUpdates map[string]any
|
||||||
LogAction func() error
|
LogAction func() error
|
||||||
|
ActionText string // Add this field
|
||||||
Ended bool
|
Ended bool
|
||||||
Victory bool
|
Victory bool
|
||||||
Won bool
|
Won bool
|
||||||
@ -55,7 +57,8 @@ func HandleAttack(fight *fights.Fight, user *users.User) *FightResult {
|
|||||||
monster, err := monsters.Find(fight.MonsterID)
|
monster, err := monsters.Find(fight.MonsterID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return &FightResult{
|
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)
|
rawAttack := math.Ceil(rand.Float64()*(maxAttack-minAttack) + minAttack)
|
||||||
tohit := rawAttack / (1.2 + math.Sqrt(attackPower)*0.05)
|
tohit := rawAttack / (1.2 + math.Sqrt(attackPower)*0.05)
|
||||||
|
|
||||||
|
damageMultiplier := 1 + math.Pow(float64(user.Attack)/400, 0.6)
|
||||||
|
tohit *= damageMultiplier
|
||||||
|
|
||||||
// Critical hit
|
// Critical hit
|
||||||
criticalRoll := rand.Intn(150) + 1
|
critChance := 85 * math.Pow(float64(user.Strength)/300, 0.6)
|
||||||
if float64(criticalRoll) <= math.Sqrt(float64(user.Strength)) {
|
criticalRoll := rand.Float64() * 100
|
||||||
|
if criticalRoll <= critChance {
|
||||||
tohit *= 2
|
tohit *= 2
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -92,14 +99,18 @@ func HandleAttack(fight *fights.Fight, user *users.User) *FightResult {
|
|||||||
finalDamage := int(damage)
|
finalDamage := int(damage)
|
||||||
newMonsterHP := max(fight.MonsterHP-finalDamage, 0)
|
newMonsterHP := max(fight.MonsterHP-finalDamage, 0)
|
||||||
|
|
||||||
|
actionText := fmt.Sprintf("You attacked for %d damage!", finalDamage)
|
||||||
|
|
||||||
result := &FightResult{
|
result := &FightResult{
|
||||||
FightUpdates: map[string]any{"monster_hp": newMonsterHP},
|
FightUpdates: map[string]any{"monster_hp": newMonsterHP},
|
||||||
LogAction: func() error { return fightlogs.AddAttackHit(fight.ID, finalDamage) },
|
LogAction: func() error { return fightlogs.AddAttackHit(fight.ID, finalDamage) },
|
||||||
|
ActionText: actionText,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if monster defeated
|
// Check if monster defeated
|
||||||
if newMonsterHP <= 0 {
|
if newMonsterHP <= 0 {
|
||||||
result.EndFightWithVictory(monster, user)
|
result.EndFightWithVictory(monster, user)
|
||||||
|
result.ActionText = actionText + " " + fmt.Sprintf("%s has been defeated!", monster.Name)
|
||||||
result.LogAction = func() error {
|
result.LogAction = func() error {
|
||||||
if err := fightlogs.AddAttackHit(fight.ID, finalDamage); err != nil {
|
if err := fightlogs.AddAttackHit(fight.ID, finalDamage); err != nil {
|
||||||
return err
|
return err
|
||||||
@ -115,19 +126,24 @@ func HandleSpell(fight *fights.Fight, user *users.User, spellID int) *FightResul
|
|||||||
spell, err := spells.Find(spellID)
|
spell, err := spells.Find(spellID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return &FightResult{
|
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 {
|
if user.MP < spell.MP {
|
||||||
|
actionText := "Not enough MP to cast " + spell.Name + "!"
|
||||||
return &FightResult{
|
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) {
|
if !user.HasSpell(spellID) {
|
||||||
|
actionText := "You don't know that spell!"
|
||||||
return &FightResult{
|
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:
|
case spells.TypeHealing:
|
||||||
newHP := min(user.HP+spell.Attribute, user.MaxHP)
|
newHP := min(user.HP+spell.Attribute, user.MaxHP)
|
||||||
result.UserUpdates["hp"] = newHP
|
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) }
|
result.LogAction = func() error { return fightlogs.AddSpellHeal(fight.ID, spell.Name, spell.Attribute) }
|
||||||
|
|
||||||
case spells.TypeHurt:
|
case spells.TypeHurt:
|
||||||
newMonsterHP := max(fight.MonsterHP-spell.Attribute, 0)
|
newMonsterHP := max(fight.MonsterHP-spell.Attribute, 0)
|
||||||
result.FightUpdates = map[string]any{"monster_hp": newMonsterHP}
|
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) }
|
result.LogAction = func() error { return fightlogs.AddSpellHurt(fight.ID, spell.Name, spell.Attribute) }
|
||||||
|
|
||||||
if newMonsterHP <= 0 {
|
if newMonsterHP <= 0 {
|
||||||
monster, err := monsters.Find(fight.MonsterID)
|
monster, err := monsters.Find(fight.MonsterID)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
result.EndFightWithVictory(monster, user)
|
result.EndFightWithVictory(monster, user)
|
||||||
|
result.ActionText += " " + fmt.Sprintf("%s has been defeated!", monster.Name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
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
|
return result
|
||||||
@ -169,9 +189,11 @@ func HandleRun(fight *fights.Fight, user *users.User) *FightResult {
|
|||||||
"fight_id": 0,
|
"fight_id": 0,
|
||||||
"currently": "Exploring",
|
"currently": "Exploring",
|
||||||
}
|
}
|
||||||
|
result.ActionText = "You successfully ran away!"
|
||||||
result.LogAction = func() error { return fightlogs.AddRunSuccess(fight.ID) }
|
result.LogAction = func() error { return fightlogs.AddRunSuccess(fight.ID) }
|
||||||
result.Ended = true
|
result.Ended = true
|
||||||
} else {
|
} else {
|
||||||
|
result.ActionText = "You failed to run away!"
|
||||||
result.LogAction = func() error { return fightlogs.AddRunFail(fight.ID) }
|
result.LogAction = func() error { return fightlogs.AddRunFail(fight.ID) }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -213,6 +235,7 @@ func HandleMonsterAttack(fight *fights.Fight, user *users.User) *FightResult {
|
|||||||
|
|
||||||
result := &FightResult{
|
result := &FightResult{
|
||||||
UserUpdates: map[string]any{"hp": newHP},
|
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) },
|
LogAction: func() error { return fightlogs.AddMonsterAttack(fight.ID, monster.Name, finalDamage) },
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,8 +65,10 @@ func showFight(ctx sushi.Ctx) {
|
|||||||
if fight.Turn == 0 {
|
if fight.Turn == 0 {
|
||||||
err := database.Transaction(func() error {
|
err := database.Transaction(func() error {
|
||||||
return database.Update("fights", map[string]any{
|
return database.Update("fights", map[string]any{
|
||||||
"first_strike": rand.Float32() < 0.5,
|
"first_strike": rand.Float32() < 0.5,
|
||||||
"turn": 1,
|
"turn": 1,
|
||||||
|
"monster_hp": monster.MaxHP,
|
||||||
|
"monster_max_hp": monster.MaxHP,
|
||||||
}, "id", fight.ID)
|
}, "id", fight.ID)
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -75,6 +77,8 @@ func showFight(ctx sushi.Ctx) {
|
|||||||
}
|
}
|
||||||
fight.FirstStrike = rand.Float32() < 0.5
|
fight.FirstStrike = rand.Float32() < 0.5
|
||||||
fight.Turn = 1
|
fight.Turn = 1
|
||||||
|
fight.MonsterHP = monster.MaxHP
|
||||||
|
fight.MonsterMaxHP = monster.MaxHP
|
||||||
}
|
}
|
||||||
|
|
||||||
monHpPct := helpers.ClampPct(float64(fight.MonsterHP), float64(fight.MonsterMaxHP), 0, 100)
|
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)
|
result = actions.HandleSpell(fight, user, spellID)
|
||||||
} else {
|
} else {
|
||||||
result = &actions.FightResult{
|
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":
|
case "run":
|
||||||
result = actions.HandleRun(fight, user)
|
result = actions.HandleRun(fight, user)
|
||||||
default:
|
default:
|
||||||
result = &actions.FightResult{
|
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
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Flash player action
|
||||||
|
if result.ActionText != "" {
|
||||||
|
sess.SetFlash("action", result.ActionText)
|
||||||
|
}
|
||||||
|
|
||||||
// Handle fight end states
|
// Handle fight end states
|
||||||
if result.Ended {
|
if result.Ended {
|
||||||
if result.Won {
|
if result.Won {
|
||||||
@ -169,6 +180,13 @@ func handleFightAction(ctx sushi.Ctx) {
|
|||||||
|
|
||||||
// Monster attacks back if fight continues
|
// Monster attacks back if fight continues
|
||||||
if fight.IsActive() && user.HP > 0 {
|
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)
|
monsterResult := actions.HandleMonsterAttack(fight, user)
|
||||||
|
|
||||||
// Execute monster action
|
// Execute monster action
|
||||||
@ -178,6 +196,11 @@ func handleFightAction(ctx sushi.Ctx) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Flash monster action
|
||||||
|
if monsterResult.ActionText != "" {
|
||||||
|
sess.SetFlash("mon_action", monsterResult.ActionText)
|
||||||
|
}
|
||||||
|
|
||||||
// Check if monster action ended fight
|
// Check if monster action ended fight
|
||||||
if monsterResult.Ended {
|
if monsterResult.Ended {
|
||||||
if monsterResult.Won {
|
if monsterResult.Won {
|
||||||
|
@ -95,7 +95,7 @@ func Explore(ctx sushi.Ctx) {
|
|||||||
func Teleport(ctx sushi.Ctx) {
|
func Teleport(ctx sushi.Ctx) {
|
||||||
sess := ctx.GetCurrentSession()
|
sess := ctx.GetCurrentSession()
|
||||||
|
|
||||||
id := ctx.Param("id").Int()
|
id := ctx.Param("to").Int()
|
||||||
|
|
||||||
town, err := towns.Find(id)
|
town, err := towns.Find(id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -28,7 +28,6 @@
|
|||||||
<section>
|
<section>
|
||||||
<h5>Town Maps</h5>
|
<h5>Town Maps</h5>
|
||||||
{if #_towns > 0}
|
{if #_towns > 0}
|
||||||
<i>Teleport to:</i>
|
|
||||||
{for t in _towns}
|
{for t in _towns}
|
||||||
{if town != nil and t.Name == town.Name}
|
{if town != nil and t.Name == town.Name}
|
||||||
<span>{t.Name} <i>(here)</i></span>
|
<span>{t.Name} <i>(here)</i></span>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user