Fixed some args in HOOK_BARTERPRICE hook when trading with PM

And added a new argument to indicate trading with a party member.

Refactored register_hook/register_hook_proc with _WRAP_OPCODE.
This commit is contained in:
NovaRain
2019-08-27 22:31:10 +08:00
parent 071581effc
commit 20cb24b385
5 changed files with 55 additions and 51 deletions
+4 -2
View File
@@ -248,13 +248,14 @@ Obj arg1 - the owner that the object is being removed from
item arg2 - the item that is being removed
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
Obj arg5 - The destination object when the item is moved to another object, 0 otherwise
-------------------------------------------
HOOK_BARTERPRICE (hs_barterprice.int)
Runs whenever the value of goods being purchased is calculated
NOTE: the hook is executed twice when entering the barter screen or after transaction: the first time is for the player and the second time is for NPC
critter arg1 - the critter doing the bartering (either dude_obj or inven_dude)
critter arg2 - the critter being bartered with
@@ -264,7 +265,8 @@ int arg5 - the amount of actual caps in the barter stack (as opposed to good
int arg6 - the value of all goods being traded before skill modifications
critter arg7 - table of offered goods (being sold to NPC)
int arg8 - the total cost of the goods offered by the player
int arg9 - set 1 if the "offers" button was pressed (not for a party member), otherwise 0
int arg9 - 1 if the "offers" button was pressed (not for a party member), 0 otherwise
int arg10 - 1 if trading with a party member, 0 otherwise
int ret1 - the modified value of all of the goods (pass -1 if you just want to modify offered goods)
int ret2 - the modified value of all offered goods
+7
View File
@@ -1169,3 +1169,10 @@ long __stdcall ItemTotalCost(TGameObj* object) {
call item_total_cost_;
}
}
long __stdcall ItemTotalWeight(TGameObj* object) {
__asm {
mov eax, object;
call item_total_weight_;
}
}
+1
View File
@@ -1083,3 +1083,4 @@ long __stdcall ItemWRounds(TGameObj* item);
long __stdcall BarterComputeValue(TGameObj* source, TGameObj* target);
long __stdcall ItemCapsTotal(TGameObj* object);
long __stdcall ItemTotalCost(TGameObj* object);
long __stdcall ItemTotalWeight(TGameObj* object);
+22 -20
View File
@@ -575,15 +575,17 @@ static void __declspec(naked) RemoveObjHook() {
}
// 4.x backport
// The hook is executed twice when entering the barter screen or after transaction: the first time is for the player and the second time is for NPC
static DWORD __fastcall BarterPriceHook_Script(register TGameObj* source, register TGameObj* target, DWORD callAddr) {
bool barterIsParty = (*ptr_dialog_target_is_party != 0);
int computeCost = BarterComputeValue(source, target);
BeginHook();
argCount = 9;
argCount = 10;
args[0] = (DWORD)source;
args[1] = (DWORD)target;
args[2] = computeCost;
args[2] = !barterIsParty ? computeCost : 0;
TGameObj* bTable = (TGameObj*)*ptr_btable;
args[3] = (DWORD)bTable;
@@ -592,24 +594,24 @@ static DWORD __fastcall BarterPriceHook_Script(register TGameObj* source, regist
TGameObj* pTable = (TGameObj*)*ptr_ptable;
args[6] = (DWORD)pTable;
int pcCost = ItemTotalCost(pTable);
args[7] = pcCost;
int pcCost = !barterIsParty ? ItemTotalCost(pTable) : ItemTotalWeight(pTable);
args[7] = !barterIsParty ? pcCost : 0;
args[8] = (DWORD)(callAddr == 0x474D51); // check offers button
args[8] = (DWORD)(callAddr == 0x474D51); // offers button is pressed
args[9] = (DWORD)barterIsParty;
RunHookScript(HOOK_BARTERPRICE);
bool isPCHook = (callAddr == 0x47551F);
bool isPCHook = (callAddr == -1);
int cost = isPCHook ? pcCost : computeCost;
if (cRet > 0) {
if (!barterIsParty && cRet > 0) {
if (isPCHook) {
if (cRet > 1) cost = rets[1]; // new cost for pc
} else if ((int)rets[0] > -1) {
cost = rets[0]; // new cost for trader
cost = rets[0]; // new cost for npc
}
}
EndHook();
return cost;
}
@@ -627,13 +629,13 @@ static void __declspec(naked) BarterPriceHook() {
}
}
static DWORD offersGoodsCost; // keep last cost
static DWORD offersGoodsCost; // keep last cost for pc
static void __declspec(naked) PC_BarterPriceHook() {
__asm {
push edx;
push ecx;
//-------
push [esp + 8]; // address on call stack
push -1; // address on call stack
mov ecx, dword ptr ds:[_obj_dude]; // source
mov edx, dword ptr ds:[_target_stack]; // target
call BarterPriceHook_Script;
@@ -644,11 +646,10 @@ static void __declspec(naked) PC_BarterPriceHook() {
}
}
static const DWORD OverrideCostRet = 0x474D44;
static void __declspec(naked) OverrideCost_BarterPriceHack() {
static void __declspec(naked) OverrideCost_BarterPriceHook() {
__asm {
mov eax, offersGoodsCost;
jmp OverrideCostRet;
retn;
}
}
@@ -1377,7 +1378,7 @@ void _stdcall RegisterHook(DWORD script, DWORD id, DWORD procNum) {
sScriptProgram *prog = GetGlobalScriptProgram(script);
if (prog) {
dlog_f("Global script %08x registered as hook id %d\n", DL_HOOK, script, id);
dlog_f("Global script %08x registered as hook ID %d\n", DL_HOOK, script, id);
sHookScript hook;
hook.prog = *prog;
hook.callback = procNum;
@@ -1503,11 +1504,12 @@ static void HookScriptInit2() {
MakeJump(0x477492, RemoveObjHook); // old 0x477490
LoadHookScript("hs_barterprice", HOOK_BARTERPRICE);
HookCall(0x474D4C, BarterPriceHook);
HookCall(0x475735, BarterPriceHook);
HookCall(0x475762, BarterPriceHook);
HookCall(0X47551A, PC_BarterPriceHook);
MakeJump(0x474D3F, OverrideCost_BarterPriceHack); // just overrides cost of offered goods
HookCall(0x474D4C, BarterPriceHook); // barter_attempt_transaction_ (offers button)
HookCall(0x475735, BarterPriceHook); // display_table_inventories_ (for party members)
HookCall(0x475762, BarterPriceHook); // display_table_inventories_
HookCall(0x4754F4, PC_BarterPriceHook); // display_table_inventories_
HookCall(0X47551A, PC_BarterPriceHook); // display_table_inventories_
HookCall(0x474D3F, OverrideCost_BarterPriceHook); // barter_attempt_transaction_ (just overrides cost of offered goods)
LoadHookScript("hs_movecost", HOOK_MOVECOST);
HookCall(0x417665, &MoveCostHook);
+21 -29
View File
@@ -805,40 +805,32 @@ end:
}
}
static void _stdcall register_hook2() {
const ScriptValue &idArg = opHandler.arg(0);
if (idArg.isInt()) {
RegisterHook((DWORD)opHandler.program(), idArg.rawValue(), -1);
} else {
OpcodeInvalidArgs("register_hook");
}
}
static void __declspec(naked) register_hook() {
__asm {
pushad;
mov ebp, eax;
call interpretPopShort_;
mov edi, eax;
mov eax, ebp;
call interpretPopLong_;
cmp di, VAR_TYPE_INT;
jnz end;
push -1;
push eax;
push ebp;
call RegisterHook;
end:
popad;
retn;
_WRAP_OPCODE(register_hook2, 1, 0)
}
static void _stdcall register_hook_proc2() {
const ScriptValue &idArg = opHandler.arg(0);
if (idArg.isInt()) {
RegisterHook((DWORD)opHandler.program(), idArg.rawValue(), opHandler.arg(1).rawValue());
} else {
OpcodeInvalidArgs("register_hook_proc");
}
}
static void __declspec(naked) register_hook_proc() {
_OP_BEGIN(ebp)
_GET_ARG_R32(ebp, ecx, esi)
_GET_ARG_R32(ebp, ebx, edi)
_CHECK_ARG_INT(cx, fail)
_CHECK_ARG_INT(bx, fail)
__asm {
push esi;
push edi;
push ebp;
call RegisterHook;
fail:
}
_OP_END
_WRAP_OPCODE(register_hook_proc2, 2, 0)
}
static void __declspec(naked) sfall_ver_major() {