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:
GreaseMonkey committed 2024-02-09 08:40:02 +13:00
1 parent 6b105d0be0
commit a0db91a0c9
10 files changed
+125 -11

No files matched your search

+6
View File
@@ -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();
+8
View File
@@ -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
View File
@@ -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;
+13
View File
@@ -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;
+10 -1
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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);
+2 -1
View File
@@ -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