• 🏆 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 Storm 1.5

Hi everybody,
Here is a new spell !

The spell works like this : The mage creates a huge arrow that goes in line like a missile.
But when it encounters an enemy it will create again 8 little arrows in circle that will damage enemies. Little arrows don't create again littler arrows it would be mad ^^

Requirements :
- JNGP
- Bound Sentinel by Vexorian that can be found here or in the test map


The code :
JASS:
scope ArrowStorm 
    //requires Bound Sountinel By Vexorian : [url]http://www.wc3c.net/showthread.php?t=102576[/url]
    
    //Feel free to comment this native if you already have it in your map
    native UnitAlive takes unit id returns boolean
    
    
    //CONFIGURATION
    globals
        //The periodic check timer, if you don't know what to do let is as it is.
        private constant real FPS = 0.0312500
        
        //The id of the spell
        private constant integer SPELL_ID = 'C000'
        
        //The id of the primary missile
        private constant integer ID_PRIMARY = 'l000'
        
        //The id of the secondary missile
        private constant integer ID_SECONDARY = 'l001'
        
        //The speed of the primary missile
        private constant real SPEED_PRIMARY = 950.
        
        //The speed of the secondary missile
        private constant real SPEED_SECONDARY = 650.
        
        //The amount of units the missile should start from the caster
        private constant real START_OFFSET = 150.
        
        //The radius around the primary missile the units should get damaged
        private constant real RADIUS_PRIMARY = 150.
        
        //The radius around the secondary missile the units should get damaged
        private constant real RADIUS_SECONDARY = 100.
        
        //The attacktype of the damage
        private constant attacktype A_TYPE =ATTACK_TYPE_MAGIC
        
        //The damagetype of the damage
        private constant damagetype D_TYPE = DAMAGE_TYPE_MAGIC
        
        //The weapontype of the damage
        private constant weapontype W_TYPE = null
        
        //The path of the effect each time the primary missile create secondary missile
        private constant string PATH = "Abilities\\Weapons\\ProcMissile\\ProcMissile.mdl"
        
        //In radian
        //The angle between each secondary missile upon creating
        private constant real SECONDARY_OFFSET = bj_PI/4
        
        //This will tell you how many secondary missiles it will create
        //If you wan to change it usually you have to change the precedent constant.
        //It works with a 2*pi reference.
        //Dividing 2*pi by the SECONDARY_OFFSET
        private constant integer NUMBER_SECONDARY = R2I(bj_PI*2/SECONDARY_OFFSET)
    endglobals
    
    
    //How many damage should the primary missile deal
    private constant function DamagePrimary takes integer level returns real
        return 55.*level
    endfunction
    
    
    //How many damage should the secondary missile deal
    private constant function DamageSecondary takes integer level returns real
        return 15.*level
    endfunction
    
    
    //The distance the primary missile should travel before the end
    private constant function DistancePrimary takes integer level returns real
        return 750.+50.*level
    endfunction
    
    
    //The distance the secondary missile should travel before the end
    private constant function DistanceSecondary takes integer level returns real
        return 300.+25.*level
    endfunction
    
    
    //The filter function 
    private function Unit_Filter takes player source, unit targ returns boolean
        return (UnitAlive(targ)) and (not IsUnitType(targ, UNIT_TYPE_MAGIC_IMMUNE)) and IsUnitEnemy(targ, source)
    endfunction
    //END CONFIGURATION
    //MAD CODING AFTER D: !
    
    
    //Textmacro for allocating because I'm lazy ^^
    //! textmacro AS_Alloc takes prefix
        if thistype(0).prev == 0 then
            set count = count + 1
            set this$prefix$ = count
        else
            set this$prefix$ = thistype(0).prev
            set thistype(0).prev = thistype(0).prev.prev
        endif
        if thistype(0).next == 0 then
            call TimerStart(period, FPS, true, function thistype.periodic)
        else
            set thistype(0).next.prev = this$prefix$
        endif
        set this$prefix$.next = thistype(0).next
        set thistype(0).next = this$prefix$
        set this$prefix$.prev = thistype(0)
    //! endtextmacro
    
    private struct ArrowStorm extends array
        unit caster
        unit missile
        real dmg
        boolean head
        integer lvl
        real X
        real Y
        real steps
        player owner
        group already
        thistype prev
        thistype next
        static integer count
        static timer period
        static group g
        
        method destroy takes nothing returns nothing
            if this.next != 0 then
                set this.next.prev = this.prev
            endif
            set this.prev.next = this.next
            set this.prev = thistype(0).prev
            set thistype(0).prev = this
            if thistype(0).next == 0 then
                call PauseTimer(period)
            endif
            call DestroyGroup(this.already)
            set this.caster = null
            set this.missile = null
            set this.already = null
            set this.owner = null
        endmethod
        
        static method periodic takes nothing returns nothing
            local thistype this = thistype(0).next
            local thistype this2
            local unit u 
            local integer i
            local real x
            local real y
            local real angle
            loop
                exitwhen this == 0
                set x = GetUnitX(this.missile)+this.X
                set y = GetUnitY(this.missile)+this.Y
                call SetUnitX(this.missile, x)
                call SetUnitY(this.missile, y)
                if this.head then
                    call GroupEnumUnitsInRange(g, x, y, RADIUS_PRIMARY, null)
                else
                    call GroupEnumUnitsInRange(g, x, y, RADIUS_SECONDARY, null)
                endif
                loop
                    set u = FirstOfGroup(g)
                    exitwhen u == null
                    call GroupRemoveUnit(g,u)
                    if Unit_Filter(this.owner,u) and not IsUnitInGroup(u,this.already) then
                        call UnitDamageTarget(this.caster, u, this.dmg, true, false, A_TYPE, D_TYPE, W_TYPE)
                        call GroupAddUnit(this.already, u)
                        if this.head then
                            set i = 0
                            set x = GetUnitX(this.missile)
                            set y = GetUnitY(this.missile)
                            call DestroyEffect(AddSpecialEffect(PATH, x, y))
                            loop
                                exitwhen i>NUMBER_SECONDARY
                                //! runtextmacro AS_Alloc("2")
                                set this2.caster = this.caster
                                set this2.owner = this.owner
                                set this2.dmg = DamageSecondary(this.lvl)
                                set this2.head = false
                                set angle = SECONDARY_OFFSET*i
                                set this2.missile = CreateUnit(this2.owner, ID_SECONDARY, x + START_OFFSET*Cos(angle), y + START_OFFSET*Sin(angle), angle*bj_RADTODEG)
                                call UnitApplyTimedLife(this2.missile, 'BTLF', DistanceSecondary(this.lvl)/SPEED_SECONDARY)
                                set this2.X = SPEED_SECONDARY*FPS*Cos(angle)
                                set this2.Y = SPEED_SECONDARY*FPS*Sin(angle)
                                set this2.steps = R2I( DistanceSecondary(this.lvl)/SPEED_SECONDARY/FPS )
                                set this2.already = CreateGroup()
                                set i = i + 1
                            endloop
                        endif
                    endif
                endloop
                set this.steps = this.steps - 1
                if this.steps == 0 then
                    call this.destroy()
                endif
                set this = this.next
            endloop
        endmethod
        
        static method cond takes nothing returns boolean
            local thistype this
            local real x
            local real y
            local real tx
            local real ty
            local real angle
            if GetSpellAbilityId() == SPELL_ID then
                //! runtextmacro AS_Alloc("")
                set this.caster = GetTriggerUnit()
                set this.lvl = GetUnitAbilityLevel(this.caster, SPELL_ID)
                set this.dmg = DamagePrimary(this.lvl)
                set this.head = true
                set x = GetUnitX(this.caster)
                set y = GetUnitY(this.caster)
                set tx = GetSpellTargetX()
                set ty = GetSpellTargetY()
                set angle = Atan2(ty-y, tx-x)
                set this.owner = GetOwningPlayer(this.caster)
                set this.missile = CreateUnit(this.owner, ID_PRIMARY, x+START_OFFSET*Cos(angle), y+START_OFFSET*Sin(angle), angle*bj_RADTODEG)
                call UnitApplyTimedLife(this.missile, 'BTLF', DistancePrimary(this.lvl)/SPEED_PRIMARY)
                set this.X = SPEED_PRIMARY*FPS*Cos(angle)
                set this.Y = SPEED_PRIMARY*FPS*Sin(angle)
                set this.steps = R2I(DistancePrimary(this.lvl)/SPEED_PRIMARY/FPS)
                set this.already = CreateGroup()
            endif
            return false
        endmethod
        
        static method onInit takes nothing returns nothing
            local trigger t = CreateTrigger()
            call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
            call TriggerAddCondition(t, Condition(function thistype.cond))
            set count = 0
            set period = CreateTimer()
            set g = CreateGroup()
            call Preload(PATH)
            set t = null
        endmethod
    endstruct
