1. Are you planning to upload your awesome spell or system to Hive? Please review the rules here.
    Dismiss Notice
  2. Updated Resource Submission Rules: All model & skin resource submissions must now include an in-game screenshot. This is to help speed up the moderation process and to show how the model and/or texture looks like from the in-game camera.
    Dismiss Notice
  3. DID YOU KNOW - That you can unlock new rank icons by posting on the forums or winning contests? Click here to customize your rank or read our User Rank Policy to see a list of ranks that you can unlock. Have you won a contest and still havn't received your rank award? Then please contact the administration.
    Dismiss Notice
  4. The Lich King demands your service! We've reached the 19th edition of the Icon Contest. Come along and make some chilling servants for the one true king.
    Dismiss Notice
  5. The 4th SFX Contest has started. Be sure to participate and have a fun factor in it.
    Dismiss Notice
  6. The poll for the 21st Terraining Contest is LIVE. Be sure to check out the entries and vote for one.
    Dismiss Notice
  7. The results are out! Check them out.
    Dismiss Notice
  8. Don’t forget to sign up for the Hive Cup. There’s a 555 EUR prize pool. Sign up now!
    Dismiss Notice
  9. The Hive Workshop Cup contest results have been announced! See the maps that'll be featured in the Hive Workshop Cup tournament!
    Dismiss Notice
  10. Check out the Staff job openings thread.
    Dismiss Notice
Dismiss Notice
60,000 passwords have been reset on July 8, 2019. If you cannot login, read this.

Rush v1.05

Submitted by sniper_zero
This bundle is marked as approved. It works and satisfies the submission rules.
I don't know how useful you'll find this but this is a dash spell template. It was originally a request that I accepted to practice some documentation and configuration. I tried to make it as configurable as possible.

Configurables
Code (vJASS):
    //Configurables
    integer Rush = 'A000' //This is the ability id the spell uses. Change it after copying the trigger.
    real Speed = 1150 //This is the speed of the caster when he uses the spell.
    real Interval = .03 //How often you want the timer to run.
    real Range = 175 //How close units should be to be damaged by the spell.
    boolean UnitOrSfx = false //This decides if you want to use a dummy unit or sfx as the well...sfx of the spell. False for sfx, true for dummy unit.
    integer Transparency = 80 //How transparent you want the dummy to be.
    integer RushDummy = 'e001' // This is the id of the dummy unit created.
    real Lifespan = 0.5 // Life span of the dummy.
    string Sfx = "Abilities\\Spells\\Orc\\MirrorImage\\MirrorImageCaster.mdl" //The sfx that appears when the caster dashes.
    string Animation = "stand ready" //What animation plays when the caster dashes.
    real DamageBase = 75 //This is the base damage which will be multiplied by the ability level.
    integer R = 255 //This is the red value for the dummy unit.
    integer G = 255 //This is the blue value for the dummy unit.
    integer B = 255 //This is the green value for the dummy unit.
    real AbilDist = 200 //This is the distance that scales per level of ability. Set BonusDist to 0 if you want a pure level based distance.
    real BonusDist = 200 // This is the bonus distance. Set AbilDist to 0 if you want constant distant.
    attacktype AttackType = ATTACK_TYPE_CHAOS //The attack type.
    damagetype DamageType = DAMAGE_TYPE_UNIVERSAL //The damage type. They're both currently set to these configurations to allow easy testing.


Updated changelog

v1.04 - The issues Doomlord and watermelon_1234 pointed out have been addressed.
v1.05 - Uses IsUnitType and GetUnitTypeId for checking dead units now.




Import Instructions

-----------------------------------
-Importing Instructions-
-----------------------------------

1. Copy the script found in the map header, Mikagami Spells.
2. Paste it into your own map header.
3. Copy the hashtable variable Rush_Hash in the variable editor or make your own and name it Rush_Hash.
4. Copy the trigger Rush. Copy the trigger Rush Dummy Dies.
5. Either copy the dummy ability and dummy units or make your own.
6. Press ctrl + d and look at the id of the dummies.
7. Replace 'A000' with the correct id.
8. Replace 'e001' with the correct id.
8. Save your map and test it.

