- changed Polyobject thinkers to operate on the actual polyobjects instead of indices

This also changes the action special interface to pass a Level parameter to the separate functions and makes a few other minor adjustments to the polyobject code.
This commit is contained in:
Christoph Oelckers 2019-01-24 01:05:07 +01:00
parent 65750bd7bf
commit 9f8dd66189
15 changed files with 331 additions and 348 deletions

View file

@ -525,7 +525,7 @@ CUSTOM_CVAR (Int, compatflags, 0, CVAR_ARCHIVE|CVAR_SERVERINFO)
i_compatflags = GetCompatibility(self) | ii_compatflags;
if ((old ^ i_compatflags) & COMPATF_POLYOBJ)
{
FPolyObj::ClearAllSubsectorLinks();
level.ClearAllSubsectorLinks();
}
}

View file

@ -1656,7 +1656,7 @@ void G_SnapshotLevel ()
if (arc.OpenWriter(save_formatted))
{
SaveVersion = SAVEVER;
G_SerializeLevel(arc, false);
G_SerializeLevel(arc, &level, false);
level.info->Snapshot = arc.GetCompressedOutput();
}
}
@ -1683,7 +1683,7 @@ void G_UnSnapshotLevel (bool hubLoad)
return;
}
G_SerializeLevel (arc, hubLoad);
G_SerializeLevel (arc, &level, hubLoad);
level.FromSnapshot = true;
TThinkerIterator<AActor> it(NAME_PlayerPawn);

View file

