-- Region Path System
RegionPathSystem = {
paths = {}, -- Table to store paths by ID (divided into segments)
pathPlayers = {}, -- Table to associate paths with specific players
unitSegmentIndex = {}, -- Tracks the current segment index for units
}
-- Function to add a region to a path
-- @param pathID: The ID of the path to add the region to
-- @param region: The region to add to the path
function RegionPathSystem:AddRegionToPath(pathID, region)
if not self.paths[pathID] then
self.paths[pathID] = {} -- Create a new path if it doesn't exist
end
-- Add the region to the last segment, or create a new segment if necessary
local segments = self.paths[pathID]
local lastSegment = segments[#segments]
if not lastSegment or #lastSegment >= 12 then
lastSegment = {}
table.insert(segments, lastSegment)
end
table.insert(lastSegment, region)
-- Automatically set up a trigger for the last region in the segment
if #lastSegment == 12 then
SetupRegionEntryTrigger(pathID, region)
end
end
-- Function to associate a path with a specific player
-- @param pathID: The ID of the path
-- @param player: The player to associate with the path
function RegionPathSystem:SetPathPlayer(pathID, player)
self.pathPlayers[pathID] = player
end
-- Function to get the current segment for a unit
-- @param pathID: The ID of the path the unit is following
-- @param unit: The unit whose current segment is being checked
-- @return The current segment and its index
function RegionPathSystem:GetCurrentSegment(pathID, unit)
local segmentIndex = self.unitSegmentIndex[unit] or 1
local segments = self.paths[pathID]
return segments and segments[segmentIndex], segmentIndex
end
-- Function to move a unit to the next segment
-- @param pathID: The ID of the path the unit is following
-- @param unit: The unit to advance to the next segment
-- @return The next segment, or nil if all segments are completed
function RegionPathSystem:AdvanceToNextSegment(pathID, unit)
local segments = self.paths[pathID]
if not segments then
--print("Path with ID '" .. pathID .. "' does not exist.")
return
end
local currentIndex = self.unitSegmentIndex[unit] or 1
if currentIndex < #segments then
self.unitSegmentIndex[unit] = currentIndex + 1
return segments[self.unitSegmentIndex[unit]]
else
--print("Unit has completed all segments of path '" .. pathID .. "'")
return nil
end
end
-- Function to handle units entering a region and transitioning to the next segment
-- @param pathID: The ID of the path the unit is following
-- @param enteringUnit: The unit entering the region
function RegionPathSystem:HandleUnitEnteringPath(pathID, enteringUnit)
local segment, segmentIndex = self:GetCurrentSegment(pathID, enteringUnit)
if not segment then
--print("Path with ID '" .. pathID .. "' does not exist or has no segments.")
return
end
local owner = GetOwningPlayer(enteringUnit)
local allowedPlayer = self.pathPlayers[pathID]
if owner ~= allowedPlayer then
--print("Unit's owner is not allowed to use path '" .. pathID .. "'.")
return
end
-- Move the unit through each region in the segment
for i, region in ipairs(segment) do
local rectCenterX, rectCenterY = GetRectCenterX(region), GetRectCenterY(region)
BlzQueuePointOrderById(enteringUnit, 851983, rectCenterX, rectCenterY) -- Move to region Thank you Waterknight for ID
end
-- Automatically move to the next segment after completing this one
local nextSegment = self:AdvanceToNextSegment(pathID, enteringUnit)
if nextSegment then
local firstRegion = nextSegment[1]
if firstRegion then
SetupRegionEntryTrigger(pathID, firstRegion)
end
else
--print("Unit has completed all segments for path '" .. pathID .. "'")
end
end
-- Trigger setup for region entry
RegionTriggers = RegionTriggers or {}
-- Utility function to check if an object is a region
-- @param object: The object to check
-- @return True if the object is a region, false otherwise
function IsRegion(object)
return object and type(object) == "userdata" and tostring(object):find("region")
end
-- Utility function to convert a rect to a region
-- @param rect: The rect to convert
-- @return The created region
function ConvertRectToRegion(rect)
if not rect then
--print("Error: Attempted to convert a nil rect to a region.")
return nil
end
local region = CreateRegion()
RegionAddRect(region, rect)
return region
end
-- Trigger setup for region entry
-- @param pathID: The ID of the path
-- @param firstRegion: The first region in the segment to set up the trigger for
function SetupRegionEntryTrigger(pathID, firstRegion)
-- Validate firstRegion
if not firstRegion then
--print("Error: firstRegion is nil for path '" .. pathID .. "'. Aborting setup.")
return
end
if not IsRegion(firstRegion) then
firstRegion = ConvertRectToRegion(firstRegion)
if not firstRegion then
--print("Error: Failed to convert firstRegion to a valid region.")
return
end
end
if not RegionTriggers[firstRegion] then
local newTrigger = CreateTrigger()
if not newTrigger then
return
end
TriggerRegisterEnterRegion(newTrigger, firstRegion, nil)
RegionTriggers[firstRegion] = newTrigger
else
--print("Using existing trigger for region: " .. tostring(firstRegion))
end
local regionTrigger = RegionTriggers[firstRegion]
TriggerAddAction(regionTrigger, function()
local enteringUnit = GetEnteringUnit()
if enteringUnit then
RegionPathSystem:HandleUnitEnteringPath(pathID, enteringUnit)
else
--print("Warning: No unit entered the region.")
end
end)
end
-- Example Initialization Setup
function InitSetup()
RegionPathSystem:AddRegionToPath("PathName", gg_rct_REGIONNAME)
RegionPathSystem:SetPathPlayer("PathName", Player(0))
SetupRegionEntryTrigger("PathName", gg_rct_REGIONNAME)
end
[LIST=1]
[*]
[/LIST]