New frame flags for more complicated animations.

* FF_MIDDLESTARTCHANCE - has a 50% chance of starting the spr2 or FF_ANIMATE animation halfway in
* FF_SPR2ENDSTATE - if var1 == S_NULL, don't loop, just stop incrementing the frames. Otherwise, go to the state represented by var1.

The former is just something I did for fun, the latter is something that'll come in handy when porting in new-character-moves.
This commit is contained in:
toasterbabe 2016-07-15 16:48:30 +01:00
parent 9b68da63de
commit 01dc98f8f0
4 changed files with 75 additions and 13 deletions

View File

@ -6967,6 +6967,8 @@ struct {
// Frame settings
{"FF_FRAMEMASK",FF_FRAMEMASK},
{"FF_SPR2ENDSTATE",FF_SPR2ENDSTATE},
{"FF_MIDDLESTARTCHANCE",FF_MIDDLESTARTCHANCE},
{"FF_ANIMATE",FF_ANIMATE},
{"FF_FULLBRIGHT",FF_FULLBRIGHT},
{"FF_TRANSMASK",FF_TRANSMASK},

View File

@ -131,8 +131,8 @@ state_t states[NUMSTATES] =
// Player
{SPR_PLAY, SPR2_STND, 105, {NULL}, 0, 0, S_PLAY_WAIT}, // S_PLAY_STND
{SPR_PLAY, SPR2_WAIT, 16, {NULL}, 0, 0, S_PLAY_WAIT}, // S_PLAY_WAIT
{SPR_PLAY, SPR2_WALK, 4, {NULL}, 0, 0, S_PLAY_WALK}, // S_PLAY_WALK
{SPR_PLAY, SPR2_RUN , 2, {NULL}, 0, 0, S_PLAY_RUN}, // S_PLAY_RUN
{SPR_PLAY, SPR2_WALK|FF_MIDDLESTARTCHANCE, 4, {NULL}, 0, 0, S_PLAY_WALK}, // S_PLAY_WALK
{SPR_PLAY, SPR2_RUN |FF_MIDDLESTARTCHANCE, 2, {NULL}, 0, 0, S_PLAY_RUN}, // S_PLAY_RUN
{SPR_PLAY, SPR2_PAIN, 350, {NULL}, 0, 0, S_PLAY_FALL}, // S_PLAY_PAIN
{SPR_PLAY, SPR2_DEAD, 4, {NULL}, 0, 0, S_PLAY_DEAD}, // S_PLAY_DEAD
{SPR_PLAY, SPR2_DRWN, 4, {NULL}, 0, 0, S_PLAY_DRWN}, // S_PLAY_DRWN
@ -153,7 +153,7 @@ state_t states[NUMSTATES] =
// Knuckles abilities
{SPR_PLAY, SPR2_GLID, 2, {NULL}, 0, 0, S_PLAY_GLIDE}, // S_PLAY_GLIDE
{SPR_PLAY, SPR2_CLNG, 6, {NULL}, 0, 0, S_PLAY_CLING}, // S_PLAY_CLING
{SPR_PLAY, SPR2_CLMB, 5, {NULL}, 0, 0, S_PLAY_CLIMB}, // S_PLAY_CLIMB
{SPR_PLAY, SPR2_CLMB|FF_MIDDLESTARTCHANCE, 5, {NULL}, 0, 0, S_PLAY_CLIMB}, // S_PLAY_CLIMB
// Super Sonic
{SPR_PLAY, SPR2_SSTD, 7, {NULL}, 0, 0, S_PLAY_SUPER_STND}, // S_PLAY_SUPER_STND

View File

@ -329,6 +329,8 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state)
}
}
mobj->anim_duration = (UINT16)st->var2; // only used if FF_ANIMATE is set
// Player animations
if (st->sprite == SPR_PLAY)
{
@ -336,9 +338,9 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state)
boolean noalt = false;
UINT8 spr2 = st->frame & FF_FRAMEMASK;
UINT16 frame = (mobj->frame & FF_FRAMEMASK)+1;
mobj->anim_duration = (UINT16)st->var2; // only used if FF_ANIMATE is set
UINT8 numframes;
while (skin->sprites[spr2].numframes <= 0
while (skin && ((numframes = skin->sprites[spr2].numframes) <= 0)
&& spr2 != SPR2_STND)
{
switch(spr2)
@ -447,17 +449,39 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state)
break;
}
if (!skin)
{
frame = 0;
numframes = 0;
}
if (mobj->sprite != SPR_PLAY)
{
mobj->sprite = SPR_PLAY;
frame = 0;
}
else if (mobj->sprite2 != spr2)
frame = 0;
{
if ((st->frame & FF_MIDDLESTARTCHANCE) && numframes && P_RandomChance(FRACUNIT/2))
frame = numframes/2;
else
frame = 0;
}
if (frame >= numframes)
{
if (st->frame & FF_SPR2ENDSTATE)
{
if (st->var1 == S_NULL)
frame--; // no frame advancement
else
return P_SetPlayerMobjState(mobj, st->var1);
}
else
frame = 0;
}
mobj->sprite2 = spr2;
if (!mobj->skin || frame >= ((skin_t *)mobj->skin)->sprites[spr2].numframes)
frame = 0;
mobj->frame = frame|(st->frame&~FF_FRAMEMASK);
}
// Regular sprites
@ -465,6 +489,8 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state)
{
mobj->sprite = st->sprite;
mobj->frame = st->frame;
if ((st->frame & (FF_ANIMATE|FF_MIDDLESTARTCHANCE)) == (FF_ANIMATE|FF_MIDDLESTARTCHANCE))
mobj->frame += (st->var1)/2;
}
// Modified handling.
@ -536,18 +562,46 @@ boolean P_SetMobjState(mobj_t *mobj, statenum_t state)
// Player animations
if (st->sprite == SPR_PLAY)
{
skin_t *skin = ((skin_t *)mobj->skin);
UINT8 spr2 = st->frame & FF_FRAMEMASK;
UINT16 frame = (mobj->frame & FF_FRAMEMASK)+1;
UINT8 numframes;
if (skin)
numframes = skin->sprites[spr2].numframes;
else
{
frame = 0;
numframes = 0;
}
if (mobj->sprite != SPR_PLAY)
{
mobj->sprite = SPR_PLAY;
frame = 0;
}
else if (mobj->sprite2 != spr2)
frame = 0;
{
if ((st->frame & FF_MIDDLESTARTCHANCE) && numframes && P_RandomChance(FRACUNIT/2))
frame = numframes/2;
else
frame = 0;
}
if (frame >= numframes)
{
if (st->frame & FF_SPR2ENDSTATE)
{
if (st->var1 == S_NULL)
frame--; // no frame advancement
else
return P_SetPlayerMobjState(mobj, st->var1);
}
else
frame = 0;
}
mobj->sprite2 = spr2;
if (!mobj->skin || frame >= ((skin_t *)mobj->skin)->sprites[spr2].numframes)
frame = 0;
mobj->frame = frame|(st->frame&~FF_FRAMEMASK);
}
// Regular sprites
@ -555,6 +609,8 @@ boolean P_SetMobjState(mobj_t *mobj, statenum_t state)
{
mobj->sprite = st->sprite;
mobj->frame = st->frame;
if ((st->frame & (FF_ANIMATE|FF_MIDDLESTARTCHANCE)) == (FF_ANIMATE|FF_MIDDLESTARTCHANCE))
mobj->frame += (st->var1)/2;
}
// Modified handling.

View File

@ -35,8 +35,12 @@
#pragma interface
#endif
/// \brief Frame flags: only the frame number
#define FF_FRAMEMASK 0x3fff
/// \brief Frame flags: only the frame number - 0 to 127 (Frames and Sprite2)
#define FF_FRAMEMASK 0x7f
/// \brief Frame flags: A change of state at the end of Sprite2 animation
#define FF_SPR2ENDSTATE 0x1000
/// \brief Frame flags: 50% of starting in middle of animation (Sprite2 and FF_ANIMATE)
#define FF_MIDDLESTARTCHANCE 0x2000
/// \brief Frame flags: Simple stateless animation
#define FF_ANIMATE 0x4000
/// \brief Frame flags: frame always appears full bright