MONSTER COMMIT.

OLD SPECIAL STAGES:
* Spheres in old special stages instead of rings!
* Individual timers in old special stages instead of a global one!
* Old special stages use a variant of the NiGHTS HUD now!
* Special stage damage in old special stages loses 5 seconds of time instead of 10 rings/spheres!
* All damage gained through old special stages is converted to special stage damage! As a consequence, the special spikeball has no need to be special anymore.
* Made emerald gaining function be based on special stage number rather than gained emeralds!
* Consistency with...

NiGHTS SPECIAL STAGES:
* Spheres now flash in bonus time. https://cdn.discordapp.com/attachments/400761370800422922/452590553100713984/srb20032.gif
* Sphere and ring mapthingnums are now less fucked up in 'em. (Rings are 300, same as usual, while Spheres are now 1706 replacing NiGHTS Wings.)

SPECIAL STAGES IN GENERAL:
* useNightsSS is now dead. Each individual special stage is now assessed for NiGHTS-mode behaviour based on maptol & TOL_NIGHTS.
* CRAWLA HONCHO\n CAN NOW BE\n SUPER CRAWLA HONCHO end tally modification now also includes a mini-tutorial on turning super. https://cdn.discordapp.com/attachments/400761370800422922/452844894113759233/srb20036.gif
* SONIC GOT A CHAOS EMERALD? https://cdn.discordapp.com/attachments/400761370800422922/452623869497573386/srb20034.gif

NiGHTS NON-SPECIAL STAGES:
* Colour Chips and Star Chips! Replaces Spheres and Rings of NiGHTS Special Stages.
* Colour Chips turn yellow in bonus time.
* Ideya!
* Its own "drowning" music!
* All of the object types for Dream Hill.
* GIF: https://cdn.discordapp.com/attachments/400761370800422922/452844894113759233/srb20036.gif

