Filtering out shop sell-able items

Lets say I want to limit a trader to only purchase food from you, I’m having a hard time figuring this out. It automatically shows everything you have in stockpiles that are selllable = true. Looking at shop_component.lua, shop.lua, and shop_service.lua, none seem to filter what you can sell to a trader, only purchase. I’ve looked through shop_bulletin_dialog.js to try to filter items out there, and managed to hide items themselves, but it still shows blank categories, and I’m not sure how to dynamically pull information from the shops json file to get what should be filtered.

I’m thinking the shop json should go something like

        "inventory": {
          "overall_price_multiplier": 4,
          "entries": [
            {
              "items": [
                "stonehearth:food:carrot:carrot_basket",
                "stonehearth:food:corn:corn_basket",
                "stonehearth:food:turnip:turnip_basket",
                "stonehearth:food:pumpkin:pumpkin_basket"
              ],
              "quantity": {
                "min": 1,
                "max": 2
              }
            }
          ]
        },
        "will_buy":{
          "category": "food"
        }

Any thoughts?

I’m 90% of the way there. I have buy_category being called from the shop json file in lua, and passed to the js file accessable as this.get('model.data.buy_category). The problem is when I set a var to that in _buildSellPalette (shop_bulletin_dialog.js), the script is run before the model.data.buy_category has be set or initilized or something(never worked with ember before), and end up with an empty var.

I’m at a loss now. I know php, and can hack my way though javascript and jquery most of the time, so maybe there’s an easier way, or something I’m just blatently missing?

I’ve noticed that the first time _updateSellableItems runs, the ember model hasn’t been set yet, and then it is the second time, but _buildSellPalette only runs once.

Maybe @yshan @Drotten or @Moai can point me in the right direction?

Update
Well, I’ve abandoned the javascript route for now, I’ll revisit that at some point later with fresh eyes. So instead of making items I don’t want the trader to be able to buy disappear from the list (idealy how it should work) I have figured out how to block the sale for now in shop.lua.

Added to function Shop:sell_item(uri, quantity)

    --Dale's additions
    --Checks if there is a buy category in the shop json file, and only allows the trader to buy items if the category is the same
    local fail = true
    if self._sv.options.buys and self._sv.options.buys.category then
        print("You're selling: ", sellable_items.category)
        for key,buys in pairs(self._sv.options.buys.category) do
            print("Trader buys: ", buys)
            if sellable_items.category == buys then
                fail = false
            end
        end
    end
    --Now checks if trade can buy uris
    if self._sv.options.buys and self._sv.options.buys.uris then
        print("You're selling: ", sellable_items.uri)
        for key,buys in pairs(self._sv.options.buys.uris) do
            print("Trader buys: ", buys)
            if sellable_items.uri == buys then
                fail = false
            end
        end
    end
    --Let sale go through if no restrictions
    if not self._sv.options.buys then
        fail = false
    end
    --Sale fails if does not meet trader restrictions
    if fail then
        print("Sale Failed") -- Figure out how to show an alert to user.
        print("")
        return false
    end

I figured out that the options table was created with the contents of inventory in the shop’s json file, and sellable_items contained the entities uri and category already. Taking the path of least resistance, here’s the additions to the shop’s json structure

        "inventory": {
          "overall_price_multiplier": 4,
          "buys": {
            "category": [
              "food",
              "tools"
            ],
            "uris":[
              "stonehearth:resources:gold:ore",
              "stonehearth:resources:iron:ore"
            ]
          },
          "entries": [
            {
              "items": [
                "stonehearth:food:carrot:carrot_basket",
                "stonehearth:food:corn:corn_basket",
                "stonehearth:food:turnip:turnip_basket",
                "stonehearth:food:pumpkin:pumpkin_basket"
              ],
              "quantity": {
                "min": 1,
                "max": 2
              }
            }
          ]
        }

Focusing on the buys part, you can see that you can choose multiple categories and uris of what the trader will purchase from you.

On a side note, I can’t believe Lua doesn’t have any sort of easy method for printing arrays, er tables(which also doesn’t make sense to me…). In the absence of a function like php’s print_r, and without creating an actual function so it could be recursive, here’s my copy and paste table printer that will go up to 4 levels deep for anyone else that’s scrounging through the code trying to figure out table structures.

   for key,value in pairs(self._sv.options) do
      print(key,value)
      if type(value) == "table" then
         for key2,value2 in pairs(value) do
            print("Next Level of ",key,"-",key2,value2)
            if type(value2) == "table" then
               for key3,value3 in pairs(value2) do
                  print("Next Level of ",key2,"-",key3,value3)
                  if type(value3) == "table" then
                     for key4,value4 in pairs(value3) do
                        print("Next Level of ",key3,"-",key4,value4)
                     end
                  end
               end
            end
         end
      end
   end

Hi @xxdalexx,
I think the javascript route would be the best way to do this.
Take a look at stonehearth\ui\game\modes\build_mode\building_designer_2\place_floor_deco_tool.js
When you create the palette, you can pass in a filter function
like this
self._palette = items.stonehearthItemPalette({
click: function(item) {
var brush = item.attr(‘uri’);

           // Remember what we've selected.
           self.buildingDesigner.saveKey(self.saveKey, brush);

           // Re/activate the tool with the new material.
           self.buildingDesigner.activateTool(self.buildTool);
        },

        filter: function(item) {
           var category_index = self.category.indexOf(item.category);
           return category_index > -1;
        },
     });

Let me know if you run into more issues.
Thanks
-Yang

1 Like