diff --git a/src/dehacked.c b/src/dehacked.c index 73fb81f6c..cbff0adce 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -6269,13 +6269,13 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_EMBLEM26", // Chaos Emeralds - "S_CEMG1", - "S_CEMG2", - "S_CEMG3", - "S_CEMG4", - "S_CEMG5", - "S_CEMG6", - "S_CEMG7", + "S_EMERALD_CHAOS1", + "S_EMERALD_CHAOS2", + "S_EMERALD_CHAOS3", + "S_EMERALD_CHAOS4", + "S_EMERALD_CHAOS5", + "S_EMERALD_CHAOS6", + "S_EMERALD_CHAOS7", // Emerald hunt shards "S_SHRD1", @@ -9499,16 +9499,9 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s "MT_REDFLAG", // Red CTF Flag "MT_BLUEFLAG", // Blue CTF Flag "MT_EMBLEM", - "MT_EMERALD1", - "MT_EMERALD2", - "MT_EMERALD3", - "MT_EMERALD4", - "MT_EMERALD5", - "MT_EMERALD6", - "MT_EMERALD7", + "MT_EMERALD", "MT_EMERHUNT", // Emerald Hunt "MT_EMERALDSPAWN", // Emerald spawner w/ delay - "MT_FLINGEMERALD", // Lost emerald // Springs and others "MT_FAN", @@ -11204,13 +11197,23 @@ struct { {"LF2_VISITNEEDED",LF2_VISITNEEDED}, // Emeralds - {"EMERALD1",EMERALD1}, - {"EMERALD2",EMERALD2}, - {"EMERALD3",EMERALD3}, - {"EMERALD4",EMERALD4}, - {"EMERALD5",EMERALD5}, - {"EMERALD6",EMERALD6}, - {"EMERALD7",EMERALD7}, + {"EMERALD_CHAOS1",EMERALD_CHAOS1}, + {"EMERALD_CHAOS2",EMERALD_CHAOS2}, + {"EMERALD_CHAOS3",EMERALD_CHAOS3}, + {"EMERALD_CHAOS4",EMERALD_CHAOS4}, + {"EMERALD_CHAOS5",EMERALD_CHAOS5}, + {"EMERALD_CHAOS6",EMERALD_CHAOS6}, + {"EMERALD_CHAOS7",EMERALD_CHAOS7}, + {"EMERALD_ALLCHAOS",EMERALD_ALLCHAOS}, + {"EMERALD_SUPER1",EMERALD_SUPER1}, + {"EMERALD_SUPER2",EMERALD_SUPER2}, + {"EMERALD_SUPER3",EMERALD_SUPER3}, + {"EMERALD_SUPER4",EMERALD_SUPER4}, + {"EMERALD_SUPER5",EMERALD_SUPER5}, + {"EMERALD_SUPER6",EMERALD_SUPER6}, + {"EMERALD_SUPER7",EMERALD_SUPER7}, + {"EMERALD_ALLSUPER",EMERALD_ALLSUPER}, + {"EMERALD_ALL",EMERALD_ALL}, // SKINCOLOR_ doesn't include these..! {"MAXSKINCOLORS",MAXSKINCOLORS}, diff --git a/src/doomstat.h b/src/doomstat.h index 57738aaa2..2df6caeb5 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -522,15 +522,34 @@ extern UINT32 matchesplayed; extern UINT8 stagefailed; // Emeralds stored as bits to throw savegame hackers off. +typedef enum +{ + EMERALD_CHAOS1 = 1, + EMERALD_CHAOS2 = 1<<1, + EMERALD_CHAOS3 = 1<<2, + EMERALD_CHAOS4 = 1<<3, + EMERALD_CHAOS5 = 1<<4, + EMERALD_CHAOS6 = 1<<5, + EMERALD_CHAOS7 = 1<<6, + EMERALD_ALLCHAOS = EMERALD_CHAOS1|EMERALD_CHAOS2|EMERALD_CHAOS3|EMERALD_CHAOS4|EMERALD_CHAOS5|EMERALD_CHAOS6|EMERALD_CHAOS7, + + EMERALD_SUPER1 = 1<<7, + EMERALD_SUPER2 = 1<<8, + EMERALD_SUPER3 = 1<<9, + EMERALD_SUPER4 = 1<<10, + EMERALD_SUPER5 = 1<<11, + EMERALD_SUPER6 = 1<<12, + EMERALD_SUPER7 = 1<<13, + EMERALD_ALLSUPER = EMERALD_SUPER1|EMERALD_SUPER2|EMERALD_SUPER3|EMERALD_SUPER4|EMERALD_SUPER5|EMERALD_SUPER6|EMERALD_SUPER7, + + EMERALD_ALL = EMERALD_ALLCHAOS|EMERALD_ALLSUPER +} emeraldflags_t; + extern UINT16 emeralds; -#define EMERALD1 1 -#define EMERALD2 2 -#define EMERALD3 4 -#define EMERALD4 8 -#define EMERALD5 16 -#define EMERALD6 32 -#define EMERALD7 64 -#define ALL7EMERALDS(v) ((v & (EMERALD1|EMERALD2|EMERALD3|EMERALD4|EMERALD5|EMERALD6|EMERALD7)) == (EMERALD1|EMERALD2|EMERALD3|EMERALD4|EMERALD5|EMERALD6|EMERALD7)) + +#define ALLCHAOSEMERALDS(v) ((v & EMERALD_ALLCHAOS) == EMERALD_ALLCHAOS) +#define ALLSUPEREMERALDS(v) ((v & EMERALD_ALLSUPER) == EMERALD_ALLSUPER) +#define ALLEMERALDS(v) ((v & EMERALD_ALL) == EMERALD_ALL) #define NUM_LUABANKS 16 // please only make this number go up between versions, never down. you'll break saves otherwise. also, must fit in UINT8 extern INT32 luabanks[NUM_LUABANKS]; diff --git a/src/f_finale.c b/src/f_finale.c index 4355cf231..0d290330c 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -889,7 +889,7 @@ void F_StartGameEvaluation(void) // Just in case they're open ... somehow M_ClearMenus(true); - goodending = (ALL7EMERALDS(emeralds)); + goodending = (ALLCHAOSEMERALDS(emeralds)); gameaction = ga_nothing; paused = false; @@ -1154,7 +1154,7 @@ static void F_CacheEnding(void) endescp[4] = W_CachePatchName("ENDESCP4", PU_PATCH); // so we only need to check once - if ((goodending = ALL7EMERALDS(emeralds))) + if ((goodending = ALLCHAOSEMERALDS(emeralds))) { endfwrk[0] = W_CachePatchName("ENDFWRK3", PU_PATCH); endfwrk[1] = W_CachePatchName("ENDFWRK4", PU_PATCH); diff --git a/src/info.c b/src/info.c index 1b62c7501..6cf3335b2 100644 --- a/src/info.c +++ b/src/info.c @@ -139,7 +139,13 @@ char sprnames[NUMSPRITES + 1][5] = "NCHP", // NiGHTS chip "NSTR", // NiGHTS star "EMBM", // Emblem - "CEMG", // Chaos Emeralds + "EMC1", // Chaos Emeralds + "EMC2", + "EMC3", + "EMC4", + "EMC5", + "EMC6", + "EMC7", "SHRD", // Emerald Hunt // Interactive Objects @@ -1896,13 +1902,13 @@ state_t states[NUMSTATES] = {SPR_EMBM, 25, -1, {NULL}, 0, 0, S_NULL}, // S_EMBLEM26 // Chaos Emeralds - {SPR_CEMG, FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_NULL}, // S_CEMG1 - {SPR_CEMG, FF_FULLBRIGHT|1, -1, {NULL}, 0, 0, S_NULL}, // S_CEMG2 - {SPR_CEMG, FF_FULLBRIGHT|2, -1, {NULL}, 0, 0, S_NULL}, // S_CEMG3 - {SPR_CEMG, FF_FULLBRIGHT|3, -1, {NULL}, 0, 0, S_NULL}, // S_CEMG4 - {SPR_CEMG, FF_FULLBRIGHT|4, -1, {NULL}, 0, 0, S_NULL}, // S_CEMG5 - {SPR_CEMG, FF_FULLBRIGHT|5, -1, {NULL}, 0, 0, S_NULL}, // S_CEMG6 - {SPR_CEMG, FF_FULLBRIGHT|6, -1, {NULL}, 0, 0, S_NULL}, // S_CEMG7 + {SPR_EMC1, FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_NULL}, // S_EMERALD_CHAOS1 + {SPR_EMC2, FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_NULL}, // S_EMERALD_CHAOS2 + {SPR_EMC3, FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_NULL}, // S_EMERALD_CHAOS3 + {SPR_EMC4, FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_NULL}, // S_EMERALD_CHAOS4 + {SPR_EMC5, FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_NULL}, // S_EMERALD_CHAOS5 + {SPR_EMC6, FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_NULL}, // S_EMERALD_CHAOS6 + {SPR_EMC7, FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_NULL}, // S_EMERALD_CHAOS7 // Emerald hunt shards {SPR_SHRD, 0, -1, {NULL}, 0, 0, S_NULL}, // S_SHRD1 @@ -3746,14 +3752,14 @@ state_t states[NUMSTATES] = {SPR_CAPS, 0, -1, {NULL}, 0, 0, S_NULL}, // S_EGGCAPSULE // 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 - {SPR_CEMG, FF_FULLBRIGHT|3, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM4}, // S_ORBITEM4 - {SPR_CEMG, FF_FULLBRIGHT|4, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM5}, // S_ORBITEM5 - {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_EMC1, FF_FULLBRIGHT, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM1}, // S_ORBITEM1 + {SPR_EMC2, FF_FULLBRIGHT, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM2}, // S_ORBITEM2 + {SPR_EMC3, FF_FULLBRIGHT, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM3}, // S_ORBITEM3 + {SPR_EMC4, FF_FULLBRIGHT, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM4}, // S_ORBITEM4 + {SPR_EMC5, FF_FULLBRIGHT, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM5}, // S_ORBITEM5 + {SPR_EMC6, FF_FULLBRIGHT, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM6}, // S_ORBITEM6 + {SPR_EMC7, FF_FULLBRIGHT, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM7}, // S_ORBITEM7 + {SPR_EMC1, FF_FULLBRIGHT, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM8}, // S_ORBITEM8 {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 @@ -8197,9 +8203,9 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, - { // MT_EMERALD1 - 313, // doomednum - S_CEMG1, // spawnstate + { // MT_EMERALD + -1, // doomednum + S_EMERALD_CHAOS1, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -8210,173 +8216,17 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_SPRK1, // deathstate + S_NULL, // deathstate S_NULL, // xdeathstate - sfx_cgot, // deathsound - EMERALD1, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height + sfx_s3k2b, // deathsound + 0, // speed + 72*FRACUNIT, // radius + 72*FRACUNIT, // height 0, // display offset 16, // mass 0, // damage sfx_None, // activesound - MF_NOGRAVITY|MF_SPECIAL, // flags - S_NULL // raisestate - }, - { // MT_EMERALD2 - 314, // doomednum - S_CEMG2, // 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_SPRK1, // deathstate - S_NULL, // xdeathstate - sfx_cgot, // deathsound - EMERALD2, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height - 0, // display offset - 16, // mass - 0, // damage - sfx_None, // activesound - MF_NOGRAVITY|MF_SPECIAL, // flags - S_NULL // raisestate - }, - { // MT_EMERALD3 - 315, // doomednum - S_CEMG3, // 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_SPRK1, // deathstate - S_NULL, // xdeathstate - sfx_cgot, // deathsound - EMERALD3, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height - 0, // display offset - 16, // mass - 0, // damage - sfx_None, // activesound - MF_NOGRAVITY|MF_SPECIAL, // flags - S_NULL // raisestate - }, - { // MT_EMERALD4 - 316, // doomednum - S_CEMG4, // 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_SPRK1, // deathstate - S_NULL, // xdeathstate - sfx_cgot, // deathsound - EMERALD4, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height - 0, // display offset - 16, // mass - 0, // damage - sfx_None, // activesound - MF_NOGRAVITY|MF_SPECIAL, // flags - S_NULL // raisestate - }, - { // MT_EMERALD5 - 317, // doomednum - S_CEMG5, // 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_SPRK1, // deathstate - S_NULL, // xdeathstate - sfx_cgot, // deathsound - EMERALD5, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height - 0, // display offset - 16, // mass - 0, // damage - sfx_None, // activesound - MF_NOGRAVITY|MF_SPECIAL, // flags - S_NULL // raisestate - }, - { // MT_EMERALD6 - 318, // doomednum - S_CEMG6, // 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_SPRK1, // deathstate - S_NULL, // xdeathstate - sfx_cgot, // deathsound - EMERALD6, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height - 0, // display offset - 16, // mass - 0, // damage - sfx_None, // activesound - MF_NOGRAVITY|MF_SPECIAL, // flags - S_NULL // raisestate - }, - { // MT_EMERALD7 - 319, // doomednum - S_CEMG7, // 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_SPRK1, // deathstate - S_NULL, // xdeathstate - sfx_cgot, // deathsound - EMERALD7, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height - 0, // display offset - 16, // mass - 0, // damage - sfx_None, // activesound - MF_NOGRAVITY|MF_SPECIAL, // flags + MF_SPECIAL, // flags S_NULL // raisestate }, @@ -8434,33 +8284,6 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, - { // MT_FLINGEMERALD - -1, // doomednum - S_CEMG1, // spawnstate - 1000, // spawnhealth - S_NULL, // seestate - sfx_None, // seesound - 0, // reactiontime - sfx_None, // attacksound - S_NULL, // painstate - 0, // painchance - sfx_None, // painsound - S_NULL, // meleestate - S_NULL, // missilestate - S_SPRK1, // deathstate - S_NULL, // xdeathstate - sfx_cgot, // deathsound - 60*FRACUNIT, // speed - 16*FRACUNIT, // radius - 48*FRACUNIT, // height - 0, // display offset - 100, // mass - 0, // damage - sfx_None, // activesound - MF_SLIDEME|MF_SPECIAL, // flags - S_NULL // raisestate - }, - { // MT_FAN 540, // doomednum S_FAN, // spawnstate @@ -19105,7 +18928,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = { // MT_GOTEMERALD -1, // doomednum - S_CEMG1, // spawnstate + S_EMERALD_CHAOS1, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound diff --git a/src/info.h b/src/info.h index e7d21744e..bb8e067be 100644 --- a/src/info.h +++ b/src/info.h @@ -410,7 +410,13 @@ typedef enum sprite SPR_NCHP, // NiGHTS chip SPR_NSTR, // NiGHTS star SPR_EMBM, // Emblem - SPR_CEMG, // Chaos Emeralds + SPR_EMC1, // Chaos Emeralds + SPR_EMC2, + SPR_EMC3, + SPR_EMC4, + SPR_EMC5, + SPR_EMC6, + SPR_EMC7, SPR_SHRD, // Emerald Hunt // Interactive Objects @@ -2111,13 +2117,13 @@ typedef enum state S_EMBLEM26, // Chaos Emeralds - S_CEMG1, - S_CEMG2, - S_CEMG3, - S_CEMG4, - S_CEMG5, - S_CEMG6, - S_CEMG7, + S_EMERALD_CHAOS1, + S_EMERALD_CHAOS2, + S_EMERALD_CHAOS3, + S_EMERALD_CHAOS4, + S_EMERALD_CHAOS5, + S_EMERALD_CHAOS6, + S_EMERALD_CHAOS7, // Emerald hunt shards S_SHRD1, @@ -5381,16 +5387,9 @@ typedef enum mobj_type MT_REDFLAG, // Red CTF Flag MT_BLUEFLAG, // Blue CTF Flag MT_EMBLEM, - MT_EMERALD1, - MT_EMERALD2, - MT_EMERALD3, - MT_EMERALD4, - MT_EMERALD5, - MT_EMERALD6, - MT_EMERALD7, + MT_EMERALD, MT_EMERHUNT, // Emerald Hunt MT_EMERALDSPAWN, // Emerald spawner w/ delay - MT_FLINGEMERALD, // Lost emerald // Springs and others MT_FAN, diff --git a/src/k_battle.c b/src/k_battle.c index 4c13cd9cf..6d73df2eb 100644 --- a/src/k_battle.c +++ b/src/k_battle.c @@ -277,24 +277,85 @@ void K_CheckBumpers(void) P_DoPlayerExit(&players[i]); } +mobj_t *K_SpawnChaosEmerald(mobj_t *parent, angle_t angle, SINT8 flip, UINT32 emeraldType) +{ + boolean validEmerald = true; + mobj_t *emerald = P_SpawnMobjFromMobj(parent, 0, 0, 0, MT_EMERALD); + + emerald->angle = angle; + + P_Thrust(emerald, + FixedAngle(P_RandomFixed() * 180) + angle, + 16*mapobjectscale); + + emerald->momz = flip * 3 * mapobjectscale; + if (emerald->eflags & MFE_UNDERWATER) + emerald->momz = (117 * emerald->momz) / 200; + + emerald->threshold = 10; + + switch (emeraldType) + { + case EMERALD_CHAOS1: + P_SetMobjState(emerald, S_EMERALD_CHAOS1); + break; + case EMERALD_CHAOS2: + P_SetMobjState(emerald, S_EMERALD_CHAOS2); + break; + case EMERALD_CHAOS3: + P_SetMobjState(emerald, S_EMERALD_CHAOS3); + break; + case EMERALD_CHAOS4: + P_SetMobjState(emerald, S_EMERALD_CHAOS4); + break; + case EMERALD_CHAOS5: + P_SetMobjState(emerald, S_EMERALD_CHAOS5); + break; + case EMERALD_CHAOS6: + P_SetMobjState(emerald, S_EMERALD_CHAOS6); + break; + case EMERALD_CHAOS7: + P_SetMobjState(emerald, S_EMERALD_CHAOS7); + break; + default: + CONS_Printf("Invalid emerald type %d\n", emeraldType); + validEmerald = false; + break; + } + + if (validEmerald == true) + { + emerald->extravalue1 = emeraldType; + } + + return emerald; +} + void K_RunPaperItemSpawners(void) { const boolean overtime = (battleovertime.enabled >= 10*TICRATE); tic_t interval = 8*TICRATE; + UINT32 emeraldsSpawned = 0; if (leveltime < starttime) { + // Round hasn't started yet! return; } if ((battleovertime.enabled > 0) && (battleovertime.radius < 256*mapobjectscale)) { + // Barrier has closed in too much return; } if (overtime == true) { + // Double frequency of items interval /= 2; + + // Even if this isn't true, we pretend it is, because it's too late to do anything about it :p + emeraldsSpawned = EMERALD_ALLCHAOS; } if (((leveltime - starttime) % interval) != 0) @@ -315,18 +376,19 @@ void K_RunPaperItemSpawners(void) else { UINT8 pcount = 0; - UINT8 i; + INT16 i; for (i = 0; i < MAXPLAYERS; i++) { - if (!playeringame[i] || players[i].spectator - || players[i].exiting > 0 - || players[i].eliminated) + if (!playeringame[i] || players[i].spectator) { continue; } - if ((gametyperules & GTR_BUMPERS) && players[i].bumpers <= 0) + emeraldsSpawned |= players[i].powers[pw_emeralds]; + + if ((players[i].exiting > 0 || players[i].eliminated) + || ((gametyperules & GTR_BUMPERS) && players[i].bumpers <= 0)) { continue; } @@ -337,10 +399,13 @@ void K_RunPaperItemSpawners(void) if (pcount > 0) { #define MAXITEM 64 - UINT16 item = 0; + UINT8 item = 0; mobj_t *spotList[MAXITEM]; boolean spotUsed[MAXITEM]; + UINT32 firstUnspawnedEmerald = 0; + INT16 starti = 0; + thinker_t *th; mobj_t *mo; @@ -348,9 +413,6 @@ void K_RunPaperItemSpawners(void) for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { - if (item >= MAXITEM) - break; - if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) continue; @@ -358,9 +420,16 @@ void K_RunPaperItemSpawners(void) if (mo->type == MT_PAPERITEMSPOT) { + if (item >= MAXITEM) + continue; + spotList[item] = mo; item++; } + else if (mo->type == MT_EMERALD) + { + emeraldsSpawned |= mo->extravalue1; + } } if (item <= 0) @@ -368,7 +437,19 @@ void K_RunPaperItemSpawners(void) return; } - for (i = 0; i < min(item, pcount); i++) + for (i = 0; i < 7; i++) + { + UINT32 emeraldFlag = (1 << i); + + if (!(emeraldsSpawned & emeraldFlag)) + { + firstUnspawnedEmerald = emeraldFlag; + starti = -1; + break; + } + } + + for (i = starti; i < min(item, pcount); i++) { UINT8 r = P_RandomRange(0, item-1); UINT8 recursion = 0; @@ -387,11 +468,23 @@ void K_RunPaperItemSpawners(void) flip = P_MobjFlip(spotList[r]); - drop = K_CreatePaperItem( - spotList[r]->x, spotList[r]->y, spotList[r]->z + (128 * mapobjectscale * flip), - FixedAngle(P_RandomRange(0, 359) * FRACUNIT), flip, - 0, 0 - ); + // When -1, we're spawning a Chaos Emerald. + if (i == -1) + { + drop = K_SpawnChaosEmerald( + spotList[r], + FixedAngle(P_RandomRange(0, 359) * FRACUNIT), flip, + firstUnspawnedEmerald + ); + } + else + { + drop = K_CreatePaperItem( + spotList[r]->x, spotList[r]->y, spotList[r]->z + (128 * mapobjectscale * flip), + FixedAngle(P_RandomRange(0, 359) * FRACUNIT), flip, + 0, 0 + ); + } K_FlipFromObject(drop, spotList[r]); spotUsed[r] = true; diff --git a/src/k_battle.h b/src/k_battle.h index 90ee20df7..346e57c48 100644 --- a/src/k_battle.h +++ b/src/k_battle.h @@ -20,6 +20,7 @@ boolean K_IsPlayerWanted(player_t *player); void K_CalculateBattleWanted(void); void K_SpawnBattlePoints(player_t *source, player_t *victim, UINT8 amount); void K_CheckBumpers(void); +mobj_t *K_SpawnChaosEmerald(mobj_t *parent, angle_t angle, SINT8 flip, UINT32 emeraldType); void K_RunPaperItemSpawners(void); void K_RunBattleOvertime(void); void K_SetupMovingCapsule(mapthing_t *mt, mobj_t *mobj); diff --git a/src/lua_mathlib.c b/src/lua_mathlib.c index c6c07fc7e..621f421ea 100644 --- a/src/lua_mathlib.c +++ b/src/lua_mathlib.c @@ -14,7 +14,7 @@ //#include "fastcmp.h" #include "tables.h" #include "p_local.h" -#include "doomstat.h" // for ALL7EMERALDS +#include "doomstat.h" // for ALLCHAOSEMERALDS #include "lua_script.h" #include "lua_libs.h" @@ -162,7 +162,7 @@ static int lib_getsecspecial(lua_State *L) static int lib_all7emeralds(lua_State *L) { - lua_pushboolean(L, ALL7EMERALDS(luaL_checkinteger(L, 1))); + lua_pushboolean(L, ALLCHAOSEMERALDS(luaL_checkinteger(L, 1))); return 1; } diff --git a/src/m_cheat.c b/src/m_cheat.c index ff5f86968..0f39bb643 100644 --- a/src/m_cheat.c +++ b/src/m_cheat.c @@ -771,12 +771,13 @@ void Command_Savecheckpoint_f(void) } // Like M_GetAllEmeralds() but for console devmode junkies. -/*void Command_Getallemeralds_f(void) +/* +void Command_Getallemeralds_f(void) { REQUIRE_SINGLEPLAYER; REQUIRE_PANDORA; - emeralds = ((EMERALD7)*2)-1; + emeralds = EMERALD_ALL; CONS_Printf(M_GetText("You now have all 7 emeralds.\n")); } @@ -788,7 +789,8 @@ void Command_Resetemeralds_f(void) emeralds = 0; CONS_Printf(M_GetText("Emeralds reset to zero.\n")); -}*/ +} +*/ void Command_Devmode_f(void) { diff --git a/src/m_menu.c b/src/m_menu.c index 7f6f542c6..dcd46b238 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -6374,7 +6374,7 @@ static void M_GetAllEmeralds(INT32 choice) { (void)choice; - emeralds = ((EMERALD7)*2)-1; + emeralds = EMERALD_ALL; M_StartMessage(M_GetText("You now have all 7 emeralds.\nUse them wisely.\nWith great power comes great ring drain.\n"),NULL,MM_NOTHING); G_SetGameModified(multiplayer, true); diff --git a/src/p_inter.c b/src/p_inter.c index 08bd29fdf..2b91278df 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -231,7 +231,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) P_SetObjectMomZ(player->mo, 12<mo, player->mo->angle, 20<mo, special, special->target, 1, DMG_NORMAL); } return; - /*case MT_EERIEFOG: + case MT_EMERALD: + if (!P_CanPickupItem(player, 0)) + return; + + if (special->threshold > 0) + return; + + player->powers[pw_emeralds] |= special->extravalue1; + + if (ALLCHAOSEMERALDS(player->powers[pw_emeralds])) + { + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i] || players[i].spectator) + { + continue; + } + + if (&players[i] == player) + { + continue; + } + + players[i].bumpers = 0; + } + + K_CheckBumpers(); + } + break; + /* + case MT_EERIEFOG: special->frame &= ~FF_TRANS80; special->frame |= FF_TRANS90; - return;*/ + return; + */ case MT_SMK_MOLE: if (special->target && !P_MobjWasRemoved(special->target)) return; diff --git a/src/p_mobj.c b/src/p_mobj.c index 1b53f8072..cc3bc3a9b 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -1130,7 +1130,6 @@ fixed_t P_GetMobjGravity(mobj_t *mo) case MT_FLINGCOIN: case MT_FLINGBLUESPHERE: case MT_FLINGNIGHTSCHIP: - case MT_FLINGEMERALD: case MT_BOUNCERING: case MT_RAILRING: case MT_INFINITYRING: @@ -2082,6 +2081,7 @@ boolean P_ZMovement(mobj_t *mo) case MT_BALLHOG: case MT_SSMINE: case MT_BUBBLESHIELDTRAP: + case MT_EMERALD: // Remove stuff from death pits. if (P_CheckDeathPitCollide(mo)) { @@ -6384,6 +6384,10 @@ static boolean P_MobjRegularThink(mobj_t *mobj) S_StartSound(mobj, sfx_s3k4e); mobj->health--; break; + case MT_EMERALD: + if (mobj->threshold > 0) + mobj->threshold--; + break; case MT_DRIFTEXPLODE: if (!mobj->target || !mobj->target->health) { @@ -8566,7 +8570,7 @@ void P_MobjThinker(mobj_t *mobj) || mobj->type == MT_FLINGCOIN || mobj->type == MT_FLINGBLUESPHERE || mobj->type == MT_FLINGNIGHTSCHIP - || mobj->type == MT_FLINGEMERALD + || mobj->type == MT_EMERALD || mobj->type == MT_BIGTUMBLEWEED || mobj->type == MT_LITTLETUMBLEWEED || mobj->type == MT_CANNONBALLDECOR @@ -8873,6 +8877,7 @@ static void P_DefaultMobjShadowScale(mobj_t *thing) case MT_SINK: case MT_ROCKETSNEAKER: case MT_SPB: + case MT_EMERALD: thing->shadowscale = 3*FRACUNIT/2; break; case MT_BANANA_SHIELD: diff --git a/src/p_mobj.h b/src/p_mobj.h index 6ffa393aa..9cafcefa7 100644 --- a/src/p_mobj.h +++ b/src/p_mobj.h @@ -530,7 +530,6 @@ boolean P_ZMovement(mobj_t *mo); void P_RingZMovement(mobj_t *mo); boolean P_SceneryZMovement(mobj_t *mo); void P_PlayerZMovement(mobj_t *mo); -void P_EmeraldManager(void); extern INT32 modulothing; diff --git a/src/p_spec.c b/src/p_spec.c index a86c54c07..f95bbd39d 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -1612,7 +1612,7 @@ boolean P_RunTriggerLinedef(line_t *triggerline, mobj_t *actor, sector_t *caller { if (GETSECSPECIAL(caller->special, 2) == 6) { - if (!(ALL7EMERALDS(emeralds))) + if (!(ALLCHAOSEMERALDS(emeralds))) return false; }