- Joined
- Aug 3, 2004
- Messages
- 2,884
I am getting a compile error on the target unit type ID line, obviously I made a mistake.
JASS:
scope Waygate initializer Init
//made by MaskedPoptart
// requires Table, TimerUtils
private keyword Waygate
globals
private constant integer UNSELECTABLE_ABIL_ID = 'Aloc'
private constant integer INVULNERABLE_ABIL_ID = 'Avul'
private constant integer WAYGATE_UNIT_ID = 'u000'
private constant integer REQUIREMENT_DUMMY_ID = 'e000'
private constant integer BUILD_WAYGATE_ABIL_ID = 'A000'
private constant real ACTIVATION_DELAY = .5 //after a waygate finishes construction, it
//will ignore all units that enter it for this amount of time (seconds).
private constant real ENTER_RANGE = 75.0 //units have to come this close to be sent through the waygate
private constant real TIMER_INTERVAL = .03 //units change scale every TIMER_INTERVAL seconds
private constant real SCALE_PER_SECOND = .7 //this is how much scale units change every second (not affected by TIMER_INTERVAL)
private constant real DISTANCE_PER_SECOND = 1000.0 //this is how fast units are transported between portals
//--------------------------------------------
//don't touch anything from this line on
private constant integer IGNORE = 1
private constant integer DONT_IGNORE = 0
private unit array playerWaygateRequirement
private Waygate array playerWaygates
private boolexpr isValidEnteringUnitExpr
endglobals
//----------------------Helper Functions-----------------------
private function CreateRequirementForPlayer takes player p returns nothing
local unit u = CreateUnit(p, REQUIREMENT_DUMMY_ID,/*
*/ GetPlayerStartLocationX(p), GetPlayerStartLocationY(p), bj_UNIT_FACING)
call UnitAddAbility(u, INVULNERABLE_ABIL_ID)
call UnitAddAbility(u, UNSELECTABLE_ABIL_ID)
set playerWaygateRequirement[GetPlayerId(p)] = u
set u = null
endfunction
private function CreateRequirements takes nothing returns nothing
local integer i = 0
loop
call CreateRequirementForPlayer(Player(i))
set i = i + 1
exitwhen i == bj_MAX_PLAYER_SLOTS
endloop
endfunction
private function RemoveRequirementForPlayer takes player p returns nothing
local integer pId = GetPlayerId(p)
call RemoveUnit(playerWaygateRequirement[pId])
set playerWaygateRequirement[pId] = null
endfunction
//----------------------Main Section------------------------
private struct TransportationData
private unit unitToTransport
private real scale
private Waygate startWaygate
private Waygate endWaygate
private timer t
private static method enlargeUnitLoop takes nothing returns nothing
local timer t = GetExpiredTimer()
local thistype this = thistype(GetTimerData(t))
local unit u = this.unitToTransport
local real scale = this.scale
if(scale <= 1.0)then
call SetUnitScale(u, scale, scale, scale)
set this.scale = scale + SCALE_PER_SECOND*TIMER_INTERVAL
else
call SetUnitScale(u, 1.0, 1.0, 1.0)
set this.scale = 1.0
call ReleaseTimer(t)
call UnitRemoveAbility(u, INVULNERABLE_ABIL_ID)
call PauseUnit(u, false)
call this.destroy()
endif
endmethod
private static method transport takes nothing returns nothing
local timer t = GetExpiredTimer()
local thistype this = thistype(GetTimerData(t))
local unit unitToTransport = this.unitToTransport
local unit source = this.startWaygate.waygateUnit
local Waygate destinationWaygate = this.endWaygate
local unit destination = endWaygate.waygateUnit
if(destination != null and destinationWaygate.isActivated)then
set destinationWaygate.unitsToIgnore[unitToTransport] = IGNORE //makes the other waygate ignore the fact that this
//unit is entering its range.
call SetUnitPosition(unitToTransport, GetUnitX(destination), GetUnitY(destination))
call TimerStart(t, TIMER_INTERVAL, true, function thistype.enlargeUnitLoop)
elseif(source != null)then
call TimerStart(t, TIMER_INTERVAL, true, function thistype.enlargeUnitLoop)
else
call SetUnitExploded(unitToTransport, true)
call KillUnit(unitToTransport)
endif
endmethod
private static method shrinkUnitLoop takes nothing returns nothing
local timer t = GetExpiredTimer()
local thistype this = thistype(GetTimerData(t))
local unit unitToTransport = this.unitToTransport
local Waygate sourceWaygate
local unit source
local Waygate destinationWaygate
local unit destination
local real scale = this.scale
local real dx
local real dy
local real transportTime
if(scale >= 0)then
call SetUnitScale(unitToTransport, scale, scale, scale)
set this.scale = scale - SCALE_PER_SECOND*TIMER_INTERVAL
else
call SetUnitScale(unitToTransport, 0.0, 0.0, 0.0)
set this.scale = 0.0
call PauseTimer(t)
set sourceWaygate = this.startWaygate
set source = sourceWaygate.waygateUnit
set destinationWaygate = this.endWaygate
set destination = destinationWaygate.waygateUnit
if(destination != null and destinationWaygate.isActivated)then
set dx = GetUnitX(destination) - GetUnitX(source)
set dy = GetUnitY(destination) - GetUnitY(source)
set transportTime = (dx*dx + dy*dy) / (DISTANCE_PER_SECOND*DISTANCE_PER_SECOND)
call TimerStart(t, transportTime, false, function thistype.transport)
elseif(source != null)then
call TimerStart(t, TIMER_INTERVAL, true, function thistype.enlargeUnitLoop)
else
call SetUnitExploded(unitToTransport, true)
call KillUnit(unitToTransport)
endif
endif
endmethod
static method create takes unit unitToTransport, Waygate startWaygate, Waygate endWaygate returns thistype
local thistype this = thistype.allocate()
local timer t = NewTimer()
set this.unitToTransport = unitToTransport
set this.scale = 1.0
set this.startWaygate = startWaygate
set this.endWaygate = endWaygate
call UnitAddAbility(unitToTransport, INVULNERABLE_ABIL_ID)
call PauseUnit(unitToTransport, true)
call SetTimerData(t, this)
call TimerStart(t, TIMER_INTERVAL, true, function thistype.shrinkUnitLoop)
set this.t = t
return this
endmethod
endstruct
private struct Waygate
readonly unit waygateUnit
private Waygate linkedWaygate
readonly boolean isActivated
private trigger entranceTrigger
readonly HandleTable unitsToIgnore
private static HandleTable instances
private method onDestroy takes nothing returns nothing
local unit toRemove = this.waygateUnit
local player owner = GetOwningPlayer(toRemove)
local integer ownerId = GetPlayerId(owner)
local thistype linkedWaygate = this.linkedWaygate
if(linkedWaygate != 0)then //if the player has two waygates
call CreateRequirementForPlayer(owner)
set linkedWaygate.linkedWaygate = 0
set playerWaygates[ownerId] = linkedWaygate
endif
if(playerWaygates[ownerId] == this)then //if the stored waygate is this
set playerWaygates[ownerId] = this.linkedWaygate //set stored waygate to other waygate
endif
if(this.entranceTrigger != null)then
call DestroyTrigger(this.entranceTrigger)
set this.entranceTrigger = null
endif
set this.linkedWaygate = 0
set this.waygateUnit = null
endmethod
private static method startTransportToLinkedWaygate takes nothing returns nothing
local unit unitToTransport = GetTriggerUnit()
local thistype this = thistype( thistype.instances[GetTriggeringTrigger()] )
if(this.isActivated)then
if(this.unitsToIgnore[unitToTransport] == IGNORE)then
set this.unitsToIgnore[unitToTransport] = DONT_IGNORE
else
call TransportationData.create(unitToTransport, this, this.linkedWaygate)
endif
endif
endmethod
private static method remove takes nothing returns nothing
local trigger trig = GetTriggeringTrigger()
local thistype this = thistype( thistype.instances[trig] )
call DestroyTrigger(trig)
call this.destroy()
endmethod
private static method activate takes nothing returns nothing
local timer t = GetExpiredTimer()
local thistype this = thistype( GetTimerData(t) )
set this.isActivated = true
call ReleaseTimer(t)
endmethod
static method finishConstruction takes unit builder, unit waygateUnit returns nothing
local trigger trig
local timer t
local thistype this = thistype( thistype.instances[waygateUnit] )
set t = NewTimer()
call SetTimerData(t, this)
call TimerStart(t, ACTIVATION_DELAY, false, function thistype.activate)
set trig = CreateTrigger()
call TriggerRegisterUnitInRange(trig, waygateUnit, ENTER_RANGE, isValidEnteringUnitExpr)
call TriggerAddAction(trig, function thistype.startTransportToLinkedWaygate)
set this.entranceTrigger = trig
set thistype.instances[trig] = this
set trig = CreateTrigger()
call TriggerRegisterUnitEvent(trig, waygateUnit, EVENT_UNIT_DEATH)
call TriggerAddAction(trig, function thistype.remove)
set thistype.instances[trig] = this
endmethod
static method cancelConstruction takes unit waygateUnit returns nothing
local thistype this = thistype( thistype.instances[waygateUnit] )
call this.destroy()
endmethod
static method startConstruction takes unit waygateUnit returns nothing
local thistype this = thistype.allocate()
local player owner = GetOwningPlayer(waygateUnit)
local integer ownerId = GetPlayerId(owner)
local thistype otherWaygate = playerWaygates[ownerId]
set this.waygateUnit = waygateUnit
if(otherWaygate != 0)then //if there are now 2 waygates owned by the player
set this.linkedWaygate = otherWaygate
set otherWaygate.linkedWaygate = this
call RemoveRequirementForPlayer(owner) //don't allow player to make any more waygates
else
set this.linkedWaygate = 0
set playerWaygates[ownerId] = this
endif
set this.entranceTrigger = null
set this.isActivated = false
set this.unitsToIgnore = HandleTable.create()
set thistype.instances[waygateUnit] = this
endmethod
private static method onInit takes nothing returns nothing
set thistype.instances = HandleTable.create()
endmethod
endstruct
private function StartWaygate takes nothing returns nothing
call Waygate.startConstruction(GetConstructingStructure())
endfunction
private function CancelWaygate takes nothing returns nothing
call Waygate.cancelConstruction(GetCancelledStructure())
endfunction
private function FinishWaygate takes nothing returns nothing
call Waygate.finishConstruction(GetTriggerUnit(), GetConstructedStructure())
endfunction
//--------------------Conditions/Filters---------------------------
private function IsValidEnteringUnit takes nothing returns boolean
return not IsUnitType(GetFilterUnit(), UNIT_TYPE_DEAD) and not IsUnitEnemy()
endfunction
private function IsBuildingWaygate takes unit building returns boolean
return GetUnitTypeId(building) == WAYGATE_UNIT_ID
endfunction
private function IsStartedBuildingWaygate takes nothing returns boolean
return IsBuildingWaygate(GetConstructingStructure())
endfunction
private function IsCancelledBuildingWaygate takes nothing returns boolean
return IsBuildingWaygate(GetCancelledStructure())
endfunction
private function IsFinishedBuildingWaygate takes nothing returns boolean
return IsBuildingWaygate(GetConstructedStructure())
endfunction
//-------------------------Init-----------------------
private function Init takes nothing returns nothing
local trigger trig = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(trig, EVENT_PLAYER_UNIT_CONSTRUCT_START)
call TriggerAddCondition(trig, Condition(function IsStartedBuildingWaygate))
call TriggerAddAction(trig, function StartWaygate)
set trig = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(trig, EVENT_PLAYER_UNIT_CONSTRUCT_CANCEL)
call TriggerAddCondition(trig, Condition(function IsCancelledBuildingWaygate))
call TriggerAddAction(trig, function CancelWaygate)
set trig = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(trig, EVENT_PLAYER_UNIT_CONSTRUCT_FINISH)
call TriggerAddCondition(trig, Condition(function IsFinishedBuildingWaygate))
call TriggerAddAction(trig, function FinishWaygate)
call CreateRequirements()
set isValidEnteringUnitExpr = Filter(function IsValidEnteringUnit)
endfunction
endscope