diff --git a/artifacts/ddraw.ini b/artifacts/ddraw.ini index a56dda1b..af8d1559 100644 --- a/artifacts/ddraw.ini +++ b/artifacts/ddraw.ini @@ -124,12 +124,12 @@ WorldMapTravelMarkers=0 ;Uncomment these lines to change the appearance of the markers ;The color index in Fallout default palette (valid range: 1..255; default is 134) ;TravelMarkerColor=134 -;The lengh of the dots in pixels (valid range: 1..10) +;The length of the dots in pixels (valid range: 1..10) ;TravelMarkerLength=2 ;The spacing between the dots in pixels (valid range: 1..10) ;TravelMarkerSpaces=2 -;Set to 1 to display terrain types when moving the cursor over the green triangle on the world map +;Set to 1 to display terrain types when hovering the cursor over the player's marker on the world map WorldMapTerrainInfo=0 ;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX diff --git a/sfall/Modules/AI.cpp b/sfall/Modules/AI.cpp index 7f09defc..f976f8ab 100644 --- a/sfall/Modules/AI.cpp +++ b/sfall/Modules/AI.cpp @@ -30,8 +30,6 @@ namespace sfall using namespace fo; using namespace Fields; -typedef std::unordered_map::const_iterator iter; - static std::unordered_map targets; static std::unordered_map sources; @@ -193,75 +191,24 @@ static void __fastcall CombatAttackHook(fo::GameObject* source, fo::GameObject* static void __declspec(naked) combat_attack_hook() { __asm { + push eax; push ecx; push edx; - push eax; mov ecx, eax; // source call CombatAttackHook; // edx - target + pop edx; + pop ecx; pop eax; - pop edx; - pop ecx; jmp fo::funcoffs::combat_attack_; } } -static DWORD combatDisabled; -void __stdcall AIBlockCombat(DWORD i) { - combatDisabled = i ? 1 : 0; -} - -static std::string combatBlockedMessage; -static void _stdcall CombatBlocked() { - fo::func::display_print(combatBlockedMessage.c_str()); -} - -static const DWORD BlockCombatHook1Ret1 = 0x45F6B4; -static const DWORD BlockCombatHook1Ret2 = 0x45F6D7; -static void __declspec(naked) BlockCombatHook1() { - __asm { - mov eax, combatDisabled; - test eax, eax; - jz end; - call CombatBlocked; - jmp BlockCombatHook1Ret2; -end: - mov eax, 0x14; - jmp BlockCombatHook1Ret1; - } -} - -static void __declspec(naked) BlockCombatHook2() { - __asm { - mov eax, dword ptr ds:[FO_VAR_intfaceEnabled]; - test eax, eax; - jz end; - mov eax, combatDisabled; - test eax, eax; - jz succeed; - push ecx; - push edx; - call CombatBlocked; - pop edx; - pop ecx; - xor eax, eax; - retn; -succeed: - inc eax; -end: - retn; - } -} - void AI::init() { HookCalls(combat_attack_hook, { 0x426A95, // combat_attack_this_ 0x42A796 // ai_attack_ }); - MakeJump(0x45F6AF, BlockCombatHook1); // intface_use_item_ - HookCall(0x4432A6, BlockCombatHook2); // game_handle_input_ - combatBlockedMessage = Translate("sfall", "BlockedCombat", "You cannot enter combat at this time."); - RetryCombatMinAP = GetConfigInt("Misc", "NPCsTryToSpendExtraAP", 0); if (RetryCombatMinAP > 0) { dlog("Applying retry combat patch.", DL_INIT); @@ -289,12 +236,12 @@ void AI::init() { } fo::GameObject* _stdcall AIGetLastAttacker(fo::GameObject* target) { - iter itr = sources.find(target); + const auto itr = sources.find(target); return (itr != sources.end()) ? itr->second : 0; } fo::GameObject* _stdcall AIGetLastTarget(fo::GameObject* source) { - iter itr = targets.find(source); + const auto itr = targets.find(source); return (itr != targets.end()) ? itr->second : 0; } diff --git a/sfall/Modules/AI.h b/sfall/Modules/AI.h index d123f4ff..cc25b556 100644 --- a/sfall/Modules/AI.h +++ b/sfall/Modules/AI.h @@ -22,7 +22,7 @@ #include "Module.h" -namespace sfall +namespace sfall { class AI : public Module { @@ -38,6 +38,4 @@ void _stdcall AICombatEnd(); fo::GameObject* _stdcall AIGetLastAttacker(fo::GameObject* target); fo::GameObject* _stdcall AIGetLastTarget(fo::GameObject* source); -void _stdcall AIBlockCombat(DWORD i); - } diff --git a/sfall/Modules/Combat.cpp b/sfall/Modules/Combat.cpp index 1937c82e..e137b04d 100644 --- a/sfall/Modules/Combat.cpp +++ b/sfall/Modules/Combat.cpp @@ -25,6 +25,8 @@ #include "LoadGameHook.h" #include "Objects.h" +#include "SubModules\CombatBlock.h" + #include "Combat.h" namespace sfall @@ -480,6 +482,7 @@ static void Combat_OnGameLoad() { } void Combat::init() { + CombatBlockedInit(); CombatProcFix(); MakeCall(0x424B76, compute_damage_hack, 2); // KnockbackMod diff --git a/sfall/Modules/Credits.cpp b/sfall/Modules/Credits.cpp index 70c53085..3181da3d 100644 --- a/sfall/Modules/Credits.cpp +++ b/sfall/Modules/Credits.cpp @@ -70,6 +70,7 @@ static const char* ExtraLines[] = { "Continuum", "Drobovik", "Burn", + "Lexx", "Anyone who has used sfall in their own mods", "The bug reporters and feature requesters", "", diff --git a/sfall/Modules/Scripting/Handlers/Misc.cpp b/sfall/Modules/Scripting/Handlers/Misc.cpp index 7e2394cd..3bc23e2d 100644 --- a/sfall/Modules/Scripting/Handlers/Misc.cpp +++ b/sfall/Modules/Scripting/Handlers/Misc.cpp @@ -35,6 +35,8 @@ #include "..\Arrays.h" #include "..\OpcodeContext.h" +#include "..\..\SubModules\CombatBlock.h" + #include "Misc.h" namespace sfall @@ -928,7 +930,7 @@ void __declspec(naked) op_block_combat() { mov esi, ecx; _GET_ARG_INT(end); push eax; - call AIBlockCombat; + call SetBlockCombat; end: mov ecx, esi; retn; diff --git a/sfall/Modules/Scripting/Handlers/Utils.cpp b/sfall/Modules/Scripting/Handlers/Utils.cpp index 380d05c3..87e534b1 100644 --- a/sfall/Modules/Scripting/Handlers/Utils.cpp +++ b/sfall/Modules/Scripting/Handlers/Utils.cpp @@ -39,11 +39,13 @@ static bool FalloutStringCompare(const char* str1, const char* str2, long codePa while (true) { unsigned char c1 = *str1; unsigned char c2 = *str2; + if (c1 == 0 && c2 == 0) return true; // end - strings are equal if (c1 == 0 || c2 == 0) return false; // strings are not equal str1++; str2++; if (c1 == c2) continue; + if (codePage == 866) { // replace Russian 'x' to English (Fallout specific) if (c1 == 229) c1 -= 229 - 'x'; @@ -60,16 +62,16 @@ static bool FalloutStringCompare(const char* str1, const char* str2, long codePa // 128 - 255 (international/extended) switch (codePage) { case 866: - if (c1 != 149 && c2 != 149) { // code used for the 'bullet' character in Fallout font + if (c1 != 149 && c2 != 149) { // code used for the 'bullet' character in Fallout font (the Russian letter 'X' uses Latin letter) // upper to lower case - if (c1 >= 0x80 && c1 <= 0x9F) { + if (c1 >= 128 && c1 <= 159) { c1 |= 32; } else if (c1 >= 224 && c1 <= 239) { c1 -= 48; // shift lower range } else if (c1 == 240) { c1++; } - if (c2 >= 0x80 && c2 <= 0x9F) { + if (c2 >= 128 && c2 <= 159) { c2 |= 32; } else if (c2 >= 224 && c2 <= 239) { c2 -= 48; // shift lower range diff --git a/sfall/Modules/SubModules/CombatBlock.cpp b/sfall/Modules/SubModules/CombatBlock.cpp new file mode 100644 index 00000000..8c8f928e --- /dev/null +++ b/sfall/Modules/SubModules/CombatBlock.cpp @@ -0,0 +1,74 @@ +/* + * sfall + * Copyright (C) 2008-2020 The sfall team + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "..\..\main.h" +#include "..\..\FalloutEngine\Fallout2.h" + +#include "CombatBlock.h" + +namespace sfall +{ + +static bool combatDisabled; +static std::string combatBlockedMessage; + +static void __stdcall CombatBlocked() { + fo::func::display_print(combatBlockedMessage.c_str()); +} + +static const DWORD BlockCombatHook1Ret1 = 0x45F6AF; +static const DWORD BlockCombatHook1Ret2 = 0x45F6D7; +static void __declspec(naked) intface_use_item_hook() { + __asm { + cmp combatDisabled, 0; + jne block; + jmp BlockCombatHook1Ret1; +block: + call CombatBlocked; + jmp BlockCombatHook1Ret2; + } +} + +static void __declspec(naked) game_handle_input_hook() { + __asm { + mov eax, dword ptr ds:[FO_VAR_intfaceEnabled]; + test eax, eax; + jz end; + cmp combatDisabled, 0; // eax = 1 + je end; // no blocked + push edx; + call CombatBlocked; + pop edx; + xor eax, eax; +end: + retn; + } +} + +void __stdcall SetBlockCombat(long toggle) { + combatDisabled = toggle != 0; +} + +void CombatBlockedInit() { + HookCall(0x45F626, intface_use_item_hook); // jnz hook + HookCall(0x4432A6, game_handle_input_hook); + + combatBlockedMessage = Translate("sfall", "BlockedCombat", "You cannot enter combat at this time."); +} + +} diff --git a/sfall/Modules/SubModules/CombatBlock.h b/sfall/Modules/SubModules/CombatBlock.h new file mode 100644 index 00000000..e7032de1 --- /dev/null +++ b/sfall/Modules/SubModules/CombatBlock.h @@ -0,0 +1,28 @@ +/* + * sfall + * Copyright (C) 2008-2020 The sfall team + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once + +namespace sfall +{ + +void CombatBlockedInit(); + +void __stdcall SetBlockCombat(long toggle); + +} diff --git a/sfall/ddraw.vcxproj b/sfall/ddraw.vcxproj index 1e57417e..999e7649 100644 --- a/sfall/ddraw.vcxproj +++ b/sfall/ddraw.vcxproj @@ -313,6 +313,7 @@ + @@ -405,6 +406,7 @@ + diff --git a/sfall/ddraw.vcxproj.filters b/sfall/ddraw.vcxproj.filters index 1a87a52a..59c628d9 100644 --- a/sfall/ddraw.vcxproj.filters +++ b/sfall/ddraw.vcxproj.filters @@ -16,6 +16,15 @@ {1e66856c-4830-4ca0-a998-15b697208223} + + {023f674e-f534-4889-af91-c5f1ef3a8913} + + + {f35af494-a226-4c24-9ac2-9876f46b7a6b} + + + {66d430dc-ddd0-41e3-a13d-bf1d5a1a1064} + @@ -31,15 +40,6 @@ Modules - - Modules - - - Modules - - - Modules - Modules @@ -55,24 +55,15 @@ Modules - - Modules - Modules Modules - - Modules - Modules - - Modules - Modules @@ -82,21 +73,9 @@ Modules - - Modules - - - Modules - - - Modules - Modules - - Modules - @@ -109,9 +88,6 @@ Modules - - Modules - Modules @@ -192,30 +168,15 @@ - - Modules - Modules - - Modules - Modules Modules - - Modules - - - Modules - - - Modules - Modules @@ -286,6 +247,57 @@ + + Modules\SubModules + + + Modules\SimplePatches + + + Modules\SimplePatches + + + Modules\SimplePatches + + + Modules\SimplePatches + + + Modules\SimplePatches + + + Modules\SimplePatches + + + Modules\SimplePatches + + + Modules\SimplePatches + + + Modules\SimplePatches + + + Modules\SimplePatches + + + Modules\SimplePatches + + + Modules\SimplePatches + + + Modules\Features + + + Modules\Features + + + Modules\Features + + + Modules\Features + @@ -301,15 +313,6 @@ Modules - - Modules - - - Modules - - - Modules - Modules @@ -325,24 +328,15 @@ Modules - - Modules - Modules Modules - - Modules - Modules - - Modules - Modules @@ -352,21 +346,9 @@ Modules - - Modules - - - Modules - - - Modules - Modules - - Modules - @@ -379,9 +361,6 @@ Modules - - Modules - Modules @@ -447,30 +426,15 @@ Modules - - Modules - Modules - - Modules - Modules Modules - - Modules - - - Modules - - - Modules - Modules @@ -532,6 +496,57 @@ + + Modules\SimplePatches + + + Modules\SimplePatches + + + Modules\SimplePatches + + + Modules\SimplePatches + + + Modules\SimplePatches + + + Modules\SimplePatches + + + Modules\SimplePatches + + + Modules\SimplePatches + + + Modules\SimplePatches + + + Modules\SimplePatches + + + Modules\SimplePatches + + + Modules\SimplePatches + + + Modules\Features + + + Modules\Features + + + Modules\Features + + + Modules\Features + + + Modules\SubModules +