• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

Void Portal System (v.1.1)

This bundle is marked as pending. It has not been reviewed by a staff member yet.

Basic Info

Documentation

Demo Triggers in Map

How to install

Credits

Changelog


Void Portal System


A system that handles sucking units towards unstable portals.
Once the unit reaches the point of no return, you'll make sure
that the unit gets the send-off it deserves, when it gets removed
from existence. Heroes are fortunate to escape from the portal
with their spirit intact.

This system allows one to create a simulated black hole (or void portal), where units falling within the grasp of the void portal will slowly reach a grim end. It has a lot of configurable variables for you, such as the amount of damage per second, range of the black hole (outer radius), radius of the black hole (inner radius) and more.

How it works:

The system will first check if a unit in range of the black hole will fall into the black hole. This is the filter phase, where you filter unwanted units out, and they subsequently do not suffer the consequences of falling inward. Filtering units out is done once, so they will not be enumerated again in the next iteration, (unless a certain Exclude_Group member is cleared).

After a unit passes the filter, it will be dragged into the black hole, with a bit of rotation for added special effect. Once it reaches a critical distance, it will be killed by the caster if the caster is defined (caster is not defined by default), then by itself if the former fails, then the game kills it if killing itself didn't work. Afterwards, the Death Flag phase kicks in, which will determine whether to make the unit's death count towards the amount of spawned units or not. This phase will not spawn the units yet.

The system will do this for every instance, so having a lot of these will be a problem later on.

When destroying an instance, it will wait until either the filter phase or the death flag phase is finished (if the instance was to be destroyed at that time) before actually being destroyed, and just proceed as normal otherwise. Upon instance destruction, the system will spawn units of unit type based on your definitions, up to the amount mentioned above. This amount should only be read, and not written (Don't set it, just get it). After this, the spawn phase will run, granting you access to the spawned units via (Last Created Unit Group). If you define a custom trigger for the spawn phase, you'll have to handle the unit group leak by yourself (Last Created Unit Group).

Under the Void Portal Folder, there is a How to Subfolder. Under this Subfolder, it will go into detail on how to create, manage and destroy Void Portal instances for your own uses.

An extensive Demo Trigger is found in the spell Nether Vacuum, where it has its' own intricacies and such, which then makes use of the Void Portal system to simulate an otherworldly summoning ritual, with a bit of black hole physics. It has its' own sets of configurable stuff, most of which overlap with the Void Portal system.

To be added..

If one does not have the World Editor, the Demo Triggers can be viewed here. (If Preview Triggers does not work as well)

  • Nether Vacuum Cast
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to NETHER_VACUUM_ABILITY
    • Actions
      • -------- Generate New Id --------
      • Set Nether_Vacuum_Current = Nether_Vacuum_Alloc[0]
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Or - Any (Conditions) are true
            • Conditions
              • Nether_Vacuum_Alloc[Nether_Vacuum_Current] Equal to -1
              • Nether_Vacuum_Current Equal to 0
        • Then - Actions
          • -------- If alloc[alloc[0]] == -1, then create new id, else get old one --------
          • -------- Edge case scenario, if alloc[0] is 0, force allocation --------
          • Set Nether_Vacuum_Current = (Nether_Vacuum_Current + 1)
          • Set Nether_Vacuum_Alloc[0] = Nether_Vacuum_Current
        • Else - Actions
          • -------- Since there are some deallocated ids, use them again and update the list of deallocated ids --------
          • Set Nether_Vacuum_Alloc[0] = Nether_Vacuum_Alloc[Nether_Vacuum_Current]
      • Set Nether_Vacuum_Alloc[Nether_Vacuum_Current] = -1
      • -------- Insert Id to the list of iterables --------
      • Set Nether_Vacuum_Next[Nether_Vacuum_Current] = 0
      • Set Nether_Vacuum_Prev[Nether_Vacuum_Current] = Nether_Vacuum_Prev[0]
      • Set Nether_Vacuum_Next[Nether_Vacuum_Prev[Nether_Vacuum_Current]] = Nether_Vacuum_Current
      • Set Nether_Vacuum_Prev[Nether_Vacuum_Next[Nether_Vacuum_Current]] = Nether_Vacuum_Current
      • -------- Now, we store the information needed for later --------
      • Set Nether_Vacuum_Caster[Nether_Vacuum_Current] = (Triggering unit)
      • Set Nether_Vacuum_List_Mode[Nether_Vacuum_Current] = 1
      • -------- Place location object references here, before assigning the needed information --------
      • Set Nether_Vacuum_Dummy_Loc[0] = (Position of Nether_Vacuum_Caster[Nether_Vacuum_Current])
      • Set Nether_Vacuum_Dummy_Loc[1] = (Target point of ability being cast)
      • -------- Now, we store the information needed for later --------
      • Set Nether_Vacuum_Level[Nether_Vacuum_Current] = (Level of NETHER_VACUUM_ABILITY for Nether_Vacuum_Caster[Nether_Vacuum_Current])
      • Set Nether_Vacuum_TargetX[Nether_Vacuum_Current] = (X of Nether_Vacuum_Dummy_Loc[1])
      • Set Nether_Vacuum_TargetY[Nether_Vacuum_Current] = (Y of Nether_Vacuum_Dummy_Loc[1])
      • -------- Create the Projectile and Closure Timer --------
      • Special Effect - Create a special effect at Nether_Vacuum_Dummy_Loc[0] using NETHER_VACUUM_PROJECTILE_MODEL
      • Set Nether_Vacuum_Projectile_SFX[Nether_Vacuum_Current] = (Last created special effect)
      • Custom script: set udg_Nether_Vacuum_Closure_Timer[udg_Nether_Vacuum_Current] = CreateTimer()
      • Set Nether_Vacuum_Projectile_SFX[Nether_Vacuum_Current] = (Last created special effect)
      • Custom script: call SaveInteger(udg_Nether_Vacuum_Hashtable, 0, GetHandleId(udg_Nether_Vacuum_Closure_Timer[udg_Nether_Vacuum_Current]), udg_Nether_Vacuum_Current)
      • -------- Calculate the Parabola based on the parameters given --------
      • -------- A Monstrosity of a function line below --------
      • Set ParabolaLoc[0] = Nether_Vacuum_Dummy_Loc[0]
      • Set ParabolaLoc[1] = Nether_Vacuum_Dummy_Loc[1]
      • Set ParabolaZ[0] = NETHER_VACUUM_PROJ_LAUNCH_Z[Nether_Vacuum_Level[Nether_Vacuum_Current]]
      • Set ParabolaZ[1] = NETHER_VACUUM_PROJ_END_Z[Nether_Vacuum_Level[Nether_Vacuum_Current]]
      • Set ParabolaZ_Max = NETHER_VACUUM_PROJ_MAX_HEIGHT[Nether_Vacuum_Level[Nether_Vacuum_Current]]
      • Set Parabola_Veloc = NETHER_VACUUM_SPEED[Nether_Vacuum_Level[Nether_Vacuum_Current]]
      • -------- Calling GetParabolicInitialVelocityEx --------
      • Set Parabola_Func_Id = 1
      • Trigger - Run Parabola Get Parameters <gen> (ignoring conditions)
      • -------- Parabola_Initial_Velocity and Parabola_Initial_Acceleration now have our desired values --------
      • Set Nether_Vacuum_Accel_Z[Nether_Vacuum_Current] = (Parabola_Initial_Acceleration x NETHER_VACUUM_INTERVAL)
      • Set Nether_Vacuum_Veloc_Z[Nether_Vacuum_Current] = (Parabola_Initial_Velocity x NETHER_VACUUM_INTERVAL)
      • Set Nether_Vacuum_SFX_Yaw[Nether_Vacuum_Current] = ((Angle from Nether_Vacuum_Dummy_Loc[0] to Nether_Vacuum_Dummy_Loc[1]) x (Pi / 180.00))
      • Set Nether_Vacuum_Pitch_Temp = ((Atan2(Nether_Vacuum_Veloc_Z[Nether_Vacuum_Current], (NETHER_VACUUM_SPEED[Nether_Vacuum_Level[Nether_Vacuum_Current]] x NETHER_VACUUM_INTERVAL))) x (-1.00 x (Pi / 180.00)))
      • -------- Make the Projectile face the targeted angle --------
      • Special Effect - Set Height of Nether_Vacuum_Projectile_SFX[Nether_Vacuum_Current] to: NETHER_VACUUM_PROJ_LAUNCH_Z[Nether_Vacuum_Level[Nether_Vacuum_Current]]
      • Special Effect - Set Yaw of Nether_Vacuum_Projectile_SFX[Nether_Vacuum_Current] to: (1.00 x Nether_Vacuum_SFX_Yaw[Nether_Vacuum_Current])
      • Special Effect - Set Pitch of Nether_Vacuum_Projectile_SFX[Nether_Vacuum_Current] to: Nether_Vacuum_Pitch_Temp
      • -------- Check if the timer has already started --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Nether_Vacuum_Prev[Nether_Vacuum_Current] Equal to 0
        • Then - Actions
          • -------- The insertion type is push. If the previous node of the current is 0, it must be at the start of the list. --------
          • Custom script: call TimerStart(udg_Nether_Vacuum_Timer, udg_NETHER_VACUUM_INTERVAL, true, null)
        • Else - Actions
      • Custom script: call RemoveLocation(udg_Nether_Vacuum_Dummy_Loc[0])
      • Custom script: call RemoveLocation(udg_Nether_Vacuum_Dummy_Loc[1])
  • Nether Vacuum Periodic
    • Events
      • Time - Nether_Vacuum_Timer expires
    • Conditions
    • Actions
      • -------- Check if the loop was discontinued via location leaks --------
      • Custom script: if GetHandleId(udg_Nether_Vacuum_Dummy_Loc[2]) != 0 or GetHandleId(udg_Nether_Vacuum_Dummy_Loc[3]) != 0 then
      • Custom script: call MoveLocation(udg_Nether_Vacuum_Dummy_Loc[2], 1, 1)
      • Custom script: if not (GetLocationX(udg_Nether_Vacuum_Dummy_Loc[2]) != 1.) then
      • Custom script: call RemoveLocation(udg_Nether_Vacuum_Dummy_Loc[2])
      • Custom script: call RemoveLocation(udg_Nether_Vacuum_Dummy_Loc[3])
      • Custom script: endif
      • Custom script: endif
      • -------- Move on to loop operations --------
      • Set Nether_Vacuum_Current = Nether_Vacuum_Next[0]
      • Set Nether_Vacuum_Dummy_Loc[0] = (Point((Position - X of Nether_Vacuum_Projectile_SFX[Nether_Vacuum_Current]), (Position - Y of Nether_Vacuum_Projectile_SFX[Nether_Vacuum_Current])))
      • Set Nether_Vacuum_Dummy_Loc[1] = (Nether_Vacuum_Dummy_Loc[0] offset by (NETHER_VACUUM_SPEED[Nether_Vacuum_Level[Nether_Vacuum_Current]] x NETHER_VACUUM_INTERVAL) towards (Nether_Vacuum_SFX_Yaw[Nether_Vacuum_Current] x (180.00 / Pi)) degrees)
      • Set Nether_Vacuum_Dummy_Loc[2] = Nether_Vacuum_Dummy_Loc[0]
      • Set Nether_Vacuum_Dummy_Loc[3] = Nether_Vacuum_Dummy_Loc[1]
      • -------- Syntactical sugar --------
      • For each (Integer Nether_Vacuum_Dummy_Var) from 1 to 1, do (Actions)
        • Loop - Actions
          • Custom script: exitwhen udg_Nether_Vacuum_Current == 0
          • -------- Update position of the projectile --------
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • Nether_Vacuum_List_Mode[Nether_Vacuum_Current] Equal to 1
            • Then - Actions
              • Special Effect - Set Position of Nether_Vacuum_Projectile_SFX[Nether_Vacuum_Current] to x: (X of Nether_Vacuum_Dummy_Loc[1]), y: (Y of Nether_Vacuum_Dummy_Loc[1]), z: ((Position - Z of Nether_Vacuum_Projectile_SFX[Nether_Vacuum_Current]) + (Nether_Vacuum_Veloc_Z[Nether_Vacuum_Current] / 2.00))
              • Set Nether_Vacuum_Veloc_Z[Nether_Vacuum_Current] = (Nether_Vacuum_Veloc_Z[Nether_Vacuum_Current] + (Nether_Vacuum_Accel_Z[Nether_Vacuum_Current] x (NETHER_VACUUM_SPEED[Nether_Vacuum_Level[Nether_Vacuum_Current]] x (NETHER_VACUUM_INTERVAL x 2.00))))
              • Set Nether_Vacuum_Pitch_Temp = ((Atan2(Nether_Vacuum_Veloc_Z[Nether_Vacuum_Current], (NETHER_VACUUM_SPEED[Nether_Vacuum_Level[Nether_Vacuum_Current]] x NETHER_VACUUM_INTERVAL))) x (-1.00 x (Pi / 180.00)))
              • Special Effect - Set Yaw of Nether_Vacuum_Projectile_SFX[Nether_Vacuum_Current] to: (1.00 x Nether_Vacuum_SFX_Yaw[Nether_Vacuum_Current])
              • Special Effect - Set Pitch of Nether_Vacuum_Projectile_SFX[Nether_Vacuum_Current] to: Nether_Vacuum_Pitch_Temp
              • -------- Check if the missile has reached its' destination or if it has touched the ground --------
              • Set Nether_Vacuum_Temp_Dist[0] = ((((Position - X of Nether_Vacuum_Projectile_SFX[Nether_Vacuum_Current]) - Nether_Vacuum_TargetX[Nether_Vacuum_Current]) x ((Position - X of Nether_Vacuum_Projectile_SFX[Nether_Vacuum_Current]) - Nether_Vacuum_TargetX[Nether_Vacuum_Current])) + (((Position - Y)
              • Custom script: set udg_Nether_Vacuum_Temp_Dist[1] = BlzGetLocalSpecialEffectZ(udg_Nether_Vacuum_Projectile_SFX[udg_Nether_Vacuum_Current]) - GetLocationZ(udg_Nether_Vacuum_Dummy_Loc[1])
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • Or - Any (Conditions) are true
                    • Conditions
                      • Nether_Vacuum_Temp_Dist[0] Less than or equal to ((NETHER_VACUUM_SPEED[Nether_Vacuum_Level[Nether_Vacuum_Current]] x NETHER_VACUUM_INTERVAL) x (NETHER_VACUUM_SPEED[Nether_Vacuum_Level[Nether_Vacuum_Current]] x NETHER_VACUUM_INTERVAL))
                      • Nether_Vacuum_Temp_Dist[1] Less than or equal to 0.00
                • Then - Actions
                  • -------- Remove the current instance from the list --------
                  • -------- Do not deallocate the instance yet.. --------
                  • Set Nether_Vacuum_Next[Nether_Vacuum_Prev[Nether_Vacuum_Current]] = Nether_Vacuum_Next[Nether_Vacuum_Current]
                  • Set Nether_Vacuum_Prev[Nether_Vacuum_Next[Nether_Vacuum_Current]] = Nether_Vacuum_Prev[Nether_Vacuum_Current]
                  • Set Nether_Vacuum_List_Mode[Nether_Vacuum_Current] = 0
                  • -------- Move Nether_Vacuum_Dummy_Loc[1] to target position --------
                  • Custom script: call MoveLocation(udg_Nether_Vacuum_Dummy_Loc[1], udg_Nether_Vacuum_TargetX[udg_Nether_Vacuum_Current], udg_Nether_Vacuum_TargetY[udg_Nether_Vacuum_Current])
                  • -------- Destroy projectile art --------
                  • Special Effect - Set Height of Nether_Vacuum_Projectile_SFX[Nether_Vacuum_Current] to: 0.00
                  • Special Effect - Destroy Nether_Vacuum_Projectile_SFX[Nether_Vacuum_Current]
                  • Custom script: set udg_Nether_Vacuum_Projectile_SFX[udg_Nether_Vacuum_Current] = null
                  • -------- Nullify unneeded parameters (not really necessary) --------
                  • Set Nether_Vacuum_Accel_Z[Nether_Vacuum_Current] = 0.00
                  • Set Nether_Vacuum_Veloc_Z[Nether_Vacuum_Current] = 0.00
                  • Set Nether_Vacuum_SFX_Yaw[Nether_Vacuum_Current] = 0.00
                  • Set Nether_Vacuum_TargetX[Nether_Vacuum_Current] = 0.00
                  • Set Nether_Vacuum_TargetY[Nether_Vacuum_Current] = 0.00
                  • -------- Create the Void Portal here --------
                  • Set Void_Portal_Create_Owner = (Owner of Nether_Vacuum_Caster[Nether_Vacuum_Current])
                  • Set Void_Portal_Create_Location = Nether_Vacuum_Dummy_Loc[1]
                  • Set Void_Portal_Create_Model = NETHER_VACUUM_PORTAL_MODEL
                  • Set Void_Portal_Create_InnerRad = NETHER_VACUUM_INNER_RADIUS[Nether_Vacuum_Level[Nether_Vacuum_Current]]
                  • Set Void_Portal_Create_OuterRad = NETHER_VACUUM_OUTER_RADIUS[Nether_Vacuum_Level[Nether_Vacuum_Current]]
                  • Trigger - Run Void Portal Create <gen> (ignoring conditions)
                  • -------- Void Portal Created. Now, we have access to Void_Portal_Current --------
                  • -------- Store the current instance as a member of our Nether Vacuum --------
                  • Set Nether_Vacuum_Portal[Nether_Vacuum_Current] = Void_Portal_Current
                  • Set Nether_Vacuum_Portal_Pointer[Void_Portal_Current] = Nether_Vacuum_Current
                  • -------- Apply Configuration Settings here --------
                  • Set Void_Portal_Capture_Dist_Ratio[Void_Portal_Current] = NETHER_VACUUM_CAP_DIST_RATIO[Nether_Vacuum_Level[Nether_Vacuum_Current]]
                  • Set Void_Portal_Caster[Void_Portal_Current] = Nether_Vacuum_Caster[Nether_Vacuum_Current]
                  • Set Void_Portal_Death_Model[Void_Portal_Current] = NETHER_VACUUM_DEATH_MODEL
                  • Set Void_Portal_Spawn_Model[Void_Portal_Current] = NETHER_VACUUM_SPAWN_MODEL
                  • Set Void_Portal_Pull_Velocity[Void_Portal_Current] = NETHER_VACUUM_PULL_VELOCITY[Nether_Vacuum_Level[Nether_Vacuum_Current]]
                  • Set Void_Portal_Pull_Rel_Veloc[Void_Portal_Current] = NETHER_VACUUM_PULL_REL_FACTOR[Nether_Vacuum_Level[Nether_Vacuum_Current]]
                  • Set Void_Portal_Rotate_Velocity[Void_Portal_Current] = NETHER_VACUUM_ROTATE_VELOCITY[Nether_Vacuum_Level[Nether_Vacuum_Current]]
                  • Set Void_Portal_DPS[Void_Portal_Current] = NETHER_VACUUM_DPS[Nether_Vacuum_Level[Nether_Vacuum_Current]]
                  • Set Void_Portal_Spawn_Type[Void_Portal_Current] = NETHER_VACUUM_SPAWN_TYPE[Nether_Vacuum_Level[Nether_Vacuum_Current]]
                  • Set Void_Portal_On_Filter[Void_Portal_Current] = Nether Vacuum Filter <gen>
                  • Set Void_Portal_On_Spawn[Void_Portal_Current] = Nether Vacuum On Spawn <gen>
                  • Set Void_Portal_On_Death_Flag[Void_Portal_Current] = Nether Vacuum On Death Flag <gen>
                  • -------- Start the timer for the portal --------
                  • -------- Avoid the inconvenience of having to refer to a changed value of (Last Started Timer) --------
                  • Custom script: call TimerStart(udg_Nether_Vacuum_Closure_Timer[udg_Nether_Vacuum_Current], udg_NETHER_VACUUM_DURATION[udg_Nether_Vacuum_Level[udg_Nether_Vacuum_Current]], false, function NetherVacuumOnClose)
                • Else - Actions
            • Else - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • Nether_Vacuum_List_Mode[Nether_Vacuum_Current] Equal to 2
            • Then - Actions
              • -------- Unpause all the units in the unit group once the countdown has finished --------
              • Set Nether_Vacuum_Spawn_DelayTicks[Nether_Vacuum_Current] = (Nether_Vacuum_Spawn_DelayTicks[Nether_Vacuum_Current] - 1)
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • Nether_Vacuum_Spawn_DelayTicks[Nether_Vacuum_Current] Less than or equal to 0
                • Then - Actions
                  • -------- Destroy the group after this iteration --------
                  • Unit Group - Pick every unit in Nether_Vacuum_Spawn_Group[Nether_Vacuum_Current] and do (Actions)
                    • Loop - Actions
                      • Set Nether_Vacuum_Dummy_Enum_Unit = (Picked unit)
                      • Unit - Unpause Nether_Vacuum_Dummy_Enum_Unit
                      • Animation - Change Nether_Vacuum_Dummy_Enum_Unit's size to ((100.00 x (Unit: Nether_Vacuum_Dummy_Enum_Unit's Real Field: Scaling Value ('usca')))%, (100.00 x (Unit: Nether_Vacuum_Dummy_Enum_Unit's Real Field: Scaling Value ('usca')))%, (100.00 x (Unit: Nether_Vacuum_Dummy_Enum_Unit's Real Field: Scaling Value ('usca')))%) of its original size
                      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                        • If - Conditions
                          • NETHER_VACUUM_SPAWN_TIMED_LIFE[Nether_Vacuum_Level[Nether_Vacuum_Current]] Greater than 0.00
                        • Then - Actions
                          • Unit - Add a NETHER_VACUUM_SPAWN_TIMED_LIFE[Nether_Vacuum_Level[Nether_Vacuum_Current]] second Generic expiration timer to Nether_Vacuum_Dummy_Enum_Unit
                        • Else - Actions
                  • Custom script: call DestroyGroup(udg_Nether_Vacuum_Spawn_Group[udg_Nether_Vacuum_Current])
                  • -------- Deallocate the instance here --------
                  • Set Nether_Vacuum_Alloc[Nether_Vacuum_Current] = Nether_Vacuum_Alloc[0]
                  • Set Nether_Vacuum_Alloc[0] = Nether_Vacuum_Current
                  • -------- Remove this instance from the list --------
                  • Set Nether_Vacuum_Next[Nether_Vacuum_Prev[Nether_Vacuum_Current]] = Nether_Vacuum_Next[Nether_Vacuum_Current]
                  • Set Nether_Vacuum_Prev[Nether_Vacuum_Next[Nether_Vacuum_Current]] = Nether_Vacuum_Prev[Nether_Vacuum_Current]
                  • Set Nether_Vacuum_List_Mode[Nether_Vacuum_Current] = 0
                  • -------- Nullify all used parameters --------
                  • Set Nether_Vacuum_Accel_Z[Nether_Vacuum_Current] = 0.00
                  • Set Nether_Vacuum_Veloc_Z[Nether_Vacuum_Current] = 0.00
                  • Set Nether_Vacuum_Spawn_DelayTicks[Nether_Vacuum_Current] = 0
                  • Set Nether_Vacuum_Spawn_TicksMax[Nether_Vacuum_Current] = 0
                  • Set Nether_Vacuum_Spawn_CurScale[Nether_Vacuum_Current] = 0.00
                  • Set Nether_Vacuum_Level[Nether_Vacuum_Current] = 0
                  • Set Nether_Vacuum_Caster[Nether_Vacuum_Current] = No unit
                  • Custom script: set udg_Nether_Vacuum_Spawn_Group[udg_Nether_Vacuum_Current] = null
                • Else - Actions
                  • Set Nether_Vacuum_Spawn_CurScale[Nether_Vacuum_Current] = (Nether_Vacuum_Spawn_CurScale[Nether_Vacuum_Current] + Nether_Vacuum_Veloc_Z[Nether_Vacuum_Current])
                  • Set Nether_Vacuum_Veloc_Z[Nether_Vacuum_Current] = (Nether_Vacuum_Veloc_Z[Nether_Vacuum_Current] + (Nether_Vacuum_Accel_Z[Nether_Vacuum_Current] x 2.00))
                  • Unit Group - Pick every unit in Nether_Vacuum_Spawn_Group[Nether_Vacuum_Current] and do (Actions)
                    • Loop - Actions
                      • Set Nether_Vacuum_Dummy_Enum_Unit = (Picked unit)
                      • Animation - Change Nether_Vacuum_Dummy_Enum_Unit's size to (((100.00 x Nether_Vacuum_Spawn_CurScale[Nether_Vacuum_Current]) x (Unit: Nether_Vacuum_Dummy_Enum_Unit's Real Field: Scaling Value ('usca')))%, ((100.00 x Nether_Vacuum_Spawn_CurScale[Nether_Vacuum_Current]) x (Unit: Nether_Vacuum_Dummy_Enum_Unit's Real Field: Scaling Value ('usca')))%, ((100.00 x Nether_Vacuum_Spawn_CurScale[Nether_Vacuum_Current]) x (Unit: Nether_Vacuum_Dummy_Enum_Unit's Real Field: Scaling Value ('usca')))%) of its original size
            • Else - Actions
          • -------- Ensure that the loop does not terminate --------
          • Set Nether_Vacuum_Dummy_Var = (Nether_Vacuum_Dummy_Var - 1)
          • Set Nether_Vacuum_Current = Nether_Vacuum_Next[Nether_Vacuum_Current]
          • -------- Destroy the locations --------
          • Custom script: call RemoveLocation(udg_Nether_Vacuum_Dummy_Loc[0])
          • Custom script: call RemoveLocation(udg_Nether_Vacuum_Dummy_Loc[1])
          • -------- Update the coordinates of each dummy location --------
          • Set Nether_Vacuum_Dummy_Loc[0] = (Point((Position - X of Nether_Vacuum_Projectile_SFX[Nether_Vacuum_Current]), (Position - Y of Nether_Vacuum_Projectile_SFX[Nether_Vacuum_Current])))
          • Set Nether_Vacuum_Dummy_Loc[1] = (Nether_Vacuum_Dummy_Loc[0] offset by (NETHER_VACUUM_SPEED[Nether_Vacuum_Level[Nether_Vacuum_Current]] x NETHER_VACUUM_INTERVAL) towards (Nether_Vacuum_SFX_Yaw[Nether_Vacuum_Current] x (180.00 / Pi)) degrees)
          • Set Nether_Vacuum_Dummy_Loc[2] = Nether_Vacuum_Dummy_Loc[0]
          • Set Nether_Vacuum_Dummy_Loc[3] = Nether_Vacuum_Dummy_Loc[1]
      • Custom script: call RemoveLocation(udg_Nether_Vacuum_Dummy_Loc[0])
      • Custom script: call RemoveLocation(udg_Nether_Vacuum_Dummy_Loc[1])
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Nether_Vacuum_Prev[0] Equal to 0
        • Then - Actions
          • Countdown Timer - Pause Nether_Vacuum_Timer
        • Else - Actions
Handler Triggers
  • Nether Vacuum Filter
    • Events
    • Conditions
    • Actions
      • -------- Clearing this will cause the system to filter units that have already failed the filter. --------
      • Unit Group - Remove all units from Void_Portal_Exclude_Group[Void_Portal_Current]
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Or - Any (Conditions) are true
            • Conditions
              • Void_Portal_Enum_Unit Equal to Void_Portal_Caster[Void_Portal_Current]
              • (Void_Portal_Enum_Unit is A structure) Equal to True
              • (Void_Portal_Enum_Unit is hidden) Equal to True
              • (Void_Portal_Enum_Unit is Magic Immune) Equal to True
              • (Void_Portal_Enum_Unit has buff Anti-magic Shell) Equal to True
              • (Void_Portal_Enum_Unit has buff Anti-magic Shell (Extra)) Equal to True
        • Then - Actions
          • -------- ... via this line --------
          • -------- Setting Void_Portal_Pass_Filter to False will exclude the unit from future searches. --------
          • Set Void_Portal_Pass_Filter = False
        • Else - Actions
  • Nether Vacuum On Spawn
    • Events
    • Conditions
    • Actions
      • Custom script: local integer lastCur = udg_Nether_Vacuum_Current
      • Set Nether_Vacuum_Current = Nether_Vacuum_Portal_Pointer[Void_Portal_Current]
      • Set Nether_Vacuum_Spawn_Group[Nether_Vacuum_Current] = (Last created unit group)
      • Set Nether_Vacuum_Spawn_DelayTicks[Nether_Vacuum_Current] = ((Integer((NETHER_VACUUM_SPAWNS_DELAY[Nether_Vacuum_Level[Nether_Vacuum_Current]] / NETHER_VACUUM_INTERVAL))) + 1)
      • Set Nether_Vacuum_Spawn_TicksMax[Nether_Vacuum_Current] = (Nether_Vacuum_Spawn_DelayTicks[Nether_Vacuum_Current] - 1)
      • -------- The lines below will facilitate growth simulation --------
      • Set ParabolaX[0] = 0.00
      • Set ParabolaX[1] = (Real(Nether_Vacuum_Spawn_TicksMax[Nether_Vacuum_Current]))
      • Set ParabolaZ[0] = 0.00
      • Set ParabolaZ[1] = 1.00
      • Set ParabolaZ_Max = NETHER_VACUUM_SPAWN_MAX_SCALE
      • Set Parabola_Veloc = 1.00
      • Set Parabola_Func_Id = 2
      • Trigger - Run Parabola Get Parameters <gen> (ignoring conditions)
      • -------- Reuse the members previously meant for projectile motion for unit scaling. --------
      • Set Nether_Vacuum_Veloc_Z[Nether_Vacuum_Current] = Parabola_Initial_Velocity
      • Set Nether_Vacuum_Accel_Z[Nether_Vacuum_Current] = Parabola_Initial_Acceleration
      • Set Nether_Vacuum_Spawn_CurScale[Nether_Vacuum_Current] = (ParabolaX[0] x 100.00)
      • -------- Rescale the units immediately on creation --------
      • Unit Group - Pick every unit in Nether_Vacuum_Spawn_Group[Nether_Vacuum_Current] and do (Actions)
        • Loop - Actions
          • Set Nether_Vacuum_Dummy_Enum_Unit = (Picked unit)
          • Animation - Change Nether_Vacuum_Dummy_Enum_Unit's size to (((100.00 x Nether_Vacuum_Spawn_CurScale[Nether_Vacuum_Current]) x (Unit: Nether_Vacuum_Dummy_Enum_Unit's Real Field: Scaling Value ('usca')))%, ((100.00 x Nether_Vacuum_Spawn_CurScale[Nether_Vacuum_Current]) x (Unit: Nether_Vacuum_Dummy_Enum_Unit's Real Field: Scaling Value ('usca')))%, ((100.00 x Nether_Vacuum_Spawn_CurScale[Nether_Vacuum_Current]) x (Unit: Nether_Vacuum_Dummy_Enum_Unit's Real Field: Scaling Value ('usca')))%) of its original size
          • Unit - Pause Nether_Vacuum_Dummy_Enum_Unit
      • -------- Clear pointer data after use --------
      • Set Nether_Vacuum_Portal_Pointer[Void_Portal_Current] = 0
      • Custom script: set udg_Nether_Vacuum_Current = lastCur
  • Nether Vacuum On Death Flag
    • Events
    • Conditions
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Void_Portal_Enum_Unit is A Hero) Equal to False
          • (Void_Portal_Enum_Unit belongs to an enemy of (Owner of Void_Portal_Caster[Void_Portal_Current])) Equal to True
        • Then - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • Void_Portal_Spawn_Count[Void_Portal_Current] Greater than or equal to NETHER_VACUUM_MAX_SPAWN_COUNT[Nether_Vacuum_Level[Nether_Vacuum_Portal_Pointer[Void_Portal_Current]]]
            • Then - Actions
              • Custom script: call NetherVacuumOnDestroy(udg_Nether_Vacuum_Portal_Pointer[udg_Void_Portal_Current])
            • Else - Actions
        • Else - Actions
          • Set Void_Portal_Do_Spawn = False
