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

Javelin Toss v1.00

This bundle is marked as useful / simple. Simplicity is bliss, low effort and/or may contain minor bugs.
  • Like
Reactions: Riven and IcemanBo
A spear that deals (125/150/175/200% Agi + 80/160/240/320) damage to the first unit it hits, which increases up to 300% based on distance traveled.

  • Javelin Toss Setup
    • Events
      • Map initialization
    • Conditions
    • Actions
      • -------- --------------------------------------------------- --------
      • -------- Ability --------
      • -------- --------------------------------------------------- --------
      • Set Cnfg_JT_Ability = Javelin Toss
      • -------- --------------------------------------------------- --------
      • -------- Acceleration Per Second --------
      • -------- --------------------------------------------------- --------
      • Set Cnfg_JT_Acceleration = 25.00
      • -------- --------------------------------------------------- --------
      • -------- Agility Bonus % Damage Per Level --------
      • -------- --------------------------------------------------- --------
      • Set Cnfg_JT_AgilityRatio[1] = 1.25
      • Set Cnfg_JT_AgilityRatio[2] = 1.50
      • Set Cnfg_JT_AgilityRatio[3] = 1.75
      • Set Cnfg_JT_AgilityRatio[4] = 2.00
      • -------- --------------------------------------------------- --------
      • -------- AoE aka Radius --------
      • -------- --------------------------------------------------- --------
      • Set Cnfg_JT_AoE = 100.00
      • -------- --------------------------------------------------- --------
      • -------- Attack Type --------
      • -------- --------------------------------------------------- --------
      • Set Cnfg_JT_AtkType = Spells
      • -------- --------------------------------------------------- --------
      • -------- Base damage per level --------
      • -------- --------------------------------------------------- --------
      • Set Cnfg_JT_DamagePL[1] = 80.00
      • Set Cnfg_JT_DamagePL[2] = 160.00
      • Set Cnfg_JT_DamagePL[3] = 240.00
      • Set Cnfg_JT_DamagePL[4] = 320.00
      • -------- --------------------------------------------------- --------
      • -------- When the damage starts increasing --------
      • -------- --------------------------------------------------- --------
      • Set Cnfg_JT_DistanceStart = 500.00
      • -------- --------------------------------------------------- --------
      • -------- Damage Type --------
      • -------- --------------------------------------------------- --------
      • Set Cnfg_JT_DmgType = Universal
      • -------- --------------------------------------------------- --------
      • -------- Dummy Unit Type --------
      • -------- --------------------------------------------------- --------
      • Set Cnfg_JT_DummyType = Dummy
      • -------- --------------------------------------------------- --------
      • -------- SFX when the Javelin hits --------
      • -------- --------------------------------------------------- --------
      • Set Cnfg_JT_EndFX = Abilities\Spells\Items\AIfb\AIfbSpecialArt.mdl
      • -------- --------------------------------------------------- --------
      • -------- Will Javelin Toss hit air units? --------
      • -------- --------------------------------------------------- --------
      • Set Cnfg_JT_HitAir = True
      • -------- --------------------------------------------------- --------
      • -------- Will Javelin Toss hit structures? --------
      • -------- --------------------------------------------------- --------
      • Set Cnfg_JT_HitStructs = True
      • -------- --------------------------------------------------- --------
      • -------- Increase in damage from DistanceStart --------
      • -------- to MaxDistance, in decimal --------
      • -------- --------------------------------------------------- --------
      • Set Cnfg_JT_MaxDmg = 2.00
      • -------- --------------------------------------------------- --------
      • -------- Max Distance for each Javelin --------
      • -------- --------------------------------------------------- --------
      • Set Cnfg_JT_MaxDist = 1300.00
      • -------- --------------------------------------------------- --------
      • -------- SFX Attachment Point --------
      • -------- --------------------------------------------------- --------
      • Set Cnfg_JT_SFXAttach = chest
      • -------- --------------------------------------------------- --------
      • -------- Base Speed of the Javelin, --------
      • -------- before Acceleration is applied --------
      • -------- --------------------------------------------------- --------
      • Set Cnfg_JT_StartSpeed = 350.00
      • -------- --------------------------------------------------- --------
      • -------- End of Configurables --------
      • -------- --------------------------------------------------- --------
      • Set Cnfg_JT_Acceleration = (Cnfg_JT_Acceleration / 32.00)
      • Set Cnfg_JT_StartSpeed = (Cnfg_JT_StartSpeed / 32.00)
      • -------- --------------------------------------------------- --------
      • Custom script: call TriggerRegisterTimerEvent(gg_trg_Javelin_Toss_Loop, 0.031250000, true)
  • Javelin Toss
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Cnfg_JT_Ability
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • JT_Index Equal to 0
        • Then - Actions
          • Trigger - Turn on Javelin Toss Loop <gen>
        • Else - Actions
      • -------- --------------------------------------------------- --------
      • -------- Generic info --------
      • -------- --------------------------------------------------- --------
      • Set JT_Index = (JT_Index + 1)
      • Set JT_Caster[JT_Index] = (Triggering unit)
      • -------- Catching the ability for use in the loop trigger. --------
      • Set B = (Level of Cnfg_JT_Ability for JT_Caster[JT_Index])
      • Set TempPoints[0] = (Target point of ability being cast)
      • Set TempPoints[1] = (Position of JT_Caster[JT_Index])
      • Set JT_Angle[JT_Index] = (Angle from TempPoints[1] to TempPoints[0])
      • Unit - Create 1 Cnfg_JT_DummyType for Neutral Passive at TempPoints[1] facing JT_Angle[JT_Index] degrees
      • Set JT_Dummy[JT_Index] = (Last created unit)
      • Set JT_Damage[JT_Index] = (((Real((Agility of JT_Caster[JT_Index] (Include bonuses)))) x Cnfg_JT_AgilityRatio[B]) + Cnfg_JT_DamagePL[B])
      • -------- Starting distance from caster. --------
      • Set JT_Distance[JT_Index] = 0.00
      • -------- Base speed of the missile, before Accel --------
      • Set JT_Speed[JT_Index] = Cnfg_JT_StartSpeed
      • Custom script: call RemoveLocation(udg_TempPoints[0])
      • Custom script: call RemoveLocation(udg_TempPoints[1])
  • Javelin Toss Loop
    • Events
    • Conditions
    • Actions
      • For each (Integer A) from 1 to JT_Index, do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • JT_Distance[A] Greater than or equal to Cnfg_JT_MaxDist
            • Then - Actions
              • Set JT_Caster[A] = No unit
              • Unit - Kill JT_Dummy[A]
              • Set JT_Angle[A] = JT_Angle[JT_Index]
              • Set JT_Caster[A] = JT_Caster[JT_Index]
              • Set JT_Damage[A] = JT_Damage[JT_Index]
              • Set JT_Distance[A] = JT_Distance[JT_Index]
              • Set JT_Dummy[A] = JT_Dummy[JT_Index]
              • Set JT_Speed[A] = JT_Speed[JT_Index]
              • Set JT_Index = (JT_Index - 1)
              • Set A = (A - 1)
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • JT_Index Equal to 0
                • Then - Actions
                  • Trigger - Turn off Javelin Toss Loop <gen>
                • Else - Actions
            • Else - Actions
              • Set JT_Speed[A] = (JT_Speed[A] + Cnfg_JT_Acceleration)
              • Set TempPoints[0] = (Position of JT_Dummy[A])
              • Set TempReals[0] = (JT_Speed[A] + JT_Distance[A])
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • (JT_Distance[A] + JT_Speed[A]) Greater than or equal to Cnfg_JT_MaxDist
                • Then - Actions
                  • Set TempPoints[1] = (TempPoints[0] offset by (Cnfg_JT_MaxDist - JT_Distance[A]) towards JT_Angle[A] degrees)
                • Else - Actions
                  • Set TempPoints[1] = (TempPoints[0] offset by JT_Speed[A] towards JT_Angle[A] degrees)
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • ((Playable map area) contains TempPoints[1]) Equal to True
                • Then - Actions
                  • Unit - Move JT_Dummy[A] instantly to TempPoints[1]
                  • Set TempPlayer = (Owner of JT_Caster[A])
                  • Set JT_Distance[A] = (JT_Speed[A] + JT_Distance[A])
                  • Set TempGroup = (Units within Cnfg_JT_AoE of TempPoints[1])
                  • Set TempReals[1] = Cnfg_JT_AoE
                  • Unit Group - Pick every unit in TempGroup and do (Actions)
                    • Loop - Actions
                      • Set TempUnits[0] = (Picked unit)
                      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                        • If - Conditions
                          • (TempUnits[0] is alive) Equal to True
                          • (TempUnits[0] belongs to an enemy of TempPlayer) Equal to True
                          • Or - Any (Conditions) are true
                            • Conditions
                              • (TempUnits[0] is A structure) Equal to Cnfg_JT_HitStructs
                              • Or - Any (Conditions) are true
                                • Conditions
                                  • (TempUnits[0] is A ground unit) Equal to True
                                  • (TempUnits[0] is A flying unit) Equal to Cnfg_JT_HitAir
                          • (Level of Invulnerable (Neutral) for TempUnits[0]) Equal to 0
                        • Then - Actions
                          • Set TempPoints[2] = (Position of TempUnits[0])
                          • Set TempReals[2] = (Distance between TempPoints[2] and TempPoints[1])
                          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                            • If - Conditions
                              • TempReals[2] Less than TempReals[1]
                            • Then - Actions
                              • Custom script: call RemoveLocation(udg_TempPoints[3])
                              • Set TempPoints[3] = (Position of TempUnits[1])
                              • Set TempReals[1] = TempReals[2]
                              • Set TempUnits[1] = TempUnits[0]
                            • Else - Actions
                          • Custom script: call RemoveLocation(udg_TempPoints[2])
                        • Else - Actions
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • TempUnits[1] Not equal to No unit
                    • Then - Actions
                      • -------- Do stuff to TempUnits[1] --------
                      • Set TempReals[3] = (((JT_Distance[A] - Cnfg_JT_DistanceStart) / (Cnfg_JT_MaxDist - Cnfg_JT_DistanceStart)) x Cnfg_JT_MaxDmg)
                      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                        • If - Conditions
                          • TempReals[3] Less than 0.00
                        • Then - Actions
                          • Set TempReals[3] = 0.00
                        • Else - Actions
                      • Set TempReals[3] = (TempReals[3] + 1.00)
                      • Unit - Cause JT_Caster[A] to damage TempUnits[1], dealing (JT_Damage[A] x TempReals[3]) damage of attack type Cnfg_JT_AtkType and damage type Cnfg_JT_DmgType
                      • Special Effect - Create a special effect attached to the Cnfg_JT_SFXAttach of TempUnits[1] using Cnfg_JT_EndFX
                      • Special Effect - Destroy (Last created special effect)
                      • Set JT_Distance[A] = Cnfg_JT_MaxDist
                      • -------- ---------------------------------- --------
                    • Else - Actions
                  • Custom script: call RemoveLocation(udg_TempPoints[3])
                  • Custom script: call DestroyGroup(udg_TempGroup)
                • Else - Actions
                  • Set JT_Distance[A] = Cnfg_JT_MaxDist
          • Custom script: call RemoveLocation(udg_TempPoints[0])
          • Custom script: call RemoveLocation(udg_TempPoints[1])
