Spellforce-Spell-framework
Loading...
Searching...
No Matches
sf_hooks.c
Go to the documentation of this file.
1
8#include "sf_wrappers.h"
9#include "sf_modloader.h"
10#include "sf_hooks.h"
14
17#include "hooks/sf_menu_hook.h"
23#include "hooks/sf_onhit_hook.h"
24#include "hooks/sf_ai_hook.h"
26
27#include <stdint.h>
28#include <stdlib.h>
29#include <stdio.h>
30#include <string.h>
31
43
52{
53 log_info("| - Internal Use Hooks");
55
56 // Required for internal use
58
59 // Used in Iterator for AOE Spells Dispose
61
63
64 // Used to print to the game console
66
67 log_info("| - FigureAPI Hooks");
68 // More defined for external use in api
69 DEFINE_FUNCTION(figure, isAlive, 0x1BE4D0);
70 DEFINE_FUNCTION(figure, setWalkSpeed, 0x2B7190);
71 DEFINE_FUNCTION(figure, addAction, 0x2AE0B0);
72 DEFINE_FUNCTION(figure, addBonusMult, 0x35A3E0);
73 DEFINE_FUNCTION(figure, decreaseHealth, 0x2b5b40);
74 DEFINE_FUNCTION(figure, getCurrentHealth, 0x279350);
75 DEFINE_FUNCTION(figure, getCurrentMaxMana, 0x2b2a20);
76 DEFINE_FUNCTION(figure, rescaleMana, 0x2b5d50);
77 DEFINE_FUNCTION(figure, getCurrentMaxHealth, 0x2b2970);
78 DEFINE_FUNCTION(figure, rescaleHealth, 0x2b5cd0);
79 DEFINE_FUNCTION(figure, getJob, 0x279290);
80 DEFINE_FUNCTION(figure, FUN_006e3a90, 0x2e3a90);
81 DEFINE_FUNCTION(figure, setJobToDoCount, 0x300910);
82 DEFINE_FUNCTION(figure, isFlagSet, 0x279d20);
83 DEFINE_FUNCTION(figure, getSpellJobStartNode, 0x2b2de0);
84 DEFINE_FUNCTION(figure, subMana, 0x2b5b60);
85 DEFINE_FUNCTION(figure, getCurrentMana, 0x2b29c0);
86 DEFINE_FUNCTION(figure, getPosition, 0x2caaf0);
87 DEFINE_FUNCTION(figure, setTask, 0x2b7110);
88 DEFINE_FUNCTION(figure, getWeaponStats, 0x2b30a0);
89 DEFINE_FUNCTION(figure, getAggroValue, 0x2b1ab0);
90 DEFINE_FUNCTION(figure, setAggroValue, 0x2b6670);
91 DEFINE_FUNCTION(figure, isWarrior, 0x1c1510);
92 DEFINE_FUNCTION(figure, getHealersList, 0x2b2870);
93 DEFINE_FUNCTION(figure, disposeHealerList, 0x36436D);
94 DEFINE_FUNCTION(figure, getCurrentHealthPercent, 0x2fdeb0);
95 log_info("| - AI API Hooks");
96
97 DEFINE_FUNCTION(ai, getTargetAction, 0x2b2f50);
98 DEFINE_FUNCTION(ai, getFigureAction, 0x2b19c0);
99 DEFINE_FUNCTION(ai, isAIVectorEmpty, 0x3645c7);
100 DEFINE_FUNCTION(ai, getAIVectorFirstElement, 0x3644dd);
101 DEFINE_FUNCTION(ai, getAIVectorGetCurrent, 0x364617);
102 DEFINE_FUNCTION(ai, getAIVectorLength, 0x2cc10a);
103 DEFINE_FUNCTION(ai, AC60AddOrGetEntity, 0x35dcc0);
104
105 DEFINE_FUNCTION(ai, canFigureDoAction, 0x35ace7);
106 DEFINE_FUNCTION(ai, setAICurrentActionRanking, 0x35e340);
107 DEFINE_FUNCTION(ai, getAICurrentActionRanking, 0x362ed0);
108 DEFINE_FUNCTION(ai, getActionStats, 0x35e0d4);
109 DEFINE_FUNCTION(ai, getCastType, 0x26dcf0);
110 DEFINE_FUNCTION(ai, getPositionToCastAlly, 0x35f197);
111 DEFINE_FUNCTION(ai, getPositionToCastEnemy, 0x35b5e2);
112 DEFINE_FUNCTION(ai, isUnknownWorldFeature, 0x34eae0);
113
114 log_info("| - SpellAPI Hooks");
115 // Define the function pointers for SpellFunctions group
116 DEFINE_FUNCTION(spell, setXData, 0x329C40);
117 DEFINE_FUNCTION(spell, setEffectDone, 0x32A730);
118 DEFINE_FUNCTION(spell, addToXData, 0x32AAC0);
119 DEFINE_FUNCTION(spell, getChanceToResistSpell, 0x317BA0);
120 DEFINE_FUNCTION(spell, getRandom, 0x2AD200);
121 DEFINE_FUNCTION(spell, addVisualEffect, 0x329B30);
122 DEFINE_FUNCTION(spell, figureAggro, 0x329c90);
123 DEFINE_FUNCTION(spell, getResourceSpellData, 0x26dc40);
124 DEFINE_FUNCTION(spell, getXData, 0x32aa60);
125 DEFINE_FUNCTION(spell, getTargetsRectangle, 0x329D80);
126 DEFINE_FUNCTION(spell, removeDLLNode, 0x34B030);
127 DEFINE_FUNCTION(spell, figClrChkSplBfrChkBattle, 0x32a470);
128 DEFINE_FUNCTION(spell, figTryClrCHkSPlBfrJob2, 0x32a4f0);
129 DEFINE_FUNCTION(spell, figTryUnfreeze, 0x32a5a0);
130 DEFINE_FUNCTION(spell, onSpellRemove, 0x32b310);
131 DEFINE_FUNCTION(spell, getSpellLine, 0x32a980);
132 DEFINE_FUNCTION(spell, getLeveledSpellID, 0x26de20);
133
134 DEFINE_FUNCTION(effect, addEffect, 0x2dc880);
135 DEFINE_FUNCTION(effect, setEffectXData, 0x2ddb30);
136 DEFINE_FUNCTION(effect, getEffectXData, 0x2dd730);
137 DEFINE_FUNCTION(effect, tryEndEffect, 0x2dcaa0);
138
139 log_info("| - ToolboxAPI Hooks");
140
141 DEFINE_FUNCTION(toolbox, dealDamage, 0x2f4a57);
142 DEFINE_FUNCTION(toolbox, isTargetable, 0x2fe704);
143 DEFINE_FUNCTION(toolbox, figuresCheckHostile, 0x2fe7b9);
144 DEFINE_FUNCTION(toolbox, figuresCheckNeutral, 0x2feba4);
145 DEFINE_FUNCTION(toolbox, figuresCheckFriendly, 0x2fe953);
146 DEFINE_FUNCTION(toolbox, hasSpellOnIt, 0x2fe4ea);
147 DEFINE_FUNCTION(toolbox, rescaleLevelStats, 0x2fff48);
148 DEFINE_FUNCTION(toolbox, buildingDealDamage, 0x2d6d80);
149 DEFINE_FUNCTION(toolbox, addSpellToFigure, 0x2f673a);
150 DEFINE_FUNCTION(toolbox, getFigureFromWorld, 0x34F160);
151 DEFINE_FUNCTION(toolbox, getSpellIndexOfType, 0x2fd939);
152 DEFINE_FUNCTION(toolbox, getSpellIndexFromDLL, 0x2fdd90);
153 DEFINE_FUNCTION(toolbox, getNextNode, 0x2fe240);
154 DEFINE_FUNCTION(toolbox, figureSetNewJob, 0x2f0ef0);
155 DEFINE_FUNCTION(toolbox, removeSpellFromList, 0x2fad57);
156 DEFINE_FUNCTION(toolbox, addUnit, 0x2f749a);
157 DEFINE_FUNCTION(toolbox, findClosestFreePosition, 0x34e9a0);
158 DEFINE_FUNCTION(toolbox, isUnitMelee, 0x2feb2b);
159
160 log_info("| - IteratorAPI Hooks");
161 DEFINE_FUNCTION(iterator, figureIteratorInit, 0x3183f0);
162 DEFINE_FUNCTION(iterator, figureIteratorSetPointers, 0x31a680);
163 DEFINE_FUNCTION(iterator, iteratorSetArea, 0x3195d0);
164 DEFINE_FUNCTION(iterator, getNextFigure, 0x318f50);
165 DEFINE_FUNCTION(iterator, buildingIteratorInit, 0x318290);
166 DEFINE_FUNCTION(iterator, buildingIteratorSetPointers, 0x31A640);
167
168 log_info("| - SpellAPI Wrappers");
169 // Method to include functions WE define in the Internal code.
172 INCLUDE_FUNCTION(spell, addSpell, &sf_spelltype_hook);
173 INCLUDE_FUNCTION(spell, getSpellID, &sf_get_spell_id);
174 INCLUDE_FUNCTION(spell, checkCanApply, &sf_refresh_hook)
177
178 log_info("| - FigureAPI Wrappers");
180
181 log_info("| - ToolboxAPI Wrappers");
183
184 log_info("| - IteratorAPI Wrappers");
187
188 log_info("| - RegistrationAPI Wrappers");
204}
205
206static void initialize_spelltype_hook()
207{
208 ASI::MemoryRegion add_spell_mreg (ASI::AddrOf(0x328d60), 5);
209 ASI::BeginRewrite(add_spell_mreg);
210 *(unsigned char *)(ASI::AddrOf(0x328d60)) = 0xE9; // jmp instruction
211 *(int *)(ASI::AddrOf(0x328d61)) = (int)(&sf_spelltype_hook) -
212 ASI::AddrOf(0x328d65);
213 ASI::EndRewrite(add_spell_mreg);
214}
215
216static void initialize_spell_trigger_hook()
217{
218 ASI::MemoryRegion add_spell_mreg (ASI::AddrOf(0x278773), 5);
219 ASI::BeginRewrite(add_spell_mreg);
220 *(unsigned char *)(ASI::AddrOf(0x278773)) = 0xE8; // CALL instruction
221 *(int *)(ASI::AddrOf(0x278774)) = (int)(&sf_spelleffect_hook) -
222 ASI::AddrOf(0x278778);
223 ASI::EndRewrite(add_spell_mreg);
224}
225
226static void initialize_subeffect_add_hook()
227{
228 ASI::MemoryRegion add_spell_mreg (ASI::AddrOf(0x2de3b7), 5);
229 ASI::BeginRewrite(add_spell_mreg);
230 *(unsigned char *)(ASI::AddrOf(0x2de3b7)) = 0xE8; // CALL instruction
231 *(int *)(ASI::AddrOf(0x2de3b8)) = (int)(&sf_subeffect_hook) -
232 ASI::AddrOf(0x2de3bc);
233 ASI::EndRewrite(add_spell_mreg);
234}
235
236static void initialize_spellend_hook()
237{
238 ASI::MemoryRegion end_spell_mreg (ASI::AddrOf(0x34b0a0), 5);
239 ASI::BeginRewrite(end_spell_mreg);
240 *(unsigned char *)(ASI::AddrOf(0x34b0a0)) = 0xE9; // jmp instruction
241 *(int *)(ASI::AddrOf(0x34b0a1)) = (int)(&sf_endspell_hook) -
242 ASI::AddrOf(0x34b0a5);
243 ASI::EndRewrite(end_spell_mreg);
244}
245
246static void initialize_spellrefresh_hook()
247{
248 ASI::MemoryRegion refresh_spell_mreg (ASI::AddrOf(0x329f90), 9);
249 ASI::BeginRewrite(refresh_spell_mreg);
250 *(unsigned char *)(ASI::AddrOf(0x329f90)) = 0x90; // nop trail
251 *(unsigned char *)(ASI::AddrOf(0x329f91)) = 0x90; // nop trail
252 *(unsigned char *)(ASI::AddrOf(0x329f92)) = 0x90; // nop trail
253 *(unsigned char *)(ASI::AddrOf(0x329f93)) = 0x90; // nop trail
254 *(unsigned char *)(ASI::AddrOf(0x329f94)) = 0xE9; // jmp instruction
255 *(int *)(ASI::AddrOf(0x329f95)) = (int)(&sf_refresh_hook) -
256 ASI::AddrOf(0x329f99);
257 ASI::EndRewrite(refresh_spell_mreg);
258}
259
260static void __declspec(naked) menuload_hook_beta()
261{
262 asm ("push %%edi \n\t" // Storing a pointed to CAppMenu
263 "call %P0 \n\t" // Calling the Hook Function (this also calls the function we replace)
264 "pop %%edi \n\t" // Restoring EDI, then we jump back to the address of the original function that we interrupted.
265 "jmp *%1 \n\t" : : "i" (sf_menu_hook),
266 "o" (g_menu_return_addr));
267}
268
269static void __declspec(naked) ui_overlay_hook()
270{
271 asm ("pop %%eax \n\t" // Pop EAX to clean it for our use case
272 "push %%ebx \n\t" // Push Figure ID into our hook
273 "push %%eax \n\t" // Push Spell ID into our hook
274 "push %%ecx \n\t" // Push CGDResource into our hook
275 "mov %%esi, %%ecx \n\t" // CGDFigure is moved into our hook
276 "call %P0 \n\t" // Call our Hook
277 "push %%eax \n\t" // Put Correct Spell ID from out Hook to the stack
278 "lea -0x120(%%ebp),%%eax \n\t" // Assign the EAX to original stack variable.
279 "mov 0x10(%%edi),%%ecx \n\t" // Restore ECX to CGDResource
280 "jmp *%1 \n\t" : : // Jump back to control flow
281 "i" (sf_ui_overlay_fix),
282 "o" (g_ui_hook_fix_addr));
283}
284
285static void __declspec(naked) ui_overlay_hook2()
286{
287 asm ("pop %%eax \n\t" // Pop EAX to clean it for our use case
288 "push %%ebx \n\t" // Push Figure ID into our hook
289 "push %%eax \n\t" // Push Spell ID into our hook
290 "push %%ecx \n\t" // Push CGDResource into our hook
291 "mov %%esi, %%ecx \n\t" // CGDFigure is moved into our hook
292 "call %P0 \n\t" // Call our Hook
293 "push %%eax \n\t" // Put Correct Spell ID from out Hook to the stack
294 "lea -0x120(%%ebp),%%eax \n\t" // Assign the EAX to original stack variable.
295 "mov 0x10(%%edi),%%ecx \n\t" // Restore ECX to CGDResource
296 "jmp *%1 \n\t" : : // Jump back to control flow
297 "i" (sf_ui_overlay_fix),
298 "o" (g_ui_hook_fix_addr2));
299}
300
301static void initialize_ui_overlay_fix_hook()
302{
303 ASI::MemoryRegion ui_load_mreg (ASI::AddrOf(0x5D1198), 6);
304 ASI::BeginRewrite(ui_load_mreg);
305 *(uint8_t *)(ASI::AddrOf(0x5D1198)) = 0x90; //Nop Trail
306 *(uint8_t *)(ASI::AddrOf(0x5D1199)) = 0xE9; // jmp instruction
307 *(int *)(ASI::AddrOf(0x5D119a)) = (int)(&ui_overlay_hook) - ASI::AddrOf(0x5D119e);
308 ASI::EndRewrite(ui_load_mreg);
309
310 ASI::MemoryRegion ui_load_mreg2 (ASI::AddrOf(0x5d0a78), 6);
311
312 ASI::BeginRewrite(ui_load_mreg2);
313 *(uint8_t *)(ASI::AddrOf(0x5d0a78)) = 0x90; //Nop Trail
314 *(uint8_t *)(ASI::AddrOf(0x5d0a79)) = 0xE9; // jmp instruction
315 *(int *)(ASI::AddrOf(0x5d0a7a)) = (int)(&ui_overlay_hook2) - ASI::AddrOf(0x5d0a7e);
316 ASI::EndRewrite(ui_load_mreg2);
317
318}
319
320static void initialize_menuload_hook()
321{
322 ASI::MemoryRegion menu_load_mreg (ASI::AddrOf(0x182794), 5);
323 ASI::BeginRewrite(menu_load_mreg);
324 *(unsigned char *)(ASI::AddrOf(0x182794)) = 0xE9; // jmp instruction
325 *(int *)(ASI::AddrOf(0x182795)) = (int)(&menuload_hook_beta) -
326 ASI::AddrOf(0x182799);
327 ASI::EndRewrite(menu_load_mreg);
328}
329
330static void initialize_deal_damage_hook()
331{
332 // uint32_t flag_pointer = *(uint32_t *)(ASI::AddrOf());
334 ASI::MemoryRegion deal_damage_mreg (ASI::AddrOf(0x2f4af3), 6);
335 ASI::BeginRewrite(deal_damage_mreg);
336 *(unsigned char *)(ASI::AddrOf(0x2f4af3)) = 0x90; // nop trail
337 *(unsigned char *)(ASI::AddrOf(0x2f4af4)) = 0xE9; // JMP
338 *(int *)(ASI::AddrOf(0x2f4af5)) = (int)(&sf_damage_hook) -
339 ASI::AddrOf(0x2f4af9);
340}
341
342static void initialize_onhit_hook()
343{
344 ASI::MemoryRegion onhit_mreg (ASI::AddrOf(0x2e0b00), 5);
345 ASI::BeginRewrite(onhit_mreg);
346 *(unsigned char *)(ASI::AddrOf(0x2e0b00)) = 0xE9; // jmp instruction
347 *(int *)(ASI::AddrOf(0x2e0b01)) = (int)(&sf_onhit_hook) -
348 ASI::AddrOf(0x2e0b05);
349 ASI::EndRewrite(onhit_mreg);
350}
351static void initialize_ai_support_spell_hook()
352{
353 ASI::MemoryRegion ai_support_mreg (ASI::AddrOf(0x35d353), 5);
354 ASI::BeginRewrite(ai_support_mreg);
355 *(unsigned char *)(ASI::AddrOf(0x35d353)) = 0xE8; // CALL instruction
356 *(int *)(ASI::AddrOf(0x35d354)) = (int)(&rank_support_spell_hook) -
357 ASI::AddrOf(0x35d358);
358 ASI::EndRewrite(ai_support_mreg);
359}
360
361static void initialize_ai_offensive_hook()
362{
363 ASI::MemoryRegion ai_offensive_mreg (ASI::AddrOf(0x35d2f8), 5);
364 ASI::BeginRewrite(ai_offensive_mreg);
365 *(unsigned char *)(ASI::AddrOf(0x35d2f8)) = 0xE8; // CALL instruction
366 *(int *)(ASI::AddrOf(0x35d2f9)) = (int)(&rank_offensive_spell_hook) -
367 ASI::AddrOf(0x35d2fd);
368 ASI::EndRewrite(ai_offensive_mreg);
369
370 ASI::MemoryRegion ai_offensive_mreg2 (ASI::AddrOf(0x360fa6), 5);
371 ASI::BeginRewrite(ai_offensive_mreg2);
372 *(unsigned char *)(ASI::AddrOf(0x360fa6)) = 0xE8; // CALL instruction
373 *(int *)(ASI::AddrOf(0x360fa7)) = (int)(&rank_offensive_spell_hook) -
374 ASI::AddrOf(0x360fab);
375 ASI::EndRewrite(ai_offensive_mreg2);
376}
377
378static void initialize_ai_aoe_hook()
379{
380 ASI::MemoryRegion ai_offensive_mreg (ASI::AddrOf(0x35cb4f), 5);
381 ASI::BeginRewrite(ai_offensive_mreg);
382 *(unsigned char *)(ASI::AddrOf(0x35cb4f)) = 0xE8; // CALL instruction
383 *(int *)(ASI::AddrOf(0x35cb50)) = (int)(&ai_AOE_hook) -
384 ASI::AddrOf(0x35cb54);
385 ASI::EndRewrite(ai_offensive_mreg);
386
387 ASI::MemoryRegion ai_offensive_mreg2 (ASI::AddrOf(0x35cadc), 5);
388 ASI::BeginRewrite(ai_offensive_mreg2);
389 *(unsigned char *)(ASI::AddrOf(0x35cadc)) = 0xE8; // CALL instruction
390 *(int *)(ASI::AddrOf(0x35cadd)) = (int)(&ai_AOE_hook) -
391 ASI::AddrOf(0x35cae1);
392 ASI::EndRewrite(ai_offensive_mreg2);
393}
394
395static void initialize_avoidance_hook()
396{
397 ASI::MemoryRegion ai_avoidance_mreg (ASI::AddrOf(0x35d39e), 5);
398 ASI::BeginRewrite(ai_avoidance_mreg);
399 *(unsigned char *)(ASI::AddrOf(0x35d39e)) = 0xE8; // CALL instruction
400 *(int *)(ASI::AddrOf(0x35d39f)) = (int)(&avoidance_penalty_hook) -
401 ASI::AddrOf(0x35d3a3);
402 ASI::EndRewrite(ai_avoidance_mreg);
403}
404static void initialize_utility_hooks()
405{
406 log_info("Hooking Combat Ability Detection");
407 ASI::MemoryRegion is_ability_line_mreg (ASI::AddrOf(0x32afb0), 5);
408 ASI::BeginRewrite(is_ability_line_mreg);
409 *(unsigned char *)(ASI::AddrOf(0x32afb0)) = 0xE9; // JUMP instruction
410 *(int *)(ASI::AddrOf(0x32afb1)) = (int)(&is_combat_ability) -
411 ASI::AddrOf(0x32afb5);
412 ASI::EndRewrite(is_ability_line_mreg);
413
414 log_info("Hooking AOE Spell Detection");
415 ASI::MemoryRegion is_aoe_line_mreg (ASI::AddrOf(0x32ac90), 5);
416 ASI::BeginRewrite(is_aoe_line_mreg);
417 *(unsigned char *)(ASI::AddrOf(0x32ac90)) = 0xE9; // JUMP instruction
418 *(int *)(ASI::AddrOf(0x32ac91)) = (int)(&is_aoe_spell) -
419 ASI::AddrOf(0x32ac95);
420 ASI::EndRewrite(is_aoe_line_mreg);
421
422 log_info("Hooking Aura Detection");
423 ASI::MemoryRegion is_aura_mreg (ASI::AddrOf(0x32ae20), 5);
424 ASI::BeginRewrite(is_aura_mreg);
425 *(unsigned char *)(ASI::AddrOf(0x32ae20)) = 0xE9; // JUMP instruction
426 *(int *)(ASI::AddrOf(0x32ae21)) = (int)(&is_aura_spell) -
427 ASI::AddrOf(0x32ae25);
428 ASI::EndRewrite(is_aura_mreg);
429
430 log_info("Hooking Black Aura Detection");
431 ASI::MemoryRegion is_black_aura_mreg (ASI::AddrOf(0x32aec0), 5);
432 ASI::BeginRewrite(is_black_aura_mreg);
433 *(unsigned char *)(ASI::AddrOf(0x32aec0)) = 0xE9; // JUMP instruction
434 *(int *)(ASI::AddrOf(0x32aec1)) = (int)(&is_black_aura_spell) -
435 ASI::AddrOf(0x32aec5);
436 ASI::EndRewrite(is_black_aura_mreg);
437
438 log_info("Hooking White Aura Detection");
439 ASI::MemoryRegion is_white_aura_mreg (ASI::AddrOf(0x32af00), 5);
440 ASI::BeginRewrite(is_white_aura_mreg);
441 *(unsigned char *)(ASI::AddrOf(0x32af00)) = 0xE9; // JUMP instruction
442 *(int *)(ASI::AddrOf(0x32af01)) = (int)(&is_white_aura_spell) -
443 ASI::AddrOf(0x32af05);
444 ASI::EndRewrite(is_white_aura_mreg);
445
446 log_info("Hooking Summon Spell Detection");
447 ASI::MemoryRegion is_summon_spell_mreg (ASI::AddrOf(0x32b060), 5);
448 ASI::BeginRewrite(is_summon_spell_mreg);
449 *(unsigned char *)(ASI::AddrOf(0x32b060)) = 0xE9; // JUMP instruction
450 *(int *)(ASI::AddrOf(0x32b061)) = (int)(&is_summon_spell) -
451 ASI::AddrOf(0x32b065);
452 ASI::EndRewrite(is_summon_spell_mreg);
453
454 log_info("Hooking Domination Spell Detection");
455 ASI::MemoryRegion is_domination_spell_mreg (ASI::AddrOf(0x32ac20), 5);
456 ASI::BeginRewrite(is_domination_spell_mreg);
457 *(unsigned char *)(ASI::AddrOf(0x32ac20)) = 0xE9; // JUMP instruction
458 *(int *)(ASI::AddrOf(0x32ac21)) = (int)(&is_domination_spell) -
459 ASI::AddrOf(0x32ac25);
460 ASI::EndRewrite(is_domination_spell_mreg);
461
462 log_info("Hooking Domination Spell Line Detection");
463 ASI::MemoryRegion is_domination_spellline_mreg (ASI::AddrOf(0x32af60), 5);
464 ASI::BeginRewrite(is_domination_spellline_mreg);
465 *(unsigned char *)(ASI::AddrOf(0x32af60)) = 0xE9; // JUMP instruction
466 *(int *)(ASI::AddrOf(0x32af61)) = (int)(&is_domination_spellline) -
467 ASI::AddrOf(0x32af65);
468 ASI::EndRewrite(is_domination_spellline_mreg);
469
470 // log_info("Temp Storm School Hook");
471 // ASI::MemoryRegion storm_test_mreg (ASI::AddrOf(0x7FFD38), 1);
472 // ASI::BeginRewrite(storm_test_mreg);
473 // *(unsigned char *)(ASI::AddrOf(0x7FFD38)) = 0x04;
474 // ASI::EndRewrite(storm_test_mreg);
475}
476
478{
479 ASI::MemoryRegion vfunction208_mreg_1 (ASI::AddrOf(0x5ebb23), 5);
480 ASI::BeginRewrite(vfunction208_mreg_1);
481 *(unsigned char *)(ASI::AddrOf(0x5ebb23)) = 0xE8; // CALL instruction
482 *(int *)(ASI::AddrOf(0x5ebb24)) = (int)(&sf_click_vertical_button) -
483 ASI::AddrOf(0x5ebb28);
484 ASI::EndRewrite(vfunction208_mreg_1);
485
486 ASI::MemoryRegion vfunction208_mreg_2 (ASI::AddrOf(0x5ebb7b), 5);
487 ASI::BeginRewrite(vfunction208_mreg_2);
488 *(unsigned char *)(ASI::AddrOf(0x5ebb7b)) = 0xE8; // CALL instruction
489 *(int *)(ASI::AddrOf(0x5ebb7c)) = (int)(&sf_click_vertical_button) -
490 ASI::AddrOf(0x5bb80);
491 ASI::EndRewrite(vfunction208_mreg_2);
492
493 ASI::MemoryRegion vfunction210_mreg(ASI::AddrOf(0x5ed94a), 5);
494 ASI::BeginRewrite(vfunction210_mreg);
495 *(unsigned char *)(ASI::AddrOf(0x5ed94a)) = 0xE8; // JUMP instruction
496 *(int *)(ASI::AddrOf(0x5ed94b)) = (int)(&sf_click_horizontal_button) -
497 ASI::AddrOf(0x5ed94f);
498 ASI::EndRewrite(vfunction210_mreg);
499
500}
501
503{
504 log_info("Hooking Spell Types");
505 initialize_spelltype_hook();
506
507 log_info("Hooking Spell Triggers");
508 initialize_spell_trigger_hook();
509
510 log_info("Hooking Spell Refresh Triggers");
511 initialize_spellrefresh_hook();
512
513 log_info("Hooking Spell End Triggers");
514 initialize_spellend_hook();
515
516 log_info("Hooking Deal Damage Trigger");
517 initialize_deal_damage_hook();
518
519 log_info("Hooking AddSpellFromEffect function");
520 initialize_subeffect_add_hook();
521
522 log_info("Dirty Menu Loading Trigger Test");
523 initialize_menuload_hook();
524
525 log_info("Hooking On Hit Trigger");
526 initialize_onhit_hook();
527
528 log_info("Hooking AI Support Spell Handling");
529 initialize_ai_support_spell_hook();
530
531 log_info("Hooking AI Offensive Spell Handling");
532 initialize_ai_offensive_hook();
533
534 log_info("Hooking AI Spell Avoidance Handling");
535 initialize_avoidance_hook();
536
537 log_info("Hook UI Overlay to Fix Descriptions");
538 initialize_ui_overlay_fix_hook();
539
540 log_info("Hook AI AOE Handling");
541 initialize_ai_aoe_hook();
542
543 log_info("Hooking Utility Functions");
544 initialize_utility_hooks();
545
546 log_info("Hooking spell buttons");
548}
549
uint32_t __thiscall rank_support_spell_hook(SF_CGdBattleDevelopment *_this, uint16_t target_index, uint16_t spell_line, SF_CGdResourceSpell *spell_data)
Injects into the ranking system for a single target AI spell.
Definition sf_ai_hook.c:71
uint32_t __thiscall avoidance_penalty_hook(SF_CGdBattleDevelopment *_this, uint16_t figure_index)
Definition sf_ai_hook.c:117
uint32_t __thiscall rank_offensive_spell_hook(SF_CGdBattleDevelopment *_this, uint16_t target_index, uint16_t spell_line, SF_CGdResourceSpell *spell_data)
Definition sf_ai_hook.c:92
uint32_t __thiscall ai_AOE_hook(SF_CGdBattleDevelopment *_this, SF_Coord cast_pos, uint16_t spell_line, SF_CGdResourceSpell *spell_data)
Definition sf_ai_hook.c:146
void initialize_console_data_hooks()
uint32_t g_damage_return_addr
void sf_damage_hook()
Hook function for damage handling in the game. This function intercepts the call to deal damage and r...
void __thiscall sf_spelleffect_hook(SF_CGdSpell *_this)
void __thiscall sf_endspell_hook(SF_CGdSpell *_this, uint16_t spell_index)
void initialize_data_hooks()
Used to initialize all disparate hooks in one place.
Definition sf_hooks.c:51
void initialize_spell_buttons_hooks()
Definition sf_hooks.c:477
EffectFunctions effectAPI
Definition sf_hooks.c:37
void initialize_beta_hooks()
Definition sf_hooks.c:502
IteratorFunctions iteratorAPI
Definition sf_hooks.c:40
ToolboxFunctions toolboxAPI
Definition sf_hooks.c:38
AiFunctions aiAPI
Definition sf_hooks.c:41
SpellFunctions spellAPI
Definition sf_hooks.c:36
FigureFunctions figureAPI
Definition sf_hooks.c:39
RegistrationFunctions registrationAPI
Definition sf_hooks.c:42
uint32_t g_menu_return_addr
uint32_t g_ui_hook_fix_addr
uint32_t g_ui_hook_fix_addr2
void sf_click_horizontal_button(SF_CUiMain *_this, uint_list_node *param1, SF_UIElement *param2)
void sf_menu_hook(uint32_t _CAppMenu)
void initialize_menu_data_hooks()
uint16_t sf_ui_overlay_fix(SF_CGdFigure *_this, void *CGdResource, uint16_t spell_id, uint16_t figure_id)
void sf_click_vertical_button(SF_CUiMain *_this, uint16_t figure_id, uint8_t entity_type, uint16_t target_id, SF_UIElement *element)
void initialize_onhit_data_hooks()
void __thiscall sf_onhit_hook(SF_CGdFigureJobs *_this, uint16_t source_index, uint32_t param_2, uint8_t param_3)
int __thiscall sf_refresh_hook(SF_CGdSpell *_this, uint16_t spell_index)
void initialize_spelltype_data_hooks()
uint16_t __thiscall sf_spelltype_hook(SF_CGdSpell *_this, uint16_t spell_id, uint16_t param2, SF_CGdTargetData *source, SF_CGdTargetData *target, uint16_t param5)
void __thiscall sf_subeffect_hook(SF_CGDEffect *_this, uint16_t effect_id)
bool __thiscall is_summon_spell(SF_CGdSpell *_this, GdSpellLine spell_line)
bool __thiscall is_white_aura_spell(SF_CGdSpell *_this, GdSpellLine spell_line)
bool __thiscall is_aura_spell(SF_CGdSpell *_this, GdSpellLine spell_line)
bool __thiscall is_combat_ability(SF_CGdSpell *_this, GdSpellLine spell_line)
bool __thiscall is_domination_spell(SF_CGdSpell *_this, GdSpellLine spell_line)
bool __thiscall is_aoe_spell(SF_CGdSpell *_this, GdSpellLine spell_line)
bool __thiscall is_domination_spellline(SF_CGdSpell *_this, GdSpellLine spell_line)
bool __thiscall is_black_aura_spell(SF_CGdSpell *_this, GdSpellLine spell_line)
void __thiscall addBonusMultToStatistic(SF_CGdFigure *figure, StatisticDataKey key, uint16_t target, int8_t value)
void log_info(const char *message)
Definition sf_wrappers.c:89
void __thiscall setupFigureIterator(CGdFigureIterator *iterator, SF_CGdSpell *spell)
bool __thiscall hasSpellTag(uint16_t spell_id, SpellTag tag)
bool __thiscall hasAuraActive(SF_CGdFigureToolbox *_this, uint16_t figure_id)
void __thiscall spellClearFigureFlag(SF_CGdSpell *_this, uint16_t spell_id, SpellFlagKey key)
void __thiscall disposeFigureIterator(CGdFigureIterator *iterator)
void initialize_wrapper_data_hooks()
Definition sf_wrappers.c:46
uint16_t __thiscall sf_get_spell_id(SF_CGdSpell *_this, uint16_t spell_index)
int AddrOf(int offset)
returns "real" virtual address of given memory offset
Definition sf_asi.h:135
bool BeginRewrite(MemoryRegion &mem_region)
allows rewriting code in a given memory region by overwriting permissions for that memory region
Definition sf_asi.cpp:6
bool EndRewrite(MemoryRegion &mem_region)
ends rewriting by restoring old permissions in a given memory region
Definition sf_asi.cpp:14
void __thiscall linkAOEAIHandler(SFSpell *spell, ai_aoe_handler_ptr handler)
#define DEFINE_FUNCTION(group, name, address)
Definition sf_hooks.h:8
void __thiscall linkEndHandler(SFSpell *spell, handler_ptr endHandler)
void __thiscall linkDealDamageHandler(SFSpell *spell, damage_handler_ptr handler, SpellDamagePhase phase)
void __thiscall applySpellTag(SFSpell *spell, SpellTag tag)
void __thiscall linkTypeHandler(SFSpell *spell, handler_ptr typeHandler)
#define INCLUDE_FUNCTION(group, name, pointer)
Definition sf_hooks.h:12
void __thiscall linkRefreshHandler(SFSpell *spell, refresh_handler_ptr handler)
void __thiscall linkEffectHandler(SFSpell *spell, uint16_t spell_effect_id, handler_ptr effectHandler)
void __thiscall linkSingleTargetAIHandler(SFSpell *spell, ai_single_handler_ptr handler)
void __thiscall linkAvoidanceAIHandler(SFSpell *spell, ai_avoidance_handler_ptr handler)
void __thiscall linkOnHitHandler(SFSpell *spell, onhit_handler_ptr handler, OnHitPhase phase)
void __thiscall linkSubEffectHandler(SFSpell *spell, sub_effect_handler_ptr handler)
SFSpell *__thiscall registerSpell(uint16_t spell_id)
uint16_t __thiscall getSpellTags(uint16_t spell_line_id)
void __thiscall initializeSpellData(SF_CGdSpell *_this, uint16_t spell_id, SpellDataKey key)
MemoryRegion is used for rewriting code in a given memory block.
Definition sf_asi.h:17
Group of functions related to AI manipulation.
Group of functions related to Effect manipulation.
Group of functions to manipulate the behavior and statistics of the game figures (units)
Group of functions related to Iteration, Often used for AOE or Chain Like Spells.
A structure dedicated to the registration of spells This structure holds functions that are used to c...
Represents a collection of function pointers for managing spell-related operations.
Holds most of the Toolbox Functions relevent for custom spells. Includes functions for the manipulati...