Compare commits

...
22 Commits
Author SHA1 Message Date
Alug 1bd901cee0 Merge remote-tracking branch 'origin/lugstuff' into neo-kart 2024-03-04 04:13:18 +01:00
Alug bf35469684 Revert "Fix players constantly JUSTHITFLOOR at the top of slopes"
This reverts commit 5b7720fe65.
2024-03-04 04:08:29 +01:00
Alug 83b62e7f53 remove more unused stuff 2024-03-02 18:57:44 +01:00
Alug e5b5b53ede bruh 2024-03-02 18:57:40 +01:00
Alug 75b4b10caa only players get cylinders 2024-03-02 04:24:23 +01:00
Alug 1732e927c1 Merge remote-tracking branch 'origin/lugstuff' into neo-kart 2024-03-02 04:12:36 +01:00
Alug fc5cab4b62 was worth a shot 2024-03-02 02:33:22 +01:00
Alug c7fcf814ef Merge remote-tracking branch 'origin/lugstuff' into neo-kart 2024-03-02 02:32:41 +01:00
Alug 914fed4a1a grow chads 2024-03-01 22:46:34 +01:00
Alug 6b1e9751a6 expose some stuff to lua
P_IsLocalPlayer
P_ResetCamera
M_MapNumber
P_ButteredSlope
R_PointInSubsector
2024-03-01 21:25:33 +01:00
Alug afa41fa88e Do not attempt to disconnect when a packet checksum is invalid 2024-03-01 21:14:23 +01:00
Alug 53010deb8b reset pmomz after applying to momz 2024-03-01 20:47:16 +01:00
Alug 785c33f5a8 netsync pmomz 2024-03-01 20:45:54 +01:00
Alug dbdbe95164 netsync crumblestate 2024-03-01 20:44:47 +01:00
Alug 5b7720fe65 Fix players constantly JUSTHITFLOOR at the top of slopes 2024-03-01 20:29:18 +01:00
Alug 332369a910 Move player friction reset after movement code 2024-03-01 20:23:10 +01:00
Alug b92d3dd7ae Update mobj floorz/ceilingz after a bustable FOF is destroyed 2024-03-01 20:21:12 +01:00
Alug 91c943263e P_CeilingzAtPos 2024-03-01 20:21:02 +01:00
Alug 3a0419703d use boxonlineside for non player mobjs 2024-03-01 20:11:51 +01:00
Alug 47011c8e07 cylindrical mobj hitboxes 2024-03-01 20:03:17 +01:00
Alug a0035f6258 port R_IsPointInSector
for optimized mobj z positions
2024-03-01 20:03:14 +01:00
Alug 528ae085e6 increment_move radius clamps from Ring Racers 2024-03-01 20:03:11 +01:00
17 changed files with 599 additions and 277 deletions

No files matched your search

