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

Fiery Rage 3.10

Well, some of you might know this spell, since it was originally made for a challenge.

Now GUI and I had failed in this challenge, so I decided to make it in vJass.

It took me a huge load of time to make this spell, but this might be due to me still learning vJass.

[highlight]IMPORTANT: You need the new JassNewGenPack in order to modify this.[/code]


Summons forth 5 fire balls and sends them out flying towards the enemy, damaging everything in their way. When they have reached their target, they explode, and cause ten burning boulders to errupt from deep outside the earth. These boulders will fly outwards from the explosion again burning everything they touch. When those boulders hit the ground, they split into three fireballs. Deals 100/200/300 damage on first impact, 25/50/75 damage on second impact and 10/20/30 damage per second while near the projectiles.


Although mods see the code, some people might also want to see the code, so they can facepalm me without even opening the map ;)

JASS:
scope FieryRage initializer init

    globals
        //The Spell ID. Click ctrl+d in object editor to check if your's is the right.
        private constant integer SpellID        = 'A000'
        
        //The ID of the dummy unit, which has to be imported.
        private constant integer DummyID        = 'h000'
        
        //Just neccesary, if you modified existing skills.
        private constant integer CrowFormID     = 'Amrf'
        
        //The SFX attached to the first dummies, which are flying in a hilf circle from the caster to the target.
        private constant string  Dummy1attach1  = "Abilities\\Weapons\\LordofFlameMissile\\LordofFlameMissile.mdl"
        
        //See above
        private constant string  Dummy1attach2  = "Abilities\\Weapons\\PhoenixMissile\\Phoenix_Missile_mini.mdl"
        
        //The SFX attached to the second dummies, which are flying at changing heights, away from the detonation center.
        private constant string  Dummy2attach1  = "Abilities\\Spells\\Other\\Volcano\\VolcanoMissile.mdl"
        
        //See above
        private constant string  Dummy2attach2  = "Abilities\\Weapons\\RedDragonBreath\\RedDragonMissile.mdl"
        
        //The SFX attached to the third dummies, which are generated out of the second ones.
        private constant string  Dummy3attach   = "Abilities\\Weapons\\PhoenixMissile\\Phoenix_Missile.mdl"
        
        //The SFX shown, when the first dummies arrive.
        private constant string  SFX1           = "Abilities\\Spells\\Other\\Incinerate\\FireLordDeathExplode.mdl"
        
        //The SFX shown, when the second dummies arrive.
        private constant string  SFX2           = "Abilities\\Spells\\Other\\Doom\\DoomDeath.mdl"
        
        //See above
        private constant string  SFX3           = "Abilities\\Spells\\Other\\Volcano\\VolcanoDeath.mdl"
        
        //The SFX which is shown on every unit (with a 10% chance) every TimerInt, when they are near a projectile.
        private constant string  SpamSFX        = "Environment\\SmallBuildingFire\\SmallBuildingFire2.mdl"
        
        //The size of the first SFX, whereas 1. would be the normal size.
        private constant real    SFX1size       = 1.5
        
        //Quite self-explanatory, isn't it?
        private constant real    TimerInt       = .03
        
        //Damage Setup
        private constant boolean Attack         = false
        
        //Damage Setup
        private constant boolean Ranged         = false
        
        //Damage Setup
        private constant attacktype AttackType  = ATTACK_TYPE_NORMAL
        
        //Damage Setup
        private constant damagetype DamageType  = DAMAGE_TYPE_NORMAL
        
        //Damage Setup
        private constant weapontype WeaponType  = WEAPON_TYPE_WHOKNOWS
        
        //The steps, the first dummies take to reach their target, so less steps mean more speed.
        private constant integer Steps1         = 40
        
        //The steps, the second dummies take to reach their target, so less steps mean more speed.
        private constant integer Steps2         = 20
        
        //The steps, the third dummies take to reach their target, so less steps mean more speed.
        private constant integer Steps3         = 16
        
    endglobals
    
    
    //The number of the first dummies. This should be an uneven number, so you have one missile flying in the middle.
    //Else it will look awkward.
    private function Dummys1 takes integer lev returns integer
        return 5
    endfunction
    
    //The number of the second dummies.
    private function Dummys2 takes integer lev returns integer
        return 10
    endfunction
    
    //The number of the first dummies. It should be divideable by Dummys2, since every Dummy3 has its origin in a Dummy2.
    private function Dummys3 takes integer lev returns integer
        return Dummys2(0)*3
    endfunction
    
    //The damage done, when the first dummies reach their target.
    private function Damage1 takes real dist, integer lev returns real
        return lev*100.
    endfunction
    
    //The damage done, when the second dummies reach their target.
    private function Damage2 takes real dist, integer lev returns real
        return lev*25.
    endfunction
    
    //The damage done, when the unit is near a projectile.
    private function DamagePerSec takes real dist, integer lev returns real
        return lev*10.*TimerInt
    endfunction
    
    //The Aoe of Damage1.
    private function AoE1 takes real dist, integer lev returns real
        return dist/2.
    endfunction
    
    //The Aoe of Damage2.
    private function AoE2 takes real dist, integer lev returns real
        return dist/3.
    endfunction
    
    //The maximum flying height of the second dummies.
    private function Dummy2maxHeight takes real dist, integer lev returns real
        return AoE2(dist, 0)
    endfunction
    
    //The flying height of the third dummies. I chose a random number to imitate an explosion (scatters flying around).
    private function Dummy3maxHeight takes real dist, integer lev returns real
        return GetRandomReal(0., 300.)
    endfunction
    
    //The AoE of Damage3.
    private function DamagePerSecAoe takes real dist, integer lev returns real
        return 220.
    endfunction
    
    //Ignore the following 5 lines.
    globals
        private player p
        private boolean heightcheck
        private real heighttolerance = 20.
    endglobals
    //Setup continues
    
    //The Filter for units.
    private function UnitFilter takes nothing returns boolean
        return IsUnitEnemy(GetFilterUnit(), p) and not IsUnitType(GetFilterUnit(), UNIT_TYPE_STRUCTURE) and not IsUnitType(GetFilterUnit(), UNIT_TYPE_MECHANICAL) and not IsUnitType(GetFilterUnit(), UNIT_TYPE_MAGIC_IMMUNE) and GetWidgetLife(GetFilterUnit())>.405
    endfunction
    
    
    //End of Setup
    
    globals
        private boolexpr b
        private group g = CreateGroup()
    endglobals
    
    private struct data
        unit cast
        unit array dum [50]
        real dist
        real curdist
        real aoe1
        real aoe2
        real aoe3
        real dmg1
        real dmg2
        real dmg3
        real cx
        real cy
        real tx
        real ty
        real ang
        real  array dumang [50]
        real formula
        real maxheight2
        real array maxheight3 [50]
        integer step
        integer dummys1
        integer dummys2
        integer dummys3
        effect e0
        effect array e1 [50]
        effect array e2 [50]
        
        static data array ar
        static timer tim = CreateTimer()
        static integer total = 0
        static real dam
        static unit cas
        static real h
        
        static method groupdamage takes nothing returns nothing
            local unit u = GetEnumUnit()
            if heightcheck then
                if GetUnitFlyHeight(u)>data.h-heighttolerance and GetUnitFlyHeight(u)<data.h+heighttolerance then
                    call UnitDamageTarget(data.cas, u, data.dam, Attack, Ranged, AttackType, DamageType, WeaponType)
                    if GetRandomInt(1, 10) == 10 then
                        call DestroyEffect(AddSpecialEffect(SpamSFX, GetUnitX(u), GetUnitY(u)))
                    endif
                    call GroupRemoveUnit(g, u)
                endif
            else
                 call UnitDamageTarget(data.cas, u, data.dam, Attack, Ranged, AttackType, DamageType, WeaponType)
                if GetRandomInt(1, 10) == 10 then
                    call DestroyEffect(AddSpecialEffect(SpamSFX, GetUnitX(u), GetUnitY(u)))
                endif
                call GroupRemoveUnit(g, u)
            endif
            set u = null
        endmethod
        
        static method periodic takes nothing returns nothing
            local data d
            local integer i = 0
            local integer ii = 0
            local integer iii = 0
            local real x = .0
            local real y = .0
            local unit u
            loop
                exitwhen i >= d.total
                set d = d.ar[i]
                if d.step == 0 then
                    loop
                        exitwhen ii >= d.dummys1
                        set ii = ii + 1
                        set d.dum[ii] = CreateUnit(Player(15), DummyID, d.cx, d.cy, d.ang)
                        call PauseUnit(d.dum[ii], true)
                        set d.e1[ii] = AddSpecialEffectTarget(Dummy1attach1 , d.dum[ii], "chest")
                        set d.e2[ii] = AddSpecialEffectTarget(Dummy1attach2 , d.dum[ii], "origin")
                        call UnitAddAbility(d.dum[ii], CrowFormID)
                    endloop
                    set d.formula = bj_PI/2.
                    set ii = 0
                    set d.step = 1
                endif
                
                if d.step == 1 then
                    set d.formula = d.formula + bj_PI/(Steps1*2.)
                    loop
                        exitwhen ii >= d.dummys1
                        set ii = ii + 1
                        set d.curdist = d.curdist + d.dist/(Steps1*5.)
                        set x = d.cx+d.curdist*Cos(d.ang+Sin(d.formula)*(bj_PI/2.)*(I2R(ii-(d.dummys1/2+1))/2.))
                        set y = d.cy+d.curdist*Sin(d.ang+Sin(d.formula)*(bj_PI/2.)*(I2R(ii-(d.dummys1/2+1))/2.))
                        call SetUnitPosition(d.dum[ii], x, y)
                        set p = GetOwningPlayer(d.cast)
                        call GroupEnumUnitsInRange(g, x, y, d.aoe3, b)
                        set d.dam = d.dmg3
                        set d.cas = d.cast
                        set heightcheck = false
                        call ForGroup(g, function data.groupdamage)
                        if d.formula >= bj_PI then
                            set d.step = 2
                            call DestroyEffect(d.e1[ii])
                            call DestroyEffect(d.e2[ii])
                            call RemoveUnit(d.dum[ii])
                        endif
                    endloop
                    set ii = 0
                endif
                
                if d.step == 2 then
                    set p = GetOwningPlayer(d.cast)
                    call GroupEnumUnitsInRange(g, d.tx, d.ty, d.aoe1, b)
                    set d.dam = d.dmg1
                    set d.cas = d.cast
                    set heightcheck = false
                    call ForGroup(g, function data.groupdamage)
                    set u = CreateUnit(Player(15), DummyID, d.tx, d.ty, .0)
                    call SetUnitScale(u, SFX1size, SFX1size, SFX1size)
                    set d.e0 = AddSpecialEffectTarget(SFX1, u, "chest")
                    call UnitApplyTimedLife(u, 'BTLF', 1.)
                    call PauseUnit(u, true)
                    set u = null
                    loop
                        exitwhen ii >= d.dummys2
                        set ii = ii + 1
                        set d.dum[ii] = CreateUnit(Player(15), DummyID, d.tx, d.ty, d.ang)
                        call PauseUnit(d.dum[ii], true)
                        set d.e1[ii] = AddSpecialEffectTarget(Dummy2attach1 , d.dum[ii], "chest")
                        set d.e2[ii] = AddSpecialEffectTarget(Dummy2attach2 , d.dum[ii], "origin")
                        call UnitAddAbility(d.dum[ii], CrowFormID)
                        set d.dumang[ii] = bj_PI*2./ii
                    endloop
                    set ii = 0
                    set d.step = 3
                    set d.formula = 0.
                    set d.curdist = 0.
                endif
                
                if d.step == 3 then
                    set d.formula = d.formula + bj_PI/Steps2
                    set d.curdist = d.curdist + d.aoe2/Steps2
                    loop
                        exitwhen ii >= d.dummys2
                        set ii = ii + 1
                        set x = d.tx+d.curdist*Cos(bj_PI*2./d.dummys2*ii)
                        set y = d.ty+d.curdist*Sin(bj_PI*2./d.dummys2*ii)
                        call SetUnitPosition(d.dum[ii], x, y)
                        call SetUnitFlyHeight(d.dum[ii], d.maxheight2*Sin(d.formula), 0.)
                        set p = GetOwningPlayer(d.cast)
                        call GroupEnumUnitsInRange(g, x, y, d.aoe3, b)
                        set d.dam = d.dmg3
                        set d.cas = d.cast
                        set d.h = GetUnitFlyHeight(d.dum[ii])
                        set heightcheck = true
                        call ForGroup(g, function data.groupdamage)
                    endloop
                    set ii = 0
                    if d.formula >= bj_PI then
                        set d.step = 4
                    endif
                endif
                
                if d.step == 4 then
                    call DestroyEffect(d.e0)
                    loop
                        exitwhen ii == d.dummys2
                        set ii = ii + 1
                        set x = GetUnitX(d.dum[ii])
                        set y = GetUnitY(d.dum[ii])
                        set p = GetOwningPlayer(d.cast)
                        call GroupEnumUnitsInRange(g, x, y, d.aoe3, b)
                        set d.dam = d.dmg2
                        set d.cas = d.cast
                        set heightcheck = false
                        call ForGroup(g, function data.groupdamage)
                        call DestroyEffect(AddSpecialEffect(SFX2, x, y))
                        call DestroyEffect(AddSpecialEffect(SFX3, x, y))
                        call DestroyEffect(d.e1[ii])
                        call DestroyEffect(d.e2[ii])
                        call RemoveUnit(d.dum[ii])
                    endloop
                    set ii = 0
                    set d.step = 5
                endif
            
                if d.step == 5 then
                    loop
                        exitwhen ii == d.dummys2
                        set ii = ii + 1
                        set x = d.tx+d.aoe2*Cos(bj_PI*2./d.dummys2*ii)
                        set y = d.ty+d.aoe2*Sin(bj_PI*2./d.dummys2*ii)
                        loop
                            exitwhen iii == d.dummys3/d.dummys2
                            set iii=iii+1
                            set d.dum[iii] = CreateUnit(Player(15), DummyID, x, y, (ii*(bj_PI*2.)/3.))
                            call PauseUnit(d.dum[ii], true)
                            set d.e1[iii] = AddSpecialEffectTarget(Dummy3attach , d.dum[iii], "chest")
                            call UnitAddAbility(d.dum[iii], CrowFormID)
                            set d.maxheight3[iii] = Dummy3maxHeight(d.dist, GetUnitAbilityLevel(d.cast, SpellID))
                        endloop
                    endloop
                    set d.formula = 0.
                    set ii = 0
                    set iii = 0
                    set d.step = 6
                endif
            
                if d.step == 6 then
                    set d.formula = d.formula+1./Steps3
                    loop
                        exitwhen ii == d.dummys3
                        set ii = ii + 1
                        set x = GetUnitX(d.dum[ii])+d.aoe3/20.*Cos(ii*(bj_PI*2.)/3.)
                        set y = GetUnitY(d.dum[ii])+d.aoe3/20.*Sin(ii*(bj_PI*2.)/3.)
                        call SetUnitPosition(d.dum[ii], x, y)
                        call SetUnitFlyHeight(d.dum[ii], d.maxheight3*d.formula, 0.)
                        set p = GetOwningPlayer(d.cast)
                        set d.cas = d.cast
                        set d.dam = d.dmg3
                        set heightcheck = true
                        set d.h = GetUnitFlyHeight(d.dum[ii])
                        call GroupEnumUnitsInRange(g, x, y, d.aoe3, b)
                        call ForGroup(g, function data.groupdamage)
                    endloop
                    set ii = 0
                    if d.formula >= 1. then
                        loop
                            exitwhen ii == d.dummys3
                            set ii = ii + 1
                            call DestroyEffect(d.e1[ii])
                            call RemoveUnit(d.dum[ii])
                        endloop
                        set ii = 0
                        set d.formula = 0
                        set d.curdist = 0
                        set d.total = d.total - 1
                        set d.ar[i] = d.ar[d.total]
                        call d.destroy()
                        set i = i - 1
                    endif
                endif
                set i = i + 1
            endloop
            if d.total == 0 then
                call PauseTimer(d.tim)
            endif
        endmethod
        
        static method actions takes nothing returns nothing
            local data d = data.allocate()
            local integer lev = GetUnitAbilityLevel(GetTriggerUnit(), SpellID)
            set d.tx = GetSpellTargetX()
            set d.ty = GetSpellTargetY()
            set d.cast = GetTriggerUnit()
            set d.cx = GetUnitX(d.cast)
            set d.cy = GetUnitY(d.cast)
            set d.ang = Atan2(d.ty-d.cy, d.tx-d.cx)
            set d.dist = SquareRoot(Pow(d.tx-d.cx, 2.)+Pow(d.ty-d.cy,2.))
            set d.aoe1 = AoE1(d.dist, lev)
            set d.aoe2 = AoE2(d.dist, lev)
            set d.aoe3 = DamagePerSecAoe(d.dist, lev)
            set d.dmg1 = Damage1(d.dist, lev)
            set d.dmg2 = Damage2(d.dist, lev)
            set d.dmg3 = DamagePerSec(d.dist, lev)
            set d.maxheight2 = Dummy2maxHeight(d.dist, lev)
            set d.step = 0
            set d.dummys1 = Dummys1(lev)
            set d.dummys2 = Dummys2(lev)
            set d.dummys3 = Dummys3(lev)
            if d.total == 0 then
                call TimerStart(d.tim, TimerInt, true, function data.periodic)
            endif
            set d.ar[d.total] = d
            set d.total = d.total + 1
        endmethod
        
    endstruct
        
    private function condition takes nothing returns boolean
        return GetSpellAbilityId()==SpellID
    endfunction



    
    private function noleakfilter takes nothing returns boolean
        return true
    endfunction

    private function init takes nothing returns nothing
        local trigger t = CreateTrigger()
        local integer i = 0
        local filterfunc ff = Filter(function noleakfilter)
        loop
            exitwhen i >= bj_MAX_PLAYER_SLOTS
            call TriggerRegisterPlayerUnitEvent(t, Player(i), EVENT_PLAYER_UNIT_SPELL_EFFECT, ff)
            set i = i + 1
        endloop
        set i = 0
        call TriggerAddAction(t, function data.actions)
        call TriggerAddCondition(t, Condition(function condition))
        set b = Condition(function UnitFilter)
        call DestroyFilter(ff)
        set ff = null
    endfunction
