require "vl_quest_utils"
-- require "buildingstructure/vl_buildingstructure_utils"

assert(VLF,  "Stack trace: Missing dependency: VLF - vl_buildingstructure_utils.lua")

VLBS = VLBS or {}
local GetOrCreateSquare = VLF.GetOrCreateSquare --GetOrCreateSquare(x, y, z)
local RemoveObjectOnSquare = VLF.RemoveObjectOnSquare
local AddObjectToSquare = VLF.AddObjectToSquare
local GetObjectOnSquare = VLF.GetObjectOnSquare
local RandomNumberFromXY = VLF.RandomNumberFromXY
local RemoveAllObjectsExceptFloor = VLF.RemoveAllObjectsExceptFloor

local function RemoveObject(sq, obj, isTransmit)
	if not sq or not obj then return end
	sq:RemoveTileObject(obj)
	if isTransmit and isTransmit == true then
		if isServer() then
			sq:transmitRemoveItemFromSquareOnClients(obj)
		else
			sq:transmitRemoveItemFromSquare(obj)
		end
	end
end

local function RemoveObjNotDoorOrWindowOrWall(sq, isTransmit)
    if not sq then return end
	local objs = sq:getObjects()
	local removeTab = {}
	for i = 0, objs:size() - 1 do
		local obj = objs:get(i)
		if obj and not obj:isWall() and not instanceof(obj, "IsoWindow") and not instanceof(obj, "IsoDoor") then
			local prop = obj:getProperties():getPropertyNames()
			if not prop or (not prop:contains("WindowN") and not prop:contains("WindowW")) then
				table.insert(removeTab, obj)
			end
		end
	end
	--for _, v in ipairs(removeTab) do
	for i = #removeTab, 1, -1 do
		if removeTab[i] then
			RemoveObject(sq, removeTab[i], isTransmit)
		end
	end
end

--Thêm nội thất yêu cầu 2+ ô --furniture require 2+ square
function VLBS.AddFurniture(firstSprite, args) --VLBS.AddFurniture("location_community_medical_01_74", {isTransmit = false, x = x, y = y, z = z, isNorth = true, numOfSquare = 2})
	if not firstSprite then return end
	local x, y, z = math.floor(args.x), math.floor(args.y), math.floor(args.z)
	if not x or not y or not z then return end
	
	local isNorth = args.isNorth or false
	local numOfSquare = args.numOfSquare or 2
	local isTransmit = args.isTransmit or false
	
	--Lấy tất cả sprite name của nội thất
	local spriteName = {}
	if numOfSquare == 2 then
		--lấy chuỗi string trước phần _ số cuối
		local firstPart = firstSprite:match("^(.*)_%d+$")
		--lấy chuỗi sau dấu _ cuối
		local lastPart = firstSprite:match("_(%d+)$")
		spriteName[1] = firstSprite
		spriteName[2] = firstPart.."_"..tostring(tonumber(lastPart) + 1)
	end
	
	--Add nội thất theo hướng đã chọn
	if numOfSquare == 2 then
		local sq = GetOrCreateSquare(x, y, z)
		local sq2
		if isNorth == true then
			sq2 = GetOrCreateSquare(x, y - 1, z)
		else
			sq2 = GetOrCreateSquare(x + 1, y, z)
		end
		if sq and sq2 then
			AddObjectToSquare(sq, spriteName[1], {isTransmit = isTransmit, x = -1, y = -1, z = 0, objType = "IsoObject"})
			AddObjectToSquare(sq2, spriteName[2], {isTransmit = isTransmit, x = -1, y = -1, z = 0, objType = "IsoObject"})
		end
	end
end
--local AddFurniture = VLBS.AddFurniture

--Thêm Fences --Hàng rào
function VLBS.AddFence(isTransmit, x, y, z, isNorth, fenceID, corner) --VLBS.AddFence(isTransmit, x, y, z, nil, 1, "top")
	if not x or not y or not z or not fenceID then return end
	isTransmit = isTransmit or false
	isNorth = isNorth or false
	local fenceSpriteTab = {}
	
	--{Left, N, W, Right, Top, Pillar}
	if fenceID == 1 then fenceSpriteTab = {"fencing_01_48", "fencing_01_49", "fencing_01_50", "fencing_01_51", "fencing_01_52", "fencing_01_53"} --hàng rào sắt cao, kiên cố
	elseif fenceID == 2 then fenceSpriteTab = {"fencing_01_56", "fencing_01_57", "fencing_01_58", "fencing_01_59", "fencing_01_60", "fencing_01_61"} --hàng rào lưới sắt cao
	elseif fenceID == 3 then fenceSpriteTab = {"fencing_01_64", "fencing_01_65", "fencing_01_66", "fencing_01_67", "fencing_01_68", "fencing_01_69"} --hàng rào thanh sắt cao, kiên cố
	end
	
	local sq = GetOrCreateSquare(x, y, z)
	if sq then
		local spriteName
		if not corner then
			if isNorth then
				spriteName = fenceSpriteTab[2]
			else
				spriteName = fenceSpriteTab[3]
			end
			AddObjectToSquare(sq, spriteName, {isTransmit = isTransmit, x = -1, y = -1, z = 0, objType = "IsoObject"})
		else
			if corner == "top" then
				AddObjectToSquare(sq, fenceSpriteTab[5], {isTransmit = isTransmit, x = -1, y = -1, z = 0, objType = "IsoObject"})
			elseif corner == "bottom" then
				--Góc dưới đã có sẵn 2 wall khi add theo biên, chỉ thiếu pillar kết nối
				AddObjectToSquare(sq, fenceSpriteTab[6], {isTransmit = isTransmit, x = -1, y = -1, z = 0, objType = "IsoObject"})
			elseif corner == "left" then
				--Góc trái cần fence N + pillar
				AddObjectToSquare(sq, fenceSpriteTab[2], {isTransmit = isTransmit, x = -1, y = -1, z = 0, objType = "IsoObject"})
				AddObjectToSquare(sq, fenceSpriteTab[6], {isTransmit = isTransmit, x = -1, y = -1, z = 0, objType = "IsoObject"})
			elseif corner == "right" then
				--Góc phải cần fence W + pillar
				AddObjectToSquare(sq, fenceSpriteTab[3], {isTransmit = isTransmit, x = -1, y = -1, z = 0, objType = "IsoObject"})
				AddObjectToSquare(sq, fenceSpriteTab[6], {isTransmit = isTransmit, x = -1, y = -1, z = 0, objType = "IsoObject"})
			end
		end
	end
end
local AddFence = VLBS.AddFence

--Thêm Door cho hàng rào --cửa 2 ô
function VLBS.AddFencedoor(args) --VLBS.AddFencedoor({isTransmit = isTransmit, x = x, y = y, z = z, isNorth = true, doorID = 1, isLocked = false})
	local x, y, z = math.floor(args.x), math.floor(args.y), math.floor(args.z)
	if not x or not y or not z then return end
	
	local isNorth = args.isNorth or false
	local doorID = args.doorID or 1
	local isLocked = args.isLocked or false
	local isTransmit = args.isTransmit or false
	
	local doorSpriteTab = {}
	--{E_2, E_1, S_1, S_2} --cửa hướng N, W đang bị lỗi. Cửa sẽ mở ra ngoài khi đúng hướng
	if doorID == 1 then doorSpriteTab = {"fixtures_doors_fences_01_32", "fixtures_doors_fences_01_33", "fixtures_doors_fences_01_34", "fixtures_doors_fences_01_35"} --cửa thanh sắt dày, cao
	elseif doorID == 2 then doorSpriteTab = {"fixtures_doors_fences_01_64", "fixtures_doors_fences_01_65", "fixtures_doors_fences_01_66", "fixtures_doors_fences_01_67"} --cửa lưới sắt
	end
	
	local sq = {}
	sq[1] = GetOrCreateSquare(x, y, z) --sq 1 luôn là ô để phần trục của cửa
	
	if sq[1] then
		if isNorth == true then
			sq[2] = GetOrCreateSquare(x + 1, y, z)
		else
			sq[2] = GetOrCreateSquare(x, y + 1, z)
		end
		if sq[2] then
			local doorSprite = {}
			if isNorth == true then
				doorSprite[1] = doorSpriteTab[3]
				doorSprite[2] = doorSpriteTab[4]
			else
				doorSprite[1] = doorSpriteTab[2]
				doorSprite[2] = doorSpriteTab[1]
			end
			
			for i = 1, 2 do
				local door = AddObjectToSquare(sq[i], doorSprite[i], {isTransmit = isTransmit, x = -1, y = -1, z = 0, objType = "IsoDoor", isNorth = isNorth, isLocked = isLocked})
				if door then
					door:setLocked(isLocked)
					door:setIsLocked(isLocked)
					if isLocked == false then
						door:setLockedByKey(isLocked)
					end
				end
				if isTransmit == true then
					if isClient() then
						door:transmitCompleteItemToServer()
					end
				end
			end
		end
	end
end
local AddFencedoor = VLBS.AddFencedoor
--VLBS.AddFencedoor({isTransmit = false, x = getPlayer():getX(), y = getPlayer():getY(), z = 0, isNorth = false, doorID = 1, isLocked = false})

--Thêm Hàng Rào quanh khu vực xác định
function VLBS.AddFenceAroundArea(args) --VLBS.AddFenceAroundArea({isTransmit = false, x = x, y = y, x2 = x2, y2 = y2, z = z, fenceID = 1, doorID = 1, doorDir = "E", removeObj = true})
	local x, y, x2, y2, z = math.floor(args.x), math.floor(args.y), math.floor(args.x2), math.floor(args.y2), math.floor(args.z)
	if not x or not y or not x2 or not y2 or not z then return end
	
	local isTransmit = args.isTransmit or false
	local fenceID = args.fenceID or 1
	local doorID, doorDir = args.doorID, args.doorDir or "E"
	local removeObj = args.removeObj or false
	
	--Xác định tọa độ cửa --door
	local function GetDoorPos(dir)
		if dir then
			local xD, yD, isNorth		
			if dir == "E" then
				xD = x2
				yD = math.floor(((y + y2) / 2 - 0.5))
				isNorth = false
			elseif dir == "S" then
				xD = math.floor(((x + x2) / 2 - 0.5))
				yD = y2
				isNorth = true
			elseif dir == "W" then
				xD = x
				yD = math.floor(((y + y2) / 2 - 0.5))
				isNorth = false
			elseif dir == "N" then
				xD = math.floor(((x + x2) / 2 - 0.5))
				yD = y
				isNorth = true
			end
			--print("------------", xD, yD, isNorth)
			return xD, yD, isNorth
		end
	end
	
	local xPlus = math.abs(x2 - x)
	local yPlus = math.abs(y2 - y)
	
	for _x = x, x + xPlus do
		for _y = y, y + yPlus do
			--check x, y chỉ nằm trong đường bao
			if (_x == x) or (_x == x2) or (_y == y) or (_y == y2) then
				local sq = GetOrCreateSquare(_x, _y, z)
				if sq then
					--Xóa tất cả object trên square ngoại trừ sàn
					if removeObj then
						if not sq:haveDoor() then
							RemoveAllObjectsExceptFloor(sq, isTransmit)
						end
					end
					
					local noWall = false
					--Thêm cửa hàng rào --door 2 ô
					if doorID then
						
						local xD, yD, isNorth = GetDoorPos(doorDir)
						if xD and yD then
							if isNorth == true then
								if _x == xD and _y == yD then
									AddFencedoor({isTransmit = isTransmit, x = _x, y = _y, z = z, isNorth = isNorth, doorID = doorID})
								end
								if ((_x == xD) or (_x == (xD + 1))) and _y == yD then
									noWall = true
								end
							else
								if _x == xD and _y == yD then
									AddFencedoor({isTransmit = isTransmit, x = _x, y = _y, z = z, isNorth = isNorth, doorID = doorID})
								end
								if (_x == xD) and ((_y == yD) or (_y == (yD + 1))) then
									noWall = true
								end
							end
						end
					end
					
					--Thêm hàng rào bao quanh
					if fenceID and noWall == false then
						if (_x == x) and (_y == y) then --góc top
							AddFence(isTransmit, _x, _y, z, false, fenceID, "top")
						elseif (_x == x2) and (_y == y) then --góc right
							AddFence(isTransmit, _x, _y, z, false, fenceID, "right")
						elseif (_x == x2) and (_y == y2) then --góc bottom
							AddFence(isTransmit, _x, _y, z, false, fenceID, "bottom")
						elseif (_x == x) and (_y == y2) then --góc left
							AddFence(isTransmit, _x, _y, z, true, fenceID, "left")
						elseif (_x == x) or (_x == x2) then --tường bao W và E
							--AddFence({isTransmit = isTransmit, x = _x, y = _y, z = z, isNorth = false, fenceID = fenceID, corner = nil, doorWall = false, windowWall = false})
							AddFence(isTransmit, _x, _y, z, false, fenceID, nil)
						elseif (_y == y) or (_y == y2)  then --tường bao N và S
							AddFence(isTransmit, _x, _y, z, true, fenceID, nil)
						end
					end
					
				end
			end
		end
	end
	print("Shared---AddFenceAroundArea---Added=", x, y, x2, y2, z)
end
--VLBS.AddFenceAroundArea({isTransmit = false, x = getPlayer():getX(), y = getPlayer():getY(), x2 = getPlayer():getX()+6, y2 = getPlayer():getY()+8, z = 0, fenceID = 2, doorID = 2, doorDir = "E", removeObj = true})

--Thêm Wall
function VLBS.AddWall(isTransmit, x, y, z, isNorth, wallID, corner, doorWall, windowWall) --VLBS.AddWall(isTransmit, x, y, z, true, 1, "bottom", false, false)
	if not x or not y or not z or not wallID then return end
	if not isTransmit then isTransmit = false end
	local wallSpriteTab = {}
	
	--{W, N, Top, Bottom, wallDoorW, wallDoorN, wallWindowW, wallWindowN}
	if wallID == 1 then wallSpriteTab = {"location_community_school_01_0", "location_community_school_01_1", "location_community_school_01_2", "location_community_school_01_3", "location_community_school_01_10", "location_community_school_01_11", "location_community_school_01_8", "location_community_school_01_9"} --tường ốp gạch men
	elseif wallID == 2 then wallSpriteTab = {"location_shop_greenes_01_0", "location_shop_greenes_01_1", "location_shop_greenes_01_2", "location_shop_greenes_01_3", "location_shop_greenes_01_10", "location_shop_greenes_01_11", "location_shop_greenes_01_8", "location_shop_greenes_01_9"} --tường gạch ba chỉ vàng đất sét
	elseif wallID == 3 then wallSpriteTab = {"location_community_police_01_0", "location_community_police_01_1", "location_community_police_01_2", "location_community_police_01_3", "location_community_police_01_10", "location_community_police_01_11"} --rào chắn sắt phòng giam
	elseif wallID == 4 then wallSpriteTab = {"location_sewer_01_0", "location_sewer_01_1", "location_sewer_01_2", "location_sewer_01_3", "location_sewer_01_18", "location_sewer_01_19", "location_sewer_01_16", "location_sewer_01_17"} --tường gạch ba chỉ nung
	elseif wallID == 5 then wallSpriteTab = {"industry_trucks_01_4", "industry_trucks_01_5", "industry_trucks_01_6", "industry_trucks_01_7", "industry_trucks_01_14", "industry_trucks_01_15", "industry_trucks_01_12", "industry_trucks_01_13"} --tường kim loại xám
	elseif wallID == 6 then wallSpriteTab = {"walls_logs_96", "walls_logs_97", "walls_logs_98", "walls_logs_99", "walls_logs_106", "walls_logs_107", "walls_logs_104", "walls_logs_105"} --tường đá
	elseif wallID == 7 then wallSpriteTab = {"walls_logs_52", "walls_logs_53", "walls_logs_54", "walls_logs_55", "walls_logs_50", "walls_logs_51", "walls_logs_48", "walls_logs_49"} --tường logs
	elseif wallID == 8 then wallSpriteTab = {"walls_commercial_03_32", "walls_commercial_03_33", "walls_commercial_03_34", "walls_commercial_03_35", "walls_commercial_03_42", "walls_commercial_03_43", "walls_commercial_03_40", "walls_commercial_03_41"} --tường đá cắt lớn, xám
	elseif wallID == 9 then wallSpriteTab = {"walls_exterior_house_02_16", "walls_exterior_house_02_17", "walls_exterior_house_02_18", "walls_exterior_house_02_19", "walls_exterior_house_02_26", "walls_exterior_house_02_27", "walls_exterior_house_02_24", "walls_exterior_house_02_25"} --tường gạch 3 chỉ, bunker
	elseif wallID == 10 then wallSpriteTab = {"industry_trucks_01_4", "industry_trucks_01_5", "industry_trucks_01_6", "industry_trucks_01_7", "industry_trucks_01_14", "industry_trucks_01_15", "industry_trucks_01_12", "industry_trucks_01_13"} --tường sắt tấm xám
	end
	
	local wallSpriteW = wallSpriteTab[1]
	local wallSpriteN = wallSpriteTab[2]
	local topCornerSprite = wallSpriteTab[3]
	local pillarSprite = wallSpriteTab[4]
	local doorWallSpriteW = wallSpriteTab[5]
	local doorWallSpriteN = wallSpriteTab[6]
	local windowWallSpriteW = wallSpriteTab[7]
	local windowWallSpriteN = wallSpriteTab[8]
	
	local sq = GetOrCreateSquare(x, y, z)
	if sq then
		local spriteName
		if not corner then
			if not doorWall and not windowWall then
				--Add tường trên các đường biên
				if isNorth and isNorth == true then
					spriteName = wallSpriteN
				else
					spriteName = wallSpriteW
				end
			elseif doorWall and doorWall == true then
				--Add tường chờ cửa
				if isNorth and isNorth == true then
					spriteName = doorWallSpriteN
				else
					spriteName = doorWallSpriteW
				end
			elseif windowWall and windowWall == true then
				--Add tường chờ cửa sổ
				if isNorth and isNorth == true then
					spriteName = windowWallSpriteN
				else
					spriteName = windowWallSpriteW
				end				
			end
			
			AddObjectToSquare(sq, spriteName, {isTransmit = isTransmit, x = -1, y = -1, z = 0, objType = "IsoObject"})
			--sq:RecalcAllWithNeighbours(true)	
		elseif corner then
			if corner == "top" then
				spriteName = topCornerSprite
				AddObjectToSquare(sq, spriteName, {isTransmit = isTransmit, x = -1, y = -1, z = 0, objType = "IsoObject"})
			elseif corner == "bottom" then
				--Góc dưới đã có sẵn 2 wall khi add theo biên, chỉ thiếu pillar kết nối
				spriteName = pillarSprite
				AddObjectToSquare(sq, spriteName, {isTransmit = isTransmit, x = -1, y = -1, z = 0, objType = "IsoObject"})
			elseif corner == "left" then
				--Góc trái cần wall N 
				AddObjectToSquare(sq, wallSpriteN, {isTransmit = isTransmit, x = -1, y = -1, z = 0, objType = "IsoObject"})
			elseif corner == "right" then
				--Góc phải cần wall W
				AddObjectToSquare(sq, wallSpriteW, {isTransmit = isTransmit, x = -1, y = -1, z = 0, objType = "IsoObject"})
			end
		end
		--sq:RecalcAllWithNeighbours(true)
	end
end
local AddWall = VLBS.AddWall
			
--Thêm cầu thang
function VLBS.AddStair(args) --VLBS.AddStair({isTransmit = false, x = x, y = y, z = z, isNorth = true, stairID = 1, side = "W", floorSprite = "floors_interior_tilesandwood_01_18"})
	local x, y, z = math.floor(args.x), math.floor(args.y), math.floor(args.z)
	if not x or not y or not z then return end
	
	local isNorth, side = args.isNorth or false, args.side or "Mid"
	local floorSprite = args.floorSprite
	local isTransmit = args.isTransmit or false
	
	local stairID = args.stairID or 1
	local stairSpriteTab = {}
	if stairID == 1 then stairSpriteTab = {"fixtures_stairs_01_0", "fixtures_stairs_01_1", "fixtures_stairs_01_2", "fixtures_stairs_01_8", "fixtures_stairs_01_9", "fixtures_stairs_01_10"} --cầu thang sắt xám
	elseif stairID == 2 then stairSpriteTab = {"fixtures_stairs_01_3", "fixtures_stairs_01_4", "fixtures_stairs_01_5", "fixtures_stairs_01_11", "fixtures_stairs_01_12", "fixtures_stairs_01_13"} --cầu thang sắt nâu đỏ
	elseif stairID == 3 then stairSpriteTab = {"fixtures_stairs_01_48", "fixtures_stairs_01_49", "fixtures_stairs_01_50", "fixtures_stairs_01_56", "fixtures_stairs_01_57", "fixtures_stairs_01_58"} --cầu thang bê tông trắng
	elseif stairID == 4 then stairSpriteTab = {"fixtures_stairs_01_32", "fixtures_stairs_01_33", "fixtures_stairs_01_34", "fixtures_stairs_01_40", "fixtures_stairs_01_41", "fixtures_stairs_01_42"} --cầu thang gỗ 
	end
	
	local stairSprite = {}
	if isNorth == false then
		stairSprite[1] = stairSpriteTab[1]
		stairSprite[2] = stairSpriteTab[2]
		stairSprite[3] = stairSpriteTab[3]
	else
		stairSprite[1] = stairSpriteTab[4]
		stairSprite[2] = stairSpriteTab[5]
		stairSprite[3] = stairSpriteTab[6]
	end
	
	--Add Floor + Stair
	for i = 0, 2 do
		local _x, _y
		if isNorth == true then
			_x = x
			_y = y - i
		else
			_x = x - i
			_y = y
		end
		
		local sq = GetOrCreateSquare(_x, _y, z)
		if sq then
			RemoveObjNotDoorOrWindowOrWall(sq, isTransmit)
			--Xóa square phía trên
			local _sq = GetOrCreateSquare(_x, _y, z + 1)
			if _sq then
				RemoveObjNotDoorOrWindowOrWall(_sq, isTransmit)
			end
			--Add Floor
			if floorSprite then
				AddObjectToSquare(nil, floorSprite, {isTransmit = isTransmit, x = _x, y = _y, z = z, objType = "IsoObject"})
			end
			--Add Stair
			local stair = AddObjectToSquare(nil, stairSprite[i+1], {isTransmit = isTransmit, x = _x, y = _y, z = z, objType = "IsoObject"})

			sq:RecalcAllWithNeighbours(true)
		end
	end
	
	--Add thanh chắn phía trên
	local spr = "fixtures_railings_01_"
	if isNorth == true then
		if side == "W" then
			AddObjectToSquare(nil, spr.."49", {isTransmit = isTransmit, x = x, y = y + 1, z = z + 1, objType = "IsoObject"})
			AddObjectToSquare(nil, spr.."50", {isTransmit = isTransmit, x = x + 1, y = y + 1, z = z + 1, objType = "IsoObject"})
			AddObjectToSquare(nil, spr.."48", {isTransmit = isTransmit, x = x + 1, y = y, z = z + 1, objType = "IsoObject"})
			AddObjectToSquare(nil, spr.."48", {isTransmit = isTransmit, x = x + 1, y = y - 1, z = z + 1, objType = "IsoObject"})		
			AddObjectToSquare(nil, spr.."48", {isTransmit = isTransmit, x = x + 1, y = y - 2, z = z + 1, objType = "IsoObject"})
		elseif side == "E" then
			AddObjectToSquare(nil, spr.."49", {isTransmit = isTransmit, x = x, y = y + 1, z = z + 1, objType = "IsoObject"})
			AddObjectToSquare(nil, spr.."48", {isTransmit = isTransmit, x = x, y = y, z = z + 1, objType = "IsoObject"})
			AddObjectToSquare(nil, spr.."48", {isTransmit = isTransmit, x = x, y = y - 1, z = z + 1, objType = "IsoObject"})		
			AddObjectToSquare(nil, spr.."48", {isTransmit = isTransmit, x = x, y = y - 2, z = z + 1, objType = "IsoObject"})
		else
			AddObjectToSquare(nil, spr.."49", {isTransmit = isTransmit, x = x, y = y + 1, z = z + 1, objType = "IsoObject"})
			AddObjectToSquare(nil, spr.."50", {isTransmit = isTransmit, x = x + 1, y = y + 1, z = z + 1, objType = "IsoObject"})
			AddObjectToSquare(nil, spr.."48", {isTransmit = isTransmit, x = x + 1, y = y, z = z + 1, objType = "IsoObject"})
			AddObjectToSquare(nil, spr.."48", {isTransmit = isTransmit, x = x + 1, y = y - 1, z = z + 1, objType = "IsoObject"})		
			AddObjectToSquare(nil, spr.."48", {isTransmit = isTransmit, x = x + 1, y = y - 2, z = z + 1, objType = "IsoObject"})
			AddObjectToSquare(nil, spr.."49", {isTransmit = isTransmit, x = x, y = y + 1, z = z + 1, objType = "IsoObject"})
			AddObjectToSquare(nil, spr.."48", {isTransmit = isTransmit, x = x, y = y, z = z + 1, objType = "IsoObject"})
			AddObjectToSquare(nil, spr.."48", {isTransmit = isTransmit, x = x, y = y - 1, z = z + 1, objType = "IsoObject"})		
			AddObjectToSquare(nil, spr.."48", {isTransmit = isTransmit, x = x, y = y - 2, z = z + 1, objType = "IsoObject"})
		end
	else
		if side == "N" then
			AddObjectToSquare(nil, spr.."48", {isTransmit = isTransmit, x = x + 1, y = y, z = z + 1, objType = "IsoObject"})
			AddObjectToSquare(nil, spr.."50", {isTransmit = isTransmit, x = x + 1, y = y + 1, z = z + 1, objType = "IsoObject"})
			AddObjectToSquare(nil, spr.."49", {isTransmit = isTransmit, x = x, y = y + 1, z = z + 1, objType = "IsoObject"})
			AddObjectToSquare(nil, spr.."49", {isTransmit = isTransmit, x = x - 1, y = y + 1, z = z + 1, objType = "IsoObject"})
			AddObjectToSquare(nil, spr.."49", {isTransmit = isTransmit, x = x - 2, y = y + 1, z = z + 1, objType = "IsoObject"})
		elseif side == "S" then
			AddObjectToSquare(nil, spr.."48", {isTransmit = isTransmit, x = x + 1, y = y, z = z + 1, objType = "IsoObject"})
			AddObjectToSquare(nil, spr.."49", {isTransmit = isTransmit, x = x, y = y, z = z + 1, objType = "IsoObject"})
			AddObjectToSquare(nil, spr.."49", {isTransmit = isTransmit, x = x - 1, y = y, z = z + 1, objType = "IsoObject"})
			AddObjectToSquare(nil, spr.."49", {isTransmit = isTransmit, x = x - 2, y = y, z = z + 1, objType = "IsoObject"})
		else
			AddObjectToSquare(nil, spr.."48", {isTransmit = isTransmit, x = x + 1, y = y, z = z + 1, objType = "IsoObject"})
			AddObjectToSquare(nil, spr.."50", {isTransmit = isTransmit, x = x + 1, y = y + 1, z = z + 1, objType = "IsoObject"})
			AddObjectToSquare(nil, spr.."49", {isTransmit = isTransmit, x = x, y = y + 1, z = z + 1, objType = "IsoObject"})
			AddObjectToSquare(nil, spr.."49", {isTransmit = isTransmit, x = x - 1, y = y + 1, z = z + 1, objType = "IsoObject"})
			AddObjectToSquare(nil, spr.."49", {isTransmit = isTransmit, x = x - 2, y = y + 1, z = z + 1, objType = "IsoObject"})
			AddObjectToSquare(nil, spr.."48", {isTransmit = isTransmit, x = x + 1, y = y, z = z + 1, objType = "IsoObject"})
			AddObjectToSquare(nil, spr.."49", {isTransmit = isTransmit, x = x, y = y, z = z + 1, objType = "IsoObject"})
			AddObjectToSquare(nil, spr.."49", {isTransmit = isTransmit, x = x - 1, y = y, z = z + 1, objType = "IsoObject"})
			AddObjectToSquare(nil, spr.."49", {isTransmit = isTransmit, x = x - 2, y = y, z = z + 1, objType = "IsoObject"})
		end
	end
	
	--Add Floor 2 đầu của Stair
	local square
	if isNorth == true then
		square = GetOrCreateSquare(x, y + 1, z) --square để xuống cầu thang
		GetOrCreateSquare(x, y - 3, z) --square để lên tầng trên --CẦN để đi lên tầng trên không bị vấp
	else
		square = GetOrCreateSquare(x + 1, y, z) --square để xuống cầu thang
		GetOrCreateSquare(x - 3, y, z) --square để lên tầng trên --CẦN để đi lên tầng trên không bị vấp
	end
	if square then
		AddObjectToSquare(square, floorSprite, {isTransmit = isTransmit, x = -1, y = -1, z = 0, objType = "IsoObject"})
	end
	--print("Shared---------AddStair")
end
local AddStair = VLBS.AddStair
--VLBS.AddStair({isTransmit = false, x = getPlayer():getX(), y = getPlayer():getY(), z = getPlayer():getZ(), isNorth = true, stairID = 1, floorSprite = "floors_interior_tilesandwood_01_18"})