endscope

Credits :
- CakeMaster for the Sun Spear model
- Vexorian for vJASS and Bound Sentinel



v1.0.0 :
- Initial Release

v1.1.0 :
- Added a filter function

v1.2.0 :
- Fix a huge bug with MUI
- Trigger optimization

v1.2.1 :
- Change some coordinates in creation
- Fix a thing in globals
- Change the name of the textmacro for not confusing with Alloc module ^^
- Using Timed life

v1.2.2 :
- Change the look ^^ Thanks to Jad

v1.3 :
- Trigger optimizations.
- Now each period can fire more than one explosion :)

v1.4 :
- Objects changements.
- Added the weapontype in constants.

v1.5 :
- Model updated !


Feel free to leave a comment !
Malhorne

Keywords:
vJASS, Malhorne, arrow, storm, Wrathion, sunspear, sun spear
Contents

Just another Warcraft III map (Map)

Reviews
Arrow Storm 1.3 | Reviewed by Maker | 18.01.14 Concept[/COLOR]] The ability is a basic projectile spell with a twist, it explodes into smaller fragments upon contacting units However I don't think the name is very fitting Triggers[/COLOR]]...

Moderator

M

Moderator


Arrow Storm 1.3 | Reviewed by Maker | 18.01.14

[COLOR="gray"

[COLOR="gray"

[COLOR="gray"

[COLOR="gray"

[COLOR="gray"

[COLOR="gray"

Concept[/COLOR]]
126248-albums6177-picture66521.png
The ability is a basic projectile spell with a twist,
it explodes into smaller fragments upon contacting units
However I don't think the name is very fitting
Triggers[/COLOR]]
126248-albums6177-picture66521.png
  • Leakless, MUI and overall very good coding
126248-albums6177-picture66523.png
  • You could check UnitAlive before magic immunity,
    since dead units can be magic immune
  • Maybe there could be a struct member for the radius
    to avoid the if/then/else for deciding the radius
  • There could be a variable for weapon type as a user could
    then give the impact a sound
  • The projectile behaves terribly on uneven ground
  • You could use IsUnitInRangeXY as it takes collision
    size into account
Objects[/COLOR]]
126248-albums6177-picture66523.png
  • You could use only one dummy unit type as they
    differ only by scale
  • Reduce sight range on the dummies
  • Set death type of the dummies to Can't raise, does not decay
    so they don't decay for 90 seconds
  • Experiment with pitch and roll angles, values 0 and uneven ground
  • There is no follow through time
  • Hot keys are wrong
  • The tooltips are not that good
Effects[/COLOR]]
126248-albums6177-picture66521.png
  • No effect spam
126248-albums6177-picture66523.png
  • There could be optional impact sound, with weapon type variable
  • The movement on uneven ground does not look good
Rating[/COLOR]]
CONCEPTTRIGGERSOBJECTSEFFECTSRATINGSTATUS
126248-albums6177-picture75359.jpg
126248-albums6177-picture75359.jpg
126248-albums6177-picture75356.jpg
126248-albums6177-picture75358.jpg
126248-albums6177-picture75358.jpg
APPROVED
Links[/COLOR]]

