• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

Sleep+AOE+channel

Status
Not open for further replies.
Level 4
Joined
Apr 23, 2011
Messages
88
So, I want to make a few different channeled ability (GUI), all of which are area of effect sleeps. They shouldn't be too hard but I can't crack it--every time I start thinking I know something about world editor it goes and makes me look foolish... Oh well, here are the abilities:

Ability One:
(1) Hero begins channeling Mass Sleep (the ability)
(2) Enemy units within targeted area fall asleep
(3) Any enemy who enters the area while channeling continues falls asleep
(4) They never wake up until channeling ends

Ability Two:
Same as Ability One but delete (3)

Ability Three:
Same as Ability Two but replace (4) with: They wake up when hit
 
Level 5
Joined
Sep 1, 2010
Messages
168
Create a channelling ability.
Use a trigger that detects *starts the efect of an ability*
->your channelling ability
pick every units within range of xyz and use an if so set which unit shall not sleep (at least you need *picked unit = triggering unit is false)
then - depending on your other stuff -> either make unit sleep (with that, they autamatically should wake up when receiving damage) or cast the undead sleep on it via a dummy unit ->should last infinite

Now a 2nd trigger that detects when your caster finishes casting an ability and also tirggers when your caster stops.
Next pick again every unit in range and a) wake them up or b) remove buff (sleep -> for the undead version).

For every unit entering you sleep region use -> unit comes within range
-> make unit sleep or dummy unit cast sleep on triggering unit.
for unit within range you might store that point in a variable...

So far should work, if you only need 1 unit casting.
If you need it MUI, things must be done different - currently no clue (just back from uni and still brain dead :vw_sad: )
 
Level 16
Joined
May 1, 2008
Messages
1,605
Peon Power!

Moin moin =)

Well I remember a spell I created longer time ago nearby the same as you need for your channel mass sleep. But before you use this:

1) Modify the "starfall" ability for the castable ability.
2) Then modify the "sleep" ability, so units can cast it, cost 0 mana, loong duration (is removed anyway when spell ends) and so on
3) At last create a dummy
4) Then c&p this code and change the configure-able things like you need it:

JASS:
library MassSleep initializer init

    globals
        private constant integer SPELL_ID = 'A000'
        private constant integer BUFF_ID = 'B000'
        private constant integer DUMMY_ID = 'dumX'
        private constant integer DUMMY_SPELL_ID = 'A001'
        
        private constant string ORDER = "starfall"
        
        // Don't change \\
        
        private integer T
        private constant real L = 0.04
        private constant hashtable H = InitHashtable()
    endglobals
    
    private function range takes integer level returns real
        return 400. + 100. * level
    endfunction
    
    private function duration takes integer level returns real
        return 7. + 2. * level
    endfunction
        
    // Don't change \\
    
    private struct MassSleep
        unit    caster      = null
        real    r          = 0.
        real    d          = 0.
        real    t          = 0.
        
        private static method GroupActions takes nothing returns boolean
            local thistype this = T
            local unit f = GetFilterUnit()
            local unit u
            
            if GetWidgetLife(f) > 0.405 and IsUnitEnemy(f,GetOwningPlayer(.caster)) and IsUnitType(f,UNIT_TYPE_STRUCTURE) == false and IsUnitType(f,UNIT_TYPE_MAGIC_IMMUNE) == false and GetUnitAbilityLevel(f,BUFF_ID) < 1 then
                set u = CreateUnit(GetOwningPlayer(.caster),DUMMY_ID,GetUnitX(f),GetUnitY(f),GetUnitFacing(f))
                call UnitAddAbility(u,DUMMY_SPELL_ID)
                call SetUnitAbilityLevel(u,DUMMY_SPELL_ID,GetUnitAbilityLevel(.caster,SPELL_ID))
                call IssueTargetOrder(u,"sleep",f)
            endif
            set f = null
            set u = null
            return false
        endmethod
        
        private static method GroupEnd takes nothing returns boolean
            local thistype this = T
            local unit f = GetFilterUnit()
            
            if GetUnitAbilityLevel(f,BUFF_ID) > 0 then
                call UnitRemoveAbility(f,BUFF_ID)
            endif
            set f = null
            return false
        endmethod
        
        private static method Loop takes nothing returns nothing
            local timer t = GetExpiredTimer()
            local integer this = LoadInteger(H,GetHandleId(t),0)
            local group g = CreateGroup()
            
            if GetUnitCurrentOrder(GetTriggerUnit()) == S2I(ORDER) then
                set .t = .t + L
                if .t <= .d then
                set T = this
                    call GroupEnumUnitsInRange(g,GetUnitX(.caster),GetUnitY(.caster),.r,Condition(function MassSleep.GroupActions))
                else
                    set T = this
                    call GroupEnumUnitsInRange(g,GetUnitX(.caster),GetUnitY(.caster),.r,Condition(function MassSleep.GroupEnd))
                    call PauseTimer(t)
                    call DestroyTimer(t)
                    call .destroy()
                endif
            else
                set T = this
                call GroupEnumUnitsInRange(g,GetUnitX(.caster),GetUnitY(.caster),.r,Condition(function MassSleep.GroupEnd))
                call PauseTimer(t)
                call DestroyTimer(t)
                call .destroy()
            endif
            call DestroyGroup(g)
            set t = null
        endmethod
        
        static method create takes unit caster returns thistype
            local thistype this = .allocate()
            local timer t = CreateTimer()
            local group g = CreateGroup()
            
            set .caster = caster
            set .r = range(GetUnitAbilityLevel(.caster,SPELL_ID))
            set .d = duration(GetUnitAbilityLevel(.caster,SPELL_ID))
            
            set T = this
            call GroupEnumUnitsInRange(g,GetUnitX(.caster),GetUnitY(.caster),.r,Condition(function MassSleep.GroupActions))
            call SaveInteger(H,GetHandleId(t),0,this)
            call TimerStart(t,L,true,function MassSleep.Loop)
            set t = null
            call DestroyGroup(g)
            return this
        endmethod
    endstruct
    
    private function cast takes nothing returns boolean
        if GetSpellAbilityId() == SPELL_ID then
            call MassSleep.create(GetTriggerUnit())
        endif
        return false
    endfunction
    
    private function init takes nothing returns nothing
        local trigger t = CreateTrigger()
        local integer i = 0
                
        loop
            exitwhen i == 15
            call TriggerRegisterPlayerUnitEvent(t,Player(i),EVENT_PLAYER_UNIT_SPELL_EFFECT,null)
            set i = i + 1
        endloop
        call TriggerAddCondition(t,Condition(function cast))
        set t = null
    endfunction
endlibrary

Greetings and Peace
Dr. Boom
 
Status
Not open for further replies.
Top