
library YDWEBase initializer InitializeYD
//===========================================================================
//Return bug
//===========================================================================
globals
	//integer abcdefghij = 15	
	string bj_AllString=".................................!.#$%&'()*+,-./0123456789:;<=>.@ABCDEFGHIJKLMNOPQRSTUVWXYZ[.]^_`abcdefghijklmnopqrstuvwxyz{|}~................................................................................................................................"
//全局系统变量
    unitpool bj_lastCreatedUnitPool=null 
    unit bj_lastPoolAbstractedUnit=null	
    itempool bj_lastCreatedItemPool=null 
    item bj_lastPoolAbstractedItem=null	    
//跳跃系统优先级	
	integer MoveMoreLevel_JumpTimer=3
//TimerSystem	
	timer TimerSystem_Timer=null         //最小时间计时器  可以自动开启和关闭 
	real TimerSystem_Timeout=0.01
	integer TimerSystem_Steps=0
	integer TimerSystem_StepsMax=0
	timer TimerSystem_BigTimer=null         //最大时间计时器  从游戏开始那刻便开启  用于记录游戏时间 
	real TimerSystem_BigTimeout=1
	integer TimerSystem_BigSteps=0
	integer TimerSystem_RunIndex=0            //中心计时器运行触发器或函数的执行索引 
//全局缓存	     
	gamecache YDGC = null
endglobals

//===========================================================================
//Return bug
//===========================================================================
function YDWEH2I takes handle h returns integer
    return h
    return 0
endfunction

function YDWEI2U takes integer i returns unit
    return i
    return null
endfunction

function YDWEI2It takes integer i returns item
    return i
    return null
endfunction

function YDWEI2P takes integer i returns player
    return i
    return null
endfunction

function YDWEI2Tm takes integer i returns timer
    return i
    return null
endfunction

function YDWEI2T takes integer i returns trigger
    return i
    return null
endfunction

function YDWEI2Pt takes integer i returns location
    return i
    return null
endfunction

function YDWEI2G takes integer i returns group
    return i
    return null
endfunction

function YDWEI2M takes integer i returns multiboard
    return i
    return null
endfunction

function YDWEI2Mt takes integer i returns multiboarditem
    return i
    return null
endfunction

function YDWEI2Tt takes integer i returns texttag
    return i
    return null
endfunction

function YDWEI2Ln takes integer i returns lightning
    return i
    return null
endfunction

function YDWEI2Rn takes integer i returns region
    return i
    return null
endfunction

function YDWEI2Rt takes integer i returns rect
    return i
    return null
endfunction

function YDWEI2Lb takes integer i returns leaderboard
    return i
    return null
endfunction

function YDWEI2E takes integer i returns effect
    return i
    return null
endfunction

function YDWEI2Da takes integer i returns destructable
    return i
    return null
endfunction

function YDWEI2TC takes integer i returns triggercondition
    return i
    return null
endfunction

function YDWEI2TA takes integer i returns triggeraction
    return i
    return null
endfunction

function YDWEI2Et takes integer i returns event
    return i
    return null
endfunction

function YDWEI2Fc takes integer i returns force
    return i
    return null
endfunction

function YDWEI2BE takes integer i returns boolexpr
    return i
    return null
endfunction

function YDWEI2Sd takes integer i returns sound
    return i
    return null
endfunction

function YDWEI2TD takes integer i returns timerdialog
    return i
    return null
endfunction

function YDWEI2Ta takes integer i returns trackable
    return i
    return null
endfunction

function YDWEI2D takes integer i returns dialog
    return i
    return null
endfunction

function YDWEI2Bt takes integer i returns button
    return i
    return null
endfunction

function YDWEGetGameCache takes nothing returns gamecache  
    return YDGC
endfunction

//============================    
//转换handle为integer 
//===========================================================================
function YDWEGetUnitID takes unit u returns integer
    return YDWEH2I(u)
endfunction

function YDWEGetItemID takes item it returns integer
    return YDWEH2I(it)
endfunction

function YDWEGetPlayerID takes player p returns integer
    return YDWEH2I(p)
endfunction

function YDWEGetTimerID takes timer t returns integer
    return YDWEH2I(t)
endfunction

function YDWEGetTriggerID takes trigger trg returns integer
    return YDWEH2I(trg)
endfunction

function YDWEGetGroupID takes group g returns integer
    return YDWEH2I(g)
endfunction

function YDWEGetLocationID takes location point returns integer
    return YDWEH2I(point)
endfunction

function YDWEGetUnitTypeID takes integer uid returns integer
    return uid
endfunction

function YDWEGetAbilityTypeID takes integer ab returns integer
    return ab
endfunction

function YDWEGetItemTypeID takes integer itid returns integer
    return itid
endfunction

function YDWEGetMultiboardID takes multiboard m returns integer
    return YDWEH2I(m)
endfunction

function YDWEGetMultiboardItemID takes multiboarditem mt returns integer
    return YDWEH2I(mt)
endfunction

function YDWEGetTextTagID takes texttag tt returns integer
    return YDWEH2I(tt)
endfunction

function YDWEGetLightningID takes lightning ln returns integer
    return YDWEH2I(ln)
endfunction

function YDWEGetRegionID takes region rn returns integer
    return YDWEH2I(rn)
endfunction

function YDWEGetRectID takes rect rt returns integer
    return YDWEH2I(rt)
endfunction

function YDWEGetLeaderboardID takes leaderboard lb returns integer
    return YDWEH2I(lb)
endfunction

function YDWEGetEffectID takes effect e returns integer
    return YDWEH2I(e)
endfunction

function YDWEGetDestructableID takes destructable da returns integer
    return YDWEH2I(da)
endfunction

function YDWEGetTriggerConditionID takes triggercondition tc returns integer
    return YDWEH2I(tc)
endfunction

function YDWEGetTriggerActionID takes triggeraction ta returns integer
    return YDWEH2I(ta)
endfunction

function YDWEGetTriggerEventID takes event et returns integer
    return YDWEH2I(et)
endfunction

function YDWEGetForceID takes force fc returns integer
    return YDWEH2I(fc)
endfunction

function YDWEGetBoolexprID takes boolexpr be returns integer
    return YDWEH2I(be)
endfunction

function YDWEGetSoundID takes sound sd returns integer
    return YDWEH2I(sd)
endfunction

function YDWEGetTimerDialogID takes timerdialog td returns integer
    return YDWEH2I(td)
endfunction

function YDWEGetTrackableID takes trackable ta returns integer
    return YDWEH2I(ta)
endfunction

function YDWEGetDialogID takes dialog d returns integer
    return YDWEH2I(d)
endfunction

function YDWEGetButtonID takes button bt returns integer
    return YDWEH2I(bt)
endfunction

//返回单位 物品 闪电的类型为整数  --UI需要 
function YDWEConverUnitcodeToInt takes integer uid returns integer
    return uid
endfunction

function YDWEConverItemcodeToInt takes integer itid returns integer
    return itid
endfunction

function YDWEConverAbilcodeToInt takes integer abid returns integer
    return abid
endfunction

//清空 
function YDWEFlushAllData takes nothing returns nothing
    call FlushGameCache(YDGC)
endfunction 

function YDWEFlushMissionByInteger takes integer i returns nothing
    call FlushStoredMission(YDGC,I2S(i))
endfunction  

function YDWEFlushMissionByString takes string s returns nothing
    call FlushStoredMission(YDGC,s)
endfunction  

//store and get integer
function YDWESaveIntegerByInteger takes integer pTable,integer pKey,integer i returns nothing
    call StoreInteger(YDGC,I2S(pTable),I2S(pKey),i)
endfunction

function YDWESaveIntegerByString takes string pTable,string pKey,integer i returns nothing
    call StoreInteger(YDGC,pTable,pKey,i)     
endfunction

function YDWEGetIntegerByInteger takes integer pTable,integer pKey returns integer
    return GetStoredInteger(YDGC,I2S(pTable),I2S(pKey))
endfunction

function YDWEGetIntegerByString takes string pTable,string pKey returns integer
    return GetStoredInteger(YDGC,pTable,pKey)
endfunction

//store and get real
function YDWESaveRealByInteger takes integer pTable,integer pKey,real r returns nothing
    call StoreReal(YDGC,I2S(pTable),I2S(pKey),r)
endfunction

function YDWESaveRealByString takes string pTable,string pKey,real r returns nothing
    call StoreReal(YDGC,pTable,pKey,r)     
endfunction

function YDWEGetRealByInteger takes integer pTable,integer pKey returns real 
    return GetStoredReal(YDGC,I2S(pTable),I2S(pKey))
endfunction

function YDWEGetRealByString takes string pTable,string pKey returns real 
    return GetStoredReal(YDGC,pTable,pKey)
endfunction

//store and get string
function YDWESaveStringByInteger takes integer pTable,integer pKey,string s returns nothing
    call StoreString(YDGC,I2S(pTable),I2S(pKey),s)
endfunction

function YDWESaveStringByString takes string pTable,string pKey,string s returns nothing
    call StoreString(YDGC,pTable,pKey,s)     
endfunction

function YDWEGetStringByInteger takes integer pTable,integer pKey returns string 
    return GetStoredString(YDGC,I2S(pTable),I2S(pKey))
endfunction

function YDWEGetStringByString takes string pTable,string pKey returns string 
    return GetStoredString(YDGC,pTable,pKey)
endfunction

//store and get boolean
function YDWESaveBooleanByInteger takes integer pTable,integer pKey,boolean b returns nothing
    call StoreBoolean(YDGC,I2S(pTable),I2S(pKey),b)
endfunction

function YDWESaveBooleanByString takes string pTable,string pKey,boolean b returns nothing
    call StoreBoolean(YDGC,pTable,pKey,b)     
endfunction

function YDWEGetBooleanByInteger takes integer pTable,integer pKey returns boolean 
    return GetStoredBoolean(YDGC,I2S(pTable),I2S(pKey))
endfunction

function YDWEGetBooleanByString takes string pTable,string pKey returns boolean 
    return GetStoredBoolean(YDGC,pTable,pKey)
endfunction

//Covert Unit
function YDWESaveUnitByInteger takes integer pTable,integer pKey,unit u returns nothing
    call StoreInteger(YDGC,I2S(pTable),I2S(pKey),YDWEH2I(u))
endfunction
                       
function YDWESaveUnitByString takes string pTable,string pKey,unit u returns nothing
    call StoreInteger(YDGC,pTable,pKey,YDWEH2I(u))
endfunction

function YDWEGetUnitByInteger takes integer pTable,integer pKey returns unit
    return YDWEI2U(GetStoredInteger(YDGC,I2S(pTable),I2S(pKey)))
endfunction

function YDWEGetUnitByString takes string pTable,string pKey returns unit
    return YDWEI2U(GetStoredInteger(YDGC,pTable,pKey))
endfunction

//Covert UnitID
function YDWESaveUnitIDByInteger takes integer pTable,integer pKey,integer uid returns nothing
    call StoreInteger(YDGC,I2S(pTable),I2S(pKey),uid)
endfunction

function YDWESaveUnitIDByString takes string pTable,string pKey,integer uid returns nothing
    call StoreInteger(YDGC,pTable,pKey,uid)
endfunction

function YDWEGetUnitIDByInteger takes integer pTable,integer pKey returns integer
    return GetStoredInteger(YDGC,I2S(pTable),I2S(pKey))
endfunction

function YDWEGetUnitIDByString takes string pTable,string pKey returns integer
    return GetStoredInteger(YDGC,pTable,pKey)
endfunction

//Covert Player
function YDWESavePlayerByInteger takes integer pTable,integer pKey,player p returns nothing
    call StoreInteger(YDGC,I2S(pTable),I2S(pKey),YDWEH2I(p))
endfunction

function YDWESavePlayerByString takes string pTable,string pKey,player p returns nothing
    call StoreInteger(YDGC,pTable,pKey,YDWEH2I(p))
endfunction

function YDWEGetPlayerByInteger takes integer pTable,integer pKey returns player
    return YDWEI2P(GetStoredInteger(YDGC,I2S(pTable),I2S(pKey)))
endfunction

function YDWEGetPlayerByString takes string pTable,string pKey returns player
    return YDWEI2P(GetStoredInteger(YDGC,pTable,pKey))
endfunction

//Covert Item
function YDWESaveItemByInteger takes integer pTable,integer pKey,item it returns nothing
    call StoreInteger(YDGC,I2S(pTable),I2S(pKey),YDWEH2I(it))
endfunction

function YDWESaveItemByString takes string pTable,string pKey,item it returns nothing
    call StoreInteger(YDGC,pTable,pKey,YDWEH2I(it))
endfunction

function YDWEGetItemByInteger takes integer pTable,integer pKey returns item
    return YDWEI2It(GetStoredInteger(YDGC,I2S(pTable),I2S(pKey)))
endfunction

function YDWEGetItemByString takes string pTable,string pKey returns item
    return YDWEI2It(GetStoredInteger(YDGC,pTable,pKey))
endfunction

//Covert ItemID
function YDWESaveItemIDByInteger takes integer pTable,integer pKey,integer itid returns nothing
    call StoreInteger(YDGC,I2S(pTable),I2S(pKey),itid)
endfunction

function YDWESaveItemIDByString takes string pTable,string pKey,integer itid returns nothing
    call StoreInteger(YDGC,pTable,pKey,itid)
endfunction

function YDWEGetItemIDByInteger takes integer pTable,integer pKey returns integer
    return GetStoredInteger(YDGC,I2S(pTable),I2S(pKey))
endfunction

function YDWEGetItemIDByString takes string pTable,string pKey returns integer
    return GetStoredInteger(YDGC,pTable,pKey)
endfunction

//Covert Timer
function YDWESaveTimerByInteger takes integer pTable,integer pKey,timer t returns nothing
    call StoreInteger(YDGC,I2S(pTable),I2S(pKey),YDWEH2I(t))
endfunction

function YDWESaveTimerByString takes string pTable,string pKey,timer t returns nothing
    call StoreInteger(YDGC,pTable,pKey,YDWEH2I(t))
endfunction

function YDWEGetTimerByInteger takes integer pTable,integer pKey returns timer
    return YDWEI2Tm(GetStoredInteger(YDGC,I2S(pTable),I2S(pKey)))
endfunction

function YDWEGetTimerByString takes string pTable,string pKey returns timer
    return YDWEI2Tm(GetStoredInteger(YDGC,pTable,pKey))
endfunction

//Covert Trigger
function YDWESaveTriggerByInteger takes integer pTable,integer pKey,trigger trg returns nothing
    call StoreInteger(YDGC,I2S(pTable),I2S(pKey),YDWEH2I(trg))
endfunction

function YDWESaveTriggerByString takes string pTable,string pKey,trigger trg returns nothing
    call StoreInteger(YDGC,pTable,pKey,YDWEH2I(trg))
endfunction

function YDWEGetTriggerByInteger takes integer pTable,integer pKey returns trigger
    return YDWEI2T(GetStoredInteger(YDGC,I2S(pTable),I2S(pKey)))
endfunction

function YDWEGetTriggerByString takes string pTable,string pKey returns trigger
    return YDWEI2T(GetStoredInteger(YDGC,pTable,pKey))
endfunction

//Covert Location
function YDWESaveLocationByInteger takes integer pTable,integer pKey,location pt returns nothing
    call StoreInteger(YDGC,I2S(pTable),I2S(pKey),YDWEH2I(pt))
endfunction

function YDWESaveLocationByString takes string pTable,string pKey,location pt returns nothing
    call StoreInteger(YDGC,pTable,pKey,YDWEH2I(pt))
endfunction

function YDWEGetLocationByInteger takes integer pTable,integer pKey returns location
    return YDWEI2Pt(GetStoredInteger(YDGC,I2S(pTable),I2S(pKey)))
endfunction

function YDWEGetLocationByString takes string pTable,string pKey returns location
    return YDWEI2Pt(GetStoredInteger(YDGC,pTable,pKey))
endfunction

//Covert Group
function YDWESaveGroupByInteger takes integer pTable,integer pKey,group g returns nothing
    call StoreInteger(YDGC,I2S(pTable),I2S(pKey),YDWEH2I(g))
endfunction

function YDWESaveGroupByString takes string pTable,string pKey,group g returns nothing
    call StoreInteger(YDGC,pTable,pKey,YDWEH2I(g))
endfunction

function YDWEGetGroupByInteger takes integer pTable,integer pKey returns group
    return YDWEI2G(GetStoredInteger(YDGC,I2S(pTable),I2S(pKey)))
endfunction

function YDWEGetGroupByString takes string pTable,string pKey returns group
    return YDWEI2G(GetStoredInteger(YDGC,pTable,pKey))
endfunction

//Covert multiboard
function YDWESaveMultiboardByInteger takes integer pTable,integer pKey,multiboard m returns nothing
    call StoreInteger(YDGC,I2S(pTable),I2S(pKey),YDWEH2I(m))
endfunction

function YDWESaveMultiboardByString takes string pTable,string pKey,multiboard m returns nothing
    call StoreInteger(YDGC,pTable,pKey,YDWEH2I(m))
endfunction

function YDWEGetMultiboardByInteger takes integer pTable,integer pKey returns multiboard
    return YDWEI2M(GetStoredInteger(YDGC,I2S(pTable),I2S(pKey)))
endfunction

function YDWEGetMultiboardByString takes string pTable,string pKey returns multiboard
    return YDWEI2M(GetStoredInteger(YDGC,pTable,pKey))
endfunction

//Covert multiboarditem
function YDWESaveMultiboardItemByInteger takes integer pTable,integer pKey,multiboarditem mt returns nothing
    call StoreInteger(YDGC,I2S(pTable),I2S(pKey),YDWEH2I(mt))
endfunction

function YDWESaveMultiboardItemByString takes string pTable,string pKey,multiboarditem mt returns nothing
    call StoreInteger(YDGC,pTable,pKey,YDWEH2I(mt))
endfunction

function YDWEGetMultiboardItemByInteger takes integer pTable,integer pKey returns multiboarditem
    return YDWEI2Mt(GetStoredInteger(YDGC,I2S(pTable),I2S(pKey)))
endfunction

function YDWEGetMultiboardItemByString takes string pTable,string pKey returns multiboarditem
    return YDWEI2Mt(GetStoredInteger(YDGC,pTable,pKey))
endfunction

//Covert Texttag
function YDWESaveTextTagByInteger takes integer pTable,integer pKey,texttag tt returns nothing
    call StoreInteger(YDGC,I2S(pTable),I2S(pKey),YDWEH2I(tt))
endfunction

function YDWESaveTextTagByString takes string pTable,string pKey,texttag tt returns nothing
    call StoreInteger(YDGC,pTable,pKey,YDWEH2I(tt))
endfunction

function YDWEGetTextTagByInteger takes integer pTable,integer pKey returns texttag
    return YDWEI2Tt(GetStoredInteger(YDGC,I2S(pTable),I2S(pKey)))
endfunction

function YDWEGetTextTagByString takes string pTable,string pKey returns texttag
    return YDWEI2Tt(GetStoredInteger(YDGC,pTable,pKey))
endfunction

//Covert lightning
function YDWESaveLightningByInteger takes integer pTable,integer pKey,lightning ln returns nothing
    call StoreInteger(YDGC,I2S(pTable),I2S(pKey),YDWEH2I(ln))
endfunction

function YDWESaveLightningByString takes string pTable,string pKey,lightning ln returns nothing
    call StoreInteger(YDGC,pTable,pKey,YDWEH2I(ln))
endfunction

function YDWEGetLightningByInteger takes integer pTable,integer pKey returns lightning
    return YDWEI2Ln(GetStoredInteger(YDGC,I2S(pTable),I2S(pKey)))
endfunction

function YDWEGetLightningByString takes string pTable,string pKey returns lightning
    return YDWEI2Ln(GetStoredInteger(YDGC,pTable,pKey))
endfunction

//Covert region
function YDWESaveRegionByInteger takes integer pTable,integer pKey,region rn returns nothing
    call StoreInteger(YDGC,I2S(pTable),I2S(pKey),YDWEH2I(rn))
endfunction

function YDWESaveRegionByString takes string pTable,string pKey,region rn returns nothing
    call StoreInteger(YDGC,pTable,pKey,YDWEH2I(rn))
endfunction

function YDWEGetRegionByInteger takes integer pTable,integer pKey returns region
    return YDWEI2Rn(GetStoredInteger(YDGC,I2S(pTable),I2S(pKey)))
endfunction

function YDWEGetRegionByString takes string pTable,string pKey returns region
    return YDWEI2Rn(GetStoredInteger(YDGC,pTable,pKey))
endfunction

