From 7cacd7ffe57474f94ceffe9fc9a803dbd88e4d4e Mon Sep 17 00:00:00 2001 From: DiaLight Date: Tue, 5 Nov 2024 02:10:05 +0300 Subject: [PATCH] trying to fix a CTA bug for the third time --- mapping/DKII_EXE_v170.sgmap | 77 +++++--- src/CMakeLists.txt | 1 - src/dk2/CDefaultPlayerInterface.cpp | 220 +++++++++++++++++++---- src/dk2/CWorld.cpp | 8 + src/patches/drop_thing_from_hand_fix.cpp | 154 ---------------- src/patches/drop_thing_from_hand_fix.h | 27 --- src/patches/micro_patches.cpp | 3 +- src/patches/micro_patches.h | 4 + src/replace_globals.map | 3 + 9 files changed, 248 insertions(+), 249 deletions(-) delete mode 100644 src/patches/drop_thing_from_hand_fix.cpp delete mode 100644 src/patches/drop_thing_from_hand_fix.h diff --git a/mapping/DKII_EXE_v170.sgmap b/mapping/DKII_EXE_v170.sgmap index 091baa7..2b59eed 100644 --- a/mapping/DKII_EXE_v170.sgmap +++ b/mapping/DKII_EXE_v170.sgmap @@ -6159,7 +6159,21 @@ struct: id=vtbl_0066EBDC,name=CNetworkCommunication,size=65034,vtable=instance_0 field: name=fF740_nullRun type: kind=int,size=4,signed=True field: name=field_F744 - type: kind=array,count=1408 + type: kind=int,size=4,signed=True + field: name=ff748_gap + type: kind=array,count=72 + type: kind=int,size=1 + field: name=fF790_timeMs_dataCb + type: kind=int,size=4,signed=True + field: name=field_F794 + type: kind=int,size=4,signed=True + field: name=field_F798 + type: kind=int,size=4,signed=True + field: name=ff79c_gap + type: kind=array,count=264 + type: kind=int,size=1 + field: name=field_F8A4 + type: kind=array,count=1056 type: kind=int,size=1,signed=True,winapi=char field: name=field_FCC4 type: kind=array,count=160 @@ -10624,7 +10638,7 @@ struct: id=instance_0066E3EC,path=dk2,name=CWorld_vtbl,size=920 type: kind=struct,id=construct_004C1EAD arg: kind=ptr type: kind=struct,id=vtbl_0066E3EC - field: name=loc_508C10 + field: name=hasActionHandler_508C10 type: kind=ptr type: kind=function,declspec=thiscall ret: kind=int,size=4,signed=True,winapi=BOOL,fname=BOOL @@ -11515,16 +11529,20 @@ struct: id=instance_0066E3EC,path=dk2,name=CWorld_vtbl,size=920 arg: kind=int,size=4,signed=True field: name=sub_509340 type: kind=ptr - type: kind=function,declspec=stdcall - ret: kind=int,size=4,signed=True - arg: kind=int,size=4,signed=True + type: kind=function,declspec=thiscall + ret: kind=int,size=4,signed=True,winapi=BOOL,fname=BOOL + arg: kind=ptr + type: kind=struct,id=vtbl_0066E3EC arg: kind=int,size=4,signed=True arg: kind=int,size=4,signed=True + arg: kind=int,size=2 arg: kind=int,size=4,signed=True field: name=sub_509370 type: kind=ptr - type: kind=function,declspec=stdcall - ret: kind=int,size=4,signed=True + type: kind=function,declspec=thiscall + ret: kind=int,size=4,signed=True,winapi=BOOL,fname=BOOL + arg: kind=ptr + type: kind=struct,id=vtbl_0066E3EC arg: kind=int,size=4,signed=True arg: kind=int,size=4,signed=True arg: kind=int,size=2,signed=True @@ -12861,7 +12879,7 @@ struct: id=constructor_00521F40,name=GameAction,size=18 type: kind=int,size=4 field: name=fC_actionKind type: kind=int,size=4,signed=True - field: name=f10__playerTagId + field: name=f10_playerTagId type: kind=int,size=2 struct: id=constructor_00525EB0,name=GameActionArray,size=588 field: name=f0_loopArr32 @@ -22824,8 +22842,6 @@ global: va=004039A0,name=fun_4039A0,size=1552,member_of=vtbl_0066C4A4 arg: kind=ptr type: kind=struct,id=vtbl_0066C4A4 arg: kind=int,size=4,signed=True - arg: kind=int,size=4,signed=True - arg: kind=int,size=4,signed=True global: va=00403FB0,name=fun_403FB0,size=3581,member_of=vtbl_0066C4A4 type: kind=function,declspec=thiscall ret: kind=void @@ -23371,7 +23387,7 @@ global: va=0040D8F0,name=checkAllowToDrop,size=443,member_of=vtbl_0066C4A4 arg: kind=int,size=4,signed=True global: va=0040DAB0,name=pushDropThingFromHandAction,size=623,member_of=vtbl_0066C4A4 type: kind=function,declspec=thiscall - ret: kind=int,size=4 + ret: kind=void arg: kind=ptr type: kind=struct,id=vtbl_0066C4A4 arg: kind=ptr @@ -24267,10 +24283,11 @@ global: va=0041FCF0,name=sub_41FCF0,size=241,member_of=vtbl_0066C4A4 arg: kind=int,size=4,signed=True arg: kind=int,size=4,signed=True arg: kind=int,size=4,signed=True -global: va=0041FDF0,name=sub_41FDF0,size=178 +global: va=0041FDF0,name=sub_41FDF0,size=178,member_of=vtbl_0066C4A4 type: kind=function,declspec=thiscall ret: kind=int,size=4,signed=True - arg: kind=int,size=4,signed=True + arg: kind=ptr + type: kind=struct,id=vtbl_0066C4A4 arg: kind=int,size=4,signed=True arg: kind=int,size=4,signed=True global: va=0041FEB0,name=sub_41FEB0,size=228 @@ -25704,11 +25721,11 @@ global: va=00431040,name=sub_431040,size=13,member_of=constructor_004107A0 type: kind=int,size=4,signed=True arg: kind=ptr type: kind=struct,id=constructor_004107A0 -global: va=00431050,name=sub_431050,size=29 +global: va=00431050,name=sub_431050,size=29,member_of=constructor_004107A0 type: kind=function,declspec=thiscall ret: kind=int,size=4,signed=True arg: kind=ptr - type: kind=int,size=4 + type: kind=struct,id=constructor_004107A0 global: va=00431070,name=sub_431070,size=36 type: kind=function,declspec=thiscall ret: kind=ptr @@ -25721,12 +25738,12 @@ global: va=004310A0,name=sub_4310A0,size=13 ret: kind=int,size=4,signed=True arg: kind=ptr type: kind=int,size=4 -global: va=004310B0,name=sub_4310B0,size=663 +global: va=004310B0,name=sub_4310B0,size=663,member_of=constructor_004107A0 type: kind=function,declspec=thiscall ret: kind=ptr type: kind=int,size=4,signed=True arg: kind=ptr - type: kind=int,size=4 + type: kind=struct,id=constructor_004107A0 global: va=00431390,name=sub_431390,size=97 type: kind=function,declspec=thiscall ret: kind=void @@ -29096,7 +29113,7 @@ global: va=00450910,name=sub_450910,size=718 arg: kind=int,size=4 arg: kind=int,size=4,signed=True arg: kind=int,size=4,signed=True -global: va=00450BE0,name=sub_450BE0,size=344,member_of=vtbl_0066D3E4 +global: va=00450BE0,name=checkAllowObjectToDrop_450BE0,size=344,member_of=vtbl_0066D3E4 type: kind=function,declspec=thiscall ret: kind=int,size=4,signed=True,winapi=BOOL,fname=BOOL arg: kind=ptr @@ -29105,7 +29122,7 @@ global: va=00450BE0,name=sub_450BE0,size=344,member_of=vtbl_0066D3E4 arg: kind=int,size=4,signed=True arg: kind=int,size=2 arg: kind=int,size=4,signed=True -global: va=00450D40,name=sub_450D40,size=97 +global: va=00450D40,name=sub_450D40,size=97,member_of=vtbl_0066D3E4 type: kind=function,declspec=thiscall ret: kind=int,size=4,signed=True,winapi=BOOL,fname=BOOL arg: kind=ptr @@ -34401,11 +34418,11 @@ global: va=004A3E90,name=sub_4A3E90,size=189 ret: kind=int,size=4,signed=True arg: kind=int,size=2,signed=True arg: kind=int,size=4,signed=True -global: va=004A3F50,name=sub_4A3F50,size=102 +global: va=004A3F50,name=sub_4A3F50,size=102,member_of=vtbl_0066D654 type: kind=function,declspec=thiscall ret: kind=int,size=4,signed=True arg: kind=ptr - type: kind=int,size=2 + type: kind=struct,id=vtbl_0066D654 arg: kind=int,size=4,signed=True arg: kind=int,size=4,signed=True arg: kind=int,size=4,signed=True @@ -42667,7 +42684,7 @@ global: va=00508C00,name=getPlayerList,size=4,member_of=vtbl_0066E3EC type: kind=struct,id=construct_004C1EAD arg: kind=ptr type: kind=struct,id=vtbl_0066E3EC -global: va=00508C10,name=fun_508C10,size=41,member_of=vtbl_0066E3EC +global: va=00508C10,name=hasActionHandler,size=41,member_of=vtbl_0066E3EC type: kind=function,declspec=thiscall ret: kind=int,size=4,signed=True,winapi=BOOL,fname=BOOL arg: kind=ptr @@ -43053,7 +43070,7 @@ global: va=00509310,name=fun_509310,size=34,member_of=vtbl_0066E3EC arg: kind=int,size=4 arg: kind=int,size=4,signed=True arg: kind=int,size=4,signed=True -global: va=00509340,name=fun_509340,size=34,member_of=vtbl_0066E3EC +global: va=00509340,name=checkAllowObjectToDrop_509340,size=34,member_of=vtbl_0066E3EC type: kind=function,declspec=thiscall ret: kind=int,size=4,signed=True,winapi=BOOL,fname=BOOL arg: kind=ptr @@ -43065,7 +43082,8 @@ global: va=00509340,name=fun_509340,size=34,member_of=vtbl_0066E3EC global: va=00509370,name=fun_509370,size=34,member_of=vtbl_0066E3EC type: kind=function,declspec=thiscall ret: kind=int,size=4,signed=True,winapi=BOOL,fname=BOOL - arg: kind=int,size=4,signed=True + arg: kind=ptr + type: kind=struct,id=vtbl_0066E3EC arg: kind=int,size=4,signed=True arg: kind=int,size=4,signed=True arg: kind=int,size=2,signed=True @@ -45826,7 +45844,7 @@ global: va=00522790,name=collectGameActions,size=212,member_of=vtbl_0066EB8C type: kind=struct,id=vtbl_0066EB8C arg: kind=ptr type: kind=struct,id=construct_005227B5 -global: va=00522870,name=sub_522870,size=274 +global: va=00522870,name=CNetworkCommunication_thread_522870,size=274 type: kind=function,declspec=stdcall ret: kind=int,size=4 arg: kind=ptr @@ -46302,7 +46320,7 @@ global: va=00527150,name=sub_527150,size=43,member_of=constructor_00526020 type: kind=struct,id=arg_a2_00527150 global: va=00527180,name=handleActions,size=229,member_of=constructor_00526020 type: kind=function,declspec=thiscall - ret: kind=int,size=4,signed=True + ret: kind=void arg: kind=ptr type: kind=struct,id=constructor_00526020 global: va=00527270,name=toggleMenu,size=66,member_of=constructor_00526020 @@ -52800,7 +52818,7 @@ global: va=00566220,name=saveGammaLevel,size=127,member_of=constructor_00563C50 type: kind=struct,id=constructor_00563C50 arg: kind=ptr type: kind=int,size=4,signed=True -global: va=005662A0,name=sub_5662A0,size=127 +global: va=005662A0,name=sub_5662A0,size=127,member_of=constructor_00563C50 type: kind=function,declspec=thiscall ret: kind=ptr,winapi=HKEY type: kind=winapi,name=HKEY__,size=4 @@ -57498,7 +57516,7 @@ global: va=005986F0,name=fun_5986F0,size=258,member_of=vtbl_00670574 arg: kind=ptr type: kind=struct,id=vtbl_00670574 arg: kind=ptr - type: kind=int,size=4,signed=True + type: kind=struct,id=constructor_00521F40 global: va=00598800,name=CPCEngineInterface::fun_598800,size=128 type: kind=function,declspec=stdcall ret: kind=int,size=4,signed=True @@ -60668,7 +60686,8 @@ global: va=005B7640,name=set,size=27,member_of=constructor_005B7610 global: va=005B7660,name=j_MySemaphore_releaseSemaphore,size=5 type: kind=function,declspec=thiscall ret: kind=int,size=4,signed=True - arg: kind=int,size=4,signed=True + arg: kind=ptr + type: kind=struct,id=constructor_005B7610 global: va=005B7670,name=waitFor,size=41,member_of=constructor_005B7610 type: kind=function,declspec=thiscall ret: kind=int,size=4,signed=True,winapi=BOOL,fname=BOOL diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 99b20c5..b1ec61e 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -37,7 +37,6 @@ add_executable(${TARGET} patches/use_wheel_to_zoom.cpp patches/micro_patches.cpp patches/game_version_patch.cpp - patches/drop_thing_from_hand_fix.cpp patches/gog_patch_dll/gog_patch_dll.cpp patches/gog_patch_dll/gog_cfg.cpp diff --git a/src/dk2/CDefaultPlayerInterface.cpp b/src/dk2/CDefaultPlayerInterface.cpp index 7dd063b..90ba1f0 100644 --- a/src/dk2/CDefaultPlayerInterface.cpp +++ b/src/dk2/CDefaultPlayerInterface.cpp @@ -7,6 +7,7 @@ #include "dk2/entities/CCreature.h" #include "dk2/entities/CObject.h" #include "dk2/entities/CTrap.h" +#include "dk2/entities/CDeadBody.h" #include "dk2/entities/data/MyObjectDataObj.h" #include "dk2/entities/data/MyTrapDataObj.h" #include "dk2/entities/data/MyCreatureDataObj.h" @@ -16,7 +17,6 @@ #include "patches/micro_patches.h" #include "gog_patch.h" #include "dk2/entities/entities_type.h" -#include "patches/drop_thing_from_hand_fix.h" #include "tools/bug_hunter.h" @@ -56,7 +56,7 @@ int dk2::CDefaultPlayerInterface::tickKeyboard2() { v17_action.data2 = 0.0; v17_action.data3 = 0; v17_action.actionKind = 8; - v17_action._playerTagId = v7; + v17_action.playerTagId = v7; v18_try_catch = 0; this->pushAction(&v17_action); v18_try_catch = -1; @@ -72,7 +72,7 @@ int dk2::CDefaultPlayerInterface::tickKeyboard2() { v17_action.data2 = 0.0; v17_action.data3 = 0; v17_action.actionKind = 8; - v17_action._playerTagId = f8__cpyToF10; + v17_action.playerTagId = f8__cpyToF10; v18_try_catch = 1; this->pushAction(&v17_action); v18_try_catch = -1; @@ -94,7 +94,7 @@ int dk2::CDefaultPlayerInterface::tickKeyboard2() { int v11 = (MyResources_instance.playerCfg.scrollSpeed * this->f1098) << 6; v17_action.data2 = (v11 / 10); v17_action.data3 = 0; - v17_action._playerTagId = this->playerTagId; + v17_action.playerTagId = this->playerTagId; v18_try_catch = 2; return this->pushAction(&v17_action); } @@ -232,7 +232,7 @@ void dk2::CDefaultPlayerInterface::handleRightClick(unsigned int a2_isPressed, O v38_act.data2 = 0; v38_act.data3 = 0; v38_act.actionKind = 15; - v38_act._playerTagId = this->playerTagId; + v38_act.playerTagId = this->playerTagId; v43_try = 0; this->pushAction(&v38_act); v43_try = -1; @@ -253,7 +253,7 @@ void dk2::CDefaultPlayerInterface::handleRightClick(unsigned int a2_isPressed, O v38_act.data2 = 0; v38_act.data3 = this->playerTagId; v38_act.actionKind = 21; // __Posessed___ReleaseCreature - v38_act._playerTagId = this->playerTagId; + v38_act.playerTagId = this->playerTagId; v43_try = 1; this->pushAction(&v38_act); v43_try = -1; @@ -266,7 +266,7 @@ void dk2::CDefaultPlayerInterface::handleRightClick(unsigned int a2_isPressed, O v38_act.data2 = 0; v38_act.data3 = 0; v38_act.actionKind = 22; - v38_act._playerTagId = this->playerTagId; + v38_act.playerTagId = this->playerTagId; v43_try = 2; this->pushAction(&v38_act); return; @@ -288,7 +288,7 @@ void dk2::CDefaultPlayerInterface::handleRightClick(unsigned int a2_isPressed, O v38_act.data2 = fD84_direction; v38_act.data3 = 0; v38_act.actionKind = 62; // SlapCreature - v38_act._playerTagId = this->playerTagId; + v38_act.playerTagId = this->playerTagId; v43_try = 3; this->pushAction(&v38_act); } break; @@ -305,7 +305,7 @@ void dk2::CDefaultPlayerInterface::handleRightClick(unsigned int a2_isPressed, O v39_act.data2 = v25_camDirection; v39_act.data3 = 0; v39_act.actionKind = 62; // SlapCreature - v39_act._playerTagId = this->playerTagId; + v39_act.playerTagId = this->playerTagId; v43_try = 4; this->pushAction(&v39_act); v43_try = -1; @@ -317,7 +317,7 @@ void dk2::CDefaultPlayerInterface::handleRightClick(unsigned int a2_isPressed, O GameAction v40_act; v40_act.data3 = 0; v40_act.actionKind = 106; // MarkCreature - v40_act._playerTagId = v24_playerTagId; + v40_act.playerTagId = v24_playerTagId; v40_act.data1 = a3_underHand->tagId; v40_act.data2 = (unsigned __int16) (f3F7_highPriorityBody & v29_playerMask) == 0; v43_try = 5; @@ -333,7 +333,7 @@ void dk2::CDefaultPlayerInterface::handleRightClick(unsigned int a2_isPressed, O v41_act.data1 = a3_underHand->tagId; v41_act.data3 = 0; v41_act.actionKind = 63; // SlapObject - v41_act._playerTagId = this->playerTagId; + v41_act.playerTagId = this->playerTagId; v43_try = 6; this->pushAction(&v41_act); } break; @@ -347,7 +347,7 @@ void dk2::CDefaultPlayerInterface::handleRightClick(unsigned int a2_isPressed, O v42_act.data2 = v33_direction; v42_act.data3 = 0; v42_act.actionKind = 64; - v42_act._playerTagId = v34_playerTagId; + v42_act.playerTagId = v34_playerTagId; v43_try = 7; this->pushAction(&v42_act); } @@ -362,21 +362,12 @@ void dk2::CDefaultPlayerInterface::handleRightClick(unsigned int a2_isPressed, O if (scheduleDropNextTick(this, a3_underHand)) return; if (!this->pCWorld->v_hasThingsInHand_5094B0(this->playerTagId)) return; int thingInHandIdx = this->pCWorld->v_getNumThingsInPlayerHand_5094D0(this->playerTagId) - 1; - if (drop_thing_from_hand_fix::enabled) { - CPlayer *player = (CPlayer *) this->pCWorld->v_getCTag_508C40(this->playerTagId); - drop_thing_from_hand_fix::modifyCheckIdx(this, player, thingInHandIdx); - if (thingInHandIdx < 0) return; - } uint16_t v36_thingInHandTagId; if (!this->pCWorld->v_getThingInPlayerHand_5094F0(this->playerTagId, thingInHandIdx, &v36_thingInHandTagId)) return; if (!this->pCWorld->v_fun_510000(a3_underHand->x, a3_underHand->y)) return; CThing *thingInHand = (CThing *) sceneObjects[v36_thingInHandTagId]; if (!this->checkAllowToDrop(thingInHand, a3_underHand->x, a3_underHand->y)) return; - if (drop_thing_from_hand_fix::enabled) { - CPlayer *player = (CPlayer *) this->pCWorld->v_getCTag_508C40(this->playerTagId); - drop_thing_from_hand_fix::onPushDropThing(player, v36_thingInHandTagId); - } this->pushDropThingFromHandAction(thingInHand, a3_underHand); } @@ -384,25 +375,72 @@ typedef int (__thiscall *CPlayer_init_t)(dk2::CPlayer *_this, void *edx, dk2::Pl int dk2::CPlayer::init(dk2::PlayerList *a2) { int ret = ((CPlayer_init_t) 0x004B8640)(this, NULL, a2); - if (drop_thing_from_hand_fix::enabled) { - drop_thing_from_hand_fix::init(this); - } return ret; } +namespace dk2 { + bool checkPlayerAllowToDrop(CWorld *world, uint16_t playerTagId, CThing *thingInHand, int a4_x, int a5_y) { + if (!thingInHand) return FALSE; + if (thingInHand->fE_type == 0) { // CCreature + CCreature *creature = (CCreature *) thingInHand; + MyMapElement *a5_ya = world->v_getMapElem(a4_x, a5_y); + if (!world->v_sub_509310(a4_x, a5_y, playerTagId, creature->typeId)) { + unsigned int stateFlags2 = creature->stateFlags2; + return (stateFlags2 & 0x100) != 0 && // isTool + a5_ya->arr6DA4A8_idx == 35 && + (stateFlags2 & 0x400) == 0; // !hasBeenKnockedOut + } + MyMapElement *v9_mapElem = a5_ya; + if (playerTagId != creature->f24_playerId) { + if (a5_ya->sub_453A20(3) && a5_ya->fC == 4) return false; + } + int stateFlags2 = creature->stateFlags2; + if ((stateFlags2 & 0x100) != 0 && // isTool + (stateFlags2 & 0x400) == 0 // !hasBeenKnockedOut + ) { + if ((v9_mapElem->_roomIdFFF & 0xFFF) == 0) return true; + if (!v9_mapElem->sub_453A20(11) + && !v9_mapElem->sub_453A20(13) + && !v9_mapElem->sub_453A20(16) + || !v9_mapElem->sub_454110()) { + return !v9_mapElem->sub_453A20(12); + } + return false; + } + return true; + } + if (thingInHand->fE_type == 2) // CObject + return world->v_sub_509340(a4_x, a5_y, playerTagId, ((CObject *) thingInHand)->typeId); + if (thingInHand->fE_type == 6) // CDeadBody + return world->v_sub_509370(a4_x, a5_y, playerTagId, ((CDeadBody *) thingInHand)->typeId); + return true; + } +} + +BOOL dk2::CDefaultPlayerInterface::checkAllowToDrop(CThing *thingInHand, int a4_x, int a5_y) { + return checkPlayerAllowToDrop(this->pCWorld, this->playerTagId, thingInHand, a4_x, a5_y); +} + int dk2::CPlayer::dropThingFromHand(Vec3i *a2_pos, uint16_t *a3_pDirection) { if (this->thingsInHand_count == 0) return 0; Vec3i *v5_pos = a2_pos; - uint16_t v5_tagId; + CThing *v6_thing; if (drop_thing_from_hand_fix::enabled) { - v5_tagId = drop_thing_from_hand_fix::popThingFromHand(this); + uint16_t v5_tagId = thingsInHand[this->thingsInHand_count - 1]; + v6_thing = (CThing *) sceneObjects[v5_tagId]; + BOOL allowToDrop = checkPlayerAllowToDrop( + g_pWorld, this->f0_tagId, v6_thing, + a2_pos->x >> 12, a2_pos->y >> 12); + if (!allowToDrop) { +// printf("cancel drop\n"); + return 0; + } } else { - v5_tagId = thingsInHand[this->thingsInHand_count - 1]; + uint16_t v5_tagId = thingsInHand[this->thingsInHand_count - 1]; + v6_thing = (CThing *) sceneObjects[v5_tagId]; } this->thingsInHand_count--; - - CThing *v6_thing = (CThing *) sceneObjects[v5_tagId]; v6_thing->fun_4B5560(v5_pos); int MapWhoType = v6_thing->getMapWhoType_except2(); v6_thing->fun_4B4E70(MapWhoType); @@ -478,14 +516,6 @@ namespace dk2 { void dropThing(CDefaultPlayerInterface *self, CPI_ThingInHand *curThing) { if (curThing->dropped != 0) return; CThing *thingInHand = (CThing *) sceneObjects[curThing->tagId]; -// if (drop_thing_from_hand_fix::enabled) { -// printf("ex drop [%d, %d] %d %s", curThing->underHand.x, curThing->underHand.y, thingInHand->f0_tagId, CThing_type_toString(thingInHand->fE_type)); -// if (thingInHand->fE_type == CThing_type_CObject) { -// dk2::CObject *object = (dk2::CObject *) thingInHand; -// printf(" obj.ty=%s", CObject_typeId_toString(object->typeId)); -// } -// printf("\n"); -// } self->pushDropThingFromHandAction(thingInHand, &curThing->underHand); curThing->dropped = 1; } @@ -531,3 +561,119 @@ void dk2::CDefaultPlayerInterface::tickThingsInHand() { --this->thingsInHand_count; } } + +namespace dk2 { + + GameAction buildDropItemAction(CDefaultPlayerInterface *self, int x_if12, int y_if12, uint16_t tagId) { + GameAction act; + act.data1 = x_if12; // x + act.data2 = y_if12; // y + uint16_t v19_direction = self->profiler->c_bridge->v_getCamera()->direction; + act.data3 = tagId | (v19_direction << 16); + act.actionKind = 61; // DropItemFromHand + act.playerTagId = self->playerTagId; + return act; + } + +} + +/** + * + * 0040E0D0 CDefaultPlayerInterface_tickThingsInHand + * CDefaultPlayerInterface_sub_40BBE0 + * CDefaultPlayerInterface_sub_40BFF0 + * CDefaultPlayerInterface_onMouseAction -> + * 00402D00 CDefaultPlayerInterface__fun_402D00 -> + * 004039A0 CDefaultPlayerInterface__fun_4039A0 -> + * 004039A0 CDefaultPlayerInterface__fun_4039A0 -> + * 00408EE0 CDefaultPlayerInterface_handleRightClick + * CDefaultPlayerInterface_onMouseAction -> + * + * CDefaultPlayerInterface_onMouseAction + * 00402D00 CDefaultPlayerInterface__fun_402D00 + * 00526FF0 MyProfiler_attachPlayerI + * 00525370 CGameComponent_mainGuiLoop + * + * 004039A0 CDefaultPlayerInterface__fun_4039A0 + * 00526590 MyProfiler_draw3dScene + * 00525370 CGameComponent_mainGuiLoop + */ +void dk2::CDefaultPlayerInterface::pushDropThingFromHandAction(CThing *a2_thing, ObjUnderHand *a3_underHand) { + int v21_try; + if (a2_thing->fE_type == 0) { // CCreature + GameAction act = buildDropItemAction( + this, a3_underHand->x_if12, a3_underHand->y_if12, 0 + ); + // will go to 00513650 and then 004C0EE0 + v21_try = 0; + this->pushAction(&act); + v21_try = -1; + this->f12DA.sub_40ABC0(8, 0); + return; + } + if (a2_thing->fE_type == 2) { // CObject + int f1C_type = a3_underHand->type; + switch (f1C_type) { + case 2: { // your CCreature + GameAction act = buildDropItemAction( + this, a3_underHand->x_if12, a3_underHand->y_if12, a3_underHand->tagId + ); + v21_try = 1; + this->pushAction(&act); + v21_try = -1; + this->f12DA.sub_40ABC0(8, 0); + } + return; + case 3: { // others CCreature + GameAction act = buildDropItemAction( + this, a3_underHand->x_if12, a3_underHand->y_if12, a3_underHand->tagId + ); + v21_try = 2; + this->pushAction(&act); + v21_try = -1; + this->f12DA.sub_40ABC0(8, 0); + } + return; + case 4: { // CObject + GameAction act = buildDropItemAction( + this, a3_underHand->x_if12, a3_underHand->y_if12, a3_underHand->tagId + ); + v21_try = 3; + this->pushAction(&act); + v21_try = -1; + this->f12DA.sub_40ABC0(8, 0); + } + return; + default: { + GameAction act = buildDropItemAction( + this, a3_underHand->x_if12, a3_underHand->y_if12, 0 + ); + v21_try = 4; + this->pushAction(&act); + v21_try = -1; + this->f12DA.sub_40ABC0(8, 0); + } + return; + } + } + if (a2_thing->fE_type == 6) { + GameAction act = buildDropItemAction( + this, a3_underHand->x_if12, a3_underHand->y_if12, 0 + ); + v21_try = 5; + this->pushAction(&act); + v21_try = -1; + this->f12DA.sub_40ABC0(8, 0); + return; + } + + GameAction act = buildDropItemAction( + this, a3_underHand->x_if12, a3_underHand->y_if12, 0 + ); + v21_try = 6; + this->pushAction(&act); + v21_try = -1; + this->f12DA.sub_40ABC0(8, 0); +} + + diff --git a/src/dk2/CWorld.cpp b/src/dk2/CWorld.cpp index d9cfbd0..f97bb86 100644 --- a/src/dk2/CWorld.cpp +++ b/src/dk2/CWorld.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include "dk2_globals.h" #include "dk2_functions.h" #include "patches/micro_patches.h" @@ -261,3 +262,10 @@ int dk2::CWorld::WorldTrigger_cpp_519F90(__int16 a2_heroPartyIdx, int a3_actionP return spawnWholeParty(this, (uint8_t) a2_heroPartyIdx, a3_actionPointId, (uint8_t) a4_bool); } +BOOL dk2::CWorld::checkAllowObjectToDrop_509340( + int x, + int y, + uint16_t playerTagId, + int objTypeId) { + return this->cmap.checkAllowObjectToDrop_450BE0(x, y, playerTagId, objTypeId); +} diff --git a/src/patches/drop_thing_from_hand_fix.cpp b/src/patches/drop_thing_from_hand_fix.cpp deleted file mode 100644 index 619bb32..0000000 --- a/src/patches/drop_thing_from_hand_fix.cpp +++ /dev/null @@ -1,154 +0,0 @@ -// -// Created by DiaLight on 27.10.2024. -// - -#include -#include -#include "drop_thing_from_hand_fix.h" -#include "dk2/entities/entities_type.h" -#include "dk2/entities/CObject.h" -#include "dk2_globals.h" -#include -#include - -bool drop_thing_from_hand_fix::enabled = true; - -namespace drop_thing_from_hand_fix { - struct PlayerFix { - std::deque pendingToDropThings; - - bool hasPendingToDrop() const { - return !pendingToDropThings.empty(); - } - void clearPendingToDrop() { - pendingToDropThings.clear(); - } - bool isPendingToDrop(uint16_t tagId) { - for (auto tag: pendingToDropThings) { - if(tag == tagId) return true; - } - return false; - } - uint16_t popPendingToDrop() { - uint16_t tagId = pendingToDropThings.front(); - pendingToDropThings.pop_front(); - return tagId; - } - }; - PlayerFix players[7]; -} - -void drop_thing_from_hand_fix::init(dk2::CPlayer *player) { - auto &extraPlayerData = players[player->playerNumber]; - extraPlayerData.clearPendingToDrop(); -} - -void drop_thing_from_hand_fix::modifyCheckIdx(dk2::CDefaultPlayerInterface *dplif, dk2::CPlayer *player, int &thingInHandIdx) { - auto &fix = players[player->playerNumber]; - while(thingInHandIdx >= 0) { - auto tagId = player->thingsInHand[thingInHandIdx]; - bool alreadyDropped = fix.isPendingToDrop(tagId); - if(!alreadyDropped) { - for (int i = 0; i < dplif->thingsInHand_count; ++i) { - auto &tih = dplif->thingsInHand[i]; - if(tih.tagId != tagId) continue; - if (!tih.dropped) continue; - alreadyDropped = true; - break; - } - } - if(!alreadyDropped) return; - thingInHandIdx--; -// printf("force dont drop2 %d\n", fix.pendingToDropThings); - } -} - -uint16_t drop_thing_from_hand_fix::popThingFromHand(dk2::CPlayer *player) { - auto &fix = players[player->playerNumber]; - - // if thingsInHand contains pending item, then select it to drop - uint16_t resultTag = 0; - while(fix.hasPendingToDrop()) { - uint16_t candidateTag = fix.popPendingToDrop(); - for (int i = player->thingsInHand_count - 1; i >= 0; --i) { - uint16_t tagId = player->thingsInHand[i]; - if (candidateTag != tagId) continue; - resultTag = tagId; - memcpy(&player->thingsInHand[i], &player->thingsInHand[i + 1], ((player->thingsInHand_count - 1) - i) * sizeof(uint16_t)); - break; - } - if(resultTag != 0) break; - } - // if there is no pending item, but we have not empty thingsInHand, use default behaviour - if(resultTag == 0) { - resultTag = player->thingsInHand[player->thingsInHand_count - 1]; - } - - // we must clear pending tags that not in thingsInHang to be able to generate drop events for them - std::vector absentTags; - for (auto pendingTagId: fix.pendingToDropThings) { - bool found = false; - for (int i = 0; i < player->thingsInHand_count; ++i) { - uint16_t tagId = player->thingsInHand[i]; - if(pendingTagId != tagId) break; - found = true; - break; - } - if(!found) { - printf("sync failed tagId=%04X\n", pendingTagId); - absentTags.push_back(pendingTagId); - } - } - for (auto absentTag : absentTags) { - auto it = std::find(fix.pendingToDropThings.begin(), fix.pendingToDropThings.end(), absentTag); - fix.pendingToDropThings.erase(it); - } - return resultTag; -} - -void drop_thing_from_hand_fix::onPushDropThing(dk2::CPlayer *player, uint16_t tagId) { - auto &fix = players[player->playerNumber]; - fix.pendingToDropThings.push_back(tagId); -} - -void drop_thing_from_hand_fix::dump(dk2::CDefaultPlayerInterface *dplif, dk2::CPlayer *player, const char *name) { - std::stringstream ss; - ss << GetTickCount() << " " << name << " "; - - ss << "dplif:["; - for (int i = 0; i < dplif->thingsInHand_count; ++i) { - if(i != 0) ss << ", "; - auto &tih = dplif->thingsInHand[i]; - auto &thing = *(dk2::CThing *) dk2::sceneObjects[tih.tagId]; - ss << CThing_type_toString(thing.fE_type); - if(!dk2::sceneObjectsPresent[tih.tagId]) ss << " np"; - if(tih.hasUnderHand) ss << " uh"; - if(tih.dropped) ss << " dr"; - - if(thing.fE_type == CThing_type_CObject) {} - } - ss << "], "; - ss << "cpl:["; - for (int i = 0; i < player->thingsInHand_count; ++i) { - if(i != 0) ss << ", "; - auto tagId = player->thingsInHand[i]; - auto &thing = *(dk2::CThing *) dk2::sceneObjects[tagId]; - ss << CThing_type_toString(thing.fE_type); - if(!dk2::sceneObjectsPresent[tagId]) ss << " np"; - - if(thing.fE_type == CThing_type_CObject) {} - } - ss << "]"; - std::cout << ss.str() << std::endl; -} -void drop_thing_from_hand_fix::dump(dk2::CPlayer *player, dk2::CThing *thingInHand, dk2::ObjUnderHand *a3_underHand) { - auto &fix = players[player->playerNumber]; - printf("%d thingInHand [%d, %d] %d %s %d", GetTickCount(), a3_underHand->x, a3_underHand->y, thingInHand->f0_tagId, - CThing_type_toString(thingInHand->fE_type), - fix.pendingToDropThings.size()); - if(thingInHand->fE_type == CThing_type_CObject) { - dk2::CObject *object = (dk2::CObject *) thingInHand; - printf(" obj.ty=%s", CObject_typeId_toString(object->typeId)); - } - printf("\n"); -} diff --git a/src/patches/drop_thing_from_hand_fix.h b/src/patches/drop_thing_from_hand_fix.h deleted file mode 100644 index 88881e4..0000000 --- a/src/patches/drop_thing_from_hand_fix.h +++ /dev/null @@ -1,27 +0,0 @@ -// -// Created by DiaLight on 27.10.2024. -// - -#ifndef FLAME_DROP_THING_FROM_HAND_FIX_H -#define FLAME_DROP_THING_FROM_HAND_FIX_H - -#include "dk2/entities/CPlayer.h" -#include "dk2/entities/CThing.h" -#include "dk2/ObjUnderHand.h" -#include "dk2/CDefaultPlayerInterface.h" - - -namespace drop_thing_from_hand_fix { - - extern bool enabled; - void init(dk2::CPlayer *player); - void modifyCheckIdx(dk2::CDefaultPlayerInterface *dplif, dk2::CPlayer *player, int &thingInHandIdx); - uint16_t popThingFromHand(dk2::CPlayer *player); - void onPushDropThing(dk2::CPlayer *player, uint16_t tagId); - - void dump(dk2::CDefaultPlayerInterface *a4_dplif, dk2::CPlayer *player, const char *name); - void dump(dk2::CPlayer *player, dk2::CThing *thingInHand, dk2::ObjUnderHand *a3_underHand); -} - - -#endif //FLAME_DROP_THING_FROM_HAND_FIX_H diff --git a/src/patches/micro_patches.cpp b/src/patches/micro_patches.cpp index d05a165..14b414e 100644 --- a/src/patches/micro_patches.cpp +++ b/src/patches/micro_patches.cpp @@ -29,6 +29,7 @@ bool max_host_port_number_fix::enabled = true; bool increase_zoom_level::enabled = true; bool fix_chat_buffer_invalid_memory_access::enabled = true; bool hero_party_spawn_limit_fix::enabled = true; +bool drop_thing_from_hand_fix::enabled = true; bool override_max_room_count::enabled = true; uint8_t override_max_room_count::limit = 255; // default is 96 @@ -77,7 +78,7 @@ void fix_close_window::window_proc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lP dk2::GameAction action; ZeroMemory(&action, sizeof(action)); action.actionKind = dk2::GA_ExitToWindows; - action._playerTagId = playetIf->playerTagId; + action.playerTagId = playetIf->playerTagId; playetIf->pushAction(&action); } else { dk2::setAppExitStatus(true); diff --git a/src/patches/micro_patches.h b/src/patches/micro_patches.h index e40a275..85dc899 100644 --- a/src/patches/micro_patches.h +++ b/src/patches/micro_patches.h @@ -72,6 +72,10 @@ namespace hero_party_spawn_limit_fix { extern bool enabled; } +namespace drop_thing_from_hand_fix { + extern bool enabled; +} + namespace override_max_room_count { extern bool enabled; extern uint8_t limit; diff --git a/src/replace_globals.map b/src/replace_globals.map index b545184..cabb9d4 100644 --- a/src/replace_globals.map +++ b/src/replace_globals.map @@ -26,6 +26,8 @@ 004BC710 int dropItemFromHand(Vec3i *, uint16_t *); /* auto */ 0040E0D0 void tickThingsInHand(); // ---------------- /* auto */ 00406530 BOOL __cdecl CDefaultPlayerInterface_onMouseAction(int, uint32_t, Pos2i, CDefaultPlayerInterface *); /* auto */ +0040DAB0 void pushDropThingFromHandAction(CThing *, ObjUnderHand *); /* auto */ +0040D8F0 BOOL checkAllowToDrop(CThing *, int, int); /* auto */ # MyDxMouse.h 005BC760 int *__cdecl MyDxMouse_create(int *, MyDxMouse **); /* auto */ @@ -107,4 +109,5 @@ # CWorld.h 00519F90 int WorldTrigger_cpp_519F90(int16_t, int, int); /* auto */ +00509340 BOOL checkAllowObjectToDrop_509340(int, int, uint16_t, int); /* auto */