Compare commits
22
Commits
threadstuff
...
neo-kart
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1bd901cee0 | ||
|
|
bf35469684 | ||
|
|
83b62e7f53 | ||
|
|
e5b5b53ede | ||
|
|
75b4b10caa | ||
|
|
1732e927c1 | ||
|
|
fc5cab4b62 | ||
|
|
c7fcf814ef | ||
|
|
914fed4a1a | ||
|
|
6b1e9751a6 | ||
|
|
afa41fa88e | ||
|
|
53010deb8b | ||
|
|
785c33f5a8 | ||
|
|
dbdbe95164 | ||
|
|
5b7720fe65 | ||
|
|
332369a910 | ||
|
|
b92d3dd7ae | ||
|
|
91c943263e | ||
|
|
3a0419703d | ||
|
|
47011c8e07 | ||
|
|
a0035f6258 | ||
|
|
528ae085e6 |
No files matched your search
+3
-2
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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},
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
@@ -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
|
||||
//
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in new issue
Block a user