Merge branch 'tripwire' into 'master'

Tripwire

See merge request KartKrew/Kart!462
This commit is contained in:
James R 2021-11-29 03:20:56 +00:00
commit 0fad5f5a23
13 changed files with 131 additions and 22 deletions

View file

@ -198,6 +198,13 @@ typedef enum
#undef KSPIN_TYPE
} kartspinoutflags_t;
typedef enum
{
TRIP_NONE,
TRIP_PASSED,
TRIP_BLOCKED,
} tripwirestate_t;
typedef enum
{
// Unsynced, HUD or clientsided effects
@ -470,6 +477,8 @@ typedef struct player_s
SINT8 glanceDir; // Direction the player is trying to look backwards in
UINT8 tripWireState; // see tripwirestate_t
//
SINT8 lives;

View file

@ -2287,6 +2287,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
p->karthud[khud_fault] = khudfault;
p->nocontrol = nocontrol;
p->kickstartaccel = kickstartaccel;
p->tripWireState = TRIP_NONE;
memcpy(&p->respawn, &respawn, sizeof (p->respawn));

View file

@ -1478,7 +1478,8 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
transnum_t transtable = R_GetLinedefTransTable(gl_linedef);
if (transtable == NUMTRANSMAPS)
transtable = 0;
if (gl_linedef->special == 910)
if (gl_linedef->special == 910 ||
P_IsLineTripWire(gl_linedef))
blend = AST_ADD;
else if (gl_linedef->special == 911)
blend = AST_SUBTRACT;

View file

@ -2673,6 +2673,19 @@ boolean K_SlopeResistance(player_t *player)
return false;
}
boolean K_TripwirePass(player_t *player)
{
if (
player->invincibilitytimer ||
player->sneakertimer ||
player->growshrinktimer > 0 ||
player->flamedash ||
player->speed > 2 * K_GetKartSpeed(player, false)
)
return true;
return false;
}
static fixed_t K_FlameShieldDashVar(INT32 val)
{
// 1 second = 75% + 50% top speed
@ -3197,10 +3210,18 @@ void K_TumblePlayer(player_t *player, mobj_t *inflictor, mobj_t *source)
player->tumbleBounces = 1;
player->mo->momx = 2 * player->mo->momx / 3;
player->mo->momy = 2 * player->mo->momy / 3;
if (player->tripWireState == TRIP_PASSED)
{
player->tumbleHeight = 50;
}
else
{
player->mo->momx = 2 * player->mo->momx / 3;
player->mo->momy = 2 * player->mo->momy / 3;
player->tumbleHeight = 30;
}
player->tumbleHeight = 30;
player->pflags &= ~PF_TUMBLESOUND;
if (inflictor && !P_MobjWasRemoved(inflictor))
@ -3300,6 +3321,23 @@ static void K_HandleTumbleSound(player_t *player)
}
}
void K_ApplyTripWire(player_t *player, tripwirestate_t state)
{
if (state == TRIP_PASSED)
S_StartSound(player->mo, sfx_ssa015);
else if (state == TRIP_BLOCKED)
S_StartSound(player->mo, sfx_kc40);
player->tripWireState = state;
K_AddHitLag(player->mo, 10, false);
if (state == TRIP_PASSED && player->spinouttimer &&
player->speed > 2* K_GetKartSpeed(player, false))
{
K_TumblePlayer(player, NULL, NULL);
}
}
INT32 K_ExplodePlayer(player_t *player, mobj_t *inflictor, mobj_t *source) // A bit of a hack, we just throw the player up higher here and extend their spinout timer
{
INT32 ringburst = 10;
@ -6983,6 +7021,16 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
// Handle invincibility sfx
K_UpdateInvincibilitySounds(player); // Also thanks, VAda!
if (player->tripWireState != TRIP_NONE)
{
if (player->tripWireState == TRIP_PASSED)
S_StartSound(player->mo, sfx_cdfm63);
else if (player->tripWireState == TRIP_BLOCKED)
S_StartSound(player->mo, sfx_kc4c);
player->tripWireState = TRIP_NONE;
}
}
void K_KartPlayerAfterThink(player_t *player)

View file

