Code correction to two previous commits

This commit is contained in:
NovaRain
2021-05-09 08:49:19 +08:00
parent 45a268ee77
commit 8c09223812
6 changed files with 38 additions and 32 deletions
+10 -11
View File
@@ -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() {
+3
View File
@@ -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);
+6 -8
View File
@@ -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
}
+1
View File
@@ -19,6 +19,7 @@
#pragma once
extern long PerkLevelMod;
extern bool perkHeaveHoModTweak;
void Perks_Init();
void PerksReset();
+14 -10
View File
@@ -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);
+4 -3
View File
@@ -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() {