Enjl

resetdoors

May 16th, 2019 (edited)
662
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 4.54 KB | None | 0 0
  1. --resetdoors.lua
  2. --V 0.9.1
  3. --by Enjl
  4.  
  5. local reset = {}
  6.  
  7. local pnpc = require("pnpc")
  8. local savestate = require("savestate")
  9.  
  10. local newblocks = require("blocks/newblocks")
  11.  
  12. local blacklist = {}
  13. local memory = {}
  14.  
  15. local schedule = {}
  16. local blockstate
  17.  
  18. local warpwhitelist
  19.  
  20. reset.blocks = true
  21. reset.npcs = true
  22.  
  23. local copyfields = {
  24.     "ai1",
  25.     "ai2",
  26.     "ai3",
  27.     "ai4",
  28.     "ai5",
  29.     "direction",
  30.     "width",
  31.     "height",
  32.     "msg",
  33.     "layerName",
  34.     "isHidden",
  35.     "dontMove",
  36.     "id",
  37. }
  38.  
  39. function reset.blacklistNPCs(ids)
  40.     if type(ids) == "number" then
  41.         blacklist[ids] = true
  42.     else
  43.         for k,v in ipairs(ids) do
  44.             blacklist[v] = true
  45.         end
  46.     end
  47. end
  48.  
  49. function reset.whitelistWarps(ids)
  50.     warpwhitelist = table.map(ids)
  51. end
  52.  
  53. function reset.onInitAPI()
  54.     registerEvent(reset, "onStart")
  55.     registerEvent(reset, "onTickEnd")
  56.     registerEvent(reset, "onNPCKill")
  57. end
  58.  
  59. function reset.onStart()
  60.     if reset.blocks then
  61.         blockstate = savestate.save(savestate.STATE_BLOCK)
  62.     end
  63.     if reset.npcs then
  64.         for k,v in ipairs(NPC.get()) do
  65.             if not blacklist[v.id] then
  66.                 if v:mem(0x64, FIELD_BOOL) == false then
  67.                     v = pnpc.wrap(v)
  68.                     memory[v.uid] = {
  69.                         basegame = table.clone(v.data._basegame),
  70.                         x = v:mem(0xA8, FIELD_DFLOAT),
  71.                         y = v:mem(0xB0, FIELD_DFLOAT),
  72.                         section = v:mem(0x146, FIELD_WORD)
  73.                     }
  74.                     for _, f in ipairs(copyfields) do
  75.                         memory[v.uid][f] = v[f]
  76.                     end
  77.                 end
  78.             end
  79.         end
  80.     end
  81. end
  82.  
  83. local function scheduleForReset(v, kill)
  84.     v.data.reset = v.data.reset or {}
  85.     if kill then
  86.         v:kill(9)
  87.     end
  88.     v.data.reset.terminated = true
  89.     if v:mem(0x138, FIELD_WORD) == 0 then
  90.         table.insert(schedule, v.uid)
  91.     end
  92. end
  93.  
  94. function reset.onNPCKill(o, v, r)
  95.     if not reset.npcs then return end
  96.     if (not v.friendly) and v:mem(0xDC, FIELD_WORD) > 0 then
  97.         v = pnpc.wrap(v)
  98.         if memory[v.uid] then
  99.             if not (v.data.reset and v.data.reset.terminated) then
  100.                 scheduleForReset(v)
  101.             end
  102.         end
  103.     end
  104. end
  105.  
  106. local lastwarp = 0
  107.  
  108. function reset.onTickEnd()
  109.     if player:mem(0x15C, FIELD_WORD) > 0 and lastwarp == 0 then
  110.         if (warpwhitelist and warpwhitelist[player:mem(0x5A, FIELD_WORD)]) or not warpwhitelist then
  111.             if reset.npcs then
  112.                 local s = Section(player.section)
  113.                 for k,v in ipairs(NPC.getIntersecting(s.boundary.left, s.boundary.top, s.boundary.right, s.boundary.bottom)) do
  114.                     if v:mem(0x64, FIELD_BOOL) == false then
  115.                         if (not v.friendly) then
  116.                             if v:mem(0x12C, FIELD_WORD) == 0 then
  117.                                 v = pnpc.wrap(v)
  118.                                 if memory[v.uid] then
  119.                                     if v:mem(0xDC, FIELD_WORD) > 0 then
  120.                                         scheduleForReset(v, true)
  121.                                     else
  122.                                         v.data.reset = {terminated = true}
  123.                                         v:kill(9)
  124.                                     end
  125.                                 end
  126.                             end
  127.                         end
  128.                     end
  129.                 end
  130.  
  131.                 for i = #schedule, 1, -1 do
  132.                     local v = schedule[i]
  133.                     local lookup = memory[v]
  134.                     local n = NPC.spawn(lookup.id, lookup.x, lookup.y, lookup.section, true)
  135.                     n = pnpc.wrap(n)
  136.                     n.data._basegame = table.clone(lookup.basegame)
  137.                     for _, f in ipairs(copyfields) do
  138.                         n[f] = lookup[f]
  139.                     end
  140.  
  141.                     n:mem(0xD8, FIELD_FLOAT, lookup.direction)
  142.                     n:mem(0xDE, FIELD_WORD, lookup.ai1)
  143.                     n:mem(0xE0, FIELD_WORD, lookup.ai2)
  144.  
  145.                     memory[n.uid] = lookup
  146.                     memory[v] = nil
  147.                     schedule[i] = nil
  148.                 end
  149.             end
  150.             if reset.blocks then
  151.                 savestate.load(blockstate, savestate.STATE_BLOCK)
  152.                 newblocks.onStart()
  153.             end
  154.         end
  155.     end
  156.  
  157.     lastwarp = player:mem(0x15C, FIELD_WORD)
  158. end
  159.  
  160. return reset
Add Comment
Please, Sign In to add comment