Work on level ups, exp management, rewards, attack scaling, etc
This commit is contained in:
parent
9e17ab9bea
commit
2d958bf8c4
736
data/fights.json
736
data/fights.json
@ -248,5 +248,741 @@
|
||||
],
|
||||
"created": 1755270614,
|
||||
"updated": 1755270620
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"user_id": 1,
|
||||
"monster_id": 2,
|
||||
"monster_hp": 0,
|
||||
"monster_max_hp": 6,
|
||||
"monster_sleep": 0,
|
||||
"monster_immune": 0,
|
||||
"uber_damage": 0,
|
||||
"uber_defense": 0,
|
||||
"first_strike": true,
|
||||
"turn": 6,
|
||||
"ran_away": false,
|
||||
"victory": true,
|
||||
"won": true,
|
||||
"reward_gold": 1,
|
||||
"reward_exp": 2,
|
||||
"actions": [
|
||||
{
|
||||
"t": 1,
|
||||
"d": 1
|
||||
},
|
||||
{
|
||||
"t": 8,
|
||||
"d": 1,
|
||||
"n": "Red Slime"
|
||||
},
|
||||
{
|
||||
"t": 1,
|
||||
"d": 1
|
||||
},
|
||||
{
|
||||
"t": 8,
|
||||
"d": 1,
|
||||
"n": "Red Slime"
|
||||
},
|
||||
{
|
||||
"t": 1,
|
||||
"d": 1
|
||||
},
|
||||
{
|
||||
"t": 8,
|
||||
"d": 1,
|
||||
"n": "Red Slime"
|
||||
},
|
||||
{
|
||||
"t": 1,
|
||||
"d": 1
|
||||
},
|
||||
{
|
||||
"t": 8,
|
||||
"d": 1,
|
||||
"n": "Red Slime"
|
||||
},
|
||||
{
|
||||
"t": 1,
|
||||
"d": 1
|
||||
},
|
||||
{
|
||||
"t": 8,
|
||||
"d": 1,
|
||||
"n": "Red Slime"
|
||||
},
|
||||
{
|
||||
"t": 1,
|
||||
"d": 1
|
||||
},
|
||||
{
|
||||
"t": 11,
|
||||
"n": "Red Slime"
|
||||
}
|
||||
],
|
||||
"created": 1755270995,
|
||||
"updated": 1755271001
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"user_id": 1,
|
||||
"monster_id": 1,
|
||||
"monster_hp": 0,
|
||||
"monster_max_hp": 4,
|
||||
"monster_sleep": 0,
|
||||
"monster_immune": 0,
|
||||
"uber_damage": 0,
|
||||
"uber_defense": 0,
|
||||
"first_strike": true,
|
||||
"turn": 4,
|
||||
"ran_away": false,
|
||||
"victory": true,
|
||||
"won": true,
|
||||
"reward_gold": 1,
|
||||
"reward_exp": 1,
|
||||
"actions": [
|
||||
{
|
||||
"t": 1,
|
||||
"d": 1
|
||||
},
|
||||
{
|
||||
"t": 8,
|
||||
"d": 1,
|
||||
"n": "Blue Slime"
|
||||
},
|
||||
{
|
||||
"t": 1,
|
||||
"d": 1
|
||||
},
|
||||
{
|
||||
"t": 8,
|
||||
"d": 1,
|
||||
"n": "Blue Slime"
|
||||
},
|
||||
{
|
||||
"t": 1,
|
||||
"d": 1
|
||||
},
|
||||
{
|
||||
"t": 8,
|
||||
"d": 1,
|
||||
"n": "Blue Slime"
|
||||
},
|
||||
{
|
||||
"t": 1,
|
||||
"d": 1
|
||||
},
|
||||
{
|
||||
"t": 11,
|
||||
"n": "Blue Slime"
|
||||
}
|
||||
],
|
||||
"created": 1755274346,
|
||||
"updated": 1755274352
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"user_id": 1,
|
||||
"monster_id": 6,
|
||||
"monster_hp": 10,
|
||||
"monster_max_hp": 11,
|
||||
"monster_sleep": 0,
|
||||
"monster_immune": 0,
|
||||
"uber_damage": 0,
|
||||
"uber_defense": 0,
|
||||
"first_strike": true,
|
||||
"turn": 1,
|
||||
"ran_away": false,
|
||||
"victory": true,
|
||||
"won": false,
|
||||
"reward_gold": 0,
|
||||
"reward_exp": 0,
|
||||
"actions": [
|
||||
{
|
||||
"t": 1,
|
||||
"d": 1
|
||||
},
|
||||
{
|
||||
"t": 8,
|
||||
"d": 2,
|
||||
"n": "Drake"
|
||||
}
|
||||
],
|
||||
"created": 1755274391,
|
||||
"updated": 1755274393
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"user_id": 1,
|
||||
"monster_id": 5,
|
||||
"monster_hp": 6,
|
||||
"monster_max_hp": 10,
|
||||
"monster_sleep": 0,
|
||||
"monster_immune": 1,
|
||||
"uber_damage": 0,
|
||||
"uber_defense": 0,
|
||||
"first_strike": false,
|
||||
"turn": 4,
|
||||
"ran_away": false,
|
||||
"victory": true,
|
||||
"won": false,
|
||||
"reward_gold": 0,
|
||||
"reward_exp": 0,
|
||||
"actions": [
|
||||
{
|
||||
"t": 1,
|
||||
"d": 1
|
||||
},
|
||||
{
|
||||
"t": 8,
|
||||
"d": 2,
|
||||
"n": "Shadow"
|
||||
},
|
||||
{
|
||||
"t": 1,
|
||||
"d": 1
|
||||
},
|
||||
{
|
||||
"t": 8,
|
||||
"d": 3,
|
||||
"n": "Shadow"
|
||||
},
|
||||
{
|
||||
"t": 1,
|
||||
"d": 1
|
||||
},
|
||||
{
|
||||
"t": 8,
|
||||
"d": 3,
|
||||
"n": "Shadow"
|
||||
},
|
||||
{
|
||||
"t": 1,
|
||||
"d": 1
|
||||
},
|
||||
{
|
||||
"t": 8,
|
||||
"d": 3,
|
||||
"n": "Shadow"
|
||||
}
|
||||
],
|
||||
"created": 1755274646,
|
||||
"updated": 1755274652
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"user_id": 1,
|
||||
"monster_id": 2,
|
||||
"monster_hp": 0,
|
||||
"monster_max_hp": 6,
|
||||
"monster_sleep": 0,
|
||||
"monster_immune": 0,
|
||||
"uber_damage": 0,
|
||||
"uber_defense": 0,
|
||||
"first_strike": true,
|
||||
"turn": 6,
|
||||
"ran_away": false,
|
||||
"victory": true,
|
||||
"won": true,
|
||||
"reward_gold": 1,
|
||||
"reward_exp": 2,
|
||||
"actions": [
|
||||
{
|
||||
"t": 1,
|
||||
"d": 1
|
||||
},
|
||||
{
|
||||
"t": 8,
|
||||
"d": 1,
|
||||
"n": "Red Slime"
|
||||
},
|
||||
{
|
||||
"t": 1,
|
||||
"d": 1
|
||||
},
|
||||
{
|
||||
"t": 8,
|
||||
"d": 1,
|
||||
"n": "Red Slime"
|
||||
},
|
||||
{
|
||||
"t": 1,
|
||||
"d": 1
|
||||
},
|
||||
{
|
||||
"t": 8,
|
||||
"d": 1,
|
||||
"n": "Red Slime"
|
||||
},
|
||||
{
|
||||
"t": 1,
|
||||
"d": 1
|
||||
},
|
||||
{
|
||||
"t": 8,
|
||||
"d": 1,
|
||||
"n": "Red Slime"
|
||||
},
|
||||
{
|
||||
"t": 1,
|
||||
"d": 1
|
||||
},
|
||||
{
|
||||
"t": 8,
|
||||
"d": 1,
|
||||
"n": "Red Slime"
|
||||
},
|
||||
{
|
||||
"t": 1,
|
||||
"d": 1
|
||||
},
|
||||
{
|
||||
"t": 11,
|
||||
"n": "Red Slime"
|
||||
}
|
||||
],
|
||||
"created": 1755274719,
|
||||
"updated": 1755274725
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"user_id": 1,
|
||||
"monster_id": 2,
|
||||
"monster_hp": 0,
|
||||
"monster_max_hp": 6,
|
||||
"monster_sleep": 0,
|
||||
"monster_immune": 0,
|
||||
"uber_damage": 0,
|
||||
"uber_defense": 0,
|
||||
"first_strike": false,
|
||||
"turn": 6,
|
||||
"ran_away": false,
|
||||
"victory": true,
|
||||
"won": true,
|
||||
"reward_gold": 1,
|
||||
"reward_exp": 2,
|
||||
"actions": [
|
||||
{
|
||||
"t": 1,
|
||||
"d": 1
|
||||
},
|
||||
{
|
||||
"t": 8,
|
||||
"d": 1,
|
||||
"n": "Red Slime"
|
||||
},
|
||||
{
|
||||
"t": 1,
|
||||
"d": 1
|
||||
},
|
||||
{
|
||||
"t": 8,
|
||||
"d": 1,
|
||||
"n": "Red Slime"
|
||||
},
|
||||
{
|
||||
"t": 1,
|
||||
"d": 1
|
||||
},
|
||||
{
|
||||
"t": 8,
|
||||
"d": 1,
|
||||
"n": "Red Slime"
|
||||
},
|
||||
{
|
||||
"t": 1,
|
||||
"d": 1
|
||||
},
|
||||
{
|
||||
"t": 8,
|
||||
"d": 1,
|
||||
"n": "Red Slime"
|
||||
},
|
||||
{
|
||||
"t": 1,
|
||||
"d": 1
|
||||
},
|
||||
{
|
||||
"t": 8,
|
||||
"d": 1,
|
||||
"n": "Red Slime"
|
||||
},
|
||||
{
|
||||
"t": 1,
|
||||
"d": 1
|
||||
},
|
||||
{
|
||||
"t": 11,
|
||||
"n": "Red Slime"
|
||||
}
|
||||
],
|
||||
"created": 1755274741,
|
||||
"updated": 1755274746
|
||||
},
|
||||
{
|
||||
"id": 11,
|
||||
"user_id": 1,
|
||||
"monster_id": 8,
|
||||
"monster_hp": 6,
|
||||
"monster_max_hp": 14,
|
||||
"monster_sleep": 0,
|
||||
"monster_immune": 0,
|
||||
"uber_damage": 0,
|
||||
"uber_defense": 0,
|
||||
"first_strike": false,
|
||||
"turn": 10,
|
||||
"ran_away": false,
|
||||
"victory": true,
|
||||
"won": false,
|
||||
"reward_gold": 0,
|
||||
"reward_exp": 0,
|
||||
"actions": [
|
||||
{
|
||||
"t": 1,
|
||||
"d": 1
|
||||
},
|
||||
{
|
||||
"t": 8,
|
||||
"d": 1,
|
||||
"n": "Drakelor"
|
||||
},
|
||||
{
|
||||
"t": 1,
|
||||
"d": 1
|
||||
},
|
||||
{
|
||||
"t": 8,
|
||||
"d": 1,
|
||||
"n": "Drakelor"
|
||||
},
|
||||
{
|
||||
"t": 1,
|
||||
"d": 1
|
||||
},
|
||||
{
|
||||
"t": 8,
|
||||
"d": 1,
|
||||
"n": "Drakelor"
|
||||
},
|
||||
{
|
||||
"t": 1,
|
||||
"d": 1
|
||||
},
|
||||
{
|
||||
"t": 8,
|
||||
"d": 1,
|
||||
"n": "Drakelor"
|
||||
},
|
||||
{
|
||||
"t": 1,
|
||||
"d": 1
|
||||
},
|
||||
{
|
||||
"t": 8,
|
||||
"d": 1,
|
||||
"n": "Drakelor"
|
||||
},
|
||||
{
|
||||
"t": 1,
|
||||
"d": 1
|
||||
},
|
||||
{
|
||||
"t": 8,
|
||||
"d": 1,
|
||||
"n": "Drakelor"
|
||||
},
|
||||
{
|
||||
"t": 1,
|
||||
"d": 1
|
||||
},
|
||||
{
|
||||
"t": 8,
|
||||
"d": 1,
|
||||
"n": "Drakelor"
|
||||
},
|
||||
{
|
||||
"t": 1,
|
||||
"d": 1
|
||||
},
|
||||
{
|
||||
"t": 8,
|
||||
"d": 1,
|
||||
"n": "Drakelor"
|
||||
},
|
||||
{
|
||||
"t": 7,
|
||||
"n": "You failed to run away!"
|
||||
},
|
||||
{
|
||||
"t": 8,
|
||||
"d": 1,
|
||||
"n": "Drakelor"
|
||||
},
|
||||
{
|
||||
"t": 7,
|
||||
"n": "You failed to run away!"
|
||||
},
|
||||
{
|
||||
"t": 8,
|
||||
"d": 1,
|
||||
"n": "Drakelor"
|
||||
}
|
||||
],
|
||||
"created": 1755274758,
|
||||
"updated": 1755274768
|
||||
},
|
||||
{
|
||||
"id": 12,
|
||||
"user_id": 1,
|
||||
"monster_id": 2,
|
||||
"monster_hp": 0,
|
||||
"monster_max_hp": 6,
|
||||
"monster_sleep": 0,
|
||||
"monster_immune": 0,
|
||||
"uber_damage": 0,
|
||||
"uber_defense": 0,
|
||||
"first_strike": true,
|
||||
"turn": 6,
|
||||
"ran_away": false,
|
||||
"victory": true,
|
||||
"won": true,
|
||||
"reward_gold": 1,
|
||||
"reward_exp": 1,
|
||||
"actions": [
|
||||
{
|
||||
"t": 1,
|
||||
"d": 1
|
||||
},
|
||||
{
|
||||
"t": 8,
|
||||
"d": 1,
|
||||
"n": "Red Slime"
|
||||
},
|
||||
{
|
||||
"t": 1,
|
||||
"d": 1
|
||||
},
|
||||
{
|
||||
"t": 8,
|
||||
"d": 1,
|
||||
"n": "Red Slime"
|
||||
},
|
||||
{
|
||||
"t": 1,
|
||||
"d": 1
|
||||
},
|
||||
{
|
||||
"t": 8,
|
||||
"d": 1,
|
||||
"n": "Red Slime"
|
||||
},
|
||||
{
|
||||
"t": 1,
|
||||
"d": 1
|
||||
},
|
||||
{
|
||||
"t": 8,
|
||||
"d": 1,
|
||||
"n": "Red Slime"
|
||||
},
|
||||
{
|
||||
"t": 1,
|
||||
"d": 1
|
||||
},
|
||||
{
|
||||
"t": 8,
|
||||
"d": 1,
|
||||
"n": "Red Slime"
|
||||
},
|
||||
{
|
||||
"t": 1,
|
||||
"d": 1
|
||||
},
|
||||
{
|
||||
"t": 11,
|
||||
"n": "Red Slime"
|
||||
}
|
||||
],
|
||||
"created": 1755274777,
|
||||
"updated": 1755274782
|
||||
},
|
||||
{
|
||||
"id": 13,
|
||||
"user_id": 1,
|
||||
"monster_id": 8,
|
||||
"monster_hp": 4,
|
||||
"monster_max_hp": 14,
|
||||
"monster_sleep": 0,
|
||||
"monster_immune": 0,
|
||||
"uber_damage": 0,
|
||||
"uber_defense": 0,
|
||||
"first_strike": true,
|
||||
"turn": 10,
|
||||
"ran_away": false,
|
||||
"victory": true,
|
||||
"won": false,
|
||||
"reward_gold": 0,
|
||||
"reward_exp": 0,
|
||||
"actions": [
|
||||
{
|
||||
"t": 1,
|
||||
"d": 1
|
||||
},
|
||||
{
|
||||
"t": 8,
|
||||
"d": 1,
|
||||
"n": "Drakelor"
|
||||
},
|
||||
{
|
||||
"t": 1,
|
||||
"d": 1
|
||||
},
|
||||
{
|
||||
"t": 8,
|
||||
"d": 1,
|
||||
"n": "Drakelor"
|
||||
},
|
||||
{
|
||||
"t": 1,
|
||||
"d": 1
|
||||
},
|
||||
{
|
||||
"t": 8,
|
||||
"d": 1,
|
||||
"n": "Drakelor"
|
||||
},
|
||||
{
|
||||
"t": 1,
|
||||
"d": 1
|
||||
},
|
||||
{
|
||||
"t": 8,
|
||||
"d": 1,
|
||||
"n": "Drakelor"
|
||||
},
|
||||
{
|
||||
"t": 1,
|
||||
"d": 1
|
||||
},
|
||||
{
|
||||
"t": 8,
|
||||
"d": 1,
|
||||
"n": "Drakelor"
|
||||
},
|
||||
{
|
||||
"t": 1,
|
||||
"d": 1
|
||||
},
|
||||
{
|
||||
"t": 8,
|
||||
"d": 1,
|
||||
"n": "Drakelor"
|
||||
},
|
||||
{
|
||||
"t": 1,
|
||||
"d": 1
|
||||
},
|
||||
{
|
||||
"t": 8,
|
||||
"d": 1,
|
||||
"n": "Drakelor"
|
||||
},
|
||||
{
|
||||
"t": 1,
|
||||
"d": 1
|
||||
},
|
||||
{
|
||||
"t": 8,
|
||||
"d": 1,
|
||||
"n": "Drakelor"
|
||||
},
|
||||
{
|
||||
"t": 1,
|
||||
"d": 1
|
||||
},
|
||||
{
|
||||
"t": 8,
|
||||
"d": 1,
|
||||
"n": "Drakelor"
|
||||
},
|
||||
{
|
||||
"t": 1,
|
||||
"d": 1
|
||||
},
|
||||
{
|
||||
"t": 8,
|
||||
"d": 1,
|
||||
"n": "Drakelor"
|
||||
}
|
||||
],
|
||||
"created": 1755274841,
|
||||
"updated": 1755275436
|
||||
},
|
||||
{
|
||||
"id": 14,
|
||||
"user_id": 1,
|
||||
"monster_id": 4,
|
||||
"monster_hp": 0,
|
||||
"monster_max_hp": 10,
|
||||
"monster_sleep": 0,
|
||||
"monster_immune": 0,
|
||||
"uber_damage": 0,
|
||||
"uber_defense": 0,
|
||||
"first_strike": true,
|
||||
"turn": 5,
|
||||
"ran_away": false,
|
||||
"victory": true,
|
||||
"won": true,
|
||||
"reward_gold": 1,
|
||||
"reward_exp": 3,
|
||||
"actions": [
|
||||
{
|
||||
"t": 1,
|
||||
"d": 2
|
||||
},
|
||||
{
|
||||
"t": 8,
|
||||
"d": 1,
|
||||
"n": "Creature"
|
||||
},
|
||||
{
|
||||
"t": 1,
|
||||
"d": 2
|
||||
},
|
||||
{
|
||||
"t": 8,
|
||||
"d": 1,
|
||||
"n": "Creature"
|
||||
},
|
||||
{
|
||||
"t": 1,
|
||||
"d": 2
|
||||
},
|
||||
{
|
||||
"t": 8,
|
||||
"d": 1,
|
||||
"n": "Creature"
|
||||
},
|
||||
{
|
||||
"t": 1,
|
||||
"d": 2
|
||||
},
|
||||
{
|
||||
"t": 8,
|
||||
"d": 1,
|
||||
"n": "Creature"
|
||||
},
|
||||
{
|
||||
"t": 1,
|
||||
"d": 2
|
||||
},
|
||||
{
|
||||
"t": 11,
|
||||
"n": "Creature"
|
||||
}
|
||||
],
|
||||
"created": 1755275442,
|
||||
"updated": 1755275447
|
||||
}
|
||||
]
|
@ -4,7 +4,7 @@
|
||||
"name": "Midworld",
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"inn_cost": 5,
|
||||
"inn_cost": 1,
|
||||
"map_cost": 0,
|
||||
"tp_cost": 0,
|
||||
"shop_list": "1,2,3,17,18,19,28,29"
|
||||
|
@ -19,11 +19,14 @@ func HandleAttack(fight *fights.Fight, user *users.User) {
|
||||
return
|
||||
}
|
||||
|
||||
// Player attack damage calculation
|
||||
// Player attack damage calculation with sqrt scaling
|
||||
attackPower := float64(user.Attack)
|
||||
minAttack := attackPower * 0.75
|
||||
maxAttack := attackPower
|
||||
tohit := math.Ceil(rand.Float64()*(maxAttack-minAttack)+minAttack) / 3
|
||||
rawAttack := math.Ceil(rand.Float64()*(maxAttack-minAttack) + minAttack)
|
||||
|
||||
// Progressive scaling using square root for smooth progression
|
||||
tohit := rawAttack / (1.2 + math.Sqrt(attackPower)*0.05)
|
||||
|
||||
// Critical hit chance based on strength
|
||||
criticalRoll := rand.Intn(150) + 1
|
||||
@ -31,11 +34,14 @@ func HandleAttack(fight *fights.Fight, user *users.User) {
|
||||
tohit *= 2 // Critical hit
|
||||
}
|
||||
|
||||
// Monster defense calculation
|
||||
// Monster defense calculation with more aggressive scaling
|
||||
armor := float64(monster.Armor)
|
||||
minBlock := armor * 0.75
|
||||
maxBlock := armor
|
||||
toblock := math.Ceil(rand.Float64()*(maxBlock-minBlock)+minBlock) / 3
|
||||
rawBlock := math.Ceil(rand.Float64()*(maxBlock-minBlock) + minBlock)
|
||||
|
||||
// Armor uses higher divisor to balance against player attack
|
||||
toblock := rawBlock / (1.8 + math.Sqrt(armor)*0.08)
|
||||
|
||||
// Calculate final damage
|
||||
damage := tohit - toblock
|
||||
@ -58,7 +64,8 @@ func HandleAttack(fight *fights.Fight, user *users.User) {
|
||||
// Check if monster is defeated
|
||||
if fight.MonsterHP <= 0 {
|
||||
fight.AddActionMonsterDeath(monster.Name)
|
||||
fight.WinFight(fight.RewardGold, fight.RewardExp)
|
||||
rewardGold, rewardExp := calculateRewards(monster, user)
|
||||
fight.WinFight(rewardGold, rewardExp)
|
||||
HandleFightWin(fight, user)
|
||||
}
|
||||
}
|
||||
@ -176,7 +183,7 @@ func HandleMonsterAttack(fight *fights.Fight, user *users.User) {
|
||||
|
||||
func HandleFightWin(fight *fights.Fight, user *users.User) {
|
||||
// Add rewards to user
|
||||
user.Exp += fight.RewardExp
|
||||
user.GrantExp(fight.RewardExp)
|
||||
user.Gold += fight.RewardGold
|
||||
|
||||
// Reset fight state
|
||||
@ -226,3 +233,23 @@ func findClosestTown(x, y int) *towns.Town {
|
||||
|
||||
return closest
|
||||
}
|
||||
|
||||
func calculateRewards(monster *monsters.Monster, user *users.User) (int, int) {
|
||||
// Base rewards (83-100% of max)
|
||||
minExp := (monster.MaxExp * 5) / 6
|
||||
maxExp := monster.MaxExp
|
||||
exp := rand.Intn(maxExp-minExp+1) + minExp
|
||||
|
||||
minGold := (monster.MaxGold * 5) / 6
|
||||
maxGold := monster.MaxGold
|
||||
gold := rand.Intn(maxGold-minGold+1) + minGold
|
||||
|
||||
// Apply bonus multipliers
|
||||
expBonus := (user.ExpBonus * exp) / 100
|
||||
exp += expBonus
|
||||
|
||||
goldBonus := (user.GoldBonus * gold) / 100
|
||||
gold += goldBonus
|
||||
|
||||
return gold, exp
|
||||
}
|
||||
|
@ -60,10 +60,8 @@ func Move(user *users.User, dir Direction) (string, int, int, error) {
|
||||
|
||||
// 33% chance to start a fight when moving to non-town location
|
||||
if rand.Float32() < 0.33 {
|
||||
fmt.Println("Fight chance!")
|
||||
monster, err := getRandomMonsterByDistance(newX, newY)
|
||||
if err != nil {
|
||||
fmt.Printf("Finding a monster failed: %s\n", err.Error())
|
||||
return "Exploring", newX, newY, nil // Fall back to exploring if monster selection fails
|
||||
}
|
||||
|
||||
@ -75,14 +73,11 @@ func Move(user *users.User, dir Direction) (string, int, int, error) {
|
||||
|
||||
err = fight.Insert()
|
||||
if err != nil {
|
||||
fmt.Printf("Inserting a fight failed: %s\n", err.Error())
|
||||
return "Exploring", newX, newY, nil // Fall back if fight creation fails
|
||||
}
|
||||
|
||||
user.FightID = fight.ID
|
||||
return "Fighting", newX, newY, nil
|
||||
} else {
|
||||
fmt.Println("No fight...")
|
||||
}
|
||||
|
||||
return "Exploring", newX, newY, nil
|
||||
|
@ -7,6 +7,7 @@ import (
|
||||
"dk/internal/models/towns"
|
||||
"dk/internal/models/users"
|
||||
"dk/internal/router"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// LeftAside generates the data map for the left sidebar.
|
||||
@ -45,6 +46,8 @@ func RightAside(ctx router.Ctx) map[string]any {
|
||||
|
||||
user := ctx.UserValue("user").(*users.User)
|
||||
|
||||
data["_expprog"] = fmt.Sprintf("%.1f", user.ExpProgress())
|
||||
|
||||
hpPct := helpers.ClampPct(float64(user.HP), float64(user.MaxHP), 0, 100)
|
||||
data["hppct"] = hpPct
|
||||
data["mppct"] = helpers.ClampPct(float64(user.MP), float64(user.MaxMP), 0, 100)
|
||||
|
5
internal/helpers/exp/exp.go
Normal file
5
internal/helpers/exp/exp.go
Normal file
@ -0,0 +1,5 @@
|
||||
package exp
|
||||
|
||||
func Calc(level int) int {
|
||||
return level * level * level
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
package users
|
||||
|
||||
import (
|
||||
"dk/internal/helpers/exp"
|
||||
"dk/internal/store"
|
||||
"fmt"
|
||||
"slices"
|
||||
@ -348,3 +349,44 @@ func (u *User) SetPosition(x, y int) {
|
||||
u.X = x
|
||||
u.Y = y
|
||||
}
|
||||
|
||||
func (u *User) ExpNeededForNextLevel() int {
|
||||
return exp.Calc(u.Level + 1)
|
||||
}
|
||||
|
||||
func (u *User) GrantExp(expAmount int) {
|
||||
u.Exp += expAmount
|
||||
u.checkLevelUp()
|
||||
}
|
||||
|
||||
func (u *User) checkLevelUp() {
|
||||
expNeeded := u.ExpNeededForNextLevel()
|
||||
|
||||
if u.Exp >= expNeeded {
|
||||
// Level up
|
||||
u.Level++
|
||||
u.Strength++
|
||||
u.Dexterity++
|
||||
|
||||
// Reset exp and carry over excess
|
||||
excessExp := u.Exp - expNeeded
|
||||
u.Exp = 0
|
||||
|
||||
// Recursive level up if enough excess exp
|
||||
if excessExp > 0 {
|
||||
u.GrantExp(excessExp)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (u *User) ExpProgress() float64 {
|
||||
if u.Level == 1 {
|
||||
return float64(u.Exp) / float64(u.ExpNeededForNextLevel()) * 100
|
||||
}
|
||||
|
||||
currentLevelExp := exp.Calc(u.Level)
|
||||
nextLevelExp := u.ExpNeededForNextLevel()
|
||||
progressExp := u.Exp
|
||||
|
||||
return float64(progressExp) / float64(nextLevelExp-currentLevelExp) * 100
|
||||
}
|
||||
|
@ -3,7 +3,7 @@
|
||||
<ul class="unstyled">
|
||||
<li><b>{user.Username}</b></li>
|
||||
<li>Level: {user.Level}</li>
|
||||
<li>Exp: {user.Exp}</li>
|
||||
<li>Exp: {user.Exp} ({_expprog}%)</li>
|
||||
<li>Gold: {user.Gold}</li>
|
||||
<li>HP: {user.HP}/{user.MaxHP}</li>
|
||||
<li>MP: {user.MP}/{user.MaxMP}</li>
|
||||
|
Loading…
x
Reference in New Issue
Block a user