Refactor objective checks

* Use a dirty flag so statuses can be recalculated only when they might have changed
* Remove support for unused criteria types
* Re-ID the status constants so the objective status can be the minimum of the criteria statuses
* Merge multiple complete flags into one criteria item
* Merge multiple fail flags into one criteria item
* Use a g_AnyObjectiveFailed variable so the objectives failed AI doesn't have to iterate them
This commit is contained in:
Ryan Dwyer 2022-11-17 17:36:19 +10:00
parent d8137e2d6b
commit 6181870b38
30 changed files with 93 additions and 277 deletions

View File

@ -979,6 +979,5 @@ void bbikeTick(void)
bgunSetAdjustPos(g_Vars.currentplayer->vv_verta360 * 0.017450513318181f);
playerUpdatePerimInfo();
bmoveUpdateRooms(g_Vars.currentplayer);
objectiveCheckRoomEntered(g_Vars.currentplayer->prop->rooms[0]);
doorsCheckAutomatic();
}

View File

@ -1139,7 +1139,6 @@ void bgrabTick(void)
}
bmoveUpdateRooms(g_Vars.currentplayer);
objectiveCheckRoomEntered(g_Vars.currentplayer->prop->rooms[0]);
bmove0f0cc19c(&g_Vars.currentplayer->prop->pos);
playerUpdatePerimInfo();
doorsCheckAutomatic();

View File

