Map automatically closing?

Joshman_09

New Member
Reaction score
2
Okay so i recently saved a custom skill to my map. and now when i go to host it or test it it just returns me to the lan screen. or if i use we to test it it just brings me to the warcraft3 screen..

any ideas how to fix?
 

Ryushi

"I will stand, or I will fall. I will not sit."
Reaction score
59
It might be an infinite loop. Try posting any triggers you have for your custom spell.
 

Joshman_09

New Member
Reaction score
2
Chain Chop
JASS:
//TESH.scrollpos=89
//TESH.alwaysfold=0
scope ChainChop initializer OnInit

//=====================================================================//
//                       CONFIGURATION                                 //
//=====================================================================//

globals
    private constant integer ABILID = 'ABCC' // raw code of ability "Chain Chop"
    private constant integer SLASHES = 6 // number of slashes
    private constant integer ANIMATION = 2 // number of attack animation that you want to display
    
    private constant real DURATION = 2.0 // duration to complete slash
    private constant real DAMAGE = 100.0 // base damage of each slash
    
    private constant boolean STR = false // true if strength added as damage
    private constant boolean AGI = true // true if agility added as damage
    private constant boolean INT = false // true if intelligence added as damage
    
    private constant string array ANIMTAG[ANIMATION - 1]
endglobals

private function Setup takes nothing returns nothing // to add more animation, simply
    set ANIMTAG[0] = "attack"                        // add more "ANIMTAG" variables
    set ANIMTAG[1] = "slam"                          // with higher array value
endfunction

//=====================================================================//
//                       END CONFIGURATION                             //
//=====================================================================//

native UnitAlive takes unit id returns boolean

private function GetAnimation takes nothing returns string
    return ANIMTAG[GetRandomInt(0, ANIMATION - 1)]
endfunction

private function GetDamage takes unit u returns real
    local real r = DAMAGE
    if STR then
        set r = r + GetHeroStr(u, true)
    endif
    if AGI then
        set r = r + GetHeroAgi(u, true)
    endif
    if INT then
        set r = r + GetHeroInt(u, true)
    endif
    return r
endfunction

private struct ChainChop
    unit caster
    unit target
    effect e
    integer slashes
endstruct

private function Slash takes nothing returns boolean
    local ChainChop d = KT_GetData()
    local real x
    local real y
    local real r
    local effect e
    if d.slashes == 0 or not UnitAlive(d.target) then
        call SetUnitTimeScale(d.caster, 1.0)
        call PauseUnit(d.caster, false)
        call DestroyEffect(d.e)
        call d.destroy()
        set e = null
        return true
    endif
    set r = GetRandomReal(0.0, 360.0)
    set x = GetUnitX(d.target) + 100.0 * Cos(r * bj_DEGTORAD)
    set y = GetUnitY(d.target) + 100.0 * Sin(r * bj_DEGTORAD)
    set e = AddSpecialEffect("Abilities\\Spells\\Orc\\MirrorImage\\MirrorImageCaster.mdl", GetUnitX(d.caster), GetUnitY(d.caster))
    call DestroyEffect(e)
    set e = AddSpecialEffectTarget("Abilities\\Spells\\Other\\Stampede\\StampedeMissileDeath.mdl", d.target, "chest")
    call DestroyEffect(e)
    call SetUnitPosition(d.caster, x, y)
    call SetUnitFacing(d.caster, r - 180.0)
    call SetUnitAnimation(d.caster, GetAnimation())
    call UnitDamageTarget(d.caster, d.target, GetDamage(d.caster), true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_WHOKNOWS)
    set d.slashes = d.slashes - 1
    set e = null
    return false
endfunction

private function Actions takes nothing returns nothing
    local ChainChop d = ChainChop.create()
    local effect e
    set d.caster = GetTriggerUnit()
    set d.target = GetSpellTargetUnit()
    set d.slashes = SLASHES - 1
    set d.e = AddSpecialEffectTarget("war3mapImported\\Sweep.mdx", d.caster, "weapon")
    call PauseUnit(d.caster, true)
    call SetUnitTimeScale(d.caster, SLASHES/DURATION)
    call SetUnitAnimation(d.caster, GetAnimation())
    set e = AddSpecialEffectTarget("Abilities\\Spells\\Other\\Stampede\\StampedeMissileDeath.mdl", d.target, "chest")
    call DestroyEffect(e)
    call UnitDamageTarget(d.caster, d.target, GetDamage(d.caster), true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_WHOKNOWS)
    call KT_Add(function Slash, d, DURATION/SLASHES)
    set e = null
endfunction

private function Conditions takes nothing returns boolean
    return GetSpellAbilityId() == ABILID
endfunction

private function OnInit 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)
    call Setup()
endfunction

endscope


KT
JASS:
//TESH.scrollpos=291
//TESH.alwaysfold=0
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//~~ KT ~~ Key Timers 2 ~~ By Jesus4Lyf ~~ Version 1.7.3 ~~
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
//  What is Key Timers?
//         - Key Timers attaches structs to timers, or more to the point timed
//           effects.
//         - You can specify different periods.
//         - Key Timers only uses one timer with one trigger per low period
//           to keep things efficient, especially within the looping.
//         - Key Timers alternatively uses one trigger per instance for all higher
//           periods to allow accurate expirations in a stable and efficient fashion.
//
//    =Pros=
//         - Easy to use.
//         - Fastest attachment loading system (storing in parallel arrays).
//         - Fastest execution system for low periods (all functions on one trigger).
//         - Allows multiple periods to be used.
//         - No H2I. Backwards compatability through patch 1.23 and 1.24.
//
//    =Cons=
//         - The code passed into KT2 must call KT_GetData exactly once.
//         - Periods must be a multiple of 0.00125 seconds. Not 0.007, for example.
//
//    Functions:
//         - KT_Add(userFunc, struct, period)
//         - KT_GetData returns the struct
//
//         - userFunc is to be a user function that takes nothing and returns boolean.
//           It will be executed by the system every period until it returns true.
//
//         - KT_GetData is to be used inside func, it will return the struct passed to
//           to the Add function. It must be called exactly once within the func.
//
//  Details:
//         - KT2 treats low periods and high periods differently, optimizing each
//           with appropriate speed and accuracy, although this effect is invisible
//           to you, the mapper.
//
//         - While func returns false the timer will continue to call it each period.
//           Once func returns true the instance will be detached from system.
//
//  Thanks:
//         - Daxtreme: For encouraging me to return to Key Timers 2, rather than
//           leave it to rot. His interest in the system restored it, and helped
//           it to become what it is now. <img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" class="smilie smilie--sprite smilie--sprite1" alt=":)" title="Smile    :)" loading="lazy" data-shortname=":)" />
//
//         - Captain Griffen: For his work on Rapid Timers, demonstrating that it
//           is possible to attach all functions to one trigger, and that it is
//           indeed faster.
//
//         - Cohadar: Told me to make Key Timers without a textmacro.
//           Thanks to him for helping me with the original Key Timers system too.
//           Also, I&#039;d like to thank him for his work on Timer Ticker (TT) which
//           demonstrated how to use triggers/conditions in this sort of system,
//           which has been used in Key Timers 2.
//
//  How to import:
//         - Create a trigger named KT.
//         - Convert it to custom text and replace the whole trigger text with this.
//
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
library KT
    ///////////////
    // Constants //
    ////////////////////////////////////////////////////////////////////////////
    // That bit that users may play with if they know what they&#039;re doing.
    // Not touching these at all is recommended.
    globals
        // Period Threshold is the point at which Key Timers 2 will switch from
        // using the single timer per period mechanism to using TAZO, which is
        // better for higher periods due to the first tick being accurate.
        private constant real PERIODTHRESHOLD=0.3 // MUST be below 10.24 seconds.
        
        // Tazo&#039;s number of precached instances. You can go over this during
        // your map at runtime, but it will probably do some small background
        // processing. Precaching just speeds things up a bit.
        private constant integer TAZO_PRECACHE=64
        
        // Tazo uses the low period part of Key Timers 2 to construct triggers
        // over time when precached ones run out. Here you can set the period used.
        private constant real TAZO_CONSTRUCT_PERIOD=0.03125
    endglobals
    
    //////////////////////////
    // Previous KT2 Globals //
    ////////////////////////////////////////////////////////////////////////////
    // These needed to be moved here for TAZO to hook GetData.
    globals
        private timer array KeyTimer
        private trigger array TimerTrigger
        private integer array KeyTimerListPointer
        private integer array KeyTimerListEndPointer
        private triggercondition array TriggerCond
        private boolexpr array Boolexpr
        private integer array Data
        private integer array Next
        private integer array Prev
        private integer TrigMax=0
        private integer array NextMem
        private integer NextMemMaxPlusOne=1
        private integer array ToAddMem
        private triggercondition array ToRemove
        private boolexpr array ToDestroy
        private boolean array IsAdd
        private integer AddRemoveMax=0
        
        // Locals
        private integer t_id=-1
        private integer t_mem
        private integer t_lastmem
        private integer a_id
        private integer a_mem
        
        // Code Chunks
        private conditionfunc RemoveInstanceCond
    endglobals
    
    //////////////////
    // Previous KT2 //
    ////////////////////////////////////////////////////////////////////////////
    // The KT2 implementation
    private function KeyTimerLoop takes nothing returns nothing
        set t_id=R2I(TimerGetTimeout(GetExpiredTimer())*800)
        set t_mem=KeyTimerListEndPointer[t_id]
        call TriggerEvaluate(TimerTrigger[t_id])
        set t_mem=0
        loop
            exitwhen t_mem==AddRemoveMax
            set t_mem=t_mem+1
            if IsAdd[t_mem] then
                set TriggerCond[ToAddMem[t_mem]]=TriggerAddCondition(TimerTrigger[t_id],Boolexpr[ToAddMem[t_mem]])
            else
                call TriggerRemoveCondition(TimerTrigger[t_id],ToRemove[t_mem])
                call DestroyBoolExpr(ToDestroy[t_mem])
            endif
        endloop
        set AddRemoveMax=0
        set t_id=-1
    endfunction
    
    private function RemoveInstance takes nothing returns boolean
        // Will only fire if code returns true.
        set AddRemoveMax=AddRemoveMax+1
        set IsAdd[AddRemoveMax]=false
        set ToRemove[AddRemoveMax]=TriggerCond[t_lastmem]
        set ToDestroy[AddRemoveMax]=Boolexpr[t_lastmem]
        if Next[t_lastmem]==0 then
            set KeyTimerListEndPointer[t_id]=Prev[t_lastmem]
        endif
        set Prev[Next[t_lastmem]]=Prev[t_lastmem]
        if Prev[t_lastmem]==0 then
            set KeyTimerListPointer[t_id]=Next[t_lastmem]
            if KeyTimerListPointer[t_id]&lt;1 then
                call PauseTimer(KeyTimer[t_id])
            endif
        else
            set Next[Prev[t_lastmem]]=Next[t_lastmem]
        endif
        set NextMem[NextMemMaxPlusOne]=t_lastmem
        set NextMemMaxPlusOne=NextMemMaxPlusOne+1
        return false
    endfunction
    
    private function KTadd takes code func, integer data, real period returns nothing
        set a_id=R2I(period*800)
        
        if KeyTimer[a_id]==null then
            set KeyTimer[a_id]=CreateTimer()
            set TimerTrigger[a_id]=CreateTrigger()
        endif
        
        if NextMemMaxPlusOne==1 then
            set TrigMax=TrigMax+1
            set a_mem=TrigMax
        else
            set NextMemMaxPlusOne=NextMemMaxPlusOne-1
            set a_mem=NextMem[NextMemMaxPlusOne]
        endif
        
        set Boolexpr[a_mem]=And(Condition(func),RemoveInstanceCond)
        if t_id==a_id then
            set AddRemoveMax=AddRemoveMax+1
            set IsAdd[AddRemoveMax]=true
            set ToAddMem[AddRemoveMax]=a_mem
        else
            if KeyTimerListPointer[a_id]&lt;1 then
                call TimerStart(KeyTimer[a_id],a_id/800.0,true,function KeyTimerLoop)
                set KeyTimerListEndPointer[a_id]=a_mem
            endif
            
            set TriggerCond[a_mem]=TriggerAddCondition(TimerTrigger[a_id],Boolexpr[a_mem])
        endif
        set Data[a_mem]=data
        
        set Prev[a_mem]=0
        set Next[a_mem]=KeyTimerListPointer[a_id]
        set Prev[KeyTimerListPointer[a_id]]=a_mem
        set KeyTimerListPointer[a_id]=a_mem
    endfunction
    
    public function GetData takes nothing returns integer // Gets hooked by TAZO.
        set t_lastmem=t_mem
        set t_mem=Prev[t_mem]
        return Data[t_lastmem]
    endfunction
    
    private function KTinit takes nothing returns nothing
        set RemoveInstanceCond=Condition(function RemoveInstance)
    endfunction
    
    //////////
    // TAZO //
    ////////////////////////////////////////////////////////////////////////////
    // KT2 implementation for higher periods (low frequency).
    globals
        private constant integer TAZO_DATAMEM=8190 // Added for KT2 hook. Don&#039;t change.
    endglobals
    
    globals
        private conditionfunc TAZO_LoadDataCond
        private conditionfunc TAZO_RemoveInstanceCond
        
        private timer   array TAZO_TrigTimer
        private integer array TAZO_Data
        private boolexpr array TAZO_Boolexpr
        
        private trigger array TAZO_AvailableTrig
        private integer       TAZO_Max=0
        
        private integer       TAZO_ConstructNext=0
        private trigger array TAZO_ConstructTrig
        private integer array TAZO_ConstructCount
    endglobals
    
    globals//locals
        private integer TAZO_ConKey
    endglobals
    private function TAZO_Constructer takes nothing returns boolean
        set TAZO_ConKey=GetData()
        call TriggerExecute(TAZO_ConstructTrig[TAZO_ConKey])
        set TAZO_ConstructCount[TAZO_ConKey]=TAZO_ConstructCount[TAZO_ConKey]-1
        if TAZO_ConstructCount[TAZO_ConKey]==0 then
            set TAZO_Max=TAZO_Max+1
            set TAZO_AvailableTrig[TAZO_Max]=TAZO_ConstructTrig[TAZO_ConKey]
            set TAZO_TrigTimer[TAZO_ConKey]=CreateTimer()
            call TriggerRegisterTimerExpireEvent(TAZO_AvailableTrig[TAZO_Max],TAZO_TrigTimer[TAZO_ConKey])
            return true
        endif
        return false
    endfunction
    
    globals//locals
        private trigger TAZO_DeadTrig
        private integer TAZO_DeadCount
    endglobals
    private function TAZO_Recycle takes nothing returns boolean
        set TAZO_DeadTrig=GetTriggeringTrigger()
        set TAZO_DeadCount=GetTriggerExecCount(TAZO_DeadTrig)
        call TriggerClearConditions(TAZO_DeadTrig)
        call DestroyBoolExpr(TAZO_Boolexpr[TAZO_DeadCount])
        call PauseTimer(TAZO_TrigTimer[TAZO_DeadCount])
        set TAZO_Max=TAZO_Max+1
        set TAZO_AvailableTrig[TAZO_Max]=TAZO_DeadTrig
        return false
    endfunction
    
    private function TAZO_LoadData takes nothing returns boolean
        // KT2 Data Hook
        set t_mem=TAZO_DATAMEM
        set Data[TAZO_DATAMEM]=TAZO_Data[GetTriggerExecCount(GetTriggeringTrigger())]
        // End KT2 Data Hook
        return false
    endfunction
    
    private function InitTrigExecCount takes trigger t, integer d returns nothing
        if d&gt;128 then
            call InitTrigExecCount.execute(t,d-128)
            set d=128
        endif
        loop
            exitwhen d==0
            set d=d-1
            call TriggerExecute(t)
        endloop
    endfunction
    
    globals//locals
        private integer TAZO_AddKey
        private trigger TAZO_AddTrigger
    endglobals
    public function TAZOadd takes code func, integer data, real period returns nothing
        if TAZO_Max==0 then
            // Failsafe.
            set TAZO_ConstructNext=TAZO_ConstructNext+1
            set TAZO_AddTrigger=CreateTrigger()
            set TAZO_AddKey=TAZO_ConstructNext
            call InitTrigExecCount.execute(TAZO_AddTrigger,TAZO_AddKey)
            set TAZO_TrigTimer[TAZO_AddKey]=CreateTimer()
            call TriggerRegisterTimerExpireEvent(TAZO_AddTrigger,TAZO_TrigTimer[TAZO_AddKey])
        else
            set TAZO_AddTrigger=TAZO_AvailableTrig[TAZO_Max]
            set TAZO_AddKey=GetTriggerExecCount(TAZO_AddTrigger)
            set TAZO_Max=TAZO_Max-1
        endif
        set TAZO_Data[TAZO_AddKey]=data
        set TAZO_Boolexpr[TAZO_AddKey]=And(Condition(func),TAZO_RemoveInstanceCond)
        call TriggerAddCondition(TAZO_AddTrigger,TAZO_LoadDataCond)
        call TriggerAddCondition(TAZO_AddTrigger,TAZO_Boolexpr[TAZO_AddKey])
        call TimerStart(TAZO_TrigTimer[TAZO_AddKey],period,true,null)
        if TAZO_Max&lt;10 then
            set TAZO_ConstructNext=TAZO_ConstructNext+1
            set TAZO_ConstructTrig[TAZO_ConstructNext]=CreateTrigger()
            set TAZO_ConstructCount[TAZO_ConstructNext]=TAZO_ConstructNext
            call KTadd(function TAZO_Constructer,TAZO_ConstructNext,TAZO_CONSTRUCT_PERIOD)
        endif
    endfunction
    
    private function TAZOinit takes nothing returns nothing
        set TAZO_LoadDataCond=Condition(function TAZO_LoadData)
        set TAZO_RemoveInstanceCond=Condition(function TAZO_Recycle)
        // Allow for GetData
        set Next[TAZO_DATAMEM]=TAZO_DATAMEM
        set Prev[TAZO_DATAMEM]=TAZO_DATAMEM
        // End allow for GetData
        loop
            exitwhen TAZO_Max==TAZO_PRECACHE
            set TAZO_ConstructNext=TAZO_ConstructNext+1 // The index.
            set TAZO_Max=TAZO_Max+1 // Will be the same in the initialiser as ConstructNext.
            set TAZO_AvailableTrig[TAZO_Max]=CreateTrigger()
            call InitTrigExecCount.execute(TAZO_AvailableTrig[TAZO_Max],TAZO_ConstructNext)
            set TAZO_TrigTimer[TAZO_ConstructNext]=CreateTimer()
            call TriggerRegisterTimerExpireEvent(TAZO_AvailableTrig[TAZO_Max],TAZO_TrigTimer[TAZO_ConstructNext])
        endloop
    endfunction
    
    ///////////////
    // Interface //
    ////////////////////////////////////////////////////////////////////////////
    // Stitches it all together neatly.
    public function Add takes code func, integer data, real period returns nothing
        if period&lt;PERIODTHRESHOLD then
            call KTadd(func,data,period)
        else
            call TAZOadd(func,data,period)
        endif
    endfunction
    
    private module InitModule
        private static method onInit takes nothing returns nothing
            call KTinit()
            call TAZOinit()
        endmethod
    endmodule
    
    private struct InitStruct extends array
        implement InitModule
    endstruct
