forked from Ports/perfect_dark
Preliminary 4-player counter-op mode
Here's some things that will be needed off the top of my head: - Handling the half-screen-width case for the pause menus - Changing the player select menu to select the not-counter-op player instead, then extending that to 4 players - Thorough testing of each level for any weird counter-op-specific features
This commit is contained in:
1 parent
6b105d0be0
commit
a0db91a0c9
10 files changed
+125
-11
No files matched your search
@@ -465,7 +465,13 @@ void mainLoop(void)
|
||||
}
|
||||
|
||||
if (g_Vars.coopplayernum >= 0 || g_Vars.antiplayernum >= 0) {
|
||||
#ifdef PLATFORM_N64
|
||||
g_MpSetup.chrslots = 0x03;
|
||||
#else
|
||||
if (getNumPlayers() <= 2) {
|
||||
g_MpSetup.chrslots = 0x03;
|
||||
}
|
||||
#endif
|
||||
mpReset();
|
||||
} else if (g_Vars.perfectbuddynum) {
|
||||
mpReset();
|
||||
|
||||
@@ -475,7 +475,11 @@ bool bwalkCalculateNewPositionWithPush(struct coord *delta, f32 rotateamount, bo
|
||||
}
|
||||
} else if (chr->chrflags & CHRCFLAG_PUSHABLE) {
|
||||
if (g_Vars.antiplayernum < 0
|
||||
#ifdef PLATFORM_N64
|
||||
|| g_Vars.currentplayer != g_Vars.anti
|
||||
#else
|
||||
|| g_Vars.currentplayer == g_Vars.bond
|
||||
#endif
|
||||
|| (chr->hidden & CHRHFLAG_ANTINONINTERACTABLE) == 0) {
|
||||
canpush = true;
|
||||
}
|
||||
@@ -809,7 +813,11 @@ void bwalkUpdateVertical(void)
|
||||
// Maybe reset counter-op's radius - not sure why
|
||||
// Maybe it gets set to 0 when they die?
|
||||
if (g_Vars.antiplayernum >= 0
|
||||
#ifdef PLATFORM_N64
|
||||
&& g_Vars.currentplayer == g_Vars.anti
|
||||
#else
|
||||
&& g_Vars.currentplayer != g_Vars.bond
|
||||
#endif
|
||||
&& g_Vars.currentplayer->bond2.radius != 30
|
||||
&& cdTestVolume(&g_Vars.currentplayer->prop->pos, 30, g_Vars.currentplayer->prop->rooms, CDTYPE_ALL, CHECKVERTICAL_YES, ymax - g_Vars.currentplayer->prop->pos.y, ymin - g_Vars.currentplayer->prop->pos.y)) {
|
||||
g_Vars.currentplayer->prop->chr->radius = 30;
|
||||
|
||||
+28
-2
@@ -4351,7 +4351,14 @@ void chrDamage(struct chrdata *chr, f32 damage, struct coord *vector, struct gse
|
||||
// Don't damage if attacker was anti and chr is non-interactable by anti
|
||||
if (g_Vars.antiplayernum >= 0
|
||||
&& aprop
|
||||
|
||||
#ifdef PLATFORM_N64
|
||||
&& aprop == g_Vars.anti->prop
|
||||
#else
|
||||
&& aprop->type == PROPTYPE_PLAYER
|
||||
&& aprop != g_Vars.bond->prop
|
||||
#endif
|
||||
|
||||
&& (chr->hidden & CHRHFLAG_ANTINONINTERACTABLE)) {
|
||||
return;
|
||||
}
|
||||
@@ -4490,7 +4497,15 @@ void chrDamage(struct chrdata *chr, f32 damage, struct coord *vector, struct gse
|
||||
}
|
||||
|
||||
// Anti shooting other enemies is lethal
|
||||
if (aprop && aprop == g_Vars.anti->prop && vprop != g_Vars.bond->prop) {
|
||||
if (aprop
|
||||
#ifdef PLATFORM_N64
|
||||
&& aprop == g_Vars.anti->prop
|
||||
#else
|
||||
&& aprop->type == PROPTYPE_PLAYER
|
||||
&& aprop != g_Vars.bond->prop
|
||||
#endif
|
||||
|
||||
&& vprop != g_Vars.bond->prop) {
|
||||
damage *= 100;
|
||||
}
|
||||
} else {
|
||||
@@ -8321,7 +8336,14 @@ void chrAlertOthersOfInjury(struct chrdata *chr, bool dying)
|
||||
s32 numinrange = 0;
|
||||
s32 numchrs = chrsGetNumSlots();
|
||||
|
||||
if (g_Vars.antiplayernum >= 0 && chr->prop == g_Vars.anti->prop) {
|
||||
if (g_Vars.antiplayernum >= 0
|
||||
#ifdef PLATFORM_N64
|
||||
&& chr->prop == g_Vars.anti->prop
|
||||
#else
|
||||
&& chr->prop->type == PROPTYPE_PLAYER
|
||||
&& chr->prop != g_Vars.bond->prop
|
||||
#endif
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -13556,7 +13578,11 @@ void chraTickBg(void)
|
||||
|
||||
if (targetprop && (targetprop->type == PROPTYPE_CHR || targetprop->type == PROPTYPE_PLAYER)) {
|
||||
if ((targetprop->type == PROPTYPE_PLAYER
|
||||
#ifdef PLATFORM_N64
|
||||
&& !(g_Vars.antiplayernum >= 0 && g_Vars.anti && g_Vars.anti->prop == targetprop)
|
||||
#else
|
||||
&& !(g_Vars.antiplayernum >= 0 && g_Vars.bond && g_Vars.bond->prop != targetprop)
|
||||
#endif
|
||||
&& chrCompareTeams(chr, targetprop->chr, COMPARE_ENEMIES))
|
||||
|| CHRRACE(targetprop->chr) == RACE_EYESPY) {
|
||||
s32 time60;
|
||||
|
||||
@@ -757,7 +757,20 @@ MenuItemHandlerResult menuhandlerAcceptMission(s32 operation, struct menuitem *i
|
||||
}
|
||||
|
||||
g_Vars.coopplayernum = -1;
|
||||
#ifdef PLATFORM_N64
|
||||
setNumPlayers(2);
|
||||
#else
|
||||
if ((joyGetConnectedControllers() & 0xF) == 0xF) {
|
||||
setNumPlayers(4);
|
||||
g_MpSetup.chrslots = 0xF;
|
||||
} else if ((joyGetConnectedControllers() & 0x7) == 0x7) {
|
||||
setNumPlayers(3);
|
||||
g_MpSetup.chrslots = 0x7;
|
||||
} else {
|
||||
setNumPlayers(2);
|
||||
g_MpSetup.chrslots = 0x3;
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
// Solo
|
||||
g_Vars.bondplayernum = 0;
|
||||
|
||||
@@ -256,7 +256,12 @@ void mpReset(void)
|
||||
g_Vars.lvmpbotlevel = true;
|
||||
}
|
||||
|
||||
if (g_Vars.coopplayernum >= 0 || g_Vars.antiplayernum >= 0) {
|
||||
#ifdef PLATFORM_N64
|
||||
if (g_Vars.coopplayernum >= 0 || g_Vars.antiplayernum >= 0)
|
||||
#else
|
||||
if ((g_Vars.coopplayernum >= 0 || g_Vars.antiplayernum >= 0) && getNumPlayers() <= 2)
|
||||
#endif
|
||||
{
|
||||
struct mpplayerconfig tmp;
|
||||
|
||||
tmp = g_PlayerConfigsArray[MAX_PLAYERS];
|
||||
@@ -1333,7 +1338,11 @@ Gfx *mpRenderModalText(Gfx *gdl)
|
||||
&& g_Vars.currentplayer->redbloodfinished
|
||||
&& g_Vars.currentplayer->deathanimfinished
|
||||
&& !(g_Vars.coopplayernum >= 0 && ((g_Vars.bond->isdead && g_Vars.coop->isdead) || !g_Vars.currentplayer->coopcanrestart || g_InCutscene))
|
||||
#ifdef PLATFORM_N64
|
||||
&& !(g_Vars.antiplayernum >= 0 && ((g_Vars.currentplayer != g_Vars.anti || g_InCutscene)))
|
||||
#else
|
||||
&& !(g_Vars.antiplayernum >= 0 && ((g_Vars.currentplayer == g_Vars.bond || g_InCutscene)))
|
||||
#endif
|
||||
&& g_NumReasonsToEndMpMatch == 0) {
|
||||
// Render "Press START" text
|
||||
gdl = text0f153628(gdl);
|
||||
|
||||
+29
-3
@@ -606,7 +606,13 @@ void playerStartNewLife(void)
|
||||
if (cmd);
|
||||
if (cmd);
|
||||
|
||||
if (g_Vars.antiplayernum < 0 || g_Vars.currentplayer != g_Vars.anti) {
|
||||
if (g_Vars.antiplayernum < 0
|
||||
#ifdef PLATFORM_N64
|
||||
|| g_Vars.currentplayer != g_Vars.anti
|
||||
#else
|
||||
|| g_Vars.currentplayer == g_Vars.bond
|
||||
#endif
|
||||
) {
|
||||
while (cmd[0] != INTROCMD_END) {
|
||||
switch (cmd[0]) {
|
||||
case INTROCMD_SPAWN:
|
||||
@@ -980,7 +986,13 @@ void playerSpawn(void)
|
||||
}
|
||||
|
||||
if (g_Vars.mplayerisrunning) {
|
||||
if (g_Vars.antiplayernum >= 0 && g_Vars.currentplayer == g_Vars.anti) {
|
||||
if (g_Vars.antiplayernum >= 0
|
||||
#ifdef PLATFORM_N64
|
||||
&& g_Vars.currentplayer == g_Vars.anti
|
||||
#else
|
||||
&& g_Vars.currentplayer != g_Vars.bond
|
||||
#endif
|
||||
) {
|
||||
numsqdists = 0;
|
||||
force = false;
|
||||
|
||||
@@ -1182,7 +1194,11 @@ void playerChooseBodyAndHead(s32 *bodynum, s32 *headnum, s32 *arg2)
|
||||
bool solo;
|
||||
|
||||
if (g_Vars.antiplayernum >= 0
|
||||
#ifdef PLATFORM_N64
|
||||
&& g_Vars.currentplayer == g_Vars.anti
|
||||
#else
|
||||
&& g_Vars.currentplayer != g_Vars.bond
|
||||
#endif
|
||||
&& g_Vars.antiheadnum >= 0
|
||||
&& g_Vars.antibodynum >= 0) {
|
||||
*headnum = g_Vars.antiheadnum;
|
||||
@@ -1514,7 +1530,11 @@ void playerTickChrBody(void)
|
||||
|
||||
#if VERSION >= VERSION_NTSC_1_0
|
||||
if (g_Vars.antiplayernum >= 0
|
||||
#ifdef PLATFORM_N64
|
||||
&& g_Vars.currentplayer == g_Vars.anti
|
||||
#else
|
||||
&& g_Vars.currentplayer != g_Vars.bond
|
||||
#endif
|
||||
&& g_Vars.currentplayer->vv_eyeheight > 159) {
|
||||
g_Vars.currentplayer->vv_eyeheight = 159;
|
||||
}
|
||||
@@ -4713,7 +4733,13 @@ Gfx *playerRenderHud(Gfx *gdl)
|
||||
chr->chrflags |= CHRCFLAG_HIDDEN;
|
||||
}
|
||||
|
||||
if (g_Vars.antiplayernum >= 0 && g_Vars.currentplayer == g_Vars.anti) {
|
||||
if (g_Vars.antiplayernum >= 0
|
||||
#ifdef PLATFORM_N64
|
||||
&& g_Vars.currentplayer == g_Vars.anti
|
||||
#else
|
||||
&& g_Vars.currentplayer != g_Vars.bond
|
||||
#endif
|
||||
) {
|
||||
// Anti
|
||||
#ifndef PLATFORM_N64
|
||||
if (g_NetMode == NETMODE_SERVER && g_Vars.currentplayer->isremote) {
|
||||
|
||||
+15
-2
@@ -186,7 +186,14 @@ void playerReset(void)
|
||||
cmd = (struct cmd32 *)((uintptr_t)cmd + 8);
|
||||
break;
|
||||
case INTROCMD_WEAPON:
|
||||
if (cmd->param3 == 0 && g_Vars.currentplayer != g_Vars.anti) {
|
||||
if (cmd->param3 == 0
|
||||
#ifdef PLATFORM_N64
|
||||
&& g_Vars.currentplayer != g_Vars.anti
|
||||
#else
|
||||
&& (g_Vars.antiplayernum < 0 || g_Vars.currentplayer == g_Vars.bond)
|
||||
#endif
|
||||
) {
|
||||
|
||||
modelmgrLoadProjectileModeldefs(cmd->param1);
|
||||
|
||||
if (cmd->param2 >= 0) {
|
||||
@@ -213,7 +220,13 @@ void playerReset(void)
|
||||
cmd = (struct cmd32 *)((uintptr_t)cmd + 16);
|
||||
break;
|
||||
case INTROCMD_AMMO:
|
||||
if (cmd->param3 == 0 && g_Vars.currentplayer != g_Vars.anti) {
|
||||
if (cmd->param3 == 0
|
||||
#ifdef PLATFORM_N64
|
||||
&& g_Vars.currentplayer != g_Vars.anti
|
||||
#else
|
||||
&& (g_Vars.antiplayernum < 0 || g_Vars.currentplayer == g_Vars.bond)
|
||||
#endif
|
||||
) {
|
||||
bgunSetAmmoQuantity(cmd->param1, cmd->param2);
|
||||
}
|
||||
cmd = (struct cmd32 *)((uintptr_t)cmd + 16);
|
||||
|
||||
+6
-1
@@ -2358,7 +2358,12 @@ void propsTestForPickup(void)
|
||||
|
||||
if (g_Vars.currentplayer->bondmovemode != MOVEMODE_CUTSCENE
|
||||
&& !g_PlayerInvincible
|
||||
&& g_Vars.currentplayer != g_Vars.anti) {
|
||||
#ifdef PLATFORM_N64
|
||||
&& g_Vars.currentplayer != g_Vars.anti
|
||||
#else
|
||||
&& (g_Vars.antiplayernum < 0 || g_Vars.currentplayer == g_Vars.bond)
|
||||
#endif
|
||||
) {
|
||||
roomsCopy(g_Vars.currentplayer->prop->rooms, allrooms);
|
||||
|
||||
for (i = 0; g_Vars.currentplayer->prop->rooms[i] != -1; i++) {
|
||||
|
||||
+8
-1
@@ -15942,7 +15942,14 @@ void objHit(struct shotdata *shotdata, struct hit *hit)
|
||||
}
|
||||
}
|
||||
|
||||
if (g_Vars.antiplayernum < 0 || g_Vars.currentplayer != g_Vars.anti || (obj->flags2 & OBJFLAG2_IMMUNETOANTI) == 0) {
|
||||
if (g_Vars.antiplayernum < 0
|
||||
#ifdef PLATFORM_N64
|
||||
|| g_Vars.currentplayer != g_Vars.anti
|
||||
#else
|
||||
|| g_Vars.currentplayer == g_Vars.bond
|
||||
#endif
|
||||
|| (obj->flags2 & OBJFLAG2_IMMUNETOANTI) == 0) {
|
||||
|
||||
if (hit->hitthing.texturenum != 10000) {
|
||||
f32 damage = gsetGetDamage(&shotdata->gset);
|
||||
|
||||
|
||||
@@ -20,8 +20,9 @@
|
||||
#define MAX_CHRWAYPOINTS 6
|
||||
#define MAX_EXPLOSIONS 6
|
||||
#define MAX_EYESPYDARTS 8
|
||||
#define MAX_COOPCHRS MAX_PLAYERS
|
||||
#define MAX_MPCHRS (MAX_PLAYERS + MAX_BOTS)
|
||||
#define MAX_MPPLAYERCONFIGS (MAX_PLAYERS + 2)
|
||||
#define MAX_MPPLAYERCONFIGS (MAX_PLAYERS + MAX_COOPCHRS)
|
||||
#define MAX_OBJECTIVES 10
|
||||
#define MAX_LOCAL_PLAYERS 4
|
||||
#define MAX_PLAYERS 8
|
||||
|
||||
Reference in new issue
Block a user