endscope

Hope you enjoy.

Productive critisism and credits are welcome.


v1.00 First idea
v1.1-2.5 irrelevant changes in fail GUI
v2.5 made it vJass
v3.0 got it working in vJass
v3.1 -Improved efficiency by inlining a function (©Anachron)
-Improved documentation by putting things above the code(©Anachron)
-Improved accuracy of first dummies (©Thanatos)
-added FAQ
-added JNGP link.


Keywords:
Fire, Rage, Wrath, Hot, Babes, Burning, Flame, Blaze, Fiery, Rofl, Coptor, Roflcoptor, Roflcopter, Copter
Contents

Fiery Rage v3.1 (Map)

Reviews
11:49, 15th Oct 2009 TriggerHappy187: Spell is nice and can be approved. I couldn't see any leaks inside the code and only some minor improvements. But I should just say that local filterfunc ff = Filter(function noleakfilter) is not needed. null...

Moderator

M

Moderator

11:49, 15th Oct 2009
TriggerHappy187:

Spell is nice and can be approved. I couldn't see any leaks inside the code and only some minor improvements. But I should just say that local filterfunc ff = Filter(function noleakfilter) is not needed. null filters don't leak inside events.
 
Level 9
Joined
Aug 2, 2008
Messages
219
Awesome spell you made there ! I really like the missile arcing and the eyecandies are also sweet ! The spell is MUI and seems to be leakless. The code in general looks neat and i like your way of projecting the X/Y coords. It has good inCode comments and a description. The only you might improve is the accuracy of the missiles, they travel near the targetloc but are not really precise and the more missiles you have the less accurate they are. Anyway the spell is worth an approval =)

