From 01dc98f8f0b5e6cf58f185812557bae6c8380f25 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Fri, 15 Jul 2016 16:48:30 +0100 Subject: [PATCH] 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. --- src/dehacked.c | 2 ++ src/info.c | 6 ++--- src/p_mobj.c | 72 ++++++++++++++++++++++++++++++++++++++++++++------ src/p_pspr.h | 8 ++++-- 4 files changed, 75 insertions(+), 13 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index aafdcf289..cc8bd44a0 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -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}, diff --git a/src/info.c b/src/info.c index 93c32801e..badc28545 100644 --- a/src/info.c +++ b/src/info.c @@ -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 diff --git a/src/p_mobj.c b/src/p_mobj.c index 373326999..61049d9e1 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -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. diff --git a/src/p_pspr.h b/src/p_pspr.h index 2fb232e73..4117a53f1 100644 --- a/src/p_pspr.h +++ b/src/p_pspr.h @@ -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