Naga'sShadow
Ultra Cool Member
- Reaction score
- 49
I've made a custom starfall spell. Damage area over time with some extra effects. I've got the spell working for the most part, except for one grantedly large issue. It targets friendlies. The way I've set the spell up I'm not sure how to filter out friendly units. Here's the code.
It filters out dead units and structures fine enough but obviously I can't use GetTriggerUnit() in the function BoolFilterMain like I want to. How would I go about referencing the struct in the filter function?
JASS:
scope RoC initializer init
globals
private constant integer SpellID = 039;A009039;
private constant integer Silence = 039;A00A039;
private constant integer Slow = 039;S000039;
private constant integer Curse = 039;Acrs039;
private constant integer Hex = 039;AChx039;
private constant integer Kill = 039;A00B039;
private constant real Damage = 15
private constant real Period = 1
private constant real Duration = 25
private constant string CasterSFX = "Abilities\\Spells\\Undead\\Unsummon\\UnsummonTarget.mdl"
private constant string TargetSFX = "Abilities\\Spells\\Items\\TomeOfRetraining\\TomeOfRetrainingCaster.mdl"
private constant string AttackSFX = "Abilities\\Spells\\Undead\\DeathandDecay\\DeathandDecayTarget.mdl"
endglobals
struct chaos
unit caster
group targets = CreateGroup()
effect Casterart
location casterpoint
real tick
static method create takes nothing returns chaos
local chaos r = chaos.allocate()
set r.caster = GetTriggerUnit()
set r.casterpoint = GetUnitLoc(r.caster)
set r.Casterart = AddSpecialEffectLoc(CasterSFX, r.casterpoint)
set r.tick = 0
return r
endmethod
method onDestory takes nothing returns nothing
call DestroyGroup(.targets)
call RemoveLocation(.casterpoint)
endmethod
endstruct
private function Conditions takes nothing returns boolean
return GetSpellAbilityId() == SpellID
endfunction
private function BoolfilterMain takes nothing returns boolean
if IsUnitEnemy(GetFilterUnit(), GetOwningPlayer(GetTriggerUnit())) == true and IsUnitType(GetFilterUnit(), UNIT_TYPE_STRUCTURE) != true and GetUnitState(GetFilterUnit(), UNIT_STATE_LIFE) >= .045 and IsUnitInvisible(GetFilterUnit(), GetOwningPlayer(GetTriggerUnit())) == false then
return true
else
return false
endif
endfunction
private function Effects takes nothing returns nothing
local integer Chance = GetRandomInt(1, 400)
local location tp = GetUnitLoc(GetEnumUnit())
local unit caster = GetTriggerUnit()
call DestroyEffect(AddSpecialEffectLoc(AttackSFX, tp))
if IsUnitType(GetEnumUnit(), UNIT_TYPE_HERO) == true then
if Chance >= 1 and Chance <= 27 then
call CasterCastAbility(GetOwningPlayer(caster), Silence, "soulburn", GetEnumUnit(), true)
elseif Chance >= 28 and Chance <= 54 then
call CasterCastAbility(GetOwningPlayer(caster), Slow, "cripple", GetEnumUnit(), false)
elseif Chance >= 55 and Chance <= 81 then
call CasterCastAbility(GetOwningPlayer(caster), Curse, "curse", GetEnumUnit(), false)
endif
elseif IsUnitType(GetEnumUnit(), UNIT_TYPE_MAGIC_IMMUNE) == true then
if Chance >= 90 and Chance <= 95 then
call SetUnitState(GetEnumUnit(), UNIT_STATE_LIFE, (GetUnitState(GetEnumUnit(), UNIT_STATE_LIFE) * .5))
call DestroyEffect(AddSpecialEffectLoc(TargetSFX, tp))
endif
else
if Chance >= 1 and Chance <= 27 then
call CasterCastAbility(GetOwningPlayer(caster), Silence, "soulburn", GetEnumUnit(), true)
elseif Chance >= 28 and Chance <= 54 then
call CasterCastAbility(GetOwningPlayer(caster), Slow, "cripple", GetEnumUnit(), false)
elseif Chance >= 55 and Chance <= 81 then
call CasterCastAbility(GetOwningPlayer(caster), Curse, "curse", GetEnumUnit(), false)
elseif Chance >= 82 and Chance <=89 then
call CasterCastAbility(GetOwningPlayer(caster), Hex, "hex", GetEnumUnit(), false)
elseif Chance >= 90 and Chance <= 95 then
call SetUnitState(GetEnumUnit(), UNIT_STATE_LIFE, (GetUnitState(GetEnumUnit(), UNIT_STATE_LIFE) * .5))
call DestroyEffect(AddSpecialEffectLoc(TargetSFX, tp))
elseif Chance >= 96 and Chance <= 100 then
call CasterCastAbility(GetOwningPlayer(caster), Kill, "frostnova", GetEnumUnit(), false)
endif
endif
call RemoveLocation(tp)
set caster = null
endfunction
private function TimerDamage takes nothing returns nothing
local timer time = GetExpiredTimer()
local chaos r = GetCSData(time)
local boolexpr TargetingInfo = Condition( function BoolfilterMain)
if GetUnitState(r.caster, UNIT_STATE_LIFE) <= 0 or GetUnitCurrentOrder(r.caster) != String2OrderIdBJ("starfall") or r.tick >= Duration then
call r.destroy()
call PauseTimer(time)
call DestroyTimer(time)
call DestroyEffect(r.Casterart)
set r.caster = null
endif
call GroupEnumUnitsInRangeOfLoc(r.targets, r.casterpoint, 900, TargetingInfo)
call GroupRemoveUnit(r.targets, r.caster)
call DamageUnitGroupEx(r.caster, Damage, r.targets, 0)
call ForGroup(r.targets, function Effects)
call GroupClear(r.targets)
call TriggerSleepAction(Period)
set r.tick = r.tick + Period
endfunction
private function Actions takes nothing returns nothing
local timer time = CreateTimer()
local chaos r = chaos.create()
call SetCSData(time, r)
call TimerStart(time, Period, true, function TimerDamage)
set time = null
endfunction
//===========================================================================
private function init takes nothing returns nothing
local trigger t = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition(t, Condition( function Conditions))
call TriggerAddAction( t, function Actions )
set t = null
endfunction
endscope