HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Simple Starfall Spell - Bugging/Not Working

04-16-2008, 08:48 AM#1
Fulla
I made a very basic/simple starfall type spell, but it doesnt work properly.

Does TriggerSleepAction not work when using ForGroup?
I wanted to avoid using timers for each unit, as I was simply going to add a Wait Random(0,1) before the initial starfall to make it all come down randomly similiar to the original Starfall spell.
Collapse JASS:
function Starfury_Group takes nothing returns nothing
    local unit u=HERO_Mystic
    local unit e=GetEnumUnit()
    local integer lvl=GetUnitAbilityLevel(u,'A009')
    local real dmg=(lvl*30)+20
    call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\NightElf\\Starfall\\StarfallTarget.mdl",e,"origin"))
    call UnitDamageSpell(u,e,dmg)
    call TriggerSleepAction(1)
    call BJDebugMsg("Test")
    call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\NightElf\\Starfall\\StarfallTarget.mdl",e,"origin"))
    call UnitDamageSpell(u,e,dmg)
    call TriggerSleepAction(1)
    call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\NightElf\\Starfall\\StarfallTarget.mdl",e,"origin"))
    call UnitDamageSpell(u,e,dmg)
    set u=null
    set e=null
endfunction

Basically starfall only comes down once + Debugmsg doesnt work?
Damnit.

Whole Code:
Collapse JASS:
function Starfury_Cons takes nothing returns boolean
    return GetSpellAbilityId()=='A009'
endfunction

function Starfury_Check takes nothing returns boolean
    return GetWidgetLife(GetFilterUnit())>.405 and IsUnitEnemy(GetFilterUnit(),GetOwningPlayer(HERO_Mystic))
endfunction

function Starfury_Group takes nothing returns nothing
    local unit u=HERO_Mystic
    local unit e=GetEnumUnit()
    local integer lvl=GetUnitAbilityLevel(u,'A009')
    local real dmg=(lvl*30)+20
    call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\NightElf\\Starfall\\StarfallTarget.mdl",e,"origin"))
    call UnitDamageSpell(u,e,dmg)
    call TriggerSleepAction(1)
    call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\NightElf\\Starfall\\StarfallTarget.mdl",e,"origin"))
    call UnitDamageSpell(u,e,dmg)
    call TriggerSleepAction(1)
    call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\NightElf\\Starfall\\StarfallTarget.mdl",e,"origin"))
    call UnitDamageSpell(u,e,dmg)
    set u=null
    set e=null
endfunction

function Starfury_Acts takes nothing returns nothing
    local unit u=HERO_Mystic
    local group g=CreateGroup()
    local boolexpr b=Filter(function Starfury_Check)
    call GroupEnumUnitsInRange(g,GetUnitX(u),GetUnitY(u),1000,b)
    call ForGroup(g,function Starfury_Group)
    call DestroyGroup(g)
    call DestroyBoolExpr(b)
    set u=null
endfunction

//===========================================================================
function InitTrig_Star_Fury takes nothing returns nothing
    set gg_trg_Star_Fury=CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ(gg_trg_Star_Fury,EVENT_PLAYER_UNIT_SPELL_EFFECT)
    call TriggerAddCondition(gg_trg_Star_Fury,Condition(function Starfury_Cons))
    call TriggerAddAction(gg_trg_Star_Fury,function Starfury_Acts)
endfunction
04-16-2008, 09:03 AM#2
Malf
I don't think waits are allowed. Although if you really don't want to use timers you could always do what I do.. Sometimes.

Collapse JASS:
function DoActions takes unit u, unit e, real dmg returns nothing
local integer i= 0
    loop
        set i = i+1
        exitwhen i > 3 //You do it three times, judging from what you posted
        call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\NightElf\\Starfall\\StarfallTarget.mdl",e,"origin"))
        call UnitDamageSpell(u,e,dmg)
        call TriggerSleepAction(GetRandomReal(1,whatever))
    endloop
