-
Notifications
You must be signed in to change notification settings - Fork 68
Player stats
Allofich edited this page Apr 15, 2020
·
21 revisions
Health for the player is rolled in character generation as follows. 25 is then added to this value.
void GetStartingHealth(NPCDATA* npcData)
{
unsigned int health = Roll(HealthDice[npcData->Class] & ID_MASK)); // Get a value between min and max
health = health + npcData->BonusHealth;
if (health == 0)
{
health = 1;
}
npcData->currentHealth = health;
npcData->maxHealth = health;
return;
}
Maximum spell points for the player and NPCs is obtained as follows:
unsigned int GetMaxSpellPoints(NPCDATA* npcData, uint currentIntelligence)
{
// See the wiki page on "Save File Formats" for the NPCDATA structure
unsigned char class = npcData->class; // Get the character class
// Default of 0 spell points. (For non-spellcasters)
int spellPoints = 0;
// If class is a spellcaster and not a sorcerer
if ((class & SPELLCASTER_MASK != 0) && (class != 0x23))
{
spellPoints = currentIntelligence; // 1x intelligence spell points (Bard)
// If not a bard
if (class != 0xe6)
{
uint spellPointBonus = currentIntelligence; // 2x intelligence spell points
// From here, a byte array in the executable file is used.
// The array has 6 values, ordered by class ID.
// If the value gotten is 2, then the total will stay 2x intelligence as was set above. (Mage, Healer).
// If the value gotten is 0, then the total will become 1.5x intelligence. (Spellsword, Nightblade)
// For any other value, the total will become 1.75x intelligence. (Battlemage)
if (SpellPointModifiers[class & ID_MASK] != 2)
{
if (SpellPointModifiers[class & ID_MASK] != 0)
{
spellPoints = currentIntelligence + (currentIntelligence >> 2); // Add 0.25x intelligence
}
spellPointBonus = currentIntelligence >> 1; // Add 0.5x intelligence
}
// Calculate the total
spellPoints = spellPoints + spellPointBonus;
}
}
// If class is a sorcerer
if (class == 0x23)
{
spellPoints = currentIntelligence * 3;
}
return spellPoints;
}
The "SpellPointModifiers" array location is 0x3C3E0
.
SpellPointModifiers
02 Mage
00 Spellsword
01 Battlemage // "1" here, but any value other than 2 or 0 has the same effect
FF Sorcerer // Unused
02 Healer
00 Nightblade
FF Bard // Unused
Maximum stamina for the player and NPCs (as stored internally) is obtained as follows:
npcStats->Stamina = (npcStats->CurrentStrength + npcStats->CurrentEndurance) * 64;
Home city ID for the player and NPC humanoids is obtained as follows:
void SetHomeCity(NPCSTATS* npcStats)
{
int maximum = 32;
if (npcStats->Race == 7) { // Argonian
maximum = 31;
}
int random = GetRandomBetween0AndMaximum(maximum); // Gets a random value between 0 and "maximum"
npcStats->HomeCityID = npc->Race * 32 + random;
return;
}
Derived stats for the player and NPCs are obtained as follows:
void DeriveStats(NPCSTATS* npcStats)
{
// Strength-related
npcStats->DamageBonus = (npcStats->CurrentStrength - 0x7a) / 0xd;
npcStats->CarryLimit = npcStats->CurrentStrength * 2;
// Intelligence-related
int intelligence = Convert256Valueto100Value(npcStats->CurrentIntelligence);
int spellPoints = GetSpellPoints(npcStats, intelligence);
npcStats->MaxSpellPoints = spellPoints;
*(short *)(npcStats + 0x3d) = spellPoints; // Unknown
*(short *)(npcStats + 0x3f) = npcStats->CurrentIntelligence - 0x80; // Unknown
// Willpower-related
int willpowerMod = npcStats->CurrentWillpower - 0x80;
npcStats->MagicDefense = -(willpowerMod);
*(short *)(npcStats + 0x45) = willpowerMod >> 1; // Unknown
// Agility-related
int agilityMod = npcStats->CurrentAgility - 0x80;
npcStats->AttackBonus = agilityMod;
npcStats->DefenseBonus = agilityMod;
npcStats->BonusAC = agilityMod;
// Speed-related
*(short *)(npcStats + 0x4d) = (0x10c - npcStats->CurrentSpeed) / 0x19; // Unknown
// Endurance-related
int enduranceMod = (npcStats->CurrentEndurance - 0x74) / 0x19;
npcStats->BonusHealth = enduranceMod;
npcStats->BonusHealing = enduranceMod;
*(short *)(npcStats + 0x51) = npcStats->CurrentEndurance * 2; // Unknown
// Personality-related
npcStats->Charisma = npcStats->CurrentPersonality - 0x74;
// Luck-related
npcStats->Bonus Luck = ((npcStats->CurrentLuck - 0x74) / 0x19) * 2;
// Other
*(char *)(npcStats + 0x5f) = (npcStats->CurrentWillpower + npcStats->CurrentEndurance + 0x200) / 0x400; // Unknown
*(char *)(npcStats + 0x6a) = (npcStats->CurrentStrength + npcStats->CurrentIntelligence + 0x400) / 0x800; // Unknown
npcStats->PoisonSavingThrow = npcStats->CurrentEndurance >> 2; // npcStats + 0x62
npcStats->MagicSavingThrow = (char)npcStats->MagicDefense; // npcStats + 0x64
return;
}