diff --git a/README.md b/README.md index 28bf8bd..b141cfb 100644 --- a/README.md +++ b/README.md @@ -73,6 +73,10 @@ local trigger = awards.register_trigger(name, { get_key = function(self, def) return minetest.registered_aliases[def.trigger.node] or def.trigger.node end, + + -- "counted_key" only, true if the key is an item name. On notify(), + -- any watched groups will also be notified as `group:groupname` keys. + key_is_item = true, }) ``` diff --git a/api.lua b/api.lua index 2fe2e22..e625785 100644 --- a/api.lua +++ b/api.lua @@ -178,8 +178,14 @@ function awards.register_trigger(tname, tdef) awards["notify_" .. tname] = tdef.notify elseif tdef.type == "counted_key" then + if tdef.key_is_item then + tdef.watched_groups = {} + end + + -- On award register local old_reg = tdef.on_register function tdef:on_register(def) + -- Register trigger local tmp = { award = def.name, key = tdef:get_key(def), @@ -187,6 +193,12 @@ function awards.register_trigger(tname, tdef) } tdef.register(tmp) + -- If group, add it to watch list + if tdef.key_is_item and tmp.key and tmp.key:sub(1, 6) == "group:" then + tdef.watched_groups[tmp.key:sub(7, #tmp.key)] = true + end + + -- Called to get progress values and labels function def.getProgress(_, data) local done data[tname] = data[tname] or {} @@ -201,6 +213,7 @@ function awards.register_trigger(tname, tdef) } end + -- Build description if none is specificed by the award function def.getDefaultDescription(_) local n = def.trigger.target if tmp.key then @@ -213,6 +226,7 @@ function awards.register_trigger(tname, tdef) end end + -- Call on_register in trigger type definition if old_reg then return old_reg(tdef, def) end @@ -221,6 +235,17 @@ function awards.register_trigger(tname, tdef) function tdef.notify(player, key, n) n = n or 1 + if tdef.key_is_item and key:sub(1, 6) ~= "group:" then + local itemdef = minetest.registered_items[key] + if itemdef then + for groupname, _ in pairs(itemdef.groups or {}) do + if tdef.watched_groups[groupname] then + tdef.notify(player, "group:" .. groupname, n) + end + end + end + end + assert(player and player.is_player and player:is_player() and key) local name = player:get_player_name() local data = awards.player(name) @@ -229,7 +254,9 @@ function awards.register_trigger(tname, tdef) data[tname] = data[tname] or {} local currentVal = (data[tname][key] or 0) + n data[tname][key] = currentVal - data[tname].__total = (data[tname].__total or 0) + n + if key:sub(1, 6) ~= "group:" then + data[tname].__total = (data[tname].__total or 0) + n + end tdef:run_callbacks(player, data, function(entry) local current diff --git a/triggers.lua b/triggers.lua index 1a7b311..32a0b85 100644 --- a/triggers.lua +++ b/triggers.lua @@ -64,7 +64,8 @@ awards.register_trigger("dig", { auto_description_total = { "Mine @1 block.", "Mine @1 blocks." }, get_key = function(self, def) return minetest.registered_aliases[def.trigger.node] or def.trigger.node - end + end, + key_is_item = true, }) minetest.register_on_dignode(function(pos, node, player) if not player or not pos or not node then @@ -84,7 +85,8 @@ awards.register_trigger("place", { auto_description_total = { "Place @1 block.", "Place @1 blocks." }, get_key = function(self, def) return minetest.registered_aliases[def.trigger.node] or def.trigger.node - end + end, + key_is_item = true, }) minetest.register_on_placenode(function(pos, node, player) if not player or not pos or not node then @@ -104,7 +106,8 @@ awards.register_trigger("craft", { auto_description_total = { "Craft @1 item", "Craft @1 items." }, get_key = function(self, def) return minetest.registered_aliases[def.trigger.item] or def.trigger.item - end + end, + key_is_item = true, }) minetest.register_on_craft(function(itemstack, player, old_craft_grid, craft_inv) if not player or itemstack:is_empty() then @@ -124,7 +127,8 @@ awards.register_trigger("eat", { auto_description_total = { "Eat @1 item", "Eat @1 items." }, get_key = function(self, def) return minetest.registered_aliases[def.trigger.item] or def.trigger.item - end + end, + key_is_item = true, }) minetest.register_on_item_eat(function(_, _, itemstack, player, _) if not player or itemstack:is_empty() then