~TNT
 
JASS:
private function AoE2 takes real dist, integer lev returns real
        return dist/3.
    endfunction
Rename the function man, who the hell should know what AoE2 is meant to be?

JASS:
set ii = ii + 1
How the hell should know what you are counting with this?
JASS:
set curUnit = curUnit + 1 
and
set curInstance = curInstance + 1
is alot better, for example.
 
Level 9
Joined
Nov 25, 2008
Messages
194
JASS:
private function AoE2 takes real dist, integer lev returns real
        return dist/3.
    endfunction
Rename the function man, who the hell should know what AoE2 is meant to be?

JASS:
set ii = ii + 1
How the hell should know what you are counting with this?
JASS:
set curUnit = curUnit + 1 
and
set curInstance = curInstance + 1
is alot better, for example.

Uhm, you did rid the full code?

You're right about the i's, although i think it doesn't matter, because this part of the code is meant to stay as it is.
And hm, who the hell should know what Aoe2 is, maybe the one who has read the green text underneath the function? Or should i call it:
JASS:
function TheAoeinwhichtheunitsaffectedbydamage2arehit takes ....

I didn't think so.

But just for you to know, the full quote:
Roflcoptor said:
JASS:
    private function AoE2 takes real dist, integer lev returns real
        return dist/3.
    endfunction
    //^The Aoe of Damage2.

