Spellforce-Spell-framework
Loading...
Searching...
No Matches
sf_mod_registry.cpp
Go to the documentation of this file.
1#include "sf_mod_registry.h"
2
10
14
15#include <windows.h>
16#include <iostream>
17#include <map>
18#include <list>
19#include <cstdint>
20#include <stdio.h>
21#include <stdarg.h>
22#include <stdlib.h>
23#include <string.h>
24
25std::list<SFSpell *> g_internal_spell_list;
26
27SFSpell *__thiscall registerSpell(uint16_t spell_id)
28{
29 SFSpell *sf_spell = new SFSpell;
30 sf_spell->spell_id = spell_id;
31 sf_spell->spell_effect_id = 0x00;
32 sf_spell->spell_tags = 0x0;
33 sf_spell->spell_type_handler = nullptr;
34 sf_spell->spell_effect_handler = nullptr;
35 sf_spell->spell_end_handler = nullptr;
36 sf_spell->spell_onhit_handler = nullptr;
37 sf_spell->spell_refresh_handler = nullptr;
38 sf_spell->sub_effect_handler = nullptr;
39 sf_spell->parent_mod = g_current_mod;
40 sf_spell->deal_damage_handler = nullptr;
41 sf_spell->ai_aoe_handler = nullptr;
42 sf_spell->ai_single_handler = nullptr;
43 sf_spell->ai_avoidance_handler = nullptr;
46 g_internal_spell_list.push_back(sf_spell);
47
48 return sf_spell;
49}
50
51void __thiscall applySpellTag(SFSpell *spell, SpellTag tag)
52{
53 uint16_t current_tags = spell->spell_tags;
54 spell->spell_tags = current_tags | tag;
55}
56
57void __thiscall linkTypeHandler(SFSpell *spell, handler_ptr typeHandler)
58{
59 spell->spell_type_handler = typeHandler;
60}
61
62void __thiscall linkSingleTargetAIHandler(SFSpell *spell,
64{
65 spell->ai_single_handler = handler;
66}
67
68void __thiscall linkAvoidanceAIHandler(SFSpell *spell,
70{
71 spell->ai_avoidance_handler = handler;
72}
73
74void __thiscall linkAOEAIHandler(SFSpell *spell, ai_aoe_handler_ptr handler)
75{
76 spell->ai_aoe_handler = handler;
77}
78
79void __thiscall linkOnHitHandler(SFSpell *spell, onhit_handler_ptr onhitHandler,
80 OnHitPhase phase)
81{
82 spell->spell_onhit_handler = onhitHandler;
83 spell->hit_phase = phase;
84}
85
86void __thiscall linkEffectHandler(SFSpell *spell, uint16_t spell_effect_id,
87 handler_ptr effectHandler)
88{
89 spell->spell_effect_id = spell_effect_id;
90 spell->spell_effect_handler = effectHandler;
91}
92
93void __thiscall linkEndHandler(SFSpell *spell, handler_ptr endHandler)
94{
95 spell->spell_end_handler = endHandler;
96}
97
98void __thiscall linkSubEffectHandler(SFSpell *spell,
100{
101 spell->sub_effect_handler = handler;
102}
103
104void __thiscall linkRefreshHandler(SFSpell *spell, refresh_handler_ptr handler)
105{
106 spell->spell_refresh_handler = handler;
107}
108
109void __thiscall linkDealDamageHandler(SFSpell *spell,
110 damage_handler_ptr handler,
111 SpellDamagePhase phase)
112{
113 spell->deal_damage_handler = handler;
114 spell->damage_phase = phase;
115}
116
117uint16_t __thiscall getSpellTags(uint16_t spell_line_id)
118{
119 for (auto &entry : g_internal_spell_list)
120 {
121 if (entry->spell_id == spell_line_id)
122 {
123 return entry->spell_tags;
124 }
125 }
126 return 0x0;
127}
128
144{
145 // Basic Conflict Checking
146 std::map<uint16_t, SFMod *> spell_id_map;
147 std::map<uint16_t, SFMod *> spell_effect_id_map;
148
149 SFMod *temp = g_current_mod;
150 uint8_t spell_count_for_mod = 0;
151 for (SFSpell *spell_data : g_internal_spell_list)
152 {
153 uint16_t spell_id = spell_data->spell_id;
154 uint16_t spell_effect_id = spell_data->spell_effect_id;
155 handler_ptr spell_type_handler = spell_data->spell_type_handler;
156 handler_ptr spell_effect_handler = spell_data->spell_effect_handler;
157 handler_ptr spell_end_handler = spell_data->spell_end_handler;
158 refresh_handler_ptr spell_refresh_handler =
159 spell_data->spell_refresh_handler;
160 sub_effect_handler_ptr sub_effect_handler =
161 spell_data->sub_effect_handler;
162 onhit_handler_ptr onhit_handler = spell_data->spell_onhit_handler;
163 damage_handler_ptr deal_damage_handler =
164 spell_data->deal_damage_handler;
165 ai_aoe_handler_ptr ai_aoe_handler = spell_data->ai_aoe_handler;
166 ai_avoidance_handler_ptr ai_avoidance_handler =
167 spell_data->ai_avoidance_handler;
168 ai_single_handler_ptr ai_single_handler = spell_data->ai_single_handler;
169
170 SpellDamagePhase damage_phase = spell_data->damage_phase;
171 OnHitPhase onhit_phase = spell_data->hit_phase;
172 SFMod *parent_mod = spell_data->parent_mod;
173 g_current_mod = spell_data->parent_mod;
174
175 if (temp != g_current_mod)
176 {
177 if (spell_count_for_mod != 0)
178 {
179 char spell_count_info[256];
180 snprintf(spell_count_info, sizeof(spell_count_info),
181 "| - Finished Registration of %d spells for %s",
182 spell_count_for_mod, temp->mod_id);
183 log_info(spell_count_info);
184 spell_count_for_mod = 0;
185 }
186
187 char info[256];
188 snprintf(info, sizeof(info),
189 "| - Starting Registration for [%s by %s]",
190 parent_mod->mod_id, parent_mod->mod_author);
191 parent_mod->mod_errors[0] = '\0';
192 log_info(info);
193 temp = g_current_mod;
194 }
195 else
196 {
197 spell_count_for_mod = spell_count_for_mod + 1;
198 }
199
200 // Check for conflicts
201 if (spell_id_map.find(spell_id) != spell_id_map.end())
202 {
203 char error_msg[256];
204 SFMod *conflict_mod = spell_id_map[spell_id];
205 if (spell_id < 242)
206 {
207 snprintf(error_msg, sizeof(error_msg),
208 "| - %s has Overwritten a vanilla spell ID [%d], this was previously registered by [%s]",
209 parent_mod->mod_id, spell_id, conflict_mod->mod_id);
210 log_warning(error_msg);
211 }
212 else
213 {
214 snprintf(error_msg, sizeof(error_msg),
215 "| - Mod Conflict Detected [%s]: Spell ID [%d] is already registered by [%s]",
216 parent_mod->mod_id, spell_id, conflict_mod->mod_id);
217 log_error(error_msg);
218 snprintf(conflict_mod->mod_errors,
219 sizeof(parent_mod->mod_errors),
220 "%sSpell ID [%d] was overwritten by %s\n",
221 conflict_mod->mod_errors, spell_id,
222 parent_mod->mod_id);
224 }
225 }
226
227 if (spell_effect_id_map.find(spell_effect_id) !=
228 spell_effect_id_map.end())
229 {
230 char error_msg[256];
231 SFMod *conflict_mod = spell_effect_id_map[spell_effect_id];
232 if (spell_effect_id < 0xa6)
233 {
234 snprintf(error_msg, sizeof(error_msg),
235 "| - %s has Overwritten a vanilla spell effect ID [%d] this was previously registered by [%s]",
236 parent_mod->mod_id, spell_effect_id,
237 conflict_mod->mod_id);
238 log_warning(error_msg);
239 }
240 else
241 {
242 snprintf(error_msg, sizeof(error_msg),
243 "| - Mod Conflict Detected [%s]: Spell Effect ID [%d] is already registered by [%s]",
244 parent_mod->mod_id, spell_effect_id,
245 conflict_mod->mod_id);
246 log_error(error_msg);
247
248 snprintf(conflict_mod->mod_errors,
249 sizeof(parent_mod->mod_errors),
250 "%sSpell Effect ID [%d] was overwritten by %s\n",
251 conflict_mod->mod_errors, spell_effect_id,
252 parent_mod->mod_id);
253
255 }
256 }
257
258 // Update Conflict Maps
259 spell_id_map[spell_id] = parent_mod;
260
261 if (spell_effect_id != 0x00)
262 {
263 spell_effect_id_map[spell_effect_id] = parent_mod;
264 }
265
266 // Do Registration
267 if (spell_type_handler != nullptr)
268 {
269 registerSpellTypeHandler(spell_id, spell_type_handler);
270 }
271
272 if (spell_effect_handler != nullptr)
273 {
274 registerEffectHandler(spell_effect_id, spell_effect_handler);
275 }
276
277 if (spell_refresh_handler != nullptr)
278 {
279 registerSpellRefreshHandler(spell_id, spell_refresh_handler);
280 }
281
282 if (spell_end_handler != nullptr)
283 {
284 registerSpellEndHandler(spell_id, spell_end_handler);
285 }
286
287 if (sub_effect_handler != nullptr)
288 {
289 registerSubEffectHandler(spell_id, sub_effect_handler);
290 }
291
292 if (onhit_handler != nullptr)
293 {
294 registerOnHitHandler(spell_id, onhit_handler, onhit_phase);
295 }
296
297 if (deal_damage_handler != nullptr)
298 {
299 registerSpellDamageHandler(spell_id, deal_damage_handler,
300 damage_phase);
301 }
302
303 if(ai_single_handler != nullptr)
304 {
305 registerAiSingleTargetHandler(spell_id, ai_single_handler);
306 }
307
308 if(ai_aoe_handler != nullptr)
309 {
310 registerAiAOEHandler(spell_id, ai_aoe_handler);
311 }
312
313 if(ai_avoidance_handler != nullptr)
314 {
315 registerAiAvoidanceHandler(spell_id, ai_avoidance_handler);
316 }
317 }
318
319 if (spell_count_for_mod != 0)
320 {
321 char spell_count_info[256];
322 snprintf(spell_count_info, sizeof(spell_count_info),
323 "| - Finished Registration of %d spells for %s",
324 spell_count_for_mod, temp->mod_id);
325 log_info(spell_count_info);
326 spell_count_for_mod = 0;
327 }
328}
void log_info(const char *message)
Definition sf_wrappers.c:89
void log_warning(const char *message)
Definition sf_wrappers.c:81
void log_error(const char *message)
Definition sf_wrappers.c:97
void registerAiAOEHandler(uint16_t spell_line, ai_aoe_handler_ptr handler)
void registerAiAvoidanceHandler(uint16_t spell_line, ai_avoidance_handler_ptr handler)
void registerAiSingleTargetHandler(uint16_t spell_line, ai_single_handler_ptr handler)
void(__thiscall * sub_effect_handler_ptr)(SF_CGDEffect *, uint16_t effect_index)
void __thiscall linkAOEAIHandler(SFSpell *spell, ai_aoe_handler_ptr handler)
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)
void __thiscall linkOnHitHandler(SFSpell *spell, onhit_handler_ptr onhitHandler, OnHitPhase phase)
void __thiscall linkRefreshHandler(SFSpell *spell, refresh_handler_ptr handler)
std::list< SFSpell * > g_internal_spell_list
void __thiscall linkEffectHandler(SFSpell *spell, uint16_t spell_effect_id, handler_ptr effectHandler)
void __thiscall linkSingleTargetAIHandler(SFSpell *spell, ai_single_handler_ptr handler)
void register_mod_spells()
Registers the mod spells and performs basic conflict checking.
void __thiscall linkAvoidanceAIHandler(SFSpell *spell, ai_avoidance_handler_ptr handler)
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)
int g_error_count
SFMod * g_current_mod
void registerOnHitHandler(uint16_t spell_line_id, onhit_handler_ptr handler, OnHitPhase phase)
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)
int(__thiscall * refresh_handler_ptr)(SF_CGdSpell *, uint16_t)
uint32_t(__thiscall * ai_single_handler_ptr)(SF_CGdBattleDevelopment *_this, uint16_t target_index, uint16_t spell_line, SF_CGdResourceSpell *spell_data)
uint32_t(__thiscall * ai_aoe_handler_ptr)(SF_CGdBattleDevelopment *_this, SF_Coord *position, uint16_t spell_line, SF_CGdResourceSpell *spell_data)
void(__thiscall * handler_ptr)(SF_CGdSpell *, uint16_t)
uint32_t(__thiscall * ai_avoidance_handler_ptr)(CGdAIBattleData *_this, uint16_t figure_index, uint16_t spell_line)
uint16_t(__thiscall * onhit_handler_ptr)(SF_CGdFigureJobs *, uint16_t source, uint16_t target, uint16_t damage)
void registerSpellDamageHandler(uint16_t spell_line_id, damage_handler_ptr handler, SpellDamagePhase phase)
void registerEffectHandler(uint16_t spell_job, handler_ptr handler)
void registerSpellEndHandler(uint16_t spell_line, handler_ptr handler)
void registerSpellRefreshHandler(uint16_t spell_line_id, refresh_handler_ptr handler)
void registerSpellTypeHandler(uint16_t spell_index, handler_ptr handler)
void registerSubEffectHandler(uint16_t spell_line, sub_effect_handler_ptr handler)
char mod_id[64]
char mod_errors[256]
char mod_author[128]
handler_ptr spell_effect_handler
ai_avoidance_handler_ptr ai_avoidance_handler
damage_handler_ptr deal_damage_handler
ai_single_handler_ptr ai_single_handler
SpellDamagePhase damage_phase
refresh_handler_ptr spell_refresh_handler
handler_ptr spell_end_handler
sub_effect_handler_ptr sub_effect_handler
onhit_handler_ptr spell_onhit_handler
ai_aoe_handler_ptr ai_aoe_handler
handler_ptr spell_type_handler