mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2025-10-30 08:01:28 +00:00
Merge branch 'sal-waypoints' into 'waypoints'
Sal edits to waypoints See merge request KartKrew/Kart!202
This commit is contained in:
commit
aeb6567b53
21 changed files with 11147 additions and 10463 deletions
|
|
@ -1886,8 +1886,6 @@ void SendWeaponPref(void)
|
||||||
buf[0] = 0;
|
buf[0] = 0;
|
||||||
if (cv_flipcam.value)
|
if (cv_flipcam.value)
|
||||||
buf[0] |= 1;
|
buf[0] |= 1;
|
||||||
if (cv_analog.value)
|
|
||||||
buf[0] |= 2;
|
|
||||||
SendNetXCmd(XD_WEAPONPREF, buf, 1);
|
SendNetXCmd(XD_WEAPONPREF, buf, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1898,8 +1896,6 @@ void SendWeaponPref2(void)
|
||||||
buf[0] = 0;
|
buf[0] = 0;
|
||||||
if (cv_flipcam2.value)
|
if (cv_flipcam2.value)
|
||||||
buf[0] |= 1;
|
buf[0] |= 1;
|
||||||
if (cv_analog2.value)
|
|
||||||
buf[0] |= 2;
|
|
||||||
SendNetXCmd2(XD_WEAPONPREF, buf, 1);
|
SendNetXCmd2(XD_WEAPONPREF, buf, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1910,8 +1906,6 @@ void SendWeaponPref3(void)
|
||||||
buf[0] = 0;
|
buf[0] = 0;
|
||||||
if (cv_flipcam3.value)
|
if (cv_flipcam3.value)
|
||||||
buf[0] |= 1;
|
buf[0] |= 1;
|
||||||
if (cv_analog3.value)
|
|
||||||
buf[0] |= 2;
|
|
||||||
SendNetXCmd3(XD_WEAPONPREF, buf, 1);
|
SendNetXCmd3(XD_WEAPONPREF, buf, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1922,8 +1916,6 @@ void SendWeaponPref4(void)
|
||||||
buf[0] = 0;
|
buf[0] = 0;
|
||||||
if (cv_flipcam4.value)
|
if (cv_flipcam4.value)
|
||||||
buf[0] |= 1;
|
buf[0] |= 1;
|
||||||
if (cv_analog4.value)
|
|
||||||
buf[0] |= 2;
|
|
||||||
SendNetXCmd4(XD_WEAPONPREF, buf, 1);
|
SendNetXCmd4(XD_WEAPONPREF, buf, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1931,11 +1923,9 @@ static void Got_WeaponPref(UINT8 **cp,INT32 playernum)
|
||||||
{
|
{
|
||||||
UINT8 prefs = READUINT8(*cp);
|
UINT8 prefs = READUINT8(*cp);
|
||||||
|
|
||||||
players[playernum].pflags &= ~(PF_FLIPCAM|PF_ANALOGMODE);
|
players[playernum].pflags &= ~(PF_FLIPCAM);
|
||||||
if (prefs & 1)
|
if (prefs & 1)
|
||||||
players[playernum].pflags |= PF_FLIPCAM;
|
players[playernum].pflags |= PF_FLIPCAM;
|
||||||
if (prefs & 2)
|
|
||||||
players[playernum].pflags |= PF_ANALOGMODE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Got_PowerLevel(UINT8 **cp,INT32 playernum)
|
static void Got_PowerLevel(UINT8 **cp,INT32 playernum)
|
||||||
|
|
@ -2857,13 +2847,15 @@ static void Got_Respawn(UINT8 **cp, INT32 playernum)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// incase the above checks were modified to allow sending a respawn on these occasions:
|
|
||||||
if (players[respawnplayer].mo && !P_IsObjectOnGround(players[respawnplayer].mo))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (players[respawnplayer].mo)
|
if (players[respawnplayer].mo)
|
||||||
P_DamageMobj(players[respawnplayer].mo, NULL, NULL, 10000);
|
{
|
||||||
demo_extradata[playernum] |= DXD_RESPAWN;
|
// incase the above checks were modified to allow sending a respawn on these occasions:
|
||||||
|
if (!P_IsObjectOnGround(players[respawnplayer].mo))
|
||||||
|
return;
|
||||||
|
|
||||||
|
K_DoIngameRespawn(&players[respawnplayer]);
|
||||||
|
demo_extradata[playernum] |= DXD_RESPAWN;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Deals with an ::XD_RANDOMSEED message in a netgame.
|
/** Deals with an ::XD_RANDOMSEED message in a netgame.
|
||||||
|
|
|
||||||
|
|
@ -121,7 +121,7 @@ typedef enum
|
||||||
|
|
||||||
/*** misc ***/
|
/*** misc ***/
|
||||||
PF_FORCESTRAFE = 1<<29, // Turning inputs are translated into strafing inputs
|
PF_FORCESTRAFE = 1<<29, // Turning inputs are translated into strafing inputs
|
||||||
PF_ANALOGMODE = 1<<30, // Analog mode?
|
PF_HITFINISHLINE = 1<<30, // Already hit the finish line this tic
|
||||||
|
|
||||||
// free: 1<<30 and 1<<31
|
// free: 1<<30 and 1<<31
|
||||||
} pflags_t;
|
} pflags_t;
|
||||||
|
|
@ -330,6 +330,7 @@ typedef enum
|
||||||
k_springstars, // Spawn stars around a player when they hit a spring
|
k_springstars, // Spawn stars around a player when they hit a spring
|
||||||
k_springcolor, // Color of spring stars
|
k_springcolor, // Color of spring stars
|
||||||
k_killfield, // How long have you been in the kill field, stay in too long and lose a bumper
|
k_killfield, // How long have you been in the kill field, stay in too long and lose a bumper
|
||||||
|
k_wrongway, // Display WRONG WAY on screen
|
||||||
|
|
||||||
NUMKARTSTUFF
|
NUMKARTSTUFF
|
||||||
} kartstufftype_t;
|
} kartstufftype_t;
|
||||||
|
|
|
||||||
|
|
@ -6648,6 +6648,11 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
|
||||||
|
|
||||||
// DEZ respawn laser
|
// DEZ respawn laser
|
||||||
"S_DEZLASER",
|
"S_DEZLASER",
|
||||||
|
"S_DEZLASER_TRAIL1",
|
||||||
|
"S_DEZLASER_TRAIL2",
|
||||||
|
"S_DEZLASER_TRAIL3",
|
||||||
|
"S_DEZLASER_TRAIL4",
|
||||||
|
"S_DEZLASER_TRAIL5",
|
||||||
|
|
||||||
// Audience Members
|
// Audience Members
|
||||||
"S_RANDOMAUDIENCE",
|
"S_RANDOMAUDIENCE",
|
||||||
|
|
@ -8167,7 +8172,7 @@ static const char *const PLAYERFLAG_LIST[] = {
|
||||||
|
|
||||||
/*** misc ***/
|
/*** misc ***/
|
||||||
"FORCESTRAFE", // Translate turn inputs into strafe inputs
|
"FORCESTRAFE", // Translate turn inputs into strafe inputs
|
||||||
"ANALOGMODE", // Analog mode?
|
"HITFINISHLINE", // Already hit the finish line this tic
|
||||||
|
|
||||||
NULL // stop loop here.
|
NULL // stop loop here.
|
||||||
};
|
};
|
||||||
|
|
@ -8485,7 +8490,8 @@ static const char *const KARTSTUFF_LIST[] = {
|
||||||
"TIREGREASE",
|
"TIREGREASE",
|
||||||
"SPRINGSTARS",
|
"SPRINGSTARS",
|
||||||
"SPRINGCOLOR",
|
"SPRINGCOLOR",
|
||||||
"KILLFIELD"
|
"KILLFIELD",
|
||||||
|
"WRONGWAY"
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2597,7 +2597,7 @@ void G_PlayerReborn(INT32 player)
|
||||||
jointime = players[player].jointime;
|
jointime = players[player].jointime;
|
||||||
splitscreenindex = players[player].splitscreenindex;
|
splitscreenindex = players[player].splitscreenindex;
|
||||||
spectator = players[player].spectator;
|
spectator = players[player].spectator;
|
||||||
pflags = (players[player].pflags & (PF_TIMEOVER|PF_FLIPCAM|PF_TAGIT|PF_TAGGED|PF_ANALOGMODE|PF_WANTSTOJOIN));
|
pflags = (players[player].pflags & (PF_TIMEOVER|PF_FLIPCAM|PF_TAGIT|PF_TAGGED|PF_WANTSTOJOIN));
|
||||||
|
|
||||||
// As long as we're not in multiplayer, carry over cheatcodes from map to map
|
// As long as we're not in multiplayer, carry over cheatcodes from map to map
|
||||||
if (!(netgame || multiplayer))
|
if (!(netgame || multiplayer))
|
||||||
|
|
@ -4935,7 +4935,10 @@ void G_ReadDemoExtraData(void)
|
||||||
if (extradata & DXD_RESPAWN)
|
if (extradata & DXD_RESPAWN)
|
||||||
{
|
{
|
||||||
if (players[p].mo)
|
if (players[p].mo)
|
||||||
P_DamageMobj(players[p].mo, NULL, NULL, 10000); // Is this how this should work..?
|
{
|
||||||
|
// Is this how this should work..?
|
||||||
|
K_DoIngameRespawn(&players[p]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (extradata & DXD_SKIN)
|
if (extradata & DXD_SKIN)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -2863,7 +2863,12 @@ state_t states[NUMSTATES] =
|
||||||
{SPR_KBLN, FF_FULLBRIGHT|1, -1, {NULL}, 0, 0, S_BATTLEBUMPER2}, // S_BATTLEBUMPER2
|
{SPR_KBLN, FF_FULLBRIGHT|1, -1, {NULL}, 0, 0, S_BATTLEBUMPER2}, // S_BATTLEBUMPER2
|
||||||
{SPR_KBLN, FF_FULLBRIGHT|2, -1, {NULL}, 0, 0, S_BATTLEBUMPER3}, // S_BATTLEBUMPER3
|
{SPR_KBLN, FF_FULLBRIGHT|2, -1, {NULL}, 0, 0, S_BATTLEBUMPER3}, // S_BATTLEBUMPER3
|
||||||
|
|
||||||
{SPR_DEZL, FF_FULLBRIGHT|FF_PAPERSPRITE, 8, {NULL}, 0, 0, S_NULL}, // S_DEZLASER
|
{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
|
||||||
|
{SPR_DEZL, FF_FULLBRIGHT|FF_PAPERSPRITE|3, 4, {NULL}, 0, 0, S_DEZLASER_TRAIL4}, // S_DEZLASER_TRAIL3
|
||||||
|
{SPR_DEZL, FF_FULLBRIGHT|2, 2, {NULL}, 0, 0, S_DEZLASER_TRAIL5}, // S_DEZLASER_TRAIL4
|
||||||
|
{SPR_DEZL, FF_FULLBRIGHT|1, 2, {NULL}, 0, 0, S_NULL}, // S_DEZLASER_TRAIL5
|
||||||
|
|
||||||
{SPR_NULL, 0, 1, {A_RandomStateRange}, S_AUDIENCE_CHAO_CHEER1, S_AUDIENCE_CHAO_CHEER2, S_RANDOMAUDIENCE}, // S_RANDOMAUDIENCE
|
{SPR_NULL, 0, 1, {A_RandomStateRange}, S_AUDIENCE_CHAO_CHEER1, S_AUDIENCE_CHAO_CHEER2, S_RANDOMAUDIENCE}, // S_RANDOMAUDIENCE
|
||||||
|
|
||||||
|
|
@ -16036,7 +16041,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
||||||
S_SPB_DEAD, // deathstate
|
S_SPB_DEAD, // deathstate
|
||||||
S_NULL, // xdeathstate
|
S_NULL, // xdeathstate
|
||||||
sfx_s3k5d, // deathsound
|
sfx_s3k5d, // deathsound
|
||||||
96*FRACUNIT, // speed
|
80*FRACUNIT, // speed
|
||||||
24*FRACUNIT, // radius
|
24*FRACUNIT, // radius
|
||||||
48*FRACUNIT, // height
|
48*FRACUNIT, // height
|
||||||
0, // display offset
|
0, // display offset
|
||||||
|
|
|
||||||
|
|
@ -3537,6 +3537,11 @@ typedef enum state
|
||||||
|
|
||||||
// DEZ Laser respawn
|
// DEZ Laser respawn
|
||||||
S_DEZLASER,
|
S_DEZLASER,
|
||||||
|
S_DEZLASER_TRAIL1,
|
||||||
|
S_DEZLASER_TRAIL2,
|
||||||
|
S_DEZLASER_TRAIL3,
|
||||||
|
S_DEZLASER_TRAIL4,
|
||||||
|
S_DEZLASER_TRAIL5,
|
||||||
|
|
||||||
// Audience Members
|
// Audience Members
|
||||||
S_RANDOMAUDIENCE,
|
S_RANDOMAUDIENCE,
|
||||||
|
|
|
||||||
1085
src/k_kart.c
1085
src/k_kart.c
File diff suppressed because it is too large
Load diff
|
|
@ -27,6 +27,7 @@ void K_KartBouncing(mobj_t *mobj1, mobj_t *mobj2, boolean bounce, boolean solid)
|
||||||
void K_KartPainEnergyFling(player_t *player);
|
void K_KartPainEnergyFling(player_t *player);
|
||||||
void K_FlipFromObject(mobj_t *mo, mobj_t *master);
|
void K_FlipFromObject(mobj_t *mo, mobj_t *master);
|
||||||
void K_MatchGenericExtraFlags(mobj_t *mo, mobj_t *master);
|
void K_MatchGenericExtraFlags(mobj_t *mo, mobj_t *master);
|
||||||
|
void K_DoIngameRespawn(player_t *player);
|
||||||
void K_RespawnChecker(player_t *player);
|
void K_RespawnChecker(player_t *player);
|
||||||
void K_KartMoveAnimation(player_t *player);
|
void K_KartMoveAnimation(player_t *player);
|
||||||
void K_KartPlayerHUDUpdate(player_t *player);
|
void K_KartPlayerHUDUpdate(player_t *player);
|
||||||
|
|
|
||||||
|
|
@ -11,9 +11,9 @@ static const UINT32 SPARKLES_PER_CONNECTION = 16U;
|
||||||
|
|
||||||
// Some defaults for the size of the dynamically allocated sets for pathfinding. These are kept for the purpose of
|
// Some defaults for the size of the dynamically allocated sets for pathfinding. These are kept for the purpose of
|
||||||
// allocating a size that is less likely to need reallocating again during the pathfinding.
|
// allocating a size that is less likely to need reallocating again during the pathfinding.
|
||||||
static const size_t OPENSET_BASE_SIZE = 16U;
|
#define OPENSET_BASE_SIZE (16U)
|
||||||
static const size_t CLOSEDSET_BASE_SIZE = 256U;
|
#define CLOSEDSET_BASE_SIZE (256U)
|
||||||
static const size_t NODESARRAY_BASE_SIZE = 256U;
|
#define NODESARRAY_BASE_SIZE (256U)
|
||||||
|
|
||||||
static waypoint_t *waypointheap = NULL;
|
static waypoint_t *waypointheap = NULL;
|
||||||
static waypoint_t *firstwaypoint = NULL;
|
static waypoint_t *firstwaypoint = NULL;
|
||||||
|
|
@ -221,8 +221,11 @@ waypoint_t *K_GetClosestWaypointToMobj(mobj_t *const mobj)
|
||||||
for (i = 0; i < numwaypoints; i++)
|
for (i = 0; i < numwaypoints; i++)
|
||||||
{
|
{
|
||||||
checkwaypoint = &waypointheap[i];
|
checkwaypoint = &waypointheap[i];
|
||||||
checkdist = P_AproxDistance(mobj->x - checkwaypoint->mobj->x, mobj->y - checkwaypoint->mobj->y);
|
|
||||||
checkdist = P_AproxDistance(checkdist, mobj->z - checkwaypoint->mobj->z);
|
checkdist = P_AproxDistance(
|
||||||
|
(mobj->x / FRACUNIT) - (checkwaypoint->mobj->x / FRACUNIT),
|
||||||
|
(mobj->y / FRACUNIT) - (checkwaypoint->mobj->y / FRACUNIT));
|
||||||
|
checkdist = P_AproxDistance(checkdist, (mobj->z / FRACUNIT) - (checkwaypoint->mobj->z / FRACUNIT));
|
||||||
|
|
||||||
if (checkdist < closestdist)
|
if (checkdist < closestdist)
|
||||||
{
|
{
|
||||||
|
|
@ -235,6 +238,52 @@ waypoint_t *K_GetClosestWaypointToMobj(mobj_t *const mobj)
|
||||||
return closestwaypoint;
|
return closestwaypoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*--------------------------------------------------
|
||||||
|
waypoint_t *K_GetBestWaypointForMobj(mobj_t *const mobj)
|
||||||
|
|
||||||
|
See header file for description.
|
||||||
|
--------------------------------------------------*/
|
||||||
|
waypoint_t *K_GetBestWaypointForMobj(mobj_t *const mobj)
|
||||||
|
{
|
||||||
|
waypoint_t *bestwaypoint = NULL;
|
||||||
|
|
||||||
|
if ((mobj == NULL) || P_MobjWasRemoved(mobj))
|
||||||
|
{
|
||||||
|
CONS_Debug(DBG_GAMELOGIC, "NULL mobj in K_GetBestWaypointForMobj.\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
size_t i = 0U;
|
||||||
|
waypoint_t *checkwaypoint = NULL;
|
||||||
|
fixed_t closestdist = INT32_MAX;
|
||||||
|
fixed_t checkdist = INT32_MAX;
|
||||||
|
|
||||||
|
for (i = 0; i < numwaypoints; i++)
|
||||||
|
{
|
||||||
|
checkwaypoint = &waypointheap[i];
|
||||||
|
|
||||||
|
checkdist = P_AproxDistance(
|
||||||
|
(mobj->x / FRACUNIT) - (checkwaypoint->mobj->x / FRACUNIT),
|
||||||
|
(mobj->y / FRACUNIT) - (checkwaypoint->mobj->y / FRACUNIT));
|
||||||
|
checkdist = P_AproxDistance(checkdist, ((mobj->z / FRACUNIT) - (checkwaypoint->mobj->z / FRACUNIT)) * 4);
|
||||||
|
|
||||||
|
if (checkdist < closestdist)
|
||||||
|
{
|
||||||
|
if (!P_CheckSight(mobj, checkwaypoint->mobj))
|
||||||
|
{
|
||||||
|
// Save sight checks for the end, so we only do it if we have to
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
bestwaypoint = checkwaypoint;
|
||||||
|
closestdist = checkdist;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return bestwaypoint;
|
||||||
|
}
|
||||||
|
|
||||||
/*--------------------------------------------------
|
/*--------------------------------------------------
|
||||||
size_t K_GetWaypointHeapIndex(waypoint_t *waypoint)
|
size_t K_GetWaypointHeapIndex(waypoint_t *waypoint)
|
||||||
|
|
||||||
|
|
@ -378,11 +427,11 @@ void K_DebugWaypointsVisualise(void)
|
||||||
}
|
}
|
||||||
else if (waypoint->numnextwaypoints == 0 || waypoint->numprevwaypoints == 0)
|
else if (waypoint->numnextwaypoints == 0 || waypoint->numprevwaypoints == 0)
|
||||||
{
|
{
|
||||||
debugmobj->color = SKINCOLOR_ORANGE;
|
debugmobj->color = SKINCOLOR_YELLOW;
|
||||||
}
|
}
|
||||||
else if (waypoint == players[displayplayers[0]].nextwaypoint)
|
else if (waypoint == players[displayplayers[0]].nextwaypoint)
|
||||||
{
|
{
|
||||||
debugmobj->color = SKINCOLOR_YELLOW;
|
debugmobj->color = SKINCOLOR_GREEN;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -151,6 +151,22 @@ UINT32 K_GetCircuitLength(void);
|
||||||
waypoint_t *K_GetClosestWaypointToMobj(mobj_t *const mobj);
|
waypoint_t *K_GetClosestWaypointToMobj(mobj_t *const mobj);
|
||||||
|
|
||||||
|
|
||||||
|
/*--------------------------------------------------
|
||||||
|
waypoint_t *K_GetBestWaypointForMobj(mobj_t *const mobj)
|
||||||
|
|
||||||
|
Similar to K_GetClosestWaypointToMobj, but prioritizes horizontal distance over vertical distance, and
|
||||||
|
sight checks to ensure that the waypoint and mobj are the in same area. Can potentially return NULL if
|
||||||
|
there are no visible waypoints.
|
||||||
|
|
||||||
|
Input Arguments:-
|
||||||
|
mobj - mobj to get the waypoint for.
|
||||||
|
|
||||||
|
Return:-
|
||||||
|
The best waypoint for the mobj, or NULL if there were no matches
|
||||||
|
--------------------------------------------------*/
|
||||||
|
waypoint_t *K_GetBestWaypointForMobj(mobj_t *const mobj);
|
||||||
|
|
||||||
|
|
||||||
/*--------------------------------------------------
|
/*--------------------------------------------------
|
||||||
boolean K_PathfindToWaypoint(
|
boolean K_PathfindToWaypoint(
|
||||||
waypoint_t *const sourcewaypoint,
|
waypoint_t *const sourcewaypoint,
|
||||||
|
|
|
||||||
|
|
@ -292,9 +292,18 @@ void Command_CheatNoClip_f(void)
|
||||||
REQUIRE_NOULTIMATE;
|
REQUIRE_NOULTIMATE;
|
||||||
|
|
||||||
plyr = &players[consoleplayer];
|
plyr = &players[consoleplayer];
|
||||||
|
|
||||||
|
if (!plyr->mo || P_MobjWasRemoved(plyr->mo))
|
||||||
|
return;
|
||||||
|
|
||||||
plyr->pflags ^= PF_NOCLIP;
|
plyr->pflags ^= PF_NOCLIP;
|
||||||
CONS_Printf(M_GetText("No Clipping %s\n"), plyr->pflags & PF_NOCLIP ? M_GetText("On") : M_GetText("Off"));
|
CONS_Printf(M_GetText("No Clipping %s\n"), plyr->pflags & PF_NOCLIP ? M_GetText("On") : M_GetText("Off"));
|
||||||
|
|
||||||
|
if (plyr->pflags & PF_NOCLIP)
|
||||||
|
plyr->mo->flags |= MF_NOCLIP;
|
||||||
|
else
|
||||||
|
plyr->mo->flags &= ~MF_NOCLIP;
|
||||||
|
|
||||||
G_SetGameModified(multiplayer, true);
|
G_SetGameModified(multiplayer, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
122
src/p_enemy.c
122
src/p_enemy.c
|
|
@ -8451,7 +8451,7 @@ static void SpawnSPBTrailRings(mobj_t *actor)
|
||||||
{
|
{
|
||||||
if (leveltime % 6 == 0)
|
if (leveltime % 6 == 0)
|
||||||
{
|
{
|
||||||
mobj_t *ring = P_SpawnMobj(actor->x - actor->momx, actor->y - actor->momx,
|
mobj_t *ring = P_SpawnMobj(actor->x - actor->momx, actor->y - actor->momy,
|
||||||
actor->z - actor->momz + (24*mapobjectscale), MT_RING);
|
actor->z - actor->momz + (24*mapobjectscale), MT_RING);
|
||||||
ring->threshold = 10;
|
ring->threshold = 10;
|
||||||
ring->fuse = 120*TICRATE;
|
ring->fuse = 120*TICRATE;
|
||||||
|
|
@ -8462,11 +8462,15 @@ static void SpawnSPBTrailRings(mobj_t *actor)
|
||||||
void A_SPBChase(mobj_t *actor)
|
void A_SPBChase(mobj_t *actor)
|
||||||
{
|
{
|
||||||
player_t *player = NULL;
|
player_t *player = NULL;
|
||||||
|
player_t *scplayer = NULL; // secondary target for seeking
|
||||||
UINT8 i;
|
UINT8 i;
|
||||||
UINT8 bestrank = UINT8_MAX;
|
UINT8 bestrank = UINT8_MAX;
|
||||||
fixed_t dist;
|
fixed_t dist;
|
||||||
angle_t hang, vang;
|
angle_t hang, vang;
|
||||||
fixed_t wspeed, xyspeed, zspeed;
|
fixed_t wspeed, xyspeed, zspeed;
|
||||||
|
fixed_t pdist = 1536<<FRACBITS; // best player distance when seeking
|
||||||
|
angle_t pangle; // angle between us and the player
|
||||||
|
|
||||||
#ifdef HAVE_BLUA
|
#ifdef HAVE_BLUA
|
||||||
if (LUA_CallAction("A_SPBChase", actor))
|
if (LUA_CallAction("A_SPBChase", actor))
|
||||||
return;
|
return;
|
||||||
|
|
@ -8478,9 +8482,9 @@ void A_SPBChase(mobj_t *actor)
|
||||||
if (actor->threshold) // Just fired, go straight.
|
if (actor->threshold) // Just fired, go straight.
|
||||||
{
|
{
|
||||||
actor->lastlook = -1;
|
actor->lastlook = -1;
|
||||||
|
actor->cusval = -1;
|
||||||
spbplace = -1;
|
spbplace = -1;
|
||||||
P_InstaThrust(actor, actor->angle, wspeed);
|
P_InstaThrust(actor, actor->angle, wspeed);
|
||||||
actor->flags &= ~MF_NOCLIPTHING; // just in case.
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -8506,18 +8510,22 @@ void A_SPBChase(mobj_t *actor)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// lastlook = last player num targetted
|
||||||
|
// cvmem = stored speed
|
||||||
|
// cusval = next waypoint heap index
|
||||||
|
// extravalue1 = SPB movement mode
|
||||||
|
// extravalue2 = mode misc option
|
||||||
|
|
||||||
if (actor->extravalue1 == 1) // MODE: TARGETING
|
if (actor->extravalue1 == 1) // MODE: TARGETING
|
||||||
{
|
{
|
||||||
|
actor->cusval = -1; // Reset waypoint
|
||||||
|
|
||||||
if (actor->tracer && actor->tracer->health)
|
if (actor->tracer && actor->tracer->health)
|
||||||
{
|
{
|
||||||
|
|
||||||
fixed_t defspeed = wspeed;
|
fixed_t defspeed = wspeed;
|
||||||
fixed_t range = (160*actor->tracer->scale);
|
fixed_t range = (160*actor->tracer->scale);
|
||||||
fixed_t cx = 0, cy =0;
|
fixed_t cx = 0, cy =0;
|
||||||
|
|
||||||
// we're tailing a player, now's a good time to regain our damage properties
|
|
||||||
actor->flags &= ~MF_NOCLIPTHING;
|
|
||||||
|
|
||||||
// Play the intimidating gurgle
|
// Play the intimidating gurgle
|
||||||
if (!S_SoundPlaying(actor, actor->info->activesound))
|
if (!S_SoundPlaying(actor, actor->info->activesound))
|
||||||
S_StartSound(actor, actor->info->activesound);
|
S_StartSound(actor, actor->info->activesound);
|
||||||
|
|
@ -8648,9 +8656,7 @@ void A_SPBChase(mobj_t *actor)
|
||||||
else if (actor->extravalue1 == 2) // MODE: WAIT...
|
else if (actor->extravalue1 == 2) // MODE: WAIT...
|
||||||
{
|
{
|
||||||
actor->momx = actor->momy = actor->momz = 0; // Stoooop
|
actor->momx = actor->momy = actor->momz = 0; // Stoooop
|
||||||
|
actor->cusval = -1; // Reset waypoint
|
||||||
// don't hurt players that have nothing to do with this:
|
|
||||||
actor->flags |= MF_NOCLIPTHING;
|
|
||||||
|
|
||||||
if (actor->lastlook != -1
|
if (actor->lastlook != -1
|
||||||
&& playeringame[actor->lastlook]
|
&& playeringame[actor->lastlook]
|
||||||
|
|
@ -8676,8 +8682,11 @@ void A_SPBChase(mobj_t *actor)
|
||||||
}
|
}
|
||||||
else // MODE: SEEKING
|
else // MODE: SEEKING
|
||||||
{
|
{
|
||||||
waypoint_t *closestwaypoint = NULL;
|
waypoint_t *lastwaypoint = NULL;
|
||||||
waypoint_t *nextwaypoint = NULL;
|
waypoint_t *bestwaypoint = NULL;
|
||||||
|
waypoint_t *nextwaypoint = NULL;
|
||||||
|
waypoint_t *tempwaypoint = NULL;
|
||||||
|
|
||||||
actor->lastlook = -1; // Just make sure this is reset
|
actor->lastlook = -1; // Just make sure this is reset
|
||||||
|
|
||||||
if (!player || !player->mo || player->mo->health <= 0 || player->kartstuff[k_respawn])
|
if (!player || !player->mo || player->mo->health <= 0 || player->kartstuff[k_respawn])
|
||||||
|
|
@ -8690,17 +8699,35 @@ void A_SPBChase(mobj_t *actor)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Found someone, now get close enough to initiate the slaughter...
|
// Found someone, now get close enough to initiate the slaughter...
|
||||||
|
|
||||||
// Seeking SPB can now hurt people
|
|
||||||
actor->flags &= ~MF_NOCLIPTHING;
|
|
||||||
|
|
||||||
P_SetTarget(&actor->tracer, player->mo);
|
P_SetTarget(&actor->tracer, player->mo);
|
||||||
spbplace = bestrank;
|
spbplace = bestrank;
|
||||||
|
|
||||||
dist = P_AproxDistance(P_AproxDistance(actor->x-actor->tracer->x, actor->y-actor->tracer->y), actor->z-actor->tracer->z);
|
dist = P_AproxDistance(P_AproxDistance(actor->x-actor->tracer->x, actor->y-actor->tracer->y), actor->z-actor->tracer->z);
|
||||||
|
|
||||||
closestwaypoint = K_GetClosestWaypointToMobj(actor);
|
// Move along the waypoints until you get close enough
|
||||||
if (closestwaypoint != NULL)
|
if (actor->cusval > -1 && actor->extravalue2 > 0)
|
||||||
|
{
|
||||||
|
// Previously set nextwaypoint
|
||||||
|
lastwaypoint = K_GetWaypointFromIndex((size_t)actor->cusval);
|
||||||
|
tempwaypoint = K_GetBestWaypointForMobj(actor);
|
||||||
|
// check if the tempwaypoint corresponds to lastwaypoint's next ID at least;
|
||||||
|
// This is to avoid situations where the SPB decides to suicide jump down a bridge because it found a COMPLETELY unrelated waypoint down there.
|
||||||
|
|
||||||
|
if (K_GetWaypointID(tempwaypoint) == K_GetWaypointNextID(lastwaypoint) || K_GetWaypointID(tempwaypoint) == K_GetWaypointID(lastwaypoint))
|
||||||
|
// either our previous or curr waypoint ID, sure, take it
|
||||||
|
bestwaypoint = tempwaypoint;
|
||||||
|
else
|
||||||
|
bestwaypoint = K_GetWaypointFromIndex((size_t)actor->extravalue2); // keep going from the PREVIOUS wp.
|
||||||
|
}
|
||||||
|
else
|
||||||
|
bestwaypoint = K_GetBestWaypointForMobj(actor);
|
||||||
|
|
||||||
|
if (bestwaypoint == NULL && lastwaypoint == NULL)
|
||||||
|
{
|
||||||
|
// We have invalid waypoints all around, so use closest to try and make it non-NULL.
|
||||||
|
bestwaypoint = K_GetClosestWaypointToMobj(actor);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bestwaypoint != NULL)
|
||||||
{
|
{
|
||||||
const boolean huntbackwards = false;
|
const boolean huntbackwards = false;
|
||||||
boolean useshortcuts = false;
|
boolean useshortcuts = false;
|
||||||
|
|
@ -8712,15 +8739,25 @@ void A_SPBChase(mobj_t *actor)
|
||||||
}
|
}
|
||||||
|
|
||||||
nextwaypoint = K_GetNextWaypointToDestination(
|
nextwaypoint = K_GetNextWaypointToDestination(
|
||||||
closestwaypoint, player->nextwaypoint, useshortcuts, huntbackwards);
|
bestwaypoint, player->nextwaypoint, useshortcuts, huntbackwards);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nextwaypoint == NULL && lastwaypoint != NULL)
|
||||||
|
{
|
||||||
|
// Restore to the last nextwaypoint
|
||||||
|
nextwaypoint = lastwaypoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nextwaypoint != NULL)
|
if (nextwaypoint != NULL)
|
||||||
{
|
{
|
||||||
const fixed_t xywaypointdist = P_AproxDistance(
|
const fixed_t xywaypointdist = P_AproxDistance(
|
||||||
actor->x - nextwaypoint->mobj->x, actor->y - nextwaypoint->mobj->y);
|
actor->x - nextwaypoint->mobj->x, actor->y - nextwaypoint->mobj->y);
|
||||||
|
|
||||||
hang = R_PointToAngle2(actor->x, actor->y, nextwaypoint->mobj->x, nextwaypoint->mobj->y);
|
hang = R_PointToAngle2(actor->x, actor->y, nextwaypoint->mobj->x, nextwaypoint->mobj->y);
|
||||||
vang = R_PointToAngle2(0, actor->z, xywaypointdist, nextwaypoint->mobj->z);
|
vang = R_PointToAngle2(0, actor->z, xywaypointdist, nextwaypoint->mobj->z);
|
||||||
|
|
||||||
|
actor->cusval = (INT32)K_GetWaypointHeapIndex(nextwaypoint);
|
||||||
|
actor->extravalue2 = (INT32)K_GetWaypointHeapIndex(bestwaypoint); // save our last best, used above.
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -8736,13 +8773,13 @@ void A_SPBChase(mobj_t *actor)
|
||||||
if (invert)
|
if (invert)
|
||||||
input = InvAngle(input);
|
input = InvAngle(input);
|
||||||
|
|
||||||
|
input = FixedAngle(AngleFixed(input)/8);
|
||||||
|
|
||||||
// Slow down when turning; it looks better and makes U-turns not unfair
|
// Slow down when turning; it looks better and makes U-turns not unfair
|
||||||
xyspeed = FixedMul(wspeed, max(0, (((180<<FRACBITS) - AngleFixed(input)) / 90) - FRACUNIT));
|
xyspeed = FixedMul(wspeed, max(0, (((180<<FRACBITS) - AngleFixed(input)) / 90) - FRACUNIT));
|
||||||
|
|
||||||
input = FixedAngle(AngleFixed(input)/4);
|
|
||||||
if (invert)
|
if (invert)
|
||||||
input = InvAngle(input);
|
input = InvAngle(input);
|
||||||
|
|
||||||
actor->angle += input;
|
actor->angle += input;
|
||||||
|
|
||||||
// Smoothly rotate vert angle
|
// Smoothly rotate vert angle
|
||||||
|
|
@ -8751,13 +8788,13 @@ void A_SPBChase(mobj_t *actor)
|
||||||
if (invert)
|
if (invert)
|
||||||
input = InvAngle(input);
|
input = InvAngle(input);
|
||||||
|
|
||||||
|
input = FixedAngle(AngleFixed(input)/8);
|
||||||
|
|
||||||
// Slow down when turning; might as well do it for momz, since we do it above too
|
// Slow down when turning; might as well do it for momz, since we do it above too
|
||||||
zspeed = FixedMul(wspeed, max(0, (((180<<FRACBITS) - AngleFixed(input)) / 90) - FRACUNIT));
|
zspeed = FixedMul(wspeed, max(0, (((180<<FRACBITS) - AngleFixed(input)) / 90) - FRACUNIT));
|
||||||
|
|
||||||
input = FixedAngle(AngleFixed(input)/4);
|
|
||||||
if (invert)
|
if (invert)
|
||||||
input = InvAngle(input);
|
input = InvAngle(input);
|
||||||
|
|
||||||
actor->movedir += input;
|
actor->movedir += input;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -8765,18 +8802,49 @@ void A_SPBChase(mobj_t *actor)
|
||||||
actor->momy = FixedMul(FixedMul(xyspeed, FINESINE(actor->angle>>ANGLETOFINESHIFT)), FINECOSINE(actor->movedir>>ANGLETOFINESHIFT));
|
actor->momy = FixedMul(FixedMul(xyspeed, FINESINE(actor->angle>>ANGLETOFINESHIFT)), FINECOSINE(actor->movedir>>ANGLETOFINESHIFT));
|
||||||
actor->momz = FixedMul(zspeed, FINESINE(actor->movedir>>ANGLETOFINESHIFT));
|
actor->momz = FixedMul(zspeed, FINESINE(actor->movedir>>ANGLETOFINESHIFT));
|
||||||
|
|
||||||
|
// see if a player is near us, if they are, try to hit them by slightly thrusting towards them, otherwise, bleh!
|
||||||
|
for (i=0; i < MAXPLAYERS; i++)
|
||||||
|
{
|
||||||
|
if (!playeringame[i] || players[i].spectator || players[i].exiting)
|
||||||
|
continue; // not in-game
|
||||||
|
|
||||||
|
if (R_PointToDist2(actor->x, actor->y, players[i].mo->x, players[i].mo->y) < pdist)
|
||||||
|
{
|
||||||
|
pdist = R_PointToDist2(actor->x, actor->y, players[i].mo->x, players[i].mo->y);
|
||||||
|
scplayer = &players[i]; // it doesn't matter if we override this guy now.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// different player from our main target, try and ram into em~!
|
||||||
|
if (scplayer && scplayer != player)
|
||||||
|
{
|
||||||
|
pangle = actor->angle - R_PointToAngle2(actor->x, actor->y,scplayer->mo->x, scplayer->mo->y);
|
||||||
|
// check if the angle wouldn't make us LOSE speed...
|
||||||
|
if ((INT32)pangle/ANG1 >= -80 && (INT32)pangle/ANG1 <= 80) // allow for around 80 degrees
|
||||||
|
{
|
||||||
|
// Thrust us towards the guy, try to screw em up!
|
||||||
|
P_Thrust(actor, R_PointToAngle2(actor->x, actor->y, scplayer->mo->x, scplayer->mo->y), actor->movefactor/4); // not too fast though.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Spawn a trail of rings behind the SPB!
|
// Spawn a trail of rings behind the SPB!
|
||||||
SpawnSPBTrailRings(actor);
|
SpawnSPBTrailRings(actor);
|
||||||
|
|
||||||
if (dist <= (3072*actor->tracer->scale)) // Close enough to target?
|
if (dist <= (1024*actor->tracer->scale)) // Close enough to target?
|
||||||
{
|
{
|
||||||
S_StartSound(actor, actor->info->attacksound); // Siren sound; might not need this anymore, but I'm keeping it for now just for debugging.
|
S_StartSound(actor, actor->info->attacksound);
|
||||||
actor->extravalue1 = 1; // TARGET ACQUIRED
|
actor->extravalue1 = 1; // TARGET ACQUIRED
|
||||||
actor->extravalue2 = 7*TICRATE;
|
actor->extravalue2 = 7*TICRATE;
|
||||||
actor->cvmem = wspeed;
|
actor->cvmem = wspeed;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Finally, no matter what, the spb should not be able to be under the ground, or above the ceiling;
|
||||||
|
if (actor->z < actor->floorz)
|
||||||
|
actor->z = actor->floorz;
|
||||||
|
else if (actor->z > actor->ceilingz - actor->height)
|
||||||
|
actor->z = actor->ceilingz - actor->height;
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -10618,8 +10686,8 @@ void A_RemoteDamage(mobj_t *actor)
|
||||||
|
|
||||||
if (locvar2 == 1) // Kill mobj!
|
if (locvar2 == 1) // Kill mobj!
|
||||||
{
|
{
|
||||||
if (target->player) // players die using P_DamageMobj instead for some reason
|
if (target->player)
|
||||||
P_DamageMobj(target, source, source, 10000);
|
K_DoIngameRespawn(target->player);
|
||||||
else
|
else
|
||||||
P_KillMobj(target, source, source);
|
P_KillMobj(target, source, source);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -180,7 +180,6 @@ boolean P_LookForEnemies(player_t *player);
|
||||||
void P_NukeEnemies(mobj_t *inflictor, mobj_t *source, fixed_t radius);
|
void P_NukeEnemies(mobj_t *inflictor, mobj_t *source, fixed_t radius);
|
||||||
void P_HomingAttack(mobj_t *source, mobj_t *enemy); /// \todo doesn't belong in p_user
|
void P_HomingAttack(mobj_t *source, mobj_t *enemy); /// \todo doesn't belong in p_user
|
||||||
//boolean P_SuperReady(player_t *player);
|
//boolean P_SuperReady(player_t *player);
|
||||||
boolean P_AnalogMove(player_t *player);
|
|
||||||
/*boolean P_TransferToNextMare(player_t *player);
|
/*boolean P_TransferToNextMare(player_t *player);
|
||||||
UINT8 P_FindLowestMare(void);*/
|
UINT8 P_FindLowestMare(void);*/
|
||||||
UINT8 P_FindLowestLap(void);
|
UINT8 P_FindLowestLap(void);
|
||||||
|
|
|
||||||
42
src/p_map.c
42
src/p_map.c
|
|
@ -129,8 +129,6 @@ boolean P_TeleportMove(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z)
|
||||||
// MOVEMENT ITERATOR FUNCTIONS
|
// MOVEMENT ITERATOR FUNCTIONS
|
||||||
// =========================================================================
|
// =========================================================================
|
||||||
|
|
||||||
//#define TELEPORTJANK
|
|
||||||
|
|
||||||
// For our intermediate buffer, remove any duplicate entries by adding each one to
|
// For our intermediate buffer, remove any duplicate entries by adding each one to
|
||||||
// a temprary buffer if it's not already in there, copy the temporary buffer back over the intermediate afterwards
|
// a temprary buffer if it's not already in there, copy the temporary buffer back over the intermediate afterwards
|
||||||
static void spechitint_removedups(void)
|
static void spechitint_removedups(void)
|
||||||
|
|
@ -225,6 +223,8 @@ static boolean P_SpecialIsLinedefCrossType(UINT16 ldspecial)
|
||||||
return linedefcrossspecial;
|
return linedefcrossspecial;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//#define TELEPORTJANK
|
||||||
|
|
||||||
boolean P_DoSpring(mobj_t *spring, mobj_t *object)
|
boolean P_DoSpring(mobj_t *spring, mobj_t *object)
|
||||||
{
|
{
|
||||||
//INT32 pflags;
|
//INT32 pflags;
|
||||||
|
|
@ -256,7 +256,7 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object)
|
||||||
object->eflags |= MFE_SPRUNG; // apply this flag asap!
|
object->eflags |= MFE_SPRUNG; // apply this flag asap!
|
||||||
spring->flags &= ~(MF_SOLID|MF_SPECIAL); // De-solidify
|
spring->flags &= ~(MF_SOLID|MF_SPECIAL); // De-solidify
|
||||||
|
|
||||||
#ifdef TELEPORTJANK
|
#if 0
|
||||||
if (horizspeed && vertispeed) // Mimic SA
|
if (horizspeed && vertispeed) // Mimic SA
|
||||||
{
|
{
|
||||||
object->momx = object->momy = 0;
|
object->momx = object->momy = 0;
|
||||||
|
|
@ -1007,12 +1007,20 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
||||||
|
|
||||||
if (thing->type == MT_PLAYER)
|
if (thing->type == MT_PLAYER)
|
||||||
{
|
{
|
||||||
S_StartSound(NULL, sfx_bsnipe); //let all players hear it.
|
mobj_t *explosion;
|
||||||
|
|
||||||
|
S_StartSound(NULL, sfx_bsnipe); // let all players hear it.
|
||||||
|
|
||||||
HU_SetCEchoFlags(0);
|
HU_SetCEchoFlags(0);
|
||||||
HU_SetCEchoDuration(5);
|
HU_SetCEchoDuration(5);
|
||||||
HU_DoCEcho(va("%s\\was hit by a kitchen sink.\\\\\\\\", player_names[thing->player-players]));
|
HU_DoCEcho(va("%s\\was hit by a kitchen sink.\\\\\\\\", player_names[thing->player-players]));
|
||||||
I_OutputMsg("%s was hit by a kitchen sink.\n", player_names[thing->player-players]);
|
I_OutputMsg("%s was hit by a kitchen sink.\n", player_names[thing->player-players]);
|
||||||
P_DamageMobj(thing, tmthing, tmthing->target, 10000);
|
|
||||||
|
explosion = P_SpawnMobj(thing->x, thing->y, thing->z, MT_SPBEXPLOSION);
|
||||||
|
explosion->extravalue1 = 1; // Tell K_ExplodePlayer to use extra knockback
|
||||||
|
if (tmthing->target && !P_MobjWasRemoved(tmthing->target))
|
||||||
|
P_SetTarget(&explosion->target, tmthing->target);
|
||||||
|
|
||||||
P_KillMobj(tmthing, thing, thing);
|
P_KillMobj(tmthing, thing, thing);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1271,15 +1279,23 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
||||||
}
|
}
|
||||||
else if (thing->type == MT_SINK)
|
else if (thing->type == MT_SINK)
|
||||||
{
|
{
|
||||||
|
mobj_t *explosion;
|
||||||
|
|
||||||
if ((thing->target == tmthing) && (thing->threshold > 0))
|
if ((thing->target == tmthing) && (thing->threshold > 0))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
S_StartSound(NULL, sfx_cgot); //let all players hear it.
|
S_StartSound(NULL, sfx_bsnipe); // let all players hear it.
|
||||||
|
|
||||||
HU_SetCEchoFlags(0);
|
HU_SetCEchoFlags(0);
|
||||||
HU_SetCEchoDuration(5);
|
HU_SetCEchoDuration(5);
|
||||||
HU_DoCEcho(va("%s\\was hit by a kitchen sink.\\\\\\\\", player_names[tmthing->player-players]));
|
HU_DoCEcho(va("%s\\was hit by a kitchen sink.\\\\\\\\", player_names[tmthing->player-players]));
|
||||||
I_OutputMsg("%s was hit by a kitchen sink.\n", player_names[tmthing->player-players]);
|
I_OutputMsg("%s was hit by a kitchen sink.\n", player_names[tmthing->player-players]);
|
||||||
P_DamageMobj(tmthing, thing, thing->target, 10000);
|
|
||||||
|
explosion = P_SpawnMobj(tmthing->x, tmthing->y, tmthing->z, MT_SPBEXPLOSION);
|
||||||
|
explosion->extravalue1 = 1; // Tell K_ExplodePlayer to use extra knockback
|
||||||
|
if (thing->target && !P_MobjWasRemoved(thing->target))
|
||||||
|
P_SetTarget(&explosion->target, thing->target);
|
||||||
|
|
||||||
P_KillMobj(thing, tmthing, tmthing);
|
P_KillMobj(thing, tmthing, tmthing);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1419,7 +1435,7 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
||||||
|
|
||||||
thing->angle = tmthing->angle;
|
thing->angle = tmthing->angle;
|
||||||
|
|
||||||
if (!demo.playback || P_AnalogMove(thing->player))
|
if (!demo.playback)
|
||||||
{
|
{
|
||||||
if (thing->player == &players[consoleplayer])
|
if (thing->player == &players[consoleplayer])
|
||||||
localangle[0] = thing->angle;
|
localangle[0] = thing->angle;
|
||||||
|
|
@ -1664,7 +1680,7 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
||||||
{
|
{
|
||||||
// Objects kill you if it falls from above.
|
// Objects kill you if it falls from above.
|
||||||
if (thing != tmthing->target)
|
if (thing != tmthing->target)
|
||||||
P_DamageMobj(thing, tmthing, tmthing->target, 10000);
|
K_DoIngameRespawn(thing->player);
|
||||||
|
|
||||||
tmthing->momz = -tmthing->momz/2; // Bounce, just for fun!
|
tmthing->momz = -tmthing->momz/2; // Bounce, just for fun!
|
||||||
// The tmthing->target allows the pusher of the object
|
// The tmthing->target allows the pusher of the object
|
||||||
|
|
@ -2082,7 +2098,7 @@ static boolean PIT_CheckLine(line_t *ld)
|
||||||
if (P_BoxOnLineSide(tmbbox, ld) != -1)
|
if (P_BoxOnLineSide(tmbbox, ld) != -1)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (tmthing->flags & MF_PAPERCOLLISION) // Caution! Turning whilst up against a wall will get you stuck. You probably shouldn't give the player this flag.
|
if (tmthing->flags & MF_PAPERCOLLISION) // Caution! Turning whilst up against a wall will get you stuck. You probably shouldn't give the player this flag.
|
||||||
{
|
{
|
||||||
fixed_t cosradius, sinradius;
|
fixed_t cosradius, sinradius;
|
||||||
cosradius = FixedMul(tmthing->radius, FINECOSINE(tmthing->angle>>ANGLETOFINESHIFT));
|
cosradius = FixedMul(tmthing->radius, FINECOSINE(tmthing->angle>>ANGLETOFINESHIFT));
|
||||||
|
|
@ -2883,8 +2899,10 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
|
||||||
// reset this to 0 at the start of each trymove call as it's only used here
|
// reset this to 0 at the start of each trymove call as it's only used here
|
||||||
numspechitint = 0U;
|
numspechitint = 0U;
|
||||||
|
|
||||||
if (radius < MAXRADIUS/2)
|
// This makes sure that there are no freezes from computing extremely small movements.
|
||||||
radius = MAXRADIUS/2;
|
// Originally was MAXRADIUS/2, but that causes some inconsistencies for small players.
|
||||||
|
if (radius < mapobjectscale)
|
||||||
|
radius = mapobjectscale;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
if (thing->flags & MF_NOCLIP) {
|
if (thing->flags & MF_NOCLIP) {
|
||||||
|
|
|
||||||
123
src/p_mobj.c
123
src/p_mobj.c
|
|
@ -47,6 +47,7 @@ consvar_t cv_splats = {"splats", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0
|
||||||
actioncache_t actioncachehead;
|
actioncache_t actioncachehead;
|
||||||
|
|
||||||
static mobj_t *overlaycap = NULL;
|
static mobj_t *overlaycap = NULL;
|
||||||
|
mobj_t *kitemcap = NULL; // Used for Kart offensive items (the ones that can get removed by sizedown)
|
||||||
mobj_t *waypointcap = NULL;
|
mobj_t *waypointcap = NULL;
|
||||||
|
|
||||||
void P_InitCachedActions(void)
|
void P_InitCachedActions(void)
|
||||||
|
|
@ -1655,18 +1656,11 @@ void P_XYMovement(mobj_t *mo)
|
||||||
{
|
{
|
||||||
mo->health--;
|
mo->health--;
|
||||||
if (mo->health == 0)
|
if (mo->health == 0)
|
||||||
mo->destscale = 1;
|
mo->destscale = 0;
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (mo->scale < mapobjectscale/16)
|
|
||||||
{
|
|
||||||
P_RemoveMobj(mo);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//}
|
//}
|
||||||
|
|
||||||
if (!P_TryMove(mo, mo->x + xmove, mo->y + ymove, true) && !(mo->eflags & MFE_SPRUNG))
|
if (!P_TryMove(mo, mo->x + xmove, mo->y + ymove, true) && !(mo->eflags & MFE_SPRUNG))
|
||||||
{
|
{
|
||||||
// blocked move
|
// blocked move
|
||||||
|
|
@ -6105,6 +6099,71 @@ static boolean P_AddShield(mobj_t *thing)
|
||||||
return true;
|
return true;
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
|
|
||||||
|
// Kartitem stuff.
|
||||||
|
boolean P_IsKartItem(INT32 type)
|
||||||
|
{
|
||||||
|
if (type == MT_EGGMANITEM || type == MT_EGGMANITEM_SHIELD ||
|
||||||
|
type == MT_BANANA || type == MT_BANANA_SHIELD ||
|
||||||
|
type == MT_ORBINAUT || type == MT_ORBINAUT_SHIELD ||
|
||||||
|
type == MT_JAWZ || type == MT_JAWZ_DUD || type == MT_JAWZ_SHIELD ||
|
||||||
|
type == MT_SSMINE || type == MT_SSMINE_SHIELD ||
|
||||||
|
type == MT_SINK || type == MT_SINK_SHIELD ||
|
||||||
|
type == MT_SPB)
|
||||||
|
return true;
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Called when a kart item "thinks"
|
||||||
|
void P_AddKartItem(mobj_t *thing)
|
||||||
|
{
|
||||||
|
I_Assert(thing != NULL);
|
||||||
|
|
||||||
|
if (kitemcap == NULL)
|
||||||
|
P_SetTarget(&kitemcap, thing);
|
||||||
|
else {
|
||||||
|
mobj_t *mo;
|
||||||
|
for (mo = kitemcap; mo && mo->itnext; mo = mo->itnext)
|
||||||
|
;
|
||||||
|
|
||||||
|
I_Assert(mo != NULL);
|
||||||
|
I_Assert(mo->itnext == NULL);
|
||||||
|
|
||||||
|
P_SetTarget(&mo->itnext, thing);
|
||||||
|
}
|
||||||
|
P_SetTarget(&thing->itnext, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Called only when a kart item is removed
|
||||||
|
// Keeps the hnext list from corrupting.
|
||||||
|
static void P_RemoveKartItem(mobj_t *thing)
|
||||||
|
{
|
||||||
|
mobj_t *mo;
|
||||||
|
for (mo = kitemcap; mo; mo = mo->itnext)
|
||||||
|
if (mo->itnext == thing)
|
||||||
|
{
|
||||||
|
P_SetTarget(&mo->itnext, thing->itnext);
|
||||||
|
P_SetTarget(&thing->itnext, NULL);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Doesn't actually do anything since items have their own thinkers,
|
||||||
|
// but this is necessary for the sole purpose of updating kitemcap
|
||||||
|
void P_RunKartItems(void)
|
||||||
|
{
|
||||||
|
mobj_t *mobj, *next;
|
||||||
|
|
||||||
|
for (mobj = kitemcap; mobj; mobj = next)
|
||||||
|
{
|
||||||
|
next = mobj->itnext;
|
||||||
|
P_SetTarget(&mobj->itnext, NULL);
|
||||||
|
}
|
||||||
|
P_SetTarget(&kitemcap, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void P_RunOverlays(void)
|
void P_RunOverlays(void)
|
||||||
{
|
{
|
||||||
// run overlays
|
// run overlays
|
||||||
|
|
@ -6538,16 +6597,25 @@ void P_MobjThinker(mobj_t *mobj)
|
||||||
mobj->z -= mobj->height - oldheight;
|
mobj->z -= mobj->height - oldheight;
|
||||||
|
|
||||||
if (mobj->scale == mobj->destscale)
|
if (mobj->scale == mobj->destscale)
|
||||||
|
{
|
||||||
/// \todo Lua hook for "reached destscale"?
|
/// \todo Lua hook for "reached destscale"?
|
||||||
switch(mobj->type)
|
|
||||||
|
if (mobj->scale == 0)
|
||||||
{
|
{
|
||||||
case MT_EGGMOBILE_FIRE:
|
P_RemoveMobj(mobj);
|
||||||
mobj->destscale = FRACUNIT;
|
return;
|
||||||
mobj->scalespeed = FRACUNIT>>4;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch (mobj->type)
|
||||||
|
{
|
||||||
|
case MT_EGGMOBILE_FIRE:
|
||||||
|
mobj->destscale = FRACUNIT;
|
||||||
|
mobj->scalespeed = FRACUNIT>>4;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mobj->type == MT_GHOST && mobj->fuse > 0 // Not guaranteed to be MF_SCENERY or not MF_SCENERY!
|
if (mobj->type == MT_GHOST && mobj->fuse > 0 // Not guaranteed to be MF_SCENERY or not MF_SCENERY!
|
||||||
|
|
@ -9728,6 +9796,12 @@ for (i = ((mobj->flags2 & MF2_STRONGBOX) ? strongboxamt : weakboxamt); i; --i) s
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (P_MobjWasRemoved(mobj))
|
||||||
|
return; // obligatory paranoia check
|
||||||
|
|
||||||
|
if (P_IsKartItem(mobj->type)) // mobj is a kart item we want on the list:
|
||||||
|
P_AddKartItem(mobj); // add to kitem list
|
||||||
|
|
||||||
// Can end up here if a player dies.
|
// Can end up here if a player dies.
|
||||||
if (mobj->player)
|
if (mobj->player)
|
||||||
P_CyclePlayerMobjState(mobj);
|
P_CyclePlayerMobjState(mobj);
|
||||||
|
|
@ -10408,6 +10482,10 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case MT_BOSS3WAYPOINT:
|
||||||
|
// Remove before release
|
||||||
|
CONS_Alert(CONS_WARNING, "Boss waypoints are deprecated. Did you forget to remove the old checkpoints, too?\n");
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -10563,6 +10641,9 @@ void P_RemoveMobj(mobj_t *mobj)
|
||||||
if (mobj->type == MT_SPB)
|
if (mobj->type == MT_SPB)
|
||||||
spbplace = -1;
|
spbplace = -1;
|
||||||
|
|
||||||
|
if (P_IsKartItem(mobj->type))
|
||||||
|
P_RemoveKartItem(mobj);
|
||||||
|
|
||||||
mobj->health = 0; // Just because
|
mobj->health = 0; // Just because
|
||||||
|
|
||||||
// unlink from sector and block lists
|
// unlink from sector and block lists
|
||||||
|
|
@ -11148,6 +11229,9 @@ void P_SpawnPlayer(INT32 playernum)
|
||||||
// Spawn with a pity shield if necessary.
|
// Spawn with a pity shield if necessary.
|
||||||
//P_DoPityCheck(p);
|
//P_DoPityCheck(p);
|
||||||
|
|
||||||
|
if (p->kartstuff[k_respawn] != 0)
|
||||||
|
p->mo->flags |= MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOCLIPTHING|MF_NOGRAVITY;
|
||||||
|
|
||||||
if (G_BattleGametype()) // SRB2kart
|
if (G_BattleGametype()) // SRB2kart
|
||||||
{
|
{
|
||||||
mobj_t *overheadarrow = P_SpawnMobj(mobj->x, mobj->y, mobj->z + P_GetPlayerHeight(p)+16*FRACUNIT, MT_PLAYERARROW);
|
mobj_t *overheadarrow = P_SpawnMobj(mobj->x, mobj->y, mobj->z + P_GetPlayerHeight(p)+16*FRACUNIT, MT_PLAYERARROW);
|
||||||
|
|
@ -11364,11 +11448,10 @@ void P_MovePlayerToStarpost(INT32 playernum)
|
||||||
sector->ceilingheight;
|
sector->ceilingheight;
|
||||||
|
|
||||||
if (mobj->player->kartstuff[k_starpostflip])
|
if (mobj->player->kartstuff[k_starpostflip])
|
||||||
z = (p->starpostz<<FRACBITS) - FixedMul(128<<FRACBITS, mapobjectscale) - mobj->height;
|
z = (p->starpostz<<FRACBITS) - (128 * mapobjectscale) - mobj->height;
|
||||||
else
|
else
|
||||||
z = (p->starpostz<<FRACBITS) + FixedMul(128<<FRACBITS, mapobjectscale);
|
z = (p->starpostz<<FRACBITS) + (128 * mapobjectscale);
|
||||||
|
|
||||||
//z = (p->starpostz + 128) << FRACBITS; // reverse gravity exists, pls
|
|
||||||
mobj->player->kartstuff[k_starpostflip] = 0;
|
mobj->player->kartstuff[k_starpostflip] = 0;
|
||||||
|
|
||||||
if (z < floor)
|
if (z < floor)
|
||||||
|
|
@ -11962,7 +12045,7 @@ ML_NOCLIMB : Direction not controllable
|
||||||
case MT_WAYPOINT:
|
case MT_WAYPOINT:
|
||||||
{
|
{
|
||||||
size_t line;
|
size_t line;
|
||||||
mobj->radius = 256*FRACUNIT;
|
mobj->radius = 384*FRACUNIT;
|
||||||
// Same reason as for MT_SPINMACEPOINT we can't use the function to find the linedef
|
// Same reason as for MT_SPINMACEPOINT we can't use the function to find the linedef
|
||||||
for (line = 0; line < numlines; line++)
|
for (line = 0; line < numlines; line++)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -319,6 +319,9 @@ typedef struct mobj_s
|
||||||
struct mobj_s *hnext;
|
struct mobj_s *hnext;
|
||||||
struct mobj_s *hprev;
|
struct mobj_s *hprev;
|
||||||
|
|
||||||
|
// One last pointer for kart item lists
|
||||||
|
struct mobj_s *itnext;
|
||||||
|
|
||||||
INT32 health; // for player this is rings + 1
|
INT32 health; // for player this is rings + 1
|
||||||
|
|
||||||
// Movement direction, movement generation (zig-zagging).
|
// Movement direction, movement generation (zig-zagging).
|
||||||
|
|
@ -437,12 +440,18 @@ typedef struct actioncache_s
|
||||||
|
|
||||||
extern actioncache_t actioncachehead;
|
extern actioncache_t actioncachehead;
|
||||||
|
|
||||||
|
extern mobj_t *kitemcap;
|
||||||
extern mobj_t *waypointcap;
|
extern mobj_t *waypointcap;
|
||||||
|
|
||||||
void P_InitCachedActions(void);
|
void P_InitCachedActions(void);
|
||||||
void P_RunCachedActions(void);
|
void P_RunCachedActions(void);
|
||||||
void P_AddCachedAction(mobj_t *mobj, INT32 statenum);
|
void P_AddCachedAction(mobj_t *mobj, INT32 statenum);
|
||||||
|
|
||||||
|
// kartitem stuff: Returns true if the specified 'type' is one of the kart item constants we want in the kitemcap list
|
||||||
|
boolean P_IsKartItem(INT32 type);
|
||||||
|
void P_AddKartItem(mobj_t *thing); // needs to be called in k_kart.c
|
||||||
|
void P_RunKartItems(void);
|
||||||
|
|
||||||
// check mobj against water content, before movement code
|
// check mobj against water content, before movement code
|
||||||
void P_MobjCheckWater(mobj_t *mobj);
|
void P_MobjCheckWater(mobj_t *mobj);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -957,9 +957,11 @@ typedef enum
|
||||||
MD2_HNEXT = 1<<7,
|
MD2_HNEXT = 1<<7,
|
||||||
MD2_HPREV = 1<<8,
|
MD2_HPREV = 1<<8,
|
||||||
MD2_COLORIZED = 1<<9,
|
MD2_COLORIZED = 1<<9,
|
||||||
MD2_WAYPOINTCAP = 1<<10
|
MD2_WAYPOINTCAP = 1<<10,
|
||||||
|
MD2_KITEMCAP = 1<<11,
|
||||||
|
MD2_ITNEXT = 1<<12
|
||||||
#ifdef ESLOPE
|
#ifdef ESLOPE
|
||||||
, MD2_SLOPE = 1<<11
|
, MD2_SLOPE = 1<<13
|
||||||
#endif
|
#endif
|
||||||
} mobj_diff2_t;
|
} mobj_diff2_t;
|
||||||
|
|
||||||
|
|
@ -1151,6 +1153,8 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type)
|
||||||
diff2 |= MD2_HNEXT;
|
diff2 |= MD2_HNEXT;
|
||||||
if (mobj->hprev)
|
if (mobj->hprev)
|
||||||
diff2 |= MD2_HPREV;
|
diff2 |= MD2_HPREV;
|
||||||
|
if (mobj->itnext)
|
||||||
|
diff2 |= MD2_ITNEXT;
|
||||||
#ifdef ESLOPE
|
#ifdef ESLOPE
|
||||||
if (mobj->standingslope)
|
if (mobj->standingslope)
|
||||||
diff2 |= MD2_SLOPE;
|
diff2 |= MD2_SLOPE;
|
||||||
|
|
@ -1159,6 +1163,8 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type)
|
||||||
diff2 |= MD2_COLORIZED;
|
diff2 |= MD2_COLORIZED;
|
||||||
if (mobj == waypointcap)
|
if (mobj == waypointcap)
|
||||||
diff2 |= MD2_WAYPOINTCAP;
|
diff2 |= MD2_WAYPOINTCAP;
|
||||||
|
if (mobj == kitemcap)
|
||||||
|
diff2 |= MD2_KITEMCAP;
|
||||||
if (diff2 != 0)
|
if (diff2 != 0)
|
||||||
diff |= MD_MORE;
|
diff |= MD_MORE;
|
||||||
|
|
||||||
|
|
@ -1274,6 +1280,8 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type)
|
||||||
WRITEUINT32(save_p, mobj->hnext->mobjnum);
|
WRITEUINT32(save_p, mobj->hnext->mobjnum);
|
||||||
if (diff2 & MD2_HPREV)
|
if (diff2 & MD2_HPREV)
|
||||||
WRITEUINT32(save_p, mobj->hprev->mobjnum);
|
WRITEUINT32(save_p, mobj->hprev->mobjnum);
|
||||||
|
if (diff2 & MD2_ITNEXT)
|
||||||
|
WRITEUINT32(save_p, mobj->itnext->mobjnum);
|
||||||
#ifdef ESLOPE
|
#ifdef ESLOPE
|
||||||
if (diff2 & MD2_SLOPE)
|
if (diff2 & MD2_SLOPE)
|
||||||
WRITEUINT16(save_p, mobj->standingslope->id);
|
WRITEUINT16(save_p, mobj->standingslope->id);
|
||||||
|
|
@ -2151,6 +2159,8 @@ static void LoadMobjThinker(actionf_p1 thinker)
|
||||||
mobj->hnext = (mobj_t *)(size_t)READUINT32(save_p);
|
mobj->hnext = (mobj_t *)(size_t)READUINT32(save_p);
|
||||||
if (diff2 & MD2_HPREV)
|
if (diff2 & MD2_HPREV)
|
||||||
mobj->hprev = (mobj_t *)(size_t)READUINT32(save_p);
|
mobj->hprev = (mobj_t *)(size_t)READUINT32(save_p);
|
||||||
|
if (diff2 & MD2_ITNEXT)
|
||||||
|
mobj->itnext = (mobj_t *)(size_t)READUINT32(save_p);
|
||||||
#ifdef ESLOPE
|
#ifdef ESLOPE
|
||||||
if (diff2 & MD2_SLOPE)
|
if (diff2 & MD2_SLOPE)
|
||||||
{
|
{
|
||||||
|
|
@ -2192,6 +2202,9 @@ static void LoadMobjThinker(actionf_p1 thinker)
|
||||||
if (diff2 & MD2_WAYPOINTCAP)
|
if (diff2 & MD2_WAYPOINTCAP)
|
||||||
P_SetTarget(&waypointcap, mobj);
|
P_SetTarget(&waypointcap, mobj);
|
||||||
|
|
||||||
|
if (diff2 & MD2_KITEMCAP)
|
||||||
|
P_SetTarget(&kitemcap, mobj);
|
||||||
|
|
||||||
mobj->info = (mobjinfo_t *)next; // temporarily, set when leave this function
|
mobj->info = (mobjinfo_t *)next; // temporarily, set when leave this function
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -3044,6 +3057,13 @@ static void P_RelinkPointers(void)
|
||||||
if (!(mobj->hprev = P_FindNewPosition(temp)))
|
if (!(mobj->hprev = P_FindNewPosition(temp)))
|
||||||
CONS_Debug(DBG_GAMELOGIC, "hprev not found on %d\n", mobj->type);
|
CONS_Debug(DBG_GAMELOGIC, "hprev not found on %d\n", mobj->type);
|
||||||
}
|
}
|
||||||
|
if (mobj->itnext)
|
||||||
|
{
|
||||||
|
temp = (UINT32)(size_t)mobj->itnext;
|
||||||
|
mobj->itnext = NULL;
|
||||||
|
if (!(mobj->itnext = P_FindNewPosition(temp)))
|
||||||
|
CONS_Debug(DBG_GAMELOGIC, "itnext not found on %d\n", mobj->type);
|
||||||
|
}
|
||||||
if (mobj->player && mobj->player->capsule)
|
if (mobj->player && mobj->player->capsule)
|
||||||
{
|
{
|
||||||
temp = (UINT32)(size_t)mobj->player->capsule;
|
temp = (UINT32)(size_t)mobj->player->capsule;
|
||||||
|
|
|
||||||
163
src/p_sight.c
163
src/p_sight.c
|
|
@ -2,7 +2,7 @@
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Copyright (C) 1993-1996 by id Software, Inc.
|
// Copyright (C) 1993-1996 by id Software, Inc.
|
||||||
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||||
// Copyright (C) 1999-2018 by Sonic Team Junior.
|
// Copyright (C) 1999-2020 by Sonic Team Junior.
|
||||||
//
|
//
|
||||||
// This program is free software distributed under the
|
// This program is free software distributed under the
|
||||||
// terms of the GNU General Public License, version 2.
|
// terms of the GNU General Public License, version 2.
|
||||||
|
|
@ -14,6 +14,7 @@
|
||||||
#include "doomdef.h"
|
#include "doomdef.h"
|
||||||
#include "doomstat.h"
|
#include "doomstat.h"
|
||||||
#include "p_local.h"
|
#include "p_local.h"
|
||||||
|
#include "p_slopes.h"
|
||||||
#include "r_main.h"
|
#include "r_main.h"
|
||||||
#include "r_state.h"
|
#include "r_state.h"
|
||||||
|
|
||||||
|
|
@ -103,12 +104,20 @@ static fixed_t P_InterceptVector2(divline_t *v2, divline_t *v1)
|
||||||
static boolean P_CrossSubsecPolyObj(polyobj_t *po, register los_t *los)
|
static boolean P_CrossSubsecPolyObj(polyobj_t *po, register los_t *los)
|
||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
|
sector_t *polysec;
|
||||||
|
|
||||||
|
if (!(po->flags & POF_RENDERALL))
|
||||||
|
return true; // the polyobject isn't visible, so we can ignore it
|
||||||
|
|
||||||
|
polysec = po->lines[0]->backsector;
|
||||||
|
|
||||||
for (i = 0; i < po->numLines; ++i)
|
for (i = 0; i < po->numLines; ++i)
|
||||||
{
|
{
|
||||||
line_t *line = po->lines[i];
|
line_t *line = po->lines[i];
|
||||||
divline_t divl;
|
divline_t divl;
|
||||||
const vertex_t *v1,*v2;
|
const vertex_t *v1,*v2;
|
||||||
|
fixed_t frac;
|
||||||
|
fixed_t topslope, bottomslope;
|
||||||
|
|
||||||
// already checked other side?
|
// already checked other side?
|
||||||
if (line->validcount == validcount)
|
if (line->validcount == validcount)
|
||||||
|
|
@ -140,7 +149,22 @@ static boolean P_CrossSubsecPolyObj(polyobj_t *po, register los_t *los)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// stop because it is not two sided
|
// stop because it is not two sided
|
||||||
return false;
|
//if (!(po->flags & POF_TESTHEIGHT))
|
||||||
|
//return false;
|
||||||
|
|
||||||
|
frac = P_InterceptVector2(&los->strace, &divl);
|
||||||
|
|
||||||
|
// get slopes of top and bottom of this polyobject line
|
||||||
|
topslope = FixedDiv(polysec->ceilingheight - los->sightzstart , frac);
|
||||||
|
bottomslope = FixedDiv(polysec->floorheight - los->sightzstart , frac);
|
||||||
|
|
||||||
|
if (topslope >= los->topslope && bottomslope <= los->bottomslope)
|
||||||
|
return false; // view completely blocked
|
||||||
|
|
||||||
|
// TODO: figure out if it's worth considering partially blocked cases or not?
|
||||||
|
// maybe to adjust los's top/bottom slopes if needed
|
||||||
|
//if (los->topslope <= los->bottomslope)
|
||||||
|
//return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -193,6 +217,15 @@ static boolean P_CrossSubsector(size_t num, register los_t *los)
|
||||||
const sector_t *front, *back;
|
const sector_t *front, *back;
|
||||||
const vertex_t *v1,*v2;
|
const vertex_t *v1,*v2;
|
||||||
fixed_t frac;
|
fixed_t frac;
|
||||||
|
fixed_t frontf, backf, frontc, backc;
|
||||||
|
#ifdef ESLOPE
|
||||||
|
fixed_t fracx, fracy;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* SRB2Kart doesn't have this?
|
||||||
|
if (seg->glseg)
|
||||||
|
continue;
|
||||||
|
*/
|
||||||
|
|
||||||
// already checked other side?
|
// already checked other side?
|
||||||
if (line->validcount == validcount)
|
if (line->validcount == validcount)
|
||||||
|
|
@ -227,36 +260,51 @@ static boolean P_CrossSubsector(size_t num, register los_t *los)
|
||||||
if (!(line->flags & ML_TWOSIDED))
|
if (!(line->flags & ML_TWOSIDED))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
// calculate fractional intercept (how far along we are divided by how far we are from t2)
|
||||||
|
frac = P_InterceptVector2(&los->strace, &divl);
|
||||||
|
|
||||||
|
front = seg->frontsector;
|
||||||
|
back = seg->backsector;
|
||||||
|
#ifdef ESLOPE
|
||||||
|
// calculate position at intercept
|
||||||
|
fracx = los->strace.x + FixedMul(los->strace.dx, frac);
|
||||||
|
fracy = los->strace.y + FixedMul(los->strace.dy, frac);
|
||||||
|
// calculate sector heights
|
||||||
|
frontf = (front->f_slope) ? P_GetZAt(front->f_slope, fracx, fracy) : front->floorheight;
|
||||||
|
frontc = (front->c_slope) ? P_GetZAt(front->c_slope, fracx, fracy) : front->ceilingheight;
|
||||||
|
backf = (back->f_slope) ? P_GetZAt(back->f_slope, fracx, fracy) : back->floorheight;
|
||||||
|
backc = (back->c_slope) ? P_GetZAt(back->c_slope, fracx, fracy) : back->ceilingheight;
|
||||||
|
#else
|
||||||
|
frontf = front->floorheight;
|
||||||
|
frontc = front->ceilingheight;
|
||||||
|
backf = back->floorheight;
|
||||||
|
backc = back->ceilingheight;
|
||||||
|
#endif
|
||||||
// crosses a two sided line
|
// crosses a two sided line
|
||||||
// no wall to block sight with?
|
// no wall to block sight with?
|
||||||
if ((front = seg->frontsector)->floorheight ==
|
if (frontf == backf && frontc == backc
|
||||||
(back = seg->backsector)->floorheight &&
|
&& !front->ffloors & !back->ffloors) // (and no FOFs)
|
||||||
front->ceilingheight == back->ceilingheight)
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// possible occluder
|
// possible occluder
|
||||||
// because of ceiling height differences
|
// because of ceiling height differences
|
||||||
popentop = front->ceilingheight < back->ceilingheight ?
|
popentop = min(frontc, backc);
|
||||||
front->ceilingheight : back->ceilingheight ;
|
|
||||||
|
|
||||||
// because of floor height differences
|
// because of floor height differences
|
||||||
popenbottom = front->floorheight > back->floorheight ?
|
popenbottom = max(frontf, backf);
|
||||||
front->floorheight : back->floorheight ;
|
|
||||||
|
|
||||||
// quick test for totally closed doors
|
// quick test for totally closed doors
|
||||||
if (popenbottom >= popentop)
|
if (popenbottom >= popentop)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
frac = P_InterceptVector2(&los->strace, &divl);
|
if (frontf != backf)
|
||||||
|
|
||||||
if (front->floorheight != back->floorheight)
|
|
||||||
{
|
{
|
||||||
fixed_t slope = FixedDiv(popenbottom - los->sightzstart , frac);
|
fixed_t slope = FixedDiv(popenbottom - los->sightzstart , frac);
|
||||||
if (slope > los->bottomslope)
|
if (slope > los->bottomslope)
|
||||||
los->bottomslope = slope;
|
los->bottomslope = slope;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (front->ceilingheight != back->ceilingheight)
|
if (frontc != backc)
|
||||||
{
|
{
|
||||||
fixed_t slope = FixedDiv(popentop - los->sightzstart , frac);
|
fixed_t slope = FixedDiv(popentop - los->sightzstart , frac);
|
||||||
if (slope < los->topslope)
|
if (slope < los->topslope)
|
||||||
|
|
@ -265,6 +313,58 @@ static boolean P_CrossSubsector(size_t num, register los_t *los)
|
||||||
|
|
||||||
if (los->topslope <= los->bottomslope)
|
if (los->topslope <= los->bottomslope)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
// Monster Iestyn: check FOFs!
|
||||||
|
if (front->ffloors || back->ffloors)
|
||||||
|
{
|
||||||
|
ffloor_t *rover;
|
||||||
|
fixed_t topslope, bottomslope;
|
||||||
|
fixed_t topz, bottomz;
|
||||||
|
// check front sector's FOFs first
|
||||||
|
for (rover = front->ffloors; rover; rover = rover->next)
|
||||||
|
{
|
||||||
|
if (!(rover->flags & FF_EXISTS)
|
||||||
|
|| !(rover->flags & FF_RENDERSIDES) || rover->flags & FF_TRANSLUCENT)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef ESLOPE
|
||||||
|
topz = (*rover->t_slope) ? P_GetZAt(*rover->t_slope, fracx, fracy) : *rover->topheight;
|
||||||
|
bottomz = (*rover->b_slope) ? P_GetZAt(*rover->b_slope, fracx, fracy) : *rover->bottomheight;
|
||||||
|
#else
|
||||||
|
topz = *rover->topheight;
|
||||||
|
bottomz = *rover->bottomheight;
|
||||||
|
#endif
|
||||||
|
topslope = FixedDiv(topz - los->sightzstart , frac);
|
||||||
|
bottomslope = FixedDiv(bottomz - los->sightzstart , frac);
|
||||||
|
if (topslope >= los->topslope && bottomslope <= los->bottomslope)
|
||||||
|
return false; // view completely blocked
|
||||||
|
}
|
||||||
|
// check back sector's FOFs as well
|
||||||
|
for (rover = back->ffloors; rover; rover = rover->next)
|
||||||
|
{
|
||||||
|
if (!(rover->flags & FF_EXISTS)
|
||||||
|
|| !(rover->flags & FF_RENDERSIDES) || rover->flags & FF_TRANSLUCENT)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef ESLOPE
|
||||||
|
topz = (*rover->t_slope) ? P_GetZAt(*rover->t_slope, fracx, fracy) : *rover->topheight;
|
||||||
|
bottomz = (*rover->b_slope) ? P_GetZAt(*rover->b_slope, fracx, fracy) : *rover->bottomheight;
|
||||||
|
#else
|
||||||
|
topz = *rover->topheight;
|
||||||
|
bottomz = *rover->bottomheight;
|
||||||
|
#endif
|
||||||
|
topslope = FixedDiv(topz - los->sightzstart , frac);
|
||||||
|
bottomslope = FixedDiv(bottomz - los->sightzstart , frac);
|
||||||
|
if (topslope >= los->topslope && bottomslope <= los->bottomslope)
|
||||||
|
return false; // view completely blocked
|
||||||
|
}
|
||||||
|
// TODO: figure out if it's worth considering partially blocked cases or not?
|
||||||
|
// maybe to adjust los's top/bottom slopes if needed
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// passed the subsector ok
|
// passed the subsector ok
|
||||||
|
|
@ -375,6 +475,8 @@ boolean P_CheckSight(mobj_t *t1, mobj_t *t2)
|
||||||
if (s1 == s2) // Both sectors are the same.
|
if (s1 == s2) // Both sectors are the same.
|
||||||
{
|
{
|
||||||
ffloor_t *rover;
|
ffloor_t *rover;
|
||||||
|
fixed_t topz1, bottomz1; // top, bottom heights at t1's position
|
||||||
|
fixed_t topz2, bottomz2; // likewise but for t2
|
||||||
|
|
||||||
for (rover = s1->ffloors; rover; rover = rover->next)
|
for (rover = s1->ffloors; rover; rover = rover->next)
|
||||||
{
|
{
|
||||||
|
|
@ -382,14 +484,35 @@ boolean P_CheckSight(mobj_t *t1, mobj_t *t2)
|
||||||
/// \todo Improve by checking fog density/translucency
|
/// \todo Improve by checking fog density/translucency
|
||||||
/// and setting a sight limit.
|
/// and setting a sight limit.
|
||||||
if (!(rover->flags & FF_EXISTS)
|
if (!(rover->flags & FF_EXISTS)
|
||||||
|| !(rover->flags & FF_RENDERPLANES) || rover->flags & FF_TRANSLUCENT)
|
|| !(rover->flags & FF_RENDERPLANES) /*|| (rover->flags & FF_TRANSLUCENT)*/)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef ESLOPE
|
||||||
|
if (*rover->t_slope)
|
||||||
|
{
|
||||||
|
topz1 = P_GetZAt(*rover->t_slope, t1->x, t1->y);
|
||||||
|
topz2 = P_GetZAt(*rover->t_slope, t2->x, t2->y);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
topz1 = topz2 = *rover->topheight;
|
||||||
|
|
||||||
|
if (*rover->b_slope)
|
||||||
|
{
|
||||||
|
bottomz1 = P_GetZAt(*rover->b_slope, t1->x, t1->y);
|
||||||
|
bottomz2 = P_GetZAt(*rover->b_slope, t2->x, t2->y);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
bottomz1 = bottomz2 = *rover->bottomheight;
|
||||||
|
#else
|
||||||
|
topz1 = topz2 = *rover->topheight;
|
||||||
|
bottomz1 = bottomz2 = *rover->bottomheight;
|
||||||
|
#endif
|
||||||
|
|
||||||
// Check for blocking floors here.
|
// Check for blocking floors here.
|
||||||
if ((los.sightzstart < *rover->bottomheight && t2->z >= *rover->topheight)
|
if ((los.sightzstart < bottomz1 && t2->z >= topz2)
|
||||||
|| (los.sightzstart >= *rover->topheight && t2->z + t2->height < *rover->bottomheight))
|
|| (los.sightzstart >= topz1 && t2->z + t2->height < bottomz2))
|
||||||
{
|
{
|
||||||
// no way to see through that
|
// no way to see through that
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -400,19 +523,19 @@ boolean P_CheckSight(mobj_t *t1, mobj_t *t2)
|
||||||
|
|
||||||
if (!(rover->flags & FF_INVERTPLANES))
|
if (!(rover->flags & FF_INVERTPLANES))
|
||||||
{
|
{
|
||||||
if (los.sightzstart >= *rover->topheight && t2->z + t2->height < *rover->topheight)
|
if (los.sightzstart >= topz1 && t2->z + t2->height < topz2)
|
||||||
return false; // blocked by upper outside plane
|
return false; // blocked by upper outside plane
|
||||||
|
|
||||||
if (los.sightzstart < *rover->bottomheight && t2->z >= *rover->bottomheight)
|
if (los.sightzstart < bottomz1 && t2->z >= bottomz2)
|
||||||
return false; // blocked by lower outside plane
|
return false; // blocked by lower outside plane
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rover->flags & FF_INVERTPLANES || rover->flags & FF_BOTHPLANES)
|
if (rover->flags & FF_INVERTPLANES || rover->flags & FF_BOTHPLANES)
|
||||||
{
|
{
|
||||||
if (los.sightzstart < *rover->topheight && t2->z >= *rover->topheight)
|
if (los.sightzstart < topz1 && t2->z >= topz2)
|
||||||
return false; // blocked by upper inside plane
|
return false; // blocked by upper inside plane
|
||||||
|
|
||||||
if (los.sightzstart >= *rover->bottomheight && t2->z + t2->height < *rover->bottomheight)
|
if (los.sightzstart >= bottomz1 && t2->z + t2->height < bottomz2)
|
||||||
return false; // blocked by lower inside plane
|
return false; // blocked by lower inside plane
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
130
src/p_spec.c
130
src/p_spec.c
|
|
@ -1705,41 +1705,6 @@ boolean P_RunTriggerLinedef(line_t *triggerline, mobj_t *actor, sector_t *caller
|
||||||
if (!(ALL7EMERALDS(emeralds)))
|
if (!(ALL7EMERALDS(emeralds)))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else if (GETSECSPECIAL(caller->special, 2) == 7) // SRB2Kart: reusing for Race Lap executor
|
|
||||||
{
|
|
||||||
UINT8 lap;
|
|
||||||
|
|
||||||
if (actor && actor->player && triggerline->flags & ML_EFFECT4)
|
|
||||||
{
|
|
||||||
/*if (maptol & TOL_NIGHTS)
|
|
||||||
lap = actor->player->mare;
|
|
||||||
else*/
|
|
||||||
lap = actor->player->laps;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/*if (maptol & TOL_NIGHTS)
|
|
||||||
lap = P_FindLowestMare();
|
|
||||||
else*/
|
|
||||||
lap = P_FindLowestLap();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (triggerline->flags & ML_NOCLIMB) // Need higher than or equal to
|
|
||||||
{
|
|
||||||
if (lap < (sides[triggerline->sidenum[0]].textureoffset >> FRACBITS))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else if (triggerline->flags & ML_BLOCKMONSTERS) // Need lower than or equal to
|
|
||||||
{
|
|
||||||
if (lap > (sides[triggerline->sidenum[0]].textureoffset >> FRACBITS))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else // Need equal to
|
|
||||||
{
|
|
||||||
if (lap != (sides[triggerline->sidenum[0]].textureoffset >> FRACBITS))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// If we were not triggered by a sector type especially for the purpose,
|
// If we were not triggered by a sector type especially for the purpose,
|
||||||
// a Linedef Executor linedef trigger is not handling sector triggers properly, return.
|
// a Linedef Executor linedef trigger is not handling sector triggers properly, return.
|
||||||
|
|
||||||
|
|
@ -1937,15 +1902,17 @@ boolean P_RunTriggerLinedef(line_t *triggerline, mobj_t *actor, sector_t *caller
|
||||||
else
|
else
|
||||||
// These special types work only once
|
// These special types work only once
|
||||||
if (specialtype == 302 // Once
|
if (specialtype == 302 // Once
|
||||||
|| specialtype == 304 // Ring count - Once
|
|| specialtype == 304 // Ring count - Once
|
||||||
|| specialtype == 307 // Character ability - Once
|
|| specialtype == 307 // Character ability - Once
|
||||||
|| specialtype == 308 // Race only - Once
|
|| specialtype == 308 // Race only - Once
|
||||||
|| specialtype == 315 // No of pushables - Once
|
|| specialtype == 315 // No of pushables - Once
|
||||||
|| specialtype == 318 // Unlockable trigger - Once
|
|| specialtype == 318 // Unlockable trigger - Once
|
||||||
|| specialtype == 320 // Unlockable - Once
|
|| specialtype == 320 // Unlockable - Once
|
||||||
|| specialtype == 321 || specialtype == 322 // Trigger on X calls - Continuous + Each Time
|
|| specialtype == 321 || specialtype == 322 // Trigger on X calls - Continuous + Each Time
|
||||||
|| specialtype == 328 // Encore Load
|
|| specialtype == 328 // Encore Load
|
||||||
|| specialtype == 399) // Level Load
|
|| specialtype == 399 // Level Load
|
||||||
|
|| specialtype == 2002 // SRB2Kart Race Lap
|
||||||
|
)
|
||||||
triggerline->special = 0; // Clear it out
|
triggerline->special = 0; // Clear it out
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -1981,6 +1948,7 @@ void P_LinedefExecute(INT16 tag, mobj_t *actor, sector_t *caller)
|
||||||
if (lines[masterline].special == 313
|
if (lines[masterline].special == 313
|
||||||
|| lines[masterline].special == 399
|
|| lines[masterline].special == 399
|
||||||
|| lines[masterline].special == 328
|
|| lines[masterline].special == 328
|
||||||
|
|| lines[masterline].special == 2002 // SRB2Kart race lap trigger
|
||||||
// Each-time executors handle themselves, too
|
// Each-time executors handle themselves, too
|
||||||
|| lines[masterline].special == 301 // Each time
|
|| lines[masterline].special == 301 // Each time
|
||||||
|| lines[masterline].special == 306 // Character ability - Each time
|
|| lines[masterline].special == 306 // Character ability - Each time
|
||||||
|
|
@ -2096,7 +2064,7 @@ static void K_HandleLapIncrement(player_t *player)
|
||||||
{
|
{
|
||||||
if ((player->starpostnum == numstarposts) || (player->laps == 0))
|
if ((player->starpostnum == numstarposts) || (player->laps == 0))
|
||||||
{
|
{
|
||||||
UINT8 i = 0;
|
size_t i = 0;
|
||||||
UINT8 nump = 0;
|
UINT8 nump = 0;
|
||||||
|
|
||||||
for (i = 0; i < MAXPLAYERS; i++)
|
for (i = 0; i < MAXPLAYERS; i++)
|
||||||
|
|
@ -2172,17 +2140,42 @@ static void K_HandleLapIncrement(player_t *player)
|
||||||
P_SetupSignExit(player);
|
P_SetupSignExit(player);
|
||||||
}
|
}
|
||||||
|
|
||||||
//player->starpostangle = player->starposttime = player->starpostnum = 0;
|
|
||||||
//player->starpostx = player->starposty = player->starpostz = 0;
|
|
||||||
|
|
||||||
// Play the starpost sound for 'consistency'
|
|
||||||
// S_StartSound(player->mo, sfx_strpst);
|
|
||||||
|
|
||||||
// Figure out how many are playing on the last lap, to prevent spectate griefing
|
|
||||||
if (!nospectategrief && player->laps > (UINT8)(cv_numlaps.value))
|
|
||||||
nospectategrief = nump;
|
|
||||||
|
|
||||||
thwompsactive = true; // Lap 2 effects
|
thwompsactive = true; // Lap 2 effects
|
||||||
|
|
||||||
|
for (i = 0; i < numlines; i++)
|
||||||
|
{
|
||||||
|
if (lines[i].special == 2002) // Race lap trigger
|
||||||
|
{
|
||||||
|
UINT8 lap;
|
||||||
|
|
||||||
|
if (lines[i].flags & ML_EFFECT4)
|
||||||
|
{
|
||||||
|
lap = player->laps;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
lap = P_FindLowestLap();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lines[i].flags & ML_NOCLIMB) // Need higher than or equal to
|
||||||
|
{
|
||||||
|
if (lap < (sides[lines[i].sidenum[0]].textureoffset >> FRACBITS))
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if (lines[i].flags & ML_BLOCKMONSTERS) // Need lower than or equal to
|
||||||
|
{
|
||||||
|
if (lap > (sides[lines[i].sidenum[0]].textureoffset >> FRACBITS))
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else // Need equal to
|
||||||
|
{
|
||||||
|
if (lap != (sides[lines[i].sidenum[0]].textureoffset >> FRACBITS))
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
P_RunTriggerLinedef(&lines[i], player->mo, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (player->starpostnum)
|
else if (player->starpostnum)
|
||||||
{
|
{
|
||||||
|
|
@ -2196,7 +2189,7 @@ static void K_HandleLapDecrement(player_t *player)
|
||||||
{
|
{
|
||||||
if (player)
|
if (player)
|
||||||
{
|
{
|
||||||
if (player->laps > 0)
|
if ((player->starpostnum == 0) && (player->laps > 0))
|
||||||
{
|
{
|
||||||
player->starpostnum = numstarposts;
|
player->starpostnum = numstarposts;
|
||||||
player->laps--;
|
player->laps--;
|
||||||
|
|
@ -2220,7 +2213,7 @@ void P_CrossSpecialLine(line_t *line, INT32 side, mobj_t *thing)
|
||||||
{
|
{
|
||||||
case 2001: // Finish Line
|
case 2001: // Finish Line
|
||||||
{
|
{
|
||||||
if (G_RaceGametype() && !(player->exiting))
|
if (G_RaceGametype() && !(player->exiting) && !(player->pflags & PF_HITFINISHLINE))
|
||||||
{
|
{
|
||||||
if (((line->flags & (ML_NOCLIMB)) && (side == 0))
|
if (((line->flags & (ML_NOCLIMB)) && (side == 0))
|
||||||
|| (!(line->flags & (ML_NOCLIMB)) && (side == 1))) // crossed from behind to infront
|
|| (!(line->flags & (ML_NOCLIMB)) && (side == 1))) // crossed from behind to infront
|
||||||
|
|
@ -2231,6 +2224,8 @@ void P_CrossSpecialLine(line_t *line, INT32 side, mobj_t *thing)
|
||||||
{
|
{
|
||||||
K_HandleLapDecrement(player);
|
K_HandleLapDecrement(player);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
player->pflags |= PF_HITFINISHLINE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
@ -3776,10 +3771,10 @@ void P_ProcessSpecialSector(player_t *player, sector_t *sector, sector_t *rovers
|
||||||
case 6: // Death Pit (Camera Mod)
|
case 6: // Death Pit (Camera Mod)
|
||||||
case 7: // Death Pit (No Camera Mod)
|
case 7: // Death Pit (No Camera Mod)
|
||||||
if (roversector || P_MobjReadyToTrigger(player->mo, sector))
|
if (roversector || P_MobjReadyToTrigger(player->mo, sector))
|
||||||
P_DamageMobj(player->mo, NULL, NULL, 10000);
|
K_DoIngameRespawn(player);
|
||||||
break;
|
break;
|
||||||
case 8: // Instant Kill
|
case 8: // Instant Kill
|
||||||
P_DamageMobj(player->mo, NULL, NULL, 10000);
|
K_DoIngameRespawn(player);
|
||||||
break;
|
break;
|
||||||
case 9: // Ring Drainer (Floor Touch)
|
case 9: // Ring Drainer (Floor Touch)
|
||||||
case 10: // Ring Drainer (No Floor Touch)
|
case 10: // Ring Drainer (No Floor Touch)
|
||||||
|
|
@ -4017,7 +4012,7 @@ DoneSection2:
|
||||||
if (player->mo->scale > mapobjectscale)
|
if (player->mo->scale > mapobjectscale)
|
||||||
linespeed = FixedMul(linespeed, mapobjectscale + (player->mo->scale - mapobjectscale));
|
linespeed = FixedMul(linespeed, mapobjectscale + (player->mo->scale - mapobjectscale));
|
||||||
|
|
||||||
if (!demo.playback || P_AnalogMove(player))
|
if (!demo.playback)
|
||||||
{
|
{
|
||||||
if (player == &players[consoleplayer])
|
if (player == &players[consoleplayer])
|
||||||
localangle[0] = player->mo->angle;
|
localangle[0] = player->mo->angle;
|
||||||
|
|
@ -5782,6 +5777,8 @@ void P_SpawnSpecials(INT32 fromnetsave)
|
||||||
switch(GETSECSPECIAL(sector->special, 4))
|
switch(GETSECSPECIAL(sector->special, 4))
|
||||||
{
|
{
|
||||||
case 10: // Circuit finish line (Unused)
|
case 10: // Circuit finish line (Unused)
|
||||||
|
// Remove before release
|
||||||
|
CONS_Alert(CONS_WARNING, "Finish line sector type is deprecated.\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -6712,12 +6709,15 @@ void P_SpawnSpecials(INT32 fromnetsave)
|
||||||
sectors[s].midmap = lines[i].frontsector->midmap;
|
sectors[s].midmap = lines[i].frontsector->midmap;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
// SRB2Kart
|
||||||
case 2000: // Waypoint Parameters
|
case 2000: // Waypoint Parameters
|
||||||
break;
|
break;
|
||||||
case 2001: // Finish Line
|
case 2001: // Finish Line
|
||||||
if (G_RaceGametype())
|
if (G_RaceGametype())
|
||||||
circuitmap = true;
|
circuitmap = true;
|
||||||
break;
|
break;
|
||||||
|
case 2002: // Linedef Trigger: Race Lap
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -6938,8 +6938,8 @@ void T_Scroll(scroll_t *s)
|
||||||
|
|
||||||
height = P_GetSpecialBottomZ(thing, sec, psec);
|
height = P_GetSpecialBottomZ(thing, sec, psec);
|
||||||
|
|
||||||
if (!(thing->flags & MF_NOCLIP)) // Thing must be clipped
|
if (!(thing->flags & MF_NOCLIP) && // Thing must be clipped
|
||||||
if (!(thing->flags & MF_NOGRAVITY || thing->z+thing->height != height)) // Thing must a) be non-floating and have z+height == height
|
(!(thing->flags & MF_NOGRAVITY || thing->z+thing->height != height))) // Thing must a) be non-floating and have z+height == height
|
||||||
{
|
{
|
||||||
// Move objects only if on floor
|
// Move objects only if on floor
|
||||||
// non-floating, and clipped.
|
// non-floating, and clipped.
|
||||||
|
|
@ -7014,8 +7014,8 @@ void T_Scroll(scroll_t *s)
|
||||||
|
|
||||||
height = P_GetSpecialTopZ(thing, sec, psec);
|
height = P_GetSpecialTopZ(thing, sec, psec);
|
||||||
|
|
||||||
if (!(thing->flags & MF_NOCLIP)) // Thing must be clipped
|
if (!(thing->flags & MF_NOCLIP) && // Thing must be clipped
|
||||||
if (!(thing->flags & MF_NOGRAVITY || thing->z != height))// Thing must a) be non-floating and have z == height
|
(!(thing->flags & MF_NOGRAVITY || thing->z != height))) // Thing must a) be non-floating and have z == height
|
||||||
{
|
{
|
||||||
// Move objects only if on floor or underwater,
|
// Move objects only if on floor or underwater,
|
||||||
// non-floating, and clipped.
|
// non-floating, and clipped.
|
||||||
|
|
@ -7910,7 +7910,7 @@ void T_Pusher(pusher_t *p)
|
||||||
thing->player->pflags |= PF_SLIDING;
|
thing->player->pflags |= PF_SLIDING;
|
||||||
thing->angle = R_PointToAngle2 (0, 0, xspeed<<(FRACBITS-PUSH_FACTOR), yspeed<<(FRACBITS-PUSH_FACTOR));
|
thing->angle = R_PointToAngle2 (0, 0, xspeed<<(FRACBITS-PUSH_FACTOR), yspeed<<(FRACBITS-PUSH_FACTOR));
|
||||||
|
|
||||||
if (!demo.playback || P_AnalogMove(thing->player))
|
if (!demo.playback)
|
||||||
{
|
{
|
||||||
if (thing->player == &players[consoleplayer])
|
if (thing->player == &players[consoleplayer])
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -173,6 +173,7 @@ void P_InitThinkers(void)
|
||||||
{
|
{
|
||||||
thinkercap.prev = thinkercap.next = &thinkercap;
|
thinkercap.prev = thinkercap.next = &thinkercap;
|
||||||
waypointcap = NULL;
|
waypointcap = NULL;
|
||||||
|
kitemcap = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
@ -629,6 +630,9 @@ void P_Ticker(boolean run)
|
||||||
if (runemeraldmanager)
|
if (runemeraldmanager)
|
||||||
P_EmeraldManager(); // Power stone mode*/
|
P_EmeraldManager(); // Power stone mode*/
|
||||||
|
|
||||||
|
// formality so kitemcap gets updated properly each frame.
|
||||||
|
P_RunKartItems();
|
||||||
|
|
||||||
if (run)
|
if (run)
|
||||||
{
|
{
|
||||||
P_RunThinkers();
|
P_RunThinkers();
|
||||||
|
|
|
||||||
124
src/p_user.c
124
src/p_user.c
|
|
@ -3716,11 +3716,6 @@ void P_Telekinesis(player_t *player, fixed_t thrust, fixed_t range)
|
||||||
player->pflags |= PF_THOKKED;
|
player->pflags |= PF_THOKKED;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean P_AnalogMove(player_t *player)
|
|
||||||
{
|
|
||||||
return player->pflags & PF_ANALOGMODE;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// P_GetPlayerControlDirection
|
// P_GetPlayerControlDirection
|
||||||
//
|
//
|
||||||
|
|
@ -3763,14 +3758,6 @@ boolean P_AnalogMove(player_t *player)
|
||||||
origtempangle = tempangle = 0; // relative to the axis rather than the player!
|
origtempangle = tempangle = 0; // relative to the axis rather than the player!
|
||||||
controlplayerdirection = R_PointToAngle2(0, 0, player->mo->momx, player->mo->momy);
|
controlplayerdirection = R_PointToAngle2(0, 0, player->mo->momx, player->mo->momy);
|
||||||
}
|
}
|
||||||
else if (P_AnalogMove(player) && thiscam->chase)
|
|
||||||
{
|
|
||||||
if (player->awayviewtics)
|
|
||||||
origtempangle = tempangle = player->awayviewmobj->angle;
|
|
||||||
else
|
|
||||||
origtempangle = tempangle = thiscam->angle;
|
|
||||||
controlplayerdirection = player->mo->angle;
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
origtempangle = tempangle = player->mo->angle;
|
origtempangle = tempangle = player->mo->angle;
|
||||||
|
|
@ -3994,7 +3981,6 @@ static void P_3dMovement(player_t *player)
|
||||||
angle_t dangle; // replaces old quadrants bits
|
angle_t dangle; // replaces old quadrants bits
|
||||||
//boolean dangleflip = false; // SRB2kart - toaster
|
//boolean dangleflip = false; // SRB2kart - toaster
|
||||||
//fixed_t normalspd = FixedMul(player->normalspeed, player->mo->scale);
|
//fixed_t normalspd = FixedMul(player->normalspeed, player->mo->scale);
|
||||||
boolean analogmove = false;
|
|
||||||
fixed_t oldMagnitude, newMagnitude;
|
fixed_t oldMagnitude, newMagnitude;
|
||||||
#ifdef ESLOPE
|
#ifdef ESLOPE
|
||||||
vector3_t totalthrust;
|
vector3_t totalthrust;
|
||||||
|
|
@ -4006,8 +3992,6 @@ static void P_3dMovement(player_t *player)
|
||||||
// Get the old momentum; this will be needed at the end of the function! -SH
|
// Get the old momentum; this will be needed at the end of the function! -SH
|
||||||
oldMagnitude = R_PointToDist2(player->mo->momx - player->cmomx, player->mo->momy - player->cmomy, 0, 0);
|
oldMagnitude = R_PointToDist2(player->mo->momx - player->cmomx, player->mo->momy - player->cmomy, 0, 0);
|
||||||
|
|
||||||
analogmove = P_AnalogMove(player);
|
|
||||||
|
|
||||||
cmd = &player->cmd;
|
cmd = &player->cmd;
|
||||||
|
|
||||||
if ((player->exiting || mapreset) || player->pflags & PF_STASIS || player->kartstuff[k_spinouttimer]) // pw_introcam?
|
if ((player->exiting || mapreset) || player->pflags & PF_STASIS || player->kartstuff[k_spinouttimer]) // pw_introcam?
|
||||||
|
|
@ -4020,19 +4004,13 @@ static void P_3dMovement(player_t *player)
|
||||||
if (!(player->pflags & PF_FORCESTRAFE) && !player->kartstuff[k_pogospring])
|
if (!(player->pflags & PF_FORCESTRAFE) && !player->kartstuff[k_pogospring])
|
||||||
cmd->sidemove = 0;
|
cmd->sidemove = 0;
|
||||||
|
|
||||||
if (analogmove)
|
if (player->kartstuff[k_drift] != 0)
|
||||||
{
|
movepushangle = player->mo->angle-(ANGLE_45/5)*player->kartstuff[k_drift];
|
||||||
movepushangle = (cmd->angleturn<<16 /* not FRACBITS */);
|
else if (player->kartstuff[k_spinouttimer] || player->kartstuff[k_wipeoutslow]) // if spun out, use the boost angle
|
||||||
}
|
movepushangle = (angle_t)player->kartstuff[k_boostangle];
|
||||||
else
|
else
|
||||||
{
|
movepushangle = player->mo->angle;
|
||||||
if (player->kartstuff[k_drift] != 0)
|
|
||||||
movepushangle = player->mo->angle-(ANGLE_45/5)*player->kartstuff[k_drift];
|
|
||||||
else if (player->kartstuff[k_spinouttimer] || player->kartstuff[k_wipeoutslow]) // if spun out, use the boost angle
|
|
||||||
movepushangle = (angle_t)player->kartstuff[k_boostangle];
|
|
||||||
else
|
|
||||||
movepushangle = player->mo->angle;
|
|
||||||
}
|
|
||||||
movepushsideangle = movepushangle-ANGLE_90;
|
movepushsideangle = movepushangle-ANGLE_90;
|
||||||
|
|
||||||
// cmomx/cmomy stands for the conveyor belt speed.
|
// cmomx/cmomy stands for the conveyor belt speed.
|
||||||
|
|
@ -6191,69 +6169,6 @@ static void P_MovePlayer(player_t *player)
|
||||||
player->pflags &= ~PF_STARTDASH;
|
player->pflags &= ~PF_STARTDASH;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
//////////////////
|
|
||||||
//ANALOG CONTROL//
|
|
||||||
//////////////////
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
// This really looks like it should be moved to P_3dMovement. -Red
|
|
||||||
if (P_AnalogMove(player)
|
|
||||||
&& (cmd->forwardmove != 0 || cmd->sidemove != 0) && !player->climbing && !twodlevel && !(player->mo->flags2 & MF2_TWOD))
|
|
||||||
{
|
|
||||||
// If travelling slow enough, face the way the controls
|
|
||||||
// point and not your direction of movement.
|
|
||||||
if (player->speed < FixedMul(5*FRACUNIT, player->mo->scale) || player->pflags & PF_GLIDING || !onground)
|
|
||||||
{
|
|
||||||
angle_t tempangle;
|
|
||||||
|
|
||||||
tempangle = (cmd->angleturn << 16);
|
|
||||||
|
|
||||||
#ifdef REDSANALOG // Ease to it. Chillax. ~Red
|
|
||||||
tempangle += R_PointToAngle2(0, 0, cmd->forwardmove*FRACUNIT, -cmd->sidemove*FRACUNIT);
|
|
||||||
{
|
|
||||||
fixed_t tweenvalue = max(abs(cmd->forwardmove), abs(cmd->sidemove));
|
|
||||||
|
|
||||||
if (tweenvalue < 10 && (cmd->buttons & (BT_FORWARD|BT_BACKWARD)) == (BT_FORWARD|BT_BACKWARD)) {
|
|
||||||
tempangle = (cmd->angleturn << 16);
|
|
||||||
tweenvalue = 16;
|
|
||||||
}
|
|
||||||
|
|
||||||
tweenvalue *= tweenvalue*tweenvalue*1536;
|
|
||||||
|
|
||||||
//if (player->pflags & PF_GLIDING)
|
|
||||||
//tweenvalue >>= 1;
|
|
||||||
|
|
||||||
tempangle -= player->mo->angle;
|
|
||||||
|
|
||||||
if (tempangle < ANGLE_180 && tempangle > tweenvalue)
|
|
||||||
player->mo->angle += tweenvalue;
|
|
||||||
else if (tempangle >= ANGLE_180 && InvAngle(tempangle) > tweenvalue)
|
|
||||||
player->mo->angle -= tweenvalue;
|
|
||||||
else
|
|
||||||
player->mo->angle += tempangle;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
// Less math this way ~Red
|
|
||||||
player->mo->angle = R_PointToAngle2(0, 0, cmd->forwardmove*FRACUNIT, -cmd->sidemove*FRACUNIT)+tempangle;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
// Otherwise, face the direction you're travelling.
|
|
||||||
else if (player->panim == PA_WALK || player->panim == PA_RUN || player->panim == PA_ROLL
|
|
||||||
/*|| ((player->mo->state >= &states[S_PLAY_ABL1] && player->mo->state <= &states[S_PLAY_SPC4]) && player->charability == CA_FLY)*/) // SRB2kart - idk
|
|
||||||
player->mo->angle = R_PointToAngle2(0, 0, player->rmomx, player->rmomy);
|
|
||||||
|
|
||||||
// Update the local angle control.
|
|
||||||
if (player == &players[consoleplayer])
|
|
||||||
localangle[0] = player->mo->angle;
|
|
||||||
else if (player == &players[displayplayers[1]])
|
|
||||||
localangle[1] = player->mo->angle;
|
|
||||||
else if (player == &players[displayplayers[2]])
|
|
||||||
localangle[2] = player->mo->angle;
|
|
||||||
else if (player == &players[displayplayers[3]])
|
|
||||||
localangle[3] = player->mo->angle;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
///////////////////////////
|
///////////////////////////
|
||||||
//BOMB SHIELD ACTIVATION,//
|
//BOMB SHIELD ACTIVATION,//
|
||||||
//HOMING, AND OTHER COOL //
|
//HOMING, AND OTHER COOL //
|
||||||
|
|
@ -8132,12 +8047,6 @@ void P_PlayerThink(player_t *player)
|
||||||
// The timer might've reached zero, but we'll run the remote view camera anyway by setting it to -1.
|
// The timer might've reached zero, but we'll run the remote view camera anyway by setting it to -1.
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \note do this in the cheat code
|
|
||||||
if (player->pflags & PF_NOCLIP)
|
|
||||||
player->mo->flags |= MF_NOCLIP;
|
|
||||||
else
|
|
||||||
player->mo->flags &= ~MF_NOCLIP;
|
|
||||||
|
|
||||||
cmd = &player->cmd;
|
cmd = &player->cmd;
|
||||||
|
|
||||||
// SRB2kart
|
// SRB2kart
|
||||||
|
|
@ -8370,26 +8279,7 @@ void P_PlayerThink(player_t *player)
|
||||||
player->mo->reactiontime--;
|
player->mo->reactiontime--;
|
||||||
else if (player->mo->tracer && player->mo->tracer->type == MT_TUBEWAYPOINT)
|
else if (player->mo->tracer && player->mo->tracer->type == MT_TUBEWAYPOINT)
|
||||||
{
|
{
|
||||||
// SRB2kart - don't need no rope hangin'
|
P_DoZoomTube(player);
|
||||||
//if (player->pflags & PF_ROPEHANG)
|
|
||||||
//{
|
|
||||||
// if (!P_AnalogMove(player))
|
|
||||||
// player->mo->angle = (cmd->angleturn<<16 /* not FRACBITS */);
|
|
||||||
|
|
||||||
// ticruned++;
|
|
||||||
// if ((cmd->angleturn & TICCMD_RECEIVED) == 0)
|
|
||||||
// ticmiss++;
|
|
||||||
|
|
||||||
// P_DoRopeHang(player);
|
|
||||||
// P_SetPlayerMobjState(player->mo, S_PLAY_CARRY);
|
|
||||||
// P_DoJumpStuff(player, &player->cmd);
|
|
||||||
//}
|
|
||||||
//else
|
|
||||||
{
|
|
||||||
P_DoZoomTube(player);
|
|
||||||
//if (!(player->panim == PA_ROLL) && player->charability2 == CA2_SPINDASH) // SRB2kart
|
|
||||||
// P_SetPlayerMobjState(player->mo, S_PLAY_ATK1);
|
|
||||||
}
|
|
||||||
player->rmomx = player->rmomy = 0; // no actual momentum from your controls
|
player->rmomx = player->rmomy = 0; // no actual momentum from your controls
|
||||||
P_ResetScore(player);
|
P_ResetScore(player);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue