Enjl

anothercurrency

Oct 20th, 2019 (edited)
1,146
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 5.28 KB | None | 0 0
  1. -- Currency system that streamlines currency creation and tracking.
  2. -- By Enjl, October 2019
  3.  
  4. -- How it works:
  5. -- When a registered NPC is collected, the respective currency counter goes up by the specified value.
  6.  
  7. local npcManager = require("npcManager")
  8.  
  9. local ac = {}
  10. local currencies = {}
  11.  
  12. -- Money saves by default into a subtable in SaveData, so that it can be carried around between levels.
  13. SaveData._anothercurrency = SaveData._anothercurrency or {}
  14. local sd = SaveData._anothercurrency
  15. local atLeastOneHijack = false
  16.  
  17. -- Registration instructions below the local functions.
  18.  
  19. local function registerCoinInternal(counter, id, value)
  20.     counter._cointypes[id] = value
  21. end
  22.  
  23. local function registerLimitInternal(counter, limit, func)
  24.     if func == nil or type(func) ~= "function" then
  25.         error("Second argument to registerLimit must be a function reference.")
  26.     end
  27.     if limit <= 0 then
  28.         error("Limit must be greater than 0.")
  29.     end
  30.     counter._limit = {value = limit, func = func}
  31. end
  32.  
  33. local function checkLimit(counter)
  34.     if counter._limit == nil then return end
  35.     if counter._value > counter._limit.value then
  36.         local diff = (counter._value - counter._limit.value)
  37.         counter._value = counter._value - diff
  38.         counter._limit.func(diff)
  39.     end
  40. end
  41.  
  42. local function addMoneyInternal(counter, value)
  43.     counter._value = math.max(counter._value + value, 0)
  44.     checkLimit(counter)
  45.     sd[counter.name] = counter._value
  46. end
  47.  
  48. local function setMoneyInternal(counter, value)
  49.     counter._value = math.max(value, 0)
  50.     checkLimit(counter)
  51.     sd[counter.name] = counter._value
  52. end
  53.  
  54. local function getMoneyInternal(counter)
  55.     return counter._value
  56. end
  57.  
  58. local function compareMoneyInternal(counter, value)
  59.     return counter._value >= value, counter._value - value
  60. end
  61.  
  62. local function drawInternal(counter)
  63.     Text.printWP(counter.name .. ": " .. tostring(counter._value), 4, 16, -4 + 20 * counter._id, 5)
  64. end
  65.  
  66. -- Registers a new currency and returns it. Save a reference of it to keep track of it. Name is for savedata.
  67. function ac.registerCurrency(name, hijackDefaultCounter)
  68.     -- In the currency table you get back, all the functions accessible for a currency are saved.
  69.     local currency = {
  70.         registerCoin = registerCoinInternal, -- Registers a new NPC as a "coin". myCurrency:registerCoin(id, value)
  71.         registerLimit = registerLimitInternal, -- Registers the limit of the currency. By default, there is no limit. When a limit is reached, the coin counter is emptied and a function is executed. myCurrency:registerLimit(value, functionToExecute)
  72.         addMoney = addMoneyInternal, -- Adds value to the coin counter manually. myCurrency:addMoney(value) (value can be negative to subtract)
  73.         setMoney = setMoneyInternal, -- Sets the absolute value of the coin counter. myCurrency:setMoney(value)
  74.         getMoney = getMoneyInternal, -- Gets the absolute value of the coin counter. Can be used for drawing, for example. myCurrency:getMoney()
  75.         compareMoney = compareMoneyInternal, -- Compares coin counter value to some other value. Useful for shops. myCurrency:compareMoney(valueToCompareTo). Returns whether counter is greater or equal to comparison value, and the difference as 2nd arg.
  76.         draw = drawInternal, -- Draws the coin counter. The function can be overridden and is not called internally. Default implementation is for debug purposes. myCurrency:draw()
  77.  
  78.         hijackDefaultCounter = hijackDefaultCounter, -- If set to true, this counter will derive its value from the default coin counter and won't register the deaths of default coin types. If at least one currency is registered to hijack the default counter, the default counter is automatically re-routed into this counter and will be permanently empty.
  79.         _cointypes = {},
  80.         _limit = nil,
  81.         _value = 0,
  82.         name = name,
  83.         _id = #currencies + 1
  84.     }
  85.     if sd[name] then
  86.         currency._value = sd[name]
  87.     end
  88.     atLeastOneHijack = atLeastOneHijack or currency.hijackDefaultCounter
  89.     table.insert(currencies, currency)
  90.     return currency
  91. end
  92.  
  93. -- Below is just code.
  94.  
  95. function ac.onInitAPI()
  96.     registerEvent(ac, "onTickEnd")
  97.     registerEvent(ac, "onNPCKill")
  98. end
  99.  
  100. local defaultCoinIDMap = {
  101.     [10] = true,
  102.     [33] = true,
  103.     [88] = true,
  104.     [102] = true,
  105.     [138] = true,
  106.     [152] = true,
  107.     [251] = true,
  108.     [252] = true,
  109.     [253] = true,
  110.     [258] = true,
  111.     [274] = true,
  112.     [411] = true,
  113. }
  114.  
  115. function ac.onTickEnd()
  116.     if atLeastOneHijack then
  117.         local hijackedValue = mem(0x00B2C5A8, FIELD_WORD)
  118.         if hijackedValue > 0 then
  119.             mem(0x00B2C5A8, FIELD_WORD, 0)
  120.             for k,v in ipairs(currencies) do
  121.                 if v.hijackDefaultCounter then
  122.                     v:addMoney(hijackedValue)
  123.                 end
  124.             end
  125.         end
  126.     end
  127. end
  128.  
  129. function ac.onNPCKill(killObj, v, killReason)
  130.     if killReason ~= 9 then return end
  131.     if not npcManager.collected(v, killReason) then return end
  132.  
  133.     for k,c in ipairs(currencies) do
  134.         if c._cointypes[v.id] then
  135.             if not (c.hijackDefaultCounter and defaultCoinIDMap[v.id]) then
  136.                 c:addMoney(c._cointypes[v.id])
  137.             end
  138.         end
  139.     end
  140. end
  141.  
  142.  
  143. return ac
Add Comment
Please, Sign In to add comment