Hi, I'm new to these forums... I'm not one to just post on a forum without trying to find out an answer on my own first, but i've been trying to create this custom spell for a few days and I just can't figure it out.
I'm trying to create a spell that would be similiar to starfall except instead of raining stars it would randomly cast nova on a unit in a radius of a hero.
I've tried basing it off roar so that when a hero has the "snowfall" buff a trigger gets set off, but then the hero can walk around while it's going off. I tried baseing it off starfall, but i can't seem to make it work right.
Can anyone point me in the right direction? Thanks.
BlueScreenODHi, I'm new to these forums... I'm not one to just post on a forum without trying to find out an answer on my own first, but i've been trying to create this custom spell for a few days and I just can't figure it out.
I'm trying to create a spell that would be similiar to starfall except instead of raining stars it would randomly cast nova on a unit in a radius of a hero.
I've tried basing it off roar so that when a hero has the "snowfall" buff a trigger gets set off, but then the hero can walk around while it's going off. I tried baseing it off starfall, but i can't seem to make it work right.
Can anyone point me in the right direction? Thanks.
okay first make it starfall but as a dummy spell (everything in data set to 0), you may want to remove/replace the effects generated by starfall. Next make a dummy unit (see Daelins tutorial), and make a frost nova spell that is to be used. Then make a trigger That randomly chooses a unit within x range and makes a dummy unit with a 1.5 sec generic expiration timer, and casts frost nova on them.
there's way to do this to work properly and nice, but if you're new to triggering, i won't tell u... cause it needs 2-3 triggers. but the best would be to do this in JASS...
edit: ok i've changed my mind...
trigger #1: ev.: unit casts a spell cond.: ability == snowfall action: turn on trigger #2 set Caster = triggering unit wait "duration" seconds turn off trigger #2
trigger #2 event: every 1 seconds action: pick a random unit in 400 range of position of Caster (check if it's an enemy and not magic immune or building) set Target = picked unit -> create a dummy with a good snowflake-like model at picked unit's position -> set Snowflake = lastcreatedunit -> add Frost Nove to Snowflake -> set Snowflake's fly height to 900 -> turn on Trigger #3
trigger #3 event: every 0.02 seconds condition: Target not equal to No unit action: set Snowflakes fly height to (fly height of Snowflake - 1 if fly height of Snowflake < 50 order Snowflake to "frostnova" Target kill/remove Frostnova Target = No unit
paskovich's idea seems kinda complicated and doesn't look to be multi-instanceable. You could try it my way, but if you don't know JASS, it will be hard to understand.
Firstly, you need to make a dummy spell, base it off of starfall. Set duration to 0.01, turn off all special effects art, set damage dealt to 0, and area of effect to 0. Make the tooltips, cooldown, and mana cost into whatever things you wanted for your snowfall spell because this will be the spell that the unit actually casts in-game. That being said, give this dummy spell to the unit you want to be able to cast snowfall.
Second, create a spell based off of frost nova. Set everything to whatever you want for the random frost nova effects that snowfall creates, but make sure mana cost is 0.
Third, create a dummy unit. Base it off of a footman, set its collision to 0, give it the Locust unit ability (so it can't be selected or attacked), set unit move type to flying, and set flying height to 900. Like paskovich said, give the unit a good snowflake or ice model (the Frost Bolt missile looks pretty good).
For the following trigger, I will assume that the dummy snowfall ability has a raw code of A000 and that the dummy unit has a raw code of h000. To make this trigger work in your map, change all references to those raw codes to the actual raw codes of the ability/unit in your map.
function Trig_Snowfall_Conditions takes nothing returns boolean
if ( GetSpellAbilityId() == 'A000' ) then
return true
endif
return false
endfunction
function Trig_Snowfall_Target_Conditions takes nothing returns boolean
local timer t = GetExpiredTimer()
local unit caster = GetHandleUnit(t, "caster")
return ( IsUnitEnemy(GetFilterUnit(), GetOwningPlayer(caster)) and IsUnitType(GetFilterUnit(), UNIT_TYPE_MAGIC_IMMUNE) == false )
endfunction
function Trig_Snowfall_Fall takes nothing returns nothing
local timer tt = GetExpiredTimer()
local unit target = GetHandleUnit(tt, "target")
local unit dummy = GetHandleUnit(tt, "dummy")
local real x = GetUnitX(dummy)
local real y = GetUnitY(dummy)
call SetUnitPosition(dummy, x, y)
call SetUnitFlyHeight(dummy, (GetUnitFlyHeight(dummy) - 5), 1500)
set tt = null
set target = null
set dummy = null
endfunction
function Trig_Snowfall_Target takes nothing returns nothing
local timer t = GetExpiredTimer()
local timer tt = CreateTimer()
local unit caster = GetHandleUnit(t, "caster")
local unit target = FirstOfGroup(GetRandomSubGroup(1, GetUnitsInRangeOfLocMatching(900, GetUnitLoc(caster), Condition(function Trig_Snowfall_Target_Conditions))))
local unit dummy = CreateUnitAtLoc(GetOwningPlayer(caster), 'h000', GetUnitLoc(target), 270)
call SetHandleHandle(tt, "target", target)
call SetHandleHandle(tt, "dummy", dummy)
call TimerStart(tt, 0.03, true, function Trig_Snowfall_Fall)
loop
exitwhen ( GetUnitFlyHeight(dummy) <= 60)
call TriggerSleepAction(0.28)
endloop
call DestroyTimer(tt)
call IssueTargetOrder( dummy, "frostnova", target )
call TriggerSleepAction(1)
call RemoveUnit(dummy)
set t = null
set tt = null
set caster = null
set target = null
set dummy = null
endfunction
function Trig_Snowfall_Actions takes nothing returns nothing
local unit caster = GetTriggerUnit()
local timer t = CreateTimer()
call SetHandleHandle(t, "caster", caster)
call TimerStart(t, 1, true, function Trig_Snowfall_Target)
call TriggerSleepAction(30)
call FlushHandleLocals(t)
call DestroyTimer(t)
set t = null
set caster = null
endfunction
//===========================================================================
function InitTrig_Snowfall takes nothing returns nothing
set gg_trg_Snowfall = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ( gg_trg_Snowfall, EVENT_PLAYER_UNIT_SPELL_EFFECT )
call TriggerAddCondition( gg_trg_Snowfall, Condition( function Trig_Snowfall_Conditions ) )
call TriggerAddAction( gg_trg_Snowfall, function Trig_Snowfall_Actions )
endfunction
Note: for this to work you need to dl Katana's handle vars and copy and paste it into your map's custom script header.
Basically, lots of complicated JASS, so if you don't know JASS, I wouldn't recommend trying to use this. But basically what it does is every time a unit casts snowfall, the trigger fires a repeatable timer. Every second, the timer selects a random enemy unit within 900 range of the unit that cast snowfall that is not magic immune, creates the dummy unit, makes the dummy unit "fall" towards the target. Once the dummy unit has "fallen" far enough, the dummy unit casts your frost nova spell on the target. The entire spell lasts 30 seconds, so essentially there will be 29 - 30 targets chosen to be frost nova'd. This trigger DOES allow the caster of snowfall to move around without the spell screwing up (because every time a target unit is selected the position of the caster is reevaluated).
OK i don't know why last post screwed up, but here it is again.
Firstly, you need to make a dummy spell, base it off of starfall. Set duration to 0.01, turn off all special effects art, set damage dealt to 0, and area of effect to 0. Make the tooltips, cooldown, and mana cost into whatever things you wanted for your snowfall spell because this will be the spell that the unit actually casts in-game. That being said, give this dummy spell to the unit you want to be able to cast snowfall.
Second, create a spell based off of frost nova. Set everything to whatever you want for the random frost nova effects that snowfall creates, but make sure mana cost is 0.
Third, create a dummy unit. Base it off of a footman, set its collision to 0, give it the Locust unit ability (so it can't be selected or attacked), set unit move type to flying, and set flying height to 900. Like paskovich said, give the unit a good snowflake or ice model (the Frost Bolt missile looks pretty good).
For the following trigger, I will assume that the dummy snowfall ability has a raw code of A000 and that the dummy unit has a raw code of h000. To make this trigger work in your map, change all references to those raw codes to the actual raw codes of the ability/unit in your map.
function Trig_Snowfall_Conditions takes nothing returns boolean
if ( GetSpellAbilityId() == 'A000' ) then
return true
endif
return false
endfunction
function Trig_Snowfall_Target_Conditions takes nothing returns boolean
local timer t = GetExpiredTimer()
local unit caster = GetHandleUnit(t, "caster")
return ( IsUnitEnemy(GetFilterUnit(), GetOwningPlayer(caster)) and IsUnitType(GetFilterUnit(), UNIT_TYPE_MAGIC_IMMUNE) == false )
endfunction
function Trig_Snowfall_Fall takes nothing returns nothing
local timer tt = GetExpiredTimer()
local unit target = GetHandleUnit(tt, "target")
local unit dummy = GetHandleUnit(tt, "dummy")
local real x = GetUnitX(dummy)
local real y = GetUnitY(dummy)
call SetUnitPosition(dummy, x, y)
call SetUnitFlyHeight(dummy, (GetUnitFlyHeight(dummy) - 5), 1500)
set tt = null
set target = null
set dummy = null
endfunction
function Trig_Snowfall_Target takes nothing returns nothing
local timer t = GetExpiredTimer()
local timer tt = CreateTimer()
local unit caster = GetHandleUnit(t, "caster")
local unit target = FirstOfGroup(GetRandomSubGroup(1, GetUnitsInRangeOfLocMatching(900, GetUnitLoc(caster), Condition(function Trig_Snowfall_Target_Conditions))))
local unit dummy = CreateUnitAtLoc(GetOwningPlayer(caster), 'h000', GetUnitLoc(target), 270)
call SetHandleHandle(tt, "target", target)
call SetHandleHandle(tt, "dummy", dummy)
call TimerStart(tt, 0.03, true, function Trig_Snowfall_Fall)
loop
exitwhen ( GetUnitFlyHeight(dummy) <= 60)
call TriggerSleepAction(0.1)
endloop
call DestroyTimer(tt)
call IssueTargetOrder( dummy, "frostnova", target )
call TriggerSleepAction(1)
call RemoveUnit(dummy)
set t = null
set tt = null
set caster = null
set target = null
set dummy = null
endfunction
function Trig_Snowfall_Actions takes nothing returns nothing
local unit caster = GetTriggerUnit()
local timer t = CreateTimer()
call SetHandleHandle(t, "caster", caster)
call TimerStart(t, 1, true, function Trig_Snowfall_Target)
call TriggerSleepAction(30)
call FlushHandleLocals(t)
call DestroyTimer(t)
set t = null
set caster = null
endfunction
//===========================================================================
function InitTrig_Snowfall takes nothing returns nothing
set gg_trg_Snowfall = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ( gg_trg_Snowfall, EVENT_PLAYER_UNIT_SPELL_EFFECT )
call TriggerAddCondition( gg_trg_Snowfall, Condition( function Trig_Snowfall_Conditions ) )
call TriggerAddAction( gg_trg_Snowfall, function Trig_Snowfall_Actions )
endfunction
Note: for this to work you need to dl Katana's handle vars and copy and paste it into your map's custom script header.
Basically, lots of complicated JASS, so if you don't know JASS, I wouldn't recommend trying to use this. But basically what it does is every time a unit casts snowfall, the trigger fires a repeatable timer. Every second, the timer selects a random enemy unit within 900 range of the unit that cast snowfall that is not magic immune, creates the dummy unit, makes the dummy unit "fall" towards the target. Once the dummy unit has "fallen" far enough, the dummy unit casts your frost nova spell on the target. The entire spell lasts 30 seconds, so essentially there will be 29 - 30 targets chosen to be frost nova'd. This trigger DOES allow the caster of snowfall to move around without the spell screwing up (because every time a target unit is selected the position of the caster is reevaluated).
man... and you say that my version is complicated ... your code is totally useless, and not working. you use waits inside a timer, and also this "filtering" is a piece of sh.t...
here you go:
function Trig_Snowfall_Conditions takes nothing returns boolean
return GetSpellAbilityId() == 'A000'
endfunction
function Trig_Snowfall_Fall takes nothing returns nothing
local timer tt = GetExpiredTimer()
local unit target = GetHandleUnit(tt, "target")
local unit d = GetHandleUnit(tt, "dummy")
call SetUnitPosition(d, GetUnitX(target), GetUnitY(target))
call SetUnitFlyHeight(d, GetUnitFlyHeight(d) - 5, 0)
if GetUnitFlyHeight(d) < 60 then
call IssueTargetOrder(d, "frostnova", target)
call UnitApplyTimedLife(d, 'BTLF', 0.1)
call FlushHandleLocals(tt)
call DestroyTimer(tt)
endif
set tt = null
set target = null
set d = null
endfunction
function Trig_Snowfall_Target takes nothing returns nothing
local timer t = GetExpiredTimer()
local timer tt
local unit caster = GetHandleUnit(t, "caster")
local group g = GetUnitsInRangeOfLocMatching(900, GetUnitLoc(caster), null)
local unit u = null
local unit d = null
loop
set u = FirstOfGroup(g)
call GroupRemoveUnit(g, u)
exitwhen u == null
if IsUnitEnemy(u, GetOwningPlayer(caster)) and IsUnitType(u, UNIT_TYPE_MAGIC_IMMUNE) == false then
set d = CreateUnit(GetOwningPlayer(caster), 'e000', GetUnitX(u), GetUnitY(u), 0)
set tt = = CreateTimer()
call SetHandleHandle(tt, "target", u)
call SetHandleHandle(tt, "dummy", d)
call TimerStart(tt, 0.03, true, function Trig_Snowfall_Fall)
set d = null
set tt = null
endif
endloop
call DestroyGroup(g)
call SetHandleInt(t, "times", GetHandleInt(t, "times") + 1)
if GetHandleInt(t, "times") == 30 then
call PauseTimer(t)
call FlushHandleLocals(t)
call DestroyTimer(t)
endif
set t = null
set caster = null
endfunction
function Trig_Snowfall_Actions takes nothing returns nothing
local unit caster = GetTriggerUnit()
local timer t = CreateTimer()
call SetHandleHandle(t, "caster", caster)
call TimerStart(t, 1, true, function Trig_Snowfall_Target)
set t = null
set caster = null
endfunction
//===========================================================================
function InitTrig_Snowfall takes nothing returns nothing
set gg_trg_Snowfall = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ( gg_trg_Snowfall, EVENT_PLAYER_UNIT_SPELL_EFFECT )
call TriggerAddCondition( gg_trg_Snowfall, Condition( function Trig_Snowfall_Conditions ) )
call TriggerAddAction( gg_trg_Snowfall, function Trig_Snowfall_Actions )
endfunction
i haven't tested it (and i won't), but it must be working.
paskovich, your trigger won't work. You nullify your timer variables without destroying the timers first. This results in the timers being unable to be destroyed and thus the timers will keep firing forever.
omfg plz ignore tht last post. My idiot friend is screwing with my account. and btw paskovich, wuts with the "times" counter? Why not just destroy the timer after 30 seconds?
well, here, we could use wait 30 seconds cause the timer shoots every second. but if it's < 0.1, then it's better to use a counter. it's more accurate.