Note: You need Jass NewGen Pack for this to work.
Note: It is EXTREMELY important that you copy the script in the map header. That script prevents any bugs and is essential for this spell to work.
Note: You might want to enable the DebugMsg to see for yourself if the spell is MUI. Just remove the "//".


Spell Description

Rush

Dash forward with an ungodly speed, dealing damage to enemy units in a line. Distance moved increases with each level of the ability.


LEVELS
Level 1: Deals 75 damage.
Level 2: Deals 150 damage.
Level 3: Deals 225 damage.


SAMPLE IMAGES

CHANGELOGS: v1.00 - Initial Release
v1.01 - Destroys g at the end, Doesn't save g every time, Lifespan is now configurable,
removed == false and true, converted facing to radians at the start, rempved cx, cy, tx, and ty using the natives of cos and sin.
v1.02 - Distance and damage are now configurable. Removed the variables count and duration. You stay in your current position if you try to pass through impassable terrain. Made configurable filter, damage and distance functions.
v1.03 - Fixed more of the issues Doomlord pointed out.
v1.04 - The issues Doomlord and watermelon_1234 pointed out have been addressed.
v1.05 - Uses IsUnitType and GetUnitTypeId for checking dead units now.

Credits: doomhammer99 - Spell description template.
Rising_Dusk - Terrain pathability check.
Weep - For GDD which is used to test this spell.
Hive - For teaching how to make spells.

  • Code (vJASS):

    library TerrainPathability initializer Init
    //******************************************************************************
    //* BY: Rising_Dusk
    //*
    //* This script can be used to detect the type of pathing at a specific point.
    //* It is valuable to do it this way because the IsTerrainPathable is very
    //* counterintuitive and returns in odd ways and aren't always as you would
    //* expect. This library, however, facilitates detecting those things reliably
    //* and easily.
    //*
    //******************************************************************************
    //*
    //*    > function IsTerrainDeepWater    takes real x, real y returns boolean
    //*    > function IsTerrainShallowWater takes real x, real y returns boolean
    //*    > function IsTerrainLand         takes real x, real y returns boolean
    //*    > function IsTerrainPlatform     takes real x, real y returns boolean
    //*    > function IsTerrainWalkable     takes real x, real y returns boolean
    //*
    //* These functions return true if the given point is of the type specified
    //* in the function's name and false if it is not. For the IsTerrainWalkable
    //* function, the MAX_RANGE constant below is the maximum deviation range from
    //* the supplied coordinates that will still return true.
    //*
    //* The IsTerrainPlatform works for any preplaced walkable destructable. It will
    //* return true over bridges, destructable ramps, elevators, and invisible
    //* platforms. Walkable destructables created at runtime do not create the same
    //* pathing hole as preplaced ones do, so this will return false for them. All
    //* other functions except IsTerrainWalkable return false for platforms, because
    //* the platform itself erases their pathing when the map is saved.
    //*
    //* After calling IsTerrainWalkable(x, y), the following two global variables
    //* gain meaning. They return the X and Y coordinates of the nearest walkable
    //* point to the specified coordinates. These will only deviate from the
    //* IsTerrainWalkable function arguments if the function returned false.
    //*
    //* Variables that can be used from the library:
    //*     [real]    TerrainPathability_X
    //*     [real]    TerrainPathability_Y
    //*
    globals
        private constant real    MAX_RANGE     = 10.
        private constant integer DUMMY_ITEM_ID = 'wolg'
    endglobals

    globals    
        private item       Item   = null
        private rect       Find   = null
        private item array Hid
        private integer    HidMax = 0
        public  real       X      = 0.
        public  real       Y      = 0.
    endglobals

    function IsTerrainDeepWater takes real x, real y returns boolean
        return not IsTerrainPathable(x, y, PATHING_TYPE_FLOATABILITY) and IsTerrainPathable(x, y, PATHING_TYPE_WALKABILITY)
    endfunction
    function IsTerrainShallowWater takes real x, real y returns boolean
        return not IsTerrainPathable(x, y, PATHING_TYPE_FLOATABILITY) and not IsTerrainPathable(x, y, PATHING_TYPE_WALKABILITY) and IsTerrainPathable(x, y, PATHING_TYPE_BUILDABILITY)
    endfunction
    function IsTerrainLand takes real x, real y returns boolean
        return IsTerrainPathable(x, y, PATHING_TYPE_FLOATABILITY)
    endfunction
    function IsTerrainPlatform takes real x, real y returns boolean
        return not IsTerrainPathable(x, y, PATHING_TYPE_FLOATABILITY) and not IsTerrainPathable(x, y, PATHING_TYPE_WALKABILITY) and not IsTerrainPathable(x, y, PATHING_TYPE_BUILDABILITY)
    endfunction

    private function HideItem takes nothing returns nothing
        if IsItemVisible(GetEnumItem()) then
            set Hid[HidMax] = GetEnumItem()
            call SetItemVisible(Hid[HidMax], false)
            set HidMax = HidMax + 1
        endif
    endfunction
    function IsTerrainWalkable takes real x, real y returns boolean
        //Hide any items in the area to avoid conflicts with our item
        call MoveRectTo(Find, x, y)
        call EnumItemsInRect(Find ,null, function HideItem)
        //Try to move the test item and get its coords
        call SetItemPosition(Item, x, y) //Unhides the item
        set X = GetItemX(Item)
        set Y = GetItemY(Item)
        static if LIBRARY_IsTerrainWalkable then
            //This is for compatibility with the IsTerrainWalkable library
            set IsTerrainWalkable_X = X
            set IsTerrainWalkable_Y = Y
        endif
        call SetItemVisible(Item, false)//Hide it again
        //Unhide any items hidden at the start
        loop
            exitwhen HidMax <= 0
            set HidMax = HidMax - 1
            call SetItemVisible(Hid[HidMax], true)
            set Hid[HidMax] = null
        endloop
        //Return walkability
        return (X-x)*(X-x)+(Y-y)*(Y-y) <= MAX_RANGE*MAX_RANGE and not IsTerrainPathable(x, y, PATHING_TYPE_WALKABILITY)
    endfunction

    private function Init takes nothing returns nothing
        set Find = Rect(0., 0., 128., 128.)
        set Item = CreateItem(DUMMY_ITEM_ID, 0, 0)
        call SetItemVisible(Item, false)
    endfunction
    endlibrary
     
  • Code (vJASS):

    //This part is where you can configure the spell.
    globals
        //Configurables
        integer Rush = 'A000' //This is the ability id the spell uses. Change it after copying the trigger.
        real Speed = 1150 //This is the speed of the caster when he uses the spell.
        real Interval = .03 //How often you want the timer to run.
        real Range = 175 //How close units should be to be damaged by the spell.
        boolean UnitOrSfx = false //This decides if you want to use a dummy unit or sfx as the well...sfx of the spell. False for sfx, true for dummy unit.
        integer Transparency = 80 //How transparent you want the dummy to be.
        integer RushDummy = 'e001' // This is the id of the dummy unit created.
        real Lifespan = 0.5 // Life span of the dummy.
        string Sfx = "Abilities\\Spells\\Orc\\MirrorImage\\MirrorImageCaster.mdl" //The sfx that appears when the caster dashes.
        string Animation = "stand ready" //What animation plays when the caster dashes.
        real DamageBase = 75 //This is the base damage which will be multiplied by the ability level.
        integer R = 255 //This is the red value for the dummy unit.
        integer G = 255 //This is the blue value for the dummy unit.
        integer B = 255 //This is the green value for the dummy unit.
        real AbilDist = 200 //This is the distance that scales per level of ability. Set BonusDist to 0 if you want a pure level based distance.
        real BonusDist = 200 // This is the bonus distance. Set AbilDist to 0 if you want constant distant.
        attacktype AttackType = ATTACK_TYPE_CHAOS //The attack type.
        damagetype DamageType = DAMAGE_TYPE_UNIVERSAL //The damage type. They're both currently set to these configurations to allow easy testing.
       
        //Non-configurables
        group RushGroup = CreateGroup() //Don't touch this. Don't null or destroy this.
        real Offset = Speed * Interval //How far the caster moves per interval.
    endglobals

    //------Configurable functions------//

    //Configure the conditions for group check here
    function UnitCheck takes unit caster, unit u returns boolean
        return IsUnitEnemy(u, GetOwningPlayer(caster)) and not (IsUnitType(u, UNIT_TYPE_DEAD) and GetUnitTypeId != 0) and IsUnitType(u, UNIT_TYPE_GROUND) and not IsUnitType(u, UNIT_TYPE_STRUCTURE)
    endfunction

    //The Damage formula for the ability.
    function Damage takes unit caster, integer Rush, real BaseDamage returns real
        return GetUnitAbilityLevel(caster, Rush) * BaseDamage
    endfunction

    //Formula for the maximum distance. If you only want the ability to affect distance, set BonusDist to 0.
    function MaximumDistance takes unit caster, integer Rush, real AbilDist, real BonusDist returns real
        return GetUnitAbilityLevel(caster, Rush) * AbilDist + BonusDist
    endfunction
    //---End of Configurable functions---//
     

    function Rush_Periodic takes nothing returns nothing
        //Local Variable Setup
        local timer t = GetExpiredTimer()
        local integer id = GetHandleId(t)
        local unit caster = LoadUnitHandle(udg_Rush_Hash, id, 0)
        local real facing = LoadReal(udg_Rush_Hash, id, 1)
        local real cur_dist = LoadReal(udg_Rush_Hash, id, 2)
        local group g = LoadGroupHandle(udg_Rush_Hash, id, 3)
        local real x = GetUnitX(caster)
        local real y = GetUnitY(caster)
        local real x1 = x + Offset * Cos(facing)
        local real y1 = y + Offset * Sin(facing)
        local player owner = GetOwningPlayer(caster)
        local unit dummy
        local unit u
        local real damage = Damage(caster, Rush, DamageBase) //You can change this to whatever you want.
        local real MaxDistance = MaximumDistance(caster, Rush, AbilDist, BonusDist) //This makes the distance you dash scale with the level.
       
       
        if cur_dist < MaxDistance then
            call SetUnitAnimation(caster, Animation)
            if not UnitOrSfx then
                call DestroyEffect(AddSpecialEffect(Sfx, x, y))
            else
                set dummy = CreateUnit(owner, RushDummy, x, y, facing)
                call SetUnitAnimation(dummy, Animation)
                call SetUnitVertexColor(dummy, R, G, B, Transparency)
                call UnitApplyTimedLife(dummy, 'BTLF', Lifespan)
                set dummy = null
            endif
            call GroupEnumUnitsInRange(RushGroup, x, y, Range, null)
            loop //What we do here is check if the target is in g. If not, then we damage it and add it to g to prevent it from being damaged again.
                set u = FirstOfGroup(RushGroup)
                exitwhen u == null
                if not IsUnitInGroup(u, g) and UnitCheck(caster, u) then
                    call UnitDamageTarget(caster, u, damage, false, false, AttackType, DamageType, null)
                    call GroupAddUnit(g, u)
                endif
                call GroupRemoveUnit(RushGroup, u)
            endloop
            if IsTerrainWalkable(x1, y1) then //If the terrain is passable the you'll dash, if not then trigger ends.
                call SetUnitX(caster, x1)
                call SetUnitY(caster, y1)
                set cur_dist = cur_dist + Offset //This counts how many times you've moved.
                call SaveReal(udg_Rush_Hash, id, 2, cur_dist)
            else
                call PauseTimer(t)
                call DestroyTimer(t)
                call DestroyGroup(g)
                call SetUnitAnimation(caster, "stand") //Resets the animation.
                call FlushChildHashtable(udg_Rush_Hash, id)
            endif
        else
            call PauseTimer(t)
            call DestroyTimer(t)
            call DestroyGroup(g)
            call SetUnitAnimation(caster, "stand") //Resets the animation.
            call FlushChildHashtable(udg_Rush_Hash, id)
        endif
       
        //Nulling
        set t = null
        set caster = null
        set g = null
    endfunction

    function Rush_Actions takes nothing returns nothing
        //Local Variable Setup
        local timer t = CreateTimer()
        local integer id = GetHandleId(t)
        local unit caster = GetTriggerUnit()
        local real dx = GetSpellTargetX() - GetUnitX(caster)
        local real dy = GetSpellTargetY() - GetUnitY(caster)
        local real dist_check = (dx*dx) + (dy*dy)
        local real facing
       
        //A little distance check to avoid bugs when you cast the spell in your current position.
        if dist_check <= 100 * 100 then
            set facing = GetUnitFacing(caster) * bj_DEGTORAD
        else
            set facing = (Atan2(dy, dx))
        endif
       
        //Hashtable Setup
        call SaveUnitHandle(udg_Rush_Hash, id, 0, caster)
        call SaveReal(udg_Rush_Hash, id, 1, facing)
        call SaveReal(udg_Rush_Hash, id, 2, 0)
        call SaveGroupHandle(udg_Rush_Hash, id, 3, CreateGroup())
        //End Hashtable Setup
       
        call TimerStart(t, Interval, true, function Rush_Periodic)
       
        //Nulling
        set t = null
        set caster = null
    endfunction

    function Rush_Conditions takes nothing returns boolean
        if GetSpellAbilityId() == Rush then
            call Rush_Actions()
        endif
        return false
    endfunction

    //===========================================================================
    function InitTrig_Rush takes nothing returns nothing
        local trigger t = CreateTrigger(  )
        call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_SPELL_EFFECT )
        call TriggerAddCondition( t, Condition( function Rush_Conditions) )
        set udg_Rush_Hash = InitHashtable()
        set t = null
    endfunction
     
    • Rush Dummy Dies
      • Events
        • Unit - A unit Dies
      • Conditions
        • (Unit-type of (Triggering unit)) Equal to Rush Dummy
      • Actions
        • Unit - Remove (Triggering unit) from the game


