* cv_directionchar and cv_autobrake, and their secondplayer versions (both on by default) now exist.

* cv_useranalog is now hidden from the menu.
* Directionchar now attempts to face the camera direction when you're standing still, and handles a few other states with more decorum.
* Tailsbot is now slightly more capable of keeping up with Sonic.
* pflags rearranged/adjusted, combining a few non-simulstaneous ones and turning PF_NIGHTSFALL into CR_NIGHTSFALL.
* [unrelated to branch] all ground-impact based abilities now happen more consistently with quicksand.
This commit is contained in:
toasterbabe 2017-09-15 20:34:46 +01:00
parent 2e6c09a636
commit f90d595332
16 changed files with 415 additions and 251 deletions

View File

@ -271,6 +271,12 @@ void B_RespawnBot(INT32 playernum)
player->powers[pw_spacetime] = sonic->player->powers[pw_spacetime]; player->powers[pw_spacetime] = sonic->player->powers[pw_spacetime];
player->powers[pw_gravityboots] = sonic->player->powers[pw_gravityboots]; player->powers[pw_gravityboots] = sonic->player->powers[pw_gravityboots];
player->powers[pw_nocontrol] = sonic->player->powers[pw_nocontrol]; player->powers[pw_nocontrol] = sonic->player->powers[pw_nocontrol];
player->acceleration = sonic->player->acceleration;
player->accelstart = sonic->player->accelstart;
player->thrustfactor = sonic->player->thrustfactor;
player->normalspeed = sonic->player->normalspeed;
player->pflags |= PF_AUTOBRAKE;
player->pflags &= ~PF_DIRECTIONCHAR;
P_TeleportMove(tails, x, y, z); P_TeleportMove(tails, x, y, z);
if (player->charability == CA_FLY) if (player->charability == CA_FLY)

View File

@ -3097,11 +3097,15 @@ static void Got_AddPlayer(UINT8 **p, INT32 playernum)
secondarydisplayplayer = newplayernum; secondarydisplayplayer = newplayernum;
DEBFILE("spawning me\n"); DEBFILE("spawning me\n");
// Apply player flags as soon as possible! // Apply player flags as soon as possible!
players[newplayernum].pflags &= ~(PF_FLIPCAM|PF_ANALOGMODE); players[newplayernum].pflags &= ~(PF_FLIPCAM|PF_ANALOGMODE|PF_DIRECTIONCHAR|PF_AUTOBRAKE);
if (cv_flipcam.value) if (cv_flipcam.value)
players[newplayernum].pflags |= PF_FLIPCAM; players[newplayernum].pflags |= PF_FLIPCAM;
if (cv_analog.value) if (cv_analog.value)
players[newplayernum].pflags |= PF_ANALOGMODE; players[newplayernum].pflags |= PF_ANALOGMODE;
if (cv_directionchar.value)
players[newplayernum].pflags |= PF_DIRECTIONCHAR;
if (cv_autobrake.value)
players[newplayernum].pflags |= PF_AUTOBRAKE;
} }
else else
{ {
@ -3110,11 +3114,15 @@ static void Got_AddPlayer(UINT8 **p, INT32 playernum)
if (botingame) if (botingame)
players[newplayernum].bot = 1; players[newplayernum].bot = 1;
// Same goes for player 2 when relevant // Same goes for player 2 when relevant
players[newplayernum].pflags &= ~(PF_FLIPCAM|PF_ANALOGMODE); players[newplayernum].pflags &= ~(PF_FLIPCAM|PF_ANALOGMODE|PF_DIRECTIONCHAR|PF_AUTOBRAKE);
if (cv_flipcam2.value) if (cv_flipcam2.value)
players[newplayernum].pflags |= PF_FLIPCAM; players[newplayernum].pflags |= PF_FLIPCAM;
if (cv_analog2.value) if (cv_analog2.value)
players[newplayernum].pflags |= PF_ANALOGMODE; players[newplayernum].pflags |= PF_ANALOGMODE;
if (cv_directionchar2.value)
players[newplayernum].pflags |= PF_DIRECTIONCHAR;
if (cv_autobrake2.value)
players[newplayernum].pflags |= PF_AUTOBRAKE;
} }
D_SendPlayerConfig(); D_SendPlayerConfig();
addedtogame = true; addedtogame = true;

View File

