Monster levels in Classic and few other stats.

Post here about all aspects of D2 mod making whether it's information, problems or whatever. Please specify whether your post is relating to Classic D2 or the Expansion.

Moderator: Nizari

User avatar
aytosy
Posts: 2
Joined: Mon Jan 16, 2023 1:31 am

Monster levels in Classic and few other stats.

Post by aytosy » Wed Nov 01, 2023 5:04 pm

With Classic, I'm referring to mode in game, where Expansion checkbox in unchecked. This applies to versions 1.10-1.14 of D2:LoD. I presume it is same for patch 1.09 and wouldn't be surprised if did work the same in D2R.

If you ever tried to adjust monster level for Classic, you can notice few things:
- MonLvl1, MonLvl2, MonLvl3 from Levels.txt are completely ignored (irrelevant of NoRatio flag in monstats.txt).
- Level(N) and Level(H) from monstats.txt are ignored also.

Sounds like something is hard-coded? Kinda, since I omitted Level from monstats.txt (value for Normal difficulty). Turns out only value that affects Classic monster level in Nightmare/Hell is value of Level from Normal Difficulty. If you try changing it, you might notice that:
- In Nightmare: mlvl = Level + 25
- In Hell: mlvl = Level + 50

Example: if you want to raise level of monster in Hell Classic to 90, you need to change value for Level in monstats.txt to 40 (Normal difficulty). Same monster will now get mlvl 65 in Nightmare.

For those looking for more technical details, here is function that is called from MONSTER_InitializeStatsAndSkills(), after most of stats are initialized for a monster. This means also most stats are calculated for Expansion first (including things like MonLvl.txt also).

Code: Select all

D2Common_11246(pUnit, pGame->bExpansion, pGame->nDifficulty);
And here is function itself, taken from D2MOO (shouts to everyone working on this project).

Code: Select all

void __stdcall D2Common_11246(D2UnitStrc* pMonster, int a2, uint8_t a3)
{
    D2MonStatsTxt* pMonStatsTxtRecord = NULL;

    if (!a2 && a3 && pMonster && pMonster->dwUnitType == UNIT_MONSTER)
    {
        pMonStatsTxtRecord = DATATBLS_GetMonStatsTxtRecord(pMonster->dwClassId);
        if (pMonStatsTxtRecord && pMonStatsTxtRecord->nAlign != 1)
        {
            STATLIST_SetUnitStat(pMonster, STAT_MAXHP, STATLIST_UnitGetStatValue(pMonster, STAT_MAXHP, 0) / 2, 0);
            STATLIST_SetUnitStat(pMonster, STAT_ARMORCLASS, 10 * STATLIST_UnitGetStatValue(pMonster, STAT_ARMORCLASS, 0) / 12, 0);
            STATLIST_SetUnitStat(pMonster, STAT_EXPERIENCE, 10 * STATLIST_UnitGetStatValue(pMonster, STAT_EXPERIENCE, 0) / (a3 == 1 ? 17 : 26), 0);
            STATLIST_SetUnitStat(pMonster, STAT_LEVEL, 25 * a3 + pMonStatsTxtRecord->nLevel[0], 0);
        }
    }
}
In simplified version, stats used for Classic:
- Mlvl matches Nightmare +25 and Hell +50 pattern discussed previously
- MaxHP is half of that in Expansion.
- AC is 10/12 of that in Expansion.
- XP is 10/17 in Nightmare and 10/26 in Hell, based on Expansion values.

Return to “General Mod Making”