//Covert rect
function YDWESaveRectByInteger takes integer pTable,integer pKey,rect rt returns nothing
    call StoreInteger(YDGC,I2S(pTable),I2S(pKey),YDWEH2I(rt))
endfunction

function YDWESaveRectByString takes string pTable,string pKey,rect rt returns nothing
    call StoreInteger(YDGC,pTable,pKey,YDWEH2I(rt))
endfunction

function YDWEGetRectByInteger takes integer pTable,integer pKey returns rect
    return YDWEI2Rt(GetStoredInteger(YDGC,I2S(pTable),I2S(pKey)))
endfunction

function YDWEGetRectByString takes string pTable,string pKey returns rect
    return YDWEI2Rt(GetStoredInteger(YDGC,pTable,pKey))
endfunction

//Covert leaderboard
function YDWESaveLeaderboardByInteger takes integer pTable,integer pKey,leaderboard lb returns nothing
    call StoreInteger(YDGC,I2S(pTable),I2S(pKey),YDWEH2I(lb))
endfunction

function YDWESaveLeaderboardByString takes string pTable,string pKey,leaderboard lb returns nothing
    call StoreInteger(YDGC,pTable,pKey,YDWEH2I(lb))
endfunction

function YDWEGetLeaderboardByInteger takes integer pTable,integer pKey returns leaderboard
    return YDWEI2Lb(GetStoredInteger(YDGC,I2S(pTable),I2S(pKey)))
endfunction

function YDWEGetLeaderboardByString takes string pTable,string pKey returns leaderboard
    return YDWEI2Lb(GetStoredInteger(YDGC,pTable,pKey))
endfunction

//Covert effect
function YDWESaveEffectByInteger takes integer pTable,integer pKey,effect e returns nothing
    call StoreInteger(YDGC,I2S(pTable),I2S(pKey),YDWEH2I(e))
endfunction

function YDWESaveEffectByString takes string pTable,string pKey,effect e returns nothing
    call StoreInteger(YDGC,pTable,pKey,YDWEH2I(e))
endfunction

function YDWEGetEffectByInteger takes integer pTable,integer pKey returns effect
    return YDWEI2E(GetStoredInteger(YDGC,I2S(pTable),I2S(pKey)))
endfunction

function YDWEGetEffectByString takes string pTable,string pKey returns effect
    return YDWEI2E(GetStoredInteger(YDGC,pTable,pKey))
endfunction

//Covert destructable
function YDWESaveDestructableByInteger takes integer pTable,integer pKey,destructable da returns nothing
    call StoreInteger(YDGC,I2S(pTable),I2S(pKey),YDWEH2I(da))
endfunction

function YDWESaveDestructableByString takes string pTable,string pKey,destructable da returns nothing
    call StoreInteger(YDGC,pTable,pKey,YDWEH2I(da))
endfunction

function YDWEGetDestructableByInteger takes integer pTable,integer pKey returns destructable
    return YDWEI2Da(GetStoredInteger(YDGC,I2S(pTable),I2S(pKey)))
endfunction

function YDWEGetDestructableByString takes string pTable,string pKey returns destructable
    return YDWEI2Da(GetStoredInteger(YDGC,pTable,pKey))
endfunction

//Covert triggercondition
function YDWESaveTriggerConditionByInteger takes integer pTable,integer pKey,triggercondition tc returns nothing
    call StoreInteger(YDGC,I2S(pTable),I2S(pKey),YDWEH2I(tc))
endfunction

function YDWESaveTriggerConditionByString takes string pTable,string pKey,triggercondition tc returns nothing
    call StoreInteger(YDGC,pTable,pKey,YDWEH2I(tc))
endfunction

function YDWEGetTriggerConditionByInteger takes integer pTable,integer pKey returns triggercondition
    return YDWEI2TC(GetStoredInteger(YDGC,I2S(pTable),I2S(pKey)))
endfunction

function YDWEGetTriggerConditionByString takes string pTable,string pKey returns triggercondition
    return YDWEI2TC(GetStoredInteger(YDGC,pTable,pKey))
endfunction

//Covert triggeraction
function YDWESaveTriggerActionByInteger takes integer pTable,integer pKey,triggeraction ta returns nothing
    call StoreInteger(YDGC,I2S(pTable),I2S(pKey),YDWEH2I(ta))
endfunction

function YDWESaveTriggerActionByString takes string pTable,string pKey,triggeraction ta returns nothing
    call StoreInteger(YDGC,pTable,pKey,YDWEH2I(ta))
endfunction

function YDWEGetTriggerActionByInteger takes integer pTable,integer pKey returns triggeraction
    return YDWEI2TA(GetStoredInteger(YDGC,I2S(pTable),I2S(pKey)))
endfunction

function YDWEGetTriggerActionByString takes string pTable,string pKey returns triggeraction
    return YDWEI2TA(GetStoredInteger(YDGC,pTable,pKey))
endfunction

//Covert event
function YDWESaveTriggerEventByInteger takes integer pTable,integer pKey,event et returns nothing
    call StoreInteger(YDGC,I2S(pTable),I2S(pKey),YDWEH2I(et))
endfunction

function YDWESaveTriggerEventByString takes string pTable,string pKey,event et returns nothing
    call StoreInteger(YDGC,pTable,pKey,YDWEH2I(et))
endfunction

function YDWEGetTriggerEventByInteger takes integer pTable,integer pKey returns event
    return YDWEI2Et(GetStoredInteger(YDGC,I2S(pTable),I2S(pKey)))
endfunction

function YDWEGetTriggerEventByString takes string pTable,string pKey returns event
    return YDWEI2Et(GetStoredInteger(YDGC,pTable,pKey))
endfunction

//Covert force
function YDWESaveForceByInteger takes integer pTable,integer pKey,force fc returns nothing
    call StoreInteger(YDGC,I2S(pTable),I2S(pKey),YDWEH2I(fc))
endfunction

function YDWESaveForceByString takes string pTable,string pKey,force fc returns nothing
    call StoreInteger(YDGC,pTable,pKey,YDWEH2I(fc))
endfunction

function YDWEGetForceByInteger takes integer pTable,integer pKey returns force
    return YDWEI2Fc(GetStoredInteger(YDGC,I2S(pTable),I2S(pKey)))
endfunction

function YDWEGetForceByString takes string pTable,string pKey returns force
    return YDWEI2Fc(GetStoredInteger(YDGC,pTable,pKey))
endfunction

//Covert boolexpr
function YDWESaveBoolexprByInteger takes integer pTable,integer pKey,boolexpr be returns nothing
    call StoreInteger(YDGC,I2S(pTable),I2S(pKey),YDWEH2I(be))
endfunction

function YDWESaveBoolexprByString takes string pTable,string pKey,boolexpr be returns nothing
    call StoreInteger(YDGC,pTable,pKey,YDWEH2I(be))
endfunction

function YDWEGetBoolexprByInteger takes integer pTable,integer pKey returns boolexpr
    return YDWEI2BE(GetStoredInteger(YDGC,I2S(pTable),I2S(pKey)))
endfunction

function YDWEGetBoolexprByString takes string pTable,string pKey returns boolexpr
    return YDWEI2BE(GetStoredInteger(YDGC,pTable,pKey))
endfunction

//Covert sound
function YDWESaveSoundByInteger takes integer pTable,integer pKey,sound sd returns nothing
    call StoreInteger(YDGC,I2S(pTable),I2S(pKey),YDWEH2I(sd))
endfunction

function YDWESaveSoundByString takes string pTable,string pKey,sound sd returns nothing
    call StoreInteger(YDGC,pTable,pKey,YDWEH2I(sd))
endfunction

function YDWEGetSoundByInteger takes integer pTable,integer pKey returns sound
    return YDWEI2Sd(GetStoredInteger(YDGC,I2S(pTable),I2S(pKey)))
endfunction

function YDWEGetSoundByString takes string pTable,string pKey returns sound
    return YDWEI2Sd(GetStoredInteger(YDGC,pTable,pKey))
endfunction

//Covert timerdialog
function YDWESaveTimerDialogByInteger takes integer pTable,integer pKey,timerdialog td returns nothing
    call StoreInteger(YDGC,I2S(pTable),I2S(pKey),YDWEH2I(td))
endfunction

function YDWESaveTimerDialogByString takes string pTable,string pKey,timerdialog td returns nothing
    call StoreInteger(YDGC,pTable,pKey,YDWEH2I(td))
endfunction

function YDWEGetTimerDialogByInteger takes integer pTable,integer pKey returns timerdialog
    return YDWEI2TD(GetStoredInteger(YDGC,I2S(pTable),I2S(pKey)))
endfunction

function YDWEGetTimerDialogByString takes string pTable,string pKey returns timerdialog
    return YDWEI2TD(GetStoredInteger(YDGC,pTable,pKey))
endfunction

//Covert trackable
function YDWESaveTrackableByInteger takes integer pTable,integer pKey,trackable ta returns nothing
    call StoreInteger(YDGC,I2S(pTable),I2S(pKey),YDWEH2I(ta))
endfunction

function YDWESaveTrackableByString takes string pTable,string pKey,trackable ta returns nothing
    call StoreInteger(YDGC,pTable,pKey,YDWEH2I(ta))
endfunction

function YDWEGetTrackableByInteger takes integer pTable,integer pKey returns trackable
    return YDWEI2Ta(GetStoredInteger(YDGC,I2S(pTable),I2S(pKey)))
endfunction

function YDWEGetTrackableByString takes string pTable,string pKey returns trackable
    return YDWEI2Ta(GetStoredInteger(YDGC,pTable,pKey))
endfunction

//Covert dialog
function YDWESaveDialogByInteger takes integer pTable,integer pKey,dialog d returns nothing
    call StoreInteger(YDGC,I2S(pTable),I2S(pKey),YDWEH2I(d))
endfunction

function YDWESaveDialogByString takes string pTable,string pKey,dialog d returns nothing
    call StoreInteger(YDGC,pTable,pKey,YDWEH2I(d))
endfunction

function YDWEGetDialogByInteger takes integer pTable,integer pKey returns dialog
    return YDWEI2D(GetStoredInteger(YDGC,I2S(pTable),I2S(pKey)))
endfunction

function YDWEGetDialogByString takes string pTable,string pKey returns dialog
    return YDWEI2D(GetStoredInteger(YDGC,pTable,pKey))
endfunction

//Covert button
function YDWESaveButtonByInteger takes integer pTable,integer pKey,button bt returns nothing
    call StoreInteger(YDGC,I2S(pTable),I2S(pKey),YDWEH2I(bt))
endfunction

function YDWESaveButtonByString takes string pTable,string pKey,button bt returns nothing
    call StoreInteger(YDGC,pTable,pKey,YDWEH2I(bt))
endfunction

function YDWEGetButtonByInteger takes integer pTable,integer pKey returns button
    return YDWEI2Bt(GetStoredInteger(YDGC,I2S(pTable),I2S(pKey)))
endfunction

function YDWEGetButtonByString takes string pTable,string pKey returns button
    return YDWEI2Bt(GetStoredInteger(YDGC,pTable,pKey))
endfunction

//===========================================================================
//===========================================================================
//Custom functions added by wataloo&Everguo
//===========================================================================
//===========================================================================

//===========================================================================  
//返回参数 
//===========================================================================
//地图边界判断   
function YDWECoordinateX takes real x returns real    
    set x=RMaxBJ(x,GetCameraBoundMinX())  
    set x=RMinBJ(x,GetCameraBoundMaxX())  
    return x
endfunction

function YDWECoordinateY takes real y returns real
    set y=RMaxBJ(y,GetCameraBoundMinY())  
    set y=RMinBJ(y,GetCameraBoundMaxY())  
    return y
endfunction  
//两个单位之间的距离 
function YDWEDistanceBetweenUnits takes unit a,unit b returns real
    return SquareRoot((GetUnitX(a)-GetUnitX(b))*(GetUnitX(a)-GetUnitX(b))+(GetUnitY(a)-GetUnitY(b))*(GetUnitY(a)-GetUnitY(b)))
endfunction
//两个单位之间的角度 
function YDWEAngleBetweenUnits takes unit from, unit to returns real
    return bj_RADTODEG * Atan2(GetUnitY(to) - GetUnitY(from), GetUnitX(to) - GetUnitX(from))
endfunction
//生成区域 
function YDWEGetRect takes real x,real y,real width, real height returns rect
    return Rect( x - width*0.5, y - height*0.5, x + width*0.5, y + height*0.5 )
endfunction


//===========================================================================
//设置单位可以飞行 
//===========================================================================
function YDWEFlyEnable takes unit u returns nothing         
    call UnitAddAbility(u,'Amrf')
    call UnitRemoveAbility(u,'Amrf')             
endfunction  

//===========================================================================
//字符窜与ID转换 
//===========================================================================
function YDWEId2S takes integer value returns string         
    local string charMap=bj_AllString
    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   

function YDWES2Id takes string targetstr returns integer
    local string originstr=bj_AllString
    local integer strlength=StringLength(targetstr)
    local integer a=0                  //分部当前数字 
    local integer b=0               //当前处理字   
    local integer numx=1      //位权 
    local integer result=0
    loop
    exitwhen b>strlength-1
        set numx=R2I(Pow(256,strlength-1-b))
        set a=1
        loop
            exitwhen a>255
            if SubString(targetstr,b,b+1)==SubString(originstr,a,a+1) then
                set result=result+a*numx
                set a=256
            endif
            set a=a+1
        endloop
        set b=b+1
    endloop
    return result
endfunction

function YDWES2UnitId takes string targetstr returns integer  
    return YDWES2Id(targetstr) 
endfunction

function YDWES2ItemId takes string targetstr returns integer  
    return YDWES2Id(targetstr) 
endfunction

//===========================================================================
//系统函数完善 
//===========================================================================
function YDWEIfThenElse takes boolexpr b,code c1,code c2 returns nothing  
    local trigger trg=CreateTrigger()
    local triggercondition tc=TriggerAddCondition(trg,b)       
    local boolean b1=TriggerEvaluate(trg) 
    if b1==true then  
        call TimerStart(CreateTimer(),0,false,c1)
      else
        call TimerStart(CreateTimer(),0,false,c2)
    endif 
    call TriggerRemoveCondition(trg,tc)     
    //call DestroyCondition(tc)
    call DestroyTrigger(trg)
    set trg=null
    set tc=null
endfunction  

function YDWEIfThenElseMultiple takes nothing returns nothing  
    
endfunction                         
function YDWEForLoopAMultiple takes nothing returns nothing  
endfunction    

function YDWECreateUnitPool takes nothing returns nothing  
    set bj_lastCreatedUnitPool=CreateUnitPool()
endfunction   

function YDWEPlaceRandomUnit takes unitpool up,player p,real x,real y,real face returns nothing     //unitpool,player,real,real,real
    set bj_lastPoolAbstractedUnit=PlaceRandomUnit(up,p,x,y,face)
endfunction  

function YDWEGetLastUnitPool takes nothing returns unitpool  
    return bj_lastCreatedUnitPool
endfunction 

function YDWEGetLastPoolAbstractedUnit takes nothing returns unit   
    return bj_lastPoolAbstractedUnit
endfunction 

function YDWECreateItemPool takes nothing returns nothing  
    set bj_lastCreatedItemPool=CreateItemPool()
endfunction  

function YDWEPlaceRandomItem takes itempool ip,real x,real y returns nothing     //unitpool,player,real,real,real
    set bj_lastPoolAbstractedItem=PlaceRandomItem(ip,x,y)
endfunction 

function YDWEGetLastItemPool takes nothing returns itempool  
    return bj_lastCreatedItemPool
endfunction 

function YDWEGetLastPoolAbstractedItem takes nothing returns item  
    return bj_lastPoolAbstractedItem
endfunction 
      //unitpool bj_lastCreatedPool=null 
    //unit bj_lastPoolAbstractedUnit=null	

//===========================================================================
//飘动的红丝带
//===========================================================================    
function YDWESetline takes nothing returns nothing
    local timer t = GetExpiredTimer()          
    local unit tru = YDWEGetUnitByString(I2S(YDWEH2I(t)),"tru")
    local integer count = YDWEGetIntegerByString(I2S(YDWEH2I(t)),"count") 
    local integer steps = YDWEGetIntegerByString(I2S(YDWEH2I(t)),"steps") 
    local integer stepscount = YDWEGetIntegerByString(I2S(YDWEH2I(t)),"stepscount") 
    local integer position = YDWEGetIntegerByString(I2S(YDWEH2I(t)),"position")         
    local real ux = GetUnitX(tru)
    local real uy = GetUnitY(tru)
    local real mjx
    local real mjy
    local real distance = YDWEGetRealByString(I2S(YDWEH2I(t)),"distance")
    local real angleadd = YDWEGetRealByString(I2S(YDWEH2I(t)),"angleadd")
    local unit array tempu
    local real array tempx
    local real array tempy
    local real array angle
    local integer i = 0
    local integer n = 0
    loop
        exitwhen i>count
        set tempu[i] = YDWEGetUnitByString(I2S(YDWEH2I(t)),I2S(1000+i))
        set angle[i] = YDWEGetRealByString(I2S(YDWEH2I(t)),I2S(2000+i))
        set tempx[i] = YDWEGetRealByString(I2S(YDWEH2I(t)),I2S(3000+i))
        set tempy[i] = YDWEGetRealByString(I2S(YDWEH2I(t)),I2S(4000+i))
        set i = i + 1
    endloop
    set i = 0
    if (steps > stepscount) or GetUnitState(tru,UNIT_STATE_LIFE)<=0  then
        loop
            exitwhen i == count
            call RemoveUnit(YDWEGetUnitByString(I2S(YDWEH2I(t)),I2S(1000+i)))
            set i = i + 1
        endloop                                                  
        call YDWEFlushMissionByString(I2S(YDWEH2I(t)))
        call PauseTimer(t)
        call DestroyTimer(t)
        //call SetUnitScalePercent( tru, 100, 100, 100 )
        return
    endif
    set i = 0
    loop
        exitwhen i == count
        set n = ModuloInteger(position + i,count)
        set mjx = GetUnitX(tempu[i])
        set mjy = GetUnitY(tempu[i])
        set mjx = mjx + (tempx[n] + i*distance*CosBJ(angle[n]) - mjx) * 0.2
        set mjy = mjy + (tempy[n] + i*distance*SinBJ(angle[n]) - mjy) * 0.2
        call SetUnitX(tempu[i],mjx)
        call SetUnitY(tempu[i],mjy)
        set i =  i + 1
    endloop
    set steps = steps + 1
    call YDWESaveIntegerByString(I2S(YDWEH2I(t)),"steps",steps)      
    set position = ModuloInteger(position - 1 , count)
    call YDWESaveRealByString(I2S(YDWEH2I(t)),I2S(2000+position),GetUnitFacing(tru) + 180 + angleadd) 
    call YDWESaveRealByString(I2S(YDWEH2I(t)),I2S(3000+position),ux)
    call YDWESaveRealByString(I2S(YDWEH2I(t)),I2S(4000+position),uy)        
    call YDWESaveIntegerByString(I2S(YDWEH2I(t)),"position",position)  
endfunction


//红丝带的先决条件            (udg_cinS_actor[11],'h01J',12,50,60,30,0.03,120,10,100,30)
function YDWECreateLine takes unit tru,integer ut,integer count,real angleadd,real distance,real lasttime,real eachtime,real heightstart,real heightadd,real sizestart,real sizeadd returns nothing
    local timer t = CreateTimer()
    local real ux = GetUnitX(tru)
    local real uy = GetUnitY(tru)
    local real angle = GetUnitFacing(tru) + 180 + angleadd
    local player p = GetOwningPlayer(tru)
    local integer i = 0
    local unit array tempu
    call YDWESaveUnitByString(I2S(YDWEH2I(t)),"tru",tru)  
    call YDWESaveIntegerByString(I2S(YDWEH2I(t)),"count",count)
    call YDWESaveIntegerByString(I2S(YDWEH2I(t)),"steps",0)
    call YDWESaveIntegerByString(I2S(YDWEH2I(t)),"stepscount",R2I(lasttime/eachtime))
    call YDWESaveRealByString(I2S(YDWEH2I(t)),"distance",distance)
    call YDWESaveRealByString(I2S(YDWEH2I(t)),"angleadd",angleadd)    
    call GroupClear(bj_lastCreatedGroup)
    loop
        exitwhen i==count
        set tempu[i] = CreateUnit(p,ut,ux,uy,0)
        call GroupAddUnit(bj_lastCreatedGroup, tempu[i])
        set bj_lastCreatedUnit=tempu[i]
        call SetUnitFlyHeight( tempu[i],i*heightadd+heightstart+150, 75 )
        call SetUnitScalePercent( tempu[i], RMaxBJ(i*sizeadd+sizestart,1),RMaxBJ(i*sizeadd+sizestart,1),RMaxBJ(i*sizeadd+sizestart,1))
        call YDWESaveUnitByString(I2S(YDWEH2I(t)),I2S(1000+i),tempu[i])
        call YDWESaveRealByString(I2S(YDWEH2I(t)),I2S(2000+i),angle)
        call YDWESaveRealByString(I2S(YDWEH2I(t)),I2S(3000+i),ux)
        call YDWESaveRealByString(I2S(YDWEH2I(t)),I2S(4000+i),uy)
        set i = i + 1
    endloop
    call YDWESaveRealByString(I2S(YDWEH2I(t)),"position",0)
    call TimerStart(t,eachtime,true,function YDWESetline)
    set t = null
    set p = null
