Merge pull request #388 from iamgreaser/gm/net/counterop-4player

port-net: Extend counter-op mode to 4 players
This commit is contained in:
fgsfds authored and GitHub committed 2024-03-09 16:58:31 +01:00
commit 7667d37ff0
15 files changed
+285 -37

No files matched your search

+8
View File
@@ -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
View File
@@ -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
View File
@@ -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;
}
+6 -4
View File
@@ -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;
+28
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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;
}
}
+5 -1
View File
@@ -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);
+10 -2
View File
@@ -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
View File
@@ -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) {
+3 -2
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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))))