Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // dllmain.cpp: определяет точку входа для приложения DLL.
- #include "..\..\include\patcher_x86_commented.hpp"
- #include "..\..\include\HotA\HoMM3.h"
- #include "..\..\include\h3sw_ids.h"
- #include "..\..\include\era.h"
- #include <math.h>
- Patcher * globalPatcher;
- PatcherInstance *patcher;
- bool HasAdditionalSpell(_Hero_* hero, int spell)
- {
- char erm_command[256];
- sprintf(erm_command,"SN:W^new_spells_%i_%i^/?v1;",hero->id,spell);
- ExecErmCmd(erm_command);
- return ErmV[1];
- }
- bool HasSpell(_Hero_* hero, int spell)
- {
- if(spell < 70)
- return hero->spell[spell];
- else
- return HasAdditionalSpell(hero, spell);
- }
- void GiveSpell(_Hero_* hero, int spell)
- {
- if(spell < 70)
- {
- hero->spell[spell] = 1;
- hero->spell_level[spell] = 1;
- }
- else
- {
- char erm_command[256];
- sprintf(erm_command,"SN:W^new_spells_%i_%i^/1;",hero->id,spell);
- ExecErmCmd(erm_command);
- }
- }
- int __stdcall GiveSpell_hook(HiHook* h, _Hero_* hero, int spell)
- {
- GiveSpell(hero, spell);
- return spell;
- }
- int __stdcall HasSpellLoHook(LoHook* h, HookContext* c)
- {
- _Hero_* hero = (_Hero_*)(c->ecx);
- int spell = c->edi;
- if(spell < 70)
- {
- return EXEC_DEFAULT;
- }
- else
- {
- c->eax = HasAdditionalSpell(hero,spell);
- c->return_address = 0x59CD62;
- return NO_EXEC_DEFAULT;
- }
- }
- //
- int __stdcall SpellChosen(LoHook* h, HookContext* c)
- {
- int spell = c->ebx;
- if(spell < 70)
- {
- return EXEC_DEFAULT;
- }
- else
- {
- c->return_address = 0x59F06A;
- return NO_EXEC_DEFAULT;
- }
- return NO_EXEC_DEFAULT;
- }
- //c
- int __stdcall SpellCast(LoHook* h, HookContext* c)
- {
- int spell = c->edx;
- _BattleStack_* target = (_BattleStack_*)(c->edi);
- int spellpower = *(int*)(c->ebp+0x1C);
- int DHp = *(int*)(c->ebp-0x3C);
- _Hero_* hero = *(_Hero_**)(c->ebp-0x14);
- //ebx - комбат менеджер 005A0E4B
- if(spell < 81)
- return EXEC_DEFAULT;
- if(spell == 82)
- {
- _Pcx16_* p = _Pcx16_::CreateNew("testt",400,450);
- target->def->Draw_Transparent(0,0,
- 0,0,target->def->width,target->def->height,
- p->buffer,0,0,p->width,p->height,p->scanline_size,0,0);
- p->DrawSurface16(0,0,p->width, p->height,
- o_WndMgr->screen_pcx16->buffer,0,0,o_WndMgr->screen_pcx16->width,
- o_WndMgr->screen_pcx16->height,
- o_WndMgr->screen_pcx16->scanline_size,
- 0);
- /*
- //Calculate Damage CombatMan_ApplyMagicDamage
- int dmg = CALL_7(int, __thiscall, 0x5A7BF0,o_BattleMgr,99,spell,hero,DHp,target,1);
- //Make a damage combatMonster_DoPhysicalDamage
- int dmg2 = CALL_2(int, __thiscall, 0x443DB0, target, dmg);
- //Выставить необходимость проиграть анимацию урона
- target->fireshield = 1;
- //Проиграть анимацию спелла CombatMan_00468570_DoHitAnimation
- CALL_3(void, __thiscall,0x468570,o_BattleMgr, 13, 1);
- //Надпись в лог CombatMan_ReportDamageDoneCreaturesKilled
- CALL_6(void, __thiscall,0x469670,o_BattleMgr,o_Spell[spell].name,1,dmg,target,dmg2);
- //Обновить экран?? CombatMan_00469020
- CALL_1(void, __thiscall,0x469020,o_BattleMgr);*/
- //CALL_5(void,__thiscall, 0x4963C0,o_BattleMgr, 1, target, 10, 0);
- c->return_address = 0x5A2368;
- return NO_EXEC_DEFAULT;
- }
- if(spell == 83)
- {
- int casterKind = 0;
- int anim_def = 31;
- int spell_level = c->esi;
- //Mass apply buff
- CALL_7(int, __thiscall, 0x5A69E0,o_BattleMgr, hero, 53, spell_level, spellpower, o_BattleMgr->current_side, casterKind);
- //
- CALL_4(int, __thiscall, 0x5A8C60,o_BattleMgr, casterKind, 83, 0);
- CALL_4(int, __thiscall, 0x5A6AD0,o_BattleMgr, c->ebx + 0x547C, anim_def, 0);
- //c->return_address = 0x5A2368;
- //return NO_EXEC_DEFAULT;
- }
- if(spell == 84)
- {
- int casterKind = 0;
- int anim_def = 19;
- int spell_level = c->esi;
- //Mass apply buff
- CALL_7(int, __thiscall, 0x5A69E0,o_BattleMgr, hero, 54, spell_level, spellpower, o_BattleMgr->current_side, casterKind);
- //
- CALL_4(int, __thiscall, 0x5A8C60,o_BattleMgr, casterKind, 84, 0);
- CALL_4(int, __thiscall, 0x5A6AD0,o_BattleMgr, c->ebx + 0x547C, anim_def, 0);
- //c->return_address = 0x5A2368;
- //return NO_EXEC_DEFAULT;
- }
- return EXEC_DEFAULT;
- }
- _BattleAnim_ new_animation_table[999];
- char def_name[999][16];
- char eff_name[999][32];
- void __stdcall LoadAnims (PEvent e)
- {
- int new_p = (int)new_animation_table;
- patcher->WriteDword(0x43F77B + 3, new_p); // Шар магога
- patcher->WriteDword(0x43FB67 + 3, new_p); // Облако смерти лича
- patcher->WriteDword(0x4963F9 + 2, new_p); // Стандартная анимация на стеке
- patcher->WriteDword(0x4965CD + 2, new_p); // Стандартная анимация на гексе
- patcher->WriteDword(0x5A5033 + 3, new_p); // Армагеддон
- patcher->WriteDword(0x5A6B11 + 3, new_p); // Массовое колдовство
- patcher->WriteDword(0x5A7A71 + 3, new_p); // Воскрешение
- patcher->WriteDword(0x5A9629 + 3, new_p); // Загрузка анимации
- patcher->WriteDword(0x4689C1 + 3, new_p + 4); // Проигрывание действия отрисовки
- patcher->WriteDword(0x496518 + 2, new_p + 4); // Стандартная анимация на стеке
- patcher->WriteDword(0x4966CB + 2, new_p + 4); // Стандартная анимация на гексе
- patcher->WriteDword(0x5A6D2A + 3, new_p + 4); // Массовое колдовство
- patcher->WriteDword(0x5A7B03 + 3, new_p + 4); // Загрузка анимации
- patcher->WriteDword(0x43E500 + 3, new_p + 8); // Отрисовка стека
- // Правки количества анимаций.
- patcher->WriteByte(0x4963E7 + 2, 127); // Стандартная анимация на стеке
- patcher->WriteByte(0x4965BB + 2, 127); // Стандартная анимация на гексе
- _Txt_* txt = o_LoadTxt("magicani.txt");
- if(txt != 0)
- {
- for(int i = 0; i!=127; i++)
- {
- _TxtLine_* corresponding_line = txt->Lines[i+1];
- strcpy((char*)(def_name[i]),corresponding_line->items[1]);
- o_BattleAnimation[i].DefName = def_name[i];
- strcpy((char*)(eff_name[i]),corresponding_line->items[2]);
- o_BattleAnimation[i].TouchEffect_Name = eff_name[i];
- o_BattleAnimation[i].Properties =
- atoi(corresponding_line->items[3]) |
- atoi(corresponding_line->items[4]) << 8;
- }
- txt->DerefOrDestruct();
- }
- }
- int __stdcall ReadSptraitsLineHook(HiHook* h, _Txt_** file_ptr, int spell, int line_num)
- {
- _Txt_* file = *file_ptr;
- char* anim_ix = file->Lines[line_num]->items[33];
- /*
- char mess[255];
- sprintf(mess,"%s %i", anim_ix, atoi(anim_ix) );
- MessageBoxA(0,(LPCSTR)mess,"",0);*/
- if(*anim_ix)
- o_Spell[spell].animation_ix = atoi(anim_ix);
- o_Spell[spell].flags = 0;
- for(int i = 0; i!=32; i++)
- {
- char* flag = file->Lines[line_num]->items[35+i];
- if(*flag)
- o_Spell[spell].flags |= 1 << i;
- }
- return CALL_3(int,__cdecl,h->GetOriginalFunc(),file_ptr,spell,line_num);
- }
- int Ray(_BattleMgr_ *cmgr, int a1, //edx
- int a2, //1
- int a3, //start x
- int a4, //start y
- int a5, //target x
- int a6, //target y
- int a7, //150
- int a8, // 100
- int a9, //9 толщина по x
- int a10, //2 толщина по y
- int a11, //color
- int a12, //param
- int a13, //param2
- int a14, //размер секции (уменьшение луч затормаживает)
- int a15, // не используется!
- int a16,
- int a17, //интервал между кадрами
- int a18 //не используется!
- )
- {
- return CALL_19(int,__fastcall,0x5A5F30,cmgr,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17,a18);
- }
- int savedspell = -1;
- int __stdcall LightningStrikeAnim(HiHook* h, _BattleMgr_ *cmgr, int animId, _BattleStack_ *target, int timeStep, char showHitting)
- {
- /*char mess[255];
- sprintf(mess,"%i %i", savedspell, cmgr->current_spell_id);
- MessageBoxA(0,(LPCSTR)mess,"",0);*/
- _Hero_* hero = cmgr->hero[cmgr->current_side];
- _HeroCombatDef_ hero_def = o_HeroCombatDefs[(hero->_class & 0xFE) + hero->sex];
- int hero_x = 0;
- if (cmgr->current_side == 0)
- hero_x = hero_def.CastX - 43;
- else
- hero_x = 693 - hero_def.CastX;
- int hero_y = hero_def.CastY - 19;
- if(savedspell != 57)
- {
- //CALL_1(void, __thiscall, 0x4F8A50, 100.0);
- CALL_19(int,__fastcall,0x5A5F30,cmgr,500,0,hero_x,hero_y,target->GetX(),target->GetY(),150,100,9,2,65504,-40,40,15/*BattleAnimPeriodFactors[Settind_BattleFast]*/,1,0,3,1);
- //cmgr->FlipBattlefield();
- cmgr->RedrawBattlefield( 1, 0, 0, 0, 1, 0);
- return 1;
- }
- else
- {
- /*_Def_* def = o_LoadDef("default.def");
- for(int i = 100; i<= 300; i+=20)
- {
- def->Draw_Transparent(0,0,0,0,def->width,def->height,o_WndMgr->screen_pcx16->buffer,i,i,o_WndMgr->screen_pcx16->width, o_WndMgr->screen_pcx16->height, o_WndMgr->screen_pcx16->scanline_size,0,0);
- CALL_1(void,__thiscall,0x493300,cmgr);
- WaitTill(o_GetTime()+100);
- }
- def->DerefOrDestruct();*/
- int colors[]=
- {63488,65504,63488,63488,65504,63488,63488,65504,63488,63488,65504};
- for(int i = 0; i!=10; i++)
- CALL_19(int,__fastcall,0x5A5F30,cmgr,500,0,hero_x,hero_y,target->GetX(),target->GetY(),150,100,3,3,colors[i],0,0,1000/*BattleAnimPeriodFactors[Settind_BattleFast]*/,1,0,45,1);
- cmgr->RedrawBattlefield( 1, 0, 0, 0, 1, 0);
- return 1;
- }
- }
- int __stdcall RainbowAnim(HiHook* h, _BattleMgr_ *cmgr, int animId, _BattleStack_ *target, int timeStep, char showHitting)
- {
- CALL_19(int,__fastcall,0x5A5F30,cmgr,500,0,cmgr->current_side*800,0,target->GetX(),target->GetY(),0,0,15,15,300,40,40,10,1,0,15,1);
- //CALL_19(int,__fastcall,0x5A5F30,cmgr,500,50,50,0,target->GetX(),target->GetY(),0,0,15,15,303,40,40,10,1,0,15,1);
- cmgr->RedrawBattlefield( 1, 0, 0, 0, 1, 0);
- return 1; //CALL_5(int,__thiscall,h->GetOriginalFunc(),cmgr,animId,target,timeStep,showHitting);
- }
- int __stdcall ColdRayAnim(HiHook* h, _BattleMgr_ *cmgr, int v264, signed int skillLevel, int target_x, int target_y, int five, int a7, int a8)
- {
- int interval = 18;
- _Hero_* hero = cmgr->hero[cmgr->current_side];
- _HeroCombatDef_ hero_def = o_HeroCombatDefs[(hero->_class & 0xFE) + hero->sex];
- int hero_x = 0;
- if (cmgr->current_side == 0)
- hero_x = hero_def.CastX - 43;
- else
- hero_x = 693 - hero_def.CastX;
- int hero_y = hero_def.CastY - 19;
- int width = target_x - hero_x ;
- int height = target_y - hero_y;
- double line = sqrt(0.0 + width * width + height*height);
- int cadres = (int)(line / interval);
- _Def_* def = o_LoadDef("coldray.def");
- for(int i = 0; i < cadres; i++)
- {
- int x = hero_x + (int)(width * i / cadres) - def->width / 2;
- int y = hero_y + (int)(height * i / cadres) - def->height / 2;
- int frame = i*10 / cadres;
- def->Draw_Transparent(0,frame,0,0,def->width,def->height,o_WndMgr->screen_pcx16->buffer,x,y,o_WndMgr->screen_pcx16->width, o_WndMgr->screen_pcx16->height, o_WndMgr->screen_pcx16->scanline_size,0,0);
- CALL_1(void,__thiscall,0x493300,cmgr);
- WaitTill(o_GetTime()+10*BattleAnimPeriodFactors[Settind_BattleFast]);
- }
- def->DerefOrDestruct();
- cmgr->RedrawBattlefield( 1, 0, 0, 0, 1, 0);
- return 0;
- }
- int __stdcall SpellCastHook(HiHook* h, _BattleMgr_ *cmgr, int spell, signed int pos, int casterKind, int pos2, int skillLevel, int spellPower)
- {
- savedspell = spell;
- return CALL_7(int,__thiscall,h->GetOriginalFunc(),cmgr,spell,pos,casterKind,pos2,skillLevel,spellPower);
- }
- int SelectByRoulette(int spells[])
- {
- int sum = 0;
- for(int i = 0; i!=200;i++)
- sum = spells[i];
- if(sum == 0)
- return -1;
- int r = Randint(0,sum);
- for(int i =0; i!=200; i++)
- {
- r-=spells[i];
- if (r<0)
- return i;
- }
- return -1;
- }
- int __stdcall TownSpellGenerate(HiHook* h, _Town_* town, int some_ptr)
- {
- int ret = CALL_2(int,__thiscall,h->GetOriginalFunc(),town, some_ptr);
- ///char* prohibited = (char*)(some_ptr + 112);
- //char* enforced = (char*)(some_ptr + 124);
- int spell_prohibited [200];
- int spell_enforced [200];
- for(int i = 0; i!= 70; i++)
- {
- int off = i / 8;
- int mask = 1 << (i % 8);
- //if((prohibited >> i) & 1)
- if(*(char*)(some_ptr + 112 + off) & mask)
- {
- spell_prohibited[i] = 1;
- MessageBoxA(0,(LPCSTR)o_Spell[i].name,"Prohibited",0);
- }
- else
- {
- spell_prohibited[i] = 0;
- }
- }
- for(int i = 0; i!= 70; i++)
- {
- int off = i / 8;
- int mask = 1 << (i % 8);
- if(*(char*)(some_ptr + 124 + off) & mask)
- {
- spell_enforced[i] = 1;
- MessageBoxA(0,(LPCSTR)o_Spell[i].name,"enforced",0);
- }
- else
- {
- spell_enforced[i] = 0;
- }
- }
- //для каждого уровня
- //подсчитать, сколько нам надо сгенерировать чар:
- //количество чар на уровне ГМ минус принудительно выставляемые
- //
- int level = 1;
- int pool[200];
- int spell_count = 5;
- for(int i = 0; i!=200; i++)
- {
- if(o_Spell[i].level == level && !spell_prohibited[i] && !spell_enforced[i])
- {
- pool[i] = o_Spell[i].chance2get_var[town->type];
- }
- else
- {
- pool[i]=0;
- }
- }
- return ret;
- }
- BOOL APIENTRY DllMain( HMODULE hModule,
- DWORD ul_reason_for_call,
- LPVOID lpReserved
- )
- {
- if (ul_reason_for_call == DLL_PROCESS_ATTACH)
- {
- globalPatcher = GetPatcher();
- patcher = globalPatcher->CreateInstance("h3sw_spells");
- ConnectEra();
- patcher->WriteHiHook(0x4D95A0,SPLICE_,EXTENDED_, THISCALL_, (void*)GiveSpell_hook);
- //Spell book
- patcher->WriteLoHook(0x59CD5B,(void*)HasSpellLoHook);
- patcher->WriteDword(0x59CDBF,0x2530+0x88*40);
- //Spell chosen
- patcher->WriteLoHook(0x59EFD4,(void*)SpellChosen);
- //Spell cast
- patcher->WriteLoHook(0x5A0649,(void*)SpellCast);
- //patcher->WriteHiHook(0x5BEA00,SPLICE_,EXTENDED_,THISCALL_,(void*)TownSpellGenerate);
- //расширение текстовика для заклинаний
- patcher->WriteHiHook(0x775990,SPLICE_,EXTENDED_, CDECL_, (void*)ReadSptraitsLineHook);
- //создание текстовика для анимаций
- RegisterHandler(LoadAnims,"OnAfterCreateWindow");
- patcher->WriteHiHook(0x5A0140,SPLICE_,EXTENDED_,THISCALL_,(void*)SpellCastHook);
- //Правки эффектов для существующих чар
- patcher->WriteHiHook(0x5A0E25,CALL_,EXTENDED_, THISCALL_,(void*)LightningStrikeAnim); //молния и грохот титанов
- patcher->WriteHiHook(0x5A6726,CALL_,EXTENDED_, THISCALL_,(void*)LightningStrikeAnim); //цепная молния
- patcher->WriteDword(0x5A67EB,65504); //замена цвета сегментов цепной молнии
- patcher->WriteHiHook(0x5A0D71,CALL_,EXTENDED_, THISCALL_,(void*)ColdRayAnim); //снаряд ледяной молнии
- patcher->WriteHiHook(0x43F6F1,CALL_,EXTENDED_, THISCALL_,(void*)RainbowAnim); //молния и грохот титанов
- }
- return TRUE;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement