commit 73c488e9f97a745827602a12aea0bfcb93f59fef Author: n0m Date: Mon Aug 19 11:32:14 2024 +0200 Форк для mtsr diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..5c3c583 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2017 Minetest Mods Team + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..0a6c552 --- /dev/null +++ b/README.md @@ -0,0 +1,38 @@ +## Castle Masonry + +by: Philipbenr, DanDuncombe, FaceDeer + +Licence: MIT + +This is a mod all about creating castles and castle dungeons. Many of the nodes are used for the outer-walls or dungeons. + +Contains: + +* Walls, Corner-walls, +* Castlestone Stairs, Slabs, and Pillars +* Arrowslits and embrasures +* Rubble (to fill the interior of thick castle walls) +* Murder holes and machicolations +* Pillars and crossbraces +* Roof slate +* Paving stone +* Dungeon stone + +Mod settings can allow for the basic castle masonry forms to be made for the following material types (all optional): + +* Cobble +* Desert stone +* Desert stone brick +* Sandstone +* Sandstone brick +* Desert Sandstone +* Desert Sandstone brick +* Silver Sandstone +* Silver Sandstone brick +* Stone +* Stone brick +* Castle wall +* Wood +* Snow +* Ice +* Obsidian Brick diff --git a/arrow_slits.lua b/arrow_slits.lua new file mode 100644 index 0000000..ee313fc --- /dev/null +++ b/arrow_slits.lua @@ -0,0 +1,174 @@ + +local S = minetest.get_translator("castle_masonry") + + +castle_masonry.register_arrowslit = function(material) + local composition_def, burn_time, tile, desc = castle_masonry.get_material_properties(material) + local mod_name = minetest.get_current_modname() + + -- Node Definition + minetest.register_node(mod_name..":arrowslit_"..material.name, { + drawtype = "nodebox", + description = S("@1 Arrowslit", desc), + tiles = tile, + groups = composition_def.groups, + _mcl_hardness = composition_def._mcl_hardness or 0.8, + _mcl_blast_resistance = composition_def._mcl_blast_resistance or 1, + sounds = composition_def.sounds, + paramtype = "light", + paramtype2 = "facedir", + node_box = { + type = "fixed", + fixed = { + {-0.5, -0.375, 0.5, -0.0625, 0.375, 0.3125}, + {0.0625, -0.375, 0.5, 0.5, 0.375, 0.3125}, + {-0.5, 0.375, 0.5, 0.5, 0.5, 0.3125}, + {-0.5, -0.5, 0.5, 0.5, -0.375, 0.3125}, + {0.25, -0.5, 0.3125, 0.5, 0.5, 0.125}, + {-0.5, -0.5, 0.3125, -0.25, 0.5, 0.125}, + }, + }, + }) + + minetest.register_node(mod_name..":arrowslit_"..material.name.."_cross", { + drawtype = "nodebox", + description = S("@1 Arrowslit with Cross", desc), + tiles = tile, + groups = composition_def.groups, + _mcl_hardness = composition_def._mcl_hardness or 0.8, + _mcl_blast_resistance = composition_def._mcl_blast_resistance or 1, + sounds = composition_def.sounds, + paramtype = "light", + paramtype2 = "facedir", + node_box = { + type = "fixed", + fixed = { + {-0.5, -0.125, 0.5, -0.0625, 0.375, 0.3125}, + {0.0625, -0.125, 0.5, 0.5, 0.375, 0.3125}, + {-0.5, 0.375, 0.5, 0.5, 0.5, 0.3125}, + {-0.5, -0.5, 0.5, 0.5, -0.375, 0.3125}, + {0.0625, -0.375, 0.5, 0.5, -0.25, 0.3125}, + {-0.5, -0.375, 0.5, -0.0625, -0.25, 0.3125}, + {-0.5, -0.25, 0.5, -0.1875, -0.125, 0.3125}, + {0.1875, -0.25, 0.5, 0.5, -0.125, 0.3125}, + {0.25, -0.5, 0.3125, 0.5, 0.5, 0.125}, + {-0.5, -0.5, 0.3125, -0.25, 0.5, 0.125}, + }, + }, + }) + + minetest.register_node(mod_name..":arrowslit_"..material.name.."_hole", { + drawtype = "nodebox", + description = S("@1 Arrowslit with Hole", desc), + tiles = tile, + groups = composition_def.groups, + _mcl_hardness = composition_def._mcl_hardness or 0.8, + _mcl_blast_resistance = composition_def._mcl_blast_resistance or 1, + sounds = composition_def.sounds, + paramtype = "light", + paramtype2 = "facedir", + node_box = { + type = "fixed", + fixed = { + {-0.5, -0.375, 0.5, -0.125, 0.375, 0.3125}, + {0.125, -0.375, 0.5, 0.5, 0.375, 0.3125}, + {-0.5, -0.5, 0.5, 0.5, -0.375, 0.3125}, + {0.0625, -0.125, 0.5, 0.125, 0.375, 0.3125}, + {-0.125, -0.125, 0.5, -0.0625, 0.375, 0.3125}, + {-0.5, 0.375, 0.5, 0.5, 0.5, 0.3125}, + {0.25, -0.5, 0.3125, 0.5, 0.5, 0.125}, + {-0.5, -0.5, 0.3125, -0.25, 0.5, 0.125}, + }, + }, + }) + + minetest.register_node(mod_name..":arrowslit_"..material.name.."_embrasure", { + drawtype = "nodebox", + description = S("@1 Embrasure", desc), + tiles = tile, + groups = composition_def.groups, + _mcl_hardness = composition_def._mcl_hardness or 0.8, + _mcl_blast_resistance = composition_def._mcl_blast_resistance or 1, + sounds = composition_def.sounds, + paramtype = "light", + paramtype2 = "facedir", + node_box = { + type = "fixed", + fixed = { + {-0.25, -0.5, 0.375, -0.125, 0.5, 0.5}, + {0.125, -0.5, 0.375, 0.25, 0.5, 0.5}, + {0.25, -0.5, 0.25, 0.5, 0.5, 0.5}, + {0.375, -0.5, 0.125, 0.5, 0.5, 0.25}, + {-0.5, -0.5, 0.25, -0.25, 0.5, 0.5}, + {-0.5, -0.5, 0.125, -0.375, 0.5, 0.25}, + }, + }, + }) + + minetest.register_craft({ + output = mod_name..":arrowslit_"..material.name.." 6", + recipe = { + {material.craft_material,"", material.craft_material}, + {material.craft_material,"", material.craft_material}, + {material.craft_material,"", material.craft_material} }, + }) + + minetest.register_craft({ + output = mod_name..":arrowslit_"..material.name.."_cross", + recipe = { + {mod_name..":arrowslit_"..material.name} }, + }) + minetest.register_craft({ + output = mod_name..":arrowslit_"..material.name.."_hole", + recipe = { + {mod_name..":arrowslit_"..material.name.."_cross"} }, + }) + minetest.register_craft({ + output = mod_name..":arrowslit_"..material.name.."_embrasure", + recipe = { + {mod_name..":arrowslit_"..material.name.."_hole"} }, + }) + minetest.register_craft({ + output = mod_name..":arrowslit_"..material.name, + recipe = { + {mod_name..":arrowslit_"..material.name.."_embrasure"} }, + }) + + if burn_time > 0 then + minetest.register_craft({ + type = "fuel", + recipe = mod_name..":arrowslit_"..material.name, + burntime = burn_time, + }) + minetest.register_craft({ + type = "fuel", + recipe = mod_name..":arrowslit_"..material.name.."_cross", + burntime = burn_time, + }) + minetest.register_craft({ + type = "fuel", + recipe = mod_name..":arrowslit_"..material.name.."_hole", + burntime = burn_time, + }) + minetest.register_craft({ + type = "fuel", + recipe = mod_name..":arrowslit_"..material.name.."_embrasure", + burntime = burn_time, + }) + end +end + + +castle_masonry.register_arrowslit_alias = function(old_mod_name, old_material_name, new_mod_name, new_material_name) + minetest.register_alias(old_mod_name..":arrowslit_"..old_material_name, new_mod_name..":arrowslit_"..new_material_name) + minetest.register_alias(old_mod_name..":arrowslit_"..old_material_name.."_cross", new_mod_name..":arrowslit_"..new_material_name.."_cross") + minetest.register_alias(old_mod_name..":arrowslit_"..old_material_name.."_hole", new_mod_name..":arrowslit_"..new_material_name.."_hole") + minetest.register_alias(old_mod_name..":arrowslit_"..old_material_name.."_embrasure", new_mod_name..":arrowslit_"..new_material_name.."_embrasure") +end + +castle_masonry.register_arrowslit_alias_force = function(old_mod_name, old_material_name, new_mod_name, new_material_name) + minetest.register_alias_force(old_mod_name..":arrowslit_"..old_material_name, new_mod_name..":arrowslit_"..new_material_name) + minetest.register_alias_force(old_mod_name..":arrowslit_"..old_material_name.."_cross", new_mod_name..":arrowslit_"..new_material_name.."_cross") + minetest.register_alias_force(old_mod_name..":arrowslit_"..old_material_name.."_hole", new_mod_name..":arrowslit_"..new_material_name.."_hole") + minetest.register_alias_force(old_mod_name..":arrowslit_"..old_material_name.."_embrasure", new_mod_name..":arrowslit_"..new_material_name.."_embrasure") +end diff --git a/i18n.py b/i18n.py new file mode 100644 index 0000000..957804a --- /dev/null +++ b/i18n.py @@ -0,0 +1,218 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# +# Script to generate the template file and update the translation files. +# Copy the script into the mod or modpack root folder and run it there. +# +# Copyright (C) 2019 Joachim Stolberg +# LGPLv2.1+ + +from __future__ import print_function +import os, fnmatch, re, shutil, errno + +#group 2 will be the string, groups 1 and 3 will be the delimiters (" or ') +#See https://stackoverflow.com/questions/46967465/regex-match-text-in-either-single-or-double-quote +#TODO: support [[]] delimiters +pattern_lua = re.compile(r'[\.=^\t,{\(\s]N?S\(\s*(["\'])((?:\\\1|(?:(?!\1)).)*)(\1)[\s,\)]', re.DOTALL) + +# Handles "concatenation" .. " of strings" +pattern_concat = re.compile(r'["\'][\s]*\.\.[\s]*["\']', re.DOTALL) + +pattern_tr = re.compile(r'(.+?[^@])=(.+)') +pattern_name = re.compile(r'^name[ ]*=[ ]*([^ \n]*)') +pattern_tr_filename = re.compile(r'\.tr$') +pattern_po_language_code = re.compile(r'(.*)\.po$') + +#attempt to read the mod's name from the mod.conf file. Returns None on failure +def get_modname(folder): + try: + with open(folder + "mod.conf", "r", encoding='utf-8') as mod_conf: + for line in mod_conf: + match = pattern_name.match(line) + if match: + return match.group(1) + except FileNotFoundError: + pass + return None + +#If there are already .tr files in /locale, returns a list of their names +def get_existing_tr_files(folder): + out = [] + for root, dirs, files in os.walk(folder + 'locale/'): + for name in files: + if pattern_tr_filename.search(name): + out.append(name) + return out + +# A series of search and replaces that massage a .po file's contents into +# a .tr file's equivalent +def process_po_file(text): + # The first three items are for unused matches + text = re.sub(r'#~ msgid "', "", text) + text = re.sub(r'"\n#~ msgstr ""\n"', "=", text) + text = re.sub(r'"\n#~ msgstr "', "=", text) + # comment lines + text = re.sub(r'#.*\n', "", text) + # converting msg pairs into "=" pairs + text = re.sub(r'msgid "', "", text) + text = re.sub(r'"\nmsgstr ""\n"', "=", text) + text = re.sub(r'"\nmsgstr "', "=", text) + # various line breaks and escape codes + text = re.sub(r'"\n"', "", text) + text = re.sub(r'"\n', "\n", text) + text = re.sub(r'\\"', '"', text) + text = re.sub(r'\\n', '@n', text) + # remove header text + text = re.sub(r'=Project-Id-Version:.*\n', "", text) + # remove double-spaced lines + text = re.sub(r'\n\n', '\n', text) + return text + +# Go through existing .po files and, if a .tr file for that language +# *doesn't* exist, convert it and create it. +# The .tr file that results will subsequently be reprocessed so +# any "no longer used" strings will be preserved. +# Note that "fuzzy" tags will be lost in this process. +def process_po_files(folder, modname): + for root, dirs, files in os.walk(folder + 'locale/'): + for name in files: + code_match = pattern_po_language_code.match(name) + if code_match == None: + continue + language_code = code_match.group(1) + tr_name = modname + "." + language_code + ".tr" + tr_file = os.path.join(root, tr_name) + if os.path.exists(tr_file): + print(tr_name + " already exists, ignoring " + name) + continue + fname = os.path.join(root, name) + with open(fname, "r", encoding='utf-8') as po_file: + print("Importing translations from " + name) + text = process_po_file(po_file.read()) + with open(tr_file, "wt", encoding='utf-8') as tr_out: + tr_out.write(text) + +# from https://stackoverflow.com/questions/600268/mkdir-p-functionality-in-python/600612#600612 +# Creates a directory if it doesn't exist, silently does +# nothing if it already exists +def mkdir_p(path): + try: + os.makedirs(path) + except OSError as exc: # Python >2.5 + if exc.errno == errno.EEXIST and os.path.isdir(path): + pass + else: raise + +# Writes a template.txt file +def write_template(templ_file, lkeyStrings): + lOut = [] + lkeyStrings.sort() + for s in lkeyStrings: + lOut.append("%s=" % s) + mkdir_p(os.path.dirname(templ_file)) + with open(templ_file, "wt", encoding='utf-8') as template_file: + template_file.write("\n".join(lOut)) + +# Gets all translatable strings from a lua file +def read_lua_file_strings(lua_file): + lOut = [] + with open(lua_file, encoding='utf-8') as text_file: + text = text_file.read() + text = re.sub(pattern_concat, "", text) + for s in pattern_lua.findall(text): + s = s[1] + s = re.sub(r'"\.\.\s+"', "", s) + s = re.sub("@[^@=0-9]", "@@", s) + s = s.replace('\\"', '"') + s = s.replace("\\'", "'") + s = s.replace("\n", "@n") + s = s.replace("\\n", "@n") + s = s.replace("=", "@=") + lOut.append(s) + return lOut + +# Gets strings from an existing translation file +def import_tr_file(tr_file): + dOut = {} + if os.path.exists(tr_file): + with open(tr_file, "r", encoding='utf-8') as existing_file : + for line in existing_file.readlines(): + s = line.strip() + if s == "" or s[0] == "#": + continue + match = pattern_tr.match(s) + if match: + dOut[match.group(1)] = match.group(2) + return dOut + +# Walks all lua files in the mod folder, collects translatable strings, +# and writes it to a template.txt file +def generate_template(folder): + lOut = [] + for root, dirs, files in os.walk(folder): + for name in files: + if fnmatch.fnmatch(name, "*.lua"): + fname = os.path.join(root, name) + found = read_lua_file_strings(fname) + print(fname + ": " + str(len(found)) + " translatable strings") + lOut.extend(found) + lOut = list(set(lOut)) + lOut.sort() + if len(lOut) == 0: + return None + templ_file = folder + "locale/template.txt" + write_template(templ_file, lOut) + return lOut + +# Updates an existing .tr file, copying the old one to a ".old" file +def update_tr_file(lNew, mod_name, tr_file): + print("updating " + tr_file) + lOut = ["# textdomain: %s\n" % mod_name] + + #TODO only make a .old if there are actual changes from the old file + if os.path.exists(tr_file): + shutil.copyfile(tr_file, tr_file+".old") + + dOld = import_tr_file(tr_file) + for key in lNew: + val = dOld.get(key, "") + lOut.append("%s=%s" % (key, val)) + lOut.append("##### not used anymore #####") + for key in dOld: + if key not in lNew: + lOut.append("%s=%s" % (key, dOld[key])) + with open(tr_file, "w", encoding='utf-8') as new_tr_file: + new_tr_file.write("\n".join(lOut)) + +# Updates translation files for the mod in the given folder +def update_mod(folder): + modname = get_modname(folder) + if modname is not None: + process_po_files(folder, modname) + print("Updating translations for " + modname) + data = generate_template(folder) + if data == None: + print("No translatable strings found in " + modname) + else: + for tr_file in get_existing_tr_files(folder): + update_tr_file(data, modname, folder + "locale/" + tr_file) + else: + print("Unable to find modname in folder " + folder) + +def update_folder(folder): + is_modpack = os.path.exists(folder+"modpack.txt") or os.path.exists(folder+"modpack.conf") + if is_modpack: + subfolders = [f.path for f in os.scandir(folder) if f.is_dir()] + for subfolder in subfolders: + update_mod(subfolder + "/") + else: + update_mod(folder) + print("Done.") + + +update_folder("./") + +# Runs this script on each sub-folder in the parent folder. +# I'm using this for testing this script on all installed mods. +#for modfolder in [f.path for f in os.scandir("../") if f.is_dir()]: +# update_folder(modfolder + "/") diff --git a/init.lua b/init.lua new file mode 100644 index 0000000..d25bcba --- /dev/null +++ b/init.lua @@ -0,0 +1,170 @@ +castle_masonry = {} + +castle_masonry.sounds = {} + +if minetest.get_modpath("default") then + castle_masonry.sounds = default +end + +if minetest.get_modpath("mcl_sounds") then + castle_masonry.sounds = mcl_sounds +end + +local MP = minetest.get_modpath(minetest.get_current_modname()) + +dofile(MP.."/pillars.lua") +dofile(MP.."/arrow_slits.lua") +dofile(MP.."/murder_holes.lua") +dofile(MP.."/stone_wall.lua") +dofile(MP.."/paving.lua") + + +local S = minetest.get_translator("castle_masonry") + +local read_setting = function(name, default) + local setting = minetest.settings:get_bool(name) + if not setting then return default end + return setting +end + +-- Material definition: +-- { +-- name=, -- the name that will be part of the resulting node names +-- desc=, -- Player-facing name of the material +-- tile=, -- Optional - the texture tile to use for the resulting blocks (can be a single texture or a table, as a normal node definition's tile def). If not set this will be taken from the material it's made out of. +-- craft_material=, -- What source block is used to craft these blocks. +-- composition_material=, -- Optional, this will override the properties of the product with a specific material. Useful if you want to use a group for the craft material (eg, "group:wood") +--} + +castle_masonry.materials = {} + +local function register_material(def, setting_default) + if read_setting("castle_masonry_" .. def.name, setting_default) then + table.insert(castle_masonry.materials, def) + end +end + +-- castle masonry materials +register_material({name="stonewall", desc=S("Stonewall"), tile="castle_stonewall.png", craft_material="castle_masonry:stonewall"}, true) + +-- MTG materials +if minetest.get_modpath("default") then + register_material({name="cobble", desc=S("Cobble"), tile="default_cobble.png", craft_material="default:cobble"}, true) + register_material({name="stonebrick", desc=S("Stonebrick"), tile="default_stone_brick.png", craft_material="default:stonebrick"}, true) + register_material({name="stone", desc=S("Stone"), tile="default_stone.png", craft_material="default:stone"}, true) + register_material({name="wood", desc=S("Wood"), tile="default_wood.png", craft_material="group:wood", composition_material="default:wood"}) + register_material({name="ice", desc=S("Ice"), tile="default_ice.png", craft_material="default:ice"}) + register_material({name="snow", desc=S("Snow"), tile="default_snow.png", craft_material="default:snow"}) + register_material({name="sandstone", desc=S("Sandstone"), tile="default_sandstone.png", craft_material="default:sandstone"}, true) + register_material({name="sandstonebrick", desc=S("Sandstone Brick"), tile="default_sandstone_brick.png", craft_material="default:sandstonebrick"}, true) + register_material({name="desertstonebrick", desc=S("Desert Stone Brick"), tile="default_desert_stone_brick.png", craft_material="default:desert_stonebrick"}, true) + register_material({name="desertsandstonebrick", desc=S("Desert Sandstone Brick"), tile="default_desert_sandstone_brick.png", craft_material="default:desert_sandstone_brick"}, true) + register_material({name="silversandstonebrick", desc=S("Silver Sandstone Brick"), tile="default_silver_sandstone_brick.png", craft_material="default:silver_sandstone_brick"}, true) + register_material({name="desertstone", desc=S("Desert Stone"), tile="default_desert_stone.png", craft_material="default:desert_stone"}, true) + register_material({name="desertsandstone", desc=S("Desert Sandstone"), tile="default_desert_sandstone.png", craft_material="default:desert_sandstone"}, true) + register_material({name="silversandstone", desc=S("Silver Sandstone"), tile="default_silver_sandstone.png", craft_material="default:silver_sandstone"}, true) + register_material({name="obsidianbrick", desc=S("Obsidian Brick"), tile="default_obsidian_brick.png", craft_material="default:obsidianbrick"}) +end + +-- MCL materials +if minetest.get_modpath("mcl_core") then + register_material({name="cobble", desc=S("Cobble"), craft_material="group:cobble", composition_material="mcl_core:cobble"}, true) + register_material({name="stonebrick", desc=S("Stonebrick"), craft_material="mcl_core:stonebrick"}, true) + register_material({name="stone", desc=S("Stone"), craft_material="group:stone", composition_material="mcl_core:stone"}, true) + register_material({name="ice", desc=S("Ice"), craft_material="mcl_core:ice"}) + register_material({name="snow", desc=S("Snow"), craft_material="mcl_core:snowblock"}) + register_material({name="sandstone", desc=S("Sandstone"), craft_material="mcl_core:sandstone"}, true) + register_material({name="redsandstone", desc=S("Red Sandstone"), craft_material="mcl_core:redsandstone"}, true) +end +-- wood ids are different in MineClonia and Mineclone2, mcl_trees is part of MineClonia +if minetest.get_modpath("mcl_trees") then + register_material({name="wood", desc=S("Wood"), craft_material="group:wood", composition_material="mcl_trees:wood_oak"}) +elseif minetest.get_modpath("mcl_core") then + register_material({name="wood", desc=S("Wood"), craft_material="group:wood", composition_material="mcl_core:wood"}) +end +if minetest.get_modpath("mcl_nether") then + register_material({name="quartz", desc=S("Quartz"), craft_material="mcl_nether:quartz_block"}, true) +end +if minetest.get_modpath("mcl_blackstone") then + register_material({name="blackstone", desc=S("Blackstone"), craft_material="mcl_blackstone:blackstone_brick_polished"}, true) +end +if minetest.get_modpath("mcl_deepslate") then + register_material({name="deepslate_bricks", desc=S("Deepslate Bricks"), craft_material="mcl_deepslate:deepslate_bricks"}, true) + register_material({name="deepslate_tiles", desc=S("Deepslate Tiles"), craft_material="mcl_deepslate:deepslate_tiles"}, true) +end + + +castle_masonry.get_material_properties = function(material) + local composition_def + local burn_time + if material.composition_material ~= nil then + composition_def = minetest.registered_nodes[material.composition_material] + burn_time = minetest.get_craft_result({method="fuel", width=1, items={ItemStack(material.composition_material)}}).time + else + composition_def = minetest.registered_nodes[material.craft_material] + burn_time = minetest.get_craft_result({method="fuel", width=1, items={ItemStack(material.craft_material)}}).time + end + + local tiles = material.tile + if tiles == nil then + tiles = composition_def.tiles + elseif type(tiles) == "string" then + tiles = {tiles} + end + + local desc = material.desc + if desc == nil then + desc = composition_def.description + end + + return composition_def, burn_time, tiles, desc +end + + +if read_setting("castle_masonry_pillar", true) then + for _, material in pairs(castle_masonry.materials) do + castle_masonry.register_pillar(material) + end +end + +if read_setting("castle_masonry_arrowslit", true) then + for _, material in pairs(castle_masonry.materials) do + castle_masonry.register_arrowslit(material) + end +end + +if read_setting("castle_masonry_murderhole", true) then + for _, material in pairs(castle_masonry.materials) do + castle_masonry.register_murderhole(material) + end +end + +minetest.register_alias("castle:pillars_bottom", "castle_masonry:pillars_stonewall_bottom") +minetest.register_alias("castle:pillars_top", "castle_masonry:pillars_stonewall_top") +minetest.register_alias("castle:pillars_middle", "castle_masonry:pillars_stonewall_middle") +minetest.register_alias("castle:arrowslit", "castle_masonry:arrowslit_stonewall") +minetest.register_alias("castle:arrowslit_hole", "castle_masonry:arrowslit_stonewall_hole") +minetest.register_alias("castle:arrowslit_cross", "castle_masonry:arrowslit_stonewall_cross") + +for _, material in pairs(castle_masonry.materials) do + castle_masonry.register_murderhole_alias("castle", material.name, "castle_masonry", material.name) + castle_masonry.register_pillar_alias("castle", material.name, "castle_masonry", material.name) + + -- Arrowslit upgrade has special handling because the castle mod arrow slit is reversed relative to current build-from-inside standard + local lbm_def = { + name = "castle_masonry:arrowslit_flip_front_to_back"..material.name, + run_at_every_load = false, + nodenames = { + "castle:arrowslit_"..material.name, + "castle:arrowslit_"..material.name.."_cross", + "castle:arrowslit_"..material.name.."_hole", + }, + action = function(pos, node) + local flip_front_to_back = {[0]=2, 3, 0, 1, 6, 7, 4, 5, 10, 7, 8, 9, 14, 15, 12, 13, 18, 19, 16, 17, 22, 23, 20, 21} + node.param2 = flip_front_to_back[node.param2] + node.name = "castle_masonry" .. string.sub(node.name, 7, -1) + minetest.swap_node(pos, node) + end + } + minetest.register_lbm(lbm_def) +end diff --git a/locale/castle_masonry.es.tr b/locale/castle_masonry.es.tr new file mode 100644 index 0000000..d613a42 --- /dev/null +++ b/locale/castle_masonry.es.tr @@ -0,0 +1,48 @@ +# textdomain: castle_masonry +@1 Arrowslit=Aspillera de @1 +@1 Arrowslit with Cross=Aspillera con Cruz de @1 +@1 Arrowslit with Hole=Aspillera con Agujero de @1 +@1 Embrasure=Aféizar de @1 +Stonewall=Pared de piedra +Cobble=Roca +Stonebrick=Ladrillo de Piedra +Sandstone Brick=Ladrillo de Arenisca +Desert Stone Brick=Ladrillo de Piedra del Desierto +Desert Sandstone Brick=Ladrillo de Arenisca del Desierto +Silver Sandstone Brick=Ladrillo de Arenisca Plateada +Stone=Piedra +Sandstone=Arenisca +Desert Stone=Piedra del Desierto +Desert Sandstone=Arenisca del Desierto +Silver Sandstone=Arenisca Plateada +Wood=Madera +Ice=Hielo +Snow=Nieve +Obsidian Brick=Ladrillo de Obsidiana +@1 Murder Hole=Agujero de @1 +@1 Machicolation=Matacán de @1 +Paving Stone=Pavimento de Piedra +Pavement Brick=Pavimento de Ladrillo +Castle Pavement Stair=Escalera de Pavimento de Castillo +Castle Pavement Slab=Losa de Pavimento de Castillo +Roof Slates=Techo de Pizarra +@1 Pillar Base=Base de Pilar de @1 +@1 Half Pillar Base=Media Base de Pilar de @1 +@1 Pillar Top=Parte Superior de Pilar de @1 +@1 Half Pillar Top=Superior de Medio Pilar @1 +@1 Pillar Middle=Medio Pilar de @1 +@1 Half Pillar Middle=Mitad del Medio Pilar de @1 +@1 Crossbrace=Viga de @1 +@1 Extended Crossbrace=Viga Extendida de @1 +Castle Wall=Muro de Castillo +Castle Rubble=Escombros de Castillo +Castle Corner=Esquina de Castillo +Stone Wall=Pared de Piedra +Rubble=Escombros +Castle Stonewall Stair=Escalera de Pared de Castillo +Castle Stonewall Slab=Losa de Pared de Castillo +Castle Rubble Stair=Escalera de Escombro de Castillo +Castle Rubble Slab=Losa de Escombro de Castillo +Dungeon Stone=Piedra de Mazmorra +Dungeon Stone Stair=Escalera de Piedra de Mazmorra +Dungeon Stone Slab=Losa de Piedra de Mazmorra diff --git a/locale/castle_masonry.fr.tr b/locale/castle_masonry.fr.tr new file mode 100644 index 0000000..8fefa63 --- /dev/null +++ b/locale/castle_masonry.fr.tr @@ -0,0 +1,49 @@ +# textdomain: castle_masonry + +@1 Arrowslit=Meurtrière en @1 +@1 Arrowslit with Cross=Meurtrière en croix en @1 +@1 Arrowslit with Hole=Meurtrière avec trou en @1 +@1 Crossbrace=Travers en @1 +@1 Embrasure=Embrasure en @1 +@1 Extended Crossbrace=Travers étendu en @1 +@1 Half Pillar Base=Base de demi pilier en @1 +@1 Half Pillar Middle=Milieu de demi pilier en @1 +@1 Half Pillar Top=Haut de demi pilier en @1 +@1 Machicolation=Machicoulis en @1 +@1 Murder Hole=Trou en @1 +@1 Pillar Base=Base de pilier en @1 +@1 Pillar Middle=Milieu de pilier en @1 +@1 Pillar Top=Haut de pilier en @1 +Castle Corner=Angle de chateau +Castle Pavement Slab=Dalle de chateau pavé +Castle Pavement Stair=Escaliers de chateau pavé +Castle Rubble=Gravats de chateau +Castle Rubble Slab=Dalle en gravats de chateau +Castle Rubble Stair=Escalier en gravats de chateau +Castle Stonewall Slab=Dalle en pierre brune +Castle Stonewall Stair=Escalier en pierre brune +Castle Wall=Pierre brune +Cobble=Pavé +Desert Sandstone=Pierre du désert +Desert Sandstone Brick=Brique de pierre du désert +Desert Stone=Pierre du désert +Desert Stone Brick=Brique de pierre du désert +Dungeon Stone=Pierre de donjon +Dungeon Stone Slab=Dalle en pierre de donjon +Dungeon Stone Stair=Escalier en pierre de donjon +Ice=Glace +Obsidian Brick=Brique d'obsidienne +Pavement Brick=Brique de pavage +Paving Stone=Pierre de pavage +Roof Slates=Toiture en ardoise +Rubble=Décombre +Sandstone=Grès +Sandstone Brick=Brique de grès +Silver Sandstone=Grès +Silver Sandstone Brick=Brique de grès +Snow=Neige +Stone=Pierre +Stone Wall=Mur de pierre +Stonebrick=Brique de pierre +Stonewall=Pierre brune +Wood=Bois diff --git a/locale/castle_masonry.it.tr b/locale/castle_masonry.it.tr new file mode 100644 index 0000000..d7e2866 --- /dev/null +++ b/locale/castle_masonry.it.tr @@ -0,0 +1,50 @@ +# textdomain: castle_masonry + +@1 Arrowslit=Feritoia per frecce di @1 +@1 Arrowslit with Cross=Feritoia a croce per frecce di @1 +@1 Arrowslit with Hole=Feritoia a foro per frecce di @1 +@1 Crossbrace=Costolone di @1 +@1 Embrasure=Feritoia di @1 +@1 Extended Crossbrace=Costolone esteso di @1 +@1 Half Pillar Base=Mezza base della colonna di @1 +@1 Half Pillar Middle=Mezzo fusto della colonna di @1 +@1 Half Pillar Top=Mezzo capitello di @1 +@1 Machicolation=Caditoia di @1 +@1 Murder Hole=Buca assassina di @1 +@1 Pillar Base=Base della colonna di @1 +@1 Pillar Middle=Fusto della colonna di @1 +@1 Pillar Top=Capitello di @1 +Castle Corner=Angolo del castello +Castle Pavement Slab=Lastra pavimentale del castello +Castle Pavement Stair=Scala pavimentale del castello +Castle Rubble=Detriti del castello +Castle Rubble Slab=Lastra del castello in detriti +Castle Rubble Stair=Scala del castello in detriti +Castle Stonewall Slab=Lastra del castello in muro di pietra +Castle Stonewall Stair=Scala del castello in muro di pietra +Castle Wall=Muro del castello +Cobble=ciottoli +Desert Sandstone=arenaria del deserto +Desert Sandstone Brick=mattone d'arenaria del deserto +Desert Stone=pietra del deserto +Desert Stone Brick=mattone di pietra del deserto +Dungeon Stone=Pietra del sotterraneo +Dungeon Stone Slab=Lastra di pietra del sotterraneo +Dungeon Stone Stair=Scala di pietra del sotterraneo +Ice=ghiaccio +Obsidian Brick=mattone d'ossidiana +Pavement Brick=Mattone pavimentale +Paving Stone=Pietra pavimentale +Roof Slates=Tegole d'ardesia +Rubble=Detriti +Sandstone=arenaria +Sandstone Brick=mattone d'arenaria del deserto +Silver Sandstone=arenaria argentata +Silver Sandstone Brick=mattone d'arenaria argentata +Snow=neve +Stone=pietra +Stone Wall=Muro di pietra +Stonebrick=mattone di pietra +Stonewall=muro di pietra +Wood=legno +##### not used anymore ##### \ No newline at end of file diff --git a/locale/template.txt b/locale/template.txt new file mode 100644 index 0000000..2827637 --- /dev/null +++ b/locale/template.txt @@ -0,0 +1,49 @@ +# textdomain:castle_masonry + +@1 Arrowslit= +@1 Arrowslit with Cross= +@1 Arrowslit with Hole= +@1 Embrasure= +Stonewall= +Cobble= +Stonebrick= +Sandstone Brick= +Desert Stone Brick= +Desert Sandstone Brick= +Silver Sandstone Brick= +Stone= +Sandstone= +Desert Stone= +Desert Sandstone= +Silver Sandstone= +Wood= +Ice= +Snow= +Obsidian Brick= +@1 Murder Hole= +@1 Machicolation= +Paving Stone= +Pavement Brick= +Castle Pavement Stair= +Castle Pavement Slab= +Roof Slates= +@1 Pillar Base= +@1 Half Pillar Base= +@1 Pillar Top= +@1 Half Pillar Top= +@1 Pillar Middle= +@1 Half Pillar Middle= +@1 Crossbrace= +@1 Extended Crossbrace= +Castle Wall= +Castle Rubble= +Castle Corner= +Stone Wall= +Rubble= +Castle Stonewall Stair= +Castle Stonewall Slab= +Castle Rubble Stair= +Castle Rubble Slab= +Dungeon Stone= +Dungeon Stone Stair= +Dungeon Stone Slab= diff --git a/mod.conf b/mod.conf new file mode 100644 index 0000000..5e06f40 --- /dev/null +++ b/mod.conf @@ -0,0 +1,7 @@ +name = castle_masonry +depends = +optional_depends = default, mcl_core, mcl_sounds, mcl_nether, mcl_deepslate, mcl_blackstone, mcl_stairs, mcl_trees, moreblocks, stairs, building_blocks, asphalt, streets +description = """ +This is a mod all about creating castles and castle dungeons. +Many of the nodes are used for the outer-walls or dungeons. +""" diff --git a/murder_holes.lua b/murder_holes.lua new file mode 100644 index 0000000..f9f3be7 --- /dev/null +++ b/murder_holes.lua @@ -0,0 +1,94 @@ + +local S = minetest.get_translator("castle_masonry") + +------------------------------------------------------------------------------------- + +castle_masonry.register_murderhole = function(material) + local composition_def, burn_time, tile, desc = castle_masonry.get_material_properties(material) + local mod_name = minetest.get_current_modname() + + -- Node Definition + minetest.register_node(mod_name..":hole_"..material.name, { + drawtype = "nodebox", + description = S("@1 Murder Hole", desc), + tiles = tile, + groups = composition_def.groups, + _mcl_hardness = composition_def._mcl_hardness or 0.8, + _mcl_blast_resistance = composition_def._mcl_blast_resistance or 1, + sounds = composition_def.sounds, + paramtype = "light", + paramtype2 = "facedir", + node_box = { + type = "fixed", + fixed = { + {-8/16,-8/16,-8/16,-4/16,8/16,8/16}, + {4/16,-8/16,-8/16,8/16,8/16,8/16}, + {-4/16,-8/16,-8/16,4/16,8/16,-4/16}, + {-4/16,-8/16,8/16,4/16,8/16,4/16}, + }, + }, + }) + + minetest.register_node(mod_name..":machicolation_"..material.name, { + drawtype = "nodebox", + description = S("@1 Machicolation", desc), + tiles = tile, + groups = composition_def.groups, + _mcl_hardness = composition_def._mcl_hardness or 0.8, + _mcl_blast_resistance = composition_def._mcl_blast_resistance or 1, + sounds = composition_def.sounds, + paramtype = "light", + paramtype2 = "facedir", + node_box = { + type = "fixed", + fixed = { + {-0.5, 0, -0.5, 0.5, 0.5, 0}, + {-0.5, -0.5, 0, -0.25, 0.5, 0.5}, + {0.25, -0.5, 0, 0.5, 0.5, 0.5}, + }, + }, + }) + + minetest.register_craft({ + output = mod_name..":hole_"..material.name.." 4", + recipe = { + {"",material.craft_material, "" }, + {material.craft_material,"", material.craft_material}, + {"",material.craft_material, ""} + }, + }) + + minetest.register_craft({ + output = mod_name..":machicolation_"..material.name, + type="shapeless", + recipe = {mod_name..":hole_"..material.name}, + }) + minetest.register_craft({ + output = mod_name..":hole_"..material.name, + type="shapeless", + recipe = {mod_name..":machicolation_"..material.name}, + }) + + if burn_time > 0 then + minetest.register_craft({ + type = "fuel", + recipe = mod_name..":hole_"..material.name, + burntime = burn_time, + }) + minetest.register_craft({ + type = "fuel", + recipe = mod_name..":machicolation_"..material.name, + burntime = burn_time, + }) + end +end + +castle_masonry.register_murderhole_alias = function(old_mod_name, old_material_name, new_mod_name, new_material_name) + minetest.register_alias(old_mod_name..":hole_"..old_material_name, new_mod_name..":hole_"..new_material_name) + minetest.register_alias(old_mod_name..":machicolation_"..old_material_name, new_mod_name..":machicolation_"..new_material_name) +end + +castle_masonry.register_murderhole_alias_force = function(old_mod_name, old_material_name, new_mod_name, new_material_name) + minetest.register_alias_force(old_mod_name..":hole_"..old_material_name, new_mod_name..":hole_"..new_material_name) + minetest.register_alias_force(old_mod_name..":machicolation_"..old_material_name, new_mod_name..":machicolation_"..new_material_name) +end diff --git a/paving.lua b/paving.lua new file mode 100644 index 0000000..d55b662 --- /dev/null +++ b/paving.lua @@ -0,0 +1,124 @@ +minetest.register_alias("castle:pavement", "castle_masonry:pavement_brick") +minetest.register_alias("castle:pavement_brick", "castle_masonry:pavement_brick") +minetest.register_alias("castle:roofslate", "castle_masonry:roofslate") + +local S = minetest.get_translator("castle_masonry") +local has_mcl = minetest.get_modpath("mcl_core") +local cobble = has_mcl and "mcl_core:cobble" or "default:cobble" + + +minetest.register_node("castle_masonry:pavement_brick", { + description = S("Paving Stone"), + drawtype = "normal", + tiles = {"castle_pavement_brick.png"}, + groups = {cracky=2, pickaxey=2}, + _mcl_hardness = 1, + _mcl_blast_resistance = 1, + paramtype = "light", + sounds = castle_masonry.sounds.node_sound_stone_defaults(), +}) + +minetest.register_craft({ + output = "castle_masonry:pavement_brick 4", + recipe = { + {"group:stone", cobble}, + {cobble, "group:stone"}, + } +}) + + +if minetest.get_modpath("moreblocks") then + stairsplus:register_all("castle_masonry", "pavement_brick", "castle_masonry:pavement_brick", { + description = S("Pavement Brick"), + tiles = {"castle_pavement_brick.png"}, + groups = {cracky=2, pickaxey=2, not_in_creative_inventory=1}, + sounds = castle_masonry.sounds.node_sound_stone_defaults(), + sunlight_propagates = true, + }) + stairsplus:register_alias_all("castle", "pavement_brick", "castle_masonry", "pavement_brick") +elseif minetest.get_modpath("mcl_stairs") then + mcl_stairs.register_stair_and_slab("pavement_brick", "castle_masonry:pavement_brick", + {pickaxey=2}, + {"castle_pavement_brick.png"}, + S("Castle Pavement Stair"), + S("Castle Pavement Slab"), + castle_masonry.sounds.node_sound_stone_defaults() + ) +elseif minetest.get_modpath("stairs") then + stairs.register_stair_and_slab("pavement_brick", "castle_masonry:pavement_brick", + {cracky=2}, + {"castle_pavement_brick.png"}, + S("Castle Pavement Stair"), + S("Castle Pavement Slab"), + castle_masonry.sounds.node_sound_stone_defaults() + ) +end + + +minetest.register_node("castle_masonry:roofslate", { + drawtype = "raillike", + description = S("Roof Slates"), + inventory_image = "castle_slate.png", + paramtype = "light", + walkable = false, + tiles = {'castle_slate.png'}, + climbable = true, + selection_box = { + type = "fixed", + fixed = {-1/2, -1/2, -1/2, 1/2, -1/2+1/16, 1/2}, + }, + groups = {cracky=3, pickaxey=1, attached_node=1}, + _mcl_hardness = 0.8, + _mcl_blast_resistance = 1, + sounds = castle_masonry.sounds.node_sound_stone_defaults(), +}) + +local mod_building_blocks = minetest.get_modpath("building_blocks") +local mod_streets = minetest.get_modpath("streets") or minetest.get_modpath("asphalt") +local has_mcl = minetest.get_modpath("mcl_core") +local gravel = has_mcl and "mcl_core:gravel" or "default:gravel" + +if mod_building_blocks then + minetest.register_craft({ + output = "castle_masonry:roofslate 4", + recipe = { + { "building_blocks:Tar" , gravel }, + { gravel, "building_blocks:Tar" } + } + }) + + minetest.register_craft( { + output = "castle_masonry:roofslate 4", + recipe = { + { gravel, "building_blocks:Tar" }, + { "building_blocks:Tar" , gravel } + } + }) +end + +if mod_streets then + minetest.register_craft( { + output = "castle_masonry:roofslate 4", + recipe = { + { "streets:asphalt" , gravel }, + { gravel, "streets:asphalt" } + } + }) + + minetest.register_craft( { + output = "castle_masonry:roofslate 4", + recipe = { + { gravel, "streets:asphalt" }, + { "streets:asphalt" , gravel } + } + }) +end + +if not (mod_building_blocks or mod_streets) then + minetest.register_craft({ + type = "cooking", + output = "castle_masonry:roofslate", + recipe = gravel, + }) + +end diff --git a/pillars.lua b/pillars.lua new file mode 100644 index 0000000..15194ff --- /dev/null +++ b/pillars.lua @@ -0,0 +1,330 @@ + +local S = minetest.get_translator("castle_masonry") + + +castle_masonry.register_pillar = function(material) + local composition_def, burn_time, tile, desc = castle_masonry.get_material_properties(material) + local crossbrace_connectable_groups = {} + for group, val in pairs(composition_def.groups) do + crossbrace_connectable_groups[group] = val + end + crossbrace_connectable_groups.crossbrace_connectable = 1 + + local mod_name = minetest.get_current_modname() + + -- Node Definition + minetest.register_node(mod_name..":pillar_"..material.name.."_bottom", { + drawtype = "nodebox", + description = S("@1 Pillar Base", desc), + tiles = tile, + groups = crossbrace_connectable_groups, + _mcl_hardness = composition_def._mcl_hardness or 0.8, + _mcl_blast_resistance = composition_def._mcl_blast_resistance or 1, + sounds = composition_def.sounds, + paramtype = "light", + paramtype2 = "facedir", + node_box = { + type = "fixed", + fixed = { + {-0.5,-0.5,-0.5,0.5,-0.375,0.5}, + {-0.375,-0.375,-0.375,0.375,-0.125,0.375}, + {-0.25,-0.125,-0.25,0.25,0.5,0.25}, + }, + }, + }) + + minetest.register_node(mod_name..":pillar_"..material.name.."_bottom_half", { + drawtype = "nodebox", + description = S("@1 Half Pillar Base", desc), + tiles = tile, + groups = composition_def.groups, + _mcl_hardness = composition_def._mcl_hardness or 0.8, + _mcl_blast_resistance = composition_def._mcl_blast_resistance or 1, + sounds = composition_def.sounds, + paramtype = "light", + paramtype2 = "facedir", + node_box = { + type = "fixed", + fixed = { + {-0.5, -0.5, 0, 0.5, -0.375, 0.5}, + {-0.375, -0.375, 0.125, 0.375, -0.125, 0.5}, + {-0.25, -0.125, 0.25, 0.25, 0.5, 0.5}, + }, + }, + }) + + minetest.register_node(mod_name..":pillar_"..material.name.."_top", { + drawtype = "nodebox", + description = S("@1 Pillar Top", desc), + tiles = tile, + groups = crossbrace_connectable_groups, + _mcl_hardness = composition_def._mcl_hardness or 0.8, + _mcl_blast_resistance = composition_def._mcl_blast_resistance or 1, + sounds = composition_def.sounds, + paramtype = "light", + paramtype2 = "facedir", + node_box = { + type = "fixed", + fixed = { + {-0.5,0.3125,-0.5,0.5,0.5,0.5}, + {-0.375,0.0625,-0.375,0.375,0.3125,0.375}, + {-0.25,-0.5,-0.25,0.25,0.0625,0.25}, + }, + }, + }) + + minetest.register_node(mod_name..":pillar_"..material.name.."_top_half", { + drawtype = "nodebox", + description = S("@1 Half Pillar Top", desc), + tiles = tile, + groups = composition_def.groups, + _mcl_hardness = composition_def._mcl_hardness or 0.8, + _mcl_blast_resistance = composition_def._mcl_blast_resistance or 1, + sounds = composition_def.sounds, + paramtype = "light", + paramtype2 = "facedir", + node_box = { + type = "fixed", + fixed = { + {-0.5, 0.3125, 0, 0.5, 0.5, 0.5}, + {-0.375, 0.0625, 0.125, 0.375, 0.3125, 0.5}, + {-0.25, -0.5, 0.25, 0.25, 0.0625, 0.5}, + }, + }, + }) + + minetest.register_node(mod_name..":pillar_"..material.name.."_middle", { + drawtype = "nodebox", + description = S("@1 Pillar Middle", desc), + tiles = tile, + groups = crossbrace_connectable_groups, + _mcl_hardness = composition_def._mcl_hardness or 0.8, + _mcl_blast_resistance = composition_def._mcl_blast_resistance or 1, + sounds = composition_def.sounds, + paramtype = "light", + paramtype2 = "facedir", + node_box = { + type = "fixed", + fixed = { + {-0.25,-0.5,-0.25,0.25,0.5,0.25}, + }, + }, + }) + + minetest.register_node(mod_name..":pillar_"..material.name.."_middle_half", { + drawtype = "nodebox", + description = S("@1 Half Pillar Middle", desc), + tiles = tile, + groups = composition_def.groups, + _mcl_hardness = composition_def._mcl_hardness or 0.8, + _mcl_blast_resistance = composition_def._mcl_blast_resistance or 1, + sounds = composition_def.sounds, + paramtype = "light", + paramtype2 = "facedir", + node_box = { + type = "fixed", + fixed = { + {-0.25, -0.5, 0.25, 0.25, 0.5, 0.5}, + }, + }, + }) + + minetest.register_node(mod_name..":pillar_"..material.name.."_crossbrace", + { + drawtype = "nodebox", + description = S("@1 Crossbrace", desc), + tiles = tile, + groups = composition_def.groups, + _mcl_hardness = composition_def._mcl_hardness or 0.8, + _mcl_blast_resistance = composition_def._mcl_blast_resistance or 1, + sounds = composition_def.sounds, + paramtype = "light", + paramtype2 = "facedir", + node_box = { + type = "connected", + fixed = {-0.25,0.25,-0.25,0.25,0.5,0.25}, + connect_front = {-0.25,0.25,-0.75,0.25,0.5,-0.25}, -- -Z + connect_left = {-0.25,0.25,-0.25,-0.75,0.5,0.25}, -- -X + connect_back = {-0.25,0.25,0.25,0.25,0.5,0.75}, -- +Z + connect_right = {0.25,0.25,-0.25,0.75,0.5,0.25}, -- +X + }, + connects_to = { + mod_name..":pillar_"..material.name.."_crossbrace", + mod_name..":pillar_"..material.name.."_extended_crossbrace", + "group:crossbrace_connectable"}, + connect_sides = { "front", "left", "back", "right" }, + }) + + minetest.register_node(mod_name..":pillar_"..material.name.."_extended_crossbrace", + { + drawtype = "nodebox", + description = S("@1 Extended Crossbrace", desc), + tiles = tile, + groups = composition_def.groups, + _mcl_hardness = composition_def._mcl_hardness or 0.8, + _mcl_blast_resistance = composition_def._mcl_blast_resistance or 1, + sounds = composition_def.sounds, + paramtype = "light", + paramtype2 = "facedir", + node_box = { + type = "fixed", + fixed = {-1.25,0.25,-0.25,1.25,0.5,0.25}, + }, + }) + + minetest.register_craft({ + output = mod_name..":pillar_"..material.name.."_bottom 4", + recipe = { + {"",material.craft_material,""}, + {"",material.craft_material,""}, + {material.craft_material,material.craft_material,material.craft_material} }, + }) + + minetest.register_craft({ + output = mod_name..":pillar_"..material.name.."_top 4", + recipe = { + {material.craft_material,material.craft_material,material.craft_material}, + {"",material.craft_material,""}, + {"",material.craft_material,""} }, + }) + + minetest.register_craft({ + output = mod_name..":pillar_"..material.name.."_middle 2", + recipe = { + {material.craft_material}, + {material.craft_material}, + {material.craft_material} }, + }) + + minetest.register_craft({ + output = mod_name..":pillar_"..material.name.."_crossbrace 10", + recipe = { + {material.craft_material,"",material.craft_material}, + {"",material.craft_material,""}, + {material.craft_material,"",material.craft_material} }, + }) + + minetest.register_craft({ + output = mod_name..":pillar_"..material.name.."_middle_half 2", + type="shapeless", + recipe = {mod_name..":pillar_"..material.name.."_middle"}, + }) + minetest.register_craft({ + output = mod_name..":pillar_"..material.name.."_middle", + type="shapeless", + recipe = {mod_name..":pillar_"..material.name.."_middle_half", mod_name..":pillar_"..material.name.."_middle_half"}, + }) + + minetest.register_craft({ + output = mod_name..":pillar_"..material.name.."_top_half 2", + type="shapeless", + recipe = {mod_name..":pillar_"..material.name.."_top"}, + }) + minetest.register_craft({ + output = mod_name..":pillar_"..material.name.."_top", + type="shapeless", + recipe = {mod_name..":pillar_"..material.name.."_top_half", mod_name..":pillar_"..material.name.."_top_half"}, + }) + + minetest.register_craft({ + output = mod_name..":pillar_"..material.name.."_bottom_half 2", + type="shapeless", + recipe = {mod_name..":pillar_"..material.name.."_bottom"}, + }) + minetest.register_craft({ + output = mod_name..":pillar_"..material.name.."_bottom", + type="shapeless", + recipe = {mod_name..":pillar_"..material.name.."_bottom_half", mod_name..":pillar_"..material.name.."_bottom_half"}, + }) + + minetest.register_craft({ + output = mod_name..":pillar_"..material.name.."_extended_crossbrace", + type="shapeless", + recipe = {mod_name..":pillar_"..material.name.."_crossbrace"}, + }) + + minetest.register_craft({ + output = mod_name..":pillar_"..material.name.."_crossbrace", + type="shapeless", + recipe = {mod_name..":pillar_"..material.name.."_extended_crossbrace"}, + }) + + if burn_time > 0 then + minetest.register_craft({ + type = "fuel", + recipe = mod_name..":pillar_"..material.name.."_top", + burntime = burn_time*5/4, + }) + minetest.register_craft({ + type = "fuel", + recipe = mod_name..":pillar_"..material.name.."_top_half", + burntime = burn_time*5/8, + }) + minetest.register_craft({ + type = "fuel", + recipe = mod_name..":pillar_"..material.name.."_bottom", + burntime = burn_time*5/4, + }) + minetest.register_craft({ + type = "fuel", + recipe = mod_name..":pillar_"..material.name.."_bottom_half", + burntime = burn_time*5/8, + }) + minetest.register_craft({ + type = "fuel", + recipe = mod_name..":pillar_"..material.name.."_middle", + burntime = burn_time*6/4, + }) + minetest.register_craft({ + type = "fuel", + recipe = mod_name..":pillar_"..material.name.."_middle_half", + burntime = burn_time*6/8, + }) + minetest.register_craft({ + type = "fuel", + recipe = mod_name..":pillar_"..material.name.."_crossbrace", + burntime = burn_time*5/10, + }) + minetest.register_craft({ + type = "fuel", + recipe = mod_name..":pillar_"..material.name.."_extended_crossbrace", + burntime = burn_time*5/10, + }) + end + +end + +-- The original castle mod had "pillars_", plural, which didn't match the arrowslit and murderhole standard. +castle_masonry.register_pillar_alias = function(old_mod_name, old_material_name, new_mod_name, new_material_name) + minetest.register_alias(old_mod_name..":pillars_"..old_material_name.."_bottom", new_mod_name..":pillar_"..new_material_name.."_bottom") + minetest.register_alias(old_mod_name..":pillars_"..old_material_name.."_bottom_half", new_mod_name..":pillar_"..new_material_name.."_bottom_half") + minetest.register_alias(old_mod_name..":pillars_"..old_material_name.."_crossbrace", new_mod_name..":pillar_"..new_material_name.."_crossbrace") + minetest.register_alias(old_mod_name..":pillars_"..old_material_name.."_middle", new_mod_name..":pillar_"..new_material_name.."_middle") + minetest.register_alias(old_mod_name..":pillars_"..old_material_name.."_middle_half", new_mod_name..":pillar_"..new_material_name.."_middle_half") + minetest.register_alias(old_mod_name..":pillars_"..old_material_name.."_top", new_mod_name..":pillar_"..new_material_name.."_top") + minetest.register_alias(old_mod_name..":pillars_"..old_material_name.."_top_half", new_mod_name..":pillar_"..new_material_name.."_top_half") + minetest.register_alias(old_mod_name..":pillar_"..old_material_name.."_bottom", new_mod_name..":pillar_"..new_material_name.."_bottom") + minetest.register_alias(old_mod_name..":pillar_"..old_material_name.."_bottom_half", new_mod_name..":pillar_"..new_material_name.."_bottom_half") + minetest.register_alias(old_mod_name..":pillar_"..old_material_name.."_crossbrace", new_mod_name..":pillar_"..new_material_name.."_crossbrace") + minetest.register_alias(old_mod_name..":pillar_"..old_material_name.."_middle", new_mod_name..":pillar_"..new_material_name.."_middle") + minetest.register_alias(old_mod_name..":pillar_"..old_material_name.."_middle_half", new_mod_name..":pillar_"..new_material_name.."_middle_half") + minetest.register_alias(old_mod_name..":pillar_"..old_material_name.."_top", new_mod_name..":pillar_"..new_material_name.."_top") + minetest.register_alias(old_mod_name..":pillar_"..old_material_name.."_top_half", new_mod_name..":pillar_"..new_material_name.."_top_half") +end + +castle_masonry.register_arrowslit_alias_force = function(old_mod_name, old_material_name, new_mod_name, new_material_name) + minetest.register_alias_force(old_mod_name..":pillars_"..old_material_name.."_bottom", new_mod_name..":pillar_"..new_material_name.."_bottom") + minetest.register_alias_force(old_mod_name..":pillars_"..old_material_name.."_bottom_half", new_mod_name..":pillar_"..new_material_name.."_bottom_half") + minetest.register_alias_force(old_mod_name..":pillars_"..old_material_name.."_crossbrace", new_mod_name..":pillar_"..new_material_name.."_crossbrace") + minetest.register_alias_force(old_mod_name..":pillars_"..old_material_name.."_middle", new_mod_name..":pillar_"..new_material_name.."_middle") + minetest.register_alias_force(old_mod_name..":pillars_"..old_material_name.."_middle_half", new_mod_name..":pillar_"..new_material_name.."_middle_half") + minetest.register_alias_force(old_mod_name..":pillars_"..old_material_name.."_top", new_mod_name..":pillar_"..new_material_name.."_top") + minetest.register_alias_force(old_mod_name..":pillars_"..old_material_name.."_top_half", new_mod_name..":pillar_"..new_material_name.."_top_half") + minetest.register_alias_force(old_mod_name..":pillar_"..old_material_name.."_bottom", new_mod_name..":pillar_"..new_material_name.."_bottom") + minetest.register_alias_force(old_mod_name..":pillar_"..old_material_name.."_bottom_half", new_mod_name..":pillar_"..new_material_name.."_bottom_half") + minetest.register_alias_force(old_mod_name..":pillar_"..old_material_name.."_crossbrace", new_mod_name..":pillar_"..new_material_name.."_crossbrace") + minetest.register_alias_force(old_mod_name..":pillar_"..old_material_name.."_middle", new_mod_name..":pillar_"..new_material_name.."_middle") + minetest.register_alias_force(old_mod_name..":pillar_"..old_material_name.."_middle_half", new_mod_name..":pillar_"..new_material_name.."_middle_half") + minetest.register_alias_force(old_mod_name..":pillar_"..old_material_name.."_top", new_mod_name..":pillar_"..new_material_name.."_top") + minetest.register_alias_force(old_mod_name..":pillar_"..old_material_name.."_top_half", new_mod_name..":pillar_"..new_material_name.."_top_half") +end diff --git a/screenshot.png b/screenshot.png new file mode 100644 index 0000000..2dd9cd8 Binary files /dev/null and b/screenshot.png differ diff --git a/settingtypes.txt b/settingtypes.txt new file mode 100644 index 0000000..decedb1 --- /dev/null +++ b/settingtypes.txt @@ -0,0 +1,31 @@ +[Materials] +castle_masonry_stonewall (Stonewall) bool true +castle_masonry_cobble (Cobble) bool true +castle_masonry_stonebrick (Stone Brick) bool true +castle_masonry_stone (Stone) bool true +castle_masonry_sandstone (Sandstone) bool true +castle_masonry_wood (Wood) bool false +castle_masonry_ice (Ice) bool false +castle_masonry_snow (Snow) bool false + +[Materials MTG] +castle_masonry_sandstonebrick (Sandstone Brick) bool true +castle_masonry_desertstonebrick (Desert Stone Brick) bool true +castle_masonry_desertsandstonebrick (Desert Sandstone Brick) bool true +castle_masonry_silversandstonebrick (Silver Sandstone Brick) bool true +castle_masonry_desertstone (Desert Stone) bool true +castle_masonry_desertsandstone (Desert Sandstone) bool true +castle_masonry_silversandstone (Silver Sandstone) bool true +castle_masonry_obsidianbrick (Obsidian Brick) bool false + +[Materials MCL] +castle_masonry_redsandstone (Red Sandstone) bool true +castle_masonry_quartz (Quartz) bool true +castle_masonry_blackstone (Blackstone) bool true +castle_masonry_deepslate_bricks (Deepslate Bricks) bool true +castle_masonry_deepslate_tiles (Deepslate Tiles) bool true + +[Forms] +castle_masonry_pillar (Pillars) bool true +castle_masonry_arrowslit (Arrow slits) bool true +castle_masonry_murderhole (Murder holes and machicolations) bool true diff --git a/stone_wall.lua b/stone_wall.lua new file mode 100644 index 0000000..ce82c37 --- /dev/null +++ b/stone_wall.lua @@ -0,0 +1,201 @@ + +local S = minetest.get_translator("castle_masonry") +local has_mcl = minetest.get_modpath("mcl_core") +local gravel = has_mcl and "mcl_core:gravel" or "default:gravel" +local desert_stone = has_mcl and "mcl_core:redsandstone" or "default:desert_stone" +local sandstone = has_mcl and "mcl_core:sandstone" or "default:sandstone" +local stonebrick = has_mcl and "mcl_core:stonebrick" or "default:stonebrick" +local obsidian = has_mcl and "mcl_core:obsidian" or "default:obsidian" +local cobble = has_mcl and "mcl_core:cobble" or "default:cobble" + + +minetest.register_alias("castle:stonewall", "castle_masonry:stonewall") +minetest.register_alias("castle:dungeon_stone", "castle_masonry:dungeon_stone") +minetest.register_alias("castle:rubble", "castle_masonry:rubble") +minetest.register_alias("castle:stonewall_corner", "castle_masonry:stonewall_corner") + +minetest.register_node("castle_masonry:stonewall", { + description = S("Castle Wall"), + drawtype = "normal", + tiles = {"castle_stonewall.png"}, + paramtype = "light", + drop = "castle_masonry:stonewall", + groups = {cracky=3, pickaxey=1}, + _mcl_hardness = 1, + _mcl_blast_resistance = 1, + sunlight_propagates = false, + sounds = castle_masonry.sounds.node_sound_stone_defaults(), +}) + +minetest.register_node("castle_masonry:rubble", { + description = S("Castle Rubble"), + drawtype = "normal", + tiles = {"castle_rubble.png"}, + paramtype = "light", + groups = {crumbly=3, shovely=1, falling_node=1}, + _mcl_hardness = 0.8, + _mcl_blast_resistance = 1, + sounds = castle_masonry.sounds.node_sound_gravel_defaults(), +}) + +minetest.register_craft({ + output = "castle_masonry:stonewall", + recipe = { + {cobble}, + {desert_stone}, + } +}) + +minetest.register_craft({ + output = "castle_masonry:rubble", + recipe = { + {"castle_masonry:stonewall"}, + } +}) + +minetest.register_craft({ + output = "castle_masonry:rubble 2", + recipe = { + {gravel}, + {desert_stone}, + } +}) + +minetest.register_node("castle_masonry:stonewall_corner", { + drawtype = "normal", + paramtype = "light", + paramtype2 = "facedir", + description = S("Castle Corner"), + tiles = {"castle_corner_stonewall_tb.png^[transformR90", + "castle_corner_stonewall_tb.png^[transformR180", + "castle_corner_stonewall1.png", + "castle_stonewall.png", + "castle_stonewall.png", + "castle_corner_stonewall2.png"}, + groups = {cracky=3, pickaxey=1}, + _mcl_hardness = 1, + _mcl_blast_resistance = 1, + sounds = castle_masonry.sounds.node_sound_stone_defaults(), +}) + +minetest.register_craft({ + output = "castle_masonry:stonewall_corner", + recipe = { + {"", "castle_masonry:stonewall"}, + {"castle_masonry:stonewall", sandstone}, + } +}) + +if minetest.get_modpath("moreblocks") then + stairsplus:register_all("castle_masonry", "stonewall", "castle_masonry:stonewall", { + description = S("Stone Wall"), + tiles = {"castle_stonewall.png"}, + groups = {cracky=3, pickaxey=1, not_in_creative_inventory=1}, + _mcl_hardness = 0.8, + _mcl_blast_resistance = 1, + sounds = castle_masonry.sounds.node_sound_stone_defaults(), + sunlight_propagates = true, + }) + + stairsplus:register_all("castle_masonry", "rubble", "castle_masonry:rubble", { + description = S("Rubble"), + tiles = {"castle_rubble.png"}, + groups = {cracky=3, pickaxey=1, not_in_creative_inventory=1}, + sounds = castle_masonry.sounds.node_sound_gravel_defaults(), + sunlight_propagates = true, + }) + + stairsplus:register_alias_all("castle", "stonewall", "castle_masonry", "stonewall") + stairsplus:register_alias_all("castle", "rubble", "castle_masonry", "rubble") + +elseif minetest.get_modpath("mcl_stairs") then + mcl_stairs.register_stair_and_slab("stonewall", "castle_masonry:stonewall", + {pickaxey=1}, + {"castle_stonewall.png"}, + S("Castle Stonewall Stair"), + S("Castle Stonewall Slab"), + castle_masonry.sounds.node_sound_stone_defaults() + ) + + mcl_stairs.register_stair_and_slab("rubble", "castle_masonry:rubble", + {shovely=1}, + {"castle_rubble.png"}, + S("Castle Rubble Stair"), + S("Castle Rubble Slab"), + castle_masonry.sounds.node_sound_gravel_defaults() + ) +elseif minetest.get_modpath("stairs") then + stairs.register_stair_and_slab("stonewall", "castle_masonry:stonewall", + {cracky=3, pickaxey=1}, + {"castle_stonewall.png"}, + S("Castle Stonewall Stair"), + S("Castle Stonewall Slab"), + castle_masonry.sounds.node_sound_stone_defaults() + ) + + stairs.register_stair_and_slab("rubble", "castle_masonry:rubble", + {cracky=3}, + {"castle_rubble.png"}, + S("Castle Rubble Stair"), + S("Castle Rubble Slab"), + castle_masonry.sounds.node_sound_stone_defaults() + ) +end + +-------------------------------------------------------------------------------------------------------------- + +minetest.register_node("castle_masonry:dungeon_stone", { + description = S("Dungeon Stone"), + drawtype = "normal", + tiles = {"castle_dungeon_stone.png"}, + groups = {cracky=2, pickaxey=2}, + _mcl_hardness = 1, + _mcl_blast_resistance = 1, + paramtype = "light", + sounds = castle_masonry.sounds.node_sound_stone_defaults(), +}) + +minetest.register_craft({ + output = "castle_masonry:dungeon_stone 2", + recipe = { + {stonebrick, obsidian}, + } +}) + +minetest.register_craft({ + output = "castle_masonry:dungeon_stone 2", + recipe = { + {stonebrick}, + {obsidian}, + } +}) + + +if minetest.get_modpath("moreblocks") then + stairsplus:register_all("castle_masonry", "dungeon_stone", "castle_masonry:dungeon_stone", { + description = S("Dungeon Stone"), + tiles = {"castle_dungeon_stone.png"}, + groups = {cracky=2, pickaxey=2, not_in_creative_inventory=1}, + sounds = castle_masonry.sounds.node_sound_stone_defaults(), + sunlight_propagates = true, + }) + + stairsplus:register_alias_all("castle", "dungeon_stone", "castle_masonry", "dungeon_stone") + +elseif minetest.get_modpath("mcl_stairs") then + mcl_stairs.register_stair_and_slab("dungeon_stone", "castle_masonry:dungeon_stone", + {pickaxey=2}, + {"castle_dungeon_stone.png"}, + S("Dungeon Stone Stair"), + S("Dungeon Stone Slab"), + castle_masonry.sounds.node_sound_stone_defaults() + ) +elseif minetest.get_modpath("stairs") then + stairs.register_stair_and_slab("dungeon_stone", "castle_masonry:dungeon_stone", + {cracky=2, pickaxey=2}, + {"castle_dungeon_stone.png"}, + S("Dungeon Stone Stair"), + S("Dungeon Stone Slab"), + castle_masonry.sounds.node_sound_stone_defaults() + ) +end diff --git a/textures/LICENSE.txt b/textures/LICENSE.txt new file mode 100644 index 0000000..306be33 --- /dev/null +++ b/textures/LICENSE.txt @@ -0,0 +1,21 @@ +-------------------------------------------- + +License Textures: Philipner - CC-BY-SA 3.0 + +-castle_corner_stonewall_tb.png +-castle_corner_stonewall1.png +-castle_corner_stonewall2.png + +-------------------------------------------- + +16 px textures based on Castle mod +original textures by Philipner + +License Textures: Napiophelios - CC-BY-SA 3.0 + +-castle_pavement_brick.png +-castle_rubble.png +-castle_slate.png +-castle_stonewall.png + +-------------------------------------------- diff --git a/textures/castle_corner_stonewall1.png b/textures/castle_corner_stonewall1.png new file mode 100644 index 0000000..0a9c091 Binary files /dev/null and b/textures/castle_corner_stonewall1.png differ diff --git a/textures/castle_corner_stonewall2.png b/textures/castle_corner_stonewall2.png new file mode 100644 index 0000000..8c9d8e9 Binary files /dev/null and b/textures/castle_corner_stonewall2.png differ diff --git a/textures/castle_corner_stonewall_tb.png b/textures/castle_corner_stonewall_tb.png new file mode 100644 index 0000000..1b0e02d Binary files /dev/null and b/textures/castle_corner_stonewall_tb.png differ diff --git a/textures/castle_dungeon_stone.png b/textures/castle_dungeon_stone.png new file mode 100644 index 0000000..6a2c154 Binary files /dev/null and b/textures/castle_dungeon_stone.png differ diff --git a/textures/castle_pavement_brick.png b/textures/castle_pavement_brick.png new file mode 100644 index 0000000..4c2da4d Binary files /dev/null and b/textures/castle_pavement_brick.png differ diff --git a/textures/castle_rubble.png b/textures/castle_rubble.png new file mode 100644 index 0000000..4788118 Binary files /dev/null and b/textures/castle_rubble.png differ diff --git a/textures/castle_slate.png b/textures/castle_slate.png new file mode 100644 index 0000000..a7de1ea Binary files /dev/null and b/textures/castle_slate.png differ diff --git a/textures/castle_stonewall.png b/textures/castle_stonewall.png new file mode 100644 index 0000000..9c26189 Binary files /dev/null and b/textures/castle_stonewall.png differ