HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

SPELL NOT WORKING

09-16-2008, 08:25 AM#1
fX_
EDIT: initial problem solved... it was a stupid trivial thing...

anyway, new problem: the triggers won't work. the timer is created and run but gTRIG_Death doesnt run when a hero dies... gTRIG_Order doesn't validate casting... etc.
Collapse JASS:
//Bonecrusher
//=========================
//Abilities:
//===[Natural Ability] Heavyweight
//For each enemy within 500 range of the Bonecrusher, he pasively gains X additional armor
//and Y additional Strength. When this is casted up to Ys after an enemy hero within
//this range of him dies, after celebrating for some time, he gains Z more Strength
//(any Z > any sum of Xs) for Q seconds. Duration of boon from enemy hero deaths in
//this manner, is wholly reseted at every instance of this effect.
//
//===1) "Don't Poke the Angry Ogre!"
//If there is an enemy unit within 200 range of the Bonecrusher that has damaged
//him at least X times in the last Ys, the Bonecrusher will knock this unit back,
//dealing Z damage to it and stunning it for Qs. If there is no such unit, the
//Bonecrusher will not cast this ability.
//
//===2) Mega Slam
//The Bonecrusher jumps onto a target area, dealing X damage to and stunning for Ys each enemy
//unit in that area when he lands there.
//
//===3) Smush!
//The Bonecrusher sits at where he is at, pinning down all enemies beneath him to
//the ground. Pinned units remain stunned and will continuously take damage for
//as long as he remains seated at this point. If there is beneath the Bonecrusher
//an enemy hero with a Strength greater than his, the Bonecrusher will become
//unable to remain seated.
//
//===4) Big Foot
//When activated, the Bonecrusher gains an X increase to movement speed. Also,
//he will knock-back enemy units that come within Y range of him with AS HE MOVES.
//(Y < Bonecrusher's attack range).

library Bonecrusher initializer Init requires GeneralLibrary

globals
    constant integer gINT_UnitIdBonecrusher = 'O01D'
endglobals

///////////////////////////////////////////////////////
///////============Heavyweight Start============///////
scope Heavyweight

globals
    constant integer gINT_AbilityIdHeavyweight = 'A00Y'
    constant integer gINT_AbilityIdHeavyweightBonusArmor = 'A00T'
    constant integer gINT_AbilityIdHeavyweightBonusStrength = 'A01O'
    constant integer gINT_AbilityIdHeavyweightBoon = 'A01C'
    constant string gSTR_OrderHeavyweight = "roar"
    
    private trigger gTRIG_EnterMap = CreateTrigger()
    private trigger gTRIG_Death = CreateTrigger()
    private trigger gTRIG_Order = CreateTrigger()
    private trigger gTRIG_Cast = CreateTrigger()
    private timer gTIM = CreateTimer()
    private string array gSTR_ModelNameFX
    private constant real gR_DurationTimer = 0.10
    private constant real gR_RangeAoE = 500.00
    private constant real gR_DurationBoon = 10.00
    private constant real gR_DurationDeadHero = 2.00
    private constant integer gINT_MaxLevelAbilityBoon = 4 //(level 1 is null boon; 3 levels of boons)//
    private constant integer gINT_MaxLevelBonus = 11 //(level 1 is null; 10 levels of bonuses)//
    
    private HeavyweightData array gDATA
    private integer gINT_CountData = 0
endglobals

    private function TimerCallback1 takes nothing returns nothing
        local integer INT_CountData = 0
        
        loop
            set INT_CountData = INT_CountData + 1
            call gDATA[INT_CountData].Execute()
            exitwhen INT_CountData == gINT_CountData
        endloop
    endfunction
    
    private function UpdateTimer takes nothing returns nothing
        if gINT_CountData == 1 then
            call TimerStart(gTIM, gR_DurationTimer, TRUE, function TimerCallback1)
        elseif gINT_CountData == 0 then
            call PauseTimer(gTIM)
        endif
    endfunction
    
    private function BoolExpr3 takes nothing returns boolean
        return IsUnitEnemy(GetFilterUnit(), gP) and GetUnitState(GetFilterUnit(), UNIT_STATE_LIFE) > 0
    endfunction

