library FearSystem uses IsUnitMoving,Table
globals
private constant real PERIOD=.05
private constant real MIN_RANGE=300.
private constant real MAX_RANGE=500.
private constant real ANGLE=45.
endglobals
//********************************************************************************
// CODE
//********************************************************************************
struct Fear
private unit u
private real dur
private real x
private real y
private real nx
private real ny
private thistype next
private thistype prev
private static Table table
private static boolean toPrevent
private method destroy takes nothing returns nothing
/*
Buff based on Slow Aura
-- REMOVE --
call UnitMakeAbilityPermanent(this.u,false,'A60B')
call UnitRemoveAbility(this.u,'A60B')
call UnitRemoveAbility(this.u,'B60B')
*/
call IssueImmediateOrder(this.u,"stop")
set this.prev.next=this.next
set this.next.prev=this.prev
call this.table.remove(GetHandleId(this.u))
call this.deallocate()
endmethod
method issue takes nothing returns nothing
local real r=GetRandomReal(MIN_RANGE,MAX_RANGE)
local real angle=GetRandomReal(GetUnitFacing(this.u)-ANGLE,GetUnitFacing(this.u)+ANGLE)
set this.nx=this.x + r * Cos(angle * bj_DEGTORAD)
set this.ny=this.y + r * Sin(angle * bj_DEGTORAD)
set thistype.toPrevent=false
call IssuePointOrderById(this.u,851986,this.nx,this.ny)
set thistype.toPrevent=true
endmethod
static method periodic takes nothing returns nothing
local thistype this = thistype(0)
loop
set this=this.next
exitwhen this==0
if this.dur<=0 or not UnitAlive(this.u) then
call this.destroy()
else
if not IsUnitMoving(this.u) then
call this.issue()
endif
set this.dur=this.dur-PERIOD
endif
endloop
endmethod
static method removeFear takes unit u returns nothing
local integer id=GetHandleId(u)
if thistype.table.has(id) then
call thistype(thistype.table[id]).destroy()
endif
endmethod
static method getFear takes unit u returns real
local integer id=GetHandleId(u)
if thistype.table.has(id) then
return thistype(thistype.table[id]).dur
else
return 0.
endif
endmethod
static method addFear takes unit u, real dur returns nothing
local thistype this
local integer id=GetHandleId(u)
if thistype.table.has(id) then
set this=thistype.table[id]
else
set this=thistype.allocate()
set thistype(0).next.prev=this
set this.next=thistype(0).next
set thistype(0).next=this
set this.prev=thistype(0)
set thistype.table[id]=this
set this.u=u
set this.dur=0
set this.x=GetUnitX(u)
set this.y=GetUnitY(u)
/*
Buff based on Slow Aura
-- ADD --
call UnitAddAbility(u,'A60B')
call UnitMakeAbilityPermanent(u,true,'A60B')
*/
endif
if this.dur<dur then
set this.dur=dur
endif
endmethod
private static method doPrevent takes nothing returns boolean
local thistype this
if thistype.table.has(GetHandleId(GetTriggerUnit())) and thistype.toPrevent then
set this=thistype.table[GetHandleId(GetTriggerUnit())]
set thistype.toPrevent=false
call IssuePointOrderById(this.u,851986,this.nx,this.ny)
set thistype.toPrevent=true
endif
return false
endmethod
private static trigger Prevent=CreateTrigger()
private static method onInit takes nothing returns nothing
set thistype.table=Table.create()
set thistype.toPrevent=true
call TimerStart(CreateTimer(),PERIOD,function true,function Fear.periodic()
call TriggerRegisterAnyUnitEventBJ(thistype.Prevent, EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER )
call TriggerRegisterAnyUnitEventBJ(thistype.Prevent, EVENT_PLAYER_UNIT_ISSUED_ORDER )
call TriggerRegisterAnyUnitEventBJ(thistype.Prevent, EVENT_PLAYER_UNIT_ISSUED_POINT_ORDER )
call TriggerAddCondition(thistype.Prevent,Condition(function thistype.doPrevent))
endmethod
endstruct
endlibrary
library FearSystem uses IsUnitMoving,Table
//******************************************************
//API:
/*
function UnitFear takes unit whichUnit, real duration returns nothing
function UnitStopFear takes unit whichUnit returns nothing
function UnitFearElapsed takes unit whichUnit returns real
*/
//******************************************************
globals
private constant real PERIOD=.05
private constant real MIN_RANGE=300.
private constant real MAX_RANGE=500.
private constant real ANGLE=45.
endglobals
//********************************************************************************
// CODE
//********************************************************************************
private struct Fear
unit u
real dur
real x
real y
real nx
real ny
thistype next
thistype prev
static Table table
static boolean toPrevent
method destroy takes nothing returns nothing
/*
Buff based on Slow Aura
-- REMOVE --
call UnitMakeAbilityPermanent(this.u,false,'A60B')
call UnitRemoveAbility(this.u,'A60B')
call UnitRemoveAbility(this.u,'B60B')
*/
call IssueImmediateOrder(this.u,"stop")
set this.prev.next=this.next
set this.next.prev=this.prev
call this.table.remove(GetHandleId(this.u))
call this.deallocate()
endmethod
private method issue takes nothing returns nothing
local real r=GetRandomReal(MIN_RANGE,MAX_RANGE)
local real angle=GetRandomReal(GetUnitFacing(this.u)-ANGLE,GetUnitFacing(this.u)+ANGLE)
set this.nx=this.x + r * Cos(angle * bj_DEGTORAD)
set this.ny=this.y + r * Sin(angle * bj_DEGTORAD)
set thistype.toPrevent=false
call IssuePointOrderById(this.u,851986,this.nx,this.ny)
set thistype.toPrevent=true
endmethod
static method periodic takes nothing returns nothing
local thistype this = thistype(0)
loop
set this=this.next
exitwhen this==0
if this.dur<=0 or not (GetWidgetLife(this.u)>0.405) then
call this.destroy()
else
if not IsUnitMoving(this.u) then
call this.issue()
endif
set this.dur=this.dur-PERIOD
endif
endloop
endmethod
private static method doPrevent takes nothing returns boolean
local thistype this
if thistype.table.has(GetHandleId(GetTriggerUnit())) and thistype.toPrevent then
set this=thistype.table[GetHandleId(GetTriggerUnit())]
set thistype.toPrevent=false
call IssuePointOrderById(this.u,851986,this.nx,this.ny)
set thistype.toPrevent=true
endif
return false
endmethod
private static trigger Prevent=CreateTrigger()
private static method onInit takes nothing returns nothing
set thistype.table=Table.create()
set thistype.toPrevent=true
call TimerStart(CreateTimer(),PERIOD,true,function Fear.periodic)
call TriggerRegisterAnyUnitEventBJ(thistype.Prevent, EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER )
call TriggerRegisterAnyUnitEventBJ(thistype.Prevent, EVENT_PLAYER_UNIT_ISSUED_ORDER )
call TriggerRegisterAnyUnitEventBJ(thistype.Prevent, EVENT_PLAYER_UNIT_ISSUED_POINT_ORDER )
call TriggerAddCondition(thistype.Prevent,Condition(function thistype.doPrevent))
endmethod
endstruct
function UnitFear takes unit u, real dur returns nothing
local Fear this
local integer id=GetHandleId(u)
if Fear.table.has(id) then
set this=Fear.table[id]
else
set this=Fear.create()
set Fear(0).next.prev=this
set this.next=Fear(0).next
set Fear(0).next=this
set this.prev=Fear(0)
set Fear.table[id]=this
set this.u=u
set this.dur=0
set this.x=GetUnitX(u)
set this.y=GetUnitY(u)
/*
Buff based on Slow Aura
-- ADD --
call UnitAddAbility(u,'A60B')
call UnitMakeAbilityPermanent(u,true,'A60B')
*/
endif
if this.dur<dur then
set this.dur=dur
endif
endfunction
function UnitStopFear takes unit u returns nothing
local integer id=GetHandleId(u)
if Fear.table.has(id) then
call Fear(Fear.table[id]).destroy()
endif
endfunction
function UnitFearElapsed takes unit u returns real
local integer id=GetHandleId(u)
if Fear.table.has(id) then
return Fear(Fear.table[id]).dur
else
return 0.
endif
endfunction
endlibrary
GetWidgetLife(u)>0.405
Then you can't optimize the map.Yeah just declare the UnitAlive native in your map script, done. AFAIK its the best way.
Then you can't optimize the map.
library IsUnitAlive
globals
private constant boolean AI_NATIVE = true
endglobals
static if AI_NATIVE then
native UnitAlive takes unit u returns boolean
endif
function IsUnitAlive takes unit u returns boolean
static if AI_NATIVE then
return UnitAlive(u)
endif
static if not AI_NATIVE then
return GetWidgetLife(u) > 0.405
endif
endfunction
endlibrary
if the unit had Tornado Wander, it instantly died when hit a tree.