• 🏆 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!

Star Fire v1.01

This bundle is marked as useful / simple. Simplicity is bliss, low effort and/or may contain minor bugs.
- Youtube -

- Images -
14281027878_de259b79c8_o.png

14487759303_577e2a30f3_o.png

14466454464_07b8c911a8_o.png


WARNING: MAX_WING mod 2 = 1

- Code vJass -
JASS:
scope test initializer int
    globals
        //================================================================
        //=             ----- Object of Spells Ability -----             =
        //================================================================
        //  1. Spells ID
        private constant    integer     SPELL_ID            =   'A000'
        
        private constant    string      LIGHTNING           =   "AFOD"
        
        private constant    string      EFFECT              =   "Abilities\\Spells\\Other\\Doom\\DoomDeath.mdl"
        
        private constant    integer     MAX_WING            =   7  
        
        private constant    real        AOE                 =   800
        
        private constant    real        INIT_DAMAGE         =   100
        
        private constant    real        PER_DAMAGE          =   300
        
        private constant    integer     BORN_TIME           =   7
    
        private constant    integer     MAX_EFFECT          =   3
        //================================================================
        private constant    real        TICK_TIME           =   0.03125
        private constant    integer     TACK                =   BORN_TIME*MAX_WING
        private constant    integer     CYCLE               =   MAX_WING/2
        private constant    real        AOE_P2              =   AOE/2
        private constant    real        CONST_1             =   (2*bj_PI*CYCLE)/MAX_WING
        private constant    real        CONST_2             =   (2*bj_PI)/MAX_WING
        private             group       g                   =   CreateGroup()
        private             unit        enemy
        private             real        temp
    endglobals

    private struct data  
        integer             iloop
        integer             jloop
        integer             tick
        integer             iwing
        integer             level
        unit                caster
        real                x_target
        real                y_target
        real        array   x[MAX_WING]
        real        array   y[MAX_WING]
        lightning   array   l[MAX_WING]
        boolean     array   b[MAX_WING]
    endstruct
        
    private function update takes nothing returns nothing
        local data this = getRT()
            
        set this.iwing = this.tick/BORN_TIME
        if this.iwing == 0 then
            set this.iwing = MAX_WING
        endif 
            
        if this.tick < TACK then
            if this.b[this.iwing] then
                if this.iwing < MAX_WING then
                    set this.l[this.iwing] = AddLightning(LIGHTNING, true, this.x[this.iwing], this.y[this.iwing], this.x[this.iwing + 1], this.y[this.iwing + 1])
                    set this.b[this.iwing] = false
                elseif this.iwing == MAX_WING then         
                    set this.l[this.iwing] = AddLightning(LIGHTNING, true, this.x[this.iwing], this.y[this.iwing], this.x[1], this.y[1])
                    set this.b[this.iwing] = false
                endif
            endif   
        else
            set this.iloop = 1
            loop                
                exitwhen this.iloop > MAX_WING
                call DestroyLightning(this.l[this.iloop])
                set this.l[this.iloop] = null
                set this.jloop = 1
                loop
                    exitwhen this.jloop > MAX_EFFECT
                    set temp = this.iloop*CONST_2
                    set this.x[this.iloop]  =   this.x_target + AOE_P2*this.jloop/MAX_EFFECT*Cos(temp)
                    set this.y[this.iloop]  =   this.y_target + AOE_P2*this.jloop/MAX_EFFECT*Sin(temp)
                    call DestroyEffect(AddSpecialEffect(EFFECT, this.x[this.iloop], this.y[this.iloop]))
                    set this.jloop          =   this.jloop + 1
                endloop                    
                set this.iloop  = this.iloop + 1                    
            endloop
                
            call EnumGroup(g, this.x_target, this.y_target, AOE)
            loop
                set enemy = FirstOfGroup(g)
                exitwhen enemy == null
                if  IsUnitEnemy(enemy, GetOwningPlayer(this.caster)) and GetUnitState(enemy, UNIT_STATE_LIFE) > 0 and not IsUnitType(enemy, UNIT_TYPE_STRUCTURE) then
                    call UnitDamageTargetBJ(this.caster, enemy, INIT_DAMAGE+PER_DAMAGE*this.level, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL )
                endif
                call GroupRemoveUnit(g, enemy)
            endloop
                
            set enemy       =   null
            set this.caster =   null
            call breakRT()
            call this.destroy()
            return                
        endif
            
        set this.tick = this.tick + 1           
    endfunction

    private function f takes nothing returns nothing
        local integer   i       =   1
        local data      this    =   data.create()
        
        set     this.tick       =   0
        set     this.caster     =   GetTriggerUnit()
        set     this.level      =   GetUnitAbilityLevel(this.caster, SPELL_ID)
        set     this.x_target   =   GetSpellTargetX()
        set     this.y_target   =   GetSpellTargetY()
        
        loop
            exitwhen i > MAX_WING
            set temp = i*CONST_1
            set this.x[i]   =   this.x_target + AOE_P2*Cos(temp)
            set this.y[i]   =   this.y_target + AOE_P2*Sin(temp)
            set this.b[i]   =   true
            set i           =   i + 1
        endloop
           
        call addRT(this, TICK_TIME, true, function update)
    endfunction

    private function c takes nothing returns boolean
        return GetSpellAbilityId() == SPELL_ID
    endfunction

//===========================================================================
    private function int takes nothing returns nothing
        local trigger t = CreateTrigger()
        call AddEvent(t, EVENT_PLAYER_UNIT_SPELL_EFFECT )
        call TriggerAddCondition(t, Condition( function c ) )
        call TriggerAddAction(t, function f )
    endfunction

endscope

- Code ExortKit -
JASS:
//=========================================================================================
//* _____                _   _  ___ _                                                                          
//*| ____|_  _____  _ __| |_| |/ (_) |_
//*|  _| \ \/ / _ \| '__| __| ' /| | __|
//*| |___ >  < (_) | |  | |_| . \| | |_
//*|_____/_/\_\___/|_|   \__|_|\_\_|\__|                                                                                                            
/* by dhguardianes ver: v2.98.22 [22/07/2014] Updates: goo.gl/VHWLF3
-------------------------------------------------------------------------------------------
        ExortKit is standard library are aggregate function. and also the engine of map.
        will updated in future, propose to satisfy the function and to write Scripts certain script built function.

P/S: Library just compatible with X Design Pack v1.06 Download: goo.gl/1rEbaQ*/
//! runtextmacro FrameInitializer() /*Backward Compatibility*/
library ExortKit initializer int
globals //Credit: 19101994,Rising_Dusk,Jesus4Lyf,Vexorian,Romek,Deaod,Maker,grim001,Anitarf,Nestharus,Tom Kazansky
//! runtextmacro VarInitializer() //Initializer===============================
//Features options============================================================

    private constant boolean    BOUND_SENTINEL         = true   //automatically fix try to get out of the map bounds and crash.
private constant boolean    POWERUP_SENTINEL         = true   //automatically fix all rune/tome memory leaks.
       
    private constant boolean    RESURRECT_TREE           = true   //resurrects Trees
    private constant boolean    RESURRECT_TREE_ANIMATION = true   //animation birth
    private constant real       RESURRECT_TREE_DURATION  = 32     //duration
    
    private constant boolean    DEBUG_LOG_TRACK_DEBUGMSG = false  // track debugmsg in debuglog
    private constant string     DEBUG_LOG_SAVE_PATH      = "logs\\DebugLog.txt"
    
    private constant boolean    DEBUG_HANDLE_COUNTER     = false //Display handle per times
    private constant boolean    DEBUG_HANDLE_BASIC_STYLE = false
    
    private constant boolean    SVLD_DIALOG              = true //save game will display.
    private constant string     SVLD_SAVE_TEXT           = ".w3z has been saved in "
    private constant string     SVLD_LOAD_TEXT           = "The file save has been loaded in  "
    
    private constant boolean    LUCKY_RANDOM_SEED        = true //update random seed every time you are getting something random and you will ensure very unique randomness.
    private constant boolean    GET_FIRST_PLAYER         = true //get first player!
//Systems options======================================================

    private constant boolean    COUNT_TIME_ELAPSED       = true //dota time elapsed
    private constant integer    GOLD_PER_SECONDS         = 1     // 0 to disable

    private constant boolean    ITEM_STACKING            = true
    private constant itemtype   STACKING_TYPE            = ITEM_TYPE_CHARGED
    
private constant boolean    ITEM_UNDROPPABLE	= false	//dota undroppable items!
    private constant boolean    ITEM_UNSAME              = false
    private constant string     HideMinimapAPIPath       = "435983460.blp" //Download: goo.gl/KmR6ID
    constant         real       MAX_COLLISION_SIZE       = 197.00
    constant         real       LIGHTNING_ZOFFSET        = 56.0 //This offset is applied for API: lightningtrack
    private constant string     KNOC_DIRT_SFX            = "KnocDrist.mdx" //Download: goo.gl/oQuiAY
    private constant string     KNOC_WATER_SFX           = "KnocWater.mdx" //Download: goo.gl/Srx6xf
    private constant boolean    ALLOW_STACK_UNIT         = true //for AddKnoc API: stack unit when knoc
    private constant boolean    BLOCK_DAMAGE_API         = false
// Plugins for: Block Damage API
    // external ObjectMerger w3a AIlz dprv anam "Life Bonus" ansf "(Damage System)" Ilif 1 500000 aite 0
// Plugins for: SetMaxHP,SetMaxMP
// external ObjectMerger w3a AIl2 Awhp anam "Health Modifier" alev 7 Ilif 1 0 Ilif 2 -1 Ilif 3 -10 Ilif 4 -100 Ilif 5 1 Ilif 6  10 Ilif 7 100 ansf "(auto set)" aite 0 aart "ReplaceableTextures\CommandButtons\BTNPeriapt1.blp"
// external ObjectMerger w3a AImz Awmp anam "Mana Modifier" alev 7 Iman 1 0 Iman 2 -1 Iman 3 -10 Iman 4 -100 Iman 5 1 Iman 6  10 Iman 7 100 ansf "(auto set)" aite 0 aart "ReplaceableTextures\CommandButtons\BTNPendantOfMana.blp"
//Variables options====================================================

        boolean IsGameSingle     = bj_isSinglePlayer //check single player
        boolean IsGameSaved      = false             // check game saved
        boolean IsGameLoaded     = false             // check game loaded
        boolean IsGameStarter    = true              // end game set false
        real    FONT_SIZE	= 10.               // config Textag API: CreateTextTagXY,AddGoldInUnit,AddHeroEXP
integer SOUND_VOLUME     = 127               // config sound volume API: PlaySoundEx,PlaySoundAll,PlaySoundPlayer
        boolean DEBUG_LOCK       = false             // config to block a track BJDebugMsg
        string  CUS_KNOC_SFX     = ""                // custom SFX for addknoc API!
        boolean NOT_KNOC_SFX     = false             // block effect for addknoc API!
        boolean SHOW_HANDLE      = true              // using to block a track Handle map
        player  GET_FIRST_USER   = Player(0)         // get first player when player 1 is empty
        integer GAME_TIME_SECOND = 0                 //automatic updates game seconds
        integer GAME_TIME_MINUTE = 0                 //automatic updates game mintues
        rect    bj_worldBounds                       //GetWorldBounds()
        string  array PlayerColor [15]
        string  array PlayerName [15]
        string  array PlayerColorName [15]