11/8/14 - Uploaded
11/17/14 - Updated


Keywords:
Javelin, Toss, Javelin Toss, Nidalee, Niggalee, Mr. Bean, Bean, Mr., Troll, Troll Toss, Troll Javelin Toss, Myth
Contents

Javelin Toss (Map)

Reviews
12th Dec 2015 IcemanBo: For long time as NeedsFix. Rejected. 17:24, 7th Jan 2015 IcemanBo: http://www.hiveworkshop.com/forums/spells-569/javelin-toss-v1-00-a-259254/#post2637135
Level 22
Joined
Sep 24, 2005
Messages
4,821
Having the starting fly-height configurable would be better too, if that's possible. Also, if you can, also factor in the target's height and adjust the spear height so that it wouldn't look like what mogul just described, at least with regards to the fly height (the model height isn't that easy to determine by triggers, or impossible, dunno really).
 
Should be changed:

  • Your iteration through nearby enemies may cause unwanted results, because you don't null "TempUnits[1]" in each iteration of your instances.
    Your condition to damage a unit is "TempUnits[1] Not equal to No unit", but you only null it only once in the end of your periodic.
  • Your unit groups leaks. You never destroy it.
  • Remove your points after usage, or at end of your iteration. But not only once in end of periodic trigger. Potential location leaks. (If index > 1)
  • Why do you use custom script for: Kill Dummy, null caster? .. You can do both with GUI. (when using GUI there should be as less as possible custom scripts)
  • Even if you don't damage an enemy you do still remove "TempPoint[3]" afterwards. No need to do so.

