Introducing player->powers[pw_carry]! Also, I made rope hangs a lot smoother.

* PF_ITEMHANG -> CR_GENERIC
* PF_CARRIED -> CR_PLAYER
* (mo->tracer == MT_TUBEWAYPOINT) -> CR_ZOOMTUBE
* PF_ROPEHANG -> CR_ROPEHANG
* PF_MACESPIN -> CR_MACESPIN
This commit is contained in:
toasterbabe 2016-09-23 23:48:48 +01:00
parent dcb82c292a
commit e16648a72b
10 changed files with 254 additions and 332 deletions

View File

@ -41,12 +41,13 @@ static inline void B_BuildTailsTiccmd(mobj_t *sonic, mobj_t *tails, ticcmd_t *cm
return;
#endif
if (tails->player->pflags & (PF_MACESPIN|PF_ITEMHANG))
if (tails->player->powers[pw_carry] == CR_MACESPIN || tails->player->powers[pw_carry] == CR_GENERIC)
{
boolean isrelevant = (sonic->player->powers[pw_carry] == CR_MACESPIN || sonic->player->powers[pw_carry] == CR_GENERIC);
dist = P_AproxDistance(tails->x-sonic->x, tails->y-sonic->y);
if (sonic->player->cmd.buttons & BT_JUMP && sonic->player->pflags & (PF_JUMPED|PF_MACESPIN|PF_ITEMHANG))
if (sonic->player->cmd.buttons & BT_JUMP && (sonic->player->pflags & PF_JUMPED) && isrelevant)
cmd->buttons |= BT_JUMP;
if (sonic->player->pflags & (PF_MACESPIN|PF_ITEMHANG))
if (isrelevant)
{
cmd->forwardmove = sonic->player->cmd.forwardmove;
cmd->angleturn = abs((signed)(tails->angle - sonic->angle))>>16;
@ -211,8 +212,9 @@ boolean B_CheckRespawn(player_t *player)
// Check if Sonic is busy first.
// If he's doing any of these things, he probably doesn't want to see us.
if (sonic->player->pflags & (PF_ROPEHANG|PF_GLIDING|PF_CARRIED|PF_SLIDING|PF_ITEMHANG|PF_MACESPIN|PF_NIGHTSMODE)
|| (sonic->player->panim != PA_IDLE && sonic->player->panim != PA_WALK))
if (sonic->player->pflags & (PF_GLIDING|PF_SLIDING|PF_NIGHTSMODE)
|| (sonic->player->panim != PA_IDLE && sonic->player->panim != PA_WALK)
|| (sonic->player->powers[pw_carry]))
return false;
// Low ceiling, do not want!

View File

@ -44,6 +44,7 @@ typedef enum
SF_STOMPDAMAGE = 1<<9, // Always damage enemies, etc by landing on them, no matter your vunerability?
SF_MARIODAMAGE = SF_NOJUMPDAMAGE|SF_STOMPDAMAGE, // The Mario method of being able to damage enemies, etc.
SF_MACHINE = 1<<10, // Beep boop. Are you a robot?
// free up to and including 1<<31
} skinflags_t;
//Primary and secondary skin abilities
@ -128,40 +129,28 @@ typedef enum
// Are you gliding?
PF_GLIDING = 1<<16,
// Tails pickup!
PF_CARRIED = 1<<17,
// Sliding (usually in water) like Labyrinth/Oil Ocean
PF_SLIDING = 1<<18,
// Hanging on a rope
PF_ROPEHANG = 1<<19,
// Hanging on an item of some kind - zipline, chain, etc. (->tracer)
PF_ITEMHANG = 1<<20,
// On the mace chain spinning around (->tracer)
PF_MACESPIN = 1<<21,
PF_SLIDING = 1<<17,
/*** NIGHTS STUFF ***/
// Is the player in NiGHTS mode?
PF_NIGHTSMODE = 1<<22,
PF_TRANSFERTOCLOSEST = 1<<23,
PF_NIGHTSMODE = 1<<18,
PF_TRANSFERTOCLOSEST = 1<<19,
// Spill rings after falling
PF_NIGHTSFALL = 1<<24,
PF_DRILLING = 1<<25,
PF_SKIDDOWN = 1<<26,
PF_NIGHTSFALL = 1<<20,
PF_DRILLING = 1<<21,
PF_SKIDDOWN = 1<<22,
/*** TAG STUFF ***/
PF_TAGGED = 1<<27, // Player has been tagged and awaits the next round in hide and seek.
PF_TAGIT = 1<<28, // The player is it! For Tag Mode
PF_TAGGED = 1<<23, // Player has been tagged and awaits the next round in hide and seek.
PF_TAGIT = 1<<24, // The player is it! For Tag Mode
/*** misc ***/
PF_FORCESTRAFE = 1<<29, // Turning inputs are translated into strafing inputs
PF_ANALOGMODE = 1<<30, // Analog mode?
PF_FORCESTRAFE = 1<<25, // Turning inputs are translated into strafing inputs
PF_ANALOGMODE = 1<<26, // Analog mode?
// free: 1<<30 and 1<<31
// free up to and including 1<<31
} pflags_t;
typedef enum
@ -204,7 +193,20 @@ typedef enum
SH_STACK = SH_FIREFLOWER,
SH_NOSTACK = ~SH_STACK
} shieldtype_t;
} shieldtype_t; // pw_shield
typedef enum
{
CR_NONE = 0,
// The generic case is suitable for most objects.
CR_GENERIC,
// Tails carry.
CR_PLAYER,
// Specific level gimmicks.
CR_ZOOMTUBE,
CR_ROPEHANG,
CR_MACESPIN
} carrytype_t; // pw_carry
// Player powers. (don't edit this comment)
typedef enum
@ -213,6 +215,7 @@ typedef enum
pw_sneakers,
pw_flashing,
pw_shield,
pw_carry,
pw_tailsfly, // tails flying
pw_underwater, // underwater timer
pw_spacetime, // In space, no one can hear you spin!

View File

