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

Fireworks v1.01

Fireworks
The hero creates a massive explosion of colourful damaging and blinding sparks.


JASS:
//*****************************************************************************************
//*****************************************************************************************
//**                                                                                   //**
//**                               Name : Fireworks  v1.01                             //**
//**                                                                                   //**
//**                              Author : scorpion182                                 //**
//**                                                                                   //**
//**                                                                                   //**
//*****************************************************************************************
//*****************************************************************************************
//Description:                                                                         //**
//The hero creates a massive explosion of colourful damaging and blinding sparks.      //**
//*****************************************************************************************
library Fireworks initializer init requires TimerUtils, xedamage, xecast, xefx, GroupUtils
//===========================================================================
//=============================SETUP START===================================
//===========================================================================
    globals
        private constant integer SPELL_ID='A000' //fireworks ability rawcode
        private constant integer DUMMY_SPELL='A001' //fireworks dummy ability rawcode
        private constant string ORDER_ID="dispel" //fireworks order string
        private constant string DUMMY_ORDER="drunkenhaze"
        private constant string FX="Abilities\\Spells\\Human\\Flare\\FlareTarget.mdl" //spell effect
        private constant real AOE=175. //aoe for missiles
        private constant real RAIN_AOE=500. //rain radius
        private constant real INTERVAL=0.3 //how often new missiles are created
        private constant real SCALE=1.0 //missile scale
    endglobals

    private constant function GetDamage takes integer lvl returns real
        return 50.+50.*lvl //deals 100/150/200 damage
    endfunction
    //damage filter
    private function DamageOptions takes xedamage spellDamage returns nothing
        set spellDamage.dtype=DAMAGE_TYPE_UNIVERSAL
        set spellDamage.atype=ATTACK_TYPE_NORMAL
        set spellDamage.exception=UNIT_TYPE_STRUCTURE
        set spellDamage.visibleOnly=true
        set spellDamage.damageAllies=false       
    endfunction
//===========================================================================
//=============================SETUP END=====================================
//=========================================================================== 
    globals
        private xedamage xed
        private xecast cast
        private boolexpr b
    endglobals
    
    private function IsUnitAlive takes nothing returns boolean
      return not IsUnitType(GetFilterUnit(), UNIT_TYPE_DEAD) or GetUnitTypeId(GetFilterUnit()) != 0
    endfunction
    //set xecast
    private function SetDummy takes xecast DummySpell returns nothing 
        set DummySpell.abilityid=DUMMY_SPELL
        set DummySpell.orderstring=DUMMY_ORDER  
    endfunction
    //Spell struct
    private struct data
        unit caster
        timer t
        xefx fx
        integer lvl
        //create
        static method create takes unit c, timer t returns data
            local data d=data.allocate()
            set d.caster=c
            set d.t=t
            set d.lvl=GetUnitAbilityLevel(c,SPELL_ID)
        
            return d
        endmethod
        
        public method createSparks takes real x, real y returns nothing
        
            if (.fx!=null) then
                call .fx.destroy()
                
                call GroupEnumUnitsInRange(ENUM_GROUP,x,y,AOE,b)
                set cast.owningplayer = GetOwningPlayer(.caster)
                set cast.level=.lvl
                //the unit group will get cleaned after calling this function
                call cast.castOnGroup(ENUM_GROUP)
                call GroupEnumUnitsInRange(ENUM_GROUP,x,y,AOE,b)
                //the unit group will get cleaned after calling this function
                call xed.damageGroup(.caster,ENUM_GROUP,GetDamage(.lvl))
            endif
            set .fx=xefx.create(x,y,0)
            set .fx.fxpath=FX
            set .fx.scale=SCALE
        endmethod
        
        private method onDestroy takes nothing returns nothing
            call ReleaseTimer(.t)
            call GroupRefresh(ENUM_GROUP)
            if (.fx!=null) then
                call .fx.destroy()
            endif
        endmethod
    endstruct

    //Ready to fire!
    private function Shower takes nothing returns nothing
        local timer t=GetExpiredTimer()
        local data d=data(GetTimerData(t))
        local real an = GetRandomReal ( 1 , 360 )
        local real dis = GetRandomReal ( 1 , RAIN_AOE )
        local real rad = an *3.14159/180
        local real x = GetUnitX (d.caster) + dis * Cos ( rad )
        local real y = GetUnitY (d.caster) + dis * Sin ( rad )
        
        if GetUnitCurrentOrder(d.caster)==OrderId(ORDER_ID) then //check the caster still casting or not
            call d.createSparks(x,y)
        else
            call d.destroy()
        endif
    
        set t=null
    endfunction
    //Spell Trigger Actions
    private function SpellEffect takes nothing returns nothing
        local timer t
        local data d
    
        if GetSpellAbilityId() == SPELL_ID then
            set t=NewTimer()
            set d=data.create(GetSpellAbilityUnit(),t)
            call SetTimerData(t,integer(d))
            call TimerStart(t,INTERVAL,true,function Shower)
        endif
    
        set t=null
    endfunction

    private function init takes nothing returns nothing
        //init spellcast trigger 
        local trigger t=CreateTrigger()
        call TriggerRegisterAnyUnitEventBJ(t,EVENT_PLAYER_UNIT_SPELL_EFFECT)
        call TriggerAddAction(t,function SpellEffect)
        
        set b=Condition(function IsUnitAlive)
        
        //init xedamage
        set xed=xedamage.create()
        call DamageOptions(xed)
        
        //init xecast
        set cast = xecast.create()  
        call SetDummy(cast)
        
        //preload dummy ability
        call XE_PreloadAbility(DUMMY_SPELL)
    endfunction
endlibrary



Requires:
- TimerUtils by Vexorian
- xe by Vexorian
- GroupUtils by Rising_Dusk

Keywords:
firework, new, year, wizard, magic, area, damage, blind, miss, spark, archmage, mage, colorful
Contents

Fireworks v1.01 (Map)

Reviews
17:51, 22nd Dec 2009 TriggerHappy: Review for Spell The effect was cool and the coding was good. The only thing I would suggest is to use the UnitAlive AI native instead of your filter. Send me a message if you want to know how to use...

Moderator

M

Moderator

17:51, 22nd Dec 2009
TriggerHappy:

Review for Spell

The effect was cool and the coding was good.
The only thing I would suggest is to use the UnitAlive AI native
instead of your filter.

Send me a message if you want to know how to use it.

Status

Feel free to message me here if you have any issues with
my review or if you have updated your resource and want it reviewed again.

Approved
 
Level 13
Joined
Mar 19, 2010
Messages
870
Bug: I got a

"Double free of type: xefx" if i'm using the spell 2,3,4...times


edit:

Just do this and it's all good!

JASS:
private method onDestroy takes nothing returns nothing
            call ReleaseTimer(.t)
            call GroupRefresh(ENUM_GROUP)
            /*if (.fx != null) then
                call .fx.destroy()
            endif*/
        endmethod
 
Top