From 428861952017fffcab7f2e0395a8dc23a92ea783 Mon Sep 17 00:00:00 2001 From: Sky Johnson Date: Thu, 28 Aug 2025 17:25:24 -0500 Subject: [PATCH] fix lots of fight/level up components --- data/dk.db | Bin 98304 -> 98304 bytes internal/actions/fight.go | 21 ++++++++------- internal/components/asides.go | 10 +++++++ internal/models/users/users.go | 48 ++++++++++++++++++++++++--------- templates/rightside.html | 2 +- 5 files changed, 58 insertions(+), 23 deletions(-) diff --git a/data/dk.db b/data/dk.db index 14fe062219cda90815fb10c113417e1ff2701d65..3682e659fdb6f321935dbbb74276325bc7cb2ea0 100644 GIT binary patch delta 5802 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 delta 1134 zcmZvaO>7%Q6vyYyj_uh^c3+YuNn2XHj$O5gHY8Y06=+F{LrB`xv7CMgF0B(gv9S|V zyAI;g*e3)B8(5@(IP_46)B|dWL23_`5bC{^IH0yfLM;+KR4Nj;M5=h}*iMTW&3pUi zuiw1)W@d{;cd_VRed^`k-B`1D+pbTUhL;%rgMZ?Eyp6Z;242H&@e+PnZEu^#eoa+& z!fa|Tc`@%|jA?2uHZ;YzrJl=V=kmHLm2Q~L<_hz|zBUv^yw3!VGR)vl_yvwqssUUI z2$cz;s&e1XC* zfl#@X2gx_c{g)w(4z-uMl4_&g%7bQ=X0R4+J(Va=nCxo(A+;2de z{cL!f;ExN#o+)L z?Dsy;Zhp>wp<=-a`%uLThwank{dS?^2eiMg^l;d;Z<6$vywf z8*qc+Mz!5~g21X9w-0%PrBZ34bQ}(_&eG&QsXOPB@S=p~sE3k9=N{b|_Vg3~(%E=n za4Hx*lbTr^iG?HYyxX4}D9i<7??-~6{?qSejx7YIkM*7X=#~EXc<|MU^qE398jU5R zgX80wba*l{I}@jq4Lh!PCOc2}o}~xe!N(V@Q`rv}G}LHvZ>z?oi!1G+OksK|omyN> zCGr|Q#1--Pu;IcG!+ZE6RxpVn`gMA6;5C=YdJmFQK?N!O&4~JkZaSP4LK@0!ER#=A z!IO^d70W*#h0YFMQx%o8w;l5<%j-k1t3{#3TaE?za`8=gNnRbI)ldMIe>ehWP;uAx zaR)o%m`)Aq#wNqZ_#6I$-{V*K2^R1?j^QBs&@?uw*Sp42m+oP7&wGSRDkHgAI+4ld zXn&-&m2_3rh09rWwfrwNscQ}eL~+60*5X+?r4tID+TmsoG zM9Wk%7I&^8fuOk~f%9Q#8cwY@?=97nN->Wb(Smx5eQO@X*5mm8D)h LTg@C@i9p}K5U4b$ diff --git a/internal/actions/fight.go b/internal/actions/fight.go index b8c9c5d..f9570ac 100644 --- a/internal/actions/fight.go +++ b/internal/actions/fight.go @@ -9,6 +9,7 @@ import ( "dk/internal/models/towns" "dk/internal/models/users" "fmt" + "maps" "math" "math/rand" ) @@ -33,18 +34,18 @@ func (r *FightResult) EndFightWithVictory(monster *monsters.Monster, user *users r.FightUpdates["reward_gold"] = rewardGold r.FightUpdates["reward_exp"] = rewardExp - newLevel, newStr, newDex, newExp := user.CalculateLevelUp(rewardExp) + levelUpResults := user.GrantExp(rewardExp) - r.UserUpdates = map[string]any{ - "fight_id": 0, - "currently": "Exploring", - "gold": user.Gold + rewardGold, - "exp": newExp, - "level": newLevel, - "strength": newStr, - "dexterity": newDex, + if r.UserUpdates == nil { + r.UserUpdates = make(map[string]any) } + r.UserUpdates["fight_id"] = 0 + r.UserUpdates["currently"] = "Exploring" + r.UserUpdates["gold"] = user.Gold + rewardGold + + maps.Copy(r.UserUpdates, levelUpResults) + r.Ended = true r.Victory = true r.Won = true @@ -167,6 +168,7 @@ func HandleSpell(fight *fights.Fight, user *users.User, spellID int) *FightResul monster, err := monsters.Find(fight.MonsterID) if err == nil { result.EndFightWithVictory(monster, user) + result.UserUpdates["mp"] = user.MP - spell.MP result.ActionText += " " + fmt.Sprintf("%s has been defeated!", monster.Name) } } @@ -182,6 +184,7 @@ func HandleSpell(fight *fights.Fight, user *users.User, spellID int) *FightResul monster, err := monsters.Find(fight.MonsterID) if err == nil { result.EndFightWithVictory(monster, user) + result.UserUpdates["mp"] = user.MP - spell.MP result.ActionText += " " + fmt.Sprintf("%s has been defeated!", monster.Name) } } diff --git a/internal/components/asides.go b/internal/components/asides.go index 829322b..4d43829 100644 --- a/internal/components/asides.go +++ b/internal/components/asides.go @@ -46,6 +46,16 @@ func RightAside(ctx sushi.Ctx) map[string]any { user := ctx.GetCurrentUser().(*users.User) data["_class"] = user.Class() + if user.Level == 1 { + data["_exp_display"] = user.Exp + data["_exp_needed"] = helpers.ExpAtLevel(2) + } else { + currentLevelExp := helpers.ExpAtLevel(user.Level) + nextLevelExp := helpers.ExpAtLevel(user.Level + 1) + data["_exp_display"] = user.Exp - currentLevelExp + data["_exp_needed"] = nextLevelExp - currentLevelExp + } + data["_expprog"] = fmt.Sprintf("%.1f", user.ExpProgress()) hpPct := helpers.ClampPct(float64(user.HP), float64(user.MaxHP), 0, 100) diff --git a/internal/models/users/users.go b/internal/models/users/users.go index f2f7c50..227756e 100644 --- a/internal/models/users/users.go +++ b/internal/models/users/users.go @@ -295,17 +295,22 @@ func (u *User) ExpNeededForNextLevel() int { func (u *User) GrantExp(expAmount int) map[string]any { oldLevel := u.Level - newLevel, newStr, newDex, newExp := u.CalculateLevelUp(expAmount) + results := u.CalculateLevelUp(expAmount) updates := map[string]any{ - "exp": newExp, + "exp": results["exp"], } + newLevel := results["level"].(int) + // Only include level/stats if they actually changed if newLevel > oldLevel { updates["level"] = newLevel - updates["strength"] = newStr - updates["dexterity"] = newDex + updates["strength"] = results["strength"] + updates["dexterity"] = results["dexterity"] + updates["max_hp"] = results["max_hp"] + updates["max_mp"] = results["max_mp"] + updates["max_tp"] = results["max_tp"] // Learn new spells for each level gained for level := oldLevel + 1; level <= newLevel; level++ { @@ -319,10 +324,15 @@ func (u *User) GrantExp(expAmount int) map[string]any { return updates } -func (u *User) CalculateLevelUp(expGain int) (newLevel, newStr, newDex, newExp int) { +func (u *User) CalculateLevelUp(expGain int) map[string]any { + class := u.Class() + level := u.Level str := u.Strength dex := u.Dexterity + maxHP := u.MaxHP + maxMP := u.MaxMP + maxTP := u.MaxTP totalExp := u.Exp + expGain for { @@ -332,24 +342,36 @@ func (u *User) CalculateLevelUp(expGain int) (newLevel, newStr, newDex, newExp i } level++ - str++ - dex++ - totalExp -= expNeeded + str += class.RateSTR + dex += class.RateDEX + maxHP += class.RateHP + maxMP += class.RateMP + maxTP += 2 } - return level, str, dex, totalExp + return map[string]any{ + "level": level, + "strength": str, + "dexterity": dex, + "max_hp": maxHP, + "max_mp": maxMP, + "max_tp": maxTP, + "exp": totalExp, + } } func (u *User) ExpProgress() float64 { + nextLevelExp := helpers.ExpAtLevel(u.Level + 1) + if u.Level == 1 { - return float64(u.Exp) / float64(u.ExpNeededForNextLevel()) * 100 + return float64(u.Exp) / float64(nextLevelExp) * 100 } currentLevelExp := helpers.ExpAtLevel(u.Level) - nextLevelExp := u.ExpNeededForNextLevel() - progressExp := u.Exp + expIntoLevel := u.Exp - currentLevelExp + expNeededForLevel := nextLevelExp - currentLevelExp - return float64(progressExp) / float64(nextLevelExp-currentLevelExp) * 100 + return float64(expIntoLevel) / float64(expNeededForLevel) * 100 } func (u *User) Class() *classes.Class { diff --git a/templates/rightside.html b/templates/rightside.html index 7ee2719..92dc191 100644 --- a/templates/rightside.html +++ b/templates/rightside.html @@ -2,7 +2,7 @@
  • {user.Username}
  • Level {user.Level} {_class.Name}
  • -
  • Exp: {user.Exp} ({_expprog}%)
  • +
  • Exp: {_exp_display} ({_expprog}%)
  • Gold: {user.Gold}
  • HP: {user.HP}/{user.MaxHP}
  • MP: {user.MP}/{user.MaxMP}