diff --git a/artifacts/scripting/headers/define_extra.h b/artifacts/scripting/headers/define_extra.h index a4d08471..f72f0c42 100644 --- a/artifacts/scripting/headers/define_extra.h +++ b/artifacts/scripting/headers/define_extra.h @@ -10,6 +10,12 @@ #define OBJ_TYPE_MISC (5) #define OBJ_TYPE_SPATIAL (6) +#define WEAPON_TYPE_NONE (0) +#define WEAPON_TYPE_UNARMED (1) +#define WEAPON_TYPE_MELEE (2) +#define WEAPON_TYPE_THROWN (3) +#define WEAPON_TYPE_GUNS (4) + /* Item Common Flags */ #define HIDDEN_ITEM 134217728 // 0x08000000 - Hidden Item @@ -39,6 +45,32 @@ #define ATKMODE_SEC_BURST 112 // 0x00000070 #define ATKMODE_SEC_FLAME 128 // 0x00000080 +/* Object flags for get/set_flags */ +#define FLAG_MOUSE_3D (0x1) +#define FLAG_WALKTHRU (0x4) +#define FLAG_FLAT (0x8) +#define FLAG_NOBLOCK (0x10) +#define FLAG_LIGHTING (0x20) +#define FLAG_TEMP (0x400) +#define FLAG_MULTIHEX (0x800) +#define FLAG_NOHIGHLIGHT (0x1000) +#define FLAG_USED (0x2000) +#define FLAG_TRANSRED (0x4000) +#define FLAG_TRANSNONE (0x8000) +#define FLAG_TRANSWALL (0x10000) +#define FLAG_TRANSGLASS (0x20000) +#define FLAG_TRANSSTEAM (0x40000) +#define FLAG_TRANSENERGY (0x80000) +#define FLAG_LEFT_HAND (0x1000000) +#define FLAG_RIGHT_HAND (0x2000000) +#define FLAG_WORN (0x4000000) +#define FLAG_HIDDENITEM (0x8000000) +#define FLAG_WALLTRANSEND (0x10000000) +#define FLAG_LIGHTTHRU (0x20000000) +#define FLAG_SEEN (0x40000000) +#define FLAG_SHOOTTHRU (0x80000000) + + /* Critter Flags */ #define CFLG_BARTER 2 // 0x00000002 - Barter (can trade with) #define CFLG_NOSTEAL 32 // 0x00000020 - Steal (cannot steal from) diff --git a/artifacts/scripting/headers/sfall.h b/artifacts/scripting/headers/sfall.h index 4276884d..b60239c2 100644 --- a/artifacts/scripting/headers/sfall.h +++ b/artifacts/scripting/headers/sfall.h @@ -158,6 +158,19 @@ #define GAME_MSG_PRO_TILE (0x1004) #define GAME_MSG_PRO_MISC (0x1005) +#define OUTLINE_NONE (0) +#define OUTLINE_RED_GLOW (0x01) +#define OUTLINE_RED (0x02) +#define OUTLINE_GREY (0x04) +#define OUTLINE_GREEN_GLOW (0x08) +#define OUTLINE_YELLOW (0x10) +#define OUTLINE_DARK_YELLOW (0x20) +#define OUTLINE_PURPLE (0x40) + +#define CURSOR_MOVEMENT (0) +#define CURSOR_COMMAND (1) +#define CURSOR_TARGETING (2) + #define mstr_combat(x) (message_str_game(GAME_MSG_COMBAT, x)) #define mstr_ai(x) (message_str_game(GAME_MSG_AI, x)) #define mstr_scrname(x) (message_str_game(GAME_MSG_SCRNAME, x)) @@ -189,15 +202,28 @@ #define party_member_list_all party_member_list(1) -#define create_win(winName, x, y, w, h) sfall_func5("create_win", winName, x, y, w, h) -#define create_win_flag(winName, x, y, w, h, flag) sfall_func6("create_win", winName, x, y, w, h, flag) -#define critter_inven_obj2(obj, type) sfall_func2("critter_inven_obj2", obj, type) -#define exec_map_update_scripts sfall_func0("exec_map_update_scripts") -#define floor2(value) sfall_func1("floor2", value) -#define get_current_inven_size(obj) sfall_func1("get_current_inven_size", obj) -#define intface_hide sfall_func0("intface_hide") -#define intface_is_hidden sfall_func0("intface_is_hidden") -#define intface_redraw sfall_func0("intface_redraw") -#define intface_show sfall_func0("intface_show") -#define set_ini_setting(setting, value) sfall_func2("set_ini_setting", setting, value) -#define spatial_radius(obj) sfall_func1("spatial_radius", obj) +#define attack_is_aimed sfall_func0("attack_is_aimed") +#define create_win(winName, x, y, w, h) sfall_func5("create_win", winName, x, y, w, h) +#define create_win_flag(winName, x, y, w, h, flag) sfall_func6("create_win", winName, x, y, w, h, flag) +#define critter_inven_obj2(obj, type) sfall_func2("critter_inven_obj2", obj, type) +#define display_stats sfall_func0("display_stats") +#define exec_map_update_scripts sfall_func0("exec_map_update_scripts") +#define floor2(value) sfall_func1("floor2", value) +#define get_current_inven_size(obj) sfall_func1("get_current_inven_size", obj) +#define get_cursor_mode sfall_func0("get_cursor_mode") +#define get_flags(obj) sfall_func1("get_flags", obj) +#define get_map_enter_position sfall_func0("get_map_enter_position") +#define get_outline(obj) sfall_func1("get_outline", obj) +#define intface_hide sfall_func0("intface_hide") +#define intface_is_hidden sfall_func0("intface_is_hidden") +#define intface_redraw sfall_func0("intface_redraw") +#define intface_show sfall_func0("intface_show") +#define item_weight(obj) sfall_func1("item_weight", obj) +#define outlined_object sfall_func0("outlined_object") +#define set_cursor_mode(mode) sfall_func1("set_cursor_mode", mode) +#define set_flags(obj, flags) sfall_func2("set_flags", obj, flags) +#define set_ini_setting(setting, value) sfall_func2("set_ini_setting", setting, value) +#define set_map_enter_position(tile, elev, rot) sfall_func3("set_map_enter_position", tile, elev, rot) +#define set_outline(obj, color) sfall_func2("set_outline", obj, color) +#define spatial_radius(obj) sfall_func1("spatial_radius", obj) +#define tile_refresh_display sfall_func0("tile_refresh_display") diff --git a/artifacts/scripting/sfall function notes.txt b/artifacts/scripting/sfall function notes.txt index 1845917d..fabb50bf 100644 --- a/artifacts/scripting/sfall function notes.txt +++ b/artifacts/scripting/sfall function notes.txt @@ -385,6 +385,54 @@ Some utility/math functions are available: - works just like vanilla floor function, but returns correct integers for negative values - vanilla floor function works exactly the same as ceil for negative values, much like trunc in C/C++ +> int sfall_func1("item_weight", object) +- gets the current weight of an object + +> int sfall_func1("get_outline", object) +- gets the current outline color for an object + +> void sfall_func2("set_outline", object, int color) +- sets the outline color of an object +- 0 means or any value above 0x00FFFFFF disables the outline +- call "tile_refresh_display" after changing outline of objects to properly redraw the scene + +> int sfall_func1("get_flags", object) +- gets the current value of object flags (see define_extra.h for available flags) + +> void sfall_func2("set_flags", object, int flags) +- sets the current flags of an object +- all flags are rewritten with given integer, so first get current flags with "get_flags" and use bwor/bwand to set/remove specific flag + +> void sfall_func0("tile_refresh_display") +- redraws the game scene (tiles, walls, objects, etc.) + +> object sfall_func0("outlined_object") +- returns an object that is currently highlighted by hovering the mouse above it + +> int sfall_func0("get_cursor_mode") +- returns the current cursor mode (0 - movement cursor, 1 - command cursor, 2 - targeting cursor) +- mode 4 to 10 are Skilldex skills (yellow targeting cursor) + +> void sfall_func1("set_cursor_mode", int mode) +- sets the current cursor mode + +> void sfall_func0("display_stats") +- displays player stats in the inventory screen display window +- works only in opened inventory + +> array sfall_func0("get_map_enter_position") +- returns an array of the player's position data (index 0 - tile, 1 - elevation, 2 - rotation) when entering the map through exit grids +- if entering from the world map, the tile value will be -1 +- should be called in map_enter_p_proc procedure to get the correct position data + +> void sfall_func3("set_map_enter_position", int tile, int elevation, int rotation) +- overrides the player's entry position when entering the map through exit grids +- setting the tile to 0 will put the player on the start hex (default tile and elevation) of the map +- works only in map_enter_p_proc procedure + +> int sfall_func0("attack_is_aimed") +- returns 1 if the aimed attack mode is selected, 0 otherwise + > int sfall_func1("get_current_inven_size", object) - returns the current inventory size of the container or the critter diff --git a/sfall/AmmoMod.cpp b/sfall/AmmoMod.cpp index 55544e48..0d504aee 100644 --- a/sfall/AmmoMod.cpp +++ b/sfall/AmmoMod.cpp @@ -615,126 +615,56 @@ end: } } -static void __declspec(naked) DisplayBonusRangedDmg() { +static void __declspec(naked) DisplayBonusRangedDmg_hook() { __asm { - mov edx, PERK_bonus_ranged_damage - mov eax, dword ptr ds:[_stack] - call perk_level_ - shl eax, 1 - add dword ptr [esp+4*4], eax // min_dmg - add dword ptr [esp+4*5], eax // max_dmg - jmp sprintf_ + mov edx, PERK_bonus_ranged_damage; + mov eax, dword ptr ds:[_stack]; + call perk_level_; + shl eax, 1; + add dword ptr [esp + 4 * 4], eax; // min_dmg + perk bonus + add dword ptr [esp + 4 * 5], eax; // max_dmg + perk bonus + jmp sprintf_; } } -static void __declspec(naked) DisplayBonusHtHDmg1() { +static void __declspec(naked) DisplayBonusHtHDmg1_hook() { __asm { - mov edx, PERK_bonus_hth_damage - mov eax, dword ptr ds:[_stack] - call perk_level_ - shl eax, 1 - add dword ptr [esp+4*4], eax // min_dmg - jmp sprintf_ + mov edx, PERK_bonus_hth_damage; + mov eax, dword ptr ds:[_stack]; + call perk_level_; + shl eax, 1; + add dword ptr [esp + 4 * 4], eax; // min_dmg + bonus + jmp sprintf_; } } -static void __declspec(naked) DisplayBonusHtHDmg2() { +static const DWORD DisplayBonusHtHDmg2Exit = 0x472569; +static void __declspec(naked) DisplayBonusHtHDmg2_hack() { __asm { - push eax - call stat_level_ - pop ecx - add eax, 2 - push eax - xchg ecx, eax - mov edx, PERK_bonus_hth_damage - call perk_level_ - shl eax, 1 - add eax, 1 - push eax - mov eax, dword ptr [esp+0x98+0x4] - push eax - push 0x509EDC // '%s %d-%d' - lea eax, [esp+0xC+0x4] - push eax - call sprintf_ - add esp, 4*5 - push 0x472569 - retn - } -} - -static const DWORD UnarmedAttacksFixEnd=0x423A0D; -static void __declspec(naked) UnarmedAttacksFix() { - __asm { - cmp edx,0x10; // Power Kick - je PowKickHPunch; - cmp edx,0x9; // Hammer Punch - jnz HKickJabCheck; -PowKickHPunch: - mov edx,0x64; - mov eax,0x1; - call roll_random_; - cmp eax,0x5; // 5% chance of critical hit - jle CriticalHit; - jmp end; -HKickJabCheck: - mov eax,dword ptr ds:[esi+0x4]; // get hit_mode - cmp eax,0x12; // Hook Kick - je HKickJab; - cmp eax,0xb; // Jab - jnz Haymaker; -HKickJab: - mov edx,0x64; - mov eax,0x1; - call roll_random_; - cmp eax,0xa; // 10% chance of critical hit - jle CriticalHit; - jmp end; -Haymaker: - cmp dword ptr ds:[esi+0x4],0xa; // Haymaker - jnz PalmStrike; - mov edx,0x64; - mov eax,0x1; - call roll_random_; - cmp eax,0xf; // 15% chance of critical hit - jle CriticalHit; - jmp end; -PalmStrike: - cmp dword ptr ds:[esi+0x4],0xc; // Palm Strike - jnz PiercingStrike; - mov edx,0x64; - mov eax,0x1; - call roll_random_; - cmp eax,0x14; // 20% chance of critical hit - jle CriticalHit; - jmp end; -PiercingStrike: - cmp dword ptr ds:[esi+0x4],0xd; // Piercing Strike - jnz PiercingKick; - mov edx,0x64; - mov eax,0x1; - call roll_random_; - cmp eax,0x28; // 40% chance of critical hit - jle CriticalHit; - jmp end; -PiercingKick: - cmp dword ptr ds:[esi+0x4],0x13; // Piercing Kick - jnz end; - mov edx,0x64; - mov eax,0x1; - call roll_random_; - cmp eax,0x32; // 50% chance of critical hit - jg end; -CriticalHit: - mov ebx,0x3; // Upgrade to critical hit -end: - jmp UnarmedAttacksFixEnd; + mov ecx, eax; + call stat_level_; + add eax, 2; + push eax; // max dmg + mov edx, PERK_bonus_hth_damage; + mov eax, ecx; + call perk_level_; + shl eax, 1; + add eax, 1; + push eax; // min dmg + bonus + mov ecx, dword ptr[esp + 0x98 + 0x4]; + push ecx; // message + push 0x509EDC; // '%s %d-%d' + lea eax, [esp + 0x0C + 0x4]; + push eax; // buf + call sprintf_; + add esp, 0x10 + 0x4; + jmp DisplayBonusHtHDmg2Exit; } } void AmmoModInit() { int formula; - if (formula=GetPrivateProfileIntA("Misc", "DamageFormula", 0, ini)) { + if (formula = GetPrivateProfileIntA("Misc", "DamageFormula", 0, ini)) { switch (formula) { case 1: MakeJump(0x424995, DamageFunction1); @@ -753,6 +683,7 @@ void AmmoModInit() { break; } } + int BonusHtHDmgFix = GetPrivateProfileIntA("Misc", "BonusHtHDamageFix", 1, ini); int DisplayBonusDmg = GetPrivateProfileIntA("Misc", "DisplayBonusDamage", 0, ini); if (BonusHtHDmgFix) { @@ -767,17 +698,13 @@ void AmmoModInit() { MakeJump(0x47854C, HtHDamageFix1b); dlogr(" Done", DL_INIT); } - //if(GetPrivateProfileIntA("Misc", "SpecialUnarmedAttacksFix", 1, ini)) { - dlog("Applying Special Unarmed Attacks fix.", DL_INIT); - MakeJump(0x42394D, UnarmedAttacksFix); - dlogr(" Done", DL_INIT); - //} + if (DisplayBonusDmg) { dlog("Applying Display Bonus Damage patch.", DL_INIT); - HookCall(0x4722DD, &DisplayBonusRangedDmg); + HookCall(0x4722DD, DisplayBonusRangedDmg_hook); if (BonusHtHDmgFix) { - HookCall(0x472309, &DisplayBonusHtHDmg1); - MakeJump(0x472546, DisplayBonusHtHDmg2); + HookCall(0x472309, DisplayBonusHtHDmg1_hook); + MakeJump(0x472546, DisplayBonusHtHDmg2_hack); } dlogr(" Done", DL_INIT); } diff --git a/sfall/Bugs.cpp b/sfall/Bugs.cpp index 625191d3..d784d446 100644 --- a/sfall/Bugs.cpp +++ b/sfall/Bugs.cpp @@ -41,6 +41,43 @@ isFloat: } } +static const DWORD UnarmedAttacksFixEnd = 0x423A0D; +static void __declspec(naked) UnarmedAttacksFix() { + __asm { + mov ecx, 5; // 5% chance of critical hit + cmp edx, 0x10; // Power Kick + je RollCheck; + cmp edx, 0x09; // Hammer Punch + je RollCheck; + add ecx, 5; // 10% chance of critical hit + cmp edx, 0x12; // Hook Kick + je RollCheck; + cmp edx, 0x0B; // Jab + je RollCheck; + add ecx, 5; // 15% chance of critical hit + cmp edx, 0x0A; // Haymaker + je RollCheck; + add ecx, 5; // 20% chance of critical hit + cmp edx, 0x0C; // Palm Strike + je RollCheck; + add ecx, 20; // 40% chance of critical hit + cmp edx, 0x0D; // Piercing Strike + je RollCheck; + cmp edx, 0x13; // Piercing Kick + jne end; + add ecx, 10; // 50% chance of critical hit +RollCheck: + mov edx, 100; + mov eax, 1; + call roll_random_; + cmp eax, ecx; // Check chance + jg end; + mov ebx, 3; // Upgrade to critical hit +end: + jmp UnarmedAttacksFixEnd; + } +} + static void __declspec(naked) SharpShooterFix() { __asm { call stat_level_ // Perception @@ -1384,24 +1421,28 @@ fix: static DWORD op_start_gdialog_ret = 0x456F4B; static void __declspec(naked) op_start_gdialog_hack() { __asm { - mov ebx, ds:[_dialog_target]; - mov ebx, [ebx + 0x64]; - shr ebx, 0x18; - cmp ebx, OBJ_TYPE_CRITTER; - jz fix; - cmp edx, -1; - jz skip; + cmp eax, -1; // check mood arg + jnz useMood; + mov eax, dword ptr [esp + 0x3C - 0x30 + 4]; // fix dialog_target (overwritten engine code) retn; -fix: - cmp eax, -1; - jnz skip; - retn; -skip: +useMood: add esp, 4; // Destroy the return address jmp op_start_gdialog_ret; } } +static void __declspec(naked) item_w_range_hook() { + __asm { + call stat_level_; // get ST + lea ecx, [eax + ebx]; // ebx - bonus from "Heave Ho!" + sub ecx, 10; // compare ST + bonus <= 10 + jbe skip; + sub ebx, ecx; // cutoff +skip: + retn; + } +} + void BugsInit() { @@ -1415,6 +1456,12 @@ void BugsInit() SafeWrite16(0x46A566, 0x04DB); SafeWrite16(0x46A4E7, 0x04DB); + //if(GetPrivateProfileIntA("Misc", "SpecialUnarmedAttacksFix", 1, ini)) { + dlog("Applying Special Unarmed Attacks fix.", DL_INIT); + MakeJump(0x42394D, UnarmedAttacksFix); + dlogr(" Done", DL_INIT); + //} + //if (GetPrivateProfileIntA("Misc", "SharpshooterFix", 1, ini)) { dlog("Applying Sharpshooter patch.", DL_INIT); // http://www.nma-fallout.com/threads/fo2-engine-tweaks-sfall.178390/page-119#post-4050162 @@ -1790,7 +1837,10 @@ void BugsInit() // Fix for the "mood" argument of start_gdialog function being ignored for talking heads if (GetPrivateProfileIntA("Misc", "StartGDialogFix", 0, ini)) { dlog("Applying start_gdialog argument fix.", DL_INIT); - MakeCall(0x456F03, op_start_gdialog_hack); + MakeCall(0x456F08, op_start_gdialog_hack); dlogr(" Done", DL_INIT); } + + // Fix for "Heave Ho!" perk increasing strength stat above 10 when determining the max range of thrown weapons + HookCall(0x478AD9, item_w_range_hook); } diff --git a/sfall/FalloutEngine.cpp b/sfall/FalloutEngine.cpp index cb979d81..0c414997 100644 --- a/sfall/FalloutEngine.cpp +++ b/sfall/FalloutEngine.cpp @@ -57,6 +57,7 @@ DWORD* ptr_dialog_target_is_party = reinterpret_cast(_dialog_target_ DWORD* ptr_drugInfoList = reinterpret_cast(_drugInfoList); DWORD* ptr_edit_win = reinterpret_cast(_edit_win); DWORD* ptr_Educated = reinterpret_cast(_Educated); +DWORD* ptr_elevation = reinterpret_cast(_elevation); DWORD* ptr_Experience_ = reinterpret_cast(_Experience_); DWORD* ptr_fallout_game_time = reinterpret_cast(_fallout_game_time); DWORD* ptr_flptr = reinterpret_cast(_flptr); @@ -167,6 +168,7 @@ DWORD* ptr_quick_done = reinterpret_cast(_quick_done); DWORD* ptr_read_callback = reinterpret_cast(_read_callback); DWORD* ptr_RedColor = reinterpret_cast(_RedColor); DWORD* ptr_retvals = reinterpret_cast(_retvals); +DWORD* ptr_rotation = reinterpret_cast(_rotation); DWORD* ptr_scr_size = reinterpret_cast(_scr_size); DWORD* ptr_scriptListInfo = reinterpret_cast(_scriptListInfo); DWORD* ptr_skill_data = reinterpret_cast(_skill_data); @@ -196,6 +198,7 @@ DWORD* ptr_text_mono_width = reinterpret_cast(_text_mono_widt DWORD* ptr_text_spacing = reinterpret_cast(_text_spacing); DWORD* ptr_text_to_buf = reinterpret_cast(_text_to_buf); DWORD* ptr_text_width = reinterpret_cast(_text_width); +DWORD* ptr_tile = reinterpret_cast(_tile); DWORD* ptr_title_color = reinterpret_cast(_title_color); DWORD* ptr_title_font = reinterpret_cast(_title_font); DWORD* ptr_trait_data = reinterpret_cast(_trait_data); @@ -353,6 +356,8 @@ const DWORD GetSlotList_ = 0x47E5D0; const DWORD get_input_ = 0x4C8B78; const DWORD get_time_ = 0x4C9370; const DWORD getmsg_ = 0x48504C; // eax - msg file addr, ebx - message ID, edx - int[4] - loads string from MSG file preloaded in memory +const DWORD gmouse_3d_get_mode_ = 0x44CB6C; +const DWORD gmouse_3d_set_mode_ = 0x44CA18; const DWORD gmouse_is_scrolling_ = 0x44B54C; const DWORD gmouse_set_cursor_ = 0x44C840; const DWORD GNW_find_ = 0x4D7888; diff --git a/sfall/FalloutEngine.h b/sfall/FalloutEngine.h index 1ab48d42..bc40907b 100644 --- a/sfall/FalloutEngine.h +++ b/sfall/FalloutEngine.h @@ -66,6 +66,7 @@ #define _drugInfoList 0x5191CC #define _edit_win 0x57060C #define _Educated 0x57082C +#define _elevation 0x631D2C #define _Experience_ 0x6681B4 #define _fallout_game_time 0x51C720 #define _flptr 0x614808 @@ -184,6 +185,7 @@ #define _read_callback 0x51DEEC #define _RedColor 0x6AB4D0 #define _retvals 0x43EA7C +#define _rotation 0x631D34 #define _sad 0x530014 #define _scr_size 0x6AC9F0 #define _scriptListInfo 0x51C7C8 @@ -215,6 +217,7 @@ #define _text_spacing 0x51E3CC #define _text_to_buf 0x51E3B8 #define _text_width 0x51E3C0 +#define _tile 0x631D30 #define _title_color 0x56D750 #define _title_font 0x56D748 #define _trait_data 0x51DB84 @@ -266,6 +269,7 @@ extern DWORD* ptr_dialog_target_is_party; extern DWORD* ptr_drugInfoList; extern DWORD* ptr_edit_win; extern DWORD* ptr_Educated; +extern DWORD* ptr_elevation; extern DWORD* ptr_Experience_; extern DWORD* ptr_fallout_game_time; extern DWORD* ptr_flptr; @@ -376,6 +380,7 @@ extern DWORD* ptr_quick_done; extern DWORD* ptr_read_callback; extern DWORD* ptr_RedColor; extern DWORD* ptr_retvals; +extern DWORD* ptr_rotation; extern DWORD* ptr_sad; extern DWORD* ptr_scr_size; extern DWORD* ptr_scriptListInfo; @@ -406,6 +411,7 @@ extern DWORD* ptr_text_mono_width; extern DWORD* ptr_text_spacing; extern DWORD* ptr_text_to_buf; extern DWORD* ptr_text_width; +extern DWORD* ptr_tile; extern DWORD* ptr_title_color; extern DWORD* ptr_title_font; extern DWORD* ptr_trait_data; @@ -543,6 +549,8 @@ extern const DWORD GetSlotList_; extern const DWORD get_input_; extern const DWORD get_time_; extern const DWORD getmsg_; +extern const DWORD gmouse_3d_get_mode_; +extern const DWORD gmouse_3d_set_mode_; extern const DWORD gmouse_is_scrolling_; extern const DWORD gmouse_set_cursor_; extern const DWORD GNW_find_; diff --git a/sfall/FalloutStructs.h b/sfall/FalloutStructs.h index c2ee571d..b1907f9f 100644 --- a/sfall/FalloutStructs.h +++ b/sfall/FalloutStructs.h @@ -116,9 +116,11 @@ struct TScript TGameObj *self_obj; TGameObj *source_obj; TGameObj *target_obj; + long action_num; long script_overrides; - char field_44; - char gap_45[15]; + char gap_48[4]; + long how_much; + char gap_50[4]; long procedure_table[28]; }; #pragma pack(pop) diff --git a/sfall/Perks.cpp b/sfall/Perks.cpp index 1b459e39..1b0a27ab 100644 --- a/sfall/Perks.cpp +++ b/sfall/Perks.cpp @@ -604,9 +604,9 @@ static void __declspec(naked) HeaveHoHook() { call stat_level_; lea ebx, [0+eax*4]; sub ebx, eax; - cmp ebx, esi; - jle lower; - mov ebx, esi; + cmp ebx, esi; // ebx = dist (3*ST), esi = max dist weapon + jle lower; // jump if dist <= max + mov ebx, esi; // dist = max lower: mov eax, ecx; mov edx, PERK_heave_ho; @@ -615,12 +615,12 @@ lower: sub ecx, eax; sub ecx, eax; mov eax, ecx; - add eax, ebx; + add eax, ebx; // distance = dist + (PERK_heave_ho * 6) push 0x478AFC; retn; } } -void _stdcall ApplyHeaveHoFix() { +void _stdcall ApplyHeaveHoFix() { // not really a fix MakeJump(0x478AC4, HeaveHoHook); Perks[PERK_heave_ho].Str = 0; } diff --git a/sfall/ScriptOps/InterfaceOp.hpp b/sfall/ScriptOps/InterfaceOp.hpp index 00a91869..d4c87c14 100644 --- a/sfall/ScriptOps/InterfaceOp.hpp +++ b/sfall/ScriptOps/InterfaceOp.hpp @@ -20,6 +20,7 @@ #include "main.h" #include "input.h" +#include "LoadGameHook.h" #include "ScriptExtender.h" @@ -452,22 +453,50 @@ static void sf_intface_redraw() { } static void sf_intface_show() { - __asm call intface_show_ + __asm call intface_show_; } static void sf_intface_hide() { - __asm call intface_hide_ + __asm call intface_hide_; } static void sf_intface_is_hidden() { int isHidden; __asm { - call intface_is_hidden_ + call intface_is_hidden_; mov isHidden, eax; } opHandler.setReturn(isHidden); } +static void sf_tile_refresh_display() { + __asm call tile_refresh_display_; +} + +static void sf_get_cursor_mode() { + int cursorMode; + __asm { + call gmouse_3d_get_mode_; + mov cursorMode, eax; + } + opHandler.setReturn(cursorMode); +} + +static void sf_set_cursor_mode() { + int cursorMode = opHandler.arg(0).asInt(); + __asm { + mov eax, cursorMode; + call gmouse_3d_set_mode_; + } +} + +static void sf_display_stats() { +// calling the function outside of inventory screen will crash the game + if (GetCurrentLoops() & INVENTORY) { + __asm call display_stats_; + } +} + static void sf_create_win() { int flags; if (opHandler.numArgs() == 6) { diff --git a/sfall/ScriptOps/MetaruleOp.hpp b/sfall/ScriptOps/MetaruleOp.hpp index de43fa85..a6ce6a8d 100644 --- a/sfall/ScriptOps/MetaruleOp.hpp +++ b/sfall/ScriptOps/MetaruleOp.hpp @@ -103,18 +103,31 @@ static void sf_get_metarule_table() { - minArgs/maxArgs - minimum and maximum number of arguments allowed for this function */ static const SfallMetarule metaruleArray[] = { + {"attack_is_aimed", sf_attack_is_aimed, 0, 0}, {"critter_inven_obj2", sf_critter_inven_obj2, 2, 2}, {"create_win", sf_create_win, 5, 6}, + {"display_stats", sf_display_stats, 0, 0}, {"exec_map_update_scripts", sf_exec_map_update_scripts, 0, 0}, {"floor2", sf_floor2, 1, 1}, {"get_current_inven_size", sf_get_current_inven_size, 1, 1}, + {"get_cursor_mode", sf_get_cursor_mode, 0, 0}, + {"get_flags", sf_get_flags, 1, 1}, + {"get_map_enter_position", sf_get_map_enter_position, 0, 0}, {"get_metarule_table", sf_get_metarule_table, 0, 0}, + {"get_outline", sf_get_outline, 1, 1}, {"intface_hide", sf_intface_hide, 0, 0}, {"intface_is_hidden", sf_intface_is_hidden, 0, 0}, {"intface_redraw", sf_intface_redraw, 0, 0}, {"intface_show", sf_intface_show, 0, 0}, + {"item_weight", sf_item_weight, 1, 1}, + {"outlined_object", sf_outlined_object, 0, 0}, + {"set_cursor_mode", sf_set_cursor_mode, 1, 1}, + {"set_flags", sf_set_flags, 2, 2}, {"set_ini_setting", sf_set_ini_setting, 2, 2}, + {"set_map_enter_position", sf_set_map_enter_position, 3, 3}, + {"set_outline", sf_set_outline, 2, 2}, {"spatial_radius", sf_spatial_radius, 1, 1}, + {"tile_refresh_display", sf_tile_refresh_display, 0, 0}, {"validate_test", sf_test, 2, 5}, }; @@ -163,6 +176,8 @@ static void _stdcall op_sfall_metarule_handler() { opHandler.setArgShift(1); if (ValidateMetaruleArguments(currentMetarule)) { currentMetarule->func(); + } else { + opHandler.setReturn(-1); } } else { opHandler.printOpcodeError("sfall_funcX(name, ...) - name '%s' is unknown.", name); diff --git a/sfall/ScriptOps/MiscOps.hpp b/sfall/ScriptOps/MiscOps.hpp index 03140877..1909302d 100644 --- a/sfall/ScriptOps/MiscOps.hpp +++ b/sfall/ScriptOps/MiscOps.hpp @@ -1286,19 +1286,27 @@ static void __declspec(naked) refresh_pc_art() { retn; } } + +static void _stdcall intface_attack_type() { + __asm { + sub esp, 8; + lea edx, [esp]; + lea eax, [esp+4]; + call intface_get_attack_; + pop edx; // is_secondary + pop ecx; // hit_mode + } +} + static void __declspec(naked) get_attack_type() { __asm { push edx; push ecx; push eax; - sub esp, 8; - lea edx, [esp]; - lea eax, [esp+4]; - call intface_get_attack_; - add esp, 4; // is_secondary + call intface_attack_type; + mov edx, ecx; // hit_mode test eax, eax; jz skip; - add esp, 4; // get reload cmp ds:[_interfaceWindow], eax; jz end; @@ -1307,17 +1315,21 @@ static void __declspec(naked) get_attack_type() { cmp ds:[_itemButtonItems+5+edx], 1; // .itsWeapon jnz end; lea eax, [ecx+6]; - jmp end; -skip: - pop eax; // hit_mode end: + mov edx, eax; // result +skip: pop ecx; - _RET_VAL_INT(ecx); + mov eax, ecx; + call interpretPushLong_; + mov eax, ecx; + mov edx, VAR_TYPE_INT; + call interpretPushShort_; pop ecx; pop edx; retn; } } + static void __declspec(naked) play_sfall_sound() { __asm { pushad @@ -1641,6 +1653,16 @@ end: _OP_END } +static void sf_attack_is_aimed() { + int is_secondary, result; + __asm { + call intface_attack_type; + mov result, eax; + mov is_secondary, edx; + } + opHandler.setReturn((result != -1) ? is_secondary : 0); +} + static void sf_exec_map_update_scripts() { __asm call scr_exec_map_update_scripts_ } diff --git a/sfall/ScriptOps/ObjectsOps.hpp b/sfall/ScriptOps/ObjectsOps.hpp index a7087c5d..7f52211c 100644 --- a/sfall/ScriptOps/ObjectsOps.hpp +++ b/sfall/ScriptOps/ObjectsOps.hpp @@ -559,11 +559,43 @@ static void sf_critter_inven_obj2() { } } +static void sf_set_outline() { + TGameObj* obj = opHandler.arg(0).asObject(); + int color = opHandler.arg(1).asInt(); + obj->outline = color; +} + +static void sf_get_outline() { + TGameObj* obj = opHandler.arg(0).asObject(); + opHandler.setReturn(obj->outline, DATATYPE_INT); +} + +static void sf_set_flags() { + TGameObj* obj = opHandler.arg(0).asObject(); + int flags = opHandler.arg(1).asInt(); + obj->flags = flags; +} + +static void sf_get_flags() { + TGameObj* obj = opHandler.arg(0).asObject(); + opHandler.setReturn(obj->flags); +} + +static void sf_outlined_object() { + opHandler.setReturn(*ptr_outlined_object, DATATYPE_INT); +} + +static void sf_item_weight() { + TGameObj* item = opHandler.arg(0).asObject(); + int weight; + __asm { + mov eax, item; + call item_weight_; + mov weight, eax; + } + opHandler.setReturn(weight); +} + static void sf_get_current_inven_size() { - TGameObj* invenObj = opHandler.arg(0).asObject(); - if (invenObj != nullptr) { - opHandler.setReturn(sf_item_total_size(invenObj), DATATYPE_INT); - } else { - opHandler.setReturn(-1, DATATYPE_INT); - } + opHandler.setReturn(sf_item_total_size(opHandler.arg(0).asObject()), DATATYPE_INT); } diff --git a/sfall/ScriptOps/WorldmapOps.hpp b/sfall/ScriptOps/WorldmapOps.hpp index 36b89b84..1ed80682 100644 --- a/sfall/ScriptOps/WorldmapOps.hpp +++ b/sfall/ScriptOps/WorldmapOps.hpp @@ -19,6 +19,7 @@ #pragma once #include "main.h" +#include "Arrays.h" #include "ScriptExtender.h" @@ -209,3 +210,27 @@ end: retn; } } + +static void sf_set_map_enter_position() { + int tile = opHandler.arg(0).asInt(); + int elev = opHandler.arg(1).asInt(); + int rot = opHandler.arg(2).asInt(); + + if (tile > -1 && tile < 40000) { + *ptr_tile = tile; + } + if (elev > -1 && elev < 3) { + *ptr_elevation = elev; + } + if (rot > -1 && rot < 6) { + *ptr_rotation = rot; + } +} + +static void sf_get_map_enter_position() { + DWORD id = TempArray(3, 0); + arrays[id].val[0].set((long)*ptr_tile); + arrays[id].val[1].set((long)*ptr_elevation); + arrays[id].val[2].set((long)*ptr_rotation); + opHandler.setReturn(id, DATATYPE_INT); +}