Fixed a crash when opening a file whose name contains the '%' char

Corrected the code in the previous commit.
This commit is contained in:
NovaRain
2021-08-19 13:33:52 +08:00
parent 94dd41f7ac
commit 3129e27737
6 changed files with 52 additions and 19 deletions
+20 -5
View File
@@ -67,7 +67,7 @@ void __stdcall CombatAI::ai_check_drugs(fo::GameObject* source) {
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)
// [FIX] for AI not checking minimum hp properly for using healing drugs (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) {
@@ -110,7 +110,7 @@ void __stdcall CombatAI::ai_check_drugs(fo::GameObject* source) {
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
// [FIX] for AI not taking chem_primary_desire in AI.txt as a preference list when using drugs in the inventory
if (drugUsePerfFixMode == 1) {
item = fo::func::inven_find_type(source, fo::ItemType::item_type_drug, &slot);
if (!item) {
@@ -121,7 +121,7 @@ void __stdcall CombatAI::ai_check_drugs(fo::GameObject* source) {
}
} while (counter < 3);
} else {
// if the durg is equal to the first item of preference, then check the next two (vanilla behavior)
// if the drug is equal to the item in the preference list, then check the next (vanilla behavior)
while (item->protoId == cap->chem_primary_desire[counter]) if (++counter > 2) break;
}
@@ -153,7 +153,7 @@ void __stdcall CombatAI::ai_check_drugs(fo::GameObject* source) {
}
}
// search for drugs on the map
if (lastItem || (!drugWasUsed /*&& noInvenDrug*/)) {
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);
@@ -191,10 +191,25 @@ static void __declspec(naked) ai_check_drugs_hack() {
}
}
static void __declspec(naked) ai_can_use_drug_hack() {
__asm {
push ecx; // item
call Items::IsHealingItem;
pop ecx;
test al, al;
retn;
}
}
void CombatAI::init() {
// Replace ai_check_drugs_ function
// Replace ai_check_drugs_ function for code fixes and checking healing items
sf::MakeJump(fo::funcoffs::ai_check_drugs_, ai_check_drugs_hack); // 0x428480
// Change ai_can_use_drug_ function code to check healing items
sf::MakeCall(0x429BDE, ai_can_use_drug_hack, 6);
sf::SafeWrite8(0x429BE9, sf::CodeType::JumpNZ); // jz > jnz
sf::SafeWrite8(0x429BF1, sf::CodeType::JumpShort); // jnz > jmp
drugUsePerfFixMode = sf::IniReader::GetConfigInt("Misc", "AIDrugUsePerfFix", 0);
if (drugUsePerfFixMode > 0) sf::dlogr("Applying AI drug use preference fix.", DL_FIX);
}
+16 -7
View File
@@ -26,16 +26,23 @@ static constexpr int reloadCostAP = 2; // engine default reload AP cost
static std::array<long, 3> healingItemPids = {fo::PID_STIMPAK, fo::PID_SUPER_STIMPAK, fo::PID_HEALING_POWDER};
void Items::SetHealingPID(long index, long pid) {
/*if (index >= 0 && index < 3)*/ healingItemPids[index] = pid;
long Items::GetHealingPID(long index) {
return healingItemPids[index];
}
bool Items::IsHealingItem(fo::GameObject* item) {
if (std::find(healingItemPids.cbegin(), healingItemPids.cend(), item->protoId) != healingItemPids.cend()) return true;
void Items::SetHealingPID(long index, long pid) {
healingItemPids[index] = pid;
}
bool __fastcall Items::IsHealingItem(fo::GameObject* item) {
//for each (long pid in healingItemPids) if (pid == item->protoId) return true;
if (healingItemPids[0] == item->protoId || healingItemPids[1] == item->protoId || healingItemPids[2] == item->protoId) {
return true;
}
fo::Proto* proto;
if (fo::GetProto(item->protoId, &proto)) {
return ((proto->item.flagsExt & fo::ItemFlags::HealingItem) != 0); // TODO: check asm code
return (proto->item.flagsExt & fo::ItemFlags::HealingItem) != 0;
}
return false;
}
@@ -54,8 +61,10 @@ bool Items::UseDrugItemFunc(fo::GameObject* source, fo::GameObject* item) {
// 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);
if (sf::UseObjOnHook_Invoke(source, item, source) == -1) { // default handler
return fo::func::item_d_take_drug(source, item);
}
return -1; // cancel the drug use
}
long Items::item_count(fo::GameObject* who, fo::GameObject* item) {
+2 -1
View File
@@ -13,9 +13,10 @@ class Items {
public:
static void init();
static long GetHealingPID(long index);
static void SetHealingPID(long index, long pid);
static bool IsHealingItem(fo::GameObject* item);
static bool __fastcall IsHealingItem(fo::GameObject* item);
// True - use failed
static bool UseDrugItemFunc(fo::GameObject* source, fo::GameObject* item);
+1 -1
View File
@@ -3645,7 +3645,7 @@ void BugFixes::init()
//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
// // Fix for AI not taking chem_primary_desire in AI.txt as a preference list when using drugs in the inventory
// MakeCall(0x42869D, ai_check_drugs_hack_break);
// MakeCall(0x4286AB, ai_check_drugs_hack_check, 1);
// MakeCall(0x4286C7, ai_check_drugs_hack_use);
+5
View File
@@ -712,6 +712,11 @@ void FileSystem::init() {
MakeJump(0x47CCE2, FSLoadHook); // LoadGame_
LoadGameHook::OnGameReset() += FileSystemReset;
// Fix crash if the filename contains a '%' character (relevant to SFX files)
// xfopen_ - remove sprintf_ function calls that do nothing (probably just checking the filename for the '%' formatting char?)
BlockCall(0x4DEF12);
BlockCall(0x4DEF84);
}
}
+8 -5
View File
@@ -118,11 +118,17 @@ static void InitModules() {
// initialize all modules
manager.add<BugFixes>(); // fixes should be applied at the beginning
manager.add<FileSystem>();
manager.add<Graphics>();
manager.add<Input>();
manager.add<LoadOrder>();
manager.add<LoadGameHook>();
manager.add<MainLoopHook>();
manager.add<Books>();
manager.add<Criticals>();
manager.add<Elevators>();
manager.add<Movies>();
manager.add<MainMenu>();
manager.add<Interface>();
@@ -136,8 +142,7 @@ static void InitModules() {
manager.add<Perks>();
manager.add<Combat>();
manager.add<Skills>();
manager.add<FileSystem>();
manager.add<Criticals>();
manager.add<Karma>();
manager.add<Tiles>();
manager.add<Credits>();
@@ -151,12 +156,10 @@ static void InitModules() {
manager.add<Drugs>(); // should be loaded before PartyControl
manager.add<PartyControl>();
manager.add<BurstMods>();
manager.add<Books>();
manager.add<Explosions>();
manager.add<Message>();
manager.add<Elevators>();
manager.add<KillCounter>();
//
manager.add<AI>();
manager.add<DamageMod>();
manager.add<Animations>();