@ -771,6 +771,12 @@ void D_RegisterClientCommands(void)
CV_RegisterVar(&cv_useranalog); CV_RegisterVar(&cv_useranalog);
CV_RegisterVar(&cv_useranalog2); CV_RegisterVar(&cv_useranalog2);
// deez New User eXperiences
CV_RegisterVar(&cv_directionchar);
CV_RegisterVar(&cv_directionchar2);
CV_RegisterVar(&cv_autobrake);
CV_RegisterVar(&cv_autobrake2);
// s_sound.c // s_sound.c
CV_RegisterVar(&cv_soundvolume); CV_RegisterVar(&cv_soundvolume);
CV_RegisterVar(&cv_closedcaptioning); CV_RegisterVar(&cv_closedcaptioning);
@ -1433,6 +1439,10 @@ void SendWeaponPref(void)
buf[0] |= 1; buf[0] |= 1;
if (players[consoleplayer].pflags & PF_ANALOGMODE) if (players[consoleplayer].pflags & PF_ANALOGMODE)
buf[0] |= 2; buf[0] |= 2;
if (players[consoleplayer].pflags & PF_DIRECTIONCHAR)
buf[0] |= 4;
if (players[consoleplayer].pflags & PF_AUTOBRAKE)
buf[0] |= 8;
SendNetXCmd(XD_WEAPONPREF, buf, 1); SendNetXCmd(XD_WEAPONPREF, buf, 1);
} }
@ -1445,6 +1455,10 @@ void SendWeaponPref2(void)
buf[0] |= 1; buf[0] |= 1;
if (players[secondarydisplayplayer].pflags & PF_ANALOGMODE) if (players[secondarydisplayplayer].pflags & PF_ANALOGMODE)
buf[0] |= 2; buf[0] |= 2;
if (players[secondarydisplayplayer].pflags & PF_DIRECTIONCHAR)
buf[0] |= 4;
if (players[secondarydisplayplayer].pflags & PF_AUTOBRAKE)
buf[0] |= 8;
SendNetXCmd2(XD_WEAPONPREF, buf, 1); SendNetXCmd2(XD_WEAPONPREF, buf, 1);
} }
@ -1452,11 +1466,15 @@ static void Got_WeaponPref(UINT8 **cp,INT32 playernum)
{ {
UINT8 prefs = READUINT8(*cp); UINT8 prefs = READUINT8(*cp);
players[playernum].pflags &= ~(PF_FLIPCAM|PF_ANALOGMODE); players[playernum].pflags &= ~(PF_FLIPCAM|PF_ANALOGMODE|PF_DIRECTIONCHAR|PF_AUTOBRAKE);
if (prefs & 1) if (prefs & 1)
players[playernum].pflags |= PF_FLIPCAM; players[playernum].pflags |= PF_FLIPCAM;
if (prefs & 2) if (prefs & 2)
players[playernum].pflags |= PF_ANALOGMODE; players[playernum].pflags |= PF_ANALOGMODE;
if (prefs & 4)
players[playernum].pflags |= PF_DIRECTIONCHAR;
if (prefs & 8)
players[playernum].pflags |= PF_AUTOBRAKE;
} }
void D_SendPlayerConfig(void) void D_SendPlayerConfig(void)
@ -2578,12 +2596,12 @@ static void Got_Teamchange(UINT8 **cp, INT32 playernum)
{ {
players[playernum].spectator = true; players[playernum].spectator = true;
players[playernum].pflags &= ~PF_TAGIT; players[playernum].pflags &= ~PF_TAGIT;
players[playernum].pflags &= ~PF_TAGGED; players[playernum].pflags &= ~PF_GAMETYPEOVER;
} }
else if (NetPacket.packet.newteam != 3) // .newteam == 1 or 2. else if (NetPacket.packet.newteam != 3) // .newteam == 1 or 2.
{ {
players[playernum].spectator = false; players[playernum].spectator = false;
players[playernum].pflags &= ~PF_TAGGED;//Just in case. players[playernum].pflags &= ~PF_GAMETYPEOVER; //Just in case.
if (NetPacket.packet.newteam == 1) //Make the player IT. if (NetPacket.packet.newteam == 1) //Make the player IT.
players[playernum].pflags |= PF_TAGIT; players[playernum].pflags |= PF_TAGIT;

View File

@ -98,66 +98,58 @@ typedef enum
// //
typedef enum typedef enum
{ {
// Flip camera angle with gravity flip prefrence. // Cvars
PF_FLIPCAM = 1, PF_FLIPCAM = 1, // Flip camera angle with gravity flip prefrence.
PF_ANALOGMODE = 1<<1, // Analog mode?
PF_DIRECTIONCHAR = 1<<2, // Directional character sprites?
PF_AUTOBRAKE = 1<<3, // Autobrake?
// Cheats // Cheats
PF_GODMODE = 1<<1, PF_GODMODE = 1<<4,
PF_NOCLIP = 1<<2, PF_NOCLIP = 1<<5,
PF_INVIS = 1<<3, PF_INVIS = 1<<6,
// True if button down last tic. // True if button down last tic.
PF_ATTACKDOWN = 1<<4, PF_ATTACKDOWN = 1<<7,
PF_USEDOWN = 1<<5, PF_USEDOWN = 1<<8,
PF_JUMPDOWN = 1<<6, PF_JUMPDOWN = 1<<9,
PF_WPNDOWN = 1<<7, PF_WPNDOWN = 1<<10,
// Unmoving states // Unmoving states
PF_STASIS = 1<<8, // Player is not allowed to move PF_STASIS = 1<<11, // Player is not allowed to move
PF_JUMPSTASIS = 1<<9, // and that includes jumping. PF_JUMPSTASIS = 1<<12, // and that includes jumping.
PF_FULLSTASIS = PF_STASIS|PF_JUMPSTASIS, PF_FULLSTASIS = PF_STASIS|PF_JUMPSTASIS,
// Did you get a time-over? // Applying autobrake?
PF_TIMEOVER = 1<<10, PF_APPLYAUTOBRAKE = 1<<13,
// Character action status // Character action status
PF_STARTJUMP = 1<<11, PF_STARTJUMP = 1<<14,
PF_JUMPED = 1<<12, PF_JUMPED = 1<<15,
PF_SPINNING = 1<<13, PF_NOJUMPDAMAGE = 1<<16,
PF_STARTDASH = 1<<14,
PF_THOKKED = 1<<15,
// Are you gliding? PF_SPINNING = 1<<17,
PF_GLIDING = 1<<16, PF_STARTDASH = 1<<18,
PF_THOKKED = 1<<19,
PF_SHIELDABILITY = 1<<20,
PF_GLIDING = 1<<21,
PF_BOUNCING = 1<<22,
// Sliding (usually in water) like Labyrinth/Oil Ocean // Sliding (usually in water) like Labyrinth/Oil Ocean
PF_SLIDING = 1<<17, PF_SLIDING = 1<<23,
// Bouncing // NiGHTS stuff
PF_BOUNCING = 1<<18, PF_TRANSFERTOCLOSEST = 1<<24,
PF_DRILLING = 1<<25,
/*** NIGHTS STUFF ***/ // Gametype-specific stuff
PF_TRANSFERTOCLOSEST = 1<<19, PF_GAMETYPEOVER = 1<<26, // Race time over, or H&S out-of-game
PF_NIGHTSFALL = 1<<20, PF_TAGIT = 1<<27, // The player is it! For Tag Mode
PF_DRILLING = 1<<21,
PF_SKIDDOWN = 1<<22,
/*** TAG STUFF ***/
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 ***/ /*** misc ***/
PF_FORCESTRAFE = 1<<25, // Turning inputs are translated into strafing inputs PF_FORCESTRAFE = 1<<28, // Turning inputs are translated into strafing inputs
PF_ANALOGMODE = 1<<26, // Analog mode? PF_CANCARRY = 1<<29, // Can carry another player?
// Can carry another player?
PF_CANCARRY = 1<<27,
// Used shield ability
PF_SHIELDABILITY = 1<<28,
// Jump damage?
PF_NOJUMPDAMAGE = 1<<29,
// up to 1<<31 is free // up to 1<<31 is free
} pflags_t; } pflags_t;
@ -234,6 +226,7 @@ typedef enum
CR_PLAYER, CR_PLAYER,
// NiGHTS mode. Not technically a CARRYING, but doesn't stack with any of the others, so might as well go here. // NiGHTS mode. Not technically a CARRYING, but doesn't stack with any of the others, so might as well go here.
CR_NIGHTSMODE, CR_NIGHTSMODE,
CR_NIGHTSFALL,
// Old Brak sucks hard, but this gimmick could be used for something better, so we might as well continue supporting it. // Old Brak sucks hard, but this gimmick could be used for something better, so we might as well continue supporting it.
CR_BRAKGOOP, CR_BRAKGOOP,
// Specific level gimmicks. // Specific level gimmicks.

View File

@ -6422,8 +6422,12 @@ static const char *const MAPTHINGFLAG_LIST[4] = {
#endif #endif
static const char *const PLAYERFLAG_LIST[] = { static const char *const PLAYERFLAG_LIST[] = {
// Flip camera angle with gravity flip prefrence.
"FLIPCAM", // Cvars
"FLIPCAM", // Flip camera angle with gravity flip prefrence.
"ANALOGMODE", // Analog mode?
"DIRECTIONCHAR", // Directional character sprites?
"AUTOBRAKE", // Autobrake?
// Cheats // Cheats
"GODMODE", "GODMODE",
@ -6441,41 +6445,36 @@ static const char *const PLAYERFLAG_LIST[] = {
"JUMPSTASIS", // and that includes jumping. "JUMPSTASIS", // and that includes jumping.
// (we don't include FULLSTASIS here I guess because it's just those two together...?) // (we don't include FULLSTASIS here I guess because it's just those two together...?)
// Did you get a time-over? // Applying autobrake?
"TIMEOVER", "APPLYAUTOBRAKE",
// Character action status // Character action status
"STARTJUMP", "STARTJUMP",
"JUMPED", "JUMPED",
"NOJUMPDAMAGE",
"SPINNING", "SPINNING",
"STARTDASH", "STARTDASH",
"THOKKED",
// Are you gliding? "THOKKED",
"SHIELDABILITY",
"GLIDING", "GLIDING",
"BOUNCING",
// Sliding (usually in water) like Labyrinth/Oil Ocean // Sliding (usually in water) like Labyrinth/Oil Ocean
"SLIDING", "SLIDING",
// Bouncing // NiGHTS stuff
"BOUNCING",
/*** NIGHTS STUFF ***/
"TRANSFERTOCLOSEST", "TRANSFERTOCLOSEST",
"NIGHTSFALL",
"DRILLING", "DRILLING",
"SKIDDOWN",
/*** TAG STUFF ***/ // Gametype-specific stuff
"TAGGED", // Player has been tagged and awaits the next round in hide and seek. "GAMETYPEOVER", // Race time over, or H&S out-of-game
"TAGIT", // The player is it! For Tag Mode "TAGIT", // The player is it! For Tag Mode
/*** misc ***/ /*** misc ***/
"FORCESTRAFE", // Translate turn inputs into strafe inputs "FORCESTRAFE", // Translate turn inputs into strafe inputs
"ANALOGMODE", // Analog mode?
"CANCARRY", // Can carry? "CANCARRY", // Can carry?
"SHIELDABILITY", // Thokked with shield ability
"NOJUMPDAMAGE", // No jump damage
NULL // stop loop here. NULL // stop loop here.
}; };
@ -6892,6 +6891,7 @@ struct {
{"CR_GENERIC",CR_GENERIC}, {"CR_GENERIC",CR_GENERIC},
{"CR_PLAYER",CR_PLAYER}, {"CR_PLAYER",CR_PLAYER},
{"CR_NIGHTSMODE",CR_NIGHTSMODE}, {"CR_NIGHTSMODE",CR_NIGHTSMODE},
{"CR_NIGHTSFALL",CR_NIGHTSFALL},
{"CR_BRAKGOOP",CR_BRAKGOOP}, {"CR_BRAKGOOP",CR_BRAKGOOP},
{"CR_ZOOMTUBE",CR_ZOOMTUBE}, {"CR_ZOOMTUBE",CR_ZOOMTUBE},
{"CR_ROPEHANG",CR_ROPEHANG}, {"CR_ROPEHANG",CR_ROPEHANG},

View File

@ -286,6 +286,10 @@ static void UserAnalog_OnChange(void);
static void UserAnalog2_OnChange(void); static void UserAnalog2_OnChange(void);
static void Analog_OnChange(void); static void Analog_OnChange(void);
static void Analog2_OnChange(void); static void Analog2_OnChange(void);
static void DirectionChar_OnChange(void);
static void DirectionChar2_OnChange(void);
static void AutoBrake_OnChange(void);
static void AutoBrake2_OnChange(void);
void SendWeaponPref(void); void SendWeaponPref(void);
void SendWeaponPref2(void); void SendWeaponPref2(void);
@ -368,6 +372,14 @@ consvar_t cv_useranalog = {"useranalog", "Off", CV_SAVE|CV_CALL, CV_OnOff, UserA
consvar_t cv_useranalog2 = {"useranalog2", "Off", CV_SAVE|CV_CALL, CV_OnOff, UserAnalog2_OnChange, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_useranalog2 = {"useranalog2", "Off", CV_SAVE|CV_CALL, CV_OnOff, UserAnalog2_OnChange, 0, NULL, NULL, 0, 0, NULL};
#endif #endif
static CV_PossibleValue_t directionchar_cons_t[] = {{0, "Camera"}, {1, "Movement"}, {0, NULL}};
// deez New User eXperiences
consvar_t cv_directionchar = {"directionchar", "Movement", CV_SAVE|CV_CALL, directionchar_cons_t, DirectionChar_OnChange, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_directionchar2 = {"directionchar2", "Movement", CV_SAVE|CV_CALL, directionchar_cons_t, DirectionChar2_OnChange, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_autobrake = {"autobrake", "On", CV_SAVE|CV_CALL, CV_OnOff, AutoBrake_OnChange, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_autobrake2 = {"autobrake2", "On", CV_SAVE|CV_CALL, CV_OnOff, AutoBrake2_OnChange, 0, NULL, NULL, 0, 0, NULL};
typedef enum typedef enum
{ {
AXISNONE = 0, AXISNONE = 0,
@ -1615,6 +1627,46 @@ static void Analog2_OnChange(void)
SendWeaponPref2(); SendWeaponPref2();
} }
static void DirectionChar_OnChange(void)
{
if (cv_directionchar.value)
players[consoleplayer].pflags |= PF_DIRECTIONCHAR;
else
players[consoleplayer].pflags &= ~PF_DIRECTIONCHAR;
SendWeaponPref();
}
static void DirectionChar2_OnChange(void)
{
if (cv_directionchar2.value)
players[secondarydisplayplayer].pflags |= PF_DIRECTIONCHAR;
else
players[secondarydisplayplayer].pflags &= ~PF_DIRECTIONCHAR;
SendWeaponPref2();
}
static void AutoBrake_OnChange(void)
{
if (cv_autobrake.value)
players[consoleplayer].pflags |= PF_AUTOBRAKE;
else
players[consoleplayer].pflags &= ~PF_AUTOBRAKE;
SendWeaponPref();
}
static void AutoBrake2_OnChange(void)
{
if (cv_autobrake2.value)
players[secondarydisplayplayer].pflags |= PF_AUTOBRAKE;
else
players[secondarydisplayplayer].pflags &= ~PF_AUTOBRAKE;
SendWeaponPref2();
}
// //
// G_DoLoadLevel // G_DoLoadLevel
// //
@ -2103,7 +2155,7 @@ void G_PlayerReborn(INT32 player)
jointime = players[player].jointime; jointime = players[player].jointime;
spectator = players[player].spectator; spectator = players[player].spectator;
outofcoop = players[player].outofcoop; outofcoop = players[player].outofcoop;
pflags = (players[player].pflags & (PF_TIMEOVER|PF_FLIPCAM|PF_TAGIT|PF_TAGGED|PF_ANALOGMODE)); pflags = (players[player].pflags & (PF_FLIPCAM|PF_ANALOGMODE|PF_DIRECTIONCHAR|PF_AUTOBRAKE|PF_TAGIT|PF_GAMETYPEOVER));
// As long as we're not in multiplayer, carry over cheatcodes from map to map // As long as we're not in multiplayer, carry over cheatcodes from map to map
if (!(netgame || multiplayer)) if (!(netgame || multiplayer))
@ -3752,7 +3804,7 @@ void G_InitNew(UINT8 pultmode, const char *mapname, boolean resetplayer, boolean
players[i].score = 0; players[i].score = 0;
// The latter two should clear by themselves, but just in case // The latter two should clear by themselves, but just in case
players[i].pflags &= ~(PF_TAGIT|PF_TAGGED|PF_FULLSTASIS); players[i].pflags &= ~(PF_TAGIT|PF_GAMETYPEOVER|PF_FULLSTASIS);
// Clear cheatcodes too, just in case. // Clear cheatcodes too, just in case.
players[i].pflags &= ~(PF_GODMODE|PF_NOCLIP|PF_INVIS); players[i].pflags &= ~(PF_GODMODE|PF_NOCLIP|PF_INVIS);

View File

@ -59,6 +59,8 @@ extern consvar_t cv_invertmouse, cv_alwaysfreelook, cv_mousemove;
extern consvar_t cv_invertmouse2, cv_alwaysfreelook2, cv_mousemove2; extern consvar_t cv_invertmouse2, cv_alwaysfreelook2, cv_mousemove2;
extern consvar_t cv_useranalog, cv_useranalog2; extern consvar_t cv_useranalog, cv_useranalog2;
extern consvar_t cv_analog, cv_analog2; extern consvar_t cv_analog, cv_analog2;
extern consvar_t cv_directionchar, cv_directionchar2;
extern consvar_t cv_autobrake, cv_autobrake2;
extern consvar_t cv_sideaxis,cv_turnaxis,cv_moveaxis,cv_lookaxis,cv_fireaxis,cv_firenaxis; extern consvar_t cv_sideaxis,cv_turnaxis,cv_moveaxis,cv_lookaxis,cv_fireaxis,cv_firenaxis;
extern consvar_t cv_sideaxis2,cv_turnaxis2,cv_moveaxis2,cv_lookaxis2,cv_fireaxis2,cv_firenaxis2; extern consvar_t cv_sideaxis2,cv_turnaxis2,cv_moveaxis2,cv_lookaxis2,cv_fireaxis2,cv_firenaxis2;
extern consvar_t cv_ghost_bestscore, cv_ghost_besttime, cv_ghost_bestrings, cv_ghost_last, cv_ghost_guest; extern consvar_t cv_ghost_bestscore, cv_ghost_besttime, cv_ghost_bestrings, cv_ghost_last, cv_ghost_guest;

View File

@ -1061,7 +1061,9 @@ static menuitem_t OP_P1ControlsMenu[] =
{IT_STRING | IT_CVAR, NULL, "Flip Camera with Gravity" , &cv_flipcam , 60}, {IT_STRING | IT_CVAR, NULL, "Flip Camera with Gravity" , &cv_flipcam , 60},
{IT_STRING | IT_CVAR, NULL, "Crosshair", &cv_crosshair, 70}, {IT_STRING | IT_CVAR, NULL, "Crosshair", &cv_crosshair, 70},
{IT_STRING | IT_CVAR, NULL, "Analog Control", &cv_useranalog, 90}, //{IT_STRING | IT_CVAR, NULL, "Analog Control", &cv_useranalog, 90},
{IT_STRING | IT_CVAR, NULL, "Character angle", &cv_directionchar, 90},
{IT_STRING | IT_CVAR, NULL, "Automatic braking", &cv_autobrake, 100},
}; };
static menuitem_t OP_P2ControlsMenu[] = static menuitem_t OP_P2ControlsMenu[] =
@ -1074,7 +1076,9 @@ static menuitem_t OP_P2ControlsMenu[] =
{IT_STRING | IT_CVAR, NULL, "Flip Camera with Gravity" , &cv_flipcam2 , 60}, {IT_STRING | IT_CVAR, NULL, "Flip Camera with Gravity" , &cv_flipcam2 , 60},
{IT_STRING | IT_CVAR, NULL, "Crosshair", &cv_crosshair2, 70}, {IT_STRING | IT_CVAR, NULL, "Crosshair", &cv_crosshair2, 70},
{IT_STRING | IT_CVAR, NULL, "Analog Control", &cv_useranalog2, 90}, //{IT_STRING | IT_CVAR, NULL, "Analog Control", &cv_useranalog2, 90},
{IT_STRING | IT_CVAR, NULL, "Character angle", &cv_directionchar2, 90},
{IT_STRING | IT_CVAR, NULL, "Automatic braking", &cv_autobrake2, 100},
}; };
static menuitem_t OP_ChangeControlsMenu[] = static menuitem_t OP_ChangeControlsMenu[] =

View File

@ -1871,7 +1871,7 @@ void P_CheckTimeLimit(void)
for (i = 0; i < MAXPLAYERS; i++) for (i = 0; i < MAXPLAYERS; i++)
{ {
if (!playeringame[i] || players[i].spectator if (!playeringame[i] || players[i].spectator
|| (players[i].pflags & PF_TAGGED) || (players[i].pflags & PF_TAGIT)) || (players[i].pflags & PF_GAMETYPEOVER) || (players[i].pflags & PF_TAGIT))
continue; continue;
CONS_Printf(M_GetText("%s received double points for surviving the round.\n"), player_names[i]); CONS_Printf(M_GetText("%s received double points for surviving the round.\n"), player_names[i]);
@ -2018,7 +2018,7 @@ void P_CheckSurvivors(void)
spectators++; spectators++;
else if (players[i].pflags & PF_TAGIT) else if (players[i].pflags & PF_TAGIT)
taggers++; taggers++;
else if (!(players[i].pflags & PF_TAGGED)) else if (!(players[i].pflags & PF_GAMETYPEOVER))
{ {
survivorarray[survivors] = i; survivorarray[survivors] = i;
survivors++; survivors++;
@ -2325,7 +2325,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
} }
else else
{ {
if (!(target->player->pflags & PF_TAGGED)) if (!(target->player->pflags & PF_GAMETYPEOVER))
{ {
//otherwise, increment the tagger's score. //otherwise, increment the tagger's score.
//in hide and seek, suiciding players are counted as found. //in hide and seek, suiciding players are counted as found.
@ -2337,7 +2337,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
P_AddPlayerScore(&players[w], 100); P_AddPlayerScore(&players[w], 100);
} }
target->player->pflags |= PF_TAGGED; target->player->pflags |= PF_GAMETYPEOVER;
CONS_Printf(M_GetText("%s was found!\n"), player_names[target->player-players]); CONS_Printf(M_GetText("%s was found!\n"), player_names[target->player-players]);
P_CheckSurvivors(); P_CheckSurvivors();
} }
@ -2793,7 +2793,7 @@ static inline boolean P_TagDamage(mobj_t *target, mobj_t *inflictor, mobj_t *sou
} }
else else
{ {
player->pflags |= PF_TAGGED; //in hide and seek, the player is tagged and stays stationary. player->pflags |= PF_GAMETYPEOVER; //in hide and seek, the player is tagged and stays stationary.
CONS_Printf(M_GetText("%s was found!\n"), player_names[player-players]); // Tell everyone who is it! CONS_Printf(M_GetText("%s was found!\n"), player_names[player-players]); // Tell everyone who is it!
} }
@ -3208,7 +3208,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
if (player->pflags & PF_GODMODE) if (player->pflags & PF_GODMODE)
return false; return false;
if (!(target->player->powers[pw_carry] == CR_NIGHTSMODE || target->player->pflags & PF_NIGHTSFALL) && (maptol & TOL_NIGHTS)) if ((maptol & TOL_NIGHTS) && target->player->powers[pw_carry] != CR_NIGHTSMODE && target->player->powers[pw_carry] != CR_NIGHTSFALL)
return false; return false;
switch (damagetype) switch (damagetype)
@ -3409,7 +3409,7 @@ void P_PlayerRingBurst(player_t *player, INT32 num_rings)
if (player->rings <= 0) if (player->rings <= 0)
num_rings = 0; num_rings = 0;
if (num_rings > 32 && !(player->pflags & PF_NIGHTSFALL)) if (num_rings > 32 && player->powers[pw_carry] != CR_NIGHTSFALL)
num_rings = 32; num_rings = 32;
if (player->powers[pw_emeralds]) if (player->powers[pw_emeralds])
@ -3441,7 +3441,7 @@ void P_PlayerRingBurst(player_t *player, INT32 num_rings)
// Make rings spill out around the player in 16 directions like SA, but spill like Sonic 2. // Make rings spill out around the player in 16 directions like SA, but spill like Sonic 2.
// Technically a non-SA way of spilling rings. They just so happen to be a little similar. // Technically a non-SA way of spilling rings. They just so happen to be a little similar.
if (player->pflags & PF_NIGHTSFALL) if (player->powers[pw_carry] == CR_NIGHTSFALL)
{ {
ns = FixedMul(((i*FRACUNIT)/16)+2*FRACUNIT, mo->scale); ns = FixedMul(((i*FRACUNIT)/16)+2*FRACUNIT, mo->scale);
mo->momx = FixedMul(FINECOSINE(fa),ns); mo->momx = FixedMul(FINECOSINE(fa),ns);
@ -3481,13 +3481,13 @@ void P_PlayerRingBurst(player_t *player, INT32 num_rings)
} }
if (player->mo->eflags & MFE_VERTICALFLIP) if (player->mo->eflags & MFE_VERTICALFLIP)
mo->momz *= -1; mo->momz *= -1;
if (P_IsObjectOnGround(player->mo))
player->powers[pw_carry] = CR_NONE;
} }
player->losstime += 10*TICRATE; player->losstime += 10*TICRATE;
if (P_IsObjectOnGround(player->mo))
player->pflags &= ~PF_NIGHTSFALL;
return; return;
} }

View File

@ -140,6 +140,7 @@ boolean P_IsObjectOnGround(mobj_t *mo);
boolean P_IsObjectOnGroundIn(mobj_t *mo, sector_t *sec); boolean P_IsObjectOnGroundIn(mobj_t *mo, sector_t *sec);
boolean P_InSpaceSector(mobj_t *mo); boolean P_InSpaceSector(mobj_t *mo);
boolean P_InQuicksand(mobj_t *mo); boolean P_InQuicksand(mobj_t *mo);
boolean P_PlayerHitFloor(player_t *player);
void P_SetObjectMomZ(mobj_t *mo, fixed_t value, boolean relative); void P_SetObjectMomZ(mobj_t *mo, fixed_t value, boolean relative);
void P_RestoreMusic(player_t *player); void P_RestoreMusic(player_t *player);

View File

@ -3042,110 +3042,9 @@ static void P_PlayerZMovement(mobj_t *mo)
} }
} }
if (mo->health && !mo->player->spectator && !P_CheckDeathPitCollide(mo)) clipmomz = P_PlayerHitFloor(mo->player);
{
if ((mo->player->charability2 == CA2_SPINDASH) && !(mo->player->pflags & PF_THOKKED) && (mo->player->cmd.buttons & BT_USE) && (FixedHypot(mo->momx, mo->momy) > (5*mo->scale)))
{
mo->player->pflags |= PF_SPINNING;
P_SetPlayerMobjState(mo, S_PLAY_ROLL);
S_StartSound(mo, sfx_spin);
}
else
mo->player->pflags &= ~PF_SPINNING;
if (mo->player->pflags & PF_GLIDING) // ground gliding
{
mo->player->skidtime = TICRATE;
mo->tics = -1;
}
else if (mo->player->charability2 == CA2_MELEE && (mo->player->panim == PA_ABILITY2 && mo->state-states != S_PLAY_MELEE_LANDING))
{
P_SetPlayerMobjState(mo, S_PLAY_MELEE_LANDING);
mo->tics = (mo->movefactor == FRACUNIT) ? TICRATE/2 : (FixedDiv(35<<(FRACBITS-1), FixedSqrt(mo->movefactor)))>>FRACBITS;
S_StartSound(mo, sfx_s3k8b);
mo->player->pflags |= PF_FULLSTASIS;
}
else if (mo->player->pflags & PF_JUMPED || !(mo->player->pflags & PF_SPINNING)
|| mo->player->powers[pw_tailsfly] || mo->state-states == S_PLAY_FLY_TIRED)
{
if (mo->player->cmomx || mo->player->cmomy)
{
if (mo->player->charflags & SF_DASHMODE && mo->player->dashmode >= 3*TICRATE && mo->player->panim != PA_DASH)
P_SetPlayerMobjState(mo, S_PLAY_DASH);
else if (mo->player->speed >= FixedMul(mo->player->runspeed, mo->scale)
&& (mo->player->panim != PA_RUN || mo->state-states == S_PLAY_FLOAT_RUN))
P_SetPlayerMobjState(mo, S_PLAY_RUN);
else if ((mo->player->rmomx || mo->player->rmomy)
&& (mo->player->panim != PA_WALK || mo->state-states == S_PLAY_FLOAT))
P_SetPlayerMobjState(mo, S_PLAY_WALK);
else if (!mo->player->rmomx && !mo->player->rmomy && mo->player->panim != PA_IDLE)
P_SetPlayerMobjState(mo, S_PLAY_STND);
}
else
{
if (mo->player->charflags & SF_DASHMODE && mo->player->dashmode >= 3*TICRATE && mo->player->panim != PA_DASH)
P_SetPlayerMobjState(mo, S_PLAY_DASH);
else if (mo->player->speed >= FixedMul(mo->player->runspeed, mo->scale)
&& (mo->player->panim != PA_RUN || mo->state-states == S_PLAY_FLOAT_RUN))
P_SetPlayerMobjState(mo, S_PLAY_RUN);
else if ((mo->momx || mo->momy)
&& (mo->player->panim != PA_WALK || mo->state-states == S_PLAY_FLOAT))
P_SetPlayerMobjState(mo, S_PLAY_WALK);
else if (!mo->momx && !mo->momy && mo->player->panim != PA_IDLE)
P_SetPlayerMobjState(mo, S_PLAY_STND);
}
}
if (!(mo->player->pflags & PF_GLIDING))
mo->player->pflags &= ~(PF_JUMPED|PF_NOJUMPDAMAGE);
mo->player->pflags &= ~(PF_STARTJUMP|PF_THOKKED|PF_CANCARRY/*|PF_GLIDING*/);
mo->player->secondjump = 0;
mo->player->glidetime = 0;
mo->player->climbing = 0;
mo->player->powers[pw_tailsfly] = 0;
if (mo->player->pflags & PF_SHIELDABILITY)
{
mo->player->pflags &= ~PF_SHIELDABILITY;
if ((mo->player->powers[pw_shield] & SH_NOSTACK) == SH_ELEMENTAL) // Elemental shield's stomp attack.
{
if (mo->eflags & (MFE_UNDERWATER|MFE_TOUCHWATER)) // play a blunt sound
S_StartSound(mo, sfx_s3k4c);
else // create a fire pattern on the ground
{
S_StartSound(mo, sfx_s3k47);
P_ElementalFire(mo->player, true);
}
P_SetObjectMomZ(mo,
(mo->eflags & MFE_UNDERWATER)
? 6*FRACUNIT/5
: 5*FRACUNIT/2,
false);
P_SetPlayerMobjState(mo, S_PLAY_FALL);
mo->momx = mo->momy = 0;
clipmomz = false;
}
else if ((mo->player->powers[pw_shield] & SH_NOSTACK) == SH_BUBBLEWRAP) // Bubble shield's bounce attack.
{
P_DoBubbleBounce(mo->player);
clipmomz = false;
}
}
if (mo->player->pflags & PF_BOUNCING)
{
P_MobjCheckWater(mo);
mo->momz *= -1;
P_DoAbilityBounce(mo->player, true);
if (mo->player->scoreadd)
mo->player->scoreadd--;
clipmomz = false;
}
}
} }
if (!(mo->player->pflags & PF_SPINNING)) if (!(mo->player->pflags & PF_SPINNING) && mo->player->powers[pw_carry] != CR_NIGHTSMODE)
mo->player->pflags &= ~PF_STARTDASH; mo->player->pflags &= ~PF_STARTDASH;
if (clipmomz) if (clipmomz)