//System's options===================================================
        constant real   P80         = .012500000 //80 period
        constant real   P64         = .015625000 //64 period
        constant real   P40         = .025000000 //40 period
        constant real   P32         = .031250000 //32 period
        constant real   PRT         = P40 //Frame Runtime, Please don't change it' if you don't know
        
        private constant real   FUC_PERIOD  = P40 //FadeUnitColor API period!
        private constant real   KBS_PERIOD  = P32 //AddKnoc API period!
        private constant real   ALT_PERIOD  = P40 //AddLightningTrack API period!
        private constant real   DLE_PERIOD  = P32 //DestroyLightningEx API period!
//Temporary variable===================================================
        real            TempX       = 0        
        real            TempY       = 0        
        integer         TempInt     = 0
        integer         TempInt2    = 0
        real            TempReal    = 0
        real            TempReal2   = 0        
        unit            TempUnit    = null
        unit            TempUnit2   = null
        group           TempGroup   = CreateGroup()
        item            TempItem    = null             
        rect            TempRect    = null             
        effect          TempEffect  = null             
        string          TempString  = null             
        player          TempPlayer  = null                     
        boolean         TempBoolean = false
        boolexpr        True        = null //useful for boolexpr
        constant player Creep       = Player(PLAYER_NEUTRAL_AGGRESSIVE) //quick var
        constant player Neutral     = Player(PLAYER_NEUTRAL_PASSIVE) //quick var
        constant hashtable       ht = InitHashtable() //please not break it!
endglobals
// runtextmacro RuntimeInitializerRed() /*not safe: Infinity times!*/
//! runtextmacro RuntimeInitializerBlue() /*safe: Overflow than 256 times!*/
//Object API===========================================================

    function AddEvent takes trigger trig, playerunitevent whichEvent returns nothing
        local integer index = 0
        loop
            call TriggerRegisterPlayerUnitEvent(trig, Player(index), whichEvent, null)
            set index = index + 1
            exitwhen index == bj_MAX_PLAYER_SLOTS
        endloop
    endfunction
       
    function SimError takes player ForPlayer, string msg returns nothing
        set msg = "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n|cffffcc00" + msg + "|r"
        if (GetLocalPlayer() == ForPlayer) then
            call ClearTextMessages()
            call DisplayTimedTextToPlayer( ForPlayer, 0.52, 0.96, 2.00, msg )
            call StartSound( Error )
        endif
    endfunction
       
    function HideUnitInMap takes unit u returns nothing
        call UnitSetUsesAltIcon(u, true)
    endfunction

    function ShowUnitInMap takes unit u returns nothing
        call UnitSetUsesAltIcon(u, false)
    endfunction
   
    function HideUnitInEnemy takes unit u returns nothing
        call UnitSetUsesAltIcon(u, true)
        if IsPlayerAlly(GetOwningPlayer(u), GetLocalPlayer()) then
            call UnitSetUsesAltIcon(u, false)
        endif
    endfunction
       
    function PrintPlayer takes player p, string s, real d returns nothing
        if d == 0 then
            call DisplayTextToPlayer(p, 0, 0, s)
        else
            call DisplayTimedTextToPlayer(p, 0, 0, d, s)
        endif
    endfunction
       
    function Print takes string s, real d returns nothing
        if d == 0 then
            call DisplayTextToPlayer(GetLocalPlayer(), 0, 0, s)
        else
            call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, d, s)
        endif
    endfunction
       
    function PlaySoundEx takes unit u, string path returns nothing
        local sound s = CreateSound(path, false, true, true, 12700, 12700, "DefaultEAXON")
        call SetSoundVolume(s, SOUND_VOLUME)
        set SOUND_VOLUME = 127
        call SetSoundChannel(s, 5)
        call SetSoundPitch(s, 1.00001)
                    //3D Sound Mode
        call SetSoundDistances(s, 600, 10000)
        call SetSoundDistanceCutoff(s, 3000)
        call SetSoundConeAngles(s, 0, 0, 127)
        call AttachSoundToUnit(s, u)
        call StartSound(s)
        if HaveSavedBoolean(ht, 0x906120, StringHash(path)) then
            call KillSoundWhenDone(s)
        else
            call SaveBoolean(ht, 0x906120, StringHash(path), true)
        endif
        set s = null
    endfunction
       
    function PlaySoundAll takes string path returns nothing
        local sound sc = CreateSound(path, false, false, false, 10, 10, "DefaultEAXON")
        call SetSoundVolume(sc, SOUND_VOLUME)
        set SOUND_VOLUME = 127
        call StartSound(sc)
        if HaveSavedBoolean(ht, 0x906122, StringHash(path)) then
            call KillSoundWhenDone(sc)
        else
            call SaveBoolean(ht, 0x906122, StringHash(path), true)
        endif
        set sc = null
    endfunction
       
    function PlaySoundPlayer takes player p, string path returns nothing
        local sound sc = CreateSound(path, false, false, false, 10, 10, "DefaultEAXON")
        call SetSoundVolume(sc, 0)
        if GetLocalPlayer() == p then
            call SetSoundVolume(sc, SOUND_VOLUME)
        endif
        call StartSound(sc)
        set SOUND_VOLUME = 127
        if HaveSavedBoolean(ht, 0x906122, StringHash(path)) then
            call KillSoundWhenDone(sc)
        else
            call SaveBoolean(ht, 0x906122, StringHash(path), true)
        endif
        set sc = null
    endfunction
       
    function CreateTextTagXY takes string s, real x, real y returns texttag
        local texttag t = CreateTextTag()
        call SetTextTagText(t, s,FONT_SIZE * 0.023 / 10)
set FONT_SIZE = 10.
        call SetTextTagPos(t, x, y, 0)
        call SetTextTagColor(t, 255, 255, 255, 255)
        call SetTextTagVelocity(t, 0, 0.036)
        call SetTextTagPermanent(t, false)
        call SetTextTagLifespan(t, 2.00)
        call SetTextTagFadepoint(t, 1.00)
        return t
    endfunction
       
//System API===========================================================
    static if BLOCK_DAMAGE_API then
    function BlockDamage takes unit u, real amount returns nothing
        local real damage = GetEventDamage()
        if damage <=0 then
            return
        endif
        if amount>=damage then
            set damage = GetWidgetLife(u) + damage
        else
            set damage = GetWidgetLife(u) + amount
        endif
   
        call SetWidgetLife(u, damage)
   
        if GetWidgetLife(u) < damage then
            call UnitAddAbility(u, 0x64707276)
            call SetWidgetLife(u, damage)
   
            set UnitStorageMax = UnitStorageMax + 1
            set UnitStorage[UnitStorageMax] = u
            call ResumeTimer(BDTimer)
        endif
    endfunction
    endif
    
    function UnitDamageTargetEx takes unit u, widget t, real d, boolean attack, boolean ranged, attacktype attackType, damagetype damageType, weapontype weaponType returns boolean
        local boolean b
        set stack = stack + 1
        set dType[stack] = damageType
        set b = UnitDamageTarget(u, t, d, attack, ranged, attackType, damageType, null)
        set stack = stack - 1
        return b
    endfunction
    
    function IsDamagePhysical takes nothing returns boolean
        return dType[stack]!=DAMAGE_TYPE_MAGIC and dType[stack]!=DAMAGE_TYPE_UNIVERSAL
    endfunction
    
    function IsDamageMagical takes nothing returns boolean
        return dType[stack]==DAMAGE_TYPE_MAGIC
    endfunction
    
    function IsDamagePure takes nothing returns boolean
        return dType[stack]==DAMAGE_TYPE_UNIVERSAL
    endfunction
    
    function DamagePhysical takes unit u, unit t, real d returns boolean
        return UnitDamageTargetEx(u, t, d, true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL, null)
    endfunction
    
    function DamageMagical takes unit u, unit t, real d returns boolean
        return UnitDamageTargetEx(u, t, d, true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_MAGIC, null)
    endfunction
    
    function DamagePure takes unit u, unit t, real d returns boolean
        return UnitDamageTargetEx(u, t, d, true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_UNIVERSAL, null)
    endfunction
    
    //! runtextmacro KillTreeRadius()
    function KillTreeRadius takes real x, real y, real radius returns nothing
        local rect r = Rect(x - radius, y - radius, x + radius, y + radius)
        set X = x
        set Y = y
        set R = radius * radius
        call EnumDestructablesInRect(r, null, function DestroyTreesInCircleEnum)
        call RemoveRect(r)
        set r = null
    endfunction

    function CineFilter takes string texture, integer r, integer g, integer b, real dur, boolean on returns nothing
        //! runtextmacro CineFilter()
    endfunction
       
    function AddSpecialEffectZ takes string path, real x, real y, real z returns effect
        local destructable d = CreateDestructableZ( 'OTip', x, y, z, 0.00, 1, 0 )
        set bj_lastCreatedEffect = AddSpecialEffect( path, x, y )
        call RemoveDestructable( d )
        set d = null
        return bj_lastCreatedEffect
    endfunction

    function GetPlayerColorName takes player p returns string
        return PlayerColorName[GetPlayerId(p)]
    endfunction
       
    function GetPlayerColorString takes player p returns string
        return PlayerColor[GetPlayerId(p)]
    endfunction
       
    function Preload_Unit takes integer id returns nothing
        call RemoveUnit(CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE), id, 0, 0, 270))
    endfunction
       
    function Preload_Item takes integer id returns nothing
        call RemoveItem(CreateItem(id, 0, 0))
    endfunction
       
    function Preload_Ability takes integer id returns nothing
        local unit u = CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE), 'nzin', 0, 0, 270)
        call UnitAddAbility(u, id)
        call UnitRemoveAbility(u,id)
        call RemoveUnit(u)
        set u = null
    endfunction
       
    function Preload_Sound takes unit u, string path returns nothing
        local sound s = CreateSound(path, false, true, true, 12700, 12700, "")
        call SetSoundVolume(s, 100)
        call AttachSoundToUnit(s, u)
        call StartSound(s)
        call KillSoundWhenDone(s)
    endfunction

//ITEMS API============================================================
static if ITEM_UNSAME then
    function SetInitItemGroup takes integer i,string g returns nothing
        call SaveStr(ht,i,0x5128,g)
        //ex: call SetInitItemGroup('I00O',"Armor")
    endfunction
    endif
static if ITEM_UNDROPPABLE then
    function Undroppable takes integer itemid, real dur returns nothing
        set untimer[uncount] = dur
        set untype[uncount] = itemid
        set Boolean[uncount] = true
        set uncount = (uncount+1)
    endfunction
    endif
    function InventoryIsFull takes unit whichUnit returns boolean
        local integer index = 0
        local integer count = 0
        local integer size = UnitInventorySize(whichUnit)
        loop
            if UnitItemInSlot(whichUnit, index)==null then
                return false
            endif
            set index = index + 1
            exitwhen index == size
        endloop
        return true
    endfunction
   
    function GetItem takes unit whichUnit, integer itemId returns item
        local integer index = 0
        local item indexItem = null
        loop
            set indexItem = UnitItemInSlot(whichUnit, index)
            if (indexItem != null) and (GetItemTypeId(indexItem) == itemId) then
                return indexItem
            endif
            set index = index + 1
            exitwhen index >= bj_MAX_INVENTORY
        endloop
        set indexItem = null
        return null
    endfunction
   
    function HaveItem takes unit whichUnit, integer itemId returns boolean
        local integer index = 0
        local item indexItem = null
        local boolean b = false
        loop
            set indexItem = UnitItemInSlot(whichUnit, index)
            if (indexItem != null) and (GetItemTypeId(indexItem) == itemId) then
                set indexItem = null
                set b = true
            endif
            set index = index + 1
            exitwhen index >= bj_MAX_INVENTORY
        endloop
   
        set indexItem = null
        return b
    endfunction
       
