HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

SunRay - spell oppinion

09-12-2008, 06:59 PM#1
Flame_Phoenix
Ok guys, this another of my spells. I trust Moyack is going to be happy with this one, it is not channeling. It is however, a very simple spell I made, I may "spice it" a little bit more.
Anyway, I hope you like this simple spell of mine. Please make CONSTRUCTIVE criticism. This will be my next submission to this community.

Collapse JASS:
//===========================================================================
//The caster uses his light powers to summon Light Rays around him, damaging 
//enemy Undead units nearby, and healing allied units
//
//@author Flame_Phoenix 
//
//@credits
//- Modeler, he originally created the spell, I remade it into something different. 
//- the-thingy, by telling me where to use bj_DEGTORAD and why
//- Alexander244, for helping me fixing a bug with parenthesis ... lol
//- My first teacher of vJASS: Blue_Jeans
//- All other people I forgot or ignored
//
//@version 1.0
//===========================================================================
scope SunRay initializer Init
    
    //needed for spell's core, don't change
    private keyword tmpPlayer
//===========================================================================
//=============================SETUP START===================================
//===========================================================================
    globals
        private constant integer AID = 'A000'   //raecode of ability
        private constant real LIGHT_RADIUS = 100    //radius of each single light
        private constant string LIGHT_EFFECT = "Abilities\\Spells\\Human\\HolyBolt\\HolyBoltSpecialArt.mdl" //the effect of the light
    endglobals

    private constant function Damage takes integer level returns real
        return level * 5.  //the damage the enemy undead units will take
    endfunction
    
    private constant function Heal takes integer level returns real
        return level * 10. //the heal your allied units will receive
    endfunction
    
    private constant function LightNumber takes integer level returns integer
    //each Sun Ray of (4 + level) lights
        return 4 + level
    endfunction
    
    private constant function RayNumber takes integer level returns integer
    //the number of Sun Rays of the spell
        return 5 + level
    endfunction
    
    private function AllyTargets takes nothing returns boolean
    //what allied units will be affected by the spell
        return IsUnitAlly(GetFilterUnit(), tmpPlayer) and (IsUnitType(GetFilterUnit(), UNIT_TYPE_STRUCTURE) == false) and (IsUnitType(GetFilterUnit(), UNIT_TYPE_MAGIC_IMMUNE) == false) and (IsUnitType(GetFilterUnit(), UNIT_TYPE_MECHANICAL) == false) and (GetWidgetLife(GetFilterUnit()) > 0.405)
    endfunction
    
    private function EnemyTargets takes nothing returns boolean
    //what enemy units will be affected by the spell
        return IsUnitEnemy(GetFilterUnit(), tmpPlayer) and (IsUnitType(GetFilterUnit(), UNIT_TYPE_STRUCTURE) == false) and (IsUnitType(GetFilterUnit(), UNIT_TYPE_MAGIC_IMMUNE) == false) and (IsUnitType(GetFilterUnit(), UNIT_TYPE_MECHANICAL) == false) and (GetUnitRace(GetFilterUnit()) == RACE_UNDEAD) and (GetWidgetLife(GetFilterUnit()) > 0.405)
    endfunction
//===========================================================================
//=============================SETUP END=====================================
//===========================================================================

    globals
        private player tmpPlayer
        private group g
        private boolexpr enemies
        private boolexpr allies
    endglobals
//===========================================================================
    private function Conditions takes nothing returns boolean
        return GetSpellAbilityId() == AID
    endfunction
