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

Arrow of Death 1.6

AoDBanner.jpg


This spell requires Jass NewGen Pack:
http://www.thehelper.net/forums/showthread.php/73936-JASS-NewGen-Pack-1-5d




aodarea.png


Shoots an arrow towards every enemy ground unit on target area. If the unit dies by an arrow, it will be reanimated. There is a chance that the arrow will bounce once to nearby enemy ground unit.

Level 1 - 100 damage, 20 seconds, 20% chance.
Level 2 - 200 damage, 25 seconds, 40% chance.
Level 3 - 300 damage, 30 seconds, 60% chance.
Level 4 - 400 damage, 35 seconds, 80% chance.
Level 5 - 500 damage, 40 seconds, bounces.


aodtarget.png

Shoots an arrow that deals damage when reaching target enemy ground unit. If the unit dies by an arrow, it will be reanimated. There is a chance that the arrow will bounce once to nearby enemy ground unit.

Level 1 - 100 damage, 20 seconds, 20% chance.
Level 2 - 200 damage, 25 seconds, 40% chance.
Level 3 - 300 damage, 30 seconds, 60% chance.
Level 4 - 400 damage, 35 seconds, 80% chance.
Level 5 - 500 damage, 40 seconds, bounces.


JASS:
//TESH.scrollpos=17
//TESH.alwaysfold=0
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
  • AoD Init
    • Events
      • Map initialization
    • Conditions
    • Actions
      • -------- --------
      • -------- Animater (Unit): --------
      • Set AoD_Animater = Animate Dead
      • -------- Arrow of Death (Unit): --------
      • Set AoD_ArrowType = Arrow of Death
      • -------- To kill destructibles on arrow's way: --------
      • Set AoD_KillDestructibles = True
      • -------- Configure this to change arrow's damage: --------
      • Set AoD_DamagePerLevel = 100.00
      • -------- Configure this to change arrow's speed (notice 0.03 loop): --------
      • Set AoD_Speed = 18.00
      • -------- This is the effect when arrow moves: --------
      • Set AoD_Effect = Abilities\Spells\Undead\AnimateDead\AnimateDeadTarget.mdl
      • -------- This is the effect when arrow dies/bounces: --------
      • Set AoD_SecondaryEffect = Abilities\Spells\Undead\DeathCoil\DeathCoilSpecialArt.mdl
      • -------- This is the chance of arrow bouncing once, increasing every level. 0 for no bounce. --------
      • Set AoD_PercentPerLevel = 20
      • -------- Interval between moving effects: --------
      • Set AoD_EffectInterval = 10
      • -------- When true it spawns the AoD_Animator if the target dies by the arrow: --------
      • Set AoD_DeathFeature = True
      • -------- Move effect damage enabled: --------
      • Set AoD_Damage2Enabled = False
      • -------- Configure this to change arrow's move effect damage: --------
      • Set AoD_Damage2PerLevel = 50.00
      • -------- --------
  • AoD Run
    • Events
    • Conditions
    • Actions
      • -------- --------
      • Set AoD_IndexSize = (AoD_IndexSize + 1)
      • -------- --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • AoD_IndexSize Greater than AoD_IndexMaxSize
        • Then - Actions
          • Set AoD_Index[AoD_IndexSize] = AoD_IndexSize
          • Set AoD_IndexMaxSize = AoD_IndexSize
        • Else - Actions
      • -------- --------
      • Set TempInt = AoD_Index[AoD_IndexSize]
      • -------- --------
      • Set AoD_Caster[TempInt] = TempUnit
      • Set AoD_Target[TempInt] = TempUnit2
      • Set AoD_From = (Position of AoD_Caster[TempInt])
      • Set AoD_Angle = (Facing of AoD_Caster[TempInt])
      • Set AoD_Timing[TempInt] = 0
      • Set AoD_Damage[TempInt] = (AoD_DamagePerLevel x (Real((Level of AoD_Ability for AoD_Caster[TempInt]))))
      • Set AoD_Damage2[TempInt] = (AoD_Damage2PerLevel x (Real((Level of AoD_Ability for AoD_Caster[TempInt]))))
      • Set AoD_BounceChance[TempInt] = (AoD_PercentPerLevel x (Level of AoD_Ability for AoD_Caster[TempInt]))
      • -------- --------
      • Unit - Create 1 AoD_ArrowType for (Owner of AoD_Caster[TempInt]) at AoD_From facing AoD_Angle degrees
      • Set AoD_Arrow[TempInt] = (Last created unit)
      • Trigger - Turn on AoD Loop <gen>
      • -------- --------
      • Custom script: call RemoveLocation(udg_AoD_From)
      • -------- --------
  • AoD Loop
    • Events
      • Time - Every 0.03 seconds of game time
    • Conditions
    • Actions
      • -------- --------
      • For each (Integer TempInt) from 1 to AoD_IndexSize, do (Actions)
        • Loop - Actions
          • Set AoD_Loop = AoD_Index[TempInt]
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (AoD_Arrow[AoD_Loop] is alive) Equal to True
            • Then - Actions
              • -------- --------
              • -------- Setting the location of the arrow --------
              • Set AoD_From = (Position of AoD_Arrow[AoD_Loop])
              • Set AoD_DesirablePoint = (Position of AoD_Target[AoD_Loop])
              • Set AoD_Angle = (Angle from AoD_From to AoD_DesirablePoint)
              • Set AoD_To = (AoD_From offset by AoD_Speed towards AoD_Angle degrees)
              • -------- --------
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • AoD_Timing[AoD_Loop] Less than AoD_EffectInterval
                • Then - Actions
                  • Set AoD_Timing[AoD_Loop] = (AoD_Timing[AoD_Loop] + 1)
                • Else - Actions
                  • -------- --------
                  • -------- If the AoD_Timing equal to AoD_EffectInterval, it will spawn the moving effect --------
                  • Special Effect - Create a special effect at AoD_To using AoD_Effect
                  • Special Effect - Destroy (Last created special effect)
                  • -------- --------
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • AoD_Damage2Enabled Equal to True
                    • Then - Actions
                      • -------- --------
                      • -------- This will locate any nearby enemy --------
                      • Set TempGroup = (Units within 100.00 of AoD_To matching ((((Matching unit) is A structure) Equal to False) and ((((Matching unit) is A flying unit) Equal to False) and ((((Owner of (Matching unit)) is an enemy of (Owner of AoD_Caster[AoD_Loop])) Equal to True) and ((Matching
                      • -------- --------
                      • Unit Group - Pick every unit in TempGroup and do (Actions)
                        • Loop - Actions
                          • -------- This will damage nearby enemies --------
                          • Unit - Cause AoD_Caster[AoD_Loop] to damage (Picked unit), dealing AoD_Damage2[AoD_Loop] damage of attack type Spells and damage type Universal
                      • -------- --------
                      • Custom script: call DestroyGroup(udg_TempGroup)
                      • -------- --------
                    • Else - Actions
                  • -------- Reset the effect interval --------
                  • Set AoD_Timing[AoD_Loop] = 0
              • -------- Moving the arrow --------
              • Unit - Move AoD_Arrow[AoD_Loop] instantly to AoD_To, facing AoD_Angle degrees
              • -------- --------
              • -------- Destroying any nearby tree --------
              • Set AoD_Region = (Region centered at AoD_To with size (100.00, 100.00))
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • AoD_KillDestructibles Equal to True
                • Then - Actions
                  • Destructible - Pick every destructible in AoD_Region and do (Actions)
                    • Loop - Actions
                      • Custom script: if (IsDestructableTree(GetEnumDestructable())) then
                      • Destructible - Kill (Picked destructible)
                      • Custom script: endif
                • Else - Actions
              • -------- --------
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • (AoD_Region contains AoD_Target[AoD_Loop]) Equal to True
                • Then - Actions
                  • -------- Making the arrow "bounce" if possible --------
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • (Random integer number between 1 and 100) Less than or equal to AoD_BounceChance[AoD_Loop]
                    • Then - Actions
                      • -------- --------
                      • Special Effect - Create a special effect attached to the chest of AoD_Arrow[AoD_Loop] using AoD_SecondaryEffect
                      • Special Effect - Destroy (Last created special effect)
                      • Unit - Cause AoD_Caster[AoD_Loop] to damage AoD_Target[AoD_Loop], dealing AoD_Damage[AoD_Loop] damage of attack type Spells and damage type Universal
                      • -------- --------
                      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                        • If - Conditions
                          • AoD_DeathFeature Equal to True
                          • (AoD_Target[AoD_Loop] is dead) Equal to True
                        • Then - Actions
                          • -------- Death feature is the animate death ability casted by the second dummy unit --------
                          • Set TempPoint = (Position of AoD_Target[AoD_Loop])
                          • Unit - Create 1 AoD_Animater for (Owner of AoD_Caster[AoD_Loop]) at TempPoint facing Default building facing degrees
                          • Set TempUnit = (Last created unit)
                          • Unit - Order TempUnit to Undead Death Knight - Animate Dead
                          • Unit - Add a 1.00 second Generic expiration timer to TempUnit
                          • Custom script: call RemoveLocation(udg_TempPoint)
                        • Else - Actions
                      • -------- --------
                      • -------- Death feature is the animate death ability casted by the second dummy unit --------
                      • Set TempGroup = (Units within 400.00 of AoD_To matching ((((Matching unit) is A structure) Equal to False) and ((((Matching unit) is A flying unit) Equal to False) and ((((Owner of (Matching unit)) is an enemy of (Owner of AoD_Caster[AoD_Loop])) Equal to True) and ((Matching
                      • Set AoD_Target[AoD_Loop] = (Random unit from TempGroup)
                      • -------- Disabling the bounce --------
                      • Set AoD_BounceChance[AoD_Loop] = 0
                      • -------- --------
                      • Custom script: call DestroyGroup(udg_TempGroup)
                      • -------- --------
                      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                        • If - Conditions
                          • AoD_Target[AoD_Loop] Equal to No unit
                        • Then - Actions
                          • -------- --------
                          • Unit - Kill AoD_Arrow[AoD_Loop]
                          • -------- --------
                          • Skip remaining actions
                        • Else - Actions
                    • Else - Actions
                      • -------- --------
                      • Special Effect - Create a special effect attached to the chest of AoD_Arrow[AoD_Loop] using AoD_SecondaryEffect
                      • Special Effect - Destroy (Last created special effect)
                      • -------- --------
                      • Unit - Kill AoD_Arrow[AoD_Loop]
                      • Unit - Cause AoD_Caster[AoD_Loop] to damage AoD_Target[AoD_Loop], dealing AoD_Damage[AoD_Loop] damage of attack type Spells and damage type Universal
                      • -------- --------
                      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                        • If - Conditions
                          • AoD_DeathFeature Equal to True
                          • (AoD_Target[AoD_Loop] is dead) Equal to True
                        • Then - Actions
                          • -------- Death feature is the animate death ability casted by the second dummy unit --------
                          • Set TempPoint = (Position of AoD_Target[AoD_Loop])
                          • Unit - Create 1 AoD_Animater for (Owner of AoD_Caster[AoD_Loop]) at TempPoint facing Default building facing degrees
                          • Set TempUnit = (Last created unit)
                          • Unit - Order TempUnit to Undead Death Knight - Animate Dead
                          • Unit - Add a 1.00 second Generic expiration timer to TempUnit
                          • Custom script: call RemoveLocation(udg_TempPoint)
                        • Else - Actions
                      • -------- --------
                      • -------- Avoiding double damage --------
                      • Skip remaining actions
                      • -------- --------
                • Else - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • (AoD_Target[AoD_Loop] is dead) Equal to True
                • Then - Actions
                  • Special Effect - Create a special effect attached to the chest of AoD_Arrow[AoD_Loop] using AoD_SecondaryEffect
                  • Special Effect - Destroy (Last created special effect)
                  • Unit - Kill AoD_Arrow[AoD_Loop]
                  • Unit - Cause AoD_Caster[AoD_Loop] to damage AoD_Target[AoD_Loop], dealing AoD_Damage[AoD_Loop] damage of attack type Spells and damage type Universal
                • Else - Actions
              • -------- --------
              • Custom script: call RemoveRect(udg_AoD_Region)
              • Custom script: call RemoveLocation(udg_AoD_From)
              • Custom script: call RemoveLocation(udg_AoD_To)
              • Custom script: call RemoveLocation(udg_AoD_DesirablePoint)
              • -------- --------
            • Else - Actions
              • -------- --------
              • -------- Dynamic stuff --------
              • Set AoD_Index[TempInt] = AoD_Index[AoD_IndexSize]
              • Set AoD_Index[AoD_IndexSize] = AoD_Loop
              • Set AoD_IndexSize = (AoD_IndexSize - 1)
              • Set TempInt = (TempInt - 1)
              • -------- --------
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • AoD_IndexSize Equal to 0
                • Then - Actions
                  • Trigger - Turn off (This trigger)
                  • Skip remaining actions
                • Else - Actions
      • -------- --------
  • AoD Target
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Arrow of Death (Target)
    • Actions
      • -------- Arrow of Death (Ability): --------
      • Set AoD_Ability = Arrow of Death (Target)
      • -------- --------
      • Set TempUnit = (Triggering unit)
      • Set TempUnit2 = (Target unit of ability being cast)
      • Trigger - Run AoD Run <gen> (ignoring conditions)
      • -------- --------
  • AoD Area
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Arrow of Death (Area)
    • Actions
      • -------- Arrow of Death (Ability): --------
      • Set AoD_Ability = Arrow of Death (Area)
      • -------- --------
      • Set TempReal = (250.00 + (50.00 x (Real((Level of AoD_Ability for (Triggering unit))))))
      • Set TempPoint = (Target point of ability being cast)
      • Set TempGroup = (Units within TempReal of TempPoint)
      • Unit Group - Pick every unit in TempGroup and do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • ((Owner of (Picked unit)) is an enemy of (Owner of (Triggering unit))) Equal to True
              • ((Picked unit) is A flying unit) Equal to False
              • ((Picked unit) is A structure) Equal to False
            • Then - Actions
              • Set TempUnit = (Triggering unit)
              • Set TempUnit2 = (Picked unit)
              • Trigger - Run AoD Run <gen> (ignoring conditions)
            • Else - Actions
      • Custom script: call DestroyGroup(udg_TempGroup)
      • Custom script: call RemoveLocation(udg_TempPoint)
      • -------- --------


Update 1.1: Fixed some leaks and added animate dead.
Update 1.2: Fixed a leak, added tree detection system (by PitzerMike) and boolean for animate dead.
Update 1.3: Added damage to moving effect.
Update 1.4: Removed the Or condition when checking if the region contains AoD_Target because there is only one condition, Replaced Run AOD (checking conditions) with Run AOD (ignoring conditions).
Update 1.5: Now uses the dynamic indexing. (Damn it was hard to learn that :D)
Update 1.6: Added comments to loop trigger, uploaded 2 screenshots and removed invulnerable ability from dummies (they dont need it).


Screenshot by mateuspv

Keywords:
arrow, dark, undead, death, coil, ranger
Contents

Just another Warcraft III map (Map)

Reviews
19 Dec 2011 Bribe: Thank you for applying all the previous recommendations. I'll approve this with a 3.5/5 (semi-recommended) status. Please change your indexing method for a better score to something like this: Hanky's Dynamic Indexing

Moderator

M

Moderator

19 Dec 2011
Bribe: Thank you for applying all the previous recommendations. I'll approve this with a 3.5/5 (semi-recommended) status. Please change your indexing method for a better score to something like this: Hanky's Dynamic Indexing
 
Troll-spell? This must be H4XXXX!11!1!11!!1!!1!!!1!!!1!1
did u yuse majnits 2 cryeat it,!..??

edit

On a serious note:

Tips:
- Referencing the same function (Anything that's not a variable) is inefficient and sloppy. In your cast trigger, you should the Triggering unit into some temporary unit variable (TempUnit)
- "Unit Group - Pick every unit in (Units within TempReal of (Target point of ability being cast)) and do (Actions)" -> This leaks the target point.
- Your indexing may be fast, but it's not the best ;/
You can use Dynamic Indexing instead (Hanky has a tutorial)
- "Set AoD_Target[AoD_Loop] = (Random unit from (Units within 400.00 of AoD_To matching (((Matching unit) Not equal to AoD_Target[AoD_Loop]) and (((AoD_Target[AoD_Loop] is A flying unit) Equal to False) and (((AoD_Target[AoD_Loop] is A structure) Equal to False) and (((Owner of (Matching"
You're leaking a group here.
You should set "Units in bla bla bla" into a group variable and destroy it later.
 
Level 6
Joined
Dec 8, 2009
Messages
165
Troll-spell? This must be H4XXXX!11!1!11!!1!!1!!!1!!!1!1
did u yuse majnits 2 cryeat it,!..??

I will get a proper screenshot when its possible. Not a troll spell. I just put the troll face to preview image, because hiveworkshop requires one in order to upload stuff :D

Edit: i will fix those leaks later, but im not going to use system when im learning indexing. Thanks for telling about leaks, im always too tired to check for leaks.

Edit2: Fixed
 
Last edited:
Top