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 haven't received your rank award? Then please contact the administration.
    Dismiss Notice
  4. Rubbed the right way, the genie is out of its lamp! The 12th Concept Art Contest Results have been announced.
    Dismiss Notice
  5. Race against the odds and Reforge, Don't Refund. The 14th Techtree Contest has begun!
    Dismiss Notice
  6. 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. sniper_zero

    sniper_zero

    Joined:
    Sep 9, 2009
    Messages:
    646
    Resources:
    2
    Spells:
    1
    Tutorials:
    1
    Resources:
    2
    Updated again. I guess I misunderstood what you mean by end code.
     
  2. Doomlord

    Doomlord

    Joined:
    Dec 15, 2011
    Messages:
    1,150
    Resources:
    14
    Spells:
    12
    JASS:
    2
    Resources:
    14
    Nice to hear that then :)

    You may want to remove the debug messages though =))
     
  3. sniper_zero

    sniper_zero

    Joined:
    Sep 9, 2009
    Messages:
    646
    Resources:
    2
    Spells:
    1
    Tutorials:
    1
    Resources:
    2
    It's for the users to check for themselves if there's any errors in the map if they still have any doubts. If it really is that much of a bother though, I'll remove it.
     
  4. deathismyfriend

    deathismyfriend

    Joined:
    Oct 24, 2012
    Messages:
    6,528
    Resources:
    14
    Spells:
    12
    Tutorials:
    2
    Resources:
    14
    no debug messages should be in the spell. It makes it look like the spell is bad / bugged.

    This should be updated to a vJass spell if it requires vJass to use.
     
  5. sniper_zero

    sniper_zero

    Joined:
    Sep 9, 2009
    Messages:
    646
    Resources:
    2
    Spells:
    1
    Tutorials:
    1
    Resources:
    2
    Only the script terrain pathability check is in vJASS though. The rest is just in normal JASS. Got it, I'll remove the debug messages when I get home.
     
  6. deathismyfriend

    deathismyfriend

    Joined:
    Oct 24, 2012
    Messages:
    6,528
    Resources:
    14
    Spells:
    12
    Tutorials:
    2
    Resources:
    14
    it stil requires vJass tho thats y it is a vJass spell not a jass spell.
     
  7. sniper_zero

    sniper_zero

    Joined:
    Sep 9, 2009
    Messages:
    646
    Resources:
    2
    Spells:
    1
    Tutorials:
    1
    Resources:
    2
    The map no longer contains the debug messages. You'll still see it in the description template but the actual map has them removed. Also changed the category to vJASS now.
     
  8. watermelon_1234

    watermelon_1234

    Joined:
    Nov 18, 2007
    Messages:
    1,066
    Resources:
    10
    Spells:
    9
    JASS:
    1
    Resources:
    10
    The code in the test-map doesn't match the code you put in the description. I'm assuming the code in the description is the updated one.

    Short Review

    • GetUnitAbilityLevel(u, 'Avul') == 0
      is not really a good check for invulnerable units since it won't be true for all the ways a unit can become invulnerable in WC3. I would suggest just removing it.
    • The
      I2R
      calls are useless since the calculations in your functions involves reals.
    • You still have some
      SomeBoolean == false
      instead of
      not SomeBoolean
    • I'd suggest a configurable string for setting the animation for the caster when it finishes the spell. Since this is a template, it should be as configurable as possible.
      In general, most literal or constants you put in the code should be configurable, except your hashtable accesses. Even having the
      100 * 100
      configurable isn't a bad idea in case the user wants more precision (though it seems better off as a template constant).
    • Code (vJASS):
      call SaveGroupHandle(udg_Rush_Hash, id, 3, g)
      The local variable g is rather useless. You can just do this:
      Code (vJASS):
      call SaveGroupHandle(udg_Rush_Hash, id, 3, CreateGroup())

    If you have the time, you could strive to make this an actual vJass template. For instance, making the template into a module that can be imported into a struct.
    You can check the tutorials section for getting started with vJass.
     
  9. sniper_zero

    sniper_zero

    Joined:
    Sep 9, 2009
    Messages:
    646
    Resources:
    2
    Spells:
    1
    Tutorials:
    1
    Resources:
    2
    The code in the test map is the updated one. I'm just too lazy to update the one in the spell description.

    I only see I2R in the top functions where ability level is involved. Since ability level is an integer, don't I have to convert it to a real?

    SomeBoolean == false
    ...are you talking about
    UnitOrSfx == false
    ? Then what do you suggest? This is the only way I could think of to make it swtichable.

    100*100 is better off as a constant.

    You mean local group at the start?
     
  10. watermelon_1234

    watermelon_1234

    Joined:
    Nov 18, 2007
    Messages:
    1,066
    Resources:
    10
    Spells:
    9
    JASS:
    1
    Resources:
    10
    I've redownloaded your test map just to make sure and this is what the code looks like:
    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 Offset = Speed * Interval //How far the caster moves per interval.
        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.
        integer Transparency = 80 //How transparent you want the dummy to be.
        integer RushDummy = 'e001' // This is the id of the dummy unit created.
        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.
        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.
    endglobals

    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 integer count = LoadInteger(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 cos = Cos(Deg2Rad(facing))
        local real sin = Sin(Deg2Rad(facing))
        local real x1 = x + Offset * cos
        local real y1 = y + Offset * sin
        local player owner = GetOwningPlayer(caster)
        local unit dummy
        local unit u
       
        //Configurable Locals
        local real damage = (GetUnitAbilityLevel(caster, Rush) * 75)//You can change this to whatever you want.
        local real MaxDistance = (GetUnitAbilityLevel(caster, Rush) * 200) + 200 //This makes the distance you dash scale with the level.
        //End of Configurable Locals
       
        local real Duration = MaxDistance * Interval //This determines how long you dash. Don't touch this unless you know what to do.
        //End Setup
       
        set count = count + 1//This counts how many times you've moved.
        call SaveInteger(udg_Rush_Hash, id, 2, count)
       
        if count < Duration then
            call SetUnitAnimation(caster, Animation)
            if UnitOrSfx == false then
                call DestroyEffect(AddSpecialEffect(Sfx, x, y))
            elseif UnitOrSfx == true then
                set dummy = CreateUnit(owner, RushDummy, x, y, facing)
                call SetUnitAnimation(dummy, Animation)
                call SetUnitVertexColor(dummy, 255, 255, 255, Transparency)
                call UnitApplyTimedLife(dummy, 'BTLF', .5)
                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 IsUnitInGroup(u, g) == false and IsUnitEnemy(u, owner) and GetUnitState(u, UNIT_STATE_LIFE) > .405 and IsUnitType(u, UNIT_TYPE_GROUND) and IsUnitType(u, UNIT_TYPE_STRUCTURE) == false then
                    call UnitDamageTarget(caster, u, damage, false, false, AttackType, DamageType, null)
                    call GroupAddUnit(g, u)
                endif
                call GroupRemoveUnit(RushGroup, u)
                call SaveGroupHandle(udg_Rush_Hash, id, 3, g)
            endloop
            if IsTerrainWalkable(x1, y1) then
                call SetUnitX(caster, x1)
                call SetUnitY(caster, y1)
            endif
           
        elseif count > Duration then
            call GroupClear(g)
            call PauseTimer(t)
            call DestroyTimer(t)
            call SetUnitAnimation(caster, "stand") //Resets the animation.
            call FlushChildHashtable(udg_Rush_Hash, id)
        endif
       
        //Leak Removal
        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 cx = GetUnitX(caster)
        local real cy = GetUnitY(caster)
        local real tx = GetSpellTargetX()
        local real ty = GetSpellTargetY()
        local real dx = tx - cx
        local real dy = ty - cy
        local real dist_check = SquareRoot((dx*dx) + (dy*dy))
        local real facing
        local group g = CreateGroup()
       
        //A little distance check to avoid bugs when you cast the spell in your current position.
        if dist_check <= 100 then
            set facing = GetUnitFacing(caster)
        elseif dist_check > 100 then
            set facing = bj_RADTODEG*(Atan2(dy, dx))
        endif
       
        //Hashtable Setup
        call SaveUnitHandle(udg_Rush_Hash, id, 0, caster)
        call SaveReal(udg_Rush_Hash, id, 1, facing)
        call SaveInteger(udg_Rush_Hash, id, 2, 0)
        call SaveGroupHandle(udg_Rush_Hash, id, 3, g)
        //End Hashtable Setup
       
        call TimerStart(t, Interval, true, function Rush_Periodic)
       
        //Leak Removal
        set t = null
        set caster = null
        set g = 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
    The integers would be implicitly converted to reals as long as you have reals in the same calculation. Just try removing both
    I2R
    calls; you'll see that your map still compiles fine.

    I already suggested an alternative: You still have some
    SomeBoolean == false
    instead of
    not SomeBoolean


    I should have been more clear. I'm talking about the local group g in Rush_Actions.
     
  11. sniper_zero

    sniper_zero

    Joined:
    Sep 9, 2009
    Messages:
    646
    Resources:
    2
    Spells:
    1
    Tutorials:
    1
    Resources:
    2
    Yep, looks like the updated one.

    So I should do it like this?
    UnitOrSfx not false
    Anyway, it's late where I am and I'll be busy tomorrow, so I'll probably update the day after tomorrow if I can't find time.
     
  12. watermelon_1234

    watermelon_1234

    Joined:
    Nov 18, 2007
    Messages:
    1,066
    Resources:
    10
    Spells:
    9
    JASS:
    1
    Resources:
    10
    No. If I'm not being clear enough, in your code, it would look just like this:
    Code (vJASS):
    if not UnitOrSfx then
    not
    is a logical operator that negates the condition after it.
     
  13. sniper_zero

    sniper_zero

    Joined:
    Sep 9, 2009
    Messages:
    646
    Resources:
    2
    Spells:
    1
    Tutorials:
    1
    Resources:
    2
    Updated! And I have to apologize, the map that was uploaded before was actually the wrong one. NOW, I've made sure the correct one is uploaded and I've corrected the issues watermelon1234 pointed out.

    Lastly, if you're going to tell me to do
    if not IsUnitType(u, UNIT_TYPE_DEAD) and GetUnitTypeId(u) != 0
    then you're going to have to tell me how to bypass the error because every time I try to place it in the filter function, cannot convert integer to boolean and cannot compare variables of primitive types blah blah error pops up. I tried doing this to no avail.

    Code (vJASS):
    if blah blah then
       return true
    endif
       return false


    EDIT: Also updated the script in the spell description.
    EDIT: I've decided to keep 100*100 and 'stand' animation after the spell as constants.
     
  14. Almia

    Almia

    Joined:
    Apr 24, 2012
    Messages:
    4,843
    Resources:
    35
    Spells:
    30
    Tutorials:
    4
    JASS:
    1
    Resources:
    35
    @sniper_zero
    put "(" and ")" in the condition.
     
  15. sniper_zero

    sniper_zero

    Joined:
    Sep 9, 2009
    Messages:
    646
    Resources:
    2
    Spells:
    1
    Tutorials:
    1
    Resources:
    2
    Oohhh, it suddenly works now! Thanks!
     
  16. deathismyfriend

    deathismyfriend

    Joined:
    Oct 24, 2012
    Messages:
    6,528
    Resources:
    14
    Spells:
    12
    Tutorials:
    2
    Resources:
    14
    change this 100 * 100 to this 10000

    your global variable names are 2 generic. They will most likely be used by something else and should be changed so they dont create problems.
     
  17. sniper_zero

    sniper_zero

    Joined:
    Sep 9, 2009
    Messages:
    646
    Resources:
    2
    Spells:
    1
    Tutorials:
    1
    Resources:
    2
    Okay, but I'm busy at the moment.Will update after I beat Pewter City Gym.
     
  18. sniper_zero

    sniper_zero

    Joined:
    Sep 9, 2009
    Messages:
    646
    Resources:
    2
    Spells:
    1
    Tutorials:
    1
    Resources:
    2
    Isn't private constant a vjass thing?
    Do I use SetUnitPropWindow to precalculate Offset * Cos(facing)? Otherwise, what would happen if I use SetUnitPropWindow? I haven't tried it out yet.
     
  19. Maker

    Maker

    Joined:
    Mar 6, 2006
    Messages:
    9,181
    Resources:
    17
    Maps:
    2
    Spells:
    14
    Tutorials:
    1
    Resources:
    17
    Setting prop window to 0 makes the unit unable to move, but it can turn, attack and cast spells etc.