Module:Sandbox/Asarta/Market

From Fallen London Wiki (Staging)

Documentation for this module may be created at Module:Sandbox/Asarta/Market/doc

local p = {}

local currency_attributes = {
   ["echoes"] = {name = "Echo", symbol = "E"},
   ["scrip"] = {name = "Hinterland Scrip", symbol = "H"},
   ["shilling"] = {name = "Rat-Shilling", symbol = "R"}
}

function extract_markets(args)
   for k, v in pairs(args) do
      if string.match(k, "Buying/Selling") then
         local shop_name = string.match(k, "(.-)Buying/Selling")
         table.insert(markets, shop_name)
      end
   end
   return markets
end

function extract_information(args, market)
   local buying_selling = args[market .. "Buying/Selling"] or nil
   if not buying_selling then
      return nil
   end
   local buy_price = string.match(buying_selling, "(.-)/")
   local sell_price = string.match(buying_selling, "/(.-)")
   local buy_currency = string.match(args[market .. "Buy Currency"], "(.-)")
   local sell_currency = string.match(args[market .. "Sell Currency"], "(.-)")
   local buy_message = args[market .. "Buy Message"]
   local sell_message = args[market .. "Sell Message"]
   local shop = args[market .. "Shop"]
   local sell_market = args[market .. "Sell Market"]
   local sell_market_appearance = args[market .. "Sell Market Appearance"]
   return buy_price, sell_price, buy_currency, sell_currency, buy_message, sell_message, shop, sell_market, sell_market_appearance
end

function normalise_currency(currency)
   currency = string.lower(currency)
   if currency_attributes[currency] then
      return currency
   -- else if
   elseif currency == "echo" then
      return "echoes"
   elseif currency == "hinterland script" then
      return "scrip"
   elseif currency == "rat-shilling" then
      return "shilling"
   else
      return nil
   end
end

function create_currency_symbol(currency, amount)
   if currency_attributes[currency] then
      local output = mw.getCurrentFrame():expandTemplate{title = currency_attributes[currency].symbol}
      if currency == "echoes" then
         output = output .. amount
      else
         output = output .. " " .. amount
      end
      return output
   else
      return mw.getCurrentFrame():expandTemplate{title = "IL", args = {currency, amount .. " x"}}
   end
end
   
function create_transaction(buy_price, sell_price, buy_currency, sell_currency, buy_message, sell_message, shop, sell_market, sell_market_appearance)
   local buy_currency_name = currency_attributes[buy_currency].name
   local sell_currency_name = currency_attributes[sell_currency].name
   sell_market_appearance = sell_market_appearance or sell_market
   local categories = {}
   if buy_price and buy_price ~= "-" then
      mw.smw.set({"Bought for", buy_price .. ";" .. buy_currency_name .. ";" .. shop})
      if buy_currency ~= "echoes" then
         mw.smw.set({"Loses", buy_currency_name})
         table.insert(categories, buy_currency_name .. " Loss")
      end
   end
   if sell_price and sell_price ~= "-" then
      mw.smw.set({"Sells for", sell_price .. ";" .. sell_currency_name .. ";" .. sell_market})
      mw.smw.set({"Gains", buy_currency_name})
      table.insert(categories, buy_currency .. " Gain")
   end

   local buying_selling_line = mw.html.create("p")
   -- if buy_price is - and sell_price is - then it cannot be bought or sold, so we can short circuit the rest of the function
   if buy_price == "-" and sell_price == "-" then
      return buying_selling_line:wikitext("It cannot be bought or sold at " .. sell_market .. ".")
   elseif buy_price == "-" then
      buying_selling_line:wikitext("It can be sold at " .. sell_market_appearance .. ":")
   elseif sell_price == "-" then
      buying_selling_line:wikitext("It can be purchased from " .. shop .. " in " .. sell_market_appearance .. " but cannot be sold there.")
   else
      buying_selling_line:wikitext("It can be purchased from " .. shop .. " in " .. sell_market_appearance .. " and sold to " .. sell_market_appearance .. ":")
   end


   local transaction_table = mw.html.create("table"):addClass("article-table")
   
   if buy_price and buy_price ~= "-" then
      transaction_table:tag("tr")
         :tag("th"):wikitext("Buying"):done()
         :tag("td"):wikitext(create_currency_symbol(buy_currency, buy_price))
         :wikitext("''" .. (buy_message or " (no message)") .. "''")
         :done()
   end
   
   if sell_price and sell_price ~= "-" then
      transaction_table:tag("tr")
         :tag("th"):wikitext("Selling"):done()
         :tag("td"):wikitext(create_currency_symbol(sell_currency, sell_price))
         :wikitext("''" .. (sell_message or " (no message)") .. "''")
         :done()
   end
   
   local output = mw.html.create("div")
   output:node(buying_selling_line)
   output:node(transaction_table)
   for _, category in ipairs(categories) do
      output:wikitext("[[Category:" .. category .. "]]")
   end
   
   return output 
end	

function p.market(frame)
	local args = frame.args
	local parentArgs = frame:getParent().args
   local all_args = table.merge(args, parentArgs)
   local markets = extract_markets(all_args)
   local output = mw.html.create("div")
   for _, market in ipairs(markets) do
      local buy_price, sell_price, buy_currency, sell_currency, buy_message, sell_message, shop, sell_market, sell_market_appearance = extract_information(all_args, market)
      output:node(create_transaction(buy_price, sell_price, buy_currency, sell_currency, buy_message, sell_message, shop, sell_market, sell_market_appearance))
   end
   return output
end

return p