//===========================================================================    
    private function Actions takes nothing returns nothing
        local unit caster = GetTriggerUnit()
        local real casterX = GetUnitX(caster)
        local real casterY = GetUnitY(caster)
        local integer level = GetUnitAbilityLevel(caster, AID)
        local unit f
        local real x 
        local real y
        local integer i
        local integer j
        local real distInc
        local real angle = 0
        
        //in this outer loop we create the Sun Rays
        set i = 0
        loop
            exitwhen(i == RayNumber(level))
            
            set distInc = 0
            //in this inner loop we create the lights of each SunRay
            set j = 0
            loop
                exitwhen(j == LightNumber(level))
            
                set x = casterX + distInc * Cos(angle)
                set y = casterY + distInc * Sin(angle)
            
                call DestroyEffect(AddSpecialEffect(LIGHT_EFFECT, x, y))
            
                //in this first double inner loop we select the enemy units and damage them
                set tmpPlayer = GetOwningPlayer(caster)
                call GroupEnumUnitsInRange(g, x, y, LIGHT_RADIUS, enemies)
                loop
                    set f = FirstOfGroup(g)
                    exitwhen(f == null)
                    call GroupRemoveUnit(g, f)
                    call UnitDamageTarget(caster, f, Damage(level), true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_UNIVERSAL, null)
                endloop
            
                //in this second double inner loop we select the allied units and heal them
                set tmpPlayer = GetOwningPlayer(caster)
                call GroupEnumUnitsInRange(g, x, y, LIGHT_RADIUS, allies)
                loop
                    set f = FirstOfGroup(g)
                    exitwhen(f == null)
                    call GroupRemoveUnit(g, f)
                    call SetWidgetLife(f, GetWidgetLife(f) + Heal(level))
                endloop
            
                set distInc = distInc + LIGHT_RADIUS
                set j = j + 1
            endloop
            
            set angle = angle + (360 / RayNumber(level)) * bj_DEGTORAD
            set i = i + 1
        endloop
        
        set caster = null
    endfunction
//===========================================================================
    private function Init takes nothing returns nothing
        local trigger SunRayTrg = CreateTrigger(  )
        call TriggerRegisterAnyUnitEventBJ( SunRayTrg, EVENT_PLAYER_UNIT_SPELL_EFFECT )
        call TriggerAddCondition( SunRayTrg, Condition( function Conditions ) )
        call TriggerAddAction( SunRayTrg, function Actions )
        
        set SunRayTrg = null
        
        //setting globals
        set g = CreateGroup()
        set enemies = Condition(function EnemyTargets)
        set allies = Condition(function AllyTargets)
        
        //preloading effect
        call Preload(LIGHT_EFFECT)
    endfunction
endscope
Attached Files
File type: w3xSunRay.w3x (24.5 KB)
09-12-2008, 08:05 PM#2
Ammorth
why are you creating another thread about your spell when you clearly have one already?
09-12-2008, 10:38 PM#3
Flame_Phoenix
That other thread is not about the spell, it was about a mathematic formula. This is something different, and therefore I believe it requires a different post.
Any comments about the spell ?

EDIT EDIT EDIT

Ok guys, here is an update of the spell, Now you can have Waves of light !
and if you don't like it, just set the interval to zero or some very small value xD.
Now the spell uses TimerUtils for high precision =)

Collapse JASS:
//===========================================================================
//The caster uses his light powers to summon waves of Light Rays around him, 
//damaging enemy Undead units nearby, and healing allied units
//
//Requires TimerUtils
//
//@author Flame_Phoenix 
//
//@credits
//- Modeler, he originally created the spell, I remade it into something different. 
//- the-thingy, by telling me where to use bj_DEGTORAD and why
//- Alexander244, for helping me fixing a bug with parenthesis ... lol
//- My first teacher of vJASS: Blue_Jeans
//- All other people I forgot or ignored
//
//@version 1.1
//===========================================================================
scope SunRay initializer Init
    
    //needed for spell's core, don't change
    private keyword tmpPlayer
//===========================================================================
//=============================SETUP START===================================
//===========================================================================
    globals
        private constant integer AID = 'A000'   //raecode of ability
        private constant real LIGHT_RADIUS = 100    //radius of each single light
        private constant string LIGHT_EFFECT = "Abilities\\Spells\\Human\\HolyBolt\\HolyBoltSpecialArt.mdl" //the effect of the light
        private constant real LIGHT_INTERVAL = 0.2 //the interval that separates each light
    endglobals

    private constant function Damage takes integer level returns real
        return level * 5.  //the damage the enemy undead units will take
    endfunction
    
    private constant function Heal takes integer level returns real
        return level * 10. //the heal your allied units will receive
    endfunction
    
    private constant function LightNumber takes integer level returns integer
    //each Sun Ray of (4 + level) lights
        return 4 + level
    endfunction
    
    private constant function RayNumber takes integer level returns integer
    //the number of Sun Rays of the spell
        return 5 + level
    endfunction
    
    private function AllyTargets takes nothing returns boolean
    //what allied units will be affected by the spell
        return IsUnitAlly(GetFilterUnit(), tmpPlayer) and (IsUnitType(GetFilterUnit(), UNIT_TYPE_STRUCTURE) == false) and (IsUnitType(GetFilterUnit(), UNIT_TYPE_MAGIC_IMMUNE) == false) and (IsUnitType(GetFilterUnit(), UNIT_TYPE_MECHANICAL) == false) and (GetWidgetLife(GetFilterUnit()) > 0.405)
    endfunction
    
    private function EnemyTargets takes nothing returns boolean
    //what enemy units will be affected by the spell
        return IsUnitEnemy(GetFilterUnit(), tmpPlayer) and (IsUnitType(GetFilterUnit(), UNIT_TYPE_STRUCTURE) == false) and (IsUnitType(GetFilterUnit(), UNIT_TYPE_MAGIC_IMMUNE) == false) and (IsUnitType(GetFilterUnit(), UNIT_TYPE_MECHANICAL) == false) and (GetUnitRace(GetFilterUnit()) == RACE_UNDEAD) and (GetWidgetLife(GetFilterUnit()) > 0.405)
    endfunction
