From 8c09223812048cb1c86e8dac8d37bd01b790be29 Mon Sep 17 00:00:00 2001 From: NovaRain Date: Sun, 9 May 2021 08:49:19 +0800 Subject: [PATCH] Code correction to two previous commits --- sfall/AI.cpp | 21 ++++++++++----------- sfall/BugFixes.cpp | 3 +++ sfall/Perks.cpp | 14 ++++++-------- sfall/Perks.h | 1 + sfall/ReplacementFuncs.cpp | 24 ++++++++++++++---------- sfall/ScriptOps/InventoryOps.hpp | 7 ++++--- 6 files changed, 38 insertions(+), 32 deletions(-) diff --git a/sfall/AI.cpp b/sfall/AI.cpp index b5ea02f9..6c22b1d1 100644 --- a/sfall/AI.cpp +++ b/sfall/AI.cpp @@ -258,9 +258,11 @@ isNotDead: static long __fastcall ai_try_attack_switch_fix(TGameObj* target, long &hitMode, TGameObj* source, TGameObj* weapon) { if (source->critter.movePoints <= 0) return -1; // exit from ai_try_attack_ - if (weapon) { - long _hitMode = fo_ai_pick_hit_mode(source, weapon, target); - if (_hitMode != hitMode) { + if (!weapon) return 1; // no weapon in inventory or hand slot, continue to search weapons on the map (call ai_switch_weapons_) + + long _hitMode = fo_ai_pick_hit_mode(source, weapon, target); + if (_hitMode != hitMode && _hitMode != ATKTYPE_PUNCH) { + if (sfgame_item_weapon_mp_cost(source, weapon, _hitMode, 0) <= source->critter.movePoints) { hitMode = _hitMode; return 0; // change hit mode, continue attack cycle } @@ -268,7 +270,7 @@ static long __fastcall ai_try_attack_switch_fix(TGameObj* target, long &hitMode, // does the NPC have other weapons in inventory? TGameObj* item = fo_ai_search_inven_weap(source, 1, target); // search based on AP - if (item && weapon) { + if (item) { // is using a close range weapon? long wType = fo_item_w_subtype(item, ATKTYPE_RWEAPON_PRIMARY); if (wType <= ATKSUBTYPE_MELEE) { // unarmed and melee weapons, check the distance before switching @@ -278,14 +280,11 @@ static long __fastcall ai_try_attack_switch_fix(TGameObj* target, long &hitMode, } // no other weapon in inventory - if (weapon) { - if (fo_item_w_range(source, ATKTYPE_PUNCH) >= fo_obj_dist(source, target)) { - hitMode = ATKTYPE_PUNCH; - return 0; // change hit mode, continue attack cycle - } + if (fo_item_w_range(source, ATKTYPE_PUNCH) >= fo_obj_dist(source, target)) { + hitMode = ATKTYPE_PUNCH; + return 0; // change hit mode, continue attack cycle } - return (weapon) ? -1 // exit, NPC has a weapon in hand slot, so we don't look for another weapon on the map - : 1; // no weapon in inventory or hand slot, continue to search weapons on the map (call ai_switch_weapons_) + return -1; // exit, NPC has a weapon in hand slot, so we don't look for another weapon on the map } static void __declspec(naked) ai_try_attack_hook_switch_fix() { diff --git a/sfall/BugFixes.cpp b/sfall/BugFixes.cpp index ac9671c1..37223687 100644 --- a/sfall/BugFixes.cpp +++ b/sfall/BugFixes.cpp @@ -3348,6 +3348,9 @@ void BugFixes_Init() // Fix crash when clicking on empty space in the inventory list opened by "Use Inventory Item On" (backpack) action icon MakeCall(0x471A94, use_inventory_on_hack); + // Fix item_count_ function returning incorrect value when there is a container-item inside + SafeWrite8(0x4780B1, 0x29); // jmp 0x4780DB + // Fix for Sequence stat value not being printed correctly when using "print to file" option MakeCall(0x4396F5, Save_as_ASCII_hack, 2); diff --git a/sfall/Perks.cpp b/sfall/Perks.cpp index aec2ccf0..cb6e4d7b 100644 --- a/sfall/Perks.cpp +++ b/sfall/Perks.cpp @@ -593,11 +593,9 @@ static void __declspec(naked) HeaveHoHook() { mov eax, ecx; call stat_level_; lea ebx, [0 + eax * 4]; - sub ebx, eax; + sub ebx, eax; // ST * 3 cmp ebx, esi; // ebx = dist (3*ST), esi = max dist weapon - jle lower; // jump if dist <= max - mov ebx, esi; // dist = max -lower: + cmovg ebx, esi; // if dist > max then dist = max mov eax, ecx; mov edx, PERK_heave_ho; call perk_level_; @@ -611,12 +609,12 @@ lower: } } -static bool perkHeaveHoModFix = false; +bool perkHeaveHoModTweak = false; void __stdcall ApplyHeaveHoFix() { // not really a fix MakeJump(0x478AC4, HeaveHoHook); perks[PERK_heave_ho].strengthMin = 0; - perkHeaveHoModFix = true; + perkHeaveHoModTweak = true; } //////////////////////////////// ENGINE PERKS ///////////////////////////////// @@ -1179,10 +1177,10 @@ void PerksReset() { // Swift Learner bonus SafeWrite32(0x4AFAE2, 100); // Restore 'Heave Ho' modify fix - if (perkHeaveHoModFix) { + if (perkHeaveHoModTweak) { SafeWrite8(0x478AC4, 0xBA); SafeWrite32(0x478AC5, 0x23); - perkHeaveHoModFix = false; + perkHeaveHoModTweak = false; } if (perksReInit) PerkSetup(); // restore perk data } diff --git a/sfall/Perks.h b/sfall/Perks.h index 9ed1fd8c..46c32bf8 100644 --- a/sfall/Perks.h +++ b/sfall/Perks.h @@ -19,6 +19,7 @@ #pragma once extern long PerkLevelMod; +extern bool perkHeaveHoModTweak; void Perks_Init(); void PerksReset(); diff --git a/sfall/ReplacementFuncs.cpp b/sfall/ReplacementFuncs.cpp index daa4ed0c..bf193108 100644 --- a/sfall/ReplacementFuncs.cpp +++ b/sfall/ReplacementFuncs.cpp @@ -136,11 +136,17 @@ long __stdcall sfgame_item_weapon_range(TGameObj* source, TGameObj* weapon, long long type = GetWeaponType(flagExt); if (type == ATKSUBTYPE_THROWING) { - // TODO: add perkHeaveHoModFix from perks.cpp long heaveHoMod = fo_perk_level(source, PERK_heave_ho); - if (heaveHoMod > 0) heaveHoMod *= 2; + long stRange = fo_stat_level(source, STAT_st); - long stRange = (fo_stat_level(source, STAT_st) + heaveHoMod); + if (perkHeaveHoModTweak) { + stRange *= 3; + if (stRange > range) stRange = range; + return stRange + (heaveHoMod * 6); + } + + // vanilla + stRange += (heaveHoMod * 2); if (stRange > 10) stRange = 10; // fix for Heave Ho! stRange *= 3; if (stRange < range) range = stRange; @@ -219,25 +225,23 @@ static void __declspec(naked) ai_search_inven_weap_hook() { } long __fastcall sfgame_item_count(TGameObj* who, TGameObj* item) { - int count = 0; for (int i = 0; i < who->invenSize; i++) { TGameObj::InvenItem* tableItem = &who->invenTable[i]; if (tableItem->object == item) { - count += tableItem->count; + return tableItem->count; // fix } else if (fo_item_get_type(tableItem->object) == item_type_container) { - count += sfgame_item_count(tableItem->object, item); + int count = sfgame_item_count(tableItem->object, item); + if (count > 0) return count; } } - return count; + return 0; } static void __declspec(naked) item_count_hack() { __asm { push ecx; // save state - //push edx; ??? mov ecx, eax; // container-object call sfgame_item_count; // edx - item - //pop edx; pop ecx; // restore retn; } @@ -673,7 +677,7 @@ void InitReplacementHacks() { HookCall(0x429A08, ai_search_inven_weap_hook); // Replace the item_count_ function (fix vanilla function returning incorrect value when there is a container-item inside) - MakeJump(0x47808C, item_count_hack); + //MakeJump(0x47808C, item_count_hack); int fastShotFix = GetConfigInt("Misc", "FastShotFix", 0); fastShotTweak = (fastShotFix > 0 && fastShotFix <= 3); diff --git a/sfall/ScriptOps/InventoryOps.hpp b/sfall/ScriptOps/InventoryOps.hpp index 9109c80f..5a2add85 100644 --- a/sfall/ScriptOps/InventoryOps.hpp +++ b/sfall/ScriptOps/InventoryOps.hpp @@ -52,23 +52,24 @@ static void mf_get_inven_ap_cost() { } static void __stdcall op_obj_is_carrying_obj2() { - int num = 0; const ScriptValue &invenObjArg = opHandler.arg(0), &itemObjArg = opHandler.arg(1); TGameObj *invenObj = invenObjArg.asObject(), *itemObj = itemObjArg.asObject(); + + int count = 0; if (invenObj != nullptr && itemObj != nullptr) { for (int i = 0; i < invenObj->invenSize; i++) { if (invenObj->invenTable[i].object == itemObj) { - num = invenObj->invenTable[i].count; + count = invenObj->invenTable[i].count; break; } } } else { OpcodeInvalidArgs("obj_is_carrying_obj"); } - opHandler.setReturn(num); + opHandler.setReturn(count); } static void __declspec(naked) op_obj_is_carrying_obj() {