Rewrote the code of force_encounter functions

Added a new flag to force_encounter_with_flags.
This commit is contained in:
NovaRain
2019-08-12 21:12:28 +08:00
parent 36523d89e5
commit 81ba15d451
7 changed files with 62 additions and 62 deletions
+1
View File
@@ -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)
+1
View File
@@ -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;
+2
View File
@@ -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_;
+3 -2
View File
@@ -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();
+1
View File
@@ -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
+3 -3
View File
@@ -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");
}
}
+50 -56
View File
@@ -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