mirror of
https://github.com/afritz1/OpenTESArena.git
synced 2026-09-11 12:56:41 +02:00
Page:
Player stats
Pages
Character Generation
Chasms
City Generation
Combat
Dialogue
Diseases
Dungeon Generation
Home
Interiors
Items
Light levels
Loot
Movement
NPCs
Name generation
Player stats
Resting
Save File Formats
Services
Shops
Sky behavior
Skybox
Spellmaker
Spells
Thieving
Time and Calendar
Timing
Travel
User interface
Weather
Wilderness
No results
21
Player stats
Allofich edited this page 2020-04-16 02:34:23 +09:00
Table of contents
Health on generation
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
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
Maximum stamina for the player and NPCs (as stored internally) is obtained as follows:
npcStats->Stamina = (npcStats->CurrentStrength + npcStats->CurrentEndurance) * 64;
Home city ID
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
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;
}