[JASS] Help with an ability

Level 20
Jul 14, 2011

I'm helping someone with an ability that makes some spirits cicle around a unit (already achieved); each spirit regens the unit depending on the level of the ability being cast (already achieved) BUT they block incoming damage, and every (30 + (level of ability x 15)) one of them flies away towards the damage dealer (the one that reached the damage gap) and explode on it's position dealing the same amount of blocked damage (30+lvl*15).

I don't know how to access the spirits that are spinning around the unit to send them to the damage dealer
I don't know how to block/null damage either.

Here's what I have

    integer Spart_SpiritCount = 5 // Number of Spirits to create
    group Spart_SpiritProtectGroup = CreateGroup() // Unit Group
    group Spart_SpiritAttackGroup = CreateGroup() // Unit Group
    group Spart_ProtectedGroup = CreateGroup() // Unit Group
    integer Spart_SpiritId = 'xxxx' // Id of your dummy
    real Spart_SpiritOffset = 15*Spart_SpiritCount // Distance between spirits and target
    real Spart_SpiritSpeed = 0.09 // Higher number means faster movement
    real Spart_SpiritDuration = 15 // Duration of the Spirits if target doesn't take any damage
    unit array Spart_SpiritTarget // Target of each spirit
    real array Spart_SpiritAngle // Angle of each spirit in relation to its target
    real array Spart_SpiritTimer // Expiration timer of each spirit
    real Spart_DBS = 360 / Spart_SpiritCount // Distance between spirits
    real array Spart_DmgAcum // Accumulated Damage
    integer Spart_HealId = 'A000' // Id of Regen ability
    integer Spart_SpiritAbilId = 'AHhb' // Id of the Ability to summon the spirits
    unit array Spart_Spirits

function SpartSpiritSetActions takes nothing returns nothing
    local unit Target = GetSpellTargetUnit()
    local integer looper = 0
    local unit dummy
    local real angle
    local real x
    local real y
    local integer cv
        exitwhen looper == Spart_SpiritCount
        set angle = (R2I(looper) * Spart_DBS) * bj_DEGTORAD
        set x = GetUnitX(Target) + Spart_SpiritOffset * Cos(angle)
        set y = GetUnitY(Target) + Spart_SpiritOffset * Sin(angle)
        set dummy = CreateUnit(GetOwningPlayer(Target), Spart_SpiritId, x, y, 0)
        set cv = GetUnitUserData(dummy)
        set Spart_SpiritAngle[cv] = angle
        set Spart_SpiritTarget[cv] = Target
        set Spart_SpiritTimer[cv] = Spart_SpiritDuration
        call GroupAddUnit(Spart_SpiritProtectGroup, dummy)
        call SetUnitAbilityLevel(dummy, Spart_HealId, GetUnitAbilityLevel(GetTriggerUnit(), Spart_SpiritAbilId))
        set looper = looper+1
    set Spart_SpiritAmount[GetUnitUserData(Target)] = Spart_SpiritAmount[GetUnitUserData(Target)] + 5
    call GroupAddUnit(Spart_ProtectedGroup, Target)
    call EnableTrigger(gg_trg_SpartSpirit_Protect_Loop)
    set Target = null
    set dummy = null


function InitTrig_SpartSpirit_Set takes nothing returns nothing
    set gg_trg_SpartSpirit_Set = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_SpartSpirit_Set, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddAction( gg_trg_SpartSpirit_Set, function SpartSpiritSetActions )