--Thêm cửa ra vào --door
function VLBS.AddDoor(args) --VLBS.AddDoor({isTransmit = isTransmit, x = x, y = y, z = z, isNorth = true, doorID = 1, isLocked = false})
	local x, y, z = math.floor(args.x), math.floor(args.y), math.floor(args.z)
	if not x or not y or not z then return end
	
	local isNorth = args.isNorth or false
	local doorID = args.doorID or 1
	local isLocked = args.isLocked or false
	local isTransmit = args.isTransmit or false
	
	local doorSpriteTab = {}
	if doorID == 1 then doorSpriteTab = {"fixtures_doors_01_48", "fixtures_doors_01_49", "fixtures_doors_01_50", "fixtures_doors_01_51", "fixtures_doors_frames_01_4", "fixtures_doors_frames_01_5"} --cửa 2 ô kính, xám
	elseif doorID == 2 then doorSpriteTab = {"fixtures_doors_01_32", "fixtures_doors_01_33", "fixtures_doors_01_34", "fixtures_doors_01_35", "fixtures_doors_frames_01_4", "fixtures_doors_frames_01_5"} --cửa sắt mã khóa, xám
	elseif doorID == 3 then doorSpriteTab = {"fixtures_doors_01_52", "fixtures_doors_01_53", "fixtures_doors_01_54", "fixtures_doors_01_55", "fixtures_doors_frames_01_4", "fixtures_doors_frames_01_5"} --cửa sắt tấm, xám
	end

	local sq = GetOrCreateSquare(x, y, z)
	if sq then
		local doorSprite, doorFrame
		if isNorth == true then
			doorSprite = doorSpriteTab[2]
			doorFrame = doorSpriteTab[6]
		else
			doorSprite = doorSpriteTab[1]
			doorFrame = doorSpriteTab[5]
		end
		AddObjectToSquare(nil, doorFrame, {isTransmit = isTransmit, x = x, y = y, z = z, objType = "IsoThumpable", isNorth = isNorth, isLocked = isLocked})
		local door = AddObjectToSquare(nil, doorSprite, {isTransmit = isTransmit, x = x, y = y, z = z, objType = "IsoDoor", isNorth = isNorth, isLocked = isLocked})
		if door then
			door:setLocked(isLocked)
			door:setIsLocked(isLocked)
			if isLocked == false then
				door:setLockedByKey(isLocked)
			end
		end
		if isTransmit == true then
			if isClient() then
				door:transmitCompleteItemToServer()
			end
		end
		return door
	end
end
local AddDoor = VLBS.AddDoor

--Thêm cửa sổ
function VLBS.AddWindow(args) --VLBS.AddWindow({isTransmit = false, x = x, y = y, z = z, isNorth = true, windowID = 1, isLocked = false})
	local x, y, z = math.floor(args.x), math.floor(args.y), math.floor(args.z)
	if not x or not y or not z then return end
	
	local isNorth = args.isNorth or false
	local windowID = args.windowID or 1
	local isLocked = args.isLocked or false
	local isTransmit = args.isTransmit or false
	
	local windowSpriteTab = {}
	if windowID == 1 then windowSpriteTab = {"fixtures_windows_01_0", "fixtures_windows_01_1"} --cửa sổ 4 ô kính, xám đen
	elseif windowID == 2 then windowSpriteTab = {"fixtures_windows_01_8", "fixtures_windows_01_9"} --cửa sổ nhiều ô kính nhỏ, trắng
	elseif windowID == 3 then windowSpriteTab = {"fixtures_windows_01_16", "fixtures_windows_01_17"} --cửa sổ nhiều ô kính nhỏ, nâu đỏ
	elseif windowID == 4 then windowSpriteTab = {"fixtures_windows_01_24", "fixtures_windows_01_25"} --cửa sổ 2 ô kính, trắng
	elseif windowID == 5 then windowSpriteTab = {"fixtures_windows_01_32", "fixtures_windows_01_33"} --cửa sổ 2 ô kính, xám
	elseif windowID == 6 then windowSpriteTab = {"fixtures_windows_01_56", "fixtures_windows_01_57"} --cửa sổ 2 ô kính dọc, xám đen
	end

	local sq = GetOrCreateSquare(x, y, z)
	if sq then
		local windowSprite
		if isNorth == true then
			windowSprite = windowSpriteTab[2]
		else
			windowSprite = windowSpriteTab[1]
		end
		local window = AddObjectToSquare(nil, windowSprite, {isTransmit = isTransmit, x = x, y = y, z = z, objType = "IsoWindow", isNorth = isNorth, isLocked = isLocked})
		return window
	end
end
local AddWindow = VLBS.AddWindow

--Thêm cửa ra vào lớn --Garadoor
function VLBS.AddGaradoor(args) --VLBS.AddGaradoor({isTransmit = false, x = x, y = y, z = z, isNorth = true, doorID = 1, isLocked = false})
	local x, y, z = math.floor(args.x), math.floor(args.y), math.floor(args.z)
	if not x or not y or not z then return end
	
	local isNorth = args.isNorth or false
	local doorID = args.doorID or 1
	local isLocked = args.isLocked or false
	local isTransmit = args.isTransmit or false
	
	local doorSpriteTab = {}
	if doorID == 1 then doorSpriteTab = {"walls_garage_01_0", "walls_garage_01_1", "walls_garage_01_2", "walls_garage_01_3", "walls_garage_01_4", "walls_garage_01_5"} --cửa gara 3 ô, trắng sữa
	elseif doorID == 2 then doorSpriteTab = {"walls_garage_01_16", "walls_garage_01_17", "walls_garage_01_18", "walls_garage_01_19", "walls_garage_01_20", "walls_garage_01_21"} --cửa gara 3 ô, xanh lá
	elseif doorID == 3 then doorSpriteTab = {"walls_garage_02_32", "walls_garage_02_33", "walls_garage_02_34", "walls_garage_02_35", "walls_garage_02_36", "walls_garage_02_37"} --cửa gara 3 ô, đỏ
	elseif doorID == 4 then doorSpriteTab = {"walls_garage_01_48", "walls_garage_01_49", "walls_garage_01_50", "walls_garage_01_51", "walls_garage_01_52", "walls_garage_01_53"} --cửa gara 3 ô, xám
	end
	
	local sq = {}
	sq[1] = GetOrCreateSquare(x, y, z)

	if sq[1] then
		if isNorth == true then
			sq[2] = GetOrCreateSquare(x + 1, y, z)
			sq[3] = GetOrCreateSquare(x + 2, y, z)
		else
			sq[2] = GetOrCreateSquare(x, y - 1, z)
			sq[3] = GetOrCreateSquare(x, y - 2, z)
		end
		if sq[2] and sq[3] then
			local doorSprite = {}
			if isNorth == true then
				doorSprite[1] = doorSpriteTab[4]
				doorSprite[2] = doorSpriteTab[5]
				doorSprite[3] = doorSpriteTab[6]
			else
				doorSprite[1] = doorSpriteTab[1]
				doorSprite[2] = doorSpriteTab[2]
				doorSprite[3] = doorSpriteTab[3]
			end
			
			for i = 1, 3 do
				local door = AddObjectToSquare(sq[i], doorSprite[i], {isTransmit = isTransmit, x = -1, y = -1, z = 0, objType = "IsoDoor", isNorth = isNorth, isLocked = isLocked})
				if door then
					door:setLocked(isLocked)
					door:setIsLocked(isLocked)
					if isLocked == false then
						door:setLockedByKey(isLocked)
					end
				end
				if isTransmit == true then
					if isClient() then
						door:transmitCompleteItemToServer()
					end
				end
			end
		end
	end
end
local AddGaradoor = VLBS.AddGaradoor
--VLBS.AddGaradoor({isTransmit = false, x = getPlayer():getX(), y = getPlayer():getY(), z = getPlayer():getZ(), isNorth = false, doorID = 3, isLocked = false})

--Thêm đèn gắn tường hoặc đặt trên bàn
function VLBS.AddLight(args) --VLBS.AddLight({isTransmit = isTransmit, x = x, y = y, z = z, attachLoc = "Wall", lightID = 5, dir = "E", isInBuilding = true})
	local x, y, z = math.floor(args.x), math.floor(args.y), math.floor(args.z)
	if not x or not y or not z then return end
	local sq = GetOrCreateSquare(x, y, z)
	if not sq then return end
	local dir, isTransmit = args.dir or "W", args.isTransmit or false
	local lightID = args.lightID or 5
	local attachLoc = args.attachLoc or "Wall" --"Wall", "Table", "Ceiling"
	local isInBuilding = args.isInBuilding or false
	
	local lightSpr_WallAttached = {}
	local lightSpr_Tabletop = {}
	local spr1 = "lighting_indoor_01_"
	local spr2 = "lighting_indoor_02_"

	if dir == "N" then
		lightSpr_WallAttached = {spr1.."0", spr1.."4", spr1.."17", spr1.."21", spr2.."45", spr2.."61", spr2.."73", spr2.."77", spr2.."81"} --9 id
		lightSpr_Tabletop = {spr2.."0", spr2.."4", spr2.."8", spr2.."12", spr2.."16", spr2.."20", spr2.."24", spr2.."28", spr2.."32", spr2.."36", spr2.."40", spr2.."56", spr2.."64", spr1.."8", spr1.."9", spr1.."10", spr1.."11", spr1.."12", spr1.."13"}
	elseif dir == "W" then
		lightSpr_WallAttached = {spr1.."1", spr1.."5", spr1.."16", spr1.."20", spr2.."44", spr2.."60", spr2.."72", spr2.."76", spr2.."80"}
		lightSpr_Tabletop = {spr2.."3", spr2.."7", spr2.."11", spr2.."15", spr2.."17", spr2.."21", spr2.."27", spr2.."29", spr2.."35", spr2.."39", spr2.."43", spr2.."59", spr2.."67", spr1.."48", spr1.."49", spr1.."50", spr1.."51", spr1.."52", spr1.."53"}
	elseif dir == "E" then
		lightSpr_WallAttached = {spr1.."2", spr1.."6", spr1.."18", spr1.."22", spr2.."47", spr2.."63", spr2.."75", spr2.."79", spr2.."83"}
		lightSpr_Tabletop = {spr2.."1", spr2.."5", spr2.."9", spr2.."13", spr2.."18", spr2.."22", spr2.."25", spr2.."30", spr2.."33", spr2.."37", spr2.."41", spr2.."57", spr2.."65", spr1.."32", spr1.."33", spr1.."34", spr1.."35", spr1.."36", spr1.."37"}
	elseif dir == "S" then
		lightSpr_WallAttached = {spr1.."3", spr1.."7", spr1.."19", spr1.."23", spr2.."46", spr2.."62", spr2.."74", spr2.."78", spr2.."82"}
		lightSpr_Tabletop = {spr2.."2", spr2.."6", spr2.."10", spr2.."14", spr2.."19", spr2.."23", spr2.."26", spr2.."31", spr2.."34", spr2.."38", spr2.."42", spr2.."58", spr2.."66", spr1.."40", spr1.."41", spr1.."42", spr1.."43", spr1.."44", spr1.."45"}
	end

	local spriteName
	if attachLoc == "Wall" then
		spriteName = lightSpr_WallAttached[lightID]
	elseif attachLoc == "Table" then
		spriteName = lightSpr_Tabletop[lightID]
	end
	
	local sprite = getSprite(spriteName)
	if not sprite then return end

	local object
	if isInBuilding then
		object = IsoLightSwitch.new(getCell(), sq, sprite, sq:getRoomID())
	else
		object = IsoLightSwitch.new(getCell(), sq, sprite, -1)
	end
	if instanceof(object, "IsoLightSwitch") then
		object:setUseBattery(false)
		object:addLightSourceFromSprite()
		sq:AddSpecialObject(object)
		object:setActive(true)
		--object:switchLight(true)
		--object:toggle()
		--object:turnOn()
		object:setActivated(true)
	end
	--print("Shared-----VLBS.AddLight")
	
	if isTransmit == true then
		if isClient() then
			object:transmitCompleteItemToServer()
		end
	end
end
local AddLight = VLBS.AddLight
--AddLight({isTransmit = false, x = getPlayer():getX() + 2, y = getPlayer():getY(), z = 0, attachLoc = "Ceiling", lightID = 5, dir = "N", isInBuilding = false})

--Thêm đèn trần nhà
function VLBS.AddCeilingLight(isTransmit, x, y, z, lightID, length, isNorth, isInBuilding)
	if not x and not y and not z then return end
	local sq = GetOrCreateSquare(x, y, z)
	if not sq then return end
	
	local function SetLight(_sq, sprite, isTransmit, isInBuilding)
		local object
		if isInBuilding then
			object = IsoLightSwitch.new(getCell(), _sq, sprite, _sq:getRoomID())
		else
			object = IsoLightSwitch.new(getCell(), _sq, sprite, -1)
		end
		if instanceof(object, "IsoLightSwitch") then
			object:setUseBattery(false)
			object:addLightSourceFromSprite()
			_sq:AddSpecialObject(object)
			object:setActive(true)
			object:setActivated(true)
		end
		
		if isTransmit == true then
			if isClient() then
				object:transmitCompleteItemToServer()
			end
		end
	end
	
	local spr3 = "lighting_indoor_03_"
	local lightSpr_Ceiling = {}
	
	if lightID == 1 then
		if isNorth == true then
			lightSpr_Ceiling = {spr3.."8", spr3.."9", spr3.."10"}
		else
			lightSpr_Ceiling = {spr3.."11", spr3.."12", spr3.."13"}
		end
	elseif lightID == 2 then
		if isNorth == true then
			lightSpr_Ceiling = {spr3.."19", spr3.."20", spr3.."21"}
		else
			lightSpr_Ceiling = {spr3.."16", spr3.."17", spr3.."18"}
		end
	end
	
	--Add đèn ô đầu
	local sprite = getSprite(lightSpr_Ceiling[1])
	SetLight(sq, sprite, isTransmit, isInBuilding)
	
	--Add đèn ở giữa --độ dài tùy chỉnh
	if length and length >= 3 then
		if isNorth == true then
			for _y = y - 1, (y - (length - 2)), -1 do
				local sq2 = GetOrCreateSquare(x, _y, z)
				if sq2 then
					local spr = getSprite(lightSpr_Ceiling[3])
					SetLight(sq2, spr, isTransmit, isInBuilding)
				end
			end
		else
			for _x = x + 1, (x + (length - 2)) do
				local sq2 = GetOrCreateSquare(_x, y, z)
				if sq2 then
					local spr = getSprite(lightSpr_Ceiling[3])
					SetLight(sq2, spr, isTransmit, isInBuilding)
				end
			end
		end
	end
	
	--Add đèn ô cuối
	if isNorth == true then
		local sq3 = GetOrCreateSquare(x, y - (length - 1), z)
		if sq3 then
			local _sprite = getSprite(lightSpr_Ceiling[2])
			SetLight(sq3, _sprite, isTransmit, isInBuilding)
		end
	else
		local sq3 = GetOrCreateSquare(x + (length - 1), y, z)
		if sq3 then
			local _sprite = getSprite(lightSpr_Ceiling[2])
			SetLight(sq3, _sprite, isTransmit, isInBuilding)
		end
	end
end

--Thêm loại tường đặc biệt để ngăn đi qua
function VLBS.AddSpecialWall(sq, location, isBorderUndergrd, isTransmit) --VLBS.AddSpecialWall(sq, "N", false, isTransmit)
	if not sq and not location then return end
	
	local wallSpecSprite = {"walls_special_01_0", "walls_special_01_1", "walls_special_01_2"}
	local object
	if isBorderUndergrd and isBorderUndergrd == true then
		if location == "N" then
			object = IsoObject.new(sq, wallSpecSprite[2], "") --(sq, spriteName/tileset sprite ID, name)
		elseif location == "S" then
			object = IsoObject.new(sq, wallSpecSprite[3], "")
		elseif location == "W" then
			object = IsoObject.new(sq, wallSpecSprite[1], "")
		elseif location == "E" then
			object = IsoObject.new(sq, wallSpecSprite[3], "")
		elseif location == "Top" then
			object = IsoObject.new(sq, wallSpecSprite[3], "")
		elseif location == "Right" then
			object = IsoObject.new(sq, wallSpecSprite[1], "")
		elseif location == "Left" then
			object = IsoObject.new(sq, wallSpecSprite[2], "")
		end
	else
		if location == "N" or location == "S" then
			object = IsoObject.new(sq, wallSpecSprite[2], "") --(sq, spriteName/tileset sprite ID, name)
		elseif location == "W" or location == "E" then
			object = IsoObject.new(sq, wallSpecSprite[1], "")
		elseif location == "Top" then
			object = IsoObject.new(sq, wallSpecSprite[3], "")
		elseif location == "Right" then
			object = IsoObject.new(sq, wallSpecSprite[1], "")
		elseif location == "Left" then
			object = IsoObject.new(sq, wallSpecSprite[2], "")
		end
	end
	if not object then return end
	
	object:getProperties():set(IsoFlagType.vegitation) --khiến obj không bị phá bởi sledgehammer
	sq:AddSpecialObject(object)
	if isTransmit and isTransmit == true then
		if isClient() then
			object:transmitCompleteItemToServer()
		end
	end
	return object
end
local AddSpecialWall = VLBS.AddSpecialWall

--Thêm tường đặc biệt xung quanh khu vực
function VLBS.AddSpecialWallsAroundArea(args) --VLBS.AddSpecialWallsAroundArea({isTransmit = false, x = x, y = y, x2 = x2, y2 = y2, z = z})
	local x, y, x2, y2, z = math.floor(args.x), math.floor(args.y), math.floor(args.x2), math.floor(args.y2), math.floor(args.z)
	if not x or not y or not x2 or not y2 or not z then return end
	local isTransmit = args.isTransmit or false
	
	local xPlus = math.abs(x2 - x)
	local yPlus = math.abs(y2 - y)
	
	for _x = x, x + xPlus do
		for _y = y, y + yPlus do
			local sq = GetOrCreateSquare(_x, _y, z)
			if sq then
				if (_x == x) and (_y == y) then --góc top
					AddSpecialWall(sq, "Top", false, isTransmit)
				elseif (_x == x2) and (_y == y) then --góc right
					AddSpecialWall(sq, "Right", false, isTransmit)
				elseif (_x == x) and (_y == y2) then --góc left
					AddSpecialWall(sq, "Left", false, isTransmit)	
				elseif (_x == x2) and (_y == y2) then --góc bottom
					
				elseif _x == x then
					AddSpecialWall(sq, "W", false, isTransmit)
				elseif _x == x2 then
					AddSpecialWall(sq, "E", false, isTransmit)
				elseif _y == y then
					AddSpecialWall(sq, "N", false, isTransmit)
				elseif _y == y2 then
					AddSpecialWall(sq, "S", false, isTransmit)
				end
			end
		end
	end
end