and
JASS:
    private function Damage2 takes real dist, integer lev returns real
        return lev*25.
    endfunction
    //^The damage done, when the second dummies reach their target.
 
Uhm, you did rid the full code?

You're right about the i's, although i think it doesn't matter, because this part of the code is meant to stay as it is.
And hm, who the hell should know what Aoe2 is, maybe the one who has read the green text underneath the function? Or should i call it:
JASS:
function TheAoeinwhichtheunitsaffectedbydamage2arehit takes ....

I didn't think so.

But just for you to know, the full quote:
All write comments above the code, so also please do that.
About the naming: You can call it for example AoEDamage or someting like that.

And about the ii stuff: The bigger your code gets, the more important it is to even name counter correctly.

Its ok for know, but I have codes with 10k lines and more and there you have to get everything.
 
Level 9
Joined
Nov 25, 2008
Messages
194
Well calling it aoedamage wont make any difference since there are 3 damages and all three are aoe, and the aoe doesn't only affect the damage, but somoe other stuff.

Well i thought it would be clear that the comments underneath belong there, because there is no free space between it and there's some kind of arrow(^) at the beginning of every comment, but you're right, i might change this in a further version.
 
JASS:
//                      exitwhen ii >= d.dummys2
//                      set ii = ii + 1
//                      set x = d.tx+d.curdist*Cos(bj_PI*2./d.dummys2*ii)
//                      set y = d.ty+d.curdist*Sin(bj_PI*2./d.dummys2*ii)
//                      call SetUnitPosition(d.dum[ii], x, y)
                        call SetUnitFlyHeight(d.dum[ii], d.maxheight2*Sin(d.formula), 0.)