//Execute API==========================================================

    //! runtextmacro APIExecute()
function AddMP takes unit u, real r returns nothing
        call AddMPexe.execute(u,r)
        set u=null
    endfunction

function AddHP takes unit u, real r returns nothing
        call AddHPexe.execute(u,r)
        set u=null
    endfunction

    function DestroyEffectTimer takes effect a, real time returns nothing
        call destroyeffectaexe.execute(a,time)
        set a=null
    endfunction
   
    function RemoveUnitTimer takes unit u, real time returns nothing
        call RemoveUnitTimerexe.execute(u,time)
        set u = null
    endfunction
   
    function PauseUnitTimer takes unit u, real time returns nothing
        call PauseUnitexe.execute(u,time)
        set u = null
    endfunction
   
    function FreezeAnimationTimer takes unit u, real time returns nothing
        call FreezeAnimationexe.execute(u,time)
        set u = null
    endfunction
       
    function PingMinimapTimer takes player p, real time, real x, real y, real duration, integer red, integer green, integer blue, boolean extraEffects returns nothing
        call PingMinimapExe.execute(p,time,x,y,duration,red,green,blue,extraEffects)
        set p = null
    endfunction
       
//Calculation API======================================================
       
    function GetChance takes real r returns boolean
        return r>=GetRandomInt(0,100)
    endfunction
    
    function GetElapsedGameTime takes nothing returns real
        return TimerGetElapsed(gameTime)
    endfunction
    
    function IsGameDay takes nothing returns boolean
        if(GetTimeOfDay() > 6.00 and GetTimeOfDay() < 18.00)then
            return true
        else
            return false
        endif
    endfunction
       
    function GetPID takes player whichPlayer returns integer
        return GetPlayerId(whichPlayer)
    endfunction
       
    function GetUID takes unit u returns integer
        return GetPlayerId(GetOwningPlayer(u))
    endfunction
       
    function RealSetPercent takes real Real, real Percent returns real//set percent to real
        return Real * (Percent / 100)//(Real / 100.) * Percent
    endfunction
         
    function GetPZ takes real x, real y returns real
        call MoveLocation(SetUnitZLoc, x, y)
        return GetLocationZ(SetUnitZLoc)
    endfunction
       
    function GetAB takes real x1, real y1, real x2, real y2 returns real
        return bj_RADTODEG * Atan2(y2 - y1, x2 - x1)
    endfunction
       
    function GetDB takes real x1, real y1, real x2, real y2 returns real
        local real dx = x2 - x1
        local real dy = y2 - y1
        return SquareRoot(dx * dx + dy * dy)
    endfunction
       
    function GetPPX takes real x, real dist, real angle returns real
        return x + dist * Cos(angle * bj_DEGTORAD)
    endfunction
       
    function GetPPY takes real y, real dist, real angle returns real
        return y + dist * Sin(angle * bj_DEGTORAD)
    endfunction

    function GetUnitZ takes unit u returns real
        call MoveLocation(SetUnitZLoc, GetUnitX(u), GetUnitY(u))
        return GetLocationZ(SetUnitZLoc) + GetUnitFlyHeight(u)
    endfunction
       
    function SetUnitZ takes unit u, real h returns nothing
        call SetUnitFlyHeight( u , h, 0. )
    endfunction
    
    function GetUnitCollision takes unit u returns real
        local real l = 0
        local real h = 300
        local real m = 150
        local real nm = 0
        local real x = GetUnitX(u)
        local real y = GetUnitY(u)
        loop
            if (IsUnitInRangeXY(u, x+m, y, 0)) then
                set l = m
            else
                set h = m
            endif
            set nm = (l+h)/2
            exitwhen nm+.001 >  m and nm-.001 < m
            set m = nm
        endloop
        return R2I(m*10)/10.
    endfunction
    
//Player API===========================================================

    function IsPlayerOnline takes player p returns boolean
        return GetPlayerSlotState(p) == PLAYER_SLOT_STATE_PLAYING and GetPlayerController(p)==MAP_CONTROL_USER
    endfunction
   
    function IsPlayerLeft takes player p returns boolean
        return GetPlayerSlotState(p) == PLAYER_SLOT_STATE_LEFT and GetPlayerController(p)==MAP_CONTROL_USER
    endfunction
   
    function IsPlayerEmpty takes player p returns boolean
        return (GetPlayerSlotState(p) == PLAYER_SLOT_STATE_EMPTY)
    endfunction

    function GetFristPlayer takes nothing returns player
        local integer i = 0
        loop
            exitwhen i ==12
            if GetPlayerSlotState(Player(i)) == PLAYER_SLOT_STATE_PLAYING and GetPlayerController(Player(i))==MAP_CONTROL_USER then
                return Player(i)
            endif
            set i = i + 1
        endloop
        return null
    endfunction
       
//Units API============================================================
       
    function CreateDummy takes player owner, integer unitid, real x, real y, real face, real dur returns unit
        local unit u = CreateUnit(owner, unitid, x, y, face)
        call SetUnitPathing(u, false)
        call SetUnitX(u, x)
        call SetUnitY(u, y)
        call UnitApplyTimedLife(u, 'BTLF', dur)
        return u
    endfunction
       
    function CreateUnitWithoutShadow takes player id, integer unitid, real x, real y, real face returns unit
        local image i = CreateImage("Textures\\white.blp", 1, 1, 0, 0, 0, 0, 1, 1, 0, 3)
        call DestroyImage(i) // destroy the dummy.
        set TempUnit = CreateUnit(id, unitid, x, y, face)
        call DestroyImage(i) // destroy the shadow of the unit
        call CreateImage("Textures\\white.blp", 1, 1, 0, 0, 0, 0, 1, 1, 0, 3) // this creates the new shadow for the unit, note that i dont need to overwrite "i" as the id this image will get is predictable
        call SetImageRenderAlways(i, false) // Hides the shadow
        call SetImageColor(i, 0, 0, 0, 0) // Makes the shadow invisible
        // no need to null "i", as images dont use ref-counting
        return TempUnit
    endfunction

    function RemoveUnitEx takes unit c returns nothing
        call UnitApplyTimedLife(c, 'BTLF', 0.01)
    endfunction

function RemoveUnitDelay takes unit c returns nothing
        call UnitApplyTimedLife(c, 'BTLF', 0.50)
    endfunction

    function ResetUnitVertexColor takes unit u returns nothing
        call SetUnitVertexColor(u, 255, 255, 255,255)
    endfunction

    function SetMaxHP takes unit u, integer v returns boolean
local integer i = 0x41776870
        local integer c = v - R2I(GetUnitState(u,UNIT_STATE_MAX_LIFE))
        //! runtextmacro MaxStateAPI()
return true
    endfunction

function SetMaxMP takes unit u, integer v returns boolean
local integer i = 0x41776d70
        local integer c = v - R2I(GetUnitState(u,UNIT_STATE_MAX_MANA))
        //! runtextmacro MaxStateAPI()
return true
    endfunction

function AddMaxHP takes unit u, integer i returns nothing
call SetMaxHP(u, i + R2I(GetUnitState(u,UNIT_STATE_MAX_LIFE)))
endfunction

function AddMaxMP takes unit u, integer i returns nothing
call SetMaxMP(u, i + R2I(GetUnitState(u,UNIT_STATE_MAX_MANA)))
endfunction

    function AddHPercent takes unit whichUnit, real percent returns nothing
        call SetUnitState(whichUnit, UNIT_STATE_LIFE, GetUnitState(whichUnit, UNIT_STATE_LIFE) + (GetUnitState(whichUnit, UNIT_STATE_MAX_LIFE) * (percent * 0.01)))
    endfunction
       
    function AddMPercent takes unit whichUnit, real percent returns nothing
        call SetUnitState(whichUnit, UNIT_STATE_MANA, GetUnitState(whichUnit, UNIT_STATE_MANA) + (GetUnitState(whichUnit, UNIT_STATE_MAX_MANA) * (percent * 0.01)))
    endfunction
       
    function ResetMS takes unit whichUnit returns nothing
        call SetUnitMoveSpeed(whichUnit, GetUnitDefaultMoveSpeed(whichUnit))
    endfunction
       
    function GetMS takes unit whichUnit returns real
        return GetUnitMoveSpeed(whichUnit)
    endfunction
       
    function GetUnitHPercent takes unit whichUnit returns real
        local real maxValue = GetUnitState(whichUnit, UNIT_STATE_MAX_LIFE)
        if (whichUnit == null) or (maxValue == 0) then
            return 0.0
        endif
        return GetUnitState(whichUnit, UNIT_STATE_LIFE) / maxValue * 100.0
    endfunction

    function GetUnitMPercent takes unit whichUnit returns real
        local real maxValue = GetUnitState(whichUnit, UNIT_STATE_MAX_MANA)
        if (whichUnit == null) or (maxValue == 0) then
            return 0.0
        endif
        return GetUnitState(whichUnit, UNIT_STATE_MANA) / maxValue * 100.0
    endfunction
       
    function AddGoldInUnit takes player whichPlayer, integer value, unit whichUnit returns nothing
        //! runtextmacro AddGoldInUnit()
    endfunction

    function AddHeroEXP takes unit whichHero, integer xpToAdd returns nothing
        //! runtextmacro AddHeroEXP()
    endfunction
       
    function GetGold takes player p returns integer
        return GetPlayerState(p, PLAYER_STATE_RESOURCE_GOLD)
    endfunction
       
    function AddGold takes player p, integer r returns nothing
        call SetPlayerState(p, PLAYER_STATE_RESOURCE_GOLD, GetGold(p) + r)
        call SetPlayerState(p, PLAYER_STATE_GOLD_GATHERED, GetPlayerState(p, PLAYER_STATE_GOLD_GATHERED) + r)
    endfunction
       
    function GetLumber takes player p returns integer
        return GetPlayerState(p, PLAYER_STATE_RESOURCE_LUMBER)
    endfunction
       
    function AddLumber takes player p, integer r returns nothing
        call SetPlayerState(p, PLAYER_STATE_RESOURCE_LUMBER, GetGold(p) + r)
        call SetPlayerState(p, PLAYER_STATE_LUMBER_GATHERED, GetPlayerState(p, PLAYER_STATE_LUMBER_GATHERED) + r)
    endfunction
       
    function SetFoodUsed takes player p, integer r returns nothing
        call SetPlayerState(p, PLAYER_STATE_RESOURCE_FOOD_USED, r)
    endfunction
    
    function ResetHP takes unit Unit returns nothing
        call SetUnitState(Unit, UNIT_STATE_LIFE, GetUnitState(Unit, UNIT_STATE_MAX_LIFE))
    endfunction
           
    function ResetMP takes unit Unit returns nothing
        call SetUnitState(Unit, UNIT_STATE_MANA, GetUnitState(Unit, UNIT_STATE_MAX_MANA))
    endfunction
           
    function AddAbility takes unit u, integer i returns nothing
        call UnitAddAbility(u, i)
        call UnitMakeAbilityPermanent(u, true, i)
    endfunction
       
    function ResetAbility takes unit a, integer id returns nothing
        local integer lv = GetUnitAbilityLevel(a, id)
        call UnitRemoveAbility(a, id)
        call UnitAddAbility(a, id)
        call SetUnitAbilityLevel(a, id, lv)
    endfunction
    
    function UnitRemoveAloc takes unit u returns nothing
        call UnitRemoveAbility(u, 'Aloc')
        call ShowUnit(u, false)
        call ShowUnit(u, true)
    endfunction
           
    function ResetOrder takes unit Unit returns nothing
        call PauseUnit(Unit, true)
        call IssueImmediateOrder(Unit, "stop")
        call PauseUnit(Unit, false)
    endfunction
           
    function HaveAbility takes unit u, integer i returns boolean
        return GetUnitAbilityLevel(u, i) > 0
    endfunction
           
    function DisableUnitMovement takes unit u returns nothing
        call SetUnitPropWindow(u, 0)
    endfunction
     
    function EnableUnitMovement takes unit u returns nothing
        call SetUnitPropWindow(u, GetUnitDefaultPropWindow(u))
    endfunction
           
    // To make the dummy face a 2 dimensional orientation instantly:
    function SetDummyFacing takes unit u, real angle returns nothing
        call SetUnitLookAt(u, "Bone_Head", u, Cos(angle) * 1000000., Sin(angle) * 1000000., 0.)
    endfunction
    // To make the dummy face a 3 dimensional orientation instantly:
    function SetDummyOrientation takes unit u, real x, real y, real z returns nothing
        call SetUnitLookAt(u, "Bone_Head", u, x * 1000000., y * 1000000., z * 1000000.)
    endfunction
    //To make the dummy always face a particular unit, for homing missiles:
    function SetDummyHomingTarget takes unit u, unit target returns nothing
        call SetUnitLookAt(u, "Bone_Head", target, 0., 0., 0.)
    endfunction
    //! runtextmacro UnitPositionChecking()
    function IsUnitInFront takes unit b, unit a returns boolean//b = infront, a = source
        return Checker(b,a,30,330,135,225) == 1
    endfunction

    function IsUnitBehind takes unit b, unit a returns boolean //b = behind, a = source
        return Checker(b,a,30,330,135,225) == 2
    endfunction

    function IsUnitAtSideRight takes unit b, unit a returns boolean//b = atside, a = source
        return Checker(b,a,30,330,135,225) == 3
    endfunction

    function IsUnitAtSideLeft takes unit b, unit a returns boolean//b = atside, a = source
        return Checker(b,a,30,330,135,225) == 4
    endfunction
    
    function IsUnitSpellImmune takes unit u returns boolean
        return IsUnitType(u, UNIT_TYPE_MAGIC_IMMUNE)
    endfunction
       
    function IsUnitSpellResistant takes unit u returns boolean
        if IsUnitType(u, UNIT_TYPE_HERO) then
            return true //unit is a hero
        elseif IsUnitType(u, UNIT_TYPE_RESISTANT) then
            return true //unit has a resistant - skin - type ability
        elseif GetPlayerId(GetOwningPlayer(u)) > 11 and GetUnitLevel(u)>=10 then
            return true //unit is a high - level creep lv 10
        endif
        return false
    endfunction
    
    function IsUnitHero takes unit u returns boolean
        return IsUnitType(u, UNIT_TYPE_HERO)
    endfunction
       
    function IsUnitFriend takes unit c, unit v returns boolean
        return IsUnitAlly(c,GetOwningPlayer(v))
    endfunction
       
    function IsUnitDead takes unit u returns boolean
        //return IsUnitType( u, UNIT_TYPE_DEAD)
        return GetUnitTypeId(u)<1 or IsUnitType(u,UNIT_TYPE_DEAD)==true
    endfunction
    
    function AddUnitDead takes unit u returns nothing
        call UnitAddType(u, UNIT_TYPE_DEAD)
    endfunction
       
    //! runtextmacro FadeUnitColor()
    function FadeUnitColor takes unit u, integer r, integer g, integer b, integer a, integer nr, integer ng, integer nb, integer na, real dur returns nothing
        local fucdata this = fucdata.create()
        local integer delay = R2I(dur / FUC_PERIOD) //5 / 0, 015625 = 320
        call SetUnitVertexColor(u, r, g, b, a)
        set this.oR = I2R(r)
        set this.oG = I2R(g)
        set this.oB = I2R(b)
        set this.oA = I2R(a)
        set this.gR = (nr - r) / I2R(delay)//this red
        set this.gB = (ng - g) / I2R(delay)//this green
        set this.gG = (nb - b) / I2R(delay)//this blue
        set this.gA = (na - a) / I2R(delay)//this alpha
        set this.u = u
        set this.dur = dur
        call addRT(this,FUC_PERIOD, true,function FUCLooper)
    endfunction
    
//Group API============================================================

    //! runtextmacro EnumGroupAPI()
    function GroupRefresh takes group g returns nothing
        set Flag = true
        set Refr = g
        call ForGroup(Refr, function AddEx)
        if Flag then
            call GroupClear(g)
        endif
    endfunction
    
    function EnumGroup takes group g, real x, real y, real r returns nothing
        set EGX = x
        set EGY = y
        set EGR = r
        call GroupEnumUnitsInRange (g, x, y, r + MAX_COLLISION_SIZE,EGFilter)
    endfunction
    
        //! runtextmacro GroupRandomUnitAPI()
    function GroupRandomUnit takes group g returns unit
        set GPRi = 0
        set GPRu = null
        call ForGroup(g, function EnumG)
        return GPRu
    endfunction
    
        //! runtextmacro CountUnit()
    function CountUnit takes group g returns integer
        local integer c = 0
        local unit e
        set bj_groupAddGroupDest = ENUM_GROUP
        call ForGroup(g, function GroupAddGroupEnumIsLive)
       
        loop
            set e = FirstOfGroup(ENUM_GROUP)
            exitwhen e==null
            if not UnitAddType(e, UNIT_TYPE_DEAD) then
                set c = c + 1
            endif
            call GroupRemoveUnit(ENUM_GROUP, e)
        endloop
        return c
    endfunction
    
    function GetNearestUnit takes real x, real y, real distance, boolexpr exp returns unit
        local unit e = null
        local real dis = distance
        local real var = 0
        local group g = CreateGroup()
        call GroupEnumUnitsInRange(g, x, y, distance, exp)
            
        loop
            set e = FirstOfGroup(g)
            exitwhen e==null
            set var = SquareRoot((GetUnitX(e) - x) * (GetUnitX(e) - x) + (GetUnitY(e) - y) * (GetUnitY(e) - y))
            if ( var < dis ) then
                set dis = var
                set ne = e
            endif
            call GroupRemoveUnit(g, e)
        endloop
            
        call DestroyGroup(g)
        set g = null
        return ne
    endfunction
    
//Lightning API========================================================
//Lightning Codes (Thanks to Flare):
//     ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
//          "CLPB" - Chain Lightning Primary
//          "CLSB" - Chain Lightning Secondary
//          "DRAB" - Drain
//          "DRAL" - Drain Life
//          "DRAM" - Drain mana
//          "AFOD" - Finger of Death
//          "FORK" - Forked Lightning
//          "HWPB" - Healing Wave Primary
//          "HWSB" - Healing Wave Secondary
//          "CHIM" - Lightning Attack
//          "LEAS" - Magic Leash
//          "MBUR" - Mana Burn
//          "MFPB" - Mana Flare
//          "SPLK" - Spirit Link
    //! runtextmacro DestroyLightningEx()
    function DestroyLightningEx takes lightning g, real e returns nothing
        local DLEXs this = DLEXs.create()
        local integer id = GetHandleId(g)
        set this.light = g
        if LoadReal(ht, id, 5) >0 then
        set this.from = LoadReal(ht, id,4)//this is alpha
        else
        set this.from = 1.00 //when don't set color. return default
        endif
        set this.delay = e
        set this.when = this.from / (e / DLE_PERIOD)
        //call SetFrameData(this)
        call addRT(this,DLE_PERIOD,true,function DLEX)
    endfunction
    
    //! runtextmacro AddLightningTrackLoopAPI()
    function AddLightningTrack takes string raw, unit u, unit e, real r, real g, real b, real a, real dur returns nothing
        local Lightdata this = Lightdata.create()
        local real x1 = GetUnitX(u)
        local real y1 = GetUnitY(u)
        local real x2 = GetUnitX(e)
        local real y2 = GetUnitY(e)
        set this.u = u
        set this.e = e
        set this.dur = dur
        set this.light = AddLightningEx(raw,true,x1,y1,GetUnitZ(u)+LIGHTNING_ZOFFSET,x2,y2,GetUnitZ(e)+LIGHTNING_ZOFFSET)
        call SetLightningColor(this.light, r, g, b, a)
        call addRT(this,ALT_PERIOD, true,function ALooper)
    endfunction
      
    function AddLightningInUnit takes string raw, unit u, real z returns lightning
        local real x = GetUnitX(u)
        local real y = GetUnitY(u)
        return AddLightningEx(raw, true, x, y, GetUnitZ(u), x, y, z + LIGHTNING_ZOFFSET)
    endfunction
//Terrain API==========================================================

    //! runtextmacro ReplaceTerrain()
    function ReplaceTerrainTypeEx takes integer oldTerrain, integer newTerrain, rect whichRect returns nothing
        call SubFunctionA.execute(oldTerrain, newTerrain, GetRectMinX(whichRect), GetRectMaxX(whichRect), GetRectMinY(whichRect), GetRectMaxY(whichRect))
    endfunction

    function ReplaceGlobalTerrain takes integer oldTerrain, integer newTerrain returns nothing
        call SubFunctionA.execute(oldTerrain, newTerrain, WBMiX, WBMaX, WBMiY, WBMaY)
    endfunction
   
    function ReplaceGlobalTerrainReversed takes integer newTerrain, integer oldTerrain returns nothing
        call SubFunctionA.execute(oldTerrain, newTerrain, WBMiX, WBMaX, WBMiY, WBMaY)
    endfunction
    
    //! runtextmacro IsTerrainWalkable()
    function IsTerrainWalkable takes real x2, real y2 returns boolean
        local real X =0
        local real Y =0
        call MoveRectTo(Find, x2, y2)
        call EnumItemsInRect(Find , null, function HideItem)
        call SetItemPosition(ItemChecker, x2, y2)
        set X = GetItemX(ItemChecker)
        set Y = GetItemY(ItemChecker)
        call SetItemVisible(ItemChecker, false)
        loop
            exitwhen HidMax <= 0
            set HidMax = HidMax - 1
            call SetItemVisible(Hid[HidMax], true)
            set Hid[HidMax] = null
        endloop
        return (X - x2) * (X - x2) + (Y - y2) * (Y - y2) <= MAX_RANGE * MAX_RANGE and not IsTerrainPathable(x2, y2, PATHING_TYPE_WALKABILITY)
    endfunction
   
    function IsTerrainDeepWater takes real x, real y returns boolean
        return not IsTerrainPathable(x, y, PATHING_TYPE_FLOATABILITY) and IsTerrainPathable(x, y, PATHING_TYPE_WALKABILITY)
    endfunction
   
    function IsTerrainShallowWater takes real x, real y returns boolean
        return not IsTerrainPathable(x, y, PATHING_TYPE_FLOATABILITY) and not IsTerrainPathable(x, y, PATHING_TYPE_WALKABILITY) and IsTerrainPathable(x, y, PATHING_TYPE_BUILDABILITY)
    endfunction
   
    function IsTerrainLand takes real x, real y returns boolean
        return IsTerrainPathable(x, y, PATHING_TYPE_FLOATABILITY)
    endfunction

    function IsTerrainPlatform takes real x, real y returns boolean
        return not IsTerrainPathable(x, y, PATHING_TYPE_FLOATABILITY) and not IsTerrainPathable(x, y, PATHING_TYPE_WALKABILITY) and not IsTerrainPathable(x, y, PATHING_TYPE_BUILDABILITY)
    endfunction

function IsRegionInRect takes region wg, rect wr returns boolean
        return IsPointInRegion(wg, GetRectCenterX(wr), GetRectCenterY(wr))
    endfunction
    
    function IsUnitInRect takes unit u , rect r returns boolean
        return ( GetUnitX ( u ) > GetRectMinX ( r ) - 32 and GetUnitX ( u ) < GetRectMaxX ( r ) + 32 ) and ( GetUnitY ( u ) > GetRectMinY ( r ) - 32 and GetUnitY ( u ) < GetRectMaxY ( r ) + 32 )
    endfunction
//Knockback API========================================================
//! runtextmacro AddKnocAPI()
    function IsKnoc takes unit u returns boolean
        local kdata this = LoadInteger(ht,GetHandleId(u),0x281)//knoc
        if this.u == u then
        return true
        endif
        return false
    endfunction
    
    function BreaKnoc takes unit u returns boolean
        local kdata this = LoadInteger(ht,GetHandleId(u),0x281)//knoc
        if this.u == u then
        set this.stop = true
        return true
        endif
        return false
    endfunction
    
    function AddKnoc takes unit u, real dis, real dur, real fa, boolean AllowMove, boolean KillTree returns nothing
        local kdata this = kdata.create()
        call SaveInteger(ht, GetHandleId(u),0x281,this)
        if NOT_KNOC_SFX then
        set this.NSFX = NOT_KNOC_SFX
        set NOT_KNOC_SFX = false
        endif
        if CUS_KNOC_SFX !=null then
        set this.CSFX = CUS_KNOC_SFX
        set CUS_KNOC_SFX = null
        endif
        
        set this.stop = false
        set this.amove = AllowMove
        set this.ktree = KillTree
        
        set this.fa = fa * bj_DEGTORAD
        set this.sp = (dis / (dur / KBS_PERIOD)) //this is speed
        set this.u = u
        set this.dur = dur
        static if ALLOW_STACK_UNIT then
            if not AllowMove then
                call SetUnitPathing(this.u, false)
            endif
        endif
        call addRT(this, KBS_PERIOD, true, function KnocLooper)
    endfunction
    
//System Timer - Runtime===============================================
//! textmacro RuntimeInitializerRed
    function addRT takes integer i, real timeout, boolean periodic, code func returns nothing
        local trigger t = CreateTrigger()
        local integer id = GetHandleId(t)
        call SaveInteger(ht, id, 0, i)
        call SaveReal(ht, id, 1, timeout)
        call TriggerRegisterTimerEvent(t, timeout, periodic)
        call TriggerAddCondition(t, Condition( func))
        set t = null
    endfunction
    
    function getRT takes nothing returns integer
        return LoadInteger(ht, GetHandleId(GetTriggeringTrigger()), 0)
    endfunction
    
    function countRT takes nothing returns real
        local trigger t = GetTriggeringTrigger()
        local real result = I2R(GetTriggerEvalCount(t)) * LoadReal(ht, GetHandleId(t), 1)
        set t = null
        return result
    endfunction
    
    function breakRT takes nothing returns nothing
        local trigger t = GetTriggeringTrigger()
        call FlushChildHashtable(ht, GetHandleId(t))
        call DisableTrigger(t)
        set t = null
    endfunction
//! endtextmacro
//! textmacro RuntimeInitializerBlue 
    function addRT takes integer i, real timeout, boolean periodic, code func returns nothing
        local timer t = CreateTimer()
        local integer id = GetHandleId(t)
        if t == null then
        call BJDebugMsg(SCOPE_PREFIX + "Warning: Overflow runtime blue")
        return
        endif
        call SaveInteger(ht, id, 0, i)
        call SaveInteger(ht, id, 2, 0)//count <<
        call SaveReal(ht, id, 1, timeout)
        call TimerStart(t,timeout,periodic,func)
        set t = null
    endfunction
    
    function getRT takes nothing returns integer
        local integer id = GetHandleId(GetExpiredTimer())
        local integer i = LoadInteger(ht,id, 0)
        call SaveInteger(ht,id,2,LoadInteger(ht,id,2)+1)
        return i
    endfunction
    
    function countRT takes nothing returns real
        local integer id = GetHandleId(GetExpiredTimer())
        local real result = I2R(LoadInteger(ht,id,2)) * LoadReal(ht,id, 1)
        return result
    endfunction
    
    function breakRT takes nothing returns nothing
        local timer t=GetExpiredTimer()
        call PauseTimer(t)
        call FlushChildHashtable(ht, GetHandleId(t))
        call DestroyTimer(t)
        set t = null
    endfunction
//! endtextmacro
//System Timer - Frame32===============================================
//! textmacro FrameInitializer
library ExortFrame initializer int
    interface frame
    method update takes nothing returns boolean
    endinterface
    globals
        private integer nF = 0
        private frame array nR
    endglobals

    function SetFrameData takes frame fr returns nothing
        set nR[nF] = fr
        set nF = nF + 1
    endfunction
    
    public module begin
        private integer tick = 0 //per in 1/32
        private integer tack = 0//per in begin
        method update takes nothing returns boolean
            set this.tick = this.tick + 1
        endmodule
        public module end
        endmethod
    endmodule
    private function exe takes nothing returns nothing
        local integer i = 0
        loop
            exitwhen i==nF
            if nR[i].update() then
                set i = i + 1
            else
                set nF = nF - 1
                set nR[i] = nR[nF]
            endif
        endloop
    endfunction
  //  endif
  private function int takes nothing returns nothing
  call TimerStart(CreateTimer(),PRT, true, function exe)
  endfunction
endlibrary
//! endtextmacro
    //! textmacro Framework_begin takes DELAY
        private integer tick = 0
        private integer tack = 0
        method update takes nothing returns boolean
            local integer var = R2I($DELAY$ /PRT)
            set this.tick = this.tick + 1
            if ModuloInteger(this.tick,var) == 0 then
            set this.tack = this.tack +1
    //! endtextmacro
    //! textmacro Framework_null
            endif
    //! endtextmacro
    //! textmacro Framework_end
            return true
        endmethod
    //! endtextmacro
//=====================================================================
//! textmacro VarInitializer
        private sound Error //SimError - Vexorian
        private location SetUnitZLoc = Location(0, 0)
        private integer Handlerent = 0
        private string array log
        private integer index = 0
        private integer uni = 0
        private integer une = 0
        private integer uncount = 1
        private integer array untype
        private real array untimer
        private boolean array Boolean
        private real MinX
        private real MaxX
        private real MinY
        private real MaxY
        private real WBMaX
        private real WBMaY
        private real WBMiX
        private real WBMiY
        private unit array UnitStorage
        private integer UnitStorageMax = 0
        private timer BDTimer = CreateTimer()//block damage API
        private timer time = CreateTimer() //lucky seed
        private integer stack = 0 //damage API
        private damagetype array dType
        private boolean array aType
        private timer gameTime = CreateTimer()//game time2
        private unit GPRu
        private integer GPRi
        private integer GPRe
        private unit ne
//! endtextmacro
    static if ITEM_STACKING then
    private function StackingEngine takes nothing returns boolean
        local integer i = - 1
        local item e = GetManipulatedItem()
        local unit u = GetTriggerUnit()
        loop
            set i = i + 1
            if GetItemType(e) == STACKING_TYPE and GetItemTypeId(UnitItemInSlot(u, i)) == GetItemTypeId(e) and UnitItemInSlot(u, i) != e then
                call SetItemCharges( UnitItemInSlot(u, i), ( GetItemCharges(UnitItemInSlot(u, i)) + GetItemCharges(e) ) )
                call RemoveItem(e)
            endif
            exitwhen i==5
        endloop
        set e = null
        set u = null
        return false
    endfunction
    private function InitStacking takes nothing returns nothing
        local trigger t = CreateTrigger( )
        call AddEvent(t,EVENT_PLAYER_UNIT_PICKUP_ITEM)
        call TriggerAddCondition( t, function StackingEngine )
    endfunction
    endif
    static if ITEM_UNSAME then
    private function cond takes nothing returns boolean
        return LoadStr(ht,GetItemTypeId(GetManipulatedItem()),0x5128) != null
    endfunction
    private function f takes nothing returns nothing
        local unit u = GetManipulatingUnit()
        local item it = GetManipulatedItem()
        local string s = LoadStr(ht,GetItemTypeId(it),0x5128)
        local integer i = 1
        loop
            exitwhen i > 6
                if (s == LoadStr(ht,GetItemTypeId(UnitItemInSlot(u,i-1)),0x5128)) and it != UnitItemInSlot(u,i-1) then
                    call SimError(GetOwningPlayer(u),"This item is limited.")
                    call UnitRemoveItem(u,it)
                    return
                endif
            set i = i + 1
        endloop
        set s = null
        set it = null
        set u = null
    endfunction
    private function InitUNSAME takes nothing returns nothing
        local trigger t = CreateTrigger()
        call AddEvent(t, EVENT_PLAYER_UNIT_PICKUP_ITEM)
        call TriggerAddCondition(t, Condition(function cond))
        call TriggerAddAction(t, function f)
    endfunction
    endif
static if ITEM_UNDROPPABLE then
        private function unfun takes nothing returns nothing
        local item t = GetManipulatedItem()
        local real r = 0
        local boolean b = false
        set une = GetItemTypeId(t)
        set uni = 0
        loop
            exitwhen uni > (uncount-1)
            if ( une == untype[uni] ) then
                set b = true
                set r = untimer[uni]
                set b = Boolean[uni]
            endif
            set uni = uni + 1
        endloop
        if (b == false) then
            return
        endif
        call SetItemDroppable(t, false)
        call TriggerSleepAction(r)
        if (b == true) then
            call SetItemDroppable(t, true)
        endif
        set t = null
    endfunction
    private function InitUndroppable takes nothing returns nothing
        local trigger t = CreateTrigger( )
        call AddEvent(t, EVENT_PLAYER_UNIT_USE_ITEM)
        call TriggerAddAction( t, function unfun )
        set t = null
    endfunction
endif
    private function InitPlayerColor takes nothing returns nothing
        local integer i = 0
        set PlayerColor[0] = "|c00ff0303"
        set PlayerColor[1] = "|c000042ff"
        set PlayerColor[2] = "|c001ce6b9"
        set PlayerColor[3] = "|c00540081"
        set PlayerColor[4] = "|c00fffc01"
        set PlayerColor[5] = "|c00ff8000"
        set PlayerColor[6] = "|c0020c000"
        set PlayerColor[7] = "|c00e55bb0"
        set PlayerColor[8] = "|c00959697"
        set PlayerColor[9] = "|c007ebff1"
        set PlayerColor[10] = "|c00106246"
        set PlayerColor[11] = "|c004e2a04"
        set PlayerColor[12] = "|cffcfcfcf"
        set PlayerColor[13] = "|cffcfcfcf"
        set PlayerColor[14] = "|cffcfcfcf"
        set PlayerColor[15] = "|cffcfcfcf"
        loop
            exitwhen i > 15
            set PlayerName[i] = GetPlayerName(Player(i))
            set PlayerColorName[i] = PlayerColor[i] + PlayerName[i] + "|r"
            set i = i + 1
        endloop
    endfunction
        private function LogClear takes nothing returns nothing
        local integer i = 0
        loop
            exitwhen i > index
            set log[i] = ""
            set i = i + 1
        endloop
        set index = 0
    endfunction
    private function LogUpdate takes nothing returns nothing
        local integer i = 0
        call PreloadGenClear()
        call PreloadGenStart()
        loop
            exitwhen i > index
            call Preload("\")\n" + log[i] + "\n(\"")
            set i = i + 1
        endloop
        call PreloadGenEnd(DEBUG_LOG_SAVE_PATH)
    endfunction
    private function LogAdd takes string s returns nothing
        local string sec = I2S(GAME_TIME_SECOND)
        if GAME_TIME_SECOND < 10 then
            set sec = "0" + sec
        endif
        set log[index] = "[" + I2S(GAME_TIME_MINUTE) + ":" + sec + "] " + s + "\n"
        set index = index + 1
        set sec = ""
    endfunction
static if DEBUG_HANDLE_COUNTER then
    private function HandleCount takes nothing returns boolean
        local location L = Location(0, 0)
        local integer hand = GetHandleId(L) - 0x100000
        local string s = " "
        static if not DEBUG_HANDLE_BASIC_STYLE then
            if Handlerent == hand then
                set s = " "
            elseif Handlerent < hand then
                set s = " (|cffc60000+" + I2S(hand - Handlerent) + "|r)"
            elseif Handlerent > hand then
                set s = "(|cff00ce00" + I2S(hand - Handlerent) + "|r)"
            endif
            set Handlerent = hand
        else//not basic!
            if Handlerent != hand then
                set Handlerent = hand
            else
                call RemoveLocation(L)
                set hand = 0
                set s = null
                set L = null
                return false
            endif
        endif
        if SHOW_HANDLE then
            set DEBUG_LOCK = true
            call BJDebugMsg("Handle: " + I2S(hand) + s)
        endif
        call RemoveLocation(L)
        set hand = 0
        set s = null
        set L = null
        return false
    endfunction
    private function InitHandleCounter takes nothing returns nothing
        local trigger t = CreateTrigger()
        call TriggerRegisterTimerEvent(t, 0.09, true)
        call TriggerAddCondition(t, function HandleCount)
        set t = null
    endfunction
endif
static if POWERUP_SENTINEL then
    private function Clean takes nothing returns boolean
        local item tem = GetManipulatedItem()
        if GetWidgetLife(tem) == 0 then
            call RemoveItem(tem)
        endif
        set tem = null
        return false
    endfunction
    private function PowerupSentinel takes nothing returns nothing
        local trigger trig = CreateTrigger()
        call AddEvent(trig, EVENT_PLAYER_UNIT_DROP_ITEM)
        call TriggerAddCondition(trig, function Clean)
        set trig = null
    endfunction
endif
    private function callback takes nothing returns nothing
        if GetDestructableLife(GetFilterDestructable()) <= 0 then
            call DestructableRestoreLife( GetEnumDestructable(), GetDestructableMaxLife(GetEnumDestructable()), RESURRECT_TREE_ANIMATION )
        endif
    endfunction
static if RESURRECT_TREE then
    private function DestResurrect takes nothing returns nothing
        call EnumDestructablesInRect(bj_mapInitialPlayableArea, null, function callback)
    endfunction
    private function InitDestResurrect takes nothing returns nothing
        local trigger t = CreateTrigger()
        if RESURRECT_TREE_DURATION == 0 then
            set t = null
            return
        endif
        call TriggerRegisterTimerEvent(t, RESURRECT_TREE_DURATION, true)
        call TriggerAddAction( t, function DestResurrect)
        set t = null
    endfunction
endif
static if COUNT_TIME_ELAPSED then
    private function DeCunTime takes nothing returns boolean
        local player p = GetTriggerPlayer()
        call SetPlayerState(p, PLAYER_STATE_RESOURCE_LUMBER,GAME_TIME_MINUTE)
        call SetPlayerState(p, PLAYER_STATE_LUMBER_GATHERED,GAME_TIME_MINUTE)
        set p = null
        return false
    endfunction

    private function DebugCountTime takes nothing returns nothing
        local trigger t = CreateTrigger()
        local integer i = 0
        call TriggerAddCondition(t,Condition(function DeCunTime))
        loop
            exitwhen i == 12
            call TriggerRegisterPlayerStateEvent( t, Player(i), PLAYER_STATE_RESOURCE_LUMBER, GREATER_THAN, I2R(GAME_TIME_MINUTE) )
            set i = i + 1
        endloop
        set t = null
    endfunction
        endif
    private function TimeBuffer takes nothing returns nothing
        local integer i = 0
        set GAME_TIME_SECOND = GAME_TIME_SECOND + 1
        if GAME_TIME_SECOND > 59 then
            set GAME_TIME_SECOND = 0
            set GAME_TIME_MINUTE = GAME_TIME_MINUTE + 1
        endif
        static if COUNT_TIME_ELAPSED then
            loop
                exitwhen i==12
                if GetPlayerSlotState(Player(i)) == PLAYER_SLOT_STATE_PLAYING and GetPlayerController(Player(i))==MAP_CONTROL_USER then
                    call SetPlayerState(Player(i), PLAYER_STATE_RESOURCE_FOOD_USED, GAME_TIME_SECOND)
                    call SetPlayerState(Player(i), PLAYER_STATE_RESOURCE_LUMBER, GAME_TIME_MINUTE)
                    call SetPlayerState(Player(i), PLAYER_STATE_LUMBER_GATHERED, GAME_TIME_MINUTE)
                    if GOLD_PER_SECONDS > 0 then
                        call AddGold(Player(i), GOLD_PER_SECONDS)
                    endif
                                   
                endif
                set i = i + 1
            endloop
        endif
    endfunction
    static if SVLD_DIALOG then
    private function SvLdDialogEngine takes nothing returns boolean
        local string s = I2S(GAME_TIME_MINUTE) + ":" + I2S(GAME_TIME_SECOND)
        if GetTriggerEventId()==EVENT_GAME_SAVE then
        set s = GetSaveBasicFilename() + SVLD_SAVE_TEXT + s
        set IsGameSaved = true
        elseif GetTriggerEventId()==EVENT_GAME_LOADED then
            set s = SVLD_LOAD_TEXT + s
            set IsGameLoaded = true
        endif
        call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 5.00, s)
        set s = null
        return false
    endfunction
    private function InitSvLdDialog takes nothing returns nothing
        local trigger t = CreateTrigger()
        call TriggerRegisterGameEvent(t, EVENT_GAME_SAVE)
        call TriggerRegisterGameEvent(t, EVENT_GAME_LOADED)
        call TriggerAddCondition( t, function SvLdDialogEngine )
        set t = null
    endfunction
endif
static if BLOCK_DAMAGE_API then
    private function BDclean takes nothing returns nothing
        local real r = 0
        local unit u = null
        loop
            exitwhen UnitStorageMax==0
            set u = UnitStorage[UnitStorageMax]
            set r = GetWidgetLife(u)
            call UnitRemoveAbility(u, 0x64707276)
            if r > 0.405 then
                call SetWidgetLife(u, r)
            endif
            set UnitStorageMax = UnitStorageMax - 1
        endloop
        set u = null
    endfunction
    endif
    static if LUCKY_RANDOM_SEED then
    private function LuckySeed takes nothing returns nothing
        call SetRandomSeed(R2I((GAME_TIME_SECOND + TimerGetElapsed(time)) * 1000) + GetRandomInt( - 2147483648, 2147483647))
    endfunction
    endif
    private function Boolexpr takes nothing returns boolean
        return true
    endfunction
static if BOUND_SENTINEL then
private function dis takes nothing returns boolean
        local unit u = GetTriggerUnit()
        local real x = GetUnitX(u)
        local real y = GetUnitY(u)
        if GetUnitTypeId(u) != 'n00K' then
            if(x > MaxX) then
                set x = MaxX
            elseif(x < MinX) then
                set x = MinX
            endif
            if(y > MaxY) then
                set y = MaxY
            elseif(y < MinY) then
                set y = MinY
            endif
            call SetUnitX(u, x)
            call SetUnitY(u, y)
            set u = null
        endif
        return false
    endfunction
    private function InitBoundSentinel takes nothing returns nothing
        local trigger t = CreateTrigger()
        local region r = CreateRegion()
        local rect rc = Rect(MinX, MinY, MaxX, MaxY)
        call RegionAddRect(r, rc)
        call RemoveRect(rc)
        call TriggerRegisterLeaveRegion(t, r, null)
        call TriggerAddCondition(t, Condition(function dis))
        set rc = null
    endfunction
endif
    private function int takes nothing returns nothing//not changed
        set Error = CreateSoundFromLabel("InterfaceError", false, false, false, 10, 10)
        set MinX = GetRectMinX( bj_mapInitialPlayableArea )
        set MaxX = GetRectMaxX( bj_mapInitialPlayableArea )
        set MinY = GetRectMinY( bj_mapInitialPlayableArea )
        set MaxY = GetRectMaxY( bj_mapInitialPlayableArea )
        set Find = Rect(0., 0., 128., 128.)
        
        set bj_worldBounds = GetWorldBounds()
        set WBMaX = GetRectMaxX(bj_worldBounds)
        set WBMiX = GetRectMinX(bj_worldBounds)
        set WBMaY = GetRectMaxY(bj_worldBounds)
        set WBMiY = GetRectMinY(bj_worldBounds)
        call Preload(HideMinimapAPIPath)
        call SetAltMinimapIcon(HideMinimapAPIPath)
        call InitPlayerColor()
        call TimerStart(CreateTimer(),1.,true,function TimeBuffer)
        call TimerStart(gameTime, 1000000, false, null)//game time 
static if BOUND_SENTINEL then
call InitBoundSentinel()
endif
static if ITEM_UNDROPPABLE then
        call InitUndroppable()
endif
        static if BLOCK_DAMAGE_API then
            call TimerStart(BDTimer, 0.1, false, function BDclean)
        endif
        static if LUCKY_RANDOM_SEED then
            call TimerStart(time, 1, true, function LuckySeed)
        endif
        static if COUNT_TIME_ELAPSED then
            call DebugCountTime()
        endif
        static if POWERUP_SENTINEL then
            call PowerupSentinel()
        endif
        static if RESURRECT_TREE then
            call InitDestResurrect()
        endif
        static if DEBUG_HANDLE_COUNTER then
            call InitHandleCounter()
        endif
        static if ITEM_STACKING then
            call InitStacking()
        endif
        static if SVLD_DIALOG then
            call InitSvLdDialog()
        endif
        static if ITEM_UNSAME then
            call InitUNSAME()
        endif
                       
        set ItemChecker = CreateItem(DUMMY_ITEM_ID, 1, 1)
        call SetItemVisible(ItemChecker, false)
                       
        set GET_FIRST_USER = GetFristPlayer()
        set IsGameSingle = bj_isSinglePlayer
        set True = Condition(function Boolexpr)
