1
0
mirror of https://gitlab.com/rubenwardy/awards.git synced 2025-06-28 22:26:17 +02:00

6 Commits

Author SHA1 Message Date
8702b6cdd8 Merge remote-tracking branch 'upstream/master' into nalc-1.2-dev 2020-06-16 20:49:49 +02:00
baf79bf9bf Merge branch 'master' of yunohost.local:mtcontrib/awards into nalc-1.2-dev 2019-12-21 13:09:58 +01:00
4f5260da5f Corrige la commande /awards.
Corrige l'affige des awards d'un joueur donné.
Empêche le retour de l'inventaire sfinv quand on active ou desactive
les awards d'un joueur.
2019-03-03 22:40:11 +01:00
89d4a93f3b Ajoute le privilège awards_admin
Modifie la commande /awards en conséquence
2019-03-03 13:24:28 +01:00
cae2c1ee3b Tente la correction d'un crash 2019-03-02 21:08:02 +01:00
54db6ce0c0 Suppression de minetest.register_on_craft
Cette fonction a été réécrite dans nalc_awards
2019-03-02 19:49:08 +01:00
8 changed files with 141 additions and 162 deletions

View File

@ -37,11 +37,10 @@ awards.register_award("mymod:award", {
The above trigger type is an example of a counted_key trigger: The above trigger type is an example of a counted_key trigger:
rather than a single counter there's a counter per key - in this rather than a single counter there's a counter per key - in this
case the key is the value of the `node` field. case the key is the value of the `node` field. If you leave out
the key in a `counted_key` trigger, then the total will be used
If you leave out the key in a `counted_key` trigger, then the total will be used instead. For example, here is an award which unlocks after you've
instead. For example, here is an award which unlocks after you've placed 10 placed 10 nodes of any type:
nodes of any type:
```lua ```lua
awards.register_award("mymod:award", { awards.register_award("mymod:award", {
@ -126,10 +125,6 @@ awards.register_trigger("foo", {
type = "custom", type = "custom",
progress = "@1/@2 foos", progress = "@1/@2 foos",
auto_description = { "Do a foo", "Foo @1 times" }, auto_description = { "Do a foo", "Foo @1 times" },
on_register = function(self, award)
print(award.name .. " was registered with foo trigger type")
end,
}) })
minetest.register_on_foo(function() minetest.register_on_foo(function()
@ -173,9 +168,7 @@ end
# API # API
## Awards * awards.register_award(name, def), the def table has the following fields:
* `awards.register_award(name, def)`, the def table has the following fields:
* `title` - title of the award (defaults to name) * `title` - title of the award (defaults to name)
* `description` - longer description of the award, displayed in Awards tab * `description` - longer description of the award, displayed in Awards tab
* `difficulty` - see [Award Difficulty](#award-difficulty). * `difficulty` - see [Award Difficulty](#award-difficulty).
@ -189,48 +182,23 @@ end
* `background` - the background image, use default otherwise. * `background` - the background image, use default otherwise.
* `trigger` - trigger definition, see [Builtin Trigger Types](#builtin-trigger-types). * `trigger` - trigger definition, see [Builtin Trigger Types](#builtin-trigger-types).
* `on_unlock(name, def)` - callback on unlock. * `on_unlock(name, def)` - callback on unlock.
* `awards.registered_awards` - table of award name to definition. * awards.register_trigger(name, def), the def table has the following fields:
* `awards.register_on_unlock(func(name, def))` * `type` - see [Trigger Types](#trigger-types).
* `name` is the player name
* `def` is the award def.
* return true to cancel HUD
* `awards.unlock(player_name, award_name)`
* gives an award to a player
* `awards.get_award_states(player_name)`
* Returns list of tables, sorted by `score`, each having the fields:
```lua
{
name = "mymod:awardname",
def = {}, -- Award definition
unlocked = true, -- Whether award has been unlocked
started = true, -- Whether any progress has been made
score = 0, -- Score used in sorting
-- Either a table or nil
-- Will be nil if progress is indeterminable or
-- if the award is unlocked
progress = {
current = 5,
target = 10,
label = "label", -- Label to show over progress bar
}
}
```
## Triggers
* `awards.register_trigger(name, def)`, the def table has the following fields:
* `type` - see trigger type types in [Trigger Types](#trigger-types).
* `progress` - used to format progress, defaults to "%1/%2". * `progress` - used to format progress, defaults to "%1/%2".
* `auto_description` - a table of two elements. Each element is a format string. Element 1 is singular, element 2 is plural. Used for the award description (not title) if none is given. * `auto_description` - a table of two elements. Each element is a format string. Element 1 is singular, element 2 is plural. Used for the award description (not title) if none is given.
* `on_register(self, award_def)` - called when an award registers with this type. * `on_register(award_def)` - called when an award registers with this type.
* "counted_key" only: * "counted_key" only:
* `auto_description_total` - Used if the trigger is for the total. * `auto_description_total` - Used if the trigger is for the total.
* `get_key(self, def)` - get key for particular award, return nil for a total. * `get_key(self, def)` - get key for particular award, return nil for a total.
* `key_is_item` - true if the key is an item name. On notify(), * `key_is_item` - true if the key is an item name. On notify(),
any watched groups will also be notified as `group:groupname` keys. any watched groups will also be notified as `group:groupname` keys.
* `awards.registered_triggers` - table of trigger name to definition. * awards.register_on_unlock(func(name, def))
* name is the player name
* def is the award def.
* return true to cancel HUD
* awards.unlock(name, award)
* gives an award to a player
* name is the player name
## Builtin Trigger Types ## Builtin Trigger Types

View File

@ -3,9 +3,7 @@
-- The global award namespace -- The global award namespace
awards = { awards = {
show_mode = "hud", show_mode = "hud",
registered_awards = {},
registered_triggers = {}, registered_triggers = {},
on_unlock = {},
} }
-- Internationalization support. -- Internationalization support.

View File

@ -127,6 +127,9 @@ function awards.unlock(name, award)
end end
else else
local player = minetest.get_player_by_name(name) local player = minetest.get_player_by_name(name)
if not (player and player.is_player and player:is_player()) then
return
end
local one = player:hud_add({ local one = player:hud_add({
hud_elem_type = "image", hud_elem_type = "image",
name = "award_bg", name = "award_bg",
@ -182,71 +185,3 @@ function awards.unlock(name, award)
end) end)
end end
end end
function awards.get_award_states(name)
local hash_is_unlocked = {}
local retval = {}
-- Add all unlocked awards
local data = awards.player(name)
if data and data.unlocked then
for awardname, _ in pairs(data.unlocked) do
local def = awards.registered_awards[awardname]
if def then
hash_is_unlocked[awardname] = true
local score = -100000
local difficulty = def.difficulty or 1
if def.trigger and def.trigger.target then
difficulty = difficulty * def.trigger.target
end
score = score + difficulty
retval[#retval + 1] = {
name = awardname,
def = def,
unlocked = true,
started = true,
score = score,
progress = nil,
}
end
end
end
-- Add all locked awards
for _, def in pairs(awards.registered_awards) do
if not hash_is_unlocked[def.name] and def:can_unlock(data) then
local progress = def.get_progress and def:get_progress(data)
local started = false
local score = def.difficulty or 1
if def.secret then
score = 1000000
elseif def.trigger and def.trigger.target and progress then
local perc = progress.current / progress.target
score = score * (1 - perc) * def.trigger.target
if perc < 0.001 then
score = score + 100
else
started = true
end
else
score = 100
end
retval[#retval + 1] = {
name = def.name,
def = def,
unlocked = false,
started = started,
score = score,
progress = progress,
}
end
end
table.sort(retval, function(a, b)
return a.score < b.score
end)
return retval
end

View File

@ -2,7 +2,9 @@
local S, NS = awards.gettext, awards.ngettext local S, NS = awards.gettext, awards.ngettext
awards.registered_awards = {}
awards.on = {} awards.on = {}
awards.on_unlock = {}
local default_def = {} local default_def = {}
@ -41,12 +43,11 @@ function awards.register_trigger(tname, tdef)
} }
tdef.register(tmp) tdef.register(tmp)
function def.get_progress(_, data) function def.getProgress(_, data)
local current = math.min(data[tname] or 0, tmp.target) local done = math.min(data[tname] or 0, tmp.target)
return { return {
current = current, perc = done / tmp.target,
target = tmp.target, label = S(tdef.progress, done, tmp.target),
label = S(tdef.progress, current, tmp.target),
} }
end end
@ -101,7 +102,7 @@ function awards.register_trigger(tname, tdef)
end end
-- Called to get progress values and labels -- Called to get progress values and labels
function def.get_progress(_, data) function def.getProgress(_, data)
data[tname] = data[tname] or {} data[tname] = data[tname] or {}
local done local done
@ -113,8 +114,7 @@ function awards.register_trigger(tname, tdef)
done = math.min(done, tmp.target) done = math.min(done, tmp.target)
return { return {
current = done, perc = done / tmp.target,
target = tmp.target,
label = S(tdef.progress, done, tmp.target), label = S(tdef.progress, done, tmp.target),
} }
end end

View File

@ -1090,7 +1090,7 @@ if minetest.get_modpath("mesecons") then
difficulty = 0.2, difficulty = 0.2,
trigger = { trigger = {
type = "place", type = "place",
node = "mesecons:wire_00000000_off", node = "pipeworks:tube_1",
target = 500, target = 500,
} }
}) })
@ -1099,7 +1099,7 @@ end
if minetest.get_modpath("basic_materials") then if minetest.get_modpath("basic_materials") then
awards.register_award("awards_oil", { awards.register_award("awards_oil", {
title = S("Oil Typhoon"), title = S("Oil Typhoon"),
description = S("Craft 500 times oil extract."), description = S("Craft 100 times flint and steel."),
trigger = { trigger = {
type = "craft", type = "craft",

View File

@ -2,28 +2,39 @@
local S = awards.gettext local S = awards.gettext
minetest.register_privilege("awards_admin", { description = "Can manage awards of given player" })
minetest.register_chatcommand("awards", { minetest.register_chatcommand("awards", {
params = S("[c|clear|disable|enable]"), params = "[c|clear|disable|enable] [player_name]",
description = S("Show, clear, disable or enable your awards"), description = "Show, clear, disable or enable player's awards",
func = function(name, param) func = function(name, param)
if param == "clear" then if not minetest.check_player_privs(name, { awards_admin = true }) then
awards.clear_player(name) return false, "You need awards_admin privilege!"
minetest.chat_send_player(name, end
S("All your awards and statistics have been cleared. You can now start again.")) local action, playern = param:split(" ")[1], param:split(" ")[2] or name
elseif param == "disable" then if action == "clear" then
awards.disable(name) awards.clear_player(playern)
minetest.chat_send_player(name, S("You have disabled awards.")) minetest.chat_send_player(playern,
elseif param == "enable" then S("All your awards and statistics have been cleared. You can now start again."))
awards.enable(name) minetest.chat_send_player(name, "All awards and statistics of "..playern.." have been cleared.")
minetest.chat_send_player(name, S("You have enabled awards.")) elseif action == "disable" then
elseif param == "c" then awards.disable(playern)
awards.show_to(name, name, nil, true) minetest.chat_send_player(playern, "Your awards are disabled.")
else minetest.chat_send_player(name, "You have disabled awards of "..playern..".")
elseif action == "enable" then
awards.enable(playern)
minetest.chat_send_player(playern, "Your awards are enabled.")
minetest.chat_send_player(name, "You have enabled awards of "..playern..".")
elseif action == "c" then
awards.show_to(playern, name, nil, true)
elseif not action then
awards.show_to(name, name, nil, false) awards.show_to(name, name, nil, false)
else
awards.show_to(action, name, nil, true)
end end
if (param == "disable" or param == "enable") and minetest.global_exists("sfinv") then if (action == "disable" or action == "enable") and minetest.global_exists("sfinv") and not minetest.get_modpath("unified_inventory") then
local player = minetest.get_player_by_name(name) local player = minetest.get_player_by_name(playern)
if player then if player then
sfinv.set_player_inventory_formspec(player) sfinv.set_player_inventory_formspec(player)
end end

View File

@ -2,9 +2,73 @@
local S = awards.gettext local S = awards.gettext
local function order_awards(name)
local hash_is_unlocked = {}
local retval = {}
local data = awards.player(name)
if data and data.unlocked then
for awardname, _ in pairs(data.unlocked) do
local def = awards.registered_awards[awardname]
if def then
hash_is_unlocked[awardname] = true
local score = -100000
local difficulty = def.difficulty or 1
if def.trigger and def.trigger.target then
difficulty = difficulty * def.trigger.target
end
score = score + difficulty
retval[#retval + 1] = {
name = awardname,
def = def,
unlocked = true,
started = true,
score = score,
}
end
end
end
for _, def in pairs(awards.registered_awards) do
if not hash_is_unlocked[def.name] and def:can_unlock(data) then
local started = false
local score = def.difficulty or 1
if def.secret then
score = 1000000
elseif def.trigger and def.trigger.target and def.getProgress then
local progress = def:getProgress(data).perc
score = score * (1 - progress) * def.trigger.target
if progress < 0.001 then
score = score + 100
else
started = true
end
else
score = 100
end
retval[#retval + 1] = {
name = def.name,
def = def,
unlocked = false,
started = started,
score = score,
}
end
end
table.sort(retval, function(a, b)
return a.score < b.score
end)
return retval
end
function awards.get_formspec(name, to, sid) function awards.get_formspec(name, to, sid)
local formspec = "" local formspec = ""
local awards_list = awards.get_award_states(name) local awards_list = order_awards(name)
local data = awards.player(name)
if #awards_list == 0 then if #awards_list == 0 then
formspec = formspec .. "label[3.9,1.5;"..minetest.formspec_escape(S("Error: No achivements available.")).."]" formspec = formspec .. "label[3.9,1.5;"..minetest.formspec_escape(S("Error: No achivements available.")).."]"
@ -42,11 +106,15 @@ function awards.get_formspec(name, to, sid)
if sdef and sdef.icon then if sdef and sdef.icon then
formspec = formspec .. "image[0.45,0;3.5,3.5;" .. sdef.icon .. "]" -- adjusted values from 0.6,0;3,3 formspec = formspec .. "image[0.45,0;3.5,3.5;" .. sdef.icon .. "]" -- adjusted values from 0.6,0;3,3
end end
local barwidth = 3.95
if sitem.progress then local perc = nil
local barwidth = 3.95 local label = nil
local perc = sitem.progress.current / sitem.progress.target if sdef.getProgress and data then
local label = sitem.progress.label local res = sdef:getProgress(data)
perc = res.perc
label = res.label
end
if perc then
if perc > 1 then if perc > 1 then
perc = 1 perc = 1
end end
@ -56,7 +124,6 @@ function awards.get_formspec(name, to, sid)
formspec = formspec .. "label[1.6,8.15;" .. minetest.formspec_escape(label) .. "]" formspec = formspec .. "label[1.6,8.15;" .. minetest.formspec_escape(label) .. "]"
end end
end end
if sdef and sdef.description then if sdef and sdef.description then
formspec = formspec .. "box[-0.05,3.75;3.9,4.2;#000]" formspec = formspec .. "box[-0.05,3.75;3.9,4.2;#000]"
formspec = formspec .. "textarea[0.25,3.75;3.9,4.2;;" .. formspec = formspec .. "textarea[0.25,3.75;3.9,4.2;;" ..
@ -101,13 +168,13 @@ function awards.show_to(name, to, sid, text)
if name == "" or name == nil then if name == "" or name == nil then
name = to name = to
end end
local data = awards.player(to) local data = awards.player(name)
if name == to and data.disabled then if name == to and data.disabled then
minetest.chat_send_player(name, S("You've disabled awards. Type /awards enable to reenable.")) minetest.chat_send_player(name, S("You've disabled awards. Type /awards enable to reenable."))
return return
end end
if text then if text then
local awards_list = awards.get_award_states(name) local awards_list = order_awards(name)
if #awards_list == 0 then if #awards_list == 0 then
minetest.chat_send_player(to, S("Error: No award available.")) minetest.chat_send_player(to, S("Error: No award available."))
return return

View File

@ -113,15 +113,15 @@ awards.register_trigger("craft", {
end, end,
key_is_item = true, key_is_item = true,
}) })
minetest.register_on_craft(function(itemstack, player, old_craft_grid, craft_inv) --minetest.register_on_craft(function(itemstack, player, old_craft_grid, craft_inv)
if not player_ok(player) or itemstack:is_empty() then -- if not player_ok(player) or itemstack:is_empty() then
return -- return
end -- end
--
local itemname = itemstack:get_name() -- local itemname = itemstack:get_name()
itemname = minetest.registered_aliases[itemname] or itemname -- itemname = minetest.registered_aliases[itemname] or itemname
awards.notify_craft(player, itemname, itemstack:get_count()) -- awards.notify_craft(player, itemname, itemstack:get_count())
end) --end)
awards.register_trigger("eat", { awards.register_trigger("eat", {