diff --git a/artifacts/scripting/headers/define_extra.h b/artifacts/scripting/headers/define_extra.h
index 87e32ba6..346b701b 100644
--- a/artifacts/scripting/headers/define_extra.h
+++ b/artifacts/scripting/headers/define_extra.h
@@ -361,6 +361,7 @@
#define ai_chem_always (5)
// common object data offsets
+#define OBJ_DATA_ID (0x00)
#define OBJ_DATA_TILENUM (0x04)
#define OBJ_DATA_CUR_FRM (0x18) // current frame number
#define OBJ_DATA_ROTATION (0x1C)
diff --git a/artifacts/scripting/headers/sfall.h b/artifacts/scripting/headers/sfall.h
index 16aece47..145d50bc 100644
--- a/artifacts/scripting/headers/sfall.h
+++ b/artifacts/scripting/headers/sfall.h
@@ -288,6 +288,7 @@
#define set_outline(obj, color) sfall_func2("set_outline", obj, color)
#define set_rest_heal_time(time) sfall_func1("set_rest_heal_time", time)
#define set_rest_mode(mode) sfall_func1("set_rest_mode", mode)
+#define set_unique_id(object) sfall_func1("set_unique_id", object)
#define set_unjam_locks_time(time) sfall_func1("set_unjam_locks_time", time)
#define spatial_radius(obj) sfall_func1("spatial_radius", obj)
#define tile_refresh_display sfall_func0("tile_refresh_display")
diff --git a/artifacts/scripting/hookscripts.txt b/artifacts/scripting/hookscripts.txt
index 7ad52661..923f0326 100644
--- a/artifacts/scripting/hookscripts.txt
+++ b/artifacts/scripting/hookscripts.txt
@@ -416,17 +416,16 @@ HOOK_INVENTORYMOVE (hs_inventorymove.int)
Runs before moving items between inventory slots in dude interface. You can override the action.
What you can NOT do with this hook:
- force moving items to inappropriate slots (like gun in armor slot)
-- block picking up items
What you can do:
- restrict player from using specific weapons or armors
- add AP costs for all inventory movement including reloading
- apply or remove some special scripted effects depending on PC's armor
-int arg1 - Target slot (0 - main backpack, 1 - left hand, 2 - right hand, 3 - armor slot, 4 - weapon, when reloading it by dropping ammo, 5 - container, like bag/backpack, 6 - dropping on the ground)
+int arg1 - Target slot (0 - main backpack, 1 - left hand, 2 - right hand, 3 - armor slot, 4 - weapon, when reloading it by dropping ammo, 5 - container, like bag/backpack, 6 - dropping on the ground, 7 - picking up item)
Item arg2 - Item being moved
Item arg3 - Item being replaced, weapon being reloaded, or container being filled (can be 0)
-int ret1 - Override setting (-1 - use engine handler, any other value - prevent relocation of item/reloading weapon)
+int ret1 - Override setting (-1 - use engine handler, any other value - prevent relocation of item/reloading weapon/picking up item)
-------------------------------------------
@@ -626,8 +625,8 @@ Runs when the Sneak skill is activated, or when the game rolls another Sneak che
You can override the result of a random Sneak check or the duration time for the current result.
int arg1 - Sneak check result: 1 - success, 0 - failure
-int arg2 - the duration in ticks for the current Sneak check (time is based on the Sneak skill level)
+int arg2 - the duration in ticks for the current Sneak check (time depends on Sneak skill level)
Critter arg3 - the critter (usually dude_obj)
-int ret1 - overrides the Sneak check result
+int ret1 - overrides the result of the Sneak check
int ret2 - overrides the duration time for the current result
diff --git a/artifacts/scripting/sfall function notes.txt b/artifacts/scripting/sfall function notes.txt
index ec3a7387..1750e689 100644
--- a/artifacts/scripting/sfall function notes.txt
+++ b/artifacts/scripting/sfall function notes.txt
@@ -578,6 +578,12 @@ Some utility/math functions are available:
- type: 0 - changes the value of NumEffects for the drug (see Drugs.ini for the description of NumEffects)
1 - changes the duration of the addiction effect for the drug (a value of 1 = one game minute)
+> int sfall_func1("set_unique_id", object)
+- assigns an unique ID number to the object and returns it. If an unique ID number has already been assigned to an object, then ID number is returned without reassignment
+- to just get the current ID number of an object, use sfall_func2("get_object_data", object, OBJ_DATA_ID)
+- unique ID numbers are saved in your savegame, and have a range from 0x10000000 to 0x7FFFFFFF
+- there is also an unique ID number range for the player and party members from 18000 to 83535
+
------------------------
------ MORE INFO -------
------------------------
diff --git a/sfall/Modules/HookScripts/InventoryHs.cpp b/sfall/Modules/HookScripts/InventoryHs.cpp
index 3e219a0e..2142f861 100644
--- a/sfall/Modules/HookScripts/InventoryHs.cpp
+++ b/sfall/Modules/HookScripts/InventoryHs.cpp
@@ -286,6 +286,27 @@ donothing:
}
}
+static void __declspec(naked) PickupObjectHack() {
+ __asm {
+ cmp edi, ds:[FO_VAR_obj_dude];
+ je runHook;
+ xor edx, edx; // engine handler
+ retn;
+runHook:
+ push eax;
+ push ecx;
+ mov edx, ecx;
+ xor ecx, ecx; // no itemReplace
+ push 7; // event: item pickup
+ call InventoryMoveHook_Script; // edx - item
+ mov edx, eax; // ret value
+ pop ecx;
+ pop eax;
+ inc edx; // 0 - engine handler, otherwise cancel pickup
+ retn;
+ }
+}
+
/* Common InvenWield hook */
static bool InvenWieldHook_Script(int flag) {
argCount = 4;
@@ -427,6 +448,11 @@ void Inject_InventoryMoveHook() {
0x47379A // caps multi drop
});
MakeCall(0x473807, InvenActionExplosiveDropHack, 1); // drop active explosives
+
+ MakeCall(0x49B660, PickupObjectHack);
+ SafeWrite32(0x49B665, 0x850FD285); // test edx, edx
+ SafeWrite32(0x49B669, 0xC2); // jnz 0x49B72F
+ SafeWrite8(0x49B66E, 0xFE); // cmp edi > cmp esi
}
void Inject_InvenWieldHook() {
diff --git a/sfall/Modules/Inventory.cpp b/sfall/Modules/Inventory.cpp
index 1dafd318..5666dbae 100644
--- a/sfall/Modules/Inventory.cpp
+++ b/sfall/Modules/Inventory.cpp
@@ -22,7 +22,7 @@
#include "..\FalloutEngine\Fallout2.h"
#include "..\InputFuncs.h"
#include "PartyControl.h"
-#include "HookScripts.h"
+//#include "HookScripts.h"
#include "LoadGameHook.h"
#include "Inventory.h"
diff --git a/sfall/Modules/Scripting/Handlers/Metarule.cpp b/sfall/Modules/Scripting/Handlers/Metarule.cpp
index ba9df558..41414249 100644
--- a/sfall/Modules/Scripting/Handlers/Metarule.cpp
+++ b/sfall/Modules/Scripting/Handlers/Metarule.cpp
@@ -127,6 +127,7 @@ static const SfallMetarule metarules[] = {
{"set_outline", sf_set_outline, 2, 2, {ARG_OBJECT, ARG_INT}},
{"set_rest_heal_time", sf_set_rest_heal_time, 1, 1, {ARG_INT}},
{"set_rest_mode", sf_set_rest_mode, 1, 1, {ARG_INT}},
+ {"set_unique_id", sf_set_unique_id, 1, 1, {ARG_OBJECT}},
{"set_unjam_locks_time", sf_set_unjam_locks_time, 1, 1, {ARG_INT}},
{"spatial_radius", sf_spatial_radius, 1, 1, {ARG_OBJECT}},
{"tile_refresh_display", sf_tile_refresh_display, 0, 0},
diff --git a/sfall/Modules/Scripting/Handlers/Objects.cpp b/sfall/Modules/Scripting/Handlers/Objects.cpp
index 1855772b..b07df25d 100644
--- a/sfall/Modules/Scripting/Handlers/Objects.cpp
+++ b/sfall/Modules/Scripting/Handlers/Objects.cpp
@@ -519,5 +519,9 @@ void sf_set_drugs_data(OpcodeContext& ctx) {
if (result) ctx.printOpcodeError("set_drugs_data() - drug PID not found in the configuration file.");
}
+void sf_set_unique_id(OpcodeContext& ctx) {
+ ctx.setReturn(Objects::SetObjectUniqueID(ctx.arg(0).asObject()));
+}
+
}
}
diff --git a/sfall/Modules/Scripting/Handlers/Objects.h b/sfall/Modules/Scripting/Handlers/Objects.h
index 74148ad4..1a54c3e5 100644
--- a/sfall/Modules/Scripting/Handlers/Objects.h
+++ b/sfall/Modules/Scripting/Handlers/Objects.h
@@ -109,5 +109,7 @@ void sf_get_object_ai_data(OpcodeContext&);
void sf_set_drugs_data(OpcodeContext&);
+void sf_set_unique_id(OpcodeContext&);
+
}
}
diff --git a/sfall/ddraw.vcxproj b/sfall/ddraw.vcxproj
index 6e441d16..de086b05 100644
--- a/sfall/ddraw.vcxproj
+++ b/sfall/ddraw.vcxproj
@@ -280,7 +280,7 @@
false
- "$(ProjectDir)postbuild.cmd" releasexp "$(TargetPath)"
+ "$(ProjectDir)postbuild.cmd" devxp "$(TargetPath)"
@@ -466,6 +466,7 @@
Create
Create
Create
+ Create