mirror of
https://github.com/perfect-dark-pc-port/perfect_dark.git
synced 2026-10-24 00:02:43 +02:00
Merge pull request #388 from iamgreaser/gm/net/counterop-4player
port-net: Extend counter-op mode to 4 players
This commit is contained in:
15 files changed
+285
-37
No files matched your search
@@ -465,7 +465,15 @@ void mainLoop(void)
|
||||
}
|
||||
|
||||
if (g_Vars.coopplayernum >= 0 || g_Vars.antiplayernum >= 0) {
|
||||
#ifdef PLATFORM_N64
|
||||
g_MpSetup.chrslots = 0x03;
|
||||
#else
|
||||
if (g_Vars.antiplayernum < 0) {
|
||||
// Counter-Operative now uses a different approach which allows more than 2 players.
|
||||
// Co-Operative, on the other hand, is currently limited to 2 players.
|
||||
g_MpSetup.chrslots = 0x03;
|
||||
}
|
||||
#endif
|
||||
mpReset();
|
||||
} else if (g_Vars.perfectbuddynum) {
|
||||
mpReset();
|
||||
|
||||
+2
-2
@@ -475,7 +475,7 @@ bool bwalkCalculateNewPositionWithPush(struct coord *delta, f32 rotateamount, bo
|
||||
}
|
||||
} else if (chr->chrflags & CHRCFLAG_PUSHABLE) {
|
||||
if (g_Vars.antiplayernum < 0
|
||||
|| g_Vars.currentplayer != g_Vars.anti
|
||||
|| PLAYER_IS_NOT_ANTI(g_Vars.currentplayer)
|
||||
|| (chr->hidden & CHRHFLAG_ANTINONINTERACTABLE) == 0) {
|
||||
canpush = true;
|
||||
}
|
||||
@@ -809,7 +809,7 @@ 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
|
||||
&& g_Vars.currentplayer == g_Vars.anti
|
||||
&& PLAYER_IS_ANTI(g_Vars.currentplayer)
|
||||
&& 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;
|
||||
|
||||
+1
-1
@@ -4662,7 +4662,7 @@ void chrHit(struct shotdata *shotdata, struct hit *hit)
|
||||
hit->model, hit->hitthing.unk28 / 2, sp90);
|
||||
|
||||
if (g_Vars.antiplayernum >= 0
|
||||
&& g_Vars.currentplayer == g_Vars.anti
|
||||
&& PLAYER_IS_ANTI(g_Vars.currentplayer)
|
||||
&& (chr->hidden & CHRHFLAG_ANTINONINTERACTABLE)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -4351,7 +4351,7 @@ 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
|
||||
&& aprop == g_Vars.anti->prop
|
||||
&& PROP_IS_FOR_ANTI_PLAYER(aprop)
|
||||
&& (chr->hidden & CHRHFLAG_ANTINONINTERACTABLE)) {
|
||||
return;
|
||||
}
|
||||
@@ -4490,7 +4490,9 @@ 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
|
||||
&& PROP_IS_FOR_ANTI_PLAYER(aprop)
|
||||
&& vprop != g_Vars.bond->prop) {
|
||||
damage *= 100;
|
||||
}
|
||||
} else {
|
||||
@@ -8321,7 +8323,7 @@ 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 && PROP_IS_FOR_ANTI_PLAYER(chr->prop)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -13556,7 +13558,7 @@ void chraTickBg(void)
|
||||
|
||||
if (targetprop && (targetprop->type == PROPTYPE_CHR || targetprop->type == PROPTYPE_PLAYER)) {
|
||||
if ((targetprop->type == PROPTYPE_PLAYER
|
||||
&& !(g_Vars.antiplayernum >= 0 && g_Vars.anti && g_Vars.anti->prop == targetprop)
|
||||
&& !(g_Vars.antiplayernum >= 0 && g_Vars.anti && PROP_IS_FOR_ANTI_PLAYER(targetprop))
|
||||
&& chrCompareTeams(chr, targetprop->chr, COMPARE_ENEMIES))
|
||||
|| CHRRACE(targetprop->chr) == RACE_EYESPY) {
|
||||
s32 time60;
|
||||
|
||||
@@ -52,6 +52,10 @@
|
||||
#include "data.h"
|
||||
#include "types.h"
|
||||
|
||||
#ifndef PLATFORM_N64
|
||||
#include "game/mplayer/mplayer.h"
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @cmd 0000
|
||||
*/
|
||||
@@ -6035,11 +6039,35 @@ bool aiSetChrPresetToChrNearPad(void)
|
||||
bool aiChrSetTeam(void)
|
||||
{
|
||||
u8 *cmd = g_Vars.ailist + g_Vars.aioffset;
|
||||
#ifdef PLATFORM_N64
|
||||
struct chrdata *chr = chrFindById(g_Vars.chrdata, cmd[2]);
|
||||
|
||||
if (chr) {
|
||||
chr->team = cmd[3];
|
||||
}
|
||||
#else
|
||||
u32 playernum;
|
||||
if (cmd[2] == CHR_ANTI && g_Vars.antiplayernum >= 0) {
|
||||
// There can be multiple counter-op players, so set this for all.
|
||||
for (playernum = 0; playernum < PLAYERCOUNT(); playernum++) {
|
||||
struct player *player = g_Vars.players[playernum];
|
||||
|
||||
if (player && PLAYER_IS_ANTI(player)) {
|
||||
struct chrdata *chr = player->prop->chr;
|
||||
|
||||
if (chr) {
|
||||
chr->team = cmd[3];
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
struct chrdata *chr = chrFindById(g_Vars.chrdata, cmd[2]);
|
||||
|
||||
if (chr) {
|
||||
chr->team = cmd[3];
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
g_Vars.aioffset += 4;
|
||||
|
||||
|
||||
+57
-12
@@ -292,6 +292,27 @@ char *endscreenMenuTextAccuracy(struct menuitem *item)
|
||||
return g_StringPointer;
|
||||
}
|
||||
|
||||
#if MAX_COOPCHRS > 2
|
||||
static bool enscreenAnyAntiAborted(void) {
|
||||
size_t num;
|
||||
|
||||
if (g_Vars.antiplayernum < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (num = 0; num < PLAYERCOUNT(); num++) {
|
||||
if (PLAYERNUM_IS_ANTI(num) && g_Vars.players[num] && g_Vars.players[num]->aborted) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
#define ANTI_ABORTED() (enscreenAnyAntiAborted())
|
||||
#else
|
||||
#define ANTI_ABORTED() (g_Vars.anti->aborted)
|
||||
#endif
|
||||
|
||||
char *endscreenMenuTextMissionStatus(struct menuitem *item)
|
||||
{
|
||||
if (g_CheatsActiveBank0 || g_CheatsActiveBank1) {
|
||||
@@ -312,7 +333,7 @@ char *endscreenMenuTextMissionStatus(struct menuitem *item)
|
||||
return langGet(L_OPTIONS_295); // "Aborted"
|
||||
}
|
||||
|
||||
if (g_Vars.anti->aborted) {
|
||||
if (ANTI_ABORTED()) {
|
||||
return langGet(L_OPTIONS_295); // "Aborted"
|
||||
}
|
||||
|
||||
@@ -320,7 +341,7 @@ char *endscreenMenuTextMissionStatus(struct menuitem *item)
|
||||
return langGet(L_OPTIONS_293); // "Failed"
|
||||
}
|
||||
} else {
|
||||
if (g_Vars.anti->aborted) {
|
||||
if (ANTI_ABORTED()) {
|
||||
return langGet(L_OPTIONS_295); // "Aborted"
|
||||
}
|
||||
|
||||
@@ -1700,14 +1721,22 @@ void endscreenPushCoop(void)
|
||||
#endif
|
||||
{
|
||||
// Failed or aborted
|
||||
if (optionsGetScreenSplit() == SCREENSPLIT_VERTICAL) {
|
||||
if (optionsGetScreenSplit() == SCREENSPLIT_VERTICAL
|
||||
#ifndef PLATFORM_N64
|
||||
|| LOCALPLAYERCOUNT() >= 3
|
||||
#endif
|
||||
) {
|
||||
menuPushRootDialog(&g_2PMissionEndscreenFailedVMenuDialog, MENUROOT_MPENDSCREEN);
|
||||
} else {
|
||||
menuPushRootDialog(&g_2PMissionEndscreenFailedHMenuDialog, MENUROOT_MPENDSCREEN);
|
||||
}
|
||||
} else {
|
||||
// Completed
|
||||
if (optionsGetScreenSplit() == SCREENSPLIT_VERTICAL) {
|
||||
if (optionsGetScreenSplit() == SCREENSPLIT_VERTICAL
|
||||
#ifndef PLATFORM_N64
|
||||
|| LOCALPLAYERCOUNT() >= 3
|
||||
#endif
|
||||
) {
|
||||
menuPushRootDialog(&g_2PMissionEndscreenCompletedVMenuDialog, MENUROOT_MPENDSCREEN);
|
||||
} else {
|
||||
menuPushRootDialog(&g_2PMissionEndscreenCompletedHMenuDialog, MENUROOT_MPENDSCREEN);
|
||||
@@ -1787,20 +1816,28 @@ void endscreenPushAnti(void)
|
||||
|
||||
if (g_Vars.currentplayer == g_Vars.bond) {
|
||||
#if VERSION >= VERSION_NTSC_1_0 && defined(DEBUG)
|
||||
if (!g_Vars.anti->aborted && (g_Vars.bond->isdead || g_Vars.bond->aborted || !objectiveIsAllComplete()) && !debugIsSetCompleteEnabled())
|
||||
if (!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()))
|
||||
if (!ANTI_ABORTED() && (g_Vars.bond->isdead || g_Vars.bond->aborted || !objectiveIsAllComplete()))
|
||||
#endif
|
||||
{
|
||||
// Bond - failed or aborted
|
||||
if (optionsGetScreenSplit() == SCREENSPLIT_VERTICAL) {
|
||||
if (optionsGetScreenSplit() == SCREENSPLIT_VERTICAL
|
||||
#ifndef PLATFORM_N64
|
||||
|| LOCALPLAYERCOUNT() >= 3
|
||||
#endif
|
||||
) {
|
||||
menuPushRootDialog(&g_2PMissionEndscreenFailedVMenuDialog, MENUROOT_MPENDSCREEN);
|
||||
} else {
|
||||
menuPushRootDialog(&g_2PMissionEndscreenFailedHMenuDialog, MENUROOT_MPENDSCREEN);
|
||||
}
|
||||
} else {
|
||||
// Bond - completed
|
||||
if (optionsGetScreenSplit() == SCREENSPLIT_VERTICAL) {
|
||||
if (optionsGetScreenSplit() == SCREENSPLIT_VERTICAL
|
||||
#ifndef PLATFORM_N64
|
||||
|| LOCALPLAYERCOUNT() >= 3
|
||||
#endif
|
||||
) {
|
||||
menuPushRootDialog(&g_2PMissionEndscreenCompletedVMenuDialog, MENUROOT_MPENDSCREEN);
|
||||
} else {
|
||||
menuPushRootDialog(&g_2PMissionEndscreenCompletedHMenuDialog, MENUROOT_MPENDSCREEN);
|
||||
@@ -1810,20 +1847,28 @@ void endscreenPushAnti(void)
|
||||
filemgrSaveOrLoad(&g_GameFileGuid, FILEOP_SAVE_GAME_000, 0);
|
||||
} else {
|
||||
#if VERSION >= VERSION_NTSC_1_0 && defined(DEBUG)
|
||||
if (!g_Vars.anti->aborted && (g_Vars.bond->isdead || g_Vars.bond->aborted || !objectiveIsAllComplete()) && !debugIsSetCompleteEnabled())
|
||||
if (!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()))
|
||||
if (!ANTI_ABORTED() && (g_Vars.bond->isdead || g_Vars.bond->aborted || !objectiveIsAllComplete()))
|
||||
#endif
|
||||
{
|
||||
// Anti - completed
|
||||
if (optionsGetScreenSplit() == SCREENSPLIT_VERTICAL) {
|
||||
if (optionsGetScreenSplit() == SCREENSPLIT_VERTICAL
|
||||
#ifndef PLATFORM_N64
|
||||
|| LOCALPLAYERCOUNT() >= 3
|
||||
#endif
|
||||
) {
|
||||
menuPushRootDialog(&g_2PMissionEndscreenCompletedVMenuDialog, MENUROOT_MPENDSCREEN);
|
||||
} else {
|
||||
menuPushRootDialog(&g_2PMissionEndscreenCompletedHMenuDialog, MENUROOT_MPENDSCREEN);
|
||||
}
|
||||
} else {
|
||||
// Anti - failed or aborted
|
||||
if (optionsGetScreenSplit() == SCREENSPLIT_VERTICAL) {
|
||||
if (optionsGetScreenSplit() == SCREENSPLIT_VERTICAL
|
||||
#ifndef PLATFORM_N64
|
||||
|| LOCALPLAYERCOUNT() >= 3
|
||||
#endif
|
||||
) {
|
||||
menuPushRootDialog(&g_2PMissionEndscreenFailedVMenuDialog, MENUROOT_MPENDSCREEN);
|
||||
} else {
|
||||
menuPushRootDialog(&g_2PMissionEndscreenFailedHMenuDialog, MENUROOT_MPENDSCREEN);
|
||||
|
||||
+15
-3
@@ -847,7 +847,7 @@ void explosionInflictDamage(struct prop *expprop)
|
||||
minfrac = (minfrac * 0.7f + 0.3f) * type->damage;
|
||||
|
||||
if (g_Vars.antiplayernum >= 0
|
||||
&& g_Vars.antiplayernum == exp->owner
|
||||
&& EXPLOSION_OWNER_IS_ANTI_PLAYER(exp->owner)
|
||||
&& (obj->flags2 & OBJFLAG2_IMMUNETOANTI)) {
|
||||
// anti cannot damage this obj
|
||||
} else if (isfirstframe) {
|
||||
@@ -997,8 +997,16 @@ void explosionInflictDamage(struct prop *expprop)
|
||||
ownerprop = g_Vars.bond->prop;
|
||||
} else if (g_Vars.coopplayernum >= 0 && exp->owner == g_Vars.coopplayernum) {
|
||||
ownerprop = g_Vars.coop->prop;
|
||||
} else if (g_Vars.antiplayernum >= 0 && exp->owner == g_Vars.antiplayernum) {
|
||||
} else if (g_Vars.antiplayernum >= 0 && EXPLOSION_OWNER_IS_ANTI_PLAYER(exp->owner)) {
|
||||
#if PLATFORM_N64
|
||||
ownerprop = g_Vars.anti->prop;
|
||||
#else
|
||||
struct chrdata *ownerchr = mpGetChrFromPlayerIndex(exp->owner);
|
||||
|
||||
if (ownerchr) {
|
||||
ownerprop = ownerchr->prop;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
chrDamageByExplosion(chr, minfrac, &spa0, ownerprop, &expprop->pos);
|
||||
@@ -1212,8 +1220,12 @@ u32 explosionTick(struct prop *prop)
|
||||
|
||||
if (g_Vars.normmplayerisrunning) {
|
||||
chr = mpGetChrFromPlayerIndex(exp->owner);
|
||||
} else if (g_Vars.antiplayernum >= 0 && exp->owner == g_Vars.antiplayernum) {
|
||||
} else if (g_Vars.antiplayernum >= 0 && EXPLOSION_OWNER_IS_ANTI_PLAYER(exp->owner)) {
|
||||
#if PLATFORM_N64
|
||||
chr = g_Vars.anti->prop->chr;
|
||||
#else
|
||||
chr = mpGetChrFromPlayerIndex(exp->owner);
|
||||
#endif
|
||||
} else if (g_Vars.coopplayernum >= 0 && exp->owner == g_Vars.coopplayernum) {
|
||||
chr = g_Vars.coop->prop->chr;
|
||||
} else {
|
||||
|
||||
+118
-1
@@ -748,6 +748,7 @@ MenuItemHandlerResult menuhandlerAcceptMission(s32 operation, struct menuitem *i
|
||||
setNumPlayers(1);
|
||||
}
|
||||
} else if (g_MissionConfig.isanti) {
|
||||
#ifdef PLATFORM_N64
|
||||
if (g_Vars.pendingantiplayernum == 1) {
|
||||
g_Vars.bondplayernum = 0;
|
||||
g_Vars.antiplayernum = 1;
|
||||
@@ -757,7 +758,27 @@ MenuItemHandlerResult menuhandlerAcceptMission(s32 operation, struct menuitem *i
|
||||
}
|
||||
|
||||
g_Vars.coopplayernum = -1;
|
||||
|
||||
setNumPlayers(2);
|
||||
#else
|
||||
u32 contmask = joyGetConnectedControllers();
|
||||
u32 plrcount = 0;
|
||||
u32 tmpmask;
|
||||
|
||||
// Count all players
|
||||
tmpmask = contmask;
|
||||
while (tmpmask) {
|
||||
plrcount += (tmpmask & 0x1);
|
||||
tmpmask >>= 1;
|
||||
}
|
||||
|
||||
g_Vars.bondplayernum = g_Vars.pendingantiplayernum ^ 1;
|
||||
g_Vars.antiplayernum = (g_Vars.bondplayernum == 0 ? 1 : 0);
|
||||
g_Vars.coopplayernum = -1;
|
||||
|
||||
setNumPlayers(plrcount);
|
||||
g_MpSetup.chrslots = contmask;
|
||||
#endif
|
||||
} else {
|
||||
// Solo
|
||||
g_Vars.bondplayernum = 0;
|
||||
@@ -1545,6 +1566,8 @@ MenuItemHandlerResult menuhandlerAntiRadar(s32 operation, struct menuitem *item,
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef PLATFORM_N64
|
||||
|
||||
MenuItemHandlerResult menuhandlerAntiPlayer(s32 operation, struct menuitem *item, union handlerdata *data)
|
||||
{
|
||||
const u16 labels[] = {L_OPTIONS_271, L_OPTIONS_272};
|
||||
@@ -1611,6 +1634,100 @@ struct menuitem g_AntiOptionsMenuItems[] = {
|
||||
{ MENUITEMTYPE_END },
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
MenuItemHandlerResult menuhandlerAntiMainPlayer(s32 operation, struct menuitem *item, union handlerdata *data)
|
||||
{
|
||||
static const char *labels[] = {
|
||||
"Player 1",
|
||||
"Player 2",
|
||||
"Player 3",
|
||||
"Player 4",
|
||||
};
|
||||
|
||||
// For consistency with the main save format,
|
||||
// the main player is (pendingantiplayernum XOR 1)
|
||||
|
||||
// g_Vars.(bond|anti|coop)playernum is based on the n'th player slot, not the n'th controller;
|
||||
// that is, it's not based on g_MpSetup.chrslots.
|
||||
// Because of this, it's easier just to change the label.
|
||||
|
||||
u32 tmpmask = joyGetConnectedControllers();
|
||||
u32 plrcount = 0;
|
||||
u32 labelidx = 0;
|
||||
while (tmpmask) {
|
||||
plrcount += (tmpmask & 0x1);
|
||||
if (plrcount <= data->dropdown.value) {
|
||||
labelidx += 1;
|
||||
}
|
||||
tmpmask >>= 1;
|
||||
}
|
||||
|
||||
switch (operation) {
|
||||
case MENUOP_GETOPTIONCOUNT:
|
||||
data->dropdown.value = plrcount;
|
||||
break;
|
||||
case MENUOP_GETOPTIONTEXT:
|
||||
return (s32) (labels[labelidx]);
|
||||
case MENUOP_SET:
|
||||
g_Vars.pendingantiplayernum = data->dropdown.value ^ 1;
|
||||
g_Vars.modifiedfiles |= MODFILE_GAME;
|
||||
break;
|
||||
case MENUOP_GETSELECTEDINDEX:
|
||||
data->dropdown.value = g_Vars.pendingantiplayernum ^ 1;
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct menuitem g_AntiOptionsMenuItems[] = {
|
||||
{
|
||||
MENUITEMTYPE_CHECKBOX,
|
||||
0,
|
||||
0,
|
||||
L_OPTIONS_267, // "Radar On"
|
||||
0,
|
||||
menuhandlerAntiRadar,
|
||||
},
|
||||
{
|
||||
MENUITEMTYPE_DROPDOWN,
|
||||
0,
|
||||
MENUITEMFLAG_LITERAL_TEXT,
|
||||
(uintptr_t)"Main Player",
|
||||
0,
|
||||
menuhandlerAntiMainPlayer,
|
||||
},
|
||||
{
|
||||
MENUITEMTYPE_SEPARATOR,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
NULL,
|
||||
},
|
||||
{
|
||||
MENUITEMTYPE_SELECTABLE,
|
||||
0,
|
||||
0,
|
||||
L_OPTIONS_269, // "Continue"
|
||||
0,
|
||||
menuhandlerBuddyOptionsContinue,
|
||||
},
|
||||
{
|
||||
MENUITEMTYPE_SELECTABLE,
|
||||
0,
|
||||
MENUITEMFLAG_SELECTABLE_CLOSESDIALOG,
|
||||
L_OPTIONS_270, // "Cancel"
|
||||
0,
|
||||
NULL,
|
||||
},
|
||||
{ MENUITEMTYPE_END },
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
struct menudialogdef g_AntiOptionsMenuDialog = {
|
||||
MENUDIALOGTYPE_DEFAULT,
|
||||
L_OPTIONS_266, // "Counter-Operative Options"
|
||||
@@ -4854,7 +4971,7 @@ MenuItemHandlerResult menuhandlerMainMenuCooperative(s32 operation, struct menui
|
||||
MenuItemHandlerResult menuhandlerMainMenuCounterOperative(s32 operation, struct menuitem *item, union handlerdata *data)
|
||||
{
|
||||
if (operation == MENUOP_CHECKDISABLED) {
|
||||
if ((joyGetConnectedControllers() & 2) == 0) {
|
||||
if ((joyGetConnectedControllers() & ~0x1) == 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -800,7 +800,11 @@ void mpPushPauseDialog(void)
|
||||
menuPushRootDialog(&g_MpPausePlayerRankingMenuDialog, MENUROOT_MPPAUSE);
|
||||
}
|
||||
} else {
|
||||
if (optionsGetScreenSplit() == SCREENSPLIT_VERTICAL) {
|
||||
if (optionsGetScreenSplit() == SCREENSPLIT_VERTICAL
|
||||
#ifndef PLATFORM_N64
|
||||
|| LOCALPLAYERCOUNT() >= 3
|
||||
#endif
|
||||
) {
|
||||
menuPushRootDialog(&g_2PMissionPauseVMenuDialog, MENUROOT_MPPAUSE);
|
||||
} else {
|
||||
menuPushRootDialog(&g_2PMissionPauseHMenuDialog, MENUROOT_MPPAUSE);
|
||||
|
||||
@@ -256,7 +256,15 @@ 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
|
||||
// Counter-Operative now uses a different approach which allows more than 2 players.
|
||||
// Co-Operative, on the other hand, is currently limited to 2 players.
|
||||
// Due to the change in approach, it's better to ignore 2.x controls for Counter-Operative.
|
||||
if (g_Vars.coopplayernum >= 0)
|
||||
#endif
|
||||
{
|
||||
struct mpplayerconfig tmp;
|
||||
|
||||
tmp = g_PlayerConfigsArray[MAX_PLAYERS];
|
||||
@@ -1333,7 +1341,7 @@ 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))
|
||||
&& !(g_Vars.antiplayernum >= 0 && ((g_Vars.currentplayer != g_Vars.anti || g_InCutscene)))
|
||||
&& !(g_Vars.antiplayernum >= 0 && ((PLAYER_IS_NOT_ANTI(g_Vars.currentplayer) || g_InCutscene)))
|
||||
&& g_NumReasonsToEndMpMatch == 0) {
|
||||
// Render "Press START" text
|
||||
gdl = text0f153628(gdl);
|
||||
|
||||
+5
-5
@@ -606,7 +606,7 @@ void playerStartNewLife(void)
|
||||
if (cmd);
|
||||
if (cmd);
|
||||
|
||||
if (g_Vars.antiplayernum < 0 || g_Vars.currentplayer != g_Vars.anti) {
|
||||
if (g_Vars.antiplayernum < 0 || PLAYER_IS_NOT_ANTI(g_Vars.currentplayer)) {
|
||||
while (cmd[0] != INTROCMD_END) {
|
||||
switch (cmd[0]) {
|
||||
case INTROCMD_SPAWN:
|
||||
@@ -980,7 +980,7 @@ void playerSpawn(void)
|
||||
}
|
||||
|
||||
if (g_Vars.mplayerisrunning) {
|
||||
if (g_Vars.antiplayernum >= 0 && g_Vars.currentplayer == g_Vars.anti) {
|
||||
if (g_Vars.antiplayernum >= 0 && PLAYER_IS_ANTI(g_Vars.currentplayer)) {
|
||||
numsqdists = 0;
|
||||
force = false;
|
||||
|
||||
@@ -1182,7 +1182,7 @@ void playerChooseBodyAndHead(s32 *bodynum, s32 *headnum, s32 *arg2)
|
||||
bool solo;
|
||||
|
||||
if (g_Vars.antiplayernum >= 0
|
||||
&& g_Vars.currentplayer == g_Vars.anti
|
||||
&& PLAYER_IS_ANTI(g_Vars.currentplayer)
|
||||
&& g_Vars.antiheadnum >= 0
|
||||
&& g_Vars.antibodynum >= 0) {
|
||||
*headnum = g_Vars.antiheadnum;
|
||||
@@ -1514,7 +1514,7 @@ void playerTickChrBody(void)
|
||||
|
||||
#if VERSION >= VERSION_NTSC_1_0
|
||||
if (g_Vars.antiplayernum >= 0
|
||||
&& g_Vars.currentplayer == g_Vars.anti
|
||||
&& PLAYER_IS_ANTI(g_Vars.currentplayer)
|
||||
&& g_Vars.currentplayer->vv_eyeheight > 159) {
|
||||
g_Vars.currentplayer->vv_eyeheight = 159;
|
||||
}
|
||||
@@ -4713,7 +4713,7 @@ Gfx *playerRenderHud(Gfx *gdl)
|
||||
chr->chrflags |= CHRCFLAG_HIDDEN;
|
||||
}
|
||||
|
||||
if (g_Vars.antiplayernum >= 0 && g_Vars.currentplayer == g_Vars.anti) {
|
||||
if (g_Vars.antiplayernum >= 0 && PLAYER_IS_ANTI(g_Vars.currentplayer)) {
|
||||
// Anti
|
||||
#ifndef PLATFORM_N64
|
||||
if (g_NetMode == NETMODE_SERVER && g_Vars.currentplayer->isremote) {
|
||||
|
||||
@@ -186,7 +186,8 @@ 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 && PLAYER_IS_NOT_ANTI(g_Vars.currentplayer)) {
|
||||
|
||||
modelmgrLoadProjectileModeldefs(cmd->param1);
|
||||
|
||||
if (cmd->param2 >= 0) {
|
||||
@@ -213,7 +214,7 @@ 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 && PLAYER_IS_NOT_ANTI(g_Vars.currentplayer)) {
|
||||
bgunSetAmmoQuantity(cmd->param1, cmd->param2);
|
||||
}
|
||||
cmd = (struct cmd32 *)((uintptr_t)cmd + 16);
|
||||
|
||||
+2
-1
@@ -2362,7 +2362,8 @@ void propsTestForPickup(void)
|
||||
|
||||
if (g_Vars.currentplayer->bondmovemode != MOVEMODE_CUTSCENE
|
||||
&& !g_PlayerInvincible
|
||||
&& g_Vars.currentplayer != g_Vars.anti) {
|
||||
&& PLAYER_IS_NOT_ANTI(g_Vars.currentplayer)
|
||||
) {
|
||||
roomsCopy(g_Vars.currentplayer->prop->rooms, allrooms);
|
||||
|
||||
for (i = 0; g_Vars.currentplayer->prop->rooms[i] != -1; i++) {
|
||||
|
||||
+5
-2
@@ -9148,7 +9148,7 @@ void autogunTickShoot(struct prop *autogunprop)
|
||||
// (ie. autogun is a Defense autogun or a thrown laptop)
|
||||
if (g_Vars.normmplayerisrunning
|
||||
|| (targetprop && (targetprop->type == PROPTYPE_CHR))
|
||||
|| (g_Vars.antiplayernum >= 0 && targetprop && targetprop == g_Vars.anti->prop)) {
|
||||
|| (g_Vars.antiplayernum >= 0 && targetprop && PROP_IS_FOR_ANTI_PLAYER(targetprop))) {
|
||||
if (cdExamLos08(&gunpos, gunrooms, &hitpos, CDTYPE_ALL, GEOFLAG_BLOCK_SHOOT) == CDRESULT_COLLISION) {
|
||||
#if VERSION >= VERSION_PAL_FINAL
|
||||
cdGetPos(&hitpos, 11480, "prop/propobj.c");
|
||||
@@ -15942,7 +15942,10 @@ 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
|
||||
|| PLAYER_IS_NOT_ANTI(g_Vars.currentplayer)
|
||||
|| (obj->flags2 & OBJFLAG2_IMMUNETOANTI) == 0) {
|
||||
|
||||
if (hit->hitthing.texturenum != 10000) {
|
||||
f32 damage = gsetGetDamage(&shotdata->gset);
|
||||
|
||||
|
||||
+20
-1
@@ -20,8 +20,13 @@
|
||||
#define MAX_CHRWAYPOINTS 6
|
||||
#define MAX_EXPLOSIONS 6
|
||||
#define MAX_EYESPYDARTS 8
|
||||
#ifdef PLATFORM_N64
|
||||
#define MAX_COOPCHRS 2
|
||||
#else
|
||||
#define MAX_COOPCHRS MAX_PLAYERS
|
||||
#endif
|
||||
#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
|
||||
@@ -81,6 +86,20 @@
|
||||
#define PLAYERCOUNT() 1
|
||||
#endif
|
||||
|
||||
#if MAX_COOPCHRS > 2
|
||||
#define PLAYER_IS_ANTI(plr) (g_Vars.antiplayernum >= 0 && (plr) != g_Vars.bond)
|
||||
#define PLAYER_IS_NOT_ANTI(plr) (g_Vars.antiplayernum < 0 || (plr) == g_Vars.bond)
|
||||
#define PLAYERNUM_IS_ANTI(plrnum) (g_Vars.antiplayernum >= 0 && (plrnum) != g_Vars.bondplayernum)
|
||||
#define PROP_IS_FOR_ANTI_PLAYER(plrprop) (g_Vars.antiplayernum >= 0 && g_Vars.anti && (plrprop)->type == PROPTYPE_PLAYER && (plrprop) != g_Vars.bond->prop)
|
||||
#define EXPLOSION_OWNER_IS_ANTI_PLAYER(expowner) (g_Vars.antiplayernum >= 0 && (expowner) != g_Vars.bondplayernum && mpGetChrFromPlayerIndex((expowner)) != NULL)
|
||||
#else
|
||||
#define PLAYER_IS_ANTI(plr) ((plr) == g_Vars.anti)
|
||||
#define PLAYER_IS_NOT_ANTI(plr) ((plr) != g_Vars.anti)
|
||||
//define PLAYERNUM_IS_ANTI(plrnum) ((plrnum) == g_Vars.antiplayernum)
|
||||
#define PROP_IS_FOR_ANTI_PLAYER(plrprop) ((plrprop) == g_Vars.anti->prop)
|
||||
#define EXPLOSION_OWNER_IS_ANTI_PLAYER(expowner) ((expowner) == g_Vars.antiplayernum)
|
||||
#endif
|
||||
|
||||
#define VALIDWEAPON() (g_Vars.currentplayer->gunctrl.weaponnum >= WEAPON_UNARMED && g_Vars.currentplayer->gunctrl.weaponnum <= WEAPON_COMBATBOOST)
|
||||
#define FUNCISSEC() (VALIDWEAPON() && (g_PlayerConfigsArray[g_Vars.currentplayerstats->mpindex].gunfuncs[(g_Vars.currentplayer->gunctrl.weaponnum - 1) >> 3] & (1 << ((g_Vars.currentplayer->gunctrl.weaponnum - 1) & 7))))
|
||||
|
||||
|
||||
Reference in new issue
Block a user