[COLOR="gray"

[/TD]
 
When in front of your hero there are enemies, then you cast behind them... is then a bug?

^...The enemies near hero gets damaged, but still there is a arrow created behind them, and can cause new damage to enemies more far away.

Also there seems a delay before arrow is created.

I don't really like the special effect of thunderclap when a unit is hit.

I really like the spell idea. +rep and no rating for now
 
Level 18
Joined
Sep 14, 2012
Messages
3,413
When in front of your hero there are enemies, then you cast behind them... is then a bug?

^...The enemies near hero gets damaged, but still there is a arrow behind them, and can cause new damage to enemies more far away.

Also there seems a delay before arrow is created.
That is normal -> Area of effect and can't reduce delay sorry :(

Maybe it is because of the custom model that the arrow seems not to be right where it should be I dunno.
Need to see with other models.
 
Level 22
Joined
Sep 24, 2005
Messages
4,821
Little arrows don't create again littler arrows it would be mad ^^
Hell no, that would be fucking awesome and lagtastic! I'd rate it five if you make it do that. I'm postponing my rating until you say otherwise.

In case you don't like to do that :D

avatar221982_6.gif
piccolo.gif
Hell no! chobi...Hell no?! Makankosappo!
 
Level 19
Joined
Mar 18, 2012
Messages
1,716
JASS:
    //! textmacro Alloc takes prefix
        if thistype(0).prev == 0 then
            set count = count + 1
            set this$prefix$ = count
        else
            set this$prefix$ = thistype(0).prev
            set thistype(0).prev = thistype(0).prev.prev
        endif
        if thistype(0).next == 0 then
            call TimerStart(period, FPS, true, function thistype.periodic)
        else
            set thistype(0).next.prev = this$prefix$
        endif
        set this$prefix$.next = thistype(0).next
        set thistype(0).next = this$prefix$
        set this$prefix$.prev = thistype(0)
    //! endtextmacro
Don't name the textmacro "Alloc", because what you've done here is more than just a simple allocation.

Alloc is a well known module and users could assume they are the same, which is obviously wrong. Just name it ArrowStormAlloc or something related to your resource, I'm sure noone else will use this textmacro anyway :grin:.

Think about using GroupUtils, afterall you use a lot of groups.

I like the spell, but the visual effects have to get better.
  • The arrow splits up too far away from the target. For instance you could add an smaller detection aoe just for the split up.
  • Don't remove the arrows, but rather apply timed life instead. They haves a nice death animation.
  • Creating the head missle on GetSpellTargetX/Y doesn't look good in all cases. You could use an offset towards the casters x/y ~100, just like you did with the small arrows.
  • You could create the thunderclap on impact at the missles coordinates and damage units in an appropriate aoe around the big missle. But that would be a different concept.

Remove that damn textmacro!
 
Level 18
Joined
Sep 14, 2012
Messages
3,413
- No I won't remove the textmacros otherwise it looks ugly ^^'
- I won't use any resource non really needed as usual you know me :p
- I think I'll use the timed life it could be prettier.
- I'll change the creation of the big arrow and the thunderclap.
Anyway thanks for your review !

EDIT : Updated !

v1.0.0 :
- Initial Release

v1.1.0 :
- Added a filter function

v1.2.0 :
- Fix a hug bug with MUI
- Trigger optimization

v1.2.1 :
- Change some coordinates in creation
- Fix a thing in globals
- Change the name of the textmacro for not confusing with Alloc module ^^
- Using Timed life
 
Level 16
Joined
Jul 31, 2012
Messages
2,217
Ummm, for instance, it's a great spell. though:

increase the speed of the big arrow, decrease the AoE where the big arrow detects units (to make it look more realistic) and maybe changing that ugly thunderclap Fx :)
(why is that thunderclap effect so global.. it's like THE model you rely on when you can't find a good one ^^')

in terms of triggers... well i have nothing to say xD

Changelog said:
v1.2.0 :
- Fix a hug bug with MUI
- Trigger optimization
WOW! i didn't know bugs do hug... rofl

i guess it's a 3.5/5 .. it just needs enhancements to the visuals ;)


EDIT:
try this, and also make the effect's size changeable, cuz the one i found may look small
JASS:
scope ArrowStorm 
    //requires Bound Sountinel By Vexorian : [url]http://www.wc3c.net/showthread.php?t=102576[/url]
    
    //Feel free to comment this native if you already have it in your map
    native UnitAlive takes unit id returns boolean
    
    
    //CONFIGURATION
    globals
        //The periodic check timer, if you don't know what to do let is as it is.
        private constant real FPS = 0.0312500
        
        //The id of the spell
        private constant integer SPELL_ID = 'C000'
        
        //The id of the primary missile
        private constant integer ID_PRIMARY = 'l000'
        
        //The id of the secondary missile
        private constant integer ID_SECONDARY = 'l001'
        
        //The speed of the primary missile
        private constant real SPEED_PRIMARY = 950.
        
        //The speed of the secondary missile
        private constant real SPEED_SECONDARY = 650.
        
        //The amount of units the missile should start from the caster
        private constant real START_OFFSET = 150.
        
        //The radius around the primary missile the units should get damaged
        private constant real RADIUS_PRIMARY = 150.
        
        //The radius around the secondary missile the units should get damaged
        private constant real RADIUS_SECONDARY = 100.
        
        //The attacktype of the damage
        private constant attacktype A_TYPE =ATTACK_TYPE_MAGIC
        
        //The damagetype of the damage
        private constant damagetype D_TYPE = DAMAGE_TYPE_MAGIC
        
        //The path of the effect each time the primary missile create secondary missile
        private constant string PATH = "Abilities\\Weapons\\ProcMissile\\ProcMissile.mdl"
        
        //The interval between the same unit can be damaged twice
        private constant real INTERVAL_BETWEEN_DAMAGE = 1.
        
        //In radian
        //The angle between each secondary missile upon creating
        private constant real SECONDARY_OFFSET = bj_PI/4
        
        //This will tell you how many secondary missiles it will create
        //If you wan to change it usually you have to change the precedent constant.
        //It works with a 2*pi reference.
        //Dividing 2*pi by the SECONDARY_OFFSET
        private constant integer NUMBER_SECONDARY = R2I(bj_PI*2/SECONDARY_OFFSET)
    endglobals
    
    
    //How many damage should the primary missile deal
    private constant function DamagePrimary takes integer level returns real
        return 55.*level
    endfunction
    
    
    //How many damage should the secondary missile deal
    private constant function DamageSecondary takes integer level returns real
        return 15.*level
    endfunction
    
    
    //The distance the primary missile should travel before the end
    private constant function DistancePrimary takes integer level returns real
        return 750.+50.*level
    endfunction
    
    
    //The distance the secondary missile should travel before the end
    private constant function DistanceSecondary takes integer level returns real
        return 300.+25.*level
    endfunction
    
    
    //The filter function 
    private function Unit_Filter takes player source, unit targ returns boolean
        return (not IsUnitType(targ, UNIT_TYPE_MAGIC_IMMUNE)) and (UnitAlive(targ)) and IsUnitEnemy(targ, source)
    endfunction
    //END CONFIGURATION
    //MAD CODING AFTER D: !
    
    
    //Textmacro for allocating because I'm lazy ^^
    //! textmacro AS_Alloc takes prefix
        if thistype(0).prev == 0 then
            set count = count + 1
            set this$prefix$ = count
        else
            set this$prefix$ = thistype(0).prev
            set thistype(0).prev = thistype(0).prev.prev
        endif
        if thistype(0).next == 0 then
            call TimerStart(period, FPS, true, function thistype.periodic)
        else
            set thistype(0).next.prev = this$prefix$
        endif
        set this$prefix$.next = thistype(0).next
        set thistype(0).next = this$prefix$
        set this$prefix$.prev = thistype(0)
    //! endtextmacro
    
    private struct ArrowStorm extends array
        unit caster
        unit missile
        real dmg
        boolean head
        integer lvl
        real X
        real Y
        real steps
        player owner
        group already
        thistype prev
        thistype next
        static integer count
        static timer period
        static group g
        
        method destroy takes nothing returns nothing
            if this.next != 0 then
                set this.next.prev = this.prev
            endif
            set this.prev.next = this.next
            set this.prev = thistype(0).prev
            set thistype(0).prev = this
            if thistype(0).next == 0 then
                call PauseTimer(period)
            endif
            call DestroyGroup(this.already)
            set this.caster = null
            set this.missile = null
            set this.already = null
        endmethod
        
        static method periodic takes nothing returns nothing
            local thistype this = thistype(0).next
            local thistype this2
            local unit u 
            local integer i
            local real x
            local real y
            local real angle
            local boolean b = true
            loop
                exitwhen this == 0
                call SetUnitX(this.missile, GetUnitX(this.missile)+this.X)
                call SetUnitY(this.missile, GetUnitY(this.missile)+this.Y)
                if this.head then
                    call GroupEnumUnitsInRange(g, GetUnitX(this.missile), GetUnitY(this.missile), RADIUS_PRIMARY, null)
                else
                    call GroupEnumUnitsInRange(g, GetUnitX(this.missile), GetUnitY(this.missile), RADIUS_SECONDARY, null)
                endif
                loop
                    set u = FirstOfGroup(g)
                    exitwhen u == null
                    call GroupRemoveUnit(g,u)
                    if Unit_Filter(this.owner,u) and not IsUnitInGroup(u,this.already) then
                        call UnitDamageTarget(this.caster, u, this.dmg, true, false, A_TYPE, D_TYPE, null)
                        call GroupAddUnit(this.already, u)
                        if this.head and b then
                            set b = false
                            set i = 0
                            set x = GetUnitX(this.missile)
                            set y = GetUnitY(this.missile)
                            call DestroyEffect(AddSpecialEffect(PATH, x, y))
                            loop
                                exitwhen i>NUMBER_SECONDARY
                                //! runtextmacro AS_Alloc("2")
                                set this2.caster = this.caster
                                set this2.owner = this.owner
                                set this2.dmg = DamageSecondary(this.lvl)
                                set this2.head = false
                                set angle = SECONDARY_OFFSET*i
                                set this2.missile = CreateUnit(this2.owner, ID_SECONDARY, x + START_OFFSET*Cos(angle), y + START_OFFSET*Sin(angle), angle*bj_RADTODEG)
                                call UnitApplyTimedLife(this2.missile, 'BTLF', DistanceSecondary(this.lvl)/SPEED_SECONDARY)
                                set this2.X = SPEED_SECONDARY*FPS*Cos(angle)
                                set this2.Y = SPEED_SECONDARY*FPS*Sin(angle)
                                set this2.steps = R2I( DistanceSecondary(this.lvl)/SPEED_SECONDARY/FPS )
                                set this2.already = CreateGroup()
                                set i = i + 1
                            endloop
                        endif
                    endif
                endloop
                set this.steps = this.steps - 1
                if this.steps == 0 then
                    call this.destroy()
                endif
                set this = this.next
            endloop
        endmethod
        
        static method cond takes nothing returns boolean
            local thistype this
            local real x
            local real y
            local real tx
            local real ty
            local real angle
            if GetSpellAbilityId() == SPELL_ID then
                //! runtextmacro AS_Alloc("")
                set this.caster = GetTriggerUnit()
                set this.lvl = GetUnitAbilityLevel(this.caster, SPELL_ID)
                set this.dmg = DamagePrimary(this.lvl)
                set this.head = true
                set x = GetUnitX(this.caster)
                set y = GetUnitY(this.caster)
                set tx = GetSpellTargetX()
                set ty = GetSpellTargetY()
                set angle = Atan2(ty-y, tx-x)
                set this.owner = GetOwningPlayer(this.caster)
                set this.missile = CreateUnit(this.owner, ID_PRIMARY, x+START_OFFSET*Cos(angle), y+START_OFFSET*Sin(angle), angle*bj_RADTODEG)
                call UnitApplyTimedLife(this.missile, 'BTLF', DistancePrimary(this.lvl)/SPEED_PRIMARY)
                set this.X = SPEED_PRIMARY*FPS*Cos(angle)
                set this.Y = SPEED_PRIMARY*FPS*Sin(angle)
                set this.steps = R2I(DistancePrimary(this.lvl)/SPEED_PRIMARY/FPS)
                set this.already = CreateGroup()
            endif
            return false
        endmethod
        
        static method onInit takes nothing returns nothing
            local trigger t = CreateTrigger()
            call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
            call TriggerAddCondition(t, Condition(function thistype.cond))
            set count = 0
            set period = CreateTimer()
            set g = CreateGroup()
            call Preload(PATH)
            set t = null
        endmethod
    endstruct
endscope
 
Level 18
Joined
Sep 14, 2012
Messages
3,413
Updated !

v1.0.0 :
- Initial Release

v1.1.0 :
- Added a filter function

v1.2.0 :
- Fix a huge bug with MUI
- Trigger optimization

v1.2.1 :
- Change some coordinates in creation
- Fix a thing in globals
- Change the name of the textmacro for not confusing with Alloc module ^^
- Using Timed life

v1.2.2 :
- Change the look ^^
 
Last edited:
Level 19
Joined
Mar 18, 2012
Messages
1,716
You have variables in the global block you don't even use anymore for instance INTERVAL_BETWEEN_DAMAGE. I guess they are left from that TempDummy block you had in the previous version.
- Both dummies use upgrades
- this.owner = GetTriggerPlayer()
- Store the missles coordinates into the two locals x and y at the top of the loop.
I'm talking about that one
JASS:
                call SetUnitX(this.missile, GetUnitX(this.missile)+this.X)
                call SetUnitY(this.missile, GetUnitY(this.missile)+this.Y)
                if this.head then
                    call GroupEnumUnitsInRange(g, GetUnitX(this.missile), GetUnitY(this.missile), RADIUS_PRIMARY, null)
                else
                    call GroupEnumUnitsInRange(g, GetUnitX(this.missile), GetUnitY(this.missile), RADIUS_SECONDARY, null)
                endif
- I don't really get the use of local boolean b in the loop. Imo two different spell instances should act independently.
In such special cases a small comment would be nice, especially for me or the other moderators.
- You could null the owner variable aswell.
- It doesn't really matter because this function will not get inlined by the JassHelper, but you could change the order of targ and source, because targ comes first.
JASS:
    private function Unit_Filter takes player source, unit targ returns boolean
        return (not IsUnitType(targ, UNIT_TYPE_MAGIC_IMMUNE)) and (UnitAlive(targ)) and IsUnitEnemy(targ, source)
    endfunction
- so many groups ... but it can't be helped

Yay for textmacros ^^. I always seperate primary and secondary missles into two different structs, but your way is totally fine aswell.
The effects got better now, but still I think this not ready to be approved.
 
Level 18
Joined
Sep 14, 2012
Messages
3,413
Yep I'll change those things you pointed.
It is lagstatic if every 0.0312500 second you got more and more explosion.

Okay anyway thanks for the reply :)


EDIT : Updated !

v1.0.0 :
- Initial Release

v1.1.0 :
- Added a filter function

v1.2.0 :
- Fix a huge bug with MUI
- Trigger optimization

v1.2.1 :
- Change some coordinates in creation
- Fix a thing in globals
- Change the name of the textmacro for not confusing with Alloc module ^^
- Using Timed life

v1.2.2 :
- Change the look ^^ Thanks to Jad

v1.3 :
- Trigger optimizations.
- Now each period can fire more than one explosion :)
 
Last edited:

Cokemonkey11

Code Reviewer
Level 29
Joined
May 9, 2006
Messages
3,522
It is lagstatic if every 0.0312500 second you got more and more explosion.

DummyUnitStack :3 (or in your case, maybe try nestharus' resource which gets units with desired facing directions)

//Feel free to comment this native if you already have it in your map
native UnitAlive takes unit id returns boolean

FYI there's no need - jasshelper filters out repeated native declarations
 
Level 18
Joined
Sep 14, 2012
Messages
3,413
Oh sorry BPower xD ! Ya I suck in tooltip. That's why I don't post every resources I have made x)
@CokeMonkey : I won't use any ressources for this. Having an explosion each time an arrow hit an enemy is impossible to balance :)

EDIT : Cohadar's doesn't filter repeated native ^^ that's why I add this comment every time ;)
 