Optional performance optimizations:
  • variable[array] is not necessarily needed with so few indices, but may be your personal taste.
  • You can check the unit's position at top of loop, and then immediatly deinex if the dummy is out of PlayableMapArea.
  • OwnerOfCaster could be stored into a global variable.
  • PlayableMapArea could be stored into a global variable.
    • Custom script: set udg_TempUnits[0] = null
    ^This nulling seems redundant, as it will be used again, and again.

Configuration possibility looks very good. :thumbs_up:
Maybe it would be cleaner to post the code in spell description.
 
Your unit groups leaks. You never destroy it.
I missed that.
Remove your points after usage, or at end of your iteration. But not only once in end of periodic trigger. Potential location leaks.
Oh, right, I didn't notice that.
Why do you use custom script for: Kill Dummy, null caster? .. You can do both with GUI. (when using GUI there should be as less as possible custom scripts)
It's been like a custom for me to null/kill things in JASS. xD

But I will GUI-fy it.

Thanks for the review!
 
Level 2
Joined
Dec 9, 2014
Messages
7
Maybe my Warcraft is a bit old, but when I tested the map, it first turned out awesome. After quite a while, when the spear hit one of the enemies, the dummy suddenly stopped appearing. Very nice anyway 5/5!
 
  • Null Caster- and Dummy[MaxIndex] onDeindex.
  • Null TempUnits[1] must be nulled after usage. Else it brings unwanted results.
  • Only remove locations if they exist. And if they exist and you don't need them anymore remove them in same code-block.
  • Your temp variables don't really need to have an array.
  • Spells with not needed imports are prefered. Could you make the imports optional and just suggest to use them here in spell description? :)
  • Please add import instructions.
Needs Fix
 
Top