mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2025-10-30 08:01:28 +00:00
Start Ring Shooter respawn: while e-braking, enter the respawn command to spawn a Ring Shooter. Currently purely visual and does not despawn. Steals the player's face for funsies.
This commit is contained in:
parent
0f6ee942a1
commit
c98ff9616b
8 changed files with 314 additions and 1 deletions
|
|
@ -3366,6 +3366,9 @@ static void Got_Respawn(UINT8 **cp, INT32 playernum)
|
|||
if (!P_IsObjectOnGround(players[respawnplayer].mo))
|
||||
return;
|
||||
|
||||
if (K_PlayerEBrake(&players[respawnplayer]))
|
||||
K_SpawnRingShooter(&players[respawnplayer]);
|
||||
else
|
||||
P_DamageMobj(players[respawnplayer].mo, NULL, NULL, 1, DMG_DEATHPIT);
|
||||
demo_extradata[playernum] |= DXD_RESPAWN;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -326,6 +326,7 @@ actionpointer_t actionpointers[] =
|
|||
{{A_FlameShieldPaper}, "A_FLAMESHIELDPAPER"},
|
||||
{{A_InvincSparkleRotate}, "A_INVINCSPARKLEROTATE"},
|
||||
{{A_SpawnItemDebrisCloud}, "A_SPAWNITEMDEBRISCLOUD"},
|
||||
{{A_RingShooterFace}, "A_RINGSHOOTERFACE"},
|
||||
|
||||
{{NULL}, "NONE"},
|
||||
|
||||
|
|
@ -3867,6 +3868,15 @@ const char *const STATE_LIST[] = { // array length left dynamic for sanity testi
|
|||
|
||||
"S_SMOOTHLANDING",
|
||||
|
||||
// DEZ Ring Shooter
|
||||
"S_TIREGRABBER",
|
||||
"S_RINGSHOOTER_SIDE",
|
||||
"S_RINGSHOOTER_NIPPLES",
|
||||
"S_RINGSHOOTER_SCREEN",
|
||||
"S_RINGSHOOTER_NUMBERBACK",
|
||||
"S_RINGSHOOTER_NUMBERFRONT",
|
||||
"S_RINGSHOOTER_FACE",
|
||||
|
||||
// DEZ respawn laser
|
||||
"S_DEZLASER",
|
||||
"S_DEZLASER_TRAIL1",
|
||||
|
|
@ -5433,6 +5443,11 @@ const char *const MOBJTYPE_LIST[] = { // array length left dynamic for sanity t
|
|||
|
||||
"MT_SMOOTHLANDING",
|
||||
|
||||
"MT_TIREGRABBER",
|
||||
"MT_RINGSHOOTER",
|
||||
"MT_RINGSHOOTER_PART",
|
||||
"MT_RINGSHOOTER_SCREEN",
|
||||
|
||||
"MT_DEZLASER",
|
||||
|
||||
"MT_WAYPOINT",
|
||||
|
|
|
|||
120
src/info.c
120
src/info.c
|
|
@ -606,6 +606,10 @@ char sprnames[NUMSPRITES + 1][5] =
|
|||
"TWBS", // Tripwire Boost
|
||||
"TWBT", // Tripwire BLASTER
|
||||
"SMLD", // Smooth landing
|
||||
|
||||
"TIRG", // Tire grabbers
|
||||
"RSHT", // DEZ Ring Shooter
|
||||
|
||||
"DEZL", // DEZ Laser respawn
|
||||
|
||||
// Additional Kart Objects
|
||||
|
|
@ -4464,6 +4468,14 @@ state_t states[NUMSTATES] =
|
|||
|
||||
{SPR_SMLD, FF_FULLBRIGHT|FF_ADD|FF_ANIMATE, -1, {NULL}, 7, 2, S_NULL}, // S_SMOOTHLANDING
|
||||
|
||||
{SPR_TIRG, FF_ANIMATE, -1, {NULL}, 1, 1, S_NULL}, // S_TIREGRABBER
|
||||
{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_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|12, -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_DEZL, FF_FULLBRIGHT|FF_PAPERSPRITE, 8, {NULL}, 0, 0, S_NULL}, // S_DEZLASER
|
||||
{SPR_DEZL, FF_FULLBRIGHT|1, 2, {NULL}, 0, 0, S_DEZLASER_TRAIL2}, // S_DEZLASER_TRAIL1
|
||||
{SPR_DEZL, FF_FULLBRIGHT|2, 2, {NULL}, 0, 0, S_DEZLASER_TRAIL3}, // S_DEZLASER_TRAIL2
|
||||
|
|
@ -24623,6 +24635,114 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
{ // MT_TIREGRABBER
|
||||
-1, // doomednum
|
||||
S_TIREGRABBER, // spawnstate
|
||||
1000, // 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
|
||||
0, // speed
|
||||
20*FRACUNIT, // radius
|
||||
36*FRACUNIT, // height
|
||||
0, // display offset
|
||||
0, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
MF_NOBLOCKMAP|MF_NOCLIPHEIGHT|MF_NOCLIPTHING|MF_NOGRAVITY|MF_SCENERY|MF_DONTENCOREMAP, // flags
|
||||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
{ // MT_RINGSHOOTER
|
||||
-1, // doomednum
|
||||
S_INVISIBLE, // spawnstate
|
||||
1000, // 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
|
||||
0, // speed
|
||||
16*FRACUNIT, // radius
|
||||
16*FRACUNIT, // height
|
||||
0, // display offset
|
||||
0, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
MF_NOBLOCKMAP|MF_NOCLIPHEIGHT|MF_NOCLIPTHING|MF_NOGRAVITY|MF_SCENERY|MF_DONTENCOREMAP, // flags
|
||||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
{ // MT_RINGSHOOTER_PART
|
||||
-1, // doomednum
|
||||
S_RINGSHOOTER_SIDE, // spawnstate
|
||||
1000, // 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
|
||||
0, // speed
|
||||
6*FRACUNIT, // radius
|
||||
70*FRACUNIT, // height
|
||||
0, // display offset
|
||||
0, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
MF_NOBLOCKMAP|MF_NOCLIPHEIGHT|MF_NOCLIPTHING|MF_NOGRAVITY|MF_SCENERY|MF_DONTENCOREMAP, // flags
|
||||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
{ // MT_RINGSHOOTER_SCREEN
|
||||
-1, // doomednum
|
||||
S_RINGSHOOTER_SCREEN, // spawnstate
|
||||
1000, // 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
|
||||
0, // speed
|
||||
23*FRACUNIT, // radius
|
||||
39*FRACUNIT, // height
|
||||
0, // display offset
|
||||
0, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
MF_NOBLOCKMAP|MF_NOCLIPHEIGHT|MF_NOCLIPTHING|MF_NOGRAVITY|MF_SCENERY|MF_DONTENCOREMAP, // flags
|
||||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
{ // MT_DEZLASER
|
||||
-1, // doomednum
|
||||
S_DEZLASER, // spawnstate
|
||||
|
|
|
|||
20
src/info.h
20
src/info.h
|
|
@ -294,6 +294,7 @@ enum actionnum
|
|||
A_FLAMESHIELDPAPER,
|
||||
A_INVINCSPARKLEROTATE,
|
||||
A_SPAWNITEMDEBRISCLOUD,
|
||||
A_RINGSHOOTERFACE,
|
||||
NUMACTIONS
|
||||
};
|
||||
|
||||
|
|
@ -568,6 +569,7 @@ void A_MementosTPParticles();
|
|||
void A_FlameShieldPaper();
|
||||
void A_InvincSparkleRotate();
|
||||
void A_SpawnItemDebrisCloud();
|
||||
void A_RingShooterFace();
|
||||
|
||||
extern boolean actionsoverridden[NUMACTIONS];
|
||||
|
||||
|
|
@ -1157,6 +1159,10 @@ typedef enum sprite
|
|||
SPR_TWBS, // Tripwire Boost
|
||||
SPR_TWBT, // Tripwire BLASTER
|
||||
SPR_SMLD, // Smooth landing
|
||||
|
||||
SPR_TIRG, // Tire grabbers
|
||||
SPR_RSHT, // DEZ Ring Shooter
|
||||
|
||||
SPR_DEZL, // DEZ Laser respawn
|
||||
|
||||
// Additional Kart Objects
|
||||
|
|
@ -4906,6 +4912,15 @@ typedef enum state
|
|||
|
||||
S_SMOOTHLANDING,
|
||||
|
||||
// DEZ Ring Shooter
|
||||
S_TIREGRABBER,
|
||||
S_RINGSHOOTER_SIDE,
|
||||
S_RINGSHOOTER_NIPPLES,
|
||||
S_RINGSHOOTER_SCREEN,
|
||||
S_RINGSHOOTER_NUMBERBACK,
|
||||
S_RINGSHOOTER_NUMBERFRONT,
|
||||
S_RINGSHOOTER_FACE,
|
||||
|
||||
// DEZ Laser respawn
|
||||
S_DEZLASER,
|
||||
S_DEZLASER_TRAIL1,
|
||||
|
|
@ -6508,6 +6523,11 @@ typedef enum mobj_type
|
|||
|
||||
MT_SMOOTHLANDING,
|
||||
|
||||
MT_TIREGRABBER,
|
||||
MT_RINGSHOOTER,
|
||||
MT_RINGSHOOTER_PART,
|
||||
MT_RINGSHOOTER_SCREEN,
|
||||
|
||||
MT_DEZLASER,
|
||||
|
||||
MT_WAYPOINT,
|
||||
|
|
|
|||
85
src/k_kart.c
85
src/k_kart.c
|
|
@ -11774,3 +11774,88 @@ boolean K_Cooperative(void)
|
|||
}
|
||||
|
||||
//}
|
||||
|
||||
void K_SpawnRingShooter(player_t *player)
|
||||
{
|
||||
const fixed_t scale = 2*FRACUNIT;
|
||||
mobjinfo_t *info = &mobjinfo[MT_RINGSHOOTER_PART];
|
||||
mobj_t *mo = player->mo;
|
||||
mobj_t *base = P_SpawnMobj(mo->x, mo->y, mo->z, MT_RINGSHOOTER);
|
||||
mobj_t *part;
|
||||
UINT32 frameNum;
|
||||
angle_t angle;
|
||||
vector2_t offset;
|
||||
SINT8 i;
|
||||
|
||||
K_FlipFromObject(base, mo);
|
||||
P_SetTarget(&base->target, mo);
|
||||
P_SetScale(base, base->destscale = FixedMul(base->destscale, scale));
|
||||
P_InitAngle(base, mo->angle);
|
||||
|
||||
// spawn the RING NIPPLES
|
||||
part = base;
|
||||
frameNum = 0;
|
||||
FV2_Load(&offset, -96*FRACUNIT, 160*FRACUNIT);
|
||||
FV2_Divide(&offset, scale);
|
||||
for (i = -1; i < 2; i += 2)
|
||||
{
|
||||
P_SetTarget(&part->hprev, P_SpawnMobjFromMobj(base,
|
||||
P_ReturnThrustX(NULL, base->angle - ANGLE_90, i*offset.x) + P_ReturnThrustX(NULL, base->angle, offset.y),
|
||||
P_ReturnThrustY(NULL, base->angle - ANGLE_90, i*offset.x) + P_ReturnThrustY(NULL, base->angle, offset.y),
|
||||
0, MT_RINGSHOOTER_PART));
|
||||
P_SetTarget(&part->hprev->hnext, part);
|
||||
part = part->hprev;
|
||||
P_SetTarget(&part->target, base);
|
||||
|
||||
P_InitAngle(part, base->angle - i * ANGLE_45);
|
||||
P_SetMobjState(part, S_RINGSHOOTER_NIPPLES);
|
||||
part->frame += frameNum;
|
||||
frameNum++;
|
||||
}
|
||||
|
||||
// spawn the box
|
||||
part = base;
|
||||
frameNum = 0;
|
||||
angle = base->angle + ANGLE_90;
|
||||
FV2_Load(&offset, offset.x - info->radius, offset.y - info->radius); // set the new origin to the centerpoint of the box
|
||||
FV2_Load(&offset,
|
||||
P_ReturnThrustX(NULL, base->angle - ANGLE_90, offset.x) + P_ReturnThrustX(NULL, base->angle, offset.y),
|
||||
P_ReturnThrustY(NULL, base->angle - ANGLE_90, offset.x) + P_ReturnThrustY(NULL, base->angle, offset.y)); // transform it relative to the base
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
P_SetTarget(&part->hnext, P_SpawnMobjFromMobj(base,
|
||||
offset.x + P_ReturnThrustX(NULL, angle, info->radius),
|
||||
offset.y + P_ReturnThrustY(NULL, angle, info->radius),
|
||||
0, MT_RINGSHOOTER_PART));
|
||||
P_SetTarget(&part->hnext->hprev, part);
|
||||
part = part->hnext;
|
||||
P_SetTarget(&part->target, base);
|
||||
|
||||
if (i == 2)
|
||||
frameNum++;
|
||||
frameNum ^= FF_HORIZONTALFLIP;
|
||||
angle -= ANGLE_90;
|
||||
part->frame += frameNum;
|
||||
P_InitAngle(part, angle);
|
||||
}
|
||||
|
||||
// spawn the screen
|
||||
part = P_SpawnMobjFromMobj(base, offset.x, offset.y, info->height, MT_RINGSHOOTER_SCREEN);
|
||||
P_SetTarget(&base->tracer, part);
|
||||
P_SetTarget(&part->target, base);
|
||||
P_InitAngle(part, base->angle - ANGLE_45);
|
||||
|
||||
// spawn the screen numbers
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
P_SetTarget(&part->tracer, P_SpawnMobjFromMobj(part, 0, 0, 0, MT_OVERLAY));
|
||||
P_SetTarget(&part->tracer->target, part);
|
||||
part = part->tracer;
|
||||
P_InitAngle(part, part->target->angle);
|
||||
P_SetMobjState(part, S_RINGSHOOTER_NUMBERBACK + i);
|
||||
}
|
||||
|
||||
// test face feature (to be moved into thinker later)
|
||||
part->skin = mo->skin;
|
||||
P_SetMobjState(part, S_RINGSHOOTER_FACE);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -189,6 +189,7 @@ boolean K_IsSPBInGame(void);
|
|||
void K_KartEbrakeVisuals(player_t *p);
|
||||
void K_HandleDirectionalInfluence(player_t *player);
|
||||
fixed_t K_DefaultPlayerRadius(player_t *player);
|
||||
void K_SpawnRingShooter(player_t *player);
|
||||
|
||||
// sound stuff for lua
|
||||
void K_PlayAttackTaunt(mobj_t *source);
|
||||
|
|
|
|||
|
|
@ -330,6 +330,7 @@ void A_MementosTPParticles(mobj_t *actor);
|
|||
void A_FlameShieldPaper(mobj_t *actor);
|
||||
void A_InvincSparkleRotate(mobj_t *actor);
|
||||
void A_SpawnItemDebrisCloud(mobj_t *actor);
|
||||
void A_RingShooterFace(mobj_t *actor);
|
||||
|
||||
//for p_enemy.c
|
||||
|
||||
|
|
@ -13810,3 +13811,49 @@ A_SpawnItemDebrisCloud (mobj_t *actor)
|
|||
puff->momz += FixedMul(target->momz, fade);
|
||||
}
|
||||
}
|
||||
|
||||
// sets the actor's
|
||||
// vars do nothing
|
||||
void A_RingShooterFace(mobj_t *actor)
|
||||
{
|
||||
player_t *player;
|
||||
mobj_t *mo = actor;
|
||||
|
||||
if (LUA_CallAction(A_RINGSHOOTERFACE, actor))
|
||||
return;
|
||||
|
||||
// get the player, if possible
|
||||
while ((mo->player == NULL) && !P_MobjWasRemoved(mo->target))
|
||||
mo = mo->target;
|
||||
|
||||
player = mo->player;
|
||||
|
||||
if (!player) // something changed my target, abort
|
||||
return;
|
||||
|
||||
// it's a good idea to set the actor's skin *before* it uses this action,
|
||||
// but just in case, if it doesn't have the player's skin, set its skin then call the state again to get the correct sprite
|
||||
if (actor->skin != &skins[player->skin])
|
||||
{
|
||||
actor->skin = &skins[player->skin];
|
||||
P_SetMobjState(actor, (statenum_t)(actor->state-states));
|
||||
return;
|
||||
}
|
||||
|
||||
// okay, now steal the player's color nyehehehe
|
||||
actor->color = player->skincolor;
|
||||
|
||||
// set the frame to the WANTED pic
|
||||
actor->frame = (actor->frame & ~FF_FRAMEMASK) | FACE_WANTED;
|
||||
|
||||
// we're going to assume the character's WANTED icon is 32 x 32
|
||||
// let's squish the sprite a bit so that it matches the dimensions of the screen's sprite, which is 26 x 22
|
||||
// (TODO: maybe get the dimensions/offsets from the patches themselves?)
|
||||
actor->spritexscale = FixedDiv(26*FRACUNIT, 32*FRACUNIT);
|
||||
actor->spriteyscale = FixedDiv(22*FRACUNIT, 32*FRACUNIT);
|
||||
|
||||
// a normal WANTED icon should have (0, 0) offsets
|
||||
// so let's offset it such that it will match the position of the screen's sprite
|
||||
actor->spritexoffset = 16*FRACUNIT; // 32 / 2
|
||||
actor->spriteyoffset = 28*FRACUNIT + FixedDiv(11*FRACUNIT, actor->spriteyscale); // 32 - 4 (generic monster bottom) + 11 (vertical offset of screen sprite from the bottom)
|
||||
}
|
||||
|
|
|
|||
22
src/p_mobj.c
22
src/p_mobj.c
|
|
@ -4550,6 +4550,25 @@ static void P_SpawnItemCapsuleParts(mobj_t *mobj)
|
|||
#undef ANG_CAPSULE
|
||||
#undef ROTATIONSPEED
|
||||
|
||||
static void P_RingShooterThinker(mobj_t *mo)
|
||||
{
|
||||
UINT32 trans;
|
||||
mobj_t *part = mo;
|
||||
|
||||
while (!P_MobjWasRemoved(part->tracer))
|
||||
part = part->tracer;
|
||||
|
||||
if (part == mo) // ??? where did you go
|
||||
return;
|
||||
|
||||
part->renderflags ^= RF_DONTDRAW;
|
||||
if (part->renderflags & RF_DONTDRAW)
|
||||
trans = FF_TRANS50;
|
||||
else
|
||||
trans = 0;
|
||||
part->target->frame = (part->target->frame & ~FF_TRANSMASK) | trans;
|
||||
}
|
||||
|
||||
//
|
||||
// P_BossTargetPlayer
|
||||
// If closest is true, find the closest player.
|
||||
|
|
@ -6641,6 +6660,9 @@ static void P_MobjSceneryThink(mobj_t *mobj)
|
|||
mobj->momz = newz - mobj->z;
|
||||
}
|
||||
break;
|
||||
case MT_RINGSHOOTER:
|
||||
P_RingShooterThinker(mobj);
|
||||
break;
|
||||
case MT_SPINDASHWIND:
|
||||
case MT_DRIFTELECTRICSPARK:
|
||||
mobj->renderflags ^= RF_DONTDRAW;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue