local I=game:GetService("\082\101\112\108\105\099\097\116\101\100\083\116\111\114\097\103\101")local x=require((I:WaitForChild("\080\114\111\106\101\099\116")):WaitForChild("\082\101\112\108\105\099\097\116\101\100\083\116\111\114\097\103\101"))local u=x:GetResource("\069\120\116\101\114\110\097\108\085\116\105\108\046\078\101\120\117\115\073\110\115\116\097\110\099\101\046\078\101\120\117\115\079\098\106\101\099\116")local U=x:GetResource("\071\097\109\101\068\097\116\097\046\071\101\110\101\114\097\116\105\111\110\046\078\080\067\076\111\099\097\116\105\111\110\115")local k=x:GetResource("\083\116\097\116\101\046\080\097\116\104\070\105\110\100\046\077\097\112\071\114\097\112\104\083\111\108\118\101\114")local R=u:Extend()R.CachedResults={}R.MapGraph=k.Create()R:SetClassName("\090\111\110\101\115")function R.GetZone(u,I,x)I,x=math.round(I),math.round(x)local k=tostring(I)..("\095"..tostring(x))if not u.CachedResults[k]then local R,p=math.huge,nil for u,U in pairs(u.MapGraph.Nodes)do local k=((I-U.X)^2+(x-U.Y)^2)^.5 if k<R then R=k p=u end end local z,n=math.huge,nil for I,x in pairs(U)do local U=tostring(x.CellX)..("\095"..tostring(x.CellY))local k=u.MapGraph:GetShortestDistance(p,U)if k<z then z=k n=x.Zone end end u.CachedResults[k]=n end return u.CachedResults[k]end return R
--[[
TheNexusAvenger

Utility for zones.
Class is static (should not be created).
--]]

local ReplicatedStorage = game:GetService("ReplicatedStorage")

local ReplicatedStorageProject = require(ReplicatedStorage:WaitForChild("Project"):WaitForChild("ReplicatedStorage"))

local NexusObject = ReplicatedStorageProject:GetResource("ExternalUtil.NexusInstance.NexusObject")
local NPCLocations = ReplicatedStorageProject:GetResource("GameData.Generation.NPCLocations")
local MapGraphSolver = ReplicatedStorageProject:GetResource("State.PathFind.MapGraphSolver")

local Zones = NexusObject:Extend()
Zones.CachedResults = {}
Zones.MapGraph = MapGraphSolver.Create()
Zones:SetClassName("Zones")



--[[
Returns the zone for a given cell.
The cell can be decimal.
--]]
function Zones:GetZone(X,Y)
    X,Y = math.round(X),math.round(Y)
    local ZoneId = tostring(X).."_"..tostring(Y)

    --Populate the cached entry.
    if not self.CachedResults[ZoneId] then
        --Determine the closest node.
        local LowestDistanceToNode,ClosestNode = math.huge,nil
        for Id,Node in pairs(self.MapGraph.Nodes) do
            local Distance = (((X - Node.X) ^ 2) + ((Y - Node.Y) ^ 2)) ^ 0.5
            if Distance < LowestDistanceToNode then
                LowestDistanceToNode = Distance
                ClosestNode = Id
            end
        end

        --Determine the closest NPC's zone.
        local LowestDistanceToNPC,ClosestZone = math.huge,nil
        for _,NPCLocationData in pairs(NPCLocations) do
            local NPCId = tostring(NPCLocationData.CellX).."_"..tostring(NPCLocationData.CellY)
            local Distance = self.MapGraph:GetShortestDistance(ClosestNode,NPCId)
            if Distance < LowestDistanceToNPC then
                LowestDistanceToNPC = Distance
                ClosestZone = NPCLocationData.Zone
            end
        end

        --Store the closest zone.
        self.CachedResults[ZoneId] = ClosestZone
    end

    --Return the cached entry.
    return self.CachedResults[ZoneId]
end



return Zones