• 🏆 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!

Psychic Vortex v1.3

GUI, MUI and leakless [as far as I can tell]

Psychic Vortex

The Psychic creates a link between his mind and his target's, giving him full control over the target's body. He then starts a rotation prosses, turtning the target around the caster, damaging his mana and hp per second. All those who try to rescue the target are knocked back.

Level 1 - 10 Mana and 15 Health per second.
Level 2 - 20 Mana and 30 Health per second.
Level 3 - 30 Mana and 45 Health per second.

Duration: 4\5\6

v1.1
-> Used filters for the unit group
-> Removed big screenshot
-> Fixed the units getting knocked back even if unit is dead
-> Added documentation explaining everything I do.

v1.1b
-> Fixed destructible filters

v1.2
-> Added an "How to implement" Text
-> More configurable settings
-> Fixed name

v1.3
-> Fixed and improved description
-> When the was finished trees still got destroyed. Fixed that.
-> Previously forgot to connect the configurable "Speed" setting. Fixed


Keywords:
Mind, Psychic, Vortex, Float, Rotate, Spin, Purple, f0rsak3n, Psy, Fire, Nova, Ice, Holy.
Contents

Psychic Vortex (Map)

Reviews
15:37, 6th Jan 2010 The_Reborn_Devil: The triggering looks ok, and there are no leaks. You should try to filter out trees though. Status: Approved Rating: Useful

Moderator

M

Moderator

15:37, 6th Jan 2010
The_Reborn_Devil:
The triggering looks ok, and there are no leaks.
You should try to filter out trees though.

Status: Approved
Rating: Useful
 
Level 14
Joined
Nov 2, 2008
Messages
579
Will post triggers here shortly

