scripts/player_stats.pyΒΆ
Part of Dungeon Explorer.
1"""Derived stat computation: base + gear + level bonuses."""
2
3from .inventory import Inventory
4
5
6def compute_derived_stats(
7 base_str: int,
8 base_dex: int,
9 base_vit: int,
10 base_int: int,
11 level: int,
12 inventory: Inventory,
13 skill_bonuses: dict[str, float] | None = None,
14) -> dict[str, float]:
15 """Compute all derived stats from base attributes + equipped gear + skill passives.
16
17 Returns dict with keys: max_hp, damage, defence, speed, crit_chance,
18 dodge_chance, block_chance, life_steal, hp_on_kill, fire_damage,
19 ice_damage, thorns.
20 """
21 gear = inventory.equipment_stats()
22 sb = skill_bonuses or {}
23
24 str_total = base_str + gear.get("str", 0)
25 dex_total = base_dex + gear.get("dex", 0)
26 vit_total = base_vit + gear.get("vit", 0)
27 int_total = base_int + gear.get("int", 0)
28
29 # Base derived stats from attributes + gear
30 max_hp = 80 + vit_total * 5 + level * 3 + gear.get("max_hp", 0) + sb.get("max_hp", 0)
31 damage = str_total // 2 + gear.get("damage", 0)
32 defence = vit_total // 3 + gear.get("defence", 0) + sb.get("defence", 0)
33 speed = 120.0 + dex_total * 0.5 + gear.get("speed", 0) * 100
34 crit_chance = 0.05 + dex_total * 0.003 + gear.get("crit_chance", 0) + sb.get("crit_chance", 0)
35 dodge_chance = 0.02 + dex_total * 0.002 + gear.get("dodge_chance", 0) + sb.get("dodge_chance", 0)
36 block_chance = gear.get("block_chance", 0) + sb.get("block_chance", 0)
37 life_steal = gear.get("life_steal", 0) + sb.get("life_steal", 0)
38 hp_on_kill = gear.get("hp_on_kill", 0) + sb.get("hp_on_kill", 0)
39 spell_power = int_total * 0.8 + gear.get("spell_power", 0)
40
41 # Apply multiplicative skill bonuses
42 damage_mult = 1.0 + sb.get("damage_mult", 0)
43 damage = int(damage * damage_mult)
44 speed *= 1.0 + sb.get("speed", 0)
45 spell_power *= 1.0 + sb.get("spell_power", 0)
46
47 stats = {
48 # Core
49 "str": str_total,
50 "dex": dex_total,
51 "vit": vit_total,
52 "int": int_total,
53 # Derived
54 "max_hp": max_hp,
55 "damage": damage,
56 "defence": defence,
57 "speed": speed,
58 "crit_chance": crit_chance,
59 "dodge_chance": dodge_chance,
60 "block_chance": block_chance,
61 "life_steal": life_steal,
62 "hp_on_kill": hp_on_kill,
63 # Elemental
64 "fire_damage": gear.get("fire_damage", 0) + sb.get("fire_damage", 0),
65 "ice_damage": gear.get("ice_damage", 0) + sb.get("ice_damage", 0),
66 "thorns": gear.get("thorns", 0) + sb.get("thorns", 0),
67 # Magic
68 "spell_power": spell_power,
69 # Knockback: small base, grows with STR and gear
70 "knockback": 2.0 + str_total * 0.5 + gear.get("knockback", 0),
71 }
72 return stats