mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2026-04-28 04:51:42 +00:00
Ring Shooter: countdown animation & experimental stretchy spawn
This commit is contained in:
parent
c98ff9616b
commit
a458490639
3 changed files with 177 additions and 16 deletions
|
|
@ -4472,8 +4472,8 @@ state_t states[NUMSTATES] =
|
||||||
{SPR_RSHT, FF_PAPERSPRITE|0, -1, {NULL}, 0, 0, S_NULL}, // S_RINGSHOOTER_SIDE
|
{SPR_RSHT, FF_PAPERSPRITE|0, -1, {NULL}, 0, 0, S_NULL}, // S_RINGSHOOTER_SIDE
|
||||||
{SPR_RSHT, FF_SEMIBRIGHT|FF_PAPERSPRITE|2, -1, {NULL}, 0, 0, S_NULL}, // S_RINGSHOOTER_NIPPLES
|
{SPR_RSHT, FF_SEMIBRIGHT|FF_PAPERSPRITE|2, -1, {NULL}, 0, 0, S_NULL}, // S_RINGSHOOTER_NIPPLES
|
||||||
{SPR_RSHT, FF_PAPERSPRITE|4, -1, {NULL}, 0, 0, S_NULL}, // S_RINGSHOOTER_SCREEN
|
{SPR_RSHT, FF_PAPERSPRITE|4, -1, {NULL}, 0, 0, S_NULL}, // S_RINGSHOOTER_SCREEN
|
||||||
{SPR_RSHT, FF_FULLBRIGHT|FF_PAPERSPRITE|8, -1, {NULL}, 0, 0, S_NULL}, // S_RINGSHOOTER_NUMBERBACK
|
{SPR_RSHT, FF_FULLBRIGHT|FF_PAPERSPRITE|5, -1, {NULL}, 0, 0, S_NULL}, // S_RINGSHOOTER_NUMBERBACK
|
||||||
{SPR_RSHT, FF_FULLBRIGHT|FF_PAPERSPRITE|12, -1, {NULL}, 0, 0, S_NULL}, // S_RINGSHOOTER_NUMBERFRONT
|
{SPR_RSHT, FF_FULLBRIGHT|FF_PAPERSPRITE|9, -1, {NULL}, 0, 0, S_NULL}, // S_RINGSHOOTER_NUMBERFRONT
|
||||||
{SPR_PLAY, FF_FULLBRIGHT|FF_PAPERSPRITE|SPR2_XTRA, -1, {A_RingShooterFace}, 0, 0, S_NULL}, // S_RINGSHOOTER_FACE
|
{SPR_PLAY, FF_FULLBRIGHT|FF_PAPERSPRITE|SPR2_XTRA, -1, {A_RingShooterFace}, 0, 0, S_NULL}, // S_RINGSHOOTER_FACE
|
||||||
|
|
||||||
{SPR_DEZL, FF_FULLBRIGHT|FF_PAPERSPRITE, 8, {NULL}, 0, 0, S_NULL}, // S_DEZLASER
|
{SPR_DEZL, FF_FULLBRIGHT|FF_PAPERSPRITE, 8, {NULL}, 0, 0, S_NULL}, // S_DEZLASER
|
||||||
|
|
@ -24672,12 +24672,12 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
||||||
sfx_None, // attacksound
|
sfx_None, // attacksound
|
||||||
S_NULL, // painstate
|
S_NULL, // painstate
|
||||||
0, // painchance
|
0, // painchance
|
||||||
sfx_None, // painsound
|
sfx_s3ka7, // painsound
|
||||||
S_NULL, // meleestate
|
S_NULL, // meleestate
|
||||||
S_NULL, // missilestate
|
S_NULL, // missilestate
|
||||||
S_NULL, // deathstate
|
S_NULL, // deathstate
|
||||||
S_NULL, // xdeathstate
|
S_NULL, // xdeathstate
|
||||||
sfx_None, // deathsound
|
sfx_s3kad, // deathsound
|
||||||
0, // speed
|
0, // speed
|
||||||
16*FRACUNIT, // radius
|
16*FRACUNIT, // radius
|
||||||
16*FRACUNIT, // height
|
16*FRACUNIT, // height
|
||||||
|
|
|
||||||
33
src/k_kart.c
33
src/k_kart.c
|
|
@ -11775,13 +11775,15 @@ boolean K_Cooperative(void)
|
||||||
|
|
||||||
//}
|
//}
|
||||||
|
|
||||||
|
// I've tried to reduce redundancy as much as I can,
|
||||||
|
// but check P_UpdateRingShooterParts if you edit this
|
||||||
void K_SpawnRingShooter(player_t *player)
|
void K_SpawnRingShooter(player_t *player)
|
||||||
{
|
{
|
||||||
const fixed_t scale = 2*FRACUNIT;
|
const fixed_t scale = 2*FRACUNIT;
|
||||||
mobjinfo_t *info = &mobjinfo[MT_RINGSHOOTER_PART];
|
mobjinfo_t *info = &mobjinfo[MT_RINGSHOOTER_PART];
|
||||||
mobj_t *mo = player->mo;
|
mobj_t *mo = player->mo;
|
||||||
mobj_t *base = P_SpawnMobj(mo->x, mo->y, mo->z, MT_RINGSHOOTER);
|
mobj_t *base = P_SpawnMobj(mo->x, mo->y, mo->z, MT_RINGSHOOTER);
|
||||||
mobj_t *part;
|
mobj_t *part, *refNipple;
|
||||||
UINT32 frameNum;
|
UINT32 frameNum;
|
||||||
angle_t angle;
|
angle_t angle;
|
||||||
vector2_t offset;
|
vector2_t offset;
|
||||||
|
|
@ -11791,6 +11793,15 @@ void K_SpawnRingShooter(player_t *player)
|
||||||
P_SetTarget(&base->target, mo);
|
P_SetTarget(&base->target, mo);
|
||||||
P_SetScale(base, base->destscale = FixedMul(base->destscale, scale));
|
P_SetScale(base, base->destscale = FixedMul(base->destscale, scale));
|
||||||
P_InitAngle(base, mo->angle);
|
P_InitAngle(base, mo->angle);
|
||||||
|
base->scalespeed = FRACUNIT/2;
|
||||||
|
base->extravalue1 = FRACUNIT; // horizontal scale
|
||||||
|
base->extravalue2 = 0; // vertical scale
|
||||||
|
|
||||||
|
// the ring shooter object itself is invisible and acts as the thinker
|
||||||
|
// each ring shooter uses three linked lists to keep track of its parts
|
||||||
|
// the hprev chain stores the two NIPPLE BARS
|
||||||
|
// the hnext chain stores the four sides of the box
|
||||||
|
// the tracer chain stores the screen and the screen layers
|
||||||
|
|
||||||
// spawn the RING NIPPLES
|
// spawn the RING NIPPLES
|
||||||
part = base;
|
part = base;
|
||||||
|
|
@ -11810,8 +11821,11 @@ void K_SpawnRingShooter(player_t *player)
|
||||||
P_InitAngle(part, base->angle - i * ANGLE_45);
|
P_InitAngle(part, base->angle - i * ANGLE_45);
|
||||||
P_SetMobjState(part, S_RINGSHOOTER_NIPPLES);
|
P_SetMobjState(part, S_RINGSHOOTER_NIPPLES);
|
||||||
part->frame += frameNum;
|
part->frame += frameNum;
|
||||||
|
part->flags |= MF_NOTHINK;
|
||||||
|
part->old_spriteyscale = part->spriteyscale = 0;
|
||||||
frameNum++;
|
frameNum++;
|
||||||
}
|
}
|
||||||
|
refNipple = part; // keep the second ring nipple; its position will be referenced by the box
|
||||||
|
|
||||||
// spawn the box
|
// spawn the box
|
||||||
part = base;
|
part = base;
|
||||||
|
|
@ -11835,15 +11849,23 @@ void K_SpawnRingShooter(player_t *player)
|
||||||
frameNum++;
|
frameNum++;
|
||||||
frameNum ^= FF_HORIZONTALFLIP;
|
frameNum ^= FF_HORIZONTALFLIP;
|
||||||
angle -= ANGLE_90;
|
angle -= ANGLE_90;
|
||||||
part->frame += frameNum;
|
|
||||||
P_InitAngle(part, angle);
|
P_InitAngle(part, angle);
|
||||||
|
part->frame += frameNum;
|
||||||
|
part->extravalue1 = part->x - refNipple->x;
|
||||||
|
part->extravalue2 = part->y - refNipple->y;
|
||||||
|
part->flags |= MF_NOTHINK;
|
||||||
|
part->old_spriteyscale = part->spriteyscale = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// spawn the screen
|
// spawn the screen
|
||||||
part = P_SpawnMobjFromMobj(base, offset.x, offset.y, info->height, MT_RINGSHOOTER_SCREEN);
|
part = P_SpawnMobjFromMobj(base, offset.x, offset.y, 0, MT_RINGSHOOTER_SCREEN);
|
||||||
P_SetTarget(&base->tracer, part);
|
P_SetTarget(&base->tracer, part);
|
||||||
P_SetTarget(&part->target, base);
|
P_SetTarget(&part->target, base);
|
||||||
P_InitAngle(part, base->angle - ANGLE_45);
|
P_InitAngle(part, base->angle - ANGLE_45);
|
||||||
|
part->extravalue1 = part->x - refNipple->x;
|
||||||
|
part->extravalue2 = part->y - refNipple->y;
|
||||||
|
part->flags |= MF_NOTHINK;
|
||||||
|
part->old_spriteyscale = part->spriteyscale = 0;
|
||||||
|
|
||||||
// spawn the screen numbers
|
// spawn the screen numbers
|
||||||
for (i = 0; i < 2; i++)
|
for (i = 0; i < 2; i++)
|
||||||
|
|
@ -11853,9 +11875,6 @@ void K_SpawnRingShooter(player_t *player)
|
||||||
part = part->tracer;
|
part = part->tracer;
|
||||||
P_InitAngle(part, part->target->angle);
|
P_InitAngle(part, part->target->angle);
|
||||||
P_SetMobjState(part, S_RINGSHOOTER_NUMBERBACK + i);
|
P_SetMobjState(part, S_RINGSHOOTER_NUMBERBACK + i);
|
||||||
|
part->renderflags |= RF_DONTDRAW;
|
||||||
}
|
}
|
||||||
|
|
||||||
// test face feature (to be moved into thinker later)
|
|
||||||
part->skin = mo->skin;
|
|
||||||
P_SetMobjState(part, S_RINGSHOOTER_FACE);
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
152
src/p_mobj.c
152
src/p_mobj.c
|
|
@ -4550,17 +4550,150 @@ static void P_SpawnItemCapsuleParts(mobj_t *mobj)
|
||||||
#undef ANG_CAPSULE
|
#undef ANG_CAPSULE
|
||||||
#undef ROTATIONSPEED
|
#undef ROTATIONSPEED
|
||||||
|
|
||||||
static void P_RingShooterThinker(mobj_t *mo)
|
// ------------
|
||||||
|
// RING SHOOTER
|
||||||
|
// ------------
|
||||||
|
|
||||||
|
static void P_ActivateRingShooter(mobj_t *mo)
|
||||||
|
{
|
||||||
|
mobj_t *part = mo->tracer;
|
||||||
|
|
||||||
|
while (!P_MobjWasRemoved(part->tracer))
|
||||||
|
{
|
||||||
|
part = part->tracer;
|
||||||
|
part->renderflags &= ~RF_DONTDRAW;
|
||||||
|
part->frame += 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#define scaleSpeed mo->scalespeed
|
||||||
|
#define scaleState mo->threshold
|
||||||
|
#define xScale mo->extravalue1
|
||||||
|
#define yScale mo->extravalue2
|
||||||
|
#define xOffset part->extravalue1
|
||||||
|
#define yOffset part->extravalue2
|
||||||
|
#define SCALEPART part->spritexscale = xScale; part->spriteyscale = yScale;
|
||||||
|
#define MOVEPART P_MoveOrigin(part, refNipple->x + FixedMul(xOffset, xScale), refNipple->y + FixedMul(yOffset, xScale), part->z);
|
||||||
|
|
||||||
|
// I've tried to reduce redundancy as much as I can,
|
||||||
|
// but check K_SpawnRingShooter if you edit this
|
||||||
|
static void P_UpdateRingShooterParts(mobj_t *mo)
|
||||||
|
{
|
||||||
|
mobj_t *part, *refNipple;
|
||||||
|
|
||||||
|
part = mo;
|
||||||
|
while (!P_MobjWasRemoved(part->hprev))
|
||||||
|
{
|
||||||
|
part = part->hprev;
|
||||||
|
SCALEPART
|
||||||
|
}
|
||||||
|
refNipple = part;
|
||||||
|
|
||||||
|
part = mo;
|
||||||
|
while (!P_MobjWasRemoved(part->hnext))
|
||||||
|
{
|
||||||
|
part = part->hnext;
|
||||||
|
MOVEPART
|
||||||
|
SCALEPART
|
||||||
|
}
|
||||||
|
|
||||||
|
part = mo->tracer;
|
||||||
|
part->z = mo->z + FixedMul(refNipple->height, yScale);
|
||||||
|
MOVEPART
|
||||||
|
SCALEPART
|
||||||
|
}
|
||||||
|
|
||||||
|
static boolean P_RingShooterInit(mobj_t *mo)
|
||||||
|
{
|
||||||
|
if (scaleState == -1)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
switch (scaleState) {
|
||||||
|
case 0:
|
||||||
|
yScale += scaleSpeed;
|
||||||
|
if (yScale >= FRACUNIT)
|
||||||
|
{
|
||||||
|
//xScale -= scaleSpeed;
|
||||||
|
scaleState++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
scaleSpeed -= FRACUNIT/5;
|
||||||
|
yScale += scaleSpeed;
|
||||||
|
xScale -= scaleSpeed;
|
||||||
|
if (yScale < 3*FRACUNIT/4)
|
||||||
|
{
|
||||||
|
scaleState ++;
|
||||||
|
scaleSpeed = FRACUNIT >> 2;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
yScale += scaleSpeed;
|
||||||
|
xScale -= scaleSpeed;
|
||||||
|
if (yScale >= FRACUNIT)
|
||||||
|
{
|
||||||
|
scaleState = -1;
|
||||||
|
xScale = yScale = FRACUNIT;
|
||||||
|
P_ActivateRingShooter(mo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
P_UpdateRingShooterParts(mo);
|
||||||
|
return scaleState != -1;
|
||||||
|
}
|
||||||
|
#undef scaleSpeed
|
||||||
|
#undef scaleState
|
||||||
|
#undef xScale
|
||||||
|
#undef yScale
|
||||||
|
#undef xOffset
|
||||||
|
#undef yOffset
|
||||||
|
#undef MOVEPART
|
||||||
|
#undef SCALEPART
|
||||||
|
|
||||||
|
static void P_RingShooterCountdown(mobj_t *mo)
|
||||||
|
{
|
||||||
|
mobj_t *part = mo->tracer;
|
||||||
|
|
||||||
|
if (mo->reactiontime == -1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (mo->reactiontime > 0)
|
||||||
|
{
|
||||||
|
mo->reactiontime--;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (!P_MobjWasRemoved(part->tracer))
|
||||||
|
{
|
||||||
|
part = part->tracer;
|
||||||
|
part->frame--;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch ((part->frame & FF_FRAMEMASK) - (part->state->frame & FF_FRAMEMASK)) {
|
||||||
|
case -1:
|
||||||
|
mo->reactiontime = -1;
|
||||||
|
part->skin = mo->skin;
|
||||||
|
P_SetMobjState(part, S_RINGSHOOTER_FACE);
|
||||||
|
break;
|
||||||
|
case 0:
|
||||||
|
mo->reactiontime = TICRATE;
|
||||||
|
S_StartSound(mo, mo->info->deathsound);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
mo->reactiontime = TICRATE;
|
||||||
|
S_StartSound(mo, mo->info->painsound);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void P_RingShooterFlicker(mobj_t *mo)
|
||||||
{
|
{
|
||||||
UINT32 trans;
|
UINT32 trans;
|
||||||
mobj_t *part = mo;
|
mobj_t *part = mo->tracer;
|
||||||
|
|
||||||
while (!P_MobjWasRemoved(part->tracer))
|
while (!P_MobjWasRemoved(part->tracer))
|
||||||
part = part->tracer;
|
part = part->tracer;
|
||||||
|
|
||||||
if (part == mo) // ??? where did you go
|
|
||||||
return;
|
|
||||||
|
|
||||||
part->renderflags ^= RF_DONTDRAW;
|
part->renderflags ^= RF_DONTDRAW;
|
||||||
if (part->renderflags & RF_DONTDRAW)
|
if (part->renderflags & RF_DONTDRAW)
|
||||||
trans = FF_TRANS50;
|
trans = FF_TRANS50;
|
||||||
|
|
@ -4569,6 +4702,15 @@ static void P_RingShooterThinker(mobj_t *mo)
|
||||||
part->target->frame = (part->target->frame & ~FF_TRANSMASK) | trans;
|
part->target->frame = (part->target->frame & ~FF_TRANSMASK) | trans;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void P_RingShooterThinker(mobj_t *mo)
|
||||||
|
{
|
||||||
|
if (P_MobjWasRemoved(mo->tracer) || P_RingShooterInit(mo))
|
||||||
|
return;
|
||||||
|
|
||||||
|
P_RingShooterCountdown(mo);
|
||||||
|
P_RingShooterFlicker(mo);
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// P_BossTargetPlayer
|
// P_BossTargetPlayer
|
||||||
// If closest is true, find the closest player.
|
// If closest is true, find the closest player.
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue