mirror of
https://github.com/sfall-team/sfall.git
synced 2026-07-27 16:52:34 -07:00
Added FastMoveFromContainer as the auxiliary option for ItemFastMoveKey (from Mr.Stalin)
Refactored the code of StackEmptyWeapons. Added missing argument validation for backported script functions.
This commit is contained in:
@@ -161,6 +161,10 @@ ReloadWeaponKey=0
|
|||||||
;Set to 0 if you don't want to use a modifier key, or a DX scancode otherwise
|
;Set to 0 if you don't want to use a modifier key, or a DX scancode otherwise
|
||||||
ItemFastMoveKey=0x1d
|
ItemFastMoveKey=0x1d
|
||||||
|
|
||||||
|
;Set to 1 to skip the 'Move Items' window when taking items from containers or corpses and not holding down ItemFastMoveKey
|
||||||
|
;Requires ItemFastMoveKey to be enabled
|
||||||
|
FastMoveFromContainer=0
|
||||||
|
|
||||||
;A key to press to open a debug game editor (requires FalloutClient.exe from the modders pack)
|
;A key to press to open a debug game editor (requires FalloutClient.exe from the modders pack)
|
||||||
;Set to 0 to disable, or a DX scancode otherwise
|
;Set to 0 to disable, or a DX scancode otherwise
|
||||||
DebugEditorKey=0
|
DebugEditorKey=0
|
||||||
|
|||||||
+1
-1
@@ -1436,7 +1436,7 @@ static void __declspec(naked) item_w_range_hook() {
|
|||||||
call stat_level_; // get ST
|
call stat_level_; // get ST
|
||||||
lea ecx, [eax + ebx]; // ebx - bonus from "Heave Ho!"
|
lea ecx, [eax + ebx]; // ebx - bonus from "Heave Ho!"
|
||||||
sub ecx, 10; // compare ST + bonus <= 10
|
sub ecx, 10; // compare ST + bonus <= 10
|
||||||
jbe skip;
|
jle skip;
|
||||||
sub ebx, ecx; // cutoff
|
sub ebx, ecx; // cutoff
|
||||||
skip:
|
skip:
|
||||||
retn;
|
retn;
|
||||||
|
|||||||
+104
-95
@@ -34,6 +34,7 @@ static DWORD sizeLimitMode;
|
|||||||
static DWORD invSizeMaxLimit;
|
static DWORD invSizeMaxLimit;
|
||||||
static DWORD ReloadWeaponKey = 0;
|
static DWORD ReloadWeaponKey = 0;
|
||||||
static DWORD ItemFastMoveKey = 0;
|
static DWORD ItemFastMoveKey = 0;
|
||||||
|
static DWORD SkipFromContainer = 0;
|
||||||
|
|
||||||
struct sMessage {
|
struct sMessage {
|
||||||
DWORD number;
|
DWORD number;
|
||||||
@@ -413,20 +414,20 @@ end:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int invenapcost;
|
static int invenApCost, invenApCostDef;
|
||||||
static char invenapqpreduction;
|
static char invenApQPReduction;
|
||||||
void _stdcall SetInvenApCost(int a) {
|
void _stdcall SetInvenApCost(int cost) {
|
||||||
invenapcost = a;
|
invenApCost = cost;
|
||||||
}
|
}
|
||||||
static const DWORD inven_ap_cost_hook_ret = 0x46E816;
|
static const DWORD inven_ap_cost_hack_ret = 0x46E816;
|
||||||
static void __declspec(naked) inven_ap_cost_hook() {
|
static void __declspec(naked) inven_ap_cost_hack() {
|
||||||
_asm {
|
_asm {
|
||||||
movzx ebx, byte ptr invenapqpreduction;
|
movzx ebx, byte ptr invenApQPReduction;
|
||||||
mul bl;
|
mul bl;
|
||||||
mov edx, invenapcost;
|
mov edx, invenApCost;
|
||||||
sub edx, eax;
|
sub edx, eax;
|
||||||
mov eax, edx;
|
mov eax, edx;
|
||||||
jmp inven_ap_cost_hook_ret;
|
jmp inven_ap_cost_hack_ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -434,31 +435,31 @@ static const DWORD add_check_for_item_ammo_cost_back = 0x4266EE;
|
|||||||
// adds check for weapons which require more than 1 ammo for single shot (super cattle prod & mega power fist)
|
// adds check for weapons which require more than 1 ammo for single shot (super cattle prod & mega power fist)
|
||||||
static void __declspec(naked) add_check_for_item_ammo_cost() {
|
static void __declspec(naked) add_check_for_item_ammo_cost() {
|
||||||
__asm {
|
__asm {
|
||||||
push edx
|
push edx
|
||||||
push ebx
|
push ebx
|
||||||
sub esp, 4
|
sub esp, 4
|
||||||
call item_w_cur_ammo_
|
call item_w_cur_ammo_
|
||||||
mov ebx, eax
|
mov ebx, eax
|
||||||
mov eax, ecx // weapon
|
mov eax, ecx // weapon
|
||||||
mov edx, esp
|
mov edx, esp
|
||||||
mov dword ptr [esp], 1
|
mov dword ptr [esp], 1
|
||||||
pushad
|
pushad
|
||||||
push 1 // hook type
|
push 1 // hook type
|
||||||
call AmmoCostHookWrapper
|
call AmmoCostHookWrapper
|
||||||
add esp, 4
|
add esp, 4
|
||||||
popad
|
popad
|
||||||
mov eax, [esp]
|
mov eax, [esp]
|
||||||
cmp eax, ebx
|
cmp eax, ebx
|
||||||
jle enoughammo
|
jle enoughammo
|
||||||
xor eax, eax // this will force "Out of ammo"
|
xor eax, eax // this will force "Out of ammo"
|
||||||
jmp end
|
jmp end
|
||||||
enoughammo:
|
enoughammo:
|
||||||
mov eax, 1 // this will force success
|
mov eax, 1 // this will force success
|
||||||
end:
|
end:
|
||||||
add esp, 4
|
add esp, 4
|
||||||
pop ebx
|
pop ebx
|
||||||
pop edx
|
pop edx
|
||||||
jmp add_check_for_item_ammo_cost_back; // jump back
|
jmp add_check_for_item_ammo_cost_back; // jump back
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -467,74 +468,72 @@ static void __declspec(naked) divide_burst_rounds_by_ammo_cost() {
|
|||||||
__asm {
|
__asm {
|
||||||
// ecx - current ammo, eax - burst rounds; need to set ebp
|
// ecx - current ammo, eax - burst rounds; need to set ebp
|
||||||
push edx
|
push edx
|
||||||
sub esp, 4
|
sub esp, 4
|
||||||
mov ebp, eax
|
mov ebp, eax
|
||||||
mov eax, edx // weapon
|
mov eax, edx // weapon
|
||||||
mov dword ptr [esp], 1
|
mov dword ptr [esp], 1
|
||||||
mov edx, esp // *rounds
|
mov edx, esp // *rounds
|
||||||
pushad
|
pushad
|
||||||
push 2
|
push 2
|
||||||
call AmmoCostHookWrapper
|
call AmmoCostHookWrapper
|
||||||
add esp, 4
|
add esp, 4
|
||||||
popad
|
popad
|
||||||
mov edx, 0
|
mov edx, 0
|
||||||
mov eax, ebp // rounds in burst
|
mov eax, ebp // rounds in burst
|
||||||
imul dword ptr [esp] // so much ammo is required for this burst
|
imul dword ptr [esp] // so much ammo is required for this burst
|
||||||
cmp eax, ecx
|
cmp eax, ecx
|
||||||
jle skip
|
jle skip
|
||||||
mov eax, ecx // if more than current ammo, set it to current
|
mov eax, ecx // if more than current ammo, set it to current
|
||||||
skip:
|
skip:
|
||||||
idiv dword ptr [esp] // divide back to get proper number of rounds for damage calculations
|
idiv dword ptr [esp] // divide back to get proper number of rounds for damage calculations
|
||||||
mov ebp, eax
|
mov ebp, eax
|
||||||
add esp, 4
|
add esp, 4
|
||||||
pop edx
|
pop edx
|
||||||
// end overwriten code
|
// end overwriten code
|
||||||
jmp divide_burst_rounds_by_ammo_cost_back; // jump back
|
jmp divide_burst_rounds_by_ammo_cost_back; // jump back
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __declspec(naked) SetDefaultAmmo() {
|
static void __declspec(naked) SetDefaultAmmo() {
|
||||||
__asm {
|
__asm {
|
||||||
push eax
|
push ecx;
|
||||||
push ebx
|
mov ecx, edx; // ecx = item
|
||||||
push edx
|
mov eax, edx;
|
||||||
xchg eax, edx
|
call item_get_type_;
|
||||||
mov ebx, eax
|
cmp eax, item_type_weapon; // is it item_type_weapon?
|
||||||
call item_get_type_
|
jne end; // no
|
||||||
cmp eax, item_type_weapon // is it item_type_weapon?
|
cmp dword ptr [ecx + 0x3C], 0; // is there any ammo in the weapon?
|
||||||
jne end // no
|
jne end; // yes
|
||||||
cmp dword ptr [ebx+0x3C], 0 // is there any ammo in the weapon?
|
sub esp, 4;
|
||||||
jne end // yes
|
mov edx, esp;
|
||||||
sub esp, 4
|
mov eax, [ecx + 0x64]; // eax = weapon pid
|
||||||
mov edx, esp
|
call proto_ptr_;
|
||||||
mov eax, [ebx+0x64] // eax = weapon pid
|
mov edx, [esp];
|
||||||
call proto_ptr_
|
mov eax, [edx + 0x5C]; // eax = default ammo pid
|
||||||
mov edx, [esp]
|
mov [ecx + 0x40], eax; // set current ammo proto
|
||||||
mov eax, [edx+0x5C] // eax = default ammo pid
|
add esp, 4;
|
||||||
mov [ebx+0x40], eax // set current ammo proto
|
|
||||||
add esp, 4
|
|
||||||
end:
|
end:
|
||||||
pop edx
|
pop ecx;
|
||||||
pop ebx
|
retn;
|
||||||
pop eax
|
|
||||||
retn
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static const DWORD inven_action_cursor_hack_End = 0x4736CB;
|
|
||||||
static void __declspec(naked) inven_action_cursor_hack() {
|
static void __declspec(naked) inven_action_cursor_hack() {
|
||||||
__asm {
|
__asm {
|
||||||
mov edx, [esp+0x1C]
|
mov edx, [esp + 0x6C - 0x50 + 4]; // source_item
|
||||||
call SetDefaultAmmo
|
call SetDefaultAmmo;
|
||||||
cmp dword ptr [esp+0x18], 0
|
cmp dword ptr [esp + 0x6C - 0x54 + 4], 0; // overwritten engine code
|
||||||
jmp inven_action_cursor_hack_End
|
retn;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __declspec(naked) item_add_mult_hook() {
|
static void __declspec(naked) item_add_mult_hook() {
|
||||||
__asm {
|
__asm {
|
||||||
call SetDefaultAmmo
|
push edx;
|
||||||
jmp item_add_force_
|
call SetDefaultAmmo;
|
||||||
|
pop edx;
|
||||||
|
mov eax, ecx; // restore
|
||||||
|
jmp item_add_force_;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -565,7 +564,7 @@ end:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __declspec(naked) loot_container_hack2() {
|
static void __declspec(naked) loot_container_hack_scroll() {
|
||||||
__asm {
|
__asm {
|
||||||
cmp esi, 0x150 // source_down
|
cmp esi, 0x150 // source_down
|
||||||
je scroll
|
je scroll
|
||||||
@@ -603,7 +602,7 @@ end:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __declspec(naked) barter_inventory_hack2() {
|
static void __declspec(naked) barter_inventory_hack_scroll() {
|
||||||
__asm {
|
__asm {
|
||||||
push edx
|
push edx
|
||||||
push ecx
|
push ecx
|
||||||
@@ -685,24 +684,31 @@ end:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void __declspec(naked) do_move_timer_hook() {
|
static const DWORD DoMoveTimer_Ret = 0x476920;
|
||||||
|
static void __declspec(naked) do_move_timer_hook() {
|
||||||
__asm {
|
__asm {
|
||||||
cmp eax, 4;
|
cmp eax, 4;
|
||||||
jnz end;
|
jnz end;
|
||||||
pushad;
|
pushad;
|
||||||
}
|
}
|
||||||
|
|
||||||
KeyDown(ItemFastMoveKey);
|
KeyDown(ItemFastMoveKey); // check pressed
|
||||||
|
|
||||||
__asm {
|
__asm {
|
||||||
|
cmp SkipFromContainer, 0;
|
||||||
|
jz noSkip;
|
||||||
|
cmp dword ptr [esp + 0x14 + 36], 0x474A43;
|
||||||
|
jnz noSkip;
|
||||||
test eax, eax;
|
test eax, eax;
|
||||||
|
setz al;
|
||||||
|
noSkip:
|
||||||
|
test eax, eax; // set if pressed
|
||||||
popad;
|
popad;
|
||||||
jz end;
|
jz end;
|
||||||
mov dword ptr [esp], 0x476920;
|
add esp, 4; // destroy ret
|
||||||
retn;
|
jmp DoMoveTimer_Ret;
|
||||||
end:
|
end:
|
||||||
call setup_move_timer_win_;
|
jmp setup_move_timer_win_;
|
||||||
retn;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -758,9 +764,9 @@ void InventoryInit() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
invenapcost = GetPrivateProfileInt("Misc", "InventoryApCost", 4, ini);
|
invenApCost = invenApCostDef = GetPrivateProfileInt("Misc", "InventoryApCost", 4, ini);
|
||||||
invenapqpreduction = GetPrivateProfileInt("Misc", "QuickPocketsApCostReduction", 2, ini);
|
invenApQPReduction = GetPrivateProfileInt("Misc", "QuickPocketsApCostReduction", 2, ini);
|
||||||
MakeJump(0x46E80B, inven_ap_cost_hook);
|
MakeJump(0x46E80B, inven_ap_cost_hack);
|
||||||
|
|
||||||
if(GetPrivateProfileInt("Misc", "SuperStimExploitFix", 0, ini)) {
|
if(GetPrivateProfileInt("Misc", "SuperStimExploitFix", 0, ini)) {
|
||||||
GetPrivateProfileString("sfall", "SuperStimExploitMsg", "You cannot use a super stim on someone who is not injured!", SuperStimMsg, 128, translationIni);
|
GetPrivateProfileString("sfall", "SuperStimExploitMsg", "You cannot use a super stim on someone who is not injured!", SuperStimMsg, 128, translationIni);
|
||||||
@@ -775,8 +781,8 @@ void InventoryInit() {
|
|||||||
ReloadWeaponKey = GetPrivateProfileInt("Input", "ReloadWeaponKey", 0, ini);
|
ReloadWeaponKey = GetPrivateProfileInt("Input", "ReloadWeaponKey", 0, ini);
|
||||||
|
|
||||||
if (GetPrivateProfileIntA("Misc", "StackEmptyWeapons", 0, ini)) {
|
if (GetPrivateProfileIntA("Misc", "StackEmptyWeapons", 0, ini)) {
|
||||||
MakeJump(0x4736C6, inven_action_cursor_hack);
|
MakeCall(0x4736C6, inven_action_cursor_hack);
|
||||||
HookCall(0x4772AA, &item_add_mult_hook);
|
HookCall(0x4772AA, item_add_mult_hook);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Do not call the 'Move Items' window when using drap and drop to reload weapons in the inventory
|
// Do not call the 'Move Items' window when using drap and drop to reload weapons in the inventory
|
||||||
@@ -791,6 +797,8 @@ void InventoryInit() {
|
|||||||
ItemFastMoveKey = GetPrivateProfileIntA("Input", "ItemFastMoveKey", DIK_LCONTROL, ini);
|
ItemFastMoveKey = GetPrivateProfileIntA("Input", "ItemFastMoveKey", DIK_LCONTROL, ini);
|
||||||
if (ItemFastMoveKey > 0) {
|
if (ItemFastMoveKey > 0) {
|
||||||
HookCall(0x476897, do_move_timer_hook);
|
HookCall(0x476897, do_move_timer_hook);
|
||||||
|
// Do not call the 'Move Items' window when taking items from containers or corpses
|
||||||
|
SkipFromContainer = GetPrivateProfileIntA("Input", "FastMoveFromContainer", 0, ini);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GetPrivateProfileIntA("Misc", "ItemCounterDefaultMax", 0, ini)) {
|
if (GetPrivateProfileIntA("Misc", "ItemCounterDefaultMax", 0, ini)) {
|
||||||
@@ -806,11 +814,12 @@ void InventoryInit() {
|
|||||||
|
|
||||||
// Enable mouse scroll control in barter and loot screens when the cursor is hovering over other lists
|
// Enable mouse scroll control in barter and loot screens when the cursor is hovering over other lists
|
||||||
if (UseScrollWheel) {
|
if (UseScrollWheel) {
|
||||||
MakeCall(0x473E66, loot_container_hack2);
|
MakeCall(0x473E66, loot_container_hack_scroll);
|
||||||
MakeCall(0x4759F1, barter_inventory_hack2);
|
MakeCall(0x4759F1, barter_inventory_hack_scroll);
|
||||||
*((DWORD*)_max) = 100;
|
*((DWORD*)_max) = 100;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
void InventoryReset() {
|
void InventoryReset() {
|
||||||
invenapcost=GetPrivateProfileInt("Misc", "InventoryApCost", 4, ini);
|
invenApCost = invenApCostDef;
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -18,7 +18,7 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
void _stdcall SetInvenApCost(int a);
|
void _stdcall SetInvenApCost(int cost);
|
||||||
DWORD __stdcall sf_item_total_size(TGameObj* critter);
|
DWORD __stdcall sf_item_total_size(TGameObj* critter);
|
||||||
void InventoryInit();
|
void InventoryInit();
|
||||||
void InventoryReset();
|
void InventoryReset();
|
||||||
|
|||||||
@@ -373,7 +373,15 @@ static OpcodeHandler opHandler;
|
|||||||
static const SfallOpcodeMetadata opcodeMetaArray[] = {
|
static const SfallOpcodeMetadata opcodeMetaArray[] = {
|
||||||
{sf_create_win, "create_win", {DATATYPE_MASK_STR, DATATYPE_MASK_INT, DATATYPE_MASK_INT, DATATYPE_MASK_INT, DATATYPE_MASK_INT, DATATYPE_MASK_INT}},
|
{sf_create_win, "create_win", {DATATYPE_MASK_STR, DATATYPE_MASK_INT, DATATYPE_MASK_INT, DATATYPE_MASK_INT, DATATYPE_MASK_INT, DATATYPE_MASK_INT}},
|
||||||
{sf_critter_inven_obj2, "critter_inven_obj2", {DATATYPE_MASK_VALID_OBJ, DATATYPE_MASK_INT}},
|
{sf_critter_inven_obj2, "critter_inven_obj2", {DATATYPE_MASK_VALID_OBJ, DATATYPE_MASK_INT}},
|
||||||
|
{sf_get_current_inven_size, "get_current_inven_size", {DATATYPE_MASK_VALID_OBJ}},
|
||||||
|
{sf_get_flags, "get_flags", {DATATYPE_MASK_VALID_OBJ}},
|
||||||
|
{sf_get_outline, "get_outline", {DATATYPE_MASK_VALID_OBJ}},
|
||||||
|
{sf_item_weight, "item_weight", {DATATYPE_MASK_VALID_OBJ}},
|
||||||
|
{sf_set_cursor_mode, "set_cursor_mode", {DATATYPE_MASK_INT}},
|
||||||
|
{sf_set_flags, "set_flags", {DATATYPE_MASK_VALID_OBJ, DATATYPE_MASK_INT}},
|
||||||
{sf_set_ini_setting, "set_ini_setting", {DATATYPE_MASK_STR, DATATYPE_MASK_INT | DATATYPE_MASK_STR}},
|
{sf_set_ini_setting, "set_ini_setting", {DATATYPE_MASK_STR, DATATYPE_MASK_INT | DATATYPE_MASK_STR}},
|
||||||
|
{sf_set_map_enter_position, "set_map_enter_position", {DATATYPE_MASK_INT, DATATYPE_MASK_INT, DATATYPE_MASK_INT}},
|
||||||
|
{sf_set_outline, "set_outline", {DATATYPE_MASK_VALID_OBJ, DATATYPE_MASK_INT}},
|
||||||
{sf_spatial_radius, "spatial_radius", {DATATYPE_MASK_VALID_OBJ}},
|
{sf_spatial_radius, "spatial_radius", {DATATYPE_MASK_VALID_OBJ}},
|
||||||
{sf_test, "validate_test", {DATATYPE_MASK_INT, DATATYPE_MASK_INT | DATATYPE_MASK_FLOAT, DATATYPE_MASK_STR, DATATYPE_NONE}},
|
{sf_test, "validate_test", {DATATYPE_MASK_INT, DATATYPE_MASK_INT | DATATYPE_MASK_FLOAT, DATATYPE_MASK_STR, DATATYPE_NONE}},
|
||||||
//{op_message_str_game, {}}
|
//{op_message_str_game, {}}
|
||||||
|
|||||||
Reference in New Issue
Block a user