mirror of
https://github.com/sfall-team/sfall.git
synced 2026-07-27 16:52:34 -07:00
Rewrote the score calculation in AIBestWeaponFix (#370)
Changed FastShotFix to be disabled by default.
This commit is contained in:
+7
-8
@@ -438,10 +438,9 @@ SkipOpeningMovies=0
|
||||
;Set to 0 to disable
|
||||
NPCsTryToSpendExtraAP=0
|
||||
|
||||
;Set to 1 to fix NPCs not checking weapon perks properly when choosing the best weapon in combat
|
||||
;Set to 2 to change the priority multiplier for having weapon perk to 3x (the original is 5x)
|
||||
;Note that enabling this option can significantly affect the weapon of choice for some NPCs
|
||||
AIBestWeaponFix=0
|
||||
;Set to 1 to fix the priority score calculation for choosing the best weapon for NPCs
|
||||
;Note that enabling this option can affect the weapon of choice for some NPCs
|
||||
AIBestWeaponFix=1
|
||||
|
||||
;Set to 1 to fix NPCs not taking chem_primary_desire in AI.txt as drug use preference when using drugs in their inventory
|
||||
;Set to 2 to allow NPCs to use only the drugs listed in chem_primary_desire and healing drugs (stimpaks and healing powder)
|
||||
@@ -546,11 +545,11 @@ RemoveCriticalTimelimits=0
|
||||
;MainMenuBigFontColour=0x3C
|
||||
|
||||
;Alternative behaviors to the Fast Shot trait
|
||||
;0 - Fallout 2 original behavior: -1 AP cost for ranged weapons; aimed attacks are disabled
|
||||
;1 - Haenlomal's fix: aimed attacks are enabled for melee/unarmed weapons and HtH attacks
|
||||
;0 - Fallout 2 original behavior: -1 AP cost for ranged weapons. Aimed attacks are disabled
|
||||
;1 - Haenlomal's tweak: aimed attacks are enabled for melee/unarmed weapons and HtH attacks
|
||||
;2 - Alternative behavior: apply -1 AP cost to melee/unarmed weapons and HtH attacks
|
||||
;3 - Fallout 1 original behavior: -1 AP cost for all weapons; aimed attacks are disabled
|
||||
FastShotFix=1
|
||||
;3 - Fallout 1 original behavior: -1 AP cost for all weapons. Aimed attacks are disabled
|
||||
FastShotFix=0
|
||||
|
||||
;Set to 1 to fix the carry weight penalty of the Small Frame trait not being applied to bonus Strength points
|
||||
SmallFrameFix=0
|
||||
|
||||
+12
-12
@@ -66,11 +66,11 @@ void __declspec(naked) Tilemap::obj_path_blocking_at_() {
|
||||
}
|
||||
}
|
||||
|
||||
static std::vector<int> buildLineTiles;
|
||||
//static std::vector<int> buildLineTiles;
|
||||
|
||||
static bool TileExists(long tile) {
|
||||
return (std::find(buildLineTiles.cbegin(), buildLineTiles.cend(), tile) != buildLineTiles.cend());
|
||||
}
|
||||
//static bool TileExists(long tile) {
|
||||
// return (std::find(buildLineTiles.cbegin(), buildLineTiles.cend(), tile) != buildLineTiles.cend());
|
||||
//}
|
||||
|
||||
// Fixed and improved implementation of tile_num_beyond_ engine function
|
||||
// - correctly gets the tile from the constructed line
|
||||
@@ -78,11 +78,11 @@ static bool TileExists(long tile) {
|
||||
long __fastcall Tilemap::tile_num_beyond(long sourceTile, long targetTile, long maxRange) {
|
||||
if (maxRange <= 0 || sourceTile == targetTile) return sourceTile;
|
||||
|
||||
if (buildLineTiles.empty()) {
|
||||
/*if (buildLineTiles.empty()) {
|
||||
buildLineTiles.reserve(100);
|
||||
} else {
|
||||
buildLineTiles.clear();
|
||||
}
|
||||
}*/
|
||||
|
||||
long currentRange = fo::func::tile_dist(sourceTile, targetTile);
|
||||
//fo::func::debug_printf("\ntile_dist: %d", currentRange);
|
||||
@@ -121,11 +121,11 @@ long __fastcall Tilemap::tile_num_beyond(long sourceTile, long targetTile, long
|
||||
long tile = fo::func::tile_num(target_X, target_Y);
|
||||
//fo::func::debug_printf("\ntile_num: %d [x:%d y:%d]", tile, target_X, target_Y);
|
||||
if (tile != lastTile) {
|
||||
if (!TileExists(tile)) {
|
||||
//if (!TileExists(tile)) {
|
||||
long dist = fo::func::tile_dist(targetTile, tile);
|
||||
if ((dist + currentRange) >= maxRange || fo::func::tile_on_edge(tile)) return tile;
|
||||
buildLineTiles.push_back(tile);
|
||||
}
|
||||
// buildLineTiles.push_back(tile);
|
||||
//}
|
||||
lastTile = tile;
|
||||
}
|
||||
stepCounter = 0;
|
||||
@@ -155,11 +155,11 @@ long __fastcall Tilemap::tile_num_beyond(long sourceTile, long targetTile, long
|
||||
long tile = fo::func::tile_num(target_X, target_Y);
|
||||
//fo::func::debug_printf("\ntile_num: %d [x:%d y:%d]", tile, target_X, target_Y);
|
||||
if (tile != lastTile) {
|
||||
if (!TileExists(tile)) {
|
||||
//if (!TileExists(tile)) {
|
||||
long dist = fo::func::tile_dist(targetTile, tile);
|
||||
if ((dist + currentRange) >= maxRange || fo::func::tile_on_edge(tile)) return tile;
|
||||
buildLineTiles.push_back(tile);
|
||||
}
|
||||
// buildLineTiles.push_back(tile);
|
||||
//}
|
||||
lastTile = tile;
|
||||
}
|
||||
stepCounter = 0;
|
||||
|
||||
@@ -1824,6 +1824,15 @@ static void __declspec(naked) op_obj_can_hear_obj_hack() {
|
||||
}
|
||||
}
|
||||
|
||||
static void __declspec(naked) ai_best_weapon_hack() {
|
||||
__asm {
|
||||
sar edx, 31;
|
||||
sub eax, edx
|
||||
sar eax, 1;
|
||||
retn;
|
||||
}
|
||||
}
|
||||
|
||||
static void __declspec(naked) ai_best_weapon_hook() {
|
||||
__asm {
|
||||
mov eax, [esp + 0xF4 - 0x10 + 4]; // prev.item
|
||||
@@ -3445,15 +3454,15 @@ void BugFixes::init()
|
||||
dlogr(" Done", DL_FIX);
|
||||
}
|
||||
|
||||
// Fix for AI not checking weapon perks properly when searching for the best weapon
|
||||
int bestWeaponPerkFix = IniReader::GetConfigInt("Misc", "AIBestWeaponFix", 0);
|
||||
if (bestWeaponPerkFix > 0) {
|
||||
if (IniReader::GetConfigInt("Misc", "AIBestWeaponFix", 1)) {
|
||||
dlog("Applying AI best weapon choice fix.", DL_FIX);
|
||||
// Fix for the incorrect item being checked for the presence of weapon perks
|
||||
HookCall(0x42954B, ai_best_weapon_hook);
|
||||
// also change the priority multiplier for having weapon perk to 3x (the original is 5x)
|
||||
if (bestWeaponPerkFix > 1) {
|
||||
SafeWriteBatch<BYTE>(0x55, {0x42955E, 0x4296E7}); // lea eax, [edx * 2];
|
||||
}
|
||||
// Corrects the calculation of the weapon score to: (maxDmg + minDmg) / 4
|
||||
SafeWriteBatch<BYTE>(0x01, {0x4294E2, 0x429675}); // sub > add
|
||||
MakeCalls(ai_best_weapon_hack, {0x4294E6, 0x429679});
|
||||
// Corrects the weapon score multiplier for having perks to 2x (was 5x)
|
||||
SafeWriteBatch<BYTE>(0x15, {0x42955E, 0x4296E7}); // lea eax, [edx*4] > lea eax, [edx]
|
||||
dlogr(" Done", DL_FIX);
|
||||
}
|
||||
|
||||
|
||||
@@ -70,7 +70,6 @@ static long heroIsFemale = -1;
|
||||
// Searches the special character in the text and removes the text depending on the player's gender
|
||||
// example: <MaleText^FemaleText>
|
||||
static long __fastcall ReplaceGenderWord(fo::MessageNode* msgData, DWORD* msgFile) {
|
||||
|
||||
if (!InDialog() || msgData->flags & MSG_GENDER_CHECK_FLG) return 1;
|
||||
if (heroIsFemale < 0) heroIsFemale = fo::HeroIsFemale();
|
||||
|
||||
|
||||
@@ -1139,7 +1139,7 @@ checkType:
|
||||
}
|
||||
}
|
||||
|
||||
// Haenlomal's fix
|
||||
// Haenlomal's tweak
|
||||
static void __declspec(naked) item_w_called_shot_hack() {
|
||||
static const DWORD FastShotTraitFix_End = 0x478E7F;
|
||||
using namespace fo;
|
||||
@@ -1169,18 +1169,18 @@ cantUse:
|
||||
}
|
||||
|
||||
static void FastShotTraitFix() {
|
||||
switch (IniReader::GetConfigInt("Misc", "FastShotFix", 1)) {
|
||||
switch (IniReader::GetConfigInt("Misc", "FastShotFix", 0)) {
|
||||
case 1:
|
||||
dlog("Applying Fast Shot trait patch. (Haenlomal's fix)", DL_INIT);
|
||||
dlog("Applying Fast Shot trait patch (Haenlomal's tweak).", DL_INIT);
|
||||
MakeJump(0x478E79, item_w_called_shot_hack);
|
||||
goto fix;
|
||||
case 2:
|
||||
dlog("Applying Fast Shot trait patch. (Alternative behavior)", DL_INIT);
|
||||
dlog("Applying Fast Shot trait patch (Alternative behavior).", DL_INIT);
|
||||
SafeWrite16(0x478C9F, 0x9090);
|
||||
HookCalls((void*)0x478C7D, {0x478BB8, 0x478BC7, 0x478BD6, 0x478BEA, 0x478BF9, 0x478C08, 0x478C2F});
|
||||
goto done;
|
||||
case 3:
|
||||
dlog("Applying Fast Shot trait patch. (Fallout 1 behavior)", DL_INIT);
|
||||
dlog("Applying Fast Shot trait patch (Fallout 1 behavior).", DL_INIT);
|
||||
HookCall(0x478C97, (void*)fo::funcoffs::item_hit_with_);
|
||||
SafeWrite16(0x478C9E, CodeType::JumpZ << 8); // ignore all unarmed attacks (cmp eax, 0; jz)
|
||||
goto done;
|
||||
|
||||
Reference in New Issue
Block a user