View File

@ -2244,7 +2244,7 @@ static void P_LevelInitStuff(void)
players[i].xtralife = players[i].deadtimer = players[i].numboxes = players[i].totalring = players[i].laps = 0; players[i].xtralife = players[i].deadtimer = players[i].numboxes = players[i].totalring = players[i].laps = 0;
players[i].rings = 0; players[i].rings = 0;
players[i].aiming = 0; players[i].aiming = 0;
players[i].pflags &= ~PF_TIMEOVER; players[i].pflags &= ~PF_GAMETYPEOVER;
players[i].losstime = 0; players[i].losstime = 0;
players[i].timeshit = 0; players[i].timeshit = 0;

View File

@ -3985,7 +3985,7 @@ DoneSection2:
player->powers[pw_carry] = CR_ZOOMTUBE; player->powers[pw_carry] = CR_ZOOMTUBE;
player->speed = speed; player->speed = speed;
player->pflags |= PF_SPINNING; player->pflags |= PF_SPINNING;
player->pflags &= ~(PF_JUMPED|PF_NOJUMPDAMAGE|PF_GLIDING|PF_SLIDING|PF_CANCARRY); player->pflags &= ~(PF_JUMPED|PF_NOJUMPDAMAGE|PF_GLIDING|PF_BOUNCING|PF_SLIDING|PF_CANCARRY);
player->climbing = 0; player->climbing = 0;
if (player->mo->state-states != S_PLAY_ROLL) if (player->mo->state-states != S_PLAY_ROLL)
@ -4065,7 +4065,7 @@ DoneSection2:
player->powers[pw_carry] = CR_ZOOMTUBE; player->powers[pw_carry] = CR_ZOOMTUBE;
player->speed = speed; player->speed = speed;
player->pflags |= PF_SPINNING; player->pflags |= PF_SPINNING;
player->pflags &= ~(PF_JUMPED|PF_NOJUMPDAMAGE|PF_GLIDING|PF_SLIDING|PF_CANCARRY); player->pflags &= ~(PF_JUMPED|PF_NOJUMPDAMAGE|PF_GLIDING|PF_BOUNCING|PF_SLIDING|PF_CANCARRY);
player->climbing = 0; player->climbing = 0;
if (player->mo->state-states != S_PLAY_ROLL) if (player->mo->state-states != S_PLAY_ROLL)
@ -4373,7 +4373,7 @@ DoneSection2:
S_StartSound(player->mo, sfx_s3k4a); S_StartSound(player->mo, sfx_s3k4a);
player->pflags &= ~(PF_JUMPED|PF_NOJUMPDAMAGE|PF_GLIDING|PF_SLIDING|PF_CANCARRY); player->pflags &= ~(PF_JUMPED|PF_NOJUMPDAMAGE|PF_GLIDING|PF_BOUNCING|PF_SLIDING|PF_CANCARRY);
player->climbing = 0; player->climbing = 0;
P_SetThingPosition(player->mo); P_SetThingPosition(player->mo);
P_SetPlayerMobjState(player->mo, S_PLAY_RIDE); P_SetPlayerMobjState(player->mo, S_PLAY_RIDE);

