diff --git a/mods/tt/API.md b/mods/tt/API.md index 4616fdc..a510553 100644 --- a/mods/tt/API.md +++ b/mods/tt/API.md @@ -7,9 +7,6 @@ Add these to the item definition. * `_tt_ignore`: If `true`, the `description` of this item won't be altered at all * `_tt_help`: Custom help text -* `_tt_food`: If `true`, item is a food item that can be consumed by the player -* `_tt_food_hp`: Health increase (in HP) for player when consuming food item -* `_tt_food_satiation`: Satiation increase for player when consuming food item (note: the meaning of satiation is depending on the game being used; some games might not have a satiation mechanic at all, in which case you can skip this field) Once this mod had overwritten the `description` field of an item was overwritten, it will save the original (unaltered) `description` in the `_tt_original_description` field. @@ -17,8 +14,11 @@ Once this mod had overwritten the `description` field of an item was overwritten Register a custom snippet function. `func` is a function of the form `func(itemstring)`. -It will be called for (nearly) every itemstring and it must return a string you want to append to this item or `nil` if nothing shall be appended. -You can optionally return the text color in `"#RRGGBB"` format as the second return value. +It will be called for (nearly) every itemstring. + +Returns: Two values, the first one is required. +1st return value: A string you want to append to this item or `nil` if nothing shall be appended. +2nd return value: If nil, `tt` will take of the text color. If a ColorString in `"#RRGGBB"` format, entire text is colorized in this color. Return `false` to force `tt` to not apply text any colorization (useful if you want to call `minetest.colorize` yourself. Example: diff --git a/mods/tt/README.md b/mods/tt/README.md index ca76902..92cd652 100644 --- a/mods/tt/README.md +++ b/mods/tt/README.md @@ -1,12 +1,11 @@ # Extended Tooltip (`tt`) This mod extends the tooltip of items to add more informative texts. -It displays the following useful information: -* Weapon damage and speed -* Tool properties -* Noteworthy block properties -* Food satiation -* Custom help text (added by mods) +The mod itself does nothing and is meant to be integrated into +games to use the API to define custom tooltips (see `API.md`). + +## Version +1.0.0 ## License MIT License. diff --git a/mods/tt/init.lua b/mods/tt/init.lua index fe663c5..a79bf27 100644 --- a/mods/tt/init.lua +++ b/mods/tt/init.lua @@ -1,127 +1,50 @@ -local S = minetest.get_translator("tt") -local COLOR_DEFAULT = "#d0ffd0" -local COLOR_DANGER = "#ffff00" -local COLOR_GOOD = "#00ff00" - tt = {} +tt.COLOR_DEFAULT = "#d0ffd0" +tt.COLOR_DANGER = "#ffff00" +tt.COLOR_GOOD = "#00ff00" + +-- API tt.registered_snippets = {} -local function append_descs() - for itemstring, def in pairs(minetest.registered_items) do - if itemstring ~= "" and itemstring ~= "air" and itemstring ~= "ignore" and itemstring ~= "unknown" and def ~= nil and def.description ~= nil and def.description ~= "" and def._tt_ignore ~= true then - local desc = def.description - local orig_desc = desc - -- Custom text - if def._tt_help then - desc = desc .. "\n" .. minetest.colorize(COLOR_DEFAULT, def._tt_help) - end - -- Tool info - if def.tool_capabilities then - -- Digging stats - if def.tool_capabilities.groupcaps then - -- TODO: Add more detail (such as digging speed) - --local groups = {} - --for group, caps in pairs(def.tool_capabilities.groupcaps) do - -- table.insert(groups, group) - --end - --desc = desc .. "\n" .. minetest.colorize(COLOR_DEFAULT, S("Digs: @1", table.concat(groups, ", "))) - end - -- Weapon stats - if def.tool_capabilities.damage_groups then - for group, damage in pairs(def.tool_capabilities.damage_groups) do - if group == "fleshy" then - desc = desc .. "\n" .. minetest.colorize(COLOR_DEFAULT, S("Damage: @1", damage)) - else - desc = desc .. "\n" .. minetest.colorize(COLOR_DEFAULT, S("Damage (@1): @2", group, damage)) - end - end - local full_punch_interval = def.tool_capabilities.full_punch_interval - if not full_punch_interval then - full_punch_interval = 1 - end - desc = desc .. "\n" .. minetest.colorize(COLOR_DEFAULT, S("Full punch interval: @1s", full_punch_interval)) - end - end - -- Food - if def._tt_food then - desc = desc .. "\n" .. minetest.colorize(COLOR_DEFAULT, S("Food item")) - if def._tt_food_hp then - local msg = S("+@1 food points", def._tt_food_hp) - desc = desc .. "\n" .. minetest.colorize(COLOR_DEFAULT, msg) - end - -- NOTE: This is unused atm - --[[if def._tt_food_satiation then - if def._tt_food_satiation >= 0 then - msg = S("+@1 satiation", def._tt_food_satiation) - else - msg = S("@1 satiation", def._tt_food_satiation) - end - desc = desc .. "\n" .. minetest.colorize(COLOR_DEFAULT, msg) - end]] - end - -- Node info - -- Damage-related - do - if def.damage_per_second and def.damage_per_second > 0 then - desc = desc .. "\n" .. minetest.colorize(COLOR_DANGER, S("Contact damage: @1 per second", def.damage_per_second)) - end - if def.drowning and def.drowning > 0 then - desc = desc .. "\n" .. minetest.colorize(COLOR_DANGER, S("Drowning damage: @1", def.drowning)) - end - local tmp = minetest.get_item_group(itemstring, "fall_damage_add_percent") - if tmp > 0 then - desc = desc .. "\n" .. minetest.colorize(COLOR_DANGER, S("Fall damage: +@1%", tmp)) - elseif tmp == -100 then - desc = desc .. "\n" .. minetest.colorize(COLOR_GOOD, S("No fall damage")) - elseif tmp < 0 then - desc = desc .. "\n" .. minetest.colorize(COLOR_DEFAULT, S("Fall damage: @1%", tmp)) - end - end - -- Movement-related node facts - if minetest.get_item_group(itemstring, "disable_jump") == 1 and not def.climbable then - if def.liquidtype == "none" then - desc = desc .. "\n" .. minetest.colorize(COLOR_DEFAULT, S("No jumping")) - else - desc = desc .. "\n" .. minetest.colorize(COLOR_DEFAULT, S("No swimming upwards")) - end - end - if def.climbable then - if minetest.get_item_group(itemstring, "disable_jump") == 1 then - desc = desc .. "\n" .. minetest.colorize(COLOR_DEFAULT, S("Climbable (only downwards)")) - else - desc = desc .. "\n" .. minetest.colorize(COLOR_DEFAULT, S("Climbable")) - end - end - if minetest.get_item_group(itemstring, "slippery") >= 1 then - desc = desc .. "\n" .. minetest.colorize(COLOR_DEFAULT, S("Slippery")) - end - local tmp = minetest.get_item_group(itemstring, "bouncy") - if tmp >= 1 then - desc = desc .. "\n" .. minetest.colorize(COLOR_DEFAULT, S("Bouncy (@1%)", tmp)) - end - -- Node appearance - tmp = def.light_source - if tmp and tmp >= 1 then - desc = desc .. "\n" .. minetest.colorize(COLOR_DEFAULT, S("Luminance: @1", tmp)) - end - -- Custom functions - for s=1, #tt.registered_snippets do - local str, snippet_color = tt.registered_snippets[s](itemstring) - if not snippet_color then - snippet_color = COLOR_DEFAULT - end - if str then - desc = desc .. "\n" .. minetest.colorize(snippet_color, str) - end - end - - minetest.override_item(itemstring, { description = desc, _tt_original_description = orig_desc }) - end - end -end - tt.register_snippet = function(func) table.insert(tt.registered_snippets, func) end -minetest.register_on_mods_loaded(append_descs) +dofile(minetest.get_modpath(minetest.get_current_modname()).."/snippets.lua") + +-- Apply item description updates + +local function append_snippets() + for itemstring, def in pairs(minetest.registered_items) do + if itemstring ~= "" and itemstring ~= "air" and itemstring ~= "ignore" and itemstring ~= "unknown" and def ~= nil and def.description ~= nil and def.description ~= "" and def._tt_ignore ~= true then + local desc = def.description + local orig_desc = desc + local first = true + -- Apply snippets + for s=1, #tt.registered_snippets do + local str, snippet_color = tt.registered_snippets[s](itemstring) + if snippet_color == nil then + snippet_color = tt.COLOR_DEFAULT + elseif snippet_color == false then + snippet_color = false + end + if str then + if first then + first = false + end + desc = desc .. "\n" + if snippet_color then + desc = desc .. minetest.colorize(snippet_color, str) + else + desc = desc .. str + end + end + end + if desc ~= def.description then + minetest.override_item(itemstring, { description = desc, _tt_original_description = orig_desc }) + end + end + end +end + +minetest.register_on_mods_loaded(append_snippets) diff --git a/mods/tt/mod.conf b/mods/tt/mod.conf index aee1572..d5c8c2e 100644 --- a/mods/tt/mod.conf +++ b/mods/tt/mod.conf @@ -1,2 +1,2 @@ name = tt -description = Appends a helpful tooltip to the item description +description = Support for custom tooltip extensions for items diff --git a/mods/tt/snippets.lua b/mods/tt/snippets.lua new file mode 100644 index 0000000..694b225 --- /dev/null +++ b/mods/tt/snippets.lua @@ -0,0 +1,11 @@ +-- CUSTOM SNIPPETS -- + +-- Custom text (_tt_help) +tt.register_snippet(function(itemstring) + local def = minetest.registered_items[itemstring] + if def._tt_help then + return def._tt_help + end +end) + + diff --git a/mods/tt_base/README.md b/mods/tt_base/README.md new file mode 100644 index 0000000..5622e36 --- /dev/null +++ b/mods/tt_base/README.md @@ -0,0 +1,25 @@ +This mod is for the Extended Tooltips [tt] mod to extend item tooltips with the following +basic info: + +* Tool digging times +* Weapon stats +* Food stats +* Node damage +* Node light level +* Node info: climbable, slippery, bouncy, jumping restriction + +This mod assumes that the default gameplay behavior of Minetest is used. + +This mod introduces support for new item definition fields: + +* `_tt_food`: If `true`, item is a food item that can be consumed by the player +* `_tt_food_hp`: Health increase (in HP) for player when consuming food item + +Because there is no standard way in Minetest (yet) to mark an item as food, these fields +are required for food items to be recognized as such. + +## Version +1.0.0 + +## License +MIT License. diff --git a/mods/tt_base/init.lua b/mods/tt_base/init.lua new file mode 100644 index 0000000..4ea8a00 --- /dev/null +++ b/mods/tt_base/init.lua @@ -0,0 +1,190 @@ +local S = minetest.get_translator("tt_base") + +local function get_min_digtime(caps) + local mintime + local unique = true + local maxlevel = caps.maxlevel + if not maxlevel then + maxlevel = 1 + end + if maxlevel > 1 then + unique = false + end + if caps.times then + for r=1,3 do + local time = caps.times[r] + if time and maxlevel > 1 then + time = time / maxlevel + end + if time and ((not mintime) or (time < mintime)) then + if mintime and (time < mintime) then + unique = false + end + mintime = time + end + end + end + return mintime, unique +end + +local function newline(str) + if str ~= "" then + str = str .. "\n" + end + return str +end + +-- Tool information (digging times, weapon stats) +tt.register_snippet(function(itemstring) + local def = minetest.registered_items[itemstring] + local desc = "" + if def.tool_capabilities then + -- Digging times + local digs = "" + local d + if def.tool_capabilities.groupcaps then + for group, caps in pairs(def.tool_capabilities.groupcaps) do + local mintime, unique_mintime + if caps.times then + mintime, unique_mintime = get_min_digtime(caps) + if mintime and (mintime > 0 or (not unique_mintime)) then + d = S("Digs @1 blocks", group) .. "\n" + d = d .. S("Minimum dig time: @1s", string.format("%.2f", mintime)) + digs = newline(digs) + digs = digs .. d + elseif mintime and mintime == 0 then + d = S("Digs @1 blocks instantly", group) + digs = newline(digs) + digs = digs .. d + end + end + end + if digs ~= "" then + desc = desc .. digs + end + end + -- Weapon stats + if def.tool_capabilities.damage_groups then + for group, damage in pairs(def.tool_capabilities.damage_groups) do + local msg + if group == "fleshy" then + if damage >= 0 then + msg = S("Damage: @1", damage) + else + msg = S("Healing: @1", math.abs(damage)) + end + else + if damage >= 0 then + msg = S("Damage (@1): @2", group, damage) + else + msg = S("Healing (@1): @2", group, math.abs(damage)) + end + end + desc = newline(desc) + desc = desc .. msg + end + local full_punch_interval = def.tool_capabilities.full_punch_interval + if not full_punch_interval then + full_punch_interval = 1 + end + desc = newline(desc) + desc = desc .. S("Full punch interval: @1s", string.format("%.2f", full_punch_interval)) + end + end + if desc == "" then + desc = nil + end + return desc +end) + +-- Food +tt.register_snippet(function(itemstring) + local def = minetest.registered_items[itemstring] + local desc + if def._tt_food then + desc = S("Food item") + if def._tt_food_hp then + local msg = S("+@1 food points", def._tt_food_hp) + desc = desc .. "\n" .. msg + end + end + return desc +end) + +-- Node info +tt.register_snippet(function(itemstring) + local def = minetest.registered_items[itemstring] + local desc = "" + + -- Health-related node facts + if def.damage_per_second then + if def.damage_per_second > 0 then + desc = newline(desc) + desc = desc .. minetest.colorize(tt.COLOR_DANGER, S("Contact damage: @1 per second", def.damage_per_second)) + elseif def.damage_per_second < 0 then + desc = newline(desc) + desc = desc .. minetest.colorize(tt.COLOR_GOOD, S("Contact healing: @1 per second", math.abs(def.damage_per_second))) + end + end + if def.drowning and def.drowning ~= 0 then + desc = newline(desc) + desc = desc .. minetest.colorize(tt.COLOR_DANGER, S("Drowning damage: @1", def.drowning)) + end + local tmp = minetest.get_item_group(itemstring, "fall_damage_add_percent") + if tmp > 0 then + desc = newline(desc) + desc = desc .. minetest.colorize(tt.COLOR_DANGER, S("Fall damage: +@1%", tmp)) + elseif tmp == -100 then + desc = newline(desc) + desc = desc .. minetest.colorize(tt.COLOR_GOOD, S("No fall damage")) + elseif tmp < 0 then + desc = newline(desc) + desc = desc .. minetest.colorize(tt.COLOR_DEFAULT, S("Fall damage: @1%", tmp)) + end + + -- Movement-related node facts + if minetest.get_item_group(itemstring, "disable_jump") == 1 and not def.climbable then + if def.liquidtype == "none" then + desc = newline(desc) + desc = desc .. minetest.colorize(tt.COLOR_DEFAULT, S("No jumping")) + elseif minetest.get_item_group(itemstring, "fake_liquid") == 0 then + desc = newline(desc) + desc = desc .. minetest.colorize(tt.COLOR_DEFAULT, S("No swimming upwards")) + else + desc = newline(desc) + desc = desc .. minetest.colorize(tt.COLOR_DEFAULT, S("No rising")) + end + end + if def.climbable then + if minetest.get_item_group(itemstring, "disable_jump") == 1 then + desc = newline(desc) + desc = desc .. minetest.colorize(tt.COLOR_DEFAULT, S("Climbable (only downwards)")) + else + desc = newline(desc) + desc = desc .. minetest.colorize(tt.COLOR_DEFAULT, S("Climbable")) + end + end + if minetest.get_item_group(itemstring, "slippery") >= 1 then + desc = newline(desc) + desc = desc .. minetest.colorize(tt.COLOR_DEFAULT, S("Slippery")) + end + local tmp = minetest.get_item_group(itemstring, "bouncy") + if tmp >= 1 then + desc = newline(desc) + desc = desc .. minetest.colorize(tt.COLOR_DEFAULT, S("Bouncy (@1%)", tmp)) + end + + -- Node appearance + tmp = def.light_source + if tmp and tmp >= 1 then + desc = newline(desc) + desc = desc .. minetest.colorize(tt.COLOR_DEFAULT, S("Luminance: @1", tmp)) + end + + + if desc == "" then + desc = nil + end + return desc, false +end) + diff --git a/mods/tt/locale/template.txt b/mods/tt_base/locale/template.txt similarity index 71% rename from mods/tt/locale/template.txt rename to mods/tt_base/locale/template.txt index 62b248b..488a0e2 100644 --- a/mods/tt/locale/template.txt +++ b/mods/tt_base/locale/template.txt @@ -1,12 +1,15 @@ # textdomain:tt Damage: @1= Damage (@1): @2= +Healing: @1= +Healing (@1): @2= Full punch interval: @1s= Food item= +@1 satiation= @1 satiation= +@1 food points= Contact damage: @1 per second= +Contact healing: @1 per second= Drowning damage: @1= Bouncy (@1%)= Luminance: @1= @@ -15,6 +18,10 @@ Climbable= Climbable (only downwards)= No jumping= No swimming upwards= +No rising= Fall damage: @1%= Fall damage: +@1%= No fall damage= +Digs @1 blocks= +Digs @1 blocks instantly= +Minimum dig time: @1s= diff --git a/mods/tt/locale/tt.de.tr b/mods/tt_base/locale/tt_base.de.tr similarity index 67% rename from mods/tt/locale/tt.de.tr rename to mods/tt_base/locale/tt_base.de.tr index adf0432..6e45bf6 100644 --- a/mods/tt/locale/tt.de.tr +++ b/mods/tt_base/locale/tt_base.de.tr @@ -1,12 +1,15 @@ -# textdomain:tt +# textdomain:tt_base Damage: @1=Schaden: @1 Damage (@1): @2=Schaden (@1): @2 +Healing: @1=Heilung: @1 +Healing (@1): @2=Heilung (@1): @2 Full punch interval: @1s=Zeit zum Ausholen: @1s Food item=Lebensmittel +@1 satiation=+@1 Sättigung @1 satiation=@1 Sättigung +@1 food points=+@1 Nahrungspunkte Contact damage: @1 per second=Kontaktschaden: @1 pro Sekunde +Contact healing: @1 per second=Kontaktheilung: @1 pro Sekunde Drowning damage: @1=Ertrinkensschaden: @1 Bouncy (@1%)=Sprunghaft (@1%) Luminance: @1=Lichtstärke: @1 @@ -15,6 +18,10 @@ Climbable=Erkletterbar Climbable (only downwards)=Erkletterbar (nur nach unten) No jumping=Kein Springen No swimming upwards=Kein nach oben schwimmen +No rising=Kein Aufsteigen Fall damage: @1%=Fallschaden: @1% Fall damage: +@1%=Fallschaden: +@1% No fall damage=Kein Fallschaden +Digs @1 blocks=Gräbt „@1“-Blöcke +Digs @1 blocks instantly=Gräbt „@1“-Blöcke sofort +Minimum dig time: @1s=Minimale Grabezeit: @1s diff --git a/mods/tt_base/mod.conf b/mods/tt_base/mod.conf new file mode 100644 index 0000000..f333041 --- /dev/null +++ b/mods/tt_base/mod.conf @@ -0,0 +1,3 @@ +name = tt_base +description = Adds generic tooltip extensions to items +depends = tt diff --git a/mods/tt_base/screenshot.png b/mods/tt_base/screenshot.png new file mode 100644 index 0000000..ef2dfa5 Binary files /dev/null and b/mods/tt_base/screenshot.png differ