Spellforce-Spell-framework
Loading...
Searching...
No Matches
sf_onhit_handlers.cpp
Go to the documentation of this file.
1#include "sf_onhit_handlers.h"
3#include "../core/sf_hooks.h"
4#include <list>
5
6uint16_t __thiscall trueshot_onhit_handler(SF_CGdFigureJobs *_this,
7 uint16_t source_index,
8 uint16_t target_index,
9 uint16_t damage)
10{
11 SF_SGtFigureAction action;
12 aiAPI.getTargetAction(_this->CGdFigure, &action, source_index);
13
14 if (isActionMelee(&action))
15 {
16 return damage;
17 }
18
19 uint16_t spell_index_of_type = toolboxAPI.getSpellIndexOfType(_this->CGdFigureToolBox, source_index,
21 SF_CGdResourceSpell spell_data;
22 uint16_t spell_id = spellAPI.getSpellID(_this->CGdSpell, spell_index_of_type);
23 spellAPI.getResourceSpellData(_this->CGdResource, &spell_data, spell_id);
24 uint16_t current_damage = (spell_data.params[1] * damage) / 100;
25 return current_damage;
26}
27
28uint16_t __thiscall riposte_onhit_handler(SF_CGdFigureJobs *_this,
29 uint16_t source_index,
30 uint16_t target_index,
31 uint16_t damage)
32{
33 SF_SGtFigureAction action;
34 aiAPI.getTargetAction(_this->CGdFigure, &action, source_index);
35 bool isMeleeAttack = isActionMelee(&action);
36
37 if (!isMeleeAttack)
38 {
39 return damage;
40 }
41
42 SF_CGdResourceSpell spell_data;
43 uint16_t spell_index =
44 toolboxAPI.getSpellIndexOfType(_this->CGdFigureToolBox, target_index,
46 uint16_t spell_id = spellAPI.getSpellID(_this->CGdSpell, spell_index);
47 spellAPI.getResourceSpellData(_this->CGdResource, &spell_data, spell_id);
48
49 uint16_t return_damage = (damage * spell_data.params[0]) / 100;
50
51 // Lower the damage by the amount that will be reflected
52 uint16_t final_damage = (damage - return_damage);
53 if (final_damage != 0)
54 {
55 toolboxAPI.dealDamage(_this->CGdFigureToolBox, target_index,
56 source_index, return_damage, 0, 0, 0);
57 }
58
59 return final_damage;
60}
61
62uint16_t __thiscall durability_onhit_handler(SF_CGdFigureJobs *_this,
63 uint16_t source_index,
64 uint16_t target_index,
65 uint16_t damage)
66{
67 SF_SGtFigureAction action;
68 aiAPI.getTargetAction(_this->CGdFigure, &action, source_index);
69 bool isMeleeAttack = isActionMelee(&action);
70
71 if (!isMeleeAttack)
72 {
73 return damage;
74 }
75
76 SF_CGdResourceSpell spell_data;
77 uint16_t spell_index =
78 toolboxAPI.getSpellIndexOfType(_this->CGdFigureToolBox, source_index,
80 uint16_t spell_id = spellAPI.getSpellID(_this->CGdSpell, spell_index);
81 spellAPI.getResourceSpellData(_this->CGdResource, &spell_data, spell_id);
82 return (damage * spell_data.params[1]) / 100;
83}
84
86 uint16_t source_index,
87 uint16_t target_index,
88 uint16_t damage)
89{
90 // no need to calculate damage in this cases
91 if (damage == 0)
92 {
93 return damage;
94 }
95 uint16_t target_level = _this->CGdFigure->figures[target_index].level;
96 uint16_t source_level = _this->CGdFigure->figures[source_index].level;
97 // not proccing on targets 5+ levels above source
98 if (source_level + 5 <= target_level)
99 {
100 return damage;
101 }
102 // outright killing targets 15+ levels below
103 if (source_level - 0xf > target_level)
104 {
105 return 0x7fff;
106 }
107 SF_CGdResourceSpell spell_data;
108 uint16_t spell_index = toolboxAPI.getSpellIndexOfType(_this->CGdFigureToolBox, source_index,
110 uint16_t spell_id = spellAPI.getSpellID(_this->CGdSpell, spell_index);
111 spellAPI.getResourceSpellData(_this->CGdResource, &spell_data, spell_id);
112
113 uint16_t tmp_damage = damage * spell_data.params[1];
114 uint16_t hp_left = figureAPI.getCurrentStat(_this->CGdFigure, target_index, HEALTH);
115 if (tmp_damage < hp_left)
116 {
117 return damage;
118 }
119
120 tmp_damage = ((tmp_damage - hp_left) * 100) / tmp_damage;
121 uint16_t chance = 5 * tmp_damage *
122 (5 + (int16_t)(source_level - target_level));
123 if (spellAPI.getRandom(_this->OpaqueClass, 10000) > chance)
124 {
125 return damage;
126 }
127 return 0x7fff;
128}
129
130uint16_t __thiscall endurance_onhit_handler(SF_CGdFigureJobs *_this,
131 uint16_t source_index,
132 uint16_t target_index,
133 uint16_t damage)
134{
135 SF_SGtFigureAction action;
136 aiAPI.getTargetAction(_this->CGdFigure, &action, source_index);
137 bool isMeleeAttack = isActionMelee(&action);
138
139 if (!isMeleeAttack)
140 {
141 return damage;
142 }
143 if (toolboxAPI.hasSpellOnIt(_this->CGdFigureToolBox, source_index,
145 {
146 return damage;
147 }
148
149 SF_CGdResourceSpell spell_data;
150 uint16_t spell_index =
151 toolboxAPI.getSpellIndexOfType(_this->CGdFigureToolBox, source_index,
153 uint16_t spell_id = spellAPI.getSpellID(_this->CGdSpell, spell_index);
154 spellAPI.getResourceSpellData(_this->CGdResource, &spell_data, spell_id);
155 return (damage * spell_data.params[1]) / 100;
156}
157
158uint16_t __thiscall berserk_onhit_handler(SF_CGdFigureJobs *_this,
159 uint16_t source_index,
160 uint16_t target_index,
161 uint16_t damage)
162{
163 SF_SGtFigureAction action;
164 aiAPI.getTargetAction(_this->CGdFigure, &action, source_index);
165 bool isMeleeAttack = isActionMelee(&action);
166
167 if (!isMeleeAttack)
168 {
169 return damage;
170 }
171 if (toolboxAPI.hasSpellOnIt(_this->CGdFigureToolBox, source_index,
173 {
174 return damage;
175 }
176 if (toolboxAPI.hasSpellOnIt(_this->CGdFigureToolBox, source_index,
178 {
179 return damage;
180 }
181 SF_CGdResourceSpell spell_data;
182 uint16_t spell_index =
183 toolboxAPI.getSpellIndexOfType(_this->CGdFigureToolBox, source_index,
185 uint16_t spell_id = spellAPI.getSpellID(_this->CGdSpell, spell_index);
186 spellAPI.getResourceSpellData(_this->CGdResource, &spell_data, spell_id);
187 return (damage * spell_data.params[1]) / 100;
188}
189
190uint16_t __thiscall warcry_onhit_handler(SF_CGdFigureJobs *_this,
191 uint16_t source_index,
192 uint16_t target_index, uint16_t damage)
193{
194 SF_SGtFigureAction action;
195 aiAPI.getTargetAction(_this->CGdFigure, &action, source_index);
196 bool isMeleeAttack = isActionMelee(&action);
197
198 if (!isMeleeAttack)
199 {
200 return damage;
201 }
202 if (toolboxAPI.hasSpellOnIt(_this->CGdFigureToolBox, source_index,
204 {
205 return damage;
206 }
207 if (toolboxAPI.hasSpellOnIt(_this->CGdFigureToolBox, source_index,
209 {
210 return damage;
211 }
212 if (toolboxAPI.hasSpellOnIt(_this->CGdFigureToolBox, source_index,
214 {
215 return damage;
216 }
217 SF_CGdResourceSpell spell_data;
218 uint16_t spell_index =
219 toolboxAPI.getSpellIndexOfType(_this->CGdFigureToolBox, source_index,
221 uint16_t spell_id = spellAPI.getSpellID(_this->CGdSpell, spell_index);
222 spellAPI.getResourceSpellData(_this->CGdResource, &spell_data, spell_id);
223 return (damage * spell_data.params[1]) / 100;
224}
225
227 uint16_t source_index,
228 uint16_t target_index,
229 uint16_t damage)
230{
231 // oneshot or zero damage
232 if (damage == 0x7fff || damage == 0)
233 {
234 return damage;
235 }
236 SF_CGdResourceSpell spell_data;
237 uint16_t spell_index = toolboxAPI.getSpellIndexOfType(_this->CGdFigureToolBox, target_index, kGdSpellLineAssistance,
238 0);
239 uint16_t spell_id = spellAPI.getSpellID(_this->CGdSpell, spell_index);
240 spellAPI.getResourceSpellData(_this->CGdResource, &spell_data, spell_id);
242 iteratorAPI.figureIteratorInit(&iter, 0, 0, 0x3ff, 0x3ff);
243 iteratorAPI.figureIteratorSetPointers(&iter, _this->CGdFigure, _this->AutoClass22, _this->CGdWorld);
244 iteratorAPI.iteratorSetArea(&iter, &_this->CGdFigure->figures[target_index].position, spell_data.params[0]);
245 std::list<uint16_t> affected_figures;
246 uint16_t figure_id = iteratorAPI.getNextFigure(&iter);
247 uint16_t element_count = 0;
248 while (figure_id != 0)
249 {
250 if ((figureAPI.isAlive(_this->CGdFigure, figure_id))
251 && (toolboxAPI.isTargetable(_this->CGdFigureToolBox, figure_id)))
252 {
253 if (toolboxAPI.figuresCheckFriendly(_this->CGdFigureToolBox,target_index, figure_id))
254 {
255
256 if (figure_id != target_index)
257 {
258 affected_figures.push_back(figure_id);
259 element_count++;
260 }
261 if (element_count == spell_data.params[1])
262 {
263 break;
264 }
265 }
266 }
267 figure_id = iteratorAPI.getNextFigure(&iter);
268 }
269 if (element_count != 0)
270 {
271 uint16_t shared_damage = (damage / (element_count + 1));
272 uint16_t remainder = (damage % (element_count + 1));
273 SF_Coord source_pos = _this->CGdFigure->figures[target_index].position;
274 SF_CGdTargetData source_data;
275 source_data.entity_index = target_index;
276 source_data.entity_type = 1;
277 source_data.position = source_pos;
278 for (auto t : affected_figures)
279 {
280 SF_Coord friend_pos = _this->CGdFigure->figures[t].position;
281 uint32_t distance = getDistance(&source_pos, &friend_pos);
282 distance = (distance * 0x578) / 1000;
283 if (distance == 0)
284 {
285 distance = 1;
286 }
287 SF_CGdTargetData friend_data;
288 friend_data.entity_type = 1;
289 friend_data.entity_index = t;
290 friend_pos = friend_pos;
291 SF_Rectangle unused = {0, 0};
292 effectAPI.addEffect(_this->CGdEffect, kGdEffectSpellAssistanceHitFigure, &source_data, &friend_data,
293 _this->OpaqueClass->current_step, distance, &unused);
294 toolboxAPI.dealDamage(_this->CGdFigureToolBox, source_index, t, shared_damage, 0, 0, 0);
295 }
296 damage = shared_damage + remainder;
297 }
298 iteratorAPI.disposeFigureIterator(&iter);
299 return damage;
300}
SpellFunctions * spellAPI
Definition TestMod.cpp:11
FigureFunctions * figureAPI
Definition TestMod.cpp:13
ToolboxFunctions * toolboxAPI
Definition TestMod.cpp:12
EffectFunctions effectAPI
Definition sf_hooks.c:45
IteratorFunctions iteratorAPI
Definition sf_hooks.c:49
AiFunctions aiAPI
Definition sf_hooks.c:51
uint32_t __thiscall getDistance(SF_Coord *pointA, SF_Coord *pointB)
Definition sf_wrappers.c:41
bool __thiscall isActionMelee(SF_SGtFigureAction *_this)
@ kGdEffectSpellAssistanceHitFigure
@ kGdSpellLineAbilityTrueShot
@ kGdSpellLineAbilityDurability
@ kGdSpellLineAbilityCriticalHits
@ kGdSpellLineAbilityWarCry
@ kGdSpellLineAssistance
@ kGdSpellLineAbilityRiposte
@ kGdSpellLineAbilityBerserk
@ kGdSpellLineAbilityEndurance
uint16_t __thiscall critical_hits_onhit_handler(SF_CGdFigureJobs *_this, uint16_t source_index, uint16_t target_index, uint16_t damage)
uint16_t __thiscall endurance_onhit_handler(SF_CGdFigureJobs *_this, uint16_t source_index, uint16_t target_index, uint16_t damage)
uint16_t __thiscall warcry_onhit_handler(SF_CGdFigureJobs *_this, uint16_t source_index, uint16_t target_index, uint16_t damage)
uint16_t __thiscall assistance_onhit_handler(SF_CGdFigureJobs *_this, uint16_t source_index, uint16_t target_index, uint16_t damage)
uint16_t __thiscall berserk_onhit_handler(SF_CGdFigureJobs *_this, uint16_t source_index, uint16_t target_index, uint16_t damage)
uint16_t __thiscall riposte_onhit_handler(SF_CGdFigureJobs *_this, uint16_t source_index, uint16_t target_index, uint16_t damage)
uint16_t __thiscall durability_onhit_handler(SF_CGdFigureJobs *_this, uint16_t source_index, uint16_t target_index, uint16_t damage)
uint16_t __thiscall trueshot_onhit_handler(SF_CGdFigureJobs *_this, uint16_t source_index, uint16_t target_index, uint16_t damage)
GdFigure figures[2000]
SF_CGdFigureToolbox * CGdFigureToolBox