+3 -2
View File
@@ -1171,8 +1171,9 @@ boolean HGetPacket(void)
if (netbuffer->checksum != NetbufferChecksum())
{
DEBFILE("Bad packet checksum\n");
//Net_CloseConnection(nodejustjoined ? (doomcom->remotenode | FORCECLOSE) : doomcom->remotenode);
Net_CloseConnection(doomcom->remotenode);
// Do not disconnect or anything, just ignore the packet.
// Bad checksums with UDP tend to happen very scarcely
// so they are not normally an issue.
continue;
}
+86
View File
@@ -24,6 +24,7 @@
#include "console.h"
#include "k_kart.h" // SRB2Kart
#include "d_netcmd.h" // IsPlayerAdmin
#include "m_misc.h" // M_MapNumber
#include "lua_script.h"
#include "lua_libs.h"
@@ -153,6 +154,23 @@ static int lib_isPlayerAdmin(lua_State *L)
return 1;
}
// M_MISC
//////////////
static int lib_mMapNumber(lua_State *L)
{
const char *arg = luaL_checkstring(L, 1);
size_t len = strlen(arg);
if (len == 2 || len == 5) {
char first = arg[len-2];
char second = arg[len-1];
lua_pushinteger(L, M_MapNumber(first, second));
} else {
lua_pushinteger(L, 0);
}
return 1;
}
// M_RANDOM
//////////////
@@ -780,6 +798,17 @@ static int lib_pSetObjectMomZ(lua_State *L)
return 0;
}
static int lib_pIsLocalPlayer(lua_State *L)
{
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
//NOHUD
//INLEVEL
if (!player)
return LUA_ErrInvalid(L, "player_t");
lua_pushboolean(L, P_IsLocalPlayer(player));
return 1;
}
static int lib_pRestoreMusic(lua_State *L)
{
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
@@ -957,6 +986,19 @@ static int lib_pHomingAttack(lua_State *L)
return 0;
}
static int lib_pResetCamera(lua_State *L)
{
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
camera_t *cam = *((camera_t **)luaL_checkudata(L, 2, META_CAMERA));
if (!player)
return LUA_ErrInvalid(L, "player_t");
if (!cam)
return LUA_ErrInvalid(L, "camera_t");
P_ResetCamera(player, cam);
return 0;
}
/*static int lib_pSuperReady(lua_State *L)
{
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
@@ -1145,6 +1187,17 @@ static int lib_pFloorzAtPos(lua_State *L)
return 1;
}
static int lib_pCeilingzAtPos(lua_State *L)
{
fixed_t x = luaL_checkfixed(L, 1);
fixed_t y = luaL_checkfixed(L, 2);
fixed_t z = luaL_checkfixed(L, 3);
fixed_t height = luaL_checkfixed(L, 4);
//HUDSAFE
lua_pushfixed(L, P_CeilingzAtPos(x, y, z, height));
return 1;
}
static int lib_pDoSpring(lua_State *L)
{
mobj_t *spring = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
@@ -1634,6 +1687,17 @@ static int lib_pGetZAt(lua_State *L)
return 1;
}
static int lib_pButteredSlope(lua_State *L)
{
mobj_t *mobj = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
NOHUD
//INLEVEL
if (!mobj)
return LUA_ErrInvalid(L, "mobj_t");
P_ButteredSlope(mobj);
return 0;
}
// R_DEFS
////////////
@@ -1686,6 +1750,20 @@ static int lib_rPointInSubsector(lua_State *L)
return 1;
}
static int lib_rIsPointInSubsector(lua_State *L)
{
fixed_t x = luaL_checkfixed(L, 1);
fixed_t y = luaL_checkfixed(L, 2);
subsector_t *sub = R_IsPointInSubsector(x, y);
//HUDSAFE
//INLEVEL
if (sub)
LUA_PushUserdata(L, sub, META_SUBSECTOR);
else
lua_pushnil(L);
return 1;
}
// R_THINGS
////////////
@@ -3007,6 +3085,9 @@ static luaL_Reg lib[] = {
{"EvalMath", lib_evalMath},
{"IsPlayerAdmin", lib_isPlayerAdmin},
// m_misc
{"M_MapNumber",lib_mMapNumber},
// m_random
{"P_RandomFixed",lib_pRandomFixed},
{"P_RandomByte",lib_pRandomByte},
@@ -3067,6 +3148,7 @@ static luaL_Reg lib[] = {
{"P_InSpaceSector",lib_pInSpaceSector},
{"P_InQuicksand",lib_pInQuicksand},
{"P_SetObjectMomZ",lib_pSetObjectMomZ},
{"P_IsLocalPlayer",lib_pIsLocalPlayer},
{"P_RestoreMusic",lib_pRestoreMusic},
{"P_SpawnShieldOrb",lib_pSpawnShieldOrb},
{"P_SpawnGhostMobj",lib_pSpawnGhostMobj},
@@ -3083,6 +3165,7 @@ static luaL_Reg lib[] = {
{"P_LookForEnemies",lib_pLookForEnemies},
{"P_NukeEnemies",lib_pNukeEnemies},
{"P_HomingAttack",lib_pHomingAttack},
{"P_ResetCamera",lib_pResetCamera},
//{"P_SuperReady",lib_pSuperReady},
{"P_Telekinesis",lib_pTelekinesis},
@@ -3099,6 +3182,7 @@ static luaL_Reg lib[] = {
{"P_CheckHoopPosition",lib_pCheckHoopPosition},
{"P_RadiusAttack",lib_pRadiusAttack},
{"P_FloorzAtPos",lib_pFloorzAtPos},
{"P_CeilingzAtPos",lib_pCeilingzAtPos},
{"P_DoSpring",lib_pDoSpring},
// p_inter
@@ -3137,6 +3221,7 @@ static luaL_Reg lib[] = {
// p_slopes
{"P_GetZAt",lib_pGetZAt},
{"P_ButteredSlope",lib_pButteredSlope},
// r_defs
{"R_PointToAngle",lib_rPointToAngle},
@@ -3144,6 +3229,7 @@ static luaL_Reg lib[] = {
{"R_PointToDist",lib_rPointToDist},
{"R_PointToDist2",lib_rPointToDist2},
{"R_PointInSubsector",lib_rPointInSubsector},
{"R_IsPointInSubsector",lib_rIsPointInSubsector},
// r_things (sprite)
{"R_Char2Frame",lib_rChar2Frame},
+5
View File
@@ -140,6 +140,7 @@ enum cameraf {
camera_x,
camera_y,
camera_z,
camera_reset,
camera_angle,
camera_subsector,
camera_floorz,
@@ -159,6 +160,7 @@ static const char *const camera_opt[] = {
"x",
"y",
"z",
"reset",
"angle",
"subsector",
"floorz",
@@ -349,6 +351,9 @@ static int camera_get(lua_State *L)
case camera_z:
lua_pushinteger(L, cam->z);
break;
case camera_reset:
lua_pushboolean(L, cam->reset);
break;
case camera_angle:
lua_pushinteger(L, cam->angle);
break;
+1 -3
View File
@@ -179,9 +179,7 @@ fixed_t FV2_Distance(const vector2_t *p1, const vector2_t *p2)
fixed_t FV2_Magnitude(const vector2_t *a_normal)
{
fixed_t xs = FixedMul(a_normal->x, a_normal->x);
fixed_t ys = FixedMul(a_normal->y, a_normal->y);
return FixedSqrt(xs + ys);
return FixedHypot(a_normal->x, a_normal->y); // Much less prone to overflowing
}
// Also returns the magnitude
+15
View File
@@ -2006,6 +2006,20 @@ void T_ThwompSector(levelspecthink_t *thwomp)
#undef ceilingwasheight
}
static void T_UpdateMobjPlaneZ(sector_t *sec)
{
msecnode_t *node = sec->touching_thinglist; // things touching this sector
mobj_t *mo;
while (node)
{
mo = node->m_thing;
mo->floorz = P_FloorzAtPos(mo->x, mo->y, mo->z, mo->height);
mo->ceilingz = P_CeilingzAtPos(mo->x, mo->y, mo->z, mo->height);
node = node->m_thinglist_next;
}
}
//
// T_NoEnemiesThinker
//
@@ -3072,6 +3086,7 @@ void EV_CrumbleChain(sector_t *sec, ffloor_t *rover)
// no longer exists (can't collide with again)
rover->flags &= ~FF_EXISTS;
rover->master->frontsector->moved = true;
T_UpdateMobjPlaneZ(sec); // prevent objects from floating
sec->moved = true;
}
+1
View File
@@ -371,6 +371,7 @@ void P_Initsecnode(void);
void P_RadiusAttack(mobj_t *spot, mobj_t *source, fixed_t damagedist);
fixed_t P_FloorzAtPos(fixed_t x, fixed_t y, fixed_t z, fixed_t height);
fixed_t P_CeilingzAtPos(fixed_t x, fixed_t y, fixed_t z, fixed_t height);
boolean PIT_PushableMoved(mobj_t *thing);
boolean P_DoSpring(mobj_t *spring, mobj_t *object);
+212 -72
View File
@@ -595,6 +595,9 @@ static boolean PIT_CheckThing(mobj_t *thing)
== P_PointOnLineSide(thing->x - thing->radius, thing->y + thing->radius, &junk)))
return true; // the line doesn't cross between either pair of opposite corners
}
else
if (abs(R_PointToDist2(thing->x, thing->y, tmx, tmy)) >= blockdist)
return true; // didn't hit it, but came very close
{
UINT8 shouldCollide = LUAh_MobjCollide(thing, tmthing); // checks hook for thing's type
@@ -1918,10 +1921,18 @@ static boolean PIT_CheckLine(line_t *ld)
|| tmbbox[BOXTOP] <= ld->bbox[BOXBOTTOM] || tmbbox[BOXBOTTOM] >= ld->bbox[BOXTOP])
return true;
if (P_BoxOnLineSide(tmbbox, ld) != -1)
return true;
if (tmthing->player)
{
if (P_CircleOnLineSide(tmx, tmy, tmthing->radius, ld) != -1)
return true;
}
else
{
if (P_BoxOnLineSide(tmbbox, ld) != -1)
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;
cosradius = FixedMul(tmthing->radius, FINECOSINE(tmthing->angle>>ANGLETOFINESHIFT));
@@ -2679,8 +2690,22 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
fixed_t startingonground = P_IsObjectOnGround(thing);
floatok = false;
if (radius < MAXRADIUS/2)
radius = MAXRADIUS/2;
// This makes sure that there are no freezes from computing extremely small movements.
// Originally was MAXRADIUS/2, but that can cause some bad inconsistencies for small players.
radius = max(radius, thing->scale);
// And we also have to prevent Big Large (tm) movements, as those can skip too far
// across slopes and cause us to fail step up checks on them when we otherwise shouldn't.
radius = min(radius, 16 * thing->scale);
// (This whole "step" system is flawed; it was OK before, but the addition of slopes has
// exposed the problems with doing it like this. The right thing to do would be to use
// raycasting for physics to fix colliding in weird order, double-checking collisions,
// randomly colliding with slopes instead of going up them, etc. I don't feel like porting
// that from RR, as its both a huge sweeping change and still incomplete at the time of
// writing. Clamping radius to make our steps more precise will work just fine as long
// as you keep all of your crazy intentions to poke any of the other deep-rooted movement
// code to yourself. -- Sal 6/5/2023)
do {
if (thing->flags & MF_NOCLIP) {
@@ -3215,6 +3240,85 @@ isblocking:
//
// PTR_SlideTraverse
//
static boolean PTR_SlideTraversePlayer(line_t *li)
{
fixed_t mmomx, mmomy, x, y, dist;
vertex_t closestpoint;
// Kludgy redo of previous work, should optimize later
if (slidemo->player)
{
mmomx = slidemo->player->rmomx = slidemo->momx - slidemo->player->cmomx;
mmomy = slidemo->player->rmomy = slidemo->momy - slidemo->player->cmomy;
}
else
{
mmomx = slidemo->momx;
mmomy = slidemo->momy;
}
x = slidemo->x + mmomx;
y = slidemo->y + mmomy;
// if (P_CircleOnLineSide(x, y, slidemo->radius, li) != -1)
// return true; // Not inside the line, non-blocking
// one-sided linedefs are always solid to sliding movement.
// one-sided linedef
if (!li->backsector)
{
if (P_PointOnLineSide(slidemo->x, slidemo->y, li))
return true; // don't hit the back side
goto isblocking;
}
if (!(slidemo->flags & MF_MISSILE))
{
if (li->flags & ML_IMPASSIBLE)
goto isblocking;
if ((slidemo->flags & (MF_ENEMY|MF_BOSS)) && li->flags & ML_BLOCKMONSTERS)
goto isblocking;
}
// set openrange, opentop, openbottom
P_LineOpening(li, slidemo);
if (openrange < slidemo->height)
goto isblocking; // doesn't fit
if (opentop - slidemo->z < slidemo->height)
goto isblocking; // mobj is too high
if (openbottom - slidemo->z > FixedMul(MAXSTEPMOVE, mapobjectscale))
goto isblocking; // too big a step up
// this line doesn't block movement
return true;
// the line does block movement,
// see if it is closer than best so far
isblocking:
if (li->polyobj && slidemo->player)
{
if ((li->polyobj->lines[0]->backsector->flags & SF_TRIGGERSPECIAL_TOUCH) && !(li->polyobj->flags & POF_NOSPECIALS))
P_ProcessSpecialSector(slidemo->player, slidemo->subsector->sector, li->polyobj->lines[0]->backsector);
}
P_ClosestPointOnLineWithinLine(x, y, li, &closestpoint);
dist = abs(R_PointToDist2(closestpoint.x, closestpoint.y, x, y));
if (dist < bestslidefrac)
{
secondslidefrac = bestslidefrac;
secondslideline = bestslideline;
bestslidefrac = dist;
bestslideline = li;
}
return true;
}
static boolean PTR_SlideTraverse(intercept_t *in)
{
line_t *li;
@@ -3386,7 +3490,10 @@ stairstep:
//
void P_SlideMove(mobj_t *mo, boolean forceslide)
{
fixed_t leadx, leady, trailx, traily, newx, newy;
fixed_t leadx, leady, trailx, traily;
fixed_t newx, newy;
fixed_t mmomx, mmomy;
fixed_t maxslidefrac;
INT16 hitcount = 0;
boolean success = false;
@@ -3429,38 +3536,55 @@ retry:
if (++hitcount == 3)
goto stairstep; // don't loop forever
// trace along the three leading corners
if (mo->momx > 0)
if (mo->player)
{
leadx = mo->x + mo->radius;
trailx = mo->x - mo->radius;
mmomx = mo->player->rmomx = mo->momx - mo->player->cmomx;
mmomy = mo->player->rmomy = mo->momy - mo->player->cmomy;
}
else
{
leadx = mo->x - mo->radius;
trailx = mo->x + mo->radius;
if (mo->momx > 0)
{
leadx = mo->x + mo->radius;
trailx = mo->x - mo->radius;
}
else
{
leadx = mo->x - mo->radius;
trailx = mo->x + mo->radius;
}
if (mo->momy > 0)
{
leady = mo->y + mo->radius;
traily = mo->y - mo->radius;
}
else
{
leady = mo->y - mo->radius;
traily = mo->y + mo->radius;
}
}
if (mo->momy > 0)
if (mo->player)
{
leady = mo->y + mo->radius;
traily = mo->y - mo->radius;
maxslidefrac = mo->radius + FixedHypot(mmomx, mmomy);
bestslidefrac = maxslidefrac;
P_RadiusLinesCheck(mo->radius, mo->x + mmomx, mo->y + mmomy, PTR_SlideTraversePlayer);
}
else
{
leady = mo->y - mo->radius;
traily = mo->y + mo->radius;
bestslidefrac = FRACUNIT+1;
P_PathTraverse(leadx, leady, leadx + mo->momx, leady + mo->momy,
PT_ADDLINES, PTR_SlideTraverse);
P_PathTraverse(trailx, leady, trailx + mo->momx, leady + mo->momy,
PT_ADDLINES, PTR_SlideTraverse);
P_PathTraverse(leadx, traily, leadx + mo->momx, traily + mo->momy,
PT_ADDLINES, PTR_SlideTraverse);
}
bestslidefrac = FRACUNIT+1;
P_PathTraverse(leadx, leady, leadx + mo->momx, leady + mo->momy,
PT_ADDLINES, PTR_SlideTraverse);
P_PathTraverse(trailx, leady, trailx + mo->momx, leady + mo->momy,
PT_ADDLINES, PTR_SlideTraverse);
P_PathTraverse(leadx, traily, leadx + mo->momx, traily + mo->momy,
PT_ADDLINES, PTR_SlideTraverse);
// Some walls are bouncy even if you're not
if (!forceslide && bestslideline && !(bestslideline->flags & ML_BOUNCY)) // SRB2kart - All walls are bouncy unless specified otherwise
{
@@ -3469,7 +3593,7 @@ retry:
}
// move up to the wall
if (bestslidefrac == FRACUNIT+1)
if ((mo->player && bestslidefrac == maxslidefrac) || (!mo->player && bestslidefrac == FRACUNIT+1))
{
// the move must have hit the middle, so stairstep
stairstep:
@@ -3554,10 +3678,9 @@ stairstep:
void P_BouncePlayerMove(mobj_t *mo)
{
fixed_t leadx, leady;
fixed_t trailx, traily;
fixed_t mmomx = 0, mmomy = 0;
fixed_t oldmomx = mo->momx, oldmomy = mo->momy;
fixed_t maxslidefrac;
if (!mo->player)
return;
@@ -3577,38 +3700,14 @@ void P_BouncePlayerMove(mobj_t *mo)
mo->player->kartstuff[k_driftcharge] = 0;
mo->player->kartstuff[k_pogospring] = 0;
// trace along the three leading corners
if (mo->momx > 0)
{
leadx = mo->x + mo->radius;
trailx = mo->x - mo->radius;
}
else
{
leadx = mo->x - mo->radius;
trailx = mo->x + mo->radius;
}
maxslidefrac = mo->radius + FixedHypot(mmomx, mmomy);
bestslidefrac = maxslidefrac;
if (mo->momy > 0)
{
leady = mo->y + mo->radius;
traily = mo->y - mo->radius;
}
else
{
leady = mo->y - mo->radius;
traily = mo->y + mo->radius;
}
bestslidefrac = FRACUNIT + 1;
P_PathTraverse(leadx, leady, leadx + mmomx, leady + mmomy, PT_ADDLINES, PTR_SlideTraverse);
P_PathTraverse(trailx, leady, trailx + mmomx, leady + mmomy, PT_ADDLINES, PTR_SlideTraverse);
P_PathTraverse(leadx, traily, leadx + mmomx, traily + mmomy, PT_ADDLINES, PTR_SlideTraverse);
P_RadiusLinesCheck(mo->radius, mo->x + mmomx, mo->y + mmomy, PTR_SlideTraversePlayer);
// Now continue along the wall.
// First calculate remainder.
bestslidefrac = FRACUNIT - bestslidefrac;
bestslidefrac = maxslidefrac - bestslidefrac;
if (bestslidefrac > FRACUNIT)
bestslidefrac = FRACUNIT;
@@ -3710,13 +3809,13 @@ retry:
}
bestslidefrac = FRACUNIT + 1;
P_PathTraverse(leadx, leady, leadx + mmomx, leady + mmomy, PT_ADDLINES, PTR_SlideTraverse);
P_PathTraverse(trailx, leady, trailx + mmomx, leady + mmomy, PT_ADDLINES, PTR_SlideTraverse);
P_PathTraverse(leadx, traily, leadx + mmomx, traily + mmomy, PT_ADDLINES, PTR_SlideTraverse);
// move up to the wall
if (bestslidefrac == FRACUNIT + 1)
if (bestslidefrac == FRACUNIT+1)
{
// the move must have hit the middle, so bounce straight back
bounceback:
@@ -4390,7 +4489,7 @@ static inline boolean PIT_GetSectors(line_t *ld)
tmbbox[BOXBOTTOM] >= ld->bbox[BOXTOP])
return true;
if (P_BoxOnLineSide(tmbbox, ld) != -1)
if (P_CircleOnLineSide(tmx, tmy, tmthing->radius, ld) != -1)
return true;
if (ld->polyobj) // line belongs to a polyobject, don't add it
@@ -4453,7 +4552,6 @@ static inline boolean PIT_GetPrecipSectors(line_t *ld)
// P_CreateSecNodeList alters/creates the sector_list that shows what sectors
// the object resides in.
void P_CreateSecNodeList(mobj_t *thing, fixed_t x, fixed_t y)
{
INT32 xl, xh, yl, yh, bx, by;
@@ -4543,6 +4641,7 @@ void P_CreatePrecipSecNodeList(precipmobj_t *thing,fixed_t x,fixed_t y)
INT32 xl, xh, yl, yh, bx, by;
mprecipsecnode_t *node = precipsector_list;
precipmobj_t *saved_tmthing = tmprecipthing; /* cph - see comment at func end */
fixed_t saved_tmx = tmx, saved_tmy = tmy; /* ditto */
// First, clear out the existing m_thing fields. As each node is
// added or verified as needed, m_thing will be set properly. When
@@ -4556,6 +4655,9 @@ void P_CreatePrecipSecNodeList(precipmobj_t *thing,fixed_t x,fixed_t y)
}
tmprecipthing = thing;
tmx = x;
tmy = y;
preciptmbbox[BOXTOP] = y + 2*FRACUNIT;
preciptmbbox[BOXBOTTOM] = y - 2*FRACUNIT;
@@ -4602,6 +4704,7 @@ void P_CreatePrecipSecNodeList(precipmobj_t *thing,fixed_t x,fixed_t y)
* Fun. We restore its previous value unless we're in a Boom/MBF demo.
*/
tmprecipthing = saved_tmthing;
tmx = saved_tmx, tmy = saved_tmy;
}
/* cphipps 2004/08/30 -
@@ -4623,10 +4726,7 @@ void P_MapEnd(void)
fixed_t P_FloorzAtPos(fixed_t x, fixed_t y, fixed_t z, fixed_t height)
{
sector_t *sec = R_PointInSubsector(x, y)->sector;
fixed_t floorz = sec->floorheight;
if (sec->f_slope)
floorz = P_GetZAt(sec->f_slope, x, y);
fixed_t floorz = P_GetSectorFloorZAt(sec, x, y);
// Intercept the stupid 'fall through 3dfloors' bug Tails 03-17-2002
if (sec->ffloors)
@@ -4643,13 +4743,8 @@ fixed_t P_FloorzAtPos(fixed_t x, fixed_t y, fixed_t z, fixed_t height)
if ((!(rover->flags & FF_SOLID || rover->flags & FF_QUICKSAND) || (rover->flags & FF_SWIMMABLE)))
continue;
topheight = *rover->topheight;
bottomheight = *rover->bottomheight;
if (*rover->t_slope)
topheight = P_GetZAt(*rover->t_slope, x, y);
if (*rover->b_slope)
bottomheight = P_GetZAt(*rover->b_slope, x, y);
topheight = P_GetFFloorTopZAt (rover, x, y);
bottomheight = P_GetFFloorBottomZAt(rover, x, y);
if (rover->flags & FF_QUICKSAND)
{
@@ -4670,3 +4765,48 @@ fixed_t P_FloorzAtPos(fixed_t x, fixed_t y, fixed_t z, fixed_t height)
return floorz;
}
// P_CeilingZAtPos
// Returns the ceilingz of the XYZ position
fixed_t P_CeilingzAtPos(fixed_t x, fixed_t y, fixed_t z, fixed_t height)
{
sector_t *sec = R_PointInSubsector(x, y)->sector;
fixed_t ceilingz = P_GetSectorCeilingZAt(sec, x, y);
if (sec->ffloors)
{
ffloor_t *rover;
fixed_t delta1, delta2, thingtop = z + height;
for (rover = sec->ffloors; rover; rover = rover->next)
{
fixed_t topheight, bottomheight;
if (!(rover->flags & FF_EXISTS))
continue;
if ((!(rover->flags & FF_SOLID || rover->flags & FF_QUICKSAND) || (rover->flags & FF_SWIMMABLE)))
continue;
topheight = P_GetFFloorTopZAt (rover, x, y);
bottomheight = P_GetFFloorBottomZAt(rover, x, y);
if (rover->flags & FF_QUICKSAND)
{
if (thingtop > bottomheight && topheight > z)
{
if (ceilingz > thingtop)
ceilingz = thingtop;
}
continue;
}
delta1 = z - (bottomheight + ((topheight - bottomheight)/2));
delta2 = thingtop - (bottomheight + ((topheight - bottomheight)/2));
if (bottomheight < ceilingz && abs(delta1) > abs(delta2))
ceilingz = bottomheight;
}
}
return ceilingz;
}
+50 -7
View File
@@ -26,6 +26,7 @@
//
// P_ClosestPointOnLine
// Finds the closest point on a given line to the supplied point
// Considers line length to be infinite, and can return results outside of the actual line
//
void P_ClosestPointOnLine(fixed_t x, fixed_t y, line_t *line, vertex_t *result)
{
@@ -65,6 +66,29 @@ void P_ClosestPointOnLine(fixed_t x, fixed_t y, line_t *line, vertex_t *result)
return;
}
//
// P_ClosestPointOnLineWithinLine
// Finds the closest point on a given line to the supplied point
// Like P_ClosestPointOnLine, except the result is constrained within the actual line
//
void P_ClosestPointOnLineWithinLine(fixed_t x, fixed_t y, line_t *line, vertex_t *result)
{
fixed_t maxx, maxy, minx, miny;
P_ClosestPointOnLine(x, y, line, result);
// Determine max and min bounds of the line
maxx = max(line->v1->x, line->v2->x);
maxy = max(line->v1->y, line->v2->y);
minx = min(line->v1->x, line->v2->x);
miny = min(line->v1->y, line->v2->y);
// Constrain result to line by ensuring x and y don't go beyond the maximums
result->x = min(max(result->x, minx),maxx);
result->y = min(max(result->y, miny),maxy);
return;
}
//
// P_ClosestPointOnLine3D
// Finds the closest point on a given line to the supplied point IN 3D!!!
@@ -167,7 +191,7 @@ INT32 P_PointOnLineSide(fixed_t x, fixed_t y, line_t *line)
//
// P_BoxOnLineSide
// Considers the line to be infinite
// Clips line, not infinite, prevents false positive collisions
// Returns side 0 or 1, -1 if box crosses the line.
//
INT32 P_BoxOnLineSide(fixed_t *tmbox, line_t *ld)
@@ -216,6 +240,23 @@ INT32 P_BoxOnLineSide(fixed_t *tmbox, line_t *ld)
return -1;
}
//
// P_CircleOnLineSide
// Considers the line to be infinite
// Returns side 0 or 1, -1 if circle crosses the line.
// Man, circles are easier than boxes
//
INT32 P_CircleOnLineSide(fixed_t x, fixed_t y, fixed_t radius, line_t *ld)
{
vertex_t closestpoint;
P_ClosestPointOnLineWithinLine(x, y, ld, &closestpoint);
if (abs(R_PointToDist2(closestpoint.x, closestpoint.y, x, y)) < radius)
return -1; // Inside circle
else
return P_PointOnLineSide(x, y, ld); // Not inside so just return this instead
}
//
// P_PointOnDivlineSide
// Returns 0 or 1.
@@ -1324,7 +1365,7 @@ boolean P_PathTraverse(fixed_t px1, fixed_t py1, fixed_t px2, fixed_t py2,
}
}
// Go through the sorted list
return P_TraverseIntercepts(trav, FRACUNIT);
return P_TraverseIntercepts(trav, 256*FRACUNIT);
}
@@ -1337,13 +1378,12 @@ boolean P_PathTraverse(fixed_t px1, fixed_t py1, fixed_t px2, fixed_t py2,
// returns FALSE if the loop exited early after a false return
// value from your user function
//abandoned, maybe I'll need it someday..
/*
boolean P_RadiusLinesCheck(fixed_t radius, fixed_t x, fixed_t y,
boolean (*func)(line_t *))
{
INT32 xl, xh, yl, yh;
INT32 bx, by;
boolean blockval = true;
tmbbox[BOXTOP] = y + radius;
tmbbox[BOXBOTTOM] = y - radius;
@@ -1355,11 +1395,14 @@ boolean P_RadiusLinesCheck(fixed_t radius, fixed_t x, fixed_t y,
xh = (unsigned)(tmbbox[BOXRIGHT] - bmaporgx)>>MAPBLOCKSHIFT;
yl = (unsigned)(tmbbox[BOXBOTTOM] - bmaporgy)>>MAPBLOCKSHIFT;
yh = (unsigned)(tmbbox[BOXTOP] - bmaporgy)>>MAPBLOCKSHIFT;
BMBOUNDFIX(xl, xh, yl, yh);
validcount++;
for (bx = xl; bx <= xh; bx++)
for (by = yl; by <= yh; by++)
if (!P_BlockLinesIterator(bx, by, func))
return false;
return true;
blockval = false;
return blockval;
}
*/
+3 -2
View File
@@ -43,12 +43,14 @@ boolean P_PathTraverse(fixed_t px1, fixed_t py1, fixed_t px2, fixed_t py2,
#define P_AproxDistance(dx, dy) FixedHypot(dx, dy)
void P_ClosestPointOnLine(fixed_t x, fixed_t y, line_t *line, vertex_t *result);
void P_ClosestPointOnLineWithinLine(fixed_t x, fixed_t y, line_t *line, vertex_t *result);
void P_ClosestPointOnLine3D(fixed_t x, fixed_t y, fixed_t z, line_t *line, vertex_t *result);
INT32 P_PointOnLineSide(fixed_t x, fixed_t y, line_t *line);
void P_MakeDivline(line_t *li, divline_t *dl);
void P_CameraLineOpening(line_t *plinedef);
fixed_t P_InterceptVector(divline_t *v2, divline_t *v1);
INT32 P_BoxOnLineSide(fixed_t *tmbox, line_t *ld);
INT32 P_CircleOnLineSide(fixed_t x, fixed_t y, fixed_t radius, line_t *ld);
void P_UnsetPrecipThingPosition(precipmobj_t *thing);
void P_SetPrecipitationThingPosition(precipmobj_t *thing);
void P_CreatePrecipSecNodeList(precipmobj_t *thing, fixed_t x,fixed_t y);
@@ -72,6 +74,5 @@ extern fixed_t tmbbox[4]; // p_map.c
// call your user function for each line of the blockmap in the
// bbox defined by the radius
//boolean P_RadiusLinesCheck(fixed_t radius, fixed_t x, fixed_t y,
// boolean (*func)(line_t *));
boolean P_RadiusLinesCheck(fixed_t radius, fixed_t x, fixed_t y, boolean (*func)(line_t *));
#endif // __P_MAPUTL__
+98 -167
View File
@@ -477,140 +477,63 @@ boolean P_InsideANonSolidFFloor(mobj_t *mobj, ffloor_t *rover)
return true;
}
static fixed_t HighestOnLine(fixed_t radius, fixed_t x, fixed_t y, line_t *line, pslope_t *slope, boolean actuallylowest)
{
// Alright, so we're sitting on a line that contains our slope sector, and need to figure out the highest point we're touching...
// https://stackoverflow.com/questions/25203613/find-intersection-of-circle-and-line because I can't be arsed to re-learn linear algebra
vertex_t closestvertex;
vector2_t n, closestpoint, offset, i1, i2;
fixed_t dist, distsquared, radiussquared;
n.x = line->dx;
n.y = line->dy;
FV2_Normalize(&n); // fixed it
P_ClosestPointOnLine(x, y, line, &closestvertex);
closestpoint.x = closestvertex.x;
closestpoint.y = closestvertex.y;
dist = R_PointToDist2(closestpoint.x, closestpoint.y, x, y);
distsquared = FixedMul(dist, dist);
radiussquared = FixedMul(radius, radius);
FV2_MulEx(&n, FixedSqrt(radiussquared - distsquared), &offset);
FV2_AddEx(&closestpoint, &offset, &i1);
FV2_SubEx(&closestpoint, &offset, &i2);
// Return the higher of the two points
if (actuallylowest)
return min(
P_GetZAt(slope, i1.x, i1.y),
P_GetZAt(slope, i2.x, i2.y)
);
else
return max(
P_GetZAt(slope, i1.x, i1.y),
P_GetZAt(slope, i2.x, i2.y)
);
}
// P_GetFloorZ (and its ceiling counterpart)
// Gets the floor height (or ceiling height) of the mobj's contact point in sector, assuming object's center if moved to [x, y]
// If line is supplied, it's a divider line on the sector. Set it to NULL if you're not checking for collision with a line
// Supply boundsec ONLY when checking for specials! It should be the "in-level" sector, and sector the control sector (if separate).
// If set, then this function will iterate through boundsec's linedefs to find the highest contact point on the slope. Non-special-checking
// usage will handle that later.
static fixed_t HighestOnLine(fixed_t radius, fixed_t x, fixed_t y, line_t *line, pslope_t *slope, boolean actuallylowest)
{
// Alright, so we're sitting on a line that contains our slope sector, and need to figure out the highest point we're touching...
// The solution is simple! Get the line's vertices, and pull each one in along its line until it touches the object's bounding box
// (assuming it isn't already inside), then test each point's slope Z and return the higher of the two.
vertex_t v1, v2;
v1.x = line->v1->x;
v1.y = line->v1->y;
v2.x = line->v2->x;
v2.y = line->v2->y;
/*CONS_Printf("BEFORE: v1 = %f %f %f\n",
FIXED_TO_FLOAT(v1.x),
FIXED_TO_FLOAT(v1.y),
FIXED_TO_FLOAT(P_GetZAt(slope, v1.x, v1.y))
);
CONS_Printf(" v2 = %f %f %f\n",
FIXED_TO_FLOAT(v2.x),
FIXED_TO_FLOAT(v2.y),
FIXED_TO_FLOAT(P_GetZAt(slope, v2.x, v2.y))
);*/
if (abs(v1.x-x) > radius) {
// v1's x is out of range, so rein it in
fixed_t diff = abs(v1.x-x) - radius;
if (v1.x < x) { // Moving right
v1.x += diff;
v1.y += FixedMul(diff, FixedDiv(line->dy, line->dx));
} else { // Moving left
v1.x -= diff;
v1.y -= FixedMul(diff, FixedDiv(line->dy, line->dx));
}
}
if (abs(v1.y-y) > radius) {
// v1's y is out of range, so rein it in
fixed_t diff = abs(v1.y-y) - radius;
if (v1.y < y) { // Moving up
v1.y += diff;
v1.x += FixedMul(diff, FixedDiv(line->dx, line->dy));
} else { // Moving down
v1.y -= diff;
v1.x -= FixedMul(diff, FixedDiv(line->dx, line->dy));
}
}
if (abs(v2.x-x) > radius) {
// v1's x is out of range, so rein it in
fixed_t diff = abs(v2.x-x) - radius;
if (v2.x < x) { // Moving right
v2.x += diff;
v2.y += FixedMul(diff, FixedDiv(line->dy, line->dx));
} else { // Moving left
v2.x -= diff;
v2.y -= FixedMul(diff, FixedDiv(line->dy, line->dx));
}
}
if (abs(v2.y-y) > radius) {
// v2's y is out of range, so rein it in
fixed_t diff = abs(v2.y-y) - radius;
if (v2.y < y) { // Moving up
v2.y += diff;
v2.x += FixedMul(diff, FixedDiv(line->dx, line->dy));
} else { // Moving down
v2.y -= diff;
v2.x -= FixedMul(diff, FixedDiv(line->dx, line->dy));
}
}
/*CONS_Printf("AFTER: v1 = %f %f %f\n",
FIXED_TO_FLOAT(v1.x),
FIXED_TO_FLOAT(v1.y),
FIXED_TO_FLOAT(P_GetZAt(slope, v1.x, v1.y))
);
CONS_Printf(" v2 = %f %f %f\n",
FIXED_TO_FLOAT(v2.x),
FIXED_TO_FLOAT(v2.y),
FIXED_TO_FLOAT(P_GetZAt(slope, v2.x, v2.y))
);*/
// Return the higher of the two points
if (actuallylowest)
return min(
P_GetZAt(slope, v1.x, v1.y),
P_GetZAt(slope, v2.x, v2.y)
);
else
return max(
P_GetZAt(slope, v1.x, v1.y),
P_GetZAt(slope, v2.x, v2.y)
);
}
fixed_t P_MobjFloorZ(mobj_t *mobj, sector_t *sector, sector_t *boundsec, fixed_t x, fixed_t y, line_t *line, boolean lowest, boolean perfect)
{
I_Assert(mobj != NULL);
I_Assert(sector != NULL);
if (sector->f_slope) {
fixed_t testx, testy;
fixed_t testx = x;
fixed_t testy = y;
angle_t angletomobjedge;
pslope_t *slope = sector->f_slope;
// Get the corner of the object that should be the highest on the slope
if (slope->d.x < 0)
testx = mobj->radius;
else
testx = -mobj->radius;
if (slope->d.y < 0)
testy = mobj->radius;
else
testy = -mobj->radius;
if ((slope->zdelta > 0) ^ !!(lowest)) {
testx = -testx;
testy = -testy;
}
testx += x;
testy += y;
angletomobjedge = (slope->zdelta >= 0 && !lowest) || (slope->zdelta < 0 && lowest) ? slope->xydirection : slope->xydirection+ANGLE_180;
testx -= P_ReturnThrustX(NULL, angletomobjedge, mobj->radius);
testy -= P_ReturnThrustY(NULL, angletomobjedge, mobj->radius);
// If the highest point is in the sector, then we have it easy! Just get the Z at that point
if (R_PointInSubsector(testx, testy)->sector == (boundsec ? boundsec : sector))
return P_GetZAt(slope, testx, testy);
if (R_IsPointInSector(boundsec ? boundsec : sector, testx, testy))
return P_GetZAt(slope, testx, testy);
// If boundsec is set, we're looking for specials. In that case, iterate over every line in this sector to find the TRUE highest/lowest point
if (perfect) {
@@ -623,6 +546,8 @@ fixed_t P_MobjFloorZ(mobj_t *mobj, sector_t *sector, sector_t *boundsec, fixed_t
finalheight = INT32_MAX;
else
finalheight = INT32_MIN;
//bbox calc is still probably faster/less calculations than P_CircleOnLineSide, so we leave it for performance
bbox[BOXLEFT] = x-mobj->radius;
bbox[BOXRIGHT] = x+mobj->radius;
@@ -634,9 +559,17 @@ fixed_t P_MobjFloorZ(mobj_t *mobj, sector_t *sector, sector_t *boundsec, fixed_t
if (bbox[BOXRIGHT] <= ld->bbox[BOXLEFT] || bbox[BOXLEFT] >= ld->bbox[BOXRIGHT]
|| bbox[BOXTOP] <= ld->bbox[BOXBOTTOM] || bbox[BOXBOTTOM] >= ld->bbox[BOXTOP])
continue;
if (P_BoxOnLineSide(bbox, ld) != -1)
continue;
if (mobj->player)
{
if (P_CircleOnLineSide(x, y, mobj->radius, ld) != -1)
continue;
}
else
{
if (P_BoxOnLineSide(bbox, ld) != -1)
continue;
}
if (lowest)
finalheight = min(finalheight, HighestOnLine(mobj->radius, x, y, ld, slope, true));
@@ -662,30 +595,17 @@ fixed_t P_MobjCeilingZ(mobj_t *mobj, sector_t *sector, sector_t *boundsec, fixed
I_Assert(mobj != NULL);
I_Assert(sector != NULL);
if (sector->c_slope) {
fixed_t testx, testy;
fixed_t testx = x;
fixed_t testy = y;
angle_t angletomobjedge;
pslope_t *slope = sector->c_slope;
// Get the corner of the object that should be the highest on the slope
if (slope->d.x < 0)
testx = mobj->radius;
else
testx = -mobj->radius;
if (slope->d.y < 0)
testy = mobj->radius;
else
testy = -mobj->radius;
if ((slope->zdelta > 0) ^ !!(lowest)) {
testx = -testx;
testy = -testy;
}
testx += x;
testy += y;
angletomobjedge = (slope->zdelta >= 0 && !lowest) || (slope->zdelta < 0 && lowest) ? slope->xydirection : slope->xydirection+ANGLE_180;
testx -= P_ReturnThrustX(mobj, angletomobjedge, mobj->radius);
testy -= P_ReturnThrustY(mobj, angletomobjedge, mobj->radius);
// If the highest point is in the sector, then we have it easy! Just get the Z at that point
if (R_PointInSubsector(testx, testy)->sector == (boundsec ? boundsec : sector))
if (R_IsPointInSector(boundsec ? boundsec : sector, testx, testy))
return P_GetZAt(slope, testx, testy);
// If boundsec is set, we're looking for specials. In that case, iterate over every line in this sector to find the TRUE highest/lowest point
@@ -711,8 +631,16 @@ fixed_t P_MobjCeilingZ(mobj_t *mobj, sector_t *sector, sector_t *boundsec, fixed
|| bbox[BOXTOP] <= ld->bbox[BOXBOTTOM] || bbox[BOXBOTTOM] >= ld->bbox[BOXTOP])
continue;
if (P_BoxOnLineSide(bbox, ld) != -1)
continue;
if (mobj->player)
{
if (P_CircleOnLineSide(x, y, mobj->radius, ld) != -1)
continue;
}
else
{
if (P_BoxOnLineSide(bbox, ld) != -1)
continue;
}
if (lowest)
finalheight = min(finalheight, HighestOnLine(mobj->radius, x, y, ld, slope, true));
@@ -762,7 +690,7 @@ fixed_t P_CameraFloorZ(camera_t *mobj, sector_t *sector, sector_t *boundsec, fix
testy += y;
// If the highest point is in the sector, then we have it easy! Just get the Z at that point
if (R_PointInSubsector(testx, testy)->sector == (boundsec ? boundsec : sector))
if (R_IsPointInSector(boundsec ? boundsec : sector, testx, testy))
return P_GetZAt(slope, testx, testy);
// If boundsec is set, we're looking for specials. In that case, iterate over every line in this sector to find the TRUE highest/lowest point
@@ -838,7 +766,7 @@ fixed_t P_CameraCeilingZ(camera_t *mobj, sector_t *sector, sector_t *boundsec, f
testy += y;
// If the highest point is in the sector, then we have it easy! Just get the Z at that point
if (R_PointInSubsector(testx, testy)->sector == (boundsec ? boundsec : sector))
if (R_IsPointInSector(boundsec ? boundsec : sector, testx, testy))
return P_GetZAt(slope, testx, testy);
// If boundsec is set, we're looking for specials. In that case, iterate over every line in this sector to find the TRUE highest/lowest point
@@ -1192,8 +1120,6 @@ static void P_XYFriction(mobj_t *mo, fixed_t oldx, fixed_t oldy)
mo->momx = FixedMul(mo->momx, mo->friction);
mo->momy = FixedMul(mo->momy, mo->friction);
}
mo->friction = ORIG_FRICTION;
}
}
else
@@ -1342,6 +1268,26 @@ void P_XYMovement(mobj_t *mo)
return;
}
}
//{ SRB2kart - Ballhogs
if (mo->type == MT_BALLHOG)
{
if (mo->health)
{
mo->health--;
if (mo->health == 0)
mo->destscale = 1;
}
else
{
if (mo->scale < mapobjectscale/16)
{
P_RemoveMobj(mo);
return;
}
}
}
//}
player = mo->player; //valid only if player avatar
@@ -1377,25 +1323,6 @@ void P_XYMovement(mobj_t *mo)
if (CheckForBustableBlocks && mo->flags & MF_PUSHABLE)
P_PushableCheckBustables(mo);
//{ SRB2kart - Ballhogs
if (mo->type == MT_BALLHOG)
{
if (mo->health)
{
mo->health--;
if (mo->health == 0)
mo->destscale = 1;
}
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))
{
// blocked move
@@ -1853,6 +1780,7 @@ static void P_RingZMovement(mobj_t *mo)
if (mo->eflags & MFE_APPLYPMOMZ && !P_IsObjectOnGround(mo))
{
mo->momz += mo->pmomz;
mo->pmomz = 0;
mo->eflags &= ~MFE_APPLYPMOMZ;
}
mo->z += mo->momz;
@@ -1928,6 +1856,7 @@ static boolean P_ZMovement(mobj_t *mo)
if (mo->eflags & MFE_APPLYPMOMZ && !P_IsObjectOnGround(mo))
{
mo->momz += mo->pmomz;
mo->pmomz = 0;
mo->eflags &= ~MFE_APPLYPMOMZ;
}
mo->z += mo->momz;
@@ -2400,6 +2329,7 @@ static void P_PlayerZMovement(mobj_t *mo)
if (mo->eflags & MFE_APPLYPMOMZ && !P_IsObjectOnGround(mo))
{
mo->momz += mo->pmomz;
mo->pmomz = 0;
mo->eflags &= ~MFE_APPLYPMOMZ;
}
@@ -2685,6 +2615,7 @@ static boolean P_SceneryZMovement(mobj_t *mo)
if (mo->eflags & MFE_APPLYPMOMZ && !P_IsObjectOnGround(mo))
{
mo->momz += mo->pmomz;
mo->pmomz = 0;
mo->eflags &= ~MFE_APPLYPMOMZ;
}
mo->z += mo->momz;
+22 -6
View File
@@ -179,7 +179,7 @@ boolean P_MobjTouchingPolyobj(polyobj_t *po, mobj_t *mo)
{
fixed_t mbbox[4];
size_t i;
mbbox[BOXTOP] = mo->y + mo->radius;
mbbox[BOXBOTTOM] = mo->y - mo->radius;
mbbox[BOXRIGHT] = mo->x + mo->radius;
@@ -187,8 +187,16 @@ boolean P_MobjTouchingPolyobj(polyobj_t *po, mobj_t *mo)
for (i = 0; i < po->numLines; i++)
{
if (P_BoxOnLineSide(mbbox, po->lines[i]) == -1)
return true;
if (mo->player)
{
if (P_CircleOnLineSide(mo->x, mo->y, mo->radius, po->lines[i]) == -1)
return true;
}
else
{
if (P_BoxOnLineSide(mbbox, po->lines[i]) == -1)
return true;
}
}
return false;
@@ -203,7 +211,7 @@ boolean P_MobjInsidePolyobj(polyobj_t *po, mobj_t *mo)
{
fixed_t mbbox[4];
size_t i;
mbbox[BOXTOP] = mo->y + mo->radius;
mbbox[BOXBOTTOM] = mo->y - mo->radius;
mbbox[BOXRIGHT] = mo->x + mo->radius;
@@ -211,8 +219,16 @@ boolean P_MobjInsidePolyobj(polyobj_t *po, mobj_t *mo)
for (i = 0; i < po->numLines; i++)
{
if (P_BoxOnLineSide(mbbox, po->lines[i]) == 0)
return false;
if (mo->player)
{
if (P_CircleOnLineSide(mo->x, mo->y, mo->radius, po->lines[i]) == 0)
return false;
}
else
{
if (P_BoxOnLineSide(mbbox, po->lines[i]) == 0)
return false;
}
}
return true;
+42 -15
View File
@@ -468,10 +468,14 @@ static void P_NetUnArchivePlayers(void)
#define SD_FYOFFS 0x02
#define SD_CXOFFS 0x04
#define SD_CYOFFS 0x08
#define SD_TAG 0x10
#define SD_FLOORANG 0x20
#define SD_CEILANG 0x40
#define SD_TAGLIST 0x80
#define SD_FLOORANG 0x10
#define SD_CEILANG 0x20
#define SD_TAG 0x40
#define SD_DIFF3 0x80
// diff3 flags
#define SD_TAGLIST 0x01
#define SD_CRUMBLESTATE 0x04
#define LD_FLAG 0x01
#define LD_SPECIAL 0x02
@@ -503,7 +507,7 @@ static void P_NetArchiveWorld(void)
mapsidedef_t *msd;
maplinedef_t *mld;
const sector_t *ss = sectors;
UINT8 diff, diff2;
UINT8 diff, diff2, diff3;
WRITEUINT32(save_p, ARCHIVEBLOCK_WORLD);
put = save_p;
@@ -530,7 +534,7 @@ static void P_NetArchiveWorld(void)
for (i = 0; i < numsectors; i++, ss++, ms++)
{
diff = diff2 = 0;
diff = diff2 = diff3 = 0;
if (ss->floorheight != SHORT(ms->floorheight)<<FRACBITS)
diff |= SD_FLOORHT;
if (ss->ceilingheight != SHORT(ms->ceilingheight)<<FRACBITS)
@@ -564,7 +568,9 @@ static void P_NetArchiveWorld(void)
if (ss->tag != SHORT(ms->tag))
diff2 |= SD_TAG;
if (ss->nexttag != ss->spawn_nexttag || ss->firsttag != ss->spawn_firsttag)
diff2 |= SD_TAGLIST;
diff3 |= SD_TAGLIST;
if (ss->crumblestate)
diff3 |= SD_CRUMBLESTATE;
// Check if any of the sector's FOFs differ from how they spawned
if (ss->ffloors)
@@ -580,6 +586,9 @@ static void P_NetArchiveWorld(void)
}
}
}
if (diff3)
diff2 |= SD_DIFF3;
if (diff2)
diff |= SD_DIFF2;
@@ -590,6 +599,8 @@ static void P_NetArchiveWorld(void)
WRITEUINT8(put, diff);
if (diff & SD_DIFF2)
WRITEUINT8(put, diff2);
if (diff2 & SD_DIFF3)
WRITEUINT8(put, diff3);
if (diff & SD_FLOORHT)
WRITEFIXED(put, ss->floorheight);
if (diff & SD_CEILHT)
@@ -610,17 +621,20 @@ static void P_NetArchiveWorld(void)
WRITEFIXED(put, ss->ceiling_xoffs);
if (diff2 & SD_CYOFFS)
WRITEFIXED(put, ss->ceiling_yoffs);
if (diff2 & SD_TAG) // save only the tag
WRITEINT16(put, ss->tag);
if (diff2 & SD_FLOORANG)
WRITEANGLE(put, ss->floorpic_angle);
if (diff2 & SD_CEILANG)
WRITEANGLE(put, ss->ceilingpic_angle);
if (diff2 & SD_TAGLIST) // save both firsttag and nexttag
if (diff2 & SD_TAG) // save only the tag
WRITEINT16(put, ss->tag);
if (diff3 & SD_TAGLIST) // save both firsttag and nexttag
{ // either of these could be changed even if tag isn't
WRITEINT32(put, ss->firsttag);
WRITEINT32(put, ss->nexttag);
}
if (diff3 & SD_CRUMBLESTATE)
WRITEINT32(put, ss->crumblestate);
// Special case: save the stats of all modified ffloors along with their ffloor "number"s
// we don't bother with ffloors that haven't changed, that would just add to savegame even more than is really needed
@@ -658,7 +672,7 @@ static void P_NetArchiveWorld(void)
// do lines
for (i = 0; i < numlines; i++, mld++, li++)
{
diff = diff2 = 0;
diff = diff2 = diff3 = 0;
if (li->special != SHORT(mld->special))
diff |= LD_SPECIAL;
@@ -749,7 +763,7 @@ static void P_NetUnArchiveWorld(void)
line_t *li;
side_t *si;
UINT8 *get;
UINT8 diff, diff2;
UINT8 diff, diff2, diff3;
if (READUINT32(save_p) != ARCHIVEBLOCK_WORLD)
I_Error("Bad $$$.sav at archive block World");
@@ -772,6 +786,11 @@ static void P_NetUnArchiveWorld(void)
else
diff2 = 0;
if (diff2 & SD_DIFF3)
diff3 = READUINT8(get);
else
diff3 = 0;
if (diff & SD_FLOORHT)
sectors[i].floorheight = READFIXED(get);
if (diff & SD_CEILHT)
@@ -799,9 +818,9 @@ static void P_NetUnArchiveWorld(void)
sectors[i].ceiling_xoffs = READFIXED(get);
if (diff2 & SD_CYOFFS)
sectors[i].ceiling_yoffs = READFIXED(get);
if (diff2 & SD_TAG)
if (diff3 & SD_TAG)
sectors[i].tag = READINT16(get); // DON'T use P_ChangeSectorTag
if (diff2 & SD_TAGLIST)
if (diff3 & SD_TAGLIST)
{
sectors[i].firsttag = READINT32(get);
sectors[i].nexttag = READINT32(get);
@@ -810,6 +829,9 @@ static void P_NetUnArchiveWorld(void)
sectors[i].floorpic_angle = READANGLE(get);
if (diff2 & SD_CEILANG)
sectors[i].ceilingpic_angle = READANGLE(get);
if (diff3 & SD_CRUMBLESTATE)
sectors[i].crumblestate = READINT32(get);
if (diff & SD_FFLOORS)
{
@@ -868,6 +890,9 @@ static void P_NetUnArchiveWorld(void)
diff2 = READUINT8(get);
else
diff2 = 0;
diff3 = 0;
if (diff & LD_FLAG)
li->flags = READINT16(get);
if (diff & LD_SPECIAL)
@@ -1062,7 +1087,7 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type)
diff2 = 0;
// not the default but the most probable
if (mobj->momx != 0 || mobj->momy != 0 || mobj->momz != 0)
if (mobj->momx != 0 || mobj->momy != 0 || mobj->momz != 0 || mobj->pmomz !=0)
diff |= MD_MOM;
if (mobj->radius != mobj->info->radius)
diff |= MD_RADIUS;
@@ -1190,6 +1215,7 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type)
WRITEFIXED(save_p, mobj->momx);
WRITEFIXED(save_p, mobj->momy);
WRITEFIXED(save_p, mobj->momz);
WRITEFIXED(save_p, mobj->pmomz);
}
if (diff & MD_RADIUS)
WRITEFIXED(save_p, mobj->radius);
@@ -2016,6 +2042,7 @@ static void LoadMobjThinker(actionf_p1 thinker)
mobj->momx = READFIXED(save_p);
mobj->momy = READFIXED(save_p);
mobj->momz = READFIXED(save_p);
mobj->pmomz = READFIXED(save_p);
} // otherwise they're zero, and the memset took care of it
if (diff & MD_RADIUS)
+11 -3
View File
@@ -837,10 +837,18 @@ void P_SlopeLaunch(mobj_t *mo)
#ifdef GROWNEVERMISSES
{
const fixed_t xyscale = mapobjectscale + (mapobjectscale - mo->scale);
//const fixed_t xyscale = mapobjectscale + (mapobjectscale - mo->scale);
const fixed_t zscale = mapobjectscale + (mapobjectscale - mo->scale);
mo->momx = FixedMul(slopemom.x, xyscale);
mo->momy = FixedMul(slopemom.y, xyscale);
// instead of scaling x and y momentum...
//mo->momx = FixedMul(slopemom.x, xyscale);
//mo->momy = FixedMul(slopemom.y, xyscale);
// we leave it unscaled
mo->momx = slopemom.x;
mo->momy = slopemom.y;
// final notes: horizontal speed still feels good while having the player feel "heavier"
// would need practical testing in custom maps to see if it's actually consistent however
mo->momz = FixedMul(slopemom.z, zscale);
}
#else
+3
View File
@@ -7740,6 +7740,9 @@ void T_Pusher(pusher_t *p)
xh = (unsigned)(tmbbox[BOXRIGHT] - bmaporgx + MAXRADIUS)>>MAPBLOCKSHIFT;
yl = (unsigned)(tmbbox[BOXBOTTOM] - bmaporgy - MAXRADIUS)>>MAPBLOCKSHIFT;
yh = (unsigned)(tmbbox[BOXTOP] - bmaporgy + MAXRADIUS)>>MAPBLOCKSHIFT;
BMBOUNDFIX(xl, xh, yl, yh);
for (bx = xl; bx <= xh; bx++)
for (by = yl; by <= yh; by++)
P_BlockThingsIterator(bx,by, PIT_PushThing);
+1
View File
@@ -2118,6 +2118,7 @@ static void P_3dMovement(player_t *player)
player->mo->momy = tempmomy + player->cmomy;
}
}
player->mo->friction = ORIG_FRICTION; //katsy: reset player friction AFTER movement code
}
//
+45
View File
@@ -1060,6 +1060,51 @@ void R_Init(void)
framecount = 0;
}
//
// R_IsPointInSector
//
boolean R_IsPointInSector(sector_t *sector, fixed_t x, fixed_t y)
{
size_t i;
size_t passes = 0;
for (i = 0; i < sector->linecount; i++)
{
line_t *line = sector->lines[i];
vertex_t *v1, *v2;
if (line->frontsector == line->backsector)
continue;
v1 = line->v1;
v2 = line->v2;
// make sure v1 is below v2
if (v1->y > v2->y)
{
vertex_t *tmp = v1;
v1 = v2;
v2 = tmp;
}
else if (v1->y == v2->y)
// horizontal line, we can't match this
continue;
if (v1->y < y && y <= v2->y)
{
// if the y axis in inside the line, find the point where we intersect on the x axis...
fixed_t vx = v1->x + (INT64)(v2->x - v1->x) * (y - v1->y) / (v2->y - v1->y);
// ...and if that point is to the left of the point, count it as inside.
if (vx < x)
passes++;
}
}
// and odd number of passes means we're inside the polygon.
return passes % 2;
}
//
// R_PointInSubsector
//
+1
View File
@@ -77,6 +77,7 @@ angle_t R_PlayerSliptideAngle(player_t *player);
fixed_t R_ScaleFromGlobalAngle(angle_t visangle);
subsector_t *R_PointInSubsector(fixed_t x, fixed_t y);
boolean R_IsPointInSector(sector_t *sector, fixed_t x, fixed_t y);
subsector_t *R_IsPointInSubsector(fixed_t x, fixed_t y);
boolean R_DoCulling(line_t *cullheight, line_t *viewcullheight, fixed_t vz, fixed_t bottomh, fixed_t toph);