diff --git a/.github/workflows/reference.yml b/.github/workflows/reference.yml
new file mode 100644
index 0000000..383bc73
--- /dev/null
+++ b/.github/workflows/reference.yml
@@ -0,0 +1,33 @@
+name: Build Reference
+
+on:
+ push:
+ branches:
+ - master
+
+jobs:
+ build:
+ name: Build
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v2
+ - name: Setup Lua
+ uses: leafo/gh-actions-lua@v8
+ with:
+ luaVersion: 5.4
+ - name: Setup Lua Rocks
+ uses: leafo/gh-actions-luarocks@v4
+ - name: Setup LDoc dependencies
+ run: luarocks install --only-deps https://raw.githubusercontent.com/lunarmodules/LDoc/master/ldoc-scm-3.rockspec
+ - name: Setup LDoc
+ run: git clone --single-branch --branch=custom https://github.com/AntumDeluge/ldoc.git .ldoc/ldoc && chmod +x .ldoc/ldoc/ldoc.lua
+ - name: Generate temp files
+ run: chmod +x .ldoc/parse_*.py && ./.ldoc/parse_src.py && ./.ldoc/parse_settings.py && ./.ldoc/parse_crafts.py
+ - name: Generate docs
+ run: ./.ldoc/ldoc/ldoc.lua --UNSAFE_NO_SANDBOX -c .ldoc/config.ld -d 3d_armor/docs/reference "$(pwd)"
+ - name: Deploy
+ uses: peaceiris/actions-gh-pages@v3
+ with:
+ github_token: ${{ secrets.GITHUB_TOKEN }}
+ publish_dir: ./3d_armor/docs
diff --git a/.ldoc/config.ld b/.ldoc/config.ld
new file mode 100644
index 0000000..615935f
--- /dev/null
+++ b/.ldoc/config.ld
@@ -0,0 +1,344 @@
+-- Place this file in mod "docs" directory
+
+local print, type, string, table, tostring, tonumber, error, pairs, ipairs
+if import then
+ print = import("print")
+ type = import("type")
+ string = import("string")
+ table = import("table")
+ tostring = import("tostring")
+ tonumber = import("tonumber")
+ error = import("error")
+ pairs = import("pairs")
+ ipairs = import("ipairs")
+end
+
+project = "3d_armor"
+title = "3D Armor"
+format = "markdown"
+not_luadoc = true
+boilerplate = false
+wrap = false
+style = true
+
+file = {
+ "3d_armor/api.lua",
+ ".ldoc/settings.luadoc",
+ --".ldoc/armors.luadoc",
+ ".ldoc/helmets.luadoc",
+ ".ldoc/chestplates.luadoc",
+ ".ldoc/leggings.luadoc",
+ ".ldoc/boots.luadoc",
+ ".ldoc/shields.luadoc",
+ ".ldoc/crafting.luadoc",
+}
+
+
+new_type("setting", "Settings")
+new_type("armor", "Armors")
+new_type("craft", "Craft Recipes")
+
+alias("helmet", "armor")
+alias("chestplate", "armor")
+alias("leggings", "armor")
+alias("boots", "armor")
+alias("shield", "armor")
+alias("grp", "group")
+
+-- function declarations
+local format_text
+local format_group
+
+custom_tags = {
+ -- settings
+ {
+ "settype",
+ title = "Type",
+ hidden = true,
+ },
+ {
+ "min",
+ title = "Minimum Value",
+ hidden = true,
+ },
+ {
+ "max",
+ title = "Maximum Value",
+ hidden = true,
+ },
+ {
+ "default",
+ title = "Default Value",
+ hidden = true,
+ },
+ -- craft items/tools
+ {
+ -- specify image basename only
+ "img",
+ title = "Image",
+ format = function(value)
+ local img = ""
+ end,
+ },
+ {
+ -- specify full (relative or absolute) image path
+ "image",
+ title = "Image",
+ format = function(value)
+ return ""
+ end,
+ },
+ {
+ "group",
+ title = "Groups",
+ format = function(value)
+ return format_group(value)
+ end,
+ },
+ {
+ "armorgrp",
+ title = "Armor Groups",
+ format = function(value)
+ return format_group(value)
+ end,
+ },
+ {
+ "damagegrp",
+ title = "Damage Groups",
+ format = function(value)
+ return format_group(value)
+ end,
+ },
+}
+
+
+if string then
+ string.trim = function(st, delim)
+ if not delim then
+ delim = " "
+ end
+
+ while string.find(st, delim) == 1 do
+ st = st:sub(2)
+ end
+
+ while string.sub(st, string.len(st)) == delim do
+ st = st:sub(1, string.len(st)-1)
+ end
+
+ return st
+ end
+
+ string.split = function(st, delim)
+ local list = {}
+
+ local idx = string.find(st, delim)
+ while idx do
+ table.insert(list, st:sub(1, idx-1))
+ st = st:sub(idx+1)
+ idx = string.find(st, delim)
+ end
+ -- add remaining item
+ table.insert(list, st)
+
+ return list
+ end
+end
+
+if table then
+ if not table.copy then
+ table.copy = function(orig_table)
+ local new_table = {}
+ for k, v in pairs(orig_table) do
+ new_table[k] = v
+ end
+
+ return new_table
+ end
+ end
+end
+
+format_text = function(text, flags)
+ local ret = "<"
+ local ttype = "span"
+ if flags.code then
+ ttype = "code"
+ end
+
+ ret = ret .. ttype .. " style=\""
+
+ if flags.size then
+ ret = ret .. "font-size:" .. flags.size .. ";"
+ end
+ if flags.mono then
+ ret = ret .. "font-family:monospace;"
+ end
+ if flags.italic then
+ ret = ret .. "font-style:italic;"
+ end
+ if flags.bold then
+ ret = ret .. "font-weight:bold;"
+ end
+ if flags.color then
+ ret = ret .. "color:" .. flags.color .. ";"
+ end
+ if flags.bgcolor then
+ ret = ret .. "background-color:" .. flags.bgcolor .. ";"
+ end
+
+ ret = ret .. "\">" .. text .. "" .. ttype .. ">"
+
+ return ret
+end
+
+format_group = function(text)
+ if string then
+ local idx, k, v = string.find(text, " ")
+ if idx then
+ text = format_text(string.sub(text, 1, idx-1) .. ": ", {mono=true, color="darkgreen"})
+ .. string.sub(text, idx)
+ end
+ end
+
+ return text
+end
+
+
+local function format_setting_tag(desc, value)
+ return "\n- `" .. desc .. ":` `" .. value .. "`"
+end
+
+
+local registered = {
+ settings = {},
+}
+
+local function setting_handler(item)
+ if not ipairs or not type then
+ return item
+ end
+
+ local tags = {
+ {"settype", "type"},
+ {"default"},
+ {"min", "minimum value"},
+ {"max", "maximum value"},
+ }
+
+ local def = {
+ ["settype"] = format_setting_tag("type", "string"),
+ }
+
+ for _, t in ipairs(tags) do
+ local name = t[1]
+ local desc = t[2]
+ if not desc then desc = name end
+
+ local value = item.tags[name]
+ if type(value) == "table" then
+ if #value > 1 then
+ local msg = item.file.filename .. " (line " .. item.lineno
+ .. "): multiple instances of tag \"" .. name .. "\" found"
+ if error then
+ error(msg)
+ elseif print then
+ print("WARNING: " .. msg)
+ end
+ end
+
+ if value[1] then
+ def[name] = format_setting_tag(desc, value[1])
+ end
+ end
+ end
+
+ item.description = item.description .. "\n\n**Definition:**\n" .. def.settype
+ for _, t in ipairs({def.default, def.min, def.max}) do
+ if t then
+ item.description = item.description .. t
+ end
+ end
+
+ registered.settings[item.name] = true
+
+ return item
+end
+
+function custom_display_name_handler(item, default_handler)
+ if item.type == "setting" then
+ -- avoid parsing again
+ if not registered.settings[item.name] then
+ item = setting_handler(item)
+ end
+ elseif item.type == "armor" and string then
+ -- HACK: not sure why "shields:" is being trimmed from item name
+ if string.find(item.name, "shield_") == 1 then
+ item.name = "shields:" .. item.name
+ end
+ end
+
+ if item then
+ return default_handler(item)
+ end
+end
+
+
+local custom_see_links = {
+ ["ObjectRef"] = "https://minetest.gitlab.io/minetest/class-reference/#objectref",
+ ["PlayerMetaRef"] = "https://minetest.gitlab.io/minetest/class-reference/#playermetaref",
+ ["ItemDef"] = "https://minetest.gitlab.io/minetest/definition-tables/#item-definition",
+ ["ItemStack"] = "https://minetest.gitlab.io/minetest/class-reference/#itemstack",
+ ["groups"] = "https://minetest.gitlab.io/minetest/groups/",
+ ["entity_damage_mechanism"] = "https://minetest.gitlab.io/minetest/entity-damage-mechanism/",
+ ["vector"] = "https://minetest.gitlab.io/minetest/representations-of-simple-things/#positionvector",
+}
+
+local function format_custom_see(name, section)
+ local url = custom_see_links[name]
+ if not url then
+ url = ""
+ end
+
+ if not name then
+ name = ""
+ end
+
+ return name, url
+end
+
+custom_see_handler("^(ObjectRef)$", function(name, section)
+ return format_custom_see(name, section)
+end)
+
+custom_see_handler("^(PlayerMetaRef)$", function(name, section)
+ return format_custom_see(name, section)
+end)
+
+custom_see_handler("^(ItemDef)$", function(name, section)
+ return format_custom_see(name, section)
+end)
+
+custom_see_handler("^(groups)$", function(name, section)
+ return format_custom_see(name, section)
+end)
+
+custom_see_handler("^(entity_damage_mechanism)$", function(name, section)
+ return format_custom_see(name, section)
+end)
+
+custom_see_handler("^(ItemStack)$", function(name, section)
+ return format_custom_see(name, section)
+end)
+
+custom_see_handler("^(vector)$", function(name, section)
+ return name, "https://minetest.gitlab.io/minetest/representations-of-simple-things/#positionvector"
+end)
diff --git a/.ldoc/ldoc.css b/.ldoc/ldoc.css
new file mode 100644
index 0000000..1fa3a99
--- /dev/null
+++ b/.ldoc/ldoc.css
@@ -0,0 +1,304 @@
+/* BEGIN RESET
+
+Copyright (c) 2010, Yahoo! Inc. All rights reserved.
+Code licensed under the BSD License:
+http://developer.yahoo.com/yui/license.html
+version: 2.8.2r1
+*/
+html {
+ color: #000;
+ background: #FFF;
+}
+body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,code,form,fieldset,legend,input,button,textarea,p,blockquote,th,td {
+ margin: 0;
+ padding: 0;
+}
+table {
+ border-collapse: collapse;
+ border-spacing: 0;
+}
+fieldset,img {
+ border: 0;
+}
+address,caption,cite,code,dfn,em,strong,th,var,optgroup {
+ font-style: inherit;
+ font-weight: inherit;
+}
+del,ins {
+ text-decoration: none;
+}
+li {
+ margin-left: 20px;
+}
+caption,th {
+ text-align: left;
+}
+h1,h2,h3,h4,h5,h6 {
+ font-size: 100%;
+ font-weight: bold;
+}
+q:before,q:after {
+ content: '';
+}
+abbr,acronym {
+ border: 0;
+ font-variant: normal;
+}
+sup {
+ vertical-align: baseline;
+}
+sub {
+ vertical-align: baseline;
+}
+legend {
+ color: #000;
+}
+input,button,textarea,select,optgroup,option {
+ font-family: inherit;
+ font-size: inherit;
+ font-style: inherit;
+ font-weight: inherit;
+}
+input,button,textarea,select {*font-size:100%;
+}
+/* END RESET */
+
+body {
+ margin-left: 1em;
+ margin-right: 1em;
+ font-family: arial, helvetica, geneva, sans-serif;
+ background-color: #ffffff; margin: 0px;
+}
+
+code, tt { font-family: monospace; font-size: 1.1em; }
+span.parameter { font-family:monospace; }
+span.parameter:after { content:":"; }
+span.types:before { content:"("; }
+span.types:after { content:")"; }
+.type { font-weight: bold; font-style:italic }
+
+body, p, td, th { font-size: .95em; line-height: 1.2em;}
+
+p, ul { margin: 10px 0 0 0px;}
+
+strong { font-weight: bold;}
+
+em { font-style: italic;}
+
+h1 {
+ font-size: 1.5em;
+ margin: 20px 0 20px 0;
+}
+h2, h3, h4 { margin: 15px 0 10px 0; }
+h2 { font-size: 1.25em; }
+h3 { font-size: 1.15em; }
+h4 { font-size: 1.06em; }
+
+a:link { font-weight: bold; color: #004080; text-decoration: none; }
+a:visited { font-weight: bold; color: #006699; text-decoration: none; }
+a:link:hover { text-decoration: underline; }
+
+hr {
+ color:#cccccc;
+ background: #00007f;
+ height: 1px;
+}
+
+blockquote { margin-left: 3em; }
+
+ul { list-style-type: disc; }
+
+p.name {
+ font-family: "Andale Mono", monospace;
+ padding-top: 1em;
+}
+
+pre {
+ background-color: rgb(245, 245, 245);
+ border: 1px solid #C0C0C0; /* silver */
+ padding: 10px;
+ margin: 10px 0 10px 0;
+ overflow: auto;
+ font-family: "Andale Mono", monospace;
+}
+
+pre.example {
+ font-size: .85em;
+}
+
+table.index { border: 1px #00007f; }
+table.index td { text-align: left; vertical-align: top; }
+
+#container {
+ margin-left: 1em;
+ margin-right: 1em;
+ background-color: #f0f0f0;
+}
+
+#product {
+ text-align: center;
+ border-bottom: 1px solid #cccccc;
+ background-color: #ffffff;
+}
+
+#product big {
+ font-size: 2em;
+}
+
+#main {
+ background-color: #f0f0f0;
+ border-left: 2px solid #cccccc;
+}
+
+#navigation {
+ float: left;
+ width: 14em;
+ vertical-align: top;
+ background-color: #f0f0f0;
+ overflow: visible;
+ position: fixed;
+}
+
+#navigation h2 {
+ background-color:#e7e7e7;
+ font-size:1.1em;
+ color:#000000;
+ text-align: left;
+ padding:0.2em;
+ border-top:1px solid #dddddd;
+ border-bottom:1px solid #dddddd;
+}
+
+#navigation ul
+{
+ font-size:1em;
+ list-style-type: none;
+ margin: 1px 1px 10px 1px;
+}
+
+#navigation li {
+ text-indent: -1em;
+ display: block;
+ margin: 3px 0px 0px 22px;
+}
+
+#navigation li li a {
+ margin: 0px 3px 0px -1em;
+}
+
+#content {
+ margin-left: 14em;
+ padding: 1em;
+ width: 700px;
+ border-left: 2px solid #cccccc;
+ border-right: 2px solid #cccccc;
+ background-color: #ffffff;
+}
+
+#about {
+ clear: both;
+ padding: 5px;
+ border-top: 2px solid #cccccc;
+ background-color: #ffffff;
+}
+
+@media print {
+ body {
+ font: 12pt "Times New Roman", "TimeNR", Times, serif;
+ }
+ a { font-weight: bold; color: #004080; text-decoration: underline; }
+
+ #main {
+ background-color: #ffffff;
+ border-left: 0px;
+ }
+
+ #container {
+ margin-left: 2%;
+ margin-right: 2%;
+ background-color: #ffffff;
+ }
+
+ #content {
+ padding: 1em;
+ background-color: #ffffff;
+ }
+
+ #navigation {
+ display: none;
+ }
+ pre.example {
+ font-family: "Andale Mono", monospace;
+ font-size: 10pt;
+ page-break-inside: avoid;
+ }
+}
+
+table.module_list {
+ border-width: 1px;
+ border-style: solid;
+ border-color: #cccccc;
+ border-collapse: collapse;
+}
+table.module_list td {
+ border-width: 1px;
+ padding: 3px;
+ border-style: solid;
+ border-color: #cccccc;
+}
+table.module_list td.name { background-color: #f0f0f0; min-width: 200px; }
+table.module_list td.summary { width: 100%; }
+
+
+table.function_list {
+ border-width: 1px;
+ border-style: solid;
+ border-color: #cccccc;
+ border-collapse: collapse;
+}
+table.function_list td {
+ border-width: 1px;
+ padding: 3px;
+ border-style: solid;
+ border-color: #cccccc;
+}
+table.function_list td.name { background-color: #f0f0f0; min-width: 200px; }
+table.function_list td.summary { width: 100%; }
+
+ul.nowrap {
+ overflow:auto;
+ white-space:nowrap;
+}
+
+dl.table dt, dl.function dt {border-top: 1px solid #ccc; padding-top: 1em;}
+dl.table dd, dl.function dd {padding-bottom: 1em; margin: 10px 0 0 20px;}
+dl.table h3, dl.function h3 {font-size: .95em;}
+
+/* stop sublists from having initial vertical space */
+ul ul { margin-top: 0px; }
+ol ul { margin-top: 0px; }
+ol ol { margin-top: 0px; }
+ul ol { margin-top: 0px; }
+
+/* make the target distinct; helps when we're navigating to a function */
+a:target + * {
+ background-color: #FF9;
+}
+
+
+/* styles for prettification of source */
+pre .comment { color: #558817; }
+pre .constant { color: #a8660d; }
+pre .escape { color: #844631; }
+pre .keyword { color: #aa5050; font-weight: bold; }
+pre .library { color: #0e7c6b; }
+pre .marker { color: #512b1e; background: #fedc56; font-weight: bold; }
+pre .string { color: #8080ff; }
+pre .number { color: #f8660d; }
+pre .operator { color: #2239a8; font-weight: bold; }
+pre .preprocessor, pre .prepro { color: #a33243; }
+pre .global { color: #800080; }
+pre .user-keyword { color: #800080; }
+pre .prompt { color: #558817; }
+pre .url { color: #272fc2; text-decoration: underline; }
+
diff --git a/.ldoc/parse_crafts.py b/.ldoc/parse_crafts.py
new file mode 100755
index 0000000..ea0af47
--- /dev/null
+++ b/.ldoc/parse_crafts.py
@@ -0,0 +1,46 @@
+#!/usr/bin/env python
+
+# This script will parse source files for craft recipes.
+
+import sys, os, codecs, errno
+
+
+path = os.path.realpath(__file__)
+script = os.path.basename(path)
+d_root = os.path.dirname(os.path.dirname(path))
+d_ldoc = os.path.join(d_root, ".ldoc")
+
+craftfile = os.path.realpath(os.path.join(d_root, "3d_armor/armor.lua"))
+if not os.path.isfile(craftfile):
+ print("ERROR: craft file does not exist for parsing: {}".format(craftfile))
+ sys.exit(errnor.ENOENT)
+
+buffer = codecs.open(craftfile, "r", "utf-8")
+if not buffer:
+ print("ERROR: could not open file for reading: {}".format(craftfile))
+ sys.exit(errno.EIO)
+
+data_in = buffer.read()
+buffer.close()
+
+craft = ""
+
+data_in = data_in.replace("\r\n", "\n").replace("\r", "\n")
+for sect in data_in.split("\n---"):
+ if "@craft armor" in sect:
+ sect = "---{}".format(sect)
+ for li in sect.split("\n"):
+ if li.startswith("--"):
+ craft = "{}\n{}".format(craft, li)
+
+outfile = os.path.join(d_ldoc, "crafting.luadoc")
+
+buffer = codecs.open(outfile, "w", "utf-8")
+if not buffer:
+ print("ERROR: could not open file for writing: {}".format(outfile))
+ sys.exit(errno.EIO)
+
+buffer.write("\n--- 3D Armor Crafting\n--\n-- @topic crafting\n\n{}\n".format(craft))
+buffer.close()
+
+print("crafts exported to\t{}".format(outfile))
diff --git a/.ldoc/parse_settings.py b/.ldoc/parse_settings.py
new file mode 100755
index 0000000..7e11ead
--- /dev/null
+++ b/.ldoc/parse_settings.py
@@ -0,0 +1,118 @@
+#!/usr/bin/env python
+
+# This script will format "settingtypes.txt" file found at the root
+# of 3d_armor modpack into a format readable by LDoc.
+
+import sys, os, errno, codecs
+
+
+path = os.path.realpath(__file__)
+script = os.path.basename(path)
+d_root = os.path.dirname(os.path.dirname(path))
+d_ldoc = os.path.join(d_root, ".ldoc")
+f_settings = os.path.join(d_root, "settingtypes.txt")
+
+if not os.path.isfile(f_settings):
+ print("settingtypes.txt does not exist")
+ sys.exit(errno.ENOENT)
+
+i_stream = codecs.open(f_settings, "r", "utf-8")
+data_in = i_stream.read()
+i_stream.close()
+
+data_in = data_in.replace("\r", "")
+
+sets = data_in.split("\n\n")
+
+for idx in reversed(range(len(sets))):
+ set = sets[idx]
+ lines = set.split("\n")
+ for idx2 in reversed(range(len(lines))):
+ li = lines[idx2].strip(" \t")
+ if li == "" or li[0] == "[":
+ lines.pop(idx2)
+
+ if len(lines) == 0:
+ sets.pop(idx)
+ else:
+ sets[idx] = "\n".join(lines)
+
+filtered = []
+
+for set in sets:
+ comment = False
+ lines = set.split("\n")
+ new_lines = []
+ for li in lines:
+ if li[0] == "#":
+ new_lines.append(li)
+ else:
+ new_lines.append(li)
+ filtered.append("\n".join(new_lines))
+ new_lines = []
+
+settings = []
+
+def parse_setting(set):
+ desc = []
+ setting = summary = stype = sdefault = soptions = None
+
+ for li in set.split("\n"):
+ if li[0] == "#":
+ desc.append("-- {}".format(li.lstrip(" #")))
+ else:
+ setting = li.split(" ")[0]
+ summary = li.split(")")[0].split("(")[-1]
+ li = li.split(")")[-1].strip()
+ rem = li.split(" ")
+ stype = rem[0]
+ rem.pop(0)
+
+ if len(rem) > 0:
+ sdefault = rem[0]
+ rem.pop(0)
+
+ if len(rem) > 0:
+ soptions = " ".join(rem)
+
+ if not setting:
+ return
+
+ st = "---"
+ if summary:
+ if summary[-1] != ".":
+ summary = "{}.".format(summary)
+ st = "{} {}".format(st, summary)
+
+ st = "{}\n--".format(st)
+
+ if len(desc) > 0:
+ st = "{}\n{}\n--".format(st, "\n".join(desc))
+
+ st = "{}\n-- @setting {}".format(st, setting)
+
+ if stype:
+ st = "{}\n-- @settype {}".format(st, stype)
+
+ if sdefault:
+ st = "{}\n-- @default {}".format(st, sdefault)
+
+ # TODO: add options
+
+ settings.append(st)
+
+for f in filtered:
+ parse_setting(f)
+
+outfile = os.path.join(d_ldoc, "settings.luadoc")
+data_out = "\n--- 3D Armor Settings\n--\n-- @topic settings\n\n\n{}\n".format("\n\n".join(settings))
+
+o_stream = codecs.open(outfile, "w", "utf-8")
+if not o_stream:
+ print("ERROR: could not open file for writing: {}".format(outfile))
+ sys.exit(errno.EIO)
+
+o_stream.write(data_out)
+o_stream.close()
+
+print("settings exported to\t{}".format(outfile))
diff --git a/.ldoc/parse_src.py b/.ldoc/parse_src.py
new file mode 100755
index 0000000..32c9c2d
--- /dev/null
+++ b/.ldoc/parse_src.py
@@ -0,0 +1,90 @@
+#!/usr/bin/env python
+
+# This script will parse source files for docstring.
+
+import os, codecs
+
+
+path = os.path.realpath(__file__)
+script = os.path.basename(path)
+d_root = os.path.dirname(os.path.dirname(path))
+d_ldoc = os.path.join(d_root, ".ldoc")
+
+
+armor_types = {
+ "armor": {"topic": "Armors", "values": []},
+ "helmet": {"topic": "Helmets", "values": []},
+ "chestplate": {"topic": "Chestplates", "values": []},
+ "leggings": {"topic": "Leggings", "values": []},
+ "boots": {"topic": "Boots", "values": []},
+ "shield": {"topic": "Shields", "values": []},
+}
+
+def parse_file(f):
+ buffer = codecs.open(f, "r", "utf-8")
+ if not buffer:
+ print("ERROR: could not open file for reading: {}".format(f))
+ return
+
+ data_in = buffer.read()
+ buffer.close()
+
+ # format to LF (Unix)
+ data_in = data_in.replace("\r\n", "\n").replace("\r", "\n")
+
+ current_item = []
+ item_type = None
+ new_item = False
+ for li in data_in.split("\n"):
+ li = li.strip()
+ if li.startswith("---"):
+ new_item = True
+ elif not li.startswith("--"):
+ new_item = False
+
+ if new_item:
+ current_item.append(li)
+ if not item_type:
+ for a_type in armor_types:
+ if "@{} ".format(a_type) in li:
+ item_type = a_type
+ break
+ elif item_type and len(current_item):
+ armor_types[item_type]["values"].append("\n".join(current_item))
+ item_type = None
+ current_item = []
+ else:
+ current_item = []
+
+to_parse = []
+
+for obj in os.listdir(d_root):
+ fullpath = os.path.join(d_root, obj)
+ if not obj.startswith(".") and os.path.isdir(fullpath):
+ for root, dirs, files in os.walk(fullpath):
+ for f in files:
+ if f.endswith(".lua"):
+ to_parse.append(os.path.join(root, f))
+
+for p in to_parse:
+ if not os.path.isfile(p):
+ print("ERROR: {} is not a file".format(p))
+ else:
+ parse_file(p)
+
+for t in armor_types:
+ topic = armor_types[t]["topic"]
+ items = armor_types[t]["values"]
+
+ if len(items):
+ outfile = os.path.join(d_ldoc, "{}.luadoc".format(topic.lower()))
+
+ buffer = codecs.open(outfile, "w", "utf-8")
+ if not buffer:
+ print("ERROR: could not open file for writing: {}".format(outfile))
+ continue
+
+ buffer.write("\n--- 3D Armor {}\n--\n-- @topic {}\n\n\n{}\n".format(topic, topic.lower(), "\n\n".join(items)))
+ buffer.close()
+
+ print("{} exported to\t{}".format(topic.lower(), outfile))
diff --git a/3d_armor/README.md b/3d_armor/README.md
index 050eb61..dd87d81 100644
--- a/3d_armor/README.md
+++ b/3d_armor/README.md
@@ -396,6 +396,8 @@ If all of the above were made of material "wood" the player would recieve an ***
## Armor Functions
+See also: [API Reference](https://minetest-mods.github.io/3d_armor/reference/)
+
### armor set_player_armor
armor:set_player_armor(player)
diff --git a/3d_armor/api.lua b/3d_armor/api.lua
index 7b7e4eb..fd0a50a 100644
--- a/3d_armor/api.lua
+++ b/3d_armor/api.lua
@@ -1,3 +1,82 @@
+
+--- 3D Armor API
+--
+-- @topic api
+
+
+local transparent_armor = minetest.settings:get_bool("armor_transparent", false)
+
+
+--- Tables
+--
+-- @section tables
+
+--- Armor definition table used for registering armor.
+--
+-- @table ArmorDef
+-- @tfield string description Human-readable name/description.
+-- @tfield string inventory_image Image filename used for icon.
+-- @tfield table groups See: `ArmorDef.groups`
+-- @tfield table armor_groups See: `ArmorDef.armor_groups`
+-- @tfield table damage_groups See: `ArmorDef.damage_groups`
+-- @see ItemDef
+-- @usage local def = {
+-- description = "Wood Helmet",
+-- inventory_image = "3d_armor_inv_helmet_wood.png",
+-- groups = {armor_head=1, armor_heal=0, armor_use=2000, flammable=1},
+-- armor_groups = {fleshy=5},
+-- damage_groups = {cracky=3, snappy=2, choppy=3, crumbly=2, level=1},
+-- }
+
+--- Groups table.
+--
+-- General groups defining item behavior.
+--
+-- Some commonly used groups: ***armor\_<type>***, ***armor\_heal***, ***armor\_use***
+--
+-- @table ArmorDef.groups
+-- @tfield int armor_type The armor type. "head", "torso", "hands", "shield", etc.
+-- (**Note:** replace "type" with actual type).
+-- @tfield int armor_heal Healing value of armor when equipped.
+-- @tfield int armor_use Amount of uses/damage before armor "breaks".
+-- @see groups
+-- @usage groups = {
+-- armor_head = 1,
+-- armor_heal = 5,
+-- armor_use = 2000,
+-- flammable = 1,
+-- }
+
+--- Armor groups table.
+--
+-- Groups that this item is effective against when taking damage.
+--
+-- Some commonly used groups: ***fleshy***
+--
+-- @table ArmorDef.armor_groups
+-- @usage armor_groups = {
+-- fleshy = 5,
+-- }
+
+--- Damage groups table.
+--
+-- Groups that this item is effective on when used as a weapon/tool.
+--
+-- Some commonly used groups: ***cracky***, ***snappy***, ***choppy***, ***crumbly***, ***level***
+--
+-- @table ArmorDef.damage_groups
+-- @see entity_damage_mechanism
+-- @usage damage_groups = {
+-- cracky = 3,
+-- snappy = 2,
+-- choppy = 3,
+-- crumbly = 2,
+-- level = 1,
+-- }
+
+--- @section end
+
+
-- support for i18n
local S = minetest.get_translator(minetest.get_current_modname())
@@ -105,8 +184,23 @@ armor.config = {
punch_damage = true,
}
--- Armor Registration
+--- Methods
+--
+-- @section methods
+
+--- Registers a new armor item.
+--
+-- @function armor:register_armor
+-- @tparam string name Armor item technical name (ex: "3d\_armor:helmet\_gold").
+-- @tparam ArmorDef def Armor definition table.
+-- @usage armor:register_armor("3d_armor:helmet_wood", {
+-- description = "Wood Helmet",
+-- inventory_image = "3d_armor_inv_helmet_wood.png",
+-- groups = {armor_head=1, armor_heal=0, armor_use=2000, flammable=1},
+-- armor_groups = {fleshy=5},
+-- damage_groups = {cracky=3, snappy=2, choppy=3, crumbly=2, level=1},
+-- })
armor.register_armor = function(self, name, def)
def.on_secondary_use = function(itemstack, player)
return armor:equip(player, itemstack)
@@ -132,6 +226,11 @@ armor.register_armor = function(self, name, def)
minetest.register_tool(name, def)
end
+--- Registers a new armor group.
+--
+-- @function armor:register_armor_group
+-- @tparam string group Group ID.
+-- @tparam int base Base armor value.
armor.register_armor_group = function(self, group, base)
base = base or 100
self.registered_groups[group] = base
@@ -140,38 +239,92 @@ armor.register_armor_group = function(self, group, base)
end
end
--- Armor callbacks
+--- Armor Callbacks Registration
+--
+-- @section callbacks
+--- Registers a callback for when player visuals are update.
+--
+-- @function armor:register_on_update
+-- @tparam function func Function to be executed.
+-- @see armor:update_player_visuals
+-- @usage armor:register_on_update(function(player, index, stack)
+-- -- code to execute
+-- end)
armor.register_on_update = function(self, func)
if type(func) == "function" then
table.insert(self.registered_callbacks.on_update, func)
end
end
+--- Registers a callback for when armor is equipped.
+--
+-- @function armor:register_on_equip
+-- @tparam function func Function to be executed.
+-- @usage armor:register_on_equip(function(player, index, stack)
+-- -- code to execute
+-- end)
armor.register_on_equip = function(self, func)
if type(func) == "function" then
table.insert(self.registered_callbacks.on_equip, func)
end
end
+--- Registers a callback for when armor is unequipped.
+--
+-- @function armor:register_on_unequip
+-- @tparam function func Function to be executed.
+-- @usage armor:register_on_unequip(function(player, index, stack)
+-- -- code to execute
+-- end)
armor.register_on_unequip = function(self, func)
if type(func) == "function" then
table.insert(self.registered_callbacks.on_unequip, func)
end
end
+--- Registers a callback for when armor is damaged.
+--
+-- @function armor:register_on_damage
+-- @tparam function func Function to be executed.
+-- @see armor:damage
+-- @usage armor:register_on_damage(function(player, index, stack)
+-- -- code to execute
+-- end)
armor.register_on_damage = function(self, func)
if type(func) == "function" then
table.insert(self.registered_callbacks.on_damage, func)
end
end
+--- Registers a callback for when armor is destroyed.
+--
+-- @function armor:register_on_destroy
+-- @tparam function func Function to be executed.
+-- @see armor:damage
+-- @usage armor:register_on_destroy(function(player, index, stack)
+-- -- code to execute
+-- end)
armor.register_on_destroy = function(self, func)
if type(func) == "function" then
table.insert(self.registered_callbacks.on_destroy, func)
end
end
+--- @section end
+
+
+--- Methods
+--
+-- @section methods
+
+--- Runs callbacks.
+--
+-- @function armor:run_callbacks
+-- @tparam function callback Function to execute.
+-- @tparam ObjectRef player First parameter passed to callback.
+-- @tparam int index Second parameter passed to callback.
+-- @tparam ItemStack stack Callback owner.
armor.run_callbacks = function(self, callback, player, index, stack)
if stack then
local def = stack:get_definition() or {}
@@ -187,6 +340,10 @@ armor.run_callbacks = function(self, callback, player, index, stack)
end
end
+--- Updates visuals.
+--
+-- @function armor:update_player_visuals
+-- @tparam ObjectRef player
armor.update_player_visuals = function(self, player)
if not player then
return
@@ -202,10 +359,10 @@ armor.update_player_visuals = function(self, player)
self:run_callbacks("on_update", player)
end
-
--- armor is not visible on player model if enabled
-local transparent_armor = minetest.settings:get_bool("armor_transparent", false)
-
+--- Sets player's armor attributes.
+--
+-- @function armor:set_player_armor
+-- @tparam ObjectRef player
armor.set_player_armor = function(self, player)
local name, armor_inv = self:get_valid_player(player, "[set_player_armor]")
if not name then
@@ -366,6 +523,13 @@ armor.set_player_armor = function(self, player)
self:update_player_visuals(player)
end
+--- Action when armor is punched.
+--
+-- @function armor:punch
+-- @tparam ObjectRef player Player wearing the armor.
+-- @tparam ObjectRef hitter Entity attacking player.
+-- @tparam[opt] int time_from_last_punch Time in seconds since last punch action.
+-- @tparam[opt] table tool_capabilities See `entity_damage_mechanism`.
armor.punch = function(self, player, hitter, time_from_last_punch, tool_capabilities)
local name, armor_inv = self:get_valid_player(player, "[punch]")
if not name then
@@ -451,6 +615,13 @@ armor.punch = function(self, player, hitter, time_from_last_punch, tool_capabili
self.def[name].count = count
end
+--- Action when armor is damaged.
+--
+-- @function armor:damage
+-- @tparam ObjectRef player
+-- @tparam int index Inventory index where armor is equipped.
+-- @tparam ItemStack stack Armor item receiving damaged.
+-- @tparam int use Amount of wear to add to armor item.
armor.damage = function(self, player, index, stack, use)
local old_stack = ItemStack(stack)
local worn_armor = armor:get_weared_armor_elements(player)
@@ -469,6 +640,11 @@ armor.damage = function(self, player, index, stack, use)
end
end
+--- Get elements of equipped armor.
+--
+-- @function armor:get_weared_armor_elements
+-- @tparam ObjectRef player
+-- @treturn table List of equipped armors.
armor.get_weared_armor_elements = function(self, player)
local name, inv = self:get_valid_player(player, "[get_weared_armor]")
local weared_armor = {}
@@ -485,6 +661,12 @@ armor.get_weared_armor_elements = function(self, player)
return weared_armor
end
+--- Equips a piece of armor to a player.
+--
+-- @function armor:equip
+-- @tparam ObjectRef player Player to whom item is equipped.
+-- @tparam ItemStack itemstack Armor item to be equipped.
+-- @treturn ItemStack Leftover item stack.
armor.equip = function(self, player, itemstack)
local name, armor_inv = self:get_valid_player(player, "[equip]")
local armor_element = self:get_element(itemstack:get_name())
@@ -509,6 +691,12 @@ armor.equip = function(self, player, itemstack)
return itemstack
end
+--- Unequips a piece of armor from a player.
+--
+-- @function armor:unequip
+-- @tparam ObjectRef player Player from whom item is removed.
+-- @tparam string armor_element Armor type identifier associated with the item
+-- to be removed ("head", "torso", "hands", "shield", "legs", "feet", etc.).
armor.unequip = function(self, player, armor_element)
local name, armor_inv = self:get_valid_player(player, "[unequip]")
if not name then
@@ -534,6 +722,10 @@ armor.unequip = function(self, player, armor_element)
end
end
+--- Removes all armor worn by player.
+--
+-- @function armor:remove_all
+-- @tparam ObjectRef player
armor.remove_all = function(self, player)
local name, inv = self:get_valid_player(player, "[remove_all]")
if not name then
@@ -546,6 +738,11 @@ end
local skin_mod
+--- Retrieves player's current skin.
+--
+-- @function armor:get_player_skin
+-- @tparam string name Player name.
+-- @treturn string Skin filename.
armor.get_player_skin = function(self, name)
if (skin_mod == "skins" or skin_mod == "simple_skins") and skins.skins[name] then
return skins.skins[name]..".png"
@@ -557,6 +754,10 @@ armor.get_player_skin = function(self, name)
return armor.default_skin..".png"
end
+--- Updates skin.
+--
+-- @function armor:update_skin
+-- @tparam string name Player name.
armor.update_skin = function(self, name)
minetest.after(0, function()
local pplayer = minetest.get_player_by_name(name)
@@ -567,10 +768,19 @@ armor.update_skin = function(self, name)
end)
end
+--- Adds preview for armor inventory.
+--
+-- @function armor:add_preview
+-- @tparam string preview Preview image filename.
armor.add_preview = function(self, preview)
skin_previews[preview] = true
end
+--- Retrieves preview for armor inventory.
+--
+-- @function armor:get_preview
+-- @tparam string name Player name.
+-- @treturn string Preview image filename.
armor.get_preview = function(self, name)
local preview = string.gsub(armor:get_player_skin(name), ".png", "_preview.png")
if skin_previews[preview] then
@@ -579,6 +789,12 @@ armor.get_preview = function(self, name)
return "character_preview.png"
end
+--- Retrieves armor formspec.
+--
+-- @function armor:get_armor_formspec
+-- @tparam string name Player name.
+-- @tparam[opt] bool listring Use `listring` formspec element (default: `false`).
+-- @treturn string Formspec formatted string.
armor.get_armor_formspec = function(self, name, listring)
if armor.def[name].init_time == 0 then
return "label[0,0;Armor not initialized!]"
@@ -601,6 +817,11 @@ armor.get_armor_formspec = function(self, name, listring)
return formspec
end
+--- Retrieves element.
+--
+-- @function armor:get_element
+-- @tparam string item_name
+-- @return Armor element.
armor.get_element = function(self, item_name)
for _, element in pairs(armor.elements) do
if minetest.get_item_group(item_name, "armor_"..element) > 0 then
@@ -609,6 +830,11 @@ armor.get_element = function(self, item_name)
end
end
+--- Serializes armor inventory.
+--
+-- @function armor:serialize_inventory_list
+-- @tparam table list Inventory contents.
+-- @treturn string
armor.serialize_inventory_list = function(self, list)
local list_table = {}
for _, stack in ipairs(list) do
@@ -617,6 +843,11 @@ armor.serialize_inventory_list = function(self, list)
return minetest.serialize(list_table)
end
+--- Deserializes armor inventory.
+--
+-- @function armor:deserialize_inventory_list
+-- @tparam string list_string Serialized inventory contents.
+-- @treturn table
armor.deserialize_inventory_list = function(self, list_string)
local list_table = minetest.deserialize(list_string)
local list = {}
@@ -626,6 +857,11 @@ armor.deserialize_inventory_list = function(self, list_string)
return list
end
+--- Loads armor inventory.
+--
+-- @function armor:load_armor_inventory
+-- @tparam ObjectRef player
+-- @treturn bool
armor.load_armor_inventory = function(self, player)
local _, inv = self:get_valid_player(player, "[load_armor_inventory]")
if inv then
@@ -639,6 +875,12 @@ armor.load_armor_inventory = function(self, player)
end
end
+--- Saves armor inventory.
+--
+-- Inventory is stored in `PlayerMetaRef` string "3d\_armor\_inventory".
+--
+-- @function armor:save_armor_inventory
+-- @tparam ObjectRef player
armor.save_armor_inventory = function(self, player)
local _, inv = self:get_valid_player(player, "[save_armor_inventory]")
if inv then
@@ -648,10 +890,22 @@ armor.save_armor_inventory = function(self, player)
end
end
+--- Updates inventory.
+--
+-- DEPRECATED: Legacy inventory support.
+--
+-- @function armor:update_inventory
+-- @param player
armor.update_inventory = function(self, player)
-- DEPRECATED: Legacy inventory support
end
+--- Sets inventory stack.
+--
+-- @function armor:set_inventory_stack
+-- @tparam ObjectRef player
+-- @tparam int i Armor inventory index.
+-- @tparam ItemStack stack Armor item.
armor.set_inventory_stack = function(self, player, i, stack)
local _, inv = self:get_valid_player(player, "[set_inventory_stack]")
if inv then
@@ -660,6 +914,13 @@ armor.set_inventory_stack = function(self, player, i, stack)
end
end
+--- Checks for a player that can use armor.
+--
+-- @function armor:get_valid_player
+-- @tparam ObjectRef player
+-- @tparam string msg Additional info for log messages.
+-- @treturn list Player name & armor inventory.
+-- @usage local name, inv = armor:get_valid_player(player, "[equip]")
armor.get_valid_player = function(self, player, msg)
msg = msg or ""
if not player then
@@ -681,6 +942,10 @@ armor.get_valid_player = function(self, player, msg)
return name, inv
end
+--- Drops armor item at given position.
+--
+-- @tparam vector pos
+-- @tparam ItemStack stack Armor item to be dropped.
armor.drop_armor = function(pos, stack)
local node = minetest.get_node_or_nil(pos)
if node then
@@ -694,6 +959,8 @@ end
--- Allows skin mod to be set manually.
--
-- Useful for skin mod forks that do not use the same name.
+--
+-- @tparam string mod Name of skin mod. Recognized names are "simple\_skins", "u\_skins", & "wardrobe".
armor.set_skin_mod = function(mod)
skin_mod = mod
end
diff --git a/3d_armor/armor.lua b/3d_armor/armor.lua
index f791239..a08da37 100644
--- a/3d_armor/armor.lua
+++ b/3d_armor/armor.lua
@@ -1,6 +1,23 @@
+
+--- Registered armors.
+--
+-- @topic armor
+
+
-- support for i18n
local S = armor.get_translator
+
+--- Admin Helmet
+--
+-- @helmet 3d_armor:helmet_admin
+-- @img 3d_armor_inv_helmet_admin.png
+-- @grp armor_head 1
+-- @grp armor_heal 100
+-- @grp armor_use 0
+-- @grp armor_water 1
+-- @grp not_in_creative_inventory 1
+-- @armorgrp fleshy 100
armor:register_armor("3d_armor:helmet_admin", {
description = S("Admin Helmet"),
inventory_image = "3d_armor_inv_helmet_admin.png",
@@ -12,6 +29,15 @@ armor:register_armor("3d_armor:helmet_admin", {
end,
})
+--- Admin Chestplate
+--
+-- @chestplate 3d_armor:chestplate_admin
+-- @img 3d_armor_inv_chestplate_admin.png
+-- @grp armor_torso 1
+-- @grp armor_heal 100
+-- @grp armor_use 0
+-- @grp not_in_creative_inventory 1
+-- @armorgrp fleshy 100
armor:register_armor("3d_armor:chestplate_admin", {
description = S("Admin Chestplate"),
inventory_image = "3d_armor_inv_chestplate_admin.png",
@@ -23,6 +49,15 @@ armor:register_armor("3d_armor:chestplate_admin", {
end,
})
+--- Admin Leggings
+--
+-- @leggings 3d_armor:leggings_admin
+-- @img 3d_armor_inv_leggings_admin.png
+-- @grp armor_legs 1
+-- @grp armor_heal 100
+-- @grp armor_use 0
+-- @grp not_in_creative_inventory 1
+-- @armorgrp fleshy 100
armor:register_armor("3d_armor:leggings_admin", {
description = S("Admin Leggings"),
inventory_image = "3d_armor_inv_leggings_admin.png",
@@ -34,6 +69,15 @@ armor:register_armor("3d_armor:leggings_admin", {
end,
})
+--- Admin Boots
+--
+-- @boots 3d_armor:boots_admin
+-- @img 3d_armor_inv_boots_admin.png
+-- @grp armor_feet 1
+-- @grp armor_heal 100
+-- @grp armor_use 0
+-- @grp not_in_creative_inventory 1
+-- @armorgrp fleshy 100
armor:register_armor("3d_armor:boots_admin", {
description = S("Admin Boots"),
inventory_image = "3d_armor_inv_boots_admin.png",
@@ -50,7 +94,28 @@ minetest.register_alias("adminhelmet", "3d_armor:helmet_admin")
minetest.register_alias("adminchestplate", "3d_armor:chestplate_admin")
minetest.register_alias("adminleggings", "3d_armor:leggings_admin")
+
+--- Wood
+--
+-- Requires setting `armor_material_wood`.
+--
+-- @section wood
+
if armor.materials.wood then
+ --- Wood Helmet
+ --
+ -- @helmet 3d_armor:helmet_wood
+ -- @img 3d_armor_inv_helmet_wood.png
+ -- @grp armor_head 1
+ -- @grp armor_heal 0
+ -- @grp armor_use 2000
+ -- @grp flammable 1
+ -- @armorgrp fleshy 5
+ -- @damagegrp cracky 3
+ -- @damagegrp snappy 2
+ -- @damagegrp choppy 3
+ -- @damagegrp crumbly 2
+ -- @damagegrp level 1
armor:register_armor("3d_armor:helmet_wood", {
description = S("Wood Helmet"),
inventory_image = "3d_armor_inv_helmet_wood.png",
@@ -58,6 +123,20 @@ if armor.materials.wood then
armor_groups = {fleshy=5},
damage_groups = {cracky=3, snappy=2, choppy=3, crumbly=2, level=1},
})
+ --- Wood Chestplate
+ --
+ -- @chestplate 3d_armor:chestplate_wood
+ -- @img 3d_armor_inv_chestplate_wood.png
+ -- @grp armor_torso 1
+ -- @grp armor_heal 0
+ -- @grp armor_use 2000
+ -- @grp flammable 1
+ -- @armorgrp fleshy 10
+ -- @damagegrp cracky 3
+ -- @damagegrp snappy 2
+ -- @damagegrp choppy 3
+ -- @damagegrp crumbly 2
+ -- @damagegrp level 1
armor:register_armor("3d_armor:chestplate_wood", {
description = S("Wood Chestplate"),
inventory_image = "3d_armor_inv_chestplate_wood.png",
@@ -65,6 +144,20 @@ if armor.materials.wood then
armor_groups = {fleshy=10},
damage_groups = {cracky=3, snappy=2, choppy=3, crumbly=2, level=1},
})
+ --- Wood Leggings
+ --
+ -- @leggings 3d_armor:leggings_wood
+ -- @img 3d_armor_inv_leggings_wood.png
+ -- @grp armor_legs 1
+ -- @grp armor_heal 0
+ -- @grp armor_use 1000
+ -- @grp flammable 1
+ -- @armorgrp fleshy 10
+ -- @damagegrp cracky 3
+ -- @damagegrp snappy 2
+ -- @damagegrp choppy 3
+ -- @damagegrp crumbly 2
+ -- @damagegrp level 1
armor:register_armor("3d_armor:leggings_wood", {
description = S("Wood Leggings"),
inventory_image = "3d_armor_inv_leggings_wood.png",
@@ -72,6 +165,20 @@ if armor.materials.wood then
armor_groups = {fleshy=10},
damage_groups = {cracky=3, snappy=2, choppy=3, crumbly=2, level=1},
})
+ --- Wood Boots
+ --
+ -- @boots 3d_armor:boots_wood
+ -- @img 3d_armor_inv_boots_wood.png
+ -- @grp armor_feet 1
+ -- @grp armor_heal 0
+ -- @grp armor_use 2000
+ -- @grp flammable 1
+ -- @armorgrp fleshy 5
+ -- @damagegrp cracky 3
+ -- @damagegrp snappy 2
+ -- @damagegrp choppy 3
+ -- @damagegrp crumbly 2
+ -- @damagegrp level 1
armor:register_armor("3d_armor:boots_wood", {
description = S("Wood Boots"),
inventory_image = "3d_armor_inv_boots_wood.png",
@@ -94,7 +201,27 @@ if armor.materials.wood then
end
end
+
+--- Cactus
+--
+-- Requires setting `armor_material_cactus`.
+--
+-- @section cactus
+
if armor.materials.cactus then
+ --- Cactus Helmet
+ --
+ -- @helmet 3d_armor:helmet_cactus
+ -- @img 3d_armor_inv_helmet_cactus.png
+ -- @grp armor_head 1
+ -- @grp armor_heal 0
+ -- @grp armor_use 1000
+ -- @armorgrp fleshy 5
+ -- @damagegrp cracky 3
+ -- @damagegrp snappy 3
+ -- @damagegrp choppy 2
+ -- @damagegrp crumbly 2
+ -- @damagegrp level 1
armor:register_armor("3d_armor:helmet_cactus", {
description = S("Cactus Helmet"),
inventory_image = "3d_armor_inv_helmet_cactus.png",
@@ -102,6 +229,19 @@ if armor.materials.cactus then
armor_groups = {fleshy=5},
damage_groups = {cracky=3, snappy=3, choppy=2, crumbly=2, level=1},
})
+ --- Cactus Chestplate
+ --
+ -- @chestplate 3d_armor:chestplate_cactus
+ -- @img 3d_armor_inv_chestplate_cactus.png
+ -- @grp armor_torso 1
+ -- @grp armor_heal 0
+ -- @grp armor_use 1000
+ -- @armorgrp fleshy 10
+ -- @damagegrp cracky 3
+ -- @damagegrp snappy 3
+ -- @damagegrp choppy 2
+ -- @damagegrp crumbly 2
+ -- @damagegrp level 1
armor:register_armor("3d_armor:chestplate_cactus", {
description = S("Cactus Chestplate"),
inventory_image = "3d_armor_inv_chestplate_cactus.png",
@@ -109,6 +249,19 @@ if armor.materials.cactus then
armor_groups = {fleshy=10},
damage_groups = {cracky=3, snappy=3, choppy=2, crumbly=2, level=1},
})
+ --- Cactus Leggings
+ --
+ -- @leggings 3d_armor:leggings_cactus
+ -- @img 3d_armor_inv_leggings_cactus.png
+ -- @grp armor_legs 1
+ -- @grp armor_heal 0
+ -- @grp armor_use 1000
+ -- @armorgrp fleshy 10
+ -- @damagegrp cracky 3
+ -- @damagegrp snappy 3
+ -- @damagegrp choppy 2
+ -- @damagegrp crumbly 2
+ -- @damagegrp level 1
armor:register_armor("3d_armor:leggings_cactus", {
description = S("Cactus Leggings"),
inventory_image = "3d_armor_inv_leggings_cactus.png",
@@ -116,6 +269,19 @@ if armor.materials.cactus then
armor_groups = {fleshy=10},
damage_groups = {cracky=3, snappy=3, choppy=2, crumbly=2, level=1},
})
+ --- Cactus Boots
+ --
+ -- @boots 3d_armor:boots_cactus
+ -- @img 3d_armor_inv_boots_cactus.png
+ -- @grp armor_feet 1
+ -- @grp armor_heal 0
+ -- @grp armor_use 1000
+ -- @armorgrp fleshy 5
+ -- @damagegrp cracky 3
+ -- @damagegrp snappy 3
+ -- @damagegrp choppy 2
+ -- @damagegrp crumbly 2
+ -- @damagegrp level 1
armor:register_armor("3d_armor:boots_cactus", {
description = S("Cactus Boots"),
inventory_image = "3d_armor_inv_boots_cactus.png",
@@ -138,7 +304,29 @@ if armor.materials.cactus then
end
end
+
+--- Steel
+--
+-- Requires setting `armor_material_steel`.
+--
+-- @section steel
+
if armor.materials.steel then
+ --- Steel Helmet
+ --
+ -- @helmet 3d_armor:helmet_steel
+ -- @img 3d_armor_inv_helmet_steel.png
+ -- @grp armor_head 1
+ -- @grp armor_heal 0
+ -- @grp armor_use 800
+ -- @grp physics_speed -0.01
+ -- @grp physica_gravity 0.01
+ -- @armorgrp fleshy 10
+ -- @damagegrp cracky 2
+ -- @damagegrp snappy 3
+ -- @damagegrp choppy 2
+ -- @damagegrp crumbly 1
+ -- @damagegrp level 2
armor:register_armor("3d_armor:helmet_steel", {
description = S("Steel Helmet"),
inventory_image = "3d_armor_inv_helmet_steel.png",
@@ -147,6 +335,21 @@ if armor.materials.steel then
armor_groups = {fleshy=10},
damage_groups = {cracky=2, snappy=3, choppy=2, crumbly=1, level=2},
})
+ --- Steel Chestplate
+ --
+ -- @chestplate 3d_armor:chestplate_steel
+ -- @img 3d_armor_inv_chestplate_steel.png
+ -- @grp armor_torso 1
+ -- @grp armor_heal 0
+ -- @grp armor_use 800
+ -- @grp physics_speed
+ -- @grp physics_gravity
+ -- @armorgrp fleshy
+ -- @damagegrp cracky 2
+ -- @damagegrp snappy 3
+ -- @damagegrp choppy 2
+ -- @damagegrp crumbly 1
+ -- @damagegrp level 2
armor:register_armor("3d_armor:chestplate_steel", {
description = S("Steel Chestplate"),
inventory_image = "3d_armor_inv_chestplate_steel.png",
@@ -155,6 +358,21 @@ if armor.materials.steel then
armor_groups = {fleshy=15},
damage_groups = {cracky=2, snappy=3, choppy=2, crumbly=1, level=2},
})
+ --- Steel Leggings
+ --
+ -- @leggings 3d_armor:leggings_steel
+ -- @img 3d_armor_inv_leggings_steel.png
+ -- @grp armor_legs 1
+ -- @grp armor_heal 0
+ -- @grp armor_use 800
+ -- @grp physics_speed -0.03
+ -- @grp physics_gravity 0.03
+ -- @armorgrp fleshy 15
+ -- @damagegrp cracky 2
+ -- @damagegrp snappy 3
+ -- @damagegrp choppy 2
+ -- @damagegrp crumbly 1
+ -- @damagegrp level 2
armor:register_armor("3d_armor:leggings_steel", {
description = S("Steel Leggings"),
inventory_image = "3d_armor_inv_leggings_steel.png",
@@ -163,6 +381,21 @@ if armor.materials.steel then
armor_groups = {fleshy=15},
damage_groups = {cracky=2, snappy=3, choppy=2, crumbly=1, level=2},
})
+ --- Steel Boots
+ --
+ -- @boots 3d_armor:boots_steel
+ -- @img 3d_armor_inv_boots_steel.png
+ -- @grp armor_feet 1
+ -- @grp armor_heal 0
+ -- @grp armor_use 800
+ -- @grp physics_speed -0.01
+ -- @grp physics_gravity 0.01
+ -- @armorgrp fleshy 10
+ -- @damagegrp cracky 2
+ -- @damagegrp snappy 3
+ -- @damagegrp choppy 2
+ -- @damagegrp crumbly 1
+ -- @damagegrp level 2
armor:register_armor("3d_armor:boots_steel", {
description = S("Steel Boots"),
inventory_image = "3d_armor_inv_boots_steel.png",
@@ -173,7 +406,29 @@ if armor.materials.steel then
})
end
+
+--- Bronze
+--
+-- Requires setting `armor_material_bronze`.
+--
+-- @section bronze
+
if armor.materials.bronze then
+ --- Bronze Helmet
+ --
+ -- @helmet 3d_armor:helmet_bronze
+ -- @img 3d_armor_inv_helmet_bronze.png
+ -- @grp armor_head 1
+ -- @grp armor_heal 6
+ -- @grp armor_use 400
+ -- @grp physics_speed -0.01
+ -- @grp physics_gravity 0.01
+ -- @armorgrp fleshy 10
+ -- @damagegrp cracky 3
+ -- @damagegrp snappy 2
+ -- @damagegrp choppy 2
+ -- @damagegrp crumbly 1
+ -- @damagegrp level 2
armor:register_armor("3d_armor:helmet_bronze", {
description = S("Bronze Helmet"),
inventory_image = "3d_armor_inv_helmet_bronze.png",
@@ -182,6 +437,21 @@ if armor.materials.bronze then
armor_groups = {fleshy=10},
damage_groups = {cracky=3, snappy=2, choppy=2, crumbly=1, level=2},
})
+ --- Bronze Chestplate
+ --
+ -- @chestplate 3d_armor:chestplate_bronze
+ -- @img 3d_armor_inv_chestplate_bronze.png
+ -- @grp armor_torso 1
+ -- @grp armor_heal 6
+ -- @grp armor_use 400
+ -- @grp physics_speed -0.04
+ -- @grp physics_gravity 0.04
+ -- @armorgrp fleshy 15
+ -- @damagegrp cracky 3
+ -- @damagegrp snappy 2
+ -- @damagegrp choppy 2
+ -- @damagegrp crumbly 1
+ -- @damagegrp level 2
armor:register_armor("3d_armor:chestplate_bronze", {
description = S("Bronze Chestplate"),
inventory_image = "3d_armor_inv_chestplate_bronze.png",
@@ -190,6 +460,21 @@ if armor.materials.bronze then
armor_groups = {fleshy=15},
damage_groups = {cracky=3, snappy=2, choppy=2, crumbly=1, level=2},
})
+ --- Bronze Leggings
+ --
+ -- @leggings 3d_armor:leggings_bronze
+ -- @img 3d_armor_inv_leggings_bronze.png
+ -- @grp armor_legs 1
+ -- @grp armor_heal 6
+ -- @grp armor_use 400
+ -- @grp physics_speed -0.03
+ -- @grp physics_gravity 0.03
+ -- @armorgrp fleshy 15
+ -- @damagegrp cracky 3
+ -- @damagegrp snappy 2
+ -- @damagegrp choppy 2
+ -- @damagegrp crumbly 1
+ -- @damagegrp level 2
armor:register_armor("3d_armor:leggings_bronze", {
description = S("Bronze Leggings"),
inventory_image = "3d_armor_inv_leggings_bronze.png",
@@ -198,6 +483,21 @@ if armor.materials.bronze then
armor_groups = {fleshy=15},
damage_groups = {cracky=3, snappy=2, choppy=2, crumbly=1, level=2},
})
+ --- Bronze Boots
+ --
+ -- @boots 3d_armor:boots_bronze
+ -- @img 3d_armor_inv_boots_bronze.png
+ -- @grp armor_feet 1
+ -- @grp armor_heal 6
+ -- @grp armor_use 400
+ -- @grp physics_speed -0.01
+ -- @grp physics_gravity 0.01
+ -- @armorgrp fleshy 10
+ -- @damagegrp cracky 3
+ -- @damagegrp snappy 2
+ -- @damagegrp choppy 2
+ -- @damagegrp crumbly 1
+ -- @damagegrp level 2
armor:register_armor("3d_armor:boots_bronze", {
description = S("Bronze Boots"),
inventory_image = "3d_armor_inv_boots_bronze.png",
@@ -208,7 +508,26 @@ if armor.materials.bronze then
})
end
+
+--- Diamond
+--
+-- Requires setting `armor_material_diamond`.
+--
+-- @section diamond
+
if armor.materials.diamond then
+ --- Diamond Helmet
+ --
+ -- @helmet 3d_armor:_diamond
+ -- @img 3d_armor_inv_helmet_diamond.png
+ -- @grp armor_head 1
+ -- @grp armor_heal 12
+ -- @grp armor_use 200
+ -- @armorgrp fleshy 15
+ -- @damagegrp cracky 2
+ -- @damagegrp snappy 1
+ -- @damagegrp choppy 1
+ -- @damagegrp level 3
armor:register_armor("3d_armor:helmet_diamond", {
description = S("Diamond Helmet"),
inventory_image = "3d_armor_inv_helmet_diamond.png",
@@ -216,6 +535,18 @@ if armor.materials.diamond then
armor_groups = {fleshy=15},
damage_groups = {cracky=2, snappy=1, choppy=1, level=3},
})
+ --- Diamond Chestplate
+ --
+ -- @chestplate 3d_armor:chestplate_diamond
+ -- @img 3d_armor_inv_chestplate_diamond.png
+ -- @grp armor_torso 1
+ -- @grp armor_heal 12
+ -- @grp armor_use 200
+ -- @armorgrp fleshy 20
+ -- @damagegrp cracky 2
+ -- @damagegrp snappy 1
+ -- @damagegrp choppy 1
+ -- @damagegrp level 3
armor:register_armor("3d_armor:chestplate_diamond", {
description = S("Diamond Chestplate"),
inventory_image = "3d_armor_inv_chestplate_diamond.png",
@@ -223,6 +554,18 @@ if armor.materials.diamond then
armor_groups = {fleshy=20},
damage_groups = {cracky=2, snappy=1, choppy=1, level=3},
})
+ --- Diamond Leggings
+ --
+ -- @leggings 3d_armor:leggings_diamond
+ -- @img 3d_armor_inv_leggings_diamond.png
+ -- @grp armor_legs 1
+ -- @grp armor_heal 12
+ -- @grp armor_use 200
+ -- @armorgrp fleshy 20
+ -- @damagegrp cracky 2
+ -- @damagegrp snappy 1
+ -- @damagegrp choppy 1
+ -- @damagegrp level 3
armor:register_armor("3d_armor:leggings_diamond", {
description = S("Diamond Leggings"),
inventory_image = "3d_armor_inv_leggings_diamond.png",
@@ -230,6 +573,18 @@ if armor.materials.diamond then
armor_groups = {fleshy=20},
damage_groups = {cracky=2, snappy=1, choppy=1, level=3},
})
+ --- Diamond Boots
+ --
+ -- @boots 3d_armor:boots_diamond
+ -- @img 3d_armor_inv_boots_diamond.png
+ -- @grp armor_feet 1
+ -- @grp armor_heal 12
+ -- @grp armor_use 200
+ -- @armorgrp fleshy 15
+ -- @damagegrp cracky 2
+ -- @damagegrp snappy 1
+ -- @damagegrp choppy 1
+ -- @damagegrp level 3
armor:register_armor("3d_armor:boots_diamond", {
description = S("Diamond Boots"),
inventory_image = "3d_armor_inv_boots_diamond.png",
@@ -239,7 +594,29 @@ if armor.materials.diamond then
})
end
+
+--- Gold
+--
+-- Requires `armor_material_gold`.
+--
+-- @section gold
+
if armor.materials.gold then
+ --- Gold Helmet
+ --
+ -- @helmet 3d_armor:helmet_gold
+ -- @img 3d_armor_inv_helmet_gold.png
+ -- @grp armor_head 1
+ -- @grp armor_heal 6
+ -- @grp armor_use 300
+ -- @grp physics_speed -0.02
+ -- @grp physics_gravity 0.02
+ -- @armorgrp fleshy 10
+ -- @damagegrp cracky 1
+ -- @damagegrp snappy 2
+ -- @damagegrp choppy 2
+ -- @damagegrp crumbly 3
+ -- @damagegrp level 2
armor:register_armor("3d_armor:helmet_gold", {
description = S("Gold Helmet"),
inventory_image = "3d_armor_inv_helmet_gold.png",
@@ -248,6 +625,21 @@ if armor.materials.gold then
armor_groups = {fleshy=10},
damage_groups = {cracky=1, snappy=2, choppy=2, crumbly=3, level=2},
})
+ --- Gold Chestplate
+ --
+ -- @chestplate 3d_armor:chestplate_gold
+ -- @img 3d_armor_inv_chestplate_gold.png
+ -- @grp armor_torso 1
+ -- @grp armor_heal 6
+ -- @grp armor_use 300
+ -- @grp physics_speed -0.05
+ -- @grp physics_gravity 0.05
+ -- @armorgrp fleshy 15
+ -- @damagegrp cracky 1
+ -- @damagegrp snappy 2
+ -- @damagegrp choppy 2
+ -- @damagegrp crumbly 3
+ -- @damagegrp level 2
armor:register_armor("3d_armor:chestplate_gold", {
description = S("Gold Chestplate"),
inventory_image = "3d_armor_inv_chestplate_gold.png",
@@ -256,6 +648,21 @@ if armor.materials.gold then
armor_groups = {fleshy=15},
damage_groups = {cracky=1, snappy=2, choppy=2, crumbly=3, level=2},
})
+ --- Gold Leggings
+ --
+ -- @leggings 3d_armor:leggings_gold
+ -- @img 3d_armor_inv_leggings_gold.png
+ -- @grp armor_legs 1
+ -- @grp armor_heal 6
+ -- @grp armor_use 300
+ -- @grp physics_speed -0.04
+ -- @grp physics_gravity 0.04
+ -- @armorgrp fleshy 15
+ -- @damagegrp cracky 1
+ -- @damagegrp snappy 2
+ -- @damagegrp choppy 2
+ -- @damagegrp crumbly 3
+ -- @damagegrp level 2
armor:register_armor("3d_armor:leggings_gold", {
description = S("Gold Leggings"),
inventory_image = "3d_armor_inv_leggings_gold.png",
@@ -264,6 +671,21 @@ if armor.materials.gold then
armor_groups = {fleshy=15},
damage_groups = {cracky=1, snappy=2, choppy=2, crumbly=3, level=2},
})
+ --- Gold Boots
+ --
+ -- @boots 3d_armor:boots_gold
+ -- @img 3d_armor_inv_boots_gold.png
+ -- @grp armor_feet 1
+ -- @grp armor_heal 6
+ -- @grp armor_use 300
+ -- @grp physics_speed -0.02
+ -- @grp physics_gravity 0.02
+ -- @armorgrp fleshy 10
+ -- @damagegrp cracky 1
+ -- @damagegrp snappy 2
+ -- @damagegrp choppy 2
+ -- @damagegrp crumbly 3
+ -- @damagegrp level 2
armor:register_armor("3d_armor:boots_gold", {
description = S("Gold Boots"),
inventory_image = "3d_armor_inv_boots_gold.png",
@@ -274,7 +696,25 @@ if armor.materials.gold then
})
end
+
+--- Mithril
+--
+-- Requires `armor_material_mithril`.
+--
+-- @section mithril
+
if armor.materials.mithril then
+ --- Mithril Helmet
+ --
+ -- @helmet 3d_armor:helmet_mithril
+ -- @img 3d_armor_inv_helmet_mithril.png
+ -- @grp armor_head 1
+ -- @grp armor_heal 12
+ -- @grp armor_use 100
+ -- @armorgrp fleshy 15
+ -- @damagegrp cracky 2
+ -- @damagegrp snappy 1
+ -- @damagegrp level 3
armor:register_armor("3d_armor:helmet_mithril", {
description = S("Mithril Helmet"),
inventory_image = "3d_armor_inv_helmet_mithril.png",
@@ -282,6 +722,17 @@ if armor.materials.mithril then
armor_groups = {fleshy=15},
damage_groups = {cracky=2, snappy=1, level=3},
})
+ --- Mithril Chestplate
+ --
+ -- @chestplate 3d_armor:chestplate_mithril
+ -- @img 3d_armor_inv_chestplate_mithril.png
+ -- @grp armor_torso 1
+ -- @grp armor_heal 12
+ -- @grp armor_use 100
+ -- @armorgrp fleshy 20
+ -- @damagegrp cracky 2
+ -- @damagegrp snappy 1
+ -- @damagegrp level 3
armor:register_armor("3d_armor:chestplate_mithril", {
description = S("Mithril Chestplate"),
inventory_image = "3d_armor_inv_chestplate_mithril.png",
@@ -289,6 +740,17 @@ if armor.materials.mithril then
armor_groups = {fleshy=20},
damage_groups = {cracky=2, snappy=1, level=3},
})
+ --- Mithril Leggings
+ --
+ -- @leggings 3d_armor:leggings_mithril
+ -- @img 3d_armor_inv_leggings_mithril.png
+ -- @grp armor_legs 1
+ -- @grp armor_heal 12
+ -- @grp armor_use 100
+ -- @armorgrp fleshy 20
+ -- @damagegrp cracky 2
+ -- @damagegrp snappy 1
+ -- @damagegrp level 3
armor:register_armor("3d_armor:leggings_mithril", {
description = S("Mithril Leggings"),
inventory_image = "3d_armor_inv_leggings_mithril.png",
@@ -296,6 +758,17 @@ if armor.materials.mithril then
armor_groups = {fleshy=20},
damage_groups = {cracky=2, snappy=1, level=3},
})
+ --- Mithril Boots
+ --
+ -- @boots 3d_armor:boots_mithril
+ -- @img 3d_armor_inv_boots_mithril.png
+ -- @grp armor_feet 1
+ -- @grp armor_heal 12
+ -- @grp armor_use 100
+ -- @armorgrp fleshy 15
+ -- @damagegrp cracky 2
+ -- @damagegrp snappy 1
+ -- @damagegrp level 3
armor:register_armor("3d_armor:boots_mithril", {
description = S("Mithril Boots"),
inventory_image = "3d_armor_inv_boots_mithril.png",
@@ -305,7 +778,26 @@ if armor.materials.mithril then
})
end
+
+--- Crystal
+--
+-- Requires `armor_material_crystal`.
+--
+-- @section crystal
+
if armor.materials.crystal then
+ --- Crystal Helmet
+ --
+ -- @helmet 3d_armor:helmet_crystal
+ -- @img 3d_armor_inv_helmet_crystal.png
+ -- @grp armor_head 1
+ -- @grp armor_heal 12
+ -- @grp armor_use 100
+ -- @grp armor_fire 1
+ -- @armorgrp fleshy 15
+ -- @damagegrp cracky 2
+ -- @damagegrp snappy 1
+ -- @damagegrp level 3
armor:register_armor("3d_armor:helmet_crystal", {
description = S("Crystal Helmet"),
inventory_image = "3d_armor_inv_helmet_crystal.png",
@@ -313,6 +805,18 @@ if armor.materials.crystal then
armor_groups = {fleshy=15},
damage_groups = {cracky=2, snappy=1, level=3},
})
+ --- Crystal Chestplate
+ --
+ -- @chestplate 3d_armor:_crystal
+ -- @img 3d_armor_inv_chestplate_crystal.png
+ -- @grp armor_torso 1
+ -- @grp armor_heal 12
+ -- @grp armor_use 100
+ -- @grp armor_fire 1
+ -- @armorgrp fleshy 20
+ -- @damagegrp cracky 2
+ -- @damagegrp snappy 1
+ -- @damagegrp level 3
armor:register_armor("3d_armor:chestplate_crystal", {
description = S("Crystal Chestplate"),
inventory_image = "3d_armor_inv_chestplate_crystal.png",
@@ -320,6 +824,18 @@ if armor.materials.crystal then
armor_groups = {fleshy=20},
damage_groups = {cracky=2, snappy=1, level=3},
})
+ --- Crystal Leggings
+ --
+ -- @leggings 3d_armor:leggings_crystal
+ -- @img 3d_armor_inv_leggings_crystal.png
+ -- @grp armor_legs 1
+ -- @grp armor_heal 12
+ -- @grp armor_use 100
+ -- @grp armor_fire 1
+ -- @armorgrp fleshy 20
+ -- @damagegrp cracky 2
+ -- @damagegrp snappy 1
+ -- @damagegrp level 3
armor:register_armor("3d_armor:leggings_crystal", {
description = S("Crystal Leggings"),
inventory_image = "3d_armor_inv_leggings_crystal.png",
@@ -327,6 +843,20 @@ if armor.materials.crystal then
armor_groups = {fleshy=20},
damage_groups = {cracky=2, snappy=1, level=3},
})
+ --- Crystal Boots
+ --
+ -- @boots 3d_armor:boots_crystal
+ -- @img 3d_armor_inv_boots_crystal.png
+ -- @grp armor_feet 1
+ -- @grp armor_heal 12
+ -- @grp armor_use 100
+ -- @grp physics_speed 1
+ -- @grp physics_jump 0.5
+ -- @grp armor_fire 1
+ -- @armorgrp fleshy 15
+ -- @damagegrp cracky 2
+ -- @damagegrp snappy 1
+ -- @damagegrp level 3
armor:register_armor("3d_armor:boots_crystal", {
description = S("Crystal Boots"),
inventory_image = "3d_armor_inv_boots_crystal.png",
@@ -337,6 +867,44 @@ if armor.materials.crystal then
})
end
+
+--- Crafting
+--
+-- @section craft
+
+--- Craft recipes for helmets, chestplates, leggings, boots, & shields.
+--
+-- @craft armor
+-- @usage
+-- Key:
+-- - m: material
+-- - wood: group:wood
+-- - cactus: default:cactus
+-- - steel: default:steel_ingot
+-- - bronze: default:bronze_ingot
+-- - diamond: default:diamond
+-- - gold: default:gold_ingot
+-- - mithril: moreores:mithril_ingot
+-- - crystal: ethereal:crystal_ingot
+--
+-- helmet: chestplate: leggings:
+-- ┌───┬───┬───┐ ┌───┬───┬───┐ ┌───┬───┬───┐
+-- │ m │ m │ m │ │ m │ │ m │ │ m │ m │ m │
+-- ├───┼───┼───┤ ├───┼───┼───┤ ├───┼───┼───┤
+-- │ m │ │ m │ │ m │ m │ m │ │ m │ │ m │
+-- ├───┼───┼───┤ ├───┼───┼───┤ ├───┼───┼───┤
+-- │ │ │ │ │ m │ m │ m │ │ m │ │ m │
+-- └───┴───┴───┘ └───┴───┴───┘ └───┴───┴───┘
+--
+-- boots: shield:
+-- ┌───┬───┬───┐ ┌───┬───┬───┐
+-- │ │ │ │ │ m │ m │ m │
+-- ├───┼───┼───┤ ├───┼───┼───┤
+-- │ m │ │ m │ │ m │ m │ m │
+-- ├───┼───┼───┤ ├───┼───┼───┤
+-- │ m │ │ m │ │ │ m │ │
+-- └───┴───┴───┘ └───┴───┴───┘
+
for k, v in pairs(armor.materials) do
minetest.register_craft({
output = "3d_armor:helmet_"..k,
diff --git a/README.md b/README.md
index 57bcf62..3655e33 100644
--- a/README.md
+++ b/README.md
@@ -51,6 +51,8 @@ see armor.conf.example for all available options.
For mod installation instructions, please visit: http://wiki.minetest.com/wiki/Installing_Mods
+[API Reference](https://minetest-mods.github.io/3d_armor/reference/)
+
[mod] Visible Wielded Items [wieldview]
---------------------------------------
diff --git a/gendoc.sh b/gendoc.sh
new file mode 100755
index 0000000..b10ea75
--- /dev/null
+++ b/gendoc.sh
@@ -0,0 +1,38 @@
+#!/usr/bin/env bash
+
+# place this file in mod "docs" directory
+
+root="$(dirname $(readlink -f $0))"
+docs="${root}/3d_armor/docs"
+config="${root}/.ldoc/config.ld"
+export_dir="${export_dir:-${docs}/reference}"
+
+cd "${root}"
+
+# clean old files
+rm -rf "${export_dir}"
+
+# generate items & settings topics temp files
+./.ldoc/parse_src.py
+./.ldoc/parse_settings.py
+./.ldoc/parse_crafts.py
+
+echo
+
+# generate new doc files
+ldoc --UNSAFE_NO_SANDBOX --multimodule -c "${config}" -d "${export_dir}" "${root}"
+retval=$?
+if test ${retval} -ne 0; then
+ # doesn't support "UNSAFE_NO_SANDBOX" or "multimodule" flag
+ echo
+ ldoc -c "${config}" -d "${export_dir}" "."
+ retval=$?
+ if test ${retval} -ne 0; then
+ exit ${retval}
+ fi
+fi
+
+# cleanup
+rm -f ./.ldoc/*.luadoc
+
+echo -e "\nDone!"
diff --git a/settingtypes.txt b/settingtypes.txt
index 4195ddd..a873995 100644
--- a/settingtypes.txt
+++ b/settingtypes.txt
@@ -58,7 +58,7 @@ armor_punch_damage (Enable damage effects) bool true
# Enable migration of old armor inventories.
armor_migrate_old_inventory (Migrate old armor inventories) bool true
-# Don't show armor on character model.
+# Armor is not visible on player model when enabled.
armor_transparent (Transparent armor) bool false
diff --git a/shields/init.lua b/shields/init.lua
index 6c7ac5a..bf28fe2 100644
--- a/shields/init.lua
+++ b/shields/init.lua
@@ -1,3 +1,9 @@
+
+--- Registered shields.
+--
+-- @topic shields
+
+
-- support for i18n
local S = minetest.get_translator(minetest.get_current_modname())
@@ -21,6 +27,14 @@ end
-- Regisiter Shields
+--- Admin Shield
+--
+-- @shield shields:shield_admin
+-- @img shields_inv_shield_admin.png
+-- @grp armor_shield 1000
+-- @grp armor_heal 100
+-- @grp armor_use 0
+-- @grp not_int_creative_inventory 1
armor:register_armor("shields:shield_admin", {
description = S("Admin Shield"),
inventory_image = "shields_inv_shield_admin.png",
@@ -29,7 +43,22 @@ armor:register_armor("shields:shield_admin", {
minetest.register_alias("adminshield", "shields:shield_admin")
+
if armor.materials.wood then
+ --- Wood Shield
+ --
+ -- @shield shields:shield_wood
+ -- @img shields_inv_shield_wood.png
+ -- @grp armor_shield 1
+ -- @grp armor_heal 0
+ -- @grp armor_use 2000
+ -- @grp flammable 1
+ -- @armorgrp fleshy 5
+ -- @damagegrp cracky 3
+ -- @damagegrp snappy 2
+ -- @damagegrp choppy 3
+ -- @damagegrp crumbly 2
+ -- @damagegrp level 1
armor:register_armor("shields:shield_wood", {
description = S("Wooden Shield"),
inventory_image = "shields_inv_shield_wood.png",
@@ -44,6 +73,19 @@ if armor.materials.wood then
play_sound_effect(player, "default_wood_footstep")
end,
})
+ --- Enhanced Wood Shield
+ --
+ -- @shield shields:shield_enhanced_wood
+ -- @img shields_inv_shield_enhanced_wood.png
+ -- @grp armor_shield 1
+ -- @grp armor_heal 0
+ -- @grp armor_use 2000
+ -- @armorgrp fleshy 8
+ -- @damagegrp cracky 3
+ -- @damagegrp snappy 2
+ -- @damagegrp choppy 3
+ -- @damagegrp crumbly 2
+ -- @damagegrp level 2
armor:register_armor("shields:shield_enhanced_wood", {
description = S("Enhanced Wood Shield"),
inventory_image = "shields_inv_shield_enhanced_wood.png",
@@ -74,6 +116,19 @@ if armor.materials.wood then
end
if armor.materials.cactus then
+ --- Cactus Shield
+ --
+ -- @shield shields:shield_cactus
+ -- @img shields_inv_shield_cactus.png
+ -- @grp armor_shield 1
+ -- @grp armor_heal 0
+ -- @grp armor_use 1000
+ -- @armorgrp fleshy 5
+ -- @damagegrp cracky 3
+ -- @damagegrp snappy 3
+ -- @damagegrp choppy 2
+ -- @damagegrp crumbly 2
+ -- @damagegrp level 1
armor:register_armor("shields:shield_cactus", {
description = S("Cactus Shield"),
inventory_image = "shields_inv_shield_cactus.png",
@@ -88,6 +143,19 @@ if armor.materials.cactus then
play_sound_effect(player, "default_wood_footstep")
end,
})
+ --- Enhanced Cactus Shield
+ --
+ -- @shield shields:shield_enhanced_cactus
+ -- @img shields_inv_shield_enhanced_cactus.png
+ -- @grp armor_shield 1
+ -- @grp armor_heal 0
+ -- @grp armor_use 1000
+ -- @armorgrp fleshy 8
+ -- @damagegrp cracky 3
+ -- @damagegrp snappy 3
+ -- @damagegrp choppy 2
+ -- @damagegrp crumbly 2
+ -- @damagegrp level 2
armor:register_armor("shields:shield_enhanced_cactus", {
description = S("Enhanced Cactus Shield"),
inventory_image = "shields_inv_shield_enhanced_cactus.png",
@@ -118,6 +186,21 @@ if armor.materials.cactus then
end
if armor.materials.steel then
+ --- Steel Shield
+ --
+ -- @shield shields:shield_steel
+ -- @img shields_inv_shield_steel.png
+ -- @grp armor_shield 1
+ -- @grp armor_heal 0
+ -- @grp armor_use 800
+ -- @grp physics_speed -0.03
+ -- @grp physics_gravity 0.03
+ -- @armorgrp fleshy 10
+ -- @damagegrp cracky 2
+ -- @damagegrp snappy 3
+ -- @damagegrp choppy 2
+ -- @damagegrp crumbly 1
+ -- @damagegrp level 2
armor:register_armor("shields:shield_steel", {
description = S("Steel Shield"),
inventory_image = "shields_inv_shield_steel.png",
@@ -136,6 +219,21 @@ if armor.materials.steel then
end
if armor.materials.bronze then
+ --- Bronze Shield
+ --
+ -- @shield shields:shield_bronze
+ -- @img shields_inv_shield_bronze.png
+ -- @grp armor_shield 1
+ -- @grp armor_heal 6
+ -- @grp armor_use 400
+ -- @grp physics_speed -0.03
+ -- @grp physics_gravity 0.03
+ -- @armorgrp fleshy 10
+ -- @damagegrp cracky 2
+ -- @damagegrp snappy 3
+ -- @damagegrp choppy 2
+ -- @damagegrp crumbly 1
+ -- @damagegrp level 2
armor:register_armor("shields:shield_bronze", {
description = S("Bronze Shield"),
inventory_image = "shields_inv_shield_bronze.png",
@@ -154,6 +252,18 @@ if armor.materials.bronze then
end
if armor.materials.diamond then
+ --- Diamond Shield
+ --
+ -- @shield shields:shield_diamond
+ -- @img shields_inv_shield_diamond.png
+ -- @grp armor_shield 1
+ -- @grp armor_heal 12
+ -- @grp armor_use 200
+ -- @armorgrp fleshy 15
+ -- @damagegrp cracky 2
+ -- @damagegrp snappy 1
+ -- @damagegrp choppy 1
+ -- @damagegrp level 3
armor:register_armor("shields:shield_diamond", {
description = S("Diamond Shield"),
inventory_image = "shields_inv_shield_diamond.png",
@@ -171,6 +281,21 @@ if armor.materials.diamond then
end
if armor.materials.gold then
+ --- Gold Shield
+ --
+ -- @shield shields:shield_gold
+ -- @img shields_inv_shield_gold.png
+ -- @grp armor_shield 1
+ -- @grp armor_heal 6
+ -- @grp armor_use 300
+ -- @grp physics_speed -0.04
+ -- @grp physics_gravity 0.04
+ -- @armorgrp fleshy 10
+ -- @damagegrp cracky 1
+ -- @damagegrp snappy 2
+ -- @damagegrp choppy 2
+ -- @damagegrp crumbly 3
+ -- @damagegrp level 2
armor:register_armor("shields:shield_gold", {
description = S("Gold Shield"),
inventory_image = "shields_inv_shield_gold.png",
@@ -189,6 +314,17 @@ if armor.materials.gold then
end
if armor.materials.mithril then
+ --- Mithril Shield
+ --
+ -- @shield shields:shield_mithril
+ -- @img shields_inv_shield_mithril.png
+ -- @grp armor_shield 1
+ -- @grp armor_heal 12
+ -- @grp armor_use 100
+ -- @armorgrp fleshy 15
+ -- @damagegrp cracky 2
+ -- @damagegrp snappy 1
+ -- @damagegrp level 3
armor:register_armor("shields:shield_mithril", {
description = S("Mithril Shield"),
inventory_image = "shields_inv_shield_mithril.png",
@@ -206,6 +342,18 @@ if armor.materials.mithril then
end
if armor.materials.crystal then
+ --- Crystal Shield
+ --
+ -- @shield shields:shield_crystal
+ -- @img shields_inv_shield_crystal.png
+ -- @grp armor_shield 1
+ -- @grp armor_heal 12
+ -- @grp armor_use 100
+ -- @grp armor_fire 1
+ -- @armorgrp fleshy 15
+ -- @damagegrp cracky 2
+ -- @damagegrp snappy 1
+ -- @damagegrp level 3
armor:register_armor("shields:shield_crystal", {
description = S("Crystal Shield"),
inventory_image = "shields_inv_shield_crystal.png",