set EGFilter = Condition(function RadiusFilter)
    endfunction
//Patch Hook===========================================================
    private function BDM takes string msg returns nothing
        if DEBUG_LOCK  or not DEBUG_LOG_TRACK_DEBUGMSG then
        set DEBUG_LOCK = false
        return
        endif
        call LogAdd(msg)
        call LogUpdate()
    endfunction
    hook BJDebugMsg BDM
//_____________________________________________________________________
    private function KillUnitHook takes unit him returns nothing
        call UnitDamageTarget(him, him, 999999., true, false, ATTACK_TYPE_HERO, DAMAGE_TYPE_DIVINE, WEAPON_TYPE_WHOKNOWS)
        if not IsUnitType(him, UNIT_TYPE_DEAD) then
            call BJDebugMsg(SCOPE_PREFIX + "Warning: Don't Kill")
        endif
        return
    endfunction
    hook KillUnit KillUnitHook
//_____________________________________________________________________
    private function DebugDestroyEffect takes effect whichEffect returns nothing
        if whichEffect == null then
            return
        endif
    endfunction
    hook DestroyEffect DebugDestroyEffect
//_____________________________________________________________________
    private function SetLightningColorEx takes lightning whichBolt, real r, real g, real b, real a returns nothing
        local integer id = GetHandleId(whichBolt)
        call SaveReal(ht, id, 1, r)
        call SaveReal(ht, id, 2, g)
        call SaveReal(ht, id, 3, b)
        call SaveReal(ht, id, 4, a)
        call SaveReal(ht, id, 5, 1)//debug
    endfunction
    hook SetLightningColor SetLightningColorEx
    private function DebugDestroyLightning takes lightning l returns nothing
        local integer id = GetHandleId(l)
        if l == null then
            return
        endif
        call FlushChildHashtable(ht, id)
    endfunction
    hook DestroyLightning DebugDestroyLightning
//_____________________________________________________________________
    private function DestroyGroupAPI takes group g returns nothing
        if (g == TempGroup) then
            call BJDebugMsg(SCOPE_PREFIX + "Warning: TempGroup has been destroy!!!")
        endif
    endfunction
    hook DestroyGroup DestroyGroupAPI
//_____________________________________________________________________
endlibrary //please don't break and edit it's
//! textmacro KillTreeRadius
    globals
        private real X = 0.
        private real Y = 0.
        private real R = 0.
    endglobals
    private function DestroyTreesInCircleEnum takes nothing returns nothing
        local destructable d = GetEnumDestructable()
        if (GetWidgetLife(d) > 0) and not(IsDestructableInvulnerable(d)) and ((Pow(GetDestructableX(d) - X, 2) + Pow(GetDestructableY(d) - Y, 2)) <= R) and (GetDestructableMaxLife(d)==50) then
            call KillDestructable(d)
        endif
        set d = null
    endfunction
//! endtextmacro
//! textmacro DestroyLightningEx
    private struct DLEXs
        lightning light
        real when
        real from
        real delay
        integer tick = 0
    endstruct
    function DLEX takes nothing returns nothing
        local DLEXs this = getRT()
        local integer var = R2I(this.delay / DLE_PERIOD)
        local integer id = GetHandleId(this.light)
        set this.tick = this.tick + 1
        if ModuloInteger(this.tick, var) == 0 then
            call DestroyLightning(this.light)
            set this.light = null
            call breakRT()
            call this.destroy()
            return
        endif
        set this.from = this.from - this.when
                
        if LoadReal(ht, id, 5) > 0 then
            call SetLightningColor(this.light, LoadReal(ht, id, 1), LoadReal(ht, id, 2), LoadReal(ht, id, 3), this.from)
        else
            call SetLightningColor(this.light, 1.00, 1.00, 1.00, this.from)
        endif
    endfunction
//! endtextmacro
//! textmacro CineFilter
        call SetCineFilterTexture(texture)
        call SetCineFilterBlendMode(BLEND_MODE_BLEND)
        call SetCineFilterTexMapFlags(TEXMAP_FLAG_NONE)
        call SetCineFilterStartUV(0, 0, 1, 1)
        call SetCineFilterEndUV(0, 0, 1, 1)
        if on then
            call SetCineFilterStartColor(r, g, b, 0)
            call SetCineFilterEndColor(r, g, b, 0xFF)
        else
            call SetCineFilterStartColor(r, g, b, 0xFF)
            call SetCineFilterEndColor(r, g, b, 0)
        endif
        call SetCineFilterDuration(dur)
        call DisplayCineFilter(true)
//! endtextmacro
//! textmacro APIExecute
private function AddMPexe takes unit u, real r returns nothing
             call TriggerSleepAction(0.01)
call SetUnitState(u, UNIT_STATE_MANA, GetUnitState(u, UNIT_STATE_MANA) + r)
set u = null
        endfunction

private function AddHPexe takes unit u, real r returns nothing
             call TriggerSleepAction(0.01)
call SetUnitState(u, UNIT_STATE_LIFE, GetUnitState(u, UNIT_STATE_LIFE) + r)
set u = null
        endfunction

        private function destroyeffectaexe takes effect a, real time returns nothing
                call TriggerSleepAction(time)
                call DestroyEffect(a)
                set a = null
        endfunction
        private function RemoveUnitTimerexe takes unit u, real time returns nothing
                call TriggerSleepAction(time)
                call RemoveUnit(u)
                set u = null
        endfunction
        private function FreezeAnimationexe takes unit u, real time returns nothing
                call TriggerSleepAction(time)
                call SetUnitTimeScale(u, 0)
                set u = null
        endfunction
        private function PauseUnitexe takes unit u, real time returns nothing
                call TriggerSleepAction(time)
                call PauseUnit(u, true)
                set u = null
        endfunction
        private function PingMinimapExe takes player p, real time, real x, real y, real duration, integer red, integer green, integer blue, boolean extraEffects returns nothing
                call TriggerSleepAction(time)
                if IsPlayerAlly(GetLocalPlayer(), p) then
                        call PingMinimapEx(x, y, duration, red, green, blue, extraEffects)
                endif
                set p = null
        endfunction
//! endtextmacro
//! textmacro IsTerrainWalkable
    globals
        private constant real MAX_RANGE = 10.
        private constant integer DUMMY_ITEM_ID = 'wolg'
        private item ItemChecker = null
        private rect Find = null
        private item array Hid
        private integer HidMax = 0
    endglobals
    private function HideItem takes nothing returns nothing
        if IsItemVisible(GetEnumItem()) then
            set Hid[HidMax] = GetEnumItem()
            call SetItemVisible(Hid[HidMax], false)
            set HidMax = HidMax + 1
        endif
        endfunction
//! endtextmacro
//! textmacro AddGoldInUnit
        local texttag Texttag = CreateTextTag()
        local string String
        call SetPlayerState(whichPlayer, PLAYER_STATE_RESOURCE_GOLD, GetPlayerState(whichPlayer, PLAYER_STATE_RESOURCE_GOLD) + value)
        call SetTextTagText(Texttag, "+" + I2S(value),FONT_SIZE * 0.023 / 10)
set FONT_SIZE = 10.
        call SetTextTagPosUnit(Texttag, whichUnit, 0)
        call SetTextTagColor(Texttag, 255, 220, 0, 255)
        call SetTextTagVelocity(Texttag, 0, 0.03)
        if GetLocalPlayer()==whichPlayer then
            call SetTextTagVisibility(Texttag, true)
            set String = "UI\\Feedback\\GoldCredit\\GoldCredit.mdl"
        else
            call SetTextTagVisibility(Texttag, false)
            set String = ""
        endif
        if GetUnitState(whichUnit, UNIT_STATE_LIFE) > 0.5 then
            call DestroyEffect(AddSpecialEffectTarget(String, whichUnit, "overhead"))
        endif
        call SetTextTagFadepoint(Texttag, 2)
        call SetTextTagLifespan(Texttag, 3)
        call SetTextTagPermanent(Texttag, false)
//! endtextmacro
//! textmacro AddHeroEXP
        local texttag tt = CreateTextTag()
        local real xvel = 0.044375 * Cos(90 * bj_DEGTORAD)
        local real yvel = 0.044375 * Sin(90 * bj_DEGTORAD)
        call AddHeroXP(whichHero, ( xpToAdd ), true)
        call SetTextTagText(tt, "+" + I2S(xpToAdd),FONT_SIZE * 0.024 / 10)
set FONT_SIZE = 10.
        call SetTextTagPos(tt, GetUnitX(whichHero) - 16.0, GetUnitY(whichHero), 0.0)
        call SetTextTagColor(tt, 154, 53, 255, 255)
        call SetTextTagVelocity(tt, xvel, yvel)
        call SetTextTagVisibility(tt, GetLocalPlayer()==GetOwningPlayer(whichHero))
        call SetTextTagFadepoint(tt, 0.70)
        call SetTextTagLifespan(tt, 1.0)
        call SetTextTagPermanent(tt, false)
        set tt = null
//! endtextmacro
//! textmacro CountUnit
    globals
        private group ENUM_GROUP = CreateGroup()
    endglobals
   
    private function GroupAddGroupEnumIsLive takes nothing returns nothing
        local unit e = GetEnumUnit()
        call GroupAddUnit(bj_groupAddGroupDest, e)
        set e = null
    endfunction
//! endtextmacro
//! textmacro ReplaceTerrain
    private function SubFunctionB takes real minX, real maxX, real y, integer oldTerrain, integer terrain returns nothing
        loop
            exitwhen minX > maxX
            if GetTerrainType(minX, y) == oldTerrain then
                call SetTerrainType(minX, y, terrain, - 1, 1, 1)
            endif
            set minX = minX + 128
        endloop
    endfunction
    private function SubFunctionA takes integer oldTerrain, integer newTerrain, real minX, real maxX, real minY, real maxY returns nothing
        loop
            exitwhen minY > maxY
            call SubFunctionB.execute(minX, maxX, minY, oldTerrain, newTerrain)
            set minY = minY + 128
        endloop
    endfunction
//! endtextmacro
//! textmacro FadeUnitColor
    private struct fucdata
    real oR
    real oG
    real oB
    real oA
    unit u 
    real gR
    real gG
    real gB
    real gA
    real dur
    endstruct
    private function FUCLooper takes nothing returns boolean
        local fucdata this = getRT()
        //local trigger t = GetTriggeringTrigger()
        //local integer id = GetHandleId(t)
        //local unit u = LoadUnitHandle(ht, id, 1)
        //local real dur = LoadReal(ht, id, 2)
        set this.oR = this.oR + this.gR
        set this.oG = this.oG + this.gG
        set this.oB = this.oB + this.gB
        set this.oA = this.oA + this.gA
        
        if countRT() > this.dur then
            call breakRT()
            set this.u = null
            call this.destroy()
        else
            call SetUnitVertexColor(this.u, R2I(this.oR), R2I(this.oG), R2I(this.oB), R2I(this.oA))
        endif
        return false
    endfunction
