-- MinecartTracks -- by Revolucas local PLUGIN_NAME = "MinecartTracks" local PLUGIN_VERSION = 1 --BlockMetas for Minecart tracks which are compatible to visually join local CompatibleMetas = { [0] = {0,4,5,6,7,8,9}, [1] = {1,2,3,6,7,8,9}, [2] = {1,2,3,7,8}, [3] = {1,2,3,6,9}, [4] = {0,4,5,6,7}, [5] = {0,4,5,8,9}, [6] = {0,1,2,3,4,5,6,7,8,9}, [7] = {0,1,2,3,4,5,6,7,8,9}, [8] = {0,1,2,3,4,5,6,7,8,9}, [9] = {0,1,2,3,4,5,6,7,8,9}} --Positions to check for tracks according to block meta local CompatibleDirections = { [0] = { {0,0,1} ,{0,0,-1},{0,1,1} ,{0,-1,1} ,{0,1,-1},{0,-1,-1}}, [1] = { {1,0,0} ,{-1,0,0},{1,1,0} ,{1,-1,0} ,{-1,1,0},{-1,-1,0}}, [2] = { {-1,0,0},{-1,1,0},{1,1,0} ,{-1,-1,0} }, [3] = { {1,0,0} ,{1,1,0} ,{-1,1,0},{-1,-1,0} }, [4] = { {0,0,1} ,{0,-1,1},{0,1,-1},{0,1,1} }, [5] = { {0,0,-1},{0,-1,-1},{0,1,1},{0,1,-1} }, [6] = { {1,0,0} ,{0,0,1} ,{1,1,0} ,{1,-1,0} ,{0,1,1},{0,-1,1} }, [7] = { {-1,0,0},{0,0,1} ,{-1,1,0},{-1,-1,0},{0,1,1},{0,-1,1}}, [8] = { {-1,0,0},{0,0,-1},{-1,1,0},{-1,-1,0},{0,1,-1},{0,-1,-1}}, [9] = { {1,0,0} ,{1,1,0} ,{1,-1,0},{0,0,-1} ,{0,1,-1},{0,-1,-1}}} --Definitions of behavior for Relative Positions to placed track -- [-1,0,0] -- [0,0,1][0,0,0 ][0,0,-1] -- [1,0,0 ] local DefineTrackBehavior = { ["1,0,0"] = { ["0,0,1"] = {9,1},["0,0,-1"] = {6,1},["-1,0,0"] = {1,1}, ["1,0,0"] = {1,1}, ["0,1,1"] = {9,1},["0,1,-1"] = {6,1},["-1,1,0"] = {1,1}, ["1,1,0"] = {1,1}, ["0,-1,1"] = {9,1},["0,-1,-1"]= {6,1},["-1,-1,0"]= {1,1}, ["1,-1,0"]= {3,1}}, ["1,1,0"] = { ["0,0,1"] = {9,2},["0,0,-1"] = {6,2},["-1,0,0"] = {1,1}, ["1,0,0"] = {2,1}, ["0,1,1"] = {9,2},["0,1,-1"] = {6,2},["-1,1,0"] = {2,1}, ["1,1,0"] = {2,1}, ["0,-1,1"] = {9,2},["0,-1,-1"]= {6,2},["-1,-1,0"]= {2,1}, ["1,-1,0"]= {2,1}}, ["1,-1,0"] = { ["0,0,1"] = {9,3},["0,0,-1"] = {6,3},["-1,0,0"] = {1,3}, ["1,0,0"] = {1,3}, ["0,1,1"] = {9,3},["0,1,-1"] = {6,3},["-1,1,0"] = {1,3}, ["1,1,0"] = {1,3}, ["0,-1,1"] = {9,3},["0,-1,-1"]= {6,3},["-1,-1,0"]= {1,3}, ["1,-1,0"]= {3,3}}, ["0,0,1"] = { ["1,0,0"] = {7,0},["-1,0,0"] = {6,0},["0,0,1"] = {0,0}, ["0,0,-1"] = {0,0}, ["1,1,0"] = {7,0},["-1,1,0"] = {6,0},["0,1,1"] = {0,0}, ["0,1,-1"] = {0,0}, ["1,-1,0"] = {7,0},["-1,-1,0"]= {6,0},["0,-1,1"] = {4,0}, ["0,-1,-1"]= {4,0}}, ["0,1,1"] = { ["1,0,0"] = {7,5},["-1,0,0"] = {6,5},["0,0,1"] = {5,0}, ["0,0,-1"] = {0,0}, ["1,1,0"] = {7,5},["-1,1,0"] = {6,5},["0,1,1"] = {5,0}, ["0,1,-1"] = {5,0}, ["1,-1,0"] = {7,5},["-1,-1,0"]= {6,5},["0,-1,1"] = {5,0}, ["0,-1,-1"]= {5,0}}, ["0,-1,1"] = { ["1,0,0"] = {7,4},["-1,0,0"] = {6,4},["0,0,1"] = {0,4}, ["0,0,-1"] = {0,4}, ["1,1,0"] = {7,4},["-1,1,0"] = {6,4},["0,1,1"] = {0,4}, ["0,1,-1"] = {0,4}, ["1,-1,0"] = {7,4},["-1,-1,0"]= {6,4},["0,-1,1"] = {4,4}, ["0,-1,-1"]= {4,4}}, ["-1,0,0"] = { ["0,0,-1"] = {7,1},["0,0,1"] = {8,1},["1,0,0"] = {1,1}, ["-1,0,0"] = {1,1}, ["0,1,-1"] = {7,1},["0,1,1"] = {8,1},["1,1,0"] = {1,1}, ["-1,1,0"] = {1,1}, ["0,-1,-1"]= {7,1},["0,-1,1"] = {8,1},["1,-1,0"] = {1,1}, ["-1,-1,0"]= {2,1}}, ["-1,1,0"] = { ["0,0,-1"] = {7,3},["0,0,1"] = {8,3},["1,0,0"] = {1,3}, ["-1,0,0"] = {1,3}, ["0,1,-1"] = {7,3},["0,1,1"] = {8,3},["1,1,0"] = {3,1}, ["-1,1,0"] = {3,1}, ["0,-1,-1"]= {7,3},["0,-1,1"] = {8,3},["1,-1,0"] = {3,1}, ["-1,-1,0"]= {3,1}}, ["-1,-1,0"]= { ["0,0,-1"] = {7,2},["0,0,1"] = {8,2},["1,0,0"] = {1,2}, ["-1,0,0"] = {1,2}, ["0,1,-1"] = {7,2},["0,1,1"] = {8,2},["1,1,0"] = {1,2}, ["-1,1,0"] = {1,2}, ["0,-1,-1"]= {7,2},["0,-1,1"] = {8,2},["1,-1,0"] = {1,2}, ["-1,-1,0"]= {2,2}}, ["0,0,-1"] = { ["-1,0,0"] = {9,0},["1,0,0"] = {8,0},["0,0,1"] = {0,0}, ["0,0,-1"] = {0,0}, ["-1,1,0"] = {9,0},["1,1,0"] = {8,0},["0,1,1"] = {0,0}, ["0,1,-1"] = {0,0}, ["-1,-1,0"]= {9,0},["1,-1,0"] = {8,0},["0,-1,1"] = {5,0}, ["0,-1,-1"]= {5,0}}, ["0,1,-1"] = { ["-1,0,0"] = {9,4},["1,0,0"] = {8,4},["0,0,1"] = {0,4}, ["0,0,-1"] = {4,0}, ["-1,1,0"] = {9,4},["1,1,0"] = {8,4},["0,1,1"] = {4,0}, ["0,1,-1"] = {4,0}, ["-1,-1,0"]= {9,4},["1,-1,0"] = {8,4},["0,-1,1"] = {4,0}, ["0,-1,-1"]= {4,0}}, ["0,-1,-1"]= { ["-1,0,0"] = {9,5},["1,0,0"] = {8,5},["0,0,1"] = {0,5}, ["0,0,-1"] = {0,5}, ["-1,1,0"] = {9,5},["1,1,0"] = {8,5},["0,1,1"] = {0,5}, ["0,1,-1"] = {0,5}, ["-1,-1,0"]= {9,5},["1,-1,0"] = {8,5},["0,-1,1"] = {0,5}, ["0,-1,-1"]= {5,5}}} --When to be placed as a corner piece local DefineCornerTrack = { ["1,0,0" ] = { ["0,0,1"] = 8, ["0,0,-1"] = 7}, ["0,0,-1"] = { ["-1,0,0"] = 6, ["1,0,0"] = 9}, ["-1,0,0"] = { ["0,0,-1"] = 6, ["0,0,1"] = 9}, ["0,0,1" ] = { ["-1,0,0"] = 8, ["1,0,0"] = 7}} -- local MinecartTracksPlugin = {} MinecartTracksPlugin.__index = MinecartTracksPlugin function MinecartTracksPlugin:new() local t = {} setmetatable(t, MinecartTracksPlugin) local w = Lua__cPlugin:new() tolua.setpeer(w, t) w:tolua__set_instance(w) return w end function MinecartTracksPlugin:OnDisable() Log( self:GetName() .. " v." .. self:GetVersion() .. " is shutting down..." ) end function MinecartTracksPlugin:Initialize() self:SetName( PLUGIN_NAME ) self:SetVersion( PLUGIN_VERSION ) PluginManager = cRoot:Get():GetPluginManager() PluginManager:AddHook( self, cPluginManager.E_PLUGIN_BLOCK_PLACE ) PluginManager:AddHook( self, cPluginManager.E_PLUGIN_TICK ) Log( "Initialized " .. self:GetName() .. " v." .. self:GetVersion() ) return true end function IsTrack(BlockID) if( BlockID == E_BLOCK_MINECART_TRACKS ) then return true end return false end function StringToXYZ(str) local pos = {} for n in string.gmatch(str,"[^,]+") do table.insert(pos,n) end return tonumber(pos[1]),tonumber(pos[2]),tonumber(pos[3]),tonumber(pos[4]) end function XYZToString(x,y,z) return tostring(x) .. "," ..tostring(y)..","..tostring(z) end --local sPlayer --(debug purposes) --local sServer = cRoot:Get():GetServer() --(debug purposes) --Searches positions according to meta to see if track is visually connected function ListConnectedTrack(X,Y,Z,IgnoreX,IgnoreY,IgnoreZ) local World = cRoot:Get():GetWorld() local Meta = World:GetBlockMeta(X,Y,Z) --Loop through tables to find compatible track to connect to local ConnectedTrack = {} for i,v in ipairs(CompatibleDirections[Meta]) do local x = X + v[1] local y = Y + v[2] local z = Z + v[3] if not(x == IgnoreX and y == IgnoreY and z == IgnoreZ) then if (IsTrack(World:GetBlock(x,y,z))) then local TargetMeta = World:GetBlockMeta(x,y,z) for ii,vv in ipairs(CompatibleMetas[Meta]) do if (vv == TargetMeta) then table.insert(ConnectedTrack,{["X"] = x, ["Y"] = y, ["Z"] = z, ["M"] = TargetMeta}) break end end end end end return ConnectedTrack end --Lists adjacentTrack that is not already connected function ListAdjacentTrack(X,Y,Z) local World = cRoot:Get():GetWorld() local AdjacentTracks = {} for k,v in pairs(DefineTrackBehavior) do -- Grab the relative x,y,z to test for adjacent track local x,y,z = StringToXYZ(k) x = X-x y = Y-y z = Z-z if (IsTrack(World:GetBlock(x,y,z))) then --Check if adjacent track is connected to anything before adding it to list local ConnectedTrack = ListConnectedTrack(x,y,z,X,Y,Z) if (#ConnectedTrack <= 1) then table.insert(AdjacentTracks,{ ["X"] = x, ["Y"] = y, ["Z"] = z, ["M"] = World:GetBlockMeta(x,y,z) }) end end end return AdjacentTracks end function EvaluateConnections(X,Y,Z) local World = cRoot:Get():GetWorld() local AdjacentTrack = ListAdjacentTrack(X,Y,Z) local ConnectedTrack = ListConnectedTrack(X,Y,Z) if (#AdjacentTrack == 0) then return -- No need to run check end local CornerMatch --See if I can visually join adjacent track for i=1, #AdjacentTrack,1 do local AdjacentTracksConnections = ListConnectedTrack(AdjacentTrack[i].X,AdjacentTrack[i].Y,AdjacentTrack[i].Z,X,Y,Z) for k,v in pairs(DefineTrackBehavior) do local RelativeXYZ = tostring(X - AdjacentTrack[i].X) .. "," .. tostring(Y - AdjacentTrack[i].Y) .. "," .. tostring(Z - AdjacentTrack[i].Z) if (k == RelativeXYZ and #AdjacentTracksConnections == 0) then local AdjConRelXYZ = XYZToString(AdjacentTrack[i].X - X,AdjacentTrack[i].Y - Y,AdjacentTrack[i].Z - Z) if (DefineTrackBehavior[RelativeXYZ][AdjConRelXYZ][1] ~= -1) then World:SetBlockMeta(AdjacentTrack[i].X,AdjacentTrack[i].Y,AdjacentTrack[i].Z,DefineTrackBehavior[RelativeXYZ][AdjConRelXYZ][1]) end if (DefineTrackBehavior[RelativeXYZ][AdjConRelXYZ][2] ~= -1) then World:SetBlockMeta(X,Y,Z,DefineTrackBehavior[RelativeXYZ][AdjConRelXYZ][2]) end --sServer:SendMessage( cChatColor.Gold .. AdjConRelXYZ.."|".. XYZToString(X-AdjacentTrack[i].X,Y-AdjacentTrack[i].Y,Z-AdjacentTrack[i].Z) .."[C]=" .. #AdjacentTracksConnections, sPlayer ) elseif (k == RelativeXYZ and #AdjacentTracksConnections > 0) then --Find Adjacent tracks connection's position so we can determine which meta to use local AdjConRelXYZ = XYZToString(AdjacentTrack[i].X - AdjacentTracksConnections[1].X,AdjacentTrack[i].Y - AdjacentTracksConnections[1].Y,AdjacentTrack[i].Z - AdjacentTracksConnections[1].Z) if (DefineTrackBehavior[RelativeXYZ][AdjConRelXYZ]) then if (DefineTrackBehavior[RelativeXYZ][AdjConRelXYZ][1] ~= -1) then World:SetBlockMeta(AdjacentTrack[i].X,AdjacentTrack[i].Y,AdjacentTrack[i].Z,DefineTrackBehavior[RelativeXYZ][AdjConRelXYZ][1]) end if (DefineTrackBehavior[RelativeXYZ][AdjConRelXYZ][2] ~= -1) then World:SetBlockMeta(X,Y,Z,DefineTrackBehavior[RelativeXYZ][AdjConRelXYZ][2]) end end --sServer:SendMessage( cChatColor.Gold .. AdjConRelXYZ .. "|" ..XYZToString(X-AdjacentTrack[i].X,Y-AdjacentTrack[i].Y,Z-AdjacentTrack[i].Z) .."[C]=" .. #AdjacentTracksConnections, sPlayer ) end end --CHeck if placed track should be a corner and apply this effect last if (#AdjacentTracksConnections <= 1 and CornerMatch == nil) then --keep tabs on this adjacent track to see if I can form a corner piece from it CornerMatch = XYZToString(X-AdjacentTrack[i].X,Y-AdjacentTrack[i].Y,Z-AdjacentTrack[i].Z) end if (CornerMatch) then local RelXYZCornerMatch = XYZToString(X-AdjacentTrack[i].X,Y-AdjacentTrack[i].Y,Z-AdjacentTrack[i].Z) if (DefineCornerTrack[CornerMatch] and DefineCornerTrack[CornerMatch][RelXYZCornerMatch]) then World:SetBlockMeta(X,Y,Z,DefineCornerTrack[CornerMatch][RelXYZCornerMatch]) end end end end UpdateMinecartTracks = false PlacedTrack = {} function MinecartTracksPlugin:OnBlockPlace(PacketData,Player) sPlayer = Player if( PacketData.m_ItemType == E_BLOCK_MINECART_TRACKS ) then local X = PacketData.m_PosX local Y = PacketData.m_PosY local Z = PacketData.m_PosZ local World = cRoot:Get():GetWorld() if (IsTrack(World:GetBlock(X,Y,Z))) then Player:GetInventory():AddItem(cItem(66,1)) end X,Y,Z = AddDirection( X, Y, Z, PacketData.m_Direction) PlacedTrack = { ["X"] = X, ["Y"] = Y, ["Z"] = Z} UpdateMinecartTracks = true end return false end function MinecartTracksPlugin:Tick( DeltaTime ) if ( UpdateMinecartTracks == true ) then local World = cRoot:Get():GetWorld() UpdateMinecartTracks = false if (IsTrack(World:GetBlock(PlacedTrack.X,PlacedTrack.Y-1,PlacedTrack.Z))) then World:SetBlock(PlacedTrack.X,PlacedTrack.Y,PlacedTrack.Z,0,0) else EvaluateConnections(PlacedTrack.X,PlacedTrack.Y,PlacedTrack.Z) end end end Plugin = MinecartTracksPlugin:new() cRoot:Get():GetPluginManager():AddPlugin( Plugin )