First pass at implementing Spray Can pickups

- Replaces a few D00DKart objects because the doomednum specifically replaced one of these
- Reports on load if the map has too many, or if one's assigned but the object doesn't exist
This commit is contained in:
toaster 2023-08-19 22:21:20 +01:00
parent 3036eaf35d
commit dc695e7acf
11 changed files with 156 additions and 245 deletions

View file

@ -1190,6 +1190,9 @@ const char *const STATE_LIST[] = { // array length left dynamic for sanity testi
"S_EMBLEM25",
"S_EMBLEM26",
// Spray Can
"S_SPRAYCAN",
// Chaos Emeralds
"S_CHAOSEMERALD1",
"S_CHAOSEMERALD2",
@ -3921,24 +3924,6 @@ const char *const STATE_LIST[] = { // array length left dynamic for sanity testi
"S_APPLE7",
"S_APPLE8",
// D00Dkart - Fall Flowers
"S_DOOD_FLOWER1",
"S_DOOD_FLOWER2",
"S_DOOD_FLOWER3",
"S_DOOD_FLOWER4",
"S_DOOD_FLOWER5",
"S_DOOD_FLOWER6",
// D00Dkart - Super Circuit Box
"S_DOOD_BOX1",
"S_DOOD_BOX2",
"S_DOOD_BOX3",
"S_DOOD_BOX4",
"S_DOOD_BOX5",
// D00Dkart - Diddy Kong Racing Bumper
"S_DOOD_BALLOON",
// Chaotix Big Ring
"S_BIGRING01",
"S_BIGRING02",
@ -4805,6 +4790,7 @@ const char *const MOBJTYPE_LIST[] = { // array length left dynamic for sanity t
"MT_REDFLAG", // Red CTF Flag
"MT_BLUEFLAG", // Blue CTF Flag
"MT_EMBLEM",
"MT_SPRAYCAN",
"MT_EMERALD",
"MT_EMERALDSPARK",
"MT_EMERHUNT", // Emerald Hunt
@ -5580,12 +5566,6 @@ const char *const MOBJTYPE_LIST[] = { // array length left dynamic for sanity t
"MT_BIGPUMA",
"MT_APPLE",
"MT_DOOD_FLOWER1",
"MT_DOOD_FLOWER2",
"MT_DOOD_FLOWER3",
"MT_DOOD_FLOWER4",
"MT_DOOD_BOX",
"MT_DOOD_BALLOON",
"MT_BIGRING",
"MT_SNES_DONUTBUSH1",

View file

@ -713,6 +713,8 @@ extern INT32 luabanks[NUM_LUABANKS];
extern INT32 nummaprings; //keep track of spawned rings/coins
extern UINT8 numspraycans;
extern UINT32 bluescore; ///< Blue Team Scores
extern UINT32 redscore; ///< Red Team Scores

View file

@ -215,6 +215,8 @@ UINT32 bluescore, redscore; // CTF and Team Match team scores
// ring count... for PERFECT!
INT32 nummaprings = 0;
UINT8 numspraycans = 0;
// Elminates unnecessary searching.
boolean CheckForBustableBlocks;
boolean CheckForBouncySector;

View file

@ -636,7 +636,7 @@ char sprnames[NUMSPRITES + 1][5] =
"POKE", // Pokey
"AUDI", // Audience members
"DECO", // Old 1.0 Kart Decoratives + New misc ones
"DOOD", // All the old D00Dkart objects
"SPCN", // Spray Can replaces all the old D00Dkart objects
"SNES", // Sprites for SNES remake maps
"GBAS", // Sprites for GBA remake maps
"SPRS", // Sapphire Coast Spring Shell
@ -1860,6 +1860,9 @@ state_t states[NUMSTATES] =
{SPR_EMBM, 24, -1, {NULL}, 0, 0, S_NULL}, // S_EMBLEM25
{SPR_EMBM, 25, -1, {NULL}, 0, 0, S_NULL}, // S_EMBLEM26
// Spray Can
{SPR_SPCN, FF_ANIMATE|FF_SEMIBRIGHT, -1, {NULL}, 15, 2, S_NULL}, // S_SPRAYCAN
// Chaos Emeralds
{SPR_EMRC, FF_FULLBRIGHT, 1, {NULL}, 0, 0, S_CHAOSEMERALD2}, // S_CHAOSEMERALD1
{SPR_EMRC, FF_FULLBRIGHT|FF_ADD, 1, {NULL}, 0, 0, S_CHAOSEMERALD1}, // S_CHAOSEMERALD2
@ -4626,21 +4629,6 @@ state_t states[NUMSTATES] =
{SPR_DECO, FF_FULLBRIGHT|20, 2, {NULL}, 0, 0, S_APPLE8}, //S_APPLE7
{SPR_DECO, FF_FULLBRIGHT|21, 2, {NULL}, 0, 0, S_APPLE1}, //S_APPLE8
{SPR_DOOD, 0, -1, {NULL}, 0, 0, S_NULL}, // S_DOOD_FLOWER1
{SPR_DOOD, 1, 14, {NULL}, 0, 0, S_DOOD_FLOWER3}, // S_DOOD_FLOWER2
{SPR_DOOD, 2, 14, {NULL}, 0, 0, S_DOOD_FLOWER2}, // S_DOOD_FLOWER3
{SPR_DOOD, 3, 7, {NULL}, 0, 0, S_DOOD_FLOWER5}, // S_DOOD_FLOWER4
{SPR_DOOD, 4, 7, {NULL}, 0, 0, S_DOOD_FLOWER4}, // S_DOOD_FLOWER5
{SPR_DOOD, 5, -1, {NULL}, 0, 0, S_NULL}, // S_DOOD_FLOWER6
{SPR_DOOD, 6, 2, {NULL}, 0, 0, S_DOOD_BOX2}, // S_DOOD_BOX1
{SPR_DOOD, 7, 2, {NULL}, 0, 0, S_DOOD_BOX3}, // S_DOOD_BOX2
{SPR_DOOD, 8, 2, {NULL}, 0, 0, S_DOOD_BOX4}, // S_DOOD_BOX3
{SPR_DOOD, 9, 2, {NULL}, 0, 0, S_DOOD_BOX5}, // S_DOOD_BOX4
{SPR_DOOD, 10, 2, {NULL}, 0, 0, S_DOOD_BOX1}, // S_DOOD_BOX5
{SPR_DOOD, 11, -1, {NULL}, 0, 0, S_NULL}, // S_DOOD_BALLOON
{SPR_BRNG, 0, 2, {NULL}, 0, 0, S_BIGRING02}, // S_BIGRING01
{SPR_BRNG, 1, 2, {NULL}, 0, 0, S_BIGRING03}, // S_BIGRING02
{SPR_BRNG, 2, 2, {NULL}, 0, 0, S_BIGRING04}, // S_BIGRING03
@ -8272,7 +8260,34 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
4, // mass
0, // damage
sfx_None, // activesound
MF_SPECIAL|MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags
MF_SPECIAL|MF_NOGRAVITY|MF_NOCLIPHEIGHT|MF_DONTENCOREMAP, // flags
S_NULL // raisestate
},
{ // MT_SPRAYCAN
2807, // doomednum
S_SPRAYCAN, // 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
30*FRACUNIT, // radius
80*FRACUNIT, // height
0, // display offset
0, // mass
0, // damage
sfx_None, // activesound
MF_SPECIAL|MF_NOGRAVITY|MF_NOCLIPHEIGHT|MF_DONTENCOREMAP, // flags
S_NULL // raisestate
},
@ -25673,168 +25688,6 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_NULL // raisestate
},
{ // MT_DOOD_FLOWER1
2805, // doomednum
S_DOOD_FLOWER1, // 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
1048576, // radius
2097152, // height
0, // display offset
100, // mass
0, // damage
sfx_None, // activesound
33558528, // flags
S_NULL // raisestate
},
{ // MT_DOOD_FLOWER2
2800, // doomednum
S_DOOD_FLOWER2, // 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
1048576, // radius
2621440, // height
0, // display offset
100, // mass
0, // damage
sfx_None, // activesound
33558528, // flags
S_NULL // raisestate
},
{ // MT_DOOD_FLOWER3
2801, // doomednum
S_DOOD_FLOWER4, // 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
1048576, // radius
6291456, // height
0, // display offset
100, // mass
0, // damage
sfx_None, // activesound
33558528, // flags
S_NULL // raisestate
},
{ // MT_DOOD_FLOWER4
2802, // doomednum
S_DOOD_FLOWER6, // 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
524288, // radius
2097152, // height
0, // display offset
100, // mass
0, // damage
sfx_None, // activesound
33558528, // flags
S_NULL // raisestate
},
{ // MT_DOOD_BOX
2809, // doomednum
S_DOOD_BOX1, // 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
1048576, // radius
2097152, // height
0, // display offset
100, // mass
0, // damage
sfx_None, // activesound
33554944, // flags
S_NULL // raisestate
},
{ // MT_DOOD_BALLOON
2807, // doomednum
S_DOOD_BALLOON, // 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
91*FRACUNIT, // radius
166*FRACUNIT, // height
0, // display offset
0, // mass
0, // damage
sfx_None, // activesound
MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY|MF_NOGRAVITY, // flags
S_NULL // raisestate
},
{ // MT_BIGRING
2808, // doomednum
S_BIGRING01, // spawnstate

View file

@ -1189,7 +1189,7 @@ typedef enum sprite
SPR_POKE, // Pokey
SPR_AUDI, // Audience members
SPR_DECO, // Old 1.0 Kart Decoratives + New misc ones
SPR_DOOD, // All the old D00Dkart objects
SPR_SPCN, // Spray Can replaces all the old D00Dkart objects
SPR_SNES, // Sprites for SNES remake maps
SPR_GBAS, // Sprites for GBA remake maps
SPR_SPRS, // Sapphire Coast Spring Shell
@ -2344,6 +2344,9 @@ typedef enum state
S_EMBLEM25,
S_EMBLEM26,
// Spray Can
S_SPRAYCAN,
// Chaos Emeralds
S_CHAOSEMERALD1,
S_CHAOSEMERALD2,
@ -5074,24 +5077,6 @@ typedef enum state
S_APPLE7,
S_APPLE8,
// D00Dkart - Fall Flowers
S_DOOD_FLOWER1,
S_DOOD_FLOWER2,
S_DOOD_FLOWER3,
S_DOOD_FLOWER4,
S_DOOD_FLOWER5,
S_DOOD_FLOWER6,
// D00Dkart - Super Circuit Box
S_DOOD_BOX1,
S_DOOD_BOX2,
S_DOOD_BOX3,
S_DOOD_BOX4,
S_DOOD_BOX5,
// D00Dkart - Diddy Kong Racing Bumper
S_DOOD_BALLOON,
// Chaotix Big Ring
S_BIGRING01,
S_BIGRING02,
@ -5994,6 +5979,7 @@ typedef enum mobj_type
MT_REDFLAG, // Red CTF Flag
MT_BLUEFLAG, // Blue CTF Flag
MT_EMBLEM,
MT_SPRAYCAN,
MT_EMERALD,
MT_EMERALDSPARK,
MT_EMERHUNT, // Emerald Hunt
@ -6768,12 +6754,6 @@ typedef enum mobj_type
MT_BIGPUMA,
MT_APPLE,
MT_DOOD_FLOWER1,
MT_DOOD_FLOWER2,
MT_DOOD_FLOWER3,
MT_DOOD_FLOWER4,
MT_DOOD_BOX,
MT_DOOD_BALLOON,
MT_BIGRING,
MT_SNES_DONUTBUSH1,

View file

@ -6050,27 +6050,13 @@ static void M_DrawMapMedals(INT32 mapnum, INT32 x, INT32 y)
{
UINT8 lasttype = UINT8_MAX, curtype;
boolean start = false;
if (mapheaderinfo[mapnum]->cachedcan != 0 && mapheaderinfo[mapnum]->cachedcan < MAXCANCOLORS)
{
V_DrawSmallMappedPatch(x, y, 0, W_CachePatchName("GOTITA", PU_CACHE),
R_GetTranslationColormap(TC_RAINBOW, mapheaderinfo[mapnum]->cachedcan, GTC_MENUCACHE));
//V_DrawRightAlignedThinString(x - 2, y, 0, skincolors[mapheaderinfo[mapnum]->cachedcan].name);
x -= 8;
start = true;
}
// Shift over if emblem is of a different discipline
if (start)
x -= 4;
// M_GetLevelEmblems is ONE-indexed, urgh
mapnum++;
emblem_t *emblem = M_GetLevelEmblems(mapnum);
boolean hasmedals = (emblem != NULL);
while (emblem)
{
switch (emblem->type)
@ -6118,6 +6104,20 @@ static void M_DrawMapMedals(INT32 mapnum, INT32 x, INT32 y)
emblem = M_GetLevelEmblems(-1);
x -= 8;
}
// Undo offset
mapnum--;
if (hasmedals)
x -= 4;
if (mapheaderinfo[mapnum]->cachedcan != 0 && mapheaderinfo[mapnum]->cachedcan < MAXCANCOLORS && gamedata->spraycans[mapheaderinfo[mapnum]->cachedcan].got == true)
{
V_DrawSmallMappedPatch(x, y, 0, W_CachePatchName("GOTCAN", PU_CACHE),
R_GetTranslationColormap(TC_RAINBOW, mapheaderinfo[mapnum]->cachedcan, GTC_MENUCACHE));
//V_DrawRightAlignedThinString(x - 2, y, 0, skincolors[mapheaderinfo[mapnum]->cachedcan].name);
x -= 8;
}
}
static void M_DrawStatsMaps(void)

View file

@ -614,6 +614,43 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
return;
}
case MT_SPRAYCAN:
{
UINT16 col = mapheaderinfo[gamemap-1]->cachedcan;
if (col == 0 || col > MAXCANCOLORS)
{
return;
}
if (demo.playback)
{
// Never collect emblems in replays.
return;
}
if (player->bot)
{
// Your nefarious opponent puppy can't grab these for you.
return;
}
if (P_IsLocalPlayer(player))
{
if (!gamedata->spraycans[col].got)
{
gamedata->spraycans[col].got = true;
if (!M_UpdateUnlockablesAndExtraEmblems(true, true))
S_StartSound(NULL, sfx_ncitem);
gamedata->deferredsave = true;
}
}
// Don't delete the object, just fade it.
P_SprayCanInit(special);
return;
}
// CTF Flags
case MT_REDFLAG:
case MT_BLUEFLAG:

View file

@ -199,6 +199,8 @@ boolean P_AutoPause(void);
void P_ElementalFire(player_t *player, boolean cropcircle);
void P_SpawnSkidDust(player_t *player, fixed_t radius, boolean sound);
void P_SprayCanInit(mobj_t* mobj);
void P_HaltPlayerOrbit(player_t *player);
void P_ExitPlayerOrbit(player_t *player);
boolean P_PlayerOrbit(player_t *player);

View file

@ -7170,7 +7170,6 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
if (P_EmblemWasCollected(mobj->health - 1) || !P_CanPickupEmblem(&players[consoleplayer], mobj->health - 1))
{
trans = tr_trans50;
mobj->renderflags |= (tr_trans50 << RF_TRANSSHIFT);
}
if (mobj->reactiontime > 0
@ -12197,6 +12196,7 @@ fixed_t P_GetMapThingSpawnHeight(const mobjtype_t mobjtype, const mapthing_t* mt
// Ring-like items, float additional units unless args[0] is set.
case MT_SPIKEBALL:
case MT_EMBLEM:
case MT_SPRAYCAN:
case MT_RING:
case MT_BLUESPHERE:
offset += mthing->args[0] ? 0 : 24*FRACUNIT;
@ -12406,6 +12406,23 @@ static boolean P_SetupEmblem(mapthing_t *mthing, mobj_t *mobj)
return true;
}
void P_SprayCanInit(mobj_t* mobj)
{
UINT16 col = mapheaderinfo[gamemap-1]->cachedcan;
if (col == 0 || col > MAXCANCOLORS)
{
mobj->renderflags = RF_DONTDRAW;
return;
}
mobj->color = col;
mobj->renderflags = (gamedata->spraycans[col].got)
? (tr_trans50 << RF_TRANSSHIFT)
: 0;
}
static boolean P_SetupMace(mapthing_t *mthing, mobj_t *mobj)
{
fixed_t mlength, mmaxlength, mlengthset, mspeed, mphase, myaw, mpitch, mminlength, mnumspokes, mpinch, mroll, mnumnospokes, mwidth, mwidthset, mmin, msound, radiusfactor, widthfactor;
@ -12866,6 +12883,23 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj)
}
break;
}
case MT_SPRAYCAN:
{
if (numspraycans)
{
if (numspraycans != UINT8_MAX)
numspraycans++;
P_RemoveMobj(mobj);
return false;
}
P_SetScale(mobj, mobj->destscale = 2*mobj->scale);
P_SprayCanInit(mobj);
numspraycans++;
break;
}
case MT_SKYBOX:
{
P_InitSkyboxPoint(mobj, mthing);

View file

@ -4190,6 +4190,10 @@ static thinker_t* LoadMobjThinker(savebuffer_t *save, actionf_p1 thinker)
{
P_InitSkyboxPoint(mobj, mobj->spawnpoint);
}
else if (mobj->type == MT_SPRAYCAN)
{
P_SprayCanInit(mobj);
}
if (diff2 & MD2_WAYPOINTCAP)
P_SetTarget(&waypointcap, mobj);

View file

@ -813,6 +813,21 @@ static void P_SpawnMapThings(boolean spawnemblems)
}
Z_Free(loopends);
if (spawnemblems)
{
if (numspraycans == 0)
{
UINT16 col = mapheaderinfo[gamemap-1]->cachedcan;
if (col > 0 && col <= MAXCANCOLORS)
{
CONS_Alert(CONS_WARNING, "SPRAY CANS: Map has assigned Spray Cans but no pickup placed!\n");
}
}
else if (numspraycans > 1)
CONS_Alert(CONS_ERROR, "SPRAY CANS: Map has too many Spray Cans (%d)!", numspraycans);
}
}
// Experimental groovy write function!
@ -7472,6 +7487,8 @@ static void P_InitLevelSettings(void)
maptargets = numtargets = 0;
battleprisons = false;
numspraycans = 0;
// emerald hunt
hunt1 = hunt2 = hunt3 = NULL;