diff --git a/src/deh_tables.c b/src/deh_tables.c index c25621861..46eaf1072 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -4407,6 +4407,7 @@ const char *const MOBJEFLAG_LIST[] = { "TRACERANGLE", // Compute and trigger on mobj angle relative to tracer "FORCESUPER", // Forces an object to use super sprites with SPR_PLAY. "FORCENOSUPER", // Forces an object to NOT use super sprites with SPR_PLAY. + "TEAMITEM", // Object is a team item "TEAMFLAG", // Object is a team flag NULL }; diff --git a/src/p_enemy.c b/src/p_enemy.c index 318a9e974..859702b4c 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -823,9 +823,8 @@ static boolean P_LookForShield(mobj_t *actor) if (!player->mo || player->mo->health <= 0) continue; // dead - //When in CTF, don't pull rings that you cannot pick up. - if ((actor->type == MT_REDTEAMRING && player->ctfteam != G_GetTeam(TEAM_RED)) || - (actor->type == MT_BLUETEAMRING && player->ctfteam != G_GetTeam(TEAM_BLUE))) + // Don't pull rings that you cannot pick up. + if ((actor->eflags & MFE_TEAMITEM) && player->ctfteam != actor->extravalue1) continue; if ((player->powers[pw_shield] & SH_PROTECTELECTRIC) diff --git a/src/p_inter.c b/src/p_inter.c index 1959595ec..f04c2fa37 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -413,6 +413,10 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) if (LUA_HookTouchSpecial(special, toucher) || P_MobjWasRemoved(special)) return; + // Don't collide with items meant for opposing teams + if (special->eflags & MFE_TEAMITEM && player->ctfteam != special->extravalue1) + return; + // 0 = none, 1 = elemental pierce, 2 = bubble bounce elementalpierce = (((player->powers[pw_shield] & SH_NOSTACK) == SH_ELEMENTAL || (player->powers[pw_shield] & SH_NOSTACK) == SH_BUBBLEWRAP) && (player->pflags & PF_SHIELDABILITY) ? (((player->powers[pw_shield] & SH_NOSTACK) == SH_ELEMENTAL) ? 1 : 2) @@ -625,21 +629,13 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) // ***************************************** // // Rings, coins, spheres, weapon panels, etc // // ***************************************** // - case MT_REDTEAMRING: - if (player->ctfteam != G_GetTeam(TEAM_RED)) - return; - P_CollectRing(player, special); - break; - case MT_BLUETEAMRING: - if (player->ctfteam != G_GetTeam(TEAM_BLUE)) - return; - P_CollectRing(player, special); - break; case MT_RING: case MT_FLINGRING: case MT_COIN: case MT_FLINGCOIN: case MT_NIGHTSSTAR: + case MT_REDTEAMRING: + case MT_BLUETEAMRING: P_CollectRing(player, special); break; case MT_BLUESPHERE: @@ -3659,14 +3655,19 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da if (target->flags2 & MF2_SKULLFLY) target->momx = target->momy = target->momz = 0; - if (!force) + // Don't damage items meant for opposing teams + if (target->eflags & MFE_TEAMITEM && !force) { - // Special case for team ring boxes - if (target->type == MT_RING_REDBOX && !(source->player->ctfteam == TEAM_RED)) - return false; - - if (target->type == MT_RING_BLUEBOX && !(source->player->ctfteam == TEAM_BLUE)) + if (source && source->player) + { + if (source->player->ctfteam != target->extravalue1) + return false; + } + else + { + // If the originator of the attack is not a player, then the item cannot be damaged. return false; + } } if (target->flags & (MF_ENEMY|MF_BOSS)) diff --git a/src/p_map.c b/src/p_map.c index f6176fc54..5de3cfe31 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -1691,7 +1691,7 @@ static boolean PIT_CheckThing(mobj_t *thing) } // Monitor? else if (thing->flags & MF_MONITOR - && !((thing->type == MT_RING_REDBOX && tmthing->player->ctfteam != G_GetTeam(TEAM_RED)) || (thing->type == MT_RING_BLUEBOX && tmthing->player->ctfteam != G_GetTeam(TEAM_BLUE))) + && !((thing->eflags & MFE_TEAMITEM) && tmthing->player->ctfteam != thing->extravalue1) && (!(thing->flags & MF_SOLID) || P_PlayerCanDamage(tmthing->player, thing))) { if (thing->z - thing->scale <= tmthing->z + tmthing->height diff --git a/src/p_mobj.c b/src/p_mobj.c index 2fbb7511a..942edff65 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -10559,6 +10559,8 @@ static fixed_t P_DefaultMobjShadowScale (mobj_t *thing) case MT_REDTEAMRING: case MT_BLUETEAMRING: + case MT_REDFLAG: + case MT_BLUEFLAG: case MT_EMBLEM: @@ -10596,9 +10598,7 @@ static fixed_t P_DefaultMobjShadowScale (mobj_t *thing) return FRACUNIT; default: - if (thing->eflags & MFE_TEAMFLAG) - return 2*FRACUNIT/3; - else if (thing->flags & (MF_ENEMY|MF_BOSS)) + if (thing->flags & (MF_ENEMY|MF_BOSS)) return FRACUNIT; else return 0; @@ -10894,10 +10894,18 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) mobj->lastlook = mobj->extravalue2 = -1; break; case MT_REDTEAMRING: - mobj->color = G_GetTeamWeaponColor(G_GetTeam(TEAM_RED)); + case MT_RING_REDBOX: + mobj->extravalue1 = G_GetTeam(TEAM_RED); + mobj->eflags |= MFE_TEAMITEM; + if (mobj->type == MT_REDTEAMRING) + mobj->color = G_GetTeamWeaponColor(mobj->extravalue1); break; case MT_BLUETEAMRING: - mobj->color = G_GetTeamWeaponColor(G_GetTeam(TEAM_BLUE)); + case MT_RING_BLUEBOX: + mobj->extravalue1 = G_GetTeam(TEAM_BLUE); + mobj->eflags |= MFE_TEAMITEM; + if (mobj->type == MT_BLUETEAMRING) + mobj->color = G_GetTeamWeaponColor(mobj->extravalue1); break; case MT_RING: case MT_COIN: @@ -13256,6 +13264,9 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean break; } + // Team flags don't have MFE_TEAMITEM, because other players must be able to collide with them. + // If team flags had MFE_TEAMITEM, then players belonging to opposing teams would not be able to + // capture the flags. if (mthing->type == THING_TYPE_CTF_TEAM_FLAG) mobj->eflags |= MFE_TEAMFLAG; diff --git a/src/p_mobj.h b/src/p_mobj.h index 6f81c5258..fd959588d 100644 --- a/src/p_mobj.h +++ b/src/p_mobj.h @@ -225,8 +225,7 @@ typedef enum // The mobj stands in a sector with water, and touches the surface // this bit is set once and for all at the start of mobjthinker MFE_TOUCHWATER = 1<<2, - // The mobj stands in a sector with water, and his waist is BELOW the water surface - // (for player, allows swimming up/down) + // The mobj stands in a sector with water, and its waist is BELOW the water surface MFE_UNDERWATER = 1<<3, // used for ramp sectors MFE_JUSTSTEPPEDDOWN = 1<<4, @@ -251,10 +250,10 @@ typedef enum MFE_FORCENOSUPER = 1<<13, // Makes an object use super sprites where they wouldn't have otherwise and vice-versa MFE_REVERSESUPER = MFE_FORCESUPER|MFE_FORCENOSUPER, + // Object is a team item - only players belonging to the same team as the item can collide with them + MFE_TEAMITEM = 1<<14, // Object is a team flag - MFE_TEAMFLAG = 1<<14, - - // free: 1<<15 + MFE_TEAMFLAG = 1<<15 } mobjeflag_t; //