mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2025-01-30 21:20:54 +00:00
Implemented the Pterabyte grabbing mechanic
This commit is contained in:
parent
22e3c37e5d
commit
26ecab14d7
7 changed files with 165 additions and 8 deletions
|
@ -234,7 +234,8 @@ typedef enum
|
|||
CR_ZOOMTUBE,
|
||||
CR_ROPEHANG,
|
||||
CR_MACESPIN,
|
||||
CR_MINECART
|
||||
CR_MINECART,
|
||||
CR_PTERABYTE
|
||||
} carrytype_t; // pw_carry
|
||||
|
||||
// Player powers. (don't edit this comment)
|
||||
|
|
|
@ -8594,6 +8594,7 @@ struct {
|
|||
{"CR_ROPEHANG",CR_ROPEHANG},
|
||||
{"CR_MACESPIN",CR_MACESPIN},
|
||||
{"CR_MINECART",CR_MINECART},
|
||||
{"CR_PTERABYTE",CR_PTERABYTE},
|
||||
|
||||
// Ring weapons (ringweapons_t)
|
||||
// Useful for A_GiveWeapon
|
||||
|
|
|
@ -13878,6 +13878,7 @@ void A_SpawnPterabytes(mobj_t *actor)
|
|||
s = FINESINE(fa);
|
||||
waypoint = P_SpawnMobjFromMobj(actor, FixedMul(c, rad), FixedMul(s, rad), 0, MT_PTERABYTEWAYPOINT);
|
||||
waypoint->angle = ang + ANGLE_90;
|
||||
P_SetTarget(&waypoint->tracer, actor);
|
||||
ptera = P_SpawnMobjFromMobj(waypoint, 0, 0, 0, MT_PTERABYTE);
|
||||
ptera->angle = waypoint->angle;
|
||||
P_SetTarget(&ptera->tracer, waypoint);
|
||||
|
|
|
@ -456,6 +456,9 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
|||
|
||||
if (P_PlayerCanDamage(player, special)) // Do you possess the ability to subdue the object?
|
||||
{
|
||||
if (special->type == MT_PTERABYTE && special->target == player->mo && special->extravalue1 == 1)
|
||||
return; // Can't hurt a Pterabyte if it's trying to pick you up
|
||||
|
||||
if ((P_MobjFlip(toucher)*toucher->momz < 0) && (elementalpierce != 1))
|
||||
{
|
||||
if (elementalpierce == 2)
|
||||
|
@ -477,7 +480,12 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
|||
P_TwinSpinRejuvenate(player, player->thokitem);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (special->type == MT_PTERABYTE && special->target == player->mo)
|
||||
return; // Don't hurt the player you're trying to grab
|
||||
|
||||
P_DamageMobj(toucher, special, special, 1, 0);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
|
37
src/p_map.c
37
src/p_map.c
|
@ -490,6 +490,40 @@ static void P_DoFanAndGasJet(mobj_t *spring, mobj_t *object)
|
|||
}
|
||||
}
|
||||
|
||||
static void P_DoPterabyteCarry(player_t *player, mobj_t *ptera)
|
||||
{
|
||||
if (player->powers[pw_carry])
|
||||
return;
|
||||
if (ptera->extravalue1 != 1)
|
||||
return; // Not swooping
|
||||
if (ptera->target != player->mo)
|
||||
return; // Not swooping for you!
|
||||
|
||||
if (player->spectator)
|
||||
return;
|
||||
|
||||
if ((player->mo->eflags & MFE_VERTICALFLIP) != (ptera->eflags & MFE_VERTICALFLIP))
|
||||
return; // Both should be in same gravity
|
||||
|
||||
if (ptera->eflags & MFE_VERTICALFLIP)
|
||||
{
|
||||
if (ptera->ceilingz - (ptera->z + ptera->height) < player->mo->height - FixedMul(2*FRACUNIT, player->mo->scale))
|
||||
return;
|
||||
}
|
||||
else if (ptera->z - ptera->floorz < player->mo->height - FixedMul(2*FRACUNIT, player->mo->scale))
|
||||
return; // No room to pick up this guy!
|
||||
|
||||
P_ResetPlayer(player);
|
||||
P_SetTarget(&player->mo->tracer, ptera);
|
||||
player->powers[pw_carry] = CR_PTERABYTE;
|
||||
S_StartSound(player->mo, sfx_s3k4a);
|
||||
P_UnsetThingPosition(player->mo);
|
||||
player->mo->x = ptera->x;
|
||||
player->mo->y = ptera->y;
|
||||
P_SetThingPosition(player->mo);
|
||||
ptera->movefactor = 3*TICRATE;
|
||||
}
|
||||
|
||||
static void P_DoTailsCarry(player_t *sonic, player_t *tails)
|
||||
{
|
||||
INT32 p;
|
||||
|
@ -920,6 +954,9 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
|||
P_DamageMobj(thing, tmthing, tmthing, 1, 0);
|
||||
}
|
||||
|
||||
if (thing->type == MT_PTERABYTE && tmthing->player)
|
||||
P_DoPterabyteCarry(tmthing->player, thing);
|
||||
|
||||
if (thing->type == MT_VULTURE && tmthing->type == MT_VULTURE)
|
||||
{
|
||||
fixed_t dx = thing->x - tmthing->x;
|
||||
|
|
36
src/p_mobj.c
36
src/p_mobj.c
|
@ -9078,7 +9078,18 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
}
|
||||
case MT_PTERABYTE:
|
||||
{
|
||||
if (mobj->extravalue1 == 0) // Hovering
|
||||
if (mobj->extravalue1 & 4) // Cooldown after grabbing
|
||||
{
|
||||
if (mobj->movefactor)
|
||||
mobj->movefactor--;
|
||||
else
|
||||
{
|
||||
P_SetTarget(&mobj->target, NULL);
|
||||
mobj->extravalue1 &= 3;
|
||||
}
|
||||
}
|
||||
|
||||
if ((mobj->extravalue1 & 3) == 0) // Hovering
|
||||
{
|
||||
fixed_t vdist, hdist, time;
|
||||
fixed_t hspeed = 3*mobj->info->speed;
|
||||
|
@ -9087,21 +9098,31 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
var1 = 1;
|
||||
var2 = 0;
|
||||
A_CapeChase(mobj);
|
||||
|
||||
if (mobj->target)
|
||||
break; // Still carrying a player or in cooldown
|
||||
|
||||
P_LookForPlayers(mobj, true, false, 256*FRACUNIT);
|
||||
|
||||
if (!mobj->target)
|
||||
break;
|
||||
|
||||
vdist = mobj->z - mobj->target->z;
|
||||
vdist = mobj->z - mobj->target->z - mobj->target->height;
|
||||
if (vdist <= 0)
|
||||
{
|
||||
P_SetTarget(&mobj->target, NULL);
|
||||
break;
|
||||
}
|
||||
|
||||
hdist = R_PointToDist2(mobj->x, mobj->y, mobj->target->x, mobj->target->y);
|
||||
if (hdist > 450*FRACUNIT)
|
||||
{
|
||||
P_SetTarget(&mobj->target, NULL);
|
||||
break;
|
||||
}
|
||||
|
||||
P_SetMobjState(mobj, S_PTERABYTE_SWOOPDOWN);
|
||||
mobj->extravalue1 = 1;
|
||||
mobj->extravalue1++;
|
||||
S_StartSound(mobj, mobj->info->attacksound);
|
||||
time = FixedDiv(hdist, hspeed);
|
||||
mobj->angle = R_PointToAngle2(mobj->x, mobj->y, mobj->target->x, mobj->target->y);
|
||||
|
@ -9113,7 +9134,7 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
mobj->movecount = time >> FRACBITS;
|
||||
mobj->reactiontime = mobj->movecount;
|
||||
}
|
||||
else if (mobj->extravalue1 == 1) // Swooping
|
||||
else if ((mobj->extravalue1 & 3) == 1) // Swooping
|
||||
{
|
||||
mobj->reactiontime--;
|
||||
mobj->momz += mobj->extravalue2;
|
||||
|
@ -9128,8 +9149,9 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
else if (mobj->state - states == S_PTERABYTE_SWOOPUP)
|
||||
{
|
||||
P_SetMobjState(mobj, S_PTERABYTE_FLY1);
|
||||
mobj->extravalue1 = 2;
|
||||
P_SetTarget(&mobj->target, NULL);
|
||||
mobj->extravalue1++;
|
||||
if (mobj->target && mobj->target->tracer != mobj)
|
||||
P_SetTarget(&mobj->target, NULL); // Failed to grab the target
|
||||
mobj->momx = mobj->momy = mobj->momz = 0;
|
||||
}
|
||||
}
|
||||
|
@ -9140,7 +9162,7 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
A_HomingChase(mobj);
|
||||
if (P_AproxDistance(mobj->x - mobj->tracer->x, mobj->y - mobj->tracer->y) <= mobj->info->speed)
|
||||
{
|
||||
mobj->extravalue1 = 0;
|
||||
mobj->extravalue1 -= 2;
|
||||
mobj->momx = mobj->momy = mobj->momz = 0;
|
||||
}
|
||||
}
|
||||
|
|
87
src/p_user.c
87
src/p_user.c
|
@ -4279,6 +4279,9 @@ void P_DoJump(player_t *player, boolean soundandstate)
|
|||
if (player->mo->ceilingz-player->mo->floorz <= player->mo->height-1)
|
||||
return;
|
||||
|
||||
if (player->powers[pw_carry] == CR_PTERABYTE)
|
||||
return;
|
||||
|
||||
// Jump this high.
|
||||
if (player->powers[pw_carry] == CR_PLAYER)
|
||||
{
|
||||
|
@ -11518,6 +11521,36 @@ void P_PlayerThink(player_t *player)
|
|||
}*/
|
||||
}
|
||||
|
||||
// Checks if the mobj is above lava. Used by Pterabyte.
|
||||
static boolean P_MobjAboveLava(mobj_t *mobj)
|
||||
{
|
||||
sector_t *sector = mobj->subsector->sector;
|
||||
|
||||
if (sector->ffloors)
|
||||
{
|
||||
ffloor_t *rover;
|
||||
|
||||
for (rover = sector->ffloors; rover; rover = rover->next)
|
||||
{
|
||||
if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_SWIMMABLE) || GETSECSPECIAL(rover->master->frontsector->special, 1) != 3)
|
||||
continue;
|
||||
|
||||
if (mobj->eflags & MFE_VERTICALFLIP)
|
||||
{
|
||||
if (*rover->bottomheight <= mobj->ceilingz && *rover->bottomheight >= mobj->z)
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (*rover->topheight >= mobj->floorz && *rover->topheight <= mobj->z)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//
|
||||
// P_PlayerAfterThink
|
||||
//
|
||||
|
@ -11831,6 +11864,60 @@ void P_PlayerAfterThink(player_t *player)
|
|||
}
|
||||
break;
|
||||
}
|
||||
case CR_PTERABYTE: // being carried by a Pterabyte
|
||||
{
|
||||
mobj_t *ptera = player->mo->tracer;
|
||||
mobj_t *spawnpoint = ptera->tracer->tracer;
|
||||
player->mo->height = FixedDiv(P_GetPlayerHeight(player), FixedDiv(14 * FRACUNIT, 10 * FRACUNIT));
|
||||
|
||||
if (ptera->health <= 0)
|
||||
goto dropoff;
|
||||
|
||||
if (P_MobjAboveLava(ptera))
|
||||
goto dropoff;
|
||||
|
||||
if (player->mo->eflags & MFE_VERTICALFLIP)
|
||||
{
|
||||
if ((ptera->z + ptera->height + player->mo->height + FixedMul(FRACUNIT, player->mo->scale)) <= ptera->ceilingz
|
||||
&& (ptera->eflags & MFE_VERTICALFLIP)) // Reverse gravity check for the carrier - Flame
|
||||
player->mo->z = ptera->z + ptera->height + FixedMul(FRACUNIT, player->mo->scale);
|
||||
|
||||
if (ptera->ceilingz - ptera->z > spawnpoint->ceilingz - spawnpoint->z + 512*FRACUNIT)
|
||||
goto dropoff;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((ptera->z - player->mo->height - FixedMul(FRACUNIT, player->mo->scale)) >= ptera->floorz
|
||||
&& !(ptera->eflags & MFE_VERTICALFLIP)) // Correct gravity check for the carrier - Flame
|
||||
player->mo->z = ptera->z - player->mo->height - FixedMul(FRACUNIT, player->mo->scale);
|
||||
|
||||
if (ptera->z - ptera->floorz > spawnpoint->z - spawnpoint->floorz + 512 * FRACUNIT)
|
||||
goto dropoff;
|
||||
}
|
||||
|
||||
ptera->movefactor--;
|
||||
if (!ptera->movefactor)
|
||||
goto dropoff;
|
||||
|
||||
P_TryMove(player->mo, ptera->x, ptera->y, true);
|
||||
player->mo->momx = ptera->momx;
|
||||
player->mo->momy = ptera->momy;
|
||||
player->mo->momz = ptera->momz;
|
||||
|
||||
if (P_AproxDistance(player->mo->x - ptera->x, player->mo->y - ptera->y) > player->mo->radius)
|
||||
goto dropoff;
|
||||
|
||||
if (player->mo->state-states != S_PLAY_RIDE)
|
||||
P_SetPlayerMobjState(player->mo, S_PLAY_RIDE);
|
||||
break;
|
||||
|
||||
dropoff:
|
||||
player->powers[pw_carry] = CR_NONE;
|
||||
P_SetTarget(&player->mo->tracer, NULL);
|
||||
ptera->movefactor = TICRATE;
|
||||
ptera->extravalue1 |= 4;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue