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; return;
#endif #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); 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; cmd->buttons |= BT_JUMP;
if (sonic->player->pflags & (PF_MACESPIN|PF_ITEMHANG)) if (isrelevant)
{ {
cmd->forwardmove = sonic->player->cmd.forwardmove; cmd->forwardmove = sonic->player->cmd.forwardmove;
cmd->angleturn = abs((signed)(tails->angle - sonic->angle))>>16; 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. // Check if Sonic is busy first.
// If he's doing any of these things, he probably doesn't want to see us. // 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) if (sonic->player->pflags & (PF_GLIDING|PF_SLIDING|PF_NIGHTSMODE)
|| (sonic->player->panim != PA_IDLE && sonic->player->panim != PA_WALK)) || (sonic->player->panim != PA_IDLE && sonic->player->panim != PA_WALK)
|| (sonic->player->powers[pw_carry]))
return false; return false;
// Low ceiling, do not want! // 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_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_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? SF_MACHINE = 1<<10, // Beep boop. Are you a robot?
// free up to and including 1<<31
} skinflags_t; } skinflags_t;
//Primary and secondary skin abilities //Primary and secondary skin abilities
@ -128,40 +129,28 @@ typedef enum
// Are you gliding? // Are you gliding?
PF_GLIDING = 1<<16, PF_GLIDING = 1<<16,
// Tails pickup!
PF_CARRIED = 1<<17,
// Sliding (usually in water) like Labyrinth/Oil Ocean // Sliding (usually in water) like Labyrinth/Oil Ocean
PF_SLIDING = 1<<18, PF_SLIDING = 1<<17,
// 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,
/*** NIGHTS STUFF ***/ /*** NIGHTS STUFF ***/
// Is the player in NiGHTS mode? // Is the player in NiGHTS mode?
PF_NIGHTSMODE = 1<<22, PF_NIGHTSMODE = 1<<18,
PF_TRANSFERTOCLOSEST = 1<<23, PF_TRANSFERTOCLOSEST = 1<<19,
// Spill rings after falling // Spill rings after falling
PF_NIGHTSFALL = 1<<24, PF_NIGHTSFALL = 1<<20,
PF_DRILLING = 1<<25, PF_DRILLING = 1<<21,
PF_SKIDDOWN = 1<<26, PF_SKIDDOWN = 1<<22,
/*** TAG STUFF ***/ /*** TAG STUFF ***/
PF_TAGGED = 1<<27, // Player has been tagged and awaits the next round in hide and seek. PF_TAGGED = 1<<23, // 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_TAGIT = 1<<24, // The player is it! For Tag Mode
/*** misc ***/ /*** misc ***/
PF_FORCESTRAFE = 1<<29, // Turning inputs are translated into strafing inputs PF_FORCESTRAFE = 1<<25, // Turning inputs are translated into strafing inputs
PF_ANALOGMODE = 1<<30, // Analog mode? PF_ANALOGMODE = 1<<26, // Analog mode?
// free: 1<<30 and 1<<31 // free up to and including 1<<31
} pflags_t; } pflags_t;
typedef enum typedef enum
@ -204,7 +193,20 @@ typedef enum
SH_STACK = SH_FIREFLOWER, SH_STACK = SH_FIREFLOWER,
SH_NOSTACK = ~SH_STACK 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) // Player powers. (don't edit this comment)
typedef enum typedef enum
@ -213,6 +215,7 @@ typedef enum
pw_sneakers, pw_sneakers,
pw_flashing, pw_flashing,
pw_shield, pw_shield,
pw_carry,
pw_tailsfly, // tails flying pw_tailsfly, // tails flying
pw_underwater, // underwater timer pw_underwater, // underwater timer
pw_spacetime, // In space, no one can hear you spin! 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? // Are you gliding?
"GLIDING", "GLIDING",
// Tails pickup!
"CARRIED",
// Sliding (usually in water) like Labyrinth/Oil Ocean // Sliding (usually in water) like Labyrinth/Oil Ocean
"SLIDING", "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 ***/ /*** NIGHTS STUFF ***/
// Is the player in NiGHTS mode? // Is the player in NiGHTS mode?
"NIGHTSMODE", "NIGHTSMODE",
@ -6903,6 +6891,7 @@ static const char *const POWERS_LIST[] = {
"SNEAKERS", "SNEAKERS",
"FLASHING", "FLASHING",
"SHIELD", "SHIELD",
"CARRY",
"TAILSFLY", // tails flying "TAILSFLY", // tails flying
"UNDERWATER", // underwater timer "UNDERWATER", // underwater timer
"SPACETIME", // In space, no one can hear you spin! "SPACETIME", // In space, no one can hear you spin!
@ -7138,6 +7127,14 @@ struct {
{"SH_STACK",SH_STACK}, {"SH_STACK",SH_STACK},
{"SH_NOSTACK",SH_NOSTACK}, {"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) // Ring weapons (ringweapons_t)
// Useful for A_GiveWeapon // Useful for A_GiveWeapon
{"RW_AUTO",RW_AUTO}, {"RW_AUTO",RW_AUTO},

View file

@ -5428,8 +5428,8 @@ void A_MixUp(mobj_t *actor)
// Zoom tube stuff // Zoom tube stuff
mobj_t *tempthing = NULL; //tracer mobj_t *tempthing = NULL; //tracer
pflags_t flags1,flags2; //player pflags UINT16 carry1,carry2; //carry
INT32 transspeed; //player speed INT32 transspeed; //player speed
// Starpost stuff // Starpost stuff
INT16 starpostx, starposty, starpostz; INT16 starpostx, starposty, starpostz;
@ -5466,8 +5466,8 @@ void A_MixUp(mobj_t *actor)
players[two].speed = transspeed; players[two].speed = transspeed;
//set flags variables now but DON'T set them. //set flags variables now but DON'T set them.
flags1 = (players[one].pflags & (PF_ITEMHANG|PF_MACESPIN|PF_ROPEHANG)); carry1 = (players[one].powers[pw_carry] == CR_PLAYER ? CR_NONE : players[one].powers[pw_carry]);
flags2 = (players[two].pflags & (PF_ITEMHANG|PF_MACESPIN|PF_ROPEHANG)); carry2 = (players[two].powers[pw_carry] == CR_PLAYER ? CR_NONE : players[two].powers[pw_carry]);
x = players[one].mo->x; x = players[one].mo->x;
y = players[one].mo->y; y = players[one].mo->y;
@ -5492,12 +5492,10 @@ void A_MixUp(mobj_t *actor)
starpostnum, starposttime, starpostangle, starpostnum, starposttime, starpostangle,
mflags2); mflags2);
//flags set after mixup. Stupid P_ResetPlayer() takes away some of the flags we look for... //carry set after mixup. Stupid P_ResetPlayer() takes away some of the stuff we look for...
//but not all of them! So we need to make sure they aren't set wrong or anything. //but not all of it! So we need to make sure they aren't set wrong or anything.
players[one].pflags &= ~(PF_ITEMHANG|PF_MACESPIN|PF_ROPEHANG); players[one].powers[pw_carry] = carry2;
players[one].pflags |= flags2; players[two].powers[pw_carry] = carry1;
players[two].pflags &= ~(PF_ITEMHANG|PF_MACESPIN|PF_ROPEHANG);
players[two].pflags |= flags1;
teleported[one] = true; teleported[one] = true;
teleported[two] = true; teleported[two] = true;
@ -5509,8 +5507,9 @@ void A_MixUp(mobj_t *actor)
INT32 pindex[MAXPLAYERS], counter = 0, teleportfrom = 0; INT32 pindex[MAXPLAYERS], counter = 0, teleportfrom = 0;
// Zoom tube stuff // Zoom tube stuff
mobj_t *transtracer[MAXPLAYERS]; //tracer mobj_t *transtracer[MAXPLAYERS]; //tracer
pflags_t transflag[MAXPLAYERS]; //player pflags //pflags_t transflag[MAXPLAYERS]; //cyan pink white pink cyan
UINT16 transcarry[MAXPLAYERS]; //player carry
INT32 transspeed[MAXPLAYERS]; //player speed INT32 transspeed[MAXPLAYERS]; //player speed
// Star post stuff // Star post stuff
@ -5544,7 +5543,7 @@ void A_MixUp(mobj_t *actor)
players[i].rmomx = players[i].rmomy = 1; players[i].rmomx = players[i].rmomy = 1;
players[i].cmomx = players[i].cmomy = 0; 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; transspeed[counter] = players[i].speed;
transtracer[counter] = players[i].mo->tracer; transtracer[counter] = players[i].mo->tracer;
@ -5596,9 +5595,8 @@ void A_MixUp(mobj_t *actor)
starpostnum[teleportfrom], starposttime[teleportfrom], starpostangle[teleportfrom], starpostnum[teleportfrom], starposttime[teleportfrom], starpostangle[teleportfrom],
flags2[teleportfrom]); flags2[teleportfrom]);
//...flags after. same reasoning. //...carry after. same reasoning.
players[i].pflags &= ~(PF_ITEMHANG|PF_MACESPIN|PF_ROPEHANG); players[i].powers[pw_carry] = transcarry[teleportfrom];
players[i].pflags |= transflag[teleportfrom];
teleported[i] = true; teleported[i] = true;
counter++; counter++;
@ -6165,7 +6163,7 @@ void A_Boss7Chase(mobj_t *actor)
if (actor->health <= actor->info->damage if (actor->health <= actor->info->damage
&& actor->target && actor->target
&& actor->target->player && actor->target->player
&& (actor->target->player->pflags & PF_ITEMHANG)) && (actor->target->player->powers[pw_carry] == CR_GENERIC))
{ {
A_FaceTarget(actor); A_FaceTarget(actor);
P_SetMobjState(actor, S_BLACKEGG_SHOOT1); 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; player->powers[pw_ingoop] = 2;
if (player->pflags & PF_ITEMHANG) if (player->powers[pw_carry] == CR_GENERIC)
{ {
P_SetTarget(&toucher->tracer, NULL); P_SetTarget(&toucher->tracer, NULL);
player->pflags &= ~PF_ITEMHANG; player->powers[pw_carry] = CR_NONE;
} }
P_ResetPlayer(player); P_ResetPlayer(player);
@ -1337,7 +1337,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
case MT_BIGMACECHAIN: case MT_BIGMACECHAIN:
// Is this the last link in the chain? // Is this the last link in the chain?
if (toucher->momz > 0 || !(special->flags & MF_AMBUSH) if (toucher->momz > 0 || !(special->flags & MF_AMBUSH)
|| (player->pflags & PF_ITEMHANG) || (player->pflags & PF_MACESPIN)) || (player->powers[pw_carry]))
return; return;
if (toucher->z > special->z + special->height/2) 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)) 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); S_StartSound(toucher, sfx_spin);
P_SetPlayerMobjState(toucher, S_PLAY_SPIN); P_SetPlayerMobjState(toucher, S_PLAY_SPIN);
} }
else else
player->pflags |= PF_ITEMHANG; player->powers[pw_carry] = CR_GENERIC;
// Can't jump first frame // Can't jump first frame
player->pflags |= PF_JUMPSTASIS; 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) 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 // Burst weapons and emeralds in Match/CTF only
if (source && (gametype == GT_MATCH || gametype == GT_TEAMMATCH || gametype == GT_CTF)) 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; INT32 p;
fixed_t zdist; // z distance between the two players' bottoms 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; return;
if ((sonic->pflags & PF_CARRIED) && sonic->mo->tracer == tails->mo) if (sonic->powers[pw_carry] == CR_PLAYER && sonic->mo->tracer == tails->mo)
return; return;
if (tails->charability != CA_FLY && tails->charability != CA_SWIM) 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) if (sonic->pflags & PF_NIGHTSMODE)
return; return;
if (sonic->mo->tracer && sonic->mo->tracer->type == MT_TUBEWAYPOINT if (sonic->mo->tracer && sonic->powers[pw_carry] == CR_ZOOMTUBE)
&& !(sonic->pflags & PF_ROPEHANG))
return; // don't steal players from zoomtubes! return; // don't steal players from zoomtubes!
if ((sonic->mo->eflags & MFE_VERTICALFLIP) != (tails->mo->eflags & MFE_VERTICALFLIP)) 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. // Search in case another player is already being carried by this fox.
for (p = 0; p < MAXPLAYERS; p++) for (p = 0; p < MAXPLAYERS; p++)
if (playeringame[p] && players[p].mo 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; return;
if (tails->mo->eflags & MFE_VERTICALFLIP) 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))) || (G_TagGametype() && (!(tails->pflags & PF_TAGIT) != !(sonic->pflags & PF_TAGIT)))
|| (gametype == GT_MATCH) || (gametype == GT_MATCH)
|| (G_GametypeHasTeams() && tails->ctfteam != sonic->ctfteam)) || (G_GametypeHasTeams() && tails->ctfteam != sonic->ctfteam))
sonic->pflags &= ~PF_CARRIED; */ sonic->powers[pw_carry] = CR_NONE; */
if (tails->spectator || sonic->spectator) if (tails->spectator || sonic->spectator)
sonic->pflags &= ~PF_CARRIED; sonic->powers[pw_carry] = CR_NONE;
else else
{ {
if (sonic-players == consoleplayer && botingame) if (sonic-players == consoleplayer && botingame)
CV_SetValue(&cv_analog2, false); CV_SetValue(&cv_analog2, false);
P_ResetPlayer(sonic); P_ResetPlayer(sonic);
P_SetTarget(&sonic->mo->tracer, tails->mo); P_SetTarget(&sonic->mo->tracer, tails->mo);
sonic->pflags |= PF_CARRIED; sonic->powers[pw_carry] = CR_PLAYER;
S_StartSound(sonic->mo, sfx_s3k4a); S_StartSound(sonic->mo, sfx_s3k4a);
P_UnsetThingPosition(sonic->mo); P_UnsetThingPosition(sonic->mo);
sonic->mo->x = tails->mo->x; sonic->mo->x = tails->mo->x;
@ -377,199 +376,10 @@ static void P_DoTailsCarry(player_t *sonic, player_t *tails)
else { else {
if (sonic-players == consoleplayer && botingame) if (sonic-players == consoleplayer && botingame)
CV_SetValue(&cv_analog2, true); 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 // 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 if (tmthing->flags & MF_MISSILE && thing->player && tmthing->target && tmthing->target->player
&& thing->player->ctfteam == tmthing->target->player->ctfteam && 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. return true; // Don't give rings to your carry player by accident.
if (thing->type == MT_EGGSHIELD) if (thing->type == MT_EGGSHIELD)
@ -901,7 +711,7 @@ static boolean PIT_CheckThing(mobj_t *thing)
&& tmthing->target != thing) && tmthing->target != thing)
{ {
// Hop on the missile for a ride! // Hop on the missile for a ride!
thing->player->pflags |= PF_ITEMHANG; thing->player->powers[pw_carry] = CR_GENERIC;
thing->player->pflags &= ~PF_JUMPED; thing->player->pflags &= ~PF_JUMPED;
P_SetTarget(&thing->tracer, tmthing); P_SetTarget(&thing->tracer, tmthing);
P_SetTarget(&tmthing->target, thing); // Set owner to the player P_SetTarget(&tmthing->target, thing); // Set owner to the player
@ -920,7 +730,7 @@ static boolean PIT_CheckThing(mobj_t *thing)
return true; 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 // Ignore
} }
@ -1121,7 +931,8 @@ static boolean PIT_CheckThing(mobj_t *thing)
else if (thing->player) { else if (thing->player) {
if (thing->player-players == consoleplayer && botingame) if (thing->player-players == consoleplayer && botingame)
CV_SetValue(&cv_analog2, true); 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) 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... 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 return false; // "cancel" P_TryMove via blocking so you keep your current position
} }
else // Monitors are not treated as solid to players who are jumping, spinning or gliding,
return P_ConsiderSolids(thing); // 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 // not solid not blocked
return true; return true;

View file

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

View file

@ -3889,7 +3889,7 @@ DoneSection2:
mobj_t *mo2; mobj_t *mo2;
angle_t an; 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; break;
// Find line #3 tagged to this sector // Find line #3 tagged to this sector
@ -3938,6 +3938,7 @@ DoneSection2:
break; // behind back break; // behind back
P_SetTarget(&player->mo->tracer, waypoint); P_SetTarget(&player->mo->tracer, waypoint);
player->powers[pw_carry] = CR_ZOOMTUBE;
player->speed = speed; player->speed = speed;
player->pflags |= PF_SPINNING; player->pflags |= PF_SPINNING;
player->pflags &= ~PF_JUMPED; player->pflags &= ~PF_JUMPED;
@ -3962,7 +3963,7 @@ DoneSection2:
mobj_t *mo2; mobj_t *mo2;
angle_t an; 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; break;
// Find line #3 tagged to this sector // Find line #3 tagged to this sector
@ -4012,6 +4013,7 @@ DoneSection2:
break; // behind back break; // behind back
P_SetTarget(&player->mo->tracer, waypoint); P_SetTarget(&player->mo->tracer, waypoint);
player->powers[pw_carry] = CR_ZOOMTUBE;
player->speed = speed; player->speed = speed;
player->pflags |= PF_SPINNING; player->pflags |= PF_SPINNING;
player->pflags &= ~PF_JUMPED; player->pflags &= ~PF_JUMPED;
@ -4084,7 +4086,7 @@ DoneSection2:
vertex_t v1, v2, resulthigh, resultlow; vertex_t v1, v2, resulthigh, resultlow;
mobj_t *highest = NULL; 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; break;
if (player->mo->momz > 0) if (player->mo->momz > 0)
@ -4305,6 +4307,7 @@ DoneSection2:
} }
P_SetTarget(&player->mo->tracer, closest); P_SetTarget(&player->mo->tracer, closest);
player->powers[pw_carry] = CR_ROPEHANG;
// Option for static ropes. // Option for static ropes.
if (lines[lineindex].flags & ML_NOCLIMB) if (lines[lineindex].flags & ML_NOCLIMB)
@ -4312,7 +4315,7 @@ DoneSection2:
else else
player->speed = speed; player->speed = speed;
player->pflags |= PF_ROPEHANG; player->powers[pw_carry] = CR_ROPEHANG;
S_StartSound(player->mo, sfx_s3k4a); S_StartSound(player->mo, sfx_s3k4a);
@ -7165,7 +7168,7 @@ static inline boolean PIT_PushThing(mobj_t *thing)
if (thing->eflags & MFE_PUSHED) if (thing->eflags & MFE_PUSHED)
return false; return false;
if (thing->player && thing->player->pflags & PF_ROPEHANG) if (thing->player && thing->player->powers[pw_carry] == CR_ROPEHANG)
return false; return false;
// Allow this to affect pushable objects at some point? // Allow this to affect pushable objects at some point?
@ -7398,7 +7401,7 @@ void T_Pusher(pusher_t *p)
if (thing->eflags & MFE_PUSHED) if (thing->eflags & MFE_PUSHED)
continue; continue;
if (thing->player && thing->player->pflags & PF_ROPEHANG) if (thing->player && thing->player->powers[pw_carry] == CR_ROPEHANG)
continue; continue;
if (thing->player && (thing->state == &states[thing->info->painstate]) && (thing->player->powers[pw_flashing] > (flashingtics/4)*3 && thing->player->powers[pw_flashing] <= flashingtics)) 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; INT32 p;
// Search for any players you might be carrying, so you can get them off before they end up being taken with you! // 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++) 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; break;
} }
thing->player->cmomx = thing->player->cmomy = 0; 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); P_InstaThrust(player->mo, ang, fallbackspeed);
if (player->pflags & PF_ROPEHANG) if (player->powers[pw_carry] == CR_ROPEHANG)
P_SetTarget(&player->mo->tracer, NULL); P_SetTarget(&player->mo->tracer, NULL);
// Point penalty for hitting a hazard during tag. // 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. // Useful when you want to kill everything the player is doing.
void P_ResetPlayer(player_t *player) 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->jumping = 0;
player->secondjump = 0; player->secondjump = 0;
player->glidetime = 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. ? (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. : 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)) && !(leveltime % TICRATE) && (player->mo->momx || player->mo->momy))
{ {
spark = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_SUPERSPARK); 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; return;
// Jump this high. // Jump this high.
if (player->pflags & PF_CARRIED) if (player->powers[pw_carry] == CR_PLAYER)
{ {
player->mo->momz = 9*FRACUNIT; player->mo->momz = 9*FRACUNIT;
player->pflags &= ~PF_CARRIED; player->powers[pw_carry] = CR_NONE;
if (player-players == consoleplayer && botingame) if (player-players == consoleplayer && botingame)
CV_SetValue(&cv_analog2, true); 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->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->mo->momz = 12*FRACUNIT;
player->pflags &= ~PF_ROPEHANG; player->powers[pw_carry] = CR_NONE;
P_SetTarget(&player->mo->tracer, NULL); P_SetTarget(&player->mo->tracer, NULL);
} }
else if (player->mo->eflags & MFE_GOOWATER) 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 (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))) 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->secondjump = 0;
player->pflags &= ~PF_THOKKED; 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 else
// can't jump while in air, can't jump while jumping // 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); P_DoJump(player, true);
player->secondjump = 0; player->secondjump = 0;
player->pflags &= ~PF_THOKKED; 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 (player->pflags & PF_SLIDING || (gametype == GT_CTF && player->gotflag))
; ;
else if (P_SuperReady(player)) else if (P_SuperReady(player))
@ -6973,7 +6974,7 @@ static void P_MovePlayer(player_t *player)
// Check for teeter! // Check for teeter!
if (!(player->mo->momz || player->mo->momx || player->mo->momy) && !(player->mo->eflags & MFE_GOOWATER) 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); P_DoTeeter(player);
// Toss a flag // Toss a flag
@ -7244,6 +7245,7 @@ static void P_DoZoomTube(player_t *player)
else else
{ {
P_SetTarget(&player->mo->tracer, NULL); // Else, we just let him fly. 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"); 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); P_SetTarget(&player->mo->tracer, NULL);
player->pflags |= PF_JUMPED; player->pflags |= PF_JUMPED;
player->pflags &= ~PF_ROPEHANG; player->powers[pw_carry] = CR_NONE;
if (!(player->pflags & PF_SLIDING) && (player->pflags & PF_JUMPED) if (!(player->pflags & PF_SLIDING) && (player->pflags & PF_JUMPED)
&& !(player->panim == PA_JUMP)) && !(player->panim == PA_JUMP))
@ -7309,6 +7311,10 @@ static void P_DoRopeHang(player_t *player)
sequence = player->mo->tracer->threshold; sequence = player->mo->tracer->threshold;
// If not allowed to move, we're done here.
if (!speed)
return;
// change slope // 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); 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)); speedy = FixedMul(FixedDiv(player->mo->tracer->y - player->mo->y, dist), (speed));
speedz = FixedMul(FixedDiv(player->mo->tracer->z - playerz, 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 // Calculate the distance between the player and the waypoint
// 'dist' already equals this. // 'dist' already equals this.
// Will the player be FURTHER away if the momx/momy/momz is added to // Will the player go past the waypoint?
// his current coordinates, or closer? (shift down to fracunits to avoid approximation errors) if (
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) ((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 // If further away, set XYZ of player to waypoint location
P_UnsetThingPosition(player->mo); P_UnsetThingPosition(player->mo);
player->mo->x = player->mo->tracer->x; player->mo->x = player->mo->tracer->x;
player->mo->y = player->mo->tracer->y; player->mo->y = player->mo->tracer->y;
player->mo->z = player->mo->tracer->z - player->mo->height; player->mo->z = player->mo->tracer->z - player->mo->height;
playerz = player->mo->tracer->z;
P_SetThingPosition(player->mo); P_SetThingPosition(player->mo);
CONS_Debug(DBG_GAMELOGIC, "Looking for next waypoint...\n"); 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); 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 // calculate MOMX/MOMY/MOMZ for next waypoint
// change slope // 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); 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->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->momy = FixedMul(FixedDiv(player->mo->tracer->y - player->mo->y, dist), (speed));
player->mo->momz = FixedMul(FixedDiv(player->mo->tracer->z - playerz, dist), (speed)); player->mo->momz = FixedMul(FixedDiv(player->mo->tracer->z - playerz, dist), (speed));
P_SetTarget(&player->mo->tracer, waypoint);
} }
else else
{ {
if (player->mo->tracer->flags & MF_SLIDEME) if (player->mo->tracer->flags & MF_SLIDEME)
{ {
player->pflags |= PF_JUMPED; player->pflags |= PF_JUMPED;
player->pflags &= ~PF_ROPEHANG;
if (!(player->pflags & PF_SLIDING) && (player->pflags & PF_JUMPED) if (!(player->pflags & PF_SLIDING) && (player->pflags & PF_JUMPED)
&& !(player->panim == PA_JUMP)) && !(player->panim == PA_JUMP))
@ -7416,6 +7427,7 @@ static void P_DoRopeHang(player_t *player)
} }
P_SetTarget(&player->mo->tracer, NULL); P_SetTarget(&player->mo->tracer, NULL);
player->powers[pw_carry] = CR_NONE;
CONS_Debug(DBG_GAMELOGIC, "Next waypoint not found!\n"); 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; 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; dist <<= 1;
} }
@ -8979,9 +8991,9 @@ void P_PlayerThink(player_t *player)
// for a bit after a teleport. // for a bit after a teleport.
if (player->mo->reactiontime) if (player->mo->reactiontime)
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)) if (!P_AnalogMove(player))
player->mo->angle = (cmd->angleturn<<16 /* not FRACBITS */); 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_SetPlayerMobjState(player->mo, S_PLAY_RIDE);
P_DoJumpStuff(player, &player->cmd); P_DoJumpStuff(player, &player->cmd);
} }
else else if (player->powers[pw_carry] == CR_ZOOMTUBE)
{ {
P_DoZoomTube(player); P_DoZoomTube(player);
if (!(player->panim == PA_ROLL)) if (!(player->panim == PA_ROLL))
@ -9406,14 +9418,14 @@ void P_PlayerAfterThink(player_t *player)
&& !(player->charflags & SF_NOJUMPSPIN)) && !(player->charflags & SF_NOJUMPSPIN))
P_SetPlayerMobjState(player->mo, S_PLAY_JUMP); 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)); player->mo->height = FixedDiv(P_GetPlayerHeight(player), FixedDiv(14*FRACUNIT,10*FRACUNIT));
if (player->mo->tracer->player if (player->mo->tracer->player
&& !player->mo->tracer->player->powers[pw_tailsfly] && !player->mo->tracer->player->powers[pw_tailsfly]
&& player->mo->tracer->state-states != S_PLAY_FLY_TIRED) && 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) 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->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); player->mo->z = player->mo->tracer->z + player->mo->tracer->height + FixedMul(FRACUNIT, player->mo->scale);
else else
player->pflags &= ~PF_CARRIED; player->powers[pw_carry] = CR_NONE;
} }
else 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->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); player->mo->z = player->mo->tracer->z - player->mo->height - FixedMul(FRACUNIT, player->mo->scale);
else else
player->pflags &= ~PF_CARRIED; player->powers[pw_carry] = CR_NONE;
} }
if (player->mo->tracer->health <= 0) if (player->mo->tracer->health <= 0)
player->pflags &= ~PF_CARRIED; player->powers[pw_carry] = CR_NONE;
else else
{ {
P_TryMove(player->mo, player->mo->tracer->x, player->mo->tracer->y, true); 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) 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); P_SetPlayerMobjState(player->mo, S_PLAY_RIDE);
if (player-players == consoleplayer && botingame) 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 // tracer is what you're hanging onto
P_UnsetThingPosition(player->mo); P_UnsetThingPosition(player->mo);
@ -9491,12 +9503,12 @@ void P_PlayerAfterThink(player_t *player)
if (player->mo->z <= player->mo->floorz if (player->mo->z <= player->mo->floorz
|| player->mo->tracer->health <= 0) || player->mo->tracer->health <= 0)
{ {
player->pflags &= ~PF_ITEMHANG; player->powers[pw_carry] = CR_NONE;
P_SetTarget(&player->mo->tracer, NULL); 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); player->mo->height = P_GetPlayerSpinHeight(player);
// tracer is what you're hanging onto.... // tracer is what you're hanging onto....