mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2026-04-26 12:01:47 +00:00
Profiles: Followers support
This commit is contained in:
parent
6db54f77d8
commit
7132a1be10
5 changed files with 475 additions and 16 deletions
|
|
@ -3505,6 +3505,7 @@ void readfollower(MYFILE *f)
|
|||
followers[numfollowers].bobamp = 4;
|
||||
followers[numfollowers].hitconfirmtime = TICRATE;
|
||||
followers[numfollowers].defaultcolor = SKINCOLOR_GREEN;
|
||||
strcpy(followers[numfollowers].icon, "M_NORANK");
|
||||
|
||||
do
|
||||
{
|
||||
|
|
@ -3538,6 +3539,11 @@ void readfollower(MYFILE *f)
|
|||
strcpy(followers[numfollowers].name, word2);
|
||||
nameset = true;
|
||||
}
|
||||
else if (fastcmp(word, "ICON"))
|
||||
{
|
||||
strcpy(followers[numfollowers].icon, word2);
|
||||
nameset = true;
|
||||
}
|
||||
else if (fastcmp(word, "DEFAULTCOLOR"))
|
||||
{
|
||||
followers[numfollowers].defaultcolor = (UINT16)get_number(word2);
|
||||
|
|
|
|||
|
|
@ -493,6 +493,8 @@ typedef enum
|
|||
CSSTEP_CHARS,
|
||||
CSSTEP_ALTS,
|
||||
CSSTEP_COLORS,
|
||||
CSSTEP_FOLLOWER,
|
||||
CSSTEP_FOLLOWERCOLORS,
|
||||
CSSTEP_READY
|
||||
} setup_mdepth_t;
|
||||
|
||||
|
|
@ -506,6 +508,13 @@ typedef struct setup_player_s
|
|||
UINT8 delay;
|
||||
UINT8 color;
|
||||
UINT8 mdepth;
|
||||
|
||||
INT32 followern;
|
||||
INT16 followercolor;
|
||||
tic_t follower_tics;
|
||||
tic_t follower_timer;
|
||||
UINT8 follower_frame;
|
||||
state_t *follower_state;
|
||||
} setup_player_t;
|
||||
|
||||
extern setup_player_t setup_player[MAXSPLITSCREENPLAYERS];
|
||||
|
|
|
|||
270
src/k_menudraw.c
270
src/k_menudraw.c
|
|
@ -823,6 +823,8 @@ static void M_DrawCharSelectCircle(setup_player_t *p, INT16 x, INT16 y)
|
|||
|
||||
if (p->mdepth == CSSTEP_ALTS)
|
||||
numoptions = setup_chargrid[p->gridx][p->gridy].numskins;
|
||||
else if (p->mdepth == CSSTEP_FOLLOWERCOLORS)
|
||||
numoptions = numskincolors-1 +2;
|
||||
else
|
||||
numoptions = numskincolors-1;
|
||||
|
||||
|
|
@ -857,6 +859,55 @@ static void M_DrawCharSelectCircle(setup_player_t *p, INT16 x, INT16 y)
|
|||
cx -= (SHORT(patch->width) << FRACBITS) >> 1;
|
||||
cy -= (SHORT(patch->height) << FRACBITS) >> 1;
|
||||
}
|
||||
|
||||
else if (p->mdepth == CSSTEP_FOLLOWERCOLORS)
|
||||
{
|
||||
INT16 diff;
|
||||
UINT16 col;
|
||||
|
||||
n = (p->followercolor-1) + numoptions/2;
|
||||
|
||||
if (subtract)
|
||||
n -= ((i+1)/2);
|
||||
else
|
||||
n += ((i+1)/2);
|
||||
|
||||
n %= numoptions;
|
||||
n++;
|
||||
|
||||
if (!n)
|
||||
continue;
|
||||
|
||||
col = (unsigned)(n);
|
||||
switch (col)
|
||||
{
|
||||
case FOLLOWERCOLOR_MATCH: // "Match"
|
||||
col = p->color;
|
||||
break;
|
||||
case FOLLOWERCOLOR_OPPOSITE: // "Opposite"
|
||||
col = skincolors[p->color].invcolor;
|
||||
break;
|
||||
}
|
||||
|
||||
colormap = R_GetTranslationColormap(TC_DEFAULT, col, GTC_MENUCACHE);
|
||||
|
||||
if (n > p->followercolor)
|
||||
diff = n - p->followercolor;
|
||||
else
|
||||
diff = p->followercolor - n;
|
||||
|
||||
if (diff == 0)
|
||||
patch = W_CachePatchName("COLORSP2", PU_CACHE);
|
||||
else if (abs(diff) < 25)
|
||||
patch = W_CachePatchName("COLORSP1", PU_CACHE);
|
||||
else
|
||||
patch = W_CachePatchName("COLORSP0", PU_CACHE);
|
||||
|
||||
radius = 28<<FRACBITS;
|
||||
//radius -= SHORT(patch->width) << FRACBITS;
|
||||
|
||||
cx -= (SHORT(patch->width) << FRACBITS) >> 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
INT16 diff;
|
||||
|
|
@ -949,6 +1000,164 @@ static boolean M_DrawCharacterSprite(INT16 x, INT16 y, SINT8 skin, INT32 addflag
|
|||
return true;
|
||||
}
|
||||
|
||||
// Draws the follower list.
|
||||
static void M_DrawFollowerList(setup_player_t *p, UINT8 num)
|
||||
{
|
||||
INT16 x = 82;
|
||||
INT16 y = 3;
|
||||
INT32 cf = p->followern;
|
||||
UINT8 i;
|
||||
UINT8 *colormap = NULL;
|
||||
|
||||
if (num & 1)
|
||||
x = 172;
|
||||
|
||||
if (num >= 2)
|
||||
y = 176;
|
||||
|
||||
// this places it at the bottom of the card!
|
||||
if (optionsmenu.profile)
|
||||
{
|
||||
x = 35;
|
||||
y = 143;
|
||||
}
|
||||
|
||||
// Start 1 follower below.
|
||||
cf--;
|
||||
if (cf < -1)
|
||||
cf = numfollowers-1;
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
patch_t *pp = NULL;
|
||||
follower_t fl = followers[cf];
|
||||
|
||||
if (W_LumpExists(fl.icon) && cf >= 0)
|
||||
{
|
||||
UINT16 col = (unsigned)p->followercolor;
|
||||
pp = W_CachePatchName(fl.icon, PU_CACHE);
|
||||
|
||||
switch (col)
|
||||
{
|
||||
case FOLLOWERCOLOR_MATCH: // "Match"
|
||||
col = p->color;
|
||||
break;
|
||||
case FOLLOWERCOLOR_OPPOSITE: // "Opposite"
|
||||
col = skincolors[p->color].invcolor;
|
||||
break;
|
||||
}
|
||||
|
||||
colormap = R_GetTranslationColormap(TC_DEFAULT, col, GTC_MENUCACHE);
|
||||
V_DrawMappedPatch(x, y, 0, pp, colormap);
|
||||
if (i == 1)
|
||||
V_DrawMappedPatch(x, y, 0, W_CachePatchName(va("K_CHILI%d", p->follower_timer%16 /2 +1), PU_CACHE), NULL);
|
||||
|
||||
}
|
||||
// No patch....
|
||||
else
|
||||
{
|
||||
V_DrawFill(x, y, 16, 16, 0);
|
||||
|
||||
if (i == 1)
|
||||
V_DrawMappedPatch(x, y, 0, W_CachePatchName(va("K_CHILI%d", p->follower_timer%16 /2 +1), PU_CACHE), NULL);
|
||||
|
||||
if (cf >= 0)
|
||||
V_DrawString(x, y, 0, va("%d\n", cf));
|
||||
else
|
||||
V_DrawMappedPatch(x-4, y-3, 0, W_CachePatchName("K_NOBLNS", PU_CACHE), NULL);
|
||||
|
||||
}
|
||||
|
||||
cf++;
|
||||
if (cf > numfollowers-1)
|
||||
cf = -1;
|
||||
|
||||
x += 23;
|
||||
}
|
||||
}
|
||||
|
||||
// Returns false is the follower shouldn't be rendered.
|
||||
// 'num' can be used to directly specify the follower number, but doing this will not animate it.
|
||||
// if a setup_player_t is specified instead, its data will be used to animate the follower sprite.
|
||||
static boolean M_DrawFollowerSprite(INT16 x, INT16 y, INT32 num, INT32 addflags, UINT16 color, setup_player_t *p)
|
||||
{
|
||||
|
||||
spritedef_t *sprdef;
|
||||
spriteframe_t *sprframe;
|
||||
patch_t *patch;
|
||||
INT32 followernum;
|
||||
state_t *usestate;
|
||||
UINT32 useframe;
|
||||
follower_t fl;
|
||||
UINT8 *colormap = NULL;
|
||||
|
||||
if (p != NULL)
|
||||
followernum = p->followern;
|
||||
else
|
||||
followernum = num;
|
||||
|
||||
// Don't draw if we're outta bounds.
|
||||
if (followernum < 0 || followernum > numfollowers-1)
|
||||
return false;
|
||||
|
||||
fl = followers[followernum];
|
||||
|
||||
if (p != NULL)
|
||||
{
|
||||
usestate = p->follower_state;
|
||||
useframe = p->follower_frame;
|
||||
}
|
||||
else
|
||||
{
|
||||
usestate = &states[followers[followernum].followstate];
|
||||
useframe = usestate->frame & FF_FRAMEMASK;
|
||||
}
|
||||
|
||||
sprdef = &sprites[usestate->sprite];
|
||||
|
||||
// draw the follower
|
||||
|
||||
if (useframe >= sprdef->numframes)
|
||||
useframe = 0; // frame doesn't exist, we went beyond it... what?
|
||||
|
||||
sprframe = &sprdef->spriteframes[useframe];
|
||||
patch = W_CachePatchNum(sprframe->lumppat[1], PU_CACHE);
|
||||
|
||||
if (sprframe->flip & 2) // Only for first sprite
|
||||
{
|
||||
if (addflags & V_FLIP)
|
||||
addflags &= ~V_FLIP;
|
||||
else
|
||||
addflags |= V_FLIP; // This sprite is left/right flipped!
|
||||
}
|
||||
|
||||
fixed_t sine = 0;
|
||||
|
||||
if (p != NULL)
|
||||
{
|
||||
const fixed_t pi = (22<<FRACBITS) / 7; // loose approximation, this doesn't need to be incredibly precise
|
||||
sine = fl.bobamp * FINESINE((((8*pi*(fl.bobspeed)) * p->follower_timer)>>ANGLETOFINESHIFT) & FINEMASK);
|
||||
color = p->followercolor;
|
||||
|
||||
switch (color)
|
||||
{
|
||||
case FOLLOWERCOLOR_MATCH: // "Match"
|
||||
color = p->color;
|
||||
break;
|
||||
case FOLLOWERCOLOR_OPPOSITE: // "Opposite"
|
||||
color = skincolors[p->color].invcolor;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
colormap = R_GetTranslationColormap(TC_DEFAULT, color, GTC_MENUCACHE);
|
||||
V_DrawFixedPatch((x)*FRACUNIT, (y-12)*FRACUNIT+sine, fl.scale, addflags, patch, colormap);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void M_DrawCharSelectSprite(UINT8 num, INT16 x, INT16 y)
|
||||
{
|
||||
setup_player_t *p = &setup_player[num];
|
||||
|
|
@ -983,7 +1192,15 @@ static void M_DrawCharSelectPreview(UINT8 num)
|
|||
{
|
||||
M_DrawCharSelectSprite(num, x+32, y+75);
|
||||
|
||||
if (p->mdepth == CSSTEP_ALTS || p->mdepth == CSSTEP_COLORS)
|
||||
if (p->mdepth >= CSSTEP_FOLLOWER)
|
||||
{
|
||||
M_DrawFollowerSprite(x+16, y+75, -1, !(num & 1) ? V_FLIP : 0, 0, p);
|
||||
|
||||
if (p->mdepth == CSSTEP_FOLLOWER)
|
||||
M_DrawFollowerList(p, num);
|
||||
}
|
||||
|
||||
if (p->mdepth == CSSTEP_ALTS || p->mdepth == CSSTEP_COLORS || p->mdepth == CSSTEP_FOLLOWERCOLORS)
|
||||
{
|
||||
M_DrawCharSelectCircle(p, x+32, y+64);
|
||||
}
|
||||
|
|
@ -1175,21 +1392,63 @@ static void M_DrawProfileCard(INT32 x, INT32 y, boolean greyedout, profile_t *p)
|
|||
// check what setup_player is doing in priority.
|
||||
if (sp->mdepth >= CSSTEP_CHARS)
|
||||
{
|
||||
skinnum = setup_chargrid[sp->gridx][sp->gridy].skinlist[sp->clonenum];
|
||||
|
||||
skinnum = setup_chargrid[sp->gridx][sp->gridy].skinlist[sp->clonenum];
|
||||
|
||||
if (M_DrawCharacterSprite(x-22, y+119, skinnum, V_FLIP, colormap))
|
||||
V_DrawMappedPatch(x+14, y+66, 0, faceprefix[skinnum][FACE_RANK], colormap);
|
||||
|
||||
if (sp->mdepth == CSSTEP_ALTS || sp->mdepth == CSSTEP_COLORS)
|
||||
if (M_DrawFollowerSprite(x-44 +12, y+119, 0, V_FLIP, 0, sp))
|
||||
{
|
||||
UINT16 col = (unsigned)p->followercolor;
|
||||
patch_t *ico = W_CachePatchName(followers[sp->followern].icon, PU_CACHE);
|
||||
UINT8 *fcolormap;
|
||||
|
||||
switch (col)
|
||||
{
|
||||
case FOLLOWERCOLOR_MATCH: // "Match"
|
||||
col = sp->color;
|
||||
break;
|
||||
case FOLLOWERCOLOR_OPPOSITE: // "Opposite"
|
||||
col = skincolors[sp->color].invcolor;
|
||||
break;
|
||||
}
|
||||
|
||||
fcolormap = R_GetTranslationColormap(TC_DEFAULT, col, GTC_MENUCACHE);
|
||||
V_DrawMappedPatch(x+14+18, y+66, 0, ico, fcolormap);
|
||||
}
|
||||
|
||||
if (sp->mdepth == CSSTEP_ALTS || sp->mdepth == CSSTEP_COLORS || sp->mdepth == CSSTEP_FOLLOWERCOLORS)
|
||||
{
|
||||
M_DrawCharSelectCircle(sp, x-22, y+104);
|
||||
}
|
||||
}
|
||||
else if (skinnum > -1) // otherwise, read from profile.
|
||||
{
|
||||
|
||||
UINT16 col = (unsigned)p->followercolor;
|
||||
UINT8 fln = R_FollowerAvailable(p->follower);
|
||||
|
||||
if (M_DrawCharacterSprite(x-22, y+119, skinnum, V_FLIP, colormap))
|
||||
V_DrawMappedPatch(x+14, y+66, 0, faceprefix[skinnum][FACE_RANK], colormap);
|
||||
|
||||
switch (col)
|
||||
{
|
||||
case FOLLOWERCOLOR_MATCH: // "Match"
|
||||
col = p->color;
|
||||
break;
|
||||
case FOLLOWERCOLOR_OPPOSITE: // "Opposite"
|
||||
col = skincolors[p->color].invcolor;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if (M_DrawFollowerSprite(x-44 +12, y+119, fln, V_FLIP, col, NULL))
|
||||
{
|
||||
patch_t *ico = W_CachePatchName(followers[fln].icon, PU_CACHE);
|
||||
UINT8 *fcolormap = R_GetTranslationColormap(TC_DEFAULT, col, GTC_MENUCACHE);
|
||||
V_DrawMappedPatch(x+14+18, y+66, 0, ico, fcolormap);
|
||||
}
|
||||
}
|
||||
|
||||
V_DrawCenteredGamemodeString(x, y+24, 0, 0, pname);
|
||||
|
|
@ -1287,8 +1546,13 @@ void M_DrawCharacterSelect(void)
|
|||
if (optionsmenu.profile == NULL)
|
||||
M_DrawCharSelectPreview(i);
|
||||
else if (i == 0)
|
||||
{
|
||||
M_DrawProfileCard(optionsmenu.optx, optionsmenu.opty, false, optionsmenu.profile);
|
||||
|
||||
if (setup_player[0].mdepth == CSSTEP_FOLLOWER)
|
||||
M_DrawFollowerList(&setup_player[0], 0);
|
||||
}
|
||||
|
||||
if (i >= setup_numplayers)
|
||||
continue;
|
||||
|
||||
|
|
|
|||
203
src/k_menufunc.c
203
src/k_menufunc.c
|
|
@ -2027,6 +2027,11 @@ static void M_SetupProfileGridPos(setup_player_t *p)
|
|||
profile_t *pr = PR_GetProfile(p->profilen);
|
||||
INT32 i;
|
||||
|
||||
// While we're here, read follower values.
|
||||
p->followern = R_FollowerAvailable(pr->follower);
|
||||
p->followercolor = pr->followercolor;
|
||||
|
||||
// Now position the grid for skin
|
||||
for (i = 0; i < numskins; i++)
|
||||
{
|
||||
if (!(strcmp(pr->skinname, skins[i].name)))
|
||||
|
|
@ -2058,9 +2063,9 @@ void M_CharacterSelectInit(void)
|
|||
if (i != 0 || optionsmenu.profile)
|
||||
CV_SetValue(&cv_usejoystick[i], -1);
|
||||
|
||||
CONS_Printf("Device for %d set to %d\n", i, -1);
|
||||
//CONS_Printf("Device for %d set to %d\n", i, -1);
|
||||
}
|
||||
CONS_Printf("========\n");
|
||||
//CONS_Printf("========\n");
|
||||
|
||||
memset(setup_chargrid, -1, sizeof(setup_chargrid));
|
||||
for (i = 0; i < 9; i++)
|
||||
|
|
@ -2075,6 +2080,13 @@ void M_CharacterSelectInit(void)
|
|||
memset(setup_explosions, 0, sizeof(setup_explosions));
|
||||
setup_animcounter = 0;
|
||||
|
||||
// Default to no follower / Match
|
||||
for (i = 0; i < MAXSPLITSCREENPLAYERS; i++)
|
||||
{
|
||||
setup_player[i].followern = -1;
|
||||
setup_player[i].followercolor = -1;
|
||||
}
|
||||
|
||||
for (i = 0; i < numskins; i++)
|
||||
{
|
||||
UINT8 x = skins[i].kartspeed-1;
|
||||
|
|
@ -2229,16 +2241,16 @@ static boolean M_HandlePressStart(setup_player_t *p, UINT8 num)
|
|||
{
|
||||
// Available!! Let's use this one!!
|
||||
CV_SetValue(&cv_usejoystick[num], i);
|
||||
CONS_Printf("Device for %d set to %d\n", num, i);
|
||||
CONS_Printf("========\n");
|
||||
//CONS_Printf("Device for %d set to %d\n", num, i);
|
||||
//CONS_Printf("========\n");
|
||||
|
||||
for (j = num+1; j < MAXSPLITSCREENPLAYERS; j++)
|
||||
{
|
||||
// Un-set devices for other players.
|
||||
CV_SetValue(&cv_usejoystick[j], -1);
|
||||
CONS_Printf("Device for %d set to %d\n", j, -1);
|
||||
//CONS_Printf("Device for %d set to %d\n", j, -1);
|
||||
}
|
||||
CONS_Printf("========\n");
|
||||
//CONS_Printf("========\n");
|
||||
|
||||
//setup_numplayers++;
|
||||
p->mdepth = CSSTEP_PROFILE;
|
||||
|
|
@ -2428,6 +2440,21 @@ static boolean M_HandleCharacterGrid(setup_player_t *p, UINT8 num)
|
|||
return false;
|
||||
}
|
||||
|
||||
// Gets the selected follower's state for a given setup player.
|
||||
static void M_GetFollowerState(setup_player_t *p)
|
||||
{
|
||||
|
||||
p->follower_state = &states[followers[p->followern].followstate];
|
||||
|
||||
if (p->follower_state->frame & FF_ANIMATE)
|
||||
p->follower_tics = p->follower_state->var2; // support for FF_ANIMATE
|
||||
else
|
||||
p->follower_tics = p->follower_state->tics;
|
||||
|
||||
p->follower_frame = p->follower_state->frame & FF_FRAMEMASK;
|
||||
}
|
||||
|
||||
|
||||
static void M_HandleCharRotate(setup_player_t *p, UINT8 num)
|
||||
{
|
||||
UINT8 numclones = setup_chargrid[p->gridx][p->gridy].numskins;
|
||||
|
|
@ -2488,10 +2515,12 @@ static void M_HandleColorRotate(setup_player_t *p, UINT8 num)
|
|||
|
||||
if (M_MenuButtonPressed(num, MBT_A) || M_MenuButtonPressed(num, MBT_X) /*|| M_MenuButtonPressed(num, MBT_START)*/)
|
||||
{
|
||||
p->mdepth = CSSTEP_READY;
|
||||
p->delay = TICRATE;
|
||||
M_SetupReadyExplosions(p);
|
||||
S_StartSound(NULL, sfx_s3k4e);
|
||||
p->mdepth = CSSTEP_FOLLOWER;
|
||||
M_GetFollowerState(p);
|
||||
|
||||
//p->delay = TICRATE;
|
||||
//M_SetupReadyExplosions(p);
|
||||
//S_StartSound(NULL, sfx_s3k4e);
|
||||
M_SetMenuDelay(num);
|
||||
}
|
||||
else if (M_MenuButtonPressed(num, MBT_B) || M_MenuButtonPressed(num, MBT_Y))
|
||||
|
|
@ -2505,6 +2534,133 @@ static void M_HandleColorRotate(setup_player_t *p, UINT8 num)
|
|||
}
|
||||
}
|
||||
|
||||
static void M_AnimateFollower(setup_player_t *p)
|
||||
{
|
||||
if (--p->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 (p->follower_state->frame & FF_ANIMATE)
|
||||
{
|
||||
p->follower_frame++;
|
||||
p->follower_tics = p->follower_state->var2;
|
||||
if (p->follower_frame > (p->follower_state->frame & FF_FRAMEMASK) + p->follower_state->var1) // that's how it works, right?
|
||||
p->follower_frame = p->follower_state->frame & FF_FRAMEMASK;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (p->follower_state->nextstate != S_NULL)
|
||||
p->follower_state = &states[p->follower_state->nextstate];
|
||||
p->follower_tics = p->follower_state->tics;
|
||||
/*if (p->follower_tics == -1)
|
||||
p->follower_tics = 15; // er, what?*/
|
||||
// get spritedef:
|
||||
p->follower_frame = p->follower_state->frame & FF_FRAMEMASK;
|
||||
}
|
||||
}
|
||||
|
||||
p->follower_timer++;
|
||||
}
|
||||
|
||||
static void M_HandleChooseFollower(setup_player_t *p, UINT8 num)
|
||||
{
|
||||
|
||||
M_AnimateFollower(p);
|
||||
|
||||
if (menucmd[num].dpad_lr > 0 && numfollowers)
|
||||
{
|
||||
p->followern++;
|
||||
if (p->followern > numfollowers-1)
|
||||
p->followern = -1;
|
||||
|
||||
M_SetMenuDelay(num);
|
||||
S_StartSound(NULL, sfx_menu1);
|
||||
M_GetFollowerState(p);
|
||||
}
|
||||
else if (menucmd[num].dpad_lr < 0 && numfollowers)
|
||||
{
|
||||
p->followern--;
|
||||
if (p->followern < -1)
|
||||
p->followern = numfollowers-1;
|
||||
|
||||
M_SetMenuDelay(num);
|
||||
S_StartSound(NULL, sfx_menu1);
|
||||
M_GetFollowerState(p);
|
||||
}
|
||||
else if (M_MenuButtonPressed(num, MBT_A) || M_MenuButtonPressed(num, MBT_X))
|
||||
{
|
||||
if (p->followern > -1)
|
||||
p->mdepth = CSSTEP_FOLLOWERCOLORS;
|
||||
else
|
||||
{
|
||||
p->mdepth = CSSTEP_READY;
|
||||
p->delay = TICRATE;
|
||||
M_SetupReadyExplosions(p);
|
||||
S_StartSound(NULL, sfx_s3k4e);
|
||||
M_SetMenuDelay(num);
|
||||
}
|
||||
|
||||
S_StartSound(NULL, sfx_s3k63);
|
||||
M_SetMenuDelay(num);
|
||||
}
|
||||
else if (M_MenuButtonPressed(num, MBT_B) || M_MenuButtonPressed(num, MBT_Y))
|
||||
{
|
||||
p->mdepth = CSSTEP_COLORS;
|
||||
S_StartSound(NULL, sfx_s3k5b);
|
||||
M_SetMenuDelay(num);
|
||||
}
|
||||
}
|
||||
|
||||
static void M_HandleFollowerColorRotate(setup_player_t *p, UINT8 num)
|
||||
{
|
||||
M_AnimateFollower(p);
|
||||
|
||||
if (menucmd[num].dpad_lr > 0)
|
||||
{
|
||||
p->followercolor++;
|
||||
|
||||
// Go back to -2 (Opposite)
|
||||
if (p->followercolor >= numskincolors)
|
||||
p->followercolor = -2;
|
||||
|
||||
// Make sure we skip 0.
|
||||
if (p->followercolor == 0)
|
||||
p->followercolor++;
|
||||
|
||||
p->rotate = CSROTATETICS;
|
||||
M_SetMenuDelay(num); //CSROTATETICS
|
||||
S_StartSound(NULL, sfx_s3k5b); //sfx_s3kc3s
|
||||
}
|
||||
else if (menucmd[num].dpad_lr < 0)
|
||||
{
|
||||
p->followercolor--;
|
||||
if (p->followercolor < -2)
|
||||
p->followercolor = numskincolors-1;
|
||||
|
||||
if (p->followercolor == 0)
|
||||
p->followercolor--;
|
||||
|
||||
p->rotate = -CSROTATETICS;
|
||||
M_SetMenuDelay(num); //CSROTATETICS
|
||||
S_StartSound(NULL, sfx_s3k5b); //sfx_s3kc3s
|
||||
}
|
||||
|
||||
if (M_MenuButtonPressed(num, MBT_A) || M_MenuButtonPressed(num, MBT_X) /*|| M_MenuButtonPressed(num, MBT_START)*/)
|
||||
{
|
||||
p->mdepth = CSSTEP_READY;
|
||||
p->delay = TICRATE;
|
||||
M_SetupReadyExplosions(p);
|
||||
S_StartSound(NULL, sfx_s3k4e);
|
||||
M_SetMenuDelay(num);
|
||||
}
|
||||
else if (M_MenuButtonPressed(num, MBT_B) || M_MenuButtonPressed(num, MBT_Y))
|
||||
{
|
||||
p->mdepth = CSSTEP_FOLLOWER;
|
||||
S_StartSound(NULL, sfx_s3k5b);
|
||||
M_SetMenuDelay(num);
|
||||
}
|
||||
}
|
||||
|
||||
boolean M_CharacterSelectHandler(INT32 choice)
|
||||
{
|
||||
INT32 i;
|
||||
|
|
@ -2535,6 +2691,12 @@ boolean M_CharacterSelectHandler(INT32 choice)
|
|||
case CSSTEP_COLORS: // Select color
|
||||
M_HandleColorRotate(p, i);
|
||||
break;
|
||||
case CSSTEP_FOLLOWER:
|
||||
M_HandleChooseFollower(p, i);
|
||||
break;
|
||||
case CSSTEP_FOLLOWERCOLORS:
|
||||
M_HandleFollowerColorRotate(p, i);
|
||||
break;
|
||||
case CSSTEP_READY:
|
||||
default: // Unready
|
||||
if (M_MenuButtonPressed(i, MBT_B) || M_MenuButtonPressed(i, MBT_Y))
|
||||
|
|
@ -2584,7 +2746,7 @@ static void M_MPConfirmCharacterSelection(void)
|
|||
INT16 col;
|
||||
|
||||
char colstr[8];
|
||||
char commandnames[][2][MAXSTRINGLENGTH] = { {"skin ", "color "}, {"skin2 ", "color2 "}, {"skin3 ", "color3 "}, {"skin4 ", "color4 "}};
|
||||
char commandnames[][4][MAXSTRINGLENGTH] = { {"skin ", "color ", "follower ", "followercolor "}, {"skin2 ", "color2 ", "follower2 ", "followercolor2 "}, {"skin3 ", "color3 " "follower3 ", "followercolor3 "}, {"skin4 ", "color4 ", "follower4 ", "followercolor4 "}};
|
||||
// ^ laziness 100 (we append a space directly so that we don't have to do it later too!!!!)
|
||||
|
||||
for (i = 0; i < MAXSPLITSCREENPLAYERS; i++)
|
||||
|
|
@ -2594,7 +2756,6 @@ static void M_MPConfirmCharacterSelection(void)
|
|||
// skin
|
||||
strcpy(cmd, commandnames[i][0]);
|
||||
strcat(cmd, skins[setup_player[i].skin].name);
|
||||
|
||||
COM_ImmedExecute(cmd);
|
||||
|
||||
// colour
|
||||
|
|
@ -2603,10 +2764,18 @@ static void M_MPConfirmCharacterSelection(void)
|
|||
sprintf(colstr, "%d", col);
|
||||
strcpy(cmd, commandnames[i][1]);
|
||||
strcat(cmd, colstr);
|
||||
COM_ImmedExecute(cmd);
|
||||
|
||||
// follower
|
||||
strcpy(cmd, commandnames[i][2]);
|
||||
strcat(cmd, va("%d", setup_player[i].followern));
|
||||
COM_ImmedExecute(cmd);
|
||||
|
||||
// follower color
|
||||
strcpy(cmd, commandnames[i][3]);
|
||||
strcat(cmd, va("%d", setup_player[i].followercolor));
|
||||
COM_ImmedExecute(cmd);
|
||||
}
|
||||
|
||||
M_ClearMenus(true);
|
||||
}
|
||||
|
||||
|
|
@ -2659,9 +2828,14 @@ void M_CharacterSelectTick(void)
|
|||
// in a profile; update the selected profile and then go back to the profile menu.
|
||||
if (optionsmenu.profile)
|
||||
{
|
||||
// save player
|
||||
strcpy(optionsmenu.profile->skinname, skins[setup_player[0].skin].name);
|
||||
optionsmenu.profile->color = setup_player[0].color;
|
||||
|
||||
// save follower
|
||||
strcpy(optionsmenu.profile->follower, followers[setup_player[0].followern].skinname);
|
||||
optionsmenu.profile->followercolor = setup_player[0].followercolor;
|
||||
|
||||
// reset setup_player
|
||||
memset(setup_player, 0, sizeof(setup_player));
|
||||
|
||||
|
|
@ -2674,6 +2848,9 @@ void M_CharacterSelectTick(void)
|
|||
{
|
||||
CV_StealthSet(&cv_skin[i], skins[setup_player[i].skin].name);
|
||||
CV_StealthSetValue(&cv_playercolor[i], setup_player[i].color);
|
||||
|
||||
CV_StealthSetValue(&cv_follower[i], setup_player[i].followern);
|
||||
CV_StealthSetValue(&cv_followercolor[i], setup_player[i].followercolor);
|
||||
}
|
||||
|
||||
CV_StealthSetValue(&cv_splitplayers, setup_numplayers);
|
||||
|
|
|
|||
|
|
@ -128,6 +128,9 @@ typedef struct follower_s
|
|||
INT32 losestate; // state when the player has lost
|
||||
INT32 hitconfirmstate; // state for hit confirm
|
||||
UINT32 hitconfirmtime; // time to keep the above playing for
|
||||
|
||||
// visual
|
||||
char icon[8+1]; // Lump names are only 8 characters. (+1 for \0)
|
||||
} follower_t;
|
||||
|
||||
extern INT32 numfollowers;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue