mirror of
https://gitlab.com/ryandwyer/perfect-dark
synced 2026-06-01 17:57:10 -04:00
1833 lines
44 KiB
C
1833 lines
44 KiB
C
#include <ultra64.h>
|
|
#include "constants.h"
|
|
#include "game/cheats.h"
|
|
#include "game/game_006900.h"
|
|
#include "game/title.h"
|
|
#include "game/pdmode.h"
|
|
#include "game/objectives.h"
|
|
#include "game/bondgun.h"
|
|
#include "game/game_0b0fd0.h"
|
|
#include "game/player.h"
|
|
#include "game/savebuffer.h"
|
|
#include "game/menugfx.h"
|
|
#include "game/menu.h"
|
|
#include "game/mainmenu.h"
|
|
#include "game/filemgr.h"
|
|
#include "game/endscreen.h"
|
|
#include "game/stagetable.h"
|
|
#include "game/lv.h"
|
|
#include "game/mplayer/ingame.h"
|
|
#include "game/challenge.h"
|
|
#include "game/gamefile.h"
|
|
#include "game/lang.h"
|
|
#include "game/options.h"
|
|
#include "game/mpstats.h"
|
|
#include "bss.h"
|
|
#include "lib/vi.h"
|
|
#include "lib/main.h"
|
|
#include "data.h"
|
|
#include "types.h"
|
|
|
|
s32 endscreenHandleDeclineMission(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
if (operation == MENUOP_SET) {
|
|
menuPopDialog();
|
|
menuPopDialog();
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
s32 endscreenHandleRetryMission(s32 operation, struct menudialogdef *dialogdef, union handlerdata *data)
|
|
{
|
|
switch (operation) {
|
|
case MENUOP_TICK:
|
|
{
|
|
/**
|
|
* NTSC Final adds this check to make sure the given dialog is
|
|
* either the one being displayed or its sibling. This most likely
|
|
* fixes a bug - perhaps there is some way that this handler is run
|
|
* when the dialog is not on screen?
|
|
*/
|
|
#if VERSION >= VERSION_NTSC_FINAL
|
|
if (g_Menus[g_MpPlayerNum].curdialog) {
|
|
if (dialogdef == g_Menus[g_MpPlayerNum].curdialog->definition
|
|
|| (dialogdef->nextsibling && dialogdef->nextsibling == g_Menus[g_MpPlayerNum].curdialog->definition)) {
|
|
#endif
|
|
struct menuinputs *inputs = data->dialog2.inputs;
|
|
bool accept = false;
|
|
|
|
if (inputs->back) {
|
|
menuPopDialog();
|
|
menuPopDialog();
|
|
}
|
|
|
|
inputs->back = false;
|
|
|
|
if (inputs->start) {
|
|
accept = true;
|
|
}
|
|
|
|
inputs->start = false;
|
|
|
|
if (inputs->select
|
|
&& g_Menus[g_MpPlayerNum].curdialog
|
|
&& dialogdef->nextsibling
|
|
&& dialogdef->nextsibling == g_Menus[g_MpPlayerNum].curdialog->definition) {
|
|
accept = true;
|
|
inputs->select = false;
|
|
}
|
|
|
|
if (accept) {
|
|
union handlerdata data2;
|
|
menuhandlerAcceptMission(MENUOP_SET, &dialogdef->items[1], &data2);
|
|
}
|
|
#if VERSION >= VERSION_NTSC_FINAL
|
|
}
|
|
}
|
|
#endif
|
|
}
|
|
}
|
|
|
|
menudialog00103608(operation, dialogdef, data);
|
|
}
|
|
|
|
char *endscreenMenuTitleRetryMission(struct menudialogdef *dialogdef)
|
|
{
|
|
char *name;
|
|
char *prefix;
|
|
|
|
if (g_Menus[g_MpPlayerNum].curdialog->definition != dialogdef) {
|
|
return langGet(L_OPTIONS_300); // "Objectives"
|
|
}
|
|
|
|
prefix = langGet(L_OPTIONS_296); // "Retry"
|
|
name = langGet(g_StageNames[g_MissionConfig.stageindex].name3);
|
|
|
|
sprintf(g_StringPointer, "%s: %s\n", prefix, name);
|
|
|
|
return g_StringPointer;
|
|
}
|
|
|
|
char *endscreenMenuTitleNextMission(struct menudialogdef *dialogdef)
|
|
{
|
|
char *name;
|
|
char *prefix;
|
|
|
|
if (g_Menus[g_MpPlayerNum].curdialog->definition != dialogdef) {
|
|
return langGet(L_OPTIONS_300); // "Objectives"
|
|
}
|
|
|
|
prefix = langGet(L_OPTIONS_297); // "Next Mission"
|
|
name = langGet(g_StageNames[g_MissionConfig.stageindex].name3);
|
|
|
|
sprintf(g_StringPointer, "%s: %s\n", prefix, name);
|
|
|
|
return g_StringPointer;
|
|
}
|
|
|
|
s32 endscreenHandleReplayPreviousMission(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
if (operation == MENUOP_SET) {
|
|
g_MissionConfig.stageindex--;
|
|
g_MissionConfig.stagenum = g_StageNames[g_MissionConfig.stageindex].stagenum;
|
|
}
|
|
|
|
return menuhandlerAcceptMission(operation, NULL, data);
|
|
}
|
|
|
|
struct menuitem g_RetryMissionMenuItems[] = {
|
|
{
|
|
MENUITEMTYPE_OBJECTIVES,
|
|
1,
|
|
0,
|
|
0,
|
|
0,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
0,
|
|
L_OPTIONS_298, // "Accept"
|
|
0,
|
|
menuhandlerAcceptMission,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
0,
|
|
L_OPTIONS_299, // "Decline"
|
|
0,
|
|
endscreenHandleDeclineMission,
|
|
},
|
|
{ MENUITEMTYPE_END },
|
|
};
|
|
|
|
struct menudialogdef g_RetryMissionMenuDialog = {
|
|
MENUDIALOGTYPE_DEFAULT,
|
|
(u32)&endscreenMenuTitleRetryMission,
|
|
g_RetryMissionMenuItems,
|
|
endscreenHandleRetryMission,
|
|
MENUDIALOGFLAG_STARTSELECTS | MENUDIALOGFLAG_DISABLEITEMSCROLL,
|
|
&g_PreAndPostMissionBriefingMenuDialog,
|
|
};
|
|
|
|
struct menuitem g_NextMissionMenuItems[] = {
|
|
{
|
|
MENUITEMTYPE_OBJECTIVES,
|
|
1,
|
|
0,
|
|
0,
|
|
0,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
0,
|
|
L_OPTIONS_298, // "Accept"
|
|
0,
|
|
menuhandlerAcceptMission,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
0,
|
|
L_OPTIONS_299, // "Decline"
|
|
0,
|
|
endscreenHandleDeclineMission,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SEPARATOR,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
0,
|
|
L_MISC_470, // "Replay Previous Mission"
|
|
0,
|
|
endscreenHandleReplayPreviousMission,
|
|
},
|
|
{ MENUITEMTYPE_END },
|
|
};
|
|
|
|
struct menudialogdef g_NextMissionMenuDialog = {
|
|
MENUDIALOGTYPE_DEFAULT,
|
|
(u32)&endscreenMenuTitleNextMission,
|
|
g_NextMissionMenuItems,
|
|
endscreenHandleRetryMission,
|
|
MENUDIALOGFLAG_STARTSELECTS | MENUDIALOGFLAG_DISABLEITEMSCROLL,
|
|
&g_PreAndPostMissionBriefingMenuDialog,
|
|
};
|
|
|
|
char *endscreenMenuTextNumKills(struct menuitem *item)
|
|
{
|
|
sprintf(g_StringPointer, "%d", mpstatsGetPlayerKillCount());
|
|
return g_StringPointer;
|
|
}
|
|
|
|
char *endscreenMenuTextNumShots(struct menuitem *item)
|
|
{
|
|
sprintf(g_StringPointer, "%d", mpstatsGetPlayerShotCountByRegion(SHOTREGION_TOTAL));
|
|
return g_StringPointer;
|
|
}
|
|
|
|
char *endscreenMenuTextNumHeadShots(struct menuitem *item)
|
|
{
|
|
sprintf(g_StringPointer, "%d", mpstatsGetPlayerShotCountByRegion(SHOTREGION_HEAD));
|
|
return g_StringPointer;
|
|
}
|
|
|
|
char *endscreenMenuTextNumBodyShots(struct menuitem *item)
|
|
{
|
|
sprintf(g_StringPointer, "%d", mpstatsGetPlayerShotCountByRegion(SHOTREGION_BODY));
|
|
return g_StringPointer;
|
|
}
|
|
|
|
char *endscreenMenuTextNumLimbShots(struct menuitem *item)
|
|
{
|
|
sprintf(g_StringPointer, "%d", mpstatsGetPlayerShotCountByRegion(SHOTREGION_LIMB));
|
|
return g_StringPointer;
|
|
}
|
|
|
|
char *endscreenMenuTextNumOtherShots(struct menuitem *item)
|
|
{
|
|
u32 total = mpstatsGetPlayerShotCountByRegion(SHOTREGION_GUN) + mpstatsGetPlayerShotCountByRegion(SHOTREGION_HAT);
|
|
sprintf(g_StringPointer, "%d", total);
|
|
return g_StringPointer;
|
|
}
|
|
|
|
char *endscreenMenuTextAccuracy(struct menuitem *item)
|
|
{
|
|
s32 total = mpstatsGetPlayerShotCountByRegion(SHOTREGION_TOTAL);
|
|
s32 numhead = mpstatsGetPlayerShotCountByRegion(SHOTREGION_HEAD);
|
|
s32 numbody = mpstatsGetPlayerShotCountByRegion(SHOTREGION_BODY);
|
|
s32 numlimb = mpstatsGetPlayerShotCountByRegion(SHOTREGION_LIMB);
|
|
s32 numgun = mpstatsGetPlayerShotCountByRegion(SHOTREGION_GUN);
|
|
s32 numhat = mpstatsGetPlayerShotCountByRegion(SHOTREGION_HAT);
|
|
s32 numobject = mpstatsGetPlayerShotCountByRegion(SHOTREGION_OBJECT);
|
|
f32 accuracy;
|
|
|
|
if (total > 0) {
|
|
s32 hits = numhead + numbody + numlimb + numgun + numhat + numobject;
|
|
accuracy = hits * 100.0f / total;
|
|
} else {
|
|
accuracy = 0;
|
|
}
|
|
|
|
if (accuracy > 100.0f) {
|
|
accuracy = 100.0f;
|
|
}
|
|
|
|
sprintf(g_StringPointer, "%s%s%.1f%%", "", "", accuracy);
|
|
return g_StringPointer;
|
|
}
|
|
|
|
char *endscreenMenuTextMissionStatus(struct menuitem *item)
|
|
{
|
|
if (g_CheatsActiveBank0 || g_CheatsActiveBank1) {
|
|
return langGet(L_MPWEAPONS_135); // "Cheated"
|
|
}
|
|
|
|
if (g_Vars.coopplayernum >= 0) {
|
|
if (g_Vars.bond->aborted || g_Vars.coop->aborted) {
|
|
return langGet(L_OPTIONS_295); // "Aborted"
|
|
}
|
|
|
|
if (g_Vars.bond->isdead && g_Vars.coop->isdead) {
|
|
return langGet(L_OPTIONS_293); // "Failed"
|
|
}
|
|
} else if (g_Vars.antiplayernum >= 0) {
|
|
if (g_Vars.currentplayer == g_Vars.bond) {
|
|
if (g_Vars.bond->aborted) {
|
|
return langGet(L_OPTIONS_295); // "Aborted"
|
|
}
|
|
|
|
if (g_Vars.anti->aborted) {
|
|
return langGet(L_OPTIONS_295); // "Aborted"
|
|
}
|
|
|
|
if (g_Vars.bond->isdead) {
|
|
return langGet(L_OPTIONS_293); // "Failed"
|
|
}
|
|
} else {
|
|
if (g_Vars.anti->aborted) {
|
|
return langGet(L_OPTIONS_295); // "Aborted"
|
|
}
|
|
|
|
if (!g_Vars.bond->aborted && !g_Vars.bond->isdead) {
|
|
return langGet(L_OPTIONS_293); // "Failed"
|
|
}
|
|
}
|
|
} else {
|
|
if (g_Vars.bond->aborted) {
|
|
return langGet(L_OPTIONS_295); // "Aborted"
|
|
}
|
|
|
|
if (g_Vars.bond->isdead) {
|
|
return langGet(L_OPTIONS_293); // "Failed"
|
|
}
|
|
}
|
|
|
|
if (objectiveIsAllComplete() == false) {
|
|
return langGet(L_OPTIONS_293); // "Failed"
|
|
}
|
|
|
|
if (g_StageIndex == STAGEINDEX_DEFENSE) {
|
|
return langGet(L_MPWEAPONS_062); // "Unknown"
|
|
}
|
|
|
|
return langGet(L_OPTIONS_294); // "Completed"
|
|
}
|
|
|
|
char *endscreenMenuTextAgentStatus(struct menuitem *item)
|
|
{
|
|
if (g_CheatsActiveBank0 || g_CheatsActiveBank1) {
|
|
return langGet(L_MPWEAPONS_134); // "Dishonored"
|
|
}
|
|
|
|
if (g_Vars.currentplayer->aborted) {
|
|
return langGet(L_OPTIONS_292); // "Disavowed"
|
|
}
|
|
|
|
if (g_Vars.currentplayer->isdead) {
|
|
return langGet(L_OPTIONS_290); // "Deceased"
|
|
}
|
|
|
|
if (g_StageIndex == STAGEINDEX_DEFENSE) {
|
|
return langGet(L_MPWEAPONS_063); // "Missing"
|
|
}
|
|
|
|
return langGet(L_OPTIONS_291); // "Active"
|
|
}
|
|
|
|
char *endscreenMenuTitleStageCompleted(struct menuitem *item)
|
|
{
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
sprintf(g_StringPointer, "%s: %s\n",
|
|
langGet(g_StageNames[g_Menus[g_MpPlayerNum].endscreen.stageindex].name3),
|
|
langGet(L_OPTIONS_276)); // "Completed"
|
|
#else
|
|
sprintf(g_StringPointer, "%s: %s\n",
|
|
langGet(g_StageNames[g_MissionConfig.stageindex].name3),
|
|
langGet(L_OPTIONS_276)); // "Completed"
|
|
#endif
|
|
|
|
return g_StringPointer;
|
|
}
|
|
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
char *endscreenMenuTextCurrentStageName3(struct menuitem *item)
|
|
{
|
|
char *name = langGet(g_StageNames[g_MissionConfig.stageindex].name3);
|
|
sprintf(g_StringPointer, "%s\n", name);
|
|
|
|
return g_StringPointer;
|
|
}
|
|
#endif
|
|
|
|
char *endscreenMenuTitleStageFailed(struct menuitem *item)
|
|
{
|
|
sprintf(g_StringPointer, "%s: %s\n",
|
|
langGet(g_StageNames[g_MissionConfig.stageindex].name3),
|
|
langGet(L_OPTIONS_277)); // "Failed"
|
|
|
|
return g_StringPointer;
|
|
}
|
|
|
|
char *endscreenMenuTextMissionTime(struct menuitem *item)
|
|
{
|
|
formatTime(g_StringPointer, playerGetMissionTime(), TIMEPRECISION_SECONDS);
|
|
strcat(g_StringPointer, "\n");
|
|
|
|
return g_StringPointer;
|
|
}
|
|
|
|
struct menudialogdef *endscreenAdvance(void)
|
|
{
|
|
#if VERSION < VERSION_NTSC_1_0
|
|
if (g_MissionConfig.stagenum == STAGE_SKEDARRUINS) {
|
|
g_MissionConfig.stagenum = STAGE_CREDITS;
|
|
titleSetNextStage(g_MissionConfig.stagenum);
|
|
lvSetDifficulty(g_MissionConfig.difficulty);
|
|
titleSetNextMode(TITLEMODE_SKIP);
|
|
mainChangeToStage(g_MissionConfig.stagenum);
|
|
|
|
return NULL;
|
|
}
|
|
#endif
|
|
|
|
g_MissionConfig.stageindex++;
|
|
g_MissionConfig.stagenum = g_StageNames[g_MissionConfig.stageindex].stagenum;
|
|
|
|
return &g_NextMissionMenuDialog;
|
|
}
|
|
|
|
void endscreen0f10d770(void)
|
|
{
|
|
func0f0f8bb4(&g_Menus[0].unk840, bgunCalculateGunMemCapacity() - menugfxGetParticleArraySize(), 0);
|
|
g_Menus[0].unk840.unk004 = bgunGetGunMem() + menugfxGetParticleArraySize();
|
|
|
|
func0f0f8bb4(&g_Menus[1].unk840, bgunCalculateGunMemCapacity() - menugfxGetParticleArraySize(), 0);
|
|
g_Menus[1].unk840.unk004 = bgunGetGunMem() + menugfxGetParticleArraySize();
|
|
|
|
func0f0f8bb4(&g_Menus[2].unk840, bgunCalculateGunMemCapacity() - menugfxGetParticleArraySize(), 0);
|
|
g_Menus[2].unk840.unk004 = bgunGetGunMem() + menugfxGetParticleArraySize();
|
|
|
|
func0f0f8bb4(&g_Menus[3].unk840, bgunCalculateGunMemCapacity() - menugfxGetParticleArraySize(), 0);
|
|
g_Menus[3].unk840.unk004 = bgunGetGunMem() + menugfxGetParticleArraySize();
|
|
}
|
|
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
s32 endscreenHandleReplayLastLevel(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
if (operation == MENUOP_SET) {
|
|
g_MissionConfig.stagenum = g_StageNames[g_MissionConfig.stageindex].stagenum;
|
|
return menuhandlerAcceptMission(operation, NULL, data);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
#endif
|
|
|
|
struct menuitem g_2PMissionEndscreenObjectivesVMenuItems[] = {
|
|
{
|
|
MENUITEMTYPE_OBJECTIVES,
|
|
2,
|
|
0,
|
|
0,
|
|
0,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SEPARATOR,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
MENUITEMFLAG_SELECTABLE_CENTRE,
|
|
L_OPTIONS_301, // "Press START"
|
|
0,
|
|
NULL,
|
|
},
|
|
{ MENUITEMTYPE_END },
|
|
};
|
|
|
|
struct menuitem g_SoloEndscreenObjectivesMenuItems[] = {
|
|
{
|
|
MENUITEMTYPE_OBJECTIVES,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SEPARATOR,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
MENUITEMFLAG_SELECTABLE_CENTRE,
|
|
L_OPTIONS_301, // "Press START"
|
|
0,
|
|
NULL,
|
|
},
|
|
{ MENUITEMTYPE_END },
|
|
};
|
|
|
|
struct menudialogdef g_SoloEndscreenObjectivesFailedMenuDialog = {
|
|
MENUDIALOGTYPE_DANGER,
|
|
L_OPTIONS_300, // "Objectives"
|
|
g_SoloEndscreenObjectivesMenuItems,
|
|
soloMenuDialogPauseStatus,
|
|
MENUDIALOGFLAG_DISABLEITEMSCROLL | MENUDIALOGFLAG_SMOOTHSCROLLABLE,
|
|
NULL,
|
|
};
|
|
|
|
struct menudialogdef g_SoloEndscreenObjectivesCompletedMenuDialog = {
|
|
MENUDIALOGTYPE_SUCCESS,
|
|
L_OPTIONS_300, // "Objectives"
|
|
g_SoloEndscreenObjectivesMenuItems,
|
|
soloMenuDialogPauseStatus,
|
|
MENUDIALOGFLAG_DISABLEITEMSCROLL | MENUDIALOGFLAG_SMOOTHSCROLLABLE,
|
|
NULL,
|
|
};
|
|
|
|
struct menudialogdef g_2PMissionEndscreenObjectivesFailedVMenuDialog = {
|
|
MENUDIALOGTYPE_DANGER,
|
|
L_OPTIONS_300, // "Objectives"
|
|
g_2PMissionEndscreenObjectivesVMenuItems,
|
|
soloMenuDialogPauseStatus,
|
|
MENUDIALOGFLAG_DISABLEITEMSCROLL | MENUDIALOGFLAG_SMOOTHSCROLLABLE,
|
|
NULL,
|
|
};
|
|
|
|
struct menudialogdef g_2PMissionEndscreenObjectivesCompletedVMenuDialog = {
|
|
MENUDIALOGTYPE_SUCCESS,
|
|
L_OPTIONS_300, // "Objectives"
|
|
g_2PMissionEndscreenObjectivesVMenuItems,
|
|
soloMenuDialogPauseStatus,
|
|
MENUDIALOGFLAG_DISABLEITEMSCROLL | MENUDIALOGFLAG_SMOOTHSCROLLABLE,
|
|
NULL,
|
|
};
|
|
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
/**
|
|
* Displayed after Defense and Skedar Ruins completion screens.
|
|
*/
|
|
s32 endscreenHandleContinueMission(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
if (operation == MENUOP_SET) {
|
|
endscreenContinue(2);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
#endif
|
|
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
struct menuitem g_MissionContinueOrReplyMenuItems[] = {
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
MENUITEMFLAG_SELECTABLE_CENTRE,
|
|
L_MPWEAPONS_244, // "Continue"
|
|
0,
|
|
endscreenHandleContinueMission,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
MENUITEMFLAG_SELECTABLE_CENTRE,
|
|
L_MPWEAPONS_245, // "Replay Last Level"
|
|
0,
|
|
endscreenHandleReplayLastLevel,
|
|
},
|
|
{ MENUITEMTYPE_END },
|
|
};
|
|
|
|
struct menudialogdef g_MissionContinueOrReplyMenuDialog = {
|
|
MENUDIALOGTYPE_DEFAULT,
|
|
(u32)&endscreenMenuTextCurrentStageName3,
|
|
g_MissionContinueOrReplyMenuItems,
|
|
NULL,
|
|
MENUDIALOGFLAG_STARTSELECTS,
|
|
NULL,
|
|
};
|
|
#endif
|
|
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
/**
|
|
* Context is:
|
|
*
|
|
* 0 when closing a completed endscreen
|
|
* 1 unsure - is invoked directly by menuTick
|
|
* 2 when pressing continue
|
|
*/
|
|
void endscreenContinue(s32 context)
|
|
{
|
|
if (g_Vars.antiplayernum >= 0) {
|
|
menuPopDialog();
|
|
} else if (g_Vars.coopplayernum >= 0 && PLAYERCOUNT() >= 2 && context == 0) {
|
|
menuPopDialog();
|
|
} else {
|
|
if (g_Vars.stagenum == STAGE_DEEPSEA || g_Vars.stagenum == STAGE_SKEDARRUINS) {
|
|
if (context == 2 || g_Menus[g_MpPlayerNum].endscreen.isfirstcompletion) {
|
|
// Pressed continue
|
|
if (g_Vars.stagenum == STAGE_DEEPSEA) {
|
|
if (!isStageDifficultyUnlocked(g_MissionConfig.stageindex + 1, g_MissionConfig.difficulty)) {
|
|
menuPopDialog();
|
|
menuPopDialog();
|
|
} else {
|
|
// Commit to starting next stage
|
|
g_MissionConfig.stageindex++;
|
|
g_MissionConfig.stagenum = g_StageNames[g_MissionConfig.stageindex].stagenum;
|
|
|
|
titleSetNextStage(g_MissionConfig.stagenum);
|
|
|
|
if (g_MissionConfig.iscoop) {
|
|
if (g_Vars.numaibuddies == 0) {
|
|
g_Vars.bondplayernum = 0;
|
|
g_Vars.coopplayernum = 1;
|
|
g_Vars.antiplayernum = -1;
|
|
setNumPlayers(2);
|
|
} else {
|
|
g_Vars.bondplayernum = 0;
|
|
g_Vars.coopplayernum = -1;
|
|
g_Vars.antiplayernum = -1;
|
|
setNumPlayers(1);
|
|
}
|
|
} else {
|
|
g_Vars.bondplayernum = 0;
|
|
g_Vars.coopplayernum = -1;
|
|
g_Vars.antiplayernum = -1;
|
|
setNumPlayers(1);
|
|
}
|
|
|
|
lvSetDifficulty(g_MissionConfig.difficulty);
|
|
titleSetNextMode(TITLEMODE_SKIP);
|
|
mainChangeToStage(g_MissionConfig.stagenum);
|
|
viBlack(true);
|
|
}
|
|
} else if (g_Vars.stagenum == STAGE_SKEDARRUINS) {
|
|
// Commit to starting credits
|
|
g_MissionConfig.stagenum = STAGE_CREDITS;
|
|
titleSetNextStage(g_MissionConfig.stagenum);
|
|
lvSetDifficulty(g_MissionConfig.difficulty);
|
|
titleSetNextMode(TITLEMODE_SKIP);
|
|
mainChangeToStage(g_MissionConfig.stagenum);
|
|
viBlack(true);
|
|
}
|
|
} else {
|
|
if (context == 1) {
|
|
menuPushRootDialog(&g_MissionContinueOrReplyMenuDialog, MENUROOT_COOPCONTINUE);
|
|
} else {
|
|
menuPushDialog(&g_MissionContinueOrReplyMenuDialog);
|
|
}
|
|
}
|
|
} else {
|
|
if (context == 2) {
|
|
menuPopDialog();
|
|
}
|
|
|
|
if (isStageDifficultyUnlocked(g_MissionConfig.stageindex + 1, g_MissionConfig.difficulty) == 0) {
|
|
if (context == 2) {
|
|
menuPopDialog();
|
|
menuPopDialog();
|
|
} else {
|
|
menuPushDialog(&g_MissionContinueOrReplyMenuDialog);
|
|
}
|
|
} else if (stageGetIndex(g_MissionConfig.stagenum) < 0
|
|
|| g_Vars.stagenum == STAGE_CITRAINING
|
|
|| g_MissionConfig.stageindex >= SOLOSTAGEINDEX_MBR) {
|
|
if (context == 2) {
|
|
menuPopDialog();
|
|
menuPopDialog();
|
|
} else {
|
|
menuPushDialog(&g_MissionContinueOrReplyMenuDialog);
|
|
}
|
|
} else {
|
|
endscreen0f10d770();
|
|
|
|
if (context == 1) {
|
|
menuPushRootDialog(endscreenAdvance(), MENUROOT_COOPCONTINUE);
|
|
} else {
|
|
menuPushDialog(endscreenAdvance());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
|
|
s32 endscreenHandle2PCompleted(s32 operation, struct menudialogdef *dialogdef, union handlerdata *data)
|
|
{
|
|
if (operation == MENUOP_OPEN) {
|
|
g_Menus[g_MpPlayerNum].endscreen.unke1c = 0;
|
|
}
|
|
|
|
if (operation == MENUOP_TICK) {
|
|
if (g_Menus[g_MpPlayerNum].curdialog) {
|
|
if (g_Menus[g_MpPlayerNum].curdialog->definition == dialogdef
|
|
|| (dialogdef->nextsibling && dialogdef->nextsibling == g_Menus[g_MpPlayerNum].curdialog->definition)) {
|
|
struct menuinputs *inputs = data->dialog2.inputs;
|
|
|
|
if (inputs->select || inputs->back || inputs->start) {
|
|
g_Menus[g_MpPlayerNum].endscreen.unke1c = VERSION >= VERSION_NTSC_1_0 ? 6 : 3;
|
|
}
|
|
|
|
if (g_Menus[g_MpPlayerNum].endscreen.unke1c) {
|
|
if (var8009dfc0) {
|
|
g_Menus[g_MpPlayerNum].endscreen.unke1c--;
|
|
}
|
|
|
|
if (g_Menus[g_MpPlayerNum].endscreen.unke1c == 0) {
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
endscreenContinue(0);
|
|
#else
|
|
if (g_Vars.stagenum == STAGE_DEEPSEA) {
|
|
if (g_Vars.antiplayernum >= 0 || (g_Vars.coopplayernum >= 0 && PLAYERCOUNT() >= 2)) {
|
|
menuPopDialog();
|
|
} else {
|
|
g_MissionConfig.stageindex++;
|
|
g_MissionConfig.stagenum = g_StageNames[g_MissionConfig.stageindex].stagenum;
|
|
|
|
titleSetNextStage(g_MissionConfig.stagenum);
|
|
lvSetDifficulty(g_MissionConfig.difficulty);
|
|
titleSetNextMode(TITLEMODE_SKIP);
|
|
mainChangeToStage(g_MissionConfig.stagenum);
|
|
}
|
|
} else if (g_Vars.antiplayernum >= 0
|
|
|| (g_Vars.coopplayernum >= 0 && PLAYERCOUNT() >= 2)
|
|
|| (stageGetIndex(g_MissionConfig.stagenum) < 0
|
|
|| g_Vars.stagenum == STAGE_CITRAINING
|
|
|| g_MissionConfig.stageindex > SOLOSTAGEINDEX_SKEDARRUINS
|
|
|| ((g_CheatsActiveBank0 || g_CheatsActiveBank1)
|
|
&& !isStageDifficultyUnlocked(g_MissionConfig.stageindex + 1, g_MissionConfig.difficulty)))) {
|
|
menuPopDialog();
|
|
} else {
|
|
endscreen0f10d770();
|
|
menuPushDialog(endscreenAdvance());
|
|
}
|
|
#endif
|
|
}
|
|
}
|
|
|
|
inputs->select = inputs->back = inputs->start = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
s32 endscreenHandle2PFailed(s32 operation, struct menudialogdef *dialogdef, union handlerdata *data)
|
|
{
|
|
if (operation == MENUOP_OPEN) {
|
|
g_Menus[g_MpPlayerNum].endscreen.unke1c = 0;
|
|
}
|
|
|
|
if (operation == MENUOP_TICK) {
|
|
if (g_Menus[g_MpPlayerNum].curdialog) {
|
|
if (g_Menus[g_MpPlayerNum].curdialog->definition == dialogdef
|
|
|| (dialogdef->nextsibling && dialogdef->nextsibling == g_Menus[g_MpPlayerNum].curdialog->definition)) {
|
|
struct menuinputs *inputs = data->dialog2.inputs;
|
|
|
|
if (inputs->select || inputs->back || inputs->start) {
|
|
g_Menus[g_MpPlayerNum].endscreen.unke1c = VERSION >= VERSION_NTSC_1_0 ? 6 : 3;
|
|
}
|
|
|
|
if (g_Menus[g_MpPlayerNum].endscreen.unke1c) {
|
|
if (var8009dfc0) {
|
|
g_Menus[g_MpPlayerNum].endscreen.unke1c--;
|
|
}
|
|
|
|
if (g_Menus[g_MpPlayerNum].endscreen.unke1c == 0) {
|
|
if (g_Vars.antiplayernum >= 0
|
|
|| (g_Vars.coopplayernum >= 0 && PLAYERCOUNT() >= 2)
|
|
|| stageGetIndex(g_MissionConfig.stagenum) < 0
|
|
|| g_Vars.stagenum == STAGE_CITRAINING) {
|
|
menuPopDialog();
|
|
} else {
|
|
endscreen0f10d770();
|
|
menuPushDialog(&g_RetryMissionMenuDialog);
|
|
}
|
|
}
|
|
}
|
|
|
|
inputs->select = inputs->back = inputs->start = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
struct menuitem g_2PMissionEndscreenVMenuItems[] = {
|
|
{
|
|
MENUITEMTYPE_LABEL,
|
|
0,
|
|
MENUITEMFLAG_LESSLEFTPADDING | MENUITEMFLAG_SMALLFONT,
|
|
L_OPTIONS_278, // "Mission Status:"
|
|
0,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_LABEL,
|
|
0,
|
|
MENUITEMFLAG_SELECTABLE_CENTRE,
|
|
(u32)&endscreenMenuTextMissionStatus,
|
|
0,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_LABEL,
|
|
0,
|
|
MENUITEMFLAG_LESSLEFTPADDING | MENUITEMFLAG_SMALLFONT,
|
|
L_OPTIONS_279, // "Agent Status:"
|
|
0,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_LABEL,
|
|
0,
|
|
MENUITEMFLAG_SELECTABLE_CENTRE,
|
|
(u32)&endscreenMenuTextAgentStatus,
|
|
0,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_LABEL,
|
|
0,
|
|
MENUITEMFLAG_LESSLEFTPADDING | MENUITEMFLAG_SMALLFONT,
|
|
L_OPTIONS_280, // "Mission Time:"
|
|
0,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_LABEL,
|
|
0,
|
|
MENUITEMFLAG_SELECTABLE_CENTRE,
|
|
(u32)&endscreenMenuTextMissionTime,
|
|
0,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_LABEL,
|
|
0,
|
|
MENUITEMFLAG_LESSLEFTPADDING | MENUITEMFLAG_SMALLFONT,
|
|
L_MPWEAPONS_129, // "Difficulty:"
|
|
0,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_LABEL,
|
|
0,
|
|
MENUITEMFLAG_SELECTABLE_CENTRE,
|
|
(u32)soloMenuTextDifficulty,
|
|
0,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SEPARATOR,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_LABEL,
|
|
0,
|
|
MENUITEMFLAG_LESSLEFTPADDING | MENUITEMFLAG_SMALLFONT,
|
|
L_OPTIONS_281, // "Weapon of Choice:"
|
|
0,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_LABEL,
|
|
0,
|
|
MENUITEMFLAG_SELECTABLE_CENTRE,
|
|
(u32)&mpMenuTextWeaponOfChoiceName,
|
|
0,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SEPARATOR,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_LABEL,
|
|
0,
|
|
0,
|
|
L_OPTIONS_282, // "Kills:"
|
|
(u32)&endscreenMenuTextNumKills,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_LABEL,
|
|
0,
|
|
0,
|
|
L_OPTIONS_283, // "Accuracy:"
|
|
(u32)&endscreenMenuTextAccuracy,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SEPARATOR,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_LABEL,
|
|
0,
|
|
0,
|
|
L_OPTIONS_284, // "Shot Total:"
|
|
(u32)&endscreenMenuTextNumShots,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_LABEL,
|
|
0,
|
|
MENUITEMFLAG_SMALLFONT,
|
|
L_OPTIONS_285, // "Head Shots:"
|
|
(u32)&endscreenMenuTextNumHeadShots,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_LABEL,
|
|
0,
|
|
MENUITEMFLAG_SMALLFONT,
|
|
L_OPTIONS_286, // "Body Shots:"
|
|
(u32)&endscreenMenuTextNumBodyShots,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_LABEL,
|
|
0,
|
|
MENUITEMFLAG_SMALLFONT,
|
|
L_OPTIONS_287, // "Limb Shots:"
|
|
(u32)&endscreenMenuTextNumLimbShots,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_LABEL,
|
|
0,
|
|
MENUITEMFLAG_SMALLFONT,
|
|
L_OPTIONS_288, // "Others:"
|
|
(u32)&endscreenMenuTextNumOtherShots,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SEPARATOR,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
MENUITEMFLAG_SELECTABLE_CENTRE,
|
|
L_OPTIONS_289, // "Press START"
|
|
0,
|
|
NULL,
|
|
},
|
|
{ MENUITEMTYPE_END },
|
|
};
|
|
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
/**
|
|
* This function is re-used for several values on the endscreen.
|
|
* item->param is used to determine which value it is. Values are:
|
|
*
|
|
* 0 = mission time
|
|
* 1 = target time
|
|
* 2 = separator and new cheat available
|
|
* 3 = completion cheat name
|
|
* 4 = others (shots)
|
|
* 5 = timed cheat name
|
|
* 6 = limb shots
|
|
*/
|
|
s32 endscreenHandleCheatInfo(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
static u32 cheatcolour = 0xff7f7fff;
|
|
|
|
if (operation == MENUOP_GETCOLOUR
|
|
&& ((g_Menus[g_MpPlayerNum].endscreen.cheatinfo & 0x200) || item->param == 5)) {
|
|
// Timed cheat just got unlocked, and this item is the timed cheat name
|
|
u32 weight = menuGetSinOscFrac(40) * 255;
|
|
|
|
mainOverrideVariable("ctcol", &cheatcolour);
|
|
|
|
if (item->param == 0
|
|
&& cheatGetTime(g_Menus[g_MpPlayerNum].endscreen.cheatinfo & 0xff) == 0) {
|
|
return 0;
|
|
}
|
|
|
|
data->label.colour2 = colourBlend(data->label.colour2, cheatcolour, weight);
|
|
|
|
if (item->param == 3) { // completion cheat name
|
|
data->label.colour1 = colourBlend(data->label.colour1, cheatcolour, weight);
|
|
}
|
|
|
|
if (item->param == 5) { // timed cheat name
|
|
data->label.colour1 = colourBlend(data->label.colour1, cheatcolour, weight);
|
|
}
|
|
}
|
|
|
|
if (operation == MENUOP_CHECKHIDDEN) {
|
|
if (item->param == 1) { // target time
|
|
u32 info = g_Menus[g_MpPlayerNum].endscreen.cheatinfo;
|
|
|
|
if (info & 0x800) { // completion cheat just got unlocked
|
|
return true;
|
|
}
|
|
|
|
// (has timed cheat)
|
|
// and (timed cheat just got unlocked or timed cheat already unlocked) == 0
|
|
// and cheat has a target time configured
|
|
if ((info & 0x100) && (info & 0x600) == 0 && cheatGetTime(info & 0xff) > 0) {
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
} else if (item->param == 2 && (g_Menus[g_MpPlayerNum].endscreen.cheatinfo & 0xa00) == 0) {
|
|
// new cheat available
|
|
return true;
|
|
} else if (item->param == 3 && (g_Menus[g_MpPlayerNum].endscreen.cheatinfo & 0x200) == 0) {
|
|
// completion cheat name
|
|
return true;
|
|
} else if (item->param == 4 && (g_Menus[g_MpPlayerNum].endscreen.cheatinfo & 0xa00)) {
|
|
// others (shots)
|
|
return true;
|
|
} else if (item->param == 6 && (g_Menus[g_MpPlayerNum].endscreen.cheatinfo & 0xa00) == 0xa00) {
|
|
// limb shots
|
|
return true;
|
|
} else if (item->param == 5 && (g_Menus[g_MpPlayerNum].endscreen.cheatinfo & 0x800) == 0) {
|
|
// timed cheat name
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
#endif
|
|
|
|
struct menuitem g_MissionEndscreenMenuItems[] = {
|
|
{
|
|
MENUITEMTYPE_LABEL,
|
|
0,
|
|
0,
|
|
L_OPTIONS_278, // "Mission Status:"
|
|
(u32)&endscreenMenuTextMissionStatus,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_LABEL,
|
|
0,
|
|
0,
|
|
L_OPTIONS_279, // "Agent Status:"
|
|
(u32)&endscreenMenuTextAgentStatus,
|
|
NULL,
|
|
},
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
{
|
|
MENUITEMTYPE_LABEL,
|
|
0,
|
|
MENUITEMFLAG_LABEL_CUSTOMCOLOUR,
|
|
L_OPTIONS_280, // "Mission Time:"
|
|
(u32)&endscreenMenuTextMissionTime,
|
|
endscreenHandleCheatInfo,
|
|
},
|
|
{
|
|
MENUITEMTYPE_LABEL,
|
|
1,
|
|
MENUITEMFLAG_LABEL_CUSTOMCOLOUR,
|
|
L_MPWEAPONS_242, // "Target Time:"
|
|
(u32)&endscreenMenuTextTargetTime,
|
|
endscreenHandleCheatInfo,
|
|
},
|
|
{
|
|
MENUITEMTYPE_LABEL,
|
|
0,
|
|
0,
|
|
L_MPWEAPONS_129, // "Difficulty:"
|
|
(u32)&soloMenuTextDifficulty,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SEPARATOR,
|
|
2,
|
|
0,
|
|
0,
|
|
0,
|
|
endscreenHandleCheatInfo,
|
|
},
|
|
{
|
|
MENUITEMTYPE_LABEL,
|
|
2,
|
|
0,
|
|
L_MPWEAPONS_243, // "New Cheat Available!:"
|
|
0,
|
|
endscreenHandleCheatInfo,
|
|
},
|
|
{
|
|
MENUITEMTYPE_LABEL,
|
|
3,
|
|
MENUITEMFLAG_SELECTABLE_CENTRE | MENUITEMFLAG_LABEL_CUSTOMCOLOUR,
|
|
(u32)&endscreenMenuTextTimedCheatName,
|
|
0,
|
|
endscreenHandleCheatInfo,
|
|
},
|
|
{
|
|
MENUITEMTYPE_LABEL,
|
|
5,
|
|
MENUITEMFLAG_SELECTABLE_CENTRE | MENUITEMFLAG_LABEL_CUSTOMCOLOUR,
|
|
(u32)&endscreenMenuTextCompletionCheatName,
|
|
0,
|
|
endscreenHandleCheatInfo,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SEPARATOR,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_LABEL,
|
|
0,
|
|
0,
|
|
L_OPTIONS_281, // "Weapon of Choice:"
|
|
(u32)&mpMenuTextWeaponOfChoiceName,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_LABEL,
|
|
0,
|
|
0,
|
|
L_OPTIONS_282, // "Kills:"
|
|
(u32)&endscreenMenuTextNumKills,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_LABEL,
|
|
0,
|
|
0,
|
|
L_OPTIONS_283, // "Accuracy:"
|
|
(u32)&endscreenMenuTextAccuracy,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SEPARATOR,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_LABEL,
|
|
0,
|
|
0,
|
|
L_OPTIONS_284, // "Shot Total:"
|
|
(u32)&endscreenMenuTextNumShots,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_LABEL,
|
|
0,
|
|
0,
|
|
L_OPTIONS_285, // "Head Shots:"
|
|
(u32)&endscreenMenuTextNumHeadShots,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_LABEL,
|
|
0,
|
|
0,
|
|
L_OPTIONS_286, // "Body Shots:"
|
|
(u32)&endscreenMenuTextNumBodyShots,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_LABEL,
|
|
6,
|
|
0,
|
|
L_OPTIONS_287, // "Limb Shots:"
|
|
(u32)&endscreenMenuTextNumLimbShots,
|
|
endscreenHandleCheatInfo,
|
|
},
|
|
{
|
|
MENUITEMTYPE_LABEL,
|
|
4,
|
|
0,
|
|
L_OPTIONS_288, // "Others:"
|
|
(u32)&endscreenMenuTextNumOtherShots,
|
|
endscreenHandleCheatInfo,
|
|
},
|
|
#else
|
|
// NTSC beta's endscreen dialog lacks cheat information
|
|
{
|
|
MENUITEMTYPE_LABEL,
|
|
0,
|
|
0,
|
|
L_OPTIONS_280, // "Mission Time:"
|
|
(u32)&endscreenMenuTextMissionTime,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_LABEL,
|
|
0,
|
|
0,
|
|
L_MPWEAPONS_129, // "Difficulty:"
|
|
(u32)&soloMenuTextDifficulty,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SEPARATOR,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_LABEL,
|
|
0,
|
|
0,
|
|
L_OPTIONS_281, // "Weapon of Choice:"
|
|
(u32)&mpMenuTextWeaponOfChoiceName,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_LABEL,
|
|
0,
|
|
0,
|
|
L_OPTIONS_282, // "Kills:"
|
|
(u32)&endscreenMenuTextNumKills,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_LABEL,
|
|
0,
|
|
0,
|
|
L_OPTIONS_283, // "Accuracy:"
|
|
(u32)&endscreenMenuTextAccuracy,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SEPARATOR,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_LABEL,
|
|
0,
|
|
0,
|
|
L_OPTIONS_284, // "Shot Total:"
|
|
(u32)&endscreenMenuTextNumShots,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_LABEL,
|
|
0,
|
|
0,
|
|
L_OPTIONS_285, // "Head Shots:"
|
|
(u32)&endscreenMenuTextNumHeadShots,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_LABEL,
|
|
0,
|
|
0,
|
|
L_OPTIONS_286, // "Body Shots:"
|
|
(u32)&endscreenMenuTextNumBodyShots,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_LABEL,
|
|
0,
|
|
0,
|
|
L_OPTIONS_287, // "Limb Shots:"
|
|
(u32)&endscreenMenuTextNumLimbShots,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_LABEL,
|
|
0,
|
|
0,
|
|
L_OPTIONS_288, // "Others:"
|
|
(u32)&endscreenMenuTextNumOtherShots,
|
|
NULL,
|
|
},
|
|
#endif
|
|
{
|
|
MENUITEMTYPE_SEPARATOR,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
MENUITEMFLAG_SELECTABLE_CENTRE,
|
|
L_OPTIONS_289, // "Press START"
|
|
0,
|
|
NULL,
|
|
},
|
|
{ MENUITEMTYPE_END },
|
|
};
|
|
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
char *endscreenMenuTextTimedCheatName(struct menuitem *item)
|
|
{
|
|
if (g_Menus[g_MpPlayerNum].endscreen.cheatinfo & 0x00000300) {
|
|
return cheatGetName(g_Menus[g_MpPlayerNum].endscreen.cheatinfo & 0xff);
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
#endif
|
|
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
char *endscreenMenuTextCompletionCheatName(struct menuitem *item)
|
|
{
|
|
if (g_Menus[g_MpPlayerNum].endscreen.cheatinfo & 0x00000800) {
|
|
return cheatGetName((g_Menus[g_MpPlayerNum].endscreen.cheatinfo >> 16) & 0xff);
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
#endif
|
|
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
char *endscreenMenuTextTargetTime(struct menuitem *item)
|
|
{
|
|
s32 time;
|
|
s32 time2;
|
|
|
|
if ((g_Menus[g_MpPlayerNum].endscreen.cheatinfo & 0x00000100) == 0) {
|
|
return NULL;
|
|
}
|
|
|
|
time = g_Menus[g_MpPlayerNum].endscreen.cheatinfo & 0xff;
|
|
time = cheatGetTime(time);
|
|
|
|
if (!time) {
|
|
return NULL;
|
|
}
|
|
|
|
formatTime(g_StringPointer, time * 60, TIMEPRECISION_SECONDS);
|
|
strcat(g_StringPointer, "\n");
|
|
return g_StringPointer;
|
|
}
|
|
#endif
|
|
|
|
void endscreenSetCoopCompleted(void)
|
|
{
|
|
if (g_CheatsActiveBank0 == 0 && g_CheatsActiveBank1 == 0) {
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
if (g_GameFile.coopcompletions[g_MissionConfig.difficulty] & (1 << g_MissionConfig.stageindex)) {
|
|
g_Menus[g_MpPlayerNum].endscreen.isfirstcompletion = true;
|
|
}
|
|
#endif
|
|
|
|
g_GameFile.coopcompletions[g_MissionConfig.difficulty] |= (1 << g_MissionConfig.stageindex);
|
|
}
|
|
}
|
|
|
|
struct menudialogdef g_SoloMissionEndscreenCompletedMenuDialog = {
|
|
MENUDIALOGTYPE_SUCCESS,
|
|
(u32)&endscreenMenuTitleStageCompleted,
|
|
g_MissionEndscreenMenuItems,
|
|
endscreenHandle2PCompleted,
|
|
MENUDIALOGFLAG_DISABLEITEMSCROLL | MENUDIALOGFLAG_SMOOTHSCROLLABLE,
|
|
&g_SoloEndscreenObjectivesCompletedMenuDialog,
|
|
};
|
|
|
|
struct menudialogdef g_SoloMissionEndscreenFailedMenuDialog = {
|
|
MENUDIALOGTYPE_DANGER,
|
|
(u32)&endscreenMenuTitleStageFailed,
|
|
g_MissionEndscreenMenuItems,
|
|
endscreenHandle2PFailed,
|
|
MENUDIALOGFLAG_DISABLEITEMSCROLL | MENUDIALOGFLAG_SMOOTHSCROLLABLE,
|
|
&g_SoloEndscreenObjectivesFailedMenuDialog,
|
|
};
|
|
|
|
/**
|
|
* Prepare the endscreen by calculating unlocked cheats, setting the new best
|
|
* time, choosing the default stage and difficulty and saving the game file.
|
|
*
|
|
* NTSC beta doesn't have cheats implemented, and has a different autostageindex
|
|
* and thumbnail calculation.
|
|
*/
|
|
void endscreenPrepare(void)
|
|
{
|
|
s32 timedcheatid;
|
|
s32 complcheatid;
|
|
s32 d;
|
|
s32 s;
|
|
u32 secs;
|
|
s32 timedalreadyunlocked;
|
|
s32 complalreadyunlocked;
|
|
u16 prevbest;
|
|
bool nowunlocked;
|
|
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
g_Menus[g_MpPlayerNum].endscreen.stageindex = g_MissionConfig.stageindex;
|
|
#endif
|
|
|
|
if (g_MenuData.root != MENUROOT_ENDSCREEN && g_Vars.mplayerisrunning == false) {
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
g_Menus[g_MpPlayerNum].endscreen.cheatinfo = 0;
|
|
g_Menus[g_MpPlayerNum].endscreen.isfirstcompletion = false;
|
|
g_Menus[g_MpPlayerNum].playernum = 0;
|
|
|
|
// Set cheat info
|
|
if (g_MissionConfig.iscoop == false
|
|
&& g_MissionConfig.isanti == false
|
|
&& g_MissionConfig.pdmode == false) {
|
|
timedcheatid = cheatGetByTimedStageIndex(g_MissionConfig.stageindex, g_MissionConfig.difficulty);
|
|
complcheatid = cheatGetByCompletedStageIndex(g_MissionConfig.stageindex);
|
|
|
|
if (timedcheatid >= 0) {
|
|
g_Menus[g_MpPlayerNum].endscreen.cheatinfo = 0x0100 | timedcheatid;
|
|
}
|
|
|
|
if (complcheatid >= 0) {
|
|
g_Menus[g_MpPlayerNum].endscreen.cheatinfo |= 0x1000 | (complcheatid << 16);
|
|
}
|
|
}
|
|
#else
|
|
g_Menus[g_MpPlayerNum].playernum = 0;
|
|
#endif
|
|
|
|
// Push the endscreen
|
|
#if VERSION == VERSION_PAL_BETA
|
|
if ((g_Vars.currentplayer->isdead || g_Vars.currentplayer->aborted || !objectiveIsAllComplete()) && !debugIsSetCompleteEnabled())
|
|
#else
|
|
if (g_Vars.currentplayer->isdead || g_Vars.currentplayer->aborted || !objectiveIsAllComplete())
|
|
#endif
|
|
{
|
|
menuPushRootDialog(&g_SoloMissionEndscreenFailedMenuDialog, MENUROOT_ENDSCREEN);
|
|
} else {
|
|
menuPushRootDialog(&g_SoloMissionEndscreenCompletedMenuDialog, MENUROOT_ENDSCREEN);
|
|
|
|
if (g_MissionConfig.iscoop) {
|
|
endscreenSetCoopCompleted();
|
|
}
|
|
}
|
|
|
|
if (g_MissionConfig.iscoop == false && g_MissionConfig.isanti == false) {
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
timedalreadyunlocked = false;
|
|
complalreadyunlocked = false;
|
|
|
|
// If there's a timed cheat for this stage + difficulty
|
|
if (g_Menus[g_MpPlayerNum].endscreen.cheatinfo & 0x100) {
|
|
timedalreadyunlocked = cheatIsUnlocked(g_Menus[g_MpPlayerNum].endscreen.cheatinfo & 0xff);
|
|
|
|
if (timedalreadyunlocked) {
|
|
g_Menus[g_MpPlayerNum].endscreen.cheatinfo |= 0x400;
|
|
}
|
|
}
|
|
|
|
// If there's a completion cheat for this stage (ie. not a special stage)
|
|
if (g_Menus[g_MpPlayerNum].endscreen.cheatinfo & 0x1000) {
|
|
complalreadyunlocked = cheatIsUnlocked((g_Menus[g_MpPlayerNum].endscreen.cheatinfo >> 16) & 0xff);
|
|
}
|
|
#else
|
|
playerGetMissionTime();
|
|
#endif
|
|
|
|
// Update total mission time
|
|
secs = playerGetMissionTime() / 60;
|
|
|
|
if (secs != 0) {
|
|
if (secs >= S32_MAX || S32_MAX - secs <= g_GameFile.totaltime) {
|
|
g_GameFile.totaltime = S32_MAX;
|
|
} else {
|
|
g_GameFile.totaltime += secs;
|
|
}
|
|
}
|
|
|
|
g_GameFile.autostageindex = g_MissionConfig.stageindex;
|
|
g_GameFile.autodifficulty = g_MissionConfig.difficulty;
|
|
|
|
#if VERSION == VERSION_PAL_BETA
|
|
if (g_CheatsActiveBank0 == 0
|
|
&& g_CheatsActiveBank1 == 0
|
|
&& g_MissionConfig.pdmode == false
|
|
&& ((g_Vars.currentplayer->isdead == false
|
|
&& g_Vars.currentplayer->aborted == false
|
|
&& objectiveIsAllComplete())
|
|
|| debugIsSetCompleteEnabled()))
|
|
#elif VERSION >= VERSION_NTSC_1_0
|
|
if (g_CheatsActiveBank0 == 0
|
|
&& g_CheatsActiveBank1 == 0
|
|
&& g_MissionConfig.pdmode == false
|
|
&& g_Vars.currentplayer->isdead == false
|
|
&& g_Vars.currentplayer->aborted == false
|
|
&& objectiveIsAllComplete())
|
|
#else
|
|
if (g_Vars.currentplayer->isdead == false
|
|
&& g_Vars.currentplayer->aborted == false
|
|
&& objectiveIsAllComplete()
|
|
&& g_CheatsActiveBank0 == 0
|
|
&& g_CheatsActiveBank1 == 0)
|
|
#endif
|
|
{
|
|
secs = playerGetMissionTime() / 60;
|
|
|
|
// The save file allows 12 bits per time, which is up to
|
|
// 1h 8m 16s. If the timer is higher than this, reduce it.
|
|
if (secs > 0xfff) {
|
|
secs = 0xfff;
|
|
}
|
|
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
// Zero is used as an indicator that the stage is not completed,
|
|
// so if the player managed to legitly complete a stage in 0:00
|
|
// adjust it to 0:01.
|
|
if (secs == 0) {
|
|
secs = 1;
|
|
}
|
|
|
|
// Set best time
|
|
prevbest = g_GameFile.besttimes[g_MissionConfig.stageindex][g_MissionConfig.difficulty];
|
|
|
|
if (prevbest == 0) {
|
|
g_Menus[g_MpPlayerNum].endscreen.isfirstcompletion = true;
|
|
}
|
|
|
|
if (secs < prevbest || prevbest == 0) {
|
|
g_GameFile.besttimes[g_MissionConfig.stageindex][g_MissionConfig.difficulty] = secs;
|
|
}
|
|
#else
|
|
prevbest = g_GameFile.besttimes[g_MissionConfig.stageindex][g_MissionConfig.difficulty];
|
|
|
|
if (secs < prevbest || prevbest == 0) {
|
|
g_GameFile.besttimes[g_MissionConfig.stageindex][g_MissionConfig.difficulty] = secs;
|
|
}
|
|
#endif
|
|
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
// Recalculate thumbnail for file select screen
|
|
if (g_MissionConfig.stageindex <= SOLOSTAGEINDEX_SKEDARRUINS) {
|
|
g_GameFile.autostageindex = g_MissionConfig.stageindex + 1;
|
|
|
|
if (g_GameFile.autostageindex > SOLOSTAGEINDEX_SKEDARRUINS) {
|
|
g_GameFile.autostageindex = SOLOSTAGEINDEX_SKEDARRUINS;
|
|
}
|
|
|
|
for (d = 0; d != 3; d++) {
|
|
for (s = 0; s <= SOLOSTAGEINDEX_SKEDARRUINS; s++) {
|
|
if (g_GameFile.besttimes[s][d]) {
|
|
g_GameFile.thumbnail = s + 1;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (g_Menus[g_MpPlayerNum].endscreen.cheatinfo & 0x100) {
|
|
nowunlocked = cheatIsUnlocked(g_Menus[g_MpPlayerNum].endscreen.cheatinfo & 0xff);
|
|
|
|
if (!timedalreadyunlocked && nowunlocked) {
|
|
g_Menus[g_MpPlayerNum].endscreen.cheatinfo |= 0x0200;
|
|
}
|
|
}
|
|
|
|
if (g_Menus[g_MpPlayerNum].endscreen.cheatinfo & 0x1000) {
|
|
nowunlocked = cheatIsUnlocked((g_Menus[g_MpPlayerNum].endscreen.cheatinfo >> 16) & 0xff);
|
|
|
|
if (!complalreadyunlocked && nowunlocked) {
|
|
g_Menus[g_MpPlayerNum].endscreen.cheatinfo |= 0x0800;
|
|
}
|
|
}
|
|
#else
|
|
// 154
|
|
if (g_MissionConfig.stageindex <= SOLOSTAGEINDEX_SKEDARRUINS) {
|
|
g_GameFile.autostageindex = g_MissionConfig.stageindex + 1;
|
|
|
|
if (g_GameFile.autostageindex > SOLOSTAGEINDEX_SKEDARRUINS) {
|
|
g_GameFile.autostageindex = SOLOSTAGEINDEX_SKEDARRUINS;
|
|
}
|
|
|
|
g_GameFile.thumbnail = g_MissionConfig.stageindex + 1;
|
|
}
|
|
#endif
|
|
|
|
challengeDetermineUnlockedFeatures();
|
|
|
|
if (g_MissionConfig.stagenum == STAGE_SKEDARRUINS && g_AltTitleUnlocked == false) {
|
|
g_AltTitleUnlocked = true;
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
*(s8 *)&g_AltTitleEnabled = true;
|
|
#else
|
|
g_AltTitleEnabled = true;
|
|
#endif
|
|
bossfileSave();
|
|
}
|
|
}
|
|
}
|
|
|
|
filemgrSaveOrLoad(&g_GameFileGuid, FILEOP_SAVE_GAME_000, 0);
|
|
}
|
|
|
|
if (g_MenuData.root == MENUROOT_ENDSCREEN) {
|
|
lvSetPaused(true);
|
|
g_Vars.currentplayer->pausemode = PAUSEMODE_PAUSED;
|
|
}
|
|
}
|
|
|
|
struct menudialogdef g_2PMissionEndscreenCompletedHMenuDialog = {
|
|
MENUDIALOGTYPE_SUCCESS,
|
|
(u32)&endscreenMenuTitleStageCompleted,
|
|
g_MissionEndscreenMenuItems,
|
|
endscreenHandle2PCompleted,
|
|
MENUDIALOGFLAG_DISABLEITEMSCROLL | MENUDIALOGFLAG_SMOOTHSCROLLABLE,
|
|
&g_SoloEndscreenObjectivesCompletedMenuDialog,
|
|
};
|
|
|
|
struct menudialogdef g_2PMissionEndscreenFailedHMenuDialog = {
|
|
MENUDIALOGTYPE_DANGER,
|
|
(u32)&endscreenMenuTitleStageFailed,
|
|
g_MissionEndscreenMenuItems,
|
|
endscreenHandle2PFailed,
|
|
MENUDIALOGFLAG_DISABLEITEMSCROLL | MENUDIALOGFLAG_SMOOTHSCROLLABLE,
|
|
&g_SoloEndscreenObjectivesFailedMenuDialog,
|
|
};
|
|
|
|
struct menudialogdef g_2PMissionEndscreenCompletedVMenuDialog = {
|
|
MENUDIALOGTYPE_SUCCESS,
|
|
L_OPTIONS_276, // "Completed"
|
|
g_2PMissionEndscreenVMenuItems,
|
|
endscreenHandle2PCompleted,
|
|
MENUDIALOGFLAG_DISABLEITEMSCROLL | MENUDIALOGFLAG_SMOOTHSCROLLABLE,
|
|
&g_2PMissionEndscreenObjectivesCompletedVMenuDialog,
|
|
};
|
|
|
|
struct menudialogdef g_2PMissionEndscreenFailedVMenuDialog = {
|
|
MENUDIALOGTYPE_DANGER,
|
|
L_OPTIONS_277, // "Failed"
|
|
g_2PMissionEndscreenVMenuItems,
|
|
endscreenHandle2PFailed,
|
|
MENUDIALOGFLAG_DISABLEITEMSCROLL | MENUDIALOGFLAG_SMOOTHSCROLLABLE,
|
|
&g_2PMissionEndscreenObjectivesFailedVMenuDialog,
|
|
};
|
|
|
|
void endscreenPushCoop(void)
|
|
{
|
|
u32 prevplayernum = g_MpPlayerNum;
|
|
|
|
lvSetPaused(true);
|
|
|
|
g_MpPlayerNum = g_Vars.currentplayerstats->mpindex;
|
|
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
g_Menus[g_MpPlayerNum].endscreen.cheatinfo = 0;
|
|
g_Menus[g_MpPlayerNum].endscreen.isfirstcompletion = false;
|
|
g_Menus[g_MpPlayerNum].endscreen.stageindex = g_MissionConfig.stageindex;
|
|
#endif
|
|
|
|
g_Menus[g_MpPlayerNum].playernum = g_Vars.currentplayernum;
|
|
|
|
#if VERSION == VERSION_PAL_BETA
|
|
if (((g_Vars.bond->isdead && g_Vars.coop->isdead)
|
|
|| g_Vars.bond->aborted
|
|
|| g_Vars.coop->aborted
|
|
|| !objectiveIsAllComplete()) && !debugIsSetCompleteEnabled())
|
|
#else
|
|
if ((g_Vars.bond->isdead && g_Vars.coop->isdead)
|
|
|| g_Vars.bond->aborted
|
|
|| g_Vars.coop->aborted
|
|
|| !objectiveIsAllComplete())
|
|
#endif
|
|
{
|
|
// Failed or aborted
|
|
if (optionsGetScreenSplit() == SCREENSPLIT_VERTICAL) {
|
|
menuPushRootDialog(&g_2PMissionEndscreenFailedVMenuDialog, MENUROOT_MPENDSCREEN);
|
|
} else {
|
|
menuPushRootDialog(&g_2PMissionEndscreenFailedHMenuDialog, MENUROOT_MPENDSCREEN);
|
|
}
|
|
} else {
|
|
// Completed
|
|
if (optionsGetScreenSplit() == SCREENSPLIT_VERTICAL) {
|
|
menuPushRootDialog(&g_2PMissionEndscreenCompletedVMenuDialog, MENUROOT_MPENDSCREEN);
|
|
} else {
|
|
menuPushRootDialog(&g_2PMissionEndscreenCompletedHMenuDialog, MENUROOT_MPENDSCREEN);
|
|
}
|
|
|
|
endscreenSetCoopCompleted();
|
|
}
|
|
|
|
if (g_Vars.currentplayer == g_Vars.bond) {
|
|
filemgrSaveOrLoad(&g_GameFileGuid, FILEOP_SAVE_GAME_000, 0);
|
|
}
|
|
|
|
g_MpPlayerNum = prevplayernum;
|
|
}
|
|
|
|
/**
|
|
* This function is misnamed. It pushes the menu after the endscreen
|
|
* (ie. retry, next mission or continue), and it looks like it might be for coop
|
|
* only but I'm not 100% sure.
|
|
*
|
|
* This function is only called from menuTick, which is a bit weird...
|
|
*/
|
|
void endscreenPushSolo(void)
|
|
{
|
|
u32 prevplayernum = g_MpPlayerNum;
|
|
|
|
g_MpPlayerNum = 0;
|
|
g_Menus[g_MpPlayerNum].playernum = 0;
|
|
|
|
#if VERSION == VERSION_PAL_BETA
|
|
if (((g_Vars.bond->isdead && g_Vars.coop->isdead)
|
|
|| g_Vars.bond->aborted
|
|
|| g_Vars.coop->aborted
|
|
|| !objectiveIsAllComplete()) && !debugIsSetCompleteEnabled())
|
|
#else
|
|
if ((g_Vars.bond->isdead && g_Vars.coop->isdead)
|
|
|| g_Vars.bond->aborted
|
|
|| g_Vars.coop->aborted
|
|
|| !objectiveIsAllComplete())
|
|
#endif
|
|
{
|
|
// Failed or aborted
|
|
endscreen0f10d770();
|
|
menuPushRootDialog(&g_RetryMissionMenuDialog, MENUROOT_COOPCONTINUE);
|
|
} else {
|
|
// Completed
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
endscreenContinue(1);
|
|
#else
|
|
struct menudialogdef *definition = endscreenAdvance();
|
|
|
|
if (definition) {
|
|
endscreen0f10d770();
|
|
menuPushRootDialog(definition, MENUROOT_COOPCONTINUE);
|
|
}
|
|
#endif
|
|
}
|
|
|
|
g_MpPlayerNum = prevplayernum;
|
|
}
|
|
|
|
void endscreenPushAnti(void)
|
|
{
|
|
u32 prevplayernum = g_MpPlayerNum;
|
|
|
|
lvSetPaused(true);
|
|
|
|
g_MpPlayerNum = g_Vars.currentplayerstats->mpindex;
|
|
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
g_Menus[g_MpPlayerNum].endscreen.cheatinfo = 0;
|
|
g_Menus[g_MpPlayerNum].endscreen.isfirstcompletion = false;
|
|
g_Menus[g_MpPlayerNum].endscreen.stageindex = g_MissionConfig.stageindex;
|
|
#endif
|
|
|
|
g_Menus[g_MpPlayerNum].playernum = g_Vars.currentplayernum;
|
|
|
|
if (g_Vars.currentplayer == g_Vars.bond) {
|
|
#if VERSION == VERSION_PAL_BETA
|
|
if (!g_Vars.anti->aborted && (g_Vars.bond->isdead || g_Vars.bond->aborted || !objectiveIsAllComplete()) && !debugIsSetCompleteEnabled())
|
|
#else
|
|
if (!g_Vars.anti->aborted && (g_Vars.bond->isdead || g_Vars.bond->aborted || !objectiveIsAllComplete()))
|
|
#endif
|
|
{
|
|
// Bond - failed or aborted
|
|
if (optionsGetScreenSplit() == SCREENSPLIT_VERTICAL) {
|
|
menuPushRootDialog(&g_2PMissionEndscreenFailedVMenuDialog, MENUROOT_MPENDSCREEN);
|
|
} else {
|
|
menuPushRootDialog(&g_2PMissionEndscreenFailedHMenuDialog, MENUROOT_MPENDSCREEN);
|
|
}
|
|
} else {
|
|
// Bond - completed
|
|
if (optionsGetScreenSplit() == SCREENSPLIT_VERTICAL) {
|
|
menuPushRootDialog(&g_2PMissionEndscreenCompletedVMenuDialog, MENUROOT_MPENDSCREEN);
|
|
} else {
|
|
menuPushRootDialog(&g_2PMissionEndscreenCompletedHMenuDialog, MENUROOT_MPENDSCREEN);
|
|
}
|
|
}
|
|
|
|
filemgrSaveOrLoad(&g_GameFileGuid, FILEOP_SAVE_GAME_000, 0);
|
|
} else {
|
|
#if VERSION == VERSION_PAL_BETA
|
|
if (!g_Vars.anti->aborted && (g_Vars.bond->isdead || g_Vars.bond->aborted || !objectiveIsAllComplete()) && !debugIsSetCompleteEnabled())
|
|
#else
|
|
if (!g_Vars.anti->aborted && (g_Vars.bond->isdead || g_Vars.bond->aborted || !objectiveIsAllComplete()))
|
|
#endif
|
|
{
|
|
// Anti - completed
|
|
if (optionsGetScreenSplit() == SCREENSPLIT_VERTICAL) {
|
|
menuPushRootDialog(&g_2PMissionEndscreenCompletedVMenuDialog, MENUROOT_MPENDSCREEN);
|
|
} else {
|
|
menuPushRootDialog(&g_2PMissionEndscreenCompletedHMenuDialog, MENUROOT_MPENDSCREEN);
|
|
}
|
|
} else {
|
|
// Anti - failed or aborted
|
|
if (optionsGetScreenSplit() == SCREENSPLIT_VERTICAL) {
|
|
menuPushRootDialog(&g_2PMissionEndscreenFailedVMenuDialog, MENUROOT_MPENDSCREEN);
|
|
} else {
|
|
menuPushRootDialog(&g_2PMissionEndscreenFailedHMenuDialog, MENUROOT_MPENDSCREEN);
|
|
}
|
|
}
|
|
}
|
|
|
|
g_MpPlayerNum = prevplayernum;
|
|
}
|