Merge pull request #19 from WumboSpasm/followers
Follower improvements. Thanks Wumbo!
This commit is contained in:
commit
6816173d98
5 changed files with 124 additions and 35 deletions
|
|
@ -316,10 +316,10 @@ consvar_t cv_follower[MAXSPLITSCREENPLAYERS] = {
|
|||
|
||||
// player's follower colors... Also saved...
|
||||
consvar_t cv_followercolor[MAXSPLITSCREENPLAYERS] = {
|
||||
CVAR_INIT ("followercolor", "1", CV_SAVE|CV_CALL|CV_NOINIT, Followercolor_cons_t, Followercolor_OnChange),
|
||||
CVAR_INIT ("followercolor2", "1", CV_SAVE|CV_CALL|CV_NOINIT, Followercolor_cons_t, Followercolor2_OnChange),
|
||||
CVAR_INIT ("followercolor3", "1", CV_SAVE|CV_CALL|CV_NOINIT, Followercolor_cons_t, Followercolor3_OnChange),
|
||||
CVAR_INIT ("followercolor4", "1", CV_SAVE|CV_CALL|CV_NOINIT, Followercolor_cons_t, Followercolor4_OnChange)
|
||||
CVAR_INIT ("followercolor", "Default", CV_SAVE|CV_CALL|CV_NOINIT, Followercolor_cons_t, Followercolor_OnChange),
|
||||
CVAR_INIT ("followercolor2", "Default", CV_SAVE|CV_CALL|CV_NOINIT, Followercolor_cons_t, Followercolor2_OnChange),
|
||||
CVAR_INIT ("followercolor3", "Default", CV_SAVE|CV_CALL|CV_NOINIT, Followercolor_cons_t, Followercolor3_OnChange),
|
||||
CVAR_INIT ("followercolor4", "Default", CV_SAVE|CV_CALL|CV_NOINIT, Followercolor_cons_t, Followercolor4_OnChange)
|
||||
};
|
||||
|
||||
consvar_t cv_skipmapcheck = CVAR_INIT ("skipmapcheck", "Off", CV_SAVE, CV_OnOff, NULL);
|
||||
|
|
@ -855,17 +855,20 @@ void D_RegisterClientCommands(void)
|
|||
Color_cons_t[i].strvalue = skincolors[i].name;
|
||||
}
|
||||
|
||||
for (i = 2; i < MAXSKINCOLORS; i++)
|
||||
for (i = 3; i < MAXSKINCOLORS; i++)
|
||||
{
|
||||
Followercolor_cons_t[i].value = i-2;
|
||||
Followercolor_cons_t[i].strvalue = skincolors[i-2].name;
|
||||
Followercolor_cons_t[i].value = i-3;
|
||||
Followercolor_cons_t[i].strvalue = skincolors[i-3].name;
|
||||
}
|
||||
|
||||
Followercolor_cons_t[1].value = FOLLOWERCOLOR_MATCH;
|
||||
Followercolor_cons_t[1].strvalue = "Match"; // Add "Match" option, which will make the follower color match the player's
|
||||
Followercolor_cons_t[2].value = FOLLOWERCOLOR_MATCH;
|
||||
Followercolor_cons_t[2].strvalue = "Match"; // Add "Match" option, which will make the follower color match the player's
|
||||
|
||||
Followercolor_cons_t[0].value = FOLLOWERCOLOR_OPPOSITE;
|
||||
Followercolor_cons_t[0].strvalue = "Opposite"; // Add "Opposite" option, ...which is like "Match", but for coloropposite.
|
||||
Followercolor_cons_t[1].value = FOLLOWERCOLOR_OPPOSITE;
|
||||
Followercolor_cons_t[1].strvalue = "Opposite"; // Add "Opposite" option, ...which is like "Match", but for coloropposite.
|
||||
|
||||
Followercolor_cons_t[0].value = FOLLOWERCOLOR_DEFAULT;
|
||||
Followercolor_cons_t[0].strvalue = "Default"; // Add "Default" option, which will use the default color of the selected follower
|
||||
|
||||
Color_cons_t[MAXSKINCOLORS].value = Followercolor_cons_t[MAXSKINCOLORS+2].value = 0;
|
||||
Color_cons_t[MAXSKINCOLORS].strvalue = Followercolor_cons_t[MAXSKINCOLORS+2].strvalue = NULL;
|
||||
|
|
@ -1516,7 +1519,7 @@ static void SendNameAndColor(UINT8 n)
|
|||
|
||||
// ditto for follower colour:
|
||||
if (!cv_followercolor[n].value)
|
||||
CV_StealthSet(&cv_followercolor[n], "Match"); // set it to "Match". I don't care about your stupidity!
|
||||
CV_StealthSet(&cv_followercolor[n], "Default"); // set it to "Default". I don't care about your stupidity!
|
||||
|
||||
// so like, this is sent before we even use anything like cvars or w/e so it's possible that follower is set to a pretty yikes value, so let's fix that before we send garbage that could crash the game:
|
||||
if (cv_follower[n].value >= numfollowers || cv_follower[n].value < -1)
|
||||
|
|
|
|||
|
|
@ -3684,7 +3684,7 @@ void readfollower(MYFILE *f)
|
|||
followers[numfollowers].horzlag = 3*FRACUNIT;
|
||||
followers[numfollowers].vertlag = 6*FRACUNIT;
|
||||
followers[numfollowers].anglelag = 8*FRACUNIT;
|
||||
followers[numfollowers].bobspeed = TICRATE*2;
|
||||
followers[numfollowers].bobspeed = (TICRATE*2)*FRACUNIT;
|
||||
followers[numfollowers].bobamp = 4*FRACUNIT;
|
||||
followers[numfollowers].hitconfirmtime = TICRATE;
|
||||
followers[numfollowers].defaultcolor = SKINCOLOR_GREEN;
|
||||
|
|
@ -3735,7 +3735,15 @@ void readfollower(MYFILE *f)
|
|||
}
|
||||
else if (fastcmp(word, "DEFAULTCOLOR"))
|
||||
{
|
||||
followers[numfollowers].defaultcolor = get_number(word2);
|
||||
if (word2)
|
||||
strupr(word2);
|
||||
|
||||
if (fastcmp(word2, "MATCH"))
|
||||
followers[numfollowers].defaultcolor = FOLLOWERCOLOR_MATCH;
|
||||
else if (fastcmp(word2, "OPPOSITE"))
|
||||
followers[numfollowers].defaultcolor = FOLLOWERCOLOR_OPPOSITE;
|
||||
else
|
||||
followers[numfollowers].defaultcolor = get_skincolor(word2);
|
||||
}
|
||||
else if (fastcmp(word, "SCALE"))
|
||||
{
|
||||
|
|
@ -3894,9 +3902,11 @@ if ((signed)followers[numfollowers].field < threshold) \
|
|||
#undef FALLBACK
|
||||
|
||||
// Special case for color I suppose
|
||||
if (followers[numfollowers].defaultcolor > (unsigned)(numskincolors-1))
|
||||
if (followers[numfollowers].defaultcolor > (unsigned)(numskincolors-1)
|
||||
&& followers[numfollowers].defaultcolor != FOLLOWERCOLOR_MATCH
|
||||
&& followers[numfollowers].defaultcolor != FOLLOWERCOLOR_OPPOSITE)
|
||||
{
|
||||
followers[numfollowers].defaultcolor = SKINCOLOR_GREEN;
|
||||
followers[numfollowers].defaultcolor = FOLLOWERCOLOR_MATCH;
|
||||
deh_warning("Follower \'%s\': Value for 'color' should be between 1 and %d.\n", dname, numskincolors-1);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -175,6 +175,43 @@ static void K_SetFollowerState(mobj_t *f, statenum_t state)
|
|||
}
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
UINT16 K_GetEffectiveFollowerColor(UINT16 followercolor, follower_t *follower, UINT16 playercolor, skin_t *playerskin)
|
||||
|
||||
See header file for description.
|
||||
--------------------------------------------------*/
|
||||
UINT16 K_GetEffectiveFollowerColor(UINT16 followercolor, follower_t *follower, UINT16 playercolor, skin_t *playerskin)
|
||||
{
|
||||
if (followercolor == SKINCOLOR_NONE && follower != NULL) // "Default"
|
||||
{
|
||||
followercolor = follower->defaultcolor;
|
||||
}
|
||||
|
||||
if (followercolor > SKINCOLOR_NONE && followercolor < numskincolors) // bog standard
|
||||
{
|
||||
return followercolor;
|
||||
}
|
||||
|
||||
if (playercolor == SKINCOLOR_NONE) // get default color
|
||||
{
|
||||
if (playerskin == NULL)
|
||||
{
|
||||
// Nothing from this line down is valid if playerskin is invalid, just guess Eggman?
|
||||
playerskin = &skins[0];
|
||||
}
|
||||
|
||||
playercolor = playerskin->prefcolor;
|
||||
}
|
||||
|
||||
if (followercolor == FOLLOWERCOLOR_OPPOSITE) // "Opposite"
|
||||
{
|
||||
return skincolors[playercolor].invcolor;
|
||||
}
|
||||
|
||||
// "Match"
|
||||
return playercolor;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
static void K_UpdateFollowerState(mobj_t *f, statenum_t state, followerstate_t type)
|
||||
|
||||
|
|
@ -312,15 +349,20 @@ void K_HandleFollower(player_t *player)
|
|||
color = skincolors[player->skincolor].invcolor;
|
||||
break;
|
||||
|
||||
case FOLLOWERCOLOR_DEFAULT: // "Default"
|
||||
color = fl.defaultcolor;
|
||||
break;
|
||||
|
||||
default:
|
||||
color = player->followercolor;
|
||||
if (color == 0 || color > MAXSKINCOLORS+2) // Make sure this isn't garbage
|
||||
{
|
||||
color = player->skincolor; // "Match" as fallback.
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (color == 0 || color > MAXSKINCOLORS+2) // Make sure this isn't garbage
|
||||
{
|
||||
color = player->skincolor; // "Match" as fallback.
|
||||
}
|
||||
|
||||
if (player->follower == NULL) // follower doesn't exist / isn't valid
|
||||
{
|
||||
//CONS_Printf("Spawning follower...\n");
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
#define FOLLOWERCOLOR_MATCH UINT16_MAX
|
||||
#define FOLLOWERCOLOR_OPPOSITE (UINT16_MAX-1)
|
||||
#define FOLLOWERCOLOR_DEFAULT 0
|
||||
|
||||
extern CV_PossibleValue_t Followercolor_cons_t[]; // follower colours table, not a duplicate because of the "Match" option.
|
||||
|
||||
|
|
@ -136,6 +137,25 @@ boolean K_SetFollowerByName(INT32 playernum, const char *skinname);
|
|||
void K_SetFollowerByNum(INT32 playernum, INT32 skinnum);
|
||||
|
||||
|
||||
/*--------------------------------------------------
|
||||
UINT16 K_GetEffectiveFollowerColor(UINT16 followercolor, follower_t *follower, UINT16 playercolor, skin_t *playerskin)
|
||||
|
||||
Updates a player's follower pointer, and does
|
||||
its positioning and animations.
|
||||
|
||||
Input Arguments:-
|
||||
followercolor - The raw color setting for the follower
|
||||
follower - Follower struct to retrieve default color from. Can be NULL
|
||||
playercolor - The player's associated colour, for reference
|
||||
playerskin - Skin struct to retrieve default color from. Can be NULL
|
||||
|
||||
Return:-
|
||||
The resultant skincolor enum for the follower
|
||||
--------------------------------------------------*/
|
||||
|
||||
UINT16 K_GetEffectiveFollowerColor(UINT16 followercolor, follower_t *follower, UINT16 playercolor, skin_t *playerskin);
|
||||
|
||||
|
||||
/*--------------------------------------------------
|
||||
void K_HandleFollower(player_t *player)
|
||||
|
||||
|
|
|
|||
44
src/m_menu.c
44
src/m_menu.c
|
|
@ -9404,7 +9404,7 @@ static state_t *multi_state;
|
|||
static UINT8 multi_spr2;
|
||||
|
||||
// used for follower display on player setup menu
|
||||
static INT32 follower_tics;
|
||||
static fixed_t follower_tics;
|
||||
static UINT32 follower_frame; // used for FF_ANIMATE garbo
|
||||
static state_t *follower_state;
|
||||
|
||||
|
|
@ -9416,6 +9416,7 @@ static consvar_t *setupm_cvskin;
|
|||
static consvar_t *setupm_cvcolor;
|
||||
static consvar_t *setupm_cvname;
|
||||
static consvar_t *setupm_cvfollower;
|
||||
static consvar_t *setupm_cvfollowercolor;
|
||||
static INT32 setupm_fakeskin;
|
||||
static menucolor_t *setupm_fakecolor;
|
||||
static INT32 setupm_fakefollower; // -1 is for none, our followers start at 0
|
||||
|
|
@ -9679,14 +9680,15 @@ static void M_DrawSetupMultiPlayerMenu(void)
|
|||
{
|
||||
// animate the follower
|
||||
|
||||
if (--follower_tics <= 0)
|
||||
follower_tics -= renderdeltatics;
|
||||
if (follower_tics <= 0)
|
||||
{
|
||||
|
||||
// FF_ANIMATE; cycle through FRAMES and get back afterwards. This will be prominent amongst followers hence why it's being supported here.
|
||||
if (follower_state->frame & FF_ANIMATE)
|
||||
{
|
||||
follower_frame++;
|
||||
follower_tics = follower_state->var2;
|
||||
follower_tics = follower_state->var2*FRACUNIT;
|
||||
if (follower_frame > (follower_state->frame & FF_FRAMEMASK) + follower_state->var1) // that's how it works, right?
|
||||
follower_frame = follower_state->frame & FF_FRAMEMASK;
|
||||
}
|
||||
|
|
@ -9695,9 +9697,7 @@ static void M_DrawSetupMultiPlayerMenu(void)
|
|||
st = follower_state->nextstate;
|
||||
if (st != S_NULL)
|
||||
follower_state = &states[st];
|
||||
follower_tics = follower_state->tics;
|
||||
if (follower_tics == -1)
|
||||
follower_tics = 15; // er, what?
|
||||
follower_tics = follower_state->tics*FRACUNIT;
|
||||
// get spritedef:
|
||||
follower_frame = follower_state->frame & FF_FRAMEMASK;
|
||||
}
|
||||
|
|
@ -9713,20 +9713,30 @@ static void M_DrawSetupMultiPlayerMenu(void)
|
|||
if (sprframe->flip & 2) // Only for first sprite
|
||||
flags |= V_FLIP; // This sprite is left/right flipped!
|
||||
|
||||
// @TODO: Reminder that followers on the menu right now do NOT support the 'followercolor' command, considering this whole menu is getting remade anyway, I see no point in incorporating it in right now.
|
||||
|
||||
// draw follower sprite
|
||||
if (setupm_fakecolor->color) // inverse should never happen
|
||||
{
|
||||
|
||||
// Fake the follower's in game appearance by now also applying some of its variables! coolio, eh?
|
||||
follower_t fl = followers[setupm_fakefollower]; // shortcut for our sanity
|
||||
|
||||
// smooth floating, totally not stolen from rocket sneakers.
|
||||
fixed_t sine = FixedMul(fl.bobamp, FINESINE(((FixedMul(4 * M_TAU_FIXED, fl.bobspeed) * followertimer)>>ANGLETOFINESHIFT) & FINEMASK));
|
||||
tic_t bobspeed = fl.bobspeed;
|
||||
if (fl.mode == FOLLOWERMODE_GROUND)
|
||||
bobspeed = FixedDiv(bobspeed, fl.bobamp / 6); // Rough approximation of bounce speed
|
||||
|
||||
UINT8 *colormap = R_GetTranslationColormap(TC_DEFAULT, setupm_fakecolor->color, 0); // why does GTC_MENUCACHE not work here...?
|
||||
V_DrawFixedPatch((mx+65)*FRACUNIT, ((my+131)*FRACUNIT)-fl.zoffs+sine, fl.scale, flags, patch, colormap);
|
||||
// smooth floating, totally not stolen from rocket sneakers.
|
||||
fixed_t sine = FixedMul(fl.bobamp, FINESINE(((FixedMul(4 * M_TAU_FIXED, bobspeed) * followertimer)>>ANGLETOFINESHIFT) & FINEMASK));
|
||||
|
||||
UINT16 color = K_GetEffectiveFollowerColor(setupm_cvfollowercolor->value, &fl, setupm_fakecolor->color, &skins[setupm_fakeskin]);
|
||||
UINT8 *colormap = R_GetTranslationColormap(TC_DEFAULT, color, 0); // why does GTC_MENUCACHE not work here...?
|
||||
|
||||
INT32 x = (mx+65)*FRACUNIT;
|
||||
INT32 y = ((my+100)*FRACUNIT);
|
||||
if (fl.mode == FOLLOWERMODE_GROUND)
|
||||
y += 40*FRACUNIT - abs(sine) * 2; // Bounce animation
|
||||
else
|
||||
y += sine;
|
||||
|
||||
V_DrawFixedPatch(x, y, fl.scale, flags, patch, colormap);
|
||||
Z_Free(colormap);
|
||||
}
|
||||
}
|
||||
|
|
@ -9748,9 +9758,9 @@ static void M_GetFollowerState(void)
|
|||
follower_state = &states[followers[setupm_fakefollower].followstate];
|
||||
|
||||
if (follower_state->frame & FF_ANIMATE)
|
||||
follower_tics = follower_state->var2; // support for FF_ANIMATE
|
||||
follower_tics = follower_state->var2*FRACUNIT; // support for FF_ANIMATE
|
||||
else
|
||||
follower_tics = follower_state->tics;
|
||||
follower_tics = follower_state->tics*FRACUNIT;
|
||||
|
||||
follower_frame = follower_state->frame & FF_FRAMEMASK;
|
||||
}
|
||||
|
|
@ -9930,6 +9940,7 @@ static void M_SetupMultiPlayer(INT32 choice)
|
|||
setupm_cvcolor = &cv_playercolor[0];
|
||||
setupm_cvname = &cv_playername[0];
|
||||
setupm_cvfollower = &cv_follower[0];
|
||||
setupm_cvfollowercolor = &cv_followercolor[0];
|
||||
|
||||
setupm_fakefollower = setupm_cvfollower->value;
|
||||
|
||||
|
|
@ -9973,6 +9984,7 @@ static void M_SetupMultiPlayer2(INT32 choice)
|
|||
setupm_cvcolor = &cv_playercolor[1];
|
||||
setupm_cvname = &cv_playername[1];
|
||||
setupm_cvfollower = &cv_follower[1];
|
||||
setupm_cvfollowercolor = &cv_followercolor[1];
|
||||
|
||||
setupm_fakefollower = setupm_cvfollower->value;
|
||||
|
||||
|
|
@ -10016,6 +10028,7 @@ static void M_SetupMultiPlayer3(INT32 choice)
|
|||
setupm_cvcolor = &cv_playercolor[2];
|
||||
setupm_cvname = &cv_playername[2];
|
||||
setupm_cvfollower = &cv_follower[2];
|
||||
setupm_cvfollowercolor = &cv_followercolor[2];
|
||||
|
||||
setupm_fakefollower = setupm_cvfollower->value;
|
||||
|
||||
|
|
@ -10059,6 +10072,7 @@ static void M_SetupMultiPlayer4(INT32 choice)
|
|||
setupm_cvcolor = &cv_playercolor[3];
|
||||
setupm_cvname = &cv_playername[3];
|
||||
setupm_cvfollower = &cv_follower[3];
|
||||
setupm_cvfollowercolor = &cv_followercolor[3];
|
||||
|
||||
setupm_fakefollower = setupm_cvfollower->value;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue