libraryaddict

Untitled

May 17th, 2012
88
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 14.79 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.   print("h:"..ClientsNo[ID])
  122.   Clients[ClientsNo[ID]]["LockedScreen"] = Locked
  123.   Clients[ClientsNo[ID]]["ScreenWidth"] = Width
  124.   Clients[ClientsNo[ID]]["ScreenHeight"] = Height
  125. end
  126.  
  127. function moveScreen(Side, UpDown, ID, Map)
  128.   if Clients[ClientsNo[ID]]["Y"]+UpDown >= 1 then
  129.     Clients[ClientsNo[ID]]["Y"] = Clients[ClientsNo[ID]]["Y"]+UpDown
  130.   elseif Clients[ClientsNo[ID]]["Y"]+UpDown <= MapSize[Map]["Y"] then
  131.     Clients[ClientsNo[ID]]["Y"] = Clients[ClientsNo[ID]]["Y"]+UpDown
  132.   else -- Wrap screen to edges.
  133.     Clients[ClientsNo[ID]]["Y"] = MapSize[Map]["Y"]
  134.   end
  135.   if Clients[ClientsNo[ID]]["X"]+Side >= 1 then
  136.     Clients[ClientsNo[ID]]["X"] = Clients[ClientsNo[ID]]["X"]+Side
  137.   elseif  Clients[ClientsNo[ID]]["X"]+Side <= MapSize[Map]["X"] then
  138.     Clients[ClientsNo[ID]]["X"] = Clients[ClientsNo[ID]]["X"]+Side
  139.   else -- wrap
  140.     Clients[ClientsNo[ID]]["X"] = MapSize[Map]["X"]
  141.   end
  142.   draw("all", ID, Map)
  143. end
  144.  
  145. function setSpawn(MapName, XCord, YCord)
  146.   Spawn[MapName] = {}
  147.   Spawn[MapName]["X"] = XCord
  148.   Spawn[MapName]["Y"] = YCord
  149. end
  150.  
  151. function playerDataLoad(Name, ID)
  152.   if fs.exists("PlayerData/"..Name) then
  153.     Clients[#Clients+1] = {}
  154.     local PlayerLoad = io.open(Name, "r")
  155.     Clients[#Clients] = textutils.unserialize(PlayerLoad.readAll())
  156.     ClientsNo[ID] = #Clients
  157.     return true
  158.   end
  159.   return false
  160. end
  161.  
  162.  
  163.  
  164. function playerJoin(ID, Name) -- When they sucessfully join. Assign them info.
  165.   if not playerDataLoad(Name, ID) then
  166.     ClientsNo[ID] = #Clients+1
  167.     Clients[ClientsNo[ID]] = {}
  168.     print("h:"..ClientsNo[ID])
  169.     Clients[ClientsNo[ID]]["Name"] = Name
  170.     Clients[ClientsNo[ID]]["ID"] = ID
  171.     setPlayerMap(ID, "OrigSpawn")
  172.     print("h:"..ClientsNo[ID])
  173.   end
  174.   print("h:"..ClientsNo[ID])
  175. end
  176.  
  177. function setPlayerMap(ID, Place, X, Y)
  178.   if Place == "OrigSpawn" then
  179.     Clients[ClientsNo[ID]]["Map"] = DefaultMap
  180.     local x, y = getSpawn(DefaultMap)
  181.     Clients[ClientsNo[ID]]["X"] = x
  182.     Clients[ClientsNo[ID]]["Y"] = y
  183.   else
  184.     Clients[ClientsNo[ID]]["Map"] = Place
  185.     Clients[ClientsNo[ID]]["X"] = X
  186.     Clients[ClientsNo[ID]]["Y"] = Y
  187.   end
  188. end
  189.    
  190.  
  191. function playerDataSave(Name, ID)
  192.   if not fs.exists("PlayerData") then
  193.     fs.makeDir("PlayerData")
  194.   end
  195.   local PlayerSaving = io.open("PlayerData/"..Name, "w")
  196.   PlayerSaving:write(textutils.serialize(Clients[ClientsNo[ID]]))
  197.   PlayerSaving:close()
  198. end
  199.  
  200. function split(str, pat)
  201.    local t = {}  -- NOTE: use {n = 0} in Lua-5.0
  202.    local fpat = "(.-)" .. pat
  203.    local last_end = 1
  204.    local s, e, cap = str:find(fpat, 1)
  205.    while s do
  206.       if s ~= 1 or cap ~= "" then
  207.      table.insert(t,cap)
  208.       end
  209.       last_end = e+1
  210.       s, e, cap = str:find(fpat, last_end)
  211.    end
  212.    if last_end <= #str then
  213.       cap = str:sub(last_end)
  214.       table.insert(t, cap)
  215.    end
  216.    return unpack(t)
  217. end
  218.  
  219. function getSpawn(Map) -- Get the point newbies spawn at
  220.   return Spawn[Map]["X"], Spawn[Map]["Y"]
  221. end
  222.  
  223. 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..
  224.   if not ClientNo then error("draw(Info, ClientNo, Map) ClientNo not found. ClientNo is needed") end
  225.   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.
  226.     ViewMap[ClientNo] = {} -- Reset client map data. They now see a blank screen
  227.     for n=1,Clients[ClientNo]["ScreenHeight"] do -- Client number bla bla. This will do it for their screenheight amount
  228.       ViewMap[ClientNo][n] = string.sub(Map[Clients[ClientNo]["Y"]+n], Clients[ClientNo]["X"], Clients[ClientNo]["ScreenWidth"])
  229.     end
  230.   elseif Info == "lines" then -- redraws a single line on their client. This should limit lag/flickering.
  231.     for n=1,#ChangedLines do -- Gonna check with all the changed lines. But only the correct ones will be updated.
  232.       local Stuff = {split(ChangedLines[n], ":")}
  233.       if Clients[ClientNo]["Map"] == Stuff[1] then -- If the changed line is on the same map as the client
  234.         --They are the same. You can now check if this client needs to see this line drawn. Or if its outside their screen scope
  235.         -- OR I could just redraw it anyways >.>
  236.         -- Wait a sec. The ChangedLines should just give the Map:Line:X thats being redrawn.
  237.         -- So I need to check if the screen is in the X and Y of the changed.
  238.         -- Could define each line like this. MAP:Y:X:X:X:X:X:X
  239.         -- So the map got edited on line x. Each of these X's got edited. No way could it all be edited?
  240.         -- I think I'll go with that
  241.         if tonumber(Stuff[2]) >= Clients[ClientsNo[ID]]["Y"] and tonumber(Stuff[2]) <= Clients[ClientsNo[ID]]["Height"] then
  242.           local p = 3
  243.           repeat
  244.             if tonumber(Stuff[p]) >= Clients[ClientsNo[ID]]["X"] and tonumber(Stuff[p]) <= Clients[ClientsNo[ID]]["Width"] then
  245.               --Ok. So you can redraw that line..
  246.               ViewMap[ClientNo][n] = string.sub(Map[Clients[ClientNo]["Map"]], Clients[ClientNo]["X"], Clients[ClientNo]["ScreenWidth"])
  247.               p = p+1
  248.             end
  249.           until not Stuff[p]
  250.         end
  251.       end
  252.     end
  253.   end
  254. end
  255.      
  256. 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.
  257.   if not sTableName then error("sTableName dont exist") end
  258.   Objects = {"S", "L", "P"} -- Sample! Replace with your own. Letters it finds in the map..
  259.   ObjectsData = {"Sample", "Libraryaddict", "Player"}
  260.   for n=1,#Maps[sTableName] do -- For lines in that table do
  261.     for q=1,string.len(Map[sTableName][n]) do
  262.       local sLetter = string.sub(Map[sTableName][n], q, q)
  263.       for p=1,#Objects do
  264.         if Objects[p] == sLetter then
  265.           setData(xInfo, yInfo, sTableName, ObjectsData[p], "Type", ObjectsData[p])
  266.         end
  267.       end
  268.     end
  269.   end
  270. end
  271.  
  272. function editMap(xCord, yCord, Maps, Stuff) -- Edit data shown to player. Aka the map view. thingy.
  273.   if Map[Maps][yCord] then
  274.     Map[Maps][yCord] = string.sub(Map[Maps][yCord], 1, xCord-1)..Stuff..string.sub(Map[Maps][yCord], xCord+1, string.len(Map[Maps][yCord]))
  275.   else error("editMap(), You wanted a yCord thats outside of the maps range.") end
  276. end
  277.    
  278. function Tick() -- This defines the actions of everything that isnt the player. Eg explosion decay.
  279.   spreadExplosion()
  280.   MoveFired()
  281.   MoveNPC()
  282.   TheTick = os.startTimer(0.1)
  283. end
  284.  
  285. 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.
  286.   --DataName is what you will see when you check Data
  287.   setData(xInfo, yInfo, MapName, "Explosion", "Type", ExplosionName)
  288.   local eNum = #Explosions+1
  289.   Explosions[eNum] = {}
  290.   local dirs = {...}
  291.   local function def(sName, sData)
  292.     Explosions[eNum][sName] = sData
  293.   end
  294.   for n=1,#dirs do
  295.     dirs[n] = string.lower(dirs[n])
  296.     if n == 5 then
  297.       error("Why are there 5 sides? error at createExplosion()")
  298.     end
  299.   end
  300.   for n=1,#dirs do
  301.     if dirs[n] == "up" then
  302.       def("Up", true)
  303.     elseif dirs[n] == "down" then
  304.       def("Down", true)
  305.     elseif dirs[n] == "left" then
  306.       def("Left", true)
  307.     elseif dirs[n] == "right" then
  308.       def("Right", true)
  309.     end
  310.   end
  311.   def("Map", MapName)
  312.   def("X", xCord)
  313.   def("Y", yCord)
  314.   def("Spread", Spread)
  315.   def("Rate", SpreadRate)
  316.   def("Decay", DecayRate)
  317.   def("Char", Character)
  318.   def("Name", ExplosionName)
  319.   def("STimer", 0)
  320.   def("DTimer", DecayRate)
  321.   setData(Explosions[EN]["X"], Explosions[EN]["Y"], Explosions[EN]["Map"], "Explosion", "Type", "Explosion")
  322.   doExplosion(eNum)
  323. end
  324.  
  325. --Add dirs! This is check for when I get back
  326.  
  327. function spreadExplosion() -- Finds all explosions and calls them. Pretty basic function but eh. I should stick this in Tick()
  328.   for n=1,#Explosions do
  329.     doExplosion(n)
  330.   end
  331. end
  332.  
  333. function deleteAllData(xInfo, yInfo, Map) -- Deletes all data there. Good for rewriting it :\
  334.   Data[Map][yInfo][xInfo] = {}
  335. end
  336.  
  337. function isSolid(xInfo, yInfo, Map)
  338.   if checkData(xInfo, yInfo, Map, "Solid", "Solid") == "Solid" then
  339.     return true
  340.   else
  341.     return false
  342.   end
  343. end
  344.  
  345. function setSolid(xInfo, yInfo, Map)
  346.   setData(xInfo, yInfo, Map, "Solid", "Solid", "Solid")
  347. end
  348.  
  349. function unsetSolid(xInfo, yInfo, Map)
  350.   setData(xInfo, yInfo, Map, "Solid", "Solid", "Not Solid")
  351. end
  352.  
  353. function returnSide(xCord, yCord, Side)
  354.   local Side = string.lower(Side)
  355.   if Side == "left" then
  356.     return (xCord-1), yCord
  357.   elseif Side == "right" then
  358.     return (xCord+1), yCord
  359.   elseif Side == "up" then
  360.     return xCord, (yCord-1)
  361.   elseif Side == "down" then
  362.     return xCord, (yCord+1)
  363.   end
  364. end
  365.  
  366. function returnExplodeData(EN)
  367.   local KO = {}
  368.   if Explosions[EN] then
  369.     for n,a in ipairs(Explosions[EN]) do
  370.       KO[n] = a
  371.     end
  372.   end
  373.   return unpack(KO)
  374. end
  375.    
  376. function returnMap(ID)
  377.   return unpack(ViewMap[ID])
  378. end
  379.    
  380. --[[function doExplosion(EN) -- EN = ExplosionsNumber. This function auctally does the explosion checking.
  381.   Explosions[EN]["STimer"] = Explosions[EN]["STimer"]-1
  382.   Explosions[EN]["DTimer"] = Explosions[EN]["DTimer"]-1
  383.   if Explosions[EN]["DTimer"] == 0 then -- Delete this one
  384.     deleteData(Explosions[EN]["X"], Explosions[EN]["Y"], Explosions[EN]["Map"], "Explosion")
  385.     table.remove(Explosions, EN)
  386.     return
  387.   end -- checkData(xInfo, yInfo, Map, InfoTable, InfoName)
  388.   if Explosions[EN]["STimer"] <= 0 then--Spread
  389.     Explosions[EN]["STimer"] = Explosions[EN]["SpreadRate"]
  390.     local Side = {Explosions[EN]["Up"], Explosions[EN]["Down"], Explosions[EN]["Left"], Explosions[EN]["Right"]}
  391.     local Sides = {Explosions[EN]["Up"], Explosions[EN]["Down"], Explosions[EN]["Left"], Explosions[EN]["Right"]}
  392.     for n=1,Side do
  393.       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.
  394.       if isSolid(returnSide(xInfo, yInfo, Side[PigSnout]), Map) == false then
  395.         doExplosion(returnSide(xInfo, yInfo, Side[PigSnout])
  396.         table.remove(Side, PigSnout)
  397.       end
  398.     end
  399.   end
  400. end
  401. end]]
Advertisement
Add Comment
Please, Sign In to add comment