endfunction

function Actions takes nothing returns nothing
local unit u=HERO_Mystic
local unit e=GetEnumUnit()
local integer lvl=GetUnitAbilityLevel(u,'A009')
local real dmg=(lvl*30)+20
local integer i = 0
local group g = YourGroup
    call GroupEnumUnitsBlahblah()
    loop
        set e = FirstOfGroup(g)
        exitwhen e == null
        call DoActions.execute(u,e,dmg)
        call GroupRemoveUnit(g,e)
    endloop
    Do some cleanups etc,.
endfunction
04-16-2008, 09:27 AM#3
Fulla
Yea I may do that, but if theres to many nearby units the waits will start to add up, becoming a problem.

I quickly remade it, starfall's each unit, then a 1/3 chance to repeat, then one more 1/3 chance to repeat.
Only bad thing is all starfalls occur at the exact same time. A little randomness like the standard Starfall would look better.

Collapse JASS:
globals
    group SF_Group=null
endglobals

function Starfury_Cons takes nothing returns boolean
    return GetSpellAbilityId()=='A009'
endfunction

function Starfury_Check takes nothing returns boolean
    return GetWidgetLife(GetFilterUnit())>.405 and IsUnitEnemy(GetFilterUnit(),GetOwningPlayer(HERO_Mystic))
endfunction

function Starfury_Effect takes nothing returns nothing
    local unit e=GetEnumUnit()
    call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\NightElf\\Starfall\\StarfallTarget.mdl",e,"origin"))
    set e=null
endfunction

function Starfury_Damage takes nothing returns nothing
    local unit u=HERO_Mystic
    local unit e=GetEnumUnit()
    local integer lvl=GetUnitAbilityLevel(u,'A009')
    local real dmg=(lvl*30)+20
    call UnitDamageSpell(u,e,dmg)
    set u=null
    set e=null
endfunction

function Starfury_Remove takes nothing returns nothing
    local unit e=GetEnumUnit()
    if GetRandomInt(0,2)==0 then
        call GroupRemoveUnit(SF_Group,e)
    endif
    set e=null
endfunction

function Starfury_Acts takes nothing returns nothing
    local unit u=HERO_Mystic
    local boolexpr b=Filter(function Starfury_Check)
    set SF_Group=CreateGroup()
    call GroupEnumUnitsInRange(SF_Group,GetUnitX(u),GetUnitY(u),1000,b)
    call ForGroup(SF_Group,function Starfury_Effect)
    call TriggerSleepAction(.3)
    call ForGroup(SF_Group,function Starfury_Damage)
    call ForGroup(SF_Group,function Starfury_Remove)
    if CountUnitsInGroup(SF_Group)>0 then
        call ForGroup(SF_Group,function Starfury_Effect)
        call TriggerSleepAction(.3)
        call ForGroup(SF_Group,function Starfury_Damage)
        call ForGroup(SF_Group,function Starfury_Remove)
    endif
    if CountUnitsInGroup(SF_Group)>0 then
        call ForGroup(SF_Group,function Starfury_Effect)
        call TriggerSleepAction(.3)
        call ForGroup(SF_Group,function Starfury_Damage)
        call ForGroup(SF_Group,function Starfury_Remove)
    endif
    call DestroyGroup(SF_Group)
    call DestroyBoolExpr(b)
    set u=null
endfunction

//===========================================================================
function InitTrig_Star_Fury takes nothing returns nothing
    set gg_trg_Star_Fury=CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ(gg_trg_Star_Fury,EVENT_PLAYER_UNIT_SPELL_EFFECT)
    call TriggerAddCondition(gg_trg_Star_Fury,Condition(function Starfury_Cons))
    call TriggerAddAction(gg_trg_Star_Fury,function Starfury_Acts)
endfunction
04-16-2008, 09:37 AM#4
Malf
If you want randomness without using timers, you're going to have to use .execute() like in my example.