Keywords:
Dash, Spell, Template, MUI, Leakless??, JASS, vJASS, Simple, Will, be, rejected, probably, updated
Contents

Dash Spell Template (Map)

Reviews
Moderator
Rush v1.05 | Reviewed by Maker | 17th Aug 2013 APPROVED [IMG] The spell is leakless an MUI but not very original [tr] [IMG] Your globals should be private constant Take the pathability library out of the header Get...
  1. Rush v1.05 | Reviewed by Maker | 17th Aug 2013
    APPROVED

    [​IMG]
    • The spell is leakless an MUI but not very original
    [​IMG]
    • Your globals should be
      private constant
    • Take the pathability library out of the header
    • Get rid of Rush Dummy Dies trigger
    • You could precalculate
      Offset * Cos(facing)
      and the Sin also
    • You can't pick units with
      GetUnitTypeId(u) != 0
      so no need to check it
    • You could use
      SetUnitPropWindow
      to lock the facing
    • Use the ability level at the time of casting
    • Try making this all vjass

     
  2. sniper_zero

    sniper_zero

    Joined:
    Sep 9, 2009
    Messages:
    647
    Resources:
    2
    Spells:
    1
    Tutorials:
    1
    Resources:
    2
    How can I edit the above post? Made a mistake.
     
  3. Doomlord

    Doomlord

    Joined:
    Dec 15, 2011
    Messages:
    1,150
    Resources:
    14
    Spells:
    12
    JASS:
    2
    Resources:
    14
    Use the Update button.

    Review:
    1. Local group g is never destroyed.
    2. You don't need to save the group handle with every iteration. The thread at that time will complete the loop first before being iterated again. Reconsider your logic there.
    3. There isn't a code block for impassable terrain encounter.
    4. You can use a real value to keep track of the distance moved and compare it to the max distance instead of having to do excessive calculations.
    5. Put the damage and max distance into a global/constant function for easy configuration. It is ill-advised to leave a configurable value in the midst of your code.
    6. Make dummy life span configurable.
    7. The Offset global is unnecessary.
    8. Remove
      == true
      and
      == false
      . They are unnecessary. You can inline them with
      Code (vJASS):
      if condition then // Instead of == true

      // or

      if not condition then // Instead of == false
    9. This code block can be improved
      Code (vJASS):
              if UnitOrSfx == false then
                  call DestroyEffect(AddSpecialEffect(Sfx, x, y))
              else
                  // Code
              endif
      and
      Code (vJASS):
          if count < Duration then
              // Code
          else
              // Code
          endif


      Since a boolean can only return either true or false, you don't need to use elseif.
    10. Code (vJASS):
          if dist_check <= 100 then
              set facing = GetUnitFacing(caster)
          elseif dist_check > 100 then
              set facing = bj_RADTODEG*(Atan2(dy, dx))
          endif


      should be
      Code (vJASS):
          if dist_check <= 100 then
              set facing = GetUnitFacing(caster)*bj_DEGTORAD
          elseif dist_check > 100 then
              set facing = (Atan2(dy, dx))
          endif


      This helps you avoid having to reconvert the values in the set x and y of the periodic function.
    11. Duration is a wrong name. Use something like distance per iteration.
    12. cx, cy, tx, ty are unnecessary. You don't have to set a local for every single thing. It is not efficient, it is the opposite of that. Either remove them or remove dx, dy and use them in dist_check.
    13. cos, sin in the periodic func is also unnecessary. Just use the natives there directly.
    14. It is called Nulling, not Leak removal.
    15. Create a filter function like this
      Code (vJASS):
          function filterUnit takes unit caster, unit u returns boolean
              return /*
             
              */
      IsUnitEnemy(u, GetOwningPlayer(caster)) and /* Target is an enemy of caster
              */
      not IsUnitType(u, UNIT_TYPE_DEAD) and /* Target is alive
              */
      GetUnitAbilityLevel(u, 'Avul') == 0 and /* Target is not invulnerable
              */
      not IsUnitType(u, UNIT_TYPE_STRUCTURE) /* Target is not a structure
              */

          endfunction
      for configuration.
    16. You may want to use Maker's Shadow Trail system to awesome-ize (I made this up) the spell.

    That is all for now. Ask if you feel like I misread the code :)
     
    Last edited: Jul 24, 2013
  4. sniper_zero

    sniper_zero

    Joined:
    Sep 9, 2009
    Messages:
    647
    Resources:
    2
    Spells:
    1
    Tutorials:
    1
    Resources:
    2
    Do I have to put the placeholder? Or is someone else going to work on that?
     
  5. Doomlord

    Doomlord

    Joined:
    Dec 15, 2011
    Messages:
    1,150
    Resources:
    14
    Spells:
    12
    JASS:
    2
    Resources:
    14
    No it means I am going to post a review there when I am done. The sentence is to inform you of that so you won't miss it.
     
  6. doomhammer99

    doomhammer99

    Joined:
    Dec 5, 2011
    Messages:
    319
    Resources:
    5
    Models:
    1
    Spells:
    3
    Tutorials:
    1
    Resources:
    5
    yay. He used my Description Template :)))
     
  7. sniper_zero

    sniper_zero

    Joined:
    Sep 9, 2009
    Messages:
    647
    Resources:
    2
    Spells:
    1
    Tutorials:
    1
    Resources:
    2
    Doesn't everybody?
     
  8. deathismyfriend

    deathismyfriend

    Joined:
    Oct 24, 2012
    Messages:
    6,529
    Resources:
    14
    Spells:
    12
    Tutorials:
    2
    Resources:
    14
    nope lol. although it is a nice one.
     
  9. Almia

    Almia

    Joined:
    Apr 24, 2012
    Messages:
    4,839
    Resources:
    35
    Spells:
    30
    Tutorials:
    4
    JASS:
    1
    Resources:
    35
    And it seems our Crimson Lord of Darkness is now mini-moderating :D
    #SWAG
     
  10. Doomlord

    Doomlord

    Joined:
    Dec 15, 2011
    Messages:
    1,150
    Resources:
    14
    Spells:
    12
    JASS:
    2
    Resources:
    14
    Yeh but it seems like the OP is giving me zero damn =))

    edit

    Just kidding :D
     
  11. sniper_zero

    sniper_zero

    Joined:
    Sep 9, 2009
    Messages:
    647
    Resources:
    2
    Spells:
    1
    Tutorials:
    1
    Resources:
    2
    1. Okay. So I just have to remove DestroyGroup(g) then?

    2. So what do you suggest I do here?

    3. The script at the map header doesn't check that?

    4. Can you point out these excessive calculations?

    5. I tried to make them as globals before but then they move at the same distance even if they have different levels of abilities.

    6. You mean the expiration timer?

    7. I'll remove it.

    8. Okay.

    9. So I should do it the way you showed me?

    10. Will do.

    11. Lol. Sure.

    12. If I remove, dx and dy what do I use in the distance check? And when should I set something to a local?

    13. What natives?

    14. Okay.

    15. Okay. But why check for invulnerability though? It's not like they'll get damaged.

    EDIT: By the way, were you waiting for my reply? I went out for a bit.

    EDIT: Didn't see 16. Can I not do that? I have nothiing against Maker's systems and spells. I'm just...not very fond of vJASS. If I can get it to work I'll try to make use of it.

    EDIT: I'm curious, suppose every issue except 11 and 14 were gone. Would this still get a Rejected or Needs Fix status?
     
  12. Doomlord

    Doomlord

    Joined:
    Dec 15, 2011
    Messages:
    1,150
    Resources:
    14
    Spells:
    12
    JASS:
    2
    Resources:
    14
    1. You never add it in the first place. Just put it in the timer destroy block.
    2. Remove that line :)
    3. No. You can debug a draft code execution and see what happens.
    4. Set local damage and max distance, calculate duration. Everything will be simplified if you do it like this:
      Code (vJASS):
      if currentDist >= maxDist then
      // execute end code
      else
      // execute move code
      // save currentDist = currentDist + intervalDist
    5. Global is just a suggestion. You can simply go with a function like this:
      Code (vJASS):
          function Rush_GetMaxDistance takes integer level returns real
              return 1000 + level*200
          endfunction
    6. Indeed.
    7. Nice :)
    8. Nice :)
    9. Yeh.
    10. Nice :)
    11. Nice :)
    12. I recommend this:
      Code (vJASS):
         
          local real dx = GetSpellTargetX() - GetUnitX(caster)
          local real dy = GetSpellTargetY() - GetUnitY(caster)
      since you will be using dx, dy again. On a side note, SquareRoot is computationally expensive, you may want to do it like this:
      Code (vJASS):
          local real dist_check = (dx*dx) + (dy*dy)

          // Square the compare value here
          if dist_check <= 100*100 then
          else
          endif
    13. Do it like this:
      Code (vJASS):
          local real x1 = x + Offset * Cos(facing)
          local real y1 = y + Offset * Sin(facing)
      The
      Sin()
      and
      Cos()
      natives are what I am talking about.
    14. Nice :)
    15. It is just an example. You can do it the way you want. Oh and filter out invulnerable units helps reduce computing effort for your spell :)
    16. Be my guest. It is just a suggestion.

    I am not an actual moderator so I cannot answer your last question. Sorry =/

    edit

    Whoops. Forgot to tell you that you can just set the dummy's death type to Can't raise, Does not decay and get rid of the Dummy removal trigger :p
     
  13. sniper_zero

    sniper_zero

    Joined:
    Sep 9, 2009
    Messages:
    647
    Resources:
    2
    Spells:
    1
    Tutorials:
    1
    Resources:
    2
    I'll get to it when I'm in front of my desktop.

    Where's the timer destroy block? Where I flushed the childtable? And you still have to destroy the group even if you save it in a hashtable and flush it?

    For number 2. Will the spell still work fine even if I don't save it? Won't bug or anything?

    I'll do something about the impassable terrain but what kind of impassable terrain? Cliffs? Trees?

    Didn't think you were referring to the variables sin and cos. I'll never use them as variable names again.

    And...never use squareroot and pow? Ever?

    And the dummies play their death sound even with Can't Raise, Does not Decay. The Dummy removal trigger prevents that from happening. Should I still remove it?

    EDIT: Map updated.
     
    Last edited: Jul 25, 2013
  14. Almia

    Almia

    Joined:
    Apr 24, 2012
    Messages:
    4,839
    Resources:
    35
    Spells:
    30
    Tutorials:
    4
    JASS:
    1
    Resources:
    35
    16. Optional.
     
  15. Doomlord

    Doomlord

    Joined:
    Dec 15, 2011
    Messages:
    1,150
    Resources:
    14
    Spells:
    12
    JASS:
    2
    Resources:
    14
    3/
    Code (vJASS):
            if IsTerrainWalkable(x1, y1) then
                call SetUnitX(caster, x1)
                call SetUnitY(caster, y1)
                else
                // This is the code to be executed when the hero encounters impassable terrain.
                // Add the end code here
            endif


    4/ Indeed it is done the way you said. Add offset to a saved real with every iteration.

    7/ The Offset variable is unnecessary because it is only a single calculation, it is not worthy of a global. You can put it into a local for use in periodic though.

    15/ It is not about efficiency. It is about readability and configuration. The filter func allows easy configuration on the user's end.
     
  16. sniper_zero

    sniper_zero

    Joined:
    Sep 9, 2009
    Messages:
    647
    Resources:
    2
    Spells:
    1
    Tutorials:
    1
    Resources:
    2
    The spell is updated now. Though since Offset is now used in these equations I thought it should stay. Is that alright?

    Code (vJASS):
        local real x1 = x + Offset * Cos(facing)
        local real y1 = y + Offset * Sin(facing)
        set cur_dist = cur_dist + Offset

    On another note, I couldn't do that thing you did with \* in the filter function. So my filter function ended up looking like this.
    Code (vJASS):

    function UnitCheck takes unit caster, unit u returns boolean
        return IsUnitEnemy(u, GetOwningPlayer(caster)) and not IsUnitType(u, UNIT_TYPE_DEAD) and IsUnitType(u, UNIT_TYPE_GROUND) and not IsUnitType(u, UNIT_TYPE_STRUCTURE) and  GetUnitAbilityLevel(u, 'Avul') == 0
    endfunction
     
  17. Doomlord

    Doomlord

    Joined:
    Dec 15, 2011
    Messages:
    1,150
    Resources:
    14
    Spells:
    12
    JASS:
    2
    Resources:
    14
    Yeh. It is a vJASS thing. Don't worry.

    Anyway, nice job on improving this :)

    edit

    Wait. You are supposed to execute the spell end code if the caster encounters impassable terrain, not like that dude :/

    Just copy the end code and replace the "stay in same position".

    Another note, you should increase then save cur_dist after you moved the unit. It is the correct logic :)
     
  18. sniper_zero

    sniper_zero

    Joined:
    Sep 9, 2009
    Messages:
    647
    Resources:
    2
    Spells:
    1
    Tutorials:
    1
    Resources:
    2
    I'm using JNGP so vJASS should be possible right? How do I do that while using vanilla JASS? Or does the trigger editor not let you do that unless you do the library, scope etc. thing only available to vJASS?
     
  19. Doomlord

    Doomlord

    Joined:
    Dec 15, 2011
    Messages:
    1,150
    Resources:
    14
    Spells:
    12
    JASS:
    2
    Resources:
    14
    You have to use JNGP to use those things since they are unique to vJASS. Btw, I updated the previous post, you should check it.