RANDOM BS:
* Turn super with the spin button instead of the jump button!
* Followmobj now correctly set with P_SetTarget instead of pointer assignment.
* Emerald hunt uses new sprites!
* Made unlock noise different from emblem gain noise! (It's the CRAWLA HONCHO CAN NOW TURN yadda yadda sound from S3K now.)
This commit is contained in:
toaster 2018-06-03 22:41:54 +01:00
parent 8d00192fee
commit 6e07631cc9
33 changed files with 1006 additions and 671 deletions

View File

@ -513,7 +513,8 @@ static inline void resynch_write_player(resynch_pak *rsp, const size_t i)
rsp->powers[j] = (UINT16)SHORT(players[i].powers[j]); rsp->powers[j] = (UINT16)SHORT(players[i].powers[j]);
// Score is resynched in the rspfirm resync packet // Score is resynched in the rspfirm resync packet
rsp->rings = LONG(players[i].rings); rsp->rings = SHORT(players[i].rings);
rsp->spheres = SHORT(players[i].spheres);
rsp->lives = players[i].lives; rsp->lives = players[i].lives;
rsp->continues = players[i].continues; rsp->continues = players[i].continues;
rsp->scoreadd = players[i].scoreadd; rsp->scoreadd = players[i].scoreadd;
@ -643,7 +644,8 @@ static void resynch_read_player(resynch_pak *rsp)
players[i].powers[j] = (UINT16)SHORT(rsp->powers[j]); players[i].powers[j] = (UINT16)SHORT(rsp->powers[j]);
// Score is resynched in the rspfirm resync packet // Score is resynched in the rspfirm resync packet
players[i].rings = LONG(rsp->rings); players[i].rings = SHORT(rsp->rings);
players[i].spheres = SHORT(rsp->spheres);
players[i].lives = rsp->lives; players[i].lives = rsp->lives;
players[i].continues = rsp->continues; players[i].continues = rsp->continues;
players[i].scoreadd = rsp->scoreadd; players[i].scoreadd = rsp->scoreadd;
@ -2377,11 +2379,11 @@ static void CL_RemovePlayer(INT32 playernum)
if (gametype == GT_CTF) if (gametype == GT_CTF)
P_PlayerFlagBurst(&players[playernum], false); // Don't take the flag with you! P_PlayerFlagBurst(&players[playernum], false); // Don't take the flag with you!
// If in a special stage, redistribute the player's rings across // If in a special stage, redistribute the player's spheres across
// the remaining players. // the remaining players.
if (G_IsSpecialStage(gamemap)) if (G_IsSpecialStage(gamemap))
{ {
INT32 i, count, increment, rings; INT32 i, count, increment, spheres;
for (i = 0, count = 0; i < MAXPLAYERS; i++) for (i = 0, count = 0; i < MAXPLAYERS; i++)
{ {
@ -2390,19 +2392,19 @@ static void CL_RemovePlayer(INT32 playernum)
} }
count--; count--;
rings = players[playernum].rings; spheres = players[playernum].spheres;
increment = rings/count; increment = spheres/count;
for (i = 0; i < MAXPLAYERS; i++) for (i = 0; i < MAXPLAYERS; i++)
{ {
if (playeringame[i] && i != playernum) if (playeringame[i] && i != playernum)
{ {
if (rings < increment) if (spheres < increment)
P_GivePlayerRings(&players[i], rings); P_GivePlayerSpheres(&players[i], spheres);
else else
P_GivePlayerRings(&players[i], increment); P_GivePlayerSpheres(&players[i], increment);
rings -= increment; spheres -= increment;
} }
} }
} }

View File

@ -164,7 +164,8 @@ typedef struct
UINT16 powers[NUMPOWERS]; UINT16 powers[NUMPOWERS];
// Score is resynched in the confirm resync packet // Score is resynched in the confirm resync packet
INT32 rings; INT16 rings;
INT16 spheres;
SINT8 lives; SINT8 lives;
SINT8 continues; SINT8 continues;
UINT8 scoreadd; UINT8 scoreadd;

View File

@ -309,8 +309,8 @@ consvar_t cv_overtime = {"overtime", "Yes", CV_NETVAR, CV_YesNo, NULL, 0, NULL,
consvar_t cv_rollingdemos = {"rollingdemos", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_rollingdemos = {"rollingdemos", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
static CV_PossibleValue_t timetic_cons_t[] = {{0, "Normal"}, {1, "Centiseconds"}, {2, "Mania"}, {3, "Tics"}, {0, NULL}}; static CV_PossibleValue_t timetic_cons_t[] = {{0, "Classic"}, {1, "Centiseconds"}, {2, "Mania"}, {3, "Tics"}, {0, NULL}};
consvar_t cv_timetic = {"timerres", "Normal", CV_SAVE, timetic_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; // use tics in display consvar_t cv_timetic = {"timerres", "Classic", CV_SAVE, timetic_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
static CV_PossibleValue_t powerupdisplay_cons_t[] = {{0, "Never"}, {1, "First-person only"}, {2, "Always"}, {0, NULL}}; static CV_PossibleValue_t powerupdisplay_cons_t[] = {{0, "Never"}, {1, "First-person only"}, {2, "Always"}, {0, NULL}};
consvar_t cv_powerupdisplay = {"powerupdisplay", "First-person only", CV_SAVE, powerupdisplay_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_powerupdisplay = {"powerupdisplay", "First-person only", CV_SAVE, powerupdisplay_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
@ -2682,8 +2682,7 @@ static void Got_Teamchange(UINT8 **cp, INT32 playernum)
// Clear player score and rings if a spectator. // Clear player score and rings if a spectator.
if (players[playernum].spectator) if (players[playernum].spectator)
{ {
players[playernum].score = 0; players[playernum].score = players[playernum].rings = 0;
players[playernum].rings = 0;
if (players[playernum].mo) if (players[playernum].mo)
players[playernum].mo->health = 1; players[playernum].mo->health = 1;
} }

View File

@ -324,7 +324,8 @@ typedef struct player_s
angle_t drawangle; angle_t drawangle;
// player's ring count // player's ring count
INT32 rings; INT16 rings;
INT16 spheres;
SINT8 pity; // i pity the fool. SINT8 pity; // i pity the fool.
INT32 currentweapon; // current weapon selected. INT32 currentweapon; // current weapon selected.
@ -460,7 +461,7 @@ typedef struct player_s
tic_t marebegunat; // Leveltime when mare begun tic_t marebegunat; // Leveltime when mare begun
tic_t startedtime; // Time which you started this mare with. tic_t startedtime; // Time which you started this mare with.
tic_t finishedtime; // Time it took you to finish the mare (used for display) tic_t finishedtime; // Time it took you to finish the mare (used for display)
INT16 finishedrings; // The rings you had left upon finishing the mare INT16 finishedspheres; // The spheres you had left upon finishing the mare
UINT32 marescore; // score for this nights stage UINT32 marescore; // score for this nights stage
UINT32 lastmarescore; // score for the last mare UINT32 lastmarescore; // score for the last mare
UINT8 lastmare; // previous mare UINT8 lastmare; // previous mare

View File

@ -2673,10 +2673,6 @@ static void readmaincfg(MYFILE *f)
sstage_start = (INT16)value; sstage_start = (INT16)value;
sstage_end = (INT16)(sstage_start+6); // 7 special stages total sstage_end = (INT16)(sstage_start+6); // 7 special stages total
} }
else if (fastcmp(word, "USENIGHTSSS"))
{
useNightsSS = (UINT8)(value || word2[0] == 'T' || word2[0] == 'Y');
}
else if (fastcmp(word, "REDTEAM")) else if (fastcmp(word, "REDTEAM"))
{ {
skincolor_redteam = (UINT8)get_number(word2); skincolor_redteam = (UINT8)get_number(word2);
@ -3799,6 +3795,7 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
// Egg Shield for Egg Guard // Egg Shield for Egg Guard
"S_EGGSHIELD", "S_EGGSHIELD",
"S_EGGSHIELDBREAK",
// Green Snapper // Green Snapper
"S_GSNAPPER_STND", "S_GSNAPPER_STND",
@ -4367,8 +4364,17 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
"S_RING", "S_RING",
// Blue Sphere for special stages // Blue Sphere for special stages
"S_BLUEBALL", "S_BLUESPHERE",
"S_BLUEBALLSPARK", "S_BLUESPHEREBONUS",
"S_BLUESPHERESPARK",
// NiGHTS Chip
"S_NIGHTSCHIP",
"S_NIGHTSCHIPBONUS",
// NiGHTS Star
"S_NIGHTSSTAR",
"S_NIGHTSSTARXMAS",
// Gravity Wells for special stages // Gravity Wells for special stages
"S_GRAVWELLGREEN", "S_GRAVWELLGREEN",
@ -4426,8 +4432,10 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
"S_CEMG6", "S_CEMG6",
"S_CEMG7", "S_CEMG7",
// Emeralds (for hunt) // Emerald hunt shards
"S_EMER1", "S_SHRD1",
"S_SHRD2",
"S_SHRD3",
// Bubble Source // Bubble Source
"S_BUBBLES1", "S_BUBBLES1",
@ -4709,7 +4717,6 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
// Arrow // Arrow
"S_ARROW", "S_ARROW",
"S_TEMPSHI",
"S_ARROWBONK", "S_ARROWBONK",
// Trapgoyle Demon fire // Trapgoyle Demon fire
@ -4739,6 +4746,7 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
"S_POLYGONTREE", "S_POLYGONTREE",
"S_BUSHTREE", "S_BUSHTREE",
"S_BUSHREDTREE", "S_BUSHREDTREE",
"S_SPRINGTREE",
// THZ flowers // THZ flowers
"S_THZFLOWERA", // THZ1 Steam flower "S_THZFLOWERA", // THZ1 Steam flower
@ -6007,9 +6015,6 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
"S_NIGHTSCORE90_2", "S_NIGHTSCORE90_2",
"S_NIGHTSCORE100_2", "S_NIGHTSCORE100_2",
"S_NIGHTSWING",
"S_NIGHTSWING_XMAS",
// NiGHTS Paraloop Powerups // NiGHTS Paraloop Powerups
"S_NIGHTSSUPERLOOP", "S_NIGHTSSUPERLOOP",
"S_NIGHTSDRILLREFILL", "S_NIGHTSDRILLREFILL",
@ -6027,14 +6032,11 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
"S_ORBITEM6", "S_ORBITEM6",
"S_ORBITEM7", "S_ORBITEM7",
"S_ORBITEM8", "S_ORBITEM8",
"S_ORBITEM9", "S_ORBIDYA1",
"S_ORBITEM10", "S_ORBIDYA2",
"S_ORBITEM11", "S_ORBIDYA3",
"S_ORBITEM12", "S_ORBIDYA4",
"S_ORBITEM13", "S_ORBIDYA5",
"S_ORBITEM14",
"S_ORBITEM15",
"S_ORBITEM16",
// "Flicky" helper // "Flicky" helper
"S_NIGHTOPIANHELPER1", "S_NIGHTOPIANHELPER1",
@ -6047,6 +6049,26 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
"S_NIGHTOPIANHELPER8", "S_NIGHTOPIANHELPER8",
"S_NIGHTOPIANHELPER9", "S_NIGHTOPIANHELPER9",
// Nightopian
"S_PIAN0",
"S_PIAN1",
"S_PIAN2",
"S_PIAN3",
"S_PIAN4",
"S_PIAN5",
"S_PIAN6",
"S_PIANSING",
// Shleep
"S_SHLEEP1",
"S_SHLEEP2",
"S_SHLEEP3",
"S_SHLEEP4",
"S_SHLEEPBOUNCE1",
"S_SHLEEPBOUNCE2",
"S_SHLEEPBOUNCE3",
// Secret badniks and hazards, shhhh // Secret badniks and hazards, shhhh
"S_HIVEELEMENTAL_LOOK", "S_HIVEELEMENTAL_LOOK",
"S_HIVEELEMENTAL_PREPARE1", "S_HIVEELEMENTAL_PREPARE1",
@ -6322,7 +6344,7 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s
// Collectible Items // Collectible Items
"MT_RING", "MT_RING",
"MT_FLINGRING", // Lost ring "MT_FLINGRING", // Lost ring
"MT_BLUEBALL", // Blue sphere replacement for special stages "MT_BLUESPHERE", // Blue sphere replacement for special stages
"MT_REDTEAMRING", //Rings collectable by red team. "MT_REDTEAMRING", //Rings collectable by red team.
"MT_BLUETEAMRING", //Rings collectable by blue team. "MT_BLUETEAMRING", //Rings collectable by blue team.
"MT_TOKEN", // Special Stage Token "MT_TOKEN", // Special Stage Token
@ -6466,6 +6488,7 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s
"MT_POLYGONTREE", "MT_POLYGONTREE",
"MT_BUSHTREE", "MT_BUSHTREE",
"MT_BUSHREDTREE", "MT_BUSHREDTREE",
"MT_SPRINGTREE",
// Techno Hill Scenery // Techno Hill Scenery
"MT_THZFLOWER1", "MT_THZFLOWER1",
@ -6778,7 +6801,8 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s
"MT_HOOPCOLLIDE", // Collision detection for NiGHTS hoops "MT_HOOPCOLLIDE", // Collision detection for NiGHTS hoops
"MT_HOOPCENTER", // Center of a hoop "MT_HOOPCENTER", // Center of a hoop
"MT_NIGHTSCORE", "MT_NIGHTSCORE",
"MT_NIGHTSWING", "MT_NIGHTSCHIP", // NiGHTS Chip
"MT_NIGHTSSTAR", // NiGHTS Star
"MT_NIGHTSSUPERLOOP", "MT_NIGHTSSUPERLOOP",
"MT_NIGHTSDRILLREFILL", "MT_NIGHTSDRILLREFILL",
"MT_NIGHTSHELPER", "MT_NIGHTSHELPER",
@ -6786,6 +6810,8 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s
"MT_NIGHTSLINKFREEZE", "MT_NIGHTSLINKFREEZE",
"MT_EGGCAPSULE", "MT_EGGCAPSULE",
"MT_NIGHTOPIANHELPER", // the actual helper object that orbits you "MT_NIGHTOPIANHELPER", // the actual helper object that orbits you
"MT_PIAN", // decorative singing friend
"MT_SHLEEP", // almost-decorative sleeping enemy
// Secret badniks and hazards, shhhh // Secret badniks and hazards, shhhh
"MT_HIVEELEMENTAL", "MT_HIVEELEMENTAL",

View File

@ -134,7 +134,6 @@ extern boolean hidetitlepics;
extern INT16 bootmap; //bootmap for loading a map on startup extern INT16 bootmap; //bootmap for loading a map on startup
extern boolean looptitle; extern boolean looptitle;
extern boolean useNightsSS;
// CTF colors. // CTF colors.
extern UINT8 skincolor_redteam, skincolor_blueteam, skincolor_redring, skincolor_bluering; extern UINT8 skincolor_redteam, skincolor_blueteam, skincolor_redring, skincolor_bluering;
@ -175,7 +174,7 @@ extern cutscene_t *cutscenes[128];
extern INT16 nextmapoverride; extern INT16 nextmapoverride;
extern boolean skipstats; extern boolean skipstats;
extern UINT32 totalrings; // Total # of rings in a level extern UINT32 ssspheres; // Total # of spheres in a level
// Fun extra stuff // Fun extra stuff
extern INT16 lastmap; // Last level you were at (returning from special stages). extern INT16 lastmap; // Last level you were at (returning from special stages).

View File

@ -1345,7 +1345,7 @@ void F_GameEvaluationDrawer(void)
++timesBeatenUltimate; ++timesBeatenUltimate;
if (M_UpdateUnlockablesAndExtraEmblems()) if (M_UpdateUnlockablesAndExtraEmblems())
S_StartSound(NULL, sfx_ncitem); S_StartSound(NULL, sfx_s3k68);
G_SaveGameData(); G_SaveGameData();
} }

View File

@ -116,7 +116,7 @@ INT32 secondarydisplayplayer; // for splitscreen
tic_t gametic; tic_t gametic;
tic_t levelstarttic; // gametic at level start tic_t levelstarttic; // gametic at level start
UINT32 totalrings; // for intermission UINT32 ssspheres; // old special stage
INT16 lastmap; // last level you were at (returning from special stages) INT16 lastmap; // last level you were at (returning from special stages)
tic_t timeinmap; // Ticker for time spent in level (used for levelcard display) tic_t timeinmap; // Ticker for time spent in level (used for levelcard display)
@ -129,7 +129,6 @@ boolean hidetitlepics = false;
INT16 bootmap; //bootmap for loading a map on startup INT16 bootmap; //bootmap for loading a map on startup
boolean looptitle = false; boolean looptitle = false;
boolean useNightsSS = false;
UINT8 skincolor_redteam = SKINCOLOR_RED; UINT8 skincolor_redteam = SKINCOLOR_RED;
UINT8 skincolor_blueteam = SKINCOLOR_BLUE; UINT8 skincolor_blueteam = SKINCOLOR_BLUE;
@ -2201,7 +2200,7 @@ void G_PlayerReborn(INT32 player)
p->pflags |= PF_JUMPDOWN; p->pflags |= PF_JUMPDOWN;
p->playerstate = PST_LIVE; p->playerstate = PST_LIVE;
p->rings = 0; // 0 rings p->rings = p->spheres = 0; // 0 rings
p->panim = PA_IDLE; // standing animation p->panim = PA_IDLE; // standing animation
//if ((netgame || multiplayer) && !p->spectator) -- moved into P_SpawnPlayer to account for forced changes there //if ((netgame || multiplayer) && !p->spectator) -- moved into P_SpawnPlayer to account for forced changes there
@ -3209,7 +3208,6 @@ void G_LoadGameSettings(void)
spstage_start = 1; spstage_start = 1;
sstage_start = 50; sstage_start = 50;
sstage_end = 57; // 8 special stages in vanilla SRB2 sstage_end = 57; // 8 special stages in vanilla SRB2
useNightsSS = false; //true;
// initialize free sfx slots for skin sounds // initialize free sfx slots for skin sounds
S_InitRuntimeSounds(); S_InitRuntimeSounds();

View File

@ -229,10 +229,12 @@ light_t *t_lspr[NUMSPRITES] =
&lspr[NOLIGHT], // SPR_TOKE &lspr[NOLIGHT], // SPR_TOKE
&lspr[REDBALL_L], // SPR_RFLG &lspr[REDBALL_L], // SPR_RFLG
&lspr[BLUEBALL_L], // SPR_BFLG &lspr[BLUEBALL_L], // SPR_BFLG
&lspr[NOLIGHT], // SPR_NWNG &lspr[NOLIGHT], // SPR_SPHR
&lspr[NOLIGHT], // SPR_NCHP
&lspr[NOLIGHT], // SPR_NSTR
&lspr[NOLIGHT], // SPR_EMBM &lspr[NOLIGHT], // SPR_EMBM
&lspr[NOLIGHT], // SPR_CEMG &lspr[NOLIGHT], // SPR_CEMG
&lspr[NOLIGHT], // SPR_EMER &lspr[NOLIGHT], // SPR_SHRD
// Interactive Objects // Interactive Objects
&lspr[NOLIGHT], // SPR_BBLS &lspr[NOLIGHT], // SPR_BBLS
@ -298,6 +300,7 @@ light_t *t_lspr[NUMSPRITES] =
&lspr[NOLIGHT], // SPR_TRE3 &lspr[NOLIGHT], // SPR_TRE3
&lspr[NOLIGHT], // SPR_TRE4 &lspr[NOLIGHT], // SPR_TRE4
&lspr[NOLIGHT], // SPR_TRE5 &lspr[NOLIGHT], // SPR_TRE5
&lspr[NOLIGHT], // SPR_TRE6
// Techno Hill Scenery // Techno Hill Scenery
&lspr[NOLIGHT], // SPR_THZP &lspr[NOLIGHT], // SPR_THZP
@ -498,6 +501,9 @@ light_t *t_lspr[NUMSPRITES] =
&lspr[NOLIGHT], // SPR_HSCR &lspr[NOLIGHT], // SPR_HSCR
&lspr[NOLIGHT], // SPR_NPRU &lspr[NOLIGHT], // SPR_NPRU
&lspr[NOLIGHT], // SPR_CAPS &lspr[NOLIGHT], // SPR_CAPS
&lspr[INVINCIBLE_L], // SPR_IDYA
&lspr[NOLIGHT], // SPR_NTPN
&lspr[NOLIGHT], // SPR_SHLP
// Secret badniks and hazards, shhhh // Secret badniks and hazards, shhhh
&lspr[NOLIGHT], // SPR_HIVE &lspr[NOLIGHT], // SPR_HIVE
@ -538,9 +544,6 @@ light_t *t_lspr[NUMSPRITES] =
&lspr[NOLIGHT], // SPR_ROIO &lspr[NOLIGHT], // SPR_ROIO
&lspr[NOLIGHT], // SPR_ROIP &lspr[NOLIGHT], // SPR_ROIP
// Blue Spheres
&lspr[NOLIGHT], // SPR_BBAL
// Gravity Well Objects // Gravity Well Objects
&lspr[NOLIGHT], // SPR_GWLG &lspr[NOLIGHT], // SPR_GWLG
&lspr[NOLIGHT], // SPR_GWLR &lspr[NOLIGHT], // SPR_GWLR

View File

@ -89,7 +89,7 @@ patch_t *tallinfin;
// coop hud // coop hud
//------------------------------------------- //-------------------------------------------
patch_t *emeraldpics[3][7]; // 0 = normal, 1 = tiny, 2 = coinbox patch_t *emeraldpics[3][8]; // 0 = normal, 1 = tiny, 2 = coinbox
static patch_t *emblemicon; static patch_t *emblemicon;
patch_t *tokenicon; patch_t *tokenicon;
static patch_t *exiticon; static patch_t *exiticon;
@ -256,6 +256,7 @@ void HU_LoadGraphics(void)
emeraldpics[0][4] = W_CachePatchName("CHAOS5", PU_HUDGFX); emeraldpics[0][4] = W_CachePatchName("CHAOS5", PU_HUDGFX);
emeraldpics[0][5] = W_CachePatchName("CHAOS6", PU_HUDGFX); emeraldpics[0][5] = W_CachePatchName("CHAOS6", PU_HUDGFX);
emeraldpics[0][6] = W_CachePatchName("CHAOS7", PU_HUDGFX); emeraldpics[0][6] = W_CachePatchName("CHAOS7", PU_HUDGFX);
emeraldpics[0][7] = W_CachePatchName("CHAOS8", PU_HUDGFX);
emeraldpics[1][0] = W_CachePatchName("TEMER1", PU_HUDGFX); emeraldpics[1][0] = W_CachePatchName("TEMER1", PU_HUDGFX);
emeraldpics[1][1] = W_CachePatchName("TEMER2", PU_HUDGFX); emeraldpics[1][1] = W_CachePatchName("TEMER2", PU_HUDGFX);
@ -264,6 +265,7 @@ void HU_LoadGraphics(void)
emeraldpics[1][4] = W_CachePatchName("TEMER5", PU_HUDGFX); emeraldpics[1][4] = W_CachePatchName("TEMER5", PU_HUDGFX);
emeraldpics[1][5] = W_CachePatchName("TEMER6", PU_HUDGFX); emeraldpics[1][5] = W_CachePatchName("TEMER6", PU_HUDGFX);
emeraldpics[1][6] = W_CachePatchName("TEMER7", PU_HUDGFX); emeraldpics[1][6] = W_CachePatchName("TEMER7", PU_HUDGFX);
//emeraldpics[1][7] = W_CachePatchName("TEMER8", PU_HUDGFX); -- unused
emeraldpics[2][0] = W_CachePatchName("EMBOX1", PU_HUDGFX); emeraldpics[2][0] = W_CachePatchName("EMBOX1", PU_HUDGFX);
emeraldpics[2][1] = W_CachePatchName("EMBOX2", PU_HUDGFX); emeraldpics[2][1] = W_CachePatchName("EMBOX2", PU_HUDGFX);
@ -272,6 +274,7 @@ void HU_LoadGraphics(void)
emeraldpics[2][4] = W_CachePatchName("EMBOX5", PU_HUDGFX); emeraldpics[2][4] = W_CachePatchName("EMBOX5", PU_HUDGFX);
emeraldpics[2][5] = W_CachePatchName("EMBOX6", PU_HUDGFX); emeraldpics[2][5] = W_CachePatchName("EMBOX6", PU_HUDGFX);
emeraldpics[2][6] = W_CachePatchName("EMBOX7", PU_HUDGFX); emeraldpics[2][6] = W_CachePatchName("EMBOX7", PU_HUDGFX);
//emeraldpics[2][7] = W_CachePatchName("EMBOX8", PU_HUDGFX); -- unused
} }
// Initialise Heads up // Initialise Heads up

View File

@ -63,7 +63,7 @@ extern patch_t *tallnum[10];
extern patch_t *nightsnum[10]; extern patch_t *nightsnum[10];
extern patch_t *lt_font[LT_FONTSIZE]; extern patch_t *lt_font[LT_FONTSIZE];
extern patch_t *cred_font[CRED_FONTSIZE]; extern patch_t *cred_font[CRED_FONTSIZE];
extern patch_t *emeraldpics[3][7]; extern patch_t *emeraldpics[3][8];
extern patch_t *rflagico; extern patch_t *rflagico;
extern patch_t *bflagico; extern patch_t *bflagico;
extern patch_t *rmatcico; extern patch_t *rmatcico;

View File

@ -118,10 +118,12 @@ char sprnames[NUMSPRITES + 1][5] =
"TOKE", // Special Stage Token "TOKE", // Special Stage Token
"RFLG", // Red CTF Flag "RFLG", // Red CTF Flag
"BFLG", // Blue CTF Flag "BFLG", // Blue CTF Flag
"NWNG", // NiGHTS Wing collectable item. "SPHR", // Sphere
"NCHP", // NiGHTS chip
"NSTR", // NiGHTS star
"EMBM", // Emblem "EMBM", // Emblem
"CEMG", // Chaos Emeralds "CEMG", // Chaos Emeralds
"EMER", // Emerald Hunt "SHRD", // Emerald hunt shards
// Interactive Objects // Interactive Objects
"BBLS", // water bubble source "BBLS", // water bubble source
@ -187,6 +189,7 @@ char sprnames[NUMSPRITES + 1][5] =
"TRE3", // Frozen Hillside "TRE3", // Frozen Hillside
"TRE4", // Polygon "TRE4", // Polygon
"TRE5", // Bush tree "TRE5", // Bush tree
"TRE6", // Spring tree
// Techno Hill Scenery // Techno Hill Scenery
"THZP", // THZ1 Steam Flower "THZP", // THZ1 Steam Flower
@ -392,6 +395,9 @@ char sprnames[NUMSPRITES + 1][5] =
"NSCR", // NiGHTS score sprite "NSCR", // NiGHTS score sprite
"NPRU", // Nights Powerups "NPRU", // Nights Powerups
"CAPS", // Capsule thingy for NiGHTS "CAPS", // Capsule thingy for NiGHTS
"IDYA", // Ideya
"NTPN", // Nightopian
"SHLP", // Shleep
// Secret badniks and hazards, shhhh // Secret badniks and hazards, shhhh
"HIVE", "HIVE",
@ -432,9 +438,6 @@ char sprnames[NUMSPRITES + 1][5] =
"ROIO", "ROIO",
"ROIP", "ROIP",
// Blue Spheres
"BBAL",
// Gravity Well Objects // Gravity Well Objects
"GWLG", "GWLG",
"GWLR", "GWLR",
@ -715,7 +718,7 @@ state_t states[NUMSTATES] =
{SPR_PLAY, SPR2_TRNS|FF_SPR2SUPER|FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_PLAY_SUPER_TRANS4}, // S_PLAY_SUPER_TRANS3 {SPR_PLAY, SPR2_TRNS|FF_SPR2SUPER|FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_PLAY_SUPER_TRANS4}, // S_PLAY_SUPER_TRANS3
{SPR_PLAY, SPR2_TRNS|FF_SPR2SUPER|FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_PLAY_SUPER_TRANS5}, // S_PLAY_SUPER_TRANS4 {SPR_PLAY, SPR2_TRNS|FF_SPR2SUPER|FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_PLAY_SUPER_TRANS5}, // S_PLAY_SUPER_TRANS4
{SPR_PLAY, SPR2_TRNS|FF_SPR2SUPER|FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_PLAY_SUPER_TRANS6}, // S_PLAY_SUPER_TRANS5 {SPR_PLAY, SPR2_TRNS|FF_SPR2SUPER|FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_PLAY_SUPER_TRANS6}, // S_PLAY_SUPER_TRANS5
{SPR_PLAY, SPR2_TRNS|FF_SPR2SUPER|FF_FULLBRIGHT, 20, {A_FadeOverlay}, 0, 0, S_PLAY_FALL}, // S_PLAY_SUPER_TRANS6 {SPR_PLAY, SPR2_TRNS|FF_SPR2SUPER|FF_FULLBRIGHT, 20, {A_FadeOverlay}, 0, 0, S_PLAY_FLOAT}, // S_PLAY_SUPER_TRANS6
{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
@ -1021,7 +1024,8 @@ state_t states[NUMSTATES] =
{SPR_SPSH, 10, 1, {A_GuardChase}, 0, 0, S_EGGGUARD_RUN4}, // S_EGGGUARD_RUN3 {SPR_SPSH, 10, 1, {A_GuardChase}, 0, 0, S_EGGGUARD_RUN4}, // S_EGGGUARD_RUN3
{SPR_SPSH, 11, 1, {A_GuardChase}, 0, 0, S_EGGGUARD_RUN1}, // S_EGGGUARD_RUN4 {SPR_SPSH, 11, 1, {A_GuardChase}, 0, 0, S_EGGGUARD_RUN1}, // S_EGGGUARD_RUN4
{SPR_ESHI, 0, 8, {A_EggShield}, 0, 0, S_EGGSHIELD}, // S_EGGSHIELD {SPR_ESHI, 0, 8, {A_EggShield}, 0, 0, S_EGGSHIELD}, // S_EGGSHIELD
{SPR_ESHI, 0, TICRATE/2, {NULL}, 0, 0, S_NULL}, // S_EGGSHIELDBREAK
// Green Snapper // Green Snapper
{SPR_GSNP, 0, 1, {A_Look}, 0, 0, S_GSNAPPER_STND}, // S_GSNAPPER_STND {SPR_GSNP, 0, 1, {A_Look}, 0, 0, S_GSNAPPER_STND}, // S_GSNAPPER_STND
@ -1591,18 +1595,22 @@ state_t states[NUMSTATES] =
// Ring // Ring
{SPR_RING, FF_ANIMATE|FF_GLOBALANIM, -1, {NULL}, 23, 1, S_RING}, // S_RING {SPR_RING, FF_ANIMATE|FF_GLOBALANIM, -1, {NULL}, 23, 1, S_RING}, // S_RING
// Blue Sphere Replacement for special stages // Blue Sphere for special stages
{SPR_BBAL, 0, -1, {NULL}, 0, 0, S_NULL}, // S_BLUEBALL {SPR_SPHR, FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_NULL}, // S_BLUESPHERE
{SPR_BBAL, 0, 20, {NULL}, 0, 0, S_NULL}, // S_BLUEBALLSPARK {SPR_SPHR, FF_FULLBRIGHT|FF_RANDOMANIM|FF_ANIMATE, -1, {NULL}, 1, 4, S_NULL}, // S_BLUESPHEREBONUS
{SPR_SPHR, 0, 20, {NULL}, 0, 0, S_NULL}, // S_BLUESPHERESPARK
// NiGHTS Chip
{SPR_NCHP, FF_FULLBRIGHT|FF_ANIMATE, -1, {NULL}, 15, 2, S_NULL}, // S_NIGHTSCHIP
{SPR_NCHP, FF_FULLBRIGHT|FF_ANIMATE|16, -1, {NULL}, 15, 2, S_NULL}, // S_NIGHTSCHIPBONUS
// NiGHTS Star
{SPR_NSTR, FF_ANIMATE, -1, {NULL}, 14, 2, S_NULL}, // S_NIGHTSSTAR
{SPR_NSTR, 15, -1, {NULL}, 0, 0, S_NULL}, // S_NIGHTSSTARXMAS
// Gravity Well sprites for Egg Rock's Special Stage // Gravity Well sprites for Egg Rock's Special Stage
{SPR_GWLG, 0, 1, {NULL}, 0, 0, S_GRAVWELLGREEN2}, // S_GRAVWELLGREEN {SPR_GWLG, FF_ANIMATE, -1, {NULL}, 2, 1, S_NULL}, // S_GRAVWELLGREEN
{SPR_GWLG, 1, 1, {NULL}, 0, 0, S_GRAVWELLGREEN3}, // S_GRAVWELLGREEN2 {SPR_GWLR, FF_ANIMATE, -1, {NULL}, 2, 1, S_NULL}, // S_GRAVWELLRED
{SPR_GWLG, 2, 1, {NULL}, 0, 0, S_GRAVWELLGREEN}, // S_GRAVWELLGREEN3
{SPR_GWLR, 0, 1, {NULL}, 0, 0, S_GRAVWELLRED2}, // S_GRAVWELLRED
{SPR_GWLR, 1, 1, {NULL}, 0, 0, S_GRAVWELLRED3}, // S_GRAVWELLRED2
{SPR_GWLR, 2, 1, {NULL}, 0, 0, S_GRAVWELLRED}, // S_GRAVWELLRED3
// Individual Team Rings (now with shield attracting action! =P) // Individual Team Rings (now with shield attracting action! =P)
{SPR_TRNG, FF_ANIMATE|FF_GLOBALANIM, -1, {NULL}, 23, 1, S_TEAMRING}, // S_TEAMRING {SPR_TRNG, FF_ANIMATE|FF_GLOBALANIM, -1, {NULL}, 23, 1, S_TEAMRING}, // S_TEAMRING
@ -1651,8 +1659,10 @@ state_t states[NUMSTATES] =
{SPR_CEMG, FF_FULLBRIGHT|5, -1, {NULL}, 0, 0, S_NULL}, // S_CEMG6 {SPR_CEMG, FF_FULLBRIGHT|5, -1, {NULL}, 0, 0, S_NULL}, // S_CEMG6
{SPR_CEMG, FF_FULLBRIGHT|6, -1, {NULL}, 0, 0, S_NULL}, // S_CEMG7 {SPR_CEMG, FF_FULLBRIGHT|6, -1, {NULL}, 0, 0, S_NULL}, // S_CEMG7
// Emeralds (for hunt) // Emerald hunt shards
{SPR_EMER, 0, -1, {NULL}, 0, 0, S_NULL}, // S_EMER1 {SPR_SHRD, 0, -1, {NULL}, 0, 0, S_NULL}, // S_SHRD1
{SPR_SHRD, 1, -1, {NULL}, 0, 0, S_NULL}, // S_SHRD2
{SPR_SHRD, 2, -1, {NULL}, 0, 0, S_NULL}, // S_SHRD3
// Bubble Source // Bubble Source
{SPR_BBLS, 0, 8, {A_BubbleSpawn}, 2048, 0, S_BUBBLES2}, // S_BUBBLES1 {SPR_BBLS, 0, 8, {A_BubbleSpawn}, 2048, 0, S_BUBBLES2}, // S_BUBBLES1
@ -1934,7 +1944,6 @@ state_t states[NUMSTATES] =
{SPR_CBLL, 0, -1, {NULL}, 0, 0, S_NULL}, // S_CANNONBALL1 {SPR_CBLL, 0, -1, {NULL}, 0, 0, S_NULL}, // S_CANNONBALL1
{SPR_AROW, 0, -1, {NULL}, 0, 0, S_NULL}, // S_ARROW {SPR_AROW, 0, -1, {NULL}, 0, 0, S_NULL}, // S_ARROW
{SPR_ESHI, 0, TICRATE/2, {NULL}, 0, 0, S_NULL}, // S_TEMPSHI
{SPR_AROW, FF_ANIMATE, TICRATE, {A_ArrowBonks}, 7, 2, S_NULL}, // S_ARROWBONK {SPR_AROW, FF_ANIMATE, TICRATE, {A_ArrowBonks}, 7, 2, S_NULL}, // S_ARROWBONK
{SPR_CFIR, FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_DEMONFIRE2}, // S_DEMONFIRE1 {SPR_CFIR, FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_DEMONFIRE2}, // S_DEMONFIRE1
@ -1963,6 +1972,7 @@ state_t states[NUMSTATES] =
{SPR_TRE4, 0, -1, {NULL}, 0, 0, S_NULL}, // S_POLYGONTREE {SPR_TRE4, 0, -1, {NULL}, 0, 0, S_NULL}, // S_POLYGONTREE
{SPR_TRE5, 0, -1, {NULL}, 0, 0, S_NULL}, // S_BUSHTREE {SPR_TRE5, 0, -1, {NULL}, 0, 0, S_NULL}, // S_BUSHTREE
{SPR_TRE5, 1, -1, {NULL}, 0, 0, S_NULL}, // S_BUSHREDTREE {SPR_TRE5, 1, -1, {NULL}, 0, 0, S_NULL}, // S_BUSHREDTREE
{SPR_TRE6, 0, -1, {NULL}, 0, 0, S_NULL}, // S_SPRINGTREE
// THZ flowers // THZ flowers
{SPR_THZP, FF_ANIMATE, -1, {NULL}, 7, 4, S_NULL}, // S_THZFLOWERA {SPR_THZP, FF_ANIMATE, -1, {NULL}, 7, 4, S_NULL}, // S_THZFLOWERA
@ -3301,9 +3311,6 @@ state_t states[NUMSTATES] =
{SPR_NSCR, FF_FULLBRIGHT|18, -1, {NULL}, 0, 0, S_NULL}, // S_NIGHTSCORE90_2 {SPR_NSCR, FF_FULLBRIGHT|18, -1, {NULL}, 0, 0, S_NULL}, // S_NIGHTSCORE90_2
{SPR_NSCR, FF_FULLBRIGHT|19, -1, {NULL}, 0, 0, S_NULL}, // S_NIGHTSCORE100_2 {SPR_NSCR, FF_FULLBRIGHT|19, -1, {NULL}, 0, 0, S_NULL}, // S_NIGHTSCORE100_2
{SPR_NWNG, 0, -1, {NULL}, 0, 0, S_NULL}, // S_NIGHTSWING
{SPR_NWNG, 1, -1, {NULL}, 0, 0, S_NULL}, // S_NIGHTSWING_XMAS
// NiGHTS Paraloop Powerups // NiGHTS Paraloop Powerups
{SPR_NPRU, 0, -1, {NULL}, 0, 0, S_NULL}, // S_NIGHTSSUPERLOOP {SPR_NPRU, 0, -1, {NULL}, 0, 0, S_NULL}, // S_NIGHTSSUPERLOOP
{SPR_NPRU, 1, -1, {NULL}, 0, 0, S_NULL}, // S_NIGHTSDRILLREFILL {SPR_NPRU, 1, -1, {NULL}, 0, 0, S_NULL}, // S_NIGHTSDRILLREFILL
@ -3313,7 +3320,7 @@ state_t states[NUMSTATES] =
{SPR_CAPS, 0, -1, {NULL}, 0, 0, S_NULL}, // S_EGGCAPSULE {SPR_CAPS, 0, -1, {NULL}, 0, 0, S_NULL}, // S_EGGCAPSULE
// Orbiting Chaos Emeralds for NiGHTS // Orbiting Chaos Emeralds/Ideya for NiGHTS
{SPR_CEMG, FF_FULLBRIGHT, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM1}, // S_ORBITEM1 {SPR_CEMG, FF_FULLBRIGHT, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM1}, // S_ORBITEM1
{SPR_CEMG, FF_FULLBRIGHT|1, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM2}, // S_ORBITEM2 {SPR_CEMG, FF_FULLBRIGHT|1, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM2}, // S_ORBITEM2
{SPR_CEMG, FF_FULLBRIGHT|2, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM3}, // S_ORBITEM3 {SPR_CEMG, FF_FULLBRIGHT|2, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM3}, // S_ORBITEM3
@ -3322,14 +3329,11 @@ state_t states[NUMSTATES] =
{SPR_CEMG, FF_FULLBRIGHT|5, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM6}, // S_ORBITEM6 {SPR_CEMG, FF_FULLBRIGHT|5, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM6}, // S_ORBITEM6
{SPR_CEMG, FF_FULLBRIGHT|6, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM7}, // S_ORBITEM7 {SPR_CEMG, FF_FULLBRIGHT|6, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM7}, // S_ORBITEM7
{SPR_CEMG, FF_FULLBRIGHT|7, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM8}, // S_ORBITEM8 {SPR_CEMG, FF_FULLBRIGHT|7, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM8}, // S_ORBITEM8
{SPR_CEMG, FF_FULLBRIGHT|8, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM8}, // S_ORBITEM9 {SPR_IDYA, FF_TRANS20|FF_FULLBRIGHT, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBIDYA1}, // S_ORBIDYA1
{SPR_CEMG, FF_FULLBRIGHT|9, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM8}, // S_ORBITEM10 {SPR_IDYA, FF_TRANS20|FF_FULLBRIGHT|1, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBIDYA2}, // S_ORBIDYA2
{SPR_CEMG, FF_FULLBRIGHT|10, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM8}, // S_ORBITEM11 {SPR_IDYA, FF_TRANS20|FF_FULLBRIGHT|2, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBIDYA3}, // S_ORBIDYA3
{SPR_CEMG, FF_FULLBRIGHT|11, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM8}, // S_ORBITEM12 {SPR_IDYA, FF_TRANS20|FF_FULLBRIGHT|3, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBIDYA4}, // S_ORBIDYA4
{SPR_CEMG, FF_FULLBRIGHT|12, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM8}, // S_ORBITEM13 {SPR_IDYA, FF_TRANS20|FF_FULLBRIGHT|4, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBIDYA5}, // S_ORBIDYA5
{SPR_CEMG, FF_FULLBRIGHT|13, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM8}, // S_ORBITEM14
{SPR_CEMG, FF_FULLBRIGHT|14, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM8}, // S_ORBITEM15
{SPR_CEMG, FF_FULLBRIGHT|15, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM8}, // S_ORBITEM16
// Flicky helper for NiGHTS // Flicky helper for NiGHTS
{SPR_FL01, 1, 1, {A_OrbitNights}, ANG2*2, 180 | 0x10000, S_NIGHTOPIANHELPER2}, // S_NIGHTOPIANHELPER1 {SPR_FL01, 1, 1, {A_OrbitNights}, ANG2*2, 180 | 0x10000, S_NIGHTOPIANHELPER2}, // S_NIGHTOPIANHELPER1
@ -3342,6 +3346,25 @@ state_t states[NUMSTATES] =
{SPR_FL01, 3, 1, {A_OrbitNights}, ANG2*2, 180 | 0x10000, S_NIGHTOPIANHELPER9}, // S_NIGHTOPIANHELPER8 {SPR_FL01, 3, 1, {A_OrbitNights}, ANG2*2, 180 | 0x10000, S_NIGHTOPIANHELPER9}, // S_NIGHTOPIANHELPER8
{SPR_FL01, 3, 1, {A_OrbitNights}, ANG2*2, 180 | 0x10000, S_NIGHTOPIANHELPER1}, // S_NIGHTOPIANHELPER9 {SPR_FL01, 3, 1, {A_OrbitNights}, ANG2*2, 180 | 0x10000, S_NIGHTOPIANHELPER1}, // S_NIGHTOPIANHELPER9
// Nightopian
{SPR_NTPN, 0, 4, {A_Look}, 0, 0, S_PIAN0}, // S_PIAN0
{SPR_NTPN, 0, 4, {A_JetgThink}, 0, 0, S_PIAN2}, // S_PIAN1
{SPR_NTPN, 1, 4, {NULL}, 0, 0, S_PIAN3}, // S_PIAN2
{SPR_NTPN, 2, 4, {NULL}, 0, 0, S_PIAN4}, // S_PIAN3
{SPR_NTPN, 3, 4, {NULL}, 0, 0, S_PIAN5}, // S_PIAN4
{SPR_NTPN, 2, 4, {NULL}, 0, 0, S_PIAN6}, // S_PIAN5
{SPR_NTPN, 1, 4, {NULL}, 0, 0, S_PIAN1}, // S_PIAN6
{SPR_NTPN, 5|FF_ANIMATE, 4, {NULL}, 1, 4, S_PIAN1}, // S_PIANSING
// Shleep
{SPR_SHLP, 0, 15, {NULL}, 0, 0, S_SHLEEP2}, // S_SHLEEP1
{SPR_SHLP, 1, 15, {NULL}, 0, 0, S_SHLEEP3}, // S_SHLEEP2
{SPR_SHLP, 2, 15, {NULL}, 0, 0, S_SHLEEP4}, // S_SHLEEP3
{SPR_SHLP, 1, 15, {NULL}, 0, 0, S_SHLEEP1}, // S_SHLEEP4
{SPR_SHLP, 3, 1, {A_Scream}, 0, 0, S_SHLEEPBOUNCE2}, // S_SHLEEPBOUNCE1
{SPR_SHLP, 3, 1, {A_ZThrust}, 9, 0, S_SHLEEPBOUNCE3}, // S_SHLEEPBOUNCE2
{SPR_SHLP, 3, 400, {A_SetObjectFlags}, MF_SLIDEME|MF_ENEMY|MF_BOUNCE|MF_NOCLIP|MF_NOCLIPHEIGHT, 0, S_NULL}, // S_SHLEEPBOUNCE3
// Secret badniks and hazards, shhhh // Secret badniks and hazards, shhhh
{SPR_HIVE, 0, 5, {A_Look}, 1, 1, S_HIVEELEMENTAL_LOOK}, // S_HIVEELEMENTAL_LOOK {SPR_HIVE, 0, 5, {A_Look}, 1, 1, S_HIVEELEMENTAL_LOOK}, // S_HIVEELEMENTAL_LOOK
{SPR_HIVE, 0, 14, {A_PlaySound}, sfx_s3k76, 1, S_HIVEELEMENTAL_PREPARE2}, // S_HIVEELEMENTAL_PREPARE1 {SPR_HIVE, 0, 14, {A_PlaySound}, sfx_s3k76, 1, S_HIVEELEMENTAL_PREPARE2}, // S_HIVEELEMENTAL_PREPARE1
@ -4337,7 +4360,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
sfx_s3k7b, // painsound sfx_s3k7b, // painsound
S_NULL, // meleestate S_NULL, // meleestate
S_NULL, // missilestate S_NULL, // missilestate
S_TEMPSHI, // deathstate S_EGGSHIELDBREAK,// deathstate
S_NULL, // xdeathstate S_NULL, // xdeathstate
sfx_wbreak, // deathsound sfx_wbreak, // deathsound
3, // speed 3, // speed
@ -5729,9 +5752,9 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_NULL // raisestate S_NULL // raisestate
}, },
{ // MT_BLUEBALL { // MT_BLUESPHERE
-1, // doomednum 1706, // doomednum
S_BLUEBALL, // spawnstate S_BLUESPHERE, // spawnstate
1000, // spawnhealth 1000, // spawnhealth
S_NULL, // seestate S_NULL, // seestate
sfx_None, // seesound sfx_None, // seesound
@ -5742,7 +5765,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
sfx_None, // painsound sfx_None, // painsound
S_NULL, // meleestate S_NULL, // meleestate
S_NULL, // missilestate S_NULL, // missilestate
S_BLUEBALLSPARK, // deathstate S_BLUESPHERESPARK, // deathstate
S_NULL, // xdeathstate S_NULL, // xdeathstate
sfx_s3k65, // deathsound sfx_s3k65, // deathsound
38*FRACUNIT, // speed 38*FRACUNIT, // speed
@ -5753,7 +5776,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
0, // damage 0, // damage
sfx_None, // activesound sfx_None, // activesound
MF_SLIDEME|MF_SPECIAL|MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags MF_SLIDEME|MF_SPECIAL|MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags
S_NULL // raisestate S_BLUESPHEREBONUS // raisestate
}, },
{ // MT_REDTEAMRING { // MT_REDTEAMRING
@ -5825,7 +5848,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_NULL, // missilestate S_NULL, // missilestate
S_SPRK1, // deathstate S_SPRK1, // deathstate
S_NULL, // xdeathstate S_NULL, // xdeathstate
sfx_token, // deathsound sfx_None, // deathsound
0, // speed 0, // speed
8*FRACUNIT, // radius 8*FRACUNIT, // radius
16*FRACUNIT, // height 16*FRACUNIT, // height
@ -6103,7 +6126,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
{ // MT_EMERHUNT { // MT_EMERHUNT
320, // doomednum 320, // doomednum
S_EMER1, // spawnstate S_SHRD1, // spawnstate
1000, // spawnhealth 1000, // spawnhealth
S_NULL, // seestate S_NULL, // seestate
sfx_None, // seesound sfx_None, // seesound
@ -6118,8 +6141,8 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_NULL, // xdeathstate S_NULL, // xdeathstate
sfx_cgot, // deathsound sfx_cgot, // deathsound
8, // speed 8, // speed
16*FRACUNIT, // radius 12*FRACUNIT, // radius
32*FRACUNIT, // height 42*FRACUNIT, // height
0, // display offset 0, // display offset
4, // mass 4, // mass
0, // damage 0, // damage
@ -6588,7 +6611,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
}, },
{ // MT_SPIKEBALL { // MT_SPIKEBALL
-1, // doomednum 521, // doomednum
S_SPIKEBALL1, // spawnstate S_SPIKEBALL1, // spawnstate
1000, // spawnhealth 1000, // spawnhealth
S_NULL, // seestate S_NULL, // seestate
@ -6604,7 +6627,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_NULL, // xdeathstate S_NULL, // xdeathstate
sfx_None, // deathsound sfx_None, // deathsound
10*FRACUNIT, // speed 10*FRACUNIT, // speed
4*FRACUNIT, // radius 12*FRACUNIT, // radius
8*FRACUNIT, // height 8*FRACUNIT, // height
0, // display offset 0, // display offset
DMG_SPIKE, // mass DMG_SPIKE, // mass
@ -8803,7 +8826,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
{ // MT_GFZTREE { // MT_GFZTREE
806, // doomednum 806, // doomednum
S_GFZTREE, // spawnstate S_GFZTREE, // spawnstate
1000, // spawnhealth 1000, // spawnhealth
S_NULL, // seestate S_NULL, // seestate
sfx_None, // seesound sfx_None, // seesound
@ -8830,7 +8853,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
{ // MT_GFZBERRYTREE { // MT_GFZBERRYTREE
807, // doomednum 807, // doomednum
S_GFZBERRYTREE, // spawnstate S_GFZBERRYTREE, // spawnstate
1000, // spawnhealth 1000, // spawnhealth
S_NULL, // seestate S_NULL, // seestate
sfx_None, // seesound sfx_None, // seesound
@ -8857,7 +8880,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
{ // MT_GFZCHERRYTREE { // MT_GFZCHERRYTREE
808, // doomednum 808, // doomednum
S_GFZCHERRYTREE, // spawnstate S_GFZCHERRYTREE, // spawnstate
1000, // spawnhealth 1000, // spawnhealth
S_NULL, // seestate S_NULL, // seestate
sfx_None, // seesound sfx_None, // seesound
@ -8884,7 +8907,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
{ // MT_CHECKERTREE { // MT_CHECKERTREE
810, // doomednum 810, // doomednum
S_CHECKERTREE, // spawnstate S_CHECKERTREE, // spawnstate
1000, // spawnhealth 1000, // spawnhealth
S_NULL, // seestate S_NULL, // seestate
sfx_None, // seesound sfx_None, // seesound
@ -8911,7 +8934,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
{ // MT_CHECKERSUNSETTREE { // MT_CHECKERSUNSETTREE
811, // doomednum 811, // doomednum
S_CHECKERSUNSETTREE, // spawnstate S_CHECKERSUNSETTREE, // spawnstate
1000, // spawnhealth 1000, // spawnhealth
S_NULL, // seestate S_NULL, // seestate
sfx_None, // seesound sfx_None, // seesound
@ -8938,7 +8961,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
{ // MT_FHZTREE { // MT_FHZTREE
812, // doomednum 812, // doomednum
S_FHZTREE, // spawnstate S_FHZTREE, // spawnstate
1000, // spawnhealth 1000, // spawnhealth
S_NULL, // seestate S_NULL, // seestate
sfx_None, // seesound sfx_None, // seesound
@ -8965,7 +8988,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
{ // MT_FHZPINKTREE { // MT_FHZPINKTREE
813, // doomednum 813, // doomednum
S_FHZPINKTREE, // spawnstate S_FHZPINKTREE, // spawnstate
1000, // spawnhealth 1000, // spawnhealth
S_NULL, // seestate S_NULL, // seestate
sfx_None, // seesound sfx_None, // seesound
@ -8992,7 +9015,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
{ // MT_POLYGONTREE { // MT_POLYGONTREE
814, // doomednum 814, // doomednum
S_POLYGONTREE, // spawnstate S_POLYGONTREE, // spawnstate
1000, // spawnhealth 1000, // spawnhealth
S_NULL, // seestate S_NULL, // seestate
sfx_None, // seesound sfx_None, // seesound
@ -9019,7 +9042,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
{ // MT_BUSHTREE { // MT_BUSHTREE
815, // doomednum 815, // doomednum
S_BUSHTREE, // spawnstate S_BUSHTREE, // spawnstate
1000, // spawnhealth 1000, // spawnhealth
S_NULL, // seestate S_NULL, // seestate
sfx_None, // seesound sfx_None, // seesound
@ -9046,7 +9069,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
{ // MT_BUSHREDTREE { // MT_BUSHREDTREE
816, // doomednum 816, // doomednum
S_BUSHREDTREE, // spawnstate S_BUSHREDTREE, // spawnstate
1000, // spawnhealth 1000, // spawnhealth
S_NULL, // seestate S_NULL, // seestate
sfx_None, // seesound sfx_None, // seesound
@ -9071,6 +9094,33 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_NULL // raisestate S_NULL // raisestate
}, },
{ // MT_SPRINGTREE
1600, // doomednum
S_SPRINGTREE, // 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
0, // speed
16*FRACUNIT, // radius
32*FRACUNIT, // height
0, // display offset
100, // mass
0, // damage
sfx_None, // activesound
MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags
S_NULL // raisestate
},
{ // MT_THZFLOWER1 { // MT_THZFLOWER1
900, // doomednum 900, // doomednum
S_THZFLOWERA, // spawnstate S_THZFLOWERA, // spawnstate
@ -14406,7 +14456,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
0, // painchance 0, // painchance
sfx_None, // painsound sfx_None, // painsound
S_ORBITEM1, // meleestate S_ORBITEM1, // meleestate
S_NULL, // missilestate S_ORBIDYA1, // missilestate
S_NULL, // deathstate S_NULL, // deathstate
S_NULL, // xdeathstate S_NULL, // xdeathstate
sfx_None, // deathsound sfx_None, // deathsound
@ -16131,11 +16181,11 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_NULL // raisestate S_NULL // raisestate
}, },
{ // MT_NIGHTSWING { // MT_NIGHTSCHIP
1706, // doomednum -1, // doomednum
S_NIGHTSWING, // spawnstate S_NIGHTSCHIP, // spawnstate
1000, // spawnhealth 1000, // spawnhealth
S_NIGHTSWING_XMAS, // seestate S_NULL, // seestate
sfx_None, // seesound sfx_None, // seesound
8, // reactiontime 8, // reactiontime
sfx_None, // attacksound sfx_None, // attacksound
@ -16146,14 +16196,41 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_NULL, // missilestate S_NULL, // missilestate
S_SPRK1, // deathstate S_SPRK1, // deathstate
S_NULL, // xdeathstate S_NULL, // xdeathstate
sfx_None, // deathsound sfx_ncchip, // deathsound
1, // speed 1, // speed
12*FRACUNIT, // radius 16*FRACUNIT, // radius
24*FRACUNIT, // height 24*FRACUNIT, // height
0, // display offset 0, // display offset
4, // mass 4, // mass
0, // damage 0, // damage
sfx_ncitem, // activesound sfx_None, // activesound
MF_SLIDEME|MF_SPECIAL|MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags
S_NIGHTSCHIPBONUS // raisestate
},
{ // MT_NIGHTSSTAR
-1, // doomednum
S_NIGHTSSTAR, // spawnstate
1000, // spawnhealth
S_NIGHTSSTARXMAS, // seestate
sfx_None, // seesound
8, // reactiontime
sfx_None, // attacksound
S_NULL, // painstate
0, // painchance
sfx_s3k33, // painsound
S_RING, // meleestate
S_NULL, // missilestate
S_SPRK1, // deathstate
S_NULL, // xdeathstate
sfx_ncitem, // deathsound
1, // speed
16*FRACUNIT, // radius
24*FRACUNIT, // height
0, // display offset
4, // mass
0, // damage
sfx_None, // activesound
MF_SLIDEME|MF_SPECIAL|MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags MF_SLIDEME|MF_SPECIAL|MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags
S_NULL // raisestate S_NULL // raisestate
}, },
@ -16320,7 +16397,6 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_NULL // raisestate S_NULL // raisestate
}, },
// the flicky that orbits the player when they have a Nightopian helper
{ // MT_NIGHTOPIANHELPER { // MT_NIGHTOPIANHELPER
-1, // doomednum -1, // doomednum
S_NIGHTOPIANHELPER1, // spawnstate S_NIGHTOPIANHELPER1, // spawnstate
@ -16348,6 +16424,60 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_NULL // raisestate S_NULL // raisestate
}, },
{ // MT_PIAN
1602, // doomednum
S_PIAN0, // spawnstate
1000, // spawnhealth
S_PIAN1, // seestate
sfx_None, // seesound
0, // reactiontime
sfx_None, // attacksound
S_NULL, // painstate
200, // painchance
sfx_None, // painsound
S_PIANSING, // meleestate
S_NULL, // missilestate
S_NULL, // deathstate
S_NULL, // xdeathstate
sfx_None, // deathsound
FRACUNIT, // speed
16*FRACUNIT, // radius
32*FRACUNIT, // height
0, // display offset
16, // mass
0, // damage
sfx_None, // activesound
MF_SLIDEME|MF_ENEMY|MF_SPECIAL|MF_SHOOTABLE|MF_NOGRAVITY, // flags
S_NULL // raisestate
},
{ // MT_SHLEEP
1601, // doomednum
S_SHLEEP1, // spawnstate
1, // spawnhealth
S_NULL, // seestate
sfx_None, // seesound
0, // reactiontime
sfx_None, // attacksound
S_NULL, // painstate
200, // painchance
sfx_None, // painsound
S_NULL, // meleestate
S_NULL, // missilestate
S_SHLEEPBOUNCE1, // deathstate
S_NULL, // xdeathstate
sfx_peww, // deathsound
0, // speed
24*FRACUNIT, // radius
32*FRACUNIT, // height
0, // display offset
16, // mass
0, // damage
sfx_None, // activesound
MF_SLIDEME|MF_ENEMY|MF_SPECIAL|MF_SHOOTABLE|MF_NOGRAVITY, // flags
S_NULL // raisestate
},
{ // MT_HIVEELEMENTAL { // MT_HIVEELEMENTAL
3190, // doomednum 3190, // doomednum
S_HIVEELEMENTAL_LOOK, // spawnstate S_HIVEELEMENTAL_LOOK, // spawnstate

View File

@ -337,10 +337,12 @@ typedef enum sprite
SPR_TOKE, // Special Stage Token SPR_TOKE, // Special Stage Token
SPR_RFLG, // Red CTF Flag SPR_RFLG, // Red CTF Flag
SPR_BFLG, // Blue CTF Flag SPR_BFLG, // Blue CTF Flag
SPR_NWNG, // NiGHTS Wing collectable item. SPR_SPHR, // Sphere
SPR_NCHP, // NiGHTS chip
SPR_NSTR, // NiGHTS star
SPR_EMBM, // Emblem SPR_EMBM, // Emblem
SPR_CEMG, // Chaos Emeralds SPR_CEMG, // Chaos Emeralds
SPR_EMER, // Emerald Hunt SPR_SHRD, // Emerald Hunt
// Interactive Objects // Interactive Objects
SPR_BBLS, // water bubble source SPR_BBLS, // water bubble source
@ -406,6 +408,7 @@ typedef enum sprite
SPR_TRE3, // Frozen Hillside SPR_TRE3, // Frozen Hillside
SPR_TRE4, // Polygon SPR_TRE4, // Polygon
SPR_TRE5, // Bush tree SPR_TRE5, // Bush tree
SPR_TRE6, // Spring tree
// Techno Hill Scenery // Techno Hill Scenery
SPR_THZP, // THZ1 Steam Flower SPR_THZP, // THZ1 Steam Flower
@ -611,6 +614,9 @@ typedef enum sprite
SPR_NSCR, // NiGHTS score sprite SPR_NSCR, // NiGHTS score sprite
SPR_NPRU, // Nights Powerups SPR_NPRU, // Nights Powerups
SPR_CAPS, // Capsule thingy for NiGHTS SPR_CAPS, // Capsule thingy for NiGHTS
SPR_IDYA, // Ideya
SPR_NTPN, // Nightopian
SPR_SHLP, // Shleep
// Secret badniks and hazards, shhhh // Secret badniks and hazards, shhhh
SPR_HIVE, SPR_HIVE,
@ -651,9 +657,6 @@ typedef enum sprite
SPR_ROIO, SPR_ROIO,
SPR_ROIP, SPR_ROIP,
// Blue Spheres
SPR_BBAL,
// Gravity Well Objects // Gravity Well Objects
SPR_GWLG, SPR_GWLG,
SPR_GWLR, SPR_GWLR,
@ -1149,6 +1152,7 @@ typedef enum state
// Egg Shield for Egg Guard // Egg Shield for Egg Guard
S_EGGSHIELD, S_EGGSHIELD,
S_EGGSHIELDBREAK,
// Green Snapper // Green Snapper
S_GSNAPPER_STND, S_GSNAPPER_STND,
@ -1717,17 +1721,21 @@ typedef enum state
S_RING, S_RING,
// Blue Sphere for special stages // Blue Sphere for special stages
S_BLUEBALL, S_BLUESPHERE,
S_BLUEBALLSPARK, S_BLUESPHEREBONUS,
S_BLUESPHERESPARK,
// NiGHTS Chip
S_NIGHTSCHIP,
S_NIGHTSCHIPBONUS,
// NiGHTS Star
S_NIGHTSSTAR,
S_NIGHTSSTARXMAS,
// Gravity Wells for special stages // Gravity Wells for special stages
S_GRAVWELLGREEN, S_GRAVWELLGREEN,
S_GRAVWELLGREEN2,
S_GRAVWELLGREEN3,
S_GRAVWELLRED, S_GRAVWELLRED,
S_GRAVWELLRED2,
S_GRAVWELLRED3,
// Individual Team Rings // Individual Team Rings
S_TEAMRING, S_TEAMRING,
@ -1776,8 +1784,10 @@ typedef enum state
S_CEMG6, S_CEMG6,
S_CEMG7, S_CEMG7,
// Emeralds (for hunt) // Emerald hunt shards
S_EMER1, S_SHRD1,
S_SHRD2,
S_SHRD3,
// Bubble Source // Bubble Source
S_BUBBLES1, S_BUBBLES1,
@ -2061,7 +2071,6 @@ typedef enum state
// Arrow // Arrow
S_ARROW, S_ARROW,
S_TEMPSHI,
S_ARROWBONK, S_ARROWBONK,
// Trapgoyle Demon fire // Trapgoyle Demon fire
@ -2091,6 +2100,7 @@ typedef enum state
S_POLYGONTREE, S_POLYGONTREE,
S_BUSHTREE, S_BUSHTREE,
S_BUSHREDTREE, S_BUSHREDTREE,
S_SPRINGTREE,
// THZ flowers // THZ flowers
S_THZFLOWERA, // THZ1 Steam flower S_THZFLOWERA, // THZ1 Steam flower
@ -3359,9 +3369,6 @@ typedef enum state
S_NIGHTSCORE90_2, S_NIGHTSCORE90_2,
S_NIGHTSCORE100_2, S_NIGHTSCORE100_2,
S_NIGHTSWING,
S_NIGHTSWING_XMAS,
// NiGHTS Paraloop Powerups // NiGHTS Paraloop Powerups
S_NIGHTSSUPERLOOP, S_NIGHTSSUPERLOOP,
S_NIGHTSDRILLREFILL, S_NIGHTSDRILLREFILL,
@ -3379,14 +3386,11 @@ typedef enum state
S_ORBITEM6, S_ORBITEM6,
S_ORBITEM7, S_ORBITEM7,
S_ORBITEM8, S_ORBITEM8,
S_ORBITEM9, S_ORBIDYA1,
S_ORBITEM10, S_ORBIDYA2,
S_ORBITEM11, S_ORBIDYA3,
S_ORBITEM12, S_ORBIDYA4,
S_ORBITEM13, S_ORBIDYA5,
S_ORBITEM14,
S_ORBITEM15,
S_ORBITEM16,
// "Flicky" helper // "Flicky" helper
S_NIGHTOPIANHELPER1, S_NIGHTOPIANHELPER1,
@ -3399,6 +3403,25 @@ typedef enum state
S_NIGHTOPIANHELPER8, S_NIGHTOPIANHELPER8,
S_NIGHTOPIANHELPER9, S_NIGHTOPIANHELPER9,
// Nightopian
S_PIAN0,
S_PIAN1,
S_PIAN2,
S_PIAN3,
S_PIAN4,
S_PIAN5,
S_PIAN6,
S_PIANSING,
// Shleep
S_SHLEEP1,
S_SHLEEP2,
S_SHLEEP3,
S_SHLEEP4,
S_SHLEEPBOUNCE1,
S_SHLEEPBOUNCE2,
S_SHLEEPBOUNCE3,
// Secret badniks and hazards, shhhh // Secret badniks and hazards, shhhh
S_HIVEELEMENTAL_LOOK, S_HIVEELEMENTAL_LOOK,
S_HIVEELEMENTAL_PREPARE1, S_HIVEELEMENTAL_PREPARE1,
@ -3694,7 +3717,7 @@ typedef enum mobj_type
// Collectible Items // Collectible Items
MT_RING, MT_RING,
MT_FLINGRING, // Lost ring MT_FLINGRING, // Lost ring
MT_BLUEBALL, // Blue sphere replacement for special stages MT_BLUESPHERE, // Blue sphere replacement for special stages
MT_REDTEAMRING, //Rings collectable by red team. MT_REDTEAMRING, //Rings collectable by red team.
MT_BLUETEAMRING, //Rings collectable by blue team. MT_BLUETEAMRING, //Rings collectable by blue team.
MT_TOKEN, // Special Stage token for special stage MT_TOKEN, // Special Stage token for special stage
@ -3838,6 +3861,7 @@ typedef enum mobj_type
MT_POLYGONTREE, MT_POLYGONTREE,
MT_BUSHTREE, MT_BUSHTREE,
MT_BUSHREDTREE, MT_BUSHREDTREE,
MT_SPRINGTREE,
// Techno Hill Scenery // Techno Hill Scenery
MT_THZFLOWER1, MT_THZFLOWER1,
@ -4150,7 +4174,8 @@ typedef enum mobj_type
MT_HOOPCOLLIDE, // Collision detection for NiGHTS hoops MT_HOOPCOLLIDE, // Collision detection for NiGHTS hoops
MT_HOOPCENTER, // Center of a hoop MT_HOOPCENTER, // Center of a hoop
MT_NIGHTSCORE, MT_NIGHTSCORE,
MT_NIGHTSWING, MT_NIGHTSCHIP, // NiGHTS Chip
MT_NIGHTSSTAR, // NiGHTS Star
MT_NIGHTSSUPERLOOP, MT_NIGHTSSUPERLOOP,
MT_NIGHTSDRILLREFILL, MT_NIGHTSDRILLREFILL,
MT_NIGHTSHELPER, MT_NIGHTSHELPER,
@ -4158,6 +4183,8 @@ typedef enum mobj_type
MT_NIGHTSLINKFREEZE, MT_NIGHTSLINKFREEZE,
MT_EGGCAPSULE, MT_EGGCAPSULE,
MT_NIGHTOPIANHELPER, // the actual helper object that orbits you MT_NIGHTOPIANHELPER, // the actual helper object that orbits you
MT_PIAN, // decorative singing friend
MT_SHLEEP, // almost-decorative sleeping enemy
// Secret badniks and hazards, shhhh // Secret badniks and hazards, shhhh
MT_HIVEELEMENTAL, MT_HIVEELEMENTAL,

View File

@ -24,7 +24,7 @@ enum hud {
// NiGHTS mode // NiGHTS mode
hud_nightslink, hud_nightslink,
hud_nightsdrill, hud_nightsdrill,
hud_nightsrings, hud_nightsspheres,
hud_nightsscore, hud_nightsscore,
hud_nightstime, hud_nightstime,
hud_nightsrecords, hud_nightsrecords,

View File

@ -130,6 +130,8 @@ static int player_get(lua_State *L)
lua_pushangle(L, plr->drawangle); lua_pushangle(L, plr->drawangle);
else if (fastcmp(field,"rings")) else if (fastcmp(field,"rings"))
lua_pushinteger(L, plr->rings); lua_pushinteger(L, plr->rings);
else if (fastcmp(field,"spheres"))
lua_pushinteger(L, plr->spheres);
else if (fastcmp(field,"pity")) else if (fastcmp(field,"pity"))
lua_pushinteger(L, plr->pity); lua_pushinteger(L, plr->pity);
else if (fastcmp(field,"currentweapon")) else if (fastcmp(field,"currentweapon"))
@ -294,8 +296,8 @@ static int player_get(lua_State *L)
lua_pushinteger(L, plr->startedtime); lua_pushinteger(L, plr->startedtime);
else if (fastcmp(field,"finishedtime")) else if (fastcmp(field,"finishedtime"))
lua_pushinteger(L, plr->finishedtime); lua_pushinteger(L, plr->finishedtime);
else if (fastcmp(field,"finishedrings")) else if (fastcmp(field,"finishedspheres"))
lua_pushinteger(L, plr->finishedrings); lua_pushinteger(L, plr->finishedspheres);
else if (fastcmp(field,"marescore")) else if (fastcmp(field,"marescore"))
lua_pushinteger(L, plr->marescore); lua_pushinteger(L, plr->marescore);
else if (fastcmp(field,"lastmarescore")) else if (fastcmp(field,"lastmarescore"))
@ -396,6 +398,8 @@ static int player_set(lua_State *L)
plr->drawangle = luaL_checkangle(L, 3); plr->drawangle = luaL_checkangle(L, 3);
else if (fastcmp(field,"rings")) else if (fastcmp(field,"rings"))
plr->rings = (INT32)luaL_checkinteger(L, 3); plr->rings = (INT32)luaL_checkinteger(L, 3);
else if (fastcmp(field,"spheres"))
plr->spheres = (INT32)luaL_checkinteger(L, 3);
else if (fastcmp(field,"pity")) else if (fastcmp(field,"pity"))
plr->pity = (SINT8)luaL_checkinteger(L, 3); plr->pity = (SINT8)luaL_checkinteger(L, 3);
else if (fastcmp(field,"currentweapon")) else if (fastcmp(field,"currentweapon"))
@ -448,7 +452,7 @@ static int player_set(lua_State *L)
else if (fastcmp(field,"followitem")) else if (fastcmp(field,"followitem"))
plr->followitem = luaL_checkinteger(L, 3); plr->followitem = luaL_checkinteger(L, 3);
else if (fastcmp(field,"followmobj")) else if (fastcmp(field,"followmobj"))
plr->followmobj = *((mobj_t **)luaL_checkudata(L, 3, META_MOBJ)); P_SetTarget(&plr->followmobj, *((mobj_t **)luaL_checkudata(L, 3, META_MOBJ)));
else if (fastcmp(field,"actionspd")) else if (fastcmp(field,"actionspd"))
plr->actionspd = (INT32)luaL_checkinteger(L, 3); plr->actionspd = (INT32)luaL_checkinteger(L, 3);
else if (fastcmp(field,"mindash")) else if (fastcmp(field,"mindash"))
@ -570,8 +574,8 @@ static int player_set(lua_State *L)
plr->startedtime = (tic_t)luaL_checkinteger(L, 3); plr->startedtime = (tic_t)luaL_checkinteger(L, 3);
else if (fastcmp(field,"finishedtime")) else if (fastcmp(field,"finishedtime"))
plr->finishedtime = (tic_t)luaL_checkinteger(L, 3); plr->finishedtime = (tic_t)luaL_checkinteger(L, 3);
else if (fastcmp(field,"finishedrings")) else if (fastcmp(field,"finishedspheres"))
plr->finishedrings = (INT16)luaL_checkinteger(L, 3); plr->finishedspheres = (INT16)luaL_checkinteger(L, 3);
else if (fastcmp(field,"marescore")) else if (fastcmp(field,"marescore"))
plr->marescore = (UINT32)luaL_checkinteger(L, 3); plr->marescore = (UINT32)luaL_checkinteger(L, 3);
else if (fastcmp(field,"lastmarescore")) else if (fastcmp(field,"lastmarescore"))

View File

@ -728,7 +728,7 @@ void Command_Setrings_f(void)
// P_GivePlayerRings does value clamping // P_GivePlayerRings does value clamping
players[consoleplayer].rings = 0; players[consoleplayer].rings = 0;
P_GivePlayerRings(&players[consoleplayer], atoi(COM_Argv(1))); P_GivePlayerRings(&players[consoleplayer], atoi(COM_Argv(1)));
if (!G_IsSpecialStage(gamemap) || !useNightsSS) if (!G_IsSpecialStage(gamemap) || !(maptol & TOL_NIGHTS))
players[consoleplayer].totalring -= atoi(COM_Argv(1)); //undo totalring addition done in P_GivePlayerRings players[consoleplayer].totalring -= atoi(COM_Argv(1)); //undo totalring addition done in P_GivePlayerRings
G_SetGameModified(multiplayer); G_SetGameModified(multiplayer);
@ -1010,7 +1010,7 @@ void OP_NightsObjectplace(player_t *player)
mt->options = (UINT16)((player->mo->z - fheight)>>FRACBITS); mt->options = (UINT16)((player->mo->z - fheight)>>FRACBITS);
mt->angle = (INT16)(mt->angle+(INT16)((FixedInt(FixedDiv(temp*FRACUNIT, 360*(FRACUNIT/256))))<<8)); mt->angle = (INT16)(mt->angle+(INT16)((FixedInt(FixedDiv(temp*FRACUNIT, 360*(FRACUNIT/256))))<<8));
P_SpawnHoopsAndRings(mt); P_SpawnHoopsAndRings(mt, false);
} }
// This places a bumper! // This places a bumper!
@ -1024,26 +1024,26 @@ void OP_NightsObjectplace(player_t *player)
P_SpawnMapThing(mt); P_SpawnMapThing(mt);
} }
// This places a ring! // This places a sphere!
if (cmd->buttons & BT_WEAPONNEXT) if (cmd->buttons & BT_WEAPONNEXT)
{ {
player->pflags |= PF_ATTACKDOWN; player->pflags |= PF_ATTACKDOWN;
if (!OP_HeightOkay(player, false)) if (!OP_HeightOkay(player, false))
return; return;
mt = OP_CreateNewMapThing(player, (UINT16)mobjinfo[MT_RING].doomednum, false); mt = OP_CreateNewMapThing(player, (UINT16)mobjinfo[MT_BLUESPHERE].doomednum, false);
P_SpawnHoopsAndRings(mt); P_SpawnHoopsAndRings(mt, false);
} }
// This places a wing item! // This places a ring!
if (cmd->buttons & BT_WEAPONPREV) if (cmd->buttons & BT_WEAPONPREV)
{ {
player->pflags |= PF_ATTACKDOWN; player->pflags |= PF_ATTACKDOWN;
if (!OP_HeightOkay(player, false)) if (!OP_HeightOkay(player, false))
return; return;
mt = OP_CreateNewMapThing(player, (UINT16)mobjinfo[MT_NIGHTSWING].doomednum, false); mt = OP_CreateNewMapThing(player, (UINT16)mobjinfo[MT_RING].doomednum, false);
P_SpawnHoopsAndRings(mt); P_SpawnHoopsAndRings(mt, false);
} }
// This places a custom object as defined in the console cv_mapthingnum. // This places a custom object as defined in the console cv_mapthingnum.
@ -1077,12 +1077,12 @@ void OP_NightsObjectplace(player_t *player)
if (mt->type == 300 // Ring if (mt->type == 300 // Ring
|| mt->type == 308 || mt->type == 309 // Team Rings || mt->type == 308 || mt->type == 309 // Team Rings
|| mt->type == 1706 // Nights Wing || mt->type == 1706 // Sphere
|| (mt->type >= 600 && mt->type <= 609) // Placement patterns || (mt->type >= 600 && mt->type <= 609) // Placement patterns
|| mt->type == 1705 || mt->type == 1713 // NiGHTS Hoops || mt->type == 1705 || mt->type == 1713 // NiGHTS Hoops
|| mt->type == 1800) // Mario Coin || mt->type == 1800) // Mario Coin
{ {
P_SpawnHoopsAndRings(mt); P_SpawnHoopsAndRings(mt, false);
} }
else else
P_SpawnMapThing(mt); P_SpawnMapThing(mt);
@ -1227,7 +1227,7 @@ void OP_ObjectplaceMovement(player_t *player)
|| mt->type == 1705 || mt->type == 1713 // NiGHTS Hoops || mt->type == 1705 || mt->type == 1713 // NiGHTS Hoops
|| mt->type == 1800) // Mario Coin || mt->type == 1800) // Mario Coin
{ {
P_SpawnHoopsAndRings(mt); P_SpawnHoopsAndRings(mt, false);
} }
else else
P_SpawnMapThing(mt); P_SpawnMapThing(mt);

View File

@ -8604,10 +8604,12 @@ void A_OrbitNights(mobj_t* actor)
return; return;
#endif #endif
if (!actor->target || !actor->target->player || if (!actor->target
!(actor->target->player->powers[pw_carry] == CR_NIGHTSMODE) || !actor->target->player->nightstime || (actor->target->player &&
// if NiGHTS special stage and not NiGHTSmode.
(((maptol & TOL_NIGHTS) && G_IsSpecialStage(gamemap) && !(actor->target->player->powers[pw_carry] == CR_NIGHTSMODE))
// 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]))))
{ {
P_RemoveMobj(actor); P_RemoveMobj(actor);
return; return;
@ -8633,7 +8635,7 @@ void A_OrbitNights(mobj_t* actor)
} }
P_SetThingPosition(actor); P_SetThingPosition(actor);
if (ishelper) // Flash a helper that's about to be removed. if (ishelper && actor->target->player) // Flash a helper that's about to be removed.
{ {
if ((actor->target->player->powers[pw_nights_helper] < TICRATE) if ((actor->target->player->powers[pw_nights_helper] < TICRATE)
&& (actor->target->player->powers[pw_nights_helper] & 1)) && (actor->target->player->powers[pw_nights_helper] & 1))
@ -11185,7 +11187,7 @@ void A_FlameParticle(mobj_t *actor)
// //
// Description: Makes a pretty overlay (primarily for super/NiGHTS transformation). // Description: Makes a pretty overlay (primarily for super/NiGHTS transformation).
// //
// var1 = bit 1 = don't halt momentum, bit 2 = don't make fast, bit 3 = don't set tracer // var1 = bit 1 = bit 1 = don't make fast, bit 2 = don't set tracer
// var2 = unused // var2 = unused
// //
void A_FadeOverlay(mobj_t *actor) void A_FadeOverlay(mobj_t *actor)
@ -11199,13 +11201,10 @@ void A_FadeOverlay(mobj_t *actor)
return; return;
#endif #endif
if (!(locvar1 & 1))
actor->momx = actor->momy = actor->momz = 0;
fade = P_SpawnGhostMobj(actor); fade = P_SpawnGhostMobj(actor);
fade->frame = actor->frame; fade->frame = actor->frame;
if (!(locvar1 & 2)) if (!(locvar1 & 1))
{ {
fade->fuse = 15; fade->fuse = 15;
fade->flags2 |= MF2_BOSSNOTRAP; fade->flags2 |= MF2_BOSSNOTRAP;
@ -11213,7 +11212,7 @@ void A_FadeOverlay(mobj_t *actor)
else else
fade->fuse = 20; fade->fuse = 20;
if (!(locvar1 & 4)) if (!(locvar1 & 2))
P_SetTarget(&actor->tracer, fade); P_SetTarget(&actor->tracer, fade);
} }

View File

@ -23,6 +23,7 @@
#include "hu_stuff.h" #include "hu_stuff.h"
#include "lua_hook.h" #include "lua_hook.h"
#include "m_cond.h" // unlockables, emblems, etc #include "m_cond.h" // unlockables, emblems, etc
#include "p_setup.h"
#include "m_cheat.h" // objectplace #include "m_cheat.h" // objectplace
#include "m_misc.h" #include "m_misc.h"
#include "v_video.h" // video flags for CEchos #include "v_video.h" // video flags for CEchos
@ -471,40 +472,49 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
/* FALLTHRU */ /* FALLTHRU */
case MT_RING: case MT_RING:
case MT_FLINGRING: case MT_FLINGRING:
if (!(P_CanPickupItem(player, false)))
return;
special->momx = special->momy = special->momz = 0;
P_GivePlayerRings(player, 1);
if ((maptol & TOL_NIGHTS) && special->type != MT_FLINGRING)
P_DoNightsScore(player);
break;
case MT_COIN: case MT_COIN:
case MT_FLINGCOIN: case MT_FLINGCOIN:
if (!(P_CanPickupItem(player, false))) if (!(P_CanPickupItem(player, false)))
return; return;
special->momx = special->momy = 0; special->momx = special->momy = special->momz = 0;
P_GivePlayerRings(player, 1); P_GivePlayerRings(player, 1);
if ((maptol & TOL_NIGHTS) && special->type != MT_FLINGCOIN) if ((maptol & TOL_NIGHTS) && special->type != MT_FLINGRING && special->type != MT_FLINGCOIN)
P_DoNightsScore(player); P_DoNightsScore(player);
break; break;
case MT_BLUEBALL: case MT_BLUESPHERE:
if (!(P_CanPickupItem(player, false))) if (!(P_CanPickupItem(player, false)))
return; return;
P_GivePlayerRings(player, 1);
special->momx = special->momy = special->momz = 0; special->momx = special->momy = special->momz = 0;
special->destscale = FixedMul(8*FRACUNIT, special->scale); P_GivePlayerSpheres(player, 1);
special->destscale = ((player->powers[pw_carry] == CR_NIGHTSMODE) ? 4 : 2)*special->scale;
if (states[special->info->deathstate].tics > 0) if (states[special->info->deathstate].tics > 0)
special->scalespeed = FixedDiv(FixedDiv(special->destscale, special->scale), states[special->info->deathstate].tics<<FRACBITS); special->scalespeed = FixedDiv(FixedDiv(special->destscale, special->scale), states[special->info->deathstate].tics<<FRACBITS);
else else
special->scalespeed = 4*FRACUNIT/5; special->scalespeed = 4*FRACUNIT/5;
if (maptol & TOL_NIGHTS)
P_DoNightsScore(player);
break;
case MT_NIGHTSCHIP:
if (!(P_CanPickupItem(player, false)))
return;
special->momx = special->momy = special->momz = 0;
P_GivePlayerSpheres(player, 1);
if (maptol & TOL_NIGHTS)
P_DoNightsScore(player);
break;
case MT_NIGHTSSTAR:
if (!(P_CanPickupItem(player, false)))
return;
special->momx = special->momy = special->momz = 0;
if (maptol & TOL_NIGHTS) if (maptol & TOL_NIGHTS)
P_DoNightsScore(player); P_DoNightsScore(player);
break; break;
@ -562,7 +572,10 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
P_AddPlayerScore(player, 1000); P_AddPlayerScore(player, 1000);
if (gametype != GT_COOP || modeattacking) // score only? if (gametype != GT_COOP || modeattacking) // score only?
{
S_StartSound(toucher, sfx_chchng);
break; break;
}
tokenlist += special->health; tokenlist += special->health;
@ -574,10 +587,17 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
players->gotcontinue = true; players->gotcontinue = true;
if (P_IsLocalPlayer(player)) if (P_IsLocalPlayer(player))
S_StartSound(NULL, sfx_s3kac); S_StartSound(NULL, sfx_s3kac);
else
S_StartSound(toucher, sfx_chchng);
} }
else
S_StartSound(toucher, sfx_chchng);
} }
else else
{
token++; token++;
S_StartSound(toucher, sfx_token);
}
break; break;
@ -602,7 +622,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
players[i].exiting = (14*TICRATE)/5 + 1; players[i].exiting = (14*TICRATE)/5 + 1;
} }
S_StartSound(NULL, sfx_lvpass); //S_StartSound(NULL, sfx_lvpass);
} }
break; break;
@ -733,45 +753,71 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
// NiGHTS gameplay items and powerups // // NiGHTS gameplay items and powerups //
// ********************************** // // ********************************** //
case MT_NIGHTSDRONE: case MT_NIGHTSDRONE:
if (player->bot)
return;
if (player->exiting)
return;
if (player->bonustime)
{ {
if (G_IsSpecialStage(gamemap)) //After-mare bonus time/emerald reward in special stages. boolean spec = G_IsSpecialStage(gamemap);
{ if (player->bot)
// only allow the player with the emerald in-hand to leave.
if (toucher->tracer
&& toucher->tracer->type == MT_GOTEMERALD)
{
}
else // Make sure that SOMEONE has the emerald, at least!
{
for (i = 0; i < MAXPLAYERS; i++)
if (playeringame[i] && players[i].playerstate == PST_LIVE
&& players[i].mo->tracer
&& players[i].mo->tracer->type == MT_GOTEMERALD)
return;
// Well no one has an emerald, so exit anyway!
}
P_GiveEmerald(false);
// Don't play Ideya sound in special stage mode
}
else
S_StartSound(toucher, special->info->activesound);
}
else //Initial transformation. Don't allow second chances in special stages!
{
if (player->powers[pw_carry] == CR_NIGHTSMODE)
return; return;
if (player->exiting)
return;
if (player->bonustime)
{
if (spec) //After-mare bonus time/emerald reward in special stages.
{
// only allow the player with the emerald in-hand to leave.
if (toucher->tracer
&& toucher->tracer->type == MT_GOTEMERALD)
{}
else // Make sure that SOMEONE has the emerald, at least!
{
for (i = 0; i < MAXPLAYERS; i++)
if (playeringame[i] && players[i].playerstate == PST_LIVE
&& players[i].mo->tracer
&& players[i].mo->tracer->type == MT_GOTEMERALD)
return;
// Well no one has an emerald, so exit anyway!
}
P_GiveEmerald(false);
// Don't play Ideya sound in special stage mode
}
else
S_StartSound(toucher, special->info->activesound);
}
else //Initial transformation. Don't allow second chances in special stages!
{
if (player->powers[pw_carry] == CR_NIGHTSMODE)
return;
S_StartSound(toucher, sfx_supert); S_StartSound(toucher, sfx_supert);
}
P_SwitchSpheresBonusMode(false);
if (!(netgame || multiplayer) && !(player->powers[pw_carry] == CR_NIGHTSMODE))
P_SetTarget(&special->tracer, toucher);
P_NightserizePlayer(player, special->health); // Transform!
if (!spec)
{
if (toucher->tracer) // Move the ideya over to the drone!
{
mobj_t *hnext = special->hnext;
P_SetTarget(&special->hnext, toucher->tracer);
P_SetTarget(&special->hnext->hnext, hnext); // Buffalo buffalo Buffalo buffalo buffalo buffalo Buffalo buffalo.
P_SetTarget(&special->hnext->target, special);
P_SetTarget(&toucher->tracer, NULL);
if (hnext)
{
special->hnext->extravalue1 = (angle_t)(hnext->extravalue1 - 72*ANG1);
if (special->hnext->extravalue1 > hnext->extravalue1)
special->hnext->extravalue1 -= (72*ANG1)/special->hnext->extravalue1;
}
}
if (player->exiting) // ...then move it back?
{
mobj_t *hnext = special;
while ((hnext = hnext->hnext))
P_SetTarget(&hnext->target, toucher);
}
}
return;
} }
if (!(netgame || multiplayer) && !(player->powers[pw_carry] == CR_NIGHTSMODE))
P_SetTarget(&special->tracer, toucher);
P_NightserizePlayer(player, special->health); // Transform!
return;
case MT_NIGHTSLOOPHELPER: case MT_NIGHTSLOOPHELPER:
// One second delay // One second delay
if (special->fuse < toucher->fuse - TICRATE) if (special->fuse < toucher->fuse - TICRATE)
@ -876,8 +922,8 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
} }
} }
if (!(mo2->type == MT_NIGHTSWING || mo2->type == MT_RING || mo2->type == MT_COIN if (!(mo2->type == MT_RING || mo2->type == MT_COIN || mo2->type == MT_BLUESPHERE
|| mo2->type == MT_BLUEBALL || mo2->type == MT_NIGHTSCHIP || mo2->type == MT_NIGHTSSTAR
|| ((mo2->type == MT_EMBLEM) && (mo2->reactiontime & GE_NIGHTSPULL)))) || ((mo2->type == MT_EMBLEM) && (mo2->reactiontime & GE_NIGHTSPULL))))
continue; continue;
@ -903,16 +949,16 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
return; return;
if (G_IsSpecialStage(gamemap) && !player->exiting) if (G_IsSpecialStage(gamemap) && !player->exiting)
{ // In special stages, share rings. Everyone gives up theirs to the player who touched the capsule { // In special stages, share spheres. Everyone gives up theirs to the player who touched the capsule
for (i = 0; i < MAXPLAYERS; i++) for (i = 0; i < MAXPLAYERS; i++)
if (playeringame[i] && (&players[i] != player) && players[i].rings > 0) if (playeringame[i] && (&players[i] != player) && players[i].spheres > 0)
{ {
player->rings += players[i].rings; player->spheres += players[i].spheres;
players[i].rings = 0; players[i].spheres = 0;
} }
} }
if (player->rings <= 0 || player->exiting) if (player->spheres <= 0 || player->exiting)
return; return;
// Mark the player as 'pull into the capsule' // Mark the player as 'pull into the capsule'
@ -1120,17 +1166,6 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
HU_DoCEcho(M_GetText("\\\\\\\\\\\\\\\\Link Freeze")); HU_DoCEcho(M_GetText("\\\\\\\\\\\\\\\\Link Freeze"));
} }
break; break;
case MT_NIGHTSWING:
if (G_IsSpecialStage(gamemap) && useNightsSS)
{ // Pseudo-ring.
S_StartSound(toucher, special->info->painsound);
player->totalring++;
}
else
S_StartSound(toucher, special->info->activesound);
P_DoNightsScore(player);
break;
case MT_HOOPCOLLIDE: case MT_HOOPCOLLIDE:
// This produces a kind of 'domino effect' with the hoop's pieces. // This produces a kind of 'domino effect' with the hoop's pieces.
for (; special->hprev != NULL; special = special->hprev); // Move to the first sprite in the hoop for (; special->hprev != NULL; special = special->hprev); // Move to the first sprite in the hoop
@ -1496,12 +1531,6 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
player->pflags |= PF_JUMPSTASIS; player->pflags |= PF_JUMPSTASIS;
return; return;
case MT_SPECIALSPIKEBALL:
if (!useNightsSS && G_IsSpecialStage(gamemap)) // Only for old special stages
P_SpecialStageDamage(player, special, NULL);
else
P_DamageMobj(toucher, special, special, 1, 0);
return;
case MT_EGGMOBILE2_POGO: case MT_EGGMOBILE2_POGO:
// sanity checks // sanity checks
if (!special->target || !special->target->health) if (!special->target || !special->target->health)
@ -2070,8 +2099,8 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
if (inflictor && (inflictor->type == MT_SHELL || inflictor->type == MT_FIREBALL)) if (inflictor && (inflictor->type == MT_SHELL || inflictor->type == MT_FIREBALL))
P_SetTarget(&target->tracer, inflictor); P_SetTarget(&target->tracer, inflictor);
if (!useNightsSS && G_IsSpecialStage(gamemap) && target->player && sstimer > 6) if (!(maptol & TOL_NIGHTS) && G_IsSpecialStage(gamemap) && target->player && target->player->nightstime > 6)
sstimer = 6; // Just let P_Ticker take care of the rest. target->player->nightstime = 6; // Just let P_Ticker take care of the rest.
if (target->flags & (MF_ENEMY|MF_BOSS)) if (target->flags & (MF_ENEMY|MF_BOSS))
target->momx = target->momy = target->momz = 0; target->momx = target->momy = target->momz = 0;
@ -2633,20 +2662,10 @@ static inline void P_NiGHTSDamage(mobj_t *target, mobj_t *source)
player->drillmeter -= 5*20; player->drillmeter -= 5*20;
else else
{ {
if (source && source->player) if (player->nightstime > 5*TICRATE)
{ player->nightstime -= 5*TICRATE;
if (player->nightstime > 20*TICRATE)
player->nightstime -= 20*TICRATE;
else
player->nightstime = 1;
}
else else
{ player->nightstime = 1;
if (player->nightstime > 5*TICRATE)
player->nightstime -= 5*TICRATE;
else
player->nightstime = 1;
}
} }
if (player->pflags & PF_TRANSFERTOCLOSEST) if (player->pflags & PF_TRANSFERTOCLOSEST)
@ -2670,7 +2689,7 @@ static inline void P_NiGHTSDamage(mobj_t *target, mobj_t *source)
&& player->nightstime < 10*TICRATE) && player->nightstime < 10*TICRATE)
{ {
//S_StartSound(NULL, sfx_timeup); // that creepy "out of time" music from NiGHTS. Dummied out, as some on the dev team thought it wasn't Sonic-y enough (Mystic, notably). Uncomment to restore. -SH //S_StartSound(NULL, sfx_timeup); // that creepy "out of time" music from NiGHTS. Dummied out, as some on the dev team thought it wasn't Sonic-y enough (Mystic, notably). Uncomment to restore. -SH
S_ChangeMusicInternal("_drown",false); S_ChangeMusicInternal((((maptol & TOL_NIGHTS) && !G_IsSpecialStage(gamemap)) ? "_ntime" : "_drown"), false);
} }
} }
} }
@ -3000,11 +3019,13 @@ static void P_RingDamage(player_t *player, mobj_t *inflictor, mobj_t *source, IN
// P_SpecialStageDamage // P_SpecialStageDamage
// //
// Do old special stage-style damaging // Do old special stage-style damaging
// Removes 10 rings from the player, or knocks off their shield if they have one. // Removes 5 seconds from the player, or knocks off their shield if they have one.
// If they don't have anything, just knock the player back anyway (this doesn't kill them). // If they don't have anything, just knock the player back anyway (this doesn't kill them).
// //
void P_SpecialStageDamage(player_t *player, mobj_t *inflictor, mobj_t *source) void P_SpecialStageDamage(player_t *player, mobj_t *inflictor, mobj_t *source)
{ {
tic_t oldnightstime = player->nightstime;
if (player->powers[pw_invulnerability] || player->powers[pw_flashing] || player->powers[pw_super]) if (player->powers[pw_invulnerability] || player->powers[pw_flashing] || player->powers[pw_super])
return; return;
@ -3015,17 +3036,24 @@ void P_SpecialStageDamage(player_t *player, mobj_t *inflictor, mobj_t *source)
} }
else else
{ {
P_PlayRinglossSound(player->mo); S_StartSound(player->mo, sfx_nghurt);
if (player->rings >= 10) if (player->nightstime > 5*TICRATE)
player->rings -= 10; player->nightstime -= 5*TICRATE;
else else
player->rings = 0; player->nightstime = 0;
} }
P_DoPlayerPain(player, inflictor, source); P_DoPlayerPain(player, inflictor, source);
if (gametype == GT_CTF && player->gotflag & (GF_REDFLAG|GF_BLUEFLAG)) if (gametype == GT_CTF && player->gotflag & (GF_REDFLAG|GF_BLUEFLAG))
P_PlayerFlagBurst(player, false); P_PlayerFlagBurst(player, false);
if (oldnightstime > 10*TICRATE
&& player->nightstime < 10*TICRATE)
{
//S_StartSound(NULL, sfx_timeup); // that creepy "out of time" music from NiGHTS. Dummied out, as some on the dev team thought it wasn't Sonic-y enough (Mystic, notably). Uncomment to restore. -SH
S_ChangeMusicInternal((((maptol & TOL_NIGHTS) && !G_IsSpecialStage(gamemap)) ? "_ntime" : "_drown"), false);
}
} }
/** Damages an object, which may or may not be a player. /** Damages an object, which may or may not be a player.
@ -3175,6 +3203,12 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
return true; return true;
} }
if (G_IsSpecialStage(gamemap))
{
P_SpecialStageDamage(player, inflictor, source);
return true;
}
if (!force && inflictor && inflictor->flags & MF_FIRE) if (!force && inflictor && inflictor->flags & MF_FIRE)
{ {
if (player->powers[pw_shield] & SH_PROTECTFIRE) if (player->powers[pw_shield] & SH_PROTECTFIRE)

View File

@ -146,6 +146,7 @@ void P_SpawnShieldOrb(player_t *player);
void P_SwitchShield(player_t *player, UINT16 shieldtype); void P_SwitchShield(player_t *player, UINT16 shieldtype);
mobj_t *P_SpawnGhostMobj(mobj_t *mobj); mobj_t *P_SpawnGhostMobj(mobj_t *mobj);
void P_GivePlayerRings(player_t *player, INT32 num_rings); void P_GivePlayerRings(player_t *player, INT32 num_rings);
void P_GivePlayerSpheres(player_t *player, INT32 num_spheres);
void P_GivePlayerLives(player_t *player, INT32 numlives); void P_GivePlayerLives(player_t *player, INT32 numlives);
void P_GiveCoopLives(player_t *player, INT32 numlives, boolean sound); void P_GiveCoopLives(player_t *player, INT32 numlives, boolean sound);
UINT8 P_GetNextEmerald(void); UINT8 P_GetNextEmerald(void);

View File

@ -2513,7 +2513,9 @@ static boolean P_ZMovement(mobj_t *mo)
case MT_RING: // Ignore still rings case MT_RING: // Ignore still rings
case MT_COIN: case MT_COIN:
case MT_BLUEBALL: case MT_BLUESPHERE:
case MT_NIGHTSCHIP:
case MT_NIGHTSSTAR:
case MT_REDTEAMRING: case MT_REDTEAMRING:
case MT_BLUETEAMRING: case MT_BLUETEAMRING:
case MT_FLINGRING: case MT_FLINGRING:
@ -2550,10 +2552,6 @@ static boolean P_ZMovement(mobj_t *mo)
if (!(mo->momx || mo->momy || mo->momz)) if (!(mo->momx || mo->momy || mo->momz))
return true; return true;
break; break;
case MT_NIGHTSWING:
if (!(mo->momx || mo->momy || mo->momz))
return true;
break;
case MT_FLAMEJET: case MT_FLAMEJET:
case MT_VERTICALFLAMEJET: case MT_VERTICALFLAMEJET:
if (!(mo->flags & MF_BOUNCE)) if (!(mo->flags & MF_BOUNCE))
@ -7225,7 +7223,7 @@ void P_MobjThinker(mobj_t *mobj)
else if (mobj->health <= 0) // Dead things think differently than the living. else if (mobj->health <= 0) // Dead things think differently than the living.
switch (mobj->type) switch (mobj->type)
{ {
case MT_BLUEBALL: case MT_BLUESPHERE:
if ((mobj->tics>>2)+1 > 0 && (mobj->tics>>2)+1 <= tr_trans60) // tr_trans50 through tr_trans90, shifting once every second frame if ((mobj->tics>>2)+1 > 0 && (mobj->tics>>2)+1 <= tr_trans60) // tr_trans50 through tr_trans90, shifting once every second frame
mobj->frame = (NUMTRANSMAPS-((mobj->tics>>2)+1))<<FF_TRANSSHIFT; mobj->frame = (NUMTRANSMAPS-((mobj->tics>>2)+1))<<FF_TRANSSHIFT;
else // tr_trans60 otherwise else // tr_trans60 otherwise
@ -7590,7 +7588,7 @@ void P_MobjThinker(mobj_t *mobj)
P_SetTarget(&mobj->target, NULL); P_SetTarget(&mobj->target, NULL);
for (i = 0; i < MAXPLAYERS; i++) for (i = 0; i < MAXPLAYERS; i++)
if (playeringame[i] && players[i].mo if (playeringame[i] && players[i].mo
&& players[i].mare == mobj->threshold && players[i].rings > 0) && players[i].mare == mobj->threshold && players[i].spheres > 0)
{ {
fixed_t dist = P_AproxDistance(players[i].mo->x - mobj->x, players[i].mo->y - mobj->y); fixed_t dist = P_AproxDistance(players[i].mo->x - mobj->x, players[i].mo->y - mobj->y);
if (dist < shortest) if (dist < shortest)
@ -7775,8 +7773,8 @@ void P_MobjThinker(mobj_t *mobj)
} }
if (!bonustime) if (!bonustime)
{ {
mobj->flags &= ~MF_NOGRAVITY; /*mobj->flags &= ~MF_NOGRAVITY;
P_SetMobjState(mobj, S_NIGHTSDRONE1); P_SetMobjState(mobj, S_NIGHTSDRONE1);*/
mobj->flags2 |= MF2_DONTDRAW; mobj->flags2 |= MF2_DONTDRAW;
} }
} }
@ -7848,7 +7846,9 @@ void P_MobjThinker(mobj_t *mobj)
mobj->flags2 &= ~MF2_DONTDRAW; mobj->flags2 &= ~MF2_DONTDRAW;
} }
mobj->angle += ANG10; mobj->angle += ANG10;
if (mobj->z <= mobj->floorz) if (mobj->flags2 & MF2_DONTDRAW)
mobj->momz = 0;
else if (mobj->z <= mobj->floorz)
mobj->momz = 5*FRACUNIT; mobj->momz = 5*FRACUNIT;
} }
break; break;
@ -7881,7 +7881,9 @@ void P_MobjThinker(mobj_t *mobj)
break; break;
case MT_RING: case MT_RING:
case MT_COIN: case MT_COIN:
case MT_BLUEBALL: case MT_BLUESPHERE:
case MT_NIGHTSCHIP:
case MT_NIGHTSSTAR:
case MT_REDTEAMRING: case MT_REDTEAMRING:
case MT_BLUETEAMRING: case MT_BLUETEAMRING:
// No need to check water. Who cares? // No need to check water. Who cares?
@ -7899,10 +7901,6 @@ void P_MobjThinker(mobj_t *mobj)
else else
A_AttractChase(mobj); A_AttractChase(mobj);
break; break;
case MT_NIGHTSWING:
if (mobj->flags2 & MF2_NIGHTSPULL)
P_NightsItemChase(mobj);
break;
case MT_EMBLEM: case MT_EMBLEM:
if (mobj->flags2 & MF2_NIGHTSPULL) if (mobj->flags2 & MF2_NIGHTSPULL)
P_NightsItemChase(mobj); P_NightsItemChase(mobj);
@ -8025,7 +8023,7 @@ void P_MobjThinker(mobj_t *mobj)
{ {
mobj_t *missile; mobj_t *missile;
if (mobj->target->player && mobj->target->player->nightstime) if (mobj->target->player && mobj->target->player->powers[pw_carry] == CR_NIGHTSMODE)
{ {
fixed_t oldval = mobjinfo[mobj->extravalue1].speed; fixed_t oldval = mobjinfo[mobj->extravalue1].speed;
@ -8726,7 +8724,6 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
break; break;
case MT_RING: case MT_RING:
case MT_COIN: case MT_COIN:
case MT_BLUEBALL:
nummaprings++; nummaprings++;
default: default:
break; break;
@ -8861,7 +8858,6 @@ void P_RemoveMobj(mobj_t *mobj)
if (mobj->spawnpoint && if (mobj->spawnpoint &&
(mobj->type == MT_RING (mobj->type == MT_RING
|| mobj->type == MT_COIN || mobj->type == MT_COIN
|| mobj->type == MT_BLUEBALL
|| mobj->type == MT_REDTEAMRING || mobj->type == MT_REDTEAMRING
|| mobj->type == MT_BLUETEAMRING || mobj->type == MT_BLUETEAMRING
|| P_WeaponOrPanel(mobj->type)) || P_WeaponOrPanel(mobj->type))
@ -8881,7 +8877,7 @@ void P_RemoveMobj(mobj_t *mobj)
if (mobj->player && mobj->player->followmobj) if (mobj->player && mobj->player->followmobj)
{ {
P_RemoveMobj(mobj->player->followmobj); P_RemoveMobj(mobj->player->followmobj);
mobj->player->followmobj = NULL; P_SetTarget(&mobj->player->followmobj, NULL);
} }
mobj->health = 0; // Just because mobj->health = 0; // Just because
@ -9314,7 +9310,7 @@ void P_SpawnPlayer(INT32 playernum)
p->spectator = p->outofcoop = p->spectator = p->outofcoop =
(((multiplayer || netgame) && gametype == GT_COOP) // only question status in coop (((multiplayer || netgame) && gametype == GT_COOP) // only question status in coop
&& ((leveltime > 0 && ((leveltime > 0
&& ((G_IsSpecialStage(gamemap) && useNightsSS) // late join special stage && ((G_IsSpecialStage(gamemap) && (maptol & TOL_NIGHTS)) // late join special stage
|| (cv_coopstarposts.value == 2 && (p->jointime < 1 || p->outofcoop)))) // late join or die in new coop || (cv_coopstarposts.value == 2 && (p->jointime < 1 || p->outofcoop)))) // late join or die in new coop
|| (((cv_cooplives.value == 1) || !P_GetLives(p)) && p->lives <= 0))); // game over and can't redistribute lives || (((cv_cooplives.value == 1) || !P_GetLives(p)) && p->lives <= 0))); // game over and can't redistribute lives
} }
@ -9383,7 +9379,7 @@ void P_SpawnPlayer(INT32 playernum)
P_SetupStateAnimation(mobj, mobj->state); P_SetupStateAnimation(mobj, mobj->state);
mobj->health = 1; mobj->health = 1;
p->rings = 0; p->rings = p->spheres = 0;
p->playerstate = PST_LIVE; p->playerstate = PST_LIVE;
p->bonustime = false; p->bonustime = false;
@ -9402,6 +9398,22 @@ void P_SpawnPlayer(INT32 playernum)
mobj->radius = FixedMul(skins[p->skin].radius, mobj->scale); mobj->radius = FixedMul(skins[p->skin].radius, mobj->scale);
mobj->height = P_GetPlayerHeight(p); mobj->height = P_GetPlayerHeight(p);
if (!leveltime && ((maptol & TOL_NIGHTS) == TOL_NIGHTS) != (G_IsSpecialStage(gamemap))) // non-special NiGHTS stage or special non-NiGHTS stage
{
if (maptol & TOL_NIGHTS)
{
if (p == players) // this is totally the wrong place to do this aaargh.
{
mobj_t *idya = P_SpawnMobjFromMobj(mobj, 0, 0, mobj->height, MT_GOTEMERALD);
P_SetTarget(&idya->target, mobj);
P_SetMobjState(idya, mobjinfo[MT_GOTEMERALD].missilestate);
P_SetTarget(&mobj->tracer, idya);
}
}
else if (sstimer)
p->nightstime = sstimer;
}
// Spawn with a pity shield if necessary. // Spawn with a pity shield if necessary.
P_DoPityCheck(p); P_DoPityCheck(p);
} }
@ -9715,10 +9727,6 @@ void P_SpawnMapThing(mapthing_t *mthing)
return; return;
} }
if (!G_RingSlingerGametype() || !cv_specialrings.value)
if (P_WeaponOrPanel(i))
return; // Don't place weapons/panels in non-ringslinger modes
if (i == MT_EMERHUNT) if (i == MT_EMERHUNT)
{ {
// Emerald Hunt is Coop only. // Emerald Hunt is Coop only.
@ -9752,6 +9760,10 @@ void P_SpawnMapThing(mapthing_t *mthing)
if ((mobjinfo[i].flags & MF_ENEMY) || (mobjinfo[i].flags & MF_BOSS)) if ((mobjinfo[i].flags & MF_ENEMY) || (mobjinfo[i].flags & MF_BOSS))
return; return;
if (!G_RingSlingerGametype() || !cv_specialrings.value)
if (P_WeaponOrPanel(i))
return; // Don't place weapons/panels in non-ringslinger modes
// Altering monitor spawns via cvars // Altering monitor spawns via cvars
// If MF_GRENADEBOUNCE is set in the monitor's info, // If MF_GRENADEBOUNCE is set in the monitor's info,
// skip this step. (Used for gold monitors) // skip this step. (Used for gold monitors)
@ -10754,8 +10766,9 @@ ML_EFFECT4 : Don't clip inside the ground
mthing->mobj = mobj; mthing->mobj = mobj;
} }
void P_SpawnHoopsAndRings(mapthing_t *mthing) void P_SpawnHoopsAndRings(mapthing_t *mthing, boolean bonustime)
{ {
mobjtype_t ringthing = MT_RING;
mobj_t *mobj = NULL; mobj_t *mobj = NULL;
INT32 r, i; INT32 r, i;
fixed_t x, y, z, finalx, finaly, finalz; fixed_t x, y, z, finalx, finaly, finalz;
@ -11034,59 +11047,26 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing)
return; return;
} }
// Wing logo item.
else if (mthing->type == mobjinfo[MT_NIGHTSWING].doomednum)
{
z =
#ifdef ESLOPE
sec->f_slope ? P_GetZAt(sec->f_slope, x, y) :
#endif
sec->floorheight;
if (mthing->options >> ZSHIFT)
z += ((mthing->options >> ZSHIFT) << FRACBITS);
mthing->z = (INT16)(z>>FRACBITS);
mobj = P_SpawnMobj(x, y, z, MT_NIGHTSWING);
mobj->spawnpoint = mthing;
if (G_IsSpecialStage(gamemap) && useNightsSS)
P_SetMobjState(mobj, mobj->info->meleestate);
else if (maptol & TOL_XMAS)
P_SetMobjState(mobj, mobj->info->seestate);
mobj->angle = FixedAngle(mthing->angle*FRACUNIT);
mobj->flags2 |= MF2_AMBUSH;
mthing->mobj = mobj;
}
// All manners of rings and coins // All manners of rings and coins
else if (mthing->type == mobjinfo[MT_RING].doomednum || mthing->type == mobjinfo[MT_COIN].doomednum || else if (mthing->type == mobjinfo[MT_RING].doomednum || mthing->type == mobjinfo[MT_COIN].doomednum ||
mthing->type == mobjinfo[MT_REDTEAMRING].doomednum || mthing->type == mobjinfo[MT_BLUETEAMRING].doomednum) mthing->type == mobjinfo[MT_REDTEAMRING].doomednum || mthing->type == mobjinfo[MT_BLUETEAMRING].doomednum ||
mthing->type == mobjinfo[MT_BLUESPHERE].doomednum)
{ {
mobjtype_t ringthing = MT_RING;
// No rings in Ultimate!
if (ultimatemode && !(G_IsSpecialStage(gamemap) || maptol & TOL_NIGHTS))
return;
// Which ringthing to use // Which ringthing to use
switch (mthing->type) if (mthing->type == mobjinfo[MT_COIN].doomednum)
{ ringthing = MT_COIN;
case 1800: else if (mthing->type == mobjinfo[MT_REDTEAMRING].doomednum) // No team rings in non-CTF
ringthing = MT_COIN; ringthing = (gametype == GT_CTF) ? MT_REDTEAMRING : MT_RING;
break; else if (mthing->type == mobjinfo[MT_BLUETEAMRING].doomednum) // Ditto
case 308: // No team rings in non-CTF ringthing = (gametype == GT_CTF) ? MT_BLUETEAMRING : MT_RING;
ringthing = (gametype == GT_CTF) ? MT_REDTEAMRING : MT_RING; else if (mthing->type == mobjinfo[MT_BLUESPHERE].doomednum)
break; ringthing = MT_BLUESPHERE;
case 309: // No team rings in non-CTF
ringthing = (gametype == GT_CTF) ? MT_BLUETEAMRING : MT_RING; if ((maptol & TOL_NIGHTS) && !G_IsSpecialStage(gamemap))
break; ringthing = ((ringthing == MT_BLUESPHERE) ? MT_NIGHTSCHIP : MT_NIGHTSSTAR);
default: else if (ringthing != MT_BLUESPHERE && ultimatemode)
// Spawn rings as blue spheres in special stages, ala S3+K. return; // No rings in Ultimate!
if (G_IsSpecialStage(gamemap) && useNightsSS)
ringthing = MT_BLUEBALL;
break;
}
// Set proper height // Set proper height
if (mthing->options & MTF_OBJECTFLIP) if (mthing->options & MTF_OBJECTFLIP)
@ -11130,8 +11110,14 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing)
} }
mobj->angle = FixedAngle(mthing->angle*FRACUNIT); mobj->angle = FixedAngle(mthing->angle*FRACUNIT);
mobj->flags2 |= MF2_AMBUSH;
mthing->mobj = mobj; mthing->mobj = mobj;
if (mthing->options & MTF_AMBUSH)
mobj->flags2 |= MF2_AMBUSH;
if (bonustime && (ringthing == MT_BLUESPHERE || ringthing == MT_NIGHTSCHIP))
P_SetMobjState(mobj, mobj->info->raisestate);
else if ((maptol & TOL_XMAS) && (ringthing == MT_NIGHTSSTAR))
P_SetMobjState(mobj, mobj->info->seestate);
} }
// *** // ***
// Special placement patterns // Special placement patterns
@ -11141,17 +11127,13 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing)
else if (mthing->type == 600 || mthing->type == 601) else if (mthing->type == 600 || mthing->type == 601)
{ {
INT32 dist = 64*FRACUNIT; INT32 dist = 64*FRACUNIT;
mobjtype_t ringthing = MT_RING;
if (mthing->type == 601) if (mthing->type == 601)
dist = 128*FRACUNIT; dist = 128*FRACUNIT;
// No rings in Ultimate! if ((maptol & TOL_NIGHTS) && !G_IsSpecialStage(gamemap))
if (ultimatemode && !(G_IsSpecialStage(gamemap) || maptol & TOL_NIGHTS)) ringthing = MT_NIGHTSSTAR;
return; else if (ultimatemode)
return; // No rings in Ultimate!
// Spawn rings as blue spheres in special stages, ala S3+K.
if (G_IsSpecialStage(gamemap) && useNightsSS)
ringthing = MT_BLUEBALL;
for (r = 1; r <= 5; r++) for (r = 1; r <= 5; r++)
{ {
@ -11187,31 +11169,30 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing)
mobj->angle = FixedAngle(mthing->angle*FRACUNIT); mobj->angle = FixedAngle(mthing->angle*FRACUNIT);
if (mthing->options & MTF_AMBUSH) if (mthing->options & MTF_AMBUSH)
mobj->flags2 |= MF2_AMBUSH; mobj->flags2 |= MF2_AMBUSH;
if ((maptol & TOL_XMAS) && (ringthing == MT_NIGHTSSTAR))
P_SetMobjState(mobj, mobj->info->seestate);
} }
} }
// Diagonal rings (handles both types) // Diagonal rings (handles both types)
else if (mthing->type == 602 || mthing->type == 603) // Diagonal rings (5) else if (mthing->type == 602 || mthing->type == 603) // Diagonal rings (5)
{ {
angle_t angle = FixedAngle(mthing->angle*FRACUNIT);
mobjtype_t ringthing = MT_RING;
INT32 iterations = 5; INT32 iterations = 5;
if (mthing->type == 603) if (mthing->type == 603)
iterations = 10; iterations = 10;
// No rings in Ultimate! if ((maptol & TOL_NIGHTS) && !G_IsSpecialStage(gamemap))
if (ultimatemode && !(G_IsSpecialStage(gamemap) || maptol & TOL_NIGHTS)) ringthing = MT_NIGHTSSTAR;
return; else if (ultimatemode)
return; // No rings in Ultimate!
// Spawn rings as blue spheres in special stages, ala S3+K. closestangle = FixedAngle(mthing->angle*FRACUNIT);
if (G_IsSpecialStage(gamemap) && useNightsSS) fa = (closestangle >> ANGLETOFINESHIFT);
ringthing = MT_BLUEBALL;
angle >>= ANGLETOFINESHIFT;
for (r = 1; r <= iterations; r++) for (r = 1; r <= iterations; r++)
{ {
x += FixedMul(64*FRACUNIT, FINECOSINE(angle)); x += FixedMul(64*FRACUNIT, FINECOSINE(fa));
y += FixedMul(64*FRACUNIT, FINESINE(angle)); y += FixedMul(64*FRACUNIT, FINESINE(fa));
if (mthing->options & MTF_OBJECTFLIP) if (mthing->options & MTF_OBJECTFLIP)
{ {
@ -11242,9 +11223,12 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing)
mobj->flags2 |= MF2_OBJECTFLIP; mobj->flags2 |= MF2_OBJECTFLIP;
} }
mobj->angle = FixedAngle(mthing->angle*FRACUNIT); mobj->angle = closestangle;
if (mthing->options & MTF_AMBUSH) if (mthing->options & MTF_AMBUSH)
mobj->flags2 |= MF2_AMBUSH; mobj->flags2 |= MF2_AMBUSH;
if ((maptol & TOL_XMAS) && (ringthing == MT_NIGHTSSTAR))
P_SetMobjState(mobj, mobj->info->seestate);
} }
} }
// Rings of items (all six of them) // Rings of items (all six of them)
@ -11252,7 +11236,6 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing)
{ {
INT32 numitems = 8; INT32 numitems = 8;
INT32 size = 96*FRACUNIT; INT32 size = 96*FRACUNIT;
mobjtype_t itemToSpawn = MT_NIGHTSWING;
if (mthing->type & 1) if (mthing->type & 1)
{ {
@ -11277,30 +11260,24 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing)
{ {
case 604: case 604:
case 605: case 605:
itemToSpawn = MT_RING; ringthing = MT_BLUESPHERE;
break; break;
case 608: case 608:
case 609: case 609:
itemToSpawn = (i & 1) ? MT_NIGHTSWING : MT_RING; ringthing = (i & 1) ? MT_RING : MT_BLUESPHERE;
break; break;
case 606: case 606:
case 607: case 607:
itemToSpawn = MT_NIGHTSWING; ringthing = MT_RING;
break; break;
default: default:
break; break;
} }
// No rings in Ultimate! if ((maptol & TOL_NIGHTS) && !G_IsSpecialStage(gamemap))
if (itemToSpawn == MT_RING) ringthing = ((ringthing == MT_BLUESPHERE) ? MT_NIGHTSCHIP : MT_NIGHTSSTAR);
{ else if (ringthing == MT_RING && ultimatemode)
if (ultimatemode && !(G_IsSpecialStage(gamemap) || (maptol & TOL_NIGHTS))) continue; // No rings in Ultimate!
continue;
// Spawn rings as blue spheres in special stages, ala S3+K.
if (G_IsSpecialStage(gamemap) && useNightsSS)
itemToSpawn = MT_BLUEBALL;
}
fa = i*FINEANGLES/numitems; fa = i*FINEANGLES/numitems;
v[0] = FixedMul(FINECOSINE(fa),size); v[0] = FixedMul(FINECOSINE(fa),size);
@ -11315,16 +11292,23 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing)
finaly = y + v[1]; finaly = y + v[1];
finalz = z + v[2]; finalz = z + v[2];
mobj = P_SpawnMobj(finalx, finaly, finalz, itemToSpawn); mobj = P_SpawnMobj(finalx, finaly, finalz, ringthing);
mobj->z -= mobj->height/2; mobj->z -= mobj->height/2;
if (itemToSpawn == MT_NIGHTSWING) if (mthing->options & MTF_OBJECTFLIP)
{ {
if (G_IsSpecialStage(gamemap) && useNightsSS) mobj->eflags |= MFE_VERTICALFLIP;
P_SetMobjState(mobj, mobj->info->meleestate); mobj->flags2 |= MF2_OBJECTFLIP;
else if ((maptol & TOL_XMAS))
P_SetMobjState(mobj, mobj->info->seestate);
} }
mobj->angle = closestangle;
if (mthing->options & MTF_AMBUSH)
mobj->flags2 |= MF2_AMBUSH;
if (bonustime && (ringthing == MT_BLUESPHERE || ringthing == MT_NIGHTSCHIP))
P_SetMobjState(mobj, mobj->info->raisestate);
else if ((maptol & TOL_XMAS) && (ringthing == MT_NIGHTSSTAR))
P_SetMobjState(mobj, mobj->info->seestate);
} }
return; return;
} }

