1. Are you planning to upload your awesome map to Hive? Please review the rules here.
    Dismiss Notice
  2. Updated Resource Submission Rules: All model & skin resource submissions must now include an in-game screenshot. This is to help speed up the moderation process and to show how the model and/or texture looks like from the in-game camera.
    Dismiss Notice
  3. DID YOU KNOW - That you can unlock new rank icons by posting on the forums or winning contests? Click here to customize your rank or read our User Rank Policy to see a list of ranks that you can unlock. Have you won a contest and still havn't received your rank award? Then please contact the administration.
    Dismiss Notice
  4. We have recently started the 16th edition of the Mini Mapping Contest. The theme is mini RPG. Do check it out and have fun.
    Dismiss Notice
  5. Choose your ride to damnation in the 5th Special Effect Contest Poll.
    Dismiss Notice
  6. The winners of the 13th Techtree Contest have been announced!
    Dismiss Notice
  7. The 13th Music Contest Poll is up! Vote for the best tracks in this symphony of frost and flame.
    Dismiss Notice
  8. Race against the odds and Reforge, Don't Refund. The 14th Techtree Contest has begun!
    Dismiss Notice
  9. Check out the Staff job openings thread.
    Dismiss Notice
Dismiss Notice
60,000 passwords have been reset on July 8, 2019. If you cannot login, read this.

Trigger Viewer

Bringer_of_Pain's DnD Version 2.9.w3x
Variables
README
DO NOT SAVE
README
Change List
To Do List
Blackroots mod stuff
Global
Initialization
Chat
DebugMultiboard
DebugMultiboardMake
OldChat
Someone Leaves
Items
Bounty
ItemConst
ItemBoard
ItemHandling
ItemDropped
ItemDropped Copy
Players
Training Room
Hero Selector
Hero Restrictor
Hero Restrictor Lock
Hero Reviver
Hero Dies
test
test Copy
PlayerCam
GUI
Give to Neutral
Misc
Create
Units
oldunits
Dialog
Pointer
ItemsOLD
Items
Doodads
Spells
Heal
Cast Spell
Summons Follow
Take Control Follow
FireWall
FireWall Item
FireWall Unit
Apocalypse
Apocalypse Item
Apocalypse Unit
BlinkLearn
Untitled Trigger 002
BlinkAuto
Root Order Object
Root Order No Target
Root Order Point
Root Periodic
Refs
RefsAbils
RefsGUI
RefsCoins
RefsCoinAbils
RefsBridges
RefsGates
Misc
Rejuvenating Waters
NPC Dies
NPC Dies Copy
KeepAlive Periodic
Village Building Explosions
DMs speak with a FUCKING PERIOD ADSRODALIHJSDKH
Hide Bridges
Give Lumber Experience
Rejuvenation Fountains
Empties Vial
Add Rejuv
Setup Unit Palette
Peasants Harvest
Hurl Boulder Facing
Palette Apology
Gold Lumber
Clear Enemy Units
Quests
IgnoreAIGuard
Time
Junk
instarejuv
coinrefs Copy
Unit Palleting
level 9 10
level 8
level 7
level 6
level 5
level 4
level 3
level 2
level 1
alllevels
trolls
villagers
orcs
nightelf
undead
stores
human heroes
orc heroes
undead heroes
nightelf heroes
neutral heroes
creeps
sasquatch
spiders
fel
player heroes
human nightelf
orc undead
human buildings
guard tower
town hall
arcane sanctum
campaign
night elf buildings
tree of life
corrupted tree of life
huntershall
ancientoflore
ancientprotector
orc buildings
town hall Copy 5
Item Attachments
BOPs Thanks
Fearless Orc Sword
Fealless Orc Sword 2
Fealless Orc Sword 2 Copy
Terrain Changers
Terrain1
Terrain1 Copy
Terrain1 Copy Copy
Terrain1 Copy Copy 2
Terrain1 Copy Copy 3
Terrain1 Copy Copy 3 Copy
Terrain1 Copy Copy 3 Copy Copy
Original VUEN DnD by... Well, vuen of course.

Slight alterations by blackroot, edited with permission of the creator (vuen).

//****************************************************
//****************************************************
//****************************************************
//Mapwide Global Utilites:
//****************************************************
//****************************************************
//****************************************************




function FillVial takes unit un returns nothing
    local integer i
    set i = 1
    loop
        exitwhen i > 6
        if GetItemTypeId(UnitItemInSlotBJ(un, i)) == 'I000' then
            call SetItemCharges( UnitItemInSlotBJ(un, i), 3 )
        elseif GetItemTypeId(UnitItemInSlotBJ(un, i)) == 'I001' then
            call RemoveItem(UnitItemInSlotBJ(un, i))
            call UnitAddItemByIdSwapped( 'I000', un )
        endif
        set i = i + 1
    endloop
endfunction

//Kutos to Blade.DK for this life glitch. Current cap is 450k, to avoid DC's.

function Bonus_RS_BRMOD takes unit u, integer bo, boolean b returns nothing
 local integer lifeabc = 'A01Q'
 local integer manaabc = 'A013'
 local integer wt = 0
 local integer max = 450000
 local integer min = -450000
 local integer I = bo
 local integer G = 0

 if(b == false)then
  set G = R2I(GetUnitState(u, UNIT_STATE_MAX_LIFE))
  set wt = lifeabc
 else
  set G = R2I(GetUnitState(u, UNIT_STATE_MAX_MANA))
  set wt = manaabc
 endif

 if((bo+G) > max)then
  set bo = max
 elseif((bo+G) < min)then
  set bo = min
 elseif(bo == 0)then
  return
 endif

 if(I > 0)then
  loop
   exitwhen(I <= 0)
   call UnitAddAbility(u, wt)
   if(I >= 100000)then
    call SetUnitAbilityLevel(u, wt, 13)
    set I = I - 100000
   elseif(I >= 10000)then
    call SetUnitAbilityLevel(u, wt, 12)
    set I = I - 10000
   elseif(I >= 1000)then
    call SetUnitAbilityLevel(u, wt, 11)
    set I = I - 1000
   elseif(I >= 100)then
    call SetUnitAbilityLevel(u, wt, 10)
    set I = I - 100
   elseif(I >= 10)then
    call SetUnitAbilityLevel(u, wt, 9)
    set I = I - 10
   else
    call SetUnitAbilityLevel(u, wt, 8)
    set I = I - 1
   endif
   call UnitRemoveAbility(u, wt)
  endloop
 elseif(I < 0)then
  loop
   exitwhen(I >= 0)
   call UnitAddAbility(u, wt)
   if(I <= -100000)then
    call SetUnitAbilityLevel(u, wt, 7)
    set I = I + 100000
   elseif(I <= -10000)then
    call SetUnitAbilityLevel(u, wt, 6)
    set I = I + 10000
   elseif(I <= -1000)then
    call SetUnitAbilityLevel(u, wt, 5)
    set I = I + 1000
   elseif(I <= -100)then
    call SetUnitAbilityLevel(u, wt, 4)
    set I = I + 100
   elseif(I <= -10)then
    call SetUnitAbilityLevel(u, wt, 3)
    set I = I + 10
   else
    call SetUnitAbilityLevel(u, wt, 2)
    set I = I + 1
   endif
   call UnitRemoveAbility(u, wt)
  endloop
 endif
endfunction

function Bonus_Apsd_BRMOD takes unit u, integer bo returns nothing
 local integer array z
 local integer array i
 local integer max = 2000
 local integer bo2 = 0
 local integer k = 10

 if(bo > max)then
  set bo2 = max
 elseif(bo <= 0)then
  set bo2 = 0
 else
  set bo2 = bo
 endif

 set i[0] = 1
 set i[1] = 2
 set i[2] = 4
 set i[3] = 8
 set i[4] = 16
 set i[5] = 32
 set i[6] = 64
 set i[7] = 128
 set i[8] = 256
 set i[9] = 512
 set i[10] = 1024

 set z[0] = 'A01E'
 set z[1] = 'A01N'
 set z[2] = 'A01O'
 set z[3] = 'A01P'
 set z[4] = 'A03U'
 set z[5] = 'A03V'
 set z[6] = 'A03W'
 set z[7] = 'A03X'
 set z[8] = 'A03Y'
 set z[9] = 'A03Z'
 set z[10] = 'A040'


 loop
  call UnitRemoveAbility(u, z[k])
  exitwhen(k == 0)
  set k = k - 1
 endloop

 if(bo2 == 0)then
  return
 endif

 set k = 10
 loop
  if(bo2 >= i[k])then
   call UnitAddAbility(u, z[k])
   set bo2 = bo2 - i[k]
  endif
  exitwhen(k == 0)
  set k = k - 1
 endloop
endfunction

function Bonus_BRMOD takes integer qq, unit u, integer dam returns nothing
 local integer array z
 local integer array i
 local integer max = 18250
 local integer dam2 = 0
 local integer k = 13

 if(dam > max)then
  set dam2 = max
 elseif(dam <= 0)then
  set dam2 = 0
 else
  set dam2 = dam
 endif

 set i[0] = 1
 set i[1] = 2
 set i[2] = 4
 set i[3] = 8
 set i[4] = 16
 set i[5] = 32
 set i[6] = 64
 set i[7] = 128
 set i[8] = 256
 set i[9] = 512
 set i[10] = 1024
 set i[11] = 2048
 set i[12] = 4096
 set i[13] = 8192

 if(qq == 1)then
  set z[0] = 'A01H'
  set z[1] = 'A010'
  set z[2] = 'A01G'
  set z[3] = 'A01F'
  set z[4] = 'A01I'
  set z[5] = 'A01J'
  set z[6] = 'A01M'
  set z[7] = 'A01K'
  set z[8] = 'A01L'
  set z[9] = 'A03O'
  set z[10] = 'A03P'
  set z[11] = 'A03Q'
  set z[12] = 'A03R'
  set z[13] = 'A03S'
 elseif(qq == 2)then
  set z[0] = 'A01D'
  set z[1] = 'A01C'
  set z[2] = 'A01B'
  set z[3] = 'A01A'
  set z[4] = 'A019'
  set z[5] = 'A018'
  set z[6] = 'A017'
  set z[7] = 'A016'
  set z[8] = 'A015'
  set z[9] = 'A01R'
  set z[10] = 'A01S'
  set z[11] = 'A01T'
  set z[12] = 'A01U'
  set z[13] = 'A03T'
 endif

 loop
  call UnitRemoveAbility(u, z[k])
  exitwhen(k == 0)
  set k = k - 1
 endloop

 if(dam2 == 0)then
  return
 endif

 set k = 13
 loop
  if(dam2 >= i[k])then
   call UnitAddAbility(u, z[k])
   set dam2 = dam2 - i[k]
  endif
  exitwhen(k == 0)
  set k = k - 1
 endloop
endfunction

function BonusEnumUnitSelected takes integer o returns nothing
 local integer i
 local integer bonus
 local unit u = GetEnumUnit()
 set bonus = udg_TEMP_Integer

 if IsUnitSelected(u, udg_TEMP_Player) then
  if GetBooleanOr(IsPlayerInForce(GetOwningPlayer(u), udg_Force[1]), IsPlayerInForce(GetOwningPlayer(u), udg_Force[3])) then

  if(o == 10)then
   call Bonus_BRMOD(2, u, bonus)
  elseif(o == 20)then
   call Bonus_BRMOD(1, u, bonus)
  elseif(o == 30)then
   call Bonus_RS_BRMOD(u, bonus, false)
  elseif(o == 40)then
   call Bonus_RS_BRMOD(u, bonus, true)
  elseif(o == 50)then
   call Bonus_Apsd_BRMOD(u, bonus)
  endif

  endif
 endif
endfunction

function BonusArmorEnumUnitSelected takes nothing returns nothing
    call BonusEnumUnitSelected(10)
endfunction
function BonusDamageEnumUnitSelected takes nothing returns nothing
    call BonusEnumUnitSelected(20)
endfunction
function BonusLifeEnumUnitSelected takes nothing returns nothing
    call BonusEnumUnitSelected(30)
endfunction
function BonusManaEnumUnitSelected takes nothing returns nothing
    call BonusEnumUnitSelected(40)
endfunction
function BonusAttackSpeedEnumUnitSelected takes nothing returns nothing
    call BonusEnumUnitSelected(50)
endfunction









//custom data funcs (yeah, yeah, i'll use a gamecache someday)
function IsUnitTrain takes unit un returns boolean
    if GetUnitUserData(un) == 1 then
        return true
    endif
    return false
endfunction

function SetUnitTrain takes unit un, boolean t returns nothing
    if not(IsUnitTrain(un) == t) then
        if t then
            call SetUnitUserData( un, 1 )
        else
            call SetUnitUserData( un, 0 )
        endif
    endif
endfunction








function GetPlayerHeroEnum takes nothing returns nothing
    if IsUnitType(GetEnumUnit(), UNIT_TYPE_HERO) then
        set udg_TEMP_Unit = GetEnumUnit()
    endif
endfunction

function GetPlayerHero takes integer id returns unit

//why isn't this just a static variable reference? because it
//used to be, and sometimes the ref would get lost and a player
//couldn't revive. i'm not taking any more chances.
//update: turns out that's not the bug. well fuck.

    local group grp

    if udg_FreeHero then
        return udg_HERO_Ref2[id]
    endif

    set udg_TEMP_Unit = null
    if IsPlayerInForce(ConvertedPlayer(id), udg_Force[1]) then
        set grp = GetUnitsOfPlayerAll(ConvertedPlayer(id))
        call ForGroupBJ(grp, function GetPlayerHeroEnum )
        call DestroyGroup(grp)
    endif

    set udg_HERO_Ref2[id] = udg_TEMP_Unit

    return udg_TEMP_Unit
endfunction





//keepalive

function KeepAliveUnit takes unit un returns nothing
    local integer i

    if IsUnitInGroup(un, udg_KA_Group) then
        set i = 1
        loop
            exitwhen i > 1000

            if udg_KA_Unit[i] == un then
                call DestroyTextTagBJ( udg_KA_Text[i] )
                call GroupRemoveUnitSimple( un, udg_KA_Group )
                set udg_KA_Unit[i] = null
                set udg_KA_Text[i] = null
                set i = 1000
            endif

            set i = i + 1
        endloop

    else
        call GroupAddUnitSimple( un, udg_KA_Group )
        call CreateTextTagUnitBJ( "KA", un, 0, 10, 100, 100, 100, 0 )
        call ShowTextTagForceBJ( false, GetLastCreatedTextTag(), udg_Force[1] )
        call ShowTextTagForceBJ( true, GetLastCreatedTextTag(), udg_Force[2] )

        set i = 1
        loop
            exitwhen i > 1000

            if udg_KA_Unit[i] == null then
                set udg_KA_Unit[i] = un
                set udg_KA_Text[i] = GetLastCreatedTextTag()
                set i = 1000
            endif

            set i = i + 1
        endloop
    endif
endfunction

function RemoveKeepAliveUnit takes unit un returns nothing
    if IsUnitInGroup(un, udg_KA_Group) then
        call KeepAliveUnit(un)
    endif
endfunction








//gamename translator

function AddTranslate takes string strfrom, string strto returns nothing
    set udg_TranslateTotal = udg_TranslateTotal + 1

    set udg_TranslateFrom[udg_TranslateTotal] = strfrom
    set udg_TranslateTo[udg_TranslateTotal] = strto
endfunction

function InitTranslator takes nothing returns nothing

    set udg_TranslateTotal = 0

    call AddTranslate("custom_h00B", "trainingroom")
    call AddTranslate("custom_h00B", "trainroom")
    call AddTranslate("custom_n001", "fountain")
    call AddTranslate("custom_n001", "fountainofhealth") //prevent creation of regular fountains
    call AddTranslate("custom_n001", "fountainofmana")
    call AddTranslate("custom_n001", "fountainoflife")
    call AddTranslate("custom_n001", "fountainofrejuvenation")

    call AddTranslate("custom_h004", "barn")
    call AddTranslate("custom_h003", "haycart")
    call AddTranslate("custom_h002", "windmill")

    call AddTranslate("custom_n00B", "questshop1")
    call AddTranslate("custom_n00C", "questshop2")
    call AddTranslate("custom_n002", "itemshop")
    call AddTranslate("custom_n00J", "blacksmith1")
    call AddTranslate("custom_n00D", "blacksmith2")
    call AddTranslate("custom_n00L", "blacksmith3")
    call AddTranslate("custom_n00E", "haven1")
    call AddTranslate("custom_n003", "haven2")
    call AddTranslate("custom_n00K", "haven3")
    call AddTranslate("custom_n00N", "tower1")
    call AddTranslate("custom_n007", "tower2")
    call AddTranslate("custom_n00M", "tower3")

    call AddTranslate("custom_H007", "elvenarcher")
    call AddTranslate("custom_H000", "elvencleric")
    call AddTranslate("custom_H001", "humanswordsman")
    call AddTranslate("custom_H005", "humanmage")
    call AddTranslate("custom_H008", "dwarvenwarrior")
    call AddTranslate("custom_H009", "dwarvenrifleman")

    call AddTranslate("custom_E005", "ancientofthunder")
    call AddTranslate("custom_E004", "ancientofstone")
    call AddTranslate("custom_E006", "nightelfdruid")
    call AddTranslate("custom_H00A", "nightelfgiant")
    call AddTranslate("custom_E003", "nightelfarcher")
    call AddTranslate("custom_E001", "nightelfslayer")

    call AddTranslate("custom_O001", "taurenbrute")
    call AddTranslate("custom_O004", "orcshaman")
    call AddTranslate("custom_O000", "orcsamurai")
    call AddTranslate("custom_O006", "orcwarlock")
    call AddTranslate("custom_O002", "trollranger")
    call AddTranslate("custom_O003", "trollpriest")

    call AddTranslate("custom_U002", "undeadbanshee")
    call AddTranslate("custom_U000", "skeletalsummoner")
    call AddTranslate("custom_N004", "undeadranger")
    call AddTranslate("custom_N005", "skeletalarcher")
    call AddTranslate("custom_U001", "undeadvampire")
    call AddTranslate("custom_U003", "skeletalbaron")

    call AddTranslate("custom_", "")

endfunction


function TranslateTo takes string str returns string
    local integer i

    set i = 1
    loop
        exitwhen i > udg_TranslateTotal
        if str == udg_TranslateFrom[i] then
            return udg_TranslateTo[i]
        endif
        set i = i + 1
    endloop

    return str
endfunction

function TranslateFrom takes string str returns string
    local integer i

    set i = 1
    loop
        exitwhen i > udg_TranslateTotal
        if str == udg_TranslateTo[i] then
            return udg_TranslateFrom[i]
        endif
        set i = i + 1
    endloop

    return str
endfunction


function isShop takes integer i returns boolean
    if i == 'n002' then //item shop
    elseif i == 'n00B' then //quest shops
    elseif i == 'n00C' then
    elseif i == 'n00J' then //blacksmiths
    elseif i == 'n00D' then
    elseif i == 'n00L' then
    elseif i == 'n00E' then //havens
    elseif i == 'n003' then
    elseif i == 'n00K' then
    elseif i == 'n00N' then //towers
    elseif i == 'n007' then
    elseif i == 'n00M' then
    else
        return false
    endif
    return true
endfunction










//items

function DropCoin takes location pt, integer level returns nothing
    if level <= 1 then
        call CreateItemLoc( 'I002', pt )
    elseif level == 2 then
        call CreateItemLoc( 'I003', pt )
    elseif level == 3 then
        call CreateItemLoc( 'I004', pt )
    elseif level == 4 then
        call CreateItemLoc( 'I005', pt )
    elseif level == 5 then
        call CreateItemLoc( 'I006', pt )
    elseif level == 6 then
        call CreateItemLoc( 'I007', pt )
    elseif level == 7 then
        call CreateItemLoc( 'I008', pt )
    elseif level == 8 then
        call CreateItemLoc( 'I009', pt )
    elseif level == 9 then
        call CreateItemLoc( 'I00A', pt )
    elseif level >= 10 then
        call CreateItemLoc( 'I00B', pt )
    endif
endfunction

function RandomItemDrop takes integer lvl returns integer

//currently ignore lvl

    local integer junk
    set junk = GetRandomInt(1,6)

    if junk == 1 then
        return 'manh'
    elseif junk == 2 then
        return 'tstr'
    elseif junk == 3 then
        return 'tdex'
    elseif junk == 4 then
        return 'tint'
    elseif junk == 5 then
        return 'tpow'
    elseif junk == 6 then
        return 'texp'
    endif

    return 0

endfunction











//doodads

//    call CreateDestructableLoc( 'ATtr', GetRectCenter(GetPlayableMapRect()), GetRandomDirectionDeg(), 1, 0 )
//    call CreateDestructableLoc( 'BTtw', GetRectCenter(GetPlayableMapRect()), GetRandomDirectionDeg(), 1, 0 )
//    call CreateDestructableLoc( 'ITtw', GetRectCenter(GetPlayableMapRect()), GetRandomDirectionDeg(), 1, 0 )


function IsBridge takes destructable d returns boolean

    local integer dt
    set dt = GetDestructableTypeId(d)

    if     dt == 'LT06' then
        return true
    elseif dt == 'LT04' then
        return true
    elseif dt == 'LT05' then
        return true
    elseif dt == 'LT07' then
        return true

    elseif dt == 'YT18' then
        return true
    elseif dt == 'YT16' then
        return true
    elseif dt == 'YT17' then
        return true
    elseif dt == 'YT43' then
        return true

    elseif dt == 'B005' then
        return true
    elseif dt == 'B007' then
        return true
    elseif dt == 'B001' then
        return true
    elseif dt == 'B003' then
        return true

    elseif dt == 'B004' then
        return true
    elseif dt == 'B006' then
        return true
    elseif dt == 'B000' then
        return true
    elseif dt == 'B002' then
        return true

    endif

    return false

endfunction



function IsGate takes destructable d returns boolean

    local integer dt
    set dt = GetDestructableTypeId(d)

    if     dt == 'LTg1' then
        return true
    elseif dt == 'LTg3' then
        return true
    elseif dt == 'LTg2' then
        return true
    elseif dt == 'LTg4' then
        return true

    elseif dt == 'LTe1' then
        return true
    elseif dt == 'LTe3' then
        return true
    elseif dt == 'LTe2' then
        return true
    elseif dt == 'LTe4' then
        return true

    elseif dt == 'ATg1' then
        return true
    elseif dt == 'ATg3' then
        return true
    elseif dt == 'ATg2' then
        return true
    elseif dt == 'ATg4' then
        return true

    endif

    return false

endfunction



function MakeGate takes location pt, integer typ, integer dir returns nothing

    if typ == 1 then
        //gate
        if dir == 1 then
            call CreateDestructableLoc( 'LTg1', pt, GetRandomDirectionDeg(), 1, 0 )
        elseif dir == 2 then
            call CreateDestructableLoc( 'LTg2', pt, GetRandomDirectionDeg(), 1, 0 )
        elseif dir == 3 then
            call CreateDestructableLoc( 'LTg3', pt, GetRandomDirectionDeg(), 1, 0 )
        elseif dir == 4 then
            call CreateDestructableLoc( 'LTg4', pt, GetRandomDirectionDeg(), 1, 0 )
        endif
    elseif typ == 2 then
        //elvengate
        if dir == 1 then
            call CreateDestructableLoc( 'LTe1', pt, GetRandomDirectionDeg(), 1, 0 )
        elseif dir == 2 then
            call CreateDestructableLoc( 'LTe2', pt, GetRandomDirectionDeg(), 1, 0 )
        elseif dir == 3 then
            call CreateDestructableLoc( 'LTe3', pt, GetRandomDirectionDeg(), 1, 0 )
        elseif dir == 4 then
            call CreateDestructableLoc( 'LTe4', pt, GetRandomDirectionDeg(), 1, 0 )
        endif
    elseif typ == 3 then
        //demonicgate
        if dir == 1 then
            call CreateDestructableLoc( 'ATg1', pt, GetRandomDirectionDeg(), 1, 0 )
        elseif dir == 2 then
            call CreateDestructableLoc( 'ATg2', pt, GetRandomDirectionDeg(), 1, 0 )
        elseif dir == 3 then
            call CreateDestructableLoc( 'ATg3', pt, GetRandomDirectionDeg(), 1, 0 )
        elseif dir == 4 then
            call CreateDestructableLoc( 'ATg4', pt, GetRandomDirectionDeg(), 1, 0 )
        endif
    endif

    call SetDestructableInvulnerableBJ( GetLastCreatedDestructable(), true )

endfunction





function MakeWall takes location pt, integer typ, integer dir returns nothing

    if typ == 1 then
        //gate
        if dir == 1 then
            call CreateDestructableLoc( 'LTw0', pt, GetRandomDirectionDeg(), 1, 2 )
        elseif dir == 2 then
            call CreateDestructableLoc( 'LTw3', pt, GetRandomDirectionDeg(), 1, 2 )
        elseif dir == 3 then
            call CreateDestructableLoc( 'LTw2', pt, GetRandomDirectionDeg(), 1, 2 )
        elseif dir == 4 then
            call CreateDestructableLoc( 'LTw1', pt, GetRandomDirectionDeg(), 1, 2 )
        endif
    endif

    call SetDestructableInvulnerableBJ( GetLastCreatedDestructable(), true )

endfunction

function MakeWallXY takes real x, real y, integer typ, integer dir returns nothing
    local location loc
    set loc = Location(x,y)
    call MakeWall(loc, typ, dir)
    call RemoveLocation(loc)
    set loc = null
endfunction



function AngleToDirNum takes real theta returns integer
    if GetBooleanAnd(-22.5 <= theta, theta < 22.5) then
        return 3 //vert
    elseif GetBooleanAnd(22.5 <= theta, theta < 67.5) then
        return 4 //diag2
    elseif GetBooleanAnd(-67.5 <= theta, theta < 22.5) then
        return 2 //diag1
    elseif GetBooleanAnd(67.5 <= theta, theta < 112.5) then
        return 1 //horiz
    elseif GetBooleanAnd(-112.5 <= theta, theta < -67.5) then
        return 1
    elseif GetBooleanAnd(112.5 <= theta, theta < 157.5) then
        return 2
    elseif GetBooleanAnd(-157.5 <= theta, theta < -112.5) then
        return 4
    else
        return 3
    endif
    return -1
endfunction

function AngleToDirNumWrap takes real junk returns integer
    local real theta
    set theta = junk
    if theta >= 180 then
        set theta = theta - 360
    endif
    return AngleToDirNum(theta)
endfunction

function FindFacingDir takes location pt, location target returns integer
    return AngleToDirNum(AngleBetweenPoints(pt, target))
endfunction

function FindAlignmentDir takes location pt, location target returns integer
    local real theta
    set theta = AngleBetweenPoints(pt, target) + 90
    if theta >= 180 then
        set theta = theta - 360
    endif
    return AngleToDirNum(theta)
endfunction


//    call CreateDestructableLoc( 'LTg1', GetRectCenter(GetPlayableMapRect()), GetRandomDirectionDeg(), 1, 0 )
//    call CreateDestructableLoc( 'LTg3', GetRectCenter(GetPlayableMapRect()), GetRandomDirectionDeg(), 1, 0 )
//    call CreateDestructableLoc( 'LTg2', GetRectCenter(GetPlayableMapRect()), GetRandomDirectionDeg(), 1, 0 )
//    call CreateDestructableLoc( 'LTg4', GetRectCenter(GetPlayableMapRect()), GetRandomDirectionDeg(), 1, 0 )


function DrawWallLine takes location pt, location target returns nothing
    local real xmult
    local real ymult
    local real theta
    local integer dir

    local real curlen
    local real totlen
    local real lenmult

    local real x = GetLocationX(pt)
    local real y = GetLocationY(pt)
    local real xt = GetLocationX(target)
    local real yt = GetLocationY(target)

    set theta = AngleBetweenPoints(pt, target)
    set dir = AngleToDirNumWrap(theta + 90)
    set totlen = DistanceBetweenPoints(pt,target)

    if theta < -112.5 or theta > 112.5 then
        set xmult = -1
    elseif theta < 67.5 and theta > -67.5 then
        set xmult = 1
    else
        set xmult = 0
    endif
    if theta < 157.5 and theta > 22.5 then
        set ymult = 1
    elseif theta < -22.5 and theta > -157.5 then
        set ymult = -1
    else
        set ymult = 0
    endif

    set x = x + 160 * xmult
    set y = y + 160 * ymult
    set lenmult = SquareRoot(Pow(xmult*320, 2.00) + Pow(ymult*320, 2.00))
    set curlen = lenmult/2

    loop
        if not(RectContainsCoords(gg_rct_DMarea, x, y)) then
            call MakeWallXY(x,y,1,dir)
        endif
        set x = x + 320 * xmult
        set y = y + 320 * ymult
        set curlen = curlen + lenmult
        exitwhen curlen >= totlen
    endloop

//    call DisplayTextToForce( GetPlayersAll(), R2S(theta) )
//    call DisplayTextToForce( GetPlayersAll(), R2S(xmult) + "  " + R2S(ymult) )
endfunction









function FindNearbyGateEnum takes nothing returns nothing
    local location pt
    set pt = GetDestructableLoc(GetEnumDestructable())
    if IsGate(GetEnumDestructable()) then
        if DistanceBetweenPoints(udg_TEMP_Location, pt) < udg_TEMP_Real then
            set udg_TEMP_Destructible = GetEnumDestructable()
            set udg_TEMP_Real = DistanceBetweenPoints(udg_TEMP_Location, pt)
        endif
    endif
    call RemoveLocation(pt)