Custom Script: Nether Vacuum On Close
JASS:
function NetherVacuumOnDestroy takes integer i returns nothing
    //  Do not allow the Nether Vacuum to be destroyed (again) when the List Mode has been flagged
    //  for destruction.
    if (udg_Nether_Vacuum_List_Mode[i] != 0) or (udg_Nether_Vacuum_Alloc[i] != -1) then
        return
    endif
    //  -- Remove the reference from the timer first
    call RemoveSavedInteger(udg_Nether_Vacuum_Hashtable, 0, GetHandleId(udg_Nether_Vacuum_Closure_Timer[i]))
    //  -- Destroy the timer
    call PauseTimer(udg_Nether_Vacuum_Closure_Timer[i])
    call DestroyTimer(udg_Nether_Vacuum_Closure_Timer[i])
    //  -- Destroy the portal here.
    call DestroyVoidPortal(udg_Nether_Vacuum_Portal[i])
    set udg_Nether_Vacuum_Portal[i]                                     = 0
    //  -- Add the instance back to the list.
    set udg_Nether_Vacuum_Next[i]                                       = 0
    set udg_Nether_Vacuum_Prev[i]                                       = udg_Nether_Vacuum_Prev[0]
    set udg_Nether_Vacuum_Next[udg_Nether_Vacuum_Prev[i]]               = i
    set udg_Nether_Vacuum_Prev[udg_Nether_Vacuum_Next[i]]               = i
    set udg_Nether_Vacuum_List_Mode[i]                                  = 2
    //  -- Restart the timer if the timer was paused
    if udg_Nether_Vacuum_Prev[i] == 0 then
        //  A direct call to TimerStart would be appreciated here
        call TimerStart(udg_Nether_Vacuum_Timer, udg_NETHER_VACUUM_INTERVAL, true, null)
    endif
