mirror of
https://github.com/sfall-team/sfall.git
synced 2026-07-27 16:52:34 -07:00
Fixed the mode 2 of get_tile_fid
Minor code/comment/format edits.
This commit is contained in:
@@ -57,7 +57,7 @@ ScriptValue HookCommon::GetHSArgAt(DWORD id) {
|
||||
return args[id];
|
||||
}
|
||||
|
||||
void __stdcall HookCommon::SetHSReturn(const ScriptValue& value) {
|
||||
void HookCommon::SetHSReturn(const ScriptValue& value) {
|
||||
// For backward compatibility - ignore non-int return values
|
||||
if (!allowNonIntReturn && !value.isInt()) return;
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ public:
|
||||
static script::ScriptValue GetHSArg();
|
||||
static script::ScriptValue GetHSArgAt(DWORD id);
|
||||
static void SetHSArg(DWORD id, const script::ScriptValue& value);
|
||||
static void __stdcall SetHSReturn(const script::ScriptValue& value);
|
||||
static void SetHSReturn(const script::ScriptValue& value);
|
||||
|
||||
static void GameModeChangeHook(DWORD exit);
|
||||
static void __stdcall KeyPressHook(DWORD* dxKey, bool pressed, DWORD vKey);
|
||||
|
||||
@@ -167,8 +167,8 @@ static DWORD __fastcall DescriptionObjHook_Script(DWORD object) {
|
||||
RunHookScript(HOOK_DESCRIPTIONOBJ);
|
||||
|
||||
DWORD textPtr = cRet > 0 && (retTypes[0] == DataType::INT || retTypes[0] == DataType::STR)
|
||||
? rets[0]
|
||||
: 0;
|
||||
? rets[0]
|
||||
: 0;
|
||||
|
||||
EndHook();
|
||||
return textPtr;
|
||||
|
||||
+23
-24
@@ -556,6 +556,28 @@ skip:
|
||||
}
|
||||
}
|
||||
|
||||
// Allow passing non-weapon/armor items to invenWieldFunc_ engine function without error
|
||||
// It used to treat all non-armor items as "weapon" and try to check if critter had weapon animation,
|
||||
// which isn't valid for other item subtypes.
|
||||
static void __declspec(naked) invenWieldFunc_hack() {
|
||||
static const DWORD invenWieldFunc_hack_back = 0x47285D;
|
||||
static const DWORD invenWieldFunc_hack_skip = 0x4728A7;
|
||||
using namespace fo;
|
||||
using namespace Fields;
|
||||
__asm {
|
||||
mov eax, edi; // weapon
|
||||
call fo::funcoffs::item_get_type_;
|
||||
cmp eax, item_type_weapon;
|
||||
je isWeapon;
|
||||
jmp invenWieldFunc_hack_skip;
|
||||
isWeapon: // overwritten engine code
|
||||
mov eax, [esi + rotation]; // cur_rot
|
||||
inc eax;
|
||||
push eax;
|
||||
jmp invenWieldFunc_hack_back;
|
||||
}
|
||||
}
|
||||
|
||||
static void __declspec(naked) do_move_timer_hook() {
|
||||
static const DWORD DoMoveTimer_Ret = 0x476920;
|
||||
__asm {
|
||||
@@ -626,29 +648,6 @@ void InventoryReset() {
|
||||
invenApCost = invenApCostDef;
|
||||
}
|
||||
|
||||
// Allows to pass items of non-armor and non-weapon type to invenWieldFunc without error
|
||||
// It used to treat all non-armor items as "weapon" and try to check if critter had weapon animation,
|
||||
// which isn't valid for other item subtypes.
|
||||
static void __declspec(naked) invenWieldFunc_hack() {
|
||||
static const DWORD invenWieldFunc_hack_back = 0x47285D;
|
||||
static const DWORD invenWieldFunc_hack_skip = 0x4728A7;
|
||||
using namespace fo;
|
||||
using namespace Fields;
|
||||
__asm {
|
||||
mov eax, edi; // weapon
|
||||
call fo::funcoffs::item_get_type_;
|
||||
cmp eax, item_type_weapon;
|
||||
je isWeapon;
|
||||
jmp invenWieldFunc_hack_skip;
|
||||
isWeapon: // overwritten engine code
|
||||
mov eax, [esi + rotation]; // cur_rot
|
||||
inc eax;
|
||||
push eax;
|
||||
jmp invenWieldFunc_hack_back;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Inventory::init() {
|
||||
OnKeyPressed() += InventoryKeyPressedHook;
|
||||
LoadGameHook::OnGameReset() += InventoryReset;
|
||||
@@ -766,7 +765,7 @@ void Inventory::init() {
|
||||
HookCall(0x45B0CE, op_inven_unwield_hook); // with fix to update interface slot after unwielding
|
||||
HookCall(0x45693C, op_wield_obj_critter_hook);
|
||||
|
||||
// Fix for invenWieldFunc (used by wield_obj_critter) to be able to put non-armor & non-weapon types into active slot.
|
||||
// Fix for invenWieldFunc_ (used by wield_obj_critter) to be able to put non-weapon/armor items into active slot
|
||||
MakeJump(0x472858, invenWieldFunc_hack);
|
||||
}
|
||||
|
||||
|
||||
+17
-22
@@ -18,7 +18,6 @@
|
||||
|
||||
#include <algorithm>
|
||||
#include <fstream>
|
||||
#include <filesystem>
|
||||
|
||||
#include "..\main.h"
|
||||
#include "..\FalloutEngine\Fallout2.h"
|
||||
@@ -266,8 +265,8 @@ static void __fastcall game_init_databases_hook1() {
|
||||
*/
|
||||
static bool NormalizePath(std::string &path) {
|
||||
const char* whiteSpaces = " \t";
|
||||
// Remove comments
|
||||
std::size_t pos = path.find_first_of(";#");
|
||||
// Remove comments.
|
||||
size_t pos = path.find_first_of(";#");
|
||||
if (pos != std::string::npos) {
|
||||
path.erase(pos);
|
||||
}
|
||||
@@ -279,7 +278,7 @@ static bool NormalizePath(std::string &path) {
|
||||
|
||||
// Disallow paths going outside of root folder.
|
||||
if (path.find(".\\") != std::string::npos || path.find("..\\") != std::string::npos) return false;
|
||||
|
||||
|
||||
// Trim whitespaces.
|
||||
path.erase(0, path.find_first_not_of(whiteSpaces)); // trim left
|
||||
path.erase(path.find_last_not_of(whiteSpaces) + 1); // trim right
|
||||
@@ -295,14 +294,12 @@ static bool FileOrFolderExists(const std::string& path) {
|
||||
|
||||
static bool FileExists(const std::string& path) {
|
||||
DWORD dwAttrib = GetFileAttributesA(path.c_str());
|
||||
return dwAttrib != INVALID_FILE_ATTRIBUTES &&
|
||||
!(dwAttrib & FILE_ATTRIBUTE_DIRECTORY);
|
||||
return (dwAttrib != INVALID_FILE_ATTRIBUTES && !(dwAttrib & FILE_ATTRIBUTE_DIRECTORY));
|
||||
}
|
||||
|
||||
static bool FolderExists(const std::string& path) {
|
||||
DWORD dwAttrib = GetFileAttributesA(path.c_str());
|
||||
return dwAttrib != INVALID_FILE_ATTRIBUTES &&
|
||||
(dwAttrib & FILE_ATTRIBUTE_DIRECTORY);
|
||||
return (dwAttrib != INVALID_FILE_ATTRIBUTES && (dwAttrib & FILE_ATTRIBUTE_DIRECTORY));
|
||||
}
|
||||
|
||||
// Patches placed at the back of the vector will have priority in the chain over the front(previous) patches
|
||||
@@ -316,18 +313,18 @@ static void GetExtraPatches() {
|
||||
}
|
||||
const std::string modsPath = ".\\mods\\";
|
||||
const std::string loadOrderFilePath = modsPath + "mods_order.txt";
|
||||
|
||||
|
||||
dlogr("Loading custom patches:", DL_MAIN);
|
||||
|
||||
// Check if mods folder exists, if not, create it.
|
||||
// If the mods folder does not exist, create it.
|
||||
if (!FolderExists(modsPath)) {
|
||||
CreateDirectoryA(modsPath.c_str(), 0);
|
||||
}
|
||||
// Check if load order file does not exist yet and initialize automatically with mods already in the mods folder.
|
||||
// If load order file does not exist, initialize it automatically with mods already in the mods folder.
|
||||
if (!FileExists(loadOrderFilePath)) {
|
||||
std::ofstream loadOrderFile(loadOrderFilePath, std::ios::out | std::ios::trunc);
|
||||
if (loadOrderFile.is_open()) {
|
||||
// Search all .dat files and folders in mods folder.
|
||||
// Search all .dat files and folders in the mods folder.
|
||||
std::vector<std::string> autoLoadedPatchFiles;
|
||||
std::string pathMask(modsPath + "*.dat");
|
||||
WIN32_FIND_DATA findData;
|
||||
@@ -337,22 +334,21 @@ static void GetExtraPatches() {
|
||||
std::string name(findData.cFileName);
|
||||
if ((name.length() - name.find_last_of('.')) > 4) continue;
|
||||
|
||||
autoLoadedPatchFiles.push_back(name.c_str());
|
||||
autoLoadedPatchFiles.push_back(name);
|
||||
} while (FindNextFile(hFind, &findData));
|
||||
FindClose(hFind);
|
||||
}
|
||||
// Sort the search result.
|
||||
std::sort(autoLoadedPatchFiles.begin(), autoLoadedPatchFiles.end());
|
||||
// Write found files into load_order files.
|
||||
// Write found files into load order file.
|
||||
for (auto& filePath : autoLoadedPatchFiles) {
|
||||
loadOrderFile << filePath << '\n';
|
||||
}
|
||||
}
|
||||
else {
|
||||
dlog_f("Error creating load order file %s.", DL_MAIN, loadOrderFilePath.c_str());
|
||||
} else {
|
||||
dlog_f("Error creating load order file %s.\n", DL_MAIN, loadOrderFilePath.c_str() + 2);
|
||||
}
|
||||
}
|
||||
// Add mods from load_order file.
|
||||
// Add mods from load order file.
|
||||
std::ifstream loadOrderFile(loadOrderFilePath, std::ios::in);
|
||||
if (loadOrderFile.is_open()) {
|
||||
std::string patch;
|
||||
@@ -361,12 +357,11 @@ static void GetExtraPatches() {
|
||||
patch = modsPath + patch;
|
||||
if (!FileOrFolderExists(patch)) continue;
|
||||
|
||||
dlog_f("> %s\n", DL_MAIN, patch.c_str());
|
||||
dlog_f("> %s\n", DL_MAIN, patch.c_str() + 2);
|
||||
patchFiles.push_back(patch);
|
||||
}
|
||||
}
|
||||
else {
|
||||
dlog_f("Error opening %s for read: %x", DL_MAIN, loadOrderFilePath.c_str(), GetLastError());
|
||||
} else {
|
||||
dlog_f("Error opening %s for read: %d\n", DL_MAIN, loadOrderFilePath.c_str() + 2, GetLastError());
|
||||
}
|
||||
|
||||
// Remove first duplicates
|
||||
|
||||
@@ -88,12 +88,12 @@ static void __declspec(naked) register_object_take_out_hack() {
|
||||
}
|
||||
|
||||
static void __declspec(naked) gdAddOptionStr_hack() {
|
||||
static const DWORD gdAddOptionStr_hack_Ret = 0x4458FA;
|
||||
__asm {
|
||||
mov ecx, ds:[FO_VAR_gdNumOptions];
|
||||
add ecx, '1';
|
||||
push ecx;
|
||||
mov ecx, 0x4458FA;
|
||||
jmp ecx;
|
||||
jmp gdAddOptionStr_hack_Ret;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -333,10 +333,10 @@ end:
|
||||
|
||||
void op_get_tile_fid(OpcodeContext& ctx) {
|
||||
long tileX, tileY, squareNum, squareData, result,
|
||||
tileAndElev = ctx.arg(0).rawValue(),
|
||||
tileNum = tileAndElev & 0xFFFFFF,
|
||||
elevation = (tileAndElev >> 24) & 0x0F,
|
||||
mode = tileAndElev >> 28;
|
||||
tileAndElev = ctx.arg(0).rawValue(),
|
||||
tileNum = tileAndElev & 0xFFFFFF,
|
||||
elevation = (tileAndElev >> 24) & 0x0F,
|
||||
mode = tileAndElev >> 28;
|
||||
|
||||
fo::func::tile_coord(tileNum, &tileX, &tileY);
|
||||
squareNum = fo::func::square_num(tileX, tileY, elevation);
|
||||
@@ -347,6 +347,7 @@ void op_get_tile_fid(OpcodeContext& ctx) {
|
||||
break;
|
||||
case 2:
|
||||
result = squareData; // raw data
|
||||
break;
|
||||
default:
|
||||
// Vanilla uses 12 bits for Tile FID, which means 4096 possible values, the mask was 0x0FFF
|
||||
// BUT sfall's FRM Limit patch extended it to 14 bits, so we need to use mask 0x3FFF
|
||||
|
||||
@@ -179,7 +179,7 @@ static SfallOpcodeInfo opcodeInfoArray[] = {
|
||||
{0x239, "scan_array", op_scan_array, 2, true, -1, {ARG_OBJECT, ARG_ANY}},
|
||||
{0x23a, "get_tile_fid", op_get_tile_fid, 1, true, 0, {ARG_INT}},
|
||||
{0x23c, "get_sfall_args", op_get_sfall_args, 0, true},
|
||||
{0x23d, "set_sfall_arg", op_set_sfall_arg, 2, false, 0, {ARG_INT, ARG_ANY}}, // hookscript system will validate type
|
||||
{0x23d, "set_sfall_arg", op_set_sfall_arg, 2, false, 0, {ARG_INT, ARG_ANY}}, // hook script system will validate type
|
||||
{0x241, "get_npc_level", op_get_npc_level, 1, true, -1, {ARG_INTSTR}},
|
||||
{0x242, "set_critter_skill_points", op_set_critter_skill_points, 3, false, 0, {ARG_OBJECT, ARG_INT, ARG_INT}},
|
||||
{0x243, "get_critter_skill_points", op_get_critter_skill_points, 2, true, 0, {ARG_OBJECT, ARG_INT}},
|
||||
|
||||
Reference in New Issue
Block a user