//===========================================================================
//=============================SETUP END=====================================
//===========================================================================

    globals
        private player tmpPlayer
        private group g
        private boolexpr enemies
        private boolexpr allies
    endglobals
    
    private struct MyStruct
        unit caster 
        real casterX
        real casterY
        integer level 
        real x
        real y
        timer t
        integer i
        real angle
        real distInc
        integer lightsCreated
        
        static method create takes unit caster returns MyStruct
            local MyStruct data = MyStruct.allocate()
            
            //setting variables
            set data.caster = caster
            set data.casterX = GetUnitX(caster)
            set data.casterY = GetUnitY(caster)
            set data.level = GetUnitAbilityLevel(caster, AID)
            set data.t = NewTimer() //this will create the lights =)
            set data.angle = 0
            set data.distInc = LIGHT_RADIUS
            set data.x = 0
            set data.y = 0
            set data.lightsCreated = 0
            
            return data
        endmethod
        
        method onDestroy takes nothing returns nothing
            call ReleaseTimer(.t)
        endmethod
    endstruct
//===========================================================================
    private function Conditions takes nothing returns boolean
        return GetSpellAbilityId() == AID
    endfunction
//===========================================================================     
    private function CreateLights takes nothing returns nothing
        local MyStruct data = MyStruct(GetTimerData(GetExpiredTimer())) 
        local unit f
        
        //if we didn't pass the number of lights, than we create lights 
        //again, however, if we did, we end everything
        if data.lightsCreated < LightNumber(data.level) then
            
            //in this outer loop we create the Sun Rays
            set data.i = 0
            loop
                exitwhen(data.i == RayNumber(data.level))
    
                set data.x = data.casterX + data.distInc * Cos(data.angle)
                set data.y = data.casterY + data.distInc * Sin(data.angle)
            
                call DestroyEffect(AddSpecialEffect(LIGHT_EFFECT, data.x, data.y))
            
                //in this first double inner loop we select the enemy units and damage them
                set tmpPlayer = GetOwningPlayer(data.caster)
                call GroupEnumUnitsInRange(g, data.x, data.y, LIGHT_RADIUS, enemies)
                loop
                    set f = FirstOfGroup(g)
                    exitwhen(f == null)
                    call GroupRemoveUnit(g, f)
                    call UnitDamageTarget(data.caster, f, Damage(data.level), true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_UNIVERSAL, null)
                endloop
            
                //in this second double inner loop we select the allied units and heal them
                set tmpPlayer = GetOwningPlayer(data.caster)
                call GroupEnumUnitsInRange(g, data.x, data.y, LIGHT_RADIUS, allies)
                loop
                    set f = FirstOfGroup(g)
                    exitwhen(f == null)
                    call GroupRemoveUnit(g, f)
                    call SetWidgetLife(f, GetWidgetLife(f) + Heal(data.level))
                endloop
            
                set data.angle = data.angle + (360 / RayNumber(data.level)) * bj_DEGTORAD
                set data.i = data.i + 1
            endloop
            
            set data.distInc = data.distInc + LIGHT_RADIUS
            set data.lightsCreated = data.lightsCreated + 1
        else
            call data.destroy()
        endif
        
    endfunction