endfunction
//  -- Callback function for the Closure Timer
function NetherVacuumOnClose takes nothing returns nothing
    local integer i = LoadInteger(udg_Nether_Vacuum_Hashtable, 0, GetHandleId(GetExpiredTimer()))
    call NetherVacuumOnDestroy(i)
endfunction

  1. Copy the Void Portal Folder and the Parabola Folder.
  2. Paste these into your map.

Mythic for the wonderful models:


  • Arcade Bolt Psyche

  • Void Rift Purple
Links for the models are located below:

Arcade Bolts

Void Rifts

  • v.1.0 - Released. (Included How to install, and Changelog into the tabs. Integrated Credits into the tabs)
  • v.1.1 - Updated resource name to Void Portal System. Introduced Void_Portal_Do_Remove, Void_Portal_Attack_Type and Void_Portal_Damage_Type.
Previews
Contents

Nether Vacuum (Map)

The relatively large file size is due to my attempt at changing the minimap for the lobby screen, which was not successful (don't know how to do that :p)

A future update will allow users to modify attack type and damage type dealt as DPS damage, with default values being ATTACK_TYPE_NORMAL and DAMAGE_TYPE_UNIVERSAL respectively.

Furthermore, minor optimizations will be made when processing the damage event from DPS and death by system, and in processing unit movement such that SquareRoot is avoided.

The update will change the behavior in the way Void_Portal_Do_Spawn runs; A value of false will no longer remove the enumerated unit if it isn't a Hero (Heroes don't get removed by the system no matter the value of Void_Portal_Do_Spawn).

Instead, a new variable Void_Portal_Do_Remove will handle unit removal (if it isn't a Hero). If false, the unit will be hidden instead.
 
Last edited:
Top