HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Inner Flame Code opinion (simple spell)

04-25-2009, 07:54 PM#1
Flame_Phoenix
Hi guys, I am making a simple spell using ABuff and UnitProperties from to make a spell that gives extra armor depending on the number of nearby allied Undead and ChaosOrc units near the caster.
I made the code and I intend to submit it, however I would like an opinion first. Also, I expect cool ideas for the spell, so I decided to use a struct (yes if I want to add extra bonuses, it will be easier !)

Collapse JASS:
//===========================================================================
//This ability gives the caster bonus armor depending on the number of 
//allied ChaosOrc units and Undead units nearby. It gains 1 armor per each unit
//and can get a maximum armor bonus of 5.
//
//Requires:
// - Abuff
// - UnitProperties
//
//@author Flame_Phoenix 
//
//@credits:
// - Anitarf, for ABuff
// - Litany, for UnitProperties
// - tamisrah, for helping me fix a bug with the spell
//
//@version 1.2
//===========================================================================
scope ChaoticDetermination initializer Init 
//===========================================================================
//=============================SETUP START===================================
//===========================================================================
    globals
        private constant integer AID = 'A052'
        private constant integer AURA_ID = 'A03O'
        private constant integer BUFF_ID = 'B00B'
        private constant string EFF = "Abilities\\Spells\\NightElf\\Taunt\\TauntCaster.mdl"
    endglobals
    
    private constant function MaxBonus takes integer level returns integer 
    //the maximum amount of armor the caster can receive
        return 5
    endfunction
    
    private constant function Radius takes integer level returns real
    //the AOE of the spell
        return 300.
    endfunction
    
    private constant function Duration takes integer level returns real
    //the duration of the spell
        return 45.
    endfunction
    
    private function CountUnits takes unit caster, unit helper returns boolean
    //the units that will add the bonus to the caster
        return IsUnitAlly(helper, GetOwningPlayer(caster)) and (IsUnitType(helper, UNIT_TYPE_STRUCTURE) == false) and (IsUnitType(helper, UNIT_TYPE_MECHANICAL) == false) and (GetWidgetLife(helper) > 0.405) and (caster != helper) and (IsUnitType(helper, UNIT_TYPE_UNDEAD) or (Race[GetPlayerId(GetOwningPlayer(helper))+1] == "Chaos_Orc"))
    endfunction
//===========================================================================
//=============================SETUP END=====================================
//=========================================================================== 
    globals
        private group helpers
        private boolexpr chooseHelpers
        private unit tmpCaster
        public aBuffType id = 0
    endglobals
    
    private struct aCaster
        unit caster
        integer bonus
        
        static method create takes unit c returns aCaster
            local aCaster data = aCaster.allocate()
            set data.caster = c
            return data
        endmethod
    endstruct
//===========================================================================
    private function ChooseHelpers takes nothing returns boolean
        return CountUnits(tmpCaster, GetFilterUnit())
    endfunction
//===========================================================================
    private function Cleanup takes aBuff eventBuff returns nothing
        local aCaster data = eventBuff.data
        
        call UnitModifyArmor(eventBuff.target.u, -data.bonus)
        call data.destroy()
        
        call UnitRemoveAbility(eventBuff.target.u, AURA_ID)
        
        //so we don't wait 2 seconds because of the aura
        call UnitRemoveAbility(eventBuff.target.u, BUFF_ID) 
    endfunction
//===========================================================================
    private function Create takes aBuff eventBuff returns nothing
        local aCaster data = eventBuff.data
        //give the bonus!
        call UnitModifyArmor(data.caster, data.bonus)
        
        //now we add the buff, we always add the buff xD
        call UnitAddAbility(eventBuff.target.u, AURA_ID)
        
        //prevent morphing from removing the ability
        call UnitMakeAbilityPermanent(eventBuff.target.u, true, AURA_ID) 
    endfunction
//===========================================================================
    private function Conditions takes nothing returns boolean
        return GetSpellAbilityId() == AID
    endfunction
//===========================================================================
    private function Actions takes nothing returns nothing
        local aCaster data = aCaster.create(GetTriggerUnit())
        local integer level = GetUnitAbilityLevel(data.caster, AID)
        
        //create a nice casting effect
        call DestroyEffect(AddSpecialEffect(EFF, GetUnitX(data.caster), GetUnitY(data.caster)))
        
        //here we count the bonus we will add and clear the group
        set tmpCaster = data.caster
        call GroupEnumUnitsInRange(helpers, GetUnitX(data.caster), GetUnitY(data.caster), Radius(level), chooseHelpers)
        
        //save the number of units and clear the group
        set data.bonus = CountUnitsInGroup(helpers)
        call GroupClear(helpers)
        
        //if we have more then 0 units, then we add the ability, else we don't
        if data.bonus > 0 then
        
            //at this point it is certain that we will use UnitProperties
            //so we innitialize it
            call CreateUnitProperties(data.caster)
            
            //we make a quick check for the max level
            if data.bonus > MaxBonus(level) then
                set data.bonus = MaxBonus(level)
            endif
            
            //apply the buff to the unit
            call ABuffApply(id, data.caster, data.caster, Duration(level), level, integer(data))
        endif
    endfunction
//===========================================================================
    private function Init takes nothing returns nothing
        local trigger ChaoticDetermTrg = CreateTrigger(  )
        call TriggerRegisterAnyUnitEventBJ(ChaoticDetermTrg, EVENT_PLAYER_UNIT_SPELL_EFFECT )
        call TriggerAddCondition(ChaoticDetermTrg, Condition(function Conditions))
        call TriggerAddAction(ChaoticDetermTrg, function Actions)
        
        //setting our globals
        set helpers = CreateGroup()
        set chooseHelpers = Condition(function ChooseHelpers)
        set id = aBuffType.create()
        
        //setting Abuff
        set id.eventCreate = ABuffEvent_Create.Create
        set id.eventCleanup = ABuffEvent_Cleanup.Cleanup
        
        //preloading effects
        call Preload(EFF)
    endfunction
endscope

Hope you like it!