library DockingSystem initializer DockingSystem_OnCast_Func requires SpellEffectEvent optional BlizzardMessage
/*** If you're getting a duplicate of UnitAlive, you can delete or comment out this one ***/
native UnitAlive takes unit id returns boolean
globals
private trigger DockingSystem_Dock_Trigger = null
private trigger DockingSystem_Undock_Trigger = null
private integer RegisterCount = 0
private unit array RegisteredUnit
private constant integer REGISTER_CLEANUP_LIMIT = 2
private constant integer MAX_PORTS_HARD_LIMIT = 8
private constant string ERROR_MESSAGE_NOT_A_STATION = "This structure is not viable."
private constant string ERROR_MESSAGE_NO_SPACE = "All docking ports are occupied."
endglobals
function DockingSystem_Undock takes nothing returns boolean
local unit caster = GetTriggerUnit()
local unit docking_station = SetDockingPlug[caster].station
local integer index = SetDockingPlug[caster].port_index
local integer i = SetDockingPlug[caster].reg_index
call BJDebugMsg("Undock")
call UnitRemoveAbility(caster, 'ARal')
call UnitAddAbility(caster, SetDockingPlug[caster].plug_out_ability)
call UnitRemoveAbility(caster, SetDockingPlug[caster].plug_out_ability)
call UnitAddAbility(caster, SetDockingPlug[caster].docking_ability)
call SetUnitPathing(caster, true)
set SetDockingPlug[caster].port_index = 0
set SetDockingPlug[caster].station = null
set SetDockingPlug[caster].reg_index = 0
set SetDockingStation[docking_station].is_port_occupied[index] = false
set SetDockingStation[docking_station].docked_unit[index] = null
set SetDockingStation[docking_station].number_of_occupied_ports = SetDockingStation[docking_station].number_of_occupied_ports - 1
//Events
set udg_DockingEvent_Plug = caster
set udg_DockingEvent_Station = docking_station
set udg_DockingEvent_Ports = SetDockingStation[docking_station].number_of_occupied_ports
set udg_DockingEvent = 2.
set udg_DockingEvent = 0.
set udg_DockingEvent_Plug = null
set udg_DockingEvent_Station = null
//End Events
/*call DestroyTrigger(DockingSystem_Undock_Trigger)
set DockingSystem_Undock_Trigger = CreateTrigger()
loop
set RegisteredUnit[i] = RegisteredUnit[i + 1]
call TriggerRegisterUnitEvent(DockingSystem_Undock_Trigger, RegisteredUnit[i], EVENT_UNIT_DEATH)
call TriggerRegisterUnitEvent(DockingSystem_Undock_Trigger, RegisteredUnit[i], EVENT_UNIT_ISSUED_ORDER)
call TriggerRegisterUnitEvent(DockingSystem_Undock_Trigger, RegisteredUnit[i], EVENT_UNIT_ISSUED_POINT_ORDER)
call TriggerRegisterUnitEvent(DockingSystem_Undock_Trigger, RegisteredUnit[i], EVENT_UNIT_ISSUED_TARGET_ORDER)
call TriggerAddCondition(DockingSystem_Undock_Trigger, function DockingSystem_Undock)
set i = i + 1
exitwhen i > RegisterCount
endloop
//set RegisteredUnit[i] = null
set RegisterCount = RegisterCount - 1*/
set caster = null
return false
endfunction
function DockingSystem_OnCast_Actions takes nothing returns nothing
local unit caster = GetTriggerUnit()
local unit target = GetSpellTargetUnit()
local integer index = GetRandomInt(1, SetDockingStation[target].number_of_ports)
local integer segments = 0
local real angle = 0.
local real newX = 0.
local real newY = 0.
if SetDockingStation[target].is_station then
if SetDockingStation[target].number_of_occupied_ports < SetDockingStation[target].number_of_ports then
if SetDockingStation[target].is_port_occupied[index] then
loop
set index = index + 1
if index > SetDockingStation[target].number_of_ports then
set index = 1
endif
exitwhen not SetDockingStation[target].is_port_occupied[index]
endloop
endif
call UnitAddAbility(caster, SetDockingPlug[caster].plug_in_ability)
call UnitRemoveAbility(caster, SetDockingPlug[caster].plug_in_ability)
set angle = 6.28319 / SetDockingStation[target].number_of_ports * index + SetDockingStation[target].angle_offset
//Atan2(GetUnitY(caster)-GetUnitY(target), GetUnitX(caster)-GetUnitX(target))
call SetUnitFacing(caster, angle * bj_RADTODEG + SetDockingPlug[caster].facing_angle)
call SetUnitPathing(caster, false)
call SetUnitX(caster, GetUnitX(target) + Cos(angle) * SetDockingStation[target].port_distance)
call SetUnitY(caster, GetUnitY(target) + Sin(angle) * SetDockingStation[target].port_distance)
call UnitRemoveAbility(caster, 'Amov')
call UnitAddAbility(caster, 'ARal')
set SetDockingPlug[caster].station = target
set SetDockingPlug[caster].port_index = index
set SetDockingStation[target].is_port_occupied[index] = true
set SetDockingStation[target].docked_unit[index] = caster
set SetDockingStation[target].number_of_occupied_ports = SetDockingStation[target].number_of_occupied_ports + 1
if DockingSystem_Undock_Trigger == null then
set DockingSystem_Undock_Trigger = CreateTrigger()
endif
call TriggerRegisterUnitEvent(DockingSystem_Undock_Trigger, caster, EVENT_UNIT_DEATH)
call TriggerRegisterUnitEvent(DockingSystem_Undock_Trigger, caster, EVENT_UNIT_ISSUED_ORDER)
call TriggerRegisterUnitEvent(DockingSystem_Undock_Trigger, caster, EVENT_UNIT_ISSUED_POINT_ORDER)
call TriggerRegisterUnitEvent(DockingSystem_Undock_Trigger, caster, EVENT_UNIT_ISSUED_TARGET_ORDER)
call TriggerAddCondition(DockingSystem_Undock_Trigger, function DockingSystem_Undock)
//set RegisterCount = RegisterCount + 1
//set RegisteredUnit[RegisterCount] = caster
//set SetDockingPlug[caster].reg_index = RegisterCount
//Events
set udg_DockingEvent_Plug = caster
set udg_DockingEvent_Station = target
set udg_DockingEvent_Ports = SetDockingStation[target].number_of_occupied_ports
set udg_DockingEvent = 1.
set udg_DockingEvent = 0.
set udg_DockingEvent_Plug = null
set udg_DockingEvent_Station = null
//End Events
else
static if LIBRARY_BlizzardMessage then
call BlizzardMessage(ERROR_MESSAGE_NO_SPACE, "|cffffcc00", 31, GetOwningPlayer(caster))
endif
endif
else
static if LIBRARY_BlizzardMessage then
call BlizzardMessage(ERROR_MESSAGE_NOT_A_STATION, "|cffffcc00", 31, GetOwningPlayer(caster))
endif
endif
set caster = null
set target = null
endfunction
/*
STRUCTS ------------------------------------------------------------------------------------------------------------
*/
//STATION
struct SetDockingStation
boolean is_station
integer number_of_ports
integer number_of_occupied_ports
integer instance
real angle_offset
real port_distance
unit array docked_unit[MAX_PORTS_HARD_LIMIT]
boolean array is_port_occupied[MAX_PORTS_HARD_LIMIT]
method destroy takes nothing returns nothing
local integer iLoop = 0
set this.number_of_ports = 0
set this.number_of_occupied_ports = 0
set this.angle_offset = 0.
set this.port_distance = 0.
set this.is_station = false
loop
exitwhen iLoop > MAX_PORTS_HARD_LIMIT
set this.docked_unit[iLoop] = null
set this.is_port_occupied[iLoop] = false
set iLoop = iLoop + 1
endloop
call this.deallocate()
endmethod
static method operator [] takes unit u returns thistype
return thistype(GetUnitUserData(u)).instance
endmethod
static method create takes unit u, integer ports, real angle, real distance returns thistype
local thistype this = allocate()
set thistype(GetUnitUserData(u)).instance = this
set this.number_of_ports = ports
set this.number_of_occupied_ports = 0
set this.angle_offset = angle
set this.port_distance = distance
set this.is_station = true
return this
endmethod
endstruct
//PLUG
struct SetDockingPlug
boolean is_plug
integer plug_in_ability
integer plug_out_ability
integer docking_ability
integer instance
integer port_index
integer reg_index
real facing_angle
unit station
method destroy takes nothing returns nothing
set this.is_plug = true
set this.plug_in_ability = 0
set this.plug_out_ability = 0
set this.docking_ability = 0
set this.facing_angle = 0.
set this.port_index = 0
set this.station = null
call this.deallocate()
endmethod
static method operator [] takes unit u returns thistype
return thistype(GetUnitUserData(u)).instance
endmethod
static method create takes unit u, integer pt_plug_in, integer pt_plug_out, integer docking_abil, real facing returns thistype
local thistype this = allocate()
set thistype(GetUnitUserData(u)).instance = this
set this.is_plug = true
set this.station = null
set this.plug_in_ability = pt_plug_in
set this.plug_out_ability = pt_plug_out
set this.docking_ability = docking_abil
set this.facing_angle = facing
set this.port_index = 0
call UnitAddAbility(u, docking_abil)
/*if DockingSystem_Dock_Trigger == null then
set DockingSystem_Dock_Trigger = CreateTrigger()
endif
call TriggerRegisterUnitEvent(DockingSystem_Dock_Trigger, u, EVENT_UNIT_SPELL_EFFECT)
call TriggerAddCondition(DockingSystem_Dock_Trigger, function DockingSystem_OnCast_Check)*/
return this
endmethod
endstruct
//===========================================================================
function DockingSystem_OnCast_Func takes nothing returns nothing
call RegisterSpellEffectEvent('dock', function DockingSystem_OnCast_Actions)
//Copy-paste the above function call and change the first argument to the id any docking ability you may have.
endfunction
endlibrary