endfunction

//===========================================================================
//修改生命
//===========================================================================
function YDWELifeChange takes unit u,integer mod,integer ch,integer aid returns nothing
    local integer a
    local integer b
    local integer c
    local integer d    
    if mod==1 then
        set ch=-ch
      elseif mod==2 then
        set ch=ch-R2I(GetUnitState(u,UNIT_STATE_MAX_LIFE))
    endif   
    if ch>99999 then
        set ch=99999
    endif
    if ch<-99999 then
        set ch=-99999
    endif
    if ch<0 then
        set a=2
        set ch=-ch
    else
        set a=7
    endif
    set b=0
    loop
        exitwhen b==5
        set c=ch-ch/10*10
        set d=0
        loop
            exitwhen d==c
            call UnitAddAbility(u,aid)
            call SetUnitAbilityLevel(u,aid,a)
            call UnitRemoveAbility(u,aid)
            set d=d+1
        endloop
        set ch=ch/10
        set a=a+1
        set b=b+1
    endloop
endfunction

//===========================================================================
//修改魔法
//===========================================================================
function YDWEManaChange takes unit u,integer mod,integer ch,integer aid returns nothing
    local integer a
    local integer b
    local integer c
    local integer d
    if mod==1 then
        set ch=-ch
      elseif mod==2 then
        set ch=ch-R2I(GetUnitState(u,UNIT_STATE_MAX_MANA))
    endif      
    if ch>99999 then
        set ch=99999
    endif
    if ch<-99999 then
        set ch=-99999
    endif
    if ch<0 then
        set a=2
        set ch=-ch
    else
        set a=7
    endif
    set b=0
    loop
        exitwhen b==5
        set c=ch-ch/10*10
        set d=0
        loop
            exitwhen d==c
            call UnitAddAbility(u,aid)
            call SetUnitAbilityLevel(u,aid,a)
            call UnitRemoveAbility(u,aid)
            set d=d+1
        endloop
        set ch=ch/10
        set a=a+1
        set b=b+1
    endloop
endfunction

//===========================================================================
//修改防御
//===========================================================================
//function YDWEDefendModifier takes unit u,integer N,integer a0,integer a1,integer a2,integer a3,integer a4,integer a5,integer a6.integer a7,integer a8,integer a9,integer a10 returns nothing

function YDWEDefendModifier takes unit u,integer N returns nothing
    local integer i=0
    local integer m=0
    local integer array ab
    set N=IMinBJ(2047,N)
    set N=IMaxBJ(0,N)
   // set ab[0]=a0
  //  set ab[1]=a1
  //  set ab[2]=a2
  //  set ab[3]=a3
  //  set ab[4]=a4
  //  set ab[5]=a5
  //  set ab[6]=a6
  //  set ab[7]=a7
  //  set ab[8]=a8
  //  set ab[9]=a9
 //   set ab[10]=a10
    set i=0  
    loop
        exitwhen i>=10
        call UnitRemoveAbility(u,ab[i]) 
        set i=i+1
    endloop     
    set i=0    
    loop                 
        exitwhen i>=10             
        if ModuloInteger(N,2)!=0 then
            call UnitAddAbility(u,ab[i])                          
        endif
        set N=N/2
        if N==0 then
            set i=10  
        endif    
        set i=i+1          
    endloop        
endfunction            

//===========================================================================
//修改攻击
//===========================================================================
function YDWEAttackModifier takes unit u,integer N returns nothing
    local integer i=0
    local integer m=0
    local integer array ab
    set N=IMinBJ(2047,N)
    set N=IMaxBJ(0,N)
    set ab[0]='AItg'
    set ab[1]='AIth'
    set ab[2]='AIti'
    set ab[3]='AItl'
    set ab[4]='AIat'
    set ab[5]='AItj'
    set ab[6]='AItn'
    set ab[7]='AItf'
    set ab[8]='AItc'
    set ab[9]='AIt9'
    set ab[10]='AItk'
    set i=0  
    loop
        exitwhen i>=11
        call UnitRemoveAbility(u,ab[i]) 
        set i=i+1
    endloop     
    set i=0    
    loop                 
        exitwhen i>=11             
        if ModuloInteger(N,2)!=0 then
            call UnitAddAbility(u,ab[i])                          
        endif
        set N=N/2
        if N==0 then
            set i=11  
        endif    
        set i=i+1          
    endloop        
endfunction   

//===========================================================================
//环绕技能模板 
//===========================================================================
function YDWEEwsp_LOOP takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local unit array tempUnit 
    local real array angle 
    local integer i = 0
    local unit orderUnit=YDWEGetUnitByString(I2S(YDWEH2I(t)),"orderUnit")     
    local real UnitLocX = GetUnitX(orderUnit)
    local real UnitLocY = GetUnitY(orderUnit)
    local real tempLocX  
    local real tempLocY  
    local real radius = YDWEGetRealByString(I2S(YDWEH2I(t)),"radius")    
    local real S = YDWEGetRealByString(I2S(YDWEH2I(t)),"speed") 
    local integer N = YDWEGetIntegerByString(I2S(YDWEH2I(t)),"number") 
    local integer steps = YDWEGetIntegerByString(I2S(YDWEH2I(t)),"steps") 
    if steps>0  then     
      set steps=steps-1
      call  YDWESaveIntegerByString(I2S(YDWEH2I(t)),"steps",steps)                  
      loop
          exitwhen i>N
          set i=i+1
          set tempUnit[i]=YDWEGetUnitByString(I2S(YDWEH2I(t)),I2S(1000+i)) 
          set angle[i]=YDWEGetRealByString(I2S(YDWEH2I(t)),I2S(2000+i)) 
          set angle[i]=angle[i]+S
          set tempLocX = UnitLocX + radius*CosBJ(angle[i])
          set tempLocY = UnitLocY + radius*SinBJ(angle[i])
          call SetUnitX(tempUnit[i],tempLocX)
          call SetUnitY(tempUnit[i],tempLocY)
          call YDWESaveRealByString(I2S(YDWEH2I(t)),I2S(2000+i),angle[i]) 
          set tempUnit[i]=null     
      endloop
      else 
        set i=0
        loop
            set i=i+1 
            exitwhen i>N            
            call RemoveUnit(YDWEGetUnitByString(I2S(YDWEH2I(t)),I2S(1000+i)))                     
        endloop 
        call YDWEFlushMissionByString(I2S(YDWEH2I(t)))
        call DestroyTimer(t)        
    endif
    set orderUnit=null
endfunction

function YDWECreateEwsp takes unit Hero,integer ewsp,integer N,real R,real T,real I,real S returns nothing
    local unit orderUnit=Hero
    local real UnitLocX = GetUnitX(orderUnit)
    local real UnitLocY = GetUnitY(orderUnit)  
    local unit array tempUnit  
    local player Masterplayer = GetOwningPlayer(orderUnit)
    local timer t=CreateTimer()
    local real interval=I
    local real lasttime=T
    local real radius=R
    local real tempLocX  
    local real tempLocY 
    local real array angle 
    local integer i=0
    local integer steps=R2I(lasttime/interval)
    call YDWESaveIntegerByString(I2S(YDWEH2I(t)),"steps",steps)      
    call YDWESaveIntegerByString(I2S(YDWEH2I(t)),"number",N) 
    call YDWESaveRealByString(I2S(YDWEH2I(t)),"radius",radius)
    call YDWESaveRealByString(I2S(YDWEH2I(t)),"speed",S)
    call GroupClear(bj_lastCreatedGroup)
    loop
        set i=i+1
        exitwhen (i>N)
        set tempLocX = UnitLocX + radius*Cos(2*i*bj_PI/N)       
        set tempLocY = UnitLocY + radius*Sin(2*i*bj_PI/N)
        set angle[i] = 180*Atan2(UnitLocY - tempLocY, UnitLocX - tempLocX)/bj_PI
        set tempUnit[i]=CreateUnit(Masterplayer,ewsp,tempLocX,tempLocY,angle[i])
        call YDWESaveUnitByString(I2S(YDWEH2I(t)),I2S(1000+i),tempUnit[i])
        call YDWESaveIntegerByString(I2S(YDWEH2I(t)),I2S(1000+i),YDWEH2I(tempUnit[i])) 
        call UnitGenerateAlarms( tempUnit[i], false )
        call YDWESaveRealByString(I2S(YDWEH2I(t)),I2S(2000+i),angle[i]) 
        call GroupAddUnit(bj_lastCreatedGroup, tempUnit[i])
        set bj_lastCreatedUnit=tempUnit[i]
    endloop 
    call YDWESaveUnitByString(I2S(YDWEH2I(t)),"orderUnit",orderUnit) 
    call TimerStart(t,interval,true,function YDWEEwsp_LOOP)
    set t=null   
    set orderUnit=null
    set i=0
    loop
        set i=i+1  
        exitwhen (i>N) 
        set tempUnit[i]=null
    endloop
endfunction

//===========================================================================
//佣兵系统 
//===========================================================================
function YDWEGetUnitCurrentFree_Func takes unit u returns boolean
    local string s = OrderId2String(GetUnitCurrentOrder(u))
    if s == null then 
        return true
    endif
    return false    
endfunction

function YDWERemoveGuard takes unit pet returns nothing
    local integer tm = YDWEGetIntegerByString( I2S(YDWEH2I(pet)), "Timer")
    call YDWEFlushMissionByString(I2S(YDWEH2I(pet)))
    call YDWEFlushMissionByString(I2S(tm))
    call DestroyTimer(YDWEGetTimerByString(I2S(YDWEH2I(pet)), "Timer"))
endfunction

function YDWESetGuard_Func takes nothing returns nothing
  local timer tm = GetExpiredTimer()
  local unit pet = (YDWEGetUnitByString( I2S(YDWEH2I(tm)), "Pet"))
  local unit captain = (YDWEGetUnitByString( I2S(YDWEH2I(tm)), "Captain"))
  local real x = GetUnitX(captain) - GetUnitX(pet)
  local real y = GetUnitY(captain) - GetUnitY(pet)
  local real d = x*x + y*y
  local real v
  local real a
  local effect e=null
  local real life = YDWEGetRealByString( I2S(YDWEH2I(tm)), "Life")
  local integer p = YDWEGetIntegerByString(I2S(YDWEH2I(tm)), "Percent")
  set v = YDWEGetRealByString( I2S(YDWEH2I(tm)), "GuardRanger")      
  if GetUnitState(pet, UNIT_STATE_LIFE)>0 and GetUnitState(captain, UNIT_STATE_LIFE)> 0 then   
      if d<v*v then
         if YDWEGetUnitCurrentFree_Func(pet)==true and GetRandomInt(0,100)<p then
           set x = GetUnitX(captain)
           set y = GetUnitY(captain)
           set d = GetRandomReal(0,v)
           set a = GetRandomReal(0,360)
           call IssuePointOrder(pet, "patrol", x+d*CosBJ(a), y+d*SinBJ(a))
         endif
      else
        set v = YDWEGetRealByString( I2S(YDWEH2I(tm)), "ReturnRanger")
        if d<v*v then
          if YDWEGetUnitCurrentFree_Func(pet)==true  then
            call IssuePointOrder(pet, "patrol", GetUnitX(captain), GetUnitY(captain))
          endif
        else
          set v = YDWEGetRealByString( I2S(YDWEH2I(tm)), "OutRanger")
            if d!=0 and d>v*v then
              call SetUnitPosition(pet,GetUnitX(captain),GetUnitY(captain))
              set e =AddSpecialEffectTarget("Abilities\\Spells\\Human\\MassTeleport\\MassTeleportTarget.mdl" ,captain,"chest")
              call DestroyEffect(e)
            else
              call IssuePointOrder(pet, "move", GetUnitX(captain), GetUnitY(captain))
            endif
          endif
       endif
     else
       call IssuePointOrder(pet, "attack", GetUnitX(captain), GetUnitY(captain))
       call YDWERemoveGuard(pet)   
  endif
  set tm = null
  set pet = null
  set captain = null
  set e=null
endfunction


function YDWESetGuard takes unit pet, unit captain, real timeout, real guardRanger, real returnRanger, real outRanger,integer percent returns nothing
    local timer tm = CreateTimer()  
    call YDWESaveTimerByString(I2S(YDWEH2I(pet)), "Timer", tm)
    call YDWESaveUnitByString(I2S(YDWEH2I(tm)), "pet",pet)
    call YDWESaveUnitByString(I2S(YDWEH2I(tm)), "Captain",captain)
    call YDWESaveIntegerByString( I2S(YDWEH2I(tm)), "Percent", percent)   
    call YDWESaveRealByString( I2S(YDWEH2I(tm)), "GuardRanger", guardRanger)    
    call YDWESaveRealByString( I2S(YDWEH2I(tm)), "ReturnRanger", returnRanger)   
    call YDWESaveRealByString( I2S(YDWEH2I(tm)), "OutRanger", outRanger)
    call TimerStart(tm, timeout, true, function YDWESetGuard_Func)
    set tm = null
endfunction

//===========================================================================
//跳跃系统 
//===========================================================================
function YDWEJumpTimerLoop takes nothing returns nothing
    local timer t=GetExpiredTimer()
    local unit hero=(YDWEGetUnitByString(I2S(YDWEH2I(t)),"Hero"))
    local real angle=YDWEGetRealByString(I2S(YDWEH2I(t)),"Angle")
    local integer steeps=YDWEGetIntegerByString(I2S(YDWEH2I(t)),"steeps")
    local integer steepsMax=YDWEGetIntegerByString(I2S(YDWEH2I(t)),"steepsMax")
    local real heightMax=YDWEGetRealByString(I2S(YDWEH2I(t)),"heightMax")
    local real dist=YDWEGetRealByString(I2S(YDWEH2I(t)),"dist")
    local real dheig=YDWEGetRealByString(I2S(YDWEH2I(t)),"dheig")
    local real OriginHeight=YDWEGetRealByString(I2S(YDWEH2I(t)),"OriginHeight")
    local real x=YDWEGetRealByString(I2S(YDWEH2I(t)),"X")
    local real y=YDWEGetRealByString(I2S(YDWEH2I(t)),"Y")
    local real x1=0
    local real y1=0
    local real height=0  
    local integer lvJumpTimer=MoveMoreLevel_JumpTimer    
    local integer lvUnitMove=YDWEGetIntegerByString(I2S(YDWEH2I(hero)),"lvUnitMove")      
    if steeps<steepsMax and lvJumpTimer>=lvUnitMove then
        set x1=x+steeps*dist*Cos(angle*3.14159/180.0)
        set y1=y+steeps*dist*Sin(angle*3.14159/180.0)
        set x1=YDWECoordinateX(x1)
        set y1=YDWECoordinateY(y1)
        call SetUnitX(hero,x1)
        call SetUnitY(hero,y1)
        set steeps=steeps+1
        call YDWESaveIntegerByString(I2S(YDWEH2I(t)),"steeps",steeps) 
        set height=(-(2*I2R(steeps)*dheig-1)*(2*I2R(steeps)*dheig-1)+1)*heightMax+OriginHeight      
        call SetUnitFlyHeight(hero,height,99999)    
        call SetUnitFacing(hero,angle)             
      else               
        call SetUnitFlyHeight(hero,OriginHeight,99999)
        call SetUnitPathing(hero, true )
        call DestroyTimer(t)
        call YDWEFlushMissionByString(I2S(YDWEH2I(t)))
        call YDWESaveIntegerByString(I2S(YDWEH2I(hero)),"lvUnitMove",0)  
    endif
    set t=null
    set hero=null    
endfunction
                            

function YDWEJumpTimer takes unit hero,real angle,real distance,real lasttime,real timeout,real heightMax returns nothing
    local timer t=null
    local real x=GetUnitX(hero)
    local real y=GetUnitY(hero)
    local integer steepsMax=R2I(lasttime/timeout)
    local integer steeps=0
    local real dist=distance/steepsMax     
    local real dheig=1.0/steepsMax  
    local real OriginHeight=GetUnitFlyHeight(hero)
    local integer lvJumpTimer=MoveMoreLevel_JumpTimer 
    local integer lvUnitMove=YDWEGetIntegerByString(I2S(YDWEH2I(hero)),"lvUnitMove")     
    if lvJumpTimer>lvUnitMove then
        set t=CreateTimer()
        set lvUnitMove=lvJumpTimer
        call YDWESaveIntegerByString(I2S(YDWEH2I(hero)),"lvUnitMove",lvUnitMove)  
      else
        return
    endif                                          
    call UnitAddAbility(hero,'Amrf')
    call UnitRemoveAbility(hero,'Amrf')
    call SetUnitPathing(hero,false)          
    call YDWESaveUnitByString(I2S(YDWEH2I(t)),"Hero",hero)
    call YDWESaveRealByString(I2S(YDWEH2I(t)),"OriginHeight",OriginHeight)   
    call YDWESaveRealByString(I2S(YDWEH2I(t)),"Angle",angle)    
    call YDWESaveRealByString(I2S(YDWEH2I(t)),"dist",dist)
    call YDWESaveRealByString(I2S(YDWEH2I(t)),"heightMax",heightMax)
    call YDWESaveRealByString(I2S(YDWEH2I(t)),"dheig",dheig)
    call YDWESaveRealByString(I2S(YDWEH2I(t)),"X",x)
    call YDWESaveRealByString(I2S(YDWEH2I(t)),"Y",y)      
    call YDWESaveIntegerByString(I2S(YDWEH2I(t)),"steeps",steeps)  
    call YDWESaveIntegerByString(I2S(YDWEH2I(t)),"steepsMax",steepsMax)   
    call TimerStart(t,timeout,true,function YDWEJumpTimerLoop)
    set t = null
endfunction

//===========================================================================
//刷兵系统 
//===========================================================================
function YDWEAttackWave takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local real x1 = YDWEGetRealByString( "AttackWave"+I2S(YDWEH2I(t)), "x1")
    local real y1 = YDWEGetRealByString( "AttackWave"+I2S(YDWEH2I(t)), "y1")
    local real x2 = YDWEGetRealByString( "AttackWave"+I2S(YDWEH2I(t)), "x2")
    local real y2 = YDWEGetRealByString( "AttackWave"+I2S(YDWEH2I(t)), "y2")
    local real face = YDWEGetRealByString( "AttackWave"+I2S(YDWEH2I(t)), "face")
    local integer N = YDWEGetIntegerByString( "AttackWave"+I2S(YDWEH2I(t)), "N")
    local integer unitid = YDWEGetIntegerByString( "AttackWave"+I2S(YDWEH2I(t)), "unitid")
    local player p = Player(YDWEGetIntegerByString("AttackWave"+I2S(YDWEH2I(t)), "playerid"))     
    local unit tempUnit
    local integer n = 0   
    call GroupClear(bj_lastCreatedGroup)                                                            
    loop              
        exitwhen (n>=N) 
        set tempUnit = CreateUnit(p,unitid,x1,y1,face)  
        call GroupAddUnit(bj_lastCreatedGroup, tempUnit) 
        set bj_lastCreatedUnit=tempUnit      
        call IssuePointOrder(tempUnit, "attack", x2,y2) 
        set n=n+1
        set tempUnit = null
    endloop    
endfunction

