mirror of
https://github.com/sfall-team/sfall.git
synced 2026-07-27 16:52:34 -07:00
Added a fixed implementation of ai_check_drugs_ function
* which has all fixes/hook built-in. Disabled old fixes for vanilla ai_check_drugs_ in AI.cpp/BugFixes.cpp.
This commit is contained in:
@@ -23,6 +23,7 @@ WRAP_WATCOM_FFUNC4(fo::GameObject*, ai_best_weapon, fo::GameObject*, source, fo:
|
||||
WRAP_WATCOM_FFUNC3(bool, ai_can_use_weapon, fo::GameObject*, critter, fo::GameObject*, item, DWORD, hitMode)
|
||||
WRAP_WATCOM_FFUNC3(long, ai_have_ammo, fo::GameObject*, critter, fo::GameObject*, item, fo::GameObject**, outAmmo)
|
||||
WRAP_WATCOM_FFUNC3(long, ai_pick_hit_mode, fo::GameObject*, source, fo::GameObject*, item, fo::GameObject*, target)
|
||||
WRAP_WATCOM_FFUNC3(long, ai_magic_hands, fo::GameObject*, source, fo::GameObject*, object, long, msgNumber)
|
||||
WRAP_WATCOM_FFUNC3(fo::GameObject*, ai_search_inven_weap, fo::GameObject*, source, long, apCheck, fo::GameObject*, target)
|
||||
WRAP_WATCOM_FFUNC3(void, check_for_death, fo::GameObject*, critter, long, amountDamage, long*, flags)
|
||||
WRAP_WATCOM_FFUNC6(long, combat_safety_invalidate_weapon_func, fo::GameObject*, source, fo::GameObject*, weapon, long, hitMode, fo::GameObject*, targetA, DWORD*, outSafeRange, fo::GameObject*, targetB)
|
||||
@@ -37,7 +38,7 @@ WRAP_WATCOM_FFUNC3(void, intface_update_items, long, animate, long, modeLeft, lo
|
||||
WRAP_WATCOM_FFUNC3(fo::GameObject*, inven_find_type, fo::GameObject*, critter, long, itemType, DWORD*, slot)
|
||||
WRAP_WATCOM_FFUNC3(long, inven_wield, fo::GameObject*, critter, fo::GameObject*, item, long, slot)
|
||||
WRAP_WATCOM_FFUNC3(long, item_add_force, fo::GameObject*, critter, fo::GameObject*, item, long, count)
|
||||
WRAP_WATCOM_FFUNC3(long, item_mp_cost, fo::GameObject*, source, long, hitMode, long, isCalled)
|
||||
WRAP_WATCOM_FFUNC3(long, item_remove_mult, fo::GameObject*, critter, fo::GameObject*, item, long, count) // WARNING: HOOK_REMOVEINVENOBJ uses the return address in this function
|
||||
WRAP_WATCOM_FFUNC3(long, item_w_mp_cost, fo::GameObject*, source, long, hitMode, long, isCalled)
|
||||
// Calculates path and returns it's length
|
||||
WRAP_WATCOM_FFUNC6(long, make_path_func, fo::GameObject*, objectFrom, long, tileFrom, long, tileTo, char*, pathDataBuffer, long, checkTileTo, void*, blockingFunc)
|
||||
@@ -46,6 +47,7 @@ WRAP_WATCOM_FFUNC3(long, message_find, DWORD*, msgFile, long, msgNumber, DWORD*,
|
||||
WRAP_WATCOM_FFUNC4(long, mouse_click_in, long, x, long, y, long, x_offs, long, y_offs)
|
||||
WRAP_WATCOM_FFUNC4(long, mouse_in, long, x, long, y, long, x_offs, long, y_offs)
|
||||
WRAP_WATCOM_FFUNC3(fo::GameObject*, obj_blocking_at, fo::GameObject*, object, long, tile, long, elevation)
|
||||
WRAP_WATCOM_FFUNC4(long, obj_connect, fo::GameObject*, object, long, tile, long, elevation, RECT*, rect)
|
||||
WRAP_WATCOM_FFUNC4(long, obj_dist_with_tile, fo::GameObject*, source, long, sourceTile, fo::GameObject*, target, long, targetTile)
|
||||
WRAP_WATCOM_FFUNC4(long, obj_move_to_tile, fo::GameObject*, object, long, tile, long, elevation, RECT*, rect)
|
||||
WRAP_WATCOM_FFUNC3(long, obj_new_sid_inst, fo::GameObject*, object, long, sType, long, scriptIndex)
|
||||
@@ -71,6 +73,8 @@ WRAP_WATCOM_FFUNC3(const char*, interpretGetString, fo::Program*, scriptPtr, DWO
|
||||
/* stdcall */
|
||||
WRAP_WATCOM_FUNC1(fo::AIcap*, ai_cap, fo::GameObject*, critter)
|
||||
WRAP_WATCOM_FUNC2(void, ai_print_msg, fo::GameObject*, object, long, mode)
|
||||
WRAP_WATCOM_FUNC2(fo::GameObject*, ai_retrieve_object, fo::GameObject*, critter, fo::GameObject*, item)
|
||||
WRAP_WATCOM_FUNC2(fo::GameObject*, ai_search_environ, fo::GameObject*, critter, long, itemType)
|
||||
WRAP_WATCOM_FUNC1(fo::Program*, allocateProgram, const char*, filePath)
|
||||
WRAP_WATCOM_FUNC2(long, anim_can_use_door, fo::GameObject*, source, fo::GameObject*, object)
|
||||
WRAP_WATCOM_FUNC1(bool, art_exists, long, artFid)
|
||||
@@ -136,6 +140,7 @@ WRAP_WATCOM_FUNC2(long, is_within_perception, fo::GameObject*, source, fo::GameO
|
||||
WRAP_WATCOM_FUNC1(long, isPartyMember, fo::GameObject*, obj)
|
||||
WRAP_WATCOM_FUNC1(long, item_c_curr_size, fo::GameObject*, critter)
|
||||
WRAP_WATCOM_FUNC1(long, item_caps_total, fo::GameObject*, object)
|
||||
WRAP_WATCOM_FUNC2(long, item_d_take_drug, fo::GameObject*, source, fo::GameObject*, item)
|
||||
WRAP_WATCOM_FUNC1(long, item_get_type, fo::GameObject*, item)
|
||||
WRAP_WATCOM_FUNC2(fo::GameObject*, item_hit_with, fo::GameObject*, critter, long, hitMode)
|
||||
WRAP_WATCOM_FUNC1(long, item_m_dec_charges, fo::GameObject*, item) // Returns 0 on success, -1 if the item has no charges
|
||||
|
||||
+181
-2
@@ -4,11 +4,13 @@
|
||||
*
|
||||
*/
|
||||
|
||||
//#include "..\main.h"
|
||||
#include "..\main.h"
|
||||
#include "..\FalloutEngine\Fallout2.h"
|
||||
|
||||
#include "..\Modules\HookScripts\CombatHs.h"
|
||||
|
||||
#include "items.h"
|
||||
|
||||
#include "combatAI.h"
|
||||
|
||||
namespace game
|
||||
@@ -22,7 +24,184 @@ bool CombatAI::ai_can_use_weapon(fo::GameObject* source, fo::GameObject* weapon,
|
||||
return sf::CanUseWeaponHook_Invoke(result, source, weapon, hitMode);
|
||||
}
|
||||
|
||||
void CombatAI::init() { // TODO: add to main.cpp
|
||||
static const long aiUseItemAPCost = 2;
|
||||
static std::vector<long> healingItemPids = {fo::PID_STIMPAK, fo::PID_SUPER_STIMPAK, fo::PID_HEALING_POWDER};
|
||||
|
||||
static bool CheckHealingItems(fo::GameObject* item) {
|
||||
return (std::find(healingItemPids.cbegin(), healingItemPids.cend(), item->protoId) != healingItemPids.cend());
|
||||
}
|
||||
|
||||
// True - use failed
|
||||
static bool UseItemDrugFunc(fo::GameObject* source, fo::GameObject* item) {
|
||||
bool result = (game::Items::item_d_take_drug(source, item) == -1);
|
||||
if (result) {
|
||||
fo::func::item_add_force(source, item, 1);
|
||||
} else {
|
||||
fo::func::ai_magic_hands(source, item, 5000);
|
||||
fo::func::obj_connect(item, source->tile, source->elevation, 0);
|
||||
fo::func::obj_destroy(item);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static long drugUsePerfFixMode;
|
||||
|
||||
void __stdcall CombatAI::ai_check_drugs(fo::GameObject* source) {
|
||||
if (fo::func::critter_body_type(source)) return; // Robotic/Quadruped cannot use drugs
|
||||
|
||||
DWORD slot = -1;
|
||||
long noInvenDrug = 0;
|
||||
bool drugWasUsed = false;
|
||||
|
||||
fo::GameObject* lastItem = nullptr; // combatAIInfoGetLastItem_(source); unused function, always returns 0
|
||||
if (!lastItem) {
|
||||
fo::AIcap* cap = fo::func::ai_cap(source);
|
||||
if (!cap) return;
|
||||
|
||||
long hpPercent = 50;
|
||||
long chance = 0;
|
||||
|
||||
switch ((fo::AIpref::chem_use_mode)cap->chem_use) {
|
||||
case fo::AIpref::chem_use_mode::stims_when_hurt_little: // use only healing drugs
|
||||
hpPercent = 60;
|
||||
break;
|
||||
case fo::AIpref::chem_use_mode::stims_when_hurt_lots: // use only healing drugs
|
||||
hpPercent = 30;
|
||||
break;
|
||||
case fo::AIpref::chem_use_mode::sometimes:
|
||||
if (!(fo::var::combatNumTurns % 3)) chance = 25; // every three turns
|
||||
//hpPercent = 50;
|
||||
break;
|
||||
case fo::AIpref::chem_use_mode::anytime:
|
||||
if (!(fo::var::combatNumTurns % 3)) chance = 75; // every three turns
|
||||
//hpPercent = 50;
|
||||
break;
|
||||
case fo::AIpref::chem_use_mode::always:
|
||||
chance = 100; // 99%
|
||||
break;
|
||||
case fo::AIpref::chem_use_mode::clean:
|
||||
return; // exit: don't use drugs
|
||||
}
|
||||
|
||||
long minHP = (hpPercent * fo::func::stat_level(source, fo::Stat::STAT_max_hit_points)) / 100;
|
||||
|
||||
// [FIX] for AI not checking minimum hp properly for using stimpaks (prevents premature fleeing)
|
||||
if (cap->min_hp > minHP) minHP = cap->min_hp;
|
||||
|
||||
while (fo::func::stat_level(source, fo::Stat::STAT_current_hp) < minHP && source->critter.movePoints >= aiUseItemAPCost) {
|
||||
fo::GameObject* itemFind = fo::func::inven_find_type(source, fo::ItemType::item_type_drug, &slot);
|
||||
if (!itemFind) {
|
||||
noInvenDrug = 2; // healing drugs were not found in the inventory (was 1)
|
||||
break;
|
||||
}
|
||||
|
||||
if (CheckHealingItems(itemFind) && !fo::func::item_remove_mult(source, itemFind, 1)) {
|
||||
if (!UseItemDrugFunc(source, itemFind)) {
|
||||
drugWasUsed = true;
|
||||
}
|
||||
|
||||
if (source->critter.movePoints < aiUseItemAPCost) {
|
||||
source->critter.movePoints = 0;
|
||||
} else {
|
||||
source->critter.movePoints -= aiUseItemAPCost;
|
||||
}
|
||||
slot = -1;
|
||||
}
|
||||
}
|
||||
|
||||
// use any drug (except healing drugs) if there is a chance of using it
|
||||
if (!drugWasUsed && chance > 0 && fo::func::roll_random(0, 100) < chance) {
|
||||
long usedCount = 0;
|
||||
while (source->critter.movePoints >= aiUseItemAPCost) {
|
||||
fo::GameObject* item = fo::func::inven_find_type(source, fo::ItemType::item_type_drug, &slot);
|
||||
if (!item) {
|
||||
noInvenDrug = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
long counter = 0;
|
||||
|
||||
if (drugUsePerfFixMode > 0) {
|
||||
fo::GameObject* firstFoundDrug = item;
|
||||
do {
|
||||
// [FIX] Allow using only the drugs listed in chem_primary_desire and healing drugs (AIDrugUsePerfFix == 2)
|
||||
while (item->protoId != cap->chem_primary_desire[counter]) if (++counter > 2) break;
|
||||
if (counter <= 2) break; // there is a match
|
||||
|
||||
// [FIX] for AI not taking chem_primary_desire in AI.txt as a preference when using drugs in the inventory
|
||||
if (drugUsePerfFixMode == 1) {
|
||||
item = fo::func::inven_find_type(source, fo::ItemType::item_type_drug, &slot);
|
||||
if (!item) {
|
||||
item = firstFoundDrug;
|
||||
break;
|
||||
}
|
||||
counter = 0;
|
||||
}
|
||||
} while (counter < 3);
|
||||
} else {
|
||||
// if the durg is equal to the first item of preference, then check the next two (vanilla behavior)
|
||||
while (item->protoId == cap->chem_primary_desire[counter]) if (++counter > 2) break;
|
||||
}
|
||||
|
||||
// if the preference counter is less than 3, then AI can use the drug
|
||||
if (counter < 3) {
|
||||
// if the item is NOT a healing drug
|
||||
if (!CheckHealingItems(item) && !fo::func::item_remove_mult(source, item, 1)) {
|
||||
if (!UseItemDrugFunc(source, item)) {
|
||||
drugWasUsed = true;
|
||||
usedCount++;
|
||||
}
|
||||
|
||||
if (source->critter.movePoints < aiUseItemAPCost) {
|
||||
source->critter.movePoints = 0;
|
||||
} else {
|
||||
source->critter.movePoints -= aiUseItemAPCost;
|
||||
}
|
||||
slot = -1;
|
||||
|
||||
fo::AIpref::chem_use_mode chemUse = (fo::AIpref::chem_use_mode)cap->chem_use;
|
||||
if (chemUse == fo::AIpref::chem_use_mode::sometimes ||
|
||||
(chemUse == fo::AIpref::chem_use_mode::anytime && usedCount >= 2))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// search for drugs on the map
|
||||
if (lastItem || (!drugWasUsed /*&& noInvenDrug*/)) {
|
||||
do {
|
||||
if (!lastItem) lastItem = fo::func::ai_search_environ(source, fo::ItemType::item_type_drug);
|
||||
if (!lastItem) lastItem = fo::func::ai_search_environ(source, fo::ItemType::item_type_misc_item);
|
||||
if (lastItem) lastItem = fo::func::ai_retrieve_object(source, lastItem);
|
||||
|
||||
// [FIX] Prevent the use of healing drugs when not necessary
|
||||
// noInvenDrug: is set to 2 that healing is required
|
||||
if (lastItem && noInvenDrug != 2 && CheckHealingItems(lastItem)) {
|
||||
long maxHP = fo::func::stat_level(source, fo::Stat::STAT_max_hit_points);
|
||||
if (10 + source->critter.health >= maxHP) { // quick check current HP
|
||||
return; // exit: don't use healing item
|
||||
}
|
||||
}
|
||||
|
||||
if (lastItem && !fo::func::item_remove_mult(source, lastItem, 1)) {
|
||||
if (!UseItemDrugFunc(source, lastItem)) lastItem = nullptr;
|
||||
|
||||
if (source->critter.movePoints < aiUseItemAPCost) {
|
||||
source->critter.movePoints = 0;
|
||||
} else {
|
||||
source->critter.movePoints -= aiUseItemAPCost;
|
||||
}
|
||||
}
|
||||
} while (lastItem && source->critter.movePoints >= aiUseItemAPCost);
|
||||
}
|
||||
}
|
||||
|
||||
void CombatAI::init() {
|
||||
drugUsePerfFixMode = sf::IniReader::GetConfigInt("Misc", "AIDrugUsePerfFix", 0);
|
||||
if (drugUsePerfFixMode > 0) sf::dlogr("Applying AI drug use preference fix.", DL_FIX);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -9,11 +9,15 @@
|
||||
namespace game
|
||||
{
|
||||
|
||||
#include "..\FalloutEngine\Fallout2.h"
|
||||
|
||||
class CombatAI {
|
||||
public:
|
||||
static void init();
|
||||
|
||||
static bool ai_can_use_weapon(fo::GameObject* source, fo::GameObject* weapon, long hitMode);
|
||||
|
||||
static void __stdcall ai_check_drugs(fo::GameObject* source);
|
||||
};
|
||||
|
||||
}
|
||||
@@ -8,6 +8,7 @@
|
||||
#include "..\FalloutEngine\Fallout2.h"
|
||||
|
||||
#include "..\Modules\HookScripts\CombatHs.h"
|
||||
#include "..\Modules\HookScripts\ObjectHs.h"
|
||||
#include "..\Modules\Perks.h"
|
||||
|
||||
#include "..\Game\stats.h"
|
||||
@@ -21,6 +22,12 @@ namespace sf = sfall;
|
||||
|
||||
static constexpr int reloadCostAP = 2; // engine default reload AP cost
|
||||
|
||||
// Implementation of item_d_take_ engine function with the HOOK_USEOBJON hook
|
||||
long Items::item_d_take_drug(fo::GameObject* source, fo::GameObject* item) {
|
||||
if (sf::UseObjOnHook_Invoke(source, item, source) == -1) return -1;
|
||||
return fo::func::item_d_take_drug(source, item);
|
||||
}
|
||||
|
||||
long Items::item_count(fo::GameObject* who, fo::GameObject* item) {
|
||||
for (int i = 0; i < who->invenSize; i++) {
|
||||
auto tableItem = &who->invenTable[i];
|
||||
|
||||
@@ -13,6 +13,9 @@ class Items {
|
||||
public:
|
||||
static void init();
|
||||
|
||||
// Implementation of item_d_take_ engine function with the HOOK_USEOBJON hook
|
||||
static long item_d_take_drug(fo::GameObject* source, fo::GameObject* item);
|
||||
|
||||
static long item_count(fo::GameObject* who, fo::GameObject* item);
|
||||
|
||||
static long item_weapon_range(fo::GameObject* source, fo::GameObject* weapon, long hitMode);
|
||||
|
||||
+10
-7
@@ -22,6 +22,7 @@
|
||||
#include "..\FalloutEngine\Fallout2.h"
|
||||
#include "LoadGameHook.h"
|
||||
|
||||
#include "..\Game\combatAI.h"
|
||||
#include "..\Game\items.h"
|
||||
|
||||
#include "AI.h"
|
||||
@@ -112,8 +113,10 @@ end:
|
||||
add esp, 4;
|
||||
jmp combat_ai_hack_Ret;
|
||||
tryHeal:
|
||||
mov eax, esi;
|
||||
call fo::funcoffs::ai_check_drugs_;
|
||||
push ecx;
|
||||
push esi; // mov eax, esi;
|
||||
call game::CombatAI::ai_check_drugs; // call fo::funcoffs::ai_check_drugs_;
|
||||
pop ecx;
|
||||
cmp [esi + health], edx; // edx - minimum hp, below which NPC will run away
|
||||
jge end;
|
||||
retn; // flee
|
||||
@@ -126,7 +129,7 @@ static void __declspec(naked) ai_check_drugs_hook() {
|
||||
mov edx, dword ptr [esp + 0x34 - 0x1C + 4]; // ai cap
|
||||
mov edx, [edx + 0x10]; // min_hp
|
||||
cmp eax, edx; // curr_hp < cap.min_hp
|
||||
cmovl edi, edx;
|
||||
cmovl edi, edx; // min_hp <- cap.min_hp
|
||||
retn;
|
||||
}
|
||||
}
|
||||
@@ -663,12 +666,12 @@ void AI::init() {
|
||||
// Fix to allow fleeing NPC to use drugs
|
||||
MakeCall(0x42B1DC, combat_ai_hack);
|
||||
// Fix for AI not checking minimum hp properly for using stimpaks (prevents premature fleeing)
|
||||
HookCall(0x428579, ai_check_drugs_hook);
|
||||
//HookCall(0x428579, ai_check_drugs_hook);
|
||||
|
||||
// Fix to prevent the use of healing drugs when not necessary
|
||||
HookCall(0x4287D7, ai_check_drugs_hook_healing);
|
||||
SafeWrite8(0x4285A8, 2); // set noInvenItem = 2
|
||||
SafeWrite8(0x4287A0, 0x8C); // jnz > jl (noInvenItem < 1)
|
||||
//HookCall(0x4287D7, ai_check_drugs_hook_healing);
|
||||
//SafeWrite8(0x4285A8, 2); // set noInvenItem = 2
|
||||
//SafeWrite8(0x4287A0, 0x8C); // jnz > jl (noInvenItem < 1)
|
||||
|
||||
// Fix for NPC stuck in fleeing mode when the hit chance of a target was too low
|
||||
HookCall(0x42B1E3, combat_ai_hook_FleeFix);
|
||||
|
||||
+14
-14
@@ -3641,20 +3641,20 @@ void BugFixes::init()
|
||||
// Display a pop-up message box about death from radiation
|
||||
HookCall(0x42D733, process_rads_hook_msg);
|
||||
|
||||
int drugUsePerfFix = IniReader::GetConfigInt("Misc", "AIDrugUsePerfFix", 0);
|
||||
if (drugUsePerfFix > 0) {
|
||||
dlog("Applying AI drug use preference fix.", DL_FIX);
|
||||
if (drugUsePerfFix == 1) {
|
||||
// Fix for AI not taking chem_primary_desire in AI.txt as drug use preference when using drugs in their inventory
|
||||
MakeCall(0x42869D, ai_check_drugs_hack_break);
|
||||
MakeCall(0x4286AB, ai_check_drugs_hack_check, 1);
|
||||
MakeCall(0x4286C7, ai_check_drugs_hack_use);
|
||||
}
|
||||
// Fix to allow using only the drugs listed in chem_primary_desire and healing drugs (stimpaks and healing powder)
|
||||
SafeWrite8(0x4286B1, CodeType::JumpZ); // jnz > jz (ai_check_drugs_)
|
||||
SafeWrite8(0x4286C5, CodeType::JumpNZ); // jz > jnz (ai_check_drugs_)
|
||||
dlogr(" Done", DL_FIX);
|
||||
}
|
||||
//int drugUsePerfFix = IniReader::GetConfigInt("Misc", "AIDrugUsePerfFix", 0);
|
||||
//if (drugUsePerfFix > 0) {
|
||||
// dlog("Applying AI drug use preference fix.", DL_FIX);
|
||||
// if (drugUsePerfFix == 1) {
|
||||
// // Fix for AI not taking chem_primary_desire in AI.txt as drug use preference when using drugs in their inventory
|
||||
// MakeCall(0x42869D, ai_check_drugs_hack_break);
|
||||
// MakeCall(0x4286AB, ai_check_drugs_hack_check, 1);
|
||||
// MakeCall(0x4286C7, ai_check_drugs_hack_use);
|
||||
// }
|
||||
// // Fix to allow using only the drugs listed in chem_primary_desire and healing drugs (stimpaks and healing powder)
|
||||
// SafeWrite8(0x4286B1, CodeType::JumpZ); // jnz > jz (ai_check_drugs_)
|
||||
// SafeWrite8(0x4286C5, CodeType::JumpNZ); // jz > jnz (ai_check_drugs_)
|
||||
// dlogr(" Done", DL_FIX);
|
||||
//}
|
||||
|
||||
// Fix for chem_primary_desire values in party member AI packets not being saved correctly
|
||||
HookCall(0x42803E, cai_cap_save_hook);
|
||||
|
||||
@@ -10,6 +10,27 @@
|
||||
namespace sfall
|
||||
{
|
||||
|
||||
static long UseObjOnHook_Script(fo::GameObject* source, fo::GameObject* item, fo::GameObject* target) {
|
||||
BeginHook();
|
||||
argCount = 3;
|
||||
|
||||
args[0] = (DWORD)target; // target
|
||||
args[1] = (DWORD)source; // user
|
||||
args[2] = (DWORD)item; // item
|
||||
|
||||
RunHookScript(HOOK_USEOBJON);
|
||||
|
||||
long result = (cRet > 0) ? rets[0] : -1;
|
||||
EndHook();
|
||||
|
||||
return result; // -1 - default handler
|
||||
}
|
||||
|
||||
long UseObjOnHook_Invoke(fo::GameObject* source, fo::GameObject* item, fo::GameObject* target) {
|
||||
if (!HookScripts::HookHasScript(HOOK_USEOBJON)) return -1;
|
||||
return UseObjOnHook_Script(source, item, target);
|
||||
}
|
||||
|
||||
static void __declspec(naked) UseObjOnHook() {
|
||||
__asm {
|
||||
HookBegin;
|
||||
@@ -369,9 +390,9 @@ void Inject_UseObjOnHook() {
|
||||
|
||||
// the following hooks allows to catch drug use of AI and from action cursor
|
||||
HookCalls(Drug_UseObjOnHook, {
|
||||
0x4285DF, // ai_check_drugs
|
||||
0x4286F8, // ai_check_drugs
|
||||
0x4287F8, // ai_check_drugs
|
||||
//0x4285DF, // ai_check_drugs
|
||||
//0x4286F8, // ai_check_drugs
|
||||
//0x4287F8, // ai_check_drugs
|
||||
0x473573 // inven_action_cursor
|
||||
});
|
||||
}
|
||||
|
||||
@@ -13,4 +13,6 @@ namespace sfall
|
||||
void Inject_ScriptProcedureHook2();
|
||||
void Inject_AdjustPoisonHook();
|
||||
void Inject_AdjustRadsHook();
|
||||
|
||||
long UseObjOnHook_Invoke(fo::GameObject* source, fo::GameObject* item, fo::GameObject* target);
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Game\combatAI.h"
|
||||
#include "Game\inventory.h"
|
||||
#include "Game\items.h"
|
||||
#include "Game\render.h"
|
||||
|
||||
@@ -102,6 +102,7 @@ DWORD HRPAddress(DWORD addr) {
|
||||
char falloutConfigName[65] = {0};
|
||||
|
||||
void InitReplacementHacks() {
|
||||
game::CombatAI::init();
|
||||
game::Inventory::init();
|
||||
game::Items::init();
|
||||
game::Render::init();
|
||||
|
||||
Reference in New Issue
Block a user