Guest
Public paste!

Lee

By: a guest | Oct 25th, 2009 | Syntax: Lua | Size: 5.25 KB | Hits: 257 | Expires: Never
This paste has a previous version, view the difference. Copy text to clipboard
  1. require "struct"
  2. dofile("table.lua")
  3.  
  4. function Class(members)
  5.         members = members or {}
  6.         local mt = {
  7.                 __metatable = members;
  8.                 __index     = members;
  9.         }
  10.         local function new(_, init)
  11.                 return setmetatable(init or {}, mt)
  12.         end
  13.         local function copy(obj, ...)
  14.                 local newobj = obj:new(unpack(arg))
  15.                 for n,v in pairs(obj) do newobj[n] = v end
  16.                 return newobj
  17.         end
  18.         members.new  = members.new  or new
  19.         members.copy = members.copy or copy
  20.         return mt
  21. end
  22.  
  23.  
  24. --[[Class]] Reader = { --
  25.         new = function(self, stream)
  26.                 local __members__ = {
  27.                                 stream = stream
  28.                 }
  29.                 local __meta__ = {__metatable = self, __index = self}
  30.                 local _return_ = setmetatable(__members__, __meta__)
  31.  
  32.                 return _return_
  33.         end
  34.         ,
  35.         line = function(self)
  36.                 return ReadLine(self.stream):trim()
  37.         end
  38.         ,
  39.         int = function(self)
  40.                 return ReadInt(self.stream)
  41.         end
  42.         ,
  43.         short = function(self)
  44.                 return ReadShort(self.stream)
  45.         end
  46.         ,
  47.         str = function(self, ln)
  48.                 return ReadString(self.stream, ln)
  49.         end
  50.         ,
  51.         byte = function(self)
  52.                 return ReadByte(self.stream)
  53.         end
  54. }
  55. Class(Reader) --[[Class]]--
  56.  
  57.  
  58. --[[Class]] Map = { --
  59.         header = "Unreal Software's Counter-Strike 2D Map File",
  60.         maxheader = "Unreal Software's Counter-Strike 2D Map File (max)",
  61.         mapcheck = "ed.erawtfoslaernu",
  62.         new = function(self, file)
  63.                 local timeit = os.clock()
  64.                 local __members__ = {
  65.  
  66.                                 file = file,
  67.                                 data = "",
  68.                                 reader = nil,
  69.                                 metadata = {},
  70.  
  71.                                 tiles = {},
  72.                                 modes = {},
  73.                                 entities = {},
  74.                                 collisions = {},
  75.                                 gradient = {},
  76.                                 antigradient = {},
  77.                 }
  78.                 local __meta__ = {__metatable = self, __index = self}
  79.                 local _return_ = setmetatable(__members__, __meta__)
  80.  
  81.                 _return_:get_meta()
  82.                 _return_:get_tiles()
  83.                 _return_:get_entities()
  84.                 _return_.metadata.loadtime = (os.clock() - timeit)
  85.                 return _return_
  86.         end
  87.         ,
  88.         get_meta = function(self)
  89.                 local _handle_ = io.open(self.file, "rb")
  90.  
  91.                 self.data = _handle_:read(100)
  92.                 while true do
  93.                         local block = _handle_:read(100)
  94.                         if not block then break end
  95.                         self.data = self.data..block
  96.                 end
  97.  
  98.                 _handle_:close()
  99.  
  100.                 self.reader = Reader:new(self.data)
  101.  
  102.                 local m = self.metadata
  103.                 local r = self.reader
  104.  
  105.                 --Header Check
  106.                 m.header = r:line():trim()
  107.                 if m.header == Map.header then
  108.                         for i = 1, 9 do r:byte() end
  109.                         for i = 1, 10 do r:int() end
  110.                         for i = 1, 10 do r:line() end
  111.                         m.version = "legacy"
  112.                 elseif m.header == Map.maxheader then
  113.                         for i = 1, 10 do r:line() end
  114.                         m.version = "max"
  115.                 else
  116.                         return "MapHeader is incorrect"
  117.                 end
  118.  
  119.                 --Coded Information
  120.                 m.code = r:line()
  121.                 m.tileset = r:line()
  122.                 m.loaded = r:byte()
  123.                 m.mx = r:int()
  124.                 m.my = r:int()
  125.                 m.background = r:line()
  126.                 m.backgroundx = r:int()
  127.                 m.backgroundy = r:int()
  128.                 m.red = r:byte()
  129.                 m.green = r:byte()
  130.                 m.blue = r:byte()
  131.  
  132.                 --Map Check
  133.                 m.check = r:line():trim()
  134.                 if m.check ~= Map.mapcheck then return "MapCheck is incorrect" end
  135.  
  136.                 m.tilemode = {}
  137.                 for i=1, m.loaded + 1 do
  138.                         table.insert(m.tilemode, r:byte())
  139.                 end
  140.         end
  141.         ,
  142.         get_tiles = function(self)
  143.                 local t_ = self.tiles
  144.                 local m_ = self.modes
  145.                 local m = self.metadata
  146.                 local r = self.reader
  147.                 local c_ = self.collisions
  148.                 local stream = s_get(r.stream):sub(1,(m.mx+1)*(m.my+1))
  149.                 s_update(r.stream, (m.mx+1)*(m.my+1))
  150.                 for x=1, m.mx+1 do
  151.                         for y=1, m.my+1 do
  152.                                 local _b_ = stream:byte((x-1)*(m.my+1)+y)
  153.                                 if _b_ > m.loaded then _b_ = 0 end
  154.                                 local _m_ = m.tilemode[_b_+1]
  155.  
  156.                                 if not t_[x] then t_[x] = {} end
  157.                                 if not m_[x] then m_[x] = {} end
  158.                                 if not c_[x] then c_[x] = {} end
  159.  
  160.                                 t_[x][y] = _b_
  161.                                 m_[x][y] = _m_
  162.  
  163.                                 if isIn(_m_, {1,2,3,4}) then
  164.                                         c_[x][y] = _m_
  165.                                         table.insert(self.gradient, {x,y,_m_})
  166.                                 else
  167.                                         c_[x][y] = 0
  168.                                         table.insert(self.antigradient, {x,y,_m_})
  169.                                 end
  170.                         end
  171.                 end
  172.  
  173.         end
  174.         ,
  175.         get_entities = function(self)
  176.                 local m = self.metadata
  177.                 local e = self.entities
  178.                 local r = self.reader
  179.  
  180.                 m.entities = r:int()
  181.  
  182.                 for i = 1, m.entities do
  183.                         local name      = r:line()
  184.                         local type      = r:byte()
  185.                         local x         = r:int()
  186.                         local y         = r:int()
  187.                         local trig      = r:line()
  188.  
  189.                         local _args_ = {}
  190.                         for _n_ = 1, 10 do
  191.                                 table.insert(_args_, {r:int(), r:line()})
  192.                         end
  193.  
  194.                         table.insert(e, {name = name, type = type, x = x, y = y, trigger = trig, args = _args_})
  195.                 end
  196.         end
  197.         ,
  198.         mapogram = function (self)
  199.                 local l = self:invert(self.modes)
  200.                 for _i_, x in ipairs(l) do
  201.                         local str = ""
  202.                         for _i__,y in ipairs(x) do
  203.                                 if isIn(y, {1,2,3,4}) then
  204.                                         str = str.."#"
  205.                                 else
  206.                                         str = str .. " "
  207.                                 end
  208.                         end
  209.                         print(str)
  210.                 end
  211.         end
  212.         ,
  213.         invert = function (self, list)
  214.                 local _tab_ = {}
  215.                 for x, _t_ in ipairs(list) do
  216.                         for y, v in ipairs(_t_) do
  217.                                 if not _tab_[y] then _tab_[y] = {} end
  218.                                 _tab_[y][x] = v
  219.                         end
  220.                 end
  221.                 return _tab_
  222.         end
  223.         ,
  224.         dumpMeta = function(self)
  225.                 table.dump(self.metadata)
  226.         end
  227. }
  228. Class(Map) --[[Class]]--
  229.  
  230. --[[--
  231. map = Map:new("maps/de_cs2d.map")
  232.  
  233. --map.tiles, map.modes, map.collisions - values accessed via [x][y]
  234. --map.gradient, map.antigradient - values accessed via ipairs()
  235. --map.metadata - key-value table
  236.  
  237. map:dumpMeta() -- Generates dump for all MetaData members
  238. map:mapogram() -- Generates a graphical display of the collision zone
  239.  
  240. map2 = Map:new("maps/de_dust.map") -- object map will not be effected
  241. --]]--