Hardcode pumice ball

Current known issues: players detached from the ball via any means other than jumping or pain do not have their ball reset properly
This commit is contained in:
lachwright 2019-09-29 20:18:40 +08:00
parent a5ae8abdb2
commit 8abb6129c1
8 changed files with 313 additions and 13 deletions

View file

@ -234,7 +234,8 @@ typedef enum
CR_ZOOMTUBE,
CR_ROPEHANG,
CR_MACESPIN,
CR_MINECART
CR_MINECART,
CR_ROLLOUT
} carrytype_t; // pw_carry
// Player powers. (don't edit this comment)

View file

@ -2435,6 +2435,8 @@ static actionpointer_t actionpointers[] =
{{A_LavafallLava}, "A_LAVAFALLLAVA"},
{{A_FallingLavaCheck}, "A_FALLINGLAVACHECK"},
{{A_FireShrink}, "A_FIRESHRINK"},
{{A_RolloutSpawn}, "A_ROLLOUTSPAWN"},
{{A_RolloutRock}, "A_ROLLOUTROCK"},
{{NULL}, "NONE"},
// This NULL entry must be the last in the list
@ -5842,6 +5844,10 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
"S_LAVAFALL_LAVA3",
"S_LAVAFALLROCK",
// Rollout Rock
"S_ROLLOUTSPAWN",
"S_ROLLOUTROCK",
// RVZ scenery
"S_BIGFERNLEAF",
"S_BIGFERN1",
@ -7572,6 +7578,9 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s
"MT_LAVAFALL_LAVA",
"MT_LAVAFALLROCK",
"MT_ROLLOUTSPAWN",
"MT_ROLLOUTROCK",
"MT_BIGFERNLEAF",
"MT_BIGFERN",
"MT_JUNGLEPALM",
@ -8579,6 +8588,7 @@ struct {
{"CR_ROPEHANG",CR_ROPEHANG},
{"CR_MACESPIN",CR_MACESPIN},
{"CR_MINECART",CR_MINECART},
{"CR_ROLLOUT", CR_ROLLOUT},
// Ring weapons (ringweapons_t)
// Useful for A_GiveWeapon

View file

@ -257,6 +257,7 @@ light_t *t_lspr[NUMSPRITES] =
&lspr[NOLIGHT], // SPR_WSPB
&lspr[NOLIGHT], // SPR_STPT
&lspr[NOLIGHT], // SPR_BMNE
&lspr[NOLIGHT], // SPR_PUMI
// Monitor Boxes
&lspr[NOLIGHT], // SPR_MSTV

View file

@ -146,6 +146,7 @@ char sprnames[NUMSPRITES + 1][5] =
"WSPB", // Wall spike base
"STPT", // Starpost
"BMNE", // Big floating mine
"PUMI", // Rollout Rock
// Monitor Boxes
"MSTV", // MiSc TV sprites
@ -2472,6 +2473,10 @@ state_t states[NUMSTATES] =
{SPR_LFAL, 2|FF_FULLBRIGHT|FF_ANIMATE, 9, {NULL}, 2, 3, S_NULL}, // S_LAVAFALL_LAVA3
{SPR_LFAL, 11|FF_ANIMATE|FF_RANDOMANIM, 12, {NULL}, 3, 3, S_LAVAFALLROCK}, // S_LAVAFALLROCK
// Rollout Rock
{SPR_NULL, 0, 1, {A_RolloutSpawn}, 256*FRACUNIT, MT_ROLLOUTROCK, S_ROLLOUTSPAWN}, // S_ROLLOUTSPAWN
{SPR_PUMI, 0, 1, {A_RolloutRock}, 63*FRACUNIT/64, 6*FRACUNIT/10, S_ROLLOUTROCK}, // S_ROLLOUTROCK
// RVZ scenery
{SPR_JPLA, FF_PAPERSPRITE, -1, {NULL}, 0, 0, S_NULL}, // S_BIGFERNLEAF
{SPR_JPLA, 1, 1, {NULL}, 0, 0, S_BIGFERN2}, // S_BIGFERN1
@ -12726,6 +12731,60 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_NULL // raisestate
},
{ // MT_ROLLOUTSPAWN
1305, // doomednum
S_ROLLOUTSPAWN, // 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
8*FRACUNIT, // radius
8*FRACUNIT, // height
0, // display offset
100, // mass
0, // damage
sfx_None, // activesound
MF_NOBLOCKMAP|MF_NOGRAVITY|MF_NOCLIP|MF_SPAWNCEILING, // flags
S_NULL // raisestate
},
{ // MT_ROLLOUTROCK
-1, // doomednum
S_ROLLOUTROCK, // spawnstate
1000, // spawnhealth
S_NULL, // seestate
sfx_None, // seesound
8, // 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
32*FRACUNIT, // speed
30*FRACUNIT, // radius
60*FRACUNIT, // height
0, // display offset
100, // mass
0, // damage
sfx_None, // activesound
MF_PUSHABLE|MF_SOLID|MF_SLIDEME, // flags
S_NULL // raisestate
},
{ // MT_BIGFERNLEAF
-1, // doomednum
S_BIGFERNLEAF, // spawnstate

View file

@ -270,6 +270,8 @@ void A_LavafallRocks();
void A_LavafallLava();
void A_FallingLavaCheck();
void A_FireShrink();
void A_RolloutSpawn();
void A_RolloutRock();
// ratio of states to sprites to mobj types is roughly 6 : 1 : 1
#define NUMMOBJFREESLOTS 512
@ -396,6 +398,7 @@ typedef enum sprite
SPR_WSPB, // Wall spike base
SPR_STPT, // Starpost
SPR_BMNE, // Big floating mine
SPR_PUMI, // Rollout Rock
// Monitor Boxes
SPR_MSTV, // MiSc TV sprites
@ -2595,6 +2598,10 @@ typedef enum state
S_LAVAFALL_LAVA3,
S_LAVAFALLROCK,
// Rollout Rock
S_ROLLOUTSPAWN,
S_ROLLOUTROCK,
// RVZ scenery
S_BIGFERNLEAF,
S_BIGFERN1,
@ -4347,6 +4354,9 @@ typedef enum mobj_type
MT_LAVAFALL_LAVA,
MT_LAVAFALLROCK,
MT_ROLLOUTSPAWN,
MT_ROLLOUTROCK,
MT_BIGFERNLEAF,
MT_BIGFERN,
MT_JUNGLEPALM,

View file

@ -300,6 +300,8 @@ void A_LavafallRocks(mobj_t *actor);
void A_LavafallLava(mobj_t *actor);
void A_FallingLavaCheck(mobj_t *actor);
void A_FireShrink(mobj_t *actor);
void A_RolloutSpawn(mobj_t *actor);
void A_RolloutRock(mobj_t *actor);
//for p_enemy.c
@ -13838,4 +13840,111 @@ void A_FireShrink(mobj_t *actor)
actor->destscale = locvar1;
actor->scalespeed = FRACUNIT/locvar2;
}
}
// Function: A_RolloutSpawn
//
// Description: Spawns a new Rollout Rock when the currently spawned rock is destroyed or moves far enough away.
//
// var1 = Distance currently spawned rock should travel before spawning a new one
// var2 = Object type to spawn
//
void A_RolloutSpawn(mobj_t *actor)
{
INT32 locvar1 = var1;
INT32 locvar2 = var2;
#ifdef HAVE_BLUA
if (LUA_CallAction("A_RolloutSpawn", actor))
return;
#endif
if (!(actor->target)
|| P_MobjWasRemoved(actor->target)
|| P_AproxDistance(actor->x - actor->target->x, actor->y - actor->target->y) > locvar1)
{
actor->target = P_SpawnMobj(actor->x, actor->y, actor->z, locvar2);
}
}
// Function: A_RolloutRock
//
// Description: Thinker for Rollout Rock.
//
// var1 = Drag
// var2 = Vertical bobbing speed factor
//
void A_RolloutRock(mobj_t *actor)
{
INT32 locvar1 = var1;
INT32 locvar2 = var2;
#ifdef HAVE_BLUA
if (LUA_CallAction("A_RolloutRock", actor))
return;
#endif
UINT8 maxframes = actor->info->reactiontime;
fixed_t pi = (22*FRACUNIT/7);
fixed_t circumference = FixedMul(2 * pi, actor->radius);
fixed_t oldspeed = P_AproxDistance(actor->momx, actor->momy), newspeed, topspeed = actor->info->speed;
mobj_t *target = actor->target;
player_t *player;
boolean inwater = actor->eflags & (MFE_TOUCHWATER|MFE_UNDERWATER);
actor->friction = FRACUNIT;
if (inwater)
{
fixed_t height;
if (actor->eflags & MFE_VERTICALFLIP)
{
height = actor->waterbottom + (actor->height>>2);
if (actor->z + actor->height > height)
{
actor->z = height;
actor->momz = 0;
}
}
else
{
height = actor->watertop - (actor->height>>2);
if (actor->z < height)
{
actor->z = height;
actor->momz = 0;
}
}
actor->momz += P_MobjFlip(actor) * FixedMul(locvar2, actor->scale);
}
if (oldspeed > topspeed)
{
actor->momx = FixedMul(FixedDiv(actor->momx, oldspeed), topspeed);
actor->momy = FixedMul(FixedDiv(actor->momy, oldspeed), topspeed);
}
actor->momx = FixedMul(actor->momx, locvar1);
actor->momy = FixedMul(actor->momy, locvar1);
newspeed = P_AproxDistance(actor->momx, actor->momy);
if (newspeed < actor->scale >> 1)
{
actor->momx = 0;
actor->momy = 0;
}
else if (newspeed > actor->scale)
{
actor->angle = R_PointToAngle2(0, 0, actor->momx, actor->momy);
actor->movefactor += newspeed;
if (actor->movefactor > circumference / maxframes)
{
actor->reactiontime++;
actor->reactiontime %= maxframes;
actor->movefactor = 0;
}
}
actor->frame = actor->reactiontime % maxframes;
}

