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_EMBLEM25",
"S_EMBLEM26", "S_EMBLEM26",
// Spray Can
"S_SPRAYCAN",
// Chaos Emeralds // Chaos Emeralds
"S_CHAOSEMERALD1", "S_CHAOSEMERALD1",
"S_CHAOSEMERALD2", "S_CHAOSEMERALD2",
@ -3921,24 +3924,6 @@ const char *const STATE_LIST[] = { // array length left dynamic for sanity testi
"S_APPLE7", "S_APPLE7",
"S_APPLE8", "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 // Chaotix Big Ring
"S_BIGRING01", "S_BIGRING01",
"S_BIGRING02", "S_BIGRING02",
@ -4805,6 +4790,7 @@ const char *const MOBJTYPE_LIST[] = { // array length left dynamic for sanity t
"MT_REDFLAG", // Red CTF Flag "MT_REDFLAG", // Red CTF Flag
"MT_BLUEFLAG", // Blue CTF Flag "MT_BLUEFLAG", // Blue CTF Flag
"MT_EMBLEM", "MT_EMBLEM",
"MT_SPRAYCAN",
"MT_EMERALD", "MT_EMERALD",
"MT_EMERALDSPARK", "MT_EMERALDSPARK",
"MT_EMERHUNT", // Emerald Hunt "MT_EMERHUNT", // Emerald Hunt
@ -5580,12 +5566,6 @@ const char *const MOBJTYPE_LIST[] = { // array length left dynamic for sanity t
"MT_BIGPUMA", "MT_BIGPUMA",
"MT_APPLE", "MT_APPLE",
"MT_DOOD_FLOWER1",
"MT_DOOD_FLOWER2",
"MT_DOOD_FLOWER3",
"MT_DOOD_FLOWER4",
"MT_DOOD_BOX",
"MT_DOOD_BALLOON",
"MT_BIGRING", "MT_BIGRING",
"MT_SNES_DONUTBUSH1", "MT_SNES_DONUTBUSH1",

View file

@ -713,6 +713,8 @@ extern INT32 luabanks[NUM_LUABANKS];
extern INT32 nummaprings; //keep track of spawned rings/coins extern INT32 nummaprings; //keep track of spawned rings/coins
extern UINT8 numspraycans;
extern UINT32 bluescore; ///< Blue Team Scores extern UINT32 bluescore; ///< Blue Team Scores
extern UINT32 redscore; ///< Red 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! // ring count... for PERFECT!
INT32 nummaprings = 0; INT32 nummaprings = 0;
UINT8 numspraycans = 0;
// Elminates unnecessary searching. // Elminates unnecessary searching.
boolean CheckForBustableBlocks; boolean CheckForBustableBlocks;
boolean CheckForBouncySector; boolean CheckForBouncySector;

View file

@ -636,7 +636,7 @@ char sprnames[NUMSPRITES + 1][5] =
"POKE", // Pokey "POKE", // Pokey
"AUDI", // Audience members "AUDI", // Audience members
"DECO", // Old 1.0 Kart Decoratives + New misc ones "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 "SNES", // Sprites for SNES remake maps
"GBAS", // Sprites for GBA remake maps "GBAS", // Sprites for GBA remake maps
"SPRS", // Sapphire Coast Spring Shell "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, 24, -1, {NULL}, 0, 0, S_NULL}, // S_EMBLEM25
{SPR_EMBM, 25, -1, {NULL}, 0, 0, S_NULL}, // S_EMBLEM26 {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 // Chaos Emeralds
{SPR_EMRC, FF_FULLBRIGHT, 1, {NULL}, 0, 0, S_CHAOSEMERALD2}, // S_CHAOSEMERALD1 {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 {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|20, 2, {NULL}, 0, 0, S_APPLE8}, //S_APPLE7
{SPR_DECO, FF_FULLBRIGHT|21, 2, {NULL}, 0, 0, S_APPLE1}, //S_APPLE8 {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, 0, 2, {NULL}, 0, 0, S_BIGRING02}, // S_BIGRING01
{SPR_BRNG, 1, 2, {NULL}, 0, 0, S_BIGRING03}, // S_BIGRING02 {SPR_BRNG, 1, 2, {NULL}, 0, 0, S_BIGRING03}, // S_BIGRING02
{SPR_BRNG, 2, 2, {NULL}, 0, 0, S_BIGRING04}, // S_BIGRING03 {SPR_BRNG, 2, 2, {NULL}, 0, 0, S_BIGRING04}, // S_BIGRING03
@ -8272,7 +8260,34 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
4, // mass 4, // mass
0, // damage 0, // damage
sfx_None, // activesound 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 S_NULL // raisestate
}, },
@ -25673,168 +25688,6 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_NULL // raisestate 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 { // MT_BIGRING
2808, // doomednum 2808, // doomednum
S_BIGRING01, // spawnstate S_BIGRING01, // spawnstate

View file

@ -1189,7 +1189,7 @@ typedef enum sprite
SPR_POKE, // Pokey SPR_POKE, // Pokey
SPR_AUDI, // Audience members SPR_AUDI, // Audience members
SPR_DECO, // Old 1.0 Kart Decoratives + New misc ones 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_SNES, // Sprites for SNES remake maps
SPR_GBAS, // Sprites for GBA remake maps SPR_GBAS, // Sprites for GBA remake maps
SPR_SPRS, // Sapphire Coast Spring Shell SPR_SPRS, // Sapphire Coast Spring Shell
@ -2344,6 +2344,9 @@ typedef enum state
S_EMBLEM25, S_EMBLEM25,
S_EMBLEM26, S_EMBLEM26,
// Spray Can
S_SPRAYCAN,
// Chaos Emeralds // Chaos Emeralds
S_CHAOSEMERALD1, S_CHAOSEMERALD1,
S_CHAOSEMERALD2, S_CHAOSEMERALD2,
@ -5074,24 +5077,6 @@ typedef enum state
S_APPLE7, S_APPLE7,
S_APPLE8, 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 // Chaotix Big Ring
S_BIGRING01, S_BIGRING01,
S_BIGRING02, S_BIGRING02,
@ -5994,6 +5979,7 @@ typedef enum mobj_type
MT_REDFLAG, // Red CTF Flag MT_REDFLAG, // Red CTF Flag
MT_BLUEFLAG, // Blue CTF Flag MT_BLUEFLAG, // Blue CTF Flag
MT_EMBLEM, MT_EMBLEM,
MT_SPRAYCAN,
MT_EMERALD, MT_EMERALD,
MT_EMERALDSPARK, MT_EMERALDSPARK,
MT_EMERHUNT, // Emerald Hunt MT_EMERHUNT, // Emerald Hunt
@ -6768,12 +6754,6 @@ typedef enum mobj_type
MT_BIGPUMA, MT_BIGPUMA,
MT_APPLE, MT_APPLE,
MT_DOOD_FLOWER1,
MT_DOOD_FLOWER2,
MT_DOOD_FLOWER3,
MT_DOOD_FLOWER4,
MT_DOOD_BOX,
MT_DOOD_BALLOON,
MT_BIGRING, MT_BIGRING,
MT_SNES_DONUTBUSH1, MT_SNES_DONUTBUSH1,

View file

@ -6050,27 +6050,13 @@ static void M_DrawMapMedals(INT32 mapnum, INT32 x, INT32 y)
{ {
UINT8 lasttype = UINT8_MAX, curtype; 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 // M_GetLevelEmblems is ONE-indexed, urgh
mapnum++; mapnum++;
emblem_t *emblem = M_GetLevelEmblems(mapnum); emblem_t *emblem = M_GetLevelEmblems(mapnum);
boolean hasmedals = (emblem != NULL);
while (emblem) while (emblem)
{ {
switch (emblem->type) switch (emblem->type)
@ -6118,6 +6104,20 @@ static void M_DrawMapMedals(INT32 mapnum, INT32 x, INT32 y)
emblem = M_GetLevelEmblems(-1); emblem = M_GetLevelEmblems(-1);
x -= 8; 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) static void M_DrawStatsMaps(void)

View file

@ -614,6 +614,43 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
return; 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 // CTF Flags
case MT_REDFLAG: case MT_REDFLAG:
case MT_BLUEFLAG: case MT_BLUEFLAG:

View file

@ -199,6 +199,8 @@ boolean P_AutoPause(void);
void P_ElementalFire(player_t *player, boolean cropcircle); void P_ElementalFire(player_t *player, boolean cropcircle);
void P_SpawnSkidDust(player_t *player, fixed_t radius, boolean sound); 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_HaltPlayerOrbit(player_t *player);
void P_ExitPlayerOrbit(player_t *player); void P_ExitPlayerOrbit(player_t *player);
boolean P_PlayerOrbit(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)) if (P_EmblemWasCollected(mobj->health - 1) || !P_CanPickupEmblem(&players[consoleplayer], mobj->health - 1))
{ {
trans = tr_trans50; trans = tr_trans50;
mobj->renderflags |= (tr_trans50 << RF_TRANSSHIFT);
} }
if (mobj->reactiontime > 0 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. // Ring-like items, float additional units unless args[0] is set.
case MT_SPIKEBALL: case MT_SPIKEBALL:
case MT_EMBLEM: case MT_EMBLEM:
case MT_SPRAYCAN:
case MT_RING: case MT_RING:
case MT_BLUESPHERE: case MT_BLUESPHERE:
offset += mthing->args[0] ? 0 : 24*FRACUNIT; offset += mthing->args[0] ? 0 : 24*FRACUNIT;
@ -12406,6 +12406,23 @@ static boolean P_SetupEmblem(mapthing_t *mthing, mobj_t *mobj)
return true; 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) 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; 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; 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: case MT_SKYBOX:
{ {
P_InitSkyboxPoint(mobj, mthing); 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); P_InitSkyboxPoint(mobj, mobj->spawnpoint);
} }
else if (mobj->type == MT_SPRAYCAN)
{
P_SprayCanInit(mobj);
}
if (diff2 & MD2_WAYPOINTCAP) if (diff2 & MD2_WAYPOINTCAP)
P_SetTarget(&waypointcap, mobj); P_SetTarget(&waypointcap, mobj);

View file

@ -813,6 +813,21 @@ static void P_SpawnMapThings(boolean spawnemblems)
} }
Z_Free(loopends); 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! // Experimental groovy write function!
@ -7472,6 +7487,8 @@ static void P_InitLevelSettings(void)
maptargets = numtargets = 0; maptargets = numtargets = 0;
battleprisons = false; battleprisons = false;
numspraycans = 0;
// emerald hunt // emerald hunt
hunt1 = hunt2 = hunt3 = NULL; hunt1 = hunt2 = hunt3 = NULL;