Refactored code in Tiles.cpp and EngineUtils.cpp.

Moved RegAnimCombatCheck code from ScriptExtender.cpp to Anims.cpp.
This commit is contained in:
NovaRain
2019-05-11 09:56:58 +08:00
parent a63ea24572
commit d2cf728131
8 changed files with 75 additions and 79 deletions
+15 -3
View File
@@ -62,6 +62,14 @@ Proto* GetProto(long pid) {
return nullptr;
}
bool CritterCopyProto(long pid, long* &proto_dst) {
fo::Proto* protoPtr;
if (fo::func::proto_ptr(pid, &protoPtr) == -1) return false;
/*if (!proto_dst)*/ proto_dst = new long[104];
memcpy(proto_dst, protoPtr, 416);
return true;
}
void SkillGetTags(long* result, long num) {
if (num > 4) {
num = 4;
@@ -129,18 +137,22 @@ void ToggleNpcFlag(fo::GameObject* npc, long flag, bool set) {
}
}
bool IsPartyMember(fo::GameObject* critter) {
if (critter->id < 18000) return false;
bool IsPartyMemberByPid(long pid) {
size_t patryCount = fo::var::partyMemberMaxCount;
if (patryCount) {
DWORD* memberPids = fo::var::partyMemberPidList; // pids from party.txt
for (size_t i = 0; i < patryCount; i++) {
if (memberPids[i] == critter->protoId) return true;;
if (memberPids[i] == pid) return true;;
}
}
return false;
}
bool IsPartyMember(fo::GameObject* critter) {
if (critter->id < 18000) return false;
return IsPartyMemberByPid(critter->protoId);
}
//---------------------------------------------------------
//print text to surface
void PrintText(char *DisplayText, BYTE ColourIndex, DWORD Xpos, DWORD Ypos, DWORD TxtWidth, DWORD ToWidth, BYTE *ToSurface) {
+4
View File
@@ -44,6 +44,8 @@ const char* _stdcall MessageSearch(const MessageList* fileAddr, long messageId);
// returns pointer to prototype by PID, or nullptr on failure
Proto* GetProto(long pid);
bool CritterCopyProto(long pid, long* &proto_dst);
// wrapper for skill_get_tags with bounds checking
void SkillGetTags(long* result, long num);
@@ -64,6 +66,8 @@ long CheckAddictByPid(fo::GameObject* critter, long pid);
void ToggleNpcFlag(fo::GameObject* npc, long flag, bool set);
bool IsPartyMemberByPid(long pid);
bool IsPartyMember(fo::GameObject* critter);
// Print text to surface
+2 -15
View File
@@ -34,9 +34,11 @@
#include "LoadGameHook.h"
#include "MainLoopHook.h"
#include "Worldmap.h"
#include "Scripting\Arrays.h"
#include "Scripting\Opcodes.h"
#include "Scripting\OpcodeContext.h"
#include "Scripting\Handlers\Anims.h"
#include "ScriptExtender.h"
@@ -527,21 +529,6 @@ bool _stdcall ScriptHasLoaded(fo::Program* script) {
return true;
}
void _stdcall RegAnimCombatCheck(DWORD newValue) {
char oldValue = regAnimCombatCheck;
regAnimCombatCheck = (newValue > 0);
if (oldValue != regAnimCombatCheck) {
SafeWrite8(0x459C97, regAnimCombatCheck); // reg_anim_func
SafeWrite8(0x459D4B, regAnimCombatCheck); // reg_anim_animate
SafeWrite8(0x459E3B, regAnimCombatCheck); // reg_anim_animate_reverse
SafeWrite8(0x459EEB, regAnimCombatCheck); // reg_anim_obj_move_to_obj
SafeWrite8(0x459F9F, regAnimCombatCheck); // reg_anim_obj_run_to_obj
SafeWrite8(0x45A053, regAnimCombatCheck); // reg_anim_obj_move_to_tile
SafeWrite8(0x45A10B, regAnimCombatCheck); // reg_anim_obj_run_to_tile
SafeWrite8(0x45AE53, regAnimCombatCheck); // reg_anim_animate_forever
}
}
// this runs before actually loading/starting the game
static void ClearGlobalScripts() {
isGameLoading = true;
-3
View File
@@ -71,8 +71,6 @@ long GetGlobalVarInternal(__int64 val);
void __fastcall SetSelfObject(fo::Program* script, fo::GameObject* obj);
void _stdcall RegAnimCombatCheck(DWORD newValue);
bool _stdcall ScriptHasLoaded(fo::Program* script);
// loads script from .int file into a sScriptProgram struct, filling script pointer and proc lookup table
@@ -94,7 +92,6 @@ void AddProgramToMap(ScriptProgram &prog);
ScriptProgram* GetGlobalScriptProgram(fo::Program* scriptPtr);
// variables
static char regAnimCombatCheck = 1;
extern DWORD isGlobalScriptLoading;
extern DWORD availableGlobalScriptTypes;
extern bool alwaysFindScripts;
+17 -1
View File
@@ -19,7 +19,6 @@
#include "..\..\..\FalloutEngine\Fallout2.h"
#include "..\..\..\SafeWrite.h"
#include "..\..\Explosions.h"
#include "..\..\ScriptExtender.h"
#include "..\OpcodeContext.h"
#include "Anims.h"
@@ -29,6 +28,23 @@ namespace sfall
namespace script
{
static char regAnimCombatCheck = 1;
void RegAnimCombatCheck(DWORD newValue) {
char oldValue = regAnimCombatCheck;
regAnimCombatCheck = (newValue > 0);
if (oldValue != regAnimCombatCheck) {
SafeWrite8(0x459C97, regAnimCombatCheck); // reg_anim_func
SafeWrite8(0x459D4B, regAnimCombatCheck); // reg_anim_animate
SafeWrite8(0x459E3B, regAnimCombatCheck); // reg_anim_animate_reverse
SafeWrite8(0x459EEB, regAnimCombatCheck); // reg_anim_obj_move_to_obj
SafeWrite8(0x459F9F, regAnimCombatCheck); // reg_anim_obj_run_to_obj
SafeWrite8(0x45A053, regAnimCombatCheck); // reg_anim_obj_move_to_tile
SafeWrite8(0x45A10B, regAnimCombatCheck); // reg_anim_obj_run_to_tile
SafeWrite8(0x45AE53, regAnimCombatCheck); // reg_anim_animate_forever
}
}
// true if combat mode is active and combat check was not disabled
bool checkCombatMode() {
return (regAnimCombatCheck & fo::var::combat_state) != 0;
+2
View File
@@ -25,6 +25,8 @@ namespace script
// new reg_anim functions (all using existing engine code)
void RegAnimCombatCheck(DWORD newValue);
class OpcodeContext;
void sf_reg_anim_combat_check(OpcodeContext&);
+3 -11
View File
@@ -255,19 +255,11 @@ static void SetStatValue(long* proto, long offset, long amount) {
proto[offset] = amount;
}
static long CopyProto(long pid, long* &proto_out) {
fo::Proto* _proto;
if (fo::func::proto_ptr(pid, &_proto) == -1) return 0;
proto_out = new long[104];
memcpy(proto_out, _proto, 416);
return 1;
}
static long ApplyAllStatsToProto(const protoMem_iterator &iter, long* &proto_out) {
long count = 0;
for (auto itBonus = s_bonusStatProto.begin(); itBonus != s_bonusStatProto.end(); itBonus++) {
if (itBonus->objID == iter->first && itBonus->objPID == iter->second.pid) {
if (!proto_out && !CopyProto(iter->second.pid, proto_out)) return 0;
if (!proto_out && !fo::CritterCopyProto(iter->second.pid, proto_out)) return 0;
itBonus->s_proto = proto_out;
SetStatValue(proto_out, 44 + itBonus->stat, itBonus->amount);
count++;
@@ -275,7 +267,7 @@ static long ApplyAllStatsToProto(const protoMem_iterator &iter, long* &proto_out
}
for (auto itBase = s_baseStatProto.begin(); itBase != s_baseStatProto.end(); itBase++) {
if (itBase->objID == iter->first && itBase->objPID == iter->second.pid) {
if (!proto_out && !CopyProto(iter->second.pid, proto_out)) return 0;
if (!proto_out && !fo::CritterCopyProto(iter->second.pid, proto_out)) return 0;
itBase->s_proto = proto_out;
SetStatValue(proto_out, 9 + itBase->stat, itBase->amount);
count++;
@@ -696,4 +688,4 @@ void _stdcall SetNPCStatMin(int stat, int i) {
}
}
}
}
+32 -46
View File
@@ -29,6 +29,9 @@ namespace sfall
{
using namespace fo;
typedef int (_stdcall *functype)();
static const functype art_init = (functype)fo::funcoffs::art_init_;
static const DWORD Tiles_0E[] = {
0x484255, 0x48429D, 0x484377, 0x484385, 0x48A897, 0x48A89A, 0x4B2231,
0x4B2374, 0x4B2381, 0x4B2480, 0x4B248D, 0x4B2A7C, 0x4B2BDA,
@@ -50,40 +53,39 @@ static const DWORD Tiles_C0[] = {
0x4B247B, 0x4B2A77, 0x4B2BD5,
};
struct tilestruct {
short tile[2];
};
struct OverrideEntry {
//DWORD id;
DWORD xtiles;
DWORD ytiles;
DWORD replacementid;
OverrideEntry(DWORD _xtiles, DWORD _ytiles, DWORD _repid) {
xtiles = _xtiles;
ytiles = _ytiles;
replacementid = _repid;
OverrideEntry(DWORD _xtiles, DWORD _ytiles, DWORD _repid)
: xtiles(_xtiles), ytiles(_ytiles), replacementid(_repid) {
}
};
static OverrideEntry** overrides;
static DWORD origTileCount = 0;
typedef int (_stdcall *functype)();
static const functype _art_init = (functype)fo::funcoffs::art_init_;
static DWORD tileMode;
static BYTE* mask;
static void CreateMask() {
mask = new BYTE[80*36];
mask = new BYTE[80 * 36];
fo::DbFile* file = fo::func::db_fopen("art\\tiles\\grid000.frm", "r");
fo::func::db_fseek(file, 0x4a, 0);
fo::func::db_freadByteCount(file, mask, 80*36);
fo::func::db_fseek(file, 0x4A, 0);
fo::func::db_freadByteCount(file, mask, 80 * 36);
fo::func::db_fclose(file);
}
static WORD ByteSwapW(WORD w) {
return ((w & 0xff) << 8) | ((w & 0xff00) >> 8);
return ((w & 0xFF) << 8) | ((w & 0xFF00) >> 8);
}
static DWORD ByteSwapD(DWORD w) {
return ((w & 0xff) << 24) | ((w & 0xff00) << 8) | ((w & 0xff0000) >> 8) | ((w & 0xff000000) >> 24);
return ((w & 0xFF) << 24) | ((w & 0xFF00) << 8) | ((w & 0xFF0000) >> 8) | ((w & 0xFF000000) >> 24);
}
static int ProcessTile(fo::Art* tiles, int tile, int listpos) {
@@ -94,7 +96,7 @@ static int ProcessTile(fo::Art* tiles, int tile, int listpos) {
fo::DbFile* art = fo::func::db_fopen(buf, "r");
if (!art) return 0;
fo::func::db_fseek(art, 0x3e, 0);
fo::func::db_fseek(art, 0x3E, 0);
WORD width;
fo::func::db_freadShort(art, &width); //80;
if (width == 80) {
@@ -145,11 +147,8 @@ static int ProcessTile(fo::Art* tiles, int tile, int listpos) {
return xsize * ysize;
}
static DWORD tileMode;
static int _stdcall ArtInitHook2() {
if (_art_init()) {
return 1;
}
static int _stdcall ArtInitHook() {
if (art_init()) return -1;
CreateMask();
@@ -186,27 +185,18 @@ static int _stdcall ArtInitHook2() {
return 0;
}
static void __declspec(naked) ArtInitHook() {
static void __declspec(naked) iso_init_hook() {
__asm {
pushad;
mov eax, dword ptr ds:[FO_VAR_read_callback];
push eax;
xor eax, eax;
mov dword ptr ds:[FO_VAR_read_callback], eax;
call ArtInitHook2;
pop eax;
mov dword ptr ds:[FO_VAR_read_callback], eax;
popad;
xor eax, eax;
mov ebx, dword ptr ds:[FO_VAR_read_callback];
xor eax, eax;
mov dword ptr ds:[FO_VAR_read_callback], eax;
call ArtInitHook;
mov dword ptr ds:[FO_VAR_read_callback], ebx;
retn;
}
}
struct tilestruct {
short tile[2];
};
static void _stdcall SquareLoadCheck(tilestruct* data) {
static void __fastcall SquareLoadCheck(tilestruct* data) {
for (DWORD y = 0; y < 100; y++) {
for (DWORD x = 0; x < 100; x++) {
for (DWORD z = 0; z < 2; z++) {
@@ -226,16 +216,13 @@ static void _stdcall SquareLoadCheck(tilestruct* data) {
}
}
static void __declspec(naked) SquareLoadHook() {
static void __declspec(naked) square_load_hook() {
__asm {
mov edi, edx;
mov ecx, edx;
call fo::funcoffs::db_freadIntCount_;
test eax, eax;
jnz end;
pushad;
push edi;
call SquareLoadCheck;
popad;
jnz end;
jmp SquareLoadCheck;
end:
retn;
}
@@ -270,11 +257,10 @@ end:
}
void Tiles::init() {
tileMode = GetConfigInt("Misc", "AllowLargeTiles", 0);
if (tileMode) {
if (tileMode = GetConfigInt("Misc", "AllowLargeTiles", 0)) {
dlog("Applying allow large tiles patch.", DL_INIT);
HookCall(0x481D72, &ArtInitHook);
HookCall(0x48434C, SquareLoadHook);
HookCall(0x481D72, iso_init_hook);
HookCall(0x48434C, square_load_hook);
dlogr(" Done", DL_INIT);
}