function SpartSpirit_Protect_Loop_GroupActions takes nothing returns nothing
    local unit dummy = GetEnumUnit()
    local integer cv = GetUnitUserData(dummy)
    local unit target = Spart_SpiritTarget[cv]
    local real x
    local real y
    local real angle = Spart_SpiritAngle[cv] + Spart_SpiritSpeed
    set Spart_SpiritAngle[cv] = angle
    set x = GetUnitX(target) + Spart_SpiritOffset * Cos(angle)
    set y = GetUnitY(target) + Spart_SpiritOffset * Sin(angle)
    call SetUnitX(dummy, x)
    call SetUnitY(dummy, y)
    set Spart_SpiritTimer[cv] = Spart_SpiritTimer[cv]-0.03
    if Spart_SpiritTimer[cv] <= 0 then
        call GroupRemoveUnit(Spart_SpiritProtectGroup, dummy)
        call KillUnit(dummy)
        set Spart_SpiritTarget[cv] = null
    set dummy = null
    set target = null

function Trig_SpartSpirit_Protect_Loop_Actions takes nothing returns nothing
    set bj_groupCountUnits = 0
    call ForGroup(Spart_SpiritProtectGroup, function CountUnitsInGroupEnum)
    if bj_groupCountUnits > 0 then
        call ForGroup(Spart_SpiritProtectGroup, function SpartSpirit_Protect_Loop_GroupActions)
        call DisableTrigger( GetTriggeringTrigger() )

function InitTrig_SpartSpirit_Protect_Loop takes nothing returns nothing
    set gg_trg_SpartSpirit_Protect_Loop = CreateTrigger(  )
    call TriggerRegisterTimerEventPeriodic( gg_trg_SpartSpirit_Protect_Loop, 0.03 )
    call TriggerAddAction( gg_trg_SpartSpirit_Protect_Loop, function Trig_SpartSpirit_Protect_Loop_Actions )

function Trig_Untitled_Trigger_001_Conditions takes nothing returns boolean
    return IsUnitInGroup(udg_GDD_DamagedUnit, Spart_ProtectedGroup) == true

function Trig_Untitled_Trigger_001_Actions takes nothing returns nothing
    local integer cv = GetUnitUserData(udg_GDD_DamagedUnit)
    set Spart_DmgAcum[cv] = Spart_DmgAcum[cv] + udg_GDD_Damage
    call BJDebugMsg(R2S(Spart_DmgAcum[cv]))
    if Spart_DmgAcum[cv] >= 300
        set Spart_DmgAcum[cv] = 0

function InitTrig_SpartSpirit_Damage_Block takes nothing returns nothing
    set gg_trg_SpartSpirit_Damage_Block = CreateTrigger(  )
    call TriggerRegisterVariableEvent( gg_trg_SpartSpirit_Damage_Block, "udg_GDD_Event", NOT_EQUAL, 0 )
    //call TriggerAddCondition( gg_trg_SpartSpirit_Damage_Block, Condition( function Trig_Untitled_Trigger_001_Conditions ) )
    call TriggerAddAction( gg_trg_SpartSpirit_Damage_Block, function Trig_Untitled_Trigger_001_Actions )

Some values are messed up because I'm just testing, but I just got tired :p


  • SpartSpirits.w3x
    25.7 KB · Views: 63
Last edited:
Level 7
Jan 28, 2012
to block the damage you would adjust the health of the unit, the only problem is that the units health will be amount of damage under max HP Bribes Engine has an Example on how to Block Damage(without this problem)but what it boils down to is when the unit is Damaged, increasing its Health by the amount of Damage Inflicted on it, and adding, then removing an ability that gives the unit a massive amount of health.

The Best way(with the way you are doing things now) to get the Spirit to fly after the unit would be to create a Unit Group for the Unit that is being Guarded, and add the Spirit to it and then just use FirstOfGroup() to get the Spirit you want to use.
Level 5
Aug 27, 2010
maintain a hashtable (preferably Table),
save the spirits with parent key as the unit around which the spirits revolve,
child key as the angle at which the spirit is created.

also maintain a variable that has (total angular displacement)%360 for every instance of spell

in your damage trigger,
angle = (anglebetween(damaging unit,damaged unit) + total angular displacement) % 360

using this "angle" u can access the spirits in the direction of damaging unit...

Edit: it does become easy if u use vJass :)