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:
@@ -58,6 +58,7 @@
|
||||
|
||||
//Valid flags for force_encounter_with_flags
|
||||
#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
|
||||
#define ATKTYPE_LWEP1 (0)
|
||||
|
||||
@@ -672,6 +672,7 @@ const DWORD wmFindCurSubTileFromPos_ = 0x4C0C00;
|
||||
const DWORD wmInterfaceScrollTabsStart_ = 0x4C219C;
|
||||
const DWORD wmMapIsSaveable_ = 0x4BFA64;
|
||||
const DWORD wmMarkSubTileRadiusVisited_ = 0x4C3550;
|
||||
const DWORD wmMatchAreaContainingMapIdx_ = 0x4C59A4;
|
||||
const DWORD wmPartyInitWalking_ = 0x4C1E54;
|
||||
const DWORD wmPartyWalkingStep_ = 0x4C1F90;
|
||||
const DWORD wmSubTileMarkRadiusVisited_ = 0x4C35A8;
|
||||
|
||||
@@ -148,6 +148,7 @@
|
||||
#define _max 0x56FB50
|
||||
#define _maxScriptNum 0x51C7CC
|
||||
#define _Meet_Frank_Horrigan 0x672E04
|
||||
#define _Move_on_Car 0x672E64
|
||||
#define _mouse_hotx 0x6AC7D0
|
||||
#define _mouse_hoty 0x6AC7CC
|
||||
#define _mouse_is_hidden 0x6AC790
|
||||
@@ -903,6 +904,7 @@ extern const DWORD wmFindCurSubTileFromPos_;
|
||||
extern const DWORD wmInterfaceScrollTabsStart_;
|
||||
extern const DWORD wmMapIsSaveable_;
|
||||
extern const DWORD wmMarkSubTileRadiusVisited_;
|
||||
extern const DWORD wmMatchAreaContainingMapIdx_;
|
||||
extern const DWORD wmPartyInitWalking_;
|
||||
extern const DWORD wmPartyWalkingStep_;
|
||||
extern const DWORD wmSubTileMarkRadiusVisited_;
|
||||
|
||||
@@ -86,9 +86,10 @@ static void _stdcall ResetState(DWORD onLoad) {
|
||||
InLoop = 0;
|
||||
PerksReset();
|
||||
InventoryReset();
|
||||
RegAnimCombatCheck(1);
|
||||
AfterAttackCleanup();
|
||||
ClearSavPrototypes();
|
||||
RegAnimCombatCheck(1);
|
||||
ForceEncounterRestore(); // restore if the encounter did not happen
|
||||
AfterAttackCleanup();
|
||||
ResetExplosionRadius();
|
||||
PartyControlReset();
|
||||
NpcEngineLevelUpReset();
|
||||
|
||||
@@ -71,6 +71,7 @@ void SetAppearanceGlobals(int race, int style);
|
||||
void GetAppearanceGlobals(int *race, int *style);
|
||||
|
||||
void _stdcall RegAnimCombatCheck(DWORD newValue);
|
||||
DWORD _stdcall ForceEncounterRestore();
|
||||
|
||||
bool _stdcall ScriptHasLoaded(DWORD script);
|
||||
// finds procedure ID for given script program pointer and procedure name
|
||||
|
||||
@@ -205,7 +205,7 @@ static void _stdcall create_message_window2() {
|
||||
DialogOut(str);
|
||||
dialogShow = false;
|
||||
} else {
|
||||
opHandler.printOpcodeError("create_message_window() - argument is not a string.");
|
||||
OpcodeInvalidArgs("create_message_window");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -274,7 +274,7 @@ static void _stdcall ShowIfaceTag2() {
|
||||
AddBox(tag);
|
||||
}
|
||||
} else {
|
||||
opHandler.printOpcodeError("show_iface_tag() - argument is not an integer.");
|
||||
OpcodeInvalidArgs("show_iface_tag");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -293,7 +293,7 @@ static void _stdcall HideIfaceTag2() {
|
||||
RemoveBox(tag);
|
||||
}
|
||||
} else {
|
||||
opHandler.printOpcodeError("hide_iface_tag() - argument is not an integer.");
|
||||
OpcodeInvalidArgs("hide_iface_tag");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -23,77 +23,71 @@
|
||||
#include "ScriptExtender.h"
|
||||
#include "Worldmap.h"
|
||||
|
||||
static DWORD EncounteredHorrigan;
|
||||
static DWORD ForceEnconterMapID;
|
||||
static DWORD ForceEnconterMapID = -1;
|
||||
static DWORD ForceEnconterFlags;
|
||||
|
||||
static void _stdcall ForceEncounterRestore() {
|
||||
*(DWORD*)0x672E04 = EncounteredHorrigan;
|
||||
SafeWrite32(0x4C070E, *(DWORD*)0x4C0718); // map id
|
||||
SafeWrite16(0x4C06D8, 0x5175);
|
||||
SafeWrite32(0x4C071D, 0xFFFC2413);
|
||||
SafeWrite8(0x4C0706, 0x75);
|
||||
DWORD _stdcall ForceEncounterRestore() {
|
||||
long long data = 0x672E043D83; // cmp ds:_Meet_Frank_Horrigan, 0
|
||||
SafeWriteBytes(0x4C06D1, (BYTE*)&data, 5);
|
||||
ForceEnconterFlags = 0;
|
||||
DWORD mapID = ForceEnconterMapID;
|
||||
ForceEnconterMapID = -1;
|
||||
return mapID;
|
||||
}
|
||||
|
||||
static void __declspec(naked) wmRndEncounterOccurred_hook() {
|
||||
static void __declspec(naked) wmRndEncounterOccurred_hack() {
|
||||
__asm {
|
||||
push ecx;
|
||||
call ForceEncounterRestore;
|
||||
pop ecx;
|
||||
test ForceEnconterFlags, 0x1; // _NoCar flag
|
||||
jnz noCar;
|
||||
cmp ds:[_Move_on_Car], 0;
|
||||
jz noCar;
|
||||
mov edx, _CarCurrArea;
|
||||
mov eax, ForceEnconterMapID;
|
||||
jmp map_load_idx_;
|
||||
call wmMatchAreaContainingMapIdx_;
|
||||
noCar:
|
||||
//push ecx;
|
||||
// TODO: implement a blinking red icon
|
||||
call ForceEncounterRestore;
|
||||
//pop ecx;
|
||||
push 0x4C0721; // return addr
|
||||
jmp map_load_idx_; // eax - mapID
|
||||
}
|
||||
}
|
||||
|
||||
static void __fastcall ForceEncounter2(DWORD mapID, DWORD flags) {
|
||||
EncounteredHorrigan = *(DWORD*)0x672E04;
|
||||
ForceEnconterMapID = mapID;
|
||||
SafeWrite32(0x4C070E, mapID);
|
||||
SafeWrite16(0x4C06D8, 0x13EB); // jmp 0x4C06ED
|
||||
HookCall(0x4C071C, wmRndEncounterOccurred_hook);
|
||||
static void _stdcall ForceEncounter2() {
|
||||
if (ForceEnconterFlags & (1 << 31)) return; // wait prev. encounter
|
||||
|
||||
if (flags & 1) SafeWrite8(0x4C0706, 0xEB);
|
||||
const ScriptValue &mapIDArg = opHandler.arg(0);
|
||||
if (mapIDArg.isInt()) {
|
||||
DWORD mapID = mapIDArg.rawValue();
|
||||
if (mapID < 0) {
|
||||
opHandler.printOpcodeError("force_encounter() - invalid map number.");
|
||||
return;
|
||||
}
|
||||
if (ForceEnconterMapID == -1) MakeJump(0x4C06D1, wmRndEncounterOccurred_hack);
|
||||
|
||||
ForceEnconterMapID = mapID;
|
||||
DWORD flags = 0;
|
||||
if (opHandler.numArgs() > 1) {
|
||||
flags = opHandler.arg(1).asInt();
|
||||
if (flags & 2) { // _Lock flag
|
||||
flags |= (1 << 31); // set bit 31
|
||||
} else {
|
||||
flags = flags & ~(1 << 31);
|
||||
}
|
||||
}
|
||||
ForceEnconterFlags = flags;
|
||||
} else {
|
||||
OpcodeInvalidArgs("force_encounter");
|
||||
}
|
||||
}
|
||||
|
||||
static void __declspec(naked) ForceEncounter() {
|
||||
__asm {
|
||||
push ecx;
|
||||
push edx;
|
||||
_GET_ARG_INT(end);
|
||||
xor edx, edx; // flags
|
||||
mov ecx, eax; // mapID
|
||||
call ForceEncounter2;
|
||||
end:
|
||||
pop edx;
|
||||
pop ecx;
|
||||
retn;
|
||||
}
|
||||
_WRAP_OPCODE(ForceEncounter2, 1, 0)
|
||||
}
|
||||
|
||||
static void __declspec(naked) ForceEncounterWithFlags() {
|
||||
__asm {
|
||||
pushad;
|
||||
mov ecx, eax;
|
||||
call interpretPopShort_;
|
||||
mov edx, eax;
|
||||
mov eax, ecx;
|
||||
call interpretPopLong_;
|
||||
mov ebx, eax;
|
||||
mov eax, ecx;
|
||||
call interpretPopShort_;
|
||||
mov edi, eax;
|
||||
mov eax, ecx;
|
||||
call interpretPopLong_;
|
||||
cmp dx, VAR_TYPE_INT;
|
||||
jnz end;
|
||||
cmp di, VAR_TYPE_INT;
|
||||
jnz end;
|
||||
mov edx, ebx; // flags
|
||||
mov ecx, eax; // mapID
|
||||
call ForceEncounter2;
|
||||
end:
|
||||
popad;
|
||||
retn;
|
||||
}
|
||||
_WRAP_OPCODE(ForceEncounter2, 2, 0)
|
||||
}
|
||||
|
||||
// world_map_functions
|
||||
|
||||
Reference in New Issue
Block a user