endfunction

function FindNearbyGate takes location pt returns destructable
    set udg_TEMP_Real = 1000000
    set udg_TEMP_Destructible = null
    set udg_TEMP_Location = pt
    call EnumDestructablesInCircleBJ( 1000.00, pt, function FindNearbyGateEnum )
    return udg_TEMP_Destructible
endfunction

function BridgeDirection takes destructable d returns integer

    local integer dt
    set dt = GetDestructableTypeId(d)

    if     dt == 'LT06' then
        return 3
    elseif dt == 'LT04' then
        return 4
    elseif dt == 'LT05' then
        return 1
    elseif dt == 'LT07' then
        return 2

    elseif dt == 'YT18' then
        return 3
    elseif dt == 'YT16' then
        return 4
    elseif dt == 'YT17' then
        return 1
    elseif dt == 'YT43' then
        return 2

    elseif dt == 'B005' then
        return 3
    elseif dt == 'B007' then
        return 4
    elseif dt == 'B001' then
        return 1
    elseif dt == 'B003' then
        return 2
    elseif dt == 'B004' then
        return 3
    elseif dt == 'B006' then
        return 4
    elseif dt == 'B000' then
        return 1
    elseif dt == 'B002' then
        return 2

    endif

    return -1

endfunction

function GetBridgeTypeAtPt takes location pt returns integer

    if RectContainsLoc(gg_rct_Forest, pt) then
        return 0
    elseif RectContainsLoc(gg_rct_Snow, pt) then
        return 2
    elseif RectContainsLoc(gg_rct_Desert, pt) then
        return 1

    elseif RectContainsLoc(gg_rct_Blend_Desert_Snow, pt) then
        if GetRectMinX(gg_rct_Blend_Desert_Snow) + GetRectMaxX(gg_rct_Blend_Desert_Snow) >= GetLocationX(pt) * 2 then
            return 1
        else
            return 2
        endif

    elseif RectContainsLoc(gg_rct_Blend_Desert_Forest, pt) then
        if GetRectMinY(gg_rct_Blend_Desert_Forest) + GetRectMaxY(gg_rct_Blend_Desert_Forest) <= GetLocationY(pt) * 2 then
            return 1
        else
            return 0
        endif

    elseif RectContainsLoc(gg_rct_Blend_Forest_Snow, pt) then
        if GetRectMinY(gg_rct_Blend_Forest_Snow) + GetRectMaxY(gg_rct_Blend_Forest_Snow) <= GetLocationY(pt) * 2 then
            return 2
        else
            return 0
        endif

    elseif RectContainsLoc(gg_rct_Blend_Middle, pt) then
        if GetRectMinY(gg_rct_Blend_Middle) + GetRectMaxY(gg_rct_Blend_Middle) <= GetLocationY(pt) * 2 then
            if GetRectMinX(gg_rct_Blend_Middle) + GetRectMaxX(gg_rct_Blend_Middle) >= GetLocationX(pt) * 2 then
                return 1
            else
                return 2
            endif
        else
            return 0
        endif

    else
        return 0
    endif
endfunction

function GetBridge takes integer typ, integer facing, location loc returns integer
    local integer var

    if typ == 0 then
        //wooden bridge

        if facing == 3 then
            return 'LT06'
        elseif facing == 4 then
            return 'LT04' 
        elseif facing == 1 then
            return 'LT05' 
        elseif facing == 2 then
            return 'LT07' 
        endif
    elseif typ == 1 then
        //stone bridge
        set var = GetBridgeTypeAtPt(loc)
        if var == 0 then
            //ashenvale
            if facing == 3 then
                return 'YT18'
            elseif facing == 4 then
                return 'YT16' 
            elseif facing == 1 then
                return 'YT17' 
            elseif facing == 2 then
                return 'YT43' 
            endif
        elseif var == 1 then
            //barrens
            if facing == 3 then
                return 'B005' 
            elseif facing == 4 then
                return 'B007' 
            elseif facing == 1 then
                return 'B001' 
            elseif facing == 2 then
                return 'B003' 
            endif
        elseif var == 2 then
            //winter
            if facing == 3 then
                return 'B004' 
            elseif facing == 4 then
                return 'B006' 
            elseif facing == 1 then
                return 'B000' 
            elseif facing == 2 then
                return 'B002' 
            endif
        endif
    endif

    return 0

endfunction


function FindNearbyBridgeEnum takes nothing returns nothing
    local location pt
    set pt = GetDestructableLoc(GetEnumDestructable())
    if IsBridge(GetEnumDestructable()) then
        if DistanceBetweenPoints(udg_TEMP_Location, pt) < udg_TEMP_Real then
            set udg_TEMP_Destructible = GetEnumDestructable()
            set udg_TEMP_Real = DistanceBetweenPoints(udg_TEMP_Location, pt)
        endif
    endif
    call RemoveLocation(pt)
endfunction

function FindNearbyBridge takes location pt returns destructable
    set udg_TEMP_Real = 1000000
    set udg_TEMP_Destructible = null
    set udg_TEMP_Location = pt
    call EnumDestructablesInCircleBJ( 1000.00, pt, function FindNearbyBridgeEnum )
    return udg_TEMP_Destructible
endfunction

function MakeBridge takes integer typ, location pt returns integer
    local destructable d
    local location loc
    local integer f

    set d = FindNearbyBridge(pt)
    if d == null then
        return -1
    else
        set loc = GetDestructableLoc(d)
        set f = BridgeDirection(d)
        call RemoveDestructable(d)
        call CreateDestructableLoc( GetBridge(typ,f,loc), loc, GetRandomDirectionDeg(), 1, 0 )
        call KillDestructable( GetLastCreatedDestructable() )
        call DestructableRestoreLife( GetLastCreatedDestructable(), GetDestructableMaxLife(GetEnumDestructable()), true)
        call RemoveLocation(loc)
    endif
    return 0
endfunction










function GetDoodadVariation takes integer dd returns integer
    if dd == 'ATtr' then
        return GetRandomInt(0, 4)
    else
        return GetRandomInt(0, 9)
    endif
    return 0
endfunction

function GetDoodadTypeAtPT takes location pt returns integer

    local real dd
    local real df
    local real ds
    local real dg
    local real rnd


    if RectContainsLoc(gg_rct_Forest, pt) then
        return 'ATtr'
    elseif RectContainsLoc(gg_rct_Snow, pt) then
        return 'ITtw'
    elseif RectContainsLoc(gg_rct_Desert, pt) then
        return 'BTtw'


    elseif RectContainsLoc(gg_rct_Blend_Desert_Snow, pt) then

        //set dd = GetLocationX(pt) - GetRectMinX(gg_rct_Blend_Desert_Snow)
        //set tt = GetRectMaxX(gg_rct_Blend_Desert_Snow) - GetRectMinX(gg_rct_Blend_Desert_Snow)

        //increase fill count 1 extra because this takes longer to calculate
        set udg_GUI_Misc_DoodadFillCount = udg_GUI_Misc_DoodadFillCount + 1
        if GetRandomReal(GetRectMinX(gg_rct_Blend_Desert_Snow), GetRectMaxX(gg_rct_Blend_Desert_Snow)) >= GetLocationX(pt) then
            return 'BTtw'
        else
            return 'ITtw'
        endif


    elseif RectContainsLoc(gg_rct_Blend_Desert_Forest, pt) then

        set udg_GUI_Misc_DoodadFillCount = udg_GUI_Misc_DoodadFillCount + 1
        if GetRandomReal(GetRectMinY(gg_rct_Blend_Desert_Forest), GetRectMaxY(gg_rct_Blend_Desert_Forest)) <= GetLocationY(pt) then
            return 'BTtw'
        else
            return 'ATtr'
        endif


    elseif RectContainsLoc(gg_rct_Blend_Forest_Snow, pt) then

        set udg_GUI_Misc_DoodadFillCount = udg_GUI_Misc_DoodadFillCount + 1
        if GetRandomReal(GetRectMinY(gg_rct_Blend_Forest_Snow), GetRectMaxY(gg_rct_Blend_Forest_Snow)) <= GetLocationY(pt) then
            return 'ITtw'
        else
            return 'ATtr'
        endif


    elseif RectContainsLoc(gg_rct_Blend_Middle, pt) then

        //increase fill count 2 extra because this takes much longer to calculate
        set udg_GUI_Misc_DoodadFillCount = udg_GUI_Misc_DoodadFillCount + 2

        if GetRandomReal(GetRectMinY(gg_rct_Blend_Middle), GetRectMaxY(gg_rct_Blend_Middle)) <= GetLocationY(pt) then
            if GetRandomReal(GetRectMinX(gg_rct_Blend_Middle), GetRectMaxX(gg_rct_Blend_Middle)) >= GetLocationX(pt) then
                return 'BTtw'
            else
                return 'ITtw'
            endif
        else
            return 'ATtr'
        endif

    
    else
        return 'ATtr'
    endif
endfunction

function DoodadFillArea takes rect area, boolean circle returns nothing

    local real inc = 150
    local real x
    local real y
    local location pt
    local integer dd

    //normalize value to multiple of 150 of world coords to prevent tree seams
    set x = I2R(R2I(GetRectMinX(area) / 150)) * 150
    loop
        exitwhen x > GetRectMaxX(area)
        set y = I2R(R2I(GetRectMinY(area) / 150)) * 150
        loop
            exitwhen y > GetRectMaxY(area)
                set pt = Location(x + GetRandomReal(-inc/5, inc/5),y + GetRandomReal(-inc/5, inc/5) + ModuloInteger(R2I(x / inc), 2) * inc / 2)
                set dd = GetDoodadTypeAtPT(pt)

                if GetBooleanOr(not(circle), DistanceBetweenPoints(pt, GetRectCenter(area)) <= (GetRectMaxX(area) - GetRectMinX(area))/2) then

                    call CreateDestructableLoc( dd, pt, GetRandomDirectionDeg(), 1, GetDoodadVariation(dd) )
                    call KillDestructable( GetLastCreatedDestructable() )
                    call DestructableRestoreLife( GetLastCreatedDestructable(), GetDestructableMaxLife(GetLastCreatedDestructable()), true )

                    if DistanceBetweenPoints(GetDestructableLoc(GetLastCreatedDestructable()), pt) > 100 then
                        call RemoveDestructable(GetLastCreatedDestructable())
                    endif
                endif

                //(prevent trigger from being stopped and prevent game desync(<-?))
                set udg_GUI_Misc_DoodadFillCount = udg_GUI_Misc_DoodadFillCount + 1
                if udg_GUI_Misc_DoodadFillCount > 500 then
                    set udg_GUI_Misc_DoodadFillCount = 0
                    call TriggerSleepAction(0)
                endif
                call RemoveLocation(pt)
            set y = y + inc
        endloop
        set x = x + inc
    endloop

endfunction

















//cam


function GUIApplyCamForDM takes player pl returns nothing
    //incomplete (zooming not yet done)
    //call CameraSetupApplyForPlayer( true, gg_cam_ZoomOutCam, pl, 0.0 )

    call SetCameraFieldForPlayer( pl, CAMERA_FIELD_ROTATION, CameraSetupGetFieldSwap(CAMERA_FIELD_ANGLE_OF_ATTACK, gg_cam_ZoomOutCam), 1.00 )
    call SetCameraFieldForPlayer( pl, CAMERA_FIELD_ANGLE_OF_ATTACK, CameraSetupGetFieldSwap(CAMERA_FIELD_ANGLE_OF_ATTACK, gg_cam_ZoomOutCam), 0.00 )
    call SetCameraFieldForPlayer( pl, CAMERA_FIELD_TARGET_DISTANCE, CameraSetupGetFieldSwap(CAMERA_FIELD_TARGET_DISTANCE, gg_cam_ZoomOutCam), 0.00 )
    call SetCameraFieldForPlayer( pl, CAMERA_FIELD_FIELD_OF_VIEW, CameraSetupGetFieldSwap(CAMERA_FIELD_FIELD_OF_VIEW, gg_cam_ZoomOutCam), 0.00 )
    call SetCameraFieldForPlayer( pl, CAMERA_FIELD_FARZ, CameraSetupGetFieldSwap(CAMERA_FIELD_FARZ, gg_cam_ZoomOutCam), 0 )
    call SetCameraFieldForPlayer( pl, CAMERA_FIELD_ROLL, CameraSetupGetFieldSwap(CAMERA_FIELD_ROLL, gg_cam_ZoomOutCam), 0 )
    call SetCameraFieldForPlayer( pl, CAMERA_FIELD_ROTATION, CameraSetupGetFieldSwap(CAMERA_FIELD_ROTATION, gg_cam_ZoomOutCam), 0 )
endfunction


function GUIApplyZoomForDM takes player pl returns nothing
    //boobies
endfunction










//spell

function MakeFirePatch takes player pl, integer lvl, location p, real dur returns nothing
    call CreateNUnitsAtLoc( 1, 'n006', pl, GetRandomLocInRect(gg_rct_Dummy_Casters), bj_UNIT_FACING )
    //call DisplayTextToForce( GetPlayersAll(), I2S(lvl) )
    if lvl == 1 then
        call UnitAddAbilityBJ( 'A00R', GetLastCreatedUnit() )
    elseif lvl == 2 then
        call UnitAddAbilityBJ( 'A00S', GetLastCreatedUnit() )
    elseif lvl == 3 then
        call UnitAddAbilityBJ( 'A00Q', GetLastCreatedUnit() )
    endif
    call UnitApplyTimedLifeBJ( dur, 'BTLF', GetLastCreatedUnit() )
    call SetUnitVertexColorBJ( GetLastCreatedUnit(), 100, 100, 100, 100.00 )
    call IssuePointOrderLocBJ( GetLastCreatedUnit(), "rainoffire", p )
endfunction






//gen

function ClearScreen takes nothing returns nothing
    local integer i
    set i = 1
    loop
        exitwhen i > 20
        call DisplayTextToForce(GetPlayersAll(), " ")
        set i = i + 1
    endloop
endfunction

function ClearScreenForce takes force fp returns nothing
    local integer i
    set i = 1
    loop
        exitwhen i > 20
        call DisplayTextToForce(fp, " ")
        set i = i + 1
    endloop
endfunction

function ColorName takes string name, integer id returns string
    if (id == 1) then
        return "|c00FF0000" + name + "|r"
    elseif (id == 2) then
        return "|c000040FF" + name + "|r"
    elseif (id == 3) then
        return "|c0000FFBF" + name + "|r"
    elseif (id == 4) then
        return "|c003F007F" + name + "|r"
    elseif (id == 5) then
        return "|c00FFFF00" + name + "|r"
    elseif (id == 6) then
        return "|c00FF7F00" + name + "|r"
    elseif (id == 7) then
        return "|c0000BF00" + name + "|r"
    elseif (id == 8) then
        return "|c00FF3FFF" + name + "|r"
    elseif (id == 9) then
        return "|c00A0A0A0" + name + "|r"
    elseif (id == 10) then
        return "|c007FBFFF" + name + "|r"
    elseif (id == 11) then
        return "|c000F5F3F" + name + "|r"
    elseif (id == 12) then
        return "|c004F2700" + name + "|r"
    else
        return "|c00303030" + name + "|r"
    endif
    //-Vuen
endfunction

function ColorNamePl takes player pl returns string
    return ColorName(GetPlayerName(pl), GetConvertedPlayerId(pl))
endfunction

function CountEnum takes nothing returns nothing
    set udg_TEMP_Integer = udg_TEMP_Integer + 1
endfunction

function PauseEnumUnit takes nothing returns nothing
    call PauseUnitBJ( false, GetEnumUnit() )
endfunction

function KillEnumUnit takes nothing returns nothing
    call KillUnit( GetEnumUnit() )
endfunction

function RemoveEnumUnit takes nothing returns nothing
    call RemoveUnit( GetEnumUnit() )
endfunction

function isWard takes unit un returns boolean
    if GetUnitName(un) == "Healing Ward" then
        return true
    elseif GetUnitName(un) == "Serpent Ward" then
        return true
    elseif GetUnitName(un) == "Sentry Ward" then
        return true
    endif
    return false
endfunction

function isDummy takes unit un returns boolean
    if GetUnitTypeId(un) == 'n006' then
        return true
    endif
    return false
endfunction










//train

//not a mirror, summoned, a dummy, a flag, a ward, a structure, or dead
function IsCountableTrainUnit takes unit un returns boolean
    if IsUnitIllusionBJ(un) then
        return false
    elseif IsUnitType(un, UNIT_TYPE_SUMMONED) then
        return false
    elseif isDummy(un) then
        return false
    elseif GetUnitTypeId(un) == 'h00B' then //training flag
        return false
    elseif isWard(un) then
        return false
    elseif not(IsUnitAliveBJ(un)) then
        return false
    elseif IsUnitType(un, UNIT_TYPE_STRUCTURE) then
        return false
    endif
    return true
endfunction

//is a training unit, and not a dummy, a flag, a ward, a structure, or dead
function IsKillableTrainUnit takes unit un returns boolean
    if not(IsUnitTrain(un)) then
        return false
    elseif isDummy(un) then
        return false
    elseif GetUnitTypeId(un) == 'h00B' then //training flag
        return false
    elseif isWard(un) then
        return false
    elseif not(IsUnitAliveBJ(un)) then
        return false
    elseif IsUnitType(un, UNIT_TYPE_STRUCTURE) then
        return false
    endif
    return true
endfunction











//math or numerical

function ICap takes integer val, integer low, integer high returns integer
    return IMaxBJ(IMinBJ(val, high), low)
endfunction

function RCap takes real val, real low, real high returns real
    return RMaxBJ(RMinBJ(val, high), low)
endfunction

function GetArrayMega takes integer i returns integer
    return (i - ModuloInteger(i, 10)) / 10    //gets high on 2d base10 array
endfunction

function RShuffle takes real val returns real //random within 1/7 of val
    return val + GetRandomReal(-val/7, val/7)
endfunction

function IShuffle takes integer val returns integer
    return R2I(RShuffle(I2R(val)))
endfunction

function RBigShuffle takes real val returns real //random within 1/5 of val
    return val + GetRandomReal(-val/5, val/5)
endfunction

function IBigShuffle takes integer val returns integer
    return R2I(RBigShuffle(I2R(val)))
endfunction

function IsANumber takes string str returns boolean
    //Couldn't really think of a simpler way to do this
    if (str == "0") then
        return true        
    elseif (str == "1") then
        return true
    elseif (str == "2") then
        return true
    elseif (str == "3") then
        return true
    elseif (str == "4") then
        return true
    elseif (str == "5") then
        return true
    elseif (str == "6") then
        return true
    elseif (str == "7") then
        return true
    elseif (str == "8") then
        return true
    elseif (str == "9") then
        return true
    endif
    return false
endfunction


function GetPlayerNumFromStr takes string text returns integer
    local integer i
    if text == "red" then
        return 1
    elseif text == "enemy" then
        return 1
    elseif text == "blue" then
        return 2
    elseif text == "teal" then
        return 3
    elseif text == "purple" then
        return 4
    elseif text == "yellow" then
        return 5
    elseif text == "ally" then
        return 5
    elseif text == "orange" then
        return 6
    elseif text == "green" then
        return 7
    elseif text == "pink" then
        return 8
    elseif text == "grey" then
        return 9
    elseif text == "gray" then
        return 9
    elseif text == "cyan" then
        return 10
    elseif text == "lightblue" then
        return 10
    elseif text == "lb" then
        return 10
    elseif text == "darkgreen" then
        return 11
    elseif text == "dg" then
        return 11
    elseif text == "brown" then
        return 12
    elseif text == "black" then
        return 13
    else
        set i = S2I(text)
        if i < 1 or i > 13 then
            return -1
        endif
        return i
    endif
    return -1
endfunction

function GetPlayerNumFromStrSafe takes string text returns integer
    local integer i
    set i = GetPlayerNumFromStr(text)
    if i == -1 then
        return 13
    endif
    return i
endfunction


//other

function CropText takes string bla returns string
    return bla
endfunction

function CenterText takes string bla returns string
    return bla
endfunction
Name Type Is Array Initial Value
asdgdfag rect No
Board leaderboard Yes
BonusAbility abilcode Yes
BOOT_Dialog dialog No
BOOT_DialogNo button No
BOOT_DialogYes button No
DebugBoard multiboard No
DebugBoardCreated boolean No
DM_Destination location Yes
DM_DoodPt location Yes
DM_Misc integer Yes
DM_MiscBool boolean Yes
DM_MiscSub integer Yes
DM_Player player Yes
DM_SubType string Yes
DM_Unit unit Yes
DM_UnitType unitcode Yes
Force force Yes
FreeHero boolean No
GUI_Doodads_Click trigger No
GUI_Items_Click trigger No
GUI_Misc_Chat trigger No
GUI_Misc_DoodadFillCount integer No 0
GUI_Misc_Escape trigger No
GUI_Misc_Poll trigger No
GUI_Misc_Select trigger No
GUI_Pointer unit Yes
GUI_Pointer_Point trigger No
GUI_Pointer_Unit trigger No
GUI_Slider_Ref unit Yes
GUI_Tile unit Yes
GUI_Tile_Group group No
GUI_Units_Click trigger No
HERO_AllowDuplicates boolean No
HERO_ButtonText texttag Yes
HERO_FloatCam boolean Yes
HERO_IsDead boolean Yes
HERO_LastSel unit Yes
HERO_Ref2 unit Yes
HERO_Restrictor trigger No
HERO_Selection trigger No
KA_Group group No
KA_Text texttag Yes
KA_Unit unit Yes
MISC_Fountains group No
Names string Yes
Status string Yes
TEMP_Boolean boolean No
TEMP_Destructible destructable No
TEMP_Integer integer No
TEMP_Item item No
TEMP_Location location No
TEMP_Player player No
TEMP_Real real No
TEMP_RealArray real Yes
TEMP_Unit unit No
TRAIN_CountBad integer No
TRAIN_CountGood integer No
TRAIN_CountGoodTotal integer No
TRAIN_CurRoom unit No
TRAIN_Level real No
TRAIN_Rooms group No
TRAIN_Type unitcode Yes
TranslateFrom string Yes
TranslateTo string Yes
TranslateTotal integer No


IF YOU SAVE THIS MAP, IT WILL BREAK.


This map uses a modified TerrainArt/Terrain.slk to
generate the pathing map, which makes the 'fake
cliffs'
unwalkable. Saving will compute the pathing
map incorrectly, meaning units will be able to walk
over cliffs. It was left out of the map because it
doesn't actually work unless you extract it and
restart the editor, and to keep the file size small.

If you accidentally save, please delete it and e-mail
me for an original copy. I don'
t want people spreading
broken versions online. Stable release versions will be
save-locked.


If you'd like to make a modification to this map,
I'
d be more than happy to send you the required files
via e-mail, but please wait until the map exits the
beta testing stage first.



 -Vuen  (physicsnick@gmail.com)
 Or
 -Bringer_of_Pain (Regin_of_Blood@hotmail.com)


  #######################################
  #                                     #
  #       Vuen's D&D Crystal RPG        #
  #                                     #
  #     by  Nicholas Fraser  (Vuen)     #
  #        physicsnick@gmail.com        #
  #                                     #
  #######################################




Okay. This is the readme file for this map.

This map was done entirely in the official
TFT World Editor; no WE mod or JASS editor was
used, and the WE Enhancer was only used to
add cliff terrain tiles to the map.

Feel free to use anything you'd like from this
map, and e-mail me if you have any questions.
If you use any chunks of code verbatim or if
you use my custom models, please leave credit.

I have people criticize me often for calling
it a D&D when it does not use D&D rules. The
reason is because this map was originally called
DM'
s Land RPG, but no one knew what that meant.
The term RPG has a different connotation when
referring to video games, and it's not the
meaning I want; besides, this map follows in the
footsteps of Neverlax and QuatreDan'
s D&D maps,
so everyone knows what D&D refers to.

I hope you prefer the pointer over the spawner.
I know I do, and I certainly hope it replaces
spawners in all D&D and RP maps from now on.

Feel free to email me if you have any ideas,
comments, questions, or complaints about this
map, or even if you just want to say 'Hi'!
Your feedback is what makes this map possible.

Happy Roleplaying!

 
-- beta --
chats hidden, OOC
hero revive bug fixed (hopefully)
new commands
  immune
  tint
  color
  life
  damage
  armor
  give
bounty fixes
  summons no longer drop gold
  mirrors no longer duplicate items
training room fixes
  properly ignores summons, mirrors (finally)
  border does not kill non-training units, but they are still counted
  removing/killing kills all trainunits
spell fixes
  firewall no longer dispels blight
  summoned / controlled units automatically follow
added walls, line of walls
unit and building lumber costs removed
items
  item types, one per unit
  all custom items
  heroes cannot give items to other heroes
fixed sticky KA bug
added yet more dobrp/qdnd compatibility
palette additions
  fountain, trainroom, goldmine
added 'cast spell' ability


-- version 1.0 (beta58) --
original release
I always forget to update this readme, so
half of this is probably done by now. Here's
my '
planned features' list as of this writing:


  known bugs
currently none aside from minor fixes


  features
hero intro cinematic
dm camera functions
hurt func (damage)
ums/move func (move selected units)
item mover
make/remove hero flag
gold collected / assets leaderboard
kill everything at rightclick function


  minor fixes
fountain heal only allegiance
mountain giant tree damage
training remove nearby flag
show floating text only to DMs
head DM float
food limit
turn off ally town under siege
make gold drops bonus hp
neutral sharevis
trainflag death no bounty
set summons from trainunits to trainunit
make Lumber say Experience
fix lava spawns follow


  improvements
document commands directly on GUI
create units -> cam pos
select waygate ping
unit random city house, high elf house
trainkill no bounty
customval bits - invuln, train
blink smart unit/item -> blink, queue
blink not past gates/cliffs
blight/dispel manually +effect
naga units, tents (finish palette)


  hero balance
?


  hero ideas
priest ult wards -> mp/hp xtranquil
heal,ifire,rdead lvlskip
shaman - heal %
night elf blink


  abilities
undead phoenix->infernal
fireball/meteor
fire arrow (fireball, immolation)
vampire bite
lightning strike
smite evil (priest/cleric)
find potion


  items
weapons (one at a time)
caster items
gold


  doodads
energyfield
rain
fog
sickness
walls


  accessories:
helmet
glove
circlet/amulet
belt
boots
ring


  accessory can:
add attributes
add life/mana
move speed bonus
immolation
magic damage
aura
immune


  ideas
non-dm quests
player allegiance - bounty? (good/evil)
item crafting system
invuln all monsts
  overhead perm-invuln (attach list boolarray, unitarray, effectarray, largest)
  last unit locs: ptarray, boolarray, unitarray, count
hero build houses for respawn point
freeze gameplay (invuln all, stop+hold + ignore orders, reset abil cools)
message log
ka chance to die
follow
  waygate (poll dist?)
  blink
follow glob players?
mercs
  ally, ka (chance?), follow, noinv, match col
town portals
Changelog:

.5b - First test version:

 Added in 450k health/mana bonus functions.
 Set the attack damage bonus & armor bonus cap to 16k.
 Added in an attack speed bonus.
 Removed that little canadian flag in the loading screen to reduce loading time
 by a bit.

To do:

 .52b

  Replicate unit command. Pefectly replicates a unit. (Mods & all)
  Magic immunity command.
  Figure out the GUI setup -,-".
  Alter the amount of reduction armor gives.
  *Clear* ability. So you can clear all doodads/units nearby. (In a large radius)
  Lay out some additional doodads to place. (Maybe a whole pallet for them)

To fix:

 .50b - .52b

  No current glitchs known.

Note to self:
Widgitize realease versions to reduce loading time.



//*************************
//    checked for leaks
//*************************








//init






function doMainConstants takes nothing returns nothing

    set udg_Force[1] = CreateForce()
    set udg_Force[2] = CreateForce()
    set udg_Force[3] = CreateForce()

    call ForceAddPlayerSimple( ConvertedPlayer(2), udg_Force[1] )
    call ForceAddPlayerSimple( ConvertedPlayer(3), udg_Force[1] )
    call ForceAddPlayerSimple( ConvertedPlayer(4), udg_Force[1] )
    call ForceAddPlayerSimple( ConvertedPlayer(6), udg_Force[1] )
    call ForceAddPlayerSimple( ConvertedPlayer(7), udg_Force[1] )
    call ForceAddPlayerSimple( ConvertedPlayer(8), udg_Force[1] )
    call ForceAddPlayerSimple( ConvertedPlayer(12), udg_Force[1] )

    call ForceAddPlayerSimple( ConvertedPlayer(9), udg_Force[2] )
    call ForceAddPlayerSimple( ConvertedPlayer(10), udg_Force[2] )
    call ForceAddPlayerSimple( ConvertedPlayer(11), udg_Force[2] )

    call ForceAddPlayerSimple( ConvertedPlayer(1), udg_Force[3] )
    call ForceAddPlayerSimple( ConvertedPlayer(5), udg_Force[3] )

endfunction



function doDebugSharePlayerControl takes nothing returns nothing
    call SetPlayerAllianceBJ( GetEnumPlayer(), ALLIANCE_SHARED_CONTROL, true, ConvertedPlayer(9) )
    call SetPlayerAllianceBJ( GetEnumPlayer(), ALLIANCE_SHARED_CONTROL, true, ConvertedPlayer(10) )
    call SetPlayerAllianceBJ( GetEnumPlayer(), ALLIANCE_SHARED_CONTROL, true, ConvertedPlayer(11) )
    call SetPlayerAllianceBJ( GetEnumPlayer(), ALLIANCE_SHARED_ADVANCED_CONTROL, true, ConvertedPlayer(9) )
    call SetPlayerAllianceBJ( GetEnumPlayer(), ALLIANCE_SHARED_ADVANCED_CONTROL, true, ConvertedPlayer(10) )
    call SetPlayerAllianceBJ( GetEnumPlayer(), ALLIANCE_SHARED_ADVANCED_CONTROL, true, ConvertedPlayer(11) )
endfunction



function doInitPlayers takes nothing returns nothing

    //set exp rate
    call SetPlayerHandicapXPBJ( GetEnumPlayer(), 50.00 )

    //handle alliances:

    call SetPlayerAllianceStateAllyBJ ( GetEnumPlayer(), ConvertedPlayer(5), true )
    call SetPlayerAllianceStateAllyBJ ( ConvertedPlayer(5), GetEnumPlayer(), true )
    //call SetPlayerAllianceStateBJ( ConvertedPlayer(5), GetEnumPlayer(), bj_ALLIANCE_ALLIED )

    call SetPlayerAllianceStateBJ( ConvertedPlayer(9), GetEnumPlayer(), bj_ALLIANCE_ALLIED )
    call SetPlayerAllianceStateBJ( ConvertedPlayer(10), GetEnumPlayer(), bj_ALLIANCE_ALLIED )
    call SetPlayerAllianceStateBJ( ConvertedPlayer(11), GetEnumPlayer(), bj_ALLIANCE_ALLIED )

    //call doDebugSharePlayerControl()

endfunction



function doInitDMs takes nothing returns nothing

    call SetPlayerAllianceStateBJ( ConvertedPlayer(1), GetEnumPlayer(), bj_ALLIANCE_ALLIED )
    call SetPlayerAllianceStateBJ( ConvertedPlayer(2), GetEnumPlayer(), bj_ALLIANCE_ALLIED )

    call SetPlayerAllianceStateBJ( ConvertedPlayer(1), GetEnumPlayer(), bj_ALLIANCE_ALLIED_ADVUNITS )
    call SetPlayerAllianceStateBJ( ConvertedPlayer(5), GetEnumPlayer(), bj_ALLIANCE_ALLIED_ADVUNITS )

//    call SetPlayerAllianceBJ( GetEnumPlayer(), ALLIANCE_PASSIVE, true, ConvertedPlayer(1) )
//    call SetPlayerAllianceBJ( GetEnumPlayer(), ALLIANCE_PASSIVE, true, ConvertedPlayer(5) )

//    call SetPlayerAllianceBJ( GetEnumPlayer(), ALLIANCE_PASSIVE, false, ConvertedPlayer(2) )
//    call SetPlayerAllianceBJ( GetEnumPlayer(), ALLIANCE_PASSIVE, false, ConvertedPlayer(3) )
//    call SetPlayerAllianceBJ( GetEnumPlayer(), ALLIANCE_PASSIVE, false, ConvertedPlayer(4) )
//    call SetPlayerAllianceBJ( GetEnumPlayer(), ALLIANCE_PASSIVE, false, ConvertedPlayer(6) )
//    call SetPlayerAllianceBJ( GetEnumPlayer(), ALLIANCE_PASSIVE, false, ConvertedPlayer(7) )
//    call SetPlayerAllianceBJ( GetEnumPlayer(), ALLIANCE_PASSIVE, false, ConvertedPlayer(8) )
//    call SetPlayerAllianceBJ( GetEnumPlayer(), ALLIANCE_PASSIVE, false, ConvertedPlayer(12) )

    //call SetPlayerAllianceStateAllyBJ ( GetEnumPlayer(), ConvertedPlayer(2), false )
    //call SetPlayerAllianceStateAllyBJ ( GetEnumPlayer(), ConvertedPlayer(3), false )
    //call SetPlayerAllianceStateAllyBJ ( GetEnumPlayer(), ConvertedPlayer(4), false )
    //call SetPlayerAllianceStateAllyBJ ( GetEnumPlayer(), ConvertedPlayer(6), false )
    //call SetPlayerAllianceStateAllyBJ ( GetEnumPlayer(), ConvertedPlayer(7), false )
    //call SetPlayerAllianceStateAllyBJ ( GetEnumPlayer(), ConvertedPlayer(8), false )
    //call SetPlayerAllianceStateAllyBJ ( GetEnumPlayer(), ConvertedPlayer(12), false )

endfunction



function Init takes nothing returns nothing
    call doMainConstants()
    call ForForce( udg_Force[1], function doInitPlayers )
    call ForForce( udg_Force[2], function doInitDMs )

    //misc
    //call EnableWorldFogBoundaryBJ( false, GetPlayersAll() )
    call InitTranslator()

    //frameskip
    call TriggerSleepAction(0)

    //init players
    //call TriggerExecute( gg_trg_PlayerGlob )
    //call TriggerExecute( gg_trg_HeroSelector )
    //call TriggerExecute( gg_trg_Inventory )

    //init dms
    call TriggerExecute( gg_trg_Create )
    call TriggerExecute( gg_trg_Units )
    call TriggerExecute( gg_trg_Misc )
    call TriggerExecute( gg_trg_Items )

    //init doodads
    call TriggerExecute( gg_trg_Doodads )

    //introduce map
    call ClearScreen()
    call DisplayTextToForce( GetPlayersAll(), "Welcome to Vuen's D&D Crystal!" )
    //call DisplayTextToForce( GetPlayersAll(), "    This is a WORK IN PROGRESS! Parts of this map are" )
    //call DisplayTextToForce( GetPlayersAll(), "    incomplete; they will be added in a future release." )
    //call DisplayTextToForce( GetPlayersAll(), "    Thank you for testing!" )
    call DisplayTextToForce( GetPlayersAll(), " " )

    call DisplayTextToForce( udg_Force[1], "Please wait while a DM selects available heroes." )

    call DisplayTextToForce( bj_FORCE_PLAYER[9], "You are a DM." )
    call DisplayTextToForce( bj_FORCE_PLAYER[9], "Press |cFFFFFF00ESC|r to get started!" )
    call DisplayTextToForce( bj_FORCE_PLAYER[9], "Help is available in the quest log (|cFFFFFF00F9|r)." )
    call DisplayTextToForce( bj_FORCE_PLAYER[10], "You are a DM." )
    call DisplayTextToForce( bj_FORCE_PLAYER[10], "Press |cFFFFFF00ESC|r to get started!" )
    call DisplayTextToForce( bj_FORCE_PLAYER[10], "Help is available in the quest log (|cFFFFFF00F9|r)." )

    call DisplayTextToForce( bj_FORCE_PLAYER[8], "Click a Hero to toggle its availability." )
    call DisplayTextToForce( bj_FORCE_PLAYER[8], "|c0000FF00Green|r = Allow, |c00FF0000Red|r = Deny." )
    call DisplayTextToForce( bj_FORCE_PLAYER[8], "Choose quickly; the heroes are waiting." )
    call TriggerSleepAction(0)
//    call CameraSetupApplyForPlayer( true, gg_cam_HeroRestrictor, Player(8), 0 )
endfunction



function InitTrig_Initialization takes nothing returns nothing
    set gg_trg_Initialization = CreateTrigger()
    call TriggerAddAction(gg_trg_Initialization, function Init)
endfunction
//*************************
//    checked for leaks
//*************************


//************************************
//************************************
//**********     CHAT       **********
//************************************
//************************************

function ShowLocalDebugBoard takes nothing returns nothing
    if GetTriggerPlayer() == GetLocalPlayer() then
        call MultiboardDisplayBJ( true, udg_DebugBoard )
        call MultiboardMinimizeBJ( false, udg_DebugBoard )
    endif
endfunction

function doSharePlayerEnumControl takes nothing returns nothing
    //careful with gettriggerplayer, its not actually in docommandentered, no guarantees
    call SetPlayerAllianceBJ( GetEnumPlayer(), ALLIANCE_SHARED_CONTROL, true, GetTriggerPlayer() )
    call SetPlayerAllianceBJ( GetEnumPlayer(), ALLIANCE_SHARED_ADVANCED_CONTROL, true, GetTriggerPlayer() )
endfunction

function VulnEnumUnitSelected takes nothing returns nothing
    if IsUnitSelected(GetEnumUnit(), udg_TEMP_Player) then
        if GetBooleanOr(IsPlayerInForce(GetOwningPlayer(GetEnumUnit()), udg_Force[1]), IsPlayerInForce(GetOwningPlayer(GetEnumUnit()), udg_Force[3])) then
            call SetUnitInvulnerable( GetEnumUnit(), false )
        endif
    endif
endfunction

function InvulnEnumUnitSelected takes nothing returns nothing
    if IsUnitSelected(GetEnumUnit(), udg_TEMP_Player) then
        if GetBooleanOr(IsPlayerInForce(GetOwningPlayer(GetEnumUnit()), udg_Force[1]), IsPlayerInForce(GetOwningPlayer(GetEnumUnit()), udg_Force[3])) then
            call SetUnitInvulnerable( GetEnumUnit(), true )
        endif
    endif
endfunction

function ColorEnumUnitSelected takes nothing returns nothing
    if IsUnitSelected(GetEnumUnit(), udg_TEMP_Player) then
        if GetBooleanOr(IsPlayerInForce(GetOwningPlayer(GetEnumUnit()), udg_Force[1]), IsPlayerInForce(GetOwningPlayer(GetEnumUnit()), udg_Force[3])) then
            call SetUnitColor( GetEnumUnit(), GetPlayerColor(ConvertedPlayer(udg_TEMP_Integer)) )
        endif
    endif
endfunction

function TintEnumUnitSelected takes nothing returns nothing
    if IsUnitSelected(GetEnumUnit(), udg_TEMP_Player) then
        if GetBooleanOr(IsPlayerInForce(GetOwningPlayer(GetEnumUnit()), udg_Force[1]), IsPlayerInForce(GetOwningPlayer(GetEnumUnit()), udg_Force[3])) then
            call SetUnitVertexColorBJ( GetEnumUnit(), udg_TEMP_RealArray[1], udg_TEMP_RealArray[2], udg_TEMP_RealArray[3], udg_TEMP_RealArray[4] )
        endif
    endif
endfunction

function ImmuneEnumUnitSelected takes nothing returns nothing
    if IsUnitSelected(GetEnumUnit(), udg_TEMP_Player) then
        if GetBooleanOr(IsPlayerInForce(GetOwningPlayer(GetEnumUnit()), udg_Force[1]), IsPlayerInForce(GetOwningPlayer(GetEnumUnit()), udg_Force[3])) then
            call UnitAddAbilityBJ( 'ACmi', GetEnumUnit() )
        endif
    endif
endfunction

function UnImmuneEnumUnitSelected takes nothing returns nothing
    if IsUnitSelected(GetEnumUnit(), udg_TEMP_Player) then
        if GetBooleanOr(IsPlayerInForce(GetOwningPlayer(GetEnumUnit()), udg_Force[1]), IsPlayerInForce(GetOwningPlayer(GetEnumUnit()), udg_Force[3])) then
            call UnitRemoveAbilityBJ( 'ACmi', GetEnumUnit() )
        endif
    endif
endfunction

function GiveEnumUnitSelected takes nothing returns nothing
    if IsUnitSelected(GetEnumUnit(), udg_TEMP_Player) then
        if GetBooleanOr(IsPlayerInForce(GetOwningPlayer(GetEnumUnit()), udg_Force[1]), IsPlayerInForce(GetOwningPlayer(GetEnumUnit()), udg_Force[3])) then
            if IsPlayerInForce(ConvertedPlayer(udg_TEMP_Integer), udg_Force[1]) and IsUnitIdType(GetUnitTypeId(GetEnumUnit()), UNIT_TYPE_HERO) then
                set udg_TEMP_Boolean = true
            else
                if IsPlayerInForce(ConvertedPlayer(udg_TEMP_Integer), udg_Force[1]) then
                    call UnitRemoveAbilityBJ( 'A03N', GetEnumUnit() )
                else
                    if not(isShop(GetUnitTypeId(GetEnumUnit()))) then
                        call UnitAddAbilityBJ( 'A03N', GetEnumUnit() )
                    endif
                endif
                call SetUnitOwner( GetEnumUnit(), ConvertedPlayer(udg_TEMP_Integer), true )
            endif
        endif
    endif
endfunction









function ClearTrainingRoomEnumUnits takes nothing returns nothing

    local location loc
    local location loc2
    local real distance

    set loc = GetUnitLoc(GetEnumUnit())
    set loc2 = GetUnitLoc(udg_TRAIN_CurRoom)
    set distance = DistanceBetweenPoints(loc, loc2)
    call RemoveLocation(loc)
    call RemoveLocation(loc2)

    if GetOwningPlayer(GetEnumUnit()) == ConvertedPlayer(1) then
        if distance < 900 then
            if IsKillableTrainUnit(GetEnumUnit()) then
                call KillUnit(GetEnumUnit())
            endif
        endif
    endif

endfunction


function ClearTrainingRoomMonsters takes unit un returns nothing
    local location trainloc
    local group grp

    set udg_TRAIN_CurRoom = un
    set trainloc = GetUnitLoc(udg_TRAIN_CurRoom)
    call MoveRectToLoc( gg_rct_TrainingRoom, trainloc )

    set grp = GetUnitsInRectAll(gg_rct_TrainingRoom)
    call ForGroupBJ( grp, function ClearTrainingRoomEnumUnits )
    call DestroyGroup(grp)

    call RemoveLocation(trainloc)
endfunction


function KillEnumUnitSelected takes nothing returns nothing
    if IsUnitSelected(GetEnumUnit(), udg_TEMP_Player) then
        if GetBooleanOr(IsPlayerInForce(GetOwningPlayer(GetEnumUnit()), udg_Force[1]), IsPlayerInForce(GetOwningPlayer(GetEnumUnit()), udg_Force[3])) then
            if GetUnitTypeId(GetEnumUnit()) == 'h00B' then
                call ClearTrainingRoomMonsters(GetEnumUnit())
            endif

            call RemoveKeepAliveUnit(GetEnumUnit())
            call KillUnit( GetEnumUnit() )
        endif
    endif
endfunction

function KeepAliveEnumUnitSelected takes nothing returns nothing
    if IsUnitSelected(GetEnumUnit(), udg_TEMP_Player) then
        if GetBooleanOr(IsPlayerInForce(GetOwningPlayer(GetEnumUnit()), udg_Force[1]), IsPlayerInForce(GetOwningPlayer(GetEnumUnit()), udg_Force[3])) then
            call KeepAliveUnit( GetEnumUnit() )
        endif
    endif
endfunction

function RemoveEnumUnitSelected takes nothing returns nothing
    local location loc
    if IsUnitSelected(GetEnumUnit(), udg_TEMP_Player) then
        if IsPlayerInForce(GetOwningPlayer(GetEnumUnit()), udg_Force[3]) then
            call RemoveKeepAliveUnit(GetEnumUnit())
            if GetUnitTypeId(GetEnumUnit()) == 'h00B' then
                call ClearTrainingRoomMonsters(GetEnumUnit())
                call KillUnit(GetEnumUnit())
            else
                set loc = GetUnitLoc(GetEnumUnit())
                call AddSpecialEffectLocBJ( loc, "Abilities\\Spells\\Human\\MassTeleport\\MassTeleportTarget.mdl" )
                call DestroyEffectBJ( GetLastCreatedEffectBJ() )
                call RemoveLocation(loc)
                call RemoveUnit( GetEnumUnit() )
            endif
        endif
    endif
endfunction

function UnitSizeEnumUnitSelected takes nothing returns nothing
    if IsUnitSelected(GetEnumUnit(), udg_TEMP_Player) then
        if GetBooleanOr(IsPlayerInForce(GetOwningPlayer(GetEnumUnit()), udg_Force[1]), IsPlayerInForce(GetOwningPlayer(GetEnumUnit()), udg_Force[3])) then
            call SetUnitScalePercent( GetEnumUnit(), udg_TEMP_Integer, udg_TEMP_Integer, udg_TEMP_Integer)
            call SetUnitMoveSpeed( GetEnumUnit(), I2R(udg_TEMP_Integer) * GetUnitDefaultMoveSpeed(GetEnumUnit()) / 100 )
        endif
    endif
endfunction

function SideSwapEnumUnitSelected takes nothing returns nothing
    if IsUnitSelected(GetEnumUnit(), udg_TEMP_Player) then
        if IsPlayerInForce(GetOwningPlayer(GetEnumUnit()), udg_Force[3]) then
            if GetOwningPlayer(GetEnumUnit()) == ConvertedPlayer(1) then
                call SetUnitOwner( GetEnumUnit(), ConvertedPlayer(5), true )
            else
                call SetUnitOwner( GetEnumUnit(), ConvertedPlayer(1), true )
            endif
        endif
    endif
endfunction

function HeroLevelEnumUnitSelected takes nothing returns nothing
    if IsUnitSelected(GetEnumUnit(), udg_TEMP_Player) then
        if GetBooleanOr(IsPlayerInForce(GetOwningPlayer(GetEnumUnit()), udg_Force[1]), IsPlayerInForce(GetOwningPlayer(GetEnumUnit()), udg_Force[3])) then
            if IsUnitType(GetEnumUnit(), UNIT_TYPE_HERO) then
                call SetHeroLevelBJ( GetEnumUnit(), udg_TEMP_Integer, true )
            endif
        endif
    endif
endfunction





function DebugCommand takes string str, integer id returns nothing
    if udg_DebugBoardCreated then
        call MultiboardSetItemValueBJ( udg_DebugBoard, 4, id, ColorName(str,id) )
        call PolledWait( 4.00 )
        call MultiboardSetItemValueBJ( udg_DebugBoard, 4, id, "" )
    endif
endfunction




function DoCommandEntered takes integer id returns boolean


    local unit GUI_Units = gg_unit_n000_0001
    local unit GUI_U_Create = gg_unit_n000_0002
    local unit GUI_U_Kill = gg_unit_n000_0003
    local unit GUI_U_Remove = gg_unit_n000_0004
    local unit GUI_U_Side = gg_unit_n000_0005
    local unit GUI_U_Move = gg_unit_n000_0006

    local unit GUI_D_Create = gg_unit_n000_0038
    local unit GUI_D_Remove = gg_unit_n000_0039
    local unit GUI_D_Kill = gg_unit_n000_0040
    local unit GUI_D_Revive = gg_unit_n000_0041
    local unit GUI_D_Toggle = gg_unit_n000_0042

    local unit GUI_D_P_Grove = gg_unit_n000_0123
    local unit GUI_D_P_Tree = gg_unit_n000_0124
    local unit GUI_D_P_Blight = gg_unit_n000_0125
    local unit GUI_D_P_Dispel = gg_unit_n000_0131
    local unit GUI_D_P_WoodenBridge = gg_unit_n008_0127
    local unit GUI_D_P_StoneBridge = gg_unit_n009_0128
    local unit GUI_D_P_Gate = gg_unit_n00G_0136
    local unit GUI_D_P_ElvenGate = gg_unit_n00H_0137
    local unit GUI_D_P_DemonicGate = gg_unit_n00F_0138
    local unit GUI_D_P_StoneWall = gg_unit_n00O_0164
    local unit GUI_D_P_Line1 = gg_unit_n00P_0183

    local unit GUI_Items = gg_unit_n000_0033
    local unit GUI_I_Create = gg_unit_n000_0034
    local unit GUI_I_Remove = gg_unit_n000_0035
    local unit GUI_I_Move = gg_unit_n000_0036
    local unit GUI_I_P_GoldPile = gg_unit_n000_0132
    local unit GUI_I_P_GoldCoin = gg_unit_n000_0133
    local unit GUI_I_P_PileOfRiches = gg_unit_n000_0079

    local unit GUI_M_Portal = gg_unit_n000_0044

    local group grp

    local player pl
    local force fp
    local string str
    local string text

    local integer utype

    local integer i1
    local integer i2
    local integer array ratios



    set pl = ConvertedPlayer(id)

    if not(IsPlayerInForce(pl, udg_Force[2])) then
//********************RETURN
            return false //not a command
    endif

    set fp = bj_FORCE_PLAYER[id-1]
    set str = StringCase(GetEventPlayerChatString(), false)




//Units
    if (str == "uc") then
        call SelectUnitForPlayerSingle( GUI_U_Create, pl )

    elseif (str == "uk") then
        call SelectUnitForPlayerSingle( GUI_U_Kill, pl )
    elseif (str == "uks" or str == "kill") then
        set udg_TEMP_Player = pl
        set grp = GetUnitsInRectAll(GetPlayableMapRect())
        call ForGroupBJ( grp, function KillEnumUnitSelected )
        call DestroyGroup(grp)
        call DebugCommand(str,id)
    elseif (str == "ur") then
        call SelectUnitForPlayerSingle( GUI_U_Remove, pl )
    elseif (str == "urs" or str == "remove") then
        set udg_TEMP_Player = pl
        set grp = GetUnitsInRectAll(GetPlayableMapRect())
        call ForGroupBJ( grp, function RemoveEnumUnitSelected )
        call DestroyGroup(grp)
        call DebugCommand(str,id)

    elseif (str == "us") then
        call SelectUnitForPlayerSingle( GUI_U_Side, pl )
    elseif (str == "uss" or str == "side") then
        set udg_TEMP_Player = pl
        set grp = GetUnitsInRectAll(GetPlayableMapRect())
        call ForGroupBJ( grp, function SideSwapEnumUnitSelected )
        call DestroyGroup(grp)
        call DebugCommand(str,id)

    elseif (str == "um") then
        call SelectUnitForPlayerSingle( GUI_U_Move, pl )






//Items
    elseif (str == "ic") then
        call SelectUnitForPlayerSingle( GUI_I_Create, pl )
    elseif (str == "ir") then
        call SelectUnitForPlayerSingle( GUI_I_Remove, pl )

    elseif (str == "goldcoin") then
        call SelectUnitForPlayerSingle( GUI_I_P_GoldCoin, pl )
    elseif (str == "gold coin") then
        call SelectUnitForPlayerSingle( GUI_I_P_GoldCoin, pl )

    elseif (str == "pileofgold") then
        call SelectUnitForPlayerSingle( GUI_I_P_GoldPile, pl )
    elseif (str == "pile of gold") then
        call SelectUnitForPlayerSingle( GUI_I_P_GoldPile, pl )
    elseif (str == "gold") then
        call SelectUnitForPlayerSingle( GUI_I_P_GoldPile, pl )
    elseif (str == "goldpile") then
        call SelectUnitForPlayerSingle( GUI_I_P_GoldPile, pl )
    elseif (str == "gold pile") then
        call SelectUnitForPlayerSingle( GUI_I_P_GoldPile, pl )

    elseif (str == "riches") then
        call SelectUnitForPlayerSingle( GUI_I_P_PileOfRiches, pl )
    elseif (str == "pileofriches") then
        call SelectUnitForPlayerSingle( GUI_I_P_PileOfRiches, pl )
    elseif (str == "pile of riches") then
        call SelectUnitForPlayerSingle( GUI_I_P_PileOfRiches, pl )






//Doodads
    elseif (str == "dc") then
        call SelectUnitForPlayerSingle( GUI_D_Create, pl )
    elseif (str == "dk") then
        call SelectUnitForPlayerSingle( GUI_D_Kill, pl )
    elseif (str == "dr") then
        call SelectUnitForPlayerSingle( GUI_D_Remove, pl )
    elseif (str == "dv") then
        call SelectUnitForPlayerSingle( GUI_D_Revive, pl )
    elseif (str == "dt") then
        call SelectUnitForPlayerSingle( GUI_D_Toggle, pl )

    elseif (str == "grove") then
        call SelectUnitForPlayerSingle( GUI_D_P_Grove, pl )
    elseif (str == "tree") then
        call SelectUnitForPlayerSingle( GUI_D_P_Tree, pl )
    elseif (str == "dispel") then
        call SelectUnitForPlayerSingle( GUI_D_P_Dispel, pl )
    elseif (str == "blight") then
        call SelectUnitForPlayerSingle( GUI_D_P_Blight, pl )

    elseif (str == "woodbridge") then
        call SelectUnitForPlayerSingle( GUI_D_P_WoodenBridge, pl )
    elseif (str == "woodenbridge") then
        call SelectUnitForPlayerSingle( GUI_D_P_WoodenBridge, pl )
    elseif (str == "stonebridge") then
        call SelectUnitForPlayerSingle( GUI_D_P_StoneBridge, pl )
    elseif (str == "wood bridge") then
        call SelectUnitForPlayerSingle( GUI_D_P_WoodenBridge, pl )
    elseif (str == "wooden bridge") then
        call SelectUnitForPlayerSingle( GUI_D_P_WoodenBridge, pl )
    elseif (str == "stone bridge") then
        call SelectUnitForPlayerSingle( GUI_D_P_StoneBridge, pl )
    elseif (str == "bridge") then
        call SelectUnitForPlayerSingle( GUI_D_P_StoneBridge, pl )

    elseif (str == "gate") then
        call SelectUnitForPlayerSingle( GUI_D_P_Gate, pl )
    elseif (str == "elvengate") then
        call SelectUnitForPlayerSingle( GUI_D_P_ElvenGate, pl )
    elseif (str == "elven gate") then
        call SelectUnitForPlayerSingle( GUI_D_P_ElvenGate, pl )
    elseif (str == "demonicgate") then
        call SelectUnitForPlayerSingle( GUI_D_P_DemonicGate, pl )
    elseif (str == "demonic gate") then
        call SelectUnitForPlayerSingle( GUI_D_P_DemonicGate, pl )
    elseif (str == "demongate") then
        call SelectUnitForPlayerSingle( GUI_D_P_DemonicGate, pl )
    elseif (str == "demon gate") then
        call SelectUnitForPlayerSingle( GUI_D_P_DemonicGate, pl )
    elseif (str == "wall") then
        call SelectUnitForPlayerSingle( GUI_D_P_StoneWall, pl )
    elseif (str == "stonewall") then
        call SelectUnitForPlayerSingle( GUI_D_P_StoneWall, pl )
    elseif (str == "stone wall") then
        call SelectUnitForPlayerSingle( GUI_D_P_StoneWall, pl )
    elseif (str == "line") then
        call SelectUnitForPlayerSingle( GUI_D_P_Line1, pl )
    elseif (str == "wallline") then
        call SelectUnitForPlayerSingle( GUI_D_P_Line1, pl )
    elseif (str == "wall line") then
        call SelectUnitForPlayerSingle( GUI_D_P_Line1, pl )





//Colors
    elseif (str == "red") then
        call SelectUnitForPlayerSingle( udg_GUI_Tile[1], pl )
    elseif (str == "enemy") then
        call SelectUnitForPlayerSingle( udg_GUI_Tile[1], pl )
    elseif (str == "enemies") then
        call SelectUnitForPlayerSingle( udg_GUI_Tile[1], pl )
    elseif (str == "yellow") then
        call SelectUnitForPlayerSingle( udg_GUI_Tile[5], pl )
    elseif (str == "ally") then
        call SelectUnitForPlayerSingle( udg_GUI_Tile[5], pl )
    elseif (str == "allies") then
        call SelectUnitForPlayerSingle( udg_GUI_Tile[5], pl )