Edit:
  • PM Start
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to (==) Psychic Vortex
    • Actions
      • -------- -------------------------------------------------------------------- --------
      • -------- IndexinG --------
        • Multiple FunctionsIf (All Conditions are True) then do (Then Actions) else do (Else Actions)
          • If - Conditions
            • PM_Index[1] Equal to (==) 0
          • Then - Actions
            • -------- -------------------------------------------------------------------- --------
            • -------- If no instances are currently running, we turn on the loop trigger --------
            • Trigger - Turn on PM Loop <gen>
          • Else - Actions
            • -------- -------------------------------------------------------------------- --------
            • -------- no else --------
      • -------- -------------------------------------------------------------------- --------
      • -------- Increase the indexes by one --------
      • Set PM_Index[1] = (PM_Index[1] + 1)
      • Set PM_Index[2] = (PM_Index[2] + 1)
      • -------- -------------------------------------------------------------------- --------
      • -------- The unit casting the spell --------
      • Set PM_Caster[PM_Index[2]] = (Triggering unit)
      • -------- -------------------------------------------------------------------- --------
      • -------- The unit being targeted --------
      • Set PM_Victim[PM_Index[2]] = (Target unit of ability being cast)
      • -------- -------------------------------------------------------------------- --------
      • -------- Ability level for the caster --------
      • Set PM_AbilityLevel[PM_Index[2]] = (Level of Psychic Vortex for (Triggering unit))
      • -------- -------------------------------------------------------------------- --------
      • -------- The owner of the caster --------
      • Set PM_Player[PM_Index[2]] = (Owner of (Triggering unit))
      • -------- -------------------------------------------------------------------- --------
      • -------- The duration of the spell --------
      • Set PM_Duration[PM_Index[2]] = (2.00 + (2.00 x (Real(PM_AbilityLevel[PM_Index[2]]))))
      • -------- -------------------------------------------------------------------- --------
      • -------- The mana damaged per second --------
      • Set PM_Mana[PM_Index[2]] = (10.00 x (Real(PM_AbilityLevel[PM_Index[2]])))
      • -------- -------------------------------------------------------------------- --------
      • -------- The damage done per second --------
      • Set PM_Damage[PM_Index[2]] = (15.00 x (Real(PM_AbilityLevel[PM_Index[2]])))
      • -------- -------------------------------------------------------------------- --------
      • -------- The Speed at witch the target rotates --------
      • Set PM_Speed[PM_Index[2]] = 3.00
      • -------- -------------------------------------------------------------------- --------
      • -------- The Speed at witch the units nearby are knocked back --------
      • Set PM_Speed2[PM_Index[2]] = -15.00
      • -------- -------------------------------------------------------------------- --------
      • -------- The locs of both targeted and casting unit. Will be used to set the distance between them --------
      • Set PM_Point[1] = (Position of PM_Victim[PM_Index[2]])
      • Set PM_Point[2] = (Position of PM_Caster[PM_Index[2]])
      • -------- -------------------------------------------------------------------- --------
      • -------- Setting the distance between them using the above 2 locs --------
      • Set PM_Distance[PM_Index[2]] = (Distance between PM_Point[1] and PM_Point[2])
      • -------- -------------------------------------------------------------------- --------
      • -------- Sets the angle so the targeted unit wont start rotating at a random location --------
      • Set PM_Angle[PM_Index[2]] = (Facing of (Triggering unit))
      • -------- -------------------------------------------------------------------- --------
      • -------- 2 Booleans. Change the "DestroyTrees" if you don't want trees to be destroyed. --------
      • Set PM_Boolean[PM_Index[2]] = True
      • Set PM_DestroyTrees[PM_Index[2]] = True
      • -------- -------------------------------------------------------------------- --------
      • -------- Turns collision off for the targeted unit so it won't look weird --------
      • Unit - Turn collision for PM_Victim[PM_Index[2]] Off
      • -------- -------------------------------------------------------------------- --------
      • -------- Clearing up leaks --------
      • Custom script: call RemoveLocation( udg_PM_Point[1] )
      • Custom script: call RemoveLocation( udg_PM_Point[2] )
  • PM Loop
    • Events
      • Time - Every 0.03 seconds of game time
    • Conditions
    • Actions
      • Do Multiple ActionsFor each (Integer PM_Index[3]) from 1 to PM_Index[2], do (Actions)
        • Loop - Actions
          • Multiple FunctionsIf (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • PM_Boolean[PM_Index[3]] Equal to (==) True
            • Then - Actions
              • -------- -------------------------------------------------------------------- --------
              • -------- Increases the Wait counter. Will be used to damage target --------
              • Set PM_WaitCounter[PM_Index[3]] = (PM_WaitCounter[PM_Index[3]] + PM_Speed[PM_Index[3]])
              • -------- -------------------------------------------------------------------- --------
              • -------- Decreases the duration, else the spell would be running for ever --------
              • Set PM_Duration[PM_Index[3]] = (PM_Duration[PM_Index[3]] - 0.03)
              • -------- -------------------------------------------------------------------- --------
              • -------- Increases the angle of witch the target will be rotating --------
              • Set PM_Angle[PM_Index[3]] = (PM_Angle[PM_Index[3]] + PM_Speed[PM_Index[3]])
              • -------- -------------------------------------------------------------------- --------
              • -------- We need the caster's position again since we destroyed it. --------
              • Set PM_Point[3] = (Position of PM_Caster[PM_Index[3]])
              • -------- -------------------------------------------------------------------- --------
              • -------- Very simple. This will be the position the target is rotating. Since we only increased the angle, he won't be moving backwords or forwards. Only side ways --------
              • Set PM_Point[4] = (PM_Point[3] offset by PM_Distance[PM_Index[3]] towards PM_Angle[PM_Index[3]] degrees)
              • -------- -------------------------------------------------------------------- --------
              • -------- This is the group getting knocked back when they draw near. --------
              • Set PM_Group[1] = (Units within 250.00 of PM_Point[4] matching (((PM_Victim[PM_Index[3]] is alive) Equal to (==) True) and ((((Matching unit) is alive) Equal to (==) True) and ((((Matching unit) is A structure) Equal to (==) False) and (((Matching unit) belongs to an enemy of
                • Multiple FunctionsIf (All Conditions are True) then do (Then Actions) else do (Else Actions)
                  • If - Conditions
                    • (PM_Victim[PM_Index[3]] is dead) Equal to (==) False
                  • Then - Actions
                    • -------- -------------------------------------------------------------------- --------
                    • -------- If the Victim isn't dead, we move him to the point mentioned earlier --------
                    • Unit - Move PM_Victim[PM_Index[3]] instantly to PM_Point[4], facing PM_Point[3]
                    • -------- -------------------------------------------------------------------- --------
                    • -------- This is the common effect applied to moving targets. Feel free to change it or add more --------
                    • Special Effect - Create a special effect attached to the origin of PM_Victim[PM_Index[3]] using Abilities\Weapons\AncientProtectorMissile\AncientProtectorMissile.mdl
                    • Special Effect - Destroy (Last created special effect)
                  • Else - Actions
                    • -------- -------------------------------------------------------------------- --------
                    • -------- no else --------
              • -------- -------------------------------------------------------------------- --------
              • -------- Picks every unit we set above --------
              • Unit Group - Pick every unit in PM_Group[1] and do (Actions)
                • Loop - Actions
                  • -------- -------------------------------------------------------------------- --------
                  • -------- Firstly we set the position of the picked unit since we will be moving him --------
                  • Set PM_Point[5] = (Position of (Picked unit))
                  • -------- -------------------------------------------------------------------- --------
                  • -------- Then the position of the victim --------
                  • Set PM_Point[6] = (Position of PM_Victim[PM_Index[3]])
                  • -------- -------------------------------------------------------------------- --------
                  • -------- Then the angle in witch they will be moving --------
                  • Set PM_Angle2[PM_Index[3]] = (Angle from PM_Point[5] to PM_Point[6])
                  • -------- -------------------------------------------------------------------- --------
                  • -------- Then the exact location --------
                  • Set PM_Point[7] = (PM_Point[5] offset by PM_Speed2[PM_Index[3]] towards PM_Angle2[PM_Index[3]] degrees)
                  • -------- -------------------------------------------------------------------- --------
                  • -------- Then we move the unit from the group to the point mentioned above --------
                  • Unit - Move (Picked unit) instantly to PM_Point[7]
                  • -------- -------------------------------------------------------------------- --------
                  • -------- Same effect as above --------
                  • Special Effect - Create a special effect attached to the origin of (Picked unit) using Abilities\Weapons\AncientProtectorMissile\AncientProtectorMissile.mdl
                  • Special Effect - Destroy (Last created special effect)
                  • -------- -------------------------------------------------------------------- --------
                  • -------- Clearing the leaks --------
                  • Custom script: call RemoveLocation( udg_PM_Point[5] )
                  • Custom script: call RemoveLocation( udg_PM_Point[6] )
                  • Custom script: call RemoveLocation( udg_PM_Point[7] )
              • -------- -------------------------------------------------------------------- --------
              • -------- Clearing the group leak we used above --------
              • Custom script: call DestroyGroup( udg_PM_Group[1] )
                • Multiple FunctionsIf (All Conditions are True) then do (Then Actions) else do (Else Actions)
                  • If - Conditions
                    • PM_DestroyTrees[PM_Index[3]] Equal to (==) True
                    • (PM_Victim[PM_Index[3]] is dead) Equal to (==) False
                  • Then - Actions
                    • -------- -------------------------------------------------------------------- --------
                    • -------- If you chose trees to be destroyed, then we pick every tree near the point of the victim --------
                    • Destructible - Pick every destructible within 150.00 of PM_Point[4] and do (Actions)
                      • Loop - Actions
                        • -------- -------------------------------------------------------------------- --------
                        • -------- We kill the tree --------
                        • Custom script: if IsDestructableTree(GetEnumDestructable()) then
                        • Destructible - Kill (Picked destructible)
                        • Custom script: endif
                  • Else - Actions
                    • -------- -------------------------------------------------------------------- --------
                    • -------- no else --------
              • -------- -------------------------------------------------------------------- --------
              • -------- Clearing the leaks we used in the beginning --------
              • Custom script: call RemoveLocation( udg_PM_Point[3] )
              • Custom script: call RemoveLocation( udg_PM_Point[4] )
                • Multiple FunctionsIf (All Conditions are True) then do (Then Actions) else do (Else Actions)
                  • If - Conditions
                    • PM_WaitCounter[PM_Index[3]] Greater than or equal to (>=) 1.00
                    • (PM_Victim[PM_Index[3]] is dead) Equal to (==) False
                  • Then - Actions
                    • -------- -------------------------------------------------------------------- --------
                    • -------- Resetting the wait counter --------
                    • Set PM_WaitCounter[PM_Index[3]] = 0.00
                    • -------- -------------------------------------------------------------------- --------
                    • -------- Damaging the victim --------
                    • Unit - Cause PM_Caster[PM_Index[3]] to damage PM_Victim[PM_Index[3]], dealing PM_Damage[PM_Index[3]] damage of attack type Spells and damage type Normal
                    • -------- -------------------------------------------------------------------- --------
                    • -------- Damaging his mana --------
                    • Unit - Set mana of PM_Victim[PM_Index[3]] to ((Mana of PM_Victim[PM_Index[3]]) - PM_Mana[PM_Index[3]])
                    • -------- -------------------------------------------------------------------- --------
                    • -------- Some eye candy --------
                    • Special Effect - Create a special effect attached to the origin of PM_Victim[PM_Index[3]] using Units\NightElf\Wisp\WispExplode.mdl
                    • Special Effect - Destroy (Last created special effect)
                  • Else - Actions
                • Multiple FunctionsIf (All Conditions are True) then do (Then Actions) else do (Else Actions)
                  • If - Conditions
                    • PM_Duration[PM_Index[3]] Less than or equal to (<=) 0.00
                  • Then - Actions
                    • -------- -------------------------------------------------------------------- --------
                    • -------- If the spell is over, we set the times it's running -1 and also change the boolean to false --------
                    • Set PM_Index[1] = (PM_Index[1] - 1)
                    • Set PM_Boolean[PM_Index[3]] = False
                    • -------- -------------------------------------------------------------------- --------
                    • -------- We turn collision back on --------
                    • Unit - Turn collision for PM_Victim[PM_Index[3]] On
                      • Multiple FunctionsIf (All Conditions are True) then do (Then Actions) else do (Else Actions)
                        • If - Conditions
                          • PM_Index[1] Equal to (==) 0
                        • Then - Actions
                          • -------- -------------------------------------------------------------------- --------
                          • -------- If no instances are running we reset the indexes --------
                          • Set PM_Index[2] = 0
                          • -------- -------------------------------------------------------------------- --------
                          • -------- No need for this trigger to keep running --------
                          • Trigger - Turn off (This trigger)
                        • Else - Actions
                          • -------- -------------------------------------------------------------------- --------
                          • -------- no else --------
                  • Else - Actions
                    • -------- -------------------------------------------------------------------- --------
                    • -------- no else --------
            • Else - Actions
              • -------- -------------------------------------------------------------------- --------
              • -------- no else --------
 
Last edited:
Level 19
Joined
Feb 25, 2009
Messages
2,004
- You are not destroying only the tree, this could bring down bridges as well. Find a script that filters other destructable objects and assign it.

- Here
  • Set PM_Group[1] = (Units within 250.00 of PM_Point[4])
You can filter out units, instead of using ITE function below.

- Improve your documenatation (trigger comments), all you do is "actions", "no else" and "leaks". Peoples need better explanation how the whole thing works.

- One screenshot is enough.
 
Level 25
Joined
Jun 5, 2008
Messages
2,572
Use this for destructable checking(Script written by PitzerMike) and just call it with a custom script:

JASS:
library DestructableLib initializer Initialization
//* ============================================================================ *
//* Made by PitzerMike                                                           *
//*                                                                              *
//* I made this to detect if a destructable is a tree or not. It works not only  *
//* for the standard trees but also for custom destructables created with the    *
//* object editor. It uses a footie as a dummy with the goul's harvest ability.  *
//* The dummy ids can be changed though. I also added the IsDestructableDead     *
//* function for completeness.                                                   *
//* ============================================================================ *

globals
    private constant integer DUMMY_UNIT_ID = 'hfoo' // footman
    private constant integer HARVEST_ID    = 'Ahrl' // ghouls harvest
    private constant player OWNING_PLAYER  = Player(15)
    
    private unit dummy = null
endglobals

function IsDestructableDead takes destructable dest returns boolean
    return GetDestructableLife(dest) <= 0.405
endfunction

function IsDestructableTree takes destructable dest returns boolean
    local boolean result = false
    if (dest != null) then
        call PauseUnit(dummy, false)
        set result = IssueTargetOrder(dummy, "harvest", dest)
        call PauseUnit(dummy, true) // stops order
    endif
    return result
endfunction

private function Initialization takes nothing returns nothing
    set dummy = CreateUnit(OWNING_PLAYER, DUMMY_UNIT_ID, 0.0, 0.0, 0.0)
    call ShowUnit(dummy, false) // cannot enumerate
    call UnitAddAbility(dummy, HARVEST_ID)
    call UnitAddAbility(dummy, 'Aloc') // unselectable, invulnerable
    call PauseUnit(dummy, true)
endfunction
endlibrary


Also use filters as mentioned above.
 
Level 25
Joined
Jun 5, 2008
Messages
2,572
First import the library in your map, then in here:
  • Destructible - Pick every destructible within 150.00 of PM_Point[4] and do (Actions)
Add this:
  • Custom script: if IsDestructableTree(GetEnumDestructable()) then
    • Destructible - Kill (Picked destructible)
  • Custom script: endif
Should work perfectly :)
 
Top