• Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.

Custom Spell - Snowfall

Status
Not open for further replies.
Level 1
Joined
Aug 16, 2006
Messages
1
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.
 
Level 3
Joined
Jul 29, 2006
Messages
61
BlueScreenOD said:
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.

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.
 
Level 11
Joined
Jul 12, 2005
Messages
764
there's way to do this to work properly and nice, but if you're new to triggering, i won't tell u... :p
cause it needs 2-3 triggers. but the best would be to do this in JASS...

edit: ok i've changed my mind... :D

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 - 18)
if fly height of Snowflake < 50
order Snowflake to "frostnova" Target
kill/remove Frostnova
Target = No unit
 
Level 11
Joined
Feb 22, 2006
Messages
752
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.

JASS:
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).
 
Level 11
Joined
Feb 22, 2006
Messages
752
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.

JASS:
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).
 
Level 11
Joined
Jul 12, 2005
Messages
764
man... and you say that my version is complicated :D... 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:

JASS:
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.
 
Status
Not open for further replies.
Top