diff --git a/src/d_netcmd.c b/src/d_netcmd.c index f3fb1f6ae8d13b84c81d1517e857b1320e6cde6a..dbb0b0ff53d3c5b191f91c56887356fdd86ee545 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -822,6 +822,7 @@ void D_RegisterClientCommands(void) COM_AddCommand("getallemeralds", Command_Getallemeralds_f); COM_AddCommand("resetemeralds", Command_Resetemeralds_f); COM_AddCommand("setrings", Command_Setrings_f); + COM_AddCommand("setspheres", Command_Setspheres_f); COM_AddCommand("setlives", Command_Setlives_f); COM_AddCommand("setcontinues", Command_Setcontinues_f); COM_AddCommand("devmode", Command_Devmode_f); diff --git a/src/d_player.h b/src/d_player.h index 24c4f92521db281b14750bebf233abedb632d191..7bee5f337e60e305929143019f328176dde20ae4 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -462,6 +462,7 @@ typedef struct player_s 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 finishedspheres; // The spheres you had left upon finishing the mare + INT16 finishedrings; // The rings/stars 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 diff --git a/src/dehacked.c b/src/dehacked.c index c4d0bc10468e3319984f40a8b24e67f729d1ccf3..fb0f958c3ffe0aeb2838db73dddb14f91b2e7b27 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -6369,6 +6369,7 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s "MT_RING", "MT_FLINGRING", // Lost ring "MT_BLUESPHERE", // Blue sphere for special stages + "MT_FLINGBLUESPHERE", // Lost blue sphere "MT_BOMBSPHERE", "MT_REDTEAMRING", //Rings collectable by red team. "MT_BLUETEAMRING", //Rings collectable by blue team. @@ -6833,6 +6834,7 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s "MT_HOOPCENTER", // Center of a hoop "MT_NIGHTSCORE", "MT_NIGHTSCHIP", // NiGHTS Chip + "MT_FLINGNIGHTSCHIP", // Lost NiGHTS Chip "MT_NIGHTSSTAR", // NiGHTS Star "MT_NIGHTSSUPERLOOP", "MT_NIGHTSDRILLREFILL", diff --git a/src/info.c b/src/info.c index 1489917b7768d598eb85e67f036c8e96763c981b..782ab638165d5d00cfc773c86967ed8d12dc1edb 100644 --- a/src/info.c +++ b/src/info.c @@ -5783,7 +5783,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound - MT_NULL, // reactiontime + MT_FLINGBLUESPHERE, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance @@ -5804,6 +5804,33 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_BLUESPHEREBONUS // raisestate }, + { // MT_FLINGBLUESPHERE + -1, // doomednum + S_BLUESPHERE, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + MT_FLINGBLUESPHERE, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + MT_BLUESPHERE, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_BLUESPHERESPARK, // deathstate + S_NULL, // xdeathstate + sfx_s3k65, // deathsound + 38*FRACUNIT, // speed + 16*FRACUNIT, // radius + 24*FRACUNIT, // height + 0, // display offset + 100, // mass + 0, // damage + sfx_None, // activesound + MF_SLIDEME|MF_SPECIAL, // flags + S_BLUESPHEREBONUS // raisestate + }, + { // MT_BOMBSPHERE 520, // doomednum S_BOMBSPHERE1, // spawnstate @@ -16320,7 +16347,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound - 8, // reactiontime + MT_FLINGNIGHTSCHIP, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance @@ -16341,6 +16368,33 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NIGHTSCHIPBONUS // raisestate }, + { // MT_FLINGNIGHTSCHIP + -1, // doomednum + S_NIGHTSCHIP, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + MT_FLINGNIGHTSCHIP, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + MT_NIGHTSCHIP, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_SPRK1, // deathstate + S_NULL, // xdeathstate + sfx_ncchip, // deathsound + 38*FRACUNIT, // speed + 16*FRACUNIT, // radius + 24*FRACUNIT, // height + 0, // display offset + 100, // mass + 0, // damage + sfx_None, // activesound + MF_SLIDEME|MF_SPECIAL, // flags + S_NIGHTSCHIPBONUS // raisestate + }, + { // MT_NIGHTSSTAR -1, // doomednum S_NIGHTSSTAR, // spawnstate diff --git a/src/info.h b/src/info.h index c9f7299d80790b60b8564e075ecb3f523ae8d332..dfd30bc5b15c3a16347b66368f3d974fa2d63764 100644 --- a/src/info.h +++ b/src/info.h @@ -3742,6 +3742,7 @@ typedef enum mobj_type MT_RING, MT_FLINGRING, // Lost ring MT_BLUESPHERE, // Blue sphere for special stages + MT_FLINGBLUESPHERE, // Lost blue sphere MT_BOMBSPHERE, MT_REDTEAMRING, //Rings collectable by red team. MT_BLUETEAMRING, //Rings collectable by blue team. @@ -4206,6 +4207,7 @@ typedef enum mobj_type MT_HOOPCENTER, // Center of a hoop MT_NIGHTSCORE, MT_NIGHTSCHIP, // NiGHTS Chip + MT_FLINGNIGHTSCHIP, // Lost NiGHTS Chip MT_NIGHTSSTAR, // NiGHTS Star MT_NIGHTSSUPERLOOP, MT_NIGHTSDRILLREFILL, diff --git a/src/lua_playerlib.c b/src/lua_playerlib.c index 8a1079c364be25080301a2880364253d9c69d864..ff62f2459d514406dd80f0087257179603a0f013 100644 --- a/src/lua_playerlib.c +++ b/src/lua_playerlib.c @@ -298,6 +298,8 @@ static int player_get(lua_State *L) lua_pushinteger(L, plr->finishedtime); else if (fastcmp(field,"finishedspheres")) lua_pushinteger(L, plr->finishedspheres); + else if (fastcmp(field,"finishedrings")) + lua_pushinteger(L, plr->finishedrings); else if (fastcmp(field,"marescore")) lua_pushinteger(L, plr->marescore); else if (fastcmp(field,"lastmarescore")) @@ -576,6 +578,8 @@ static int player_set(lua_State *L) plr->finishedtime = (tic_t)luaL_checkinteger(L, 3); else if (fastcmp(field,"finishedspheres")) plr->finishedspheres = (INT16)luaL_checkinteger(L, 3); + else if (fastcmp(field,"finishedrings")) + plr->finishedrings = (INT16)luaL_checkinteger(L, 3); else if (fastcmp(field,"marescore")) plr->marescore = (UINT32)luaL_checkinteger(L, 3); else if (fastcmp(field,"lastmarescore")) diff --git a/src/m_cheat.c b/src/m_cheat.c index 5ac7422707c228f85bcaf3922704fb4281581faf..b572b84eb53d19975843b6e483ddea9bf543bad4 100644 --- a/src/m_cheat.c +++ b/src/m_cheat.c @@ -890,6 +890,23 @@ void Command_Setrings_f(void) } } +void Command_Setspheres_f(void) +{ + REQUIRE_INLEVEL; + REQUIRE_SINGLEPLAYER; + REQUIRE_NOULTIMATE; + REQUIRE_PANDORA; + + if (COM_Argc() > 1) + { + // P_GivePlayerRings does value clamping + players[consoleplayer].spheres = 0; + P_GivePlayerSpheres(&players[consoleplayer], atoi(COM_Argv(1))); + + G_SetGameModified(multiplayer); + } +} + void Command_Setlives_f(void) { REQUIRE_INLEVEL; diff --git a/src/m_cheat.h b/src/m_cheat.h index 951c7a16a261f435fc464f37dd93585c0c156b2e..31f650b3fdeff5f2aaa24f4a346ac81106f63d92 100644 --- a/src/m_cheat.h +++ b/src/m_cheat.h @@ -51,6 +51,7 @@ void Command_Savecheckpoint_f(void); void Command_Getallemeralds_f(void); void Command_Resetemeralds_f(void); void Command_Setrings_f(void); +void Command_Setspheres_f(void); void Command_Setlives_f(void); void Command_Setcontinues_f(void); void Command_Devmode_f(void); diff --git a/src/m_menu.c b/src/m_menu.c index b11873adb4500d00e60d965cc01b140a41549016..f99f5d860c73e3db25f8b746840d23f60d3e2a4b 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -5273,7 +5273,10 @@ static void M_HandleAddons(INT32 choice) static void M_PandorasBox(INT32 choice) { (void)choice; - CV_StealthSetValue(&cv_dummyrings, max(players[consoleplayer].rings, 0)); + if (maptol & TOL_NIGHTS) + CV_StealthSetValue(&cv_dummyrings, max(players[consoleplayer].spheres, 0)); + else + CV_StealthSetValue(&cv_dummyrings, max(players[consoleplayer].rings, 0)); if (players[consoleplayer].lives == 0x7f) CV_StealthSetValue(&cv_dummylives, -1); else @@ -5291,7 +5294,12 @@ static void M_PandorasBox(INT32 choice) static boolean M_ExitPandorasBox(void) { if (cv_dummyrings.value != max(players[consoleplayer].rings, 0)) - COM_ImmedExecute(va("setrings %d", cv_dummyrings.value)); + { + if (maptol & TOL_NIGHTS) + COM_ImmedExecute(va("setspheres %d", cv_dummyrings.value)); + else + COM_ImmedExecute(va("setrings %d", cv_dummyrings.value)); + } if (cv_dummylives.value != players[consoleplayer].lives) COM_ImmedExecute(va("setlives %d", cv_dummylives.value)); if (cv_dummycontinues.value != players[consoleplayer].continues) diff --git a/src/p_inter.c b/src/p_inter.c index 5737e2c2acb266561beffc2475e480aef596f49d..ce8bba6b6e7cc9a33c3d1e664b4846914be545ae 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -490,7 +490,9 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) P_DoNightsScore(player); break; case MT_BLUESPHERE: + case MT_FLINGBLUESPHERE: case MT_NIGHTSCHIP: + case MT_FLINGNIGHTSCHIP: if (!(P_CanPickupItem(player, false)) && !(special->flags2 & MF2_NIGHTSPULL)) return; @@ -2770,18 +2772,26 @@ static inline boolean P_TagDamage(mobj_t *target, mobj_t *inflictor, mobj_t *sou return true; } - if (player->rings > 0) // Ring loss + if (player->powers[pw_carry] == CR_NIGHTSFALL) + { + if (player->spheres > 0) + { + P_PlayRinglossSound(target); + P_PlayerRingBurst(player, player->spheres); + player->spheres = 0; + } + } + else if (player->rings > 0) // Ring loss { P_PlayRinglossSound(target); P_PlayerRingBurst(player, player->rings); + player->rings = 0; } else // Death { P_PlayDeathSound(target); P_PlayVictorySound(source); // Killer laughs at you! LAUGHS! BWAHAHAHHAHAA!! } - - player->rings = 0; return true; } @@ -2996,7 +3006,7 @@ static void P_ShieldDamage(player_t *player, mobj_t *inflictor, mobj_t *source, } } -static void P_RingDamage(player_t *player, mobj_t *inflictor, mobj_t *source, INT32 damage, UINT8 damagetype) +static void P_RingDamage(player_t *player, mobj_t *inflictor, mobj_t *source, INT32 damage, UINT8 damagetype, boolean dospheres) { P_DoPlayerPain(player, source, inflictor); @@ -3026,9 +3036,19 @@ static void P_RingDamage(player_t *player, mobj_t *inflictor, mobj_t *source, IN // Ring loss sound plays despite hitting spikes P_PlayRinglossSound(player->mo); // Ringledingle! P_PlayerRingBurst(player, damage); - player->rings -= damage; - if (player->rings < 0) - player->rings = 0; + + if (dospheres) + { + player->spheres -= damage; + if (player->spheres < 0) + player->spheres = 0; + } + else + { + player->rings -= damage; + if (player->rings < 0) + player->rings = 0; + } } // @@ -3245,7 +3265,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da if (damagetype & DMG_DEATHMASK) { P_KillPlayer(player, source, damage); - player->rings = 0; + player->rings = player->spheres = 0; } else if (metalrecording) { @@ -3289,10 +3309,19 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da P_ShieldDamage(player, inflictor, source, damage, damagetype); damage = 0; } + else if (player->powers[pw_carry] == CR_NIGHTSFALL) + { + if (player->spheres > 0) + { + damage = player->spheres; + P_RingDamage(player, inflictor, source, damage, damagetype, true); + damage = 0; + } + } else if (player->rings > 0) // No shield but have rings. { damage = player->rings; - P_RingDamage(player, inflictor, source, damage, damagetype); + P_RingDamage(player, inflictor, source, damage, damagetype, false); damage = 0; } // To reduce griefing potential, don't allow players to be killed @@ -3373,13 +3402,14 @@ void P_PlayerRingBurst(player_t *player, INT32 num_rings) angle_t fa; fixed_t ns; fixed_t z; + boolean nightsreplace = ((maptol & TOL_NIGHTS) && !G_IsSpecialStage(gamemap)); // Better safe than sorry. if (!player) return; // If no health, don't spawn ring! - if (player->rings <= 0) + if (((maptol & TOL_NIGHTS) && player->spheres <= 0) || (!(maptol & TOL_NIGHTS) && player->rings <= 0)) num_rings = 0; if (num_rings > 32 && player->powers[pw_carry] != CR_NIGHTSFALL) @@ -3396,6 +3426,8 @@ void P_PlayerRingBurst(player_t *player, INT32 num_rings) INT32 objType = mobjinfo[MT_RING].reactiontime; if (mariomode) objType = mobjinfo[MT_COIN].reactiontime; + else if (player->powers[pw_carry] == CR_NIGHTSFALL) + objType = mobjinfo[(nightsreplace ? MT_NIGHTSCHIP : MT_BLUESPHERE)].reactiontime; z = player->mo->z; if (player->mo->eflags & MFE_VERTICALFLIP) @@ -3424,6 +3456,9 @@ void P_PlayerRingBurst(player_t *player, INT32 num_rings) P_SetObjectMomZ(mo, 8*FRACUNIT, false); mo->fuse = 20*TICRATE; // Adjust fuse for NiGHTS + + // Toggle bonus time colors + P_SetMobjState(mo, (player->bonustime ? mo->info->raisestate : mo->info->spawnstate)); } else { diff --git a/src/p_mobj.c b/src/p_mobj.c index be373fbf4a3745a09eea481c7ef48342b8e65739..4353e67c392f13700790ced6df1330d8f791709c 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -1539,6 +1539,8 @@ fixed_t P_GetMobjGravity(mobj_t *mo) { case MT_FLINGRING: case MT_FLINGCOIN: + case MT_FLINGBLUESPHERE: + case MT_FLINGNIGHTSCHIP: case MT_FLINGEMERALD: case MT_BOUNCERING: case MT_RAILRING: @@ -2523,6 +2525,8 @@ static boolean P_ZMovement(mobj_t *mo) case MT_BLUETEAMRING: case MT_FLINGRING: case MT_FLINGCOIN: + case MT_FLINGBLUESPHERE: + case MT_FLINGNIGHTSCHIP: case MT_FLINGEMERALD: // Remove flinged stuff from death pits. if (P_CheckDeathPitCollide(mo)) @@ -2709,6 +2713,8 @@ static boolean P_ZMovement(mobj_t *mo) // Flingrings bounce if (mo->type == MT_FLINGRING || mo->type == MT_FLINGCOIN + || mo->type == MT_FLINGBLUESPHERE + || mo->type == MT_FLINGNIGHTSCHIP || P_WeaponOrPanel(mo->type) || mo->type == MT_FLINGEMERALD || mo->type == MT_BIGTUMBLEWEED @@ -7941,6 +7947,8 @@ void P_MobjThinker(mobj_t *mobj) // Flung items case MT_FLINGRING: case MT_FLINGCOIN: + case MT_FLINGBLUESPHERE: + case MT_FLINGNIGHTSCHIP: if (mobj->flags2 & MF2_NIGHTSPULL) P_NightsItemChase(mobj); else @@ -8278,6 +8286,8 @@ for (i = ((mobj->flags2 & MF2_STRONGBOX) ? strongboxamt : weakboxamt); i; --i) s #ifdef ESLOPE // Sliding physics for slidey mobjs! if (mobj->type == MT_FLINGRING || mobj->type == MT_FLINGCOIN + || mobj->type == MT_FLINGBLUESPHERE + || mobj->type == MT_FLINGNIGHTSCHIP || P_WeaponOrPanel(mobj->type) || mobj->type == MT_FLINGEMERALD || mobj->type == MT_BIGTUMBLEWEED diff --git a/src/p_saveg.c b/src/p_saveg.c index 2e47f2077787bac16977c43c6b11ca79aafa3046..7cf43738463bce64297f60f54aa09a5d3687de03 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -203,6 +203,7 @@ static void P_NetArchivePlayers(void) WRITEUINT32(save_p, players[i].startedtime); WRITEUINT32(save_p, players[i].finishedtime); WRITEINT16(save_p, players[i].finishedspheres); + WRITEINT16(save_p, players[i].finishedrings); WRITEUINT32(save_p, players[i].marescore); WRITEUINT32(save_p, players[i].lastmarescore); WRITEUINT8(save_p, players[i].lastmare); @@ -391,6 +392,7 @@ static void P_NetUnArchivePlayers(void) players[i].startedtime = READUINT32(save_p); players[i].finishedtime = READUINT32(save_p); players[i].finishedspheres = READINT16(save_p); + players[i].finishedrings = READINT16(save_p); players[i].marescore = READUINT32(save_p); players[i].lastmarescore = READUINT32(save_p); players[i].lastmare = READUINT8(save_p); diff --git a/src/p_setup.c b/src/p_setup.c index 80d004314ee9d9554b24c458e2d1629d9fb7005c..c62f281b3ee461eed4ccce49121c6a23d988bbb8 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -885,7 +885,8 @@ void P_SwitchSpheresBonusMode(boolean bonustime) mo = (mobj_t *)th; - if (mo->type != MT_BLUESPHERE && mo->type != MT_NIGHTSCHIP) + if (mo->type != MT_BLUESPHERE && mo->type != MT_NIGHTSCHIP + && mo->type != MT_FLINGBLUESPHERE && mo->type != MT_FLINGNIGHTSCHIP) continue; if (!mo->health) @@ -2379,12 +2380,13 @@ static void P_LevelInitStuff(void) players[i].marescore = players[i].lastmarescore =\ players[i].maxlink = players[i].startedtime =\ players[i].finishedtime = players[i].finishedspheres =\ - players[i].lastmare = players[i].marebegunat =\ - players[i].textvar = players[i].texttimer =\ - players[i].linkcount = players[i].linktimer =\ - players[i].flyangle = players[i].anotherflyangle =\ - players[i].nightstime = players[i].mare =\ - players[i].realtime = players[i].exiting = 0; + players[i].finishedrings = players[i].lastmare =\ + players[i].marebegunat = players[i].textvar =\ + players[i].texttimer = players[i].linkcount =\ + players[i].linktimer = players[i].flyangle =\ + players[i].anotherflyangle = players[i].nightstime =\ + players[i].mare = players[i].realtime =\ + players[i].exiting = 0; // i guess this could be part of the above but i feel mildly uncomfortable implicitly casting players[i].gotcontinue = false; diff --git a/src/p_user.c b/src/p_user.c index 357933f1401d42291e955c850a3eab176e89ab89..fd09b084755a07215b8487ee56716f9e5b3da787 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -590,8 +590,9 @@ static void P_DeNightserizePlayer(player_t *player) else if (player == &players[secondarydisplayplayer]) localaiming2 = 0; - // If you screwed up, kiss your score goodbye. + // If you screwed up, kiss your score and ring bonus goodbye. player->marescore = 0; + player->rings = 0; P_SetPlayerMobjState(player->mo, S_PLAY_FALL); @@ -684,6 +685,7 @@ void P_NightserizePlayer(player_t *player, INT32 nighttime) { INT32 i; INT32 total_spheres = 0; + INT32 total_rings = 0; P_SetTarget(&player->mo->target, NULL); @@ -691,7 +693,10 @@ 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_spheres += players[i].spheres; + total_rings += players[i].rings; + } } for (i = 0; i < MAXPLAYERS; i++) @@ -705,11 +710,13 @@ void P_NightserizePlayer(player_t *player, INT32 nighttime) if (G_IsSpecialStage(gamemap)) { players[i].finishedspheres = (INT16)total_spheres; + players[i].finishedrings = (INT16)total_rings; P_AddPlayerScore(player, total_spheres * 50); } else { players[i].finishedspheres = (INT16)(players[i].spheres); + players[i].finishedrings = (INT16)(players[i].rings); P_AddPlayerScore(&players[i], (players[i].spheres) * 50); } @@ -721,7 +728,7 @@ void P_NightserizePlayer(player_t *player, INT32 nighttime) players[i].lastmarescore = players[i].marescore; players[i].marescore = 0; - players[i].spheres = 0; + players[i].spheres = players[i].rings = 0; P_DoPlayerExit(&players[i]); } } @@ -745,7 +752,7 @@ void P_NightserizePlayer(player_t *player, INT32 nighttime) player->marescore = 0; player->marebegunat = leveltime; - player->spheres = 0; + player->spheres = player->rings = 0; } else { @@ -7023,7 +7030,7 @@ static void P_MovePlayer(player_t *player) if (playeringame[i]) players[i].exiting = (14*TICRATE)/5 + 1; } - else if (player->rings > 0) + else if (player->spheres > 0) P_DamageMobj(player->mo, NULL, NULL, 1, 0); player->powers[pw_carry] = CR_NONE; }