--Thêm lớp phủ (overlay) lên sàn nhà
function VLBS.AttachFloorOverlay(args)  --VLBS.AttachFloorOverlay({isTransmit = isTransmit, x = x, y = y, x2 = x2, y2 = y2, z = z, sideID = 1, midID = 1, rateSqToAdd = 5})
	--x, y, x2, y2 là tọa độ của room
	local x, y, x2, y2, z = math.floor(args.x), math.floor(args.y), math.floor(args.x2), math.floor(args.y2), math.floor(args.z)
	if not x or not y or not x2 or not y2 or not z then return end
	
	local isTransmit = args.isTransmit or false
	local sideID, midID = args.sideID, args.midID
	local rateSqToAdd = args.rateSqToAdd or 1
	
	--Giữa phòng
	local overlayMid, minNum, maxNum = nil, 0, 1
	if midID then
		if midID == 1 then
			overlayMid = "floors_overlay_street_01_" --từ 0 - 31 --63 là max
			maxNum = 63
		elseif midID == 2 then
			overlayMid = "floors_overlay_tiles_01_" -- từ 0 - 71
			maxNum = 71
		elseif midID == 3 then
			overlayMid = "floors_overlay_tiles_02_" -- từ 0 - 7
			maxNum = 7
		elseif midID == 4 then
			overlayMid = "floors_overlay_wood_01_" --từ 0 - 55
			maxNum = 55
		elseif midID == 5 then
			overlayMid = "overlay_blood_floor_01_" --từ 0 - 47
			maxNum = 47
		elseif midID == 6 then
			overlayMid = "overlay_grime_floor_01_" --từ 20 - 23
			minNum = 20			
			maxNum = 23
		end
	end
	--4 mép phòng
	--{W, N, Top, Right, S, E, Bottom, Left}
	local spr = "overlay_grime_floor_01_"
	local overlaySide = {}
	if sideID then
		if sideID == 1 then overlaySide = {spr.."0", spr.."1", spr.."2", spr.."3", spr.."8", spr.."9", spr.."10", spr.."11"}
		elseif sideID == 2 then overlaySide = {spr.."28", spr.."29", spr.."30", spr.."31", spr.."36", spr.."37", spr.."38", spr.."39"}
		elseif sideID == 3 then overlaySide = {spr.."48", spr.."64", spr.."84", spr.."83", spr.."56", spr.."72", spr.."82", spr.."85"}
		end
	end

	local xPlus = math.abs(x2 - x)
	local yPlus = math.abs(y2 - y)
	for _x = x, x + xPlus do
		for _y = y, y + yPlus do
			local sq = GetOrCreateSquare(_x, _y, z)
			if sq then
				local _floor = sq:getFloor()
				if _floor then
					
					--Mép phòng --Side
					if sideID then
						if (_x == x) and (_y == y) then --góc top
							_floor:addAttachedAnimSprite(getSprite(overlaySide[3]))
							_floor:addAttachedAnimSprite(getSprite(overlaySide[1]))
							_floor:addAttachedAnimSprite(getSprite(overlaySide[2]))
						elseif (_x == (x2 - 1)) and (_y == y) then --góc right
							_floor:addAttachedAnimSprite(getSprite(overlaySide[4]))
							_floor:addAttachedAnimSprite(getSprite(overlaySide[2]))
							_floor:addAttachedAnimSprite(getSprite(overlaySide[6]))
						elseif (_x == (x2 - 1)) and (_y == (y2 - 1)) then --góc bottom
							_floor:addAttachedAnimSprite(getSprite(overlaySide[7]))
							_floor:addAttachedAnimSprite(getSprite(overlaySide[5]))
							_floor:addAttachedAnimSprite(getSprite(overlaySide[6]))
						elseif (_x == x) and (_y == (y2 - 1)) then --góc left
							_floor:addAttachedAnimSprite(getSprite(overlaySide[8]))
							_floor:addAttachedAnimSprite(getSprite(overlaySide[5]))
							_floor:addAttachedAnimSprite(getSprite(overlaySide[1])) 
						elseif (_x == x) and (_y >= y) and (_y <= (y2 - 1)) then --tường bao W
							_floor:addAttachedAnimSprite(getSprite(overlaySide[1])) 
						elseif (_y == y) and (_x >= x) and (_x <= (x2 - 1)) then --tường bao N
							_floor:addAttachedAnimSprite(getSprite(overlaySide[2]))
						elseif (_y == (y2 - 1)) and (_x >= x) and (_x <= (x2 - 1))  then --tường bao S
							_floor:addAttachedAnimSprite(getSprite(overlaySide[5]))
						elseif (_x == (x2 - 1)) and (_y >= y) and (_y <= (y2 - 1)) then --tường bao E
							_floor:addAttachedAnimSprite(getSprite(overlaySide[6]))
						end
					end
					
					--Giữa phòng --mid
					if midID then
						if (_x >= (x + 1)) and (_x <= (x2 - 2)) and (_y >= (y + 1)) and (_y <= (y2 - 2)) then
							local idx = RandomNumberFromXY(_x, _y, minNum, maxNum)
							local rate = RandomNumberFromXY(_x, _y, 0, 100)
							
							if (rate % rateSqToAdd) == 0 then
								--print("------------= ", idx, rateSqToAdd)
								_floor:addAttachedAnimSprite(getSprite(overlayMid..tostring(idx)))
							end
						end
					end
					
					--Transmit
					if isTransmit == true then
						if isClient() then
							_floor:transmitCompleteItemToServer()
						end
					end
				
				end
			end
		end
	end
end
local AttachFloorOverlay = VLBS.AttachFloorOverlay
--VLBS.AttachFloorOverlay({isTransmit = false, x = getPlayer():getX(), y = getPlayer():getY(), x2 = getPlayer():getX()+5, y2 = getPlayer():getY()+7, z = 0, sideID = 2, midID = 6, rateSqToAdd = 5})

--Thêm lớp phủ (overlay) lên tường
function VLBS.AttachWallOverlay(args)  --VLBS.AttachWallOverlay({isTransmit = isTransmit, x = x, y = y, x2 = x2, y2 = y2, z = z, overlayID = 1, isBlood = false})
	--x, y, x2, y2 là tọa độ của room
	local x, y, x2, y2, z = math.floor(args.x), math.floor(args.y), math.floor(args.x2), math.floor(args.y2), math.floor(args.z)
	if not x or not y or not x2 or not y2 or not z then return end
	
	local isTransmit = args.isTransmit or false
	local overlayID, isBlood = args.overlayID or 1, args.isBlood or false
	
	--{lowerW, lowerN, lowerTop-3, lowerBottom, upperW, upperN-6, upperTop, empty, windowLowerW-9, windowLowerN, doorW, doorN-12, windowMidW, windowMidN, windowUpperW-15, windowUpperN}
	local spr = "overlay_grime_wall_01_"
	local overlaySprite = {}
	if overlayID == 1 then overlaySprite = {spr.."0", spr.."1", spr.."2", spr.."3", spr.."4", spr.."5", spr.."6", spr.."7", spr.."8", spr.."9", spr.."10", spr.."11", spr.."12", spr.."13", spr.."14", spr.."15"}
	elseif overlayID == 2 then overlaySprite = {spr.."16", spr.."17", spr.."18", spr.."19", spr.."20", spr.."21", spr.."22", spr.."23", spr.."24", spr.."25", spr.."26", spr.."27", spr.."28", spr.."29", spr.."30", spr.."31"}
	end
	--print("Shared-----AttachWallOverlay")
	local xPlus = math.abs(x2 - x)
	local yPlus = math.abs(y2 - y)
	for _x = x, x + xPlus do
		for _y = y, y + yPlus do
			local sq = GetOrCreateSquare(_x, _y, z)
			if sq and not sq:getIsoDoor() then
				local wall = sq:getWall()
				if wall then
					--lấy số ngẫu nhiên dựa theo tọa độ x và y. 
					local num = RandomNumberFromXY(_x, _y, 0, 1487) --dùng để tính tỉ lệ cho lower
					local num2 = RandomNumberFromXY(_x, _y, 0, 373) --dùng để tính tỉ lệ cho upper
					
					--tỉ lệ để được add 	--d = 1 -> 100% 	--d = 5 -> 1/5 == 20%
					local function TrueNum(num, d)
						return (num % d) == 0
					end
					
					--thêm overlay lên tường
					if (_x == x) and (_y == y) then --góc top
						wall:addAttachedAnimSprite(getSprite(overlaySprite[3]))
						wall:addAttachedAnimSprite(getSprite(overlaySprite[7]))
					elseif (_x == (x2 - 1)) and (_y == (y2 - 1)) then --góc bottom
						wall:addAttachedAnimSprite(getSprite(overlaySprite[4]))
					elseif (_x == x) and (_y >= y + 1) and (_y <= (y2 - 1)) then --tường bao W
						--lower
						if TrueNum(num, 1) then
							if sq:getWindow() then
								wall:addAttachedAnimSprite(getSprite(overlaySprite[9]))
							else
								wall:addAttachedAnimSprite(getSprite(overlaySprite[1]))
							end
						end
						--upper
						if TrueNum(num2, 5) then
							if sq:getWindow() then
								wall:addAttachedAnimSprite(getSprite(overlaySprite[15]))
							else
								wall:addAttachedAnimSprite(getSprite(overlaySprite[5]))
							end
						end
					elseif (_y == y) and (_x >= x + 1) and (_x <= (x2 - 1)) then --tường bao N
						--lower
						if TrueNum(num, 1) then
							if sq:getWindow() then
								wall:addAttachedAnimSprite(getSprite(overlaySprite[10]))
							else
								wall:addAttachedAnimSprite(getSprite(overlaySprite[2]))
							end
						end
						--upper
						if TrueNum(num2, 5) then
							if sq:getWindow() then
								wall:addAttachedAnimSprite(getSprite(overlaySprite[16]))
							else
								wall:addAttachedAnimSprite(getSprite(overlaySprite[6]))
							end
							
						end
					elseif (_y == y2) and (_x >= x) and (_x <= (x2 - 1))  then --tường bao S
						--lower
						if TrueNum(num, 1) then
							if sq:getWindow() then
								wall:addAttachedAnimSprite(getSprite(overlaySprite[10]))
							else
								wall:addAttachedAnimSprite(getSprite(overlaySprite[2]))
							end
						end
						--upper
						if TrueNum(num2, 3) then
							if sq:getWindow() then
								wall:addAttachedAnimSprite(getSprite(overlaySprite[16]))
							else
								wall:addAttachedAnimSprite(getSprite(overlaySprite[6]))
							end
						end
					elseif (_x == x2) and (_y >= y) and (_y <= (y2 - 1)) then --tường bao E
						--lower
						if TrueNum(num, 1) then
							if sq:getWindow() then
								wall:addAttachedAnimSprite(getSprite(overlaySprite[9]))
							else
								wall:addAttachedAnimSprite(getSprite(overlaySprite[1]))
							end
						end
						--upper
						if TrueNum(num, 3) then
							if sq:getWindow() then
								wall:addAttachedAnimSprite(getSprite(overlaySprite[15]))
							else
								wall:addAttachedAnimSprite(getSprite(overlaySprite[5]))
							end
							
						end
					end
					
					--Transmit
					if isTransmit == true then
						if isClient() then
							wall:transmitCompleteItemToServer()
						end
					end
				end
			end
		end
	end