@ -6750,21 +6750,9 @@ static const char *const PLAYERFLAG_LIST[] = {
// Are you gliding?
"GLIDING",
// Tails pickup!
"CARRIED",
// Sliding (usually in water) like Labyrinth/Oil Ocean
"SLIDING",
// Hanging on a rope
"ROPEHANG",
// Hanging on an item of some kind - zipline, chain, etc. (->tracer)
"ITEMHANG",
// On the mace chain spinning around (->tracer)
"MACESPIN",
/*** NIGHTS STUFF ***/
// Is the player in NiGHTS mode?
"NIGHTSMODE",
@ -6903,6 +6891,7 @@ static const char *const POWERS_LIST[] = {
"SNEAKERS",
"FLASHING",
"SHIELD",
"CARRY",
"TAILSFLY", // tails flying
"UNDERWATER", // underwater timer
"SPACETIME", // In space, no one can hear you spin!
@ -7138,6 +7127,14 @@ struct {
{"SH_STACK",SH_STACK},
{"SH_NOSTACK",SH_NOSTACK},
// Carrying
{"CR_NONE",CR_NONE},
{"CR_GENERIC",CR_GENERIC},
{"CR_PLAYER",CR_PLAYER},
{"CR_ZOOMTUBE",CR_ZOOMTUBE},
{"CR_ROPEHANG",CR_ROPEHANG},
{"CR_MACESPIN",CR_MACESPIN},
// Ring weapons (ringweapons_t)
// Useful for A_GiveWeapon
{"RW_AUTO",RW_AUTO},

View File

@ -5428,8 +5428,8 @@ void A_MixUp(mobj_t *actor)
// Zoom tube stuff
mobj_t *tempthing = NULL; //tracer
pflags_t flags1,flags2; //player pflags
INT32 transspeed; //player speed
UINT16 carry1,carry2; //carry
INT32 transspeed; //player speed
// Starpost stuff
INT16 starpostx, starposty, starpostz;
@ -5466,8 +5466,8 @@ void A_MixUp(mobj_t *actor)
players[two].speed = transspeed;
//set flags variables now but DON'T set them.
flags1 = (players[one].pflags & (PF_ITEMHANG|PF_MACESPIN|PF_ROPEHANG));
flags2 = (players[two].pflags & (PF_ITEMHANG|PF_MACESPIN|PF_ROPEHANG));
carry1 = (players[one].powers[pw_carry] == CR_PLAYER ? CR_NONE : players[one].powers[pw_carry]);
carry2 = (players[two].powers[pw_carry] == CR_PLAYER ? CR_NONE : players[two].powers[pw_carry]);
x = players[one].mo->x;
y = players[one].mo->y;
@ -5492,12 +5492,10 @@ void A_MixUp(mobj_t *actor)
starpostnum, starposttime, starpostangle,
mflags2);
//flags set after mixup. Stupid P_ResetPlayer() takes away some of the flags we look for...
//but not all of them! So we need to make sure they aren't set wrong or anything.
players[one].pflags &= ~(PF_ITEMHANG|PF_MACESPIN|PF_ROPEHANG);
players[one].pflags |= flags2;
players[two].pflags &= ~(PF_ITEMHANG|PF_MACESPIN|PF_ROPEHANG);
players[two].pflags |= flags1;
//carry set after mixup. Stupid P_ResetPlayer() takes away some of the stuff we look for...
//but not all of it! So we need to make sure they aren't set wrong or anything.
players[one].powers[pw_carry] = carry2;
players[two].powers[pw_carry] = carry1;
teleported[one] = true;
teleported[two] = true;
@ -5509,8 +5507,9 @@ void A_MixUp(mobj_t *actor)
INT32 pindex[MAXPLAYERS], counter = 0, teleportfrom = 0;
// Zoom tube stuff
mobj_t *transtracer[MAXPLAYERS]; //tracer
pflags_t transflag[MAXPLAYERS]; //player pflags
mobj_t *transtracer[MAXPLAYERS]; //tracer
//pflags_t transflag[MAXPLAYERS]; //cyan pink white pink cyan
UINT16 transcarry[MAXPLAYERS]; //player carry
INT32 transspeed[MAXPLAYERS]; //player speed
// Star post stuff
@ -5544,7 +5543,7 @@ void A_MixUp(mobj_t *actor)
players[i].rmomx = players[i].rmomy = 1;
players[i].cmomx = players[i].cmomy = 0;
transflag[counter] = (players[i].pflags & (PF_ITEMHANG|PF_MACESPIN|PF_ROPEHANG));
transcarry[counter] = (players[i].powers[pw_carry] == CR_PLAYER ? CR_NONE : players[i].powers[pw_carry]);
transspeed[counter] = players[i].speed;
transtracer[counter] = players[i].mo->tracer;
@ -5596,9 +5595,8 @@ void A_MixUp(mobj_t *actor)
starpostnum[teleportfrom], starposttime[teleportfrom], starpostangle[teleportfrom],
flags2[teleportfrom]);
//...flags after. same reasoning.
players[i].pflags &= ~(PF_ITEMHANG|PF_MACESPIN|PF_ROPEHANG);
players[i].pflags |= transflag[teleportfrom];
//...carry after. same reasoning.
players[i].powers[pw_carry] = transcarry[teleportfrom];
teleported[i] = true;
counter++;
@ -6165,7 +6163,7 @@ void A_Boss7Chase(mobj_t *actor)
if (actor->health <= actor->info->damage
&& actor->target
&& actor->target->player
&& (actor->target->player->pflags & PF_ITEMHANG))
&& (actor->target->player->powers[pw_carry] == CR_GENERIC))
{
A_FaceTarget(actor);
P_SetMobjState(actor, S_BLACKEGG_SHOOT1);

View File

@ -1249,10 +1249,10 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
player->powers[pw_ingoop] = 2;
if (player->pflags & PF_ITEMHANG)
if (player->powers[pw_carry] == CR_GENERIC)
{
P_SetTarget(&toucher->tracer, NULL);
player->pflags &= ~PF_ITEMHANG;
player->powers[pw_carry] = CR_NONE;
}
P_ResetPlayer(player);
@ -1337,7 +1337,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
case MT_BIGMACECHAIN:
// Is this the last link in the chain?
if (toucher->momz > 0 || !(special->flags & MF_AMBUSH)
|| (player->pflags & PF_ITEMHANG) || (player->pflags & PF_MACESPIN))
|| (player->powers[pw_carry]))
return;
if (toucher->z > special->z + special->height/2)
@ -1354,12 +1354,12 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
if (special->target && (special->target->type == MT_SPINMACEPOINT || special->target->type == MT_HIDDEN_SLING))
{
player->pflags |= PF_MACESPIN;
player->powers[pw_carry] = CR_MACESPIN;
S_StartSound(toucher, sfx_spin);
P_SetPlayerMobjState(toucher, S_PLAY_SPIN);
}
else
player->pflags |= PF_ITEMHANG;
player->powers[pw_carry] = CR_GENERIC;
// Can't jump first frame
player->pflags |= PF_JUMPSTASIS;
@ -2623,7 +2623,9 @@ static inline boolean P_PlayerHitsPlayer(mobj_t *target, mobj_t *inflictor, mobj
static void P_KillPlayer(player_t *player, mobj_t *source, INT32 damage)
{
player->pflags &= ~(PF_CARRIED|PF_SLIDING|PF_ITEMHANG|PF_MACESPIN|PF_ROPEHANG|PF_NIGHTSMODE);
player->pflags &= ~(PF_SLIDING|PF_NIGHTSMODE);
player->powers[pw_carry] = CR_NONE;
// Burst weapons and emeralds in Match/CTF only
if (source && (gametype == GT_MATCH || gametype == GT_TEAMMATCH || gametype == GT_CTF))

View File

@ -302,9 +302,9 @@ static void P_DoTailsCarry(player_t *sonic, player_t *tails)
INT32 p;
fixed_t zdist; // z distance between the two players' bottoms
if ((tails->pflags & PF_CARRIED) && tails->mo->tracer == sonic->mo)
if (tails->powers[pw_carry] == CR_PLAYER)// && tails->mo->tracer == sonic->mo) <-- why was this here?
return;
if ((sonic->pflags & PF_CARRIED) && sonic->mo->tracer == tails->mo)
if (sonic->powers[pw_carry] == CR_PLAYER && sonic->mo->tracer == tails->mo)
return;
if (tails->charability != CA_FLY && tails->charability != CA_SWIM)
@ -319,8 +319,7 @@ static void P_DoTailsCarry(player_t *sonic, player_t *tails)
if (sonic->pflags & PF_NIGHTSMODE)
return;
if (sonic->mo->tracer && sonic->mo->tracer->type == MT_TUBEWAYPOINT
&& !(sonic->pflags & PF_ROPEHANG))
if (sonic->mo->tracer && sonic->powers[pw_carry] == CR_ZOOMTUBE)
return; // don't steal players from zoomtubes!
if ((sonic->mo->eflags & MFE_VERTICALFLIP) != (tails->mo->eflags & MFE_VERTICALFLIP))
@ -337,7 +336,7 @@ static void P_DoTailsCarry(player_t *sonic, player_t *tails)
// Search in case another player is already being carried by this fox.
for (p = 0; p < MAXPLAYERS; p++)
if (playeringame[p] && players[p].mo
&& players[p].pflags & PF_CARRIED && players[p].mo->tracer == tails->mo)
&& players[p].powers[pw_carry] == CR_PLAYER && players[p].mo->tracer == tails->mo)
return;
if (tails->mo->eflags & MFE_VERTICALFLIP)
@ -357,16 +356,16 @@ static void P_DoTailsCarry(player_t *sonic, player_t *tails)
|| (G_TagGametype() && (!(tails->pflags & PF_TAGIT) != !(sonic->pflags & PF_TAGIT)))
|| (gametype == GT_MATCH)
|| (G_GametypeHasTeams() && tails->ctfteam != sonic->ctfteam))
sonic->pflags &= ~PF_CARRIED; */
sonic->powers[pw_carry] = CR_NONE; */
if (tails->spectator || sonic->spectator)
sonic->pflags &= ~PF_CARRIED;
sonic->powers[pw_carry] = CR_NONE;
else
{
if (sonic-players == consoleplayer && botingame)
CV_SetValue(&cv_analog2, false);
P_ResetPlayer(sonic);
P_SetTarget(&sonic->mo->tracer, tails->mo);
sonic->pflags |= PF_CARRIED;
sonic->powers[pw_carry] = CR_PLAYER;
S_StartSound(sonic->mo, sfx_s3k4a);
P_UnsetThingPosition(sonic->mo);
sonic->mo->x = tails->mo->x;
@ -377,199 +376,10 @@ static void P_DoTailsCarry(player_t *sonic, player_t *tails)
else {
if (sonic-players == consoleplayer && botingame)
CV_SetValue(&cv_analog2, true);
sonic->pflags &= ~PF_CARRIED;
sonic->powers[pw_carry] = CR_NONE;
}
}
//
// P_ConsiderSolids (moved out of PIT_CheckThing in order to have additional flexibility)
//
static boolean P_ConsiderSolids(mobj_t *thing)
{
// Monitors are not treated as solid to players who are jumping, spinning or gliding,
// unless it's a CTF team monitor and you're on the wrong team
if (thing->flags & MF_MONITOR && tmthing->player
&& (tmthing->player->pflags & (PF_SPINNING|PF_GLIDING)
|| ((tmthing->player->pflags & PF_JUMPED)
&& !(tmthing->player->charflags & SF_NOJUMPDAMAGE
&& !(tmthing->player->charability == CA_TWINSPIN && tmthing->player->panim == PA_ABILITY)))
|| (tmthing->player->charability2 == CA2_MELEE && tmthing->player->panim == PA_ABILITY2)
|| ((tmthing->player->charflags & SF_STOMPDAMAGE)
&& (P_MobjFlip(tmthing)*(tmthing->z - (thing->z + thing->height/2)) > 0) && (P_MobjFlip(tmthing)*tmthing->momz < 0)))
&& !((thing->type == MT_REDRINGBOX && tmthing->player->ctfteam != 1) || (thing->type == MT_BLUERINGBOX && tmthing->player->ctfteam != 2)))
;
// z checking at last
// Treat noclip things as non-solid!
else if ((thing->flags & (MF_SOLID|MF_NOCLIP)) == MF_SOLID
&& (tmthing->flags & (MF_SOLID|MF_NOCLIP)) == MF_SOLID)
{
fixed_t topz, tmtopz;
if (tmthing->eflags & MFE_VERTICALFLIP)
{
// pass under
tmtopz = tmthing->z;
if (tmtopz > thing->z + thing->height)
{
if (thing->z + thing->height > tmfloorz)
{
tmfloorz = thing->z + thing->height;
#ifdef ESLOPE
tmfloorslope = NULL;
#endif
}
return true;
}
topz = thing->z - FixedMul(FRACUNIT, thing->scale);
// block only when jumping not high enough,
// (dont climb max. 24units while already in air)
// if not in air, let P_TryMove() decide if it's not too high
if (tmthing->player && tmthing->z + tmthing->height > topz
&& tmthing->z + tmthing->height < tmthing->ceilingz)
return false; // block while in air
if (thing->flags & MF_SPRING)
;
else if (topz < tmceilingz && tmthing->z+tmthing->height <= thing->z+thing->height)
{
tmceilingz = topz;
#ifdef ESLOPE
tmceilingslope = NULL;
#endif
tmfloorthing = thing; // thing we may stand on
}
}
else
{
// pass under
tmtopz = tmthing->z + tmthing->height;
if (tmtopz < thing->z)
{
if (thing->z < tmceilingz)
{
tmceilingz = thing->z;
#ifdef ESLOPE
tmceilingslope = NULL;
#endif
}
return true;
}
topz = thing->z + thing->height + FixedMul(FRACUNIT, thing->scale);
// block only when jumping not high enough,
// (dont climb max. 24units while already in air)
// if not in air, let P_TryMove() decide if it's not too high
if (tmthing->player && tmthing->z < topz && tmthing->z > tmthing->floorz)
return false; // block while in air
if (thing->flags & MF_SPRING)
;
else if (topz > tmfloorz && tmthing->z >= thing->z)
{
tmfloorz = topz;
#ifdef ESLOPE
tmfloorslope = NULL;
#endif
tmfloorthing = thing; // thing we may stand on
}
}
}
// not solid not blocked
return true;
}
#if 0
//
// PIT_CheckSolid (PIT_CheckThing, but for solids only, and guaranteed no side effects)
//
static boolean PIT_CheckSolid(mobj_t *thing)
{
fixed_t blockdist;
// don't clip against self
if (thing == tmthing)
return true;
// Ignore... things.
if (!tmthing || !thing || P_MobjWasRemoved(thing))
return true;
I_Assert(!P_MobjWasRemoved(tmthing));
I_Assert(!P_MobjWasRemoved(thing));
if (!(thing->flags & MF_SOLID))
return true;
// Ignore spectators
if ((tmthing->player && tmthing->player->spectator)
|| (thing->player && thing->player->spectator))
return true;
// Metal Sonic destroys tiny baby objects.
if (tmthing->type == MT_METALSONIC_RACE
&& (thing->flags & (MF_MISSILE|MF_ENEMY|MF_BOSS) || thing->type == MT_SPIKE))
return true;
// CA_DASHMODE users destroy spikes and monitors, CA_TWINSPIN users and CA2_MELEE users destroy spikes.
if ((tmthing->player)
&& (((tmthing->player->charability == CA_DASHMODE) && (tmthing->player->dashmode >= 3*TICRATE)
&& (thing->flags & (MF_MONITOR) || thing->type == MT_SPIKE))
|| ((((tmthing->player->charability == CA_TWINSPIN) && (tmthing->player->panim == PA_ABILITY))
|| (tmthing->player->charability2 == CA2_MELEE && tmthing->player->panim == PA_ABILITY2))
&& (thing->type == MT_SPIKE))))
return true;
// Don't collide with your buddies while NiGHTS-flying.
if (tmthing->player && thing->player && (maptol & TOL_NIGHTS)
&& ((tmthing->player->pflags & PF_NIGHTSMODE) || (thing->player->pflags & PF_NIGHTSMODE)))
return true;
blockdist = thing->radius + tmthing->radius;
if (abs(thing->x - tmx) >= blockdist || abs(thing->y - tmy) >= blockdist)
return true; // didn't hit it
// Force solid players in hide and seek to avoid corner stacking.
if (cv_tailspickup.value && gametype != GT_HIDEANDSEEK)
{
if (tmthing->player && thing->player)
return true;
}
if (tmthing->player) // Is the moving/interacting object the player?
{
if (!tmthing->health)
return true;
// Are you touching the side of the object you're interacting with?
else if (thing->z - FixedMul(FRACUNIT, thing->scale) <= tmthing->z + tmthing->height
&& thing->z + thing->height + FixedMul(FRACUNIT, thing->scale) >= tmthing->z)
{
if (thing->flags & MF_MONITOR
&& (tmthing->player->pflags & (PF_SPINNING|PF_GLIDING)
|| ((tmthing->player->pflags & PF_JUMPED)
&& !(tmthing->player->charflags & SF_NOJUMPDAMAGE
&& !(tmthing->player->charability == CA_TWINSPIN && tmthing->player->panim == PA_ABILITY)))
|| (tmthing->player->charability2 == CA2_MELEE && tmthing->player->panim == PA_ABILITY2)
|| ((tmthing->player->charflags & SF_STOMPDAMAGE)
&& (P_MobjFlip(tmthing)*(tmthing->z - (thing->z + thing->height/2)) > 0) && (P_MobjFlip(tmthing)*tmthing->momz < 0))))
{
return false;
}
}
}
return P_ConsiderSolids(thing);
}
#endif
//
// PIT_CheckThing
//
@ -858,7 +668,7 @@ static boolean PIT_CheckThing(mobj_t *thing)
if (tmthing->flags & MF_MISSILE && thing->player && tmthing->target && tmthing->target->player
&& thing->player->ctfteam == tmthing->target->player->ctfteam
&& thing->player->pflags & PF_CARRIED && thing->tracer == tmthing->target)
&& thing->player->powers[pw_carry] == CR_PLAYER && thing->tracer == tmthing->target)
return true; // Don't give rings to your carry player by accident.
if (thing->type == MT_EGGSHIELD)
@ -901,7 +711,7 @@ static boolean PIT_CheckThing(mobj_t *thing)
&& tmthing->target != thing)
{
// Hop on the missile for a ride!
thing->player->pflags |= PF_ITEMHANG;
thing->player->powers[pw_carry] = CR_GENERIC;
thing->player->pflags &= ~PF_JUMPED;
P_SetTarget(&thing->tracer, tmthing);
P_SetTarget(&tmthing->target, thing); // Set owner to the player
@ -920,7 +730,7 @@ static boolean PIT_CheckThing(mobj_t *thing)
return true;
}
else if (tmthing->type == MT_BLACKEGGMAN_MISSILE && thing->player && ((thing->player->pflags & PF_ITEMHANG) || (thing->player->pflags & PF_JUMPED)))
else if (tmthing->type == MT_BLACKEGGMAN_MISSILE && thing->player && ((thing->player->powers[pw_carry] == CR_GENERIC) || (thing->player->pflags & PF_JUMPED)))
{
// Ignore
}
@ -1121,7 +931,8 @@ static boolean PIT_CheckThing(mobj_t *thing)
else if (thing->player) {
if (thing->player-players == consoleplayer && botingame)
CV_SetValue(&cv_analog2, true);
thing->player->pflags &= ~PF_CARRIED;
if (thing->player->powers[pw_carry] == CR_PLAYER)
thing->player->powers[pw_carry] = CR_NONE;
}
if (thing->player)
@ -1199,8 +1010,99 @@ static boolean PIT_CheckThing(mobj_t *thing)
if (iwassprung) // this spring caused you to gain MFE_SPRUNG just now...
return false; // "cancel" P_TryMove via blocking so you keep your current position
}
else
return P_ConsiderSolids(thing);
// Monitors are not treated as solid to players who are jumping, spinning or gliding,
// unless it's a CTF team monitor and you're on the wrong team
else if (thing->flags & MF_MONITOR && tmthing->player
&& (tmthing->player->pflags & (PF_SPINNING|PF_GLIDING)
|| ((tmthing->player->pflags & PF_JUMPED)
&& !(tmthing->player->charflags & SF_NOJUMPDAMAGE
&& !(tmthing->player->charability == CA_TWINSPIN && tmthing->player->panim == PA_ABILITY)))
|| (tmthing->player->charability2 == CA2_MELEE && tmthing->player->panim == PA_ABILITY2)
|| ((tmthing->player->charflags & SF_STOMPDAMAGE)
&& (P_MobjFlip(tmthing)*(tmthing->z - (thing->z + thing->height/2)) > 0) && (P_MobjFlip(tmthing)*tmthing->momz < 0)))
&& !((thing->type == MT_REDRINGBOX && tmthing->player->ctfteam != 1) || (thing->type == MT_BLUERINGBOX && tmthing->player->ctfteam != 2)))
;
// z checking at last
// Treat noclip things as non-solid!
else if ((thing->flags & (MF_SOLID|MF_NOCLIP)) == MF_SOLID
&& (tmthing->flags & (MF_SOLID|MF_NOCLIP)) == MF_SOLID)
{
fixed_t topz, tmtopz;
if (tmthing->eflags & MFE_VERTICALFLIP)
{
// pass under
tmtopz = tmthing->z;
if (tmtopz > thing->z + thing->height)
{
if (thing->z + thing->height > tmfloorz)
{
tmfloorz = thing->z + thing->height;
#ifdef ESLOPE
tmfloorslope = NULL;
#endif
}
return true;
}
topz = thing->z - FixedMul(FRACUNIT, thing->scale);
// block only when jumping not high enough,
// (dont climb max. 24units while already in air)
// if not in air, let P_TryMove() decide if it's not too high
if (tmthing->player && tmthing->z + tmthing->height > topz
&& tmthing->z + tmthing->height < tmthing->ceilingz)
return false; // block while in air
if (thing->flags & MF_SPRING)
;
else if (topz < tmceilingz && tmthing->z+tmthing->height <= thing->z+thing->height)
{
tmceilingz = topz;
#ifdef ESLOPE
tmceilingslope = NULL;
#endif
tmfloorthing = thing; // thing we may stand on
}
}
else
{
// pass under
tmtopz = tmthing->z + tmthing->height;
if (tmtopz < thing->z)
{
if (thing->z < tmceilingz)
{
tmceilingz = thing->z;
#ifdef ESLOPE
tmceilingslope = NULL;
#endif
}
return true;
}
topz = thing->z + thing->height + FixedMul(FRACUNIT, thing->scale);
// block only when jumping not high enough,
// (dont climb max. 24units while already in air)
// if not in air, let P_TryMove() decide if it's not too high
if (tmthing->player && tmthing->z < topz && tmthing->z > tmthing->floorz)
return false; // block while in air
if (thing->flags & MF_SPRING)
;
else if (topz > tmfloorz && tmthing->z >= thing->z)
{
tmfloorz = topz;
#ifdef ESLOPE
tmfloorslope = NULL;
#endif
tmfloorthing = thing; // thing we may stand on
}
}
}
// not solid not blocked
return true;

View File

@ -3998,20 +3998,23 @@ static void P_PlayerMobjThinker(mobj_t *mobj)
mobj->eflags &= ~MFE_JUSTSTEPPEDDOWN;
// Zoom tube
if (mobj->tracer && mobj->tracer->type == MT_TUBEWAYPOINT)
if (mobj->tracer)
{
P_UnsetThingPosition(mobj);
mobj->x += mobj->momx;
mobj->y += mobj->momy;
mobj->z += mobj->momz;
P_SetThingPosition(mobj);
P_CheckPosition(mobj, mobj->x, mobj->y);
goto animonly;
}
else if (mobj->player->pflags & PF_MACESPIN && mobj->tracer)
{
P_CheckPosition(mobj, mobj->x, mobj->y);
goto animonly;
if (mobj->player->powers[pw_carry] == CR_ZOOMTUBE)
{
P_UnsetThingPosition(mobj);
mobj->x += mobj->momx;
mobj->y += mobj->momy;
mobj->z += mobj->momz;
P_SetThingPosition(mobj);
P_CheckPosition(mobj, mobj->x, mobj->y);
goto animonly;
}
else if (mobj->player->powers[pw_carry] == CR_MACESPIN)
{
P_CheckPosition(mobj, mobj->x, mobj->y);
goto animonly;
}
}
// Needed for gravity boots

View File

@ -3889,7 +3889,7 @@ DoneSection2:
mobj_t *mo2;
angle_t an;
if (player->mo->tracer && player->mo->tracer->type == MT_TUBEWAYPOINT)
if (player->mo->tracer && player->mo->tracer->type == MT_TUBEWAYPOINT && player->powers[pw_carry] == CR_ZOOMTUBE)
break;
// Find line #3 tagged to this sector
@ -3938,6 +3938,7 @@ DoneSection2:
break; // behind back
P_SetTarget(&player->mo->tracer, waypoint);
player->powers[pw_carry] = CR_ZOOMTUBE;
player->speed = speed;
player->pflags |= PF_SPINNING;
player->pflags &= ~PF_JUMPED;
@ -3962,7 +3963,7 @@ DoneSection2:
mobj_t *mo2;
angle_t an;
if (player->mo->tracer && player->mo->tracer->type == MT_TUBEWAYPOINT)
if (player->mo->tracer && player->mo->tracer->type == MT_TUBEWAYPOINT && player->powers[pw_carry] == CR_ZOOMTUBE)
break;
// Find line #3 tagged to this sector
@ -4012,6 +4013,7 @@ DoneSection2:
break; // behind back
P_SetTarget(&player->mo->tracer, waypoint);
player->powers[pw_carry] = CR_ZOOMTUBE;
player->speed = speed;
player->pflags |= PF_SPINNING;
player->pflags &= ~PF_JUMPED;
@ -4084,7 +4086,7 @@ DoneSection2:
vertex_t v1, v2, resulthigh, resultlow;
mobj_t *highest = NULL;
if (player->mo->tracer && player->mo->tracer->type == MT_TUBEWAYPOINT)
if (player->mo->tracer && player->mo->tracer->type == MT_TUBEWAYPOINT && player->powers[pw_carry] == CR_ROPEHANG)
break;
if (player->mo->momz > 0)
@ -4305,6 +4307,7 @@ DoneSection2:
}
P_SetTarget(&player->mo->tracer, closest);
player->powers[pw_carry] = CR_ROPEHANG;
// Option for static ropes.
if (lines[lineindex].flags & ML_NOCLIMB)
@ -4312,7 +4315,7 @@ DoneSection2:
else
player->speed = speed;
player->pflags |= PF_ROPEHANG;
player->powers[pw_carry] = CR_ROPEHANG;
S_StartSound(player->mo, sfx_s3k4a);
@ -7165,7 +7168,7 @@ static inline boolean PIT_PushThing(mobj_t *thing)
if (thing->eflags & MFE_PUSHED)
return false;
if (thing->player && thing->player->pflags & PF_ROPEHANG)
if (thing->player && thing->player->powers[pw_carry] == CR_ROPEHANG)
return false;
// Allow this to affect pushable objects at some point?
@ -7398,7 +7401,7 @@ void T_Pusher(pusher_t *p)
if (thing->eflags & MFE_PUSHED)
continue;
if (thing->player && thing->player->pflags & PF_ROPEHANG)
if (thing->player && thing->player->powers[pw_carry] == CR_ROPEHANG)
continue;
if (thing->player && (thing->state == &states[thing->info->painstate]) && (thing->player->powers[pw_flashing] > (flashingtics/4)*3 && thing->player->powers[pw_flashing] <= flashingtics))

