From e7978a77dd0c859d8d7138194d915897878d8f3b Mon Sep 17 00:00:00 2001 From: Marisa the Magician Date: Fri, 5 Aug 2022 21:37:20 +0200 Subject: [PATCH] Re-save ZPolyobject files with unix line endings. --- language.version | 4 +- .../swwm_Polyobjects/PolyobjectEffector.zs | 96 +-- zscript/swwm_Polyobjects/PolyobjectHandle.zs | 718 +++++++++--------- .../PolyobjectMapPostprocessor.zs | 246 +++--- zscript/swwm_Polyobjects/Polyobjects.zs | 6 +- 5 files changed, 535 insertions(+), 535 deletions(-) diff --git a/language.version b/language.version index ab3715364..ccd4e03cf 100644 --- a/language.version +++ b/language.version @@ -1,3 +1,3 @@ [default] -SWWM_MODVER="\cyDEMOLITIONIST \cw1.3pre r256 \cu(Fri 5 Aug 21:30:11 CEST 2022)\c-"; -SWWM_SHORTVER="\cw1.3pre r256 \cu(2022-08-05 21:30:11)\c-"; +SWWM_MODVER="\cyDEMOLITIONIST \cw1.3pre r257 \cu(Fri 5 Aug 21:37:20 CEST 2022)\c-"; +SWWM_SHORTVER="\cw1.3pre r257 \cu(2022-08-05 21:37:20)\c-"; diff --git a/zscript/swwm_Polyobjects/PolyobjectEffector.zs b/zscript/swwm_Polyobjects/PolyobjectEffector.zs index 445df752c..1aa54fe76 100644 --- a/zscript/swwm_Polyobjects/PolyobjectEffector.zs +++ b/zscript/swwm_Polyobjects/PolyobjectEffector.zs @@ -1,48 +1,48 @@ -class swwm_PolyobjectEffector: Thinker abstract -{ - // Base abstract class for Polyobject Effectors - // Polyobject Effectors affect how a polyobject behaves. - // Polyobject Effectors contain a pointer to the next Effector of a polyobject, - // forming a circular linked list. - // To add an effector to a polyobject, call AddEffector() on a PolyobjectHandle. - // To remove an effector, simply call Destroy() on it. - - swwm_PolyobjectHandle Polyobject; - swwm_PolyobjectEffector Next; - - // OnAdd() is called once after adding the effector to a PolyobjectHandle - virtual void OnAdd() - { - - } - - // PolyTick() is called every tic by a PolyobjectHandle - virtual void PolyTick() - { - - } - - override void OnDestroy() - { - swwm_PolyobjectEffector e = Polyobject.EffectorList; - if (e != NULL) - { - // Find previous effector - while (e && e.Next != self) - { - e = e.Next; - } - - // Link previous effector to the next effector - e.Next = Next; - - // Check if this effector is the last one - if (e == self) - { - // Polyobject has no other effectors, set EffectorList to NULL - Polyobject.EffectorList = NULL; - } - } - Super.OnDestroy(); - } -} +class swwm_PolyobjectEffector: Thinker abstract +{ + // Base abstract class for Polyobject Effectors + // Polyobject Effectors affect how a polyobject behaves. + // Polyobject Effectors contain a pointer to the next Effector of a polyobject, + // forming a circular linked list. + // To add an effector to a polyobject, call AddEffector() on a PolyobjectHandle. + // To remove an effector, simply call Destroy() on it. + + swwm_PolyobjectHandle Polyobject; + swwm_PolyobjectEffector Next; + + // OnAdd() is called once after adding the effector to a PolyobjectHandle + virtual void OnAdd() + { + + } + + // PolyTick() is called every tic by a PolyobjectHandle + virtual void PolyTick() + { + + } + + override void OnDestroy() + { + swwm_PolyobjectEffector e = Polyobject.EffectorList; + if (e != NULL) + { + // Find previous effector + while (e && e.Next != self) + { + e = e.Next; + } + + // Link previous effector to the next effector + e.Next = Next; + + // Check if this effector is the last one + if (e == self) + { + // Polyobject has no other effectors, set EffectorList to NULL + Polyobject.EffectorList = NULL; + } + } + Super.OnDestroy(); + } +} diff --git a/zscript/swwm_Polyobjects/PolyobjectHandle.zs b/zscript/swwm_Polyobjects/PolyobjectHandle.zs index f67d92f45..0be289e2d 100644 --- a/zscript/swwm_Polyobjects/PolyobjectHandle.zs +++ b/zscript/swwm_Polyobjects/PolyobjectHandle.zs @@ -1,359 +1,359 @@ -class swwm_PolyobjectHandle: Thinker -{ - // This thinker keeps track of a polyobject's position, angle, movement speed etc. - // Instances of this thinker should only be created by the included map postprocessor - - enum EPolyobjType - { - POTYP_NORMAL = 9301, // Normal StartSpot - POTYP_CRUSH = 9302, // Crush StartSpot - POTYP_HURT = 9303 // Hurt StartSpot - } - - // Polyobject Number - int PolyobjectNum; - - // Line defining the polyobject (Polyobj_StartLine, or one of Polyobj_ExplicitLine) - Line StartLine; - - // [MK] All lines belonging to the polyobject - Array Lines; - - // Initial angle of StartLine - double StartAngle; - - // Last tic angle of StartLine - double LastAngle; - - // Starting positions of StartLine vertices - Vector2[2] VertexStartingPos; - - // Last tic positions of StartLine vertices - Vector2[2] VertexLastPos; - - // Last tic position of the polyobject - Vector2 LastPos; - - // SoundSequence number - int SoundSequenceNum; - - // StartSpot position - Vector2 StartSpotPos; - - // For bounds checking - double z; - - // Sector the polyobject spawns in () - Sector StartSector; - - // Polyobject type (normal, crush, hurt) - EPolyobjType Type; - - // Mirror Polyobject - swwm_PolyobjectHandle Mirror; - - // Circular linked list of attached Polyobject Effectors - swwm_PolyobjectEffector EffectorList; - - // Whether the initalization has finished - bool IsInitialized; - - // Creates a PolyobjectHandle - static swwm_PolyobjectHandle Create() - { - swwm_PolyobjectHandle po = swwm_PolyobjectHandle(new('swwm_PolyobjectHandle')); - // Sets the underlying Thinker StatNum to 127 so that LastPos, LastAngle etc. get - // updated after all the other thinkers. - po.ChangeStatNum(127); - - return po; - } - - // Returns a PolyobjectHandle corresponding to the provided polyobject number - // Returns NULL if no such handler exists. - static swwm_PolyobjectHandle FindPolyobj(int pobjnum) - { - swwm_PolyobjectHandle po; - let it = ThinkerIterator.Create('swwm_PolyobjectHandle'); - while ((po = swwm_PolyobjectHandle(it.Next())) != NULL) - { - if (po.PolyobjectNum == pobjnum) - return po; - } - return NULL; - } - - // Adds effector to the end of current effector list - void AddEffector(swwm_PolyobjectEffector effector) - { - - effector.Polyobject = self; - - // If effector list is empty, new effector becomes head of the list - if (EffectorList == NULL) - { - EffectorList = effector; - effector.Next = effector; - } - else - { - swwm_PolyobjectEffector e = EffectorList; - // Go through every effector until the last item - while (e.Next != EffectorList) - { - e = e.Next; - } - effector.Next = EffectorList; - e.Next = effector; - } - if (IsInitialized) - { - // If we're initialized, run the OnAdd effect immediately - effector.OnAdd(); - } - } - - // Finds effector of specified class, and returns it - swwm_PolyobjectEffector FindEffector(class effectorclass) - { - // No effectors? Nothing to find then - if (EffectorList == NULL) - return NULL; - - // Go through each effector - swwm_PolyobjectEffector e = EffectorList; - do - { - - // Effector is of specified class, return it - if (e is effectorclass) - return e; - - e = e.Next; - } - while (e != EffectorList); - return NULL; - } - - override void PostBeginPlay() - { - // Initialization shouldn't happen when reentering the map - if (Level.Time > 0) - return; - - // Map has no lines corresponding to this polyobject, destroy the handle - if (StartLine == NULL) - { - Destroy(); - return; - } - - // Using polyobject linedefs is the only way to track polyobject movements. - // All geometric calculations will be done relative to StartLine. - - // Store initial position and angle - StartAngle = VectorAngle(StartLine.Delta.x, StartLine.Delta.y); - VertexStartingPos[0] = VertexLastPos[0] = StartLine.v1.p; - VertexStartingPos[1] = VertexLastPos[1] = StartLine.v2.p; - - // Now that the map is loaded, it's safe to call effectors' OnAdd() methods - swwm_PolyobjectEffector e = EffectorList; - if (e != NULL) - { - do - { - e.OnAdd(); - e = e.Next; - } - while (e != EffectorList); - } - - // Done initializing - IsInitialized = true; - } - - override void Tick() - { - // Call PolyTick() for each effector - if (EffectorList != NULL) - { - swwm_PolyobjectEffector e = EffectorList; - do - { - e.PolyTick(); - e = e.Next; - } - while (e != EffectorList); - } - - // Store current position/angle to be used during the next tic - VertexLastPos[0] = StartLine.v1.p; - VertexLastPos[1] = StartLine.v2.p; - LastAngle = GetAngle(); - LastPos = GetPos(); - } - - override void OnDestroy() - { - // Clean up effectors first - swwm_PolyobjectEffector e = EffectorList; - if (e != NULL) - { - swwm_PolyobjectEffector next; - do - { - next = e.Next; - e.Destroy(); - e = next; - } - while (e != EffectorList); - } - } - - Sector GetSector() - { - if (StartSector == NULL) - { - Vector2 SpotPos = StartSpotPos; - - // Sometimes if StartSpot lies on a one-sided linedef, its position is considered - // out of bounds by GZDoom, which makes Level.PointInSector() produce unexpected - // results. In that case, we need to compensate. - if (!Level.IsPointInLevel((SpotPos, z))) - { - // Look at points in a 5x5 square around the StartSpot - for (int x = -2; x <= 2; x++) - { - for (int y = -2; y <= 2; y++) - { - SpotPos = StartSpotPos + (x, y); - - if (Level.IsPointInLevel((SpotPos, z))) - { - // Found a point within bounds, should be good enough - StartSector = Level.PointInSector(SpotPos); - break; - } - } - if (StartSector) - break; - } - } - else - { - StartSector = Level.PointInSector(SpotPos); - } - } - return StartSector; - } - - // Returns initial StartSpot position - Vector2 GetOrigin() - { - return StartSpotPos; - } - - // Returns current polyobject angle - double GetAngle() - { - double lineangle = VectorAngle(StartLine.Delta.x, StartLine.Delta.y); - return Actor.DeltaAngle(StartAngle, lineangle); - } - - // Returns current polyobject startspot position - Vector2 GetPos() - { - let spotdelta = StartSpotPos - VertexStartingPos[0]; - return StartLine.v1.p + Actor.RotateVector(spotdelta, GetAngle()); - } - - // Returns polyobject coordinates relative to the startspot - Vector2 GetPosDelta() - { - return GetPos() - StartSpotPos; - } - - // Returns last polyobject angle - double GetLastAngle() - { - return LastAngle; - } - - // Returns last polyobject startspot position - Vector2 GetLastPos() - { - return LastPos; - } - - // Returns last coordinates relative to the startspot - Vector2 GetLastPosDelta() - { - return LastPos - StartSpotPos; - } - - // Returns current polyobject velocity - Vector2 GetVel() - { - return StartLine.v1.p - VertexLastPos[0]; - } - - // Returns current polyobject rotation speed - double GetRotationSpeed() - { - return GetAngle() - LastAngle; - } - - // Returns whether the polyobject has moved from its spawn position - bool IsAtOrigin() - { - return (VertexStartingPos[0] == StartLine.v1.p && VertexStartingPos[1] == StartLine.v2.p); - } - - // Returns whether the polyobject is in motion - bool IsMoving() - { - return (GetPos() != GetLastPos() || GetAngle() != GetLastAngle()); - } - - // Moves the polyobject to specified location, with specified speed, and plays the - // specified sound of its sound sequence - // (i.e. for a door sound sequence, sndseqmode 0 plays the open sound, 1 plays the - // closing sound) - void MoveTo(Actor activator, Vector2 dest, int Speed, int sndseqmode = 0) - { - // Stop any polyobject movement - Level.ExecuteSpecial(Polyobj_Stop, activator, StartLine, Line.Front, PolyobjectNum); - // Move the polyobject - Level.ExecuteSpecial(Polyobj_OR_MoveTo, activator, StartLine, Line.Front, PolyobjectNum, - Speed, int(dest.x), int(dest.y)); - - // Polyobj_OR_MoveTo ignores the sound sequence set by the polyobject. - // Play the sound sequence manually inside the sector containing the polyobject. - if (SoundSequenceNum) - { - GetSector().StartSoundSequenceID(CHAN_AUTO, SoundSequenceNum, SeqNode.DOOR, sndseqmode, false); - } - } -} - -// Class for iterating over polyobjects -class swwm_PolyobjectIterator: Object -{ - private ThinkerIterator it; - static swwm_PolyobjectIterator Create() - { - let it = New('swwm_PolyobjectIterator'); - it.it = ThinkerIterator.Create('swwm_PolyobjectHandle'); - return it; - } - - swwm_PolyobjectHandle Next() - { - return swwm_PolyobjectHandle(it.Next()); - } - - void Reinit() - { - it.Reinit(); - } -} +class swwm_PolyobjectHandle: Thinker +{ + // This thinker keeps track of a polyobject's position, angle, movement speed etc. + // Instances of this thinker should only be created by the included map postprocessor + + enum EPolyobjType + { + POTYP_NORMAL = 9301, // Normal StartSpot + POTYP_CRUSH = 9302, // Crush StartSpot + POTYP_HURT = 9303 // Hurt StartSpot + } + + // Polyobject Number + int PolyobjectNum; + + // Line defining the polyobject (Polyobj_StartLine, or one of Polyobj_ExplicitLine) + Line StartLine; + + // [MK] All lines belonging to the polyobject + Array Lines; + + // Initial angle of StartLine + double StartAngle; + + // Last tic angle of StartLine + double LastAngle; + + // Starting positions of StartLine vertices + Vector2[2] VertexStartingPos; + + // Last tic positions of StartLine vertices + Vector2[2] VertexLastPos; + + // Last tic position of the polyobject + Vector2 LastPos; + + // SoundSequence number + int SoundSequenceNum; + + // StartSpot position + Vector2 StartSpotPos; + + // For bounds checking + double z; + + // Sector the polyobject spawns in () + Sector StartSector; + + // Polyobject type (normal, crush, hurt) + EPolyobjType Type; + + // Mirror Polyobject + swwm_PolyobjectHandle Mirror; + + // Circular linked list of attached Polyobject Effectors + swwm_PolyobjectEffector EffectorList; + + // Whether the initalization has finished + bool IsInitialized; + + // Creates a PolyobjectHandle + static swwm_PolyobjectHandle Create() + { + swwm_PolyobjectHandle po = swwm_PolyobjectHandle(new('swwm_PolyobjectHandle')); + // Sets the underlying Thinker StatNum to 127 so that LastPos, LastAngle etc. get + // updated after all the other thinkers. + po.ChangeStatNum(127); + + return po; + } + + // Returns a PolyobjectHandle corresponding to the provided polyobject number + // Returns NULL if no such handler exists. + static swwm_PolyobjectHandle FindPolyobj(int pobjnum) + { + swwm_PolyobjectHandle po; + let it = ThinkerIterator.Create('swwm_PolyobjectHandle'); + while ((po = swwm_PolyobjectHandle(it.Next())) != NULL) + { + if (po.PolyobjectNum == pobjnum) + return po; + } + return NULL; + } + + // Adds effector to the end of current effector list + void AddEffector(swwm_PolyobjectEffector effector) + { + + effector.Polyobject = self; + + // If effector list is empty, new effector becomes head of the list + if (EffectorList == NULL) + { + EffectorList = effector; + effector.Next = effector; + } + else + { + swwm_PolyobjectEffector e = EffectorList; + // Go through every effector until the last item + while (e.Next != EffectorList) + { + e = e.Next; + } + effector.Next = EffectorList; + e.Next = effector; + } + if (IsInitialized) + { + // If we're initialized, run the OnAdd effect immediately + effector.OnAdd(); + } + } + + // Finds effector of specified class, and returns it + swwm_PolyobjectEffector FindEffector(class effectorclass) + { + // No effectors? Nothing to find then + if (EffectorList == NULL) + return NULL; + + // Go through each effector + swwm_PolyobjectEffector e = EffectorList; + do + { + + // Effector is of specified class, return it + if (e is effectorclass) + return e; + + e = e.Next; + } + while (e != EffectorList); + return NULL; + } + + override void PostBeginPlay() + { + // Initialization shouldn't happen when reentering the map + if (Level.Time > 0) + return; + + // Map has no lines corresponding to this polyobject, destroy the handle + if (StartLine == NULL) + { + Destroy(); + return; + } + + // Using polyobject linedefs is the only way to track polyobject movements. + // All geometric calculations will be done relative to StartLine. + + // Store initial position and angle + StartAngle = VectorAngle(StartLine.Delta.x, StartLine.Delta.y); + VertexStartingPos[0] = VertexLastPos[0] = StartLine.v1.p; + VertexStartingPos[1] = VertexLastPos[1] = StartLine.v2.p; + + // Now that the map is loaded, it's safe to call effectors' OnAdd() methods + swwm_PolyobjectEffector e = EffectorList; + if (e != NULL) + { + do + { + e.OnAdd(); + e = e.Next; + } + while (e != EffectorList); + } + + // Done initializing + IsInitialized = true; + } + + override void Tick() + { + // Call PolyTick() for each effector + if (EffectorList != NULL) + { + swwm_PolyobjectEffector e = EffectorList; + do + { + e.PolyTick(); + e = e.Next; + } + while (e != EffectorList); + } + + // Store current position/angle to be used during the next tic + VertexLastPos[0] = StartLine.v1.p; + VertexLastPos[1] = StartLine.v2.p; + LastAngle = GetAngle(); + LastPos = GetPos(); + } + + override void OnDestroy() + { + // Clean up effectors first + swwm_PolyobjectEffector e = EffectorList; + if (e != NULL) + { + swwm_PolyobjectEffector next; + do + { + next = e.Next; + e.Destroy(); + e = next; + } + while (e != EffectorList); + } + } + + Sector GetSector() + { + if (StartSector == NULL) + { + Vector2 SpotPos = StartSpotPos; + + // Sometimes if StartSpot lies on a one-sided linedef, its position is considered + // out of bounds by GZDoom, which makes Level.PointInSector() produce unexpected + // results. In that case, we need to compensate. + if (!Level.IsPointInLevel((SpotPos, z))) + { + // Look at points in a 5x5 square around the StartSpot + for (int x = -2; x <= 2; x++) + { + for (int y = -2; y <= 2; y++) + { + SpotPos = StartSpotPos + (x, y); + + if (Level.IsPointInLevel((SpotPos, z))) + { + // Found a point within bounds, should be good enough + StartSector = Level.PointInSector(SpotPos); + break; + } + } + if (StartSector) + break; + } + } + else + { + StartSector = Level.PointInSector(SpotPos); + } + } + return StartSector; + } + + // Returns initial StartSpot position + Vector2 GetOrigin() + { + return StartSpotPos; + } + + // Returns current polyobject angle + double GetAngle() + { + double lineangle = VectorAngle(StartLine.Delta.x, StartLine.Delta.y); + return Actor.DeltaAngle(StartAngle, lineangle); + } + + // Returns current polyobject startspot position + Vector2 GetPos() + { + let spotdelta = StartSpotPos - VertexStartingPos[0]; + return StartLine.v1.p + Actor.RotateVector(spotdelta, GetAngle()); + } + + // Returns polyobject coordinates relative to the startspot + Vector2 GetPosDelta() + { + return GetPos() - StartSpotPos; + } + + // Returns last polyobject angle + double GetLastAngle() + { + return LastAngle; + } + + // Returns last polyobject startspot position + Vector2 GetLastPos() + { + return LastPos; + } + + // Returns last coordinates relative to the startspot + Vector2 GetLastPosDelta() + { + return LastPos - StartSpotPos; + } + + // Returns current polyobject velocity + Vector2 GetVel() + { + return StartLine.v1.p - VertexLastPos[0]; + } + + // Returns current polyobject rotation speed + double GetRotationSpeed() + { + return GetAngle() - LastAngle; + } + + // Returns whether the polyobject has moved from its spawn position + bool IsAtOrigin() + { + return (VertexStartingPos[0] == StartLine.v1.p && VertexStartingPos[1] == StartLine.v2.p); + } + + // Returns whether the polyobject is in motion + bool IsMoving() + { + return (GetPos() != GetLastPos() || GetAngle() != GetLastAngle()); + } + + // Moves the polyobject to specified location, with specified speed, and plays the + // specified sound of its sound sequence + // (i.e. for a door sound sequence, sndseqmode 0 plays the open sound, 1 plays the + // closing sound) + void MoveTo(Actor activator, Vector2 dest, int Speed, int sndseqmode = 0) + { + // Stop any polyobject movement + Level.ExecuteSpecial(Polyobj_Stop, activator, StartLine, Line.Front, PolyobjectNum); + // Move the polyobject + Level.ExecuteSpecial(Polyobj_OR_MoveTo, activator, StartLine, Line.Front, PolyobjectNum, + Speed, int(dest.x), int(dest.y)); + + // Polyobj_OR_MoveTo ignores the sound sequence set by the polyobject. + // Play the sound sequence manually inside the sector containing the polyobject. + if (SoundSequenceNum) + { + GetSector().StartSoundSequenceID(CHAN_AUTO, SoundSequenceNum, SeqNode.DOOR, sndseqmode, false); + } + } +} + +// Class for iterating over polyobjects +class swwm_PolyobjectIterator: Object +{ + private ThinkerIterator it; + static swwm_PolyobjectIterator Create() + { + let it = New('swwm_PolyobjectIterator'); + it.it = ThinkerIterator.Create('swwm_PolyobjectHandle'); + return it; + } + + swwm_PolyobjectHandle Next() + { + return swwm_PolyobjectHandle(it.Next()); + } + + void Reinit() + { + it.Reinit(); + } +} diff --git a/zscript/swwm_Polyobjects/PolyobjectMapPostprocessor.zs b/zscript/swwm_Polyobjects/PolyobjectMapPostprocessor.zs index 564e0ed13..7e9335d42 100644 --- a/zscript/swwm_Polyobjects/PolyobjectMapPostprocessor.zs +++ b/zscript/swwm_Polyobjects/PolyobjectMapPostprocessor.zs @@ -1,123 +1,123 @@ -// Creates a PolyobjectHandle for every polyobject in the map -class swwm_PolyobjectHandlePostProcessor: LevelPostProcessor -{ - protected void Apply(Name checksum, String mapname) - { - Array pobjnums; - Array pobjhandles; - - // Make sure initialization doesn't happen when reentering a map - if (Level.Time > 0) - return; - - // Look for Polyobject StartSpots and create a handle for each - for (uint i = 0; i < GetThingCount(); i++) - { - // Ignore every thing that isn't a Polyobject StartSpot - int ednum = GetThingEdNum(i); - // [MK] hotfix for this to recognize hexen polyobjects - if (gameinfo.gametype&GAME_Hexen) - { - if (ednum == 3001) ednum = swwm_PolyobjectHandle.POTYP_NORMAL; - else if (ednum == 3002) ednum = swwm_PolyobjectHandle.POTYP_CRUSH; - } - if (ednum < swwm_PolyobjectHandle.POTYP_NORMAL || ednum > swwm_PolyobjectHandle.POTYP_HURT) - continue; - - // Create a PolyobjectHandle - swwm_PolyobjectHandle handle = swwm_PolyobjectHandle.Create(); - - // Get polyobject number from StartSpot angle - handle.PolyobjectNum = GetThingAngle(i); - - // Store StartSpot position - Vector3 pos = GetThingPos(i); - handle.StartSpotPos = pos.xy; - handle.z = pos.z; - - // Store StartSpot type (normal, crush, hurt) - handle.Type = ednum; - - // Append polyobject number and corresponding handle to the respective arrays - pobjnums.Push(handle.PolyobjectNum); - pobjhandles.Push(handle); - } - - // Look for Polyobj_StartLine/Polyobj_ExplicitLine lines - for (int i = 0; i < Level.Lines.Size(); i++) - { - Line line = Level.Lines[i]; - - // Ignore every line that doesn't have a Polyobj_StartLine or Polyobj_ExplicitLine - // line special - if (line.Special != Polyobj_StartLine && line.Special != Polyobj_ExplicitLine) - continue; - - // Get polyobject number - // (Args[0] for both Polyobj_StartLine and Polyobj_ExplicitLine) - int pobjnum = line.Args[0]; - - // Find the array index of the corresponding handle - int pobjhandleindex = pobjnums.Find(pobjnum); - if (pobjhandleindex >= pobjnums.Size()) - continue; // Polyobject doesn't have a corresponding StartSpot - - swwm_PolyobjectHandle handle = pobjhandles[pobjhandleindex]; - - // Get mirror polyobject number - // (Args[1] for Polyobj_StartLine, Args[2] for Polyobj_ExplicitLine) - int mirrorpobjnum = line.Special == Polyobj_StartLine ? line.Args[1] : line.Args[2]; - if (mirrorpobjnum != 0) - { - // Find the array index of the mirror polyobject handle - int mirrorpobjhandleindex = pobjnums.Find(mirrorpobjnum); - if (mirrorpobjhandleindex < pobjnums.Size()) - { - // Mirror polyobject handle exists, store it - handle.Mirror = pobjhandles[mirrorpobjhandleindex]; - } - } - - // Get sound sequence number and store it - // (Args[2] for Polyobj_StartLine, Args[3] for Polyobj_ExplicitLine) - int soundseq = line.Special == Polyobj_StartLine ? line.Args[2] : line.Args[3]; - handle.SoundSequenceNum = soundseq; - - // Store the line - handle.StartLine = line; - - // [MK] the library doesn't store ALL lines belonging to the polyobject, but we need them - handle.Lines.Push(line); - - // [MK] collect all connected lines if this is Polyobj_StartLine - if ( line.Special != Polyobj_StartLine ) - continue; - - bool newlines; - do - { - newlines = false; - for (int j = 0; j < Level.Lines.Size(); j++) - { - Line linea = Level.Lines[j]; - if (handle.Lines.Find(linea) < handle.Lines.Size()) - continue; - bool nomatches = true; - for (int k = 0; k < handle.Lines.Size(); k++) - { - Line lineb = handle.Lines[k]; - if ((linea.v1 != lineb.v1) && (linea.v1 != lineb.v2) && (linea.v2 != lineb.v1) && (linea.v2 != lineb.v2)) - continue; - nomatches = false; - break; - } - if (nomatches) - continue; - newlines = true; - handle.Lines.Push(linea); - } - } - while (newlines); - } - } -} +// Creates a PolyobjectHandle for every polyobject in the map +class swwm_PolyobjectHandlePostProcessor: LevelPostProcessor +{ + protected void Apply(Name checksum, String mapname) + { + Array pobjnums; + Array pobjhandles; + + // Make sure initialization doesn't happen when reentering a map + if (Level.Time > 0) + return; + + // Look for Polyobject StartSpots and create a handle for each + for (uint i = 0; i < GetThingCount(); i++) + { + // Ignore every thing that isn't a Polyobject StartSpot + int ednum = GetThingEdNum(i); + // [MK] hotfix for this to recognize hexen polyobjects + if (gameinfo.gametype&GAME_Hexen) + { + if (ednum == 3001) ednum = swwm_PolyobjectHandle.POTYP_NORMAL; + else if (ednum == 3002) ednum = swwm_PolyobjectHandle.POTYP_CRUSH; + } + if (ednum < swwm_PolyobjectHandle.POTYP_NORMAL || ednum > swwm_PolyobjectHandle.POTYP_HURT) + continue; + + // Create a PolyobjectHandle + swwm_PolyobjectHandle handle = swwm_PolyobjectHandle.Create(); + + // Get polyobject number from StartSpot angle + handle.PolyobjectNum = GetThingAngle(i); + + // Store StartSpot position + Vector3 pos = GetThingPos(i); + handle.StartSpotPos = pos.xy; + handle.z = pos.z; + + // Store StartSpot type (normal, crush, hurt) + handle.Type = ednum; + + // Append polyobject number and corresponding handle to the respective arrays + pobjnums.Push(handle.PolyobjectNum); + pobjhandles.Push(handle); + } + + // Look for Polyobj_StartLine/Polyobj_ExplicitLine lines + for (int i = 0; i < Level.Lines.Size(); i++) + { + Line line = Level.Lines[i]; + + // Ignore every line that doesn't have a Polyobj_StartLine or Polyobj_ExplicitLine + // line special + if (line.Special != Polyobj_StartLine && line.Special != Polyobj_ExplicitLine) + continue; + + // Get polyobject number + // (Args[0] for both Polyobj_StartLine and Polyobj_ExplicitLine) + int pobjnum = line.Args[0]; + + // Find the array index of the corresponding handle + int pobjhandleindex = pobjnums.Find(pobjnum); + if (pobjhandleindex >= pobjnums.Size()) + continue; // Polyobject doesn't have a corresponding StartSpot + + swwm_PolyobjectHandle handle = pobjhandles[pobjhandleindex]; + + // Get mirror polyobject number + // (Args[1] for Polyobj_StartLine, Args[2] for Polyobj_ExplicitLine) + int mirrorpobjnum = line.Special == Polyobj_StartLine ? line.Args[1] : line.Args[2]; + if (mirrorpobjnum != 0) + { + // Find the array index of the mirror polyobject handle + int mirrorpobjhandleindex = pobjnums.Find(mirrorpobjnum); + if (mirrorpobjhandleindex < pobjnums.Size()) + { + // Mirror polyobject handle exists, store it + handle.Mirror = pobjhandles[mirrorpobjhandleindex]; + } + } + + // Get sound sequence number and store it + // (Args[2] for Polyobj_StartLine, Args[3] for Polyobj_ExplicitLine) + int soundseq = line.Special == Polyobj_StartLine ? line.Args[2] : line.Args[3]; + handle.SoundSequenceNum = soundseq; + + // Store the line + handle.StartLine = line; + + // [MK] the library doesn't store ALL lines belonging to the polyobject, but we need them + handle.Lines.Push(line); + + // [MK] collect all connected lines if this is Polyobj_StartLine + if ( line.Special != Polyobj_StartLine ) + continue; + + bool newlines; + do + { + newlines = false; + for (int j = 0; j < Level.Lines.Size(); j++) + { + Line linea = Level.Lines[j]; + if (handle.Lines.Find(linea) < handle.Lines.Size()) + continue; + bool nomatches = true; + for (int k = 0; k < handle.Lines.Size(); k++) + { + Line lineb = handle.Lines[k]; + if ((linea.v1 != lineb.v1) && (linea.v1 != lineb.v2) && (linea.v2 != lineb.v1) && (linea.v2 != lineb.v2)) + continue; + nomatches = false; + break; + } + if (nomatches) + continue; + newlines = true; + handle.Lines.Push(linea); + } + } + while (newlines); + } + } +} diff --git a/zscript/swwm_Polyobjects/Polyobjects.zs b/zscript/swwm_Polyobjects/Polyobjects.zs index 56460e605..7bd8ac962 100644 --- a/zscript/swwm_Polyobjects/Polyobjects.zs +++ b/zscript/swwm_Polyobjects/Polyobjects.zs @@ -1,3 +1,3 @@ -#include "zscript/swwm_Polyobjects/PolyobjectHandle.zs" -#include "zscript/swwm_Polyobjects/PolyobjectMapPostprocessor.zs" -#include "zscript/swwm_Polyobjects/PolyobjectEffector.zs" +#include "zscript/swwm_Polyobjects/PolyobjectHandle.zs" +#include "zscript/swwm_Polyobjects/PolyobjectMapPostprocessor.zs" +#include "zscript/swwm_Polyobjects/PolyobjectEffector.zs"