library DoorSystem initializer Init
// Door system by The_Witcher
//
// this system opens every instance of the registered doortypes when a units comes close
// if the unit moves away from the door it will close again
globals
//if this is true doors will only close on leave if there are no units in their range
public boolean CLOSE_ONLY_WHEN_EMPTY = true
// These are the standart animations for the doors in your map
private constant string STANDART_OPEN_ANIMATION = "Death Alternate"
private constant string STANDART_STAND_OPEN_ANIMATION = "Stand Alternate"
private constant string STANDART_CLOSE_ANIMATION = "Birth"
private constant string STANDART_STAND_CLOSE_ANIMATION = "stand"
endglobals
//Doors will only be triggered when the entering unit matches these conditions
private function DoorEventConditions takes nothing returns boolean
return not (IsUnitType(GetFilterUnit(),UNIT_TYPE_DEAD) or GetUnitTypeId(GetFilterUnit()) == 0 )
endfunction
//-----------Don't modify anything below this line---------
globals
private integer array doors
private real array range
private integer total
private hashtable h
private boolexpr filt
private boolexpr enter
private integer i
private group g
private timer tim
endglobals
private function FilterFunc takes nothing returns boolean
return GetDestructableTypeId(GetFilterDestructable()) == doors[i] and LoadBoolean(h,GetHandleId(GetFilterDestructable()),1) != true and LoadBoolean(h,GetHandleId(GetFilterDestructable()),2) != true
endfunction
private function DoorActions takes nothing returns nothing
local destructable d = LoadDestructableHandle(h,GetHandleId(GetTriggeringTrigger()),0)
if GetTriggerEventId()==EVENT_GAME_ENTER_REGION and not LoadBoolean(h,GetHandleId(d),0) then
call KillDestructable(d)
call SaveBoolean(h,GetHandleId(d),0,true)
call SetDestructableAnimation(d,LoadStr(h,GetDestructableTypeId(d),4))
call QueueDestructableAnimation(d,LoadStr(h,GetDestructableTypeId(d),5))
elseif GetTriggerEventId()==EVENT_GAME_LEAVE_REGION and LoadBoolean(h,GetHandleId(d),0) then
if not CLOSE_ONLY_WHEN_EMPTY then
call DestructableRestoreLife(d,GetDestructableMaxLife(d),true)
call SaveBoolean(h,GetHandleId(d),0,false)
call SetDestructableAnimation(d, LoadStr(h,GetDestructableTypeId(d),6))
call QueueDestructableAnimation(d, LoadStr(h,GetDestructableTypeId(d),7))
else
call GroupClear(g)
call GroupEnumUnitsInRect(g, LoadRectHandle(h,GetHandleId(d),3), enter)
if FirstOfGroup(g) == null then
call DestructableRestoreLife(d,GetDestructableMaxLife(d),true)
call SaveBoolean(h,GetHandleId(d),0,false)
call SetDestructableAnimation(d, LoadStr(h,GetDestructableTypeId(d),6))
call QueueDestructableAnimation(d, LoadStr(h,GetDestructableTypeId(d),7))
endif
endif
endif
set d = null
endfunction
private function RegisterEvents takes nothing returns nothing
local destructable d = GetEnumDestructable()
local trigger t = CreateTrigger()
local region g = CreateRegion()
local real x = GetDestructableX(d)
local real y = GetDestructableY(d)
local rect r = Rect(x-range[i], y-range[i], x+range[i], y+range[i])
call RegionAddRect(g,r)
call SaveBoolean(h,GetHandleId(d),0,false)
call SaveDestructableHandle(h,GetHandleId(t),0,d)
call SaveRectHandle(h,GetHandleId(d),3,r)
call SaveBoolean(h,GetHandleId(d),1,true)
call SaveStr(h,GetDestructableTypeId(d),4,STANDART_OPEN_ANIMATION)
call SaveStr(h,GetDestructableTypeId(d),5,STANDART_STAND_OPEN_ANIMATION)
call SaveStr(h,GetDestructableTypeId(d),6,STANDART_CLOSE_ANIMATION)
call SaveStr(h,GetDestructableTypeId(d),7,STANDART_STAND_CLOSE_ANIMATION)
call TriggerRegisterEnterRegion(t,g,enter)
call TriggerRegisterLeaveRegion(t,g,enter)
call TriggerAddAction(t,function DoorActions)
set t = null
set d = null
set r = null
set g = null
endfunction
private function RescanAll takes nothing returns nothing
set i = 0
loop
exitwhen i >= total
call EnumDestructablesInRect(bj_mapInitialPlayableArea, filt, function RegisterEvents)
set i = i + 1
endloop
endfunction
function OpenDoor takes destructable d, boolean flag returns nothing
call SaveBoolean(h,GetHandleId(h),0,flag)
endfunction
function ExcludeDoor takes destructable d, boolean flag returns nothing
call SaveBoolean(h,GetHandleId(h),2,flag)
endfunction
function ChangeDoorTypeAnimations takes integer id, string openAnimation, string standOpenAnimation, string closeAnimation, string standCloseAnimation returns nothing
call SaveStr(h,id,4,openAnimation)
call SaveStr(h,id,5,standOpenAnimation)
call SaveStr(h,id,6,closeAnimation)
call SaveStr(h,id,7,standCloseAnimation)
endfunction
function AddDoorType takes integer id, real enterRange returns nothing
set doors[total] = id
set range[total] = enterRange
call SaveStr(h,id,4,STANDART_OPEN_ANIMATION)
call SaveStr(h,id,5,STANDART_STAND_OPEN_ANIMATION)
call SaveStr(h,id,6,STANDART_CLOSE_ANIMATION)
call SaveStr(h,id,7,STANDART_STAND_CLOSE_ANIMATION)
set total = total + 1
call RescanAll()
endfunction
private function Init takes nothing returns nothing
set h = InitHashtable()
set total = 0
set filt = Condition(function FilterFunc)
set enter = Condition(function DoorEventConditions)
set g = CreateGroup()
set tim = CreateTimer()
endfunction
private function CatchNewDoors takes integer objectid, real x, real y, real face, real scale, integer variation returns nothing
call TimerStart(tim,0.01,false,function RescanAll)
endfunction
private function CatchNewDoors2 takes integer objectid, real x, real y, real z, real face, real scale, integer variation returns nothing
call TimerStart(tim,0.01,false,function RescanAll)
endfunction
hook CreateDestructable CatchNewDoors
hook CreateDestructableZ CatchNewDoors2
endlibrary