View File

@ -160,9 +160,9 @@ boolean P_Teleport(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z, angle_t angle
INT32 p;
// Search for any players you might be carrying, so you can get them off before they end up being taken with you!
for (p = 0; p < MAXPLAYERS; p++)
if (playeringame[p] && players[p].mo && players[p].pflags & PF_CARRIED && players[p].mo->tracer == thing)
if (playeringame[p] && players[p].mo && players[p].powers[pw_carry] == CR_PLAYER && players[p].mo->tracer == thing)
{
players[p].pflags &= ~PF_CARRIED;
players[p].powers[pw_carry] = CR_NONE;
break;
}
thing->player->cmomx = thing->player->cmomy = 0;

View File

@ -873,7 +873,7 @@ void P_DoPlayerPain(player_t *player, mobj_t *source, mobj_t *inflictor)
P_InstaThrust(player->mo, ang, fallbackspeed);
if (player->pflags & PF_ROPEHANG)
if (player->powers[pw_carry] == CR_ROPEHANG)
P_SetTarget(&player->mo->tracer, NULL);
// Point penalty for hitting a hazard during tag.
@ -900,7 +900,8 @@ void P_DoPlayerPain(player_t *player, mobj_t *source, mobj_t *inflictor)
// Useful when you want to kill everything the player is doing.
void P_ResetPlayer(player_t *player)
{
player->pflags &= ~(PF_ROPEHANG|PF_ITEMHANG|PF_MACESPIN|PF_SPINNING|PF_STARTDASH|PF_JUMPED|PF_GLIDING|PF_THOKKED|PF_CARRIED);
player->pflags &= ~(PF_SPINNING|PF_STARTDASH|PF_JUMPED|PF_GLIDING|PF_THOKKED);
player->powers[pw_carry] = CR_NONE;
player->jumping = 0;
player->secondjump = 0;
player->glidetime = 0;
@ -3415,7 +3416,7 @@ static void P_DoSuperStuff(player_t *player)
? (SKINCOLOR_SUPERSILVER1 + 5*((leveltime >> 1) % 7)) // A wholesome easter egg.
: skins[player->skin].supercolor + (unsigned)abs( ( (signed)(leveltime >> 1) % 9) - 4); // This is where super flashing is handled.
if ((cmd->forwardmove != 0 || cmd->sidemove != 0 || player->pflags & (PF_CARRIED|PF_ROPEHANG|PF_ITEMHANG|PF_MACESPIN))
if ((cmd->forwardmove != 0 || cmd->sidemove != 0 || player->powers[pw_carry])
&& !(leveltime % TICRATE) && (player->mo->momx || player->mo->momy))
{
spark = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_SUPERSPARK);
@ -3583,22 +3584,22 @@ void P_DoJump(player_t *player, boolean soundandstate)
return;
// Jump this high.
if (player->pflags & PF_CARRIED)
if (player->powers[pw_carry] == CR_PLAYER)
{
player->mo->momz = 9*FRACUNIT;
player->pflags &= ~PF_CARRIED;
player->powers[pw_carry] = CR_NONE;
if (player-players == consoleplayer && botingame)
CV_SetValue(&cv_analog2, true);
}
else if (player->pflags & PF_ITEMHANG)
else if (player->powers[pw_carry] == CR_GENERIC)
{
player->mo->momz = 9*FRACUNIT;
player->pflags &= ~PF_ITEMHANG;
player->powers[pw_carry] = CR_NONE;
}
else if (player->pflags & PF_ROPEHANG)
else if (player->powers[pw_carry] == CR_ROPEHANG)
{
player->mo->momz = 12*FRACUNIT;
player->pflags &= ~PF_ROPEHANG;
player->powers[pw_carry] = CR_NONE;
P_SetTarget(&player->mo->tracer, NULL);
}
else if (player->mo->eflags & MFE_GOOWATER)
@ -3935,9 +3936,9 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd)
if (cmd->buttons & BT_USE && !(player->pflags & PF_JUMPDOWN) && !player->exiting && !P_PlayerInPain(player))
{
if (onground || player->climbing || player->pflags & (PF_CARRIED|PF_ITEMHANG|PF_ROPEHANG))
if (player->mo->tracer && player->powers[pw_carry] == CR_MACESPIN)
{}
else if (player->pflags & PF_MACESPIN && player->mo->tracer)
else if (onground || player->climbing || (player->mo->tracer && player->powers[pw_carry]))
{}
else if (!(player->pflags & PF_SLIDING) && ((gametype != GT_CTF) || (!player->gotflag)))
{
@ -4010,19 +4011,19 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd)
player->secondjump = 0;
player->pflags &= ~PF_THOKKED;
}
else if (player->powers[pw_carry] == CR_MACESPIN && player->mo->tracer)
{
player->powers[pw_carry] = CR_NONE;
player->powers[pw_flashing] = TICRATE/4;
}
else
// can't jump while in air, can't jump while jumping
if (onground || player->climbing || player->pflags & (PF_CARRIED|PF_ITEMHANG|PF_ROPEHANG))
if (onground || player->climbing || player->powers[pw_carry])
{
P_DoJump(player, true);
player->secondjump = 0;
player->pflags &= ~PF_THOKKED;
}
else if (player->pflags & PF_MACESPIN && player->mo->tracer)
{
player->pflags &= ~PF_MACESPIN;
player->powers[pw_flashing] = TICRATE/4;
}
else if (player->pflags & PF_SLIDING || (gametype == GT_CTF && player->gotflag))
;
else if (P_SuperReady(player))
@ -6973,7 +6974,7 @@ static void P_MovePlayer(player_t *player)
// Check for teeter!
if (!(player->mo->momz || player->mo->momx || player->mo->momy) && !(player->mo->eflags & MFE_GOOWATER)
&& player->panim == PA_IDLE && !(player->pflags & (PF_CARRIED|PF_ITEMHANG|PF_ROPEHANG)))
&& player->panim == PA_IDLE && !(player->powers[pw_carry]))
P_DoTeeter(player);
// Toss a flag
@ -7244,6 +7245,7 @@ static void P_DoZoomTube(player_t *player)
else
{
P_SetTarget(&player->mo->tracer, NULL); // Else, we just let him fly.
player->powers[pw_carry] = CR_NONE;
CONS_Debug(DBG_GAMELOGIC, "Next waypoint not found, releasing from track...\n");
}
@ -7291,7 +7293,7 @@ static void P_DoRopeHang(player_t *player)
P_SetTarget(&player->mo->tracer, NULL);
player->pflags |= PF_JUMPED;
player->pflags &= ~PF_ROPEHANG;
player->powers[pw_carry] = CR_NONE;
if (!(player->pflags & PF_SLIDING) && (player->pflags & PF_JUMPED)
&& !(player->panim == PA_JUMP))
@ -7309,6 +7311,10 @@ static void P_DoRopeHang(player_t *player)
sequence = player->mo->tracer->threshold;
// If not allowed to move, we're done here.
if (!speed)
return;
// change slope
dist = P_AproxDistance(P_AproxDistance(player->mo->tracer->x - player->mo->x, player->mo->tracer->y - player->mo->y), player->mo->tracer->z - playerz);
@ -7319,22 +7325,28 @@ static void P_DoRopeHang(player_t *player)
speedy = FixedMul(FixedDiv(player->mo->tracer->y - player->mo->y, dist), (speed));
speedz = FixedMul(FixedDiv(player->mo->tracer->z - playerz, dist), (speed));
// If not allowed to move, we're done here.
if (!speed)
return;
// Calculate the distance between the player and the waypoint
// 'dist' already equals this.
// Will the player be FURTHER away if the momx/momy/momz is added to
// his current coordinates, or closer? (shift down to fracunits to avoid approximation errors)
if (dist>>FRACBITS <= P_AproxDistance(P_AproxDistance(player->mo->tracer->x - player->mo->x - speedx, player->mo->tracer->y - player->mo->y - speedy), player->mo->tracer->z - playerz - speedz)>>FRACBITS)
// Will the player go past the waypoint?
if (
((speedx || speedy)
&& (R_PointToAngle2(player->mo->x, player->mo->y, player->mo->tracer->x, player->mo->tracer->y)
- R_PointToAngle2(player->mo->x + speedx, player->mo->y + speedy, player->mo->tracer->x, player->mo->tracer->y)) > ANG1)
|| ((speedz)
&& ((playerz - player->mo->tracer->z) > 0) != ((playerz + speedz - player->mo->tracer->z) > 0))
)
{
if (speed > dist)
speed -= dist;
else
speed = 0;
// If further away, set XYZ of player to waypoint location
P_UnsetThingPosition(player->mo);
player->mo->x = player->mo->tracer->x;
player->mo->y = player->mo->tracer->y;
player->mo->z = player->mo->tracer->z - player->mo->height;
playerz = player->mo->tracer->z;
P_SetThingPosition(player->mo);
CONS_Debug(DBG_GAMELOGIC, "Looking for next waypoint...\n");
@ -7390,6 +7402,8 @@ static void P_DoRopeHang(player_t *player)
{
CONS_Debug(DBG_GAMELOGIC, "Found waypoint (sequence %d, number %d).\n", waypoint->threshold, waypoint->health);
P_SetTarget(&player->mo->tracer, waypoint);
// calculate MOMX/MOMY/MOMZ for next waypoint
// change slope
dist = P_AproxDistance(P_AproxDistance(player->mo->tracer->x - player->mo->x, player->mo->tracer->y - player->mo->y), player->mo->tracer->z - playerz);
@ -7400,15 +7414,12 @@ static void P_DoRopeHang(player_t *player)
player->mo->momx = FixedMul(FixedDiv(player->mo->tracer->x - player->mo->x, dist), (speed));
player->mo->momy = FixedMul(FixedDiv(player->mo->tracer->y - player->mo->y, dist), (speed));
player->mo->momz = FixedMul(FixedDiv(player->mo->tracer->z - playerz, dist), (speed));
P_SetTarget(&player->mo->tracer, waypoint);
}
else
{
if (player->mo->tracer->flags & MF_SLIDEME)
{
player->pflags |= PF_JUMPED;
player->pflags &= ~PF_ROPEHANG;
if (!(player->pflags & PF_SLIDING) && (player->pflags & PF_JUMPED)
&& !(player->panim == PA_JUMP))
@ -7416,6 +7427,7 @@ static void P_DoRopeHang(player_t *player)
}
P_SetTarget(&player->mo->tracer, NULL);
player->powers[pw_carry] = CR_NONE;
CONS_Debug(DBG_GAMELOGIC, "Next waypoint not found!\n");
}
@ -8109,7 +8121,7 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
{
dist = camdist;
if (player->climbing || player->exiting || player->playerstate == PST_DEAD || (player->pflags & (PF_MACESPIN|PF_ITEMHANG|PF_ROPEHANG)))
if (player->climbing || player->exiting || player->playerstate == PST_DEAD || (player->powers[pw_carry] && player->powers[pw_carry] != CR_PLAYER))
dist <<= 1;
}
@ -8979,9 +8991,9 @@ void P_PlayerThink(player_t *player)
// for a bit after a teleport.
if (player->mo->reactiontime)
player->mo->reactiontime--;
else if (player->mo->tracer && player->mo->tracer->type == MT_TUBEWAYPOINT)
else if (player->mo->tracer && player->mo->tracer->type == MT_TUBEWAYPOINT && (player->powers[pw_carry] == CR_ROPEHANG || player->powers[pw_carry] == CR_ZOOMTUBE))
{
if (player->pflags & PF_ROPEHANG)
if (player->powers[pw_carry] == CR_ROPEHANG)
{
if (!P_AnalogMove(player))
player->mo->angle = (cmd->angleturn<<16 /* not FRACBITS */);
@ -8994,7 +9006,7 @@ void P_PlayerThink(player_t *player)
P_SetPlayerMobjState(player->mo, S_PLAY_RIDE);
P_DoJumpStuff(player, &player->cmd);
}
else
else if (player->powers[pw_carry] == CR_ZOOMTUBE)
{
P_DoZoomTube(player);
if (!(player->panim == PA_ROLL))
@ -9406,14 +9418,14 @@ void P_PlayerAfterThink(player_t *player)
&& !(player->charflags & SF_NOJUMPSPIN))
P_SetPlayerMobjState(player->mo, S_PLAY_JUMP);
if (player->pflags & PF_CARRIED && player->mo->tracer)
if (player->powers[pw_carry] == CR_PLAYER && player->mo->tracer)
{
player->mo->height = FixedDiv(P_GetPlayerHeight(player), FixedDiv(14*FRACUNIT,10*FRACUNIT));
if (player->mo->tracer->player
&& !player->mo->tracer->player->powers[pw_tailsfly]
&& player->mo->tracer->state-states != S_PLAY_FLY_TIRED)
player->pflags &= ~PF_CARRIED;
player->powers[pw_carry] = CR_NONE;
if (player->mo->eflags & MFE_VERTICALFLIP)
{
@ -9421,7 +9433,7 @@ void P_PlayerAfterThink(player_t *player)
&& (player->mo->tracer->eflags & MFE_VERTICALFLIP)) // Reverse gravity check for the carrier - Flame
player->mo->z = player->mo->tracer->z + player->mo->tracer->height + FixedMul(FRACUNIT, player->mo->scale);
else
player->pflags &= ~PF_CARRIED;
player->powers[pw_carry] = CR_NONE;
}
else
{
@ -9429,11 +9441,11 @@ void P_PlayerAfterThink(player_t *player)
&& !(player->mo->tracer->eflags & MFE_VERTICALFLIP)) // Correct gravity check for the carrier - Flame
player->mo->z = player->mo->tracer->z - player->mo->height - FixedMul(FRACUNIT, player->mo->scale);
else
player->pflags &= ~PF_CARRIED;
player->powers[pw_carry] = CR_NONE;
}
if (player->mo->tracer->health <= 0)
player->pflags &= ~PF_CARRIED;
player->powers[pw_carry] = CR_NONE;
else
{
P_TryMove(player->mo, player->mo->tracer->x, player->mo->tracer->y, true);
@ -9456,14 +9468,14 @@ void P_PlayerAfterThink(player_t *player)
}
if (P_AproxDistance(player->mo->x - player->mo->tracer->x, player->mo->y - player->mo->tracer->y) > player->mo->radius)
player->pflags &= ~PF_CARRIED;
player->powers[pw_carry] = CR_NONE;
P_SetPlayerMobjState(player->mo, S_PLAY_RIDE);
if (player-players == consoleplayer && botingame)
CV_SetValue(&cv_analog2, !(player->pflags & PF_CARRIED));
CV_SetValue(&cv_analog2, (player->powers[pw_carry] != CR_PLAYER));
}
else if (player->pflags & PF_ITEMHANG && player->mo->tracer)
else if (player->powers[pw_carry] == CR_GENERIC && player->mo->tracer)
{
// tracer is what you're hanging onto
P_UnsetThingPosition(player->mo);
@ -9491,12 +9503,12 @@ void P_PlayerAfterThink(player_t *player)
if (player->mo->z <= player->mo->floorz
|| player->mo->tracer->health <= 0)
{
player->pflags &= ~PF_ITEMHANG;
player->powers[pw_carry] = CR_NONE;
P_SetTarget(&player->mo->tracer, NULL);
}
}
}
else if (player->pflags & PF_MACESPIN && player->mo->tracer && player->mo->tracer->target)
else if (player->powers[pw_carry] == CR_MACESPIN && player->mo->tracer && player->mo->tracer->target)
{
player->mo->height = P_GetPlayerSpinHeight(player);
// tracer is what you're hanging onto....