Extract additional player class attributes to attributes.tsv files

This commit is contained in:
Developer Guilliman
2026-09-26 09:45:42 +00:00
committed by GitHub
parent 8bef7bce51
commit bd1ee963f7
14 changed files with 125 additions and 62 deletions
+1
View File
@@ -12,6 +12,7 @@ set(hellfire_mod
nlevels/cutl6w.clx
nlevels/l5data/cornerstone.dun
nlevels/l5data/uberroom.dun
txtdata/classes/sorcerer/attributes.tsv
txtdata/classes/sorcerer/starting_loadout.tsv
txtdata/classes/classdat.tsv
txtdata/items/item_prefixes.tsv
+8 -21
View File
@@ -109,18 +109,11 @@ namespace {
int AddClassHealingBonus(int hp, HeroClass heroClass, SpellID spellId)
{
switch (heroClass) {
case HeroClass::Warrior:
case HeroClass::Barbarian:
return hp * 2;
case HeroClass::Rogue:
case HeroClass::Bard:
return hp + (hp / 2);
case HeroClass::Monk:
return spellId == SpellID::HealOther ? hp * 3 : hp * 2;
default:
return hp;
const ClassAttributes &classAttributes = GetClassAttributes(heroClass);
if (spellId == SpellID::HealOther) {
return hp * classAttributes.healOtherRestoreLife >> 6;
}
return hp * classAttributes.splRestoreLife >> 6;
}
int ScaleSpellEffect(int base, int spellLevel)
@@ -1668,10 +1661,8 @@ void AddMana(Missile &missile, AddMissileParameter & /*parameter*/)
for (int i = 0; i < missile._mispllvl; i++) {
manaAmount += (GenerateRnd(6) + 1) << 6;
}
if (player._pClass == HeroClass::Sorcerer)
manaAmount *= 2;
if (player._pClass == HeroClass::Rogue || player._pClass == HeroClass::Bard)
manaAmount += manaAmount / 2;
const ClassAttributes &classAttributes = GetClassAttributes(player._pClass);
manaAmount = manaAmount * classAttributes.splRestoreMana >> 6;
player._pMana += manaAmount;
player._pMana = std::min(player._pMana, player._pMaxMana);
player._pManaBase += manaAmount;
@@ -2468,12 +2459,8 @@ void AddHealing(Missile &missile, AddMissileParameter & /*parameter*/)
hp += GenerateRndSum(6, missile._mispllvl) + missile._mispllvl;
hp <<= 6;
if (player._pClass == HeroClass::Warrior || player._pClass == HeroClass::Barbarian || player._pClass == HeroClass::Monk) {
hp *= 2;
} else if (player._pClass == HeroClass::Rogue || player._pClass == HeroClass::Bard) {
hp += hp / 2;
}
const ClassAttributes &classAttributes = GetClassAttributes(player._pClass);
hp = hp * classAttributes.splRestoreLife >> 6;
player._pHitPoints = std::min(player._pHitPoints + hp, player._pMaxHP);
player._pHPBase = std::min(player._pHPBase + hp, player._pMaxHPBase);
+4 -8
View File
@@ -1745,10 +1745,8 @@ void Player::RestorePartialLife()
{
const int wholeHitpoints = _pMaxHP >> 6;
int l = ((wholeHitpoints / 8) + GenerateRnd(wholeHitpoints / 4)) << 6;
if (IsAnyOf(_pClass, HeroClass::Warrior, HeroClass::Barbarian))
l *= 2;
if (IsAnyOf(_pClass, HeroClass::Rogue, HeroClass::Monk, HeroClass::Bard))
l += l / 2;
const ClassAttributes &classAttributes = GetClassAttributes(_pClass);
l = l * classAttributes.itmRestoreLife >> 6;
_pHitPoints = std::min(_pHitPoints + l, _pMaxHP);
_pHPBase = std::min(_pHPBase + l, _pMaxHPBase);
}
@@ -1757,10 +1755,8 @@ void Player::RestorePartialMana()
{
const int wholeManaPoints = _pMaxMana >> 6;
int l = ((wholeManaPoints / 8) + GenerateRnd(wholeManaPoints / 4)) << 6;
if (_pClass == HeroClass::Sorcerer)
l *= 2;
if (IsAnyOf(_pClass, HeroClass::Rogue, HeroClass::Monk, HeroClass::Bard))
l += l / 2;
const ClassAttributes &classAttributes = GetClassAttributes(_pClass);
l = l * classAttributes.itmRestoreMana >> 6;
if (HasNoneOf(_pIFlags, ItemSpecialEffect::NoMana)) {
_pMana = std::min(_pMana + l, _pMaxMana);
_pManaBase = std::min(_pManaBase + l, _pMaxManaBase);
+4 -13
View File
@@ -131,11 +131,8 @@ int GetManaAmount(const Player &player, SpellID sn)
ma = std::max(ma, 0);
ma <<= 6;
if (gbIsHellfire && player._pClass == HeroClass::Sorcerer) {
ma /= 2;
} else if (player._pClass == HeroClass::Rogue || player._pClass == HeroClass::Monk || player._pClass == HeroClass::Bard) {
ma -= ma / 4;
}
const ClassAttributes &classAttributes = GetClassAttributes(player._pClass);
ma = ma * classAttributes.manaCost >> 6;
if (GetSpellData(sn).sMinMana > ma >> 6) {
ma = GetSpellData(sn).sMinMana << 6;
@@ -291,14 +288,8 @@ void DoHealOther(const Player &caster, Player &target)
for (int i = 0; i < caster.GetSpellLevel(SpellID::HealOther); i++) {
hp += (GenerateRnd(6) + 1) << 6;
}
if (caster._pClass == HeroClass::Warrior || caster._pClass == HeroClass::Barbarian) {
hp *= 2;
} else if (caster._pClass == HeroClass::Rogue || caster._pClass == HeroClass::Bard) {
hp += hp / 2;
} else if (caster._pClass == HeroClass::Monk) {
hp *= 3;
}
const ClassAttributes &classAttributes = GetClassAttributes(caster._pClass);
hp = hp * classAttributes.healOtherRestoreLife >> 6;
target._pHitPoints = std::min(target._pHitPoints + hp, target._pMaxHP);
target._pHPBase = std::min(target._pHPBase + hp, target._pMaxHPBase);
+6
View File
@@ -193,6 +193,12 @@ void LoadClassData(std::string_view classPath, ClassAttributes &attributes, Play
reader.readDecimal("chrMana", attributes.chrMana);
reader.readDecimal("itmLife", attributes.itmLife);
reader.readDecimal("itmMana", attributes.itmMana);
reader.readDecimal("manaCost", attributes.manaCost);
reader.readDecimal("itmRestoreLife", attributes.itmRestoreLife);
reader.readDecimal("itmRestoreMana", attributes.itmRestoreMana);
reader.readDecimal("splRestoreLife", attributes.splRestoreLife);
reader.readDecimal("splRestoreMana", attributes.splRestoreMana);
reader.readDecimal("healOtherRestoreLife", attributes.healOtherRestoreLife);
reader.readInt("baseMagicToHit", combat.baseMagicToHit);
reader.readInt("baseMeleeToHit", combat.baseMeleeToHit);
reader.readInt("baseRangedToHit", combat.baseRangedToHit);
+12
View File
@@ -89,6 +89,18 @@ struct ClassAttributes {
int16_t itmLife;
/* Mana from item bonus Magic */
int16_t itmMana;
/* Mana cost multipler */
int16_t manaCost;
/* Life restore item multipler */
int16_t itmRestoreLife;
/* Mana restore item multipler */
int16_t itmRestoreMana;
/* Life restore spell multipler */
int16_t splRestoreLife;
/* Mana restore spell multipler */
int16_t splRestoreMana;
/* Life restore heal other multipler */
int16_t healOtherRestoreLife;
};
const ClassAttributes &GetClassAttributes(HeroClass playerClass);
+26 -20
View File
@@ -6,23 +6,29 @@ There is one folder per class.
Attribute | Description
------------------:|--------------------------------------
`baseStr` | Class Starting Strength Stat, uint8_t
`baseMag` | Class Starting Magic Stat, uint8_t
`baseDex` | Class Starting Dexterity Stat, uint8_t
`baseVit` | Class Starting Vitality Stat, uint8_t
`maxStr` | Class Maximum Strength Stat, uint8_t
`maxMag` | Class Maximum Magic Stat, uint8_t
`maxDex` | Class Maximum Dexterity Stat, uint8_t
`maxVit` | Class Maximum Vitality Stat, uint8_t
`blockBonus` | Class Block Bonus, %
`adjLife` | Class Life Adjustment, decimal
`adjMana` | Class Mana Adjustment, decimal
`lvlLife` | Life gained on level up, decimal
`lvlMana` | Mana gained on level up, decimal
`chrLife` | Life from base Vitality, decimal
`chrMana` | Mana from base Magic, decimal
`itmLife` | Life from item bonus Vitality, decimal
`itmMana` | Mana from item bonus Magic, decimal
`baseMagicToHit` | Starting chance to hit with spells/scrolls, %
`baseMeleeToHit` | Starting chance to hit with melee weapons/fists, %
`baseRangedToHit` | Starting chance to hit with ranged weapons, %
`baseStr` | Class Starting Strength Stat, uint8_t
`baseMag` | Class Starting Magic Stat, uint8_t
`baseDex` | Class Starting Dexterity Stat, uint8_t
`baseVit` | Class Starting Vitality Stat, uint8_t
`maxStr` | Class Maximum Strength Stat, uint8_t
`maxMag` | Class Maximum Magic Stat, uint8_t
`maxDex` | Class Maximum Dexterity Stat, uint8_t
`maxVit` | Class Maximum Vitality Stat, uint8_t
`blockBonus` | Class Block Bonus, %
`adjLife` | Class Life Adjustment, decimal
`adjMana` | Class Mana Adjustment, decimal
`lvlLife` | Life gained on level up, decimal
`lvlMana` | Mana gained on level up, decimal
`chrLife` | Life from base Vitality, decimal
`chrMana` | Mana from base Magic, decimal
`itmLife` | Life from item bonus Vitality, decimal
`itmMana` | Mana from item bonus Magic, decimal
`manaCost` | Mana cost for spells multipler, decimal
`itmRestoreLife` | Life restored by items multipler, decimal
`itmRestoreMana` | Mana restored by items multipler, decimal
`splRestoreLife` | Life restored by spells multipler, decimal
`splRestoreMana` | Mana restored by spells multiplerr, decimal
`healOtherRestoreLife` | Life restored by spells Heal Other spell multipler, decimal
`baseMagicToHit` | Starting chance to hit with spells/scrolls, %
`baseMeleeToHit` | Starting chance to hit with melee weapons/fists, %
`baseRangedToHit` | Starting chance to hit with ranged weapons, %
@@ -17,6 +17,12 @@ chrLife 2
chrMana 1
itmLife 2.5
itmMana 1
manaCost 1
itmRestoreLife 2
itmRestoreMana 1
splRestoreLife 2
splRestoreMana 1
healOtherRestoreLife 2
baseMagicToHit 50
baseMeleeToHit 50
baseRangedToHit 50
1 Attribute Value
17 chrMana 1
18 itmLife 2.5
19 itmMana 1
20 manaCost 1
21 itmRestoreLife 2
22 itmRestoreMana 1
23 splRestoreLife 2
24 splRestoreMana 1
25 healOtherRestoreLife 2
26 baseMagicToHit 50
27 baseMeleeToHit 50
28 baseRangedToHit 50
@@ -17,6 +17,12 @@ chrLife 1
chrMana 1.5
itmLife 1.5
itmMana 1.75
manaCost 0.75
itmRestoreLife 1.5
itmRestoreMana 1.5
splRestoreLife 1.5
splRestoreMana 1.5
healOtherRestoreLife 1.5
baseMagicToHit 60
baseMeleeToHit 50
baseRangedToHit 60
1 Attribute Value
17 chrMana 1.5
18 itmLife 1.5
19 itmMana 1.75
20 manaCost 0.75
21 itmRestoreLife 1.5
22 itmRestoreMana 1.5
23 splRestoreLife 1.5
24 splRestoreMana 1.5
25 healOtherRestoreLife 1.5
26 baseMagicToHit 60
27 baseMeleeToHit 50
28 baseRangedToHit 60
@@ -17,6 +17,12 @@ chrLife 1
chrMana 1
itmLife 1.5
itmMana 1.5
manaCost 0.75
itmRestoreLife 1.5
itmRestoreMana 1.5
splRestoreLife 2
splRestoreMana 2
healOtherRestoreLife 3
baseMagicToHit 50
baseMeleeToHit 50
baseRangedToHit 50
1 Attribute Value
17 chrMana 1
18 itmLife 1.5
19 itmMana 1.5
20 manaCost 0.75
21 itmRestoreLife 1.5
22 itmRestoreMana 1.5
23 splRestoreLife 2
24 splRestoreMana 2
25 healOtherRestoreLife 3
26 baseMagicToHit 50
27 baseMeleeToHit 50
28 baseRangedToHit 50
@@ -17,6 +17,12 @@ chrLife 1
chrMana 1
itmLife 1.5
itmMana 1.5
manaCost 0.75
itmRestoreLife 1.5
itmRestoreMana 1.5
splRestoreLife 1.5
splRestoreMana 1.5
healOtherRestoreLife 1.5
baseMagicToHit 50
baseMeleeToHit 50
baseRangedToHit 70
1 Attribute Value
17 chrMana 1
18 itmLife 1.5
19 itmMana 1.5
20 manaCost 0.75
21 itmRestoreLife 1.5
22 itmRestoreMana 1.5
23 splRestoreLife 1.5
24 splRestoreMana 1.5
25 healOtherRestoreLife 1.5
26 baseMagicToHit 50
27 baseMeleeToHit 50
28 baseRangedToHit 70
@@ -17,6 +17,12 @@ chrLife 1
chrMana 2
itmLife 1
itmMana 2
manaCost 1
itmRestoreLife 1
itmRestoreMana 2
splRestoreLife 1
splRestoreMana 2
healOtherRestoreLife 1
baseMagicToHit 70
baseMeleeToHit 50
baseRangedToHit 50
1 Attribute Value
17 chrMana 2
18 itmLife 1
19 itmMana 2
20 manaCost 1
21 itmRestoreLife 1
22 itmRestoreMana 2
23 splRestoreLife 1
24 splRestoreMana 2
25 healOtherRestoreLife 1
26 baseMagicToHit 70
27 baseMeleeToHit 50
28 baseRangedToHit 50
@@ -17,6 +17,12 @@ chrLife 2
chrMana 1
itmLife 2
itmMana 1
manaCost 1
itmRestoreLife 2
itmRestoreMana 1
splRestoreLife 2
splRestoreMana 1
healOtherRestoreLife 2
baseMagicToHit 50
baseMeleeToHit 70
baseRangedToHit 60
1 Attribute Value
17 chrMana 1
18 itmLife 2
19 itmMana 1
20 manaCost 1
21 itmRestoreLife 2
22 itmRestoreMana 1
23 splRestoreLife 2
24 splRestoreMana 1
25 healOtherRestoreLife 2
26 baseMagicToHit 50
27 baseMeleeToHit 70
28 baseRangedToHit 60
@@ -0,0 +1,28 @@
Attribute Value
classFlags
baseStr 15
baseMag 35
baseDex 15
baseVit 20
maxStr 45
maxMag 250
maxDex 85
maxVit 80
blockBonus 10
adjLife 9
adjMana -2
lvlLife 1
lvlMana 2
chrLife 1
chrMana 2
itmLife 1
itmMana 2
manaCost 0.5
itmRestoreLife 1
itmRestoreMana 2
splRestoreLife 1
splRestoreMana 2
healOtherRestoreLife 1
baseMagicToHit 70
baseMeleeToHit 50
baseRangedToHit 50
1 Attribute Value
2 classFlags
3 baseStr 15
4 baseMag 35
5 baseDex 15
6 baseVit 20
7 maxStr 45
8 maxMag 250
9 maxDex 85
10 maxVit 80
11 blockBonus 10
12 adjLife 9
13 adjMana -2
14 lvlLife 1
15 lvlMana 2
16 chrLife 1
17 chrMana 2
18 itmLife 1
19 itmMana 2
20 manaCost 0.5
21 itmRestoreLife 1
22 itmRestoreMana 2
23 splRestoreLife 1
24 splRestoreMana 2
25 healOtherRestoreLife 1
26 baseMagicToHit 70
27 baseMeleeToHit 50
28 baseRangedToHit 50