@ -1655,7 +1655,6 @@ void bwalkTick(void)
}
bmoveUpdateRooms(g_Vars.currentplayer);
objectiveCheckRoomEntered(g_Vars.currentplayer->prop->rooms[0]);
if (g_Vars.currentplayer->walkinitmove) {
struct coord coord;

View File

@ -1967,22 +1967,6 @@ bool aiIfObjectiveFailed(s32 index)
&& objectiveGetDifficultyBits(index) & (1 << lvGetDifficulty());
}
bool aiIfAnyObjectiveFailed(void)
{
s32 numobjectives = objectiveGetCount();
s32 mask = 1 << lvGetDifficulty();
s32 i;
for (i = 0; i < numobjectives; i++) {
if (g_ObjectiveStatuses[i] == OBJECTIVE_FAILED
&& objectiveGetDifficultyBits(i) & mask) {
return true;
}
}
return false;
}
bool aiIfObjectDistanceToPadLessThan(s32 tagnum, s32 padnum, f32 distance)
{
f32 xdiff;
@ -3657,6 +3641,12 @@ void aiSetShotList(u8 *ailist)
}
}
void aiSetStageFlag(u32 flag)
{
g_StageFlags |= flag;
g_ObjectivesDirty = true;
}
void aiSetSquadron(s32 squadron)
{
g_Vars.chrdata->squadron = squadron;
@ -4311,6 +4301,12 @@ void aiUnsetRoomFlag(s32 roomnum, u32 flag)
g_Rooms[roomnum].flags &= ~flag;
}
void aiUnsetStageFlag(u32 flag)
{
g_StageFlags &= flag;
g_ObjectivesDirty = true;
}
void aiWalkToPad(s32 padnum)
{
chrGoToPad(g_Vars.chrdata, padnum, GOPOSFLAG_WALK);

View File

@ -452,6 +452,8 @@ bool invGiveProp(struct prop *prop)
item->type = INVITEMTYPE_PROP;
item->type_prop.prop = prop;
invInsertItem(item);
g_ObjectivesDirty = true;
}
return true;
@ -467,6 +469,7 @@ void invRemoveProp(struct prop *prop)
if (item->type == INVITEMTYPE_PROP && item->type_prop.prop == prop) {
invRemoveItem(item);
g_ObjectivesDirty = true;
}
if (item == g_Vars.currentplayer->weapons || !g_Vars.currentplayer->weapons) {

View File

@ -26,12 +26,12 @@ struct objective *g_Objectives[MAX_OBJECTIVES];
u32 g_ObjectiveStatuses[MAX_OBJECTIVES];
struct tag *g_TagsLinkedList;
struct briefingobj *g_BriefingObjs;
struct criteria_roomentered *g_RoomEnteredCriterias;
struct criteria_throwinroom *g_ThrowInRoomCriterias;
struct criteria_holograph *g_HolographCriterias;
s32 g_NumTags;
struct tag **g_TagPtrs;
u32 var8009d0cc;
bool g_ObjectivesDirty;
bool g_AnyObjectiveFailed;
s32 g_ObjectiveLastIndex = -1;
bool g_ObjectiveChecksDisabled = false;
@ -142,31 +142,23 @@ s32 objectiveCheck(s32 index)
if (g_Objectives[index] == NULL) {
objstatus = g_ObjectiveStatuses[index];
} else {
// Note: This is setting the cmd pointer to the start of the
// beginobjective macro in the stage's setup file. The first
// iteration of the while loop below will skip past it.
u32 *cmd = (u32 *)g_Objectives[index];
// Move past beginobjective
cmd = cmd + setupGetCmdLength(cmd);
while ((u8)cmd[0] != OBJTYPE_ENDOBJECTIVE) {
// The status of this requirement
s32 reqstatus = OBJECTIVE_COMPLETE;
switch ((u8)cmd[0]) {
case OBJECTIVETYPE_DESTROYOBJ:
{
struct defaultobj *obj = objFindByTagId(cmd[1]);
if (obj && obj->prop && objIsHealthy(obj)) {
reqstatus = OBJECTIVE_INCOMPLETE;
}
}
break;
case OBJECTIVETYPE_COMPFLAGS:
if (!chrHasStageFlag(NULL, cmd[1])) {
if ((g_StageFlags & cmd[1]) != cmd[1]) {
reqstatus = OBJECTIVE_INCOMPLETE;
}
break;
case OBJECTIVETYPE_FAILFLAGS:
if (chrHasStageFlag(NULL, cmd[1])) {
if (g_StageFlags & cmd[1]) {
reqstatus = OBJECTIVE_FAILED;
}
break;
@ -196,74 +188,26 @@ s32 objectiveCheck(s32 index)
setCurrentPlayerNum(prevplayernum);
if (!collected) {
reqstatus = OBJECTIVE_INCOMPLETE;
reqstatus = OBJECTIVE_INCOMPLETE;
}
}
}
break;
case OBJECTIVETYPE_THROWOBJ:
{
struct defaultobj *obj = objFindByTagId(cmd[1]);
if (obj && obj->prop) {
s32 i;
s32 prevplayernum = g_Vars.currentplayernum;
for (i = 0; i < PLAYERCOUNT(); i++) {
if (g_Vars.players[i] == g_Vars.bond || g_Vars.players[i] == g_Vars.coop) {
setCurrentPlayerNum(i);
if (invHasProp(obj->prop)) {
reqstatus = OBJECTIVE_INCOMPLETE;
break;
}
}
}
setCurrentPlayerNum(prevplayernum);
}
}
break;
case OBJECTIVETYPE_HOLOGRAPH:
{
if (cmd[2] == OBJECTIVE_INCOMPLETE) {
struct defaultobj *obj = objFindByTagId(cmd[1]);
if (cmd[2] == 0) {
if (!obj || !obj->prop || !objIsHealthy(obj)) {
reqstatus = OBJECTIVE_FAILED;
} else {
reqstatus = OBJECTIVE_INCOMPLETE;
}
if (!obj || !obj->prop || !objIsHealthy(obj)) {
reqstatus = OBJECTIVE_FAILED;
} else {
reqstatus = OBJECTIVE_INCOMPLETE;
}
}
break;
case OBJECTIVETYPE_ENTERROOM:
if (cmd[2] == 0) {
reqstatus = OBJECTIVE_INCOMPLETE;
}
break;
case OBJECTIVETYPE_THROWINROOM:
if (cmd[3] == 0) {
reqstatus = OBJECTIVE_INCOMPLETE;
}
break;
case OBJTYPE_BEGINOBJECTIVE:
case OBJTYPE_ENDOBJECTIVE:
break;
}
if (objstatus == OBJECTIVE_COMPLETE) {
if (reqstatus != OBJECTIVE_COMPLETE) {
// This is the first requirement that is causing the
// objective to not be complete, so apply it.
objstatus = reqstatus;
}
} else if (objstatus == OBJECTIVE_INCOMPLETE) {
if (reqstatus == OBJECTIVE_FAILED) {
// An earlier requirement was incomplete,
// and this requirement is failed.
objstatus = reqstatus;
}
if (reqstatus < objstatus) {
objstatus = reqstatus;
}
cmd = cmd + setupGetCmdLength(cmd);
@ -315,9 +259,10 @@ void objectivesCheckAll(void)
{
s32 availableindex = 0;
s32 i;
char buffer[50] = "";
char buffer[50];
bool anyfailed = false;
if (!g_ObjectiveChecksDisabled) {
if (g_ObjectivesDirty && !g_ObjectiveChecksDisabled) {
for (i = 0; i <= g_ObjectiveLastIndex; i++) {
s32 status = objectiveCheck(i);
@ -342,50 +287,17 @@ void objectivesCheckAll(void)
}
}
if (status == OBJECTIVE_FAILED) {
anyfailed = true;
}
if (objectiveGetDifficultyBits(i) & (1 << lvGetDifficulty())) {
availableindex++;
}
}
}
}
void objectiveCheckRoomEntered(s32 currentroom)
{
struct criteria_roomentered *criteria = g_RoomEnteredCriterias;
while (criteria) {
if (criteria->status == OBJECTIVE_INCOMPLETE) {
s32 room = chrGetPadRoom(NULL, criteria->pad);
if (room >= 0 && room == currentroom) {
criteria->status = OBJECTIVE_COMPLETE;
}
}
criteria = criteria->next;
}
}
void objectiveCheckThrowInRoom(s32 arg0, s16 *inrooms)
{
struct criteria_throwinroom *criteria = g_ThrowInRoomCriterias;
while (criteria) {
if (criteria->status == OBJECTIVE_INCOMPLETE && criteria->unk04 == arg0) {
s32 room = chrGetPadRoom(NULL, criteria->pad);
if (room >= 0) {
s16 requirerooms[2];
requirerooms[0] = room;
requirerooms[1] = -1;
if (arrayIntersects(requirerooms, inrooms)) {
criteria->status = OBJECTIVE_COMPLETE;
}
}
}
criteria = criteria->next;
g_AnyObjectiveFailed = anyfailed;
g_ObjectivesDirty = false;
}
}
@ -436,6 +348,8 @@ void objectiveCheckHolograph(f32 maxdist)
struct trainingdata *data = dtGetData();
data->holographedpc = true;
}
g_ObjectivesDirty = true;
}
}
}

View File

@ -14,7 +14,7 @@ void objectivesReset(void)
g_ObjectiveLastIndex = -1;
for (i = 0; i < ARRAYCOUNT(g_ObjectiveStatuses); i++) {
g_ObjectiveStatuses[i] = 0;
g_ObjectiveStatuses[i] = OBJECTIVE_INCOMPLETE;
}
}
@ -26,9 +26,10 @@ void objectivesReset(void)
g_TagsLinkedList = NULL;
g_BriefingObjs = NULL;
g_RoomEnteredCriterias = NULL;
g_ThrowInRoomCriterias = NULL;
g_HolographCriterias = NULL;
g_ObjectivesDirty = true;
g_AnyObjectiveFailed = false;
}
void tagInsert(struct tag *tag)
@ -52,18 +53,6 @@ void objectiveInsert(struct objective *objective)
}
}
void objectiveAddRoomEnteredCriteria(struct criteria_roomentered *criteria)
{
criteria->next = g_RoomEnteredCriterias;
g_RoomEnteredCriterias = criteria;
}
void objectiveAddThrowInRoomCriteria(struct criteria_throwinroom *criteria)
{
criteria->next = g_ThrowInRoomCriterias;
g_ThrowInRoomCriterias = criteria;
}
void objectiveAddHolographCriteria(struct criteria_holograph *criteria)
{
criteria->next = g_HolographCriterias;

View File

@ -3922,8 +3922,6 @@ void objLand(struct prop *prop, struct coord *arg1, struct coord *arg2, bool *em
obj->flags2 |= OBJFLAG2_IMMUNETOGUNFIRE;
}
objectiveCheckThrowInRoom(weapon->weaponnum, prop->rooms);
if (weapon->weaponnum == WEAPON_BOLT) {
boltLand(weapon, arg1);
} else if (weapon->weaponnum == WEAPON_COMBATKNIFE) {
@ -7145,11 +7143,6 @@ s32 projectileTick(struct defaultobj *obj, bool *embedded)
if (stop) {
objFreeProjectile(obj);
if (obj->type == OBJTYPE_WEAPON) {
struct weaponobj *weapon = (struct weaponobj *) obj;
objectiveCheckThrowInRoom(weapon->weaponnum, prop->rooms);
}
}
if (result) {

View File

@ -1788,12 +1788,6 @@ void setupCreateProps(s32 stagenum)
}
}
break;
case OBJECTIVETYPE_ENTERROOM:
objectiveAddRoomEnteredCriteria((struct criteria_roomentered *)obj);
break;
case OBJECTIVETYPE_THROWINROOM:
objectiveAddThrowInRoomCriteria((struct criteria_throwinroom *)obj);
break;
case OBJECTIVETYPE_HOLOGRAPH:
objectiveAddHolographCriteria((struct criteria_holograph *)obj);
break;

View File

@ -123,10 +123,10 @@ extern struct stagesetup g_StageSetup;
extern u8 *g_GeCreditsData;
extern struct objective *g_Objectives[MAX_OBJECTIVES];
extern u32 g_ObjectiveStatuses[MAX_OBJECTIVES];
extern bool g_ObjectivesDirty;
extern bool g_AnyObjectiveFailed;
extern struct tag *g_TagsLinkedList;
extern struct briefingobj *g_BriefingObjs;
extern struct criteria_roomentered *g_RoomEnteredCriterias;
extern struct criteria_throwinroom *g_ThrowInRoomCriterias;
extern struct criteria_holograph *g_HolographCriterias;
extern struct sndstate *g_CasingAudioHandles[2];
extern s32 var8009d0d8;

View File

@ -3017,9 +3017,9 @@
#define NUM_STAGES 90
#define NUM_TEXTURES (VERSION == VERSION_JPN_FINAL ? 3511 : 3503)
#define OBJECTIVE_INCOMPLETE 0
#define OBJECTIVE_COMPLETE 1
#define OBJECTIVE_FAILED 2
#define OBJECTIVE_FAILED 0
#define OBJECTIVE_INCOMPLETE 1
#define OBJECTIVE_COMPLETE 2
#define OBJECTIVEFLAG_AUTOCOMPLETE 0x01

View File

@ -26,8 +26,6 @@ bool objectiveIsAllComplete(void);
void objectivesDisableChecking(void);
void objectivesShowHudmsg(char *buffer, s32 hudmsgtype);
void objectivesCheckAll(void);
void objectiveCheckRoomEntered(s32 currentroom);
void objectiveCheckThrowInRoom(s32 arg0, s16 *requiredrooms);
void objectiveCheckHolograph(f32 sqdist);
struct prop *chopperGetTargetProp(struct chopperobj *heli);
struct defaultobj *objFindByTagId(s32 tag_id);

View File

@ -116,7 +116,7 @@
0x1d, object,
#define require_object_holographed(object) \
0x1e, object, 0, 0,
0x1e, object, OBJECTIVE_INCOMPLETE, 0,
#define require_room_entered(room) \
0x20, room,

View File

@ -157,27 +157,22 @@ u32 props[] = {
beginobjective(0, L_AME_016, (DIFFBIT_SA | DIFFBIT_PA | DIFFBIT_PD)) // "Disable internal security hub"
complete_flags(STAGEFLAG_SECURITYHUB_COMPLETE)
fail_flags(STAGEFLAG_SECURITYHUB_MINES_WASTED)
fail_flags(STAGEFLAG_SECURITYHUB_DESTROYED)
fail_flags(STAGEFLAG_SECURITYHUB_MINES_WASTED | STAGEFLAG_SECURITYHUB_DESTROYED)
endobjective
beginobjective(1, L_AME_017, (DIFFBIT_SA | DIFFBIT_PA | DIFFBIT_PD)) // "Obtain keycode necklace"
require_object_collected(OBJ_NECKLACE)
fail_flags(STAGEFLAG_DOORSWITCH_DESTROYED)
fail_flags(STAGEFLAG_CIVILIANS_KILLED)
fail_flags(STAGEFLAG_DOORSWITCH_DESTROYED | STAGEFLAG_CIVILIANS_KILLED)
endobjective
beginobjective(2, L_AME_018, (DIFFBIT_PA | DIFFBIT_PD)) // "Download project files"
complete_flags(STAGEFLAG_DOWNLOAD_COMPLETE)
fail_flags(STAGEFLAG_PROGRAMMER_DEAD)
fail_flags(STAGEFLAG_DELETED_WITHOUT_DOWNLOAD)
fail_flags(STAGEFLAG_PC_DESTROYED)
fail_flags(STAGEFLAG_PROGRAMMER_DEAD | STAGEFLAG_DELETED_WITHOUT_DOWNLOAD | STAGEFLAG_PC_DESTROYED)
endobjective
beginobjective(3, L_AME_019, (DIFFBIT_SA | DIFFBIT_PA | DIFFBIT_PD)) // "Disable external comms hub"
complete_flags(STAGEFLAG_EXTCOMMSHUB_COMPLETE)
fail_flags(STAGEFLAG_EXTCOMMSHUB_MINES_WASTED)
fail_flags(STAGEFLAG_EXTCOMMSHUB_DESTROYED)
fail_flags(STAGEFLAG_EXTCOMMSHUB_MINES_WASTED | STAGEFLAG_EXTCOMMSHUB_DESTROYED)
endobjective
beginobjective(4, L_AME_020, DIFFBIT_A) // "Gain entrance to laboratory"

View File

@ -101,26 +101,18 @@ u32 props[] = {
briefing(BRIEFINGTYPE_TEXT_A, L_CAVE_003)
beginobjective(0, L_CAVE_005, (DIFFBIT_A | DIFFBIT_SA | DIFFBIT_PA | DIFFBIT_PD)) // "Obtain disguise and enter base"
complete_flags(STAGEFLAG_DISGUISED2)
complete_flags(STAGEFLAG_ENTERED_BASE)
fail_flags(STAGEFLAG_CIVILIANS_KILLED)
fail_flags(STAGEFLAG_DISGUISE_UNCOVERED)
fail_flags(STAGEFLAG_STEWARDESS_ENTERED_BASE)
fail_flags(STAGEFLAG_RECEPTIONIST_CALLED_SECURITY)
fail_flags(STAGEFLAG_TOO_MANY_NEUTRALS_KILLED)
fail_flags(STAGEFLAG_SECRETARY_DEAD)
complete_flags(STAGEFLAG_DISGUISED2 | STAGEFLAG_ENTERED_BASE)
fail_flags(STAGEFLAG_CIVILIANS_KILLED | STAGEFLAG_DISGUISE_UNCOVERED | STAGEFLAG_STEWARDESS_ENTERED_BASE | STAGEFLAG_RECEPTIONIST_CALLED_SECURITY | STAGEFLAG_TOO_MANY_NEUTRALS_KILLED | STAGEFLAG_SECRETARY_DEAD)
endobjective
beginobjective(1, L_CAVE_006, (DIFFBIT_SA | DIFFBIT_PA | DIFFBIT_PD)) // "Check in equipment"
complete_flags(STAGEFLAG_SUITCASE_DEPOSITED)
fail_flags(STAGEFLAG_WEAPONS_DETECTED)
fail_flags(STAGEFLAG_TROLLEY_SHUT_DOWN_WITHOUT_BRIEFCASE)
fail_flags(STAGEFLAG_WEAPONS_DETECTED | STAGEFLAG_TROLLEY_SHUT_DOWN_WITHOUT_BRIEFCASE)
endobjective
beginobjective(2, L_CAVE_007, (DIFFBIT_A | DIFFBIT_SA | DIFFBIT_PA | DIFFBIT_PD)) // "Subvert security monitoring system"
complete_flags(STAGEFLAG_SECURITY_SHUT_DOWN)
fail_flags(STAGEFLAG_SUITCASE_SCANNED)
fail_flags(STAGEFLAG_CONSOLE_DESTROYED)
fail_flags(STAGEFLAG_SUITCASE_SCANNED | STAGEFLAG_CONSOLE_DESTROYED)
endobjective
beginobjective(3, L_CAVE_008, (DIFFBIT_PA | DIFFBIT_PD)) // "Obtain flight plans from safe"

View File

@ -119,11 +119,8 @@ u32 props[] = {
endobjective
beginobjective(2, L_DAM_005, (DIFFBIT_A | DIFFBIT_SA | DIFFBIT_PA | DIFFBIT_PD)) // "Deactivate GPS and autopilot"
complete_flags(STAGEFLAG_GPS_DISABLED)
complete_flags(STAGEFLAG_AUTOPILOT_DISABLED)
fail_flags(STAGEFLAG_00000400)
fail_flags(STAGEFLAG_PILOT_DEAD)
fail_flags(STAGEFLAG_JO_KILLED_A_PILOT)
complete_flags(STAGEFLAG_GPS_DISABLED | STAGEFLAG_AUTOPILOT_DISABLED)
fail_flags(STAGEFLAG_00000400 | STAGEFLAG_PILOT_DEAD | STAGEFLAG_JO_KILLED_A_PILOT)
endobjective
beginobjective(3, L_DAM_008, (DIFFBIT_SA | DIFFBIT_PA | DIFFBIT_PD)) // "Activate Moon Pool lift"

View File

@ -126,22 +126,13 @@ u32 props[] = {
endobjective
beginobjective(1, L_DEPO_010, (DIFFBIT_SA | DIFFBIT_PA | DIFFBIT_PD)) // "Deactivate laser grid systems"
complete_flags(STAGEFLAG_ALL_LASERS_DISABLED)
complete_flags(STAGEFLAG_LASERSET1_DISABLED)
complete_flags(STAGEFLAG_LASERSET2_DISABLED)
complete_flags(STAGEFLAG_LASERSET3_DISABLED)
complete_flags(STAGEFLAG_LASERSET4_DISABLED)
fail_flags(STAGEFLAG_LASERSWITCH1_DESTROYED)
fail_flags(STAGEFLAG_LASERSWITCH2_DESTROYED)
fail_flags(STAGEFLAG_LASERSWITCH3_DESTROYED)
fail_flags(STAGEFLAG_LASERSWITCH4_DESTROYED)
complete_flags(STAGEFLAG_ALL_LASERS_DISABLED | STAGEFLAG_LASERSET1_DISABLED | STAGEFLAG_LASERSET2_DISABLED | STAGEFLAG_LASERSET3_DISABLED | STAGEFLAG_LASERSET4_DISABLED)
fail_flags(STAGEFLAG_LASERSWITCH1_DESTROYED | STAGEFLAG_LASERSWITCH2_DESTROYED | STAGEFLAG_LASERSWITCH3_DESTROYED | STAGEFLAG_LASERSWITCH4_DESTROYED)
endobjective
beginobjective(2, L_DEPO_011, (DIFFBIT_A | DIFFBIT_SA | DIFFBIT_PA | DIFFBIT_PD)) // "Holograph meeting conspirators"
complete_flags(STAGEFLAG_MEETING_HOLOGRAPHED)
fail_flags(STAGEFLAG_20000000)
fail_flags(STAGEFLAG_CONSPIRATORS_ALERTED)
fail_flags(STAGEFLAG_00002000)
fail_flags(STAGEFLAG_20000000 | STAGEFLAG_CONSPIRATORS_ALERTED | STAGEFLAG_00002000)
endobjective
beginobjective(3, L_DEPO_012, (DIFFBIT_A | DIFFBIT_SA | DIFFBIT_PA | DIFFBIT_PD)) // "Retrieve Dr. Caroll backup from safe"

View File

@ -118,17 +118,12 @@ u32 props[] = {
beginobjective(1, L_EAR_011, (DIFFBIT_SA | DIFFBIT_PA | DIFFBIT_PD)) // "Start security maintenance cycle"
complete_flags(STAGEFLAG_BOT_ACTIVE_MAINTENANCE)
fail_flags(STAGEFLAG_BOT_ACTIVATION_TERMINAL_DESTROYED)
fail_flags(STAGEFLAG_BOT_PROGRAMMING_TERMINAL_DESTROYED)
fail_flags(STAGEFLAG_BOT_ACTIVATION_TERMINAL_DESTROYED | STAGEFLAG_BOT_PROGRAMMING_TERMINAL_DESTROYED)
endobjective
beginobjective(2, L_EAR_010, (DIFFBIT_SA | DIFFBIT_PA | DIFFBIT_PD)) // "Shut down experiments"
complete_flags(STAGEFLAG_SHUT_DOWN_EXPERIMENT1)
complete_flags(STAGEFLAG_SHUT_DOWN_EXPERIMENT2)
complete_flags(STAGEFLAG_SHUT_DOWN_EXPERIMENT3)
fail_flags(STAGEFLAG_GOODTERM_DESTROYED)
fail_flags(STAGEFLAG_UNACCEPTABLE_CASUALTIES)
fail_flags(STAGEFLAG_00000008)
complete_flags(STAGEFLAG_SHUT_DOWN_EXPERIMENT1 | STAGEFLAG_SHUT_DOWN_EXPERIMENT2 | STAGEFLAG_SHUT_DOWN_EXPERIMENT3)
fail_flags(STAGEFLAG_GOODTERM_DESTROYED | STAGEFLAG_UNACCEPTABLE_CASUALTIES | STAGEFLAG_00000008)
endobjective
beginobjective(3, L_EAR_012, (DIFFBIT_PA | DIFFBIT_PD)) // "Obtain experimental technologies"

View File

@ -123,8 +123,7 @@ u32 props[] = {
beginobjective(3, L_ELD_008, (DIFFBIT_PA | DIFFBIT_PD)) // "Locate and eliminate dataDyne hackers"
complete_flags(STAGEFLAG_HACKERS_DEAD)
fail_flags(STAGEFLAG_HACKERS_SUCCEEDED)
fail_flags(STAGEFLAG_HACKER_PC_DESTROYED)
fail_flags(STAGEFLAG_HACKERS_SUCCEEDED | STAGEFLAG_HACKER_PC_DESTROYED)
endobjective
beginobjective(4, L_ELD_010, (DIFFBIT_PA | DIFFBIT_PD)) // "Capture dataDyne guard"

View File

@ -164,11 +164,8 @@ u32 props[] = {
briefing(BRIEFINGTYPE_TEXT_A, L_IMP_003)
beginobjective(0, L_IMP_005, (DIFFBIT_SA | DIFFBIT_PA | DIFFBIT_PD)) // "Reactivate automatic defenses"
complete_flags(STAGEFLAG_AUTOGUN1_ACTIVE)
complete_flags(STAGEFLAG_AUTOGUN2_ACTIVE)
complete_flags(STAGEFLAG_AUTOGUN3_ACTIVE)
fail_flags(STAGEFLAG_AUTOGUN_SWITCH_DESTROYED)
fail_flags(STAGEFLAG_00000001)
complete_flags(STAGEFLAG_AUTOGUN1_ACTIVE | STAGEFLAG_AUTOGUN2_ACTIVE | STAGEFLAG_AUTOGUN3_ACTIVE)
fail_flags(STAGEFLAG_AUTOGUN_SWITCH_DESTROYED | STAGEFLAG_00000001)
endobjective
beginobjective(1, L_IMP_006, (DIFFBIT_A | DIFFBIT_SA | DIFFBIT_PA | DIFFBIT_PD)) // "Release hostages"
@ -187,8 +184,7 @@ u32 props[] = {
beginobjective(4, L_IMP_009, (DIFFBIT_A | DIFFBIT_SA | DIFFBIT_PA | DIFFBIT_PD)) // "Deactivate bomb"
complete_flags(STAGEFLAG_BOMB_AIRBORNE)
fail_flags(STAGEFLAG_BOMB_EXPLODING_ON_GROUND)
fail_flags(STAGEFLAG_CARRINGTON_DEAD)
fail_flags(STAGEFLAG_BOMB_EXPLODING_ON_GROUND | STAGEFLAG_CARRINGTON_DEAD)
endobjective
tag(0x23, 2)

View File

@ -361,14 +361,12 @@ u32 props[] = {
beginobjective(3, L_LIP_012, (DIFFBIT_A | DIFFBIT_SA | DIFFBIT_PA | DIFFBIT_PD)) // "Gain access to autopsy lab"
complete_flags(STAGEFLAG_ENTERED_LAB)
require_object_collected(OBJ_KEYCARD)
fail_flags(STAGEFLAG_DOORMAN_REJECTED)
fail_flags(STAGEFLAG_DOORMAN_DEAD)
fail_flags(STAGEFLAG_DOORMAN_REJECTED | STAGEFLAG_DOORMAN_DEAD)
endobjective
beginobjective(4, L_LIP_013, (DIFFBIT_A | DIFFBIT_SA | DIFFBIT_PA | DIFFBIT_PD)) // "Rescue the crash Survivor"
complete_flags(STAGEFLAG_RESCUED_ELVIS)
fail_flags(STAGEFLAG_ELVIS_DEAD)
fail_flags(STAGEFLAG_CRATE_DESTROYED)
fail_flags(STAGEFLAG_ELVIS_DEAD | STAGEFLAG_CRATE_DESTROYED)
endobjective
chr(SPAWNFLAG_00000200, 0x00, PAD_LIP_039F, BODY_A51AIRMAN, HEAD_RANDOM, 0x0401, -1, -1, 1000, 20, CHRFLAG0_CAN_THROW_GRENADES | CHRFLAG0_00008000 | CHRFLAG0_HOLD_POSITION | CHRFLAG0_COVER_TYPE2 | CHRFLAG0_CANLOSEGUN, 0, TEAM_ENEMY, SQUADRON_01, -1, 0, 0, 0, 0, 0)

View File

@ -104,14 +104,11 @@ u32 props[] = {
beginobjective(1, L_LUE_010, (DIFFBIT_SA | DIFFBIT_PA | DIFFBIT_PD)) // "Plant comms device on antenna"
complete_flags(STAGEFLAG_COMMSBUG_PLACED)
fail_flags(STAGEFLAG_COMMSBUG_MISPLACED)
fail_flags(STAGEFLAG_ANTENNA_DESTROYED)
fail_flags(STAGEFLAG_COMMSBUG_MISPLACED | STAGEFLAG_ANTENNA_DESTROYED)
endobjective
beginobjective(2, L_LUE_011, (DIFFBIT_PA | DIFFBIT_PD)) // "Disable all robot interceptors"
complete_flags(STAGEFLAG_INTERCEPTOR1_DESTROYED)
complete_flags(STAGEFLAG_INTERCEPTOR2_DESTROYED)
complete_flags(STAGEFLAG_INTERCEPTOR3_DESTROYED)
complete_flags(STAGEFLAG_INTERCEPTOR1_DESTROYED | STAGEFLAG_INTERCEPTOR2_DESTROYED | STAGEFLAG_INTERCEPTOR3_DESTROYED)
endobjective
beginobjective(3, L_LUE_012, (DIFFBIT_A | DIFFBIT_SA | DIFFBIT_PA | DIFFBIT_PD)) // "Gain access to hangar lift"

View File

@ -136,8 +136,7 @@ u32 props[] = {
beginobjective(4, L_PAM_009, (DIFFBIT_A | DIFFBIT_SA | DIFFBIT_PA | DIFFBIT_PD)) // "Escape from Cetan ship"
complete_flags(STAGEFLAG_ESCAPED)
fail_flags(STAGEFLAG_ALLY_DEAD)
fail_flags(STAGEFLAG_TIMER_EXPIRED)
fail_flags(STAGEFLAG_ALLY_DEAD | STAGEFLAG_TIMER_EXPIRED)
endobjective
chr(SPAWNFLAG_ANTINONINTERACTABLE, 0x40, PAD_PAM_01B3, BODY_DDSNIPER, HEAD_RANDOM, GAILIST_IDLE, -1, -1, 1000, 200, CHRFLAG0_SKIPSAFETYCHECKS, CHRFLAG1_AIVSAI_ADVANTAGED | CHRFLAG1_NOOP_00200000 | CHRFLAG1_IGNORECOVER | CHRFLAG1_PUNCHHARDER, TEAM_ALLY, SQUADRON_01, -1, 0, 0, 0, 0, 0)

View File

@ -122,10 +122,7 @@ u32 props[] = {
beginobjective(1, L_PETE_010, (DIFFBIT_PA | DIFFBIT_PD)) // "Attach tracer to limousine"
complete_flags(STAGEFLAG_TRACERBUG_PLACED)
fail_flags(STAGEFLAG_TRACERBUG_WASTED)
fail_flags(STAGEFLAG_LIMO_DESTROYED)
fail_flags(STAGEFLAG_LIMO_ESCAPED)
fail_flags(STAGEFLAG_TRACERBUG_SPOTTED)
fail_flags(STAGEFLAG_TRACERBUG_WASTED | STAGEFLAG_LIMO_DESTROYED | STAGEFLAG_LIMO_ESCAPED | STAGEFLAG_TRACERBUG_SPOTTED)
endobjective
beginobjective(2, L_PETE_011, (DIFFBIT_SA | DIFFBIT_PA | DIFFBIT_PD)) // "Prepare escape route"
@ -135,14 +132,12 @@ u32 props[] = {
beginobjective(3, L_PETE_013, (DIFFBIT_A | DIFFBIT_SA | DIFFBIT_PA | DIFFBIT_PD)) // "Create vehicular diversion"
complete_flags(STAGEFLAG_DIVERSION_CREATED)
fail_flags(STAGEFLAG_TAXI_DESTROYED)
fail_flags(STAGEFLAG_ROBOT_DESTROYED)
fail_flags(STAGEFLAG_TAXI_DESTROYED | STAGEFLAG_ROBOT_DESTROYED)
endobjective
beginobjective(4, L_PETE_014, (DIFFBIT_A | DIFFBIT_SA | DIFFBIT_PA | DIFFBIT_PD)) // "Gain entry to G5 building"
complete_flags(STAGEFLAG_IN_ELEVATOR)
fail_flags(STAGEFLAG_CIVILIAN_DEAD)
fail_flags(STAGEFLAG_ELEVATOR_SEALED)
fail_flags(STAGEFLAG_CIVILIAN_DEAD | STAGEFLAG_ELEVATOR_SEALED)
endobjective
chr(SPAWNFLAG_ANTINONINTERACTABLE | SPAWNFLAG_DONTSHOOTME | SPAWNFLAG_BLUESIGHT, 0x1a, PAD_PETE_00A9, BODY_CIAGUY, HEAD_RANDOM, AILIST_INIT_CIA1, -1, -1, 1000, 6, CHRFLAG0_FORCESAFETYCHECKS | CHRFLAG0_CANLOSEGUN, 0, TEAM_20, SQUADRON_00, -1, 0, 0, 0, 0, 0)

View File

@ -147,9 +147,7 @@ u32 props[] = {
beginobjective(2, L_RIT_007, (DIFFBIT_A | DIFFBIT_SA | DIFFBIT_PA | DIFFBIT_PD)) // "Get President to escape capsule"
complete_flags(STAGEFLAG_PRESIDENT_AT_POD)
fail_flags(STAGEFLAG_PRESIDENT_DEAD)
fail_flags(STAGEFLAG_KILLED_NEUTRALS)
fail_flags(STAGEFLAG_POD_DESTROYED)
fail_flags(STAGEFLAG_PRESIDENT_DEAD | STAGEFLAG_KILLED_NEUTRALS | STAGEFLAG_POD_DESTROYED)
endobjective
beginobjective(3, L_RIT_008, (DIFFBIT_PA | DIFFBIT_PD)) // "Secure Air Force One flight path"
@ -159,8 +157,7 @@ u32 props[] = {
beginobjective(4, L_RIT_009, (DIFFBIT_A | DIFFBIT_SA | DIFFBIT_PA | DIFFBIT_PD)) // "Detach UFO from Air Force One"
complete_flags(STAGEFLAG_UFO_ATTACHMENT_DAMAGED)
fail_flags(STAGEFLAG_BOTH_MINES_WASTED)
fail_flags(STAGEFLAG_PLANE_CRASHED)
fail_flags(STAGEFLAG_BOTH_MINES_WASTED | STAGEFLAG_PLANE_CRASHED)
endobjective
chr(SPAWNFLAG_ANTINONINTERACTABLE, 0x32, PAD_RIT_00BE, BODY_TRENT, HEAD_TRENT, GAILIST_IDLE, -1, -1, 200, 8, CHRFLAG0_00008000 | CHRFLAG0_AIVSAI | CHRFLAG0_NOHEAR, CHRFLAG1_PREWARNED | CHRFLAG1_PUNCHAIEXTRADAMAGE | CHRFLAG1_NOHANDCOMBAT | CHRFLAG1_AIVSAI_ADVANTAGED, TEAM_NONCOMBAT, SQUADRON_0F, -1, 0, 0, 0, 0, 0)

View File

@ -72,8 +72,7 @@ u32 props[] = {
beginobjective(2, L_SEV_006, (DIFFBIT_A | DIFFBIT_SA | DIFFBIT_PA | DIFFBIT_PD)) // "Activate distress signal"
complete_flags(STAGEFLAG_CONSOLE_ACTIVATED)
fail_flags(STAGEFLAG_CONSOLE_DESTROYED)
fail_flags(STAGEFLAG_TRAPPED_AT_START)
fail_flags(STAGEFLAG_CONSOLE_DESTROYED | STAGEFLAG_TRAPPED_AT_START)
endobjective
chr(SPAWNFLAG_FIXEDHEIGHT, CHR_LABTECH1, PAD_SEV_03DC, BODY_LABTECH, HEAD_RANDOM, AILIST_INIT_LABTECH, -1, -1, 1000, 100, CHRFLAG0_SURPRISABLE | CHRFLAG0_00008000 | CHRFLAG0_AIVSAI | CHRFLAG0_SQUADALERTANYDIST | CHRFLAG0_HOLD_POSITION | CHRFLAG0_COVER_TYPE2 | CHRFLAG0_CANLOSEGUN, CHRFLAG1_DOINGIDLEANIMATION | CHRFLAG1_CAN_DRAW_PISTOL, TEAM_ENEMY, SQUADRON_01, -1, 0, 0, 4, 0, 0)

View File

@ -124,9 +124,7 @@ u32 props[] = {
briefing(BRIEFINGTYPE_TEXT_A, L_SHO_003)
beginobjective(0, L_SHO_005, (DIFFBIT_A | DIFFBIT_SA | DIFFBIT_PA | DIFFBIT_PD)) // "Identify temple targets"
complete_flags(STAGEFLAG_PILLAR1_MARKED)
complete_flags(STAGEFLAG_PILLAR2_MARKED)
complete_flags(STAGEFLAG_PILLAR3_MARKED)
complete_flags(STAGEFLAG_PILLAR1_MARKED | STAGEFLAG_PILLAR2_MARKED | STAGEFLAG_PILLAR3_MARKED)
fail_flags(STAGEFLAG_BUG_WASTED)
endobjective
@ -143,11 +141,7 @@ u32 props[] = {
endobjective
beginobjective(4, L_SHO_009, (DIFFBIT_A | DIFFBIT_SA | DIFFBIT_PA | DIFFBIT_PD)) // "Assassinate Skedar leader"
complete_flags(STAGEFLAG_SPIKE1_DESTROYED)
complete_flags(STAGEFLAG_SPIKE2_DESTROYED)
complete_flags(STAGEFLAG_SPIKE3_DESTROYED)
complete_flags(STAGEFLAG_SPIKE4_DESTROYED)
complete_flags(STAGEFLAG_SPIKE5_DESTROYED)
complete_flags(STAGEFLAG_SPIKE1_DESTROYED | STAGEFLAG_SPIKE2_DESTROYED | STAGEFLAG_SPIKE3_DESTROYED | STAGEFLAG_SPIKE4_DESTROYED | STAGEFLAG_SPIKE5_DESTROYED)
fail_flags(STAGEFLAG_GRENADES_WASTED)
endobjective

View File

@ -117,8 +117,7 @@ u32 props[] = {
beginobjective(0, L_TRA_009, (DIFFBIT_PA | DIFFBIT_PD)) // "Locate alien tech medpack"
complete_flags(STAGEFLAG_COLLECTED_MEDPACK)
fail_flags(STAGEFLAG_00000200)
fail_flags(STAGEFLAG_MEDPACK_SWITCH_DESTROYED)
fail_flags(STAGEFLAG_00000200 | STAGEFLAG_MEDPACK_SWITCH_DESTROYED)
endobjective
beginobjective(1, L_TRA_010, (DIFFBIT_A | DIFFBIT_SA | DIFFBIT_PA | DIFFBIT_PD)) // "Rendezvous with CI spy"
@ -136,8 +135,7 @@ u32 props[] = {
beginobjective(4, L_TRA_013, (DIFFBIT_A | DIFFBIT_SA | DIFFBIT_PA | DIFFBIT_PD)) // "Escape from Area 51"
complete_flags(STAGEFLAG_ESCAPED)
fail_flags(STAGEFLAG_HANGAR_TERMINAL_DESTROYED)
fail_flags(STAGEFLAG_ELVIS_DEAD)
fail_flags(STAGEFLAG_HANGAR_TERMINAL_DESTROYED | STAGEFLAG_ELVIS_DEAD)
endobjective
chr(SPAWNFLAG_ANTINONINTERACTABLE, 0x23, PAD_TRA_03BE, BODY_BIOTECH, HEAD_DUNCAN2, GAILIST_IDLE, -1, -1, 1000, 100, CHRFLAG0_CAN_RETREAT | CHRFLAG0_SURPRISABLE | CHRFLAG0_FORCESAFETYCHECKS | CHRFLAG0_NOHEAR, 0, TEAM_ENEMY, SQUADRON_0E, -1, 0, 0, 0, 0, 0)

View File

@ -67,8 +67,7 @@ u32 props[] = {
beginobjective(0, L_WAX_005, (DIFFBIT_SA | DIFFBIT_PA | DIFFBIT_PD)) // "Plant explosive device in lab lift"
complete_flags(STAGEFLAG_BOMB_PLANTED)
fail_flags(STAGEFLAG_BOMB_EXPIRED)
fail_flags(STAGEFLAG_BOMB_UNPLANTABLE)
fail_flags(STAGEFLAG_BOMB_EXPIRED | STAGEFLAG_BOMB_UNPLANTABLE)
endobjective
beginobjective(1, L_WAX_006, (DIFFBIT_PA | DIFFBIT_PD)) // "Eliminate dataDyne Captain"

View File

@ -563,7 +563,8 @@ class App():
self.emit_bnez_label(params[3])
def ai_if_any_objective_failed(self, params):
self.emit('jal', ['aiIfAnyObjectiveFailed'])
self.emit('lui', ['$a0', '%hi(g_AnyObjectiveFailed)'])
self.emit('lw', ['$v0', '%lo(g_AnyObjectiveFailed)($a0)'])
self.emit_bnez_label(params[0])
def ai_if_calculated_safety2_lt(self, params):
@ -1665,15 +1666,8 @@ class App():
self.emit('jal', ['aiSetSquadron'])
def ai_set_stage_flag(self, params):
flag = self.u32(params, 0)
self.emit('lui', ['$a0', '%hi(g_StageFlags)'])
self.emit('lw', ['$v0', '%lo(g_StageFlags)($a0)'])
if flag & 0xffff0000:
self.emit('li', ['$v1', '0x%08x' % flag])
self.emit('or', ['$v0', '$v0', '$v1'])
else:
self.emit('ori', ['$v0', '$v0', '0x%04x' % flag])
self.emit('sw', ['$v0', '%lo(g_StageFlags)($a0)'])
self.emit('li', ['$a0', self.u32(params, 0)])
self.emit('jal', ['aiSetStageFlag'])
def ai_set_target_chr(self, params):
self.emit('li', ['$a0', '0x%02x' % params[0]])
@ -1997,11 +1991,8 @@ class App():
def ai_unset_stage_flag(self, params):
flag = self.u32(params, 0)
self.emit('lui', ['$a0', '%hi(g_StageFlags)'])
self.emit('lw', ['$v0', '%lo(g_StageFlags)($a0)'])
self.emit('li', ['$v1', '0x%08x' % (~flag & 0xffffffff)])
self.emit('and', ['$v0', '$v0', '$v1'])
self.emit('sw', ['$v0', '%lo(g_StageFlags)($a0)'])
self.emit('li', ['$a0', (~flag & 0xffffffff)])
self.emit('jal', ['aiUnsetStageFlag'])
def ai_walk_to_pad(self, params):
self.emit('li', ['$a0', '0x%04x' % self.u16(params, 0)])