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]);
// 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->continues = players[i].continues;
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]);
// 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].continues = rsp->continues;
players[i].scoreadd = rsp->scoreadd;
@ -2377,11 +2379,11 @@ static void CL_RemovePlayer(INT32 playernum)
if (gametype == GT_CTF)
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.
if (G_IsSpecialStage(gamemap))
{
INT32 i, count, increment, rings;
INT32 i, count, increment, spheres;
for (i = 0, count = 0; i < MAXPLAYERS; i++)
{
@ -2390,19 +2392,19 @@ static void CL_RemovePlayer(INT32 playernum)
}
count--;
rings = players[playernum].rings;
increment = rings/count;
spheres = players[playernum].spheres;
increment = spheres/count;
for (i = 0; i < MAXPLAYERS; i++)
{
if (playeringame[i] && i != playernum)
{
if (rings < increment)
P_GivePlayerRings(&players[i], rings);
if (spheres < increment)
P_GivePlayerSpheres(&players[i], spheres);
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];
// Score is resynched in the confirm resync packet
INT32 rings;
INT16 rings;
INT16 spheres;
SINT8 lives;
SINT8 continues;
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};
static CV_PossibleValue_t timetic_cons_t[] = {{0, "Normal"}, {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
static CV_PossibleValue_t timetic_cons_t[] = {{0, "Classic"}, {1, "Centiseconds"}, {2, "Mania"}, {3, "Tics"}, {0, NULL}};
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}};
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.
if (players[playernum].spectator)
{
players[playernum].score = 0;
players[playernum].rings = 0;
players[playernum].score = players[playernum].rings = 0;
if (players[playernum].mo)
players[playernum].mo->health = 1;
}

View File

@ -324,7 +324,8 @@ typedef struct player_s
angle_t drawangle;
// player's ring count
INT32 rings;
INT16 rings;
INT16 spheres;
SINT8 pity; // i pity the fool.
INT32 currentweapon; // current weapon selected.
@ -460,7 +461,7 @@ typedef struct player_s
tic_t marebegunat; // Leveltime when mare begun
tic_t startedtime; // Time which you started this mare with.
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 lastmarescore; // score for the last mare
UINT8 lastmare; // previous mare

View File

@ -2673,10 +2673,6 @@ static void readmaincfg(MYFILE *f)
sstage_start = (INT16)value;
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"))
{
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
"S_EGGSHIELD",
"S_EGGSHIELDBREAK",
// Green Snapper
"S_GSNAPPER_STND",
@ -4367,8 +4364,17 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
"S_RING",
// Blue Sphere for special stages
"S_BLUEBALL",
"S_BLUEBALLSPARK",
"S_BLUESPHERE",
"S_BLUESPHEREBONUS",
"S_BLUESPHERESPARK",
// NiGHTS Chip
"S_NIGHTSCHIP",
"S_NIGHTSCHIPBONUS",
// NiGHTS Star
"S_NIGHTSSTAR",
"S_NIGHTSSTARXMAS",
// Gravity Wells for special stages
"S_GRAVWELLGREEN",
@ -4426,8 +4432,10 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
"S_CEMG6",
"S_CEMG7",
// Emeralds (for hunt)
"S_EMER1",
// Emerald hunt shards
"S_SHRD1",
"S_SHRD2",
"S_SHRD3",
// Bubble Source
"S_BUBBLES1",
@ -4709,7 +4717,6 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
// Arrow
"S_ARROW",
"S_TEMPSHI",
"S_ARROWBONK",
// Trapgoyle Demon fire
@ -4739,6 +4746,7 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
"S_POLYGONTREE",
"S_BUSHTREE",
"S_BUSHREDTREE",
"S_SPRINGTREE",
// THZ flowers
"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_NIGHTSCORE100_2",
"S_NIGHTSWING",
"S_NIGHTSWING_XMAS",
// NiGHTS Paraloop Powerups
"S_NIGHTSSUPERLOOP",
"S_NIGHTSDRILLREFILL",
@ -6027,14 +6032,11 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
"S_ORBITEM6",
"S_ORBITEM7",
"S_ORBITEM8",
"S_ORBITEM9",
"S_ORBITEM10",
"S_ORBITEM11",
"S_ORBITEM12",
"S_ORBITEM13",
"S_ORBITEM14",
"S_ORBITEM15",
"S_ORBITEM16",
"S_ORBIDYA1",
"S_ORBIDYA2",
"S_ORBIDYA3",
"S_ORBIDYA4",
"S_ORBIDYA5",
// "Flicky" helper
"S_NIGHTOPIANHELPER1",
@ -6047,6 +6049,26 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
"S_NIGHTOPIANHELPER8",
"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
"S_HIVEELEMENTAL_LOOK",
"S_HIVEELEMENTAL_PREPARE1",
@ -6322,7 +6344,7 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s
// Collectible Items
"MT_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_BLUETEAMRING", //Rings collectable by blue team.
"MT_TOKEN", // Special Stage Token
@ -6466,6 +6488,7 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s
"MT_POLYGONTREE",
"MT_BUSHTREE",
"MT_BUSHREDTREE",
"MT_SPRINGTREE",
// Techno Hill Scenery
"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_HOOPCENTER", // Center of a hoop
"MT_NIGHTSCORE",
"MT_NIGHTSWING",
"MT_NIGHTSCHIP", // NiGHTS Chip
"MT_NIGHTSSTAR", // NiGHTS Star
"MT_NIGHTSSUPERLOOP",
"MT_NIGHTSDRILLREFILL",
"MT_NIGHTSHELPER",
@ -6786,6 +6810,8 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s
"MT_NIGHTSLINKFREEZE",
"MT_EGGCAPSULE",
"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
"MT_HIVEELEMENTAL",

View File

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

View File

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

View File

@ -116,7 +116,7 @@ INT32 secondarydisplayplayer; // for splitscreen
tic_t gametic;
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)
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
boolean looptitle = false;
boolean useNightsSS = false;
UINT8 skincolor_redteam = SKINCOLOR_RED;
UINT8 skincolor_blueteam = SKINCOLOR_BLUE;
@ -2201,7 +2200,7 @@ void G_PlayerReborn(INT32 player)
p->pflags |= PF_JUMPDOWN;
p->playerstate = PST_LIVE;
p->rings = 0; // 0 rings
p->rings = p->spheres = 0; // 0 rings
p->panim = PA_IDLE; // standing animation
//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;
sstage_start = 50;
sstage_end = 57; // 8 special stages in vanilla SRB2
useNightsSS = false; //true;
// initialize free sfx slots for skin sounds
S_InitRuntimeSounds();

View File

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

View File

@ -89,7 +89,7 @@ patch_t *tallinfin;
// 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;
patch_t *tokenicon;
static patch_t *exiticon;
@ -256,6 +256,7 @@ void HU_LoadGraphics(void)
emeraldpics[0][4] = W_CachePatchName("CHAOS5", PU_HUDGFX);
emeraldpics[0][5] = W_CachePatchName("CHAOS6", 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][1] = W_CachePatchName("TEMER2", PU_HUDGFX);
@ -264,6 +265,7 @@ void HU_LoadGraphics(void)
emeraldpics[1][4] = W_CachePatchName("TEMER5", PU_HUDGFX);
emeraldpics[1][5] = W_CachePatchName("TEMER6", 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][1] = W_CachePatchName("EMBOX2", PU_HUDGFX);
@ -272,6 +274,7 @@ void HU_LoadGraphics(void)
emeraldpics[2][4] = W_CachePatchName("EMBOX5", PU_HUDGFX);
emeraldpics[2][5] = W_CachePatchName("EMBOX6", PU_HUDGFX);
emeraldpics[2][6] = W_CachePatchName("EMBOX7", PU_HUDGFX);
//emeraldpics[2][7] = W_CachePatchName("EMBOX8", PU_HUDGFX); -- unused
}
// Initialise Heads up

View File

@ -63,7 +63,7 @@ extern patch_t *tallnum[10];
extern patch_t *nightsnum[10];
extern patch_t *lt_font[LT_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 *bflagico;
extern patch_t *rmatcico;

View File

@ -118,10 +118,12 @@ char sprnames[NUMSPRITES + 1][5] =
"TOKE", // Special Stage Token
"RFLG", // Red CTF Flag
"BFLG", // Blue CTF Flag
"NWNG", // NiGHTS Wing collectable item.
"SPHR", // Sphere
"NCHP", // NiGHTS chip
"NSTR", // NiGHTS star
"EMBM", // Emblem
"CEMG", // Chaos Emeralds
"EMER", // Emerald Hunt
"SHRD", // Emerald hunt shards
// Interactive Objects
"BBLS", // water bubble source
@ -187,6 +189,7 @@ char sprnames[NUMSPRITES + 1][5] =
"TRE3", // Frozen Hillside
"TRE4", // Polygon
"TRE5", // Bush tree
"TRE6", // Spring tree
// Techno Hill Scenery
"THZP", // THZ1 Steam Flower
@ -392,6 +395,9 @@ char sprnames[NUMSPRITES + 1][5] =
"NSCR", // NiGHTS score sprite
"NPRU", // Nights Powerups
"CAPS", // Capsule thingy for NiGHTS
"IDYA", // Ideya
"NTPN", // Nightopian
"SHLP", // Shleep
// Secret badniks and hazards, shhhh
"HIVE",
@ -432,9 +438,6 @@ char sprnames[NUMSPRITES + 1][5] =
"ROIO",
"ROIP",
// Blue Spheres
"BBAL",
// Gravity Well Objects
"GWLG",
"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_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, 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
@ -1021,7 +1024,8 @@ state_t states[NUMSTATES] =
{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_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
{SPR_GSNP, 0, 1, {A_Look}, 0, 0, S_GSNAPPER_STND}, // S_GSNAPPER_STND
@ -1591,18 +1595,22 @@ state_t states[NUMSTATES] =
// Ring
{SPR_RING, FF_ANIMATE|FF_GLOBALANIM, -1, {NULL}, 23, 1, S_RING}, // S_RING
// Blue Sphere Replacement for special stages
{SPR_BBAL, 0, -1, {NULL}, 0, 0, S_NULL}, // S_BLUEBALL
{SPR_BBAL, 0, 20, {NULL}, 0, 0, S_NULL}, // S_BLUEBALLSPARK
// Blue Sphere for special stages
{SPR_SPHR, FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_NULL}, // S_BLUESPHERE
{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
{SPR_GWLG, 0, 1, {NULL}, 0, 0, S_GRAVWELLGREEN2}, // S_GRAVWELLGREEN
{SPR_GWLG, 1, 1, {NULL}, 0, 0, S_GRAVWELLGREEN3}, // S_GRAVWELLGREEN2
{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
{SPR_GWLG, FF_ANIMATE, -1, {NULL}, 2, 1, S_NULL}, // S_GRAVWELLGREEN
{SPR_GWLR, FF_ANIMATE, -1, {NULL}, 2, 1, S_NULL}, // S_GRAVWELLRED
// Individual Team Rings (now with shield attracting action! =P)
{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|6, -1, {NULL}, 0, 0, S_NULL}, // S_CEMG7
// Emeralds (for hunt)
{SPR_EMER, 0, -1, {NULL}, 0, 0, S_NULL}, // S_EMER1
// Emerald hunt shards
{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
{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_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_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_TRE5, 0, -1, {NULL}, 0, 0, S_NULL}, // S_BUSHTREE
{SPR_TRE5, 1, -1, {NULL}, 0, 0, S_NULL}, // S_BUSHREDTREE
{SPR_TRE6, 0, -1, {NULL}, 0, 0, S_NULL}, // S_SPRINGTREE
// THZ flowers
{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|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
{SPR_NPRU, 0, -1, {NULL}, 0, 0, S_NULL}, // S_NIGHTSSUPERLOOP
{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
// 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, 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
@ -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|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|8, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM8}, // S_ORBITEM9
{SPR_CEMG, FF_FULLBRIGHT|9, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM8}, // S_ORBITEM10
{SPR_CEMG, FF_FULLBRIGHT|10, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM8}, // S_ORBITEM11
{SPR_CEMG, FF_FULLBRIGHT|11, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM8}, // S_ORBITEM12
{SPR_CEMG, FF_FULLBRIGHT|12, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM8}, // S_ORBITEM13
{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
{SPR_IDYA, FF_TRANS20|FF_FULLBRIGHT, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBIDYA1}, // S_ORBIDYA1
{SPR_IDYA, FF_TRANS20|FF_FULLBRIGHT|1, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBIDYA2}, // S_ORBIDYA2
{SPR_IDYA, FF_TRANS20|FF_FULLBRIGHT|2, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBIDYA3}, // S_ORBIDYA3
{SPR_IDYA, FF_TRANS20|FF_FULLBRIGHT|3, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBIDYA4}, // S_ORBIDYA4
{SPR_IDYA, FF_TRANS20|FF_FULLBRIGHT|4, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBIDYA5}, // S_ORBIDYA5
// Flicky helper for NiGHTS
{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_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
{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
@ -4337,7 +4360,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
sfx_s3k7b, // painsound
S_NULL, // meleestate
S_NULL, // missilestate
S_TEMPSHI, // deathstate
S_EGGSHIELDBREAK,// deathstate
S_NULL, // xdeathstate
sfx_wbreak, // deathsound
3, // speed
@ -5729,9 +5752,9 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_NULL // raisestate
},
{ // MT_BLUEBALL
-1, // doomednum
S_BLUEBALL, // spawnstate
{ // MT_BLUESPHERE
1706, // doomednum
S_BLUESPHERE, // spawnstate
1000, // spawnhealth
S_NULL, // seestate
sfx_None, // seesound
@ -5742,7 +5765,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
sfx_None, // painsound
S_NULL, // meleestate
S_NULL, // missilestate
S_BLUEBALLSPARK, // deathstate
S_BLUESPHERESPARK, // deathstate
S_NULL, // xdeathstate
sfx_s3k65, // deathsound
38*FRACUNIT, // speed
@ -5753,7 +5776,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
0, // damage
sfx_None, // activesound
MF_SLIDEME|MF_SPECIAL|MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags
S_NULL // raisestate
S_BLUESPHEREBONUS // raisestate
},
{ // MT_REDTEAMRING
@ -5825,7 +5848,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_NULL, // missilestate
S_SPRK1, // deathstate
S_NULL, // xdeathstate
sfx_token, // deathsound
sfx_None, // deathsound
0, // speed
8*FRACUNIT, // radius
16*FRACUNIT, // height
@ -6103,7 +6126,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
{ // MT_EMERHUNT
320, // doomednum
S_EMER1, // spawnstate
S_SHRD1, // spawnstate
1000, // spawnhealth
S_NULL, // seestate
sfx_None, // seesound
@ -6118,8 +6141,8 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_NULL, // xdeathstate
sfx_cgot, // deathsound
8, // speed
16*FRACUNIT, // radius
32*FRACUNIT, // height
12*FRACUNIT, // radius
42*FRACUNIT, // height
0, // display offset
4, // mass
0, // damage
@ -6588,7 +6611,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
},
{ // MT_SPIKEBALL
-1, // doomednum
521, // doomednum
S_SPIKEBALL1, // spawnstate
1000, // spawnhealth
S_NULL, // seestate
@ -6604,7 +6627,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_NULL, // xdeathstate
sfx_None, // deathsound
10*FRACUNIT, // speed
4*FRACUNIT, // radius
12*FRACUNIT, // radius
8*FRACUNIT, // height
0, // display offset
DMG_SPIKE, // mass
@ -8803,7 +8826,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
{ // MT_GFZTREE
806, // doomednum
S_GFZTREE, // spawnstate
S_GFZTREE, // spawnstate
1000, // spawnhealth
S_NULL, // seestate
sfx_None, // seesound
@ -8830,7 +8853,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
{ // MT_GFZBERRYTREE
807, // doomednum
S_GFZBERRYTREE, // spawnstate
S_GFZBERRYTREE, // spawnstate
1000, // spawnhealth
S_NULL, // seestate
sfx_None, // seesound
@ -8857,7 +8880,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
{ // MT_GFZCHERRYTREE
808, // doomednum
S_GFZCHERRYTREE, // spawnstate
S_GFZCHERRYTREE, // spawnstate
1000, // spawnhealth
S_NULL, // seestate
sfx_None, // seesound
@ -8884,7 +8907,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
{ // MT_CHECKERTREE
810, // doomednum
S_CHECKERTREE, // spawnstate
S_CHECKERTREE, // spawnstate
1000, // spawnhealth
S_NULL, // seestate
sfx_None, // seesound
@ -8911,7 +8934,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
{ // MT_CHECKERSUNSETTREE
811, // doomednum
S_CHECKERSUNSETTREE, // spawnstate
S_CHECKERSUNSETTREE, // spawnstate
1000, // spawnhealth
S_NULL, // seestate
sfx_None, // seesound
@ -8938,7 +8961,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
{ // MT_FHZTREE
812, // doomednum
S_FHZTREE, // spawnstate
S_FHZTREE, // spawnstate
1000, // spawnhealth
S_NULL, // seestate
sfx_None, // seesound
@ -8965,7 +8988,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
{ // MT_FHZPINKTREE
813, // doomednum
S_FHZPINKTREE, // spawnstate
S_FHZPINKTREE, // spawnstate
1000, // spawnhealth
S_NULL, // seestate
sfx_None, // seesound
@ -8992,7 +9015,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
{ // MT_POLYGONTREE
814, // doomednum
S_POLYGONTREE, // spawnstate
S_POLYGONTREE, // spawnstate
1000, // spawnhealth
S_NULL, // seestate
sfx_None, // seesound
@ -9019,7 +9042,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
{ // MT_BUSHTREE
815, // doomednum
S_BUSHTREE, // spawnstate
S_BUSHTREE, // spawnstate
1000, // spawnhealth
S_NULL, // seestate
sfx_None, // seesound
@ -9046,7 +9069,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
{ // MT_BUSHREDTREE
816, // doomednum
S_BUSHREDTREE, // spawnstate
S_BUSHREDTREE, // spawnstate
1000, // spawnhealth
S_NULL, // seestate
sfx_None, // seesound
@ -9071,6 +9094,33 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
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
900, // doomednum
S_THZFLOWERA, // spawnstate
@ -14406,7 +14456,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
0, // painchance
sfx_None, // painsound
S_ORBITEM1, // meleestate
S_NULL, // missilestate
S_ORBIDYA1, // missilestate
S_NULL, // deathstate
S_NULL, // xdeathstate
sfx_None, // deathsound
@ -16131,11 +16181,11 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_NULL // raisestate
},
{ // MT_NIGHTSWING
1706, // doomednum
S_NIGHTSWING, // spawnstate
{ // MT_NIGHTSCHIP
-1, // doomednum
S_NIGHTSCHIP, // spawnstate
1000, // spawnhealth
S_NIGHTSWING_XMAS, // seestate
S_NULL, // seestate
sfx_None, // seesound
8, // reactiontime
sfx_None, // attacksound
@ -16146,14 +16196,41 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_NULL, // missilestate
S_SPRK1, // deathstate
S_NULL, // xdeathstate
sfx_None, // deathsound
sfx_ncchip, // deathsound
1, // speed
12*FRACUNIT, // radius
16*FRACUNIT, // radius
24*FRACUNIT, // height
0, // display offset
4, // mass
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
S_NULL // raisestate
},
@ -16320,7 +16397,6 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_NULL // raisestate
},
// the flicky that orbits the player when they have a Nightopian helper
{ // MT_NIGHTOPIANHELPER
-1, // doomednum
S_NIGHTOPIANHELPER1, // spawnstate
@ -16348,6 +16424,60 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
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
3190, // doomednum
S_HIVEELEMENTAL_LOOK, // spawnstate

View File

@ -337,10 +337,12 @@ typedef enum sprite
SPR_TOKE, // Special Stage Token
SPR_RFLG, // Red 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_CEMG, // Chaos Emeralds
SPR_EMER, // Emerald Hunt
SPR_SHRD, // Emerald Hunt
// Interactive Objects
SPR_BBLS, // water bubble source
@ -406,6 +408,7 @@ typedef enum sprite
SPR_TRE3, // Frozen Hillside
SPR_TRE4, // Polygon
SPR_TRE5, // Bush tree
SPR_TRE6, // Spring tree
// Techno Hill Scenery
SPR_THZP, // THZ1 Steam Flower
@ -611,6 +614,9 @@ typedef enum sprite
SPR_NSCR, // NiGHTS score sprite
SPR_NPRU, // Nights Powerups
SPR_CAPS, // Capsule thingy for NiGHTS
SPR_IDYA, // Ideya
SPR_NTPN, // Nightopian
SPR_SHLP, // Shleep
// Secret badniks and hazards, shhhh
SPR_HIVE,
@ -651,9 +657,6 @@ typedef enum sprite
SPR_ROIO,
SPR_ROIP,
// Blue Spheres
SPR_BBAL,
// Gravity Well Objects
SPR_GWLG,
SPR_GWLR,
@ -1149,6 +1152,7 @@ typedef enum state
// Egg Shield for Egg Guard
S_EGGSHIELD,
S_EGGSHIELDBREAK,
// Green Snapper
S_GSNAPPER_STND,
@ -1717,17 +1721,21 @@ typedef enum state
S_RING,
// Blue Sphere for special stages
S_BLUEBALL,
S_BLUEBALLSPARK,
S_BLUESPHERE,
S_BLUESPHEREBONUS,
S_BLUESPHERESPARK,
// NiGHTS Chip
S_NIGHTSCHIP,
S_NIGHTSCHIPBONUS,
// NiGHTS Star
S_NIGHTSSTAR,
S_NIGHTSSTARXMAS,
// Gravity Wells for special stages
S_GRAVWELLGREEN,
S_GRAVWELLGREEN2,
S_GRAVWELLGREEN3,
S_GRAVWELLRED,
S_GRAVWELLRED2,
S_GRAVWELLRED3,
// Individual Team Rings
S_TEAMRING,
@ -1776,8 +1784,10 @@ typedef enum state
S_CEMG6,
S_CEMG7,
// Emeralds (for hunt)
S_EMER1,
// Emerald hunt shards
S_SHRD1,
S_SHRD2,
S_SHRD3,
// Bubble Source
S_BUBBLES1,
@ -2061,7 +2071,6 @@ typedef enum state
// Arrow
S_ARROW,
S_TEMPSHI,
S_ARROWBONK,
// Trapgoyle Demon fire
@ -2091,6 +2100,7 @@ typedef enum state
S_POLYGONTREE,
S_BUSHTREE,
S_BUSHREDTREE,
S_SPRINGTREE,
// THZ flowers
S_THZFLOWERA, // THZ1 Steam flower
@ -3359,9 +3369,6 @@ typedef enum state
S_NIGHTSCORE90_2,
S_NIGHTSCORE100_2,
S_NIGHTSWING,
S_NIGHTSWING_XMAS,
// NiGHTS Paraloop Powerups
S_NIGHTSSUPERLOOP,
S_NIGHTSDRILLREFILL,
@ -3379,14 +3386,11 @@ typedef enum state
S_ORBITEM6,
S_ORBITEM7,
S_ORBITEM8,
S_ORBITEM9,
S_ORBITEM10,
S_ORBITEM11,
S_ORBITEM12,
S_ORBITEM13,
S_ORBITEM14,
S_ORBITEM15,
S_ORBITEM16,
S_ORBIDYA1,
S_ORBIDYA2,
S_ORBIDYA3,
S_ORBIDYA4,
S_ORBIDYA5,
// "Flicky" helper
S_NIGHTOPIANHELPER1,
@ -3399,6 +3403,25 @@ typedef enum state
S_NIGHTOPIANHELPER8,
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
S_HIVEELEMENTAL_LOOK,
S_HIVEELEMENTAL_PREPARE1,
@ -3694,7 +3717,7 @@ typedef enum mobj_type
// Collectible Items
MT_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_BLUETEAMRING, //Rings collectable by blue team.
MT_TOKEN, // Special Stage token for special stage
@ -3838,6 +3861,7 @@ typedef enum mobj_type
MT_POLYGONTREE,
MT_BUSHTREE,
MT_BUSHREDTREE,
MT_SPRINGTREE,
// Techno Hill Scenery
MT_THZFLOWER1,
@ -4150,7 +4174,8 @@ typedef enum mobj_type
MT_HOOPCOLLIDE, // Collision detection for NiGHTS hoops
MT_HOOPCENTER, // Center of a hoop
MT_NIGHTSCORE,
MT_NIGHTSWING,
MT_NIGHTSCHIP, // NiGHTS Chip
MT_NIGHTSSTAR, // NiGHTS Star
MT_NIGHTSSUPERLOOP,
MT_NIGHTSDRILLREFILL,
MT_NIGHTSHELPER,
@ -4158,6 +4183,8 @@ typedef enum mobj_type
MT_NIGHTSLINKFREEZE,
MT_EGGCAPSULE,
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
MT_HIVEELEMENTAL,

View File

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

View File

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

View File

@ -728,7 +728,7 @@ void Command_Setrings_f(void)
// P_GivePlayerRings does value clamping
players[consoleplayer].rings = 0;
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
G_SetGameModified(multiplayer);
@ -1010,7 +1010,7 @@ void OP_NightsObjectplace(player_t *player)
mt->options = (UINT16)((player->mo->z - fheight)>>FRACBITS);
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!
@ -1024,26 +1024,26 @@ void OP_NightsObjectplace(player_t *player)
P_SpawnMapThing(mt);
}
// This places a ring!
// This places a sphere!
if (cmd->buttons & BT_WEAPONNEXT)
{
player->pflags |= PF_ATTACKDOWN;
if (!OP_HeightOkay(player, false))
return;
mt = OP_CreateNewMapThing(player, (UINT16)mobjinfo[MT_RING].doomednum, false);
P_SpawnHoopsAndRings(mt);
mt = OP_CreateNewMapThing(player, (UINT16)mobjinfo[MT_BLUESPHERE].doomednum, false);
P_SpawnHoopsAndRings(mt, false);
}
// This places a wing item!
// This places a ring!
if (cmd->buttons & BT_WEAPONPREV)
{
player->pflags |= PF_ATTACKDOWN;
if (!OP_HeightOkay(player, false))
return;
mt = OP_CreateNewMapThing(player, (UINT16)mobjinfo[MT_NIGHTSWING].doomednum, false);
P_SpawnHoopsAndRings(mt);
mt = OP_CreateNewMapThing(player, (UINT16)mobjinfo[MT_RING].doomednum, false);
P_SpawnHoopsAndRings(mt, false);
}
// 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
|| 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 == 1705 || mt->type == 1713 // NiGHTS Hoops
|| mt->type == 1800) // Mario Coin
{
P_SpawnHoopsAndRings(mt);
P_SpawnHoopsAndRings(mt, false);
}
else
P_SpawnMapThing(mt);
@ -1227,7 +1227,7 @@ void OP_ObjectplaceMovement(player_t *player)
|| mt->type == 1705 || mt->type == 1713 // NiGHTS Hoops
|| mt->type == 1800) // Mario Coin
{
P_SpawnHoopsAndRings(mt);
P_SpawnHoopsAndRings(mt, false);
}
else
P_SpawnMapThing(mt);

View File

@ -8604,10 +8604,12 @@ void A_OrbitNights(mobj_t* actor)
return;
#endif
if (!actor->target || !actor->target->player ||
!(actor->target->player->powers[pw_carry] == CR_NIGHTSMODE) || !actor->target->player->nightstime
if (!actor->target
|| (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
|| (ishelper && !actor->target->player->powers[pw_nights_helper]))
|| (ishelper && !actor->target->player->powers[pw_nights_helper]))))
{
P_RemoveMobj(actor);
return;
@ -8633,7 +8635,7 @@ void A_OrbitNights(mobj_t* 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)
&& (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).
//
// 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
//
void A_FadeOverlay(mobj_t *actor)
@ -11199,13 +11201,10 @@ void A_FadeOverlay(mobj_t *actor)
return;
#endif
if (!(locvar1 & 1))
actor->momx = actor->momy = actor->momz = 0;
fade = P_SpawnGhostMobj(actor);
fade->frame = actor->frame;
if (!(locvar1 & 2))
if (!(locvar1 & 1))
{
fade->fuse = 15;
fade->flags2 |= MF2_BOSSNOTRAP;
@ -11213,7 +11212,7 @@ void A_FadeOverlay(mobj_t *actor)
else
fade->fuse = 20;
if (!(locvar1 & 4))
if (!(locvar1 & 2))
P_SetTarget(&actor->tracer, fade);
}

View File

@ -23,6 +23,7 @@
#include "hu_stuff.h"
#include "lua_hook.h"
#include "m_cond.h" // unlockables, emblems, etc
#include "p_setup.h"
#include "m_cheat.h" // objectplace
#include "m_misc.h"
#include "v_video.h" // video flags for CEchos
@ -471,40 +472,49 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
/* FALLTHRU */
case MT_RING:
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_FLINGCOIN:
if (!(P_CanPickupItem(player, false)))
return;
special->momx = special->momy = 0;
special->momx = special->momy = special->momz = 0;
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);
break;
case MT_BLUEBALL:
case MT_BLUESPHERE:
if (!(P_CanPickupItem(player, false)))
return;
P_GivePlayerRings(player, 1);
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)
special->scalespeed = FixedDiv(FixedDiv(special->destscale, special->scale), states[special->info->deathstate].tics<<FRACBITS);
else
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)
P_DoNightsScore(player);
break;
@ -562,7 +572,10 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
P_AddPlayerScore(player, 1000);
if (gametype != GT_COOP || modeattacking) // score only?
{
S_StartSound(toucher, sfx_chchng);
break;
}
tokenlist += special->health;
@ -574,10 +587,17 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
players->gotcontinue = true;
if (P_IsLocalPlayer(player))
S_StartSound(NULL, sfx_s3kac);
else
S_StartSound(toucher, sfx_chchng);
}
else
S_StartSound(toucher, sfx_chchng);
}
else
{
token++;
S_StartSound(toucher, sfx_token);
}
break;
@ -602,7 +622,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
players[i].exiting = (14*TICRATE)/5 + 1;
}
S_StartSound(NULL, sfx_lvpass);
//S_StartSound(NULL, sfx_lvpass);
}
break;
@ -733,45 +753,71 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
// NiGHTS gameplay items and powerups //
// ********************************** //
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.
{
// 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)
boolean spec = G_IsSpecialStage(gamemap);
if (player->bot)
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:
// One second delay
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
|| mo2->type == MT_BLUEBALL
if (!(mo2->type == MT_RING || mo2->type == MT_COIN || mo2->type == MT_BLUESPHERE
|| mo2->type == MT_NIGHTSCHIP || mo2->type == MT_NIGHTSSTAR
|| ((mo2->type == MT_EMBLEM) && (mo2->reactiontime & GE_NIGHTSPULL))))
continue;
@ -903,16 +949,16 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
return;
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++)
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;
players[i].rings = 0;
player->spheres += players[i].spheres;
players[i].spheres = 0;
}
}
if (player->rings <= 0 || player->exiting)
if (player->spheres <= 0 || player->exiting)
return;
// 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"));
}
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:
// 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
@ -1496,12 +1531,6 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
player->pflags |= PF_JUMPSTASIS;
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:
// sanity checks
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))
P_SetTarget(&target->tracer, inflictor);
if (!useNightsSS && G_IsSpecialStage(gamemap) && target->player && sstimer > 6)
sstimer = 6; // Just let P_Ticker take care of the rest.
if (!(maptol & TOL_NIGHTS) && G_IsSpecialStage(gamemap) && target->player && target->player->nightstime > 6)
target->player->nightstime = 6; // Just let P_Ticker take care of the rest.
if (target->flags & (MF_ENEMY|MF_BOSS))
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;
else
{
if (source && source->player)
{
if (player->nightstime > 20*TICRATE)
player->nightstime -= 20*TICRATE;
else
player->nightstime = 1;
}
if (player->nightstime > 5*TICRATE)
player->nightstime -= 5*TICRATE;
else
{
if (player->nightstime > 5*TICRATE)
player->nightstime -= 5*TICRATE;
else
player->nightstime = 1;
}
player->nightstime = 1;
}
if (player->pflags & PF_TRANSFERTOCLOSEST)
@ -2670,7 +2689,7 @@ static inline void P_NiGHTSDamage(mobj_t *target, mobj_t *source)
&& 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("_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
//
// 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).
//
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])
return;
@ -3015,17 +3036,24 @@ void P_SpecialStageDamage(player_t *player, mobj_t *inflictor, mobj_t *source)
}
else
{
P_PlayRinglossSound(player->mo);
if (player->rings >= 10)
player->rings -= 10;
S_StartSound(player->mo, sfx_nghurt);
if (player->nightstime > 5*TICRATE)
player->nightstime -= 5*TICRATE;
else
player->rings = 0;
player->nightstime = 0;
}
P_DoPlayerPain(player, inflictor, source);
if (gametype == GT_CTF && player->gotflag & (GF_REDFLAG|GF_BLUEFLAG))
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.
@ -3175,6 +3203,12 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
return true;
}
if (G_IsSpecialStage(gamemap))
{
P_SpecialStageDamage(player, inflictor, source);
return true;
}
if (!force && inflictor && inflictor->flags & MF_FIRE)
{
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);
mobj_t *P_SpawnGhostMobj(mobj_t *mobj);
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_GiveCoopLives(player_t *player, INT32 numlives, boolean sound);
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_COIN:
case MT_BLUEBALL:
case MT_BLUESPHERE:
case MT_NIGHTSCHIP:
case MT_NIGHTSSTAR:
case MT_REDTEAMRING:
case MT_BLUETEAMRING:
case MT_FLINGRING:
@ -2550,10 +2552,6 @@ static boolean P_ZMovement(mobj_t *mo)
if (!(mo->momx || mo->momy || mo->momz))
return true;
break;
case MT_NIGHTSWING:
if (!(mo->momx || mo->momy || mo->momz))
return true;
break;
case MT_FLAMEJET:
case MT_VERTICALFLAMEJET:
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.
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
mobj->frame = (NUMTRANSMAPS-((mobj->tics>>2)+1))<<FF_TRANSSHIFT;
else // tr_trans60 otherwise
@ -7590,7 +7588,7 @@ void P_MobjThinker(mobj_t *mobj)
P_SetTarget(&mobj->target, NULL);
for (i = 0; i < MAXPLAYERS; i++)
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);
if (dist < shortest)
@ -7775,8 +7773,8 @@ void P_MobjThinker(mobj_t *mobj)
}
if (!bonustime)
{
mobj->flags &= ~MF_NOGRAVITY;
P_SetMobjState(mobj, S_NIGHTSDRONE1);
/*mobj->flags &= ~MF_NOGRAVITY;
P_SetMobjState(mobj, S_NIGHTSDRONE1);*/
mobj->flags2 |= MF2_DONTDRAW;
}
}
@ -7848,7 +7846,9 @@ void P_MobjThinker(mobj_t *mobj)
mobj->flags2 &= ~MF2_DONTDRAW;
}
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;
}
break;
@ -7881,7 +7881,9 @@ void P_MobjThinker(mobj_t *mobj)
break;
case MT_RING:
case MT_COIN:
case MT_BLUEBALL:
case MT_BLUESPHERE:
case MT_NIGHTSCHIP:
case MT_NIGHTSSTAR:
case MT_REDTEAMRING:
case MT_BLUETEAMRING:
// No need to check water. Who cares?
@ -7899,10 +7901,6 @@ void P_MobjThinker(mobj_t *mobj)
else
A_AttractChase(mobj);
break;
case MT_NIGHTSWING:
if (mobj->flags2 & MF2_NIGHTSPULL)
P_NightsItemChase(mobj);
break;
case MT_EMBLEM:
if (mobj->flags2 & MF2_NIGHTSPULL)
P_NightsItemChase(mobj);
@ -8025,7 +8023,7 @@ void P_MobjThinker(mobj_t *mobj)
{
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;
@ -8726,7 +8724,6 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
break;
case MT_RING:
case MT_COIN:
case MT_BLUEBALL:
nummaprings++;
default:
break;
@ -8861,7 +8858,6 @@ void P_RemoveMobj(mobj_t *mobj)
if (mobj->spawnpoint &&
(mobj->type == MT_RING
|| mobj->type == MT_COIN
|| mobj->type == MT_BLUEBALL
|| mobj->type == MT_REDTEAMRING
|| mobj->type == MT_BLUETEAMRING
|| P_WeaponOrPanel(mobj->type))
@ -8881,7 +8877,7 @@ void P_RemoveMobj(mobj_t *mobj)
if (mobj->player && mobj->player->followmobj)
{
P_RemoveMobj(mobj->player->followmobj);
mobj->player->followmobj = NULL;
P_SetTarget(&mobj->player->followmobj, NULL);
}
mobj->health = 0; // Just because
@ -9314,7 +9310,7 @@ void P_SpawnPlayer(INT32 playernum)
p->spectator = p->outofcoop =
(((multiplayer || netgame) && gametype == GT_COOP) // only question status in coop
&& ((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_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);
mobj->health = 1;
p->rings = 0;
p->rings = p->spheres = 0;
p->playerstate = PST_LIVE;
p->bonustime = false;
@ -9402,6 +9398,22 @@ void P_SpawnPlayer(INT32 playernum)
mobj->radius = FixedMul(skins[p->skin].radius, mobj->scale);
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.
P_DoPityCheck(p);
}
@ -9715,10 +9727,6 @@ void P_SpawnMapThing(mapthing_t *mthing)
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)
{
// 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))
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
// If MF_GRENADEBOUNCE is set in the monitor's info,
// skip this step. (Used for gold monitors)
@ -10754,8 +10766,9 @@ ML_EFFECT4 : Don't clip inside the ground
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;
INT32 r, i;
fixed_t x, y, z, finalx, finaly, finalz;
@ -11034,59 +11047,26 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing)
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
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
switch (mthing->type)
{
case 1800:
ringthing = MT_COIN;
break;
case 308: // No team rings in non-CTF
ringthing = (gametype == GT_CTF) ? MT_REDTEAMRING : MT_RING;
break;
case 309: // No team rings in non-CTF
ringthing = (gametype == GT_CTF) ? MT_BLUETEAMRING : MT_RING;
break;
default:
// Spawn rings as blue spheres in special stages, ala S3+K.
if (G_IsSpecialStage(gamemap) && useNightsSS)
ringthing = MT_BLUEBALL;
break;
}
if (mthing->type == mobjinfo[MT_COIN].doomednum)
ringthing = MT_COIN;
else if (mthing->type == mobjinfo[MT_REDTEAMRING].doomednum) // No team rings in non-CTF
ringthing = (gametype == GT_CTF) ? MT_REDTEAMRING : MT_RING;
else if (mthing->type == mobjinfo[MT_BLUETEAMRING].doomednum) // Ditto
ringthing = (gametype == GT_CTF) ? MT_BLUETEAMRING : MT_RING;
else if (mthing->type == mobjinfo[MT_BLUESPHERE].doomednum)
ringthing = MT_BLUESPHERE;
if ((maptol & TOL_NIGHTS) && !G_IsSpecialStage(gamemap))
ringthing = ((ringthing == MT_BLUESPHERE) ? MT_NIGHTSCHIP : MT_NIGHTSSTAR);
else if (ringthing != MT_BLUESPHERE && ultimatemode)
return; // No rings in Ultimate!
// Set proper height
if (mthing->options & MTF_OBJECTFLIP)
@ -11130,8 +11110,14 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing)
}
mobj->angle = FixedAngle(mthing->angle*FRACUNIT);
mobj->flags2 |= MF2_AMBUSH;
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
@ -11141,17 +11127,13 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing)
else if (mthing->type == 600 || mthing->type == 601)
{
INT32 dist = 64*FRACUNIT;
mobjtype_t ringthing = MT_RING;
if (mthing->type == 601)
dist = 128*FRACUNIT;
// No rings in Ultimate!
if (ultimatemode && !(G_IsSpecialStage(gamemap) || maptol & TOL_NIGHTS))
return;
// Spawn rings as blue spheres in special stages, ala S3+K.
if (G_IsSpecialStage(gamemap) && useNightsSS)
ringthing = MT_BLUEBALL;
if ((maptol & TOL_NIGHTS) && !G_IsSpecialStage(gamemap))
ringthing = MT_NIGHTSSTAR;
else if (ultimatemode)
return; // No rings in Ultimate!
for (r = 1; r <= 5; r++)
{
@ -11187,31 +11169,30 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing)
mobj->angle = FixedAngle(mthing->angle*FRACUNIT);
if (mthing->options & MTF_AMBUSH)
mobj->flags2 |= MF2_AMBUSH;
if ((maptol & TOL_XMAS) && (ringthing == MT_NIGHTSSTAR))
P_SetMobjState(mobj, mobj->info->seestate);
}
}
// Diagonal rings (handles both types)
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;
if (mthing->type == 603)
iterations = 10;
// No rings in Ultimate!
if (ultimatemode && !(G_IsSpecialStage(gamemap) || maptol & TOL_NIGHTS))
return;
if ((maptol & TOL_NIGHTS) && !G_IsSpecialStage(gamemap))
ringthing = MT_NIGHTSSTAR;
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;
angle >>= ANGLETOFINESHIFT;
closestangle = FixedAngle(mthing->angle*FRACUNIT);
fa = (closestangle >> ANGLETOFINESHIFT);
for (r = 1; r <= iterations; r++)
{
x += FixedMul(64*FRACUNIT, FINECOSINE(angle));
y += FixedMul(64*FRACUNIT, FINESINE(angle));
x += FixedMul(64*FRACUNIT, FINECOSINE(fa));
y += FixedMul(64*FRACUNIT, FINESINE(fa));
if (mthing->options & MTF_OBJECTFLIP)
{
@ -11242,9 +11223,12 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing)
mobj->flags2 |= MF2_OBJECTFLIP;
}
mobj->angle = FixedAngle(mthing->angle*FRACUNIT);
mobj->angle = closestangle;
if (mthing->options & MTF_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)
@ -11252,7 +11236,6 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing)
{
INT32 numitems = 8;
INT32 size = 96*FRACUNIT;
mobjtype_t itemToSpawn = MT_NIGHTSWING;
if (mthing->type & 1)
{
@ -11277,30 +11260,24 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing)
{
case 604:
case 605:
itemToSpawn = MT_RING;
ringthing = MT_BLUESPHERE;
break;
case 608:
case 609:
itemToSpawn = (i & 1) ? MT_NIGHTSWING : MT_RING;
ringthing = (i & 1) ? MT_RING : MT_BLUESPHERE;
break;
case 606:
case 607:
itemToSpawn = MT_NIGHTSWING;
ringthing = MT_RING;
break;
default:
break;
}
// No rings in Ultimate!
if (itemToSpawn == MT_RING)
{
if (ultimatemode && !(G_IsSpecialStage(gamemap) || (maptol & TOL_NIGHTS)))
continue;
// Spawn rings as blue spheres in special stages, ala S3+K.
if (G_IsSpecialStage(gamemap) && useNightsSS)
itemToSpawn = MT_BLUEBALL;
}
if ((maptol & TOL_NIGHTS) && !G_IsSpecialStage(gamemap))
ringthing = ((ringthing == MT_BLUESPHERE) ? MT_NIGHTSCHIP : MT_NIGHTSSTAR);
else if (ringthing == MT_RING && ultimatemode)
continue; // No rings in Ultimate!
fa = i*FINEANGLES/numitems;
v[0] = FixedMul(FINECOSINE(fa),size);
@ -11315,16 +11292,23 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing)
finaly = y + v[1];
finalz = z + v[2];
mobj = P_SpawnMobj(finalx, finaly, finalz, itemToSpawn);
mobj = P_SpawnMobj(finalx, finaly, finalz, ringthing);
mobj->z -= mobj->height/2;
if (itemToSpawn == MT_NIGHTSWING)
if (mthing->options & MTF_OBJECTFLIP)
{
if (G_IsSpecialStage(gamemap) && useNightsSS)
P_SetMobjState(mobj, mobj->info->meleestate);
else if ((maptol & TOL_XMAS))
P_SetMobjState(mobj, mobj->info->seestate);
mobj->eflags |= MFE_VERTICALFLIP;
mobj->flags2 |= MF2_OBJECTFLIP;
}
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;
}

