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
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)
@ -675,8 +694,30 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
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;
}

View file

@ -12443,8 +12443,14 @@ void P_SprayCanInit(mobj_t* mobj)
// Prevent footguns - these won't persist when custom levels are unloaded
else if (gamemap-1 < basenummapheaders)
{
// Unassigned, get the next grabbable colour
// Unassigned, get the next grabbable colour (offset by threshold)
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;
}
@ -12920,17 +12926,15 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj)
}
case MT_SPRAYCAN:
{
if (nummapspraycans)
if (nummapspraycans == UINT8_MAX)
{
if (nummapspraycans != UINT8_MAX)
nummapspraycans++;
P_RemoveMobj(mobj);
return false;
}
P_SetScale(mobj, mobj->destscale = 2*mobj->scale);
mobj->threshold = nummapspraycans;
P_SprayCanInit(mobj);
nummapspraycans++;
break;

View file

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