//===========================================================================    
    private function Actions takes nothing returns nothing
        local MyStruct data = MyStruct.create(GetTriggerUnit())        
        call SetTimerData(data.t, integer(data))
        call TimerStart(data.t, LIGHT_INTERVAL, true, function CreateLights)
    endfunction
//===========================================================================
    private function Init takes nothing returns nothing
        local trigger SunRayTrg = CreateTrigger(  )
        call TriggerRegisterAnyUnitEventBJ( SunRayTrg, EVENT_PLAYER_UNIT_SPELL_EFFECT )
        call TriggerAddCondition( SunRayTrg, Condition( function Conditions ) )
        call TriggerAddAction( SunRayTrg, function Actions )
        
        set SunRayTrg = null
        
        //setting globals
        set g = CreateGroup()
        set enemies = Condition(function EnemyTargets)
        set allies = Condition(function AllyTargets)
        
        //preloading effect
        call Preload(LIGHT_EFFECT)
    endfunction
endscope

Please enjoy and comment. I shall probably make one more update tomorrow, and then submit it =)
Attached Files
File type: w3xSunRay.w3x (31.4 KB)
09-12-2008, 10:48 PM#4
TKF
Perhaps replace the bj_DEGTORAD with my magical number?
09-13-2008, 10:16 AM#5
Flame_Phoenix
Quote:
Perhaps replace the bj_DEGTORAD with my magical number?
Looooool.
Nah constants are faster than magic numbers and calculations because they already save its result, afaik.
Still, thx for posting, hope you like the spell =)

EDIT EDIT EDIT

Ok guys, I made the final update of the spell, I hope you all enjoy it !


Collapse JASS:
/===========================================================================
//The caster uses his light powers to summon waves of Light Rays around him, 
//damaging enemy Undead units nearby, and healing allied units
//
//Requires TimerUtils
//
//@author Flame_Phoenix 
//
//@credits
//- Blackroot (aka Modeler), the first creator, gave me the basic idea and concept
//- the-thingy, by telling me where to use bj_DEGTORAD and why
//- Alexander244, for helping me fixing a bug with parenthesis ... lol
//- My first teacher of vJASS: Blue_Jeans
//- All other people I forgot or ignored
//
//@version 1.2
//===========================================================================
scope SunRay initializer Init
    
    //needed for spell's core, don't change
    private keyword tmpPlayer
//===========================================================================
//=============================SETUP START===================================
//===========================================================================
    globals
        private constant integer AID = 'A000'   //raecode of ability
        private constant real LIGHT_RADIUS = 100    //radius of each single light
        private constant string LIGHT_EFFECT = "Abilities\\Spells\\Human\\HolyBolt\\HolyBoltSpecialArt.mdl" //the effect of the light
        private constant real LIGHT_INTERVAL = 0.2 //the interval that separates each light
    endglobals

    private constant function Damage takes integer level returns real
        return level * 5.  //the damage the enemy undead units will take
    endfunction
    
    private constant function Heal takes integer level returns real
        return level * 10. //the heal your allied units will receive
    endfunction
    
    private constant function LightNumber takes integer level returns integer
    //each Sun Ray of (4 + level) lights
        return 4 + level
    endfunction
    
    private constant function RayNumber takes integer level returns integer
    //the number of Sun Rays of the spell
        return 5 + level
    endfunction
    
    private function AllyTargets takes nothing returns boolean
    //what allied units will be affected by the spell
        return IsUnitAlly(GetFilterUnit(), tmpPlayer) and (IsUnitType(GetFilterUnit(), UNIT_TYPE_STRUCTURE) == false) and (IsUnitType(GetFilterUnit(), UNIT_TYPE_MAGIC_IMMUNE) == false) and (IsUnitType(GetFilterUnit(), UNIT_TYPE_MECHANICAL) == false) and (GetWidgetLife(GetFilterUnit()) > 0.405)
    endfunction
    
    private function EnemyTargets takes nothing returns boolean
    //what enemy units will be affected by the spell
        return IsUnitEnemy(GetFilterUnit(), tmpPlayer) and (IsUnitType(GetFilterUnit(), UNIT_TYPE_STRUCTURE) == false) and (IsUnitType(GetFilterUnit(), UNIT_TYPE_MAGIC_IMMUNE) == false) and (IsUnitType(GetFilterUnit(), UNIT_TYPE_MECHANICAL) == false) and (GetUnitRace(GetFilterUnit()) == RACE_UNDEAD) and (GetWidgetLife(GetFilterUnit()) > 0.405)
    endfunction