View File

@ -533,7 +533,7 @@ static inline void P_DoTagStuff(void)
for (i=0; i < MAXPLAYERS; i++) for (i=0; i < MAXPLAYERS; i++)
{ {
if (playeringame[i] && !players[i].spectator && players[i].playerstate == PST_LIVE if (playeringame[i] && !players[i].spectator && players[i].playerstate == PST_LIVE
&& !(players[i].pflags & (PF_TAGIT|PF_TAGGED))) && !(players[i].pflags & (PF_TAGIT|PF_GAMETYPEOVER)))
//points given is the number of participating players divided by two. //points given is the number of participating players divided by two.
P_AddPlayerScore(&players[i], participants/2); P_AddPlayerScore(&players[i], participants/2);
} }

View File

@ -576,7 +576,7 @@ static void P_DeNightserizePlayer(player_t *player)
thinker_t *th; thinker_t *th;
mobj_t *mo2; mobj_t *mo2;
player->powers[pw_carry] = CR_NONE; player->powers[pw_carry] = CR_NIGHTSFALL;
player->powers[pw_underwater] = 0; player->powers[pw_underwater] = 0;
player->pflags &= ~(PF_USEDOWN|PF_JUMPDOWN|PF_ATTACKDOWN|PF_STARTDASH|PF_GLIDING|PF_STARTJUMP|PF_JUMPED|PF_NOJUMPDAMAGE|PF_THOKKED|PF_SPINNING|PF_DRILLING|PF_TRANSFERTOCLOSEST); player->pflags &= ~(PF_USEDOWN|PF_JUMPDOWN|PF_ATTACKDOWN|PF_STARTDASH|PF_GLIDING|PF_STARTJUMP|PF_JUMPED|PF_NOJUMPDAMAGE|PF_THOKKED|PF_SPINNING|PF_DRILLING|PF_TRANSFERTOCLOSEST);
@ -603,7 +603,6 @@ static void P_DeNightserizePlayer(player_t *player)
player->marescore = 0; player->marescore = 0;
P_SetPlayerMobjState(player->mo, S_PLAY_FALL); P_SetPlayerMobjState(player->mo, S_PLAY_FALL);
player->pflags |= PF_NIGHTSFALL;
// If in a special stage, add some preliminary exit time. // If in a special stage, add some preliminary exit time.
if (G_IsSpecialStage(gamemap)) if (G_IsSpecialStage(gamemap))
@ -863,7 +862,7 @@ void P_DoPlayerPain(player_t *player, mobj_t *source, mobj_t *inflictor)
// Point penalty for hitting a hazard during tag. // Point penalty for hitting a hazard during tag.
// Discourages players from intentionally hurting themselves to avoid being tagged. // Discourages players from intentionally hurting themselves to avoid being tagged.
if (gametype == GT_TAG && (!(player->pflags & PF_TAGGED) && !(player->pflags & PF_TAGIT))) if (gametype == GT_TAG && (!(player->pflags & PF_GAMETYPEOVER) && !(player->pflags & PF_TAGIT)))
{ {
if (player->score >= 50) if (player->score >= 50)
player->score -= 50; player->score -= 50;
@ -885,7 +884,7 @@ void P_ResetPlayer(player_t *player)
{ {
player->pflags &= ~(PF_SPINNING|PF_STARTDASH|PF_STARTJUMP|PF_JUMPED|PF_NOJUMPDAMAGE|PF_GLIDING|PF_THOKKED|PF_CANCARRY|PF_SHIELDABILITY|PF_BOUNCING); player->pflags &= ~(PF_SPINNING|PF_STARTDASH|PF_STARTJUMP|PF_JUMPED|PF_NOJUMPDAMAGE|PF_GLIDING|PF_THOKKED|PF_CANCARRY|PF_SHIELDABILITY|PF_BOUNCING);
if (!(player->powers[pw_carry] == CR_NIGHTSMODE || player->powers[pw_carry] == CR_BRAKGOOP)) if (!(player->powers[pw_carry] == CR_NIGHTSMODE || player->powers[pw_carry] == CR_NIGHTSFALL || player->powers[pw_carry] == CR_BRAKGOOP))
player->powers[pw_carry] = CR_NONE; player->powers[pw_carry] = CR_NONE;
player->secondjump = 0; player->secondjump = 0;
@ -1778,6 +1777,122 @@ boolean P_InSpaceSector(mobj_t *mo) // Returns true if you are in space
return false; // No vacuum here, Captain! return false; // No vacuum here, Captain!
} }
//
// P_PlayerHitFloor
//
// Handles player hitting floor surface.
// Returns whether to clip momz.
boolean P_PlayerHitFloor(player_t *player)
{
boolean clipmomz;
I_Assert(player->mo != NULL);
if ((clipmomz = !(P_CheckDeathPitCollide(player->mo))) && player->mo->health && !player->spectator)
{
if ((player->charability2 == CA2_SPINDASH) && !(player->pflags & PF_THOKKED) && (player->cmd.buttons & BT_USE) && (FixedHypot(player->mo->momx, player->mo->momy) > (5*player->mo->scale)))
{
player->pflags |= PF_SPINNING;
P_SetPlayerMobjState(player->mo, S_PLAY_ROLL);
S_StartSound(player->mo, sfx_spin);
}
else
player->pflags &= ~PF_SPINNING;
if (player->pflags & PF_GLIDING) // ground gliding
{
player->skidtime = TICRATE;
player->mo->tics = -1;
}
else if (player->charability2 == CA2_MELEE && (player->panim == PA_ABILITY2 && player->mo->state-states != S_PLAY_MELEE_LANDING))
{
P_SetPlayerMobjState(player->mo, S_PLAY_MELEE_LANDING);
player->mo->tics = (player->mo->movefactor == FRACUNIT) ? TICRATE/2 : (FixedDiv(35<<(FRACBITS-1), FixedSqrt(player->mo->movefactor)))>>FRACBITS;
S_StartSound(player->mo, sfx_s3k8b);
player->pflags |= PF_FULLSTASIS;
}
else if (player->pflags & PF_JUMPED || !(player->pflags & PF_SPINNING)
|| player->powers[pw_tailsfly] || player->mo->state-states == S_PLAY_FLY_TIRED)
{
if (player->cmomx || player->cmomy)
{
if (player->charflags & SF_DASHMODE && player->dashmode >= 3*TICRATE && player->panim != PA_DASH)
P_SetPlayerMobjState(player->mo, S_PLAY_DASH);
else if (player->speed >= FixedMul(player->runspeed, player->mo->scale)
&& (player->panim != PA_RUN || player->mo->state-states == S_PLAY_FLOAT_RUN))
P_SetPlayerMobjState(player->mo, S_PLAY_RUN);
else if ((player->rmomx || player->rmomy)
&& (player->panim != PA_WALK || player->mo->state-states == S_PLAY_FLOAT))
P_SetPlayerMobjState(player->mo, S_PLAY_WALK);
else if (!player->rmomx && !player->rmomy && player->panim != PA_IDLE)
P_SetPlayerMobjState(player->mo, S_PLAY_STND);
}
else
{
if (player->charflags & SF_DASHMODE && player->dashmode >= 3*TICRATE && player->panim != PA_DASH)
P_SetPlayerMobjState(player->mo, S_PLAY_DASH);
else if (player->speed >= FixedMul(player->runspeed, player->mo->scale)
&& (player->panim != PA_RUN || player->mo->state-states == S_PLAY_FLOAT_RUN))
P_SetPlayerMobjState(player->mo, S_PLAY_RUN);
else if ((player->mo->momx || player->mo->momy)
&& (player->panim != PA_WALK || player->mo->state-states == S_PLAY_FLOAT))
P_SetPlayerMobjState(player->mo, S_PLAY_WALK);
else if (!player->mo->momx && !player->mo->momy && player->panim != PA_IDLE)
P_SetPlayerMobjState(player->mo, S_PLAY_STND);
}
}
if (!(player->pflags & PF_GLIDING))
player->pflags &= ~(PF_JUMPED|PF_NOJUMPDAMAGE);
player->pflags &= ~(PF_STARTJUMP|PF_THOKKED|PF_CANCARRY/*|PF_GLIDING*/);
player->secondjump = 0;
player->glidetime = 0;
player->climbing = 0;
player->powers[pw_tailsfly] = 0;
if (player->pflags & PF_SHIELDABILITY)
{
player->pflags &= ~PF_SHIELDABILITY;
if ((player->powers[pw_shield] & SH_NOSTACK) == SH_ELEMENTAL) // Elemental shield's stomp attack.
{
if (player->mo->eflags & (MFE_UNDERWATER|MFE_TOUCHWATER)) // play a blunt sound
S_StartSound(player->mo, sfx_s3k4c);
else // create a fire pattern on the ground
{
S_StartSound(player->mo, sfx_s3k47);
P_ElementalFire(player, true);
}
P_SetObjectMomZ(player->mo,
(player->mo->eflags & MFE_UNDERWATER)
? 6*FRACUNIT/5
: 5*FRACUNIT/2,
false);
P_SetPlayerMobjState(player->mo, S_PLAY_FALL);
player->mo->momx = player->mo->momy = 0;
clipmomz = false;
}
else if ((player->powers[pw_shield] & SH_NOSTACK) == SH_BUBBLEWRAP) // Bubble shield's bounce attack.
{
P_DoBubbleBounce(player);
clipmomz = false;
}
}
if (player->pflags & PF_BOUNCING)
{
P_MobjCheckWater(player->mo);
player->mo->momz *= -1;
P_DoAbilityBounce(player, true);
if (player->scoreadd)
player->scoreadd--;
clipmomz = false;
}
}
return clipmomz;
}
boolean P_InQuicksand(mobj_t *mo) // Returns true if you are in quicksand boolean P_InQuicksand(mobj_t *mo) // Returns true if you are in quicksand
{ {
sector_t *sector = mo->subsector->sector; sector_t *sector = mo->subsector->sector;
@ -2153,6 +2268,9 @@ static void P_CheckQuicksand(player_t *player)
if (player->mo->z + player->mo->height >= ceilingheight) if (player->mo->z + player->mo->height >= ceilingheight)
player->mo->z = ceilingheight - player->mo->height; player->mo->z = ceilingheight - player->mo->height;
if (player->mo->momz <= 0)
P_PlayerHitFloor(player);
} }
else else
{ {
@ -2162,6 +2280,9 @@ static void P_CheckQuicksand(player_t *player)
if (player->mo->z <= floorheight) if (player->mo->z <= floorheight)
player->mo->z = floorheight; player->mo->z = floorheight;
if (player->mo->momz >= 0)
P_PlayerHitFloor(player);
} }
friction = abs(rover->master->v1->y - rover->master->v2->y)>>6; friction = abs(rover->master->v1->y - rover->master->v2->y)>>6;
@ -6282,7 +6403,7 @@ static void P_NiGHTSMovement(player_t *player)
&& ((cmd->buttons & (BT_CAMLEFT|BT_CAMRIGHT)) == (BT_CAMLEFT|BT_CAMRIGHT) && ((cmd->buttons & (BT_CAMLEFT|BT_CAMRIGHT)) == (BT_CAMLEFT|BT_CAMRIGHT)
|| (cmd->buttons & BT_USE))) || (cmd->buttons & BT_USE)))
{ {
if (!(player->pflags & PF_SKIDDOWN)) if (!(player->pflags & PF_STARTDASH))
S_StartSound(player->mo, sfx_ngskid); S_StartSound(player->mo, sfx_ngskid);
// You can tap the button to only slow down a bit, // You can tap the button to only slow down a bit,
@ -6300,10 +6421,10 @@ static void P_NiGHTSMovement(player_t *player)
} }
} }
player->pflags |= PF_SKIDDOWN; player->pflags |= PF_STARTDASH;
} }
else else
player->pflags &= ~PF_SKIDDOWN; player->pflags &= ~PF_STARTDASH;
{ {
const angle_t fa = (FixedAngle(player->flyangle*FRACUNIT)>>ANGLETOFINESHIFT) & FINEMASK; const angle_t fa = (FixedAngle(player->flyangle*FRACUNIT)>>ANGLETOFINESHIFT) & FINEMASK;
@ -6749,7 +6870,7 @@ static void P_MovePlayer(player_t *player)
if (!(player->pflags & PF_TAGIT)) if (!(player->pflags & PF_TAGIT))
{ {
forcestasis = true; forcestasis = true;
if (player->pflags & PF_TAGGED) // Already hit. if (player->pflags & PF_GAMETYPEOVER) // Already hit.
player->powers[pw_flashing] = 5; player->powers[pw_flashing] = 5;
} }
} }
@ -6819,8 +6940,7 @@ static void P_MovePlayer(player_t *player)
P_CheckQuicksand(player); P_CheckQuicksand(player);
return; return;
} }
else if (player->powers[pw_carry] == CR_NIGHTSFALL && P_IsObjectOnGround(player->mo))
if (player->pflags & PF_NIGHTSFALL && P_IsObjectOnGround(player->mo))
{ {
if (G_IsSpecialStage(gamemap)) if (G_IsSpecialStage(gamemap))
{ {
@ -6832,7 +6952,7 @@ static void P_MovePlayer(player_t *player)
} }
else if (player->rings > 0) else if (player->rings > 0)
P_DamageMobj(player->mo, NULL, NULL, 1, 0); P_DamageMobj(player->mo, NULL, NULL, 1, 0);
player->pflags &= ~PF_NIGHTSFALL; player->powers[pw_carry] = CR_NONE;
} }
} }
@ -7192,7 +7312,7 @@ static void P_MovePlayer(player_t *player)
//////////////////////////// ////////////////////////////
// If the player isn't on the ground, make sure they aren't in a "starting dash" position. // If the player isn't on the ground, make sure they aren't in a "starting dash" position.
if (!onground) if (!onground && player->powers[pw_carry] != CR_NIGHTSMODE)
{ {
player->pflags &= ~PF_STARTDASH; player->pflags &= ~PF_STARTDASH;
player->dashspeed = 0; player->dashspeed = 0;
@ -7209,7 +7329,7 @@ static void P_MovePlayer(player_t *player)
P_DoJumpStuff(player, cmd); P_DoJumpStuff(player, cmd);
// If you're not spinning, you'd better not be spindashing! // If you're not spinning, you'd better not be spindashing!
if (!(player->pflags & PF_SPINNING)) if (!(player->pflags & PF_SPINNING) && player->powers[pw_carry] != CR_NIGHTSMODE)
player->pflags &= ~PF_STARTDASH; player->pflags &= ~PF_STARTDASH;
////////////////// //////////////////
@ -8390,7 +8510,7 @@ static void P_DeathThink(player_t *player)
if (gametype == GT_RACE || gametype == GT_COMPETITION || (gametype == GT_COOP && (multiplayer || netgame))) if (gametype == GT_RACE || gametype == GT_COMPETITION || (gametype == GT_COOP && (multiplayer || netgame)))
{ {
// Keep time rolling in race mode // Keep time rolling in race mode
if (!(countdown2 && !countdown) && !player->exiting && !(player->pflags & PF_TIMEOVER)) if (!(countdown2 && !countdown) && !player->exiting && !(player->pflags & PF_GAMETYPEOVER))
{ {
if (gametype == GT_RACE || gametype == GT_COMPETITION) if (gametype == GT_RACE || gametype == GT_COMPETITION)
{ {
@ -9415,7 +9535,7 @@ void P_PlayerThink(player_t *player)
if (netgame && player->mo->health > 0) if (netgame && player->mo->health > 0)
CONS_Printf(M_GetText("%s ran out of time.\n"), player_names[player-players]); CONS_Printf(M_GetText("%s ran out of time.\n"), player_names[player-players]);
player->pflags |= PF_TIMEOVER; player->pflags |= PF_GAMETYPEOVER;
if (player->powers[pw_carry] == CR_NIGHTSMODE) if (player->powers[pw_carry] == CR_NIGHTSMODE)
{ {
@ -9614,55 +9734,116 @@ void P_PlayerThink(player_t *player)
if (!player->mo) if (!player->mo)
return; // P_MovePlayer removed player->mo. return; // P_MovePlayer removed player->mo.
if ((player->climbing // stuff where the direction is forced at all times // deez New User eXperiences.
|| (player->pflags & (PF_GLIDING|PF_SLIDING)))
|| (player->powers[pw_carry] == CR_NIGHTSMODE)
|| P_AnalogMove(player) // keep things synchronised up there, since the camera IS seperate from player motion when that happens
|| G_RingSlingerGametype()) // no firing rings in directions your player isn't aiming
player->drawangle = player->mo->angle;
else if (player->pflags & PF_STARTDASH) // fun spindash experiment
{ {
angle_t diff = (player->mo->angle - player->drawangle); // Directionchar!
if (diff > ANGLE_180) // Camera angle stuff.
diff = InvAngle(InvAngle(diff)/4); if (player->exiting) // no control, no modification
else ;
diff /= 4; else if (!(player->pflags & PF_DIRECTIONCHAR)
player->drawangle += diff; || (player->climbing // stuff where the direction is forced at all times
} || (player->pflags & PF_GLIDING))
else if (P_PlayerInPain(player)) || (player->powers[pw_carry] == CR_NIGHTSMODE)
; || (P_AnalogMove(player) || twodlevel || player->mo->flags2 & MF2_TWOD) // keep things synchronised up there, since the camera IS seperate from player motion when that happens
else if (player->powers[pw_carry] && player->mo->tracer) // carry || G_RingSlingerGametype()) // no firing rings in directions your player isn't aiming
{ player->drawangle = player->mo->angle;
switch (player->powers[pw_carry]) else if (P_PlayerInPain(player))
;
else if (player->powers[pw_carry] && player->mo->tracer) // carry
{ {
case CR_PLAYER: switch (player->powers[pw_carry])
player->drawangle = (player->mo->tracer->player ? player->mo->tracer->player->drawangle : player->mo->tracer->angle); {
break; case CR_PLAYER:
/* -- in case we wanted to have the camera freely movable during zoom tube style stuff player->drawangle = (player->mo->tracer->player ? player->mo->tracer->player->drawangle : player->mo->tracer->angle);
case CR_ZOOMTUBE: break;
case CR_ROPEHANG: /* -- in case we wanted to have the camera freely movable during zoom tube style stuff
player->drawangle = R_PointToAngle2(0, 0, player->mo->momx, player->mo->momy); case CR_ZOOMTUBE:
break; case CR_ROPEHANG:
*/ player->drawangle = R_PointToAngle2(0, 0, player->mo->momx, player->mo->momy);
default: break;
player->drawangle = player->mo->angle; */
break; default:
player->drawangle = player->mo->angle;
break;
}
}
else if ((player->skidtime > (TICRATE/2 - 2) || ((player->pflags & (PF_SPINNING|PF_STARTDASH)) == PF_SPINNING)) && (abs(player->rmomx) > 5*player->mo->scale || abs(player->rmomy) > 5*player->mo->scale)) // spin/skid force
player->drawangle = R_PointToAngle2(0, 0, player->rmomx, player->rmomy);
else if (((player->charability2 == CA2_GUNSLINGER || player->charability2 == CA2_MELEE) && player->panim == PA_ABILITY2) || player->pflags & PF_STASIS || player->skidtime)
;
else
{
angle_t diff;
UINT8 factor;
if (player->pflags & PF_SLIDING)
{
#if 0 // fun hydrocity style horizontal spin
if (player->mo->eflags & MFE_TOUCHWATER || player->powers[pw_flashing] > (flashingtics/4)*3)
{
diff = (player->mo->angle - player->drawangle);
factor = 4;
}
else
{
diff = factor = 0;
player->drawangle += ANGLE_22h;
}
#else
diff = (player->mo->angle - player->drawangle);
factor = 4;
#endif
}
else if (cmd->forwardmove || cmd->sidemove) // only when you're pressing movement keys
{
diff = ((player->mo->angle + R_PointToAngle2(0, 0, cmd->forwardmove<<FRACBITS, -cmd->sidemove<<FRACBITS)) - player->drawangle);
factor = 4;
}
else if (player->rmomx || player->rmomy)
diff = factor = 0;
else
{
diff = (player->mo->angle - player->drawangle);
factor = ((player->pflags & PF_STARTDASH) ? 4 : 8);
}
if (diff)
{
if (diff > ANGLE_180)
diff = InvAngle(InvAngle(diff)/factor);
else
diff /= factor;
player->drawangle += diff;
}
}
// Autobrake!
{
boolean currentlyonground = P_IsObjectOnGround(player->mo);
if (((player->pflags & (PF_AUTOBRAKE|PF_APPLYAUTOBRAKE)) == (PF_AUTOBRAKE|PF_APPLYAUTOBRAKE))
&& !(cmd->forwardmove || cmd->sidemove)
&& (player->rmomx || player->rmomy))
{
fixed_t acceleration = player->accelstart + (FixedDiv(player->speed, player->mo->scale)>>FRACBITS) * player->acceleration * player->thrustfactor * 20;
angle_t moveAngle = R_PointToAngle2(0, 0, player->rmomx, player->rmomy);
if (!currentlyonground)
acceleration /= 2;
P_Thrust(player->mo, moveAngle, -acceleration);
}
if (!(player->pflags & PF_AUTOBRAKE)
|| player->panim == PA_SPRING
|| player->panim == PA_PAIN
|| !player->mo->health
|| player->pflags & PF_SPINNING)
player->pflags &= ~PF_APPLYAUTOBRAKE;
else if (currentlyonground)
player->pflags |= PF_APPLYAUTOBRAKE;
} }
} }
else if ((player->pflags & PF_SPINNING) && (abs(player->rmomx) > 5*player->mo->scale || abs(player->rmomy) > 5*player->mo->scale)) // spin force
player->drawangle = R_PointToAngle2(0, 0, player->rmomx, player->rmomy);
else if (((player->charability2 == CA2_GUNSLINGER || player->charability2 == CA2_MELEE) && player->panim == PA_ABILITY2) || player->pflags & PF_STASIS || player->skidtime)
;
else if (cmd->forwardmove || cmd->sidemove) // only when you're pressing movement keys
{
angle_t diff = ((player->mo->angle + R_PointToAngle2(0, 0, cmd->forwardmove<<FRACBITS, -cmd->sidemove<<FRACBITS)) - player->drawangle);
if (diff > ANGLE_180)
diff = InvAngle(InvAngle(diff)/4);
else
diff /= 4;
player->drawangle += diff;
}
if (player->powers[pw_pushing]) if (player->powers[pw_pushing])
player->powers[pw_pushing]--; player->powers[pw_pushing]--;

View File

@ -475,7 +475,7 @@ void Y_IntermissionDrawer(void)
V_DrawRightAlignedString(x+152, y, 0, va("%i", data.match.scores[i])); V_DrawRightAlignedString(x+152, y, 0, va("%i", data.match.scores[i]));
else if (intertype == int_race) else if (intertype == int_race)
{ {
if (players[data.match.num[i]].pflags & PF_TIMEOVER) if (players[data.match.num[i]].pflags & PF_GAMETYPEOVER)
snprintf(strtime, sizeof strtime, "DNF"); snprintf(strtime, sizeof strtime, "DNF");
else else
snprintf(strtime, sizeof strtime, snprintf(strtime, sizeof strtime,
@ -493,7 +493,7 @@ void Y_IntermissionDrawer(void)
V_DrawRightAlignedString(x+152+BASEVIDWIDTH/2, y, 0, va("%u", data.match.scores[i])); V_DrawRightAlignedString(x+152+BASEVIDWIDTH/2, y, 0, va("%u", data.match.scores[i]));
else if (intertype == int_race) else if (intertype == int_race)
{ {
if (players[data.match.num[i]].pflags & PF_TIMEOVER) if (players[data.match.num[i]].pflags & PF_GAMETYPEOVER)
snprintf(strtime, sizeof strtime, "DNF"); snprintf(strtime, sizeof strtime, "DNF");
else else
snprintf(strtime, sizeof strtime, "%i:%02i.%02i", G_TicsToMinutes(data.match.scores[i], true), snprintf(strtime, sizeof strtime, "%i:%02i.%02i", G_TicsToMinutes(data.match.scores[i], true),
@ -643,7 +643,7 @@ void Y_IntermissionDrawer(void)
// already constrained to 8 characters // already constrained to 8 characters
V_DrawString(x+36, y, V_ALLOWLOWERCASE, data.competition.name[i]); V_DrawString(x+36, y, V_ALLOWLOWERCASE, data.competition.name[i]);
if (players[data.competition.num[i]].pflags & PF_TIMEOVER) if (players[data.competition.num[i]].pflags & PF_GAMETYPEOVER)
snprintf(sstrtime, sizeof sstrtime, "Time Over"); snprintf(sstrtime, sizeof sstrtime, "Time Over");
else if (players[data.competition.num[i]].lives <= 0) else if (players[data.competition.num[i]].lives <= 0)
snprintf(sstrtime, sizeof sstrtime, "Game Over"); snprintf(sstrtime, sizeof sstrtime, "Game Over");