library IndieSummons initializer Init requires AutoIndex, TimerUtils, Table
//**************************************************************************************************
//*
//* Independant Summons (Code + config)
//* ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
//* You just need to copy this trigger, notice that these functions do nothing without the other
//* part which has the header functions and you'll also need to call them.
//*
//**************************************************************************************************
// 2010-01-18 (Original system by Vexorian, modified by MoCo):
// - vjassification of system
// - now works with latest patches
//==================================================================================================
// Independant Summons Configuration:
//
globals
private Table SummonIdTab
private unit array Summons[1]
private unit array Masters[1]
private integer N = 0
private constant integer MAX_N = 64
endglobals
private constant function IndieSummon_maxdelay takes nothing returns real
return 2.5 //* The max delay betwen orders issued to the summon
endfunction
private constant function IndieSummon_mindelay takes nothing returns real
return 1.00 //* The min delay betwen orders issued to the summon
endfunction
private constant function IndieSummon_maxdistance takes nothing returns real
return 500.0 //* If the distance betwen the summon and the master is greater than this value,
// The summon will move to the position of the master instead of attack move
endfunction
private constant function IndieSummon_cometomaxdist takes nothing returns real
return 300.0 //* Max distance for issued orders to approach the master
endfunction
private constant function IndieSummon_cometomindist takes nothing returns real
return 100.0 //* Min distance for issued orders to approach the master
endfunction
//==================================================================================================
private function SetSummonId takes unit summon returns integer
set N = N + 1
set SummonIdTab[GetUnitId(summon)] = N
if N > MAX_N then
set N = 0
endif
return SummonIdTab[GetUnitId(summon)]
endfunction
private function GetSummonId takes unit summon returns integer
return SummonIdTab[GetUnitId(summon)]
endfunction
private function IndieSummon_GetMaster takes unit summon returns unit
local integer id = GetSummonId(summon)
return Masters[id]
return null
endfunction
private function IndieSummon_StopAI takes unit summon returns nothing
local integer id = GetSummonId(summon)
set Masters[id] = null
endfunction
private function IndieSummon_Order takes unit summon, unit master returns nothing
local integer o=GetUnitCurrentOrder(summon)
local real tx=GetUnitX(master)
local real ty=GetUnitY(master)
local real angle
local real dist
set dist=Pow(tx-GetUnitX(summon),2) + Pow(ty-GetUnitY(summon),2)
if (dist > (IndieSummon_maxdistance()*IndieSummon_maxdistance()) ) and (o == 0 or o == OrderId("attack") or o == OrderId("move") or o == OrderId("stop") or o==851971) then
call IssuePointOrder(summon, "move", tx,ty)
elseif dist >= (IndieSummon_cometomindist()*IndieSummon_cometomindist()) and (o == 0 or o == 851971) then
set angle = GetRandomReal( GetUnitFacing(master)-80, GetUnitFacing(master)+80)
if (ModuloInteger(GetUnitPointValue(summon),2)==0) then
set angle=angle * bj_DEGTORAD
else
set angle=- angle * bj_DEGTORAD
endif
set dist = GetRandomReal(IndieSummon_cometomindist(), IndieSummon_cometomaxdist() )
set tx=tx+dist*Cos(angle)
set ty=ty+dist*Sin(angle)
if not IssuePointOrder(summon, "attack", tx, ty ) then
call IssuePointOrder(summon, "move", tx, ty )
endif
endif
set summon=null
set master=null
endfunction
private function IndieSummon_AntiSmart_Timer takes nothing returns nothing
local timer t = GetExpiredTimer()
local integer id = GetTimerData(t)
local unit s = Summons[id]
local unit m = Masters[id]
if (GetUnitCurrentOrder(s)!=851971) then
call DestroyTimer(t)
else
call IndieSummon_Order( s, m )
call TimerStart(t,0.1,false,function IndieSummon_AntiSmart_Timer)
endif
set t = null
set s = null
set m = null
endfunction
private function IndieSummon_AntiSmart takes nothing returns nothing
local timer t
local integer id = GetSummonId(GetTriggerUnit())
if (GetIssuedOrderId() == 851971) then
set t=CreateTimer()
call SetTimerData(t, id)
call TimerStart(t,0,false,function IndieSummon_AntiSmart_Timer)
set t=null
endif
endfunction
private function IndieSummon_loop takes integer id returns nothing
local unit summon = Summons[id]
local unit master // = Masters[id]
local trigger smart=CreateTrigger()
local integer n = 0
local triggeraction ac = TriggerAddAction( smart, function IndieSummon_AntiSmart)
call TriggerRegisterUnitEvent( smart, summon, EVENT_UNIT_ISSUED_TARGET_ORDER )
call TriggerRegisterUnitEvent( smart, summon, EVENT_UNIT_ISSUED_POINT_ORDER )
loop
exitwhen (GetWidgetLife(summon)<=0)
set master = Masters[id]
if (master==null) then
exitwhen true
else
call IndieSummon_Order( summon, master)
call PolledWait( GetRandomReal( IndieSummon_mindelay(), IndieSummon_maxdelay() ))
endif
endloop
set Masters[id] = null
call TriggerRemoveAction(smart,ac)
if smart != null then
call DestroyTrigger(smart)
endif
set ac=null
set summon=null
set master=null
set smart=null
endfunction
function IndieSummon_SetMaster takes unit summon, unit master returns nothing
local integer id
set id = SetSummonId(summon)
set Masters[id] = master
set Summons[id] = summon
call IndieSummon_loop.execute(id)
endfunction
//===========================================================================
private function Init takes nothing returns nothing
set SummonIdTab = Table.create()
endfunction
endlibrary |