Added a new argument to REMOVEINVENOBJ hook (from Mr.Stalin)

Fixed inconsistent return value of get_npc_level.
This commit is contained in:
NovaRain
2019-02-25 12:26:42 +08:00
parent ae3d4fcb69
commit 627c0df484
6 changed files with 53 additions and 36 deletions
+2 -1
View File
@@ -103,6 +103,7 @@
#define RMOBJ_RM_MULT_OBJS 4563866
#define RMOBJ_REPLACE_WEAPON 4658526
#define RMOBJ_THROW 4266040
#define RMOBJ_SUB_CONTAINER 4683191 // search and remove the item from a container inside of an inventory
// offsets for get_proto_data
#define PROTO_PID (1)
@@ -348,7 +349,7 @@
#define OBJ_DATA_FID (0x20)
#define OBJ_DATA_ELEVATION (0x28)
#define OBJ_DATA_PID (0x64)
#define OBJ_DATA_CID (0x68)
#define OBJ_DATA_CID (0x68) // combat id, used for savegame
#define OBJ_DATA_SID (0x78)
// items
#define OBJ_DATA_CUR_CHARGES (0x3C)
+5 -4
View File
@@ -242,12 +242,13 @@ int ret1 - overrides hard-coded handler and selects what should happen with
HOOK_REMOVEINVENOBJ (hs_removeinvenobj.int)
Runs when an object is removed from a critters inventory for any reason
Runs when an object is removed from a container or critter's inventory for any reason
critter arg1 - the critter the object is being removed from
Obj arg1 - the owner that the object is being removed from
item arg2 - the item that is being removed
int arg3 - a flag, or possibly the number of items to remove
int arg4 - The reason the object is being removed. (Actually, the site from which _item_remove_mult was called)
int arg3 - the number of items to remove
int arg4 - The reason the object is being removed (see RMOBJ_* constants)
Obj arg5 - The destination object when the item is moved to another object, otherwise 0
-------------------------------------------
+5 -4
View File
@@ -100,11 +100,12 @@ array - array ID to be used with array-related functions (actually an integer)
> int game_loaded()
- returns 1 the first time it is called after a new game or game load, and 0 any time after. It works on an individual basis for each script, so one script wont interfere with others. Its primary use is for global scripts, so that they know when to call set_global_script_repeat, but it can be called from normal scripts too.
> void inc_npc_level(string npc)
- takes an NPC name as an argument. The NPC must be in your party. This function ignores player level requirements and the minimum 3 player level delay between NPC level gains. It also ignores the random element, regardless of sfall's NPCAutoLevel setting.
> void inc_npc_level(int pid/string name)
- takes a party member PID or an NPC name (deprecated, for compatibility with sfall 4.1.5/3.8.15 or earlier) as an argument. The NPC must be in your party.
- This function ignores player level requirements and the minimum 3 player level delay between NPC level gains. It also ignores the random element, regardless of sfall's NPCAutoLevel setting.
> int get_npc_level(string npc)
- also takes the NPC name as an argument, and returns the NPC's current level. Again, the NPC needs to be in your party.
> int get_npc_level(int pid/string name)
- also takes the party member PID or NPC name (deprecated, for compatibility with sfall 4.1.5/3.8.15 or earlier) as an argument, and returns the NPC's current level. Again, the NPC needs to be in your party.
> void set_car_current_town(int town)
- changes the current town index for the player's car
+2 -2
View File
@@ -162,8 +162,8 @@
0x81a3 - int eax_available()
0x81a4 - void set_eax_environment(int environment)
0x81a5 - void inc_npc_level(string npcName/int pid)
0x8241 - int get_npc_level(string npcName/int pid)
0x81a5 - void inc_npc_level(int pid/string name)
0x8241 - int get_npc_level(int pid/string name)
0x81a6 - int get_viewport_x()
0x81a7 - int get_viewport_y()
+16 -10
View File
@@ -16,21 +16,27 @@ static void __declspec(naked) RemoveObjHook() {
__asm {
mov ecx, [esp + 8]; // call addr
HookBegin;
mov args[0], eax;
mov args[4], edx;
mov args[8], ebx;
mov args[0], eax; // source
mov args[4], edx; // item
mov args[8], ebx; // count
mov args[12], ecx;
pushad;
xor esi, esi;
xor ecx, 0x47761D; // from item_move_func_
cmovz esi, ebp; // target
mov args[16], esi;
push edi;
push ebp;
push eax;
push edx;
}
argCount = 4;
argCount = 5;
RunHookScript(HOOK_REMOVEINVENOBJ);
EndHook();
__asm {
popad;
push edi;
push ebp;
pop edx;
pop eax;
sub esp, 0x0C;
jmp RemoveObjHookRet;
}
@@ -43,14 +49,14 @@ static void __declspec(naked) MoveCostHook() {
mov args[4], edx;
call fo::funcoffs::critter_compute_ap_from_distance_;
mov args[8], eax;
pushad;
pushadc;
}
argCount = 3;
RunHookScript(HOOK_MOVECOST);
__asm {
popad;
popadc;
cmp cRet, 1;
cmovge eax, rets[0];
HookEnd;
+14 -6
View File
@@ -608,12 +608,14 @@ void sf_inc_npc_level(OpcodeContext& ctx) {
void sf_get_npc_level(OpcodeContext& ctx) {
int level = -1;
DWORD pid = ctx.arg(0).asInt(); // set to 0 if passing npc name
if (!pid) {
const char *critterName, *name = ctx.arg(0).strValue();
if (name[0] != 0) {
DWORD findPid = ctx.arg(0).asInt(); // set to 0 if passing npc name
const char *critterName, *name = ctx.arg(0).asString();
if (findPid || name[0] != 0) {
DWORD pid = 0;
DWORD* members = fo::var::partyMemberList;
for (DWORD i = 0; i < fo::var::partyMemberCount; i++) {
if (!findPid) {
__asm {
mov eax, members;
mov eax, [eax];
@@ -624,10 +626,15 @@ void sf_get_npc_level(OpcodeContext& ctx) {
pid = ((fo::GameObject*)*members)->protoId;
break;
}
} else {
DWORD _pid = ((fo::GameObject*)*members)->protoId;
if (findPid == _pid) {
pid = _pid;
break;
}
}
members += 4;
}
}
}
if (pid) {
DWORD* pids = fo::var::partyMemberPidList;
for (DWORD j = 0; j < fo::var::partyMemberMaxCount; j++) {
@@ -637,6 +644,7 @@ void sf_get_npc_level(OpcodeContext& ctx) {
}
}
}
}
ctx.setReturn(level);
}