mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2025-01-18 23:42:11 +00:00
Merge branch 'knuxtweaks' into 'next'
Knuckles tweaks See merge request STJr/SRB2!1030
This commit is contained in:
commit
9c1bee694b
9 changed files with 257 additions and 158 deletions
|
@ -50,6 +50,7 @@ typedef enum
|
|||
SF_NONIGHTSROTATION = 1<<14, // Disable sprite rotation for NiGHTS
|
||||
SF_NONIGHTSSUPER = 1<<15, // Disable super colors for NiGHTS (if you have SF_SUPER)
|
||||
SF_NOSUPERSPRITES = 1<<16, // Don't use super sprites while super
|
||||
SF_NOSUPERJUMPBOOST = 1<<17, // Disable the jump boost given while super (i.e. Knuckles)
|
||||
// free up to and including 1<<31
|
||||
} skinflags_t;
|
||||
|
||||
|
|
|
@ -9666,6 +9666,7 @@ struct {
|
|||
{"SF_NONIGHTSROTATION",SF_NONIGHTSROTATION},
|
||||
{"SF_NONIGHTSSUPER",SF_NONIGHTSSUPER},
|
||||
{"SF_NOSUPERSPRITES",SF_NOSUPERSPRITES},
|
||||
{"SF_NOSUPERJUMPBOOST",SF_NOSUPERJUMPBOOST},
|
||||
|
||||
// Dashmode constants
|
||||
{"DASHMODE_THRESHOLD",DASHMODE_THRESHOLD},
|
||||
|
|
12
src/info.c
12
src/info.c
|
@ -727,7 +727,7 @@ state_t states[NUMSTATES] =
|
|||
|
||||
// CA_GLIDEANDCLIMB
|
||||
{SPR_PLAY, SPR2_GLID, 2, {NULL}, 0, 0, S_PLAY_GLIDE}, // S_PLAY_GLIDE
|
||||
{SPR_PLAY, SPR2_LAND, 9, {NULL}, 0, 0, S_PLAY_STND}, // S_PLAY_GLIDE_LANDING
|
||||
{SPR_PLAY, SPR2_LAND, 7, {NULL}, 0, 0, S_PLAY_STND}, // S_PLAY_GLIDE_LANDING
|
||||
{SPR_PLAY, SPR2_CLNG|FF_ANIMATE, -1, {NULL}, 0, 4, S_NULL}, // S_PLAY_CLING
|
||||
{SPR_PLAY, SPR2_CLMB, 5, {NULL}, 0, 0, S_PLAY_CLIMB}, // S_PLAY_CLIMB
|
||||
|
||||
|
@ -2933,11 +2933,11 @@ state_t states[NUMSTATES] =
|
|||
{SPR_IVSP, FF_ANIMATE, 32, {NULL}, 31, 1, S_NULL}, // S_IVSP
|
||||
|
||||
// Super Sonic Spark
|
||||
{SPR_SSPK, 0, 2, {NULL}, 0, 0, S_SSPK2}, // S_SSPK1
|
||||
{SPR_SSPK, 1, 2, {NULL}, 0, 0, S_SSPK3}, // S_SSPK2
|
||||
{SPR_SSPK, 2, 2, {NULL}, 0, 0, S_SSPK4}, // S_SSPK3
|
||||
{SPR_SSPK, 1, 2, {NULL}, 0, 0, S_SSPK5}, // S_SSPK4
|
||||
{SPR_SSPK, 0, 2, {NULL}, 0, 0, S_NULL}, // S_SSPK5
|
||||
{SPR_SSPK, FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_SSPK2}, // S_SSPK1
|
||||
{SPR_SSPK, 1|FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_SSPK3}, // S_SSPK2
|
||||
{SPR_SSPK, 2|FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_SSPK4}, // S_SSPK3
|
||||
{SPR_SSPK, 1|FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_SSPK5}, // S_SSPK4
|
||||
{SPR_SSPK, FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_NULL}, // S_SSPK5
|
||||
|
||||
// Flicky-sized bubble
|
||||
{SPR_FBUB, 0, -1, {NULL}, 0, 0, S_NULL}, // S_FLICKY_BUBBLE
|
||||
|
|
|
@ -1259,6 +1259,19 @@ static int lib_pElementalFire(lua_State *L)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int lib_pSpawnSkidDust(lua_State *L)
|
||||
{
|
||||
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
|
||||
fixed_t radius = luaL_checkfixed(L, 2);
|
||||
boolean sound = lua_optboolean(L, 3);
|
||||
NOHUD
|
||||
INLEVEL
|
||||
if (!player)
|
||||
return LUA_ErrInvalid(L, "player_t");
|
||||
P_SpawnSkidDust(player, radius, sound);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lib_pDoPlayerFinish(lua_State *L)
|
||||
{
|
||||
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
|
||||
|
@ -1346,6 +1359,19 @@ static int lib_pNukeEnemies(lua_State *L)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int lib_pEarthquake(lua_State *L)
|
||||
{
|
||||
mobj_t *inflictor = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
|
||||
mobj_t *source = *((mobj_t **)luaL_checkudata(L, 2, META_MOBJ));
|
||||
fixed_t radius = luaL_checkfixed(L, 3);
|
||||
NOHUD
|
||||
INLEVEL
|
||||
if (!inflictor || !source)
|
||||
return LUA_ErrInvalid(L, "mobj_t");
|
||||
P_Earthquake(inflictor, source, radius);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lib_pHomingAttack(lua_State *L)
|
||||
{
|
||||
mobj_t *source = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
|
||||
|
@ -1554,11 +1580,12 @@ static int lib_pRadiusAttack(lua_State *L)
|
|||
mobj_t *source = *((mobj_t **)luaL_checkudata(L, 2, META_MOBJ));
|
||||
fixed_t damagedist = luaL_checkfixed(L, 3);
|
||||
UINT8 damagetype = luaL_optinteger(L, 4, 0);
|
||||
boolean sightcheck = lua_opttrueboolean(L, 5);
|
||||
NOHUD
|
||||
INLEVEL
|
||||
if (!spot || !source)
|
||||
return LUA_ErrInvalid(L, "mobj_t");
|
||||
P_RadiusAttack(spot, source, damagedist, damagetype);
|
||||
P_RadiusAttack(spot, source, damagedist, damagetype, sightcheck);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -3262,6 +3289,7 @@ static luaL_Reg lib[] = {
|
|||
{"P_DoBubbleBounce",lib_pDoBubbleBounce},
|
||||
{"P_BlackOw",lib_pBlackOw},
|
||||
{"P_ElementalFire",lib_pElementalFire},
|
||||
{"P_SpawnSkidDust", lib_pSpawnSkidDust},
|
||||
{"P_DoPlayerFinish",lib_pDoPlayerFinish},
|
||||
{"P_DoPlayerExit",lib_pDoPlayerExit},
|
||||
{"P_InstaThrust",lib_pInstaThrust},
|
||||
|
@ -3269,6 +3297,7 @@ static luaL_Reg lib[] = {
|
|||
{"P_ReturnThrustY",lib_pReturnThrustY},
|
||||
{"P_LookForEnemies",lib_pLookForEnemies},
|
||||
{"P_NukeEnemies",lib_pNukeEnemies},
|
||||
{"P_Earthquake",lib_pEarthquake},
|
||||
{"P_HomingAttack",lib_pHomingAttack},
|
||||
{"P_SuperReady",lib_pSuperReady},
|
||||
{"P_DoJump",lib_pDoJump},
|
||||
|
|
|
@ -3858,7 +3858,7 @@ void A_Explode(mobj_t *actor)
|
|||
if (LUA_CallAction("A_Explode", actor))
|
||||
return;
|
||||
|
||||
P_RadiusAttack(actor, actor->target, actor->info->damage, locvar1);
|
||||
P_RadiusAttack(actor, actor->target, actor->info->damage, locvar1, true);
|
||||
}
|
||||
|
||||
// Function: A_BossDeath
|
||||
|
@ -5639,7 +5639,7 @@ void A_MinusPopup(mobj_t *actor)
|
|||
P_SetObjectMomZ(rock, 3*FRACUNIT, false);
|
||||
P_SetScale(rock, rock->scale/3);
|
||||
}
|
||||
P_RadiusAttack(actor, actor, 2*actor->radius, 0);
|
||||
P_RadiusAttack(actor, actor, 2*actor->radius, 0, true);
|
||||
if (actor->tracer)
|
||||
P_DamageMobj(actor->tracer, actor, actor, 1, 0);
|
||||
|
||||
|
@ -11034,7 +11034,7 @@ void A_VileAttack(mobj_t *actor)
|
|||
actor->target->x - P_ReturnThrustX(fire, actor->angle, FixedMul(24*FRACUNIT, fire->scale)),
|
||||
actor->target->y - P_ReturnThrustY(fire, actor->angle, FixedMul(24*FRACUNIT, fire->scale)),
|
||||
fire->z);
|
||||
P_RadiusAttack(fire, actor, 70*FRACUNIT, 0);
|
||||
P_RadiusAttack(fire, actor, 70*FRACUNIT, 0, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -11079,7 +11079,7 @@ void A_VileAttack(mobj_t *actor)
|
|||
actor->target->x - P_ReturnThrustX(fire, actor->angle, FixedMul(24*FRACUNIT, fire->scale)),
|
||||
actor->target->y - P_ReturnThrustY(fire, actor->angle, FixedMul(24*FRACUNIT, fire->scale)),
|
||||
fire->z);
|
||||
P_RadiusAttack(fire, actor, 70*FRACUNIT, 0);
|
||||
P_RadiusAttack(fire, actor, 70*FRACUNIT, 0, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -12315,7 +12315,7 @@ void A_MineExplode(mobj_t *actor)
|
|||
quake.intensity = 8*FRACUNIT;
|
||||
quake.time = TICRATE/3;
|
||||
|
||||
P_RadiusAttack(actor, actor->tracer, 192*FRACUNIT, DMG_CANHURTSELF);
|
||||
P_RadiusAttack(actor, actor->tracer, 192*FRACUNIT, DMG_CANHURTSELF, true);
|
||||
P_MobjCheckWater(actor);
|
||||
|
||||
{
|
||||
|
@ -13316,7 +13316,7 @@ void A_Boss5BombExplode(mobj_t *actor)
|
|||
actor->flags2 = MF2_EXPLOSION;
|
||||
|
||||
if (actor->target)
|
||||
P_RadiusAttack(actor, actor->target, 7*actor->radius, 0);
|
||||
P_RadiusAttack(actor, actor->target, 7*actor->radius, 0, true);
|
||||
|
||||
P_DustRing(locvar1, 4, actor->x, actor->y, actor->z+actor->height, 2*actor->radius, 0, FRACUNIT, actor->scale);
|
||||
P_DustRing(locvar1, 6, actor->x, actor->y, actor->z+actor->height/2, 3*actor->radius, FRACUNIT, FRACUNIT, actor->scale);
|
||||
|
|
|
@ -175,6 +175,7 @@ void P_DoAbilityBounce(player_t *player, boolean changemomz);
|
|||
void P_TwinSpinRejuvenate(player_t *player, mobjtype_t type);
|
||||
void P_BlackOw(player_t *player);
|
||||
void P_ElementalFire(player_t *player, boolean cropcircle);
|
||||
void P_SpawnSkidDust(player_t *player, fixed_t radius, boolean sound);
|
||||
|
||||
void P_DoPityCheck(player_t *player);
|
||||
void P_PlayerThink(player_t *player);
|
||||
|
@ -192,6 +193,7 @@ mobj_t *P_LookForFocusTarget(player_t *player, mobj_t *exclude, SINT8 direction,
|
|||
|
||||
mobj_t *P_LookForEnemies(player_t *player, boolean nonenemies, boolean bullet);
|
||||
void P_NukeEnemies(mobj_t *inflictor, mobj_t *source, fixed_t radius);
|
||||
void P_Earthquake(mobj_t *inflictor, mobj_t *source, fixed_t radius);
|
||||
boolean P_HomingAttack(mobj_t *source, mobj_t *enemy); /// \todo doesn't belong in p_user
|
||||
boolean P_SuperReady(player_t *player);
|
||||
void P_DoJump(player_t *player, boolean soundandstate);
|
||||
|
@ -419,7 +421,7 @@ void P_DelPrecipSeclist(mprecipsecnode_t *node);
|
|||
void P_CreateSecNodeList(mobj_t *thing, fixed_t x, fixed_t y);
|
||||
void P_Initsecnode(void);
|
||||
|
||||
void P_RadiusAttack(mobj_t *spot, mobj_t *source, fixed_t damagedist, UINT8 damagetype);
|
||||
void P_RadiusAttack(mobj_t *spot, mobj_t *source, fixed_t damagedist, UINT8 damagetype, boolean sightcheck);
|
||||
|
||||
fixed_t P_FloorzAtPos(fixed_t x, fixed_t y, fixed_t z, fixed_t height);
|
||||
boolean PIT_PushableMoved(mobj_t *thing);
|
||||
|
|
23
src/p_map.c
23
src/p_map.c
|
@ -3391,8 +3391,13 @@ static void PTR_GlideClimbTraverse(line_t *li)
|
|||
|
||||
if (!slidemo->player->climbing)
|
||||
{
|
||||
S_StartSound(slidemo->player->mo, sfx_s3k4a);
|
||||
S_StartSound(slidemo, sfx_s3k4a);
|
||||
slidemo->player->climbing = 5;
|
||||
if (slidemo->player->powers[pw_super])
|
||||
{
|
||||
P_Earthquake(slidemo, slidemo, 256*FRACUNIT);
|
||||
S_StartSound(slidemo, sfx_s3k49);
|
||||
}
|
||||
}
|
||||
|
||||
slidemo->player->pflags &= ~(PF_GLIDING|PF_SPINNING|PF_JUMPED|PF_NOJUMPDAMAGE|PF_THOKKED);
|
||||
|
@ -4028,6 +4033,7 @@ static fixed_t bombdamage;
|
|||
static mobj_t *bombsource;
|
||||
static mobj_t *bombspot;
|
||||
static UINT8 bombdamagetype;
|
||||
static boolean bombsightcheck;
|
||||
|
||||
//
|
||||
// PIT_RadiusAttack
|
||||
|
@ -4041,10 +4047,16 @@ static boolean PIT_RadiusAttack(mobj_t *thing)
|
|||
if (thing == bombspot) // ignore the bomb itself (Deton fix)
|
||||
return true;
|
||||
|
||||
if ((thing->flags & (MF_MONITOR|MF_SHOOTABLE)) != MF_SHOOTABLE)
|
||||
if (bombsource && thing->type == bombsource->type && !(bombdamagetype & DMG_CANHURTSELF)) // ignore the type of guys who dropped the bomb (Jetty-Syn Bomber or Skim can bomb eachother, but not themselves.)
|
||||
return true;
|
||||
|
||||
if (bombsource && thing->type == bombsource->type && !(bombdamagetype & DMG_CANHURTSELF)) // ignore the type of guys who dropped the bomb (Jetty-Syn Bomber or Skim can bomb eachother, but not themselves.)
|
||||
if (thing->type == MT_MINUS && !(thing->flags & (MF_SPECIAL|MF_SHOOTABLE)) && !bombsightcheck)
|
||||
thing->flags = (thing->flags & ~MF_NOCLIPTHING)|MF_SPECIAL|MF_SHOOTABLE;
|
||||
|
||||
if (thing->type == MT_EGGGUARD && thing->tracer) //nuke Egg Guard's shield!
|
||||
P_KillMobj(thing->tracer, bombspot, bombsource, bombdamagetype);
|
||||
|
||||
if ((thing->flags & (MF_MONITOR|MF_SHOOTABLE)) != MF_SHOOTABLE)
|
||||
return true;
|
||||
|
||||
dx = abs(thing->x - bombspot->x);
|
||||
|
@ -4066,7 +4078,7 @@ static boolean PIT_RadiusAttack(mobj_t *thing)
|
|||
if (thing->ceilingz < bombspot->z && bombspot->floorz > thing->z)
|
||||
return true;
|
||||
|
||||
if (P_CheckSight(thing, bombspot))
|
||||
if (!bombsightcheck || P_CheckSight(thing, bombspot))
|
||||
{ // must be in direct path
|
||||
P_DamageMobj(thing, bombspot, bombsource, 1, bombdamagetype); // Tails 01-11-2001
|
||||
}
|
||||
|
@ -4078,7 +4090,7 @@ static boolean PIT_RadiusAttack(mobj_t *thing)
|
|||
// P_RadiusAttack
|
||||
// Source is the creature that caused the explosion at spot.
|
||||
//
|
||||
void P_RadiusAttack(mobj_t *spot, mobj_t *source, fixed_t damagedist, UINT8 damagetype)
|
||||
void P_RadiusAttack(mobj_t *spot, mobj_t *source, fixed_t damagedist, UINT8 damagetype, boolean sightcheck)
|
||||
{
|
||||
INT32 x, y;
|
||||
INT32 xl, xh, yl, yh;
|
||||
|
@ -4096,6 +4108,7 @@ void P_RadiusAttack(mobj_t *spot, mobj_t *source, fixed_t damagedist, UINT8 dama
|
|||
bombsource = source;
|
||||
bombdamage = FixedMul(damagedist, spot->scale);
|
||||
bombdamagetype = damagetype;
|
||||
bombsightcheck = sightcheck;
|
||||
|
||||
for (y = yl; y <= yh; y++)
|
||||
for (x = xl; x <= xh; x++)
|
||||
|
|
12
src/p_mobj.c
12
src/p_mobj.c
|
@ -211,10 +211,16 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state)
|
|||
return P_SetPlayerMobjState(mobj, S_PLAY_FALL);
|
||||
|
||||
// Catch swimming versus flying
|
||||
if (state == S_PLAY_FLY && player->mo->eflags & MFE_UNDERWATER)
|
||||
if ((state == S_PLAY_FLY || (state == S_PLAY_GLIDE && skins[player->skin].sprites[SPR2_SWIM].numframes))
|
||||
&& player->mo->eflags & MFE_UNDERWATER && !player->skidtime)
|
||||
return P_SetPlayerMobjState(player->mo, S_PLAY_SWIM);
|
||||
else if (state == S_PLAY_SWIM && !(player->mo->eflags & MFE_UNDERWATER))
|
||||
return P_SetPlayerMobjState(player->mo, S_PLAY_FLY);
|
||||
{
|
||||
if (player->charability == CA_GLIDEANDCLIMB)
|
||||
return P_SetPlayerMobjState(player->mo, S_PLAY_GLIDE);
|
||||
else
|
||||
return P_SetPlayerMobjState(player->mo, S_PLAY_FLY);
|
||||
}
|
||||
|
||||
// Catch SF_NOSUPERSPIN jumps for Supers
|
||||
if (player->powers[pw_super] && (player->charflags & SF_NOSUPERSPIN))
|
||||
|
@ -874,7 +880,7 @@ void P_ExplodeMissile(mobj_t *mo)
|
|||
|
||||
if (mo->type == MT_DETON)
|
||||
{
|
||||
P_RadiusAttack(mo, mo, 96*FRACUNIT, 0);
|
||||
P_RadiusAttack(mo, mo, 96*FRACUNIT, 0, true);
|
||||
|
||||
explodemo = P_SpawnMobj(mo->x, mo->y, mo->z, MT_EXPLODE);
|
||||
P_SetScale(explodemo, mo->scale);
|
||||
|
|
319
src/p_user.c
319
src/p_user.c
|
@ -2325,6 +2325,7 @@ boolean P_PlayerHitFloor(player_t *player, boolean dorollstuff)
|
|||
}
|
||||
else
|
||||
{
|
||||
P_MobjCheckWater(player->mo);
|
||||
if (player->pflags & PF_SPINNING)
|
||||
{
|
||||
if (player->mo->state-states != S_PLAY_ROLL && !(player->pflags & PF_STARTDASH))
|
||||
|
@ -2338,21 +2339,32 @@ boolean P_PlayerHitFloor(player_t *player, boolean dorollstuff)
|
|||
if (dorollstuff)
|
||||
{
|
||||
player->skidtime = TICRATE;
|
||||
P_SetPlayerMobjState(player->mo, S_PLAY_GLIDE);
|
||||
P_SpawnSkidDust(player, player->mo->radius, true); // make sure the player knows they landed
|
||||
player->mo->tics = -1;
|
||||
}
|
||||
else if (!player->skidtime)
|
||||
player->pflags &= ~PF_GLIDING;
|
||||
}
|
||||
else if (player->charability == CA_GLIDEANDCLIMB && player->pflags & PF_THOKKED && !(player->pflags & (PF_JUMPED|PF_SHIELDABILITY)) && player->mo->state-states == S_PLAY_FALL)
|
||||
else if (player->charability == CA_GLIDEANDCLIMB && player->pflags & PF_THOKKED && !(player->pflags & (PF_JUMPED|PF_SHIELDABILITY))
|
||||
&& (player->mo->floorz != player->mo->watertop) && player->mo->state-states == S_PLAY_FALL)
|
||||
{
|
||||
if (player->mo->state-states != S_PLAY_GLIDE_LANDING)
|
||||
{
|
||||
P_ResetPlayer(player);
|
||||
P_SetPlayerMobjState(player->mo, S_PLAY_GLIDE_LANDING);
|
||||
S_StartSound(player->mo, sfx_s3k4c);
|
||||
player->pflags |= PF_STASIS;
|
||||
player->mo->momx = ((player->mo->momx - player->cmomx)/3) + player->cmomx;
|
||||
player->mo->momy = ((player->mo->momy - player->cmomy)/3) + player->cmomy;
|
||||
if (player->speed > FixedMul(player->runspeed, player->mo->scale))
|
||||
player->skidtime += player->mo->tics;
|
||||
player->mo->momx = ((player->mo->momx - player->cmomx)/2) + player->cmomx;
|
||||
player->mo->momy = ((player->mo->momy - player->cmomy)/2) + player->cmomy;
|
||||
if (player->powers[pw_super])
|
||||
{
|
||||
P_Earthquake(player->mo, player->mo, 256*FRACUNIT);
|
||||
S_StartSound(player->mo, sfx_s3k49);
|
||||
}
|
||||
else
|
||||
S_StartSound(player->mo, sfx_s3k4c);
|
||||
}
|
||||
}
|
||||
else if (player->charability2 == CA2_MELEE
|
||||
|
@ -4448,7 +4460,7 @@ void P_DoJump(player_t *player, boolean soundandstate)
|
|||
}
|
||||
else if (maptol & TOL_NIGHTS)
|
||||
player->mo->momz = 18*FRACUNIT;
|
||||
else if (player->powers[pw_super])
|
||||
else if (player->powers[pw_super] && !(player->charflags & SF_NOSUPERJUMPBOOST))
|
||||
{
|
||||
player->mo->momz = 13*FRACUNIT;
|
||||
|
||||
|
@ -5347,9 +5359,12 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd)
|
|||
if (player->mo->eflags & MFE_UNDERWATER)
|
||||
{
|
||||
glidespeed >>= 1;
|
||||
playerspeed >>= 1;
|
||||
player->mo->momx = ((player->mo->momx - player->cmomx) >> 1) + player->cmomx;
|
||||
player->mo->momy = ((player->mo->momy - player->cmomy) >> 1) + player->cmomy;
|
||||
playerspeed = 2*playerspeed/3;
|
||||
if (!(player->powers[pw_super] || player->powers[pw_sneakers]))
|
||||
{
|
||||
player->mo->momx = (2*(player->mo->momx - player->cmomx)/3) + player->cmomx;
|
||||
player->mo->momy = (2*(player->mo->momy - player->cmomy)/3) + player->cmomy;
|
||||
}
|
||||
}
|
||||
|
||||
player->pflags |= PF_GLIDING|PF_THOKKED;
|
||||
|
@ -5776,7 +5791,7 @@ static void P_2dMovement(player_t *player)
|
|||
if (player->climbing)
|
||||
{
|
||||
if (cmd->forwardmove != 0)
|
||||
P_SetObjectMomZ(player->mo, FixedDiv(cmd->forwardmove*FRACUNIT, 15*FRACUNIT>>1), false);
|
||||
P_SetObjectMomZ(player->mo, FixedDiv(cmd->forwardmove*FRACUNIT, player->powers[pw_super] ? 5*FRACUNIT : 15*FRACUNIT>>1), false); // 2/3 while super
|
||||
|
||||
player->mo->momx = 0;
|
||||
}
|
||||
|
@ -5991,9 +6006,9 @@ static void P_3dMovement(player_t *player)
|
|||
if (cmd->forwardmove)
|
||||
{
|
||||
if (player->mo->eflags & MFE_UNDERWATER)
|
||||
P_SetObjectMomZ(player->mo, FixedDiv(cmd->forwardmove*FRACUNIT, 10*FRACUNIT), false);
|
||||
P_SetObjectMomZ(player->mo, FixedDiv(cmd->forwardmove*FRACUNIT, player->powers[pw_super] ? 20*FRACUNIT/3 : 10*FRACUNIT), false); // 2/3 while super
|
||||
else
|
||||
P_SetObjectMomZ(player->mo, FixedDiv(cmd->forwardmove*FRACUNIT, 15*FRACUNIT>>1), false);
|
||||
P_SetObjectMomZ(player->mo, FixedDiv(cmd->forwardmove*FRACUNIT, player->powers[pw_super] ? 5*FRACUNIT : 15*FRACUNIT>>1), false); // 2/3 while super
|
||||
}
|
||||
}
|
||||
else if (!(controlstyle == CS_LMAOGALOG)
|
||||
|
@ -6026,9 +6041,9 @@ static void P_3dMovement(player_t *player)
|
|||
if (player->climbing)
|
||||
{
|
||||
if (player->mo->eflags & MFE_UNDERWATER)
|
||||
P_InstaThrust(player->mo, player->mo->angle-ANGLE_90, FixedDiv(cmd->sidemove*player->mo->scale, 10*FRACUNIT));
|
||||
P_InstaThrust(player->mo, player->mo->angle-ANGLE_90, FixedDiv(cmd->sidemove*player->mo->scale, player->powers[pw_super] ? 20*FRACUNIT/3 : 10*FRACUNIT)); // 2/3 while super
|
||||
else
|
||||
P_InstaThrust(player->mo, player->mo->angle-ANGLE_90, FixedDiv(cmd->sidemove*player->mo->scale, 15*FRACUNIT>>1));
|
||||
P_InstaThrust(player->mo, player->mo->angle-ANGLE_90, FixedDiv(cmd->sidemove*player->mo->scale, player->powers[pw_super] ? 5*FRACUNIT : 15*FRACUNIT>>1)); // 2/3 while super
|
||||
}
|
||||
// Analog movement control
|
||||
else if (controlstyle == CS_LMAOGALOG)
|
||||
|
@ -7756,6 +7771,39 @@ void P_ElementalFire(player_t *player, boolean cropcircle)
|
|||
}
|
||||
}
|
||||
|
||||
//
|
||||
// P_SpawnSkidDust
|
||||
//
|
||||
// Spawns spindash dust randomly around the player within a certain radius.
|
||||
//
|
||||
void P_SpawnSkidDust(player_t *player, fixed_t radius, boolean sound)
|
||||
{
|
||||
mobj_t *mo = player->mo;
|
||||
mobj_t *particle;
|
||||
|
||||
particle = P_SpawnMobjFromMobj(mo, 0, 0, 0, MT_SPINDUST);
|
||||
if (radius >>= FRACBITS)
|
||||
{
|
||||
P_UnsetThingPosition(particle);
|
||||
particle->x += P_RandomRange(-radius, radius) << FRACBITS;
|
||||
particle->y += P_RandomRange(-radius, radius) << FRACBITS;
|
||||
P_SetThingPosition(particle);
|
||||
}
|
||||
particle->tics = 10;
|
||||
|
||||
particle->destscale = (2*mo->scale)/3;
|
||||
P_SetScale(particle, particle->destscale);
|
||||
P_SetObjectMomZ(particle, FRACUNIT, false);
|
||||
|
||||
if (mo->eflags & (MFE_TOUCHWATER|MFE_UNDERWATER)) // overrides fire version
|
||||
P_SetMobjState(particle, S_SPINDUST_BUBBLE1);
|
||||
else if (player->powers[pw_shield] == SH_ELEMENTAL)
|
||||
P_SetMobjState(particle, S_SPINDUST_FIRE1);
|
||||
|
||||
if (sound)
|
||||
S_StartSound(mo, sfx_s3k7e); // the proper "Knuckles eats dirt" sfx.
|
||||
}
|
||||
|
||||
static void P_SkidStuff(player_t *player)
|
||||
{
|
||||
fixed_t pmx = player->rmomx + player->cmomx;
|
||||
|
@ -7769,7 +7817,7 @@ static void P_SkidStuff(player_t *player)
|
|||
{
|
||||
player->skidtime = 0;
|
||||
player->pflags &= ~(PF_GLIDING|PF_JUMPED|PF_NOJUMPDAMAGE);
|
||||
player->pflags |= PF_THOKKED; // nice try, speedrunners (but for real this is just behavior from S3K)
|
||||
player->pflags |= PF_THOKKED;
|
||||
P_SetPlayerMobjState(player->mo, S_PLAY_FALL);
|
||||
}
|
||||
// Get up and brush yourself off, idiot.
|
||||
|
@ -7778,29 +7826,18 @@ static void P_SkidStuff(player_t *player)
|
|||
P_ResetPlayer(player);
|
||||
P_SetPlayerMobjState(player->mo, S_PLAY_GLIDE_LANDING);
|
||||
player->pflags |= PF_STASIS;
|
||||
player->mo->momx = ((player->mo->momx - player->cmomx)/3) + player->cmomx;
|
||||
player->mo->momy = ((player->mo->momy - player->cmomy)/3) + player->cmomy;
|
||||
if (player->speed > FixedMul(player->runspeed, player->mo->scale))
|
||||
player->skidtime += player->mo->tics;
|
||||
player->mo->momx = ((player->mo->momx - player->cmomx)/2) + player->cmomx;
|
||||
player->mo->momy = ((player->mo->momy - player->cmomy)/2) + player->cmomy;
|
||||
}
|
||||
// Didn't stop yet? Skid FOREVER!
|
||||
else if (player->skidtime == 1)
|
||||
player->skidtime = 3*TICRATE+1;
|
||||
// Spawn a particle every 3 tics.
|
||||
else if (!(player->skidtime % 3))
|
||||
else if (!(player->skidtime % 3) && !(player->charflags & SF_NOSKID))
|
||||
{
|
||||
fixed_t radius = player->mo->radius >> FRACBITS;
|
||||
mobj_t *particle = P_SpawnMobjFromMobj(player->mo, P_RandomRange(-radius, radius) << FRACBITS, P_RandomRange(-radius, radius) << FRACBITS, 0, MT_SPINDUST);
|
||||
particle->tics = 10;
|
||||
|
||||
particle->destscale = (2*player->mo->scale)/3;
|
||||
P_SetScale(particle, particle->destscale);
|
||||
P_SetObjectMomZ(particle, FRACUNIT, false);
|
||||
|
||||
if (player->mo->eflags & (MFE_TOUCHWATER|MFE_UNDERWATER)) // overrides fire version
|
||||
P_SetMobjState(particle, S_SPINDUST_BUBBLE1);
|
||||
else if (player->powers[pw_shield] == SH_ELEMENTAL)
|
||||
P_SetMobjState(particle, S_SPINDUST_FIRE1);
|
||||
|
||||
S_StartSound(player->mo, sfx_s3k7e); // the proper "Knuckles eats dirt" sfx.
|
||||
P_SpawnSkidDust(player, player->mo->radius, true);
|
||||
}
|
||||
}
|
||||
// Skidding!
|
||||
|
@ -7811,17 +7848,10 @@ static void P_SkidStuff(player_t *player)
|
|||
// Spawn a particle every 3 tics.
|
||||
if (!(player->skidtime % 3))
|
||||
{
|
||||
mobj_t *particle = P_SpawnMobjFromMobj(player->mo, 0, 0, 0, MT_SPINDUST);
|
||||
particle->tics = 10;
|
||||
|
||||
particle->destscale = (2*player->mo->scale)/3;
|
||||
P_SetScale(particle, particle->destscale);
|
||||
P_SetObjectMomZ(particle, FRACUNIT, false);
|
||||
|
||||
if (player->mo->eflags & (MFE_TOUCHWATER|MFE_UNDERWATER)) // overrides fire version
|
||||
P_SetMobjState(particle, S_SPINDUST_BUBBLE1);
|
||||
else if (player->powers[pw_shield] == SH_ELEMENTAL)
|
||||
P_SetMobjState(particle, S_SPINDUST_FIRE1);
|
||||
if (player->mo->state-states == S_PLAY_GLIDE_LANDING)
|
||||
P_SpawnSkidDust(player, player->mo->radius, true);
|
||||
else
|
||||
P_SpawnSkidDust(player, 0, false);
|
||||
}
|
||||
}
|
||||
else if (P_AproxDistance(pmx, pmy) >= FixedMul(player->runspeed/2, player->mo->scale) // if you were moving faster than half your run speed last frame
|
||||
|
@ -8182,10 +8212,11 @@ static void P_MovePlayer(player_t *player)
|
|||
if (player->pflags & PF_GLIDING)
|
||||
{
|
||||
mobj_t *mo = player->mo; // seriously why isn't this at the top of the function hngngngng
|
||||
fixed_t leeway = (P_ControlStyle(player) != CS_LMAOGALOG) ? FixedAngle(cmd->sidemove*(FRACUNIT)) : 0;
|
||||
fixed_t glidespeed = player->actionspd;
|
||||
fixed_t momx = mo->momx - player->cmomx, momy = mo->momy - player->cmomy;
|
||||
angle_t angle, moveangle = R_PointToAngle2(0, 0, momx, momy);
|
||||
boolean swimming = mo->state - states == S_PLAY_SWIM;
|
||||
boolean in2d = mo->flags2 & MF2_TWOD || twodlevel;
|
||||
|
||||
if (player->powers[pw_super] || player->powers[pw_sneakers])
|
||||
glidespeed *= 2;
|
||||
|
@ -8202,42 +8233,82 @@ static void P_MovePlayer(player_t *player)
|
|||
}
|
||||
|
||||
// Strafing while gliding.
|
||||
angle = mo->angle - leeway;
|
||||
if ((P_ControlStyle(player) & CS_LMAOGALOG) || in2d)
|
||||
angle = mo->angle;
|
||||
else if (swimming)
|
||||
angle = mo->angle + R_PointToAngle2(0, 0, cmd->forwardmove<<FRACBITS, -cmd->sidemove<<FRACBITS);
|
||||
else
|
||||
angle = mo->angle - FixedAngle(cmd->sidemove * FRACUNIT);
|
||||
|
||||
if (!player->skidtime) // TODO: make sure this works in 2D!
|
||||
{
|
||||
angle_t anglediff = angle - moveangle;
|
||||
fixed_t accelfactor = 4*FRACUNIT - 3*FINECOSINE((anglediff >> ANGLETOFINESHIFT) & FINEMASK);
|
||||
fixed_t speed, scale = mo->scale;
|
||||
fixed_t newMagnitude, oldMagnitude = R_PointToDist2(momx, momy, 0, 0);
|
||||
fixed_t accelfactor = 4*FRACUNIT - 3*FINECOSINE(((angle-moveangle) >> ANGLETOFINESHIFT) & FINEMASK); // mamgic number BAD but this feels right
|
||||
|
||||
if (mo->eflags & MFE_UNDERWATER)
|
||||
speed = FixedMul((glidespeed>>1) + player->glidetime*750, scale);
|
||||
else
|
||||
speed = FixedMul(glidespeed + player->glidetime*1500, scale);
|
||||
|
||||
P_Thrust(mo, angle, FixedMul(accelfactor, scale));
|
||||
|
||||
newMagnitude = R_PointToDist2(player->mo->momx - player->cmomx, player->mo->momy - player->cmomy, 0, 0);
|
||||
if (newMagnitude > speed)
|
||||
if (in2d)
|
||||
{
|
||||
fixed_t tempmomx, tempmomy;
|
||||
if (oldMagnitude > speed)
|
||||
if (mo->eflags & MFE_UNDERWATER)
|
||||
speed = FixedMul((glidespeed>>1) + player->glidetime*750, scale);
|
||||
else
|
||||
speed = FixedMul(glidespeed + player->glidetime*1500, scale);
|
||||
P_InstaThrust(mo, angle, speed);
|
||||
}
|
||||
else if (swimming)
|
||||
{
|
||||
fixed_t minspeed;
|
||||
|
||||
if (anglediff > ANGLE_180)
|
||||
anglediff = InvAngle(InvAngle(anglediff) >> 3);
|
||||
else
|
||||
anglediff = anglediff >> 3;
|
||||
|
||||
minspeed = FixedMul((glidespeed>>1) + player->glidetime*750, scale); // underwater-specific
|
||||
speed = FixedHypot(momx, momy) - abs(P_ReturnThrustY(mo, anglediff, mo->scale));
|
||||
|
||||
if (speed < minspeed)
|
||||
{
|
||||
if (newMagnitude > oldMagnitude)
|
||||
momx += P_ReturnThrustX(mo, angle, FixedMul(accelfactor, scale));
|
||||
momy += P_ReturnThrustY(mo, angle, FixedMul(accelfactor, scale));
|
||||
speed = FixedHypot(momx, momy); // recalculate speed
|
||||
}
|
||||
|
||||
mo->momx = P_ReturnThrustX(mo, moveangle + anglediff, speed) + player->cmomx;
|
||||
mo->momy = P_ReturnThrustY(mo, moveangle + anglediff, speed) + player->cmomy;
|
||||
}
|
||||
else
|
||||
{
|
||||
fixed_t newMagnitude, oldMagnitude = R_PointToDist2(momx, momy, 0, 0);
|
||||
|
||||
if (mo->eflags & MFE_UNDERWATER)
|
||||
speed = FixedMul((glidespeed>>1) + player->glidetime*750, scale);
|
||||
else
|
||||
speed = FixedMul(glidespeed + player->glidetime*1500, scale);
|
||||
|
||||
P_Thrust(mo, angle, FixedMul(accelfactor, scale));
|
||||
|
||||
newMagnitude = R_PointToDist2(player->mo->momx - player->cmomx, player->mo->momy - player->cmomy, 0, 0);
|
||||
if (newMagnitude > speed)
|
||||
{
|
||||
fixed_t tempmomx, tempmomy;
|
||||
if (oldMagnitude > speed)
|
||||
{
|
||||
tempmomx = FixedMul(FixedDiv(player->mo->momx - player->cmomx, newMagnitude), oldMagnitude);
|
||||
tempmomy = FixedMul(FixedDiv(player->mo->momy - player->cmomy, newMagnitude), oldMagnitude);
|
||||
if (newMagnitude > oldMagnitude)
|
||||
{
|
||||
tempmomx = FixedMul(FixedDiv(player->mo->momx - player->cmomx, newMagnitude), oldMagnitude);
|
||||
tempmomy = FixedMul(FixedDiv(player->mo->momy - player->cmomy, newMagnitude), oldMagnitude);
|
||||
player->mo->momx = tempmomx + player->cmomx;
|
||||
player->mo->momy = tempmomy + player->cmomy;
|
||||
}
|
||||
// else do nothing
|
||||
}
|
||||
else
|
||||
{
|
||||
tempmomx = FixedMul(FixedDiv(player->mo->momx - player->cmomx, newMagnitude), speed);
|
||||
tempmomy = FixedMul(FixedDiv(player->mo->momy - player->cmomy, newMagnitude), speed);
|
||||
player->mo->momx = tempmomx + player->cmomx;
|
||||
player->mo->momy = tempmomy + player->cmomy;
|
||||
}
|
||||
// else do nothing
|
||||
}
|
||||
else
|
||||
{
|
||||
tempmomx = FixedMul(FixedDiv(player->mo->momx - player->cmomx, newMagnitude), speed);
|
||||
tempmomy = FixedMul(FixedDiv(player->mo->momy - player->cmomy, newMagnitude), speed);
|
||||
player->mo->momx = tempmomx + player->cmomx;
|
||||
player->mo->momy = tempmomy + player->cmomy;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -8553,6 +8624,7 @@ static void P_MovePlayer(player_t *player)
|
|||
|| ((player->pflags & PF_JUMPED) && !(player->pflags & PF_NOJUMPDAMAGE))
|
||||
|| (player->pflags & PF_SPINNING)
|
||||
|| player->powers[pw_tailsfly] || player->pflags & PF_GLIDING
|
||||
|| (player->charability == CA_GLIDEANDCLIMB && player->mo->state-states == S_PLAY_GLIDE_LANDING)
|
||||
|| (player->charability == CA_FLY && player->mo->state-states == S_PLAY_FLY_TIRED))
|
||||
player->mo->height = P_GetPlayerSpinHeight(player);
|
||||
else
|
||||
|
@ -8618,74 +8690,6 @@ static void P_MovePlayer(player_t *player)
|
|||
if (CheckForBustableBlocks)
|
||||
P_CheckBustableBlocks(player);
|
||||
|
||||
// Special handling for
|
||||
// gliding in 2D mode
|
||||
if ((twodlevel || player->mo->flags2 & MF2_TWOD) && player->pflags & PF_GLIDING && player->charability == CA_GLIDEANDCLIMB
|
||||
&& !(player->mo->flags & MF_NOCLIP))
|
||||
{
|
||||
msecnode_t *node; // only place it's being used in P_MovePlayer now
|
||||
fixed_t oldx;
|
||||
fixed_t oldy;
|
||||
fixed_t floorz, ceilingz;
|
||||
|
||||
oldx = player->mo->x;
|
||||
oldy = player->mo->y;
|
||||
|
||||
P_UnsetThingPosition(player->mo);
|
||||
player->mo->x += player->mo->momx;
|
||||
player->mo->y += player->mo->momy;
|
||||
P_SetThingPosition(player->mo);
|
||||
|
||||
for (node = player->mo->touching_sectorlist; node; node = node->m_sectorlist_next)
|
||||
{
|
||||
if (!node->m_sector)
|
||||
break;
|
||||
|
||||
if (node->m_sector->ffloors)
|
||||
{
|
||||
ffloor_t *rover;
|
||||
fixed_t topheight, bottomheight;
|
||||
|
||||
for (rover = node->m_sector->ffloors; rover; rover = rover->next)
|
||||
{
|
||||
if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_BLOCKPLAYER))
|
||||
continue;
|
||||
|
||||
topheight = P_GetFOFTopZ(player->mo, node->m_sector, rover, player->mo->x, player->mo->y, NULL);
|
||||
bottomheight = P_GetFOFBottomZ(player->mo, node->m_sector, rover, player->mo->x, player->mo->y, NULL);
|
||||
if (topheight > player->mo->z && bottomheight < player->mo->z)
|
||||
{
|
||||
P_ResetPlayer(player);
|
||||
S_StartSound(player->mo, sfx_s3k4a);
|
||||
player->climbing = 5;
|
||||
player->mo->momx = player->mo->momy = player->mo->momz = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
floorz = P_GetFloorZ(player->mo, node->m_sector, player->mo->x, player->mo->y, NULL);
|
||||
ceilingz = P_GetCeilingZ(player->mo, node->m_sector, player->mo->x, player->mo->y, NULL);
|
||||
|
||||
if (player->mo->z+player->mo->height > ceilingz
|
||||
&& node->m_sector->ceilingpic == skyflatnum)
|
||||
continue;
|
||||
|
||||
if (floorz > player->mo->z || ceilingz < player->mo->z)
|
||||
{
|
||||
P_ResetPlayer(player);
|
||||
S_StartSound(player->mo, sfx_s3k4a);
|
||||
player->climbing = 5;
|
||||
player->mo->momx = player->mo->momy = player->mo->momz = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
P_UnsetThingPosition(player->mo);
|
||||
player->mo->x = oldx;
|
||||
player->mo->y = oldy;
|
||||
P_SetThingPosition(player->mo);
|
||||
}
|
||||
|
||||
// Check for a BOUNCY sector!
|
||||
if (CheckForBouncySector)
|
||||
P_CheckBouncySectors(player);
|
||||
|
@ -8991,6 +8995,49 @@ void P_NukeEnemies(mobj_t *inflictor, mobj_t *source, fixed_t radius)
|
|||
}
|
||||
}
|
||||
|
||||
//
|
||||
// P_Earthquake
|
||||
// Used for Super Knuckles' landing - damages enemies within the given radius
|
||||
//
|
||||
void P_Earthquake(mobj_t *inflictor, mobj_t *source, fixed_t radius)
|
||||
{
|
||||
const fixed_t scaledradius = FixedMul(radius, inflictor->scale);
|
||||
const fixed_t ns = scaledradius/12;
|
||||
mobj_t *mo;
|
||||
angle_t fa;
|
||||
INT32 i;
|
||||
boolean grounded = P_IsObjectOnGround(inflictor);
|
||||
|
||||
for (i = 0; i < 16; i++)
|
||||
{
|
||||
fa = (i*(FINEANGLES/16));
|
||||
mo = P_SpawnMobjFromMobj(inflictor, 0, 0, 0, MT_SUPERSPARK);
|
||||
if (!P_MobjWasRemoved(mo))
|
||||
{
|
||||
if (grounded)
|
||||
{
|
||||
mo->momx = FixedMul(FINESINE(fa),ns);
|
||||
mo->momy = FixedMul(FINECOSINE(fa),ns);
|
||||
}
|
||||
else
|
||||
{
|
||||
P_InstaThrust(mo, inflictor->angle + ANGLE_90, FixedMul(FINECOSINE(fa),ns));
|
||||
mo->momz = FixedMul(FINESINE(fa),ns);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (inflictor->player && P_IsLocalPlayer(inflictor->player))
|
||||
{
|
||||
quake.epicenter = NULL;
|
||||
quake.intensity = 8*inflictor->scale;
|
||||
quake.time = 8;
|
||||
quake.radius = scaledradius;
|
||||
}
|
||||
|
||||
P_RadiusAttack(inflictor, source, radius, 0, false);
|
||||
}
|
||||
|
||||
//
|
||||
// P_LookForFocusTarget
|
||||
// Looks for a target for a player to focus on, for Z-targeting etc.
|
||||
|
|
Loading…
Reference in a new issue