Skip to content

Commit

Permalink
Removed NPCStage6Fix from ddraw.ini (always enabled)
Browse files Browse the repository at this point in the history
Moved the code of NPCStage6Fix to BugFixes module.
(to its original relative location, right above MultiHexPathingFix)

Reorganized some code in BugFixes.cpp.
  • Loading branch information
NovaRain committed Sep 27, 2019
1 parent 98199b4 commit 000b116
Show file tree
Hide file tree
Showing 5 changed files with 69 additions and 79 deletions.
3 changes: 0 additions & 3 deletions artifacts/ddraw.ini
Original file line number Diff line number Diff line change
Expand Up @@ -509,9 +509,6 @@ AnimationsAtOnceLimit=120
;Set to 1 to remove the limits that stop the player rolling critical successes/misses in the first few days of game time
RemoveCriticalTimelimits=0

;Set to 1 to enable party members with level 6 protos to reach level 6
NPCStage6Fix=0

;Change the colour of the font used on the main menu for the Fallout/sfall version number and copyright text
;It's the last byte ('3C' by default) that picks the colour used. The first byte supplies additional flags for this option
;MainMenuFontColour=0x00003C
Expand Down
108 changes: 67 additions & 41 deletions sfall/Modules/BugFixes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -817,6 +817,25 @@ static void __declspec(naked) op_wield_obj_critter_adjust_ac_hook() {
}
}

static const DWORD NPCStage6Fix1End = 0x493D16;
static void __declspec(naked) NPCStage6Fix1() {
__asm {
imul eax, edx, 204; // necessary memory = number of NPC records in party.txt * record size
mov ebx, eax; // copy total record size for later memset
call fo::funcoffs::mem_malloc_; // malloc the necessary memory
jmp NPCStage6Fix1End; // call memset to set all malloc'ed memory to 0
}
}

static const DWORD NPCStage6Fix2End = 0x49423A;
static void __declspec(naked) NPCStage6Fix2() {
__asm {
imul edx, edx, 204; // NPC number as listed in party.txt * record size
mov eax, ds:[FO_VAR_partyMemberAIOptions]; // get starting offset of internal NPC table
jmp NPCStage6Fix2End; // eax+edx = offset of specific NPC record
}
}

