HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Spell 3 (JASS) - Corpse Explosion not working?

09-28-2006, 10:04 PM#1
Fulla
Area corpse explosion, cast based of Silence

Collapse JASS:
function Trig_corpseexplosion_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'A07I'
endfunction

function corpseexplosion_Conditions_dead takes nothing returns boolean
    return (GetWidgetLife(GetFilterUnit()) <= 0.405)
endfunction

function corpseexplosion_Conditions_alive takes nothing returns boolean
    return (GetWidgetLife(GetFilterUnit()) > 0.405) and IsUnitEnemy(GetFilterUnit(), udg_tempplayer)
endfunction

function Trig_corpseexplosion_Actions takes nothing returns nothing
    local unit caster = GetTriggerUnit()
    local unit dummy
    local unit target
    local group dead = CreateGroup()
    local group alive = CreateGroup()
    local real newx = GetOrderPointX()
    local real newy = GetOrderPointY()
    local real damage
    local real total
    local real temp
    local real health
    local integer level = GetUnitAbilityLevel(caster, 'A07I')
    set damage = (10 * (I2R(level)))
    set udg_tempplayer = GetOwningPlayer(caster)
    call GroupEnumUnitsInRange(dead, newx, newy, 500, Condition(function corpseexplosion_Conditions_dead))
    call GroupEnumUnitsInRange(alive, newx, newy, 500, Condition(function corpseexplosion_Conditions_alive))
        loop
        set dummy = FirstOfGroup(dead)
        exitwhen dummy == null
        set health = GetUnitState(dummy, UNIT_STATE_MAX_LIFE)
        set temp = (health / damage)
        set total = (total + temp)
        call ExplodeUnitBJ(dummy)
        call GroupRemoveUnit(dead,dummy)
        endloop
            loop
            set dummy = FirstOfGroup(alive)
            exitwhen dummy == null
            call UnitDamageTargetBJ(caster, dummy, total, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL)
            call GroupRemoveUnit(alive,dummy)
            endloop
endfunction

//===========================================================================
function InitTrig_corpseexplosion takes nothing returns nothing
    set gg_trg_Lightning_Blast = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_corpseexplosion, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddAction( gg_trg_corpseexplosion, function Trig_corpseexplosion_Actions )
    call TriggerAddCondition( gg_trg_corpseexplosion, Condition( function Trig_corpseexplosion_Conditions ) )
endfunction