function YDWEAttackWaveTimer takes player p,integer N,integer unitid,location whichLocation,real face,location TargetLocation,real timeout returns nothing
    local  real x1 = GetLocationX(whichLocation)
    local  real y1 = GetLocationY(whichLocation)  
    local  real x2 = GetLocationX(TargetLocation) 
    local  real y2 = GetLocationY(TargetLocation)   
    local  timer t = CreateTimer()   
    call YDWESaveIntegerByString( "AttackWave"+I2S(unitid)+R2S(x1)+R2S(y1)+R2S(timeout), "Timer", YDWEH2I(t))
    call YDWESaveIntegerByString( "AttackWave"+I2S(YDWEH2I(t)), "unitid", unitid)
    call YDWESaveIntegerByString( "AttackWave"+I2S(YDWEH2I(t)), "playerid", GetPlayerId(p))
    call YDWESaveIntegerByString( "AttackWave"+I2S(YDWEH2I(t)), "N", N)   
    call YDWESaveRealByString( "AttackWave"+I2S(YDWEH2I(t)), "x1", x1)       
    call YDWESaveRealByString( "AttackWave"+I2S(YDWEH2I(t)), "y1", y1)        
    call YDWESaveRealByString( "AttackWave"+I2S(YDWEH2I(t)), "x2", x2)        
    call YDWESaveRealByString( "AttackWave"+I2S(YDWEH2I(t)), "y2", y2)
    call YDWESaveRealByString( "AttackWave"+I2S(YDWEH2I(t)), "face", face)  
    call YDWESaveIntegerByString( "AttackWaveLastTimer", "Timer", YDWEH2I(t))
    call YDWESaveStringByString( "AttackWave"+I2S(YDWEH2I(t)), "Store", "AttackWave"+I2S(unitid)+R2S(x1)+R2S(y1)+R2S(timeout))
    call TimerStart(t,timeout,true,function YDWEAttackWave) 
    call RemoveLocation(whichLocation)   
    set t = null
endfunction

function YDWERemoveAttackWaveByUnitID takes integer unitid,location whichLocation,real timeout returns nothing
    local integer t = YDWEGetIntegerByString( "AttackWave"+I2S(unitid)+R2S(GetLocationX(whichLocation))+R2S(GetLocationY(whichLocation))+R2S(timeout), "Timer")
    call YDWEFlushMissionByString( "AttackWave"+I2S(unitid)+I2S(YDWEH2I(whichLocation))+R2S(timeout))    
// YDWEFlushMissionByString(    YDWEFlushMissionByString(
    call YDWEFlushMissionByString( "AttackWave"+I2S(t))
    call DestroyTimer(YDWEGetTimerByString("AttackWave"+I2S(unitid)+R2S(GetLocationX(whichLocation))+R2S(GetLocationY(whichLocation))+R2S(timeout), "Timer"))
endfunction

function YDWERemoveAttackWaveByTimer takes timer t returns nothing
    call YDWEFlushMissionByString( YDWEGetStringByString("AttackWave"+I2S(YDWEH2I(t)), "Store"))
    call YDWEFlushMissionByString( "AttackWave"+I2S(YDWEH2I(t)))
    call DestroyTimer(t)
endfunction   

function YDWERemoveAttackWaveReturnTimer takes nothing returns timer
    return YDWEGetTimerByString("AttackWaveLastTimer","Timer")
endfunction

//===========================================================================
//AI-自动学习技能 
//===========================================================================
 function YDWEAIStringFind takes string subject,string find,integer offset returns integer
    local integer len = StringLength(find)
    local integer pos = offset
    local string s
    local string str    
    if ( offset < 1 ) then
        set pos = 1
    endif 
    if ( find == "" ) then
        return -1
    endif   
    loop
        set s = SubString(subject, pos-1, pos+len-1)
        if ( s == find ) then
            return pos
        endif
        if ( SubString(subject, pos-1, pos) == "" ) then
            return -1
        endif
        set pos = pos + 1
    endloop
    return -1
endfunction                       

function YDWEAIRecordAbility takes integer uid,integer ab1,integer ab2,integer ab3,integer ab4,integer ab5 returns nothing
    call YDWESaveIntegerByString("HeroAbilities",I2S(uid)+"_1",ab1)
    call YDWESaveIntegerByString("HeroAbilities",I2S(uid)+"_2",ab2)
    call YDWESaveIntegerByString("HeroAbilities",I2S(uid)+"_3",ab3)
    call YDWESaveIntegerByString("HeroAbilities",I2S(uid)+"_4",ab4)
    call YDWESaveIntegerByString("HeroAbilities",I2S(uid)+"_5",ab5)
endfunction

function YDWEAIRecordLearn_sequence takes integer uid,string ls1,string ls2,string ls3,string ls4,string ls5 returns nothing
    call YDWESaveStringByString("learn_quence",I2S(uid)+"_1",ls1)
    call YDWESaveStringByString("learn_quence",I2S(uid)+"_2",ls2)
    call YDWESaveStringByString("learn_quence",I2S(uid)+"_3",ls3)
    call YDWESaveStringByString("learn_quence",I2S(uid)+"_4",ls4)
    call YDWESaveStringByString("learn_quence",I2S(uid)+"_5",ls5)
endfunction

function YDWEHeroLearnSkillAI takes unit hero,integer level returns integer
    local string array learn_sequence
    local integer numofskill = 5
    local integer array skills
    local integer i = 1
    local integer learnskill  
    local integer uid=GetUnitTypeId(hero) 
    set skills[1] = YDWEGetIntegerByString("HeroAbilities",I2S(uid)+"_1")
    set skills[2] = YDWEGetIntegerByString("HeroAbilities",I2S(uid)+"_2")
    set skills[3] = YDWEGetIntegerByString("HeroAbilities",I2S(uid)+"_3")
    set skills[4] = YDWEGetIntegerByString("HeroAbilities",I2S(uid)+"_4")
    set skills[5] = YDWEGetIntegerByString("HeroAbilities",I2S(uid)+"_5")
    set learn_sequence[1] = YDWEGetStringByString("learn_quence",I2S(uid)+"_1")
    set learn_sequence[2] = YDWEGetStringByString("learn_quence",I2S(uid)+"_2")
    set learn_sequence[3] = YDWEGetStringByString("learn_quence",I2S(uid)+"_3")
    set learn_sequence[4] = YDWEGetStringByString("learn_quence",I2S(uid)+"_4")
    set learn_sequence[5] = YDWEGetStringByString("learn_quence",I2S(uid)+"_5")       
    loop
        exitwhen i > numofskill     
        if YDWEAIStringFind(learn_sequence[i] , "^" + I2S(level) + "^", 1) != -1 then
        //trace msg          
            if GetUnitAbilityLevel(hero,skills[i])==0 then      
                call UnitAddAbility(hero,skills[i])
              else      
                call IncUnitAbilityLevel(hero,skills[i])    
            endif            
            call UnitModifySkillPoints(hero, -1)               
           // call SelectHeroSkill(hero,skills[i])
           // call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 3600, ( "学习  " + GetAbilityName(skills[i])+ "，" +  "目前技能等级为" +I2S(GetUnitAbilityLevel(hero,skills[i]))))   
            return skills[i]
        endif
        set i = i + 1
    endloop
    return 0
endfunction                                                 

function YDWEHeroMaxSkillAI takes unit hero returns nothing
    local integer level = GetHeroLevel(hero)
    local integer uid = GetUnitTypeId(hero)
    local integer numofskill = 5
    local integer i=0
    local integer array skills
    call ModifyHeroSkillPoints( hero, bj_MODIFYMETHOD_SET, level )    
    loop 
        set i = i + 1 
        exitwhen i>5
        call UnitRemoveAbility(hero,YDWEGetIntegerByString("HeroAbilities",I2S(uid)+"_"+I2S(i)))         
    endloop   
    set i = 0
    loop  
        set i = i + 1         
        exitwhen i>level           
        call  YDWEHeroLearnSkillAI(hero,i)
    endloop    
endfunction


//===========================================================================
//技能-钩子 
//===========================================================================

//===========================================================================
function YDWEIcanFly takes nothing returns nothing
	local timer Mt=GetExpiredTimer()
	local timer Mtt=YDWEGetTimerByString(I2S(YDWEH2I(Mt)),"ExtendCache")
	local string ors=I2S(YDWEH2I(Mtt))
	local integer Mn=YDWEGetIntegerByString(ors,"ChainLinkNumber")
    local unit Muu=YDWEGetUnitByString(ors,"ChainLinks"+I2S(Mn))
	local unit lTl=YDWEGetUnitByString(ors,"Pudge")
    local real Mx=GetUnitX(Muu)
    local real My=GetUnitY(Muu)
    if Mn>=3 and GetUnitState(lTl,UNIT_STATE_LIFE)>0  then
    call SetUnitX(lTl,Mx)
    call SetUnitY(lTl,My)
    endif
    call KillUnit(Muu)
    call YDWESaveIntegerByString(ors,"ChainLinkNumber",Mn-1)
    if Mn==1 then
        //call UnitRemoveAbility(lTl, 'A00A' )
    	call PauseTimer(Mt)
		call YDWEFlushMissionByString(ors)
		call YDWEFlushMissionByString(I2S(YDWEH2I(Mt)))
		call PolledWait(1)
		call DestroyTimer(Mt)
		call DestroyTimer(Mtt)
    endif
endfunction
//========旗重置============

function YDWEMeatHookFilter takes nothing returns boolean
	if GetUnitState(GetFilterUnit(),UNIT_STATE_LIFE)<=0 or IsUnitType(GetFilterUnit(),UNIT_TYPE_STRUCTURE) or GetFilterUnit()==(YDWEGetUnitByString("YDWEMeatHook","MHtemp")) then //or GetUnitTypeId(GetFilterUnit())=='u000' or GetUnitTypeId(GetFilterUnit())=='u00F'  
		return false
	endif
	return true
endfunction

function YDWEMeatHookAim takes string ors,real Mxx,real Myy returns nothing
    local group lEw
    local group OHh=CreateGroup()
    local location OHf
    local boolexpr lTM
    local unit Maim
    local unit lTl=YDWEGetUnitByString(ors,"Pudge")
    local real Ma=YDWEGetRealByString(ors,"Angle")
    local rect ItemRec
    local real Mb
    local unit OHu
    local unit Fhel
    local location Mtlo
    local real damage=YDWEGetRealByString(ors,"Damage")
    local integer lmZ=4//GetUnitAbilityLevel(lTl,'A000')伤害有关
    set lEw=CreateGroup()
    call YDWESaveUnitByString("YDWEMeatHook","MHtemp",lTl) 
    set lTM=Condition(function YDWEMeatHookFilter)
    call GroupEnumUnitsInRange(lEw,Mxx,Myy,'}',lTM)
    call DestroyBoolExpr(lTM)
    set Maim=FirstOfGroup(lEw)
    call DestroyGroup(lEw)            
    if(Maim!=null)then   //检查印记              
        call YDWESaveUnitByString(ors,"Target",Maim) //save the target
        if IsUnitEnemy(Maim,GetOwningPlayer(lTl))then
            call DestroyEffect(AddSpecialEffectTarget("Objects\\Spawnmodels\\Human\\HumanBlood\\BloodElfSpellThiefBlood.mdl",Maim,"origin"))
            call UnitDamageTarget(lTl,Maim,damage, true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_ENHANCED, WEAPON_TYPE_WHOKNOWS)
        endif    
    endif//if main!=null
    set lEw=null
    set OHu=null
    set lTM=null
    set Maim=null
endfunction

function YDWEMeatHookBack takes string ors returns nothing
local integer Mnn=YDWEGetIntegerByString(ors,"ChainLinkNumber")
local unit Maim=YDWEGetUnitByString(ors,"Target")
local unit lTl=YDWEGetUnitByString(ors,"Pudge")
local integer OLe=YDWEGetIntegerByString(ors,"OLevel")
local integer OHo=YDWEGetIntegerByString(ors,"OHook")
local location FireLoc
local unit Mu
local unit Muu
local real Mxx
local real Myy
local real Maa
local real damage=YDWEGetRealByString(ors,"Damage")
    loop
        exitwhen Mnn<1
        set Mu=YDWEGetUnitByString(ors,"ChainLinks"+I2S(Mnn+1))
        set Muu=YDWEGetUnitByString(ors,"ChainLinks"+I2S(Mnn))
        if (Mu!=null)and(Muu!=null) then
            set Maa=bj_RADTODEG * Atan2(GetUnitY(Mu) - GetUnitY(Muu), GetUnitX(Mu) - GetUnitX(Muu))
            set Mxx=GetUnitX(Muu)+40*Cos(Maa*bj_DEGTORAD)
            set Myy=GetUnitY(Muu)+40*Sin(Maa*bj_DEGTORAD)
            call SetUnitFacing(Muu,Maa+180)
            call SetUnitX(Muu,Mxx)
            call SetUnitY(Muu,Myy)
            if (Mnn==1) then
                if(Maim!=null)then
		            call SetUnitX(Maim,Mxx)
		            call SetUnitY(Maim,Myy)
                  else                    
                    call YDWEMeatHookAim(ors,Mxx,Myy)//=====钩头目标====
                endif
            endif
        endif
        set Mnn=Mnn-1
    endloop
    set lTl=null
    set Mu=null
    set Muu=null
    set Maim=null
endfunction

function YDWEMeatHookPull takes nothing returns nothing
	local timer Mt=GetExpiredTimer()
	local timer Mtt=YDWEGetTimerByString(I2S(YDWEH2I(Mt)),"ExtendCache")
	local string ors=I2S(YDWEH2I(Mtt))
	local integer Mn=YDWEGetIntegerByString(ors,"ChainLinkNumber")
    local integer Noe=YDWEGetIntegerByString(ors,"ErrorAway")//==防出错
    local integer Mnn=0
    local integer MakerY
	local unit lTl=YDWEGetUnitByString(ors,"Pudge")
    local unit Maim
    local unit Mu
    local unit Muu
    local real Mxx
    local real Myy
    local real Mx
    local real My
    local real MDis
    local real Maa
    //========不让该function在同一时间运行两次..=================
    if (Noe==0) then
        call YDWESaveIntegerByString(ors,"ErrorAway",1)
        //=========检查距离(添加删除单位)==================
        set Mn=YDWEGetIntegerByString(ors,"ChainLinkNumber")
        set Muu=YDWEGetUnitByString(ors,"ChainLinks"+I2S(Mn))
        if (Muu!=null) then
            set MDis=SquareRoot((GetUnitX(lTl)-GetUnitX(Muu))*(GetUnitX(lTl)-GetUnitX(Muu))+(GetUnitY(lTl)-GetUnitY(Muu))*(GetUnitY(lTl)-GetUnitY(Muu)))
            if (MDis<50) then//==删除链条==
                loop
                    exitwhen MDis>=50
                    call RemoveUnit(Muu)
                    set Mn=Mn-1
                    call YDWESaveIntegerByString(ors,"ChainLinkNumber",Mn)
                    set Muu=YDWEGetUnitByString(ors,"ChainLinks"+I2S(Mn))
                    exitwhen Muu==null
                    set MDis=SquareRoot((GetUnitX(lTl)-GetUnitX(Muu))*(GetUnitX(lTl)-GetUnitX(Muu))+(GetUnitY(lTl)-GetUnitY(Muu))*(GetUnitY(lTl)-GetUnitY(Muu)))
                endloop
              else//==添加链条===
                if (MDis>90) then
                    set Maa=bj_RADTODEG * Atan2(GetUnitY(lTl) - GetUnitY(Muu), GetUnitX(lTl) - GetUnitX(Muu))
                    set Mx=GetUnitX(Muu)
                    set My=GetUnitY(Muu)
                    loop
                        exitwhen Mnn*40>MDis-50
                        set Mnn=Mnn+1
                        set Mn=YDWEGetIntegerByString(ors,"ChainLinkNumber")
                        set Mxx=Mx+Mnn*40*Cos(Maa*bj_DEGTORAD)
                        set Myy=My+Mnn*40*Sin(Maa*bj_DEGTORAD)
                        set Mu=CreateUnit(GetOwningPlayer(lTl),'u001',Mxx,Myy,Maa+180)
                        call YDWESaveUnitByString(ors,"ChainLinks"+I2S(Mn+1),Mu)
                        call YDWESaveIntegerByString(ors,"ChainLinkNumber",Mn+1)
                    endloop
                endif
            endif
        endif
        //=======开始移动=====
        set Mn=YDWEGetIntegerByString(ors,"ChainLinkNumber")
        call YDWESaveUnitByString(ors,"ChainLinks"+I2S(Mn+1),lTl)
        call YDWEMeatHookBack(ors)
        set MakerY=YDWEGetIntegerByString(ors,"breakN")
        //检查印记2
        if MakerY==2 then
	    	call PauseTimer(Mt)
	    	call TimerStart(Mt,.03,true,function YDWEIcanFly)
    	endif
	    if(Mn==0)then
        //清除印记
            set Maim=YDWEGetUnitByString(ors,"Target")     
	    	call PauseTimer(Mt)
	    	call YDWEFlushMissionByString(ors)
	    	call YDWEFlushMissionByString(I2S(YDWEH2I(Mt)))
	    	call PolledWait(1)
	    	call DestroyTimer(Mt)
	    	call DestroyTimer(Mtt)
	    endif
        call YDWESaveIntegerByString(ors,"ErrorAway",0)
    endif              
endfunction

function YDWEMeatHookOut takes string ors,unit lTl returns nothing
    local integer Mn=YDWEGetIntegerByString(ors,"ChainLinkNumber")
    local integer Mnn=0
    local real Ma=YDWEGetRealByString(ors,"Angle")
    local real Maa
    local group lEw
    local boolexpr lTM
    local unit Mu
    local unit Muu
    local real Mxx
    local real Myy
    //========钩头=====
    set Mu=YDWEGetUnitByString(ors,"ChainLinks"+I2S(1))
    set Mxx=GetUnitX(Mu)+40*Cos(Ma*bj_DEGTORAD)
    set Myy=GetUnitY(Mu)+40*Sin(Ma*bj_DEGTORAD)
    //======检查边界====

    call SetUnitX(Mu,YDWECoordinateX(Mxx))
    call SetUnitY(Mu,YDWECoordinateY(Myy))
    call YDWEMeatHookAim(ors,Mxx,Myy)//目标
    //=========链条=====
    loop
        exitwhen Mnn>Mn-2
        set Mnn=Mnn+1
        set Mu=YDWEGetUnitByString(ors,"ChainLinks"+I2S(Mnn))
        set Muu=YDWEGetUnitByString(ors,"ChainLinks"+I2S(Mnn+1))
        set Maa=bj_RADTODEG * Atan2(GetUnitY(Mu) - GetUnitY(Muu), GetUnitX(Mu) - GetUnitX(Muu))
        set Mxx=GetUnitX(Muu)+40*Cos(Maa*bj_DEGTORAD)
        set Myy=GetUnitY(Muu)+40*Sin(Maa*bj_DEGTORAD) 
        call SetUnitX(Muu,YDWECoordinateX(Mxx))
        call SetUnitY(Muu,YDWECoordinateY(Myy))
        call SetUnitFacing(Muu,Maa)
    endloop
endfunction

function YDWEMeatHookThrow takes nothing returns nothing
	local timer Mt=GetExpiredTimer()
	local string ors=I2S(YDWEH2I(Mt))
	local integer Mn=YDWEGetIntegerByString(ors,"ChainLinkMax")
    local integer Mnn=YDWEGetIntegerByString(ors,"ChainLinkNumber")     
	local unit lTl=YDWEGetUnitByString(ors,"Pudge")
	local real Maa=YDWEGetRealByString(ors,"Angle")    
	local integer lmZ=YDWEGetIntegerByString(I2S(YDWEH2I(Mt)),"ChainLinkNumberMax")//15//GetUnitAbilityLevel(lTl,'A000')长度有关
    local integer Mnnn=1
    local unit Maim
	local unit Mu
    local unit Muu
    local integer Nbreak=0
    local real Mx
	local real My
	local real Mxx
	local real Myy
    local real MDis
	local boolexpr lTM
	local timer lTn
	local string lCache2
	local integer uid1=YDWEGetIntegerByString(I2S(YDWEH2I(Mt)),"ChainHead")
	local integer uid2=YDWEGetIntegerByString(I2S(YDWEH2I(Mt)),"ChainLink")
	local real timeout=YDWEGetRealByString(I2S(YDWEH2I(Mt)),"Timeout")
	if(Mn<lmZ)then
		set Mn=Mn+1
        call YDWESaveIntegerByString(ors,"ChainLinkMax",Mn)
		set Mxx=GetUnitX(lTl)+35*Cos(Maa*bj_DEGTORAD)
		set Myy=GetUnitY(lTl)+35*Sin(Maa*bj_DEGTORAD)
        if (Mn==1) then
        set Mu=CreateUnit(GetOwningPlayer(lTl),uid1,Mxx,Myy,Maa)
        call YDWESaveUnitByString(ors,"ChainLinks"+I2S(1),Mu)
        call YDWESaveIntegerByString(ors,"ChainLinkNumber",1)
        else
    set Muu=YDWEGetUnitByString(ors,"ChainLinks"+I2S(Mnn))
    set MDis=SquareRoot((GetUnitX(lTl)-GetUnitX(Muu))*(GetUnitX(lTl)-GetUnitX(Muu))+(GetUnitY(lTl)-GetUnitY(Muu))*(GetUnitY(lTl)-GetUnitY(Muu)))
    if (MDis>34) then
    set Mx=GetUnitX(Muu)
    set My=GetUnitY(Muu)
    set Maa=bj_RADTODEG * Atan2(GetUnitY(lTl) - GetUnitY(Muu), GetUnitX(lTl) - GetUnitX(Muu))
    loop
    exitwhen MDis-Mnnn*35<0
     set Mxx=Mx+Mnnn*35*Cos(Maa*bj_DEGTORAD)
     set Myy=My+Mnnn*35*Sin(Maa*bj_DEGTORAD)
     set Mu=CreateUnit(GetOwningPlayer(lTl),uid2,Mxx,Myy,Maa+180)
     set Mnn=Mnn+1
     set Mnnn=Mnnn+1
     call YDWESaveUnitByString(ors,"ChainLinks"+I2S(Mnn),Mu) 
     call YDWESaveIntegerByString(ors,"ChainLinkNumber",Mnn)
    endloop
    endif
    endif
    call YDWEMeatHookOut(ors,lTl)
     set Maim=YDWEGetUnitByString(ors,"Target")
     set Nbreak=YDWEGetIntegerByString(ors,"breakN")
     if (Maim!=null)or(Nbreak==1) then
            call PauseTimer(Mt)
			set lTn=CreateTimer()
			call YDWESaveTimerByString(I2S(YDWEH2I(lTn)),"ExtendCache",Mt)
			call TimerStart(lTn,timeout,true,function YDWEMeatHookPull)
    endif
    if Nbreak==2 then
            call PauseTimer(Mt)
			set lTn=CreateTimer()
			call YDWESaveTimerByString(I2S(YDWEH2I(lTn)),"ExtendCache",Mt)
			call TimerStart(lTn,timeout,true,function YDWEIcanFly)
	endif
	else
		call PauseTimer(Mt)
		set lTn=CreateTimer()
		call YDWESaveTimerByString(I2S(YDWEH2I(lTn)),"ExtendCache",Mt)
		call TimerStart(lTn,timeout,true,function YDWEMeatHookPull)
	endif
endfunction

function YDWEMeatHook takes unit lTl,location lng,integer uid1,integer uid2,real distance,real dis,real damage,real timeout returns nothing
	local location lTo=GetUnitLoc(lTl)
	local timer Mt=CreateTimer()
	local real lnM=AngleBetweenPoints(lTo,lng)
    call YDWESaveUnitByString(I2S(YDWEH2I(Mt)),"Pudge",lTl)
	call YDWESaveRealByString(I2S(YDWEH2I(Mt)),"Angle",lnM)
	call YDWESaveIntegerByString(I2S(YDWEH2I(Mt)),"ChainHead",uid1)
	call YDWESaveIntegerByString(I2S(YDWEH2I(Mt)),"ChainLink",uid2)
	call YDWESaveIntegerByString(I2S(YDWEH2I(Mt)),"ChainLinkNumberMax",R2I(distance/dis))
	call YDWESaveRealByString(I2S(YDWEH2I(Mt)),"Timeout",timeout)
	call YDWESaveRealByString(I2S(YDWEH2I(Mt)),"Damage",damage)        
	call TimerStart(Mt,timeout,true,function YDWEMeatHookThrow)     
	set lTo=null
	set lng=null
	set Mt=null
endfunction

//===========================================================================
//系统-TimerSystem 
//===========================================================================
function YDWETimerSystemLoop takes nothing returns nothing
    local trigger trg=null
    local triggercondition tc=null
    local unit u=null
    local timer t=null
    local item it=null
    local texttag tt=null
    local effect e=null
    local integer N=0
    local integer i=0   
    local integer j=0 
    local integer k=0 
    local integer RunIndex=0
    local integer data=0
    local boolean b=false       
    local boolean addtimes=false  
    local real R=0   
          
    set TimerSystem_Steps=TimerSystem_Steps+1    
    if TimerSystem_Steps>TimerSystem_StepsMax then
        call PauseTimer(TimerSystem_Timer)
        //set TimerSystem_Steps=0
        set TimerSystem_StepsMax=0
    endif 
//运行函数
    set i=YDWEGetIntegerByString("YDWETimerRunFunction"+I2S(TimerSystem_Steps),"RunFunctionNumber")
    loop    
        exitwhen i<=0 
        set trg=YDWEGetTriggerByString("YDWETimerRunFunction"+I2S(TimerSystem_Steps),"YDWETimerRunFunctionTrigger"+I2S(i))
        set tc=YDWEGetTriggerConditionByString("YDWETimerRunFunction"+I2S(TimerSystem_Steps),"YDWETimerRunFunctionTriggerCondition"+I2S(i))
        if trg!=null and tc!=null then
            set b=TriggerEvaluate(trg)
            call TriggerRemoveCondition(trg,tc)
            call DestroyTrigger(trg)        
        endif
        set i=i-1        
    endloop      
    call YDWEFlushMissionByString("YDWETimerRunFunction"+I2S(TimerSystem_Steps))                        
//删除单位    
    set i=YDWEGetIntegerByString("YDWETimerRemoveUnit"+I2S(TimerSystem_Steps),"RemoveUnitNumber")
    loop    
        exitwhen i<=0         
        set u=YDWEGetUnitByString("YDWETimerRemoveUnit"+I2S(TimerSystem_Steps),I2S(i))
        if u!=null then
            call RemoveUnit(u)            
        endif
        set i=i-1        
    endloop      
    call YDWEFlushMissionByString("YDWETimerRemoveUnit"+I2S(TimerSystem_Steps))       
//摧毁计时器    
    set i=YDWEGetIntegerByString("YDWETimerDestroyTimer"+I2S(TimerSystem_Steps),"DestroyTimerNumber")
    loop    
    exitwhen i<=0         
        set t=YDWEGetTimerByString("YDWETimerDestroyTimer"+I2S(TimerSystem_Steps),I2S(i))
        if t!=null then
            call DestroyTimer(t)         
        endif
        set i=i-1         
    endloop      
    call YDWEFlushMissionByString("YDWETimerDestroyTimer"+I2S(TimerSystem_Steps)) 
//删除物品    
    set i=YDWEGetIntegerByString("YDWETimerDestroyTimer"+I2S(TimerSystem_Steps),"DestroyTimerNumber")
    loop  
    exitwhen i<=0           
        set it=YDWEGetItemByString("YDWETimerRemoveItem"+I2S(TimerSystem_Steps),I2S(i))
        if it!=null then
            call RemoveItem(it)       
        endif
        set i=i-1          
    endloop          
    call YDWEFlushMissionByString("YDWETimerRemoveItem"+I2S(TimerSystem_Steps)) 
//运行触发器  
    set i=YDWEGetIntegerByString("YDWETimerRunTriggerSingle"+I2S(TimerSystem_Steps),"RunTriggerNumber")
    loop  
        exitwhen i<=0           
        set trg=YDWEGetTriggerByString("YDWETimerRunTriggerSingle"+I2S(TimerSystem_Steps),I2S(i))
        if trg!=null then
            call TriggerExecute(trg)         
        endif
        set i=i-1          
    endloop          
    call YDWEFlushMissionByString("YDWETimerRemoveTriggerSingle"+I2S(TimerSystem_Steps)) 
//循环运行触发器  
    set i=YDWEGetIntegerByString("YDWETimerRunTrigger"+I2S(TimerSystem_Steps),"RunTriggerNumber")
    loop              
        exitwhen i<=0      
        set trg=YDWEGetTriggerByString("YDWETimerRunTrigger"+I2S(TimerSystem_Steps),"Trigger"+I2S(i))
        if trg!=null then     
 
            set R=YDWEGetRealByString(I2S(YDWEH2I(trg))+I2S(TimerSystem_Steps),"YDWETimerRunTriggerTimeout"+I2S(i)) 
            set RunIndex=YDWEGetIntegerByString(I2S(YDWEH2I(trg))+I2S(TimerSystem_Steps),"YDWETimerRunTriggerStoreAddress"+I2S(i))     
            set data=YDWEGetIntegerByString(I2S(YDWEH2I(trg)),"YDWETimerRunIndex"+I2S(RunIndex))               
            if YDWEGetIntegerByString(I2S(YDWEH2I(trg)),"YDWETimerRunIndexOverData"+I2S(data))!=0 then           
                set b=YDWEGetBooleanByString(I2S(YDWEH2I(trg))+I2S(TimerSystem_Steps),"YDWETimerRunTriggerBoolean"+I2S(i))  
                set k=YDWEGetIntegerByString(I2S(YDWEH2I(trg))+I2S(TimerSystem_Steps),"YDWETimerRunTriggerTimes"+I2S(i))
              else
                set b=false
                set k=0   
            endif
            set N=TimerSystem_Steps+R2I(R/TimerSystem_Timeout)                   
            if b==true then                                
                set j=YDWEGetIntegerByString("YDWETimerRunTrigger"+I2S(N),"RunTriggerNumber")              
                set j=j+1               
                call YDWESaveIntegerByString("YDWETimerRunTrigger"+I2S(N),"RunTriggerNumber",j)
                call YDWESaveTriggerByString("YDWETimerRunTrigger"+I2S(N),"Trigger"+I2S(j),trg)                     
                call YDWESaveRealByString(I2S(YDWEH2I(trg))+I2S(N),"YDWETimerRunTriggerTimeout"+I2S(j),R) 
                call YDWESaveBooleanByString(I2S(YDWEH2I(trg))+I2S(N),"YDWETimerRunTriggerBoolean"+I2S(j),b)                 
                call YDWESaveIntegerByString(I2S(YDWEH2I(trg))+I2S(N),"YDWETimerRunTriggerStoreAddress"+I2S(j),RunIndex)                
                set addtimes=true      
              else                           
                set k=k-1 
                if k>0 then                                           
                    set j=YDWEGetIntegerByString("YDWETimerRunTrigger"+I2S(N),"RunTriggerNumber")
                    set j=j+1         
                    call YDWESaveIntegerByString("YDWETimerRunTrigger"+I2S(N),"RunTriggerNumber",j)
                    call YDWESaveTriggerByString("YDWETimerRunTrigger"+I2S(N),"Trigger"+I2S(j),trg)                   
                    call YDWESaveIntegerByString(I2S(YDWEH2I(trg))+I2S(N),"YDWETimerRunTriggerTimes"+I2S(j),k)     //这里容易混淆                      
                    call YDWESaveRealByString(I2S(YDWEH2I(trg))+I2S(N),"YDWETimerRunTriggerTimeout"+I2S(j),R)  
                    call YDWESaveIntegerByString(I2S(YDWEH2I(trg))+I2S(N),"YDWETimerRunTriggerStoreAddress"+I2S(j),RunIndex)                       
                    set addtimes=true                        
                endif   
                  
            endif                                                                         
             if YDWEGetIntegerByString(I2S(YDWEH2I(trg)),"YDWETimerRunIndexOverData"+I2S(data))!=0 then  
                call YDWESaveIntegerByString(I2S(YDWEH2I(trg)),"RunIndex",RunIndex)          
                call ConditionalTriggerExecute(trg)  
            endif       
        endif
        set i=i-1               
    endloop    
    if addtimes==true then
        set TimerSystem_StepsMax=TimerSystem_StepsMax+R2I(R/TimerSystem_Timeout)
        set addtimes=false
    endif      
    call YDWEFlushMissionByString("YDWETimerRunTrigger"+I2S(TimerSystem_Steps))  
//删除漂浮文字    
    set i=YDWEGetIntegerByString("YDWETimerDestroyTextTag"+I2S(TimerSystem_Steps),"DestroyTextTagNumber") 
    loop     
        exitwhen i<=0        
        set tt=YDWEGetTextTagByString("YDWETimerDestroyTextTag"+I2S(TimerSystem_Steps),I2S(i))
        if tt!=null then  
            call SetTextTagPermanent( tt, false )               
            call DestroyTextTag(tt)   
        endif
        set i=i-1            
    endloop      
    call YDWEFlushMissionByString("YDWETimerDestroyTextTag"+I2S(TimerSystem_Steps))  
//删除特效    
    set i=YDWEGetIntegerByString("YDWETimerDestroyEffect"+I2S(TimerSystem_Steps),"DestroyEffectNumber") 
    loop     
        exitwhen i<=0        
        set e=YDWEGetEffectByString("YDWETimerDestroyEffect"+I2S(TimerSystem_Steps),I2S(i))
        if e!=null then  
            call DestroyEffect(e)   
        endif
        set i=i-1            
    endloop      
    call YDWEFlushMissionByString("YDWETimerDestroyEffect"+I2S(TimerSystem_Steps))     
    set trg=null   
    set tc=null 
    set u=null
    set t=null  
    set trg=null     
    set it=null    
    set tt=null     
endfunction

function YDWETimerSystemGetRunIndex takes nothing returns integer
    return TimerSystem_RunIndex       
endfunction

function YDWETimerSystem takes real time returns nothing
    local integer N=TimerSystem_Steps+R2I(time/TimerSystem_Timeout)
    if TimerSystem_StepsMax==0 and TimerSystem_Timer!=null then
        call ResumeTimer(TimerSystem_Timer)
        call TimerStart(TimerSystem_Timer,TimerSystem_Timeout,true,function YDWETimerSystemLoop)
    endif    
    if TimerSystem_StepsMax<N then
        set TimerSystem_StepsMax=N
    endif
    if TimerSystem_Timer==null then
        set TimerSystem_Timer=CreateTimer()
        call TimerStart(TimerSystem_Timer,TimerSystem_Timeout,true,function YDWETimerSystemLoop)
    endif        
endfunction

function YDWETimerRunFunction takes real time,boolexpr be returns nothing
    local integer N=TimerSystem_Steps+R2I(time/TimerSystem_Timeout)
    local integer i=YDWEGetIntegerByString("YDWETimerRunFunction"+I2S(N),"RunFunctionNumber")  
    local trigger trg=CreateTrigger()
    local triggercondition tc=TriggerAddCondition(trg,be)
    if time==0 then 
        call TriggerRemoveCondition(trg,tc)
        call DestroyTrigger(trg)  
      else     
        set N=TimerSystem_Steps+R2I(time/TimerSystem_Timeout)
        set i=YDWEGetIntegerByString("YDWETimerRunFunction"+I2S(N),"RunFunctionNumber") 
        set i=i+1    
        call YDWESaveIntegerByString("YDWETimerRunFunction"+I2S(N),"RunFunctionNumber",i)
        call YDWESaveTriggerByString("YDWETimerRunFunction"+I2S(N),"YDWETimerRunFunctionTrigger"+I2S(i),trg)
        call YDWESaveTriggerConditionByString("YDWETimerRunFunction"+I2S(N),"YDWETimerRunFunctionTriggerCondition"+I2S(i),tc)
        call YDWETimerSystem(time) 
    endif    
    set trg=null
    set tc=null
endfunction

function YDWETimerRemoveUnit takes real time,unit u returns nothing
    local integer N=TimerSystem_Steps+R2I(time/TimerSystem_Timeout)
    local integer i=YDWEGetIntegerByString("YDWETimerRemoveUnit"+I2S(N),"RemoveUnitNumber")  
    if time==0 then 
        call RemoveUnit(u)     
      else     
        set N=TimerSystem_Steps+R2I(time/TimerSystem_Timeout)
        set i=YDWEGetIntegerByString("YDWETimerRemoveUnit"+I2S(N),"RemoveUnitNumber") 
        set i=i+1    
        call YDWESaveIntegerByString("YDWETimerRemoveUnit"+I2S(N),"RemoveUnitNumber",i)
        call YDWESaveUnitByString("YDWETimerRemoveUnit"+I2S(N),I2S(i),u)
        call YDWETimerSystem(time) 
    endif    
endfunction

function YDWETimerDestroyTimer takes real time,timer t returns nothing
    local integer N=0
    local integer i=0
    if time==0 then 
        call DestroyTimer(t) 
      else       
        set N=TimerSystem_Steps+R2I(time/TimerSystem_Timeout)
        set i=YDWEGetIntegerByString("YDWETimerDestroyTimer"+I2S(N),"DestroyTimerNumber")
        set i=i+1    
        call YDWESaveIntegerByString("YDWETimerDestroyTimer"+I2S(N),"DestroyTimerNumber",i)
        call YDWESaveTimerByString("YDWETimerDestroyTimer"+I2S(N),I2S(i),t)
        call YDWETimerSystem(time) 
    endif    
endfunction

function YDWETimerRemoveItem takes real time,item it returns nothing
    local integer N=0
    local integer i=0 
    if time==0 then 
        call RemoveItem(it)
      else      
        set N=TimerSystem_Steps+R2I(time/TimerSystem_Timeout) 
        set i=YDWEGetIntegerByString("YDWETimerRemoveItem"+I2S(N),"RemoveItemNumber")
        set i=i+1    
        call YDWESaveIntegerByString("YDWETimerRemoveItem"+I2S(N),"RemoveItemNumber",i)
        call YDWESaveItemByString("YDWETimerRemoveItem"+I2S(N),I2S(i),it)
        call YDWETimerSystem(time) 
    endif    
endfunction

function YDWETimerRunPeriodicTrigger takes real timeout,trigger trg,boolean b,integer times,integer data returns nothing
    local integer N=0
    local integer i=0                    
    if timeout<0.01 then 
        return
      else  
        set TimerSystem_RunIndex=TimerSystem_RunIndex+1 
        set N=TimerSystem_Steps+R2I(timeout/TimerSystem_Timeout)   
        set i=YDWEGetIntegerByString("YDWETimerRunTrigger"+I2S(N),"RunTriggerNumber")   
        set i=i+1   
        call YDWESaveIntegerByString("YDWETimerRunTrigger"+I2S(N),"RunTriggerNumber",i)
        call YDWESaveRealByString(I2S(YDWEH2I(trg))+I2S(N),"YDWETimerRunTriggerTimeout"+I2S(i),timeout)
        call YDWESaveBooleanByString(I2S(YDWEH2I(trg))+I2S(N),"YDWETimerRunTriggerBoolean"+I2S(i),b)
        call YDWESaveIntegerByString(I2S(YDWEH2I(trg))+I2S(N),"YDWETimerRunTriggerTimes"+I2S(i),times)       
        call YDWESaveIntegerByString(I2S(YDWEH2I(trg))+I2S(N),"YDWETimerRunTriggerStoreAddress"+I2S(i),TimerSystem_RunIndex)  
        call YDWESaveBooleanByString(I2S(YDWEH2I(trg)),"YDWETimerRunIndex"+I2S(data),true)   
        
        call YDWESaveIntegerByString(I2S(YDWEH2I(trg)),"YDWETimerRunIndexOverData"+I2S(data),TimerSystem_RunIndex) 
        call YDWESaveIntegerByString(I2S(YDWEH2I(trg)),"YDWETimerRunIndex"+I2S(TimerSystem_RunIndex),data) 
                   
        call YDWESaveTriggerByString("YDWETimerRunTrigger"+I2S(N),"Trigger"+I2S(i),trg)               
        call YDWETimerSystem(timeout)     
    endif            
endfunction

function YDWETimerRunPeriodicTriggerOver takes trigger trg,integer data returns nothing
    call YDWESaveIntegerByString(I2S(YDWEH2I(trg)),"YDWETimerRunIndexOverData"+I2S(data),0)                   
endfunction

function YDWETimerRunTrigger takes real time,trigger trg returns nothing
    local integer N=0
    local integer i=0
    if time==0 then 
        call TriggerExecute(trg)
      else  
        set N=TimerSystem_Steps+R2I(time/TimerSystem_Timeout)   
        set i=YDWEGetIntegerByString("YDWETimerRunTriggerSingle"+I2S(N),"RunTriggerNumber")   
        set i=i+1    
        call YDWESaveIntegerByString("YDWETimerRunTriggerSingle"+I2S(N),"RunTriggerNumber",i)
        call YDWESaveTriggerByString("YDWETimerRunTriggerSingle"+I2S(N),I2S(i),trg)
        call YDWETimerSystem(time)     
    endif            
endfunction

function YDWETimerDestroyTextTag takes real time,texttag tt returns nothing
    local integer N=0
    local integer i=0
    if time==0 then 
        call DestroyTextTag(tt)
      else  
        set N=TimerSystem_Steps+R2I(time/TimerSystem_Timeout)   
        set i=YDWEGetIntegerByString("YDWETimerDestroyTextTag"+I2S(N),"DestroyTextTagNumber")   
        set i=i+1    
        call YDWESaveIntegerByString("YDWETimerDestroyTextTag"+I2S(N),"DestroyTextTagNumber",i)
        call YDWESaveTextTagByString("YDWETimerDestroyTextTag"+I2S(N),I2S(i),tt)
        call YDWETimerSystem(time)     
    endif   
endfunction

function YDWETimerDestroyEffect takes real time,effect e returns nothing
    local integer N=0
    local integer i=0
    if time==0 then 
        call DestroyEffect(e)
      else  
        set N=TimerSystem_Steps+R2I(time/TimerSystem_Timeout)   
        set i=YDWEGetIntegerByString("YDWETimerDestroyEffect"+I2S(N),"DestroyEffectNumber")   
        set i=i+1    
        call YDWESaveIntegerByString("YDWETimerDestroyEffect"+I2S(N),"DestroyEffectNumber",i)
        call YDWESaveEffectByString("YDWETimerDestroyEffect"+I2S(N),I2S(i),e)
        call YDWETimerSystem(time)     
    endif   
endfunction

//===========================================================================
//AI-自动释放技能 
//===========================================================================
function YDWEAIOrderRun takes nothing returns boolean           
    local unit u = GetTriggerUnit()
    local integer count = YDWEGetIntegerByString(I2S(YDWEH2I(u)), "MercenaryAIOrder_Count")
    local integer order = 0
    local integer pro = 0
    local integer index = 0
    local integer i = 0
    local integer a = 0
    set a = GetRandomInt(0,100*count)
    loop
        set pro = YDWEGetIntegerByString(I2S(YDWEH2I(u)), "MercenaryAIOrder_Probability"+I2S(i))
        if 100*i <= a and a < 100*i+pro then  
            set order = YDWEGetIntegerByString(I2S(YDWEH2I(u)), "MercenaryAIOrder"+I2S(i))
            set index = YDWEGetIntegerByString(I2S(YDWEH2I(u)), "MercenaryAIOrder_Index"+I2S(i))
        endif
        exitwhen i >= count
        set i = i + 1
    endloop
    // 1：敌目标 2：点目标 3：无目标 4：自己
    if index == 1 then
        call IssueTargetOrderById(u,order,GetEventTargetUnit())
    elseif index == 2 then
        call IssuePointOrderById(u,order,GetUnitX(GetEventTargetUnit()),GetUnitY(GetEventTargetUnit()))
    elseif index == 3 then
        call IssueImmediateOrderById(u, order)
    elseif index == 4 then
        call IssueTargetOrderById(u,order,u)
    endif
    set u = null    
    return false
endfunction

function YDWEAddAIOrder takes unit u,integer N,integer index,string orderA,string orderB,string orderC,integer probability returns nothing
    local integer i = YDWEGetIntegerByString(I2S(YDWEH2I(u)), "MercenaryAIOrder_Count")
    local trigger trg
    local string order=null
    if i==0 then
        set trg = CreateTrigger()
        if N==1 then
            call TriggerRegisterUnitEvent(trg, u, EVENT_UNIT_TARGET_IN_RANGE) //用发动攻击为事件
          else
            call TriggerRegisterUnitEvent(trg, u, EVENT_UNIT_ATTACKED  ) //用被攻击为事件 
        endif      
        call YDWESaveIntegerByString(I2S(YDWEH2I(u)), "MercenaryTrigger",YDWEH2I(trg))
        call YDWESaveTriggerConditionByString(I2S(YDWEH2I(trg)), "TriggerCondition",TriggerAddCondition(trg, Condition(function YDWEAIOrderRun))) //好吧，这个提升效率是非常明显的
    endif
    if index == 1 then
        set order=orderA
      elseif index == 2 then
        set order=orderB
      elseif index == 3 then
        set order=orderC
      elseif index == 4 then
        set order=orderA
    endif                                         
    call YDWESaveIntegerByString(I2S(YDWEH2I(u)), "MercenaryAIOrder"+I2S(i), OrderId(order)) //使用OrderId要比OrderString好得多
    call YDWESaveIntegerByString(I2S(YDWEH2I(u)), "MercenaryAIOrder_Probability"+I2S(i), probability)
    call YDWESaveIntegerByString(I2S(YDWEH2I(u)), "MercenaryAIOrder_Index"+I2S(i), index)
    call YDWESaveIntegerByString(I2S(YDWEH2I(u)), "MercenaryAIOrder_Count", i+1)
    set trg = null            
endfunction 

//这个是清空函数
function YDWEFlushAIOrder takes unit u returns nothing
    local trigger trg=YDWEGetTriggerByString(I2S(YDWEH2I(u)), "MercenaryTrigger")
    call TriggerRemoveCondition(trg,YDWEGetTriggerConditionByString(I2S(YDWEH2I(trg)), "TriggerCondition"))
    call DestroyTrigger(trg)
    call YDWEFlushMissionByString(I2S(YDWEH2I(trg)))
    call YDWEFlushMissionByString(I2S(YDWEH2I(u)))
    set trg=null
endfunction


//===========================================================================
//多重物品栏 
//===========================================================================   
function YDWEIsItemSwitch takes unit u returns boolean    
    return YDWEGetBooleanByString(I2S(YDWEH2I(u)), "YDWEItemAbilitySystemTriggerClose")
endfunction 

function YDWEItemSwitch takes unit Ua,unit Ub returns nothing
    local item array Ia
    local item array Ib
    local integer i = 0        
    call YDWESaveBooleanByString(I2S(YDWEH2I(Ua)), "YDWEItemAbilitySystemTriggerClose",true)
    call SetUnitOwner(Ub,GetOwningPlayer(Ua),false)
    loop               
        exitwhen i >5              
        if   UnitItemInSlot(Ua, i) != null   then 
            set Ia[i]= UnitItemInSlot(Ua, i) 
            call UnitRemoveItemFromSlot(Ua,i)           
        endif
        if   UnitItemInSlot(Ub, i) != null   then 
            set Ib[i]= UnitItemInSlot(Ub, i)            
            call UnitRemoveItemFromSlot(Ub,i)  
        endif  
        set i = i+1              
     endloop
     set i = 0
     loop         
        exitwhen i >5 
        if Ia[i] == null then                  
           call UnitAddItem(Ub,CreateItem('mort',GetUnitX(Ub),GetUnitY(Ub)))              
          else 
           call UnitAddItem(Ub,Ia[i])
        endif 
        set i = i+1 
     endloop  
 //给A的物品    
     set i = 0
     loop             
        exitwhen i >5
        if Ib[i] == null then                  
           call UnitAddItem(Ua,CreateItem('mort',GetUnitX(Ua),GetUnitY(Ua)))             
          else 
           call UnitAddItem(Ua,Ib[i])
        endif  
        set i = i+1
     endloop  
     set i = 0
     loop           
        exitwhen i >5
        if GetItemTypeId(UnitItemInSlot(Ua,i))=='mort' then              
          call RemoveItem(UnitItemInSlot(Ua,i))           
        endif
        if GetItemTypeId(UnitItemInSlot(Ub,i))=='mort' then             
          call RemoveItem(UnitItemInSlot(Ub,i))
        endif
        set i = i+1
     endloop 
    set i = 0 
    loop              
        exitwhen i >5 
        set Ia[i]=null
        set Ib[i]=null
        set i = i+1
    endloop  
    call SetUnitOwner(Ub,Player(PLAYER_NEUTRAL_PASSIVE),false)
    call YDWESaveBooleanByString(I2S(YDWEH2I(Ua)), "YDWEItemAbilitySystemTriggerClose",false)
endfunction                    

function YDWEDoubleItemSlotByAbility_CON takes nothing returns boolean 
    local unit u = null    
    local trigger trg = GetTriggeringTrigger()
    local unit hero = GetTriggerUnit()
    local integer ab = YDWEGetIntegerByString(I2S(YDWEH2I(trg)),"Ability")     
    local integer ItemSlotMax=YDWEGetIntegerByString(I2S(YDWEH2I(trg)),"ItemSlotMax")
    local integer i=0 
    if GetSpellAbilityId() !=ab then 
        set u=null
        set trg=null
        set hero=null
        return false
    endif          
    if ItemSlotMax == 1  then       
        set u=null
        set trg=null
        set hero=null
        return false
    endif
    set i=YDWEGetIntegerByString(I2S(YDWEH2I(trg)),"ItemSlotNum")    
    set i=i+1         
    if i>ItemSlotMax then 
       set i=1                
    endif          
    call YDWESaveIntegerByString(I2S(YDWEH2I(trg)),"ItemSlotNum",i)
    set u=YDWEGetUnitByString(I2S(YDWEH2I(trg)),I2S(i))
    call YDWEItemSwitch(hero,u)
    call SetUnitAbilityLevel(hero,ab,i) 
    if i==1 then
        call YDWESaveUnitByString(I2S(YDWEH2I(trg)),I2S(ItemSlotMax),u)
      else  
        call YDWESaveUnitByString(I2S(YDWEH2I(trg)),I2S(i-1),u)
    endif                                    
    set u=null
    set trg=null
    set hero=null
    return false     
endfunction 

function YDWEDoubleItemSlotByAbility takes unit hero,integer ab,integer uid,integer MaxItemSlot returns nothing 
    local integer i = YDWEGetIntegerByString(I2S(YDWEH2I(hero)),"MulItemSlotByAbility")
    local trigger trg = null   
    local unit u=null     
    if i==0 then
        set trg = CreateTrigger()
        call TriggerRegisterUnitEvent(trg, hero, EVENT_UNIT_SPELL_EFFECT) 
        call TriggerAddCondition(trg, Condition(function YDWEDoubleItemSlotByAbility_CON))
        call YDWESaveTriggerByString(I2S(YDWEH2I(hero)),"MulItemSlotByAbility",trg)
        call YDWESaveIntegerByString(I2S(YDWEH2I(trg)),"Ability",ab)
        call YDWESaveIntegerByString(I2S(YDWEH2I(trg)),"ItemSlotMax",MaxItemSlot)
        call YDWESaveIntegerByString(I2S(YDWEH2I(trg)),"ItemSlotNum",1)
        if MaxItemSlot>1 then
          loop
            exitwhen MaxItemSlot==1                
                set u=CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE),uid,0,0,0)    
                call YDWESaveBooleanByString(I2S(YDWEH2I(u)), "YDWEItemAbilitySystemTriggerClose",true)        
                call YDWESaveUnitByString(I2S(YDWEH2I(trg)),I2S(MaxItemSlot),u)  
                set MaxItemSlot=MaxItemSlot-1     
                set u=null        
          endloop
        endif      
    endif    
    //call YDWEItemAbilitySystem(hero)        
    set trg=null
endfunction 

function YDWEDoubleItemSlotByItem_CON takes nothing returns boolean 
    local unit u = null    
    local trigger trg = GetTriggeringTrigger()
    local unit hero = GetTriggerUnit()
    local integer itid = YDWEGetIntegerByString(I2S(YDWEH2I(trg)),"ItemTypeId")     
    local integer ItemSlotMax=YDWEGetIntegerByString(I2S(YDWEH2I(trg)),"ItemSlotMax")
    local integer i=0 
    if GetItemTypeId(GetManipulatedItem()) !=itid then 
        set u=null
        set trg=null
        set hero=null
        return false
    endif          
    if ItemSlotMax == 1  then       
        set u=null
        set trg=null
        set hero=null
        return false
    endif
    set i=YDWEGetIntegerByString(I2S(YDWEH2I(trg)),"ItemSlotNum")    
    set i=i+1         
    if i>ItemSlotMax then 
       set i=1                
    endif          
    call YDWESaveIntegerByString(I2S(YDWEH2I(trg)),"ItemSlotNum",i)
    set u=YDWEGetUnitByString(I2S(YDWEH2I(trg)),I2S(i))
    call YDWEItemSwitch(hero,u)
    call SetItemCharges(UnitItemInSlot(hero,5),i)   
    if i==1 then
        call YDWESaveUnitByString(I2S(YDWEH2I(trg)),I2S(ItemSlotMax),u)
      else  
        call YDWESaveUnitByString(I2S(YDWEH2I(trg)),I2S(i-1),u)
    endif                                    
    set u=null
    set trg=null
    set hero=null
    return false     
endfunction 

function YDWEDoubleItemSlotByItem takes unit hero,integer ItemTypeId,integer uid,integer MaxItemSlot returns nothing 
    local integer i = YDWEGetIntegerByString(I2S(YDWEH2I(hero)),"MulItemSlotByItem") 
    local trigger trg = null    
    local unit u=null    
    local item it=null    
    if i==0 then
        set trg = CreateTrigger()
            call TriggerRegisterUnitEvent(trg, hero, EVENT_UNIT_USE_ITEM) 
        call TriggerAddCondition(trg, Condition(function YDWEDoubleItemSlotByItem_CON))
        call YDWESaveTriggerByString(I2S(YDWEH2I(hero)),"MulItemSlotByItem",trg)
        call YDWESaveIntegerByString(I2S(YDWEH2I(trg)),"ItemTypeId",ItemTypeId)
        call YDWESaveIntegerByString(I2S(YDWEH2I(trg)),"ItemSlotMax",MaxItemSlot)
        call YDWESaveIntegerByString(I2S(YDWEH2I(trg)),"ItemSlotNum",1)                  
        if MaxItemSlot>1 then
            loop
                exitwhen MaxItemSlot==1   
                set u=CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE),uid,0,0,0)    
                call YDWESaveBooleanByString(I2S(YDWEH2I(u)), "YDWEItemAbilitySystemTriggerClose",true)        
                call YDWESaveUnitByString(I2S(YDWEH2I(trg)),I2S(MaxItemSlot),u) 
                set it=CreateItem(ItemTypeId, 0, 0)                 
                call UnitAddItem(u,it)
                call UnitDropItemSlot(u,it,5)                    
                set MaxItemSlot=MaxItemSlot-1      
                set u=null   
                set it=null    
            endloop
        endif      
    endif      
    set trg=null
endfunction 
                                                                   
//===========================================================================
//===========================================================================  
//局部变量 
//===========================================================================
//=========================================================================== 
//function YDWELocalVariableInitiliation takes nothing returns nothing
//    local integer trg = YDWEH2I(GetTriggeringTrigger()) 
//    local integer t = YDWEH2I(GetExpiredTimer()) 
//    local integer N1=YDWEGetIntegerByString(I2S(trg+t),"当前索引")
//    local integer N2=YDWEGetIntegerByString(I2S(trg+t),"最大索引")     
//    call YDWESaveIntegerByString(I2S(trg+t),"最大索引",N2+1)            
//endfunction

//function YDWELocalVariableReturn takes handle h returns integer
 //   if h!=null then
  //      return YDWEH2I(h)
  //  endif
   // return 0
//endfunction



//integer
//function YDWESetLocalVariableInteger takes string s,integer i returns nothing       
//    local integer dir = YDWEH2I(GetTriggeringTrigger())+YDWEH2I(GetExpiredTimer())+YDWEH2I(GetOrderPointLoc())+YDWEH2I(GetSpellTargetLoc())
//    call YDWESaveIntegerByString(I2S(dir),s,i)
//endfunction

function YDWELocalVariableInitiliation takes nothing returns nothing   
    local integer TriggerRunSteps = YDWEGetIntegerByString(I2S(YDWEH2I(GetTriggeringTrigger())),"TriggerRunSteps")
    set TriggerRunSteps=TriggerRunSteps+1
    call YDWESaveIntegerByString(I2S(YDWEH2I(GetTriggeringTrigger())),"TriggerRunSteps",TriggerRunSteps)     
endfunction

function YDWEWaitForLocalVariable takes real time returns nothing
    local integer TriggerRunSteps=YDWEGetIntegerByString(I2S(YDWEH2I(GetTriggeringTrigger())),"TriggerRunSteps")
 //call BJDebugMsg("等待之前TriggerRunSteps= "+I2S(TriggerRunSteps))   
    call TriggerSleepAction(time)
 //call BJDebugMsg("等待之后TriggerRunSteps= "+I2S(TriggerRunSteps))      
    call YDWESaveIntegerByString(I2S(YDWEH2I(GetTriggeringTrigger())),"TriggerRunSteps",TriggerRunSteps)
endfunction

function YDWELocalVariableEnd takes nothing returns nothing
    local integer TriggerRunSteps = YDWEGetIntegerByString(I2S(YDWEH2I(GetTriggeringTrigger())),"TriggerRunSteps") 
    local string dir = I2S(YDWEH2I(GetTriggeringTrigger()))+I2S(TriggerRunSteps)
    call YDWEFlushMissionByString(dir)
endfunction

//integer
function YDWESetLocalVariableInteger takes string s,integer i returns nothing      
    local integer TriggerRunSteps = YDWEGetIntegerByString(I2S(YDWEH2I(GetTriggeringTrigger())),"TriggerRunSteps") 
    local string dir = I2S(YDWEH2I(GetTriggeringTrigger()))+I2S(TriggerRunSteps)
    call YDWESaveIntegerByString(dir,s,i)
endfunction

function YDWEGetLocalVariableInteger takes string s returns integer
    local integer TriggerRunSteps = YDWEGetIntegerByString(I2S(YDWEH2I(GetTriggeringTrigger())),"TriggerRunSteps")  
    local string dir = I2S(YDWEH2I(GetTriggeringTrigger()))+I2S(TriggerRunSteps)
    return YDWEGetIntegerByString(dir,s)   
endfunction

//real
function YDWESetLocalVariableReal takes string s,real R returns nothing       
    local integer TriggerRunSteps = YDWEGetIntegerByString(I2S(YDWEH2I(GetTriggeringTrigger())),"TriggerRunSteps")  
    local string dir = I2S(YDWEH2I(GetTriggeringTrigger()))+I2S(TriggerRunSteps)
    call YDWESaveRealByString(dir,s,R)
endfunction

function YDWEGetLocalVariableReal takes string s returns real
    local integer TriggerRunSteps = YDWEGetIntegerByString(I2S(YDWEH2I(GetTriggeringTrigger())),"TriggerRunSteps")  
    local string dir = I2S(YDWEH2I(GetTriggeringTrigger()))+I2S(TriggerRunSteps)
    return YDWEGetRealByString(dir,s)   
endfunction

//string
function YDWESetLocalVariableString takes string s,string str returns nothing       
    local integer TriggerRunSteps = YDWEGetIntegerByString(I2S(YDWEH2I(GetTriggeringTrigger())),"TriggerRunSteps")  
    local string dir = I2S(YDWEH2I(GetTriggeringTrigger()))+I2S(TriggerRunSteps)
    call YDWESaveStringByString(dir,s,str)
endfunction

function YDWEGetLocalVariableString takes string s returns string
    local integer TriggerRunSteps = YDWEGetIntegerByString(I2S(YDWEH2I(GetTriggeringTrigger())),"TriggerRunSteps")  
    local string dir = I2S(YDWEH2I(GetTriggeringTrigger()))+I2S(TriggerRunSteps)
    return YDWEGetStringByString(dir,s)   
endfunction

//boolean
function YDWESetLocalVariableBoolean takes string s,boolean bl returns nothing       
    local integer TriggerRunSteps = YDWEGetIntegerByString(I2S(YDWEH2I(GetTriggeringTrigger())),"TriggerRunSteps")  
    local string dir = I2S(YDWEH2I(GetTriggeringTrigger()))+I2S(TriggerRunSteps)
    call YDWESaveBooleanByString(dir,s,bl)
endfunction

function YDWEGetLocalVariableBoolean takes string s returns boolean
    local integer TriggerRunSteps = YDWEGetIntegerByString(I2S(YDWEH2I(GetTriggeringTrigger())),"TriggerRunSteps")  
    local string dir = I2S(YDWEH2I(GetTriggeringTrigger()))+I2S(TriggerRunSteps)
    return YDWEGetBooleanByString(dir,s)   
endfunction

//unit
function YDWESetLocalVariableUnit takes string s,unit u returns nothing       
    local integer TriggerRunSteps = YDWEGetIntegerByString(I2S(YDWEH2I(GetTriggeringTrigger())),"TriggerRunSteps")  
    local string dir = I2S(YDWEH2I(GetTriggeringTrigger()))+I2S(TriggerRunSteps)
    call YDWESaveUnitByString(dir,s,u)
endfunction

function YDWEGetLocalVariableUnit takes string s returns unit
    local integer TriggerRunSteps = YDWEGetIntegerByString(I2S(YDWEH2I(GetTriggeringTrigger())),"TriggerRunSteps")  
    local string dir = I2S(YDWEH2I(GetTriggeringTrigger()))+I2S(TriggerRunSteps)
    return YDWEGetUnitByString(dir,s)   
endfunction

//item
function YDWESetLocalVariableItem takes string s,item it returns nothing       
    local integer TriggerRunSteps = YDWEGetIntegerByString(I2S(YDWEH2I(GetTriggeringTrigger())),"TriggerRunSteps")  
    local string dir = I2S(YDWEH2I(GetTriggeringTrigger()))+I2S(TriggerRunSteps)
    call YDWESaveItemByString(dir,s,it)
endfunction

function YDWEGetLocalVariableItem takes string s returns item
    local integer TriggerRunSteps = YDWEGetIntegerByString(I2S(YDWEH2I(GetTriggeringTrigger())),"TriggerRunSteps")  
    local string dir = I2S(YDWEH2I(GetTriggeringTrigger()))+I2S(TriggerRunSteps)
    return YDWEGetItemByString(dir,s)   
endfunction

//location
function YDWESetLocalVariableLocation takes string s,location point returns nothing       
    local integer TriggerRunSteps = YDWEGetIntegerByString(I2S(YDWEH2I(GetTriggeringTrigger())),"TriggerRunSteps")  
    local string dir = I2S(YDWEH2I(GetTriggeringTrigger()))+I2S(TriggerRunSteps)
    call YDWESaveLocationByString(dir,s,point)
endfunction

function YDWEGetLocalVariableLocation takes string s returns location
    local integer TriggerRunSteps = YDWEGetIntegerByString(I2S(YDWEH2I(GetTriggeringTrigger())),"TriggerRunSteps")  
    local string dir = I2S(YDWEH2I(GetTriggeringTrigger()))+I2S(TriggerRunSteps)
    return YDWEGetLocationByString(dir,s)   
endfunction

//===========================================================================
//===========================================================================  
//全局函数 
//===========================================================================
//=========================================================================== 

//===========================================================================  
//物品属性系统 
//===========================================================================
function YDWEItemAbilityStorage takes integer itid,integer ab returns nothing 
    local integer index = YDWEGetIntegerByString(I2S(itid),"AbilityStorageIndex") 
    set index = index + 1 
    call YDWESaveIntegerByString(I2S(itid),"AbilityStorage"+I2S(index),ab) 
    call YDWESaveIntegerByString(I2S(itid),"AbilityStorageIndex",index) 
endfunction 

//===========================================================================  
//拾取物品触发 
//===========================================================================
function YDWEItemAbilitySystemByAbility_CON takes nothing returns boolean 
    local unit hero = GetTriggerUnit() 
    local item it=GetManipulatedItem()
    local trigger trg=YDWEGetTriggerByString(I2S(YDWEH2I(hero)), "MulItemSlotByAbility")
    local integer itid=GetItemTypeId(it)
    local integer index = YDWEGetIntegerByString(I2S(itid),"AbilityStorageIndex") 
    local integer array skills
    local integer i=0          
    local integer N=YDWEGetIntegerByString(I2S(YDWEH2I(trg)), "ItemSlotNum")
    local boolean OnOff=YDWEGetBooleanByString(I2S(YDWEH2I(hero)), "YDWEItemAbilitySystemTriggerClose")                                      
    if index==0 or OnOff==true then
        set it=null
        set hero=null
        set trg=null   
        return false
    endif
    loop
        set i=i+1
        exitwhen i>index
        set skills[i] = YDWEGetIntegerByString(I2S(itid),"AbilityStorage"+I2S(i))//获得物品携带的技能数据  
        if GetTriggerEventId()==ConvertUnitEvent(48) then      //ConvertUnitEvent(85)是“当单位”                   
            call UnitRemoveAbility(hero,skills[i])
          elseif GetTriggerEventId()==ConvertUnitEvent(49) then 
            call UnitAddAbility(hero,skills[i])              
            call UnitMakeAbilityPermanent(hero,true,skills[i])
        endif  
    endloop
    set it=null
    set hero=null
    set trg=null
    return false     
endfunction 

 function YDWEItemAbilitySystem takes nothing returns nothing 
    local trigger trg=CreateTrigger()     
    call TriggerRegisterAnyUnitEventBJ(trg,EVENT_PLAYER_UNIT_PICKUP_ITEM)
    call TriggerRegisterAnyUnitEventBJ(trg,EVENT_PLAYER_UNIT_DROP_ITEM)
    call TriggerAddCondition(trg, Condition(function YDWEItemAbilitySystemByAbility_CON))  
    set trg=null
endfunction 

//===========================================================================  
//任意单位伤害事件 
//===========================================================================
function YDWEAnyUnitDamagedTriggerAction takes nothing returns nothing
    local integer i=YDWEGetIntegerByString("YDWESyStemAnyUnitDamagedTrigger","TriggerNumber") 
    local trigger array trg
    loop           
        set trg[i]=YDWEGetTriggerByString("YDWESyStemAnyUnitDamagedTrigger",I2S(i))
        if trg[i]!=null and TriggerEvaluate(trg[i])==true and IsTriggerEnabled(trg[i])==true  then
            call TriggerExecute(trg[i])
        endif
        set trg[i]=null
        set i=i-1
        exitwhen i<=0    
    endloop    
    //return
endfunction

function YDWEAnyUnitDamagedEnumUnitFunction takes nothing returns nothing     
    local trigger trg=YDWEGetTriggerByString("YDWESyStemAnyUnitDamagedTrigger","Trigger") 
    if GetUnitAbilityLevel(GetEnumUnit(),'Aloc')==0 then
        call TriggerRegisterUnitEvent(trg,GetEnumUnit(),EVENT_UNIT_DAMAGED)
    endif    
    set trg=null
endfunction

function YDWESyStemAnyUnitEnterMapRectTriggerAction takes nothing returns nothing     
    local trigger trg=YDWEGetTriggerByString("YDWESyStemAnyUnitDamagedTrigger","Trigger")
    if GetUnitAbilityLevel(GetTriggerUnit(),'Aloc')==0 then 
        call TriggerRegisterUnitEvent(trg,GetTriggerUnit(),EVENT_UNIT_DAMAGED)
    endif
    set trg=null
endfunction

function YDWEAnyUnitDamagedEnumUnit takes nothing returns nothing   
    local trigger trg=CreateTrigger()
    local group g=CreateGroup()
    set g=GetUnitsInRectAll(GetPlayableMapRect())
    call ForGroup(g,function YDWEAnyUnitDamagedEnumUnitFunction)
    //call YDWESaveGroupByString("YDWESyStemAnyUnitDamagedTrigger","Group",g)
    call TriggerRegisterEnterRectSimple(trg,GetPlayableMapRect())
    call TriggerAddAction(trg,function YDWESyStemAnyUnitEnterMapRectTriggerAction)
    call YDWESaveTriggerByString("YDWESyStemAnyUnitEnterMapRectTrigger","Trigger",trg)   
    call DestroyGroup(g)      
    set trg=null
    set g=null
    //return
endfunction

function YDWESyStemAnyUnitDamagedRegistTrigger takes trigger trg returns nothing
    local integer i=YDWEGetIntegerByString("YDWESyStemAnyUnitDamagedTrigger","TriggerNumber")   
    local trigger SyStemTriger=null 
    if i == 0 then
        set SyStemTriger=CreateTrigger()
        call TriggerAddAction(SyStemTriger,function YDWEAnyUnitDamagedTriggerAction)
        call YDWESaveTriggerByString("YDWESyStemAnyUnitDamagedTrigger","Trigger",SyStemTriger)  
        call YDWEAnyUnitDamagedEnumUnit()
    endif   
    set i=i+1   
    call YDWESaveIntegerByString("YDWESyStemAnyUnitDamagedTrigger","TriggerNumber",i) 
    call YDWESaveTriggerByString("YDWESyStemAnyUnitDamagedTrigger",I2S(i),trg)  
    set SyStemTriger=null        
    //return
endfunction

//===========================================================================  
//===========================================================================  
//地图初始化 
//===========================================================================
//=========================================================================== 
function YDWEGetGameCurrentTime takes nothing returns integer
    return TimerSystem_BigSteps 
endfunction
 
function YDWEGameTimeElapse takes nothing returns nothing
    set TimerSystem_BigSteps=TimerSystem_BigSteps+1         
endfunction

function YDWEGameStartActions takes nothing returns nothing
    set TimerSystem_BigTimer=CreateTimer()
    call TimerStart(TimerSystem_BigTimer, TimerSystem_BigTimeout, true,function YDWEGameTimeElapse) 
    call YDWEItemAbilitySystem()   //开启单位拾取物品触发器      
endfunction

function InitializeYD takes nothing returns nothing
    local trigger trg=CreateTrigger()
    set YDGC=InitGameCache("YDWE.wav")  
    call TriggerRegisterTimerEventSingle(trg, 0.00 )
    call TriggerAddAction(trg, function YDWEGameStartActions )  
    set trg=null
	//call BJDebugMsg("The result is " + I2S(abcdefghij))
endfunction

endlibrary


//=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#

//===========================================================================  
//∑ - Matrix 万能模板函数(修正版)v1.2    作者：Warft_TigerCN    代码优化：Fetrix_sai  
//===========================================================================
//=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#

library TimerPatternUnion 
    
    globals
        //-=-=-=-=-=-=-=-=-=-=-==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
        constant attacktype TimerPattern_at   = ATTACK_TYPE_NORMAL
        constant damagetype TimerPattern_dt   = DAMAGE_TYPE_NORMAL
        constant weapontype TimerPattern_wt   = WEAPON_TYPE_METAL_HEAVY_SLICE
        //-=-=-=-=-=-=-=-=-=-=-==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
        string     TimerPattern_gsfx = "Abilities\\Weapons\\AncientProtectorMissile\\AncientProtectorMissile.mdl" 
        string     TimerPattern_wsfx = "Abilities\\Spells\\Other\\CrushingWave\\CrushingWaveDamage.mdl" 
        string     TimerPattern_osfx = "Objects\\Spawnmodels\\Undead\\ImpaleTargetDust\\ImpaleTargetDust.mdl" 
        string     TimerPattern_dsfx = "Abilities\\Spells\\Other\\Stampede\\StampedeMissileDeath.mdl"
        //-=-=-=-=-=-=-=-=-=-=-==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
                 real       TimerPattern_MAX_X
                 real       TimerPattern_MAX_Y
                 real       TimerPattern_MIN_X
                 real       TimerPattern_MIN_Y
        //-=-=-=-=-=-=-=-=-=-=-==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
        constant integer    TimerPattern_DummyID = 'npng'
        //-=-=-=-=-=-=-=-=-=-=-==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
    endglobals

    // Map boundary measurement     
    //! textmacro tolerance takes s
    function YDWETimerPatterncheck$s$ takes real $s$ returns real       
        local real r = GetRectMin$s$(bj_mapInitialPlayableArea) + 50
        if $s$ < r then
            return r
        endif
        set r = GetRectMax$s$(bj_mapInitialPlayableArea) - 50
        if $s$ > r then
            return r
        endif
        return $s$
    endfunction
    
    function YDWETimerPatternGetSpellTarget$s$ takes nothing returns real
        local location l = GetSpellTargetLoc()
        local real $s$ = GetLocation$s$(l) 
        call RemoveLocation(l)
        set l = null
        return $s$
    endfunction
    //! endtextmacro
    
    // Dispersed text macro list
    //! runtextmacro tolerance("X")
    //! runtextmacro tolerance("Y")
    
endlibrary

//=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#

library TimerPatternInvulnerabilityDetector initializer YDWETimerPatternInvulnerabilityDetectorInit

//    globals
//        public constant integer INV_DETECTOR_CODE      = 'A002' // You need to modify the ASC character of the spell according to the corresponding order.
//        public constant integer DUMMY_UNIT_CODE        = 'nshe'
//        public constant string INV_DETECTOR_ORDERSTR   = "fingerofdeath"
//        public unit dummy
//    endglobals
    
    function YDWETimerPatternInvulnerabilityDetectorIsUnitInvulnerable takes unit whichUnit returns boolean
          local boolean result = false
//        if whichUnit != null and GetUnitTypeId(whichUnit) != 0 then
//            call PauseUnit(dummy, false) 
//            if not IsUnitVisible(whichUnit, Player(PLAYER_NEUTRAL_PASSIVE)) then
//                call UnitShareVision(whichUnit, Player(PLAYER_NEUTRAL_PASSIVE), true)
//                set result = not IssueTargetOrder(dummy, INV_DETECTOR_ORDERSTR, whichUnit)
//                call UnitShareVision(whichUnit, Player(PLAYER_NEUTRAL_PASSIVE), false)
//            else
//                set result = not IssueTargetOrder(dummy, INV_DETECTOR_ORDERSTR, whichUnit)            
//            endif
//            call PauseUnit(dummy, true)
//        endif     
        return result
    endfunction
//    
    function YDWETimerPatternInvulnerabilityDetectorInit takes nothing returns nothing
//        set dummy = CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE), DUMMY_UNIT_CODE, 0, 0, bj_UNIT_FACING)
//        call UnitAddAbility(dummy, INV_DETECTOR_CODE)
//        call ShowUnit(dummy, false)
//        call PauseUnit(dummy, true)
    endfunction
    
endlibrary
//==============================================================================
//  ABC -- STRUCT ATTACHMENT SYSTEM BY COHADAR -- v5.1
//==============================================================================

//------------------------------------------------------------------------------
//  We will use textmacros to create multiple instances of system
//------------------------------------------------------------------------------
//! textmacro ABC takes X, NAME, TYPE

//------------------------------------------------------------------------------
// Global arrays represent our hash tables.
// System is currently using 3 hash tables per handle type. (A, B, C)
//------------------------------------------------------------------------------
globals
    public $TYPE$    array $TYPE$Key$X$
    public integer  array $TYPE$Value$X$
    public integer  $TYPE$maxCollision$X$ = 0
endglobals

//------------------------------------------------------------------------------
// returns the maximum collision so far
//------------------------------------------------------------------------------
function YDWETimerPatternHashABCGet$NAME$Collision$X$ takes nothing returns integer
    return $TYPE$maxCollision$X$
endfunction

//------------------------------------------------------------------------------
// initializes hash arrays to prevent lag when ABC is used for the first time
//------------------------------------------------------------------------------
function YDWETimerPatternHashABCInit$NAME$Hash$X$ takes nothing returns nothing
    set $TYPE$Key$X$[HASH_INDEX_LIMIT]   = null
    set $TYPE$Value$X$[HASH_INDEX_LIMIT] = 0
endfunction

//------------------------------------------------------------------------------
// attaches struct to a handle by using hash table
//------------------------------------------------------------------------------
function YDWETimerPatternHashABCSet$NAME$Struct$X$ takes $TYPE$ t, integer s returns nothing
    debug local integer collision
    
    // hash using 32-bit integer overflow
    local integer i = (GetHandleId(t) * HASH_UP) / HASH_DOWN + HASH_BIAS

    if $TYPE$Key$X$[i] == null then
        set $TYPE$Value$X$[i] = s
        set $TYPE$Key$X$[i] = t
        return
    endif

    debug if $TYPE$Key$X$[i] == t then
        //debug call BJDebugMsg("|cFFFF0000ERROR: Hash[$X$] attachment overwrite on $TYPE$ #" +I2S(GetHandleId(t)))
        debug return
    debug endif        
    
    // if function gets below this line we have a collision
    debug set collision = 1
    loop
        debug if collision >= HASH_COLLISION_LIMIT then
            //debug call BJDebugMsg("|cFFFF0000ERROR: Hash[$X$] overflow")
            debug return
        debug endif    
        debug set collision = collision + 1
    
        set i = i + 1    
        exitwhen $TYPE$Key$X$[i] == null

        debug if $TYPE$Key$X$[i] == t then
            //debug call BJDebugMsg("|cFFFF0000ERROR: Hash[$X$] attachment overwrite on $TYPE$ #" +I2S(GetHandleId(t)))
            debug return
        debug endif    
    endloop

    debug if collision > $TYPE$maxCollision$X$ then
    debug     call BJDebugMsg("|cFFFF4444Warning: Hash[$X$] maximum collision is now: " + I2S(collision))
    debug     set $TYPE$maxCollision$X$ = collision
    debug endif
    
    set $TYPE$Value$X$[i] = s
    set $TYPE$Key$X$[i] = t

    return
endfunction

//------------------------------------------------------------------------------
// gets stored struct from a handle 
//------------------------------------------------------------------------------
function YDWETimerPatternHashABCGet$NAME$Struct$X$ takes $TYPE$ t returns integer
    debug local integer collision
    
    // hash using 32-bit integer overflow
    local integer i = (GetHandleId(t) * HASH_UP) / HASH_DOWN + HASH_BIAS
    
    if $TYPE$Key$X$[i] == t then
        return $TYPE$Value$X$[i]
    endif
    
    // if function gets below this line we have a collision
    debug set collision = 1
    loop
        debug if collision >= HASH_COLLISION_LIMIT then
        debug   call BJDebugMsg("|cFFFF0000ERROR: Hash[$X$] : get request on unknown handle")
        debug   return 0
        debug endif        
        debug set collision = collision + 1      
    
        set i = i + 1
        exitwhen $TYPE$Key$X$[i] == t
    endloop    
    
    return $TYPE$Value$X$[i]
endfunction

//------------------------------------------------------------------------------
// clears stored struct from a handle, also returns cleared value
//------------------------------------------------------------------------------
function YDWETimerPatternHashABCClear$NAME$Struct$X$ takes $TYPE$ t returns integer
    debug local integer collision
    local integer ik
    local integer ret
    
    // hash using 32-bit integer overflow
    local integer i = (GetHandleId(t) * HASH_UP) / HASH_DOWN + HASH_BIAS
    
    // first find the index on witch key is stored
    debug set collision = 0
    loop
        debug if collision >= HASH_COLLISION_LIMIT then
        debug   call BJDebugMsg("|cFFFF0000ERROR: Hash[$X$] : clear request on unknown handle")
        debug   return 0
        debug endif        
        debug set collision = collision + 1       
    
        exitwhen $TYPE$Key$X$[i] == t
        set i = i + 1
    endloop
    
    set ik = i
    set ret = $TYPE$Value$X$[ik]
    
    // then find last used key index in bucket
    loop
        set i = i + 1
        // we use the fact bucket borders (mod 8 indexes) are always null
        exitwhen $TYPE$Key$X$[i] == null  
    endloop
    
    // shift last bucket entry to the place of removed one
    set $TYPE$Key$X$[ik] = $TYPE$Key$X$[i-1]
    set $TYPE$Value$X$[ik] = $TYPE$Value$X$[i-1]
    // clear the previous last bucket entry
    set $TYPE$Key$X$[i-1] = null
    
    return ret
endfunction

//! endtextmacro

//==============================================================================
//  Macro execution -- this is where real functions get created
//==============================================================================
library TimerPatternHashABC initializer YDWETimerPatternHashABCInit

    globals
        public constant integer HASH_SIZE = 8192
        public constant integer HASH_INDEX_LIMIT = 8190
        public constant integer HASH_DOWN = 524288     // 2^19	
        public constant integer HASH_UP   = 2134900736 // 2^22 * 509
        public constant integer HASH_BIAS = 4096       // HASH_SIZE / 2
        public constant integer HASH_COLLISION_LIMIT = 7 // ABC v5.0 had limit 8
        // 509 is the prime closest to 512
    endglobals

    //------------------------------------------------------------------------------
    // conversion function used by the system internally
    // you will not need to use it directly
    //------------------------------------------------------------------------------
    public function GetHandleId takes handle h returns integer
        return h
        return 0
    endfunction

    //! runtextmacro ABC("A","Timer","timer")
    //! runtextmacro ABC("B","Timer","timer")
    //! runtextmacro ABC("C","Timer","timer")

    //! runtextmacro ABC("A","Trigger","trigger")
    //! runtextmacro ABC("B","Trigger","trigger")
    //! runtextmacro ABC("C","Trigger","trigger")

    //! runtextmacro ABC("A","Dialog","dialog")
    //! runtextmacro ABC("B","Dialog","dialog")
    //! runtextmacro ABC("C","Dialog","dialog")

    //! runtextmacro ABC("A","Group","group")
    //! runtextmacro ABC("B","Group","group")
    //! runtextmacro ABC("C","Group","group")

    function YDWETimerPatternHashABCInit takes nothing returns nothing
        call YDWETimerPatternHashABCInitTimerHashA()
        call YDWETimerPatternHashABCInitTimerHashB()
        call YDWETimerPatternHashABCInitTimerHashC()

        call YDWETimerPatternHashABCInitTriggerHashA()
        call YDWETimerPatternHashABCInitTriggerHashB()
        call YDWETimerPatternHashABCInitTriggerHashC()       
    
        call YDWETimerPatternHashABCInitDialogHashA()
        call YDWETimerPatternHashABCInitDialogHashB()
        call YDWETimerPatternHashABCInitDialogHashC()
        
        call YDWETimerPatternHashABCInitGroupHashA()
        call YDWETimerPatternHashABCInitGroupHashB()
        call YDWETimerPatternHashABCInitGroupHashC()
    endfunction