end
local AttachWallOverlay = VLBS.AttachWallOverlay
--VLBS.AttachWallOverlay({isTransmit = false, x = getPlayer():getX(), y = getPlayer():getY(), x2 = getPlayer():getX()+5, y2 = getPlayer():getY()+7, z = 0, overlayID = 2, isBlood = false})

--Thêm khung nhà/phòng đơn giản
function VLBS.AddEmptyRoom(args) --VLBS.CreateEmptyRoom({isTransmit = false, x = x, y = y, x2 = x2, y2 = y2, z = z, wallID = 1, doorID = 1, doorDir = "E", isGaradoor = true, windowID = 1, windowDir = "W", window2ID = 1, window2Dir = "N", window3ID = 1, window3Dir = "S", floorSprite = "floors_interior_tilesandwood_01_12", roofSprite = "floors_interior_tilesandwood_01_12", removeObj = true, borderUndergrd = true, attachWall = true, attachFloor = true, addLights = true})
	local x, y, x2, y2, z = math.floor(args.x), math.floor(args.y), math.floor(args.x2), math.floor(args.y2), math.floor(args.z)
	if not x or not y or not x2 or not y2 or not z then return end
	
	local floorSprite, roofSprite = args.floorSprite, args.roofSprite
	local isTransmit = args.isTransmit or false
	local wallID = args.wallID
	local doorID, doorDir, isGaradoor = args.doorID, args.doorDir or "E", args.isGaradoor or false
	local windowID, windowDir = args.windowID, args.windowDir or "N"
	local window2ID, window2Dir = args.window2ID, args.window2Dir or "S"
	local window3ID, window3Dir = args.window3ID, args.window3Dir or "W"
	local removeObj = args.removeObj or false
	local borderUndergrd = args.borderUndergrd or false
	local attachWall, attachFloor, addLights = args.attachWall or false, args.attachFloor or false, args.addLights or false
	
	--Xác định tọa độ cửa --door
	local function GetDoorPos(dir)
		if dir then
			local xD, yD, isNorth		
			if dir == "E" then
				xD = x2
				if isGaradoor == true then
					yD = math.floor(((y + y2) / 2) + 1)
				else
					yD = math.floor(((y + y2) / 2))
				end
				isNorth = false
			elseif dir == "S" then
				if isGaradoor == true then
					xD = math.floor(((x + x2) / 2) - 1)
				else
					xD = math.floor(((x + x2) / 2))
				end
				yD = y2
				isNorth = true
			elseif dir == "W" then
				xD = x
				if isGaradoor == true then
					yD = math.floor(((y + y2) / 2) + 1)
				else
					yD = math.floor(((y + y2) / 2))
				end
				isNorth = false
			elseif dir == "N" then
				if isGaradoor == true then
					xD = math.floor(((x + x2) / 2) - 1)
				else
					xD = math.floor(((x + x2) / 2))
				end
				yD = y
				isNorth = true
			end
			return xD, yD, isNorth
		end
	end

	
	local xPlus = math.abs(x2 - x)
	local yPlus = math.abs(y2 - y)
	
	for _x = x, x + xPlus do
		for _y = y, y + yPlus do
			--Tạo square + floor của room
			local sq = GetOrCreateSquare(_x, _y, z)
			if sq then
				--Thêm sàn
				if floorSprite then
					if not (_x == x2) and not (_y == y2) then --không thêm sàn ở 2 đường viền dưới
						if removeObj == true then
							RemoveObjectOnSquare(sq, "", isTransmit, true)							
						end
						AddObjectToSquare(sq, floorSprite, {isTransmit = isTransmit, x = -1, y = -1, z = 0, objType = "IsoObject"})
					end
				end
				
				local noWall = false
				if doorID then
					--Thêm cửa --door
					local xD, yD, isNorth = GetDoorPos(doorDir)
					if xD and yD then
						--print("Shared--------Door ", xD, yD)
						--Nếu là Garadoor
						if isGaradoor == true then
							if isNorth == true then
								if _x == xD and _y == yD then
									AddGaradoor({isTransmit = isTransmit, x = _x, y = _y, z = z, isNorth = isNorth, doorID = doorID})
								end
								if ((_x == xD) or (_x == (xD + 1)) or (_x == (xD + 2))) and _y == yD then
									noWall = true
								end
							else
								if _x == xD and _y == yD then
									AddGaradoor({isTransmit = isTransmit, x = _x, y = _y, z = z, isNorth = isNorth, doorID = doorID})
								end
								if (_x == xD) and ((_y == yD) or (_y == (yD - 1)) or (_y == (yD - 2))) then
									noWall = true
								end
							end
						else
							--door thường
							if _x == xD and _y == yD then					
								--Thêm doorWall
								AddWall(isTransmit, _x, _y, z, isNorth, wallID, nil, true, false)
								--Thêm cửa
								local door = AddDoor({isTransmit = isTransmit, x = _x, y = _y, z = z, isNorth = isNorth, doorID = doorID})
								noWall = true --để không thêm tường vị trí của cửa
							end
						end
					end
				end
				
				if windowID or window2ID or window3ID then
					--Thêm cửa sổ --window
					local function AddAWindown(dir)
						local xW, yW, isNorth = GetDoorPos(dir)
						if xW and yW then
							if _x == xW and _y == yW then					
								--Thêm windowWall
								AddWall(isTransmit, _x, _y, z, isNorth, wallID, nil, nil, true)
								--Thêm cửa sổ
								local window = AddWindow({isTransmit = isTransmit, x = _x, y = _y, z = z, isNorth = isNorth, windowID = windowID})
								noWall = true --để không thêm tường vị trí của cửa sổ
							end
						end
					end
					
					if windowID and windowDir ~= doorDir then --vị trí cửa sổ khác cửa ra vào
						AddAWindown(windowDir)
					end
					if window2ID and window2Dir ~= doorDir then
						AddAWindown(window2Dir)
					end
					if window3ID and window3Dir ~= doorDir then
						AddAWindown(window3Dir)
					end
				end
				
				--Thêm tường bao quanh phòng
				if wallID and noWall == false then
					if (_x == x) and (_y == y) then --góc top
						AddWall(isTransmit, _x, _y, z, false, wallID, "top", false, false)
						if borderUndergrd == true then AddSpecialWall(sq, "Top", true, isTransmit) end
					elseif (_x == x2) and (_y == y) then --góc right
						AddWall(isTransmit, _x, _y, z, false, wallID, "right", false, false)
						if borderUndergrd == true then AddSpecialWall(sq, "Right", true, isTransmit) end
					elseif (_x == x2) and (_y == y2) then --góc bottom
						AddWall(isTransmit, _x, _y, z, false, wallID, "bottom", false, false)
					elseif (_x == x) and (_y == y2) then --góc left
						AddWall(isTransmit, _x, _y, z, true, wallID, "left", false, false)
						if borderUndergrd == true then AddSpecialWall(sq, "Left", true, isTransmit) end
					elseif (_x == x) or (_x == x2) then --tường bao W và E
						AddWall(isTransmit, _x, _y, z, false, wallID, nil, false, false)
						if borderUndergrd == true then
							if (_x == x) then -- W
								AddSpecialWall(sq, "W", true, isTransmit)
							elseif (_x == x2) then -- E
								AddSpecialWall(sq, "E", true, isTransmit)
							end
						end
					elseif (_y == y) or (_y == y2)  then --tường bao N và S
						AddWall(isTransmit, _x, _y, z, true, wallID, nil, false, false)
						if borderUndergrd == true then
							if (_y == y) then -- N
								AddSpecialWall(sq, "N", true, isTransmit)
							elseif (_y == y2) then -- S
								AddSpecialWall(sq, "S", true, isTransmit)
							end

						end
					end
				end
				
				--Thêm mái nhà
				if roofSprite then
					if not (_x == x2) and not (_y == y2) then
						AddObjectToSquare(nil, roofSprite, {isTransmit = isTransmit, x = _x, y = _y, z = z + 1, objType = "IsoObject"})
					end
				end
				--sq:RecalcProperties()
				--sq:RecalcAllWithNeighbours(true)
			end
		end
	end
	
	--Thêm đèn gắn tường
	if addLights then
		if not (doorDir == "W") then
			AddLight({isTransmit = isTransmit, x = x, y = math.floor((y + y2) / 2), z = z, attachLoc = "Wall", lightID = 5, dir = "W", isInBuilding = false})
		end
		if not (doorDir == "N") then
			AddLight({isTransmit = isTransmit, x = math.floor((x + x2) / 2), y = y, z = z, attachLoc = "Wall", lightID = 5, dir = "N", isInBuilding = false})
		end
		if not (doorDir == "E") then
			AddLight({isTransmit = isTransmit, x = x2 - 1, y = math.floor((y + y2) / 2), z = z, attachLoc = "Wall", lightID = 5, dir = "E", isInBuilding = false})
		end
		if not (doorDir == "S") then
			AddLight({isTransmit = isTransmit, x = math.floor((x + x2) / 2), y = y2 - 1, z = z, attachLoc = "Wall", lightID = 5, dir = "S", isInBuilding = false})
		end
	end
	
	--Thêm bụi bẩn trên tường
	if attachWall == true then
		AttachWallOverlay({isTransmit = isTransmit, x = x, y = y, x2 = x2, y2 = y2, z = z, overlayID = 2, isBlood = false})
	end
	--Thêm bụi bẩn trên sàn
	if attachFloor == true then
		AttachFloorOverlay({isTransmit = isTransmit, x = x, y = y, x2 = x2, y2 = y2, z = z, sideID = 2, midID = 6, rateSqToAdd = 5})
	end
	print("Shared---AddEmptyRoom---Added=", x, y, x2, y2, z)
end
--VLBS.AddEmptyRoom({isTransmit = false, x = getPlayer():getX(), y = getPlayer():getY(), x2 = getPlayer():getX()+5, y2 = getPlayer():getY()+7, z = 0, wallID = 9, doorID = 1, doorDir = "E", isGaradoor = true, windowID = nil, windowDir = "W", window2ID = nil, window2Dir = "N", window3ID = nil, window3Dir = "S", floorSprite = "floors_exterior_street_01_16", roofSprite = "blends_natural_01_32", removeObj = true, borderUndergrd = true, attachWall = true, attachFloor = true, addLights = true})

