mirror of
https://github.com/sfall-team/sfall.git
synced 2026-07-27 16:52:34 -07:00
Rewrote the code of force_encounter functions
Added a new flag to force_encounter_with_flags.
This commit is contained in:
@@ -73,7 +73,8 @@
|
|||||||
#define LIST_ALL (9)
|
#define LIST_ALL (9)
|
||||||
|
|
||||||
//Valid flags for force_encounter_with_flags
|
//Valid flags for force_encounter_with_flags
|
||||||
#define ENCOUNTER_FLAG_NO_CAR (1)
|
#define ENCOUNTER_FLAG_NO_CAR (1)
|
||||||
|
#define ENCOUNTER_FLAG_LOCK (2) // block new forced encounter by the next function call until the current specified encounter occurs
|
||||||
|
|
||||||
//The attack types returned by get_attack_type
|
//The attack types returned by get_attack_type
|
||||||
#define ATKTYPE_LWEP1 (0)
|
#define ATKTYPE_LWEP1 (0)
|
||||||
|
|||||||
@@ -132,6 +132,7 @@
|
|||||||
#define FO_VAR_max 0x56FB50
|
#define FO_VAR_max 0x56FB50
|
||||||
#define FO_VAR_maxScriptNum 0x51C7CC
|
#define FO_VAR_maxScriptNum 0x51C7CC
|
||||||
#define FO_VAR_Meet_Frank_Horrigan 0x672E04
|
#define FO_VAR_Meet_Frank_Horrigan 0x672E04
|
||||||
|
#define FO_VAR_Move_on_Car 0x672E64
|
||||||
#define FO_VAR_mouse_hotx 0x6AC7D0
|
#define FO_VAR_mouse_hotx 0x6AC7D0
|
||||||
#define FO_VAR_mouse_hoty 0x6AC7CC
|
#define FO_VAR_mouse_hoty 0x6AC7CC
|
||||||
#define FO_VAR_mouse_is_hidden 0x6AC790
|
#define FO_VAR_mouse_is_hidden 0x6AC790
|
||||||
|
|||||||
@@ -31,77 +31,58 @@ namespace sfall
|
|||||||
namespace script
|
namespace script
|
||||||
{
|
{
|
||||||
|
|
||||||
static DWORD EncounteredHorrigan;
|
static DWORD ForceEnconterMapID = -1;
|
||||||
static DWORD ForceEnconterMapID;
|
static DWORD ForceEnconterFlags;
|
||||||
|
|
||||||
static void _stdcall ForceEncounterRestore() {
|
DWORD ForceEncounterRestore() {
|
||||||
*(DWORD*)0x672E04 = EncounteredHorrigan;
|
long long data = 0x672E043D83; // cmp ds:_Meet_Frank_Horrigan, 0
|
||||||
SafeWrite32(0x4C070E, *(DWORD*)0x4C0718); // map id
|
SafeWriteBytes(0x4C06D1, (BYTE*)&data, 5);
|
||||||
SafeWrite16(0x4C06D8, 0x5175);
|
ForceEnconterFlags = 0;
|
||||||
SafeWrite32(0x4C071D, 0xFFFC2413);
|
DWORD mapID = ForceEnconterMapID;
|
||||||
SafeWrite8(0x4C0706, 0x75);
|
ForceEnconterMapID = -1;
|
||||||
|
return mapID;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __declspec(naked) wmRndEncounterOccurred_hook() {
|
static void __declspec(naked) wmRndEncounterOccurred_hack() {
|
||||||
__asm {
|
__asm {
|
||||||
push ecx;
|
test ForceEnconterFlags, 0x1; // _NoCar flag
|
||||||
call ForceEncounterRestore;
|
jnz noCar;
|
||||||
pop ecx;
|
cmp ds:[FO_VAR_Move_on_Car], 0;
|
||||||
|
jz noCar;
|
||||||
|
mov edx, FO_VAR_carCurrentArea;
|
||||||
mov eax, ForceEnconterMapID;
|
mov eax, ForceEnconterMapID;
|
||||||
jmp fo::funcoffs::map_load_idx_;
|
call fo::funcoffs::wmMatchAreaContainingMapIdx_;
|
||||||
|
noCar:
|
||||||
|
//push ecx;
|
||||||
|
// TODO: implement a blinking red icon
|
||||||
|
call ForceEncounterRestore;
|
||||||
|
//pop ecx;
|
||||||
|
push 0x4C0721; // return addr
|
||||||
|
jmp fo::funcoffs::map_load_idx_; // eax - mapID
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __fastcall ForceEncounter(DWORD mapID, DWORD flags) {
|
void sf_force_encounter(OpcodeContext& cxt) {
|
||||||
EncounteredHorrigan = *(DWORD*)0x672E04;
|
if (ForceEnconterFlags & (1 << 31)) return; // wait prev. encounter
|
||||||
|
|
||||||
|
DWORD mapID = cxt.arg(0).rawValue();
|
||||||
|
if (mapID < 0) {
|
||||||
|
cxt.printOpcodeError("%s() - invalid map number.", cxt.getOpcodeName());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (ForceEnconterMapID == -1) MakeJump(0x4C06D1, wmRndEncounterOccurred_hack);
|
||||||
|
|
||||||
ForceEnconterMapID = mapID;
|
ForceEnconterMapID = mapID;
|
||||||
SafeWrite32(0x4C070E, mapID);
|
DWORD flags = 0;
|
||||||
SafeWrite16(0x4C06D8, 0x13EB); // jmp 0x4C06ED
|
if (cxt.numArgs() > 1) {
|
||||||
HookCall(0x4C071C, wmRndEncounterOccurred_hook);
|
flags = cxt.arg(1).rawValue();
|
||||||
|
if (flags & 2) { // _Lock flag
|
||||||
if (flags & 1) SafeWrite8(0x4C0706, 0xEB);
|
flags |= (1 << 31); // set bit 31
|
||||||
}
|
} else {
|
||||||
|
flags = flags & ~(1 << 31);
|
||||||
void __declspec(naked) op_force_encounter() {
|
}
|
||||||
__asm {
|
|
||||||
push ecx;
|
|
||||||
push edx;
|
|
||||||
_GET_ARG_INT(end);
|
|
||||||
xor edx, edx; // flags
|
|
||||||
mov ecx, eax; // mapID
|
|
||||||
call ForceEncounter;
|
|
||||||
end:
|
|
||||||
pop edx;
|
|
||||||
pop ecx;
|
|
||||||
retn;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void __declspec(naked) op_force_encounter_with_flags() {
|
|
||||||
__asm {
|
|
||||||
pushad;
|
|
||||||
mov ecx, eax;
|
|
||||||
call fo::funcoffs::interpretPopShort_;
|
|
||||||
mov edx, eax;
|
|
||||||
mov eax, ecx;
|
|
||||||
call fo::funcoffs::interpretPopLong_;
|
|
||||||
mov ebx, eax;
|
|
||||||
mov eax, ecx;
|
|
||||||
call fo::funcoffs::interpretPopShort_;
|
|
||||||
mov edi, eax;
|
|
||||||
mov eax, ecx;
|
|
||||||
call fo::funcoffs::interpretPopLong_;
|
|
||||||
cmp dx, VAR_TYPE_INT;
|
|
||||||
jnz end;
|
|
||||||
cmp di, VAR_TYPE_INT;
|
|
||||||
jnz end;
|
|
||||||
mov edx, ebx; // flags
|
|
||||||
mov ecx, eax; // mapID
|
|
||||||
call ForceEncounter;
|
|
||||||
end:
|
|
||||||
popad;
|
|
||||||
retn;
|
|
||||||
}
|
}
|
||||||
|
ForceEnconterFlags = flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
// world_map_functions
|
// world_map_functions
|
||||||
|
|||||||
@@ -25,9 +25,9 @@ namespace script
|
|||||||
|
|
||||||
class OpcodeContext;
|
class OpcodeContext;
|
||||||
|
|
||||||
void __declspec() op_force_encounter();
|
void sf_force_encounter(OpcodeContext&);
|
||||||
|
|
||||||
void __declspec() op_force_encounter_with_flags();
|
DWORD ForceEncounterRestore();
|
||||||
|
|
||||||
// world_map_functions
|
// world_map_functions
|
||||||
void __declspec() op_in_world_map();
|
void __declspec() op_in_world_map();
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
#include "..\..\FalloutEngine\Fallout2.h"
|
#include "..\..\FalloutEngine\Fallout2.h"
|
||||||
#include "..\KillCounter.h"
|
#include "..\KillCounter.h"
|
||||||
|
#include "..\LoadGameHook.h"
|
||||||
|
|
||||||
#include "Handlers\Anims.h"
|
#include "Handlers\Anims.h"
|
||||||
#include "Handlers\Arrays.h"
|
#include "Handlers\Arrays.h"
|
||||||
@@ -72,6 +73,7 @@ static SfallOpcodeInfo opcodeInfoArray[] = {
|
|||||||
{0x161, "get_critter_extra_stat", sf_get_critter_extra_stat, 2, true, {ARG_OBJECT, ARG_INT}},
|
{0x161, "get_critter_extra_stat", sf_get_critter_extra_stat, 2, true, {ARG_OBJECT, ARG_INT}},
|
||||||
{0x163, "get_year", sf_get_year, 0, true},
|
{0x163, "get_year", sf_get_year, 0, true},
|
||||||
{0x16c, "key_pressed", sf_key_pressed, 1, true, {ARG_INT}},
|
{0x16c, "key_pressed", sf_key_pressed, 1, true, {ARG_INT}},
|
||||||
|
{0x171, "force_encounter", sf_force_encounter, 1, false, {ARG_INT}},
|
||||||
|
|
||||||
{0x190, "get_perk_available", sf_get_perk_available, 1, true, {ARG_INT}},
|
{0x190, "get_perk_available", sf_get_perk_available, 1, true, {ARG_INT}},
|
||||||
{0x195, "set_weapon_knockback", sf_set_object_knockback, 3, false, {ARG_OBJECT, ARG_INT, ARG_NUMBER}},
|
{0x195, "set_weapon_knockback", sf_set_object_knockback, 3, false, {ARG_OBJECT, ARG_INT, ARG_NUMBER}},
|
||||||
@@ -143,6 +145,7 @@ static SfallOpcodeInfo opcodeInfoArray[] = {
|
|||||||
|
|
||||||
{0x224, "create_message_window", sf_create_message_window, 1, false, {ARG_STRING}},
|
{0x224, "create_message_window", sf_create_message_window, 1, false, {ARG_STRING}},
|
||||||
{0x228, "get_attack_type", sf_get_attack_type, 0, true},
|
{0x228, "get_attack_type", sf_get_attack_type, 0, true},
|
||||||
|
{0x229, "force_encounter_with_flags", sf_force_encounter, 2, false, {ARG_INT, ARG_INT}},
|
||||||
{0x22d, "create_array", sf_create_array, 2, true, {ARG_INT, ARG_INT}},
|
{0x22d, "create_array", sf_create_array, 2, true, {ARG_INT, ARG_INT}},
|
||||||
{0x22e, "set_array", sf_set_array, 3, false, {ARG_OBJECT, ARG_ANY, ARG_ANY}},
|
{0x22e, "set_array", sf_set_array, 3, false, {ARG_OBJECT, ARG_ANY, ARG_ANY}},
|
||||||
{0x22f, "get_array", sf_get_array, 2, true, {ARG_ANY, ARG_ANY}}, // can also be used on strings
|
{0x22f, "get_array", sf_get_array, 2, true, {ARG_ANY, ARG_ANY}}, // can also be used on strings
|
||||||
@@ -286,7 +289,6 @@ void InitNewOpcodes() {
|
|||||||
opcodes[0x16e] = op_set_shader_float;
|
opcodes[0x16e] = op_set_shader_float;
|
||||||
opcodes[0x16f] = op_set_shader_vector;
|
opcodes[0x16f] = op_set_shader_vector;
|
||||||
opcodes[0x170] = op_in_world_map;
|
opcodes[0x170] = op_in_world_map;
|
||||||
opcodes[0x171] = op_force_encounter;
|
|
||||||
opcodes[0x172] = op_set_world_map_pos;
|
opcodes[0x172] = op_set_world_map_pos;
|
||||||
opcodes[0x173] = op_get_world_map_x_pos;
|
opcodes[0x173] = op_get_world_map_x_pos;
|
||||||
opcodes[0x174] = op_get_world_map_y_pos;
|
opcodes[0x174] = op_get_world_map_y_pos;
|
||||||
@@ -384,7 +386,6 @@ void InitNewOpcodes() {
|
|||||||
opcodes[0x225] = op_remove_trait;
|
opcodes[0x225] = op_remove_trait;
|
||||||
opcodes[0x226] = op_get_light_level;
|
opcodes[0x226] = op_get_light_level;
|
||||||
opcodes[0x227] = op_refresh_pc_art;
|
opcodes[0x227] = op_refresh_pc_art;
|
||||||
opcodes[0x229] = op_force_encounter_with_flags;
|
|
||||||
opcodes[0x22a] = op_set_map_time_multi;
|
opcodes[0x22a] = op_set_map_time_multi;
|
||||||
opcodes[0x22b] = op_play_sfall_sound;
|
opcodes[0x22b] = op_play_sfall_sound;
|
||||||
opcodes[0x22c] = op_stop_sfall_sound;
|
opcodes[0x22c] = op_stop_sfall_sound;
|
||||||
@@ -424,6 +425,10 @@ void InitNewOpcodes() {
|
|||||||
|
|
||||||
InitOpcodeInfoTable();
|
InitOpcodeInfoTable();
|
||||||
InitMetaruleTable();
|
InitMetaruleTable();
|
||||||
|
|
||||||
|
LoadGameHook::OnGameReset() += []() {
|
||||||
|
ForceEncounterRestore(); // restore if the encounter did not happen
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user