Implement MFE_TEAMITEM

This commit is contained in:
Lactozilla 2023-08-14 14:44:41 -03:00
parent 73f759d76e
commit fac87627a4
6 changed files with 41 additions and 30 deletions

View file

@ -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
};

View file

@ -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)

View file

@ -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,15 +3655,20 @@ 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))
if (source && source->player)
{
if (source->player->ctfteam != target->extravalue1)
return false;
if (target->type == MT_RING_BLUEBOX && !(source->player->ctfteam == TEAM_BLUE))
}
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))
{

View file

@ -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

View file

@ -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;

View file

@ -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;
//