Spellforce-Spell-framework
Loading...
Searching...
No Matches
sf_wrappers.c
Go to the documentation of this file.
1#include <windows.h>
2#include <stdio.h>
3#include <stdlib.h>
4#include <string.h>
5
6#include "sf_wrappers.h"
7#include "sf_hooks.h"
8
12
45
70
71void log_message(const char *filename, const char *message)
72{
73 FILE *file = fopen(filename, "a");
74 if (file != NULL)
75 {
76 fprintf(file, "%s\n", message);
77 fclose(file);
78 }
79}
80
81void log_warning(const char *message)
82{
83 // Logs a warning message to the console and the debug output
84 static char modifiedMessage[256];
85 snprintf(modifiedMessage, sizeof(modifiedMessage), "[WARNING] %s", message);
86 console_log(modifiedMessage);
87}
88
89void log_info(const char *message)
90{
91 // Logs an informational message to the console and the debug output
92 static char modifiedMessage[256];
93 snprintf(modifiedMessage, sizeof(modifiedMessage), "[SFSF] %s", message);
94 console_log(modifiedMessage);
95}
96
97void log_error(const char *message)
98{
99 // Logs an error message to the console and the debug output, including the last error code
100 int lastError = GetLastError();
101 static char modifiedMessage[256];
102 snprintf(modifiedMessage, sizeof(modifiedMessage),
103 "[ERROR] %s [(Win32 SysErr) Last Error: %d]", message, lastError);
104 console_log(modifiedMessage);
105}
106
115
116// TODO: Parse me through an as an ActionAPI Wrapped Function
117bool __thiscall isActionMelee(SF_SGtFigureAction *_this)
118{
119 if ((_this->type == 10000) || (_this->type == 0x2711))
120 {
121 return 1;
122 }
123 return 0;
124}
125
126void __thiscall setupFigureIterator(CGdFigureIterator *iterator,
127 SF_CGdSpell *spell)
128{
129 iteratorAPI.figureIteratorInit(iterator, 0x0, 0x0, 0x3ff, 0x3ff);
131 spell->unkn3, spell->SF_CGdWorld);
132}
133
134bool __thiscall hasSpellTag(uint16_t spell_id, SpellTag tag)
135{
136 return spellAPI.getSpellTags(spell_id) & tag;
137}
138
139uint32_t getDistance(SF_Coord *pointA, SF_Coord *pointB)
140{
141
142 uint32_t delta;
143 uint32_t uVar1;
144 uint32_t uVar2;
145 uint32_t uVar3;
146 uint32_t uVar4;
147
148 delta = (uint32_t)(uint16_t)pointA->X - (uint32_t)(uint16_t)pointB->X;
149 uVar2 = (int)delta >> 0x1f;
150 uVar2 = (delta ^ uVar2) - uVar2;
151 uVar4 = uVar2 & 0xffff;
152 delta = (uint32_t)(uint16_t)pointA->Y - (uint32_t)(uint16_t)pointB->Y;
153 uVar3 = (int)delta >> 0x1f;
154 uVar3 = (delta ^ uVar3) - uVar3;
155 uVar1 = uVar3 & 0xffff;
156 delta = uVar1;
157 if ((uint16_t)uVar2 < (uint16_t)uVar3)
158 {
159 delta = uVar4;
160 uVar4 = uVar1;
161 }
162 return ((delta * 0xd) >> 5) + uVar4;
163}
164
165// Some funky stuff to clean up Iterator memory, not 100% sure if correct
166void __thiscall disposeFigureIterator(CGdFigureIterator *iterator)
167{
168 uint32_t unused;
169 FUN_0069eaf0(&(iterator->data.offset_0x30), &unused,
170 ((AutoClass69 *)iterator->data.offset_0x30.ac69_ptr1)->
171 ac69_ptr1, iterator->data.offset_0x30.ac69_ptr1);
173}
174
175void __thiscall spellEffectCallback(SF_CGdSpell *_this, uint16_t source_index,
176 uint16_t spell_index,
177 bool (*condition)(SF_CGdSpell *_this,
178 uint16_t source_index,
179 uint16_t spell_index),
180 void (*callback)(SF_CGdSpell *_this,
181 uint16_t source_index,
182 uint16_t spell_index))
183{
184 if (!condition || !callback)
185 return;
186
187 uint16_t node_id = figureAPI.getSpellJobStartNode(_this->SF_CGdFigure,
188 source_index);
189 while (node_id != 0)
190 {
191 uint16_t current_index =
193 (uint32_t *)_this->SF_CGdDoubleLinkedList, node_id);
194 if ((*condition)(_this, current_index, spell_index))
195 {
196 (*callback)(_this, source_index, current_index);
197 break;
198 }
199 node_id =
201 node_id);
202 }
203}
204
205void __thiscall addBonusMultToStatistic(SF_CGdFigure *figure,
206 StatisticDataKey key, uint16_t target,
207 int8_t value)
208{
209 bool invalid = FALSE;
210 FigureStatistic *statistic;
211 switch (key)
212 {
213 case ARMOR:
214 {
215 statistic = &(figure->figures[target].armor);
216 break;
217 }
218 case AGILITY:
219 {
220 statistic = &(figure->figures[target].agility);
221 break;
222 }
223 case CHARISMA:
224 {
225 statistic = &(figure->figures[target].charisma);
226 break;
227 }
228 case DEXTERITY:
229 {
230 statistic = &(figure->figures[target].dexterity);
231 break;
232 }
233 case INTELLIGENCE:
234 {
235 statistic = &(figure->figures[target].intelligence);
236 break;
237 }
238 case STRENGTH:
239 {
240 statistic = &(figure->figures[target].strength);
241 break;
242 }
243 case WISDOM:
244 {
245 statistic = &(figure->figures[target].wisdom);
246 break;
247 }
248 case RESISTANCE_FIRE:
249 {
250 statistic = &(figure->figures[target].resistance_fire);
251 break;
252 }
253 case RESISTANCE_ICE:
254 {
255 statistic = &(figure->figures[target].resistance_ice);
256 break;
257 }
259 {
260 statistic = &(figure->figures[target].resistance_mental);
261 break;
262 }
263 case RESISTANCE_BLACK:
264 {
265 statistic = &(figure->figures[target].resistance_black);
266 break;
267 }
268 case WALK_SPEED:
269 {
270 statistic = &(figure->figures[target].walk_speed);
271 break;
272 }
273 case FIGHT_SPEED:
274 {
275 statistic = &(figure->figures[target].fight_speed);
276 break;
277 }
278 case CAST_SPEED:
279 {
280 statistic = &(figure->figures[target].cast_speed);
281 break;
282 }
283 default:
284 {
285 invalid = TRUE;
286 break;
287 }
288 }
289
290 if (invalid)
291 {
292 log_warning("INVALID STATISTIC KEY");
293 return;
294 }
295
296 figureAPI.addBonusMult(statistic, value);
297}
298
299void __thiscall spellClearFigureFlag(SF_CGdSpell *_this, uint16_t spell_id,
300 SpellFlagKey key)
301{
302 switch (key)
303 {
305 {
306 spellAPI.figClrChkSplBfrChkBattle(_this, spell_id, 0);
307 break;
308 }
310 {
311 spellAPI.figTryClrCHkSPlBfrJob2(_this, spell_id);
312 break;
313 }
314 case UNFREEZE:
315 {
316 spellAPI.figTryUnfreeze(_this, spell_id, 0);
317 break;
318 }
319 }
320}
321
322bool __thiscall hasAuraActive(SF_CGdFigureToolbox *_this, uint16_t figure_id)
323{
324 return has_spell_effect(_this, figure_id, 0x49);
325}
326
327CMnuLabel * __thiscall attach_new_label(CMnuLabel *label_ptr,
328 CMnuContainer *parent,
329 char *label_chars, uint8_t font_index,
330 uint16_t x_pos, uint16_t y_pos,
331 uint16_t width, uint16_t height)
332{
333 char empty[1];
334 sprintf(empty, "");
335 return attach_new_meshed_label(label_ptr, parent, empty, label_chars,
336 font_index, x_pos, y_pos, width, height);
337}
338
339void wrap_text(const char *input, char *output, size_t max_width)
340{
341 size_t input_len = strlen(input);
342 size_t current_line_width = 0;
343 size_t output_index = 0;
344
345 for (size_t i = 0; i < input_len; ++i)
346 {
347 output[output_index++] = input[i];
348 current_line_width++;
349
350 if (current_line_width >= max_width)
351 {
352 size_t break_point = output_index;
353 while (break_point > 0 && !isspace(output[break_point - 1]))
354 {
355 break_point--;
356 }
357
358 if (break_point > 0)
359 {
360 output[break_point - 1] = '\n';
361 current_line_width = output_index - break_point;
362 }
363 else
364 {
365 output[output_index++] = '\n';
366 current_line_width = 0;
367 }
368 }
369 }
370
371 output[output_index] = '\0';
372}
373
374static bool is_init_finished = false;
375
382static void update_label_text(CMnuLabel *label, const char *text)
383{
384 if (!label || !text)
385 {
386 return;
387 }
388
389 SF_String string_obj;
390 SF_String *sf_string = g_create_sf_string(&string_obj, text);
391 g_menu_label_set_string(label, sf_string);
392 g_destroy_sf_string(sf_string);
393}
394
402void attach_mod_labels(CMnuContainer *container, int mods_per_page, int page)
403{
404 if (g_internal_spell_list.empty())
405 {
406 return; // Early return if no mods to display
407 }
408
409 // Calculate pagination values
410 const int start_index = mods_per_page * page;
411 const int end_index = start_index + mods_per_page;
412 const int y_base_offset = 48;
413 const int y_item_spacing = 36;
414
415 SFMod *current_parent = nullptr;
416 int mod_index = 0;
417
418 // Iterate through spell list to find unique parent mods
419 for (const SFSpell *spell_data : g_internal_spell_list)
420 {
421 SFMod *parent_mod = spell_data->parent_mod;
422
423 // Only process each mod once
424 if (current_parent != parent_mod)
425 {
426 // Check if this mod should be displayed on the current page
427 if (mod_index >= start_index && mod_index < end_index)
428 {
429 const int relative_y_pos = (mod_index - start_index) *
430 y_item_spacing;
431 const int absolute_y_pos = y_base_offset + relative_y_pos;
432
433 // Prepare mod information strings
434 char mod_title[512] = {0};
435 snprintf(mod_title, sizeof(mod_title), "%s %s\nby %s",
436 parent_mod->mod_id,
437 parent_mod->mod_version,
438 parent_mod->mod_author);
439
440 char mod_description[512] = {0};
441 snprintf(mod_description, sizeof(mod_description), "%s",
442 parent_mod->mod_description);
443
444 char wrapped_description[1024] = {0};
445 wrap_text(mod_description, wrapped_description, 64);
446
447 char mod_page_info[48] = {0};
448 snprintf(mod_page_info, sizeof(mod_page_info), "(%u / %u)",
449 (mod_index + 1), (g_mod_count + 1));
450
451 char mod_error_info[512] = {0};
452 if (parent_mod->mod_errors && parent_mod->mod_errors[0] != '\0')
453 {
454 snprintf(mod_error_info, sizeof(mod_error_info), "%s",
455 parent_mod->mod_errors);
456 }
457 else
458 {
459 snprintf(mod_error_info, sizeof(mod_error_info),
460 "No errors found");
461 }
462
463 char wrapped_error_info[1024] = {0};
464 wrap_text(mod_error_info, wrapped_error_info, 64);
465
466 // Update or create labels
467 if (is_init_finished)
468 {
469 // Update existing labels
470 update_label_text(mod_struct.title_label, mod_title);
471 update_label_text(mod_struct.desc_label,
472 wrapped_description);
473 update_label_text(mod_struct.page_label, mod_page_info);
474 update_label_text(mod_struct.error_label,
475 wrapped_error_info);
476 }
477 else
478 {
479 // Create new labels
481 attach_new_label(nullptr, container, mod_title,
482 6, 100, absolute_y_pos - 32, 50,
483 y_item_spacing);
484
486 attach_new_label(nullptr, container,
487 wrapped_description,
488 11, 48, absolute_y_pos + 24,
489 227, y_item_spacing);
490
492 attach_new_label(nullptr, container, mod_page_info,
493 6, 92, 382, 50, y_item_spacing);
494
496 attach_new_label(nullptr, container, wrapped_error_info,
497 11, 48, absolute_y_pos + 224,
498 227, y_item_spacing);
499
500 // Set label colors
502 '\0');
503 set_label_color(mod_struct.title_label, 0.85, 0.64, 0.12,
504 '\0');
505 set_label_color(mod_struct.title_label, 0.85, 0.64, 0.12,
506 '\x01');
507
508 is_init_finished = true;
509 }
510 }
511
512 current_parent = parent_mod;
513 mod_index++;
514 }
515 }
516}
517
518void __fastcall navigate_callback_left(CMnuSmpButton *button,
519 int32_t *cui_menu_ptr_maybe)
520{
521 CMnuContainer *parent =
523 uint8_t index = mod_struct.index;
524
525 if((index - 1) < 0)
526 {
528 index = g_mod_count;
529 }
530 else
531 {
532 index = index - 1;
533 }
534 attach_mod_labels(parent, 1, index);
535 mod_struct.index = index;
536}
537
539 int32_t *cui_menu_ptr_maybe)
540{
541 CMnuContainer *parent =
543 uint8_t index = mod_struct.index;
544
545 index = index + 1;
546 if(index > g_mod_count)
547 {
548 mod_struct.index = 0;
549 index = 0;
550 }
551 attach_mod_labels(parent, 1, index);
552 mod_struct.index = index;
553}
554
557static bool is_mod_list_shown = false;
558static bool does_mod_list_exist = false;
559
560void __thiscall show_mod_list(CMnuSmpButton *button)
561{
562 CMnuContainer *parent =
564
565
566 if(!does_mod_list_exist)
567 {
568 is_mod_list_shown = true;
569 SF_String s_menu_border, s_menu_background, s_alt_btn_name;
570 SF_String *p_menu_border, *p_menu_background, *p_alt_btn_name;
571
572 char alt_name[32] = "HIDE MOD LIST";
573 p_alt_btn_name = g_create_sf_string(&s_alt_btn_name, alt_name);
574
575 set_button_name(button, p_alt_btn_name);
576
577 g_destroy_sf_string(p_alt_btn_name);
580
581 // Setup mesh loading for background of the container.
582 char menu_border[128] = "ui_bgr_options_select_border.msb";
583 char menu_background_fade[128] =
584 "ui_bgr_options_select_border_transparency.msb";
585 p_menu_border = g_create_sf_string(&s_menu_border, menu_border);
586 p_menu_background = g_create_sf_string(&s_menu_background,
587 menu_background_fade);
588
589 setup_menu_container_data(mod_list, 500, 124, 432, 432,
590 p_menu_background, p_menu_border);
591
593
594 g_destroy_sf_string(p_menu_background);
595 g_destroy_sf_string(p_menu_border);
596
597 // Add new container to this container.
598 g_container_add_control(parent, (CMnuBase *)mod_list, '\x01', '\x01',
599 0);
600
601 char btn_disabled[128]= "ui_btn_togglearrow_right_disabled.msh";
602 char btn_pressed[128] = "ui_btn_togglearrow_right_pressed.msh";
603 char btn_load[1] = "";
604 char btn_default[128] = "ui_btn_togglearrow_right_default.msh";
605 char btn_label[1] = "";
606
607 attach_new_button(mod_list, btn_default, btn_pressed, btn_load,
608 btn_disabled, btn_label, 7, (432 - (48 + 32)), 332,
609 48, 48, 0, (uint32_t) &navigate_callback_right);
610
611 char btn_disabled_left[128] = "ui_btn_togglearrow_left_disabled.msh";
612 char btn_pressed_left[128] = "ui_btn_togglearrow_left_pressed.msh";
613 char btn_default_left[128] = "ui_btn_togglearrow_left_default.msh";
614
615 attach_new_button(mod_list, btn_default_left, btn_pressed_left,
616 btn_load, btn_disabled_left, btn_label, 7, 28, 332,
617 48, 48, 1, (uint32_t) &navigate_callback_left);
618
620 does_mod_list_exist = true;
621 }
622 else
623 {
624 if(is_mod_list_shown)
625 {
626 log_info("Hide Mod List");
627 char alt_name[32] = "SHOW MOD LIST";
628 SF_String s_alt_btn_name;
629 SF_String *p_alt_btn_name;
630 p_alt_btn_name = g_create_sf_string(&s_alt_btn_name, alt_name);
631
632 set_button_name(button, p_alt_btn_name);
633 g_destroy_sf_string(p_alt_btn_name);
634
636 is_mod_list_shown = false;
637 }
638 else
639 {
640 log_info("Show Mod List");
641 char alt_name[32] = "HIDE MOD LIST";
642 SF_String s_alt_btn_name;
643 SF_String *p_alt_btn_name;
644 p_alt_btn_name = g_create_sf_string(&s_alt_btn_name, alt_name);
645
646 set_button_name(button, p_alt_btn_name);
647 g_destroy_sf_string(p_alt_btn_name);
648
650 is_mod_list_shown = true;
651 }
652 }
653}
654
655void __fastcall show_mod_list_callback(CMnuSmpButton *button,
656 int32_t *cui_menu_ptr_maybe)
657{
658 CMnuContainer *parent =
660 uint8_t toggle = mod_struct.toggle;
661
662 show_mod_list(button);
663}
664
665
666void __thiscall attach_new_button(CMnuContainer *parent,
667 char *button_mesh_default,
668 char *button_mesh_pressed,
669 char *button_initial_load_mesh,
670 char *button_mesh_disabled, char *label_char,
671 uint8_t font_index, uint16_t x_pos,
672 uint16_t y_pos, uint16_t width,
673 uint16_t height, int button_index,
674 uint32_t callback_func_ptr)
675{
676 SF_String m_mesh_string_default;
677 SF_String m_mesh_string_pressed;
678 SF_String m_button_initial_load_mesh;
679 SF_String m_mesh_string_disabled;
680
681 SF_String m_label_string;
682 CMnuSmpButton *new_button;
683 void *new_btn_operation;
684
686 SF_String *label_string = g_create_sf_string(&m_label_string, label_char);
687
688 // Default
689 SF_String *mesh_string_default = g_create_sf_string(&m_mesh_string_default,
690 button_mesh_default);
691
692 // Pressed
693 SF_String *mesh_string_pressed = g_create_sf_string(&m_mesh_string_pressed,
694 button_mesh_pressed);
695
696 // Highlight
697 SF_String *init_load_mesh = g_create_sf_string(&m_button_initial_load_mesh,
698 button_initial_load_mesh);
699
700 // Disabled
701 SF_String *mesh_string_disabled =
702 g_create_sf_string(&m_mesh_string_disabled, button_mesh_disabled);
703
704 // 0x3b0 seems to corralate to CUiStartMenu, but is directly cast to be a type of CUiFrameStats
705 new_button = (CMnuSmpButton *)g_new_operator(0x428); // 0x368, 0x3b0 and 0x708 are all valid. (I suspect that they're creating objects that have CMnuLabel as an Parent Class).
706
707 if (font_index > 32)
708 {
709 log_error("Invalid font index 0~32, defaulting to font 6");
710 font_index = 6;
711 }
712
713 new_button = initialize_smp_button(new_button);
714 SF_Font *selected_font = g_get_font(fonts, font_index);
715
716 CMnuBase_setname((CMnuBase *)new_button, label_string);
717
718 // This seems to fill out the actual button data itself.
719 create_button_func(new_button,x_pos,y_pos,width,height,mesh_string_default,
720 init_load_mesh,mesh_string_pressed,mesh_string_disabled);
721
722 set_font(new_button, selected_font);
723
724 set_button_index(new_button, button_index);
725
726 set_menu_button_flag(new_button, '\x01');
727
728 set_button_name(new_button, label_string);
729
730 CUtlCallback2 callback;
731 callback.vtable_ptr = *(uint32_t *)(ASI::AddrOf(0x7F9C64));
732 callback.param_ptr = (uint32_t) parent;
733 callback.callback_func = callback_func_ptr;
734
735 uint32_t param1, param2, param3;
736
737 attach_callback(&callback, &param1, &param2, &param3);
738
739 new_button->CMnuBase_data.param_1_callback = param1;
740 new_button->CMnuBase_data.param_2_callback = param2;
741 new_button->CMnuBase_data.param_3_callback = param3;
742
743 vfunction16_attach_callback(new_button, '\x01');
744
745 g_container_add_control(parent, (CMnuBase *)new_button, '\x01', '\x01', 0);
746
747 g_destroy_sf_string(mesh_string_default);
748 g_destroy_sf_string(mesh_string_pressed);
749 g_destroy_sf_string(init_load_mesh);
750 g_destroy_sf_string(mesh_string_disabled);
751 g_destroy_sf_string(label_string);
752}
753
755 CMnuContainer *parent,
756 char *mesh_char,
757 char *label_char,
758 uint8_t font_index,
759 uint16_t x_pos, uint16_t y_pos,
760 uint16_t width, uint16_t height)
761{
762 SF_String m_mesh_string;
763 SF_String m_label_string;
764
766 SF_String *label_string = g_create_sf_string(&m_label_string, label_char);
767 SF_String *mesh_string = g_create_sf_string(&m_mesh_string, mesh_char);
768
769 new_label = (CMnuLabel *)g_new_operator(0x3b0);
770
771 if (font_index > 32)
772 {
773 log_error("Invalid font index 0~32, defaulting to font 6");
774 font_index = 6;
775 }
776
777 SF_Font *selected_font = g_get_font(fonts, font_index);
778
779 g_menu_label_constructor(new_label);
780
781 g_set_label_flags(new_label, 7);
782
783 g_init_menu_element(new_label, x_pos, y_pos, width, height, mesh_string);
784
785 g_menu_label_set_font(new_label, selected_font);
786
787 g_container_add_control(parent, (CMnuBase *) new_label, '\x01', '\x01', 0);
788
789 g_menu_label_set_string(new_label, label_string);
790
791 g_destroy_sf_string(label_string);
792 g_destroy_sf_string(mesh_string);
793
794 return new_label;
795}
796
797uint16_t __thiscall sf_get_spell_id(SF_CGdSpell *_this, uint16_t spell_index)
798{
799 return _this->active_spell_list[spell_index].spell_id;
800}
801
802SFMod *createModInfo(const char *mod_id, const char *mod_version,
803 const char *mod_author, const char *mod_description)
804{
805 SFMod *mod = (SFMod *)malloc(sizeof(SFMod));
806
807 strncpy(mod->mod_id, mod_id, 63);
808 mod->mod_id[63] = '\0';
809
810 strncpy(mod->mod_version, mod_version, 23);
811 mod->mod_version[23] = '\0';
812
813 strncpy(mod->mod_description, mod_description, 127);
814 mod->mod_description[127] = '\0';
815
816 strncpy(mod->mod_author, mod_author, 127);
817 mod->mod_author[127] = '\0';
818
819 return mod;
820}
821
822// WARNING: Function not fully implemented.
823// This function successfully loads a video, but the video container is attached to a layer above the default container.
824// As a result, the video container intercepts click events and prevents proper interaction with the underlying elements.
825void attachVideo(CAppMenu *CAppMenu_ptr, CMnuContainer *parent,
826 char *video_loc_and_name_chars)
827{
828 SF_CUiVideo *video_ptr = (SF_CUiVideo *) g_new_operator(0x348);
829 SF_String m_video_name_string;
830 SF_String *video_name_string = g_create_sf_string(&m_video_name_string,
831 video_loc_and_name_chars);
832 // TODO Cleanup: Not Sequence, just normal Video, haven't renamed it from previous investigations.
833 video_ptr =(SF_CUiVideo *) cuiVideoSequence_constructor(video_ptr,
834 video_name_string);
835
836 char controller_mark_chars[64];
837 sprintf(controller_mark_chars, "<Cont>CreditsVideoController");
838 SF_String m_controller_mark_string;
839 SF_String *controller_mark_string =
840 g_create_sf_string(&m_controller_mark_string, controller_mark_chars);
841 CMnuBase_setname((CMnuBase *)video_ptr, controller_mark_string);
842
843 //void *_CMnuScreen_ptr, CMnuBase* base, char flag
844 //CMnuScreen_attach_control(parent, CAppMenu_ptr->CAppMenu_data.CMnuBase_ptr, '\x01');
845}
846
SpellFunctions * spellAPI
Definition TestMod.cpp:11
FigureFunctions * figureAPI
Definition TestMod.cpp:13
ToolboxFunctions * toolboxAPI
Definition TestMod.cpp:12
void console_log(const char *message)
IteratorFunctions iteratorAPI
Definition sf_hooks.c:40
new_operator_ptr g_new_operator
get_smth_fonts_ptr g_get_smth_fonts
SFSF_ModlistStruct mod_struct
cuiVideoSequence_constructor_ptr cuiVideoSequence_constructor
get_font_ptr g_get_font
menu_label_set_font_ptr g_menu_label_set_font
mnu_label_init_data_ptr g_init_menu_element
menu_label_set_string_ptr g_menu_label_set_string
menu_label_constructor_ptr g_menu_label_constructor
container_add_control_ptr g_container_add_control
set_label_flags_ptr g_set_label_flags
void __thiscall addBonusMultToStatistic(SF_CGdFigure *figure, StatisticDataKey key, uint16_t target, int8_t value)
initialize_menu_container_ptr initialize_menu_container
Definition sf_wrappers.c:35
CMnuLabel *__thiscall attach_new_label(CMnuLabel *label_ptr, CMnuContainer *parent, char *label_chars, uint8_t font_index, uint16_t x_pos, uint16_t y_pos, uint16_t width, uint16_t height)
void __thiscall attach_new_button(CMnuContainer *parent, char *button_mesh_default, char *button_mesh_pressed, char *button_initial_load_mesh, char *button_mesh_disabled, char *label_char, uint8_t font_index, uint16_t x_pos, uint16_t y_pos, uint16_t width, uint16_t height, int button_index, uint32_t callback_func_ptr)
uint32_t getDistance(SF_Coord *pointA, SF_Coord *pointB)
void __thiscall spellEffectCallback(SF_CGdSpell *_this, uint16_t source_index, uint16_t spell_index, bool(*condition)(SF_CGdSpell *_this, uint16_t source_index, uint16_t spell_index), void(*callback)(SF_CGdSpell *_this, uint16_t source_index, uint16_t spell_index))
void __thiscall show_mod_list(CMnuSmpButton *button)
CMnuBase_setname_ptr CMnuBase_setname
Definition sf_wrappers.c:44
void log_info(const char *message)
Definition sf_wrappers.c:89
SFSF_ModlistStruct modinformation
container_alpha_ptr set_container_alpha
Definition sf_wrappers.c:37
void wrap_text(const char *input, char *output, size_t max_width)
SFLog sf_logger
void __thiscall setupFigureIterator(CGdFigureIterator *iterator, SF_CGdSpell *spell)
create_button_ptr create_button_func
Definition sf_wrappers.c:28
vfunction_ptr vfunction176
Definition sf_wrappers.c:30
vfunction_ptr vfunction16_attach_callback
Definition sf_wrappers.c:43
void log_warning(const char *message)
Definition sf_wrappers.c:81
has_spell_effect_ptr has_spell_effect
Definition sf_wrappers.c:27
vfunction2_callback_attach_ptr attach_callback
Definition sf_wrappers.c:42
initialize_smp_button_ptr initialize_smp_button
Definition sf_wrappers.c:33
void __fastcall navigate_callback_left(CMnuSmpButton *button, int32_t *cui_menu_ptr_maybe)
set_btn_name_ptr set_button_name
Definition sf_wrappers.c:34
set_label_color_ptr set_label_color
Definition sf_wrappers.c:36
set_button_flag_ptr set_menu_button_flag
Definition sf_wrappers.c:41
void log_error(const char *message)
Definition sf_wrappers.c:97
bool __thiscall hasSpellTag(uint16_t spell_id, SpellTag tag)
bool __thiscall hasAuraActive(SF_CGdFigureToolbox *_this, uint16_t figure_id)
void attachVideo(CAppMenu *CAppMenu_ptr, CMnuContainer *parent, char *video_loc_and_name_chars)
SF_String_ctor_ptr g_create_sf_string
Definition sf_wrappers.c:25
void __thiscall spellClearFigureFlag(SF_CGdSpell *_this, uint16_t spell_id, SpellFlagKey key)
void __thiscall disposeFigureIterator(CGdFigureIterator *iterator)
fidfree_ptr fidFree
Definition sf_wrappers.c:24
void attach_mod_labels(CMnuContainer *container, int mods_per_page, int page)
void __fastcall show_mod_list_callback(CMnuSmpButton *button, int32_t *cui_menu_ptr_maybe)
void log_message(const char *filename, const char *message)
Definition sf_wrappers.c:71
FUN_0069eaf0_ptr FUN_0069eaf0
Definition sf_wrappers.c:23
vfunction_2_ptr set_font
Definition sf_wrappers.c:39
SFLog * setup_logger()
void initialize_wrapper_data_hooks()
Definition sf_wrappers.c:46
SF_String_dtor_ptr g_destroy_sf_string
Definition sf_wrappers.c:26
CMnuLabel *__thiscall attach_new_meshed_label(CMnuLabel *new_label, CMnuContainer *parent, char *mesh_char, char *label_char, uint8_t font_index, uint16_t x_pos, uint16_t y_pos, uint16_t width, uint16_t height)
uint16_t __thiscall sf_get_spell_id(SF_CGdSpell *_this, uint16_t spell_index)
SFMod * createModInfo(const char *mod_id, const char *mod_version, const char *mod_author, const char *mod_description)
attach_string_ptr vfunction_apply_string
Definition sf_wrappers.c:29
set_btn_index_ptr set_button_index
Definition sf_wrappers.c:40
vfunction_ptr vfunction25
Definition sf_wrappers.c:31
bool __thiscall isActionMelee(SF_SGtFigureAction *_this)
void __fastcall navigate_callback_right(CMnuSmpButton *button, int32_t *cui_menu_ptr_maybe)
setup_menu_container_data_ptr setup_menu_container_data
Definition sf_wrappers.c:38
vfunction12_ptr vfunction12
Definition sf_wrappers.c:32
CMnuContainer * mod_list
int AddrOf(int offset)
returns "real" virtual address of given memory offset
Definition sf_asi.h:135
StatisticDataKey
@ DEXTERITY
@ AGILITY
@ RESISTANCE_ICE
@ CAST_SPEED
@ INTELLIGENCE
@ RESISTANCE_FIRE
@ RESISTANCE_MENTAL
@ RESISTANCE_BLACK
@ FIGHT_SPEED
@ WALK_SPEED
void(* fidfree_ptr)(uint32_t *memory_ptr)
void(__thiscall * initialize_menu_container_ptr)(CMnuContainer *_this)
uint32_t(__thiscall * FUN_0069eaf0_ptr)(void *ac69, void *ac69_2, void *ac69_3, void *ac69_4)
std::list< SFSpell * > g_internal_spell_list
int g_mod_count
SpellFlagKey
@ CHECK_SPELLS_BEFORE_JOB2
@ UNFREEZE
@ CHECK_SPELLS_BEFORE_CHECK_BATTLE
bool(__thiscall * has_spell_effect_ptr)(SF_CGdFigureToolbox *_this, uint16_t param_1, uint16_t param_2)
Definition sf_wrappers.h:9
SF_String *(__thiscall * SF_String_ctor_ptr)(SF_String *, const char *)
Definition sf_wrappers.h:7
void(__thiscall * SF_String_dtor_ptr)(SF_String *)
Definition sf_wrappers.h:8
void(__thiscall * container_alpha_ptr)(CMnuContainer *_this, float alpha)
Definition sf_wrappers.h:79
void(__thiscall * set_button_flag_ptr)(void *container, char flag)
Definition sf_wrappers.h:56
void(__thiscall * set_btn_index_ptr)(void *container, int index)
Definition sf_wrappers.h:57
void(__thiscall * vfunction_2_ptr)(void *_this, void *input)
Definition sf_wrappers.h:51
void(__thiscall * vfunction2_callback_attach_ptr)(void *, void *, void *, void *)
Definition sf_wrappers.h:70
void(__thiscall * set_label_color_ptr)(CMnuLabel *_this, float r, float g, float b, char flag)
Definition sf_wrappers.h:65
void(__thiscall * set_btn_name_ptr)(void *button, SF_String *string)
Definition sf_wrappers.h:67
void(__thiscall * CMnuBase_setname_ptr)(CMnuBase *_this, SF_String *name)
Definition sf_wrappers.h:81
void(__thiscall * setup_menu_container_data_ptr)(CMnuContainer *_this, float x, float y, float width, float height, SF_String *background, SF_String *border)
Definition sf_wrappers.h:73
void(__thiscall * create_button_ptr)(CMnuSmpButton *smpButton, float x_pos, float y_pos, float width, float height, SF_String *default_mesh, SF_String *unkn_mesh_string, SF_String *pressed_mesh, SF_String *disable_mesh)
Definition sf_wrappers.h:58
void(__thiscall * vfunction12_ptr)(void *container, void *test, char p1)
Definition sf_wrappers.h:53
void(__thiscall * attach_string_ptr)(void *container, void *string)
Definition sf_wrappers.h:55
CMnuSmpButton *(__thiscall * initialize_smp_button_ptr)(CMnuSmpButton *btn)
Definition sf_wrappers.h:68
void(__thiscall * vfunction_ptr)(void *_this, char p1)
Definition sf_wrappers.h:52
CGdTileIterator_data data
CMnuBase_data CMnuBase_data
addBonusMult_ptr addBonusMult
getSpellJobStartNode_ptr getSpellJobStartNode
FigureStatistic strength
FigureStatistic dexterity
FigureStatistic resistance_mental
FigureStatistic charisma
FigureStatistic resistance_fire
FigureStatistic cast_speed
FigureStatistic wisdom
FigureStatistic fight_speed
FigureStatistic resistance_ice
FigureStatistic agility
FigureStatistic resistance_black
FigureStatistic walk_speed
FigureStatistic armor
FigureStatistic intelligence
figureIteratorSetPointers_ptr figureIteratorSetPointers
figureIteratorInit_ptr figureIteratorInit
A structure for the global list of figures and related statistics for them.
GdFigure figures[2000]
SF_CGdFigure * SF_CGdFigure
SF_CGdWorld * SF_CGdWorld
SF_GdSpell active_spell_list[800]
log_function_ptr logInfo
log_function_ptr logError
log_function_ptr logWarning
char mod_id[64]
char mod_description[128]
char mod_version[24]
char mod_errors[256]
char mod_author[128]
getSpellTags_ptr getSpellTags
Retrieves the tags associated with a spell.
figTryClrCHkSPlBfrJob2_ptr figTryClrCHkSPlBfrJob2
clears the CHECK_SPELLS_BEFORE_JOB2 flag
figTryUnfreeze_ptr figTryUnfreeze
clears the UNFREEZE flag
figClrChkSplBfrChkBattle_ptr figClrChkSplBfrChkBattle
Clears the CHECK_SPELLS_BEFORE_CHECK_BATTLE flag.
getNextNode_ptr getNextNode
getSpellIndexFromDLL_ptr getSpellIndexFromDLL