// Haenlomal: Check path to critter for attack
static void __declspec(naked) MultiHexFix() {
__asm {
Expand All @@ -830,38 +849,38 @@ static void __declspec(naked) MultiHexFix() {
}
}

static const DWORD ai_move_steps_closer_run_object_ret = 0x42A169;
static void __declspec(naked) MultiHexCombatRunFix() {
static const DWORD ai_move_steps_closer_move_object_ret = 0x42A192;
static void __declspec(naked) MultiHexCombatMoveFix() {
__asm {
test [edi + flags + 1], 0x08; // is target multihex?
jnz multiHex;
test [esi + flags + 1], 0x08; // is source multihex?
jz runTile;
jz moveTile;
multiHex:
mov edx, [esp + 4]; // source's destination tilenum
cmp [edi + tile], edx; // target's tilenum
jnz runTile;
jnz moveTile;
add esp, 4;
jmp ai_move_steps_closer_run_object_ret;
runTile:
jmp ai_move_steps_closer_move_object_ret;
moveTile:
retn;
}
}

static const DWORD ai_move_steps_closer_move_object_ret = 0x42A192;
static void __declspec(naked) MultiHexCombatMoveFix() {
static const DWORD ai_move_steps_closer_run_object_ret = 0x42A169;
static void __declspec(naked) MultiHexCombatRunFix() {
__asm {
test [edi + flags + 1], 0x08; // is target multihex?
jnz multiHex;
test [esi + flags + 1], 0x08; // is source multihex?
jz moveTile;
jz runTile;
multiHex:
mov edx, [esp + 4]; // source's destination tilenum
cmp [edi + tile], edx; // target's tilenum
jnz moveTile;
jnz runTile;
add esp, 4;
jmp ai_move_steps_closer_move_object_ret;
moveTile:
jmp ai_move_steps_closer_run_object_ret;
runTile:
retn;
}
}
Expand Down Expand Up @@ -1288,30 +1307,28 @@ static void __declspec(naked) use_inventory_on_hack() {
}
}

static int __stdcall ItemCountFixStdcall(fo::GameObject* who, fo::GameObject* item) {
static int __stdcall ItemCountFix(fo::GameObject* who, fo::GameObject* item) {
int count = 0;
for (int i = 0; i < who->invenSize; i++) {
auto tableItem = &who->invenTable[i];
if (tableItem->object == item) {
count += tableItem->count;
} else if (fo::func::item_get_type(tableItem->object) == fo::item_type_container) {
count += ItemCountFixStdcall(tableItem->object, item);
count += ItemCountFix(tableItem->object, item);
}
}
return count;
}

static void __declspec(naked) ItemCountFix() {
static void __declspec(naked) item_count_hack() {
__asm {
push ebx;
push ecx;
push edx; // save state
push edx; // item
push eax; // container-object
call ItemCountFixStdcall;
pop edx;
pop ecx;
pop ebx; // restore
call ItemCountFix;
pop edx;
pop ecx; // restore
retn;
}
}
Expand Down Expand Up @@ -1870,6 +1887,14 @@ static void __declspec(naked) db_freadInt_hook() {
}
}

static void __declspec(naked) op_attack_hook() {
__asm {
mov esi, dword ptr [esp + 0x3C + 4]; // free_move
mov ebx, dword ptr [esp + 0x40 + 4]; // add amount damage to target
jmp fo::funcoffs::gdialogActive_;
}
}

static void __declspec(naked) combat_attack_hack() {
__asm {
mov ebx, ds:[FO_VAR_main_ctd + 0x2C]; // amountTarget
Expand All @@ -1883,14 +1908,6 @@ static void __declspec(naked) combat_attack_hack() {
}
}

static void __declspec(naked) op_attack_hook() {
__asm {
mov esi, dword ptr [esp + 0x3C + 4]; // free_move
mov ebx, dword ptr [esp + 0x40 + 4]; // add amount damage to target
jmp fo::funcoffs::gdialogActive_;
}
}

static void __declspec(naked) op_use_obj_on_obj_hack() {
__asm {
test eax, eax; // source
Expand Down Expand Up @@ -2268,14 +2285,14 @@ static void __declspec(naked) wmInterfaceInit_hack() {

static long __fastcall GetFreeTilePlacement(long elev, long tile) {
long count = 0, dist = 1;
long freeTile = tile;
long checkTile = tile;
long rotation = fo::var::rotation;
while (fo::func::obj_blocking_at(0, freeTile, elev)) {
freeTile = fo::func::tile_num_in_direction(freeTile, rotation, dist);
while (fo::func::obj_blocking_at(0, checkTile, elev)) {
checkTile = fo::func::tile_num_in_direction(checkTile, rotation, dist);
if (++count > 5 && ++dist > 5) return tile;
if (++rotation > 5) rotation = 0;
}
return freeTile;
return checkTile; // free tile
}

static void __declspec(naked) map_check_state_hook() {
Expand Down Expand Up @@ -2497,6 +2514,15 @@ void BugFixes::init()
dlogr(" Done", DL_INIT);
//}

//if (GetConfigInt("Misc", "NPCStage6Fix", 1)) {
dlog("Applying NPC Stage 6 Fix.", DL_INIT);
MakeJump(0x493CE9, NPCStage6Fix1);
SafeWrite8(0x494063, 6); // loop should look for a potential 6th stage
SafeWrite8(0x4940BB, 204); // move pointer by 204 bytes instead of 200
MakeJump(0x494224, NPCStage6Fix2);
dlogr(" Done", DL_INIT);
//}

//if (GetConfigInt("Misc", "MultiHexPathingFix", 1)) {
dlog("Applying MultiHex Pathing Fix.", DL_INIT);
MakeCalls(MultiHexFix, {0x42901F, 0x429170});
Expand Down Expand Up @@ -2602,7 +2628,7 @@ void BugFixes::init()
MakeCall(0x471A94, use_inventory_on_hack);

// Fix item_count function returning incorrect value when there is a container-item inside
MakeJump(0x47808C, ItemCountFix); // replacing item_count_ function
MakeJump(0x47808C, item_count_hack); // replacing item_count_ function

// Fix for Sequence stat value not being printed correctly when using "print to file" option
MakeCall(0x4396F5, Save_as_ASCII_hack, 2);
Expand Down Expand Up @@ -2766,14 +2792,6 @@ void BugFixes::init()
// Fix returned result value when the file is missing
HookCall(0x4C6162, db_freadInt_hook);

// Fix for attack_complex still causing minimum damage to the target when the attacker misses
MakeCall(0x422FE5, combat_attack_hack, 1);

// Fix for critter_mod_skill taking a negative amount value as a positive
dlog("Applying critter_mod_skill fix.", DL_INIT);
SafeWrite8(0x45B910, 0x7E); // jbe > jle
dlogr(" Done", DL_INIT);

// Fix and repurpose the unused called_shot/num_attack arguments of attack_complex function
// also change the behavior of the result flags arguments
// called_shot - additional damage, when the damage received by the target is above the specified minimum
Expand All @@ -2788,6 +2806,14 @@ void BugFixes::init()
dlogr(" Done", DL_INIT);
}

// Fix for attack_complex still causing minimum damage to the target when the attacker misses
MakeCall(0x422FE5, combat_attack_hack, 1);

// Fix for critter_mod_skill taking a negative amount value as a positive
dlog("Applying critter_mod_skill fix.", DL_INIT);
SafeWrite8(0x45B910, 0x7E); // jbe > jle
dlogr(" Done", DL_INIT);

// Fix crash when calling use_obj/use_obj_on_obj without using set_self in global scripts
// also change the behavior of use_obj_on_obj function
// if the object uses the item on itself, then another function is called (not a bug fix)
Expand Down
33 changes: 0 additions & 33 deletions sfall/Modules/MiscPatches.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -207,27 +207,6 @@ static void __declspec(naked) CorpseHitFix2b() {
}
}

static const DWORD NPCStage6Fix1End = 0x493D16;
static void __declspec(naked) NPCStage6Fix1() {
__asm {
mov eax, 204; // set record size to 204 bytes
imul eax, edx; // multiply by number of NPC records in party.txt
mov ebx, eax; // copy total record size for later memset
call fo::funcoffs::mem_malloc_; // malloc the necessary memory
jmp NPCStage6Fix1End; // call memset to set all malloc'ed memory to 0
}
}

static const DWORD NPCStage6Fix2End = 0x49423A;
static void __declspec(naked) NPCStage6Fix2() {
__asm {
mov eax, 204; // record size is 204 bytes
imul edx, eax; // multiply by NPC number as listed in party.txt
mov eax, dword ptr ds:[FO_VAR_partyMemberAIOptions]; // get starting offset of internal NPC table
jmp NPCStage6Fix2End; // eax+edx = offset of specific NPC record
}
}

static const DWORD ScannerHookRet = 0x41BC1D;
static const DWORD ScannerHookFail = 0x41BC65;
static void __declspec(naked) ScannerAutomapHook() {
Expand Down Expand Up @@ -512,17 +491,6 @@ void CorpseLineOfFireFix() {
}
}

void NpcStage6Fix() {
if (GetConfigInt("Misc", "NPCStage6Fix", 1)) {
dlog("Applying NPC Stage 6 Fix.", DL_INIT);
MakeJump(0x493CE9, NPCStage6Fix1);
SafeWrite8(0x494063, 6); // loop should look for a potential 6th stage
SafeWrite8(0x4940BB, 204); // move pointer by 204 bytes instead of 200
MakeJump(0x494224, NPCStage6Fix2);
dlogr(" Done", DL_INIT);
}
}

void MotionScannerFlagsPatch() {
DWORD flags;
if (flags = GetConfigInt("Misc", "MotionScannerFlags", 1)) {
Expand Down Expand Up @@ -810,7 +778,6 @@ void MiscPatches::init() {
BlockCall(0x4425E6);

OverrideMusicDirPatch();
NpcStage6Fix();
BoostScriptDialogLimitPatch();
MotionScannerFlagsPatch();
EncounterTableSizePatch();
Expand Down
2 changes: 1 addition & 1 deletion sfall/Modules/Scripting/Arrays.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -712,7 +712,7 @@ void SaveArray(const ScriptValue& key, DWORD id) {
it->second.key.unset();
}
}
// make "saved" array
// make array "saved"
itArray->second.key.setByType(key.rawValue(), key.type());
savedArrays.emplace(itArray->second.key, id); // savedArrays[itArray->second.key] = id;
} else { // key of int(0) is used to "unsave" array without destroying it
Expand Down
2 changes: 1 addition & 1 deletion sfall/Modules/Scripting/Handlers/Misc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -694,7 +694,7 @@ void __declspec(naked) op_set_bodypart_hit_modifier() {
}
}

static char* valueOutRange = "%s() - argument values out of range.";
static const char* valueOutRange = "%s() - argument values out of range.";

void sf_set_critical_table(OpcodeContext& ctx) {
DWORD critter = ctx.arg(0).asInt(),
Expand Down

1 comment on commit 000b116

@NovaRain
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just some trivial changes like re-ordering code.

Please sign in to comment.