Nothing happens? :(
09-28-2006, 10:23 PM#2
Vexorian
initialize total as 0.

You are also leaking 2 boolexprs (conditions)
09-28-2006, 11:24 PM#3
Fulla
ok I think ive removed all the leaks now

Collapse JASS:
function Trig_corpseexplosion_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'A07I'
endfunction

function corpseexplosion_Conditions_dead takes nothing returns boolean
    return (GetWidgetLife(GetFilterUnit()) <= 0.405)
endfunction

function corpseexplosion_Conditions_alive takes nothing returns boolean
    return (GetWidgetLife(GetFilterUnit()) > 0.405) and IsUnitEnemy(GetFilterUnit(), udg_tempplayer)
endfunction

function Trig_corpseexplosion_Actions takes nothing returns nothing
    local unit caster = GetTriggerUnit()
    local unit dummy
    local unit target
    local group dead = CreateGroup()
    local group alive = CreateGroup()
    local real newx = GetOrderPointX()
    local real newy = GetOrderPointY()
    local real damage
    local real total = 0
    local real temp
    local real health
    local integer level = GetUnitAbilityLevel(caster, 'A07I')
    local boolexpr b  = Condition(function corpseexplosion_Conditions_dead)
    local boolexpr c  = Condition(function corpseexplosion_Conditions_alive)
    set damage = (10 * (I2R(level)))
    set udg_tempplayer = GetOwningPlayer(caster)
    call GroupEnumUnitsInRange(dead, newx, newy, 500, b)
    call GroupEnumUnitsInRange(alive, newx, newy, 500, c)
        loop
        set dummy = FirstOfGroup(dead)
        exitwhen dummy == null
        set health = GetUnitState(dummy, UNIT_STATE_MAX_LIFE)
        set temp = (health / damage)
        set total = (total + temp)
        call ExplodeUnitBJ(dummy)
        call GroupRemoveUnit(dead,dummy)
        endloop
            loop
            set dummy = FirstOfGroup(alive)
            exitwhen dummy == null
            call UnitDamageTargetBJ(caster, dummy, total, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL)
            call GroupRemoveUnit(alive,dummy)
            endloop
    call DestroyGroup(dead)
    call DestroyGroup(alive)
    set caster = null
    set dummy = null
    set target = null
    set b = null
    set c = null
endfunction

//===========================================================================
function InitTrig_corpseexplosion takes nothing returns nothing
    set gg_trg_Lightning_Blast = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_corpseexplosion, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddAction( gg_trg_corpseexplosion, function Trig_corpseexplosion_Actions )
    call TriggerAddCondition( gg_trg_corpseexplosion, Condition( function Trig_corpseexplosion_Conditions ) )
endfunction

It still doesnt work?
i.e. dead bodies dont explode and no dmg is dealt to surrounding units.

Collapse JASS:
local real newx = GetOrderPointX()

Is that correct? I think this is the problem?
09-28-2006, 11:39 PM#4
Vexorian
the total one was a problem, but that is a problem as well, you have to use GetSpellTargetLoc() for that event, it is a pity blizzard didn't add X/Y versions of it
09-29-2006, 12:20 AM#5
PipeDream
the cost of having a wrapper that gets x / y and is completely lazy and gets the location twice isn't that big anyway. it's not like you will ever call for an order point intensively. you write it once, it's a little bit slower, but it saves you 10s of typing the next 100 times you use it.
09-29-2006, 12:29 AM#6
Fulla
Collapse JASS:
function Trig_corpseexplosion_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'A07I'
endfunction

function corpseexplosion_Conditions_dead takes nothing returns boolean
    return (GetUnitState(GetFilterUnit(), UNIT_STATE_LIFE) <= 0.)
endfunction

function corpseexplosion_Conditions_alive takes nothing returns boolean
    return (GetUnitState(GetFilterUnit(), UNIT_STATE_LIFE) > 0.) and IsUnitEnemy(GetFilterUnit(), udg_tempplayer)
endfunction

function Trig_corpseexplosion_Actions takes nothing returns nothing
    local unit caster = GetTriggerUnit()
    local unit dummy
    local unit target
    local group dead = CreateGroup()
    local group alive = CreateGroup()
    local location newx = GetSpellTargetLoc()
    local real damage
    local real total = 0
    local real temp
    local real health
    local integer level = GetUnitAbilityLevel(caster, 'A07I')
    local boolexpr b  = Condition(function corpseexplosion_Conditions_dead)
    local boolexpr c  = Condition(function corpseexplosion_Conditions_alive)
    set damage = (10 * (I2R(level)))
    set udg_tempplayer = GetOwningPlayer(caster)
    call GroupEnumUnitsInRangeOfLoc(dead, newx, 500, b)
    call GroupEnumUnitsInRangeOfLoc(alive, newx, 500, c)
    call BJDebugMsg(GetObjectName(GetUnitTypeId( caster )))
        loop
        set dummy = FirstOfGroup(dead)
        exitwhen dummy == null
        call BJDebugMsg(GetObjectName(GetUnitTypeId( dummy )))
        set health = GetUnitState(dummy, UNIT_STATE_MAX_LIFE)
        set temp = (health * damage * 0.1)
        set total = (total + temp)
        call ExplodeUnitBJ(dummy)
        call GroupRemoveUnit(dead,dummy)
        endloop
            loop
            set dummy = FirstOfGroup(alive)
            exitwhen dummy == null
            call BJDebugMsg(GetObjectName(GetUnitTypeId( dummy )))
            call UnitDamageTargetBJ(caster, dummy, total, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL)
            call GroupRemoveUnit(alive,dummy)
            endloop
    call DestroyGroup(dead)
    call DestroyGroup(alive)
    set caster = null
    set dummy = null
    set target = null
    set b = null
    set c = null
endfunction

//===========================================================================
function InitTrig_corpseexplosion takes nothing returns nothing
    set gg_trg_Lightning_Blast = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_corpseexplosion, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddAction( gg_trg_corpseexplosion, function Trig_corpseexplosion_Actions )
    call TriggerAddCondition( gg_trg_corpseexplosion, Condition( function Trig_corpseexplosion_Conditions ) )
endfunction

Gah the rawcode is definetly right :-(

Debug msg displayed nothing each time
09-29-2006, 12:33 AM#7
Chuckle_Brother
Oh man, the issue is so simple I totally missed it

set gg_trg_Lightning_Blast = CreateTrigger( )
09-29-2006, 12:35 AM#8
Fulla
lol, my terrible bad.

I always assumed that the map wouldnt compile with something like that.
09-29-2006, 12:43 AM#9
Chuckle_Brother
Didn't think it would, but hey, its the WE right?
09-29-2006, 02:22 AM#10
Vexorian
Quote:
Originally Posted by PipeDream
the cost of having a wrapper that gets x / y and is completely lazy and gets the location twice isn't that big anyway. it's not like you will ever call for an order point intensively. you write it once, it's a little bit slower, but it saves you 10s of typing the next 100 times you use it.
A wrapper sounds way too trivial
---

There is no syntax error there, World Editor barely expects you to have an init trig function and you can do whatever you want there, I actually think it is a good thing.
09-29-2006, 03:05 AM#11
DotA_DR
Quote:
Originally Posted by Vexorian
You are also leaking 2 boolexprs (conditions)

It is possible to not do it
Allocated handle reused for same function.

Collapse JASS:
  set filter1 = Filter(function AFilter)
  set filter2 = Filter(function AFilter)

filter1 and filter2 would have same handle.
09-29-2006, 03:11 AM#12
Vexorian
he could just save them in locals and destroy them
09-29-2006, 03:41 AM#13
DotA_DR
To Fulla
1. see declaration of ExplodeUnitBJ

Collapse JASS:
function ExplodeUnitBJ takes unit whichUnit returns nothing
    call SetUnitExploded(whichUnit, true)
    call KillUnit(whichUnit)
endfunction

i think, dead unit can't die again

2. I think, it's better to delete unit from group after condition, simply what to not forget it
Collapse JASS:
   set dummy = FirstOfGroup(g)
   exitwhen dummy == null
   call GroupRemove(g, dummy)
just advice

3. Add debug message for health, damage variable to looking for a bug

To Vexorian
He could, but what for? Unnecessary efforts
09-29-2006, 03:52 AM#14
Vexorian
saving them in globals seems to be more of an effort, specially since it is so hard to declare a boolexpr variable in WE, if you have a way to easily create them then they are probably just the same thing, same effort and same speed, maybe creating destroying boolexpr would increase the exec time but keeping them in variables also increases memory, but the time increase or the memory are really slow.
09-29-2006, 04:38 AM#15
DotA_DR
Quote:
Originally Posted by Vexorian
saving them in globals seems to be more of an effort, specially since it is so hard to declare a boolexpr variable in WE, if you have a way to easily create them then they are probably just the same thing, same effort and same speed, maybe creating destroying boolexpr would increase the exec time but keeping them in variables also increases memory, but the time increase or the memory are really slow.
Sorry for bad explanation
I mean that there is no necessity to save and delete them in general. Because by a repeated call Filter/Condition for same function new handle is not allocated (fact) so memory is not increased (I think)