Merge branch 'player-new-frames' into 'master'

New player frames: Glancing and death

See merge request KartKrew/Kart!362
This commit is contained in:
James R 2021-02-06 05:57:11 -05:00
commit caa7fe1b47
16 changed files with 605 additions and 72 deletions

View file

@ -631,6 +631,8 @@ static inline void resynch_write_player(resynch_pak *rsp, const size_t i)
rsp->tumbleLastBounce = players[i].tumbleLastBounce;
rsp->tumbleSound = players[i].tumbleSound;
rsp->glanceDir = players[i].glanceDir;
// respawnvars_t
rsp->respawn_state = players[i].respawn.state;
rsp->respawn_pointx = (fixed_t)LONG(players[i].respawn.pointx);
@ -789,6 +791,8 @@ static void resynch_read_player(resynch_pak *rsp)
players[i].tumbleLastBounce = (boolean)rsp->tumbleLastBounce;
players[i].tumbleSound = (boolean)rsp->tumbleSound;
players[i].glanceDir = (SINT8)rsp->glanceDir;
// respawnvars_t
players[i].respawn.state = rsp->respawn_state;
players[i].respawn.pointx = (fixed_t)LONG(rsp->respawn_pointx);

View file

@ -295,6 +295,8 @@ typedef struct
boolean tumbleLastBounce;
boolean tumbleSound;
SINT8 glanceDir;
// respawnvars_t
UINT8 respawn_state;
fixed_t respawn_pointx;

View file

@ -115,19 +115,11 @@ typedef enum
{
// Are animation frames playing?
PA_ETC=0,
PA_IDLE,
PA_EDGE,
PA_WALK,
PA_RUN,
PA_DASH,
PA_PAIN,
PA_ROLL,
PA_JUMP,
PA_SPRING,
PA_FALL,
PA_ABILITY,
PA_ABILITY2,
PA_RIDE
PA_STILL,
PA_SLOW,
PA_FAST,
PA_DRIFT,
PA_HURT
} panim_t;
//
@ -577,6 +569,8 @@ typedef struct player_s
boolean tumbleLastBounce;
boolean tumbleSound;
SINT8 glanceDir; // Direction the player is trying to look backwards in
//
UINT32 charflags; // Extra abilities/settings for skins (combinable stuff)

View file

@ -5211,12 +5211,24 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
"S_KART_STILL",
"S_KART_STILL_L",
"S_KART_STILL_R",
"S_KART_STILL_GLANCE_L",
"S_KART_STILL_GLANCE_R",
"S_KART_STILL_LOOK_L",
"S_KART_STILL_LOOK_R",
"S_KART_SLOW",
"S_KART_SLOW_L",
"S_KART_SLOW_R",
"S_KART_SLOW_GLANCE_L",
"S_KART_SLOW_GLANCE_R",
"S_KART_SLOW_LOOK_L",
"S_KART_SLOW_LOOK_R",
"S_KART_FAST",
"S_KART_FAST_L",
"S_KART_FAST_R",
"S_KART_FAST_GLANCE_L",
"S_KART_FAST_GLANCE_R",
"S_KART_FAST_LOOK_L",
"S_KART_FAST_LOOK_R",
"S_KART_DRIFT_L",
"S_KART_DRIFT_L_OUT",
"S_KART_DRIFT_L_IN",
@ -5224,12 +5236,18 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
"S_KART_DRIFT_R_OUT",
"S_KART_DRIFT_R_IN",
"S_KART_SPINOUT",
"S_KART_SQUISH",
"S_KART_DEAD",
"S_KART_SIGN",
// technically the player goes here but it's an infinite tic state
"S_OBJPLACE_DUMMY",
"S_KART_LEFTOVER",
"S_KART_LEFTOVER_NOTIRES",
"S_KART_TIRE1",
"S_KART_TIRE2",
// Blue Crawla
"S_POSS_STND",
"S_POSS_RUN1",
@ -9428,6 +9446,8 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s
"MT_THOK", // Thok! mobj
"MT_PLAYER",
"MT_KART_LEFTOVER",
"MT_KART_TIRE",
// Enemies
"MT_BLUECRAWLA", // Crawla (Blue)
@ -11450,19 +11470,11 @@ struct {
// Player animation (panim_t)
{"PA_ETC",PA_ETC},
{"PA_IDLE",PA_IDLE},
{"PA_EDGE",PA_EDGE},
{"PA_WALK",PA_WALK},
{"PA_RUN",PA_RUN},
{"PA_DASH",PA_DASH},
{"PA_PAIN",PA_PAIN},
{"PA_ROLL",PA_ROLL},
{"PA_JUMP",PA_JUMP},
{"PA_SPRING",PA_SPRING},
{"PA_FALL",PA_FALL},
{"PA_ABILITY",PA_ABILITY},
{"PA_ABILITY2",PA_ABILITY2},
{"PA_RIDE",PA_RIDE},
{"PA_STILL",PA_STILL},
{"PA_SLOW",PA_SLOW},
{"PA_FAST",PA_FAST},
{"PA_DRIFT",PA_DRIFT},
{"PA_HURT",PA_HURT},
// Value for infinite lives
{"INFLIVES",INFLIVES},

View file

@ -2261,7 +2261,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
p->pflags |= PF_JUMPDOWN;
p->playerstate = PST_LIVE;
p->panim = PA_IDLE; // standing animation
p->panim = PA_STILL; // standing animation
// Check to make sure their color didn't change somehow...
if (G_GametypeHasTeams())

View file

@ -32,6 +32,8 @@ char sprnames[NUMSPRITES + 1][5] =
"THOK", // Thok! mobj
"PLAY",
"KART",
"TIRE",
// Enemies
"POSS", // Crawla (Blue)
@ -748,12 +750,23 @@ char sprnames[NUMSPRITES + 1][5] =
char spr2names[NUMPLAYERSPRITES][5] =
{
"STIN", "STIL", "STIR", // Still
"STGL", "STGR", // Still (glance back)
"STLL", "STLR", // Still (look back)
"SLWN", "SLWL", "SLWR", // Slow driving
"SLGL", "SLGR", // Slow (glance back)
"SLLL", "SLLR", // Slow (look back)
"FSTN", "FSTL", "FSTR", // Fast driving
"FSGL", "FSGR", // Fast (glance back)
"FSLL", "FSLR", // Fast (look back)
"DRLN", "DRLO", "DRLI", // Drifting left
"DRRN", "DRRO", "DRRI", // Drifting right
"SPIN", // Spinout
"SQSH", // Squish
"DEAD", // Dead
"SIGN", // Finish signpost
"XTRA", // Three Faces of Darkness
};
@ -763,14 +776,26 @@ playersprite_t spr2defaults[NUMPLAYERSPRITES] = {
0, // SPR2_STIN
SPR2_STIN, // SPR2_STIL
SPR2_STIN, // SPR2_STIR
SPR2_STIN, // SPR2_STGL
SPR2_STIN, // SPR2_STGR
SPR2_STGL, // SPR2_STLL
SPR2_STGR, // SPR2_STLR
0, // SPR2_SLWN
SPR2_SLWN, // SPR2_SLWL
SPR2_SLWN, // SPR2_SLWR
SPR2_SLWN, // SPR2_SLGL
SPR2_SLWN, // SPR2_SLGR
SPR2_SLGL, // SPR2_SLLL
SPR2_SLGR, // SPR2_SLLR
0, // SPR2_FSTN
SPR2_FSTN, // SPR2_FSTL
SPR2_FSTN, // SPR2_FSTR
SPR2_FSTN, // SPR2_FSGL
SPR2_FSTN, // SPR2_FSGR
SPR2_FSGL, // SPR2_FSLL
SPR2_FSGR, // SPR2_FSLR
0, // SPR2_DRLN
SPR2_DRLN, // SPR2_DRLO
@ -781,9 +806,10 @@ playersprite_t spr2defaults[NUMPLAYERSPRITES] = {
SPR2_DRRN, // SPR2_DRRI
0, // SPR2_SPIN
SPR2_SPIN, // SPR2_SQSH
0, // SPR2_DEAD
0, // SPR2_SIGN
0, // SPR2_XTRA
};
// Doesn't work with g++, needs actionf_p1 (don't modify this comment)
@ -814,12 +840,24 @@ state_t states[NUMSTATES] =
{SPR_PLAY, SPR2_STIN, 1, {NULL}, 0, 0, S_KART_STILL}, // S_KART_STILL
{SPR_PLAY, SPR2_STIL, 1, {NULL}, 0, 0, S_KART_STILL_L}, // S_KART_STILL_L
{SPR_PLAY, SPR2_STIR, 1, {NULL}, 0, 0, S_KART_STILL_R}, // S_KART_STILL_R
{SPR_PLAY, SPR2_STGL, 1, {NULL}, 0, 0, S_KART_STILL_GLANCE_L}, // S_KART_STILL_GLANCE_L
{SPR_PLAY, SPR2_STGR, 1, {NULL}, 0, 0, S_KART_STILL_GLANCE_R}, // S_KART_STILL_GLANCE_R
{SPR_PLAY, SPR2_STLL, 1, {NULL}, 0, 0, S_KART_STILL_LOOK_L}, // S_KART_STILL_LOOK_L
{SPR_PLAY, SPR2_STLR, 1, {NULL}, 0, 0, S_KART_STILL_LOOK_R}, // S_KART_STILL_LOOK_R
{SPR_PLAY, SPR2_SLWN, 1, {NULL}, 0, 0, S_KART_SLOW}, // S_KART_SLOW
{SPR_PLAY, SPR2_SLWL, 1, {NULL}, 0, 0, S_KART_SLOW_L}, // S_KART_SLOW_L
{SPR_PLAY, SPR2_SLWR, 1, {NULL}, 0, 0, S_KART_SLOW_R}, // S_KART_SLOW_R
{SPR_PLAY, SPR2_SLGL, 1, {NULL}, 0, 0, S_KART_SLOW_GLANCE_L}, // S_KART_SLOW_GLANCE_L
{SPR_PLAY, SPR2_SLGR, 1, {NULL}, 0, 0, S_KART_SLOW_GLANCE_R}, // S_KART_SLOW_GLANCE_R
{SPR_PLAY, SPR2_SLLL, 1, {NULL}, 0, 0, S_KART_SLOW_LOOK_L}, // S_KART_SLOW_LOOK_L
{SPR_PLAY, SPR2_SLLR, 1, {NULL}, 0, 0, S_KART_SLOW_LOOK_R}, // S_KART_SLOW_LOOK_R
{SPR_PLAY, SPR2_FSTN, 1, {NULL}, 0, 0, S_KART_FAST}, // S_KART_FAST
{SPR_PLAY, SPR2_FSTL, 1, {NULL}, 0, 0, S_KART_FAST_L}, // S_KART_FAST_L
{SPR_PLAY, SPR2_FSTR, 1, {NULL}, 0, 0, S_KART_FAST_R}, // S_KART_FAST_R
{SPR_PLAY, SPR2_FSGL, 1, {NULL}, 0, 0, S_KART_FAST_GLANCE_L}, // S_KART_FAST_GLANCE_L
{SPR_PLAY, SPR2_FSGR, 1, {NULL}, 0, 0, S_KART_FAST_GLANCE_R}, // S_KART_FAST_GLANCE_R
{SPR_PLAY, SPR2_FSLL, 1, {NULL}, 0, 0, S_KART_FAST_LOOK_L}, // S_KART_FAST_LOOK_L
{SPR_PLAY, SPR2_FSLR, 1, {NULL}, 0, 0, S_KART_FAST_LOOK_R}, // S_KART_FAST_LOOK_R
{SPR_PLAY, SPR2_DRLN, 1, {NULL}, 0, 0, S_KART_DRIFT_L}, // S_KART_DRIFT_L
{SPR_PLAY, SPR2_DRLO, 1, {NULL}, 0, 0, S_KART_DRIFT_L_OUT}, // S_KART_DRIFT_L_OUT
{SPR_PLAY, SPR2_DRLI, 1, {NULL}, 0, 0, S_KART_DRIFT_L_IN}, // S_KART_DRIFT_L_IN
@ -827,11 +865,17 @@ state_t states[NUMSTATES] =
{SPR_PLAY, SPR2_DRRO, 1, {NULL}, 0, 0, S_KART_DRIFT_R_OUT}, // S_KART_DRIFT_R_OUT
{SPR_PLAY, SPR2_DRRI, 1, {NULL}, 0, 0, S_KART_DRIFT_R_IN}, // S_KART_DRIFT_R_IN
{SPR_PLAY, SPR2_SPIN|FF_ANIMATE, 350, {NULL}, 0, 1, S_KART_STILL}, // S_KART_SPINOUT
{SPR_PLAY, SPR2_SQSH|FF_ANIMATE, 350, {NULL}, 0, 1, S_KART_STILL}, // S_KART_SQUISH
{SPR_PLAY, SPR2_DEAD, 3, {NULL}, 0, 0, S_KART_DEAD}, // S_KART_DEAD
{SPR_PLAY, SPR2_SIGN|FF_PAPERSPRITE, 1, {NULL}, 0, 0, S_KART_SIGN}, // S_KART_SIGN
{SPR_NULL, 0, -1, {NULL}, 0, 0, S_OBJPLACE_DUMMY}, // S_OBJPLACE_DUMMY
{SPR_KART, 0, -1, {NULL}, 0, 0, S_NULL}, // S_KART_LEFTOVER
{SPR_KART, 1, -1, {NULL}, 0, 0, S_NULL}, // S_KART_LEFTOVER_NOTIRES
{SPR_TIRE, 0, -1, {NULL}, 0, 0, S_NULL}, // S_KART_TIRE1
{SPR_TIRE, 1, -1, {NULL}, 0, 0, S_NULL}, // S_KART_TIRE2
// Blue Crawla
{SPR_POSS, 0, 5, {A_Look}, 0, 0, S_POSS_STND}, // S_POSS_STND
{SPR_POSS, 0, 3, {A_Chase}, 0, 0, S_POSS_RUN2}, // S_POSS_RUN1
@ -5227,7 +5271,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
sfx_None, // painsound
S_NULL, // meleestate
S_NULL, // missilestate
S_KART_SPINOUT, // deathstate
S_KART_DEAD, // deathstate
S_NULL, // xdeathstate
sfx_None, // deathsound
1, // speed
@ -5241,6 +5285,60 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
(statenum_t)MT_THOK // raisestate
},
{ // MT_KART_LEFTOVER
4095, // doomednum
S_KART_LEFTOVER, // spawnstate
2, // spawnhealth
S_NULL, // seestate
sfx_None, // seesound
0, // reactiontime
sfx_None, // attacksound
S_NULL, // painstate
0, // painchance
sfx_None, // painsound
S_NULL, // meleestate
S_NULL, // missilestate
S_NULL, // deathstate
S_NULL, // xdeathstate
sfx_None, // deathsound
1, // speed
16*FRACUNIT, // radius
48*FRACUNIT, // height
-1, // display offset
1000, // mass
0, // damage
sfx_None, // activesound
MF_SOLID|MF_DONTENCOREMAP, // flags
S_NULL // raisestate
},
{ // MT_KART_TIRE
-1, // doomednum
S_KART_TIRE1, // spawnstate
1, // spawnhealth
S_NULL, // seestate
sfx_None, // seesound
0, // reactiontime
sfx_None, // attacksound
S_NULL, // painstate
0, // painchance
sfx_None, // painsound
S_NULL, // meleestate
S_NULL, // missilestate
S_NULL, // deathstate
S_NULL, // xdeathstate
sfx_None, // deathsound
1, // speed
6*FRACUNIT, // radius
12*FRACUNIT, // height
-1, // display offset
1000, // mass
0, // damage
sfx_None, // activesound
MF_DONTENCOREMAP, // flags
S_NULL // raisestate
},
{ // MT_BLUECRAWLA
100, // doomednum
S_POSS_STND, // spawnstate

View file

@ -303,6 +303,8 @@ typedef enum sprite
SPR_THOK, // Thok! mobj
SPR_PLAY,
SPR_KART,
SPR_TIRE,
// Enemies
SPR_POSS, // Crawla (Blue)
@ -1026,12 +1028,15 @@ typedef enum sprite
typedef enum playersprite
{
SPR2_STIN = 0, SPR2_STIL, SPR2_STIR,
SPR2_STGL, SPR2_STGR, SPR2_STLL, SPR2_STLR,
SPR2_SLWN, SPR2_SLWL, SPR2_SLWR,
SPR2_SLGL, SPR2_SLGR, SPR2_SLLL, SPR2_SLLR,
SPR2_FSTN, SPR2_FSTL, SPR2_FSTR,
SPR2_FSGL, SPR2_FSGR, SPR2_FSLL, SPR2_FSLR,
SPR2_DRLN, SPR2_DRLO, SPR2_DRLI,
SPR2_DRRN, SPR2_DRRO, SPR2_DRRI,
SPR2_SPIN,
SPR2_SQSH,
SPR2_DEAD,
SPR2_SIGN,
SPR2_XTRA,
SPR2_FIRSTFREESLOT,
@ -1059,12 +1064,24 @@ typedef enum state
S_KART_STILL,
S_KART_STILL_L,
S_KART_STILL_R,
S_KART_STILL_GLANCE_L,
S_KART_STILL_GLANCE_R,
S_KART_STILL_LOOK_L,
S_KART_STILL_LOOK_R,
S_KART_SLOW,
S_KART_SLOW_L,
S_KART_SLOW_R,
S_KART_SLOW_GLANCE_L,
S_KART_SLOW_GLANCE_R,
S_KART_SLOW_LOOK_L,
S_KART_SLOW_LOOK_R,
S_KART_FAST,
S_KART_FAST_L,
S_KART_FAST_R,
S_KART_FAST_GLANCE_L,
S_KART_FAST_GLANCE_R,
S_KART_FAST_LOOK_L,
S_KART_FAST_LOOK_R,
S_KART_DRIFT_L,
S_KART_DRIFT_L_OUT,
S_KART_DRIFT_L_IN,
@ -1072,12 +1089,18 @@ typedef enum state
S_KART_DRIFT_R_OUT,
S_KART_DRIFT_R_IN,
S_KART_SPINOUT,
S_KART_SQUISH,
S_KART_DEAD,
S_KART_SIGN,
// technically the player goes here but it's an infinite tic state
S_OBJPLACE_DUMMY,
S_KART_LEFTOVER,
S_KART_LEFTOVER_NOTIRES,
S_KART_TIRE1,
S_KART_TIRE2,
// Blue Crawla
S_POSS_STND,
S_POSS_RUN1,
@ -5315,6 +5338,8 @@ typedef enum mobj_type
MT_THOK, // Thok! mobj
MT_PLAYER,
MT_KART_LEFTOVER,
MT_KART_TIRE,
// Enemies
MT_BLUECRAWLA, // Crawla (Blue)

View file

@ -2425,6 +2425,7 @@ static void K_drawKartPlayerCheck(void)
UINT8 cnum = 0;
UINT8 i;
INT32 splitflags = V_SNAPTOBOTTOM|V_SPLITSCREEN;
fixed_t y = CHEK_Y * FRACUNIT;
if (stplyr == NULL || stplyr->mo == NULL || P_MobjWasRemoved(stplyr->mo))
{
@ -2443,6 +2444,8 @@ static void K_drawKartPlayerCheck(void)
if (r_splitscreen)
{
y /= 2;
for (i = 1; i <= r_splitscreen; i++)
{
if (stplyr == &players[displayplayers[i]])
@ -2515,7 +2518,7 @@ static void K_drawKartPlayerCheck(void)
K_ObjectTracking(&x, NULL, &c, thiscam->angle + ANGLE_180, 0, &v, cnum);
colormap = R_GetTranslationColormap(TC_DEFAULT, checkplayer->mo->color, GTC_CACHE);
V_DrawFixedPatch(x, CHEK_Y * FRACUNIT, FRACUNIT, V_HUDTRANS|V_SPLITSCREEN|splitflags, kp_check[pnum], colormap);
V_DrawFixedPatch(x, y, FRACUNIT, V_HUDTRANS|V_SPLITSCREEN|splitflags, kp_check[pnum], colormap);
}
}

View file

@ -1010,6 +1010,14 @@ fixed_t K_GetMobjWeight(mobj_t *mobj, mobj_t *against)
break;
weight = K_PlayerWeight(mobj, against);
break;
case MT_KART_LEFTOVER:
weight = 5*FRACUNIT/2;
if (mobj->extravalue1 > 0)
{
weight = mobj->extravalue1 * (FRACUNIT >> 1);
}
break;
case MT_BUBBLESHIELD:
weight = K_PlayerWeight(mobj->target, against);
break;
@ -1726,6 +1734,102 @@ void K_SpawnDriftBoostClipSpark(mobj_t *clip)
spark->momy = clip->momx/2;
}
static SINT8 K_GlanceAtPlayers(player_t *glancePlayer)
{
const fixed_t maxdistance = FixedMul(1280 * mapobjectscale, K_GetKartGameSpeedScalar(gamespeed));
const angle_t blindSpotSize = ANG10; // ANG5
UINT8 i;
SINT8 glanceDir = 0;
SINT8 lastValidGlance = 0;
// See if there's any players coming up behind us.
// If so, your character will glance at 'em.
for (i = 0; i < MAXPLAYERS; i++)
{
player_t *p;
angle_t back;
angle_t diff;
fixed_t distance;
SINT8 dir = -1;
if (!playeringame[i])
{
// Invalid player
continue;
}
p = &players[i];
if (p == glancePlayer)
{
// FOOL! Don't glance at yerself!
continue;
}
if (!p->mo || P_MobjWasRemoved(p->mo))
{
// Invalid mobj
continue;
}
if (p->spectator || p->kartstuff[k_hyudorotimer] > 0)
{
// Not playing / invisible
continue;
}
distance = R_PointToDist2(glancePlayer->mo->x, glancePlayer->mo->y, p->mo->x, p->mo->y);
if (distance > maxdistance)
{
continue;
}
back = glancePlayer->mo->angle + ANGLE_180;
diff = R_PointToAngle2(glancePlayer->mo->x, glancePlayer->mo->y, p->mo->x, p->mo->y) - back;
if (diff > ANGLE_180)
{
diff = InvAngle(diff);
dir = -dir;
}
if (diff > ANGLE_90)
{
// Not behind the player
continue;
}
if (diff < blindSpotSize)
{
// Small blindspot directly behind your back, gives the impression of smoothly turning.
continue;
}
if (P_CheckSight(glancePlayer->mo, p->mo) == true)
{
// Not blocked by a wall, we can glance at 'em!
// Adds, so that if there's more targets on one of your sides, it'll glance on that side.
glanceDir += dir;
// That poses a limitation if there's an equal number of targets on both sides...
// In that case, we'll pick the last chosen glance direction.
lastValidGlance = dir;
}
}
if (glanceDir > 0)
{
return 1;
}
else if (glanceDir < 0)
{
return -1;
}
return lastValidGlance;
}
/** \brief Handles the state changing for moving players, moved here to eliminate duplicate code
\param player player data
@ -1735,7 +1839,6 @@ void K_SpawnDriftBoostClipSpark(mobj_t *clip)
void K_KartMoveAnimation(player_t *player)
{
const INT16 minturn = KART_FULLTURN/8;
SINT8 turndir = 0;
const fixed_t fastspeed = (K_GetKartSpeed(player, false) * 17) / 20; // 85%
const fixed_t speedthreshold = player->mo->scale / 8;
@ -1743,7 +1846,12 @@ void K_KartMoveAnimation(player_t *player)
const boolean onground = P_IsObjectOnGround(player->mo);
ticcmd_t *cmd = &player->cmd;
const boolean spinningwheels = ((cmd->buttons & BT_ACCELERATE) || (onground && player->speed > 0));
const boolean spinningwheels = (((cmd->buttons & BT_ACCELERATE) == BT_ACCELERATE) || (onground && player->speed > 0));
const boolean lookback = ((cmd->buttons & BT_LOOKBACK) == BT_LOOKBACK);
SINT8 turndir = 0;
SINT8 destGlanceDir = 0;
SINT8 drift = player->kartstuff[k_drift];
if (cmd->turning < -minturn)
{
@ -1754,20 +1862,89 @@ void K_KartMoveAnimation(player_t *player)
turndir = 1;
}
if (lookback == true && drift == 0)
{
// Prioritize looking back frames over turning
turndir = 0;
}
if (turndir == 0 && drift == 0)
{
// Only try glancing if you're driving straight.
// This avoids all-players loops when we don't need it.
destGlanceDir = K_GlanceAtPlayers(player);
if (lookback == true)
{
if (destGlanceDir == 0)
{
if (player->glanceDir != 0)
{
// Keep to the side you were already on.
if (player->glanceDir < 0)
{
destGlanceDir = -1;
}
else
{
destGlanceDir = 1;
}
}
else
{
// Look to your right by default
destGlanceDir = -1;
}
}
else
{
// Looking back AND glancing? Amplify the look!
destGlanceDir *= 2;
}
}
else if (K_GetForwardMove(player) < 0 && destGlanceDir == 0)
{
// Reversing -- like looking back, but doesn't stack on the other glances.
if (player->glanceDir != 0)
{
// Keep to the side you were already on.
if (player->glanceDir < 0)
{
destGlanceDir = -1;
}
else
{
destGlanceDir = 1;
}
}
else
{
// Look to your right by default
destGlanceDir = -1;
}
}
}
else
{
// Not glancing
destGlanceDir = 0;
player->glanceDir = 0;
}
#define SetState(sn) \
if (player->mo->state != &states[sn]) \
P_SetPlayerMobjState(player->mo, sn)
if (!onground)
if (onground == false)
{
// Only use certain frames in the air, to make it look like your tires are spinning fruitlessly!
if (player->kartstuff[k_drift] > 0)
if (drift > 0)
{
// Neutral drift
SetState(S_KART_DRIFT_L);
}
else if (player->kartstuff[k_drift] > 0)
else if (drift < 0)
{
// Neutral drift
SetState(S_KART_DRIFT_R);
@ -1782,22 +1959,41 @@ void K_KartMoveAnimation(player_t *player)
{
SetState(S_KART_FAST_L);
}
else if (turndir == 0)
else
{
SetState(S_KART_FAST);
switch (player->glanceDir)
{
case -2:
SetState(S_KART_FAST_LOOK_R);
break;
case 2:
SetState(S_KART_FAST_LOOK_L);
break;
case -1:
SetState(S_KART_FAST_GLANCE_R);
break;
case 1:
SetState(S_KART_FAST_GLANCE_L);
break;
default:
SetState(S_KART_FAST);
break;
}
}
}
if (!spinningwheels)
{
// TODO: These should prooobably be different SPR2s
// Just a quick hack to prevent needing to do that :V
// TODO: The "tires still in the air" states should have it's own SPR2s.
// This was a quick hack to get the same functionality with less work,
// but it's really dunderheaded & isn't customizable at all.
player->mo->frame = (player->mo->frame & ~FF_FRAMEMASK);
player->mo->tics++; // Makes it properly use frame 0
}
}
else
{
if (player->kartstuff[k_drift] > 0)
if (drift > 0)
{
// Drifting LEFT!
@ -1817,7 +2013,7 @@ void K_KartMoveAnimation(player_t *player)
SetState(S_KART_DRIFT_L);
}
}
else if (player->kartstuff[k_drift] < 0)
else if (drift < 0)
{
// Drifting RIGHT!
@ -1853,7 +2049,24 @@ void K_KartMoveAnimation(player_t *player)
}
else
{
SetState(S_KART_FAST);
switch (player->glanceDir)
{
case -2:
SetState(S_KART_FAST_LOOK_R);
break;
case 2:
SetState(S_KART_FAST_LOOK_L);
break;
case -1:
SetState(S_KART_FAST_GLANCE_R);
break;
case 1:
SetState(S_KART_FAST_GLANCE_L);
break;
default:
SetState(S_KART_FAST);
break;
}
}
}
else
@ -1872,7 +2085,24 @@ void K_KartMoveAnimation(player_t *player)
}
else
{
SetState(S_KART_SLOW);
switch (player->glanceDir)
{
case -2:
SetState(S_KART_SLOW_LOOK_R);
break;
case 2:
SetState(S_KART_SLOW_LOOK_L);
break;
case -1:
SetState(S_KART_SLOW_GLANCE_R);
break;
case 1:
SetState(S_KART_SLOW_GLANCE_L);
break;
default:
SetState(S_KART_SLOW);
break;
}
}
}
else
@ -1889,7 +2119,24 @@ void K_KartMoveAnimation(player_t *player)
}
else
{
SetState(S_KART_STILL);
switch (player->glanceDir)
{
case -2:
SetState(S_KART_STILL_LOOK_R);
break;
case 2:
SetState(S_KART_STILL_LOOK_L);
break;
case -1:
SetState(S_KART_STILL_GLANCE_R);
break;
case 1:
SetState(S_KART_STILL_GLANCE_L);
break;
default:
SetState(S_KART_STILL);
break;
}
}
}
}
@ -1898,6 +2145,16 @@ void K_KartMoveAnimation(player_t *player)
#undef SetState
// Update your glance value to smooth it out.
if (player->glanceDir > destGlanceDir)
{
player->glanceDir--;
}
else if (player->glanceDir < destGlanceDir)
{
player->glanceDir++;
}
// Update lastspeed value -- we use to display slow driving frames instead of fast driving when slowing down.
player->lastspeed = player->speed;
}

View file

@ -122,9 +122,9 @@ void K_DoIngameRespawn(player_t *player)
// If player was tumbling, set variables so that they don't tumble like crazy after they're done respawning
if (player->tumbleBounces > 0)
{
player->tumbleBounces = TUMBLEBOUNCES-1; // Max # of bounces-1 (so you still tumble once)
player->tumbleBounces = TUMBLEBOUNCES-1; // Max # of bounces-1 (so you still tumble once)
player->tumbleLastBounce = false; // Still force them to bounce at least once for the funny
players->tumbleHeight = 20; // force tumble height
players->tumbleHeight = 20; // force tumble height
}
P_ResetPlayer(player);

View file

@ -226,6 +226,8 @@ static int player_get(lua_State *L)
lua_pushboolean(L, plr->tumbleLastBounce);
else if (fastcmp(field,"tumbleSound"))
lua_pushboolean(L, plr->tumbleSound);
else if (fastcmp(field,"glanceDir"))
lua_pushinteger(L, plr->glanceDir);
else if (fastcmp(field,"trickpanel"))
lua_pushinteger(L, plr->trickpanel);
else if (fastcmp(field,"trickdelay"))
@ -535,6 +537,8 @@ static int player_set(lua_State *L)
plr->tumbleLastBounce = luaL_checkboolean(L, 3);
else if (fastcmp(field,"tumbleSound"))
plr->tumbleSound = luaL_checkboolean(L, 3);
else if (fastcmp(field,"glanceDir"))
plr->glanceDir = (SINT8)luaL_checkinteger(L, 3);
else if (fastcmp(field,"trickpanel"))
plr->trickpanel = luaL_checkinteger(L, 3);
else if (fastcmp(field,"trickdelay"))

View file

@ -1371,13 +1371,47 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
case MT_PLAYER:
{
angle_t flingAngle;
mobj_t *kart;
target->fuse = TICRATE*3; // timer before mobj disappears from view (even if not an actual player)
target->momx = target->momy = target->momz = 0;
if (target->player && target->player->pflags & PF_GAMETYPEOVER)
break;
kart = P_SpawnMobjFromMobj(target, 0, 0, 0, MT_KART_LEFTOVER);
if (kart && !P_MobjWasRemoved(kart))
{
kart->angle = target->angle;
kart->color = target->color;
kart->hitlag = target->hitlag;
P_SetObjectMomZ(kart, 6*FRACUNIT, false);
kart->extravalue1 = target->player->kartweight;
}
if (source && !P_MobjWasRemoved(source))
{
flingAngle = R_PointToAngle2(
source->x - source->momx, source->y - source->momy,
target->x, target->y
);
}
else
{
flingAngle = target->angle + ANGLE_180;
if (P_RandomByte() & 1)
{
flingAngle -= ANGLE_45;
}
else
{
flingAngle += ANGLE_45;
}
}
P_InstaThrust(target, flingAngle, 14 * target->scale);
P_SetObjectMomZ(target, 14*FRACUNIT, false);
P_PlayDeathSound(target);
}
break;

View file

@ -1399,6 +1399,21 @@ static boolean PIT_CheckThing(mobj_t *thing)
return false;
}
else if (thing->type == MT_KART_LEFTOVER)
{
// see if it went over / under
if (tmthing->z > thing->z + thing->height)
return true; // overhead
if (tmthing->z + tmthing->height < thing->z)
return true; // underneath
if (P_IsObjectOnGround(thing) && tmthing->momz < 0)
K_KartBouncing(tmthing, thing, true, false);
else
K_KartBouncing(tmthing, thing, false, false);
return false;
}
else if (thing->flags & MF_SOLID)
{
// see if it went over / under

View file

@ -221,17 +221,29 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state)
case S_KART_STILL:
case S_KART_STILL_L:
case S_KART_STILL_R:
player->panim = PA_IDLE;
case S_KART_STILL_GLANCE_L:
case S_KART_STILL_GLANCE_R:
case S_KART_STILL_LOOK_L:
case S_KART_STILL_LOOK_R:
player->panim = PA_STILL;
break;
case S_KART_SLOW:
case S_KART_SLOW_L:
case S_KART_SLOW_R:
player->panim = PA_WALK;
case S_KART_SLOW_GLANCE_L:
case S_KART_SLOW_GLANCE_R:
case S_KART_SLOW_LOOK_L:
case S_KART_SLOW_LOOK_R:
player->panim = PA_SLOW;
break;
case S_KART_FAST:
case S_KART_FAST_L:
case S_KART_FAST_R:
player->panim = PA_RUN;
case S_KART_FAST_GLANCE_L:
case S_KART_FAST_GLANCE_R:
case S_KART_FAST_LOOK_L:
case S_KART_FAST_LOOK_R:
player->panim = PA_FAST;
break;
case S_KART_DRIFT_L:
case S_KART_DRIFT_L_OUT:
@ -239,11 +251,11 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state)
case S_KART_DRIFT_R:
case S_KART_DRIFT_R_OUT:
case S_KART_DRIFT_R_IN:
player->panim = PA_DASH;
player->panim = PA_DRIFT;
break;
case S_KART_SPINOUT:
case S_KART_SQUISH:
player->panim = PA_PAIN;
case S_KART_DEAD:
player->panim = PA_HURT;
break;
default:
player->panim = PA_ETC;
@ -1300,7 +1312,7 @@ static void P_XYFriction(mobj_t *mo, fixed_t oldx, fixed_t oldy)
&& !(player->mo->standingslope && (!(player->mo->standingslope->flags & SL_NOPHYSICS)) /*&& (abs(player->mo->standingslope->zdelta) >= FRACUNIT/2)*/))
{
// if in a walking frame, stop moving
if (player->panim == PA_WALK)
if (player->panim == PA_SLOW)
{
P_SetPlayerMobjState(mo, S_KART_STILL);
}
@ -2334,6 +2346,68 @@ boolean P_ZMovement(mobj_t *mo)
if (mo->flags2 & MF2_SKULLFLY) // the skull slammed into something
mom.z = -mom.z;
else if (mo->type == MT_KART_LEFTOVER)
{
if (mo->health > 1)
{
const fixed_t tireOffset = 32;
const angle_t aOffset = ANGLE_22h;
UINT8 i;
angle_t tireAngle;
mobj_t *tire;
// Spawn tires!
mo->health = 1;
P_SetMobjState(mo, S_KART_LEFTOVER_NOTIRES);
// Front tires
tireAngle = mo->angle - aOffset;
for (i = 0; i < 2; i++)
{
tire = P_SpawnMobjFromMobj(
mo,
tireOffset * FINECOSINE(tireAngle >> ANGLETOFINESHIFT),
tireOffset * FINESINE(tireAngle >> ANGLETOFINESHIFT),
0,
MT_KART_TIRE
);
tire->angle = mo->angle;
tire->fuse = 3*TICRATE;
P_InstaThrust(tire, tireAngle, 4 * mo->scale);
P_SetObjectMomZ(tire, 4*FRACUNIT, false);
tireAngle += (aOffset * 2);
}
// Back tires
tireAngle = (mo->angle + ANGLE_180) - aOffset;
for (i = 0; i < 2; i++)
{
tire = P_SpawnMobjFromMobj(
mo,
tireOffset * FINECOSINE(tireAngle >> ANGLETOFINESHIFT),
tireOffset * FINESINE(tireAngle >> ANGLETOFINESHIFT),
0,
MT_KART_TIRE
);
tire->angle = mo->angle;
tire->fuse = 3*TICRATE;
P_InstaThrust(tire, tireAngle, 4 * mo->scale);
P_SetObjectMomZ(tire, 4*FRACUNIT, false);
P_SetMobjState(tire, S_KART_TIRE2);
tireAngle += (aOffset * 2);
}
}
}
else if (mo->type == MT_KART_TIRE)
{
mom.z = -mom.z;
}
else if (mo->type == MT_BIGTUMBLEWEED
|| mo->type == MT_LITTLETUMBLEWEED
|| mo->type == MT_CANNONBALLDECOR
@ -2633,7 +2707,7 @@ void P_PlayerZMovement(mobj_t *mo)
mo->z = mo->floorz;
// Get up if you fell.
if (mo->player->panim == PA_PAIN && mo->player->kartstuff[k_spinouttimer] == 0 && mo->player->tumbleBounces == 0)
if (mo->player->panim == PA_HURT && mo->player->kartstuff[k_spinouttimer] == 0 && mo->player->tumbleBounces == 0)
P_SetPlayerMobjState(mo, S_KART_STILL);
if (!mo->standingslope && (mo->eflags & MFE_VERTICALFLIP ? tmceilingslope : tmfloorslope)) {
@ -5867,8 +5941,11 @@ static boolean P_MobjDeadThink(mobj_t *mobj)
{ // Go away.
/// \todo Actually go ahead and remove mobj completely, and fix any bugs and crashes doing this creates. Chasecam should stop moving, and F12 should never return to it.
mobj->momz = 0;
if (mobj->player)
{
mobj->drawflags |= MFD_DONTDRAW;
}
else // safe to remove, nobody's going to complain!
{
P_RemoveMobj(mobj);
@ -5877,16 +5954,6 @@ static boolean P_MobjDeadThink(mobj_t *mobj)
}
else // Apply gravity to fall downwards.
{
if (mobj->player && !(mobj->fuse % 8) && (mobj->player->charflags & SF_MACHINE))
{
fixed_t r = mobj->radius >> FRACBITS;
mobj_t *explosion = P_SpawnMobj(
mobj->x + (P_RandomRange(r, -r) << FRACBITS),
mobj->y + (P_RandomRange(r, -r) << FRACBITS),
mobj->z + (P_RandomKey(mobj->height >> FRACBITS) << FRACBITS),
MT_SONIC3KBOSSEXPLODE);
S_StartSound(explosion, sfx_s3kb4);
}
P_SetObjectMomZ(mobj, -2*FRACUNIT/3, true);
}
break;
@ -9079,6 +9146,7 @@ static void P_DefaultMobjShadowScale(mobj_t *thing)
switch (thing->type)
{
case MT_PLAYER:
case MT_KART_LEFTOVER:
case MT_SMALLMACE:
case MT_BIGMACE:
case MT_PUMA:
@ -9371,6 +9439,19 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
mobj->color = (P_RandomChance(FRACUNIT/2) ? SKINCOLOR_RED : SKINCOLOR_AQUAMARINE);
break;
case MT_BALLOON:
{
static const UINT8 BALLOONCOLORS[] = {
// Carnival Night balloon colors
SKINCOLOR_KETCHUP,
SKINCOLOR_SAPPHIRE,
SKINCOLOR_TANGERINE,
SKINCOLOR_JET
};
mobj->color = BALLOONCOLORS[P_RandomKey(sizeof(BALLOONCOLORS))];
}
break;
case MT_KART_LEFTOVER:
mobj->color = SKINCOLOR_RED;
break;
case MT_EGGROBO1:

View file

@ -271,6 +271,8 @@ static void P_NetArchivePlayers(void)
WRITEUINT8(save_p, players[i].tumbleLastBounce);
WRITEUINT8(save_p, players[i].tumbleSound);
WRITESINT8(save_p, players[i].glanceDir);
// respawnvars_t
WRITEUINT8(save_p, players[i].respawn.state);
WRITEUINT32(save_p, K_GetWaypointHeapIndex(players[i].respawn.wp));
@ -471,6 +473,8 @@ static void P_NetUnArchivePlayers(void)
players[i].tumbleLastBounce = (boolean)READUINT8(save_p);
players[i].tumbleSound = (boolean)READUINT8(save_p);
players[i].glanceDir = READSINT8(save_p);
// respawnvars_t
players[i].respawn.state = READUINT8(save_p);
players[i].respawn.wp = (waypoint_t *)(size_t)READUINT32(save_p);

View file

@ -3075,7 +3075,7 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
mo = player->mo;
if (mo->hitlag > 0)
if (mo->hitlag > 0 || player->playerstate == PST_DEAD)
{
// Do not move the camera while in hitlag!
// The camera zooming out after you got hit makes it hard to focus on the vibration.