//===========================================================================
//
// Terenas Stand
//
// Warcraft III map script
// Generated by the Warcraft III World Editor
// Date: Tue Dec 06 14:06:56 2011
// Map Author: Blizzard Entertainment
//
//===========================================================================
//***************************************************************************
//*
//* Global Variables
//*
//***************************************************************************
globals
// Generated
trigger gg_trg_Custom_Initialization = null
trigger gg_trg_paladin = null
trigger gg_trg_notes = null
trigger gg_trg_timerloops = null
trigger gg_trg_yojimbo = null
trigger gg_trg_coin_drops = null
trigger gg_trg_GT = null
trigger gg_trg_MSGS = null
trigger gg_trg_DebugS = null
trigger gg_trg_Sorter = null
trigger gg_trg_jBoard = null
trigger gg_trg_jasscault = null
trigger gg_trg_Skeleton_Lord = null
trigger gg_trg_Untitled_Trigger_005 = null
trigger gg_trg_fudo = null
trigger gg_trg_STM = null
trigger gg_trg_TTG = null
trigger gg_trg_TimerEvents = null
trigger gg_trg_pool = null
trigger gg_trg_SimError = null
trigger gg_trg_jumpy = null
trigger gg_trg_quests = null
trigger gg_trg_GUI_BLANK_TRIGGER = null
trigger gg_trg_testing = null
trigger gg_trg_xecollider_Copy = null
trigger gg_trg_xefx_Copy_Copy = null
trigger gg_trg_SomeNeatFunctions = null
trigger gg_trg_Black_Hole = null
trigger gg_trg_SithDebilitate = null
trigger gg_trg_Maelstrom = null
trigger gg_trg_Passive_Polymorph = null
trigger gg_trg_forceshield = null
trigger gg_trg_Demon_Slash = null
trigger gg_trg_kathy_windwood = null
trigger gg_trg_korg_lighthorn = null
trigger gg_trg_Birds = null
trigger gg_trg_Aquatic_Blast__NoLightning_Version = null
trigger gg_trg_Water_Spirits = null
trigger gg_trg_Water_Strike = null
trigger gg_trg_Hydro_Rings = null
trigger gg_trg_Web = null
trigger gg_trg_AquaCrush = null
trigger gg_trg_Unleash_Liquid = null
trigger gg_trg_Egg_Shack = null
trigger gg_trg_Drown = null
trigger gg_trg_apocalypse = null
trigger gg_trg_angelskiss = null
trigger gg_trg_coloritems = null
trigger gg_trg_mercenaries = null
trigger gg_trg_recipesinstructions = null
trigger gg_trg_recipesTAF = null
trigger gg_trg_itemfunctions = null
trigger gg_trg_getissuedorderitem = null
trigger gg_trg_mbSTM = null
trigger gg_trg_leap = null
trigger gg_trg_TT = null
trigger gg_trg_Geometry_Funcs = null
trigger gg_trg_recipesys = null
trigger gg_trg_table = null
trigger gg_trg_spellevents = null
trigger gg_trg_timereffects = null
trigger gg_trg_GroupUtils = null
trigger gg_trg_TimerUtils = null
trigger gg_trg_SoundUtils = null
trigger gg_trg_Stack = null
trigger gg_trg_PolarProjection = null
trigger gg_trg_oct_09_damage_stuff_by_anitarf = null
trigger gg_trg_GetNearest = null
trigger gg_trg_DestructableLib = null
trigger gg_trg_TerrainPathabilitynew = null
trigger gg_trg_LineSegment_Copy = null
trigger gg_trg_xebasic_Copy = null
trigger gg_trg_xedamage_Copy = null
trigger gg_trg_BoundSentinel = null
trigger gg_trg_xepreload_Copy_Copy = null
trigger gg_trg_xecast_Copy_Copy = null
trigger gg_trg_KT = null
trigger gg_trg_ABuff_Copy = null
trigger gg_trg_LightLeaklessDamageDetect = null
endglobals
function InitGlobals takes nothing returns nothing
endfunction
//***************************************************************************
//*
//* Unit Item Tables
//*
//***************************************************************************
function Unit000012_DropItems takes nothing returns nothing
local widget trigWidget = null
local unit trigUnit = null
local integer itemID = 0
local boolean canDrop = true
set trigWidget = bj_lastDyingWidget
if (trigWidget == null) then
set trigUnit = GetTriggerUnit()
endif
if (trigUnit != null) then
set canDrop = not IsUnitHidden(trigUnit)
if (canDrop and GetChangingUnit() != null) then
set canDrop = (GetChangingUnitPrevOwner() == Player(PLAYER_NEUTRAL_AGGRESSIVE))
endif
endif
if (canDrop) then
// Item set 0
call RandomDistReset( )
call RandomDistAddItem( ChooseRandomItemEx( ITEM_TYPE_PERMANENT, 1 ), 100 )
set itemID = RandomDistChoose( )
if (trigUnit != null) then
call UnitDropItem( trigUnit, itemID )
else
call WidgetDropItem( trigWidget, itemID )
endif
endif
set bj_lastDyingWidget = null
call DestroyTrigger(GetTriggeringTrigger())
endfunction
function Unit000015_DropItems takes nothing returns nothing
local widget trigWidget = null
local unit trigUnit = null
local integer itemID = 0
local boolean canDrop = true
set trigWidget = bj_lastDyingWidget
if (trigWidget == null) then
set trigUnit = GetTriggerUnit()
endif
if (trigUnit != null) then
set canDrop = not IsUnitHidden(trigUnit)
if (canDrop and GetChangingUnit() != null) then
set canDrop = (GetChangingUnitPrevOwner() == Player(PLAYER_NEUTRAL_AGGRESSIVE))
endif
endif
if (canDrop) then
// Item set 0
call RandomDistReset( )
call RandomDistAddItem( ChooseRandomItemEx( ITEM_TYPE_PERMANENT, 1 ), 100 )
set itemID = RandomDistChoose( )
if (trigUnit != null) then
call UnitDropItem( trigUnit, itemID )
else
call WidgetDropItem( trigWidget, itemID )
endif
endif
set bj_lastDyingWidget = null
call DestroyTrigger(GetTriggeringTrigger())
endfunction
function Unit000018_DropItems takes nothing returns nothing
local widget trigWidget = null
local unit trigUnit = null
local integer itemID = 0
local boolean canDrop = true
set trigWidget = bj_lastDyingWidget
if (trigWidget == null) then
set trigUnit = GetTriggerUnit()
endif
if (trigUnit != null) then
set canDrop = not IsUnitHidden(trigUnit)
if (canDrop and GetChangingUnit() != null) then
set canDrop = (GetChangingUnitPrevOwner() == Player(PLAYER_NEUTRAL_AGGRESSIVE))
endif
endif
if (canDrop) then
// Item set 0
call RandomDistReset( )
call RandomDistAddItem( ChooseRandomItemEx( ITEM_TYPE_PERMANENT, 1 ), 100 )
set itemID = RandomDistChoose( )
if (trigUnit != null) then
call UnitDropItem( trigUnit, itemID )
else
call WidgetDropItem( trigWidget, itemID )
endif
endif
set bj_lastDyingWidget = null
call DestroyTrigger(GetTriggeringTrigger())
endfunction
function Unit000021_DropItems takes nothing returns nothing
local widget trigWidget = null
local unit trigUnit = null
local integer itemID = 0
local boolean canDrop = true
set trigWidget = bj_lastDyingWidget
if (trigWidget == null) then
set trigUnit = GetTriggerUnit()
endif
if (trigUnit != null) then
set canDrop = not IsUnitHidden(trigUnit)
if (canDrop and GetChangingUnit() != null) then
set canDrop = (GetChangingUnitPrevOwner() == Player(PLAYER_NEUTRAL_AGGRESSIVE))
endif
endif
if (canDrop) then
// Item set 0
call RandomDistReset( )
call RandomDistAddItem( ChooseRandomItemEx( ITEM_TYPE_PERMANENT, 2 ), 100 )
set itemID = RandomDistChoose( )
if (trigUnit != null) then
call UnitDropItem( trigUnit, itemID )
else
call WidgetDropItem( trigWidget, itemID )
endif
endif
set bj_lastDyingWidget = null
call DestroyTrigger(GetTriggeringTrigger())
endfunction
function Unit000022_DropItems takes nothing returns nothing
local widget trigWidget = null
local unit trigUnit = null
local integer itemID = 0
local boolean canDrop = true
set trigWidget = bj_lastDyingWidget
if (trigWidget == null) then
set trigUnit = GetTriggerUnit()
endif
if (trigUnit != null) then
set canDrop = not IsUnitHidden(trigUnit)
if (canDrop and GetChangingUnit() != null) then
set canDrop = (GetChangingUnitPrevOwner() == Player(PLAYER_NEUTRAL_AGGRESSIVE))
endif
endif
if (canDrop) then
// Item set 0
call RandomDistReset( )
call RandomDistAddItem( ChooseRandomItemEx( ITEM_TYPE_POWERUP, 1 ), 100 )
set itemID = RandomDistChoose( )
if (trigUnit != null) then
call UnitDropItem( trigUnit, itemID )
else
call WidgetDropItem( trigWidget, itemID )
endif
endif
set bj_lastDyingWidget = null
call DestroyTrigger(GetTriggeringTrigger())
endfunction
function Unit000024_DropItems takes nothing returns nothing
local widget trigWidget = null
local unit trigUnit = null
local integer itemID = 0
local boolean canDrop = true
set trigWidget = bj_lastDyingWidget
if (trigWidget == null) then
set trigUnit = GetTriggerUnit()
endif
if (trigUnit != null) then
set canDrop = not IsUnitHidden(trigUnit)
if (canDrop and GetChangingUnit() != null) then
set canDrop = (GetChangingUnitPrevOwner() == Player(PLAYER_NEUTRAL_AGGRESSIVE))
endif
endif
if (canDrop) then
// Item set 0
call RandomDistReset( )
call RandomDistAddItem( ChooseRandomItemEx( ITEM_TYPE_PERMANENT, 2 ), 100 )
set itemID = RandomDistChoose( )
if (trigUnit != null) then
call UnitDropItem( trigUnit, itemID )
else
call WidgetDropItem( trigWidget, itemID )
endif
endif
set bj_lastDyingWidget = null
call DestroyTrigger(GetTriggeringTrigger())
endfunction
function Unit000025_DropItems takes nothing returns nothing
local widget trigWidget = null
local unit trigUnit = null
local integer itemID = 0
local boolean canDrop = true
set trigWidget = bj_lastDyingWidget
if (trigWidget == null) then
set trigUnit = GetTriggerUnit()
endif
if (trigUnit != null) then
set canDrop = not IsUnitHidden(trigUnit)
if (canDrop and GetChangingUnit() != null) then
set canDrop = (GetChangingUnitPrevOwner() == Player(PLAYER_NEUTRAL_AGGRESSIVE))
endif
endif
if (canDrop) then
// Item set 0
call RandomDistReset( )
call RandomDistAddItem( ChooseRandomItemEx( ITEM_TYPE_POWERUP, 1 ), 100 )
set itemID = RandomDistChoose( )
if (trigUnit != null) then
call UnitDropItem( trigUnit, itemID )
else
call WidgetDropItem( trigWidget, itemID )
endif
endif
set bj_lastDyingWidget = null
call DestroyTrigger(GetTriggeringTrigger())
endfunction
function Unit000032_DropItems takes nothing returns nothing
local widget trigWidget = null
local unit trigUnit = null
local integer itemID = 0
local boolean canDrop = true
set trigWidget = bj_lastDyingWidget
if (trigWidget == null) then
set trigUnit = GetTriggerUnit()
endif
if (trigUnit != null) then
set canDrop = not IsUnitHidden(trigUnit)
if (canDrop and GetChangingUnit() != null) then
set canDrop = (GetChangingUnitPrevOwner() == Player(PLAYER_NEUTRAL_AGGRESSIVE))
endif
endif
if (canDrop) then
// Item set 0
call RandomDistReset( )
call RandomDistAddItem( ChooseRandomItemEx( ITEM_TYPE_CHARGED, 2 ), 100 )
set itemID = RandomDistChoose( )
if (trigUnit != null) then
call UnitDropItem( trigUnit, itemID )
else
call WidgetDropItem( trigWidget, itemID )
endif
// Item set 1
call RandomDistReset( )
call RandomDistAddItem( ChooseRandomItemEx( ITEM_TYPE_POWERUP, 1 ), 100 )
set itemID = RandomDistChoose( )
if (trigUnit != null) then
call UnitDropItem( trigUnit, itemID )
else
call WidgetDropItem( trigWidget, itemID )
endif
endif
set bj_lastDyingWidget = null
call DestroyTrigger(GetTriggeringTrigger())
endfunction
function Unit000033_DropItems takes nothing returns nothing
local widget trigWidget = null
local unit trigUnit = null
local integer itemID = 0
local boolean canDrop = true
set trigWidget = bj_lastDyingWidget
if (trigWidget == null) then
set trigUnit = GetTriggerUnit()
endif
if (trigUnit != null) then
set canDrop = not IsUnitHidden(trigUnit)
if (canDrop and GetChangingUnit() != null) then
set canDrop = (GetChangingUnitPrevOwner() == Player(PLAYER_NEUTRAL_AGGRESSIVE))
endif
endif
if (canDrop) then
// Item set 0
call RandomDistReset( )
call RandomDistAddItem( ChooseRandomItemEx( ITEM_TYPE_PERMANENT, 4 ), 100 )
set itemID = RandomDistChoose( )
if (trigUnit != null) then
call UnitDropItem( trigUnit, itemID )
else
call WidgetDropItem( trigWidget, itemID )
endif
endif
set bj_lastDyingWidget = null
call DestroyTrigger(GetTriggeringTrigger())
endfunction
function Unit000034_DropItems takes nothing returns nothing
local widget trigWidget = null
local unit trigUnit = null
local integer itemID = 0
local boolean canDrop = true
set trigWidget = bj_lastDyingWidget
if (trigWidget == null) then
set trigUnit = GetTriggerUnit()
endif
if (trigUnit != null) then
set canDrop = not IsUnitHidden(trigUnit)
if (canDrop and GetChangingUnit() != null) then
set canDrop = (GetChangingUnitPrevOwner() == Player(PLAYER_NEUTRAL_AGGRESSIVE))
endif
endif
if (canDrop) then
// Item set 0
call RandomDistReset( )
call RandomDistAddItem( ChooseRandomItemEx( ITEM_TYPE_POWERUP, 2 ), 100 )
set itemID = RandomDistChoose( )
if (trigUnit != null) then
call UnitDropItem( trigUnit, itemID )
else
call WidgetDropItem( trigWidget, itemID )
endif
endif
set bj_lastDyingWidget = null
call DestroyTrigger(GetTriggeringTrigger())
endfunction
function Unit000038_DropItems takes nothing returns nothing
local widget trigWidget = null
local unit trigUnit = null
local integer itemID = 0
local boolean canDrop = true
set trigWidget = bj_lastDyingWidget
if (trigWidget == null) then
set trigUnit = GetTriggerUnit()
endif
if (trigUnit != null) then
set canDrop = not IsUnitHidden(trigUnit)
if (canDrop and GetChangingUnit() != null) then
set canDrop = (GetChangingUnitPrevOwner() == Player(PLAYER_NEUTRAL_AGGRESSIVE))
endif
endif
if (canDrop) then
// Item set 0
call RandomDistReset( )
call RandomDistAddItem( ChooseRandomItemEx( ITEM_TYPE_PERMANENT, 4 ), 100 )
set itemID = RandomDistChoose( )
if (trigUnit != null) then
call UnitDropItem( trigUnit, itemID )
else
call WidgetDropItem( trigWidget, itemID )
endif
endif
set bj_lastDyingWidget = null
call DestroyTrigger(GetTriggeringTrigger())
endfunction
function Unit000039_DropItems takes nothing returns nothing
local widget trigWidget = null
local unit trigUnit = null
local integer itemID = 0
local boolean canDrop = true
set trigWidget = bj_lastDyingWidget
if (trigWidget == null) then
set trigUnit = GetTriggerUnit()
endif
if (trigUnit != null) then
set canDrop = not IsUnitHidden(trigUnit)
if (canDrop and GetChangingUnit() != null) then
set canDrop = (GetChangingUnitPrevOwner() == Player(PLAYER_NEUTRAL_AGGRESSIVE))
endif
endif
if (canDrop) then
// Item set 0
call RandomDistReset( )
call RandomDistAddItem( ChooseRandomItemEx( ITEM_TYPE_POWERUP, 2 ), 100 )
set itemID = RandomDistChoose( )
if (trigUnit != null) then
call UnitDropItem( trigUnit, itemID )
else
call WidgetDropItem( trigWidget, itemID )
endif
endif
set bj_lastDyingWidget = null
call DestroyTrigger(GetTriggeringTrigger())
endfunction
function Unit000043_DropItems takes nothing returns nothing
local widget trigWidget = null
local unit trigUnit = null
local integer itemID = 0
local boolean canDrop = true
set trigWidget = bj_lastDyingWidget
if (trigWidget == null) then
set trigUnit = GetTriggerUnit()
endif
if (trigUnit != null) then
set canDrop = not IsUnitHidden(trigUnit)
if (canDrop and GetChangingUnit() != null) then
set canDrop = (GetChangingUnitPrevOwner() == Player(PLAYER_NEUTRAL_AGGRESSIVE))
endif
endif
if (canDrop) then
// Item set 0
call RandomDistReset( )
call RandomDistAddItem( ChooseRandomItemEx( ITEM_TYPE_CHARGED, 3 ), 100 )
set itemID = RandomDistChoose( )
if (trigUnit != null) then
call UnitDropItem( trigUnit, itemID )
else
call WidgetDropItem( trigWidget, itemID )
endif
endif
set bj_lastDyingWidget = null
call DestroyTrigger(GetTriggeringTrigger())
endfunction
function Unit000044_DropItems takes nothing returns nothing
local widget trigWidget = null
local unit trigUnit = null
local integer itemID = 0
local boolean canDrop = true
set trigWidget = bj_lastDyingWidget
if (trigWidget == null) then
set trigUnit = GetTriggerUnit()
endif
if (trigUnit != null) then
set canDrop = not IsUnitHidden(trigUnit)
if (canDrop and GetChangingUnit() != null) then
set canDrop = (GetChangingUnitPrevOwner() == Player(PLAYER_NEUTRAL_AGGRESSIVE))
endif
endif
if (canDrop) then
// Item set 0
call RandomDistReset( )
call RandomDistAddItem( ChooseRandomItemEx( ITEM_TYPE_POWERUP, 1 ), 100 )
set itemID = RandomDistChoose( )
if (trigUnit != null) then
call UnitDropItem( trigUnit, itemID )
else
call WidgetDropItem( trigWidget, itemID )
endif
endif
set bj_lastDyingWidget = null
call DestroyTrigger(GetTriggeringTrigger())
endfunction
function Unit000048_DropItems takes nothing returns nothing
local widget trigWidget = null
local unit trigUnit = null
local integer itemID = 0
local boolean canDrop = true
set trigWidget = bj_lastDyingWidget
if (trigWidget == null) then
set trigUnit = GetTriggerUnit()
endif
if (trigUnit != null) then
set canDrop = not IsUnitHidden(trigUnit)
if (canDrop and GetChangingUnit() != null) then
set canDrop = (GetChangingUnitPrevOwner() == Player(PLAYER_NEUTRAL_AGGRESSIVE))
endif
endif
if (canDrop) then
// Item set 0
call RandomDistReset( )
call RandomDistAddItem( ChooseRandomItemEx( ITEM_TYPE_CHARGED, 3 ), 100 )
set itemID = RandomDistChoose( )
if (trigUnit != null) then
call UnitDropItem( trigUnit, itemID )
else
call WidgetDropItem( trigWidget, itemID )
endif
endif
set bj_lastDyingWidget = null
call DestroyTrigger(GetTriggeringTrigger())
endfunction
function Unit000049_DropItems takes nothing returns nothing
local widget trigWidget = null
local unit trigUnit = null
local integer itemID = 0
local boolean canDrop = true
set trigWidget = bj_lastDyingWidget
if (trigWidget == null) then
set trigUnit = GetTriggerUnit()
endif
if (trigUnit != null) then
set canDrop = not IsUnitHidden(trigUnit)
if (canDrop and GetChangingUnit() != null) then
set canDrop = (GetChangingUnitPrevOwner() == Player(PLAYER_NEUTRAL_AGGRESSIVE))
endif
endif
if (canDrop) then
// Item set 0
call RandomDistReset( )
call RandomDistAddItem( ChooseRandomItemEx( ITEM_TYPE_POWERUP, 1 ), 100 )
set itemID = RandomDistChoose( )
if (trigUnit != null) then
call UnitDropItem( trigUnit, itemID )
else
call WidgetDropItem( trigWidget, itemID )
endif
endif
set bj_lastDyingWidget = null
call DestroyTrigger(GetTriggeringTrigger())
endfunction
function Unit000055_DropItems takes nothing returns nothing
local widget trigWidget = null
local unit trigUnit = null
local integer itemID = 0
local boolean canDrop = true
set trigWidget = bj_lastDyingWidget
if (trigWidget == null) then
set trigUnit = GetTriggerUnit()
endif
if (trigUnit != null) then
set canDrop = not IsUnitHidden(trigUnit)
if (canDrop and GetChangingUnit() != null) then
set canDrop = (GetChangingUnitPrevOwner() == Player(PLAYER_NEUTRAL_AGGRESSIVE))
endif
endif
if (canDrop) then
// Item set 0
call RandomDistReset( )
call RandomDistAddItem( ChooseRandomItemEx( ITEM_TYPE_PERMANENT, 2 ), 100 )
set itemID = RandomDistChoose( )
if (trigUnit != null) then
call UnitDropItem( trigUnit, itemID )
else
call WidgetDropItem( trigWidget, itemID )
endif
endif
set bj_lastDyingWidget = null
call DestroyTrigger(GetTriggeringTrigger())
endfunction
function Unit000060_DropItems takes nothing returns nothing
local widget trigWidget = null
local unit trigUnit = null
local integer itemID = 0
local boolean canDrop = true
set trigWidget = bj_lastDyingWidget
if (trigWidget == null) then
set trigUnit = GetTriggerUnit()
endif
if (trigUnit != null) then
set canDrop = not IsUnitHidden(trigUnit)
if (canDrop and GetChangingUnit() != null) then
set canDrop = (GetChangingUnitPrevOwner() == Player(PLAYER_NEUTRAL_AGGRESSIVE))
endif
endif
if (canDrop) then
// Item set 0
call RandomDistReset( )
call RandomDistAddItem( ChooseRandomItemEx( ITEM_TYPE_PERMANENT, 2 ), 100 )
set itemID = RandomDistChoose( )
if (trigUnit != null) then
call UnitDropItem( trigUnit, itemID )
else
call WidgetDropItem( trigWidget, itemID )
endif
endif
set bj_lastDyingWidget = null
call DestroyTrigger(GetTriggeringTrigger())
endfunction
function Unit000063_DropItems takes nothing returns nothing
local widget trigWidget = null
local unit trigUnit = null
local integer itemID = 0
local boolean canDrop = true
set trigWidget = bj_lastDyingWidget
if (trigWidget == null) then
set trigUnit = GetTriggerUnit()
endif
if (trigUnit != null) then
set canDrop = not IsUnitHidden(trigUnit)
if (canDrop and GetChangingUnit() != null) then
set canDrop = (GetChangingUnitPrevOwner() == Player(PLAYER_NEUTRAL_AGGRESSIVE))
endif
endif
if (canDrop) then
// Item set 0
call RandomDistReset( )
call RandomDistAddItem( ChooseRandomItemEx( ITEM_TYPE_POWERUP, 1 ), 100 )
set itemID = RandomDistChoose( )
if (trigUnit != null) then
call UnitDropItem( trigUnit, itemID )
else
call WidgetDropItem( trigWidget, itemID )
endif
endif
set bj_lastDyingWidget = null
call DestroyTrigger(GetTriggeringTrigger())
endfunction
function Unit000066_DropItems takes nothing returns nothing
local widget trigWidget = null
local unit trigUnit = null
local integer itemID = 0
local boolean canDrop = true
set trigWidget = bj_lastDyingWidget
if (trigWidget == null) then
set trigUnit = GetTriggerUnit()
endif
if (trigUnit != null) then
set canDrop = not IsUnitHidden(trigUnit)
if (canDrop and GetChangingUnit() != null) then
set canDrop = (GetChangingUnitPrevOwner() == Player(PLAYER_NEUTRAL_AGGRESSIVE))
endif
endif
if (canDrop) then
// Item set 0
call RandomDistReset( )
call RandomDistAddItem( ChooseRandomItemEx( ITEM_TYPE_POWERUP, 1 ), 100 )
set itemID = RandomDistChoose( )
if (trigUnit != null) then
call UnitDropItem( trigUnit, itemID )
else
call WidgetDropItem( trigWidget, itemID )
endif
endif
set bj_lastDyingWidget = null
call DestroyTrigger(GetTriggeringTrigger())
endfunction
function Unit000069_DropItems takes nothing returns nothing
local widget trigWidget = null
local unit trigUnit = null
local integer itemID = 0
local boolean canDrop = true
set trigWidget = bj_lastDyingWidget
if (trigWidget == null) then
set trigUnit = GetTriggerUnit()
endif
if (trigUnit != null) then
set canDrop = not IsUnitHidden(trigUnit)
if (canDrop and GetChangingUnit() != null) then
set canDrop = (GetChangingUnitPrevOwner() == Player(PLAYER_NEUTRAL_AGGRESSIVE))
endif
endif
if (canDrop) then
// Item set 0
call RandomDistReset( )
call RandomDistAddItem( ChooseRandomItemEx( ITEM_TYPE_POWERUP, 1 ), 100 )
set itemID = RandomDistChoose( )
if (trigUnit != null) then
call UnitDropItem( trigUnit, itemID )
else
call WidgetDropItem( trigWidget, itemID )
endif
endif
set bj_lastDyingWidget = null
call DestroyTrigger(GetTriggeringTrigger())
endfunction
function Unit000072_DropItems takes nothing returns nothing
local widget trigWidget = null
local unit trigUnit = null
local integer itemID = 0
local boolean canDrop = true
set trigWidget = bj_lastDyingWidget
if (trigWidget == null) then
set trigUnit = GetTriggerUnit()
endif
if (trigUnit != null) then
set canDrop = not IsUnitHidden(trigUnit)
if (canDrop and GetChangingUnit() != null) then
set canDrop = (GetChangingUnitPrevOwner() == Player(PLAYER_NEUTRAL_AGGRESSIVE))
endif
endif
if (canDrop) then
// Item set 0
call RandomDistReset( )
call RandomDistAddItem( ChooseRandomItemEx( ITEM_TYPE_POWERUP, 1 ), 100 )
set itemID = RandomDistChoose( )
if (trigUnit != null) then
call UnitDropItem( trigUnit, itemID )
else
call WidgetDropItem( trigWidget, itemID )
endif
endif
set bj_lastDyingWidget = null
call DestroyTrigger(GetTriggeringTrigger())
endfunction
function Unit000075_DropItems takes nothing returns nothing
local widget trigWidget = null
local unit trigUnit = null
local integer itemID = 0
local boolean canDrop = true
set trigWidget = bj_lastDyingWidget
if (trigWidget == null) then
set trigUnit = GetTriggerUnit()
endif
if (trigUnit != null) then
set canDrop = not IsUnitHidden(trigUnit)
if (canDrop and GetChangingUnit() != null) then
set canDrop = (GetChangingUnitPrevOwner() == Player(PLAYER_NEUTRAL_AGGRESSIVE))
endif
endif
if (canDrop) then
// Item set 0
call RandomDistReset( )
call RandomDistAddItem( ChooseRandomItemEx( ITEM_TYPE_PERMANENT, 1 ), 100 )
set itemID = RandomDistChoose( )
if (trigUnit != null) then
call UnitDropItem( trigUnit, itemID )
else
call WidgetDropItem( trigWidget, itemID )
endif
endif
set bj_lastDyingWidget = null
call DestroyTrigger(GetTriggeringTrigger())
endfunction
function Unit000078_DropItems takes nothing returns nothing
local widget trigWidget = null
local unit trigUnit = null
local integer itemID = 0
local boolean canDrop = true
set trigWidget = bj_lastDyingWidget
if (trigWidget == null) then
set trigUnit = GetTriggerUnit()
endif
if (trigUnit != null) then
set canDrop = not IsUnitHidden(trigUnit)
if (canDrop and GetChangingUnit() != null) then
set canDrop = (GetChangingUnitPrevOwner() == Player(PLAYER_NEUTRAL_AGGRESSIVE))
endif
endif
if (canDrop) then
// Item set 0
call RandomDistReset( )
call RandomDistAddItem( ChooseRandomItemEx( ITEM_TYPE_PERMANENT, 1 ), 100 )
set itemID = RandomDistChoose( )
if (trigUnit != null) then
call UnitDropItem( trigUnit, itemID )
else
call WidgetDropItem( trigWidget, itemID )
endif
endif
set bj_lastDyingWidget = null
call DestroyTrigger(GetTriggeringTrigger())
endfunction
function Unit000084_DropItems takes nothing returns nothing
local widget trigWidget = null
local unit trigUnit = null
local integer itemID = 0
local boolean canDrop = true
set trigWidget = bj_lastDyingWidget
if (trigWidget == null) then
set trigUnit = GetTriggerUnit()
endif
if (trigUnit != null) then
set canDrop = not IsUnitHidden(trigUnit)
if (canDrop and GetChangingUnit() != null) then
set canDrop = (GetChangingUnitPrevOwner() == Player(PLAYER_NEUTRAL_AGGRESSIVE))
endif
endif
if (canDrop) then
// Item set 0
call RandomDistReset( )
call RandomDistAddItem( ChooseRandomItemEx( ITEM_TYPE_CHARGED, 2 ), 100 )
set itemID = RandomDistChoose( )
if (trigUnit != null) then
call UnitDropItem( trigUnit, itemID )
else
call WidgetDropItem( trigWidget, itemID )
endif
// Item set 1
call RandomDistReset( )
call RandomDistAddItem( ChooseRandomItemEx( ITEM_TYPE_POWERUP, 1 ), 100 )
set itemID = RandomDistChoose( )
if (trigUnit != null) then
call UnitDropItem( trigUnit, itemID )
else
call WidgetDropItem( trigWidget, itemID )
endif
endif
set bj_lastDyingWidget = null
call DestroyTrigger(GetTriggeringTrigger())
endfunction
function Unit000087_DropItems takes nothing returns nothing
local widget trigWidget = null
local unit trigUnit = null
local integer itemID = 0
local boolean canDrop = true
set trigWidget = bj_lastDyingWidget
if (trigWidget == null) then
set trigUnit = GetTriggerUnit()
endif
if (trigUnit != null) then
set canDrop = not IsUnitHidden(trigUnit)
if (canDrop and GetChangingUnit() != null) then
set canDrop = (GetChangingUnitPrevOwner() == Player(PLAYER_NEUTRAL_AGGRESSIVE))
endif
endif
if (canDrop) then
// Item set 0
call RandomDistReset( )
call RandomDistAddItem( ChooseRandomItemEx( ITEM_TYPE_PERMANENT, 1 ), 100 )
set itemID = RandomDistChoose( )
if (trigUnit != null) then
call UnitDropItem( trigUnit, itemID )
else
call WidgetDropItem( trigWidget, itemID )
endif
endif
set bj_lastDyingWidget = null
call DestroyTrigger(GetTriggeringTrigger())
endfunction
//***************************************************************************
//*
//* Unit Creation
//*
//***************************************************************************
//===========================================================================
function CreateNeutralHostile takes nothing returns nothing
local player p = Player(PLAYER_NEUTRAL_AGGRESSIVE)
local unit u
local integer unitID
local trigger t
local real life
set u = CreateUnit( p, 'nkot', -21.8, -5279.9, 119.087 )
call SetUnitAcquireRange( u, 200.0 )
set t = CreateTrigger( )
call TriggerRegisterUnitEvent( t, u, EVENT_UNIT_DEATH )
call TriggerRegisterUnitEvent( t, u, EVENT_UNIT_CHANGE_OWNER )
call TriggerAddAction( t, function Unit000015_DropItems )
set u = CreateUnit( p, 'nkob', -147.8, -5293.0, 106.136 )
call SetUnitAcquireRange( u, 200.0 )
set u = CreateUnit( p, 'nkob', 72.3, -5184.0, 133.033 )
call SetUnitAcquireRange( u, 200.0 )
set u = CreateUnit( p, 'nkot', -256.2, 4663.8, 291.705 )
call SetUnitAcquireRange( u, 200.0 )
set t = CreateTrigger( )
call TriggerRegisterUnitEvent( t, u, EVENT_UNIT_DEATH )
call TriggerRegisterUnitEvent( t, u, EVENT_UNIT_CHANGE_OWNER )
call TriggerAddAction( t, function Unit000018_DropItems )
set u = CreateUnit( p, 'nkob', -371.4, 4716.6, 306.763 )
call SetUnitAcquireRange( u, 200.0 )
set u = CreateUnit( p, 'nkob', -126.4, 4698.3, 260.185 )
call SetUnitAcquireRange( u, 200.0 )
set u = CreateUnit( p, 'nwzg', 4551.8, -4770.4, 203.110 )
call SetUnitState( u, UNIT_STATE_MANA, 0 )
call SetUnitAcquireRange( u, 200.0 )
set t = CreateTrigger( )
call TriggerRegisterUnitEvent( t, u, EVENT_UNIT_DEATH )
call TriggerRegisterUnitEvent( t, u, EVENT_UNIT_CHANGE_OWNER )
call TriggerAddAction( t, function Unit000021_DropItems )
set u = CreateUnit( p, 'nrog', 4551.2, -4944.0, 166.440 )
call SetUnitAcquireRange( u, 200.0 )
set t = CreateTrigger( )
call TriggerRegisterUnitEvent( t, u, EVENT_UNIT_DEATH )
call TriggerRegisterUnitEvent( t, u, EVENT_UNIT_CHANGE_OWNER )
call TriggerAddAction( t, function Unit000022_DropItems )
set u = CreateUnit( p, 'nrog', 4547.5, -4605.6, 227.156 )
call SetUnitAcquireRange( u, 200.0 )
set u = CreateUnit( p, 'nwzg', -4443.9, 4402.4, 359.305 )
call SetUnitState( u, UNIT_STATE_MANA, 0 )
call SetUnitAcquireRange( u, 200.0 )
set t = CreateTrigger( )
call TriggerRegisterUnitEvent( t, u, EVENT_UNIT_DEATH )
call TriggerRegisterUnitEvent( t, u, EVENT_UNIT_CHANGE_OWNER )
call TriggerAddAction( t, function Unit000024_DropItems )
set u = CreateUnit( p, 'nrog', -4444.6, 4228.9, 24.344 )
call SetUnitAcquireRange( u, 200.0 )
set t = CreateTrigger( )
call TriggerRegisterUnitEvent( t, u, EVENT_UNIT_DEATH )
call TriggerRegisterUnitEvent( t, u, EVENT_UNIT_CHANGE_OWNER )
call TriggerAddAction( t, function Unit000025_DropItems )
set u = CreateUnit( p, 'nrog', -4448.2, 4567.2, 335.827 )
call SetUnitAcquireRange( u, 200.0 )
set u = CreateUnit( p, 'nftr', 1795.9, -5095.8, 129.902 )
call SetUnitAcquireRange( u, 200.0 )
set u = CreateUnit( p, 'nftr', 1382.4, -5102.7, 95.950 )
call SetUnitAcquireRange( u, 200.0 )
set u = CreateUnit( p, 'nftr', 1819.1, -4981.9, 141.410 )
call SetUnitAcquireRange( u, 200.0 )
set u = CreateUnit( p, 'nfsp', 1587.8, -4996.6, 115.882 )
call SetUnitState( u, UNIT_STATE_MANA, 0 )
call SetUnitAcquireRange( u, 200.0 )
set u = CreateUnit( p, 'nsqt', 1497.7, -4910.3, 101.491 )
call SetUnitAcquireRange( u, 200.0 )
set t = CreateTrigger( )
call TriggerRegisterUnitEvent( t, u, EVENT_UNIT_DEATH )
call TriggerRegisterUnitEvent( t, u, EVENT_UNIT_CHANGE_OWNER )
call TriggerAddAction( t, function Unit000084_DropItems )
set u = CreateUnit( p, 'nwiz', 3006.7, -5007.9, 34.696 )
call SetUnitAcquireRange( u, 200.0 )
set u = CreateUnit( p, 'nwzg', 301.5, 2219.1, 138.380 )
set t = CreateTrigger( )
call TriggerRegisterUnitEvent( t, u, EVENT_UNIT_DEATH )
call TriggerRegisterUnitEvent( t, u, EVENT_UNIT_CHANGE_OWNER )
call TriggerAddAction( t, function Unit000033_DropItems )
set u = CreateUnit( p, 'nenf', 140.9, 2084.0, 120.120 )
set t = CreateTrigger( )
call TriggerRegisterUnitEvent( t, u, EVENT_UNIT_DEATH )
call TriggerRegisterUnitEvent( t, u, EVENT_UNIT_CHANGE_OWNER )
call TriggerAddAction( t, function Unit000034_DropItems )
set u = CreateUnit( p, 'nenf', 351.5, 2438.3, 152.894 )
set u = CreateUnit( p, 'nbrg', 292.0, 1994.3, 125.337 )
set u = CreateUnit( p, 'nbrg', 487.2, 2337.3, 151.028 )
set u = CreateUnit( p, 'nwzg', -606.3, -3127.7, 297.070 )
set t = CreateTrigger( )
call TriggerRegisterUnitEvent( t, u, EVENT_UNIT_DEATH )
call TriggerRegisterUnitEvent( t, u, EVENT_UNIT_CHANGE_OWNER )
call TriggerAddAction( t, function Unit000038_DropItems )
set u = CreateUnit( p, 'nenf', -442.5, -3023.2, 278.810 )
set t = CreateTrigger( )
call TriggerRegisterUnitEvent( t, u, EVENT_UNIT_DEATH )
call TriggerRegisterUnitEvent( t, u, EVENT_UNIT_CHANGE_OWNER )
call TriggerAddAction( t, function Unit000039_DropItems )
set u = CreateUnit( p, 'nenf', -757.8, -3247.2, 311.584 )
set u = CreateUnit( p, 'nbrg', -550.6, -2884.9, 284.026 )
set u = CreateUnit( p, 'nbrg', -904.0, -3150.6, 309.717 )
set u = CreateUnit( p, 'nkol', -4476.2, -925.1, 318.360 )
call SetUnitAcquireRange( u, 200.0 )
set t = CreateTrigger( )
call TriggerRegisterUnitEvent( t, u, EVENT_UNIT_DEATH )
call TriggerRegisterUnitEvent( t, u, EVENT_UNIT_CHANGE_OWNER )
call TriggerAddAction( t, function Unit000043_DropItems )
set u = CreateUnit( p, 'nkog', -4699.8, -990.4, 340.140 )
call SetUnitState( u, UNIT_STATE_MANA, 0 )
call SetUnitAcquireRange( u, 200.0 )
set t = CreateTrigger( )
call TriggerRegisterUnitEvent( t, u, EVENT_UNIT_DEATH )
call TriggerRegisterUnitEvent( t, u, EVENT_UNIT_CHANGE_OWNER )
call TriggerAddAction( t, function Unit000044_DropItems )
set u = CreateUnit( p, 'nkog', -4381.6, -747.4, 293.253 )
call SetUnitState( u, UNIT_STATE_MANA, 0 )
call SetUnitAcquireRange( u, 200.0 )
set u = CreateUnit( p, 'ngrk', -4567.6, -1076.3, 345.548 )
call SetUnitState( u, UNIT_STATE_MANA, 0 )
call SetUnitAcquireRange( u, 200.0 )
set u = CreateUnit( p, 'ngrk', -4349.0, -918.8, 300.637 )
call SetUnitState( u, UNIT_STATE_MANA, 0 )
call SetUnitAcquireRange( u, 200.0 )
set u = CreateUnit( p, 'nkol', 4464.3, 346.0, 138.360 )
call SetUnitAcquireRange( u, 200.0 )
set t = CreateTrigger( )
call TriggerRegisterUnitEvent( t, u, EVENT_UNIT_DEATH )
call TriggerRegisterUnitEvent( t, u, EVENT_UNIT_CHANGE_OWNER )
call TriggerAddAction( t, function Unit000048_DropItems )
set u = CreateUnit( p, 'nkog', 4687.9, 411.3, 160.140 )
call SetUnitState( u, UNIT_STATE_MANA, 0 )
call SetUnitAcquireRange( u, 200.0 )
set t = CreateTrigger( )
call TriggerRegisterUnitEvent( t, u, EVENT_UNIT_DEATH )
call TriggerRegisterUnitEvent( t, u, EVENT_UNIT_CHANGE_OWNER )
call TriggerAddAction( t, function Unit000049_DropItems )
set u = CreateUnit( p, 'nkog', 4369.7, 168.3, 113.253 )
call SetUnitState( u, UNIT_STATE_MANA, 0 )
call SetUnitAcquireRange( u, 200.0 )
set u = CreateUnit( p, 'ngrk', 4555.6, 497.2, 165.548 )
call SetUnitState( u, UNIT_STATE_MANA, 0 )
call SetUnitAcquireRange( u, 200.0 )
set u = CreateUnit( p, 'ngrk', 4337.0, 339.7, 120.637 )
call SetUnitState( u, UNIT_STATE_MANA, 0 )
call SetUnitAcquireRange( u, 200.0 )
set u = CreateUnit( p, 'nass', 4189.6, 4143.1, 211.390 )
set t = CreateTrigger( )
call TriggerRegisterUnitEvent( t, u, EVENT_UNIT_DEATH )
call TriggerRegisterUnitEvent( t, u, EVENT_UNIT_CHANGE_OWNER )
call TriggerAddAction( t, function Unit000055_DropItems )
set u = CreateUnit( p, 'nwiz', 4092.1, 4331.7, 239.425 )
set u = CreateUnit( p, 'nwiz', 4340.3, 4090.7, 194.918 )
set u = CreateUnit( p, 'nban', 4008.9, 4224.8, 238.044 )
set u = CreateUnit( p, 'nban', 4216.3, 3988.8, 185.357 )
set u = CreateUnit( p, 'nwiz', -4571.3, -4512.7, 29.694 )
set u = CreateUnit( p, 'nwiz', -4313.5, -4743.3, 62.318 )
set u = CreateUnit( p, 'nass', -4418.7, -4558.9, 42.422 )
set t = CreateTrigger( )
call TriggerRegisterUnitEvent( t, u, EVENT_UNIT_DEATH )
call TriggerRegisterUnitEvent( t, u, EVENT_UNIT_CHANGE_OWNER )
call TriggerAddAction( t, function Unit000060_DropItems )
set u = CreateUnit( p, 'nban', -4234.8, -4633.1, 64.554 )
set u = CreateUnit( p, 'nban', -4451.6, -4405.8, 25.565 )
set u = CreateUnit( p, 'nkog', 247.9, -1803.5, 94.954 )
call SetUnitState( u, UNIT_STATE_MANA, 0 )
call SetUnitAcquireRange( u, 200.0 )
set t = CreateTrigger( )
call TriggerRegisterUnitEvent( t, u, EVENT_UNIT_DEATH )
call TriggerRegisterUnitEvent( t, u, EVENT_UNIT_CHANGE_OWNER )
call TriggerAddAction( t, function Unit000063_DropItems )
set u = CreateUnit( p, 'nkob', 101.0, -1766.8, 77.577 )
call SetUnitAcquireRange( u, 200.0 )
set u = CreateUnit( p, 'nkob', 403.3, -1724.9, 115.048 )
call SetUnitAcquireRange( u, 200.0 )
set u = CreateUnit( p, 'nkog', -719.0, 799.6, 313.978 )
call SetUnitState( u, UNIT_STATE_MANA, 0 )
call SetUnitAcquireRange( u, 200.0 )
set t = CreateTrigger( )
call TriggerRegisterUnitEvent( t, u, EVENT_UNIT_DEATH )
call TriggerRegisterUnitEvent( t, u, EVENT_UNIT_CHANGE_OWNER )
call TriggerAddAction( t, function Unit000066_DropItems )
set u = CreateUnit( p, 'nkob', -832.9, 679.5, 329.964 )
call SetUnitAcquireRange( u, 200.0 )
set u = CreateUnit( p, 'nkob', -571.2, 721.9, 286.804 )
call SetUnitAcquireRange( u, 200.0 )
set u = CreateUnit( p, 'nwzr', -3455.1, -2573.0, 315.980 )
call SetUnitState( u, UNIT_STATE_MANA, 0 )
call SetUnitAcquireRange( u, 200.0 )
set t = CreateTrigger( )
call TriggerRegisterUnitEvent( t, u, EVENT_UNIT_DEATH )
call TriggerRegisterUnitEvent( t, u, EVENT_UNIT_CHANGE_OWNER )
call TriggerAddAction( t, function Unit000069_DropItems )
set u = CreateUnit( p, 'nwiz', -3559.3, -2655.4, 340.475 )
call SetUnitAcquireRange( u, 200.0 )
set u = CreateUnit( p, 'nwiz', -3418.3, -2406.1, 291.552 )
call SetUnitAcquireRange( u, 200.0 )
set u = CreateUnit( p, 'nwzr', 2775.4, 1602.1, 139.581 )
call SetUnitState( u, UNIT_STATE_MANA, 0 )
call SetUnitAcquireRange( u, 200.0 )
set t = CreateTrigger( )
call TriggerRegisterUnitEvent( t, u, EVENT_UNIT_DEATH )
call TriggerRegisterUnitEvent( t, u, EVENT_UNIT_CHANGE_OWNER )
call TriggerAddAction( t, function Unit000072_DropItems )
set u = CreateUnit( p, 'nwiz', 2671.1, 1519.8, 126.255 )
call SetUnitAcquireRange( u, 200.0 )
set u = CreateUnit( p, 'nwiz', 2812.1, 1769.1, 156.516 )
call SetUnitAcquireRange( u, 200.0 )
set u = CreateUnit( p, 'nmrm', 5055.2, 2393.2, 176.310 )
call SetUnitAcquireRange( u, 200.0 )
set t = CreateTrigger( )
call TriggerRegisterUnitEvent( t, u, EVENT_UNIT_DEATH )
call TriggerRegisterUnitEvent( t, u, EVENT_UNIT_CHANGE_OWNER )
call TriggerAddAction( t, function Unit000075_DropItems )
set u = CreateUnit( p, 'nmrr', 4923.6, 2527.9, 190.169 )
call SetUnitAcquireRange( u, 200.0 )
set u = CreateUnit( p, 'nmrr', 4908.0, 2254.1, 160.165 )
call SetUnitAcquireRange( u, 200.0 )
set u = CreateUnit( p, 'nmrm', -5164.0, -3390.4, 23.567 )
call SetUnitAcquireRange( u, 200.0 )
set t = CreateTrigger( )
call TriggerRegisterUnitEvent( t, u, EVENT_UNIT_DEATH )
call TriggerRegisterUnitEvent( t, u, EVENT_UNIT_CHANGE_OWNER )
call TriggerAddAction( t, function Unit000078_DropItems )
set u = CreateUnit( p, 'nmrr', -4996.2, -3310.6, 37.426 )
call SetUnitAcquireRange( u, 200.0 )
set u = CreateUnit( p, 'nmrr', -5143.9, -3149.0, 7.422 )
call SetUnitAcquireRange( u, 200.0 )
set u = CreateUnit( p, 'nwiz', 3203.6, -5000.8, 72.973 )
call SetUnitAcquireRange( u, 200.0 )
set u = CreateUnit( p, 'nwiz', 3108.3, -5102.7, 19.480 )
call SetUnitAcquireRange( u, 200.0 )
set t = CreateTrigger( )
call TriggerRegisterUnitEvent( t, u, EVENT_UNIT_DEATH )
call TriggerRegisterUnitEvent( t, u, EVENT_UNIT_CHANGE_OWNER )
call TriggerAddAction( t, function Unit000087_DropItems )
set u = CreateUnit( p, 'nwiz', -2958.5, 4397.3, 214.696 )
call SetUnitAcquireRange( u, 200.0 )
set u = CreateUnit( p, 'nwiz', -3264.0, 4424.7, 252.973 )
call SetUnitAcquireRange( u, 200.0 )
set u = CreateUnit( p, 'nsqt', -1508.4, 4324.3, 281.491 )
call SetUnitAcquireRange( u, 200.0 )
set t = CreateTrigger( )
call TriggerRegisterUnitEvent( t, u, EVENT_UNIT_DEATH )
call TriggerRegisterUnitEvent( t, u, EVENT_UNIT_CHANGE_OWNER )
call TriggerAddAction( t, function Unit000032_DropItems )
set u = CreateUnit( p, 'nfsp', -1598.5, 4410.6, 295.882 )
call SetUnitState( u, UNIT_STATE_MANA, 0 )
call SetUnitAcquireRange( u, 200.0 )
set u = CreateUnit( p, 'nftr', -1829.8, 4395.9, 321.410 )
call SetUnitAcquireRange( u, 200.0 )
set u = CreateUnit( p, 'nftr', -1393.1, 4516.8, 275.950 )
call SetUnitAcquireRange( u, 200.0 )
set u = CreateUnit( p, 'nftr', -1806.6, 4509.8, 309.902 )
call SetUnitAcquireRange( u, 200.0 )
set u = CreateUnit( p, 'nwiz', -3121.1, 4376.6, 199.480 )
call SetUnitAcquireRange( u, 200.0 )
set t = CreateTrigger( )
call TriggerRegisterUnitEvent( t, u, EVENT_UNIT_DEATH )
call TriggerRegisterUnitEvent( t, u, EVENT_UNIT_CHANGE_OWNER )
call TriggerAddAction( t, function Unit000012_DropItems )
endfunction
//===========================================================================
function CreateNeutralPassiveBuildings takes nothing returns nothing
local player p = Player(PLAYER_NEUTRAL_PASSIVE)
local unit u
local integer unitID
local trigger t
local real life
set u = CreateUnit( p, 'ngol', -4544.0, -4864.0, 270.000 )
call SetResourceAmount( u, 12500 )
set u = CreateUnit( p, 'ngol', 4736.0, -2560.0, 270.000 )
call SetResourceAmount( u, 12500 )
set u = CreateUnit( p, 'ngol', -4800.0, 2048.0, 270.000 )
call SetResourceAmount( u, 12500 )
set u = CreateUnit( p, 'ngol', 4416.0, 4352.0, 270.000 )
call SetResourceAmount( u, 12500 )
set u = CreateUnit( p, 'ngol', 512.0, 2048.0, 270.000 )
call SetResourceAmount( u, 12500 )
set u = CreateUnit( p, 'ngol', -768.0, -2944.0, 270.000 )
call SetResourceAmount( u, 12500 )
set u = CreateUnit( p, 'ntav', -256.0, -576.0, 270.000 )
call SetUnitColor( u, ConvertPlayerColor(0) )
set u = CreateUnit( p, 'ngme', -1600.0, 4608.0, 270.000 )
set u = CreateUnit( p, 'ngme', 1600.0, -5248.0, 270.000 )
set u = CreateUnit( p, 'nmer', -4672.0, -704.0, 270.000 )
call SetUnitColor( u, ConvertPlayerColor(0) )
set u = CreateUnit( p, 'ngad', 4864.0, -4864.0, 270.000 )
set u = CreateUnit( p, 'ngad', -4736.0, 4480.0, 270.000 )
set u = CreateUnit( p, 'nmer', 4672.0, 128.0, 270.000 )
call SetUnitColor( u, ConvertPlayerColor(0) )
endfunction
//===========================================================================
function CreatePlayerBuildings takes nothing returns nothing
endfunction
//===========================================================================
function CreatePlayerUnits takes nothing returns nothing
endfunction
//===========================================================================
function CreateAllUnits takes nothing returns nothing
call CreateNeutralPassiveBuildings( )
call CreatePlayerBuildings( )
call CreateNeutralHostile( )
call CreatePlayerUnits( )
endfunction
//***************************************************************************
//*
//* Custom Script Code
//*
//***************************************************************************
//TESH.scrollpos=0
//TESH.alwaysfold=0
//***************************************************************************
//*
//* Triggers
//*
//***************************************************************************
//===========================================================================
// Trigger: Custom Initialization
//
// Default melee game initialization for all players
//===========================================================================
//TESH.scrollpos=-1
//TESH.alwaysfold=0
void CustomGrantItemsToHero (unit whichUnit){
integer owner = GetPlayerId(GetOwningPlayer(whichUnit))
if (bj_meleeTwinkedHeroes[owner] < bj_MELEE_MAX_TWINKED_HEROES) then
if GetUnitRace(whichUnit)==RACE_HUMAN then
UnitAddItemById(whichUnit, 'mcri');UnitAddItemById(whichUnit, 'stwp')
elseif GetUnitRace(whichUnit)==RACE_NIGHTELF then
UnitAddItemById(whichUnit, 'moon');UnitAddItemById(whichUnit, 'stwp')
elseif GetUnitRace(whichUnit)==RACE_UNDEAD then
UnitAddItemById(whichUnit, 'skul');UnitAddItemById(whichUnit, 'stwp')
elseif GetUnitRace(whichUnit)==RACE_ORC then
UnitAddItemById(whichUnit, 'shas');UnitAddItemById(whichUnit, 'stwp')
else;UnitAddItemById(whichUnit, 'I001');UnitAddItemById(whichUnit, 'tret')
endif;set bj_meleeTwinkedHeroes[owner] = bj_meleeTwinkedHeroes[owner] + 1;endif}
void CustomGrantItemsToTrainedHero(){CustomGrantItemsToHero(GetTrainedUnit())}
void CustomGrantItemsToHiredHero(){CustomGrantItemsToHero(GetSoldUnit())}
void CustomGrantHeroItems(){integer index;trigger trig;index = 0;loop;bj_meleeTwinkedHeroes[index] = 0
index = index + 1;exitwhen index == bj_MAX_PLAYER_SLOTS;endloop;index = 0;loop
trig = CreateTrigger();TriggerRegisterPlayerUnitEvent(trig, Player(index), EVENT_PLAYER_UNIT_TRAIN_FINISH, filterMeleeTrainedUnitIsHeroBJ)
TriggerAddAction(trig, function CustomGrantItemsToTrainedHero);index = index + 1;exitwhen index == bj_MAX_PLAYERS
endloop;trig = CreateTrigger();TriggerRegisterPlayerUnitEvent(trig, Player(PLAYER_NEUTRAL_PASSIVE), EVENT_PLAYER_UNIT_SELL, filterMeleeTrainedUnitIsHeroBJ)
TriggerAddAction(trig, function CustomGrantItemsToHiredHero);bj_meleeGrantHeroItems = true}
unit CustomRandomHeroLoc(player p, integer id1, integer id2, integer id3, integer id4, integer id5, location loc){
unit hero = null;integer roll,pick;version v;v = VersionGet();if (v == VERSION_REIGN_OF_CHAOS) then
roll = GetRandomInt(1,3);else;roll = GetRandomInt(1,5);endif;if roll == 1 then;pick = id1
elseif roll == 2 then;pick = id2;elseif roll == 3 then;pick = id3;elseif roll == 4 then
pick = id4;elseif roll == 5 then;pick = id5;else;pick = id1;endif;hero = CreateUnitAtLoc(p, pick, loc, bj_UNIT_FACING)
if bj_meleeGrantHeroItems then;MeleeGrantItemsToHero(hero);endif;return hero}
void CustomStartingUnitsHuman(player whichPlayer, location startLoc, boolean doHeroes, boolean doCamera, boolean doPreload)
{boolean useRandomHero = IsMapFlagSet(MAP_RANDOM_HERO)
real unitSpacing = 64.00;unit nearestMine,townHall = null;location nearMineLoc,heroLoc
real peonX,peonY;if (doPreload) then;Preloader( "scripts\\HumanMelee.pld" );endif
nearestMine = MeleeFindNearestMine(startLoc, bj_MELEE_MINE_SEARCH_RADIUS)
if(nearestMine!=null)then;townHall=CreateUnitAtLoc(whichPlayer,'htow',startLoc,bj_UNIT_FACING)
nearMineLoc = MeleeGetProjectedLoc(GetUnitLoc(nearestMine), startLoc, 320, 0)
peonX = GetLocationX(nearMineLoc);peonY = GetLocationY(nearMineLoc)
CreateUnit(whichPlayer, 'hpea', peonX + 0.00 * unitSpacing, peonY + 1.00 * unitSpacing, bj_UNIT_FACING)
CreateUnit(whichPlayer, 'hpea', peonX + 1.00 * unitSpacing, peonY + 0.15 * unitSpacing, bj_UNIT_FACING)
CreateUnit(whichPlayer, 'hpea', peonX - 1.00 * unitSpacing, peonY + 0.15 * unitSpacing, bj_UNIT_FACING)
CreateUnit(whichPlayer, 'hpea', peonX + 0.60 * unitSpacing, peonY - 1.00 * unitSpacing, bj_UNIT_FACING)
CreateUnit(whichPlayer, 'hpea', peonX - 0.60 * unitSpacing, peonY - 1.00 * unitSpacing, bj_UNIT_FACING)
heroLoc = MeleeGetProjectedLoc(GetUnitLoc(nearestMine), startLoc, 384, 45);else;
townHall = CreateUnitAtLoc(whichPlayer, 'htow', startLoc, bj_UNIT_FACING)
peonX = GetLocationX(startLoc);peonY = GetLocationY(startLoc) - 224.00
CreateUnit(whichPlayer, 'hpea', peonX + 2.00 * unitSpacing, peonY + 0.00 * unitSpacing, bj_UNIT_FACING)
CreateUnit(whichPlayer, 'hpea', peonX + 1.00 * unitSpacing, peonY + 0.00 * unitSpacing, bj_UNIT_FACING)
CreateUnit(whichPlayer, 'hpea', peonX + 0.00 * unitSpacing, peonY + 0.00 * unitSpacing, bj_UNIT_FACING)
CreateUnit(whichPlayer, 'hpea', peonX - 1.00 * unitSpacing, peonY + 0.00 * unitSpacing, bj_UNIT_FACING)
CreateUnit(whichPlayer, 'hpea', peonX - 2.00 * unitSpacing, peonY + 0.00 * unitSpacing, bj_UNIT_FACING)
heroLoc = Location(peonX, peonY - 2.00 * unitSpacing);endif;if (townHall != null) then
UnitAddAbilityBJ('Amic', townHall);UnitMakeAbilityPermanentBJ(true, 'Amic', townHall);endif
if (doHeroes) then;if useRandomHero then
CustomRandomHeroLoc(whichPlayer, 'Hamg', 'Hmkg', 'Hpal', 'Hblm', 'E007', heroLoc);else
SetPlayerState(whichPlayer, PLAYER_STATE_RESOURCE_HERO_TOKENS, bj_MELEE_STARTING_HERO_TOKENS)
endif;endif;if (doCamera) then;SetCameraPositionForPlayer(whichPlayer, peonX, peonY)
SetCameraQuickPositionForPlayer(whichPlayer, peonX, peonY);endif}
void CustomStartingUnits(){integer index;player indexPlayer;location indexStartLoc
race indexRace;Preloader( "scripts\\SharedMelee.pld" );index = 0;loop;
indexPlayer = Player(index);if (GetPlayerSlotState(indexPlayer) == PLAYER_SLOT_STATE_PLAYING) then
indexStartLoc = GetStartLocationLoc(GetPlayerStartLocation(indexPlayer));indexRace = GetPlayerRace(indexPlayer)
if (indexRace == RACE_HUMAN) then;CustomStartingUnitsHuman(indexPlayer, indexStartLoc, true, true, true)
elseif (indexRace == RACE_ORC) then;MeleeStartingUnitsOrc(indexPlayer, indexStartLoc, true, true, true)
elseif (indexRace == RACE_UNDEAD) then;MeleeStartingUnitsUndead(indexPlayer, indexStartLoc, true, true, true)
elseif (indexRace == RACE_NIGHTELF) then;MeleeStartingUnitsNightElf(indexPlayer, indexStartLoc, true, true, true)
else;MeleeStartingUnitsUnknownRace(indexPlayer, indexStartLoc, true, true, true);endif;endif
set index = index + 1;exitwhen index == bj_MAX_PLAYERS;endloop}
void Trig_Custom_Initialization_Actions(){MeleeStartingVisibility();MeleeStartingHeroLimit()
CustomGrantHeroItems();MeleeStartingResources();MeleeClearExcessUnits();CustomStartingUnits()
MeleeStartingAI();MeleeInitVictoryDefeat()}
//==
void InitTrig_Custom_Initialization(){gg_trg_Custom_Initialization=CreateTrigger()
TriggerAddAction( gg_trg_Custom_Initialization, function Trig_Custom_Initialization_Actions )}
//===========================================================================
// Trigger: paladin
//===========================================================================
//TESH.scrollpos=-1
//TESH.alwaysfold=0
//'AIpr'
scope shieldpala initializer I
struct divineShield; unit x; integer y
private method onTimedLoop takes nothing returns boolean
y++;if y>=160 then//160 is 4 seconds
SetUnitInvulnerable(x,false);return false; endif;SetUnitInvulnerable(x,true); return true; endmethod
implement TimedLoop
static method create takes unit u returns divineShield
local divineShield m= divineShield.allocate()
set m.x = u;set m.y=0
call m.startTimedLoop()
return m
endmethod
endstruct
private function Actions takes nothing returns boolean;call divineShield.create(GetSpellTargetUnit());return false;endfunction
private void I (){effectstartGT(Actions, 'AIpr')};endscope
//===========================================================================
// Trigger: timerloops
//===========================================================================
//TESH.scrollpos=108
//TESH.alwaysfold=0
library TimedLoop
// *******************************************************
// TimedLoop
// ---------
//
// Requires jasshelper 0.9.G.1 or greater.
//
// A library + module that are meant to make those
// array + timer loops easy, yet still faster than
// other alternatives meant to be easy (In other words
// no TriggerEvaluate is involved).
//
// The OOPness is interesting.
//
// Before implementing TimedLoop
// your struct needs an onTimedLoop method that takes
// nothing and returns boolean, if the method
// returns false, the instance will get removed
// from the loop and destroyed, else it will continue,
// think of it as if the call asks the method a
// question: "Should I continue the loop afterwards?"
//
// Alternatively, if you are not convinced, you may
// use the TimedLoop_CONTINUE and TimedLoop_STOP
// constants in the method's returns.
//
// After implementing TimedLoop, you can call
// the startTimedLoop method to add the periodic event
// to that instance, only call it once per instance.
//
// I recommend to call implement just bellow the
// declaration of the onLoop method, else it will
// actually use TriggerEvaluate, which is lame. Remind
// me to implement a topsort in jasshelper.
//
// If you feel the need to destroy the struct outside
// the loop, well, you'll have to add a flag to it so
// you send a message to onLoop to make it return false.
// A more complicated module to allow that easily would
// come later.
//
// *******************************************************
//========================================================
// config:
globals
public constant real PERIOD = 0.025
// A lower value and everything using the module will
// look better, yet performance will drop.
endglobals
//========================================================
// implementation:
//
globals
public constant boolean STOP = false
public constant boolean CONTINUE = true
endglobals
//===========================
module TimedLoop
// god bless private module members.
//
private static thistype array V // The array
private static integer N = 0 // The count
private static timer T = null // the timer, one per
// struct that implements this
private static method onExpire takes nothing returns nothing
local integer n = 0
local thistype this // yay for odd-sounding syntax constructs
local integer i = 0
loop
exitwhen (i== thistype.N)
set this = .V[i]
if ( this.onTimedLoop() == CONTINUE ) then
set .V[n] = this
set n=n+1
else
call this.destroy()
endif
set i=i+1
endloop
set thistype.N = n
if (n== 0) then
call PauseTimer(.T)
endif
endmethod
public method startTimedLoop takes nothing returns nothing
set .V[.N] = this
set .N=.N + 1
if (.N == 1) then
if (.T == null) then
set .T = CreateTimer()
endif
call TimerStart(.T, PERIOD, true, function thistype.onExpire)
endif
endmethod
endmodule
endlibrary
//example
/*struct moveUnit
unit u
//=====================================================
// You need to code an onTimedLoop method before
// implementing the module.
//
private method onTimedLoop takes nothing returns boolean
//instance's timer expired:
// This will just move a unit's x coordinate with
// a speed of 100 until it reaches 5000.0
call SetUnitX(u, GetUnitX(u) + 100.0* TimedLoop_PERIOD )
// notice the use of the TimedLoop_PERIOD constant
// since it may be tweaked by the user...
if ( GetUnitX(u) >= 5000) then
return TimedLoop_STOP
endif
return TimedLoop_CONTINUE
//You are free to/should use false and true instead of the
//constants.
endmethod
implement TimedLoop //This does the module magic
static method create takes unit u returns moveUnit
local moveUnit m= moveUnit.allocate()
set m.u = u
call m.startTimedLoop() //The module works by
// creating a startTimedLoop method that will
// do all the dirty work and end up calling
// .onTimedLoop...
//
return m
endmethod
endstruct
//call moveUnit.create(GetTriggerUnit()) and see...
*///===========================================================================
// Trigger: yojimbo
//===========================================================================
//TESH.scrollpos=-1
//TESH.alwaysfold=0
// Ice Trap by BRUTAL.
// Requires GT, and KT2.
// Credits are welcome but not necessary.
// October 12th 2009.
//
// Modified to be Fire Barrier for Valkyrie Hero by SanKakU
// My memories are a little fuzzy of the Xena episodes but
// from what i remember, Odin's top blonde valkyrie cursed
// Gabrielle by putting her in a fire trap much like this one.
// In further research it can be found that in the tv show
// Bleach, the Captain Commander Yamamoto uses an ability
// like this.
//
// the spell now enables countering of escape spells.
scope FireBarrier initializer I
define{private ID='A00E';private IMMO_ID='A00F';private DUMMY_ID='h000';;private PATH_BLOCK='YTpb'
private PERIOD=.04;private SCALE=1. ;private ALPHA=75 ;private MAX_UNITS=36;private DISTANCE=350.}
private struct Data;unit caster, target;real x, y;real angle;integer pbInt=0, ticks, maxTicks
destructable array pathBlock[MAX_UNITS];unit array a[MAX_UNITS]
static method create takes unit u, unit z returns Data
local Data data=Data.allocate()
set data.caster=u
set data.target=z
set data.x=GetUnitX(data.target)
set data.y=GetUnitY(data.target)
set data.angle=GetUnitFacing(u)+140
set data.ticks=R2I(45*(GetUnitAbilityLevel(data.caster,ID))/PERIOD)+10
set data.maxTicks=data.ticks
return data
endmethod
method circle takes nothing returns nothing
integer level=GetUnitAbilityLevel(.caster,ID)
real dis=DISTANCE
//==AS AN ULTIMATE, THIS SPELL LASTS 45 SECONDS AT LEVEL 1, 90 SECONDS AT LEVEL 2, AND 135 SECONDS AT LEVEL 3
real x=.x+dis*Cos(.angle*bj_DEGTORAD)
real y=.y+dis*Sin(.angle*bj_DEGTORAD)
.a[.pbInt]=CreateUnit(GetOwningPlayer(.caster),DUMMY_ID,x,y,bj_RADTODEG*Atan2(y-.y,x-.x))
call SetUnitScale(.a[pbInt],SCALE,SCALE,1.75)
call SetUnitVertexColor(.a[pbInt],255,255,255,R2I(2.55*ALPHA))
call UnitAddAbility(.a[pbInt],IMMO_ID)
call SetUnitAbilityLevel(.a[pbInt],IMMO_ID,level)
call IssueImmediateOrder(.a[pbInt],"immolation")
set .angle=.angle+360./MAX_UNITS
set .pathBlock[.pbInt]=CreateDestructable(PATH_BLOCK,x,y,0,1,0)
set .pbInt=.pbInt+1
endmethod
method end takes nothing returns nothing
integer i=-1;whilenot(i++>MAX_UNITS){RemoveUnit(.a[i]);KillDestructable(.pathBlock[i])};endmethod
endstruct
private function PeriodicFunc takes nothing returns boolean
local Data data=KT_GetData()
if getdisr(data.x,data.y,data.target)>=DISTANCE then
call SetUnitX(data.target,data.x)
call SetUnitY(data.target,data.y)
endif
set data.ticks=data.ticks-1
if data.ticks<=0 then
call data.end()
return true
else
if data.ticks>=data.maxTicks-MAX_UNITS then
call data.circle()
endif
return false
endif
endfunction
private function actions takes nothing returns nothing
call KT_Add(function PeriodicFunc,Data.create(GetTriggerUnit(),GetSpellTargetUnit()),PERIOD)
endfunction
private function I takes nothing returns nothing
XE_PreloadAbility(IMMO_ID)
call TriggerAddAction(GT_RegisterStartsEffectEvent(CreateTrigger(),ID),function actions)
endfunction
endscope
scope Cloudarchmage initializer I
private function f takes nothing returns boolean
location tl = GetSpellTargetLoc();real tx = GetLocationX(tl),ty = GetLocationY(tl)
unit ut = GetTriggerUnit(),u = CreateUnit(GetOwningPlayer(ut), 'e005', tx, ty, 270.00)
integer lvl = GetUnitAbilityLevel(ut,'A008')
UnitAddAbility(u, 'Aclf')
SetUnitAbilityLevel(u, 'Aclf', lvl)
IssuePointOrder(u, "cloudoffog", tx,ty)
UnitApplyTimedLife(u, 'BTLF', 20. )
RemoveLocation(tl);tl = null;u = null;ut = null;return false;endfunction
public function I takes nothing returns nothing
effectstartGT(f,'A008')
XE_PreloadAbility('Aclf')
endfunction
endscope
scope banishher initializer I;globals;private boolean ya=false;private integer za=0;endglobals
//define private {HEROABI = 'AOsf';DUMMABI = 'AHbn';TEMPABI = 'AHpx';DUMMID='e000';PURGABI='A006'}
struct banaaa;unit x,u;integer y,z
private method onTimedLoop takes nothing returns boolean;SetUnitX(u,gux(x));SetUnitY(u,guy(x));if ya==false then;KillUnit(u);
return false;endif;y++;if y>=1280 then;KillUnit(u);return false;else;y++;if y>=1200 then;if z>0 then;return true;endif;z++;
if ya==true then;ya=false;UnitRemoveAbility(x,'A001');UnitAddAbility(x, 'AOsf');SetUnitAbilityLevel(x, 'AOsf', za);
UnitAddAbility(u, 'A006');IssueTargetOrder(u, "purge", x);endif;else;;endif;endif;
return true;endmethod;implement TimedLoop ;static method create takes unit x returns banaaa
local banaaa m= banaaa.allocate();set m.x = x;set m.y=0;set m.z=0
m.u = CreateUnit(GetOwningPlayer(m.x), 'e004', gux(m.x), guy(m.x), 270.00)
UnitRemoveAbility(m.x,'AOsf');UnitAddAbility(m.x, 'A001');UnitAddAbility(m.u, 'AHbn');SetUnitAbilityLevel(m.u, 'AHbn', za)
IssueTargetOrder(m.u, "banish", m.x);ya=true;call m.startTimedLoop() ; return m;endmethod;endstruct
private boolean e(){unit u=CreateUnit(GetOwningPlayer(gtu), 'e004', gux(gtu), guy(gtu), 270.00)
;ya=false;UnitRemoveAbility(gtu,'A001');UnitAddAbility(gtu, 'AOsf');SetUnitAbilityLevel(gtu, 'AOsf', za);
UnitAddAbility(u, 'A006');IssueTargetOrder(u, "purge", gtu);UnitApplyTimedLife(u,'BTLF',2.);return false}
private boolean g (){za++;return false};private boolean Actions (){call banaaa.create(gtu);return false}
private void I (){effectstartGT(Actions, 'AOsf');effectstartGT(e, 'A001');skillGT(g,'AOsf')
call XE_PreloadAbility('A006');call XE_PreloadAbility('AHbn');XE_PreloadAbility('AOsf');XE_PreloadAbility('A001')};endscope
//
scope projectora initializer I;struct propur;unit x,d,p,t;integer y;real a,b
private method onTimedLoop takes nothing returns boolean;b=getdis(t,p);a=b-10.0
SetDistanceToUnit(t,p,a);if b<129.0 then;KillUnit(p);KillUnit(d);
UnitDamageTarget(x,t,100.0,false,false,ATTACK_TYPE_HERO,DAMAGE_TYPE_UNIVERSAL,WEAPON_TYPE_WHOKNOWS);return false;
endif;y++;if y>=400 then;KillUnit(p);KillUnit(d);return false;endif;SetUnitX(d,gux(p));SetUnitY(d,guy(p));
UnitAddAbility(d, 'A006');IssueTargetOrder(d, "purge", p);return true
endmethod;implement TimedLoop ;static method create takes unit x, unit w returns propur
local propur m= propur.allocate();set m.t = w;m.x = x;set m.y=0;m.a=0.0;m.b=0.0
m.d = CreateUnit(GetOwningPlayer(m.x), 'e004', gux(m.x), guy(m.x), 270.00)
m.p = CreateUnit(GetOwningPlayer(m.x), 'e006', gux(m.x), guy(m.x), 270.00)
call m.startTimedLoop() ; return m;endmethod;endstruct
private boolean Actions (){call propur.create(gtu,GetSpellTargetUnit());return false}
private void I (){effectstartGT(Actions, 'A009')};endscope
//
//function SetDistanceToUnit takes unit y, unit x, real dist returns nothing
//extension to snippet.
//function getdis takes unit x, unit y returns real
//
scope SpinBash initializer Init
// Spin Bash by The_Witcher
// The Blademaster spins the target around,
// damaging all enemies in range.
// After some time he releases his target, throwing it away.
globals
// the rawcode of your ability(press CTRL + D in object editor)
private constant integer SpellID = 'A0C5'
// the interval of the timer (increase if laggy)
private constant real interval = 0.01
// the distance between the target and the caster when
// spinnig around
private constant real SpinDistance = 150
// the curve is a constant used by the parabola forumla
private constant real Curve = 1.5
// this is the range in where units have to be around the target
// to get damaged
private constant real DamageRange = 80
endglobals
private function GetRotateTime takes integer lvl returns real
local real lowest = IMaxBJ(4-lvl,0)
local real highest = lowest + 2
return GetRandomReal(lowest,highest) // on lvl 1 between 4 and 6 seconds
endfunction
private function GetThrowDistance takes integer lvl returns real
return 200.*lvl //100 on lvl 1, 200 on lvl 2,...
endfunction
private function GetRotateSpeed takes integer lvl returns real
return 4.*lvl// +4 degree every interval
endfunction
private function GetSpinDamage takes integer lvl returns real
return 30.*lvl // every unit hit by the spinning/thrown unit takes this damage (here 30/60/90)
endfunction
private function GetTargetDamage takes integer lvl returns real
return 40.*lvl // the damage the target takes (here 40/80/120)
endfunction
//-----------Don't modify anything below this line---------
private struct data
unit u
unit v
real a
real d
real s
real maxd
integer lvl
integer mode = 1
real dmg1
real dmg2
group DamageOnceGroup
endstruct
globals
private data array DATAS
private integer total = 0
private timer tim = CreateTimer()
private group g = CreateGroup()
private item ite
private player TempPlayer
private data TempDat
endglobals
private function IsCoordPathable takes real x, real y returns boolean
local real xx
local real yy
call SetItemVisible(ite,true)
call SetItemPosition(ite,x,y)
set xx = GetItemX( ite ) - x
set yy = GetItemY( ite ) - y
call SetItemVisible(ite,false)
if xx < 1 and xx > -1 and yy < 1 and yy > -1 then
return true
endif
return false
endfunction
private function JumpParabola takes real dist, real maxdist, real curve returns real
local real t = (dist * 2) / maxdist - 1
return (- t * t + 1) * (maxdist / curve)
endfunction
private function EnemiesOnly takes nothing returns boolean
return IsUnitEnemy(GetFilterUnit(),TempPlayer) and not (IsUnitType(GetFilterUnit(),UNIT_TYPE_DEAD) or GetUnitTypeId(GetFilterUnit()) == 0 )
endfunction
private function Damage takes nothing returns nothing
if not IsUnitInGroup(GetEnumUnit(),TempDat.DamageOnceGroup) then
call UnitDamageTarget(TempDat.u,GetEnumUnit(),TempDat.dmg1,true,false,ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_WHOKNOWS)
call GroupAddUnit(TempDat.DamageOnceGroup,GetEnumUnit())
endif
endfunction
private function execute takes nothing returns nothing
local data dat
local integer i = 0
local real x
local real y
local unit u
loop
exitwhen i >= total
set dat = DATAS[i]
if dat.mode == 1 then
// Spinning around
set x = GetUnitX(dat.u) + SpinDistance * Cos(dat.a*bj_DEGTORAD)
set y = GetUnitY(dat.u) + SpinDistance * Sin(dat.a*bj_DEGTORAD)
call SetUnitX(dat.v,x)
call SetUnitY(dat.v,y)
call SetUnitFacing(dat.v,dat.a-180)
set dat.a = dat.a + dat.s
set dat.d = dat.d - interval
set TempPlayer = GetOwningPlayer(dat.u)
call GroupEnumUnitsInRange(g,GetUnitX(dat.v),GetUnitY(dat.v), DamageRange,Condition(function EnemiesOnly))
call GroupRemoveUnit(g,dat.v)
set TempDat = dat
call ForGroup(g, function Damage)
call GroupClear(g)
if dat.a > 360 then
set dat.a = dat.a - 360
call GroupClear(dat.DamageOnceGroup)
endif
if dat.d <= 0 then
set dat.d = 0
set dat.maxd = GetThrowDistance(dat.lvl)
set dat.mode = 2
call PauseUnit(dat.u,false)
call SetUnitAnimation(dat.u,"stand")
call GroupClear(dat.DamageOnceGroup)
endif
else
// throw
set x = GetUnitX(dat.v) + dat.s * Cos(dat.a*bj_DEGTORAD)
set y = GetUnitY(dat.v) + dat.s * Sin(dat.a*bj_DEGTORAD)
if IsCoordPathable(x,y) then
call SetUnitX(dat.v,x)
call SetUnitY(dat.v,y)
call GroupEnumUnitsInRange(g,GetUnitX(dat.v),GetUnitY(dat.v), DamageRange,Condition(function EnemiesOnly))
call GroupRemoveUnit(g,dat.v)
set TempDat = dat
call ForGroup(g, function Damage)
call GroupClear(g)
endif
set dat.d = dat.d + dat.s
if dat.mode == 3 then
call SetUnitFlyHeight(dat.v,JumpParabola(dat.d,dat.maxd,Curve),0)
else
call SetUnitFlyHeight(dat.v,JumpParabola(dat.d,dat.maxd,Curve*3),0)
endif
if dat.d >= dat.maxd and dat.mode == 2 then
set dat.d = 0
set dat.maxd = GetThrowDistance(dat.lvl) / 3
set dat.mode = 3
call GroupClear(dat.DamageOnceGroup)
call UnitDamageTarget(dat.u,dat.v,dat.dmg2,true,false,ATTACK_TYPE_NORMAL,DAMAGE_TYPE_NORMAL,WEAPON_TYPE_WHOKNOWS)
elseif dat.d >= dat.maxd and dat.mode == 3 then
call SetUnitFlyHeight(dat.v,0,0)
call PauseUnit(dat.v,false)
call SetUnitTimeScale(dat.v,1)
call DestroyGroup(dat.DamageOnceGroup)
set total = total - 1
set DATAS[i] = DATAS[total]
call dat.destroy()
set i = i - 1
endif
endif
set i = i + 1
endloop
if total == 0 then
call PauseTimer(tim)
endif
endfunction
private function start takes nothing returns boolean
local data dat
if GetSpellAbilityId() == SpellID then
set dat = data.create()
set dat.u = GetTriggerUnit()
set dat.v = GetSpellTargetUnit()
set dat.a = bj_RADTODEG * Atan2(GetUnitY(dat.v) - GetUnitY(dat.u), GetUnitX(dat.v) - GetUnitX(dat.u))
set dat.lvl = GetUnitAbilityLevel(dat.u,SpellID)
set dat.d = GetRotateTime(dat.lvl)
set dat.s = GetRotateSpeed(dat.lvl)
set dat.dmg1 = GetSpinDamage(dat.lvl)
set dat.dmg2 = GetTargetDamage(dat.lvl)
set dat.DamageOnceGroup = CreateGroup()
call IssueImmediateOrder(dat.u,"stop")
call PauseUnit(dat.u,true)
call PauseUnit(dat.v,true)
call SetUnitTimeScale(dat.v,0)
call SetUnitAnimation(dat.u,"spin")
call UnitAddAbility(dat.v,'Amrf')
call UnitRemoveAbility(dat.v,'Amrf')
set DATAS[total] = dat
set total = total + 1
if total == 1 then
call TimerStart(tim,interval,true, function execute)
endif
endif
return false
endfunction
private function Init takes nothing returns nothing
local trigger t = CreateTrigger()
call TriggerAddCondition(t,Condition(function start))
call TriggerRegisterAnyUnitEventBJ(t,EVENT_PLAYER_UNIT_SPELL_EFFECT)
set ite = CreateItem('wolg',0,0)
call SetItemVisible(ite,false)
call SetItemInvulnerable( ite, true)
endfunction
endscope//===========================================================================
// Trigger: GT
//===========================================================================
//TESH.scrollpos=74
//TESH.alwaysfold=0
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//~~ GT ~~ GTrigger ~~ By Jesus4Lyf ~~ Version 1.05 ~~
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// What is GTrigger?
// - GTrigger is an event system that replaces the cumbersome WC3
// event system.
// - GTrigger only launches the necessary threads instead of x threads,
// where x is the number of times the event type occurs in the map.
//
// =Pros=
// - Instead of having 16 events (for "16" players) per use of an,
// event type, you have 0 per use and 16 total for that event type.
// - If you have 100 events of one type in your map, instead of firing
// 100 triggers each time any spell is cast, you fire only what's needed.
// - GTrigger is faster to code with, more efficient to execute, and just
// better programming practises and nicer code all round.
//
// =Cons=
// - If a trigger with a GTrigger event is destroyed, it must have its
// event unregistered first or it will leak an event (slows firing down).
// - Shouldn't use "wait" actions anywhere in the triggers.
//
// Functions:
// // General
// - GT_UnregisterTriggeringEvent()
//
// // Ability events
// - GT_RegisterStartsEffectEvent(trigger, abilityid) (returns the trigger passed in)
// - GT_RegisterBeginsChanellingEvent(trigger, abilityid) (returns the trigger passed in)
// - GT_RegisterBeginsCastingEvent(trigger, abilityid) (returns the trigger passed in)
// - GT_RegisterStopsCastingEvent(trigger, abilityid) (returns the trigger passed in)
// - GT_RegisterFinishesCastingEvent(trigger, abilityid) (returns the trigger passed in)
// - GT_RegisterLearnsAbilityEvent(trigger, abilityid) (returns the trigger passed in)
// // Order events // (can use String2OrderIdBJ("OrderString") for orderid
// - GT_RegisterTargetOrderEvent(trigger, orderid) (returns the trigger passed in)
// - GT_RegisterPointOrderEvent(trigger, orderid) (returns the trigger passed in)
// - GT_RegisterNoTargetOrderEvent(trigger, orderid) (returns the trigger passed in)
// // Item events
// - GT_RegisterItemUsedEvent(trigger, itemtypeid) (returns the trigger passed in)
// - GT_RegisterItemAcquiredEvent(trigger, itemtypeid) (returns the trigger passed in)
// - GT_RegisterItemDroppedEvent(trigger, itemtypeid) (returns the trigger passed in)
// // Unit events
// - GT_RegisterUnitDiesEvent(trigger, unittypeid) (returns the trigger passed in)
//
// // Ability Events
// - GT_UnregisterSpellEffectEvent(trigger, abilityid) (returns the trigger passed in)
// - GT_UnregisterBeginsChanellingEvent(trigger, abilityid) (returns the trigger passed in)
// - GT_UnregisterBeginsCastingEvent(trigger, abilityid) (returns the trigger passed in)
// - GT_UnregisterStopsCastingEvent(trigger, abilityid) (returns the trigger passed in)
// - GT_UnregisterFinishesCastingEvent(trigger, abilityid) (returns the trigger passed in)
// - GT_UnregisterLearnsAbilityEvent(trigger, abilityid) (returns the trigger passed in)
// // Order events // (can use String2OrderIdBJ("OrderString") for orderid
// - GT_UnregisterTargetOrderEvent(trigger, orderid) (returns the trigger passed in)
// - GT_UnregisterPointOrderEvent(trigger, orderid) (returns the trigger passed in)
// - GT_UnregisterNoTargetOrderEvent(trigger, orderid) (returns the trigger passed in)
// // Item events
// - GT_UnregisterItemUsedEvent(trigger, itemtypeid) (returns the trigger passed in)
// - GT_UnregisterItemAcquiredEvent(trigger, itemtypeid) (returns the trigger passed in)
// - GT_UnregisterItemDroppedEvent(trigger, itemtypeid) (returns the trigger passed in)
// // Unit events
// - GT_UnregisterUnitDiesEvent(trigger, unittypeid) (returns the trigger passed in)
//
// Alternative interface (not recommended):
// If you aren't familiar with how this works, you shouldn't use it.
// All funcs must return false. (That is the only reason it isn't recommended.)
// // General
// - GT_RemoveTriggeringAction() // Use this to remove actions.
// // Ability Events
// - GT_AddStartsEffectAction(func, abilityid)
// - GT_AddBeginsChanellingActon(func, abilityid)
// - GT_AddBeginsCastingAction(func, abilityid)
// - GT_AddStopsCastingAction(func, abilityid)
// - GT_AddFinishesCastingAction(func, abilityid)
// - GT_AddLearnsAbilityAction(func, abilityid)
// // Order events // (can use String2OrderIdBJ("OrderString") for orderid
// - GT_AddTargetOrderAction(func, orderid)
// - GT_AddPointOrderAction(func, orderid)
// - GT_AddNoTargetOrderAction(func, orderid)
// // Item events
// - GT_AddItemUsedAction(func, itemtypeid)
// - GT_AddItemAcquiredAction(func, itemtypeid)
// - GT_AddItemDroppedAction(func, itemtypeid)
// // Unit events
// - GT_AddUnitDiesAction(func, unittypeid)
//
// Details:
// - Due to the storage method, only 8191 GTrigger events are possible at any one time.
//
// Thanks:
// - Daxtreme: For voluntarily testing this system and the UnitDies event idea.
// - kenny!: For the Order and Learns Ability event ideas.
//
// How to import:
// - Create a trigger named GT.
// - Convert it to custom text and replace the whole trigger text with this.
//
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
library GT initializer Init
//////////////
// Pointers //
////////////////////////////////////////////////////////////////////////////
// Assigned to abilities, and point to trigger grouping linked lists.
//
// Use:
// GetPointer --> int (pointer)
// FreePointer(int (pointer))
// set PointerTarget[int (pointer)]=int (list link)
// PointerTarget[int (pointer)] --> int (list link)
globals
// Pointer
private integer array PointerTarget
private integer PointerMax=0
// Spare Pointer Stack
private integer array NextPointer
private integer NextPointerMaxPlusOne=1
endglobals
private function GetPointer takes nothing returns integer
if NextPointerMaxPlusOne==1 then
set PointerMax=PointerMax+1
return PointerMax
endif
set NextPointerMaxPlusOne=NextPointerMaxPlusOne-1
return NextPointer[NextPointerMaxPlusOne]
endfunction
private function FreePointer takes integer pointer returns nothing
set PointerTarget[pointer]=0
set NextPointer[NextPointerMaxPlusOne]=pointer
set NextPointerMaxPlusOne=NextPointerMaxPlusOne+1
endfunction
///////////////////////////////////
// Trigger Grouping Linked Lists //
////////////////////////////////////////////////////////////////////////////
// Contains a chain of triggers to be executed together.
//
// Use:
// GetMem() --> int (mem)
// FreeMem(int (mem))
// Link(int (pointer), int (mem))
// Unlink(int (pointer), int (mem))
globals
// Spare Link Stack
private integer array NextMem
private integer NextMemMaxPlusOne=1
// Linked list
private trigger array Trig
private integer array Next
private integer array Prev
private integer TrigMax=0
endglobals
private function GetMem takes nothing returns integer
if NextMemMaxPlusOne==1 then
set TrigMax=TrigMax+1
return TrigMax
endif
set NextMemMaxPlusOne=NextMemMaxPlusOne-1
return NextMem[NextMemMaxPlusOne]
endfunction
private function FreeMem takes integer i returns nothing
set Trig[i]=null
set NextMem[NextMemMaxPlusOne]=i
set NextMemMaxPlusOne=NextMemMaxPlusOne+1
endfunction
// Linked list functionality
// NOTE: This means "Next" must be loaded BEFORE executing the trigger, which could delete the current link.
private function Link takes integer pointer, integer new returns nothing
set Prev[new]=0
set Next[new]=PointerTarget[pointer]
set Prev[PointerTarget[pointer]]=new
set PointerTarget[pointer]=new
endfunction
private function Unlink takes integer pointer, integer rem returns nothing
if Prev[rem]==0 then
set PointerTarget[pointer]=Next[rem]
set Prev[Next[rem]]=0
endif
set Next[Prev[rem]]=Next[rem]
set Prev[Next[rem]]=Prev[rem]
endfunction
//////////////////////
// GTrigger General //
////////////////////////////////////////////////////////////////////////////
// Only contains the UnregisterTriggeringEvent action for public use.
globals
boolean UnregisterLastEvent=false
endglobals
public function UnregisterTriggeringEvent takes nothing returns nothing
set UnregisterLastEvent=true
endfunction
/////////////////////////////////////
// GTrigger Ability Implementation //
////////////////////////////////////////////////////////////////////////////
// The nasty textmacro implementation of special "All Players" events.
//! textmacro SetupSpecialAllPlayersEvent takes NAME, EVENT, GETSPECIAL
globals
private trigger $NAME$Trigger=CreateTrigger()
// Extendable arrays
private integer array $NAME$AbilityIdA
private integer array $NAME$ListPointerA
private integer array $NAME$AbilityIdB
private integer array $NAME$ListPointerB
private integer array $NAME$AbilityIdC
private integer array $NAME$ListPointerC
private integer array $NAME$AbilityIdD
private integer array $NAME$ListPointerD
private integer array $NAME$AbilityIdE
private integer array $NAME$ListPointerE
endglobals
globals//locals
private integer GetOrCreateListPointer$NAME$AbilHashed
endglobals
private function GetOrCreate$NAME$ListPointer takes integer abil returns integer
set GetOrCreateListPointer$NAME$AbilHashed=abil-(abil/8191)*8191
if $NAME$AbilityIdA[GetOrCreateListPointer$NAME$AbilHashed]==abil then // Correct
return $NAME$ListPointerA[GetOrCreateListPointer$NAME$AbilHashed]
elseif $NAME$AbilityIdA[GetOrCreateListPointer$NAME$AbilHashed]<1 then // Empty
set $NAME$AbilityIdA[GetOrCreateListPointer$NAME$AbilHashed]=abil
set $NAME$ListPointerA[GetOrCreateListPointer$NAME$AbilHashed]=GetPointer()
return $NAME$ListPointerA[GetOrCreateListPointer$NAME$AbilHashed]
endif
if $NAME$AbilityIdB[GetOrCreateListPointer$NAME$AbilHashed]==abil then // Correct
return $NAME$ListPointerB[GetOrCreateListPointer$NAME$AbilHashed]
elseif $NAME$AbilityIdB[GetOrCreateListPointer$NAME$AbilHashed]<1 then // Empty
set $NAME$AbilityIdB[GetOrCreateListPointer$NAME$AbilHashed]=abil
set $NAME$ListPointerB[GetOrCreateListPointer$NAME$AbilHashed]=GetPointer()
return $NAME$ListPointerB[GetOrCreateListPointer$NAME$AbilHashed]
endif
if $NAME$AbilityIdC[GetOrCreateListPointer$NAME$AbilHashed]==abil then // Correct
return $NAME$ListPointerC[GetOrCreateListPointer$NAME$AbilHashed]
elseif $NAME$AbilityIdC[GetOrCreateListPointer$NAME$AbilHashed]<1 then // Empty
set $NAME$AbilityIdC[GetOrCreateListPointer$NAME$AbilHashed]=abil
set $NAME$ListPointerC[GetOrCreateListPointer$NAME$AbilHashed]=GetPointer()
return $NAME$ListPointerC[GetOrCreateListPointer$NAME$AbilHashed]
endif
if $NAME$AbilityIdD[GetOrCreateListPointer$NAME$AbilHashed]==abil then // Correct
return $NAME$ListPointerD[GetOrCreateListPointer$NAME$AbilHashed]
elseif $NAME$AbilityIdD[GetOrCreateListPointer$NAME$AbilHashed]<1 then // Empty
set $NAME$AbilityIdD[GetOrCreateListPointer$NAME$AbilHashed]=abil
set $NAME$ListPointerD[GetOrCreateListPointer$NAME$AbilHashed]=GetPointer()
return $NAME$ListPointerD[GetOrCreateListPointer$NAME$AbilHashed]
endif
if $NAME$AbilityIdE[GetOrCreateListPointer$NAME$AbilHashed]==abil then // Correct
return $NAME$ListPointerE[GetOrCreateListPointer$NAME$AbilHashed]
elseif $NAME$AbilityIdE[GetOrCreateListPointer$NAME$AbilHashed]<1 then // Empty
set $NAME$AbilityIdE[GetOrCreateListPointer$NAME$AbilHashed]=abil
set $NAME$ListPointerE[GetOrCreateListPointer$NAME$AbilHashed]=GetPointer()
return $NAME$ListPointerE[GetOrCreateListPointer$NAME$AbilHashed]
endif
call BJDebugMsg("GTrigger Error: Ran out of storage locations for pointers on object "+GetObjectName(abil)+"!")
set PointerTarget[0]=0
return 0
endfunction
globals//locals
private integer GetListPointer$NAME$AbilHashed
endglobals
private function Get$NAME$ListPointer takes integer abil returns integer
set GetListPointer$NAME$AbilHashed=abil-(abil/8191)*8191
if $NAME$AbilityIdA[GetListPointer$NAME$AbilHashed]==abil then // Correct
return $NAME$ListPointerA[GetListPointer$NAME$AbilHashed]
elseif $NAME$AbilityIdA[GetListPointer$NAME$AbilHashed]<1 then // Empty
set PointerTarget[0]=0 // Make sure.
return 0
endif
if $NAME$AbilityIdB[GetListPointer$NAME$AbilHashed]==abil then // Correct
return $NAME$ListPointerB[GetListPointer$NAME$AbilHashed]
elseif $NAME$AbilityIdB[GetListPointer$NAME$AbilHashed]<1 then // Empty
set PointerTarget[0]=0 // Make sure.
return 0
endif
if $NAME$AbilityIdC[GetListPointer$NAME$AbilHashed]==abil then // Correct
return $NAME$ListPointerC[GetListPointer$NAME$AbilHashed]
elseif $NAME$AbilityIdC[GetListPointer$NAME$AbilHashed]<1 then // Empty
set PointerTarget[0]=0 // Make sure.
return 0
endif
if $NAME$AbilityIdD[GetListPointer$NAME$AbilHashed]==abil then // Correct
return $NAME$ListPointerD[GetListPointer$NAME$AbilHashed]
elseif $NAME$AbilityIdD[GetListPointer$NAME$AbilHashed]<1 then // Empty
set PointerTarget[0]=0 // Make sure.
return 0
endif
if $NAME$AbilityIdE[GetListPointer$NAME$AbilHashed]==abil then // Correct
return $NAME$ListPointerE[GetListPointer$NAME$AbilHashed]
elseif $NAME$AbilityIdE[GetListPointer$NAME$AbilHashed]<1 then // Empty
set PointerTarget[0]=0 // Make sure.
return 0
endif
call BJDebugMsg("GTrigger Error: Ran out of storage locations for pointers at ability "+GetObjectName(abil)+"!")
set PointerTarget[0]=0
return 0
endfunction
globals//locals
private integer Register$NAME$Mem
endglobals
public function Register$NAME$Event takes trigger t, integer abil returns trigger
set Register$NAME$Mem=GetMem()
set Trig[Register$NAME$Mem]=t
call Link(GetOrCreate$NAME$ListPointer(abil),Register$NAME$Mem)
return t
endfunction
globals//locals
private integer Unregister$NAME$Pointer
private integer Unregister$NAME$Mem
endglobals
public function Unregister$NAME$Event takes trigger t, integer abil returns trigger
set Unregister$NAME$Pointer=Get$NAME$ListPointer(abil)
set Unregister$NAME$Mem=PointerTarget[Unregister$NAME$Pointer]
loop
exitwhen Trig[Unregister$NAME$Mem]==t
if Unregister$NAME$Mem==0 then
return t // Not found.
endif
set Unregister$NAME$Mem=Next[Unregister$NAME$Mem]
endloop
call Unlink(Unregister$NAME$Pointer,Unregister$NAME$Mem)
call FreeMem(Unregister$NAME$Mem)
return t
endfunction
private function Trigger$NAME$Event takes nothing returns boolean
local integer Trigger$NAME$Pointer=Get$NAME$ListPointer($GETSPECIAL$)
local integer Trigger$NAME$Mem=PointerTarget[Trigger$NAME$Pointer]
local integer Trigger$NAME$NextMem
set UnregisterLastEvent=false
loop
exitwhen Trigger$NAME$Mem<1
set Trigger$NAME$NextMem=Next[Trigger$NAME$Mem]
if TriggerEvaluate(Trig[Trigger$NAME$Mem]) then
call TriggerExecute(Trig[Trigger$NAME$Mem])
endif
if UnregisterLastEvent then
set UnregisterLastEvent=false
call Unlink(Trigger$NAME$Pointer,Trigger$NAME$Mem)
call FreeMem(Trigger$NAME$Mem)
endif
set Trigger$NAME$Mem=Trigger$NAME$NextMem
endloop
return false
endfunction
private function Init$NAME$ takes nothing returns nothing
local integer i=bj_MAX_PLAYER_SLOTS
call TriggerAddCondition($NAME$Trigger,Condition(function Trigger$NAME$Event))
loop
set i=i-1
call TriggerRegisterPlayerUnitEvent($NAME$Trigger,Player(i),EVENT_PLAYER_$EVENT$,null)
exitwhen i==0
endloop
endfunction
//! endtextmacro
//! runtextmacro SetupSpecialAllPlayersEvent("StartsEffect", "UNIT_SPELL_EFFECT", "GetSpellAbilityId()")
//! runtextmacro SetupSpecialAllPlayersEvent("BeginsChanelling", "UNIT_SPELL_CHANNEL", "GetSpellAbilityId()")
//! runtextmacro SetupSpecialAllPlayersEvent("BeginsCasting", "UNIT_SPELL_CAST", "GetSpellAbilityId()")
//! runtextmacro SetupSpecialAllPlayersEvent("StopsCasting", "UNIT_SPELL_ENDCAST", "GetSpellAbilityId()")
//! runtextmacro SetupSpecialAllPlayersEvent("FinishesCasting", "UNIT_SPELL_FINISH", "GetSpellAbilityId()")
//! runtextmacro SetupSpecialAllPlayersEvent("TargetOrder", "UNIT_ISSUED_TARGET_ORDER", "GetIssuedOrderId()")
//! runtextmacro SetupSpecialAllPlayersEvent("PointOrder", "UNIT_ISSUED_POINT_ORDER", "GetIssuedOrderId()")
//! runtextmacro SetupSpecialAllPlayersEvent("NoTargetOrder", "UNIT_ISSUED_ORDER", "GetIssuedOrderId()")
//! runtextmacro SetupSpecialAllPlayersEvent("ItemUsed", "UNIT_USE_ITEM", "GetItemTypeId(GetManipulatedItem())")
//! runtextmacro SetupSpecialAllPlayersEvent("ItemAcquired", "UNIT_PICKUP_ITEM", "GetItemTypeId(GetManipulatedItem())")
//! runtextmacro SetupSpecialAllPlayersEvent("ItemDropped", "UNIT_DROP_ITEM", "GetItemTypeId(GetManipulatedItem())")
//! runtextmacro SetupSpecialAllPlayersEvent("UnitDies", "UNIT_DEATH", "GetUnitTypeId(GetTriggerUnit())")
//! runtextmacro SetupSpecialAllPlayersEvent("LearnsAbility", "HERO_SKILL", "GetLearnedSkill()")
// Note to self: Remember to update the Init function.
/////////////////////////////////////////
// GTrigger All Players Implementation //
////////////////////////////////////////////////////////////////////////////
// The textmacro implementation of other "All Players" events.
//! textmacro SetupAllPlayersEvent takes NAME, EVENT
globals
private trigger $NAME$Trigger=CreateTrigger()
private integer $NAME$ListPointer=0
endglobals
globals//locals
private integer Register$NAME$Mem
endglobals
public function Register$NAME$Event takes trigger t returns trigger
set Register$NAME$Mem=GetMem()
set Trig[Register$NAME$Mem]=t
call Link($NAME$ListPointer,Register$NAME$Mem)
return t
endfunction
globals//locals
private integer Unregister$NAME$Pointer
private integer Unregister$NAME$Mem
endglobals
public function Unregister$NAME$Event takes trigger t returns trigger
set Unregister$NAME$Mem=PointerTarget[$NAME$ListPointer]
loop
exitwhen Trig[Unregister$NAME$Mem]==t
if Unregister$NAME$Mem==0 then
return t // Not found.
endif
set Unregister$NAME$Mem=Next[Unregister$NAME$Mem]
endloop
call Unlink($NAME$ListPointer,Unregister$NAME$Mem)
call FreeMem(Unregister$NAME$Mem)
return t
endfunction
private function Trigger$NAME$Event takes nothing returns boolean
local integer Trigger$NAME$Mem=PointerTarget[$NAME$ListPointer]
local integer Trigger$NAME$NextMem
set UnregisterLastEvent=false
loop
exitwhen Trigger$NAME$Mem<1
set Trigger$NAME$NextMem=Next[Trigger$NAME$Mem]
if TriggerEvaluate(Trig[Trigger$NAME$Mem]) then
call TriggerExecute(Trig[Trigger$NAME$Mem])
endif
if UnregisterLastEvent then
set UnregisterLastEvent=false
call Unlink($NAME$ListPointer,Trigger$NAME$Mem)
call FreeMem(Trigger$NAME$Mem)
endif
set Trigger$NAME$Mem=Trigger$NAME$NextMem
endloop
return false
endfunction
private function Init$NAME$ takes nothing returns nothing
local integer i=bj_MAX_PLAYER_SLOTS
call TriggerAddCondition($NAME$Trigger,Condition(function Trigger$NAME$Event))
loop
set i=i-1
call TriggerRegisterPlayerUnitEvent($NAME$Trigger,Player(i),EVENT_PLAYER_UNIT_$EVENT$,null)
exitwhen i==0
endloop
// Initialise the pointer.
set $NAME$ListPointer=GetPointer()
endfunction
//! endtextmacro
// Old: //! runtextmacro SetupAllPlayersEvent("AnyUnitDies", "DEATH")
private function Init takes nothing returns nothing
// Ability events
call InitStartsEffect()
call InitBeginsChanelling()
call InitBeginsCasting()
call InitStopsCasting()
call InitFinishesCasting()
call InitLearnsAbility()
// Order events
call InitTargetOrder()
call InitPointOrder()
call InitNoTargetOrder()
// Item events
call InitItemUsed()
call InitItemAcquired()
call InitItemDropped()
// Unit events
call InitUnitDies()
endfunction
//////////////
// Wrappers //
////////////////////////////////////////////////////////////////////////////
// Wraps it up, for those who really want this interface.
// General
public function RemoveTriggeringAction takes nothing returns nothing
call UnregisterTriggeringEvent()
call DestroyTrigger(GetTriggeringTrigger())
endfunction
// Special All Player Events
//! textmacro AddSpecialAllPlayersWrapper takes EVENT
public function Add$EVENT$Action takes code func, integer special returns nothing
call TriggerAddCondition(Register$EVENT$Event(CreateTrigger(),special),Condition(func))
endfunction
//! endtextmacro
//! runtextmacro AddSpecialAllPlayersWrapper("StartsEffect")
//! runtextmacro AddSpecialAllPlayersWrapper("BeginsChanelling")
//! runtextmacro AddSpecialAllPlayersWrapper("BeginsCasting")
//! runtextmacro AddSpecialAllPlayersWrapper("StopsCasting")
//! runtextmacro AddSpecialAllPlayersWrapper("FinishesCasting")
//! runtextmacro AddSpecialAllPlayersWrapper("TargetOrder")
//! runtextmacro AddSpecialAllPlayersWrapper("PointOrder")
//! runtextmacro AddSpecialAllPlayersWrapper("NoTargetOrder")
//! runtextmacro AddSpecialAllPlayersWrapper("ItemUsed")
//! runtextmacro AddSpecialAllPlayersWrapper("ItemAcquired")
//! runtextmacro AddSpecialAllPlayersWrapper("ItemDropped")
//! runtextmacro AddSpecialAllPlayersWrapper("UnitDies")
//! runtextmacro AddSpecialAllPlayersWrapper("LearnsAbility")
// Note to self: Remember to update the Init function.
// All Player Events
//! textmacro AddAllPlayersWrapper takes EVENT
public function Add$EVENT$Action takes code func returns nothing
call TriggerAddCondition(Register$EVENT$Event(CreateTrigger()),Condition(func))
endfunction
//! endtextmacro
//// runtextmacro AddAllPlayersWrapper("UnitSell")
// Old: //! runtextmacro AddAllPlayersWrapper("AnyUnitDies")
endlibrary//===========================================================================
// Trigger: MSGS
//===========================================================================
//TESH.scrollpos=-1
//TESH.alwaysfold=0
library MSGS{define{c_goldbrown="daa520";c_gold="ffd700";c_palegreen="7aff7c";c_pink="db7093";c_pretty="ee82ee"
c_grassgreen="7fff00";c_brightgreen="00ff00";c_brightblue="0000ff";c_aqua="00ffff";c_white="f0ffff"
c_black="000000";c_seagreen="7fffd4";c_twilightblur="20b2aa";c_twilightgreen="009966"
c_coralgreen="00fa9a";c_coralpink="f08080";c_coralblue="33aaff";c_plum="ba55d3";c_indigo="4169e1"
c_flowerpurple="aaaaff";c_green="32cd32";c_blue="4169e1";c_yellowgreen="adff2f";c_brightpurple="ff00ff"
c_paledenim="c3dbff";c_orange="ffa500";c_purple="da70d6";c_royalpurple="aa00ff";c_flowerred="ee2222"
c_grey="c0c0c0";c_gray="c0c0c0";c_redorange="ff4500";c_red="ff0000";c_spanishgreen="9acd32"
c_darkspanishgreen="6b8e23";c_brown ="995500";c_yellow="ffff00";c_sand="ffffcc";private low=1;private high=5
}//if I2R(d.orb/2)==I2R(d.orb)/I2R(2) then
string gtc(string x, string y){return "|cff"+x+y+"|r"}//colors text
string msggetcolor(integer x, string y){if x==0 then;return gtc(c_red,y);elseif x==1 then
return gtc(c_brightblue,y);elseif x==2 then;return gtc(c_aqua,y);elseif x==3 then
return gtc(c_purple,y);elseif x==4 then;return gtc(c_yellow,y);elseif x==5 then
return gtc(c_orange,y);else;return gtc(c_white,y);endif;return y}//colors text based on player color
integer GetPlayerTeamMSGS(integer playerid){if playerid==0 then;return 1;elseif playerid==1 then
return 2;elseif playerid==3 then;return 1;elseif playerid>high then;return 3;endif;return 2}//player number for team number//customize as needed
nothing msgally(real x, player y, string z, boolean ally){integer a=GetPlayerId(y),b=GetPlayerTeamMSGS(a)
if ally then;a=low;whilenot(a++>high){if GetPlayerTeamMSGS(a)==b then;timedmsg(Player(a),0,0,x,z);endif}
else;a=low;whilenot(a++>high){if GetPlayerTeamMSGS(a)!=b then;timedmsg(Player(a),0,0,x,z);endif}endif}
nothing msgallyo(real x, player y, string z){integer a=GetPlayerId(y),b=GetPlayerTeamMSGS(a)
a=low;whilenot(a++>high){if GetPlayerTeamMSGS(a)==b then;timedmsg(Player(a),0,0,x,z);endif}}
nothing msgenemyno(real x, player y, string z){integer a=GetPlayerId(y),b=GetPlayerTeamMSGS(a)
a=low;whilenot(a++>high){if GetPlayerTeamMSGS(a)!=b then;timedmsg(Player(a),0,0,x,z);endif}}
nothing msgall(real dur, string s){integer i=low;whilenot (i++>high){timedmsg(Player(i),0,0,dur,s)}}//standard text
nothing msgone(real dur, player p, string s, boolean one){integer i=low,ip=GetPlayerId(p);if one then
timedmsg(p,0,0,dur,(s));else;whilenot(i++>high){if i!=ip then;timedmsg(Player(i),0,0,dur,s);endif}endif}}//===========================================================================
// Trigger: DebugS
//===========================================================================
//TESH.scrollpos=-1
//TESH.alwaysfold=0
library DebugS uses MSGS
define{gdx=GetDestructableX;gdy=GetDestructableY;gux=GetUnitX;guy=GetUnitY;gix=GetItemX;giy=GetItemY
gtu=GetTriggerUnit()}
void gos(string order, integer orderid){msgall(5,order);msgall(5,I2S(orderid))}
string sxyi(item x){return R2S(gix(x))+","+R2S(giy(x))};string sxyu(unit x){return R2S(gux(x))+","+R2S(guy(x))}
string sxyd(destructable x){return R2S(gdx(x))+","+R2S(gdy(x))}
boolean cxyi(item x, real x1, real y1, real x2, real y2)
{if gix(x) > x1 and gix(x) < x2 and giy(x) > y1 and giy(x) < y2 then;return true;endif;return false}
boolean cxyu(unit x, real x1, real y1, real x2, real y2)
{if gux(x) > x1 and gux(x) < x2 and guy(x) > y1 and guy(x) < y2 then;return true;endif;return false}
boolean cxyd(destructable x, real x1, real y1, real x2, real y2)
{if gdx(x) > x1 and gdx(x) < x2 and gdy(x) > y1 and gdy(x) < y2 then;return true;endif;return false};endlibrary
scope GetOrderStringForUnit initializer I
define {feedgos=OrderId2String(GetIssuedOrderId()),GetIssuedOrderId()
unitgos=GetUnitTypeId(GetOrderedUnit());private UNITID='U004'}
private boolean f(){if unitgos==UNITID then;msgall(5,"target order:");gos(feedgos);endif;return false}
private boolean g(){if unitgos==UNITID then;msgall(5,"point order:");gos(feedgos);msgall(5,R2S(GetOrderPointX())+\
R2S(GetOrderPointY()));endif;return false}
private boolean h(){if unitgos==UNITID then;msgall(5,"order:");gos(feedgos);endif;return false}
private void I(){trigger t=CreateTrigger();TriggerRegisterAnyUnitEventBJ(t,EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER);TriggerAddCondition( t,Condition( function f));set t = CreateTrigger( )
TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_ISSUED_POINT_ORDER );TriggerAddCondition( t,Condition( function g));set t = CreateTrigger( )
TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_ISSUED_ORDER );TriggerAddCondition( t,Condition( function h))}
endscope//===========================================================================
// Trigger: jBoard
//===========================================================================
//TESH.scrollpos=36
//TESH.alwaysfold=0
//==============================================================================
// jBoard -- ADVANCED MULTIBOARD SYSTEM BY MAGENTIX -- v1.2
//==============================================================================
//==============================================================================
// Quick manual:
//==============================================================================
//
// Implement by adding "requires jBoardLib" behind your library/scope names
//
// ----------------------------------------------------------------------
// What is jBoard?
// ----------------------------------------------------------------------
//
// jBoard is an enhanced multiboard management system, inspired by the
// jQuery library that is available to webdesigners. That javascript library
// allows for a cool functionality called "chaining".
//
// Because WC3 multiboards often require a huge amount of function calls,
// I came up with jBoard to allow you to make your multiboard code shorter,
// smoother and overall more easy to use.
//
//
// ----------------------------------------------------------------------
// What is chaining and how to use it?
// ----------------------------------------------------------------------
//
// An example says a thousand words, assume this is your 10x5 multiboard setup
// and you want to set all fields to "0" and the first field to "1":
//
// - local multiboard MB = CreateMultiboard()
// local multiboarditem MBI
// call MultiboardSetTitleText(MB,"My Multiboard")
// call MultiboardDisplay(MB,true)
// call MultiboardSetRowCount(MB,10)
// call MultiboardSetColumnCount(MB,5)
// call MultiboardSetItemsValue(MB,"0")
// call MultiboardSetItemsStyle(MB,true,false)
// set MBI = MultiboardGetItem(MB,0,0)
// call MultiboardSetItemValue(MBI,"1")
//
// Now take a look at jBoard:
// - //! runtextmacro jBoardCreate("MyBoard","10","5")
// local MyBoard MB = MyBoard.create("My Multiboard").field(0,0).setValue("1")
// That's all you need to type!
//
// Remember: the textmacro also only has to be called ONCE to create a
// multiboard with the wanted dimensions. So actually that line wouldn't be
// there, but at the top of your script.
//
// Did you also notice how every method call returned an object that you
// could then call another method on? That is the beauty of chaining.
//
// !! EVERY FUNCTION CALL RETURNS A jBoard OBJECT UNLESS STATED OTHERWISE !!
//
//
// ----------------------------------------------------------------------
// I noticed a textmacro there, what gives?
// ----------------------------------------------------------------------
//
// Since you need to create structs that represent your multiboard, jBoard
// needs to know the dimensions of your multiboard to ensure the structs
// don't take up more space than they need to.
//
// For every multiboard variation you plan to use, simply call this once at
// the top of your script:
// //! runtextmacro jBoardCreate("StructName","RowAmount","ColAmount")
//
// Example for an 8 row, 4 col board:
// //! runtextmacro jBoardCreate("My8x4Board","8","4")
// Which you can then instanciate in your script as
// My8x4Board.create("BoardTitle")
//
//
// ----------------------------------------------------------------------
// Defaults
// ----------------------------------------------------------------------
//
// Somtimes we don't want our board cells to be empty by default, but show
// 0 for example. This is easy to achieve by setting a default. Take a look
// at the jBoard struct further down this info block and edit the defaults
// you like to see changed. Every jBoard that gets created after a change
// will take those defaults into account.
//
// Note that you can hardcode defaults below and still change them on the fly!
// set jBoard.defaultItemValue = "1" -- Valid syntax!
//
// Edit your defaults here:
//ReplaceableTextures\CommandButtons\BTNUndeadShrine.blp
//ReplaceableTextures\CommandButtons\BTNReplay-Speedup.blp
//ReplaceableTextures\CommandButtons\BTNReplay-Speeddown.blp
//ReplaceableTextures\CommandButtons\BTNReplay-Loop.blp
//ReplaceableTextures\CommandButtons\BTNReplay-Pause.blp
//ReplaceableTextures\CommandButtons\BTNReplay-Play.blp
//! textmacro jBoardDefaults
static string defaultItemValue = "/"
static string defaultIconPath = "war3mapImported\\sankaku.blp"
static boolean defaultShowValue = true
static boolean defaultShowIcon = true
static boolean defaultShowBoard = true
static real defaultItemWidth = 0.03
//! endtextmacro
//
//==============================================================================
//==============================================================================
// Tip: Commenting out newlines
//==============================================================================
//
// Sometimes when chaining methods, a command can get quite lengthy. jQuery
// doesn't suffer from this visually, because javascript allows people to write
// code over multiple lines until they end it with a semicolon (;)
//
// JASS, however, doesn't allow that directly. Fortunately you can call jBoard
// commands just as easily on multiple lines. Remember: Until you call .reset(),
// your selection will be saved to the next line!
//
// Example:
// local MyBoard MB = MyBoard.create("funkyboard").setplayerrow(0,2).setcolour("ff0000").reset().setplayerrow(1,3).setcolour("0000ff").reset().etc...
//
// Could become:
// local MyBoard MB = MyBoard.create("funkyboard")
// call MB.setplayerrow(0,2).setcolour("ff0000").reset()
// call MB.setplayerrow(1,3)
// call MB.setcolour("0000ff").reset() <-- Previous row selection was saved to this line
//
// In the end it all boils down to which type of coding you prefer, of course.
//
//==============================================================================
//==============================================================================
// Tip: -R Functions
//==============================================================================
//
// When chaining several commands onto a set of fields, one could easily say:
// "There, now let me reset my selection and continue chaining methods"
//
// However, when chaining that way, a string of jBoard commands could easily
// contain the call .reset() a dozen times.
//
// To save coding space and safeguard readability, I introduced the -R functions:
// Basically, any non-selector function that returns a jBoard object can be called
// with a capital "R" behind the name and the jBoard system will automatically
// call a .reset() for you.
//
// The above example of commenting out newlines would then become:
// local MyBoard MB = MyBoard.create("funkyboard").setPlayerRow(0,2).setColourR("ff0000").setPlayerRow(1,3).setColourR("0000ff").etc...
//
// As you can see, this makes the chaining process yet again a little smoother
// Once again: this functionality does not work on selectors/"getters"!
//
//==============================================================================
//==============================================================================
// Function index:
//==============================================================================
//
// ----------------------------------------------------------------------
// Standard Functions - Creating, showing, etc...
// ----------------------------------------------------------------------
//
// Main functionality you'd expect from any multiboard. May be used within
// a local player block. Can be used on any jBoard object (boad, row, col,
// field(s)) and returns the selection you called the function on.
//
// .create("MultiboardName")
// .show()
// .hide()
// .clear() -- SHOULD NEVER BE CALLED, just here for completion
// .fold()
// .unfold()
// .setName()
// .getName() -- Returns the multiboard name as a string, not a jBoard object
// .setNameColour("rgb value")
// Colour syntax: rrggbb (in hexadecimal)
// .getNameColour()
// .destroy()
//
//
// ----------------------------------------------------------------------
// Selection Functions - Adds rows, cols or fields to the selection
// ----------------------------------------------------------------------
//
// Selectors can be used on any jBoard object (boad, row, col, field(s))
// They always return the collection of all the objects you selected from
// the last .reset() up to that point.
//
// VERY IMPORTANT!
// .reset()
// Resets the current selection to the board
//
// MAIN SELECTORS
// .row(integer start, integer end)
// .col(integer start, integer end)
// Selects a row, a columns or multiple of any
// - .row(0,0) returns the row object of row 0
// - .row(0,1) returns the combined fields of row 0 and row 1
// - ONLY WHEN HAVING -ONE- ROW/COL SELECTED will you be able
// to use row/col only functionality
// (it won't give errors or bugs if you try, though)
//
// SINGLE SELECTOR
// .field(integer row, integer col)
// Adds one field to the selection or (if selection is empty)
// returns one field to use field-level manipulations on
// .getPlayerRowField(integer player, integer column)
// .getPlayerColField(integer player, integer row)
// The above two return just ONE field of a player's row.
// Since the player selectors return an entire row and a deep
// selector inside that row would clear the selection first,
// it would otherwise be impossible to select multiple fields
// from player rows or columns...
// You should use this over .getPlayerRow(0).getField(3) unless
// you want only that field of course.
//
// DEEP SELECTOR
// .getField(integer which)
// Returns just ONE field, selected from your previous selection
//
// Quick list of what it does when used on a:
// - Board: Returns the field in position X of the board,
// reading from top left to bottom right
// - Row: Returns the field in column X of that row
// - Column: Returns the field in row X of that column
// - Fields: Returns the field in position X of the selection,
// reading from top left to bottom right
// - Field: Does nothing (returns same field)
//
//
// ----------------------------------------------------------------------
// Player Selectors
// ----------------------------------------------------------------------
//
// Simple functions that allow you to save a row/col to a player.
//
// Both the setters and the getters add the row/col you just set
// to the current selection. Hence, this is both valid syntax:
// - MB.setPlayerRow(0,1).setcolour("ff0000")
// - MB.setPlayerRow(0,1)
// MB.getPlayerRow(0,1).setcolour("ff0000")
//
// The player "setters" have -R functionality, but the "getters" don't!
//
// .setPlayerRow(integer player, integer row)
// .setPlayerCol(integer player, integer col)
// .getPlayerRow(integer player)
// .getPlayerCol(integer player)
//
//
// ----------------------------------------------------------------------
// Manipulation Functions - Also referred to as "setters"
// ----------------------------------------------------------------------
//
// Setters can be used on any jBoard object (boad, row, col, field(s))
// They always return the object that was just manipulated
//
// ABOUT PREFIXES AND SUFFIXES:
// Imagine you want a row with user experience values, by setting a suffix
// "XP", you could still use .add(value) to a field, because the content
// can still be handled by S2I(). Example:
// - .field(1,2) has content "2" and suffix " xp", the field shows "2 xp"
// A user calls .field(1,2).add(4), the field now show "6 xp", without
// having to worry about the " xp" bit!
//
// VALUE SETTERS
// .setValue("value")
// .setColour("rgb value")
// Colour syntax: rrggbb (in hexadecimal)
// .setPrefix("value")
// .setSuffix("value")
// .setIconPath("path")
// .setWidth(real width)
//
// VALUE MANIPULATORS
// .add(integer value)
// Only works if field contents are numerical strings, value can be negative
//
//
// ----------------------------------------------------------------------
// Retrieval Functions - Also referred to as "getters"
// ----------------------------------------------------------------------
//
// Getters can be used on any jBoard object (boad, row, col, field(s))
// !! EVERY GETTER RETURNS A STRING !!
//
// HERE'S WHY:
// When using a getter on anything but a single field, a string is returned
// with all values in it, separated by a pipe (|).
// Future versions may support smart retrieval of a row's/col's properties
// should they all have the same colour for example...
//
// Naturally, the fact that these methods return a string instead of a
// jBoard object means that calling any of these methods is in fact
// "The end of the line" for that chaining process...
//
// .getValue()
// .getColour()
// .getPrefix()
// .getSuffix()
// .getIconPath() -- CAREFUL USE on many fields! (might blow up in your face)
// .getWidth()
//
//
// ----------------------------------------------------------------------
// Extra Functions - Various
// ----------------------------------------------------------------------
//
// .showIcon()
// .hideIcon()
// .showValue()
// .hideValue()
//
//==============================================================================
//==============================================================================
// Credits:
//==============================================================================
//
// John Resig for coming up with jQuery and its chaining
// Vexorian for vJass and JassHelper, making jBoard possible
//
//==============================================================================
//==============================================================================
// Open letter to Vexorian:
//==============================================================================
//
// Take a look at the setter/getter methods and the -R functions. If that isn't
// a reason why textmacroes should be allowed to be nested, I don't know what
// is :x (They're all the same bar the function name...)
//
// Protip: Yes, this is a request to you to get nested textmacroes working :)
//
//==============================================================================
//==============================================================================
// Macro function core -- No touchy from here on out!
//==============================================================================
//! textmacro jBoardCreate takes NAME, ROWS, COLS
globals
private constant integer $NAME$SIZE = $ROWS$*$COLS$
private constant integer $NAME$ROWS = $ROWS$
private constant integer $NAME$COLS = $COLS$
endglobals
private struct $NAME$FIELD
$NAME$ parent
integer realRow
integer realCol
multiboarditem mbi
real width= jBoard.defaultItemWidth
string iconpath = jBoard.defaultIconPath
string colour = "ffffff"
string prefix = ""
string content = jBoard.defaultItemValue
string suffix = ""
boolean showV = jBoard.defaultShowValue
boolean showI = jBoard.defaultShowIcon
static method create takes $NAME$ parent, integer row, integer col returns thistype
local thistype f = thistype.allocate()
set f.parent = parent
set f.realRow = row
set f.realCol = col
set f.mbi = MultiboardGetItem(f.parent.MB,f.realRow,f.realCol)
return f
endmethod
method onDestroy takes nothing returns nothing
call MultiboardReleaseItem(.mbi)
endmethod
private method updateField takes nothing returns nothing
call MultiboardSetItemValue(.mbi,"|cff"+.colour+.prefix+.content+.suffix+"|r")
endmethod
method add takes integer i returns nothing
set .content = I2S(S2I(.content) + i)
call .updateField()
endmethod
method setValue takes string s returns nothing
set .content = s
call .updateField()
endmethod
method setPrefix takes string s returns nothing
set .prefix = s
call .updateField()
endmethod
method setSuffix takes string s returns nothing
set .suffix = s
call .updateField()
endmethod
method setColour takes string rgb returns nothing
set .colour = rgb
call .updateField()
endmethod
method setWidth takes real w returns nothing
set .width = w
call MultiboardSetItemWidth(.mbi,w)
endmethod
method showIcon takes nothing returns nothing
set .showI = true
call MultiboardSetItemStyle(.mbi,.showV,.showI)
endmethod
method hideIcon takes nothing returns nothing
set .showI = false
call MultiboardSetItemStyle(.mbi,.showV,.showI)
endmethod
method showValue takes nothing returns nothing
set .showV = true
call MultiboardSetItemStyle(.mbi,.showV,.showI)
endmethod
method hideValue takes nothing returns nothing
set .showV = false
call MultiboardSetItemStyle(.mbi,.showV,.showI)
endmethod
method setIconPath takes string s returns nothing
set .iconpath = s
call MultiboardSetItemIcon(.mbi,.iconpath)
endmethod
method getValue takes nothing returns string
return .content
endmethod
method getPrefix takes nothing returns string
return .prefix
endmethod
method getSuffix takes nothing returns string
return .suffix
endmethod
method getColour takes nothing returns string
return .colour
endmethod
method getWidth takes nothing returns string
return R2S(.width)
endmethod
method getIconPath takes nothing returns string
return .iconpath
endmethod
endstruct
private interface $NAME$FIELDCOLLECTION
$NAME$ parent
method getField takes integer i returns $NAME$FIELD
endinterface
private struct $NAME$UTILITY extends $NAME$FIELDCOLLECTION
stub method getField takes integer i returns $NAME$FIELD
return 0
endmethod
endstruct
private struct $NAME$ROW extends $NAME$UTILITY
$NAME$FIELD array fields[$COLS$]
integer realPos
integer fromPlayer = -1
static method create takes $NAME$ parent, integer pos returns thistype
local thistype row = thistype.allocate()
local integer i = 0
set row.parent = parent
set row.realPos = pos
loop
exitwhen i == $NAME$COLS
set row.fields[i] = $NAME$FIELD.create(parent,pos,i)
set i = i + 1
endloop
return row
endmethod
method getField takes integer i returns $NAME$FIELD
return .fields[i]
endmethod
endstruct
private struct $NAME$COL extends $NAME$UTILITY
$NAME$FIELD array fields[$ROWS$]
integer realPos
integer fromPlayer = -1
static method create takes $NAME$ parent, integer pos returns thistype
local thistype col = thistype.allocate()
local integer i = 0
set col.parent = parent
set col.realPos = pos
loop
exitwhen i == $NAME$ROWS
set col.fields[i] = col.parent.rows[i].fields[pos]
set i = i + 1
endloop
return col
endmethod
method getField takes integer i returns $NAME$FIELD
return .fields[i]
endmethod
endstruct
private struct $NAME$FLD extends $NAME$UTILITY
$NAME$FIELD array fields[$NAME$SIZE]
static method create takes $NAME$ parent returns thistype
local thistype fld = thistype.allocate()
set fld.parent = parent
return fld
endmethod
private method hasField takes $NAME$FIELD f returns boolean
local integer i = 0
loop
exitwhen i == .parent.selectionAmount
if (.fields[i] == f) then
return true
endif
set i = i + 1
endloop
return false
endmethod
method addFields takes $NAME$FIELDCOLLECTION f, integer amount returns nothing
local integer i = 0
loop
exitwhen i == amount
if not(.hasField(f.getField(i))) then
set .fields[.parent.selectionAmount] = f.getField(i)
set .parent.selectionAmount = .parent.selectionAmount + 1
endif
set i = i + 1
endloop
endmethod
method getField takes integer i returns $NAME$FIELD
return .fields[i]
endmethod
endstruct
struct $NAME$ extends jBoard
$NAME$ROW array rows[$ROWS$]
$NAME$COL array cols[$COLS$]
$NAME$FLD selection
static method create takes string boardName returns thistype
local thistype board = thistype.allocate(boardName)
local integer i = 0
call MultiboardSetRowCount(board.MB,$NAME$ROWS)
call MultiboardSetColumnCount(board.MB,$NAME$COLS)
set board.selection = $NAME$FLD.create(board)
loop
exitwhen i == $NAME$ROWS
set board.rows[i] = $NAME$ROW.create(board,i)
set i = i + 1
endloop
set i = 0
loop
exitwhen i == $NAME$COLS
set board.cols[i] = $NAME$COL.create(board,i)
set i = i + 1
endloop
call board.initBoard()
return board
endmethod
private method transfer takes $NAME$FIELDCOLLECTION f, integer ftype, integer amount returns nothing
set .selectionLevel = IntegerTertiaryOp(.selectionLevel == jBoard_SELECTION_LVL_BOARD,ftype,jBoard_SELECTION_LVL_FIELDS)
call .selection.addFields(f,amount)
endmethod
method reset takes nothing returns thistype
set .selectionLevel = jBoard_SELECTION_LVL_BOARD
set .selectionAmount = 0
return this
endmethod
method field takes integer row, integer col returns thistype
set .selection.fields[0] = .rows[row].fields[col]
set .selectionLevel = jBoard_SELECTION_LVL_FLD
return this
endmethod
method getField takes integer which returns thistype
if .selectionLevel == jBoard_SELECTION_LVL_ROW then
set .selection.fields[0] = .rows[.selectionSpecial].fields[which]
elseif .selectionLevel == jBoard_SELECTION_LVL_COL then
set .selection.fields[0] = .cols[.selectionSpecial].fields[which]
elseif .selectionLevel == jBoard_SELECTION_LVL_FIELDS then
set .selection.fields[0] = .selection.fields[which]
elseif .selectionLevel == jBoard_SELECTION_LVL_BOARD then
set .selection.fields[0] = .rows[which/$NAME$COLS].fields[ModuloInteger(which,$NAME$COLS)]
endif
set .selectionLevel = jBoard_SELECTION_LVL_FLD
return this
endmethod
method row takes integer start, integer end returns thistype
local integer i = IntegerTertiaryOp(start<end,start,end)
local integer j = IntegerTertiaryOp(start<end,end,start)
if start == end then
set .selectionSpecial = start
call .transfer(.rows[start],jBoard_SELECTION_LVL_ROW,$NAME$COLS)
else
loop
exitwhen i > j
call .transfer(.rows[i],jBoard_SELECTION_LVL_ROW,$NAME$COLS)
set i = i + 1
endloop
endif
return this
endmethod
method col takes integer start, integer end returns thistype
local integer i = IntegerTertiaryOp(start<end,start,end)
local integer j = IntegerTertiaryOp(start<end,end,start)
if start == end then
set .selectionSpecial = start
call .transfer(.cols[start],jBoard_SELECTION_LVL_COL,$NAME$ROWS)
else
loop
exitwhen i > j
call .transfer(.cols[i],jBoard_SELECTION_LVL_COL,$NAME$ROWS)
set i = i + 1
endloop
endif
return this
endmethod
method setPlayerRow takes integer p, integer row returns thistype
set .playerRow = row
set .rows[row].fromPlayer = p
return .row(row,row)
endmethod
method getPlayerRow takes integer p returns thistype
return .row(.playerRow,.playerRow)
endmethod
method getPlayerRowField takes integer p, integer i returns thistype
return .field(.playerRow,i)
endmethod
method setPlayerCol takes integer p, integer col returns thistype
set .playerCol = col
set .cols[col].fromPlayer = p
return .col(col,col)
endmethod
method getPlayerCol takes integer p returns thistype
return .col(.playerCol,.playerCol)
endmethod
method getPlayerColField takes integer p, integer i returns thistype
return .field(i,.playerCol)
endmethod
method setColour takes string rgb returns thistype
local integer i = 0
if (.selectionLevel == jBoard_SELECTION_LVL_BOARD) then
loop
exitwhen i == $NAME$ROWS
call .reset().row(i,i).setColour(rgb)
set i = i + 1
endloop
set .selectionLevel = jBoard_SELECTION_LVL_BOARD
elseif (.selectionLevel == jBoard_SELECTION_LVL_FIELDS) then
loop
exitwhen i == .selectionAmount
call .selection.fields[i].setColour(rgb)
set i = i + 1
endloop
elseif (.selectionLevel == jBoard_SELECTION_LVL_ROW) then
loop
exitwhen i == $NAME$COLS
call .rows[.selectionSpecial].fields[i].setColour(rgb)
set i = i + 1
endloop
elseif (.selectionLevel == jBoard_SELECTION_LVL_COL) then
loop
exitwhen i == $NAME$ROWS
call .cols[.selectionSpecial].fields[i].setColour(rgb)
set i = i + 1
endloop
elseif (.selectionLevel == jBoard_SELECTION_LVL_FLD) then
call .selection.fields[0].setColour(rgb)
endif
return this
endmethod
method setWidth takes real w returns thistype
local integer i = 0
if (.selectionLevel == jBoard_SELECTION_LVL_BOARD) then
loop
exitwhen i == $NAME$ROWS
call .reset().row(i,i).setWidth(w)
set i = i + 1
endloop
set .selectionLevel = jBoard_SELECTION_LVL_BOARD
elseif (.selectionLevel == jBoard_SELECTION_LVL_FIELDS) then
loop
exitwhen i == .selectionAmount
call .selection.fields[i].setWidth(w)
set i = i + 1
endloop
elseif (.selectionLevel == jBoard_SELECTION_LVL_ROW) then
loop
exitwhen i == $NAME$COLS
call .rows[.selectionSpecial].fields[i].setWidth(w)
set i = i + 1
endloop
elseif (.selectionLevel == jBoard_SELECTION_LVL_COL) then
loop
exitwhen i == $NAME$ROWS
call .cols[.selectionSpecial].fields[i].setWidth(w)
set i = i + 1
endloop
elseif (.selectionLevel == jBoard_SELECTION_LVL_FLD) then
call .selection.fields[0].setWidth(w)
endif
return this
endmethod
method setPrefix takes string val returns thistype
local integer i = 0
if (.selectionLevel == jBoard_SELECTION_LVL_BOARD) then
loop
exitwhen i == $NAME$ROWS
call .reset().row(i,i).setPrefix(val)
set i = i + 1
endloop
set .selectionLevel = jBoard_SELECTION_LVL_BOARD
elseif (.selectionLevel == jBoard_SELECTION_LVL_FIELDS) then
loop
exitwhen i == .selectionAmount
call .selection.fields[i].setPrefix(val)
set i = i + 1
endloop
elseif (.selectionLevel == jBoard_SELECTION_LVL_ROW) then
loop
exitwhen i == $NAME$COLS
call .rows[.selectionSpecial].fields[i].setPrefix(val)
set i = i + 1
endloop
elseif (.selectionLevel == jBoard_SELECTION_LVL_COL) then
loop
exitwhen i == $NAME$ROWS
call .cols[.selectionSpecial].fields[i].setPrefix(val)
set i = i + 1
endloop
elseif (.selectionLevel == jBoard_SELECTION_LVL_FLD) then
call .selection.fields[0].setPrefix(val)
endif
return this
endmethod
method setSuffix takes string val returns thistype
local integer i = 0
if (.selectionLevel == jBoard_SELECTION_LVL_BOARD) then
loop
exitwhen i == $NAME$ROWS
call .reset().row(i,i).setSuffix(val)
set i = i + 1
endloop
set .selectionLevel = jBoard_SELECTION_LVL_BOARD
elseif (.selectionLevel == jBoard_SELECTION_LVL_FIELDS) then
loop
exitwhen i == .selectionAmount
call .selection.fields[i].setSuffix(val)
set i = i + 1
endloop
elseif (.selectionLevel == jBoard_SELECTION_LVL_ROW) then
loop
exitwhen i == $NAME$COLS
call .rows[.selectionSpecial].fields[i].setSuffix(val)
set i = i + 1
endloop
elseif (.selectionLevel == jBoard_SELECTION_LVL_COL) then
loop
exitwhen i == $NAME$ROWS
call .cols[.selectionSpecial].fields[i].setSuffix(val)
set i = i + 1
endloop
elseif (.selectionLevel == jBoard_SELECTION_LVL_FLD) then
call .selection.fields[0].setSuffix(val)
endif
return this
endmethod
method setIconPath takes string val returns thistype
local integer i = 0
if (.selectionLevel == jBoard_SELECTION_LVL_BOARD) then
loop
exitwhen i == $NAME$ROWS
call .reset().row(i,i).setIconPath(val)
set i = i + 1
endloop
set .selectionLevel = jBoard_SELECTION_LVL_BOARD
elseif (.selectionLevel == jBoard_SELECTION_LVL_FIELDS) then
loop
exitwhen i == .selectionAmount
call .selection.fields[i].setIconPath(val)
set i = i + 1
endloop
elseif (.selectionLevel == jBoard_SELECTION_LVL_ROW) then
loop
exitwhen i == $NAME$COLS
call .rows[.selectionSpecial].fields[i].setIconPath(val)
set i = i + 1
endloop
elseif (.selectionLevel == jBoard_SELECTION_LVL_COL) then
loop
exitwhen i == $NAME$ROWS
call .cols[.selectionSpecial].fields[i].setIconPath(val)
set i = i + 1
endloop
elseif (.selectionLevel == jBoard_SELECTION_LVL_FLD) then
call .selection.fields[0].setIconPath(val)
endif
return this
endmethod
method showIcon takes nothing returns thistype
local integer i = 0
if (.selectionLevel == jBoard_SELECTION_LVL_BOARD) then
loop
exitwhen i == $NAME$ROWS
call .reset().row(i,i).showIcon()
set i = i + 1
endloop
set .selectionLevel = jBoard_SELECTION_LVL_BOARD
elseif (.selectionLevel == jBoard_SELECTION_LVL_FIELDS) then
loop
exitwhen i == .selectionAmount
call .selection.fields[i].showIcon()
set i = i + 1
endloop
elseif (.selectionLevel == jBoard_SELECTION_LVL_ROW) then
loop
exitwhen i == $NAME$COLS
call .rows[.selectionSpecial].fields[i].showIcon()
set i = i + 1
endloop
elseif (.selectionLevel == jBoard_SELECTION_LVL_COL) then
loop
exitwhen i == $NAME$ROWS
call .cols[.selectionSpecial].fields[i].showIcon()
set i = i + 1
endloop
elseif (.selectionLevel == jBoard_SELECTION_LVL_FLD) then
call .selection.fields[0].showIcon()
endif
return this
endmethod
method hideIcon takes nothing returns thistype
local integer i = 0
if (.selectionLevel == jBoard_SELECTION_LVL_BOARD) then
loop
exitwhen i == $NAME$ROWS
call .reset().row(i,i).hideIcon()
set i = i + 1
endloop
set .selectionLevel = jBoard_SELECTION_LVL_BOARD
elseif (.selectionLevel == jBoard_SELECTION_LVL_FIELDS) then
loop
exitwhen i == .selectionAmount
call .selection.fields[i].hideIcon()
set i = i + 1
endloop
elseif (.selectionLevel == jBoard_SELECTION_LVL_ROW) then
loop
exitwhen i == $NAME$COLS
call .rows[.selectionSpecial].fields[i].hideIcon()
set i = i + 1
endloop
elseif (.selectionLevel == jBoard_SELECTION_LVL_COL) then
loop
exitwhen i == $NAME$ROWS
call .cols[.selectionSpecial].fields[i].hideIcon()
set i = i + 1
endloop
elseif (.selectionLevel == jBoard_SELECTION_LVL_FLD) then
call .selection.fields[0].hideIcon()
endif
return this
endmethod
method showValue takes nothing returns thistype
local integer i = 0
if (.selectionLevel == jBoard_SELECTION_LVL_BOARD) then
loop
exitwhen i == $NAME$ROWS
call .reset().row(i,i).showValue()
set i = i + 1
endloop
set .selectionLevel = jBoard_SELECTION_LVL_BOARD
elseif (.selectionLevel == jBoard_SELECTION_LVL_FIELDS) then
loop
exitwhen i == .selectionAmount
call .selection.fields[i].showValue()
set i = i + 1
endloop
elseif (.selectionLevel == jBoard_SELECTION_LVL_ROW) then
loop
exitwhen i == $NAME$COLS
call .rows[.selectionSpecial].fields[i].showValue()
set i = i + 1
endloop
elseif (.selectionLevel == jBoard_SELECTION_LVL_COL) then
loop
exitwhen i == $NAME$ROWS
call .cols[.selectionSpecial].fields[i].showValue()
set i = i + 1
endloop
elseif (.selectionLevel == jBoard_SELECTION_LVL_FLD) then
call .selection.fields[0].showValue()
endif
return this
endmethod
method hideValue takes nothing returns thistype
local integer i = 0
if (.selectionLevel == jBoard_SELECTION_LVL_BOARD) then
loop
exitwhen i == $NAME$ROWS
call .reset().row(i,i).hideValue()
set i = i + 1
endloop
set .selectionLevel = jBoard_SELECTION_LVL_BOARD
elseif (.selectionLevel == jBoard_SELECTION_LVL_FIELDS) then
loop
exitwhen i == .selectionAmount
call .selection.fields[i].hideValue()
set i = i + 1
endloop
elseif (.selectionLevel == jBoard_SELECTION_LVL_ROW) then
loop
exitwhen i == $NAME$COLS
call .rows[.selectionSpecial].fields[i].hideValue()
set i = i + 1
endloop
elseif (.selectionLevel == jBoard_SELECTION_LVL_COL) then
loop
exitwhen i == $NAME$ROWS
call .cols[.selectionSpecial].fields[i].hideValue()
set i = i + 1
endloop
elseif (.selectionLevel == jBoard_SELECTION_LVL_FLD) then
call .selection.fields[0].hideValue()
endif
return this
endmethod
method setValue takes string val returns thistype
local integer i = 0
if (.selectionLevel == jBoard_SELECTION_LVL_BOARD) then
loop
exitwhen i == $NAME$ROWS
call .reset().row(i,i).setValue(val)
set i = i + 1
endloop
set .selectionLevel = jBoard_SELECTION_LVL_BOARD
elseif (.selectionLevel == jBoard_SELECTION_LVL_FIELDS) then
loop
exitwhen i == .selectionAmount
call .selection.fields[i].setValue(val)
set i = i + 1
endloop
elseif (.selectionLevel == jBoard_SELECTION_LVL_ROW) then
loop
exitwhen i == $NAME$COLS
call .rows[.selectionSpecial].fields[i].setValue(val)
set i = i + 1
endloop
elseif (.selectionLevel == jBoard_SELECTION_LVL_COL) then
loop
exitwhen i == $NAME$ROWS
call .cols[.selectionSpecial].fields[i].setValue(val)
set i = i + 1
endloop
elseif (.selectionLevel == jBoard_SELECTION_LVL_FLD) then
call .selection.fields[0].setValue(val)
endif
return this
endmethod
method add takes integer val returns thistype
local integer i = 0
if (.selectionLevel == jBoard_SELECTION_LVL_BOARD) then
loop
exitwhen i == $NAME$ROWS
call .reset().row(i,i).add(val)
set i = i + 1
endloop
set .selectionLevel = jBoard_SELECTION_LVL_BOARD
elseif (.selectionLevel == jBoard_SELECTION_LVL_FIELDS) then
loop
exitwhen i == .selectionAmount
call .selection.fields[i].add(val)
set i = i + 1
endloop
elseif (.selectionLevel == jBoard_SELECTION_LVL_ROW) then
loop
exitwhen i == $NAME$COLS
call .rows[.selectionSpecial].fields[i].add(val)
set i = i + 1
endloop
elseif (.selectionLevel == jBoard_SELECTION_LVL_COL) then
loop
exitwhen i == $NAME$ROWS
call .cols[.selectionSpecial].fields[i].add(val)
set i = i + 1
endloop
elseif (.selectionLevel == jBoard_SELECTION_LVL_FLD) then
call .selection.fields[0].add(val)
endif
return this
endmethod
method getValue takes nothing returns string
local integer i = 0
local string s = ""
if (.selectionLevel == jBoard_SELECTION_LVL_FLD) then
set s = .selection.fields[0].getValue()
else
loop
exitwhen i == .selectionAmount
set s = s + .selection.fields[i].getValue()
set i = i + 1
exitwhen i == .selectionAmount
set s = s + "|"
endloop
endif
call .reset()
return s
endmethod
method getPrefix takes nothing returns string
local integer i = 0
local string s = ""
if (.selectionLevel == jBoard_SELECTION_LVL_FLD) then
set s = .selection.fields[0].getPrefix()
else
loop
exitwhen i == .selectionAmount
set s = s + .selection.fields[i].getPrefix()
set i = i + 1
exitwhen i == .selectionAmount
set s = s + "|"
endloop
endif
call .reset()
return s
endmethod
method getSuffix takes nothing returns string
local integer i = 0
local string s = ""
if (.selectionLevel == jBoard_SELECTION_LVL_FLD) then
set s = .selection.fields[0].getSuffix()
else
loop
exitwhen i == .selectionAmount
set s = s + .selection.fields[i].getSuffix()
set i = i + 1
exitwhen i == .selectionAmount
set s = s + "|"
endloop
endif
call .reset()
return s
endmethod
method getWidth takes nothing returns string
local integer i = 0
local string s = ""
if (.selectionLevel == jBoard_SELECTION_LVL_FLD) then
set s = .selection.fields[0].getWidth()
else
loop
exitwhen i == .selectionAmount
set s = s + .selection.fields[i].getWidth()
set i = i + 1
exitwhen i == .selectionAmount
set s = s + "|"
endloop
endif
call .reset()
return s
endmethod
method getColour takes nothing returns string
local integer i = 0
local string s = ""
if (.selectionLevel == jBoard_SELECTION_LVL_FLD) then
set s = .selection.fields[0].getColour()
else
loop
exitwhen i == .selectionAmount
set s = s + .selection.fields[i].getColour()
set i = i + 1
exitwhen i == .selectionAmount
set s = s + "|"
endloop
endif
call .reset()
return s
endmethod
method getIconPath takes nothing returns string
local integer i = 0
local string s = ""
if (.selectionLevel == jBoard_SELECTION_LVL_FLD) then
set s = .selection.fields[0].getIconPath()
else
loop
exitwhen i == .selectionAmount
set s = s + .selection.fields[i].getIconPath()
set i = i + 1
exitwhen i == .selectionAmount
set s = s + "|"
endloop
endif
call .reset()
return s
endmethod
method setName takes string s returns thistype
set .boardName = s
call MultiboardSetTitleText(.MB,"|cff"+.boardNameColour+.boardName+"|r")
return this
endmethod
method getName takes nothing returns string
call .reset()
return .boardName
endmethod
method setNameColour takes string s returns thistype
set .boardNameColour = s
call MultiboardSetTitleText(.MB,"|cff"+.boardNameColour+.boardName+"|r")
return this
endmethod
method getNameColour takes nothing returns string
call .reset()
return .boardNameColour
endmethod
method show takes nothing returns thistype
call MultiboardDisplay(.MB,true)
return this
endmethod
method hide takes nothing returns thistype
call MultiboardDisplay(.MB,false)
return this
endmethod
method clear takes nothing returns thistype
call MultiboardClear(.MB)
return this
endmethod
method fold takes nothing returns thistype
call MultiboardMinimize(.MB,true)
return this
endmethod
method unfold takes nothing returns thistype
call MultiboardMinimize(.MB,false)
return this
endmethod
method setValueR takes string val returns thistype
call .setValue(val)
call .reset()
return this
endmethod
method setColourR takes string rgb returns thistype
call .setColour(rgb)
call .reset()
return this
endmethod
method setPrefixR takes string val returns thistype
call .setPrefix(val)
call .reset()
return this
endmethod
method setSuffixR takes string val returns thistype
call .setSuffix(val)
call .reset()
return this
endmethod
method setIconPathR takes string val returns thistype
call .setIconPath(val)
call .reset()
return this
endmethod
method setWidthR takes real w returns thistype
call .setWidth(w)
call .reset()
return this
endmethod
method addR takes integer val returns thistype
call .add(val)
call .reset()
return this
endmethod
method setPlayerRowR takes integer p, integer col returns thistype
call .setPlayerRow(p,row)
call .reset()
return this
endmethod
method setPlayerColR takes integer p, integer col returns thistype
call .setPlayerCol(p,col)
call .reset()
return this
endmethod
method setNameR takes string s returns thistype
call .setName(s)
call .reset()
return this
endmethod
method setNameColourR takes string s returns thistype
call .setNameColour(s)
call .reset()
return this
endmethod
method showR takes nothing returns thistype
call .show()
call .reset()
return this
endmethod
method showIconR takes nothing returns thistype
call .showIcon()
call .reset()
return this
endmethod
method hideIconR takes nothing returns thistype
call .hideIcon()
call .reset()
return this
endmethod
method showValueR takes nothing returns thistype
call .showValue()
call .reset()
return this
endmethod
method hideValueR takes nothing returns thistype
call .hideValue()
call .reset()
return this
endmethod
method hideR takes nothing returns thistype
call .hide()
call .reset()
return this
endmethod
method clearR takes nothing returns thistype
call .clear()
call .reset()
return this
endmethod
method foldR takes nothing returns thistype
call .fold()
call .reset()
return this
endmethod
method unfoldR takes nothing returns thistype
call .unfold()
call .reset()
return this
endmethod
method destroy takes nothing returns nothing
local integer i = 0
local integer j = 0
loop
exitwhen i == $NAME$ROWS
loop
exitwhen j == $NAME$COLS
call rows[i].fields[j].destroy()
set j = j + 1
endloop
set i = i + 1
endloop
call DestroyMultiboard(.MB)
call .deallocate()
endmethod
endstruct
//! endtextmacro
/*method setItemIcon takes integer column, integer row, string iconFileName returns nothing
//Works similar to the MultiboardSetItem* functions.
//However, a value of 0 refers to the first column/row, -1 refers to all columns/rows
//Using a Column or Row higher than the current max will result in the function not doing anything.
local integer curCol = 0
local integer curRow = 0
if column > .columnCount or row > .rowCount then
return
endif
if column == -1 or row == -1 then
if column == -1 and row == -1 then
call MultiboardSetItemsIcon(.which,iconFileName)
return
elseif column == -1 then
loop
exitwhen curCol > .columnCount
call MultiboardSetItemIcon(.MBIZ[curCol * MAX_ROW_COUNT + row],iconFileName)
set curCol = curCol + 1
endloop
return
else
loop
exitwhen curRow > .rowCount
call MultiboardSetItemIcon(.MBIZ[column * MAX_ROW_COUNT + curRow],iconFileName)
set curRow = curRow + 1
endloop
return
endif
endif
call MultiboardSetItemIcon(.MBIZ[column * MAX_ROW_COUNT + row],iconFileName)
endmethod*/
//==============================================================================
// ACTUAL LIBRARY
//==============================================================================
library jBoardLib
globals
constant integer jBoard_SELECTION_LVL_BOARD = 0
constant integer jBoard_SELECTION_LVL_ROW = 1
constant integer jBoard_SELECTION_LVL_COL = 2
constant integer jBoard_SELECTION_LVL_FLD = 3
constant integer jBoard_SELECTION_LVL_FIELDS = 4
endglobals
struct jBoard
//! runtextmacro jBoardDefaults()
multiboard MB
string boardName
string boardNameColour = "ffffcc"
integer selectionLevel = 0
integer selectionSpecial = 0
integer selectionAmount = 0
integer array playerRow[12]
integer array playerCol[12]
static method create takes string boardName returns jBoard
local integer i = 0
set jB = thistype.allocate()
set jB.MB = CreateMultiboard()
set jB.boardName = boardName
call MultiboardSetTitleText(jB.MB,boardName)
call MultiboardDisplay(jB.MB,false)
return jB
endmethod
method initBoard takes nothing returns nothing
call MultiboardSetItemsValue(.MB,.defaultItemValue)
call MultiboardSetItemsIcon(.MB,defaultIconPath)
call MultiboardSetItemsStyle(.MB,.defaultShowValue,.defaultShowIcon)
call MultiboardSetItemsWidth(.MB,.defaultItemWidth)
call MultiboardDisplay(.MB,.defaultShowBoard)
endmethod
endstruct
endlibrary
//==============================================================================
// END OF jBoard ADVANCED MULTIBOARD SYSTEM
//==============================================================================//===========================================================================
// Trigger: STM
//===========================================================================
//TESH.scrollpos=31
//TESH.alwaysfold=0
//SLARK, THE MURLOC
//==By SanKakU
//==
//==Don't bother looking in the quests section for credits because you won't see them there.
//==Just find what you want here in the Trigger editor. It's all here.
library STM uses MSGS
define CREDITSFORSTM={
ICONS
kola
MODELS
republicola
SKINS
chr2
sankaku
}
define {timedmsg=DisplayTimedTextToPlayer;void=nothing
getitemGT(x, y) = {GT_AddItemAcquiredAction(function x, y)}
targetorderGT(x,y) = {GT_AddTargetOrderAction(function x, y)}
pointorderGT(x,y) = {GT_AddPointOrderAction(function x, y)}
iorderGT(x,y) = {GT_AddNoTargetOrderAction(function x, y)}
unitdiesGT(x, y) = {GT_AddUnitDiesAction(function x, y)}
effectstartGT(x, y) = {GT_AddStartsEffectAction(function x, y)}
skillGT(x, y) = {GT_AddLearnsAbilityAction(function x, y)}
STM_PUE(x,y)={TriggerRegisterPlayerUnitEvent(x,Player(6),y,null)}
}
define iconTIME="UI\\Widgets\\BattleNet\\bnet-tournament-clock.blp"
globals
endglobals
//== snippet by Jesus4Lyf
function SetDistanceToUnit takes unit y, unit x, real dist returns nothing
local real rx=GetUnitX(x)-GetUnitX(y)
local real ry=GetUnitY(x)-GetUnitY(y)
local real factor=dist/SquareRoot(rx*rx+ry*ry)
call SetUnitX(x,GetUnitX(y)+rx*factor)
call SetUnitY(x,GetUnitY(y)+ry*factor)
endfunction
function SetDistanceToXY takes real rx, real ry, unit x, real dist returns nothing
local real tx=GetUnitX(x)-rx
local real ty=GetUnitY(x)-ry
local real factor=dist/SquareRoot(tx*tx+ty*ty)
call SetUnitX(x,rx+tx*factor)
call SetUnitY(x,ry+ty*factor)
endfunction
//extension to snippet.
function getdis takes unit x, unit y returns real
local real dx = GetUnitX(x) - GetUnitX(y)
local real dy = GetUnitY(x) - GetUnitY(y)
return SquareRoot(dx * dx + dy * dy)
endfunction
function getdisr takes real x, real y, unit z returns real
local real dx = x - GetUnitX(z)
local real dy = y - GetUnitY(z)
return SquareRoot(dx * dx + dy * dy)
endfunction
//==end of extension to snippet
function GetHeroSlotMultiboard takes integer heroid, integer playerid returns integer
return heroid+((playerid - 2)*3)
endfunction
//
public function MID takes integer a, integer b, integer c, real x, real y, itempool p returns nothing
call ItemPoolAddItemType(p,a,6)//monster common itemdrop
call ItemPoolAddItemType(p,b,3)//monster uncommon itemdrop
call ItemPoolAddItemType(p,c,1)//monster rare itemdrop
call PlaceRandomItem(p,x,y)
endfunction
//not sure if i'm going to end up using this function, but i used to use it so...here it is
public function IUTNI takes unit u, unittype ut returns boolean
return IsUnitType(u, ut) and IsUnitIllusion(u)==false
endfunction
//this is an interesting function, i need to write more like this
public function IUIDNI takes unit u, integer uid returns boolean
return GetUnitTypeId(u)==uid and IsUnitIllusion(u)==false
endfunction
endlibrary
//===========================================================================
// Trigger: TimerEvents
//===========================================================================
//TESH.scrollpos=0
//TESH.alwaysfold=0
scope TimerEvents initializer I
globals
private boolean debugmode=true
endglobals
private function mbtime takes nothing returns boolean
call ConditionalTriggerExecute( gg_trg_mbSTM )
call SetPlayerState(Player(6), PLAYER_STATE_RESOURCE_GOLD, 1)
return false
endfunction
private function mbtimeaddsec takes nothing returns boolean
local integer x=S2I(jBoard_STM.field(0,1).getSuffix())+1
if x==60 then
call jBoard_STM.field(0,1).setSuffix("0")
set x=S2I(jBoard_STM.field(0,1).getPrefix())+1
if x==60 then
call jBoard_STM.field(0,1).setPrefix("0")
return false
endif
call jBoard_STM.field(0,1).setPrefix(I2S(x))
return false
endif
call jBoard_STM.field(0,1).setSuffix(I2S(x))
return false
endfunction
globals
group TIMERGROUP=CreateGroup()
endglobals
private function ru0 takes nothing returns boolean
if GetUnitAbilityLevel(GetFilterUnit(), 'A0C3')>1 then
call IssuePointOrder(GetFilterUnit(), "attack", 3000.0,3000.0 )
endif
return false
endfunction
private function ru1 takes nothing returns boolean
if GetUnitAbilityLevel(GetFilterUnit(), 'A0C3')>1 then
call IssuePointOrder(GetFilterUnit(), "attack", -3000.0,-3000.0 )
endif
return false
endfunction
private function removeall takes nothing returns nothing
call GroupEnumUnitsOfPlayer(TIMERGROUP, Player(0), Filter(function ru0))
call GroupEnumUnitsOfPlayer(TIMERGROUP, Player(1), Filter(function ru1))
endfunction
private function fbf takes nothing returns boolean
call removeall()
return false
endfunction//
public function I takes nothing returns nothing
local trigger t = CreateTrigger( )
call TriggerRegisterTimerEvent( t, 1.0 ,false)
call TriggerAddCondition( t,Condition( function mbtime ))
set t= CreateTrigger()
call TriggerRegisterTimerEvent( t, 1.0 ,true)
call TriggerAddCondition( t,Condition( function mbtimeaddsec ))
endfunction
endscope//===========================================================================
// Trigger: mbSTM
//===========================================================================
//TESH.scrollpos=0
//TESH.alwaysfold=0
library mbSTM initializer Init requires jBoardLib
globals
MyBoard jBoard_STM
jBoard jB
endglobals
//! runtextmacro jBoardCreate("MyBoard","1","2")
private function Actions takes nothing returns nothing
set jBoard_STM = MyBoard.create(".")
call jBoard_STM.col(0,0).hideIconR().field(0,0).hideValue().showIcon().setIconPathR(iconTIME)
call jBoard_STM.field(0,1).hideIcon().setPrefix("0").setSuffix("0").setValueR(":")
endfunction
public function Init takes nothing returns nothing
set gg_trg_mbSTM =CreateTrigger()
call TriggerAddAction(gg_trg_mbSTM,function Actions)
endfunction
endlibrary//===========================================================================
// Trigger: TimerUtils
//===========================================================================
//TESH.scrollpos=56
//TESH.alwaysfold=0
library_once TimerUtils initializer init
//*********************************************************************
//* TimerUtils (Blue flavor for 1.23b or later)
//* ----------
//*
//* To implement it , create a custom text trigger called TimerUtils
//* and paste the contents of this script there.
//*
//* To copy from a map to another, copy the trigger holding this
//* library to your map.
//*
//* (requires vJass) More scripts: htt://www.wc3campaigns.net
//*
//* For your timer needs:
//* * Attaching
//* * Recycling (with double-free protection)
//*
//* set t=NewTimer() : Get a timer (alternative to CreateTimer)
//* ReleaseTimer(t) : Relese a timer (alt to DestroyTimer)
//* SetTimerData(t,2) : Attach value 2 to timer
//* GetTimerData(t) : Get the timer's value.
//* You can assume a timer's value is 0
//* after NewTimer.
//*
//* Blue Flavor: Slower than the red flavor, it got a 408000 handle id
//* limit, which means that if more than 408000 handle ids
//* are used in your map, TimerUtils might fail, this
//* value is quite big and it is much bigger than the
//* timer limit in Red flavor.
//*
//********************************************************************
//==================================================================================================
globals
private hashtable hasht //I <3 blizz
endglobals
//It is dependent on jasshelper's recent inlining optimization in order to perform correctly.
function SetTimerData takes timer t, integer value returns nothing
call SaveInteger(hasht,0, GetHandleId(t), value)
endfunction
function GetTimerData takes timer t returns integer
return LoadInteger(hasht, 0, GetHandleId(t))
endfunction
//==========================================================================================
globals
private timer array tT
private integer tN = 0
private constant integer HELD=0x28829022
//use a totally random number here, the more improbable someone uses it, the better.
endglobals
//==========================================================================================
function NewTimer takes nothing returns timer
if (tN==0) then
set tT[0]=CreateTimer()
else
set tN=tN-1
endif
call SetTimerData(tT[tN],0)
return tT[tN]
endfunction
//==========================================================================================
function ReleaseTimer takes timer t returns nothing
if(t==null) then
debug call BJDebugMsg("Warning: attempt to release a null timer")
return
endif
if (tN==8191) then
debug call BJDebugMsg("Warning: Timer stack is full, destroying timer!!")
//stack is full, the map already has much more troubles than the chance of bug
call DestroyTimer(t)
else
call PauseTimer(t)
if(GetTimerData(t)==HELD) then
debug call BJDebugMsg("Warning: ReleaseTimer: Double free!")
return
endif
call SetTimerData(t,HELD)
set tT[tN]=t
set tN=tN+1
endif
endfunction
private function init takes nothing returns nothing
set hasht = InitHashtable()
endfunction
endlibrary
//===========================================================================
// Trigger: xebasic Copy
//===========================================================================
//TESH.scrollpos=0
//TESH.alwaysfold=0
library xebasic
//**************************************************************************
//
// xebasic 0.4
// =======
// XE_DUMMY_UNITID : Rawcode of the dummy unit in your map. It should
// use the dummy.mdx model, so remember to import it as
// well, just use copy&paste to copy the dummy from the
// xe map to yours, then change the rawcode.
//
// XE_HEIGHT_ENABLER: Medivh's raven form ability, you may need to change
// this rawcode to another spell that morphs into a flier
// in case you modified medivh's spell in your map.
//
// XE_TREE_RECOGNITION: The ancients' Eat tree ability, same as with medivh
// raven form, you might have to change it.
//
// XE_ANIMATION_PERIOD: The global period of animation used by whatever
// timer that depends on it, if you put a low value
// the movement will look good but it may hurt your
// performance, if instead you use a high value it
// will not lag but will be fast.
//
// XE_MAX_COLLISION_SIZE: The maximum unit collision size in your map, if
// you got a unit bigger than 197.0 it would be
// a good idea to update this constant, since some
// enums will not find it. Likewise, if none of
// your units can go bellow X and X is much smaller
// than 197.0, it would be a good idea to update
// as well, since it will improve the performance
// those enums.
//
// Notice you probably don't have to update this library, unless I specify
// there are new constants which would be unlikely.
//
//**************************************************************************
//===========================================================================
globals
constant integer XE_DUMMY_UNITID = 'e000'
constant integer XE_HEIGHT_ENABLER = 'Amrf'
constant integer XE_TREE_RECOGNITION = 'Aeat'
constant real XE_ANIMATION_PERIOD = 0.025
constant real XE_MAX_COLLISION_SIZE = 197.0
endglobals
endlibrary
//===========================================================================
// Trigger: xedamage Copy
//===========================================================================
//TESH.scrollpos=0
//TESH.alwaysfold=0
library xedamage initializer init requires xebasic
//************************************************************************
// xedamage 0.8
// --------
// For all your damage and targetting needs.
//
//************************************************************************
//===========================================================================================================
globals
private constant integer MAX_SUB_OPTIONS = 3
private constant real FACTOR_TEST_DAMAGE = 0.01
// a low damage to do on units to test their damage factors for specific
// attacktype/damagetype combos.
// You'll need something as high as 20.0 to make it work well with armor resistances.
// (Yes, you read it correctly, 20 ...
//
// If you use such a large value, there may be conflicts with some things relying on damage
// (ie they are not away of the isDummyDamage tag that xedamage posseses.) which may be quite bad if you think about it...
// then maybe it is better to change it to 0.01 ... then will work fine, just fine - but it will generally ignore armor -
// I am leaving it as 0.01 by default, because honestly, I'd rather make it ignore armor than have a lot of people sending me
// rants about how they detect 20.0 damage where none is visible...
private constant real MAX_DAMAGE_FACTOR = 3.00
// The maximum damage factor in the map. I think 3 is fine.
//=======================================================
private constant real EPSILON = 0.000000001
private unit dmger
private constant integer MAX_SPACE = 8190 // MAX_SPACE/MAX_SUB_OPTIONS is the instance limit for xedamage, usually big enough...
endglobals
private keyword structInit
struct xedamage[MAX_SPACE]
//----
// fields and methods for a xedamage object, they aid determining valid targets and special
// damage factor conditions.
//
// Notice the default values.
//
boolean damageSelf = false // the damage and factor methods usually have a source unit parameter
// xedamage would consider this unit as immune unless you set damageSelf to true
boolean damageAllies = false // Alliance dependent target options.
boolean damageEnemies = true // *
boolean damageNeutral = true // *
boolean ranged = true // Is the attack ranged? This has some effect on the AI of the affected units
// true by default, you may not really need to modify this.
boolean visibleOnly = false // Should only units that are visible for source unit's owner be affected?
boolean deadOnly = false // Should only corpses be affected by "the damage"? (useful when using xedamage as a target selector)
boolean alsoDead = false // Should even corpses and alive units be considered?
boolean damageTrees = true //Also damage destructables? Notice this is used only in certain methods.
//AOE for example targets a circle, so it can affect the destructables
//in that circle, a custom spell using xedamage for targetting configuration
//could also have an if-then-else implemented so it can verify if it is true
//then affect trees manually.
//
// Damage type stuff:
// .dtype : the "damagetype" , determines if the spell is physical, magical or ultimate.
// .atype : the "attacktype" , deals with armor.
// .wtype : the "weapontype" , determines the sound effect to be played when damage is done.
//
// Please use common.j/blizzard.j/ some guide to know what damage/attack/weapon types can be used
//
damagetype dtype = DAMAGE_TYPE_UNIVERSAL
attacktype atype = ATTACK_TYPE_MAGIC
weapontype wtype = WEAPON_TYPE_WHOKNOWS
//
// Damage type 'tag' people might use xedamage.isInUse() to detect xedamage usage, there are other static
// variables like xedamage.CurrentDamageType and xedamage.CurrentDamageTag. The tag allows you to specify
// a custom id for the damage type ** Notice the tag would aid you for some spell stuff, for example,
// you can use it in a way similar to Rising_Dusk's damage system.
//
integer tag = 0
//
// if true, forceDamage will make xedamage ignore dtype and atype and try as hard as possible to deal 100%
// damage.
boolean forceDamage = false
//
// Ally factor! Certain spells probably have double purposes and heal allies while harming enemies. This
// field allows you to do such thing.
//
real allyfactor = 1.0
//
// field: .exception = SOME_UNIT_TYPE
// This field adds an exception unittype (classification), if the unit belongs to this unittype it will
// be ignored.
//
method operator exception= takes unittype ut returns nothing
set this.use_ex=true
set this.ex_ut=ut
endmethod
//
// field: .required = SOME_UNIT_TYPE
// This field adds a required unittype (classification), if the unit does not belong to this unittype
// it will be ignored.
//
method operator required= takes unittype ut returns nothing
set this.use_req=true
set this.req_ut=ut
endmethod
private boolean use_ex = false
private unittype ex_ut = null
private boolean use_req = false
private unittype req_ut = null
private unittype array fct[MAX_SUB_OPTIONS]
private real array fc[MAX_SUB_OPTIONS]
private integer fcn=0
//
// method .factor(SOME_UNIT_TYPE, factor)
// You might call factor() if you wish to specify a special damage factor for a certain classification,
// for example call d.factor(UNIT_TYPE_STRUCTURE, 0.5) makes xedamage do half damage to structures.
//
method factor takes unittype ut, real fc returns nothing
if(this.fcn==MAX_SUB_OPTIONS) then
debug call BJDebugMsg("In one instance of xedamage, you are doing too much calls to factor(), please increase MAX_SUB_OPTIONS to allow more, or cut the number of factor() calls")
return
endif
set this.fct[this.fcn] = ut
set this.fc[this.fcn] = fc
set this.fcn = this.fcn+1
endmethod
private integer array abifct[MAX_SUB_OPTIONS]
private real array abifc[MAX_SUB_OPTIONS]
private integer abifcn=0
//
// method .abilityFactor('abil', factor)
// You might call abilityFactor() if you wish to specify a special damage factor for units that have a
// certain ability/buff.
// for example call d.abilityFactor('A000', 1.5 ) makes units that have the A000 ability take 50% more
// damage than usual.
//
method abilityFactor takes integer abilityId, real fc returns nothing
if(this.abifcn==MAX_SUB_OPTIONS) then
debug call BJDebugMsg("In one instance of xedamage, you are doing too much calls to abilityFactor(), please increase MAX_SUB_OPTIONS to allow more, or cut the number of abilityFactor() calls")
return
endif
set this.abifct[this.abifcn] = abilityId
set this.abifc[this.abifcn] = fc
set this.abifcn = this.abifcn+1
endmethod
private boolean usefx = false
private string fxpath
private string fxattach
//
// method .useSpecialEffect("effect\\path.mdl", "origin")
// Makes it add (and destroy) an effect when damage is performed.
//
method useSpecialEffect takes string path, string attach returns nothing
set this.usefx = true
set this.fxpath=path
set this.fxattach=attach
endmethod
//********************************************************************
//* Now, the usage stuff:
//*
//================================================================================
// static method xedamage.isInUse() will return true during a unit damaged
// event in case this damage was caused by xedamage, in this case, you can
// read variables like CurrentDamageType, CurrentAttackType and CurrentDamageTag
// to be able to recognize what sort of damage was done.
//
readonly static damagetype CurrentDamageType=null
readonly static attacktype CurrentAttackType=null
readonly static integer CurrentDamageTag =0
private static integer inUse = 0
static method isInUse takes nothing returns boolean
return (inUse>0) //inline friendly.
endmethod
readonly static boolean isDummyDamage = false
//========================================================================================================
// This function calculates the damage factor caused by a certain attack and damage
// type, it is static : xedamage.getDamageTypeFactor(someunit, ATTAcK_TYPE_NORMAL, DAMAGE_TYPE_FIRE, 100)
//
static method getDamageTypeFactor takes unit u, attacktype a, damagetype d returns real
local real hp=GetWidgetLife(u)
local real mana=GetUnitState(u,UNIT_STATE_MANA)
local real r
local real fc = FACTOR_TEST_DAMAGE
//Since a unit is in that point, we don't need checks.
call SetUnitX(dmger,GetUnitX(u))
call SetUnitY(dmger,GetUnitY(u))
call SetUnitOwner(dmger,GetOwningPlayer(u),false)
set r=hp
if (hp< FACTOR_TEST_DAMAGE*MAX_DAMAGE_FACTOR) then
call SetWidgetLife(u, hp + FACTOR_TEST_DAMAGE*MAX_DAMAGE_FACTOR )
set r = hp + FACTOR_TEST_DAMAGE*MAX_DAMAGE_FACTOR
set fc = GetWidgetLife(u)-hp + EPSILON
endif
set isDummyDamage = true
call UnitDamageTarget(dmger,u, fc ,false,false,a,d,null)
static if DEBUG_MODE then
if IsUnitType(u, UNIT_TYPE_DEAD) and (hp>0.405) then
call BJDebugMsg("xedamage: For some reason, the unit being tested by getDamageTypeFactor has died. Verify MAX_DAMAGE_FACTOR is set to a correct value. ")
endif
endif
set isDummyDamage = false
call SetUnitOwner(dmger,Player(15),false)
if (mana>GetUnitState(u,UNIT_STATE_MANA)) then
//Unit had mana shield, return 1 and restore mana too.
call SetUnitState(u,UNIT_STATE_MANA,mana)
set r=1
else
set r= (r-GetWidgetLife(u)) / fc
endif
call SetWidgetLife(u,hp)
return r
endmethod
private method getTargetFactorCore takes unit source, unit target, boolean usetypes returns real
local player p=GetOwningPlayer(source)
local boolean allied=IsUnitAlly(target,p)
local boolean enemy =IsUnitEnemy(target,p)
local boolean neutral=allied
local real f
local real negf=1.0
local integer i
if(this.damageAllies != this.damageNeutral) then
set neutral= allied and not (GetPlayerAlliance(GetOwningPlayer(target),p, ALLIANCE_HELP_REQUEST ))
//I thought accuracy was not as important as speed , I think that REQUEST is false is enough to consider
// it neutral.
//set neutral= allied and not (GetPlayerAlliance(GetOwningPlayer(target),p, ALLIANCE_HELP_RESPONSE ))
//set neutral= allied and not (GetPlayerAlliance(GetOwningPlayer(target),p, ALLIANCE_SHARED_XP ))
//set neutral= allied and not (GetPlayerAlliance(GetOwningPlayer(target),p, ALLIANCE_SHARED_SPELLS ))
set allied= allied and not(neutral)
endif
if (not this.damageAllies) and allied then
return 0.0
elseif (not this.damageEnemies) and enemy then
return 0.0
elseif( (not this.damageSelf) and (source==target) ) then
return 0.0
elseif (not this.damageNeutral) and neutral then
return 0.0
elseif( this.use_ex and IsUnitType(target, this.ex_ut) ) then
return 0.0
elseif( this.visibleOnly and not IsUnitVisible(target,p) ) then
return 0.0
elseif ( this.deadOnly and not IsUnitType(target,UNIT_TYPE_DEAD) ) then
return 0.0
elseif ( not(this.alsoDead) and IsUnitType(target,UNIT_TYPE_DEAD) ) then
return 0.0
endif
set f=1.0
if ( IsUnitAlly(target,p) ) then
set f=f*this.allyfactor
if(f<=-EPSILON) then
set f=-f
set negf=-1.0
endif
endif
if (this.use_req and not IsUnitType(target,this.req_ut)) then
return 0.0
endif
set i=.fcn-1
loop
exitwhen (i<0)
if( IsUnitType(target, this.fct[i] ) ) then
set f=f*this.fc[i]
if(f<=-EPSILON) then
set f=-f
set negf=-1.0
endif
endif
set i=i-1
endloop
set i=.abifcn-1
loop
exitwhen (i<0)
if( GetUnitAbilityLevel(target,this.abifct[i] )>0 ) then
set f=f*this.abifc[i]
if(f<=-EPSILON) then
set f=-f
set negf=-1.0
endif
endif
set i=i-1
endloop
set f=f*negf
if ( f<EPSILON) and (f>-EPSILON) then
return 0.0
endif
if( this.forceDamage or not usetypes ) then
return f
endif
set f=f*xedamage.getDamageTypeFactor(target,this.atype,this.dtype)
if ( f<EPSILON) and (f>-EPSILON) then
return 0.0
endif
return f
endmethod
//====================================================================
// With this you might decide if a unit is a valid target for a spell.
//
method getTargetFactor takes unit source, unit target returns real
return this.getTargetFactorCore(source,target,true)
endmethod
//======================================================================
// a little better, I guess
//
method allowedTarget takes unit source, unit target returns boolean
return (this.getTargetFactorCore(source,target,false)!=0.0)
endmethod
//=======================================================================
// performs damage to the target unit, for unit 'source'.
//
method damageTarget takes unit source, unit target, real damage returns boolean
local damagetype dt=.CurrentDamageType
local attacktype at=.CurrentAttackType
local integer tg=.CurrentDamageTag
local real f = this.getTargetFactorCore(source,target,false)
local real pl
if(f!=0.0) then
set .CurrentDamageType = .dtype
set .CurrentAttackType = .atype
set .CurrentDamageTag = .tag
set .inUse = .inUse +1
set pl=GetWidgetLife(target)
call UnitDamageTarget(source,target, f*damage, true, .ranged, .atype, .dtype, .wtype )
set .inUse = .inUse -1
set .CurrentDamageTag = tg
set .CurrentDamageType = dt
set .CurrentAttackType = at
if(pl != GetWidgetLife(target) ) then
if(usefx) then
call DestroyEffect( AddSpecialEffectTarget(this.fxpath, target, this.fxattach) )
endif
return true
endif
endif
return false
endmethod
//=======================================================================================
// The same as damageTarget, but it forces a specific damage value, good if you already
// know the target.
//
method damageTargetForceValue takes unit source, unit target, real damage returns nothing
local damagetype dt=.CurrentDamageType
local attacktype at=.CurrentAttackType
local integer tg=.CurrentDamageTag
set .CurrentDamageType = .dtype
set .CurrentAttackType = .atype
set .CurrentDamageTag = .tag
if( usefx) then
call DestroyEffect( AddSpecialEffectTarget(this.fxpath, target, this.fxattach) )
endif
set .inUse = .inUse +1
call UnitDamageTarget(source,target, damage, true, .ranged, null, null, .wtype )
set .inUse = .inUse -1
set .CurrentDamageTag = tg
set .CurrentDamageType = dt
set .CurrentAttackType = at
endmethod
//=====================================================================================
// Notice: this will not Destroy the group, but it will certainly empty the group.
//
method damageGroup takes unit source, group targetGroup, real damage returns integer
local damagetype dt=.CurrentDamageType
local attacktype at=.CurrentAttackType
local integer tg=.CurrentDamageTag
local unit target
local real f
local integer count=0
local real hp
set .CurrentDamageType = .dtype
set .CurrentAttackType = .atype
set .CurrentDamageTag = .tag
set .inUse = .inUse +1
loop
set target=FirstOfGroup(targetGroup)
exitwhen (target==null)
call GroupRemoveUnit(targetGroup,target)
set f= this.getTargetFactorCore(source,target,false)
if (f!=0.0) then
set count=count+1
if(usefx) then
set hp = GetWidgetLife(target)
endif
call UnitDamageTarget(source,target, f*damage, true, .ranged, .atype, .dtype, .wtype )
if(usefx and (hp > GetWidgetLife(target)) ) then
call DestroyEffect( AddSpecialEffectTarget(this.fxpath, target, this.fxattach) )
endif
endif
endloop
set .inUse = .inUse -1
set .CurrentDamageTag=tg
set .CurrentDamageType = dt
set .CurrentAttackType = at
return count
endmethod
private static xedamage instance
private integer countAOE
private unit sourceAOE
private real AOEx
private real AOEy
private real AOEradius
private real AOEdamage
private static boolexpr filterAOE
private static boolexpr filterDestAOE
private static group enumgroup
private static rect AOERect
private static method damageAOE_Enum takes nothing returns boolean
local unit target=GetFilterUnit()
local xedamage this=.instance //adopting a instance.
local real f
local real hp
if( not IsUnitInRangeXY(target,.AOEx, .AOEy, .AOEradius) ) then
set target=null
return false
endif
set f=.getTargetFactorCore(.sourceAOE, target, false)
if(f!=0.0) then
set .countAOE=.countAOE+1
if(this.usefx) then
set hp =GetWidgetLife(target)
endif
call UnitDamageTarget(.sourceAOE,target, f*this.AOEdamage, true, .ranged, .atype, .dtype, .wtype )
if(this.usefx and (hp > GetWidgetLife(target) ) ) then
call DestroyEffect( AddSpecialEffectTarget(this.fxpath, target, this.fxattach) )
endif
endif
set .instance= this //better restore, nesting IS possible!
set target=null
return false
endmethod
private static method damageAOE_DestructablesEnum takes nothing returns boolean
local destructable target=GetFilterDestructable()
local xedamage this=.instance //adopting a instance.
local real dx=.AOEx-GetDestructableX(target)
local real dy=.AOEy-GetDestructableY(target)
if( dx*dx + dy*dy >= .AOEradius+EPSILON ) then
set target=null
return false
endif
set .countAOE=.countAOE+1
if(.usefx) then
call DestroyEffect( AddSpecialEffectTarget(this.fxpath, target, this.fxattach) )
endif
call UnitDamageTarget(.sourceAOE,target, this.AOEdamage, true, .ranged, .atype, .dtype, .wtype )
set .instance= this //better restore, nesting IS possible!
set target=null
return false
endmethod
//==========================================================================================
// will affect trees if damageTrees is true!
//
method damageAOE takes unit source, real x, real y, real radius, real damage returns integer
local damagetype dt=.CurrentDamageType
local attacktype at=.CurrentAttackType
local integer tg=.CurrentDamageTag
set .CurrentDamageType = .dtype
set .CurrentAttackType = .atype
set .CurrentDamageTag = .tag
set .inUse = .inUse +1
set .instance=this
set .countAOE=0
set .sourceAOE=source
set .AOEx=x
set .AOEradius=radius
set .AOEy=y
set .AOEdamage=damage
call GroupEnumUnitsInRange(.enumgroup,x,y,radius+XE_MAX_COLLISION_SIZE, .filterAOE)
if(.damageTrees) then
call SetRect(.AOERect, x-radius, y-radius, x+radius, y+radius)
set .AOEradius=.AOEradius*.AOEradius
call EnumDestructablesInRect(.AOERect, .filterDestAOE, null)
endif
set .inUse = .inUse -1
set .CurrentDamageTag = tg
set .CurrentDamageType = dt
set .CurrentAttackType = at
return .countAOE
endmethod
method damageAOELoc takes unit source, location loc, real radius, real damage returns integer
return .damageAOE(source, GetLocationX(loc), GetLocationY(loc), radius, damage)
endmethod
//==========================================================================================
// only affects trees, ignores damageTrees
//
method damageDestructablesAOE takes unit source, real x, real y, real radius, real damage returns integer
set .instance=this
set .countAOE=0
set .sourceAOE=source
set .AOEx=x
set .AOEradius=radius*radius
set .AOEy=y
set .AOEdamage=damage
//if(.damageTrees) then
call SetRect(.AOERect, x-radius, y-radius, x+radius, y+radius)
call EnumDestructablesInRect(.AOERect, .filterDestAOE, null)
//endif
return .countAOE
endmethod
method damageDestructablesAOELoc takes unit source, location loc, real radius, real damage returns integer
return .damageDestructablesAOE(source,GetLocationX(loc), GetLocationY(loc), radius, damage)
endmethod
//'friend' with the library init
static method structInit takes nothing returns nothing
set .AOERect= Rect(0,0,0,0)
set .filterAOE= Condition(function xedamage.damageAOE_Enum)
set .filterDestAOE = Condition( function xedamage.damageAOE_DestructablesEnum)
set .enumgroup = CreateGroup()
endmethod
endstruct
private function init takes nothing returns nothing
set dmger=CreateUnit(Player(15), XE_DUMMY_UNITID , 400,-400,0.)
call UnitAddAbility(dmger,'Aloc')
call xedamage.structInit()
endfunction
endlibrary
//===========================================================================
// Trigger: xepreload Copy Copy
//===========================================================================
//TESH.scrollpos=-1
//TESH.alwaysfold=0
library xepreload initializer init requires xebasic, optional TimerUtils
//******************************************************************************
// xepreload 0.8
// ---------
// Ah, the joy of preloading abilities, it is such a necessary evil...
// Notice you are not supposed to use this system in places outside map init
//
// This one does the preloading and tries to minimize the hit on loading time
// for example, it only needs one single native call per ability preloaded.
//
//******************************************************************************
//==============================================================================
globals
private unit dum=null
endglobals
private keyword DebugIdInteger2IdString
//inline friendly (when debug mode is off..)
function XE_PreloadAbility takes integer abilid returns nothing
call UnitAddAbility(dum, abilid)
/*static if DEBUG_MODE then
if(dum==null) then
call BJDebugMsg("XE_PreloadAbility: do not load abilities after map init or during structs' onInit")
elseif GetUnitAbilityLevel(dum, abilid) == 0 then
call BJDebugMsg("XE_PreloadAbility: Ability "+DebugIdInteger2IdString.evaluate(abilid)+" does not exist.")
endif
endif*/
endfunction
// ................................................................................
//================================================================================
// Convert a integer id value into a 4-letter id code.
// * Taken from cheats.j so I don't have to code it again.
// * Used only on debug so making a whole library for it seemed silly
// * Private so people don't begin using xepreload just to call this function....
// * It will not work correctly if you paste this code in the custom script section
// due to the infamous % bug. Then again, if you do that then you probably
// deserve it....
//
private function DebugIdInteger2IdString takes integer value returns string
local string charMap = ".................................!.#$%&'()*+,-./0123456789:;<=>.@ABCDEFGHIJKLMNOPQRSTUVWXYZ[.]^_`abcdefghijklmnopqrstuvwxyz{|}~................................................................................................................................."
local string result = ""
local integer remainingValue = value
local integer charValue
local integer byteno
set byteno = 0
loop
set charValue = ModuloInteger(remainingValue, 256)
set remainingValue = remainingValue / 256
set result = SubString(charMap, charValue, charValue + 1) + result
set byteno = byteno + 1
exitwhen byteno == 4
endloop
return result
endfunction
//--------------------------------
private function kill takes nothing returns nothing
call RemoveUnit(dum)
set dum=null
// static if (LIBRARY_TimerUtils ) then
call ReleaseTimer( GetExpiredTimer() )
// else
// call DestroyTimer(GetExpiredTimer())
//endif
endfunction
private function init takes nothing returns nothing
local timer t
set dum = CreateUnit( Player(15), XE_DUMMY_UNITID, 400,-400,0)
if( dum == null) then
debug call BJDebugMsg("xePreload : XE_DUMMY_UNITID ("+DebugIdInteger2IdString.evaluate(XE_DUMMY_UNITID)+") not added correctly to the map.")
endif
//static if (LIBRARY_TimerUtils) then
set t=NewTimer()
// else
set t=CreateTimer()
// endif
call TimerStart(t,0.0,false,function kill)
set t=null
endfunction
endlibrary
//===========================================================================
// Trigger: xecast Copy Copy
//===========================================================================
//TESH.scrollpos=-1
//TESH.alwaysfold=0
library xecast initializer init requires xebasic
//******************************************************************************
// xecast 0.7
// ------
// Because dummy casters REALLY ARE this complicated!
//
//******************************************************************************
//==============================================================================
globals
private constant integer MAXINSTANCES = 8190
//this is a lot, unless you leak xecast objects (which is a bad thing)
private constant integer INITIAL_DUMMY_COUNT = 12
//don't allow to keep more than DUMMY_STACK_LIMIT innactive dummy units :
private constant integer DUMMY_STACK_LIMIT = 50
// If your map does not give visibility to all players, or
// for other reasons, you might want xecast to work on
// units that are not visible to the player, in that case
// change this to true, else it is just a performance loss.
private constant boolean FORCE_INVISIBLE_CAST = false
//When AUTO_RESET_MANA_COOLDOWN is set to true, xecast will reset
// the dummy unit's cooldown and mana before casting every spell.
// it is a performance penalty, so if you are sure that all dummy spells
// in your map got 0 mana and cooldown cost, you may set it to false.
private constant boolean AUTO_RESET_MANA_COOLDOWN = true
endglobals
//=========================================================================
// Please notice all textmacros in this library are considered private.
// in other words: DON'T RUN THOSE TEXTMACROS!
//
private keyword structinit
globals
private real EPSILON=0.001 //noticed in war3 this is the sort of precision we want...
endglobals
struct xecast[MAXINSTANCES]
public integer abilityid = 0 //ID (rawcode) of the ability to cast
public integer level = 1 //Level of the ability to cast
public real recycledelay = 0.0 //Please notice, some spells need a recycle delay
// This is, a time period before they get recycle.
// For example, some spells are not instant, there is
// also the problem with damaging spells, this recycle
// delay must be large enough to contain all the time
// in which the spell can do damage.
public player owningplayer=Player(15) //which player to credit for the ability cast?
//notice this can also affect what units are targeteable
//==================================================================================================
// You need an order id for the ability so the dummy unit is able to cast it, two ways to assign it
// set instance.orderid = 288883 //would assign an integer orderid
// set instance.orderstring = "chainlightning" //would assign an orderstring
// (as those in the object editor)
//
method operator orderid= takes integer v returns nothing
set .oid=v
endmethod
method operator orderstring= takes string s returns nothing
set .oid=OrderId(s)
endmethod
//=================================================================================================
// Finally, you can determine from which point to cast the ability: z is the height coordinate.
//
public boolean customsource=false //Use a custom casting source?
public real sourcex // Determine the casting source for the dummy spell, require customsource =true
public real sourcey // You might prefer to use the setSourcePoint method
public real sourcez=0.0 //
method setSourcePoint takes real x, real y, real z returns nothing
set .sourcex=x
set .sourcey=y
set .sourcez=z
set .customsource=true
endmethod
method setSourceLoc takes location loc, real z returns nothing
set .sourcex=GetLocationX(loc)
set .sourcey=GetLocationY(loc)
set .sourcez=z
set .customsource=true
endmethod
private boolean autodestroy = false
//========================================================================================================
// you are always allowed to use .create() but you can also use createBasic which sets some things that
// are usually necessary up.
//
public static method createBasic takes integer abilityID, integer orderid, player owner returns xecast
local xecast r=xecast.allocate()
if(r==0) then
debug call BJDebugMsg("Warning: unbelievable but you actually used all xecast instances in your map! Please make sure you are not forgetting to destroy those what you create intensively, if that's not the case, then you'll have to increase xecast MAXINSTANCES")
endif
set r.oid=orderid
set r.abilityid=abilityID
set r.owningplayer=owner
return r
endmethod
//========================================================================================================
// Just like the above one, but the instance will self destruct after a call to any cast method
// (recommended)
//
public static method createBasicA takes integer abilityID, integer orderid, player owner returns xecast
local xecast r=xecast.allocate()
if(r==0) then
debug call BJDebugMsg("Warning: unbelievable but you actually used all xecast instances in your map! Please make sure you are not forgetting to destroy those what you create intensively, if that's not the case, then you'll have to increase xecast MAXINSTANCES")
endif
set r.oid=orderid
set r.abilityid=abilityID
set r.owningplayer=owner
set r.autodestroy=true
return r
endmethod
//==========================================================================================================
// Just like create, but the struct instance self destructs after a call to any cast method
// (Recommended)
//
public static method createA takes nothing returns xecast
local xecast r=xecast.allocate()
set r.autodestroy=true
return r
endmethod
//==========================================================================================================
// So, create the dummy, assign options and cast the skill!
// .castOnTarget(w) : If you want to hit a widget w with the ability
// .castOnPoint(x,y) : If you want to hit a point (x,y) with the ability
// .castInPoint(x,y) : For spells like warstomp which do not have a target.
// .castOnAOE(x,y,radius) : Classic area of effect cast. Considers collision size
// .castOnGroup(g) : Cast unit the unit group g, notice it will empty the group yet not destroy it.
//
//**********************************************************************************************************
// The implementation of such methods follows:
private static unit array dummystack
private static integer top=0
private static unit instantdummy
private integer oid=0
private static timer gametime
private static timer T
private static unit array recycle
private static real array expiretime
private static integer rn=0
//==========================================================================================================
// private dorecycle method, sorry but I need this up here.
//
private static method dorecycle takes nothing returns nothing
local unit u =.recycle[0]
local integer l
local integer r
local integer p
local real lt
call UnitRemoveAbility(u,GetUnitUserData(u))
call SetUnitUserData(u,0)
call SetUnitFlyHeight(u,0,0)
call PauseUnit(u,false)
if(.top==DUMMY_STACK_LIMIT) then
call RemoveUnit(u)
else
set .dummystack[.top]=u
set .top=.top+1
endif
set .rn=.rn-1
if(.rn==0) then
return
endif
set p=0
set lt=.expiretime[.rn]
loop
set l=p*2+1
exitwhen l>=.rn
set r=p*2+2
if(r>=.rn)then
if(.expiretime[l]<lt) then
set .expiretime=.expiretime[l]
set .recycle=.recycle[l]
set p=l
else
exitwhen true
endif
elseif (lt<=.expiretime[l]) and (lt<=.expiretime[r]) then
exitwhen true
elseif (.expiretime[l]<.expiretime[r]) then
set .expiretime=.expiretime[l]
set .recycle=.recycle[l]
set p=l
else
set .expiretime=.expiretime[r]
set .recycle=.recycle[r]
set p=r
endif
endloop
set .recycle=.recycle[.rn]
set .expiretime=lt
call TimerStart(.T, .expiretime[0]-TimerGetElapsed(.gametime), false, function xecast.dorecycle)
endmethod
private static trigger abilityRemove
// Repetitive process and no inline implemented for large functions, so for now it is a textmacro:
//! textmacro xecast_allocdummy
if(.recycledelay<EPSILON) then
set dummy=.instantdummy
call SetUnitOwner(dummy,.owningplayer,false)
elseif (.top>0) then
set .top=.top-1
set dummy=.dummystack[.top]
call SetUnitOwner(dummy,.owningplayer,false)
else
set dummy=CreateUnit(.owningplayer,XE_DUMMY_UNITID,400,-400,0)
call TriggerRegisterUnitEvent(.abilityRemove,dummy,EVENT_UNIT_SPELL_ENDCAST)
call UnitAddAbility(dummy,'Aloc')
call UnitAddAbility(dummy,XE_HEIGHT_ENABLER)
call UnitRemoveAbility(dummy,XE_HEIGHT_ENABLER)
endif
call UnitAddAbility(dummy, abilityid)
static if AUTO_RESET_MANA_COOLDOWN then
call UnitResetCooldown(dummy)
call SetUnitState(dummy, UNIT_STATE_MANA, 10000.0)
endif
if(level>1) then
call SetUnitAbilityLevel(dummy, abilityid, level)
endif
//! endtextmacro
private static integer cparent
private static integer current
private static real cexpire
//! textmacro xecast_deallocdummy
if(.recycledelay>=EPSILON) then
set .cexpire=TimerGetElapsed(.gametime)+.recycledelay
set .current=.rn
set .rn=.rn+1
loop
exitwhen (.current==0)
set .cparent=(.current-1)/2
exitwhen (.expiretime[.cparent]<=.cexpire)
set .recycle[.current]=.recycle[.cparent]
set .expiretime[.current]=.expiretime[.cparent]
set .current=.cparent
endloop
set .expiretime[.current]=.cexpire
set .recycle[.current]=dummy
call SetUnitUserData(dummy,.abilityid)
call TimerStart(.T, .expiretime[0]-TimerGetElapsed(.gametime), false, function xecast.dorecycle)
else
call SetUnitUserData(dummy,0)
call SetUnitFlyHeight(dummy,0,0)
call UnitRemoveAbility(dummy,.abilityid)
endif
//! endtextmacro
method castOnTarget takes unit target returns nothing
local unit dummy
local unit tar
//! runtextmacro xecast_allocdummy()
if (.customsource) then
call SetUnitX(dummy,.sourcex)
call SetUnitY(dummy,.sourcey)
call SetUnitFlyHeight(dummy,.sourcez,0.0)
else
call SetUnitX(dummy,GetWidgetX(target))
call SetUnitY(dummy,GetWidgetY(target))
endif
if (FORCE_INVISIBLE_CAST) then
call UnitShareVision(target, .owningplayer, true)
call IssueTargetOrderById(dummy,this.oid,target)
call UnitShareVision(target, .owningplayer, false)
else
call IssueTargetOrderById(dummy,this.oid,target)
endif
//! runtextmacro xecast_deallocdummy()
if(.autodestroy ) then
call this.destroy()
endif
endmethod
//accepts units, items and destructables, if you know it is
// a unit it is better to use castOnTarget since that would
// be able to use FORCE_INVISIBLE_CAST if necessary.
//
method castOnWidgetTarget takes widget target returns nothing
local unit dummy
local unit tar
//! runtextmacro xecast_allocdummy()
if (.customsource) then
call SetUnitX(dummy,.sourcex)
call SetUnitY(dummy,.sourcey)
call SetUnitFlyHeight(dummy,.sourcez,0.0)
else
call SetUnitX(dummy,GetWidgetX(target))
call SetUnitY(dummy,GetWidgetY(target))
endif
call IssueTargetOrderById(dummy,this.oid,target)
//! runtextmacro xecast_deallocdummy()
if(.autodestroy ) then
call this.destroy()
endif
endmethod
method castOnPoint takes real x, real y returns nothing
local unit dummy
//! runtextmacro xecast_allocdummy()
if (.customsource) then
call SetUnitX(dummy,.sourcex)
call SetUnitY(dummy,.sourcey)
call SetUnitFlyHeight(dummy,.sourcez,0.0)
else
call SetUnitX(dummy,x)
call SetUnitY(dummy,y)
endif
call IssuePointOrderById(dummy,this.oid,x,y)
//! runtextmacro xecast_deallocdummy()
if(.autodestroy ) then
call this.destroy()
endif
endmethod
method castOnLoc takes location loc returns nothing
//debug call BJDebugMsg("Warning: Locations are in use")
//nah but I should
call .castOnPoint(GetLocationX(loc),GetLocationY(loc))
endmethod
//ignores custom source x and y (for obvious reasons)
method castInPoint takes real x, real y returns nothing
local unit dummy
//! runtextmacro xecast_allocdummy()
if (.customsource) then
call SetUnitFlyHeight(dummy,.sourcez,0.0)
endif
call SetUnitX(dummy, x)
call SetUnitY(dummy, y)
call IssueImmediateOrderById(dummy,this.oid)
//! runtextmacro xecast_deallocdummy()
if(.autodestroy ) then
call this.destroy()
endif
endmethod
method castInLoc takes location loc returns nothing
//debug call BJDebugMsg("Warning: Locations are in use")
//nah but I should
call .castInPoint(GetLocationX(loc),GetLocationY(loc))
endmethod
//===================================================================================================
// For method castOnAOE:
//
private static group enumgroup
private static real aoex
private static real aoey
private static real aoeradius
private static xecast cinstance
private static boolexpr aoefunc
// Might look wrong, but this is the way to make it consider collision size, a spell that
// got a target circle and uses this method will let the user know which units it will
// hit with the mass cast.
static method filterAOE takes nothing returns boolean
local unit u=GetFilterUnit()
if IsUnitInRangeXY(u, .aoex, .aoey, .aoeradius) then
call .cinstance.castOnTarget(u)
endif
set u=null
return false
endmethod
//
method castOnAOE takes real x, real y, real radius returns nothing
local boolean ad=this.autodestroy
if(ad) then
set this.autodestroy=false
endif
set .aoex=x
set .aoey=y
set .aoeradius=radius
set .cinstance=this
call GroupEnumUnitsInRange(.enumgroup,x,y,radius + XE_MAX_COLLISION_SIZE , .aoefunc)
if(ad) then
call this.destroy()
endif
endmethod
method castOnAOELoc takes location loc,real radius returns nothing
call .castOnAOE(GetLocationX(loc),GetLocationY(loc),radius)
endmethod
//==================================================================================================
// A quick and dirt castOnGroup method, perhaps it'll later have castOntarget inlined, but not now
//
method castOnGroup takes group g returns nothing
local boolean ad=this.autodestroy
local unit t
if(ad) then
set this.autodestroy=false
endif
loop
set t=FirstOfGroup(g)
exitwhen(t==null)
call GroupRemoveUnit(g,t)
call .castOnTarget(t)
endloop
if(ad) then
call this.destroy()
endif
endmethod
private static method removeAbility takes nothing returns boolean
local unit u=GetTriggerUnit()
if(GetUnitUserData(u)!=0) then
call PauseUnit(u,true)
endif
//This is necessary, picture a value for recycle delay that's higher than the casting time,
//for example if the spell does dps, if you leave the dummy caster with the ability and it
//is owned by an AI player it will start casting the ability on player units, so it is
// a good idea to pause it...
set u=null
return true
endmethod
//===================================================================================================
// structinit is a scope private keyword.
//
static method structinit takes nothing returns nothing
local integer i=INITIAL_DUMMY_COUNT+1
local unit u
set .aoefunc=Condition(function xecast.filterAOE)
set .enumgroup=CreateGroup()
set .abilityRemove = CreateTrigger()
loop
exitwhen (i==0)
set u=CreateUnit(Player(15),XE_DUMMY_UNITID,400,-400,0)
call TriggerRegisterUnitEvent(.abilityRemove,u,EVENT_UNIT_SPELL_ENDCAST)
call UnitAddAbility(u,'Aloc')
call UnitAddAbility(u,XE_HEIGHT_ENABLER)
call UnitRemoveAbility(u,XE_HEIGHT_ENABLER)
set .dummystack[.top]=u
set .top=.top+1
set i=i-1
endloop
call TriggerAddCondition(.abilityRemove, Condition(function xecast.removeAbility ) )
set .top=.top-1
set .instantdummy=.dummystack[.top]
set .T=CreateTimer()
set .gametime=CreateTimer()
call TimerStart(.gametime,12*60*60,false,null)
endmethod
endstruct
private function init takes nothing returns nothing
call xecast.structinit()
endfunction
endlibrary
//===========================================================================
// Trigger: KT
//===========================================================================
//TESH.scrollpos=66
//TESH.alwaysfold=0
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//~~ KT ~~ Key Timers 2 ~~ By Jesus4Lyf ~~ Version 1.6.1 ~~
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// What is Key Timers?
// - Key Timers attaches structs to timers, or more to the point timed
// effects.
// - You can specify different periods.
// - Key Timers only uses one timer with one trigger per low period
// to keep things efficient, especially within the looping.
// - Key Timers alternatively uses one single timer for all higher periods
// to allow accurate expirations in a stable and reasonably efficient fashion.
//
// =Pros=
// - Easy to use.
// - Fastest attachment loading system (storing in parallel arrays).
// - Fastest execution system for low periods (attaching all functions to one trigger).
// - Allows multiple periods to be used.
//
// =Cons=
// - The code passed into KT2 must call KT_GetData exactly once.
// - Periods must be a multiple of 0.00125 seconds. Not 0.007, for example.
//
// Functions:
// - KT_Add(userFunc, struct, period)
// - KT_GetData returns the struct
//
// - userFunc is to be a user function that takes nothing and returns boolean.
// It will be executed by the system every period until it returns true.
//
// - KT_GetData is to be used inside func, it will return the struct passed to
// to the Add function. It must be called exactly once within the func.
//
// Details:
// - KT2 treats low periods and high periods differently, optimizing each
// with appropriate speed and accuracy, although this effect is invisible
// to you, the mapper.
//
// - While func returns false the timer will continue to call it each period.
// Once func returns true the instance will be detached from system.
//
// Thanks:
// - Daxtreme: For encouraging me to return to Key Timers 2, rather than
// leave it to rot. His interest in the system restored it, and helped
// it to become what it is now. :)
//
// - Captain Griffen: For his work on Rapid Timers, demonstrating that it
// is possible to attach all functions to one trigger, and that it is
// indeed faster.
//
// - Cohadar: Told me to make Key Timers without a textmacro.
// Thanks to him for helping me with the original Key Timers system too.
// Also, I'd like to thank him for his work on Timer Ticker (TT) which
// demonstrated how to use triggers/conditions in this sort of system,
// which has been used in Key Timers 2.
//
// How to import:
// - Create a trigger named KT.
// - Convert it to custom text and replace the whole trigger text with this.
//
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
library KT initializer Init
///////////////
// Constants //
////////////////////////////////////////////////////////////////////////////
// That bit that users may play with if they know what they're doing.
// Not touching these at all is recommended.
globals
private constant real PERIODTHRESHOLD=0.3 // MUST be below 10.24 seconds.
private constant real HT_MARGINOFERROR=0.01
endglobals
//////////////////////////
// Previous KT2 Globals //
////////////////////////////////////////////////////////////////////////////
// These needed to be moved here for HT to hook GetData.
globals
private timer array KeyTimer
private trigger array TimerTrigger
private integer array KeyTimerListPointer
private integer array KeyTimerListEndPointer
private triggercondition array TriggerCond
private boolexpr array Boolexpr
private integer array Data
private integer array Next
private integer array Prev
private integer TrigMax=0
private integer array NextMem
private integer NextMemMaxPlusOne=1
private integer array ToAddMem
private triggercondition array ToRemove
private boolexpr array ToDestroy
private boolean array IsAdd
private integer AddRemoveMax=0
// Locals
private integer t_id=-1
private integer t_mem
private integer t_lastmem
private integer a_id
private integer a_mem
// Code Chunks
private conditionfunc RemoveInstanceCond
endglobals
/////////////////////
// Hibernate Timer //
////////////////////////////////////////////////////////////////////////////
// KT2 implementation for higher periods (low frequency).
private keyword HTnode
globals
private timer HT_Moderator=CreateTimer()
private real HT_Time=0.0
private HTnode HT_Top
private constant integer HT_DATAMEM=8190 // Added for KT2 hook. Don't change.
endglobals
globals//locals
private HTnode newHTnode
endglobals
private struct HTnode
HTnode prev // Make sure to link this before use
HTnode next // Make sure to link this before use
real period
real firewhen // = HT_Time at creation
trigger trig
integer data
static method new takes code func, integer data, real period returns HTnode
set newHTnode=HTnode.create()
if newHTnode.trig==null then
set newHTnode.trig=CreateTrigger()
endif
call TriggerAddCondition(newHTnode.trig,Condition(func))
set newHTnode.data=data
set newHTnode.period=period
set newHTnode.firewhen=HT_Time
return newHTnode
endmethod
method link takes HTnode prev, HTnode next returns nothing
set prev.next=this
set next.prev=this
set this.next=next
set this.prev=prev
endmethod
method unlink takes nothing returns nothing
set this.prev.next=this.next
set this.next.prev=this.prev
endmethod
method autolink takes HTnode start returns nothing
loop
if start.next==0 then
call this.link(start,0)
return
endif
if start.next.firewhen > this.firewhen then
call this.link(start,start.next)
return
endif
set start=start.next
endloop
endmethod
endstruct
globals//locals
private HTnode HT_handlenode
private HTnode HT_handlenext
endglobals
private function HT_Handler takes nothing returns nothing
// KT2 Data Hook
set t_mem=HT_DATAMEM
// End KT2 Data Hook
set HT_handlenode=HT_Top
set HT_handlenext=HT_handlenode.next
loop
set HT_handlenode=HT_handlenext
exitwhen HT_handlenode==0 // Would pause timer here under old method.
set HT_handlenext=HT_handlenode.next
if HT_handlenode.firewhen<HT_Time+HT_MARGINOFERROR then
// Load data
set Data[HT_DATAMEM]=HT_handlenode.data
// End load data
if TriggerEvaluate(HT_handlenode.trig) then
call HT_handlenode.unlink()
call TriggerClearConditions(HT_handlenode.trig)
call HT_handlenode.destroy()
else
set HT_handlenode.firewhen=HT_handlenode.firewhen+HT_handlenode.period
call HT_handlenode.unlink()
call HT_handlenode.autolink(HT_handlenode.prev)
if HT_handlenext==0 then
set HT_handlenext=HT_handlenode
endif
endif
else
// More to fire, but not yet.
return
endif
endloop
endfunction
globals//locals
private HTnode HT_addnode
endglobals
private function HTadd takes code func, integer data, real period returns nothing
set HT_addnode=HTnode.new(func, data, period)
set HT_addnode.firewhen=HT_Time+period
call HT_addnode.autolink(HT_Top)
//if HT_Top.next==HT_addnode then
// //Old start timer stuff
//endif
endfunction
private function HT_ModeratorLoop takes nothing returns nothing
set HT_Time=HT_Time+HT_MARGINOFERROR
if HT_Top.next.firewhen<HT_Time then
call HT_Handler()
endif
endfunction
private function HTinit takes nothing returns nothing
call TimerStart(HT_Moderator,HT_MARGINOFERROR,true,function HT_ModeratorLoop)
set HT_Top=HTnode.create()
set HT_Top.prev=0
set HT_Top.next=0
set HT_Top.firewhen=0.0
// Allow for GetData
set Next[HT_DATAMEM]=HT_DATAMEM
set Prev[HT_DATAMEM]=HT_DATAMEM
// End allow for GetData
endfunction
//////////////////
// Previous KT2 //
////////////////////////////////////////////////////////////////////////////
// The rest of the KT2 implementation
// Globals have been moved to top.
private function KeyTimerLoop takes nothing returns nothing
set t_id=R2I(TimerGetTimeout(GetExpiredTimer())*800)
set t_mem=KeyTimerListEndPointer[t_id]
call TriggerEvaluate(TimerTrigger[t_id])
set t_mem=0
loop
exitwhen t_mem==AddRemoveMax
set t_mem=t_mem+1
if IsAdd[t_mem] then
set TriggerCond[ToAddMem[t_mem]]=TriggerAddCondition(TimerTrigger[t_id],Boolexpr[ToAddMem[t_mem]])
else
call TriggerRemoveCondition(TimerTrigger[t_id],ToRemove[t_mem])
call DestroyBoolExpr(ToDestroy[t_mem])
endif
endloop
set AddRemoveMax=0
set t_id=-1
endfunction
private function RemoveInstance takes nothing returns boolean
// Will only fire if code returns true.
set AddRemoveMax=AddRemoveMax+1
set IsAdd[AddRemoveMax]=false
set ToRemove[AddRemoveMax]=TriggerCond[t_lastmem]
set ToDestroy[AddRemoveMax]=Boolexpr[t_lastmem]
if Next[t_lastmem]==0 then
set KeyTimerListEndPointer[t_id]=Prev[t_lastmem]
endif
set Prev[Next[t_lastmem]]=Prev[t_lastmem]
if Prev[t_lastmem]==0 then
set KeyTimerListPointer[t_id]=Next[t_lastmem]
if KeyTimerListPointer[t_id]<1 then
call PauseTimer(KeyTimer[t_id])
endif
else
set Next[Prev[t_lastmem]]=Next[t_lastmem]
endif
set NextMem[NextMemMaxPlusOne]=t_lastmem
set NextMemMaxPlusOne=NextMemMaxPlusOne+1
return false
endfunction
private function KTadd takes code func, integer data, real period returns nothing
set a_id=R2I(period*800)
if KeyTimer[a_id]==null then
set KeyTimer[a_id]=CreateTimer()
set TimerTrigger[a_id]=CreateTrigger()
endif
if NextMemMaxPlusOne==1 then
set TrigMax=TrigMax+1
set a_mem=TrigMax
else
set NextMemMaxPlusOne=NextMemMaxPlusOne-1
set a_mem=NextMem[NextMemMaxPlusOne]
endif
set Boolexpr[a_mem]=And(Condition(func),RemoveInstanceCond)
if t_id==a_id then
set AddRemoveMax=AddRemoveMax+1
set IsAdd[AddRemoveMax]=true
set ToAddMem[AddRemoveMax]=a_mem
else
if KeyTimerListPointer[a_id]<1 then
call TimerStart(KeyTimer[a_id],a_id/800.0,true,function KeyTimerLoop)
set KeyTimerListEndPointer[a_id]=a_mem
endif
set TriggerCond[a_mem]=TriggerAddCondition(TimerTrigger[a_id],Boolexpr[a_mem])
endif
set Data[a_mem]=data
set Prev[a_mem]=0
set Next[a_mem]=KeyTimerListPointer[a_id]
set Prev[KeyTimerListPointer[a_id]]=a_mem
set KeyTimerListPointer[a_id]=a_mem
endfunction
public function GetData takes nothing returns integer // Gets hooked by HT.
set t_lastmem=t_mem
set t_mem=Prev[t_mem]
return Data[t_lastmem]
endfunction
private function KTinit takes nothing returns nothing
set RemoveInstanceCond=Condition(function RemoveInstance)
endfunction
///////////////
// Interface //
////////////////////////////////////////////////////////////////////////////
// Stitches it all together neatly.
public function Add takes code func, integer data, real period returns nothing
if period<PERIODTHRESHOLD then
call KTadd(func,data,period)
else
call HTadd(func,data,period)
endif
endfunction
private function Init takes nothing returns nothing
call KTinit()
call HTinit()
endfunction
endlibrary
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// End of Key Timers 2
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//===========================================================================
function InitCustomTriggers takes nothing returns nothing
call InitTrig_Custom_Initialization( )
call InitTrig_paladin( )
call InitTrig_timerloops( )
call InitTrig_yojimbo( )
call InitTrig_GT( )
call InitTrig_MSGS( )
call InitTrig_DebugS( )
call InitTrig_jBoard( )
call InitTrig_STM( )
call InitTrig_TimerEvents( )
call InitTrig_mbSTM( )
call InitTrig_TimerUtils( )
call InitTrig_xebasic_Copy( )
call InitTrig_xedamage_Copy( )
call InitTrig_xepreload_Copy_Copy( )
call InitTrig_xecast_Copy_Copy( )
call InitTrig_KT( )
endfunction
//===========================================================================
function RunInitializationTriggers takes nothing returns nothing
call ConditionalTriggerExecute( gg_trg_Custom_Initialization )
endfunction
//***************************************************************************
//*
//* Players
//*
//***************************************************************************
function InitCustomPlayerSlots takes nothing returns nothing
// Player 0
call SetPlayerStartLocation( Player(0), 0 )
call ForcePlayerStartLocation( Player(0), 0 )
call SetPlayerColor( Player(0), ConvertPlayerColor(0) )
call SetPlayerRacePreference( Player(0), RACE_PREF_HUMAN )
call SetPlayerRaceSelectable( Player(0), true )
call SetPlayerController( Player(0), MAP_CONTROL_USER )
// Player 1
call SetPlayerStartLocation( Player(1), 1 )
call ForcePlayerStartLocation( Player(1), 1 )
call SetPlayerColor( Player(1), ConvertPlayerColor(1) )
call SetPlayerRacePreference( Player(1), RACE_PREF_HUMAN )
call SetPlayerRaceSelectable( Player(1), true )
call SetPlayerController( Player(1), MAP_CONTROL_USER )
endfunction
function InitCustomTeams takes nothing returns nothing
// Force: Force 1
call SetPlayerTeam( Player(0), 0 )
call SetPlayerTeam( Player(1), 0 )
endfunction
function InitAllyPriorities takes nothing returns nothing
call SetStartLocPrioCount( 0, 1 )
call SetStartLocPrio( 0, 0, 1, MAP_LOC_PRIO_HIGH )
call SetStartLocPrioCount( 1, 1 )
call SetStartLocPrio( 1, 0, 0, MAP_LOC_PRIO_HIGH )
endfunction
//***************************************************************************
//*
//* Main Initialization
//*
//***************************************************************************
//===========================================================================
function main takes nothing returns nothing
local weathereffect we
call SetCameraBounds( -5376.0 + GetCameraMargin(CAMERA_MARGIN_LEFT), -5632.0 + GetCameraMargin(CAMERA_MARGIN_BOTTOM), 5376.0 - GetCameraMargin(CAMERA_MARGIN_RIGHT), 5120.0 - GetCameraMargin(CAMERA_MARGIN_TOP), -5376.0 + GetCameraMargin(CAMERA_MARGIN_LEFT), 5120.0 - GetCameraMargin(CAMERA_MARGIN_TOP), 5376.0 - GetCameraMargin(CAMERA_MARGIN_RIGHT), -5632.0 + GetCameraMargin(CAMERA_MARGIN_BOTTOM) )
call SetDayNightModels( "Environment\\DNC\\DNCLordaeron\\DNCLordaeronTerrain\\DNCLordaeronTerrain.mdl", "Environment\\DNC\\DNCLordaeron\\DNCLordaeronUnit\\DNCLordaeronUnit.mdl" )
call SetTerrainFogEx( 0, 3000.0, 4000.0, 0.500, 0.502, 0.502, 0.502 )
call SetWaterBaseColor( 128, 128, 255, 255 )
set we = AddWeatherEffect( Rect(-6144.0,-6144.0,6144.0,6144.0), 'RLlr' )
call EnableWeatherEffect( we, true )
call NewSoundEnvironment( "Default" )
call SetAmbientDaySound( "VillageDay" )
call SetAmbientNightSound( "VillageNight" )
call SetMapMusic( "Music", true, 0 )
call CreateAllUnits( )
call InitBlizzard( )
call InitGlobals( )
call InitCustomTriggers( )
call RunInitializationTriggers( )
endfunction
//***************************************************************************
//*
//* Map Configuration
//*
//***************************************************************************
function config takes nothing returns nothing
call SetMapName( "TRIGSTR_001" )
call SetMapDescription( "TRIGSTR_003" )
call SetPlayers( 2 )
call SetTeams( 2 )
call SetGamePlacement( MAP_PLACEMENT_TEAMS_TOGETHER )
call DefineStartLocation( 0, -4032.0, 2112.0 )
call DefineStartLocation( 1, 3968.0, -2560.0 )
// Player setup
call InitCustomPlayerSlots( )
call SetPlayerSlotAvailable( Player(0), MAP_CONTROL_USER )
call SetPlayerSlotAvailable( Player(1), MAP_CONTROL_USER )
call InitGenericPlayerSlots( )
call InitAllyPriorities( )
endfunction