View File

@ -314,7 +314,7 @@ typedef struct mobj_s
mobjtype_t type; mobjtype_t type;
const mobjinfo_t *info; // &mobjinfo[mobj->type] const mobjinfo_t *info; // &mobjinfo[mobj->type]
INT32 health; // for player this is rings + 1 INT32 health; // for player this is rings + 1 -- no it isn't, not any more!!
// Movement direction, movement generation (zig-zagging). // Movement direction, movement generation (zig-zagging).
angle_t movedir; // dirtype_t 0-7; also used by Deton for up/down angle angle_t movedir; // dirtype_t 0-7; also used by Deton for up/down angle
@ -435,7 +435,7 @@ void P_MovePlayerToStarpost(INT32 playernum);
void P_AfterPlayerSpawn(INT32 playernum); void P_AfterPlayerSpawn(INT32 playernum);
void P_SpawnMapThing(mapthing_t *mthing); void P_SpawnMapThing(mapthing_t *mthing);
void P_SpawnHoopsAndRings(mapthing_t *mthing); void P_SpawnHoopsAndRings(mapthing_t *mthing, boolean bonustime);
void P_SpawnHoopOfSomething(fixed_t x, fixed_t y, fixed_t z, fixed_t radius, INT32 number, mobjtype_t type, angle_t rotangle); void P_SpawnHoopOfSomething(fixed_t x, fixed_t y, fixed_t z, fixed_t radius, INT32 number, mobjtype_t type, angle_t rotangle);
void P_SpawnPrecipitation(void); void P_SpawnPrecipitation(void);
void P_SpawnParaloop(fixed_t x, fixed_t y, fixed_t z, fixed_t radius, INT32 number, mobjtype_t type, statenum_t nstate, angle_t rotangle, boolean spawncenter); void P_SpawnParaloop(fixed_t x, fixed_t y, fixed_t z, fixed_t radius, INT32 number, mobjtype_t type, statenum_t nstate, angle_t rotangle, boolean spawncenter);