//===========================================================================
//=============================SETUP END=====================================
//===========================================================================

    globals
        private player tmpPlayer
        private group g
        private boolexpr enemies
        private boolexpr allies
    endglobals
    
    private struct MyStruct
        unit caster 
        real casterX
        real casterY
        integer level 
        real x
        real y
        timer t
        integer i
        real angle
        real distInc
        integer lightsCreated
        
        static method create takes unit caster returns MyStruct
            local MyStruct data = MyStruct.allocate()
            
            //setting variables
            set data.caster = caster
            set data.casterX = GetUnitX(caster)
            set data.casterY = GetUnitY(caster)
            set data.level = GetUnitAbilityLevel(caster, AID)
            set data.t = NewTimer() //this will create the lights =)
            set data.angle = 0
            set data.distInc = LIGHT_RADIUS
            set data.x = 0
            set data.y = 0
            set data.lightsCreated = 0
            
            return data
        endmethod
        
        method onDestroy takes nothing returns nothing
            call ReleaseTimer(.t)
        endmethod
    endstruct
//===========================================================================     
    private function CreateLights takes nothing returns nothing
        local MyStruct data = MyStruct(GetTimerData(GetExpiredTimer())) 
        local unit f
        
        //if we didn't pass the number of lights, than we create lights 
        //again, however, if we did, we end everything
        if data.lightsCreated < LightNumber(data.level) then
            
            //in this outer loop we create the Sun Rays
            set data.i = 0
            loop
                exitwhen(data.i == RayNumber(data.level))
    
                set data.x = data.casterX + data.distInc * Cos(data.angle)
                set data.y = data.casterY + data.distInc * Sin(data.angle)
            
                call DestroyEffect(AddSpecialEffect(LIGHT_EFFECT, data.x, data.y))
            
                //in this first double inner loop we select the enemy units and damage them
                set tmpPlayer = GetOwningPlayer(data.caster)
                call GroupEnumUnitsInRange(g, data.x, data.y, LIGHT_RADIUS, enemies)
                loop
                    set f = FirstOfGroup(g)
                    exitwhen(f == null)
                    call GroupRemoveUnit(g, f)
                    call UnitDamageTarget(data.caster, f, Damage(data.level), true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_UNIVERSAL, null)
                endloop
            
                //in this second double inner loop we select the allied units and heal them
                set tmpPlayer = GetOwningPlayer(data.caster)
                call GroupEnumUnitsInRange(g, data.x, data.y, LIGHT_RADIUS, allies)
                loop
                    set f = FirstOfGroup(g)
                    exitwhen(f == null)
                    call GroupRemoveUnit(g, f)
                    call SetWidgetLife(f, GetWidgetLife(f) + Heal(data.level))
                endloop
            
                set data.angle = data.angle + (360 / RayNumber(data.level)) * bj_DEGTORAD
                set data.i = data.i + 1
            endloop
            
            set data.distInc = data.distInc + LIGHT_RADIUS
            set data.lightsCreated = data.lightsCreated + 1
        else
            call data.destroy()
        endif
        
    endfunction
//===========================================================================
    private function Conditions takes nothing returns boolean
        local MyStruct data
        if GetSpellAbilityId() == AID then
            set data = MyStruct.create(GetTriggerUnit())
            
            //now we start the timer !
            call SetTimerData(data.t, integer(data))
            call TimerStart(data.t, LIGHT_INTERVAL, true, function CreateLights)
        endif
            
        return false
    endfunction
//===========================================================================
    private function Init takes nothing returns nothing
        local trigger SunRayTrg = CreateTrigger(  )
        call TriggerRegisterAnyUnitEventBJ( SunRayTrg, EVENT_PLAYER_UNIT_SPELL_EFFECT )
        call TriggerAddCondition( SunRayTrg, Condition( function Conditions ) )
        
        set SunRayTrg = null
        
        //setting globals
        set g = CreateGroup()
        set enemies = Condition(function EnemyTargets)
        set allies = Condition(function AllyTargets)
        
        //preloading effect
        call Preload(LIGHT_EFFECT)
    endfunction
endscope

I will submit it today, please all give opinion of this simple light spell =)