Merge branch 'charabilities_mk3' into 'master'

Charabilities MK3 - The third and probably not last branch of character stuff

Been too long since I've made a merge request. This isn't quite done, but I'd consider it... done ENOUGH that I want to work on something else, and keeping it seperate from master will just cause everyone hassle.

Abilities:
* CA_BOUNCE. Bounce on basically anything! Break bustable blocks downwards! Don't take damage from below, unless it's death pit damage, in which case eat shit! Averages to double the jumpheight of the player.
* CA_TWINSPIN can now break bustable blocks up and down in addition to breaking horizontally. Also, a spring boost.
* CA_HOVER now uses seperate states/frames, has dashmode support, and falls slowly whilst not moving very quickly.
* CA_SLOWFALL gets the CA_HOVER states/frames and dashmode support too.
* CA_HOMINGTHOK now targets Sea Egg fakes and egg guard shields, and uncurls when there's no target. It also shows a target icon.
* CA2_GUNSLINGER. Uses revitem as bullet. Autotargets within range/angle limitations on similar rules to homing attacks. Shows a target icon.
* CA2_MELEE can now break bustable blocks up and down in addition to breaking horizontally, and plays much more fluidly. Also, a spring boost.
* CA2_SPINDASH allows you to roll when landing on any surface when moving fast enough unless you have PF_THOKKED. Also, fixed you being able to roll forever.

Conversions:
* CA_DASHMODE -> SF_DASHMODE
* CA2_MULTIABILITY -> SF_MULTIABILITY
* player.jumping -> PF_STARTJUMP
* pw_ingoop -> CR_BRAKGOOP
* PF_NIGHTSMODE -> CR_NIGHTSMODE
* PF_SUPERREADY -> P_SuperReady()
* SPR2_SPIN -> SPR2_ROLL
* SPR2_DASH -> SPR2_SPIN
* SPR2_PEEL -> SPR2_DASH
* SPR2_SSTD, other super frames -> see below...

Others:
* Super sprites are now seperated from normal sprites via using S_SUPER lump in a skin, rather than being an explicitly named super version of the lump (which required a ton of effort from us to make super versions of all sprite2 names). Accessible via FF_SPR2SUPER.
* Unlockable skin stuff is now netcode synchronised. We won't be repeating 2.1's bullshit if we can help it!
* Host can't switch their skin if there's any restrictions applied, since that was unfair.
* Unique Attraction Shield sound instead of reusing S3nK Thundercoin sound.
* Character select menu code is defuckened.
* Fixed zoom tube camera distance being borq'd by a bug.
* Hudnames are now padded if they're less than 5 symbols long.
* Instead of jump damage when jumping being controlled directly by SF_NOJUMPDAMAGE, it now indirectly controls it via applying the flag PF_NOJUMPDAMAGE.
* SF_FASTEDGE. Does... a fast edge animation, really.
* Fixed some oversights with the SPR2isation of NiGHTS.
* P_SpawnLockOn(player_t player, mobj_t lockon, statenum_t state) function for Lua allowing the homing target visualisation stuff to be done locally without performing horrible, horrible hacks.
* Objects and sounds for the cork, which CA2_GUNSLINGER's main toter uses.

<root>/toaster/charabilities/ has the testing files outside of patch.dta, which is in master.
* srb2win_branch_charabilities.exe.
* player.dta - can't be used with master executables because of sprite2 renaming plus super stuff.
* socchar.wad - very simple WAD which helps test unlocks for the purpose of netplay.

Please let me know if you have a thunk.

See merge request !76
This commit is contained in:
Rob 2017-04-04 19:07:50 -04:00
commit 2c264d430b
39 changed files with 1669 additions and 1259 deletions

View file

@ -212,7 +212,7 @@ 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_GLIDING|PF_SLIDING|PF_NIGHTSMODE) if (sonic->player->pflags & (PF_GLIDING|PF_SLIDING|PF_BOUNCING)
|| (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])) || (sonic->player->powers[pw_carry]))
return false; return false;

View file

@ -1165,7 +1165,7 @@ found:
if (var == &cv_forceskin) if (var == &cv_forceskin)
{ {
var->value = R_SkinAvailable(var->string); var->value = R_SkinAvailable(var->string);
if (!R_SkinUnlock(var->value)) if (!R_SkinUsable(-1, var->value))
var->value = -1; var->value = -1;
} }
else else
@ -1361,6 +1361,16 @@ static void CV_SetCVar(consvar_t *var, const char *value, boolean stealth)
return; return;
} }
if (var == &cv_forceskin)
{
INT32 skin = R_SkinAvailable(value);
if ((stricmp(value, "None")) && ((skin == -1) || !R_SkinUsable(-1, skin)))
{
CONS_Printf("Please provide a valid skin name (\"None\" disables).\n");
return;
}
}
// Only add to netcmd buffer if in a netgame, otherwise, just change it. // Only add to netcmd buffer if in a netgame, otherwise, just change it.
if (netgame || multiplayer) if (netgame || multiplayer)
{ {
@ -1478,7 +1488,7 @@ void CV_AddValue(consvar_t *var, INT32 increment)
else if (newvalue >= numskins) else if (newvalue >= numskins)
newvalue = -1; newvalue = -1;
} while ((oldvalue != newvalue) } while ((oldvalue != newvalue)
&& !(R_SkinUnlock(newvalue))); && !(R_SkinUsable(-1, newvalue)));
} }
else else
newvalue = var->value + increment; newvalue = var->value + increment;

View file

@ -528,6 +528,7 @@ static inline void resynch_write_player(resynch_pak *rsp, const size_t i)
rsp->skincolor = players[i].skincolor; rsp->skincolor = players[i].skincolor;
rsp->skin = LONG(players[i].skin); rsp->skin = LONG(players[i].skin);
rsp->availabilities = LONG(players[i].availabilities);
// Just in case Lua does something like // Just in case Lua does something like
// modify these at runtime // modify these at runtime
rsp->camerascale = (fixed_t)LONG(players[i].camerascale); rsp->camerascale = (fixed_t)LONG(players[i].camerascale);
@ -551,7 +552,6 @@ static inline void resynch_write_player(resynch_pak *rsp, const size_t i)
rsp->playerspinheight = (fixed_t)LONG(players[i].spinheight); rsp->playerspinheight = (fixed_t)LONG(players[i].spinheight);
rsp->speed = (fixed_t)LONG(players[i].speed); rsp->speed = (fixed_t)LONG(players[i].speed);
rsp->jumping = players[i].jumping;
rsp->secondjump = players[i].secondjump; rsp->secondjump = players[i].secondjump;
rsp->fly1 = players[i].fly1; rsp->fly1 = players[i].fly1;
rsp->glidetime = (tic_t)LONG(players[i].glidetime); rsp->glidetime = (tic_t)LONG(players[i].glidetime);
@ -657,6 +657,7 @@ static void resynch_read_player(resynch_pak *rsp)
players[i].skincolor = rsp->skincolor; players[i].skincolor = rsp->skincolor;
players[i].skin = LONG(rsp->skin); players[i].skin = LONG(rsp->skin);
players[i].availabilities = LONG(rsp->availabilities);
// Just in case Lua does something like // Just in case Lua does something like
// modify these at runtime // modify these at runtime
players[i].camerascale = (fixed_t)LONG(rsp->camerascale); players[i].camerascale = (fixed_t)LONG(rsp->camerascale);
@ -680,7 +681,6 @@ static void resynch_read_player(resynch_pak *rsp)
players[i].spinheight = (fixed_t)LONG(rsp->playerspinheight); players[i].spinheight = (fixed_t)LONG(rsp->playerspinheight);
players[i].speed = (fixed_t)LONG(rsp->speed); players[i].speed = (fixed_t)LONG(rsp->speed);
players[i].jumping = rsp->jumping;
players[i].secondjump = rsp->secondjump; players[i].secondjump = rsp->secondjump;
players[i].fly1 = rsp->fly1; players[i].fly1 = rsp->fly1;
players[i].glidetime = (tic_t)LONG(rsp->glidetime); players[i].glidetime = (tic_t)LONG(rsp->glidetime);
@ -1364,6 +1364,7 @@ static boolean SV_SendServerConfig(INT32 node)
// which is nice and easy for us to detect // which is nice and easy for us to detect
memset(netbuffer->u.servercfg.playerskins, 0xFF, sizeof(netbuffer->u.servercfg.playerskins)); memset(netbuffer->u.servercfg.playerskins, 0xFF, sizeof(netbuffer->u.servercfg.playerskins));
memset(netbuffer->u.servercfg.playercolor, 0xFF, sizeof(netbuffer->u.servercfg.playercolor)); memset(netbuffer->u.servercfg.playercolor, 0xFF, sizeof(netbuffer->u.servercfg.playercolor));
memset(netbuffer->u.servercfg.playeravailabilities, 0xFF, sizeof(netbuffer->u.servercfg.playeravailabilities));
for (i = 0; i < MAXPLAYERS; i++) for (i = 0; i < MAXPLAYERS; i++)
{ {
@ -1371,6 +1372,7 @@ static boolean SV_SendServerConfig(INT32 node)
continue; continue;
netbuffer->u.servercfg.playerskins[i] = (UINT8)players[i].skin; netbuffer->u.servercfg.playerskins[i] = (UINT8)players[i].skin;
netbuffer->u.servercfg.playercolor[i] = (UINT8)players[i].skincolor; netbuffer->u.servercfg.playercolor[i] = (UINT8)players[i].skincolor;
netbuffer->u.servercfg.playeravailabilities[i] = (UINT32)LONG(players[i].availabilities);
} }
memcpy(netbuffer->u.servercfg.server_context, server_context, 8); memcpy(netbuffer->u.servercfg.server_context, server_context, 8);
@ -2308,12 +2310,7 @@ static void ResetNode(INT32 node);
void CL_ClearPlayer(INT32 playernum) void CL_ClearPlayer(INT32 playernum)
{ {
if (players[playernum].mo) if (players[playernum].mo)
{
// Don't leave a NiGHTS ghost!
if ((players[playernum].pflags & PF_NIGHTSMODE) && players[playernum].mo->tracer)
P_RemoveMobj(players[playernum].mo->tracer);
P_RemoveMobj(players[playernum].mo); P_RemoveMobj(players[playernum].mo);
}
memset(&players[playernum], 0, sizeof (player_t)); memset(&players[playernum], 0, sizeof (player_t));
} }
@ -3497,10 +3494,12 @@ static void HandlePacketFromAwayNode(SINT8 node)
for (j = 0; j < MAXPLAYERS; j++) for (j = 0; j < MAXPLAYERS; j++)
{ {
if (netbuffer->u.servercfg.playerskins[j] == 0xFF if (netbuffer->u.servercfg.playerskins[j] == 0xFF
&& netbuffer->u.servercfg.playercolor[j] == 0xFF) && netbuffer->u.servercfg.playercolor[j] == 0xFF
&& netbuffer->u.servercfg.playeravailabilities[j] == 0xFFFFFFFF)
continue; // not in game continue; // not in game
playeringame[j] = true; playeringame[j] = true;
players[j].availabilities = (UINT32)LONG(netbuffer->u.servercfg.playeravailabilities[j]);
SetPlayerSkinByNum(j, (INT32)netbuffer->u.servercfg.playerskins[j]); SetPlayerSkinByNum(j, (INT32)netbuffer->u.servercfg.playerskins[j]);
players[j].skincolor = netbuffer->u.servercfg.playercolor[j]; players[j].skincolor = netbuffer->u.servercfg.playercolor[j];
} }

View file

@ -172,6 +172,7 @@ typedef struct
UINT8 skincolor; UINT8 skincolor;
INT32 skin; INT32 skin;
UINT32 availabilities;
// Just in case Lua does something like // Just in case Lua does something like
// modify these at runtime // modify these at runtime
fixed_t camerascale; fixed_t camerascale;
@ -195,7 +196,6 @@ typedef struct
fixed_t playerspinheight; fixed_t playerspinheight;
fixed_t speed; fixed_t speed;
UINT8 jumping;
UINT8 secondjump; UINT8 secondjump;
UINT8 fly1; UINT8 fly1;
tic_t glidetime; tic_t glidetime;
@ -284,6 +284,7 @@ typedef struct
// 0xFF == not in game; else player skin num // 0xFF == not in game; else player skin num
UINT8 playerskins[MAXPLAYERS]; UINT8 playerskins[MAXPLAYERS];
UINT8 playercolor[MAXPLAYERS]; UINT8 playercolor[MAXPLAYERS];
UINT32 playeravailabilities[MAXPLAYERS];
UINT8 gametype; UINT8 gametype;
UINT8 modifiedgame; UINT8 modifiedgame;

View file