struct HeavyweightData
    integer intDataIndex
    unit uCaster
    effect array fxBoon[5]
    integer intLevelAbilityBoon
    real rDurationBoon
    integer intCountDeadHero
    real rDurationDeadHero

    static method Create takes unit caster returns nothing
        local HeavyweightData New = HeavyweightData.allocate()
        
        set gINT_CountData = gINT_CountData + 1
        set New.intDataIndex = gINT_CountData
        set New.uCaster = caster
        set New.intLevelAbilityBoon = 0
        set New.rDurationBoon = 0.00
        set New.intCountDeadHero = 0
        set New.rDurationDeadHero = 0.00
        set gDATA[gINT_CountData] = New

        call UpdateTimer()
    endmethod
    
    private method Destroy takes nothing returns nothing
        set .uCaster = null
        
        set gDATA[gINT_CountData].intDataIndex = .intDataIndex
        set gDATA[.intDataIndex] = gDATA[gINT_CountData]
        set gDATA[gINT_CountData] = 0
        set gINT_CountData = gINT_CountData - 1
        
        call UpdateTimer()
    endmethod
    
    method Execute takes nothing returns nothing
        local unit U_Target
        local group UG_Target = CreateGroup()
        local integer INT_CountTarget = 1

                    call BJDebugMsg("Heavyweight Level: " + I2S(INT_CountTarget))
            call BJDebugMsg("Heavyweight Level: " + I2S(.intLevelAbilityBoon))
            call BJDebugMsg("Heavyweight Level: " + I2S(.intCountDeadHero))
        if IsUnitInRegion(gREG_Map, .uCaster) then
            set gP = GetOwningPlayer(.uCaster)
            call GroupEnumUnitsInRange(UG_Target, GetUnitX(.uCaster), GetUnitY(.uCaster), gR_RangeAoE, Filter(function BoolExpr3))
            set gP = null
            loop
                set U_Target = FirstOfGroup(UG_Target)
                exitwhen U_Target == null
                set INT_CountTarget = INT_CountTarget + 1
                call GroupRemoveUnit(UG_Target, U_Target)
            endloop
            if INT_CountTarget > gINT_MaxLevelBonus then
                set INT_CountTarget = gINT_MaxLevelBonus
            endif
            call SetUnitAbilityLevel(.uCaster, gINT_AbilityIdHeavyweight, INT_CountTarget)
            call SetUnitAbilityLevel(.uCaster, gINT_AbilityIdHeavyweightBonusArmor, INT_CountTarget)
            call SetUnitAbilityLevel(.uCaster, gINT_AbilityIdHeavyweightBonusStrength, INT_CountTarget)
            
            if .intLevelAbilityBoon > 1 then
                set .rDurationBoon = .rDurationBoon - gR_DurationTimer
                if .rDurationBoon == 0 then
                    call SetUnitAbilityLevel(.uCaster, gINT_AbilityIdHeavyweightBoon, 1)
                    call DestroyEffect(.fxBoon[0])
                    call DestroyEffect(.fxBoon[1])
                    call DestroyEffect(.fxBoon[2])
                    call DestroyEffect(.fxBoon[3])
                    call DestroyEffect(.fxBoon[4])
                endif
            endif
            
            if .intCountDeadHero > 0 then
                set .rDurationDeadHero = .rDurationDeadHero - gR_DurationTimer
                if .rDurationDeadHero == 0 then
                    set .intCountDeadHero = 0
                endif
            endif
        else
            call .Destroy()
        endif

        call DestroyGroup(UG_Target)
        set U_Target = null
    endmethod
    
    private static method FindDataIndex takes unit caster returns integer
        local integer INT_CountData = 0
        
        loop
            set INT_CountData = INT_CountData + 1
            exitwhen gDATA[INT_CountData].uCaster == caster
        endloop
        
        return INT_CountData
    endmethod
    
    static method BoonOpen takes unit caster returns nothing
        local integer INT_DataIndex = HeavyweightData.FindDataIndex(caster)
        
        set gDATA[INT_DataIndex].intCountDeadHero = gDATA[INT_DataIndex].intCountDeadHero + 1
        set gDATA[INT_DataIndex].rDurationDeadHero = gR_DurationDeadHero
    endmethod

    static method Invalidate takes unit caster returns boolean
        local integer INT_DataIndex = HeavyweightData.FindDataIndex(caster)
        
        return gDATA[INT_DataIndex].intCountDeadHero == 0
    endmethod
    
    static method BoonUp takes unit caster returns nothing
        local integer INT_DataIndex = HeavyweightData.FindDataIndex(caster)
        local integer INT_LevelAbilityBoonNew = GetUnitAbilityLevel(caster, gINT_AbilityIdHeavyweightBoon) + 1

        if INT_LevelAbilityBoonNew <= gINT_MaxLevelAbilityBoon then
            call SetUnitAbilityLevel(caster, gINT_AbilityIdHeavyweightBoon, INT_LevelAbilityBoonNew)
            if INT_LevelAbilityBoonNew == 2 then
                set gDATA[INT_DataIndex].fxBoon[0] = AddSpecialEffectTarget(gSTR_ModelNameFX[0], caster, "head")
            elseif INT_LevelAbilityBoonNew == 3 then
                set gDATA[INT_DataIndex].fxBoon[1] = AddSpecialEffectTarget(gSTR_ModelNameFX[0], caster, "foot,left")
                set gDATA[INT_DataIndex].fxBoon[2] = AddSpecialEffectTarget(gSTR_ModelNameFX[0], caster, "foot,right")
            elseif INT_LevelAbilityBoonNew == 4 then
                set gDATA[INT_DataIndex].fxBoon[3] = AddSpecialEffectTarget(gSTR_ModelNameFX[0], caster, "hand,left")
                set gDATA[INT_DataIndex].fxBoon[4] = AddSpecialEffectTarget(gSTR_ModelNameFX[1], caster, "weapon")
            endif
            set gDATA[INT_DataIndex].intCountDeadHero = gDATA[INT_DataIndex].intCountDeadHero - 1
            set gDATA[INT_DataIndex].rDurationBoon = gR_DurationBoon
            set gDATA[INT_DataIndex].intLevelAbilityBoon = gDATA[INT_DataIndex].intLevelAbilityBoon + 1
        endif
    endmethod