View File

@ -116,7 +116,8 @@ static void P_NetArchivePlayers(void)
WRITEANGLE(save_p, players[i].drawangle); WRITEANGLE(save_p, players[i].drawangle);
WRITEANGLE(save_p, players[i].awayviewaiming); WRITEANGLE(save_p, players[i].awayviewaiming);
WRITEINT32(save_p, players[i].awayviewtics); WRITEINT32(save_p, players[i].awayviewtics);
WRITEINT32(save_p, players[i].rings); WRITEINT16(save_p, players[i].rings);
WRITEINT16(save_p, players[i].spheres);
WRITESINT8(save_p, players[i].pity); WRITESINT8(save_p, players[i].pity);
WRITEINT32(save_p, players[i].currentweapon); WRITEINT32(save_p, players[i].currentweapon);
@ -201,7 +202,7 @@ static void P_NetArchivePlayers(void)
WRITEUINT32(save_p, players[i].marebegunat); WRITEUINT32(save_p, players[i].marebegunat);
WRITEUINT32(save_p, players[i].startedtime); WRITEUINT32(save_p, players[i].startedtime);
WRITEUINT32(save_p, players[i].finishedtime); WRITEUINT32(save_p, players[i].finishedtime);
WRITEINT16(save_p, players[i].finishedrings); WRITEINT16(save_p, players[i].finishedspheres);
WRITEUINT32(save_p, players[i].marescore); WRITEUINT32(save_p, players[i].marescore);
WRITEUINT32(save_p, players[i].lastmarescore); WRITEUINT32(save_p, players[i].lastmarescore);
WRITEUINT8(save_p, players[i].lastmare); WRITEUINT8(save_p, players[i].lastmare);
@ -303,7 +304,8 @@ static void P_NetUnArchivePlayers(void)
players[i].drawangle = READANGLE(save_p); players[i].drawangle = READANGLE(save_p);
players[i].awayviewaiming = READANGLE(save_p); players[i].awayviewaiming = READANGLE(save_p);
players[i].awayviewtics = READINT32(save_p); players[i].awayviewtics = READINT32(save_p);
players[i].rings = READINT32(save_p); players[i].rings = READINT16(save_p);
players[i].spheres = READINT16(save_p);
players[i].pity = READSINT8(save_p); players[i].pity = READSINT8(save_p);
players[i].currentweapon = READINT32(save_p); players[i].currentweapon = READINT32(save_p);
@ -388,7 +390,7 @@ static void P_NetUnArchivePlayers(void)
players[i].marebegunat = READUINT32(save_p); players[i].marebegunat = READUINT32(save_p);
players[i].startedtime = READUINT32(save_p); players[i].startedtime = READUINT32(save_p);
players[i].finishedtime = READUINT32(save_p); players[i].finishedtime = READUINT32(save_p);
players[i].finishedrings = READINT16(save_p); players[i].finishedspheres = READINT16(save_p);
players[i].marescore = READUINT32(save_p); players[i].marescore = READUINT32(save_p);
players[i].lastmarescore = READUINT32(save_p); players[i].lastmarescore = READUINT32(save_p);
players[i].lastmare = READUINT8(save_p); players[i].lastmare = READUINT8(save_p);
@ -1986,7 +1988,7 @@ static void LoadMobjThinker(actionf_p1 thinker)
if (mapthings[spawnpointnum].type == 1705 || mapthings[spawnpointnum].type == 1713) // NiGHTS Hoop special case if (mapthings[spawnpointnum].type == 1705 || mapthings[spawnpointnum].type == 1713) // NiGHTS Hoop special case
{ {
P_SpawnHoopsAndRings(&mapthings[spawnpointnum]); P_SpawnHoopsAndRings(&mapthings[spawnpointnum], false);
return; return;
} }
@ -3261,7 +3263,7 @@ static void P_NetArchiveMisc(void)
WRITEUINT32(save_p, tokenlist); WRITEUINT32(save_p, tokenlist);
WRITEUINT32(save_p, leveltime); WRITEUINT32(save_p, leveltime);
WRITEUINT32(save_p, totalrings); WRITEUINT32(save_p, ssspheres);
WRITEINT16(save_p, lastmap); WRITEINT16(save_p, lastmap);
WRITEUINT16(save_p, emeralds); WRITEUINT16(save_p, emeralds);
@ -3338,7 +3340,7 @@ static inline boolean P_NetUnArchiveMisc(void)
// get the time // get the time
leveltime = READUINT32(save_p); leveltime = READUINT32(save_p);
totalrings = READUINT32(save_p); ssspheres = READUINT32(save_p);
lastmap = READINT16(save_p); lastmap = READINT16(save_p);
emeralds = READUINT16(save_p); emeralds = READUINT16(save_p);

View File

@ -808,7 +808,7 @@ void P_ReloadRings(void)
mapthing_t *hoopsToRespawn[4096]; mapthing_t *hoopsToRespawn[4096];
mapthing_t *mt = mapthings; mapthing_t *mt = mapthings;
// scan the thinkers to find rings/wings/hoops to unset // scan the thinkers to find rings/spheres/hoops to unset
for (th = thinkercap.next; th != &thinkercap; th = th->next) for (th = thinkercap.next; th != &thinkercap; th = th->next)
{ {
if (th->function.acp1 != (actionf_p1)P_MobjThinker) if (th->function.acp1 != (actionf_p1)P_MobjThinker)
@ -826,7 +826,8 @@ void P_ReloadRings(void)
} }
continue; continue;
} }
if (!(mo->type == MT_RING || mo->type == MT_NIGHTSWING || mo->type == MT_COIN || mo->type == MT_BLUEBALL)) if (!(mo->type == MT_RING || mo->type == MT_COIN || mo->type == MT_BLUESPHERE
|| mo->type == MT_NIGHTSCHIP || mo->type == MT_NIGHTSSTAR))
continue; continue;
// Don't auto-disintegrate things being pulled to us // Don't auto-disintegrate things being pulled to us
@ -840,9 +841,9 @@ void P_ReloadRings(void)
for (i = 0; i < nummapthings; i++, mt++) for (i = 0; i < nummapthings; i++, mt++)
{ {
// Notice an omission? We handle hoops differently. // Notice an omission? We handle hoops differently.
if (mt->type == 300 || mt->type == 308 || mt->type == 309 if (mt->type == mobjinfo[MT_RING].doomednum || mt->type == mobjinfo[MT_REDTEAMRING].doomednum || mt->type == mobjinfo[MT_BLUETEAMRING].doomednum
|| mt->type == 1706 || (mt->type >= 600 && mt->type <= 609) || mt->type == mobjinfo[MT_BLUESPHERE].doomednum || mt->type == mobjinfo[MT_COIN].doomednum
|| mt->type == 1800) || (mt->type >= 600 && mt->type <= 609)) // circles
{ {
mt->mobj = NULL; mt->mobj = NULL;
@ -850,12 +851,35 @@ void P_ReloadRings(void)
mt->z = (INT16)(R_PointInSubsector(mt->x << FRACBITS, mt->y << FRACBITS) mt->z = (INT16)(R_PointInSubsector(mt->x << FRACBITS, mt->y << FRACBITS)
->sector->floorheight>>FRACBITS); ->sector->floorheight>>FRACBITS);
P_SpawnHoopsAndRings (mt); P_SpawnHoopsAndRings(mt, true);
} }
} }
for (i = 0; i < numHoops; i++) for (i = 0; i < numHoops; i++)
{ {
P_SpawnHoopsAndRings(hoopsToRespawn[i]); P_SpawnHoopsAndRings(hoopsToRespawn[i], false);
}
}
void P_SwitchSpheresBonusMode(boolean bonustime)
{
mobj_t *mo;
thinker_t *th;
// scan the thinkers to find spheres to switch
for (th = thinkercap.next; th != &thinkercap; th = th->next)
{
if (th->function.acp1 != (actionf_p1)P_MobjThinker)
continue;
mo = (mobj_t *)th;
if (mo->type != MT_BLUESPHERE && mo->type != MT_NIGHTSCHIP)
continue;
if (!mo->health)
continue;
P_SetMobjState(mo, ((bonustime) ? mo->info->raisestate : mo->info->spawnstate));
} }
} }
@ -1025,20 +1049,22 @@ static void P_LoadThings(void)
} }
//decrement spawn values to the actual number because zero is valid. //decrement spawn values to the actual number because zero is valid.
if (emer1) if (emer1--)
P_SpawnMobj(huntemeralds[emer1 - 1]->x<<FRACBITS, P_SpawnMobj(huntemeralds[emer1]->x<<FRACBITS,
huntemeralds[emer1 - 1]->y<<FRACBITS, huntemeralds[emer1]->y<<FRACBITS,
huntemeralds[emer1 - 1]->z<<FRACBITS, MT_EMERHUNT); huntemeralds[emer1]->z<<FRACBITS, MT_EMERHUNT);
if (emer2) if (emer2--)
P_SpawnMobj(huntemeralds[emer2 - 1]->x<<FRACBITS, P_SetMobjStateNF(P_SpawnMobj(huntemeralds[emer2]->x<<FRACBITS,
huntemeralds[emer2 - 1]->y<<FRACBITS, huntemeralds[emer2]->y<<FRACBITS,
huntemeralds[emer2 - 1]->z<<FRACBITS, MT_EMERHUNT); huntemeralds[emer2]->z<<FRACBITS, MT_EMERHUNT),
mobjinfo[MT_EMERHUNT].spawnstate+1);
if (emer3) if (emer3--)
P_SpawnMobj(huntemeralds[emer3 - 1]->x<<FRACBITS, P_SetMobjStateNF(P_SpawnMobj(huntemeralds[emer3]->x<<FRACBITS,
huntemeralds[emer3 - 1]->y<<FRACBITS, huntemeralds[emer3]->y<<FRACBITS,
huntemeralds[emer3 - 1]->z<<FRACBITS, MT_EMERHUNT); huntemeralds[emer3]->z<<FRACBITS, MT_EMERHUNT),
mobjinfo[MT_EMERHUNT].spawnstate+2);
} }
if (metalrecording) // Metal Sonic gets no rings to distract him. if (metalrecording) // Metal Sonic gets no rings to distract him.
@ -1058,7 +1084,7 @@ static void P_LoadThings(void)
mt->z = (INT16)(R_PointInSubsector(mt->x << FRACBITS, mt->y << FRACBITS) mt->z = (INT16)(R_PointInSubsector(mt->x << FRACBITS, mt->y << FRACBITS)
->sector->floorheight>>FRACBITS); ->sector->floorheight>>FRACBITS);
P_SpawnHoopsAndRings (mt); P_SpawnHoopsAndRings(mt, false);
} }
} }
} }
@ -2298,7 +2324,7 @@ static void P_LevelInitStuff(void)
// circuit, race and competition stuff // circuit, race and competition stuff
circuitmap = false; circuitmap = false;
numstarposts = 0; numstarposts = 0;
totalrings = timeinmap = 0; ssspheres = timeinmap = 0;
// special stage // special stage
stagefailed = false; stagefailed = false;
@ -2334,6 +2360,7 @@ static void P_LevelInitStuff(void)
players[i].xtralife = players[i].deadtimer = players[i].numboxes = players[i].totalring = players[i].laps = 0; players[i].xtralife = players[i].deadtimer = players[i].numboxes = players[i].totalring = players[i].laps = 0;
players[i].rings = 0; players[i].rings = 0;
players[i].spheres = 0;
players[i].aiming = 0; players[i].aiming = 0;
players[i].pflags &= ~PF_GAMETYPEOVER; players[i].pflags &= ~PF_GAMETYPEOVER;
@ -2341,7 +2368,7 @@ static void P_LevelInitStuff(void)
players[i].timeshit = 0; players[i].timeshit = 0;
players[i].marescore = players[i].lastmarescore = players[i].maxlink = 0; players[i].marescore = players[i].lastmarescore = players[i].maxlink = 0;
players[i].startedtime = players[i].finishedtime = players[i].finishedrings = 0; players[i].startedtime = players[i].finishedtime = players[i].finishedspheres = 0;
players[i].lastmare = players[i].marebegunat = 0; players[i].lastmare = players[i].marebegunat = 0;
// Don't show anything // Don't show anything