endlibrary
//==============================================================================
//  END OF ABC STRUCT ATTACHMENT SYSTEM
//==============================================================================

//=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#

library TimerPatternDummy requires TimerPatternUnion
 
    public struct MonomerVeil
        
        unit Clerk
        
        method onDestroy takes nothing returns nothing
            local boolean IsVisible = IsUnitHidden(.Clerk)
            if (IsVisible) then
                call KillUnit(.Clerk)
                call RemoveUnit(.Clerk)
            else
                call RemoveUnit(.Clerk)
            endif
        endmethod
        
    endstruct
        
        function YDWETimerPatternDummyEliminate takes nothing returns nothing
            local MonomerVeil Mode = MonomerVeil(YDWETimerPatternHashABCGetTimerStructA(GetExpiredTimer()))
            call YDWETimerPatternHashABCClearTimerStructA(GetExpiredTimer())
            call DestroyTimer(GetExpiredTimer())
        endfunction
        
        function YDWETimerPatternDummyCreateAider takes unit Caster, real thisX, real thisY, real Extent, real Loftiness, /*
        */ integer SpellId, integer SkillLV, unit Target, real thatX, real thatY, string Dictate returns MonomerVeil
            local MonomerVeil Mode = MonomerVeil.create()
            local timer t = CreateTimer()
            local integer i = 0
            local integer uid=0
            if IsTerrainPathable(thisX, thisY, PATHING_TYPE_WALKABILITY) == false and GetUnitState(Caster, UNIT_STATE_LIFE) > 0 then
                //------------------------------------------------------------------
                // Construct the dummy and link together all parameters and members.
                //------------------------------------------------------------------
                set uid=YDWEGetIntegerByString(I2S(YDWEH2I(Caster)),"TimerPattern_uid")
                set Mode.Clerk = CreateUnit(GetOwningPlayer(Caster), uid, thisX, thisY, 0) 
                //--------------------------------------------------------------------------
                // Set the relational properties of units, include the caster and the dummy.
                //--------------------------------------------------------------------------
                //call UnitApplyTimedLife(Mode.Clerk, 'BHwe', Extent)
                call YDWETimerRemoveUnit(Extent,Mode.Clerk)
                //call ShowUnit(Mode.Clerk, false) 
                //call SetUnitPathing(Mode.Clerk, true)
                call UnitAddAbility(Mode.Clerk, SpellId)
                //call SetUnitAbilityLevel(Mode.Clerk, SpellId, GetUnitAbilityLevel(Caster, SkillId))
                call SetUnitAbilityLevel(Mode.Clerk, SpellId,SkillLV)
                call SetUnitFlyHeight(Mode.Clerk, Loftiness, 0.)
                //----------------------------------------------------------------------------------
                // Distribute the indispensable command, according to presence or absence of target.
                //----------------------------------------------------------------------------------
                if Target != null then
                    call IssueTargetOrder(Mode.Clerk, Dictate, Target)
                    //debug call BJDebugMsg("Target order")
                elseif thatX != 0.00 and thatY != 0.00 then
                    call IssuePointOrder(Mode.Clerk, Dictate, thatX, thatY)
                    //debug call BJDebugMsg("Point order")
                else
                    call IssueImmediateOrder(Mode.Clerk, Dictate)
                    //debug call BJDebugMsg("Self order")
                endif
                //----------------------------
                // Injury and effects install.
                //----------------------------
                call YDWETimerPatternHashABCSetTimerStructA(t, Mode)
                call TimerStart(t, Extent, false, function YDWETimerPatternDummyEliminate)
                set t = null
            else
                //debug call BJDebugMsg("No principal part")
            endif
            return Mode
        endfunction
        
    
    //struct MassVeil
    
        function YDWETimerPatternDummyRecurrence takes unit Hub, integer Number, real Path, integer Id, real Expectancy, integer Lord, integer Bout, /*
        */ string Behest1, string Behest2, string Behest3, unit Aim, string Modle, string Actplay returns nothing
            local unit array beau
            local integer i = 1
            local real array x
            local real array y
            loop
                exitwhen i > Number
                set x[i] = GetUnitX(Hub) + Path * Cos((360 / Number) * i * .01745)
                set y[i] = GetUnitX(Hub) + Path * Sin((360 / Number) * i * .01745)
                set beau[i] = CreateUnit(GetOwningPlayer(Hub), Id, x[i], y[i], ((360 / Number) * i))
                //---------------------------------------
                // Site all characteristics of severals.
                //---------------------------------------
                call DestroyEffect(AddSpecialEffect(Modle, x[i], y[i]))
                call UnitApplyTimedLife(beau[i], 'BHwe', Expectancy)
                call SetUnitAnimation(beau[i], Actplay)
                call SetUnitAbilityLevel(beau[i], Bout, GetUnitAbilityLevel(Hub, Lord))
                call IssueImmediateOrder(beau[i], Behest1)
                call IssuePointOrder(beau[i], Behest2, x[i], y[i])
                call IssueTargetOrder(beau[i], Behest3, Aim)
                set beau[i] = null
                set i = i + 1
            endloop
        endfunction
    
    //endstruct
                                   
endlibrary

//=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#

library TimerPattern initializer YDWETimerPatternInit requires TimerPatternUnion, TimerPatternInvulnerabilityDetector, TimerPatternDummy

    globals
        //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
        public constant real coll = 120.0
        public constant real blank = 0.1 
        public constant real seg = 0.05
        public constant real grav = 7.83  
        public constant real bot = 3.0
        public constant real allote = 0.5
        //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
        public boolean paused = false
        //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
        public integer Total = 0
        public integer Temp_Struct
        public integer array Structs
        //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
        public constant timer t = CreateTimer()
        //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
    endglobals

    //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
    //                                            Filter Funcs                                                //
    //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
    function YDWETimerPatternEnemyFilter takes unit u, unit caster returns boolean
        return IsUnitType(u, UNIT_TYPE_MAGIC_IMMUNE) == false and IsUnitType(u, UNIT_TYPE_RESISTANT) == false /*
        */ and IsUnitType(u, UNIT_TYPE_SLEEPING) == false     and GetUnitState(u, UNIT_STATE_LIFE) > 0.405    /*
        */ and IsUnitType(u, UNIT_TYPE_STRUCTURE) == false    and IsUnitIllusion(u) == false                  /*
        */ and IsUnitHidden(u) == false                       and IsUnitEnemy(u, GetOwningPlayer(caster))     /*
        */ and IsUnitVisible(u, GetOwningPlayer(caster))      and YDWETimerPatternInvulnerabilityDetectorIsUnitInvulnerable(u) == false
    endfunction
    
    function YDWETimerPatternTreeFilter takes nothing returns boolean
        local integer id = GetDestructableTypeId(GetFilterDestructable())
        return id == 'LTlt' or id == 'ATtr' or id == 'BTtw' or id == 'KTtw' /*
          */or id == 'YTft' or id == 'JTct' or id == 'YTst' or id == 'YTct' /*
          */or id == 'YTwt' or id == 'JTtw' or id == 'DTsh' or id == 'FTtw' /*
          */or id == 'CTtr' or id == 'ITtw' or id == 'NTtw' or id == 'OTtw' /*
          */or id == 'ZTtw' or id == 'WTst' or id == 'GTsh' or id == 'VTlt' /*
          */or id == 'WTtw' or id == 'ATtc' or id == 'BTtc' or id == 'CTtc' /*
          */or id == 'ITtc' or id == 'NTtc' or id == 'ZTtc'
    endfunction
    
    //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
    //                                         Major Structure Code                                           //
    //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
    public struct operate
        
        unit u
        real sheight
        real xvel
        real yvel
        real xvelred
        real yvelred
        real zred
        real gap
        real data
        real z
        real step
        real height
        real apex
        boolean killtrees
        boolean recyclable
        boolean hostility
        boolean volume
        boolean perish
        boolean parabola
        boolean aviate
        boolean follow
        string order
        group g
        integer i
        integer sfx
        integer dep
        integer lord
        
        method onDestroy takes nothing returns nothing
            call DestroyGroup(.g)
            set .u = null
            set .g = null
            //debug call BJDebugMsg("Knockback stopped!")
        endmethod
        
    endstruct

        function YDWETimerPatternTreeKill takes nothing returns nothing
            local destructable d = GetEnumDestructable()
            if GetWidgetLife(d) > 0.405 then
                call KillDestructable(d)
            endif
            set d = null
        endfunction
        
        function YDWETimerPatternRetrieve takes unit u, boolean wither returns nothing
            if not(wither) then
                call SetUnitFlyHeight(u, GetUnitDefaultFlyHeight(u), 5000.)
                call SetUnitAnimation(u, "stand")
                call SetUnitTimeScale(u, 1)
                if (GetLocalPlayer() == GetOwningPlayer(u)) then
                    call ClearSelection()
                    call SelectUnit(u, true)
                endif
            else
                call RemoveUnit(u)
            endif
        endfunction
        
        function YDWETimerPatternDamage takes real x, real y returns nothing
            local operate k = Temp_Struct
            local group opt = CreateGroup()
            local unit f=null
            local unit u=null
            local string part=YDWEGetStringByString(I2S(YDWEH2I(k.u)),"TimerPattern_part")  
            local string path=YDWEGetStringByString(I2S(YDWEH2I(k.u)),"TimerPattern_dsfx")  
            call GroupEnumUnitsInRange(opt, x, y, coll, null)
            loop
               set f = FirstOfGroup(opt)
               exitwhen f == null
               if IsUnitInGroup(f, k.g) == false then
                   if YDWETimerPatternEnemyFilter(f, k.u) then
                       call GroupAddUnit(k.g, f)
                       call UnitDamageTarget(k.u, f, k.data, true, true, TimerPattern_at, TimerPattern_dt, TimerPattern_wt)
                       call YDWETimerDestroyEffect( 2, AddSpecialEffectTarget(path, f, part) ) 
                       if not(k.recyclable) then
                           if GetUnitState(f, UNIT_STATE_LIFE) > 0.405 then
                               call YDWETimerPatternDummyCreateAider(k.u, x, y, allote, 0., k.dep, k.lord, f, 0., 0., k.order)
                           endif
                           call YDWETimerPatternRetrieve(k.u, k.perish)
                           call k.destroy()
                           //debug call BJDebugMsg("A one-time.")
                       endif
                   endif
               endif
               call GroupRemoveUnit(opt, f)
            endloop
            call DestroyGroup(opt)
            set opt = null
            set f = null                
        endfunction
    
        function YDWETimerPatternMove takes nothing returns nothing
            local operate k
            local integer i = 1
            local real x =0
            local real y =0
            local boolexpr b=null
            local rect r =null
            local location stupid=null
            local string osfx =null
            local string wsfx =null
            local string part =null
            if Total == 0 then
                //debug call BJDebugMsg("Timer paused.")
                call PauseTimer(t)
                set paused = true
            endif
            loop
                exitwhen i > Total
                set k = Structs[i]
                if k.i != null and k.i != 0 then
                    if (GetLocalPlayer() == GetOwningPlayer(k.u)) then
                        call SelectUnit(k.u, false)
                    endif
                    if k.volume then
                        //debug call BJDebugMsg("Pathable without terrain.")
                        if (IsTerrainPathable(GetUnitX(k.u), GetUnitY(k.u), PATHING_TYPE_WALKABILITY) == true) then
                            //call DestroyEffect(AddSpecialEffectLoc(TimerPattern_osfx, GetUnitLoc(k.u)))                                 
                            set osfx=YDWEGetStringByString(I2S(YDWEH2I(k.u)),"TimerPattern_osfx")
                            if osfx!=null then
                                set part=YDWEGetStringByString(I2S(YDWEH2I(k.u)),"TimerPattern_part")
                                call DestroyEffect(AddSpecialEffectTarget(osfx,k.u,part)) 
                            endif    
                            set Structs[i] = Structs[Total]    
                            set Total = Total - 1
                            set i = i - 1
                            set k.i = 0
                            set k.step = 0.
                            call YDWETimerPatternRetrieve(k.u, k.perish)
                            call k.destroy()
                            set k.u = null
                        endif
                    endif
                    set x = GetUnitX(k.u) + k.xvel
                    set y = GetUnitY(k.u) + k.yvel
                    if k.aviate then
                        set stupid = Location(x, y)
                        set k.z = k.z - GetLocationZ(stupid)
                        call SetUnitFlyHeight(k.u, k.z, 0.)
                        set k.z = k.z - k.zred
                        if k.z > GetUnitDefaultFlyHeight(k.u) then
                            set k.zred = k.zred + (grav / (1. / k.gap)) * 2.
                        else
                            set k.zred = 0.
                            call SetUnitFlyHeight(k.u, GetUnitDefaultFlyHeight(k.u), 500.)
                        endif
                        if k.z < 0. then
                            set k.z = 0.
                            set k.zred = 0.
                        endif
                        set k.z = k.z + GetLocationZ(stupid)
                        call RemoveLocation(stupid)
                        set stupid = null
                    endif
                    call SetUnitX(k.u, x)
                    call SetUnitY(k.u, y)
                    set k.sfx = k.sfx + 1
                    if k.follow then
                        if k.u != null and k.sfx == 1 and GetUnitFlyHeight(k.u) < 5. then 
                            if IsTerrainPathable(x, y, PATHING_TYPE_FLOATABILITY) then
                                call DestroyEffect(AddSpecialEffect(TimerPattern_gsfx, x, y))
                            else
                                set wsfx=YDWEGetStringByString(I2S(YDWEH2I(k.u)),"TimerPattern_wsfx")
                                if wsfx!=null then
                                    set part=YDWEGetStringByString(I2S(YDWEH2I(k.u)),"TimerPattern_part")
                                    call DestroyEffect(AddSpecialEffectTarget(wsfx,k.u,part)) 
                                endif     
                                //call DestroyEffect(AddSpecialEffect(TimerPattern_wsfx, x, y))
                            endif
                        endif
                    endif
                    if k.sfx == 5 then
                        set k.sfx = 0
                    endif
                    if k.xvel * k.xvel + k.yvel * k.yvel < 2. then
                        if (GetUnitFlyHeight(k.u) - GetUnitDefaultFlyHeight(k.u)) * (GetUnitFlyHeight(k.u) - GetUnitDefaultFlyHeight(k.u)) < 5. then
                            set Structs[i] = Structs[Total]
                            set Total = Total - 1
                            set i = i - 1
                            set k.i = 0
                            set k.step = 0.
                            call YDWETimerPatternRetrieve(k.u, k.perish)
                            call k.destroy()
                            set k.u = null
                        endif
                    else
                        set k.xvel = k.xvel - k.xvelred
                        set k.yvel = k.yvel - k.yvelred
                    endif
                    if k.killtrees then
                        set b = Condition(function YDWETimerPatternTreeFilter)
                        set r = Rect(x - coll, y - coll, x + coll, y + coll)
                        call EnumDestructablesInRect(r, b, function YDWETimerPatternTreeKill)
                        call DestroyBoolExpr(b)
                        set b = null
                        call RemoveRect(r)
                        set r = null
                    endif
                    if k.hostility then
                        set Temp_Struct = k
                        call YDWETimerPatternDamage(x, y)
                    endif
                    if k.parabola then
                        set k.step = k.step + seg
                        set k.height = k.apex * k.step - (k.apex / bot) * (k.step * k.step)
                        call SetUnitFlyHeight(k.u, k.sheight+k.height, 0.)
                    endif
                    if x > TimerPattern_MAX_X or x < TimerPattern_MIN_X or y > TimerPattern_MAX_Y or y < TimerPattern_MIN_Y then
                        set Structs[i] = Structs[Total]
                        set Total = Total - 1
                        set i = i - 1
                        set k.i = 0
                        set k.step = 0.
                        call YDWETimerPatternRetrieve(k.u, k.perish)
                        call k.destroy()
                        set k.u = null
                       endif
                    set i = i + 1
                endif
            endloop
        endfunction
    
        function YDWETimerPatternSustain takes unit u, string id, integer pair, integer allah, real dist, real a, real time, real interval, real damage, real h, /*
        */ boolean killtrees, boolean injure, boolean cycle, boolean path, boolean ruin, boolean capriole, boolean sequel returns nothing
            local operate k = operate.create()
            local location stupid = Location(GetUnitX(u), GetUnitY(u))
            set k.g = CreateGroup()
            set k.u = u
            set k.order = id
            set k.dep = pair
            set k.lord = allah
            set k.gap = interval
            set k.data = damage
            set k.apex = h
            set k.xvel = 2 * (dist * Cos(a * .01745)) / (time / interval + 1)
            set k.yvel = 2 * (dist * Sin(a * .01745)) / (time / interval + 1)
            set k.xvelred = k.xvel / (time / interval)
            set k.yvelred = k.yvel / (time / interval)
            set k.zred = 0.
            set k.z = GetUnitFlyHeight(u) + GetLocationZ(stupid)
            set k.killtrees = killtrees
            set k.hostility = injure
            set k.recyclable = cycle
            set k.volume = path
            set k.perish = ruin
            set k.parabola = capriole
            set k.aviate = true // canfly
            set k.follow = sequel
            set k.i = 1
            set k.sfx = 0
            set k.sheight = GetUnitFlyHeight(u)
            set Total = Total + 1
            set Structs[Total] = k
            call SetUnitTimeScale(u, 1.)                        
            //call SetUnitTimeScale(u, rate)
            if capriole then
                call UnitAddAbility(u, 'Amrf')
                call UnitRemoveAbility(u, 'Amrf')
            endif
            if paused then
                //debug call BJDebugMsg("Timer resumed.")
                call TimerStart(t, interval, true, function YDWETimerPatternMove)
                set paused = false
            endif
            call RemoveLocation(stupid)
            set stupid = null
            //debug call BJDebugMsg("Knockback started!")
        endfunction
    

    function YDWETimerPatternInit takes nothing returns nothing
        local rect r = bj_mapInitialPlayableArea
        call TimerStart(t, blank, true, function YDWETimerPatternMove)
        set TimerPattern_MAX_X = GetRectMaxX(r)
        set TimerPattern_MAX_Y = GetRectMaxY(r)
        set TimerPattern_MIN_X = GetRectMinX(r)
        set TimerPattern_MIN_Y = GetRectMinY(r)
        set r = null
    endfunction
    
function YDWETimerPatternJumpAttack takes unit u,real face,real dis,real lasttime,real timeout,real high,real damage,string part,string dsfx returns nothing
    local boolean injure=false
    call YDWESaveStringByString(I2S(YDWEH2I(u)),"TimerPattern_part",part)  
    call YDWESaveStringByString(I2S(YDWEH2I(u)),"TimerPattern_dsfx",dsfx)              
    if damage>0 then
        set injure=true
    endif    
    call YDWETimerPatternSustain(u,null,0,0,dis,face,lasttime,timeout,damage,high,false,injure,true,false, false,true,false)        
endfunction    

function YDWETimerPatternMoonPriestessArrow takes unit u,real face,real dis,real lasttime,real timeout,integer lv,integer aid,integer uid,string order,string part,string dsfx returns nothing
    call YDWESaveStringByString(I2S(YDWEH2I(u)),"TimerPattern_part",part)   
    call YDWESaveStringByString(I2S(YDWEH2I(u)),"TimerPattern_dsfx",dsfx)
    call YDWESaveIntegerByString(I2S(YDWEH2I(u)),"TimerPattern_uid",uid)  
    call YDWETimerPatternSustain(u,order,aid,lv,dis,face,lasttime,timeout,0,0,false,true,false,false,true,false,false)
endfunction

function YDWETimerPatternRushSlide takes unit u,real face,real dis,real lasttime,real timeout,real damage,boolean killtrees,boolean cycle,boolean path,string part,string osfx,string wsfx returns nothing
    local boolean injure=false
    call YDWESaveStringByString(I2S(YDWEH2I(u)),"TimerPattern_part",part)   
    call YDWESaveStringByString(I2S(YDWEH2I(u)),"TimerPattern_osfx",osfx)  
    call YDWESaveStringByString(I2S(YDWEH2I(u)),"TimerPattern_wsfx",wsfx)
    if damage>0 then
        set injure=true
    endif 
    set path=not path        
    call YDWETimerPatternSustain(u,null,0,0,dis,face,lasttime,timeout,damage,0, killtrees, injure, cycle, path, false, false, true)
endfunction
endlibrary




