nonogamer9

teest

Oct 13th, 2026
35
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 111.10 KB | None | 0 0
  1. --[[
  2. PETSCII ROBOTS - OpenComputers port (single file)
  3. Original PET 4032 game by David Murray (the 8-Bit Guy), 2020-2022.
  4. Port of the PET assembly source (PETROBOTS12.ASM / BACKGROUND_TASKS.ASM);
  5. all 14 maps, the tileset, screens and sounds are embedded below.
  6.  
  7. Requirements: OpenComputers, GPU + screen able to do at least 40x25
  8. (Tier 2 or Tier 3), a keyboard. ~512 KB RAM recommended.
  9.  
  10. Run: petrobots [green|amber|white] [-q]
  11. -q = no sound
  12.  
  13. Keys (original PET layout, arrow keys also work):
  14. Arrows / 8 2 4 6 walk W A S D fire up/left/down/right
  15. < or , cycle weapon > or . cycle item
  16. Space use item Z search object
  17. M move object Tab/Home big map
  18. Shift+M music on/off Esc / P pause (then Y = quit to menu)
  19. Q (title screen) quit to OpenOS
  20. Menu: Up/Down + Space/Enter. "CONTROLS" can switch to custom keys.
  21. ]]
  22.  
  23. local component = require("component")
  24. local computer = require("computer")
  25. local event = require("event")
  26. local gpu = component.gpu
  27. local floor, sbyte, schar, ssub, concat = math.floor, string.byte, string.char, string.sub, table.concat
  28. local unpack = table.unpack or unpack
  29. local ucode = (unicode and unicode.char) or (utf8 and utf8.char)
  30.  
  31. local ARGS = {...}
  32. local QUIET = false
  33. local FG, BG = 0x55FF55, 0x000000
  34. for _, a in ipairs(ARGS) do
  35. if a == "-q" then QUIET = true
  36. elseif a == "amber" then FG = 0xFFB000
  37. elseif a == "white" then FG = 0xE0E0E0
  38. elseif a == "green" then FG = 0x55FF55 end
  39. end
  40.  
  41. -- ---------------------------------------------------------------- decoders
  42. local B64 = {}
  43. do
  44. local alpha = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
  45. for i = 1, 64 do B64[sbyte(alpha, i)] = i - 1 end
  46. end
  47.  
  48. local function bytes_to_string(t, n)
  49. local parts = {}
  50. for i = 1, n, 4000 do
  51. local j = i + 3999
  52. if j > n then j = n end
  53. parts[#parts + 1] = schar(unpack(t, i, j))
  54. end
  55. return concat(parts)
  56. end
  57.  
  58. local function b64decode(s)
  59. local out, n = {}, 0
  60. local acc, bits = 0, 0
  61. for i = 1, #s do
  62. local v = B64[sbyte(s, i)]
  63. if v then
  64. acc = acc * 64 + v
  65. bits = bits + 6
  66. if bits >= 8 then
  67. bits = bits - 8
  68. local p = 2 ^ bits
  69. local b = floor(acc / p)
  70. acc = acc - b * p
  71. n = n + 1
  72. out[n] = b
  73. end
  74. end
  75. end
  76. return bytes_to_string(out, n)
  77. end
  78.  
  79. -- raw DEFLATE decoder (after zlib's "puff")
  80. local LBASE = {3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258}
  81. local LEXT = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0}
  82. local DBASE = {1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577}
  83. local DEXT = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13}
  84. local CLORD = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15}
  85. local POW2 = {}
  86. for i = 0, 32 do POW2[i] = 2 ^ i end
  87.  
  88. local function huff(lengths, n)
  89. local count, symbol = {}, {}
  90. for i = 0, 15 do count[i] = 0 end
  91. for i = 0, n - 1 do count[lengths[i]] = count[lengths[i]] + 1 end
  92. local offs = {[1] = 0}
  93. for i = 1, 14 do offs[i + 1] = offs[i] + count[i] end
  94. for i = 0, n - 1 do
  95. local l = lengths[i]
  96. if l ~= 0 then symbol[offs[l]] = i; offs[l] = offs[l] + 1 end
  97. end
  98. return {count = count, symbol = symbol}
  99. end
  100.  
  101. local function inflate(s)
  102. local pos, bitbuf, bitcnt = 1, 0, 0
  103. local out, on = {}, 0
  104. local function getbits(n)
  105. if n == 0 then return 0 end
  106. while bitcnt < n do
  107. bitbuf = bitbuf + (sbyte(s, pos) or 0) * POW2[bitcnt]
  108. pos = pos + 1
  109. bitcnt = bitcnt + 8
  110. end
  111. local p = POW2[n]
  112. local v = bitbuf % p
  113. bitbuf = (bitbuf - v) / p
  114. bitcnt = bitcnt - n
  115. return floor(v)
  116. end
  117. local function decode(h)
  118. local code, first, index = 0, 0, 0
  119. local count, symbol = h.count, h.symbol
  120. for len = 1, 15 do
  121. code = code + getbits(1)
  122. local c = count[len]
  123. if code - c < first then return symbol[index + (code - first)] end
  124. index = index + c
  125. first = (first + c) * 2
  126. code = code * 2
  127. end
  128. error("bad huffman code")
  129. end
  130. local fixl, fixd
  131. repeat
  132. local last = getbits(1)
  133. local typ = getbits(2)
  134. if typ == 0 then
  135. bitbuf, bitcnt = 0, 0
  136. local len = sbyte(s, pos) + sbyte(s, pos + 1) * 256
  137. pos = pos + 4
  138. for i = 0, len - 1 do on = on + 1; out[on] = sbyte(s, pos + i) end
  139. pos = pos + len
  140. else
  141. local lh, dh
  142. if typ == 1 then
  143. if not fixl then
  144. local l = {}
  145. for i = 0, 143 do l[i] = 8 end
  146. for i = 144, 255 do l[i] = 9 end
  147. for i = 256, 279 do l[i] = 7 end
  148. for i = 280, 287 do l[i] = 8 end
  149. fixl = huff(l, 288)
  150. local d = {}
  151. for i = 0, 29 do d[i] = 5 end
  152. fixd = huff(d, 30)
  153. end
  154. lh, dh = fixl, fixd
  155. else
  156. local nlen = getbits(5) + 257
  157. local ndist = getbits(5) + 1
  158. local ncode = getbits(4) + 4
  159. local lengths = {}
  160. for i = 0, 18 do lengths[i] = 0 end
  161. for i = 1, ncode do lengths[CLORD[i]] = getbits(3) end
  162. local ch = huff(lengths, 19)
  163. local idx = 0
  164. local ll = {}
  165. while idx < nlen + ndist do
  166. local sym = decode(ch)
  167. if sym < 16 then
  168. ll[idx] = sym; idx = idx + 1
  169. else
  170. local prev, rep = 0, 0
  171. if sym == 16 then prev = ll[idx - 1]; rep = 3 + getbits(2)
  172. elseif sym == 17 then rep = 3 + getbits(3)
  173. else rep = 11 + getbits(7) end
  174. for _ = 1, rep do ll[idx] = prev; idx = idx + 1 end
  175. end
  176. end
  177. local l1, l2 = {}, {}
  178. for i = 0, nlen - 1 do l1[i] = ll[i] end
  179. for i = 0, ndist - 1 do l2[i] = ll[nlen + i] end
  180. lh = huff(l1, nlen)
  181. dh = huff(l2, ndist)
  182. end
  183. while true do
  184. local sym = decode(lh)
  185. if sym < 256 then
  186. on = on + 1; out[on] = sym
  187. elseif sym == 256 then
  188. break
  189. else
  190. sym = sym - 256
  191. local len = LBASE[sym] + getbits(LEXT[sym])
  192. local ds = decode(dh) + 1
  193. local dist = DBASE[ds] + getbits(DEXT[ds])
  194. for _ = 1, len do on = on + 1; out[on] = out[on - dist] end
  195. end
  196. end
  197. end
  198. until last == 1
  199. return bytes_to_string(out, on)
  200. end
  201.  
  202. local function unpack_blob(b64) return inflate(b64decode(b64)) end
  203.  
  204. local D_TILES=[=[
  205. pVbPixzHFZ6LQYYQJpkYgjWEgiUMNGgOFr48GGi0IGmmqZWGZTIi8VKHnX2rgGTWMQGRRLr4kHNAx0UU5NYHgZ3kaGhLIORkq81ibJ1667A1XR
  206. f/BXMQ+V7NOLKMIYS8mVfd9ft9733vzZTlD8ubm0a+6ZGhHb75/RX/i/zghjculH8u/2/59Jm0JydlWX9Rl3Up3/KL8gT6X+QnZWctl6X5ttPp
  207. /VzaX/R6/W6vL3rzvf5NUYze7OQ5FH3pdbrdzuvS3Wh67/XW9+D9R91ur8w73XK3183xnuTChbKf75Y/291FW67vv9y7DGvk9JtpTVnmu7u9fP
  208. c7Bva6uLZ7GYpnnvffy/NO/tOLvd7FixeT+Ri/sNHet4L3blmKQetzxC6lYrAhxEhxFQM6K3xCaDoxroKfzQzNPE32iPkGi2ItR55znNN0yoFD
  209. MLyCMNEqYs+KA608lIIIVc10ugPB++mhcxiNRC6EYtZUTeUcun9hRaRqnJDRX2XTiEZyDRvH2O9wEfZsRYwFlU5drSoYs+LBIELDV09v8BM3Py
  210. 3q2+1QKcqmnN25c4egHSiOHwyIB8wDTJKb4qIpZRlNh3SklJcTvSVvbUDHiztCPfPeBtre9u02UUueeZ/Ze+ANbOeOrYNLGKvDGTZa64yxzjmL
  211. sZYpqUhb10QHELmj3yeMmiODdjYW/FUT3MybIc2MZ3obPpRNl/aME/wPMVY3FR1hh9k6pP/gZyf4/eFgIBqefr7P9XPfzurbpGh4ixSPCSCvzf
  212. AhYlIDgGfWwJ9RtdijbIHpbEiUK1WkOFkaCn4KlPBTRxHwj8fkcdSSSHvvcabYAOCkES1ijdXBk00OcNYee8HvuQ1L3yZLlw3W3dj5g8R/xxjZ
  213. b6lCW1TNIeYadMlLVCgd79fx/2gEkDqMmBosuv++Jbc1f4XfWXH+AKhEw1PYZpcDX9ScHADLMoVQq0J18EzxZyVrJf61uOaPEn/I++C/idYK/0
  214. 006FhjvVL1LEZjzJUrNLsCs4X/ByCkYawF9x1HxH/KysB2w0mIwX+2x47gC7LeGvCBJP77EHjIgAhTthH883zylcQfGRDJwLOzoWFxwMq5Ezfy
  215. o1EQTzrO66bJj46iF/7jQGXXUvFiYTf8N0/qA/7nM7OJP76KZ6BuBp3QNuLPCT4vWJKj2aE8O9zE/x2FE52cSPJIHaeUqTJ54+mc21+xa8kliM
  216. 4xFrFlN7fuBQaUU0Y7kWNPLrHAfdM6D6XwzWdflm1Tnb4QkfTQmnbY7gPmAYfxOv/PzqZOq7fm9FtGnk9XDx+Hx5euA//jNf6mcTkzzN3y9OjR
  217. I/XxJ3/7+z+cq7TWTg8GVtQ9Z372L7cqvubbaigu4F9j/jfQDJriL6o1+J+d6b080xJ+PaR3kf8wO67z36KDB3wyBKVeWr5+XS+va70kDSI6IQ
  218. wWeXbCV038e+UV+Pvy5cvPMPQlwJeYXx4bu3QmxQn8//DDMUTqHvJ/ASfdJUJ+b/jvkFuobuMDOejHey8syjDq3yhEptWIf9c0w3w8RrZtsdyt
  219. NrlGiwV7sFoUt5ydPVt6h/i34Put+ZSL7W1UU5SubdrmFHzowSDF/wHin/L/QcIfiw3/KQ5VRCGwdrGoUP/hyMmErkyAGvwH9zUcG5EFUbgO9+
  220. l7spjSnEjivzDp2IBNUewlJDvtoADA5h3wnxzG4UVX+EWFucpG8YZ41thMGixE9fcnqP3GaZmgu/ejBf8dZl/xH3FP/EcdeGKRqucDg/p/W6nh
  221. rankv6RBQev8B3wiKRUp/x8A+58k/4H/LmK9jhRZE4x0kP/Ab2xA3l+9qturWhvUu6pKJQ/cP5babxH/e/dkr6BZ174kx65F31hqJf9bqj74YA
  222. Lp961AuVFZ/8uEv1rjPwf2sE+FGsJR9Panzj10l4og+U8orTPZNJkI/y19N/9R960o8Bv7/Ozs/Nw44KdU/6Y8uaauZdcKeAD4RRR+AwaHqf7v
  223. oP4fvqr/kugx5X/Y5P9iYZDMUmWLQi8LZBrAOmngAPzyCf+thF9LzdD69fwH91MFTFVlKfaPx5PJ6WlEKpLGaCb4TbWADaTPsaJGSQAzZKn7KF
  224. rwfzVaRUL9p0IGi2IO/O41/iOYTrgPaPZ06dw5bp7hP4RKjOFU3OG9tckogCn+699/LX80JP7I//v/Bg==
  225. ]=]
  226. local D_SCREENS=[=[
  227. 7ZdPa9swGMZRXbnWYlvBUhZyez+HTmGBsbY00ENPo+wwJjCDsdEvpI/S6zYi2sOOZYcMir/FpFdOE6cmMTTbwrYHZMv2j+f9Y9lxAGD6dqnpO0
  228. BVNoxVzcyDLNScNmGsyghJCglHJKOm5iptjdHWrnE0pZGEjPRrrjJzZz63TdAcsjhm0SCVo8BVOsjaRmQT8VwWPBVuipxWZ0qpqdLGrJZkl3XM
  229. pljExeRMTSfHgWsrqS72xfkr5YY25Sr3cTweX7ki3rv9B+ROXp4qNzSWgaU7rsfSFIgbySAjucBLQRg2HJTQGvjGq+ZC1EmbFlxZH5rJRLVp0T
  230. 93I/HQqHZVxtzf+HZZs4mrfCvniLVwlf3eDKv1t+vPePxwxWPz2eLG6HOkzvWdDa4zu+TM7b1e111o4+19ueTeGKvW4365/uqv/CgbzTC+AIsb
  231. P/RiUhljmxyuOR9pdVL6scZZt9jdRfMwqc+2+pmF34LTjQbWJ4OR8yv9JGT9iCtVSAdTCpt6D9t0OaSkz/PtHHTTvnP+aXXq4MckzeB/Xx759e
  232. hI7HN+v6R/VyyPeZERyXhep9LU6675JZSkMtldfp9QFz74FZGSRD3gMciEQp9KETEGBT/gUmDWxx1tL/9GTkQ0JwXjagd+NCV9QQ9Bsow+1S/c
  233. HyhoRljO8qMn+gkaFXSHfrWWX2PqH1kvv5M7GXfS6R99zvsFFQJD4m/AiA9gyEQCksNA0BU/96pELOZpyoduCUI8yCP/7hR7cj8y/pzCoK82c0
  234. gd8mHehUtpLDdziBXsKNnC+Q6yokN+SHXID7nt+SG2Lb9oFKUUwlej2OgXSP8ZJbbV65ePBzdwgpIiSoAfPHN/Hjf6YZs7cPv8nP8E
  235. ]=]
  236. local D_LEVELS={
  237. [=[
  238. tVl9jxVXGd9d9m5n8BIWlmCjrWIXdtkCxYIvhRbRXTSkYlOamCbGWGv8Q1RMu2mJAq3gFqP/adLPoMn6NdqkTe/OnOeZvV3Aay+QkOi38Hk7Lz
  239. N3lqWxnnvvnJm5c87veX/OeWZ827YJ/Uzsnsgntu0aq7ftSZt+ZGzs2rVrK9ffufHHG3+4fmOFPnuf2v+luSPHT5z4zvx3j/4gP/1CMnaV2r4v
  240. 07/Pnjsz9/LTL55/fmz11FMv7fnWD585/8L5n53+9qFTz8/t++Jual/Yd7wzc+LQjvn9zfF7qX3+4Nzcnn2z80fGVncdOLB/7rGd09OPnVyY37
  241. l3YXVs88bj/fk4tbHxsdXxsYmfd7Ptk91Ot3use2z7VuM7SeNbI888DP74Nj5O2OPjSo8cxx6Wfn+LphrncTKefl3RzBQf9mz/Hh02G7/K16Nw
  242. VWjDcNajVn2GrVdrD/X4/w9+dOrh5vA3by3dohYO9Lv9P8K3seZKBEcN0KGjRxyAA1dBNXAjjW/Rw5UMqKhDoKdpDu5ApkP6ly/oh86NwPPDWM
  243. NnWH1YHucOsSKcgfvnhnyc037DDZBn5hFCBuPSTy55BFZyRQ8QUXQLW+BtZIJfMiIM+Q9h3ymTbpR/GBBvguNURsj88x0SF1NGIkERn9x0qfgd
  244. s+2McjpXGniEIqKyDwpEf6f82wndAlaWKIzlXmkvc4IJo7IpABLpC6yQrlhBBTS48Oz1TPvya/APwujAVTKBYMhTclbJ1OAPrFBkxBTez2OPVy
  245. 7aX2XiYg2BiYPaHTP9u87dM/v/hKXrhG0vBL5WOkCkpjJBp8bsZd9sVco/mPxU+abQyj/pXFHaSWRCNKxiEvGDsSY+AIwPdXzxk5SAQMKSzrhk
  246. xgdqR5WYssy7WMKi8QoQ1BGoM4KUbcUn6VeJ+mtDVH+YyP8mS/nWbad0JvKxy7IsnOcvnjhvdM5/2S9BlYNCTMCHVHTDykKIxx98zG3gxPi9YV
  247. VV6YDkXrgyGChEOXuTNGrBDAI9i+wkmPIPYLbv/S9aQMQ3dHBlQTyXBZQlw5cuoKbHmj3IpOhnZ2FgMH81VQwEiLoQN8Mn4Jq7pHgQZQ4NSlKi
  248. FMvjQxALmnvW+L9zt7hHrhXkL/CTr73+2uuXpnzX4T50dKvT4bvcdTrX6HBp6qtPH5vsdH7U6UxtN1EE70cXTU87CrvR/kXAS6IoEQBfZm+8+c
  249. abee67XHrf8a2c76bta1//RraQv8L3CR4T//f5Qsmi/0itVYgBIAnACfsCL9LPnjuV58+dau/yfGc+e3A+44P+vjmfP3OCCXolP834ghT1j951
  250. kd2pLGvxzxUa+3yYIvmjM95au66QcJguZ58l7MP6W85P0g3hf9EtIX2T+ANorBOzaLlTwDnTliH2q5ToGh/E/2RnKst3d6au1+SfMb7I/8x94T
  251. +GfzYs1vqSwxKFiioaAPMf2ScxFW4L/jPhny+97LlflhuMf5bciTy4vPev0O6q7jmSIUIt/pK/1ZOE2H9XWW3tCPxzZAFe/qaD7CDT9zLhnyN8
  252. CiBFuRYb08OBlEWuudsboHNrvWD73IR/cqUXz7/EC/9ax8eprhlBtyb/7mGVD9nff0T+6GoCEB2ozlHyFPgV4lovjf0kDxpbn7veppmOH4edyS
  253. 6yBe1tENk/21+agWV+VJY1Xyfr0zVXy9Hif5Nx3timHskf2KZlzFSGFuTS9acGTUtrZv5GWJms+9g4ymh/jZaxeNNPW3s0c0ZATQJpXiXZsy5k
  254. TcpwgX3WmoSjbJZn9wC/v3z58qsjEW+Txvgx1KZBwOdctBN2zIrDrc+RkkFLjhWEn7Qrp3un32IbezAypQDWksS/EO7rqxATAFa6FeBAWLKUkt
  255. UJh78G/1doPONPNuxhknLPtWgVlALyfGElM+YRU3xNbkMTgK4/hkxDEfi3RWWp8m/hn3y8aQ+pVigFnMzz+SzqcoR/8BZgkuB1jsf38cfiX8L/
  256. T69evfo2Ix3OHxdjkPYqR6BDEvlCCM5T/Kb8we99QvynVti+K64fChrZrukzOeFf8TO+lV/PZ4/OR/7tZLm2OEo2QC66oMh/yFQwu+Cjv/DPEt
  257. lBawoOdpdqTn82xf/t75j/4zX+D9Enz9rxMVn5h/jvhP8kAIHqn7aDjsK4q5vCuQb/Df1n+VH6bIav6z/werf4K/pvCYBkvoS/5Bbd8mxqbw38
  258. mv6/nx+nz6bydz71JPyr/hsWQB5o/N+v80/2/7gYo7S3m/o/K8dfZdH40viD5pDGv7HP/EMigHduqAIof/Cy+P5SGoopxzX8r6b/cz7/uBABk/
  259. iLxqDhy14JTf4QCPjTn1UDQ1d8rO2MxXqyrMlfXLhw4Zd27Fgmjvx3KfisrDyZjQpf8x96AtyI/F0v3X7RpoMWEP9W/LM2O0v61xcvXvyNHReO
  260. UDxkH5kJ+e8vf+UIOdMC30u3CQCQ1n/k5j1dJRkBtCQfOlQCzkX8v/2dT/SYreQLzXz07rvL6/029F59m6K1C5Y/Vljw2oi+a2vEtNOdV1moC4
  261. r/mfzJslf/wSh6JOwnMwuSLIefcDrozPTXW9C99Q/j/hti/Uc3eCYAT2QhJshtObW33bTE8MeFoHnaeHjDM8vvjcKL9w1tkW32J/WvEiU3J4tA
  262. tF3AkD+p/TeOWS3wLkT8NnhPmmxFquAHvOEBo1kdx3J3GeTfWGDZ0owOMyb/hH9EbJc9YgwKaQXOhf29Vb/Q79aMgOWtlzzZE3Oe/9rOswGPcR
  263. ud4tuWCEKM9Im49Pw/usWX8L+i/LfDJ/imYPN/VPl7k2kUFgoRQXdr/rtPzB0w/Fa3Rx8QrbgnRVrjv98v+xsWAXUFGEtwUnvZIZv8B/6szTTx
  264. o91B4v+AQf+u6rP7F33nQvGxXlopkrAV/uNUggPUNlqnrcXcpGaX0ODrT8Q9E7Bh4rcqUaj+SfFLngDu+ZKDFbUSB++9b/i4KT6m9pTWbHz83+
  265. hL7OtDGiN5ZRRMhYOiFKGYDEEvUcgYfPAhfoTvvT9AxLrY6viNUhH4ArMaYJ8zjbHvSxRDcYtGgQn81lhLKEWh8v/gw0HI7M3g5zB1KKvdVVp/
  266. 9hbQ36CP1AoSFSk8NOAXoSwXvfpLwlcFDKKFNZfcECuljRJZUoDCNP2DrysntU6tfQf+tQ7L/JMCSAMDB55JxJElF6RZD6L9xfoPWVzldwBV0/
  267. ytvyn1b66Ea1H8NuHfuXXrLkrlLlo5tmy5atYXdr/qgqiWbtYn6xKzF2i++Kl54MCJLRZSGgaMQgZI3B8SlaZqiG9gQOohshNORVUfhIy3vt6n
  268. 1A7r0ugaxSsldQPWBqV7fohiAf+c4of1f6URuwrQlVb/dY1iKXPJJa91+LomHnRtKz7xp0XN7ZTHzaSHamBmfiZ/Tn2VldFVLv59msQjfvGy3i
  269. cBgFP+YQAw+lLDQT310OVCtH8pdUUPc8n7t0r4R3uXwaWJUKaGysV3QeCL/m5gNWWoleWhDh+k5fF1By4L4fQFJAVjKdKiT4xshYjpa4g7/kWo
  270. dZ+Yz+nrx2qoFLQtemRSn+y862HCv1VCtniROtz6Tu9Tvmp+IP7wYUj4rNBH8Idbjxh+2vfMLe2/
  271. ]=],
  272. [=[
  273. 3VndbxTXFV/bO8vc3UnWH4AWhzQbr2F38QJJ3LQEElmKE4ICVaB1pSgPVVtVVZwEAhtwJMCtnYU+tA996kuQ3IdIoCRSFJw8pBVO+ilaQHhnRl
  274. rZloVpIR+k/0TPuefeO3dm7qwdlahVz8zOzszdvb/7O5/3znSwnt7ezq5OkK4e+HT29nSxHviGWymQbLYPJZtdl0VJNaanfnH2zNTUmenpM2+c
  275. PfvG+g3jx8cO7v3eWGVD94mfvlr8fvk7L+w98PqPx59+vor/LzywZey1sdc2DPQdefa55/amBkrZ0tDrP3l69IXRZ54fG9q24f7K1lzG2dhfrQ
  276. 6nc/3lwceqjwzu6N+0rnDvRvz/xm8Uu7t37CgO3PeQ4+yqpO574NGtW+99mG3ePLBly67+QmoV6ZDfXFKp/ZtS1vpsZ4eTzeazecda7f+WFDpL
  277. fVXpSHV0dqWtrlSqUxtShxjSWnoI43am8F/8n/z/zv5N69dnSfg3XO0XN9bS+7X/QFJ3Qf5n8BcW1ypLXwf+wg13beL7N+UIeAdp68Xxl9LoIx
  278. k6PXosQ5ebqHkCLidmrQmLjrNwPWFNTVBzSpLn8L7neXHAKD6MYCnAP3/hlcNH7J+fPHnyR3R6/ASjSxub62+eY3UWFrqua/jLouMAxvNoLHiT
  279. BiVa8Wf+coD/zrvQl30KLif5aY49/gRdcgC7VoZb6RfHx1FLU5l1bITZjBXhPwE+Vz7HV/Q91/M9vMPvyZHIEZACeAcOcnF+ePr06Z85kiBdEn
  280. 9+w37l8OHDR3J4xvmXhsoaf2l7XdPAnuP7vudKRQT4pABh/x7Wa8EBjQ70ekW+6iGCzsw5lmdyZHmOn2OlnWWN/zKn6+nYePQFpFQ/v0CFhPBt
  281. SRpPtud0M/PhgTvaODbulH3wqwI0IX5dx8cBaKr3FKxud24Hugrw68D46DFAcRoNwi19u8w/pH9wxzpsM5XzF4pFGmWelYYj/F1Xp6/bwdW8Eh
  282. UTxccOj58AlLR1EfUP+HvK/MMB7JkK6Bs0vge9M89y5P+DLMJfH4Aunh4WQXhq/JEqylPqoOu/XtojLs9fqHD2I8IbIvxJRrUPB/TDYenG8G2k
  283. ikbdh53iocC4T2ZsGR551s+2b3/n3Rqwz8N1N7eXET/KHsPQAK/hq6A7oA5AVRFEzwP/Q/9QXkr2MuM/6a7wbRXR4u/oMR6BgDLCuHunMzwRCf
  284. 3z/Ffn/mHNYgSk0UmqYf3H0+5om09Y/9B1wAxJ2m/D8fEnhP/x/CczD5PNMIIwvkdd324J+bQNefixhg9IDPF4/0Dy4sFD72W42oP8x1ilbFPz
  285. bKg5rP8n3VZ7+VSGZ4D/0MOPWFOWJfSfC5IREXQGB7n/1UTmE83FRtVof4V0x0T8i5aoTBr+Nx/9lqZ/PRlq/tdtzWb0dnswEn9N3v8K4o9giI
  286. KmoGCLT4aXr/GXsm4rbv9dj+2mPnOU4CV+oyHrbxFsUCwW7VBzFL9J9gd8ExssX1Da3ZYh/oOfwbCdAiuxMisofHuP1DoeZTN8R/k3JX/q6xkd
  287. n+KZGfHrbIjhTty6QWEXeaHpDfsfCTbP6uXRYP8RJhMZY3wewxjFM0vgv3M37qrGSimI/FfFkQHf/kh7kv21bMZOjVwbmYRhv4/lPWOb7K/w05
  288. YmKv9S/aXQxLRLs0PVLPDR/Cb783mUuFGtJuh/mOFO/6iUxa7y3/ET1Trnb/O0i4mXFSvszXNG/X/RukOTV5onCP4s3QPuU27vf9PoBZDtaJfx
  289. H0S9zX75K9zgZKYGPzHn/5ZrD2x9UPLn8zjJrdoe3y7tNBhY+F8BR6H4J9dfwt/CxDwJZUhZw2j/OpSSBtaTabRCTP92JYh6xR9qUqliwh8lfE
  290. Is0BBgqgZX2xjbJvn74fpbBXw4cP+P6d+Bc4qMfsnfwfaZWhy/SfyrspCRoG85Vfbyth0K39fwN1tJ0kfNmENlMp3Qzvoi+DwGEF9EC05ZDx76
  291. LlTrdCZNMxYT/l1Y/y0r9ojvcP52A6azVNKrULFRcVVhf/9rwG8Se7R/2jp46AdWn8JPvw8VmzIG8cclyV3H1/y/oVVRraSr/OuH6m9aFUk8yQ
  292. RZkBa4H/0uSX6fEH9axcjJ4KWt7hrqvw2uzzfym9xbb/1WbNzBL83NfXYL5fO5iHwcwad5bog/00t6EP9eOP+ycMX+9W9oo/i/BPD/ArQvYwOI
  293. 4PNpPtpfraMEtAMVm3bp/yF8CleFnxdRLifYl+YAvgXbl7cQ9CrfzfhC/7BK5xPqKTGlwwmemOEl5V+R1vQsDzcEf8BF/Llbbfn7Ct8Oz+KYmu
  294. Al1L+qXE/Q0j/OH/BbUfwrcXxa2qL/lSq4S3yc4NEUp27K/07Y/pr/20b+ly+b+Iu1Pc//rFTDHRBt2e/wbtyN/BEQ0iROuWTeajA8NKT+P+f4
  295. nyn8yyZ86QGa/neWI/FfF/HvGv2fRfEFf/J8igJdATp+U3mApv/hYBJM+jfWP3s1fBgACsL/5a+B+aP4vop/qX9h0rzQf4L9o/iR9f8l3ev+9v
  296. cE/28KeB7/QQ9OuBKr/B/WP06S+TRZpExY4HIl2DF8LunMJ8b4l/n3nkilDi77zPEPk1TIyJPBMN92YvhXA3xoNuA3RQ1qu/C9bcZ3r11b8SZl
  297. +H2AC1zQgEH/c9D8ITZ/EuffbIYXoEa5Y5j/sVOeBwqY1CsWumFM/6CD/bLZUH9E/TcsfOevx57BhPh7K4o/a4MPsk+6Zjz/+DL+ggeQ8rHv9X
  298. nf155DeTF8DzxgMlQsbV3/IuyA/4FE/hKgFTyKU88956/jKLTHcK4X0r+74sllklrg6vyDsFPL4xg+rtOyEp8/cuZKoFHBAIISxR9HR/iDBiYj
  299. 6V/lf13+DPc/xKlxDB8fI+X80dutsKkJ//q8hs8f1er4uEiiZRIoFpYWM7RX6ub4N9ffOoOMix4ewpdWmY8+H0/K/3ZtEB+uwqFUM/BXCTiG70
  300. DGzcvoCuEvLP5jfv6f+OJn2Tf6//1M7NzvIuu/ML6egMP496BVmtG3LfxRvyvs764BH5//woSpB/jr+r+yiv6b2gosjL+weKMpm4z49RD+vmDC
  301. VLO/iv2bCS+7grG52iuyhRsJ9e8AnzCx3VH9Xw2VAO4HAf7NpaZY/xheti25SfQVvlwfCPvnOHyxnf+jHwT4NAAzvn9zcVEMIcAn+pH5H+Uf5X
  302. 8z58z6vxLXPwxgcamZ9LqRe6CODy6hvX/cHFRrXqyDc77A/sMfk+RPofefN9f8+lWi/5+9f/4v4f8b
  303. ]=],
  304. [=[
  305. tZnrb1xHFcDr9e76znoXN9mIJqWtaCzibJu4gTRxGydIpKAguagxXxAVjw/wgbeSVV6EDyR1gtr/gvChFSAh+MSrLW+Vx2bunZnGwdTiAgIp/B
  306. fMeczr7t04DjBe767X987vnDPnnDlzdmpHo9HYIURjugGPxvT0zsYD0ej3+53OjH3M0N9rV65eu/LS9etXr1771ktX1670z33s0YOfme2eXdl/
  307. cXjxiYWPfOjk5+L7L1164flPnjrZPXWK/t79+OLlsydWn+x9/tT5Fz/44cFjz3T3PHak1T706KHWwaMPHj52bPfh+P7FZzvvOtJ9RMz26O93v/
  308. fpA0tHxeKRpeV296H39B64hzE1Fd6vTHVnGu09zW5nptXurmx5bwuGfY7n2M5oTE81pq0IF+ciecLrlrNOT0/j68zR5P4pVmuqu6vT6exaWen4
  309. sauzHflG/89hYGh6mTDuear7xZvRJL7eBn8bkiZwug9fyzG+jmdtti60LrQ7qn7YK5XS9seOe6FrHI6vCQefwFPzzNkLrXYHL+DrlRquwRjWs4
  310. 0iPg3tRsyaMHgB4G2Jf9mX7Nx5cfxEBtIYh1fZmrAjK4p6Ae6XbwmG+SSNfR4CSQxT/hD5w3rro/r1fM0WPXO2ZVcQlhA/yfM8XGR0ws+WBOpv
  311. nP1V0H+S/eOhYwHw1VrU2pRGBnSJP8k1vP5WgO4yXef9H1Sz609GqV3DWtOGmYfzS2J+/5xotmdgilxeuw6P3F1lorm07rV2iJ2tvon4yn54ev
  312. VTrX4dPdyeqj7yn2TzB4RY7j6Rfbc7yID/8iu5fXgpWYGSlTE6p3kj+9vFzaWKMIpfvfYYgGN8/Ig86sEfnl79QRv5aH+nf2JApGqp4/zHS8oL
  313. ptWYsjoxQPAAxTJle/cJEdYf7S9zb34d80n/PGQHz89lClYTQooud1aBy4Z79z3u+ENQ3xqf1n80quiPBmD9dcKXxHeZOWJQhFFkKaezXxb729
  314. 27733AnhdiIQO+BBeQLvqCB5VOfznG9wETpjbB9yBnZalfRtL1oEo4vfppeOnbmdABpHROAvMouKNkq1v/M+TYxKeMIZ2POkJpnNQ6O36iyo8F
  315. 0HodB3pd7jWJFl/RG956JN0e8aVPWNVFQJt3ObM425BpTMhGxM+Jzp40crHPWcuw0hZGAE7h8E9aET+5YVLJFunZlNGPotF4qyb8an7i5Mtiuo
  316. 0XWDra/5V9L/MxkybDJXTnGmyLiv4VerBhxIc4c9u/4xsDJjOTBfA2jTNyCKvnHP+5RPkk8Eq+Q+bsu55v9zcX/RNSfRQcXsI0PVT099Xf2E4C
  317. 2jvzOb4JfA73Vqttf1svUp2ipYxyz9u33q7ylb4D+H9Hyo/TS05ysZsxP8q+FO4D6+5fFuKzYpDR6kdefMvcInyThAQRUYAKvt6ObGOWMPCB4W
  318. /JhFi0v5Z/LAv6Ez9ob6WcxaqNPcCtfpiz1olM8A72v4Isk/vlB3Ym1sQnOOrJ+VVlR3j1tVBygAfEO6PRRWXTUFq6xOVqZF36/dcWWSQAlUji
  319. oMiiyWPnD+N73xdzwlctzPdFWZEIoLwHm6C/NhHfxiBvC3ZDsbN2A7/ke8vgdQDptdog5CCr8InOfJcipbOeCVWJy7+OT5iTlO6aUCW12lX9VR
  320. LdIOQgXv9QlCHf1Yu2tgn8MkQjTlS6QtNj/mmDyap27ElSzur/5w0af0EB3BlH906vfpyrNtS/Wo67minXKvUepeP87xdAX7vusgkUVU/x+st8
  321. 853b79iH3uSq3vu4Tzp1fFYf3JfeeSnsa7r+BfFffsXxZ63+T3n/2+QZN7UXwCRuX68/B56u8EvmR/rbg4+RbgGAD8532OkvN2/fvq2tATZ1pT
  322. ZZX/+XDuvv+Imxc2cKFf6R2r/Ac1cJVatx/IfR/QfO/qn+IRDurPsR6R+fUxRppar5w4RMMHIHG4nlAyZTLKpa5Fy5/NvGxt/1PzY2/uqVc651
  323. p44fu5uSqvKJr0PN+Kk5l1EFEzLneBle3QKB7w87CCti+9cfq5zysRAQhzIQ+TRRg4/5tP7hrMMpqHDuV4eP80/ci9BYQMtcxudIGdVUTtKq/l
  324. xts+IOn+fjZYVh/4347AHjZ3qi3bxbswMvuMk53ZMLt69t0X9yDRbnILWUm2OCVS+46YsOn/z9tro1H3bACVPrZBFVxb+d16yv15WPeVT4Tuaj
  325. 9mb8wFekE/nD11gpQPwKPoebcpesJvcfAY0y1DmJrgYRb6fkmlCW40+Oh66cXBcPIfgc+fpd+IVvsVUOWEEAO5MsJCUHikcpGeY/zV3u8NfoCr
  326. /5hS9+CTp90Cjak/C5w1X69BUdBkg1jESJupJlq1mpLlNV+NlXvvo1KFl2Q2ET8w13uHTEx9Vn5ehMWeTxAaC0/yy5rva/VukyPcbGfKgY7b4K
  327. jaJBxFfkAXGGNlyUsxHRmBxUtCZFfVlYp7/xfFsxwljDRlHML/CR8pX+5uXLlx/C5oOtxc6c5eae4exmL+HUUsN3DQzjTn20/ragmxE7f4SNok
  328. R/bnym28M3RqNLX6fmgxDwlHk+4qFiNP5gr0OlnnS5deAP9y+g/bFqTvhKqbTBxfzRj117S8wvLQx9BVvQ9Fgv+IZ20sWpCED+d0CERlUc/9zi
  329. Tfnm2zdu3PgOVePAX17I+Ojvr4AFSPhkAGMOvf8DLTxE2ojreD5o8jC5/+5I/yAtm4HygW8+2dVv41PmO3ja6x+6KrgQ3Fp7+shRkPnV1yDiPP
  330. 8Rin189D2fwaHRS+Hv8w+eszJ3GOG0UCAm7G3aH+9xAZ551hbvQqDDZ1vkP8Rih82L4OkwJU7SPX4Ci0GXleh0QQdKj3cGkPIFLF5Z6q3yLzbA
  331. z50fzEa9bpcE4ZCB9oKnvuc3sdeuKuHOBrA/HyWfmbVnqHbg/+SnYfws8G/BFwBweaXLrtKWZ9z+gIbcYDbuiyTH7Px5gfanEtrzX38jjDdT/c
  332. G+M8pX6aqm5RrviBSTgG/6xOTEA78Ykv3nxNpawv/t74DdbP8i5hfWAD0wr7e8VtGRxbd8/ddWBr/EEHNg6lmbmPZniXj2hWO2m67/62/8/g/A
  333. t/k31b8I4aej9dd15QZSussLYhF6vTlkhgMp377h0wMdIar2/43Nvz8P/FHB33H58NNBc7J/Ud1OeuyOWkctiKSDmTbd77b+/tvCkIcnrH/cnH
  334. V/usCsdK5N2q1N+G+9VeGPxr5kGvvyKcoMaXc4WGJS89JE/D85Af74Zvr98za+C3ardc9DO/4vfxXGr/+L77/NfYz/6ffv21N9Mv8/
  335. ]=],
  336. [=[
  337. 7ZndbxRVFMD3Y2Z37uy023b5EAEtn+lgIQEMxFjQBKImNRE0BiQB5E1BpB1g8bFQ8AFeNOHNhEeNmhh9s8oS8SNVaGc7d7HZbsbdbRMSnv0LPO
  338. feO/sxs9uZWYpNjGezgaG993fOueece+YQjcXh00v6CInF4pIUj/FPRIiqrspkMkl1VY+aTMLz2PiVq9eujo1dvvLx5WtXr1zr239wYMO+/SNH
  339. R0ffePedS+fe+ijb07vh4JCzfqW6zugxzo68evzt02fxOXH6zPnzl06dOjG0/sVXX1bX7Bl4fu+657pTu3clkz3rnyXJnWpmaLC2vkdbLZHV6d
  340. QzqczubnhOJXbu7N60hsiJvS+s3bY7E/GTaDQiR6LwETIsq5oajalyXNOUeNpvuSyvlWU5Ir8SkaPRSCeyJxaNR+JHI7FzZ+Ap3qhaJBJky3ic
  341. L+reFWlegOs1FWXF8IrhYbVRgmo39S/J/3whUmJNS35xTkjpyfKVLzUvH+BlKqTamQKwhSTLWXlMziYkOTuWlRPsWU7EHD4+f3fo8DeSvGLlKp
  342. n7gS8V8ErnChRhC2WcCSHKtm074KMQHUVx+ArhIv5UHL5NdcsScAv+ZnfAt2kDP8UBKbJd367rhsM3iPPvm0Ea+YDlHpASKu2QX6HO/i7x2E9c
  343. 9ldLQJ5hfIiODvgifGr2pzkgzf1vuPlpl/1TNloPQSN/C9GBMZMVURPC+dSiWu38dcTs0IiOB6C4/e8+f1hvVajSwmshnM8sGBkdGYXrIrODbd
  344. HzyacSPjl8TWytue1nB3Cwzh7oJ8QIaT+40CAXLl64WNtFJzdvGn/SB3ZD/h06fILlJUqmnv82nP5rhPSD4Mpbtz4LaT9LXoVcv3H9Rt0M4GTo
  345. A2q7/K8rnvoDG8y8jlwAd+D/KlRN0EBrtp8o6BRaLLvjz/Dy4Rfhp+xYyEsEv0b4/Jfee/90khH6joF/E8h3qgnjb9zazv6ZGap1Hn9O/fng7I
  346. fCxpNsCyxm3Hzu/41bN7Sxv0F7CYLkzSyP2nAp8PkXtdLH+RCVAs/jf+PWLbXE8/qfaf8UaE1nLTt8/bPoV1/XvHcEgnnAoPVajqx1vLTIGQ+/
  347. WrJY/qP2hnVgNnwJtMHXGmj/dE2FW4NgfxN/kf4DDgC9J7zWCR9YXSyts3B+x7mdTvD78yGD0HtpsIDZH/oOZiVM3GOzs7NOM2Ev3n817qCxyi
  348. jst6rzYRUQ3RM9YCH/gFXP/UD911Sc+S6LXpt9CGs767PwLgf+Q9qQe/79V30tc+IjVGBq6u8O+HgOj5gCtOkiR9b3ExMTv8AN++MEkx9a8MUZ
  349. 4g7T09PtIIv8iG3iKODi387lcpPim8vdu+PmQxai1/jJzbdvNubNvLkwJ42MjrVoE6pzwgMU2ko3/9ffcpOTiL8PXw+f9yGowWI9EBpo5qFewV
  350. WzaUBp/QvIt9399+3c73/k6uLlw+ExeFPktNo+bwIfr9pBxfvCgB5ow88J03PoCS+fO89q9lxL+01uP8tWr6uq88BfKLfmcwFP3Gn1/sXSuOxX
  351. 6fJ5Ku5LpfVReSKU8e/lcov6P3ClRf93ZXtJXzbD+b6p2mT/XSY/d8YvsfgzUQXxwja/WD624N95rPdf1myhAigm0yS/UArOv/+YfOey4WTTZF
  352. r43le1/H9s+2tRWmo4A98Lu57/k0vAF14IzWcyuUT8KRvLYAj+T3cbAn8p+Gg/vjYekxPJZZj/MPsV1u2OK8vCh+hPQct2MvTrwpKIjanHu319
  353. WfhYALBlPbJc9pvONaQvE9+Cpj8rO0OG5eAHzP8nIMUy5J8lWlY/fm28umQz1mKZtYG8XfXj43jSGfJZIUacBZS2O/L6b/n7H35ZNJZigR0UXy
  354. ngigWPxzg+L/CFYtmvZ5JYnLJvQg3Mr02F3R6zwfl4+TOD/PDY2Cs6DgXHRdMYht9yLG7TvCRDA4jz2uJc2b9n5MMvzjcC8mmjVP9qlLJpKrzw
  355. BDlMm1oKG/6Esl/io3wZbYTDnm4U8D7wcU5I/ZzP7Yc6uSUkXxnaR1Kkvx+bfNMsNtkPHaABB7pZD+RLG4cj2UQSFEAJxHdKO9iYwhcO272jEt
  356. wW8WZfG0DSql8JYvPkkdFeHEoSgonu4Ws6ujMQv1oSA2KU/gHFv2Ah33CGqek8bcHvEkOmIGeJL5aW49BBhfr+JwtmPRjI52k4SGt+nWTzPsz8
  357. QtBahgsgBvCdTc74V0DcuYvNg/ggzT0PsnHA45ox+XpAzFeY6n5aFypN2U9bvQJVrEJQPNfAqjgF1X9ZoZFeaDfwC47nQ1LuAP+KGXTgVw6/JO
  358. yq/7T8Aw==
  359. ]=],
  360. [=[
  361. zZnbbxxXGcDX9u56znqM42zcOGDEgt1413HKxQ1OmrSIJFIDNiiphAqINg+8kIpU7SqpuDyQ1AmC5IEnXogULpWoAAkBL9xCIAXUC6vdnTPSmt
  362. Yrbkqk5L/gu50z58yMvQ4Sar+xd/ZyZn7nu5zvfOfMkBqZHJ4c3lkcHhkZVsMsI/g/MlIAqZBUQeA0Whm9cOnixcsvvri2dvHyNwsXLlz8+Nix
  363. lQNLByvLS5/6xGqj8dnPPfnU2aefOrF6+oufqeD1KwcOfPKxo6Ojow8/Vt8/d3iuHO545PiR0vgx9finC3sPnnlffWphdmF/OZicmtoxtmf3nv
  364. fsOzi/PFqaqFQewOtnZmq1ej1870PT1ZnxqXft2vvgrsX64u49uw9NTBam9x4qbEOGhuiVzsOVSjgxWlpZmZgowVfhoGtLrhRKQ4X7FbpieKQ4
  365. NDQyDOYc4p6YH7YpRRB6c9i7frhYCFcqu+hAWal4UvifpcUS///lncAvll4omb/yngH8v7/pyFvpL+ibYqm0a+qBUtmcKwP4wUsvfd8eQcKXJj
  366. pprbXudzq6ozW9tPu3e3f6Xa27eIDobh+aBIrFnrUr0Er7/Kb6znfNoZqWT+QIroikG5r4ug1g+O+0daff6/X6/+zSoel1O/xuFNkukP7q3Hlz
  367. qMDlAxuFW/PlfeC2kQ0nTXy+Kxz0M/HnUJQ9021c/bETA+2P+sJlpq9yOQDaly4jXov+6ySaXzfRX/j2Nh5/M/uL+losj9LTfVD9W9+Gt77+Ou
  368. lenv5aM58NGaG99Hbsn5jN8jHuOp3OpctggW3rb/jWkj7fytqaE/8GWpT0W66Q/mh9rcEGnfvRnyVxgMNvqmJ5VPiNpsunWNHBGgj+2CT9iYxG
  369. aJP//0Xj/t/6P3T+B/wSijKhq39sO5DRP1TBT7DtwoJqNIJcvrlRD8cf0NEGHRj/vazc0cUvnTnzzKjaWZpUOz8PZkvxHVtI/vvlyVM/h7ZlTI
  370. RVy+cw7Tr8FY4/CDywAXYjj9/TwZfPnn1WnHpaqUbggnP41v+Bl/8BH8XMF+eckPgjNuW/XP6PX06C77TNPwYcRU5OEf+TTPPYS/jAjrva4a8C
  371. H4z7TBFnipOnnihXAFd87vnyhz78EZk+Knd7+qc/g8ZjfM2Tjv48oLL8cFap+Rz9IzFawOHH8QfGfTaYrtVqdAHwAxi0Dx/4KNGuXMUQCZUnHl
  372. 8Gomf/GTP7VVP2F364JoI3R+MGs3LrJvDRegcPqUfw87nz2GRcxiuEFJ2rEn/CN7l40PyvTdia+5Wqt9m4xN8HDiP9Vb1mNG40wER3jIK3e8n7
  373. RO6PT0nPDS5EIX/2g/DmcfhmTF1fLBptYazlhmTk8jPjj7MbnZz6w7Tl7zHMMLiKwKkq4Z+Ae7uZllLEPb2VRFm+XD2mGg+l8g91IPjAXvV+BW
  374. G2gM61qCWw/yrwJ9T3rgUQjrP1eVWrYYgWjeMhYUvA2aDXXi6W8Xfl6pWrXg5omQ4Y/oMqgCaGP2Ebk/8X54Lr19Ts4ry6fk2aNPgIHHszP0oC
  375. INGfJj6+q6s/DkGQEPjK6o+ThbWBif8AZhmUuTnif82Iy5deaLcYED7rH+5vNBaUz8erixRbVcn/YYMnC6t/iHpiQNQxh1CKMJe3gqSC2oLfZP
  376. 05ztJ8ms73KZt/ir9wJwvgj0PWI/8vov+DDJ/rR+lCkv10nIm/xv6U/bm/TY51mB+9+AtkaNIMCf5HEf+n+ZprHnfw5/DJ/an401zOLCXzbxPC
  377. fpp8r48J/5huWv83N+HHQs7jS/3BUd3M8JPk5iX3gDMcpbjQHf86TPFNHo1sNEIvnPpbQiqE6PP0l0vBwaWTp55Gd8NyYxw/fAE/IP6evosd4C
  378. ZPmCZ2wVzNFF6RmYrd9devKKR2pOqPFqm3pWCquzugjT8FRKK7v/7YpP4YhAffHx3cKpuA4/T6y6STFH+QaqTb7cE2amVmAI+/Wf3hZy1TjIun
  379. Mbej7zEGIEVROVR8gTN+Slqt7HcufwZrj5Lxvc+PolQKZWdBrgvE9/eSFUcAMxHrx6smobfy5sHB+w86d95q1jnR+OOfk2cVZiLtrNpEeafm1l
  380. 0u6bfJJ014DWokXDSrCzf/oeocQq5+rH1sTUH8iDvh8H/zW0d+5/AjM1s6FoA6BA9yGNe/6DgVQPbHLgSudsJ39cdYog0L2VVA2o0/kLz6Kr7e
  381. TMWfa3x825R1qjP/mwoIukBrbe1vybz5VuyWPlGXVzUu/y9/5S7A+aaTf1IFC32UyXqf+hgcPP/jkiCg2VctN5HfX9/YWN9Y1xrO8KZvc19k9M
  382. ebOfzXXmc+nDP8yMFHor+ZEY8D/7jCJcEYRGS9phYp/vt+x/v+7M8RGOm0/VluuvsfsTNjyhvWX/hYf55QtN7iQcH+75P6G6A/njb6Se7FzZ+u
  383. qOXy38jh62TB5PClWFki+2P9uapwSSAl4TLFf98ftH2v8rbDaZD+OlmvOYVz4Bar4n8c+qz/YdZ/XfTH0/pGP119OQWQy/9byv60VeOMP3ph/W
  384. XJwPE/5iz2Amzrb4kkHxNPpvQvlv8ofXjD47uZw8u/YwuNBpRrpv4lqdWhBjXxj57vgP7rjv/d6s/nQ/2RtT9tgGU64C1uqf5V75bwW4Q/1D8S
  385. IO4S+PGfv/648WeoP36P8Fu3br3i8+NunOwammrI/kn9m3xBFU8kW0Id3hKiPaEt+Zz+RPc0v2v2N+3U4e7H9Xq4D8V/9OL82M5fAOb4X5Jfim
  386. 83gOTNZnzpQKdtO9J2PtDbtnRQhp+//3GDI/+1128W/MUH75MlM1eUx3c+WTOQtNuOWagHtGkb8RrQ4f/plsgrLr6lfcfnSra8Q7t7XnACUc7p
  387. +M999mH5unu/fNoa522D557HkqzT0bR90Gnnxt+W/MQH0Xb5rCjNiOfOH3k0wI+4SxXk6N/aVKzmjgUyIWj4dMtvmGX3bvRAE8qBCS6JQO/gyK
  388. OqKcPDSf+b8h3fOyVbxhnC5xH1dXPxr/EBRcA7wLgkBftj2grb7ACegLbka91Nu56mgy7+xdwxhFq+9vlt5hcpSaH9iyVYYOGyvSL85ImS3Rm0
  389. z5xs5HmFG6+aaFPURkSu/l/5KvJxXhhLokH5D0PihMvnxlFTkvFDJ9l9jVMFe5d6ZTYSmW+eU2Ttr3j047TZwC2S5XkqkImf1Z/fdSlAYh+etO
  390. LHZz5fuuzbHz0+gVmHeCHxD8/bAjnFjykr2uJQm4c+6Gx0hVdDx6Y0EPvLjz/4ociPMNDHk/U3tBz3l+Rxhh/LPomzNtHyorvuAzAncnABdi/2
  391. nypsseHqbwak+W+PvKP4b0NX/gs=
  392. ]=],
  393. [=[
  394. rVlbbxvHFdaFpGaoVWhLSiK7bq1GckjaNOxYThMrviSWgQqwgaZ9CoI4TgIYiJ3GtReW3JsbKUz60D70qS8NEDR9aI32B/RPECRnCCygwEhvNm
  395. D9i5xz5r4XSjJ6lsPd2dnd79zn7Ozo2PgYL01PT4+NjU/D8fh+DkdjRCNAVU0Tet/+7ebnn21ufLqxsfnp55+1N+s/vPJWbfbg6urpM62puQ/e
  396. fSv+8MDJifrhl968/jO8/0hz6dDzz9ydunnj6q3r1797/vTx77y4OlPl1eONU+9ffffmkelpXtlXOXzswFTlwIFnZ6b3n4xKL8/WagcPfw/vP3
  397. QIeKtOPPfs5MHFxfpzExVeG2fPlNjpKcarsxFdszONjoyOjtLB5XK1NsXGyqMjEYh0KtrpzrKmEf038hQ0ipoc91hRf/j/FA8L74/AJpers7Oz
  398. sMdWnb1sTFbdzeM6g8FAwjaghiTpQLoT+sA/E5K9Qx/5l5ozZuce0el06D8fwzHh8+Yu8zrhoLQC+WMyxayPTydK5dt37t3BVimV19fXN7xWOf
  399. nSqcpEKHJW/sLhLG0RfY0MKPmFYPzu2oM1bJzxNJ1++QfLsdTKk5qsyrNUcDr1gIeoAYKXQsT8d7/HDdA2+cIr9aC9emaZR/L/TQ9ReLKCFDIG
  400. +XHj7TbjC6/VgwYaaZRUHIJ1qL1+/vwbZWWqvbZKVa4ofJK+QxqJm7x5FHWN+GmKOW+Zs+w4b+LxPHYu8aehS0mSPPbxhRTsKG82FX5W/4jHtI
  401. FYk1P/yy/gb/Wp8FcBP9H4kiIA7N/Ug3n6B/mbTBvIyE90hfPShzdulu7duUeRcxsiaD+fvn2nXJng1KvA+I2bE3Bdeb2sfpUrAL8trPykgKh5
  402. 1MgfZRiOQvmPW3w4YD/9+Nbkg7UHFDnkQZzjH1O9Box/fAuvmzc0x9L2B3xyrzd/fLXsCATxDq38pItFIlTMX/+GjFCPs7Pn4LgG7ew5Rr35Fo
  403. 3DTT+y0tRj0Lfxf5WApGRzOxjNyD+pHmfl//s/EBHlUucXGqyhhibpEhgvlWd8V6nHNv4GygUAP17gF2DsQiF+ZAKUnu3kj7R96BqUvxW16iQ/
  404. R0eogPxMu8qfvuBfNrL4Kv4WDJALdPQf3N4ub8D2tuqAKSq+/KWMscroh3BNDR2hAfJP4iFc2lrkiy3AZ1v/Ef/d2vomH581//BH3FhTCXx37R
  405. qql1/Llz/Os9VdzOJkjVak+Ywz9nfuD/mPOXzjaCYiF67R7lrd8wV3kIsPdmDKGpzij9GlOsMr/Qs58OQX8ZyxP/NA5hscDAb4c4QPvfkc+T/5
  406. pU/vc52vVPyb+Iu5cSCNr7FpGoP8s+AHu9lDkoOflh8MqLKevQSBwMt/1fHpPsU6nFfxb+LPyypMT4WQ+1T6g/h3+PsoEbyDfz/RM8w6eBfucO
  407. Kh05DFcMO44in8n/8CAIhNjL+F1zA+rZ9CVsTpxE7FLv84+4c0OaRHVMuTH/Brehzkp/hn7gE6/sDsdv4TO8Z/EcV5+OAaGH8wo9ZBfoJmL7hb
  408. wP8FKUAHAPSigvxXczzB/mBeXuTv/dqn3xj/Y85FaoT/fZWbwf4GHxWg5n9r2UrJ5hHoq1TziXJrPYnpholoIvArlytt/J09Z+I/eoEf0Vcb+V
  409. UEKnz2v0RvMP029E/deYEUfJ9i0w6ZUch66RJH0Qzf50SZUW6t0yMTRn6Nj/nfwCeA39I/fkwpUeEjnh3So5DFC6o7rDFYgcsIqfClKcAh/jz5
  410. HZ2ok/zvkVm93KRHFf6/cjbFwqVCfFtAm/o7kN9qeCmFGOp/aZj8UGMkMOfq0ugeVETwFvH6Gxuof5t/dP0P8RdZ+SNPw2n3igL9853khzmXqd
  411. IIiiN8i4Bbms2myz96/gdzTPnuk/IoiANq2VJ6Rsp/b+XR15jhE5X2j3FqzVfP8GVk2uHbFCCK3xISn7b91weaxFSTZo9+JfSgTGLymBPLqjGC
  412. PwblG11n5UcjqBlZusf1+2p/8YkPf9GcJghhr7/o3wrejYMrQuMvcWqqal4GTmIpTfypCMziA46BeuJJD4N9T37oPsKB+x6Pj+k0DSZhecLaFD
  413. RpfCKFb5pF76MbP7HwK0KIQP8Av+3kV9w+xoc8xOsSVXaA7ZehtQl/eYmn8T35hbVm30gqlNBCGze0P8Kv6GjT/8SA8Oy/fIJTU/ikCBRDSM/+
  414. 9tl6R9CiLyHxP08sCICSqtt3+I8Ch/Q1gPY3+tf25xbf1l9UA3Z8fGd+2kHi/adQNkbrY9eX34dH/gwDJL+yv8sf+r3qI/4R1Z9+ACC8IcMBca
  415. QAk+1EJlJ3hY9voMPYTJT/UfzvM/Nq2R7o/GcTABYiPgMe/p+/+uovaH7EBwawi2Zx+GR2xZ+Xd734z6G5WBU/LgEX5R7jgTLpJ8Y0QvbT8uNB
  416. 4qcsjH+5MhTfLlEV4wt0AyGCQIBTnv9RrGXwHyUm/mJVdlr9m/nfzj7W/gXLRMJEZC+UXeM/sQxIH34b/U/Y+M/Ov1r9hfrXS2ouI3W7vb5nER
  417. v/yIAf/7CjmET5hY7/drsdNFX/+/nXMJC3sknU6/YAuR8yQCGW0cAjXNmQzv4Knwf4sQ7/ED93AZGeCdLnLZ+JcHZwk4Sf/335iQ1u8q9CgdQb
  418. 4KcWTBG9lwtv5j8/LZsJUexof2mWejvpdVoZ6kMpvwg/zYEImMvqHw60/Q1ehzB1OMr0Gjec7na7+eGZX/ho+ia0fztlf3892lsW951AX9O38E
  419. KIPSyuohUK8UW4gj7I+r5RRL/bM9oX/b5X/ewMr+q/Ivvb+FfLTznBh2e6nuuL3cIKkzaGxb9B1OHn6kFFPfC6HsneNylX7MYAOl/hb5j9vfcP
  420. Jb8Q/lcNgdiA3u/ZKlCIXSlAx4SgkiXE5z5+Ov0JAS8q65Uq9hC6S4OevXftfcLNG0mU/3qs8i95uIk/eAF7sPYKnxyILsIbMwQM7MX7lfxT9C
  421. 6TeUGeIWnc6w9NNLjqzTnJ3gsicy+BZ4yEvrIikyJSWgrSv6BaodbrikwC3gu+yNNEgZHIAB3DAK0Wxr0g/v3AK2BikCu/tHPyitB7vwkz/0k3
  422. /0zhgtqMyKahoTTIiCtyz6eY1OWvLr+lE1TY1Ke/I+4CM40/MCXM0CQx8JY/rKaFzHytHIY/yOrfN8AwHgyO+f6q50DpSmP3HTHgxR0OUuelHK
  423. Q+Mdrb0wLY+UWq8i/vo3K6I3NG5O6/uQ4DCIoevxaS4Xdl5xj+52oZ8hhenceXzPlsLPPm4/RTZI5GvMJNZr+D52vFO/kt
  424. ]=],
  425. [=[
  426. 7ZnbbxRVHMe3e/Oc7UJbtm1aL02xxW5tDZaiRIqauIQgN0EeCMTEJxPQomWA+gosEIUHnniBpI8QNTH65g3iNVHYzuw5k0ApY7dtYuKzf4G/3+
  427. /MzM5sZ7a7dYuJ8dcLnd2d+ZzvOb/bOTRFo7F1sbZY1LYYWDQei0ds60ylMpnOTCr1WIquL+Qvnjt7/vyZsxfOnbmYj0RGR0aeO6F98OG2Y8cy
  428. T3Qc1A69NZ5Zu2PvDuf+ngMHD598/eQ7HW176fqFzYcPtwyNHx+fmHhl375IZP1gz9qXNj071JJkLT39zTzz+Gh368imUef+9s7W9hc7NrCeni
  429. xd9/W2tnSt3do7NpJd8/zmyPLW1KR+N6nL1KYkS6VS0VRroimxe/nbn0qA4a9IIrIS2xWJNkV3xSIxZzjOP03O0Ja1WPlu3/2kKQ1i2uGr0mod
  430. X+F/+y/ZzAOyWf9L8USivaMzkUxVvtdw/Jwkm5/1vcS4Mkbvrd4QHLx3AJYUwO9H40yYJlx6h7c6eA/Ckjnh6hfSBJPSWiU8PBq+SzgAq6xfbH
  431. f1w4VpChHMh7tgclbMt+B+Uie9/PlZKXe66y/C+XiTwAHiHzUBcbh+voMveaYYXt7j6EcCAqxg8WRqBMtGFn7Q/zlLOIsvyM1nnZdFuuz/9PiZ
  432. uVD55ScsWVyBLzt+JQQE9WQyJbz66RNC2r/tj8LLaxLKMvTsmQeBeHjgZOIIJAlpj1L6FzdOOOepQrBtL6NH+71fKPFKiUWz5gkKhZ8LXEuI0k
  433. uX+duca4Z0p8E7uWyQ8zQ82bL5GkzoFk1U4uPJ+MSJiRMwVuRbOBP20tkWiIfnCe3U6T7gNxs6PInUSq84Dfit6qlKP+d9Y65+O/Yx17BTp0+d
  434. 5u9pAjLdnJgJI1bySf8hEKUb8ByW5YNMen2L5QGY1Vz9aZVRPItPuU3ju8nXBply5xpTDYw9DaMGazGQrw3DSkivbxFvmNn6pVzTxtdNZjx8CD
  435. 6BuV5F+6AGYShkrXx8IPgfOamhK3Ws7ACgn3jwruV8XseF8kS5wBkA/h432cg6+AUnN0ihG4qWkTnpmV4DgaLMh+vyBM0v2C4L65/P53k8yUC+
  436. KNXBd0IXlQkdYMb09LTz+AcLcDG96PHf6fK7YPfQ/oABazyNfPZJmoKwdn6hnDkMnfB64a968j8NAPS3Js4kvth/4HNcTgii2h8AUQeBewTuAb
  437. gBP/XVH5qCe9u5x7IDnNXDh9DdSikAY0BK3wzXAgcD738Vv4eQP3Wda/XwIachn1MKgoXI1VyNZxbka/JP4NvezzcO2GFQl37IcYecFCAqaoBJ
  438. VqX42/7/D/jpQbylSwP9uSV1GNP4rGkuBraPNh/9X83/KD7pWl3zX1ApCJKMbiytQKb1UNy3cFLmA0aAbQ4FUNrrf8N1+V/BLZ7g+6q8+/j3iw
  439. 8tg7LTfPAAMHhtCe53plDXALAJSKYg/Fm2l+eZX38R9BvnL+iyFJBV1ADKPYBwmwCwGjee4D5PP7OevwHBr0Hs5DXPAqD+xTlhfPSxEZzV7CUQ
  440. zihUh1YXv4D8DXwn6E87GxaXP79QFLQ0YVnVkha1iKLkNHElL/+rr237pgqfsHtAvyqvXn6pWCxCgqQ2LIyvasXSdgeJ392y7XYVPrlPBmurig
  441. GzzDdVj4SlvSo/yBT/51+AfrcqX6r6g3hd9w3ANGH609h08nQIXyzD//W3ZfVTHwxTD6GHFUjkhHDwshjH/uRIG49PHo2uRP/y8w9FWNy4iZ0t
  442. wzYAOyGXn5PNly5fuQr14cbNcRbMD8vQxL9D9Hiyu0oYwOx/+hnwx5idh/TF38kWirrBsbOF+gCf8PNVaYD5NwV8VdcPnUkVPnbQfVsGeD/wcz
  443. gA3VB1FYfSYqfV5oqyYtp8pT9oBsr8n6Az+TY8DDGD940NYGetdoPS0S+pKe2buj5QWdaASFuMOTzbwBJlhvHv3irbnWA3gD4Y22DorMly0nTX
  444. X2BwTtpdspcuTMve+sGArSp8n4Xx3V0o6XfiD3fW7juWrJh82B5OJvYfeBNTEwzHDOXjDFAaCA0Dh1Is0l9mOf85G0j/jgrlA1/1HV2M9C/xQZ
  445. 9+TAMwhjA+6CyiVXZApllaDNhACuX60HcMUcWwRIALKr5n+WEMYWkAtauNiKjhJMQJPcb7NgIfUrMZyq9l/e2jiKX9T9UTxznsu0aVfjPAARD1
  446. /Q9++7FqGq71EEht/ITdd3WxcP2rc/5t0bnJZBJqA5YN1C8eKV/CfpPn83bfXWX9qbWLHz32bncjD/7J83Hhe7OcX7qs9AfGH+O9vZyNH3+fNZ
  447. av9DdPDXOoTyy4BiJRw+0YFtfG8t0dDyf9whIh+RdPobF0NpgvNNLfMpVF/RrqL4TwcZn4Kuln/cPO+ofUfw3XvxlPRhobf2nST/EP6y9C+QzX
  448. n/Pq/ccK9Pt2XJngHtRd/3Vfuicj3Q3SL3zHvuF8reynV65eudogN/DvNsLOV13/U0YnpFpD+GaFhfffbJD7rEFhQO0GfgV3vp75d/jXrtNPw8
  449. JQCa9Cr9A/3E8/WiPTQPjJkMtPQ5SuwvzXZIh60ncuAi30I+b/m///Hsr/Gw==
  450. ]=],
  451. [=[
  452. rVndbxzVFbex155xNlkbJ4S4BSX2NsYtkYCQpkmgQRhUquQhtA9Ikaq0bwVKZa8SVPoBNJtULTz0qS9F4rGV2n8DpFZYM7rnatdtPe0F1Ej4v+
  453. g59/PcOzNO4nJ2d+bu3Z353d/5uufemZyamnqABM9TCw9ie2ohzye8zFmZnTXfb9/6zfDmrXdv/1p/bt7Mj1+4eGL11OlzV1Ce+v7m6tefW33x
  454. arh++Ymjp7/74itfOXLEfD+1/I3ZKxsb/W8/9+jpo/3+2lzv0KHjJEuHD2VZ/+yBhRMPHT0Wrs/mD813lo4tHXvYfF9cmMv65848euzI3ENfXZ
  455. jPJu4mk5OT9qClN9u5NNub7PVmJ7pzc53O3S7vWJmYnNif0HUP4Od195XGYsZkf703OdN8fXeOyeHD+njp0r0PT6KA/UgZNSDtkJFA3AfuPr5L
  456. sT9vWZF1AdmIA9Ep6uIwYN98sOx/7ljHZ/f9xz+/ZPksJh/jQ00BFSTy3/H/J3csQ3M3anl8CL1aU3SuQFCPEsI0YLxLDfPGg22I0BZ2oPYK/H
  457. yB15ivAtv63gpvr/AFnL/S4xqNRsy9Kg9gBzAW0503O/f1vvLy92bMRTNzMAbnJI5rZP9yVBbFCLwpiL+y5PRhDFm+D/nTnz/8IH/m2UyMi7IE
  458. FxB0Z4avZInoZVGOvANo+4ugYOQ/WMkfvm/8v/y138fTAMYlAWhTGy18/m8r6JllMSrp91HQP8Ct2wLAmxn5r9ANpzc2SbGY/jY2zWtmFntRzb
  459. UX/XCArtH8iSRiINFCD6V0nqm/jbQGRj4WEP+3vzO2F8b+hI/8s+s36JaPHc+v3zCvHA3TbJvQOyD7ezXTEMrC4dN3KUfYFdTv9G+dWlj90z3/
  460. +AGdPtTH/L3333ufYAaN+Ni7ZEcixkRMyRDQXP9oGIn+z/JehT4inA/iZ30sDP/u46sMgfN/5+dcfmT4T+uZaobwZQh0khD+aP8yydPe/wx3LU
  461. ab81c3NhfyHmqBFBH4P5L/YovLrwx/6/+of+94CTxlxaJQUqCdE/173V/M84v5C3TI82vkAKSFx/sx/zp+5v0f+Wt2NfpmZihLhCQ/q/PXsaeZ
  462. v2RUfu187tTascpt4P+ztwx/5//of43aVzoXlYUUEM2uhr/i/C9bfOvZv/+De30nJ9008w/+L3xCEQHfDon8TwKwabcy7i9i+190/LM1H37Xb7
  463. xEummxf/B/G8o2psLcQ1IWSndLHv8QRkz+LweB/1p3jQXBZf3Of/hLLm/H/o/6F4KFNDM/6b+U+LOQLghARvOvzv8S428V39z0nZknnnxqJsT/
  464. I/rF49/lf7K/z2XB/Fr/lJYQU/Bqx+cfYcfs8eNU9/SZbxLNblv+C/k/TM0s+MjnKCNqeF6FRP6/TuWHHDj8lbOr+cpjq/r8rXPnycenf/zqq6
  465. /Nam3P0OGqC4zg/wLW3WQWzbwBPuQf5fUvtMaw+NmVlviBfOXCqvlgErCKz37yxhs/zZDwqXyIvklOguuHoKrM+r9xaI6vdU95WQCk8e/yDxU/
  466. ILstKh72yMy6TWwJ//w19+NSiD9finB8glem6hK2LtNv7n8CjWf9GGfUntG/tcHgPAKSmbE/80MK+Mz/s+EwH5IqPP4WZV5X9EELf3I/vHj55I
  467. l8ONSplvTubED8Tf4l9j03677i8EP+v/OC7hsOmANQ5EuelaP4d7KOgx8sn/xarvNcbIaugemaFn7W1rrIE6Xf77P8jznM5O9hxhyAMp8KaVk2
  468. 8Vem+Fg+aeeA+U4qiw2dV17+gf4h+P/uZcufeSDx54kmLLw4f0X8farbl5D/db39mQJq+Al/ZYp/wIS7lrflmT1kyccfHDRV+WKU/6gkjQegEv
  469. 5CrIeLMX6mOwv5g3scjWA7MpGJ/3T6RfsXyoQdp68YvsDfxfhOuJRCfeWsDviz9XYWikZ9rvzyjfxYJLO/sb+ec9rjD2gl5ZdxgKGe5xfouHKh
  470. 3s6oZESNAU5mdKrcunHXjUvE+KUFt0e3Qo7iP5y+cMug1iN5jEuleK7Gu7iU/gw+xyXwv1w6EVz/oe6RrACoIHJAUh1agjwhe+ZZrL5bj7pupo
  471. PJK9UYqo8+plt8ApWf0Lj/N2w/sPknUoBfBurUgifdzqMeXbKbBS5Y/L/9HfQQXE3F6y+a+6JtE5XGvwrgeiboIk8MxJZjBmHdDMLg41ccgsYX
  472. aQBo/6vvPzh8ZeHZTHTwzc4er8Vk2+M/Xv8ffczwnf4L439SJntO6f6HELZ24ZHYLGHNaCoHrf9PSAWVryfi/FvffErqP4tv9jTuU3bhU6+LWv
  473. WP5i/5sss0FMg6vouDeESNCuA/Nf+HhZ9Z+qV7UKpqv6UehaC0rPyI1rWvrOt0uS7Yf/bGV1j4F9AUgVVd+ywcRBiQCv3CiWKjblKTp0/ppwyJ
  474. t0zXXyk+OwsFSYja7bImx2lC1/ho/sJtyD1fFEVL/oeoGkYlG16qZiMaVzS2dng9XkQsC+UWYUVZhv2HRnQlaqSUp55opRGfkzf8afPBXFga/i
  475. H/MzcWkRc227XWJ1rRLbxJ/2VBvJA8bY+pSP9h0hScSyN+rUO1GX7LrXeEUbjee4szUNXgeAxUQGvwJ+BhnBG8W24X3PH1Qojz94gNbOEuA6gl
  476. ji2+4e2Crqg/GYCm/e+2ZMc9P9Q3dg6OxrlVw3fMNSDtv9gxgKrHnxCNpEUkqWJUo/U1mmT4UpdKIsyA0BD/QnAjJLiReURUN6Q7DjTnssciqH
  477. +ht+XNH9vzj4hMYEC55gXzlThVJ/ild3Ub/1KwChzi+SdmHAg2pXYWHXVthIrD7D4Xbh9ayumNTVyVSxXqb0j3f/fOafcigX7hcixN8zgBysH1
  478. G7RA5o+xdP7d2d7eoc82tvR5e6dlPrsPfIR/3gYbmJ3f8oCp26MCAKrGsPNl2L7xzd3Jc2y5XxQ57dUMAGTif8R6h1QAO7axE/YP949vSgUw+6
  479. 1KFuXSml43xI8BK2hMtPvV/1a036gncH0msIO0rF2M1U/421YB27C9Y5t75N17g0/zmaYnAeL6T0FL/bFfifE9BUo9YB5LJA9h1adf5qPXrT0e
  480. NdeeOiv7lJAXxYo9WfYlAn5T4V+KP19m/dGDPoZRY8zLcBWth8yMoCA8y+YrJZU86U65JA86o6fzYb7n8j8=
  481. ]=],
  482. [=[
  483. vVlLcxNHEJZsSd6VZR42h1QqBIh5qUIeNmCMAxfEgZSAghxCykVCDjlASChQMFxNjKk8DiRVcAlVOUIq+SvOTO0sZfkxkWyf4F+ke147u9pdrV
  484. 0qZqWVVurtnu7p+eab3nxf387+/n535zCcCgV4Fdyc1cqqDQyUd+D13PyDh48ePZyfnf9x9sHsg/kDJyZnvpi+Oj2ww6lcOF+vX7h4sW7fP3lr
  485. 2/WvvywPlkqfXsTr0WPH79+/8fmVH0rbtw1+Uz//3jvFAxMTE86OwcnJsbGx8fGx8aP2/e+Ofjg16AyOlAePnsTrfW/t3rP7xNDQ7qHKtg9Kk5
  486. O5bi2PhziJyzr4UhxwKn3lUq6cL2/vdntRtVy+mNtKQ6v9ub5c7pi6zssf8/l8flOK+mPuh89KubwLXKrvgnNdvMr1zaj1ZWO+37Y/8czUD/qn
  487. eKkFaN2lsunaihTaf7MWl5Zry9hqyyvwo/A/JLW0HNdWetYvznTjyv+wFPcY86SA5+ELrjwh25tIcNZchaO5ijoXlP+WFGeF4r0ivEricxa+ls
  488. oe79kIBf6TtrZvS3HPefzUxea4ujmM9ywnwP/mKkaAEUqN/4EUZ427M+4cNMcdPXxIvBse71kW2uNP9PSzpMD/m+4cen3WHT1ySLzB/57NjjWT
  489. /y2fWsOvpTiDuAv75+z4p1gsQJKUCiJnMFc20S+i7NtSEH9l/7yxL+OfpMt57+A+t+66j5/i4WxihIT/ESmIP1jE8a9E8i9Jl7Pn4AEM1t0ZPB
  490. rZR4gSBX+2lLSPrVC8dPkrEdYRxlN0VVSwfvkVDyd7TpAFC36s/NdeL5qG8U/UVbh/pzg9ov13ss8O2om+YN+rVKvViH3GU3Q5f8241/CGP57B
  491. q5F9dpBO9EX/hzCRMeoh+4m6fIjXlLB/ZD+8nOzzkXaiL/rP5ArgsVeLi6/PMDxC+R/V5cwp+3LUMuMEoZ3o6/tr1qJHiF4NWym6GjBbrwRzNS
  492. syUeJ3oq8t5XNCeTdd8LUy51rNyYqFxG/b7CNGilPCu+jCD5Evly5/Bh9wjGTEaEKl/RQp9L+LLvyiUmXx9aZWBWV+IUWKU8q76RL2Gau9Wnxd
  493. y5L3OqHW6cZKsPrG+8gJ4V3GEb9KvkQpy5L3wfLLuLGf4KMY/y7jyDxfzVegEwTfNDVeSK9u3xHrJI9B31Dv5finR1XFXzT5L/YgORKcPX8B/E
  494. asacZ+go8y/ptnHSRFirO//3HdvXvdhrKfokvk3xZ4DqXJUoLeuH8+C/xP1qXHX+paimwIUvpFk+Ml7e/fb+yn5SqV49+OEEeRvGmRIMnxMst7
  495. w/ifnKsC/4LMKVy/8W1BkTyelhM0OaqcVaqaU9nLb2yuQv7ZmdP47vtbDizybrXBeFpOkOSoiuX90uWryKms5S8+VyH+duY8fwHdBjpuE+LY3l
  496. NbFw1JyVEkGn9SM9rMfzX+OHMEOawK+8mZQwMEIAKQAqk1Bb64pqejr7/UomRtxcocJJoVnTyp85EqXWD94TyhHVLED/beod5vWFOsVSO0FtCR
  497. FivsdIeni3AqOUH+x/aeBFj4088YAhMEKSUGKICfQBdAOApTeQ+erMuz4Pk1a0OUnDlE94tI075cGnQkKPZvQduX/VLLB1WGhVFhXb3hEjdk16
  498. ZM/FMyxySACLWR0nrh5G/8B21ddEb+JKTs+K/UKKkFqLfCzmv/51T+bwkBwMgKGvwXmrZM43StIf9sBWxIIKfwX9tPQACGCOCn1WDgb+m/skgy
  499. 8C+JnILozjX0hiDWRxZBgM4aDDWlHw3Y8fyLWPxLzj/XxN9YjCxMbTkBVYuvwRBD/uRPNIF/UR5BTrnJR/C0dqzhhamtss5PqcGEyKdvD1cy/4
  500. qYsXeshSKsTOWgUqYAKLkGQ3XpSf1L4vkXtfnXWijMLWvHCgsDrky6Y0DKGPGtBIxm4VKLWKU3tEgT+BfNwr/kwuCifU9WFQP78RwAuLKx3w7G
  501. v4N/Cf7XlX/JiVmtyMks7dN2KAEiHIBE0Zdk4F+JkUD7w8VSAbZgpTLlegVM4QA0ir40gX8RnqmiKxblQbEwEJ6W0YoD6OEP5uPHY+P3iqVyhH
  502. /JaHav6OqKzejhhs4YmlIBb8HsCO39OD12fGLKvelE+BclPFNFt3LqtOu+DfaPOBoxSUq8qPbfzEcyeVLWDsL8i1CeqaI7pHGpOKJ3rFRRkDT0
  503. NbUXTmBpf1/UTkL8S41/loquJyr1HjOImYwAiL5B/okJgUv7R1PCfjt4AtGidK1zy9ERCc68Gtg+g9twZhCTxsfLj0Ffn3uwtB+F+Ld1hV4/gd
  504. BfPfW8Ii4S3IjC2SAmjY+XQL8I+uoZ5DqyAs6abFUcRqs4JWGhlsezR1TE1snGcnxrURpBX/C/oWtnojdSV9NrM3nIMCRhoZD3muIepqhiiM0R
  505. EvmIoK/xv6LGU3rTlAsatsLtO7DpSshCkPdEvKAPjC2tZ9kjB/Ajnzk5brU6/NvvZVkBb+IB+oT3cMZHIqMnnARdXPVW9JjxTNUCbZ/Z1ObJk8
  506. bLly+FPvSl6Wn/PWTenzQSdHHRVxkBlu1J2YL14EeM/5BAj+IImMd8ktqY8f+czs64qMbxny61x0jljTMJHnD4QQXYuM9wep467SRENUJMslRq
  507. Qugbqvmu+xF9ognmN9K7J7Edzx3fzLNf828Ifd+IxbDUQo+eu/8P
  508. ]=],
  509. [=[
  510. 3VnbbxTXGbeXmWXO7iRrex13IaRZ2IFljbGhTkOyJrJaVykC1EJASYQiEZRESksbyuKQKoTEzkLTy0NbKX0pEn1ASnqRKof2oRc7vUNLLNiZkV
  511. a2ZWG3DjSQ9n/o953bnJk543VUqlY9M7O7s7M7v/P77t+Z9i5CYMcj1dUFb6nUqlTKSOFog5HJ5HFkcHRkMqvH6q9/bfzM2NnXx8+cqZ8dG+/s
  512. OTH67K7REwdGR59/9qtHnnny4O7H+q3nRkefHNmN/7///o0HTxw8cd+jjz7+zOi+z35605r82k3PHenav3f3C49/avfnBorbtm1cs317d8/H1h
  513. rp/NCmHdV0Opu5tzTwQAn/vzX/8bvv7usrZnt6Vnf3O86DG9ZvqWwcuqfn3nXGXQ8/tKFtZaOdvba3t+1Jm5lMKmfm7NzOXHuu1R9NZcBJ20cd
  514. AJlaZfD/rUrRqbTj123i44pmEKIS/L+93e7eswd2PDLd3fCWCcZK5jf9b4y2OzD+Z/BnZlc65v4T+DPX3ZUN318UM6A3ME6aYyY90gZaSvc9Pa
  515. aZNp7/whfX0MtwjV7CN3VPr1HwZ2YpvO95Xhwwig8zmAvwLSKHtSX4+KUvv2DRyxd+gJtVKveT3v5Kby9crLOfKPjz/MYBjOexueCXbFL8Kv7M
  516. nw/wa6Re57s1QBzHocdbb3OA2re/h5vlIGQvwh/lm4JPhU/xJX3P9XwPv6HfiZmIGTABcP4qvhg//gnHt0dfxM2qkugI8IXuVUkDe4rv+54rBB
  517. HgMwHQG4wrdxyU/G0BYJj79j9mmnnC+fdLAQT485Sup2Ljq88hhfjpCQokhK/yD/TfYXYyfKtQUjj3A/wb9Sj/eZc535wUvSdhVb1TPbCz+Rb6
  518. lwC1UkGAU/e4aPLXtIo/v4RjXtBX9eAqVomCieLbivwD/RsCwCo78nKS/iP4oeGpbhG4Z4CPrKiKzUP5weDmR+tMwVbJKUv8YXl9eHl8TwL6Yb
  519. d0Y/gBq8OCO0Sb/FEh/2qhGuZvpFfT95qCvzj712t/m70uwRvsU8NDN9TAq/ovkTLdq4cJI2j9yK6gsXP5F50wPlyOyR/GVfejDIW/wGf8DfOd
  520. fft/ihTrXP6FoiJ/w7zIL4fwgedVZO25I8B+BOiPuMlHMn9CshyrwvFrRaek8M8GH2shfO+aG9y9xYDZKvwLpEB38kRg2wWrV8i/UI7bf9GKy/
  521. 8anYD7fnO5cUO4p+r/yiiQXIDF8IvVsoLPLp/X4LtXr+HWvOXzUAxx7gOAvMUjHjvnmUmr/wN4a5uUNgOg3Svtv0oU/dsFnKQTlb8weNdtupi6
  522. DXNsArzo0L79Tx2iaX1sAgJKBq620n+Hab5DQ5yIv6SoCr0DQ993vhvj32ATGHGbPk3ddL4lvOPhslXaUSZ4WH6zhf0Pq8qgBK1qP4cvZcWFN9
  523. +M4wsJNH2auhk+WtQT5fFSH+APlUnN1eDbsfgTwq8J9y+VizI2X8xH5S9H08fUnWWqjNitlr+Mv+lt2z9hvnQcN3bO8r/DYR0nJ+/XS+L8pf4l
  524. oQ4aJoyJPFoUlb9O/7zAunDhwgOffJD88EXclARjnLx4spN0wWta8LDj+Fz9qH9qf6sVLyJU9qgDvf5ZgQW/fOhhjfyt75+L+j/YYOcy8mf299
  525. rLR4apGrKBUWn1b7ECi92/ihUIr0J4/IN5f/NbuC2Xf1V8tL8sOTV9Wg0ruCfwl/K3thICFUB1oKrgIyifocX8QxwJ+C7aHyFPv/LqMI1WOcG/
  526. WNTrX8of8QcBezBk/5uLlD+EJUujngj+CLe/tSH9s4x9/pzg74f8T8i/Ym8Nbl4nRxl/+/w5yp+c77Nbyb9B5U/LtAl8oRZri4ztODWB7yv464
  527. L+XO1v4Mizy8FX4QYoH8FnPtB0hUKxa6HRYkJmbB3+Hej/5t0zZ0UIAPtnCsXtMzJjF6xA//6dx//6Nxh7Gv+ZQnHbFWhrHPXP/A9bkjuMr8Q/
  528. 3+LuCmOvzNiAL/Xvh/Ivdrasvz2JERg0O6Y2uL/4ZdL4VYL/cYOuVCrEkgm9YMn4E8n/9oZNaBrFAmwYgXFgf1VnBj45lTTejeCzOhft/yvH2Z
  529. bm9oeM8or/e+H800nWkz0UNxSB34jivwfHH//EPl+J4dMyH/3fIkL9wv/ZCPw/hI/8N5Jd6J9Q1mAAxvhb6eUBJsL/z39J4s/LfNA/ZAyq/i3h
  530. +A+3d7X5t5NZSrGIFQ4EYIy/0OdWBP/LsLWUv+hymm6tzyEYz0oDsY5dW38w/XMjxQAM8bcfGpBKWP5XWuGz1hbkv5kw/oPh+A8C9TXxn4ZLMA
  531. +Hyj8WYDX2d0WDz3t79H8WsWX8t1vwVzGteIJZof37wgJo/J8AnXalofKhVRB49UvH8Qtuf35i/Q/2Uq/j8gK8HFP4v6fTgIrfkBYA9gcKXa+y
  532. Aa9mJZXg70f4v/YyjiMs8dXrkC7rx5L930j/RofPDRDsjzoU2k8JO4oDZeHVO7T6t+4jp1xveto9TWMl4EO6xPWQJPnDZQ0+g6f6pwYNQczm9b
  533. 9NqgRLmiEhfz8i/1MAv+CdZrWC+TOWLo/p+f/h53D51zr/F/H3riBfQ2H9lJLd89r6C/lPT3vIH/zv83S5p2CjHAQ+DXpR/7sSxm/wHNS8gd0e
  534. b/mwGb3hB9b5vt7+T7kLTP7wmaXMslz/mQwHveT4z0vwD5btf29p+j/g76EATlP738vaMdlghfLfP6b+CcCXLmnzj9L/A/cFPEQnjGfhBcoQ/6
  535. dfwfEqay4i+BH9w+klusfij7rOxE58sezJ9LEgfuElxp8c7X9pPIRsoNj/zaWlpb8vhx+egMf074lVT19c98UCpXb9jyTEX0D/cOo2ncEklT81
  536. SI38AwG4C1hm+Bx2wZfvLluOVuI/VgqHIDzyelmDD+g4bi8xfG6QSfhIdkHRgwLO14ND+LRcxEABZZI+/t8E3CZsUyCAycAP39XWX6FVcImqvG
  537. rzDy4UQIeq54/0KT4IYDK5/tI8ahFa9y8HYkhef0jSP9CfAt9FRbTAb/BQ4yqPOihv+TGOz9p1A8vetF7+aHeU/02Gz2vAaP4THZhUAhf5AvU/
  538. BT4c/1m7nmULFFr+t6X+P5xSwmEs/gqZo/XzgiSwOolPw/PMdYkvl4uGEv2PuT61Q638F+caDbECIrydKUGRuc8DYvD4g+Gz5aLccvUPdX0aBP
  539. T4bAKSvlh9VKKSkAA3C0ZftT975yNk5yO2hv9l5vpLLAjo8acXZ+caPLWL3U98ADkze115/rgu9mRR7LTB/u3vQkM5/X3o+efiih+/CvT/s+fP
  540. /yX8fwE=
  541. ]=],
  542. [=[
  543. 5VnNbxNHFHec3c08Myi214WArBKIK8dLYr6bkH5AJVQBTivooaeqaqSqokARUJIUaKmNQ9XCoadeQGoPSFBaqX9JL978Q52vHc/szuw6m6g99K
  544. 29u56dmd+8N29+7816DKBaHK9WiuPkqDhE6B0UYXy8WCDi+yUmE6US/Vn4obvxsN999Gij33248bDXK8P62sXO2fWVPZNeefrixeXllTMnTl64
  545. fmHl8xatD2dXOxOzB/f6H7/P2k/eu7f+4fEjtQMffLG8fOXru65bPVxynMWFo8eOLS6eXji90J4v7akdqO7fvUTrOwerpw6dWHx9b+Cz9l5ld+
  546. AUa0eXjpcqtdrsqUKmjLHvGLsWCm6x5HbGMC51CqVaYbKW1doVQm4KeaQ4VqTw49poiBTEeDLbF2PajCntyQd3OrVSqVZjk8TPRDrkEBNmFCzv
  547. NomE0YndCCn8O8LBVODwP8Df3HS8kj4Cc3Xn5q2bt9bJ0fX20Z+uvJKDlrOfW8NncOgVJndUUu2P7qzeWf2dHACI/oToOrPQBFaOctnfuXT5L2
  548. KBaAChDb/HgGZmmxy3B9F15q0mPH7y+Eku/DC8TTqC22E4GAy4BUKL/jAz12RfoD6MgnaAhR0AqG22jh9SfEzbozDceDQYpNofpJQJK/jyysyy
  549. IMyi+ItL/IJ+bX7BsAbh7gpUXT8Mf/yJ4ocp+NXu2Xff61YgJtT+zCwobq9ZPjCU4n8DNu+huHAHyNSfqOZNKFchCXwxMJSmP0UesLmXC8CC//
  550. Y7APyr+l+sODI9nyDTuGL+z4AV/BT/1zpEMFwHcRzFVNWbtzyUzj/MCpHv2fXHuqIRPjboj8jMeM6VL69O0JUB2fiS/FL4r+5K8RX8WLEwFXmC
  551. rn91AxFiGNrFiSryFRFj/XBr8QfZJ5Y8I09evATYRdQf2gVdY1MyBS1k1J/zURiOhN/Lwv/jTwqm6i/cIsLfnmTqj6HR2K/p37u2HXziT0Ku7l
  552. PwHWVGtfmvJ/wCccpYc708+MSfhNyI/B8XHI8ZNdA1QmbL0Kod6Pf7j/PgU38SEsWdsutPnWMl7SQ+Sww8kjVI29Am51m0yoNP/KlJ1vOEEn8g
  553. 6hCCJD56+mzq11mkrH/qsstpjJilf/PFyyXy0eIA73Ae6fNPLIRoSJpDJDNQ/R9T+0Ne/cmXLqso7jD+Y/jx+S9HBqJZk4pfTvM/HrItERs3Gg
  554. 0MSzjG//UY98X4fxfE1/80EQs+PgRwECzPLfxrdvQh/ytxoZcVER23Am+M6B9p/KfwP8T1lwmkRX8gtNVAO8b/qv7ULIbZ0kxM/MqxPt8SPud/
  555. Xf+R9BptcWDBQyn8D7CfmXsr+I4/Cj7lNpq2ds25rZX/0Shq4dGcb0jFBv1HLHZcnqTzEztfuvypvLedPKRSoNJYnH3G0IkHtLirRUtEuDCPUL
  556. 92GAXuytG635eMkA+ee/UrnLepxMc58SdJYk22rRXq4VuXQEbLukd2vx85bopwQoiV6fOfUVsrjPMLymRb06qxM7lxjamFsQoIzuTAx9vBx6PS
  557. qL3HOglvhH8MTJ2K74i1qbBWPnx7w1R8sQGBJtqm/fPigwF/R/U3hw+J3zLi4zz45vzDHD5U/VtJ+5djTK0HtZH1Z9kjoZNkAinxAz6ANkqmit
  558. PTU9EHUC58BPZXMQK/HcR3K0YOz4ffo6l9n5/Y/kdufaIuMIMPlN3K0WPH19Y4J9Ze2xMlrXn11/DR/J3VFtK6qCfeVJw89SbtByLb8aQV5fK/
  559. mP1RW9awJz6Lp3k4j8I4Yr92xP4YRsAnvRzmyA0qwDe5+fCxjl+n0+pn4S/BkSUSzieF/nx354+QkA7xHbFlUzZIvAcJm6r/CYDbxO5cf5NWtm
  560. RSWpfo226hlHzTjo+v8VmPliGmYxBaeTxpuHT5k+QbFtX/UD/xAoIl6DTUcS5D4k2NyF+VrqjNPGLiquA+yn6i16fP0PPnvw0PZNOfjT3AlrWA
  561. JD4C/jdBfKzawhlqNUem5edfhocF34lIVzNQD76/R2VFvKvBPNllfxMkXn9FlUULGSsQqx8dBnysDR5rT+//TeU78a6Gn0W2GyS64pVFC4l/Ls
  562. v+vNcp8VavrPq/xNcTb8PLGh3/m7tD/PNp9u/pfQ6vQiJ8NfMVdYJEV2b9l7Psr///4GgZ932tNzHivjFpxfDZt1IeRF7dAmwPitr/b7NNbZut
  563. z78a6vvmrur6dsE3FSYyXYk/A3PJv1l6QqUHKj6Fn2/nfP1n2gIg61bAVIp58kXi/07g14VJ6kYDmUrrNlP+T+Uf
  564. ]=],
  565. [=[
  566. xVlLbxxFEF6vd+3p9dhrewNKiJ2E2FZi7DwIgRDiHEiQEsmRSDgQAQdAXHhLrPLmlbAxguTAiUsshUMknhKC/2FPq3ulmIDJJjnBv6Cqunu6ex
  567. 5+rA3UeMczOz391aurumo7BovFzk5WLA50DnbCVbGzWMRv8KIAVKnVKkDdBU2Ny1cuX776+WdXGldmZmauFo5vOP/G4WcvnD6/pzo2tuvhno17
  568. a4MTo/0vXTp98RUcP9x7evPmrVsHzfvHzl/a/uK2bYPVRx7aOraxvxAOHdrX1ze2s7NnfGttYqCna+jggalNYzu6u/dP4fiJoLR9YGD7BvN+5c
  569. BU3+iW0YHuLcN9o/2ThRVQB5K5mS5Uix1VFlSne6uVvr5lXy4rKrRNHcVCZ0fRYQY+hQ7F1kreLxYTwjjvdxYK4QY0z3SlsqFCVy6tZHqJNLc6
  570. ai5Bq1XPqsGJAbl++HPt0NL4pS44znVtysMslc+Vy/p5Jj6YRCiyV0JqMiMMaWB9gXOGLPghHGFhHn7AgBqNAK8tok8JfOkwILPGSwe/9OvJUz
  571. 8PsH4Us5xxqjFioG7xM2bzhRYJfHjjtzuGfk/gk3zL0IEdLPDxyWrlrkomJD5XVqsY/MX4yWI2filH/q5uxkYOMQefXierjbNQ5jCgZw2MARbl
  572. gj4Qv+Xg1/XIXPs36Hndxy/9sozVGg2ympXf4hOnjv8tjR/STEn5V2C1hpI/hS98/CHQcAkYzsMfKtOAmo9fT1ltgA36VgP8RmBWoId/dUYIJ/
  573. 4E+cInBiTlh/k5HJLjJ4KTNJ9Aaa2egS/FF196+HVl3HyKB7j+p6ICXiO6+mc5CA1/2gAJ/9f4ZgWsXv5ebTXJzUoDePiiq/TmW2/DquvVVsuS
  574. nxiQa8NHCyjlB7vZbtJ0JL/9ju0K3n3v/QDNgQPQ0eYy1h/IvxZ8cuCAFrez0rn88Se2GxUfkhHAann4rTgTtIcPB06PYY7i8wRjz8uIH4PLfl
  575. oHYI4M+QUc1hOcCLQq/9OhnvQfjKPsI3sYOw76P87Yp5eQXqdncIKRnvzAQRp/lfLrXEP6D3cb/BOAf4KxD2nIx/iMBlh8E6TXER89fgAZeALs
  576. D/4fDCv8CxeN/ACp8O9B5rsvH8D57nrga/+X4XbGHlX5AeQPh135yUGM/VWE8DYGa1x/OD1H+ccoDkMkwKDw2kdIn1j53Q2DDlRr9D9n/ZP8Js
  577. 9yExbpC57G9+Hl2uMPSFxW+aYmj0L8P6rvgWpcpuWP1he/x52NI5EWuDI176H15+l/PfEhA0c8Un90cH0HH/qPPhnjk9/l2L8NfPDjgFWT8rti
  578. cl515Fd+nyP/yv1P2gQg0LzR3sf30XajAvbn8ijGYyLceAYWX+/PI2+v2Ib8SXy5/8mnyN1D7V3BrVvf0BFwB98wwO1OfU34QuNH8umDjF27fu
  579. 16PwiM0bDGvvoaj3j9C2nf4BElfl2jNNeIT+EN1/uZs2fOsvEAZsdshHdwD/L78S+W36/E2tW/jj+4+YGE+/K5Lsz/sfZB/yb++fE3VQi263+E
  580. DxKPQGnEnnkVIyDcae2T/mUaP8ry/nbkj+NvMHII8Nlpxp6D/ce01r7SfwrfXf5NDz9cDl8PaCbweRzvzf4jjv+kf5HKf2l8dNr+8lL1Pw5Qz1
  581. 18ci/a5m4Dwv0HP8FMVYLxHwcILwLzbO9TKzi//qNSIkjW35R/aJt7c/bmrNp/3JiFkTd3BuRqev/l4EdSiIzod+067hvLOaVkjfAb9XT+oeIX
  582. TDAKRP4XTjK2g41MBlSL6AEJ+UU6+oO7LE9WfqHqe7IaVRoq4UoeZ98al9pqFa8DE8VVulN/xfV/tvxg3wYeCXxd3wV6TUdu/WefvxMk8GXcpk
  583. nU/41gyf6PW//TDPWGifum7HPzP7iC7hp4+NxpEPn1fyMfP0zJr6IPUX9O/a27RixI4SsNCOv/Q1Q/LlX/2+cp/GW9Jql/KZ32x6r7j07/oZHs
  584. P5w89YLff/D6LwTMRWb8awdfdWXGA13MwsS3gez2wvYHnPwX8WT6sbRMpzgepBno1VaJFXoE8Y/ECrbPLT5PJ4C28DP7mfKv27f/zvrewY/Wii
  585. /nMjgw383PJ7rCXgNYyZ/MwHAWTXjUxCjZtE1S1Sl1m6o+fhb5+GlebJPK5QEYAHQl/6LwaDGNL5tt4LvJ32egpaZFFeDCXhQLCwtC/KEI8Vui
  586. JVu2XSKTdnD2w2DepdDj4oAKFVWkxHIp/QOgp5xFKTP9JaPji0swlqzleIVfehKbqlxyT6KpusSLEuRfkMKRX3ryW/yWlH7DGVZ3lPL9Viyx7d
  587. LbF1G7YHl4Lgy++2sC4mfJ7+E616ruc3VLMdegizS+QAOD7tEpUFn3rO/f5w/u3M2WnzBBPQtE6C40IdcFqD0ZSyeZVfgt/K8lwjHWXKpWE35H
  588. PyE/guqxdIlA3njiAdG58wuBFK7fCM2AcgrpFrfAkcGHFHP+g3NdFYuPY2L58VJp2GW4lfGbhPsDVawO41DAwIM/ge7HXsrRNjBPzzj7/uyN2c
  589. Dzv5aRn1jBdN6SvsIUTkso1Uln5+PiW4cGBubn58l5lCFNb4ES6SSrNz0LAKiR30RShdBy8WXyqffznDAxhe5i8Tm1yUh4lL9KDOwImukI4Edy
  590. bzG4ys97RQVUOhKFmktqf/hYPZGJ0jPlQLmvJAb68+Uk1nDqMO00mv8y5f1WbXYS/wF+83+kuZXg/wM=
  591. ]=],
  592. [=[
  593. 7VnbbxTXGV97d82c9RIwBroWicqtgAE7KQTqmKRJ7VSladJCWqlS1ZSXSqWlBewEQ9+SGKKkfeCJp0rkIVJLqFQ1b71ko164xtLsOWfW67YesW
  594. m5pCTt/9Dv931nds+sd4156BtnZmd2ZufM73z3y3apbHd3LtutstlcrptGX3d2VbY7i+8ZGoVCf2FZAaO/kOnPZF6dfv3V02dof/2102+89kZm
  595. d+9z33qub33p6/u/cfTU8Rc2Hj41tOwHT+x5etvIyMhFGi8fPfyVzc+M7NrRd3hFZlcms3b8qy8Hj5366b5Hdq7+8gvfzGzcuWvXQ8t7ez+zfk
  596. Nf35r8wM69W9YNrFv78EMje0cxf9XaLWt6H+nrW7Ei2JlRmczqwu49jw8Eq9ctLxY2fHZV5mKm88B8OnV1yaWcvp/tKqzoLhSzQSE7kL3n/DyN
  597. TF5GJt/mmXvM785kGTkLdnZh7+qSFeHUtYT1Z91VNiOvSs8vfo2FU3CnQmE17zwc/YuO6P89HuA/wL8XvtFaW0NH7KENK5UKfUJNt+r0E902kc
  598. WP9DWK6FF6nJ7SuBdWQtp1xdJbjLH8EE/Resn48jgWoUOAmzDklyYv8oYhZBvhUV4gnscUOtIKk2E1r8bDz/UMLI7PQ0cm0iG/negzLdCab+R6
  599. ChbMStZHA6u1jeURciTr9vCDd4uL4deZxxYQFoPmOsIjvuSXESjxl96EMxhNv0UEB2kAl+ZYbJhudIr+3IGDv3mvJ3dyYuqZL9L4Un7q5MRAmn
  600. 5wzeTy+al8vid3fGKKvnwHF3SF0/EJund8ogdv+i2c8RQfVq9ZO0UP5PFMY+spGBOl6A9KSqlScOEEndavp4O6cCJo4ocVU2GOBe+8rdTQYPAK
  601. Htx+6IjiaRu3bFCvnKB7tAdqwRgMSiWa6G2BqGETf5If5Lnnz5//BV9NNvErECDNMZNnzwHYgRySE+F/rgHWBh/3grPnmpuajFgkHv2bFs716K
  602. 9oUXgjhKtgu+AfSfCV+tnPsdFFyX/HsfVqveCDP8mmQL/VbfE382jFBziZnQ4G8cu2YBin4UO42rSNly1vHuWLp5U7lM6DmyW619tYEbMWvNRL
  603. p5/IhxUZWxwC4r4i0z/07UG58ibtTNPfQSaBbpV/K/3HUvJnhwbzy+UPHHwJit2n1KrmiceBg9+jY397+S+jhe7Y6g5qkh1pG/qPtacf0BH8z2
  604. Qb6u49iPnBqNr0KPBxYPnPz5sly589Zp10Zrmza3dsuWLXcODgi3I8ObGsuYRiSW3aDXwcSgHRM5+Sf/JQc5SCdPzhCGTEC8J5QYNZJk2vbmq6
  605. FDQkTh7EvYrWQa4tkVP+5ERA8PO+/xP7X5nPvwc5vgSP1ePJH8bHFvO3v3ca/7h02dqaVr/8VVPjghKM4GmsiVzb9PS0UjjQwtj85z36E6fT0J
  606. jBwZT/IwuEO49nq1U48NNndLVKLKCzrlpbnZ2Nr103oP/ir1cd/uGPgiefUk8+FTT171mBpm0aNzgo+Phqc4vGbvfxOX4S520MeIoub76FSIYz
  607. HWirzsYzehz0E9aPf3LU0c9apbbS1X6lBFo5+6dJHv+LCyxmcCjlf+CBKceIieLTZ0A+7/zV0NGa+NJlo4l+x3+hv4n/vP/24QBr9vFziQm/yO
  608. eeQA0PpuRPzg+RMyaK33zLJDuxgXdaAfFfg37H/8EW+gPf/RH9CMu+/b2Tik9vB2n7g/sjdE34hgnWyS7fSQyx0WNO/8H/VvkHTeaTHgScM1hf
  609. /n58Onuut8X+nb3p2NqEdvmi5dJY4r/Vi+g/4w85/EnbcH8Jvh+fXJDz/R/nPdrEMHgRORPujrQ28F931v8ioR5T2yluDYN+dqi2M/+XpeO/qc
  610. PvUAYF/WtwQDfIh/xnbKv+D3n4K/Pe6IH9O/hE/9P8L5KitPhf+D4dV4nx4uuQCmqsiphDS4jF/5TEkopMf2JVrdZVEv336H+YXXj60+/FPyId
  611. rlfHs7PV2SrScIsNK6lW6WW2Svxn+SeETk05i/ouRYM+ipInJ5A24ltPrp/zH7P0+gcPw/N/lLjbfxJ8GP6r6X9vkA7cqt1WpZaNqBVtvHCi5L
  612. InFdQ4L9b3g8/ZteHCgXg3ZjkjDMdwwWLAXqvV2sbf4rDTAyRoSh0hfJ50H/VPzoXXApceEDv5JJYA12BwxnqsA37psc/vYr4n9E/W9P3hW0v2
  613. Oz0Iy+EoTFyoVLi+YsWwXPB0pv/xPXvp+IWtTP8O0B+5UnGp9SfjK2e5BEl3wH6pcjiVgz10on/kCTWq1L6tTP+jo0R/ZNP5973woya+dvkHKl
  614. xxCtq4BKWj/AHv7HB0t8hf30/9a8zkoJQyyJx5MqdC2ohhcDatxwmfU2/VclwJ1fEytv4a55926fWvadCvOXXgShcVPocFKfxNVOswbmsthoKS
  615. mVZ/qyal7JLrX9uU/6XLkWMAFKAScUeB00LWv6WNu6xEHv//SlXrH3+fHn/w8HUxwac0C5mwdBYqFcuqAAMkj9IRzpgx4tu4NRTI/03oQoCH/3
  616. 554fjA538OtQZMeIY7CBIDQousJOIUjN5p6NXj1o5pO07cCe04XJwZ16yidMdw28Q45SN+LRnftz/OnOqWQxA5YSmM4BUpRyO/iu5QyL0W8lBI
  617. nCVEcQ0X8s2ay+ajxfA/TNOvG/jkdUByxAkBYhDnnxrlqY5qbJWVKGT/RvVyRXPejnBj6/DZNGquc+Lrv4d/6fJC+pv69+ztMXCW0sEIGmBBH2
  618. fH48TfW/Rq6TbVYZm0Dmv5SYNow3IIzXhtXLs6Jo1/5SrDXrs+s5D/kbN/tT+lWEKPp2hoe0Uh6nXCJEZoWQ6pCHduED4oSCdjyfK3Df/3/N0x
  619. WjppMjoypH+cmJM8KqRsHCM5PqBbwA3DurQKaRGuw0Nsb4/fYHtbfE//aDF1dvfISojD9H54kqQGRCyi4CT5IsdsaUBKLtZ7G0l6G/yZa9fLZc
  620. f48pUrrfZnG/avbbPcJIGGQKxYdoKgN4LEUapoCU1YTQgxSIWpPJfo4/+u4XX+Uy5fvcqq4Ms/bNi/xqul42fY61hBZKOOLHO7wuznDI/VjH6o
  621. MP3bVtylOShiayhZO8if4FvwdejZv3gP6WBalriUp6LhlhMzm4QIK4GWDFgaR+jkxPNz85Y+sY9/5yaNj8vl/84kluDT78UfLd1dbRIvJs4Frh
  622. idXyNMCCU/aTRd9SS3igIYbGxl+Ph3bn5aLn9CC3i/rf8LvfjDfWDOOLz2MxmEdXIh2kNOzzUWELF3jLTkfgE5Cx3Pzc9Z+vj4Nz+tlcu1T262
  623. xw/DRvynMocp5wgqcqBkFpoWcWAgoSMsSaOiIq0JcEtyv0k0sJMk+oaPXwZ+uRN+M/+ZQeqU8DX5EnEMAPeh/5A/ZDw3r3GYi/GIo9+1ra1O9x
  624. +BT0PwnSv4wO8/ePkXW1YCbZhsYQL3v9EnrFgTS4xlOcTAKoJ++J9IiqaW+OvRD1fwYSv/i0n+G4k6SwYm2afcsHBTiDVIC1nG83OauRDX6cnl
  625. nHz1a0nVbKv/ufkx8O904n9luSvL+pspr3aJT/LHA/85gd/QWojZ/7GBUtEqKZtxf9W4qSl8qH4ZRtAWn/wah1z3L4gsXjsbMFqMXOyMs3Pivy
  626. 9/WEDdeKTbBfST7dEgG+yAT3PrxpWhXLlzwuPUoC5/iMi/I+J0YtZH6dvGXJ2J0kTwFkamefnnn/6cjOa3v7T2Hz3WWefYXIhxlg9li1gJzUde
  627. a/CG/GSZbCu1mpWk6MH/jw/wFx//Aw==
  628. ]=],
  629. [=[
  630. 7ZnNbxtVEMAdx3b3Oa6S2FEbWr6qqoJIVP1KKkAg0QSklrT0SyoICr30AA0trZUUqRxImwbxceDEhUqFUgkQnBDnnNqKVnL29b21cWKZrNM/gb
  631. +Amfex3l3vOvbaLRwYe9fr1G9/M/PmzZvZ9pCEkHg8m83Ge+PxeG9vFs9xEkNJb0iDrItpmZ2fnftsdv7q5SuX567Mx2KZs/sPvD558FA22//O
  632. sRPvnZuYOPT4nrGBgY1PPCl+f/b44RMnX9vnjD83dSD9bKbvzBtvHTr11OZYrG9DToiRzo3t3b6rb9Pw5m29qcTw0O5R8fvhTTtGd2552hk/NN
  633. Sf3jOYG3hsdO/2sR2xtaUH3j09ztd4pue0Ecv0Z1LpSSOz9vDk8SRILLLETwO716NPj1DIpVNb4hufmUwrGRoa0lfiPNnS7QqtiMWYzSxLvJm+
  634. sCzbKjwakTg8EOrS4CGwlpaXlyu+vz2oWJaCW56rhwBfsSxe86tQ5dzi0nApCGes6/gVLgRuXqv4+JzX0erEuo4XTpU6eBSoVRTeZkxcWYx3na
  635. +tV1Jb/qsuK9p6Jh3EkN/m/W2U5ngMPiFgL6WLLjGpaVI8OLfRA3C0D7ebqCCsr2orq5wCasnlgeUKGk9NORHw26j44FUDeLhptVwucziAj5b6
  636. YgBn32QR8eWyosPaDfhFlV+d53xC2z/BTfRzteBVgDEaDQ82lW2RWvDCDuJ//oXHfgR5+YXaqrI/ivWAxVVcFXw7yP3MM/8I8k4AiuBHiHs/32
  637. 4wX6255VX+ANy0QgXf5wCQxRZTti/0BLW2Sh+sBK+CqlhWHKPexLdYaLwVPqZsULUWqoJjvm1TU4RfMJ+zcQZRPw6a1BPNmvylFZgUlD9YrbLG
  638. 0qNU7V2NfEywuLBNrjK9nA+8e1O++IEOmkAFtPvLt++YwguhDkicvzBIsrOpdBPzfXylXzMFFL1cvnuPis9gBwDfmJ4hU4QQw8Gvxa+7J1wBZ/
  639. atKgYXRQWCJ+DHn4iQvNqAGGt0v4fv+me9P1dZ6PTv3LUbfGuqPNiwAmuVX36VfKMJ3s3HmHfJqg0Ld6UhNenEa4+O7SUjBg3jF2oZYH/00suK
  640. H4z38Jm2mjvlSUBmVgnHfv4F9K1jf+Ote6HQvwhHrgney1+qW19Zk58XvqWW+hpwb70I8cyD8S6+mO2yEp25eaMCMuQtKzMn+U2qAKGA1CEE7+
  641. c7kkjOvn3+Qiod6ADBX588cvTdnNm0CKmJygf9GoL38e879htbyanpmRGDYdXkG7K4qNYgrj+5+sJ3KwzqYHgJxce/r6MP+S+if83FvxuVVrsK
  642. HUdHgCbtF6cCXiyVzFLJP/94YhBdbxJYXyYN2p5tS9deFrqifXxR8ovIrysgEsAqww07o3IHZSEdnNM4RcIXJb5YpPjhybmyJFoPWwes3pzJCs
  643. 0UaD734XihAB6CX3L4ql4Qxbn8YE262ODSs4W5l3wUs+RRgCaSSczqFNYsaNDtnki0eSW3UPWpFDAzT8GsHzZF9dhlvOgFfXhT90Gm6ooSg2QL
  644. 2U8F3+w+3sc3qXOpYhDs30YOchWI3X3mIRo9VlLTDwc19TJwFiFsWr//lpMLgXYVL3YijQcirD1aKjlfS97KB2XRVYzwjvGyyWVy3QmmqVzv4W
  645. sV9N7ARA/HJ9ptkD2idkHlfjUDzuT7+e69CeGfXrq0UYyPipezabpyi/gs6jQQzhcjPykUNjLtlKh8k8pbOAFfLGq+PAfx5ZDvb9z4gXWigAtf
  646. V6BYchQIxsM2i7+HBmoczh0owHSf7+YXtYTzYY4g+jh3PSyLpIDMJfomjvH1pRfMx5BxOhddDkZRgOlG0HFAsVSsb8HiKnDYnyAJUUTjO5V4ZR
  647. 8UhBH9z+t2OOY7sxCEL0wIfv7mze/UyyAjI0ZEvpmYTSXe/+CMaEbd8y6uQ3IG8g3y9TfyRQzRzEWbALMPirkPz54TzShzxX1I7Al+4sjRkzky
  648. PSNf5FXZzEbgc0ZhLNZ0eRkDa+ORb4ga8Pr1a19+9e01QvZH53PeT8hAclA248yzC4fn7PxWQo6jCtMzzz1DyEFCpvKRViDcSxW0eeZNBM3GMG
  649. gCyCniCHRcU0a0FMTZ+oupdSPZlCEferMR1sKYzDARXYiSBDazEVMw7n559TCgxWftnN1KJlOJjy9Ao3cMzimjk00QkBlsaAS/pXKCsQUQ4+cZ
  650. tB3PRkeFCPQU+mFAizdht+8sLOTr85/vrA5y/X9DiyPu3ltYyMzNzUm88F1nZVi7z5rB/7d0+he+KzxiES7DMIi693VDgQWIg07Kr04VWIA4+L
  651. fw7nr8f/nvyz8=
  652. ]=]}
  653. local D_SFX={[0]={39,11,13,7,8,11,3,7,3,5,6,12,14,2,1,6,8,13,11,1,5,6,7,10,10,3,6,37},{39,11,13,7,8,11,3,7,3,5,6,12,14,2,1,6,8,13,11,1,5,6,7,10,10,3,6,37},{41,9,4,1,37},{39,2,7,12,17,22,27,32,27,22,17,12,7,2,37},{42,23,13,18,35,15,21,9,23,3,37},{39,38,14,38,14,38,14,38,14,38,4,38,4,38,4,38,4,37},{40,2,38,14,38,37},{39,38,14,38,14,38,14,38,14,38,4,38,4,38,4,38,4,37},{39,7,19,6,18,7,19,6,18,7,19,6,18,7,19,37},{39,36,35,34,33,32,31,37},{40,9,21,11,23,13,25,14,2,14,2,14,37},{39,1,38,1,38,1,38,1,37},{39,21,19,17,15,13,21,37},{39,13,12,11,10,11,12,13,37},{40,11,13,14,16,18,19,21,37},{40,14,4,37},{40,17,37},{40,17,37},{44,7,0,9,0,12,0,16,0,0,14,0,0,16,0,17,0,0,16,0,0,17,0,19,0,0,0,0,0,37},{47,13,0,11,0,9,0,8,0,6,0,2,0,0,4,0,0,6,0,0,0,0,0,37}}
  654. local D_SONGS={[0]={48,1,3,4,6,8,0,6,4,6,38,11,38,9,38,6,4,6,38,11,38,9,38,4,3,4,38,9,38,8,0,0,0,1,3,4,6,8,0,6,4,6,38,11,38,9,38,6,4,6,38,15,38,11,38,9,8,9,0,0,0,8,0,0,0,9,0,20,0,21,0,11,9,8,0,18,0,20,0,9,8,6,38,18,0,20,0,2,4,8,9,8,6,8,0,0,0,9,0,20,0,21,0,11,9,8,0,18,0,20,0,9,8,6,0,18,0,20,0,2,6,13,0,11,9,11,0,0,0,1,3,4,6,8,0,6,4,6,38,11,38,9,38,6,4,6,38,11,38,9,38,4,3,4,38,9,38,8,0,0,0,1,3,4,6,8,0,6,4,6,38,11,38,9,38,6,4,6,38,15,38,11,38,9,8,9,0,0,0,8,0,0,38,8,0,19,0,20,0,22,20,19,0,5,0,7,0,20,19,17,0,5,0,7,0,1,3,7,8,7,5,7,0,0,0,8,0,19,0,20,0,10,8,7,0,17,0,19,0,8,7,5,0,17,0,19,0,3,4,9,0,6,0,8,0,0},{46,3,0,38,3,15,0,0,3,0,0,15,0,1,13,2,14,3,0,38,3,15,0,0,3,0,0,15,0,1,13,2,14,15,38,0,15,38,0,15,38,0,15,0,18,0,15,38,15,38,0,15,38,0,15,38,0,15,0,20,0,15,38,15,38,0,15,38,0,15,38,0,15,0,18,0,15,0,13,0,0,14,0,0,15,48,0,0,38,0,0,46,15,38,0,15,38,0,15,38,0,15,0,18,0,15,0,15,38,0,15,38,0,15,38,0,15,0,20,0,15,38,15,38,0,15,38,0,15,38,0,15,0,18,0,15,0,13,0,0,14,0,0,15,0,0,0,14,0,13,0,12,38,12,0,0,14,0,0,15,48,0,0,0,38,0,0,0,46,12,0,0,14,0,0,17,48,0,0,0,38,0,0,0,46,12,0,0,14,0,0,19,0,0,0,20,0,19,0,17,0,12,0,0,14,0,0,15,48,0,0,0,38,0,0,0,46,12,0,0,14,0,0,17,48,0,0,0,38,0,0,0,46,12,0,0,14,0,0,19,0,0,0,20,0,19,0,17,0,15,0,14,0,13,46,0},{44,2,0,9,0,14,0,9,0,14,0,9,0,2,0,9,0,12,0,9,0,12,0,9,0,2,0,9,0,14,0,9,0,14,0,9,0,2,0,9,0,12,0,9,0,12,0,9,0,47,14,0,0,0,0,44,12,0,0,0,9,0,12,0,0,0,0,0,2,0,9,0,12,0,0,0,9,0,12,0,47,14,0,0,0,0,44,12,0,9,0,38,0,9,0,38,0,0,0,9,0,12,0,16,0,17,0,16,0,12,0,47,14,0,0,0,0,44,12,0,0,0,9,0,12,0,0,0,0,0,2,0,9,0,12,0,0,0,9,0,12,0,47,14,0,0,0,0,44,16,0,0,0,0,0,19,0,0,0,0,0,0,2,0,5,0,7,0,9,0,7,0,11,0,47,16,0,0,0,0,44,14,0,12,0,38,0,12,0,38,0,14,0,38,0,11,0,0,0,0,0,9,0,11,0,16,0,38,0,16,0,18,0,38,0,23,0,38,0,21,0,0,0,0,0,0,0,18,0,0,0,0,0,0,0,20,0,0,0,0,0,0,17,0,0,0,0,0,0,19,0,0,0,0,0,0}}
  655. local D_INTRO_MUSIC={45,6,18,15,3,15,13,8,18,3,6,8,10,3,18,3,9,45,3,0,1,1,3,38,6,38,0,0,1,38,3,1,0,0,3,0,1,1,3,38,6,38,0,0,1,38,8,6,0,0,3,0,1,1,3,38,6,38,0,0,1,38,3,1,0,0,8,10,8,0,6,0,3,1,3,38,6,38,3,38,0,0,15,0,13,15,38,0,18,0,0,0,13,15,18,0,15,38,15,0,13,15,38,0,18,0,0,0,13,15,20,0,18,0,15,0,13,15,38,0,18,0,0,0,13,15,20,0,15,0,20,22,20,0,18,0,15,13,15,38,18,38,15,38,0,0,15,0,13,15,38,0,18,0,0,0,13,15,18,38,15,38,15,0,13,15,38,0,18,0,0,0,13,15,18,0,20,0,15,0,13,15,38,0,18,0,0,0,13,15,18,0,15,0,20,22,20,0,18,20,18,0,15,18,13,0,15,8,10,11,15,4,1,4,13,4,1,4,15,4,1,4,18,4,1,4,13,4,15,4,18,4,1,4,13,4,1,4,11,10,8,6,8,4,1,4,15,4,1,4,13,4,1,4,11,0}
  656. local NOTE_FREQ={[0]=0,251,238,224,210,199,188,177,168,158,149,140,133,251,238,224,210,199,188,177,168,158,149,140,133,251,238,224,210,199,188,177,168,158,149,140,133}
  657. local NOTE_OCT={[0]=0,15,15,15,15,15,15,15,15,15,15,15,15,51,51,51,51,51,51,51,51,51,51,51,51,85,85,85,85,85,85,85,85,85,85,85,85}
  658. local ART={weapon={{44,32,32,32,32,44},{226,249,239,228,102,102},{32,32,32,32,95,223},{32,32,32,32,32,32}},pistol={{32,32,32,32,32,32},{32,104,98,98,98,32},{32,32,32,95,223,32},{32,32,32,32,32,32}},bomb={{32,32,85,42,32,32},{32,85,102,73,32,32},{32,66,32,72,32,32},{32,74,70,75,32,32}},emp={{32,85,67,67,73,32},{102,223,85,73,233,102},{102,105,74,75,95,102},{32,74,70,70,75,32}},magnet={{77,112,110,112,110,78},{32,66,66,72,72,32},{99,66,74,75,72,99},{78,74,70,70,75,77}},medkit={{32,85,67,67,73,32},{32,160,160,160,160,32},{32,160,235,243,160,32},{32,228,228,228,228,32}}}
  659. local GAMEOVER={{112,64,64,64,64,64,64,64,64,64,110},{93,7,1,13,5,32,15,22,5,18,93},{109,64,64,64,64,64,64,64,64,64,125}}
  660. local OUCH={{205,160,160,160,160,206},{160,143,149,131,136,160},{206,160,160,160,160,205}}
  661. local CP={[0]=64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,163,93,8593,8592,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,9473,9824,9475,9473,9473,9620,9473,9475,9475,9491,9495,9499,9625,9586,9585,9627,9628,9679,9601,9829,9615,9487,9587,9675,9827,9621,9830,9547,9617,9475,960,9701,32,9612,9604,9620,9601,9614,9618,9621,9617,9700,9624,9507,9623,9495,9491,9602,9487,9531,9523,9515,9614,9613,9615,9600,9600,9603,9631,9622,9629,9499,9624,9626}
  662. local CPINV={[32]=9608,[96]=9608,[97]=9616,[98]=9600,[102]=9618,[108]=9627,[123]=9628,[124]=9625,[126]=9631,[127]=9630}
  663.  
  664. -- ------------------------------------------------------- screen buffer
  665. -- scr[i+1] holds the PET screen code for screen offset i (row*40+col)
  666. local scr, shadow = {}, {}
  667. for i = 1, 1000 do scr[i] = 32; shadow[i] = -1 end
  668. local function scr_set(off, code) scr[off + 1] = code end
  669. local function P(off, code) scr[off + 1] = code end
  670. local function scr_get(off) return scr[off + 1] end
  671. local function xor80(c) if c < 128 then return c + 128 end return c - 128 end
  672.  
  673. local GS, GSW = {}, {}
  674. for c = 0, 255 do
  675. if c < 128 then
  676. GS[c] = ucode(CP[c]); GSW[c] = false
  677. else
  678. local b = c - 128
  679. if CPINV[b] then GS[c] = ucode(CPINV[b]); GSW[c] = false
  680. else GS[c] = ucode(CP[b]); GSW[c] = true end
  681. end
  682. end
  683.  
  684. local curswap = nil
  685. local function setswap(sw)
  686. if curswap == sw then return end
  687. curswap = sw
  688. if sw then gpu.setBackground(FG); gpu.setForeground(BG)
  689. else gpu.setBackground(BG); gpu.setForeground(FG) end
  690. end
  691.  
  692. local function flush()
  693. for y = 0, 24 do
  694. local base = y * 40
  695. local x = 0
  696. while x < 40 do
  697. local i = base + x + 1
  698. if scr[i] ~= shadow[i] then
  699. local sw = GSW[scr[i]]
  700. local chars, nch = {}, 0
  701. local xs, last, gap, j = x, x, 0, x
  702. while j < 40 do
  703. local ij = base + j + 1
  704. local c = scr[ij]
  705. if GSW[c] ~= sw then break end
  706. if c ~= shadow[ij] then last = j; gap = 0
  707. else gap = gap + 1; if gap > 2 then break end end
  708. nch = nch + 1; chars[nch] = GS[c]
  709. j = j + 1
  710. end
  711. local cnt = last - xs + 1
  712. for k = xs, last do shadow[base + k + 1] = scr[base + k + 1] end
  713. setswap(sw)
  714. gpu.set(xs + 1, y + 1, concat(chars, "", 1, cnt))
  715. x = last + 1
  716. else
  717. x = x + 1
  718. end
  719. end
  720. end
  721. end
  722.  
  723. local function invalidate() for i = 1, 1000 do shadow[i] = -1 end end
  724. local function cls() for i = 1, 1000 do scr[i] = 32 end end
  725.  
  726. local SCREENS = unpack_blob(D_SCREENS)
  727. local function show_screen(n) -- n = 0..3 : intro, game, endgame, custom keys
  728. local d = SCREENS
  729. local o = n * 1000
  730. for i = 1, 1000 do scr[i] = sbyte(d, o + i) end
  731. end
  732.  
  733. -- ------------------------------------------------------- text helpers
  734. local function tc(ch) -- source char -> PET screen code
  735. local b = sbyte(ch)
  736. if b >= 97 and b <= 122 then return b - 96 end
  737. return b
  738. end
  739. local function put_text(off, s) -- write text at screen offset (row*40+col)
  740. for i = 1, #s do scr_set(off + i - 1, tc(ssub(s, i, i))) end
  741. end
  742.  
  743. -- ------------------------------------------------------- data decode
  744.  
  745. local TL, TM, TR, ML, MM, MR, BL, BM, BR = {}, {}, {}, {}, {}, {}, {}, {}, {}
  746. local TT = {TL, TM, TR, ML, MM, MR, BL, BM, BR}
  747. local DESTRUCT, ATTR = {}, {}
  748. local T_WALK, T_HOVER, T_MOVE, T_DESTR, T_SEE, T_PLACE, T_SEARCH = {}, {}, {}, {}, {}, {}, {}
  749. do
  750. local d = unpack_blob(D_TILES)
  751. for t = 0, 255 do
  752. DESTRUCT[t] = sbyte(d, t + 1)
  753. local a = sbyte(d, 256 + t + 1)
  754. ATTR[t] = a
  755. T_WALK[t] = a % 2 == 1
  756. T_HOVER[t] = floor(a / 2) % 2 == 1
  757. T_MOVE[t] = floor(a / 4) % 2 == 1
  758. T_DESTR[t] = floor(a / 8) % 2 == 1
  759. T_SEE[t] = floor(a / 16) % 2 == 1
  760. T_PLACE[t] = floor(a / 32) % 2 == 1
  761. T_SEARCH[t] = floor(a / 64) % 2 == 1
  762. for k = 1, 9 do TT[k][t] = sbyte(d, (k + 1) * 256 + t + 1) end
  763. end
  764. end
  765.  
  766. -- ------------------------------------------------------- game state
  767. local utype, ux, uy, ua, ub, uc, ud, uhealth = {}, {}, {}, {}, {}, {}, {}, {}
  768. local utimera, utimerb, utile = {}, {}, {}
  769. local rows = {}
  770. local KEYS, AMMO_PISTOL, AMMO_PLASMA = 0, 0, 0
  771. local INV_BOMBS, INV_EMP, INV_MEDKIT, INV_MAGNET = 0, 0, 0, 0
  772. local SELW, SELI, SELECT_TIMEOUT = 0, 0, 0
  773. local BIG_EXP_ACT, MAGNET_ACT, PLASMA_ACT = 0, 0, 0
  774. local RANDOM, BORDER, SCREEN_SHAKE = 0, 0, 0
  775. local KEYTIMER, BGTIMER2 = 0, 0
  776. local WX, WY = 0, 0
  777. local CURSOR_X, CURSOR_Y, CURSOR_ON = 0, 0, 0
  778. local REDRAW = 0
  779. local SEL_MAP, DIFF = 0, 1
  780. local CONTROL = 0
  781. local HOURS, MINUTES, SECONDS, CYCLES, CLOCK_ACTIVE = 0, 0, 0, 0, 0
  782. local EXP_BUF = {}
  783. local MODE = "none" -- "game" while the game screen is live
  784. local WORLD = false -- run unit AI each tick
  785. local QUIT = {}
  786.  
  787. local function gettile(x, y)
  788. if x < 0 or x > 127 or y < 0 or y > 63 then return 0 end
  789. return sbyte(rows[y], x + 1)
  790. end
  791. local function puttile(x, y, t)
  792. if x < 0 or x > 127 or y < 0 or y > 63 then return end
  793. local r = rows[y]
  794. rows[y] = ssub(r, 1, x) .. schar(t) .. ssub(r, x + 2)
  795. end
  796.  
  797. local function load_level(n)
  798. local L = unpack_blob(D_LEVELS[n + 1])
  799. local names = {utype, ux, uy, ua, ub, uc, ud, uhealth}
  800. for k = 1, 8 do
  801. local arr = names[k]
  802. for i = 0, 63 do arr[i] = sbyte(L, (k - 1) * 64 + i + 1) end
  803. end
  804. for i = 0, 63 do utimera[i] = 0; utimerb[i] = 0; utile[i] = 0 end
  805. for y = 0, 63 do rows[y] = ssub(L, 513 + y * 128, 640 + y * 128) end
  806. end
  807.  
  808. local function xor8(a, b)
  809. local res, bit = 0, 1
  810. for _ = 1, 8 do
  811. if (a % 2) ~= (b % 2) then res = res + bit end
  812. a = floor(a / 2); b = floor(b / 2); bit = bit * 2
  813. end
  814. return res
  815. end
  816. local function random_number() -- 6502 LFSR from the original
  817. local r = RANDOM
  818. if r ~= 0 then
  819. r = r * 2
  820. if r <= 255 then RANDOM = r; return end
  821. r = r % 256
  822. end
  823. RANDOM = xor8(r, 0x1D)
  824. end
  825.  
  826. -- ------------------------------------------------------- sound
  827. local SFX_ON = not QUIET
  828. local MUSIC_ON = false
  829. local mus = {pat = nil, line = 0, tempo = 7, timer = 0}
  830. local fx = {pat = nil, line = 0, tempo = 7, timer = 0, id = 255}
  831. local pending_note = nil
  832.  
  833. local function note_freq(n)
  834. if n < 1 or n > 36 then return nil end
  835. local N = NOTE_FREQ[n]
  836. local o = NOTE_OCT[n]
  837. local shifts = (o == 15 and 8) or (o == 51 and 4) or 2
  838. local f = 1000000 / (shifts * (N + 2))
  839. while f > 2000 do f = f / 2 end
  840. if f < 20 then f = 20 end
  841. return floor(f)
  842. end
  843.  
  844. local function voice_step(v)
  845. if v.timer > 0 then v.timer = v.timer - 1; return nil end
  846. local pat = v.pat
  847. if not pat then return nil end
  848. local b = pat[v.line + 1]
  849. if b == nil then v.line = 0; b = pat[1] end
  850. if b == 0 then
  851. v.timer = v.tempo; v.line = v.line + 1
  852. elseif b == 37 then
  853. return "end"
  854. elseif b == 38 then
  855. pending_note = nil
  856. v.timer = v.tempo; v.line = v.line + 1
  857. elseif b >= 39 and b <= 48 then
  858. v.tempo = b - 38; v.line = v.line + 1
  859. else
  860. pending_note = note_freq(b % 64)
  861. v.timer = v.tempo; v.line = v.line + 1
  862. end
  863. return nil
  864. end
  865.  
  866. local function music_tick()
  867. if not SFX_ON then return end
  868. if fx.id ~= 255 then
  869. if voice_step(fx) == "end" then fx.id = 255; fx.pat = nil; pending_note = nil end
  870. elseif MUSIC_ON then
  871. if voice_step(mus) == "end" then mus.line = 0 end
  872. end
  873. end
  874.  
  875. local function play_sound(n)
  876. if not SFX_ON then return end
  877. if fx.id ~= 255 and n > fx.id then return end
  878. fx.pat = D_SFX[n]; fx.line = 0; fx.timer = 0; fx.tempo = 7; fx.id = n
  879. end
  880.  
  881. local function stop_song()
  882. fx.id = 255; fx.pat = nil; pending_note = nil
  883. end
  884.  
  885. local function start_music(pat)
  886. mus.pat = pat; mus.line = 0; mus.timer = 0; mus.tempo = 7
  887. MUSIC_ON = true
  888. end
  889.  
  890. local function emit_sound()
  891. if pending_note then
  892. local f = pending_note
  893. pending_note = nil
  894. pcall(computer.beep, f, 0.08)
  895. end
  896. end
  897.  
  898. -- ------------------------------------------------------- tile animation
  899. local WATER_TIMER, HVAC_STATE, CINEMA_STATE = 0, 0, 0
  900. local CINEMA = {}
  901. do
  902. local msg = "coming soon: space balls 2 - the search for more money, " ..
  903. "attack of the paperclips: clippy's revenge, it came from planet earth, " ..
  904. "rocky 5000, all my circuits the movie, conan the librarian, and more! "
  905. for i = 1, #msg do CINEMA[i - 1] = tc(ssub(msg, i, i)) end
  906. end
  907. local CINEMA_LEN = #CINEMA + 1
  908.  
  909. local function animate_tiles()
  910. WATER_TIMER = WATER_TIMER + 1
  911. if WATER_TIMER < 20 then return end
  912. WATER_TIMER = 0
  913. local t
  914. t = BR[204]; BR[204] = MM[204]; BR[221] = MM[204]; MM[204] = TL[204]; TL[204] = t
  915. t = BL[204]; BL[204] = MR[204]; BL[221] = MR[204]; MR[204] = TM[204]; TM[204] = t; TM[221] = t
  916. t = BM[204]; BM[204] = ML[204]; BM[221] = ML[204]; ML[204] = TR[204]; TR[204] = t; TR[221] = t
  917. -- trash compactor
  918. t = TR[148]; TR[148] = TM[148]; TM[148] = TL[148]; TL[148] = t
  919. t = MR[148]; MR[148] = MM[148]; MM[148] = ML[148]; ML[148] = t
  920. t = BR[148]; BR[148] = BM[148]; BM[148] = BL[148]; BL[148] = t
  921. -- HVAC fan
  922. if HVAC_STATE ~= 0 then
  923. MM[196] = 0xCD; TL[201] = 0xCD; ML[197] = 0xCE; TM[200] = 0xCE
  924. MR[196] = 0xA0; BM[196] = 0xA0; BL[197] = 0xA0; TR[200] = 0xA0
  925. HVAC_STATE = 0
  926. else
  927. MM[196] = 0xA0; TL[201] = 0xA0; ML[197] = 0xA0; TM[200] = 0xA0
  928. MR[196] = 0xC2; TR[200] = 0xC2; BM[196] = 0xC0; BL[197] = 0xC0
  929. HVAC_STATE = 1
  930. end
  931. -- cinema screen
  932. MM[20] = MR[20]; MR[20] = ML[21]; ML[21] = MM[21]; MM[21] = MR[21]; MR[21] = ML[22]
  933. ML[22] = CINEMA[CINEMA_STATE]
  934. CINEMA_STATE = CINEMA_STATE + 1
  935. if CINEMA_STATE == CINEMA_LEN then CINEMA_STATE = 0 end
  936. -- server light
  937. if MR[143] == 0xD7 then MR[143] = 0xD1 else MR[143] = 0xD7 end
  938. REDRAW = 1
  939. end
  940.  
  941. (function()
  942.  
  943. -- ------------------------------------------------------- side panel displays
  944. -- NOTE: the original proximity test for robot attacks (CMP #1) can only be true
  945. -- for the player's own tile, so robots would never hurt you. The comments say
  946. -- "robot next to player"; ATTACK_RANGE = 2 gives that. Set to 1 for the
  947. -- literal behaviour of the shipped code.
  948. local ATTACK_RANGE = 2
  949.  
  950. local function decwrite(off, n)
  951. n = n % 256
  952. P(off, 0x30 + floor(n / 100)); P(off + 1, 0x30 + floor(n / 10) % 10); P(off + 2, 0x30 + n % 10)
  953. end
  954.  
  955. local function display_player_health()
  956. local h = uhealth[0]
  957. local half = floor(h / 2)
  958. local y = 0
  959. while y < half do P(0x3BA + y, 0x66); y = y + 1 end
  960. if h % 2 == 1 then P(0x3BA + y, 0x5C); y = y + 1 end
  961. while y < 6 do P(0x3BA + y, 0x20); y = y + 1 end
  962. end
  963.  
  964. local function draw_art(off, art, nrows)
  965. for r = 1, nrows do
  966. local row = art[r]
  967. for i = 1, 6 do P(off + (r - 1) * 40 + i - 1, row[i]) end
  968. end
  969. end
  970. local function blank_area(off)
  971. for r = 0, 4 do for i = 0, 5 do P(off + r * 40 + i, 32) end end
  972. end
  973.  
  974. local function preselect_weapon()
  975. if SELW ~= 0 then return end
  976. if AMMO_PISTOL ~= 0 then SELW = 1
  977. elseif AMMO_PLASMA ~= 0 then SELW = 2
  978. else SELW = 0; blank_area(0x4A) end
  979. end
  980. local function display_weapon()
  981. while true do
  982. preselect_weapon()
  983. if SELW == 0 then return end
  984. if SELW == 1 then
  985. if AMMO_PISTOL == 0 then SELW = 0
  986. else draw_art(0x4A, ART.pistol, 4); decwrite(0xED, AMMO_PISTOL); return end
  987. elseif SELW == 2 then
  988. if AMMO_PLASMA == 0 then SELW = 0
  989. else draw_art(0x4A, ART.weapon, 4); decwrite(0xED, AMMO_PLASMA); return end
  990. else SELW = 0 end
  991. end
  992. end
  993.  
  994. local function preselect_item()
  995. if SELI ~= 0 then return end
  996. if INV_BOMBS ~= 0 then SELI = 1
  997. elseif INV_EMP ~= 0 then SELI = 2
  998. elseif INV_MEDKIT ~= 0 then SELI = 3
  999. elseif INV_MAGNET ~= 0 then SELI = 4
  1000. else SELI = 0; blank_area(0x162) end
  1001. end
  1002. local function display_item()
  1003. preselect_item()
  1004. while true do
  1005. local s = SELI
  1006. if s == 0 then return end
  1007. if s == 5 then SELI = 0; return end
  1008. if s == 1 then
  1009. if INV_BOMBS == 0 then SELI = 2 else draw_art(0x162, ART.bomb, 4); decwrite(0x205, INV_BOMBS); return end
  1010. elseif s == 2 then
  1011. if INV_EMP == 0 then SELI = 3 else draw_art(0x162, ART.emp, 4); decwrite(0x205, INV_EMP); return end
  1012. elseif s == 3 then
  1013. if INV_MEDKIT == 0 then SELI = 4 else draw_art(0x162, ART.medkit, 4); decwrite(0x205, INV_MEDKIT); return end
  1014. elseif s == 4 then
  1015. if INV_MAGNET == 0 then SELI = 0; preselect_item(); return display_item()
  1016. else draw_art(0x162, ART.magnet, 4); decwrite(0x205, INV_MAGNET); return end
  1017. else SELI = 0 end
  1018. end
  1019. end
  1020.  
  1021. local function display_keys()
  1022. for i = 0, 5 do P(0x27A + i, 32); P(0x2A2 + i, 32) end
  1023. if KEYS % 2 == 1 then P(0x27A, 0x63); P(0x27B, 0x4D); P(0x2A2, 0x41); P(0x2A3, 0x67) end
  1024. if floor(KEYS / 2) % 2 == 1 then P(0x27C, 0x63); P(0x27D, 0x4D); P(0x2A4, 0x53); P(0x2A5, 0x67) end
  1025. if floor(KEYS / 4) % 2 == 1 then P(0x27E, 0x63); P(0x27F, 0x4D); P(0x2A6, 0x2A); P(0x2A7, 0x67) end
  1026. end
  1027.  
  1028. -- info window (3 lines at the bottom left)
  1029. local function scroll_info()
  1030. for x = 0, 32 do
  1031. scr[0x370 + x + 1] = scr[0x398 + x + 1]
  1032. scr[0x398 + x + 1] = scr[0x3C0 + x + 1]
  1033. scr[0x3C0 + x + 1] = 32
  1034. end
  1035. end
  1036. local function print_info(text)
  1037. scroll_info()
  1038. local x = 0
  1039. for i = 1, #text do
  1040. local ch = ssub(text, i, i)
  1041. if ch == "\n" then x = 0; scroll_info()
  1042. else
  1043. if x < 33 then P(0x3C0 + x, tc(ch)) end
  1044. x = x + 1
  1045. end
  1046. end
  1047. end
  1048.  
  1049. -- ------------------------------------------------------- map window
  1050. local PRE = {}
  1051. local function reverse_tile()
  1052. local o = CURSOR_Y * 120 + CURSOR_X * 3
  1053. for r = 0, 2 do for c = 0, 2 do
  1054. local i = o + r * 40 + c + 1
  1055. if scr[i] then scr[i] = xor80(scr[i]) end
  1056. end end
  1057. end
  1058.  
  1059. local function draw_map_window()
  1060. for i = 0, 76 do PRE[i] = 0 end
  1061. for u = 0, 31 do
  1062. local ok
  1063. if u == 0 then ok = true
  1064. else ok = utype[u] ~= 0 and ux[u] >= WX and ux[u] <= WX + 10 and uy[u] >= WY and uy[u] <= WY + 6 end
  1065. if ok then
  1066. local dx, dy = ux[u] - WX, uy[u] - WY
  1067. if dx >= 0 and dx <= 10 and dy >= 0 and dy <= 6 then
  1068. local idx = dy * 11 + dx
  1069. local t = utile[u]
  1070. if (t == 130 or t == 134) and PRE[idx] ~= 0 then
  1071. else PRE[idx] = t end
  1072. end
  1073. end
  1074. end
  1075. REDRAW = 0
  1076. for ty = 0, 6 do
  1077. for tx = 0, 10 do
  1078. local t = gettile(WX + tx, WY + ty)
  1079. local o = ty * 120 + tx * 3 + 1
  1080. scr[o] = TL[t]; scr[o + 1] = TM[t]; scr[o + 2] = TR[t]
  1081. scr[o + 40] = ML[t]; scr[o + 41] = MM[t]; scr[o + 42] = MR[t]
  1082. scr[o + 80] = BL[t]; scr[o + 81] = BM[t]; scr[o + 82] = BR[t]
  1083. local s = PRE[ty * 11 + tx]
  1084. if s ~= 0 then
  1085. local c
  1086. c = TL[s]; if c ~= 0x3A then scr[o] = c end
  1087. c = TM[s]; if c ~= 0x3A then scr[o + 1] = c end
  1088. c = TR[s]; if c ~= 0x3A then scr[o + 2] = c end
  1089. c = ML[s]; if c ~= 0x3A then scr[o + 40] = c end
  1090. c = MM[s]; if c ~= 0x3A then scr[o + 41] = c end
  1091. c = MR[s]; if c ~= 0x3A then scr[o + 42] = c end
  1092. c = BL[s]; if c ~= 0x3A then scr[o + 80] = c end
  1093. c = BM[s]; if c ~= 0x3A then scr[o + 81] = c end
  1094. c = BR[s]; if c ~= 0x3A then scr[o + 82] = c end
  1095. end
  1096. end
  1097. if CURSOR_ON == 1 and ty == CURSOR_Y then reverse_tile() end
  1098. end
  1099. end
  1100.  
  1101. local function calc_and_redraw()
  1102. WX = ux[0] - 5; WY = uy[0] - 3
  1103. REDRAW = 1
  1104. end
  1105.  
  1106. local function check_window_redraw(u)
  1107. if ux[u] >= WX and ux[u] <= WX + 10 and uy[u] >= WY and uy[u] <= WY + 6 then REDRAW = 1 end
  1108. end
  1109.  
  1110. -- ------------------------------------------------------- unit helpers
  1111. local function check_for_unit(x, y)
  1112. for u = 0, 27 do
  1113. if utype[u] ~= 0 and ux[u] == x and uy[u] == y then return u end
  1114. end
  1115. return 255
  1116. end
  1117.  
  1118. local function check_for_hidden_unit(x, y)
  1119. for u = 48, 63 do
  1120. if utype[u] ~= 0 then
  1121. local ok = false
  1122. if ux[u] == x then ok = true
  1123. elseif ux[u] < x and ux[u] + uc[u] >= x then ok = true end
  1124. if ok then
  1125. ok = false
  1126. if uy[u] == y then ok = true
  1127. elseif uy[u] < y and uy[u] + ud[u] >= y then ok = true end
  1128. if ok then return u end
  1129. end
  1130. end
  1131. end
  1132. return 255
  1133. end
  1134.  
  1135. local function free_weapon_slot()
  1136. for u = 28, 31 do if utype[u] == 0 then return u end end
  1137. return nil
  1138. end
  1139.  
  1140. -- dir: 0 up, 1 down, 2 left, 3 right. mt: 1 walk, 2 hover. returns success
  1141. local DX = {[0] = 0, 0, -1, 1}
  1142. local DY = {[0] = -1, 1, 0, 0}
  1143. local function walk(u, dir, mt)
  1144. local x, y = ux[u], uy[u]
  1145. if dir == 3 and x == 122 then return false end
  1146. if dir == 2 and x == 5 then return false end
  1147. if dir == 1 and y == 60 then return false end
  1148. if dir == 0 and y == 3 then return false end
  1149. local nx, ny = x + DX[dir], y + DY[dir]
  1150. local t = gettile(nx, ny)
  1151. if mt == 1 then if not T_WALK[t] then return false end
  1152. else if not T_HOVER[t] then return false end end
  1153. if check_for_unit(nx, ny) ~= 255 then return false end
  1154. ux[u] = nx; uy[u] = ny
  1155. return true
  1156. end
  1157.  
  1158. local function inflict_damage(t, dmg)
  1159. local h = uhealth[t] - dmg
  1160. if h > 0 then
  1161. uhealth[t] = h
  1162. if t == 0 then display_player_health(); BORDER = 10 end
  1163. return
  1164. end
  1165. uhealth[t] = 0
  1166. if t == 0 then
  1167. utype[0] = 0
  1168. display_player_health()
  1169. BORDER = 10
  1170. else
  1171. if utype[t] ~= 8 then
  1172. utype[t] = 8; utimera[t] = 255; utile[t] = 115
  1173. end
  1174. end
  1175. end
  1176.  
  1177. local function alter_ai(t)
  1178. if utype[t] == 2 or utype[t] == 3 then utype[t] = 4 end
  1179. end
  1180.  
  1181. local function create_player_explosion()
  1182. local s = free_weapon_slot()
  1183. if not s then return end
  1184. utype[s] = 11; utile[s] = 248; utimera[s] = 1
  1185. ux[s] = ux[0]; uy[s] = uy[0]
  1186. end
  1187.  
  1188. local function in_range(u, r)
  1189. local dx = ux[u] - ux[0]; if dx < 0 then dx = -dx end
  1190. local dy = uy[u] - uy[0]; if dy < 0 then dy = -dy end
  1191. return dx < r and dy < r
  1192. end
  1193. local function robot_attack_range(u) return in_range(u, ATTACK_RANGE == 1 and 1 or 2) end
  1194. local function door_proximity(u) return in_range(u, 2) end
  1195.  
  1196. -- ------------------------------------------------------- explosions
  1197. local function bex_center(u)
  1198. local f = check_for_unit(ux[u], uy[u])
  1199. if f ~= 255 then inflict_damage(f, 11) end
  1200. end
  1201. local BDIRS = {{0, -1}, {0, 1}, {1, 0}, {-1, 0}, {1, -1}, {-1, -1}, {1, 1}, {-1, 1}}
  1202.  
  1203. local function big_exp_phase1(u)
  1204. if BIG_EXP_ACT ~= 0 then utimera[u] = 10; return end
  1205. BIG_EXP_ACT = 1; SCREEN_SHAKE = 1
  1206. play_sound(0)
  1207. bex_center(u)
  1208. for d = 1, 8 do
  1209. local x, y = ux[u], uy[u]
  1210. for step = 1, 2 do
  1211. x = x + BDIRS[d][1]; y = y + BDIRS[d][2]
  1212. local t = gettile(x, y)
  1213. if not T_SEE[t] then break end
  1214. EXP_BUF[(d - 1) * 2 + step - 1] = t
  1215. puttile(x, y, 246)
  1216. local f = check_for_unit(x, y)
  1217. if f ~= 255 then inflict_damage(f, 11) end
  1218. end
  1219. end
  1220. utile[u] = 246
  1221. ua[u] = 1
  1222. utimera[u] = 12
  1223. REDRAW = 1
  1224. end
  1225.  
  1226. local function restore_tile(x, y, orig)
  1227. if gettile(x, y) ~= 246 then return end
  1228. if orig == 131 then
  1229. puttile(x, y, 135)
  1230. local s = free_weapon_slot()
  1231. if not s then return end
  1232. utype[s] = 6; utile[s] = 131; ux[s] = x; uy[s] = y
  1233. utimera[s] = 10; ua[s] = 0
  1234. elseif T_DESTR[orig] then puttile(x, y, DESTRUCT[orig])
  1235. else puttile(x, y, orig) end
  1236. end
  1237.  
  1238. local function big_exp_phase2(u)
  1239. local cx, cy = ux[u], uy[u]
  1240. local ct = gettile(cx, cy)
  1241. puttile(cx, cy, 246)
  1242. restore_tile(cx, cy, ct)
  1243. for d = 1, 8 do
  1244. local x, y = cx, cy
  1245. for step = 1, 2 do
  1246. x = x + BDIRS[d][1]; y = y + BDIRS[d][2]
  1247. restore_tile(x, y, EXP_BUF[(d - 1) * 2 + step - 1] or 0)
  1248. end
  1249. end
  1250. REDRAW = 1
  1251. utype[u] = 0; BIG_EXP_ACT = 0; SCREEN_SHAKE = 0
  1252. end
  1253.  
  1254. -- ------------------------------------------------------- AI routines
  1255. local AI = {}
  1256. local function hoverbot_animate(u)
  1257. if utimerb[u] ~= 0 then utimerb[u] = utimerb[u] - 1; return end
  1258. utimerb[u] = 3
  1259. if utile[u] == 98 then utile[u] = 99 else utile[u] = 98 end
  1260. end
  1261.  
  1262. local function droid(u, a, b) -- a,b = the two directions (dir0 when A~=1)
  1263. hoverbot_animate(u)
  1264. utimera[u] = 10
  1265. if ua[u] ~= 1 then
  1266. if not walk(u, a, 2) then ua[u] = 1 end
  1267. else
  1268. if not walk(u, b, 2) then ua[u] = 0 end
  1269. end
  1270. check_window_redraw(u)
  1271. end
  1272. AI[2] = function(u) droid(u, 2, 3) end -- left / right
  1273. AI[3] = function(u) droid(u, 0, 1) end -- up / down
  1274.  
  1275. local function chase(u, mt)
  1276. if ux[u] ~= ux[0] then
  1277. if ux[u] < ux[0] then walk(u, 3, mt) else walk(u, 2, mt) end
  1278. end
  1279. if uy[u] ~= uy[0] then
  1280. if uy[u] < uy[0] then walk(u, 1, mt) else walk(u, 0, mt) end
  1281. end
  1282. end
  1283.  
  1284. AI[4] = function(u) -- hoverbot attack mode
  1285. utimerb[u] = 0
  1286. hoverbot_animate(u)
  1287. utimera[u] = 7
  1288. chase(u, 2)
  1289. if robot_attack_range(u) then
  1290. inflict_damage(0, 1)
  1291. create_player_explosion()
  1292. play_sound(7)
  1293. utimera[u] = 30
  1294. end
  1295. check_window_redraw(u)
  1296. end
  1297.  
  1298. AI[5] = function(u) -- robot on water after EMP
  1299. utile[u] = utile[u] + 1
  1300. if utile[u] == 143 then utile[u] = 140 end
  1301. ua[u] = (ua[u] - 1) % 256
  1302. if ua[u] == 0 then
  1303. utype[u] = 8; utimera[u] = 255; utile[u] = 115
  1304. end
  1305. check_window_redraw(u)
  1306. end
  1307.  
  1308. AI[6] = function(u)
  1309. if ua[u] == 0 then big_exp_phase1(u)
  1310. elseif ua[u] == 1 then big_exp_phase2(u) end
  1311. end
  1312.  
  1313. AI[7] = function(u) -- transporter pad
  1314. if ux[u] == ux[0] and uy[u] == uy[0] then
  1315. if ua[u] ~= 0 then
  1316. print_info("transporter will not activate\nuntil all robots destroyed.")
  1317. play_sound(11)
  1318. utimera[u] = 100
  1319. else
  1320. utype[u] = 23; utimera[u] = 5; utimerb[u] = 0
  1321. end
  1322. return
  1323. end
  1324. if ua[u] == 1 then
  1325. local alldead = true
  1326. for x = 1, 27 do if utype[x] ~= 0 then alldead = false; break end end
  1327. if alldead then ua[u] = 0 end
  1328. utimera[u] = 30
  1329. return
  1330. end
  1331. if utimerb[u] == 1 then utimerb[u] = 0; puttile(ux[u], uy[u], 31)
  1332. else utimerb[u] = 1; puttile(ux[u], uy[u], 30) end
  1333. check_window_redraw(u)
  1334. utimera[u] = 30
  1335. end
  1336.  
  1337. AI[8] = function(u) utype[u] = 0 end
  1338.  
  1339. AI[9] = function(u) -- evilbot
  1340. utimera[u] = 5
  1341. local t = utile[u]
  1342. if t == 100 or t == 101 or t == 102 then utile[u] = t + 1 else utile[u] = 100 end
  1343. if utimerb[u] ~= 0 then
  1344. utimerb[u] = utimerb[u] - 1
  1345. check_window_redraw(u)
  1346. return
  1347. end
  1348. utimerb[u] = 1
  1349. chase(u, 1)
  1350. if robot_attack_range(u) then
  1351. inflict_damage(0, 5)
  1352. create_player_explosion()
  1353. play_sound(7)
  1354. utimera[u] = 15
  1355. end
  1356. check_window_redraw(u)
  1357. end
  1358.  
  1359. -- doors ------------------------------------------------------------
  1360. local function hdoor(u, p1, p2, p3)
  1361. local x, y = ux[u], uy[u]
  1362. puttile(x - 1, y, p1); puttile(x, y, p2); puttile(x + 1, y, p3)
  1363. end
  1364. local function vdoor(u, p1, p2, p3)
  1365. local x, y = ux[u], uy[u]
  1366. puttile(x, y - 1, p1); puttile(x, y, p2); puttile(x, y + 1, p3)
  1367. end
  1368. local function door_draw(u, h1, h2, h3, v1, v2, v3)
  1369. if ua[u] == 1 then vdoor(u, v1, v2, v3) else hdoor(u, h1, h2, h3) end
  1370. end
  1371.  
  1372. AI[10] = function(u)
  1373. local b = ub[u]
  1374. if b == 0 then
  1375. door_draw(u, 88, 89, 86, 70, 74, 78); ub[u] = 1; utimera[u] = 5
  1376. elseif b == 1 then
  1377. door_draw(u, 17, 9, 91, 27, 9, 15); ub[u] = 2; utimera[u] = 30
  1378. elseif b == 2 then
  1379. if door_proximity(u) then utimerb[u] = 30; return end
  1380. if gettile(ux[u], uy[u]) ~= 9 then utimera[u] = 35; return end
  1381. play_sound(14)
  1382. door_draw(u, 88, 89, 86, 70, 74, 78); ub[u] = 3; utimera[u] = 5
  1383. elseif b == 3 then
  1384. door_draw(u, 84, 85, 86, 69, 73, 77); ub[u] = 4; utimera[u] = 5
  1385. elseif b == 4 then
  1386. door_draw(u, 80, 81, 82, 68, 72, 76); ub[u] = 5; utimera[u] = 5
  1387. elseif b == 5 then
  1388. if not door_proximity(u) then utimera[u] = 20; return end
  1389. local lock = uc[u]
  1390. local ok = false
  1391. if lock == 0 then ok = true
  1392. elseif lock == 1 then ok = KEYS % 2 == 1
  1393. elseif lock == 2 then ok = floor(KEYS / 2) % 2 == 1
  1394. elseif lock == 3 then ok = floor(KEYS / 4) % 2 == 1 end
  1395. if not ok then utimera[u] = 20; return end
  1396. play_sound(14)
  1397. door_draw(u, 84, 85, 86, 69, 73, 77); ub[u] = 0; utimera[u] = 5
  1398. else return end
  1399. check_window_redraw(u)
  1400. end
  1401.  
  1402. local elevator_panel -- defined later (needs input loop)
  1403. AI[19] = function(u)
  1404. local b = ub[u]
  1405. if b == 0 then
  1406. hdoor(u, 181, 89, 173); ub[u] = 1; utimera[u] = 5
  1407. elseif b == 1 then
  1408. hdoor(u, 182, 9, 172); ub[u] = 2; utimera[u] = 50
  1409. elseif b == 2 then
  1410. if gettile(ux[u], uy[u]) ~= 9 or check_for_unit(ux[u], uy[u]) ~= 255 then utimera[u] = 35; return end
  1411. play_sound(14)
  1412. hdoor(u, 181, 89, 173); ub[u] = 3; utimera[u] = 5
  1413. elseif b == 3 then
  1414. hdoor(u, 84, 85, 173); ub[u] = 4; utimera[u] = 5
  1415. elseif b == 4 then
  1416. hdoor(u, 80, 81, 174); ub[u] = 5; utimera[u] = 5
  1417. check_window_redraw(u)
  1418. elevator_panel(u)
  1419. return
  1420. elseif b == 5 then
  1421. if not door_proximity(u) then utimera[u] = 20; return end
  1422. play_sound(14)
  1423. hdoor(u, 84, 85, 173); ub[u] = 0; utimera[u] = 5
  1424. else return end
  1425. check_window_redraw(u)
  1426. end
  1427.  
  1428. AI[11] = function(u) -- small explosion
  1429. utimera[u] = 0
  1430. utile[u] = utile[u] + 1
  1431. if utile[u] == 252 then utype[u] = 0 end
  1432. check_window_redraw(u)
  1433. end
  1434.  
  1435. -- weapons fire -----------------------------------------------------
  1436. local function deactivate_weapon(u)
  1437. utype[u] = 0
  1438. if ub[u] == 1 then ub[u] = 0; PLASMA_ACT = 0 end
  1439. end
  1440.  
  1441. local function start_bomb(u, x, y, timer)
  1442. utype[u] = 6; utile[u] = 131; ux[u] = x; uy[u] = y
  1443. utimera[u] = timer; ua[u] = 0
  1444. end
  1445.  
  1446. local function pistol_common(u)
  1447. if ub[u] ~= 0 then
  1448. -- plasma
  1449. ua[u] = (ua[u] - 1) % 256
  1450. local t = gettile(ux[u], uy[u])
  1451. local hit = true
  1452. if t ~= 131 and T_SEE[t] then
  1453. if check_for_unit(ux[u], uy[u]) == 255 then hit = false end
  1454. end
  1455. if not hit then check_window_redraw(u); return end
  1456. utype[u] = 6; utimera[u] = 1; ua[u] = 0; PLASMA_ACT = 0
  1457. check_window_redraw(u)
  1458. return
  1459. end
  1460. ua[u] = (ua[u] - 1) % 256
  1461. local x, y = ux[u], uy[u]
  1462. local t = gettile(x, y)
  1463. if t == 131 then
  1464. puttile(x, y, 135)
  1465. start_bomb(u, x, y, 5)
  1466. return
  1467. end
  1468. if not T_SEE[t] then
  1469. utype[u] = 11; utile[u] = 248
  1470. check_window_redraw(u)
  1471. return
  1472. end
  1473. local f = check_for_unit(x, y)
  1474. if f == 255 then check_window_redraw(u); return end
  1475. utype[u] = 11; utile[u] = 248
  1476. inflict_damage(f, 1)
  1477. alter_ai(f)
  1478. check_window_redraw(u)
  1479. end
  1480.  
  1481. for dir = 0, 3 do
  1482. AI[12 + dir] = function(u)
  1483. if ua[u] == 0 then
  1484. deactivate_weapon(u)
  1485. check_window_redraw(u)
  1486. return
  1487. end
  1488. ux[u] = ux[u] + DX[dir]; uy[u] = uy[u] + DY[dir]
  1489. pistol_common(u)
  1490. end
  1491. end
  1492.  
  1493. AI[16] = function(u) -- trash compactor
  1494. local st = ua[u]
  1495. local function piece(a, b, c, d)
  1496. local x, y = ux[u], uy[u]
  1497. puttile(x, y - 1, a); puttile(x + 1, y - 1, b); puttile(x, y, c); puttile(x + 1, y, d)
  1498. check_window_redraw(u)
  1499. end
  1500. if st == 0 then
  1501. local x, y = ux[u], uy[u]
  1502. local idle = false
  1503. if gettile(x, y) == 148 and gettile(x + 1, y) == 148 then
  1504. utimera[u] = 20
  1505. if check_for_unit(x, y) == 255 then idle = true end
  1506. end
  1507. if idle then return end
  1508. piece(146, 147, 150, 151)
  1509. ua[u] = 1; utimera[u] = 10
  1510. play_sound(14)
  1511. elseif st == 1 then
  1512. piece(152, 153, 156, 157)
  1513. ua[u] = 2; utimera[u] = 50
  1514. local x, y = ux[u], uy[u]
  1515. local f = check_for_unit(x, y)
  1516. if f == 255 then f = check_for_unit(x + 1, y) end
  1517. if f == 255 then return end
  1518. print_info("you're terminated!")
  1519. play_sound(0)
  1520. utype[f] = 0; uhealth[f] = 0
  1521. local s = free_weapon_slot()
  1522. if not s then check_window_redraw(u); return end
  1523. utype[s] = 11; utile[s] = 248; utimera[s] = 0
  1524. ux[s] = x; uy[s] = y
  1525. if f == 0 then BORDER = 10 end
  1526. check_window_redraw(u)
  1527. elseif st == 2 then
  1528. piece(146, 147, 150, 151)
  1529. ua[u] = 3; utimera[u] = 10
  1530. elseif st == 3 then
  1531. piece(144, 145, 148, 148)
  1532. ua[u] = 0; utimera[u] = 20
  1533. play_sound(14)
  1534. end
  1535. end
  1536.  
  1537. -- rollerbots ---------------------------------------------------------
  1538. local function rollerbot_animate(u)
  1539. if utimerb[u] ~= 0 then utimerb[u] = utimerb[u] - 1; return end
  1540. utimerb[u] = 3
  1541. if utile[u] == 164 then utile[u] = 165 else utile[u] = 164 end
  1542. check_window_redraw(u)
  1543. end
  1544.  
  1545. local function rollerbot_shoot(u, dir, ox, oy)
  1546. local s = free_weapon_slot()
  1547. if not s then return end
  1548. utype[s] = 12 + dir
  1549. utile[s] = (dir < 2) and 244 or 245
  1550. ua[s] = 5; ub[s] = 0; utimera[s] = 0
  1551. ux[s] = ox; uy[s] = oy
  1552. play_sound(9)
  1553. end
  1554.  
  1555. local function rollerbot_fire_detect(u)
  1556. local ox, oy = ux[u], uy[u]
  1557. if oy == uy[0] then
  1558. if ox < ux[0] then
  1559. if ux[0] - ox < 6 then rollerbot_shoot(u, 3, ox, oy) end
  1560. else
  1561. if ox - ux[0] < 6 then rollerbot_shoot(u, 2, ox, oy) end
  1562. end
  1563. elseif ox == ux[0] then
  1564. if oy < uy[0] then
  1565. if uy[0] - oy < 4 then rollerbot_shoot(u, 1, ox, oy) end
  1566. else
  1567. if oy - uy[0] < 4 then rollerbot_shoot(u, 0, ox, oy) end
  1568. end
  1569. end
  1570. end
  1571.  
  1572. local function roller(u, a, b)
  1573. utimera[u] = 7
  1574. rollerbot_animate(u)
  1575. if ua[u] ~= 1 then
  1576. if not walk(u, a, 1) then ua[u] = 1 end
  1577. else
  1578. if not walk(u, b, 1) then ua[u] = 0 end
  1579. end
  1580. rollerbot_fire_detect(u)
  1581. check_window_redraw(u)
  1582. end
  1583. AI[17] = function(u) roller(u, 0, 1) end
  1584. AI[18] = function(u) roller(u, 2, 3) end
  1585.  
  1586. -- magnet -------------------------------------------------------------
  1587. AI[20] = function(u)
  1588. utimerb[u] = (utimerb[u] - 1) % 256
  1589. if utimerb[u] == 0 then
  1590. ua[u] = (ua[u] - 1) % 256
  1591. if ua[u] == 0 then utype[u] = 0; MAGNET_ACT = 0; return end
  1592. end
  1593. local f = check_for_unit(ux[u], uy[u])
  1594. if f == 255 then return end
  1595. if f == 0 then
  1596. INV_MAGNET = (INV_MAGNET + 1) % 256
  1597. display_item()
  1598. else
  1599. play_sound(4)
  1600. ud[f] = utype[f]
  1601. utype[f] = 21
  1602. utimerb[f] = 60
  1603. end
  1604. utype[u] = 0; MAGNET_ACT = 0
  1605. end
  1606.  
  1607. AI[21] = function(u) -- magnetized (crazy) robot
  1608. random_number()
  1609. local d = RANDOM % 4
  1610. walk(u, d, 1)
  1611. check_window_redraw(u)
  1612. utimera[u] = 10
  1613. utimerb[u] = (utimerb[u] - 1) % 256
  1614. if utimerb[u] == 0 then utype[u] = ud[u] end
  1615. end
  1616.  
  1617. AI[22] = function(u) -- water raft
  1618. local x, y = ux[u], uy[u]
  1619. local right = ua[u] == 1
  1620. puttile(x, y, 204)
  1621. if x == ux[0] and y == uy[0] then
  1622. local d = right and 1 or -1
  1623. ux[0] = ux[0] + d; ux[u] = ux[u] + d
  1624. puttile(ux[u], uy[u], 242)
  1625. calc_and_redraw()
  1626. else
  1627. ux[u] = ux[u] + (right and 1 or -1)
  1628. puttile(ux[u], uy[u], 242)
  1629. check_window_redraw(u)
  1630. end
  1631. local dest = right and uc[u] or ub[u]
  1632. if ux[u] ~= dest then utimera[u] = 6
  1633. else utimera[u] = 100; ua[u] = right and 0 or 1 end
  1634. end
  1635.  
  1636. AI[23] = function(u) -- dematerialize (transporter in use)
  1637. local tb = utimerb[u]
  1638. utile[0] = 252 + tb % 2 + floor(tb / 8) % 2
  1639. utimerb[u] = tb + 1
  1640. if utimerb[u] ~= 16 then
  1641. utimera[u] = 1; REDRAW = 1
  1642. return
  1643. end
  1644. if ub[u] == 1 then
  1645. utile[0] = 243
  1646. ux[0] = uc[u]; uy[0] = ud[u]
  1647. utype[u] = 7
  1648. calc_and_redraw()
  1649. else
  1650. utype[0] = 2 -- level complete
  1651. utype[u] = 7
  1652. end
  1653. end
  1654.  
  1655. local function background_tasks()
  1656. for u = 1, 63 do
  1657. local t = utype[u]
  1658. if t ~= 0 then
  1659. if utimera[u] ~= 0 then utimera[u] = utimera[u] - 1
  1660. elseif t < 24 then
  1661. local f = AI[t]
  1662. if f then f(u) end
  1663. end
  1664. end
  1665. end
  1666. end
  1667.  
  1668.  
  1669. -- ------------------------------------------------------- time, input, pump
  1670. local lasttime = 0
  1671. local keyq = {}
  1672. local FLASH_STATE = 0
  1673. local SHAKE_PHASE = false
  1674. local LASTKEY = nil
  1675. local PX, PY = 0, 0
  1676.  
  1677. local function keyname(ch, code)
  1678. if code == 200 then return "UP" elseif code == 208 then return "DOWN"
  1679. elseif code == 203 then return "LEFT" elseif code == 205 then return "RIGHT"
  1680. elseif code == 28 or code == 156 then return "ENTER"
  1681. elseif code == 1 then return "ESC"
  1682. elseif code == 199 then return "HOME" elseif code == 15 then return "TAB" end
  1683. if ch and ch >= 32 and ch < 127 then return schar(ch) end
  1684. return nil
  1685. end
  1686.  
  1687. local function handle_event(name, a, b, c)
  1688. if name == "key_down" then
  1689. local k = keyname(b, c)
  1690. if k then keyq[#keyq + 1] = k; if #keyq > 16 then table.remove(keyq, 1) end end
  1691. elseif name == "interrupted" then
  1692. error(QUIT, 0)
  1693. end
  1694. end
  1695.  
  1696. local function getkey()
  1697. if #keyq == 0 then return nil end
  1698. return table.remove(keyq, 1)
  1699. end
  1700.  
  1701. local function irq()
  1702. animate_tiles()
  1703. music_tick()
  1704. if CLOCK_ACTIVE == 1 then
  1705. CYCLES = CYCLES + 1
  1706. if CYCLES >= 60 then
  1707. CYCLES = 0; SECONDS = SECONDS + 1
  1708. if SECONDS == 60 then
  1709. SECONDS = 0; MINUTES = MINUTES + 1
  1710. if MINUTES == 60 then MINUTES = 0; HOURS = HOURS + 1 end
  1711. end
  1712. end
  1713. end
  1714. if BGTIMER2 > 0 then BGTIMER2 = BGTIMER2 - 1 end
  1715. if KEYTIMER > 0 then KEYTIMER = KEYTIMER - 1 end
  1716. if BORDER > 0 then BORDER = BORDER - 1 end
  1717. end
  1718.  
  1719. local function game_tick_extras()
  1720. if SELECT_TIMEOUT > 0 then SELECT_TIMEOUT = SELECT_TIMEOUT - 1 end
  1721. if BORDER == 0 then
  1722. if FLASH_STATE == 1 then
  1723. for i = 0, 5 do P(0x2F2 + i, 32); P(0x31A + i, 32); P(0x342 + i, 32) end
  1724. FLASH_STATE = 0
  1725. end
  1726. elseif FLASH_STATE == 0 then
  1727. for i = 1, 6 do P(0x2F2 + i - 1, OUCH[1][i]); P(0x31A + i - 1, OUCH[2][i]); P(0x342 + i - 1, OUCH[3][i]) end
  1728. FLASH_STATE = 1
  1729. end
  1730. end
  1731.  
  1732. local function pump(wait)
  1733. local now = computer.uptime()
  1734. local n = floor((now - lasttime) * 60)
  1735. if n > 0 then
  1736. if n > 6 then n = 6; lasttime = now else lasttime = lasttime + n / 60 end
  1737. for _ = 1, n do
  1738. irq()
  1739. if MODE == "game" then
  1740. game_tick_extras()
  1741. if WORLD then background_tasks() end
  1742. end
  1743. end
  1744. end
  1745. if MODE == "game" then
  1746. if SCREEN_SHAKE == 1 then
  1747. REDRAW = 1
  1748. SHAKE_PHASE = not SHAKE_PHASE
  1749. else SHAKE_PHASE = false end
  1750. if REDRAW == 1 then
  1751. draw_map_window()
  1752. if SHAKE_PHASE then
  1753. for r = 0, 20 do for c = 0, 31 do scr[r * 40 + c + 1] = scr[r * 40 + c + 2] end end
  1754. end
  1755. end
  1756. end
  1757. emit_sound()
  1758. flush()
  1759. handle_event(event.pull(wait or 0.05))
  1760. end
  1761.  
  1762. local function raw_key() -- wait for a key without advancing the world
  1763. flush()
  1764. while true do
  1765. handle_event(event.pull(0.1))
  1766. local k = getkey()
  1767. if k then lasttime = computer.uptime(); return k end
  1768. end
  1769. end
  1770.  
  1771. local function clear_key_buffer() keyq = {}; KEYTIMER = 20 end
  1772.  
  1773. -- ------------------------------------------------------- controls
  1774. local K = {up = "8", down = "2", left = "4", right = "6", fup = "w", fdown = "s",
  1775. fleft = "a", fright = "d", cw = "<", ci = ">", use = " ", search = "z", move = "m"}
  1776. local KORDER = {"up", "down", "left", "right", "fup", "fdown", "fleft", "fright", "cw", "ci", "use", "search", "move"}
  1777. local KEYS_DEFINED = false
  1778. local KSTD = {}
  1779. for k, v in pairs(K) do KSTD[k] = v end
  1780.  
  1781. local function action_of(n)
  1782. if n == "UP" then return "up" elseif n == "DOWN" then return "down"
  1783. elseif n == "LEFT" then return "left" elseif n == "RIGHT" then return "right" end
  1784. if n == K.cw or n == "," then return "cw" end
  1785. if n == K.ci or n == "." then return "ci" end
  1786. for _, a in ipairs(KORDER) do if K[a] == n then return a end end
  1787. if n == "ESC" or n == "p" or n == "P" then return "pause" end
  1788. if n == "HOME" or n == "TAB" then return "map" end
  1789. if n == "M" then return "music" end
  1790. if n == "C" then return "cheat" end
  1791. return nil
  1792. end
  1793.  
  1794. local function dir_of(a)
  1795. if a == "up" or a == "fup" and false then return 0 end
  1796. if a == "up" then return 0 elseif a == "down" then return 1
  1797. elseif a == "left" then return 2 elseif a == "right" then return 3 end
  1798. return nil
  1799. end
  1800.  
  1801. -- ------------------------------------------------------- player actions
  1802. local function animate_player()
  1803. if utile[0] == 243 then utile[0] = 247 else utile[0] = 243 end
  1804. end
  1805.  
  1806. local function fire(dir)
  1807. if SELW == 0 then return end
  1808. local s
  1809. if SELW == 1 then
  1810. if AMMO_PISTOL == 0 then return end
  1811. s = free_weapon_slot(); if not s then return end
  1812. ub[s] = 0
  1813. utile[s] = (dir < 2) and 244 or 245
  1814. else
  1815. if BIG_EXP_ACT == 1 or PLASMA_ACT == 1 or AMMO_PLASMA == 0 then return end
  1816. s = free_weapon_slot(); if not s then return end
  1817. ub[s] = 1; PLASMA_ACT = 1
  1818. utile[s] = (dir < 2) and 240 or 241
  1819. end
  1820. utype[s] = 12 + dir
  1821. ua[s] = (dir < 2) and 3 or 5
  1822. utimera[s] = 0
  1823. ux[s] = ux[0]; uy[s] = uy[0]
  1824. if SELW == 2 then play_sound(8); AMMO_PLASMA = AMMO_PLASMA - 1
  1825. else play_sound(9); AMMO_PISTOL = AMMO_PISTOL - 1 end
  1826. display_weapon()
  1827. end
  1828.  
  1829. local function cycle_weapon()
  1830. play_sound(12)
  1831. if SELECT_TIMEOUT ~= 0 then return end
  1832. SELECT_TIMEOUT = 3; KEYTIMER = 20
  1833. SELW = SELW + 1
  1834. if SELW ~= 2 then SELW = 0 end
  1835. display_weapon()
  1836. end
  1837.  
  1838. local function cycle_item()
  1839. play_sound(13)
  1840. if SELECT_TIMEOUT ~= 0 then return end
  1841. SELECT_TIMEOUT = 3; KEYTIMER = 20
  1842. SELI = SELI + 1
  1843. if SELI == 5 then SELI = 0 end
  1844. display_item()
  1845. end
  1846.  
  1847. -- returns true when the player picked a direction (CURSOR_* updated)
  1848. local function user_select_object()
  1849. play_sound(16)
  1850. CURSOR_X = 5; CURSOR_Y = 3; CURSOR_ON = 1
  1851. reverse_tile()
  1852. while true do
  1853. pump()
  1854. if utype[0] == 0 then CURSOR_ON = 0; return false end
  1855. local k = getkey()
  1856. if k then
  1857. local a = action_of(k)
  1858. if k == "ESC" then CURSOR_ON = 0; draw_map_window(); return false end
  1859. if a == "right" then CURSOR_X = CURSOR_X + 1; return true
  1860. elseif a == "left" then CURSOR_X = CURSOR_X - 1; return true
  1861. elseif a == "down" then CURSOR_Y = CURSOR_Y + 1; return true
  1862. elseif a == "up" then CURSOR_Y = CURSOR_Y - 1; return true end
  1863. end
  1864. end
  1865. end
  1866.  
  1867. local function cursor_map() return CURSOR_X + WX, CURSOR_Y + WY end
  1868.  
  1869. local function search_object()
  1870. if not user_select_object() then return end
  1871. REDRAW = 1
  1872. local mx, my = cursor_map()
  1873. local t = gettile(mx, my)
  1874. if not T_SEARCH[t] then
  1875. CURSOR_ON = 0
  1876. print_info("nothing found here.")
  1877. return
  1878. end
  1879. if t == 41 or t == 45 or t == 199 then puttile(mx, my, DESTRUCT[t]) end
  1880. print_info("searching")
  1881. for bar = 0, 7 do
  1882. BGTIMER2 = 18
  1883. while BGTIMER2 ~= 0 do pump() end
  1884. P(0x3C9 + bar, 46)
  1885. end
  1886. CURSOR_ON = 0
  1887. draw_map_window()
  1888. local f = check_for_hidden_unit(mx, my)
  1889. if f == 255 then print_info("nothing found here."); return end
  1890. local typ, qty = utype[f], ua[f]
  1891. utype[f] = 0
  1892. play_sound(10)
  1893. if typ == 128 then
  1894. if qty == 0 then KEYS = KEYS % 2 == 1 and KEYS or KEYS + 1
  1895. elseif qty == 1 then KEYS = floor(KEYS / 2) % 2 == 1 and KEYS or KEYS + 2
  1896. else KEYS = floor(KEYS / 4) % 2 == 1 and KEYS or KEYS + 4 end
  1897. print_info("you found a key card!")
  1898. display_keys()
  1899. elseif typ == 129 then
  1900. INV_BOMBS = (INV_BOMBS + qty) % 256
  1901. print_info("you found a timebomb!"); display_item()
  1902. elseif typ == 130 then
  1903. INV_EMP = (INV_EMP + qty) % 256
  1904. print_info("you found an emp device!"); display_item()
  1905. elseif typ == 131 then
  1906. AMMO_PISTOL = AMMO_PISTOL + qty
  1907. if AMMO_PISTOL > 255 then AMMO_PISTOL = 255 end
  1908. print_info("you found a pistol!"); display_weapon()
  1909. elseif typ == 132 then
  1910. AMMO_PLASMA = (AMMO_PLASMA + qty) % 256
  1911. print_info("you found a plasma gun!"); display_weapon()
  1912. elseif typ == 133 then
  1913. INV_MEDKIT = (INV_MEDKIT + qty) % 256
  1914. print_info("you found a medkit!"); display_item()
  1915. elseif typ == 134 then
  1916. INV_MAGNET = (INV_MAGNET + qty) % 256
  1917. print_info("you found a magnet!"); display_item()
  1918. end
  1919. end
  1920.  
  1921. local function move_object()
  1922. if not user_select_object() then return end
  1923. CURSOR_ON = 0
  1924. draw_map_window()
  1925. local mx, my = cursor_map()
  1926. local hidden = check_for_hidden_unit(mx, my)
  1927. local t = gettile(mx, my)
  1928. if not T_MOVE[t] then
  1929. print_info("can't move that!")
  1930. play_sound(11)
  1931. return
  1932. end
  1933. local otile, ox, oy = t, mx, my
  1934. CURSOR_ON = 1
  1935. reverse_tile()
  1936. local got = false
  1937. while not got do
  1938. pump()
  1939. if utype[0] == 0 then CURSOR_ON = 0; return end
  1940. local k = getkey()
  1941. if k then
  1942. local a = action_of(k)
  1943. if k == "ESC" then CURSOR_ON = 0; draw_map_window(); return end
  1944. if a == "right" then CURSOR_X = CURSOR_X + 1; got = true
  1945. elseif a == "left" then CURSOR_X = CURSOR_X - 1; got = true
  1946. elseif a == "down" then CURSOR_Y = CURSOR_Y + 1; got = true
  1947. elseif a == "up" then CURSOR_Y = CURSOR_Y - 1; got = true end
  1948. end
  1949. end
  1950. CURSOR_ON = 0
  1951. draw_map_window()
  1952. local dx, dy = cursor_map()
  1953. local dt = gettile(dx, dy)
  1954. if not T_PLACE[dt] or check_for_unit(dx, dy) ~= 255 then
  1955. print_info("blocked!")
  1956. play_sound(11)
  1957. return
  1958. end
  1959. play_sound(6)
  1960. puttile(dx, dy, otile)
  1961. if dt == 148 then dt = 9 end
  1962. puttile(ox, oy, dt)
  1963. REDRAW = 1
  1964. if hidden ~= 255 then ux[hidden] = dx; uy[hidden] = dy end
  1965. end
  1966.  
  1967. local function bomb_magnet_common1()
  1968. CURSOR_ON = 0
  1969. draw_map_window()
  1970. local mx, my = cursor_map()
  1971. return mx, my, T_WALK[gettile(mx, my)]
  1972. end
  1973. local function blocked_msg() print_info("blocked!"); play_sound(11) end
  1974.  
  1975. local function use_bomb()
  1976. if not user_select_object() then return end
  1977. local mx, my, ok = bomb_magnet_common1()
  1978. if not ok or check_for_unit(mx, my) ~= 255 then blocked_msg(); return end
  1979. local s = free_weapon_slot(); if not s then return end
  1980. utype[s] = 6; utile[s] = 130; ux[s] = mx; uy[s] = my
  1981. utimera[s] = 100; ua[s] = 0
  1982. INV_BOMBS = INV_BOMBS - 1
  1983. display_item()
  1984. REDRAW = 1; SELECT_TIMEOUT = 3
  1985. play_sound(6)
  1986. end
  1987.  
  1988. local function use_magnet()
  1989. if MAGNET_ACT ~= 0 then return end
  1990. if not user_select_object() then return end
  1991. local mx, my, ok = bomb_magnet_common1()
  1992. if not ok then blocked_msg(); return end
  1993. local s = free_weapon_slot(); if not s then return end
  1994. utype[s] = 20; utile[s] = 134; ux[s] = mx; uy[s] = my
  1995. utimera[s] = 1; utimerb[s] = 255; ua[s] = 3
  1996. MAGNET_ACT = 1
  1997. INV_MAGNET = INV_MAGNET - 1
  1998. display_item()
  1999. REDRAW = 1
  2000. play_sound(6)
  2001. end
  2002.  
  2003. local function wait_real(sec)
  2004. local t0 = computer.uptime()
  2005. while computer.uptime() - t0 < sec do
  2006. flush()
  2007. handle_event(event.pull(0.05))
  2008. end
  2009. lasttime = computer.uptime()
  2010. end
  2011.  
  2012. local function use_emp()
  2013. for r = 0, 20 do for c = 0, 32 do
  2014. local i = r * 40 + c + 1
  2015. scr[i] = xor80(scr[i])
  2016. end end
  2017. REDRAW = 0
  2018. play_sound(3)
  2019. INV_EMP = INV_EMP - 1
  2020. display_item()
  2021. flush()
  2022. for u = 1, 27 do
  2023. if utype[u] ~= 0 and ux[u] >= WX and ux[u] <= WX + 10 and uy[u] >= WY and uy[u] <= WY + 6 then
  2024. utimera[u] = 255
  2025. if gettile(ux[u], uy[u]) == 204 then
  2026. utype[u] = 5; utimera[u] = 5; ua[u] = 60; utile[u] = 140
  2027. end
  2028. end
  2029. end
  2030. print_info("emp activated!\nnearby robots are rebooting.")
  2031. SELECT_TIMEOUT = 3
  2032. wait_real(0.15)
  2033. REDRAW = 1
  2034. end
  2035.  
  2036. local function use_medkit()
  2037. if uhealth[0] == 12 then return end
  2038. local need = 12 - uhealth[0]
  2039. if INV_MEDKIT >= need then
  2040. uhealth[0] = 12; INV_MEDKIT = INV_MEDKIT - need
  2041. else
  2042. uhealth[0] = uhealth[0] + INV_MEDKIT; INV_MEDKIT = 0
  2043. end
  2044. display_player_health(); display_item()
  2045. play_sound(2)
  2046. print_info("ahhh, much better!")
  2047. end
  2048.  
  2049. local function use_item()
  2050. if SELECT_TIMEOUT ~= 0 then return end
  2051. if SELI == 1 then use_bomb()
  2052. elseif SELI == 2 then use_emp()
  2053. elseif SELI == 3 then use_medkit()
  2054. elseif SELI == 4 then use_magnet() end
  2055. end
  2056.  
  2057. local function cheater()
  2058. KEYS = 7
  2059. AMMO_PISTOL = 100; AMMO_PLASMA = 100; INV_BOMBS = 100; INV_EMP = 100
  2060. INV_MEDKIT = 100; INV_MAGNET = 100
  2061. SELW = 1; SELI = 1
  2062. display_keys(); display_weapon(); display_item()
  2063. end
  2064.  
  2065. local LEVEL_MUSIC = {0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1}
  2066. local function toggle_music()
  2067. if MUSIC_ON then
  2068. print_info("music off.")
  2069. MUSIC_ON = false; pending_note = nil
  2070. else
  2071. print_info("music on.")
  2072. start_music(D_SONGS[LEVEL_MUSIC[SEL_MAP + 1]])
  2073. end
  2074. end
  2075.  
  2076. -- ------------------------------------------------------- elevator
  2077. function elevator_panel(u)
  2078. if ux[u] ~= ux[0] or uy[u] - 1 ~= uy[0] then return end
  2079. print_info("[ elevator panel ] down\n[ select level ] opens")
  2080. print_info("[ ] door")
  2081. draw_map_window()
  2082. local maxf = ud[u]
  2083. for i = 0, maxf - 1 do P(0x3C6 + i, 0x31 + i) end
  2084. local cur = uc[u]
  2085. local function invert() local o = 0x3C5 + cur; scr[o + 1] = xor80(scr[o + 1]) end
  2086. invert()
  2087. local function find_xy()
  2088. for e = 32, 47 do
  2089. if utype[e] == 19 and uc[e] == cur then
  2090. ux[0] = ux[e]; uy[0] = uy[e] - 1
  2091. WX = ux[e] - 5; WY = uy[e] - 4
  2092. draw_map_window()
  2093. play_sound(17)
  2094. return
  2095. end
  2096. end
  2097. end
  2098. while true do
  2099. local k = raw_key()
  2100. local a = action_of(k)
  2101. if a == "left" then
  2102. if cur ~= 1 then invert(); cur = cur - 1; invert(); find_xy() end
  2103. elseif a == "right" then
  2104. if cur ~= maxf then invert(); cur = cur + 1; invert(); find_xy() end
  2105. elseif a == "down" then
  2106. scroll_info(); scroll_info(); scroll_info()
  2107. clear_key_buffer()
  2108. lasttime = computer.uptime()
  2109. return
  2110. end
  2111. end
  2112. end
  2113.  
  2114. -- ------------------------------------------------------- map view
  2115. local BIGX, BIGY = 16, 0
  2116. local BP_STATUS, BP_ROBOTS = 0, 0
  2117. local PIXELMAP = {[0] = 0x20, 0x6C, 0x7B, 0x62, 0x7C, 0xE1, 0xFF, 0xFE, 0x7E, 0x7F, 0x61, 0xFC, 0xE2, 0xFB, 0xEC, 0xA0}
  2118. local PMIDX = {}
  2119. for i = 0, 15 do PMIDX[PIXELMAP[i]] = i end
  2120.  
  2121. local function pixel_info()
  2122. local off = floor(PY / 2) * 40 + floor(PX / 2)
  2123. local cur = PMIDX[scr[off + 1]] or 0
  2124. local m = (PX % 2 == 0) and 2 or 1
  2125. if PY % 2 == 0 then m = m * 4 end
  2126. return off, cur, m
  2127. end
  2128. local function pixel_plot()
  2129. local off, cur, m = pixel_info()
  2130. if floor(cur / m) % 2 == 0 then cur = cur + m end
  2131. scr[off + 1] = PIXELMAP[cur]
  2132. end
  2133. local function pixel_unplot()
  2134. local off, cur, m = pixel_info()
  2135. if floor(cur / m) % 2 == 1 then cur = cur - m end
  2136. scr[off + 1] = PIXELMAP[cur]
  2137. end
  2138.  
  2139. local function render_map()
  2140. cls()
  2141. for py = 0, 49 do
  2142. for px = 0, 79 do
  2143. if not T_WALK[gettile(px + BIGX, py + BIGY)] then PX = px; PY = py; pixel_plot() end
  2144. end
  2145. end
  2146. end
  2147.  
  2148. local function blink_robots()
  2149. for u = 1, 27 do
  2150. if utype[u] ~= 0 and ux[u] >= BIGX and ux[u] <= BIGX + 79 and uy[u] >= BIGY and uy[u] <= BIGY + 49 then
  2151. PX = ux[u] - BIGX; PY = uy[u] - BIGY
  2152. if BP_STATUS ~= 0 then pixel_unplot() else pixel_plot() end
  2153. end
  2154. end
  2155. BP_STATUS = 1 - BP_STATUS
  2156. end
  2157.  
  2158. local function blink_player()
  2159. BGTIMER2 = 20
  2160. if BP_ROBOTS ~= 0 then blink_robots(); return end
  2161. if ux[0] >= BIGX and ux[0] <= BIGX + 79 and uy[0] >= BIGY and uy[0] <= BIGY + 49 then
  2162. PX = ux[0] - BIGX; PY = uy[0] - BIGY
  2163. if BP_STATUS ~= 0 then pixel_unplot(); BP_STATUS = 0
  2164. else pixel_plot(); BP_STATUS = 1 end
  2165. end
  2166. end
  2167.  
  2168. local function toggle_player_robots()
  2169. play_sound(15)
  2170. if BP_ROBOTS == 0 then
  2171. pixel_unplot(); BP_ROBOTS = 1
  2172. else
  2173. BP_STATUS = 1; blink_robots(); BP_ROBOTS = 0
  2174. end
  2175. end
  2176.  
  2177. local function display_game_frame()
  2178. show_screen(1)
  2179. draw_map_window()
  2180. display_player_health(); display_keys(); display_weapon(); display_item()
  2181. end
  2182.  
  2183. local function display_map()
  2184. play_sound(15)
  2185. local m0, w0 = MODE, WORLD
  2186. MODE = "map"; WORLD = false
  2187. render_map()
  2188. clear_key_buffer()
  2189. while true do
  2190. pump()
  2191. if BGTIMER2 == 0 then blink_player() end
  2192. local k = getkey()
  2193. if k then
  2194. local a = action_of(k)
  2195. if a == "right" then
  2196. play_sound(17); if BIGX ~= 48 then BIGX = BIGX + 16; render_map() end
  2197. elseif a == "left" then
  2198. play_sound(17); if BIGX ~= 0 then BIGX = BIGX - 16; render_map() end
  2199. elseif a == "up" then
  2200. play_sound(17); if BIGY ~= 0 then BIGY = 0; render_map() end
  2201. elseif a == "down" then
  2202. play_sound(17); if BIGY ~= 14 then BIGY = 14; render_map() end
  2203. elseif a == "map" then toggle_player_robots()
  2204. else break end
  2205. end
  2206. end
  2207. play_sound(15)
  2208. MODE = m0; WORLD = w0
  2209. display_game_frame()
  2210. REDRAW = 1
  2211. lasttime = computer.uptime()
  2212. clear_key_buffer()
  2213. end
  2214.  
  2215. -- ------------------------------------------------------- menus & flow
  2216. local MAP_NAMES = {"01-research lab ", "02-headquarters ", "03-the village ", "04-the islands ",
  2217. "05-downtown ", "06-pi university", "07-more islands ", "08-robot hotel ",
  2218. "09-forest moon ", "10-death tower ", "11-bunker ", "12-castle robot ",
  2219. "13-rocket center", "14-pilands "}
  2220. local FACES = {{0x3A, 0x43, 0x49, 0x55, 0x43, 0x3A, 0x49, 0x55}, {0x40, 0x40, 0x6E, 0x70, 0x40, 0x40, 0x49, 0x55},
  2221. {0x3A, 0x4D, 0x3A, 0x3A, 0x4E, 0x3A, 0x4D, 0x4E}}
  2222. local FACE_OFF = {0xDD, 0xDE, 0xDF, 0xE1, 0xE2, 0xE3, 0x107, 0x109}
  2223. local DIFF_WORDS = {[0] = "easy", "normal", "hard"}
  2224. local CONTROL_TEXT = {[0] = "keyboard ", "custom key"}
  2225.  
  2226. local function display_map_name(off)
  2227. put_text(off or 0x16A, MAP_NAMES[SEL_MAP + 1])
  2228. end
  2229. local function change_difficulty()
  2230. local f = FACES[DIFF + 1]
  2231. for i = 1, 8 do P(FACE_OFF[i], f[i]) end
  2232. end
  2233. local function show_controls_text()
  2234. local s = CONTROL_TEXT[CONTROL]
  2235. for i = 1, 10 do P(0xCC + i - 1, tc(ssub(s, i, i)) + 128) end
  2236. end
  2237.  
  2238. local function custom_keys_screen()
  2239. if KEYS_DEFINED then return end
  2240. show_screen(3)
  2241. for i, a in ipairs(KORDER) do
  2242. local k = raw_key()
  2243. K[a] = k
  2244. local off = 0x151 + 40 * (i - 1)
  2245. local nm = string.upper(k)
  2246. for j = 1, 5 do P(off + j - 1, j <= #nm and tc(ssub(string.lower(nm), j, j)) or 32) end
  2247. flush()
  2248. end
  2249. KEYS_DEFINED = true
  2250. end
  2251.  
  2252. local function set_controls()
  2253. if CONTROL == 1 then custom_keys_screen()
  2254. else for k, v in pairs(KSTD) do K[k] = v end end
  2255. end
  2256.  
  2257. local function reset_game_state()
  2258. KEYS = 0; AMMO_PISTOL = 0; AMMO_PLASMA = 0
  2259. INV_BOMBS = 0; INV_EMP = 0; INV_MEDKIT = 0; INV_MAGNET = 0
  2260. SELW = 0; SELI = 0; MAGNET_ACT = 0; PLASMA_ACT = 0; BIG_EXP_ACT = 0
  2261. CYCLES = 0; SECONDS = 0; MINUTES = 0; HOURS = 0
  2262. SCREEN_SHAKE = 0; BORDER = 0; FLASH_STATE = 0; SELECT_TIMEOUT = 0
  2263. WATER_TIMER = 0
  2264. end
  2265.  
  2266. local function set_diff_level()
  2267. if DIFF == 0 then
  2268. for u = 48, 63 do
  2269. if utype[u] ~= 0 and utype[u] ~= 128 then ua[u] = (ua[u] * 2) % 256 end
  2270. end
  2271. elseif DIFF == 2 then
  2272. for u = 0, 27 do
  2273. if utype[u] == 2 or utype[u] == 3 then utype[u] = 4 end
  2274. end
  2275. end
  2276. end
  2277.  
  2278. local function init_game()
  2279. reset_game_state()
  2280. show_screen(1)
  2281. load_level(SEL_MAP)
  2282. set_diff_level()
  2283. animate_player()
  2284. calc_and_redraw()
  2285. draw_map_window()
  2286. display_player_health(); display_keys(); display_weapon()
  2287. utype[0] = 1
  2288. for u = 1, 47 do utimera[u] = u; utimerb[u] = 0 end
  2289. MODE = "game"; WORLD = true
  2290. CLOCK_ACTIVE = 1
  2291. print_info("welcome to pet-robots v1.1!\nby david murray 2022\nmap on tab/home key.")
  2292. KEYTIMER = 30
  2293. lasttime = computer.uptime()
  2294. end
  2295.  
  2296. local function pause_game()
  2297. play_sound(15)
  2298. CLOCK_ACTIVE = 0
  2299. WORLD = false
  2300. scroll_info()
  2301. print_info("game paused.\nexit game (y/n)")
  2302. clear_key_buffer()
  2303. while true do
  2304. pump()
  2305. local k = getkey()
  2306. if k == "ESC" or k == "p" or k == "P" or k == "n" or k == "N" then
  2307. scroll_info(); scroll_info(); scroll_info()
  2308. clear_key_buffer()
  2309. CLOCK_ACTIVE = 1; WORLD = true
  2310. play_sound(15)
  2311. lasttime = computer.uptime()
  2312. return false
  2313. elseif k == "y" or k == "Y" then
  2314. utype[0] = 0
  2315. play_sound(15)
  2316. WORLD = true
  2317. return true
  2318. end
  2319. end
  2320. end
  2321.  
  2322. local function endgame_screen()
  2323. MODE = "end"; WORLD = false
  2324. show_screen(2)
  2325. put_text(0x12E, MAP_NAMES[SEL_MAP + 1])
  2326. decwrite(0x17D, HOURS); decwrite(0x180, MINUTES); decwrite(0x183, SECONDS)
  2327. P(0x17D, 32); P(0x180, 58); P(0x183, 58)
  2328. local n = 0
  2329. for u = 1, 27 do if utype[u] ~= 0 then n = n + 1 end end
  2330. decwrite(0x1CE, n)
  2331. n = 0
  2332. for u = 48, 63 do if utype[u] ~= 0 then n = n + 1 end end
  2333. decwrite(0x21E, n)
  2334. put_text(0x26E, DIFF_WORDS[DIFF])
  2335. stop_song()
  2336. if utype[0] == 0 then
  2337. put_text(0x88, "you lose!"); play_sound(19)
  2338. else
  2339. put_text(0x88, "you win!"); play_sound(18)
  2340. end
  2341. clear_key_buffer()
  2342. while true do
  2343. pump()
  2344. if getkey() then break end
  2345. end
  2346. end
  2347.  
  2348. local function game_over(skip_anim)
  2349. CLOCK_ACTIVE = 0
  2350. MUSIC_ON = false; pending_note = nil
  2351. if not skip_anim then
  2352. if utype[0] == 0 then utile[0] = 111; KEYTIMER = 100 end
  2353. while KEYTIMER ~= 0 do pump() end
  2354. for i = 0, 10 do
  2355. P(0x173 + i, GAMEOVER[1][i + 1]); P(0x19B + i, GAMEOVER[2][i + 1]); P(0x1C3 + i, GAMEOVER[3][i + 1])
  2356. end
  2357. KEYTIMER = 100
  2358. while KEYTIMER ~= 0 do pump() end
  2359. keyq = {}
  2360. while true do
  2361. pump()
  2362. if getkey() then break end
  2363. end
  2364. end
  2365. keyq = {}
  2366. MUSIC_ON = false
  2367. endgame_screen()
  2368. end
  2369.  
  2370. local function game_loop()
  2371. while true do
  2372. pump()
  2373. if utype[0] ~= 1 then return game_over(false) end
  2374. local k = getkey()
  2375. if k and (k ~= LASTKEY or KEYTIMER == 0) then
  2376. LASTKEY = k
  2377. local a = action_of(k)
  2378. if a == "up" or a == "down" or a == "left" or a == "right" then
  2379. local d = dir_of(a)
  2380. if walk(0, d, 1) then
  2381. animate_player()
  2382. calc_and_redraw()
  2383. end
  2384. KEYTIMER = 6
  2385. elseif a == "fup" then fire(0); KEYTIMER = 20
  2386. elseif a == "fdown" then fire(1); KEYTIMER = 20
  2387. elseif a == "fleft" then fire(2); KEYTIMER = 20
  2388. elseif a == "fright" then fire(3); KEYTIMER = 20
  2389. elseif a == "cw" then cycle_weapon(); clear_key_buffer()
  2390. elseif a == "ci" then cycle_item(); clear_key_buffer()
  2391. elseif a == "move" then move_object(); clear_key_buffer()
  2392. elseif a == "search" then search_object(); clear_key_buffer()
  2393. elseif a == "use" then use_item(); clear_key_buffer()
  2394. elseif a == "pause" then
  2395. if pause_game() then return game_over(true) end
  2396. elseif a == "cheat" then cheater()
  2397. elseif a == "music" then toggle_music(); clear_key_buffer()
  2398. elseif a == "map" then display_map() end
  2399. end
  2400. end
  2401. end
  2402.  
  2403. local function intro_screen()
  2404. MODE = "menu"; WORLD = false
  2405. show_screen(0)
  2406. display_map_name()
  2407. change_difficulty()
  2408. show_controls_text()
  2409. start_music(D_INTRO_MUSIC)
  2410. local menuy = 0
  2411. local function rev(y)
  2412. for i = 0, 9 do local o = 0x54 + 40 * y + i; scr[o + 1] = xor80(scr[o + 1]) end
  2413. end
  2414. rev(menuy)
  2415. clear_key_buffer()
  2416. while true do
  2417. pump()
  2418. local k = getkey()
  2419. if k then
  2420. local a = action_of(k)
  2421. if a == "down" and menuy < 3 then
  2422. rev(menuy); menuy = menuy + 1; rev(menuy); play_sound(15)
  2423. elseif a == "up" and menuy > 0 then
  2424. rev(menuy); menuy = menuy - 1; rev(menuy); play_sound(15)
  2425. elseif k == " " or k == "ENTER" then
  2426. if k == "ENTER" then play_sound(15) end
  2427. if menuy == 0 then
  2428. set_controls()
  2429. MUSIC_ON = false; stop_song(); pending_note = nil
  2430. return true
  2431. elseif menuy == 1 then
  2432. play_sound(15)
  2433. SEL_MAP = (SEL_MAP + 1) % 14
  2434. display_map_name()
  2435. elseif menuy == 2 then
  2436. DIFF = (DIFF + 1) % 3
  2437. change_difficulty()
  2438. play_sound(15)
  2439. else
  2440. KEYS_DEFINED = false
  2441. CONTROL = (CONTROL + 1) % 2
  2442. show_controls_text()
  2443. play_sound(15)
  2444. end
  2445. elseif k == "q" or k == "Q" then
  2446. return false
  2447. end
  2448. end
  2449. end
  2450. end
  2451.  
  2452. -- ------------------------------------------------------- main
  2453. local function main()
  2454. local mw, mh = gpu.maxResolution()
  2455. if mw < 40 or mh < 25 then
  2456. error("PETSCII Robots needs a screen/GPU that supports 40x25 (Tier 2 or better).", 0)
  2457. end
  2458. local ow, oh = gpu.getResolution()
  2459. local ofg, obg = gpu.getForeground(), gpu.getBackground()
  2460. local function restore()
  2461. pcall(gpu.setResolution, ow, oh)
  2462. pcall(gpu.setBackground, obg)
  2463. pcall(gpu.setForeground, ofg)
  2464. pcall(gpu.fill, 1, 1, ow, oh, " ")
  2465. end
  2466. gpu.setResolution(40, 25)
  2467. curswap = nil
  2468. setswap(false)
  2469. gpu.fill(1, 1, 40, 25, " ")
  2470. invalidate()
  2471. lasttime = computer.uptime()
  2472. local ok, err = pcall(function()
  2473. while intro_screen() do
  2474. init_game()
  2475. game_loop()
  2476. end
  2477. end)
  2478. restore()
  2479. if not ok and err ~= QUIT then error(err, 0) end
  2480. end
  2481.  
  2482. main()
  2483.  
  2484. end)()
Add Comment
Please, Sign In to add comment