Spellforce-Spell-framework
Loading...
Searching...
No Matches
sf_damage_hook.c
Go to the documentation of this file.
1
7
8#include "sf_damage_hook.h"
9
10#include "../sf_wrappers.h"
11#include "../sf_hooks.h"
12
15
16#include <stdint.h>
17#include <stdlib.h>
18#include <stdio.h>
19#include <string.h>
20
22
23uint32_t __attribute__((no_caller_saved_registers,
24 thiscall)) sf_deal_damage(
25 SF_CGdFigureToolbox *figureToolbox,
26 uint16_t
27 dmg_source,
28 uint16_t dmg_target, uint32_t damage_amount,
29 uint32_t is_spell_damage,
30 uint32_t is_ranged_damage, uint32_t vry_unknown_6)
31{
32 /* TODO - rewrite this for later use after spell damage function call
33 if ((((source != 0) && (iVar6 = CGdFigure::IsAlive(local_270->gd_figure,source), iVar6 != 0)) &&
34 (iVar6 = HasSpellOnIt(local_270,source,0xa5), iVar6 != 0)) ||
35 (iVar6 = HasSpellOnIt(local_270,target,0xa5), iVar6 != 0)) {
36 local_29c = 1;
37 }
38 */
39
40 bool check_spells_before_job = figureAPI.isFlagSet(figureToolbox->CGdFigure, dmg_target, F_CHECK_SPELLS_BEFORE_JOB);
41 if (check_spells_before_job)
42 {
43 uint16_t spell_job_start_node = figureAPI.getSpellJobStartNode(figureToolbox->CGdFigure, dmg_target);
44 uint16_t current_list_size = 0;
45
46 uint32_t ids_by_phase[COUNT][799];
47 size_t sizes_by_phase[COUNT] = {0};
48
49 while (spell_job_start_node != 0)
50 {
51 uint16_t spell_index =
52 toolboxAPI.getSpellIndexFromDLL(
53 figureToolbox->CGdDoubleLinkedList, spell_job_start_node);
54 uint16_t spell_line_id =
55 spellAPI.getSpellLine(figureToolbox->CGdSpell, spell_index);
56 // collect spell_line_id & spell_index here to list
57
58 for (int i = PRE; i < COUNT; ++i)
59 {
61 damage_handler_ptr exists = get_spell_damage(spell_line_id,
62 phase);
63 if (exists != NULL)
64 {
65 ids_by_phase[phase][sizes_by_phase[phase]++] =
66 (spell_index << 0x10) | spell_line_id;
67 current_list_size++;
68 }
69 }
70 spell_job_start_node = toolboxAPI.getNextNode(figureToolbox->CGdDoubleLinkedList, spell_job_start_node);
71 }
72
73 for (int i = PRE; i < COUNT; ++i)
74 {
76
77 for (size_t i = 0; i < sizes_by_phase[phase]; ++i)
78 {
79 uint32_t packed_id = ids_by_phase[phase][i];
80 uint16_t spell_line_id = packed_id & 0xffff;
81 uint16_t spell_index = (packed_id >> 0x10);
82 uint16_t spell_id = spellAPI.getSpellID(figureToolbox->CGdSpell,
83 spell_index);
84 damage_handler_ptr spell_damage_func =
85 get_spell_damage(spell_line_id, phase);
86 if(spell_damage_func != NULL)
87 {
88 damage_amount = spell_damage_func(figureToolbox, dmg_source,
89 dmg_target, damage_amount,
90 is_spell_damage,
91 is_ranged_damage,
92 spell_id);
93 }
94 }
95 }
96 }
97#if _DEBUG_
98 log_error("Dealing Damage: %d", damage_amount);
99#endif
100 return damage_amount;
101}
102
121void __declspec(naked) sf_damage_hook()
122{
123 asm ("push 0x1c(%%ebp) \n\t"
124 "push 0x18(%%ebp) \n\t"
125 "push 0x14(%%ebp) \n\t"
126 "push 0x10(%%ebp) \n\t"
127 "push 0x0c(%%ebp) \n\t"
128 "push 0x08(%%ebp) \n\t"
129 "mov -0x26c(%%ebp), %%ecx \n\t"
130 "call %P0 \n\t"
131 "movw %%ax, 0x10(%%ebp) \n\t"
132 "jmp *%1 " : : "i" (sf_deal_damage),
134}
135
SpellFunctions * spellAPI
Definition TestMod.cpp:11
FigureFunctions * figureAPI
Definition TestMod.cpp:13
ToolboxFunctions * toolboxAPI
Definition TestMod.cpp:12
uint32_t g_damage_return_addr
uint32_t sf_deal_damage(SF_CGdFigureToolbox *figureToolbox, uint16_t dmg_source, uint16_t dmg_target, uint32_t damage_amount, uint32_t is_spell_damage, uint32_t is_ranged_damage, uint32_t vry_unknown_6)
void sf_damage_hook()
Hook function for damage handling in the game. This function intercepts the call to deal damage and r...
void log_error(const char *format,...)
Group of Structures and Enums used throught SFSF.
@ F_CHECK_SPELLS_BEFORE_JOB
uint16_t(__thiscall * damage_handler_ptr)(SF_CGdFigureToolbox *_toolbox, uint16_t source, uint16_t target, uint16_t current_damage, uint16_t is_spell_damage, uint32_t is_ranged_damage, uint16_t spell_id)
damage_handler_ptr get_spell_damage(const uint16_t spell_line_id, SpellDamagePhase phase)