View File

@ -314,7 +314,7 @@ typedef struct mobj_s
mobjtype_t 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).
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_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_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);

View File

@ -116,7 +116,8 @@ static void P_NetArchivePlayers(void)
WRITEANGLE(save_p, players[i].drawangle);
WRITEANGLE(save_p, players[i].awayviewaiming);
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);
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].startedtime);
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].lastmarescore);
WRITEUINT8(save_p, players[i].lastmare);
@ -303,7 +304,8 @@ static void P_NetUnArchivePlayers(void)
players[i].drawangle = READANGLE(save_p);
players[i].awayviewaiming = READANGLE(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].currentweapon = READINT32(save_p);
@ -388,7 +390,7 @@ static void P_NetUnArchivePlayers(void)
players[i].marebegunat = READUINT32(save_p);
players[i].startedtime = 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].lastmarescore = READUINT32(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
{
P_SpawnHoopsAndRings(&mapthings[spawnpointnum]);
P_SpawnHoopsAndRings(&mapthings[spawnpointnum], false);
return;
}
@ -3261,7 +3263,7 @@ static void P_NetArchiveMisc(void)
WRITEUINT32(save_p, tokenlist);
WRITEUINT32(save_p, leveltime);
WRITEUINT32(save_p, totalrings);
WRITEUINT32(save_p, ssspheres);
WRITEINT16(save_p, lastmap);
WRITEUINT16(save_p, emeralds);
@ -3338,7 +3340,7 @@ static inline boolean P_NetUnArchiveMisc(void)
// get the time
leveltime = READUINT32(save_p);
totalrings = READUINT32(save_p);
ssspheres = READUINT32(save_p);
lastmap = READINT16(save_p);
emeralds = READUINT16(save_p);

View File

@ -808,7 +808,7 @@ void P_ReloadRings(void)
mapthing_t *hoopsToRespawn[4096];
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)
{
if (th->function.acp1 != (actionf_p1)P_MobjThinker)
@ -826,7 +826,8 @@ void P_ReloadRings(void)
}
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;
// Don't auto-disintegrate things being pulled to us
@ -840,9 +841,9 @@ void P_ReloadRings(void)
for (i = 0; i < nummapthings; i++, mt++)
{
// Notice an omission? We handle hoops differently.
if (mt->type == 300 || mt->type == 308 || mt->type == 309
|| mt->type == 1706 || (mt->type >= 600 && mt->type <= 609)
|| mt->type == 1800)
if (mt->type == mobjinfo[MT_RING].doomednum || mt->type == mobjinfo[MT_REDTEAMRING].doomednum || mt->type == mobjinfo[MT_BLUETEAMRING].doomednum
|| mt->type == mobjinfo[MT_BLUESPHERE].doomednum || mt->type == mobjinfo[MT_COIN].doomednum
|| (mt->type >= 600 && mt->type <= 609)) // circles
{
mt->mobj = NULL;
@ -850,12 +851,35 @@ void P_ReloadRings(void)
mt->z = (INT16)(R_PointInSubsector(mt->x << FRACBITS, mt->y << FRACBITS)
->sector->floorheight>>FRACBITS);
P_SpawnHoopsAndRings (mt);
P_SpawnHoopsAndRings(mt, true);
}
}
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.
if (emer1)
P_SpawnMobj(huntemeralds[emer1 - 1]->x<<FRACBITS,
huntemeralds[emer1 - 1]->y<<FRACBITS,
huntemeralds[emer1 - 1]->z<<FRACBITS, MT_EMERHUNT);
if (emer1--)
P_SpawnMobj(huntemeralds[emer1]->x<<FRACBITS,
huntemeralds[emer1]->y<<FRACBITS,
huntemeralds[emer1]->z<<FRACBITS, MT_EMERHUNT);
if (emer2)
P_SpawnMobj(huntemeralds[emer2 - 1]->x<<FRACBITS,
huntemeralds[emer2 - 1]->y<<FRACBITS,
huntemeralds[emer2 - 1]->z<<FRACBITS, MT_EMERHUNT);
if (emer2--)
P_SetMobjStateNF(P_SpawnMobj(huntemeralds[emer2]->x<<FRACBITS,
huntemeralds[emer2]->y<<FRACBITS,
huntemeralds[emer2]->z<<FRACBITS, MT_EMERHUNT),
mobjinfo[MT_EMERHUNT].spawnstate+1);
if (emer3)
P_SpawnMobj(huntemeralds[emer3 - 1]->x<<FRACBITS,
huntemeralds[emer3 - 1]->y<<FRACBITS,
huntemeralds[emer3 - 1]->z<<FRACBITS, MT_EMERHUNT);
if (emer3--)
P_SetMobjStateNF(P_SpawnMobj(huntemeralds[emer3]->x<<FRACBITS,
huntemeralds[emer3]->y<<FRACBITS,
huntemeralds[emer3]->z<<FRACBITS, MT_EMERHUNT),
mobjinfo[MT_EMERHUNT].spawnstate+2);
}
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)
->sector->floorheight>>FRACBITS);
P_SpawnHoopsAndRings (mt);
P_SpawnHoopsAndRings(mt, false);
}
}
}
@ -2298,7 +2324,7 @@ static void P_LevelInitStuff(void)
// circuit, race and competition stuff
circuitmap = false;
numstarposts = 0;
totalrings = timeinmap = 0;
ssspheres = timeinmap = 0;
// special stage
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].rings = 0;
players[i].spheres = 0;
players[i].aiming = 0;
players[i].pflags &= ~PF_GAMETYPEOVER;
@ -2341,7 +2368,7 @@ static void P_LevelInitStuff(void)
players[i].timeshit = 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;
// Don't show anything