@ -1011,7 +1011,7 @@ UINT8 CanChangeSkin(INT32 playernum)
return true; return true;
// Force skin in effect. // Force skin in effect.
if (client && (cv_forceskin.value != -1) && !(adminplayer == playernum && serverplayer == -1)) if ((cv_forceskin.value != -1) || (mapheaderinfo[gamemap-1] && mapheaderinfo[gamemap-1]->forcecharacter[0] != '\0'))
return false; return false;
// Can change skin in intermission and whatnot. // Can change skin in intermission and whatnot.
@ -1109,6 +1109,8 @@ static void SendNameAndColor(void)
if (!Playing()) if (!Playing())
return; return;
players[consoleplayer].availabilities = R_GetSkinAvailabilities();
// If you're not in a netgame, merely update the skin, color, and name. // If you're not in a netgame, merely update the skin, color, and name.
if (!netgame) if (!netgame)
{ {
@ -1127,7 +1129,7 @@ static void SendNameAndColor(void)
SetPlayerSkinByNum(consoleplayer, 0); SetPlayerSkinByNum(consoleplayer, 0);
CV_StealthSet(&cv_skin, skins[0].name); CV_StealthSet(&cv_skin, skins[0].name);
} }
else if ((foundskin = R_SkinAvailable(cv_skin.string)) != -1 && R_SkinUnlock(foundskin)) else if ((foundskin = R_SkinAvailable(cv_skin.string)) != -1 && R_SkinUsable(consoleplayer, foundskin))
{ {
boolean notsame; boolean notsame;
@ -1174,7 +1176,7 @@ static void SendNameAndColor(void)
// check if player has the skin loaded (cv_skin may have // check if player has the skin loaded (cv_skin may have
// the name of a skin that was available in the previous game) // the name of a skin that was available in the previous game)
cv_skin.value = R_SkinAvailable(cv_skin.string); cv_skin.value = R_SkinAvailable(cv_skin.string);
if ((cv_skin.value < 0) || !R_SkinUnlock(cv_skin.value)) if ((cv_skin.value < 0) || !R_SkinUsable(consoleplayer, cv_skin.value))
{ {
CV_StealthSet(&cv_skin, DEFAULTSKIN); CV_StealthSet(&cv_skin, DEFAULTSKIN);
cv_skin.value = 0; cv_skin.value = 0;
@ -1182,6 +1184,7 @@ static void SendNameAndColor(void)
// Finally write out the complete packet and send it off. // Finally write out the complete packet and send it off.
WRITESTRINGN(p, cv_playername.zstring, MAXPLAYERNAME); WRITESTRINGN(p, cv_playername.zstring, MAXPLAYERNAME);
WRITEUINT32(p, (UINT32)players[consoleplayer].availabilities);
WRITEUINT8(p, (UINT8)cv_playercolor.value); WRITEUINT8(p, (UINT8)cv_playercolor.value);
WRITEUINT8(p, (UINT8)cv_skin.value); WRITEUINT8(p, (UINT8)cv_skin.value);
SendNetXCmd(XD_NAMEANDCOLOR, buf, p - buf); SendNetXCmd(XD_NAMEANDCOLOR, buf, p - buf);
@ -1224,6 +1227,8 @@ static void SendNameAndColor2(void)
if (!Playing()) if (!Playing())
return; return;
players[secondplaya].availabilities = R_GetSkinAvailabilities();
// If you're not in a netgame, merely update the skin, color, and name. // If you're not in a netgame, merely update the skin, color, and name.
if (botingame) if (botingame)
{ {
@ -1252,7 +1257,7 @@ static void SendNameAndColor2(void)
SetPlayerSkinByNum(secondplaya, forcedskin); SetPlayerSkinByNum(secondplaya, forcedskin);
CV_StealthSet(&cv_skin2, skins[forcedskin].name); CV_StealthSet(&cv_skin2, skins[forcedskin].name);
} }
else if ((foundskin = R_SkinAvailable(cv_skin2.string)) != -1 && R_SkinUnlock(foundskin)) else if ((foundskin = R_SkinAvailable(cv_skin2.string)) != -1 && R_SkinUsable(secondplaya, foundskin))
{ {
boolean notsame; boolean notsame;
@ -1307,6 +1312,7 @@ static void Got_NameAndColor(UINT8 **cp, INT32 playernum)
#endif #endif
READSTRINGN(*cp, name, MAXPLAYERNAME); READSTRINGN(*cp, name, MAXPLAYERNAME);
p->availabilities = READUINT32(*cp);
color = READUINT8(*cp); color = READUINT8(*cp);
skin = READUINT8(*cp); skin = READUINT8(*cp);
@ -1323,6 +1329,7 @@ static void Got_NameAndColor(UINT8 **cp, INT32 playernum)
if (server && (p != &players[consoleplayer] && p != &players[secondarydisplayplayer])) if (server && (p != &players[consoleplayer] && p != &players[secondarydisplayplayer]))
{ {
boolean kick = false; boolean kick = false;
INT32 s;
// team colors // team colors
if (G_GametypeHasTeams()) if (G_GametypeHasTeams())
@ -1337,6 +1344,16 @@ static void Got_NameAndColor(UINT8 **cp, INT32 playernum)
if (!p->skincolor) if (!p->skincolor)
kick = true; kick = true;
// availabilities
for (s = 0; s < MAXSKINS; s++)
{
if (!skins[s].availability && (p->availabilities & (1 << s)))
{
kick = true;
break;
}
}
if (kick) if (kick)
{ {
XBOXSTATIC UINT8 buf[2]; XBOXSTATIC UINT8 buf[2];
@ -4043,13 +4060,6 @@ static void Command_Archivetest_f(void)
*/ */
static void ForceSkin_OnChange(void) static void ForceSkin_OnChange(void)
{ {
if ((server || adminplayer == consoleplayer) && ((cv_forceskin.value == -1 && stricmp(cv_forceskin.string, "None")) || !(R_SkinUnlock(cv_forceskin.value))))
{
CONS_Printf("Please provide a valid skin name (\"None\" disables).\n");
CV_SetValue(&cv_forceskin, -1);
return;
}
// NOT in SP, silly! // NOT in SP, silly!
if (!(netgame || multiplayer)) if (!(netgame || multiplayer))
return; return;
@ -4058,7 +4068,7 @@ static void ForceSkin_OnChange(void)
CONS_Printf("The server has lifted the forced skin restrictions.\n"); CONS_Printf("The server has lifted the forced skin restrictions.\n");
else else
{ {
CONS_Printf("The server is restricting all players to skin \"%s\".\n",skins[cv_forceskin.value].realname); CONS_Printf("The server is restricting all players to skin \"%s\".\n",skins[cv_forceskin.value].name);
ForceAllSkins(cv_forceskin.value); ForceAllSkins(cv_forceskin.value);
} }
} }

View file

@ -32,19 +32,21 @@
// Extra abilities/settings for skins (combinable stuff) // Extra abilities/settings for skins (combinable stuff)
typedef enum typedef enum
{ {
SF_SUPER = 1, // Can turn super in singleplayer/co-op mode. SF_SUPER = 1, // Can turn super in singleplayer/co-op mode?
SF_SUPERANIMS = 1<<1, // If super, use the super sonic animations SF_NOSUPERSPIN = 1<<1, // Should spin frames be played while super?
SF_SUPERSPIN = 1<<2, // Should spin frames be played while super? SF_NOSPINDASHDUST = 1<<2, // Spawn dust particles when charging a spindash?
SF_HIRES = 1<<3, // Draw the sprite 2x as small? SF_HIRES = 1<<3, // Draw the sprite at different size?
SF_NOSKID = 1<<4, // No skid particles etc SF_NOSKID = 1<<4, // No skid particles etc
SF_NOSPEEDADJUST = 1<<5, // Skin-specific version of disablespeedadjust SF_NOSPEEDADJUST = 1<<5, // Skin-specific version of disablespeedadjust
SF_RUNONWATER = 1<<6, // Run on top of water FOFs? SF_RUNONWATER = 1<<6, // Run on top of water FOFs?
SF_NOJUMPSPIN = 1<<7, // SPR2_JUMP defaults to SPR2_SPRG instead of SPR2_SPIN, falling states used, and player height is full when jumping? SF_NOJUMPSPIN = 1<<7, // SPR2_JUMP defaults to SPR2_SPRG instead of SPR2_ROLL, falling states used, and player height is full when jumping?
SF_NOJUMPDAMAGE = 1<<8, // Don't damage enemies, etc whilst jumping? SF_NOJUMPDAMAGE = 1<<8, // Don't damage enemies, etc whilst jumping?
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?
SF_NOSPINDASHDUST = 1<<11, // Don't spawn dust particles when charging a spindash SF_DASHMODE = 1<<11, // Sonic Advance 2 style top speed increase?
SF_FASTEDGE = 1<<12, // Faster edge teeter?
SF_MULTIABILITY = 1<<13, // Revenge of Final Demo.
// free up to and including 1<<31 // free up to and including 1<<31
} skinflags_t; } skinflags_t;
@ -65,7 +67,7 @@ typedef enum
CA_JUMPBOOST, CA_JUMPBOOST,
CA_AIRDRILL, CA_AIRDRILL,
CA_JUMPTHOK, CA_JUMPTHOK,
CA_DASHMODE, CA_BOUNCE,
CA_TWINSPIN CA_TWINSPIN
} charability_t; } charability_t;
@ -74,7 +76,7 @@ typedef enum
{ {
CA2_NONE=0, CA2_NONE=0,
CA2_SPINDASH, CA2_SPINDASH,
CA2_MULTIABILITY, CA2_GUNSLINGER,
CA2_MELEE CA2_MELEE
} charability2_t; } charability2_t;
@ -118,10 +120,8 @@ typedef enum
// Did you get a time-over? // Did you get a time-over?
PF_TIMEOVER = 1<<10, PF_TIMEOVER = 1<<10,
// Ready for Super?
PF_SUPERREADY = 1<<11,
// Character action status // Character action status
PF_STARTJUMP = 1<<11,
PF_JUMPED = 1<<12, PF_JUMPED = 1<<12,
PF_SPINNING = 1<<13, PF_SPINNING = 1<<13,
PF_STARTDASH = 1<<14, PF_STARTDASH = 1<<14,
@ -133,12 +133,11 @@ typedef enum
// Sliding (usually in water) like Labyrinth/Oil Ocean // Sliding (usually in water) like Labyrinth/Oil Ocean
PF_SLIDING = 1<<17, PF_SLIDING = 1<<17,
/*** NIGHTS STUFF ***/ // Bouncing
// Is the player in NiGHTS mode? PF_BOUNCING = 1<<18,
PF_NIGHTSMODE = 1<<18,
PF_TRANSFERTOCLOSEST = 1<<19,
// Spill rings after falling /*** NIGHTS STUFF ***/
PF_TRANSFERTOCLOSEST = 1<<19,
PF_NIGHTSFALL = 1<<20, PF_NIGHTSFALL = 1<<20,
PF_DRILLING = 1<<21, PF_DRILLING = 1<<21,
PF_SKIDDOWN = 1<<22, PF_SKIDDOWN = 1<<22,
@ -157,10 +156,10 @@ typedef enum
// Used shield ability // Used shield ability
PF_SHIELDABILITY = 1<<28, PF_SHIELDABILITY = 1<<28,
// Force jump damage? // Jump damage?
PF_FORCEJUMPDAMAGE = 1<<29 PF_NOJUMPDAMAGE = 1<<29,
// free up to and including 1<<31 // up to 1<<31 is free
} pflags_t; } pflags_t;
typedef enum typedef enum
@ -171,7 +170,7 @@ typedef enum
PA_EDGE, PA_EDGE,
PA_WALK, PA_WALK,
PA_RUN, PA_RUN,
PA_PEEL, PA_DASH,
PA_PAIN, PA_PAIN,
PA_ROLL, PA_ROLL,
PA_JUMP, PA_JUMP,
@ -223,6 +222,10 @@ typedef enum
CR_GENERIC, CR_GENERIC,
// Tails carry. // Tails carry.
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.
CR_NIGHTSMODE,
// Old Brak sucks hard, but this gimmick could be used for something better, so we might as well continue supporting it.
CR_BRAKGOOP,
// Specific level gimmicks. // Specific level gimmicks.
CR_ZOOMTUBE, CR_ZOOMTUBE,
CR_ROPEHANG, CR_ROPEHANG,
@ -262,9 +265,7 @@ typedef enum
pw_nights_helper, pw_nights_helper,
pw_nights_linkfreeze, pw_nights_linkfreeze,
//for linedef exec 427 pw_nocontrol, //for linedef exec 427
pw_nocontrol,
pw_ingoop, // In goop
NUMPOWERS NUMPOWERS
} powertype_t; } powertype_t;
@ -340,6 +341,7 @@ typedef struct player_s
UINT8 skincolor; UINT8 skincolor;
INT32 skin; INT32 skin;
UINT32 availabilities;
UINT32 score; // player score UINT32 score; // player score
fixed_t dashspeed; // dashing speed fixed_t dashspeed; // dashing speed
@ -377,7 +379,6 @@ typedef struct player_s
UINT8 gotcontinue; // Got continue from this stage? UINT8 gotcontinue; // Got continue from this stage?
fixed_t speed; // Player's speed (distance formula of MOMX and MOMY values) fixed_t speed; // Player's speed (distance formula of MOMX and MOMY values)
UINT8 jumping; // Holding down jump button
UINT8 secondjump; // Jump counter UINT8 secondjump; // Jump counter
UINT8 fly1; // Tails flying UINT8 fly1; // Tails flying

View file

@ -432,22 +432,20 @@ static void readAnimTex(MYFILE *f, INT32 num)
} }
*/ */
static boolean findFreeSlot(INT32 *num, UINT16 wadnum) static boolean findFreeSlot(INT32 *num)
{ {
// Send the character select entry to a free slot. // Send the character select entry to a free slot.
while (*num < 32 && (!(PlayerMenu[*num].status & IT_DISABLED) || description[*num].wadnum == wadnum)) // Will kill hidden characters from other files, but that's okay. while (*num < 32 && (description[*num].used))
*num = *num+1; *num = *num+1;
// No more free slots. :( // No more free slots. :(
if (*num >= 32) if (*num >= 32)
return false; return false;
PlayerMenu[*num].status = IT_CALL;
description[*num].wadnum = wadnum;
description[*num].picname[0] = '\0'; // Redesign your logo. (See M_DrawSetupChoosePlayerMenu in m_menu.c...) description[*num].picname[0] = '\0'; // Redesign your logo. (See M_DrawSetupChoosePlayerMenu in m_menu.c...)
// Found one! ^_^ // Found one! ^_^
return true; return (description[*num].used = true);
} }
// Reads a player. // Reads a player.
@ -479,7 +477,7 @@ static void readPlayer(MYFILE *f, INT32 num)
{ {
char *playertext = NULL; char *playertext = NULL;
if (!slotfound && (slotfound = findFreeSlot(&num, f->wad)) == false) if (!slotfound && (slotfound = findFreeSlot(&num)) == false)
goto done; goto done;
for (i = 0; i < MAXLINELEN-3; i++) for (i = 0; i < MAXLINELEN-3; i++)
@ -528,7 +526,7 @@ static void readPlayer(MYFILE *f, INT32 num)
if (fastcmp(word, "PICNAME")) if (fastcmp(word, "PICNAME"))
{ {
if (!slotfound && (slotfound = findFreeSlot(&num, f->wad)) == false) if (!slotfound && (slotfound = findFreeSlot(&num)) == false)
goto done; goto done;
DEH_WriteUndoline(word, &description[num].picname[0], UNDO_NONE); DEH_WriteUndoline(word, &description[num].picname[0], UNDO_NONE);
@ -536,12 +534,6 @@ static void readPlayer(MYFILE *f, INT32 num)
} }
else if (fastcmp(word, "STATUS")) else if (fastcmp(word, "STATUS"))
{ {
// Limit the status to only IT_DISABLED and IT_CALL
if (i)
i = IT_CALL;
else
i = IT_DISABLED;
/* /*
You MAY disable previous entries if you so desire... You MAY disable previous entries if you so desire...
But try to enable something that's already enabled and you will be sent to a free slot. But try to enable something that's already enabled and you will be sent to a free slot.
@ -549,15 +541,15 @@ static void readPlayer(MYFILE *f, INT32 num)
Because of this, you are allowed to edit any previous entries you like, but only if you Because of this, you are allowed to edit any previous entries you like, but only if you
signal that you are purposely doing so by disabling and then reenabling the slot. signal that you are purposely doing so by disabling and then reenabling the slot.
*/ */
if (i != IT_DISABLED && !slotfound && (slotfound = findFreeSlot(&num, f->wad)) == false) if (i && !slotfound && (slotfound = findFreeSlot(&num)) == false)
goto done; goto done;
DEH_WriteUndoline(word, va("%d", PlayerMenu[num].status), UNDO_NONE); DEH_WriteUndoline(word, va("%d", description[num].used), UNDO_NONE);
PlayerMenu[num].status = (INT16)i; description[num].used = (!!i);
} }
else if (fastcmp(word, "SKINNAME")) else if (fastcmp(word, "SKINNAME"))
{ {
// Send to free slot. // Send to free slot.
if (!slotfound && (slotfound = findFreeSlot(&num, f->wad)) == false) if (!slotfound && (slotfound = findFreeSlot(&num)) == false)
goto done; goto done;
DEH_WriteUndoline(word, description[num].skinname, UNDO_NONE); DEH_WriteUndoline(word, description[num].skinname, UNDO_NONE);
@ -3925,12 +3917,12 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
"S_PLAY_WAIT", "S_PLAY_WAIT",
"S_PLAY_WALK", "S_PLAY_WALK",
"S_PLAY_RUN", "S_PLAY_RUN",
"S_PLAY_PEEL", "S_PLAY_DASH",
"S_PLAY_PAIN", "S_PLAY_PAIN",
"S_PLAY_STUN",
"S_PLAY_DEAD", "S_PLAY_DEAD",
"S_PLAY_DRWN", "S_PLAY_DRWN",
"S_PLAY_SPIN", "S_PLAY_ROLL",
"S_PLAY_DASH",
"S_PLAY_GASP", "S_PLAY_GASP",
"S_PLAY_JUMP", "S_PLAY_JUMP",
"S_PLAY_SPRING", "S_PLAY_SPRING",
@ -3938,6 +3930,9 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
"S_PLAY_EDGE", "S_PLAY_EDGE",
"S_PLAY_RIDE", "S_PLAY_RIDE",
// CA2_SPINDASH
"S_PLAY_SPINDASH",
// CA_FLY/SWIM // CA_FLY/SWIM
"S_PLAY_FLY", "S_PLAY_FLY",
"S_PLAY_SWIM", "S_PLAY_SWIM",
@ -3948,30 +3943,25 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
"S_PLAY_CLING", "S_PLAY_CLING",
"S_PLAY_CLIMB", "S_PLAY_CLIMB",
// CA_FLOAT/CA_SLOWFALL
"S_PLAY_FLOAT",
"S_PLAY_FLOAT_RUN",
// CA_BOUNCE
"S_PLAY_BOUNCE",
"S_PLAY_BOUNCE_LANDING",
// CA2_GUNSLINGER
"S_PLAY_FIRE",
"S_PLAY_FIRE_FINISH",
// CA_TWINSPIN // CA_TWINSPIN
"S_PLAY_TWINSPIN", "S_PLAY_TWINSPIN",
// CA2_MELEE // CA2_MELEE
"S_PLAY_MELEE", "S_PLAY_MELEE",
"S_PLAY_MELEE_FINISH", "S_PLAY_MELEE_FINISH",
"S_PLAY_MELEE_LANDING",
// SF_SUPERANIMS
"S_PLAY_SUPER_STND",
"S_PLAY_SUPER_WALK",
"S_PLAY_SUPER_RUN",
"S_PLAY_SUPER_PEEL",
"S_PLAY_SUPER_PAIN",
"S_PLAY_SUPER_STUN",
"S_PLAY_SUPER_DEAD",
"S_PLAY_SUPER_DRWN",
"S_PLAY_SUPER_SPIN",
"S_PLAY_SUPER_GASP",
"S_PLAY_SUPER_JUMP",
"S_PLAY_SUPER_SPRING",
"S_PLAY_SUPER_FALL",
"S_PLAY_SUPER_EDGE",
"S_PLAY_SUPER_RIDE",
"S_PLAY_SUPER_FLOAT",
// SF_SUPER // SF_SUPER
"S_PLAY_SUPERTRANS1", "S_PLAY_SUPERTRANS1",
@ -4010,7 +4000,7 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
"S_PLAY_NIGHTS_STAND", "S_PLAY_NIGHTS_STAND",
"S_PLAY_NIGHTS_FLOAT", "S_PLAY_NIGHTS_FLOAT",
"S_PLAY_NIGHTS_PAIN", "S_PLAY_NIGHTS_STUN",
"S_PLAY_NIGHTS_PULL", "S_PLAY_NIGHTS_PULL",
"S_PLAY_NIGHTS_ATTACK", "S_PLAY_NIGHTS_ATTACK",
@ -5935,14 +5925,18 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
"S_FOUR2", "S_FOUR2",
"S_FIVE2", "S_FIVE2",
"S_LOCKON1",
"S_LOCKON2",
// Tag Sign // Tag Sign
"S_TTAG1", "S_TTAG",
// Got Flag Sign // Got Flag Sign
"S_GOTFLAG1", "S_GOTFLAG",
"S_GOTFLAG2", "S_GOTREDFLAG",
"S_GOTFLAG3", "S_GOTBLUEFLAG",
"S_GOTFLAG4",
"S_CORK",
// Red Ring // Red Ring
"S_RRNG1", "S_RRNG1",
@ -6733,9 +6727,9 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s
"MT_SCORE", // score logo "MT_SCORE", // score logo
"MT_DROWNNUMBERS", // Drowning Timer "MT_DROWNNUMBERS", // Drowning Timer
"MT_GOTEMERALD", // Chaos Emerald (intangible) "MT_GOTEMERALD", // Chaos Emerald (intangible)
"MT_LOCKON", // Target
"MT_TAG", // Tag Sign "MT_TAG", // Tag Sign
"MT_GOTFLAG", // Got Flag sign "MT_GOTFLAG", // Got Flag sign
"MT_GOTFLAG2", // Got Flag sign
// Ambient Sounds // Ambient Sounds
"MT_AWATERA", // Ambient Water Sound 1 "MT_AWATERA", // Ambient Water Sound 1
@ -6749,6 +6743,8 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s
"MT_RANDOMAMBIENT", "MT_RANDOMAMBIENT",
"MT_RANDOMAMBIENT2", "MT_RANDOMAMBIENT2",
"MT_CORK",
// Ring Weapons // Ring Weapons
"MT_REDRING", "MT_REDRING",
"MT_BOUNCERING", "MT_BOUNCERING",
@ -6972,10 +6968,8 @@ static const char *const PLAYERFLAG_LIST[] = {
// Did you get a time-over? // Did you get a time-over?
"TIMEOVER", "TIMEOVER",
// Ready for Super?
"SUPERREADY",
// Character action status // Character action status
"STARTJUMP",
"JUMPED", "JUMPED",
"SPINNING", "SPINNING",
"STARTDASH", "STARTDASH",
@ -6987,12 +6981,11 @@ static const char *const PLAYERFLAG_LIST[] = {
// Sliding (usually in water) like Labyrinth/Oil Ocean // Sliding (usually in water) like Labyrinth/Oil Ocean
"SLIDING", "SLIDING",
/*** NIGHTS STUFF ***/ // Bouncing
// Is the player in NiGHTS mode? "BOUNCING",
"NIGHTSMODE",
"TRANSFERTOCLOSEST",
// Spill rings after falling /*** NIGHTS STUFF ***/
"TRANSFERTOCLOSEST",
"NIGHTSFALL", "NIGHTSFALL",
"DRILLING", "DRILLING",
"SKIDDOWN", "SKIDDOWN",
@ -7006,7 +6999,7 @@ static const char *const PLAYERFLAG_LIST[] = {
"ANALOGMODE", // Analog mode? "ANALOGMODE", // Analog mode?
"CANCARRY", // Can carry? "CANCARRY", // Can carry?
"SHIELDABILITY", // Thokked with shield ability "SHIELDABILITY", // Thokked with shield ability
"FORCEJUMPDAMAGE", // Force jump damage "NOJUMPDAMAGE", // No jump damage
NULL // stop loop here. NULL // stop loop here.
}; };
@ -7155,8 +7148,7 @@ static const char *const POWERS_LIST[] = {
"NIGHTS_LINKFREEZE", "NIGHTS_LINKFREEZE",
//for linedef exec 427 //for linedef exec 427
"NOCONTROL", "NOCONTROL"
"INGOOP" // In goop
}; };
static const char *const HUDITEMS_LIST[] = { static const char *const HUDITEMS_LIST[] = {
@ -7248,14 +7240,15 @@ struct {
// Frame settings // Frame settings
{"FF_FRAMEMASK",FF_FRAMEMASK}, {"FF_FRAMEMASK",FF_FRAMEMASK},
{"FF_VERTICALFLIP",FF_VERTICALFLIP}, {"FF_SPR2SUPER",FF_SPR2SUPER},
{"FF_PAPERSPRITE",FF_PAPERSPRITE},
{"FF_SPR2ENDSTATE",FF_SPR2ENDSTATE}, {"FF_SPR2ENDSTATE",FF_SPR2ENDSTATE},
{"FF_SPR2MIDSTART",FF_SPR2MIDSTART}, {"FF_SPR2MIDSTART",FF_SPR2MIDSTART},
{"FF_ANIMATE",FF_ANIMATE}, {"FF_ANIMATE",FF_ANIMATE},
{"FF_RANDOMANIM",FF_RANDOMANIM}, {"FF_RANDOMANIM",FF_RANDOMANIM},
{"FF_GLOBALANIM",FF_GLOBALANIM}, {"FF_GLOBALANIM",FF_GLOBALANIM},
{"FF_FULLBRIGHT",FF_FULLBRIGHT}, {"FF_FULLBRIGHT",FF_FULLBRIGHT},
{"FF_VERTICALFLIP",FF_VERTICALFLIP},
{"FF_PAPERSPRITE",FF_PAPERSPRITE},
{"FF_TRANSMASK",FF_TRANSMASK}, {"FF_TRANSMASK",FF_TRANSMASK},
{"FF_TRANSSHIFT",FF_TRANSSHIFT}, {"FF_TRANSSHIFT",FF_TRANSSHIFT},
// new preshifted translucency (used in source) // new preshifted translucency (used in source)
@ -7380,6 +7373,8 @@ struct {
{"CR_NONE",CR_NONE}, {"CR_NONE",CR_NONE},
{"CR_GENERIC",CR_GENERIC}, {"CR_GENERIC",CR_GENERIC},
{"CR_PLAYER",CR_PLAYER}, {"CR_PLAYER",CR_PLAYER},
{"CR_NIGHTSMODE",CR_NIGHTSMODE},
{"CR_BRAKGOOP",CR_BRAKGOOP},
{"CR_ZOOMTUBE",CR_ZOOMTUBE}, {"CR_ZOOMTUBE",CR_ZOOMTUBE},
{"CR_ROPEHANG",CR_ROPEHANG}, {"CR_ROPEHANG",CR_ROPEHANG},
{"CR_MACESPIN",CR_MACESPIN}, {"CR_MACESPIN",CR_MACESPIN},
@ -7395,8 +7390,8 @@ struct {
// Character flags (skinflags_t) // Character flags (skinflags_t)
{"SF_SUPER",SF_SUPER}, {"SF_SUPER",SF_SUPER},
{"SF_SUPERANIMS",SF_SUPERANIMS}, {"SF_NOSUPERSPIN",SF_NOSUPERSPIN},
{"SF_SUPERSPIN",SF_SUPERSPIN}, {"SF_NOSPINDASHDUST",SF_NOSPINDASHDUST},
{"SF_HIRES",SF_HIRES}, {"SF_HIRES",SF_HIRES},
{"SF_NOSKID",SF_NOSKID}, {"SF_NOSKID",SF_NOSKID},
{"SF_NOSPEEDADJUST",SF_NOSPEEDADJUST}, {"SF_NOSPEEDADJUST",SF_NOSPEEDADJUST},
@ -7406,7 +7401,9 @@ struct {
{"SF_STOMPDAMAGE",SF_STOMPDAMAGE}, {"SF_STOMPDAMAGE",SF_STOMPDAMAGE},
{"SF_MARIODAMAGE",SF_MARIODAMAGE}, {"SF_MARIODAMAGE",SF_MARIODAMAGE},
{"SF_MACHINE",SF_MACHINE}, {"SF_MACHINE",SF_MACHINE},
{"SF_NOSPINDASHDUST",SF_NOSPINDASHDUST}, {"SF_DASHMODE",SF_DASHMODE},
{"SF_FASTEDGE",SF_FASTEDGE},
{"SF_MULTIABILITY",SF_MULTIABILITY},
// Character abilities! // Character abilities!
// Primary // Primary
@ -7424,12 +7421,12 @@ struct {
{"CA_JUMPBOOST",CA_JUMPBOOST}, {"CA_JUMPBOOST",CA_JUMPBOOST},
{"CA_AIRDRILL",CA_AIRDRILL}, {"CA_AIRDRILL",CA_AIRDRILL},
{"CA_JUMPTHOK",CA_JUMPTHOK}, {"CA_JUMPTHOK",CA_JUMPTHOK},
{"CA_DASHMODE",CA_DASHMODE}, {"CA_BOUNCE",CA_BOUNCE},
{"CA_TWINSPIN",CA_TWINSPIN}, {"CA_TWINSPIN",CA_TWINSPIN},
// Secondary // Secondary
{"CA2_NONE",CA2_NONE}, // now slot 0! {"CA2_NONE",CA2_NONE}, // now slot 0!
{"CA2_SPINDASH",CA2_SPINDASH}, {"CA2_SPINDASH",CA2_SPINDASH},
{"CA2_MULTIABILITY",CA2_MULTIABILITY}, {"CA2_GUNSLINGER",CA2_GUNSLINGER},
{"CA2_MELEE",CA2_MELEE}, {"CA2_MELEE",CA2_MELEE},
// Sound flags // Sound flags
@ -7498,7 +7495,7 @@ struct {
{"PA_EDGE",PA_EDGE}, {"PA_EDGE",PA_EDGE},
{"PA_WALK",PA_WALK}, {"PA_WALK",PA_WALK},
{"PA_RUN",PA_RUN}, {"PA_RUN",PA_RUN},
{"PA_PEEL",PA_PEEL}, {"PA_DASH",PA_DASH},
{"PA_PAIN",PA_PAIN}, {"PA_PAIN",PA_PAIN},
{"PA_ROLL",PA_ROLL}, {"PA_ROLL",PA_ROLL},
{"PA_JUMP",PA_JUMP}, {"PA_JUMP",PA_JUMP},

View file

@ -222,7 +222,7 @@ extern FILE *logstream;
// NOTE: it needs more than this to increase the number of players... // NOTE: it needs more than this to increase the number of players...
#define MAXPLAYERS 32 #define MAXPLAYERS 32
#define MAXSKINS MAXPLAYERS #define MAXSKINS 32
#define PLAYERSMASK (MAXPLAYERS-1) #define PLAYERSMASK (MAXPLAYERS-1)
#define MAXPLAYERNAME 21 #define MAXPLAYERNAME 21
@ -543,4 +543,7 @@ extern const char *compdate, *comptime, *comprevision, *compbranch;
/// Experimental attempts at preventing MF_PAPERCOLLISION objects from getting stuck in walls. /// Experimental attempts at preventing MF_PAPERCOLLISION objects from getting stuck in walls.
//#define PAPER_COLLISIONCORRECTION //#define PAPER_COLLISIONCORRECTION
/// Hudname padding.
#define SKINNAMEPADDING
#endif // __DOOMDEF__ #endif // __DOOMDEF__

View file

@ -1014,9 +1014,8 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics)
if (cv_analog.value || twodlevel if (cv_analog.value || twodlevel
|| (player->mo && (player->mo->flags2 & MF2_TWOD)) || (player->mo && (player->mo->flags2 & MF2_TWOD))
|| (!demoplayback && (player->climbing || (!demoplayback && (player->climbing
|| (player->pflags & PF_NIGHTSMODE) || (player->powers[pw_carry] == CR_NIGHTSMODE)
|| (player->pflags & PF_SLIDING) || (player->pflags & (PF_SLIDING|PF_FORCESTRAFE))))) // Analog
|| (player->pflags & PF_FORCESTRAFE)))) // Analog
forcestrafe = true; forcestrafe = true;
if (forcestrafe) // Analog if (forcestrafe) // Analog
{ {
@ -1119,7 +1118,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics)
cmd->buttons |= BT_USE; cmd->buttons |= BT_USE;
// Camera Controls // Camera Controls
if (cv_debug || cv_analog.value || demoplayback || objectplacing || player->pflags & PF_NIGHTSMODE) if (cv_debug || cv_analog.value || demoplayback || objectplacing || player->powers[pw_carry] == CR_NIGHTSMODE)
{ {
if (PLAYER1INPUTDOWN(gc_camleft)) if (PLAYER1INPUTDOWN(gc_camleft))
cmd->buttons |= BT_CAMLEFT; cmd->buttons |= BT_CAMLEFT;
@ -1305,9 +1304,8 @@ void G_BuildTiccmd2(ticcmd_t *cmd, INT32 realtics)
if (cv_analog2.value || twodlevel if (cv_analog2.value || twodlevel
|| (player->mo && (player->mo->flags2 & MF2_TWOD)) || (player->mo && (player->mo->flags2 & MF2_TWOD))
|| player->climbing || player->climbing
|| (player->pflags & PF_NIGHTSMODE) || (player->powers[pw_carry] == CR_NIGHTSMODE)
|| (player->pflags & PF_SLIDING) || (player->pflags & (PF_SLIDING|PF_FORCESTRAFE))) // Analog
|| (player->pflags & PF_FORCESTRAFE)) // Analog
forcestrafe = true; forcestrafe = true;
if (forcestrafe) // Analog if (forcestrafe) // Analog
{ {
@ -1407,7 +1405,7 @@ void G_BuildTiccmd2(ticcmd_t *cmd, INT32 realtics)
cmd->buttons |= BT_USE; cmd->buttons |= BT_USE;
// Camera Controls // Camera Controls
if (cv_debug || cv_analog2.value || player->pflags & PF_NIGHTSMODE) if (cv_debug || cv_analog2.value || player->powers[pw_carry] == CR_NIGHTSMODE)
{ {
if (PLAYER2INPUTDOWN(gc_camleft)) if (PLAYER2INPUTDOWN(gc_camleft))
cmd->buttons |= BT_CAMLEFT; cmd->buttons |= BT_CAMLEFT;
@ -2071,6 +2069,7 @@ void G_PlayerReborn(INT32 player)
UINT8 mare; UINT8 mare;
UINT8 skincolor; UINT8 skincolor;
INT32 skin; INT32 skin;
UINT32 availabilities;
tic_t jointime; tic_t jointime;
boolean spectator; boolean spectator;
INT16 bot; INT16 bot;
@ -2095,6 +2094,7 @@ void G_PlayerReborn(INT32 player)
skincolor = players[player].skincolor; skincolor = players[player].skincolor;
skin = players[player].skin; skin = players[player].skin;
availabilities = players[player].availabilities;
camerascale = players[player].camerascale; camerascale = players[player].camerascale;
shieldscale = players[player].shieldscale; shieldscale = players[player].shieldscale;
charability = players[player].charability; charability = players[player].charability;
@ -2140,6 +2140,7 @@ void G_PlayerReborn(INT32 player)
// save player config truth reborn // save player config truth reborn
p->skincolor = skincolor; p->skincolor = skincolor;
p->skin = skin; p->skin = skin;
p->availabilities = availabilities;
p->camerascale = camerascale; p->camerascale = camerascale;
p->shieldscale = shieldscale; p->shieldscale = shieldscale;
p->charability = charability; p->charability = charability;
@ -3913,12 +3914,8 @@ void G_WriteGhostTic(mobj_t *ghost)
if (!(demoflags & DF_GHOST)) if (!(demoflags & DF_GHOST))
return; // No ghost data to write. return; // No ghost data to write.
if (ghost->player && ghost->player->pflags & PF_NIGHTSMODE && ghost->tracer) if (ghost->player && ghost->player->powers[pw_carry] == CR_NIGHTSMODE) // We're talking about the NiGHTS thing, not the normal platforming thing!
{
// We're talking about the NiGHTS thing, not the normal platforming thing!
ziptic |= GZT_NIGHTS; ziptic |= GZT_NIGHTS;
ghost = ghost->tracer;
}
ziptic_p = demo_p++; // the ziptic, written at the end of this function ziptic_p = demo_p++; // the ziptic, written at the end of this function
@ -4100,11 +4097,9 @@ void G_ConsGhostTic(void)
demo_p++; demo_p++;
if (ziptic & GZT_SPR2) if (ziptic & GZT_SPR2)
demo_p++; demo_p++;
if(ziptic & GZT_NIGHTS) { if (ziptic & GZT_NIGHTS) {
if (!testmo->player || !(testmo->player->pflags & PF_NIGHTSMODE) || !testmo->tracer) if (!testmo->player || !(testmo->player->powers[pw_carry] == CR_NIGHTSMODE))
nightsfail = true; nightsfail = true;
else
testmo = testmo->tracer;
} }
if (ziptic & GZT_EXTRA) if (ziptic & GZT_EXTRA)

View file

@ -404,7 +404,7 @@ light_t *t_lspr[NUMSPRITES] =
&lspr[NOLIGHT], // SPR_SPLA &lspr[NOLIGHT], // SPR_SPLA
&lspr[NOLIGHT], // SPR_SMOK &lspr[NOLIGHT], // SPR_SMOK
&lspr[NOLIGHT], // SPR_BUBL &lspr[NOLIGHT], // SPR_BUBL
&lspr[SUPERSPARK_L], // SPR_WZAP &lspr[RINGLIGHT_L], // SPR_WZAP
&lspr[SUPERSPARK_L], // SPR_TFOG &lspr[SUPERSPARK_L], // SPR_TFOG
&lspr[NIGHTSLIGHT_L], // SPR_SEED // Sonic CD flower seed &lspr[NIGHTSLIGHT_L], // SPR_SEED // Sonic CD flower seed
&lspr[NOLIGHT], // SPR_PRTL &lspr[NOLIGHT], // SPR_PRTL
@ -412,9 +412,12 @@ light_t *t_lspr[NUMSPRITES] =
// Game Indicators // Game Indicators
&lspr[NOLIGHT], // SPR_SCOR &lspr[NOLIGHT], // SPR_SCOR
&lspr[NOLIGHT], // SPR_DRWN &lspr[NOLIGHT], // SPR_DRWN
&lspr[NOLIGHT], // SPR_LCKN
&lspr[NOLIGHT], // SPR_TTAG &lspr[NOLIGHT], // SPR_TTAG
&lspr[NOLIGHT], // SPR_GFLG &lspr[NOLIGHT], // SPR_GFLG
&lspr[NOLIGHT], // SPR_CORK
// Ring Weapons // Ring Weapons
&lspr[RINGLIGHT_L], // SPR_RRNG &lspr[RINGLIGHT_L], // SPR_RRNG
&lspr[RINGLIGHT_L], // SPR_RNGB &lspr[RINGLIGHT_L], // SPR_RNGB

View file

@ -1226,9 +1226,9 @@ void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, I
} }
else else
{ {
if (players[tab[i].num].powers[pw_super]) if (players[tab[i].num].powers[pw_super] && players[tab[i].num].mo && (players[tab[i].num].mo->state < &states[S_PLAY_SUPER_TRANS] || players[tab[i].num].mo->state > &states[S_PLAY_SUPER_TRANS9]))
{ {
colormap = R_GetTranslationColormap(players[tab[i].num].skin, players[tab[i].num].mo ? players[tab[i].num].mo->color : tab[i].color, GTC_CACHE); colormap = R_GetTranslationColormap(players[tab[i].num].skin, players[tab[i].num].mo->color, GTC_CACHE);
V_DrawSmallMappedPatch (x, y-4, 0, superprefix[players[tab[i].num].skin], colormap); V_DrawSmallMappedPatch (x, y-4, 0, superprefix[players[tab[i].num].skin], colormap);
} }
else else

View file

@ -301,9 +301,12 @@ char sprnames[NUMSPRITES + 1][5] =
// Game Indicators // Game Indicators
"SCOR", // Score logo "SCOR", // Score logo
"DRWN", // Drowning Timer "DRWN", // Drowning Timer
"LCKN", // Target
"TTAG", // Tag Sign "TTAG", // Tag Sign
"GFLG", // Got Flag sign "GFLG", // Got Flag sign
"CORK",
// Ring Weapons // Ring Weapons
"RRNG", // Red Ring "RRNG", // Red Ring
"RNGB", // Bounce Ring "RNGB", // Bounce Ring
@ -390,12 +393,12 @@ char spr2names[NUMPLAYERSPRITES][5] =
"WAIT", "WAIT",
"WALK", "WALK",
"RUN_", "RUN_",
"PEEL", "DASH",
"PAIN", "PAIN",
"STUN",
"DEAD", "DEAD",
"DRWN", "DRWN",
"SPIN", "ROLL",
"DASH",
"GASP", "GASP",
"JUMP", "JUMP",
"SPNG", "SPNG",
@ -403,8 +406,7 @@ char spr2names[NUMPLAYERSPRITES][5] =
"EDGE", "EDGE",
"RIDE", "RIDE",
"SIGN", "SPIN",
"LIFE",
"FLY_", "FLY_",
"SWIM", "SWIM",
@ -414,32 +416,24 @@ char spr2names[NUMPLAYERSPRITES][5] =
"CLNG", "CLNG",
"CLMB", "CLMB",
"FLT_",
"FRUN",
"BNCE",
"BLND",
"FIRE",
"TWIN", "TWIN",
"MLEE", "MLEE",
"MLEL",
"TRNS", "TRNS",
"SSTD",
"SWLK",
"SRUN",
"SPEE",
"SPAN",
"SSTN",
"SDTH",
"SDRN",
"SSPN",
"SGSP",
"SJMP",
"SSPG",
"SFAL",
"SEDG",
"SRID",
"SFLT",
"NTRN",
"NSTD", "NSTD",
"NFLT", "NFLT",
"NPAN", "NSTN",
"NPUL", "NPUL",
"NATK", "NATK",
@ -469,7 +463,10 @@ char spr2names[NUMPLAYERSPRITES][5] =
"DRL9", "DRL9",
"DRLA", "DRLA",
"DRLB", "DRLB",
"DRLC" "DRLC",
"SIGN",
"LIFE"
}; };
enum playersprite free_spr2 = SPR2_FIRSTFREESLOT; enum playersprite free_spr2 = SPR2_FIRSTFREESLOT;
@ -503,19 +500,22 @@ state_t states[NUMSTATES] =
{SPR_PLAY, SPR2_WAIT|FF_ANIMATE, -1, {NULL}, 0, 16, S_NULL}, // S_PLAY_WAIT {SPR_PLAY, SPR2_WAIT|FF_ANIMATE, -1, {NULL}, 0, 16, S_NULL}, // S_PLAY_WAIT
{SPR_PLAY, SPR2_WALK, 4, {NULL}, 0, 0, S_PLAY_WALK}, // S_PLAY_WALK {SPR_PLAY, SPR2_WALK, 4, {NULL}, 0, 0, S_PLAY_WALK}, // S_PLAY_WALK
{SPR_PLAY, SPR2_RUN , 2, {NULL}, 0, 0, S_PLAY_RUN}, // S_PLAY_RUN {SPR_PLAY, SPR2_RUN , 2, {NULL}, 0, 0, S_PLAY_RUN}, // S_PLAY_RUN
{SPR_PLAY, SPR2_PEEL, 2, {NULL}, 0, 0, S_PLAY_PEEL}, // S_PLAY_PEEL {SPR_PLAY, SPR2_DASH, 2, {NULL}, 0, 0, S_PLAY_DASH}, // S_PLAY_DASH
{SPR_PLAY, SPR2_PAIN|FF_ANIMATE, 350, {NULL}, 0, 4, S_PLAY_FALL}, // S_PLAY_PAIN {SPR_PLAY, SPR2_PAIN|FF_ANIMATE, 350, {NULL}, 0, 4, S_PLAY_FALL}, // S_PLAY_PAIN
{SPR_PLAY, SPR2_STUN|FF_ANIMATE, 350, {NULL}, 0, 4, S_PLAY_FALL}, // S_PLAY_STUN
{SPR_PLAY, SPR2_DEAD|FF_ANIMATE, -1, {NULL}, 0, 4, S_NULL}, // S_PLAY_DEAD {SPR_PLAY, SPR2_DEAD|FF_ANIMATE, -1, {NULL}, 0, 4, S_NULL}, // S_PLAY_DEAD
{SPR_PLAY, SPR2_DRWN|FF_ANIMATE, -1, {NULL}, 0, 4, S_NULL}, // S_PLAY_DRWN {SPR_PLAY, SPR2_DRWN|FF_ANIMATE, -1, {NULL}, 0, 4, S_NULL}, // S_PLAY_DRWN
{SPR_PLAY, SPR2_SPIN, 1, {NULL}, 0, 0, S_PLAY_SPIN}, // S_PLAY_SPIN {SPR_PLAY, SPR2_ROLL, 1, {NULL}, 0, 0, S_PLAY_ROLL}, // S_PLAY_ROLL
{SPR_PLAY, SPR2_DASH, 2, {NULL}, 0, 0, S_PLAY_DASH}, // S_PLAY_DASH
{SPR_PLAY, SPR2_GASP|FF_ANIMATE, 14, {NULL}, 0, 4, S_PLAY_WALK}, // S_PLAY_GASP {SPR_PLAY, SPR2_GASP|FF_ANIMATE, 14, {NULL}, 0, 4, S_PLAY_WALK}, // S_PLAY_GASP
{SPR_PLAY, SPR2_JUMP, 1, {NULL}, 0, 0, S_PLAY_JUMP}, // S_PLAY_JUMP {SPR_PLAY, SPR2_JUMP, 1, {NULL}, 0, 0, S_PLAY_JUMP}, // S_PLAY_JUMP
{SPR_PLAY, SPR2_SPNG, 2, {NULL}, 0, 0, S_PLAY_SPRING}, // S_PLAY_SPRING {SPR_PLAY, SPR2_SPNG, 2, {NULL}, 0, 0, S_PLAY_SPRING}, // S_PLAY_SPRING
{SPR_PLAY, SPR2_FALL, 2, {NULL}, 0, 0, S_PLAY_FALL}, // S_PLAY_FALL {SPR_PLAY, SPR2_FALL, 2, {NULL}, 0, 0, S_PLAY_FALL}, // S_PLAY_FALL
{SPR_PLAY, SPR2_EDGE|FF_ANIMATE, -1, {NULL}, 0, 12, S_NULL}, // S_PLAY_EDGE {SPR_PLAY, SPR2_EDGE, 12, {NULL}, 0, 0, S_PLAY_EDGE}, // S_PLAY_EDGE
{SPR_PLAY, SPR2_RIDE, 4, {NULL}, 0, 0, S_PLAY_RIDE}, // S_PLAY_RIDE {SPR_PLAY, SPR2_RIDE, 4, {NULL}, 0, 0, S_PLAY_RIDE}, // S_PLAY_RIDE
// CA2_SPINDASH
{SPR_PLAY, SPR2_SPIN, 2, {NULL}, 0, 0, S_PLAY_SPINDASH}, // S_PLAY_SPINDASH
// CA_FLY/CA_SWIM // CA_FLY/CA_SWIM
{SPR_PLAY, SPR2_FLY , 2, {NULL}, 0, 0, S_PLAY_FLY}, // S_PLAY_FLY {SPR_PLAY, SPR2_FLY , 2, {NULL}, 0, 0, S_PLAY_FLY}, // S_PLAY_FLY
{SPR_PLAY, SPR2_SWIM, 2, {NULL}, 0, 0, S_PLAY_SWIM}, // S_PLAY_SWIM {SPR_PLAY, SPR2_SWIM, 2, {NULL}, 0, 0, S_PLAY_SWIM}, // S_PLAY_SWIM
@ -526,45 +526,40 @@ state_t states[NUMSTATES] =
{SPR_PLAY, SPR2_CLNG|FF_ANIMATE, -1, {NULL}, 0, 4, S_NULL}, // S_PLAY_CLING {SPR_PLAY, SPR2_CLNG|FF_ANIMATE, -1, {NULL}, 0, 4, S_NULL}, // S_PLAY_CLING
{SPR_PLAY, SPR2_CLMB, 5, {NULL}, 0, 0, S_PLAY_CLIMB}, // S_PLAY_CLIMB {SPR_PLAY, SPR2_CLMB, 5, {NULL}, 0, 0, S_PLAY_CLIMB}, // S_PLAY_CLIMB
// CA_FLOAT/CA_SLOWFALL
{SPR_PLAY, SPR2_FLT , 7, {NULL}, 0, 0, S_PLAY_FLOAT}, // S_PLAY_FLOAT
{SPR_PLAY, SPR2_FRUN, 7, {NULL}, 0, 0, S_PLAY_FLOAT_RUN}, // S_PLAY_FLOAT_RUN
// CA_BOUNCE
{SPR_PLAY, SPR2_BNCE|FF_ANIMATE, -1, {NULL}, 0, 0, S_NULL}, // S_PLAY_BOUNCE
{SPR_PLAY, SPR2_BLND|FF_SPR2ENDSTATE, 2, {NULL}, S_PLAY_BOUNCE, 0, S_PLAY_BOUNCE_LANDING}, // S_PLAY_BOUNCE_LANDING
// CA2_GUNSLINGER
{SPR_PLAY, SPR2_FIRE|FF_SPR2ENDSTATE, 2, {NULL}, S_PLAY_FIRE_FINISH, 0, S_PLAY_FIRE}, // S_PLAY_FIRE
{SPR_PLAY, SPR2_FIRE, 15, {NULL}, S_PLAY_STND, 0, S_PLAY_STND}, // S_PLAY_FIRE_FINISH
// CA_TWINSPIN // CA_TWINSPIN
{SPR_PLAY, SPR2_TWIN|FF_SPR2ENDSTATE, 1, {NULL}, S_PLAY_JUMP, 0, S_PLAY_TWINSPIN}, // S_PLAY_TWINSPIN {SPR_PLAY, SPR2_TWIN|FF_SPR2ENDSTATE, 1, {NULL}, S_PLAY_JUMP, 0, S_PLAY_TWINSPIN}, // S_PLAY_TWINSPIN
// CA2_MELEE // CA2_MELEE
{SPR_PLAY, SPR2_MLEE|FF_SPR2ENDSTATE, 1, {NULL}, S_PLAY_MELEE_FINISH, 0, S_PLAY_MELEE}, // S_PLAY_MELEE {SPR_PLAY, SPR2_MLEE|FF_SPR2ENDSTATE, 1, {NULL}, S_PLAY_MELEE_FINISH, 0, S_PLAY_MELEE}, // S_PLAY_MELEE
{SPR_PLAY, SPR2_MLEE, 20, {NULL}, 0, 0, S_PLAY_FALL}, // S_PLAY_MELEE_FINISH {SPR_PLAY, SPR2_MLEE, 70, {NULL}, 0, 0, S_PLAY_FALL}, // S_PLAY_MELEE_FINISH
{SPR_PLAY, SPR2_MLEL, 35, {NULL}, 0, 0, S_PLAY_WALK}, // S_PLAY_MELEE_LANDING
// SF_SUPERANIMS
{SPR_PLAY, SPR2_SSTD|FF_ANIMATE, -1, {NULL}, 0, 7, S_NULL}, // S_PLAY_SUPER_STND
{SPR_PLAY, SPR2_SWLK, 7, {NULL}, 0, 0, S_PLAY_SUPER_WALK}, // S_PLAY_SUPER_WALK
{SPR_PLAY, SPR2_SRUN, 7, {NULL}, 0, 0, S_PLAY_SUPER_RUN}, // S_PLAY_SUPER_RUN
{SPR_PLAY, SPR2_SPEE, 7, {NULL}, 0, 0, S_PLAY_SUPER_PEEL}, // S_PLAY_SUPER_PEEL
{SPR_PLAY, SPR2_SPAN|FF_ANIMATE, 350, {NULL}, 0, 4, S_PLAY_SUPER_FALL}, // S_PLAY_SUPER_PAIN
{SPR_PLAY, SPR2_SSTN|FF_ANIMATE, 350, {NULL}, 0, 4, S_PLAY_SUPER_FALL}, // S_PLAY_SUPER_STUN
{SPR_PLAY, SPR2_SDTH|FF_ANIMATE, -1, {NULL}, 0, 4, S_NULL}, // S_PLAY_SUPER_DEAD
{SPR_PLAY, SPR2_SDRN|FF_ANIMATE, -1, {NULL}, 0, 4, S_NULL}, // S_PLAY_SUPER_DRWN
{SPR_PLAY, SPR2_SSPN, 1, {NULL}, 0, 0, S_PLAY_SUPER_SPIN}, // S_PLAY_SUPER_SPIN
{SPR_PLAY, SPR2_SGSP|FF_ANIMATE, 14, {NULL}, 0, 4, S_PLAY_SUPER_WALK}, // S_PLAY_SUPER_GASP
{SPR_PLAY, SPR2_SJMP, 1, {NULL}, 0, 0, S_PLAY_SUPER_JUMP}, // S_PLAY_SUPER_JUMP
{SPR_PLAY, SPR2_SSPG, 2, {NULL}, 0, 0, S_PLAY_SUPER_SPRING}, // S_PLAY_SUPER_SPRING
{SPR_PLAY, SPR2_SFAL, 2, {NULL}, 0, 0, S_PLAY_SUPER_FALL}, // S_PLAY_SUPER_FALL
{SPR_PLAY, SPR2_SEDG|FF_ANIMATE, -1, {NULL}, 0, 12, S_NULL}, // S_PLAY_SUPER_EDGE
{SPR_PLAY, SPR2_SRID, 4, {NULL}, 0, 0, S_PLAY_SUPER_RIDE}, // S_PLAY_SUPER_RIDE
{SPR_PLAY, SPR2_SFLT, 7, {NULL}, 0, 0, S_PLAY_SUPER_FLOAT}, // S_PLAY_SUPER_FLOAT
// SF_SUPER // SF_SUPER
{SPR_PLAY, SPR2_TRNS, 4, {NULL}, 0, 0, S_PLAY_SUPER_TRANS2}, // S_PLAY_SUPER_TRANS {SPR_PLAY, SPR2_TRNS|FF_SPR2SUPER, 4, {NULL}, 0, 0, S_PLAY_SUPER_TRANS2}, // S_PLAY_SUPER_TRANS
{SPR_PLAY, SPR2_TRNS, 4, {NULL}, 0, 0, S_PLAY_SUPER_TRANS3}, // S_PLAY_SUPER_TRANS2 {SPR_PLAY, SPR2_TRNS|FF_SPR2SUPER, 4, {NULL}, 0, 0, S_PLAY_SUPER_TRANS3}, // S_PLAY_SUPER_TRANS2
{SPR_PLAY, SPR2_TRNS|FF_FULLBRIGHT, 4, {NULL}, 0, 0, S_PLAY_SUPER_TRANS4}, // S_PLAY_SUPER_TRANS3 {SPR_PLAY, SPR2_TRNS|FF_SPR2SUPER|FF_FULLBRIGHT, 4, {NULL}, 0, 0, S_PLAY_SUPER_TRANS4}, // S_PLAY_SUPER_TRANS3
{SPR_PLAY, SPR2_TRNS|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_PLAY_SUPER_TRANS5}, // S_PLAY_SUPER_TRANS4 {SPR_PLAY, SPR2_TRNS|FF_SPR2SUPER|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_PLAY_SUPER_TRANS5}, // S_PLAY_SUPER_TRANS4
{SPR_PLAY, SPR2_TRNS|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_PLAY_SUPER_TRANS6}, // S_PLAY_SUPER_TRANS5 {SPR_PLAY, SPR2_TRNS|FF_SPR2SUPER|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_PLAY_SUPER_TRANS6}, // S_PLAY_SUPER_TRANS5
{SPR_PLAY, SPR2_TRNS|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_PLAY_SUPER_TRANS7}, // S_PLAY_SUPER_TRANS6 {SPR_PLAY, SPR2_TRNS|FF_SPR2SUPER|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_PLAY_SUPER_TRANS7}, // S_PLAY_SUPER_TRANS6
{SPR_PLAY, SPR2_TRNS|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_PLAY_SUPER_TRANS8}, // S_PLAY_SUPER_TRANS7 {SPR_PLAY, SPR2_TRNS|FF_SPR2SUPER|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_PLAY_SUPER_TRANS8}, // S_PLAY_SUPER_TRANS7
{SPR_PLAY, SPR2_TRNS|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_PLAY_SUPER_TRANS9}, // S_PLAY_SUPER_TRANS8 {SPR_PLAY, SPR2_TRNS|FF_SPR2SUPER|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_PLAY_SUPER_TRANS9}, // S_PLAY_SUPER_TRANS8
{SPR_PLAY, SPR2_TRNS|FF_FULLBRIGHT, 16, {NULL}, 0, 0, S_PLAY_WALK}, // S_PLAY_SUPER_TRANS9 {SPR_PLAY, SPR2_TRNS|FF_SPR2SUPER|FF_FULLBRIGHT, 16, {NULL}, 0, 0, S_PLAY_WALK}, // S_PLAY_SUPER_TRANS9
{SPR_NULL, 0, -1, {NULL}, 0, 0, S_OBJPLACE_DUMMY}, //S_OBJPLACE_DUMMY {SPR_NULL, 0, -1, {NULL}, 0, 0, S_OBJPLACE_DUMMY}, //S_OBJPLACE_DUMMY
// 1-Up Box Sprites (uses player sprite) // 1-Up box sprites (uses player sprite)
{SPR_PLAY, SPR2_LIFE, 2, {NULL}, 0, 16, S_PLAY_BOX2}, // S_PLAY_BOX1 {SPR_PLAY, SPR2_LIFE, 2, {NULL}, 0, 16, S_PLAY_BOX2}, // S_PLAY_BOX1
{SPR_NULL, 0, 1, {NULL}, 0, 0, S_PLAY_BOX1}, // S_PLAY_BOX2 {SPR_NULL, 0, 1, {NULL}, 0, 0, S_PLAY_BOX1}, // S_PLAY_BOX2
{SPR_PLAY, SPR2_LIFE, 4, {NULL}, 0, 4, S_PLAY_ICON2}, // S_PLAY_ICON1 {SPR_PLAY, SPR2_LIFE, 4, {NULL}, 0, 4, S_PLAY_ICON2}, // S_PLAY_ICON1
@ -575,50 +570,50 @@ state_t states[NUMSTATES] =
{SPR_PLAY, SPR2_SIGN, 1, {NULL}, 0, 24, S_PLAY_SIGN}, // S_PLAY_SIGN {SPR_PLAY, SPR2_SIGN, 1, {NULL}, 0, 24, S_PLAY_SIGN}, // S_PLAY_SIGN
// NiGHTS Player, transforming // NiGHTS Player, transforming
{SPR_PLAY, SPR2_NTRN, 4, {A_Scream}, 0, 0, S_PLAY_NIGHTS_TRANS2}, // S_PLAY_NIGHTS_TRANS {SPR_PLAY, SPR2_TRNS, 4, {A_Scream}, 0, 0, S_PLAY_NIGHTS_TRANS2}, // S_PLAY_NIGHTS_TRANS
{SPR_PLAY, SPR2_NTRN, 4, {NULL}, 0, 0, S_PLAY_NIGHTS_TRANS3}, // S_PLAY_NIGHTS_TRANS2 {SPR_PLAY, SPR2_TRNS, 4, {NULL}, 0, 0, S_PLAY_NIGHTS_TRANS3}, // S_PLAY_NIGHTS_TRANS2
{SPR_PLAY, SPR2_NTRN|FF_FULLBRIGHT, 4, {NULL}, 0, 0, S_PLAY_NIGHTS_TRANS4}, // S_PLAY_NIGHTS_TRANS3 {SPR_PLAY, SPR2_TRNS|FF_FULLBRIGHT, 4, {NULL}, 0, 0, S_PLAY_NIGHTS_TRANS4}, // S_PLAY_NIGHTS_TRANS3
{SPR_PLAY, SPR2_NTRN, 3, {NULL}, 0, 0, S_PLAY_NIGHTS_TRANS5}, // S_PLAY_NIGHTS_TRANS4 {SPR_PLAY, SPR2_TRNS, 3, {NULL}, 0, 0, S_PLAY_NIGHTS_TRANS5}, // S_PLAY_NIGHTS_TRANS4
{SPR_PLAY, SPR2_NTRN, 3, {NULL}, 0, 0, S_PLAY_NIGHTS_TRANS6}, // S_PLAY_NIGHTS_TRANS5 {SPR_PLAY, SPR2_TRNS, 3, {NULL}, 0, 0, S_PLAY_NIGHTS_TRANS6}, // S_PLAY_NIGHTS_TRANS5
{SPR_PLAY, SPR2_NTRN, 3, {NULL}, 0, 0, S_PLAY_NIGHTS_TRANS7}, // S_PLAY_NIGHTS_TRANS6 {SPR_PLAY, SPR2_TRNS, 3, {NULL}, 0, 0, S_PLAY_NIGHTS_TRANS7}, // S_PLAY_NIGHTS_TRANS6
{SPR_PLAY, SPR2_NTRN, 3, {NULL}, 0, 0, S_PLAY_NIGHTS_TRANS8}, // S_PLAY_NIGHTS_TRANS7 {SPR_PLAY, SPR2_TRNS, 3, {NULL}, 0, 0, S_PLAY_NIGHTS_TRANS8}, // S_PLAY_NIGHTS_TRANS7
{SPR_PLAY, SPR2_NTRN, 3, {NULL}, 0, 0, S_PLAY_NIGHTS_TRANS9}, // S_PLAY_NIGHTS_TRANS8 {SPR_PLAY, SPR2_TRNS, 3, {NULL}, 0, 0, S_PLAY_NIGHTS_TRANS9}, // S_PLAY_NIGHTS_TRANS8
{SPR_PLAY, SPR2_NTRN, 16, {NULL}, 0, 0, S_PLAY_NIGHTS_FLOAT}, // S_PLAY_NIGHTS_TRANS9 {SPR_PLAY, SPR2_TRNS, 16, {NULL}, 0, 0, S_PLAY_NIGHTS_FLOAT}, // S_PLAY_NIGHTS_TRANS9
// NiGHTS Player, Stand, Floating, Pain, Pull and Attack // NiGHTS Player, stand, float, pain, pull and attack
{SPR_PLAY, SPR2_NSTD, 7, {NULL}, 0, 0, S_PLAY_NIGHTS_STAND}, // S_PLAY_NIGHTS_STAND {SPR_PLAY, SPR2_NSTD, 7, {NULL}, 0, 0, S_PLAY_NIGHTS_STAND}, // S_PLAY_NIGHTS_STAND
{SPR_PLAY, SPR2_NFLT, 7, {NULL}, 0, 0, S_PLAY_NIGHTS_FLOAT}, // S_PLAY_NIGHTS_FLOAT {SPR_PLAY, SPR2_NFLT, 7, {NULL}, 0, 0, S_PLAY_NIGHTS_FLOAT}, // S_PLAY_NIGHTS_FLOAT
{SPR_PLAY, SPR2_NPAN, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_PAIN}, // S_PLAY_NIGHTS_PAIN {SPR_PLAY, SPR2_NSTN, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_STUN}, // S_PLAY_NIGHTS_STUN
{SPR_PLAY, SPR2_NPUL, 1, {NULL}, 0, 0, S_PLAY_NIGHTS_PULL}, // S_PLAY_NIGHTS_PULL {SPR_PLAY, SPR2_NPUL, 1, {NULL}, 0, 0, S_PLAY_NIGHTS_PULL}, // S_PLAY_NIGHTS_PULL
{SPR_PLAY, SPR2_NATK, 1, {NULL}, 0, 0, S_PLAY_NIGHTS_ATTACK}, // S_PLAY_NIGHTS_ATTACK {SPR_PLAY, SPR2_NATK, 1, {NULL}, 0, 0, S_PLAY_NIGHTS_ATTACK}, // S_PLAY_NIGHTS_ATTACK
// NiGHTS Player, Flying and Drilling // NiGHTS Player, flying and drilling
{SPR_PLAY, SPR2_NGT0, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_FLY0}, // S_PLAY_NIGHTS_FLY0 {SPR_PLAY, SPR2_NGT0, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_FLY0}, // S_PLAY_NIGHTS_FLY0
{SPR_PLAY, SPR2_DRL0, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_DRILL0}, // S_PLAY_NIGHTS_DRILL0 {SPR_PLAY, SPR2_DRL0, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_DRILL0}, // S_PLAY_NIGHTS_DRILL0
{SPR_PLAY, SPR2_NGT1, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_FLY1}, // S_PLAY_NIGHTS_FLY1 {SPR_PLAY, SPR2_NGT1, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_FLY1}, // S_PLAY_NIGHTS_FLY1
{SPR_PLAY, SPR2_DRL1, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_DRILL1}, // S_PLAY_NIGHTS_DRILL1 {SPR_PLAY, SPR2_DRL1, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_DRILL1}, // S_PLAY_NIGHTS_DRILL1
{SPR_PLAY, SPR2_NGT2, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_FLY2}, // S_PLAY_NIGHTS_FLY2 {SPR_PLAY, SPR2_NGT2, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_FLY2}, // S_PLAY_NIGHTS_FLY2
{SPR_PLAY, SPR2_DRL2, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_DRILL2}, // S_PLAY_NIGHTS_DRILL2 {SPR_PLAY, SPR2_DRL2, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_DRILL2}, // S_PLAY_NIGHTS_DRILL2
{SPR_PLAY, SPR2_NGT3, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_FLY3}, // S_PLAY_NIGHTS_FLY3 {SPR_PLAY, SPR2_NGT3, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_FLY3}, // S_PLAY_NIGHTS_FLY3
{SPR_PLAY, SPR2_DRL3, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_DRILL3}, // S_PLAY_NIGHTS_DRILL3 {SPR_PLAY, SPR2_DRL3, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_DRILL3}, // S_PLAY_NIGHTS_DRILL3
{SPR_PLAY, SPR2_NGT4, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_FLY4}, // S_PLAY_NIGHTS_FLY4 {SPR_PLAY, SPR2_NGT4, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_FLY4}, // S_PLAY_NIGHTS_FLY4
{SPR_PLAY, SPR2_DRL4, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_DRILL4}, // S_PLAY_NIGHTS_DRILL4 {SPR_PLAY, SPR2_DRL4, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_DRILL4}, // S_PLAY_NIGHTS_DRILL4
{SPR_PLAY, SPR2_NGT5, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_FLY5}, // S_PLAY_NIGHTS_FLY5 {SPR_PLAY, SPR2_NGT5, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_FLY5}, // S_PLAY_NIGHTS_FLY5
{SPR_PLAY, SPR2_DRL5, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_DRILL5}, // S_PLAY_NIGHTS_DRILL5 {SPR_PLAY, SPR2_DRL5, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_DRILL5}, // S_PLAY_NIGHTS_DRILL5
{SPR_PLAY, SPR2_NGT6, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_FLY6}, // S_PLAY_NIGHTS_FLY6 {SPR_PLAY, SPR2_NGT6, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_FLY6}, // S_PLAY_NIGHTS_FLY6
{SPR_PLAY, SPR2_DRL6, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_DRILL6}, // S_PLAY_NIGHTS_DRILL6 {SPR_PLAY, SPR2_DRL6, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_DRILL6}, // S_PLAY_NIGHTS_DRILL6
{SPR_PLAY, SPR2_NGT7, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_FLY7}, // S_PLAY_NIGHTS_FLY7 {SPR_PLAY, SPR2_NGT7, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_FLY7}, // S_PLAY_NIGHTS_FLY7
{SPR_PLAY, SPR2_DRL7, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_DRILL7}, // S_PLAY_NIGHTS_DRILL7 {SPR_PLAY, SPR2_DRL7, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_DRILL7}, // S_PLAY_NIGHTS_DRILL7
{SPR_PLAY, SPR2_NGT8, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_FLY8}, // S_PLAY_NIGHTS_FLY8 {SPR_PLAY, SPR2_NGT8, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_FLY8}, // S_PLAY_NIGHTS_FLY8
{SPR_PLAY, SPR2_DRL8, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_DRILL8}, // S_PLAY_NIGHTS_DRILL8 {SPR_PLAY, SPR2_DRL8, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_DRILL8}, // S_PLAY_NIGHTS_DRILL8
{SPR_PLAY, SPR2_NGT9, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_FLY9}, // S_PLAY_NIGHTS_FLY9 {SPR_PLAY, SPR2_NGT9, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_FLY9}, // S_PLAY_NIGHTS_FLY9
{SPR_PLAY, SPR2_DRL9, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_DRILL9}, // S_PLAY_NIGHTS_DRILL9 {SPR_PLAY, SPR2_DRL9, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_DRILL9}, // S_PLAY_NIGHTS_DRILL9
{SPR_PLAY, SPR2_NGTA, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_FLYA}, // S_PLAY_NIGHTS_FLYA {SPR_PLAY, SPR2_NGTA, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_FLYA}, // S_PLAY_NIGHTS_FLYA
{SPR_PLAY, SPR2_DRLA, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_DRILLA}, // S_PLAY_NIGHTS_DRILLA {SPR_PLAY, SPR2_DRLA, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_DRILLA}, // S_PLAY_NIGHTS_DRILLA
{SPR_PLAY, SPR2_NGTB, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_FLYB}, // S_PLAY_NIGHTS_FLYB {SPR_PLAY, SPR2_NGTB, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_FLYB}, // S_PLAY_NIGHTS_FLYB
{SPR_PLAY, SPR2_DRLB, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_DRILLB}, // S_PLAY_NIGHTS_DRILLB {SPR_PLAY, SPR2_DRLB, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_DRILLB}, // S_PLAY_NIGHTS_DRILLB
{SPR_PLAY, SPR2_NGTC, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_FLYC}, // S_PLAY_NIGHTS_FLYC {SPR_PLAY, SPR2_NGTC, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_FLYC}, // S_PLAY_NIGHTS_FLYC
{SPR_PLAY, SPR2_DRLC, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_DRILLC}, // S_PLAY_NIGHTS_DRILLC {SPR_PLAY, SPR2_DRLC, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_DRILLC}, // S_PLAY_NIGHTS_DRILLC
// Blue Crawla // Blue Crawla
{SPR_POSS, 0, 5, {A_Look}, 0, 0, S_POSS_STND}, // S_POSS_STND {SPR_POSS, 0, 5, {A_Look}, 0, 0, S_POSS_STND}, // S_POSS_STND
@ -2535,13 +2530,17 @@ state_t states[NUMSTATES] =
{SPR_DRWN, 10, 40, {NULL}, 0, 0, S_NULL}, // S_FOUR2 {SPR_DRWN, 10, 40, {NULL}, 0, 0, S_NULL}, // S_FOUR2
{SPR_DRWN, 11, 40, {NULL}, 0, 0, S_NULL}, // S_FIVE2 {SPR_DRWN, 11, 40, {NULL}, 0, 0, S_NULL}, // S_FIVE2
{SPR_TTAG, FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_NULL}, // S_TTAG1 {SPR_LCKN, FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_NULL}, // S_LOCKON1
{SPR_LCKN, 1|FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_NULL}, // S_LOCKON2
{SPR_TTAG, FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_NULL}, // S_TTAG
// CTF Sign // CTF Sign
{SPR_GFLG, 0, 1, {NULL}, 0, 0, S_GOTFLAG2}, // S_GOTFLAG1 {SPR_GFLG, FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_NULL}, // S_GOTFLAG
{SPR_GFLG, 1, 1, {NULL}, 0, 0, S_NULL}, // S_GOTFLAG2 {SPR_GFLG, 1|FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_NULL}, // S_GOTREDFLAG
{SPR_GFLG, 0, 1, {NULL}, 0, 0, S_GOTFLAG4}, // S_GOTFLAG3 {SPR_GFLG, 2|FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_NULL}, // S_GOTBLUEFLAG
{SPR_GFLG, 2, 1, {NULL}, 0, 0, S_NULL}, // S_GOTFLAG4
{SPR_CORK, 0, -1, {NULL}, 0, 0, S_NULL}, // S_CORK
// Red Rings (thrown) // Red Rings (thrown)
{SPR_RRNG, FF_FULLBRIGHT, 1, {A_ThrownRing}, 0, 0, S_RRNG2}, // S_RRNG1 {SPR_RRNG, FF_FULLBRIGHT, 1, {A_ThrownRing}, 0, 0, S_RRNG2}, // S_RRNG1
@ -3062,7 +3061,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
MT_THOK, // painchance MT_THOK, // painchance
sfx_None, // painsound sfx_None, // painsound
S_NULL, // meleestate S_NULL, // meleestate
S_PLAY_SPIN, // missilestate S_PLAY_ROLL, // missilestate
S_PLAY_DEAD, // deathstate S_PLAY_DEAD, // deathstate
S_PLAY_DRWN, // xdeathstate S_PLAY_DRWN, // xdeathstate
sfx_None, // deathsound sfx_None, // deathsound
@ -4581,7 +4580,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
30*FRACUNIT, // speed 30*FRACUNIT, // speed
11*FRACUNIT, // radius 11*FRACUNIT, // radius
8*FRACUNIT, // height 8*FRACUNIT, // height
0, // display offset 100, // display offset
100, // mass 100, // mass
0, // damage 0, // damage
sfx_None, // activesound sfx_None, // activesound
@ -7127,7 +7126,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_ATTRACT_ICON1, // spawnstate S_ATTRACT_ICON1, // spawnstate
1, // spawnhealth 1, // spawnhealth
S_NULL, // seestate S_NULL, // seestate
sfx_s3k41, // seesound sfx_attrsg, // seesound
8, // reactiontime 8, // reactiontime
sfx_None, // attacksound sfx_None, // attacksound
S_NULL, // painstate S_NULL, // painstate
@ -12032,7 +12031,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
8, // speed 8, // speed
8*FRACUNIT, // radius 8*FRACUNIT, // radius
8*FRACUNIT, // height 8*FRACUNIT, // height
0, // display offset 113, // display offset
16, // mass 16, // mass
0, // damage 0, // damage
sfx_None, // activesound sfx_None, // activesound
@ -12059,7 +12058,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
8, // speed 8, // speed
8*FRACUNIT, // radius 8*FRACUNIT, // radius
16*FRACUNIT, // height 16*FRACUNIT, // height
0, // display offset 112, // display offset
16, // mass 16, // mass
0, // damage 0, // damage
sfx_None, // activesound sfx_None, // activesound
@ -12067,9 +12066,9 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_NULL // raisestate S_NULL // raisestate
}, },
{ // MT_TAG { // MT_LOCKON
-1, // doomednum -1, // doomednum
S_TTAG1, // spawnstate S_LOCKON1, // spawnstate
1000, // spawnhealth 1000, // spawnhealth
S_NULL, // seestate S_NULL, // seestate
sfx_None, // seesound sfx_None, // seesound
@ -12086,7 +12085,34 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
8, // speed 8, // speed
16*FRACUNIT, // radius 16*FRACUNIT, // radius
32*FRACUNIT, // height 32*FRACUNIT, // height
0, // display offset 111, // display offset
16, // mass
0, // damage
sfx_None, // activesound
MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY|MF_SCENERY, // flags
S_NULL // raisestate
},
{ // MT_TAG
-1, // doomednum
S_TTAG, // spawnstate
1000, // spawnhealth
S_NULL, // seestate
sfx_None, // seesound
8, // reactiontime
sfx_None, // attacksound
S_NULL, // painstate
0, // painchance
sfx_None, // painsound
S_NULL, // meleestate
S_NULL, // missilestate
S_NULL, // deathstate
S_NULL, // xdeathstate
sfx_None, // deathsound
8, // speed
16*FRACUNIT, // radius
32*FRACUNIT, // height
111, // display offset
16, // mass 16, // mass
0, // damage 0, // damage
sfx_None, // activesound sfx_None, // activesound
@ -12096,7 +12122,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
{ // MT_GOTFLAG { // MT_GOTFLAG
-1, // doomednum -1, // doomednum
S_GOTFLAG1, // spawnstate S_GOTFLAG, // spawnstate
1000, // spawnhealth 1000, // spawnhealth
S_NULL, // seestate S_NULL, // seestate
sfx_None, // seesound sfx_None, // seesound
@ -12113,34 +12139,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
8, // speed 8, // speed
64*FRACUNIT, // radius 64*FRACUNIT, // radius
32*FRACUNIT, // height 32*FRACUNIT, // height
0, // display offset 111, // display offset
16, // mass
0, // damage
sfx_None, // activesound
MF_NOBLOCKMAP|MF_NOCLIP|MF_NOGRAVITY|MF_SCENERY, // flags
S_NULL // raisestate
},
{ // MT_GOTFLAG2
-1, // doomednum
S_GOTFLAG3, // spawnstate
1000, // spawnhealth
S_NULL, // seestate
sfx_None, // seesound
8, // reactiontime
sfx_None, // attacksound
S_NULL, // painstate
0, // painchance
sfx_None, // painsound
S_NULL, // meleestate
S_NULL, // missilestate
S_NULL, // deathstate
S_NULL, // xdeathstate
sfx_None, // deathsound
8, // speed
64*FRACUNIT, // radius
32*FRACUNIT, // height
0, // display offset
16, // mass 16, // mass
0, // damage 0, // damage
sfx_None, // activesound sfx_None, // activesound
@ -12426,6 +12425,33 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_NULL // raisestate S_NULL // raisestate
}, },
{ // MT_CORK
-1, // doomednum
S_CORK, // spawnstate
1000, // spawnhealth
S_NULL, // seestate
sfx_corkp, // seesound
0, // reactiontime
sfx_None, // attacksound
S_NULL, // painstate
0, // painchance
sfx_None, // painsound
S_NULL, // meleestate
S_NULL, // missilestate
S_SMOKE1, // deathstate
S_NULL, // xdeathstate
sfx_corkh, // deathsound
60*FRACUNIT, // speed
16*FRACUNIT, // radius
16*FRACUNIT, // height
0, // display offset
100, // mass
1, // damage
sfx_None, // activesound
MF_NOBLOCKMAP|MF_MISSILE|MF_NOGRAVITY, // flags
S_NULL // raisestate
},
{ // MT_REDRING { // MT_REDRING
-1, // doomednum -1, // doomednum
S_RRNG1, // spawnstate S_RRNG1, // spawnstate

View file

@ -450,7 +450,7 @@ typedef enum sprite
SPR_ARMB, // Armageddon Shield Ring, Back SPR_ARMB, // Armageddon Shield Ring, Back
SPR_WIND, // Whirlwind Shield Orb SPR_WIND, // Whirlwind Shield Orb
SPR_MAGN, // Attract Shield Orb SPR_MAGN, // Attract Shield Orb
SPR_ELEM, // Elemental Shield Orb and Fire SPR_ELEM, // Elemental Shield Orb
SPR_FORC, // Force Shield Orb SPR_FORC, // Force Shield Orb
SPR_PITY, // Pity Shield Orb SPR_PITY, // Pity Shield Orb
SPR_FIRS, // Flame Shield Orb SPR_FIRS, // Flame Shield Orb
@ -507,9 +507,12 @@ typedef enum sprite
// Game Indicators // Game Indicators
SPR_SCOR, // Score logo SPR_SCOR, // Score logo
SPR_DRWN, // Drowning Timer SPR_DRWN, // Drowning Timer
SPR_LCKN, // Target
SPR_TTAG, // Tag Sign SPR_TTAG, // Tag Sign
SPR_GFLG, // Got Flag sign SPR_GFLG, // Got Flag sign
SPR_CORK,
// Ring Weapons // Ring Weapons
SPR_RRNG, // Red Ring SPR_RRNG, // Red Ring
SPR_RNGB, // Bounce Ring SPR_RNGB, // Bounce Ring
@ -594,21 +597,21 @@ typedef enum sprite
NUMSPRITES NUMSPRITES
} spritenum_t; } spritenum_t;
// Make sure to be conscious of FF_FRAMEMASK whenever you change this table. // Make sure to be conscious of FF_FRAMEMASK and the fact sprite2 is stored as a UINT8 whenever you change this table.
// Currently, FF_FRAMEMASK is 0x1ff, or 511 - and NUMSPRITEFREESLOTS is 256. // Currently, FF_FRAMEMASK is 0xff, or 255 - but the second half is used by FF_SPR2SUPER, so the limitation is 0x7f.
// Since this is zero-based, there can be at most 256 different SPR2_'s without changing that. // Since this is zero-based, there can be at most 128 different SPR2_'s without changing that.
enum playersprite enum playersprite
{ {
SPR2_STND = 0, SPR2_STND = 0,
SPR2_WAIT, SPR2_WAIT,
SPR2_WALK, SPR2_WALK,
SPR2_RUN , SPR2_RUN ,
SPR2_PEEL, SPR2_DASH,
SPR2_PAIN, SPR2_PAIN,
SPR2_STUN,
SPR2_DEAD, SPR2_DEAD,
SPR2_DRWN, // drown SPR2_DRWN, // drown
SPR2_SPIN, SPR2_ROLL,
SPR2_DASH, // spindash charge
SPR2_GASP, SPR2_GASP,
SPR2_JUMP, SPR2_JUMP,
SPR2_SPNG, // spring SPR2_SPNG, // spring
@ -616,8 +619,7 @@ enum playersprite
SPR2_EDGE, SPR2_EDGE,
SPR2_RIDE, SPR2_RIDE,
SPR2_SIGN, // end sign head SPR2_SPIN, // spindash
SPR2_LIFE, // life monitor icon
SPR2_FLY , SPR2_FLY ,
SPR2_SWIM, SPR2_SWIM,
@ -627,36 +629,28 @@ enum playersprite
SPR2_CLNG, // cling SPR2_CLNG, // cling
SPR2_CLMB, // climb SPR2_CLMB, // climb
SPR2_FLT , // float
SPR2_FRUN, // float run
SPR2_BNCE, // bounce
SPR2_BLND, // bounce landing
SPR2_FIRE, // fire
SPR2_TWIN, // twinspin SPR2_TWIN, // twinspin
SPR2_MLEE, // melee SPR2_MLEE, // melee
SPR2_MLEL, // melee land
SPR2_TRNS, // super transformation SPR2_TRNS, // transformation
SPR2_SSTD, // super stand
SPR2_SWLK, // super walk
SPR2_SRUN, // super run
SPR2_SPEE, // super peelout
SPR2_SPAN, // super pain
SPR2_SSTN, // super stun
SPR2_SDTH, // super death
SPR2_SDRN, // super drown
SPR2_SSPN, // super spin
SPR2_SGSP, // super gasp
SPR2_SJMP, // super jump
SPR2_SSPG, // super spring
SPR2_SFAL, // super fall
SPR2_SEDG, // super edge
SPR2_SRID, // super ride
SPR2_SFLT, // super float
SPR2_NTRN, // NiGHTS transformation
SPR2_NSTD, // NiGHTS stand SPR2_NSTD, // NiGHTS stand
SPR2_NFLT, // NiGHTS float SPR2_NFLT, // NiGHTS float
SPR2_NPAN, // NiGHTS pain SPR2_NSTN, // NiGHTS stun
SPR2_NPUL, // NiGHTS pull SPR2_NPUL, // NiGHTS pull
SPR2_NATK, // NiGHTS attack SPR2_NATK, // NiGHTS attack
// NiGHTS flight. // NiGHTS flight
SPR2_NGT0, SPR2_NGT0,
SPR2_NGT1, SPR2_NGT1,
SPR2_NGT2, SPR2_NGT2,
@ -671,7 +665,7 @@ enum playersprite
SPR2_NGTB, SPR2_NGTB,
SPR2_NGTC, SPR2_NGTC,
// NiGHTS drill. // NiGHTS drill
SPR2_DRL0, SPR2_DRL0,
SPR2_DRL1, SPR2_DRL1,
SPR2_DRL2, SPR2_DRL2,
@ -686,8 +680,11 @@ enum playersprite
SPR2_DRLB, SPR2_DRLB,
SPR2_DRLC, SPR2_DRLC,
SPR2_SIGN, // end sign head
SPR2_LIFE, // life monitor icon
SPR2_FIRSTFREESLOT, SPR2_FIRSTFREESLOT,
SPR2_LASTFREESLOT = SPR2_FIRSTFREESLOT + NUMSPRITEFREESLOTS - 1, SPR2_LASTFREESLOT = 0x7f,
NUMPLAYERSPRITES NUMPLAYERSPRITES
}; };
@ -713,19 +710,22 @@ typedef enum state
S_PLAY_WAIT, S_PLAY_WAIT,
S_PLAY_WALK, S_PLAY_WALK,
S_PLAY_RUN, S_PLAY_RUN,
S_PLAY_PEEL, S_PLAY_DASH,
S_PLAY_PAIN, S_PLAY_PAIN,
S_PLAY_STUN,
S_PLAY_DEAD, S_PLAY_DEAD,
S_PLAY_DRWN, S_PLAY_DRWN,
S_PLAY_SPIN, S_PLAY_ROLL,
S_PLAY_DASH,
S_PLAY_GASP, S_PLAY_GASP,
S_PLAY_JUMP, // spin jump S_PLAY_JUMP,
S_PLAY_SPRING, S_PLAY_SPRING,
S_PLAY_FALL, S_PLAY_FALL,
S_PLAY_EDGE, S_PLAY_EDGE,
S_PLAY_RIDE, S_PLAY_RIDE,
// CA2_SPINDASH
S_PLAY_SPINDASH,
// CA_FLY/SWIM // CA_FLY/SWIM
S_PLAY_FLY, S_PLAY_FLY,
S_PLAY_SWIM, S_PLAY_SWIM,
@ -736,30 +736,25 @@ typedef enum state
S_PLAY_CLING, S_PLAY_CLING,
S_PLAY_CLIMB, S_PLAY_CLIMB,
// CA_FLOAT/CA_SLOWFALL
S_PLAY_FLOAT,
S_PLAY_FLOAT_RUN,
// CA_BOUNCE
S_PLAY_BOUNCE,
S_PLAY_BOUNCE_LANDING,
// CA2_GUNSLINGER
S_PLAY_FIRE,
S_PLAY_FIRE_FINISH,
// CA_TWINSPIN // CA_TWINSPIN
S_PLAY_TWINSPIN, S_PLAY_TWINSPIN,
// CA2_MELEE // CA2_MELEE
S_PLAY_MELEE, S_PLAY_MELEE,
S_PLAY_MELEE_FINISH, S_PLAY_MELEE_FINISH,
S_PLAY_MELEE_LANDING,
// SF_SUPERANIMS
S_PLAY_SUPER_STND,
S_PLAY_SUPER_WALK,
S_PLAY_SUPER_RUN,
S_PLAY_SUPER_PEEL,
S_PLAY_SUPER_PAIN,
S_PLAY_SUPER_STUN,
S_PLAY_SUPER_DEAD,
S_PLAY_SUPER_DRWN,
S_PLAY_SUPER_SPIN,
S_PLAY_SUPER_GASP,
S_PLAY_SUPER_JUMP, // see note above
S_PLAY_SUPER_SPRING,
S_PLAY_SUPER_FALL,
S_PLAY_SUPER_EDGE,
S_PLAY_SUPER_RIDE,
S_PLAY_SUPER_FLOAT,
// SF_SUPER // SF_SUPER
S_PLAY_SUPER_TRANS, S_PLAY_SUPER_TRANS,
@ -798,7 +793,7 @@ typedef enum state
S_PLAY_NIGHTS_STAND, S_PLAY_NIGHTS_STAND,
S_PLAY_NIGHTS_FLOAT, S_PLAY_NIGHTS_FLOAT,
S_PLAY_NIGHTS_PAIN, S_PLAY_NIGHTS_STUN,
S_PLAY_NIGHTS_PULL, S_PLAY_NIGHTS_PULL,
S_PLAY_NIGHTS_ATTACK, S_PLAY_NIGHTS_ATTACK,
@ -2725,14 +2720,18 @@ typedef enum state
S_FOUR2, S_FOUR2,
S_FIVE2, S_FIVE2,
S_LOCKON1,
S_LOCKON2,
// Tag Sign // Tag Sign
S_TTAG1, S_TTAG,
// Got Flag Sign // Got Flag Sign
S_GOTFLAG1, S_GOTFLAG,
S_GOTFLAG2, S_GOTREDFLAG,
S_GOTFLAG3, S_GOTBLUEFLAG,
S_GOTFLAG4,
S_CORK,
// Red Ring // Red Ring
S_RRNG1, S_RRNG1,
@ -3542,9 +3541,9 @@ typedef enum mobj_type
MT_SCORE, // score logo MT_SCORE, // score logo
MT_DROWNNUMBERS, // Drowning Timer MT_DROWNNUMBERS, // Drowning Timer
MT_GOTEMERALD, // Chaos Emerald (intangible) MT_GOTEMERALD, // Chaos Emerald (intangible)
MT_LOCKON, // Target
MT_TAG, // Tag Sign MT_TAG, // Tag Sign
MT_GOTFLAG, // Got Flag sign MT_GOTFLAG, // Got Flag sign
MT_GOTFLAG2, // Got Flag sign
// Ambient Sounds // Ambient Sounds
MT_AWATERA, // Ambient Water Sound 1 MT_AWATERA, // Ambient Water Sound 1
@ -3558,6 +3557,8 @@ typedef enum mobj_type
MT_RANDOMAMBIENT, MT_RANDOMAMBIENT,
MT_RANDOMAMBIENT2, MT_RANDOMAMBIENT2,
MT_CORK,
// Ring Weapons // Ring Weapons
MT_REDRING, MT_REDRING,
MT_BOUNCERING, MT_BOUNCERING,

View file

@ -445,10 +445,32 @@ static int lib_pIsValidSprite2(lua_State *L)
INLEVEL INLEVEL
if (!mobj) if (!mobj)
return LUA_ErrInvalid(L, "mobj_t"); return LUA_ErrInvalid(L, "mobj_t");
lua_pushboolean(L, (mobj->skin && (((skin_t *)mobj->skin)->sprites[spr2].numframes > 0))); lua_pushboolean(L, (mobj->skin && (((skin_t *)mobj->skin)->sprites[spr2].numframes)));
return 1; return 1;
} }
// P_SpawnLockOn doesn't exist either, but we want to expose making a local mobj without encouraging hacks.
static int lib_pSpawnLockOn(lua_State *L)
{
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
mobj_t *lockon = *((mobj_t **)luaL_checkudata(L, 2, META_MOBJ));
statenum_t state = luaL_checkinteger(L, 3);
NOHUD
INLEVEL
if (!lockon)
return LUA_ErrInvalid(L, "mobj_t");
if (!player)
return LUA_ErrInvalid(L, "player_t");
if (player == &players[consoleplayer] || player == &players[secondarydisplayplayer] || player == &players[displayplayer]) // Only display it on your own view.
{
mobj_t *visual = P_SpawnMobj(lockon->x, lockon->y, lockon->z, MT_LOCKON); // positioning, flip handled in P_SceneryThinker
visual->target = lockon;
P_SetMobjStateNF(visual, state);
}
return 0;
}
static int lib_pSpawnMissile(lua_State *L) static int lib_pSpawnMissile(lua_State *L)
{ {
mobj_t *source = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); mobj_t *source = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
@ -793,6 +815,17 @@ static int lib_pStealPlayerScore(lua_State *L)
return 0; return 0;
} }
static int lib_pGetJumpFlags(lua_State *L)
{
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
NOHUD
INLEVEL
if (!player)
return LUA_ErrInvalid(L, "player_t");
lua_pushinteger(L, P_GetJumpFlags(player));
return 1;
}
static int lib_pPlayerInPain(lua_State *L) static int lib_pPlayerInPain(lua_State *L)
{ {
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
@ -1055,11 +1088,12 @@ static int lib_pLookForEnemies(lua_State *L)
{ {
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
boolean nonenemies = lua_opttrueboolean(L, 2); boolean nonenemies = lua_opttrueboolean(L, 2);
boolean bullet = lua_optboolean(L, 3);
NOHUD NOHUD
INLEVEL INLEVEL
if (!player) if (!player)
return LUA_ErrInvalid(L, "player_t"); return LUA_ErrInvalid(L, "player_t");
lua_pushboolean(L, P_LookForEnemies(player, nonenemies)); LUA_PushUserdata(L, P_LookForEnemies(player, nonenemies, bullet), META_MOBJ);
return 1; return 1;
} }
@ -2327,6 +2361,7 @@ static luaL_Reg lib[] = {
{"P_SpawnMobj",lib_pSpawnMobj}, {"P_SpawnMobj",lib_pSpawnMobj},
{"P_RemoveMobj",lib_pRemoveMobj}, {"P_RemoveMobj",lib_pRemoveMobj},
{"P_IsValidSprite2", lib_pIsValidSprite2}, {"P_IsValidSprite2", lib_pIsValidSprite2},
{"P_SpawnLockOn", lib_pSpawnLockOn},
{"P_SpawnMissile",lib_pSpawnMissile}, {"P_SpawnMissile",lib_pSpawnMissile},
{"P_SpawnXYZMissile",lib_pSpawnXYZMissile}, {"P_SpawnXYZMissile",lib_pSpawnXYZMissile},
{"P_SpawnPointMissile",lib_pSpawnPointMissile}, {"P_SpawnPointMissile",lib_pSpawnPointMissile},
@ -2354,6 +2389,7 @@ static luaL_Reg lib[] = {
{"P_GetPlayerControlDirection",lib_pGetPlayerControlDirection}, {"P_GetPlayerControlDirection",lib_pGetPlayerControlDirection},
{"P_AddPlayerScore",lib_pAddPlayerScore}, {"P_AddPlayerScore",lib_pAddPlayerScore},
{"P_StealPlayerScore",lib_pStealPlayerScore}, {"P_StealPlayerScore",lib_pStealPlayerScore},
{"P_GetJumpFlags",lib_pGetJumpFlags},
{"P_PlayerInPain",lib_pPlayerInPain}, {"P_PlayerInPain",lib_pPlayerInPain},
{"P_DoPlayerPain",lib_pDoPlayerPain}, {"P_DoPlayerPain",lib_pDoPlayerPain},
{"P_ResetPlayer",lib_pResetPlayer}, {"P_ResetPlayer",lib_pResetPlayer},

View file

@ -511,7 +511,8 @@ static int mobj_set(lua_State *L)
for (i = 0; i < numskins; i++) for (i = 0; i < numskins; i++)
if (fastcmp(skins[i].name, skin)) if (fastcmp(skins[i].name, skin))
{ {
mo->skin = &skins[i]; if (!mo->player || R_SkinUsable(mo->player-players, i))
mo->skin = &skins[i];
return 0; return 0;
} }
return luaL_error(L, "mobj.skin '%s' not found!", skin); return luaL_error(L, "mobj.skin '%s' not found!", skin);

View file

@ -194,8 +194,6 @@ static int player_get(lua_State *L)
lua_pushinteger(L, plr->gotcontinue); lua_pushinteger(L, plr->gotcontinue);
else if (fastcmp(field,"speed")) else if (fastcmp(field,"speed"))
lua_pushfixed(L, plr->speed); lua_pushfixed(L, plr->speed);
else if (fastcmp(field,"jumping"))
lua_pushboolean(L, plr->jumping);
else if (fastcmp(field,"secondjump")) else if (fastcmp(field,"secondjump"))
lua_pushinteger(L, plr->secondjump); lua_pushinteger(L, plr->secondjump);
else if (fastcmp(field,"fly1")) else if (fastcmp(field,"fly1"))
@ -459,8 +457,6 @@ static int player_set(lua_State *L)
plr->gotcontinue = (UINT8)luaL_checkinteger(L, 3); plr->gotcontinue = (UINT8)luaL_checkinteger(L, 3);
else if (fastcmp(field,"speed")) else if (fastcmp(field,"speed"))
plr->speed = luaL_checkfixed(L, 3); plr->speed = luaL_checkfixed(L, 3);
else if (fastcmp(field,"jumping"))
plr->jumping = luaL_checkboolean(L, 3);
else if (fastcmp(field,"secondjump")) else if (fastcmp(field,"secondjump"))
plr->secondjump = (UINT8)luaL_checkinteger(L, 3); plr->secondjump = (UINT8)luaL_checkinteger(L, 3);
else if (fastcmp(field,"fly1")) else if (fastcmp(field,"fly1"))

View file

@ -942,7 +942,7 @@ boolean OP_FreezeObjectplace(void)
if (!objectplacing) if (!objectplacing)
return false; return false;
if ((maptol & TOL_NIGHTS) && (players[consoleplayer].pflags & PF_NIGHTSMODE)) if ((maptol & TOL_NIGHTS) && (players[consoleplayer].powers[pw_carry] == CR_NIGHTSMODE))
return false; return false;
return true; return true;
@ -1255,7 +1255,7 @@ void Command_ObjectPlace_f(void)
{ {
objectplacing = true; objectplacing = true;
if ((players[0].pflags & PF_NIGHTSMODE)) if ((players[0].powers[pw_carry] == CR_NIGHTSMODE))
return; return;
if (!COM_CheckParm("-silent")) if (!COM_CheckParm("-silent"))
@ -1326,7 +1326,7 @@ void Command_ObjectPlace_f(void)
// Don't touch the NiGHTS Objectplace stuff. // Don't touch the NiGHTS Objectplace stuff.
// ... or if the mo mysteriously vanished. // ... or if the mo mysteriously vanished.
if (!players[0].mo || (players[0].pflags & PF_NIGHTSMODE)) if (!players[0].mo || (players[0].powers[pw_carry] == CR_NIGHTSMODE))
return; return;
// If still in dummy state, get out of it. // If still in dummy state, get out of it.

View file

@ -109,41 +109,45 @@ typedef enum
const char *quitmsg[NUM_QUITMESSAGES]; const char *quitmsg[NUM_QUITMESSAGES];
// Stuff for customizing the player select screen Tails 09-22-2003 // Stuff for customizing the player select screen Tails 09-22-2003
// A rare case.
// External files modify this menu, so we can't call it static.
// And I'm too lazy to go through and rename it everywhere. ARRGH!
description_t description[32] = description_t description[32] =
{ {
{"???", "", "", 0, 0, 0}, {false, "???", "", "", 0, 0},
{"???", "", "", 0, 0, 0}, {false, "???", "", "", 0, 0},
{"???", "", "", 0, 0, 0}, {false, "???", "", "", 0, 0},
{"???", "", "", 0, 0, 0}, {false, "???", "", "", 0, 0},
{"???", "", "", 0, 0, 0}, {false, "???", "", "", 0, 0},
{"???", "", "", 0, 0, 0}, {false, "???", "", "", 0, 0},
{"???", "", "", 0, 0, 0}, {false, "???", "", "", 0, 0},
{"???", "", "", 0, 0, 0}, {false, "???", "", "", 0, 0},
{"???", "", "", 0, 0, 0}, {false, "???", "", "", 0, 0},
{"???", "", "", 0, 0, 0}, {false, "???", "", "", 0, 0},
{"???", "", "", 0, 0, 0}, {false, "???", "", "", 0, 0},
{"???", "", "", 0, 0, 0}, {false, "???", "", "", 0, 0},
{"???", "", "", 0, 0, 0}, {false, "???", "", "", 0, 0},
{"???", "", "", 0, 0, 0}, {false, "???", "", "", 0, 0},
{"???", "", "", 0, 0, 0}, {false, "???", "", "", 0, 0},
{"???", "", "", 0, 0, 0}, {false, "???", "", "", 0, 0},
{"???", "", "", 0, 0, 0}, {false, "???", "", "", 0, 0},
{"???", "", "", 0, 0, 0}, {false, "???", "", "", 0, 0},
{"???", "", "", 0, 0, 0}, {false, "???", "", "", 0, 0},
{"???", "", "", 0, 0, 0}, {false, "???", "", "", 0, 0},
{"???", "", "", 0, 0, 0}, {false, "???", "", "", 0, 0},
{"???", "", "", 0, 0, 0}, {false, "???", "", "", 0, 0},
{"???", "", "", 0, 0, 0}, {false, "???", "", "", 0, 0},
{"???", "", "", 0, 0, 0}, {false, "???", "", "", 0, 0},
{"???", "", "", 0, 0, 0}, {false, "???", "", "", 0, 0},
{"???", "", "", 0, 0, 0}, {false, "???", "", "", 0, 0},
{"???", "", "", 0, 0, 0}, {false, "???", "", "", 0, 0},
{"???", "", "", 0, 0, 0}, {false, "???", "", "", 0, 0},
{"???", "", "", 0, 0, 0}, {false, "???", "", "", 0, 0},
{"???", "", "", 0, 0, 0}, {false, "???", "", "", 0, 0},
{"???", "", "", 0, 0, 0}, {false, "???", "", "", 0, 0},
{"???", "", "", 0, 0, 0} {false, "???", "", "", 0, 0}
}; };
static INT16 char_on = 0;
static char *char_notes = NULL; static char *char_notes = NULL;
static fixed_t char_scroll = 0; static fixed_t char_scroll = 0;
@ -171,7 +175,6 @@ static saveinfo_t savegameinfo[MAXSAVEGAMES]; // Extra info about the save games
INT16 startmap; // Mario, NiGHTS, or just a plain old normal game? INT16 startmap; // Mario, NiGHTS, or just a plain old normal game?
static INT16 itemOn = 1; // menu item skull is on, Hack by Tails 09-18-2002 static INT16 itemOn = 1; // menu item skull is on, Hack by Tails 09-18-2002
static boolean lastdirection = true; // toaster - Only You Can Prevent Hacks - true is for forward, false is for backwards
static INT16 skullAnimCounter = 10; // skull animation counter static INT16 skullAnimCounter = 10; // skull animation counter
static boolean setupcontrols_secondaryplayer; static boolean setupcontrols_secondaryplayer;
@ -272,6 +275,7 @@ static void M_ChooseNightsAttack(INT32 choice);
static void M_ModeAttackRetry(INT32 choice); static void M_ModeAttackRetry(INT32 choice);
static void M_ModeAttackEndGame(INT32 choice); static void M_ModeAttackEndGame(INT32 choice);
static void M_SetGuestReplay(INT32 choice); static void M_SetGuestReplay(INT32 choice);
static void M_HandleChoosePlayerMenu(INT32 choice);
static void M_ChoosePlayer(INT32 choice); static void M_ChoosePlayer(INT32 choice);
menu_t SP_GameStatsDef, SP_LevelStatsDef; menu_t SP_GameStatsDef, SP_LevelStatsDef;
static menu_t SP_TimeAttackDef, SP_ReplayDef, SP_GuestReplayDef, SP_GhostDef; static menu_t SP_TimeAttackDef, SP_ReplayDef, SP_GuestReplayDef, SP_GhostDef;
@ -764,7 +768,7 @@ static menuitem_t SP_TimeAttackMenu[] =
enum enum
{ {
talevelback, talevel,
taplayer, taplayer,
taguest, taguest,
@ -862,7 +866,7 @@ static menuitem_t SP_NightsAttackMenu[] =
enum enum
{ {
nalevelback, nalevel,
narecords, narecords,
naguest, naguest,
@ -882,43 +886,10 @@ static menuitem_t SP_LevelStatsMenu[] =
{IT_KEYHANDLER | IT_NOTHING, NULL, "", M_HandleLevelStats, 0}, // dummy menuitem for the control func {IT_KEYHANDLER | IT_NOTHING, NULL, "", M_HandleLevelStats, 0}, // dummy menuitem for the control func
}; };
// A rare case. // Player menu dummy
// External files modify this menu, so we can't call it static. static menuitem_t SP_PlayerMenu[] =
// And I'm too lazy to go through and rename it everywhere. ARRGH!
menuitem_t PlayerMenu[32] =
{ {
{IT_DISABLED, NULL, NULL, M_ChoosePlayer, 0}, {IT_NOTHING | IT_KEYHANDLER, NULL, "", M_HandleChoosePlayerMenu, 0}, // dummy menuitem for the control func
{IT_DISABLED, NULL, NULL, M_ChoosePlayer, 0},
{IT_DISABLED, NULL, NULL, M_ChoosePlayer, 0},
{IT_DISABLED, NULL, NULL, M_ChoosePlayer, 0},
{IT_DISABLED, NULL, NULL, M_ChoosePlayer, 0},
{IT_DISABLED, NULL, NULL, M_ChoosePlayer, 0},
{IT_DISABLED, NULL, NULL, M_ChoosePlayer, 0},
{IT_DISABLED, NULL, NULL, M_ChoosePlayer, 0},
{IT_DISABLED, NULL, NULL, M_ChoosePlayer, 0},
{IT_DISABLED, NULL, NULL, M_ChoosePlayer, 0},
{IT_DISABLED, NULL, NULL, M_ChoosePlayer, 0},
{IT_DISABLED, NULL, NULL, M_ChoosePlayer, 0},
{IT_DISABLED, NULL, NULL, M_ChoosePlayer, 0},
{IT_DISABLED, NULL, NULL, M_ChoosePlayer, 0},
{IT_DISABLED, NULL, NULL, M_ChoosePlayer, 0},
{IT_DISABLED, NULL, NULL, M_ChoosePlayer, 0},
{IT_DISABLED, NULL, NULL, M_ChoosePlayer, 0},
{IT_DISABLED, NULL, NULL, M_ChoosePlayer, 0},
{IT_DISABLED, NULL, NULL, M_ChoosePlayer, 0},
{IT_DISABLED, NULL, NULL, M_ChoosePlayer, 0},
{IT_DISABLED, NULL, NULL, M_ChoosePlayer, 0},
{IT_DISABLED, NULL, NULL, M_ChoosePlayer, 0},
{IT_DISABLED, NULL, NULL, M_ChoosePlayer, 0},
{IT_DISABLED, NULL, NULL, M_ChoosePlayer, 0},
{IT_DISABLED, NULL, NULL, M_ChoosePlayer, 0},
{IT_DISABLED, NULL, NULL, M_ChoosePlayer, 0},
{IT_DISABLED, NULL, NULL, M_ChoosePlayer, 0},
{IT_DISABLED, NULL, NULL, M_ChoosePlayer, 0},
{IT_DISABLED, NULL, NULL, M_ChoosePlayer, 0},
{IT_DISABLED, NULL, NULL, M_ChoosePlayer, 0},
{IT_DISABLED, NULL, NULL, M_ChoosePlayer, 0},
{IT_DISABLED, NULL, NULL, M_ChoosePlayer, 0}
}; };
// ----------------------------------- // -----------------------------------
@ -1681,9 +1652,9 @@ static menu_t SP_NightsGhostDef =
menu_t SP_PlayerDef = menu_t SP_PlayerDef =
{ {
"M_PICKP", "M_PICKP",
sizeof (PlayerMenu)/sizeof (menuitem_t),//player_end, sizeof (SP_PlayerMenu)/sizeof (menuitem_t),
&SP_MainDef, &SP_MainDef,
PlayerMenu, SP_PlayerMenu,
M_DrawSetupChoosePlayerMenu, M_DrawSetupChoosePlayerMenu,
24, 32, 24, 32,
0, 0,
@ -2170,8 +2141,6 @@ static boolean M_ChangeStringCvar(INT32 choice)
static void M_NextOpt(void) static void M_NextOpt(void)
{ {
INT16 oldItemOn = itemOn; // prevent infinite loop INT16 oldItemOn = itemOn; // prevent infinite loop
lastdirection = true;
do do
{ {
if (itemOn + 1 > currentMenu->numitems - 1) if (itemOn + 1 > currentMenu->numitems - 1)
@ -2184,8 +2153,6 @@ static void M_NextOpt(void)
static void M_PrevOpt(void) static void M_PrevOpt(void)
{ {
INT16 oldItemOn = itemOn; // prevent infinite loop INT16 oldItemOn = itemOn; // prevent infinite loop
lastdirection = false;
do do
{ {
if (!itemOn) if (!itemOn)
@ -2456,8 +2423,7 @@ boolean M_Responder(event_t *ev)
case KEY_DOWNARROW: case KEY_DOWNARROW:
M_NextOpt(); M_NextOpt();
S_StartSound(NULL, sfx_menu1); S_StartSound(NULL, sfx_menu1);
if (currentMenu == &SP_PlayerDef if (currentMenu == &MISC_ChangeGameTypeDef)
|| currentMenu == &MISC_ChangeGameTypeDef)
{ {
Z_Free(char_notes); Z_Free(char_notes);
char_notes = NULL; char_notes = NULL;
@ -2467,8 +2433,7 @@ boolean M_Responder(event_t *ev)
case KEY_UPARROW: case KEY_UPARROW:
M_PrevOpt(); M_PrevOpt();
S_StartSound(NULL, sfx_menu1); S_StartSound(NULL, sfx_menu1);
if (currentMenu == &SP_PlayerDef if (currentMenu == &MISC_ChangeGameTypeDef)
|| currentMenu == &MISC_ChangeGameTypeDef)
{ {
Z_Free(char_notes); Z_Free(char_notes);
char_notes = NULL; char_notes = NULL;
@ -3537,7 +3502,7 @@ static void M_PatchSkinNameTable(void)
for (j = 0; j < MAXSKINS; j++) for (j = 0; j < MAXSKINS; j++)
{ {
if (skins[j].name[0] != '\0' && R_SkinUnlock(j)) if (skins[j].name[0] != '\0' && R_SkinUsable(-1, j))
{ {
skins_cons_t[j].strvalue = skins[j].realname; skins_cons_t[j].strvalue = skins[j].realname;
skins_cons_t[j].value = j+1; skins_cons_t[j].value = j+1;
@ -5380,19 +5345,19 @@ static void M_SetupChoosePlayer(INT32 choice)
UINT8 i; UINT8 i;
UINT8 firstvalid = 255; UINT8 firstvalid = 255;
UINT8 lastvalid = 0; UINT8 lastvalid = 0;
boolean allowed = false;
char *name; char *name;
(void)choice; (void)choice;
if (PlayerMenu[0].status & (IT_DYBIGSPACE)) // Correcting a hack that may be made below. SP_PlayerMenu[0].status &= ~IT_DYBIGSPACE; // Correcting a hack that may be made below.
PlayerMenu[0].status = (IT_DISABLED|(PlayerMenu[0].status & IT_CENTER));
for (i = 0; i < 32; i++) // Handle charsels, availability, and unlocks. for (i = 0; i < 32; i++) // Handle charsels, availability, and unlocks.
{ {
if (PlayerMenu[i].status != IT_DISABLED) // If the character's disabled through SOC, there's nothing we can do for it. if (description[i].used) // If the character's disabled through SOC, there's nothing we can do for it.
{ {
name = strtok(Z_StrDup(description[i].skinname), "&"); name = strtok(Z_StrDup(description[i].skinname), "&");
skinnum = R_SkinAvailable(name); skinnum = R_SkinAvailable(name);
if ((skinnum != -1) && (R_SkinUnlock(skinnum))) if ((skinnum != -1) && (R_SkinUsable(-1, skinnum)))
{ {
// Handling order. // Handling order.
if (firstvalid == 255) if (firstvalid == 255)
@ -5404,14 +5369,13 @@ static void M_SetupChoosePlayer(INT32 choice)
} }
lastvalid = i; lastvalid = i;
// Handling visibility. if (i == char_on)
if (PlayerMenu[i].status & (IT_DISABLED|IT_CENTER)) allowed = true;
PlayerMenu[i].status = IT_CALL;
if (description[i].picname[0] == '\0') if (description[i].picname[0] == '\0')
strncpy(description[i].picname, skins[skinnum].charsel, 8); strncpy(description[i].picname, skins[skinnum].charsel, 8);
} }
else // Technically, character select icons without corresponding skins get bundled away behind this too. Sucks to be them. // else -- Technically, character select icons without corresponding skins get bundled away behind this too. Sucks to be them.
PlayerMenu[i].status = (IT_DISABLED|IT_CENTER);
Z_Free(name); Z_Free(name);
} }
} }
@ -5427,7 +5391,7 @@ static void M_SetupChoosePlayer(INT32 choice)
} }
else // We're being forced into a specific character, so might as well. else // We're being forced into a specific character, so might as well.
{ {
PlayerMenu[0].status = (IT_CALL|IT_DYBIGSPACE|(PlayerMenu[0].status & IT_CENTER)); // This is a hack to make a non-IT_CALL character in slot 0 not softlock the game. IT_DYBIGSPACE is a dummy flag, whilst IT_CENTER is preserved. SP_PlayerMenu[0].status |= IT_DYBIGSPACE; // This is a dummy flag hack to make a non-IT_CALL character in slot 0 not softlock the game.
M_ChoosePlayer(0); M_ChoosePlayer(0);
return; return;
} }
@ -5441,9 +5405,77 @@ static void M_SetupChoosePlayer(INT32 choice)
SP_PlayerDef.prevMenu = currentMenu; SP_PlayerDef.prevMenu = currentMenu;
M_SetupNextMenu(&SP_PlayerDef); M_SetupNextMenu(&SP_PlayerDef);
char_scroll = itemOn*128*FRACUNIT; // finish scrolling the menu if (!allowed)
char_on = firstvalid;
char_scroll = 0; // finish scrolling the menu
Z_Free(char_notes); Z_Free(char_notes);
char_notes = NULL; char_notes = V_WordWrap(0, 21*8, V_ALLOWLOWERCASE, description[char_on].notes);
}
//
// M_HandleChoosePlayerMenu
//
// Reacts to your key inputs. Basically a mini menu thinker.
//
static void M_HandleChoosePlayerMenu(INT32 choice)
{
boolean exitmenu = false; // exit to previous menu
INT32 selectval;
switch (choice)
{
case KEY_DOWNARROW:
if ((selectval = description[char_on].next) != char_on)
{
S_StartSound(NULL,sfx_s3kb7);
char_on = selectval;
char_scroll = -128*FRACUNIT;
Z_Free(char_notes);
char_notes = V_WordWrap(0, 21*8, V_ALLOWLOWERCASE, description[char_on].notes);
}
else if (!char_scroll)
{
S_StartSound(NULL,sfx_s3kb7);
char_scroll = 16*FRACUNIT;
}
break;
case KEY_UPARROW:
if ((selectval = description[char_on].prev) != char_on)
{
S_StartSound(NULL,sfx_s3kb7);
char_on = selectval;
char_scroll = 128*FRACUNIT;
Z_Free(char_notes);
char_notes = V_WordWrap(0, 21*8, V_ALLOWLOWERCASE, description[char_on].notes);
}
else if (!char_scroll)
{
S_StartSound(NULL,sfx_s3kb7);
char_scroll = -16*FRACUNIT;
}
break;
case KEY_ENTER:
S_StartSound(NULL, sfx_menu1);
M_ChoosePlayer(char_on);
break;
case KEY_ESCAPE:
exitmenu = true;
break;
default:
break;
}
if (exitmenu)
{
if (currentMenu->prevMenu)
M_SetupNextMenu(currentMenu->prevMenu);
else
M_ClearMenus(true);
}
} }
// Draw the choose player setup menu, had some fun with player anim // Draw the choose player setup menu, had some fun with player anim
@ -5453,7 +5485,6 @@ static void M_DrawSetupChoosePlayerMenu(void)
patch_t *patch; patch_t *patch;
INT32 i, o; INT32 i, o;
UINT8 prev, next; UINT8 prev, next;
boolean loophack = false;
// Black BG // Black BG
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31); V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31);
@ -5462,37 +5493,20 @@ static void M_DrawSetupChoosePlayerMenu(void)
// Character select profile images!1 // Character select profile images!1
M_DrawTextBox(0, my, 16, 20); M_DrawTextBox(0, my, 16, 20);
i = (itemOn*128 - (char_scroll / FRACUNIT)); if (abs(char_scroll) > FRACUNIT)
char_scroll -= (char_scroll>>2);
if (!char_notes)
{
if (i) // turns out this and the preceding check is better then (abs(i) > 128)
{
o = (lastdirection) ? -1 : 1;
char_scroll = (itemOn + o)*128*FRACUNIT;
i = -o*128;
}
char_notes = V_WordWrap(0, 21*8, V_ALLOWLOWERCASE, description[itemOn].notes);
}
if (abs(i) > 1)
char_scroll += i*FRACUNIT>>2;
else // close enough. else // close enough.
char_scroll = itemOn*128*FRACUNIT; // just be exact now. char_scroll = 0; // just be exact now.
o = ((char_scroll / FRACUNIT) + 16); o = (char_scroll >> FRACBITS) + 16;
if (o < 0) // This hack is to prevent visual glitches when looping from the last character to the 1st character. if (o < 0) // A little hacky...
loophack = true; {
i = description[char_on].prev;
if (loophack)
o += 128; o += 128;
}
i = (o / 128); else
o = (o % 128); i = char_on;
if (loophack)
i = description[i].prev;
// Get prev character... // Get prev character...
prev = description[i].prev; prev = description[i].prev;
@ -5503,7 +5517,7 @@ static void M_DrawSetupChoosePlayerMenu(void)
next = description[i].next; next = description[i].next;
// Draw prev character if it's visible and its number isn't greater than the current one or there's more than two // Draw prev character if it's visible and its number isn't greater than the current one or there's more than two
if (o < 32) // (prev != i) was previously a part of this, but we don't need to check again after above. if (o < 32)
{ {
patch = W_CachePatchName(description[prev].picname, PU_CACHE); patch = W_CachePatchName(description[prev].picname, PU_CACHE);
if (SHORT(patch->width) >= 256) if (SHORT(patch->width) >= 256)
@ -5523,31 +5537,24 @@ static void M_DrawSetupChoosePlayerMenu(void)
V_DrawCroppedPatch(8<<FRACBITS, (my + 168 - o)<<FRACBITS, FRACUNIT, 0, patch, 0, 0, SHORT(patch->width), o); V_DrawCroppedPatch(8<<FRACBITS, (my + 168 - o)<<FRACBITS, FRACUNIT, 0, patch, 0, 0, SHORT(patch->width), o);
W_UnlockCachedPatch(patch); W_UnlockCachedPatch(patch);
} }
// current character
if (PlayerMenu[i].status & IT_DISABLED) // Prevent flickering.
i = (lastdirection) ? prev : next; // This actually causes duplication at slow scroll speeds (<16FU per tic), but thankfully we always go quickly.
} }
if (!(PlayerMenu[i].status & IT_DISABLED)) patch = W_CachePatchName(description[i].picname, PU_CACHE);
if (o >= 0 && o <= 32)
{ {
patch = W_CachePatchName(description[i].picname, PU_CACHE); if (SHORT(patch->width) >= 256)
if (o >= 0 && o <= 32) V_DrawSmallScaledPatch(8, my + 40 - o, 0, patch);
{
if (SHORT(patch->width) >= 256)
V_DrawSmallScaledPatch(8, my + 40 - o, 0, patch);
else
V_DrawScaledPatch(8, my + 40 - o, 0, patch);
}
else else
{ V_DrawScaledPatch(8, my + 40 - o, 0, patch);
if (SHORT(patch->width) >= 256)
V_DrawCroppedPatch(8<<FRACBITS, (my + 8)<<FRACBITS, FRACUNIT/2, 0, patch, 0, (o - 32)*2, SHORT(patch->width), SHORT(patch->height));
else
V_DrawCroppedPatch(8<<FRACBITS, (my + 8)<<FRACBITS, FRACUNIT, 0, patch, 0, o - 32, SHORT(patch->width), SHORT(patch->height));
}
W_UnlockCachedPatch(patch);
} }
else
{
if (SHORT(patch->width) >= 256)
V_DrawCroppedPatch(8<<FRACBITS, (my + 8)<<FRACBITS, FRACUNIT/2, 0, patch, 0, (o-32)*2, SHORT(patch->width), SHORT(patch->height));
else
V_DrawCroppedPatch(8<<FRACBITS, (my + 8)<<FRACBITS, FRACUNIT, 0, patch, 0, (o-32), SHORT(patch->width), SHORT(patch->height));
}
W_UnlockCachedPatch(patch);
// draw title (or big pic) // draw title (or big pic)
M_DrawMenuTitle(); M_DrawMenuTitle();
@ -5565,10 +5572,10 @@ static void M_ChoosePlayer(INT32 choice)
boolean ultmode = (ultimate_selectable && SP_PlayerDef.prevMenu == &SP_LoadDef && saveSlotSelected == NOSAVESLOT); boolean ultmode = (ultimate_selectable && SP_PlayerDef.prevMenu == &SP_LoadDef && saveSlotSelected == NOSAVESLOT);
// skip this if forcecharacter or no characters available // skip this if forcecharacter or no characters available
if (!(PlayerMenu[choice].status & IT_DYBIGSPACE)) if (!(SP_PlayerMenu[0].status & IT_DYBIGSPACE))
{ {
// M_SetupChoosePlayer didn't call us directly, that means we've been properly set up. // M_SetupChoosePlayer didn't call us directly, that means we've been properly set up.
char_scroll = itemOn*128*FRACUNIT; // finish scrolling the menu char_scroll = 0; // finish scrolling the menu
M_DrawSetupChoosePlayerMenu(); // draw the finally selected character one last time for the fadeout M_DrawSetupChoosePlayerMenu(); // draw the finally selected character one last time for the fadeout
} }
M_ClearMenus(true); M_ClearMenus(true);
@ -6002,7 +6009,7 @@ void M_DrawTimeAttackMenu(void)
x = SP_TimeAttackDef.x; x = SP_TimeAttackDef.x;
y = SP_TimeAttackDef.y; y = SP_TimeAttackDef.y;
V_DrawString(x, y + SP_TimeAttackMenu[talevelback].alphaKey, V_TRANSLUCENT, SP_TimeAttackMenu[talevelback].text); V_DrawString(x, y + SP_TimeAttackMenu[talevel].alphaKey, V_TRANSLUCENT, SP_TimeAttackMenu[talevel].text);
ncv = (consvar_t *)SP_TimeAttackMenu[taplayer].itemaction; ncv = (consvar_t *)SP_TimeAttackMenu[taplayer].itemaction;
V_DrawString(x, y + SP_TimeAttackMenu[taplayer].alphaKey, V_TRANSLUCENT, SP_TimeAttackMenu[taplayer].text); V_DrawString(x, y + SP_TimeAttackMenu[taplayer].alphaKey, V_TRANSLUCENT, SP_TimeAttackMenu[taplayer].text);
@ -6177,7 +6184,7 @@ void M_DrawNightsAttackMenu(void)
// ALWAYS DRAW level even when not on this menu! // ALWAYS DRAW level even when not on this menu!
if (currentMenu != &SP_NightsAttackDef) if (currentMenu != &SP_NightsAttackDef)
V_DrawString(SP_NightsAttackDef.x, SP_NightsAttackDef.y + SP_TimeAttackMenu[nalevelback].alphaKey, V_TRANSLUCENT, SP_NightsAttackMenu[nalevelback].text); V_DrawString(SP_NightsAttackDef.x, SP_NightsAttackDef.y + SP_TimeAttackMenu[nalevel].alphaKey, V_TRANSLUCENT, SP_NightsAttackMenu[nalevel].text);
} }
static void M_NightsAttackLevelSelect(INT32 choice) static void M_NightsAttackLevelSelect(INT32 choice)
@ -7207,7 +7214,7 @@ static void M_HandleSetupMultiPlayer(INT32 choice)
if (setupm_fakeskin < 0) if (setupm_fakeskin < 0)
setupm_fakeskin = numskins-1; setupm_fakeskin = numskins-1;
} }
while ((prev_setupm_fakeskin != setupm_fakeskin) && !(R_SkinUnlock(setupm_fakeskin))); while ((prev_setupm_fakeskin != setupm_fakeskin) && !(R_SkinUsable(-1, setupm_fakeskin)));
} }
else if (itemOn == 1) // player color else if (itemOn == 1) // player color
{ {
@ -7227,7 +7234,7 @@ static void M_HandleSetupMultiPlayer(INT32 choice)
if (setupm_fakeskin > numskins-1) if (setupm_fakeskin > numskins-1)
setupm_fakeskin = 0; setupm_fakeskin = 0;
} }
while ((prev_setupm_fakeskin != setupm_fakeskin) && !(R_SkinUnlock(setupm_fakeskin))); while ((prev_setupm_fakeskin != setupm_fakeskin) && !(R_SkinUsable(-1, setupm_fakeskin)));
} }
else if (itemOn == 1) // player color else if (itemOn == 1) // player color
{ {

View file

@ -149,8 +149,6 @@ typedef struct menuitem_s
UINT8 alphaKey; UINT8 alphaKey;
} menuitem_t; } menuitem_t;
extern menuitem_t PlayerMenu[32];
typedef struct menu_s typedef struct menu_s
{ {
const char *menutitlepic; const char *menutitlepic;
@ -174,10 +172,10 @@ extern menu_t SP_LoadDef;
// Stuff for customizing the player select screen // Stuff for customizing the player select screen
typedef struct typedef struct
{ {
boolean used;
char notes[441]; char notes[441];
char picname[8]; char picname[8];
char skinname[SKINNAMESIZE*2+2]; // skin&skin\0 char skinname[SKINNAMESIZE*2+2]; // skin&skin\0
UINT16 wadnum; // for duplicate characters
UINT8 prev; UINT8 prev;
UINT8 next; UINT8 next;
} description_t; } description_t;

View file

@ -4182,12 +4182,15 @@ void A_SignPlayer(mobj_t *actor)
actor->frame += Color_Opposite[actor->target->player->skincolor*2+1]; actor->frame += Color_Opposite[actor->target->player->skincolor*2+1];
} }
// spawn an overlay of the player's face. if (skin->sprites[SPR2_SIGN].numframes)
ov = P_SpawnMobj(actor->x, actor->y, actor->z, MT_OVERLAY); {
P_SetTarget(&ov->target, actor); // spawn an overlay of the player's face.
ov->color = actor->target->player->skincolor; ov = P_SpawnMobj(actor->x, actor->y, actor->z, MT_OVERLAY);
ov->skin = skin; P_SetTarget(&ov->target, actor);
P_SetMobjState(ov, actor->info->seestate); // S_PLAY_SIGN ov->color = actor->target->player->skincolor;
ov->skin = skin;
P_SetMobjState(ov, actor->info->seestate); // S_PLAY_SIGN
}
} }
// Function: A_OverlayThink // Function: A_OverlayThink
@ -4517,7 +4520,7 @@ void A_MinusDigging(mobj_t *actor)
// If we're close enough to our target, pop out of the ground // If we're close enough to our target, pop out of the ground
if (P_AproxDistance(actor->target->x-actor->x, actor->target->y-actor->y) < actor->radius if (P_AproxDistance(actor->target->x-actor->x, actor->target->y-actor->y) < actor->radius
&& abs(actor->target->z - actor->z) < actor->height) && abs(actor->target->z - actor->z) < 2*actor->height)
P_SetMobjState(actor, actor->info->missilestate); P_SetMobjState(actor, actor->info->missilestate);
// Snap to ground // Snap to ground
@ -5608,7 +5611,7 @@ void A_MixUp(mobj_t *actor)
// and grab their xyz coords // and grab their xyz coords
for (i = 0; i < MAXPLAYERS; i++) for (i = 0; i < MAXPLAYERS; i++)
if (playeringame[i] && players[i].mo && players[i].mo->health > 0 && players[i].playerstate == PST_LIVE if (playeringame[i] && players[i].mo && players[i].mo->health > 0 && players[i].playerstate == PST_LIVE
&& !players[i].exiting && !players[i].powers[pw_super]) && !players[i].exiting && !players[i].powers[pw_super] && players[i].powers[pw_carry] != CR_NIGHTSMODE)
{ {
if ((netgame || multiplayer) && players[i].spectator) // Ignore spectators if ((netgame || multiplayer) && players[i].spectator) // Ignore spectators
continue; continue;
@ -5727,7 +5730,7 @@ void A_MixUp(mobj_t *actor)
for (i = 0; i < MAXPLAYERS; i++) for (i = 0; i < MAXPLAYERS; i++)
{ {
if (playeringame[i] && players[i].playerstate == PST_LIVE if (playeringame[i] && players[i].playerstate == PST_LIVE
&& players[i].mo && players[i].mo->health > 0 && !players[i].exiting && !players[i].powers[pw_super]) && players[i].mo && players[i].mo->health > 0 && !players[i].exiting && !players[i].powers[pw_super] && players[i].powers[pw_carry] != CR_NIGHTSMODE)
{ {
if ((netgame || multiplayer) && players[i].spectator)// Ignore spectators if ((netgame || multiplayer) && players[i].spectator)// Ignore spectators
continue; continue;
@ -5777,7 +5780,7 @@ void A_MixUp(mobj_t *actor)
for (i = 0; i < MAXPLAYERS; i++) for (i = 0; i < MAXPLAYERS; i++)
{ {
if (playeringame[i] && players[i].playerstate == PST_LIVE if (playeringame[i] && players[i].playerstate == PST_LIVE
&& players[i].mo && players[i].mo->health > 0 && !players[i].exiting && !players[i].powers[pw_super]) && players[i].mo && players[i].mo->health > 0 && !players[i].exiting && !players[i].powers[pw_super] && players[i].powers[pw_carry] != CR_NIGHTSMODE)
{ {
if ((netgame || multiplayer) && players[i].spectator)// Ignore spectators if ((netgame || multiplayer) && players[i].spectator)// Ignore spectators
continue; continue;
@ -5807,7 +5810,7 @@ void A_MixUp(mobj_t *actor)
if (teleported[i]) if (teleported[i])
{ {
if (playeringame[i] && players[i].playerstate == PST_LIVE if (playeringame[i] && players[i].playerstate == PST_LIVE
&& players[i].mo && players[i].mo->health > 0 && !players[i].exiting && !players[i].powers[pw_super]) && players[i].mo && players[i].mo->health > 0 && !players[i].exiting && !players[i].powers[pw_super] && players[i].powers[pw_carry] != CR_NIGHTSMODE)
{ {
if ((netgame || multiplayer) && players[i].spectator)// Ignore spectators if ((netgame || multiplayer) && players[i].spectator)// Ignore spectators
continue; continue;
@ -5949,7 +5952,7 @@ void A_RecyclePowers(mobj_t *actor)
for (j = 0; j < NUMPOWERS; j++) for (j = 0; j < NUMPOWERS; j++)
{ {
if (j == pw_flashing || j == pw_underwater || j == pw_spacetime if (j == pw_flashing || j == pw_underwater || j == pw_spacetime || j == pw_carry
|| j == pw_tailsfly || j == pw_extralife || j == pw_nocontrol || j == pw_super) || j == pw_tailsfly || j == pw_extralife || j == pw_nocontrol || j == pw_super)
continue; continue;
players[recv_pl].powers[j] = powers[send_pl][j]; players[recv_pl].powers[j] = powers[send_pl][j];
@ -8235,7 +8238,7 @@ void A_OrbitNights(mobj_t* actor)
#endif #endif
if (!actor->target || !actor->target->player || if (!actor->target || !actor->target->player ||
!(actor->target->player->pflags & PF_NIGHTSMODE) || !actor->target->player->nightstime !(actor->target->player->powers[pw_carry] == CR_NIGHTSMODE) || !actor->target->player->nightstime
// Also remove this object if they no longer have a NiGHTS helper // Also remove this object if they no longer have a NiGHTS helper
|| (ishelper && !actor->target->player->powers[pw_nights_helper])) || (ishelper && !actor->target->player->powers[pw_nights_helper]))
{ {

View file

@ -1776,9 +1776,9 @@ static mobj_t *SearchMarioNode(msecnode_t *node)
case MT_SCORE: case MT_SCORE:
case MT_DROWNNUMBERS: case MT_DROWNNUMBERS:
case MT_GOTEMERALD: case MT_GOTEMERALD:
case MT_LOCKON:
case MT_TAG: case MT_TAG:
case MT_GOTFLAG: case MT_GOTFLAG:
case MT_GOTFLAG2:
case MT_HOOP: case MT_HOOP:
case MT_HOOPCOLLIDE: case MT_HOOPCOLLIDE:
case MT_NIGHTSCORE: case MT_NIGHTSCORE:

View file

@ -367,11 +367,11 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
return; return;
} }
if (((player->pflags & PF_NIGHTSMODE) && (player->pflags & PF_DRILLING)) if (((player->powers[pw_carry] == CR_NIGHTSMODE) && (player->pflags & PF_DRILLING))
|| ((player->pflags & PF_JUMPED) && (player->pflags & PF_FORCEJUMPDAMAGE || !(player->charflags & SF_NOJUMPSPIN) || (player->charability == CA_TWINSPIN && player->panim == PA_ABILITY))) || ((player->pflags & PF_JUMPED) && (!(player->pflags & PF_NOJUMPDAMAGE) || (player->charability == CA_TWINSPIN && player->panim == PA_ABILITY)))
|| (player->pflags & (PF_SPINNING|PF_GLIDING)) || (player->pflags & (PF_SPINNING|PF_GLIDING))
|| (player->charability2 == CA2_MELEE && player->panim == PA_ABILITY2) || (player->charability2 == CA2_MELEE && player->panim == PA_ABILITY2)
|| ((player->charflags & SF_STOMPDAMAGE) && (P_MobjFlip(toucher)*(toucher->z - (special->z + special->height/2)) > 0) && (P_MobjFlip(toucher)*toucher->momz < 0)) || ((player->charflags & SF_STOMPDAMAGE || player->pflags & PF_BOUNCING) && (P_MobjFlip(toucher)*(toucher->z - (special->z + special->height/2)) > 0) && (P_MobjFlip(toucher)*toucher->momz < 0))
|| player->powers[pw_invulnerability] || player->powers[pw_super] || player->powers[pw_invulnerability] || player->powers[pw_super]
|| elementalpierce) // Do you possess the ability to subdue the object? || elementalpierce) // Do you possess the ability to subdue the object?
{ {
@ -379,9 +379,11 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
{ {
if (elementalpierce == 2) if (elementalpierce == 2)
P_DoBubbleBounce(player); P_DoBubbleBounce(player);
else else if (!(player->charability2 == CA2_MELEE && player->panim == PA_ABILITY2))
toucher->momz = -toucher->momz; toucher->momz = -toucher->momz;
} }
if (player->pflags & PF_BOUNCING)
P_DoAbilityBounce(player, false);
toucher->momx = -toucher->momx; toucher->momx = -toucher->momx;
toucher->momy = -toucher->momy; toucher->momy = -toucher->momy;
P_DamageMobj(special, toucher, toucher, 1, 0); P_DamageMobj(special, toucher, toucher, 1, 0);
@ -406,7 +408,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
//////////////////////////////////////////////////////// ////////////////////////////////////////////////////////
/////ENEMIES!!////////////////////////////////////////// /////ENEMIES!!//////////////////////////////////////////
//////////////////////////////////////////////////////// ////////////////////////////////////////////////////////
if (special->type == MT_GSNAPPER && !(((player->pflags & PF_NIGHTSMODE) && (player->pflags & PF_DRILLING)) if (special->type == MT_GSNAPPER && !(((player->powers[pw_carry] == CR_NIGHTSMODE) && (player->pflags & PF_DRILLING))
|| player->powers[pw_invulnerability] || player->powers[pw_super] || elementalpierce) || player->powers[pw_invulnerability] || player->powers[pw_super] || elementalpierce)
&& toucher->z < special->z + special->height && toucher->z + toucher->height > special->z) && toucher->z < special->z + special->height && toucher->z + toucher->height > special->z)
{ {
@ -416,23 +418,30 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
else if (special->type == MT_SHARP else if (special->type == MT_SHARP
&& ((special->state == &states[special->info->xdeathstate]) || (toucher->z > special->z + special->height/2))) && ((special->state == &states[special->info->xdeathstate]) || (toucher->z > special->z + special->height/2)))
{ {
// Cannot hit sharp from above or when red and angry if (player->pflags & PF_BOUNCING)
P_DamageMobj(toucher, special, special, 1, 0); {
toucher->momz = -toucher->momz;
P_DoAbilityBounce(player, false);
}
else // Cannot hit sharp from above or when red and angry
P_DamageMobj(toucher, special, special, 1, 0);
} }
else if (((player->pflags & PF_NIGHTSMODE) && (player->pflags & PF_DRILLING)) else if (((player->powers[pw_carry] == CR_NIGHTSMODE) && (player->pflags & PF_DRILLING))
|| ((player->pflags & PF_JUMPED) && (player->pflags & PF_FORCEJUMPDAMAGE || !(player->charflags & SF_NOJUMPSPIN) || (player->charability == CA_TWINSPIN && player->panim == PA_ABILITY))) || ((player->pflags & PF_JUMPED) && (!(player->pflags & PF_NOJUMPDAMAGE) || (player->charability == CA_TWINSPIN && player->panim == PA_ABILITY)))
|| (player->pflags & (PF_SPINNING|PF_GLIDING)) || (player->pflags & (PF_SPINNING|PF_GLIDING))
|| (player->charability2 == CA2_MELEE && player->panim == PA_ABILITY2) || (player->charability2 == CA2_MELEE && player->panim == PA_ABILITY2)
|| ((player->charflags & SF_STOMPDAMAGE) && (P_MobjFlip(toucher)*(toucher->z - (special->z + special->height/2)) > 0) && (P_MobjFlip(toucher)*toucher->momz < 0)) || ((player->charflags & SF_STOMPDAMAGE || player->pflags & PF_BOUNCING) && (P_MobjFlip(toucher)*(toucher->z - (special->z + special->height/2)) > 0) && (P_MobjFlip(toucher)*toucher->momz < 0))
|| player->powers[pw_invulnerability] || player->powers[pw_super]) // Do you possess the ability to subdue the object? || player->powers[pw_invulnerability] || player->powers[pw_super]) // Do you possess the ability to subdue the object?
{ {
if ((P_MobjFlip(toucher)*toucher->momz < 0) && (elementalpierce != 1)) if ((P_MobjFlip(toucher)*toucher->momz < 0) && (elementalpierce != 1))
{ {
if (elementalpierce == 2) if (elementalpierce == 2)
P_DoBubbleBounce(player); P_DoBubbleBounce(player);
else else if (!(player->charability2 == CA2_MELEE && player->panim == PA_ABILITY2))
toucher->momz = -toucher->momz; toucher->momz = -toucher->momz;
} }
if (player->pflags & PF_BOUNCING)
P_DoAbilityBounce(player, false);
P_DamageMobj(special, toucher, toucher, 1, 0); P_DamageMobj(special, toucher, toucher, 1, 0);
} }
@ -756,12 +765,12 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
} }
else //Initial transformation. Don't allow second chances in special stages! else //Initial transformation. Don't allow second chances in special stages!
{ {
if (player->pflags & PF_NIGHTSMODE) if (player->powers[pw_carry] == CR_NIGHTSMODE)
return; return;
S_StartSound(toucher, sfx_supert); S_StartSound(toucher, sfx_supert);
} }
if (!(netgame || multiplayer) && !(player->pflags & PF_NIGHTSMODE)) if (!(netgame || multiplayer) && !(player->powers[pw_carry] == CR_NIGHTSMODE))
P_SetTarget(&special->tracer, toucher); P_SetTarget(&special->tracer, toucher);
P_NightserizePlayer(player, special->health); // Transform! P_NightserizePlayer(player, special->health); // Transform!
return; return;
@ -885,7 +894,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
return; return;
// make sure everything is as it should be, THEN take rings from players in special stages // make sure everything is as it should be, THEN take rings from players in special stages
if (player->pflags & PF_NIGHTSMODE && !toucher->target) if (player->powers[pw_carry] == CR_NIGHTSMODE && !toucher->target)
return; return;
if (player->mare != special->threshold) // wrong mare if (player->mare != special->threshold) // wrong mare
@ -923,7 +932,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
if (player->bumpertime < TICRATE/4) if (player->bumpertime < TICRATE/4)
{ {
S_StartSound(toucher, special->info->seesound); S_StartSound(toucher, special->info->seesound);
if (player->pflags & PF_NIGHTSMODE) if (player->powers[pw_carry] == CR_NIGHTSMODE)
{ {
player->bumpertime = TICRATE/2; player->bumpertime = TICRATE/2;
if (special->threshold > 0) if (special->threshold > 0)
@ -979,14 +988,14 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
} }
return; return;
case MT_NIGHTSSUPERLOOP: case MT_NIGHTSSUPERLOOP:
if (player->bot || !(player->pflags & PF_NIGHTSMODE)) if (player->bot || !(player->powers[pw_carry] == CR_NIGHTSMODE))
return; return;
if (!G_IsSpecialStage(gamemap)) if (!G_IsSpecialStage(gamemap))
player->powers[pw_nights_superloop] = (UINT16)special->info->speed; player->powers[pw_nights_superloop] = (UINT16)special->info->speed;
else else
{ {
for (i = 0; i < MAXPLAYERS; i++) for (i = 0; i < MAXPLAYERS; i++)
if (playeringame[i] && players[i].pflags & PF_NIGHTSMODE) if (playeringame[i] && players[i].powers[pw_carry] == CR_NIGHTSMODE)
players[i].powers[pw_nights_superloop] = (UINT16)special->info->speed; players[i].powers[pw_nights_superloop] = (UINT16)special->info->speed;
if (special->info->deathsound != sfx_None) if (special->info->deathsound != sfx_None)
S_StartSound(NULL, special->info->deathsound); S_StartSound(NULL, special->info->deathsound);
@ -1001,14 +1010,14 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
} }
break; break;
case MT_NIGHTSDRILLREFILL: case MT_NIGHTSDRILLREFILL:
if (player->bot || !(player->pflags & PF_NIGHTSMODE)) if (player->bot || !(player->powers[pw_carry] == CR_NIGHTSMODE))
return; return;
if (!G_IsSpecialStage(gamemap)) if (!G_IsSpecialStage(gamemap))
player->drillmeter = special->info->speed; player->drillmeter = special->info->speed;
else else
{ {
for (i = 0; i < MAXPLAYERS; i++) for (i = 0; i < MAXPLAYERS; i++)
if (playeringame[i] && players[i].pflags & PF_NIGHTSMODE) if (playeringame[i] && players[i].powers[pw_carry] == CR_NIGHTSMODE)
players[i].drillmeter = special->info->speed; players[i].drillmeter = special->info->speed;
if (special->info->deathsound != sfx_None) if (special->info->deathsound != sfx_None)
S_StartSound(NULL, special->info->deathsound); S_StartSound(NULL, special->info->deathsound);
@ -1023,7 +1032,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
} }
break; break;
case MT_NIGHTSHELPER: case MT_NIGHTSHELPER:
if (player->bot || !(player->pflags & PF_NIGHTSMODE)) if (player->bot || !(player->powers[pw_carry] == CR_NIGHTSMODE))
return; return;
if (!G_IsSpecialStage(gamemap)) if (!G_IsSpecialStage(gamemap))
{ {
@ -1037,7 +1046,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
{ {
mobj_t *flickyobj; mobj_t *flickyobj;
for (i = 0; i < MAXPLAYERS; i++) for (i = 0; i < MAXPLAYERS; i++)
if (playeringame[i] && players[i].mo && players[i].pflags & PF_NIGHTSMODE) { if (playeringame[i] && players[i].mo && players[i].powers[pw_carry] == CR_NIGHTSMODE) {
players[i].powers[pw_nights_helper] = (UINT16)special->info->speed; players[i].powers[pw_nights_helper] = (UINT16)special->info->speed;
flickyobj = P_SpawnMobj(players[i].mo->x, players[i].mo->y, players[i].mo->z + players[i].mo->info->height, MT_NIGHTOPIANHELPER); flickyobj = P_SpawnMobj(players[i].mo->x, players[i].mo->y, players[i].mo->z + players[i].mo->info->height, MT_NIGHTOPIANHELPER);
P_SetTarget(&flickyobj->target, players[i].mo); P_SetTarget(&flickyobj->target, players[i].mo);
@ -1055,7 +1064,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
} }
break; break;
case MT_NIGHTSEXTRATIME: case MT_NIGHTSEXTRATIME:
if (player->bot || !(player->pflags & PF_NIGHTSMODE)) if (player->bot || !(player->powers[pw_carry] == CR_NIGHTSMODE))
return; return;
if (!G_IsSpecialStage(gamemap)) if (!G_IsSpecialStage(gamemap))
{ {
@ -1066,7 +1075,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
else else
{ {
for (i = 0; i < MAXPLAYERS; i++) for (i = 0; i < MAXPLAYERS; i++)
if (playeringame[i] && players[i].pflags & PF_NIGHTSMODE) if (playeringame[i] && players[i].powers[pw_carry] == CR_NIGHTSMODE)
{ {
players[i].nightstime += special->info->speed; players[i].nightstime += special->info->speed;
players[i].startedtime += special->info->speed; players[i].startedtime += special->info->speed;
@ -1085,7 +1094,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
} }
break; break;
case MT_NIGHTSLINKFREEZE: case MT_NIGHTSLINKFREEZE:
if (player->bot || !(player->pflags & PF_NIGHTSMODE)) if (player->bot || !(player->powers[pw_carry] == CR_NIGHTSMODE))
return; return;
if (!G_IsSpecialStage(gamemap)) if (!G_IsSpecialStage(gamemap))
{ {
@ -1095,7 +1104,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
else else
{ {
for (i = 0; i < MAXPLAYERS; i++) for (i = 0; i < MAXPLAYERS; i++)
if (playeringame[i] && players[i].pflags & PF_NIGHTSMODE) if (playeringame[i] && players[i].powers[pw_carry] == CR_NIGHTSMODE)
{ {
players[i].powers[pw_nights_linkfreeze] += (UINT16)special->info->speed; players[i].powers[pw_nights_linkfreeze] += (UINT16)special->info->speed;
players[i].linktimer = 2*TICRATE; players[i].linktimer = 2*TICRATE;
@ -1153,7 +1162,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
if (G_IsSpecialStage(gamemap)) if (G_IsSpecialStage(gamemap))
{ {
for (i = 0; i < MAXPLAYERS; i++) for (i = 0; i < MAXPLAYERS; i++)
if (playeringame[i] && players[i].pflags & PF_NIGHTSMODE) if (playeringame[i] && players[i].powers[pw_carry] == CR_NIGHTSMODE)
players[i].drillmeter += TICRATE/2; players[i].drillmeter += TICRATE/2;
} }
else if (player->bot) else if (player->bot)
@ -1336,9 +1345,10 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
toucher->momz = -toucher->momz; toucher->momz = -toucher->momz;
if (player->pflags & PF_GLIDING) if (player->pflags & PF_GLIDING)
{ {
player->pflags &= ~(PF_GLIDING|PF_JUMPED); player->pflags &= ~(PF_GLIDING|PF_JUMPED|PF_NOJUMPDAMAGE);
P_SetPlayerMobjState(toucher, S_PLAY_FALL); P_SetPlayerMobjState(toucher, S_PLAY_FALL);
} }
player->homing = 0;
// Play a bounce sound? // Play a bounce sound?
S_StartSound(toucher, special->info->painsound); S_StartSound(toucher, special->info->painsound);
@ -1346,7 +1356,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
return; return;
case MT_BLACKEGGMAN_GOOPFIRE: case MT_BLACKEGGMAN_GOOPFIRE:
if (toucher->state != &states[S_PLAY_PAIN] && !player->powers[pw_flashing]) if (!player->powers[pw_flashing])
{ {
toucher->momx = 0; toucher->momx = 0;
toucher->momy = 0; toucher->momy = 0;
@ -1354,13 +1364,8 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
if (toucher->momz != 0) if (toucher->momz != 0)
special->momz = toucher->momz; special->momz = toucher->momz;
player->powers[pw_ingoop] = 2; player->powers[pw_carry] = CR_BRAKGOOP;
P_SetTarget(&toucher->tracer, special);
if (player->powers[pw_carry] == CR_GENERIC)
{
P_SetTarget(&toucher->tracer, NULL);
player->powers[pw_carry] = CR_NONE;
}
P_ResetPlayer(player); P_ResetPlayer(player);
@ -1372,8 +1377,6 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
P_SetMobjState(special->target, special->target->info->raisestate); P_SetMobjState(special->target, special->target->info->raisestate);
} }
} }
else
player->powers[pw_ingoop] = 0;
return; return;
case MT_EGGSHIELD: case MT_EGGSHIELD:
{ {
@ -1403,17 +1406,18 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
toucher->momz = -toucher->momz; toucher->momz = -toucher->momz;
if (player->pflags & PF_GLIDING) if (player->pflags & PF_GLIDING)
{ {
player->pflags &= ~(PF_GLIDING|PF_JUMPED); player->pflags &= ~(PF_GLIDING|PF_JUMPED|PF_NOJUMPDAMAGE);
P_SetPlayerMobjState(toucher, S_PLAY_FALL); P_SetPlayerMobjState(toucher, S_PLAY_FALL);
} }
player->homing = 0;
// Play a bounce sound? // Play a bounce sound?
S_StartSound(toucher, special->info->painsound); S_StartSound(toucher, special->info->painsound);
return; return;
} }
else if (((player->pflags & PF_NIGHTSMODE) && (player->pflags & PF_DRILLING)) else if (((player->powers[pw_carry] == CR_NIGHTSMODE) && (player->pflags & PF_DRILLING))
|| ((player->pflags & PF_JUMPED) && (player->pflags & PF_FORCEJUMPDAMAGE || !(player->charflags & SF_NOJUMPSPIN) || (player->charability == CA_TWINSPIN && player->panim == PA_ABILITY))) || ((player->pflags & PF_JUMPED) && (!(player->pflags & PF_NOJUMPDAMAGE) || (player->charability == CA_TWINSPIN && player->panim == PA_ABILITY)))
|| ((player->charflags & SF_STOMPDAMAGE) && (P_MobjFlip(toucher)*(toucher->z - (special->z + special->height/2)) > 0) && (P_MobjFlip(toucher)*toucher->momz < 0)) || ((player->charflags & SF_STOMPDAMAGE || player->pflags & PF_BOUNCING) && (P_MobjFlip(toucher)*(toucher->z - (special->z + special->height/2)) > 0) && (P_MobjFlip(toucher)*toucher->momz < 0))
|| (player->pflags & (PF_SPINNING|PF_GLIDING)) || (player->pflags & (PF_SPINNING|PF_GLIDING))
|| player->powers[pw_invulnerability] || player->powers[pw_super]) // Do you possess the ability to subdue the object? || player->powers[pw_invulnerability] || player->powers[pw_super]) // Do you possess the ability to subdue the object?
{ {
@ -1463,7 +1467,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
{ {
player->powers[pw_carry] = CR_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_ROLL);
} }
else else
player->powers[pw_carry] = CR_GENERIC; player->powers[pw_carry] = CR_GENERIC;
@ -2597,7 +2601,7 @@ static inline void P_NiGHTSDamage(mobj_t *target, mobj_t *source)
} }
player->powers[pw_flashing] = flashingtics; player->powers[pw_flashing] = flashingtics;
P_SetPlayerMobjState(target, S_PLAY_NIGHTS_PAIN); P_SetPlayerMobjState(target, S_PLAY_NIGHTS_STUN);
S_StartSound(target, sfx_nghurt); S_StartSound(target, sfx_nghurt);
if (oldnightstime > 10*TICRATE if (oldnightstime > 10*TICRATE
@ -2724,7 +2728,7 @@ 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_SLIDING|PF_NIGHTSMODE); player->pflags &= ~PF_SLIDING;
player->powers[pw_carry] = CR_NONE; player->powers[pw_carry] = CR_NONE;
@ -2820,10 +2824,7 @@ static inline void P_SuperDamage(player_t *player, mobj_t *inflictor, mobj_t *so
P_InstaThrust(player->mo, ang, fallbackspeed); P_InstaThrust(player->mo, ang, fallbackspeed);
if (player->charflags & SF_SUPERANIMS) P_SetPlayerMobjState(player->mo, S_PLAY_STUN);
P_SetPlayerMobjState(player->mo, S_PLAY_SUPER_STUN);
else
P_SetPlayerMobjState(player->mo, player->mo->info->painstate);
P_ResetPlayer(player); P_ResetPlayer(player);
@ -3069,7 +3070,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->pflags & (PF_NIGHTSMODE|PF_NIGHTSFALL)) && (maptol & TOL_NIGHTS)) if (!(target->player->powers[pw_carry] == CR_NIGHTSMODE || target->player->pflags & PF_NIGHTSFALL) && (maptol & TOL_NIGHTS))
return false; return false;
switch (damagetype) switch (damagetype)
@ -3091,7 +3092,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
} }
} }
if (player->pflags & PF_NIGHTSMODE) // NiGHTS damage handling if (player->powers[pw_carry] == CR_NIGHTSMODE) // NiGHTS damage handling
{ {
if (!force) if (!force)
{ {

View file

@ -130,6 +130,7 @@ void P_ResetCamera(player_t *player, camera_t *thiscam);
boolean P_TryCameraMove(fixed_t x, fixed_t y, camera_t *thiscam); boolean P_TryCameraMove(fixed_t x, fixed_t y, camera_t *thiscam);
void P_SlideCameraMove(camera_t *thiscam); void P_SlideCameraMove(camera_t *thiscam);
boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcalled); boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcalled);
pflags_t P_GetJumpFlags(player_t *player);
boolean P_PlayerInPain(player_t *player); boolean P_PlayerInPain(player_t *player);
void P_DoPlayerPain(player_t *player, mobj_t *source, mobj_t *inflictor); void P_DoPlayerPain(player_t *player, mobj_t *source, mobj_t *inflictor);
void P_ResetPlayer(player_t *player); void P_ResetPlayer(player_t *player);
@ -150,11 +151,16 @@ void P_GivePlayerRings(player_t *player, INT32 num_rings);
void P_GivePlayerLives(player_t *player, INT32 numlives); void P_GivePlayerLives(player_t *player, INT32 numlives);
UINT8 P_GetNextEmerald(void); UINT8 P_GetNextEmerald(void);
void P_GiveEmerald(boolean spawnObj); void P_GiveEmerald(boolean spawnObj);
#if 0
void P_ResetScore(player_t *player); void P_ResetScore(player_t *player);
#else
#define P_ResetScore(player) player->scoreadd = 0
#endif
boolean P_AutoPause(void); boolean P_AutoPause(void);
void P_DoJumpShield(player_t *player); void P_DoJumpShield(player_t *player);
void P_DoBubbleBounce(player_t *player); void P_DoBubbleBounce(player_t *player);
void P_DoAbilityBounce(player_t *player, boolean changemomz);
void P_BlackOw(player_t *player); void P_BlackOw(player_t *player);
void P_ElementalFire(player_t *player, boolean cropcircle); void P_ElementalFire(player_t *player, boolean cropcircle);
@ -169,12 +175,16 @@ fixed_t P_ReturnThrustX(mobj_t *mo, angle_t angle, fixed_t move);
fixed_t P_ReturnThrustY(mobj_t *mo, angle_t angle, fixed_t move); fixed_t P_ReturnThrustY(mobj_t *mo, angle_t angle, fixed_t move);
void P_InstaThrustEvenIn2D(mobj_t *mo, angle_t angle, fixed_t move); void P_InstaThrustEvenIn2D(mobj_t *mo, angle_t angle, fixed_t move);
boolean P_LookForEnemies(player_t *player, boolean nonenemies); mobj_t *P_LookForEnemies(player_t *player, boolean nonenemies, boolean bullet);
void P_NukeEnemies(mobj_t *inflictor, mobj_t *source, fixed_t radius); void P_NukeEnemies(mobj_t *inflictor, mobj_t *source, fixed_t radius);
void P_HomingAttack(mobj_t *source, mobj_t *enemy); /// \todo doesn't belong in p_user void P_HomingAttack(mobj_t *source, mobj_t *enemy); /// \todo doesn't belong in p_user
boolean P_SuperReady(player_t *player); boolean P_SuperReady(player_t *player);
void P_DoJump(player_t *player, boolean soundandstate); void P_DoJump(player_t *player, boolean soundandstate);
#if 0
boolean P_AnalogMove(player_t *player); boolean P_AnalogMove(player_t *player);
#else
#define P_AnalogMove(player) (player->pflags & PF_ANALOGMODE)
#endif
boolean P_TransferToNextMare(player_t *player); boolean P_TransferToNextMare(player_t *player);
UINT8 P_FindLowestMare(void); UINT8 P_FindLowestMare(void);
void P_FindEmerald(void); void P_FindEmerald(void);

View file

@ -115,7 +115,7 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object)
fixed_t offx, offy; fixed_t offx, offy;
fixed_t vertispeed = spring->info->mass; fixed_t vertispeed = spring->info->mass;
fixed_t horizspeed = spring->info->damage; fixed_t horizspeed = spring->info->damage;
UINT8 jumping, secondjump; UINT8 secondjump;
if (object->eflags & MFE_SPRUNG) // Object was already sprung this tic if (object->eflags & MFE_SPRUNG) // Object was already sprung this tic
return false; return false;
@ -124,20 +124,25 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object)
if (object->player && object->player->spectator) if (object->player && object->player->spectator)
return false; return false;
if (object->player && (object->player->pflags & PF_NIGHTSMODE)) if (object->player && (object->player->powers[pw_carry] == CR_NIGHTSMODE))
{ {
/*Someone want to make these work like bumpers?*/ /*Someone want to make these work like bumpers?*/
return false; return false;
} }
#ifdef ESLOPE if (object->player
object->standingslope = NULL; // Okay, now we can't return - no launching off at silly angles for you. && ((object->player->charability == CA_TWINSPIN && object->player->panim == PA_ABILITY)
#endif || (object->player->charability2 == CA2_MELEE && object->player->panim == PA_ABILITY2)))
{
S_StartSound(object, sfx_s3k8b);
horizspeed = FixedMul(horizspeed, (4*FRACUNIT)/3);
vertispeed = FixedMul(vertispeed, (6*FRACUNIT)/5); // aprox square root of above
}
object->eflags |= MFE_SPRUNG; // apply this flag asap! object->eflags |= MFE_SPRUNG; // apply this flag asap!
spring->flags &= ~(MF_SOLID|MF_SPECIAL); // De-solidify spring->flags &= ~(MF_SOLID|MF_SPECIAL); // De-solidify
if (horizspeed && vertispeed) // Mimic SA if ((horizspeed && vertispeed) || (object->player && object->player->homing)) // Mimic SA
{ {
object->momx = object->momy = 0; object->momx = object->momy = 0;
P_TryMove(object, spring->x, spring->y, true); P_TryMove(object, spring->x, spring->y, true);
@ -203,32 +208,36 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object)
} }
} }
pflags = object->player->pflags & (PF_JUMPED|PF_SPINNING|PF_THOKKED|PF_SHIELDABILITY); // I still need these. pflags = object->player->pflags & (PF_STARTJUMP|PF_JUMPED|PF_NOJUMPDAMAGE|PF_SPINNING|PF_THOKKED|PF_SHIELDABILITY|PF_BOUNCING); // I still need these.
jumping = object->player->jumping;
secondjump = object->player->secondjump; secondjump = object->player->secondjump;
P_ResetPlayer(object->player); P_ResetPlayer(object->player);
if (spring->info->painchance) if (spring->info->painchance)
{ {
object->player->pflags |= PF_JUMPED; object->player->pflags |= P_GetJumpFlags(object->player);
P_SetPlayerMobjState(object, S_PLAY_JUMP); P_SetPlayerMobjState(object, S_PLAY_JUMP);
} }
else if (P_MobjFlip(object)*vertispeed > 0) else if (!vertispeed || (pflags & PF_BOUNCING)) // horizontal spring or bouncing
P_SetPlayerMobjState(object, S_PLAY_SPRING);
else if (P_MobjFlip(object)*vertispeed < 0)
P_SetPlayerMobjState(object, S_PLAY_FALL);
else // horizontal spring
{ {
if (pflags & (PF_JUMPED|PF_SPINNING) && (object->player->panim == PA_ROLL || object->player->panim == PA_JUMP || object->player->panim == PA_FALL)) if ((pflags & PF_BOUNCING)
|| (pflags & (PF_JUMPED|PF_SPINNING) && (object->player->panim == PA_ROLL || object->player->panim == PA_JUMP || object->player->panim == PA_FALL)))
{ {
object->player->pflags |= pflags; object->player->pflags |= pflags;
object->player->jumping = jumping;
object->player->secondjump = secondjump; object->player->secondjump = secondjump;
} }
else else
P_SetPlayerMobjState(object, S_PLAY_WALK); P_SetPlayerMobjState(object, S_PLAY_WALK);
} }
else if (P_MobjFlip(object)*vertispeed > 0)
P_SetPlayerMobjState(object, S_PLAY_SPRING);
else
P_SetPlayerMobjState(object, S_PLAY_FALL);
} }
#ifdef ESLOPE
object->standingslope = NULL; // Okay, now we know it's not going to be relevant - no launching off at silly angles for you.
#endif
return true; return true;
} }
@ -324,9 +333,6 @@ static void P_DoTailsCarry(player_t *sonic, player_t *tails)
if (tails->bot == 1) if (tails->bot == 1)
return; return;
if (sonic->pflags & PF_NIGHTSMODE)
return;
if ((sonic->mo->eflags & MFE_VERTICALFLIP) != (tails->mo->eflags & MFE_VERTICALFLIP)) if ((sonic->mo->eflags & MFE_VERTICALFLIP) != (tails->mo->eflags & MFE_VERTICALFLIP))
return; // Both should be in same gravity return; // Both should be in same gravity
@ -377,6 +383,7 @@ 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);
P_SetTarget(&sonic->mo->tracer, NULL);
sonic->powers[pw_carry] = CR_NONE; sonic->powers[pw_carry] = CR_NONE;
} }
} }
@ -460,9 +467,9 @@ static boolean PIT_CheckThing(mobj_t *thing)
return true; return true;
} }
// CA_DASHMODE users destroy spikes and monitors, CA_TWINSPIN users and CA2_MELEE users destroy spikes. // SF_DASHMODE users destroy spikes and monitors, CA_TWINSPIN users and CA2_MELEE users destroy spikes.
if ((tmthing->player) if ((tmthing->player)
&& (((tmthing->player->charability == CA_DASHMODE) && (tmthing->player->dashmode >= 3*TICRATE) && (((tmthing->player->charflags & SF_DASHMODE) && (tmthing->player->dashmode >= 3*TICRATE)
&& (thing->flags & (MF_MONITOR) || thing->type == MT_SPIKE)) && (thing->flags & (MF_MONITOR) || thing->type == MT_SPIKE))
|| ((((tmthing->player->charability == CA_TWINSPIN) && (tmthing->player->panim == PA_ABILITY)) || ((((tmthing->player->charability == CA_TWINSPIN) && (tmthing->player->panim == PA_ABILITY))
|| (tmthing->player->charability2 == CA2_MELEE && tmthing->player->panim == PA_ABILITY2)) || (tmthing->player->charability2 == CA2_MELEE && tmthing->player->panim == PA_ABILITY2))
@ -499,7 +506,7 @@ static boolean PIT_CheckThing(mobj_t *thing)
// Don't collide with your buddies while NiGHTS-flying. // Don't collide with your buddies while NiGHTS-flying.
if (tmthing->player && thing->player && (maptol & TOL_NIGHTS) if (tmthing->player && thing->player && (maptol & TOL_NIGHTS)
&& ((tmthing->player->pflags & PF_NIGHTSMODE) || (thing->player->pflags & PF_NIGHTSMODE))) && ((tmthing->player->powers[pw_carry] == CR_NIGHTSMODE) || (thing->player->powers[pw_carry] == CR_NIGHTSMODE)))
return true; return true;
blockdist = thing->radius + tmthing->radius; blockdist = thing->radius + tmthing->radius;
@ -785,7 +792,7 @@ static boolean PIT_CheckThing(mobj_t *thing)
{ {
// Hop on the missile for a ride! // Hop on the missile for a ride!
thing->player->powers[pw_carry] = CR_GENERIC; thing->player->powers[pw_carry] = CR_GENERIC;
thing->player->pflags &= ~PF_JUMPED; thing->player->pflags &= ~(PF_JUMPED|PF_NOJUMPDAMAGE);
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
P_SetTarget(&tmthing->tracer, NULL); // Disable homing-ness P_SetTarget(&tmthing->tracer, NULL); // Disable homing-ness
@ -896,7 +903,7 @@ static boolean PIT_CheckThing(mobj_t *thing)
// must be flying in the SAME DIRECTION as the last time you came through. // must be flying in the SAME DIRECTION as the last time you came through.
// not (your direction) xor (stored direction) // not (your direction) xor (stored direction)
// In other words, you can't u-turn and respawn rings near the drone. // In other words, you can't u-turn and respawn rings near the drone.
if (pl->bonustime && (pl->pflags & PF_NIGHTSMODE) && (INT32)leveltime > droneobj->extravalue2 && ( if (pl->bonustime && (pl->powers[pw_carry] == CR_NIGHTSMODE) && (INT32)leveltime > droneobj->extravalue2 && (
!(pl->anotherflyangle >= 90 && pl->anotherflyangle <= 270) !(pl->anotherflyangle >= 90 && pl->anotherflyangle <= 270)
^ (droneobj->extravalue1 >= 90 && droneobj->extravalue1 <= 270) ^ (droneobj->extravalue1 >= 90 && droneobj->extravalue1 <= 270)
)) ))
@ -928,11 +935,13 @@ static boolean PIT_CheckThing(mobj_t *thing)
if (tmthing->eflags & MFE_VERTICALFLIP) if (tmthing->eflags & MFE_VERTICALFLIP)
{ {
if (thing->z + thing->height <= tmthing->z + FixedMul(FRACUNIT, tmthing->scale) if (thing->z + thing->height <= tmthing->z + FixedMul(FRACUNIT, tmthing->scale)
&& thing->z + thing->height + thing->momz >= tmthing->z + FixedMul(FRACUNIT, tmthing->scale) + tmthing->momz) && thing->z + thing->height + thing->momz >= tmthing->z + FixedMul(FRACUNIT, tmthing->scale) + tmthing->momz
&& !(thing->player->charability == CA_BOUNCE && thing->player->panim == PA_ABILITY && thing->eflags & MFE_VERTICALFLIP))
P_DamageMobj(thing, tmthing, tmthing, 1, 0); P_DamageMobj(thing, tmthing, tmthing, 1, 0);
} }
else if (thing->z >= tmthing->z + tmthing->height - FixedMul(FRACUNIT, tmthing->scale) else if (thing->z >= tmthing->z + tmthing->height - FixedMul(FRACUNIT, tmthing->scale)
&& thing->z + thing->momz <= tmthing->z + tmthing->height - FixedMul(FRACUNIT, tmthing->scale) + tmthing->momz) && thing->z + thing->momz <= tmthing->z + tmthing->height - FixedMul(FRACUNIT, tmthing->scale) + tmthing->momz
&& !(thing->player->charability == CA_BOUNCE && thing->player->panim == PA_ABILITY && !(thing->eflags & MFE_VERTICALFLIP)))
P_DamageMobj(thing, tmthing, tmthing, 1, 0); P_DamageMobj(thing, tmthing, tmthing, 1, 0);
} }
else if (thing->type == MT_SPIKE && thing->flags & MF_SOLID && tmthing->player) // unfortunate player falls into spike?! else if (thing->type == MT_SPIKE && thing->flags & MF_SOLID && tmthing->player) // unfortunate player falls into spike?!
@ -940,11 +949,13 @@ static boolean PIT_CheckThing(mobj_t *thing)
if (thing->eflags & MFE_VERTICALFLIP) if (thing->eflags & MFE_VERTICALFLIP)
{ {
if (tmthing->z + tmthing->height <= thing->z - FixedMul(FRACUNIT, thing->scale) if (tmthing->z + tmthing->height <= thing->z - FixedMul(FRACUNIT, thing->scale)
&& tmthing->z + tmthing->height + tmthing->momz >= thing->z - FixedMul(FRACUNIT, thing->scale)) && tmthing->z + tmthing->height + tmthing->momz >= thing->z - FixedMul(FRACUNIT, thing->scale)
&& !(tmthing->player->charability == CA_BOUNCE && tmthing->player->panim == PA_ABILITY && tmthing->eflags & MFE_VERTICALFLIP))
P_DamageMobj(tmthing, thing, thing, 1, 0); P_DamageMobj(tmthing, thing, thing, 1, 0);
} }
else if (tmthing->z >= thing->z + thing->height + FixedMul(FRACUNIT, thing->scale) else if (tmthing->z >= thing->z + thing->height + FixedMul(FRACUNIT, thing->scale)
&& tmthing->z + tmthing->momz <= thing->z + thing->height + FixedMul(FRACUNIT, thing->scale)) && tmthing->z + tmthing->momz <= thing->z + thing->height + FixedMul(FRACUNIT, thing->scale)
&& !(tmthing->player->charability == CA_BOUNCE && tmthing->player->panim == PA_ABILITY && !(tmthing->eflags & MFE_VERTICALFLIP)))
P_DamageMobj(tmthing, thing, thing, 1, 0); P_DamageMobj(tmthing, thing, thing, 1, 0);
} }
@ -1005,7 +1016,10 @@ static boolean PIT_CheckThing(mobj_t *thing)
if (thing->player-players == consoleplayer && botingame) if (thing->player-players == consoleplayer && botingame)
CV_SetValue(&cv_analog2, true); CV_SetValue(&cv_analog2, true);
if (thing->player->powers[pw_carry] == CR_PLAYER) if (thing->player->powers[pw_carry] == CR_PLAYER)
{
P_SetTarget(&thing->tracer, NULL);
thing->player->powers[pw_carry] = CR_NONE; thing->player->powers[pw_carry] = CR_NONE;
}
} }
if (thing->player) if (thing->player)
@ -1063,11 +1077,10 @@ static boolean PIT_CheckThing(mobj_t *thing)
if (thing->flags & MF_MONITOR if (thing->flags & MF_MONITOR
&& (tmthing->player->pflags & (PF_SPINNING|PF_GLIDING) && (tmthing->player->pflags & (PF_SPINNING|PF_GLIDING)
|| ((tmthing->player->pflags & PF_JUMPED) || ((tmthing->player->pflags & PF_JUMPED)
&& (tmthing->player->pflags & PF_FORCEJUMPDAMAGE && (!(tmthing->player->pflags & PF_NOJUMPDAMAGE)
|| !(tmthing->player->charflags & SF_NOJUMPSPIN)
|| (tmthing->player->charability == CA_TWINSPIN && tmthing->player->panim == PA_ABILITY))) || (tmthing->player->charability == CA_TWINSPIN && tmthing->player->panim == PA_ABILITY)))
|| (tmthing->player->charability2 == CA2_MELEE && tmthing->player->panim == PA_ABILITY2) || (tmthing->player->charability2 == CA2_MELEE && tmthing->player->panim == PA_ABILITY2)
|| ((tmthing->player->charflags & SF_STOMPDAMAGE) || ((tmthing->player->charflags & SF_STOMPDAMAGE || tmthing->player->pflags & PF_BOUNCING)
&& (P_MobjFlip(tmthing)*(tmthing->z - (thing->z + thing->height/2)) > 0) && (P_MobjFlip(tmthing)*tmthing->momz < 0)) && (P_MobjFlip(tmthing)*(tmthing->z - (thing->z + thing->height/2)) > 0) && (P_MobjFlip(tmthing)*tmthing->momz < 0))
|| elementalpierce)) || elementalpierce))
{ {
@ -1084,11 +1097,15 @@ static boolean PIT_CheckThing(mobj_t *thing)
{ {
if (elementalpierce == 2) if (elementalpierce == 2)
P_DoBubbleBounce(player); P_DoBubbleBounce(player);
else else if (!(player->charability2 == CA2_MELEE && player->panim == PA_ABILITY2))
*momz = -*momz; // Therefore, you should be thrust in the opposite direction, vertically. *momz = -*momz; // Therefore, you should be thrust in the opposite direction, vertically.
} }
if (!(elementalpierce == 1 && thing->flags & MF_GRENADEBOUNCE)) // prevent gold monitor clipthrough. if (!(elementalpierce == 1 && thing->flags & MF_GRENADEBOUNCE)) // prevent gold monitor clipthrough.
{
if (player->pflags & PF_BOUNCING)
P_DoAbilityBounce(player, false);
return false; return false;
}
else else
*z -= *momz; // to ensure proper collision. *z -= *momz; // to ensure proper collision.
} }
@ -1105,11 +1122,10 @@ static boolean PIT_CheckThing(mobj_t *thing)
else if (thing->flags & MF_MONITOR && tmthing->player else if (thing->flags & MF_MONITOR && tmthing->player
&& (tmthing->player->pflags & (PF_SPINNING|PF_GLIDING) && (tmthing->player->pflags & (PF_SPINNING|PF_GLIDING)
|| ((tmthing->player->pflags & PF_JUMPED) || ((tmthing->player->pflags & PF_JUMPED)
&& (tmthing->player->pflags & PF_FORCEJUMPDAMAGE && (!(tmthing->player->pflags & PF_NOJUMPDAMAGE)
|| !(tmthing->player->charflags & SF_NOJUMPSPIN)
|| (tmthing->player->charability == CA_TWINSPIN && tmthing->player->panim == PA_ABILITY))) || (tmthing->player->charability == CA_TWINSPIN && tmthing->player->panim == PA_ABILITY)))
|| (tmthing->player->charability2 == CA2_MELEE && tmthing->player->panim == PA_ABILITY2) || (tmthing->player->charability2 == CA2_MELEE && tmthing->player->panim == PA_ABILITY2)
|| ((tmthing->player->charflags & SF_STOMPDAMAGE) || ((tmthing->player->charflags & SF_STOMPDAMAGE || tmthing->player->pflags & PF_BOUNCING)
&& (P_MobjFlip(tmthing)*(tmthing->z - (thing->z + thing->height/2)) > 0) && (P_MobjFlip(tmthing)*tmthing->momz < 0))) && (P_MobjFlip(tmthing)*(tmthing->z - (thing->z + thing->height/2)) > 0) && (P_MobjFlip(tmthing)*tmthing->momz < 0)))
&& !((thing->type == MT_RING_REDBOX && tmthing->player->ctfteam != 1) || (thing->type == MT_RING_BLUEBOX && tmthing->player->ctfteam != 2))) && !((thing->type == MT_RING_REDBOX && tmthing->player->ctfteam != 1) || (thing->type == MT_RING_BLUEBOX && tmthing->player->ctfteam != 2)))
; ;
@ -1512,7 +1528,7 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y)
else if (thing->type == MT_SKIM && (rover->flags & FF_SWIMMABLE)) else if (thing->type == MT_SKIM && (rover->flags & FF_SWIMMABLE))
; ;
else if (!((rover->flags & FF_BLOCKPLAYER && thing->player) else if (!((rover->flags & FF_BLOCKPLAYER && thing->player)
|| (rover->flags & FF_BLOCKOTHERS && !thing->player) || (rover->flags & FF_BLOCKOTHERS && !thing->player)
|| rover->flags & FF_QUICKSAND)) || rover->flags & FF_QUICKSAND))
continue; continue;
@ -2890,7 +2906,7 @@ isblocking:
slidemo->player->climbing = 5; slidemo->player->climbing = 5;
} }
slidemo->player->pflags &= ~(PF_GLIDING|PF_SPINNING|PF_JUMPED|PF_THOKKED); slidemo->player->pflags &= ~(PF_GLIDING|PF_SPINNING|PF_JUMPED|PF_NOJUMPDAMAGE|PF_THOKKED);
slidemo->player->glidetime = 0; slidemo->player->glidetime = 0;
slidemo->player->secondjump = 0; slidemo->player->secondjump = 0;

View file

@ -187,32 +187,41 @@ static void P_CyclePlayerMobjState(mobj_t *mobj)
// //
// P_GetMobjSprite2 // P_GetMobjSprite2
// For non-super players, tries each sprite2's immediate predecessor until it finds one with a number of frames or ends up at standing.
// For super players, does the same as above - but tries the super equivalent for each sprite2 before the non-super version.
// //
UINT8 P_GetMobjSprite2(mobj_t *mobj, UINT8 spr2) UINT8 P_GetMobjSprite2(mobj_t *mobj, UINT8 spr2)
{ {
player_t *player = mobj->player; player_t *player = mobj->player;
skin_t *skin = ((skin_t *)mobj->skin); skin_t *skin = ((skin_t *)mobj->skin);
UINT8 super = (spr2 & FF_SPR2SUPER);
if (!skin) if (!skin)
return 0; return 0;
while ((skin->sprites[spr2].numframes <= 0) while (!(skin->sprites[spr2].numframes)
&& spr2 != SPR2_STND) && spr2 != SPR2_STND)
{ {
if (spr2 & FF_SPR2SUPER)
{
spr2 &= ~FF_SPR2SUPER;
continue;
}
switch(spr2) switch(spr2)
{ {
case SPR2_PEEL:
spr2 = SPR2_RUN;
break;
case SPR2_RUN: case SPR2_RUN:
spr2 = SPR2_WALK; spr2 = SPR2_WALK;
break; break;
case SPR2_STUN:
spr2 = SPR2_PAIN;
break;
case SPR2_DRWN: case SPR2_DRWN:
spr2 = SPR2_DEAD; spr2 = SPR2_DEAD;
break; break;
case SPR2_DASH: case SPR2_SPIN:
spr2 = SPR2_SPIN; spr2 = SPR2_ROLL;
break; break;
case SPR2_GASP: case SPR2_GASP:
spr2 = SPR2_SPNG; spr2 = SPR2_SPNG;
@ -221,7 +230,7 @@ UINT8 P_GetMobjSprite2(mobj_t *mobj, UINT8 spr2)
spr2 = ((player spr2 = ((player
? player->charflags ? player->charflags
: skin->flags) : skin->flags)
& SF_NOJUMPSPIN) ? SPR2_SPNG : SPR2_SPIN; & SF_NOJUMPSPIN) ? SPR2_SPNG : SPR2_ROLL;
break; break;
case SPR2_SPNG: // spring case SPR2_SPNG: // spring
spr2 = SPR2_FALL; spr2 = SPR2_FALL;
@ -233,11 +242,11 @@ UINT8 P_GetMobjSprite2(mobj_t *mobj, UINT8 spr2)
spr2 = SPR2_FALL; spr2 = SPR2_FALL;
break; break;
case SPR2_FLY: case SPR2_FLY :
spr2 = SPR2_SPNG; spr2 = SPR2_SPNG;
break; break;
case SPR2_SWIM: case SPR2_SWIM:
spr2 = SPR2_FLY; spr2 = SPR2_FLY ;
break; break;
case SPR2_TIRE: case SPR2_TIRE:
spr2 = (player && player->charability == CA_SWIM) ? SPR2_SWIM : SPR2_FLY; spr2 = (player && player->charability == CA_SWIM) ? SPR2_SWIM : SPR2_FLY;
@ -247,91 +256,59 @@ UINT8 P_GetMobjSprite2(mobj_t *mobj, UINT8 spr2)
spr2 = SPR2_FLY; spr2 = SPR2_FLY;
break; break;
case SPR2_CLMB: case SPR2_CLMB:
spr2 = SPR2_SPIN; spr2 = SPR2_ROLL;
break; break;
case SPR2_CLNG: case SPR2_CLNG:
spr2 = SPR2_CLMB; spr2 = SPR2_CLMB;
break; break;
case SPR2_FLT :
spr2 = SPR2_WALK;
break;
case SPR2_FRUN:
spr2 = SPR2_RUN ;
break;
case SPR2_DASH:
spr2 = SPR2_FRUN;
break;
case SPR2_BNCE:
spr2 = SPR2_FALL;
break;
case SPR2_BLND:
spr2 = SPR2_ROLL;
break;
case SPR2_TWIN: case SPR2_TWIN:
spr2 = SPR2_SPIN; spr2 = SPR2_ROLL;
break; break;
case SPR2_MLEE: case SPR2_MLEE:
spr2 = SPR2_TWIN; spr2 = SPR2_TWIN;
break; break;
// Super sprites fallback to regular sprites
case SPR2_SWLK:
spr2 = SPR2_WALK;
break;
case SPR2_SRUN:
spr2 = SPR2_RUN;
break;
case SPR2_SPEE:
spr2 = SPR2_PEEL;
break;
case SPR2_SPAN:
spr2 = SPR2_PAIN;
break;
case SPR2_SSTN:
spr2 = SPR2_SPAN;
break;
case SPR2_SDTH:
spr2 = SPR2_DEAD;
break;
case SPR2_SDRN:
spr2 = SPR2_DRWN;
break;
case SPR2_SSPN:
spr2 = SPR2_SPIN;
break;
case SPR2_SGSP:
spr2 = SPR2_GASP;
break;
case SPR2_SJMP:
spr2 = ((player
? player->charflags
: skin->flags)
& SF_NOJUMPSPIN) ? SPR2_SSPG : SPR2_SSPN;
break;
case SPR2_SSPG:
spr2 = SPR2_SPNG;
break;
case SPR2_SFAL:
spr2 = SPR2_FALL;
break;
case SPR2_SEDG:
spr2 = SPR2_EDGE;
break;
case SPR2_SRID:
spr2 = SPR2_RIDE;
break;
case SPR2_SFLT:
spr2 = SPR2_SWLK;
break;
// NiGHTS sprites. // NiGHTS sprites.
case SPR2_NTRN:
spr2 = SPR2_TRNS;
break;
case SPR2_NSTD: case SPR2_NSTD:
spr2 = SPR2_SSTD; spr2 = SPR2_STND;
super = FF_SPR2SUPER;
break; break;
case SPR2_NFLT: case SPR2_NFLT:
spr2 = (skin->flags & SF_SUPERANIMS) ? SPR2_SFLT : SPR2_FALL; // This is skin-exclusive so the default NiGHTS skin changing system plays nice. spr2 = SPR2_FLT ;
super = FF_SPR2SUPER;
break;
case SPR2_NSTN:
spr2 = SPR2_STUN;
break; break;
case SPR2_NPUL: case SPR2_NPUL:
spr2 = SPR2_NFLT; spr2 = SPR2_NSTN;
break;
case SPR2_NPAN:
spr2 = SPR2_NPUL;
break; break;
case SPR2_NATK: case SPR2_NATK:
spr2 = SPR2_SSPN; spr2 = SPR2_ROLL;
super = FF_SPR2SUPER;
break; break;
/*case SPR2_NGT0: /*case SPR2_NGT0:
spr2 = SPR2_STND; spr2 = SPR2_NFLT;
break;*/ break;*/
case SPR2_NGT1: case SPR2_NGT1:
case SPR2_NGT7: case SPR2_NGT7:
@ -390,7 +367,10 @@ UINT8 P_GetMobjSprite2(mobj_t *mobj, UINT8 spr2)
spr2 = SPR2_STND; spr2 = SPR2_STND;
break; break;
} }
spr2 |= super;
} }
return spr2; return spr2;
} }
@ -427,45 +407,17 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state)
else if (state == S_PLAY_SWIM && !(player->mo->eflags & MFE_UNDERWATER)) else if (state == S_PLAY_SWIM && !(player->mo->eflags & MFE_UNDERWATER))
return P_SetPlayerMobjState(player->mo, S_PLAY_FLY); return P_SetPlayerMobjState(player->mo, S_PLAY_FLY);
// Catch state changes for Super Sonic // Catch SF_NOSUPERSPIN jumps for Supers
if (player->powers[pw_super] && (player->charflags & SF_SUPERANIMS)) if (player->powers[pw_super] && (player->charflags & SF_NOSUPERSPIN))
{ {
switch (state) if (state == S_PLAY_JUMP)
{ {
case S_PLAY_STND: if (player->mo->state-states == S_PLAY_WALK)
case S_PLAY_WAIT: return P_SetPlayerMobjState(mobj, S_PLAY_FLOAT);
return P_SetPlayerMobjState(mobj, S_PLAY_SUPER_STND); return true;
case S_PLAY_WALK:
return P_SetPlayerMobjState(mobj, S_PLAY_SUPER_WALK);
case S_PLAY_RUN:
return P_SetPlayerMobjState(mobj, S_PLAY_SUPER_RUN);
case S_PLAY_PEEL:
return P_SetPlayerMobjState(mobj, S_PLAY_SUPER_PEEL);
case S_PLAY_PAIN:
return P_SetPlayerMobjState(mobj, S_PLAY_SUPER_PAIN);
case S_PLAY_DEAD:
return P_SetPlayerMobjState(mobj, S_PLAY_SUPER_DEAD);
case S_PLAY_DRWN:
return P_SetPlayerMobjState(mobj, S_PLAY_SUPER_DRWN);
case S_PLAY_SPIN:
if (!(player->charflags & SF_SUPERSPIN))
return true;
return P_SetPlayerMobjState(mobj, S_PLAY_SUPER_SPIN);
case S_PLAY_GASP:
return P_SetPlayerMobjState(mobj, S_PLAY_SUPER_GASP);
case S_PLAY_JUMP:
if (!(player->charflags & SF_SUPERSPIN))
return true;
return P_SetPlayerMobjState(mobj, S_PLAY_SUPER_JUMP);
case S_PLAY_SPRING:
return P_SetPlayerMobjState(mobj, S_PLAY_SUPER_SPRING);
case S_PLAY_FALL:
return P_SetPlayerMobjState(mobj, S_PLAY_SUPER_FALL);
case S_PLAY_EDGE:
return P_SetPlayerMobjState(mobj, S_PLAY_SUPER_EDGE);
default:
break;
} }
else if (player->mo->state-states == S_PLAY_FLOAT && state == S_PLAY_STND)
return true;
} }
// You were in pain state after taking a hit, and you're moving out of pain state now? // You were in pain state after taking a hit, and you're moving out of pain state now?
else if (mobj->state == &states[mobj->info->painstate] && player->powers[pw_flashing] == flashingtics && state != mobj->info->painstate) else if (mobj->state == &states[mobj->info->painstate] && player->powers[pw_flashing] == flashingtics && state != mobj->info->painstate)
@ -481,61 +433,56 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state)
{ {
case S_PLAY_STND: case S_PLAY_STND:
case S_PLAY_WAIT: case S_PLAY_WAIT:
case S_PLAY_SUPER_STND:
player->panim = PA_IDLE; player->panim = PA_IDLE;
break; break;
case S_PLAY_EDGE: case S_PLAY_EDGE:
case S_PLAY_SUPER_EDGE:
player->panim = PA_EDGE; player->panim = PA_EDGE;
break; break;
case S_PLAY_WALK: case S_PLAY_WALK:
case S_PLAY_SUPER_WALK: case S_PLAY_FLOAT:
case S_PLAY_SUPER_FLOAT:
player->panim = PA_WALK; player->panim = PA_WALK;
break; break;
case S_PLAY_RUN: case S_PLAY_RUN:
case S_PLAY_SUPER_RUN: case S_PLAY_FLOAT_RUN:
player->panim = PA_RUN; player->panim = PA_RUN;
break; break;
case S_PLAY_PEEL: case S_PLAY_DASH:
case S_PLAY_SUPER_PEEL: player->panim = PA_DASH;
player->panim = PA_PEEL;
break; break;
case S_PLAY_PAIN: case S_PLAY_PAIN:
case S_PLAY_SUPER_PAIN: case S_PLAY_STUN:
case S_PLAY_SUPER_STUN:
player->panim = PA_PAIN; player->panim = PA_PAIN;
break; break;
case S_PLAY_SPIN: case S_PLAY_ROLL:
//case S_PLAY_DASH: -- everyone can ROLL thanks to zoom tubes... //case S_PLAY_SPINDASH: -- everyone can ROLL thanks to zoom tubes...
case S_PLAY_SUPER_SPIN:
player->panim = PA_ROLL; player->panim = PA_ROLL;
break; break;
case S_PLAY_JUMP: case S_PLAY_JUMP:
case S_PLAY_SUPER_JUMP:
player->panim = PA_JUMP; player->panim = PA_JUMP;
break; break;
case S_PLAY_SPRING: case S_PLAY_SPRING:
case S_PLAY_SUPER_SPRING:
player->panim = PA_SPRING; player->panim = PA_SPRING;
break; break;
case S_PLAY_FALL: case S_PLAY_FALL:
case S_PLAY_SUPER_FALL:
player->panim = PA_FALL; player->panim = PA_FALL;
break; break;
case S_PLAY_FLY: case S_PLAY_FLY:
case S_PLAY_SWIM: case S_PLAY_SWIM:
case S_PLAY_GLIDE: case S_PLAY_GLIDE:
case S_PLAY_BOUNCE:
case S_PLAY_BOUNCE_LANDING:
case S_PLAY_TWINSPIN: case S_PLAY_TWINSPIN:
player->panim = PA_ABILITY; player->panim = PA_ABILITY;
break; break;
case S_PLAY_DASH: // ...but the act of SPINDASHING is charability2 specific. case S_PLAY_SPINDASH: // ...but the act of SPINDASHING is charability2 specific.
case S_PLAY_FIRE:
case S_PLAY_FIRE_FINISH:
case S_PLAY_MELEE: case S_PLAY_MELEE:
case S_PLAY_MELEE_FINISH: case S_PLAY_MELEE_FINISH:
case S_PLAY_MELEE_LANDING:
player->panim = PA_ABILITY2; player->panim = PA_ABILITY2;
break; break;
case S_PLAY_RIDE: case S_PLAY_RIDE:
case S_PLAY_SUPER_RIDE:
player->panim = PA_RIDE; player->panim = PA_RIDE;
break; break;
default: default:
@ -562,7 +509,9 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state)
mobj->tics = st->tics; mobj->tics = st->tics;
// Adjust the player's animation speed to match their velocity. // Adjust the player's animation speed to match their velocity.
if (!(disableSpeedAdjust || player->charflags & SF_NOSPEEDADJUST)) if (player->panim == PA_EDGE && (player->charflags & SF_FASTEDGE))
mobj->tics = 2;
else if (!(disableSpeedAdjust || player->charflags & SF_NOSPEEDADJUST))
{ {
fixed_t speed;// = FixedDiv(player->speed, FixedMul(mobj->scale, player->mo->movefactor)); fixed_t speed;// = FixedDiv(player->speed, FixedMul(mobj->scale, player->mo->movefactor));
if (player->panim == PA_FALL) if (player->panim == PA_FALL)
@ -598,7 +547,7 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state)
else else
mobj->tics = 2; mobj->tics = 2;
} }
else if (P_IsObjectOnGround(mobj) || player->powers[pw_super]) // Only if on the ground or superflying. else if (P_IsObjectOnGround(mobj) || ((player->charability == CA_FLOAT || player->charability == CA_SLOWFALL) && player->secondjump == 1) || player->powers[pw_super]) // Only if on the ground or superflying.
{ {
if (player->panim == PA_WALK) if (player->panim == PA_WALK)
{ {
@ -609,7 +558,7 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state)
else else
mobj->tics = 4; mobj->tics = 4;
} }
else if ((player->panim == PA_RUN) || (player->panim == PA_PEEL)) else if ((player->panim == PA_RUN) || (player->panim == PA_DASH))
{ {
if (speed > 52<<FRACBITS) if (speed > 52<<FRACBITS)
mobj->tics = 1; mobj->tics = 1;
@ -627,7 +576,7 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state)
UINT16 frame = (mobj->frame & FF_FRAMEMASK)+1; UINT16 frame = (mobj->frame & FF_FRAMEMASK)+1;
UINT8 numframes; UINT8 numframes;
UINT8 spr2 = P_GetMobjSprite2(mobj, st->frame & FF_FRAMEMASK); UINT8 spr2 = P_GetMobjSprite2(mobj, (((player->powers[pw_super]) ? FF_SPR2SUPER : 0)|st->frame) & FF_FRAMEMASK);
if (skin) if (skin)
numframes = skin->sprites[spr2].numframes; numframes = skin->sprites[spr2].numframes;
@ -1646,11 +1595,8 @@ static void P_PlayerFlip(mobj_t *mo)
G_GhostAddFlip(); G_GhostAddFlip();
// Flip aiming to match! // Flip aiming to match!
if (mo->player->pflags & PF_NIGHTSMODE) // NiGHTS doesn't use flipcam if (mo->player->powers[pw_carry] == CR_NIGHTSMODE) // NiGHTS doesn't use flipcam
{ ;
if (mo->tracer)
mo->tracer->eflags ^= MFE_VERTICALFLIP;
}
else if (mo->player->pflags & PF_FLIPCAM) else if (mo->player->pflags & PF_FLIPCAM)
{ {
mo->player->aiming = InvAngle(mo->player->aiming); mo->player->aiming = InvAngle(mo->player->aiming);
@ -1746,7 +1692,7 @@ fixed_t P_GetMobjGravity(mobj_t *mo)
|| (mo->player->charability == CA_FLY && (mo->player->powers[pw_tailsfly] || (mo->player->charability == CA_FLY && (mo->player->powers[pw_tailsfly]
|| mo->state-states == S_PLAY_FLY_TIRED))) || mo->state-states == S_PLAY_FLY_TIRED)))
gravityadd = gravityadd/3; // less gravity while flying/gliding gravityadd = gravityadd/3; // less gravity while flying/gliding
if (mo->player->climbing || (mo->player->pflags & PF_NIGHTSMODE)) if (mo->player->climbing || (mo->player->powers[pw_carry] == CR_NIGHTSMODE))
gravityadd = 0; gravityadd = 0;
if (!(mo->flags2 & MF2_OBJECTFLIP) != !(mo->player->powers[pw_gravityboots])) // negated to turn numeric into bool - would be double negated, but not needed if both would be if (!(mo->flags2 & MF2_OBJECTFLIP) != !(mo->player->powers[pw_gravityboots])) // negated to turn numeric into bool - would be double negated, but not needed if both would be
@ -1898,9 +1844,12 @@ static void P_XYFriction(mobj_t *mo, fixed_t oldx, fixed_t oldy)
// spinning friction // spinning friction
if (player->pflags & PF_SPINNING && (player->rmomx || player->rmomy) && !(player->pflags & PF_STARTDASH)) if (player->pflags & PF_SPINNING && (player->rmomx || player->rmomy) && !(player->pflags & PF_STARTDASH))
{ {
const fixed_t ns = FixedDiv(549*ORIG_FRICTION,500*FRACUNIT); if (twodlevel || player->mo->flags2 & MF2_TWOD) // Otherwise handled in P_3DMovement
mo->momx = FixedMul(mo->momx, ns); {
mo->momy = FixedMul(mo->momy, ns); const fixed_t ns = FixedDiv(549*ORIG_FRICTION,500*FRACUNIT);
mo->momx = FixedMul(mo->momx, ns);
mo->momy = FixedMul(mo->momy, ns);
}
} }
else if (abs(player->rmomx) < FixedMul(STOPSPEED, mo->scale) else if (abs(player->rmomx) < FixedMul(STOPSPEED, mo->scale)
&& abs(player->rmomy) < FixedMul(STOPSPEED, mo->scale) && abs(player->rmomy) < FixedMul(STOPSPEED, mo->scale)
@ -2326,7 +2275,7 @@ void P_XYMovement(mobj_t *mo)
// Check the gravity status. // Check the gravity status.
P_CheckGravity(mo, false); P_CheckGravity(mo, false);
if (player && !moved && player->pflags & PF_NIGHTSMODE && mo->target) if (player && !moved && player->powers[pw_carry] == CR_NIGHTSMODE && mo->target)
{ {
angle_t fa; angle_t fa;
@ -2369,7 +2318,7 @@ void P_XYMovement(mobj_t *mo)
if (player && player->homing) // no friction for homing if (player && player->homing) // no friction for homing
return; return;
if (player && player->pflags & PF_NIGHTSMODE) if (player && player->powers[pw_carry] == CR_NIGHTSMODE)
return; // no friction for NiGHTS players return; // no friction for NiGHTS players
#ifdef ESLOPE #ifdef ESLOPE
@ -2592,6 +2541,9 @@ boolean P_CheckDeathPitCollide(mobj_t *mo)
I_Assert(mo != NULL); I_Assert(mo != NULL);
I_Assert(!P_MobjWasRemoved(mo)); I_Assert(!P_MobjWasRemoved(mo));
if (mo->player && mo->player->pflags & PF_GODMODE)
return false;
if (((mo->z <= mo->subsector->sector->floorheight if (((mo->z <= mo->subsector->sector->floorheight
&& !(mo->eflags & MFE_VERTICALFLIP) && (mo->subsector->sector->flags & SF_FLIPSPECIAL_FLOOR)) && !(mo->eflags & MFE_VERTICALFLIP) && (mo->subsector->sector->flags & SF_FLIPSPECIAL_FLOOR))
|| (mo->z + mo->height >= mo->subsector->sector->ceilingheight || (mo->z + mo->height >= mo->subsector->sector->ceilingheight
@ -3151,7 +3103,7 @@ static void P_PlayerZMovement(mobj_t *mo)
else else
mo->z = mo->floorz; mo->z = mo->floorz;
if (mo->player->pflags & PF_NIGHTSMODE) if (mo->player->powers[pw_carry] == CR_NIGHTSMODE)
{ {
// bounce off floor if you were flying towards it // bounce off floor if you were flying towards it
if ((mo->eflags & MFE_VERTICALFLIP && mo->player->flyangle > 0 && mo->player->flyangle < 180) if ((mo->eflags & MFE_VERTICALFLIP && mo->player->flyangle > 0 && mo->player->flyangle < 180)
@ -3259,60 +3211,69 @@ static void P_PlayerZMovement(mobj_t *mo)
// aren't pressing any controls. // aren't pressing any controls.
if (!(mo->player->cmd.forwardmove || mo->player->cmd.sidemove) && !mo->player->cmomx && !mo->player->cmomy && !(mo->player->pflags & PF_SPINNING)) if (!(mo->player->cmd.forwardmove || mo->player->cmd.sidemove) && !mo->player->cmomx && !mo->player->cmomy && !(mo->player->pflags & PF_SPINNING))
{ {
mo->momx = mo->momx/2; mo->momx >>= 1;
mo->momy = mo->momy/2; mo->momy >>= 1;
} }
} }
if (mo->health) if (mo->health && !P_CheckDeathPitCollide(mo))
{ {
if (mo->player->pflags & PF_GLIDING) // ground gliding if (mo->player->pflags & PF_GLIDING) // ground gliding
{ {
mo->player->skidtime = TICRATE; mo->player->skidtime = TICRATE;
mo->tics = -1; mo->tics = -1;
} }
else if (mo->player->charability2 == CA2_MELEE && mo->player->panim == PA_ABILITY2) else if (mo->player->charability2 == CA2_MELEE && (mo->player->panim == PA_ABILITY2 && mo->state-states != S_PLAY_MELEE_LANDING))
{ {
P_InstaThrust(mo, mo->angle, 0); P_SetPlayerMobjState(mo, S_PLAY_MELEE_LANDING);
P_SetPlayerMobjState(mo, S_PLAY_STND); 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|PF_USEDOWN)) != (PF_SPINNING|PF_USEDOWN) else if (mo->player->pflags & PF_JUMPED || (mo->player->pflags & (PF_SPINNING|PF_USEDOWN)) != (PF_SPINNING|PF_USEDOWN)
|| mo->player->powers[pw_tailsfly] || mo->state-states == S_PLAY_FLY_TIRED) || mo->player->powers[pw_tailsfly] || mo->state-states == S_PLAY_FLY_TIRED)
{ {
if (mo->player->cmomx || mo->player->cmomy) if (mo->player->cmomx || mo->player->cmomy)
{ {
if (mo->player->charability == CA_DASHMODE && mo->player->dashmode >= 3*TICRATE && mo->player->panim != PA_PEEL) if (mo->player->charflags & SF_DASHMODE && mo->player->dashmode >= 3*TICRATE && mo->player->panim != PA_DASH)
P_SetPlayerMobjState(mo, S_PLAY_PEEL); P_SetPlayerMobjState(mo, S_PLAY_DASH);
else if (mo->player->speed >= FixedMul(mo->player->runspeed, mo->scale) && mo->player->panim != PA_RUN) 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); P_SetPlayerMobjState(mo, S_PLAY_RUN);
else if ((mo->player->rmomx || mo->player->rmomy) && (mo->player->panim != PA_WALK || mo->state-states == S_PLAY_SUPER_FLOAT)) 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); P_SetPlayerMobjState(mo, S_PLAY_WALK);
else if (!mo->player->rmomx && !mo->player->rmomy && mo->player->panim != PA_IDLE) else if (!mo->player->rmomx && !mo->player->rmomy && mo->player->panim != PA_IDLE)
P_SetPlayerMobjState(mo, S_PLAY_STND); P_SetPlayerMobjState(mo, S_PLAY_STND);
} }
else else
{ {
if (mo->player->charability == CA_DASHMODE && mo->player->dashmode >= 3*TICRATE && mo->player->panim != PA_PEEL) if (mo->player->charflags & SF_DASHMODE && mo->player->dashmode >= 3*TICRATE && mo->player->panim != PA_DASH)
P_SetPlayerMobjState(mo, S_PLAY_PEEL); P_SetPlayerMobjState(mo, S_PLAY_DASH);
if (mo->player->speed >= FixedMul(mo->player->runspeed, mo->scale) && mo->player->panim != PA_RUN) 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); P_SetPlayerMobjState(mo, S_PLAY_RUN);
else if ((mo->momx || mo->momy) && (mo->player->panim != PA_WALK || mo->state-states == S_PLAY_SUPER_FLOAT)) else if ((mo->momx || mo->momy)
&& (mo->player->panim != PA_WALK || mo->state-states == S_PLAY_FLOAT))
P_SetPlayerMobjState(mo, S_PLAY_WALK); P_SetPlayerMobjState(mo, S_PLAY_WALK);
else if (!mo->momx && !mo->momy && mo->player->panim != PA_IDLE) else if (!mo->momx && !mo->momy && mo->player->panim != PA_IDLE)
P_SetPlayerMobjState(mo, S_PLAY_STND); P_SetPlayerMobjState(mo, S_PLAY_STND);
} }
} }
if (mo->player->pflags & PF_JUMPED) 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; {
else if (!(mo->player->pflags & PF_USEDOWN)) mo->player->pflags |= PF_SPINNING;
P_SetPlayerMobjState(mo, S_PLAY_ROLL);
S_StartSound(mo, sfx_spin);
}
else
mo->player->pflags &= ~PF_SPINNING; mo->player->pflags &= ~PF_SPINNING;
if (!(mo->player->pflags & PF_GLIDING)) if (!(mo->player->pflags & PF_GLIDING))
mo->player->pflags &= ~(PF_JUMPED|PF_FORCEJUMPDAMAGE); mo->player->pflags &= ~(PF_JUMPED|PF_NOJUMPDAMAGE);
mo->player->pflags &= ~(PF_THOKKED|PF_CANCARRY/*|PF_GLIDING*/); mo->player->pflags &= ~(PF_STARTJUMP|PF_THOKKED|PF_CANCARRY/*|PF_GLIDING*/);
mo->player->jumping = 0;
mo->player->secondjump = 0; mo->player->secondjump = 0;
mo->player->glidetime = 0; mo->player->glidetime = 0;
mo->player->climbing = 0; mo->player->climbing = 0;
@ -3346,6 +3307,16 @@ static void P_PlayerZMovement(mobj_t *mo)
clipmomz = false; 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))
@ -3394,7 +3365,7 @@ nightsdone:
else else
mo->z = mo->ceilingz - mo->height; mo->z = mo->ceilingz - mo->height;
if (mo->player->pflags & PF_NIGHTSMODE) if (mo->player->powers[pw_carry] == CR_NIGHTSMODE)
{ {
// bounce off ceiling if you were flying towards it // bounce off ceiling if you were flying towards it
if ((mo->eflags & MFE_VERTICALFLIP && mo->player->flyangle > 180 && mo->player->flyangle <= 359) if ((mo->eflags & MFE_VERTICALFLIP && mo->player->flyangle > 180 && mo->player->flyangle <= 359)
@ -3607,8 +3578,8 @@ static boolean P_SceneryZMovement(mobj_t *mo)
// //
boolean P_CanRunOnWater(player_t *player, ffloor_t *rover) boolean P_CanRunOnWater(player_t *player, ffloor_t *rover)
{ {
if (!(player->pflags & PF_NIGHTSMODE) && !player->homing if (!player->powers[pw_carry] && !player->homing
&& ((player->powers[pw_super] || player->charflags & SF_RUNONWATER) && player->mo->ceilingz-*rover->topheight >= player->mo->height) && ((player->powers[pw_super] || player->charflags & SF_RUNONWATER || player->dashmode >= 3*TICRATE) && player->mo->ceilingz-*rover->topheight >= player->mo->height)
&& (rover->flags & FF_SWIMMABLE) && !(player->pflags & PF_SPINNING) && player->speed > FixedMul(player->runspeed, player->mo->scale) && (rover->flags & FF_SWIMMABLE) && !(player->pflags & PF_SPINNING) && player->speed > FixedMul(player->runspeed, player->mo->scale)
&& !(player->pflags & PF_SLIDING) && !(player->pflags & PF_SLIDING)
&& abs(player->mo->z - *rover->topheight) < FixedMul(30*FRACUNIT, player->mo->scale)) && abs(player->mo->z - *rover->topheight) < FixedMul(30*FRACUNIT, player->mo->scale))
@ -4013,7 +3984,7 @@ void P_DestroyRobots(void)
continue; // not a mobj thinker continue; // not a mobj thinker
mo = (mobj_t *)think; mo = (mobj_t *)think;
if (mo->health <= 0 || !(mo->flags & MF_ENEMY || mo->flags & MF_BOSS)) if (mo->health <= 0 || !(mo->flags & (MF_ENEMY|MF_BOSS)))
continue; // not a valid enemy continue; // not a valid enemy
if (mo->type == MT_PLAYER) // Don't chase after other players! if (mo->type == MT_PLAYER) // Don't chase after other players!
@ -4036,7 +4007,7 @@ boolean P_CameraThinker(player_t *player, camera_t *thiscam, boolean resetcalled
|| (thiscam == &camera2 && players[secondarydisplayplayer].mo && (players[secondarydisplayplayer].mo->flags2 & MF2_TWOD))) || (thiscam == &camera2 && players[secondarydisplayplayer].mo && (players[secondarydisplayplayer].mo->flags2 & MF2_TWOD)))
itsatwodlevel = true; itsatwodlevel = true;
if (player->pflags & PF_FLIPCAM && !(player->pflags & PF_NIGHTSMODE) && player->mo->eflags & MFE_VERTICALFLIP) if (player->pflags & PF_FLIPCAM && !(player->powers[pw_carry] == CR_NIGHTSMODE) && player->mo->eflags & MFE_VERTICALFLIP)
postimg = postimg_flip; postimg = postimg_flip;
else if (player->awayviewtics) else if (player->awayviewtics)
{ {
@ -4169,6 +4140,9 @@ static void P_PlayerMobjThinker(mobj_t *mobj)
// momentum movement // momentum movement
mobj->eflags &= ~MFE_JUSTSTEPPEDDOWN; mobj->eflags &= ~MFE_JUSTSTEPPEDDOWN;
if (mobj->state-states == S_PLAY_BOUNCE_LANDING)
goto animonly; // no need for checkposition - doesn't move at ALL
// Zoom tube // Zoom tube
if (mobj->tracer) if (mobj->tracer)
{ {
@ -4289,9 +4263,9 @@ static void P_PlayerMobjThinker(mobj_t *mobj)
} }
else else
{ {
if (!(mobj->player->pflags & PF_NIGHTSMODE)) // "jumping" is used for drilling if (!(mobj->player->powers[pw_carry] == CR_NIGHTSMODE)) // used for drilling
mobj->player->jumping = 0; mobj->player->pflags &= ~PF_STARTJUMP;
mobj->player->pflags &= ~PF_JUMPED; mobj->player->pflags &= ~(PF_JUMPED|PF_NOJUMPDAMAGE);
if (mobj->player->secondjump || mobj->player->powers[pw_tailsfly]) if (mobj->player->secondjump || mobj->player->powers[pw_tailsfly])
{ {
mobj->player->secondjump = 0; mobj->player->secondjump = 0;
@ -5491,10 +5465,10 @@ static void P_Boss7Thinker(mobj_t *mobj)
if (players[i].mo->health <= 0) if (players[i].mo->health <= 0)
continue; continue;
if (players[i].powers[pw_ingoop]) if (players[i].powers[pw_carry] == CR_BRAKGOOP)
{ {
closestNum = -1; closestNum = -1;
closestdist = 16384*FRACUNIT; // Just in case... closestdist = INT32_MAX; // Just in case...
// Find waypoint he is closest to // Find waypoint he is closest to
for (th = thinkercap.next; th != &thinkercap; th = th->next) for (th = thinkercap.next; th != &thinkercap; th = th->next)
@ -6903,7 +6877,7 @@ void P_MobjThinker(mobj_t *mobj)
return; return;
if (/*(mobj->target) -- the following is implicit by P_AddShield if (/*(mobj->target) -- the following is implicit by P_AddShield
&& (mobj->target->player) && (mobj->target->player)
&& */ (mobj->target->player->homing)) && */ (mobj->target->player->homing) && (mobj->target->player->pflags & PF_SHIELDABILITY))
{ {
P_SetMobjState(mobj, mobj->info->painstate); P_SetMobjState(mobj, mobj->info->painstate);
mobj->tics++; mobj->tics++;
@ -7038,6 +7012,25 @@ void P_MobjThinker(mobj_t *mobj)
return; return;
} }
break; break;
case MT_LOCKON:
if (!mobj->target)
{
P_RemoveMobj(mobj);
return;
}
mobj->x = mobj->target->x;
mobj->y = mobj->target->y;
mobj->eflags |= (mobj->target->eflags & MFE_VERTICALFLIP);
mobj->destscale = mobj->target->destscale;
P_SetScale(mobj, mobj->target->scale);
if (!(mobj->eflags & MFE_VERTICALFLIP))
mobj->z = mobj->target->z + mobj->target->height + FixedMul((16 + abs((leveltime % TICRATE) - TICRATE/2))*FRACUNIT, mobj->target->scale);
else
mobj->z = mobj->target->z - FixedMul((16 + abs((leveltime % TICRATE) - TICRATE/2))*FRACUNIT, mobj->target->scale) - mobj->height;
break;
case MT_DROWNNUMBERS: case MT_DROWNNUMBERS:
if (!mobj->target) if (!mobj->target)
{ {
@ -7309,7 +7302,6 @@ void P_MobjThinker(mobj_t *mobj)
ns = 4 * FRACUNIT; ns = 4 * FRACUNIT;
mo2->momx = FixedMul(FINESINE(fa),ns); mo2->momx = FixedMul(FINESINE(fa),ns);
mo2->momy = FixedMul(FINECOSINE(fa),ns); mo2->momy = FixedMul(FINECOSINE(fa),ns);
mo2->angle = fa << ANGLETOFINESHIFT;
if (P_RandomChance(FRACUNIT/4)) // I filled a spreadsheet trying to get the equivalent chance to the original P_RandomByte hack! if (P_RandomChance(FRACUNIT/4)) // I filled a spreadsheet trying to get the equivalent chance to the original P_RandomByte hack!
S_StartSound(mo2, mobj->info->deathsound); S_StartSound(mo2, mobj->info->deathsound);
@ -7321,6 +7313,7 @@ void P_MobjThinker(mobj_t *mobj)
P_SetTarget(&flicky->target, mo2); P_SetTarget(&flicky->target, mo2);
flicky->momx = mo2->momx; flicky->momx = mo2->momx;
flicky->momy = mo2->momy; flicky->momy = mo2->momy;
flicky->angle = fa << ANGLETOFINESHIFT;
} }
mobj->fuse--; mobj->fuse--;
@ -7652,7 +7645,7 @@ void P_MobjThinker(mobj_t *mobj)
} }
else if (mobj->tracer && mobj->tracer->player) else if (mobj->tracer && mobj->tracer->player)
{ {
if (!(mobj->tracer->player->pflags & PF_NIGHTSMODE)) if (!(mobj->tracer->player->powers[pw_carry] == CR_NIGHTSMODE))
{ {
mobj->flags &= ~MF_NOGRAVITY; mobj->flags &= ~MF_NOGRAVITY;
mobj->flags2 &= ~MF2_DONTDRAW; mobj->flags2 &= ~MF2_DONTDRAW;
@ -7704,7 +7697,7 @@ void P_MobjThinker(mobj_t *mobj)
P_SetTarget(&mobj->target, NULL); P_SetTarget(&mobj->target, NULL);
} }
if (mobj->tracer->player->pflags & PF_NIGHTSMODE) if (mobj->tracer->player->powers[pw_carry] == CR_NIGHTSMODE)
{ {
if (mobj->tracer->player->bonustime) if (mobj->tracer->player->bonustime)
{ {

View file

@ -35,9 +35,11 @@
#pragma interface #pragma interface
#endif #endif
/// \brief Frame flags: only the frame number - 0 to 511 (Frames from 0 to 63, Sprite2 number uses full range) /// \brief Frame flags: only the frame number - 0 to 256 (Frames from 0 to 63, Sprite2 number uses 0 to 127 plus FF_SPR2SUPER)
#define FF_FRAMEMASK 0x1ff #define FF_FRAMEMASK 0xff
/// \brief Frame flags - SPR2: Super sprite2
#define FF_SPR2SUPER 0x80
/// \brief Frame flags - SPR2: A change of state at the end of Sprite2 animation /// \brief Frame flags - SPR2: A change of state at the end of Sprite2 animation
#define FF_SPR2ENDSTATE 0x1000 #define FF_SPR2ENDSTATE 0x1000
/// \brief Frame flags - SPR2: 50% of starting in middle of Sprite2 animation /// \brief Frame flags - SPR2: 50% of starting in middle of Sprite2 animation

View file

@ -152,7 +152,6 @@ static void P_NetArchivePlayers(void)
WRITESINT8(save_p, players[i].xtralife); WRITESINT8(save_p, players[i].xtralife);
WRITEUINT8(save_p, players[i].gotcontinue); WRITEUINT8(save_p, players[i].gotcontinue);
WRITEFIXED(save_p, players[i].speed); WRITEFIXED(save_p, players[i].speed);
WRITEUINT8(save_p, players[i].jumping);
WRITEUINT8(save_p, players[i].secondjump); WRITEUINT8(save_p, players[i].secondjump);
WRITEUINT8(save_p, players[i].fly1); WRITEUINT8(save_p, players[i].fly1);
WRITEUINT8(save_p, players[i].scoreadd); WRITEUINT8(save_p, players[i].scoreadd);
@ -332,7 +331,6 @@ static void P_NetUnArchivePlayers(void)
players[i].xtralife = READSINT8(save_p); // Ring Extra Life counter players[i].xtralife = READSINT8(save_p); // Ring Extra Life counter
players[i].gotcontinue = READUINT8(save_p); // got continue from stage players[i].gotcontinue = READUINT8(save_p); // got continue from stage
players[i].speed = READFIXED(save_p); // Player's speed (distance formula of MOMX and MOMY values) players[i].speed = READFIXED(save_p); // Player's speed (distance formula of MOMX and MOMY values)
players[i].jumping = READUINT8(save_p); // Jump counter
players[i].secondjump = READUINT8(save_p); players[i].secondjump = READUINT8(save_p);
players[i].fly1 = READUINT8(save_p); // Tails flying players[i].fly1 = READUINT8(save_p); // Tails flying
players[i].scoreadd = READUINT8(save_p); // Used for multiple enemy attack bonus players[i].scoreadd = READUINT8(save_p); // Used for multiple enemy attack bonus

View file

@ -2777,8 +2777,6 @@ boolean P_SetupLevel(boolean skipprecip)
for (i = 0; i < MAXPLAYERS; i++) for (i = 0; i < MAXPLAYERS; i++)
if (playeringame[i]) if (playeringame[i])
{ {
players[i].pflags &= ~PF_NIGHTSMODE;
// Start players with pity shields if possible // Start players with pity shields if possible
players[i].pity = -1; players[i].pity = -1;

View file

@ -3575,7 +3575,7 @@ void P_ProcessSpecialSector(player_t *player, sector_t *sector, sector_t *rovers
P_DamageMobj(player->mo, NULL, NULL, 1, 0); P_DamageMobj(player->mo, NULL, NULL, 1, 0);
break; break;
case 2: // Damage (Water) case 2: // Damage (Water)
if ((roversector || P_MobjReadyToTrigger(player->mo, sector)) && (player->powers[pw_underwater] || player->pflags & PF_NIGHTSMODE)) if ((roversector || P_MobjReadyToTrigger(player->mo, sector)) && (player->powers[pw_underwater] || player->powers[pw_carry] == CR_NIGHTSMODE))
P_DamageMobj(player->mo, NULL, NULL, 1, DMG_WATER); P_DamageMobj(player->mo, NULL, NULL, 1, DMG_WATER);
break; break;
case 3: // Damage (Fire) case 3: // Damage (Fire)
@ -3792,7 +3792,7 @@ DoneSection2:
if (!(player->pflags & PF_SPINNING)) if (!(player->pflags & PF_SPINNING))
player->pflags |= PF_SPINNING; player->pflags |= PF_SPINNING;
P_SetPlayerMobjState(player->mo, S_PLAY_SPIN); P_SetPlayerMobjState(player->mo, S_PLAY_ROLL);
} }
player->powers[pw_flashing] = TICRATE/3; player->powers[pw_flashing] = TICRATE/3;
@ -3953,7 +3953,7 @@ DoneSection2:
if (!(player->pflags & PF_SPINNING) && P_IsObjectOnGround(player->mo) && (player->charability2 == CA2_SPINDASH)) if (!(player->pflags & PF_SPINNING) && P_IsObjectOnGround(player->mo) && (player->charability2 == CA2_SPINDASH))
{ {
player->pflags |= PF_SPINNING; player->pflags |= PF_SPINNING;
P_SetPlayerMobjState(player->mo, S_PLAY_SPIN); P_SetPlayerMobjState(player->mo, S_PLAY_ROLL);
S_StartAttackSound(player->mo, sfx_spin); S_StartAttackSound(player->mo, sfx_spin);
if (abs(player->rmomx) < FixedMul(5*FRACUNIT, player->mo->scale) if (abs(player->rmomx) < FixedMul(5*FRACUNIT, player->mo->scale)
@ -4030,12 +4030,12 @@ 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_GLIDING|PF_SLIDING|PF_CANCARRY); player->pflags &= ~(PF_JUMPED|PF_NOJUMPDAMAGE|PF_GLIDING|PF_SLIDING|PF_CANCARRY);
player->climbing = 0; player->climbing = 0;
if (player->mo->state-states != S_PLAY_SPIN) if (player->mo->state-states != S_PLAY_ROLL)
{ {
P_SetPlayerMobjState(player->mo, S_PLAY_SPIN); P_SetPlayerMobjState(player->mo, S_PLAY_ROLL);
S_StartSound(player->mo, sfx_spin); S_StartSound(player->mo, sfx_spin);
} }
} }
@ -4110,12 +4110,12 @@ 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_GLIDING|PF_SLIDING|PF_CANCARRY); player->pflags &= ~(PF_JUMPED|PF_NOJUMPDAMAGE|PF_GLIDING|PF_SLIDING|PF_CANCARRY);
player->climbing = 0; player->climbing = 0;
if (player->mo->state-states != S_PLAY_SPIN) if (player->mo->state-states != S_PLAY_ROLL)
{ {
P_SetPlayerMobjState(player->mo, S_PLAY_SPIN); P_SetPlayerMobjState(player->mo, S_PLAY_ROLL);
S_StartSound(player->mo, sfx_spin); S_StartSound(player->mo, sfx_spin);
} }
} }
@ -4128,7 +4128,7 @@ DoneSection2:
{ {
player->laps++; player->laps++;
if (player->pflags & PF_NIGHTSMODE) if (player->powers[pw_carry] == CR_NIGHTSMODE)
player->drillmeter += 48*20; player->drillmeter += 48*20;
if (player->laps >= (UINT8)cv_numlaps.value) if (player->laps >= (UINT8)cv_numlaps.value)
@ -4418,7 +4418,7 @@ DoneSection2:
S_StartSound(player->mo, sfx_s3k4a); S_StartSound(player->mo, sfx_s3k4a);
player->pflags &= ~(PF_JUMPED|PF_GLIDING|PF_SLIDING|PF_CANCARRY); player->pflags &= ~(PF_JUMPED|PF_NOJUMPDAMAGE|PF_GLIDING|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);
@ -7301,7 +7301,7 @@ static inline boolean PIT_PushThing(mobj_t *thing)
return false; return false;
// Allow this to affect pushable objects at some point? // Allow this to affect pushable objects at some point?
if (thing->player && (!(thing->flags & (MF_NOGRAVITY | MF_NOCLIP)) || thing->player->pflags & PF_NIGHTSMODE)) if (thing->player && (!(thing->flags & (MF_NOGRAVITY | MF_NOCLIP)) || thing->player->powers[pw_carry] == CR_NIGHTSMODE))
{ {
INT32 dist; INT32 dist;
INT32 speed; INT32 speed;
@ -7332,7 +7332,7 @@ static inline boolean PIT_PushThing(mobj_t *thing)
// Written with bits and pieces of P_HomingAttack // Written with bits and pieces of P_HomingAttack
if ((speed > 0) && (P_CheckSight(thing, tmpusher->source))) if ((speed > 0) && (P_CheckSight(thing, tmpusher->source)))
{ {
if (!(thing->player->pflags & PF_NIGHTSMODE)) if (thing->player->powers[pw_carry] != CR_NIGHTSMODE)
{ {
// only push wrt Z if health & 1 (mapthing has ambush flag) // only push wrt Z if health & 1 (mapthing has ambush flag)
if (tmpusher->source->health & 1) if (tmpusher->source->health & 1)
@ -7661,11 +7661,11 @@ void T_Pusher(pusher_t *p)
{ {
if (p->slider && thing->player) if (p->slider && thing->player)
{ {
boolean jumped = (thing->player->pflags & PF_JUMPED); pflags_t jumped = (thing->player->pflags & (PF_JUMPED|PF_NOJUMPDAMAGE));
P_ResetPlayer (thing->player); P_ResetPlayer (thing->player);
if (jumped) if (jumped)
thing->player->pflags |= PF_JUMPED; thing->player->pflags |= jumped;
thing->player->pflags |= PF_SLIDING; thing->player->pflags |= PF_SLIDING;
P_SetPlayerMobjState (thing, thing->info->painstate); // Whee! P_SetPlayerMobjState (thing, thing->info->painstate); // Whee!

View file

@ -163,6 +163,7 @@ boolean P_Teleport(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z, angle_t angle
if (playeringame[p] && players[p].mo && players[p].powers[pw_carry] == CR_PLAYER && 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].powers[pw_carry] = CR_NONE; players[p].powers[pw_carry] = CR_NONE;
P_SetTarget(&players[p].mo->tracer, NULL);
break; break;
} }
thing->player->cmomx = thing->player->cmomy = 0; thing->player->cmomx = thing->player->cmomy = 0;

File diff suppressed because it is too large Load diff

View file

@ -194,10 +194,10 @@ const UINT8 Color_Opposite[MAXSKINCOLORS*2] =
SKINCOLOR_BROWN,8, // SKINCOLOR_PEACH - ditto SKINCOLOR_BROWN,8, // SKINCOLOR_PEACH - ditto
SKINCOLOR_PEACH,8, // SKINCOLOR_BROWN - ditto SKINCOLOR_PEACH,8, // SKINCOLOR_BROWN - ditto
SKINCOLOR_GREEN,5, // SKINCOLOR_RED SKINCOLOR_GREEN,5, // SKINCOLOR_RED
SKINCOLOR_CYAN,8, // SKINCOLOR_CRIMSON - ditto SKINCOLOR_CYAN,8, // SKINCOLOR_CRIMSON - ditto
SKINCOLOR_BLUE,12, // SKINCOLOR_ORANGE SKINCOLOR_BLUE,11, // SKINCOLOR_ORANGE
SKINCOLOR_TAN,8, // SKINCOLOR_RUST - ditto SKINCOLOR_TAN,8, // SKINCOLOR_RUST - ditto
SKINCOLOR_LAVENDER,8, // SKINCOLOR_GOLD - ditto SKINCOLOR_LAVENDER,8, // SKINCOLOR_GOLD
SKINCOLOR_TEAL,8, // SKINCOLOR_YELLOW - ditto SKINCOLOR_TEAL,8, // SKINCOLOR_YELLOW - ditto
SKINCOLOR_RUST,8, // SKINCOLOR_TAN - ditto SKINCOLOR_RUST,8, // SKINCOLOR_TAN - ditto
SKINCOLOR_MAGENTA,3, // SKINCOLOR_MOSS SKINCOLOR_MAGENTA,3, // SKINCOLOR_MOSS
@ -206,15 +206,15 @@ const UINT8 Color_Opposite[MAXSKINCOLORS*2] =
SKINCOLOR_PASTEL,8, // SKINCOLOR_EMERALD - ditto SKINCOLOR_PASTEL,8, // SKINCOLOR_EMERALD - ditto
SKINCOLOR_ROSY,8, // SKINCOLOR_AQUA - ditto SKINCOLOR_ROSY,8, // SKINCOLOR_AQUA - ditto
SKINCOLOR_YELLOW,8, // SKINCOLOR_TEAL - ditto SKINCOLOR_YELLOW,8, // SKINCOLOR_TEAL - ditto
SKINCOLOR_CRIMSON,8, // SKINCOLOR_CYAN - ditto SKINCOLOR_CRIMSON,8, // SKINCOLOR_CYAN - ditto
SKINCOLOR_ORANGE,9, // SKINCOLOR_BLUE SKINCOLOR_ORANGE,9, // SKINCOLOR_BLUE
SKINCOLOR_PINK,8, // SKINCOLOR_AZURE - ditto SKINCOLOR_PINK,8, // SKINCOLOR_AZURE - ditto
SKINCOLOR_EMERALD,8, // SKINCOLOR_PASTEL - ditto SKINCOLOR_EMERALD,8, // SKINCOLOR_PASTEL - ditto
SKINCOLOR_PERIDOT,10, // SKINCOLOR_PURPLE - ditto SKINCOLOR_PERIDOT,10, // SKINCOLOR_PURPLE
SKINCOLOR_GOLD,8, // SKINCOLOR_LAVENDER - ditto SKINCOLOR_GOLD,10, // SKINCOLOR_LAVENDER
SKINCOLOR_MOSS,8, // SKINCOLOR_MAGENTA - ditto SKINCOLOR_MOSS,8, // SKINCOLOR_MAGENTA - ditto
SKINCOLOR_AZURE,8, // SKINCOLOR_PINK - ditto SKINCOLOR_AZURE,8, // SKINCOLOR_PINK - ditto
SKINCOLOR_AQUA,14 // SKINCOLOR_ROSY - ditto SKINCOLOR_AQUA,14 // SKINCOLOR_ROSY
}; };
CV_PossibleValue_t Color_cons_t[MAXSKINCOLORS+1]; CV_PossibleValue_t Color_cons_t[MAXSKINCOLORS+1];

View file

@ -1000,7 +1000,7 @@ void R_SetupFrame(player_t *player, boolean skybox)
chasecam = (cv_chasecam.value != 0); chasecam = (cv_chasecam.value != 0);
} }
if (player->climbing || (player->pflags & PF_NIGHTSMODE) || player->playerstate == PST_DEAD) if (player->climbing || (player->powers[pw_carry] == CR_NIGHTSMODE) || player->playerstate == PST_DEAD)
chasecam = true; // force chasecam on chasecam = true; // force chasecam on
else if (player->spectator) // no spectator chasecam else if (player->spectator) // no spectator chasecam
chasecam = false; // force chasecam off chasecam = false; // force chasecam off

View file

@ -1182,7 +1182,7 @@ static void R_ProjectSprite(mobj_t *thing)
{ {
sprdef = &((skin_t *)thing->skin)->sprites[thing->sprite2]; sprdef = &((skin_t *)thing->skin)->sprites[thing->sprite2];
if (rot >= sprdef->numframes) { if (rot >= sprdef->numframes) {
CONS_Alert(CONS_ERROR, M_GetText("R_ProjectSprite: invalid skins[\"%s\"].sprites[SPR2_%s] frame %s\n"), ((skin_t *)thing->skin)->name, spr2names[thing->sprite2], sizeu5(rot)); CONS_Alert(CONS_ERROR, M_GetText("R_ProjectSprite: invalid skins[\"%s\"].sprites[%sSPR2_%s] frame %s\n"), ((skin_t *)thing->skin)->name, ((thing->sprite2 & FF_SPR2SUPER) ? "FF_SPR2SUPER|": ""), spr2names[(thing->sprite2 & ~FF_SPR2SUPER)], sizeu5(rot));
thing->sprite = states[S_UNKNOWN].sprite; thing->sprite = states[S_UNKNOWN].sprite;
thing->frame = states[S_UNKNOWN].frame; thing->frame = states[S_UNKNOWN].frame;
sprdef = &sprites[thing->sprite]; sprdef = &sprites[thing->sprite];
@ -2492,7 +2492,11 @@ static void Sk_SetDefaultValue(skin_t *skin)
skin->flags = 0; skin->flags = 0;
strcpy(skin->realname, "Someone"); strcpy(skin->realname, "Someone");
#ifdef SKINNAMEPADDING
strcpy(skin->hudname, " ???");
#else
strcpy(skin->hudname, "???"); strcpy(skin->hudname, "???");
#endif
strncpy(skin->charsel, "CHRSONIC", 8); strncpy(skin->charsel, "CHRSONIC", 8);
strncpy(skin->face, "MISSING", 8); strncpy(skin->face, "MISSING", 8);
strncpy(skin->superface, "MISSING", 8); strncpy(skin->superface, "MISSING", 8);
@ -2554,16 +2558,29 @@ void R_InitSkins(void)
numskins = 0; numskins = 0;
} }
UINT32 R_GetSkinAvailabilities(void)
{
INT32 s;
UINT32 response = 0;
for (s = 0; s < MAXSKINS; s++)
{
if (skins[s].availability && unlockables[skins[s].availability - 1].unlocked)
response |= (1 << s);
}
return response;
}
// returns true if available in circumstances, otherwise nope // returns true if available in circumstances, otherwise nope
// warning don't use with an invalid skinnum other than -1 which always returns true // warning don't use with an invalid skinnum other than -1 which always returns true
boolean R_SkinUnlock(INT32 skinnum) boolean R_SkinUsable(INT32 playernum, INT32 skinnum)
{ {
return ((skinnum == -1) // Simplifies things elsewhere, since there's already plenty of checks for less-than-0... return ((skinnum == -1) // Simplifies things elsewhere, since there's already plenty of checks for less-than-0...
|| (!skins[skinnum].availability) || (!skins[skinnum].availability)
|| (unlockables[skins[skinnum].availability - 1].unlocked) || ((playernum != -1) ? (players[playernum].availabilities & (1 << skinnum)) : (unlockables[skins[skinnum].availability - 1].unlocked))
|| (modeattacking) // If you have someone else's run you might as well take a look || (modeattacking) // If you have someone else's run you might as well take a look
|| (Playing() && (R_SkinAvailable(mapheaderinfo[gamemap-1]->forcecharacter) == skinnum)) // Force 1. || (Playing() && (R_SkinAvailable(mapheaderinfo[gamemap-1]->forcecharacter) == skinnum)) // Force 1.
|| (netgame && !(server || adminplayer == consoleplayer) && (cv_forceskin.value == skinnum)) // Force 2. || (netgame && (cv_forceskin.value == skinnum)) // Force 2.
); );
} }
@ -2588,7 +2605,7 @@ void SetPlayerSkin(INT32 playernum, const char *skinname)
INT32 i = R_SkinAvailable(skinname); INT32 i = R_SkinAvailable(skinname);
player_t *player = &players[playernum]; player_t *player = &players[playernum];
if ((i != -1) && (!P_IsLocalPlayer(player) || R_SkinUnlock(i))) if ((i != -1) && R_SkinUsable(playernum, i))
{ {
SetPlayerSkinByNum(playernum, i); SetPlayerSkinByNum(playernum, i);
return; return;
@ -2610,8 +2627,7 @@ void SetPlayerSkinByNum(INT32 playernum, INT32 skinnum)
skin_t *skin = &skins[skinnum]; skin_t *skin = &skins[skinnum];
UINT8 newcolor = 0; UINT8 newcolor = 0;
if ((skinnum >= 0 && skinnum < numskins) // Make sure it exists! if (skinnum >= 0 && skinnum < numskins && R_SkinUsable(playernum, skinnum)) // Make sure it exists!
&& (!P_IsLocalPlayer(player) || R_SkinUnlock(skinnum))) // ...but is it allowed? We must always allow external players to change skin. The server should vet that...
{ {
player->skin = skinnum; player->skin = skinnum;
@ -2653,7 +2669,7 @@ void SetPlayerSkinByNum(INT32 playernum, INT32 skinnum)
if (player->mo) if (player->mo)
{ {
if ((player->pflags & PF_NIGHTSMODE) && (skin->sprites[SPR2_NGT0].numframes == 0)) // If you don't have a sprite for flying horizontally, use the default NiGHTS skin. if ((player->powers[pw_carry] == CR_NIGHTSMODE) && (skin->sprites[SPR2_NGT0].numframes == 0)) // If you don't have a sprite for flying horizontally, use the default NiGHTS skin.
{ {
skin = &skins[DEFAULTNIGHTSSKIN]; skin = &skins[DEFAULTNIGHTSSKIN];
newcolor = ((skin->flags & SF_SUPER) ? skin->supercolor : skin->prefcolor); newcolor = ((skin->flags & SF_SUPER) ? skin->supercolor : skin->prefcolor);
@ -2663,16 +2679,16 @@ void SetPlayerSkinByNum(INT32 playernum, INT32 skinnum)
player->mo->color = newcolor; player->mo->color = newcolor;
P_SetScale(player->mo, player->mo->scale); P_SetScale(player->mo, player->mo->scale);
player->mo->radius = FixedMul(skin->radius, player->mo->scale); player->mo->radius = FixedMul(skin->radius, player->mo->scale);
P_SetPlayerMobjState(player->mo, player->mo->state-states); // Prevent visual errors when switching between skins with differing number of frames
} }
return; return;
} }
else if (skinnum >= 0 && skinnum < numskins)
skinnum = 255; // Cheeky emulation.
if (P_IsLocalPlayer(player)) if (P_IsLocalPlayer(player))
CONS_Alert(CONS_WARNING, M_GetText("Skin %d not found\n"), skinnum); CONS_Alert(CONS_WARNING, M_GetText("Requested skin not found\n"));
else if(server || adminplayer == consoleplayer) else if(server || adminplayer == consoleplayer)
CONS_Alert(CONS_WARNING, "Player %d (%s) skin %d not found\n", playernum, player_names[playernum], skinnum); CONS_Alert(CONS_WARNING, "Player %d (%s) skin not found\n", playernum, player_names[playernum]);
SetPlayerSkinByNum(playernum, 0); // not found put the sonic skin SetPlayerSkinByNum(playernum, 0); // not found put the sonic skin
} }
@ -2701,6 +2717,12 @@ static UINT16 W_CheckForSkinMarkerInPwad(UINT16 wadid, UINT16 startlump)
return INT16_MAX; // not found return INT16_MAX; // not found
} }
#ifdef SKINNAMEPADDING
#define HUDNAMEWRITE(value) snprintf(skin->hudname, sizeof(skin->hudname), "%5s", value)
#else
#define HUDNAMEWRITE(value) STRBUFCPY(skin->hudname, value)
#endif
// //
// Find skin sprites, sounds & optional status bar face, & add them // Find skin sprites, sounds & optional status bar face, & add them
// //
@ -2793,7 +2815,7 @@ void R_AddSkins(UINT16 wadnum)
} }
if (!hudname) if (!hudname)
{ {
STRBUFCPY(skin->hudname, skin->name); HUDNAMEWRITE(skin->name);
strupr(skin->hudname); strupr(skin->hudname);
for (value = skin->hudname; *value; value++) for (value = skin->hudname; *value; value++)
if (*value == '_') *value = ' '; // turn _ into spaces. if (*value == '_') *value = ' '; // turn _ into spaces.
@ -2806,12 +2828,12 @@ void R_AddSkins(UINT16 wadnum)
for (value = skin->realname; *value; value++) for (value = skin->realname; *value; value++)
if (*value == '_') *value = ' '; // turn _ into spaces. if (*value == '_') *value = ' '; // turn _ into spaces.
if (!hudname) if (!hudname)
STRBUFCPY(skin->hudname, skin->realname); HUDNAMEWRITE(skin->realname);
} }
else if (!stricmp(stoken, "hudname")) else if (!stricmp(stoken, "hudname"))
{ // Life icon name (eg. "K.T.E") { // Life icon name (eg. "K.T.E")
hudname = true; hudname = true;
STRBUFCPY(skin->hudname, value); HUDNAMEWRITE(value);
for (value = skin->hudname; *value; value++) for (value = skin->hudname; *value; value++)
if (*value == '_') *value = ' '; // turn _ into spaces. if (*value == '_') *value = ' '; // turn _ into spaces.
if (!realname) if (!realname)
@ -2905,8 +2927,8 @@ void R_AddSkins(UINT16 wadnum)
// these are uppercase so they can be concatenated with SF_ // these are uppercase so they can be concatenated with SF_
// 1, true, yes are all valid values // 1, true, yes are all valid values
GETFLAG(SUPER) GETFLAG(SUPER)
GETFLAG(SUPERANIMS) GETFLAG(NOSUPERSPIN)
GETFLAG(SUPERSPIN) GETFLAG(NOSPINDASHDUST)
GETFLAG(HIRES) GETFLAG(HIRES)
GETFLAG(NOSKID) GETFLAG(NOSKID)
GETFLAG(NOSPEEDADJUST) GETFLAG(NOSPEEDADJUST)
@ -2916,7 +2938,9 @@ void R_AddSkins(UINT16 wadnum)
GETFLAG(STOMPDAMAGE) GETFLAG(STOMPDAMAGE)
GETFLAG(MARIODAMAGE) GETFLAG(MARIODAMAGE)
GETFLAG(MACHINE) GETFLAG(MACHINE)
GETFLAG(NOSPINDASHDUST) GETFLAG(DASHMODE)
GETFLAG(FASTEDGE)
GETFLAG(MULTIABILITY)
#undef GETFLAG #undef GETFLAG
else // let's check if it's a sound, otherwise error out else // let's check if it's a sound, otherwise error out
@ -2962,20 +2986,35 @@ next_token:
// Add sprites // Add sprites
{ {
UINT16 z; UINT16 newlastlump;
UINT8 sprite2; UINT8 sprite2;
lump++; // start after S_SKIN lump++; // start after S_SKIN
lastlump = W_CheckNumForNamePwad("S_END",wadnum,lump); // stop at S_END lastlump = W_CheckNumForNamePwad("S_END",wadnum,lump); // stop at S_END
// old wadding practices die hard -- stop at S_SKIN or S_START if they come before S_END.
z = W_CheckNumForNamePwad("S_SKIN",wadnum,lump);
if (z < lastlump) lastlump = z;
z = W_CheckNumForNamePwad("S_START",wadnum,lump);
if (z < lastlump) lastlump = z;
// load all sprite sets we are aware of. // old wadding practices die hard -- stop at S_SKIN or S_START if they come before S_END.
newlastlump = W_CheckNumForNamePwad("S_SKIN",wadnum,lump);
if (newlastlump < lastlump) lastlump = newlastlump;
newlastlump = W_CheckNumForNamePwad("S_START",wadnum,lump);
if (newlastlump < lastlump) lastlump = newlastlump;
// ...and let's handle super, too
newlastlump = W_CheckNumForNamePwad("S_SUPER",wadnum,lump);
if (newlastlump < lastlump)
{
newlastlump++;
// load all sprite sets we are aware of... for super!
for (sprite2 = 0; sprite2 < free_spr2; sprite2++)
R_AddSingleSpriteDef(spr2names[sprite2], &skin->sprites[FF_SPR2SUPER|sprite2], wadnum, newlastlump, lastlump);
newlastlump--;
lastlump = newlastlump; // okay, make the normal sprite set loading end there
}
// load all sprite sets we are aware of... for normal stuff.
for (sprite2 = 0; sprite2 < free_spr2; sprite2++) for (sprite2 = 0; sprite2 < free_spr2; sprite2++)
R_AddSingleSpriteDef(spr2names[sprite2], &skin->sprites[sprite2], wadnum, lump, lastlump); R_AddSingleSpriteDef(spr2names[sprite2], &skin->sprites[sprite2], wadnum, lump, lastlump);
} }
R_FlushTranslationColormapCache(); R_FlushTranslationColormapCache();
@ -3000,6 +3039,8 @@ next_token:
return; return;
} }
#undef HUDNAMEWRITE
#ifdef DELFILE #ifdef DELFILE
void R_DelSkins(UINT16 wadnum) void R_DelSkins(UINT16 wadnum)
{ {

View file

@ -29,8 +29,6 @@
#define VISSPRITESPERCHUNK (1 << VISSPRITECHUNKBITS) #define VISSPRITESPERCHUNK (1 << VISSPRITECHUNKBITS)
#define VISSPRITEINDEXMASK (VISSPRITESPERCHUNK - 1) #define VISSPRITEINDEXMASK (VISSPRITESPERCHUNK - 1)
#define DEFAULTNIGHTSSKIN 0
// Constant arrays used for psprite clipping // Constant arrays used for psprite clipping
// and initializing clipping. // and initializing clipping.
extern INT16 negonearray[MAXVIDWIDTH]; extern INT16 negonearray[MAXVIDWIDTH];
@ -71,6 +69,7 @@ void R_DrawMasked(void);
// should be all lowercase!! S_SKIN processing does a strlwr // should be all lowercase!! S_SKIN processing does a strlwr
#define DEFAULTSKIN "sonic" #define DEFAULTSKIN "sonic"
#define DEFAULTSKIN2 "tails" // secondary player #define DEFAULTSKIN2 "tails" // secondary player
#define DEFAULTNIGHTSSKIN 0
typedef struct typedef struct
{ {
@ -118,7 +117,7 @@ typedef struct
// specific sounds per skin // specific sounds per skin
sfxenum_t soundsid[NUMSKINSOUNDS]; // sound # in S_sfx table sfxenum_t soundsid[NUMSKINSOUNDS]; // sound # in S_sfx table
spritedef_t sprites[NUMPLAYERSPRITES]; spritedef_t sprites[NUMPLAYERSPRITES*2]; // contains super versions too
UINT8 availability; // lock? UINT8 availability; // lock?
} skin_t; } skin_t;
@ -204,7 +203,8 @@ extern skin_t skins[MAXSKINS + 1];
void SetPlayerSkin(INT32 playernum,const char *skinname); void SetPlayerSkin(INT32 playernum,const char *skinname);
void SetPlayerSkinByNum(INT32 playernum,INT32 skinnum); // Tails 03-16-2002 void SetPlayerSkinByNum(INT32 playernum,INT32 skinnum); // Tails 03-16-2002
boolean R_SkinUnlock(INT32 skinnum); boolean R_SkinUsable(INT32 playernum, INT32 skinnum);
UINT32 R_GetSkinAvailabilities(void);
INT32 R_SkinAvailable(const char *name); INT32 R_SkinAvailable(const char *name);
void R_AddSkins(UINT16 wadnum); void R_AddSkins(UINT16 wadnum);

View file

@ -611,6 +611,7 @@ void S_StartSound(const void *origin, sfxenum_t sfx_id)
case sfx_forcsg: case sfx_forcsg:
case sfx_elemsg: case sfx_elemsg:
case sfx_armasg: case sfx_armasg:
case sfx_attrsg:
case sfx_s3k3e: case sfx_s3k3e:
case sfx_s3k3f: case sfx_s3k3f:
case sfx_s3k41: case sfx_s3k41:

View file

@ -170,6 +170,7 @@ sfxinfo_t S_sfx[NUMSFX] =
{"forcsg", false, 60, 0, -1, NULL, 0, -1, -1, LUMPERROR}, // Force GET! {"forcsg", false, 60, 0, -1, NULL, 0, -1, -1, LUMPERROR}, // Force GET!
{"elemsg", false, 60, 0, -1, NULL, 0, -1, -1, LUMPERROR}, // Elemental GET! {"elemsg", false, 60, 0, -1, NULL, 0, -1, -1, LUMPERROR}, // Elemental GET!
{"armasg", false, 60, 0, -1, NULL, 0, -1, -1, LUMPERROR}, // Armaggeddon GET! {"armasg", false, 60, 0, -1, NULL, 0, -1, -1, LUMPERROR}, // Armaggeddon GET!
{"attrsg", false, 60, 0, -1, NULL, 0, -1, -1, LUMPERROR}, // Attract GET!
{"shldls", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, // You LOSE! {"shldls", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, // You LOSE!
{"spdpad", false, 127, 0, -1, NULL, 0, -1, -1, LUMPERROR}, {"spdpad", false, 127, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"spkdth", false, 127, 0, -1, NULL, 0, -1, -1, LUMPERROR}, {"spkdth", false, 127, 0, -1, NULL, 0, -1, -1, LUMPERROR},
@ -188,6 +189,8 @@ sfxinfo_t S_sfx[NUMSFX] =
{"mswarp", false, 60, 16, -1, NULL, 0, -1, -1, LUMPERROR}, {"mswarp", false, 60, 16, -1, NULL, 0, -1, -1, LUMPERROR},
{"mspogo", false, 60, 8, -1, NULL, 0, -1, -1, LUMPERROR}, {"mspogo", false, 60, 8, -1, NULL, 0, -1, -1, LUMPERROR},
{"boingf", false, 60, 0, -1, NULL, 0, -1, -1, LUMPERROR}, {"boingf", false, 60, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"corkp", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"corkh", false, 32, 0, -1, NULL, 0, -1, -1, LUMPERROR},
// Menu, interface // Menu, interface
{"chchng", false, 120, 0, -1, NULL, 0, -1, -1, LUMPERROR}, {"chchng", false, 120, 0, -1, NULL, 0, -1, -1, LUMPERROR},

View file

@ -233,6 +233,7 @@ typedef enum
sfx_forcsg, sfx_forcsg,
sfx_elemsg, sfx_elemsg,
sfx_armasg, sfx_armasg,
sfx_attrsg,
sfx_shldls, sfx_shldls,
sfx_spdpad, sfx_spdpad,
sfx_spkdth, sfx_spkdth,
@ -251,6 +252,8 @@ typedef enum
sfx_mswarp, sfx_mswarp,
sfx_mspogo, sfx_mspogo,
sfx_boingf, sfx_boingf,
sfx_corkp,
sfx_corkh,
// Menu, interface // Menu, interface
sfx_chchng, sfx_chchng,

View file

@ -581,16 +581,16 @@ static void ST_drawDebugInfo(void)
{ {
V_DrawRightAlignedString(320, height - 104, V_MONOSPACE, va("SHIELD: %5x", stplyr->powers[pw_shield])); V_DrawRightAlignedString(320, height - 104, V_MONOSPACE, va("SHIELD: %5x", stplyr->powers[pw_shield]));
V_DrawRightAlignedString(320, height - 96, V_MONOSPACE, va("SCALE: %5d%%", (stplyr->mo->scale*100)/FRACUNIT)); V_DrawRightAlignedString(320, height - 96, V_MONOSPACE, va("SCALE: %5d%%", (stplyr->mo->scale*100)/FRACUNIT));
V_DrawRightAlignedString(320, height - 88, V_MONOSPACE, va("DASH: %3d/%3d", stplyr->dashspeed>>FRACBITS, stplyr->maxdash>>FRACBITS)); V_DrawRightAlignedString(320, height - 88, V_MONOSPACE, va("CARRY: %5x", stplyr->powers[pw_carry]));
V_DrawRightAlignedString(320, height - 80, V_MONOSPACE, va("AIR: %4d, %3d", stplyr->powers[pw_underwater], stplyr->powers[pw_spacetime])); V_DrawRightAlignedString(320, height - 80, V_MONOSPACE, va("AIR: %4d, %3d", stplyr->powers[pw_underwater], stplyr->powers[pw_spacetime]));
// Flags // Flags
V_DrawRightAlignedString(304-92, height - 72, V_MONOSPACE, "PF:"); V_DrawRightAlignedString(304-92, height - 72, V_MONOSPACE, "PF:");
V_DrawString(304-90, height - 72, (stplyr->jumping) ? V_GREENMAP : V_REDMAP, "JM"); V_DrawString(304-90, height - 72, (stplyr->pflags & PF_STARTJUMP) ? V_GREENMAP : V_REDMAP, "SJ");
V_DrawString(304-72, height - 72, (stplyr->pflags & PF_JUMPED) ? V_GREENMAP : V_REDMAP, "JD"); V_DrawString(304-72, height - 72, (stplyr->pflags & PF_JUMPED) ? V_GREENMAP : V_REDMAP, "JD");
V_DrawString(304-54, height - 72, (stplyr->pflags & PF_SPINNING) ? V_GREENMAP : V_REDMAP, "SP"); V_DrawString(304-54, height - 72, (stplyr->pflags & PF_SPINNING) ? V_GREENMAP : V_REDMAP, "SP");
V_DrawString(304-36, height - 72, (stplyr->pflags & PF_STARTDASH) ? V_GREENMAP : V_REDMAP, "ST"); V_DrawString(304-36, height - 72, (stplyr->pflags & PF_STARTDASH) ? V_GREENMAP : V_REDMAP, "ST");
V_DrawString(304-18, height - 72, (stplyr->pflags & PF_THOKKED) ? V_GREENMAP : V_REDMAP, "TH"); V_DrawString(304-18, height - 72, (stplyr->pflags & PF_THOKKED) ? V_GREENMAP : V_REDMAP, "TH");
V_DrawString(304, height - 72, (stplyr->pflags & PF_SHIELDABILITY) ? V_GREENMAP : V_REDMAP, "SH"); V_DrawString(304, height - 72, (stplyr->pflags & PF_SHIELDABILITY) ? V_GREENMAP : V_REDMAP, "SH");
V_DrawRightAlignedString(320, height - 64, V_MONOSPACE, va("CEILZ: %6d", stplyr->mo->ceilingz>>FRACBITS)); V_DrawRightAlignedString(320, height - 64, V_MONOSPACE, va("CEILZ: %6d", stplyr->mo->ceilingz>>FRACBITS));
@ -717,7 +717,7 @@ static void ST_drawLives(void)
// skincolor face/super // skincolor face/super
UINT8 *colormap = R_GetTranslationColormap(stplyr->skin, stplyr->mo->color, GTC_CACHE); UINT8 *colormap = R_GetTranslationColormap(stplyr->skin, stplyr->mo->color, GTC_CACHE);
patch_t *face = faceprefix[stplyr->skin]; patch_t *face = faceprefix[stplyr->skin];
if (stplyr->powers[pw_super] || stplyr->pflags & PF_NIGHTSMODE) if ((stplyr->powers[pw_super] && (stplyr->mo->state < &states[S_PLAY_SUPER_TRANS] || stplyr->mo->state > &states[S_PLAY_SUPER_TRANS9])) || (stplyr->powers[pw_carry] == CR_NIGHTSMODE && skins[stplyr->skin].flags & SF_SUPER))
face = superprefix[stplyr->skin]; face = superprefix[stplyr->skin];
V_DrawSmallMappedPatch(hudinfo[HUD_LIVESPIC].x, hudinfo[HUD_LIVESPIC].y + (v_splitflag ? -12 : 0), V_DrawSmallMappedPatch(hudinfo[HUD_LIVESPIC].x, hudinfo[HUD_LIVESPIC].y + (v_splitflag ? -12 : 0),
V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_HUDTRANS|v_splitflag,face, colormap); V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_HUDTRANS|v_splitflag,face, colormap);
@ -1080,7 +1080,7 @@ static void ST_drawNiGHTSHUD(void)
#ifdef HAVE_BLUA #ifdef HAVE_BLUA
LUA_HudEnabled(hud_nightsdrill) && LUA_HudEnabled(hud_nightsdrill) &&
#endif #endif
stplyr->pflags & PF_NIGHTSMODE) stplyr->powers[pw_carry] == CR_NIGHTSMODE)
{ {
INT32 locx, locy; INT32 locx, locy;
INT32 dfill; INT32 dfill;
@ -1166,7 +1166,7 @@ static void ST_drawNiGHTSHUD(void)
INT32 i; INT32 i;
total_ringcount = 0; total_ringcount = 0;
for (i = 0; i < MAXPLAYERS; i++) for (i = 0; i < MAXPLAYERS; i++)
if (playeringame[i] /*&& players[i].pflags & PF_NIGHTSMODE*/ && players[i].rings) if (playeringame[i] /*&& players[i].powers[pw_carry] == CR_NIGHTSMODE*/ && players[i].rings)
total_ringcount += players[i].rings; total_ringcount += players[i].rings;
} }
else else
@ -1299,7 +1299,7 @@ static void ST_drawNiGHTSHUD(void)
tic_t lowest_time = stplyr->nightstime; tic_t lowest_time = stplyr->nightstime;
INT32 i; INT32 i;
for (i = 0; i < MAXPLAYERS; i++) for (i = 0; i < MAXPLAYERS; i++)
if (playeringame[i] && players[i].pflags & PF_NIGHTSMODE && players[i].nightstime < lowest_time) if (playeringame[i] && players[i].powers[pw_carry] == CR_NIGHTSMODE && players[i].nightstime < lowest_time)
lowest_time = players[i].nightstime; lowest_time = players[i].nightstime;
realnightstime = lowest_time/TICRATE; realnightstime = lowest_time/TICRATE;
} }
@ -1486,14 +1486,30 @@ static void ST_drawMatchHUD(void)
static inline void ST_drawRaceHUD(void) static inline void ST_drawRaceHUD(void)
{ {
if (leveltime > TICRATE && leveltime <= 2*TICRATE) if (leveltime >= TICRATE && leveltime < 5*TICRATE)
V_DrawScaledPatch(SCX((BASEVIDWIDTH - SHORT(race3->width))/2), (INT32)(SCY(BASEVIDHEIGHT/2)), V_NOSCALESTART, race3); {
else if (leveltime > 2*TICRATE && leveltime <= 3*TICRATE) INT32 height = (BASEVIDHEIGHT/2);
V_DrawScaledPatch(SCX((BASEVIDWIDTH - SHORT(race2->width))/2), (INT32)(SCY(BASEVIDHEIGHT/2)), V_NOSCALESTART, race2); INT32 bounce = (leveltime % TICRATE);
else if (leveltime > 3*TICRATE && leveltime <= 4*TICRATE) patch_t *racenum;
V_DrawScaledPatch(SCX((BASEVIDWIDTH - SHORT(race1->width))/2), (INT32)(SCY(BASEVIDHEIGHT/2)), V_NOSCALESTART, race1); switch (leveltime/TICRATE)
else if (leveltime > 4*TICRATE && leveltime <= 5*TICRATE) {
V_DrawScaledPatch(SCX((BASEVIDWIDTH - SHORT(racego->width))/2), (INT32)(SCY(BASEVIDHEIGHT/2)), V_NOSCALESTART, racego); case 1:
racenum = race3;
break;
case 2:
racenum = race2;
break;
case 3:
racenum = race1;
break;
default:
racenum = racego;
break;
}
if (bounce < 3)
height -= (2 - bounce);
V_DrawScaledPatch(SCX((BASEVIDWIDTH - SHORT(racenum->width))/2), (INT32)(SCY(height)), V_NOSCALESTART, racenum);
}
if (circuitmap) if (circuitmap)
{ {