- Код: Выделить всё
#define _CRT_SECURE_NO_WARNINGS
#include <bitset>
#include "..\..\HotA\homm3.h"
#define SPELLS_MAX 128
#define ANIMS_MAX 128
#define ADVSPELLS_NUM 10
#define SPECABIL_NUM 11
#define ARTIFACTS_NUM 144
#define SPELLS_NUM 89
#define SPL_FEAR_NEW 81
#define SPL_POISON_NEW 82
#define SPL_DISEASE_NEW 83
#define SPL_AGING_NEW 84
#define SPL_DEATH_CLOUD_NEW 85
#define SPL_DEATH_BLOW_NEW 86
#define SPL_FIREBIRD_NEW 87
#define SPL_MAGIC_ELEMENTAL_NEW 88
#define ANIMS_NUM 89
#define ANIM_FEAR_NEW 83
#define ANIM_POISON_NEW 84
#define ANIM_DISEASE_NEW 85
#define ANIM_AGING_NEW 86
#define ANIM_DEATH_CLOUD_NEW 87
#define ANIM_DEATH_BLOW_NEW 88
Patcher* _P;
PatcherInstance* _PI;
struct _ComboArtInfo_ {
int index;
std::bitset<160> parts;
};
struct _MagicAnim_ {
char* defName;
char* name;
int type;
};
#define o_ComboArtInfo (*(_ComboArtInfo_**)0x660B6C)
#define o_MagicAnim ((_MagicAnim_*)0x641E18)
_Spell_ spell[SPELLS_MAX];
_MagicAnim_ anim[ANIMS_MAX];
//char iniPath[MAX_PATH];
char spellIndirectTableA[] = {
// Spells (starting from Quicksand #10)
0, 1, 2, 2, 3, 4, 4, 4, 4, 4,
5, 5, 5, 5, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
6, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 5,
4, 4, 4, 7, 8, 9, 10, 10, 10, 10,
// Special Abilities (you cannot cast them anyway)
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1,
// New Spells (starting from Fear #81)
4, 4, 4, 4, 5, 4, 10, 10
};
char spellIndirectTableB[] = {
// Spells (starting from Quicksand #10)
0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
10, 11, 12, 13, 14, 15, 16, 17, 17, 17,
17, 17, 17, 17, 17, 18, 17, 19, 20, 20,
21, 17, 17, 22, 17, 17, 17, 23, 17, 17,
17, 17, 17, 17, 17, 17, 17, 7, 17, 24,
17, 17, 17, 25, 26, 27, 28, 29, 30, 31,
// Special Abilities
32, 33, 34, 17, 17, 34, 37, 37, 35, 37,
36,
// New Spells (starting from Fear #81)
17, 17, 17, 17, 11, 17, 38, 39
};
char spellIndirectTableC[] = {
// Spells (starting from Shield #27)
0, 1, 2, 3, 4, 5, 6, 7, 32, 8,
32, 32, 32, 32, 9, 10, 11, 12, 13, 14,
32, 15, 16, 17, 18, 19, 20, 21, 22, 23,
32, 24, 25, 26, 27, 28, 32, 32, 32, 32,
32, 32, 32,
// Special Abilities
32, 29, 32, 30, 32, 31, -1, -1, -1, -1,
-1,
// New Spells (starting from Fear #81)
32, 32, 33, 32, 32, 32, 32, 32
};
char spellIndirectTableD[] = {
// Spells (starting from Weakness #45)
0, 1, 9, 2, 9, 9, 9, 9, 3, 4,
9, 9, 9, 9, 9, 5, 9, 9, 9, 9,
9, 9, 9, 9, 9,
// Special Abilities
9, 9, 6, 7, 9, 8, -1, -1, -1, -1,
-1,
// New Spells (starting from Fear #81)
9, 9, 10, 9, 9, 9, 9, 9
};
bool shrineSpells[SPELLS_MAX];
struct DiseaseSpellParams {
int AttackPenalty;
int DefensePenalty;
int SpeedPenalty;
};
DiseaseSpellParams diseaseSpell[4];
DiseaseSpellParams diseaseSpellParams[2][21];
int __stdcall afterInit(LoHook* h, HookContext* c)
{
// Spell Table
for (int i = 0; i < SPL_FEAR_NEW; ++i)
spell[i] = o_Spell[i];
// Fear
spell[SPL_FEAR_NEW].type = -1;
spell[SPL_FEAR_NEW].wav_name = "FearRoE.wav";
spell[SPL_FEAR_NEW].animation_ix = ANIM_FEAR_NEW;
spell[SPL_FEAR_NEW].flags = 0x20415;
spell[SPL_FEAR_NEW].name = "Fear";
spell[SPL_FEAR_NEW].short_name = "Fear";
spell[SPL_FEAR_NEW].level = 4;
spell[SPL_FEAR_NEW].school_flags = SSF_EARTH;
spell[SPL_FEAR_NEW].mana_cost[0] = 16;
spell[SPL_FEAR_NEW].mana_cost[1] = 8;
spell[SPL_FEAR_NEW].mana_cost[2] = 8;
spell[SPL_FEAR_NEW].mana_cost[3] = 8;
spell[SPL_FEAR_NEW].eff_power = 0;
spell[SPL_FEAR_NEW].effect[0] = 75;
spell[SPL_FEAR_NEW].effect[1] = 75;
spell[SPL_FEAR_NEW].effect[2] = 50;
spell[SPL_FEAR_NEW].effect[3] = 25;
spell[SPL_FEAR_NEW].chance2get_var[0] = 10;
spell[SPL_FEAR_NEW].chance2get_var[1] = 10;
spell[SPL_FEAR_NEW].chance2get_var[2] = 10;
spell[SPL_FEAR_NEW].chance2get_var[3] = 10;
spell[SPL_FEAR_NEW].chance2get_var[4] = 10;
spell[SPL_FEAR_NEW].chance2get_var[5] = 10;
spell[SPL_FEAR_NEW].chance2get_var[6] = 10;
spell[SPL_FEAR_NEW].chance2get_var[7] = 10;
spell[SPL_FEAR_NEW].chance2get_var[8] = 10;
spell[SPL_FEAR_NEW].ai_value[0] = 50;
spell[SPL_FEAR_NEW].ai_value[1] = 50;
spell[SPL_FEAR_NEW].ai_value[2] = 50;
spell[SPL_FEAR_NEW].ai_value[3] = 50;
spell[SPL_FEAR_NEW].description[0] =
"{Fear}\n\nStrikes an enemy unit with such fear that it becomes unable to attack and nearly unable to move.\n";
spell[SPL_FEAR_NEW].description[1] =
"{Basic Fear}\n\nStrikes an enemy unit with such fear that it becomes unable to attack and nearly unable to move.\n\nSpell Point cost is half that of Normal Fear.\n";
spell[SPL_FEAR_NEW].description[2] =
"{Advanced Fear}\n\nStrikes an enemy unit with such fear that it becomes unable to attack and nearly unable to move.\n\nPenalty to movement is twice that of Basic Fear.\n";
spell[SPL_FEAR_NEW].description[3] =
"{Expert Fear}\n\nStrikes an enemy unit with such fear that it becomes unable to attack and nearly unable to move.\n\nPenalty to movement is three times that of Basic Fear.\n";
// Poison
spell[SPL_POISON_NEW].type = -1;
spell[SPL_POISON_NEW].wav_name = "Poison.wav";
spell[SPL_POISON_NEW].animation_ix = ANIM_POISON_NEW;
spell[SPL_POISON_NEW].flags = 0x1015;
spell[SPL_POISON_NEW].name = "Poison";
spell[SPL_POISON_NEW].short_name = "Poison";
spell[SPL_POISON_NEW].level = 4;
spell[SPL_POISON_NEW].school_flags = SSF_EARTH;
spell[SPL_POISON_NEW].mana_cost[0] = 20;
spell[SPL_POISON_NEW].mana_cost[1] = 16;
spell[SPL_POISON_NEW].mana_cost[2] = 16;
spell[SPL_POISON_NEW].mana_cost[3] = 16;
spell[SPL_POISON_NEW].eff_power = 0;
spell[SPL_POISON_NEW].effect[0] = 0;
spell[SPL_POISON_NEW].effect[1] = 0;
spell[SPL_POISON_NEW].effect[2] = 0;
spell[SPL_POISON_NEW].effect[3] = 0;
spell[SPL_POISON_NEW].chance2get_var[0] = 10;
spell[SPL_POISON_NEW].chance2get_var[1] = 10;
spell[SPL_POISON_NEW].chance2get_var[2] = 10;
spell[SPL_POISON_NEW].chance2get_var[3] = 10;
spell[SPL_POISON_NEW].chance2get_var[4] = 10;
spell[SPL_POISON_NEW].chance2get_var[5] = 10;
spell[SPL_POISON_NEW].chance2get_var[6] = 10;
spell[SPL_POISON_NEW].chance2get_var[7] = 10;
spell[SPL_POISON_NEW].chance2get_var[8] = 10;
spell[SPL_POISON_NEW].ai_value[0] = 50;
spell[SPL_POISON_NEW].ai_value[1] = 50;
spell[SPL_POISON_NEW].ai_value[2] = 50;
spell[SPL_POISON_NEW].ai_value[3] = 50;
spell[SPL_POISON_NEW].description[0] =
"{Poison}\n\nPoison Description.\n";
spell[SPL_POISON_NEW].description[1] =
"{Basic Poison}\n\nBasic Poison Description.\n";
spell[SPL_POISON_NEW].description[2] =
"{Advanced Poison}\n\nAdvanced Poison Description.\n";
spell[SPL_POISON_NEW].description[3] =
"{Expert Poison}\n\nExpert Poison Description.\n";
// Disease
spell[SPL_DISEASE_NEW].type = -1;
spell[SPL_DISEASE_NEW].wav_name = "Disease.wav";
spell[SPL_DISEASE_NEW].animation_ix = ANIM_DISEASE_NEW;
spell[SPL_DISEASE_NEW].flags = 0x40045;
spell[SPL_DISEASE_NEW].name = "Disease";
spell[SPL_DISEASE_NEW].short_name = "Disease";
spell[SPL_DISEASE_NEW].level = 4;
spell[SPL_DISEASE_NEW].school_flags = SSF_EARTH;
spell[SPL_DISEASE_NEW].mana_cost[0] = 16;
spell[SPL_DISEASE_NEW].mana_cost[1] = 12;
spell[SPL_DISEASE_NEW].mana_cost[2] = 12;
spell[SPL_DISEASE_NEW].mana_cost[3] = 12;
spell[SPL_DISEASE_NEW].eff_power = 0;
spell[SPL_DISEASE_NEW].effect[0] = 2;
spell[SPL_DISEASE_NEW].effect[1] = 2;
spell[SPL_DISEASE_NEW].effect[2] = 4;
spell[SPL_DISEASE_NEW].effect[3] = 4;
spell[SPL_DISEASE_NEW].chance2get_var[0] = 10;
spell[SPL_DISEASE_NEW].chance2get_var[1] = 10;
spell[SPL_DISEASE_NEW].chance2get_var[2] = 10;
spell[SPL_DISEASE_NEW].chance2get_var[3] = 10;
spell[SPL_DISEASE_NEW].chance2get_var[4] = 10;
spell[SPL_DISEASE_NEW].chance2get_var[5] = 10;
spell[SPL_DISEASE_NEW].chance2get_var[6] = 10;
spell[SPL_DISEASE_NEW].chance2get_var[7] = 10;
spell[SPL_DISEASE_NEW].chance2get_var[8] = 10;
spell[SPL_DISEASE_NEW].ai_value[0] = 50;
spell[SPL_DISEASE_NEW].ai_value[1] = 50;
spell[SPL_DISEASE_NEW].ai_value[2] = 50;
spell[SPL_DISEASE_NEW].ai_value[3] = 50;
spell[SPL_DISEASE_NEW].description[0] =
"{Disease}\n\nDisease Description.\n";
spell[SPL_DISEASE_NEW].description[1] =
"{Basic Disease}\n\nBasic Disease Description.\n";
spell[SPL_DISEASE_NEW].description[2] =
"{Advanced Disease}\n\nAdvanced Disease Description.\n";
spell[SPL_DISEASE_NEW].description[3] =
"{Expert Disease}\n\nExpert Disease Description.\n";
diseaseSpell[0].AttackPenalty = 2;
diseaseSpell[0].DefensePenalty = 2;
diseaseSpell[0].SpeedPenalty = 20;
diseaseSpell[1].AttackPenalty = 2;
diseaseSpell[1].DefensePenalty = 2;
diseaseSpell[1].SpeedPenalty = 20;
diseaseSpell[2].AttackPenalty = 4;
diseaseSpell[2].DefensePenalty = 4;
diseaseSpell[2].SpeedPenalty = 40;
diseaseSpell[3].AttackPenalty = 4;
diseaseSpell[3].DefensePenalty = 4;
diseaseSpell[3].SpeedPenalty = 40;
// Aging
spell[SPL_AGING_NEW].type = -1;
spell[SPL_AGING_NEW].wav_name = "Age.wav";
spell[SPL_AGING_NEW].animation_ix = ANIM_AGING_NEW;
spell[SPL_AGING_NEW].flags = 0x1015;
spell[SPL_AGING_NEW].name = "Aging";
spell[SPL_AGING_NEW].short_name = "Aging";
spell[SPL_AGING_NEW].level = 5;
spell[SPL_AGING_NEW].school_flags = SSF_FIRE;
spell[SPL_AGING_NEW].mana_cost[0] = 25;
spell[SPL_AGING_NEW].mana_cost[1] = 20;
spell[SPL_AGING_NEW].mana_cost[2] = 20;
spell[SPL_AGING_NEW].mana_cost[3] = 20;
spell[SPL_AGING_NEW].eff_power = 0;
spell[SPL_AGING_NEW].effect[0] = 0;
spell[SPL_AGING_NEW].effect[1] = 0;
spell[SPL_AGING_NEW].effect[2] = 0;
spell[SPL_AGING_NEW].effect[3] = 0;
spell[SPL_AGING_NEW].chance2get_var[0] = 10;
spell[SPL_AGING_NEW].chance2get_var[1] = 10;
spell[SPL_AGING_NEW].chance2get_var[2] = 10;
spell[SPL_AGING_NEW].chance2get_var[3] = 10;
spell[SPL_AGING_NEW].chance2get_var[4] = 10;
spell[SPL_AGING_NEW].chance2get_var[5] = 10;
spell[SPL_AGING_NEW].chance2get_var[6] = 10;
spell[SPL_AGING_NEW].chance2get_var[7] = 10;
spell[SPL_AGING_NEW].chance2get_var[8] = 10;
spell[SPL_AGING_NEW].ai_value[0] = 50;
spell[SPL_AGING_NEW].ai_value[1] = 50;
spell[SPL_AGING_NEW].ai_value[2] = 50;
spell[SPL_AGING_NEW].ai_value[3] = 50;
spell[SPL_AGING_NEW].description[0] =
"{Aging}\n\nAging Description.\n";
spell[SPL_AGING_NEW].description[1] =
"{Basic Aging}\n\nBasic Aging Description.\n";
spell[SPL_AGING_NEW].description[2] =
"{Advanced Aging}\n\nAdvanced Aging Description.\n";
spell[SPL_AGING_NEW].description[3] =
"{Expert Aging}\n\nExpert Aging Description.\n";
// Death Cloud
spell[SPL_DEATH_CLOUD_NEW].type = 0;
spell[SPL_DEATH_CLOUD_NEW].wav_name = "Deathcld.wav";
spell[SPL_DEATH_CLOUD_NEW].animation_ix = ANIM_DEATH_CLOUD_NEW;
spell[SPL_DEATH_CLOUD_NEW].flags = 0x8281;
spell[SPL_DEATH_CLOUD_NEW].name = "Death Cloud";
spell[SPL_DEATH_CLOUD_NEW].short_name = "Death Cloud";
spell[SPL_DEATH_CLOUD_NEW].level = 5;
spell[SPL_DEATH_CLOUD_NEW].school_flags = SSF_EARTH;
spell[SPL_DEATH_CLOUD_NEW].mana_cost[0] = 25;
spell[SPL_DEATH_CLOUD_NEW].mana_cost[1] = 20;
spell[SPL_DEATH_CLOUD_NEW].mana_cost[2] = 20;
spell[SPL_DEATH_CLOUD_NEW].mana_cost[3] = 20;
spell[SPL_DEATH_CLOUD_NEW].eff_power = 40;
spell[SPL_DEATH_CLOUD_NEW].effect[0] = 30;
spell[SPL_DEATH_CLOUD_NEW].effect[1] = 30;
spell[SPL_DEATH_CLOUD_NEW].effect[2] = 60;
spell[SPL_DEATH_CLOUD_NEW].effect[3] = 120;
spell[SPL_DEATH_CLOUD_NEW].chance2get_var[0] = 10;
spell[SPL_DEATH_CLOUD_NEW].chance2get_var[1] = 10;
spell[SPL_DEATH_CLOUD_NEW].chance2get_var[2] = 10;
spell[SPL_DEATH_CLOUD_NEW].chance2get_var[3] = 10;
spell[SPL_DEATH_CLOUD_NEW].chance2get_var[4] = 10;
spell[SPL_DEATH_CLOUD_NEW].chance2get_var[5] = 10;
spell[SPL_DEATH_CLOUD_NEW].chance2get_var[6] = 10;
spell[SPL_DEATH_CLOUD_NEW].chance2get_var[7] = 10;
spell[SPL_DEATH_CLOUD_NEW].chance2get_var[8] = 10;
spell[SPL_DEATH_CLOUD_NEW].ai_value[0] = 50;
spell[SPL_DEATH_CLOUD_NEW].ai_value[1] = 50;
spell[SPL_DEATH_CLOUD_NEW].ai_value[2] = 50;
spell[SPL_DEATH_CLOUD_NEW].ai_value[3] = 50;
spell[SPL_DEATH_CLOUD_NEW].description[0] =
"{Death Cloud}\n\nDeath Cloud Description.\n";
spell[SPL_DEATH_CLOUD_NEW].description[1] =
"{Basic Death Cloud}\n\nBasic Death Cloud Description.\n";
spell[SPL_DEATH_CLOUD_NEW].description[2] =
"{Advanced Death Cloud}\n\nAdvanced Death Cloud Description.\n";
spell[SPL_DEATH_CLOUD_NEW].description[3] =
"{Expert Death Cloud}\n\nExpert Death Cloud Description.\n";
// Death Blow
spell[SPL_DEATH_BLOW_NEW].type = 1;
spell[SPL_DEATH_BLOW_NEW].wav_name = "Deathblo.wav";
spell[SPL_DEATH_BLOW_NEW].animation_ix = ANIM_DEATH_BLOW_NEW;
spell[SPL_DEATH_BLOW_NEW].flags = 0x1015;
spell[SPL_DEATH_BLOW_NEW].name = "Death Blow";
spell[SPL_DEATH_BLOW_NEW].short_name = "Death Blow";
spell[SPL_DEATH_BLOW_NEW].level = 5;
spell[SPL_DEATH_BLOW_NEW].school_flags = SSF_FIRE;
spell[SPL_DEATH_BLOW_NEW].mana_cost[0] = 25;
spell[SPL_DEATH_BLOW_NEW].mana_cost[1] = 20;
spell[SPL_DEATH_BLOW_NEW].mana_cost[2] = 20;
spell[SPL_DEATH_BLOW_NEW].mana_cost[3] = 20;
spell[SPL_DEATH_BLOW_NEW].eff_power = 0;
spell[SPL_DEATH_BLOW_NEW].effect[0] = 0;
spell[SPL_DEATH_BLOW_NEW].effect[1] = 0;
spell[SPL_DEATH_BLOW_NEW].effect[2] = 0;
spell[SPL_DEATH_BLOW_NEW].effect[3] = 0;
spell[SPL_DEATH_BLOW_NEW].chance2get_var[0] = 10;
spell[SPL_DEATH_BLOW_NEW].chance2get_var[1] = 10;
spell[SPL_DEATH_BLOW_NEW].chance2get_var[2] = 10;
spell[SPL_DEATH_BLOW_NEW].chance2get_var[3] = 10;
spell[SPL_DEATH_BLOW_NEW].chance2get_var[4] = 10;
spell[SPL_DEATH_BLOW_NEW].chance2get_var[5] = 10;
spell[SPL_DEATH_BLOW_NEW].chance2get_var[6] = 10;
spell[SPL_DEATH_BLOW_NEW].chance2get_var[7] = 10;
spell[SPL_DEATH_BLOW_NEW].chance2get_var[8] = 10;
spell[SPL_DEATH_BLOW_NEW].ai_value[0] = 50;
spell[SPL_DEATH_BLOW_NEW].ai_value[1] = 50;
spell[SPL_DEATH_BLOW_NEW].ai_value[2] = 50;
spell[SPL_DEATH_BLOW_NEW].ai_value[3] = 50;
spell[SPL_DEATH_BLOW_NEW].description[0] =
"{Death Blow}\n\nDeath Blow Description.\n";
spell[SPL_DEATH_BLOW_NEW].description[1] =
"{Basic Death Blow}\n\nBasic Death Blow Description.\n";
spell[SPL_DEATH_BLOW_NEW].description[2] =
"{Advanced Death Blow}\n\nAdvanced Death Blow Description.\n";
spell[SPL_DEATH_BLOW_NEW].description[3] =
"{Expert Death Blow}\n\nExpert Death Blow Description.\n";
// Firebird
spell[SPL_FIREBIRD_NEW].type = 0;
spell[SPL_FIREBIRD_NEW].wav_name = "SumnElm.wav";
spell[SPL_FIREBIRD_NEW].animation_ix = ID_NONE;
spell[SPL_FIREBIRD_NEW].flags = 0x80001;
spell[SPL_FIREBIRD_NEW].name = "Firebird";
spell[SPL_FIREBIRD_NEW].short_name = "Firebird";
spell[SPL_FIREBIRD_NEW].level = 5;
spell[SPL_FIREBIRD_NEW].school_flags = SSF_FIRE;
spell[SPL_FIREBIRD_NEW].mana_cost[0] = 30;
spell[SPL_FIREBIRD_NEW].mana_cost[1] = 25;
spell[SPL_FIREBIRD_NEW].mana_cost[2] = 25;
spell[SPL_FIREBIRD_NEW].mana_cost[3] = 25;
spell[SPL_FIREBIRD_NEW].eff_power = 0;
spell[SPL_FIREBIRD_NEW].effect[0] = 50;
spell[SPL_FIREBIRD_NEW].effect[1] = 50;
spell[SPL_FIREBIRD_NEW].effect[2] = 75;
spell[SPL_FIREBIRD_NEW].effect[3] = 100;
spell[SPL_FIREBIRD_NEW].chance2get_var[0] = 10;
spell[SPL_FIREBIRD_NEW].chance2get_var[1] = 10;
spell[SPL_FIREBIRD_NEW].chance2get_var[2] = 10;
spell[SPL_FIREBIRD_NEW].chance2get_var[3] = 10;
spell[SPL_FIREBIRD_NEW].chance2get_var[4] = 10;
spell[SPL_FIREBIRD_NEW].chance2get_var[5] = 10;
spell[SPL_FIREBIRD_NEW].chance2get_var[6] = 10;
spell[SPL_FIREBIRD_NEW].chance2get_var[7] = 10;
spell[SPL_FIREBIRD_NEW].chance2get_var[8] = 10;
spell[SPL_FIREBIRD_NEW].ai_value[0] = 50;
spell[SPL_FIREBIRD_NEW].ai_value[1] = 50;
spell[SPL_FIREBIRD_NEW].ai_value[2] = 100;
spell[SPL_FIREBIRD_NEW].ai_value[3] = 150;
spell[SPL_FIREBIRD_NEW].description[0] =
"{Firebird}\n\nAllows you to summon firebirds. Once cast, no other elemental types may be summoned.\n";
spell[SPL_FIREBIRD_NEW].description[1] =
"{Basic Firebird}\n\nAllows you to summon firebirds. Once cast, no other elemental types may be summoned.\n";
spell[SPL_FIREBIRD_NEW].description[2] =
"{Advanced Firebird}\n\nAllows you to summon firebirds. Once cast, no other elemental types may be summoned.\n\n" \
"Summons approximately one-and-a-half times the number of units as Basic Summon Firebird.\n";
spell[SPL_FIREBIRD_NEW].description[3] =
"{Expert Firebird}\n\nAllows you to summon firebirds. Once cast, no other elemental types may be summoned.\n\n" \
"Summons approximately twice the number of units as Basic Summon Firebird.\n";
// Magic Elemental
spell[SPL_MAGIC_ELEMENTAL_NEW].type = 0;
spell[SPL_MAGIC_ELEMENTAL_NEW].wav_name = "SumnElm.wav";
spell[SPL_MAGIC_ELEMENTAL_NEW].animation_ix = ID_NONE;
spell[SPL_MAGIC_ELEMENTAL_NEW].flags = 0x80001;
spell[SPL_MAGIC_ELEMENTAL_NEW].name = "Magic Elemental";
spell[SPL_MAGIC_ELEMENTAL_NEW].short_name = "Magic Elemental";
spell[SPL_MAGIC_ELEMENTAL_NEW].level = 5;
spell[SPL_MAGIC_ELEMENTAL_NEW].school_flags = SSF_AIR | SSF_FIRE | SSF_WATER | SSF_EARTH;
spell[SPL_MAGIC_ELEMENTAL_NEW].mana_cost[0] = 30;
spell[SPL_MAGIC_ELEMENTAL_NEW].mana_cost[1] = 25;
spell[SPL_MAGIC_ELEMENTAL_NEW].mana_cost[2] = 25;
spell[SPL_MAGIC_ELEMENTAL_NEW].mana_cost[3] = 25;
spell[SPL_MAGIC_ELEMENTAL_NEW].eff_power = 0;
spell[SPL_MAGIC_ELEMENTAL_NEW].effect[0] = 100;
spell[SPL_MAGIC_ELEMENTAL_NEW].effect[1] = 100;
spell[SPL_MAGIC_ELEMENTAL_NEW].effect[2] = 150;
spell[SPL_MAGIC_ELEMENTAL_NEW].effect[3] = 200;
spell[SPL_MAGIC_ELEMENTAL_NEW].chance2get_var[0] = 10;
spell[SPL_MAGIC_ELEMENTAL_NEW].chance2get_var[1] = 10;
spell[SPL_MAGIC_ELEMENTAL_NEW].chance2get_var[2] = 10;
spell[SPL_MAGIC_ELEMENTAL_NEW].chance2get_var[3] = 10;
spell[SPL_MAGIC_ELEMENTAL_NEW].chance2get_var[4] = 10;
spell[SPL_MAGIC_ELEMENTAL_NEW].chance2get_var[5] = 10;
spell[SPL_MAGIC_ELEMENTAL_NEW].chance2get_var[6] = 10;
spell[SPL_MAGIC_ELEMENTAL_NEW].chance2get_var[7] = 10;
spell[SPL_MAGIC_ELEMENTAL_NEW].chance2get_var[8] = 10;
spell[SPL_MAGIC_ELEMENTAL_NEW].ai_value[0] = 50;
spell[SPL_MAGIC_ELEMENTAL_NEW].ai_value[1] = 50;
spell[SPL_MAGIC_ELEMENTAL_NEW].ai_value[2] = 100;
spell[SPL_MAGIC_ELEMENTAL_NEW].ai_value[3] = 150;
spell[SPL_MAGIC_ELEMENTAL_NEW].description[0] =
"{Magic Elemental}\n\nAllows you to summon magic elementals. Once cast, no other elemental types may be summoned.\n";
spell[SPL_MAGIC_ELEMENTAL_NEW].description[1] =
"{Basic Magic Elemental}\n\nAllows you to summon magic elementals. Once cast, no other elemental types may be summoned.\n";
spell[SPL_MAGIC_ELEMENTAL_NEW].description[2] =
"{Advanced Magic Elemental}\n\nAllows you to summon magic elementals. Once cast, no other elemental types may be summoned.\n\n" \
"Summons approximately one-and-a-half times the number of units as Basic Summon Magic Elemental.\n";
spell[SPL_MAGIC_ELEMENTAL_NEW].description[3] =
"{Expert Magic Elemental}\n\nAllows you to summon magic elementals. Once cast, no other elemental types may be summoned.\n\n" \
"Summons approximately twice the number of units as Basic Summon Magic Elemental.\n";
_PI->WriteDword(0x687FA8, (int)&spell);
// Magic Animation Table
for (int i = 0; i < ANIM_FEAR_NEW; ++i)
anim[i] = o_MagicAnim[i];
// Fear
anim[ANIM_FEAR_NEW].defName = "C07spE0.def";
anim[ANIM_FEAR_NEW].name = "Fear";
anim[ANIM_FEAR_NEW].type = 0x101;
// Poison
anim[ANIM_POISON_NEW].defName = "sp11_.def";
anim[ANIM_POISON_NEW].name = "Poison";
anim[ANIM_POISON_NEW].type = 1;
// Disease
anim[ANIM_DISEASE_NEW].defName = "sp05_.def";
anim[ANIM_DISEASE_NEW].name = "Disease";
anim[ANIM_DISEASE_NEW].type = 1;
// Aging
anim[ANIM_AGING_NEW].defName = "sp01_.def";
anim[ANIM_AGING_NEW].name = "Aging";
anim[ANIM_AGING_NEW].type = 1;
// Death Cloud
anim[ANIM_DEATH_CLOUD_NEW].defName = "sp04_.def";
anim[ANIM_DEATH_CLOUD_NEW].name = "DeathCloud";
anim[ANIM_DEATH_CLOUD_NEW].type = 1;
// Death Blow
anim[ANIM_DEATH_BLOW_NEW].defName = "sp03_.def";
anim[ANIM_DEATH_BLOW_NEW].name = "DeathBlow";
anim[ANIM_DEATH_BLOW_NEW].type = 1;
int AnimAddrDefName[] = {0x43F77E, 0x43FB6A, 0x4963FB, 0x4965CF, 0x5A5036, 0x5A6B14, 0x5A7A74, 0x5A962C};
int AnimAddrName[] = {0x4689C4, 0x49651A, 0x4966CD, 0x5A6D2D, 0x5A7B06};
for (int i = 0; i < sizeof(AnimAddrDefName) / sizeof(int); ++i)
_PI->WriteDword(AnimAddrDefName[i], (int)&anim->defName);
for (int i = 0; i < sizeof(AnimAddrName) / sizeof(int); ++i)
_PI->WriteDword(AnimAddrName[i], (int)&anim->name);
_PI->WriteDword(0x43E503, (int)&anim->type);
return EXEC_DEFAULT;
}
int __stdcall disableCreatureSpells(LoHook* h, HookContext* c)
{
for (int i = SPL_STONE; i <= SPL_ACID_BREATH; ++i)
o_GameMgr->disabled_shrines[i] = true;
return EXEC_DEFAULT;
}
int __stdcall shrineSpellsInit(LoHook* h, HookContext* c)
{
for (int i = SPL_STONE; i <= SPL_ACID_BREATH; ++i)
o_GameMgr->disabled_shrines[i] = true;
memcpy(&shrineSpells, &o_GameMgr->disabled_shrines, sizeof(shrineSpells) / sizeof(bool));
c->return_address = 0x4C2641;
return NO_EXEC_DEFAULT;
}
int __fastcall fillShrines(_GameMgr_* game, int unused_edx, int shrineFlags)
{
int availSpellsNum = 0;
for (int i = 0; i < SPELLS_NUM; ++i)
{
int lvl = o_Spell[i].level - 1;
if (lvl < 5 && 1 << lvl & shrineFlags && o_Spell[i].school_flags && !shrineSpells[i])
++availSpellsNum;
}
int spell = 0;
int chosenSpell = 0;
if (availSpellsNum)
{
int rndSpell = Randint(0, availSpellsNum - 1);
for (int i = 0; i < SPELLS_NUM; ++i)
{
int lvl = o_Spell[i].level - 1;
if (lvl < 5 && 1 << lvl & shrineFlags && o_Spell[i].school_flags && !shrineSpells[i])
{
if (spell == rndSpell) break;
++spell;
}
++chosenSpell;
}
shrineSpells[chosenSpell] = true;
}
else
{
spell = 0;
for (int i = 0; i < SPELLS_NUM; ++i)
{
int lvl = o_Spell[i].level - 1;
if (lvl < 5 && 1 << lvl & shrineFlags && o_Spell[i].school_flags && !game->disabled_shrines[i])
{
shrineSpells[i] = false;
++spell;
}
}
chosenSpell = spell ? fillShrines(game, unused_edx, shrineFlags) : ID_NONE;
}
return chosenSpell;
}
int __stdcall Disease(LoHook* h, HookContext* c)
{
if (c->ebx == 33)
{
_Hero_* hero = *(_Hero_**)(c->ebp + 0x14);
_BattleStack_* stack = (_BattleStack_*)c->esi;
int schoolLevel = c->eax;
int effect = 0;
diseaseSpellParams[stack->side][stack->index_on_side].AttackPenalty = diseaseSpell[schoolLevel].AttackPenalty;
diseaseSpellParams[stack->side][stack->index_on_side].DefensePenalty = diseaseSpell[schoolLevel].DefensePenalty;
diseaseSpellParams[stack->side][stack->index_on_side].SpeedPenalty = diseaseSpell[schoolLevel].SpeedPenalty; // %
// optional, as we don't have heroes with Disease spell specialty yet
if (hero)
{
effect = CALL_4(int, __thiscall, 0x4E6260, hero, SPL_DISEASE_NEW, hero->level, effect);
diseaseSpellParams[stack->side][stack->index_on_side].AttackPenalty += effect;
diseaseSpellParams[stack->side][stack->index_on_side].DefensePenalty += effect;
diseaseSpellParams[stack->side][stack->index_on_side].SpeedPenalty += effect; // %
}
stack->creature.attack -= diseaseSpellParams[stack->side][stack->index_on_side].AttackPenalty;
stack->creature.defence -= diseaseSpellParams[stack->side][stack->index_on_side].DefensePenalty;
// not allowing attack and defense to drop below 0
if (stack->creature.attack < 0)
{
diseaseSpellParams[stack->side][stack->index_on_side].AttackPenalty += stack->creature.attack;
stack->creature.attack = 0;
}
if (stack->creature.defence < 0)
{
diseaseSpellParams[stack->side][stack->index_on_side].DefensePenalty += stack->creature.defence;
stack->creature.defence = 0;
}
if (!(stack->creature.flags & BCF_CANT_MOVE))
{
diseaseSpellParams[stack->side][stack->index_on_side].SpeedPenalty =
stack->creature.speed * diseaseSpellParams[stack->side][stack->index_on_side].SpeedPenalty / 100;
if (diseaseSpellParams[stack->side][stack->index_on_side].SpeedPenalty < 1)
diseaseSpellParams[stack->side][stack->index_on_side].SpeedPenalty = 1;
stack->creature.speed -= diseaseSpellParams[stack->side][stack->index_on_side].SpeedPenalty;
if (stack->creature.speed < 1)
{
diseaseSpellParams[stack->side][stack->index_on_side].SpeedPenalty += stack->creature.speed - 1;
stack->creature.speed = 1;
}
}
c->return_address = 0x444D5C;
return NO_EXEC_DEFAULT;
}
return EXEC_DEFAULT;
}
int __stdcall resetNewSpells(LoHook* h, HookContext* c)
{
if (c->ecx == 10)
{
_BattleStack_* stack = (_BattleStack_*)c->esi;
stack->creature.attack += diseaseSpellParams[stack->side][stack->index_on_side].AttackPenalty;
stack->creature.defence += diseaseSpellParams[stack->side][stack->index_on_side].DefensePenalty;
if (!(stack->creature.flags & BCF_CANT_MOVE))
stack->creature.speed += diseaseSpellParams[stack->side][stack->index_on_side].SpeedPenalty;
c->return_address = 0x4444E1;
return NO_EXEC_DEFAULT;
}
return EXEC_DEFAULT;
}
int __stdcall DeathCloud(LoHook* h, HookContext* c)
{
if (c->edx == SPL_DEATH_CLOUD_NEW)
{
CALL_5(void, __thiscall, 0x5A4C80, o_BattleMgr, *(int*)(c->ebp + 0xC), SPL_DEATH_CLOUD_NEW, c->esi, *(int*)(c->ebp + 0x1C));
c->return_address = 0x5A2368;
return NO_EXEC_DEFAULT;
}
return EXEC_DEFAULT;
}
int __stdcall SummonCreatures(LoHook* h, HookContext* c)
{
if (c->ecx == 38 || c->ecx == 39)
{
int spell;
int creature;
switch (c->ecx)
{
case 38:
spell = SPL_FIREBIRD_NEW;
creature = CID_FIREBIRD;
break;
case 39:
spell = SPL_MAGIC_ELEMENTAL_NEW;
creature = CID_MAGIC_ELEMENTAL;
break;
}
CALL_5(void, __thiscall, 0x5A7390, o_BattleMgr, spell, creature, *(int*)(c->ebp + 0x1C), c->esi);
c->return_address = 0x5A2368;
return NO_EXEC_DEFAULT;
}
return EXEC_DEFAULT;
}
int __stdcall setSummonedCreaturesNumber(LoHook* h, HookContext* c)
{
int creature = *(int*)(c->ebp + 0xC);
int sp = *(int*)(c->ebp + 0x10);
int schoolLevel = *(int*)(c->ebp + 0x14);
if (creature == CID_FIREBIRD)
c->esi = o_Spell[SPL_FIREBIRD_NEW].effect[schoolLevel] * sp / 100;
else if (creature == CID_MAGIC_ELEMENTAL)
c->esi = o_Spell[SPL_MAGIC_ELEMENTAL_NEW].effect[schoolLevel] * sp / 100;
else
return EXEC_DEFAULT;
if (c->esi < 1) c->esi = 1;
c->return_address = 0x5A7526;
return NO_EXEC_DEFAULT;
}
int __stdcall checkSummonedCreaturesType(LoHook* h, HookContext* c)
{
int spell = c->ebx;
switch (spell)
{
case SPL_FIRE_ELEMENTAL:
c->eax = CID_FIRE_ELEMENTAL;
break;
case SPL_EARTH_ELEMENTAL:
c->eax = CID_EARTH_ELEMENTAL;
break;
case SPL_WATER_ELEMENTAL:
c->eax = CID_WATER_ELEMENTAL;
break;
case SPL_AIR_ELEMENTAL:
c->eax = CID_AIR_ELEMENTAL;
break;
case SPL_FIREBIRD_NEW:
c->eax = CID_FIREBIRD;
break;
case SPL_MAGIC_ELEMENTAL_NEW:
c->eax = CID_MAGIC_ELEMENTAL;
break;
default:
c->eax = ID_NONE;
}
c->return_address = 0x59F8B7;
return NO_EXEC_DEFAULT;
}
void __fastcall updateSpellsFromArtifacts(_Hero_* hero)
{
for (int iSpell = 0; iSpell < SPELLS_MAX; ++iSpell)
if (hero->spell[iSpell] > 1) hero->spell[iSpell] = 0;
for (int iSlot = 0; iSlot < 19; ++iSlot)
{
if (hero->doll_art[iSlot].id != ID_NONE)
{
if (hero->doll_art[iSlot].id == AID_SPELL_SCROLL)
{
if (hero->doll_art[iSlot].mod < SPELLS_NUM && !hero->spell[hero->doll_art[iSlot].mod])
hero->spell[hero->doll_art[iSlot].mod] = 2;
}
else if (o_ArtInfo[hero->doll_art[iSlot].id].new_spell)
{
std::bitset<SPELLS_MAX> spells;
CALL_2(int, __fastcall, 0x4D95C0, &spells, hero->doll_art[iSlot].id);
for (std::size_t iSpell = 0; iSpell < spells.size(); ++iSpell)
{
if (spells[iSpell] && !hero->spell[iSpell])
hero->spell[iSpell] = 2;
}
int comboArtIndex = o_ArtInfo[hero->doll_art[iSlot].id].supercomposite;
if (comboArtIndex != -1)
{
for (int iArt = 0; iArt < ARTIFACTS_NUM; ++iArt)
{
if (o_ComboArtInfo[comboArtIndex].parts[iArt] && o_ArtInfo[iArt].new_spell)
{
std::bitset<SPELLS_MAX> spells;
CALL_2(int, __fastcall, 0x4D95C0, &spells, iArt);
for (std::size_t iSpell = 0; iSpell < spells.size(); ++iSpell)
{
if (spells[iSpell] && !hero->spell[iSpell])
hero->spell[iSpell] = 2;
}
}
}
}
}
}
}
}
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
static bool plugin_On = false;
if ( DLL_PROCESS_ATTACH == ul_reason_for_call )
{
if ( !plugin_On )
{
plugin_On = true;
_P = GetPatcher();
_PI = _P->CreateInstance("HD.Plugin.H3.NewSpells");
//GetCurrentDirectoryA(sizeof(iniPath), iniPath);
//strcat(iniPath, "\\NewSpells.ini");
// Moving and Expanding Spell Table
_PI->WriteLoHook(0x4EE1C1, afterInit);
// nwcthereisnospoon
_PI->WriteByte (0x402902, SPELLS_NUM);
// "(Already learned)" Text
_PI->WriteDword(0x40D97C, 0x3EA);
// AI
_PI->WriteDword(0x41FBDF, 0x3EA);
_PI->WriteByte (0x41FC91, SPELLS_NUM);
_PI->WriteDword(0x425C72, 0x3EA);
_PI->WriteDword(0x425E98, SPELLS_NUM * sizeof(_Spell_));
_PI->WriteDword(0x427039, 0x3EA);
_PI->WriteDword(0x427044, 0x3EA);
_PI->WriteByte (0x427085, SPELLS_NUM);
_PI->WriteDword(0x4329C1, 0x3EA);
_PI->WriteDword(0x432A43, SPELLS_NUM * sizeof(_Spell_));
_PI->WriteDword(0x432CDE, 0x3EA);
_PI->WriteDword(0x432D1E, SPELLS_NUM * sizeof(_Spell_));
// ------------
// Adventure AI
// ------------
_PI->WriteDword(0x430AE5, 0x3EA + SPL_DIMENSION_DOOR);
_PI->WriteDword(0x4E57CC, 0x3EA + SPL_SUMMON_BOAT);
_PI->WriteDword(0x56B346, 0x3EA + SPL_TOWN_PORTAL);
_PI->WriteDword(0x56B7EA, 0x3EA + SPL_DIMENSION_DOOR);
_PI->WriteDword(0x56B93F, 0x3EA + SPL_FLY);
_PI->WriteDword(0x56B99A, 0x3EA + SPL_WATER_WALK);
// Battle AI
_PI->WriteDword(0x43C6F2, SPELLS_NUM * sizeof(_Spell_));
// Master Genie AI Spell Weighting
_PI->WriteDword(0x43C21B, SPELLS_NUM * sizeof(_Spell_));
// AI Quick Battle
_PI->WriteDword(0x433026, 0x3EA);
_PI->WriteDword(0x433719, 0x3EA);
_PI->WriteDword(0x43940C, 0x3EA);
_PI->WriteDword(0x43C561, 0x3EA);
// AI Spell Scrolls?
_PI->WriteDword(0x52A97A, 0x3EA);
_PI->WriteDword(0x52A9B6, SPELLS_NUM * sizeof(_Spell_));
// Can cast?
_PI->WriteDword(0x447551, SPELLS_NUM * sizeof(_Spell_));
_PI->WriteDword(0x447C7D, SPELLS_NUM * sizeof(_Spell_));
_PI->WriteDword(0x447CC8, SPELLS_NUM * sizeof(_Spell_));
// Cheats in battle
_PI->WriteByte (0x471C57, SPELLS_NUM);
// Clear _Hero_.spell[140] (optional)
_PI->WriteDword(0x48647A, 0x23);
_PI->WriteJmp (0x486485, 0x486498);
_PI->WriteByte (0x4864B0, SPELLS_NUM);
// Load Game?
_PI->WriteByte (0x48A34B, SPELLS_NUM);
// Scholar Secondary Skill
_PI->WriteByte (0x4A2743, SPELLS_NUM);
// New Game?
_PI->WriteByte (0x4C244D, SPELLS_NUM);
_PI->WriteByte (0x4C246F, SPELLS_NUM);
_PI->WriteDword(0x4C24C9, SPELLS_NUM * sizeof(_Spell_));
_PI->WriteByte (0x4C250E, SPELLS_NUM);
_PI->WriteDword(0x4C2557, SPELLS_NUM * sizeof(_Spell_));
_PI->WriteDword(0x4C260D, SPELLS_NUM * sizeof(_Spell_));
_PI->WriteByte (0x4E67AC, SPELLS_NUM);
// Cheat Menu?
_PI->WriteByte (0x4F508B, SPELLS_NUM);
_PI->WriteDword(0x4F50CE, SPELLS_NUM * sizeof(_Spell_));
_PI->WriteDword(0x4F5114, SPELLS_NUM * sizeof(_Spell_));
// Pyramids
_PI->WriteByte (0x4C170D, SPELLS_NUM);
// Shrines
_PI->WriteDword(0x4C92C5, SPELLS_NUM * sizeof(_Spell_));
_PI->WriteDword(0x4C9347, SPELLS_NUM * sizeof(_Spell_));
_PI->WriteDword(0x4C93C0, SPELLS_NUM * sizeof(_Spell_));
_PI->WriteByte (0x4CEC4F, SPELLS_NUM);
// Clear _Hero_.spell[140] (optional)
_PI->WriteDword(0x4D8F2E, 0x23);
_PI->WriteJmp (0x4D8F36, 0x4D8F49);
_PI->WriteByte (0x4D8F53, SPELLS_NUM);
_PI->WriteByte (0x4D8F8A, SPELLS_NUM);
// Tome of Air Magic
_PI->WriteDword(0x4D962D, SPELLS_NUM * sizeof(_Spell_));
// Tome of Fire Magic
_PI->WriteDword(0x4D9681, SPELLS_NUM * sizeof(_Spell_));
// Tome of Water Magic
_PI->WriteDword(0x4D96D6, SPELLS_NUM * sizeof(_Spell_));
// Tome of Earth Magic
_PI->WriteDword(0x4D972E, SPELLS_NUM * sizeof(_Spell_));
// Spellbinder's Hat
_PI->WriteDword(0x4D9771, SPELLS_NUM * sizeof(_Spell_));
// Scholars
_PI->WriteByte (0x5012B7, SPELLS_NUM);
_PI->WriteDword(0x527ACB, 0x3EA);
_PI->WriteDword(0x527B08, SPELLS_NUM * sizeof(_Spell_));
// RMG
_PI->WriteDword(0x534C4B, SPELLS_NUM * sizeof(_Spell_));
// RMG Spell Scrolls
_PI->WriteDword(0x5353D5, SPELLS_NUM);
_PI->WriteByte (0x53542B, SPELLS_NUM);
// Spell Book
_PI->WriteDword(0x59CD5E, 0x3EA);
_PI->WriteDword(0x59CDBF, SPELLS_NUM * sizeof(_Spell_));
// Cast Spell
_PI->WriteDword(0x5A1AD6, SPELLS_NUM * sizeof(_Spell_));
// Mage Guild
_PI->WriteByte (0x5BEA2C, SPELLS_NUM);
_PI->WriteByte (0x5BEA70, SPELLS_NUM);
_PI->WriteByte (0x5BEAAD, SPELLS_NUM);
_PI->WriteDword(0x5BEAFE, SPELLS_NUM * sizeof(_Spell_));
_PI->WriteDword(0x5BEB2C, SPELLS_NUM * sizeof(_Spell_));
_PI->WriteByte (0x5BEB48, SPELLS_NUM);
_PI->WriteByte (0x5BEB71, SPELLS_NUM);
_PI->WriteByte (0x5BEBB2, SPELLS_NUM);
_PI->WriteDword(0x5BEC05, SPELLS_NUM * sizeof(_Spell_));
_PI->WriteByte (0x5BEC1B, SPELLS_NUM);
// Conflux Grail
_PI->WriteDword(0x5BE512, SPELLS_NUM * sizeof(_Spell_));
_PI->WriteDword(0x5BE56E, SPELLS_NUM * sizeof(_Spell_));
_PI->WriteDword(0x5D7464, SPELLS_NUM);
// ---------------------------
// New _Hero_.spell[140] field
// ---------------------------
_PI->WriteCodePatch(0x4D8B72, "%n", 8);
_PI->WriteCodePatch(0x4D8F7F, "%n", 8);
_PI->WriteCodePatch(0x4D95AF, "%n", 7);
// ----------------------------------------
// New _GameMgr_.disabled_spells[140] field
// ----------------------------------------
_PI->WriteByte(0x4C16ED, 4); // Pyramids
_PI->WriteByte(0x4C254C, 4); // Titan's Lightning Bolt
_PI->WriteByte(0x4C25F1, 4); // Titan's Lightning Bolt
_PI->WriteByte(0x501297, 4); // Scholars
_PI->WriteByte(0x5BEA55, 4); // Mage Guild
_PI->WriteDword(0x52AE1C, 0x3EA);
// ------
// Battle
// ------
_PI->WriteByte (0x4963E9, ANIMS_NUM);
_PI->WriteByte (0x4965BD, ANIMS_NUM);
_PI->WriteByte (0x502405, SPELLS_NUM);
_PI->WriteByte (0x502451, SPELLS_NUM);
_PI->WriteByte (0x5024CF, SPELLS_NUM);
_PI->WriteByte (0x502515, SPELLS_NUM);
_PI->WriteByte (0x502E62, SPELLS_NUM);
_PI->WriteByte (0x502EB7, SPELLS_NUM);
_PI->WriteByte (0x59EFD9, SPELLS_NUM - 1 - ADVSPELLS_NUM);
_PI->WriteDword(0x59EFE4, (int)&spellIndirectTableA);
_PI->WriteByte (0x5A064E, SPELLS_NUM - 1 - ADVSPELLS_NUM);
_PI->WriteDword(0x5A0659, (int)&spellIndirectTableB);
_PI->WriteByte (0x4446EA, SPELLS_NUM - 1 - SPL_SHIELD);
_PI->WriteDword(0x4446FD, (int)&spellIndirectTableC);
_PI->WriteByte (0x444262, SPELLS_NUM - 1 - SPL_WEAKNESS);
_PI->WriteDword(0x44427A, (int)&spellIndirectTableD);
// --------------------------------------------------
// New _BattleStack_.active_spell_duration[162] field
// --------------------------------------------------
_PI->WriteDword(0x43787A, 162);
_PI->WriteCodePatch(0x437880, "%n", 19);
_PI->WriteDword(0x43D314, 162);
_PI->WriteDword(0x43E3DF, SPELLS_NUM);
_PI->WriteByte (0x443F63, SPELLS_NUM);
_PI->WriteByte (0x446F03, SPELLS_NUM);
_PI->WriteByte (0x5A1907, SPELLS_NUM);
_PI->WriteByte (0x5A1995, SPELLS_NUM);
_PI->WriteByte (0x5A84C8, SPELLS_NUM);
_PI->WriteByte (0x5A852F, SPELLS_NUM);
_PI->WriteCodePatch(0x4446D2, "%n", 7);
_PI->WriteCodePatch(0x4446D2, "%n", 7);
_PI->WriteJmp (0x444694, 0x4450C2);
// Disable creature spells
_PI->WriteLoHook(0x4C2567, disableCreatureSpells);
// Shrine Spells
_PI->WriteLoHook(0x4C2625, shrineSpellsInit);
_PI->WriteHiHook(0x4C9260, SPLICE_, DIRECT_, THISCALL_, fillShrines);
// Disease
_PI->WriteLoHook(0x444701, Disease);
_PI->WriteLoHook(0x44427E, resetNewSpells);
// Death Cloud
_PI->WriteLoHook(0x5A0F4C, DeathCloud);
// Firebird, Magic Elemental
_PI->WriteLoHook(0x59F889, checkSummonedCreaturesType);
_PI->WriteLoHook(0x5A065D, SummonCreatures);
_PI->WriteLoHook(0x5A7516, setSummonedCreaturesNumber);
// Artifacts (incl. Spell Scrolls);
_PI->WriteHiHook(0x4D9840, SPLICE_, DIRECT_, THISCALL_, updateSpellsFromArtifacts);
}
}
return TRUE;
}
Т.к. это заклинание новое, то к нему только стандартные иммунитеты. На какие группы монстров оно не должно действовать? Делаем иммунитеты как против абилки Зомби?