@ -115,6 +115,8 @@ struct FLevelLocals : public FLevelData
void ClearLevelData();
void ClearPortals();
bool CheckIfExitIsGood(AActor *self, level_info_t *newmap);
void FormatMapName(FString &mapname, const char *mapnamecolor);
void ClearAllSubsectorLinks();
FSectorTagIterator GetSectorTagIterator(int tag)
{
return FSectorTagIterator(tag);
@ -160,6 +162,13 @@ struct FLevelLocals : public FLevelData
{
return P_PointInSector(pos);
}
FPolyObj *GetPolyobj (int polyNum)
{
auto index = Polyobjects.FindEx([=](const auto &poly) { return poly.tag == polyNum; });
return index == Polyobjects.Size()? nullptr : &Polyobjects[index];
}
uint8_t md5[16]; // for savegame validation. If the MD5 does not match the savegame won't be loaded.
int time; // time in the hub

View file

@ -424,7 +424,7 @@ void HWDrawInfo::CreateScene()
// reset the portal manager
screen->mPortalState->StartFrame();
PO_LinkToSubsectors();
PO_LinkToSubsectors(&level);
ProcessAll.Clock();

View file

@ -282,7 +282,7 @@ void MapLoader::TranslateToStartSpot (int tag, const DVector2 &origin)
FPolyObj *po;
DVector2 delta;
po = PO_GetPolyobj(tag);
po = Level->GetPolyobj(tag);
if (po == nullptr)
{ // didn't match the tag with a polyobj tag
Printf(TEXTCOLOR_RED "TranslateToStartSpot: Unable to match polyobj tag: %d\n", tag);

View file

@ -5654,7 +5654,7 @@ int DLevelScript::CallFunction(int argCount, int funcIndex, int32_t *args)
const char *seqname = level.Behaviors.LookupString(args[1]);
if (seqname != NULL)
{
FPolyObj *poly = PO_GetPolyobj(args[0]);
FPolyObj *poly = level.GetPolyobj(args[0]);
if (poly != NULL)
{
SN_StartSequence(poly, seqname, 0);
@ -5665,7 +5665,7 @@ int DLevelScript::CallFunction(int argCount, int funcIndex, int32_t *args)
case ACSF_GetPolyobjX:
{
FPolyObj *poly = PO_GetPolyobj(args[0]);
FPolyObj *poly = level.GetPolyobj(args[0]);
if (poly != NULL)
{
return DoubleToACS(poly->StartSpot.pos.X);
@ -5675,7 +5675,7 @@ int DLevelScript::CallFunction(int argCount, int funcIndex, int32_t *args)
case ACSF_GetPolyobjY:
{
FPolyObj *poly = PO_GetPolyobj(args[0]);
FPolyObj *poly = level.GetPolyobj(args[0]);
if (poly != NULL)
{
return DoubleToACS(poly->StartSpot.pos.Y);
@ -6817,7 +6817,7 @@ int DLevelScript::RunScript ()
case SCRIPT_PolyWait:
// Wait for polyobj(s) to stop moving, then enter state running
if (!PO_Busy (statedata))
if (!PO_Busy (&level, statedata))
{
state = SCRIPT_Running;
}

View file

@ -71,7 +71,7 @@
static const uint8_t ChangeMap[8] = { 0, 1, 5, 3, 7, 2, 6, 0 };
#define FUNC(a) static int a (line_t *ln, AActor *it, bool backSide, \
#define FUNC(a) static int a (FLevelLocals *Level, line_t *ln, AActor *it, bool backSide, \
int arg0, int arg1, int arg2, int arg3, int arg4)
#define SPEED(a) ((a) / 8.)
@ -141,31 +141,31 @@ FUNC(LS_NOP)
FUNC(LS_Polyobj_RotateLeft)
// Polyobj_RotateLeft (po, speed, angle)
{
return EV_RotatePoly (ln, arg0, arg1, arg2, 1, false);
return EV_RotatePoly (Level, ln, arg0, arg1, arg2, 1, false);
}
FUNC(LS_Polyobj_RotateRight)
// Polyobj_rotateRight (po, speed, angle)
{
return EV_RotatePoly (ln, arg0, arg1, arg2, -1, false);
return EV_RotatePoly (Level, ln, arg0, arg1, arg2, -1, false);
}
FUNC(LS_Polyobj_Move)
// Polyobj_Move (po, speed, angle, distance)
{
return EV_MovePoly (ln, arg0, SPEED(arg1), BYTEANGLE(arg2), arg3, false);
return EV_MovePoly (Level, ln, arg0, SPEED(arg1), BYTEANGLE(arg2), arg3, false);
}
FUNC(LS_Polyobj_MoveTimes8)
// Polyobj_MoveTimes8 (po, speed, angle, distance)
{
return EV_MovePoly (ln, arg0, SPEED(arg1), BYTEANGLE(arg2), arg3 * 8, false);
return EV_MovePoly (Level, ln, arg0, SPEED(arg1), BYTEANGLE(arg2), arg3 * 8, false);
}
FUNC(LS_Polyobj_MoveTo)
// Polyobj_MoveTo (po, speed, x, y)
{
return EV_MovePolyTo (ln, arg0, SPEED(arg1), DVector2(arg2, arg3), false);
return EV_MovePolyTo (Level, ln, arg0, SPEED(arg1), DVector2(arg2, arg3), false);
}
FUNC(LS_Polyobj_MoveToSpot)
@ -174,49 +174,49 @@ FUNC(LS_Polyobj_MoveToSpot)
FActorIterator iterator (arg2);
AActor *spot = iterator.Next();
if (spot == NULL) return false;
return EV_MovePolyTo (ln, arg0, SPEED(arg1), spot->Pos(), false);
return EV_MovePolyTo (Level, ln, arg0, SPEED(arg1), spot->Pos(), false);
}
FUNC(LS_Polyobj_DoorSwing)
// Polyobj_DoorSwing (po, speed, angle, delay)
{
return EV_OpenPolyDoor (ln, arg0, arg1, BYTEANGLE(arg2), arg3, 0, PODOOR_SWING);
return EV_OpenPolyDoor (Level, ln, arg0, arg1, BYTEANGLE(arg2), arg3, 0, PODOOR_SWING);
}
FUNC(LS_Polyobj_DoorSlide)
// Polyobj_DoorSlide (po, speed, angle, distance, delay)
{
return EV_OpenPolyDoor (ln, arg0, SPEED(arg1), BYTEANGLE(arg2), arg4, arg3, PODOOR_SLIDE);
return EV_OpenPolyDoor (Level, ln, arg0, SPEED(arg1), BYTEANGLE(arg2), arg4, arg3, PODOOR_SLIDE);
}
FUNC(LS_Polyobj_OR_RotateLeft)
// Polyobj_OR_RotateLeft (po, speed, angle)
{
return EV_RotatePoly (ln, arg0, arg1, arg2, 1, true);
return EV_RotatePoly (Level, ln, arg0, arg1, arg2, 1, true);
}
FUNC(LS_Polyobj_OR_RotateRight)
// Polyobj_OR_RotateRight (po, speed, angle)
{
return EV_RotatePoly (ln, arg0, arg1, arg2, -1, true);
return EV_RotatePoly (Level, ln, arg0, arg1, arg2, -1, true);
}
FUNC(LS_Polyobj_OR_Move)
// Polyobj_OR_Move (po, speed, angle, distance)
{
return EV_MovePoly (ln, arg0, SPEED(arg1), BYTEANGLE(arg2), arg3, true);
return EV_MovePoly (Level, ln, arg0, SPEED(arg1), BYTEANGLE(arg2), arg3, true);
}
FUNC(LS_Polyobj_OR_MoveTimes8)
// Polyobj_OR_MoveTimes8 (po, speed, angle, distance)
{
return EV_MovePoly (ln, arg0, SPEED(arg1), BYTEANGLE(arg2), arg3 * 8, true);
return EV_MovePoly (Level, ln, arg0, SPEED(arg1), BYTEANGLE(arg2), arg3 * 8, true);
}
FUNC(LS_Polyobj_OR_MoveTo)
// Polyobj_OR_MoveTo (po, speed, x, y)
{
return EV_MovePolyTo (ln, arg0, SPEED(arg1), DVector2(arg2, arg3), true);
return EV_MovePolyTo (Level, ln, arg0, SPEED(arg1), DVector2(arg2, arg3), true);
}
FUNC(LS_Polyobj_OR_MoveToSpot)
@ -225,13 +225,13 @@ FUNC(LS_Polyobj_OR_MoveToSpot)
FActorIterator iterator (arg2);
AActor *spot = iterator.Next();
if (spot == NULL) return false;
return EV_MovePolyTo (ln, arg0, SPEED(arg1), spot->Pos(), true);
return EV_MovePolyTo (Level, ln, arg0, SPEED(arg1), spot->Pos(), true);
}
FUNC(LS_Polyobj_Stop)
// Polyobj_Stop (po)
{
return EV_StopPoly (arg0);
return EV_StopPoly (Level, arg0);
}
FUNC(LS_Door_Close)
@ -258,7 +258,7 @@ FUNC(LS_Door_LockedRaise)
#if 0
// In Hexen this originally created a thinker running for nearly 4 years.
// Let's not do this unless it becomes necessary because this can hang tagwait.
return EV_DoDoor (arg2 || (level.flags2 & LEVEL2_HEXENHACK) ? DDoor::doorRaise : DDoor::doorOpen, ln, it,
return EV_DoDoor (arg2 || (Level->flags2 & LEVEL2_HEXENHACK) ? DDoor::doorRaise : DDoor::doorOpen, ln, it,
#else
return EV_DoDoor (arg2 ? DDoor::doorRaise : DDoor::doorOpen, ln, it,
#endif
@ -1060,7 +1060,7 @@ FUNC(LS_Generic_Lift)
FUNC(LS_Exit_Normal)
// Exit_Normal (position)
{
if (level.CheckIfExitIsGood (it, FindLevelInfo(G_GetExitMap())))
if (Level->CheckIfExitIsGood (it, FindLevelInfo(G_GetExitMap())))
{
G_ExitLevel (arg0, false);
return true;
@ -1071,7 +1071,7 @@ FUNC(LS_Exit_Normal)
FUNC(LS_Exit_Secret)
// Exit_Secret (position)
{
if (level.CheckIfExitIsGood (it, FindLevelInfo(G_GetSecretExitMap())))
if (Level->CheckIfExitIsGood (it, FindLevelInfo(G_GetSecretExitMap())))
{
G_SecretExitLevel (arg0);
return true;
@ -1086,7 +1086,7 @@ FUNC(LS_Teleport_NewMap)
{
level_info_t *info = FindLevelByNum (arg0);
if (info && level.CheckIfExitIsGood (it, info))
if (info && Level->CheckIfExitIsGood (it, info))
{
G_ChangeLevel(info->MapName, arg1, arg2 ? CHANGELEVEL_KEEPFACING : 0);
return true;
@ -1181,7 +1181,7 @@ FUNC(LS_TeleportInSector)
FUNC(LS_Teleport_EndGame)
// Teleport_EndGame ()
{
if (!backSide && level.CheckIfExitIsGood (it, NULL))
if (!backSide && Level->CheckIfExitIsGood (it, NULL))
{
G_ChangeLevel(NULL, 0, 0);
return true;
@ -1219,7 +1219,7 @@ FUNC(LS_ThrustThing)
}
else if (it)
{
if (level.flags2 & LEVEL2_HEXENHACK && backSide)
if (Level->flags2 & LEVEL2_HEXENHACK && backSide)
{
return false;
}
@ -1913,7 +1913,7 @@ FUNC(LS_ACS_Execute)
if (arg1 == 0)
{
mapname = level.MapName;
mapname = Level->MapName;
}
else if ((info = FindLevelByNum(arg1)) != NULL)
{
@ -1936,7 +1936,7 @@ FUNC(LS_ACS_ExecuteAlways)
if (arg1 == 0)
{
mapname = level.MapName;
mapname = Level->MapName;
}
else if ((info = FindLevelByNum(arg1)) != NULL)
{
@ -1955,7 +1955,7 @@ FUNC(LS_ACS_LockedExecute)
if (arg4 && !P_CheckKeys (it, arg4, true))
return false;
else
return LS_ACS_Execute (ln, it, backSide, arg0, arg1, arg2, arg3, 0);
return LS_ACS_Execute (Level, ln, it, backSide, arg0, arg1, arg2, arg3, 0);
}
FUNC(LS_ACS_LockedExecuteDoor)
@ -1964,7 +1964,7 @@ FUNC(LS_ACS_LockedExecuteDoor)
if (arg4 && !P_CheckKeys (it, arg4, false))
return false;
else
return LS_ACS_Execute (ln, it, backSide, arg0, arg1, arg2, arg3, 0);
return LS_ACS_Execute (Level, ln, it, backSide, arg0, arg1, arg2, arg3, 0);
}
FUNC(LS_ACS_ExecuteWithResult)
@ -1976,7 +1976,7 @@ FUNC(LS_ACS_ExecuteWithResult)
int args[4] = { arg1, arg2, arg3, arg4 };
int flags = (backSide ? ACS_BACKSIDE : 0) | ACS_ALWAYS | ACS_WANTRESULT;
return P_StartScript (it, ln, arg0, level.MapName, args, 4, flags);
return P_StartScript (it, ln, arg0, Level->MapName, args, 4, flags);
}
FUNC(LS_ACS_Suspend)
@ -1985,7 +1985,7 @@ FUNC(LS_ACS_Suspend)
level_info_t *info;
if (arg1 == 0)
P_SuspendScript (arg0, level.MapName);
P_SuspendScript (arg0, Level->MapName);
else if ((info = FindLevelByNum (arg1)) )
P_SuspendScript (arg0, info->MapName);
@ -1998,7 +1998,7 @@ FUNC(LS_ACS_Terminate)
level_info_t *info;
if (arg1 == 0)
P_TerminateScript (arg0, level.MapName);
P_TerminateScript (arg0, Level->MapName);
else if ((info = FindLevelByNum (arg1)) )
P_TerminateScript (arg0, info->MapName);
@ -2197,7 +2197,7 @@ FUNC(LS_Sector_ChangeSound)
FSectorTagIterator itr(arg0);
while ((secNum = itr.Next()) >= 0)
{
level.sectors[secNum].seqType = arg1;
Level->sectors[secNum].seqType = arg1;
rtn = true;
}
return rtn;
@ -2219,7 +2219,7 @@ FUNC(LS_Sector_ChangeFlags)
arg2 &= ~SECF_NOMODIFY;
while ((secNum = itr.Next()) >= 0)
{
level.sectors[secNum].Flags = (level.sectors[secNum].Flags | arg1) & ~arg2;
Level->sectors[secNum].Flags = (Level->sectors[secNum].Flags | arg1) & ~arg2;
rtn = true;
}
return rtn;
@ -2265,8 +2265,8 @@ FUNC(LS_Sector_SetTranslucent)
FSectorTagIterator itr(arg0);
while ((secnum = itr.Next()) >= 0)
{
level.sectors[secnum].SetAlpha(arg1, clamp(arg2, 0, 255) / 255.);
level.sectors[secnum].ChangeFlags(arg1, ~PLANEF_ADDITIVE, arg3? PLANEF_ADDITIVE:0);
Level->sectors[secnum].SetAlpha(arg1, clamp(arg2, 0, 255) / 255.);
Level->sectors[secnum].ChangeFlags(arg1, ~PLANEF_ADDITIVE, arg3? PLANEF_ADDITIVE:0);
}
return true;
}
@ -2281,7 +2281,7 @@ FUNC(LS_Sector_SetLink)
int control = P_FindFirstSectorFromTag(arg0);
if (control >= 0)
{
return P_AddSectorLinks(&level.sectors[control], arg1, arg2, arg3);
return P_AddSectorLinks(&Level->sectors[control], arg1, arg2, arg3);
}
}
return false;
@ -2401,10 +2401,10 @@ FUNC(LS_Sector_SetDamage)
arg3 = 1;
}
}
level.sectors[secnum].damageamount = (short)arg1;
level.sectors[secnum].damagetype = MODtoDamageType(arg2);
level.sectors[secnum].damageinterval = (short)arg3;
level.sectors[secnum].leakydamage = (short)arg4;
Level->sectors[secnum].damageamount = (short)arg1;
Level->sectors[secnum].damagetype = MODtoDamageType(arg2);
Level->sectors[secnum].damageinterval = (short)arg3;
Level->sectors[secnum].leakydamage = (short)arg4;
}
return true;
}
@ -2421,7 +2421,7 @@ FUNC(LS_Sector_SetGravity)
FSectorTagIterator itr(arg0);
int secnum;
while ((secnum = itr.Next()) >= 0)
level.sectors[secnum].gravity = gravity;
Level->sectors[secnum].gravity = gravity;
return true;
}
@ -2433,7 +2433,7 @@ FUNC(LS_Sector_SetColor)
int secnum;
while ((secnum = itr.Next()) >= 0)
{
level.sectors[secnum].SetColor(PalEntry(arg1, arg2, arg3), arg4);
Level->sectors[secnum].SetColor(PalEntry(arg1, arg2, arg3), arg4);
}
return true;
@ -2446,7 +2446,7 @@ FUNC(LS_Sector_SetFade)
int secnum;
while ((secnum = itr.Next()) >= 0)
{
level.sectors[secnum].SetFade(PalEntry(arg1, arg2, arg3));
Level->sectors[secnum].SetFade(PalEntry(arg1, arg2, arg3));
}
return true;
}
@ -2461,8 +2461,8 @@ FUNC(LS_Sector_SetCeilingPanning)
int secnum;
while ((secnum = itr.Next()) >= 0)
{
level.sectors[secnum].SetXOffset(sector_t::ceiling, xofs);
level.sectors[secnum].SetYOffset(sector_t::ceiling, yofs);
Level->sectors[secnum].SetXOffset(sector_t::ceiling, xofs);
Level->sectors[secnum].SetYOffset(sector_t::ceiling, yofs);
}
return true;
}
@ -2477,8 +2477,8 @@ FUNC(LS_Sector_SetFloorPanning)
int secnum;
while ((secnum = itr.Next()) >= 0)
{
level.sectors[secnum].SetXOffset(sector_t::floor, xofs);
level.sectors[secnum].SetYOffset(sector_t::floor, yofs);
Level->sectors[secnum].SetXOffset(sector_t::floor, xofs);
Level->sectors[secnum].SetYOffset(sector_t::floor, yofs);
}
return true;
}
@ -2499,9 +2499,9 @@ FUNC(LS_Sector_SetFloorScale)
while ((secnum = itr.Next()) >= 0)
{
if (xscale)
level.sectors[secnum].SetXScale(sector_t::floor, xscale);
Level->sectors[secnum].SetXScale(sector_t::floor, xscale);
if (yscale)
level.sectors[secnum].SetYScale(sector_t::floor, yscale);
Level->sectors[secnum].SetYScale(sector_t::floor, yscale);
}
return true;
}
@ -2522,9 +2522,9 @@ FUNC(LS_Sector_SetCeilingScale)
while ((secnum = itr.Next()) >= 0)
{
if (xscale)
level.sectors[secnum].SetXScale(sector_t::ceiling, xscale);
Level->sectors[secnum].SetXScale(sector_t::ceiling, xscale);
if (yscale)
level.sectors[secnum].SetYScale(sector_t::ceiling, yscale);
Level->sectors[secnum].SetYScale(sector_t::ceiling, yscale);
}
return true;
}
@ -2544,9 +2544,9 @@ FUNC(LS_Sector_SetFloorScale2)
while ((secnum = itr.Next()) >= 0)
{
if (arg1)
level.sectors[secnum].SetXScale(sector_t::floor, xscale);
Level->sectors[secnum].SetXScale(sector_t::floor, xscale);
if (arg2)
level.sectors[secnum].SetYScale(sector_t::floor, yscale);
Level->sectors[secnum].SetYScale(sector_t::floor, yscale);
}
return true;
}
@ -2566,9 +2566,9 @@ FUNC(LS_Sector_SetCeilingScale2)
while ((secnum = itr.Next()) >= 0)
{
if (arg1)
level.sectors[secnum].SetXScale(sector_t::ceiling, xscale);
Level->sectors[secnum].SetXScale(sector_t::ceiling, xscale);
if (arg2)
level.sectors[secnum].SetYScale(sector_t::ceiling, yscale);
Level->sectors[secnum].SetYScale(sector_t::ceiling, yscale);
}
return true;
}
@ -2583,8 +2583,8 @@ FUNC(LS_Sector_SetRotation)
int secnum;
while ((secnum = itr.Next()) >= 0)
{
level.sectors[secnum].SetAngle(sector_t::floor, floor);
level.sectors[secnum].SetAngle(sector_t::ceiling, ceiling);
Level->sectors[secnum].SetAngle(sector_t::floor, floor);
Level->sectors[secnum].SetAngle(sector_t::ceiling, ceiling);
}
return true;
}
@ -2631,7 +2631,7 @@ FUNC(LS_Line_SetTextureOffset)
int line;
while ((line = itr.Next()) >= 0)
{
side_t *side = level.lines[line].sidedef[arg3];
side_t *side = Level->lines[line].sidedef[arg3];
if (side != NULL)
{
@ -2686,7 +2686,7 @@ FUNC(LS_Line_SetTextureScale)
int line;
while ((line = itr.Next()) >= 0)
{
side_t *side = level.lines[line].sidedef[arg3];
side_t *side = Level->lines[line].sidedef[arg3];
if (side != NULL)
{
if ((arg4&8)==0)
@ -2760,7 +2760,7 @@ FUNC(LS_Line_SetBlocking)
int line;
while ((line = itr.Next()) >= 0)
{
level.lines[line].flags = (level.lines[line].flags & ~clearflags) | setflags;
Level->lines[line].flags = (Level->lines[line].flags & ~clearflags) | setflags;
}
return true;
}
@ -2792,7 +2792,7 @@ FUNC(LS_Line_SetAutomapFlags)
int line;
while ((line = itr.Next()) >= 0)
{
level.lines[line].flags = (level.lines[line].flags & ~clearflags) | setflags;
Level->lines[line].flags = (Level->lines[line].flags & ~clearflags) | setflags;
}
return true;
@ -2807,7 +2807,7 @@ FUNC(LS_Line_SetAutomapStyle)
int line;
while ((line = itr.Next()) >= 0)
{
level.lines[line].automapstyle = (AutomapLineStyle) arg1;
Level->lines[line].automapstyle = (AutomapLineStyle) arg1;
}
return true;
@ -2953,7 +2953,7 @@ FUNC(LS_SetPlayerProperty)
}
else if (it->player - players == consoleplayer)
{
level.flags2 |= LEVEL2_ALLMAP;
Level->flags2 |= LEVEL2_ALLMAP;
}
}
else
@ -2968,7 +2968,7 @@ FUNC(LS_SetPlayerProperty)
}
else if (it->player - players == consoleplayer)
{
level.flags2 &= ~LEVEL2_ALLMAP;
Level->flags2 &= ~LEVEL2_ALLMAP;
}
}
}
@ -2993,7 +2993,7 @@ FUNC(LS_SetPlayerProperty)
}
else if (i == consoleplayer)
{
level.flags2 |= LEVEL2_ALLMAP;
Level->flags2 |= LEVEL2_ALLMAP;
}
}
else
@ -3008,7 +3008,7 @@ FUNC(LS_SetPlayerProperty)
}
else if (i == consoleplayer)
{
level.flags2 &= ~LEVEL2_ALLMAP;
Level->flags2 &= ~LEVEL2_ALLMAP;
}
}
}
@ -3107,14 +3107,14 @@ FUNC(LS_TranslucentLine)
int linenum;
while ((linenum = itr.Next()) >= 0)
{
level.lines[linenum].alpha = clamp(arg1, 0, 255) / 255.;
Level->lines[linenum].alpha = clamp(arg1, 0, 255) / 255.;
if (arg2 == 0)
{
level.lines[linenum].flags &= ~ML_ADDTRANS;
Level->lines[linenum].flags &= ~ML_ADDTRANS;
}
else if (arg2 == 1)
{
level.lines[linenum].flags |= ML_ADDTRANS;
Level->lines[linenum].flags |= ML_ADDTRANS;
}
else
{
@ -3129,7 +3129,7 @@ FUNC(LS_Autosave)
{
if (gameaction != ga_savegame)
{
level.flags2 &= ~LEVEL2_NOAUTOSAVEHINT;
Level->flags2 &= ~LEVEL2_NOAUTOSAVEHINT;
Net_WriteByte (DEM_CHECKAUTOSAVE);
}
return true;
@ -3237,7 +3237,7 @@ FUNC(LS_ClearForceField)
int secnum;
while ((secnum = itr.Next()) >= 0)
{
sector_t *sec = &level.sectors[secnum];
sector_t *sec = &Level->sectors[secnum];
rtn = true;
sec->RemoveForceField();
@ -3413,9 +3413,9 @@ FUNC(LS_Sector_SetPlaneReflection)
while ((secnum = itr.Next()) >= 0)
{
sector_t * s = &level.sectors[secnum];
sector_t * s = &Level->sectors[secnum];
if (!s->floorplane.isSlope()) s->reflect[sector_t::floor] = arg1 / 255.f;
if (!s->ceilingplane.isSlope()) level.sectors[secnum].reflect[sector_t::ceiling] = arg2 / 255.f;
if (!s->ceilingplane.isSlope()) Level->sectors[secnum].reflect[sector_t::ceiling] = arg2 / 255.f;
}
return true;
@ -3428,15 +3428,15 @@ FUNC(LS_SetGlobalFogParameter)
switch (arg0)
{
case 0:
level.fogdensity = arg1 >> 1;
Level->fogdensity = arg1 >> 1;
return true;
case 1:
level.outsidefogdensity = arg1 >> 1;
Level->outsidefogdensity = arg1 >> 1;
return true;
case 2:
level.skyfog = arg1;
Level->skyfog = arg1;
return true;
default:
@ -3454,7 +3454,7 @@ FUNC(LS_Sector_SetFloorGlow)
while ((secnum = itr.Next()) >= 0)
{
sector_t * s = &level.sectors[secnum];
sector_t * s = &Level->sectors[secnum];
s->SetGlowColor(sector_t::floor, color);
s->SetGlowHeight(sector_t::floor, float(arg1));
}
@ -3471,7 +3471,7 @@ FUNC(LS_Sector_SetCeilingGlow)
while ((secnum = itr.Next()) >= 0)
{
sector_t * s = &level.sectors[secnum];
sector_t * s = &Level->sectors[secnum];
s->SetGlowColor(sector_t::ceiling, color);
s->SetGlowHeight(sector_t::ceiling, float(arg1));
}
@ -3489,7 +3489,7 @@ FUNC(LS_Line_SetHealth)
while ((l = itr.Next()) >= 0)
{
line_t* line = &level.lines[l];
line_t* line = &Level->lines[l];
line->health = arg1;
if (line->healthgroup)
P_SetHealthGroupHealth(line->healthgroup, arg1);
@ -3508,7 +3508,7 @@ FUNC(LS_Sector_SetHealth)
while ((s = itr.Next()) >= 0)
{
sector_t* sector = &level.sectors[s];
sector_t* sector = &Level->sectors[s];
if (arg1 == SECPART_Ceiling)
{
sector->healthceiling = arg2;
@ -3937,7 +3937,7 @@ int P_ExecuteSpecial(int num,
{
if (num >= 0 && num < (int)countof(LineSpecials))
{
return LineSpecials[num](line, activator, backSide, arg1, arg2, arg3, arg4, arg5);
return LineSpecials[num](&level, line, activator, backSide, arg1, arg2, arg3, arg4, arg5);
}
return 0;
}

View file

@ -187,10 +187,12 @@ typedef enum {
struct line_t;
class AActor;
struct FLevelLocals;
FName MODtoDamageType (int mod);
typedef int (*lnSpecFunc)(struct line_t *line,
typedef int (*lnSpecFunc)(FLevelLocals *Level,
struct line_t *line,
class AActor *activator,
bool backSide,
int arg1,
@ -211,6 +213,7 @@ int P_GetMaxLineSpecial();
int P_FindLineSpecial (const char *string, int *min_args=NULL, int *max_args=NULL);
bool P_ActivateThingSpecial(AActor * thing, AActor * trigger, bool death=false);
int P_ExecuteSpecial(int num,
//FLevelLocals *lev, must be added later.
struct line_t *line,
class AActor *activator,
bool backSide,

View file

@ -248,11 +248,6 @@ FSerializer &Serialize(FSerializer &arc, const char *key, secplane_t &p, secplan
FSerializer &Serialize(FSerializer &arc, const char *key, sector_t &p, sector_t *def)
{
// save the Scroll data here because it's a lot easier to handle a default.
// Just writing out the full array can massively inflate the archive for no gain.
DVector2 scroll = { 0,0 }, nul = { 0,0 };
if (arc.isWriting() && level.Scrolls.Size() > 0) scroll = level.Scrolls[p.sectornum];
if (arc.BeginObject(key))
{
arc("floorplane", p.floorplane, def->floorplane)
@ -300,23 +295,12 @@ FSerializer &Serialize(FSerializer &arc, const char *key, sector_t &p, sector_t
("gravity", p.gravity, def->gravity)
.Terrain("floorterrain", p.terrainnum[0], &def->terrainnum[0])
.Terrain("ceilingterrain", p.terrainnum[1], &def->terrainnum[1])
("scrolls", scroll, nul)
("healthfloor", p.healthfloor, def->healthfloor)
("healthceiling", p.healthceiling, def->healthceiling)
("health3d", p.health3d, def->health3d)
// GZDoom exclusive:
.Array("reflect", p.reflect, def->reflect, 2, true)
.EndObject();
if (arc.isReading() && !scroll.isZero())
{
if (level.Scrolls.Size() == 0)
{
level.Scrolls.Resize(level.sectors.Size());
memset(&level.Scrolls[0], 0, sizeof(level.Scrolls[0])*level.Scrolls.Size());
level.Scrolls[p.sectornum] = scroll;
}
}
}
return arc;
}
@ -575,7 +559,7 @@ void P_SerializeSounds(FSerializer &arc)
void CopyPlayer(player_t *dst, player_t *src, const char *name);
static void ReadOnePlayer(FSerializer &arc, bool skipload);
static void ReadMultiplePlayers(FSerializer &arc, int numPlayers, int numPlayersNow, bool skipload);
static void SpawnExtraPlayers();
static void SpawnExtraPlayers(FLevelLocals *Level);
//==========================================================================
//
@ -583,7 +567,7 @@ static void SpawnExtraPlayers();
//
//==========================================================================
void P_SerializePlayers(FSerializer &arc, bool skipload)
void P_SerializePlayers(FLevelLocals *Level, FSerializer &arc, bool skipload)
{
int numPlayers, numPlayersNow;
int i;
@ -640,7 +624,7 @@ void P_SerializePlayers(FSerializer &arc, bool skipload)
}
if (!skipload && numPlayersNow > numPlayers)
{
SpawnExtraPlayers();
SpawnExtraPlayers(Level);
}
// Redo pitch limits, since the spawned player has them at 0.
players[consoleplayer].SendPitchLimits();
@ -891,7 +875,7 @@ void CopyPlayer(player_t *dst, player_t *src, const char *name)
//
//==========================================================================
static void SpawnExtraPlayers()
static void SpawnExtraPlayers(FLevelLocals *Level)
{
// If there are more players now than there were in the savegame,
// be sure to spawn the extra players.
@ -907,7 +891,7 @@ static void SpawnExtraPlayers()
if (playeringame[i] && players[i].mo == NULL)
{
players[i].playerstate = PST_ENTER;
P_SpawnPlayer(&level.playerstarts[i], i, (level.flags2 & LEVEL2_PRERAISEWEAPON) ? SPF_WEAPONFULLYUP : 0);
P_SpawnPlayer(&Level->playerstarts[i], i, (level.flags2 & LEVEL2_PRERAISEWEAPON) ? SPF_WEAPONFULLYUP : 0);
}
}
}
@ -918,13 +902,13 @@ static void SpawnExtraPlayers()
//
//============================================================================
void G_SerializeLevel(FSerializer &arc, bool hubload)
void G_SerializeLevel(FSerializer &arc, FLevelLocals *Level, bool hubload)
{
int i = level.totaltime;
int i = Level->totaltime;
if (arc.isWriting())
{
arc.Array("checksum", level.md5, 16);
arc.Array("checksum", Level->md5, 16);
}
else
{
@ -933,11 +917,11 @@ void G_SerializeLevel(FSerializer &arc, bool hubload)
// deep down in the deserializer or just a crash if the few insufficient safeguards were not triggered.
uint8_t chk[16] = { 0 };
arc.Array("checksum", chk, 16);
if (arc.GetSize("linedefs") != level.lines.Size() ||
arc.GetSize("sidedefs") != level.sides.Size() ||
arc.GetSize("sectors") != level.sectors.Size() ||
arc.GetSize("polyobjs") != level.Polyobjects.Size() ||
memcmp(chk, level.md5, 16))
if (arc.GetSize("linedefs") != Level->lines.Size() ||
arc.GetSize("sidedefs") != Level->sides.Size() ||
arc.GetSize("sectors") != Level->sectors.Size() ||
arc.GetSize("polyobjs") != Level->Polyobjects.Size() ||
memcmp(chk, Level->md5, 16))
{
I_Error("Savegame is from a different level");
}
@ -953,55 +937,57 @@ void G_SerializeLevel(FSerializer &arc, bool hubload)
arc("multiplayer", multiplayer);
arc("level.flags", level.flags)
("level.flags2", level.flags2)
("level.fadeto", level.fadeto)
("level.found_secrets", level.found_secrets)
("level.found_items", level.found_items)
("level.killed_monsters", level.killed_monsters)
("level.total_secrets", level.total_secrets)
("level.total_items", level.total_items)
("level.total_monsters", level.total_monsters)
("level.gravity", level.gravity)
("level.aircontrol", level.aircontrol)
("level.teamdamage", level.teamdamage)
("level.maptime", level.maptime)
("level.totaltime", i)
("level.skytexture1", level.skytexture1)
("level.skytexture2", level.skytexture2)
("level.fogdensity", level.fogdensity)
("level.outsidefogdensity", level.outsidefogdensity)
("level.skyfog", level.skyfog)
("level.deathsequence", level.deathsequence)
("level.bodyqueslot", level.bodyqueslot)
("level.spawnindex", level.spawnindex)
.Array("level.bodyque", level.bodyque, level.BODYQUESIZE)
("level.corpsequeue", level.CorpseQueue)
("level.spotstate", level.SpotState)
("level.fragglethinker", level.FraggleScriptThinker)
("level.acsthinker", level.ACSThinker);
("level.impactdecalcount", level.ImpactDecalCount);
arc("flags", Level->flags)
("flags2", Level->flags2)
("fadeto", Level->fadeto)
("found_secrets", Level->found_secrets)
("found_items", Level->found_items)
("killed_monsters", Level->killed_monsters)
("total_secrets", Level->total_secrets)
("total_items", Level->total_items)
("total_monsters", Level->total_monsters)
("gravity", Level->gravity)
("aircontrol", Level->aircontrol)
("teamdamage", Level->teamdamage)
("maptime", Level->maptime)
("totaltime", i)
("skytexture1", Level->skytexture1)
("skytexture2", Level->skytexture2)
("fogdensity", Level->fogdensity)
("outsidefogdensity", Level->outsidefogdensity)
("skyfog", Level->skyfog)
("deathsequence", Level->deathsequence)
("bodyqueslot", Level->bodyqueslot)
("spawnindex", Level->spawnindex)
.Array("bodyque", Level->bodyque, Level->BODYQUESIZE)
("corpsequeue", Level->CorpseQueue)
("spotstate", Level->SpotState)
("fragglethinker", Level->FraggleScriptThinker)
("acsthinker", Level->ACSThinker)
("impactdecalcount", Level->ImpactDecalCount)
("scrolls", Level->Scrolls);
// Hub transitions must keep the current total time
if (!hubload)
level.totaltime = i;
Level->totaltime = i;
if (arc.isReading())
{
sky1texture = level.skytexture1;
sky2texture = level.skytexture2;
sky1texture = Level->skytexture1;
sky2texture = Level->skytexture2;
R_InitSkyMap();
G_AirControlChanged();
}
level.Behaviors.SerializeModuleStates(arc);
Level->Behaviors.SerializeModuleStates(arc);
// The order here is important: First world state, then portal state, then thinkers, and last polyobjects.
arc("linedefs", level.lines, level.loadlines);
arc("sidedefs", level.sides, level.loadsides);
arc("sectors", level.sectors, level.loadsectors);
arc("zones", level.Zones);
arc("lineportals", level.linePortals);
arc("sectorportals", level.sectorPortals);
arc("linedefs", Level->lines, Level->loadlines);
arc("sidedefs", Level->sides, Level->loadsides);
arc("sectors", Level->sectors, Level->loadsectors);
arc("zones", Level->Zones);
arc("lineportals", Level->linePortals);
arc("sectorportals", Level->sectorPortals);
if (arc.isReading()) P_FinalizePortals();
// [ZZ] serialize health groups
@ -1009,18 +995,18 @@ void G_SerializeLevel(FSerializer &arc, bool hubload)
// [ZZ] serialize events
E_SerializeEvents(arc);
DThinker::SerializeThinkers(arc, hubload);
arc("polyobjs", level.Polyobjects);
arc("polyobjs", Level->Polyobjects);
SerializeSubsectors(arc, "subsectors");
StatusBar->SerializeMessages(arc);
AM_SerializeMarkers(arc);
FRemapTable::StaticSerializeTranslations(arc);
level.canvasTextureInfo.Serialize(arc);
P_SerializePlayers(arc, hubload);
Level->canvasTextureInfo.Serialize(arc);
P_SerializePlayers(Level, arc, hubload);
P_SerializeSounds(arc);
if (arc.isReading())
{
for (auto &sec : level.sectors)
for (auto &sec : Level->sectors)
{
P_Recalculate3DFloors(&sec);
}
@ -1033,5 +1019,5 @@ void G_SerializeLevel(FSerializer &arc, bool hubload)
}
}
AActor::RecreateAllAttachedLights();
InitPortalGroups(&level);
InitPortalGroups(Level);
}

View file

@ -44,6 +44,6 @@ void P_DestroyThinkers(bool hubLoad);
void P_ReadACSDefereds (FSerializer &);
void P_WriteACSDefereds (FSerializer &);
void G_SerializeLevel(FSerializer &arc, bool hubLoad);
void G_SerializeLevel(FSerializer &arc, FLevelLocals *Level, bool hubLoad);
#endif // __P_SAVEG_H__

View file

@ -338,7 +338,7 @@ void P_FreeLevelData ()
AActor::ClearTIDHashes();
interpolator.ClearInterpolations(); // [RH] Nothing to interpolate on a fresh level.
FPolyObj::ClearAllSubsectorLinks(); // can't be done as part of the polyobj deletion process.
level.ClearAllSubsectorLinks(); // can't be done as part of the polyobj deletion process.
SN_StopAllSequences ();
DThinker::DestroyAllThinkers ();
tagManager.Clear();

View file

@ -46,12 +46,12 @@ class DRotatePoly : public DPolyAction
{
DECLARE_CLASS (DRotatePoly, DPolyAction)
public:
DRotatePoly (int polyNum);
DRotatePoly (FPolyObj *polyNum);
void Tick ();
private:
DRotatePoly ();
friend bool EV_RotatePoly (line_t *line, int polyNum, int speed, int byteAngle, int direction, bool overRide);
friend bool EV_RotatePoly (FLevelLocals *Level, line_t *line, int polyNum, int speed, int byteAngle, int direction, bool overRide);
};
@ -59,7 +59,7 @@ class DMovePoly : public DPolyAction
{
DECLARE_CLASS (DMovePoly, DPolyAction)
public:
DMovePoly (int polyNum);
DMovePoly (FPolyObj *polyNum);
void Serialize(FSerializer &arc);
void Tick ();
protected:
@ -67,14 +67,14 @@ protected:
DAngle m_Angle;
DVector2 m_Speedv;
friend bool EV_MovePoly(line_t *line, int polyNum, double speed, DAngle angle, double dist, bool overRide);
friend bool EV_MovePoly(FLevelLocals *Level, line_t *line, int polyNum, double speed, DAngle angle, double dist, bool overRide);
};
class DMovePolyTo : public DPolyAction
{
DECLARE_CLASS(DMovePolyTo, DPolyAction)
public:
DMovePolyTo(int polyNum);
DMovePolyTo(FPolyObj *polyNum);
void Serialize(FSerializer &arc);
void Tick();
protected:
@ -82,7 +82,7 @@ protected:
DVector2 m_Speedv;
DVector2 m_Target;
friend bool EV_MovePolyTo(line_t *line, int polyNum, double speed, const DVector2 &pos, bool overRide);
friend bool EV_MovePolyTo(FLevelLocals *Level, line_t *line, int polyNum, double speed, const DVector2 &pos, bool overRide);
};
@ -90,7 +90,7 @@ class DPolyDoor : public DMovePoly
{
DECLARE_CLASS (DPolyDoor, DMovePoly)
public:
DPolyDoor (int polyNum, podoortype_t type);
DPolyDoor (FPolyObj *polyNum, podoortype_t type);
void Serialize(FSerializer &arc);
void Tick ();
protected:
@ -101,7 +101,7 @@ protected:
podoortype_t m_Type;
bool m_Close;
friend bool EV_OpenPolyDoor(line_t *line, int polyNum, double speed, DAngle angle, int delay, double distance, podoortype_t type);
friend bool EV_OpenPolyDoor(FLevelLocals *Level, line_t *line, int polyNum, double speed, DAngle angle, int delay, double distance, podoortype_t type);
private:
DPolyDoor ();
};
@ -165,7 +165,7 @@ void DPolyAction::Serialize(FSerializer &arc)
("interpolation", m_Interpolation);
}
DPolyAction::DPolyAction (int polyNum)
DPolyAction::DPolyAction (FPolyObj *polyNum)
{
m_PolyObj = polyNum;
m_Speed = 0;
@ -175,11 +175,9 @@ DPolyAction::DPolyAction (int polyNum)
void DPolyAction::OnDestroy()
{
FPolyObj *poly = PO_GetPolyobj (m_PolyObj);
if (poly->specialdata == this)
if (m_PolyObj->specialdata == this)
{
poly->specialdata = NULL;
m_PolyObj->specialdata = nullptr;
}
StopInterpolation();
@ -188,23 +186,21 @@ void DPolyAction::OnDestroy()
void DPolyAction::Stop()
{
FPolyObj *poly = PO_GetPolyobj(m_PolyObj);
SN_StopSequence(poly);
SN_StopSequence(m_PolyObj);
Destroy();
}
void DPolyAction::SetInterpolation ()
{
FPolyObj *poly = PO_GetPolyobj (m_PolyObj);
m_Interpolation = poly->SetInterpolation();
m_Interpolation = m_PolyObj->SetInterpolation();
}
void DPolyAction::StopInterpolation ()
{
if (m_Interpolation != NULL)
if (m_Interpolation != nullptr)
{
m_Interpolation->DelRef();
m_Interpolation = NULL;
m_Interpolation = nullptr;
}
}
@ -220,7 +216,7 @@ DRotatePoly::DRotatePoly ()
{
}
DRotatePoly::DRotatePoly (int polyNum)
DRotatePoly::DRotatePoly (FPolyObj *polyNum)
: Super (polyNum)
{
}
@ -244,7 +240,7 @@ void DMovePoly::Serialize(FSerializer &arc)
("speedv", m_Speedv);
}
DMovePoly::DMovePoly (int polyNum)
DMovePoly::DMovePoly (FPolyObj *polyNum)
: Super (polyNum)
{
m_Angle = 0.;
@ -271,7 +267,7 @@ void DMovePolyTo::Serialize(FSerializer &arc)
("target", m_Target);
}
DMovePolyTo::DMovePolyTo(int polyNum)
DMovePolyTo::DMovePolyTo(FPolyObj *polyNum)
: Super(polyNum)
{
m_Speedv = m_Target = { 0,0 };
@ -300,7 +296,7 @@ void DPolyDoor::Serialize(FSerializer &arc)
("close", m_Close);
}
DPolyDoor::DPolyDoor (int polyNum, podoortype_t type)
DPolyDoor::DPolyDoor (FPolyObj * polyNum, podoortype_t type)
: Super (polyNum), m_Type (type)
{
m_Direction = 0.;
@ -320,8 +316,7 @@ DPolyDoor::DPolyDoor (int polyNum, podoortype_t type)
void DRotatePoly::Tick ()
{
FPolyObj *poly = PO_GetPolyobj (m_PolyObj);
if (poly == NULL) return;
if (m_PolyObj == nullptr) return;
// Don't let non-perpetual polyobjs overshoot their targets.
if (m_Dist != -1 && m_Dist < fabs(m_Speed))
@ -329,7 +324,7 @@ void DRotatePoly::Tick ()
m_Speed = m_Speed < 0 ? -m_Dist : m_Dist;
}
if (poly->RotatePolyobj (m_Speed))
if (m_PolyObj->RotatePolyobj (m_Speed))
{
if (m_Dist == -1)
{ // perpetual polyobj
@ -338,7 +333,7 @@ void DRotatePoly::Tick ()
m_Dist -= fabs(m_Speed);
if (m_Dist == 0)
{
SN_StopSequence (poly);
SN_StopSequence (m_PolyObj);
Destroy ();
}
}
@ -351,22 +346,21 @@ void DRotatePoly::Tick ()
//==========================================================================
bool EV_RotatePoly (line_t *line, int polyNum, int speed, int byteAngle,
int direction, bool overRide)
bool EV_RotatePoly (FLevelLocals *Level, line_t *line, int polyNum, int speed, int byteAngle, int direction, bool overRide)
{
DRotatePoly *pe = NULL;
DRotatePoly *pe = nullptr;
FPolyObj *poly;
if ((poly = PO_GetPolyobj(polyNum)) == NULL)
if ((poly = Level->GetPolyobj(polyNum)) == nullptr)
{
Printf("EV_RotatePoly: Invalid polyobj num: %d\n", polyNum);
return false;
}
FPolyMirrorIterator it(poly);
while ((poly = it.NextMirror()) != NULL)
while ((poly = it.NextMirror()) != nullptr)
{
if ((poly->specialdata != NULL || poly->bBlocked) && !overRide)
if ((poly->specialdata != nullptr || poly->bBlocked) && !overRide)
{ // poly is already in motion
break;
}
@ -375,7 +369,7 @@ bool EV_RotatePoly (line_t *line, int polyNum, int speed, int byteAngle,
// cannot do rotations on linked polyportals.
break;
}
pe = Create<DRotatePoly>(poly->tag);
pe = Create<DRotatePoly>(poly);
poly->specialdata = pe;
poly->bBlocked = false;
if (byteAngle != 0)
@ -397,7 +391,7 @@ bool EV_RotatePoly (line_t *line, int polyNum, int speed, int byteAngle,
SN_StartSequence (poly, poly->seqType, SEQ_DOOR, 0);
direction = -direction; // Reverse the direction
}
return pe != NULL; // Return true if something started moving.
return pe != nullptr; // Return true if something started moving.
}
//==========================================================================
@ -408,17 +402,15 @@ bool EV_RotatePoly (line_t *line, int polyNum, int speed, int byteAngle,
void DMovePoly::Tick ()
{
FPolyObj *poly = PO_GetPolyobj (m_PolyObj);
if (poly != NULL)
if (m_PolyObj != nullptr)
{
if (poly->MovePolyobj (m_Speedv))
if (m_PolyObj->MovePolyobj (m_Speedv))
{
double absSpeed = fabs (m_Speed);
m_Dist -= absSpeed;
if (m_Dist <= 0)
{
SN_StopSequence (poly);
SN_StopSequence (m_PolyObj);
Destroy ();
}
else if (m_Dist < absSpeed)
@ -426,7 +418,7 @@ void DMovePoly::Tick ()
m_Speed = m_Dist * (m_Speed < 0 ? -1 : 1);
m_Speedv = m_Angle.ToVector(m_Speed);
}
poly->UpdateLinks();
m_PolyObj->UpdateLinks();
}
}
}
@ -437,27 +429,26 @@ void DMovePoly::Tick ()
//
//==========================================================================
bool EV_MovePoly (line_t *line, int polyNum, double speed, DAngle angle,
double dist, bool overRide)
bool EV_MovePoly (FLevelLocals *Level, line_t *line, int polyNum, double speed, DAngle angle, double dist, bool overRide)
{
DMovePoly *pe = NULL;
DMovePoly *pe = nullptr;
FPolyObj *poly;
DAngle an = angle;
if ((poly = PO_GetPolyobj(polyNum)) == NULL)
if ((poly = Level->GetPolyobj(polyNum)) == nullptr)
{
Printf("EV_MovePoly: Invalid polyobj num: %d\n", polyNum);
return false;
}
FPolyMirrorIterator it(poly);
while ((poly = it.NextMirror()) != NULL)
while ((poly = it.NextMirror()) != nullptr)
{
if ((poly->specialdata != NULL || poly->bBlocked) && !overRide)
if ((poly->specialdata != nullptr || poly->bBlocked) && !overRide)
{ // poly is already in motion
break;
}
pe = Create<DMovePoly>(poly->tag);
pe = Create<DMovePoly>(poly);
poly->specialdata = pe;
poly->bBlocked = false;
pe->m_Dist = dist; // Distance
@ -477,7 +468,7 @@ bool EV_MovePoly (line_t *line, int polyNum, double speed, DAngle angle,
angle += 180.; // Reverse the angle.
}
return pe != NULL; // Return true if something started moving.
return pe != nullptr; // Return true if something started moving.
}
//==========================================================================
@ -488,25 +479,23 @@ bool EV_MovePoly (line_t *line, int polyNum, double speed, DAngle angle,
void DMovePolyTo::Tick ()
{
FPolyObj *poly = PO_GetPolyobj (m_PolyObj);
if (poly != NULL)
if (m_PolyObj != nullptr)
{
if (poly->MovePolyobj (m_Speedv))
if (m_PolyObj->MovePolyobj (m_Speedv))
{
double absSpeed = fabs (m_Speed);
m_Dist -= absSpeed;
if (m_Dist <= 0)
{
SN_StopSequence (poly);
SN_StopSequence (m_PolyObj);
Destroy ();
}
else if (m_Dist < absSpeed)
{
m_Speed = m_Dist * (m_Speed < 0 ? -1 : 1);
m_Speedv = m_Target - poly->StartSpot.pos;
m_Speedv = m_Target - m_PolyObj->StartSpot.pos;
}
poly->UpdateLinks();
m_PolyObj->UpdateLinks();
}
}
}
@ -517,14 +506,14 @@ void DMovePolyTo::Tick ()
//
//==========================================================================
bool EV_MovePolyTo(line_t *line, int polyNum, double speed, const DVector2 &targ, bool overRide)
bool EV_MovePolyTo(FLevelLocals *Level, line_t *line, int polyNum, double speed, const DVector2 &targ, bool overRide)
{
DMovePolyTo *pe = NULL;
DMovePolyTo *pe = nullptr;
FPolyObj *poly;
DVector2 dist;
double distlen;
if ((poly = PO_GetPolyobj(polyNum)) == NULL)
if ((poly = Level->GetPolyobj(polyNum)) == nullptr)
{
Printf("EV_MovePolyTo: Invalid polyobj num: %d\n", polyNum);
return false;
@ -533,13 +522,13 @@ bool EV_MovePolyTo(line_t *line, int polyNum, double speed, const DVector2 &targ
dist = targ - poly->StartSpot.pos;
distlen = dist.MakeUnit();
while ((poly = it.NextMirror()) != NULL)
while ((poly = it.NextMirror()) != nullptr)
{
if ((poly->specialdata != NULL || poly->bBlocked) && !overRide)
if ((poly->specialdata != nullptr || poly->bBlocked) && !overRide)
{ // poly is already in motion
break;
}
pe = Create<DMovePolyTo>(poly->tag);
pe = Create<DMovePolyTo>(poly);
poly->specialdata = pe;
poly->bBlocked = false;
pe->m_Dist = distlen;
@ -552,7 +541,7 @@ bool EV_MovePolyTo(line_t *line, int polyNum, double speed, const DVector2 &targ
}
dist = -dist; // reverse the direction
}
return pe != NULL; // Return true if something started moving.
return pe != nullptr; // Return true if something started moving.
}
//==========================================================================
@ -563,28 +552,26 @@ bool EV_MovePolyTo(line_t *line, int polyNum, double speed, const DVector2 &targ
void DPolyDoor::Tick ()
{
FPolyObj *poly = PO_GetPolyobj (m_PolyObj);
if (poly == NULL) return;
if (m_PolyObj == nullptr) return;
if (m_Tics)
{
if (!--m_Tics)
{
SN_StartSequence (poly, poly->seqType, SEQ_DOOR, m_Close);
SN_StartSequence (m_PolyObj, m_PolyObj->seqType, SEQ_DOOR, m_Close);
}
return;
}
switch (m_Type)
{
case PODOOR_SLIDE:
if (m_Dist <= 0 || poly->MovePolyobj (m_Speedv))
if (m_Dist <= 0 || m_PolyObj->MovePolyobj (m_Speedv))
{
double absSpeed = fabs (m_Speed);
m_Dist -= absSpeed;
if (m_Dist <= 0)
{
SN_StopSequence (poly);
SN_StopSequence (m_PolyObj);
if (!m_Close && m_WaitTics >= 0)
{
m_Dist = m_TotalDist;
@ -597,15 +584,15 @@ void DPolyDoor::Tick ()
{
// if set to wait infinitely, Hexen kept the dead thinker to block the polyobject from getting activated again but that causes some problems
// with the subsectorlinks and the interpolation. Better delete the thinker and use a different means to block it.
if (!m_Close) poly->bBlocked = true;
if (!m_Close) m_PolyObj->bBlocked = true;
Destroy ();
}
}
poly->UpdateLinks();
m_PolyObj->UpdateLinks();
}
else
{
if (poly->crush || !m_Close)
if (m_PolyObj->crush || !m_Close)
{ // continue moving if the poly is a crusher, or is opening
return;
}
@ -615,19 +602,19 @@ void DPolyDoor::Tick ()
m_Direction = -m_Direction;
m_Speedv = -m_Speedv;
m_Close = false;
SN_StartSequence (poly, poly->seqType, SEQ_DOOR, 0);
SN_StartSequence (m_PolyObj, m_PolyObj->seqType, SEQ_DOOR, 0);
}
}
break;
case PODOOR_SWING:
if (m_Dist <= 0 || poly->RotatePolyobj (m_Speed))
if (m_Dist <= 0 || m_PolyObj->RotatePolyobj (m_Speed))
{
double absSpeed = fabs (m_Speed);
m_Dist -= absSpeed;
if (m_Dist <= 0)
{
SN_StopSequence (poly);
SN_StopSequence (m_PolyObj);
if (!m_Close && m_WaitTics >= 0)
{
m_Dist = m_TotalDist;
@ -637,14 +624,14 @@ void DPolyDoor::Tick ()
}
else
{
if (!m_Close) poly->bBlocked = true;
if (!m_Close) m_PolyObj->bBlocked = true;
Destroy ();
}
}
}
else
{
if(poly->crush || !m_Close)
if(m_PolyObj->crush || !m_Close)
{ // continue moving if the poly is a crusher, or is opening
return;
}
@ -653,7 +640,7 @@ void DPolyDoor::Tick ()
m_Dist = m_TotalDist - m_Dist;
m_Speed = -m_Speed;
m_Close = false;
SN_StartSequence (poly, poly->seqType, SEQ_DOOR, 0);
SN_StartSequence (m_PolyObj, m_PolyObj->seqType, SEQ_DOOR, 0);
}
}
break;
@ -669,22 +656,22 @@ void DPolyDoor::Tick ()
//
//==========================================================================
bool EV_OpenPolyDoor(line_t *line, int polyNum, double speed, DAngle angle, int delay, double distance, podoortype_t type)
bool EV_OpenPolyDoor(FLevelLocals *Level, line_t *line, int polyNum, double speed, DAngle angle, int delay, double distance, podoortype_t type)
{
DPolyDoor *pd = NULL;
DPolyDoor *pd = nullptr;
FPolyObj *poly;
int swingdir = 1; // ADD: PODOOR_SWINGL, PODOOR_SWINGR
if ((poly = PO_GetPolyobj(polyNum)) == NULL)
if ((poly = Level->GetPolyobj(polyNum)) == nullptr)
{
Printf("EV_OpenPolyDoor: Invalid polyobj num: %d\n", polyNum);
return false;
}
FPolyMirrorIterator it(poly);
while ((poly = it.NextMirror()) != NULL)
while ((poly = it.NextMirror()) != nullptr)
{
if ((poly->specialdata != NULL || poly->bBlocked))
if ((poly->specialdata != nullptr || poly->bBlocked))
{ // poly is already moving
break;
}
@ -694,7 +681,7 @@ bool EV_OpenPolyDoor(line_t *line, int polyNum, double speed, DAngle angle, int
break;
}
pd = Create<DPolyDoor>(poly->tag, type);
pd = Create<DPolyDoor>(poly, type);
poly->specialdata = pd;
if (type == PODOOR_SLIDE)
{
@ -717,7 +704,7 @@ bool EV_OpenPolyDoor(line_t *line, int polyNum, double speed, DAngle angle, int
}
}
return pd != NULL; // Return true if something started moving.
return pd != nullptr; // Return true if something started moving.
}
//==========================================================================
@ -726,13 +713,13 @@ bool EV_OpenPolyDoor(line_t *line, int polyNum, double speed, DAngle angle, int
//
//==========================================================================
bool EV_StopPoly(int polynum)
bool EV_StopPoly(FLevelLocals *Level, int polynum)
{
FPolyObj *poly;
if (NULL != (poly = PO_GetPolyobj(polynum)))
if (nullptr != (poly = Level->GetPolyobj(polynum)))
{
if (poly->specialdata != NULL)
if (poly->specialdata != nullptr)
{
poly->specialdata->Stop();
}
@ -743,23 +730,6 @@ bool EV_StopPoly(int polynum)
// ===== Higher Level Poly Interface code =====
//==========================================================================
//
// PO_GetPolyobj
//
//==========================================================================
FPolyObj *PO_GetPolyobj (int polyNum)
{
for(auto &poly : level.Polyobjects)
{
if (poly.tag == polyNum)
{
return &poly;
}
}
return nullptr;
}
//==========================================================================
@ -780,9 +750,9 @@ FPolyObj::FPolyObj()
seqType = 0;
Size = 0;
bBlocked = false;
subsectorlinks = NULL;
specialdata = NULL;
interpolation = NULL;
subsectorlinks = nullptr;
specialdata = nullptr;
interpolation = nullptr;
}
//==========================================================================
@ -796,6 +766,11 @@ int FPolyObj::GetMirror()
return MirrorNum;
}
FLevelLocals *FPolyObj::GetLevel() const
{
return &level;
}
//==========================================================================
//
// ThrustMobj
@ -806,6 +781,7 @@ void FPolyObj::ThrustMobj (AActor *actor, side_t *side)
{
DAngle thrustAngle;
DPolyAction *pe;
auto Level = GetLevel();
double force;
@ -843,11 +819,11 @@ void FPolyObj::ThrustMobj (AActor *actor, side_t *side)
DVector2 pos = actor->Vec2Offset(thrust.X, thrust.Y);
if (bHurtOnTouch || !P_CheckMove (actor, pos))
{
int newdam = P_DamageMobj (actor, NULL, NULL, crush, NAME_Crush);
int newdam = P_DamageMobj (actor, nullptr, nullptr, crush, NAME_Crush);
P_TraceBleed (newdam > 0 ? newdam : crush, actor);
}
}
if (level.flags2 & LEVEL2_POLYGRIND) actor->CallGrind(false); // crush corpses that get caught in a polyobject's way
if (Level->flags2 & LEVEL2_POLYGRIND) actor->CallGrind(false); // crush corpses that get caught in a polyobject's way
}
//==========================================================================
@ -860,6 +836,7 @@ void FPolyObj::UpdateLinks()
{
if (bHasPortals == 2)
{
auto Level = GetLevel();
TMap<int, bool> processed;
for (unsigned i = 0; i < Linedefs.Size(); i++)
{
@ -878,7 +855,7 @@ void FPolyObj::UpdateLinks()
{
processed[destgroup] = true;
DVector2 delta = port->mDisplacement - old;
level.Displacements.MoveGroup(destgroup, delta);
Level->Displacements.MoveGroup(destgroup, delta);
}
}
}
@ -1048,25 +1025,26 @@ void FPolyObj::UnLinkPolyobj ()
polyblock_t *link;
int i, j;
int index;
auto Level = GetLevel();
// remove the polyobj from each blockmap section
for(j = bbox[BOXBOTTOM]; j <= bbox[BOXTOP]; j++)
{
index = j*level.blockmap.bmapwidth;
index = j*Level->blockmap.bmapwidth;
for(i = bbox[BOXLEFT]; i <= bbox[BOXRIGHT]; i++)
{
if(i >= 0 && i < level.blockmap.bmapwidth && j >= 0 && j < level.blockmap.bmapheight)
if(i >= 0 && i < Level->blockmap.bmapwidth && j >= 0 && j < Level->blockmap.bmapheight)
{
link = level.PolyBlockMap[index+i];
while(link != NULL && link->polyobj != this)
link = Level->PolyBlockMap[index+i];
while(link != nullptr && link->polyobj != this)
{
link = link->next;
}
if(link == NULL)
if(link == nullptr)
{ // polyobj not located in the link cell
continue;
}
link->polyobj = NULL;
link->polyobj = nullptr;
}
}
}
@ -1080,6 +1058,7 @@ void FPolyObj::UnLinkPolyobj ()
bool FPolyObj::CheckMobjBlocking (side_t *sd)
{
auto Level = GetLevel();
static TArray<AActor *> checker;
FBlockNode *block;
AActor *mobj;
@ -1088,15 +1067,15 @@ bool FPolyObj::CheckMobjBlocking (side_t *sd)
line_t *ld;
bool blocked;
bool performBlockingThrust;
int bmapwidth = level.blockmap.bmapwidth;
int bmapheight = level.blockmap.bmapheight;
int bmapwidth = Level->blockmap.bmapwidth;
int bmapheight = Level->blockmap.bmapheight;
ld = sd->linedef;
top = level.blockmap.GetBlockY(ld->bbox[BOXTOP]);
bottom = level.blockmap.GetBlockY(ld->bbox[BOXBOTTOM]);
left = level.blockmap.GetBlockX(ld->bbox[BOXLEFT]);
right = level.blockmap.GetBlockX(ld->bbox[BOXRIGHT]);
top = Level->blockmap.GetBlockY(ld->bbox[BOXTOP]);
bottom = Level->blockmap.GetBlockY(ld->bbox[BOXBOTTOM]);
left = Level->blockmap.GetBlockX(ld->bbox[BOXLEFT]);
right = Level->blockmap.GetBlockX(ld->bbox[BOXRIGHT]);
blocked = false;
checker.Clear();
@ -1114,7 +1093,7 @@ bool FPolyObj::CheckMobjBlocking (side_t *sd)
{
for (i = left; i <= right; i++)
{
for (block = level.blockmap.blocklinks[j+i]; block != NULL; block = block->NextActor)
for (block = Level->blockmap.blocklinks[j+i]; block != nullptr; block = block->NextActor)
{
mobj = block->Me;
for (k = (int)checker.Size()-1; k >= 0; --k)
@ -1133,7 +1112,7 @@ bool FPolyObj::CheckMobjBlocking (side_t *sd)
open.top = LINEOPEN_MAX;
open.bottom = LINEOPEN_MIN;
// [TN] Check wether this actor gets blocked by the line.
if (ld->backsector != NULL &&
if (ld->backsector != nullptr &&
!(ld->flags & (ML_BLOCKING|ML_BLOCKEVERYTHING))
&& !(ld->flags & ML_BLOCK_PLAYERS && (mobj->player || (mobj->flags8 & MF8_BLOCKASPLAYER)))
&& !(ld->flags & ML_BLOCKMONSTERS && mobj->flags3 & MF3_ISMONSTER)
@ -1173,7 +1152,7 @@ bool FPolyObj::CheckMobjBlocking (side_t *sd)
// We have a two-sided linedef so we should only check one side
// so that the thrust from both sides doesn't cancel each other out.
// Best use the one facing the player and ignore the back side.
if (ld->sidedef[1] != NULL)
if (ld->sidedef[1] != nullptr)
{
int side = P_PointOnLineSidePrecise(mobj->Pos(), ld);
if (ld->sidedef[side] != sd)
@ -1215,8 +1194,9 @@ void FPolyObj::LinkPolyobj ()
{
polyblock_t **link;
polyblock_t *tempLink;
int bmapwidth = level.blockmap.bmapwidth;
int bmapheight = level.blockmap.bmapheight;
auto Level = GetLevel();
int bmapwidth = Level->blockmap.bmapwidth;
int bmapheight = Level->blockmap.bmapheight;
// calculate the polyobj bbox
Bounds.ClearBox();
@ -1229,10 +1209,10 @@ void FPolyObj::LinkPolyobj ()
vt = Sidedefs[i]->linedef->v2;
Bounds.AddToBox(vt->fPos());
}
bbox[BOXRIGHT] = level.blockmap.GetBlockX(Bounds.Right());
bbox[BOXLEFT] = level.blockmap.GetBlockX(Bounds.Left());
bbox[BOXTOP] = level.blockmap.GetBlockY(Bounds.Top());
bbox[BOXBOTTOM] = level.blockmap.GetBlockY(Bounds.Bottom());
bbox[BOXRIGHT] = Level->blockmap.GetBlockX(Bounds.Right());
bbox[BOXLEFT] = Level->blockmap.GetBlockX(Bounds.Left());
bbox[BOXTOP] = Level->blockmap.GetBlockY(Bounds.Top());
bbox[BOXBOTTOM] = Level->blockmap.GetBlockY(Bounds.Bottom());
// add the polyobj to each blockmap section
for(int j = bbox[BOXBOTTOM]*bmapwidth; j <= bbox[BOXTOP]*bmapwidth;
j += bmapwidth)
@ -1241,24 +1221,24 @@ void FPolyObj::LinkPolyobj ()
{
if(i >= 0 && i < bmapwidth && j >= 0 && j < bmapheight*bmapwidth)
{
link = &level.PolyBlockMap[j+i];
link = &Level->PolyBlockMap[j+i];
if(!(*link))
{ // Create a new link at the current block cell
*link = new polyblock_t;
(*link)->next = NULL;
(*link)->prev = NULL;
(*link)->next = nullptr;
(*link)->prev = nullptr;
(*link)->polyobj = this;
continue;
}
else
{
tempLink = *link;
while(tempLink->next != NULL && tempLink->polyobj != NULL)
while(tempLink->next != nullptr && tempLink->polyobj != nullptr)
{
tempLink = tempLink->next;
}
}
if(tempLink->polyobj == NULL)
if(tempLink->polyobj == nullptr)
{
tempLink->polyobj = this;
continue;
@ -1266,7 +1246,7 @@ void FPolyObj::LinkPolyobj ()
else
{
tempLink->next = new polyblock_t;
tempLink->next->next = NULL;
tempLink->next->next = nullptr;
tempLink->next->prev = tempLink;
tempLink->next->polyobj = this;
}
@ -1290,7 +1270,7 @@ void FPolyObj::RecalcActorFloorCeil(FBoundingBox bounds) const
FBlockThingsIterator it(bounds);
AActor *actor;
while ((actor = it.Next()) != NULL)
while ((actor = it.Next()) != nullptr)
{
// skip everything outside the bounding box.
if (actor->X() + actor->radius <= bounds.Left() ||
@ -1322,7 +1302,7 @@ void FPolyObj::ClosestPoint(const DVector2 &fpos, DVector2 &out, side_t **side)
double x = fpos.X, y = fpos.Y;
double bestdist = HUGE_VAL;
double bestx = 0, besty = 0;
side_t *bestline = NULL;
side_t *bestline = nullptr;
for (i = 0; i < Sidedefs.Size(); ++i)
{
@ -1370,7 +1350,7 @@ void FPolyObj::ClosestPoint(const DVector2 &fpos, DVector2 &out, side_t **side)
}
}
out = { bestx, besty };
if (side != NULL)
if (side != nullptr)
{
*side = bestline;
}
@ -1382,12 +1362,12 @@ void FPolyObj::ClosestPoint(const DVector2 &fpos, DVector2 &out, side_t **side)
//
//==========================================================================
bool PO_Busy (int polyobj)
bool PO_Busy (FLevelLocals *Level, int polyobj)
{
FPolyObj *poly;
poly = PO_GetPolyobj (polyobj);
return (poly != NULL && poly->specialdata != NULL);
poly = Level->GetPolyobj(polyobj);
return (poly != nullptr && poly->specialdata != nullptr);
}
@ -1400,19 +1380,19 @@ bool PO_Busy (int polyobj)
void FPolyObj::ClearSubsectorLinks()
{
while (subsectorlinks != NULL)
while (subsectorlinks != nullptr)
{
assert(subsectorlinks->state == 1337);
FPolyNode *next = subsectorlinks->snext;
if (subsectorlinks->pnext != NULL)
if (subsectorlinks->pnext != nullptr)
{
assert(subsectorlinks->pnext->state == 1337);
subsectorlinks->pnext->pprev = subsectorlinks->pprev;
}
if (subsectorlinks->pprev != NULL)
if (subsectorlinks->pprev != nullptr)
{
assert(subsectorlinks->pprev->state == 1337);
subsectorlinks->pprev->pnext = subsectorlinks->pnext;
@ -1422,7 +1402,7 @@ void FPolyObj::ClearSubsectorLinks()
subsectorlinks->subsector->polys = subsectorlinks->pnext;
}
if (subsectorlinks->subsector->BSP != NULL)
if (subsectorlinks->subsector->BSP != nullptr)
{
subsectorlinks->subsector->BSP->bDirty = true;
}
@ -1431,12 +1411,12 @@ void FPolyObj::ClearSubsectorLinks()
delete subsectorlinks;
subsectorlinks = next;
}
subsectorlinks = NULL;
subsectorlinks = nullptr;
}
void FPolyObj::ClearAllSubsectorLinks()
void FLevelLocals::ClearAllSubsectorLinks()
{
for(auto &poly : level.Polyobjects)
for(auto &poly : Polyobjects)
{
poly.ClearSubsectorLinks();
}
@ -1676,12 +1656,12 @@ static void SplitPoly(FPolyNode *pnode, void *node, float bbox[4])
// Link node to subsector
pnode->pnext = sub->polys;
if (pnode->pnext != NULL)
if (pnode->pnext != nullptr)
{
assert(pnode->pnext->state == 1337);
pnode->pnext->pprev = pnode;
}
pnode->pprev = NULL;
pnode->pprev = nullptr;
sub->polys = pnode;
// link node to polyobject
@ -1711,6 +1691,7 @@ static void SplitPoly(FPolyNode *pnode, void *node, float bbox[4])
void FPolyObj::CreateSubsectorLinks()
{
auto Level = GetLevel();
FPolyNode *node = NewPolyNode();
// Even though we don't care about it, we need to initialize this
// bounding box to something so that Valgrind won't complain about it
@ -1731,7 +1712,7 @@ void FPolyObj::CreateSubsectorLinks()
}
if (!(i_compatflags & COMPATF_POLYOBJ))
{
SplitPoly(node, level.HeadNode(), dummybbox);
SplitPoly(node, Level->HeadNode(), dummybbox);
}
else
{
@ -1739,12 +1720,12 @@ void FPolyObj::CreateSubsectorLinks()
// Link node to subsector
node->pnext = sub->polys;
if (node->pnext != NULL)
if (node->pnext != nullptr)
{
assert(node->pnext->state == 1337);
node->pnext->pprev = node;
}
node->pprev = NULL;
node->pprev = nullptr;
sub->polys = node;
// link node to polyobject
@ -1760,9 +1741,9 @@ void FPolyObj::CreateSubsectorLinks()
//
//==========================================================================
void PO_LinkToSubsectors()
void PO_LinkToSubsectors(FLevelLocals *Level)
{
for(auto &poly : level.Polyobjects)
for(auto &poly : Level->Polyobjects)
{
if (poly.subsectorlinks == nullptr)
{
@ -1781,7 +1762,7 @@ static FPolyNode *NewPolyNode()
{
FPolyNode *node;
if (FreePolyNodes != NULL)
if (FreePolyNodes != nullptr)
{
node = FreePolyNodes;
FreePolyNodes = node->pnext;
@ -1791,11 +1772,11 @@ static FPolyNode *NewPolyNode()
node = new FPolyNode;
}
node->state = 1337;
node->poly = NULL;
node->pnext = NULL;
node->pprev = NULL;
node->subsector = NULL;
node->snext = NULL;
node->poly = nullptr;
node->pnext = nullptr;
node->pprev = nullptr;
node->subsector = nullptr;
node->snext = nullptr;
return node;
}
@ -1822,7 +1803,7 @@ void ReleaseAllPolyNodes()
{
FPolyNode *node, *next;
for (node = FreePolyNodes; node != NULL; node = next)
for (node = FreePolyNodes; node != nullptr; node = next)
{
next = node->pnext;
delete node;
@ -1841,7 +1822,7 @@ void ReleaseAllPolyNodes()
FPolyMirrorIterator::FPolyMirrorIterator(FPolyObj *poly)
{
CurPoly = poly;
if (poly != NULL)
if (poly != nullptr)
{
UsedPolys[0] = poly->tag;
NumUsedPolys = 1;
@ -1856,7 +1837,7 @@ FPolyMirrorIterator::FPolyMirrorIterator(FPolyObj *poly)
//
// FPolyMirrorIterator :: NextMirror
//
// Returns the polyobject that mirrors the current one, or NULL if there
// Returns the polyobject that mirrors the current one, or nullptr if there
// is no mirroring polyobject, or there is a mirroring polyobject but it was
// already returned.
//
@ -1866,15 +1847,15 @@ FPolyObj *FPolyMirrorIterator::NextMirror()
{
FPolyObj *poly = CurPoly, *nextpoly;
if (poly == NULL)
if (poly == nullptr)
{
return NULL;
return nullptr;
}
// Do the work to decide which polyobject to return the next time this
// function is called.
int mirror = poly->GetMirror(), i;
nextpoly = NULL;
nextpoly = nullptr;
// Is there a mirror and we have room to remember it?
if (mirror != 0 && NumUsedPolys != countof(UsedPolys))
@ -1890,8 +1871,8 @@ FPolyObj *FPolyMirrorIterator::NextMirror()
if (i == NumUsedPolys)
{ // No, it has not been returned.
UsedPolys[NumUsedPolys++] = mirror;
nextpoly = PO_GetPolyobj(mirror);
if (nextpoly == NULL)
nextpoly = poly->GetLevel()->GetPolyobj(mirror);
if (nextpoly == nullptr)
{
Printf("Invalid mirror polyobj num %d for polyobj num %d\n", mirror, UsedPolys[i - 1]);
}

View file

@ -6,12 +6,14 @@
#include "m_bbox.h"
#include "dthinker.h"
struct FPolyObj;
class DPolyAction : public DThinker
{
DECLARE_CLASS(DPolyAction, DThinker)
HAS_OBJECT_POINTERS
public:
DPolyAction(int polyNum);
DPolyAction(FPolyObj *polyNum);
void Serialize(FSerializer &arc);
void OnDestroy() override;
void Stop();
@ -20,7 +22,7 @@ public:
void StopInterpolation();
protected:
DPolyAction();
int m_PolyObj;
FPolyObj *m_PolyObj;
double m_Speed;
double m_Dist;
TObjPtr<DInterpolation*> m_Interpolation;
@ -107,6 +109,9 @@ struct FPolyObj
void UpdateLinks();
static void ClearAllSubsectorLinks();
FLevelLocals *GetLevel() const;
private:
void ThrustMobj (AActor *actor, side_t *side);
@ -125,7 +130,7 @@ struct polyblock_t
};
void PO_LinkToSubsectors();
void PO_LinkToSubsectors(FLevelLocals *Level);
// ===== PO_MAN =====
@ -137,14 +142,13 @@ typedef enum
PODOOR_SWING,
} podoortype_t;
bool EV_RotatePoly (line_t *line, int polyNum, int speed, int byteAngle, int direction, bool overRide);
bool EV_MovePoly (line_t *line, int polyNum, double speed, DAngle angle, double dist, bool overRide);
bool EV_MovePolyTo (line_t *line, int polyNum, double speed, const DVector2 &pos, bool overRide);
bool EV_OpenPolyDoor (line_t *line, int polyNum, double speed, DAngle angle, int delay, double distance, podoortype_t type);
bool EV_StopPoly (int polyNum);
bool EV_RotatePoly (FLevelLocals *Level, line_t *line, int polyNum, int speed, int byteAngle, int direction, bool overRide);
bool EV_MovePoly (FLevelLocals *Level, line_t *line, int polyNum, double speed, DAngle angle, double dist, bool overRide);
bool EV_MovePolyTo (FLevelLocals *Level, line_t *line, int polyNum, double speed, const DVector2 &pos, bool overRide);
bool EV_OpenPolyDoor (FLevelLocals *Level, line_t *line, int polyNum, double speed, DAngle angle, int delay, double distance, podoortype_t type);
bool EV_StopPoly (FLevelLocals *Level, int polyNum);
bool PO_Busy (int polyobj);
FPolyObj *PO_GetPolyobj(int polyNum);
bool PO_Busy (FLevelLocals *Level, int polyobj);
#endif
#endif

View file

@ -134,7 +134,7 @@ void PolyRenderer::RenderActorView(AActor *actor, bool dontmaplines)
R_SetupFrame(Viewpoint, Viewwindow, actor);
P_FindParticleSubsectors();
PO_LinkToSubsectors();
PO_LinkToSubsectors(&level);
static bool firstcall = true;
if (firstcall)

View file

@ -163,7 +163,7 @@ namespace swrenderer
P_FindParticleSubsectors();
// Link the polyobjects right before drawing the scene to reduce the amounts of calls to this function
PO_LinkToSubsectors();
PO_LinkToSubsectors(&level);
R_UpdateFuzzPosFrameStart();