View File

@ -72,6 +72,7 @@ void P_DeleteFlickies(INT16 i);
// Needed for NiGHTS
void P_ReloadRings(void);
void P_SwitchSpheresBonusMode(boolean bonustime);
void P_DeleteGrades(INT16 i);
void P_AddGradesForMare(INT16 i, UINT8 mare, char *gtext);
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?
if (M_UpdateUnlockablesAndExtraEmblems())
{
S_StartSound(NULL, sfx_ncitem);
S_StartSound(NULL, sfx_s3k68);
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
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;
P_SpecialStageDamage(player, NULL, NULL);
@ -3775,8 +3775,8 @@ DoneSection2:
case 2: // Special stage GOAL sector / Exit Sector / CTF Flag Return
if (player->bot)
break;
if (!useNightsSS && G_IsSpecialStage(gamemap) && sstimer > 6)
sstimer = 6; // Just let P_Ticker take care of the rest.
if (!(maptol & TOL_NIGHTS) && G_IsSpecialStage(gamemap) && player->nightstime > 6)
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)
{
@ -4643,7 +4643,7 @@ static void P_RunSpecialSectorCheck(player_t *player, sector_t *sector)
switch(GETSECSPECIAL(sector->special, 4))
{
case 2: // Level Exit / GOAL Sector / Flag Return
if (!useNightsSS && G_IsSpecialStage(gamemap))
if (!(maptol & TOL_NIGHTS) && G_IsSpecialStage(gamemap))
{
// Special stage GOAL sector
// requires touching floor.
@ -5502,7 +5502,7 @@ void P_InitSpecials(void)
// Defaults in case levels don't have them set.
sstimer = 90*TICRATE + 6;
totalrings = 1;
ssspheres = 1;
CheckForBustableBlocks = CheckForBouncySector = CheckForQuicksand = CheckForMarioBlocks = CheckForFloatBob = CheckForReverseGravity = false;
@ -5596,7 +5596,7 @@ void P_SpawnSpecials(INT32 fromnetsave)
{
case 10: // Time for special stage
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;
case 11: // Custom global gravity!

View File

@ -424,7 +424,7 @@ void P_DoTeamscrambling(void)
static inline void P_DoSpecialStageStuff(void)
{
boolean inwater = false;
boolean stillalive = false;
INT32 i;
// 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;
}
if (sstimer < 15*TICRATE+6 && sstimer > 7 && (mapheaderinfo[gamemap-1]->levelflags & LF_SPEEDMUSIC))
S_SpeedMusic(1.4f);
//if (sstimer < 15*TICRATE+6 && sstimer > 7 && (mapheaderinfo[gamemap-1]->levelflags & LF_SPEEDMUSIC))
//S_SpeedMusic(1.4f);
if (sstimer < 7 && sstimer > 0) // The special stage time is up!
if (sstimer && !objectplacing)
{
sstimer = 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;
UINT16 countspheres = 0;
// Count up the rings of all the players and see if
// they've collected the required amount.
for (i = 0; i < MAXPLAYERS; 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 ((players[i].mo->eflags & MFE_TOUCHWATER)
|| (players[i].mo->eflags & MFE_UNDERWATER))
inwater = true;
if (players[i].mo->eflags & (MFE_TOUCHWATER|MFE_UNDERWATER))
players[i].nightstime -= 5;
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
for (i = 0; i < MAXPLAYERS; i++)
if (playeringame[i])
{
players[i].mo->momx = players[i].mo->momy = 0;
players[i].exiting = (14*TICRATE)/5 + 1;
}
if (countspheres >= ssspheres)
{
// Halt all the players
for (i = 0; i < MAXPLAYERS; i++)
if (playeringame[i])
{
players[i].mo->momx = players[i].mo->momy = 0;
players[i].exiting = (14*TICRATE)/5 + 1;
}
sstimer = 0;
P_GiveEmerald(true);
sstimer = 0;
P_GiveEmerald(true);
}
}
// Decrement the timer
if (!objectplacing)
else
{
if (inwater)
sstimer -= 6;
else
sstimer--;
sstimer = 0;
stagefailed = true;
}
}
}
@ -608,7 +599,7 @@ void P_Ticker(boolean run)
// Keep track of how long they've been playing!
totalplaytime++;
if (!useNightsSS && G_IsSpecialStage(gamemap))
if (!(maptol & TOL_NIGHTS) && G_IsSpecialStage(gamemap))
P_DoSpecialStageStuff();
if (runemeraldmanager)

View File

@ -283,22 +283,9 @@ boolean P_PlayerMoving(INT32 pnum)
//
UINT8 P_GetNextEmerald(void)
{
if (!useNightsSS) // In order
{
if (!(emeralds & EMERALD1)) return 0;
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);
}
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)
{
INT32 i;
UINT8 em;
UINT8 em = P_GetNextEmerald();
S_StartSound(NULL, sfx_cgot); // Got the emerald!
em = P_GetNextEmerald();
emeralds |= (1 << em);
if (spawnObj)
if (spawnObj && playeringame[consoleplayer])
{
for (i = 0; i < MAXPLAYERS; i++)
if (playeringame[i])
P_SetMobjState(P_SpawnMobj(players[i].mo->x, players[i].mo->y, players[i].mo->z + players[i].mo->info->height, MT_GOTEMERALD),
mobjinfo[MT_GOTEMERALD].spawnstate + em);
// The Chaos Emerald begins to orbit us!
UINT8 em = P_GetNextEmerald();
// Only give it to ONE person!
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;
if (P_TransferToNextMare(player) == false)
if (!P_TransferToNextMare(player))
{
INT32 i;
INT32 total_rings = 0;
INT32 total_spheres = 0;
P_SetTarget(&player->mo->target, NULL);
@ -703,7 +690,7 @@ void P_NightserizePlayer(player_t *player, INT32 nighttime)
{
for (i = 0; i < MAXPLAYERS; i++)
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++)
@ -716,13 +703,13 @@ void P_NightserizePlayer(player_t *player, INT32 nighttime)
players[i].lastmare = players[i].mare;
if (G_IsSpecialStage(gamemap))
{
players[i].finishedrings = (INT16)total_rings;
P_AddPlayerScore(player, total_rings * 50);
players[i].finishedspheres = (INT16)total_spheres;
P_AddPlayerScore(player, total_spheres * 50);
}
else
{
players[i].finishedrings = (INT16)(players[i].rings);
P_AddPlayerScore(&players[i], (players[i].rings) * 50);
players[i].finishedspheres = (INT16)(players[i].spheres);
P_AddPlayerScore(&players[i], (players[i].spheres) * 50);
}
// 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].marescore = 0;
players[i].rings = 0;
players[i].spheres = 0;
P_DoPlayerExit(&players[i]);
}
}
else if (oldmare != player->mare)
{
/// \todo Handle multi-mare special stages.
// Ring bonus
P_AddPlayerScore(player, (player->rings) * 50);
// Spheres bonus
P_AddPlayerScore(player, (player->spheres) * 50);
player->lastmare = (UINT8)oldmare;
player->texttimer = 4*TICRATE;
player->textvar = 4; // Score and grades
player->finishedrings = (INT16)(player->rings);
player->finishedspheres = (INT16)(player->spheres);
// Add score to temp leaderboards
if (!(netgame||multiplayer) && P_IsLocalPlayer(player))
@ -757,7 +744,7 @@ void P_NightserizePlayer(player_t *player, INT32 nighttime)
player->marescore = 0;
player->marebegunat = leveltime;
player->rings = 0;
player->spheres = 0;
}
else
{
@ -857,7 +844,7 @@ void P_DoPlayerPain(player_t *player, mobj_t *source, mobj_t *inflictor)
}
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);
}
@ -923,8 +910,7 @@ void P_GivePlayerRings(player_t *player, INT32 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!
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
//
@ -1035,10 +1041,11 @@ void P_DoSuperTransformation(player_t *player, boolean giverings)
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
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
if (giverings)
@ -3793,12 +3800,15 @@ static void P_DoSuperStuff(player_t *player)
//
boolean P_SuperReady(player_t *player)
{
if ((ALL7EMERALDS(emeralds) && player->rings >= 50) && !player->powers[pw_super] && !player->powers[pw_tailsfly]
&& !(player->powers[pw_shield] & SH_NOSTACK)
if (!player->powers[pw_super]
&& !player->powers[pw_invulnerability]
&& !(maptol & TOL_NIGHTS || (player->powers[pw_carry] == CR_NIGHTSMODE)) // don't turn 'regular super' in nights levels
&& player->pflags & PF_JUMPED
&& player->charflags & SF_SUPER)
&& !player->powers[pw_tailsfly]
&& (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 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 (P_SuperReady(player))
/*else if (P_SuperReady(player))
{
// If you can turn super and aren't already,
// and you don't have a shield, do it!
P_DoSuperTransformation(player, false);
}
}*/
else if (player->pflags & PF_JUMPED)
{
#ifdef HAVE_BLUA
@ -5953,10 +5963,10 @@ static void P_DoNiGHTSCapsule(player_t *player)
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!
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;
players[i].rings = 0;
player->spheres += players[i].spheres;
players[i].spheres = 0;
}
}
@ -5965,9 +5975,9 @@ static void P_DoNiGHTSCapsule(player_t *player)
&& player->mo->y == player->capsule->y
&& 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->extravalue1++;
@ -5999,9 +6009,6 @@ static void P_DoNiGHTSCapsule(player_t *player)
if (G_IsSpecialStage(gamemap))
{
// The Chaos Emerald begins to orbit us!
mobj_t *emmo;
UINT8 em = P_GetNextEmerald();
tic_t lowest_time;
/*for (i = 0; i < MAXPLAYERS; i++)
@ -6016,8 +6023,10 @@ static void P_DoNiGHTSCapsule(player_t *player)
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!
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_SetMobjState(emmo, mobjinfo[MT_GOTEMERALD].meleestate + em);
P_SetTarget(&player->mo->tracer, emmo);
@ -6035,18 +6044,24 @@ static void P_DoNiGHTSCapsule(player_t *player)
}
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);
flicky->z += player->capsule->height/2;
flicky->angle = (i*(ANGLE_MAX/16));
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++)
if (playeringame[i] && players[i].mare == player->mare)
P_SetTarget(&players[i].capsule, NULL); // Remove capsule from everyone now that it is dead!
S_StartScreamSound(player->mo, sfx_ngdone);
P_SwitchSpheresBonusMode(true);
}
}
else
@ -6139,7 +6154,7 @@ static void P_NiGHTSMovement(player_t *player)
}
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_ChangeMusicInternal("_drown",false);
S_ChangeMusicInternal((((maptol & TOL_NIGHTS) && !G_IsSpecialStage(gamemap)) ? "_ntime" : "_drown"), false);
if (player->mo->z < player->mo->floorz)
@ -7477,7 +7492,7 @@ static void P_MovePlayer(player_t *player)
#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
&& (!(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
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)
{
// Super!
case SH_NONE:
if (P_SuperReady(player))
P_DoSuperTransformation(player, false);
break;
// Whirlwind/Thundercoin shield activation
case SH_WHIRLWIND:
case SH_THUNDERCOIN:
@ -9563,11 +9583,8 @@ void P_PlayerThink(player_t *player)
// If 11 seconds are left on the timer,
// begin the drown music for countdown!
if (countdown == 11*TICRATE - 1)
{
if (P_IsLocalPlayer(player))
S_ChangeMusicInternal("_drown", false);
}
if (countdown == 11*TICRATE - 1 && P_IsLocalPlayer(player))
S_ChangeMusicInternal("_drown", false);
// If you've hit the countdown and you haven't made
// it to the exit, you're a goner!
@ -9667,7 +9684,7 @@ void P_PlayerThink(player_t *player)
if (gametype != GT_COOP)
player->score = 0;
player->mo->health = 1;
player->rings = 0;
player->rings = player->spheres = 0;
}
else if ((netgame || multiplayer) && player->lives <= 0 && gametype != GT_COOP)
{
@ -9720,8 +9737,8 @@ void P_PlayerThink(player_t *player)
mo2 = (mobj_t *)th;
if (!(mo2->type == MT_NIGHTSWING || mo2->type == MT_RING || mo2->type == MT_COIN
|| mo2->type == MT_BLUEBALL))
if (!(mo2->type == MT_RING || mo2->type == MT_COIN || mo2->type == MT_BLUESPHERE
|| mo2->type == MT_NIGHTSCHIP || mo2->type == MT_NIGHTSSTAR))
continue;
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)
{
P_RemoveMobj(player->followmobj);
player->followmobj = NULL;
P_SetTarget(&player->followmobj, NULL);
}
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))
{
P_RemoveMobj(player->followmobj);
player->followmobj = NULL;
P_SetTarget(&player->followmobj, NULL);
}
if (!player->spectator && player->mo->health && player->followitem)
{
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);
player->followmobj->flags2 |= MF2_LINKDRAW;
}

View File

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

View File

@ -446,10 +446,11 @@ void SCR_ClosedCaptions(void)
{
if (splitscreen)
basey -= 8;
else if (((maptol & TOL_NIGHTS) && (modeattacking == ATTACKING_NIGHTS))
|| (cv_powerupdisplay.value == 2)
else if ((modeattacking == ATTACKING_NIGHTS)
|| (!(maptol & TOL_NIGHTS)
&& ((cv_powerupdisplay.value == 2)
|| (cv_powerupdisplay.value == 1 && ((stplyr == &players[displayplayer] && !camera.chase)
|| ((splitscreen && stplyr == &players[secondarydisplayplayer]) && !camera2.chase))))
|| ((splitscreen && stplyr == &players[secondarydisplayplayer]) && !camera2.chase))))))
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!
{"bnce2", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Scatter"}, // Boing!
{"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"},
{"deton", true, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Ominous beeping"},
{"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
{"nbmper", false, 96, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Bumper"},
{"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"},
{"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"},
{"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"},
{"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"},
@ -228,12 +229,13 @@ sfxinfo_t S_sfx[NUMSFX] =
{"hoop3", false, 192, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Hoop++"},
{"hidden", false, 204, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Discovery"},
{"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
{"lntsit", false, 60, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Cacolantern awake"},
{"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"},
// Mario
@ -334,10 +336,10 @@ sfxinfo_t S_sfx[NUMSFX] =
{"s3k62", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Jump"},
{"s3k63", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Starpost"},
{"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"},
{"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"},
{"s3k6a", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Special stage clear"},
{"s3k6b", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Punch"},

View File

@ -280,6 +280,7 @@ typedef enum
sfx_xideya, // Xmas
sfx_nbmper,
sfx_nxbump, // Xmas
sfx_ncchip,
sfx_ncitem,
sfx_nxitem, // Xmas
sfx_ngdone,
@ -294,7 +295,8 @@ typedef enum
sfx_hoop3,
sfx_hidden,
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
sfx_lntsit,

View File

@ -112,6 +112,8 @@ static patch_t *yelstat;
static patch_t *nbracket;
static patch_t *nhud[12];
static patch_t *nsshud;
static patch_t *nbon[12];
static patch_t *nssbon;
static patch_t *narrow[9];
static patch_t *nredar[8]; // Red arrow
static patch_t *drillbar;
@ -309,8 +311,12 @@ void ST_LoadGraphics(void)
yelstat = W_CachePatchName("YELSTAT", PU_HUDGFX);
nbracket = W_CachePatchName("NBRACKET", PU_HUDGFX);
for (i = 0; i < 12; ++i)
{
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);
nssbon = W_CachePatchName("NSSBON", PU_HUDGFX);
minicaps = W_CachePatchName("MINICAPS", PU_HUDGFX);
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));
if (objectplacing)
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);
ringnum = ((objectplacing) ? op_currentdoomednum : max(stplyr->rings, 0));
if (cv_timetic.value == 2) // Yes, even in modeattacking
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,
va(M_GetText("\x80GET\x82 %d\x80 %s%s%s!"), stplyr->capsule->health,
(stplyr->textvar == 3) ? M_GetText("MORE ") : "",
(G_IsSpecialStage(gamemap)) ? "SPHERE" : "RING",
(G_IsSpecialStage(gamemap)) ? "SPHERE" : "CHIP",
(stplyr->capsule->health > 1) ? "S" : ""));
}
// End Bonus
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_DrawRightAlignedString(BASEVIDWIDTH/2 + 56, 140, V_ORANGEMAP|aflag, va("%d", stplyr->finishedrings));
V_DrawRightAlignedString(BASEVIDWIDTH/2 + 56, 140, V_ORANGEMAP|aflag, va("%d", stplyr->finishedrings * 50));
V_DrawRightAlignedString(BASEVIDWIDTH/2 + 56, 140, V_ORANGEMAP|aflag, va("%d", stplyr->finishedspheres));
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);
// If new record, say so!
@ -1462,15 +1457,15 @@ static void ST_drawNiGHTSHUD(void)
{
INT32 origamount;
INT32 minlink = 1;
INT32 total_ringcount;
// When debugging, show "0 Link".
if (cv_debug & DBG_NIGHTSBASIC)
minlink = 0;
INT32 total_spherecount;
const boolean oldspecialstage = (G_IsSpecialStage(gamemap) && !(maptol & TOL_NIGHTS));
// 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;
// When debugging, show "0 Link".
else if (cv_debug & DBG_NIGHTSBASIC)
minlink = 0;
// Drill meter
if (
@ -1576,25 +1571,35 @@ static void ST_drawNiGHTSHUD(void)
// Begin drawing brackets/chip display
#ifdef HAVE_BLUA
if (LUA_HudEnabled(hud_nightsrings))
if (LUA_HudEnabled(hud_nightsspheres))
{
#endif
ST_DrawTopLeftOverlayPatch(16, 8, nbracket);
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
ST_DrawTopLeftOverlayPatch(24, 16, nhud[(leveltime/2)%12]);
if (G_IsSpecialStage(gamemap))
{
INT32 i;
total_ringcount = 0;
total_spherecount = 0;
for (i = 0; i < MAXPLAYERS; i++)
if (playeringame[i] /*&& players[i].powers[pw_carry] == CR_NIGHTSMODE*/ && players[i].rings)
total_ringcount += players[i].rings;
if (playeringame[i] /*&& players[i].powers[pw_carry] == CR_NIGHTSMODE*/ && players[i].spheres)
total_spherecount += players[i].spheres;
}
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)
{
@ -1650,28 +1655,48 @@ static void ST_drawNiGHTSHUD(void)
amount = (origamount - stplyr->capsule->health);
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);
}
if (total_ringcount >= stplyr->capsule->health)
ST_DrawTopLeftOverlayPatch(40, 8 + 5, nredar[leveltime%8]);
if (total_spherecount >= stplyr->capsule->health)
ST_DrawTopLeftOverlayPatch(40, 8 + 5, nredar[leveltime&7]);
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
ST_DrawTopLeftOverlayPatch(40, 8 + 5, narrow[8]);
if (total_ringcount >= 100)
V_DrawTallNum((total_ringcount >= 1000) ? 76 : 72, 8 + 11, V_PERPLAYER|V_SNAPTOTOP|V_SNAPTOLEFT|V_HUDTRANS, total_ringcount);
if (total_spherecount >= 100)
V_DrawTallNum((total_spherecount >= 1000) ? 76 : 72, 8 + 11, V_PERPLAYER|V_SNAPTOTOP|V_SNAPTOLEFT|V_HUDTRANS, total_spherecount);
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
}
#endif
// Score
if (!stplyr->exiting
if (!stplyr->exiting && !oldspecialstage
#ifdef HAVE_BLUA
&& LUA_HudEnabled(hud_nightsscore)
#endif
@ -1714,6 +1739,7 @@ static void ST_drawNiGHTSHUD(void)
{
INT32 realnightstime = stplyr->nightstime/TICRATE;
INT32 numbersize;
UINT8 col = ((realnightstime < 10) ? SKINCOLOR_RED : SKINCOLOR_SUPERGOLD4);
if (G_IsSpecialStage(gamemap))
{
@ -1744,46 +1770,66 @@ static void ST_drawNiGHTSHUD(void)
else
numbersize = 48/2;
ST_DrawNightsOverlayNum((160 + numbersize)<<FRACBITS, 14<<FRACBITS, FRACUNIT, V_PERPLAYER|V_SNAPTOTOP, realnightstime, nightsnum,
((realnightstime < 10) ? SKINCOLOR_RED : SKINCOLOR_SUPERGOLD4));
if ((oldspecialstage && leveltime & 2)
&& (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
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)));
}
// Show pickup durations
if (cv_debug & DBG_NIGHTSBASIC)
if (oldspecialstage)
{
UINT16 pwr;
if (stplyr->powers[pw_nights_superloop])
if (leveltime < 5*TICRATE)
{
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)));
INT32 aflag = V_PERPLAYER;
tic_t drawtime = (5*TICRATE) - leveltime;
if (drawtime < TICRATE/2)
aflag |= (9 - 9*drawtime/(TICRATE/2)) << V_ALPHASHIFT;
// This one, not quite as much so.
V_DrawCenteredString(BASEVIDWIDTH/2, 60, aflag,
va(M_GetText("\x80GET\x82 %d\x80 SPHERE%s!"), ssspheres,
(ssspheres > 1) ? "S" : ""));
}
}
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
if (LUA_HudEnabled(hud_nightsrecords))
if (LUA_HudEnabled(hud_nightsrecords))
#endif
ST_drawNightsRecords();
ST_drawNightsRecords();
}
}
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))
{
if (G_IsSpecialStage(gamemap) && useNightsSS)
if (G_IsSpecialStage(gamemap) && (maptol & TOL_NIGHTS))
textHUDdraw(M_GetText("\x82""Wait for the stage to end..."))
else if (gametype == GT_COOP)
{
@ -2070,22 +2116,22 @@ num:
#undef SEP
}
static void ST_drawSpecialStageHUD(void)
/*static void ST_drawSpecialStageHUD(void)
{
if (totalrings > 0)
if (ssspheres > 0)
{
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)
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
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_DrawNumFromHud(HUD_GETRINGSNUM, totalrings, V_HUDTRANS);
ST_DrawNumFromHud(HUD_GETRINGSNUM, ssspheres, V_HUDTRANS);
}
if (sstimer)
@ -2095,7 +2141,7 @@ static void ST_drawSpecialStageHUD(void)
}
else
ST_DrawPatchFromHud(HUD_TIMEUP, timeup, V_HUDTRANS);
}
}*/
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
if (!(hu_showscores && (netgame || multiplayer)))
{
if (maptol & TOL_NIGHTS)
if (maptol & TOL_NIGHTS || G_IsSpecialStage(gamemap))
ST_drawNiGHTSHUD();
else
{
@ -2340,10 +2386,6 @@ static void ST_overlayDrawer(void)
if (gametype == GT_RACE || gametype == GT_COMPETITION)
ST_drawRaceHUD();
// Special Stage HUD
if (!useNightsSS && G_IsSpecialStage(gamemap) && stplyr == &players[displayplayer])
ST_drawSpecialStageHUD();
// Emerald Hunt Indicators
if (cv_itemfinder.value && M_SecretUnlocked(SECRET_ITEMFINDER))
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!
if ((stplyr == &players[displayplayer] && !camera.chase)
|| ((splitscreen && stplyr == &players[secondarydisplayplayer]) && !camera2.chase))
if (!(maptol & TOL_NIGHTS))
{
ST_drawFirstPersonHUD();
if (cv_powerupdisplay.value)
if ((stplyr == &players[displayplayer] && !camera.chase)
|| ((splitscreen && stplyr == &players[secondarydisplayplayer]) && !camera2.chase))
{
ST_drawFirstPersonHUD();
if (cv_powerupdisplay.value)
ST_drawPowerupHUD();
}
else if (cv_powerupdisplay.value == 2)
ST_drawPowerupHUD();
}
else if (cv_powerupdisplay.value == 2)
ST_drawPowerupHUD();
}
#ifdef HAVE_BLUA

View File

@ -78,7 +78,7 @@ typedef union
struct
{
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 passed4[SKINNAMESIZE+7]; // SUPER CRAWLA HONCHO
INT32 passedx1;
@ -315,6 +315,8 @@ void Y_IntermissionDrawer(void)
INT32 xoffset1 = 0; // Line 1 x offset
INT32 xoffset2 = 0; // Line 2 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;
if (gottoken) // first to be behind everything else
@ -324,28 +326,40 @@ void Y_IntermissionDrawer(void)
if (intertic <= 2*TICRATE)
animatetic = 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);
if (animatetimer <= 8)
if (animatetimer <= 12)
{
xoffset1 = -(animatetimer * 40);
xoffset2 = -((animatetimer-2) * 40);
xoffset4 = -((animatetimer-4) * 40);
xoffset5 = -((animatetimer-6) * 40);
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;
xoffset1 = (16-animatetimer) * 40;
xoffset2 = (18-animatetimer) * 40;
xoffset3 = (20-animatetimer) * 40;
xoffset1 = (20-animatetimer) * 40;
xoffset2 = (22-animatetimer) * 40;
xoffset3 = (24-animatetimer) * 40;
xoffset4 = (26-animatetimer) * 40;
xoffset5 = (28-animatetimer) * 40;
if (xoffset1 < 0) xoffset1 = 0;
if (xoffset2 < 0) xoffset2 = 0;
if (xoffset3 < 0) xoffset3 = 0;
if (xoffset4 < 0) xoffset4 = 0;
}
else
{
drawsection = 1;
if (animatetimer == 28)
S_StartSound(NULL, sfx_s3k68);
}
}
if (drawsection == 1)
@ -356,39 +370,60 @@ void Y_IntermissionDrawer(void)
V_DrawLevelTitle(data.spec.passedx3 + xoffset2, ttheight, 0, data.spec.passed3);
ttheight += V_LevelNameHeight(data.spec.passed4) + 2;
V_DrawLevelTitle(data.spec.passedx4 + xoffset3, ttheight, 0, data.spec.passed4);
}
else if (data.spec.passed1[0] != '\0')
{
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);
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");
}
else
{
ttheight = 24 + (V_LevelNameHeight(data.spec.passed2)/2) + 2;
V_DrawLevelTitle(data.spec.passedx2 + xoffset1, ttheight, 0, data.spec.passed2);
if (data.spec.passed1[0] != '\0')
{
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
//if (intertic & 1)
{
boolean drawthistic = !(ALL7EMERALDS(emeralds) && (intertic & 1));
INT32 emeraldx = 152 - 3*28;
INT32 em = (gamemap - sstage_start);
for (i = 0; i < 7; ++i)
if (em == 7)
{
if ((i != em) && !(intertic & 1) && (emeralds & (1 << i)))
V_DrawScaledPatch(emeraldx, 74, 0, emeraldpics[0][i]);
emeraldx += 28;
if (!stagefailed)
{
fixed_t adjust = 2*(FINESINE(FixedAngle((intertic + 1)<<(FRACBITS-4)) & FINEMASK));
V_DrawFixedPatch(152<<FRACBITS, (74<<FRACBITS) - adjust, FRACUNIT, 0, emeraldpics[0][em], NULL);
}
}
if (em < 7)
else if (em < 7)
{
static UINT8 emeraldbounces = 0;
static INT32 emeraldmomy = 20;
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;
if (intertic <= 1)
@ -399,7 +434,7 @@ void Y_IntermissionDrawer(void)
}
else
{
if (emeralds & (1 << em))
if (!stagefailed)
{
if (emeraldbounces < 3)
{
@ -427,16 +462,12 @@ void Y_IntermissionDrawer(void)
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!
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 (M_UpdateUnlockablesAndExtraEmblems())
S_StartSound(NULL, sfx_ncitem);
S_StartSound(NULL, sfx_s3k68);
G_SaveGameData();
}
@ -865,7 +896,7 @@ void Y_Ticker(void)
if (playeringame[i] && (players[i].cmd.buttons & BT_USE))
skip = true;
if ((data.spec.continues & 0x80) && tallydonetic != -1)
if (((data.spec.continues & 0x80) || ALL7EMERALDS(emeralds)) && tallydonetic != -1)
{
if ((intertic - tallydonetic) > (3*TICRATE)/2)
{
@ -896,7 +927,7 @@ void Y_Ticker(void)
if ((!modifiedgame || savemoddata) && !(netgame || multiplayer) && !demoplayback)
{
if (M_UpdateUnlockablesAndExtraEmblems())
S_StartSound(NULL, sfx_ncitem);
S_StartSound(NULL, sfx_s3k68);
G_SaveGameData();
}
@ -1307,6 +1338,11 @@ void Y_StartIntermission(void)
else
strcpy(data.spec.passed1, "YOU GOT");
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.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
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);
else
Y_SetRingBonus(&players[i], &localbonus);