//                      set p = GetOwningPlayer(d.cast)
//                      call GroupEnumUnitsInRange(g, x, y, d.aoe3, b)
//                      set d.dam = d.dmg3
//                      set d.cas = d.cast
                        set d.h = GetUnitFlyHeight(d.dum[ii])
//                     set heightcheck = true
//                     call ForGroup(g, function data.groupdamage)
Calculate a temporary
JASS:
local height h = d.maxheight2*Sin(d.formula)
and then use
JASS:
//                     exitwhen ii >= d.dummys2
//                      set ii = ii + 1
//                      set x = d.tx+d.curdist*Cos(bj_PI*2./d.dummys2*ii)
//                      set y = d.ty+d.curdist*Sin(bj_PI*2./d.dummys2*ii)
//                      call SetUnitPosition(d.dum[ii], x, y)
                        set h = d.maxheight2*Sin(d.formula)
                        call SetUnitFlyHeight(d.dum[ii], h, 0.)
//                      set p = GetOwningPlayer(d.cast)
//                      call GroupEnumUnitsInRange(g, x, y, d.aoe3, b)
//                      set d.dam = d.dmg3
//                      set d.cas = d.cast
                        set d.h = h
//                      set heightcheck = true
//                      call ForGroup(g, function data.groupdamage)