@ -105,6 +105,8 @@ void K_StripOther(player_t *player);
void K_MomentumToFacing(player_t *player);
boolean K_ApplyOffroad(player_t *player);
boolean K_SlopeResistance(player_t *player);
boolean K_TripwirePass(player_t *player);
void K_ApplyTripWire(player_t *player, tripwirestate_t state);
INT16 K_GetSpindashChargeTime(player_t *player);
fixed_t K_GetSpindashChargeSpeed(player_t *player);
fixed_t K_GetKartSpeedFromStat(UINT8 kartspeed);

View file

@ -398,6 +398,7 @@ void P_SetThingPosition(mobj_t *thing);
void P_SetUnderlayPosition(mobj_t *thing);
boolean P_IsLineBlocking(const line_t *ld, const mobj_t *thing);
boolean P_IsLineTripWire(const line_t *ld);
boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y);
boolean P_CheckCameraPosition(fixed_t x, fixed_t y, camera_t *thiscam);
boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff);

View file

@ -206,11 +206,14 @@ static void add_spechit(line_t *ld)
numspechit++;
}
static boolean P_SpecialIsLinedefCrossType(UINT16 ldspecial)
static boolean P_SpecialIsLinedefCrossType(line_t *ld)
{
boolean linedefcrossspecial = false;
switch (ldspecial)
if (P_IsLineTripWire(ld))
return true;
switch (ld->special)
{
case 2001: // Finish line
case 2003: // Respawn line
@ -1552,6 +1555,11 @@ boolean P_IsLineBlocking(const line_t *ld, const mobj_t *thing)
}
}
boolean P_IsLineTripWire(const line_t *ld)
{
return ld->tripwire;
}
//
// PIT_CheckLine
// Adjusts tmfloorz and tmceilingz as lines are contacted
@ -1666,7 +1674,7 @@ static boolean PIT_CheckLine(line_t *ld)
tmdropoffz = lowfloor;
// we've crossed the line
if (P_SpecialIsLinedefCrossType(ld->special))
if (P_SpecialIsLinedefCrossType(ld))
{
add_spechit(ld);
}
@ -2660,10 +2668,7 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
oldside = P_PointOnLineSide(oldx, oldy, ld);
if (side != oldside)
{
if (ld->special)
{
P_CrossSpecialLine(ld, oldside, thing);
}
P_CrossSpecialLine(ld, oldside, thing);
}
}
}
@ -2745,7 +2750,7 @@ static boolean PTR_GetSpecialLines(intercept_t *in)
return true;
}
if (P_SpecialIsLinedefCrossType(ld->special))
if (P_SpecialIsLinedefCrossType(ld))
{
add_spechit(ld);
}
@ -2815,10 +2820,7 @@ void P_HitSpecialLines(mobj_t *thing, fixed_t x, fixed_t y, fixed_t momx, fixed_
oldside = P_PointOnLineSide(x, y, ld);
if (side != oldside)
{
if (ld->special)
{
P_CrossSpecialLine(ld, oldside, thing);
}
P_CrossSpecialLine(ld, oldside, thing);
}
}
}
@ -3022,6 +3024,7 @@ static void P_PlayerHitBounceLine(line_t *ld)
INT32 side;
angle_t lineangle;
fixed_t movelen;
fixed_t x, y;
side = P_PointOnLineSide(slidemo->x, slidemo->y, ld);
lineangle = R_PointToAngle2(0, 0, ld->dx, ld->dy)-ANGLE_90;
@ -3036,8 +3039,19 @@ static void P_PlayerHitBounceLine(line_t *ld)
if (slidemo->player && movelen < (15*mapobjectscale))
movelen = (15*mapobjectscale);
tmxmove += FixedMul(movelen, FINECOSINE(lineangle));
tmymove += FixedMul(movelen, FINESINE(lineangle));
x = FixedMul(movelen, FINECOSINE(lineangle));
y = FixedMul(movelen, FINESINE(lineangle));
if (P_IsLineTripWire(ld))
{
tmxmove = x * 4;
tmymove = y * 4;
}
else
{
tmxmove += x;
tmymove += y;
}
}
//
@ -3675,6 +3689,11 @@ void P_BouncePlayerMove(mobj_t *mo)
tmymove = FixedMul(mmomy, (FRACUNIT - (FRACUNIT>>2) - (FRACUNIT>>3)));
}
if (P_IsLineTripWire(bestslideline))
{
K_ApplyTripWire(mo->player, TRIP_BLOCKED);
}
else
{
mobj_t *fx = P_SpawnMobj(mo->x, mo->y, mo->z, MT_BUMP);
if (mo->eflags & MFE_VERTICALFLIP)
@ -3694,8 +3713,11 @@ void P_BouncePlayerMove(mobj_t *mo)
mo->player->cmomx = tmxmove;
mo->player->cmomy = tmymove;
if (!P_TryMove(mo, mo->x + tmxmove, mo->y + tmymove, true)) {
P_TryMove(mo, mo->x - oldmomx, mo->y - oldmomy, true);
if (!P_IsLineTripWire(bestslideline))
{
if (!P_TryMove(mo, mo->x + tmxmove, mo->y + tmymove, true)) {
P_TryMove(mo, mo->x - oldmomx, mo->y - oldmomy, true);
}
}
}

View file

@ -15,6 +15,7 @@
#include "doomdef.h"
#include "doomstat.h"
#include "k_kart.h"
#include "p_local.h"
#include "r_main.h"
#include "r_data.h"
@ -588,7 +589,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
if (mobj)
{
// Check for collision with front side's midtexture if Effect 4 is set
if (linedef->flags & ML_EFFECT4
if ((linedef->flags & ML_EFFECT4 || (mobj->player && P_IsLineTripWire(linedef) && !K_TripwirePass(mobj->player)))
&& !linedef->polyobj // don't do anything for polyobjects! ...for now
) {
side_t *side = &sides[linedef->sidenum[0]];

View file

@ -318,6 +318,7 @@ static void P_NetArchivePlayers(void)
WRITEINT16(save_p, players[i].spheres);
WRITESINT8(save_p, players[i].glanceDir);
WRITEUINT8(save_p, players[i].tripWireState);
WRITEUINT8(save_p, players[i].typing_timer);
WRITEUINT8(save_p, players[i].typing_duration);
@ -573,6 +574,7 @@ static void P_NetUnArchivePlayers(void)
players[i].spheres = READINT16(save_p);
players[i].glanceDir = READSINT8(save_p);
players[i].tripWireState = READUINT8(save_p);
players[i].typing_timer = READUINT8(save_p);
players[i].typing_duration = READUINT8(save_p);

View file

@ -1044,6 +1044,8 @@ static void P_InitializeLinedef(line_t *ld)
ld->validcount = 0;
ld->polyobj = NULL;
ld->tripwire = false;
ld->text = NULL;
ld->callcount = 0;
@ -1936,11 +1938,23 @@ static void P_ProcessLinedefsAfterSidedefs(void)
{
size_t i = numlines;
register line_t *ld = lines;
const INT32 TEX_TRIPWIRE = R_TextureNumForName("TRIPWIRE");
const INT32 TEX_4RIPWIRE = R_TextureNumForName("4RIPWIRE");
for (; i--; ld++)
{
INT32 midtexture = sides[ld->sidenum[0]].midtexture;
ld->frontsector = sides[ld->sidenum[0]].sector; //e6y: Can't be -1 here
ld->backsector = ld->sidenum[1] != 0xffff ? sides[ld->sidenum[1]].sector : 0;
if (midtexture == TEX_TRIPWIRE ||
midtexture == TEX_4RIPWIRE)
{
ld->tripwire = true;
}
switch (ld->special)
{
// Compile linedef 'text' from both sidedefs 'text' for appropriate specials.

View file

@ -2018,6 +2018,12 @@ void P_CrossSpecialLine(line_t *line, INT32 side, mobj_t *thing)
return;
{
player_t *player = thing->player;
if (P_IsLineTripWire(line))
{
K_ApplyTripWire(player, TRIP_PASSED);
}
switch (line->special)
{
case 2001: // Finish Line

View file

@ -420,6 +420,8 @@ typedef struct line_s
size_t validcount; // if == validcount, already checked
polyobj_t *polyobj; // Belongs to a polyobject?
boolean tripwire;
char *text; // a concatenation of all front and back texture names, for linedef specials that require a string.
INT16 callcount; // no. of calls left before triggering, for the "X calls" linedef specials, defaults to 0
} line_t;

View file

@ -162,7 +162,7 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2)
return;
transtable = R_GetLinedefTransTable(ldef);
if (ldef->special == 910)
if (ldef->special == 910 || P_IsLineTripWire(ldef))
{
if (transtable == NUMTRANSMAPS)
transtable = 0;