From 753b733f7e87afe6c61c286a8b7523fecbc36c31 Mon Sep 17 00:00:00 2001 From: toaster Date: Wed, 13 Sep 2023 18:02:43 +0100 Subject: [PATCH] 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. --- src/p_inter.c | 45 +++++++++++++++++++++++++++++++++++++++++++-- src/p_mobj.c | 14 +++++++++----- src/p_setup.c | 3 ++- 3 files changed, 54 insertions(+), 8 deletions(-) diff --git a/src/p_inter.c b/src/p_inter.c index 86004ad50..79ac76e9e 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -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; } diff --git a/src/p_mobj.c b/src/p_mobj.c index dad3be9d8..59cc5f1b1 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -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; diff --git a/src/p_setup.c b/src/p_setup.c index 8ab8a2588..da3f780b7 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -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