Level 18
Joined
Sep 14, 2012
Messages
3,413
Updated :)

v1.0.0 :
- Initial Release

v1.1.0 :
- Added a filter function

v1.2.0 :
- Fix a huge bug with MUI
- Trigger optimization

v1.2.1 :
- Change some coordinates in creation
- Fix a thing in globals
- Change the name of the textmacro for not confusing with Alloc module ^^
- Using Timed life

v1.2.2 :
- Change the look ^^ Thanks to Jad

v1.3 :
- Trigger optimizations.
- Now each period can fire more than one explosion :)

v1.4 :
- Objects changements.
- Added the weapontype in constants.
 
Level 18
Joined
Sep 14, 2012
Messages
3,413

v1.0.0 :
- Initial Release

v1.1.0 :
- Added a filter function

v1.2.0 :
- Fix a huge bug with MUI
- Trigger optimization

v1.2.1 :
- Change some coordinates in creation
- Fix a thing in globals
- Change the name of the textmacro for not confusing with Alloc module ^^
- Using Timed life

v1.2.2 :
- Change the look ^^ Thanks to Jad

v1.3 :
- Trigger optimizations.
- Now each period can fire more than one explosion :)

v1.4 :
- Objects changements.
- Added the weapontype in constants.

v1.5 :
- Model updated !
 
Top