From 66001cc73c66f027ff4db8d6a12851c400559a4a Mon Sep 17 00:00:00 2001 From: toaster Date: Fri, 15 Nov 2019 12:47:21 +0000 Subject: [PATCH] Resolve #288. * Fix off-by-one error I caused in the skin randomisation selection. * Clean up signcolour set to never go outside of valid entry range. * Fix the preventing-console-spam mechanism for invalid sprites viewed in-game by only setting the state's sprite/frame to S_UNKNOWN's if the object's sprite/frame is currenly equal to the state's. --- src/p_enemy.c | 59 ++++++++++++++++++++------------------------------ src/r_things.c | 24 ++++++++++---------- 2 files changed, 35 insertions(+), 48 deletions(-) diff --git a/src/p_enemy.c b/src/p_enemy.c index eedbecaa7..374160d41 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -5121,7 +5121,7 @@ void A_SignPlayer(mobj_t *actor) return; #endif - if (actor->tracer == NULL || locvar1 < -3 || locvar1 >= numskins) + if (actor->tracer == NULL || locvar1 < -3 || locvar1 >= numskins || signcolor >= MAXTRANSLATIONS) return; // if no face overlay, spawn one @@ -5148,26 +5148,9 @@ void A_SignPlayer(mobj_t *actor) if (signcolor) ; else if ((actor->target->player->skincolor == skin->prefcolor) && (skin->prefoppositecolor)) // Set it as the skin's preferred oppositecolor? - { signcolor = skin->prefoppositecolor; - /* - If you're here from the comment above Color_Opposite, - the following line is the one which is dependent on the - array being symmetrical. It gets the opposite of the - opposite of your desired colour just so it can get the - brightness frame for the End Sign. It's not a great - design choice, but it's constant time array access and - the idea that the colours should be OPPOSITES is kind - of in the name. If you have a better idea, feel free - to let me know. ~toast 2016/07/20 - */ - signframe += (15 - Color_Opposite[Color_Opposite[skin->prefoppositecolor - 1][0] - 1][1]); - } else if (actor->target->player->skincolor) // Set the sign to be an appropriate background color for this player's skincolor. - { signcolor = Color_Opposite[actor->target->player->skincolor - 1][0]; - signframe += (15 - Color_Opposite[actor->target->player->skincolor - 1][1]); - } else signcolor = SKINCOLOR_NONE; } @@ -5188,10 +5171,10 @@ void A_SignPlayer(mobj_t *actor) skinnum = P_RandomKey(skincount); for (skincount = 0; skincount < numskins; skincount++) { - if (skincheck(skincount)) - skinnum++; if (skincount > skinnum) break; + if (skincheck(skincount)) + skinnum++; } } else // otherwise, advance 1 skin @@ -5203,42 +5186,46 @@ void A_SignPlayer(mobj_t *actor) skin = &skins[skinnum]; } else // specific skin - { skin = &skins[locvar1]; - } facecolor = skin->prefcolor; if (signcolor) ; else if (skin->prefoppositecolor) - { signcolor = skin->prefoppositecolor; - } - else - { + else if (facecolor) signcolor = Color_Opposite[facecolor - 1][0]; - } - signframe += (15 - Color_Opposite[Color_Opposite[signcolor - 1][0] - 1][1]); } - if (skin != NULL && skin->sprites[SPR2_SIGN].numframes) // player face + if (skin && skin->sprites[SPR2_SIGN].numframes) // player face { ov->color = facecolor; ov->skin = skin; P_SetMobjState(ov, actor->info->seestate); // S_PLAY_SIGN - actor->tracer->color = signcolor; - actor->tracer->frame = signframe; } else // Eggman face { ov->color = SKINCOLOR_NONE; P_SetMobjState(ov, actor->info->meleestate); // S_EGGMANSIGN - if (signcolor) - actor->tracer->color = signcolor; - else - actor->tracer->color = signcolor = SKINCOLOR_CARBON; - actor->tracer->frame = signframe += (15 - Color_Opposite[Color_Opposite[signcolor - 1][0] - 1][1]); + if (!signcolor) + signcolor = SKINCOLOR_CARBON; } + + actor->tracer->color = signcolor; + /* + If you're here from the comment above Color_Opposite, + the following line is the one which is dependent on the + array being symmetrical. It gets the opposite of the + opposite of your desired colour just so it can get the + brightness frame for the End Sign. It's not a great + design choice, but it's constant time array access and + the idea that the colours should be OPPOSITES is kind + of in the name. If you have a better idea, feel free + to let me know. ~toast 2016/07/20 + */ + if (signcolor && signcolor < MAXSKINCOLORS) + signframe += (15 - Color_Opposite[Color_Opposite[signcolor - 1][0] - 1][1]); + actor->tracer->frame = signframe; } // Function: A_OverlayThink diff --git a/src/r_things.c b/src/r_things.c index ae3c47db4..c89d87bf4 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -1196,20 +1196,20 @@ static void R_ProjectSprite(mobj_t *thing) #ifdef ROTSPRITE sprinfo = NULL; #endif - } - if (rot >= sprdef->numframes) - { - CONS_Alert(CONS_ERROR, M_GetText("R_ProjectSprite: invalid sprite frame %s/%s for %s\n"), - sizeu1(rot), sizeu2(sprdef->numframes), sprnames[thing->sprite]); - thing->sprite = states[S_UNKNOWN].sprite; - thing->frame = states[S_UNKNOWN].frame; - sprdef = &sprites[thing->sprite]; - rot = thing->frame&FF_FRAMEMASK; - if (!thing->skin) + if (rot >= sprdef->numframes) { - thing->state->sprite = thing->sprite; - thing->state->frame = thing->frame; + CONS_Alert(CONS_ERROR, M_GetText("R_ProjectSprite: invalid sprite frame %s/%s for %s\n"), + sizeu1(rot), sizeu2(sprdef->numframes), sprnames[thing->sprite]); + if (thing->sprite == thing->state->sprite && thing->frame == thing->state->frame) + { + thing->state->sprite = states[S_UNKNOWN].sprite; + thing->state->frame = states[S_UNKNOWN].frame; + } + thing->sprite = states[S_UNKNOWN].sprite; + thing->frame = states[S_UNKNOWN].frame; + sprdef = &sprites[thing->sprite]; + rot = thing->frame&FF_FRAMEMASK; } }