diff --git a/src/dehacked.c b/src/dehacked.c index a8eccf49d..227c48b69 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -8726,7 +8726,7 @@ static inline int lib_getenum(lua_State *L) lua_pushinteger(L, mapmusic); return 1; } else if (fastcmp(word,"server")) { - if (!playeringame[serverplayer]) + if ((!multiplayer || !netgame) && !playeringame[serverplayer]) return 0; LUA_PushUserdata(L, &players[serverplayer], META_PLAYER); return 1; diff --git a/src/p_enemy.c b/src/p_enemy.c index a1cc9dabc..ef9ff5dda 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -5024,7 +5024,7 @@ void A_MaceRotate(mobj_t *actor) actor->movecount += actor->target->lastlook; actor->movecount &= FINEMASK; - actor->threshold = FixedMul(FINECOSINE(actor->movecount), actor->target->lastlook); + actor->threshold = FixedMul(FINECOSINE(actor->movecount), actor->target->lastlook << FRACBITS); v[0] = FRACUNIT; v[1] = 0; @@ -5032,7 +5032,7 @@ void A_MaceRotate(mobj_t *actor) v[3] = FRACUNIT; // Calculate the angle matrixes for the link. - res = VectorMatrixMultiply(v, *RotateXMatrix(FixedAngle(actor->threshold << FRACBITS))); + res = VectorMatrixMultiply(v, *RotateXMatrix(FixedAngle(actor->threshold))); M_Memcpy(&v, res, sizeof(v)); res = VectorMatrixMultiply(v, *RotateZMatrix(actor->target->health << ANGLETOFINESHIFT)); M_Memcpy(&v, res, sizeof(v)); diff --git a/src/p_local.h b/src/p_local.h index e496990ca..1e0a9e2eb 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -38,6 +38,9 @@ #define MAPBMASK (MAPBLOCKSIZE-1) #define MAPBTOFRAC (MAPBLOCKSHIFT-FRACBITS) +// Convenience macro to fix issue with collision along bottom/left edges of blockmap -Red +#define BMBOUNDFIX(xl, xh, yl, yh) {if (xl > xh) xl = 0; if (yl > yh) yl = 0;} + // player radius used only in am_map.c #define PLAYERRADIUS (16*FRACUNIT) diff --git a/src/p_map.c b/src/p_map.c index 8bdf6987b..46e32e385 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -1309,6 +1309,8 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y) yl = (tmbbox[BOXBOTTOM] - bmaporgy - MAXRADIUS)>>MAPBLOCKSHIFT; yh = (tmbbox[BOXTOP] - bmaporgy + MAXRADIUS)>>MAPBLOCKSHIFT; + BMBOUNDFIX(xl, xh, yl, yh); + #ifdef POLYOBJECTS // Check polyobjects and see if tmfloorz/tmceilingz need to be altered { @@ -1526,6 +1528,8 @@ boolean P_CheckCameraPosition(fixed_t x, fixed_t y, camera_t *thiscam) yl = (tmbbox[BOXBOTTOM] - bmaporgy)>>MAPBLOCKSHIFT; yh = (tmbbox[BOXTOP] - bmaporgy)>>MAPBLOCKSHIFT; + BMBOUNDFIX(xl, xh, yl, yh); + #ifdef POLYOBJECTS // Check polyobjects and see if tmfloorz/tmceilingz need to be altered { @@ -1953,6 +1957,8 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff) xh = (thing->x + MAXRADIUS - bmaporgx)>>MAPBLOCKSHIFT; xl = (thing->x - MAXRADIUS - bmaporgx)>>MAPBLOCKSHIFT; + BMBOUNDFIX(xl, xh, yl, yh); + stand = thing; standx = x; standy = y; @@ -3039,6 +3045,8 @@ void P_RadiusAttack(mobj_t *spot, mobj_t *source, fixed_t damagedist) xh = (spot->x + dist - bmaporgx)>>MAPBLOCKSHIFT; xl = (spot->x - dist - bmaporgx)>>MAPBLOCKSHIFT; + BMBOUNDFIX(xl, xh, yl, yh); + bombspot = spot; bombsource = source; bombdamage = FixedMul(damagedist, spot->scale); @@ -3653,6 +3661,8 @@ void P_CreateSecNodeList(mobj_t *thing, fixed_t x, fixed_t y) yl = (tmbbox[BOXBOTTOM] - bmaporgy)>>MAPBLOCKSHIFT; yh = (tmbbox[BOXTOP] - bmaporgy)>>MAPBLOCKSHIFT; + BMBOUNDFIX(xl, xh, yl, yh); + for (bx = xl; bx <= xh; bx++) for (by = yl; by <= yh; by++) P_BlockLinesIterator(bx, by, PIT_GetSectors); @@ -3730,6 +3740,8 @@ void P_CreatePrecipSecNodeList(precipmobj_t *thing,fixed_t x,fixed_t y) yl = (preciptmbbox[BOXBOTTOM] - bmaporgy)>>MAPBLOCKSHIFT; yh = (preciptmbbox[BOXTOP] - bmaporgy)>>MAPBLOCKSHIFT; + BMBOUNDFIX(xl, xh, yl, yh); + for (bx = xl; bx <= xh; bx++) for (by = yl; by <= yh; by++) P_BlockLinesIterator(bx, by, PIT_GetPrecipSectors); diff --git a/src/p_polyobj.c b/src/p_polyobj.c index 102c03b7a..05cc03d34 100644 --- a/src/p_polyobj.c +++ b/src/p_polyobj.c @@ -1040,9 +1040,10 @@ static void Polyobj_carryThings(polyobj_t *po, fixed_t dx, fixed_t dy) mo->lastlook = pomovecount; - // always push players even if not solid - if (!((mo->flags & MF_SOLID) || mo->player)) + // Don't scroll objects that aren't affected by gravity + if (mo->flags & MF_NOGRAVITY) continue; + // (The above check used to only move MF_SOLID objects, but that's inconsistent with conveyor behavior. -Red) if (mo->flags & MF_NOCLIP) continue; @@ -1094,9 +1095,11 @@ static INT32 Polyobj_clipThings(polyobj_t *po, line_t *line) for (; mo; mo = mo->bnext) { - // always push players even if not solid - if (!((mo->flags & MF_SOLID) || mo->player)) + + // Don't scroll objects that aren't affected by gravity + if (mo->flags & MF_NOGRAVITY) continue; + // (The above check used to only move MF_SOLID objects, but that's inconsistent with conveyor behavior. -Red) if (mo->flags & MF_NOCLIP) continue; @@ -1256,6 +1259,7 @@ static void Polyobj_rotateThings(polyobj_t *po, vertex_t origin, angle_t delta, { static INT32 pomovecount = 10000; INT32 x, y; + angle_t deltafine = delta >> ANGLETOFINESHIFT; pomovecount++; @@ -1280,9 +1284,10 @@ static void Polyobj_rotateThings(polyobj_t *po, vertex_t origin, angle_t delta, mo->lastlook = pomovecount; - // always push players even if not solid - if (!((mo->flags & MF_SOLID) || mo->player)) + // Don't scroll objects that aren't affected by gravity + if (mo->flags & MF_NOGRAVITY) continue; + // (The above check used to only move MF_SOLID objects, but that's inconsistent with conveyor behavior. -Red) if (mo->flags & MF_NOCLIP) continue; @@ -1297,21 +1302,28 @@ static void Polyobj_rotateThings(polyobj_t *po, vertex_t origin, angle_t delta, continue; { - fixed_t newxoff, newyoff; - angle_t angletoobj = R_PointToAngle2(origin.x, origin.y, mo->x, mo->y); - fixed_t disttoobj = R_PointToDist2(origin.x, origin.y, mo->x, mo->y); + fixed_t oldxoff, oldyoff, newxoff, newyoff; + fixed_t c, s; + + c = FINECOSINE(deltafine); + s = FINESINE(deltafine); + + oldxoff = mo->x-origin.x; + oldyoff = mo->y-origin.y; if (mo->player) // Hack to fix players sliding off of spinning polys -Red { - disttoobj = FixedMul(disttoobj, 0xfe40); + fixed_t temp; + + temp = FixedMul(oldxoff, c)-FixedMul(oldyoff, s); + oldyoff = FixedMul(oldyoff, c)+FixedMul(oldxoff, s); + oldxoff = temp; } - angletoobj += delta; - angletoobj >>= ANGLETOFINESHIFT; - newxoff = FixedMul(FINECOSINE(angletoobj), disttoobj); - newyoff = FixedMul(FINESINE(angletoobj), disttoobj); + newxoff = FixedMul(oldxoff, c)-FixedMul(oldyoff, s); + newyoff = FixedMul(oldyoff, c)+FixedMul(oldxoff, s); - Polyobj_slideThing(mo, origin.x+newxoff-mo->x, origin.y+newyoff-mo->y); + Polyobj_slideThing(mo, newxoff-oldxoff, newyoff-oldyoff); if (turnthings == 2 || (turnthings == 1 && !mo->player)) { mo->angle += delta; @@ -2488,6 +2500,10 @@ INT32 EV_DoPolyObjWaypoint(polywaypointdata_t *pwdata) return 0; } + // Hotfix to not crash on single-waypoint sequences -Red + if (!last) + last = first; + // Set diffx, diffy, diffz // Put these at 0 for now...might not be needed after all. th->diffx = 0;//first->x - po->centerPt.x; diff --git a/src/p_polyobj.h b/src/p_polyobj.h index b42f8b98b..cfcb3b99c 100644 --- a/src/p_polyobj.h +++ b/src/p_polyobj.h @@ -100,6 +100,8 @@ typedef struct polyobj_s UINT8 isBad; // a bad polyobject: should not be rendered/manipulated INT32 translucency; // index to translucency tables + struct visplane_s *visplane; // polyobject's visplane, for ease of putting into the list later + // these are saved for netgames, so do not let Lua touch these! INT32 spawnflags; // Flags the polyobject originally spawned with INT32 spawntrans; // Translucency the polyobject originally spawned with diff --git a/src/p_user.c b/src/p_user.c index d60de97a8..32dc8733f 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -2958,6 +2958,8 @@ static void P_DoTeeter(player_t *player) xh = (player->mo->x + player->mo->radius - bmaporgx)>>MAPBLOCKSHIFT; xl = (player->mo->x - player->mo->radius - bmaporgx)>>MAPBLOCKSHIFT; + BMBOUNDFIX(xl, xh, yl, yh); + // Polyobjects #ifdef POLYOBJECTS validcount++; @@ -8089,6 +8091,8 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall yl = (tmbbox[BOXBOTTOM] - bmaporgy)>>MAPBLOCKSHIFT; yh = (tmbbox[BOXTOP] - bmaporgy)>>MAPBLOCKSHIFT; + BMBOUNDFIX(xl, xh, yl, yh); + for (by = yl; by <= yh; by++) for (bx = xl; bx <= xh; bx++) { diff --git a/src/r_bsp.c b/src/r_bsp.c index e967e28ce..fb25b8e4d 100644 --- a/src/r_bsp.c +++ b/src/r_bsp.c @@ -978,11 +978,12 @@ static void R_Subsector(size_t num) polysec->floorpic_angle-po->angle, NULL, NULL); - ffloor[numffloors].plane->polyobj = po; + //ffloor[numffloors].plane->polyobj = po; ffloor[numffloors].height = polysec->floorheight; ffloor[numffloors].polyobj = po; // ffloor[numffloors].ffloor = rover; + po->visplane = ffloor[numffloors].plane; numffloors++; } @@ -1014,11 +1015,12 @@ static void R_Subsector(size_t num) ffloor[numffloors].plane = R_FindPlane(polysec->ceilingheight, polysec->ceilingpic, polysec->lightlevel, xoff, yoff, polysec->ceilingpic_angle-po->angle, NULL, NULL); - ffloor[numffloors].plane->polyobj = po; + //ffloor[numffloors].plane->polyobj = po; ffloor[numffloors].polyobj = po; ffloor[numffloors].height = polysec->ceilingheight; // ffloor[numffloors].ffloor = rover; + po->visplane = ffloor[numffloors].plane; numffloors++; } diff --git a/src/r_things.c b/src/r_things.c index f5231854d..0c93932cb 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -1691,6 +1691,19 @@ static void R_CreateDrawNodes(void) } if (ds->maskedtexturecol) { +#ifdef POLYOBJECTS_PLANES + // Check for a polyobject plane, but only if this is a front line + if (ds->curline->polyseg && ds->curline->polyseg->visplane && !ds->curline->side) { + // Put it in! + + entry = R_CreateDrawNode(&nodehead); + entry->plane = ds->curline->polyseg->visplane; + entry->seg = ds; + ds->curline->polyseg->visplane->polyobj = ds->curline->polyseg; + ds->curline->polyseg->visplane = NULL; + } +#endif + entry = R_CreateDrawNode(&nodehead); entry->seg = ds; } @@ -1707,7 +1720,7 @@ static void R_CreateDrawNodes(void) plane = ds->ffloorplanes[p]; R_PlaneBounds(plane); - if (plane->low < con_clipviewtop || plane->high > vid.height || plane->high > plane->low) + if (plane->low < con_clipviewtop || plane->high > vid.height || plane->high > plane->low || plane->polyobj) { ds->ffloorplanes[p] = NULL; continue; @@ -1818,7 +1831,7 @@ static void R_CreateDrawNodes(void) } else if (r2->seg) { -#ifdef POLYOBJECTS_PLANES +#if 0 //#ifdef POLYOBJECTS_PLANES if (r2->seg->curline->polyseg && rover->mobj && P_MobjInsidePolyobj(r2->seg->curline->polyseg, rover->mobj)) { // Determine if we need to sort in front of the polyobj, based on the planes. This fixes the issue where // polyobject planes render above the object standing on them. (A bit hacky... but it works.) -Red