or even better, overwrite the values

JASS:
//                     exitwhen ii >= d.dummys2
//                      set ii = ii + 1
//                      set x = d.tx+d.curdist*Cos(bj_PI*2./d.dummys2*ii)
//                      set y = d.ty+d.curdist*Sin(bj_PI*2./d.dummys2*ii)
//                      call SetUnitPosition(d.dum[ii], x, y)
                        set d.h = d.maxheight2*Sin(d.formula)
                        call SetUnitFlyHeight(d.dum[ii], d.h, 0.)
//                      set p = GetOwningPlayer(d.cast)
//                      call GroupEnumUnitsInRange(g, x, y, d.aoe3, b)
//                      set d.dam = d.dmg3
//                      set d.cas = d.cast
//                      set heightcheck = true
//                      call ForGroup(g, function data.groupdamage)

Edit:
JASS:
call ForGroup(g, function data.groupdamage)

ForGroups are bad, I would either use

JASS:
local unit u = null

loop
   set u = FirstOfGroup(g)
   exitwhen u == null
   call GroupRemoveUnit(g, u)
   call data.unitdamage(u)
endloop

instead of that native.

But that really doesn't matter at all.

Edit2:
JASS:
call SetUnitScale(u, SFX1size, SFX1size, SFX1size)
You should save somewhere the default scale, because remember, you can change the scale in object editor.
Else you will get bugs if you change object editor scale and use this spell.