View File

@ -72,6 +72,7 @@ void P_DeleteFlickies(INT16 i);
// Needed for NiGHTS // Needed for NiGHTS
void P_ReloadRings(void); void P_ReloadRings(void);
void P_SwitchSpheresBonusMode(boolean bonustime);
void P_DeleteGrades(INT16 i); void P_DeleteGrades(INT16 i);
void P_AddGradesForMare(INT16 i, UINT8 mare, char *gtext); void P_AddGradesForMare(INT16 i, UINT8 mare, char *gtext);
UINT8 P_GetGrade(UINT32 pscore, INT16 map, UINT8 mare); UINT8 P_GetGrade(UINT32 pscore, INT16 map, UINT8 mare);

View File

@ -2868,7 +2868,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
// Unlocked something? // Unlocked something?
if (M_UpdateUnlockablesAndExtraEmblems()) if (M_UpdateUnlockablesAndExtraEmblems())
{ {
S_StartSound(NULL, sfx_ncitem); S_StartSound(NULL, sfx_s3k68);
G_SaveGameData(); // only save if unlocked something G_SaveGameData(); // only save if unlocked something
} }
} }
@ -3527,7 +3527,7 @@ void P_ProcessSpecialSector(player_t *player, sector_t *sector, sector_t *rovers
if (player->exiting || player->bot) // Don't do anything for bots or players who have just finished if (player->exiting || player->bot) // Don't do anything for bots or players who have just finished
break; break;
if (!(player->powers[pw_shield] || player->rings > 0)) // Don't do anything if no shield or rings anyway if (!(player->powers[pw_shield] || player->spheres > 0)) // Don't do anything if no shield or spheres anyway
break; break;
P_SpecialStageDamage(player, NULL, NULL); P_SpecialStageDamage(player, NULL, NULL);
@ -3775,8 +3775,8 @@ DoneSection2:
case 2: // Special stage GOAL sector / Exit Sector / CTF Flag Return case 2: // Special stage GOAL sector / Exit Sector / CTF Flag Return
if (player->bot) if (player->bot)
break; break;
if (!useNightsSS && G_IsSpecialStage(gamemap) && sstimer > 6) if (!(maptol & TOL_NIGHTS) && G_IsSpecialStage(gamemap) && player->nightstime > 6)
sstimer = 6; // Just let P_Ticker take care of the rest. player->nightstime = 6; // Just let P_Ticker take care of the rest.
// Exit (for FOF exits; others are handled in P_PlayerThink in p_user.c) // Exit (for FOF exits; others are handled in P_PlayerThink in p_user.c)
{ {
@ -4643,7 +4643,7 @@ static void P_RunSpecialSectorCheck(player_t *player, sector_t *sector)
switch(GETSECSPECIAL(sector->special, 4)) switch(GETSECSPECIAL(sector->special, 4))
{ {
case 2: // Level Exit / GOAL Sector / Flag Return case 2: // Level Exit / GOAL Sector / Flag Return
if (!useNightsSS && G_IsSpecialStage(gamemap)) if (!(maptol & TOL_NIGHTS) && G_IsSpecialStage(gamemap))
{ {
// Special stage GOAL sector // Special stage GOAL sector
// requires touching floor. // requires touching floor.
@ -5502,7 +5502,7 @@ void P_InitSpecials(void)
// Defaults in case levels don't have them set. // Defaults in case levels don't have them set.
sstimer = 90*TICRATE + 6; sstimer = 90*TICRATE + 6;
totalrings = 1; ssspheres = 1;
CheckForBustableBlocks = CheckForBouncySector = CheckForQuicksand = CheckForMarioBlocks = CheckForFloatBob = CheckForReverseGravity = false; CheckForBustableBlocks = CheckForBouncySector = CheckForQuicksand = CheckForMarioBlocks = CheckForFloatBob = CheckForReverseGravity = false;
@ -5596,7 +5596,7 @@ void P_SpawnSpecials(INT32 fromnetsave)
{ {
case 10: // Time for special stage case 10: // Time for special stage
sstimer = (sector->floorheight>>FRACBITS) * TICRATE + 6; // Time to finish sstimer = (sector->floorheight>>FRACBITS) * TICRATE + 6; // Time to finish
totalrings = sector->ceilingheight>>FRACBITS; // Ring count for special stage ssspheres = sector->ceilingheight>>FRACBITS; // Ring count for special stage
break; break;
case 11: // Custom global gravity! case 11: // Custom global gravity!

View File

@ -424,7 +424,7 @@ void P_DoTeamscrambling(void)
static inline void P_DoSpecialStageStuff(void) static inline void P_DoSpecialStageStuff(void)
{ {
boolean inwater = false; boolean stillalive = false;
INT32 i; INT32 i;
// Can't drown in a special stage // Can't drown in a special stage
@ -436,68 +436,59 @@ static inline void P_DoSpecialStageStuff(void)
players[i].powers[pw_underwater] = players[i].powers[pw_spacetime] = 0; players[i].powers[pw_underwater] = players[i].powers[pw_spacetime] = 0;
} }
if (sstimer < 15*TICRATE+6 && sstimer > 7 && (mapheaderinfo[gamemap-1]->levelflags & LF_SPEEDMUSIC)) //if (sstimer < 15*TICRATE+6 && sstimer > 7 && (mapheaderinfo[gamemap-1]->levelflags & LF_SPEEDMUSIC))
S_SpeedMusic(1.4f); //S_SpeedMusic(1.4f);
if (sstimer < 7 && sstimer > 0) // The special stage time is up! if (sstimer && !objectplacing)
{ {
sstimer = 0; UINT16 countspheres = 0;
for (i = 0; i < MAXPLAYERS; i++)
{
if (playeringame[i])
{
players[i].exiting = (14*TICRATE)/5 + 1;
players[i].pflags &= ~PF_GLIDING;
}
if (i == consoleplayer)
S_StartSound(NULL, sfx_lose);
}
if (mapheaderinfo[gamemap-1]->levelflags & LF_SPEEDMUSIC)
S_SpeedMusic(1.0f);
stagefailed = true;
}
if (sstimer > 1) // As long as time isn't up...
{
UINT32 ssrings = 0;
// Count up the rings of all the players and see if // Count up the rings of all the players and see if
// they've collected the required amount. // they've collected the required amount.
for (i = 0; i < MAXPLAYERS; i++) for (i = 0; i < MAXPLAYERS; i++)
if (playeringame[i]) if (playeringame[i])
{ {
ssrings += players[i].rings; tic_t oldnightstime = players[i].nightstime;
countspheres += players[i].spheres;
// If in water, deplete timer 6x as fast. // If in water, deplete timer 6x as fast.
if ((players[i].mo->eflags & MFE_TOUCHWATER) if (players[i].mo->eflags & (MFE_TOUCHWATER|MFE_UNDERWATER))
|| (players[i].mo->eflags & MFE_UNDERWATER)) players[i].nightstime -= 5;
inwater = true; if (--players[i].nightstime > 6)
{
if (P_IsLocalPlayer(&players[i]) && oldnightstime > 10*TICRATE && players[i].nightstime <= 10*TICRATE)
S_ChangeMusicInternal("_drown", false);
stillalive = true;
}
else if (!players[i].exiting)
{
players[i].exiting = (14*TICRATE)/5 + 1;
players[i].pflags &= ~(PF_GLIDING|PF_BOUNCING);
players[i].nightstime = 0;
if (P_IsLocalPlayer(&players[i]))
S_StartSound(NULL, sfx_s3k66);
}
} }
if (ssrings >= totalrings && totalrings > 0) if (stillalive)
{ {
// Halt all the players if (countspheres >= ssspheres)
for (i = 0; i < MAXPLAYERS; i++) {
if (playeringame[i]) // Halt all the players
{ for (i = 0; i < MAXPLAYERS; i++)
players[i].mo->momx = players[i].mo->momy = 0; if (playeringame[i])
players[i].exiting = (14*TICRATE)/5 + 1; {
} players[i].mo->momx = players[i].mo->momy = 0;
players[i].exiting = (14*TICRATE)/5 + 1;
}
sstimer = 0; sstimer = 0;
P_GiveEmerald(true);
P_GiveEmerald(true); }
} }
else
// Decrement the timer
if (!objectplacing)
{ {
if (inwater) sstimer = 0;
sstimer -= 6; stagefailed = true;
else
sstimer--;
} }
} }
} }
@ -608,7 +599,7 @@ void P_Ticker(boolean run)
// Keep track of how long they've been playing! // Keep track of how long they've been playing!
totalplaytime++; totalplaytime++;
if (!useNightsSS && G_IsSpecialStage(gamemap)) if (!(maptol & TOL_NIGHTS) && G_IsSpecialStage(gamemap))
P_DoSpecialStageStuff(); P_DoSpecialStageStuff();
if (runemeraldmanager) if (runemeraldmanager)

View File

@ -283,22 +283,9 @@ boolean P_PlayerMoving(INT32 pnum)
// //
UINT8 P_GetNextEmerald(void) UINT8 P_GetNextEmerald(void)
{ {
if (!useNightsSS) // In order if (gamemap < sstage_start || gamemap > sstage_end)
{ return 0;
if (!(emeralds & EMERALD1)) return 0; return (UINT8)(gamemap - sstage_start);
if (!(emeralds & EMERALD2)) return 1;
if (!(emeralds & EMERALD3)) return 2;
if (!(emeralds & EMERALD4)) return 3;
if (!(emeralds & EMERALD5)) return 4;
if (!(emeralds & EMERALD6)) return 5;
return 6;
}
else // Depends on stage
{
if (gamemap < sstage_start || gamemap > sstage_end)
return 0;
return (UINT8)(gamemap - sstage_start);
}
} }
// //
@ -309,20 +296,20 @@ UINT8 P_GetNextEmerald(void)
// //
void P_GiveEmerald(boolean spawnObj) void P_GiveEmerald(boolean spawnObj)
{ {
INT32 i; UINT8 em = P_GetNextEmerald();
UINT8 em;
S_StartSound(NULL, sfx_cgot); // Got the emerald! S_StartSound(NULL, sfx_cgot); // Got the emerald!
em = P_GetNextEmerald();
emeralds |= (1 << em); emeralds |= (1 << em);
if (spawnObj) if (spawnObj && playeringame[consoleplayer])
{ {
for (i = 0; i < MAXPLAYERS; i++) // The Chaos Emerald begins to orbit us!
if (playeringame[i]) UINT8 em = P_GetNextEmerald();
P_SetMobjState(P_SpawnMobj(players[i].mo->x, players[i].mo->y, players[i].mo->z + players[i].mo->info->height, MT_GOTEMERALD), // Only give it to ONE person!
mobjinfo[MT_GOTEMERALD].spawnstate + em); mobj_t *emmo = P_SpawnMobjFromMobj(players[consoleplayer].mo, 0, 0, players[consoleplayer].mo->height, MT_GOTEMERALD);
P_SetTarget(&emmo->target, players[consoleplayer].mo);
P_SetMobjState(emmo, mobjinfo[MT_GOTEMERALD].meleestate + em);
P_SetTarget(&players[consoleplayer].mo->tracer, emmo);
} }
} }
@ -692,10 +679,10 @@ void P_NightserizePlayer(player_t *player, INT32 nighttime)
oldmare = player->mare; oldmare = player->mare;
if (P_TransferToNextMare(player) == false) if (!P_TransferToNextMare(player))
{ {
INT32 i; INT32 i;
INT32 total_rings = 0; INT32 total_spheres = 0;
P_SetTarget(&player->mo->target, NULL); P_SetTarget(&player->mo->target, NULL);
@ -703,7 +690,7 @@ void P_NightserizePlayer(player_t *player, INT32 nighttime)
{ {
for (i = 0; i < MAXPLAYERS; i++) for (i = 0; i < MAXPLAYERS; i++)
if (playeringame[i]/* && players[i].powers[pw_carry] == CR_NIGHTSMODE*/) if (playeringame[i]/* && players[i].powers[pw_carry] == CR_NIGHTSMODE*/)
total_rings += players[i].rings; total_spheres += players[i].spheres;
} }
for (i = 0; i < MAXPLAYERS; i++) for (i = 0; i < MAXPLAYERS; i++)
@ -716,13 +703,13 @@ void P_NightserizePlayer(player_t *player, INT32 nighttime)
players[i].lastmare = players[i].mare; players[i].lastmare = players[i].mare;
if (G_IsSpecialStage(gamemap)) if (G_IsSpecialStage(gamemap))
{ {
players[i].finishedrings = (INT16)total_rings; players[i].finishedspheres = (INT16)total_spheres;
P_AddPlayerScore(player, total_rings * 50); P_AddPlayerScore(player, total_spheres * 50);
} }
else else
{ {
players[i].finishedrings = (INT16)(players[i].rings); players[i].finishedspheres = (INT16)(players[i].spheres);
P_AddPlayerScore(&players[i], (players[i].rings) * 50); P_AddPlayerScore(&players[i], (players[i].spheres) * 50);
} }
// Add score to leaderboards now // Add score to leaderboards now
@ -733,20 +720,20 @@ void P_NightserizePlayer(player_t *player, INT32 nighttime)
players[i].lastmarescore = players[i].marescore; players[i].lastmarescore = players[i].marescore;
players[i].marescore = 0; players[i].marescore = 0;
players[i].rings = 0; players[i].spheres = 0;
P_DoPlayerExit(&players[i]); P_DoPlayerExit(&players[i]);
} }
} }
else if (oldmare != player->mare) else if (oldmare != player->mare)
{ {
/// \todo Handle multi-mare special stages. /// \todo Handle multi-mare special stages.
// Ring bonus // Spheres bonus
P_AddPlayerScore(player, (player->rings) * 50); P_AddPlayerScore(player, (player->spheres) * 50);
player->lastmare = (UINT8)oldmare; player->lastmare = (UINT8)oldmare;
player->texttimer = 4*TICRATE; player->texttimer = 4*TICRATE;
player->textvar = 4; // Score and grades player->textvar = 4; // Score and grades
player->finishedrings = (INT16)(player->rings); player->finishedspheres = (INT16)(player->spheres);
// Add score to temp leaderboards // Add score to temp leaderboards
if (!(netgame||multiplayer) && P_IsLocalPlayer(player)) if (!(netgame||multiplayer) && P_IsLocalPlayer(player))
@ -757,7 +744,7 @@ void P_NightserizePlayer(player_t *player, INT32 nighttime)
player->marescore = 0; player->marescore = 0;
player->marebegunat = leveltime; player->marebegunat = leveltime;
player->rings = 0; player->spheres = 0;
} }
else else
{ {
@ -857,7 +844,7 @@ void P_DoPlayerPain(player_t *player, mobj_t *source, mobj_t *inflictor)
} }
else else
{ {
ang = R_PointToAngle2(player->mo->momx, player->mo->momy, 0, 0); ang = ((player->mo->momx || player->mo->momy) ? R_PointToAngle2(player->mo->momx, player->mo->momy, 0, 0) : player->drawangle);
fallbackspeed = FixedMul(4*FRACUNIT, player->mo->scale); fallbackspeed = FixedMul(4*FRACUNIT, player->mo->scale);
} }
@ -923,8 +910,7 @@ void P_GivePlayerRings(player_t *player, INT32 num_rings)
player->rings += num_rings; player->rings += num_rings;
if (!G_IsSpecialStage(gamemap) || !useNightsSS) player->totalring += num_rings;
player->totalring += num_rings;
// Can only get up to 9999 rings, sorry! // Can only get up to 9999 rings, sorry!
if (player->rings > 9999) if (player->rings > 9999)
@ -956,6 +942,26 @@ void P_GivePlayerRings(player_t *player, INT32 num_rings)
} }
} }
void P_GivePlayerSpheres(player_t *player, INT32 num_spheres)
{
if (!player)
return;
if (player->bot)
player = &players[consoleplayer];
if (!player->mo)
return;
player->spheres += num_spheres;
// Can only get up to 9999 spheres, sorry!
if (player->spheres > 9999)
player->spheres = 9999;
else if (player->spheres < 0)
player->spheres = 0;
}
// //
// P_GivePlayerLives // P_GivePlayerLives
// //
@ -1035,10 +1041,11 @@ void P_DoSuperTransformation(player_t *player, boolean giverings)
S_StartSound(NULL, sfx_supert); //let all players hear it -mattw_cfi S_StartSound(NULL, sfx_supert); //let all players hear it -mattw_cfi
player->mo->momx = player->mo->momy = player->mo->momz = player->cmomx = player->cmomy = player->rmomx = player->rmomy = 0;
// Transformation animation // Transformation animation
P_SetPlayerMobjState(player->mo, S_PLAY_SUPER_TRANS1); P_SetPlayerMobjState(player->mo, S_PLAY_SUPER_TRANS1);
player->mo->momx = player->mo->momy = player->mo->momz = 0;
player->pflags |= PF_NOJUMPDAMAGE; // just to avoid recurling but still allow thok player->pflags |= PF_NOJUMPDAMAGE; // just to avoid recurling but still allow thok
if (giverings) if (giverings)
@ -3793,12 +3800,15 @@ static void P_DoSuperStuff(player_t *player)
// //
boolean P_SuperReady(player_t *player) boolean P_SuperReady(player_t *player)
{ {
if ((ALL7EMERALDS(emeralds) && player->rings >= 50) && !player->powers[pw_super] && !player->powers[pw_tailsfly] if (!player->powers[pw_super]
&& !(player->powers[pw_shield] & SH_NOSTACK)
&& !player->powers[pw_invulnerability] && !player->powers[pw_invulnerability]
&& !(maptol & TOL_NIGHTS || (player->powers[pw_carry] == CR_NIGHTSMODE)) // don't turn 'regular super' in nights levels && !player->powers[pw_tailsfly]
&& player->pflags & PF_JUMPED && (player->charflags & SF_SUPER)
&& player->charflags & SF_SUPER) && (player->pflags & PF_JUMPED)
&& !(player->powers[pw_shield] & SH_NOSTACK)
&& !(maptol & TOL_NIGHTS)
&& ALL7EMERALDS(emeralds)
&& (player->rings >= 50))
return true; return true;
return false; return false;
@ -4484,12 +4494,12 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd)
} }
else if (player->pflags & PF_SLIDING || (gametype == GT_CTF && player->gotflag)) else if (player->pflags & PF_SLIDING || (gametype == GT_CTF && player->gotflag))
; ;
else if (P_SuperReady(player)) /*else if (P_SuperReady(player))
{ {
// If you can turn super and aren't already, // If you can turn super and aren't already,
// and you don't have a shield, do it! // and you don't have a shield, do it!
P_DoSuperTransformation(player, false); P_DoSuperTransformation(player, false);
} }*/
else if (player->pflags & PF_JUMPED) else if (player->pflags & PF_JUMPED)
{ {
#ifdef HAVE_BLUA #ifdef HAVE_BLUA
@ -5953,10 +5963,10 @@ static void P_DoNiGHTSCapsule(player_t *player)
if (G_IsSpecialStage(gamemap)) if (G_IsSpecialStage(gamemap))
{ // In special stages, share rings. Everyone gives up theirs to the capsule player always, because we can't have any individualism here! { // In special stages, share rings. Everyone gives up theirs to the capsule player always, because we can't have any individualism here!
for (i = 0; i < MAXPLAYERS; i++) for (i = 0; i < MAXPLAYERS; i++)
if (playeringame[i] && (&players[i] != player) && players[i].rings > 0) if (playeringame[i] && (&players[i] != player) && players[i].spheres > 0)
{ {
player->rings += players[i].rings; player->spheres += players[i].spheres;
players[i].rings = 0; players[i].spheres = 0;
} }
} }
@ -5965,9 +5975,9 @@ static void P_DoNiGHTSCapsule(player_t *player)
&& player->mo->y == player->capsule->y && player->mo->y == player->capsule->y
&& player->mo->z == player->capsule->z+(player->capsule->height/3)) && player->mo->z == player->capsule->z+(player->capsule->height/3))
{ {
if (player->rings > 0) if (player->spheres > 0)
{ {
player->rings--; player->spheres--;
player->capsule->health--; player->capsule->health--;
player->capsule->extravalue1++; player->capsule->extravalue1++;
@ -5999,9 +6009,6 @@ static void P_DoNiGHTSCapsule(player_t *player)
if (G_IsSpecialStage(gamemap)) if (G_IsSpecialStage(gamemap))
{ {
// The Chaos Emerald begins to orbit us!
mobj_t *emmo;
UINT8 em = P_GetNextEmerald();
tic_t lowest_time; tic_t lowest_time;
/*for (i = 0; i < MAXPLAYERS; i++) /*for (i = 0; i < MAXPLAYERS; i++)
@ -6016,8 +6023,10 @@ static void P_DoNiGHTSCapsule(player_t *player)
if (player->powers[pw_carry] == CR_NIGHTSMODE) if (player->powers[pw_carry] == CR_NIGHTSMODE)
{ {
// The Chaos Emerald begins to orbit us!
UINT8 em = P_GetNextEmerald();
// Only give it to ONE person, and THAT player has to get to the goal! // Only give it to ONE person, and THAT player has to get to the goal!
emmo = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z + player->mo->info->height, MT_GOTEMERALD); mobj_t *emmo = P_SpawnMobjFromMobj(player->mo, 0, 0, player->mo->height, MT_GOTEMERALD);
P_SetTarget(&emmo->target, player->mo); P_SetTarget(&emmo->target, player->mo);
P_SetMobjState(emmo, mobjinfo[MT_GOTEMERALD].meleestate + em); P_SetMobjState(emmo, mobjinfo[MT_GOTEMERALD].meleestate + em);
P_SetTarget(&player->mo->tracer, emmo); P_SetTarget(&player->mo->tracer, emmo);
@ -6035,18 +6044,24 @@ static void P_DoNiGHTSCapsule(player_t *player)
} }
else else
{ {
for (i = 0; i < 16; i++) /*for (i = 0; i < 16; i++)
{ {
mobj_t *flicky = P_InternalFlickySpawn(player->capsule, 0, ((i%4) + 1)*2*FRACUNIT, true); mobj_t *flicky = P_InternalFlickySpawn(player->capsule, 0, ((i%4) + 1)*2*FRACUNIT, true);
flicky->z += player->capsule->height/2; flicky->z += player->capsule->height/2;
flicky->angle = (i*(ANGLE_MAX/16)); flicky->angle = (i*(ANGLE_MAX/16));
P_InstaThrust(flicky, flicky->angle, 8*FRACUNIT); P_InstaThrust(flicky, flicky->angle, 8*FRACUNIT);
} }*/
mobj_t *idya = P_SpawnMobjFromMobj(player->mo, 0, 0, player->mo->height, MT_GOTEMERALD);
idya->extravalue2 = player->mare/5;
P_SetTarget(&idya->target, player->mo);
P_SetMobjState(idya, mobjinfo[MT_GOTEMERALD].missilestate + ((player->mare + 1) % 5));
P_SetTarget(&player->mo->tracer, idya);
} }
for (i = 0; i < MAXPLAYERS; i++) for (i = 0; i < MAXPLAYERS; i++)
if (playeringame[i] && players[i].mare == player->mare) if (playeringame[i] && players[i].mare == player->mare)
P_SetTarget(&players[i].capsule, NULL); // Remove capsule from everyone now that it is dead! P_SetTarget(&players[i].capsule, NULL); // Remove capsule from everyone now that it is dead!
S_StartScreamSound(player->mo, sfx_ngdone); S_StartScreamSound(player->mo, sfx_ngdone);
P_SwitchSpheresBonusMode(true);
} }
} }
else else
@ -6139,7 +6154,7 @@ static void P_NiGHTSMovement(player_t *player)
} }
else if (P_IsLocalPlayer(player) && player->nightstime == 10*TICRATE) else if (P_IsLocalPlayer(player) && player->nightstime == 10*TICRATE)
// S_StartSound(NULL, sfx_timeup); // that creepy "out of time" music from NiGHTS. Dummied out, as some on the dev team thought it wasn't Sonic-y enough (Mystic, notably). Uncomment to restore. -SH // S_StartSound(NULL, sfx_timeup); // that creepy "out of time" music from NiGHTS. Dummied out, as some on the dev team thought it wasn't Sonic-y enough (Mystic, notably). Uncomment to restore. -SH
S_ChangeMusicInternal("_drown",false); S_ChangeMusicInternal((((maptol & TOL_NIGHTS) && !G_IsSpecialStage(gamemap)) ? "_ntime" : "_drown"), false);
if (player->mo->z < player->mo->floorz) if (player->mo->z < player->mo->floorz)
@ -7477,7 +7492,7 @@ static void P_MovePlayer(player_t *player)
#endif #endif
{ {
if (!(player->pflags & (PF_USEDOWN|PF_GLIDING|PF_SLIDING|PF_SHIELDABILITY)) // If the player is not holding down BT_USE, or having used an ability previously if (!(player->pflags & (PF_USEDOWN|PF_GLIDING|PF_SLIDING|PF_SHIELDABILITY)) // If the player is not holding down BT_USE, or having used an ability previously
&& (!(player->pflags & PF_THOKKED) || ((player->powers[pw_shield] & SH_NOSTACK) == SH_BUBBLEWRAP && player->secondjump == UINT8_MAX))) // thokked is optional if you're bubblewrapped && (!(player->powers[pw_shield] & SH_NOSTACK) || !(player->pflags & PF_THOKKED) || ((player->powers[pw_shield] & SH_NOSTACK) == SH_BUBBLEWRAP && player->secondjump == UINT8_MAX))) // thokked is optional if you're bubblewrapped/turning super
{ {
// Force shield activation // Force shield activation
if ((player->powers[pw_shield] & ~(SH_FORCEHP|SH_STACK)) == SH_FORCE) if ((player->powers[pw_shield] & ~(SH_FORCEHP|SH_STACK)) == SH_FORCE)
@ -7490,6 +7505,11 @@ static void P_MovePlayer(player_t *player)
{ {
switch (player->powers[pw_shield] & SH_NOSTACK) switch (player->powers[pw_shield] & SH_NOSTACK)
{ {
// Super!
case SH_NONE:
if (P_SuperReady(player))
P_DoSuperTransformation(player, false);
break;
// Whirlwind/Thundercoin shield activation // Whirlwind/Thundercoin shield activation
case SH_WHIRLWIND: case SH_WHIRLWIND:
case SH_THUNDERCOIN: case SH_THUNDERCOIN:
@ -9563,11 +9583,8 @@ void P_PlayerThink(player_t *player)
// If 11 seconds are left on the timer, // If 11 seconds are left on the timer,
// begin the drown music for countdown! // begin the drown music for countdown!
if (countdown == 11*TICRATE - 1) if (countdown == 11*TICRATE - 1 && P_IsLocalPlayer(player))
{ S_ChangeMusicInternal("_drown", false);
if (P_IsLocalPlayer(player))
S_ChangeMusicInternal("_drown", false);
}
// If you've hit the countdown and you haven't made // If you've hit the countdown and you haven't made
// it to the exit, you're a goner! // it to the exit, you're a goner!
@ -9667,7 +9684,7 @@ void P_PlayerThink(player_t *player)
if (gametype != GT_COOP) if (gametype != GT_COOP)
player->score = 0; player->score = 0;
player->mo->health = 1; player->mo->health = 1;
player->rings = 0; player->rings = player->spheres = 0;
} }
else if ((netgame || multiplayer) && player->lives <= 0 && gametype != GT_COOP) else if ((netgame || multiplayer) && player->lives <= 0 && gametype != GT_COOP)
{ {
@ -9720,8 +9737,8 @@ void P_PlayerThink(player_t *player)
mo2 = (mobj_t *)th; mo2 = (mobj_t *)th;
if (!(mo2->type == MT_NIGHTSWING || mo2->type == MT_RING || mo2->type == MT_COIN if (!(mo2->type == MT_RING || mo2->type == MT_COIN || mo2->type == MT_BLUESPHERE
|| mo2->type == MT_BLUEBALL)) || mo2->type == MT_NIGHTSCHIP || mo2->type == MT_NIGHTSSTAR))
continue; continue;
if (P_AproxDistance(P_AproxDistance(mo2->x - x, mo2->y - y), mo2->z - z) > FixedMul(128*FRACUNIT, player->mo->scale)) if (P_AproxDistance(P_AproxDistance(mo2->x - x, mo2->y - y), mo2->z - z) > FixedMul(128*FRACUNIT, player->mo->scale))
@ -10210,7 +10227,7 @@ void P_PlayerAfterThink(player_t *player)
if (player->followmobj) if (player->followmobj)
{ {
P_RemoveMobj(player->followmobj); P_RemoveMobj(player->followmobj);
player->followmobj = NULL; P_SetTarget(&player->followmobj, NULL);
} }
return; return;
} }
@ -10495,14 +10512,14 @@ void P_PlayerAfterThink(player_t *player)
if (player->followmobj && (player->spectator || player->mo->health <= 0 || player->followmobj->type != player->followitem)) if (player->followmobj && (player->spectator || player->mo->health <= 0 || player->followmobj->type != player->followitem))
{ {
P_RemoveMobj(player->followmobj); P_RemoveMobj(player->followmobj);
player->followmobj = NULL; P_SetTarget(&player->followmobj, NULL);
} }
if (!player->spectator && player->mo->health && player->followitem) if (!player->spectator && player->mo->health && player->followitem)
{ {
if (!player->followmobj || P_MobjWasRemoved(player->followmobj)) if (!player->followmobj || P_MobjWasRemoved(player->followmobj))
{ {
player->followmobj = P_SpawnMobjFromMobj(player->mo, 0, 0, 0, player->followitem); P_SetTarget(&player->followmobj, P_SpawnMobjFromMobj(player->mo, 0, 0, 0, player->followitem));
P_SetTarget(&player->followmobj->tracer, player->mo); P_SetTarget(&player->followmobj->tracer, player->mo);
player->followmobj->flags2 |= MF2_LINKDRAW; player->followmobj->flags2 |= MF2_LINKDRAW;
} }

View File

@ -2673,7 +2673,7 @@ void SetPlayerSkinByNum(INT32 playernum, INT32 skinnum)
if (player->followmobj) if (player->followmobj)
{ {
P_RemoveMobj(player->followmobj); P_RemoveMobj(player->followmobj);
player->followmobj = NULL; P_SetTarget(&player->followmobj, NULL);
} }
if (player->mo) if (player->mo)

View File

@ -446,10 +446,11 @@ void SCR_ClosedCaptions(void)
{ {
if (splitscreen) if (splitscreen)
basey -= 8; basey -= 8;
else if (((maptol & TOL_NIGHTS) && (modeattacking == ATTACKING_NIGHTS)) else if ((modeattacking == ATTACKING_NIGHTS)
|| (cv_powerupdisplay.value == 2) || (!(maptol & TOL_NIGHTS)
&& ((cv_powerupdisplay.value == 2)
|| (cv_powerupdisplay.value == 1 && ((stplyr == &players[displayplayer] && !camera.chase) || (cv_powerupdisplay.value == 1 && ((stplyr == &players[displayplayer] && !camera.chase)
|| ((splitscreen && stplyr == &players[secondarydisplayplayer]) && !camera2.chase)))) || ((splitscreen && stplyr == &players[secondarydisplayplayer]) && !camera2.chase))))))
basey -= 16; basey -= 16;
} }

View File

@ -141,7 +141,7 @@ sfxinfo_t S_sfx[NUMSFX] =
{"bnce1", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Bounce"}, // Boing! {"bnce1", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Bounce"}, // Boing!
{"bnce2", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Scatter"}, // Boing! {"bnce2", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Scatter"}, // Boing!
{"cannon", false, 64, 8, -1, NULL, 0, -1, -1, LUMPERROR, "Powerful shot"}, {"cannon", false, 64, 8, -1, NULL, 0, -1, -1, LUMPERROR, "Powerful shot"},
{"cgot" , true, 120, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Got Chaos Emerald"}, // Got Emerald! Tails 09-02-2001 {"cgot" , true, 120, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Got Emerald"}, // Got Emerald! Tails 09-02-2001
{"cybdth", false, 32, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Explosion"}, {"cybdth", false, 32, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Explosion"},
{"deton", true, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Ominous beeping"}, {"deton", true, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Ominous beeping"},
{"ding", false, 127, 8, -1, NULL, 0, -1, -1, LUMPERROR, "Ding"}, {"ding", false, 127, 8, -1, NULL, 0, -1, -1, LUMPERROR, "Ding"},
@ -214,11 +214,12 @@ sfxinfo_t S_sfx[NUMSFX] =
{"xideya", false, 127, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Success"}, // Xmas {"xideya", false, 127, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Success"}, // Xmas
{"nbmper", false, 96, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Bumper"}, {"nbmper", false, 96, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Bumper"},
{"nxbump", false, 96, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Bumper"}, // Xmas {"nxbump", false, 96, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Bumper"}, // Xmas
{"ncchip", false, 204, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Got chip"},
{"ncitem", false, 204, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Got special"}, {"ncitem", false, 204, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Got special"},
{"nxitem", false, 204, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Got special"}, // Xmas {"nxitem", false, 204, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Got special"}, // Xmas
{"ngdone", true, 127, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Bonus time start"}, {"ngdone", true, 127, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Bonus time start"},
{"nxdone", true, 127, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Bonus time start"}, // Xmas {"nxdone", true, 127, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Bonus time start"}, // Xmas
{"drill1", false, 48, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Drill start"}, {"drill1", false, 48, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Drill"},
{"drill2", false, 48, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Drill"}, {"drill2", false, 48, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Drill"},
{"ncspec", false, 204, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Power-up"}, // Tails 12-15-2003 {"ncspec", false, 204, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Power-up"}, // Tails 12-15-2003
{"nghurt", false, 96, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Hurt"}, {"nghurt", false, 96, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Hurt"},
@ -228,12 +229,13 @@ sfxinfo_t S_sfx[NUMSFX] =
{"hoop3", false, 192, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Hoop++"}, {"hoop3", false, 192, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Hoop++"},
{"hidden", false, 204, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Discovery"}, {"hidden", false, 204, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Discovery"},
{"prloop", false, 104, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Gust of wind"}, {"prloop", false, 104, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Gust of wind"},
{"timeup", true, 256, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Ominous Countdown"}, {"ngjump", false, 96, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Jump"},
{"peww", false, 96, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Pew"},
// Halloween // Halloween
{"lntsit", false, 60, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Cacolantern awake"}, {"lntsit", false, 60, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Cacolantern awake"},
{"lntdie", false, 60, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Cacolantern death"}, {"lntdie", false, 60, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Cacolantern death"},
{"pumpkn", false, 60, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Pumpkin smash"}, {"pumpkn", false, 60, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Pumpkin smash"}, // idspispopd
{"ghosty", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Laughter"}, {"ghosty", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Laughter"},
// Mario // Mario
@ -334,10 +336,10 @@ sfxinfo_t S_sfx[NUMSFX] =
{"s3k62", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Jump"}, {"s3k62", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Jump"},
{"s3k63", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Starpost"}, {"s3k63", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Starpost"},
{"s3k64", false, 64, 2, -1, NULL, 0, -1, -1, LUMPERROR, "Clatter"}, {"s3k64", false, 64, 2, -1, NULL, 0, -1, -1, LUMPERROR, "Clatter"},
{"s3k65", false, 255, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Got blue sphere"}, // Blue Spheres {"s3k65", false, 255, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Got sphere"}, // Blue Spheres
{"s3k66", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Special stage end"}, {"s3k66", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Special stage end"},
{"s3k67", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Firing missile"}, {"s3k67", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Firing missile"},
{"s3k68", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Unknown possibilities"}, {"s3k68", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Discovery"},
{"s3k69", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Switch click"}, {"s3k69", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Switch click"},
{"s3k6a", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Special stage clear"}, {"s3k6a", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Special stage clear"},
{"s3k6b", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Punch"}, {"s3k6b", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Punch"},

View File

@ -280,6 +280,7 @@ typedef enum
sfx_xideya, // Xmas sfx_xideya, // Xmas
sfx_nbmper, sfx_nbmper,
sfx_nxbump, // Xmas sfx_nxbump, // Xmas
sfx_ncchip,
sfx_ncitem, sfx_ncitem,
sfx_nxitem, // Xmas sfx_nxitem, // Xmas
sfx_ngdone, sfx_ngdone,
@ -294,7 +295,8 @@ typedef enum
sfx_hoop3, sfx_hoop3,
sfx_hidden, sfx_hidden,
sfx_prloop, sfx_prloop,
sfx_timeup, // Was gonna be played when less than ten seconds are on the clock; uncomment uses of this to see it in-context sfx_ngjump,
sfx_peww,
// Halloween // Halloween
sfx_lntsit, sfx_lntsit,

View File

@ -112,6 +112,8 @@ static patch_t *yelstat;
static patch_t *nbracket; static patch_t *nbracket;
static patch_t *nhud[12]; static patch_t *nhud[12];
static patch_t *nsshud; static patch_t *nsshud;
static patch_t *nbon[12];
static patch_t *nssbon;
static patch_t *narrow[9]; static patch_t *narrow[9];
static patch_t *nredar[8]; // Red arrow static patch_t *nredar[8]; // Red arrow
static patch_t *drillbar; static patch_t *drillbar;
@ -309,8 +311,12 @@ void ST_LoadGraphics(void)
yelstat = W_CachePatchName("YELSTAT", PU_HUDGFX); yelstat = W_CachePatchName("YELSTAT", PU_HUDGFX);
nbracket = W_CachePatchName("NBRACKET", PU_HUDGFX); nbracket = W_CachePatchName("NBRACKET", PU_HUDGFX);
for (i = 0; i < 12; ++i) for (i = 0; i < 12; ++i)
{
nhud[i] = W_CachePatchName(va("NHUD%d", i+1), PU_HUDGFX); nhud[i] = W_CachePatchName(va("NHUD%d", i+1), PU_HUDGFX);
nbon[i] = W_CachePatchName(va("NBON%d", i+1), PU_HUDGFX);
}
nsshud = W_CachePatchName("NSSHUD", PU_HUDGFX); nsshud = W_CachePatchName("NSSHUD", PU_HUDGFX);
nssbon = W_CachePatchName("NSSBON", PU_HUDGFX);
minicaps = W_CachePatchName("MINICAPS", PU_HUDGFX); minicaps = W_CachePatchName("MINICAPS", PU_HUDGFX);
for (i = 0; i < 8; ++i) for (i = 0; i < 8; ++i)
@ -735,18 +741,7 @@ static inline void ST_drawRings(void)
ST_DrawPatchFromHud(HUD_RINGS, ((!stplyr->spectator && stplyr->rings <= 0 && leveltime/5 & 1) ? sboredrings : sborings), ((stplyr->spectator) ? V_HUDTRANSHALF : V_HUDTRANS)); ST_DrawPatchFromHud(HUD_RINGS, ((!stplyr->spectator && stplyr->rings <= 0 && leveltime/5 & 1) ? sboredrings : sborings), ((stplyr->spectator) ? V_HUDTRANSHALF : V_HUDTRANS));
if (objectplacing) ringnum = ((objectplacing) ? op_currentdoomednum : max(stplyr->rings, 0));
ringnum = op_currentdoomednum;
else if (!useNightsSS && G_IsSpecialStage(gamemap))
{
INT32 i;
ringnum = 0;
for (i = 0; i < MAXPLAYERS; i++)
if (playeringame[i] && players[i].mo && players[i].rings > 0)
ringnum += players[i].rings;
}
else
ringnum = max(stplyr->rings, 0);
if (cv_timetic.value == 2) // Yes, even in modeattacking if (cv_timetic.value == 2) // Yes, even in modeattacking
ST_DrawNumFromHud(HUD_RINGSNUMTICS, ringnum, V_PERPLAYER|((stplyr->spectator) ? V_HUDTRANSHALF : V_HUDTRANS)); ST_DrawNumFromHud(HUD_RINGSNUMTICS, ringnum, V_PERPLAYER|((stplyr->spectator) ? V_HUDTRANSHALF : V_HUDTRANS));
@ -1394,17 +1389,17 @@ static void ST_drawNightsRecords(void)
V_DrawCenteredString(BASEVIDWIDTH/2, 60, aflag, V_DrawCenteredString(BASEVIDWIDTH/2, 60, aflag,
va(M_GetText("\x80GET\x82 %d\x80 %s%s%s!"), stplyr->capsule->health, va(M_GetText("\x80GET\x82 %d\x80 %s%s%s!"), stplyr->capsule->health,
(stplyr->textvar == 3) ? M_GetText("MORE ") : "", (stplyr->textvar == 3) ? M_GetText("MORE ") : "",
(G_IsSpecialStage(gamemap)) ? "SPHERE" : "RING", (G_IsSpecialStage(gamemap)) ? "SPHERE" : "CHIP",
(stplyr->capsule->health > 1) ? "S" : "")); (stplyr->capsule->health > 1) ? "S" : ""));
} }
// End Bonus // End Bonus
else if (stplyr->textvar == 4) else if (stplyr->textvar == 4)
{ {
V_DrawString(BASEVIDWIDTH/2 - 56, 140, aflag, (G_IsSpecialStage(gamemap)) ? "SPHERES:" : "RINGS:"); V_DrawString(BASEVIDWIDTH/2 - 56, 140, aflag, (G_IsSpecialStage(gamemap)) ? "SPHERES:" : "CHIPS:");
V_DrawString(BASEVIDWIDTH/2 - 56, 148, aflag, "BONUS:"); V_DrawString(BASEVIDWIDTH/2 - 56, 148, aflag, "BONUS:");
V_DrawRightAlignedString(BASEVIDWIDTH/2 + 56, 140, V_ORANGEMAP|aflag, va("%d", stplyr->finishedrings)); V_DrawRightAlignedString(BASEVIDWIDTH/2 + 56, 140, V_ORANGEMAP|aflag, va("%d", stplyr->finishedspheres));
V_DrawRightAlignedString(BASEVIDWIDTH/2 + 56, 140, V_ORANGEMAP|aflag, va("%d", stplyr->finishedrings * 50)); V_DrawRightAlignedString(BASEVIDWIDTH/2 + 56, 148, V_ORANGEMAP|aflag, va("%d", stplyr->finishedspheres * 50));
ST_DrawNightsOverlayNum((BASEVIDWIDTH/2 + 56)<<FRACBITS, 160<<FRACBITS, FRACUNIT, aflag, stplyr->lastmarescore, nightsnum, SKINCOLOR_AZURE); ST_DrawNightsOverlayNum((BASEVIDWIDTH/2 + 56)<<FRACBITS, 160<<FRACBITS, FRACUNIT, aflag, stplyr->lastmarescore, nightsnum, SKINCOLOR_AZURE);
// If new record, say so! // If new record, say so!
@ -1462,15 +1457,15 @@ static void ST_drawNiGHTSHUD(void)
{ {
INT32 origamount; INT32 origamount;
INT32 minlink = 1; INT32 minlink = 1;
INT32 total_ringcount; INT32 total_spherecount;
const boolean oldspecialstage = (G_IsSpecialStage(gamemap) && !(maptol & TOL_NIGHTS));
// When debugging, show "0 Link".
if (cv_debug & DBG_NIGHTSBASIC)
minlink = 0;
// Cheap hack: don't display when the score is showing (it popping up for a split second when exiting a map is intentional) // Cheap hack: don't display when the score is showing (it popping up for a split second when exiting a map is intentional)
if (stplyr->texttimer && stplyr->textvar == 4) if (oldspecialstage || (stplyr->texttimer && stplyr->textvar == 4))
minlink = INT32_MAX; minlink = INT32_MAX;
// When debugging, show "0 Link".
else if (cv_debug & DBG_NIGHTSBASIC)
minlink = 0;
// Drill meter // Drill meter
if ( if (
@ -1576,25 +1571,35 @@ static void ST_drawNiGHTSHUD(void)
// Begin drawing brackets/chip display // Begin drawing brackets/chip display
#ifdef HAVE_BLUA #ifdef HAVE_BLUA
if (LUA_HudEnabled(hud_nightsrings)) if (LUA_HudEnabled(hud_nightsspheres))
{ {
#endif #endif
ST_DrawTopLeftOverlayPatch(16, 8, nbracket); ST_DrawTopLeftOverlayPatch(16, 8, nbracket);
if (G_IsSpecialStage(gamemap)) if (G_IsSpecialStage(gamemap))
ST_DrawTopLeftOverlayPatch(24, 16, nsshud); ST_DrawTopLeftOverlayPatch(24, 16, ((stplyr->bonustime && (leveltime & 4)) ? nssbon : nsshud));
else if (stplyr->bonustime)
ST_DrawTopLeftOverlayPatch(24, 16, nbon[(leveltime/2)%12]);
else else
ST_DrawTopLeftOverlayPatch(24, 16, nhud[(leveltime/2)%12]); ST_DrawTopLeftOverlayPatch(24, 16, nhud[(leveltime/2)%12]);
if (G_IsSpecialStage(gamemap)) if (G_IsSpecialStage(gamemap))
{ {
INT32 i; INT32 i;
total_ringcount = 0; total_spherecount = 0;
for (i = 0; i < MAXPLAYERS; i++) for (i = 0; i < MAXPLAYERS; i++)
if (playeringame[i] /*&& players[i].powers[pw_carry] == CR_NIGHTSMODE*/ && players[i].rings) if (playeringame[i] /*&& players[i].powers[pw_carry] == CR_NIGHTSMODE*/ && players[i].spheres)
total_ringcount += players[i].rings; total_spherecount += players[i].spheres;
} }
else else
total_ringcount = stplyr->rings; total_spherecount = stplyr->spheres;
/*if (oldspecialstage)
{
if (total_spherecount < ssspheres)
total_spherecount = ssspheres - total_spherecount;
else
total_spherecount = 0;
}*/
if (stplyr->capsule) if (stplyr->capsule)
{ {
@ -1650,28 +1655,48 @@ static void ST_drawNiGHTSHUD(void)
amount = (origamount - stplyr->capsule->health); amount = (origamount - stplyr->capsule->health);
amount = (amount * length)/origamount; amount = (amount * length)/origamount;
for (cfill = 0; cfill < amount && cfill < 88; ++cfill) for (cfill = 0; cfill < amount && cfill < length; ++cfill)
V_DrawScaledPatch(15 + cfill + 1, 8 + 35, V_PERPLAYER|V_SNAPTOLEFT|V_SNAPTOTOP|V_HUDTRANS, capsulefill); V_DrawScaledPatch(15 + cfill + 1, 8 + 35, V_PERPLAYER|V_SNAPTOLEFT|V_SNAPTOTOP|V_HUDTRANS, capsulefill);
} }
if (total_ringcount >= stplyr->capsule->health) if (total_spherecount >= stplyr->capsule->health)
ST_DrawTopLeftOverlayPatch(40, 8 + 5, nredar[leveltime%8]); ST_DrawTopLeftOverlayPatch(40, 8 + 5, nredar[leveltime&7]);
else else
ST_DrawTopLeftOverlayPatch(40, 8 + 5, narrow[(leveltime/2)%8]); ST_DrawTopLeftOverlayPatch(40, 8 + 5, narrow[(leveltime/2)&7]);
}
else if (oldspecialstage && total_spherecount < ssspheres)
{
INT32 cfill, amount;
const INT32 length = 88;
UINT8 em = P_GetNextEmerald();
ST_DrawTopLeftOverlayPatch(72, 8, nbracket);
if (em <= 7)
ST_DrawTopLeftOverlayPatch(80, 8 + 8, emeraldpics[0][em]);
ST_DrawTopLeftOverlayPatch(40, 8 + 5, narrow[(leveltime/2)&7]);
// Lil' white box!
V_DrawScaledPatch(15, 8 + 34, V_PERPLAYER|V_SNAPTOLEFT|V_SNAPTOTOP|V_HUDTRANS, capsulebar);
amount = (total_spherecount * length)/ssspheres;
for (cfill = 0; cfill < amount && cfill < length; ++cfill)
V_DrawScaledPatch(15 + cfill + 1, 8 + 35, V_PERPLAYER|V_SNAPTOLEFT|V_SNAPTOTOP|V_HUDTRANS, capsulefill);
} }
else else
ST_DrawTopLeftOverlayPatch(40, 8 + 5, narrow[8]); ST_DrawTopLeftOverlayPatch(40, 8 + 5, narrow[8]);
if (total_ringcount >= 100) if (total_spherecount >= 100)
V_DrawTallNum((total_ringcount >= 1000) ? 76 : 72, 8 + 11, V_PERPLAYER|V_SNAPTOTOP|V_SNAPTOLEFT|V_HUDTRANS, total_ringcount); V_DrawTallNum((total_spherecount >= 1000) ? 76 : 72, 8 + 11, V_PERPLAYER|V_SNAPTOTOP|V_SNAPTOLEFT|V_HUDTRANS, total_spherecount);
else else
V_DrawTallNum(68, 8 + 11, V_PERPLAYER|V_SNAPTOTOP|V_SNAPTOLEFT|V_HUDTRANS, total_ringcount); V_DrawTallNum(68, 8 + 11, V_PERPLAYER|V_SNAPTOTOP|V_SNAPTOLEFT|V_HUDTRANS, total_spherecount);
#ifdef HAVE_BLUA #ifdef HAVE_BLUA
} }
#endif #endif
// Score // Score
if (!stplyr->exiting if (!stplyr->exiting && !oldspecialstage
#ifdef HAVE_BLUA #ifdef HAVE_BLUA
&& LUA_HudEnabled(hud_nightsscore) && LUA_HudEnabled(hud_nightsscore)
#endif #endif
@ -1714,6 +1739,7 @@ static void ST_drawNiGHTSHUD(void)
{ {
INT32 realnightstime = stplyr->nightstime/TICRATE; INT32 realnightstime = stplyr->nightstime/TICRATE;
INT32 numbersize; INT32 numbersize;
UINT8 col = ((realnightstime < 10) ? SKINCOLOR_RED : SKINCOLOR_SUPERGOLD4);
if (G_IsSpecialStage(gamemap)) if (G_IsSpecialStage(gamemap))
{ {
@ -1744,46 +1770,66 @@ static void ST_drawNiGHTSHUD(void)
else else
numbersize = 48/2; numbersize = 48/2;
ST_DrawNightsOverlayNum((160 + numbersize)<<FRACBITS, 14<<FRACBITS, FRACUNIT, V_PERPLAYER|V_SNAPTOTOP, realnightstime, nightsnum, if ((oldspecialstage && leveltime & 2)
((realnightstime < 10) ? SKINCOLOR_RED : SKINCOLOR_SUPERGOLD4)); && (stplyr->mo->eflags & (MFE_TOUCHWATER|MFE_UNDERWATER)))
col = SKINCOLOR_ORANGE;
ST_DrawNightsOverlayNum((160 + numbersize)<<FRACBITS, 14<<FRACBITS, FRACUNIT, V_PERPLAYER|V_SNAPTOTOP, realnightstime, nightsnum, col);
// Show exact time in debug // Show exact time in debug
if (cv_debug & DBG_NIGHTSBASIC) if (cv_debug & DBG_NIGHTSBASIC)
V_DrawString(160 + numbersize + 8, 24, V_SNAPTOTOP|((realnightstime < 10) ? V_REDMAP : V_YELLOWMAP), va("%02d", G_TicsToCentiseconds(stplyr->nightstime))); V_DrawString(160 + numbersize + 8, 24, V_SNAPTOTOP|((realnightstime < 10) ? V_REDMAP : V_YELLOWMAP), va("%02d", G_TicsToCentiseconds(stplyr->nightstime)));
} }
// Show pickup durations if (oldspecialstage)
if (cv_debug & DBG_NIGHTSBASIC)
{ {
UINT16 pwr; if (leveltime < 5*TICRATE)
if (stplyr->powers[pw_nights_superloop])
{ {
pwr = stplyr->powers[pw_nights_superloop]; INT32 aflag = V_PERPLAYER;
V_DrawSmallScaledPatch(110, 44, 0, W_CachePatchName("NPRUA0",PU_CACHE)); tic_t drawtime = (5*TICRATE) - leveltime;
V_DrawThinString(106, 52, V_MONOSPACE, va("%2d.%02d", pwr/TICRATE, G_TicsToCentiseconds(pwr))); if (drawtime < TICRATE/2)
} aflag |= (9 - 9*drawtime/(TICRATE/2)) << V_ALPHASHIFT;
// This one, not quite as much so.
if (stplyr->powers[pw_nights_helper]) V_DrawCenteredString(BASEVIDWIDTH/2, 60, aflag,
{ va(M_GetText("\x80GET\x82 %d\x80 SPHERE%s!"), ssspheres,
pwr = stplyr->powers[pw_nights_helper]; (ssspheres > 1) ? "S" : ""));
V_DrawSmallScaledPatch(150, 44, 0, W_CachePatchName("NPRUC0",PU_CACHE));
V_DrawThinString(146, 52, V_MONOSPACE, va("%2d.%02d", pwr/TICRATE, G_TicsToCentiseconds(pwr)));
}
if (stplyr->powers[pw_nights_linkfreeze])
{
pwr = stplyr->powers[pw_nights_linkfreeze];
V_DrawSmallScaledPatch(190, 44, 0, W_CachePatchName("NPRUE0",PU_CACHE));
V_DrawThinString(186, 52, V_MONOSPACE, va("%2d.%02d", pwr/TICRATE, G_TicsToCentiseconds(pwr)));
} }
} }
else
{
// Show pickup durations
if (cv_debug & DBG_NIGHTSBASIC)
{
UINT16 pwr;
// Records/extra text if (stplyr->powers[pw_nights_superloop])
{
pwr = stplyr->powers[pw_nights_superloop];
V_DrawSmallScaledPatch(110, 44, 0, W_CachePatchName("NPRUA0",PU_CACHE));
V_DrawThinString(106, 52, V_MONOSPACE, va("%2d.%02d", pwr/TICRATE, G_TicsToCentiseconds(pwr)));
}
if (stplyr->powers[pw_nights_helper])
{
pwr = stplyr->powers[pw_nights_helper];
V_DrawSmallScaledPatch(150, 44, 0, W_CachePatchName("NPRUC0",PU_CACHE));
V_DrawThinString(146, 52, V_MONOSPACE, va("%2d.%02d", pwr/TICRATE, G_TicsToCentiseconds(pwr)));
}
if (stplyr->powers[pw_nights_linkfreeze])
{
pwr = stplyr->powers[pw_nights_linkfreeze];
V_DrawSmallScaledPatch(190, 44, 0, W_CachePatchName("NPRUE0",PU_CACHE));
V_DrawThinString(186, 52, V_MONOSPACE, va("%2d.%02d", pwr/TICRATE, G_TicsToCentiseconds(pwr)));
}
}
// Records/extra text
#ifdef HAVE_BLUA #ifdef HAVE_BLUA
if (LUA_HudEnabled(hud_nightsrecords)) if (LUA_HudEnabled(hud_nightsrecords))
#endif #endif
ST_drawNightsRecords(); ST_drawNightsRecords();
}
} }
static inline void ST_drawWeaponSelect(INT32 xoffs, INT32 y) static inline void ST_drawWeaponSelect(INT32 xoffs, INT32 y)
@ -1952,7 +1998,7 @@ static void ST_drawTextHUD(void)
} }
else if (stplyr->spectator && (gametype != GT_COOP || stplyr->playerstate == PST_LIVE)) else if (stplyr->spectator && (gametype != GT_COOP || stplyr->playerstate == PST_LIVE))
{ {
if (G_IsSpecialStage(gamemap) && useNightsSS) if (G_IsSpecialStage(gamemap) && (maptol & TOL_NIGHTS))
textHUDdraw(M_GetText("\x82""Wait for the stage to end...")) textHUDdraw(M_GetText("\x82""Wait for the stage to end..."))
else if (gametype == GT_COOP) else if (gametype == GT_COOP)
{ {
@ -2070,22 +2116,22 @@ num:
#undef SEP #undef SEP
} }
static void ST_drawSpecialStageHUD(void) /*static void ST_drawSpecialStageHUD(void)
{ {
if (totalrings > 0) if (ssspheres > 0)
{ {
if (hudinfo[HUD_SS_TOTALRINGS].x) if (hudinfo[HUD_SS_TOTALRINGS].x)
ST_DrawNumFromHud(HUD_SS_TOTALRINGS, totalrings, V_HUDTRANS); ST_DrawNumFromHud(HUD_SS_TOTALRINGS, ssspheres, V_HUDTRANS);
else if (cv_timetic.value == 2) else if (cv_timetic.value == 2)
V_DrawTallNum(hudinfo[HUD_RINGSNUMTICS].x, hudinfo[HUD_SS_TOTALRINGS].y, hudinfo[HUD_RINGSNUMTICS].f|V_PERPLAYER|V_HUDTRANS, totalrings); V_DrawTallNum(hudinfo[HUD_RINGSNUMTICS].x, hudinfo[HUD_SS_TOTALRINGS].y, hudinfo[HUD_RINGSNUMTICS].f|V_PERPLAYER|V_HUDTRANS, ssspheres);
else else
V_DrawTallNum(hudinfo[HUD_RINGSNUM].x, hudinfo[HUD_SS_TOTALRINGS].y, hudinfo[HUD_RINGSNUM].f|V_PERPLAYER|V_HUDTRANS, totalrings); V_DrawTallNum(hudinfo[HUD_RINGSNUM].x, hudinfo[HUD_SS_TOTALRINGS].y, hudinfo[HUD_RINGSNUM].f|V_PERPLAYER|V_HUDTRANS, ssspheres);
} }
if (leveltime < 5*TICRATE && totalrings > 0) if (leveltime < 5*TICRATE && ssspheres > 0)
{ {
ST_DrawPatchFromHud(HUD_GETRINGS, getall, V_HUDTRANS); ST_DrawPatchFromHud(HUD_GETRINGS, getall, V_HUDTRANS);
ST_DrawNumFromHud(HUD_GETRINGSNUM, totalrings, V_HUDTRANS); ST_DrawNumFromHud(HUD_GETRINGSNUM, ssspheres, V_HUDTRANS);
} }
if (sstimer) if (sstimer)
@ -2095,7 +2141,7 @@ static void ST_drawSpecialStageHUD(void)
} }
else else
ST_DrawPatchFromHud(HUD_TIMEUP, timeup, V_HUDTRANS); ST_DrawPatchFromHud(HUD_TIMEUP, timeup, V_HUDTRANS);
} }*/
static INT32 ST_drawEmeraldHuntIcon(mobj_t *hunt, patch_t **patches, INT32 offset) static INT32 ST_drawEmeraldHuntIcon(mobj_t *hunt, patch_t **patches, INT32 offset)
{ {
@ -2231,7 +2277,7 @@ static void ST_overlayDrawer(void)
//hu_showscores = auto hide score/time/rings when tab rankings are shown //hu_showscores = auto hide score/time/rings when tab rankings are shown
if (!(hu_showscores && (netgame || multiplayer))) if (!(hu_showscores && (netgame || multiplayer)))
{ {
if (maptol & TOL_NIGHTS) if (maptol & TOL_NIGHTS || G_IsSpecialStage(gamemap))
ST_drawNiGHTSHUD(); ST_drawNiGHTSHUD();
else else
{ {
@ -2340,10 +2386,6 @@ static void ST_overlayDrawer(void)
if (gametype == GT_RACE || gametype == GT_COMPETITION) if (gametype == GT_RACE || gametype == GT_COMPETITION)
ST_drawRaceHUD(); ST_drawRaceHUD();
// Special Stage HUD
if (!useNightsSS && G_IsSpecialStage(gamemap) && stplyr == &players[displayplayer])
ST_drawSpecialStageHUD();
// Emerald Hunt Indicators // Emerald Hunt Indicators
if (cv_itemfinder.value && M_SecretUnlocked(SECRET_ITEMFINDER)) if (cv_itemfinder.value && M_SecretUnlocked(SECRET_ITEMFINDER))
ST_doItemFinderIconsAndSound(); ST_doItemFinderIconsAndSound();
@ -2362,15 +2404,18 @@ static void ST_overlayDrawer(void)
} }
// This is where we draw all the fun cheese if you have the chasecam off! // This is where we draw all the fun cheese if you have the chasecam off!
if ((stplyr == &players[displayplayer] && !camera.chase) if (!(maptol & TOL_NIGHTS))
|| ((splitscreen && stplyr == &players[secondarydisplayplayer]) && !camera2.chase))
{ {
ST_drawFirstPersonHUD(); if ((stplyr == &players[displayplayer] && !camera.chase)
if (cv_powerupdisplay.value) || ((splitscreen && stplyr == &players[secondarydisplayplayer]) && !camera2.chase))
{
ST_drawFirstPersonHUD();
if (cv_powerupdisplay.value)
ST_drawPowerupHUD();
}
else if (cv_powerupdisplay.value == 2)
ST_drawPowerupHUD(); ST_drawPowerupHUD();
} }
else if (cv_powerupdisplay.value == 2)
ST_drawPowerupHUD();
} }
#ifdef HAVE_BLUA #ifdef HAVE_BLUA

View File

@ -78,7 +78,7 @@ typedef union
struct struct
{ {
char passed1[29]; // KNUCKLES GOT / CRAWLA HONCHO char passed1[29]; // KNUCKLES GOT / CRAWLA HONCHO
char passed2[17]; // A CHAOS EMERALD / GOT THEM ALL! char passed2[17]; // A CHAOS EMERALD? / GOT THEM ALL!
char passed3[15]; // CAN NOW BECOME char passed3[15]; // CAN NOW BECOME
char passed4[SKINNAMESIZE+7]; // SUPER CRAWLA HONCHO char passed4[SKINNAMESIZE+7]; // SUPER CRAWLA HONCHO
INT32 passedx1; INT32 passedx1;
@ -315,6 +315,8 @@ void Y_IntermissionDrawer(void)
INT32 xoffset1 = 0; // Line 1 x offset INT32 xoffset1 = 0; // Line 1 x offset
INT32 xoffset2 = 0; // Line 2 x offset INT32 xoffset2 = 0; // Line 2 x offset
INT32 xoffset3 = 0; // Line 3 x offset INT32 xoffset3 = 0; // Line 3 x offset
INT32 xoffset4 = 0; // Bonus line x offset
INT32 xoffset5 = 0; // Score line x offset
UINT8 drawsection = 0; UINT8 drawsection = 0;
if (gottoken) // first to be behind everything else if (gottoken) // first to be behind everything else
@ -324,28 +326,40 @@ void Y_IntermissionDrawer(void)
if (intertic <= 2*TICRATE) if (intertic <= 2*TICRATE)
animatetic = 0; animatetic = 0;
else if (!animatetic && data.spec.bonus.points == 0 && data.spec.passed3[0] != '\0') else if (!animatetic && data.spec.bonus.points == 0 && data.spec.passed3[0] != '\0')
animatetic = intertic; animatetic = intertic + TICRATE;
if (animatetic) if (animatetic && intertic >= animatetic)
{ {
INT32 animatetimer = (intertic - animatetic); INT32 animatetimer = (intertic - animatetic);
if (animatetimer <= 8) if (animatetimer <= 12)
{ {
xoffset1 = -(animatetimer * 40); xoffset1 = -(animatetimer * 40);
xoffset2 = -((animatetimer-2) * 40); xoffset2 = -((animatetimer-2) * 40);
xoffset4 = -((animatetimer-4) * 40);
xoffset5 = -((animatetimer-6) * 40);
if (xoffset2 > 0) xoffset2 = 0; if (xoffset2 > 0) xoffset2 = 0;
if (xoffset4 > 0) xoffset4 = 0;
if (xoffset5 > 0) xoffset5 = 0;
} }
else if (animatetimer <= 19) else if (animatetimer < 28)
{ {
drawsection = 1; drawsection = 1;
xoffset1 = (16-animatetimer) * 40; xoffset1 = (20-animatetimer) * 40;
xoffset2 = (18-animatetimer) * 40; xoffset2 = (22-animatetimer) * 40;
xoffset3 = (20-animatetimer) * 40; xoffset3 = (24-animatetimer) * 40;
xoffset4 = (26-animatetimer) * 40;
xoffset5 = (28-animatetimer) * 40;
if (xoffset1 < 0) xoffset1 = 0; if (xoffset1 < 0) xoffset1 = 0;
if (xoffset2 < 0) xoffset2 = 0; if (xoffset2 < 0) xoffset2 = 0;
if (xoffset3 < 0) xoffset3 = 0;
if (xoffset4 < 0) xoffset4 = 0;
} }
else else
{
drawsection = 1; drawsection = 1;
if (animatetimer == 28)
S_StartSound(NULL, sfx_s3k68);
}
} }
if (drawsection == 1) if (drawsection == 1)
@ -356,39 +370,60 @@ void Y_IntermissionDrawer(void)
V_DrawLevelTitle(data.spec.passedx3 + xoffset2, ttheight, 0, data.spec.passed3); V_DrawLevelTitle(data.spec.passedx3 + xoffset2, ttheight, 0, data.spec.passed3);
ttheight += V_LevelNameHeight(data.spec.passed4) + 2; ttheight += V_LevelNameHeight(data.spec.passed4) + 2;
V_DrawLevelTitle(data.spec.passedx4 + xoffset3, ttheight, 0, data.spec.passed4); V_DrawLevelTitle(data.spec.passedx4 + xoffset3, ttheight, 0, data.spec.passed4);
}
else if (data.spec.passed1[0] != '\0') V_DrawCenteredString(BASEVIDWIDTH/2 + xoffset4, 108 - 4, 0, "\x86""50 RINGS, NO SHIELD");
{ V_DrawCenteredString(BASEVIDWIDTH/2 + xoffset5, 124 - 4, 0, "\x86""PRESS ""\x82""JUMP""\x86"", THEN ""\x82""SPIN");
ttheight = 24;
V_DrawLevelTitle(data.spec.passedx1 + xoffset1, ttheight, 0, data.spec.passed1);
ttheight += V_LevelNameHeight(data.spec.passed2) + 2;
V_DrawLevelTitle(data.spec.passedx2 + xoffset2, ttheight, 0, data.spec.passed2);
} }
else else
{ {
ttheight = 24 + (V_LevelNameHeight(data.spec.passed2)/2) + 2; if (data.spec.passed1[0] != '\0')
V_DrawLevelTitle(data.spec.passedx2 + xoffset1, ttheight, 0, data.spec.passed2); {
ttheight = 24;
V_DrawLevelTitle(data.spec.passedx1 + xoffset1, ttheight, 0, data.spec.passed1);
ttheight += V_LevelNameHeight(data.spec.passed2) + 2;
V_DrawLevelTitle(data.spec.passedx2 + xoffset2, ttheight, 0, data.spec.passed2);
}
else
{
ttheight = 24 + (V_LevelNameHeight(data.spec.passed2)/2) + 2;
V_DrawLevelTitle(data.spec.passedx2 + xoffset1, ttheight, 0, data.spec.passed2);
}
V_DrawScaledPatch(152 + xoffset4, 108, 0, data.spec.bonuspatch);
V_DrawTallNum(BASEVIDWIDTH + xoffset4 - 68, 109, 0, data.spec.bonus.points);
V_DrawScaledPatch(152 + xoffset5, 124, 0, data.spec.pscore);
V_DrawTallNum(BASEVIDWIDTH + xoffset5 - 68, 125, 0, data.spec.score);
} }
// draw the emeralds // draw the emeralds
//if (intertic & 1) //if (intertic & 1)
{ {
boolean drawthistic = !(ALL7EMERALDS(emeralds) && (intertic & 1));
INT32 emeraldx = 152 - 3*28; INT32 emeraldx = 152 - 3*28;
INT32 em = (gamemap - sstage_start); INT32 em = (gamemap - sstage_start);
for (i = 0; i < 7; ++i) if (em == 7)
{ {
if ((i != em) && !(intertic & 1) && (emeralds & (1 << i))) if (!stagefailed)
V_DrawScaledPatch(emeraldx, 74, 0, emeraldpics[0][i]); {
emeraldx += 28; fixed_t adjust = 2*(FINESINE(FixedAngle((intertic + 1)<<(FRACBITS-4)) & FINEMASK));
V_DrawFixedPatch(152<<FRACBITS, (74<<FRACBITS) - adjust, FRACUNIT, 0, emeraldpics[0][em], NULL);
}
} }
else if (em < 7)
if (em < 7)
{ {
static UINT8 emeraldbounces = 0; static UINT8 emeraldbounces = 0;
static INT32 emeraldmomy = 20; static INT32 emeraldmomy = 20;
static INT32 emeraldy = -40; static INT32 emeraldy = -40;
if (drawthistic)
for (i = 0; i < 7; ++i)
{
if ((i != em) && (emeralds & (1 << i)))
V_DrawScaledPatch(emeraldx, 74, 0, emeraldpics[0][i]);
emeraldx += 28;
}
emeraldx = 152 + (em-3)*28; emeraldx = 152 + (em-3)*28;
if (intertic <= 1) if (intertic <= 1)
@ -399,7 +434,7 @@ void Y_IntermissionDrawer(void)
} }
else else
{ {
if (emeralds & (1 << em)) if (!stagefailed)
{ {
if (emeraldbounces < 3) if (emeraldbounces < 3)
{ {
@ -427,16 +462,12 @@ void Y_IntermissionDrawer(void)
emeraldy = 74; emeraldy = 74;
} }
} }
V_DrawScaledPatch(emeraldx, emeraldy, 0, emeraldpics[0][em]); if (drawthistic)
V_DrawScaledPatch(emeraldx, emeraldy, 0, emeraldpics[0][em]);
} }
} }
} }
V_DrawScaledPatch(152, 108, 0, data.spec.bonuspatch);
V_DrawTallNum(BASEVIDWIDTH - 68, 109, 0, data.spec.bonus.points);
V_DrawScaledPatch(152, 124, 0, data.spec.pscore);
V_DrawTallNum(BASEVIDWIDTH - 68, 125, 0, data.spec.score);
// Draw continues! // Draw continues!
if (!multiplayer /* && (data.spec.continues & 0x80) */) // Always draw outside of netplay if (!multiplayer /* && (data.spec.continues & 0x80) */) // Always draw outside of netplay
{ {
@ -831,7 +862,7 @@ void Y_Ticker(void)
if ((!modifiedgame || savemoddata) && !(netgame || multiplayer) && !demoplayback) if ((!modifiedgame || savemoddata) && !(netgame || multiplayer) && !demoplayback)
{ {
if (M_UpdateUnlockablesAndExtraEmblems()) if (M_UpdateUnlockablesAndExtraEmblems())
S_StartSound(NULL, sfx_ncitem); S_StartSound(NULL, sfx_s3k68);
G_SaveGameData(); G_SaveGameData();
} }
@ -865,7 +896,7 @@ void Y_Ticker(void)
if (playeringame[i] && (players[i].cmd.buttons & BT_USE)) if (playeringame[i] && (players[i].cmd.buttons & BT_USE))
skip = true; skip = true;
if ((data.spec.continues & 0x80) && tallydonetic != -1) if (((data.spec.continues & 0x80) || ALL7EMERALDS(emeralds)) && tallydonetic != -1)
{ {
if ((intertic - tallydonetic) > (3*TICRATE)/2) if ((intertic - tallydonetic) > (3*TICRATE)/2)
{ {
@ -896,7 +927,7 @@ void Y_Ticker(void)
if ((!modifiedgame || savemoddata) && !(netgame || multiplayer) && !demoplayback) if ((!modifiedgame || savemoddata) && !(netgame || multiplayer) && !demoplayback)
{ {
if (M_UpdateUnlockablesAndExtraEmblems()) if (M_UpdateUnlockablesAndExtraEmblems())
S_StartSound(NULL, sfx_ncitem); S_StartSound(NULL, sfx_s3k68);
G_SaveGameData(); G_SaveGameData();
} }
@ -1307,6 +1338,11 @@ void Y_StartIntermission(void)
else else
strcpy(data.spec.passed1, "YOU GOT"); strcpy(data.spec.passed1, "YOU GOT");
strcpy(data.spec.passed2, "A CHAOS EMERALD"); strcpy(data.spec.passed2, "A CHAOS EMERALD");
if (gamemap > (sstage_start + 5))
{
data.spec.passed2[15] = '?';
data.spec.passed2[16] = '\0';
}
} }
data.spec.passedx1 = (BASEVIDWIDTH - V_LevelNameWidth(data.spec.passed1))/2; data.spec.passedx1 = (BASEVIDWIDTH - V_LevelNameWidth(data.spec.passed1))/2;
data.spec.passedx2 = (BASEVIDWIDTH - V_LevelNameWidth(data.spec.passed2))/2; data.spec.passedx2 = (BASEVIDWIDTH - V_LevelNameWidth(data.spec.passed2))/2;
@ -1857,7 +1893,7 @@ static void Y_AwardSpecialStageBonus(void)
if (!playeringame[i] || players[i].lives < 1) // not active or game over if (!playeringame[i] || players[i].lives < 1) // not active or game over
Y_SetNullBonus(&players[i], &localbonus); Y_SetNullBonus(&players[i], &localbonus);
else if (useNightsSS) // Link instead of Score else if (maptol & TOL_NIGHTS) // Link instead of Rings
Y_SetLinkBonus(&players[i], &localbonus); Y_SetLinkBonus(&players[i], &localbonus);
else else
Y_SetRingBonus(&players[i], &localbonus); Y_SetRingBonus(&players[i], &localbonus);