endlibrary

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//    End of Key Timers 2
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 

Ayanami

칼리
Reaction score
288
For vJASS spells/systems/etc, you need to save the map before pressing the "Test Map" button.
 

Joshman_09

New Member
Reaction score
2
Yeah. I even have saved it into my wc3 folder and opened up warcraft try playing and nothing... idk what to do =[
 

luorax

Invasion in Duskwood
Reaction score
67
JASS:
native UnitAlive takes unit id returns boolean

This/that (I've never known which is the correct) is the line which causes the error. Replace the functions with "GetWidgetLife(u) > 0.405", and it'll work fine.
 

Darthfett

Aerospace/Cybersecurity Software Engineer
Reaction score
615
JASS:
native UnitAlive takes unit id returns boolean

This/that (I've never known which is the correct) is the line which causes the error. Replace the functions with "GetWidgetLife(u) > 0.405", and it'll work fine.

IMO, 'this' makes more sense. However, this shouldn't cause any problems.

I should think JASSHelper would throw an error if it wasn't updated, but then again I know nothing about how declaring natives works. Are you sure you have the latest version of JASSHelper?
 

luorax

Invasion in Duskwood
Reaction score
67
0.A.2.B, the newest JASSHelper. I've just tested it, but happens the same. That native "crashes" my map. But as I remember, each native crashes it.
 

0WN3D

New Member
Reaction score
15
Not sure if this info will help but it also happens to me when i try to open a map last time when i havent patch warcraft and it is playable... but after i patch it, the map does the same thing as it is doing to you..... pretty sure it is the patch problem....
 

luorax

Invasion in Duskwood
Reaction score
67
how exactly would i change the native to that? o.o sorry jass noob here.. =P

Here you are:

JASS:
//TESH.scrollpos=89
//TESH.alwaysfold=0
scope ChainChop initializer OnInit

//=====================================================================//
//                       CONFIGURATION                                 //
//=====================================================================//

globals
    private constant integer ABILID = &#039;ABCC&#039; // raw code of ability &quot;Chain Chop&quot;
    private constant integer SLASHES = 6 // number of slashes
    private constant integer ANIMATION = 2 // number of attack animation that you want to display
    
    private constant real DURATION = 2.0 // duration to complete slash
    private constant real DAMAGE = 100.0 // base damage of each slash
    
    private constant boolean STR = false // true if strength added as damage
    private constant boolean AGI = true // true if agility added as damage
    private constant boolean INT = false // true if intelligence added as damage
    
    private constant string array ANIMTAG[ANIMATION - 1]
endglobals

private function Setup takes nothing returns nothing // to add more animation, simply
    set ANIMTAG[0] = &quot;attack&quot;                        // add more &quot;ANIMTAG&quot; variables
    set ANIMTAG[1] = &quot;slam&quot;                          // with higher array value
endfunction

//=====================================================================//
//                       END CONFIGURATION                             //
//=====================================================================//

private function GetAnimation takes nothing returns string
    return ANIMTAG[GetRandomInt(0, ANIMATION - 1)]
endfunction

private function GetDamage takes unit u returns real
    local real r = DAMAGE
    if STR then
        set r = r + GetHeroStr(u, true)
    endif
    if AGI then
        set r = r + GetHeroAgi(u, true)
    endif
    if INT then
        set r = r + GetHeroInt(u, true)
    endif
    return r
endfunction

private struct ChainChop
    unit caster
    unit target
    effect e
    integer slashes
endstruct

private function Slash takes nothing returns boolean
    local ChainChop d = KT_GetData()
    local real x
    local real y
    local real r
    local effect e
    if d.slashes == 0 or GetWidgetLife(d.target) &lt; 0.405 then
        call SetUnitTimeScale(d.caster, 1.0)
        call PauseUnit(d.caster, false)
        call DestroyEffect(d.e)
        call d.destroy()
        set e = null
        return true
    endif
    set r = GetRandomReal(0.0, 360.0)
    set x = GetUnitX(d.target) + 100.0 * Cos(r * bj_DEGTORAD)
    set y = GetUnitY(d.target) + 100.0 * Sin(r * bj_DEGTORAD)
    set e = AddSpecialEffect(&quot;Abilities\\Spells\\Orc\\MirrorImage\\MirrorImageCaster.mdl&quot;, GetUnitX(d.caster), GetUnitY(d.caster))
    call DestroyEffect(e)
    set e = AddSpecialEffectTarget(&quot;Abilities\\Spells\\Other\\Stampede\\StampedeMissileDeath.mdl&quot;, d.target, &quot;chest&quot;)
    call DestroyEffect(e)
    call SetUnitPosition(d.caster, x, y)
    call SetUnitFacing(d.caster, r - 180.0)
    call SetUnitAnimation(d.caster, GetAnimation())
    call UnitDamageTarget(d.caster, d.target, GetDamage(d.caster), true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_WHOKNOWS)
    set d.slashes = d.slashes - 1
    set e = null
    return false
endfunction

private function Actions takes nothing returns nothing
    local ChainChop d = ChainChop.create()
    local effect e
    set d.caster = GetTriggerUnit()
    set d.target = GetSpellTargetUnit()
    set d.slashes = SLASHES - 1
    set d.e = AddSpecialEffectTarget(&quot;war3mapImported\\Sweep.mdx&quot;, d.caster, &quot;weapon&quot;)
    call PauseUnit(d.caster, true)
    call SetUnitTimeScale(d.caster, SLASHES/DURATION)
    call SetUnitAnimation(d.caster, GetAnimation())
    set e = AddSpecialEffectTarget(&quot;Abilities\\Spells\\Other\\Stampede\\StampedeMissileDeath.mdl&quot;, d.target, &quot;chest&quot;)
    call DestroyEffect(e)
    call UnitDamageTarget(d.caster, d.target, GetDamage(d.caster), true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_WHOKNOWS)
    call KT_Add(function Slash, d, DURATION/SLASHES)
    set e = null
endfunction

private function Conditions takes nothing returns boolean
    return GetSpellAbilityId() == ABILID
endfunction

private function OnInit 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)
    call Setup()
endfunction

endscope
 

Joshman_09

New Member
Reaction score
2
ok i got it now however when i use the skill it doesnt play the animation or deal damage? ayanami was i supposed to copy the dummy caster units from ur map aswell or something?
 
General chit-chat
Help Users
  • No one is chatting at the moment.

      The Helper Discord

      Members online

      No members online now.

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top