10 - 15 waits at a time aren't that bad. But then again, waits are bad.
04-16-2008, 09:39 AM#5
Fulla
Aha, I missed that part.
I thought you was just calling the function normally, my bad.

I'll have a fiddle with it, thx
04-16-2008, 10:18 AM#6
DioD
Next time read tips on gui triggers...


w8 not allowed with any kind of enumerators (force,group,destructables,doodads,items and may be other)
04-16-2008, 12:43 PM#7
Fulla
Ok, I re-coded alot of it but now still getting the same problem. It only ever fires off once.

Starfalls should occur multiple times on some units, but they simply dont.
I've used Debug Msges, it simply confused me further.

First of the code:
Collapse JASS:
function StarFury_Damage takes unit u,unit e,real dmg returns nothing
    call TriggerSleepAction(GetRandomReal(0,.4))
    call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\NightElf\\Starfall\\StarfallTarget.mdl",e,"origin"))
    call TriggerSleepAction(.3)
    call UnitDamageSpell(u,e,dmg)
endfunction

function Starfury_Acts takes nothing returns nothing
    local unit u=HERO_Mystic
    local unit d=null
    local integer lvl=GetUnitAbilityLevel(u,'A009')
    local integer cap=(lvl*1)+1
    local real dmg=(lvl*10)+40
    local boolexpr b=Filter(function Starfury_Check)
    local group f=CreateGroup()
    local group g=CreateGroup()
    call GroupEnumUnitsInRange(f,GetUnitX(u),GetUnitY(u),1000,b)
    loop
        call BJDebugMsg("Cap "+I2S(cap))
        call BJDebugMsg("Count "+I2S(CountUnitsInGroup(f)))
        exitwhen cap==0
        exitwhen CountUnitsInGroup(f)==0
        call GroupAddGroup(f,g)
        loop
            set d=FirstOfGroup(g)
            exitwhen d==null
            call StarFury_Damage.execute(u,d,dmg)
            call GroupRemoveUnit(g,d)
            if GetRandomInt(0,2)==0 then
                call GroupRemoveUnit(f,d)
            endif
        endloop
        set cap=cap-1
        call TriggerSleepAction(.1)
    endloop
    call DestroyGroup(f)
    call DestroyGroup(g)
    call DestroyBoolExpr(b)
    set u=null
endfunction

Debug Mesges I get:


This means it should be running, the StarFury_Damage function again & again, but I only ever get ONE Starfall per unit.

RAWR??
04-16-2008, 12:57 PM#8
emjlr3
what does the .execute do?

btw im not sure y your spell doesnt work there, but then again i dont know what .execute does
04-16-2008, 01:27 PM#9
Fulla
Im not actually sure, Malf suggested it & it seemed to work to an extent.

As im not exactly a master in scripting languages I find it difficult to describe with correct terminology:

I assume it allows you to to call a function, separating it out/making it independent similar to running a timer with 0 duration, except you can transfer things, rather than having to attach them.

If I just did call Function() normally, if I have waits in that function, I'll have to keep waiting for it to finish each time, whilst this way I don't.
04-16-2008, 01:29 PM#10
Malf
.execute() is basically ExecuteFunc() with the ability to pass arguments and is faster than ExecuteFunc()

--

You only have two debug messages, doesn't help too much. When I'm debugging I usually have around 5 or more or them. Don't just use BJDebugMsg for cap and count. Try to put a debug message in Starfury_Damage.

If you have AIM just send me a message and we can discuss this faster. My screenname is Malphwnage.
04-16-2008, 01:41 PM#11
Fulla
EDIT:

Ok, got it working now, thx for help Malf + Others
04-17-2008, 04:24 AM#12
Valdez
Just a thought..if its just a simple starfall spell with only 1 wave.. couldn't you just give it a very small interval time like .05 and a duration of .06 and essentially the same effect without the triggered ability?