Changed implementation of StartGDialogFix, additionally fixed the game crash if calling start_gdialog function outside of talk_p_proc procedure for talking heads.

Fixed "Heave Ho!" perk increasing strength stat above 10 when determining the max range of thrown weapons.
Moved SpecialUnarmedAttacksFix to BugFixes.cpp and simplified the code.
Added comments to old ApplyHeaveHoFix in Perks.cpp.
Backported some non-hook related script functions from 4.0: item_weight, get/set_outline, get/set_flags, tile_refresh_display, outlined_object, get/set_cursor_mode, display_stats, get/set_map_enter_position, attack_is_aimed.
This commit is contained in:
NovaRain
2018-10-10 17:24:05 +08:00
parent a7e492a80f
commit dad0860d6e
14 changed files with 386 additions and 165 deletions
@@ -10,6 +10,12 @@
#define OBJ_TYPE_MISC (5) #define OBJ_TYPE_MISC (5)
#define OBJ_TYPE_SPATIAL (6) #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 */ /* Item Common Flags */
#define HIDDEN_ITEM 134217728 // 0x08000000 - Hidden Item #define HIDDEN_ITEM 134217728 // 0x08000000 - Hidden Item
@@ -39,6 +45,32 @@
#define ATKMODE_SEC_BURST 112 // 0x00000070 #define ATKMODE_SEC_BURST 112 // 0x00000070
#define ATKMODE_SEC_FLAME 128 // 0x00000080 #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 */ /* Critter Flags */
#define CFLG_BARTER 2 // 0x00000002 - Barter (can trade with) #define CFLG_BARTER 2 // 0x00000002 - Barter (can trade with)
#define CFLG_NOSTEAL 32 // 0x00000020 - Steal (cannot steal from) #define CFLG_NOSTEAL 32 // 0x00000020 - Steal (cannot steal from)
+38 -12
View File
@@ -158,6 +158,19 @@
#define GAME_MSG_PRO_TILE (0x1004) #define GAME_MSG_PRO_TILE (0x1004)
#define GAME_MSG_PRO_MISC (0x1005) #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_combat(x) (message_str_game(GAME_MSG_COMBAT, x))
#define mstr_ai(x) (message_str_game(GAME_MSG_AI, x)) #define mstr_ai(x) (message_str_game(GAME_MSG_AI, x))
#define mstr_scrname(x) (message_str_game(GAME_MSG_SCRNAME, 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 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 attack_is_aimed sfall_func0("attack_is_aimed")
#define create_win_flag(winName, x, y, w, h, flag) sfall_func6("create_win", winName, x, y, w, h, flag) #define create_win(winName, x, y, w, h) sfall_func5("create_win", winName, x, y, w, h)
#define critter_inven_obj2(obj, type) sfall_func2("critter_inven_obj2", obj, type) #define create_win_flag(winName, x, y, w, h, flag) sfall_func6("create_win", winName, x, y, w, h, flag)
#define exec_map_update_scripts sfall_func0("exec_map_update_scripts") #define critter_inven_obj2(obj, type) sfall_func2("critter_inven_obj2", obj, type)
#define floor2(value) sfall_func1("floor2", value) #define display_stats sfall_func0("display_stats")
#define get_current_inven_size(obj) sfall_func1("get_current_inven_size", obj) #define exec_map_update_scripts sfall_func0("exec_map_update_scripts")
#define intface_hide sfall_func0("intface_hide") #define floor2(value) sfall_func1("floor2", value)
#define intface_is_hidden sfall_func0("intface_is_hidden") #define get_current_inven_size(obj) sfall_func1("get_current_inven_size", obj)
#define intface_redraw sfall_func0("intface_redraw") #define get_cursor_mode sfall_func0("get_cursor_mode")
#define intface_show sfall_func0("intface_show") #define get_flags(obj) sfall_func1("get_flags", obj)
#define set_ini_setting(setting, value) sfall_func2("set_ini_setting", setting, value) #define get_map_enter_position sfall_func0("get_map_enter_position")
#define spatial_radius(obj) sfall_func1("spatial_radius", obj) #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")
@@ -385,6 +385,54 @@ Some utility/math functions are available:
- works just like vanilla floor function, but returns correct integers for negative values - 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++ - 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) > int sfall_func1("get_current_inven_size", object)
- returns the current inventory size of the container or the critter - returns the current inventory size of the container or the critter
+41 -114
View File
@@ -615,126 +615,56 @@ end:
} }
} }
static void __declspec(naked) DisplayBonusRangedDmg() { static void __declspec(naked) DisplayBonusRangedDmg_hook() {
__asm { __asm {
mov edx, PERK_bonus_ranged_damage mov edx, PERK_bonus_ranged_damage;
mov eax, dword ptr ds:[_stack] mov eax, dword ptr ds:[_stack];
call perk_level_ call perk_level_;
shl eax, 1 shl eax, 1;
add dword ptr [esp+4*4], eax // min_dmg add dword ptr [esp + 4 * 4], eax; // min_dmg + perk bonus
add dword ptr [esp+4*5], eax // max_dmg add dword ptr [esp + 4 * 5], eax; // max_dmg + perk bonus
jmp sprintf_ jmp sprintf_;
} }
} }
static void __declspec(naked) DisplayBonusHtHDmg1() { static void __declspec(naked) DisplayBonusHtHDmg1_hook() {
__asm { __asm {
mov edx, PERK_bonus_hth_damage mov edx, PERK_bonus_hth_damage;
mov eax, dword ptr ds:[_stack] mov eax, dword ptr ds:[_stack];
call perk_level_ call perk_level_;
shl eax, 1 shl eax, 1;
add dword ptr [esp+4*4], eax // min_dmg add dword ptr [esp + 4 * 4], eax; // min_dmg + bonus
jmp sprintf_ jmp sprintf_;
} }
} }
static void __declspec(naked) DisplayBonusHtHDmg2() { static const DWORD DisplayBonusHtHDmg2Exit = 0x472569;
static void __declspec(naked) DisplayBonusHtHDmg2_hack() {
__asm { __asm {
push eax mov ecx, eax;
call stat_level_ call stat_level_;
pop ecx add eax, 2;
add eax, 2 push eax; // max dmg
push eax mov edx, PERK_bonus_hth_damage;
xchg ecx, eax mov eax, ecx;
mov edx, PERK_bonus_hth_damage call perk_level_;
call perk_level_ shl eax, 1;
shl eax, 1 add eax, 1;
add eax, 1 push eax; // min dmg + bonus
push eax mov ecx, dword ptr[esp + 0x98 + 0x4];
mov eax, dword ptr [esp+0x98+0x4] push ecx; // message
push eax push 0x509EDC; // '%s %d-%d'
push 0x509EDC // '%s %d-%d' lea eax, [esp + 0x0C + 0x4];
lea eax, [esp+0xC+0x4] push eax; // buf
push eax call sprintf_;
call sprintf_ add esp, 0x10 + 0x4;
add esp, 4*5 jmp DisplayBonusHtHDmg2Exit;
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;
} }
} }
void AmmoModInit() { void AmmoModInit() {
int formula; int formula;
if (formula=GetPrivateProfileIntA("Misc", "DamageFormula", 0, ini)) { if (formula = GetPrivateProfileIntA("Misc", "DamageFormula", 0, ini)) {
switch (formula) { switch (formula) {
case 1: case 1:
MakeJump(0x424995, DamageFunction1); MakeJump(0x424995, DamageFunction1);
@@ -753,6 +683,7 @@ void AmmoModInit() {
break; break;
} }
} }
int BonusHtHDmgFix = GetPrivateProfileIntA("Misc", "BonusHtHDamageFix", 1, ini); int BonusHtHDmgFix = GetPrivateProfileIntA("Misc", "BonusHtHDamageFix", 1, ini);
int DisplayBonusDmg = GetPrivateProfileIntA("Misc", "DisplayBonusDamage", 0, ini); int DisplayBonusDmg = GetPrivateProfileIntA("Misc", "DisplayBonusDamage", 0, ini);
if (BonusHtHDmgFix) { if (BonusHtHDmgFix) {
@@ -767,17 +698,13 @@ void AmmoModInit() {
MakeJump(0x47854C, HtHDamageFix1b); MakeJump(0x47854C, HtHDamageFix1b);
dlogr(" Done", DL_INIT); 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) { if (DisplayBonusDmg) {
dlog("Applying Display Bonus Damage patch.", DL_INIT); dlog("Applying Display Bonus Damage patch.", DL_INIT);
HookCall(0x4722DD, &DisplayBonusRangedDmg); HookCall(0x4722DD, DisplayBonusRangedDmg_hook);
if (BonusHtHDmgFix) { if (BonusHtHDmgFix) {
HookCall(0x472309, &DisplayBonusHtHDmg1); HookCall(0x472309, DisplayBonusHtHDmg1_hook);
MakeJump(0x472546, DisplayBonusHtHDmg2); MakeJump(0x472546, DisplayBonusHtHDmg2_hack);
} }
dlogr(" Done", DL_INIT); dlogr(" Done", DL_INIT);
} }
+63 -13
View File
@@ -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() { static void __declspec(naked) SharpShooterFix() {
__asm { __asm {
call stat_level_ // Perception call stat_level_ // Perception
@@ -1384,24 +1421,28 @@ fix:
static DWORD op_start_gdialog_ret = 0x456F4B; static DWORD op_start_gdialog_ret = 0x456F4B;
static void __declspec(naked) op_start_gdialog_hack() { static void __declspec(naked) op_start_gdialog_hack() {
__asm { __asm {
mov ebx, ds:[_dialog_target]; cmp eax, -1; // check mood arg
mov ebx, [ebx + 0x64]; jnz useMood;
shr ebx, 0x18; mov eax, dword ptr [esp + 0x3C - 0x30 + 4]; // fix dialog_target (overwritten engine code)
cmp ebx, OBJ_TYPE_CRITTER;
jz fix;
cmp edx, -1;
jz skip;
retn; retn;
fix: useMood:
cmp eax, -1;
jnz skip;
retn;
skip:
add esp, 4; // Destroy the return address add esp, 4; // Destroy the return address
jmp op_start_gdialog_ret; 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() void BugsInit()
{ {
@@ -1415,6 +1456,12 @@ void BugsInit()
SafeWrite16(0x46A566, 0x04DB); SafeWrite16(0x46A566, 0x04DB);
SafeWrite16(0x46A4E7, 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)) { //if (GetPrivateProfileIntA("Misc", "SharpshooterFix", 1, ini)) {
dlog("Applying Sharpshooter patch.", DL_INIT); dlog("Applying Sharpshooter patch.", DL_INIT);
// http://www.nma-fallout.com/threads/fo2-engine-tweaks-sfall.178390/page-119#post-4050162 // 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 // Fix for the "mood" argument of start_gdialog function being ignored for talking heads
if (GetPrivateProfileIntA("Misc", "StartGDialogFix", 0, ini)) { if (GetPrivateProfileIntA("Misc", "StartGDialogFix", 0, ini)) {
dlog("Applying start_gdialog argument fix.", DL_INIT); dlog("Applying start_gdialog argument fix.", DL_INIT);
MakeCall(0x456F03, op_start_gdialog_hack); MakeCall(0x456F08, op_start_gdialog_hack);
dlogr(" Done", DL_INIT); 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);
} }
+5
View File
@@ -57,6 +57,7 @@ DWORD* ptr_dialog_target_is_party = reinterpret_cast<DWORD*>(_dialog_target_
DWORD* ptr_drugInfoList = reinterpret_cast<DWORD*>(_drugInfoList); DWORD* ptr_drugInfoList = reinterpret_cast<DWORD*>(_drugInfoList);
DWORD* ptr_edit_win = reinterpret_cast<DWORD*>(_edit_win); DWORD* ptr_edit_win = reinterpret_cast<DWORD*>(_edit_win);
DWORD* ptr_Educated = reinterpret_cast<DWORD*>(_Educated); DWORD* ptr_Educated = reinterpret_cast<DWORD*>(_Educated);
DWORD* ptr_elevation = reinterpret_cast<DWORD*>(_elevation);
DWORD* ptr_Experience_ = reinterpret_cast<DWORD*>(_Experience_); DWORD* ptr_Experience_ = reinterpret_cast<DWORD*>(_Experience_);
DWORD* ptr_fallout_game_time = reinterpret_cast<DWORD*>(_fallout_game_time); DWORD* ptr_fallout_game_time = reinterpret_cast<DWORD*>(_fallout_game_time);
DWORD* ptr_flptr = reinterpret_cast<DWORD*>(_flptr); DWORD* ptr_flptr = reinterpret_cast<DWORD*>(_flptr);
@@ -167,6 +168,7 @@ DWORD* ptr_quick_done = reinterpret_cast<DWORD*>(_quick_done);
DWORD* ptr_read_callback = reinterpret_cast<DWORD*>(_read_callback); DWORD* ptr_read_callback = reinterpret_cast<DWORD*>(_read_callback);
DWORD* ptr_RedColor = reinterpret_cast<DWORD*>(_RedColor); DWORD* ptr_RedColor = reinterpret_cast<DWORD*>(_RedColor);
DWORD* ptr_retvals = reinterpret_cast<DWORD*>(_retvals); DWORD* ptr_retvals = reinterpret_cast<DWORD*>(_retvals);
DWORD* ptr_rotation = reinterpret_cast<DWORD*>(_rotation);
DWORD* ptr_scr_size = reinterpret_cast<DWORD*>(_scr_size); DWORD* ptr_scr_size = reinterpret_cast<DWORD*>(_scr_size);
DWORD* ptr_scriptListInfo = reinterpret_cast<DWORD*>(_scriptListInfo); DWORD* ptr_scriptListInfo = reinterpret_cast<DWORD*>(_scriptListInfo);
DWORD* ptr_skill_data = reinterpret_cast<DWORD*>(_skill_data); DWORD* ptr_skill_data = reinterpret_cast<DWORD*>(_skill_data);
@@ -196,6 +198,7 @@ DWORD* ptr_text_mono_width = reinterpret_cast<DWORD*>(_text_mono_widt
DWORD* ptr_text_spacing = reinterpret_cast<DWORD*>(_text_spacing); DWORD* ptr_text_spacing = reinterpret_cast<DWORD*>(_text_spacing);
DWORD* ptr_text_to_buf = reinterpret_cast<DWORD*>(_text_to_buf); DWORD* ptr_text_to_buf = reinterpret_cast<DWORD*>(_text_to_buf);
DWORD* ptr_text_width = reinterpret_cast<DWORD*>(_text_width); DWORD* ptr_text_width = reinterpret_cast<DWORD*>(_text_width);
DWORD* ptr_tile = reinterpret_cast<DWORD*>(_tile);
DWORD* ptr_title_color = reinterpret_cast<DWORD*>(_title_color); DWORD* ptr_title_color = reinterpret_cast<DWORD*>(_title_color);
DWORD* ptr_title_font = reinterpret_cast<DWORD*>(_title_font); DWORD* ptr_title_font = reinterpret_cast<DWORD*>(_title_font);
DWORD* ptr_trait_data = reinterpret_cast<DWORD*>(_trait_data); DWORD* ptr_trait_data = reinterpret_cast<DWORD*>(_trait_data);
@@ -353,6 +356,8 @@ const DWORD GetSlotList_ = 0x47E5D0;
const DWORD get_input_ = 0x4C8B78; const DWORD get_input_ = 0x4C8B78;
const DWORD get_time_ = 0x4C9370; 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 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_is_scrolling_ = 0x44B54C;
const DWORD gmouse_set_cursor_ = 0x44C840; const DWORD gmouse_set_cursor_ = 0x44C840;
const DWORD GNW_find_ = 0x4D7888; const DWORD GNW_find_ = 0x4D7888;
+8
View File
@@ -66,6 +66,7 @@
#define _drugInfoList 0x5191CC #define _drugInfoList 0x5191CC
#define _edit_win 0x57060C #define _edit_win 0x57060C
#define _Educated 0x57082C #define _Educated 0x57082C
#define _elevation 0x631D2C
#define _Experience_ 0x6681B4 #define _Experience_ 0x6681B4
#define _fallout_game_time 0x51C720 #define _fallout_game_time 0x51C720
#define _flptr 0x614808 #define _flptr 0x614808
@@ -184,6 +185,7 @@
#define _read_callback 0x51DEEC #define _read_callback 0x51DEEC
#define _RedColor 0x6AB4D0 #define _RedColor 0x6AB4D0
#define _retvals 0x43EA7C #define _retvals 0x43EA7C
#define _rotation 0x631D34
#define _sad 0x530014 #define _sad 0x530014
#define _scr_size 0x6AC9F0 #define _scr_size 0x6AC9F0
#define _scriptListInfo 0x51C7C8 #define _scriptListInfo 0x51C7C8
@@ -215,6 +217,7 @@
#define _text_spacing 0x51E3CC #define _text_spacing 0x51E3CC
#define _text_to_buf 0x51E3B8 #define _text_to_buf 0x51E3B8
#define _text_width 0x51E3C0 #define _text_width 0x51E3C0
#define _tile 0x631D30
#define _title_color 0x56D750 #define _title_color 0x56D750
#define _title_font 0x56D748 #define _title_font 0x56D748
#define _trait_data 0x51DB84 #define _trait_data 0x51DB84
@@ -266,6 +269,7 @@ extern DWORD* ptr_dialog_target_is_party;
extern DWORD* ptr_drugInfoList; extern DWORD* ptr_drugInfoList;
extern DWORD* ptr_edit_win; extern DWORD* ptr_edit_win;
extern DWORD* ptr_Educated; extern DWORD* ptr_Educated;
extern DWORD* ptr_elevation;
extern DWORD* ptr_Experience_; extern DWORD* ptr_Experience_;
extern DWORD* ptr_fallout_game_time; extern DWORD* ptr_fallout_game_time;
extern DWORD* ptr_flptr; extern DWORD* ptr_flptr;
@@ -376,6 +380,7 @@ extern DWORD* ptr_quick_done;
extern DWORD* ptr_read_callback; extern DWORD* ptr_read_callback;
extern DWORD* ptr_RedColor; extern DWORD* ptr_RedColor;
extern DWORD* ptr_retvals; extern DWORD* ptr_retvals;
extern DWORD* ptr_rotation;
extern DWORD* ptr_sad; extern DWORD* ptr_sad;
extern DWORD* ptr_scr_size; extern DWORD* ptr_scr_size;
extern DWORD* ptr_scriptListInfo; extern DWORD* ptr_scriptListInfo;
@@ -406,6 +411,7 @@ extern DWORD* ptr_text_mono_width;
extern DWORD* ptr_text_spacing; extern DWORD* ptr_text_spacing;
extern DWORD* ptr_text_to_buf; extern DWORD* ptr_text_to_buf;
extern DWORD* ptr_text_width; extern DWORD* ptr_text_width;
extern DWORD* ptr_tile;
extern DWORD* ptr_title_color; extern DWORD* ptr_title_color;
extern DWORD* ptr_title_font; extern DWORD* ptr_title_font;
extern DWORD* ptr_trait_data; extern DWORD* ptr_trait_data;
@@ -543,6 +549,8 @@ extern const DWORD GetSlotList_;
extern const DWORD get_input_; extern const DWORD get_input_;
extern const DWORD get_time_; extern const DWORD get_time_;
extern const DWORD getmsg_; 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_is_scrolling_;
extern const DWORD gmouse_set_cursor_; extern const DWORD gmouse_set_cursor_;
extern const DWORD GNW_find_; extern const DWORD GNW_find_;
+4 -2
View File
@@ -116,9 +116,11 @@ struct TScript
TGameObj *self_obj; TGameObj *self_obj;
TGameObj *source_obj; TGameObj *source_obj;
TGameObj *target_obj; TGameObj *target_obj;
long action_num;
long script_overrides; long script_overrides;
char field_44; char gap_48[4];
char gap_45[15]; long how_much;
char gap_50[4];
long procedure_table[28]; long procedure_table[28];
}; };
#pragma pack(pop) #pragma pack(pop)
+5 -5
View File
@@ -604,9 +604,9 @@ static void __declspec(naked) HeaveHoHook() {
call stat_level_; call stat_level_;
lea ebx, [0+eax*4]; lea ebx, [0+eax*4];
sub ebx, eax; sub ebx, eax;
cmp ebx, esi; cmp ebx, esi; // ebx = dist (3*ST), esi = max dist weapon
jle lower; jle lower; // jump if dist <= max
mov ebx, esi; mov ebx, esi; // dist = max
lower: lower:
mov eax, ecx; mov eax, ecx;
mov edx, PERK_heave_ho; mov edx, PERK_heave_ho;
@@ -615,12 +615,12 @@ lower:
sub ecx, eax; sub ecx, eax;
sub ecx, eax; sub ecx, eax;
mov eax, ecx; mov eax, ecx;
add eax, ebx; add eax, ebx; // distance = dist + (PERK_heave_ho * 6)
push 0x478AFC; push 0x478AFC;
retn; retn;
} }
} }
void _stdcall ApplyHeaveHoFix() { void _stdcall ApplyHeaveHoFix() { // not really a fix
MakeJump(0x478AC4, HeaveHoHook); MakeJump(0x478AC4, HeaveHoHook);
Perks[PERK_heave_ho].Str = 0; Perks[PERK_heave_ho].Str = 0;
} }
+32 -3
View File
@@ -20,6 +20,7 @@
#include "main.h" #include "main.h"
#include "input.h" #include "input.h"
#include "LoadGameHook.h"
#include "ScriptExtender.h" #include "ScriptExtender.h"
@@ -452,22 +453,50 @@ static void sf_intface_redraw() {
} }
static void sf_intface_show() { static void sf_intface_show() {
__asm call intface_show_ __asm call intface_show_;
} }
static void sf_intface_hide() { static void sf_intface_hide() {
__asm call intface_hide_ __asm call intface_hide_;
} }
static void sf_intface_is_hidden() { static void sf_intface_is_hidden() {
int isHidden; int isHidden;
__asm { __asm {
call intface_is_hidden_ call intface_is_hidden_;
mov isHidden, eax; mov isHidden, eax;
} }
opHandler.setReturn(isHidden); 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() { static void sf_create_win() {
int flags; int flags;
if (opHandler.numArgs() == 6) { if (opHandler.numArgs() == 6) {
+15
View File
@@ -103,18 +103,31 @@ static void sf_get_metarule_table() {
- minArgs/maxArgs - minimum and maximum number of arguments allowed for this function - minArgs/maxArgs - minimum and maximum number of arguments allowed for this function
*/ */
static const SfallMetarule metaruleArray[] = { static const SfallMetarule metaruleArray[] = {
{"attack_is_aimed", sf_attack_is_aimed, 0, 0},
{"critter_inven_obj2", sf_critter_inven_obj2, 2, 2}, {"critter_inven_obj2", sf_critter_inven_obj2, 2, 2},
{"create_win", sf_create_win, 5, 6}, {"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}, {"exec_map_update_scripts", sf_exec_map_update_scripts, 0, 0},
{"floor2", sf_floor2, 1, 1}, {"floor2", sf_floor2, 1, 1},
{"get_current_inven_size", sf_get_current_inven_size, 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_metarule_table", sf_get_metarule_table, 0, 0},
{"get_outline", sf_get_outline, 1, 1},
{"intface_hide", sf_intface_hide, 0, 0}, {"intface_hide", sf_intface_hide, 0, 0},
{"intface_is_hidden", sf_intface_is_hidden, 0, 0}, {"intface_is_hidden", sf_intface_is_hidden, 0, 0},
{"intface_redraw", sf_intface_redraw, 0, 0}, {"intface_redraw", sf_intface_redraw, 0, 0},
{"intface_show", sf_intface_show, 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_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}, {"spatial_radius", sf_spatial_radius, 1, 1},
{"tile_refresh_display", sf_tile_refresh_display, 0, 0},
{"validate_test", sf_test, 2, 5}, {"validate_test", sf_test, 2, 5},
}; };
@@ -163,6 +176,8 @@ static void _stdcall op_sfall_metarule_handler() {
opHandler.setArgShift(1); opHandler.setArgShift(1);
if (ValidateMetaruleArguments(currentMetarule)) { if (ValidateMetaruleArguments(currentMetarule)) {
currentMetarule->func(); currentMetarule->func();
} else {
opHandler.setReturn(-1);
} }
} else { } else {
opHandler.printOpcodeError("sfall_funcX(name, ...) - name '%s' is unknown.", name); opHandler.printOpcodeError("sfall_funcX(name, ...) - name '%s' is unknown.", name);
+32 -10
View File
@@ -1286,19 +1286,27 @@ static void __declspec(naked) refresh_pc_art() {
retn; 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() { static void __declspec(naked) get_attack_type() {
__asm { __asm {
push edx; push edx;
push ecx; push ecx;
push eax; push eax;
sub esp, 8; call intface_attack_type;
lea edx, [esp]; mov edx, ecx; // hit_mode
lea eax, [esp+4];
call intface_get_attack_;
add esp, 4; // is_secondary
test eax, eax; test eax, eax;
jz skip; jz skip;
add esp, 4;
// get reload // get reload
cmp ds:[_interfaceWindow], eax; cmp ds:[_interfaceWindow], eax;
jz end; jz end;
@@ -1307,17 +1315,21 @@ static void __declspec(naked) get_attack_type() {
cmp ds:[_itemButtonItems+5+edx], 1; // .itsWeapon cmp ds:[_itemButtonItems+5+edx], 1; // .itsWeapon
jnz end; jnz end;
lea eax, [ecx+6]; lea eax, [ecx+6];
jmp end;
skip:
pop eax; // hit_mode
end: end:
mov edx, eax; // result
skip:
pop ecx; pop ecx;
_RET_VAL_INT(ecx); mov eax, ecx;
call interpretPushLong_;
mov eax, ecx;
mov edx, VAR_TYPE_INT;
call interpretPushShort_;
pop ecx; pop ecx;
pop edx; pop edx;
retn; retn;
} }
} }
static void __declspec(naked) play_sfall_sound() { static void __declspec(naked) play_sfall_sound() {
__asm { __asm {
pushad pushad
@@ -1641,6 +1653,16 @@ end:
_OP_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() { static void sf_exec_map_update_scripts() {
__asm call scr_exec_map_update_scripts_ __asm call scr_exec_map_update_scripts_
} }
+38 -6
View File
@@ -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() { static void sf_get_current_inven_size() {
TGameObj* invenObj = opHandler.arg(0).asObject(); opHandler.setReturn(sf_item_total_size(opHandler.arg(0).asObject()), DATATYPE_INT);
if (invenObj != nullptr) {
opHandler.setReturn(sf_item_total_size(invenObj), DATATYPE_INT);
} else {
opHandler.setReturn(-1, DATATYPE_INT);
}
} }
+25
View File
@@ -19,6 +19,7 @@
#pragma once #pragma once
#include "main.h" #include "main.h"
#include "Arrays.h"
#include "ScriptExtender.h" #include "ScriptExtender.h"
@@ -209,3 +210,27 @@ end:
retn; 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);
}