Edit3:
JASS:
                          set p = GetOwningPlayer(d.cast)
//                        set d.cas = d.cast
//                        set d.dam = d.dmg3
//                        set heightcheck = true
//                        set d.h = GetUnitFlyHeight(d.dum[ii])
//                        call GroupEnumUnitsInRange(g, x, y, d.aoe3, b)
//                        call ForGroup(g, function data.groupdamage)
Where do you need p for?
 
Level 9
Joined
Nov 25, 2008
Messages
194
Wow Anachron nice thanks.

Well someone (I think it was DD) once said, ForGroup would be 16-times faster than the FirstOfGroup method.

And p is used in the boolexpr for filtering group units (it is the owning player) so you only hit enemies. It was the only solution to transfer this data.

Well about the size, why should someone change the size of a dummy unit, used for this spell? Oo

Everything else: Really Great, thanks!


Oh and a question to the public: Should I add the possibility to destroy trees?
(Cause fire normally burns wood)
 
Well someone (I think it was DD) once said, ForGroup would be 16-times faster than the FirstOfGroup method.
Oh hell, why should it? Its basicly in blizzard just a loop which saves the bj_PickedUnit to the current unit and runs the method for every unit.

And p is used in the boolexpr for filtering group units (it is the owning player) so you only hit enemies. It was the only solution to transfer this data.
OH I see. Yeah, I see. I doubt you need this when you don't use ForGroup.

Well about the size, why should someone change the size of a dummy unit, used for this spell? Oo
Because he can, and then it gets bugged? Its not the fault why users should make it buggy, they don't know that it will bug then, just remove the possibility and then everything is fine.
 
Level 9
Joined
Nov 25, 2008
Messages
194
Ok point 1:
-I don't know if it is right, but what DD said was, that the ForGroup uses a C++ For-Loop, which would be 16-times faster than JASS-Loops.
And besides your version is also really strange: First it would double-remove the unit, second it would include many useless function calls. I'd rather write the whole function in the loop then.

-Well, actually it has nothing to do with the ForGroup() but rather with the GroupEnumUnitsInRange().
If I did it the FirstOfGroup-way, I could just check inside the loop, but this would increase the number of loop-runs.

-I am not quite sure about this issue. My first idea would be adding it into the docu that you don't change the size. The other solution would be a global, holding the actual size of the unit.
 
Level 9
Joined
Nov 25, 2008
Messages
194
@Cocobo you need the newest version of both world editor and jassnewgenpack, otherwise you can only test the map.

@baassee: Yeah that's what I thought first, too.
But simply create a GUI-Trigger with just one action (Unit - Damage Target) with spells and normal and you'll see that in jass it's both normal ;)
 
Level 4
Joined
Jan 7, 2014
Messages
69
i didnt found there somethin like DestroyGroup...so its leak or not? idk how its works in structs. and why i askin. pls tell me, if u not sure, then dont answer ;)
 
Top