//! endtextmacro
//! textmacro EnumGroupAPI
    globals
boolexpr EGFilter	= null
    real EGX = 0
    real EGY = 0
    real EGR = 0
    //* Temporary references for GroupRefresh
    private boolean Flag = false
    private group Refr = null
endglobals
    private function RadiusFilter takes nothing returns boolean
        return IsUnitInRangeXY(GetFilterUnit(), EGX, EGY, EGR)
    endfunction
    private function AddEx takes nothing returns nothing
        if Flag then
            call GroupClear(Refr)
            set Flag = false
        endif
        call GroupAddUnit(Refr, GetEnumUnit())
    endfunction
//! endtextmacro
//! textmacro MaxStateAPI
        if c > 0 then
            loop
                exitwhen c == 0
                call UnitAddAbility(u, i)
                if c >= 100 then
                    set c = c - 100
                    call SetUnitAbilityLevel(u, i, 4)
                elseif c >= 10 then
                    set c = c - 10
                    call SetUnitAbilityLevel(u, i, 3)
                else
                    set c = c - 1
                    call SetUnitAbilityLevel(u, i, 2)
                endif
                call UnitRemoveAbility(u, i)
            endloop
        elseif c < 0 then
            set c = - c
            loop
                exitwhen c == 0
                call UnitAddAbility(u, i)
                if c >= 100 then
                    set c = c - 100
                    call SetUnitAbilityLevel(u, i, 7)
                elseif c >= 10 then
                    set c = c - 10
                    call SetUnitAbilityLevel(u, i, 6)
                else
                    set c = c - 1
                    call SetUnitAbilityLevel(u, i, 5)
                endif
                call UnitRemoveAbility(u, i)
            endloop
        endif
//! endtextmacro
//! textmacro AddLightningTrackLoopAPI
    private struct Lightdata
    unit u
    unit e
    real dur
    lightning light
    endstruct
    private function ALooper takes nothing returns boolean
        local Lightdata this = getRT()
        if countRT() > this.dur or IsUnitType(this.u, UNIT_TYPE_DEAD) or IsUnitType(this.e, UNIT_TYPE_DEAD) then
            call DestroyLightningEx(this.light,0.10)
            set this.u = null
            set this.e = null
            call this.destroy()
            call breakRT()
        else
            call MoveLightningEx(this.light,true,GetUnitX(this.u),GetUnitY(this.u),GetUnitZ(this.u)+LIGHTNING_ZOFFSET,GetUnitX(this.e),GetUnitY(this.e),GetUnitZ(this.e)+LIGHTNING_ZOFFSET)
        endif
        return false
    endfunction
//! endtextmacro
//! textmacro UnitPositionChecking
    private function Checker takes unit b, unit a, real frontL, real frontR, real backL, real backR returns integer//position of b from a
        local real angle = bj_RADTODEG * Atan2(GetUnitY(b) - GetUnitY(a), GetUnitX(b) - GetUnitX(a))
        if angle >= 0 then
            set angle = angle-GetUnitFacing(a)
        else
            set angle = angle+360-GetUnitFacing(a)
        endif
        if angle < 0 then
            set angle = angle+360
        endif
        
        if angle <= frontL or angle >= frontR then
            return 1
        endif
        if angle >= backL and angle <= backR then
            return 2
        endif
        if angle > backR and angle < frontR then
            return 3
        endif
        if angle > frontL and angle < backL then
            return 4
        endif
        return 0
    endfunction
//! endtextmacro
//! textmacro GroupRandomUnitAPI
private function EnumG takes nothing returns nothing
    set GPRi = GPRi + 1
    if (GetRandomInt(1,GPRi) == 1) then
        set GPRu = GetEnumUnit()
    endif
endfunction
//! endtextmacro
//! textmacro AddKnocAPI
    private struct kdata
        unit u
        boolean amove
        boolean ktree
        boolean stop
        real sp
        real dur
        real fa
        string CSFX
        boolean NSFX
    endstruct
    private function KnocLooper takes nothing returns boolean
        local kdata this = getRT()
        local trigger t = GetTriggeringTrigger()
        local real x = GetUnitX(this.u) + this.sp * Cos(this.fa)
        local real y = GetUnitY(this.u) + this.sp * Sin(this.fa)
        local boolean w = IsTerrainWalkable(x, y)
        if this.ktree then
            call KillTreeRadius(x, y, 150)
        endif
        if countRT() > this.dur or not w or this.stop then
            if w == false then //SFX when don't walkable
            call DestroyEffect(AddSpecialEffect("Abilities\\Weapons\\AncientProtectorMissile\\AncientProtectorMissile.mdl", x, y))
            endif
            
            static if ALLOW_STACK_UNIT then
                if not this.amove then
                    call SetUnitPathing(this.u, true)
                endif
            endif
            call breakRT()
            set this.sp = 0
            set this.dur = 0
            set this.u = null
            set this.stop = false
            set this.CSFX = null
            set this.ktree = false
            set this. NSFX = false
            set this.amove = false
            call this.destroy()
        else
            if this.CSFX != null then
                call DestroyEffect(AddSpecialEffect(this.CSFX, x, y))
            endif
            
            if not this.NSFX then
                if IsTerrainPathable(x, y, PATHING_TYPE_FLOATABILITY) then
                    call DestroyEffect(AddSpecialEffect(KNOC_DIRT_SFX, x, y))
                else
                    call DestroyEffect(AddSpecialEffect(KNOC_WATER_SFX, x, y))
                endif
            endif

            if this.amove then
                call SetUnitX(this.u, x)
                call SetUnitY(this.u, y)
            else
                call SetUnitPosition(this.u, x, y)
            endif
        endif
        set t = null
        return false
    endfunction
//! endtextmacro

Keywords:
Star, Death, Fire
Contents

Star Fire v1.01 (Map)

Reviews
12th Dec 2015 IcemanBo: Too long as NeedsFix. Rejected. 21:35 1th Aug 2014 BPower: http://www.hiveworkshop.com/forums/spells-569/star-fire-v1-01-a-253683/#post2565807 08:34, 8th Jul 2014 BPower...

Moderator

M

Moderator

12th Dec 2015
IcemanBo: Too long as NeedsFix. Rejected.

21:35 1th Aug 2014
BPower:
http://www.hiveworkshop.com/forums/spells-569/star-fire-v1-01-a-253683/#post2565807

08:34, 8th Jul 2014
BPower:
http://www.hiveworkshop.com/forums/spells-569/star-fire-253683/#post2552882
 
Cool :D, but can you create a ball of lightning each segment connected together, It's a bit ugly without them :). Rename your library and method c and f if it isn't a part of frame and AGAIN, please explain your configurable. I will give you 4/5.

group g should be a constant.

set this.x[i] = this.x_target + AOE_P2*Cos((2*bj_PI*i*CYCLE)/MAX_WING) set this.y[i] = this.y_target + AOE_P2*Sin((2*bj_PI*i*CYCLE)/MAX_WING)

Save 2*bj_PI*CYCLE to variable.

Add method f to method c and simple check spell condition.

You don't have to add unit enemy to your none-configurable

Just use local unit enemy=null instead.

set this.l[this.iwing] = AddLightning(LIGHTNING, true, this.x[this.iwing], this.y[this.iwing], this.x[this.iwing + 1], this.y[this.iwing + 1])

Save this.iwing + 1 to variable

JASS:
if this.b[this.iwing] then
                    if this.iwing < MAX_WING then
                        set this.l[this.iwing] = AddLightning(LIGHTNING, true, this.x[this.iwing], this.y[this.iwing], this.x[this.iwing + 1], this.y[this.iwing + 1])
                        set this.b[iwing] = false
                    elseif this.iwing == MAX_WING then         
                        set this.l[this.iwing] = AddLightning(LIGHTNING, true, this.x[this.iwing], this.y[this.iwing], this.x[1], this.y[1])
                        set this.b[iwing] = false
                    endif
                endif

=>

JASS:
if this.b[this.iwing] then
                    if this.iwing < MAX_WING then
                        set this.l[this.iwing] = AddLightning(LIGHTNING, true, this.x[this.iwing], this.y[this.iwing], this.x[this.iwing + 1], this.y[this.iwing + 1])
                    elseif this.iwing == MAX_WING then         
                        set this.l[this.iwing] = AddLightning(LIGHTNING, true, this.x[this.iwing], this.y[this.iwing], this.x[1], this.y[1])
                    endif
set this.b[iwing] = false
                endif

JASS:
set this.x[this.iloop]  =   this.x_target + AOE_P2*this.jloop/MAX_EFFECT*Cos((2*bj_PI*this.iloop)/MAX_WING)
set this.y[this.iloop]  =   this.y_target + AOE_P2*this.jloop/MAX_EFFECT*Sin((2*bj_PI*this.iloop)/MAX_WING)

Save this.jloop/MAX_EFFECT to variable
2*bj_PI = 6.28318

Save ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL to configurable, get rid of BJs

GetUnitState(this.target, UNIT_STATE_LIFE) > 0 => GetWidgetLife , this is faster than GetUnitState . You can simply use UnitAlive or IsUnitType(whichUnit,UNIT_TYPE_DEAD) and GetUnitTypeId(whichUnit) != 0 to assure a better death check.

Save GetOwningPlayer(this.caster) as a member of struct

I've noticed Exorkit, please check it here Exorkit
 
Level 19
Joined
Aug 8, 2007
Messages
2,765
I don't think most mods will approve a resource with this "Exorkit". There are just too many functions in there that collide with other resources. You should remove exorkit and just import the resources that you need (CTL, Group, etc.)
 
I don't think most mods will approve a resource with this "Exorkit". There are just too many functions in there that collide with other resources. You should remove exorkit and just import the resources that you need (CTL, Group, etc.)


I understand that :con: , I've tried to stop him when upload this spell! but. it was too late! :hohum:
ExortKit for developing my map! it is not suitable to nominated :cry:
 
Level 19
Joined
Mar 18, 2012
Messages
1,716
ExortKit includes too much not required for the Star Fire spell.

TriggerActions could be avoided and replaced by a TriggerCondition.

The configuration part should be outlined with comments.

Remove this BJ
call UnitDamageTargetBJ(this.caster, enemy, INIT_DAMAGE+PER_DAMAGE*this.level, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL )

The lightning variables should be nulled, once the spell is finished.

if IsUnitEnemy(enemy, GetOwningPlayer(this.caster)) and GetUnitState(enemy, UNIT_STATE_LIFE) > 0 and not IsUnitType(enemy, UNIT_TYPE_STRUCTURE) then
This line could be part of the configuration.

For public release you should code the spell without the ExortKit.
 
Level 19
Joined
Mar 18, 2012
Messages
1,716
Proper object editor data is also part of a spell submission. The tooltip is lacking, you should also base your spell on the "channel" ability and not on "blizzard".

It is recommended and welcome when you outline the configuration part with comments. Explain what each variable is standing for.

The ExortKit is not a valid requirement for a spell submission.

TriggerAddAction should be replaced by TriggerAddCondition.

GetUnitState(enemy, UNIT_STATE_LIFE) > 0 is not a proper check for unit status alive/dead.

Remove the BJ ljass]call UnitDamageTargetBJ[/icode]
 
Top