--Thêm viền bunker bao quanh nhà trên hầm trú ẩn
function VLBS.AddRimBunker(args) --VLBS.AddRimBunker({isTransmit = false, x = x, y = y, x2 = x2, y2 = y2, z = z, floorSprite = "blends_street_01_102"})
	--Nhà trong Bunker kích thước tối thiểu 3x5
	--x, y, x2, y2 đều sử dụng tọa độ của nhà trong bunker. +3 ô các hướng. Cố định không thay đổi
	--Bunker chỉ có 1 hướng duy nhất.
	local x, y, x2, y2, z = math.floor(args.x), math.floor(args.y), math.floor(args.x2), math.floor(args.y2), math.floor(args.z)
	if not x or not y or not x2 or not y2 or not z then return end
	local xB, yB, xB2, yB2 = x - 3, y -3, x2 + 3, y2 + 3
	local floorSprite = args.floorSprite
	local isTransmit = args.isTransmit or false
	local yD = math.floor(((yB + yB2) / 2)) --tọa độ giữa y và y2
	
	--Kiểm tra tọa độ có nằm trong khu vực trước cửa Bunker không
	local function IsSquareFrontDoor(_x, _y)
		if _x >= (xB2 - 3) and (_y >= (yD - 2)) and (_y <= (yD + 2)) then
			return true
		end
		return false
	end
	
	--Kiểm tra square thuộc khu vực của RimBunker, nằm ngoài phòng bên trong
	local function IsSquareOfRimBunker(_x, _y, x, y, x2, y2)
		if not (((_x >= x) and (_x <= x2 - 1)) and ((_y >= y) and (_y <= y2 - 1))) then
			if (_x <= xB2 - 1) and (_y <= yB2 - 1) then
				return true
			end
		end
		return false
	end
	
	local wallSpecSprite = {"walls_special_01_0", "walls_special_01_1", "walls_special_01_2"}
	local bunkerSprite = "industry_bunker_01_"
	local wall = {"walls_exterior_roofs_06_0", "walls_exterior_roofs_06_1", "walls_exterior_roofs_06_2", "walls_exterior_roofs_06_3", "walls_exterior_roofs_06_4", "walls_exterior_roofs_06_5"}
	--Viền bao quanh
	local xPlus = math.abs(xB2 - xB)
	local yPlus = math.abs(yB2 - yB)
	for _x = xB, xB + xPlus do
		for _y = yB, yB + yPlus do
			local sq = GetOrCreateSquare(_x, _y, z)
			if sq then
				--Xóa object cũ, loại trừ wall, door
				if IsSquareOfRimBunker(_x, _y, x, y, x2, y2) then
						RemoveObjNotDoorOrWindowOrWall(sq, isTransmit)
					if floorSprite then
						AddObjectToSquare(sq, floorSprite, {isTransmit = isTransmit, x = -1, y = -1, z = 0, objType = "IsoObject"})
					end
				end
				
				--Thêm đường viền đặc biệt ngăn đi qua
				if (_x == xB) and (_y == yB) then --góc top
					AddSpecialWall(sq, "Top", false, isTransmit)
				elseif (_x == xB2) and (_y == yB) then --góc right
					AddSpecialWall(sq, "Right", false, isTransmit)
				elseif (_x == xB2) and (_y == yB2) then --góc bottom
			
				elseif (_x == xB) and (_y == yB2) then --góc left
					AddSpecialWall(sq, "Left", false, isTransmit)
				elseif (_x == xB) or (_x == xB2) then --tường bao W và E
					if IsSquareFrontDoor(_x, _y) ~= true then
						AddSpecialWall(sq, "W", false, isTransmit)
					end
				elseif (_y == yB) or (_y == yB2)  then --tường bao N và S
					AddSpecialWall(sq, "N", false, isTransmit)
				elseif (_y == (yD - 2)) and (_x >= (xB2 - 3)) and (_x <= (xB2 - 1)) then --mép phải cửa ra vào
					AddSpecialWall(sq, "N", false, isTransmit)
					
					--Add tường bao chéo bên phải trước cửa
					if _x == (xB2 - 3) then
						AddObjectToSquare(nil, wall[4], {isTransmit = isTransmit, x = _x, y = _y, z = z, objType = "IsoObject"})
						--add thang sắt leo thẳng đứng
						AddObjectToSquare(nil, "industry_railroad_05_20", {isTransmit = isTransmit, x = _x, y = _y, z = z, objType = "IsoObject"})
					elseif _x == (xB2 - 2) then
						AddObjectToSquare(nil, wall[5], {isTransmit = isTransmit, x = _x, y = _y, z = z, objType = "IsoObject"})
					elseif _x == (xB2 - 1) then
						AddObjectToSquare(nil, wall[6], {isTransmit = isTransmit, x = _x, y = _y, z = z, objType = "IsoObject"})
					end
				elseif (_y == (yD + 3)) and (_x >= (xB2 - 3)) and (_x <= (xB2 - 1)) then --mép trái cửa ra vào
					AddSpecialWall(sq, "N", false, isTransmit)
				end
				
				--Thêm bunk Wall phía E
				if IsSquareFrontDoor(_x, _y) ~= true then
					if _x == (xB2 - 1) then
						if _y == yB then --góc phải
							AddObjectToSquare(nil, bunkerSprite.."21", {isTransmit = isTransmit, x = _x, y = _y, z = z, objType = "IsoObject"})
						elseif _y == yB2 - 1 then --góc dưới
							AddObjectToSquare(nil, bunkerSprite.."8", {isTransmit = isTransmit, x = _x, y = _y, z = z, objType = "IsoObject"})
						elseif _y >= (yB + 1) and _y <= (yB2 - 2) then --viền E
							AddObjectToSquare(nil, bunkerSprite.."5", {isTransmit = isTransmit, x = _x, y = _y, z = z, objType = "IsoObject"})	
						end
					elseif _x == (xB2 - 2) then
						if _y == yB + 1 then --góc phải
							AddObjectToSquare(nil, bunkerSprite.."20", {isTransmit = isTransmit, x = _x, y = _y, z = z, objType = "IsoObject"})
						elseif _y == yB2 - 2 then --góc dưới
							AddObjectToSquare(nil, bunkerSprite.."9", {isTransmit = isTransmit, x = _x, y = _y, z = z, objType = "IsoObject"})
						elseif _y >= (yB + 2) and _y <= (yB2 - 3) then --viền E
							AddObjectToSquare(nil, bunkerSprite.."4", {isTransmit = isTransmit, x = _x, y = _y, z = z, objType = "IsoObject"})
						end	
					elseif _x == (xB2 - 3) then
						if _y == yB + 2 then --góc phải
							AddObjectToSquare(nil, bunkerSprite.."19", {isTransmit = isTransmit, x = _x, y = _y, z = z, objType = "IsoObject"})
						elseif _y == yB2 - 3 then --góc dưới
							AddObjectToSquare(nil, bunkerSprite.."10", {isTransmit = isTransmit, x = _x, y = _y, z = z, objType = "IsoObject"})
						elseif _y >= (yB + 3) and _y <= (yB2 - 4) then --viền E
							AddObjectToSquare(nil, bunkerSprite.."3", {isTransmit = isTransmit, x = _x, y = _y, z = z, objType = "IsoObject"})
						end	
					end
				end
				
				--Thêm bunk Wall phía S
				if _y == (yB2 - 1) then
					if _x == (xB) then --góc trái
						AddObjectToSquare(nil, bunkerSprite.."16", {isTransmit = isTransmit, x = _x, y = _y, z = z, objType = "IsoObject"})
					elseif (_x >= (xB + 1)) and (_x <= (xB2 - 2)) then --viền S
						AddObjectToSquare(nil, bunkerSprite.."0", {isTransmit = isTransmit, x = _x, y = _y, z = z, objType = "IsoObject"})
					end
				elseif _y == (yB2 - 2) then
					if _x == (xB + 1) then --góc trái
						AddObjectToSquare(nil, bunkerSprite.."17", {isTransmit = isTransmit, x = _x, y = _y, z = z, objType = "IsoObject"})
					elseif (_x >= (xB + 2)) and (_x <= (xB2 - 3)) then --viền S
						AddObjectToSquare(nil, bunkerSprite.."1", {isTransmit = isTransmit, x = _x, y = _y, z = z, objType = "IsoObject"})
					end
				elseif _y == (yB2 - 3) then
					if _x == (xB + 2) then --góc trái
						AddObjectToSquare(nil, bunkerSprite.."18", {isTransmit = isTransmit, x = _x, y = _y, z = z, objType = "IsoObject"})
					elseif (_x >= (xB + 3)) and (_x <= (xB2 - 4)) then --viền S
						AddObjectToSquare(nil, bunkerSprite.."2", {isTransmit = isTransmit, x = _x, y = _y, z = z, objType = "IsoObject"})
					end
				end
				
			end
		end
	end
	VLBS.AttachFloorOverlay({isTransmit = isTransmit, x = (xB2 - 3), y = (yD - 2), x2 = (xB2), y2 = (yD + 3), z = z, sideID = 2, midID = 1, rateSqToAdd = 2})
	print("Shared---AddRimBunker---Added=", x, y, x2, y2, z)
end
--VLBS.AddRimBunker({isTransmit = false, x = getPlayer():getX(), y = getPlayer():getY(), x2 = getPlayer():getX()+5, y2 = getPlayer():getY()+7, z = 0, floorSprite = "blends_street_01_16"})

--CLIENT ONLY
--Kích hoạt để tường đặc biệt không thể bị phá mỗi lần login
local function OnGameStart_SetSpecialWall()
	local sq = getPlayer():getCurrentSquare()
	local obj = GetObjectOnSquare(sq, "walls_special_01_0", nil, nil)					
	if not obj then
		obj = AddSpecialWall(sq, "W", false, false)
	end
	sq:RemoveTileObject(obj)
end
Events.OnGameStart.Add(OnGameStart_SetSpecialWall)