Add op_force_encounter
This commit is contained in:
parent
84aecfa823
commit
bb3513956c
|
@ -138,6 +138,13 @@ static void op_in_world_map(Program* program)
|
|||
programStackPushInteger(program, GameMode::isInGameMode(GameMode::kWorldmap) ? 1 : 0);
|
||||
}
|
||||
|
||||
// force_encounter
|
||||
static void op_force_encounter(Program* program)
|
||||
{
|
||||
int map = programStackPopInteger(program);
|
||||
wmForceEncounter(map, 0);
|
||||
}
|
||||
|
||||
// set_world_map_pos
|
||||
static void op_set_world_map_pos(Program* program)
|
||||
{
|
||||
|
@ -541,6 +548,14 @@ static void op_get_attack_type(Program* program)
|
|||
}
|
||||
}
|
||||
|
||||
// force_encounter_with_flags
|
||||
static void op_force_encounter_with_flags(Program* program)
|
||||
{
|
||||
unsigned int flags = programStackPopInteger(program);
|
||||
int map = programStackPopInteger(program);
|
||||
wmForceEncounter(map, flags);
|
||||
}
|
||||
|
||||
// atoi
|
||||
static void opParseInt(Program* program)
|
||||
{
|
||||
|
@ -894,6 +909,7 @@ void sfallOpcodesInit()
|
|||
interpreterRegisterOpcode(0x816A, op_set_global_script_repeat);
|
||||
interpreterRegisterOpcode(0x816C, op_key_pressed);
|
||||
interpreterRegisterOpcode(0x8170, op_in_world_map);
|
||||
interpreterRegisterOpcode(0x8171, op_force_encounter);
|
||||
interpreterRegisterOpcode(0x8172, op_set_world_map_pos);
|
||||
interpreterRegisterOpcode(0x8193, opGetCurrentHand);
|
||||
interpreterRegisterOpcode(0x819B, op_set_global_script_type);
|
||||
|
@ -927,6 +943,7 @@ void sfallOpcodesInit()
|
|||
interpreterRegisterOpcode(0x8221, opGetScreenHeight);
|
||||
interpreterRegisterOpcode(0x8224, op_create_message_window);
|
||||
interpreterRegisterOpcode(0x8228, op_get_attack_type);
|
||||
interpreterRegisterOpcode(0x8229, op_force_encounter_with_flags);
|
||||
interpreterRegisterOpcode(0x822D, opCreateArray);
|
||||
interpreterRegisterOpcode(0x822E, opSetArray);
|
||||
interpreterRegisterOpcode(0x822F, opGetArray);
|
||||
|
|
|
@ -817,6 +817,8 @@ static double gGameTimeIncRemainder = 0.0;
|
|||
static FrmImage _backgroundFrmImage;
|
||||
static FrmImage _townFrmImage;
|
||||
static bool wmFaded = false;
|
||||
static int wmForceEncounterMapId = -1;
|
||||
static unsigned int wmForceEncounterFlags = 0;
|
||||
|
||||
static inline bool cityIsValid(int city)
|
||||
{
|
||||
|
@ -929,6 +931,9 @@ static int wmGenDataInit()
|
|||
wmGenData.tabsScrollingDelta = 0;
|
||||
wmGenData.viewportMaxX = 0;
|
||||
|
||||
wmForceEncounterMapId = -1;
|
||||
wmForceEncounterFlags = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -979,6 +984,9 @@ static int wmGenDataReset()
|
|||
|
||||
wmMarkSubTileRadiusVisited(wmGenData.worldPosX, wmGenData.worldPosY);
|
||||
|
||||
wmForceEncounterMapId = -1;
|
||||
wmForceEncounterFlags = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -3347,6 +3355,33 @@ static int wmRndEncounterOccurred()
|
|||
}
|
||||
}
|
||||
|
||||
// SFALL: Handle forced encounter.
|
||||
// CE: In Sfall a check for forced encounter is inserted instead of check
|
||||
// for Horrigan encounter (above). This implemenation gives Horrigan
|
||||
// encounter a priority.
|
||||
if (wmForceEncounterMapId != -1) {
|
||||
if ((wmForceEncounterFlags & ENCOUNTER_FLAG_NO_CAR) != 0) {
|
||||
if (wmGenData.isInCar) {
|
||||
wmMatchAreaContainingMapIdx(wmForceEncounterMapId, &(wmGenData.currentCarAreaId));
|
||||
}
|
||||
}
|
||||
|
||||
// For unknown reason fadeout and blinking icon are mutually exclusive.
|
||||
if ((wmForceEncounterFlags & ENCOUNTER_FLAG_FADEOUT) != 0) {
|
||||
wmFadeOut();
|
||||
} else if ((wmForceEncounterFlags & ENCOUNTER_FLAG_NO_ICON) == 0) {
|
||||
bool special = (wmForceEncounterFlags & ENCOUNTER_FLAG_ICON_SP) != 0;
|
||||
wmBlinkRndEncounterIcon(special);
|
||||
}
|
||||
|
||||
mapLoadById(wmForceEncounterMapId);
|
||||
|
||||
wmForceEncounterMapId = -1;
|
||||
wmForceEncounterFlags = 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
// NOTE: Uninline.
|
||||
wmPartyFindCurSubTile();
|
||||
|
||||
|
@ -6608,4 +6643,21 @@ void wmCarSetCurrentArea(int area)
|
|||
wmGenData.currentCarAreaId = area;
|
||||
}
|
||||
|
||||
void wmForceEncounter(int map, unsigned int flags)
|
||||
{
|
||||
if ((wmForceEncounterFlags & (1 << 31)) != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
wmForceEncounterMapId = map;
|
||||
wmForceEncounterFlags = flags;
|
||||
|
||||
// I don't quite understand the reason why locking needs one more flag.
|
||||
if ((wmForceEncounterFlags & ENCOUNTER_FLAG_LOCK) != 0) {
|
||||
wmForceEncounterFlags |= (1 << 31);
|
||||
} else {
|
||||
wmForceEncounterFlags &= ~(1 << 31);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace fallout
|
||||
|
|
|
@ -229,6 +229,12 @@ typedef enum Map {
|
|||
MAP_IN_GAME_MOVIE1 = 149,
|
||||
} Map;
|
||||
|
||||
#define ENCOUNTER_FLAG_NO_CAR 0x1
|
||||
#define ENCOUNTER_FLAG_LOCK 0x2
|
||||
#define ENCOUNTER_FLAG_NO_ICON 0x4
|
||||
#define ENCOUNTER_FLAG_ICON_SP 0x8
|
||||
#define ENCOUNTER_FLAG_FADEOUT 0x10
|
||||
|
||||
extern unsigned char* circleBlendTable;
|
||||
|
||||
int wmWorldMap_init();
|
||||
|
@ -279,6 +285,7 @@ int wmTeleportToArea(int areaIdx);
|
|||
|
||||
void wmSetPartyWorldPos(int x, int y);
|
||||
void wmCarSetCurrentArea(int area);
|
||||
void wmForceEncounter(int map, unsigned int flags);
|
||||
|
||||
} // namespace fallout
|
||||
|
||||
|
|
Loading…
Reference in New Issue