//Misc
    elseif (str == "mw") then
        call SelectUnitForPlayerSingle( GUI_M_Portal, pl )
    elseif (str == "waygate") then
        call SelectUnitForPlayerSingle( GUI_M_Portal, pl )


    //Invulnerable
    elseif (str == "invuln" or str == "invulon") then
        set udg_TEMP_Player = pl
        set grp = GetUnitsInRectAll(GetPlayableMapRect())
        call ForGroupBJ( grp, function InvulnEnumUnitSelected )
        call DestroyGroup(grp)
        call DebugCommand(str,id)
    elseif (str == "vuln" or str == "invuloff") then
        set udg_TEMP_Player = pl
        set grp = GetUnitsInRectAll(GetPlayableMapRect())
        call ForGroupBJ( grp, function VulnEnumUnitSelected )
        call DestroyGroup(grp)
        call DebugCommand(str,id)

    //Magic Immune
    elseif (str == "immune" or str == "immunon") then
        set udg_TEMP_Player = pl
        set grp = GetUnitsInRectAll(GetPlayableMapRect())
        call ForGroupBJ( grp, function ImmuneEnumUnitSelected )
        call DestroyGroup(grp)
        call DebugCommand(str,id)
    elseif (str == "mune" or str == "unimmune" or str == "immunoff") then
        set udg_TEMP_Player = pl
        set grp = GetUnitsInRectAll(GetPlayableMapRect())
        call ForGroupBJ( grp, function UnImmuneEnumUnitSelected )
        call DestroyGroup(grp)
        call DebugCommand(str,id)



    //Hero Level
    elseif SubStringBJ(str,1,5) == "level" then
        //Get rid of that pesky space people like to add
        if (SubStringBJ(str,6,6) == " ") then
            set text = SubStringBJ(str,7,StringLength(str))
        else
            set text = SubStringBJ(str,6,StringLength(str))
        endif

        set udg_TEMP_Integer = S2I(text)
        set udg_TEMP_Player = pl

        set grp = GetUnitsInRectAll(GetPlayableMapRect())
        call ForGroupBJ( grp, function HeroLevelEnumUnitSelected )
        call DestroyGroup(grp)
        call DebugCommand(str,id)


    //Unit Armor Bonus
    elseif SubStringBJ(str,1,5) == "armor" then
        //Get rid of that pesky space people like to add
        if (SubStringBJ(str,6,6) == " ") then
            set text = SubStringBJ(str,7,StringLength(str))
        else
            set text = SubStringBJ(str,6,StringLength(str))
        endif

        set udg_TEMP_Integer = IMaxBJ(0, IMinBJ(16000, S2I(text)))
        set udg_TEMP_Player = pl

        set grp = GetUnitsInRectAll(GetPlayableMapRect())
        call ForGroupBJ( grp, function BonusArmorEnumUnitSelected )
        call DestroyGroup(grp)
        call DebugCommand(str,id)


    //Unit Damage Bonus
    elseif SubStringBJ(str,1,6) == "damage" then
        //Get rid of that pesky space people like to add
        if (SubStringBJ(str,7,7) == " ") then
            set text = SubStringBJ(str,8,StringLength(str))
        else
            set text = SubStringBJ(str,7,StringLength(str))
        endif

        set udg_TEMP_Integer = IMaxBJ(0, IMinBJ(16000, S2I(text)))
        set udg_TEMP_Player = pl

        set grp = GetUnitsInRectAll(GetPlayableMapRect())
        call ForGroupBJ( grp, function BonusDamageEnumUnitSelected )
        call DestroyGroup(grp)
        call DebugCommand(str,id)


    //Unit Life Bonus
    elseif SubStringBJ(str,1,4) == "life" then
        //Get rid of that pesky space people like to add
        if (SubStringBJ(str,5,5) == " ") then
            set text = SubStringBJ(str,6,StringLength(str))
        else
            set text = SubStringBJ(str,5,StringLength(str))
        endif

        set udg_TEMP_Integer = S2I(text)
        set udg_TEMP_Player = pl

        set grp = GetUnitsInRectAll(GetPlayableMapRect())
        call ForGroupBJ( grp, function BonusLifeEnumUnitSelected )
        call DestroyGroup(grp)
        call DebugCommand(str,id)

    //Unit Mana Bonus
    elseif SubStringBJ(str,1,4) == "mana" then
        //Get rid of that pesky space people like to add
        if (SubStringBJ(str,5,5) == " ") then
            set text = SubStringBJ(str,6,StringLength(str))
        else
            set text = SubStringBJ(str,5,StringLength(str))
        endif

        set udg_TEMP_Integer = S2I(text)
        set udg_TEMP_Player = pl

        set grp = GetUnitsInRectAll(GetPlayableMapRect())
        call ForGroupBJ( grp, function BonusManaEnumUnitSelected )
        call DestroyGroup(grp)
        call DebugCommand(str,id)

    //Unit Attack Speed Bonus
    elseif SubStringBJ(str,1,6) == "aspeed" then
        //Get rid of that pesky space people like to add
        if (SubStringBJ(str,7,7) == " ") then
            set text = SubStringBJ(str,8,StringLength(str))
        else
            set text = SubStringBJ(str,7,StringLength(str))
        endif

        set udg_TEMP_Integer = IMaxBJ(0, IMinBJ(2000, S2I(text)))
        set udg_TEMP_Player = pl

        set grp = GetUnitsInRectAll(GetPlayableMapRect())
        call ForGroupBJ( grp, function BonusAttackSpeedEnumUnitSelected )
        call DestroyGroup(grp)
        call DebugCommand(str,id)

    //Unit Size
    elseif SubStringBJ(str,1,4) == "size" then
        //Get rid of that pesky space people like to add
        if (SubStringBJ(str,5,5) == " ") then
            set text = SubStringBJ(str,6,StringLength(str))
        else
            set text = SubStringBJ(str,5,StringLength(str))
        endif

        set udg_TEMP_Integer = IMaxBJ(0, IMinBJ(5000, S2I(text)))
        set udg_TEMP_Player = pl

        set grp = GetUnitsInRectAll(GetPlayableMapRect())
        call ForGroupBJ( grp, function UnitSizeEnumUnitSelected )
        call DestroyGroup(grp)
        call DebugCommand(str,id)




    //Give
    elseif SubStringBJ(str,1,4) == "give" then
        //Get rid of that pesky 'to' in quatredan
        if (SubStringBJ(str,5,6) == "to") then
            //Get rid of that pesky space people like to add
            if (SubStringBJ(str,7,7) == " ") then
                set text = SubStringBJ(str,8,StringLength(str))
            else
                set text = SubStringBJ(str,7,StringLength(str))
            endif
        else
            //Get rid of that pesky space people like to add
            if (SubStringBJ(str,5,5) == " ") then
                set text = SubStringBJ(str,6,StringLength(str))
            else
                set text = SubStringBJ(str,5,StringLength(str))
            endif
        endif

        set udg_TEMP_Integer = GetPlayerNumFromStr(text)
        set udg_TEMP_Player = pl
        set udg_TEMP_Boolean = false

        if udg_TEMP_Integer == -1 then
            call DisplayTextToForce( fp, "    |c00FF0000Invalid Player: |r" + text )
        elseif IsPlayerInForce(ConvertedPlayer(udg_TEMP_Integer), udg_Force[1]) or IsPlayerInForce(ConvertedPlayer(udg_TEMP_Integer), udg_Force[3]) then
            set grp = GetUnitsInRectAll(GetPlayableMapRect())
            call ForGroupBJ( grp, function GiveEnumUnitSelected )
            call DestroyGroup(grp)
            if udg_TEMP_Boolean then
                call DisplayTextToForce( fp, "    |c00FF0000Cannot give heroes to players.|r" )
            endif
            call DebugCommand(str,id)
        else
            call DisplayTextToForce( fp, "    |c00FF0000Cannot give units to |r" + ColorNamePl(ConvertedPlayer(udg_TEMP_Integer)) + "|c00FF0000.|r" )
        endif




    //Color
    elseif SubStringBJ(str,1,5) == "color" then
        //Get rid of that pesky space people like to add
        if (SubStringBJ(str,6,6) == " ") then
            set text = SubStringBJ(str,7,StringLength(str))
        else
            set text = SubStringBJ(str,6,StringLength(str))
        endif

        set udg_TEMP_Integer = GetPlayerNumFromStrSafe(text)
        set udg_TEMP_Player = pl
        set grp = GetUnitsInRectAll(GetPlayableMapRect())
        call ForGroupBJ( grp, function ColorEnumUnitSelected )
        call DestroyGroup(grp)
        call DebugCommand(str,id)



    //Tint
    elseif SubStringBJ(str, 1, 4) == "tint" then
        //Get rid of that pesky space people like to add
        if (SubStringBJ(str,5,5) == " ") then
            set text = SubStringBJ(str,6,StringLength(str))
        else
            set text = SubStringBJ(str,5,StringLength(str))
        endif

        set i1 = 1
        set i2 = 2
        loop
            exitwhen GetBooleanOr(i2 > StringLength(str), SubStringBJ(text, i2, i2) == " ")
            set i2 = i2 + 1
        endloop

        if GetBooleanOr(i2 > StringLength(str), i2 > 8) then
            //dobrp can lick my nuts
            set udg_TEMP_RealArray[1] = S2R(SubStringBJ(text, 1, 3))
            set udg_TEMP_RealArray[2] = S2R(SubStringBJ(text, 4, 6))
            set udg_TEMP_RealArray[3] = S2R(SubStringBJ(text, 7, 9))
            if StringLength(str) > 9 then
                set udg_TEMP_RealArray[4] = S2R(SubStringBJ(text, 10, 12))
            else
                set udg_TEMP_RealArray[4] = 0
            endif

            //so can quatredan. lazy programmers
            if udg_TEMP_RealArray[1] > 100 or udg_TEMP_RealArray[2] > 100 or udg_TEMP_RealArray[3] > 100 or udg_TEMP_RealArray[4] > 100 then
                set udg_TEMP_RealArray[1] = udg_TEMP_RealArray[1] * 100 / 255
                set udg_TEMP_RealArray[2] = udg_TEMP_RealArray[1] * 100 / 255
                set udg_TEMP_RealArray[3] = udg_TEMP_RealArray[1] * 100 / 255
                set udg_TEMP_RealArray[4] = udg_TEMP_RealArray[1] * 100 / 255
            endif
        else
            //ratios
            set udg_TEMP_RealArray[1] = S2R(SubStringBJ(text, i1, i2-1)) * 100

            set i1 = i2 + 1
            set i2 = i1 + 1
            loop
                exitwhen GetBooleanOr(i2 > StringLength(str), SubStringBJ(text, i2, i2) == " ")
                set i2 = i2 + 1
            endloop
            set udg_TEMP_RealArray[2] = S2R(SubStringBJ(text, i1, i2-1)) * 100

            set i1 = i2 + 1
            set i2 = i1 + 1
            loop
                exitwhen GetBooleanOr(i2 > StringLength(str), SubStringBJ(text, i2, i2) == " ")
                set i2 = i2 + 1
            endloop
            set udg_TEMP_RealArray[3] = S2R(SubStringBJ(text, i1, i2-1)) * 100

            if StringLength(str) > i2 then //we hit a space and there's more - alpha term
                set i1 = i2 + 1
                set i2 = i1 + 1
                loop
                    exitwhen GetBooleanOr(i2 > StringLength(str), SubStringBJ(text, i2, i2) == " ")
                    set i2 = i2 + 1
                endloop
                set udg_TEMP_RealArray[4] = S2R(SubStringBJ(text, i1, i2-1)) * 100
            else
                set udg_TEMP_RealArray[4] = 0
            endif
        endif

        set udg_TEMP_RealArray[1] = RMinBJ(RMaxBJ(udg_TEMP_RealArray[1], 0), 100)
        set udg_TEMP_RealArray[2] = RMinBJ(RMaxBJ(udg_TEMP_RealArray[2], 0), 100)
        set udg_TEMP_RealArray[3] = RMinBJ(RMaxBJ(udg_TEMP_RealArray[3], 0), 100)
        set udg_TEMP_RealArray[4] = RMinBJ(RMaxBJ(udg_TEMP_RealArray[4], 0), 100)
        set udg_TEMP_Player = pl
        set grp = GetUnitsInRectAll(GetPlayableMapRect())
        call ForGroupBJ( grp, function TintEnumUnitSelected )
        call DestroyGroup(grp)
        call DebugCommand(str,id)





//Expert
    elseif (str == "ka") then
        set udg_TEMP_Player = pl
        set grp = GetUnitsInRectAll(GetPlayableMapRect())
        call ForGroupBJ( grp, function KeepAliveEnumUnitSelected )
        call DestroyGroup(grp)
        call DebugCommand(str,id)

    elseif (str == "control") then
        call ForForce( udg_Force[1], function doSharePlayerEnumControl )
        call DebugCommand(str,id)

    elseif (str == "unlock") then
        if pl == ConvertedPlayer(9) then
            call DisableTrigger( gg_trg_Hero_Restrictor_Lock )
        endif
        call DebugCommand(str,id)

    elseif (str == "freehero") then
        if pl == ConvertedPlayer(9) then
            set udg_FreeHero = true
        endif
        call DebugCommand(str,id)




    //Unit Type

    else
        set utype = String2UnitIdBJ(TranslateFrom(str))
        if utype == null then
//********************RETURN
            return false //not a command
        else
            set udg_Status[id] = "unit_create"
            set udg_DM_UnitType[id] = utype
            call GUIApplyCamForDM(pl)
            call LeaderboardSetPlayerItemLabelBJ( ConvertedPlayer(4), udg_Board[id], "|cFFFFFFFF-> '|r" + ColorName(TranslateTo(UnitId2StringBJ(udg_DM_UnitType[id])), GetConvertedPlayerId(udg_DM_Player[id])) + "|cFFFFFFFF'|r" )
            call SelectUnitForPlayerSingle( udg_GUI_Pointer[id], pl )
            call DisplayTextToForce( fp, "    Right click to create a '|cFFFF0000" + TranslateTo(UnitId2StringBJ(udg_DM_UnitType[id])) + "|r' for " + ColorNamePl(udg_DM_Player[id]) + "." )
            call DisplayTextToForce( fp, "    Click a tile in the Toolbox to select the owner of the new unit.")
        endif

    endif


//********************RETURN
    return true //is a command


endfunction











function DoChatSystem takes integer id returns nothing

    local player pl
    local force fp
    local integer chatnum
    local string text
    local string str
    local integer i

    //local unit GUI_D_P_Grove = gg_unit_n000_0123
    //local unit GUI_D_P_Tree = gg_unit_n000_0124
    //local unit GUI_D_P_Blight = gg_unit_n000_0125

    set pl = ConvertedPlayer(id)
    set fp = bj_FORCE_PLAYER[id-1]
    set str = GetEventPlayerChatString()

    //call SetUnitScalePercent( GUI_D_P_Grove, S2R(str), S2R(str), S2R(str) )
    //call SetUnitScalePercent( GUI_D_P_Tree, S2R(str), S2R(str), S2R(str) )
    //call SetUnitScalePercent( GUI_D_P_Blight, S2R(str), S2R(str), S2R(str) )



    //DoBRP Set Name
    if SubStringBJ(str, 1, 7) == "setname" then
        if IsANumber(SubStringBJ(str, 8, 8)) then
            set chatnum = S2I(SubStringBJ(str, 8, 8))
            //Get rid of that pesky space people like to add
            if (SubStringBJ(str,9,9) == " ") then
                set text = SubStringBJ(str,10,StringLength(str))
            else
                set text = SubStringBJ(str,9,StringLength(str))
            endif
            set udg_Names[chatnum + id*10] = text
            call DisplayTextToForce( fp, "|c0000FF00Name " + I2S(chatnum) + " set to |r" + ColorName(udg_Names[chatnum + id*10],id))
        else
            call DisplayTextToForce( fp, "|c00FF0000This map uses the numbers 0-9 instead of symbols for character chatting.|r" )
        endif


    //Set Name
    elseif SubStringBJ(str, 1, 3) == "set" then
        if IsANumber(SubStringBJ(str, 4, 4)) then
            set chatnum = S2I(SubStringBJ(str, 4, 4))
            //Get rid of that pesky space people like to add
            if (SubStringBJ(str,5,5) == " ") then
                set text = SubStringBJ(str,6,StringLength(str))
            else
                set text = SubStringBJ(str,5,StringLength(str))
            endif
            set udg_Names[chatnum + id*10] = text
            call DisplayTextToForce( fp, "|c0000FF00Name " + I2S(chatnum) + " set to |r" + ColorName(udg_Names[chatnum + id*10],id))
        else
            call DisplayTextToForce( fp, "|c00FF0000This map uses the numbers 0-9 instead of symbols for character chatting.|r" )
        endif





    //Chat Name
    elseif IsANumber(SubStringBJ(str, 1, 1)) then

        set chatnum = S2I(SubStringBJ(str, 1, 1))

        //Get rid of that pesky space people like to add
        if (SubStringBJ(str,2,2) == " ") then
            set text = SubStringBJ(str,3,StringLength(str))
        else
            set text = SubStringBJ(str,2,StringLength(str))
        endif

        call DisplayTextToForce( GetPlayersAll(), ColorName(udg_Names[chatnum + id*10] + ": ",id) + text)        





    //Narrate (DMs Only)
    elseif GetBooleanAnd(SubStringBJ(str,1,1) == "-", IsPlayerInForce(pl, udg_Force[2])) then
        //Get rid of that pesky space people like to add
        if (SubStringBJ(str,2,2) == " ") then
            set text = SubStringBJ(str,3,StringLength(str))
        else
            set text = SubStringBJ(str,2,StringLength(str))
        endif
        call DisplayTextToForce(GetPlayersAll(), ColorName("- ", id) + text)






    //OOC to All (DMs Only)
    elseif GetBooleanAnd(SubStringBJ(str,1,1) == ".", IsPlayerInForce(pl, udg_Force[2])) then
        //Get rid of that pesky space people like to add
        if (SubStringBJ(str,2,2) == " ") then
            set text = SubStringBJ(str,3,StringLength(str))
        else
            set text = SubStringBJ(str,2,StringLength(str))
        endif
        call DisplayTextToForce( GetPlayersAll(), "    [" + ColorName("OOC: ",id) + text + "]")




    //List Names
    elseif StringCase(str, false) == "names" then
        set i = 0
        loop
            exitwhen i > 9
            if not(udg_Names[i + id*10] == null) then
                call DisplayTextToForce( fp, "|c0000FF00 " + I2S(i) + " - |r" + ColorName(udg_Names[i + id*10],id))
            endif
            set i = i + 1
        endloop




    //Debug
    elseif StringCase(str, false) == "debug" then
        call ForForce( GetPlayersAll(), function ShowLocalDebugBoard )



    elseif DoCommandEntered(id) then
        //is a command - prevents from being ooc


    else
        //not any command whatsoever - ooc chat
        if IsPlayerInForce(pl, udg_Force[2]) then
            call DisplayTextToForce( udg_Force[2], "    (" + ColorName("DMs: ",id) + str + ")")
        else
            call DisplayTextToForce( GetPlayersAll(), "    [" + ColorName("OOC: ",id) + str + "]")
        endif



    endif



endfunction










function ChatEntered takes nothing returns nothing
    local integer id
    set id = GetConvertedPlayerId(GetTriggerPlayer())

    //call DisplayTextToForce( GetPlayersAll(), I2S(id) )
    call DoChatSystem(id)

endfunction






function InitTrig_Chat takes nothing returns nothing

    local integer ip

    set gg_trg_Chat = CreateTrigger(  )
    call TriggerAddAction( gg_trg_Chat, function ChatEntered )

    //Add Event: Any Player types Any Chat Message
    set ip = 1
    loop
        exitwhen ip > 12
        call TriggerRegisterPlayerChatEvent( gg_trg_Chat, ConvertedPlayer(ip), "", false )
        set ip = ip + 1
    endloop

endfunction

 
DebugMultiboard
  Events
    Time - Every 2.00 seconds of game time
  Conditions
  Actions
    For each (Integer A) from 1 to 12, do (Actions)
      Loop - Actions
        If (All Conditions are True) then do (Then Actions) else do (Else Actions)
          If - Conditions
            ((Player((Integer A))) is in Force[1].) Equal to True
          Then - Actions
            Multiboard - Set the text for DebugBoard item in column 1, row (Integer A) to (String((Unit-type of HERO_Ref2[(Integer A)])))
            Multiboard - Set the text for DebugBoard item in column 1, row (Integer A) to Status[(Integer A)]
            Custom script: call MultiboardSetItemValueBJ( udg_DebugBoard, 2, GetForLoopIndexA(), ColorName(TranslateTo(UnitId2StringBJ(GetUnitTypeId(udg_HERO_Ref2[GetForLoopIndexA()]))),GetForLoopIndexA()) )
            If (All Conditions are True) then do (Then Actions) else do (Else Actions)
              If - Conditions
                (HERO_Ref2[(Integer A)] is alive) Equal to True
              Then - Actions
                Custom script: call MultiboardSetItemValueBJ( udg_DebugBoard, 3, GetForLoopIndexA(), ColorName("alive",GetForLoopIndexA()) )
              Else - Actions
                Custom script: call MultiboardSetItemValueBJ( udg_DebugBoard, 3, GetForLoopIndexA(), ColorName("dead",GetForLoopIndexA()) )
          Else - Actions
            If (All Conditions are True) then do (Then Actions) else do (Else Actions)
              If - Conditions
                ((Player((Integer A))) is in Force[2].) Equal to True
              Then - Actions
                Multiboard - Set the text for DebugBoard item in column 1, row (Integer A) to Status[(Integer A)]
                Custom script: call MultiboardSetItemValueBJ( udg_DebugBoard, 1, GetForLoopIndexA(), ColorName(udg_Status[GetForLoopIndexA()], GetForLoopIndexA()) )
                Multiboard - Set the text for DebugBoard item in column 2, row (Integer A) to DM_SubType[(Integer A)]
                Multiboard - Set the text for DebugBoard item in column 3, row (Integer A) to (String(DM_UnitType[(Integer A)]))
                Custom script: call MultiboardSetItemValueBJ( udg_DebugBoard, 3, GetForLoopIndexA(), ColorName(TranslateTo(UnitId2StringBJ(udg_DM_UnitType[GetForLoopIndexA()])),GetConvertedPlayerId(udg_DM_Player[GetForLoopIndexA()])) )
              Else - Actions
                Custom script: call MultiboardSetItemValueBJ( udg_DebugBoard, 1, GetForLoopIndexA(), ColorName("computer",GetForLoopIndexA()) )
function Trig_DebugMultiboardMake_Actions takes nothing returns nothing
    call TriggerSleepAction(0)

    call CreateMultiboardBJ( 4, 12, "Debug Info" )
    set udg_DebugBoard = GetLastCreatedMultiboard()
    set udg_DebugBoardCreated = true

    call MultiboardSetItemStyleBJ( GetLastCreatedMultiboard(), 0, 0, true, false )
    call MultiboardSetItemWidthBJ( GetLastCreatedMultiboard(), 0, 0, 7.00 )
    call MultiboardSetItemWidthBJ( GetLastCreatedMultiboard(), 4, 0, 4.00 )
    call MultiboardDisplayBJ( false, GetLastCreatedMultiboard() )
endfunction

//===========================================================================
function InitTrig_DebugMultiboardMake takes nothing returns nothing
    set gg_trg_DebugMultiboardMake = CreateTrigger(  )
    call TriggerAddAction( gg_trg_DebugMultiboardMake, function Trig_DebugMultiboardMake_Actions )
endfunction
 


//************************************
//************************************
//**********     CHAT       **********
//************************************
//************************************

function DMChatEntered takes nothing returns nothing
    //set udg_ChatString[GetConvertedPlayerId(GetTriggerPlayer())] = GetEventPlayerChatString()
endfunction

function ForDMChat takes nothing returns nothing
    //if GetBooleanAnd(udg_ChatString[GetConvertedPlayerId(GetEnumPlayer())] != "", udg_Echo[GetConvertedPlayerId(GetEnumPlayer())]) then
    //    call DisplayTextToForce( GetPlayersAll(), udg_ChatString[GetConvertedPlayerId(GetEnumPlayer())] )
    //    set udg_ChatString[GetConvertedPlayerId(GetEnumPlayer())] = ""
    //endif
//commands go here, including set1name, 1bla, -uc etc
endfunction

function MiscPoll takes nothing returns nothing
    call ForForce( udg_Force[2], function ForDMChat )
endfunction




function InitTrig_OldChat takes nothing returns nothing

    local integer i
    local string chars
    local string cur

    set udg_GUI_Misc_Chat = CreateTrigger(  )
    call TriggerAddAction( udg_GUI_Misc_Chat, function DMChatEntered )
    set i = 1
    set chars = "abcdefghijklmnopqrstuvwxyx1234567890!?.,;:()*$@=+-_ "
    loop
        exitwhen i > 52
        set cur = SubStringBJ(chars, i, i)
        call TriggerRegisterPlayerChatEvent( udg_GUI_Misc_Chat, ConvertedPlayer(9), cur, false )
        call TriggerRegisterPlayerChatEvent( udg_GUI_Misc_Chat, ConvertedPlayer(10), cur, false )
        call TriggerRegisterPlayerChatEvent( udg_GUI_Misc_Chat, ConvertedPlayer(11), cur, false )
        set i = i + 1
    endloop

    set udg_GUI_Misc_Poll = CreateTrigger(  )
    call TriggerRegisterTimerEventPeriodic( udg_GUI_Misc_Poll, 0.75 )
    call TriggerAddAction( udg_GUI_Misc_Poll, function MiscPoll )
endfunction

 
Someone Leaves
  Events
    Player - Player 2 (Blue) leaves the game
    Player - Player 3 (Teal) leaves the game
    Player - Player 4 (Purple) leaves the game
    Player - Player 6 (Orange) leaves the game
    Player - Player 7 (Green) leaves the game
    Player - Player 8 (Pink) leaves the game
    Player - Player 9 (Gray) leaves the game
    Player - Player 10 (Light Blue) leaves the game
    Player - Player 11 (Dark Green) leaves the game
    Player - Player 12 (Brown) leaves the game
  Conditions
  Actions
    If (All Conditions are True) then do (Then Actions) else do (Else Actions)
      If - Conditions
        ((Triggering player) is in Force[1].) Equal to True
      Then - Actions
        Custom script: set udg_TEMP_Unit = GetPlayerHero(GetConvertedPlayerId(GetTriggerPlayer()))
        For each (Integer A) from 1 to 6, do (Actions)
          Loop - Actions
            If (All Conditions are True) then do (Then Actions) else do (Else Actions)
              If - Conditions
                Or - Any (Conditions) are true
                  Conditions
                    Full Vial Equal to (Item-type of (Item carried by TEMP_Unit in slot (Integer A)))
                    Empty Vial Equal to (Item-type of (Item carried by TEMP_Unit in slot (Integer A)))
              Then - Actions
                Item - Remove (Item carried by TEMP_Unit in slot (Integer A))
              Else - Actions
                Hero - Drop the item from slot (Integer A) of TEMP_Unit.
        Special Effect - Create a special effect at (Position of TEMP_Unit) using Abilities\Spells\Human\MassTeleport\MassTeleportCaster.mdl
        Special Effect - Destroy (Last created special effect)
        Unit - Remove TEMP_Unit from the game
      Else - Actions
    Custom script: call DisplayTextToForce( GetPlayersAll(), ColorNamePl(GetTriggerPlayer()) + " has left the game." )



//*************************
//    checked for leaks
//*************************







function DoBounty takes nothing returns nothing

    local integer level
    local real pgold = 1.0  //probability of drop
    local real pitem = 0.1  //probability of drop
    local integer junk
    local location loc
    local location loc2

    set level = GetUnitLevel(GetDyingUnit())

    //call DisplayTextToForce( GetPlayersAll(), I2S(GetUnitUserData(GetDyingUnit())) )

    if IsUnitTrain(GetDyingUnit()) then
        //Training Room
        set pgold = pgold * 0.4
        set pitem = pitem * 0.4
    endif

    if GetRandomReal(0,1) <= pgold then

        if IsUnitType(GetTriggerUnit(), UNIT_TYPE_STRUCTURE) then
            //set level = GetUnitPointValue(GetDyingUnit())
            set level = R2I(GetUnitStateSwap(UNIT_STATE_MAX_LIFE, GetDyingUnit()) / 10)
            loop
                exitwhen level < 0
                set junk = GetRandomInt(1,10)

                set loc = GetUnitLoc(GetDyingUnit())
                set loc2 = PolarProjectionBJ(loc, GetRandomReal(25,200), GetRandomReal(0,360))
                call DropCoin(loc2, junk)
                call RemoveLocation(loc)
                call RemoveLocation(loc2)

                set level = level - junk * 5
            endloop
           

        elseif IsUnitType(GetTriggerUnit(), UNIT_TYPE_HERO) then
            set level = GetHeroLevel(GetDyingUnit()) * 3 * 5
            loop
                exitwhen level < 0
                set junk = GetRandomInt(1,10)

                set loc = GetUnitLoc(GetDyingUnit())
                set loc2 = PolarProjectionBJ(loc, GetRandomReal(25,150), GetRandomReal(0,360))
                call DropCoin(loc2, junk)
                call RemoveLocation(loc)
                call RemoveLocation(loc2)

                set level = level - junk * 5
            endloop


        //plain old unit - not summoned
        elseif not(IsUnitType(GetTriggerUnit(), UNIT_TYPE_SUMMONED)) then
            set loc = GetUnitLoc(GetDyingUnit())
            call DropCoin(loc, IBigShuffle(level))

            if level > 5 then
                if GetRandomReal(0,1) < pitem then
                    call CreateItemLoc( RandomItemDrop(level), loc )
                endif
            endif

            call RemoveLocation(loc)
        endif
    endif

endfunction

function InitTrig_Bounty takes nothing returns nothing
    set gg_trg_Bounty = CreateTrigger(  )
    call TriggerRegisterPlayerUnitEventSimple( gg_trg_Bounty, Player(0), EVENT_PLAYER_UNIT_DEATH )
    call TriggerAddAction( gg_trg_Bounty, function DoBounty )
endfunction

 
//this trigger just builds the constants table for
// all the item modifiers in the game.
//all MOD arrays are constants, 2d base 1 (inner size 10)

