* Rudimentary (set everything every state or DIE) support for ghost followmobjs.

* Rename GZT_SPRITE to GZT_FRAME, since otherwise it's easy to confuse with EZT_SPRITE (which does something completely different).
* Fix issue where ghosts were facing wrong direction on spawn.
* Other minor refactorings.

* ...also, made smiles' tails pop up instead of down when skidding
This commit is contained in:
toasterbabe 2017-10-14 17:50:14 +01:00
parent 31dff22202
commit 1ba9d1fe6e
2 changed files with 116 additions and 38 deletions

View File

@ -3978,10 +3978,10 @@ static ticcmd_t oldcmd;
#define GZT_MOMZ 0x04
#define GZT_ANGLE 0x08
// Not used for Metal Sonic
#define GZT_SPRITE 0x10 // Animation frame
#define GZT_FRAME 0x10 // Animation frame
#define GZT_SPR2 0x20 // Player animations
// spare GZT slot 0x40
#define GZT_EXTRA 0x80
#define GZT_EXTRA 0x40
#define GZT_FOLLOW 0x80 // Followmobj
// GZT_EXTRA flags
#define EZT_THOK 0x01 // Spawned a thok object
@ -3993,6 +3993,7 @@ static ticcmd_t oldcmd;
#define EZT_SCALE 0x10 // Changed size
#define EZT_HIT 0x20 // Damaged a mobj
#define EZT_SPRITE 0x40 // Changed sprite set completely out of PLAY (NiGHTS, SOCs, whatever)
// spare EZT slot 0x80
static mobj_t oldmetal, oldghost;
@ -4252,10 +4253,10 @@ void G_WriteGhostTic(mobj_t *ghost)
}
// Store the sprite frame.
if ((ghost->frame & 0xFF) != oldghost.frame)
if ((ghost->frame & FF_FRAMEMASK) != oldghost.frame)
{
oldghost.frame = (ghost->frame & 0xFF);
ziptic |= GZT_SPRITE;
oldghost.frame = (ghost->frame & FF_FRAMEMASK);
ziptic |= GZT_FRAME;
WRITEUINT8(demo_p,oldghost.frame);
}
@ -4300,7 +4301,7 @@ void G_WriteGhostTic(mobj_t *ghost)
for (i = 0; i < ghostext.hits; i++)
{
mobj_t *mo = ghostext.hitlist[i];
WRITEUINT32(demo_p,UINT32_MAX); // reserved for some method of determining exactly which mobj this is. (mobjnum doesn't work here.)
//WRITEUINT32(demo_p,UINT32_MAX); // reserved for some method of determining exactly which mobj this is. (mobjnum doesn't work here.)
WRITEUINT32(demo_p,mo->type);
WRITEUINT16(demo_p,(UINT16)mo->health);
WRITEFIXED(demo_p,mo->x);
@ -4317,11 +4318,28 @@ void G_WriteGhostTic(mobj_t *ghost)
ghostext.flags = 0;
}
if (ghost->player && ghost->player->followmobj)
{
INT16 temp;
ziptic |= GZT_FOLLOW;
temp = (INT16)((ghost->player->followmobj->x-ghost->x)>>8);
WRITEINT16(demo_p,temp);
temp = (INT16)((ghost->player->followmobj->y-ghost->y)>>8);
WRITEINT16(demo_p,temp);
temp = (INT16)((ghost->player->followmobj->z-ghost->z)>>8);
WRITEINT16(demo_p,temp);
WRITEUINT8(demo_p,ghost->player->followmobj->sprite);
WRITEUINT8(demo_p,ghost->player->followmobj->sprite2);
WRITEUINT8(demo_p,(ghost->player->followmobj->frame & FF_FRAMEMASK));
}
*ziptic_p = ziptic;
// attention here for the ticcmd size!
// latest demos with mouse aiming byte in ticcmd
if (demo_p >= demoend - (13 + 9))
if (demo_p >= demoend - (13 + 9 + 9))
{
G_CheckDemoStatus(); // no more space
return;
@ -4366,19 +4384,19 @@ void G_ConsGhostTic(void)
}
if (ziptic & GZT_ANGLE)
demo_p++;
if (ziptic & GZT_SPRITE)
if (ziptic & GZT_FRAME)
demo_p++;
if (ziptic & GZT_SPR2)
demo_p++;
if (ziptic & GZT_EXTRA)
{ // But wait, there's more!
ziptic = READUINT8(demo_p);
if (ziptic & EZT_COLOR)
UINT8 xziptic = READUINT8(demo_p);
if (xziptic & EZT_COLOR)
demo_p++;
if (ziptic & EZT_SCALE)
if (xziptic & EZT_SCALE)
demo_p += sizeof(fixed_t);
if (ziptic & EZT_HIT)
if (xziptic & EZT_HIT)
{ // Resync mob damage.
UINT16 i, count = READUINT16(demo_p);
thinker_t *th;
@ -4392,7 +4410,7 @@ void G_ConsGhostTic(void)
for (i = 0; i < count; i++)
{
demo_p += 4; // reserved.
//demo_p += 4; // reserved.
type = READUINT32(demo_p);
health = READUINT16(demo_p);
x = READFIXED(demo_p);
@ -4419,10 +4437,20 @@ void G_ConsGhostTic(void)
}
}
}
if (ziptic & EZT_SPRITE)
if (xziptic & EZT_SPRITE)
demo_p++;
}
if (ziptic & GZT_FOLLOW)
{ // Even more...
demo_p += sizeof(INT16);
demo_p += sizeof(INT16);
demo_p += sizeof(INT16);
demo_p++;
demo_p++;
demo_p++;
}
// Re-synchronise
px = testmo->x>>FRACBITS;
py = testmo->y>>FRACBITS;
@ -4459,6 +4487,7 @@ void G_GhostTicker(void)
{
// Skip normal demo data.
UINT8 ziptic = READUINT8(g->p);
UINT8 xziptic = 0;
if (ziptic & ZT_FWD)
g->p++;
if (ziptic & ZT_SIDE)
@ -4492,8 +4521,8 @@ void G_GhostTicker(void)
g->oldmo.z += g->oldmo.momz;
}
if (ziptic & GZT_ANGLE)
g->oldmo.angle = READUINT8(g->p)<<24;
if (ziptic & GZT_SPRITE)
g->mo->angle = READUINT8(g->p)<<24;
if (ziptic & GZT_FRAME)
g->oldmo.frame = READUINT8(g->p);
if (ziptic & GZT_SPR2)
g->oldmo.sprite2 = READUINT8(g->p);
@ -4504,14 +4533,13 @@ void G_GhostTicker(void)
g->mo->y = g->oldmo.y;
g->mo->z = g->oldmo.z;
P_SetThingPosition(g->mo);
g->mo->angle = g->oldmo.angle;
g->mo->frame = g->oldmo.frame | tr_trans30<<FF_TRANSSHIFT;
g->mo->sprite2 = g->oldmo.sprite2;
if (ziptic & GZT_EXTRA)
{ // But wait, there's more!
ziptic = READUINT8(g->p);
if (ziptic & EZT_COLOR)
xziptic = READUINT8(g->p);
if (xziptic & EZT_COLOR)
{
g->color = READUINT8(g->p);
switch(g->color)
@ -4529,22 +4557,22 @@ void G_GhostTicker(void)
break;
}
}
if (ziptic & EZT_FLIP)
if (xziptic & EZT_FLIP)
g->mo->eflags ^= MFE_VERTICALFLIP;
if (ziptic & EZT_SCALE)
if (xziptic & EZT_SCALE)
{
g->mo->destscale = READFIXED(g->p);
if (g->mo->destscale != g->mo->scale)
P_SetScale(g->mo, g->mo->destscale);
}
if (ziptic & EZT_THOKMASK)
if (xziptic & EZT_THOKMASK)
{ // Let's only spawn ONE of these per frame, thanks.
mobj_t *mobj;
INT32 type = -1;
if (g->mo->skin)
{
skin_t *skin = (skin_t *)g->mo->skin;
switch (ziptic & EZT_THOKMASK)
switch (xziptic & EZT_THOKMASK)
{
case EZT_THOK:
type = skin->thokitem < 0 ? (UINT32)mobjinfo[MT_PLAYER].painchance : (UINT32)skin->thokitem;
@ -4585,7 +4613,7 @@ void G_GhostTicker(void)
mobj->fuse = 8;
P_SetTarget(&mobj->target, g->mo);
}
if (ziptic & EZT_HIT)
if (xziptic & EZT_HIT)
{ // Spawn hit poofs for killing things!
UINT16 i, count = READUINT16(g->p), health;
UINT32 type;
@ -4594,7 +4622,7 @@ void G_GhostTicker(void)
mobj_t *poof;
for (i = 0; i < count; i++)
{
g->p += 4; // reserved
//g->p += 4; // reserved
type = READUINT32(g->p);
health = READUINT16(g->p);
x = READFIXED(g->p);
@ -4612,7 +4640,7 @@ void G_GhostTicker(void)
P_SetMobjStateNF(poof, S_XPLD1);
}
}
if (ziptic & EZT_SPRITE)
if (xziptic & EZT_SPRITE)
g->mo->sprite = READUINT8(g->p);
}
@ -4636,6 +4664,54 @@ void G_GhostTicker(void)
break;
}
#define follow g->mo->tracer
if (ziptic & GZT_FOLLOW)
{ // Even more...
if (!follow)
{
mobj_t *newmo = P_SpawnMobj(g->mo->x, g->mo->y, g->mo->z, MT_GHOST);
P_SetTarget(&g->mo->tracer, newmo);
P_SetTarget(&newmo->tracer, g->mo);
newmo->skin = g->mo->skin;
newmo->tics = -1;
newmo->flags2 |= MF2_LINKDRAW;
follow->eflags = (follow->eflags & ~MFE_VERTICALFLIP)|(g->mo->eflags & MFE_VERTICALFLIP);
follow->destscale = g->mo->destscale;
if (follow->destscale != follow->scale)
P_SetScale(follow, follow->destscale);
}
else
{
if (xziptic & EZT_FLIP)
g->mo->eflags ^= MFE_VERTICALFLIP;
if (xziptic & EZT_SCALE)
{
follow->destscale = g->mo->destscale;
if (follow->destscale != follow->scale)
P_SetScale(follow, follow->destscale);
}
}
P_UnsetThingPosition(follow);
follow->x = g->mo->x + (READINT16(g->p)<<8);
follow->y = g->mo->y + (READINT16(g->p)<<8);
follow->z = g->mo->z + (READINT16(g->p)<<8);
P_SetThingPosition(follow);
follow->sprite = READUINT8(g->p);
follow->sprite2 = READUINT8(g->p);
follow->frame = (READUINT8(g->p)) | tr_trans30<<FF_TRANSSHIFT;
follow->angle = g->mo->angle;
follow->color = g->mo->color;
}
else if (follow)
{
P_RemoveMobj(follow);
P_SetTarget(&follow, NULL);
}
#undef follow
// Demo ends after ghost data.
if (*g->p == DEMOMARKER)
{
@ -4682,8 +4758,8 @@ void G_ReadMetalTic(mobj_t *metal)
oldmetal.z += oldmetal.momz;
}
if (ziptic & GZT_ANGLE)
oldmetal.angle = READUINT8(metal_p)<<24;
if (ziptic & GZT_SPRITE)
metal->angle = READUINT8(metal_p)<<24;
if (ziptic & GZT_FRAME)
metal_p++; // Currently unused. (Metal Sonic figures out what he's doing his own damn self.)
if (ziptic & GZT_SPR2)
metal_p++;
@ -4698,7 +4774,6 @@ void G_ReadMetalTic(mobj_t *metal)
metal->y = oldmetal.y;
metal->z = oldmetal.z;
P_SetThingPosition(metal);
metal->angle = oldmetal.angle;
if (ziptic & GZT_EXTRA)
{ // But wait, there's more!
@ -5668,10 +5743,6 @@ void G_AddGhost(char *defdemoname)
gh->mo = P_SpawnMobj(x, y, z, MT_GHOST);
gh->mo->angle = FixedAngle(mthing->angle*FRACUNIT);
}
gh->mo->state = states+S_PLAY_STND;
gh->mo->sprite = gh->mo->state->sprite;
gh->mo->frame = (gh->mo->state->frame & FF_FRAMEMASK) | tr_trans20<<FF_TRANSSHIFT;
gh->mo->tics = -1;
gh->oldmo.x = gh->mo->x;
gh->oldmo.y = gh->mo->y;
@ -5697,6 +5768,12 @@ void G_AddGhost(char *defdemoname)
}
gh->oldmo.color = gh->mo->color;
gh->mo->state = states+S_PLAY_STND;
gh->mo->sprite = gh->mo->state->sprite;
gh->mo->sprite2 = (gh->mo->state->frame & FF_FRAMEMASK);
gh->mo->frame = tr_trans20<<FF_TRANSSHIFT;
gh->mo->tics = -1;
CONS_Printf(M_GetText("Added ghost %s from %s\n"), name, pdemoname);
Z_Free(pdemoname);
}
@ -5743,8 +5820,10 @@ void G_DoPlayMetal(void)
continue;
mo = (mobj_t *)th;
if (mo->type == MT_METALSONIC_RACE)
break;
if (mo->type != MT_METALSONIC_RACE)
continue;
break;
}
if (!mo)
{
@ -5781,7 +5860,6 @@ void G_DoPlayMetal(void)
oldmetal.x = mo->x;
oldmetal.y = mo->y;
oldmetal.z = mo->z;
oldmetal.angle = mo->angle;
metalplayback = mo;
}

View File

@ -10612,7 +10612,7 @@ void P_PlayerAfterThink(player_t *player)
chosenstate = S_TAILSOVERLAY_RUN;
else if (player->panim == PA_WALK)
{
if (!smilesonground)
if (!smilesonground || player->mo->state-states == S_PLAY_SKID)
chosenstate = S_TAILSOVERLAY_PLUS30DEGREES;
else if (player->speed >= FixedMul(player->runspeed/2, player->mo->scale))
chosenstate = S_TAILSOVERLAY_0DEGREES;