A_SignPlayer is an action that changes the state of an Level End Sign to reflect that the player hit it (goes to SeeState
). It will also change the skin color of the actor to become the "opposite" of the player's current skin color (the frame is also changed to adjust the end sign's shade of the color displayed – see List of skin colors > Skin color opposites for more details), and will display the End Sign Icon sprite (the SIGN
sprite set) for the player's current skin as an overlay in front (which is colored to match the player's own skin color). If the player's skin does not have this sprite however, the actor will have the default "CLEAR!" icon displayed in front of it.
If desired, the state's variables can change the appearance of the sign: var1
determines the skin to display on the icon (skin numbers are to be used, e.g. setting it to 2 will show Knuckles), and var2
determines the color of the sign. var1
has some special cases if the number is negative: setting it to -1 will display the target's skin's end sign icon, -2 will select a random skin to display, and -3 will display Eggman's icon (the default when the sign spawns).
Code – A_SignPlayer
|
|
// Function: A_SignPlayer
//
// Description: Changes the state of a level end sign to reflect the player that hit it.
// Also used to display Eggman or the skin roulette whilst spinning.
//
// var1 = number of skin to display (e.g. 2 = Knuckles; special cases: -1 = target's skin, -2 = skin roulette, -3 = Eggman)
// var2 = custom sign color, if desired.
//
void A_SignPlayer(mobj_t *actor)
{
INT32 locvar1 = var1;
INT32 locvar2 = var2;
skin_t *skin = NULL;
mobj_t *ov;
UINT16 facecolor, signcolor = 0;
UINT32 signframe = states[actor->info->raisestate].frame;
facecolor = signcolor = (UINT16)locvar2;
if (LUA_CallAction(A_SIGNPLAYER, actor))
return;
if (actor->tracer == NULL || locvar1 < -3 || locvar1 >= numskins || signcolor >= numskincolors)
return;
// if no face overlay, spawn one
if (actor->tracer->tracer == NULL || P_MobjWasRemoved(actor->tracer->tracer))
{
ov = P_SpawnMobj(actor->x, actor->y, actor->z, MT_OVERLAY);
P_SetTarget(&ov->target, actor->tracer);
P_SetTarget(&actor->tracer->tracer, ov);
}
else
ov = actor->tracer->tracer;
if (locvar1 == -1) // set to target's skin
{
if (!actor->target)
return;
if (!actor->target->player)
return;
skin = &skins[actor->target->player->skin];
facecolor = actor->target->player->skincolor;
if (signcolor)
;
else if (!skin->sprites[SPR2_SIGN].numframes)
signcolor = facecolor;
else if ((facecolor == skin->prefcolor) && (skin->prefoppositecolor)) // Set it as the skin's preferred oppositecolor?
signcolor = skin->prefoppositecolor;
else if (facecolor) // Set the sign to be an appropriate background color for this player's skincolor.
signcolor = skincolors[facecolor].invcolor;
}
else if (locvar1 != -3) // set to a defined skin
{
// I turned this function into a fucking mess. I'm so sorry. -Lach
if (locvar1 == -2) // random skin
{
player_t *player = actor->target ? actor->target->player : NULL;
UINT8 skinnum;
UINT8 skincount = 0;
for (skinnum = 0; skinnum < numskins; skinnum++)
if (SignSkinCheck(player, skinnum))
skincount++;
skinnum = P_RandomKey(skincount);
for (skincount = 0; skincount < numskins; skincount++)
{
if (skincount > skinnum)
break;
if (!SignSkinCheck(player, skincount))
skinnum++;
}
skin = &skins[skinnum];
}
else // specific skin
skin = &skins[locvar1];
facecolor = skin->prefcolor;
if (signcolor)
;
else if (!skin->sprites[SPR2_SIGN].numframes)
signcolor = facecolor;
else if (skin->prefoppositecolor)
signcolor = skin->prefoppositecolor;
else if (facecolor)
signcolor = skincolors[facecolor].invcolor;
}
if (skin)
{
if (skin->sprites[SPR2_SIGN].numframes) // player face
{
ov->color = facecolor;
ov->skin = skin;
if ((statenum_t)(ov->state-states) != actor->info->seestate)
P_SetMobjState(ov, actor->info->seestate); // S_PLAY_SIGN
}
else // CLEAR! sign
{
ov->color = SKINCOLOR_NONE;
ov->skin = NULL; // needs to be NULL in the case of SF_HIRES characters
if ((statenum_t)(ov->state-states) != actor->info->missilestate)
P_SetMobjState(ov, actor->info->missilestate); // S_CLEARSIGN
}
}
else // Eggman face
{
ov->color = SKINCOLOR_NONE;
ov->skin = NULL;
if ((statenum_t)(ov->state-states) != actor->info->meleestate)
P_SetMobjState(ov, actor->info->meleestate); // S_EGGMANSIGN
if (!signcolor)
signcolor = SKINCOLOR_CARBON;
facecolor = signcolor;
}
actor->tracer->color = signcolor;
if (signcolor && signcolor < numskincolors)
signframe += (15 - skincolors[skincolors[signcolor].invcolor].invshade);
actor->tracer->frame = signframe;
}
|
|