function CreateItemConstantsTable takes nothing returns nothing






  //PREFIXES

    set udg_MOD_P_Num = 6

      //Gold Increase:
    set udg_MOD_P_Name[11] = "Wealthy"
    set udg_MOD_P_Name[12] = "Rich"
    set udg_MOD_P_Name[13] = "Plentiful"
    set udg_MOD_P_Name[14] = "Greedy"
    set udg_MOD_P_Min[11] = 10
    set udg_MOD_P_Max[11] = 40
    set udg_MOD_P_Min[12] = 41
    set udg_MOD_P_Max[12] = 80
    set udg_MOD_P_Min[13] = 81
    set udg_MOD_P_Max[13] = 150
    set udg_MOD_P_Min[14] = 151
    set udg_MOD_P_Max[14] = 250

      //Drop Increase:
    set udg_MOD_P_Name[21] = "Lucky"
    set udg_MOD_P_Name[22] = "Lucky"
    set udg_MOD_P_Name[23] = "Fortuitous"
    set udg_MOD_P_Name[24] = "Fortuitous"
    set udg_MOD_P_Min[21] = 5
    set udg_MOD_P_Max[21] = 10
    set udg_MOD_P_Min[22] = 11
    set udg_MOD_P_Max[22] = 25
    set udg_MOD_P_Min[23] = 26
    set udg_MOD_P_Max[23] = 50
    set udg_MOD_P_Min[24] = 51
    set udg_MOD_P_Max[24] = 80

      //Experience Rate Increase:
    set udg_MOD_P_Name[31] = "Apprentice's"
    set udg_MOD_P_Name[32] = "Apprentice's"
    set udg_MOD_P_Name[33] = "Magus's"
    set udg_MOD_P_Name[34] = "Wizard's"
    set udg_MOD_P_Min[31] = 5
    set udg_MOD_P_Max[31] = 10
    set udg_MOD_P_Min[32] = 11
    set udg_MOD_P_Max[32] = 25
    set udg_MOD_P_Min[33] = 26
    set udg_MOD_P_Max[33] = 50
    set udg_MOD_P_Min[34] = 51
    set udg_MOD_P_Max[34] = 80

      //Damage Increase (%):
    set udg_MOD_P_Name[41] = "Jagged"
    set udg_MOD_P_Name[42] = "Brutal"
    set udg_MOD_P_Name[43] = "Savage"
    set udg_MOD_P_Name[44] = "Merciless"
    set udg_MOD_P_Min[41] = 5
    set udg_MOD_P_Max[41] = 10
    set udg_MOD_P_Min[42] = 11
    set udg_MOD_P_Max[42] = 25
    set udg_MOD_P_Min[43] = 26
    set udg_MOD_P_Max[43] = 50
    set udg_MOD_P_Min[44] = 51
    set udg_MOD_P_Max[44] = 80

      //Damage Increase (%):
    set udg_MOD_P_Name[51] = "Warrior's"
    set udg_MOD_P_Name[52] = "Knight's"
    set udg_MOD_P_Name[53] = "Lord's"
    set udg_MOD_P_Name[54] = "King's"
    set udg_MOD_P_Min[51] = 5
    set udg_MOD_P_Max[51] = 10
    set udg_MOD_P_Min[52] = 11
    set udg_MOD_P_Max[52] = 25
    set udg_MOD_P_Min[53] = 26
    set udg_MOD_P_Max[53] = 50
    set udg_MOD_P_Min[54] = 51
    set udg_MOD_P_Max[54] = 80

      //Defense Increase:
//    set udg_MOD_P_Name[61] = "Sturdy"
//    set udg_MOD_P_Name[62] = "Blessed"
//    set udg_MOD_P_Name[63] = "Saintly"
//    set udg_MOD_P_Name[64] = "Godly"
//    set udg_MOD_P_Min[61] = 1
//    set udg_MOD_P_Max[61] = 4
//    set udg_MOD_P_Min[62] = 5
//    set udg_MOD_P_Max[62] = 10
//    set udg_MOD_P_Min[63] = 11
//    set udg_MOD_P_Max[63] = 20
//    set udg_MOD_P_Min[64] = 21
//    set udg_MOD_P_Max[64] = 35

       //Mana Increase:
    set udg_MOD_P_Name[61] = "Lizard's"
    set udg_MOD_P_Name[62] = "Serpent's"
    set udg_MOD_P_Name[63] = "Drake's"
    set udg_MOD_P_Name[64] = "Wyrm's"
    set udg_MOD_P_Min[61] = 10
    set udg_MOD_P_Max[61] = 40
    set udg_MOD_P_Min[62] = 41
    set udg_MOD_P_Max[62] = 80
    set udg_MOD_P_Min[63] = 81
    set udg_MOD_P_Max[63] = 150
    set udg_MOD_P_Min[64] = 151
    set udg_MOD_P_Max[64] = 250





//SUFFIXES

    set udg_MOD_S_Num = 12

      //Gold Increase:
    set udg_MOD_S_Name[11] = "of Wealth"
    set udg_MOD_S_Name[12] = "of Riches"
    set udg_MOD_S_Name[13] = "of Plenty"
    set udg_MOD_S_Name[14] = "of Greed"
    set udg_MOD_S_Min[11] = 10
    set udg_MOD_S_Max[11] = 40
    set udg_MOD_S_Min[12] = 41
    set udg_MOD_S_Max[12] = 80
    set udg_MOD_S_Min[13] = 81
    set udg_MOD_S_Max[13] = 150
    set udg_MOD_S_Min[14] = 151
    set udg_MOD_S_Max[14] = 250

      //Drop Increase:
    set udg_MOD_S_Name[21] = "of Luck"
    set udg_MOD_S_Name[22] = "of Luck"
    set udg_MOD_S_Name[23] = "of Fortune"
    set udg_MOD_S_Name[24] = "of Fortune"
    set udg_MOD_S_Min[21] = 5
    set udg_MOD_S_Max[21] = 10
    set udg_MOD_S_Min[22] = 11
    set udg_MOD_S_Max[22] = 25
    set udg_MOD_S_Min[23] = 26
    set udg_MOD_S_Max[23] = 50
    set udg_MOD_S_Min[24] = 51
    set udg_MOD_S_Max[24] = 80

      //Experience Rate Increase:
    set udg_MOD_S_Name[31] = "of the Apprentice"
    set udg_MOD_S_Name[32] = "of the Apprentice"
    set udg_MOD_S_Name[33] = "of the Magus"
    set udg_MOD_S_Name[34] = "of the Wizard"
    set udg_MOD_S_Min[31] = 5
    set udg_MOD_S_Max[31] = 10
    set udg_MOD_S_Min[32] = 11
    set udg_MOD_S_Max[32] = 25
    set udg_MOD_S_Min[33] = 26
    set udg_MOD_S_Max[33] = 50
    set udg_MOD_S_Min[34] = 51
    set udg_MOD_S_Max[34] = 80

      //Damage Increase (fixed):
    set udg_MOD_S_Name[41] = "of Maiming"
    set udg_MOD_S_Name[42] = "of Gore"
    set udg_MOD_S_Name[43] = "of Carnage"
    set udg_MOD_S_Name[44] = "of Slaughter"
    set udg_MOD_S_Min[41] = 1
    set udg_MOD_S_Max[41] = 4
    set udg_MOD_S_Min[42] = 5
    set udg_MOD_S_Max[42] = 10
    set udg_MOD_S_Min[43] = 11
    set udg_MOD_S_Max[43] = 20
    set udg_MOD_S_Min[44] = 21
    set udg_MOD_S_Max[44] = 35

      //Damage Increase (fixed):
    set udg_MOD_S_Name[51] = "of Worth"
    set udg_MOD_S_Name[52] = "of Craftsmanship"
    set udg_MOD_S_Name[53] = "of Quality"
    set udg_MOD_S_Name[54] = "of Excellence"
    set udg_MOD_S_Min[51] = 1
    set udg_MOD_S_Max[51] = 4
    set udg_MOD_S_Min[52] = 5
    set udg_MOD_S_Max[52] = 10
    set udg_MOD_S_Min[53] = 11
    set udg_MOD_S_Max[53] = 20
    set udg_MOD_S_Min[54] = 21
    set udg_MOD_S_Max[54] = 35

      //Attack Speed Increase:
    set udg_MOD_S_Name[61] = "of Readiness"
    set udg_MOD_S_Name[62] = "of Alacrity"
    set udg_MOD_S_Name[63] = "of Swiftness"
    set udg_MOD_S_Name[64] = "of Quickness"
    set udg_MOD_S_Min[61] = 5
    set udg_MOD_S_Max[61] = 10
    set udg_MOD_S_Min[62] = 11
    set udg_MOD_S_Max[62] = 25
    set udg_MOD_S_Min[63] = 26
    set udg_MOD_S_Max[63] = 50
    set udg_MOD_S_Min[64] = 51
    set udg_MOD_S_Max[64] = 80

      //Movement Speed Increase:
    set udg_MOD_S_Name[71] = "of Walking"
    set udg_MOD_S_Name[72] = "of Pacing"
    set udg_MOD_S_Name[73] = "of Haste"
    set udg_MOD_S_Name[74] = "of Speed"
    set udg_MOD_S_Min[71] = 5
    set udg_MOD_S_Max[71] = 10
    set udg_MOD_S_Min[72] = 11
    set udg_MOD_S_Max[72] = 25
    set udg_MOD_S_Min[73] = 26
    set udg_MOD_S_Max[73] = 50
    set udg_MOD_S_Min[74] = 51
    set udg_MOD_S_Max[74] = 80

      //Strength Increase:
    set udg_MOD_S_Name[81] = "of Strength"
    set udg_MOD_S_Name[82] = "of Might"
    set udg_MOD_S_Name[83] = "of the Ox"
    set udg_MOD_S_Name[84] = "of the Titans"
    set udg_MOD_S_Min[81] = 1
    set udg_MOD_S_Max[81] = 4
    set udg_MOD_S_Min[82] = 5
    set udg_MOD_S_Max[82] = 10
    set udg_MOD_S_Min[83] = 11
    set udg_MOD_S_Max[83] = 20
    set udg_MOD_S_Min[84] = 21
    set udg_MOD_S_Max[84] = 35

      //Agility Increase:
    set udg_MOD_S_Name[91] = "of Agility"
    set udg_MOD_S_Name[92] = "of Skill"
    set udg_MOD_S_Name[93] = "of Accuracy"
    set udg_MOD_S_Name[94] = "of Precision"
    set udg_MOD_S_Min[91] = 1
    set udg_MOD_S_Max[91] = 4
    set udg_MOD_S_Min[92] = 5
    set udg_MOD_S_Max[92] = 10
    set udg_MOD_S_Min[93] = 11
    set udg_MOD_S_Max[93] = 20
    set udg_MOD_S_Min[94] = 21
    set udg_MOD_S_Max[94] = 35

      //Intelligence Increase:
    set udg_MOD_S_Name[101] = "of Intelligence"
    set udg_MOD_S_Name[102] = "of Wit"
    set udg_MOD_S_Name[103] = "of Mind"
    set udg_MOD_S_Name[104] = "of Consciousness"
    set udg_MOD_S_Min[101] = 1
    set udg_MOD_S_Max[101] = 4
    set udg_MOD_S_Min[102] = 5
    set udg_MOD_S_Max[102] = 10
    set udg_MOD_S_Min[103] = 11
    set udg_MOD_S_Max[103] = 20
    set udg_MOD_S_Min[104] = 21
    set udg_MOD_S_Max[104] = 35

      //Life Increase:
    set udg_MOD_S_Name[111] = "of the Jackal"
    set udg_MOD_S_Name[112] = "of the Fox"
    set udg_MOD_S_Name[113] = "of the Wolf"
    set udg_MOD_S_Name[114] = "of the Whale"
    set udg_MOD_S_Min[111] = 30
    set udg_MOD_S_Max[111] = 80
    set udg_MOD_S_Min[112] = 81
    set udg_MOD_S_Max[112] = 150
    set udg_MOD_S_Min[113] = 151
    set udg_MOD_S_Max[113] = 250
    set udg_MOD_S_Min[114] = 251
    set udg_MOD_S_Max[114] = 400

      //Mana Increase:
    set udg_MOD_S_Name[121] = "of Energy"
    set udg_MOD_S_Name[122] = "of Brilliance"
    set udg_MOD_S_Name[123] = "of Sorcery"
    set udg_MOD_S_Name[124] = "of Wizardry"
    set udg_MOD_S_Min[121] = 10
    set udg_MOD_S_Max[121] = 40
    set udg_MOD_S_Min[122] = 41
    set udg_MOD_S_Max[122] = 80
    set udg_MOD_S_Min[123] = 81
    set udg_MOD_S_Max[123] = 150
    set udg_MOD_S_Min[124] = 151
    set udg_MOD_S_Max[124] = 250





endfunction







function InitTrig_ItemConst takes nothing returns nothing
    set gg_trg_ItemConst = CreateTrigger(  )
    call TriggerAddAction( gg_trg_ItemConst, function CreateItemConstantsTable )
endfunction

 
//This holds the item selection events to display item
// information in the player's leaderboard.




function GetItemValueText takes integer typ, integer value returns string
    if typ > 1 then
        return "Health: " + I2S(value)
    else
        return "Damage: " + I2S(value)
    endif
endfunction

function GetItemPrefixValueText takes integer prefix, integer value returns string
    local integer typ
    set typ = GetArrayMega(prefix)

    if typ == 0 then
        return ""
    elseif typ == 1 then
        return "+" + I2S(value) + "% gold"
    elseif typ == 2 then
        return "+" + I2S(value) + "% chance to find items"
    elseif typ == 3 then
        return "+" + I2S(value) + "% experience rate"
    elseif typ == 4 then
        return "+" + I2S(value) + "% damage"
    elseif typ == 5 then
        return "+" + I2S(value) + "% damage"
    elseif typ == 6 then
        return "+" + I2S(value) + " mana"
    endif

    return "<unknown effect>"
endfunction





function GetItemSuffixValueText takes integer suffix, integer value returns string
    local integer typ
    set typ = GetArrayMega(suffix)

    if typ == 0 then
        return ""
    elseif typ == 1 then
        return "+" + I2S(value) + "% gold"
    elseif typ == 2 then
        return "+" + I2S(value) + "% chance to find items"
    elseif typ == 3 then
        return "+" + I2S(value) + "% experience rate"
    elseif typ == 4 then
        return "+" + I2S(value) + " damage"
    elseif typ == 5 then
        return "+" + I2S(value) + " damage"
    elseif typ == 6 then
        return "+" + I2S(value) + "% attack speed"
    elseif typ == 7 then
        return "+" + I2S(value) + "% movement speed"
    elseif typ == 8 then
        return "+" + I2S(value) + " strength"
    elseif typ == 9 then
        return "+" + I2S(value) + " agility"
    elseif typ == 10 then
        return "+" + I2S(value) + " intelligence"
    elseif typ == 11 then
        return "+" + I2S(value) + " life"
    elseif typ == 12 then
        return "+" + I2S(value) + " mana"
    endif

    return "<unknown effect>"
endfunction




function onItemSelectionEvent takes nothing returns nothing

    local integer id = 0
    local player pl
    local force fp
    local unit un
    local integer iid

    set id = GetConvertedPlayerId(GetTriggerPlayer())
    set pl = ConvertedPlayer(id)
    set fp = bj_FORCE_PLAYER[id-1]
    set un = GetTriggerUnit()

    if isItem(un) then

        set iid = FindItemID(un)
        call LeaderboardAddItemBJ( ConvertedPlayer(8), udg_Board[id], "", 0 )
        if udg_ITEM_Prefix[iid] > 0 then
            call LeaderboardAddItemBJ( ConvertedPlayer(9), udg_Board[id], "|c0000FFFF" + CenterText(GetItemPrefixName(udg_ITEM_Prefix[iid])) + "|r", 0 )
        else
            call LeaderboardRemovePlayerItemBJ( ConvertedPlayer(9), udg_Board[id] )
        endif
        call LeaderboardAddItemBJ( ConvertedPlayer(10), udg_Board[id], "|c00FFFFFF" + CenterText(GetItemMainName(udg_ITEM_Type[iid], udg_ITEM_SubType[iid])) + "|r", 0 )
        if udg_ITEM_Suffix[iid] > 0 then
            call LeaderboardAddItemBJ( ConvertedPlayer(11), udg_Board[id], "|c0000FFFF" + CenterText(GetItemSuffixName(udg_ITEM_Suffix[iid])) + "|r", 0 )
        else
            call LeaderboardRemovePlayerItemBJ( ConvertedPlayer(11), udg_Board[id] )
        endif
        call LeaderboardAddItemBJ( ConvertedPlayer(12), udg_Board[id], "", 0 )
        call LeaderboardAddItemBJ( ConvertedPlayer(13), udg_Board[id], "|c00FFFFFFReq: Lvl 1, 15/15/15|r", 0 )
        call LeaderboardAddItemBJ( ConvertedPlayer(14), udg_Board[id], "|c00AAAAAA" + GetItemValueText(udg_ITEM_Type[iid], udg_ITEM_Val[iid]) + "|r", 0 )
        if udg_ITEM_Prefix[iid] > 0 then
            call LeaderboardAddItemBJ( ConvertedPlayer(15), udg_Board[id], "|c00AAAAAA" + GetItemPrefixValueText(udg_ITEM_Prefix[iid], udg_ITEM_PrefixVal[iid]) + "", 0 )
        else
            call LeaderboardRemovePlayerItemBJ( ConvertedPlayer(15), udg_Board[id] )
        endif
        if udg_ITEM_Suffix[iid] > 0 then
            call LeaderboardAddItemBJ( ConvertedPlayer(16), udg_Board[id], "|c00AAAAAA" + GetItemSuffixValueText(udg_ITEM_Suffix[iid], udg_ITEM_SuffixVal[iid]) + "", 0 )
        else
            call LeaderboardRemovePlayerItemBJ( ConvertedPlayer(16), udg_Board[id] )
        endif

    else
        call LeaderboardRemovePlayerItemBJ( ConvertedPlayer(8), udg_Board[id] )
        call LeaderboardRemovePlayerItemBJ( ConvertedPlayer(9), udg_Board[id] )
        call LeaderboardRemovePlayerItemBJ( ConvertedPlayer(10), udg_Board[id] )
        call LeaderboardRemovePlayerItemBJ( ConvertedPlayer(11), udg_Board[id] )
        call LeaderboardRemovePlayerItemBJ( ConvertedPlayer(12), udg_Board[id] )
        call LeaderboardRemovePlayerItemBJ( ConvertedPlayer(13), udg_Board[id] )
        call LeaderboardRemovePlayerItemBJ( ConvertedPlayer(14), udg_Board[id] )
        call LeaderboardRemovePlayerItemBJ( ConvertedPlayer(15), udg_Board[id] )
        call LeaderboardRemovePlayerItemBJ( ConvertedPlayer(16), udg_Board[id] )
    endif

endfunction










function ForItemBoardInit takes nothing returns nothing
    call TriggerRegisterPlayerSelectionEventBJ( udg_ITEM_Click, GetEnumPlayer(), true )
endfunction


function InitItemBoards takes nothing returns nothing
    set udg_ITEM_Click = CreateTrigger()
    call TriggerAddAction(udg_ITEM_Click, function onItemSelectionEvent)
    call ForForce( GetPlayersAll(), function ForItemBoardInit )
endfunction





function InitTrig_ItemBoard takes nothing returns nothing
    set gg_trg_ItemBoard = CreateTrigger(  )
    call TriggerAddAction( gg_trg_ItemBoard, function InitItemBoards )
endfunction

 
function isSword takes integer t returns boolean
    if t == 'I01F' then
    elseif t == 'I01E' then
    elseif t == 'I01G' then
    elseif t == 'I01H' then
    elseif t == 'I01I' then
    elseif t == 'I01J' then

    elseif t == 'I020' then
    elseif t == 'I01W' then
    elseif t == 'I021' then
    elseif t == 'I01Z' then
    elseif t == 'I01Y' then
    elseif t == 'I01X' then
    elseif t == 'I02I' then
    elseif t == 'I02J' then
    else
        return false
    endif
    return true
endfunction

function isBolt takes integer t returns boolean
    if t == 'I01L' then
    elseif t == 'I01M' then
    elseif t == 'I01K' then
    elseif t == 'I01N' then
    elseif t == 'I01O' then
    elseif t == 'I01P' then

    elseif t == 'I025' then
    elseif t == 'I026' then
    elseif t == 'I027' then
    elseif t == 'I024' then
    elseif t == 'I023' then
    elseif t == 'I022' then
    else
        return false
    endif
    return true
endfunction

function isStaff takes integer t returns boolean
    if t == 'I019' then
    elseif t == 'I01A' then
    elseif t == 'I017' then
    elseif t == 'I01B' then
    elseif t == 'I01C' then
    elseif t == 'I01D' then

    elseif t == 'I013' then
    elseif t == 'I01S' then
    elseif t == 'I01R' then
    elseif t == 'I01U' then
    elseif t == 'I01V' then
    elseif t == 'I02E' then
    else
        return false
    endif
    return true
endfunction

function isWeapon takes integer t returns boolean
    if isSword(t) then
    elseif isBolt(t) then
    elseif isStaff(t) then
    else
        return false
    endif
    return true
endfunction

function isLeather takes integer t returns boolean
    if t == 'I00R' then
    elseif t == 'I00S' then
    elseif t == 'I00T' then
    elseif t == 'I00U' then
    elseif t == 'I00V' then
    elseif t == 'I00Q' then
    else
        return false
    endif
    return true
endfunction

function isRobe takes integer t returns boolean
    if t == 'I014' then
    elseif t == 'I012' then
    elseif t == 'I018' then
    elseif t == 'I015' then
    elseif t == 'I016' then
    elseif t == 'I01Q' then
    elseif t == 'I024' then
    elseif t == 'I02F' then
    else
        return false
    endif
    return true
endfunction

function isPlate takes integer t returns boolean
    if t == 'I00W' then
    elseif t == 'I00X' then
    elseif t == 'I00Y' then
    elseif t == 'I00Z' then
    elseif t == 'I010' then
    elseif t == 'I011' then
    elseif t == 'I02K' then
    else
        return false
    endif
    return true
endfunction

function isArmor takes integer t returns boolean
    if isPlate(t) then
    elseif isRobe(t) then
    elseif isLeather(t) then
    else
        return false
    endif
    return true
endfunction





function isWarrior takes integer t returns boolean
    if t == 'H001' then
    elseif t == 'H008' then
    elseif t == 'O000' then
    elseif t == 'O001' then
    elseif t == 'U003' then
    elseif t == 'U001' then
    elseif t == 'E004' then
    elseif t == 'E006' then
    elseif t == 'E001' then
    elseif t == 'H00A' then
    elseif t == 'H00L' then
    elseif t == 'H00E' then
    elseif t == 'U006' then
    elseif t == 'E00D' then
    elseif t == 'O007' then
    elseif t == 'U005' then
    elseif t == 'E00B' then
    else
        return false
    endif
    return true
endfunction

function isSpellcaster takes integer t returns boolean
    if t == 'H000' then
    elseif t == 'H005' then
    elseif t == 'O004' then
    elseif t == 'O003' then
    elseif t == 'O006' then
    elseif t == 'U002' then
    elseif t == 'U000' then
    elseif t == 'E005' then
    else
        return false
    endif
    return true
endfunction

function isRanger takes integer t returns boolean
    if t == 'H009' then
    elseif t == 'H007' then
    elseif t == 'O002' then
    elseif t == 'N005' then
    elseif t == 'N004' then
    elseif t == 'E003' then
    elseif t == 'H00M' then
    else
        return false
    endif
    return true
endfunction





function DoItemError takes string str returns nothing
    call DisplayTextToForce( GetForceOfPlayer(GetOwningPlayer(GetManipulatingUnit())), "|cffffcc00" + str + "|r")
endfunction





function Trig_ItemHandling_Actions takes nothing returns nothing
    local integer it
    local item im
    local integer ut
    local integer i
    local boolean drop
    set im = GetManipulatedItem()
    set it = GetItemTypeId(GetManipulatedItem())
    set ut = GetUnitTypeId(GetManipulatingUnit())


    if GetItemUserData(GetManipulatedItem()) == 2 then
        //spellbook being re-picked up

    elseif GetItemUserData(GetManipulatedItem()) == 1 and IsPlayerInForce(GetOwningPlayer(GetManipulatingUnit()), udg_Force[1]) then
        call UnitRemoveItemSwapped( GetManipulatedItem(), GetManipulatingUnit() )
        //prevent heroes from giving eachother items

    elseif IsPlayerInForce(GetOwningPlayer(GetManipulatingUnit()), udg_Force[3]) then
        //NPC heroes can carry whatever they want

    elseif isWeapon(it) then

        if isWarrior(ut) and not(isSword(it)) then
            if isBolt(it) then
                call DoItemError("Warriors cannot carry Bolts or Arrowheads." )
            else
                call DoItemError("Warriors cannot carry Staffs, Wands or Spellbooks." )
            endif
            call UnitRemoveItemSwapped( GetManipulatedItem(), GetManipulatingUnit() )
        elseif isRanger(ut) and not(isBolt(it)) then
            if isSword(it) then
                call DoItemError("Rangers cannot carry Swords, Axes, Mauls or Hammers." )
            else
                call DoItemError("Rangers cannot carry Staffs, Wands or Spellbooks." )
            endif
            call UnitRemoveItemSwapped( GetManipulatedItem(), GetManipulatingUnit() )
        elseif isSpellcaster(ut) and not(isStaff(it)) then
            if isBolt(it) then
                call DoItemError("Spellcasters cannot carry Bolts or Arrowheads." )
            else
                call DoItemError("Spellcasters cannot carry Swords, Axes, Mauls or Hammers." )
            endif
            call UnitRemoveItemSwapped( GetManipulatedItem(), GetManipulatingUnit() )
        else
            set i = 1
            loop
                exitwhen i > 6
                if isWeapon(GetItemTypeId(UnitItemInSlotBJ(GetManipulatingUnit(), i))) and not(UnitItemInSlotBJ(GetManipulatingUnit(), i) == GetManipulatedItem()) then
                    call UnitRemoveItemFromSlotSwapped( i, GetManipulatingUnit() )
                    if isStaff(it) then
                        //fix spellbook empty bug
                        call SetItemUserData( im, 2 )
                        call UnitRemoveItemSwapped( im, GetManipulatingUnit() )
                        call UnitAddItemSwapped( im, GetManipulatingUnit() )
                    endif
                    call UnitDropItemSlotBJ( GetManipulatingUnit(), im, i )
                    call DoItemError("You may only carry one weapon at a time.")
                endif
                set i = i + 1
            endloop
            if isStaff(it) then
                call TriggerSleepAction(0)
                call SetItemUserData( im, 0 )
            endif
        endif

    elseif isArmor(it) then

        if isPlate(it) and isSpellcaster(ut) then
            call DoItemError("Spellcasters cannot carry Plate armor." )
            call UnitRemoveItemSwapped( GetManipulatedItem(), GetManipulatingUnit() )
        elseif isRobe(it) and isWarrior(ut) then
            call DoItemError("Warriors cannot carry Robe armor." )
            call UnitRemoveItemSwapped( GetManipulatedItem(), GetManipulatingUnit() )
        else
            set i = 1
            loop
                exitwhen i > 6
                if isArmor(GetItemTypeId(UnitItemInSlotBJ(GetManipulatingUnit(), i))) and not(UnitItemInSlotBJ(GetManipulatingUnit(), i) == GetManipulatedItem()) then
                    call UnitRemoveItemFromSlotSwapped( i, GetManipulatingUnit() )
                    call UnitDropItemSlotBJ( GetManipulatingUnit(), GetManipulatedItem(), i )
                    call DoItemError("You may only carry one suit of armor at a time.")
                endif
                set i = i + 1
            endloop
        endif

    endif
endfunction

function InitTrig_ItemHandling takes nothing returns nothing
    set gg_trg_ItemHandling = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_ItemHandling, EVENT_PLAYER_UNIT_PICKUP_ITEM )
    call TriggerAddAction( gg_trg_ItemHandling, function Trig_ItemHandling_Actions )
endfunction

 
ItemDropped
  Events
    Unit - A unit Loses an item
  Conditions
    (Custom value of (Item being manipulated)) Not equal to 2
    ((Owner of (Hero manipulating item)) is in Force[1].) Equal to True
  Actions
    -------- PREVENT PEOPLE FROM GIVING ITEMS --------
    Custom script: local item udg_TEMP_Item
    Set VariableSet TEMP_Item = (Item being manipulated)
    Item - Set the custom value of TEMP_Item to 1
    Wait 0.00 seconds
    Item - Set the custom value of TEMP_Item to 0
function Trig_ItemDropped_Copy_Conditions takes nothing returns boolean
    if ( not ( GetItemUserData(GetManipulatedItem()) != 2 ) ) then
        return false
    endif
    if ( not ( IsPlayerInForce(GetOwningPlayer(GetManipulatingUnit()), udg_Force[1]) == true ) ) then
        return false
    endif
    return true
endfunction

function Trig_ItemDropped_Copy_Actions takes nothing returns nothing
    // PREVENT PEOPLE FROM GIVING ITEMS
    local item udg_TEMP_Item
    set udg_TEMP_Item = GetManipulatedItem()
    call SetItemUserData( udg_TEMP_Item, 1 )
    call TriggerSleepAction( 0.00 )
    call SetItemUserData( udg_TEMP_Item, 0 )
endfunction

//===========================================================================
function InitTrig_ItemDropped_Copy takes nothing returns nothing
    set gg_trg_ItemDropped_Copy = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_ItemDropped_Copy, EVENT_PLAYER_UNIT_DROP_ITEM )
    call TriggerAddCondition( gg_trg_ItemDropped_Copy, Condition( function Trig_ItemDropped_Copy_Conditions ) )
    call TriggerAddAction( gg_trg_ItemDropped_Copy, function Trig_ItemDropped_Copy_Actions )
endfunction

 



//*************************
//    checked for leaks
//*************************