endstruct

    private function gTRIG_Cast_Conditions takes nothing returns boolean
        return GetSpellAbilityId() == gINT_AbilityIdHeavyweight
    endfunction
    
    private function gTRIG_Cast_Actions takes nothing returns nothing
        local unit U_Caster = GetTriggerUnit()
        
        //Animation bit//
        call PauseUnit(U_Caster, TRUE)
        call SetUnitTimeScale(U_Caster, 0.50)
        call SetUnitAnimation(U_Caster, "death")
        call PolledWait(0.25)
        call SetUnitTimeScale(U_Caster, 0.00)
        call HeavyweightData.BoonUp(U_Caster)
        call PolledWait(1.00)
        call SetUnitTimeScale(U_Caster, 1.00)
        call SetUnitAnimation(U_Caster, "stand")
        
        set U_Caster = null
    endfunction
    
    private function gTRIG_Order_Conditions takes nothing returns boolean
        return OrderId2String(GetIssuedOrderId()) == gSTR_OrderHeavyweight
    endfunction
    
    private function gTRIG_Order_Actions takes nothing returns nothing
        local unit U_Caster = GetTriggerUnit()
        
        if HeavyweightData.Invalidate(U_Caster) then
            call BJDebugMsg("Unable to cast Heavyweight")
            call PauseUnit(U_Caster, TRUE)
            call IssueImmediateOrder(U_Caster, "stop")
            call PauseUnit(U_Caster, FALSE)
        endif
        
        set U_Caster = null
    endfunction
    
    private function gTRIG_Death_Conditions takes nothing returns boolean
        return IsUnitType(GetTriggerUnit(), UNIT_TYPE_HERO)
    endfunction
    
    private function BoolExpr2 takes nothing returns boolean
        return GetUnitAbilityLevel(GetFilterUnit(), gINT_AbilityIdHeavyweight) > 0 and IsUnitEnemy(GetDyingUnit(), GetOwningPlayer(GetFilterUnit())) and GetUnitState(GetFilterUnit(), UNIT_STATE_LIFE) > 0
    endfunction
    
    private function gTRIG_Death_Actions takes nothing returns nothing
        local unit U_Target = GetTriggerUnit()
        local unit U_Caster
        local group UG_Caster = CreateGroup()
        local integer INT_CountFX = 0
        local effect array FX_Attachment
        
        call BJDebugMsg("Now's your chance")
        call GroupEnumUnitsInRange(UG_Caster, GetUnitX(U_Target), GetUnitY(U_Target), gR_RangeAoE, Filter(function BoolExpr2))
        
        loop
            set U_Caster = FirstOfGroup(UG_Caster)
            exitwhen U_Caster == null
            call HeavyweightData.BoonOpen(U_Caster)
            set INT_CountFX = INT_CountFX + 1
            //play sound on unit (EffectSystem): "what an enemy is dead yay"//
            set FX_Attachment[INT_CountFX] = AddSpecialEffectTarget(gSTR_ModelNameFX[2], U_Caster, "overhead")
            call GroupRemoveUnit(UG_Caster, U_Caster)
        endloop
        call PolledWait(gR_DurationDeadHero)
        loop
            call DestroyEffect(FX_Attachment[INT_CountFX])
            set INT_CountFX = INT_CountFX - 1
            exitwhen INT_CountFX == 0
        endloop
        
        call DestroyGroup(UG_Caster)
        set U_Caster = null
        set U_Caster = null
    endfunction
    
    private function gTRIG_EnterMap_Actions takes nothing returns nothing
        call HeavyweightData.Create(GetTriggerUnit())
    endfunction
    
    private function BoolExpr1 takes nothing returns boolean
        return GetUnitAbilityLevel(GetFilterUnit(), gINT_AbilityIdHeavyweight) > 0
    endfunction

    public function Init takes nothing returns nothing
        local unit U_Caster
        local group UG_Caster = CreateGroup()
        
        set gSTR_ModelNameFX[0] = "Doodads\\Outland\\Props\\Skull\\Skull0.mdl" //Single skull//
        set gSTR_ModelNameFX[1] = "Doodads\\Outland\\Props\\Skull\\Skull1.mdl" //Skull pile (attached to club//
        set gSTR_ModelNameFX[2] = "Abilities\\Spells\\Other\\TalkToMe\\TalkToMe" //Exclamation mark//
        
        call GroupEnumUnitsInRect(UG_Caster, gRECT_Map, Filter(function BoolExpr1))
        loop
            set U_Caster = FirstOfGroup(UG_Caster)
            exitwhen U_Caster == null
            call HeavyweightData.Create(U_Caster)
            call GroupRemoveUnit(UG_Caster, U_Caster)
        endloop

        call TriggerRegisterEnterRegion(gTRIG_EnterMap, gREG_Map, Filter(function BoolExpr1))
        call TriggerAddAction(gTRIG_EnterMap, function gTRIG_EnterMap_Actions)
        
        call TriggerRegisterAnyUnitEventBJ(gTRIG_Death, EVENT_PLAYER_UNIT_DEATH)
        call TriggerAddCondition(gTRIG_Death, Condition(function gTRIG_Death_Conditions))
        call TriggerAddAction(gTRIG_Death, function gTRIG_Death_Actions)
        
        call TriggerRegisterAnyUnitEventBJ(gTRIG_Order, EVENT_PLAYER_UNIT_ISSUED_ORDER)
        call TriggerAddCondition(gTRIG_Order, Condition(function gTRIG_Order_Conditions))
        call TriggerAddAction(gTRIG_Order, function gTRIG_Order_Actions)
        
        call TriggerRegisterAnyUnitEventBJ(gTRIG_Cast, EVENT_PLAYER_UNIT_SPELL_EFFECT)
        call TriggerAddCondition(gTRIG_Cast, Condition(function gTRIG_Cast_Conditions))
        call TriggerAddAction(gTRIG_Cast, function gTRIG_Cast_Actions)

        call DestroyGroup(UG_Caster)
        set U_Caster = null
    endfunction
endscope
///////============Heavyweight End============///////
/////////////////////////////////////////////////////

    private function Init takes nothing returns nothing
        call Heavyweight_Init()
    endfunction

endlibrary
09-16-2008, 10:13 AM#2
Anitarf
Why oh why do you have to put all spells in a single scope?
09-16-2008, 10:19 AM#3
fX_
dunno

theyre in diff scopes but it one library
one library contains all a hero's spells coz most of the time they'll be interrelated (i can keep some stuff only for the hero private in the library). a library contains scopes of abilities (1 scope per ability)

all those triggers n stuff in scope heavyweight are for the heavyweight spell

my problem?