Permit multiple Spray Cans in one map

- Up to 255
- Each Spray Can placed does, in order, the postion in the list from the current head
    - So if there were 3 cans, and your can list was Red Yellow Blue Green, then Red, Yellow, and Blue would be in the level.
- Grabbing the nth colour in the list will swap that colour to the current head of the list
- However, the game will print to the console if you do this outside of GS_TUTORIAL.
This commit is contained in:
toaster 2023-09-13 18:02:43 +01:00
parent 8326a2d588
commit 753b733f7e
3 changed files with 54 additions and 8 deletions

View file

@ -655,6 +655,25 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
{ {
// Unassigned, get the next grabbable colour // Unassigned, get the next grabbable colour
can_id = gamedata->gotspraycans; can_id = gamedata->gotspraycans;
// Multiple cans in one map?
if (special->threshold != 0)
{
UINT16 ref_id = can_id + (special->threshold & UINT8_MAX);
if (ref_id >= gamedata->numspraycans)
return;
// Swap this specific can to the head of the list.
UINT16 swapcol = gamedata->spraycans[ref_id].col;
gamedata->spraycans[ref_id].col =
gamedata->spraycans[can_id].col;
skincolors[gamedata->spraycans[ref_id].col].cache_spraycan = ref_id;
gamedata->spraycans[can_id].col = swapcol;
skincolors[swapcol].cache_spraycan = can_id;
}
} }
if (can_id >= gamedata->numspraycans) if (can_id >= gamedata->numspraycans)
@ -675,8 +694,30 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
gamedata->deferredsave = true; gamedata->deferredsave = true;
} }
// Don't delete the object, just fade it. {
P_SprayCanInit(special); mobj_t *canmo = NULL;
mobj_t *next = NULL;
for (canmo = trackercap; canmo; canmo = next)
{
next = canmo->itnext;
if (canmo->type != MT_SPRAYCAN)
continue;
// Don't delete the object(s), just fade it.
if (netgame || canmo == special)
{
P_SprayCanInit(canmo);
continue;
}
// Get ready to get rid of these
canmo->renderflags |= (tr_trans50 << RF_TRANSSHIFT);
canmo->destscale = 0;
}
}
return; return;
} }

View file

@ -12443,8 +12443,14 @@ void P_SprayCanInit(mobj_t* mobj)
// Prevent footguns - these won't persist when custom levels are unloaded // Prevent footguns - these won't persist when custom levels are unloaded
else if (gamemap-1 < basenummapheaders) else if (gamemap-1 < basenummapheaders)
{ {
// Unassigned, get the next grabbable colour // Unassigned, get the next grabbable colour (offset by threshold)
can_id = gamedata->gotspraycans; can_id = gamedata->gotspraycans;
// It's ok if this goes over gamedata->numspraycans, as they're
// capped below in this func... but NEVER let this go backwards!!
if (mobj->threshold != 0)
can_id += (mobj->threshold & UINT8_MAX);
mobj->renderflags = 0; mobj->renderflags = 0;
} }
@ -12920,17 +12926,15 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj)
} }
case MT_SPRAYCAN: case MT_SPRAYCAN:
{ {
if (nummapspraycans) if (nummapspraycans == UINT8_MAX)
{ {
if (nummapspraycans != UINT8_MAX)
nummapspraycans++;
P_RemoveMobj(mobj); P_RemoveMobj(mobj);
return false; return false;
} }
P_SetScale(mobj, mobj->destscale = 2*mobj->scale); P_SetScale(mobj, mobj->destscale = 2*mobj->scale);
mobj->threshold = nummapspraycans;
P_SprayCanInit(mobj); P_SprayCanInit(mobj);
nummapspraycans++; nummapspraycans++;
break; break;

View file

@ -816,7 +816,8 @@ static void P_SpawnMapThings(boolean spawnemblems)
Z_Free(loopends); Z_Free(loopends);
if (spawnemblems) if (spawnemblems
&& gametype != GT_TUTORIAL)
{ {
const UINT8 recommendedcans = const UINT8 recommendedcans =
#ifdef DEVELOP #ifdef DEVELOP