libraryaddict

Untitled

May 17th, 2012
71
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 14.70 KB | None | 0 0
  1. local Clients = {} -- Stores all info on each client. Clients X/Y is based on their screen cords. use x y for client itself.
  2. local ClientsNo = {}
  3. local Servers = {} -- ID's of all the servers which rebroadcast the game for more range
  4. local Maps = {}  -- Stores maps in it in another table. Can host unlimited maps.
  5. local MapInfo = {} -- Stuff that was in the "Info:" This is so if there was a spawn then they spawn there. Or if you need to check so and so.
  6. local Data = {} -- Stores data on each map, Is there a enemy here? A pickup pack?
  7. local ViewMap = {} -- Every players viewable map is in here stored in its own seperate table
  8. local Spawn = {} -- Define the spawn for each map
  9. local DefaultMap = "Default" -- Map everyone first spawns on
  10. local ChangedLines = {} -- Stores lines changed so it can try update the map with min lag
  11. local ClientData = {"ID", "Name", "Map", "X", "Y", "Height", "Width"} -- Just add a bunch of names for each thingy so it knows it exists and can save it
  12. local Explosions = {}
  13. local MapSize = {}
  14.  
  15. function setDefault(map)
  16.   DefaultMap = map
  17. end
  18.  
  19. function sendClients(Info) -- Send the clients the info. This sends them all it :\
  20.   for n=1,#Clients do
  21.     rednet.send(Clients[n], Info)
  22.   end
  23. end
  24.  
  25. function sendServers(Info) -- Send the servers the info. Sends them all of it.
  26.   for n=1,#Servers do
  27.     rednet.send(Servers[n], Info)
  28.   end
  29. end
  30.  
  31. function tag(sTag) -- Tags the messages so tagView can use it
  32.   return "["..string.gsub(string.gsub(sTag, "%[", "~RightBracket~"), "%]", "~LeftBracket~").."]"
  33. end
  34.  
  35. function tagView(msg) -- libraryaddict's little thingy ;D
  36.   local ReturnMsg = msg
  37.   local ReturnTag = {}
  38.   if string.find(ReturnMsg, "%[") and string.find(ReturnMsg, "%]") then
  39.     while true do
  40.       first = string.find(ReturnMsg, "%[", 1)
  41.       last = string.find(ReturnMsg, "%]", 2)
  42.       if first and last then ReturnTag[#ReturnTag+1] = string.gsub(string.gsub(string.sub(ReturnMsg, first+1, last-1), "~RightBracket~", "%["), "~LeftBracket", "%]")
  43.         ReturnMsg = string.sub(ReturnMsg, last+1, string.len(msg))
  44.       else
  45.         break
  46.       end
  47.     end
  48.     ReturnTag[#ReturnTag+1] = ReturnMsg
  49.     return unpack(ReturnTag)
  50.   else
  51.     return false
  52.   end
  53. end
  54.  
  55. function loadMap(MapName, TableName) -- Loads a map into a table, The info included is loaded into another table
  56.   if not MapName then error("function loadMap, Please use loadMap(MapNameAndDir, TableNameYouWantToAccessItWith)") end
  57.   if not fs.exists(MapName) then error("Please use a map that exists!") end
  58.   Maps[TableName] = {}
  59.   local MapLoadVari = io.open(MapName, "r")
  60.   local i = 1
  61.   local a = 0
  62.   local b = 0
  63.   local Returns = {}
  64.   for line in MapLoadVari:lines() do
  65.     if not string.sub(line, 1, 5) == "Info:" then
  66.       Map[TableName][i] = line
  67.       b = b+1
  68.       if string.len(line) > a then
  69.         a = string.len(line)
  70.       end
  71.     else
  72.       Returns[#Returns+1] = string.sub(line, 6)
  73.     end
  74.     i = i+1
  75.   end
  76.   MapSize[TableName] = {}
  77.   MapSize[TableName]["X"] = a
  78.   MapSize[TableName]["Y"] = b
  79.   loadObjects(TableName)
  80.   Returns[#Returns+1] = TableName
  81.   return unpack(Returns)
  82. end
  83.    
  84. function setData(xInfo, yInfo, Map, InfoTable, InfoName, Info) -- Used for map data. Bahahaha confuse my stealers!
  85.   local xInfo = tonumber(xInfo)
  86.   local yInfo = tonumber(yInfo)
  87.   if not Data[Map][yInfo] then
  88.     Data[Map][yInfo] = {}
  89.   end
  90.   if not Data[Map][yInfo][xInfo] then
  91.     Data[Map][yInfo][xInfo] = {}
  92.   end
  93.   if not Data[Map][yInfo][xInfo][InfoTable] then
  94.     Data[Map][yInfo][xInfo][InfoTable] = {}
  95.   end
  96.   Data[Map][yInfo][xInfo][InfoTable][InfoName] = Info
  97. end
  98.  
  99. function checkData(xInfo, yInfo, Map, InfoTable, InfoName) -- Return data at these cords.
  100.   local xInfo = tonumber(xInfo)
  101.   local yInfo = tonumber(yInfo)
  102.   if InfoName then
  103.     if Data[Map][yInfo][xInfo][InfoTable][InfoName] then
  104.       return unpack(Data[Map][yInfo][xInfo][InfoTable][InfoName])
  105.     end
  106.   else
  107.     if Data[Map][yInfo][xInfo][InfoTable] then
  108.       return unpack(Data[Map][yInfo][xInfo][InfoTable])
  109.     end
  110.   end
  111. end
  112.    
  113. function deleteData(xInfo, yInfo, Map, InfoTable)
  114.   if Data[Map][yInfo][xInfo][InfoTable] then
  115.     Data[Map][yInfo][xInfo][InfoTable] = nil
  116.   end
  117. end
  118.  
  119.  
  120. function screenOptions(Locked, Width, Height, ID) -- No idea what screenlocked is gonna be good for, Locked must be true or false.
  121.   Clients[ClientsNo[ID]]["LockedScreen"] = Locked
  122.   Clients[ClientsNo[ID]]["ScreenWidth"] = Width
  123.   Clients[ClientsNo[ID]]["ScreenHeight"] = Height
  124. end
  125.  
  126. function moveScreen(Side, UpDown, ID, Map)
  127.   if Clients[ClientsNo[ID]]["Y"]+UpDown >= 1 then
  128.     Clients[ClientsNo[ID]]["Y"] = Clients[ClientsNo[ID]]["Y"]+UpDown
  129.   elseif Clients[ClientsNo[ID]]["Y"]+UpDown <= MapSize[Map]["Y"] then
  130.     Clients[ClientsNo[ID]]["Y"] = Clients[ClientsNo[ID]]["Y"]+UpDown
  131.   else -- Wrap screen to edges.
  132.     Clients[ClientsNo[ID]]["Y"] = MapSize[Map]["Y"]
  133.   end
  134.   if Clients[ClientsNo[ID]]["X"]+Side >= 1 then
  135.     Clients[ClientsNo[ID]]["X"] = Clients[ClientsNo[ID]]["X"]+Side
  136.   elseif  Clients[ClientsNo[ID]]["X"]+Side <= MapSize[Map]["X"] then
  137.     Clients[ClientsNo[ID]]["X"] = Clients[ClientsNo[ID]]["X"]+Side
  138.   else -- wrap
  139.     Clients[ClientsNo[ID]]["X"] = MapSize[Map]["X"]
  140.   end
  141.   draw("all", ID, Map)
  142. end
  143.  
  144. function setSpawn(MapName, XCord, YCord)
  145.   Spawn[MapName] = {}
  146.   Spawn[MapName]["X"] = XCord
  147.   Spawn[MapName]["Y"] = YCord
  148. end
  149.  
  150. function playerDataLoad(Name, ID)
  151.   if fs.exists("PlayerData/"..Name) then
  152.     Clients[#Clients+1] = {}
  153.     local PlayerLoad = io.open(Name, "r")
  154.     Clients[#Clients] = textutils.unserialize(PlayerLoad.readAll())
  155.     ClientsNo[ID] = #Clients
  156.     return true
  157.   end
  158.   return false
  159. end
  160.  
  161.  
  162.  
  163. function playerJoin(ID, Name) -- When they sucessfully join. Assign them info.
  164.   if not playerDataLoad(Name, ID) then
  165.     ClientsNo[ID] = #Clients+1
  166.     Clients[ClientsNo[ID]] = {}
  167.     print("h:"..ClientsNo[ID])
  168.     Clients[ClientsNo[ID]]["Name"] = Name
  169.     Clients[ClientsNo[ID]]["ID"] = ID
  170.     setPlayerMap(ID, "OrigSpawn")
  171.   end
  172. end
  173.  
  174. function setPlayerMap(ID, Place, X, Y)
  175.   if Place == "OrigSpawn" then
  176.     Clients[ClientsNo[ID]]["Map"] = DefaultMap
  177.     local x, y = getSpawn(DefaultMap)
  178.     Clients[ClientsNo[ID]]["X"] = x
  179.     Clients[ClientsNo[ID]]["Y"] = y
  180.   else
  181.     Clients[ClientsNo[ID]]["Map"] = Place
  182.     Clients[ClientsNo[ID]]["X"] = X
  183.     Clients[ClientsNo[ID]]["Y"] = Y
  184.   end
  185. end
  186.    
  187.  
  188. function playerDataSave(Name, ID)
  189.   if not fs.exists("PlayerData") then
  190.     fs.makeDir("PlayerData")
  191.   end
  192.   local PlayerSaving = io.open("PlayerData/"..Name, "w")
  193.   PlayerSaving:write(textutils.serialize(Clients[ClientsNo[ID]]))
  194.   PlayerSaving:close()
  195. end
  196.  
  197. function split(str, pat)
  198.    local t = {}  -- NOTE: use {n = 0} in Lua-5.0
  199.    local fpat = "(.-)" .. pat
  200.    local last_end = 1
  201.    local s, e, cap = str:find(fpat, 1)
  202.    while s do
  203.       if s ~= 1 or cap ~= "" then
  204.      table.insert(t,cap)
  205.       end
  206.       last_end = e+1
  207.       s, e, cap = str:find(fpat, last_end)
  208.    end
  209.    if last_end <= #str then
  210.       cap = str:sub(last_end)
  211.       table.insert(t, cap)
  212.    end
  213.    return unpack(t)
  214. end
  215.  
  216. function getSpawn(Map) -- Get the point newbies spawn at
  217.   return Spawn[Map]["X"], Spawn[Map]["Y"]
  218. end
  219.  
  220. function draw(Info, ClientNo, Map) -- redraws for the client. Does NOT send the info out! Does NOT edit the map! Well it prob have to send it..
  221.   if not ClientNo then error("draw(Info, ClientNo, Map) ClientNo not found. ClientNo is needed") end
  222.   if Info == "all" then -- Draw every single appropriate line for the client. They now see the proper screen! Basically forcing a complete redraw. Eg if the screen moved.
  223.     ViewMap[ClientNo] = {} -- Reset client map data. They now see a blank screen
  224.     for n=1,Clients[ClientNo]["ScreenHeight"] do -- Client number bla bla. This will do it for their screenheight amount
  225.       ViewMap[ClientNo][n] = string.sub(Map[Clients[ClientNo]["Y"]+n], Clients[ClientNo]["X"], Clients[ClientNo]["ScreenWidth"])
  226.     end
  227.   elseif Info == "lines" then -- redraws a single line on their client. This should limit lag/flickering.
  228.     for n=1,#ChangedLines do -- Gonna check with all the changed lines. But only the correct ones will be updated.
  229.       local Stuff = {split(ChangedLines[n], ":")}
  230.       if Clients[ClientNo]["Map"] == Stuff[1] then -- If the changed line is on the same map as the client
  231.         --They are the same. You can now check if this client needs to see this line drawn. Or if its outside their screen scope
  232.         -- OR I could just redraw it anyways >.>
  233.         -- Wait a sec. The ChangedLines should just give the Map:Line:X thats being redrawn.
  234.         -- So I need to check if the screen is in the X and Y of the changed.
  235.         -- Could define each line like this. MAP:Y:X:X:X:X:X:X
  236.         -- So the map got edited on line x. Each of these X's got edited. No way could it all be edited?
  237.         -- I think I'll go with that
  238.         if tonumber(Stuff[2]) >= Clients[ClientsNo[ID]]["Y"] and tonumber(Stuff[2]) <= Clients[ClientsNo[ID]]["Height"] then
  239.           local p = 3
  240.           repeat
  241.             if tonumber(Stuff[p]) >= Clients[ClientsNo[ID]]["X"] and tonumber(Stuff[p]) <= Clients[ClientsNo[ID]]["Width"] then
  242.               --Ok. So you can redraw that line..
  243.               ViewMap[ClientNo][n] = string.sub(Map[Clients[ClientNo]["Map"]], Clients[ClientNo]["X"], Clients[ClientNo]["ScreenWidth"])
  244.               p = p+1
  245.             end
  246.           until not Stuff[p]
  247.         end
  248.       end
  249.     end
  250.   end
  251. end
  252.      
  253. function loadObjects(sTableName) -- Define the objects in here to be loaded into the data. This is for stuff like healthpacks etc defined with the map itself.
  254.   if not sTableName then error("sTableName dont exist") end
  255.   Objects = {"S", "L", "P"} -- Sample! Replace with your own. Letters it finds in the map..
  256.   ObjectsData = {"Sample", "Libraryaddict", "Player"}
  257.   for n=1,#Maps[sTableName] do -- For lines in that table do
  258.     for q=1,string.len(Map[sTableName][n]) do
  259.       local sLetter = string.sub(Map[sTableName][n], q, q)
  260.       for p=1,#Objects do
  261.         if Objects[p] == sLetter then
  262.           setData(xInfo, yInfo, sTableName, ObjectsData[p], "Type", ObjectsData[p])
  263.         end
  264.       end
  265.     end
  266.   end
  267. end
  268.  
  269. function editMap(xCord, yCord, Maps, Stuff) -- Edit data shown to player. Aka the map view. thingy.
  270.   if Map[Maps][yCord] then
  271.     Map[Maps][yCord] = string.sub(Map[Maps][yCord], 1, xCord-1)..Stuff..string.sub(Map[Maps][yCord], xCord+1, string.len(Map[Maps][yCord]))
  272.   else error("editMap(), You wanted a yCord thats outside of the maps range.") end
  273. end
  274.    
  275. function Tick() -- This defines the actions of everything that isnt the player. Eg explosion decay.
  276.   spreadExplosion()
  277.   MoveFired()
  278.   MoveNPC()
  279.   TheTick = os.startTimer(0.1)
  280. end
  281.  
  282. function createExplosion(xCord, yCord, MapName, Spread, SpreadRate, DecayRate, Characters, ExplosionName, ...) -- All of this is needed. The "..." is directions. Use left, right, up, down if you want it to act like a normal explosion. ExplosionName is the kind of explosion this is, Eg. a nuke.
  283.   --DataName is what you will see when you check Data
  284.   setData(xInfo, yInfo, MapName, "Explosion", "Type", ExplosionName)
  285.   local eNum = #Explosions+1
  286.   Explosions[eNum] = {}
  287.   local dirs = {...}
  288.   local function def(sName, sData)
  289.     Explosions[eNum][sName] = sData
  290.   end
  291.   for n=1,#dirs do
  292.     dirs[n] = string.lower(dirs[n])
  293.     if n == 5 then
  294.       error("Why are there 5 sides? error at createExplosion()")
  295.     end
  296.   end
  297.   for n=1,#dirs do
  298.     if dirs[n] == "up" then
  299.       def("Up", true)
  300.     elseif dirs[n] == "down" then
  301.       def("Down", true)
  302.     elseif dirs[n] == "left" then
  303.       def("Left", true)
  304.     elseif dirs[n] == "right" then
  305.       def("Right", true)
  306.     end
  307.   end
  308.   def("Map", MapName)
  309.   def("X", xCord)
  310.   def("Y", yCord)
  311.   def("Spread", Spread)
  312.   def("Rate", SpreadRate)
  313.   def("Decay", DecayRate)
  314.   def("Char", Character)
  315.   def("Name", ExplosionName)
  316.   def("STimer", 0)
  317.   def("DTimer", DecayRate)
  318.   setData(Explosions[EN]["X"], Explosions[EN]["Y"], Explosions[EN]["Map"], "Explosion", "Type", "Explosion")
  319.   doExplosion(eNum)
  320. end
  321.  
  322. --Add dirs! This is check for when I get back
  323.  
  324. function spreadExplosion() -- Finds all explosions and calls them. Pretty basic function but eh. I should stick this in Tick()
  325.   for n=1,#Explosions do
  326.     doExplosion(n)
  327.   end
  328. end
  329.  
  330. function deleteAllData(xInfo, yInfo, Map) -- Deletes all data there. Good for rewriting it :\
  331.   Data[Map][yInfo][xInfo] = {}
  332. end
  333.  
  334. function isSolid(xInfo, yInfo, Map)
  335.   if checkData(xInfo, yInfo, Map, "Solid", "Solid") == "Solid" then
  336.     return true
  337.   else
  338.     return false
  339.   end
  340. end
  341.  
  342. function setSolid(xInfo, yInfo, Map)
  343.   setData(xInfo, yInfo, Map, "Solid", "Solid", "Solid")
  344. end
  345.  
  346. function unsetSolid(xInfo, yInfo, Map)
  347.   setData(xInfo, yInfo, Map, "Solid", "Solid", "Not Solid")
  348. end
  349.  
  350. function returnSide(xCord, yCord, Side)
  351.   local Side = string.lower(Side)
  352.   if Side == "left" then
  353.     return (xCord-1), yCord
  354.   elseif Side == "right" then
  355.     return (xCord+1), yCord
  356.   elseif Side == "up" then
  357.     return xCord, (yCord-1)
  358.   elseif Side == "down" then
  359.     return xCord, (yCord+1)
  360.   end
  361. end
  362.  
  363. function returnExplodeData(EN)
  364.   local KO = {}
  365.   if Explosions[EN] then
  366.     for n,a in ipairs(Explosions[EN]) do
  367.       KO[n] = a
  368.     end
  369.   end
  370.   return unpack(KO)
  371. end
  372.    
  373. function returnMap(ID)
  374.   return unpack(ViewMap[ID])
  375. end
  376.    
  377. --[[function doExplosion(EN) -- EN = ExplosionsNumber. This function auctally does the explosion checking.
  378.   Explosions[EN]["STimer"] = Explosions[EN]["STimer"]-1
  379.   Explosions[EN]["DTimer"] = Explosions[EN]["DTimer"]-1
  380.   if Explosions[EN]["DTimer"] == 0 then -- Delete this one
  381.     deleteData(Explosions[EN]["X"], Explosions[EN]["Y"], Explosions[EN]["Map"], "Explosion")
  382.     table.remove(Explosions, EN)
  383.     return
  384.   end -- checkData(xInfo, yInfo, Map, InfoTable, InfoName)
  385.   if Explosions[EN]["STimer"] <= 0 then--Spread
  386.     Explosions[EN]["STimer"] = Explosions[EN]["SpreadRate"]
  387.     local Side = {Explosions[EN]["Up"], Explosions[EN]["Down"], Explosions[EN]["Left"], Explosions[EN]["Right"]}
  388.     local Sides = {Explosions[EN]["Up"], Explosions[EN]["Down"], Explosions[EN]["Left"], Explosions[EN]["Right"]}
  389.     for n=1,Side do
  390.       local PigSnout = math.random(1,#Side) -- function createExplosion(xCord, yCord, MapName, Spread, SpreadRate, DecayRate, Characters, ExplosionName, ...) -- All of this is needed. The "..." is directions. Use left, right, up, down if you want it to act like a normal explosion. ExplosionName is the kind of explosion this is, Eg. a nuke.
  391.       if isSolid(returnSide(xInfo, yInfo, Side[PigSnout]), Map) == false then
  392.         doExplosion(returnSide(xInfo, yInfo, Side[PigSnout])
  393.         table.remove(Side, PigSnout)
  394.       end
  395.     end
  396.   end
  397. end
  398. end]]
Advertisement
Add Comment
Please, Sign In to add comment