О специализациях по заклинаниям.
Вообще, за специализацию по заклинаниям отвечает
CODE
//----- (004E6260) --------------------------------------------------------
int __thiscall HeroSpellSpecialityEffect(_Hero_ *this, int spell, int heroLevel, signed int effect) //herolevel - уровень подвергаемого заклинанию существа, тащемта
{
signed __int64 v4; // qax@1
LODWORD(v4) = 0;
HIDWORD(v4) = &(*HeroSpecStrPo)[this->Number];
if ( *HIDWORD(v4) == 3 )
{
if ( *(_DWORD *)(HIDWORD(v4) + 4) == spell )
{
switch ( spell )
{
case 43:
case 44:
case 45:
case 46:
case 48:
case 53:
LODWORD(v4) = dword_0063EAA8[heroLevel];
break;
case 55:
LODWORD(v4) = dword_0063EAC4[heroLevel];
break;
case 51:
LODWORD(v4) = 3 - effect;
break;
case 13:
LODWORD(v4) = effect;
break;
case 47:
LODWORD(v4) = 2;
break;
case 15:
LODWORD(v4) = effect >> 1;
break;
default:
v4 = (signed __int64)ceil((double)(effect * this->ExpLevel / (heroLevel + 1)) * 0.03);
break;
}
}
}
return v4;
}
Для дамагающих заклинаний (не уверен про Land Mines) прибавка к урону считается автоматически.
Для баффов и дебаффов (кроме Disrupting Ray) дополнительно есть кусок кода
CODE
switch ( spell )
{
case 27:
v116 = (long double)SchoolLevel;
*(float *)&v5->ShieldMul = v116 / 100.0;
break;
case 28:
v116 = (long double)SchoolLevel;
*(float *)&v5->AirShieldMul = v116 / 100.0;
break;
case 29:
v116 = (long double)SchoolLevel;
v5->FireShieldMul = v116 / 100.0;
break;
case 30:
v116 = (long double)SchoolLevel;
v5->ProtAirMul = v116 / 100.0;
break;
case 31:
v116 = (long double)SchoolLevel;
v5->ProtFireMul = v116 / 100.0;
break;
case 32:
v116 = (long double)SchoolLevel;
v5->ProtWaterMul = v116 / 100.0;
break;
case 33:
v116 = (long double)SchoolLevel;
v5->ProtEarthMul = v116 / 100.0;
break;
case 34:
v5->AntiMagicEffect = vEffect;
v11 = SpellTable_Offset;
v12 = 0;
v13 = 0;
do
{
if ( *(int *)((char *)&v11->Level + v13) < v5->AntiMagicEffect )
{
if ( *(int *)((char *)&v11->FRposNOzerENneg + v13) < 0 )
{
if ( !(*((_BYTE *)&v11->Flags + v13) & 8) )
{
combatMonster_ResetSpellFromStack(v5, v12);
v11 = SpellTable_Offset;
}
}
}
v13 += 136;
++v12;
}
while ( v13 < 11016 );
break;
case 41:
combatMonster_ResetSpellFromStack(v5, 42);
v5->BlessBonus = vEffect;
break;
case 42:
combatMonster_ResetSpellFromStack(v5, 41);
v5->CurseValue = vEffect;
break;
case 43:
v14 = hero;
v5->BloodlustBonus = vEffect;
if ( v14 )
v5->BloodlustBonus += HeroSpellSpecialityEffect(v14, spell, v5->Level, vEffect);
break;
case 44:
v15 = hero;
v5->PrecisionBonus = vEffect;
if ( v15 )
v5->PrecisionBonus += HeroSpellSpecialityEffect(v15, spell, v5->Level, vEffect);
break;
case 45:
v16 = hero;
v5->WeaknessAddedEffect = vEffect;
if ( v16 )
v5->WeaknessAddedEffect += HeroSpellSpecialityEffect(v16, spell, v5->Level, vEffect);
v17 = v5->Attack;
if ( v17 < v5->WeaknessAddedEffect )
v5->WeaknessAddedEffect = v17;
v5->Attack = v17 - v5->WeaknessAddedEffect;
break;
case 46:
v18 = hero;
v5->StoneSkinAddedBonus = vEffect;
if ( v18 )
v5->StoneSkinAddedBonus += HeroSpellSpecialityEffect(v18, spell, v5->Level, vEffect);
v5->Defence += v5->StoneSkinAddedBonus;
break;
case 48:
v19 = hero;
v5->PrayerAddedBonus = vEffect;
if ( v19 )
v5->PrayerAddedBonus += HeroSpellSpecialityEffect(v19, spell, v5->Level, vEffect);
v20 = v5->PrayerAddedBonus;
v21 = v5->Defence;
v5->Attack += v20;
v22 = (unsigned int)v5->Flags >> 6;
v5->Defence = v20 + v21;
if ( !(v22 & 1) )
v5->Speed += v20;
break;
case 49:
v5->MirthEffect = vEffect;
break;
case 50:
v5->SorrowEffect = vEffect;
break;
case 51:
v23 = hero;
v5->FortuneEffect = vEffect;
if ( v23 )
v5->FortuneEffect += HeroSpellSpecialityEffect(v23, spell, v5->Level, vEffect);
break;
case 52:
v5->MisfortuneEffect = vEffect;
break;
case 53:
if ( !(((unsigned int)v5->Flags >> 6) & 1) )
{
combatMonster_ResetSpellFromStack(v5, 54);
v24 = hero;
v5->HasteAddedBonus = vEffect;
if ( v24 )
v5->HasteAddedBonus += HeroSpellSpecialityEffect(v24, spell, v5->Level, vEffect);
v25 = v5->HasteAddedBonus;
v26 = v5->Speed;
v116 = (long double)v5->field_68;
v27 = v116 * 0.65;
v5->Speed = v25 + v26;
v5->field_158 = (signed __int64)v27;
}
break;
case 54:
if ( !(((unsigned int)v5->Flags >> 6) & 1) )
{
combatMonster_ResetSpellFromStack(v5, 53);
v116 = (long double)SchoolLevel;
v5->SlowMul = v116 / 100.0;
v116 = (long double)v5->field_68;
v5->field_158 = (signed __int64)(v116 * 1.5);
}
break;
case 55:
v5->KingType = vLevel;
break;
case 56:
v116 = (long double)SchoolLevel;
v5->FrenzyMul = v116 / 100.0;
break;
case 58:
v28 = v5->Retaliations;
v5->CounterstrikeEffect = vEffect;
v5->Retaliations = vEffect + v28;
break;
case 59:
combatMonster_ResetSpellFromStack(v5, 60);
break;
case 60:
combatMonster_ResetSpellFromStack(v5, 59);
v29 = v5->Hypnotize_528;
if ( v29 )
v30 = (v5->Hypnotize_52C - v29) >> 2;
else
v30 = 0;
v31 = v30;
v32 = v30 - 1;
if ( v31 > 0 )
{
do
{
v34 = *(_DWORD *)(v5->Hypnotize_528 + 4 * v32) + 1300;
v35 = VectorSizeInDwords(v34);
v33 = v35 - 1;
if ( v35 )
{
v36 = *(_DWORD *)(v34 + 4) + 4 * v33;
while ( *(_CombatMonster_ **)v36 != v5 )
{
v37 = v33--;
v36 -= 4;
if ( !v37 )
goto LABEL_68;
}
sub_0054CDC0(v34, *(_DWORD *)(v34 + 4) + 4 * v33);
}
LABEL_68:
v38 = v32--;
}
while ( v38 > 0 );
}
sub_004D4E90((int)&v5->field_524, v5->Hypnotize_528, v5->Hypnotize_52C);
v39 = v5->field_518;
if ( v39 )
v40 = (v5->field_51C - v39) >> 2;
else
v40 = 0;
v41 = v40;
v42 = v40 - 1;
if ( v41 > 0 )
{
do
{
v44 = *(_DWORD *)(v5->field_518 + 4 * v42) + 1316;
v45 = VectorSizeInDwords(v44);
v43 = v45 - 1;
if ( v45 )
{
v46 = *(_DWORD *)(v44 + 4) + 4 * v43;
while ( *(_CombatMonster_ **)v46 != v5 )
{
v47 = v43--;
v46 -= 4;
if ( !v47 )
goto LABEL_79;
}
sub_0054CDC0(v44, *(_DWORD *)(v44 + 4) + 4 * v43);
}
LABEL_79:
v48 = v42--;
}
while ( v48 > 0 );
}
sub_004D4E90((int)&v5->field_514, v5->field_518, v5->field_51C);
combatMonster_CalcUnicornAura((int)v5);
break;
case 62:
v116 = (long double)SchoolLevel;
v5->BlindCounterattackDamageMul = v116 / 100.0;
break;
case 73:
v50 = v5->Defence;
v49 = &hero;
if ( v50 >= 2 )
v49 = &SchoolLevel;
v53 = *(_DWORD *)v49;
v51 = v5->Attack;
SchoolLevel = 2;
v5->DeseaseAddedEffect_Defence = v53;
hero = (_Hero_ *)v51;
v52 = &hero;
if ( v51 >= 2 )
v52 = &SchoolLevel;
v54 = *(_DWORD *)v52;
v5->DeseaseAddedEffect_Attack = v54;
v5->Attack = v51 - v54;
v5->Defence = v50 - v53;
break;
case 71:
v56 = v5->HealthMul - 0.1000000014901161;
v118 = 0;
v119 = 1071644672;
v117 = v56;
v55 = &v118;
if ( (double)v56 >= 0.5 )
v55 = (int *)&v117;
v58 = v55[1];
LODWORD(v116) = *v55;
HIDWORD(v116) = v58;
*(float *)&hero = v116;
v57 = (long double)v5->BaseHealth;
LODWORD(v5->HealthMul) = hero;
if ( v5->SpellDuration[75] )
{
*(float *)&SchoolLevel = v57;
v59 = *(float *)&SchoolLevel * *(float *)&hero * 0.5;
}
else
{
*(float *)&SchoolLevel = v57;
v59 = *(float *)&SchoolLevel * *(float *)&hero;
}
v61 = (signed __int64)(v59 + 0.949999988079071);
v62 = v5->HealthLost;
v5->Health = v61;
LODWORD(v61) = v61 - 1;
SchoolLevel = v62;
hero = (_Hero_ *)v61;
v64 = __SETO__(v61, v62);
v63 = (_DWORD)v61 - v62 < 0;
v60 = (int *)&hero;
if ( !(v63 ^ v64) )
v60 = &SchoolLevel;
v5->HealthLost = *v60;
break;
case 75:
v65 = (long double)v5->BaseHealth;
if ( v5->SpellDuration[75] )
{
*(float *)&hero = v65;
v66 = *(float *)&hero * v5->HealthMul * 0.5;
}
else
{
*(float *)&hero = v65;
v66 = *(float *)&hero * v5->HealthMul;
}
v69 = (signed __int64)(v66 + 0.949999988079071);
v70 = v69;
v5->Health = v69;
LODWORD(v69) = v5->HealthLost;
v68 = (_Hero_ *)(v70 - 1);
v72 = __SETO__(v68, v69);
v71 = (signed int)((char *)v68 - v69) < 0;
v67 = &hero;
if ( !(v71 ^ v72) )
v67 = &SchoolLevel;
v74 = *(_DWORD *)v67;
hero = v68;
v5->HealthLost = v74;
SchoolLevel = v74;
v76 = __SETO__(v68, v74);
v75 = (signed int)((char *)v68 - v74) < 0;
v73 = (int *)&hero;
if ( !(v75 ^ v76) )
v73 = &SchoolLevel;
v5->HealthLost = *v73;
break;
case 36:
v5->MagicMirrorEffect = vEffect;
break;
case 61:
v5->ForgetfulnessLevel = vLevel;
break;
default:
break;
}
Из него мы видим, что программисты героев были ленивыми и отсутствующие специальности (зеркало, проклятье, замедление, защиты-щиты, ярость, неудачу-мораль-уныние etc) кодить не стали.
Палач, блесс, оба воскрешения, разрывающий луч, гипноз и лечение здесь не упомянуты, но есть в других местах.
Все остальное - не реализовано.