function DoTrainingRoomEnumUnits takes nothing returns nothing

    local location loc
    local location loc2
    local real distance

    set loc = GetUnitLoc(GetEnumUnit())
    set loc2 = GetUnitLoc(udg_TRAIN_CurRoom)
    set distance = DistanceBetweenPoints(loc, loc2)
    call RemoveLocation(loc)
    call RemoveLocation(loc2)

    if GetOwningPlayer(GetEnumUnit()) == ConvertedPlayer(1) then

        if GetBooleanAnd(distance > 700, distance < 1200) then
            if IsKillableTrainUnit(GetEnumUnit()) then
                call KillUnit(GetEnumUnit())
            endif
        elseif distance < 700 then
            if IsCountableTrainUnit(GetEnumUnit()) then
                set udg_TRAIN_CountBad = udg_TRAIN_CountBad + GetUnitLevel(GetEnumUnit())
            endif
        endif

    else

        if IsCountableTrainUnit(GetEnumUnit()) then
            if (distance < 700) then
                set udg_TRAIN_CountGood = udg_TRAIN_CountGood + GetUnitLevel(GetEnumUnit())
                set udg_TRAIN_CountGoodTotal = udg_TRAIN_CountGoodTotal + 1
            endif
        endif

    endif

endfunction




function GetTrainingUnitType takes nothing returns integer
    local integer level
    set level = R2I(I2R(udg_TRAIN_CountGood) / I2R(udg_TRAIN_CountGoodTotal))

    if level < 6 then
        return udg_TRAIN_Type[GetRandomInt(1, 9) + level * 10]
    else
        return udg_TRAIN_Type[GetRandomInt(1, 9) + IMaxBJ(IMinBJ(IShuffle((level - 5)/2 + 5),9),0) * 10]
    endif
endfunction



function DoEnumTrainingRoom takes nothing returns nothing

    local integer utype
    local integer lvl

    local location trainloc
    local location loc
    local group grp

    set udg_TRAIN_CurRoom = GetEnumUnit()

    if IsUnitAliveBJ(udg_TRAIN_CurRoom) then
        set trainloc = GetUnitLoc(udg_TRAIN_CurRoom)

        set udg_TRAIN_CountGood = 0
        set udg_TRAIN_CountGoodTotal = 0
        set udg_TRAIN_CountBad = 0

        call MoveRectToLoc( gg_rct_TrainingRoom, trainloc )

        set grp = GetUnitsInRectAll(gg_rct_TrainingRoom)
        call ForGroupBJ( grp, function DoTrainingRoomEnumUnits )
        call DestroyGroup(grp)

        if udg_TRAIN_CountGood > udg_TRAIN_CountBad then
            set loc = PolarProjectionBJ(trainloc, GetRandomReal(0, 600.00), GetRandomReal(0, 360.00))
            call CreateNUnitsAtLoc( 1, GetTrainingUnitType(), ConvertedPlayer(1), loc, GetRandomDirectionDeg() )
            call RemoveLocation(loc)
            call SetUnitTrain( GetLastCreatedUnit(), true )
        endif

        call RemoveLocation(trainloc)
    else

        call GroupRemoveUnitSimple( GetEnumUnit(), udg_TRAIN_Rooms )
    endif
endfunction




function TrainingRoomPoll takes nothing returns nothing
    call ForGroupBJ( udg_TRAIN_Rooms, function DoEnumTrainingRoom )
endfunction





function InitTrig_Training_Room takes nothing returns nothing

    set udg_TRAIN_Type[11] = 'nspb'
    set udg_TRAIN_Type[12] = 'nspg'
    set udg_TRAIN_Type[13] = 'ngna'
    set udg_TRAIN_Type[14] = 'ngno'
    set udg_TRAIN_Type[15] = 'nmrl'
    set udg_TRAIN_Type[16] = 'nsty'
    set udg_TRAIN_Type[17] = 'nsat'
    set udg_TRAIN_Type[18] = 'nban'
    set udg_TRAIN_Type[19] = 'nwiz'
    set udg_TRAIN_Type[21] = 'nftr'
    set udg_TRAIN_Type[22] = 'nfsp'
    set udg_TRAIN_Type[23] = 'ngrk'
    set udg_TRAIN_Type[24] = 'nmrr'
    set udg_TRAIN_Type[25] = 'nltl'
    set udg_TRAIN_Type[26] = 'nwlt'
    set udg_TRAIN_Type[27] = 'nbrg'
    set udg_TRAIN_Type[28] = 'nfgu'
    set udg_TRAIN_Type[29] = 'ndmu'
    set udg_TRAIN_Type[31] = 'nbdr'
    set udg_TRAIN_Type[32] = 'nftt'
    set udg_TRAIN_Type[33] = 'ngns'
    set udg_TRAIN_Type[34] = 'ngnb'
    set udg_TRAIN_Type[35] = 'ngnw'
    set udg_TRAIN_Type[36] = 'nmrm'
    set udg_TRAIN_Type[37] = 'nogr'
    set udg_TRAIN_Type[38] = 'nrog'
    set udg_TRAIN_Type[39] = 'nsc2'
    set udg_TRAIN_Type[41] = 'nftb'
    set udg_TRAIN_Type[42] = 'nfsh'
    set udg_TRAIN_Type[43] = 'nfrl'
    set udg_TRAIN_Type[44] = 'nfrs'
    set udg_TRAIN_Type[45] = 'nsgt'
    set udg_TRAIN_Type[46] = 'nwlg'
    set udg_TRAIN_Type[47] = 'nowb'
    set udg_TRAIN_Type[48] = 'nass'
    set udg_TRAIN_Type[49] = 'nfgb'
    set udg_TRAIN_Type[51] = 'ngnv'
    set udg_TRAIN_Type[52] = 'nomg'
    set udg_TRAIN_Type[53] = 'nogm'
    set udg_TRAIN_Type[54] = 'nstl'
    set udg_TRAIN_Type[55] = 'nkol'
    set udg_TRAIN_Type[56] = 'nsln'
    set udg_TRAIN_Type[57] = 'nslr'
    set udg_TRAIN_Type[58] = 'nenf'
    set udg_TRAIN_Type[59] = 'nwzg'
    set udg_TRAIN_Type[61] = 'nrdr'
    set udg_TRAIN_Type[62] = 'nftk'
    set udg_TRAIN_Type[63] = 'ngst'
    set udg_TRAIN_Type[64] = 'nsqe'
    set udg_TRAIN_Type[65] = 'nthl'
    set udg_TRAIN_Type[66] = 'nowe'
    set udg_TRAIN_Type[67] = 'nfrb'
    set udg_TRAIN_Type[68] = 'nsbm'
    set udg_TRAIN_Type[69] = 'nmmu'
    set udg_TRAIN_Type[71] = 'nogl'
    set udg_TRAIN_Type[72] = 'nfrg'
    set udg_TRAIN_Type[73] = 'nfre'
    set udg_TRAIN_Type[74] = 'nhrq'
    set udg_TRAIN_Type[75] = 'nrzg'
    set udg_TRAIN_Type[76] = 'nslv'
    set udg_TRAIN_Type[77] = 'nbld'
    set udg_TRAIN_Type[78] = 'npfm'
    set udg_TRAIN_Type[79] = 'nehy'
    set udg_TRAIN_Type[81] = 'nfra'
    set udg_TRAIN_Type[82] = 'ncnk'
    set udg_TRAIN_Type[83] = 'nowk'
    set udg_TRAIN_Type[84] = 'ninm'
    set udg_TRAIN_Type[85] = 'ndqp'
    set udg_TRAIN_Type[86] = 'nbal'
    set udg_TRAIN_Type[87] = 'ninf'
    set udg_TRAIN_Type[88] = 'nwzd'
    set udg_TRAIN_Type[89] = 'nelb'
    set udg_TRAIN_Type[91] = 'nggr'
    set udg_TRAIN_Type[92] = 'nrwm'
    set udg_TRAIN_Type[93] = 'nstw'
    set udg_TRAIN_Type[94] = 'nsth'
    set udg_TRAIN_Type[95] = 'nsgg'
    set udg_TRAIN_Type[96] = 'nsll'
    set udg_TRAIN_Type[97] = 'nerw'
    set udg_TRAIN_Type[98] = 'nsqa'
    set udg_TRAIN_Type[99] = 'nahy'

    call CreateNUnitsAtLoc( 1, 'h00B', ConvertedPlayer(1), GetRectCenter(gg_rct_TrainingRoomMake), 270.00 )
    call GroupAddUnitSimple( GetLastCreatedUnit(), udg_TRAIN_Rooms )

    set gg_trg_Training_Room = CreateTrigger(  )
    call TriggerRegisterTimerEventPeriodic( gg_trg_Training_Room, 1.00 )
    call TriggerAddAction( gg_trg_Training_Room, function TrainingRoomPoll )
endfunction

 



function HeroSpawn takes nothing returns nothing

    local integer id = 0
    local player pl
    local force fp

    set id = GetConvertedPlayerId(GetTriggerPlayer())
    set pl = ConvertedPlayer(id)
    set fp = bj_FORCE_PLAYER[id-1]

//    if GetBooleanAnd(GetOwningPlayer(GetTriggerUnit()) == Player(PLAYER_NEUTRAL_PASSIVE), RectContainsUnit(gg_rct_HeroSelector, GetTriggerUnit())) then

//        call ClearScreenForce(fp)
        call CreateNUnitsAtLocFacingLocBJ( 1, GetUnitTypeId(GetTriggerUnit()), pl, GetUnitLoc(gg_unit_h006_0197), OffsetLocation(GetUnitLoc(gg_unit_h006_0197), 0, 500.00) )
//        set udg_HERO_Ref[id] = GetLastCreatedUnit()
        call UnitAddItemByIdSwapped( 'I001', GetLastCreatedUnit() )
        call AddSpecialEffectLocBJ( GetUnitLoc(GetTriggerUnit()), "Abilities\\Spells\\Human\\MassTeleport\\MassTeleportTarget.mdl" )
        call DestroyEffectBJ( GetLastCreatedEffectBJ() )

        call ResetToGameCameraForPlayer( pl, 0 )
        call PanCameraToTimedLocForPlayer( pl, GetUnitLoc(gg_unit_h006_0197), 0 )

//        call SetCameraTargetControllerNoZForPlayer( pl, GetLastCreatedUnit(), 0, 0, false )

        set udg_HERO_Ref2[id] = GetLastCreatedUnit() //should ONLY be used for camera

        if isSpellcaster(GetUnitTypeId(GetTriggerUnit())) then
            call UnitAddItemByIdSwapped( 'I014', GetLastCreatedUnit() )
        elseif isWarrior(GetUnitTypeId(GetTriggerUnit())) then
            call UnitAddItemByIdSwapped( 'I00W', GetLastCreatedUnit() )
        else
            call UnitAddItemByIdSwapped( 'I00R', GetLastCreatedUnit() )
        endif

        if not(udg_HERO_AllowDuplicates) then
            call RemoveUnit(GetTriggerUnit())
        endif

        if GetPlayerState(GetTriggerPlayer(), PLAYER_STATE_RESOURCE_LUMBER) > 0 then
            call AddHeroXPSwapped( GetPlayerState(pl, PLAYER_STATE_RESOURCE_LUMBER), GetLastCreatedUnit(), true )
            call SetPlayerStateBJ( pl, PLAYER_STATE_RESOURCE_LUMBER, 0 )
        endif




        //make sure teleport sound works
        call TriggerSleepAction(0)
        call AddSpecialEffectLocBJ( GetUnitLoc(GetPlayerHero(id)), "Abilities\\Spells\\Human\\MassTeleport\\MassTeleportTarget.mdl" )
        call DestroyEffectBJ( GetLastCreatedEffectBJ() )

//    endif

endfunction






function HeroSelection takes nothing returns nothing

    local integer id = 0
    local player pl
    local force fp
    local real time = 15.00

    local string name = ""
    local string desc = ""
    local string know = ""
    local string lern = ""
    local string utyp = ""
    local string atyp = ""
    local string wtyp = ""

    set id = GetConvertedPlayerId(GetTriggerPlayer())
    set pl = ConvertedPlayer(id)
    set fp = bj_FORCE_PLAYER[id-1]

    if GetBooleanAnd(GetPlayerHero(id) == null, GetBooleanAnd(GetOwningPlayer(GetTriggerUnit()) == Player(PLAYER_NEUTRAL_PASSIVE), RectContainsUnit(gg_rct_HeroSelector, GetTriggerUnit()))) then

    if (udg_HERO_LastSel[id] == GetTriggerUnit()) then
        call HeroSpawn()
    else
        set udg_HERO_LastSel[id] = GetTriggerUnit()


  //Human
            if (GetHeroProperName(GetTriggerUnit()) == "Angel") then
            set name = "Angel"
            set desc = "Master of healing and the art of combat!!."
            set know = "Consume Life"
            set lern = "Healvenly Light, God's Blessing, Sword of Light, Gods Hammer, Rebirth"
            set utyp = "Healing Tank"
            set wtyp = "Axes, Swords, Mauls, Hammers"
            set atyp = "Plate, Leather"
        elseif (GetHeroProperName(GetTriggerUnit()) == "Blood Elf Paladin") then
            set name = "Blood Elf Paladin"
            set desc = "Warrior who has mastered the art of combat and light"
            set know = "None"
            set lern = "Transmune, Heavenly Light, Spirit Walk, Bash"
            set utyp = "Warrior"
            set wtyp = "Axes, Swords, Mauls, Hammers"
            set atyp = "Plate, Leather"
        elseif (GetHeroProperName(GetTriggerUnit()) == "Demon Killer") then
            set name = "Demon Killer"
            set desc = "Strong warrior adept at the quick demise of his enemies"
            set know = "None"
            set lern = "Mortal Blow, Bash, Immolation, Metamorhpisis"
            set utyp = "Warrior"
            set wtyp = "Axes, Swords, Mauls, Hammers"
            set atyp = "Plate, Leather"
        elseif (GetHeroProperName(GetTriggerUnit()) == "Human Swordsman") then
            set name = "Human Swordsman"
            set desc = "Master of the sword and close combat skills."
            set know = "Defend"
            set lern = "Inner Fire, Evasion, Critical Strike, Avatar"
            set utyp = "Warrior"
            set wtyp = "Axes, Swords, Mauls, Hammers"
            set atyp = "Plate, Leather"
        elseif (GetHeroProperName(GetTriggerUnit()) == "Dwarven Warrior") then
            set name = "Dwarven Warrior"
            set desc = "Brave and charismatic, especially when drinking."
            set know = "Ensnare"
            set lern = "Thunder Clap, Bash, Drunken Brawler, Avatar"
            set utyp = "Warrior"
            set wtyp = "Axes, Swords, Mauls, Hammers"
            set atyp = "Plate, Leather"
        elseif (GetHeroProperName(GetTriggerUnit()) == "Elven Archer") then
            set name = "Elven Archer"
            set desc = "Skilled in the art of the bow and arrow."
            set know = "Multi Shot"
            set lern = "Blink, Sleepy Arrow, Bash, Summon Hippogryph"
            set utyp = "Ranger"
            set wtyp = "Bolts, Arrowheads"
            set atyp = "Any"
        elseif (GetHeroProperName(GetTriggerUnit()) == "Gryphon Rider") then
            set name = "Gryphon Rider"
            set desc = "Skilled in the art of the gryphon."
            set know = "None"
            set lern = "Bash, Rebirth, Transmune, Avatar"
            set utyp = "Warrior"
            set wtyp = "Mauls"
            set atyp = "Any"
        elseif (GetHeroProperName(GetTriggerUnit()) == "Night Elf Archer") then
            set name = "Night Elf Archer"
            set desc = "Skilled in the art of the bow and arrow."
            set know = "Shadow Meld"
            set lern = "Spirit Walk, Transmune, Burrowing Arrows, Summon Hippogryph"
            set utyp = "Ranger"
            set wtyp = "Bolts, Arrowheads"
            set atyp = "Any"
        elseif (GetHeroProperName(GetTriggerUnit()) == "Dwarven Rifleman") then
            set name = "Dwarven Rifleman"
            set desc = "A highly skilled, yet greedy sharpshooter."
            set know = "Pillage"
            set lern = "Cluster Rockets, Concentration, Critical Strike, Transmute"
            set utyp = "Ranger"
            set wtyp = "Bolts, Arrowheads"
            set atyp = "Any"
        elseif (GetHeroProperName(GetTriggerUnit()) == "Cleric") then
            set name = "Cleric"
            set desc = "Follower of the divine, a must for any party."
            set know = "Healing Ward"
            set lern = "Heal, Sleep, Auto-Blink, Tranquility"
            set utyp = "Spellcaster"
            set wtyp = "Staffs, Wands, Books"
            set atyp = "Robes, Leather"
        elseif (GetHeroProperName(GetTriggerUnit()) == "Human Mage") then
            set name = "Human Mage"
            set desc = "Casts elemental spells to devastate the enemy."
            set know = "Cyclone"
            set lern = "Chain Lightning, Fire Wall, Blizzard, Thunderstorm"
            set utyp = "Spellcaster"
            set wtyp = "Staffs, Wands, Books"
            set atyp = "Robes, Leather"


  //Undead
        elseif (GetHeroProperName(GetTriggerUnit()) == "Skeletal Summoner") then
            set name = "Skeletal Summoner"
            set desc = "Raises and empowers fallen warriors."
            set know = "Control Magic"
            set lern = "Raise Dead, Dark Ritual, Unholy Aura, Inferno"
            set utyp = "Spellcaster"
            set wtyp = "Staffs, Wands, Books"
            set atyp = "Robes, Leather"
        elseif (GetHeroProperName(GetTriggerUnit()) == "The Earth Warder") then
            set name = "The Earth Warder"
            set desc = "A wonderous being adept at controling nature."
            set know = "None"
            set lern = "Summon Spirit of Air, Entangeling Roots, Volcano, Summon Quillbeast"
            set utyp = "Warrior/Summoner"
            set wtyp = "Any"
            set atyp = "Any"
        elseif (GetHeroProperName(GetTriggerUnit()) == "Reaper of Souls") then
            set name = "Reaper of Souls"
            set desc = "Killing enemies while regenarating his hp is the way this reaper fights."
            set know = "None"
            set lern = "Raise Dead, Exume Soul, Death Coil, Scourge of the Reaper"
            set utyp = "Warrior"
            set wtyp = "Swords, Axes, Mauls"
            set atyp = "Plate. Leather"
        elseif (GetHeroProperName(GetTriggerUnit()) == "Hell Knight") then
            set name = "Hell Knight"
            set desc = "Amazing warrior adept at kicking enemys asses!."
            set know = "Inner Fury"
            set lern = "Satan's Pain, Rebirth, Spirit Walk, Bash"
            set utyp = "Warrior"
            set wtyp = "Swords, Axes, Mauls"
            set atyp = "Plate. Leather"
        elseif (GetHeroProperName(GetTriggerUnit()) == "Skeletal Archer") then
            set name = "Skeletal Archer"
            set desc = "A dexterious long-range attacker."
            set know = "Lightning Shield"
            set lern = "Frost Arrows, Trueshot Aura, Critical Strike, Starfall"
            set utyp = "Ranger"
            set wtyp = "Bolts, Arrowheads"
            set atyp = "Any"
        elseif (GetHeroProperName(GetTriggerUnit()) == "Undead Ranger") then
            set name = "Undead Ranger"
            set desc = "A cunning and manipulative hero."
            set know = "Unholy Frenzy"
            set lern = "Death Coil, Black Arrow, Silence, Animate Dead"
            set utyp = "Ranger"
            set wtyp = "Bolts, Arrowheads"
            set atyp = "Any"
        elseif (GetHeroProperName(GetTriggerUnit()) == "Undead Vampire") then
            set name = "Undead Vampire"
            set desc = "Suffers from an unquencheable thirst for blood."
            set know = "Cannibalize"
            set lern = "Bloodlust, Vampiric Aura, Carrion Swarm, Locust Swarm"
            set utyp = "Warrior"
            set wtyp = "Axes, Swords, Mauls, Hammers"
            set atyp = "Plate, Leather"
        elseif (GetHeroProperName(GetTriggerUnit()) == "Undead Banshee") then
            set name = "Undead Banshee"
            set desc = "Supporting spellcaster from the depths of hell."
            set know = "Curse"
            set lern = "Frost Nova, Howl of Terror, Auto-Blink, Apocalypse"
            set utyp = "Spellcaster"
            set wtyp = "Staffs, Wands, Books"
            set atyp = "Robes, Leather"
        elseif (GetHeroProperName(GetTriggerUnit()) == "Skeletal Baron") then
            set name = "Skeletal Baron"
            set desc = "Mindless, but sturdy brute warrior."
            set know = "Ensnare"
            set lern = "War Stomp, Cleaving Attack, Endurance Aura, Reincarnation"
            set utyp = "Warrior"
            set wtyp = "Axes, Swords, Mauls, Hammers"
            set atyp = "Plate, Leather"


  //Night Elf
        elseif (GetHeroProperName(GetTriggerUnit()) == "Elven Swordsmen") then
            set name = "Elven Swordsmen"
            set desc = "Cunning hero, adept at slaying foes."
            set know = "Dual Fighter"
            set lern = "Bash, Cleaving Attack, Crushing Blow, Mortal Blow"
            set utyp = "Passive Warrior"
            set wtyp = "Axes, Swords, Mauls, Hammers"
            set atyp = "Plate, Leather"
        elseif (GetHeroProperName(GetTriggerUnit()) == "Night Elf Slayer") then
            set name = "Night Elf Slayer"
            set desc = "Cunning hero, adept at maneuvering through battles."
            set know = "Ensnare"
            set lern = "Mana Burn, Immolation, Evasion, Metamorphosis"
            set utyp = "Warrior"
            set wtyp = "Axes, Swords, Mauls, Hammers"
            set atyp = "Plate, Leather"
        elseif (GetHeroProperName(GetTriggerUnit()) == "Ancient of Stone") then
            set name = "Ancient of Stone"
            set desc = "Protector of the Ancient forest."
            set know = "Rejuvenation"
            set lern = "Hurl Boulder, Bash, Entangling Roots, Earthquake"
            set utyp = "Warrior"
            set wtyp = "Axes, Swords, Mauls, Hammers"
            set atyp = "Plate, Leather"
        elseif (GetHeroProperName(GetTriggerUnit()) == "Ancient of Thunder") then
            set name = "Ancient of Thunder"
            set desc = "Elemental treant. caster of offensive magic."
            set know = "Lightning Shield"
            set lern = "Forked Lightning, Mana Shield, Brilliance Aura, Thunderstorm"
            set utyp = "Spellcaster"
            set wtyp = "Staffs, Wands, Books"
            set atyp = "Robes, Leather"
        elseif (GetHeroProperName(GetTriggerUnit()) == "Night Elf Druid") then
            set name = "Night Elf Druid"
            set desc = "Melee shapeshifter and supporting spellcaster."
            set know = "Faerie Fire"
            set lern = "Healing Wave, Force of Nature, Thorns Aura, Bear Form"
            set utyp = "Warrior"
            set wtyp = "Axes, Swords, Mauls, Hammers"
            set atyp = "Plate, Leather"
        elseif (GetHeroProperName(GetTriggerUnit()) == "Night Elf Giant") then
            set name = "Night Elf Giant"
            set desc = "Massive, but reclusive forest beast."
            set know = "War Club"
            set lern = "Shockwave, Bash, Endurance Aura, Avatar"
            set utyp = "Warrior"
            set wtyp = "Axes, Swords, Mauls, Hammers"
            set atyp = "Plate, Leather"


  //Orc
        elseif (GetHeroProperName(GetTriggerUnit()) == "Troll Rouge") then
            set name = "Troll Rouge"
            set desc = "Agile and versatile spear-thrower."
            set know = "Evasion"
            set lern = "Posin Ingection, Kidney Shot, Assassian's Reflex, Assassian's Strike, Stealth"
            set utyp = "Ranger"
            set wtyp = "Bolts, Arrowheads"
            set atyp = "Any"
        elseif (GetHeroProperName(GetTriggerUnit()) == "Orc Shaman") then
            set name = "Orc Shaman"
            set desc = "An excellent supporting spellcaster in battle."
            set know = "Healing Stream Totem"
            set lern = "Bloodlust, Earth Shock, Lightning Strike, Shield of Destruction, Wind Fury"
            set utyp = "Spellcaster"
            set wtyp = "Staffs, Wands, Books"
            set atyp = "Robes, Leather"
        elseif (GetHeroProperName(GetTriggerUnit()) == "Tauren Brute") then
            set name = "Tauren Brute"
            set desc = "A strong and sturdy defensive warrior."
            set know = "Pulverize"
            set lern = "War Stomp, Shockwave, Endurance Aura, Big Bad Voodoo"
            set utyp = "Warrior"
            set wtyp = "Axes, Swords, Mauls, Hammers"
            set atyp = "Plate, Leather"
        elseif (GetHeroProperName(GetTriggerUnit()) == "Orc Warlock") then
            set name = "Orc Warlock"
            set desc = "Fanatical sorceror, casting summons and arcane magic."
            set know = "Summon Sea Elemental"
            set lern = "Rain of Fire, Fire Wall, Summon Bear, Apocalypse"
            set utyp = "Spellcaster"
            set wtyp = "Staffs, Wands, Books"
            set atyp = "Robes, Leather"
        elseif (GetHeroProperName(GetTriggerUnit()) == "Troll Priest") then
            set name = "Troll Priest"
            set desc = "Praised and worshipped hero of the trolls."
            set know = "Cripple"
            set lern = "Heal, Auto-Blink, Brilliance Aura, Tranquility"
            set utyp = "Spellcaster"
            set wtyp = "Staffs, Wands, Books"
            set atyp = "Robes, Leather"
        elseif (GetHeroProperName(GetTriggerUnit()) == "Fearless Orc") then
            set name = "Fearless Orc"
            set desc = "Brave and strong warrior."
            set know = "Fearless Strength"
            set lern = "None"
            set utyp = "Master Tank"
            set wtyp = "Swords, Axes, Mauls"
            set atyp = "Plate, Leather"
 
     //Other
        elseif (GetHeroProperName(GetTriggerUnit()) == "") then
        elseif (GetHeroProperName(GetTriggerUnit()) == "") then
        endif


        call DisplayTimedTextToForce( fp, time, " ")
        call DisplayTimedTextToForce( fp, time, "|c0000FF00" + name + "|r (|c00ffff00" + utyp + "|r) - " + desc )
        call DisplayTimedTextToForce( fp, time, "|c007777FFKnows: |r" + know )
        call DisplayTimedTextToForce( fp, time, "|c007777FFLearns: |r" + lern )
        call DisplayTimedTextToForce( fp, time, "|c007777FFWeapons: |r" + wtyp + "   |c007777FFArmor: |r" + atyp )
    endif

    endif

endfunction




function InitPlayerHeroSelector takes nothing returns nothing

    local integer id = 0
    local player pl
    local force fp

    set id = GetConvertedPlayerId(GetEnumPlayer())
    set pl = ConvertedPlayer(id)
    set fp = bj_FORCE_PLAYER[id-1]

    //set udg_Status[id] = "none"
    //set udg_ChatString[id] = ""
    //set udg_HERO_Ref[id] = null

//    call ClearScreenForce(fp)
    call CreateFogModifierRectBJ( true, GetEnumPlayer(), FOG_OF_WAR_VISIBLE, gg_rct_HeroSelector )
    call CameraSetupApplyForPlayer( true, gg_cam_HeroSelector, GetEnumPlayer(), 0 )
    call TriggerRegisterPlayerSelectionEventBJ( udg_HERO_Selection, pl, true )

    if GetPlayerSlotState(ConvertedPlayer(id)) == PLAYER_SLOT_STATE_PLAYING then
        set udg_TEMP_Integer = udg_TEMP_Integer + 1
    endif

endfunction






function HeroSelectorInit takes nothing returns nothing
    local integer numplayers

    set udg_HERO_Selection = CreateTrigger(  )
    call DisableTrigger( udg_HERO_Selection )
    call TriggerAddAction( udg_HERO_Selection, function HeroSelection )

    set udg_TEMP_Integer = 0
    call ForForce( udg_Force[1], function InitPlayerHeroSelector )
    set numplayers = udg_TEMP_Integer

    set udg_TEMP_Integer = 0
    call ForGroupBJ( GetUnitsInRectAll(gg_rct_HeroSelector), function CountEnum )

    if numplayers > udg_TEMP_Integer then
        set udg_HERO_AllowDuplicates = true
    else
        set udg_HERO_AllowDuplicates = false
    endif

    call DisplayTextToForce( udg_Force[1], "Click a Hero to view its description." )
    call DisplayTextToForce( udg_Force[1], "Click it again to select it." )

    call PolledWait( 1 )
    call EnableTrigger( udg_HERO_Selection )
endfunction

function InitTrig_Hero_Selector takes nothing returns nothing
    set gg_trg_Hero_Selector = CreateTrigger(  )
    call TriggerAddAction( gg_trg_Hero_Selector, function HeroSelectorInit )
endfunction

 





function HeroRestrictorDoneEnum takes nothing returns nothing
    if GetUnitUserData(GetEnumUnit()) == 1 then
        call SetUnitVertexColorBJ( GetEnumUnit(), 100, 100, 100, 0 )
    else
        call RemoveUnit( GetEnumUnit() )
    endif
endfunction



function HeroAllowEnum takes nothing returns nothing
    call SetUnitUserData( GetEnumUnit(), 1 )
    call SetUnitVertexColorBJ( GetEnumUnit(), 0.00, 100, 0.00, 0 )
endfunction

function HeroRestrictEnum takes nothing returns nothing
    call SetUnitUserData( GetEnumUnit(), 0 )
    call SetUnitVertexColorBJ( GetEnumUnit(), 100, 0, 0.00, 0 )
endfunction

function DMRestrictHeroSelect takes nothing returns nothing

    local unit bHuman = gg_unit_n000_0283
    local unit bOrc = gg_unit_n000_0282
    local unit bUndead = gg_unit_n000_0285
    local unit bNightElf = gg_unit_n000_0284
    local unit bDone = gg_unit_n000_0286


    if RectContainsLoc(gg_rct_HeroSelector, GetUnitLoc(GetTriggerUnit())) then
        if GetTriggerUnit() == bDone then
            call DestroyTextTagBJ( udg_HERO_ButtonText[1] )
            call DestroyTextTagBJ( udg_HERO_ButtonText[2] )
            call DestroyTextTagBJ( udg_HERO_ButtonText[3] )
            call DestroyTextTagBJ( udg_HERO_ButtonText[4] )
            call DestroyTextTagBJ( udg_HERO_ButtonText[5] )

            call RemoveUnit(bHuman)
            call RemoveUnit(bOrc)
            call RemoveUnit(bUndead)
            call RemoveUnit(bNightElf)
            call RemoveUnit(bDone)

            call ForGroupBJ( GetUnitsInRectAll(gg_rct_HeroSelector), function HeroRestrictorDoneEnum )

            //call GUIApplyCamForDM(Player(8))
            //call CameraSetupApplyForPlayer( true, gg_cam_ZoomOutCam, Player(8), 0.0 )

            call DisableTrigger( GetTriggeringTrigger() )
            call DisableTrigger( gg_trg_Hero_Restrictor_Lock )

            call TriggerExecute( gg_trg_Hero_Selector )



        elseif GetTriggerUnit() == bHuman then
            if GetUnitUserData(GetTriggerUnit()) == 1 then
                call SetUnitUserData( GetTriggerUnit(), 0 )
                call ForGroupBJ( GetUnitsInRectAll(gg_rct_HeroSelectorHuman), function HeroRestrictEnum )
            else
                call SetUnitUserData( GetTriggerUnit(), 1 )
                call ForGroupBJ( GetUnitsInRectAll(gg_rct_HeroSelectorHuman), function HeroAllowEnum )
            endif

        elseif GetTriggerUnit() == bOrc then
            if GetUnitUserData(GetTriggerUnit()) == 1 then
                call SetUnitUserData( GetTriggerUnit(), 0 )
                call ForGroupBJ( GetUnitsInRectAll(gg_rct_HeroSelectorOrc), function HeroRestrictEnum )
            else
                call SetUnitUserData( GetTriggerUnit(), 1 )
                call ForGroupBJ( GetUnitsInRectAll(gg_rct_HeroSelectorOrc), function HeroAllowEnum )
            endif

        elseif GetTriggerUnit() == bUndead then
            if GetUnitUserData(GetTriggerUnit()) == 1 then
                call SetUnitUserData( GetTriggerUnit(), 0 )
                call ForGroupBJ( GetUnitsInRectAll(gg_rct_HeroSelectorUndead), function HeroRestrictEnum )
            else
                call SetUnitUserData( GetTriggerUnit(), 1 )
                call ForGroupBJ( GetUnitsInRectAll(gg_rct_HeroSelectorUndead), function HeroAllowEnum )
            endif

        elseif GetTriggerUnit() == bNightElf then
            if GetUnitUserData(GetTriggerUnit()) == 1 then
                call SetUnitUserData( GetTriggerUnit(), 0 )
                call ForGroupBJ( GetUnitsInRectAll(gg_rct_HeroSelectorNightElf), function HeroRestrictEnum )
            else
                call SetUnitUserData( GetTriggerUnit(), 1 )
                call ForGroupBJ( GetUnitsInRectAll(gg_rct_HeroSelectorNightElf), function HeroAllowEnum )
            endif



        else
            if GetUnitUserData(GetTriggerUnit()) == 1 then
                call SetUnitUserData( GetTriggerUnit(), 0 )
                call SetUnitVertexColorBJ( GetTriggerUnit(), 100, 0, 0.00, 0 )
            else
                call SetUnitUserData( GetTriggerUnit(), 1 )
                call SetUnitVertexColorBJ( GetTriggerUnit(), 0.00, 100, 0.00, 0 )
            endif




        endif

    endif







endfunction










function InitHeroRestrictorEnum takes nothing returns nothing
    call SetUnitOwner( GetEnumUnit(), Player(PLAYER_NEUTRAL_PASSIVE), false )
    call SetUnitUserData( GetEnumUnit(), 1 )

    if not ( GetUnitTypeId(GetEnumUnit()) == 'n000' ) then
         call SetUnitVertexColorBJ( GetEnumUnit(), 0.00, 100, 0.00, 0 )
    endif
endfunction

function InitHeroRestrictor takes nothing returns nothing

    local unit bHuman = gg_unit_n000_0283
    local unit bOrc = gg_unit_n000_0282
    local unit bUndead = gg_unit_n000_0285
    local unit bNightElf = gg_unit_n000_0284
    local unit bDone = gg_unit_n000_0286

    call ForGroupBJ( GetUnitsInRectAll(gg_rct_HeroSelector), function InitHeroRestrictorEnum )

    set udg_HERO_Restrictor = CreateTrigger( )
    call TriggerAddAction( udg_HERO_Restrictor, function DMRestrictHeroSelect )
    call TriggerRegisterPlayerSelectionEventBJ( udg_HERO_Restrictor, Player(8), true )
//    call TriggerRegisterPlayerSelectionEventBJ( udg_HERO_Restrictor, Player(1), true )

    call CreateTextTagLocBJ( "Human", GetUnitLoc(bHuman), 0, 20.00, 100, 100, 100, 0 )
    set udg_HERO_ButtonText[1] = GetLastCreatedTextTag()
    call CreateTextTagLocBJ( "Orc", GetUnitLoc(bOrc), 0, 20.00, 100, 100, 100, 0 )
    set udg_HERO_ButtonText[2] = GetLastCreatedTextTag()
    call CreateTextTagLocBJ( "Undead", GetUnitLoc(bUndead), 0, 20.00, 100, 100, 100, 0 )
    set udg_HERO_ButtonText[3] = GetLastCreatedTextTag()
    call CreateTextTagLocBJ( "Night Elf", GetUnitLoc(bNightElf), 0, 20.00, 100, 100, 100, 0 )
    set udg_HERO_ButtonText[4] = GetLastCreatedTextTag()
    call CreateTextTagLocBJ( "Done", GetUnitLoc(bDone), 0, 20.00, 100, 100, 100, 0 )
    set udg_HERO_ButtonText[5] = GetLastCreatedTextTag()

    call SetUnitScalePercent( bHuman, 50.00, 50.00, 50.00 )
    call SetUnitScalePercent( bOrc, 50.00, 50.00, 50.00 )
    call SetUnitScalePercent( bUndead, 50.00, 50.00, 50.00 )
    call SetUnitScalePercent( bNightElf, 50.00, 50.00, 50.00 )
    call SetUnitScalePercent( bDone, 50.00, 50.00, 50.00 )
    call SetUnitVertexColorBJ( bHuman, 100, 100, 100, 100 )
    call SetUnitVertexColorBJ( bOrc, 100, 100, 100, 100 )
    call SetUnitVertexColorBJ( bUndead, 100, 100, 100, 100 )
    call SetUnitVertexColorBJ( bNightElf, 100, 100, 100, 100 )
    call SetUnitVertexColorBJ( bDone, 100, 100, 100, 100 )

endfunction









function InitTrig_Hero_Restrictor takes nothing returns nothing
    set gg_trg_Hero_Restrictor = CreateTrigger(  )
    call TriggerAddAction( gg_trg_Hero_Restrictor, function InitHeroRestrictor )
endfunction

 
Hero Restrictor Lock
  Events
    Time - Every 0.10 seconds of game time
  Conditions
  Actions
    Camera - .Apply. gg_cam_HeroRestrictor for Player 9 (Gray) over 0 seconds
function Trig_Hero_Reviver_Actions takes nothing returns nothing
    local integer id = 0
    local player pl
    local force fp
    local unit un
    local integer exp = 0

    set id = GetConvertedPlayerId(GetTriggerPlayer())
    set pl = ConvertedPlayer(id)
    set fp = bj_FORCE_PLAYER[id-1]

    set un = GetPlayerHero(id)

    if GetBooleanAnd(not(un == null), udg_HERO_IsDead[id] or IsUnitDeadBJ(un)) then

        if udg_DebugBoardCreated then
           call MultiboardSetItemValueBJ( udg_DebugBoard, 4, id, ColorName("ESC (rev)",id) )
        endif

        if gg_unit_h006_0197 == null then
            call DisplayTextToForce( GetPlayersAll(), "ERROR: Hero Flag Null!!" )
        endif

        call ReviveHeroLoc( un, GetUnitLoc(gg_unit_h006_0197), true )
        call DisplayTextToForce( fp, "Your death has cost you 1/5th of your experience points." )
        call DisplayTextToForce( fp, "You have been revived." )
        call ResetToGameCameraForPlayer( pl, 0 )
        call PanCameraToTimedLocForPlayer( pl, GetUnitLoc(gg_unit_h006_0197), 0 )
        set exp = GetHeroXP(un)
        call SetHeroLevelBJ( un, 1, false )
        call SetHeroXP(un, R2I(I2R(exp) * 0.80), false )

//note: the reviver does not depend on this;
//this is a hack to try to stop the revive bug.
        set udg_HERO_IsDead[id] = false

        //call UnitRemoveItemFromSlotSwapped( 1, un )
        //call UnitAddItemByIdSwapped( 'tret', un )
        //call UnitUseItem( un, GetLastCreatedItem() )
        //call UnitAddItemSwapped( GetLastRemovedItem(), un )

        if GetPlayerState(GetTriggerPlayer(), PLAYER_STATE_RESOURCE_LUMBER) > 0 then
            call AddHeroXPSwapped( GetPlayerState(pl, PLAYER_STATE_RESOURCE_LUMBER), un, false )
            call SetPlayerStateBJ( pl, PLAYER_STATE_RESOURCE_LUMBER, 0 )
        endif

    else

        if udg_DebugBoardCreated then
            call MultiboardSetItemValueBJ( udg_DebugBoard, 4, id, ColorName("ESC (cam)",id) )
        endif

//change camera
        if udg_HERO_FloatCam[id] == false then
            set udg_HERO_FloatCam[id] = true
            call DisplayTextToForce( fp, "|c0000FF00Camera unlocked.|r")
//            call SetCameraTargetControllerNoZForPlayer( pl, null, 0, 0, false )
//            call SetCameraFieldForPlayer( pl, CAMERA_FIELD_ROTATION, CameraSetupGetFieldSwap(CAMERA_FIELD_ROTATION, gg_cam_PlayerCam), 1.00 )        else
        else
            set udg_HERO_FloatCam[id] = false
            call DisplayTextToForce( fp, "|c0000FF00Camera locked.|r")
//            call SetCameraTargetControllerNoZForPlayer( pl, un, 0, 0, false )
        endif

    endif




    if udg_DebugBoardCreated then
        call PolledWait( 4.00 )
        call MultiboardSetItemValueBJ( udg_DebugBoard, 4, id, "" )
    endif




endfunction

function InitTrig_Hero_Reviver takes nothing returns nothing
    set gg_trg_Hero_Reviver = CreateTrigger(  )
    call TriggerRegisterPlayerEventEndCinematic( gg_trg_Hero_Reviver, Player(1) )
    call TriggerRegisterPlayerEventEndCinematic( gg_trg_Hero_Reviver, Player(2) )
    call TriggerRegisterPlayerEventEndCinematic( gg_trg_Hero_Reviver, Player(3) )
    call TriggerRegisterPlayerEventEndCinematic( gg_trg_Hero_Reviver, Player(5) )
    call TriggerRegisterPlayerEventEndCinematic( gg_trg_Hero_Reviver, Player(6) )
    call TriggerRegisterPlayerEventEndCinematic( gg_trg_Hero_Reviver, Player(7) )
    call TriggerRegisterPlayerEventEndCinematic( gg_trg_Hero_Reviver, Player(11) )
    call TriggerAddAction( gg_trg_Hero_Reviver, function Trig_Hero_Reviver_Actions )
endfunction

 

function Trig_Hero_Dies_Conditions takes nothing returns boolean
    if ( not ( GetDyingUnit() == GetPlayerHero(GetConvertedPlayerId(GetOwningPlayer(GetDyingUnit()))) ) ) then
        return false
    endif
    return true
endfunction

function Trig_Hero_Dies_Actions takes nothing returns nothing
    local integer id = 0
    local player pl
    local force fp
    local unit un
    local integer exp = 0

    set id = GetConvertedPlayerId(GetTriggerPlayer())
    set pl = ConvertedPlayer(id)
    set fp = bj_FORCE_PLAYER[id-1]
    set un = GetPlayerHero(id)

//note: the reviver does not depend on this;
//this is a hack to try to stop the revive bug.
    set udg_HERO_IsDead[id] = true

    call RemoveKeepAliveUnit(GetDyingUnit())

    call DisplayTextToForce( fp, "You have died! Press |cFFFFFF00ESC|r to revive." )
endfunction

//===========================================================================
function InitTrig_Hero_Dies takes nothing returns nothing
    set gg_trg_Hero_Dies = CreateTrigger(  )
    call TriggerRegisterPlayerUnitEventSimple( gg_trg_Hero_Dies, Player(1), EVENT_PLAYER_UNIT_DEATH )
    call TriggerRegisterPlayerUnitEventSimple( gg_trg_Hero_Dies, Player(2), EVENT_PLAYER_UNIT_DEATH )
    call TriggerRegisterPlayerUnitEventSimple( gg_trg_Hero_Dies, Player(3), EVENT_PLAYER_UNIT_DEATH )
    call TriggerRegisterPlayerUnitEventSimple( gg_trg_Hero_Dies, Player(5), EVENT_PLAYER_UNIT_DEATH )
    call TriggerRegisterPlayerUnitEventSimple( gg_trg_Hero_Dies, Player(6), EVENT_PLAYER_UNIT_DEATH )
    call TriggerRegisterPlayerUnitEventSimple( gg_trg_Hero_Dies, Player(7), EVENT_PLAYER_UNIT_DEATH )
    call TriggerRegisterPlayerUnitEventSimple( gg_trg_Hero_Dies, Player(11), EVENT_PLAYER_UNIT_DEATH )
    call TriggerAddCondition( gg_trg_Hero_Dies, Condition( function Trig_Hero_Dies_Conditions ) )
    call TriggerAddAction( gg_trg_Hero_Dies, function Trig_Hero_Dies_Actions )
endfunction

 
disable this in release builds for safety
test
  Events
    Map initialization
  Conditions
    (Name of Player 2 (Blue)) Equal to WorldEdit
  Actions
    Custom script: call TriggerRegisterPlayerSelectionEventBJ( udg_HERO_Restrictor, Player(1), true )
    Player - Set Player 2 (Blue).Current gold to 200000
disable this in release builds for safety
test Copy
  Events
    Map initialization
  Conditions
    (Name of Player 2 (Blue)) Equal to Bringer_of_Pain
  Actions
    Custom script: call TriggerRegisterPlayerSelectionEventBJ( udg_HERO_Restrictor, Player(1), true )
    Player - Set Player 2 (Blue).Current gold to 200000
the getplayerhero finding seems like a big overhead for a periodic event, but the only units controlled by players are their heroes and summons and possibly units given by dms. we'll see it if lags or leaks.

update: it leaks A LOT. so changed to permanent ref. this should be the only place hero_ref2 is used, so it should not break. called ref2 to diff from old broken ref.
PlayerCam
  Events
    Time - Every 0.20 seconds of game time
  Conditions
  Actions
    Player Group - Pick every player in Force[1] and do (Actions)
      Loop - Actions
        If (All Conditions are True) then do (Then Actions) else do (Else Actions)
          If - Conditions
            HERO_FloatCam[(Player number of (Picked player))] Equal to True
          Then - Actions
          Else - Actions
            Custom script: set udg_TEMP_Unit = GetPlayerHero(GetConvertedPlayerId(GetEnumPlayer()))
            Custom script: set udg_TEMP_Unit = udg_HERO_Ref2[GetConvertedPlayerId(GetEnumPlayer())]
            If (All Conditions are True) then do (Then Actions) else do (Else Actions)
              If - Conditions
                TEMP_Unit Equal to No unit
              Then - Actions
              Else - Actions
                Camera - Lock camera target for (Picked player) to TEMP_Unit, offset by (0, 0) using Default rotation
                Camera - .Apply. gg_cam_PlayerCam for Player 1 (Red) over 2.00 seconds
                Set VariableSet TEMP_Location = (Position of TEMP_Unit)
                Camera - Set (Picked player)'s camera Rotation to (Facing of TEMP_Unit) over 0.50 seconds
                Camera - Pan camera for (Picked player) to TEMP_Location over 0.25 seconds
                Custom script: call RemoveLocation(udg_TEMP_Location)
Give to Neutral
  Events
    Time - Elapsed game time is 0.01 seconds
  Conditions
  Actions
    Game - Display to (All players) the text: Players the Fearless Orc has on abilities because he has much more health,armor,and damage then the others.
    Unit - Change ownership of Town Hall 0215 <gen> to Neutral Passive and Change color
    Unit - Change ownership of Tree of Life 0222 <gen> to Neutral Passive and Change color
    Unit - Change ownership of Scout Tower 0074 <gen> to Neutral Passive and Change color
    Unit - Change ownership of Arcane Sanctum 0216 <gen> to Neutral Passive and Change color



//*************************
//    checked for leaks
//*************************



function onGUIMiscClick takes nothing returns nothing

    local unit GUI_Misc = gg_unit_n000_0043
    local unit GUI_M_Portal = gg_unit_n000_0044
    local unit GUI_M_Cinematic = gg_unit_n000_0045
    local unit GUI_M_Boot = gg_unit_n000_0047

    local integer i = 0
    local integer i2 = 0

    local integer id = 0
    local player pl
    local force fp

    set id = GetConvertedPlayerId(GetTriggerPlayer())
    set pl = ConvertedPlayer(id)
    set fp = bj_FORCE_PLAYER[id-1]


    if (GetTriggerUnit() == GUI_M_Portal) then

        set udg_Status[id] = "misc_portal_source"
        set udg_DM_Unit[id] = null
        call GUIApplyCamForDM(pl)

        call LeaderboardSetPlayerItemLabelBJ( ConvertedPlayer(4), udg_Board[id], "|cFFFFFFFFWay Gate...|r" )
        call SelectUnitForPlayerSingle( udg_GUI_Pointer[id], pl )
        call DisplayTextToForce( fp, " " )
        call DisplayTextToForce( fp, "Left click a Way Gate to deactivate it or to set its destination." )
        call DisplayTextToForce( fp, "Right click the ground to create a new Way Gate." )




    elseif (GetTriggerUnit() == GUI_M_Boot) then
        if id == 9 then
            call CameraSetupApplyForPlayer( true, gg_cam_GUI, pl, 0 )
            call DisplayTextToForce( fp, "Click the colored tile in the Toolbox of the player you'd like to boot." )
            set udg_Status[id] = "misc_boot"
            call LeaderboardSetPlayerItemLabelBJ( ConvertedPlayer(4), udg_Board[id], "|cFFFFFFFFBooting...|r" )
            set udg_DM_UnitType[id] = 0
            set udg_DM_Player[id] = ConvertedPlayer(5)
        else
            call DisplayTextToForce( fp, "Only the head DM may boot players." )
        endif














    //toolbox tile clicked

    elseif IsUnitInGroup(GetTriggerUnit(), udg_GUI_Tile_Group) then

        set i = 1
        loop
            exitwhen i > 12

            if udg_GUI_Tile[i] == GetTriggerUnit() then
                set i2 = i
            endif

            set i = i + 1
        endloop


        if GetBooleanAnd(udg_Status[id] == "unit_create", not(IsPlayerInForce(ConvertedPlayer(i2), udg_Force[2]))) then
            set udg_DM_Player[id] = ConvertedPlayer(i2)

            if udg_DM_UnitType[id] == 0 then
                call CameraSetupApplyForPlayer( true, gg_cam_Palette, pl, 0 )
//                call DisplayTextToForce( fp, " " )
//                call DisplayTextToForce( fp, "|cFF00FF00You have selected '|r|cFFFF0000" + ColorNamePl(ConvertedPlayer(i2)) + "|r|cFF00FF00'.|r" )
                call DisplayTextToForce( fp, "    Left click the type of unit you would like to create." )
//                call DisplayTextToForce( fp, "    Click a coloured tile in the Toolbox to select the owner of the new unit.")
//                call DisplayTextToForce( fp, "    Press |c00FFFF00ESC|r to exit." )

            else
                call GUIApplyCamForDM(pl)
                call LeaderboardSetPlayerItemLabelBJ( ConvertedPlayer(4), udg_Board[id], "|cFFFFFFFF-> '|r" + ColorName(UnitId2StringBJ(udg_DM_UnitType[id]), GetConvertedPlayerId(udg_DM_Player[id])) + "|c00FFFFFF'|r" )
                call SelectUnitForPlayerSingle( udg_GUI_Pointer[id], pl )
//                call DisplayTextToForce( fp, " " )
//                call DisplayTextToForce( fp, "|cFF00FF00You have selected '|r|c00FF0000" + ColorNamePl(ConvertedPlayer(i2)) + "|r|cFF00FF00'.|r" )
//                call DisplayTextToForce( fp, "    Select your Pointer (|cFFFFFF00F1|r), then right click to create a '|cFFFF0000" + UnitId2StringBJ(udg_DM_UnitType[id]) + "|r' for " + ColorNamePl(udg_DM_Player[id]) + "." )
                call DisplayTextToForce( fp, "    Right click to create a '|cFFFF0000" + TranslateTo(UnitId2StringBJ(udg_DM_UnitType[id])) + "|r' for " + ColorNamePl(udg_DM_Player[id]) + "." )
//                call DisplayTextToForce( fp, "    Left click a unit in the Palette to select a different unit type." )
//                call DisplayTextToForce( fp, "    Click a coloured tile in the Toolbox to select the owner of the new unit.")
//                call DisplayTextToForce( fp, "    Press |cFFFFFF00ESC|r to exit." )
            endif


        elseif udg_Status[id] == "unit_revive" then
            if IsPlayerInForce(ConvertedPlayer(i2), udg_Force[1]) then
                if not(GetPlayerSlotState(ConvertedPlayer(i2)) == PLAYER_SLOT_STATE_PLAYING) then
                    call DisplayTextToForce( fp, ColorNamePl(ConvertedPlayer(i2)) + " is not playing.")
                elseif IsUnitDeadBJ(GetPlayerHero(i2)) then
                    call ReviveHeroLoc( GetPlayerHero(i2), GetUnitLoc(GetPlayerHero(i2)), true )
                    call DisplayTextToForce( udg_Force[2], ColorNamePl(ConvertedPlayer(i2)) + " has been revived.")
                    call DisplayTextToForce( bj_FORCE_PLAYER[i2-1], "You have been revived.")
                else
                    call DisplayTextToForce( fp, ColorNamePl(ConvertedPlayer(i2)) + " is not dead!")
                endif
            else
                call DisplayTextToForce( fp, "|c00FF0000Revival of NPC heros is not yet functional.|r")
            endif



        elseif udg_Status[id] == "misc_boot" then
           
            if IsPlayerInForce(ConvertedPlayer(i2), udg_Force[3]) then
                call DisplayTextToForce( fp, "You cannot boot the NPCs.")
            elseif i2 == 9 then
                call DisplayTextToForce( fp, "You cannot boot yourself.")
            elseif not(GetPlayerSlotState(ConvertedPlayer(i2)) == PLAYER_SLOT_STATE_PLAYING) then
                call DisplayTextToForce( fp, ColorNamePl(ConvertedPlayer(i2)) + " is not playing.")
            else
                set udg_Status[id] = "none"
                call LeaderboardSetPlayerItemLabelBJ( ConvertedPlayer(4), udg_Board[id], "|c00FFFFFFNo Active Mode|r" )
                set udg_DM_Player[id] = ConvertedPlayer(i2)
                call DialogSetMessageBJ( udg_BOOT_Dialog, "Boot " + ColorNamePl(ConvertedPlayer(i2)) + "?" )
                call DialogDisplayBJ( true, udg_BOOT_Dialog, pl )
            endif


        endif














    endif

endfunction























function DMPressedEscape takes nothing returns nothing

    local integer id = 0
    local player pl
    local force fp

    set id = GetConvertedPlayerId(GetTriggerPlayer())
    set pl = ConvertedPlayer(id)
    set fp = bj_FORCE_PLAYER[id-1]



    if udg_Status[id] == "none" then

        call CameraSetupApplyForPlayer( true, gg_cam_GUI, pl, 0 )
        call DisplayTextToForce( fp, " " )
        call DisplayTextToForce( fp, "Welcome to the onscreen GUI." )
        call DisplayTextToForce( fp, "Click a menu item to activate it." )
        //call DisplayTextToForce( fp, "    Items in |c00777777grey|r are not yet available." )
        //call DisplayTextToForce( fp, "    Look for them in a future release." )

    else

        set udg_Status[id] = "none"
        call DisplayTextToForce( fp, " " )
        call DisplayTextToForce( fp, "|c0000FF00You have no current active mode.|r" )
        call LeaderboardSetPlayerItemLabelBJ( ConvertedPlayer(4), udg_Board[id], "|c00FFFFFFNo Active Mode|r" )

    endif





    if udg_DebugBoardCreated then
        call MultiboardSetItemValueBJ( udg_DebugBoard, 4, id, ColorName("ESC",id) )
        call PolledWait( 4.00 )
        call MultiboardSetItemValueBJ( udg_DebugBoard, 4, id, "" )
    endif



endfunction





function DMMiscSelect takes nothing returns nothing

    local unit GUI_Misc = gg_unit_n000_0043
    local unit GUI_M_Portal = gg_unit_n000_0044
    local unit GUI_M_Cinematic = gg_unit_n000_0045
    local unit GUI_M_Effect = gg_unit_n000_0047
    local unit GUI_M_Revive = gg_unit_n000_0047

    local integer id = 0
    local player pl
    local force fp
    local unit un
    local player pu
    local location loc

    set id = GetConvertedPlayerId(GetTriggerPlayer())
    set pl = ConvertedPlayer(id)
    set fp = bj_FORCE_PLAYER[id-1]
    set un = GetTriggerUnit()
    set pu = GetOwningPlayer(un)




    //call DisplayTextToForce( GetPlayersAll(), "jiggy" )


    if GetBooleanAnd(udg_Status[id] == "unit_kill", GetBooleanOr(IsPlayerInForce(pu, udg_Force[1]), IsPlayerInForce(pu, udg_Force[3]))) then
        call RemoveKeepAliveUnit(un)
        call KillUnit( un )
        call SelectUnitForPlayerSingle( udg_GUI_Pointer[id], pl )
    elseif GetBooleanAnd(udg_Status[id] == "unit_remove", IsPlayerInForce(pu, udg_Force[3])) then
        set loc = GetUnitLoc(un)
        call AddSpecialEffectLocBJ( loc, "Abilities\\Spells\\Human\\MassTeleport\\MassTeleportTarget.mdl" )
        call DestroyEffectBJ( GetLastCreatedEffectBJ() )
        call RemoveLocation(loc)
        if GetUnitTypeId(GetEnumUnit()) == 'h00B' then
            call ClearTrainingRoomMonsters(un)
        endif
        call RemoveKeepAliveUnit(un)
        call RemoveUnit( un )
    elseif GetBooleanAnd(udg_Status[id] == "unit_side", IsPlayerInForce(pu, udg_Force[3])) then
        if GetOwningPlayer( un ) == ConvertedPlayer(1) then
            call SetUnitOwner( un, ConvertedPlayer(5), true )
        else
            call SetUnitOwner( un, ConvertedPlayer(1), true )
        endif
    elseif udg_Status[id] == "unit_move" then
        //if is hero spawner
        if (un == gg_unit_h006_0197) then
            call SetUnitPositionLoc( un, udg_DM_Destination[id] )

        elseif GetBooleanOr(IsPlayerInForce(pu, udg_Force[1]), IsPlayerInForce(pu, udg_Force[3])) then
            set loc = GetUnitLoc(un)
            call AddSpecialEffectLocBJ( loc, "Abilities\\Spells\\Human\\MassTeleport\\MassTeleportTarget.mdl" )
            call DestroyEffectBJ( GetLastCreatedEffectBJ() )
            call RemoveLocation(loc)

            call SetUnitPositionLoc( un, udg_DM_Destination[id] )
            call RemoveGuardPosition( un )
            if not(IsUnitType(GetLastCreatedUnit(), UNIT_TYPE_STRUCTURE)) then
                call SetUnitAnimation( un, "birth" )
            endif
            call PauseUnitBJ( false, un )

            set loc = GetUnitLoc(un)
            call AddSpecialEffectLocBJ( loc, "Abilities\\Spells\\Human\\MassTeleport\\MassTeleportTarget.mdl" )
            call DestroyEffectBJ( GetLastCreatedEffectBJ() )
            call RemoveLocation(loc)
        endif








    elseif udg_Status[id] == "misc_portal_source" then
        if GetUnitTypeId(un) == 'nwgt' then
            //we have a source

            set udg_Status[id] = "misc_portal_dest"
            set udg_DM_Unit[id] = un
            call GUIApplyCamForDM(pl)
            call WaygateActivateBJ( false, un )

            call LeaderboardSetPlayerItemLabelBJ( ConvertedPlayer(4), udg_Board[id], "|cFFFFFFFFWay Gate Link...|r" )
            call SelectUnitForPlayerSingle( udg_GUI_Pointer[id], pl )
            call DisplayTextToForce( fp, " " )
            call DisplayTextToForce( fp, "Left click a Way Gate to link it to this one." )
            call DisplayTextToForce( fp, "Right click the ground to create a linking Way Gate." )
        endif


    elseif udg_Status[id] == "misc_portal_dest" then
        if GetBooleanAnd(GetUnitTypeId(un) == 'nwgt', not(un == udg_DM_Unit[id])) then
            //we have a destination

            call WaygateSetDestinationLocBJ( un, GetUnitLoc(udg_DM_Unit[id]) )
            call WaygateSetDestinationLocBJ( udg_DM_Unit[id], GetUnitLoc(un) )
            call WaygateActivateBJ( true, un )
            call WaygateActivateBJ( true, udg_DM_Unit[id] )



            set udg_Status[id] = "none"
            set udg_DM_Unit[id] = null
            call DisplayTextToForce( fp, " " )
            call DisplayTextToForce( fp, "The two Way Gates are now linked." )
            call LeaderboardSetPlayerItemLabelBJ( ConvertedPlayer(4), udg_Board[id], "|c00FFFFFFNo Active Mode|r" )
        endif





    endif

endfunction


function GUIMiscInit takes nothing returns nothing
    call DialogClearBJ( udg_BOOT_Dialog )
    call DialogAddButtonBJ( udg_BOOT_Dialog, "Yes" )
    set udg_BOOT_DialogYes = GetLastCreatedButtonBJ()
    call DialogAddButtonBJ( udg_BOOT_Dialog, "No" )
    set udg_BOOT_DialogNo = GetLastCreatedButtonBJ()
endfunction


function InitTrig_Misc takes nothing returns nothing

    set udg_GUI_Misc_Escape = CreateTrigger(  )
    call TriggerRegisterPlayerEventEndCinematic( udg_GUI_Misc_Escape, ConvertedPlayer(9) )
    call TriggerRegisterPlayerEventEndCinematic( udg_GUI_Misc_Escape, ConvertedPlayer(10) )
    call TriggerRegisterPlayerEventEndCinematic( udg_GUI_Misc_Escape, ConvertedPlayer(11) )
    call TriggerAddAction( udg_GUI_Misc_Escape, function DMPressedEscape )

    set udg_GUI_Misc_Select = CreateTrigger(  )
    call TriggerRegisterPlayerSelectionEventBJ( udg_GUI_Misc_Select, ConvertedPlayer(9), true )
    call TriggerRegisterPlayerSelectionEventBJ( udg_GUI_Misc_Select, ConvertedPlayer(10), true )
    call TriggerRegisterPlayerSelectionEventBJ( udg_GUI_Misc_Select, ConvertedPlayer(11), true )
    call TriggerAddAction( udg_GUI_Misc_Select, function DMMiscSelect )
    call TriggerAddAction( udg_GUI_Misc_Select, function onGUIMiscClick )

    set gg_trg_Misc = CreateTrigger(  )
    call TriggerAddAction( gg_trg_Misc, function GUIMiscInit )

endfunction




function InitGUIDM takes nothing returns nothing

    local integer id = 0

    set id = GetConvertedPlayerId(GetEnumPlayer())

    call CreateLeaderboardBJ( bj_FORCE_PLAYER[id-1], "Current Status" )
    set udg_Board[id] = GetLastCreatedLeaderboard()

    call LeaderboardSetStyleBJ( udg_Board[id], true, true, false, false )
//call LeaderboardAddItemBJ( ConvertedPlayer(1), udg_Board[id], "|c0000FF00(Echo) BLABLABLA|r", 0 )
//call LeaderboardAddItemBJ( ConvertedPlayer(2), udg_Board[id], "|c000000FFPortal:          OFF|r", 0 )
//call LeaderboardAddItemBJ( ConvertedPlayer(3), udg_Board[id], "|c00FFFF00(Cinematic) BLABLABLA|r", 0 )
    call LeaderboardAddItemBJ( ConvertedPlayer(4), udg_Board[id], "|c00FFFFFFNo Active Mode|r", 0 )
    call LeaderboardDisplayBJ( true, udg_Board[id] )

    set udg_Status[id] = "none"
    //set udg_ChatString[id] = ""
    set udg_DM_Player[id] = ConvertedPlayer(5)

    call CreateFogModifierRectBJ( true, GetEnumPlayer(), FOG_OF_WAR_VISIBLE, GetEntireMapRect() )

    call GUIApplyCamForDM(GetEnumPlayer())


endfunction











function DoGUIAnims takes nothing returns nothing

    local integer i

    local string GUI_Tag_Tile = "Spell Lumber Second"


//Units
    local unit GUI_Units = gg_unit_n000_0001
    local unit GUI_U_Create = gg_unit_n000_0002
    local unit GUI_U_Kill = gg_unit_n000_0003
    local unit GUI_U_Remove = gg_unit_n000_0004
    local unit GUI_U_Side = gg_unit_n000_0005
    local unit GUI_U_Move = gg_unit_n000_0006
    local unit GUI_U_Give = gg_unit_n000_0007
    local unit GUI_U_Size = gg_unit_n000_0009
    local unit GUI_U_Revive = gg_unit_n000_0010
    local unit GUI_U_Tint = gg_unit_n000_0011
        local unit GUI_U_Tint_Invis = gg_unit_n000_0016
        local unit GUI_U_Tint_White = gg_unit_n000_0017
        local unit GUI_U_Tint_Yellow = gg_unit_n000_0018
        local unit GUI_U_Tint_Green = gg_unit_n000_0021
        local unit GUI_U_Tint_Red = gg_unit_n000_0020
        local unit GUI_U_Tint_Blue = gg_unit_n000_0019
    local unit GUI_U_Invincible = gg_unit_n000_0012


//Items
    local unit GUI_Items = gg_unit_n000_0033
    local unit GUI_I_Create = gg_unit_n000_0034
    local unit GUI_I_Remove = gg_unit_n000_0035
    local unit GUI_I_Move = gg_unit_n000_0036
    local unit GUI_I_P_GoldPile = gg_unit_n000_0132
    local unit GUI_I_P_GoldCoin = gg_unit_n000_0133
    local unit GUI_I_P_PileOfRiches = gg_unit_n000_0079


//Doodads
    local unit GUI_Doodads = gg_unit_n000_0037
    local unit GUI_D_Create = gg_unit_n000_0038
    local unit GUI_D_Remove = gg_unit_n000_0039
    local unit GUI_D_Kill = gg_unit_n000_0040
    local unit GUI_D_Revive = gg_unit_n000_0041
    local unit GUI_D_Toggle = gg_unit_n000_0042

    local unit GUI_D_P_Grove = gg_unit_n000_0123
    local unit GUI_D_P_Tree = gg_unit_n000_0124
    local unit GUI_D_P_Blight = gg_unit_n000_0125
    local unit GUI_D_P_Dispel = gg_unit_n000_0131
    local unit GUI_D_P_WoodenBridge = gg_unit_n008_0127
    local unit GUI_D_P_StoneBridge = gg_unit_n009_0128
    local unit GUI_D_P_Gate = gg_unit_n00G_0136
    local unit GUI_D_P_ElvenGate = gg_unit_n00H_0137
    local unit GUI_D_P_DemonicGate = gg_unit_n00F_0138
    local unit GUI_D_P_Line1 = gg_unit_n00P_0183
    local unit GUI_D_P_Line2 = gg_unit_n00P_0182

 
//Misc
    local unit GUI_Misc = gg_unit_n000_0043
    local unit GUI_M_Portal = gg_unit_n000_0044
    local unit GUI_M_Cinematic = gg_unit_n000_0045
    local unit GUI_M_Boot = gg_unit_n000_0047


//Toolbox
    local unit GUI_Toolbox = gg_unit_n000_0048
    local unit GUI_T_Tile_Blue = gg_unit_n000_0049
    local unit GUI_T_Tile_Teal = gg_unit_n000_0050
    local unit GUI_T_Tile_Purple = gg_unit_n000_0051
    local unit GUI_T_Tile_Orange = gg_unit_n000_0052
    local unit GUI_T_Tile_Green = gg_unit_n000_0053
    local unit GUI_T_Tile_Pink = gg_unit_n000_0054
    local unit GUI_T_Tile_Brown = gg_unit_n000_0055

    local unit GUI_T_Tile_Enemy = gg_unit_n000_0056
    local unit GUI_T_Tile_Ally = gg_unit_n000_0057

    local unit GUI_T_Tile_Gray = gg_unit_n000_0104
    local unit GUI_T_Tile_Cyan = gg_unit_n000_0179
    local unit GUI_T_Tile_DarkGreen = gg_unit_n000_0207











//Units
    call CreateTextTagLocBJ( "Units", GetUnitLoc(GUI_Units), 0, 17.00, 100, 100, 100, 0 )
    call SetUnitVertexColorBJ( GUI_Units, 100, 100, 100, 100.00 )

    call CreateTextTagLocBJ( "Create   (uc)", GetUnitLoc(GUI_U_Create), 0, 15.00, 100, 100, 100, 0 )
    call SetUnitVertexColorBJ( GUI_U_Create, 100, 100, 100, 100.00 )

    call CreateTextTagLocBJ( "Kill   (uk/uks)", GetUnitLoc(GUI_U_Kill), 0, 15.00, 100, 100, 100, 0 )
    call SetUnitVertexColorBJ( GUI_U_Kill, 100, 100, 100, 100.00 )

    call CreateTextTagLocBJ( "Remove   (ur/urs)", GetUnitLoc(GUI_U_Remove), 0, 15.00, 100, 100, 100, 0 )
    call SetUnitVertexColorBJ( GUI_U_Remove, 100, 100, 100, 100.00 )

    call CreateTextTagLocBJ( "Side   (us/uss)", GetUnitLoc(GUI_U_Side), 0, 15.00, 100, 100, 100, 0 )
    call SetUnitVertexColorBJ( GUI_U_Side, 100, 100, 100, 100.00 )

    call CreateTextTagLocBJ( "Move   (um)", GetUnitLoc(GUI_U_Move), 0, 15.00, 100, 100, 100, 0 )
    call SetUnitVertexColorBJ( GUI_U_Move, 100, 100, 100, 100.00 )

//    call CreateTextTagLocBJ( "Give", GetUnitLoc(GUI_U_Give), 0, 15.00, 100, 100, 100, 0 )
    call SetUnitVertexColorBJ( GUI_U_Give, 100, 100, 100, 100.00 )

//    call CreateTextTagLocBJ( "Size", GetUnitLoc(GUI_U_Size), 0, 15.00, 30, 30, 30, 0 )
    call SetUnitVertexColorBJ( GUI_U_Size, 100, 100, 100, 100.00 )

//    call CreateTextTagLocBJ( "Revive", GetUnitLoc(GUI_U_Revive), 0, 15.00, 30, 30, 30, 0 )
    call SetUnitVertexColorBJ( GUI_U_Revive, 100, 100, 100, 100.00 )

//    call CreateTextTagLocBJ( "Tint", GetUnitLoc(GUI_U_Tint), 0, 15.00, 30, 30, 30, 0 )
    call SetUnitVertexColorBJ( GUI_U_Tint, 100, 100, 100, 100.00 )

//    call CreateTextTagLocBJ( "Invulnerable", GetUnitLoc(GUI_U_Invincible), 0, 15.00, 30, 30, 30, 0 )
    call SetUnitVertexColorBJ( GUI_U_Invincible, 100, 100, 100, 100.00 )


        call SetUnitAnimation(GUI_U_Tint_Invis, GUI_Tag_Tile)
        call SetUnitAnimation(GUI_U_Tint_White, GUI_Tag_Tile)
        call SetUnitAnimation(GUI_U_Tint_Yellow, GUI_Tag_Tile)
        call SetUnitAnimation(GUI_U_Tint_Green, GUI_Tag_Tile)
        call SetUnitAnimation(GUI_U_Tint_Red, GUI_Tag_Tile)
        call SetUnitAnimation(GUI_U_Tint_Blue, GUI_Tag_Tile)
        call SetUnitVertexColorBJ( GUI_U_Tint_Invis, 100,100,100,70 )
        call SetUnitVertexColorBJ( GUI_U_Tint_Yellow, 100,100,0,0 )
        call SetUnitVertexColorBJ( GUI_U_Tint_Green, 0,100,0,0 )
        call SetUnitVertexColorBJ( GUI_U_Tint_Red, 100,0,0,0 )
        call SetUnitVertexColorBJ( GUI_U_Tint_Blue, 0,0,100,0 )
        call SetUnitScalePercent( GUI_U_Tint_Invis, 50.00, 50.00, 50.00 )
        call SetUnitScalePercent( GUI_U_Tint_White, 50.00, 50.00, 50.00 )
        call SetUnitScalePercent( GUI_U_Tint_Yellow, 50.00, 50.00, 50.00 )
        call SetUnitScalePercent( GUI_U_Tint_Green, 50.00, 50.00, 50.00 )
        call SetUnitScalePercent( GUI_U_Tint_Red, 50.00, 50.00, 50.00 )
        call SetUnitScalePercent( GUI_U_Tint_Blue, 50.00, 50.00, 50.00 )
        call SetUnitVertexColorBJ( GUI_U_Tint_Invis, 30,30,30,0 )
        call SetUnitVertexColorBJ( GUI_U_Tint_White, 30,30,30,0 )
        call SetUnitVertexColorBJ( GUI_U_Tint_Yellow, 30,30,30,0 )
        call SetUnitVertexColorBJ( GUI_U_Tint_Green, 30,30,30,0 )
        call SetUnitVertexColorBJ( GUI_U_Tint_Red, 30,30,30,0 )
        call SetUnitVertexColorBJ( GUI_U_Tint_Blue, 30,30,30,0 )
        call RemoveUnit(GUI_U_Tint_Invis)
        call RemoveUnit(GUI_U_Tint_White)
        call RemoveUnit(GUI_U_Tint_Yellow)
        call RemoveUnit(GUI_U_Tint_Green)
        call RemoveUnit(GUI_U_Tint_Red)
        call RemoveUnit(GUI_U_Tint_Blue)






//Items
//    call SetUnitAnimation(GUI_Items, GUI_Tag_Items)
//        call SetUnitScalePercent( GUI_Items, 120,120,120 )
//        call SetUnitVertexColorBJ( GUI_Items, 50,50,100,0 )
//    //    call SetUnitVertexColorBJ( GUI_Items, 30,30,30,0 )
//    call SetUnitAnimation(GUI_I_Create, GUI_Tag_Create)
//    //    call SetUnitVertexColorBJ( GUI_I_Create, 30,30,30,0 )
//    call SetUnitAnimation(GUI_I_Remove, GUI_Tag_Remove)
//    //    call SetUnitVertexColorBJ( GUI_I_Remove, 30,30,30,0 )
//    call SetUnitAnimation(GUI_I_Move, GUI_Tag_Move)
//    //    call SetUnitVertexColorBJ( GUI_I_Move, 30,30,30,0 )



    call CreateTextTagLocBJ( "Items", GetUnitLoc(GUI_Items), 0, 17.00, 100, 100, 100, 0 )
    call SetUnitVertexColorBJ( GUI_Items, 100, 100, 100, 100.00 )

    call CreateTextTagLocBJ( "Create   (ic)", GetUnitLoc(GUI_I_Create), 0, 15.00, 100, 100, 100, 0 )
    call SetUnitVertexColorBJ( GUI_I_Create, 100, 100, 100, 100.00 )

    call CreateTextTagLocBJ( "Remove   (ir)", GetUnitLoc(GUI_I_Remove), 0, 15.00, 100, 100, 100, 0 )
    call SetUnitVertexColorBJ( GUI_I_Remove, 100, 100, 100, 100.00 )

//    call CreateTextTagLocBJ( "Move", GetUnitLoc(GUI_I_Move), 0, 15.00, 30, 30, 30, 0 )
    call SetUnitVertexColorBJ( GUI_I_Move, 100, 100, 100, 100.00 )

        call SetUnitAnimation( GUI_I_P_GoldPile, GUI_Tag_Tile)
        call SetUnitAnimation( GUI_I_P_GoldCoin, GUI_Tag_Tile)
        call SetUnitAnimation( GUI_I_P_PileOfRiches, GUI_Tag_Tile)
        call SetUnitVertexColorBJ( GUI_I_P_GoldPile, 100,100,100,100 )
        call SetUnitVertexColorBJ( GUI_I_P_GoldCoin, 100,100,100,100 )
        call SetUnitVertexColorBJ( GUI_I_P_PileOfRiches, 100,100,100,100 )
        call SetUnitScalePercent( GUI_I_P_GoldPile, 200, 200, 200 )
        call SetUnitScalePercent( GUI_I_P_GoldCoin, 200, 200, 200 )
        call SetUnitScalePercent( GUI_I_P_PileOfRiches, 200, 200, 200 )

    set i = 1
    loop
        exitwhen i > 40
        call AddSpecialEffectLocBJ(PolarProjectionBJ(GetRectCenter(gg_rct_PileOfRiches), GetRandomReal(5,100), GetRandomReal(0,360)), "Objects\\InventoryItems\\PotofGold\\PotofGold.mdl" )
        set i = i + 1
    endloop
    call AddSpecialEffectLocBJ(PolarProjectionBJ(GetRectCenter(gg_rct_PileOfRiches), GetRandomReal(5,100), GetRandomReal(0,360)), "Objects\\InventoryItems\\tomeGreen\\tomeGreen.mdl" )
    call AddSpecialEffectLocBJ(PolarProjectionBJ(GetRectCenter(gg_rct_PileOfRiches), GetRandomReal(5,100), GetRandomReal(0,360)), "Objects\\InventoryItems\\tomeRed\\tomeRed.mdl" )
    call AddSpecialEffectLocBJ(PolarProjectionBJ(GetRectCenter(gg_rct_PileOfRiches), GetRandomReal(5,100), GetRandomReal(0,360)), "Objects\\InventoryItems\\tomeBlue\\tomeBlue.mdl" )

    set i = 1
    loop
        exitwhen i > 40
        call AddSpecialEffectLocBJ(PolarProjectionBJ(GetRectCenter(gg_rct_GoldPile), GetRandomReal(5,100), GetRandomReal(0,360)), "Objects\\InventoryItems\\PotofGold\\PotofGold.mdl" )
        set i = i + 1
    endloop

    call AddSpecialEffectLocBJ( GetRectCenter(gg_rct_GoldCoin), "Objects\\InventoryItems\\PotofGold\\PotofGold.mdl" )





//Doodads
    call CreateTextTagLocBJ( "Doodads", GetUnitLoc(GUI_Doodads), 0, 17.00, 100, 100, 100, 0 )
    call SetUnitVertexColorBJ( GUI_Doodads, 100, 100, 100, 100.00 )

    call CreateTextTagLocBJ( "Create   (dc)", GetUnitLoc(GUI_D_Create), 0, 15.00, 100, 100, 100, 0 )
    call SetUnitVertexColorBJ( GUI_D_Create, 100, 100, 100, 100.00 )

    call CreateTextTagLocBJ( "Remove   (dr)", GetUnitLoc(GUI_D_Remove), 0, 15.00, 100, 100, 100, 0 )
    call SetUnitVertexColorBJ( GUI_D_Remove, 100, 100, 100, 100.00 )

    call CreateTextTagLocBJ( "Kill   (dk)", GetUnitLoc(GUI_D_Kill), 0, 15.00, 100, 100, 100, 0 )
    call SetUnitVertexColorBJ( GUI_D_Kill, 100, 100, 100, 100.00 )

    call CreateTextTagLocBJ( "Revive   (dv)", GetUnitLoc(GUI_D_Revive), 0, 15.00, 100, 100, 100, 0 )
    call SetUnitVertexColorBJ( GUI_D_Revive, 100, 100, 100, 100.00 )

    call CreateTextTagLocBJ( "Toggle   (dt)", GetUnitLoc(GUI_D_Toggle), 0, 15.00, 100, 100, 100, 0 )
    call SetUnitVertexColorBJ( GUI_D_Toggle, 100, 100, 100, 100.00 )

        call SetUnitAnimation( GUI_D_P_Grove, GUI_Tag_Tile)
        call SetUnitAnimation( GUI_D_P_Tree, GUI_Tag_Tile)
        call SetUnitAnimation( GUI_D_P_Blight, GUI_Tag_Tile)
        call SetUnitAnimation( GUI_D_P_Dispel, GUI_Tag_Tile)
        call SetUnitVertexColorBJ( GUI_D_P_Grove, 100,100,100,100 )
        call SetUnitVertexColorBJ( GUI_D_P_Tree, 100,100,100,100 )
        call SetUnitVertexColorBJ( GUI_D_P_Blight, 100,100,100,100 )
        call SetUnitVertexColorBJ( GUI_D_P_Dispel, 100,100,100,100 )
        call SetUnitScalePercent( GUI_D_P_Grove, 400, 400, 400 )
        call SetUnitScalePercent( GUI_D_P_Tree, 200, 200, 200 )
        call SetUnitScalePercent( GUI_D_P_Blight, 300, 300, 300 )
        call SetUnitScalePercent( GUI_D_P_Dispel, 200, 200, 200 )
        call AddSpecialEffectLocBJ( GetRectCenter(gg_rct_BlightDispel), "Abilities\\Spells\\NightElf\\TargetArtLumber\\TargetArtLumber.mdl" )
        call SetUnitOwner( GUI_D_P_Line1, Player(PLAYER_NEUTRAL_PASSIVE), true )
        call SetUnitOwner( GUI_D_P_Line2, Player(PLAYER_NEUTRAL_PASSIVE), true )




//Misc
//    call SetUnitAnimation(GUI_Misc, GUI_Tag_Misc)
//        call SetUnitScalePercent( GUI_Misc, 120,120,120 )
//        call SetUnitVertexColorBJ( GUI_Misc, 50,50,100,0 )

//    call SetUnitAnimation(GUI_M_Portal, GUI_Tag_Portal)
//        call SetUnitVertexColorBJ( GUI_M_Portal, 30,30,30,0 )

//    call SetUnitAnimation(GUI_M_Cinematic, GUI_Tag_Cinematic)
//        call SetUnitVertexColorBJ( GUI_M_Cinematic, 30,30,30,0 )

//    call SetUnitAnimation(GUI_M_Effect, GUI_Tag_Effect)
//        call SetUnitVertexColorBJ( GUI_M_Effect, 30,30,30,0 )


    call CreateTextTagLocBJ( "Misc", GetUnitLoc(GUI_Misc), 0, 17.00, 100, 100, 100, 0 )
    call SetUnitVertexColorBJ( GUI_Misc, 100, 100, 100, 100.00 )

    call CreateTextTagLocBJ( "Waygate (mw)", GetUnitLoc(GUI_M_Portal), 0, 15.00, 100, 100, 100, 0 )
    call SetUnitVertexColorBJ( GUI_M_Portal, 100, 100, 100, 100.00 )

//    call CreateTextTagLocBJ( "Cinematic", GetUnitLoc(GUI_M_Cinematic), 0, 15.00, 30, 30, 30, 0 )
    call SetUnitVertexColorBJ( GUI_M_Cinematic, 100, 100, 100, 100.00 )

    call CreateTextTagLocBJ( "Boot", GetUnitLoc(GUI_M_Boot), 0, 15.00, 100, 100, 100, 0 )
    call SetUnitVertexColorBJ( GUI_M_Boot, 100, 100, 100, 100.00 )




//Toolbox
    call CreateTextTagLocBJ( "Toolbox", GetUnitLoc(GUI_Toolbox), 0, 17.00, 100, 100, 100, 0 )
    call SetUnitVertexColorBJ( GUI_Toolbox, 100, 100, 100, 100.00 )

        call SetUnitAnimation(GUI_T_Tile_Blue, GUI_Tag_Tile)
        call SetUnitAnimation(GUI_T_Tile_Teal, GUI_Tag_Tile)
        call SetUnitAnimation(GUI_T_Tile_Purple, GUI_Tag_Tile)
        call SetUnitAnimation(GUI_T_Tile_Orange, GUI_Tag_Tile)
        call SetUnitAnimation(GUI_T_Tile_Green, GUI_Tag_Tile)
        call SetUnitAnimation(GUI_T_Tile_Pink, GUI_Tag_Tile)
        call SetUnitAnimation(GUI_T_Tile_Brown, GUI_Tag_Tile)
        call SetUnitAnimation(GUI_T_Tile_Enemy, GUI_Tag_Tile)
        call SetUnitAnimation(GUI_T_Tile_Ally, GUI_Tag_Tile)
        call SetUnitAnimation(GUI_T_Tile_Gray, GUI_Tag_Tile)
        call SetUnitAnimation(GUI_T_Tile_Cyan, GUI_Tag_Tile)
        call SetUnitAnimation(GUI_T_Tile_DarkGreen, GUI_Tag_Tile)
        call SetUnitVertexColorBJ( GUI_T_Tile_Blue, 0,0,100,0 )
        call SetUnitVertexColorBJ( GUI_T_Tile_Teal, 0,100,80,0 )
        call SetUnitVertexColorBJ( GUI_T_Tile_Purple, 25,0,50,0 )
        call SetUnitVertexColorBJ( GUI_T_Tile_Orange, 100,50,0,0 )
        call SetUnitVertexColorBJ( GUI_T_Tile_Green, 0,100,0,0 )
        call SetUnitVertexColorBJ( GUI_T_Tile_Pink, 100,30,70,0 )
        call SetUnitVertexColorBJ( GUI_T_Tile_Brown, 25,15,0,0 )
        call SetUnitVertexColorBJ( GUI_T_Tile_Enemy, 100,0,0,0 )
        call SetUnitVertexColorBJ( GUI_T_Tile_Ally, 100,100,0,0 )
        call SetUnitVertexColorBJ( GUI_T_Tile_Gray, 50,50,50,0 )
        call SetUnitVertexColorBJ( GUI_T_Tile_Cyan, 50,75,100,0 )
        call SetUnitVertexColorBJ( GUI_T_Tile_DarkGreen, 5,38,25,0 )


    set udg_GUI_Tile[1] = GUI_T_Tile_Enemy
    set udg_GUI_Tile[5] = GUI_T_Tile_Ally

    set udg_GUI_Tile[2] = GUI_T_Tile_Blue
    set udg_GUI_Tile[3] = GUI_T_Tile_Teal
    set udg_GUI_Tile[4] = GUI_T_Tile_Purple
    set udg_GUI_Tile[6] = GUI_T_Tile_Orange
    set udg_GUI_Tile[7] = GUI_T_Tile_Green
    set udg_GUI_Tile[8] = GUI_T_Tile_Pink
    set udg_GUI_Tile[12] = GUI_T_Tile_Brown

    set udg_GUI_Tile[9] = GUI_T_Tile_Gray
    set udg_GUI_Tile[10] = GUI_T_Tile_Cyan
    set udg_GUI_Tile[11] = GUI_T_Tile_DarkGreen


    call GroupAddUnitSimple( GUI_T_Tile_Enemy, udg_GUI_Tile_Group )
    call GroupAddUnitSimple( GUI_T_Tile_Ally, udg_GUI_Tile_Group )

    call GroupAddUnitSimple( GUI_T_Tile_Blue, udg_GUI_Tile_Group )
    call GroupAddUnitSimple( GUI_T_Tile_Teal, udg_GUI_Tile_Group )
    call GroupAddUnitSimple( GUI_T_Tile_Purple, udg_GUI_Tile_Group )
    call GroupAddUnitSimple( GUI_T_Tile_Orange, udg_GUI_Tile_Group )
    call GroupAddUnitSimple( GUI_T_Tile_Green, udg_GUI_Tile_Group )
    call GroupAddUnitSimple( GUI_T_Tile_Pink, udg_GUI_Tile_Group )
    call GroupAddUnitSimple( GUI_T_Tile_Brown, udg_GUI_Tile_Group )

    call GroupAddUnitSimple( GUI_T_Tile_Gray, udg_GUI_Tile_Group )
    call GroupAddUnitSimple( GUI_T_Tile_Cyan, udg_GUI_Tile_Group )
    call GroupAddUnitSimple( GUI_T_Tile_DarkGreen, udg_GUI_Tile_Group )


    //pointers
    //set udg_GUI_Pointer_Loc[9] = GetUnitLoc(gg_unit_E000_0147)
    //set udg_GUI_Pointer_Loc[10] = GetUnitLoc(gg_unit_E000_0148)
    //set udg_GUI_Pointer_Loc[11] = GetUnitLoc(gg_unit_E000_0149)
    call SetUnitInvulnerable