View file

@ -920,6 +920,59 @@ static boolean PIT_CheckThing(mobj_t *thing)
P_DamageMobj(thing, tmthing, tmthing, 1, 0);
}
if (thing->type == MT_ROLLOUTROCK)
{
if (tmthing->player)
{
if (tmthing->player->powers[pw_carry] == CR_ROLLOUT)
{
return true;
}
if ((thing->flags & MF_PUSHABLE) // carrying a player
&& ((tmthing->eflags & MFE_VERTICALFLIP) == (thing->eflags & MFE_VERTICALFLIP))
&& (P_AproxDistance(thing->x - tmthing->x, thing->y - tmthing->y) < (thing->radius))
&& (P_MobjFlip(tmthing)*tmthing->momz <= 0)
&& ((!(tmthing->eflags & MFE_VERTICALFLIP) && abs(thing->z + thing->height - tmthing->z) < (thing->height>>2))
|| (tmthing->eflags & MFE_VERTICALFLIP && abs(tmthing->z + tmthing->height - thing->z) < (thing->height>>2))))
{
thing->flags &= ~MF_PUSHABLE;
P_SetTarget(&thing->target, tmthing);
P_ResetPlayer(tmthing->player);
P_SetPlayerMobjState(tmthing, S_PLAY_WALK);
tmthing->player->powers[pw_carry] = CR_ROLLOUT;
P_SetTarget(&tmthing->tracer, thing);
return false;
}
}
else if (tmthing->type == thing->type)
{
if (tmthing->z > thing->z + thing->height || thing->z > tmthing->z + tmthing->height)
return true;
fixed_t tempmomx = thing->momx, tempmomy = thing->momy;
thing->momx = tmthing->momx;
thing->momy = tmthing->momy;
tmthing->momx = tempmomx;
tmthing->momy = tempmomy;
}
}
else if (tmthing->type == MT_ROLLOUTROCK)
{
if (tmthing->z > thing->z + thing->height || thing->z > tmthing->z + tmthing->height || !thing->health)
return true;
if (thing->flags & MF_SPRING)
{
P_DoSpring(thing, tmthing);
return true;
}
else if (thing->flags & MF_MONITOR && thing->flags & MF_SHOOTABLE && !(tmthing->flags & MF_PUSHABLE)) // carrying a player
{
P_KillMobj(thing, tmthing, tmthing->target, 0);
return true;
}
}
if (thing->type == MT_VULTURE && tmthing->type == MT_VULTURE)
{
fixed_t dx = thing->x - tmthing->x;

View file

@ -948,6 +948,17 @@ void P_DoPlayerPain(player_t *player, mobj_t *source, mobj_t *inflictor)
if (player->powers[pw_carry] == CR_ROPEHANG)
P_SetTarget(&player->mo->tracer, NULL);
if (player->powers[pw_carry] == CR_ROLLOUT)
{
if (player->mo->tracer && !P_MobjWasRemoved(player->mo->tracer))
{
player->mo->tracer->flags |= MF_PUSHABLE;
P_SetTarget(&player->mo->tracer->target, NULL);
}
P_SetTarget(&player->mo->tracer, NULL);
player->powers[pw_carry] = CR_NONE;
}
{
angle_t ang;
fixed_t fallbackspeed;
@ -4292,6 +4303,8 @@ void P_DoJump(player_t *player, boolean soundandstate)
{
player->mo->momz = 9*FRACUNIT;
player->powers[pw_carry] = CR_NONE;
player->mo->tracer->flags |= MF_PUSHABLE;
P_SetTarget(&player->mo->tracer->target, NULL);
P_SetTarget(&player->mo->tracer, NULL);
}
else if (player->powers[pw_carry] == CR_ROPEHANG)
@ -4300,6 +4313,14 @@ void P_DoJump(player_t *player, boolean soundandstate)
player->powers[pw_carry] = CR_NONE;
P_SetTarget(&player->mo->tracer, NULL);
}
else if (player->powers[pw_carry] == CR_ROLLOUT)
{
player->mo->momz = 9*FRACUNIT + player->mo->tracer->momz;
player->powers[pw_carry] = CR_NONE;
player->mo->tracer->flags |= MF_PUSHABLE;
P_SetTarget(&player->mo->tracer->target, NULL);
P_SetTarget(&player->mo->tracer, NULL);
}
else if (player->mo->eflags & MFE_GOOWATER)
{
player->mo->momz = 7*FRACUNIT;
@ -11121,6 +11142,8 @@ void P_PlayerThink(player_t *player)
// deez New User eXperiences.
{
angle_t diff = 0;
UINT8 factor;
// Directionchar!
// Camera angle stuff.
if (player->exiting // no control, no modification
@ -11149,6 +11172,13 @@ void P_PlayerThink(player_t *player)
case CR_GENERIC:
player->drawangle = player->mo->tracer->angle;
break;
case CR_ROLLOUT:
if (cmd->forwardmove || cmd->sidemove) // only when you're pressing movement keys
{ // inverse direction!
diff = ((player->mo->angle + R_PointToAngle2(0, 0, -cmd->forwardmove<<FRACBITS, cmd->sidemove<<FRACBITS)) - player->drawangle);
factor = 4;
}
break;
/* -- in case we wanted to have the camera freely movable during zoom tubes
case CR_ZOOMTUBE:*/
case CR_ROPEHANG:
@ -11169,9 +11199,6 @@ void P_PlayerThink(player_t *player)
;
else
{
angle_t diff;
UINT8 factor;
if (player->pflags & PF_SLIDING)
{
#if 0 // fun hydrocity style horizontal spin
@ -11207,15 +11234,15 @@ void P_PlayerThink(player_t *player)
diff = (player->mo->angle - player->drawangle);
factor = 8;
}
}
if (diff)
{
if (diff > ANGLE_180)
diff = InvAngle(InvAngle(diff)/factor);
else
diff /= factor;
player->drawangle += diff;
}
if (diff)
{
if (diff > ANGLE_180)
diff = InvAngle(InvAngle(diff)/factor);
else
diff /= factor;
player->drawangle += diff;
}
// Autobrake! check ST_drawInput if you modify this
@ -11831,6 +11858,36 @@ void P_PlayerAfterThink(player_t *player)
}
break;
}
case CR_ROLLOUT:
{
mobj_t *mo = player->mo, *rock = player->mo->tracer;
UINT8 walktics = mo->state->tics - P_GetPlayerControlDirection(player);
if (!rock || P_MobjWasRemoved(rock))
{
P_SetTarget(&player->mo->tracer, NULL);
player->powers[pw_carry] = CR_NONE;
break;
}
if (player->cmd.forwardmove || player->cmd.sidemove)
{
rock->movedir = (player->cmd.angleturn << FRACBITS) + R_PointToAngle2(0, 0, player->cmd.forwardmove << FRACBITS, -player->cmd.sidemove << FRACBITS);
P_Thrust(rock, rock->movedir, rock->scale >> 1);
}
mo->momx = rock->momx;
mo->momy = rock->momy;
mo->momz = 0;
if (player->panim == PA_WALK && mo->tics > walktics)
{
mo->tics = walktics;
}
P_TeleportMove(player->mo, rock->x, rock->y, rock->z + rock->height);
break;
}
default:
break;
}