diff --git a/.github/workflows/pre-commit.yml b/.github/workflows/pre-commit.yml new file mode 100644 index 0000000..9d5b459 --- /dev/null +++ b/.github/workflows/pre-commit.yml @@ -0,0 +1,25 @@ +name: pre-commit +on: [push, pull_request, workflow_dispatch] + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@master + - uses: actions/setup-python@master + + - name: install luarocks + run: sudo apt-get install -y luarocks + + - name: luacheck install + run: luarocks install --local luacheck + + - name: add luacheck path + run: echo "$HOME/.luarocks/bin" >> $GITHUB_PATH + + - name: Install pre-commit + run: pip3 install pre-commit + + - name: Run pre-commit + run: pre-commit run --all-files diff --git a/.luacheckrc b/.luacheckrc new file mode 100644 index 0000000..c0d728b --- /dev/null +++ b/.luacheckrc @@ -0,0 +1,50 @@ +std = "lua51+luajit+minetest+cottages" +unused_args = false +max_line_length = 120 + +stds.minetest = { + read_globals = { + "DIR_DELIM", + "minetest", + "core", + "dump", + "vector", + "nodeupdate", + "VoxelManip", + "VoxelArea", + "PseudoRandom", + "ItemStack", + "default", + "table", + "math", + "string", + } +} + +stds.cottages = { + globals = { + "cottages", + }, + read_globals = { + player_api = { + fields = { + player_attached = { + read_only = false, + other_fields = true, + }, + }, + other_fields = true, + }, + + "carts", + "default", + "doors", + "fs_layout", + "futil", + "node_entity_queue", + "player_monoids", + "stairs", + "stamina", + "unified_inventory", + }, +} diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..1b81d73 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,19 @@ +repos: + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v3.3.0 + hooks: + - id: fix-byte-order-marker + - id: end-of-file-fixer + - id: trailing-whitespace + + - id: mixed-line-ending + args: [ --fix=lf ] + + - repo: local + hooks: + - id: luacheck + name: luacheck + language: system + entry: luacheck + pass_filenames: false + args: [-q,.] diff --git a/API.md b/API.md new file mode 100644 index 0000000..9dec09e --- /dev/null +++ b/API.md @@ -0,0 +1,54 @@ +# anvil + +* `cottages.anvil.make_unrepairable(itemstring)` + makes the item unrepairable in the anvil +* `cottages.anvil.can_repair(item_or_stack)` + returns true/false + +# barrel + +* `cottages.barrel.register_barrel_liquid(def)` + ```lua + def = { + liquid = "default:water_source", + liquid_name = S("Water"), + liquid_texture = "default_water.png", + liquid_input_sound = cottages.sounds.water_empty, + liquid_output_sound = cottages.sounds.water_fill, + bucket_empty = "bucket:bucket_empty", + bucket_full = "bucket:bucket_water", + } + ``` +# doorlike + +* `api.register_hatch(nodename, description, texture, receipe_item, def)` + +# feldweg + +* `api.register_feldweg(node, suffix)` + register feldweg variants of a node + +# roof + +* `cottages.roof.register_roof(name, material, tiles)` + register roof variants of a node + +# straw + +* `api.register_quern_craft(recipe)` + register a crafting recipe w/ the quern. recipe is like + ```lua + { + input = "farming:seed_barley", + output = "farming:flour", + } + ``` + +* `api.register_threshing_craft(recipe)` + register a crafting recipe w/ the threshing floor. recipe is like + ```lua + { + input = "farming:barley", + output = {"farming:seed_barley", "cottages:straw_mat"}, + } + ``` diff --git a/LICENSE b/LICENSE index 733c072..9cecc1d 100644 --- a/LICENSE +++ b/LICENSE @@ -672,4 +672,3 @@ may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read . - diff --git a/README.md b/README.md index 0b0a033..56fd62b 100644 --- a/README.md +++ b/README.md @@ -1,93 +1,56 @@ Contains nodes for building medieval houses. -This used to be part of my random_buildings modpack, found under - https://github.com/Sokomine/random_buildings -It is now its own mod as all other mods in the modpack have been -superseded by newer versions. - -For more information about this mod, please refer to - https://forum.minetest.net/viewtopic.php?id=5120 -The thread introduces the nodes, shows crafting receipes and provides a place -to discuss about the mod. - -Special functions: -* Window shutters use an abm to automaticly close at night and open at day. -* The treshing place can be used to seperate harvested wheat into wheat seeds - and straw. The straw is useful for roofing purposes, straw bales etc. -* The handmill turns wheat seeds into flour. -* With anvil and hammer, tools can be repaired. -* The barrels do not yet have any further functionality. They may be used for - brewing in the future. Until then, punching makes them rotate and switch from - standing to lying on the ground. - -Liscence of this mod: GPLv3 -Autor: Sokomine +Liscence of this mod: GPLv3 Author: Sokomine, fluxionary --- --- Textures and media: --- VanessaE (CC-by-SA 3.0): - cottages_waonwheel.png - cottages_homedecor_shingles_asphalt.png - cottages_homedecor_shingles_terracotta.png - cottages_homedecor_shingles_wood.png - cottages_sleepingmat.png - cottages_barrel.png +cottages_waonwheel.png cottages_homedecor_shingles_asphalt.png cottages_homedecor_shingles_terracotta.png +cottages_homedecor_shingles_wood.png cottages_sleepingmat.png cottages_barrel.png CC-by-SA; done by GloopMaster (CC-by-SA): - glooptest_tool_steelhammer.png +glooptest_tool_steelhammer.png badger436 (created for this mod; CC BY-SA 3.0): - cottages_feldweg.png +cottages_feldweg.png Some textures are taken from - https://github.com/minetest/minetest_game +https://github.com/minetest/minetest_game and renamed (default_NAME.png -> cottages_NAME.png) Cisoun's WTFPL texture pack: - cottages_stone.png (for anvil and handmill) - cottages_wool.png +cottages_stone.png (for handmill) +cottages_wool.png Zeg9 (CC BY-SA 3.0): - cottages_steel_block.png (for steel hatch and stovepipie) +cottages_steel_block.png (for anvil and steel hatch and stovepipie) MasterGollum (WTFPL, darkage mod): - cottages_darkage_straw_bale.png - cottages_darkage_straw.png - cottages_reet.png (straw texture changed in color) +cottages_darkage_straw_bale.png cottages_darkage_straw.png cottages_reet.png (straw texture changed in color) Sokomine (CC-by-SA 3.0): - cottages_glass_pane.png (modification of default_glass.png) - cottages_loam.png (part of a real loam wall) +cottages_glass_pane.png (modification of default_glass.png) +cottages_loam.png (part of a real loam wall) Copyright (C) 2010-2012 celeron55, Perttu Ahola Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0) http://creativecommons.org/licenses/by-sa/3.0/ - cottages_clay.png (washing place, stairs and slab) +cottages_clay.png (washing place, stairs and slab) From the supplied minimal game: - cottages_minimal_wood.png - +cottages_minimal_wood.png + PilzAdam (WTFPL; default and beds mod): - cottages_junglewood.png - cottages_beds_bed_side.png - cottages_beds_bed_side_top_l.png - cottages_beds_bed_side_top_r.png - cottages_beds_bed_top_bottom.png - cottages_beds_bed_top_top.png +cottages_junglewood.png cottages_beds_bed_side.png cottages_beds_bed_side_top_l.png cottages_beds_bed_side_top_r.png +cottages_beds_bed_top_bottom.png cottages_beds_bed_top_top.png Bas080 (CC; see https://forum.minetest.net/viewtopic.php?t=2344) - cottages_rope.png +cottages_rope.png -Derived from Universal schema.jpg by Stefanie Lindener, which can be found here: http://de.wikipedia.org/w/index.php?title=Datei:Universal_schema.jpg&filetimestamp=20060510110309& The texture is CC-by-sa 2.0/de. - cottages_slate.png +Derived from Universal schema.jpg by Stefanie Lindener, which can be found +here: http://de.wikipedia.org/w/index.php?title=Datei:Universal_schema.jpg&filetimestamp=20060510110309& The texture is +CC-by-sa 2.0/de. cottages_slate.png Textures not provided but used (need to be supplied by a default mod): - default_wood.png - default_tree.png - default_dirt.png - default_grass_side.png - default_chest_top.png - default_chest_side.png - default_chest_front.png - default_stick.png - farming_wheat.png +default_wood.png default_tree.png default_dirt.png default_grass_side.png default_chest_top.png default_chest_side.png +default_chest_front.png default_stick.png farming_wheat.png diff --git a/adaptions.lua b/adaptions.lua deleted file mode 100644 index 24782cd..0000000 --- a/adaptions.lua +++ /dev/null @@ -1,104 +0,0 @@ --- some games may not have the default nodes; --- change this so that craft receipes work! - --- used for: anvil, hammer, barrel, steel hatch, stove pipe, wagon wheel, handmill. -cottages.craftitem_steel = "default:steel_ingot"; --- used for: hammer, wood+steel hatch, fence gate, bed, table, bench, shelf, --- washing place, wagon wheel, glass pane, flat wood, handmill, --- operating the treshing floor. -cottages.craftitem_stick = "group:stick"; --- used for: treshing floor, handmill, slate roof, vertical slate -cottages.craftitem_stone = "default:stone"; --- used for: window shutter, half door, half door inverted, fence gate, --- bed, bench, shelf, roof connector, vertical slate -cottages.craftitem_wood = "group:wood"; --- used for: half door -cottages.craftitem_door = "doors:door_wood"; --- used for: small fence -cottages.craftitem_fence = "default:fence_wood"; --- used for: bed (head+foot), wool for tents -cottages.craftitem_wool = "wool:white"; --- used for: washing place, loam -cottages.craftitem_clay = "default:clay"; --- used for: wagon wheel -cottages.craftitem_iron = "default:iron_lump"; --- used for: dirt road, brown roof (if no homedecor is installed) -cottages.craftitem_dirt = "default:dirt"; --- used for: loam -cottages.craftitem_sand = "default:sand"; --- used for: glass pane -cottages.craftitem_glass = "default:glass"; --- used for: reet roof, reet block -cottages.craftitem_papyrus = "default:papyrus"; --- used for: black roof (if no homedecor is installed) -cottages.craftitem_coal_lump = "default:coal_lump"; --- used for: red roof (if no homedecor is installed) -cottages.craftitem_clay_brick = "default:clay_brick"; --- used for: treshing floor -cottages.craftitem_junglewood = "default:junglewood"; -cottages.craftitem_chest_locked = "default:chest_locked"; --- used for: hatch, table -cottages.craftitem_slab_wood = "stairs:slab_wood"; - --- texture used for fence gate and bed posts -cottages.texture_furniture = "default_wood.png"; --- texture for the side of roof nodes -cottages.texture_roof_sides = "default_wood.png"; --- if the default wood node does not exist, use an alternate wood texture --- (which is also used for furnitures and doors in this mod) -if( not( minetest.registered_nodes['default:wood'])) then - cottages.texture_roof_sides = "cottages_minimal_wood.png"; - cottages.texture_furniture = "cottages_minimal_wood.png"; -end - -cottages.texture_chest = {"default_chest_top.png", "default_chest_top.png", "default_chest_side.png", - "default_chest_side.png", "default_chest_side.png", "default_chest_front.png"}; - --- the treshing floor produces wheat seeds -cottages.craftitem_seed_wheat = "farming:seed_wheat"; -cottages.texture_wheat_seed = "farming_wheat_seed.png"; -cottages.texture_stick = "default_stick.png"; - --- texture for roofs where the tree bark is the main roof texture -cottages.textures_roof_wood = "default_tree.png"; -if( not( minetest.registered_nodes["default:tree"])) then - -- realtest has diffrent barks; the spruce one seems to be the most fitting - if( minetest.registered_nodes["trees:spruce_log" ]) then - cottages.textures_roof_wood = "trees_spruce_trunk.png"; - - -- this is also an indicator that we are dealing with realtest; - cottages.craftitem_steel = "metals:pig_iron_ingot"; - -- stone exists, but is hard to obtain; chiseled stone is more suitable - cottages.craftitem_stone = "default:stone_flat"; - -- there are far more diffrent wood tpyes - cottages.craftitem_wood = "group:planks"; - cottages.craftitem_door = "doors:door_birch"; - cottages.craftitem_fence = "group:fence"; - cottages.craftitem_clay = "grounds:clay_lump"; - cottages.craftitem_iron = "group:plank"; -- iron lumps would be too specific - cottages.craftitem_coal_lump = "minerals:charcoal"; - cottages.craftitem_junglewood = "trees:chestnut_planks"; - cottages.craftitem_slab_wood = "group:plank"; - - cottages.texture_chest = { "spruce_chest_top.png", "spruce_chest_top.png", "spruce_chest_side.png", - "spruce_chest_side.png", "spruce_chest_side.png", "spruce_chest_front.png"}; - - -- wheat is called spelt in RealTest - cottages.craftitem_seed_wheat = 'farming:seed_spelt'; - cottages.texture_wheat_seed = 'farming_spelt_seed.png'; - cottages.texture_stick = 'trees_maple_stick.png'; - else - -- does not look so well in this case as it's no bark; but what else shall we do? - cottages.textures_roof_wood = "cottages_minimal_wood.png"; - end -end - -if( minetest.get_modpath("moreblocks") - and minetest.registered_nodes[ "moreblocks:slab_wood" ]) then - cottages.craftitem_slab_wood = "moreblocks:slab_wood"; -end - -if( not( minetest.registered_nodes["wool:white"])) then - cottages.craftitem_wool = "cottages:wool"; -end - diff --git a/alias.lua b/alias.lua deleted file mode 100644 index 8600a92..0000000 --- a/alias.lua +++ /dev/null @@ -1,40 +0,0 @@ - -minetest.register_alias("random_buildings:roof", "cottages:roof_wood"); -minetest.register_alias("random_buildings:roof_connector", "cottages:roof_connector_wood"); -minetest.register_alias("random_buildings:roof_flat", "cottages:roof_flat_wood"); -minetest.register_alias("random_buildings:roof_wood", "cottages:roof_wood"); -minetest.register_alias("random_buildings:roof_connector_wood", "cottages:roof_connector_wood"); -minetest.register_alias("random_buildings:roof_flat_wood", "cottages:roof_flat_wood"); -minetest.register_alias("random_buildings:roof_straw", "cottages:roof_straw"); -minetest.register_alias("random_buildings:roof_connector_straw", "cottages:roof_connector_straw"); -minetest.register_alias("random_buildings:roof_flat_straw", "cottages:roof_flat_straw"); -minetest.register_alias("random_buildings:barrel", "cottages:barrel"); -minetest.register_alias("random_buildings:barrel_open", "cottages:barrel_open"); -minetest.register_alias("random_buildings:barrel_lying", "cottages:barrel_lying"); -minetest.register_alias("random_buildings:barrel_lying_open", "cottages:barrel_lying_open"); -minetest.register_alias("random_buildings:tub", "cottages:tub"); -minetest.register_alias("random_buildings:window_shutter_open", "cottages:window_shutter_open"); -minetest.register_alias("random_buildings:window_shutter_closed", "cottages:window_shutter_closed"); -minetest.register_alias("random_buildings:half_door", "cottages:half_door"); -minetest.register_alias("random_buildings:half_door_inverted", "cottages:half_door_inverted"); -minetest.register_alias("random_buildings:gate_closed", "cottages:gate_closed"); -minetest.register_alias("random_buildings:gate_open", "cottages:gate_open"); -minetest.register_alias("random_buildings:bed_foot", "cottages:bed_foot"); -minetest.register_alias("random_buildings:bed_head", "cottages:bed_head"); -minetest.register_alias("random_buildings:sleeping_mat", "cottages:sleeping_mat"); -minetest.register_alias("random_buildings:loam", "cottages:loam"); -minetest.register_alias("random_buildings:bench", "cottages:bench"); -minetest.register_alias("random_buildings:table", "cottages:table"); -minetest.register_alias("random_buildings:shelf", "cottages:shelf"); -minetest.register_alias("random_buildings:stovepipe", "cottages:stovepipe"); -minetest.register_alias("random_buildings:washing", "cottages:washing"); -minetest.register_alias("random_buildings:wagon_wheel", "cottages:wagon_wheel"); -minetest.register_alias("random_buildings:feldweg", "cottages:feldweg"); -minetest.register_alias("random_buildings:straw_ground", "cottages:straw_ground"); -minetest.register_alias("random_buildings:glass_pane", "cottages:glass_pane"); -minetest.register_alias("random_buildings:straw_mat", "cottages:straw_mat"); -minetest.register_alias("random_buildings:straw_bale", "cottages:straw_bale"); -minetest.register_alias("random_buildings:straw", "cottages:straw"); -minetest.register_alias("random_buildings:chest_private", "cottages:chest_private"); -minetest.register_alias("random_buildings:chest_work", "cottages:chest_work"); -minetest.register_alias("random_buildings:chest_storage", "cottages:chest_storage"); diff --git a/api/init.lua b/api/init.lua new file mode 100644 index 0000000..96701fd --- /dev/null +++ b/api/init.lua @@ -0,0 +1,5 @@ +cottages.api = {} + +cottages.dofile("api", "register_machine") + +cottages.dofile("api", "legacy") diff --git a/api/legacy.lua b/api/legacy.lua new file mode 100644 index 0000000..83bc7c2 --- /dev/null +++ b/api/legacy.lua @@ -0,0 +1,5 @@ +cottages.handmill_product = { + __newindex = function(t, k, v) + cottages.straw.register_quern_craft({input = k, output = v}) + end +} diff --git a/api/register_machine.lua b/api/register_machine.lua new file mode 100644 index 0000000..291df05 --- /dev/null +++ b/api/register_machine.lua @@ -0,0 +1,261 @@ +local S = cottages.S +local F = minetest.formspec_escape +local FS = function(...) return F(S(...)) end + +local player_can_use = cottages.util.player_can_use +local toggle_public = cottages.util.toggle_public + +local items_equals = futil.items_equals + +function cottages.api.update_formspec(pos) + +end + +function cottages.api.register_machine(name, def) + local update_formspec + + if def.get_fs_parts then + function update_formspec(pos) + -- TODO instead create "public button formspec" api call, to generate this. works better w/ fs_layout + local fs_parts = def.get_fs_parts(pos) + + table.insert(fs_parts, ("button[6.0,1.5;1.5,0.5;public;%s]"):format(FS("public?"))) + + local meta = minetest.get_meta(pos) + local public = meta:get_int("public") + + if public == 0 then + local owner = meta:get_string("owner") + table.insert(fs_parts, ("label[6.1,2.1;%s]"):format(FS("owner: @1", owner))) + + elseif public == 1 then + table.insert(fs_parts, ("label[6.1,2.1;%s]"):format(FS("(protected)"))) + + elseif public == 2 then + table.insert(fs_parts, ("label[6.1,2.1;%s]"):format(FS("(public)"))) + end + + meta:set_string("formspec", table.concat(fs_parts, "")) + end + end + + local update_infotext + if def.get_info then + function update_infotext(pos) + local info = def.get_info(pos) + + local meta = minetest.get_meta(pos) + local public = meta:get_int("public") + if public == 0 then + local owner = meta:get("owner") + meta:set_string("infotext", S("@1 (owned by @2)", info, owner)) + + elseif public == 1 then + meta:set_string("infotext", S("protected @1", info)) + + elseif public == 2 then + meta:set_string("infotext", S("public @1", info)) + + else + meta:set_string("infotext", "ERROR IN INFOTEXT") + end + end + end + + minetest.register_node(name, { + description = def.description, + short_description = def.short_description, + drawtype = def.drawtype or "normal", + mesh = def.mesh, + node_box = def.node_box, + selection_box = def.selection_box or def.node_box, + collision_box = def.collision_box or def.selection_box or def.node_box, + paramtype = def.paramtype or "light", + paramtype2 = def.paramtype2 or "facedir", + tiles = def.tiles, + is_ground_content = false, + groups = def.groups, + sounds = def.sounds, + + after_place_node = function(pos, placer) + local meta = minetest.get_meta(pos) + + if def.inv_info then + local inv = meta:get_inventory() + for inv_name, size in pairs(def.inv_info) do + inv:set_size(inv_name, size) + end + end + + local owner = placer:get_player_name() + meta:set_string("owner", owner or "") + if update_infotext then update_infotext(pos) end + if update_formspec then update_formspec(pos) end + end, + + on_receive_fields = function(pos, formname, fields, sender) + if fields.public and toggle_public(pos, sender) then + if update_infotext then update_infotext(pos) end + if update_formspec then update_formspec(pos) end + end + end, + + can_dig = function(pos, player) + if not minetest.is_player(player) then + return false + end + + local meta = minetest.get_meta(pos) + + if def.inv_info then + local inv = meta:get_inventory() + for inv_name in pairs(def.inv_info) do + if not inv:is_empty(inv_name) then + return false + end + end + end + + if def.can_dig and not def.can_dig(pos, player) then + return false + end + + local player_name = player:get_player_name() + local owner = meta:get("owner") + local public = meta:get_int("public") + + return owner == player_name or ( + (public > 0 or owner == "" or owner == " ") and not minetest.is_protected(pos, player_name) + ) + end, + + allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player) + if not player_can_use(pos, player) then + return 0 + end + + if def.allow_metadata_inventory_move then + return def.allow_metadata_inventory_move(pos, from_list, from_index, to_list, to_index, count, player) + end + + return count + end, + + allow_metadata_inventory_put = function(pos, listname, index, stack, player) + if not player_can_use(pos, player) then + return 0 + end + + if def.allow_metadata_inventory_put then + return def.allow_metadata_inventory_put(pos, listname, index, stack, player) + end + + return stack:get_count() + end, + + allow_metadata_inventory_take = function(pos, listname, index, stack, player) + if not player_can_use(pos, player) then + return 0 + end + + if def.allow_metadata_inventory_take then + return def.allow_metadata_inventory_take(pos, listname, index, stack, player) + end + + return stack:get_count() + end, + + on_metadata_inventory_put = function(pos, listname, index, stack, player) + local meta = minetest.get_meta(pos) + meta:set_int("used", 0) + + if def.on_metadata_inventory_put then + def.on_metadata_inventory_put(pos, listname, index, stack, player) + end + + if update_infotext then update_infotext(pos) end + if update_formspec then update_formspec(pos) end + end, + + on_metadata_inventory_take = function(pos, listname, index, stack, player) + local meta = minetest.get_meta(pos) + meta:set_int("used", 0) + + if def.on_metadata_inventory_take then + def.on_metadata_inventory_take(pos, listname, index, stack, player) + end + + if update_infotext then update_infotext(pos) end + if update_formspec then update_formspec(pos) end + end, + + on_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player) + local meta = minetest.get_meta(pos) + meta:set_int("used", 0) + + if def.on_metadata_inventory_move then + def.on_metadata_inventory_move(pos, from_list, from_index, to_list, to_index, count, player) + end + + if update_infotext then update_infotext(pos) end + if update_formspec then update_formspec(pos) end + end, + + on_punch = function(pos, node, puncher, pointed_thing) + if not (def.use and pos and puncher and player_can_use(pos, puncher)) then + return + end + + if def.use(pos, puncher) then + local meta = minetest.get_meta(pos) + meta:set_int("used", 1) + if update_infotext then update_infotext(pos) end + if update_formspec then update_formspec(pos) end + end + end, + + on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) + if not (def.rightclick and pos and clicker and itemstack and player_can_use(pos, clicker)) then + return + end + + local rv = def.rightclick(pos, clicker, ItemStack(itemstack)) + + if rv and not items_equals(rv, itemstack) then + local meta = minetest.get_meta(pos) + meta:set_int("used", 1) + if update_infotext then update_infotext(pos) end + if update_formspec then update_formspec(pos) end + end + + return rv + end, + + on_timer = def.on_timer, + + on_blast = function() + end, + }) + + if update_formspec then + minetest.register_lbm({ + name = ("cottages:update_formspec_%s"):format(name:gsub(":", "_")), + label = ("update %s formspec"):format(name), + nodenames = {name}, + run_at_every_load = true, + action = update_formspec, + }) + + else + minetest.register_lbm({ + name = ("cottages:update_formspec_%s"):format(name:gsub(":", "_")), + label = ("remove %s formspec"):format(name), + nodenames = {name}, + run_at_every_load = true, + action = function(pos) + local meta = minetest.get_meta(pos) + meta:set_string("formspec", "") + end, + }) + end +end diff --git a/compat/adventuretest.lua b/compat/adventuretest.lua new file mode 100644 index 0000000..1d99f57 --- /dev/null +++ b/compat/adventuretest.lua @@ -0,0 +1,10 @@ +-- search for the workbench in AdventureTest +local workbench = minetest.registered_nodes["workbench:3x3"] +if workbench then + local cottages_table_def = minetest.registered_nodes["cottages:table"] + + minetest.override_item("cottages:table", { + tiles = {workbench.tiles[1], cottages_table_def.tiles[1]}, + on_rightclick = workbench.on_rightclick + }) +end diff --git a/compat/init.lua b/compat/init.lua new file mode 100644 index 0000000..2d921e8 --- /dev/null +++ b/compat/init.lua @@ -0,0 +1,5 @@ + +if cottages.has.workbench then + cottages.dofile("compat", "adventuretest") + cottages.dofile("compat", "realtest") +end diff --git a/compat/realtest.lua b/compat/realtest.lua new file mode 100644 index 0000000..a1bf468 --- /dev/null +++ b/compat/realtest.lua @@ -0,0 +1,15 @@ +-- search for the workbench from RealTest +local workbench = minetest.registered_nodes["workbench:work_bench_birch"] + +if workbench then + local cottages_table_def = minetest.registered_nodes["cottages:table"] + + minetest.override_item("cottages:table", { + tiles = {workbench.tiles[1], cottages_table_def.tiles[1]}, + on_construct = workbench.on_construct, + can_dig = workbench.can_dig, + on_metadata_inventory_take = workbench.on_metadata_inventory_take, + on_metadata_inventory_move = workbench.on_metadata_inventory_move, + on_metadata_inventory_put = workbench.on_metadata_inventory_put, + }) +end diff --git a/depends.txt b/depends.txt deleted file mode 100644 index d0220ae..0000000 --- a/depends.txt +++ /dev/null @@ -1,8 +0,0 @@ -default? -farming? -stairs? -homedecor? -intllib? -trees? -wool? -moreblocks? diff --git a/functions.lua b/functions.lua deleted file mode 100644 index 81d88bc..0000000 --- a/functions.lua +++ /dev/null @@ -1,42 +0,0 @@ - -local S = cottages.S - ---- if no owner is set, all players may use the node; else only the owner -cottages.player_can_use = function( meta, player ) - if( not( player) or not( meta )) then - return false; - end - local pname = player:get_player_name(); - local owner = meta:get_string('owner' ); - local public = meta:get_string('public') - if( not(owner) or owner=="" or owner==pname or public=="public") then - return true; - end - return false; -end - - --- call this in on_receive_fields and add suitable buttons in order --- to switch between public and private use -cottages.switch_public = function(pos, formname, fields, sender, name_of_the_thing) - -- switch between public and private - local meta = minetest.get_meta(pos) - local public = meta:get_string("public") - local owner = meta:get_string("owner") - if( sender and sender:get_player_name() == owner and fields.public) then - if( public ~= "public") then - meta:set_string("public", "public") - meta:set_string("infotext", - S("Public "..name_of_the_thing.." (owned by %s)"):format(owner)) - minetest.chat_send_player(owner, - S("Your "..name_of_the_thing.." can now be used by other players as well.")) - else - meta:set_string("public", "") - meta:set_string("infotext", - S("Private "..name_of_the_thing.." (owned by %s)"):format(owner)) - minetest.chat_send_player(owner, - S("Your "..name_of_the_thing.." can only be used by yourself.")) - end - return true - end -end diff --git a/init.lua b/init.lua index 3874218..3cca7c7 100644 --- a/init.lua +++ b/init.lua @@ -1,105 +1,46 @@ +local modname = minetest.get_current_modname() +local modpath = minetest.get_modpath(modname) +local S = minetest.get_translator(modname) --- Version: 2.2 --- Autor: Sokomine --- License: GPLv3 --- --- Modified: --- 11.03.19 Adjustments for MT 5.x --- cottages_feldweg_mode is now a setting in minetest.conf --- 27.07.15 Moved into its own repository. --- Made sure textures and craft receipe indigrents are available or can be replaced. --- Took care of "unregistered globals" warnings. --- 23.01.14 Added conversion receipes in case of installed castle-mod (has its own anvil) --- 23.01.14 Added hammer and anvil as decoration and for repairing tools. --- Added hatches (wood and steel). --- Changed the texture of the fence/handrail. --- 17.01.13 Added alternate receipe for fences in case of interference due to xfences --- 14.01.13 Added alternate receipes for roof parts in case homedecor is not installed. --- Added receipe for stove pipe, tub and barrel. --- Added stairs/slabs for dirt road, loam and clay --- Added fence_small, fence_corner and fence_end, which are useful as handrails and fences --- If two or more window shutters are placed above each other, they will now all close/open simultaneously. --- Added threshing floor. --- Added hand-driven mill. +cottages = { + version = os.time({year = 2022, month = 9, day = 29}), + fork = "fluxionary", -cottages = {} + modname = modname, + modpath = modpath, + S = S, --- Boilerplate to support localized strings if intllib mod is installed. -if minetest.get_modpath( "intllib" ) and intllib then - cottages.S = intllib.Getter() -else - cottages.S = function(s) return s end -end + has = { + bucket = minetest.get_modpath("bucket"), + default = minetest.get_modpath("default"), + doors = minetest.get_modpath("doors"), + env_sounds = minetest.get_modpath("env_sounds"), + ethereal = minetest.get_modpath("ethereal"), + farming = minetest.get_modpath("farming"), + moreblocks = minetest.get_modpath("moreblocks"), + node_entity_queue = minetest.get_modpath("node_entity_queue"), + player_api = minetest.get_modpath("player_api"), + player_monoids = minetest.get_modpath("player_monoids"), + stairs = minetest.get_modpath("stairs"), + stairsplus = minetest.get_modpath("stairsplus"), + stamina = minetest.get_modpath("stamina") and minetest.global_exists("stamina") and stamina.exhaust_player, + technic = minetest.get_modpath("technic"), + unified_inventory = minetest.get_modpath("unified_inventory"), + wool = minetest.get_modpath("wool"), + workbench = minetest.get_modpath("workbench"), + }, -cottages.sounds = {} --- MineClone2 needs special treatment; default is only needed for --- crafting materials and sounds (less important) -if( not( minetest.get_modpath("default"))) then - default = {}; - cottages.sounds.wood = nil - cottages.sounds.dirt = nil - cottages.sounds.leaves = nil - cottages.sounds.stone = nil -else - cottages.sounds.wood = default.node_sound_wood_defaults() - cottages.sounds.dirt = default.node_sound_dirt_defaults() - cottages.sounds.stone = default.node_sound_stone_defaults() - cottages.sounds.leaves = default.node_sound_leaves_defaults() -end + log = function(level, messagefmt, ...) + return minetest.log(level, ("[%s] %s"):format(modname, messagefmt:format(...))) + end, --- the straw from default comes with stairs as well and might replace --- cottages:roof_connector_straw and cottages:roof_flat_straw --- however, that does not look very good -if( false and minetest.registered_nodes["farming:straw"]) then - cottages.straw_texture = "farming_straw.png" - cottages.use_farming_straw_stairs = true -else - cottages.straw_texture = "cottages_darkage_straw.png" -end ---cottages.config_use_mesh_barrel = false; ---cottages.config_use_mesh_handmill = true; + dofile = function(...) + return dofile(table.concat({modpath, ...}, DIR_DELIM) .. ".lua") + end, +} --- set alternate crafting materials and textures where needed --- (i.e. in combination with realtest) -dofile(minetest.get_modpath("cottages").."/adaptions.lua"); - --- add to this table what you want the handmill to convert; --- add a stack size if you want a higher yield -cottages.handmill_product = {}; -cottages.handmill_product[ cottages.craftitem_seed_wheat ] = 'farming:flour 1'; ---[[ some examples: -cottages.handmill_product[ 'default:cobble' ] = 'default:gravel'; -cottages.handmill_product[ 'default:gravel' ] = 'default:sand'; -cottages.handmill_product[ 'default:sand' ] = 'default:dirt 2'; -cottages.handmill_product[ 'flowers:rose' ] = 'dye:red 6'; -cottages.handmill_product[ 'default:cactus' ] = 'dye:green 6'; -cottages.handmill_product[ 'default:coal_lump'] = 'dye:black 6'; ---]] --- process that many inputs per turn -cottages.handmill_max_per_turn = 20; -cottages.handmill_min_per_turn = 0; - -dofile(minetest.get_modpath("cottages").."/functions.lua"); - --- uncomment parts you do not want -dofile(minetest.get_modpath("cottages").."/nodes_furniture.lua"); -dofile(minetest.get_modpath("cottages").."/nodes_historic.lua"); -dofile(minetest.get_modpath("cottages").."/nodes_feldweg.lua"); --- allows to dig hay and straw fast -dofile(minetest.get_modpath("cottages").."/nodes_pitchfork.lua"); -dofile(minetest.get_modpath("cottages").."/nodes_straw.lua"); -dofile(minetest.get_modpath("cottages").."/nodes_hay.lua"); -dofile(minetest.get_modpath("cottages").."/nodes_anvil.lua"); -dofile(minetest.get_modpath("cottages").."/nodes_doorlike.lua"); -dofile(minetest.get_modpath("cottages").."/nodes_fences.lua"); -dofile(minetest.get_modpath("cottages").."/nodes_roof.lua"); -dofile(minetest.get_modpath("cottages").."/nodes_barrel.lua"); -dofile(minetest.get_modpath("cottages").."/nodes_mining.lua"); -dofile(minetest.get_modpath("cottages").."/nodes_water.lua"); ---dofile(minetest.get_modpath("cottages").."/nodes_chests.lua"); - --- this is only required and useful if you run versions of the random_buildings mod where the nodes where defined inside that mod -dofile(minetest.get_modpath("cottages").."/alias.lua"); - --- variable no longer needed -cottages.S = nil; +cottages.dofile("settings") +cottages.dofile("util") +cottages.dofile("resources", "init") +cottages.dofile("api", "init") +cottages.dofile("modules", "init") diff --git a/locale/de.txt b/locale/de.txt index d8f8207..7d3cfb9 100644 --- a/locale/de.txt +++ b/locale/de.txt @@ -11,29 +11,22 @@ Anvil = Amboss The workpiece slot is for damaged tools only. = Das Werkstueckfeld gilt nur fuer beschaedigtes Werkzeug. Your tool has been repaired successfully. = Dein Werkzeug wurde erfolgreich repariert. Your workpiece improves. = Dein Werkstueck verbessert sich. -Anvil (owned by %s) = Amboss (gehoert %s) +Anvil (owned by @1) = Amboss (gehoert @1) Workpiece: = Werkstueck Optional = Moegliche storage for = Aufbewahrung fuer your hammer = deinen Hammer -Owner: %s = Besitzer: %s +Owner: @1 = Besitzer: @1 Punch anvil with hammer to = Schlage mit dem Hammer auf den Amboss um repair tool in workpiece-slot. = das Werkzeug im Werkstueckfeld zu reparieren. ### nodes_barrel.lua ### Pour: = Eingiessen Fill: = Ausgiessen -barrel (closed) = Fass (geschlossen) -barrel (open) = Fass (offen) -barrel (closed), lying somewhere = Liegendes Fass (geschlossen) -barrel (opened), lying somewhere = Liegendes Fass (offen) +Barrel (closed) = Fass (geschlossen) +Barrel (open) = Fass (offen) tub = Bottich -### nodes_chests.lua ### -private NPC chest = Private NSC-Truhe -chest for work utils and kitchens = NSC-Truhe fuer Arbeitsutensilien und Kuechen -storage chest = NSC-Lagertruhe - ### nodes_doorlike.lua ### opened window shutters = Offene Fensterlaeden closed window shutters = Geschlossene Fensterlaeden @@ -108,30 +101,30 @@ straw bale = Strohballen straw = Stroh threshing floor = Dreschboden Threshing floor = Dreschboden -Threshing floor (owned by %s) = Dreschboden (gehoert %s) -Public threshing floor (owned by %s) = Öffentlicher Dreschboden (gehoert %s) -Private threshing floor (owned by %s) = Privater Dreschboden (gehoert %s) +Threshing floor (owned by @1) = Dreschboden (gehoert @1) +Public threshing floor (owned by @1) = Öffentlicher Dreschboden (gehoert @1) +Private threshing floor (owned by @1) = Privater Dreschboden (gehoert @1) Harvested wheat: = Geernteter Weizen Straw: = Stroh Seeds: = Koerner -Owner: %s = Besitzer: %s -Punch threshing floor with a stick = Schlage mit einem Stock auf den Dreschboden +Owner: @1 = Besitzer: @1 +Punch threshing floor with a stick = Schlage mit einem Stock auf den Dreschboden to get straw and seeds from wheat. = um Stroh und Koerner vom Weizen zu bekommen. -You have threshed %s wheat (%s are left). = Du hast %s Weizenaehren gedroschen (%s bleiben uebrig). -You have threshed the last %s wheat. = Du hast die letzten %s Weizenaehren gedroschen. +You have threshed @1 wheat (@2 are left). = Du hast @1 Weizenaehren gedroschen (@2 bleiben uebrig). +You have threshed the last @1 wheat. = Du hast die letzten @1 Weizenaehren gedroschen. mill, powered by punching = Muehle, durch Schlagen antreiben Mill, powered by punching = Muehle, durch Schlagen antreiben -Mill, powered by punching (owned by %s) = Muehle, durch Schlagen antreiben (gehoert %s) -Public mill, powered by punching (owned by %s) = Öffentliche Muehle, durch Schlagen antreiben (gehoert %s) -Private mill, powered by punching (owned by %s) = Private Muehle, durch Schlagen antreiben (gehoert %s) +Mill, powered by punching (owned by @1) = Muehle, durch Schlagen antreiben (gehoert @1) +Public mill, powered by punching (owned by @1) = Öffentliche Muehle, durch Schlagen antreiben (gehoert @1) +Private mill, powered by punching (owned by @1) = Private Muehle, durch Schlagen antreiben (gehoert @1) Wheat seeds: = Weizenkoerner Flour: = Mehl Mill = Muehle -Owner: %s = Besitzer: %s +Owner: @1 = Besitzer: @1 Punch this hand-driven mill = Schlage auf diese handbetriebene Muehle to convert wheat seeds into flour. = um Weizenkoerner in Mehl umzuwandeln. -You have grinded %s wheat seeds (%s are left). = Du hast %s Weizenkoerner gemahlen (%s bleiben uebrig). -You have grinded the last %s wheat seeds. = Du hast die letzten %s Weizenkoerner gemahlen. +You have grinded @1 wheat seeds (@2 are left). = Du hast @1 Weizenkoerner gemahlen (@2 bleiben uebrig). +You have grinded the last @1 wheat seeds. = Du hast die letzten @1 Weizenkoerner gemahlen. Your threshing floor can now be used by other players as well. = Dein Dreschboden kann jetzt auch von anderen Spielern benutzt werden. Your mill, powered by punching can now be used by other players as well. = Deine Mühle kann jetzt auch von anderen Spielern benutzt werden. @@ -142,9 +135,9 @@ Your mill, powered by punching can only be used by yourself. = Deine Mühle kann Public? = Oeffentlich? Public tree trunk well = Oeffentlicher Baumstammbrunnen -Public tree trunk well (owned by %s) = Oeffentlicher Baumstammbrunnen (gehoert %s) -Private tree trunk well (owned by %s) = Privater Baumstammbrunnen (gehoert %s) -This tree trunk well is owned by %s. You can't use it. = Dieser Baumstammbrunnen gehoert %s. Du kannst ihn leider nicht benutzen. +Public tree trunk well (owned by @1) = Oeffentlicher Baumstammbrunnen (gehoert @1) +Private tree trunk well (owned by @1) = Privater Baumstammbrunnen (gehoert @1) +This tree trunk well is owned by @1. You can't use it. = Dieser Baumstammbrunnen gehoert @1. Du kannst ihn leider nicht benutzen. Sorry. You have no room for the bucket. Please free some space in your inventory first! = Du hast leider keinen Platz mehr fuer den Eimer. Bitte schaffe erst ein wenig Platz! Your tree trunk well can now be used by other players as well. = Dein Baumstammbrunnen kann jetzt auch von anderen Spielern benutzt werdn. Your tree trunk well can only be used by yourself. = Dein Baumstammbrunnen kann jetzt nur noch von dir selbst benutzt werdn. diff --git a/locale/template.txt b/locale/template.txt index 40c24d3..a5c8039 100644 --- a/locale/template.txt +++ b/locale/template.txt @@ -11,28 +11,26 @@ Anvil = The workpiece slot is for damaged tools only. = Your tool has been repaired successfully. = Your workpiece improves. = -Anvil (owned by %s) = -Workpiece: = -Optional = -storage for = -your hammer = -Owner: %s = -Punch anvil with hammer to = -repair tool in workpiece-slot. = +Anvil (owned by @1) = +Workpiece: = +Optional = +storage for = +your hammer = +Owner: @1 = +Punch anvil with hammer to = +repair tool in workpiece-slot. = ### nodes_barrel.lua ### Pour: = Fill: = -barrel (closed) = -barrel (open) = -barrel (closed), lying somewhere = -barrel (opened), lying somewhere = +Barrel (closed) = +Barrel (open) = tub = ### nodes_chests.lua ### -private NPC chest = -chest for work utils and kitchens = -storage chest = +private NPC chest = +chest for work utils and kitchens = +storage chest = ### nodes_doorlike.lua ### opened window shutters = @@ -61,7 +59,7 @@ open storage shelf (empty) = stovepipe = washing place = Sorry. This washing place is out of water. Please place it above water! = -You feel much cleaner after some washing. = +You feel much cleaner after some washing. = ### nodes_historic.lua ### wagon wheel = @@ -77,7 +75,7 @@ straw ground for animals = simple glass pane = ### nodes_roof.lua ### -Roof straw = +Roof straw = Roof wood = Roof black = Roof red = @@ -107,30 +105,30 @@ straw bale = straw = threshing floor = Threshing floor = -Threshing floor (owned by %s) = -Public threshing floor (owned by %s) = -Private threshing floor (owned by %s) = -Harvested wheat: = -Straw: = -Seeds: = -Owner: %s = -Punch threshing floor with a stick = -to get straw and seeds from wheat. = -You have threshed %s wheat (%s are left). = -You have threshed the last %s wheat. = +Threshing floor (owned by @1) = +Public threshing floor (owned by @1) = +Private threshing floor (owned by @1) = +Harvested wheat: = +Straw: = +Seeds: = +Owner: @1 = +Punch threshing floor with a stick = +to get straw and seeds from wheat. = +You have threshed @1 wheat (@2 are left). = +You have threshed the last @1 wheat. = mill, powered by punching = Mill, powered by punching = -Mill, powered by punching (owned by %s) = -Public mill, powered by punching (owned by %s) = -Private mill, powered by punching (owned by %s) = +Mill, powered by punching (owned by @1) = +Public mill, powered by punching (owned by @1) = +Private mill, powered by punching (owned by @1) = Wheat seeds: = Flour: = Mill = -Owner: %s = +Owner: @1 = Punch this hand-driven mill = to convert wheat seeds into flour. = -You have grinded %s wheat seeds (%s are left). = -You have grinded the last %s wheat seeds. = +You have grinded @1 wheat seeds (@2 are left). = +You have grinded the last @1 wheat seeds. = Your threshing floor can now be used by other players as well. = Your mill, powered by punching can now be used by other players as well. = @@ -141,8 +139,8 @@ Your mill, powered by punching can only be used by yourself. = Public? = Public tree trunk well = -Public tree trunk well (owned by %s) = -This tree trunk well is owned by %s. You can't use it. = +Public tree trunk well (owned by @1) = +This tree trunk well is owned by @1. You can't use it. = Sorry. You have no room for the bucket. Please free some space in your inventory first! = Your tree trunk well can now be used by other players as well. = Your tree trunk well can only be used by yourself. = diff --git a/mod.conf b/mod.conf index 7ca5444..ba70b47 100644 --- a/mod.conf +++ b/mod.conf @@ -1,5 +1,9 @@ name = cottages -description = Contains a lot of blocks that fit to medieval settlements and small cottages. Comes with hammer & anvil to repair tools. Threshing floor and handmill help process grains etc. -optional_depends = default, farming, stairs, homedecor, intllib, trees, wool, moreblocks -author = Sokomine title = Blocks for building cottages. +description = Contains a lot of blocks that fit to medieval settlements and small cottages. Comes with hammer & anvil to repair tools. Threshing floor and handmill help process grains etc. +author = Sokomine +description = Contains nodes for building medieval houses. +url = https://github.com/sokomine/cottages +version = 2022-09-29 +depends = futil +optional_depends = bucket, default, doors, env_sounds, ethereal, farming, moreblocks, node_entity_queue, player_api, player_monoids, stairs, stairsplus, stamina, technic, unified_inventory, wool, workbench diff --git a/models/cottages_handmill.obj b/models/cottages_quern.obj similarity index 100% rename from models/cottages_handmill.obj rename to models/cottages_quern.obj diff --git a/modules/anvil/anvil.lua b/modules/anvil/anvil.lua new file mode 100644 index 0000000..1c0c605 --- /dev/null +++ b/modules/anvil/anvil.lua @@ -0,0 +1,513 @@ +local S = cottages.S +local F = minetest.formspec_escape +local FS = function(...) return F(S(...)) end +local anvil = cottages.anvil + +local add_entity = minetest.add_entity +local get_node = minetest.get_node +local get_objects_in_area = minetest.get_objects_in_area +local serialize = minetest.serialize + +local v_add = vector.add +local v_eq = vector.equals +local v_new = vector.new +local v_sub = vector.subtract + +local get_safe_short_description = futil.get_safe_short_description +local resolve_item = futil.resolve_item + +local has_stamina = cottages.has.stamina + +local repair_amount = cottages.settings.anvil.repair_amount +local hammer_wear = cottages.settings.anvil.hammer_wear +local formspec_enabled = cottages.settings.anvil.formspec_enabled +local tool_hud_enabled = cottages.settings.anvil.tool_hud_enabled +local hud_timeout = cottages.settings.anvil.hud_timeout +local stamina_use = cottages.settings.anvil.stamina +local tool_entity_enabled = cottages.settings.anvil.tool_entity_enabled +local tool_entity_displacement = cottages.settings.anvil.tool_entity_displacement + +local hud_info_by_puncher_name = {} + +local function get_hud_image(tool) + local tool_def = tool:get_definition() + if tool_def then + return tool_def.inventory_image or tool_def.wield_image + end +end + +function anvil.get_anvil_info(pos) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + local input = inv:get_stack("input", 1) + local wear = math.round((65536 - input:get_wear()) / 655.36) + + if input:is_empty() then + return S("anvil") + + elseif input:get_wear() > 0 then + return S("anvil; repairing @1 (@2%)", get_safe_short_description(input), wear) + + else + return S("anvil; @1 is repaired", get_safe_short_description(input)) + end +end + +function anvil.get_anvil_fs_parts() + return { + ("size[8,8]"), + ("image[7,3;1,1;cottages_tool_steelhammer.png]"), + ("label[2.5,1.0;%s]"):format(FS("Workpiece:")), + ("label[6.0,2.7;%s]"):format(FS("Optional")), + ("label[6.0,3.0;%s]"):format(FS("storage for")), + ("label[6.0,3.3;%s]"):format(FS("your hammer")), + ("label[0,0.0;%s]"):format(FS("Anvil")), + ("label[0,3.0;%s]"):format(FS("Punch anvil with hammer to")), + ("label[0,3.3;%s]"):format(FS("repair tool in workpiece-slot.")), + ("list[context;input;2.5,1.5;1,1;]"), + ("list[context;hammer;5,3;1,1;]"), + ("list[current_player;main;0,4;8,4;]"), + ("listring[context;hammer]"), + ("listring[current_player;main]"), + ("listring[context;input]"), + ("listring[current_player;main]"), + } +end + +local function sparks(pos) + pos.y = pos.y + tool_entity_displacement + minetest.add_particlespawner({ + amount = 10, + time = 0.1, + minpos = pos, + maxpos = pos, + minvel = {x = 2, y = 3, z = 2}, + maxvel = {x = -2, y = 1, z = -2}, + minacc = {x = 0, y = -10, z = 0}, + maxacc = {x = 0, y = -10, z = 0}, + minexptime = 0.5, + maxexptime = 1, + minsize = 1, + maxsize = 1, + collisiondetection = true, + vertical = false, + texture = "cottages_anvil_spark.png", + }) +end + +local function update_hud(puncher, tool) + local puncher_name = puncher:get_player_name() + local damage_state = 40 - math.floor(40 * tool:get_wear() / 65535) + local hud_image = get_hud_image(tool) + + local hud1, hud1_def, hud2, hud3, hud3_def + + if hud_info_by_puncher_name[puncher_name] then + if tool_hud_enabled then + hud1, hud2, hud3 = unpack(hud_info_by_puncher_name[puncher_name]) + hud1_def = puncher:hud_get(hud1) + + else + hud2, hud3 = unpack(hud_info_by_puncher_name[puncher_name]) + end + hud3_def = puncher:hud_get(hud3) + end + + if hud3_def and hud3_def.name == "anvil_foreground" then + if tool_hud_enabled and hud1_def and hud1_def.name == "anvil_image" then + puncher:hud_change(hud1, "text", hud_image) + end + puncher:hud_change(hud3, "number", damage_state) + + else + if tool_hud_enabled and hud_image then + hud1 = puncher:hud_add({ + hud_elem_type = "image", + name = "anvil_image", + text = hud_image, + scale = {x = 15, y = 15}, + position = {x = 0.5, y = 0.5}, + alignment = {x = 0, y = 0} + }) + end + hud2 = puncher:hud_add({ + hud_elem_type = "statbar", + name = "anvil_background", + text = "default_cloud.png^[colorize:#ff0000:256", + number = 40, + direction = 0, -- left to right + position = {x = 0.5, y = 0.65}, + alignment = {x = 0, y = 0}, + offset = {x = -320, y = 0}, + size = {x = 32, y = 32}, + }) + hud3 = puncher:hud_add({ + hud_elem_type = "statbar", + name = "anvil_foreground", + text = "default_cloud.png^[colorize:#00ff00:256", + number = damage_state, + direction = 0, -- left to right + position = {x = 0.5, y = 0.65}, + alignment = {x = 0, y = 0}, + offset = {x = -320, y = 0}, + size = {x = 32, y = 32}, + }) + end + + if tool_hud_enabled then + hud_info_by_puncher_name[puncher_name] = {hud1, hud2, hud3, os.time() + hud_timeout} + + else + hud_info_by_puncher_name[puncher_name] = {hud2, hud3, os.time() + hud_timeout} + end +end + +function anvil.use_anvil(pos, puncher) + -- only punching with the hammer is supposed to work + local wielded = puncher:get_wielded_item() + + if wielded:get_name() ~= resolve_item("cottages:hammer") then + return + end + + local puncher_name = puncher:get_player_name() + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + local tool = inv:get_stack("input", 1) + local tool_name = tool:get_name() + + if tool:is_empty() then + return + + elseif not anvil.can_repair(tool) then + -- just to make sure that tool really can't be repaired if it should not + -- (if the check of placing the item in the input slot failed somehow) + minetest.chat_send_player(puncher_name, S("@1 is not repairable by the anvil", tool_name)) + + elseif tool:get_wear() > 0 then + minetest.sound_play({name = "anvil_clang"}, {pos = pos}) + sparks(pos) + + -- do the actual repair + tool:add_wear(-repair_amount) + inv:set_stack("input", 1, tool) + + -- damage the hammer slightly + wielded:add_wear(hammer_wear) + puncher:set_wielded_item(wielded) + + update_hud(puncher, tool) + + if has_stamina then + stamina.exhaust_player(puncher, stamina_use, "cottages:anvil") + end + + else + -- tell the player when the job is done, but only once + if meta:get_int("informed") > 0 then + return + end + + meta:set_int("informed", 1) + + local tool_desc = tool:get_short_description() or tool:get_description() + minetest.chat_send_player(puncher_name, S("Your @1 has been repaired successfully.", tool_desc)) + end +end + +function anvil.rightclick_anvil(pos, clicker, itemstack) + if formspec_enabled or not (pos and itemstack) then + return + end + + local meta = minetest.get_meta(pos) + meta:set_string("formspec", "") + local inv = meta:get_inventory() + local input_stack = inv:get_stack("input", 1) + local hammer_stack = inv:get_stack("hammer", 1) + + local taken + if anvil.allow_metadata_inventory_take(pos, "input", 1, input_stack, clicker) > 0 then + taken = inv:remove_item("input", input_stack) + + elseif anvil.allow_metadata_inventory_take(pos, "hammer", 1, hammer_stack, clicker) > 0 then + taken = inv:remove_item("hammer", hammer_stack) + end + + local can_put = anvil.allow_metadata_inventory_put(pos, "input", 1, itemstack, clicker) + + if can_put == 1 then + inv:add_item("input", itemstack) + itemstack:clear() + meta:set_int("informed", 0) + + elseif taken and not itemstack:is_empty() then + -- put it back + inv:add_item("input", input_stack) + taken = nil + end + + anvil.update_entity(pos) + + return taken or itemstack +end + +function anvil.get_entity(pos) + local to_return + + for _, obj in ipairs(get_objects_in_area(v_sub(pos, 0.5), v_add(pos, 0.5))) do + local ent = obj:get_luaentity() + if ent and ent.name == "cottages:anvil_item" then + local ent_pos = ent.pos + if not ent_pos then + obj:remove() + + elseif v_eq(ent_pos, pos) then + if to_return then + obj:remove() + + else + to_return = obj + end + end + end + end + + return to_return +end + +function anvil.clear_entity(pos) + local obj = anvil.get_entity(pos) + if obj then + obj:remove() + end +end + +function anvil.add_entity(pos) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + + if inv:is_empty("input") then + return + end + + local tool = inv:get_stack("input", 1) + local tool_name = tool:get_name() + local node = get_node(pos) + + local entity_pos = v_add(pos, v_new(0, tool_entity_displacement, 0)) + + local obj = add_entity(entity_pos, "cottages:anvil_item", serialize({pos, tool_name})) + + if obj then + local yaw = math.pi * 2 - node.param2 * math.pi / 2 + obj:set_rotation({ x = -math.pi / 2, y = yaw, z = 0}) -- x is pitch + end +end + +function anvil.update_entity(pos) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + local tool = inv:get_stack("input", 1) + local tool_name = tool:get_name() + local obj = anvil.get_entity(pos) + + if tool:is_empty() and obj then + anvil.clear_entity(pos) + + elseif obj then + local e = obj:get_luaentity() + if e.item ~= tool_name then + e.item = tool_name + obj:set_properties({wield_item = tool_name}) + end + + elseif tool_entity_enabled and not tool:is_empty() then + anvil.add_entity(pos) + end +end + +function anvil.allow_metadata_inventory_put(pos, listname, index, stack, player) + local count = stack:get_count() + if count == 0 then + return count + end + + local stack_name = stack:get_name() + + if listname == "hammer" and stack_name ~= resolve_item("cottages:hammer") then + return 0 + end + + if listname == "input" then + local wear = stack:get_wear() + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + + if stack_name == resolve_item("cottages:hammer") and wear == 0 and inv:is_empty("hammer") then + -- we will move it to the hammer slot in on_metadata_inventory_put + return count + end + + local player_name = player and player:get_player_name() + + if wear == 0 or not stack:is_known() then + minetest.chat_send_player(player:get_player_name(), S("The workpiece slot is for damaged tools only.")) + return 0 + end + + if not anvil.can_repair(stack) then + local description = stack:get_short_description() or stack:get_description() + minetest.chat_send_player(player_name, S("@1 cannot be repaired with an anvil.", description)) + return 0 + end + end + + return count +end + +function anvil.allow_metadata_inventory_take(pos, listname, index, stack, player) + return stack:get_count() +end + +function anvil.allow_metadata_inventory_move(pos, from_list, from_index, to_list, to_index, count, player) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + local from_stack = inv:get_stack(from_list, from_index) + + if anvil.allow_metadata_inventory_take(pos, from_list, from_index, from_stack, player) > 0 + and anvil.allow_metadata_inventory_put(pos, to_list, to_index, from_stack, player) > 0 then + return count + end + + return 0 +end + +function anvil.on_metadata_inventory_move(pos, from_list, from_index, to_list, to_index, count, player) + if to_list == "input" then + local meta = minetest.get_meta(pos) + meta:set_int("informed", 0) + end + + anvil.update_entity(pos) +end + +function anvil.on_metadata_inventory_put(pos, listname, index, stack, player) + if listname == "input" and stack:get_name() == resolve_item("cottages:hammer") and stack:get_wear() == 0 then + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + if inv:is_empty("hammer") then + inv:set_stack("hammer", 1, stack) + inv:set_stack("input", 1, ItemStack()) + end + return + end + + if listname == "input" then + local meta = minetest.get_meta(pos) + meta:set_int("informed", 0) + end + + anvil.update_entity(pos) +end + +function anvil.on_metadata_inventory_take(pos, listname, index, stack, player) + anvil.update_entity(pos) +end + +function anvil.preserve_metadata(pos, oldnode, oldmeta, drops) + for _, item in ipairs(drops) do + if item:get_name() == "cottages:anvil" then + local drop_meta = item:get_meta() + local owner = oldnode:get_string("owner") + + if owner == "" then + drop_meta:set_int("shared", 1) + drop_meta:set_string("description", S("Anvil (public)")) + + elseif owner == " " then + drop_meta:set_int("shared", 2) + drop_meta:set_string("description", S("Anvil (protected)")) + end + end + end + return drops +end + +cottages.api.register_machine("cottages:anvil", { + description = S("anvil"), + drawtype = "nodebox", + -- the nodebox model comes from realtest + node_box = { + type = "fixed", + fixed = { + {-0.5, -0.5, -0.3, 0.5, -0.4, 0.3}, + {-0.35, -0.4, -0.25, 0.35, -0.3, 0.25}, + {-0.3, -0.3, -0.15, 0.3, -0.1, 0.15}, + {-0.35, -0.1, -0.2, 0.35, 0.1, 0.2}, + }, + }, + tiles = {"cottages_stone.png^[colorize:#000:192"}, + groups = {cracky = 2}, + sounds = cottages.sounds.metal, + + inv_info = { + input = 1, + hammer = 1, + }, + + use = anvil.use_anvil, + rightclick = anvil.rightclick_anvil, + get_fs_parts = formspec_enabled and anvil.get_anvil_fs_parts, + get_info = anvil.get_anvil_info, + + on_metadata_inventory_move = anvil.on_metadata_inventory_move, + on_metadata_inventory_put = anvil.on_metadata_inventory_put, + on_metadata_inventory_take = anvil.on_metadata_inventory_take, + + allow_metadata_inventory_move = anvil.allow_metadata_inventory_move, + allow_metadata_inventory_put = anvil.allow_metadata_inventory_put, + allow_metadata_inventory_take = anvil.allow_metadata_inventory_take, +}) + +-- clear hud info +minetest.register_globalstep(function() + local now = os.time() + + for puncher_name, hud_info in pairs(hud_info_by_puncher_name) do + local puncher = minetest.get_player_by_name(puncher_name) + local hud1, hud2, hud3, hud_expire_time + if tool_hud_enabled then + hud1, hud2, hud3, hud_expire_time = unpack(hud_info) + + else + hud2, hud3, hud_expire_time = unpack(hud_info) + end + + if puncher then + if now > hud_expire_time then + if tool_hud_enabled then + local hud1_def = puncher:hud_get(hud1) + if hud1_def and hud1_def.name == "anvil_image" then + puncher:hud_remove(hud1) + end + end + + local hud2_def = puncher:hud_get(hud2) + if hud2_def and hud2_def.name == "anvil_background" then + puncher:hud_remove(hud2) + end + + local hud3_def = puncher:hud_get(hud3) + if hud3_def and hud3_def.name == "anvil_foreground" then + puncher:hud_remove(hud3) + end + + hud_info_by_puncher_name[puncher_name] = nil + end + + else + hud_info_by_puncher_name[puncher_name] = nil + end + end +end) diff --git a/modules/anvil/api.lua b/modules/anvil/api.lua new file mode 100644 index 0000000..945cec8 --- /dev/null +++ b/modules/anvil/api.lua @@ -0,0 +1,15 @@ +local api = cottages.anvil + +function api.make_unrepairable(itemstring) + local def = minetest.registered_items[itemstring] + local groups = table.copy(def.groups or {}) + groups.not_repaired_by_anvil = 1 + minetest.override_item(itemstring, {groups = groups}) +end + +function api.can_repair(tool_stack) + if type(tool_stack) == "string" then + tool_stack = ItemStack(tool_stack) + end + return tool_stack:is_known() and minetest.get_item_group(tool_stack:get_name(), "not_repaired_by_anvil") == 0 +end diff --git a/modules/anvil/compat.lua b/modules/anvil/compat.lua new file mode 100644 index 0000000..7fc284c --- /dev/null +++ b/modules/anvil/compat.lua @@ -0,0 +1,27 @@ + +if cottages.has.technic then + -- make rechargeable technic tools unrepairable` + cottages.anvil.make_unrepairable("technic:water_can") + cottages.anvil.make_unrepairable("technic:lava_can") + cottages.anvil.make_unrepairable("technic:flashlight") + cottages.anvil.make_unrepairable("technic:battery") + cottages.anvil.make_unrepairable("technic:vacuum") + cottages.anvil.make_unrepairable("technic:prospector") + cottages.anvil.make_unrepairable("technic:sonic_screwdriver") + cottages.anvil.make_unrepairable("technic:chainsaw") + cottages.anvil.make_unrepairable("technic:laser_mk1") + cottages.anvil.make_unrepairable("technic:laser_mk2") + cottages.anvil.make_unrepairable("technic:laser_mk3") + cottages.anvil.make_unrepairable("technic:mining_drill") + cottages.anvil.make_unrepairable("technic:mining_drill_mk2") + cottages.anvil.make_unrepairable("technic:mining_drill_mk2_1") + cottages.anvil.make_unrepairable("technic:mining_drill_mk2_2") + cottages.anvil.make_unrepairable("technic:mining_drill_mk2_3") + cottages.anvil.make_unrepairable("technic:mining_drill_mk2_4") + cottages.anvil.make_unrepairable("technic:mining_drill_mk3") + cottages.anvil.make_unrepairable("technic:mining_drill_mk3_1") + cottages.anvil.make_unrepairable("technic:mining_drill_mk3_2") + cottages.anvil.make_unrepairable("technic:mining_drill_mk3_3") + cottages.anvil.make_unrepairable("technic:mining_drill_mk3_4") + cottages.anvil.make_unrepairable("technic:mining_drill_mk3_5") +end diff --git a/modules/anvil/crafts.lua b/modules/anvil/crafts.lua new file mode 100644 index 0000000..ac60f6c --- /dev/null +++ b/modules/anvil/crafts.lua @@ -0,0 +1,56 @@ +local S = cottages.S +local ci = cottages.craftitems + +if ci.steel then + minetest.register_craft({ + output = "cottages:anvil", + recipe = { + {ci.steel, ci.steel, ci.steel}, + {"", ci.steel, ""}, + {ci.steel, ci.steel, ci.steel}}, + }) + + minetest.register_craft({ + output = "cottages:hammer", + recipe = { + {ci.steel}, + {"cottages:anvil"}, + {ci.stick}} + }) +end + +if ci.paper then + local function build_public_string() + local stack = ItemStack("cottages:anvil") + local meta = stack:get_meta() + meta:set_int("shared", 1) + meta:set_string("description", S("Anvil (public)")) + return stack:to_string() + end + + local function build_protected_string() + local stack = ItemStack("cottages:anvil") + local meta = stack:get_meta() + meta:set_int("shared", 2) + meta:set_string("description", S("Anvil (protected)")) + return stack:to_string() + end + + minetest.register_craft({ + output = build_protected_string(), + type = "shapeless", + recipe = {"anvil:anvil", ci.paper} + }) + + minetest.register_craft({ + output = build_public_string(), + type = "shapeless", + recipe = {build_protected_string(), ci.paper} + }) + + minetest.register_craft({ + output = "anvil:anvil", + type = "shapeless", + recipe = {build_public_string(), ci.paper} + }) +end diff --git a/modules/anvil/entity.lua b/modules/anvil/entity.lua new file mode 100644 index 0000000..5195c1e --- /dev/null +++ b/modules/anvil/entity.lua @@ -0,0 +1,65 @@ +local anvil = cottages.anvil + +local deserialize = minetest.deserialize +local serialize = minetest.serialize + +minetest.register_entity("cottages:anvil_item", { + hp_max = 1, + visual = "wielditem", + visual_size = {x = .33, y = .33}, + collisionbox = {0, 0, 0, 0, 0, 0}, + physical = false, + + get_staticdata = function(self) + return serialize({self.pos, self.item}) + end, + + on_activate = function(self, staticdata, dtime_s) + local pos, item = unpack(deserialize(staticdata)) + local obj = self.object + + if not (pos and item and minetest.get_node(pos).name == "cottages:anvil") then + obj:remove() + return + end + + self.pos = pos -- *MUST* set before calling api.get_entity + + local other_obj = anvil.get_entity(pos) + if other_obj and obj ~= other_obj then + obj:remove() + return + end + + self.item = item + + obj:set_properties({wield_item = item}) + end, +}) + +if cottages.settings.anvil.tool_entity_enabled then + -- automatically restore entities lost due to /clearobjects or similar + if cottages.has.node_entity_queue then + node_entity_queue.api.register_node_entity_loader("cottages:anvil", anvil.update_entity) + + else + minetest.register_lbm({ + name = "cottages:anvil_item_restoration", + nodenames = {"cottages:anvil"}, + run_at_every_load = true, + action = function(pos, node, active_object_count, active_object_count_wider) + anvil.update_entity(pos) + end, + }) + end + +else + minetest.register_lbm({ + name = "cottages:anvil_item_removal", + nodenames = {"cottages:anvil"}, + run_at_every_load = true, + action = function(pos, node, active_object_count, active_object_count_wider) + anvil.clear_entity(pos) + end, + }) +end diff --git a/modules/anvil/hammer.lua b/modules/anvil/hammer.lua new file mode 100644 index 0000000..a4684f0 --- /dev/null +++ b/modules/anvil/hammer.lua @@ -0,0 +1,22 @@ +local S = cottages.S + +-- the hammer for the anvil +minetest.register_tool("cottages:hammer", { + description = S("Steel hammer for repairing tools on the anvil"), + image = "cottages_tool_steelhammer.png", + inventory_image = "cottages_tool_steelhammer.png", + + tool_capabilities = { + full_punch_interval = 0.8, + max_drop_level = 1, + groupcaps = { + -- about equal to a stone pick (it's not intended as a tool) + cracky = {times = {[2] = 2.00, [3] = 1.20}, uses = 30, maxlevel = 1}, + }, + damage_groups = {fleshy = 6}, + } +}) + +if cottages.settings.anvil.disable_hammer_repair then + cottages.anvil.make_unrepairable("cottages:hammer") +end diff --git a/modules/anvil/init.lua b/modules/anvil/init.lua new file mode 100644 index 0000000..7b5448a --- /dev/null +++ b/modules/anvil/init.lua @@ -0,0 +1,8 @@ +cottages.anvil = {} + +cottages.dofile("modules", "anvil", "api") +cottages.dofile("modules", "anvil", "anvil") +cottages.dofile("modules", "anvil", "entity") +cottages.dofile("modules", "anvil", "hammer") +cottages.dofile("modules", "anvil", "crafts") +cottages.dofile("modules", "anvil", "compat") diff --git a/modules/barrel/api.lua b/modules/barrel/api.lua new file mode 100644 index 0000000..4b77652 --- /dev/null +++ b/modules/barrel/api.lua @@ -0,0 +1,121 @@ +local max_liquid_amount = cottages.settings.barrel.max_liquid_amount + +local api = cottages.barrel + +api.bucket_empty_by_bucket_full = {} +api.bucket_full_by_empty_and_liquid = {} +api.liquid_by_bucket_full = {} + +api.name_by_liquid = {} +api.texture_by_liquid = {} + +api.input_sound_by_liquid = {} +api.output_sound_by_liquid = {} + +function api.get_barrel_liquid(pos) + local meta = minetest.get_meta(pos) + return meta:get("liquid") +end + +function api.set_barrel_liquid(pos, liquid) + local meta = minetest.get_meta(pos) + meta:set_string("liquid", liquid) +end + +function api.get_liquid_amount(pos) + local meta = minetest.get_meta(pos) + return meta:get_int("amount") +end + +function api.increase_liquid_amount(pos) + local meta = minetest.get_meta(pos) + meta:set_int("amount", meta:get_int("amount") + 1) +end + +function api.decrease_liquid_amount(pos) + local meta = minetest.get_meta(pos) + local amount = meta:get_int("amount") - 1 + meta:set_int("amount", amount) + if amount == 0 then + api.set_barrel_liquid(pos, "") + end +end + +local function empty_and_liquid(bucket_empty, liquid) + return table.concat({bucket_empty, liquid}, "::") +end + +function api.register_barrel_liquid(def) + api.liquid_by_bucket_full[def.bucket_full] = def.liquid + api.bucket_empty_by_bucket_full[def.bucket_full] = def.bucket_empty + + api.bucket_full_by_empty_and_liquid[empty_and_liquid(def.bucket_empty, def.liquid)] = def.bucket_full + + api.name_by_liquid[def.liquid] = def.liquid_name + api.texture_by_liquid[def.liquid] = def.liquid_texture + api.input_sound_by_liquid[def.liquid] = def.liquid_input_sound + api.output_sound_by_liquid[def.liquid] = def.liquid_output_sound +end + +function api.get_bucket_liquid(bucket_full) + return api.liquid_by_bucket_full[bucket_full] +end + +function api.get_bucket_empty(liquid) + return api.bucket_empty_by_liquid[liquid] +end + +function api.get_bucket_empty(bucket_full) + return api.bucket_empty_by_bucket_full[bucket_full] +end + +function api.get_bucket_full(bucket_empty, liquid) + return api.bucket_full_by_empty_and_liquid[empty_and_liquid(bucket_empty, liquid)] +end + +function api.can_fill(pos, bucket_empty) + local liquid = api.get_barrel_liquid(pos) + return liquid and api.get_bucket_full(bucket_empty, liquid) +end + +function api.can_drain(pos, bucket_full) + local barrel_liquid = api.get_barrel_liquid(pos) + local liquid_amount = api.get_liquid_amount(pos) + local bucket_liquid = api.get_bucket_liquid(bucket_full) + + if (not bucket_liquid) or liquid_amount >= max_liquid_amount then + return false + end + + return bucket_liquid and ((not barrel_liquid) or barrel_liquid == bucket_liquid) +end + +function api.add_barrel_liquid(pos, bucket_full) + local liquid = api.get_bucket_liquid(bucket_full) + + if not api.get_barrel_liquid(pos) then + api.set_barrel_liquid(pos, liquid) + end + + api.increase_liquid_amount(pos) + + minetest.sound_play( + {name = api.input_sound_by_liquid[liquid]}, + {pos = pos, loop = false, gain = 0.5, pitch = 2.0} + ) + + return api.get_bucket_empty(bucket_full) +end + +function api.drain_barrel_liquid(pos, bucket_empty) + local liquid = api.get_barrel_liquid(pos) + + api.decrease_liquid_amount(pos) + + minetest.sound_play( + {name = api.output_sound_by_liquid[liquid]}, + {pos = pos, loop = false, gain = 0.5, pitch = 2.0} + ) + + return api.get_bucket_full(bucket_empty, liquid) +end diff --git a/modules/barrel/barrel.lua b/modules/barrel/barrel.lua new file mode 100644 index 0000000..5ec076f --- /dev/null +++ b/modules/barrel/barrel.lua @@ -0,0 +1,168 @@ +local S = cottages.S +local F = minetest.formspec_escape +local FS = function(...) return F(S(...)) end + +local max_liquid_amount = cottages.settings.barrel.max_liquid_amount + +local barrel = cottages.barrel + +function barrel.get_barrel_info(pos) + local liquid = barrel.get_barrel_liquid(pos) + if liquid then + return ("%s (%i/%i)"):format( + barrel.name_by_liquid[liquid], + barrel.get_liquid_amount(pos), + max_liquid_amount + ) + + else + return S("Empty") + end +end + +function barrel.get_barrel_fs_parts(pos) + local parts = { + ("size[8,9]"), + ("label[0,0.0;%s]"):format(FS("barrel (liquid storage)")), + ("label[3,0;%s]"):format(FS("fill:")), + ("list[context;input;3,0.5;1,1;]"), + ("label[5,3.3;%s]"):format(FS("drain:")), + ("list[context;output;5,3.8;1,1;]"), + ("list[current_player;main;0,5;8,4;]"), + ("listring[context;output]"), + ("listring[current_player;main]"), + ("listring[context;input]"), + ("listring[current_player;main]"), + } + + local liquid = barrel.get_barrel_liquid(pos) + local liquid_amount = barrel.get_liquid_amount(pos) + + if liquid then + local liquid_texture = barrel.texture_by_liquid[liquid] + table.insert(parts, ("image[2.6,2;2,3;%s^[resize:99x99^[lowpart:%s:%s]"):format( + F(cottages.textures.furniture), + math.floor(99 * liquid_amount / max_liquid_amount), + F(liquid_texture .. futil.escape_texture("^[resize:99x99")) + )) + table.insert(parts, ("tooltip[2.6,2;2,3;%s]"):format( + F(("%s (%i/%i)"):format( + barrel.name_by_liquid[liquid], + barrel.get_liquid_amount(pos), + max_liquid_amount + ))) + ) + + else + table.insert(parts, ("image[2.6,2;2,3;%s^[resize:99x99^[lowpart:%s:%s]"):format( + F(cottages.textures.furniture), + 0, + F(cottages.textures.furniture .. futil.escape_texture("^[resize:99x99")) + )) + end + + return parts +end + + +function barrel.can_dig(pos, player) + return barrel.get_liquid_amount(pos) == 0 +end + +function barrel.allow_metadata_inventory_move(pos, from_list, from_index, to_list, to_index, count, player) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + local to_stack = inv:get_stack(to_list, to_index) + + if not to_stack:is_empty() then + return 0 + end + + local from_stack = inv:get_stack(from_list, from_index) + local item = from_stack:get_name() + + if to_list == "input" then + if barrel.can_drain(pos, item) then + return 1 + end + + elseif to_list == "output" then + if barrel.can_fill(pos, item) then + return 1 + end + end + + return 0 +end + +function barrel.allow_metadata_inventory_put(pos, listname, index, stack, player) + local item = stack:get_name() + + if listname == "input" then + if barrel.can_drain(pos, item) then + return 1 + end + + elseif listname == "output" then + if barrel.can_fill(pos, item) then + return 1 + end + end + + return 0 +end + +function barrel.on_metadata_inventory_put(pos, listname, index, stack, player) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + local name = stack:get_name() + + if listname == "input" then + local empty = barrel.add_barrel_liquid(pos, name) + inv:set_stack(listname, index, empty) + + elseif listname == "output" then + local full = barrel.drain_barrel_liquid(pos, name) + inv:set_stack(listname, index, full) + end +end + +function barrel.on_metadata_inventory_move(pos, from_list, from_index, to_list, to_index, count, player) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + local stack = inv:get_stack(to_list, to_index) + barrel.on_metadata_inventory_put(pos, to_list, to_index, stack, player) +end + +cottages.api.register_machine("cottages:barrel", { + description = S("barrel"), + paramtype = "light", + paramtype2 = "facedir", + drawtype = "mesh", + mesh = "cottages_barrel_closed.obj", + tiles = {"cottages_barrel.png"}, + is_ground_content = false, + groups = { + snappy = 1, + choppy = 2, + oddly_breakable_by_hand = 1, + flammable = 2 + }, + sounds = cottages.sounds.wood, + + inv_info = { + input = 1, + output = 1, + }, + + can_dig = barrel.can_dig, + + get_fs_parts = barrel.get_barrel_fs_parts, + get_info = barrel.get_barrel_info, + + allow_metadata_inventory_move = barrel.allow_metadata_inventory_move, + allow_metadata_inventory_put = barrel.allow_metadata_inventory_put, + + on_metadata_inventory_move = barrel.on_metadata_inventory_move, + on_metadata_inventory_put = barrel.on_metadata_inventory_put, +}) diff --git a/modules/barrel/compat.lua b/modules/barrel/compat.lua new file mode 100644 index 0000000..00f9985 --- /dev/null +++ b/modules/barrel/compat.lua @@ -0,0 +1,41 @@ +local api = cottages.barrel + +if cottages.has.bucket and cottages.has.default then + local S = minetest.get_translator("default") + + if minetest.registered_items["bucket:bucket_water"] then + api.register_barrel_liquid({ + liquid = "default:water_source", + liquid_name = S("Water"), + liquid_texture = "default_water.png", + liquid_input_sound = cottages.sounds.water_empty, + liquid_output_sound = cottages.sounds.water_fill, + bucket_empty = "bucket:bucket_empty", + bucket_full = "bucket:bucket_water", + }) + end + + if minetest.registered_items["bucket:bucket_river_water"] then + api.register_barrel_liquid({ + liquid = "default:river_water_source", + liquid_name = S("River Water"), + liquid_texture = "default_river_water.png", + liquid_input_sound = cottages.sounds.water_empty, + liquid_output_sound = cottages.sounds.water_fill, + bucket_empty = "bucket:bucket_empty", + bucket_full = "bucket:bucket_river_water", + }) + end + + if minetest.registered_items["bucket:bucket_lava"] then + api.register_barrel_liquid({ + liquid = "default:lava_source", + liquid_name = S("Lava"), + liquid_input_sound = cottages.sounds.lava_empty, + liquid_output_sound = cottages.sounds.lava_fill, + liquid_texture = "default_lava.png", + bucket_empty = "bucket:bucket_empty", + bucket_full = "bucket:bucket_lava", + }) + end +end diff --git a/modules/barrel/convert.lua b/modules/barrel/convert.lua new file mode 100644 index 0000000..1c8d5ad --- /dev/null +++ b/modules/barrel/convert.lua @@ -0,0 +1,23 @@ +local api = cottages.barrel + +local rotations = { + 3 * 4, + 2 * 4, + 4 * 4, + 1 * 4, +} + +minetest.register_lbm({ + label = "Convert lying barrels", + name = "cottages:convert_lying_barrels", + nodenames = {"cottages:barrel_lying", "cottages:barrel_lying_open"}, + run_at_every_load = false, + action = function(pos, node) + node.name = string.gsub(node.name, "_lying", "") + node.param2 = rotations[node.param2 + 1] or 0 + minetest.swap_node(pos, node) + + api.update_infotext(pos) + api.update_formspec(pos) + end +}) diff --git a/modules/barrel/crafts.lua b/modules/barrel/crafts.lua new file mode 100644 index 0000000..0385dc2 --- /dev/null +++ b/modules/barrel/crafts.lua @@ -0,0 +1,36 @@ +local ci = cottages.craftitems + +if ci.wood and ci.steel then + minetest.register_craft({ + output = "cottages:barrel", + recipe = { + {ci.wood, ci.wood, ci.wood}, + {ci.steel, "", ci.steel}, + {ci.wood, ci.wood, ci.wood}, + }, + }) + + minetest.register_craft({ + output = "cottages:barrel_open", + recipe = { + {ci.wood, "", ci.wood}, + {ci.steel, "", ci.steel}, + {ci.wood, ci.wood, ci.wood}, + }, + }) +end + +minetest.register_craft({ + output = "cottages:tub 2", + recipe = { + {"cottages:barrel"}, + }, +}) + +minetest.register_craft({ + output = "cottages:barrel", + recipe = { + {"cottages:tub"}, + {"cottages:tub"}, + }, +}) diff --git a/modules/barrel/init.lua b/modules/barrel/init.lua new file mode 100644 index 0000000..9f2d2a4 --- /dev/null +++ b/modules/barrel/init.lua @@ -0,0 +1,8 @@ +cottages.barrel = {} + +cottages.dofile("modules", "barrel", "api") +cottages.dofile("modules", "barrel", "barrel") +cottages.dofile("modules", "barrel", "nodes") +cottages.dofile("modules", "barrel", "convert") +cottages.dofile("modules", "barrel", "crafts") +cottages.dofile("modules", "barrel", "compat") diff --git a/modules/barrel/nodes.lua b/modules/barrel/nodes.lua new file mode 100644 index 0000000..f7e2a73 --- /dev/null +++ b/modules/barrel/nodes.lua @@ -0,0 +1,44 @@ +local S = cottages.S + +-- this barrel is opened at the top +minetest.register_node("cottages:barrel_open", { + description = S("Barrel (Open)"), + drawtype = "mesh", + paramtype = "light", + paramtype2 = "facedir", + mesh = "cottages_barrel.obj", + tiles = {"cottages_barrel.png"}, + is_ground_content = false, + groups = { + snappy = 1, + choppy = 2, + oddly_breakable_by_hand = 1, + flammable = 2, + }, +}) + +-- let's hope "tub" is the correct english word for "bottich" +minetest.register_node("cottages:tub", { + description = S("tub"), + paramtype = "light", + drawtype = "mesh", + mesh = "cottages_tub.obj", + tiles = {"cottages_barrel.png"}, + selection_box = { + type = "fixed", + fixed = { + {-0.5, -0.5, -0.5, 0.5, -0.1, 0.5}, + }}, + collision_box = { + type = "fixed", + fixed = { + {-0.5, -0.5, -0.5, 0.5, -0.1, 0.5}, + }}, + groups = { + snappy = 1, + choppy = 2, + oddly_breakable_by_hand = 1, + flammable = 2 + }, + is_ground_content = false, +}) diff --git a/modules/doorlike/abms.lua b/modules/doorlike/abms.lua new file mode 100644 index 0000000..34e9e41 --- /dev/null +++ b/modules/doorlike/abms.lua @@ -0,0 +1,23 @@ +-- open shutters in the morning +minetest.register_abm({ + nodenames = {"cottages:window_shutter_closed"}, + interval = 20, -- change this to 600 if your machine is too slow + chance = 3, -- not all people wake up at the same time! + action = function(pos) + if not cottages.doorlike.is_night() then + cottages.doorlike.shutter_open(pos) + end + end +}) + +-- close them at night +minetest.register_abm({ + nodenames = {"cottages:window_shutter_open"}, + interval = 20, -- change this to 600 if your machine is too slow + chance = 2, + action = function(pos) + if cottages.doorlike.is_night() then + cottages.doorlike.shutter_close(pos) + end + end +}) diff --git a/modules/doorlike/api.lua b/modules/doorlike/api.lua new file mode 100644 index 0000000..7b588b9 --- /dev/null +++ b/modules/doorlike/api.lua @@ -0,0 +1,163 @@ +local S = cottages.S + +local api = cottages.doorlike +local stamina_use = cottages.settings.doorlike.stamina +local has_stamina = cottages.has.stamina + +-- propagate shutting/closing of window shutters to window shutters below/above this one +local offsets = { + vector.new(0, 1, 0), + vector.new(0, 2, 0), + vector.new(0, 3, 0), +} + +function api.shutter_operate(pos, old_node_state_name, new_node_state_name) + local new_node = {name = new_node_state_name} + local old_node = minetest.get_node(pos) + new_node.param2 = old_node.param2 + minetest.swap_node(pos, {name = new_node_state_name, param2 = old_node.param2}) + + local stop_up = false + local stop_down = false + + for _, offset in ipairs(offsets) do + local npos = pos + offset + old_node = minetest.get_node(npos) + if old_node.name == old_node_state_name and not stop_up then + new_node.param2 = old_node.param2 + minetest.swap_node(npos, new_node) + else + stop_up = true + end + + npos = pos - offset + old_node = minetest.get_node(npos) + if old_node.name == old_node_state_name and not stop_down then + new_node.param2 = old_node.param2 + minetest.swap_node(npos, new_node) + else + stop_down = true + end + end +end + +function api.shutter_open(pos, puncher) + api.shutter_operate(pos, "cottages:window_shutter_closed", "cottages:window_shutter_open") + if has_stamina then + stamina.exhaust_player(puncher, stamina_use, "cottages:shutter") + end +end + +function api.shutter_close(pos, puncher) + api.shutter_operate(pos, "cottages:window_shutter_open", "cottages:window_shutter_closed") + if has_stamina then + stamina.exhaust_player(puncher, stamina_use, "cottages:shutter") + end +end + +function api.is_night() + -- at this time, sleeping in a bed is not possible + return minetest.get_timeofday() < 0.2 or minetest.get_timeofday() > 0.805 +end + +----------------------------------------------------------------------------------------------------------- +-- a hatch; nodebox definition taken from realtest +----------------------------------------------------------------------------------------------------------- + +-- hatches rotate around their axis +-- old facedir: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,16,17,18,19,20,21,22,23 +local new_facedirs = {10, 19, 4, 13, 2, 18, 22, 14, 20, 16, 0, 12, 11, 3, 7, 21, 9, 23, 5, 1, 8, 15, 6, 17} + +local node_box = { + {-0.49, -0.55, -0.49, -0.3, -0.45, 0.45}, + {0.3, -0.55, -0.3, 0.49, -0.45, 0.45}, + {0.49, -0.55, -0.49, -0.3, -0.45, -0.3}, + {-0.075, -0.55, -0.3, 0.075, -0.45, 0.3}, + {-0.3, -0.55, -0.075, -0.075, -0.45, 0.075}, + {0.075, -0.55, -0.075, 0.3, -0.45, 0.075}, + + {-0.3, -0.55, 0.3, 0.3, -0.45, 0.45}, + + -- hinges + {-0.45, -0.530, 0.45, -0.15, -0.470, 0.525}, + {0.15, -0.530, 0.45, 0.45, -0.470, 0.525}, + + -- handle + {-0.05, -0.60, -0.35, 0.05, -0.40, -0.45}, +} + +local function rotate(unrotated) + local rotated = {} + for _, row in ipairs(unrotated) do + local x1, y1, z1, x2, y2, z2 = unpack(row) + local tmp = x1 + x1 = -x2 + x2 = -tmp + + tmp = y1 + y1 = -z2 + z2 = -y2 + y2 = -z1 + z1 = -tmp + + table.insert(rotated, {x1, y1, z1, x2, y2, z2}) + end + return rotated +end + +function api.register_hatch(nodename, description, texture, receipe_item, def) + if cottages.has.doors then + def = def or {} + def.description = S(description) + def.tile_front = texture + def.tile_side = texture + def.groups = def.groups or {snappy = 2, choppy = 2, oddly_breakable_by_hand = 2} + def.nodebox_closed = { + type = "fixed", + fixed = node_box, + } + def.nodebox_opened = { + type = "fixed", + fixed = rotate(node_box), + } + + doors.register_trapdoor(nodename, def) + + else + minetest.register_node(nodename, { + description = S(description), -- not that there are any other... + drawtype = "nodebox", + -- top, bottom, side1, side2, inner, outer + tiles = {texture}, + paramtype = "light", + paramtype2 = "facedir", + groups = {snappy = 2, choppy = 2, oddly_breakable_by_hand = 2}, + + node_box = { + type = "fixed", + fixed = node_box, + }, + selection_box = { + type = "fixed", + fixed = {-0.5, -0.55, -0.5, 0.5, -0.45, 0.5}, + }, + on_rightclick = function(pos, node, puncher) + if has_stamina then + stamina.exhaust_player(puncher, stamina_use, nodename) + end + + minetest.swap_node(pos, {name = node.name, param2 = new_facedirs[node.param2 + 1]}) + end, + is_ground_content = false, + on_place = minetest.rotate_node, + }) + end + + minetest.register_craft({ + output = nodename, + recipe = { + {"", "", receipe_item}, + {receipe_item, cottages.craftitems.stick, ""}, + } + }) +end diff --git a/modules/doorlike/crafts.lua b/modules/doorlike/crafts.lua new file mode 100644 index 0000000..9ec8933 --- /dev/null +++ b/modules/doorlike/crafts.lua @@ -0,0 +1,74 @@ +local ci = cottages.craftitems + +-- transform opend and closed shutters into each other for convenience +minetest.register_craft({ + output = "cottages:window_shutter_open", + recipe = { + {"cottages:window_shutter_closed"}, + } +}) + +minetest.register_craft({ + output = "cottages:window_shutter_closed", + recipe = { + {"cottages:window_shutter_open"}, + } +}) + +if ci.wood then + minetest.register_craft({ + output = "cottages:window_shutter_open", + recipe = { + {ci.wood, "", ci.wood}, + } + }) +end + +-- transform one half door into another +minetest.register_craft({ + output = "cottages:half_door", + recipe = { + {"cottages:half_door_inverted"}, + } +}) + +minetest.register_craft({ + output = "cottages:half_door_inverted", + recipe = { + {"cottages:half_door"}, + } +}) + +if ci.wood and ci.door then + minetest.register_craft({ + output = "cottages:half_door 2", + recipe = { + {"", ci.wood, ""}, + {"", ci.door, ""}, + } + }) +end + +-- transform open and closed versions into into another for convenience +minetest.register_craft({ + output = "cottages:gate_closed", + recipe = { + {"cottages:gate_open"}, + } +}) + +minetest.register_craft({ + output = "cottages:gate_open", + recipe = { + {"cottages:gate_closed"}, + } +}) + +if ci.stick and ci.wood then + minetest.register_craft({ + output = "cottages:gate_closed", + recipe = { + {ci.stick, ci.stick, ci.wood}, + } + }) +end diff --git a/modules/doorlike/init.lua b/modules/doorlike/init.lua new file mode 100644 index 0000000..93024c0 --- /dev/null +++ b/modules/doorlike/init.lua @@ -0,0 +1,6 @@ +cottages.doorlike = {} + +cottages.dofile("modules", "doorlike", "api") +cottages.dofile("modules", "doorlike", "nodes") +cottages.dofile("modules", "doorlike", "crafts") +cottages.dofile("modules", "doorlike", "abms") diff --git a/modules/doorlike/nodes.lua b/modules/doorlike/nodes.lua new file mode 100644 index 0000000..badca7d --- /dev/null +++ b/modules/doorlike/nodes.lua @@ -0,0 +1,229 @@ +local S = cottages.S + +-- window shutters - they cover half a node to each side +minetest.register_node("cottages:window_shutter_open", { + description = S("opened window shutters"), + drawtype = "nodebox", + tiles = {"cottages_minimal_wood.png"}, + paramtype = "light", + paramtype2 = "facedir", + groups = {snappy = 2, choppy = 2, oddly_breakable_by_hand = 2}, + -- larger than one node but slightly smaller than a half node so that wallmounted torches pose no problem + node_box = { + type = "fixed", + fixed = { + {-0.90, -0.5, 0.4, -0.45, 0.5, 0.5}, + {0.45, -0.5, 0.4, 0.9, 0.5, 0.5}, + }, + }, + selection_box = { + type = "fixed", + fixed = { + {-0.9, -0.5, 0.4, 0.9, 0.5, 0.5}, + }, + }, + on_rightclick = function(pos, node, puncher) + cottages.doorlike.shutter_close(pos, puncher) + end, + is_ground_content = false, +}) + +minetest.register_node("cottages:window_shutter_closed", { + description = S("closed window shutters"), + drawtype = "nodebox", + tiles = {"cottages_minimal_wood.png"}, + paramtype = "light", + paramtype2 = "facedir", + groups = {snappy = 2, choppy = 2, oddly_breakable_by_hand = 2, not_in_creative_inventory = 1}, + node_box = { + type = "fixed", + fixed = { + {-0.5, -0.5, 0.4, -0.05, 0.5, 0.5}, + {0.05, -0.5, 0.4, 0.5, 0.5, 0.5}, + }, + }, + selection_box = { + type = "fixed", + fixed = { + {-0.5, -0.5, 0.4, 0.5, 0.5, 0.5}, + }, + }, + on_rightclick = function(pos, node, puncher) + cottages.doorlike.shutter_open(pos, puncher) + end, + is_ground_content = false, + drop = "cottages:window_shutter_open", +}) + +minetest.register_node("cottages:half_door", { + description = S("half door"), + drawtype = "nodebox", + tiles = {"cottages_minimal_wood.png"}, + paramtype = "light", + paramtype2 = "facedir", + groups = {snappy = 2, choppy = 2, oddly_breakable_by_hand = 2}, + node_box = { + type = "fixed", + fixed = { + {-0.5, -0.5, 0.4, 0.48, 0.5, 0.5}, + }, + }, + selection_box = { + type = "fixed", + fixed = { + {-0.5, -0.5, 0.4, 0.48, 0.5, 0.5}, + }, + }, + on_rightclick = function(pos, node, puncher) + local node2 = minetest.get_node({x = pos.x, y = (pos.y + 1), z = pos.z}) + + local param2 = node.param2 + if param2 % 4 == 1 then + param2 = param2 + 1; --2 + elseif param2 % 4 == 2 then + param2 = param2 - 1; --1 + elseif param2 % 4 == 3 then + param2 = param2 - 3; --0 + elseif param2 % 4 == 0 then + param2 = param2 + 3; --3 + end + minetest.swap_node(pos, {name = "cottages:half_door", param2 = param2}) + -- if the node above consists of a door of the same type, open it as well + -- Note: doors beneath this one are not opened! + -- It is a special feature of these doors that they can be opend partly + if node2 ~= nil and node2.name == node.name and node2.param2 == node.param2 then + minetest.swap_node({x = pos.x, y = (pos.y + 1), z = pos.z}, {name = "cottages:half_door", param2 = param2}) + end + end, + is_ground_content = false, +}) + +minetest.register_node("cottages:half_door_inverted", { + description = S("half door inverted"), + drawtype = "nodebox", + tiles = {"cottages_minimal_wood.png"}, + paramtype = "light", + paramtype2 = "facedir", + groups = {snappy = 2, choppy = 2, oddly_breakable_by_hand = 2}, + node_box = { + type = "fixed", + fixed = { + {-0.5, -0.5, -0.5, 0.48, 0.5, -0.4}, + }, + }, + selection_box = { + type = "fixed", + fixed = { + {-0.5, -0.5, -0.5, 0.48, 0.5, -0.4}, + }, + }, + on_rightclick = function(pos, node, puncher) + local node2 = minetest.get_node({x = pos.x, y = (pos.y + 1), z = pos.z}) + + local param2 = node.param2 + if param2 % 4 == 1 then + param2 = param2 - 1; --0 + elseif param2 % 4 == 0 then + param2 = param2 + 1; --1 + elseif param2 % 4 == 2 then + param2 = param2 + 1; --3 + elseif param2 % 4 == 3 then + param2 = param2 - 1; --2 + end + minetest.swap_node(pos, {name = "cottages:half_door_inverted", param2 = param2}) + -- open upper parts of this door (if there are any) + if node2 ~= nil and node2.name == node.name and node2.param2 == node.param2 then + minetest.swap_node({x = pos.x, y = (pos.y + 1), z = pos.z}, + {name = "cottages:half_door_inverted", param2 = param2}) + end + end, + is_ground_content = false, +}) + +minetest.register_node("cottages:gate_closed", { + description = S("closed fence gate"), + drawtype = "nodebox", + tiles = {cottages.textures.furniture}, + paramtype = "light", + paramtype2 = "facedir", + groups = {snappy = 2, choppy = 2, oddly_breakable_by_hand = 2}, + node_box = { + type = "fixed", + fixed = { + {-0.85, -0.25, -0.02, 0.85, -0.05, 0.02}, + {-0.85, 0.15, -0.02, 0.85, 0.35, 0.02}, + + {-0.80, -0.05, -0.02, -0.60, 0.15, 0.02}, + {0.60, -0.05, -0.02, 0.80, 0.15, 0.02}, + {-0.15, -0.05, -0.02, 0.15, 0.15, 0.02}, + }, + }, + selection_box = { + type = "fixed", + fixed = { + {-0.85, -0.25, -0.1, 0.85, 0.35, 0.1}, + }, + }, + on_rightclick = function(pos, node, puncher) + minetest.swap_node(pos, {name = "cottages:gate_open", param2 = node.param2}) + end, + is_ground_content = false, +}) + +minetest.register_node("cottages:gate_open", { + description = S("opened fence gate"), + drawtype = "nodebox", + tiles = {cottages.textures.furniture}, + paramtype = "light", + paramtype2 = "facedir", + drop = "cottages:gate_closed", + groups = {snappy = 2, choppy = 2, oddly_breakable_by_hand = 2, not_in_creative_inventory = 1}, + node_box = { + type = "fixed", + fixed = { + {-0.85, -0.5, -0.25, 0.85, -0.46, -0.05}, + {-0.85, -0.5, 0.15, 0.85, -0.46, 0.35}, + + {-0.80, -0.5, -0.05, -0.60, -0.46, 0.15}, + {0.60, -0.5, -0.05, 0.80, -0.46, 0.15}, + {-0.15, -0.5, -0.05, 0.15, -0.46, 0.15}, + + }, + }, + selection_box = { + type = "fixed", + fixed = { + {-0.85, -0.5, -0.25, 0.85, -0.3, 0.35}, + }, + }, + on_rightclick = function(pos, node, puncher) + minetest.swap_node(pos, {name = "cottages:gate_closed", param2 = node.param2}) + end, + is_ground_content = false, +}) + +-- further alternate hatch materials: wood, tree, copper_block +cottages.doorlike.register_hatch( + "cottages:hatch_wood", + "wooden hatch", + "cottages_minimal_wood.png", + cottages.craftitems.slab_wood, + { + groups = {node = 1, choppy = 2, oddly_breakable_by_hand = 2, flammable = 2}, + sounds = cottages.sounds.wood, + } +) + +cottages.doorlike.register_hatch( + "cottages:hatch_steel", + "metal hatch", + "cottages_steel_block.png", + cottages.craftitems.steel, + { + groups = {node = 1, cracky = 1, level = 2}, + sounds = cottages.sounds.metal, + sound_open = "doors_steel_door_open", + sound_close = "doors_steel_door_close", + protected = true, + } +) diff --git a/modules/feldweg/api.lua b/modules/feldweg/api.lua new file mode 100644 index 0000000..df277e5 --- /dev/null +++ b/modules/feldweg/api.lua @@ -0,0 +1,331 @@ +local S = cottages.S +local api = cottages.feldweg + +local box_slope = { + type = "fixed", + fixed = { + {-0.5, -0.5, -0.5, 0.5, -0.25, 0.5}, + {-0.5, -0.25, -0.25, 0.5, 0, 0.5}, + {-0.5, 0, 0, 0.5, 0.25, 0.5}, + {-0.5, 0.25, 0.25, 0.5, 0.5, 0.5} + } +} + +local box_slope_long = { + type = "fixed", + fixed = { + {-0.5, -0.5, -1.5, 0.5, -0.10, 0.5}, + {-0.5, -0.25, -1.3, 0.5, -0.25, 0.5}, + {-0.5, -0.25, -1.0, 0.5, 0, 0.5}, + {-0.5, 0, -0.5, 0.5, 0.25, 0.5}, + {-0.5, 0.25, 0, 0.5, 0.5, 0.5} + } +} + +local function simplify_tile(tile) + if type(tile) == "string" then + return tile + + elseif type(tile) == "table" then + if type(tile.name) == "string" then + return tile.name + + else + error(("weird tile %q"):dump(tile)) + end + + else + error(("weird tile %q"):dump(tile)) + end +end + +local function get_textures(tiles, special) + if #tiles == 1 then + local tile1 = simplify_tile(tiles[1]) + return tile1, tile1, tile1, tile1, "cottages_feldweg_surface.png^" .. (special or tile1) + + elseif #tiles == 2 then + local tile1 = simplify_tile(tiles[1]) + local tile2 = simplify_tile(tiles[2]) + return tile1, tile2, tile1, tile1, "cottages_feldweg_surface.png^" .. (special or tile1) + + elseif #tiles == 3 then + local tile1 = simplify_tile(tiles[1]) + local tile2 = simplify_tile(tiles[2]) + local tile3 = simplify_tile(tiles[3]) + return tile1, tile2, tile3, tile3, "cottages_feldweg_surface.png^" .. (special or tile1) + + else + error(("not implemented: %i tiles"):format(#tiles)) + end +end + +local function register_feldweg(name, base_def, def) + minetest.register_node(name, { + description = def.description, + + paramtype = "light", + paramtype2 = "facedir", + legacy_facedir_simple = true, + + drawtype = "mesh", + mesh = def.mesh, + tiles = def.tiles, + collision_box = def.collision_box, + selection_box = def.selection_box, + + is_ground_content = false, + groups = base_def.groups, + sounds = base_def.sounds, + }) + + minetest.register_craft({ + output = name .. " " .. def.output_amount, + recipe = def.recipe + }) + + minetest.register_craft({ + output = def.reverts_to, + recipe = { + {name}, + } + }) +end + +function api.register_feldweg(node, suffix, special) + local def = minetest.registered_nodes[node] + local texture_top, texture_bottom, texture_side, texture_side_with_dent, texture_edges = + get_textures(def.tiles, special) + local desc = futil.get_safe_short_description(node) + local feldweg_name = "cottages:feldweg" .. suffix + + register_feldweg(feldweg_name, def, { + description = S("dirt road on @1", desc), + mesh = "feldweg.obj", + tiles = { + texture_side_with_dent, + texture_side, + texture_bottom, + texture_top, + "cottages_feldweg_surface.png", + texture_edges + }, + recipe = { + {"", "cottages:wagon_wheel", ""}, + {node, node, node}, + }, + output_amount = 3, + reverts_to = node, + }) + + register_feldweg("cottages:feldweg_crossing" .. suffix, def, { + description = S("dirt road crossing on @1", desc), + mesh = "feldweg-crossing.obj", + tiles = { + texture_side_with_dent, + texture_bottom, + texture_top, + "cottages_feldweg_surface.png", + texture_edges + }, + recipe = { + {"", feldweg_name, ""}, + {feldweg_name, feldweg_name, feldweg_name}, + {"", feldweg_name, ""}, + }, + output_amount = 5, + reverts_to = feldweg_name, + }) + + register_feldweg("cottages:feldweg_t_junction" .. suffix, def, { + description = S("dirt road t junction on @1", desc), + mesh = "feldweg-T-junction.obj", + tiles = { + texture_side_with_dent, + texture_side, + texture_bottom, + texture_top, + "cottages_feldweg_surface.png", + texture_edges + }, + recipe = { + {"", feldweg_name, ""}, + {"", feldweg_name, ""}, + {feldweg_name, feldweg_name, feldweg_name}, + }, + output_amount = 5, + reverts_to = feldweg_name, + }) + + register_feldweg("cottages:feldweg_curve" .. suffix, def, { + description = S("dirt road curve on @1", desc), + mesh = "feldweg-curve.obj", + tiles = { + texture_side, + texture_top, + texture_side, + "cottages_feldweg_surface.png", + texture_bottom, + texture_edges + }, + recipe = { + {feldweg_name, "", ""}, + {feldweg_name, "", ""}, + {feldweg_name, feldweg_name, feldweg_name}, + }, + output_amount = 5, + reverts_to = feldweg_name, + }) + + register_feldweg("cottages:feldweg_end" .. suffix, def, { + description = S("dirt road end on @1", desc), + mesh = "feldweg_end.obj", + tiles = { + texture_side_with_dent, + texture_side, + texture_bottom, + texture_top, + texture_edges, + "cottages_feldweg_surface.png" + }, + recipe = { + {feldweg_name, "", feldweg_name}, + {feldweg_name, feldweg_name, feldweg_name}, + }, + output_amount = 5, + reverts_to = feldweg_name, + }) + + register_feldweg("cottages:feldweg_45" .. suffix, def, { + description = S("dirt road 45º on @1", desc), + mesh = "feldweg_45.b3d", + tiles = { + "cottages_feldweg_surface.png", + texture_edges, + texture_side, + texture_bottom, + texture_top, + }, + recipe = { + {feldweg_name, "", feldweg_name}, + {"", feldweg_name, ""}, + {feldweg_name, "", feldweg_name}, + }, + output_amount = 5, + reverts_to = feldweg_name, + }) + + register_feldweg("cottages:feldweg_s_45" .. suffix, def, { + description = S("dirt road 45º edge on @1", desc), + mesh = "feldweg_s_45.b3d", + tiles = { + texture_top, + texture_side, + texture_bottom, + "cottages_feldweg_surface.png", + texture_edges, + }, + recipe = { + {feldweg_name, ""}, + {"", feldweg_name}, + }, + output_amount = 2, + reverts_to = feldweg_name, + }) + + register_feldweg("cottages:feldweg_d_45" .. suffix, def, { + description = S("dirt road 45º double edge on @1", desc), + mesh = "feldweg_d_45.b3d", + tiles = { + texture_side, + texture_bottom, + texture_top, + texture_edges, + "cottages_feldweg_surface.png", + }, + recipe = { + {feldweg_name, "", feldweg_name}, + {"", feldweg_name, ""}, + }, + output_amount = 3, + reverts_to = feldweg_name, + }) + + register_feldweg("cottages:feldweg_l_curve" .. suffix, def, { + description = S("dirt road left curve on @1", desc), + mesh = "feldweg_l_45_curve.b3d", + tiles = { + texture_side, + texture_bottom, + texture_top, + texture_edges, + "cottages_feldweg_surface.png", + }, + recipe = { + {"", "", feldweg_name}, + {feldweg_name, feldweg_name, ""}, + }, + output_amount = 3, + reverts_to = feldweg_name, + }) + + register_feldweg("cottages:feldweg_r_curve" .. suffix, def, { + description = S("dirt road right curve on @1", desc), + mesh = "feldweg_r_45_curve.b3d", + tiles = { + texture_side, + texture_bottom, + texture_top, + texture_edges, + "cottages_feldweg_surface.png", + }, + recipe = { + {feldweg_name, "", ""}, + {"", feldweg_name, feldweg_name}, + }, + output_amount = 3, + reverts_to = feldweg_name, + }) + + register_feldweg("cottages:feldweg_slope" .. suffix, def, { + description = S("dirt road slope on @1", desc), + mesh = "feldweg_slope.obj", + tiles = { + texture_side_with_dent, + texture_side, + texture_bottom, + texture_top, + "cottages_feldweg_surface.png", + texture_edges + }, + collision_box = box_slope, + selection_box = box_slope, + recipe = { + {feldweg_name, ""}, + {feldweg_name, feldweg_name}, + }, + output_amount = 3, + reverts_to = feldweg_name, + }) + + register_feldweg("cottages:feldweg_slope_long" .. suffix, def, { + description = S("dirt road slope long on @1", desc), + mesh = "feldweg_slope_long.obj", + tiles = { + texture_side_with_dent, + texture_side, + texture_bottom, + texture_top, + "cottages_feldweg_surface.png", + texture_edges + }, + collision_box = box_slope_long, + selection_box = box_slope_long, + recipe = { + {feldweg_name, "", ""}, + {feldweg_name, feldweg_name, feldweg_name}, + }, + output_amount = 4, + reverts_to = feldweg_name, + }) +end diff --git a/modules/feldweg/compat_default.lua b/modules/feldweg/compat_default.lua new file mode 100644 index 0000000..73927f2 --- /dev/null +++ b/modules/feldweg/compat_default.lua @@ -0,0 +1,5 @@ +cottages.feldweg.register_feldweg("default:dirt_with_grass", "", "cottages_feldweg_edges.png") +cottages.feldweg.register_feldweg("default:gravel", "_gravel") +cottages.feldweg.register_feldweg("default:dirt_with_coniferous_litter", "_coniferous") +cottages.feldweg.register_feldweg("default:dirt_with_snow", "_snow") +cottages.feldweg.register_feldweg("default:dirt_with_dry_grass", "_dry") diff --git a/modules/feldweg/compat_ethereal.lua b/modules/feldweg/compat_ethereal.lua new file mode 100644 index 0000000..4410180 --- /dev/null +++ b/modules/feldweg/compat_ethereal.lua @@ -0,0 +1,2 @@ + +cottages.feldweg.register_feldweg("ethereal:bamboo_dirt", "_bamboo") diff --git a/modules/feldweg/compat_stairs.lua b/modules/feldweg/compat_stairs.lua new file mode 100644 index 0000000..95a7d18 --- /dev/null +++ b/modules/feldweg/compat_stairs.lua @@ -0,0 +1,18 @@ +local S = cottages.S + +stairs.register_stair_and_slab( + "feldweg", + "cottages:feldweg", + {crumbly = 3}, + { + "cottages_feldweg.png", + "default_dirt.png", + "default_grass.png", + "default_grass.png", + "cottages_feldweg.png", + "cottages_feldweg.png" + }, + S("Dirt Road Stairs"), + S("Dirt Road, half height"), + cottages.sounds.dirt +) diff --git a/modules/feldweg/init.lua b/modules/feldweg/init.lua new file mode 100644 index 0000000..c059441 --- /dev/null +++ b/modules/feldweg/init.lua @@ -0,0 +1,15 @@ +cottages.feldweg = {} + +cottages.dofile("modules", "feldweg", "api") + +if cottages.has.default then + cottages.dofile("modules", "feldweg", "compat_default") +end + +if cottages.has.ethereal then + cottages.dofile("modules", "feldweg", "compat_ethereal") +end + +if cottages.has.stairs then + cottages.dofile("modules", "feldweg", "compat_stairs") +end diff --git a/modules/fences/crafts.lua b/modules/fences/crafts.lua new file mode 100644 index 0000000..5b2c191 --- /dev/null +++ b/modules/fences/crafts.lua @@ -0,0 +1,48 @@ +local ci = cottages.craftitems + +if ci.fence then + minetest.register_craft({ + output = "cottages:fence_small 3", + recipe = { + {ci.fence, ci.fence}, + } + }) +end + +-- xfences can be configured to replace normal fences - which makes them uncraftable +if minetest.get_modpath("xfences") then + minetest.register_craft({ + output = "cottages:fence_small 3", + recipe = { + {"xfences:fence", "xfences:fence"}, + } + }) +end + +minetest.register_craft({ + output = "cottages:fence_corner", + recipe = { + {"cottages:fence_small", "cottages:fence_small"}, + } +}) + +minetest.register_craft({ + output = "cottages:fence_small 2", + recipe = { + {"cottages:fence_corner"}, + } +}) + +minetest.register_craft({ + output = "cottages:fence_end", + recipe = { + {"cottages:fence_small", "cottages:fence_small", "cottages:fence_small"}, + } +}) + +minetest.register_craft({ + output = "cottages:fence_small 3", + recipe = { + {"cottages:fence_end"}, + } +}) diff --git a/modules/fences/init.lua b/modules/fences/init.lua new file mode 100644 index 0000000..80100ca --- /dev/null +++ b/modules/fences/init.lua @@ -0,0 +1,4 @@ +cottages.fences = {} + +cottages.dofile("modules", "fences", "nodes") +cottages.dofile("modules", "fences", "crafts") diff --git a/modules/fences/nodes.lua b/modules/fences/nodes.lua new file mode 100644 index 0000000..a54a25c --- /dev/null +++ b/modules/fences/nodes.lua @@ -0,0 +1,108 @@ +-- 22.01.13 Changed texture to that of the wood from the minimal development game + +local S = cottages.S + +minetest.register_node("cottages:fence_small", { + description = S("small fence"), + drawtype = "nodebox", + -- top, bottom, side1, side2, inner, outer + tiles = {"cottages_minimal_wood.png"}, + paramtype = "light", + paramtype2 = "facedir", + groups = {snappy = 2, choppy = 2, oddly_breakable_by_hand = 2}, + node_box = { + type = "fixed", + fixed = { + {-0.45, -0.35, 0.46, 0.45, -0.20, 0.50}, + {-0.45, 0.00, 0.46, 0.45, 0.15, 0.50}, + {-0.45, 0.35, 0.46, 0.45, 0.50, 0.50}, + + {-0.50, -0.50, 0.46, -0.45, 0.50, 0.50}, + {0.45, -0.50, 0.46, 0.50, 0.50, 0.50}, + }, + }, + selection_box = { + type = "fixed", + fixed = { + {-0.50, -0.50, 0.4, 0.50, 0.50, 0.5}, + }, + }, + is_ground_content = false, +}) + +minetest.register_node("cottages:fence_corner", { + description = S("small fence corner"), + drawtype = "nodebox", + -- top, bottom, side1, side2, inner, outer + tiles = {"cottages_minimal_wood.png"}, + paramtype = "light", + paramtype2 = "facedir", + groups = {snappy = 2, choppy = 2, oddly_breakable_by_hand = 2}, + node_box = { + type = "fixed", + fixed = { + {-0.45, -0.35, 0.46, 0.45, -0.20, 0.50}, + {-0.45, 0.00, 0.46, 0.45, 0.15, 0.50}, + {-0.45, 0.35, 0.46, 0.45, 0.50, 0.50}, + + {-0.50, -0.50, 0.46, -0.45, 0.50, 0.50}, + {0.45, -0.50, 0.46, 0.50, 0.50, 0.50}, + + {0.46, -0.35, -0.45, 0.50, -0.20, 0.45}, + {0.46, 0.00, -0.45, 0.50, 0.15, 0.45}, + {0.46, 0.35, -0.45, 0.50, 0.50, 0.45}, + + {0.46, -0.50, -0.50, 0.50, 0.50, -0.45}, + {0.46, -0.50, 0.45, 0.50, 0.50, 0.50}, + }, + }, + selection_box = { + type = "fixed", + fixed = { + {-0.50, -0.50, -0.5, 0.50, 0.50, 0.5}, + }, + }, + is_ground_content = false, +}) + +minetest.register_node("cottages:fence_end", { + description = S("small fence end"), + drawtype = "nodebox", + -- top, bottom, side1, side2, inner, outer + tiles = {"cottages_minimal_wood.png"}, + paramtype = "light", + paramtype2 = "facedir", + groups = {snappy = 2, choppy = 2, oddly_breakable_by_hand = 2}, + node_box = { + type = "fixed", + fixed = { + {-0.45, -0.35, 0.46, 0.45, -0.20, 0.50}, + {-0.45, 0.00, 0.46, 0.45, 0.15, 0.50}, + {-0.45, 0.35, 0.46, 0.45, 0.50, 0.50}, + + {-0.50, -0.50, 0.46, -0.45, 0.50, 0.50}, + {0.45, -0.50, 0.46, 0.50, 0.50, 0.50}, + + {0.46, -0.35, -0.45, 0.50, -0.20, 0.45}, + {0.46, 0.00, -0.45, 0.50, 0.15, 0.45}, + {0.46, 0.35, -0.45, 0.50, 0.50, 0.45}, + + {0.46, -0.50, -0.50, 0.50, 0.50, -0.45}, + {0.46, -0.50, 0.45, 0.50, 0.50, 0.50}, + + {-0.50, -0.35, -0.45, -0.46, -0.20, 0.45}, + {-0.50, 0.00, -0.45, -0.46, 0.15, 0.45}, + {-0.50, 0.35, -0.45, -0.46, 0.50, 0.45}, + + {-0.50, -0.50, -0.50, -0.46, 0.50, -0.45}, + {-0.50, -0.50, 0.45, -0.46, 0.50, 0.50}, + }, + }, + selection_box = { + type = "fixed", + fixed = { + {-0.50, -0.50, -0.5, 0.50, 0.50, 0.5}, + }, + }, + is_ground_content = false, +}) diff --git a/modules/furniture/api.lua b/modules/furniture/api.lua new file mode 100644 index 0000000..2f014ac --- /dev/null +++ b/modules/furniture/api.lua @@ -0,0 +1,294 @@ +local S = cottages.S +local pts = minetest.pos_to_string + +local api = cottages.furniture + +local attached_to = {} +local attached_at = {} + +function api.allow_attach(pos, player) + if not minetest.is_player(player) then + return false + end + + if attached_to[player] then + -- allow re-attaching to the same spot, but not a different spot + for _, p2 in ipairs(attached_to[player]) do + if vector.equals(pos, p2) then + return true + end + end + + return false + end + + local ps = pts(pos) + if attached_at[ps] and attached_at[ps] ~= player then + -- disallow multiple people to attach to the same spot + return false + end + + return true +end + +function api.get_up(player) + local player_name = player:get_player_name() + + if cottages.has.player_monoids then + player_monoids.speed:del_change(player, "cottages:furniture") + player_monoids.jump:del_change(player, "cottages:furniture") + player_monoids.gravity:del_change(player, "cottages:furniture") + + else + player:set_physics_override(1, 1, 1) + end + + player_api.player_attached[player_name] = nil + player_api.set_animation(player, "stand") + + if attached_to[player] then + for _, pos in ipairs(attached_to[player]) do + attached_at[pos] = nil + end + attached_to[player] = nil + end + + player:set_eye_offset({x = 0, y = 0, z = 0}, {x = 0, y = 0, z = 0}) +end + +function api.stop_moving(player) + if cottages.has.player_monoids then + player_monoids.speed:add_change(player, 0, "cottages:furniture") + player_monoids.jump:add_change(player, 0, "cottages:furniture") + player_monoids.gravity:add_change(player, 0, "cottages:furniture") + + else + player:set_physics_override(0, 0, 0) + end +end + +function api.sit_on_bench(pos, node, player) + if not (cottages.has.player_api and api.allow_attach(pos, player)) then + return + end + + local animation = player_api.get_animation(player) + + if not animation then + -- certain versions of minetest have a broken API + return + elseif animation.animation == "sit" then + api.get_up(player) + + else + -- the bench is not centered; prevent the player from sitting on air + local player_pos = {x = pos.x, y = pos.y, z = pos.z} + local player_name = player:get_player_name() + + if node.param2 == 0 then + player_pos.z = player_pos.z + 0.3 + elseif node.param2 == 1 then + player_pos.x = player_pos.x + 0.3 + elseif node.param2 == 2 then + player_pos.z = player_pos.z - 0.3 + elseif node.param2 == 3 then + player_pos.x = player_pos.x - 0.3 + end + + api.stop_moving(player) + + player_api.set_animation(player, "sit") + player_api.player_attached[player_name] = true + + player:set_eye_offset({x = 0, y = -7, z = 2}, {x = 0, y = 0, z = 0}) + player:set_pos(player_pos) + + attached_to[player] = {pos} + attached_at[pts(pos)] = player + end +end + +function api.is_head(node_name) + return node_name == "cottages:bed_head" or node_name == "cottages:sleeping_mat_head" +end + +function api.is_bed(node_name) + return node_name == "cottages:bed_head" or node_name == "cottages:bed_foot" +end + +function api.is_mat(node_name) + return node_name == "cottages:sleeping_mat_head" or node_name == "cottages:sleeping_mat" +end + +function api.is_head_of(foot_name, head_name) + if foot_name == "cottages:bed_foot" then + return head_name == "cottages:bed_head" + elseif foot_name == "cottages:sleeping_mat" then + return head_name == "cottages:sleeping_mat_head" + end +end + +function api.is_foot_of(head_name, foot_name) + if head_name == "cottages:bed_head" then + return foot_name == "cottages:bed_foot" + elseif head_name == "cottages:sleeping_mat_head" then + return foot_name == "cottages:sleeping_mat" + end +end + +function api.is_valid_bed(pos, node) + local head_pos = vector.copy(pos) + local foot_pos = vector.copy(pos) + + if api.is_head(node.name) then + if node.param2 == 0 then + foot_pos.z = foot_pos.z - 1 + elseif node.param2 == 1 then + foot_pos.x = foot_pos.x - 1 + elseif node.param2 == 2 then + foot_pos.z = foot_pos.z + 1 + elseif node.param2 == 3 then + foot_pos.x = foot_pos.x + 1 + end + + local foot_node = minetest.get_node(foot_pos) + + if api.is_foot_of(node.name, foot_node.name) and node.param2 == foot_node.param2 then + return head_pos, foot_pos + end + + else + if node.param2 == 2 then + head_pos.z = pos.z - 1 + elseif node.param2 == 3 then + head_pos.x = pos.x - 1 + elseif node.param2 == 0 then + head_pos.z = pos.z + 1 + elseif node.param2 == 1 then + head_pos.x = pos.x + 1 + end + + local head_node = minetest.get_node(head_pos) + + if api.is_head_of(node.name, head_node.name) and node.param2 == head_node.param2 then + return head_pos, foot_pos + end + end +end + +function api.sleep_in_bed(pos, node, player) + if not (cottages.has.player_api and api.allow_attach(pos, player)) then + return + end + + local player_name = player:get_player_name() + local head_pos, foot_pos = api.is_valid_bed(pos, node) + + for _, p in ipairs({head_pos, foot_pos}) do + if p then + for y = 1, 2 do + local node_above = minetest.get_node(vector.add(p, {x = 0, y = y, z = 0})) + + if node_above.name ~= "air" then + minetest.chat_send_player( + player_name, + S("This place is too narrow for sleeping. At least for you!") + ) + return + end + end + end + end + + local animation = player_api.get_animation(player) + + if not animation then + -- certain versions of minetest have a broken API + return + end + + if attached_to[player] then + if animation.animation == "lay" then + api.get_up(player) + minetest.chat_send_player(player_name, "That was enough sleep for now. You stand up again.") + + elseif animation.animation == "sit" then + if head_pos and foot_pos then + player_api.set_animation(player, "lay") + player:set_eye_offset({x = 0, y = -14, z = 2}, {x = 0, y = 0, z = 0}) + minetest.chat_send_player(player_name, S("You lie down and take a nap. A right-click will wake you up.")) + + else + api.get_up(player) + minetest.chat_send_player(player_name, S("That was enough sitting around for now. You stand up again.")) + end + end + + else + -- sit on the bed before lying down + api.stop_moving(player) + + player_api.set_animation(player, "sit") + player_api.player_attached[player_name] = true + + local sleep_pos = vector.copy(pos) + local bed_type = api.is_bed(node.name) and "bed" or "mat" + + if bed_type == "bed" then + -- set the right height for the bed + sleep_pos.y = sleep_pos.y + 0.4 + + elseif bed_type == "mat" then + sleep_pos.y = sleep_pos.y - 0.4 + end + + if head_pos and foot_pos then + sleep_pos.x = (head_pos.x + foot_pos.x) / 2 + sleep_pos.z = (head_pos.z + foot_pos.z) / 2 + end + + player:set_eye_offset({x = 0, y = -7, z = 2}, {x = 0, y = 0, z = 0}) + player:set_pos(sleep_pos) + + if head_pos and foot_pos then + attached_to[player] = {head_pos, foot_pos} + attached_at[pts(head_pos)] = player + attached_at[pts(foot_pos)] = player + + minetest.chat_send_player( + player_name, + S("Aaah! What a comfortable @1. A second right-click will let you sleep.", bed_type) + ) + else + attached_to[player] = {pos} + attached_at[pts(pos)] = player + + minetest.chat_send_player( + player_name, + S("Comfortable, but not good enough for a nap. Right-click again if you want to get back up.") + ) + end + end +end + +function api.break_attach(pos) + local player = attached_at[pts(pos)] + if player then + api.get_up(player) + end +end + +minetest.register_on_leaveplayer(function(player) + if attached_to[player] then + api.get_up(player) + end +end) + +minetest.register_globalstep(function(dtime) + for player in pairs(attached_to) do + local c = player:get_player_control() + if c.up or c.down or c.left or c.right or c.jump then + api.get_up(player) + end + end +end) diff --git a/modules/furniture/crafts.lua b/modules/furniture/crafts.lua new file mode 100644 index 0000000..64a4371 --- /dev/null +++ b/modules/furniture/crafts.lua @@ -0,0 +1,83 @@ +local ci = cottages.craftitems + +if ci.wool and ci.wood and ci.stick then + minetest.register_craft({ + output = "cottages:bed_foot", + recipe = { + {ci.wool, "", "", }, + {ci.wood, "", "", }, + {ci.stick, "", "", } + } + }) + + minetest.register_craft({ + output = "cottages:bed_head", + recipe = { + {"", "", ci.wool, }, + {"", ci.stick, ci.wood, }, + {"", "", ci.stick, } + } + }) +end + +minetest.register_craft({ + output = "cottages:sleeping_mat 3", + recipe = { + {"cottages:wool_tent", "cottages:straw_mat", "cottages:straw_mat"} + } +}) + +minetest.register_craft({ + output = "cottages:sleeping_mat_head", + recipe = { + {"cottages:sleeping_mat", "cottages:straw_mat"} + } +}) + +if ci.stick and ci.slab_wood then + minetest.register_craft({ + output = "cottages:table", + recipe = { + {"", ci.slab_wood, "", }, + {"", ci.stick, ""} + } + }) +end + +minetest.register_craft({ + output = "cottages:bench", + recipe = { + {"", ci.wood, "", }, + {ci.stick, "", ci.stick, } + } +}) + +if ci.stick and ci.wood then + minetest.register_craft({ + output = "cottages:shelf", + recipe = { + {ci.stick, ci.wood, ci.stick, }, + {ci.stick, ci.wood, ci.stick, }, + {ci.stick, "", ci.stick} + } + }) +end + +if ci.stick and ci.clay then + minetest.register_craft({ + output = "cottages:washing 2", + recipe = { + {ci.stick, }, + {ci.clay, }, + } + }) +end + +if ci.steel then + minetest.register_craft({ + output = "cottages:stovepipe 2", + recipe = { + {ci.steel, "", ci.steel}, + } + }) +end diff --git a/modules/furniture/init.lua b/modules/furniture/init.lua new file mode 100644 index 0000000..3ea912f --- /dev/null +++ b/modules/furniture/init.lua @@ -0,0 +1,5 @@ +cottages.furniture = {} + +cottages.dofile("modules", "furniture", "api") +cottages.dofile("modules", "furniture", "nodes") +cottages.dofile("modules", "furniture", "crafts") diff --git a/modules/furniture/nodes.lua b/modules/furniture/nodes.lua new file mode 100644 index 0000000..82c14cb --- /dev/null +++ b/modules/furniture/nodes.lua @@ -0,0 +1,326 @@ +local S = cottages.S + +minetest.register_node("cottages:bed_foot", { + description = S("Bed (foot region)"), + drawtype = "nodebox", + tiles = { + "cottages_beds_bed_top_bottom.png", + cottages.textures.furniture, + "cottages_beds_bed_side.png", + "cottages_beds_bed_side.png", + "cottages_beds_bed_side.png", + "cottages_beds_bed_side.png" + }, + paramtype = "light", + paramtype2 = "facedir", + groups = {snappy = 1, choppy = 2, oddly_breakable_by_hand = 2, flammable = 3}, + sounds = cottages.sounds.wood, + node_box = { + type = "fixed", + fixed = { + {-0.5, 0.0, -0.5, 0.5, 0.3, 0.5}, + {-0.5, -0.5, -0.5, -0.4, 0.5, -0.4}, + {0.4, -0.5, -0.5, 0.5, 0.5, -0.4}, + {-0.4, 0.3, -0.5, 0.4, 0.5, -0.4}, + } + }, + selection_box = { + type = "fixed", + fixed = { + {-0.5, -0.5, -0.5, 0.5, 0.3, 0.5}, + } + }, + is_ground_content = false, + on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) + return cottages.furniture.sleep_in_bed(pos, node, clicker) + end, + after_dig_node = function(pos, oldnode, oldmetadata, digger) + cottages.furniture.break_attach(pos) + end, +}) + +minetest.register_node("cottages:bed_head", { + description = S("Bed (head region)"), + drawtype = "nodebox", + tiles = { + "cottages_beds_bed_top_top.png", + cottages.textures.furniture, + "cottages_beds_bed_side_top_r.png", + "cottages_beds_bed_side_top_l.png", + cottages.textures.furniture, + "cottages_beds_bed_side.png" + }, + paramtype = "light", + paramtype2 = "facedir", + groups = {snappy = 1, choppy = 2, oddly_breakable_by_hand = 2, flammable = 3}, + sounds = cottages.sounds.wood, + node_box = { + type = "fixed", + fixed = { + {-0.5, 0.0, -0.5, 0.5, 0.3, 0.5}, + {-0.5, -0.5, 0.4, -0.4, 0.5, 0.5}, + {0.4, -0.5, 0.4, 0.5, 0.5, 0.5}, + {-0.4, 0.3, 0.4, 0.4, 0.5, 0.5}, + } + }, + selection_box = { + type = "fixed", + fixed = { + {-0.5, -0.5, -0.5, 0.5, 0.3, 0.5}, + } + }, + is_ground_content = false, + on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) + return cottages.furniture.sleep_in_bed(pos, node, clicker) + end, + after_dig_node = function(pos, oldnode, oldmetadata, digger) + cottages.furniture.break_attach(pos) + end, +}) + +minetest.register_node("cottages:sleeping_mat", { + description = S("sleeping mat"), + drawtype = "nodebox", + tiles = {"cottages_sleepingmat.png"}, + wield_image = "cottages_sleepingmat.png", + inventory_image = "cottages_sleepingmat.png", + sunlight_propagates = true, + paramtype = "light", + paramtype2 = "facedir", + walkable = false, + groups = {snappy = 3}, + sounds = cottages.sounds.leaves, + node_box = { + type = "fixed", + fixed = { + {-0.48, -0.5, -0.48, 0.48, -0.5 + 1 / 16, 0.48}, + } + }, + selection_box = { + type = "fixed", + fixed = { + {-0.48, -0.5, -0.48, 0.48, -0.5 + 2 / 16, 0.48}, + } + }, + is_ground_content = false, + on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) + return cottages.furniture.sleep_in_bed(pos, node, clicker) + end, + after_dig_node = function(pos, oldnode, oldmetadata, digger) + cottages.furniture.break_attach(pos) + end, +}) + +minetest.register_node("cottages:sleeping_mat_head", { + description = S("sleeping mat with pillow"), + drawtype = "nodebox", + tiles = {"cottages_sleepingmat.png"}, -- done by VanessaE + wield_image = "cottages_sleepingmat.png", + inventory_image = "cottages_sleepingmat.png", + sunlight_propagates = true, + paramtype = "light", + paramtype2 = "facedir", + groups = {snappy = 3}, + sounds = cottages.sounds.leaves, + node_box = { + type = "fixed", + fixed = { + {-0.48, -0.5, -0.48, 0.48, -0.5 + 1 / 16, 0.48}, + {-0.34, -0.5 + 1 / 16, -0.12, 0.34, -0.5 + 2 / 16, 0.34}, + }, + }, + selection_box = { + type = "fixed", + fixed = { + {-0.48, -0.5, -0.48, 0.48, -0.5 + 2 / 16, 0.48}, + }, + }, + is_ground_content = false, + on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) + return cottages.furniture.sleep_in_bed(pos, node, clicker) + end, + after_dig_node = function(pos, oldnode, oldmetadata, digger) + cottages.furniture.break_attach(pos) + end, +}) + +minetest.register_node("cottages:bench", { + drawtype = "nodebox", + description = S("simple wooden bench"), + tiles = { + "cottages_minimal_wood.png", + "cottages_minimal_wood.png", + "cottages_minimal_wood.png", + "cottages_minimal_wood.png", + "cottages_minimal_wood.png", + "cottages_minimal_wood.png" + }, + paramtype = "light", + paramtype2 = "facedir", + groups = {snappy = 1, choppy = 2, oddly_breakable_by_hand = 2, flammable = 3}, + sounds = cottages.sounds.wood, + node_box = { + type = "fixed", + fixed = { + {-0.5, -0.15, 0.1, 0.5, -0.05, 0.5}, + {-0.4, -0.5, 0.2, -0.3, -0.15, 0.4}, + {0.3, -0.5, 0.2, 0.4, -0.15, 0.4}, + } + }, + selection_box = { + type = "fixed", + fixed = { + {-0.5, -0.5, 0, 0.5, 0, 0.5}, + } + }, + is_ground_content = false, + on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) + return cottages.furniture.sit_on_bench(pos, node, clicker) + end, + after_dig_node = function(pos, oldnode, oldmetadata, digger) + cottages.furniture.break_attach(pos) + end, +}) + +minetest.register_node("cottages:table", { + description = S("table"), + drawtype = "nodebox", + tiles = {"cottages_minimal_wood.png"}, + paramtype = "light", + paramtype2 = "facedir", + groups = {snappy = 2, choppy = 2, oddly_breakable_by_hand = 2}, + node_box = { + type = "fixed", + fixed = { + {-0.1, -0.5, -0.1, 0.1, 0.3, 0.1}, + {-0.5, 0.48, -0.5, 0.5, 0.4, 0.5}, + }, + }, + selection_box = { + type = "fixed", + fixed = { + {-0.5, -0.5, -0.5, 0.5, 0.4, 0.5}, + }, + }, + is_ground_content = false, +}) + +minetest.register_node("cottages:shelf", { + description = S("open storage shelf"), + drawtype = "nodebox", + tiles = {"cottages_minimal_wood.png"}, + paramtype = "light", + paramtype2 = "facedir", + groups = {snappy = 2, choppy = 2, oddly_breakable_by_hand = 2}, + node_box = { + type = "fixed", + fixed = { + + {-0.5, -0.5, -0.3, -0.4, 0.5, 0.5}, + {0.4, -0.5, -0.3, 0.5, 0.5, 0.5}, + + {-0.5, -0.2, -0.3, 0.5, -0.1, 0.5}, + {-0.5, 0.3, -0.3, 0.5, 0.4, 0.5}, + }, + }, + selection_box = { + type = "fixed", + fixed = { + {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, + }, + }, + on_construct = function(pos) + local meta = minetest.get_meta(pos) + meta:set_string("formspec", [[ + size[8,8] + list[context;main;0,0;8,3;] + list[current_player;main;0,4;8,4;] + listring[] + ]]) + meta:set_string("infotext", S("open storage shelf")) + local inv = meta:get_inventory() + inv:set_size("main", 24) + end, + can_dig = function(pos, player) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + return inv:is_empty("main") + end, + on_metadata_inventory_put = function(pos, listname, index, stack, player) + local meta = minetest.get_meta(pos) + meta:set_string("infotext", S("open storage shelf (in use)")) + end, + on_metadata_inventory_take = function(pos, listname, index, stack, player) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + if inv:is_empty("main") then + meta:set_string("infotext", S("open storage shelf (empty)")) + end + end, + is_ground_content = false, +}) + +minetest.register_node("cottages:stovepipe", { + description = S("stovepipe"), + drawtype = "nodebox", + tiles = {"cottages_steel_block.png"}, + paramtype = "light", + paramtype2 = "facedir", + groups = {snappy = 2, choppy = 2, oddly_breakable_by_hand = 2}, + node_box = { + type = "fixed", + fixed = { + {0.20, -0.5, 0.20, 0.45, 0.5, 0.45}, + }, + }, + selection_box = { + type = "fixed", + fixed = { + {0.20, -0.5, 0.20, 0.45, 0.5, 0.45}, + }, + }, + is_ground_content = false, +}) + +minetest.register_node("cottages:washing", { + description = S("washing place"), + drawtype = "nodebox", + -- top, bottom, side1, side2, inner, outer + tiles = {"cottages_clay.png"}, + paramtype = "light", + paramtype2 = "facedir", + is_ground_content = false, + groups = {snappy = 2, choppy = 2, oddly_breakable_by_hand = 2}, + node_box = { + type = "fixed", + fixed = { + {-0.5, -0.5, -0.5, 0.5, -0.2, -0.2}, + {-0.5, -0.5, -0.2, -0.4, 0.2, 0.5}, + {0.4, -0.5, -0.2, 0.5, 0.2, 0.5}, + {-0.4, -0.5, 0.4, 0.4, 0.2, 0.5}, + {-0.4, -0.5, -0.2, 0.4, 0.2, -0.1}, + }, + }, + selection_box = { + type = "fixed", + fixed = { + {-0.5, -0.5, -0.5, 0.5, 0.2, 0.5}, + }, + }, + on_rightclick = function(pos, node, player) + -- works only with water beneath + local node_under = minetest.get_node({x = pos.x, y = (pos.y - 1), z = pos.z}) + if minetest.get_item_group(node_under.name, "water") > 0 then + minetest.chat_send_player( + player:get_player_name(), + S("You feel much cleaner after some washing.") + ) + + else + minetest.chat_send_player( + player:get_player_name(), + S("Sorry. This washing place is out of water. Please place it above water!") + ) + end + end, +}) diff --git a/modules/hay/crafts.lua b/modules/hay/crafts.lua new file mode 100644 index 0000000..f5c4e9f --- /dev/null +++ b/modules/hay/crafts.lua @@ -0,0 +1,26 @@ + +minetest.register_craft({ + output = "cottages:hay_mat 9", + recipe = { + {"cottages:hay"}, + }, +}) + +minetest.register_craft({ + output = "cottages:hay", + recipe = { + {"cottages:hay_mat", "cottages:hay_mat", "cottages:hay_mat"}, + {"cottages:hay_mat", "cottages:hay_mat", "cottages:hay_mat"}, + {"cottages:hay_mat", "cottages:hay_mat", "cottages:hay_mat"}, + }, +}) + +minetest.register_craft({ + output = "cottages:hay", + recipe = {{"cottages:hay_bale"}}, +}) + +minetest.register_craft({ + output = "cottages:hay_bale", + recipe = {{"cottages:hay"}}, +}) diff --git a/modules/hay/init.lua b/modules/hay/init.lua new file mode 100644 index 0000000..1028bb0 --- /dev/null +++ b/modules/hay/init.lua @@ -0,0 +1,3 @@ + +cottages.dofile("modules", "hay", "nodes") +cottages.dofile("modules", "hay", "crafts") diff --git a/modules/hay/nodes.lua b/modules/hay/nodes.lua new file mode 100644 index 0000000..871075e --- /dev/null +++ b/modules/hay/nodes.lua @@ -0,0 +1,57 @@ +local S = cottages.S + +minetest.register_node("cottages:hay_mat", { + drawtype = "nodebox", + paramtype2 = "leveled", + description = S("Some hay"), + tiles = { + cottages.textures.straw .. "^[multiply:#88BB88" + }, + groups = {hay = 3, snappy = 2, oddly_breakable_by_hand = 2, flammable = 3}, + sounds = cottages.sounds.leaves, + -- the bale is slightly smaller than a full node + is_ground_content = false, + node_box = { + type = "leveled", --"fixed", + fixed = { + {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, + } + }, + -- make sure a placed hay block looks halfway reasonable + after_place_node = function(pos, placer, itemstack, pointed_thing) + minetest.swap_node(pos, {name = "cottages:hay_mat", param2 = math.random(2, 25)}) + end, +}) + +-- hay block, similar to straw block +minetest.register_node("cottages:hay", { + description = S("Hay"), + tiles = {cottages.textures.straw .. "^[multiply:#88BB88"}, + groups = {hay = 3, snappy = 2, oddly_breakable_by_hand = 2, flammable = 3}, + sounds = cottages.sounds.leaves, + is_ground_content = false, +}) + +-- hay bales for hungry animals +minetest.register_node("cottages:hay_bale", { + drawtype = "nodebox", + description = S("Hay bale"), + tiles = {"cottages_darkage_straw_bale.png^[multiply:#88BB88"}, + paramtype = "light", + groups = {hay = 3, snappy = 2, oddly_breakable_by_hand = 2, flammable = 3}, + sounds = cottages.sounds.leaves, + -- the bale is slightly smaller than a full node + node_box = { + type = "fixed", + fixed = { + {-0.45, -0.5, -0.45, 0.45, 0.45, 0.45}, + } + }, + selection_box = { + type = "fixed", + fixed = { + {-0.45, -0.5, -0.45, 0.45, 0.45, 0.45}, + } + }, + is_ground_content = false, +}) diff --git a/modules/historic/crafts.lua b/modules/historic/crafts.lua new file mode 100644 index 0000000..44a2c3d --- /dev/null +++ b/modules/historic/crafts.lua @@ -0,0 +1,82 @@ +local ci = cottages.craftitems + +if ci.iron and ci.stick and ci.steel then + minetest.register_craft({ + output = "cottages:wagon_wheel 3", + recipe = { + {ci.iron, ci.stick, ci.iron}, + {ci.stick, ci.steel, ci.stick}, + {ci.iron, ci.stick, ci.iron} + } + }) +end + +if ci.sand and ci.clay then + minetest.register_craft({ + output = "cottages:loam 4", + recipe = { + {ci.sand}, + {ci.clay} + } + }) +end + +minetest.register_craft({ + output = "cottages:straw_ground 2", + recipe = { + {"cottages:straw_mat"}, + {"cottages:loam"} + } +}) + +if ci.stick and ci.glass then + minetest.register_craft({ + output = "cottages:glass_pane 4", + recipe = { + {ci.stick, ci.stick, ci.stick}, + {ci.stick, ci.glass, ci.stick}, + {ci.stick, ci.stick, ci.stick} + } + }) +end + +minetest.register_craft({ + output = "cottages:glass_pane_side", + recipe = { + {"cottages:glass_pane"}, + } +}) + +minetest.register_craft({ + output = "cottages:glass_pane", + recipe = { + {"cottages:glass_pane_side"}, + } +}) + +if ci.stick and ci.string then + minetest.register_craft({ + output = "cottages:wood_flat 16", + recipe = { + {ci.stick, ci.string, ci.stick}, + {ci.stick, "", ci.stick}, + } + }) +end + +if ci.stick then + minetest.register_craft({ + output = "cottages:wool_tent 2", + recipe = { + {ci.string, ci.string}, + {"", ci.stick} + } + }) +end + +minetest.register_craft({ + output = "cottages:wool", + recipe = { + {"cottages:wool_tent", "cottages:wool_tent"} + } +}) diff --git a/modules/historic/init.lua b/modules/historic/init.lua new file mode 100644 index 0000000..851c786 --- /dev/null +++ b/modules/historic/init.lua @@ -0,0 +1,3 @@ + +cottages.dofile("modules", "historic", "nodes") +cottages.dofile("modules", "historic", "crafts") diff --git a/modules/historic/nodes.lua b/modules/historic/nodes.lua new file mode 100644 index 0000000..3a6aa74 --- /dev/null +++ b/modules/historic/nodes.lua @@ -0,0 +1,155 @@ +local S = cottages.S + +if cottages.has.wool and minetest.registered_nodes["wool:white"] then + minetest.register_alias("cottages:wool", "wool:white") + +else + minetest.register_node("cottages:wool", { + description = "Wool", + tiles = {"cottages_wool.png"}, + is_ground_content = false, + groups = {snappy = 2, choppy = 2, oddly_breakable_by_hand = 3, flammable = 3, wool = 1}, + }) +end + +minetest.register_node("cottages:wool_tent", { + description = S("wool for tents"), + drawtype = "nodebox", + tiles = {"cottages_wool.png"}, + paramtype = "light", + paramtype2 = "facedir", + groups = {snappy = 2, choppy = 2, oddly_breakable_by_hand = 2}, + node_box = { + type = "fixed", + fixed = { + {-0.5, -0.5, -0.50, 0.5, -0.5 + 1 / 16, 0.50}, + }, + }, + selection_box = { + type = "fixed", + fixed = { + {-0.5, -0.5, -0.50, 0.5, -0.5 + 1 / 16, 0.50}, + }, + }, + is_ground_content = false, + on_place = minetest.rotate_node, +}) + +minetest.register_node("cottages:wood_flat", { + description = S("flat wooden planks"), + drawtype = "nodebox", + tiles = {"cottages_minimal_wood.png"}, + paramtype = "light", + paramtype2 = "facedir", + groups = {snappy = 2, choppy = 2, oddly_breakable_by_hand = 2}, + node_box = { + type = "fixed", + fixed = { + {-0.5, -0.5, -0.50, 0.5, -0.5 + 1 / 16, 0.50}, + }, + }, + selection_box = { + type = "fixed", + fixed = { + {-0.5, -0.5, -0.50, 0.5, -0.5 + 1 / 16, 0.50}, + }, + }, + is_ground_content = false, + on_place = minetest.rotate_node, +}) + +minetest.register_node("cottages:glass_pane", { + description = S("simple glass pane (centered)"), + drawtype = "nodebox", + tiles = {"cottages_glass_pane.png"}, + paramtype = "light", + paramtype2 = "facedir", + groups = {snappy = 2, choppy = 2, oddly_breakable_by_hand = 2}, + node_box = { + type = "fixed", + fixed = { + {-0.5, -0.5, -0.05, 0.5, 0.5, 0.05}, + }, + }, + selection_box = { + type = "fixed", + fixed = { + {-0.5, -0.5, -0.05, 0.5, 0.5, 0.05}, + }, + }, + is_ground_content = false, +}) + +minetest.register_node("cottages:glass_pane_side", { + description = S("simple glass pane"), + drawtype = "nodebox", + tiles = {"cottages_glass_pane.png"}, + paramtype = "light", + paramtype2 = "facedir", + groups = {snappy = 2, choppy = 2, oddly_breakable_by_hand = 2}, + node_box = { + type = "fixed", + fixed = { + {-0.5, -0.5, -0.40, 0.5, 0.5, -0.50}, + }, + }, + selection_box = { + type = "fixed", + fixed = { + {-0.5, -0.5, -0.40, 0.5, 0.5, -0.50}, + }, + }, + is_ground_content = false, +}) + +minetest.register_node("cottages:straw_ground", { + description = S("straw ground for animals"), + tiles = { + cottages.straw_texture, + "cottages_loam.png", + "cottages_loam.png", + "cottages_loam.png", + "cottages_loam.png", + "cottages_loam.png" + }, + groups = {snappy = 2, crumbly = 3, choppy = 2, oddly_breakable_by_hand = 2}, + sounds = cottages.sounds.leaves, + is_ground_content = false, +}) + + +minetest.register_node("cottages:loam", { + description = S("loam"), + tiles = {"cottages_loam.png"}, + groups = {snappy = 2, crumbly = 3, choppy = 2, oddly_breakable_by_hand = 2}, + sounds = cottages.sounds.dirt, + is_ground_content = false, +}) + +minetest.register_node("cottages:wagon_wheel", { + description = S("wagon wheel"), + drawtype = "signlike", + tiles = {"cottages_wagonwheel.png"}, + inventory_image = "cottages_wagonwheel.png", + wield_image = "cottages_wagonwheel.png", + paramtype = "light", + paramtype2 = "wallmounted", + sunlight_propagates = true, + walkable = false, + selection_box = { + type = "wallmounted", + }, + groups = {choppy = 2, dig_immediate = 2, attached_node = 1}, + legacy_wallmounted = true, + is_ground_content = false, +}) + +if cottages.has.stairs then + stairs.register_stair_and_slab("loam", "cottages:loam", + {snappy = 2, crumbly = 3, choppy = 2, oddly_breakable_by_hand = 2}, + {"cottages_loam.png"}, + S("Loam Stairs"), + S("Loam Slab"), + cottages.sounds.dirt + ) +end diff --git a/modules/init.lua b/modules/init.lua new file mode 100644 index 0000000..78ea54c --- /dev/null +++ b/modules/init.lua @@ -0,0 +1,5 @@ +for module, settings in pairs(cottages.settings) do + if settings.enabled then + cottages.dofile("modules", module, "init") + end +end diff --git a/modules/mining/crafts.lua b/modules/mining/crafts.lua new file mode 100644 index 0000000..6e9935c --- /dev/null +++ b/modules/mining/crafts.lua @@ -0,0 +1,19 @@ +local ci = cottages.craftitems + +if ci.cotton then + minetest.register_craft({ + output = "cottages:rope", + recipe = { + {ci.cotton, ci.cotton, ci.cotton} + } + }) +end + +if ci.ladder and ci.rail then + minetest.register_craft({ + output = "cottages:ladder_with_rope_and_rail 3", + recipe = { + {ci.ladder, "cottages:rope", ci.rail} + } + }) +end diff --git a/modules/mining/init.lua b/modules/mining/init.lua new file mode 100644 index 0000000..3268b84 --- /dev/null +++ b/modules/mining/init.lua @@ -0,0 +1,3 @@ + +cottages.dofile("modules", "mining", "nodes") +cottages.dofile("modules", "mining", "crafts") diff --git a/modules/mining/nodes.lua b/modules/mining/nodes.lua new file mode 100644 index 0000000..b0cffb5 --- /dev/null +++ b/modules/mining/nodes.lua @@ -0,0 +1,70 @@ +local S = cottages.S + +minetest.register_node("cottages:rope", { + description = S("Rope"), + tiles = {"cottages_rope.png"}, + groups = { + snappy = 3, choppy = 3, oddly_breakable_by_hand = 3, + }, + walkable = false, + climbable = true, + paramtype = "light", + sunlight_propagates = true, + drawtype = "plantlike", + is_ground_content = false, + can_dig = function(pos, player) + local below = minetest.get_node({x = pos.x, y = pos.y - 1, z = pos.z}) + + if below.name == "cottages:rope" then + if minetest.is_player(player) then + minetest.chat_send_player( + player:get_player_name(), + S("The entire rope would be too heavy. Start digging at its lowest end!") + ) + end + return false + end + return true + end +}) + +if cottages.has.carts then + carts:register_rail("cottages:ladder_with_rope_and_rail", { + description = S("Ladder with \"rail support\""), + tiles = { + "default_ladder_wood.png^carts_rail_straight.png^cottages_rope.png" + }, + inventory_image = "default_ladder_wood.png", + wield_image = "default_ladder_wood.png", + groups = carts:get_rail_groups(), + sounds = cottages.sounds.wood, + paramtype2 = "wallmounted", + legacy_wallmounted = true, + }, {}) + +else + minetest.register_node("cottages:ladder_with_rope_and_rail", { + description = S("Ladder with \"rail support\""), + inventory_image = "default_ladder_wood.png", + wield_image = "default_ladder_wood.png", + drawtype = "raillike", + tiles = { + "default_ladder_wood.png^carts_rail_straight.png^cottages_rope.png" + }, + paramtype = "light", + paramtype2 = "wallmounted", + sunlight_propagates = true, + walkable = false, + climbable = true, + is_ground_content = false, + selection_box = { + type = "wallmounted", + }, + groups = { + choppy = 2, oddly_breakable_by_hand = 3, rail = 1, + connect_to_raillike = minetest.raillike_group("rail"), + }, + legacy_wallmounted = true, + sounds = cottages.sounds.wood, + }) +end diff --git a/modules/pitchfork/crafts.lua b/modules/pitchfork/crafts.lua new file mode 100644 index 0000000..bb7a319 --- /dev/null +++ b/modules/pitchfork/crafts.lua @@ -0,0 +1,30 @@ +local S = cottages.S +local ci = cottages.craftitems + +if ci.stick then + minetest.register_craft({ + output = "cottages:pitchfork", + recipe = { + {ci.stick, ci.stick, ci.stick}, + {"", ci.stick, ""}, + {"", ci.stick, ""}, + } + }) +end + +if cottages.has.unified_inventory then + unified_inventory.register_craft_type("cottages:pitchfork", { + description = S("gathered w/ the pitchfork"), + icon = "cottages_pitchfork.png", + width = 1, + height = 1, + uses_crafting_grid = false, + }) + + unified_inventory.register_craft({ + output = "cottages:hay_mat", + type = "cottages:pitchfork", + items = {"default:dirt_with_grass"}, + width = 1, + }) +end diff --git a/modules/pitchfork/init.lua b/modules/pitchfork/init.lua new file mode 100644 index 0000000..a3a01ad --- /dev/null +++ b/modules/pitchfork/init.lua @@ -0,0 +1,3 @@ + +cottages.dofile("modules", "pitchfork", "tool") +cottages.dofile("modules", "pitchfork", "crafts") diff --git a/modules/pitchfork/tool.lua b/modules/pitchfork/tool.lua new file mode 100644 index 0000000..01357d2 --- /dev/null +++ b/modules/pitchfork/tool.lua @@ -0,0 +1,105 @@ +local S = cottages.S + +local has_stamina = cottages.has.stamina +local stamina_use = cottages.settings.pitchfork.stamina + +minetest.register_node("cottages:pitchfork", { + description = S("Pitchfork (dig dirt with grass to get hay, place with right-click)"), + short_description = S("Pitchfork"), + inventory_image = "cottages_pitchfork.png", + wield_image = "cottages_pitchfork.png^[transformFYR180", + wield_scale = {x = 1.5, y = 1.5, z = 0.5}, + stack_max = 1, + liquids_pointable = false, + + tool_capabilities = { + full_punch_interval = 1.0, + max_drop_level = 1, + groupcaps = { + crumbly = {times={[2]=3.00, [3]=0.70}, maxlevel = 1, uses = 0, punch_attack_uses = 0, }, + snappy = {times = {[2] = 0.40, [3] = 0.20}, maxlevel = 1, uses = 0, punch_attack_uses = 0, }, + hay = {times = {[2] = 0.10, [3] = 0.10}, maxlevel = 1, uses = 0, punch_attack_uses = 0, }, + }, + damage_groups = {fleshy = 5}, -- slightly stronger than a stone sword + }, + + drawtype = "nodebox", + paramtype = "light", + paramtype2 = "facedir", + is_ground_content = false, + drop = "cottages:pitchfork", + + groups = {snappy = 2, dig_immediate = 3, falling_node = 1, attached_node = 1}, + + sounds = cottages.sounds.wood, + + visual_scale = 1.0, + tiles = {"default_wood.png^[transformR90"}, + special_tiles = {}, + post_effect_color = {a=0, r=0, g=0, b=0}, + node_box = { + type = "fixed", + fixed = { + -- handle (goes a bit into the ground) + {-(1 / 32), -(11 / 16), -(1 / 32), (1 / 32), 16 / 16, (1 / 32)}, + -- middle connection + {-(7 / 32), -(4 / 16), -(1 / 32), (7 / 32), -(2 / 16), (1 / 32)}, + -- thongs + {-(7 / 32), -(11 / 16), -(1 / 32), -(5 / 32), -(4 / 16), (1 / 32)}, + {(5 / 32), -(11 / 16), -(1 / 32), (7 / 32), -(4 / 16), (1 / 32)}, + }, + }, + selection_box = { + type = "fixed", + fixed = {-0.3, -0.5, -0.1, 0.3, 1.0, 0.1} + }, +}) + +local function override_on_dig(node_name, replacement) + local node_def = minetest.registered_nodes[node_name] + + if not node_def and minetest.registered_nodes[replacement] then + return + end + + local old_on_dig = node_def.on_dig + + minetest.override_item(node_name, { + on_dig = function(pos, node, digger) + if not minetest.is_player(digger) then + return old_on_dig(pos, node, digger) + end + + local wielded = digger:get_wielded_item() + + if wielded:get_name() ~= "cottages:pitchfork" then + return old_on_dig(pos, node, digger) + end + + local digger_name = digger:get_player_name() + if minetest.is_protected(pos, digger_name) then + return old_on_dig(pos, node, digger) + end + + local pos_above = vector.add(pos, {x=0, y=1, z=0}) + local node_above = minetest.get_node(pos_above) + + if minetest.is_protected(pos_above, digger_name) or node_above.name ~= "air" then + return old_on_dig(pos, node, digger) + end + + minetest.swap_node(pos, {name = replacement}) + minetest.swap_node(pos_above, {name = "cottages:hay_mat", param2 = math.random(2, 25)}) + + if has_stamina then + stamina.exhaust_player(digger, stamina_use, "cottages:pitchfork") + end + + return true + end, + }) +end + +override_on_dig("default:dirt_with_grass", "default:dirt") + +minetest.register_alias("cottages:pitchfork_placed", "cottages:pitchfork") diff --git a/modules/roof/api.lua b/modules/roof/api.lua new file mode 100644 index 0000000..3715307 --- /dev/null +++ b/modules/roof/api.lua @@ -0,0 +1,111 @@ +local S = cottages.S +local ci = cottages.craftitems + +function cottages.roof.register_roof(name, material, tiles) + minetest.register_node("cottages:roof_" .. name, { + description = S("Roof " .. name), + drawtype = "nodebox", + tiles = tiles, + paramtype = "light", + paramtype2 = "facedir", + groups = {snappy = 2, choppy = 2, oddly_breakable_by_hand = 2}, + node_box = { + type = "fixed", + fixed = { + {-0.5, -0.5, -0.5, 0.5, 0, 0}, + {-0.5, 0, 0, 0.5, 0.5, 0.5}, + }, + }, + selection_box = { + type = "fixed", + fixed = { + {-0.5, -0.5, -0.5, 0.5, 0, 0}, + {-0.5, 0, 0, 0.5, 0.5, 0.5}, + }, + }, + is_ground_content = false, + }) + + minetest.register_node("cottages:roof_connector_" .. name, { + description = S("Roof connector " .. name), + drawtype = "nodebox", + -- top, bottom, side1, side2, inner, outer + tiles = tiles, + paramtype = "light", + paramtype2 = "facedir", + groups = {snappy = 2, choppy = 2, oddly_breakable_by_hand = 2}, + node_box = { + type = "fixed", + fixed = { + {-0.5, -0.5, -0.5, 0.5, 0, 0.5}, + {-0.5, 0, 0, 0.5, 0.5, 0.5}, + }, + }, + selection_box = { + type = "fixed", + fixed = { + {-0.5, -0.5, -0.5, 0.5, 0, 0.5}, + {-0.5, 0, 0, 0.5, 0.5, 0.5}, + }, + }, + is_ground_content = false, + }) + + -- this one is the slab version of the above roof + minetest.register_node("cottages:roof_flat_" .. name, { + description = S("Roof (flat) " .. name), + drawtype = "nodebox", + -- top, bottom, side1, side2, inner, outer + -- this one is from all sides - except from the underside - of the given material + tiles = {tiles[1], tiles[2], tiles[1], tiles[1], tiles[1], tiles[1]}, + paramtype = "light", + paramtype2 = "facedir", + groups = {snappy = 2, choppy = 2, oddly_breakable_by_hand = 2}, + node_box = { + type = "fixed", + fixed = { + {-0.5, -0.5, -0.5, 0.5, 0, 0.5}, + }, + }, + selection_box = { + type = "fixed", + fixed = { + {-0.5, -0.5, -0.5, 0.5, 0, 0.5}, + }, + }, + is_ground_content = false, + }) + + minetest.register_craft({ + output = "cottages:roof_" .. name .. " 6", + recipe = { + {"", "", material}, + {"", material, ""}, + {material, "", ""} + } + }) + + minetest.register_craft({ + output = "cottages:roof_connector_" .. name, + recipe = { + {"cottages:roof_" .. name}, + {ci.wood}, + } + }) + + minetest.register_craft({ + output = "cottages:roof_flat_" .. name .. " 2", + recipe = { + {"cottages:roof_" .. name, "cottages:roof_" .. name}, + } + }) + + -- convert flat roofs back to normal roofs + minetest.register_craft({ + output = "cottages:roof_" .. name, + recipe = { + {"cottages:roof_flat_" .. name, "cottages:roof_flat_" .. name} + } + }) + +end -- of cottages.register_roof( name, tiles, basic_material ) diff --git a/modules/roof/crafts.lua b/modules/roof/crafts.lua new file mode 100644 index 0000000..67f31a1 --- /dev/null +++ b/modules/roof/crafts.lua @@ -0,0 +1,13 @@ +local ci = cottages.craftitems + +minetest.register_craft({ + output = "cottages:reet", + recipe = {{ci.papyrus, ci.papyrus}, + {ci.papyrus, ci.papyrus}, + }, +}) + +minetest.register_craft({ + output = "cottages:slate_vertical", + recipe = {{ci.stone, ci.wood}} +}) diff --git a/modules/roof/init.lua b/modules/roof/init.lua new file mode 100644 index 0000000..76e33a9 --- /dev/null +++ b/modules/roof/init.lua @@ -0,0 +1,5 @@ +cottages.roof = {} + +cottages.dofile("modules", "roof", "api") +cottages.dofile("modules", "roof", "nodes") +cottages.dofile("modules", "roof", "crafts") diff --git a/modules/roof/nodes.lua b/modules/roof/nodes.lua new file mode 100644 index 0000000..df38715 --- /dev/null +++ b/modules/roof/nodes.lua @@ -0,0 +1,86 @@ +local S = cottages.S +local ci = cottages.craftitems + +if cottages.settings.roof.use_farming_straw_stairs then + minetest.register_alias("cottages:roof_straw", "stairs:stair_straw") + minetest.register_alias("cottages:roof_connector_straw", "stairs:stair_straw") + minetest.register_alias("cottages:roof_flat_straw", "stairs:slab_straw") + +else + cottages.roof.register_roof( + "straw", + "cottages:straw_mat", + {cottages.textures.straw, cottages.textures.straw, + cottages.textures.straw, cottages.textures.straw, + cottages.textures.straw, cottages.textures.straw} + ) +end + +cottages.roof.register_roof( + "reet", + ci.papyrus, + {"cottages_reet.png", "cottages_reet.png", + "cottages_reet.png", "cottages_reet.png", + "cottages_reet.png", "cottages_reet.png"} +) + +cottages.roof.register_roof( + "wood", + ci.wood, + {cottages.textures.roof_wood, cottages.textures.roof_sides, + cottages.textures.roof_sides, cottages.textures.roof_sides, + cottages.textures.roof_sides, cottages.textures.roof_wood} +) + +cottages.roof.register_roof( + "black", + ci.coal_lump, + {"cottages_homedecor_shingles_asphalt.png", cottages.textures.roof_sides, + cottages.textures.roof_sides, cottages.textures.roof_sides, + cottages.textures.roof_sides, "cottages_homedecor_shingles_asphalt.png"} +) + +cottages.roof.register_roof( + "red", + ci.clay_brick, + {"cottages_homedecor_shingles_terracotta.png", cottages.textures.roof_sides, + cottages.textures.roof_sides, cottages.textures.roof_sides, + cottages.textures.roof_sides, "cottages_homedecor_shingles_terracotta.png"} +) + +cottages.roof.register_roof( + "brown", + ci.dirt, + {"cottages_homedecor_shingles_wood.png", cottages.textures.roof_sides, + cottages.textures.roof_sides, cottages.textures.roof_sides, + cottages.textures.roof_sides, "cottages_homedecor_shingles_wood.png"} +) + +cottages.roof.register_roof( + "slate", + ci.stone, + {"cottages_slate.png", cottages.textures.roof_sides, + "cottages_slate.png", "cottages_slate.png", + cottages.textures.roof_sides, "cottages_slate.png"} +) + +-------- + +minetest.register_node("cottages:reet", { + description = S("Reed for thatching"), + tiles = {"cottages_reet.png"}, + groups = {hay = 3, snappy = 3, choppy = 3, oddly_breakable_by_hand = 3, flammable = 3}, + sounds = cottages.sounds.leaves, + is_ground_content = false, +}) + +minetest.register_node("cottages:slate_vertical", { + description = S("Vertical Slate"), + tiles = {"cottages_slate.png", cottages.textures.roof_sides, + "cottages_slate.png", "cottages_slate.png", + cottages.textures.roof_sides, "cottages_slate.png"}, + paramtype2 = "facedir", + groups = {cracky = 2, stone = 1}, + sounds = cottages.sounds.stone, + is_ground_content = false, +}) diff --git a/modules/straw/api.lua b/modules/straw/api.lua new file mode 100644 index 0000000..caeba57 --- /dev/null +++ b/modules/straw/api.lua @@ -0,0 +1,55 @@ +local S = cottages.S + +local api = cottages.straw + +local has_ui = cottages.has.unified_inventory + +if has_ui then + unified_inventory.register_craft_type("cottages:quern", { + description = S("quern-stone"), + icon = "cottages_quern.png", + width = 1, + height = 1, + uses_crafting_grid = false, + }) + + unified_inventory.register_craft_type("cottages:threshing", { + description = S("threshing floor"), + icon = "cottages_junglewood.png^farming_wheat.png", + width = 1, + height = 1, + uses_crafting_grid = false, + }) +end + +api.registered_quern_crafts = {} + +function api.register_quern_craft(recipe) + api.registered_quern_crafts[recipe.input] = recipe.output + + if has_ui then + unified_inventory.register_craft({ + output = recipe.output, + type = "cottages:quern", + items = {recipe.input}, + width = 1, + }) + end +end + +api.registered_threshing_crafts = {} + +function api.register_threshing_craft(recipe) + api.registered_threshing_crafts[recipe.input] = recipe.output + + if has_ui then + for _, output in ipairs(recipe.output) do + unified_inventory.register_craft({ + output = output, + type = "cottages:threshing", + items = {recipe.input}, + width = 1, + }) + end + end +end diff --git a/modules/straw/crafts.lua b/modules/straw/crafts.lua new file mode 100644 index 0000000..26bef3a --- /dev/null +++ b/modules/straw/crafts.lua @@ -0,0 +1,93 @@ +local ci = cottages.craftitems + +minetest.register_craft({ + output = "cottages:straw_mat 6", + recipe = { + {ci.stone, "", ""}, + {"farming:wheat", "farming:wheat", "farming:wheat", }, + }, + replacements = {{ci.stone, ci.seed_wheat .. " 3"}}, +}) + +-- this is a better way to get straw mats +minetest.register_craft({ + output = "cottages:threshing_floor", + recipe = { + {ci.junglewood, ci.chest_locked, ci.junglewood, }, + {ci.junglewood, ci.stone, ci.junglewood, }, + }, +}) + +-- and a way to turn wheat seeds into flour +minetest.register_craft({ + output = "cottages:quern", + recipe = { + {ci.stick, ci.stone, "", }, + {"", ci.steel, "", }, + {"", ci.stone, "", }, + }, +}) + +minetest.register_craft({ + output = "cottages:straw_bale", + recipe = { + {"cottages:straw_mat"}, + {"cottages:straw_mat"}, + {"cottages:straw_mat"}, + }, +}) + +minetest.register_craft({ + output = "cottages:straw", + recipe = { + {"cottages:straw_bale"}, + }, +}) + +minetest.register_craft({ + output = "cottages:straw_bale", + recipe = { + {"cottages:straw"}, + }, +}) + +minetest.register_craft({ + output = "cottages:straw_mat 3", + recipe = { + {"cottages:straw_bale"}, + }, +}) + +--------------------------------- + +if ci.flour then + if ci.seed_barley then + cottages.straw.register_quern_craft({input = ci.seed_barley, output = ci.flour}) + end + if ci.seed_oat then + cottages.straw.register_quern_craft({input = ci.seed_oat, output = ci.flour}) + end + if ci.seed_rye then + cottages.straw.register_quern_craft({input = ci.seed_rye, output = ci.flour}) + end + if ci.seed_wheat then + cottages.straw.register_quern_craft({input = ci.seed_wheat, output = ci.flour}) + end +end + +if ci.rice and ci.rice_flour then + cottages.straw.register_quern_craft({input = ci.rice, output = ci.rice_flour}) +end + +if ci.barley and ci.seed_barley then + cottages.straw.register_threshing_craft({input = ci.barley, output = {ci.seed_barley, ci.straw_mat}}) +end +if ci.oat and ci.seed_oat then + cottages.straw.register_threshing_craft({input = ci.oat, output = {ci.seed_oat, ci.straw_mat}}) +end +if ci.rye and ci.seed_rye then + cottages.straw.register_threshing_craft({input = ci.rye, output = {ci.seed_rye, ci.straw_mat}}) +end +if ci.wheat and ci.seed_wheat then + cottages.straw.register_threshing_craft({input = ci.wheat, output = {ci.seed_wheat, ci.straw_mat}}) +end diff --git a/modules/straw/init.lua b/modules/straw/init.lua new file mode 100644 index 0000000..fcaf209 --- /dev/null +++ b/modules/straw/init.lua @@ -0,0 +1,7 @@ +cottages.straw = {} + +cottages.dofile("modules", "straw", "api") +cottages.dofile("modules", "straw", "nodes") +cottages.dofile("modules", "straw", "quern") +cottages.dofile("modules", "straw", "threshing") +cottages.dofile("modules", "straw", "crafts") diff --git a/modules/straw/nodes.lua b/modules/straw/nodes.lua new file mode 100644 index 0000000..8606caa --- /dev/null +++ b/modules/straw/nodes.lua @@ -0,0 +1,71 @@ +local S = cottages.S + +if not (minetest.registered_nodes["farming:straw"]) then + minetest.register_node("cottages:straw", { + drawtype = "normal", + description = S("straw"), + tiles = {cottages.textures.straw}, + groups = {hay = 3, snappy = 2, oddly_breakable_by_hand = 2, flammable = 3}, + sounds = cottages.sounds.leaves, + -- the bale is slightly smaller than a full node + is_ground_content = false, + }) +else + minetest.register_alias("cottages:straw", "farming:straw") +end + + +minetest.register_node("cottages:straw_mat", { + description = S("layer of straw"), + drawtype = "nodebox", + tiles = {cottages.textures.straw}, -- done by VanessaE + wield_image = cottages.textures.straw, + inventory_image = cottages.textures.straw, + sunlight_propagates = true, + paramtype = "light", + paramtype2 = "facedir", + walkable = false, + groups = {hay = 3, snappy = 2, oddly_breakable_by_hand = 2, flammable = 3}, + sounds = cottages.sounds.leaves, + node_box = { + type = "fixed", + fixed = { + {-0.48, -0.5, -0.48, 0.48, -0.45, 0.48}, + } + }, + selection_box = { + type = "fixed", + fixed = { + {-0.48, -0.5, -0.48, 0.48, -0.25, 0.48}, + } + }, + is_ground_content = false, + on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) + return cottages.sleep_in_bed(pos, node, clicker, itemstack, pointed_thing) + end +}) + +-- straw bales are a must for farming environments; if you for some reason do not have the darkage mod installed, this +-- here gets you a straw bale +minetest.register_node("cottages:straw_bale", { + drawtype = "nodebox", + description = S("straw bale"), + tiles = {"cottages_darkage_straw_bale.png"}, + paramtype = "light", + groups = {hay = 3, snappy = 2, oddly_breakable_by_hand = 2, flammable = 3}, + sounds = cottages.sounds.leaves, + -- the bale is slightly smaller than a full node + node_box = { + type = "fixed", + fixed = { + {-0.45, -0.5, -0.45, 0.45, 0.45, 0.45}, + } + }, + selection_box = { + type = "fixed", + fixed = { + {-0.45, -0.5, -0.45, 0.45, 0.45, 0.45}, + } + }, + is_ground_content = false, +}) diff --git a/modules/straw/quern.lua b/modules/straw/quern.lua new file mode 100644 index 0000000..f4995cf --- /dev/null +++ b/modules/straw/quern.lua @@ -0,0 +1,180 @@ +local straw = cottages.straw + +local S = cottages.S +local F = minetest.formspec_escape +local FS = function(...) return F(S(...)) end + +local get_safe_short_description = futil.get_safe_short_description + +local has_stamina = cottages.has.stamina +local stamina_use = cottages.settings.straw.quern_stamina +local quern_min_per_turn = cottages.settings.straw.quern_min_per_turn +local quern_max_per_turn = cottages.settings.straw.quern_max_per_turn + + +function straw.get_quern_fs_parts() + return { + ("size[8,8]"), + ("image[0,1;1,1;%s]"):format(F(cottages.textures.wheat_seed)), + ("label[0,0.5;%s]"):format(FS("Input:")), + ("label[3,0.5;%s]"):format(FS("Output:")), + ("label[0,-0.3;%s]"):format(FS("Quern")), + ("label[0,2.5;%s]"):format(FS("Punch this hand-driven quern")), + ("label[0,3.0;%s]"):format(FS("to grind suitable items.")), + ("list[context;seeds;1,1;1,1;]"), + ("list[context;flour;4,1;2,2;]"), + ("list[current_player;main;0,4;8,4;]"), + ("listring[current_player;main]"), + ("listring[context;seeds]"), + ("listring[current_player;main]"), + ("listring[context;flour]"), + } +end + +function straw.get_quern_info(pos) + local meta = minetest.get_meta(pos) + + if meta:get_int("used") == 0 then + return S("quern, powered by punching") + + else + local inv = meta:get_inventory() + local input = inv:get_stack("seeds", 1) + local count = input:get_count() + + if count > 0 then + local input_description = get_safe_short_description(input) + return S("quern, @1 @2 remaining", count, input_description) + + else + return S("quern, none remaining") + end + end +end + +local function get_quern_results(input) + local item = input:get_name() + local output_def = straw.registered_quern_crafts[item] + if type(output_def) == "string" then + return {ItemStack(output_def)} + + elseif type(output_def) == "table" and #output_def > 0 then + local outputs = {} + for _, output_item in ipairs(output_def) do + if type(output_item) == "string" then + table.insert(outputs, ItemStack(output_item)) + + elseif type(output_item) == "table" then + local chance + output_item, chance = unpack(output_item) + if math.random() <= chance then + table.insert(outputs, ItemStack(output_item)) + end + end + end + + return outputs + + elseif type(output_def) == "function" then + return output_def() + end +end + +function straw.use_quern(pos, player) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + local input = inv:get_stack("seeds", 1) + + if input:is_empty() then + return + end + + local input_count = input:get_count() + local number_to_process = math.min(math.random(quern_min_per_turn, quern_max_per_turn), input_count) + + local above = vector.add(pos, vector.new(0, 1, 0)) + for _ = 1, number_to_process do + local results = get_quern_results(input:take_item(1)) + + for _, result in ipairs(results) do + local leftovers = inv:add_item("flour", result) + if not leftovers:is_empty() then + minetest.add_item(above, leftovers) + end + end + end + + inv:set_stack("seeds", 1, input) + + local node = minetest.get_node(pos) + node.param2 = (node.param2 + 1) % 4 + minetest.swap_node(pos, node) + + minetest.add_particlespawner({ + amount = 30, + time = 0.1, + collisiondetection = true, + texture = cottages.textures.dust, + minsize = 1, + maxsize = 1, + minexptime = 0.4, + maxexptime = 0.8, + minpos = vector.subtract(pos, 0.1), + maxpos = vector.add(pos, vector.new(0.1, 0, 0.1)), + minvel = vector.new(-1, -0.5, -1), + maxvel = vector.new(1, 0.5, 1), + minacc = vector.new(0, -3, 0), + maxacc = vector.new(0, -3, 0), + }) + + minetest.sound_play( + {name = cottages.sounds.use_quern}, + {pos = pos, gain = 1, pitch = 0.25}, + true + ) + + if has_stamina then + stamina.exhaust_player(player, stamina_use, "cottages:quern") + end + + return true +end + +cottages.api.register_machine("cottages:quern", { + description = S("quern-stone\npunch to operate"), + short_description = S("quern-stone"), + drawtype = "mesh", + mesh = "cottages_quern.obj", + tiles = {"cottages_stone.png"}, + selection_box = {type = "fixed", fixed = {{-0.50, -0.5, -0.50, 0.50, 0.25, 0.50}}}, + groups = {cracky = 2}, + sounds = cottages.sounds.stone, + + inv_info = { + seeds = 1, + flour = 4, + }, + + update_infotext = straw.update_quern_infotext, + update_formspec = straw.update_quern_formspec, + + allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player) + return 0 + end, + + allow_metadata_inventory_put = function(pos, listname, index, stack, player) + if listname == "flour" then + return 0 + end + + if listname == "seeds" and not cottages.straw.registered_quern_crafts[stack:get_name()] then + return 0 + end + + return stack:get_count() + end, + + use = straw.use_quern, + get_fs_parts = straw.get_quern_fs_parts, + get_info = straw.get_quern_info, +}) diff --git a/modules/straw/threshing.lua b/modules/straw/threshing.lua new file mode 100644 index 0000000..1987531 --- /dev/null +++ b/modules/straw/threshing.lua @@ -0,0 +1,243 @@ +local straw = cottages.straw + +local S = cottages.S +local F = minetest.formspec_escape +local FS = function(...) return F(S(...)) end + +local get_safe_short_description = futil.get_safe_short_description + +local has_stamina = cottages.has.stamina +local stamina_use = cottages.settings.straw.threshing_stamina +local threshing_min_per_punch = cottages.settings.straw.threshing_min_per_punch +local threshing_max_per_punch = cottages.settings.straw.threshing_max_per_punch + +function straw.get_threshing_fs_parts() + return { + ("size[8,8]"), + ("image[3,1;1,1;%s]"):format(F(cottages.textures.stick)), + ("image[0,1;1,1;%s]"):format(F(cottages.textures.wheat)), + ("label[1,0.5;%s]"):format(FS("Input:")), + ("label[3,0.0;%s]"):format(FS("Output:")), + ("label[0,0;%s]"):format(FS("Threshing Floor")), + ("label[0,2.5;%s]"):format(FS("Punch threshing floor with a stick")), + ("label[0,3.0;%s]"):format(FS("to get straw and seeds from wheat.")), + ("list[context;harvest;1,1;2,1;]"), + ("list[context;straw;4,0;2,2;]"), + ("list[context;seeds;4,2;2,2;]"), + ("list[current_player;main;0,4;8,4;]"), + ("listring[current_player;main]"), + ("listring[context;harvest]"), + ("listring[current_player;main]"), + ("listring[context;straw]"), + ("listring[current_player;main]"), + ("listring[context;seeds]"), + } +end + +function straw.get_threshing_info(pos) + local meta = minetest.get_meta(pos) + + if meta:get_int("used") == 0 then + return S("threshing floor") + + else + local inv = meta:get_inventory() + local input1 = inv:get_stack("harvest", 1) + local input2 = inv:get_stack("harvest", 2) + local count = input1:get_count() + input2:get_count() + + if count > 0 then + local input_description + if input1:is_empty() then + input_description = get_safe_short_description(input2) + + else + input_description = get_safe_short_description(input1) + end + return S("threshing floor, @1 @2 remaining", count, input_description) + + else + return S("threshing floor, none remaining") + end + end +end + +local function get_threshing_results(input) + local item = input:get_name() + local output_def = straw.registered_threshing_crafts[item] + if type(output_def) == "string" then + return {ItemStack(output_def)} + + elseif type(output_def) == "table" and #output_def > 0 then + local outputs = {} + for _, output_item in ipairs(output_def) do + if type(output_item) == "string" then + table.insert(outputs, ItemStack(output_item)) + + elseif type(output_item) == "table" then + local chance + output_item, chance = unpack(output_item) + if math.random() <= chance then + table.insert(outputs, ItemStack(output_item)) + end + end + end + + return outputs + + elseif type(output_def) == "function" then + return output_def() + end +end + +function straw.use_threshing(pos, player) + -- only punching with a normal stick is supposed to work + local wielded = player:get_wielded_item() + if minetest.get_item_group(wielded:get_name(), "stick") == 0 then + return + end + + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + + local input1 = inv:get_stack("harvest", 1) + local input2 = inv:get_stack("harvest", 2) + + local input_count = input1:get_count() + input2:get_count() + + if input_count == 0 then + return + end + + local number_to_process = math.min(math.random(threshing_min_per_punch, threshing_max_per_punch), input_count) + + for _ = 1, number_to_process do + local results + if input1:is_empty() then + results = get_threshing_results(input2:take_item(1)) + else + results = get_threshing_results(input1:take_item(1)) + end + + for _, result in ipairs(results) do + local leftovers = inv:add_item("straw", result) + if not leftovers:is_empty() then + leftovers = inv:add_item("seeds", result) + if not leftovers:is_empty() then + minetest.add_item(pos, leftovers) + end + end + end + end + + inv:set_stack("harvest", 1, input1) + inv:set_stack("harvest", 2, input2) + + local particle_pos = vector.subtract(pos, vector.new(0, 0.25, 0)) + minetest.add_particlespawner({ + amount = 10, + time = 0.1, + collisiondetection = true, + texture = cottages.textures.straw, + minsize = 1, + maxsize = 1, + minexptime = 0.2, + maxexptime = 0.4, + minpos = vector.subtract(particle_pos, 0.1), + maxpos = vector.add(particle_pos, 0.1), + minvel = vector.new(-3, 1, -3), + maxvel = vector.new(3, 2, 3), + minacc = vector.new(0, -10, 0), + maxacc = vector.new(0, -10, 0), + }) + + minetest.add_particlespawner({ + amount = 10, + time = 0.1, + collisiondetection = true, + texture = cottages.textures.wheat_seed, + minsize = 1, + maxsize = 1, + minexptime = 0.2, + maxexptime = 0.4, + minpos = vector.subtract(particle_pos, 0.1), + maxpos = vector.add(particle_pos, 0.1), + minvel = vector.new(-3, 0.5, -3), + maxvel = vector.new(3, 1, 3), + minacc = vector.new(0, -10, 0), + maxacc = vector.new(0, -10, 0), + }) + + minetest.sound_play( + {name = cottages.sounds.use_thresher}, + {pos = particle_pos, gain = 1, pitch = 0.5}, + true + ) + + if has_stamina then + stamina.exhaust_player(player, stamina_use, "cottages:quern") + end + + return true +end + +cottages.api.register_machine("cottages:threshing_floor", { + description = S("threshing floor\npunch with a stick to operate"), + short_description = S("threshing floor"), + drawtype = "nodebox", + node_box = { + type = "fixed", + fixed = { + {-0.50, -0.5, -0.50, 0.50, -0.40, 0.50}, + + {-0.50, -0.4, -0.50, -0.45, -0.20, 0.50}, + {0.45, -0.4, -0.50, 0.50, -0.20, 0.50}, + + {-0.45, -0.4, -0.50, 0.45, -0.20, -0.45}, + {-0.45, -0.4, 0.45, 0.45, -0.20, 0.50}, + } + }, + selection_box = { + type = "fixed", + fixed = { + {-0.50, -0.5, -0.50, 0.50, -0.20, 0.50}, + } + }, + tiles = { + "cottages_junglewood.png^farming_wheat.png", + "cottages_junglewood.png", + "cottages_junglewood.png^" .. cottages.textures.stick + }, + groups = {cracky = 2, choppy = 2}, + sounds = cottages.sounds.wood, + is_ground_content = false, + + inv_info = { + harvest = 2, + straw = 4, + seeds = 4, + }, + + update_infotext = straw.update_threshing_infotext, + update_formspec = straw.update_threshing_formspec, + + allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player) + return 0 + end, + + allow_metadata_inventory_put = function(pos, listname, index, stack, player) + if listname == "straw" or listname == "seeds" then + return 0 + end + + if not cottages.straw.registered_threshing_crafts[stack:get_name()] then + return 0 + end + + return stack:get_count() + end, + + use = straw.use_threshing, + get_fs_parts = straw.get_threshing_fs_parts, + get_info = straw.get_threshing_info, +}) diff --git a/modules/water/api.lua b/modules/water/api.lua new file mode 100644 index 0000000..c939e9c --- /dev/null +++ b/modules/water/api.lua @@ -0,0 +1,92 @@ +local ci = cottages.craftitems +local s = cottages.sounds + +local settings = cottages.settings.water + +local api = cottages.water + +local sound_handles_by_pos = {} +local particlespawner_ids_by_pos = {} + +function api.add_filling_effects(pos) + local entity_pos = vector.add(pos, vector.new(0, 1/4, 0)) + + local spos = minetest.pos_to_string(pos) + + local previous_handle = sound_handles_by_pos[spos] + if previous_handle then + minetest.sound_stop(previous_handle) + end + sound_handles_by_pos[spos] = minetest.sound_play( + {name = s.water_fill}, + {pos = entity_pos, loop = true, gain = 0.5, pitch = 2.0} + ) + + local previous_id = particlespawner_ids_by_pos[spos] + if previous_id then + minetest.delete_particlespawner(previous_id) + end + local particle_pos = vector.add(pos, vector.new(0, 1/2 + 1/16, 0)) + particlespawner_ids_by_pos[spos] = minetest.add_particlespawner({ + amount = 10, + time = 0, + collisiondetection = false, + texture = "bubble.png", + minsize = 1, + maxsize = 1, + minexptime = 0.4, + maxexptime = 0.4, + minpos = particle_pos, + maxpos = particle_pos, + minvel = vector.new(-0.1, -0.2, -0.01), + maxvel = vector.new(0.1, -0.2, 0.1), + minacc = vector.new(0, -2, 0), + maxacc = vector.new(0, -2, 0), + }) +end + +function api.fill_bucket(pos) + local entity_pos = vector.add(pos, vector.new(0, 1/4, 0)) + + for _, obj in ipairs(minetest.get_objects_inside_radius(entity_pos, .1)) do + local ent = obj:get_luaentity() + if ent and ent.name == "cottages:bucket_entity" then + local props = obj:get_properties() + props.wield_item = ci.bucket_filled + obj:set_properties(props) + end + end + + local meta = minetest.get_meta(pos) + meta:set_string("bucket", ci.bucket_filled) + + local spos = minetest.pos_to_string(pos) + local handle = sound_handles_by_pos[spos] + if handle then + minetest.sound_stop(handle) + end + local id = particlespawner_ids_by_pos[spos] + if id then + minetest.delete_particlespawner(id) + end +end + +function api.initialize_entity(pos) + local meta = minetest.get_meta(pos) + local bucket = meta:get("bucket") + if bucket then + local entity_pos = vector.add(pos, vector.new(0, 1/4, 0)) + local obj = minetest.add_entity(entity_pos, "cottages:bucket_entity") + local props = obj:get_properties() + props.wield_item = bucket + obj:set_properties(props) + + if bucket == ci.bucket then + local timer = minetest.get_node_timer(pos) + if not timer:is_started() then + timer:start(settings.well_fill_time) + end + api.add_filling_effects(pos) + end + end +end diff --git a/modules/water/crafts.lua b/modules/water/crafts.lua new file mode 100644 index 0000000..3ea6be3 --- /dev/null +++ b/modules/water/crafts.lua @@ -0,0 +1,12 @@ +local ci = cottages.craftitems + +if ci.stick and ci.tree and ci.stick and ci.bucket then + minetest.register_craft({ + output = "cottages:water_gen", + recipe = { + {ci.stick, "", ""}, + {ci.tree, ci.bucket, ci.tree}, + {ci.tree, ci.tree, ci.tree}, + } + }) +end diff --git a/modules/water/entity.lua b/modules/water/entity.lua new file mode 100644 index 0000000..3000010 --- /dev/null +++ b/modules/water/entity.lua @@ -0,0 +1,14 @@ +local ci = cottages.craftitems + +minetest.register_entity("cottages:bucket_entity", { + initial_properties = { + visual = "wielditem", + automatic_rotate = 1, + wield_item = ci.bucket, + visual_size = {x = 0.33, y = 0.33}, + collisionbox = {0, 0, 0, 0, 0, 0}, + pointable = false, + physical = false, + static_save = false, + }, +}) diff --git a/modules/water/init.lua b/modules/water/init.lua new file mode 100644 index 0000000..55cd941 --- /dev/null +++ b/modules/water/init.lua @@ -0,0 +1,10 @@ +if not (cottages.craftitems.bucket and cottages.craftitems.bucket_filled) then + return +end + +cottages.water = {} + +cottages.dofile("modules", "water", "api") +cottages.dofile("modules", "water", "entity") +cottages.dofile("modules", "water", "well") +cottages.dofile("modules", "water", "crafts") diff --git a/modules/water/well.lua b/modules/water/well.lua new file mode 100644 index 0000000..af36bea --- /dev/null +++ b/modules/water/well.lua @@ -0,0 +1,174 @@ +local F = minetest.formspec_escape +local S = cottages.S +local FS = function(...) return F(S(...)) end + +local s = cottages.sounds +local t = cottages.textures +local water = cottages.water +local ci = cottages.craftitems + +local well_fill_time = cottages.settings.water.well_fill_time + +function water.get_well_fs_parts(pos) + return { + ("size[8,9]"), + ("label[3.0,0.0;%s]"):format(FS("Tree trunk well")), + ("label[0,0.7;%s]"):format(FS("Punch the well while wielding an empty bucket.")), + ("label[0,1.0;%s]"):format(FS("Your bucket will slowly be filled with river water.")), + ("label[0,1.3;%s]"):format(FS("Punch again to get the bucket back when it is full.")), + ("label[0,1.9;%s]"):format(FS("Punch well with full water bucket in order to empty bucket.")), + ("label[1.0,2.9;%s]"):format(FS("Internal bucket storage (passive storage only):")), + ("item_image[0,2.8;1.0,1.0;%s]"):format(F(ci.bucket)), + ("item_image[0,3.8;1.0,1.0;%s]"):format(F(ci.bucket_filled)), + ("list[context;main;1,3.3;8,1;]"), + ("list[current_player;main;0,4.85;8,4;]"), + ("listring[]"), + } +end + +function water.get_well_info(pos) + return S("Tree trunk well") +end + +function water.use_well(pos, puncher) + local player_name = puncher:get_player_name() + local meta = minetest.get_meta(pos) + + local pinv = puncher:get_inventory() + local bucket = meta:get("bucket") + + local entity_pos = vector.add(pos, vector.new(0, 1/4, 0)) + + if not bucket then + local wielded = puncher:get_wielded_item() + local wielded_name = wielded:get_name() + if wielded_name == ci.bucket then + meta:set_string("bucket", wielded_name) + + minetest.add_entity(entity_pos, "cottages:bucket_entity") + + pinv:remove_item("main", "bucket:bucket_empty") + + local timer = minetest.get_node_timer(pos) + timer:start(well_fill_time) + + water.add_filling_effects(pos) + + elseif wielded_name == ci.bucket_filled then + -- empty a bucket + pinv:remove_item("main", ci.bucket_filled) + pinv:add_item("main", ci.bucket) + + minetest.sound_play( + {name = s.water_empty}, + {pos = entity_pos, gain = 0.5, pitch = 2.0}, + true + ) + end + + elseif bucket == ci.bucket then + minetest.chat_send_player(player_name, S("Please wait until your bucket has been filled.")) + local timer = minetest.get_node_timer(pos) + if not timer:is_started() then + timer:start(well_fill_time) + water.add_filling_effects(pos) + end + + elseif bucket == ci.bucket_filled then + meta:set_string("bucket", "") + + for _, obj in ipairs(minetest.get_objects_inside_radius(entity_pos, .1)) do + local ent = obj:get_luaentity() + if ent and ent.name == "cottages:bucket_entity" then + obj:remove() + end + end + + pinv:add_item("main", ci.bucket_filled) + end +end + + +cottages.api.register_machine("cottages:water_gen", { + description = S("Tree Trunk Well"), + tiles = {t.tree_top, ("%s^[transformR90"):format(t.tree), ("%s^[transformR90"):format(t.tree)}, + drawtype = "nodebox", + paramtype = "light", + paramtype2 = "facedir", + + is_ground_content = false, + groups = {choppy = 2, cracky = 1, flammable = 2}, + sounds = cottages.sounds.wood, + + inv_info = { + main = 6, + }, + + node_box = { + type = "fixed", + fixed = { + -- floor of water bassin + {-0.5, -0.5 + (3 / 16), -0.5, 0.5, -0.5 + (4 / 16), 0.5}, + -- walls + {-0.5, -0.5 + (3 / 16), -0.5, 0.5, (4 / 16), -0.5 + (2 / 16)}, + {-0.5, -0.5 + (3 / 16), -0.5, -0.5 + (2 / 16), (4 / 16), 0.5}, + {0.5, -0.5 + (3 / 16), 0.5, 0.5 - (2 / 16), (4 / 16), -0.5}, + {0.5, -0.5 + (3 / 16), 0.5, -0.5 + (2 / 16), (4 / 16), 0.5 - (2 / 16)}, + -- feet + {-0.5 + (3 / 16), -0.5, -0.5 + (3 / 16), -0.5 + (6 / 16), -0.5 + (3 / 16), 0.5 - (3 / 16)}, + {0.5 - (3 / 16), -0.5, -0.5 + (3 / 16), 0.5 - (6 / 16), -0.5 + (3 / 16), 0.5 - (3 / 16)}, + -- real pump + {0.5 - (4 / 16), -0.5, -(2 / 16), 0.5, 0.5 + (4 / 16), (2 / 16)}, + -- water pipe inside wooden stem + {0.5 - (8 / 16), 0.5 + (1 / 16), -(1 / 16), 0.5, 0.5 + (3 / 16), (1 / 16)}, + -- where the water comes out + {0.5 - (15 / 32), 0.5, -(1 / 32), 0.5 - (12 / 32), 0.5 + (1 / 16), (1 / 32)}, + }, + }, + selection_box = { + type = "fixed", + fixed = {-0.5, -0.5, -0.5, 0.5, 0.5 + (4 / 16), 0.5} + }, + + + get_fs_parts = water.get_well_fs_parts, + get_info = water.get_well_info, + + can_dig = function(pos, player) + local meta = minetest.get_meta(pos) + return not meta:get("bucket") + end, + + allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player) + return 0 + end, + + allow_metadata_inventory_put = function(pos, listname, index, stack, player) + local sname = stack:get_name() + if sname ~= ci.bucket and sname ~= ci.bucket_filled then + return 0 + end + + return stack:get_count() + end, + + allow_metadata_inventory_take = function(pos, listname, index, stack, player) + return stack:get_count() + end, + + on_timer = function(pos, elapsed) + water.fill_bucket(pos) + end, + + use = water.use_well, +}) + +minetest.register_lbm({ + name = "cottages:add_well_entity", + label = "Initialize entity to cottages well", + nodenames = {"cottages:water_gen"}, + run_at_every_load = true, + action = function(pos, node) + water.initialize_entity(pos) + end +}) diff --git a/nodes_anvil.lua b/nodes_anvil.lua deleted file mode 100644 index 0b7149c..0000000 --- a/nodes_anvil.lua +++ /dev/null @@ -1,323 +0,0 @@ ---------------------------------------------------------------------------------------- --- simple anvil that can be used to repair tools ---------------------------------------------------------------------------------------- --- * can be used to repair tools --- * the hammer gets dammaged a bit at each repair step ---------------------------------------------------------------------------------------- --- License of the hammer picture: CC-by-SA; done by GloopMaster; source: --- https://github.com/GloopMaster/glooptest/blob/master/glooptest/textures/glooptest_tool_steelhammer.png - -local S = cottages.S - --- disable repair with anvil by setting a message for the item in question -cottages.forbid_repair = {} --- example for hammer no longer beeing able to repair the hammer ---cottages.forbid_repair["cottages:hammer"] = 'The hammer is too complex for repairing.' - - --- the hammer for the anvil -minetest.register_tool("cottages:hammer", { - description = S("Steel hammer for repairing tools on the anvil"), - image = "glooptest_tool_steelhammer.png", - inventory_image = "glooptest_tool_steelhammer.png", - - tool_capabilities = { - full_punch_interval = 0.8, - max_drop_level=1, - groupcaps={ - -- about equal to a stone pick (it's not intended as a tool) - cracky={times={[2]=2.00, [3]=1.20}, uses=30, maxlevel=1}, - }, - damage_groups = {fleshy=6}, - } -}) - - -local cottages_anvil_formspec = - "size[8,8]".. - "image[7,3;1,1;glooptest_tool_steelhammer.png]".. --- "list[current_name;sample;0,0.5;1,1;]".. - "list[current_name;input;2.5,1.5;1,1;]".. --- "list[current_name;material;5,0;3,3;]".. - "list[current_name;hammer;5,3;1,1;]".. --- "label[0.0,0.0;Sample:]".. --- "label[0.0,1.0;(Receipe)]".. - "label[2.5,1.0;"..S("Workpiece:").."]".. --- "label[6.0,-0.5;Materials:]".. - "label[6.0,2.7;"..S("Optional").."]".. - "label[6.0,3.0;"..S("storage for").."]".. - "label[6.0,3.3;"..S("your hammer").."]".. - - "label[0,-0.5;"..S("Anvil").."]".. - "label[0,3.0;"..S("Punch anvil with hammer to").."]".. - "label[0,3.3;"..S("repair tool in workpiece-slot.").."]".. - "list[current_player;main;0,4;8,4;]"; - - -minetest.register_node("cottages:anvil", { - drawtype = "nodebox", - description = S("anvil"), - tiles = {"cottages_stone.png"}, -- TODO default_steel_block.png, default_obsidian.png are also nice - paramtype = "light", - paramtype2 = "facedir", - groups = {cracky=2}, - -- the nodebox model comes from realtest - node_box = { - type = "fixed", - fixed = { - {-0.5,-0.5,-0.3,0.5,-0.4,0.3}, - {-0.35,-0.4,-0.25,0.35,-0.3,0.25}, - {-0.3,-0.3,-0.15,0.3,-0.1,0.15}, - {-0.35,-0.1,-0.2,0.35,0.1,0.2}, - }, - }, - selection_box = { - type = "fixed", - fixed = { - {-0.5,-0.5,-0.3,0.5,-0.4,0.3}, - {-0.35,-0.4,-0.25,0.35,-0.3,0.25}, - {-0.3,-0.3,-0.15,0.3,-0.1,0.15}, - {-0.35,-0.1,-0.2,0.35,0.1,0.2}, - } - }, - on_construct = function(pos) - - local meta = minetest.get_meta(pos); - meta:set_string("infotext", S("Anvil")); - local inv = meta:get_inventory(); - inv:set_size("input", 1); --- inv:set_size("material", 9); --- inv:set_size("sample", 1); - inv:set_size("hammer", 1); - meta:set_string("formspec", cottages_anvil_formspec ); - end, - - after_place_node = function(pos, placer) - local meta = minetest.get_meta(pos); - meta:set_string("owner", placer:get_player_name() or ""); - meta:set_string("infotext", S("Anvil (owned by %s)"):format((meta:get_string("owner") or ""))); - meta:set_string("formspec", - cottages_anvil_formspec, - "label[2.5,-0.5;"..S("Owner: %s"):format(meta:get_string('owner') or "").."]"); - end, - - can_dig = function(pos,player) - - local meta = minetest.get_meta(pos); - local inv = meta:get_inventory(); - local owner = meta:get_string('owner'); - - if( not( inv:is_empty("input")) --- or not( inv:is_empty("material")) --- or not( inv:is_empty("sample")) - or not( inv:is_empty("hammer")) - or not( player ) - or ( owner and owner ~= '' and player:get_player_name() ~= owner )) then - - return false; - end - return true; - end, - - allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player) - local meta = minetest.get_meta(pos) - if( player and player:get_player_name() ~= meta:get_string('owner' ) and from_list~="input") then - return 0 - end - return count; - end, - - allow_metadata_inventory_put = function(pos, listname, index, stack, player) - local meta = minetest.get_meta(pos) - if( player and player:get_player_name() ~= meta:get_string('owner' ) and listname~="input") then - return 0; - end - if( listname=='hammer' and stack and stack:get_name() ~= 'cottages:hammer') then - return 0; - end - if( listname=='input' - and( stack:get_wear() == 0 - or stack:get_name() == "technic:water_can" - or stack:get_name() == "technic:lava_can" )) then - - minetest.chat_send_player( player:get_player_name(), - S('The workpiece slot is for damaged tools only.')); - return 0; - end - if( listname=='input' - and cottages.forbid_repair[ stack:get_name() ]) then - minetest.chat_send_player( player:get_player_name(), - S(cottages.forbid_repair[ stack:get_name() ])); - return 0; - end - return stack:get_count() - end, - - allow_metadata_inventory_take = function(pos, listname, index, stack, player) - local meta = minetest.get_meta(pos) - if( player and player:get_player_name() ~= meta:get_string('owner' ) and listname~="input") then - return 0 - end - return stack:get_count() - end, - - - on_punch = function(pos, node, puncher) - if( not( pos ) or not( node ) or not( puncher )) then - return; - end - -- only punching with the hammer is supposed to work - local wielded = puncher:get_wielded_item(); - if( not( wielded ) or not( wielded:get_name() ) or wielded:get_name() ~= 'cottages:hammer') then - return; - end - local name = puncher:get_player_name(); - - local meta = minetest.get_meta(pos); - local inv = meta:get_inventory(); - - local input = inv:get_stack('input',1); - - -- only tools can be repaired - if( not( input ) - or input:is_empty() - or input:get_name() == "technic:water_can" - or input:get_name() == "technic:lava_can" ) then - - meta:set_string("formspec", - cottages_anvil_formspec, - "label[2.5,-0.5;"..S("Owner: %s"):format(meta:get_string('owner') or "").."]"); - return; - end - - -- 65535 is max damage - local damage_state = 40-math.floor(input:get_wear()/1638); - - -- just to make sure that it really can't get repaired if it should not - -- (if the check of placing the item in the input slot failed somehow) - if( puncher and name and cottages.forbid_repair[ input:get_name() ]) then - minetest.chat_send_player( name, - S(cottages.forbid_repair[ input:get_name() ])); - return; - end - - local tool_name = input:get_name(); - local hud_image = ""; - if( tool_name - and minetest.registered_items[ tool_name ] ) then - if( minetest.registered_items[ tool_name ].inventory_image ) then - hud_image = minetest.registered_items[ tool_name ].inventory_image; - elseif( minetest.registered_items[ tool_name ].textures - and type(minetest.registered_items[ tool_name ].textures)=='table') then - hud_image = minetest.registered_items[ tool_name ].textures[1]; - elseif( minetest.registered_items[ tool_name ].textures - and type(minetest.registered_items[ tool_name ].textures)=='string') then - hud_image = minetest.registered_items[ tool_name ].textures; - end - end - - local hud1 = puncher:hud_add({ - hud_elem_type = "image", - scale = {x = 15, y = 15}, - text = hud_image, - position = {x = 0.5, y = 0.5}, - alignment = {x = 0, y = 0} - }); - local hud2 = nil; - local hud3 = nil; - if( input:get_wear()>0 ) then - hud2 = puncher:hud_add({ - hud_elem_type = "statbar", - text = "default_cloud.png^[colorize:#ff0000:256", - number = 40, - direction = 0, -- left to right - position = {x=0.5, y=0.65}, - alignment = {x = 0, y = 0}, - offset = {x = -320, y = 0}, - size = {x=32, y=32}, - }) - hud3 = puncher:hud_add({ - hud_elem_type = "statbar", - text = "default_cloud.png^[colorize:#00ff00:256", - number = damage_state, - direction = 0, -- left to right - position = {x=0.5, y=0.65}, - alignment = {x = 0, y = 0}, - offset = {x = -320, y = 0}, - size = {x=32, y=32}, - }); - end - minetest.after(2, function() - if( puncher ) then - if(hud1) then puncher:hud_remove(hud1); end - if(hud2) then puncher:hud_remove(hud2); end - if(hud3) then puncher:hud_remove(hud3); end - end - end) - - -- tell the player when the job is done - if( input:get_wear() == 0 ) then --- minetest.chat_send_player( puncher:get_player_name(), --- S('Your tool has been repaired successfully.')); - return; - end - - -- do the actual repair - input:add_wear( -5000 ); -- equals to what technic toolshop does in 5 seconds - inv:set_stack("input", 1, input) - - -- damage the hammer slightly - wielded:add_wear( 100 ); - puncher:set_wielded_item( wielded ); - - -- do not spam too much --- if( math.random( 1,5 )==1 ) then --- minetest.chat_send_player( puncher:get_player_name(), --- S('Your workpiece improves.')); --- end - end, - is_ground_content = false, -}) - - - ---------------------------------------------------------------------------------------- --- crafting receipes ---------------------------------------------------------------------------------------- -minetest.register_craft({ - output = "cottages:anvil", - recipe = { - {cottages.craftitem_steel,cottages.craftitem_steel,cottages.craftitem_steel}, - {'', cottages.craftitem_steel,'' }, - {cottages.craftitem_steel,cottages.craftitem_steel,cottages.craftitem_steel} }, -}) - - --- the castle-mod has an anvil as well - with the same receipe. convert the two into each other -if ( minetest.get_modpath("castle") ~= nil ) then - - minetest.register_craft({ - output = "cottages:anvil", - recipe = { - {'castle:anvil'}, - }, - }) - - minetest.register_craft({ - output = "castle:anvil", - recipe = { - {'cottages:anvil'}, - }, - }) -end - - - -minetest.register_craft({ - output = "cottages:hammer", - recipe = { - {cottages.craftitem_steel}, - {'cottages:anvil'}, - {cottages.craftitem_stick} } -}) - diff --git a/nodes_barrel.lua b/nodes_barrel.lua deleted file mode 100644 index 4c84983..0000000 --- a/nodes_barrel.lua +++ /dev/null @@ -1,214 +0,0 @@ - ---------------------------------------------------------------------- --- a barrel and a tub - plus a function that makes 'round' objects ---------------------------------------------------------------------- --- IMPORTANT NOTE: The barrel requires a lot of nodeboxes. That may be --- too much for weak hardware! ---------------------------------------------------------------------- --- Functionality: right-click to open/close a barrel; --- punch a barrel to change between vertical/horizontal ---------------------------------------------------------------------- --- Changelog: --- 24.03.13 Can no longer be opended/closed on rightclick because that is now used for a formspec; --- instead, it can be filled with liquids. --- Filled barrels will always be closed, while empty barrels will always be open. - --- pipes: table with the following entries for each pipe-part: --- f: radius factor; if 1, it will have a radius of half a nodebox and fill the entire nodebox --- h1, h2: height at witch the nodebox shall start and end; usually -0.5 and 0.5 for a full nodebox --- b: make a horizontal part/shelf --- horizontal: if 1, then x and y coordinates will be swapped - --- TODO: option so that it works without nodeboxes - -local S = cottages.S - -barrel = {}; - --- prepare formspec -barrel.on_construct = function( pos ) - - local meta = minetest.get_meta(pos); - local percent = math.random( 1, 100 ); -- TODO: show real filling - - meta:set_string( 'formspec', - "size[8,9]".. - "image[2.6,2;2,3;default_sandstone.png^[lowpart:".. - (100-percent)..":default_desert_stone.png]".. -- TODO: better images - "label[2.2,0;"..S("Pour:").."]".. - "list[current_name;input;3,0.5;1,1;]".. - "label[5,3.3;"..S("Fill:").."]".. - "list[current_name;output;5,3.8;1,1;]".. - "list[current_player;main;0,5;8,4;]"); - - - meta:set_string( 'liquid_type', '' ); -- which liquid is in the barrel? - meta:set_int( 'liquid_level', 0 ); -- how much of the liquid is in there? - - local inv = meta:get_inventory() - inv:set_size("input", 1); -- to fill in new liquid - inv:set_size("output", 1); -- to extract liquid -end - - --- can only be digged if there are no more vessels/buckets in any of the slots --- TODO: allow digging of a filled barrel? this would disallow stacking of them -barrel.can_dig = function( pos, player ) - local meta = minetest.get_meta(pos); - local inv = meta:get_inventory() - - return ( inv:is_empty('input') - and inv:is_empty('output')); -end - - --- the barrel received input; either a new liquid that is to be poured in or a vessel that is to be filled -barrel.on_metadata_inventory_put = function( pos, listname, index, stack, player ) -end - - --- right-click to open/close barrel; punch to switch between horizontal/vertical position - minetest.register_node("cottages:barrel", { - description = S("barrel (closed)"), - paramtype = "light", - drawtype = "mesh", - mesh = "cottages_barrel_closed.obj", - tiles = {"cottages_barrel.png" }, - groups = { tree = 1, snappy = 1, choppy = 2, oddly_breakable_by_hand = 1, flammable = 2 - }, - drop = "cottages:barrel", --- on_rightclick = function(pos, node, puncher) --- minetest.add_node(pos, {name = "cottages:barrel_open", param2 = node.param2}) --- end, --- TODO: on_rightclick is no longer available - maybe open if empty and closed if full? - on_punch = function(pos, node, puncher) - minetest.add_node(pos, {name = "cottages:barrel_lying", param2 = node.param2}) - end, - - on_construct = function( pos ) - return barrel.on_construct( pos ); - end, - can_dig = function(pos,player) - return barrel.can_dig( pos, player ); - end, - on_metadata_inventory_put = function(pos, listname, index, stack, player) - return barrel.on_metadata_inventory_put( pos, listname, index, stack, player ); - end, - is_ground_content = false, - - }) - - -- this barrel is opened at the top - minetest.register_node("cottages:barrel_open", { - description = S("barrel (open)"), - paramtype = "light", - drawtype = "mesh", - mesh = "cottages_barrel.obj", - tiles = {"cottages_barrel.png" }, - groups = { tree = 1, snappy = 1, choppy = 2, oddly_breakable_by_hand = 1, flammable = 2, not_in_creative_inventory=1, - }, - drop = "cottages:barrel", --- on_rightclick = function(pos, node, puncher) --- minetest.add_node(pos, {name = "cottages:barrel", param2 = node.param2}) --- end, - on_punch = function(pos, node, puncher) - minetest.add_node(pos, {name = "cottages:barrel_lying_open", param2 = node.param2}) - end, - is_ground_content = false, - }) - - -- horizontal barrel - minetest.register_node("cottages:barrel_lying", { - description = S("barrel (closed), lying somewhere"), - paramtype = "light", - paramtype2 = "facedir", - drawtype = "mesh", - mesh = "cottages_barrel_closed_lying.obj", - tiles = {"cottages_barrel.png" }, - groups = { tree = 1, snappy = 1, choppy = 2, oddly_breakable_by_hand = 1, flammable = 2, not_in_creative_inventory=1, - }, - drop = "cottages:barrel", - on_rightclick = function(pos, node, puncher) - minetest.add_node(pos, {name = "cottages:barrel_lying_open", param2 = node.param2}) - end, - on_punch = function(pos, node, puncher) - if( node.param2 < 4 ) then - minetest.add_node(pos, {name = "cottages:barrel_lying", param2 = (node.param2+1)}) - else - minetest.add_node(pos, {name = "cottages:barrel", param2 = 0}) - end - end, - is_ground_content = false, - }) - - -- horizontal barrel, open - minetest.register_node("cottages:barrel_lying_open", { - description = S("barrel (opened), lying somewhere"), - paramtype = "light", - paramtype2 = "facedir", - drawtype = "mesh", - mesh = "cottages_barrel_lying.obj", - tiles = {"cottages_barrel.png" }, - groups = { tree = 1, snappy = 1, choppy = 2, oddly_breakable_by_hand = 1, flammable = 2, not_in_creative_inventory=1, - }, - drop = "cottages:barrel", - on_rightclick = function(pos, node, puncher) - minetest.add_node(pos, {name = "cottages:barrel_lying", param2 = node.param2}) - end, - on_punch = function(pos, node, puncher) - if( node.param2 < 4 ) then - minetest.add_node(pos, {name = "cottages:barrel_lying_open", param2 = (node.param2+1)}) - else - minetest.add_node(pos, {name = "cottages:barrel_open", param2 = 0}) - end - end, - is_ground_content = false, - - }) - - -- let's hope "tub" is the correct english word for "bottich" - minetest.register_node("cottages:tub", { - description = S("tub"), - paramtype = "light", - drawtype = "mesh", - mesh = "cottages_tub.obj", - tiles = {"cottages_barrel.png" }, - selection_box = { - type = "fixed", - fixed = { - {-0.5, -0.5, -0.5, 0.5,-0.1, 0.5}, - }}, - collision_box = { - type = "fixed", - fixed = { - {-0.5, -0.5, -0.5, 0.5,-0.1, 0.5}, - }}, - groups = { tree = 1, snappy = 1, choppy = 2, oddly_breakable_by_hand = 1, flammable = 2 - }, - is_ground_content = false, - }) - - -minetest.register_craft({ - output = "cottages:barrel", - recipe = { - {cottages.craftitem_wood, "", cottages.craftitem_wood }, - {cottages.craftitem_steel, "", cottages.craftitem_steel}, - {cottages.craftitem_wood, cottages.craftitem_wood, cottages.craftitem_wood }, - }, -}) - -minetest.register_craft({ - output = "cottages:tub 2", - recipe = { - {"cottages:barrel"}, - }, -}) - -minetest.register_craft({ - output = "cottages:barrel", - recipe = { - {"cottages:tub"}, - {"cottages:tub"}, - }, -}) diff --git a/nodes_chests.lua b/nodes_chests.lua deleted file mode 100644 index c099749..0000000 --- a/nodes_chests.lua +++ /dev/null @@ -1,61 +0,0 @@ - --- TODO: make these chests as chests and indicate that they are owned by npc --- TODO: add bags (not for carrying around but for decoration) - --- Boilerplate to support localized strings if intllib mod is installed. -local S = cottages.S - -cottages_chests = {} --- uses default.chest_formspec for now -cottages_chests.on_construct = function(pos) - local meta = minetest.get_meta(pos) - meta:set_string("formspec",default.chest_formspec) --- meta:set_string("infotext", "Chest") - local inv = meta:get_inventory() - inv:set_size("main", 8*4) - end - -cottages_chests.can_dig = function(pos,player) - local meta = minetest.get_meta(pos); - local inv = meta:get_inventory() - return inv:is_empty("main") - end - --- the chests do not need receipes since they are only placeholders and not intended to be built by players --- (they are later on supposed to be filled with diffrent items by fill_chest.lua) -minetest.register_node("cottages:chest_private", { - description = S("private NPC chest"), - infotext = "chest containing the possesions of one of the inhabitants", - tiles = cottages.texture_chest, - paramtype2 = "facedir", - groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2}, - legacy_facedir_simple = true, - on_construct = cottages_chests.on_construct, - can_dig = cottages_chests.can_dig, - is_ground_content = false, -}) - -minetest.register_node("cottages:chest_work", { - description = S("chest for work utils and kitchens"), - infotext = "everything the inhabitant needs for his work", - tiles = cottages.texture_chest, - paramtype2 = "facedir", - groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2}, - legacy_facedir_simple = true, - on_construct = cottages_chests.on_construct, - can_dig = cottages_chests.can_dig, - is_ground_content = false, -}) - -minetest.register_node("cottages:chest_storage", { - description = S("storage chest"), - infotext = "stored food reserves", - tiles = cottages.texture_chest, - paramtype2 = "facedir", - groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2}, - legacy_facedir_simple = true, - on_construct = cottages_chests.on_construct, - can_dig = cottages_chests.can_dig, - is_ground_content = false, -}) - diff --git a/nodes_doorlike.lua b/nodes_doorlike.lua deleted file mode 100644 index d989c05..0000000 --- a/nodes_doorlike.lua +++ /dev/null @@ -1,437 +0,0 @@ - ------------------------------------------------------------------------------------------------------------ --- These nodes are all like doors in a way: --- * window shutters (they open on right-click and when it turns day; they close at night) --- * a half-door where the top part can be opened seperately from the bottom part --- * a gate that drops to the floor when opened --- ------------------------------------------------------------------------------------------------------------ --- IMPORTANT NOTICE: If you have a very slow computer, it might be wise to increase the rate at which the --- abm that opens/closes the window shutters is called. Anything less than 10 minutes --- (600 seconds) ought to be ok. ------------------------------------------------------------------------------------------------------------ -local S = cottages.S - ------------------------------------------------------------------------------------------------------------ --- small window shutters for single-node-windows; they open at day and close at night if the abm is working ------------------------------------------------------------------------------------------------------------ - --- propagate shutting/closing of window shutters to window shutters below/above this one -cottages_window_sutter_operate = function( pos, old_node_state_name, new_node_state_name ) - - local offsets = {-1,1,-2,2,-3,3}; - local stop_up = 0; - local stop_down = 0; - - for i,v in ipairs(offsets) do - - local node = minetest.get_node_or_nil( {x=pos.x, y=(pos.y+v), z=pos.z } ); - if( node and node.name and node.name==old_node_state_name - and ( (v > 0 and stop_up == 0 ) - or (v < 0 and stop_down == 0 ))) then - - minetest.swap_node({x=pos.x, y=(pos.y+v), z=pos.z }, {name = new_node_state_name, param2 = node.param2}) - - -- found a diffrent node - no need to search further up - elseif( v > 0 and stop_up == 0 ) then - stop_up = 1; - - elseif( v < 0 and stop_down == 0 ) then - stop_down = 1; - end - end -end - --- window shutters - they cover half a node to each side -minetest.register_node("cottages:window_shutter_open", { - description = S("opened window shutters"), - drawtype = "nodebox", - -- top, bottom, side1, side2, inner, outer - tiles = {"cottages_minimal_wood.png"}, - paramtype = "light", - paramtype2 = "facedir", - groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2}, - -- larger than one node but slightly smaller than a half node so that wallmounted torches pose no problem - node_box = { - type = "fixed", - fixed = { - {-0.90, -0.5, 0.4, -0.45, 0.5, 0.5}, - { 0.45, -0.5, 0.4, 0.9, 0.5, 0.5}, - }, - }, - selection_box = { - type = "fixed", - fixed = { - {-0.9, -0.5, 0.4, 0.9, 0.5, 0.5}, - }, - }, - on_rightclick = function(pos, node, puncher) - minetest.swap_node(pos, {name = "cottages:window_shutter_closed", param2 = node.param2}) - cottages_window_sutter_operate( pos, "cottages:window_shutter_open", "cottages:window_shutter_closed" ); - end, - is_ground_content = false, -}) - -minetest.register_node("cottages:window_shutter_closed", { - description = S("closed window shutters"), - drawtype = "nodebox", - -- top, bottom, side1, side2, inner, outer - tiles = {"cottages_minimal_wood.png"}, - paramtype = "light", - paramtype2 = "facedir", - groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2,not_in_creative_inventory=1}, - node_box = { - type = "fixed", - fixed = { - {-0.5, -0.5, 0.4, -0.05, 0.5, 0.5}, - { 0.05, -0.5, 0.4, 0.5, 0.5, 0.5}, - }, - }, - selection_box = { - type = "fixed", - fixed = { - {-0.5, -0.5, 0.4, 0.5, 0.5, 0.5}, - }, - }, - on_rightclick = function(pos, node, puncher) - minetest.swap_node(pos, {name = "cottages:window_shutter_open", param2 = node.param2}) - cottages_window_sutter_operate( pos, "cottages:window_shutter_closed", "cottages:window_shutter_open" ); - end, - is_ground_content = false, - drop = "cottages:window_shutter_open", -}) - - --- open shutters in the morning -minetest.register_abm({ - nodenames = {"cottages:window_shutter_closed"}, - interval = 20, -- change this to 600 if your machine is too slow - chance = 3, -- not all people wake up at the same time! - action = function(pos) - - -- at this time, sleeping in a bed is not possible - if( not(minetest.get_timeofday() < 0.2 or minetest.get_timeofday() > 0.805)) then - local old_node = minetest.get_node( pos ); - minetest.swap_node(pos, {name = "cottages:window_shutter_open", param2 = old_node.param2}) - cottages_window_sutter_operate( pos, "cottages:window_shutter_closed", "cottages:window_shutter_open" ); - end - end -}) - - --- close them at night -minetest.register_abm({ - nodenames = {"cottages:window_shutter_open"}, - interval = 20, -- change this to 600 if your machine is too slow - chance = 2, - action = function(pos) - - -- same time at which sleeping is allowed in beds - if( minetest.get_timeofday() < 0.2 or minetest.get_timeofday() > 0.805) then - local old_node = minetest.get_node( pos ); - minetest.swap_node(pos, {name = "cottages:window_shutter_closed", param2 = old_node.param2}) - cottages_window_sutter_operate( pos, "cottages:window_shutter_open", "cottages:window_shutter_closed" ); - end - end -}) - - ------------------------------------------------------------------------------------------------------------------------------- --- a half door; can be combined to a full door where the upper part can be operated seperately; usually found in barns/stables ------------------------------------------------------------------------------------------------------------------------------- -minetest.register_node("cottages:half_door", { - description = S("half door"), - drawtype = "nodebox", - -- top, bottom, side1, side2, inner, outer - tiles = {"cottages_minimal_wood.png"}, - paramtype = "light", - paramtype2 = "facedir", - groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2}, - node_box = { - type = "fixed", - fixed = { - {-0.5, -0.5, 0.4, 0.48, 0.5, 0.5}, - }, - }, - selection_box = { - type = "fixed", - fixed = { - {-0.5, -0.5, 0.4, 0.48, 0.5, 0.5}, - }, - }, - on_rightclick = function(pos, node, puncher) - local node2 = minetest.get_node( {x=pos.x,y=(pos.y+1),z=pos.z}); - - local param2 = node.param2; - if( param2%4 == 1) then param2 = param2+1; --2; - elseif( param2%4 == 2) then param2 = param2-1; --1; - elseif( param2%4 == 3) then param2 = param2-3; --0; - elseif( param2%4 == 0) then param2 = param2+3; --3; - end; - minetest.swap_node(pos, {name = "cottages:half_door", param2 = param2}) - -- if the node above consists of a door of the same type, open it as well - -- Note: doors beneath this one are not opened! It is a special feature of these doors that they can be opend partly - if( node2 ~= nil and node2.name == node.name and node2.param2==node.param2) then - minetest.swap_node( {x=pos.x,y=(pos.y+1),z=pos.z}, {name = "cottages:half_door", param2 = param2}) - end - end, - is_ground_content = false, -}) - - - -minetest.register_node("cottages:half_door_inverted", { - description = S("half door inverted"), - drawtype = "nodebox", - -- top, bottom, side1, side2, inner, outer - tiles = {"cottages_minimal_wood.png"}, - paramtype = "light", - paramtype2 = "facedir", - groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2}, - node_box = { - type = "fixed", - fixed = { - {-0.5, -0.5, -0.5, 0.48, 0.5, -0.4}, - }, - }, - selection_box = { - type = "fixed", - fixed = { - {-0.5, -0.5, -0.5, 0.48, 0.5, -0.4}, - }, - }, - on_rightclick = function(pos, node, puncher) - local node2 = minetest.get_node( {x=pos.x,y=(pos.y+1),z=pos.z}); - - local param2 = node.param2; - if( param2%4 == 1) then param2 = param2-1; --0; - elseif( param2%4 == 0) then param2 = param2+1; --1; - elseif( param2%4 == 2) then param2 = param2+1; --3; - elseif( param2%4 == 3) then param2 = param2-1; --2; - end; - minetest.swap_node(pos, {name = "cottages:half_door_inverted", param2 = param2}) - -- open upper parts of this door (if there are any) - if( node2 ~= nil and node2.name == node.name and node2.param2==node.param2) then - minetest.swap_node( {x=pos.x,y=(pos.y+1),z=pos.z}, {name = "cottages:half_door_inverted", param2 = param2}) - end - end, - is_ground_content = false, -}) - - - - ------------------------------------------------------------------------------------------------------------------------------- --- this gate for fences solves the "where to store the opened gate" problem by dropping it to the floor in optened state ------------------------------------------------------------------------------------------------------------------------------- -minetest.register_node("cottages:gate_closed", { - description = S("closed fence gate"), - drawtype = "nodebox", - -- top, bottom, side1, side2, inner, outer - tiles = {cottages.texture_furniture}, - paramtype = "light", - paramtype2 = "facedir", - groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2}, - node_box = { - type = "fixed", - fixed = { - { -0.85, -0.25, -0.02, 0.85, -0.05, 0.02}, - { -0.85, 0.15, -0.02, 0.85, 0.35, 0.02}, - - { -0.80, -0.05, -0.02, -0.60, 0.15, 0.02}, - { 0.60, -0.05, -0.02, 0.80, 0.15, 0.02}, - { -0.15, -0.05, -0.02, 0.15, 0.15, 0.02}, - }, - }, - selection_box = { - type = "fixed", - fixed = { - { -0.85, -0.25, -0.1, 0.85, 0.35, 0.1}, - }, - }, - on_rightclick = function(pos, node, puncher) - minetest.swap_node(pos, {name = "cottages:gate_open", param2 = node.param2}) - end, - is_ground_content = false, -}) - - -minetest.register_node("cottages:gate_open", { - description = S("opened fence gate"), - drawtype = "nodebox", - -- top, bottom, side1, side2, inner, outer - tiles = {cottages.texture_furniture}, - paramtype = "light", - paramtype2 = "facedir", - drop = "cottages:gate_closed", - groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2,not_in_creative_inventory=1}, - node_box = { - type = "fixed", - fixed = { - { -0.85, -0.5, -0.25, 0.85, -0.46, -0.05}, - { -0.85, -0.5, 0.15, 0.85, -0.46, 0.35}, - - { -0.80, -0.5, -0.05, -0.60, -0.46, 0.15}, - { 0.60, -0.5, -0.05, 0.80, -0.46, 0.15}, - { -0.15, -0.5, -0.05, 0.15, -0.46, 0.15}, - - }, - }, - selection_box = { - type = "fixed", - fixed = { - { -0.85, -0.5, -0.25, 0.85, -0.3, 0.35}, - }, - }, - on_rightclick = function(pos, node, puncher) - minetest.swap_node(pos, {name = "cottages:gate_closed", param2 = node.param2}) - end, - is_ground_content = false, - drop = "cottages:gate_closed", -}) - - - ------------------------------------------------------------------------------------------------------------ --- a hatch; nodebox definition taken from realtest ------------------------------------------------------------------------------------------------------------ - --- hatches rotate around their axis --- old facedir: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,16,17,18,19,20,21,22,23 -new_facedirs = { 10,19, 4,13, 2,18,22,14,20,16, 0,12,11, 3, 7,21, 9,23, 5, 1, 8,15, 6,17}; - - -cottages.register_hatch = function( nodename, description, texture, receipe_item ) - - minetest.register_node( nodename, { - description = S(description), -- not that there are any other... - drawtype = "nodebox", - -- top, bottom, side1, side2, inner, outer - tiles = { texture }, - paramtype = "light", - paramtype2 = "facedir", - groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2}, - - node_box = { - type = "fixed", - fixed = { - {-0.49, -0.55, -0.49, -0.3, -0.45, 0.45}, --- {-0.5, -0.55, 0.3, 0.3, -0.45, 0.5}, - {0.3, -0.55, -0.3, 0.49, -0.45, 0.45}, - {0.49, -0.55, -0.49, -0.3, -0.45, -0.3}, - {-0.075, -0.55, -0.3, 0.075, -0.45, 0.3}, - {-0.3, -0.55, -0.075, -0.075, -0.45, 0.075}, - {0.075, -0.55, -0.075, 0.3, -0.45, 0.075}, - - {-0.3, -0.55, 0.3, 0.3, -0.45, 0.45}, - - -- hinges - {-0.45,-0.530, 0.45, -0.15,-0.470, 0.525}, - { 0.15,-0.530, 0.45, 0.45,-0.470, 0.525}, - - -- handle - {-0.05,-0.60,-0.35, 0.05,-0.40,-0.45}, - }, - }, - selection_box = { - type = "fixed", - fixed = {-0.5, -0.55, -0.5, 0.5, -0.45, 0.5}, - }, - on_rightclick = function(pos, node, puncher) - - minetest.swap_node(pos, {name = node.name, param2 = new_facedirs[ node.param2+1 ]}) - end, - is_ground_content = false, - on_place = minetest.rotate_node, - }) - - minetest.register_craft({ - output = nodename, - recipe = { - { '', '', receipe_item }, - { receipe_item, cottages.craftitem_stick, '' }, - { '', '', '' }, - } - }) -end - - --- further alternate hatch materials: wood, tree, copper_block -cottages.register_hatch( 'cottages:hatch_wood', 'wooden hatch', 'cottages_minimal_wood.png', cottages.craftitem_slab_wood ); -cottages.register_hatch( 'cottages:hatch_steel', 'metal hatch', 'cottages_steel_block.png', cottages.craftitem_steel ); - - - - ------------------------------------------------------------------------------------------------------------ --- and now the crafting receipes: ------------------------------------------------------------------------------------------------------------ - --- transform opend and closed shutters into each other for convenience -minetest.register_craft({ - output = "cottages:window_shutter_open", - recipe = { - {"cottages:window_shutter_closed" }, - } -}) - -minetest.register_craft({ - output = "cottages:window_shutter_closed", - recipe = { - {"cottages:window_shutter_open" }, - } -}) - -minetest.register_craft({ - output = "cottages:window_shutter_open", - recipe = { - {cottages.craftitem_wood, "", cottages.craftitem_wood }, - } -}) - --- transform one half door into another -minetest.register_craft({ - output = "cottages:half_door", - recipe = { - {"cottages:half_door_inverted" }, - } -}) - -minetest.register_craft({ - output = "cottages:half_door_inverted", - recipe = { - {"cottages:half_door" }, - } -}) - -minetest.register_craft({ - output = "cottages:half_door 2", - recipe = { - {"", cottages.craftitem_wood, "" }, - {"", cottages.craftitem_door, "" }, - } -}) - - --- transform open and closed versions into into another for convenience -minetest.register_craft({ - output = "cottages:gate_closed", - recipe = { - {"cottages:gate_open" }, - } -}) - -minetest.register_craft({ - output = "cottages:gate_open", - recipe = { - {"cottages:gate_closed"}, - } -}) - -minetest.register_craft({ - output = "cottages:gate_closed", - recipe = { - {cottages.craftitem_stick, cottages.craftitem_stick, cottages.craftitem_wood }, - } -}) - diff --git a/nodes_feldweg.lua b/nodes_feldweg.lua deleted file mode 100644 index fb516e9..0000000 --- a/nodes_feldweg.lua +++ /dev/null @@ -1,612 +0,0 @@ ---------------------------------------------------------------------------------------- --- decoration and building material ---------------------------------------------------------------------------------------- --- * includes a wagon wheel that can be used as decoration on walls or to build (stationary) wagons --- * dirt road - those are more natural in small old villages than cobble roads --- * loam - no, old buildings are usually not built out of clay; loam was used --- * straw - useful material for roofs --- * glass pane - an improvement compared to fence posts as windows :-) ---------------------------------------------------------------------------------------- - -local S = cottages.S - --- supported modes: --- * simple: only a straight dirt road; no curves, junctions etc. --- * flat: each node is a full node; junction, t-junction and corner are included --- * nodebox: like flat - except that each node has a nodebox that fits to that road node --- * mesh: like nodebox - except that it uses a nice roundish model -local cottages_feldweg_mode = minetest.settings:get("cottages_feldweg_mode") -if( cottages_feldweg_mode ~= "mesh" - and cottages_feldweg_mode ~= "flat" - and cottages_feldweg_mode ~= "nodebox" - and cottages_feldweg_mode ~= "mesh_incl_45") then - cottages_feldweg_mode = "mesh"; - -- add the setting to the minetest.conf so that the player can set it there - minetest.settings:set("cottages_feldweg_mode", "mesh") -end - - --- make sure groups etc. are always the same -cottages.register_feldweg_node = function(node_name, def) - def.paramtype = "light" - def.paramtype2 = "facedir" - def.legacy_facedir_simple = true - def.groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2,crumbly=2} - def.sounds = cottages.sounds.dirt - def.is_ground_content = false - - minetest.register_node(node_name, def) -end - - -local function register_recipes(include_end, postfix, base_craftitem) - - if(not(postfix)) then - postfix = "" - end - if(not(base_craftitem)) then - base_craftitem = cottages.craftitem_dirt - end - local base_node = "cottages:feldweg"..postfix - - -- run a wagon wheel over dirt :-) - minetest.register_craft({ - output = base_node.." 4", - recipe = { - {"", "cottages:wagon_wheel", "" }, - {base_craftitem, base_craftitem, base_craftitem} - }, - replacements = { {'cottages:wagon_wheel', 'cottages:wagon_wheel'}, } - }) - - - minetest.register_craft({ - output = "cottages:feldweg_crossing"..postfix.." 5", - recipe = { - {"", base_node, "" }, - {base_node, base_node, base_node}, - {"", base_node, "" }, - }, - }) - - minetest.register_craft({ - output = "cottages:feldweg_t_junction"..postfix.." 5", - recipe = { - {"", base_node, "" }, - {"", base_node, "" }, - {base_node, base_node, base_node} - - }, - }) - - minetest.register_craft({ - output = "cottages:feldweg_curve"..postfix.." 5", - recipe = { - {base_node, "", "" }, - {base_node, "", ""}, - {base_node, base_node, base_node} - }, - }) - - if include_end then - minetest.register_craft({ - output = "cottages:feldweg_end"..postfix.." 5", - recipe = { - {base_node, "", base_node }, - {base_node, base_node, base_node} - }, - }) - end - - -- if the 45 degree version is loaded - if(minetest.registered_nodes["cottages:feldweg_45"..postfix]) then - minetest.register_craft({ - output = "cottages:feldweg_45"..postfix, - recipe = {{base_node}} - }) - minetest.register_craft({ - output = "cottages:feldweg_l_curve"..postfix, - recipe = {{"cottages:feldweg_45"..postfix}} - }) - minetest.register_craft({ - output = "cottages:feldweg_r_curve"..postfix, - recipe = {{"cottages:feldweg_l_curve"..postfix}} - }) - minetest.register_craft({ - output = "cottages:feldweg_s_45"..postfix, - recipe = {{"cottages:feldweg_r_curve"..postfix}} - }) - minetest.register_craft({ - output = "cottages:feldweg_d_45"..postfix, - recipe = {{"cottages:feldweg_s_45"..postfix}} - }) - minetest.register_craft({ - output = "cottages:feldweg"..postfix, - recipe = {{"cottages:feldweg_d_45"..postfix}} - }) - end -end - --- ignore_mode is unused here (exists just for compatibility with the _mesh version of the function) -cottages.register_nodes_slope = function(postfix, texture_top, texture_bottom, texture_side, ignore_mode, name_postfix, texture_side_with_dent, texture_edges) - if(not(postfix)) then - postfix = "" - end - local box_slope = { - type = "fixed", - fixed = { - {-0.5, -0.5, -0.5, 0.5, -0.25, 0.5}, - {-0.5, -0.25, -0.25, 0.5, 0, 0.5}, - {-0.5, 0, 0, 0.5, 0.25, 0.5}, - {-0.5, 0.25, 0.25, 0.5, 0.5, 0.5} - }}; - - local box_slope_long = { - type = "fixed", - fixed = { - {-0.5, -0.5, -1.5, 0.5, -0.10, 0.5}, - {-0.5, -0.25, -1.3, 0.5, -0.25, 0.5}, - {-0.5, -0.25, -1.0, 0.5, 0, 0.5}, - {-0.5, 0, -0.5, 0.5, 0.25, 0.5}, - {-0.5, 0.25, 0, 0.5, 0.5, 0.5} - }}; - - cottages.register_feldweg_node("cottages:feldweg_slope"..postfix, { - description = S("dirt road slope"..name_postfix), - tiles = {texture_side_with_dent, - texture_side, texture_bottom, texture_top, - "cottages_feldweg_surface.png", - texture_edges}, - drawtype = "mesh", - mesh = "feldweg_slope.obj", - - collision_box = box_slope, - selection_box = box_slope, - }) - - - cottages.register_feldweg_node("cottages:feldweg_slope_long"..postfix, { - description = S("dirt road slope long"..name_postfix), - tiles = {texture_side_with_dent, - texture_side, texture_bottom, texture_top, - "cottages_feldweg_surface.png", - texture_edges}, - drawtype = "mesh", - mesh = "feldweg_slope_long.obj", - collision_box = box_slope_long, - selection_box = box_slope_long, - }) - - local base_node = "cottages:feldweg"..postfix - - minetest.register_craft({ - output = "cottages:feldweg_slope"..postfix.." 3", - recipe = { - {base_node, "", "" }, - {base_node, base_node, ""} - }, - }) - - minetest.register_craft({ - output = "cottages:feldweg_slope_long"..postfix.." 4", - recipe = { - {base_node, "", "" }, - {base_node, base_node, base_node} - }, - }) -end - --- those can be offered in diffrent variants... -cottages.register_nodes_mesh = function(postfix, texture_top, texture_bottom, texture_side, cottages_feldweg_mode, name_postfix, texture_side_with_dent, texture_edges) - -- a nice dirt road for small villages or paths to fields - cottages.register_feldweg_node("cottages:feldweg"..postfix, { - description = S("dirt road"..name_postfix), - tiles = {texture_side_with_dent, - -- "default_dirt.png^default_grass_side.png", "default_dirt.png", "default_grass.png", - texture_side, texture_bottom, texture_top, - "cottages_feldweg_surface.png", - texture_edges}, - drawtype = "mesh", - mesh = "feldweg.obj", - }) - - - cottages.register_feldweg_node("cottages:feldweg_crossing"..postfix, { - description = S("dirt road crossing"..name_postfix), - tiles = {texture_side_with_dent, - --"default_dirt.png", "default_grass.png", - texture_bottom, texture_top, - "cottages_feldweg_surface.png", - texture_edges}, - drawtype = "mesh", - mesh = "feldweg-crossing.obj", - }) - - cottages.register_feldweg_node("cottages:feldweg_t_junction"..postfix, { - description = S("dirt road t junction"..name_postfix), - tiles = {texture_side_with_dent, - -- "default_dirt.png^default_grass_side.png", "default_dirt.png", "default_grass.png", - texture_side, texture_bottom, texture_top, - "cottages_feldweg_surface.png", - texture_edges}, - drawtype = "mesh", - mesh = "feldweg-T-junction.obj", - }) - - cottages.register_feldweg_node("cottages:feldweg_curve"..postfix, { - description = S("dirt road curve"..name_postfix), - tiles = { - -- "default_dirt.png^default_grass_side.png","default_grass.png", - texture_side, texture_top, - -- "default_dirt.png^default_grass_side.png", - texture_side, - "cottages_feldweg_surface.png", - -- "default_dirt.png", - texture_bottom, - texture_edges}, - -- "default_dirt.png^default_grass_side.png", "default_dirt.png", "default_grass.png", - texture_side, texture_bottom, texture_top, - drawtype = "mesh", - mesh = "feldweg-curve.obj", - }) - - cottages.register_feldweg_node("cottages:feldweg_end"..postfix, { - description = S("dirt road end"..name_postfix), - tiles = {texture_side_with_dent, - -- "default_dirt.png^default_grass_side.png", "default_dirt.png", "default_grass.png", - texture_side, texture_bottom, texture_top, - texture_edges, - "cottages_feldweg_surface.png"}, - drawtype = "mesh", - mesh = "feldweg_end.obj", - }) - - if( cottages_feldweg_mode ~= "mesh_incl_45" ) then - return - end - - -- new feldweg - cottages.register_feldweg_node("cottages:feldweg_45"..postfix, { - description = S("dirt road 45º"..name_postfix), - tiles = { - "cottages_feldweg_surface.png", - texture_edges, - -- "default_dirt.png^default_grass_side.png", "default_dirt.png", "default_grass.png", - texture_side, texture_bottom, texture_top, - }, - drawtype = "mesh", - mesh = "feldweg_45.b3d", - }) - - cottages.register_feldweg_node("cottages:feldweg_s_45"..postfix, { - description = S("dirt road 45º edge"..name_postfix), - tiles = { - -- "default_grass.png", "default_dirt.png^default_grass_side.png", "default_dirt.png", - texture_top, texture_side, texture_bottom, - "cottages_feldweg_surface.png", - texture_edges, - }, - drawtype = "mesh", - mesh = "feldweg_s_45.b3d", - }) - - cottages.register_feldweg_node("cottages:feldweg_d_45"..postfix, { - description = S("dirt road 45º double edge"..name_postfix), - tiles = { - -- "default_dirt.png^default_grass_side.png", "default_dirt.png", "default_grass.png", - texture_side, texture_bottom, texture_top, - texture_edges, - "cottages_feldweg_surface.png", - }, - drawtype = "mesh", - mesh = "feldweg_d_45.b3d", - }) - - cottages.register_feldweg_node("cottages:feldweg_l_curve"..postfix, { - description = S("dirt road left curve"..name_postfix), - tiles = { - -- "default_dirt.png^default_grass_side.png", "default_dirt.png", "default_grass.png", - texture_side, texture_bottom, texture_top, - texture_edges, - "cottages_feldweg_surface.png", - }, - drawtype = "mesh", - mesh = "feldweg_l_45_curve.b3d", - }) - - cottages.register_feldweg_node("cottages:feldweg_r_curve"..postfix, { - description = S("dirt road right curve"..name_postfix), - tiles = { - -- "default_dirt.png^default_grass_side.png", "default_dirt.png", "default_grass.png", - texture_side, texture_bottom, texture_top, - texture_edges, - "cottages_feldweg_surface.png", - }, - drawtype = "mesh", - mesh = "feldweg_r_45_curve.b3d", - }) -end - - - - ---- a nice dirt road for small villages or paths to fields -if( cottages_feldweg_mode == "simple" or cottages_feldweg_mode == "flat" ) then - cottages.register_feldweg_node("cottages:feldweg", { - description = S("dirt road"), - tiles = {"cottages_feldweg.png","default_dirt.png", "default_dirt.png^default_grass_side.png"}, - }) -end - --- add crossing, t-junction and corner - --- --- flat - just textures, full blocks --- -if( cottages_feldweg_mode == "flat" ) then - - cottages.register_feldweg_node("cottages:feldweg_crossing", { - description = S("dirt road crossing"), - tiles = {"cottages_feldweg_kreuzung.png","default_dirt.png", "default_dirt.png^default_grass_side.png"}, - paramtype2 = "facedir", - }) - - cottages.register_feldweg_node("cottages:feldweg_t_junction", { - description = S("dirt road t junction"), - tiles = {"cottages_feldweg_t-kreuzung.png^[transform2","default_dirt.png", "default_dirt.png^default_grass_side.png"}, - }) - - cottages.register_feldweg_node("cottages:feldweg_curve", { - description = S("dirt road curve"), - tiles = {"cottages_feldweg_ecke.png^[transform2","default_dirt.png", "default_dirt.png^default_grass_side.png"}, - }) - - register_recipes(false) --- --- cube-style nodebox version --- -elseif( cottages_feldweg_mode == "nodebox" ) then - cottages.register_feldweg_node("cottages:feldweg", { - description = S("dirt road"), - tiles = {"cottages_feldweg_orig.png","default_dirt.png", "default_dirt.png^default_grass_side.png"}, - paramtype2 = "facedir", - drawtype = "nodebox", - -- top, bottom, side1, side2, inner, outer - paramtype = "light", - node_box = { - type = "fixed", - fixed = { - { -0.5, -0.5, -0.5, 0.5, 0.5-2/16, 0.5}, - -- Rasenkanten - { -0.5, 0.5-2/16, -0.5, -0.5+3/16, 0.5, 0.5}, - { 0.5-3/16, 0.5-2/16, -0.5, 0.5, 0.5, 0.5}, - -- uebergang zwischen Wagenspur und Rasenkante - { -0.5+3/16, 0.5-2/16, -0.5, -0.5+4/16, 0.5-1/16, 0.5}, - { 0.5-4/16, 0.5-2/16, -0.5, 0.5-3/16, 0.5-1/16, 0.5}, - }, - }, - selection_box = { - type = "fixed", - fixed = { - { -0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, - }, - }, - }) - - cottages.register_feldweg_node("cottages:feldweg_crossing", { - description = S("dirt road crossing"), - tiles = {"cottages_feldweg_kreuzung.png","default_dirt.png", "default_dirt.png^default_grass_side.png"}, - drawtype = "nodebox", - -- top, bottom, side1, side2, inner, outer - node_box = { - type = "fixed", - fixed = { - { -0.5, -0.5, -0.5, 0.5, 0.5-2/16, 0.5}, - -- Rasenkanten - { -0.5, 0.5-2/16, -0.5, -0.5+3/16, 0.5, -0.5+3/16}, - { 0.5-3/16, 0.5-2/16, -0.5, 0.5, 0.5, -0.5+3/16}, - - { -0.5, 0.5-2/16, 0.5-3/16, -0.5+3/16, 0.5, 0.5}, - { 0.5-3/16, 0.5-2/16, 0.5-3/16, 0.5, 0.5, 0.5}, - -- uebergang zwischen Wagenspur und Rasenkante - { -0.5+3/16, 0.5-2/16, -0.5, -0.5+4/16, 0.5-1/16, -0.5+4/16}, - { 0.5-4/16, 0.5-2/16, -0.5, 0.5-3/16, 0.5-1/16, -0.5+4/16}, - - { -0.5+3/16, 0.5-2/16, 0.5-4/16, -0.5+4/16, 0.5-1/16, 0.5}, - { 0.5-4/16, 0.5-2/16, 0.5-4/16, 0.5-3/16, 0.5-1/16, 0.5}, - - - { -0.5, 0.5-2/16, -0.5+3/16, -0.5+3/16, 0.5-1/16, -0.5+4/16}, - { 0.5-3/16, 0.5-2/16, -0.5+3/16, 0.5, 0.5-1/16, -0.5+4/16}, - - { -0.5, 0.5-2/16, 0.5-4/16, -0.5+3/16, 0.5-1/16, 0.5-3/16}, - { 0.5-3/16, 0.5-2/16, 0.5-4/16, 0.5, 0.5-1/16, 0.5-3/16}, - }, - }, - selection_box = { - type = "fixed", - fixed = { - { -0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, - }, - }, - }) - - cottages.register_feldweg_node("cottages:feldweg_t_junction", { - description = S("dirt road t junction"), - tiles = {"cottages_feldweg_t-kreuzung.png^[transform2","default_dirt.png", "default_dirt.png^default_grass_side.png"}, - drawtype = "nodebox", - -- top, bottom, side1, side2, inner, outer - node_box = { - type = "fixed", - fixed = { - { -0.5, -0.5, -0.5, 0.5, 0.5-2/16, 0.5}, - -- Rasenkanten - { -0.5, 0.5-2/16, -0.5, -0.5+3/16, 0.5, -0.5+3/16}, - - { -0.5, 0.5-2/16, 0.5-3/16, -0.5+3/16, 0.5, 0.5}, - -- Rasenkante seitlich durchgehend - { 0.5-3/16, 0.5-2/16, -0.5, 0.5, 0.5, 0.5}, - -- uebergang zwischen Wagenspur und Rasenkante - { -0.5+3/16, 0.5-2/16, -0.5, -0.5+4/16, 0.5-1/16, -0.5+4/16}, - - { -0.5+3/16, 0.5-2/16, 0.5-4/16, -0.5+4/16, 0.5-1/16, 0.5}, - - - { -0.5, 0.5-2/16, -0.5+3/16, -0.5+3/16, 0.5-1/16, -0.5+4/16}, - - { -0.5, 0.5-2/16, 0.5-4/16, -0.5+3/16, 0.5-1/16, 0.5-3/16}, - -- Ueberganng seitlich durchgehend - { 0.5-4/16, 0.5-2/16, -0.5, 0.5-3/16, 0.5-1/16, 0.5}, - }, - }, - selection_box = { - type = "fixed", - fixed = { - { -0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, - }, - }, - }) - - cottages.register_feldweg_node("cottages:feldweg_curve", { - description = S("dirt road curve"), - tiles = {"cottages_feldweg_ecke.png^[transform2","default_dirt.png", "default_dirt.png^default_grass_side.png"}, - drawtype = "nodebox", - node_box = { - type = "fixed", - fixed = { - { -0.5, -0.5, -0.5, 0.5, 0.5-2/16, 0.5}, - -- Rasenkante vorne durchgehend - { -0.5, 0.5-2/16, -0.5, 0.5-3/16, 0.5, -0.5+3/16}, - - -- Rasenkanten - { -0.5, 0.5-2/16, 0.5-3/16, -0.5+3/16, 0.5, 0.5}, - -- Rasenkante seitlich durchgehend - { 0.5-3/16, 0.5-2/16, -0.5, 0.5, 0.5, 0.5}, - -- uebergang zwischen Wagenspur und Rasenkante - { -0.5+3/16, 0.5-2/16, 0.5-4/16, -0.5+4/16, 0.5-1/16, 0.5}, - - - -- Uebergang vorne durchgehend - { -0.5, 0.5-2/16, -0.5+3/16, 0.5-3/16, 0.5-1/16, -0.5+4/16}, - - { -0.5, 0.5-2/16, 0.5-4/16, -0.5+3/16, 0.5-1/16, 0.5-3/16}, - -- Ueberganng seitlich durchgehend - { 0.5-4/16, 0.5-2/16, -0.5, 0.5-3/16, 0.5-1/16, 0.5}, - }, - }, - selection_box = { - type = "fixed", - fixed = { - { -0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, - }, - }, - }) - - register_recipes(false) - - --- --- the mesh version (rounded); provided and created by VanessaE --- -elseif( cottages_feldweg_mode == "mesh" - or cottages_feldweg_mode == "mesh_incl_45" ) then - - - local variants = {} - variants["grass"] = { - "default_grass.png", -- grass top - "default_dirt.png", -- bottom - "default_dirt.png^default_grass_side.png", -- side - "", - "default:dirt", - "", - "cottages_feldweg_end.png", - "cottages_feldweg_surface.png^cottages_feldweg_edges.png", - } - variants["gravel"] = { - "default_gravel.png", -- grass top - "default_gravel.png", -- bottom - "default_gravel.png", -- side - "_gravel", - "default:gravel", - " on gravel", - "default_gravel.png", - "cottages_feldweg_surface.png^default_gravel.png", - } - variants["coniferous"] = { - "default_coniferous_litter.png", -- grass top - "default_dirt.png", -- bottom - "default_dirt.png^default_coniferous_litter_side.png", -- side - "_coniferous", - "default:dirt_with_coniferous_litter", - " on coniferious litter", - "default_dirt.png^default_coniferous_litter_side.png", -- side with dent - "cottages_feldweg_surface.png^default_coniferous_litter.png", - } - variants["snow"] = { - "default_snow.png", -- grass top - "default_dirt.png", -- bottom - "default_dirt.png^default_snow_side.png", -- side - "_snow", - "default:dirt_with_snow", - " on snow", - "default_dirt.png^default_snow_side.png", -- side - "cottages_feldweg_surface.png^default_snow.png", - } - variants["dry"] = { - "default_dry_grass.png", -- grass top - "default_dirt.png", -- bottom - "default_dirt.png^default_dry_grass_side.png", -- side - "_dry", - "default:dry_dirt", - " on dry dirt", - "default_dirt.png^default_dry_grass_side.png", -- side - "cottages_feldweg_surface.png^default_dry_grass.png", - } - variants["bamboo"] = { - "ethereal_grass_bamboo_top.png", -- grass top - "default_dirt.png", -- bottom - "default_dirt.png^ethereal_grass_bamboo_side.png", -- side - "_bamboo", - "ethereal:bamboo_dirt", - " on bamboo dirt", - "default_dirt.png^ethereal_grass_bamboo_side.png", -- side - "cottages_feldweg_surface.png^ethereal_grass_bamboo_top.png", - } - - for k, v in pairs(variants) do - cottages.register_nodes_mesh(v[4], v[1], v[2], v[3], cottages_feldweg_mode, v[6], v[7], v[8]) - register_recipes(true, v[4], v[5]) - -- register the two slope nodes - cottages.register_nodes_slope(v[4], v[1], v[2], v[3], cottages_feldweg_mode, v[6], v[7], v[8]) - end -end - - - --- create stairs if possible -if( minetest.get_modpath("stairs") and stairs and stairs.register_stair_and_slab) then - stairs.register_stair_and_slab("feldweg", "cottages:feldweg", - {snappy=2,choppy=2,oddly_breakable_by_hand=2}, - {"cottages_feldweg.png","default_dirt.png", "default_grass.png","default_grass.png","cottages_feldweg.png","cottages_feldweg.png"}, - S("Dirt Road Stairs"), - S("Dirt Road, half height"), - cottages.sounds.dirt) -end - -if( cottages_feldweg_mode == "nodebox") then - local variants = {} - variants["grass"] = { - "default_grass.png", -- grass top - "default_dirt.png", -- bottom - "default_dirt.png^default_grass_side.png", -- side - "", - "default:dirt", - "", - "cottages_feldweg_end.png", - "cottages_feldweg_surface.png^cottages_feldweg_edges.png", - } - for k, v in pairs(variants) do - cottages.register_nodes_slope(v[4], v[1], v[2], v[3], cottages_feldweg_mode, v[6], v[7], v[8]) - end -end diff --git a/nodes_fences.lua b/nodes_fences.lua deleted file mode 100644 index 0a4a26f..0000000 --- a/nodes_fences.lua +++ /dev/null @@ -1,159 +0,0 @@ --- 22.01.13 Changed texture to that of the wood from the minimal development game - -local S = cottages.S - -minetest.register_node("cottages:fence_small", { - description = S("small fence"), - drawtype = "nodebox", - -- top, bottom, side1, side2, inner, outer - tiles = {"cottages_minimal_wood.png"}, - paramtype = "light", - paramtype2 = "facedir", - groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2}, - node_box = { - type = "fixed", - fixed = { - { -0.45, -0.35, 0.46, 0.45, -0.20, 0.50}, - { -0.45, 0.00, 0.46, 0.45, 0.15, 0.50}, - { -0.45, 0.35, 0.46, 0.45, 0.50, 0.50}, - - { -0.50, -0.50, 0.46, -0.45, 0.50, 0.50}, - { 0.45, -0.50, 0.46, 0.50, 0.50, 0.50}, - }, - }, - selection_box = { - type = "fixed", - fixed = { - { -0.50, -0.50, 0.4, 0.50, 0.50, 0.5}, - }, - }, - is_ground_content = false, -}) - - -minetest.register_node("cottages:fence_corner", { - description = S("small fence corner"), - drawtype = "nodebox", - -- top, bottom, side1, side2, inner, outer - tiles = {"cottages_minimal_wood.png"}, - paramtype = "light", - paramtype2 = "facedir", - groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2}, - node_box = { - type = "fixed", - fixed = { - { -0.45, -0.35, 0.46, 0.45, -0.20, 0.50}, - { -0.45, 0.00, 0.46, 0.45, 0.15, 0.50}, - { -0.45, 0.35, 0.46, 0.45, 0.50, 0.50}, - - { -0.50, -0.50, 0.46, -0.45, 0.50, 0.50}, - { 0.45, -0.50, 0.46, 0.50, 0.50, 0.50}, - - { 0.46, -0.35, -0.45, 0.50, -0.20, 0.45}, - { 0.46, 0.00, -0.45, 0.50, 0.15, 0.45}, - { 0.46, 0.35, -0.45, 0.50, 0.50, 0.45}, - - { 0.46, -0.50, -0.50, 0.50, 0.50, -0.45}, - { 0.46, -0.50, 0.45, 0.50, 0.50, 0.50}, - }, - }, - selection_box = { - type = "fixed", - fixed = { - { -0.50, -0.50,-0.5, 0.50, 0.50, 0.5}, - }, - }, - is_ground_content = false, -}) - - -minetest.register_node("cottages:fence_end", { - description = S("small fence end"), - drawtype = "nodebox", - -- top, bottom, side1, side2, inner, outer - tiles = {"cottages_minimal_wood.png"}, - paramtype = "light", - paramtype2 = "facedir", - groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2}, - node_box = { - type = "fixed", - fixed = { - { -0.45, -0.35, 0.46, 0.45, -0.20, 0.50}, - { -0.45, 0.00, 0.46, 0.45, 0.15, 0.50}, - { -0.45, 0.35, 0.46, 0.45, 0.50, 0.50}, - - { -0.50, -0.50, 0.46, -0.45, 0.50, 0.50}, - { 0.45, -0.50, 0.46, 0.50, 0.50, 0.50}, - - { 0.46, -0.35, -0.45, 0.50, -0.20, 0.45}, - { 0.46, 0.00, -0.45, 0.50, 0.15, 0.45}, - { 0.46, 0.35, -0.45, 0.50, 0.50, 0.45}, - - { 0.46, -0.50, -0.50, 0.50, 0.50, -0.45}, - { 0.46, -0.50, 0.45, 0.50, 0.50, 0.50}, - - { -0.50, -0.35, -0.45, -0.46, -0.20, 0.45}, - { -0.50, 0.00, -0.45, -0.46, 0.15, 0.45}, - { -0.50, 0.35, -0.45, -0.46, 0.50, 0.45}, - - { -0.50, -0.50, -0.50, -0.46, 0.50, -0.45}, - { -0.50, -0.50, 0.45, -0.46, 0.50, 0.50}, - }, - }, - selection_box = { - type = "fixed", - fixed = { - { -0.50, -0.50,-0.5, 0.50, 0.50, 0.5}, - }, - }, - is_ground_content = false, -}) - -minetest.register_craft({ - output = "cottages:fence_small 3", - recipe = { - {cottages.craftitem_fence, cottages.craftitem_fence}, - } -}) - --- xfences can be configured to replace normal fences - which makes them uncraftable -if ( minetest.get_modpath("xfences") ~= nil ) then - minetest.register_craft({ - output = "cottages:fence_small 3", - recipe = { - {"xfences:fence","xfences:fence" }, - } - }) -end - -minetest.register_craft({ - output = "cottages:fence_corner", - recipe = { - {"cottages:fence_small","cottages:fence_small" }, - } -}) - -minetest.register_craft({ - output = "cottages:fence_small 2", - recipe = { - {"cottages:fence_corner" }, - } -}) - -minetest.register_craft({ - output = "cottages:fence_end", - recipe = { - {"cottages:fence_small","cottages:fence_small", "cottages:fence_small" }, - } -}) - -minetest.register_craft({ - output = "cottages:fence_small 3", - recipe = { - {"cottages:fence_end" }, - } -}) - - - - diff --git a/nodes_furniture.lua b/nodes_furniture.lua deleted file mode 100644 index 424764c..0000000 --- a/nodes_furniture.lua +++ /dev/null @@ -1,646 +0,0 @@ ---------------------------------------------------------------------------------------- --- furniture ---------------------------------------------------------------------------------------- --- contains: --- * a bed seperated into foot and head reagion so that it can be placed manually; it has --- no other functionality than decoration! --- * a sleeping mat - mostly for NPC that cannot afford a bet yet --- * bench - if you don't have 3dforniture:chair, then this is the next best thing --- * table - very simple one --- * shelf - for stroring things; this one is 3d --- * stovepipe - so that the smoke from the furnace can get away --- * washing place - put it over a water source and you can 'wash' yourshelf ---------------------------------------------------------------------------------------- --- TODO: change the textures of the bed (make the clothing white, foot path not entirely covered with cloth) - -local S = cottages.S - --- a bed without functionality - just decoration -minetest.register_node("cottages:bed_foot", { - description = S("Bed (foot region)"), - drawtype = "nodebox", - tiles = {"cottages_beds_bed_top_bottom.png", cottages.texture_furniture, "cottages_beds_bed_side.png", "cottages_beds_bed_side.png", "cottages_beds_bed_side.png", "cottages_beds_bed_side.png"}, - paramtype = "light", - paramtype2 = "facedir", - groups = {snappy=1,choppy=2,oddly_breakable_by_hand=2,flammable=3}, - sounds = cottages.sounds.wood, - node_box = { - type = "fixed", - fixed = { - -- bed - {-0.5, 0.0, -0.5, 0.5, 0.3, 0.5}, - - -- stützen - {-0.5, -0.5, -0.5, -0.4, 0.5, -0.4}, - { 0.4,-0.5, -0.5, 0.5, 0.5, -0.4}, - - -- Querstrebe - {-0.4, 0.3, -0.5, 0.4, 0.5, -0.4} - } - }, - selection_box = { - type = "fixed", - fixed = { - {-0.5, -0.5, -0.5, 0.5, 0.3, 0.5}, - } - }, - is_ground_content = false, - on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) - return cottages.sleep_in_bed( pos, node, clicker, itemstack, pointed_thing ); - end -}) - --- the bed is split up in two parts to avoid destruction of blocks on placement -minetest.register_node("cottages:bed_head", { - description = S("Bed (head region)"), - drawtype = "nodebox", - tiles = {"cottages_beds_bed_top_top.png", cottages.texture_furniture, "cottages_beds_bed_side_top_r.png", "cottages_beds_bed_side_top_l.png", cottages.texture_furniture, "cottages_beds_bed_side.png"}, - paramtype = "light", - paramtype2 = "facedir", - groups = {snappy=1,choppy=2,oddly_breakable_by_hand=2,flammable=3}, - sounds = cottages.sounds.wood, - node_box = { - type = "fixed", - fixed = { - -- bed - {-0.5, 0.0, -0.5, 0.5, 0.3, 0.5}, - - -- stützen - {-0.5,-0.5, 0.4, -0.4, 0.5, 0.5}, - { 0.4,-0.5, 0.4, 0.5, 0.5, 0.5}, - - -- Querstrebe - {-0.4, 0.3, 0.4, 0.4, 0.5, 0.5} - } - }, - selection_box = { - type = "fixed", - fixed = { - {-0.5, -0.5, -0.5, 0.5, 0.3, 0.5}, - } - }, - is_ground_content = false, - on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) - return cottages.sleep_in_bed( pos, node, clicker, itemstack, pointed_thing ); - end -}) - - --- the basic version of a bed - a sleeping mat --- to facilitate upgrade path straw mat -> sleeping mat -> bed, this uses a nodebox -minetest.register_node("cottages:sleeping_mat", { - description = S("sleeping mat"), - drawtype = 'nodebox', - tiles = { 'cottages_sleepingmat.png' }, -- done by VanessaE - wield_image = 'cottages_sleepingmat.png', - inventory_image = 'cottages_sleepingmat.png', - sunlight_propagates = true, - paramtype = 'light', - paramtype2 = "facedir", - walkable = false, - groups = { snappy = 3 }, - sounds = cottages.sounds.leaves, - selection_box = { - type = "wallmounted", - }, - node_box = { - type = "fixed", - fixed = { - {-0.48, -0.5,-0.48, 0.48, -0.5+1/16, 0.48}, - } - }, - selection_box = { - type = "fixed", - fixed = { - {-0.48, -0.5,-0.48, 0.48, -0.5+2/16, 0.48}, - } - }, - is_ground_content = false, - on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) - return cottages.sleep_in_bed( pos, node, clicker, itemstack, pointed_thing ); - end -}) - - --- this one has a pillow for the head; thus, param2 becomes visible to the builder, and mobs may use it as a bed -minetest.register_node("cottages:sleeping_mat_head", { - description = S("sleeping mat with pillow"), - drawtype = 'nodebox', - tiles = { 'cottages_sleepingmat.png' }, -- done by VanessaE - wield_image = 'cottages_sleepingmat.png', - inventory_image = 'cottages_sleepingmat.png', - sunlight_propagates = true, - paramtype = 'light', - paramtype2 = "facedir", - groups = { snappy = 3 }, - sounds = cottages.sounds.leaves, - node_box = { - type = "fixed", - fixed = { - {-0.48, -0.5,-0.48, 0.48, -0.5+1/16, 0.48}, - {-0.34, -0.5+1/16,-0.12, 0.34, -0.5+2/16, 0.34}, - } - }, - selection_box = { - type = "fixed", - fixed = { - {-0.48, -0.5,-0.48, 0.48, -0.5+2/16, 0.48}, - } - }, - is_ground_content = false, - on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) - return cottages.sleep_in_bed( pos, node, clicker, itemstack, pointed_thing ); - end -}) - - --- furniture; possible replacement: 3dforniture:chair -minetest.register_node("cottages:bench", { - drawtype = "nodebox", - description = S("simple wooden bench"), - tiles = {"cottages_minimal_wood.png", "cottages_minimal_wood.png", "cottages_minimal_wood.png", "cottages_minimal_wood.png", "cottages_minimal_wood.png", "cottages_minimal_wood.png"}, - paramtype = "light", - paramtype2 = "facedir", - groups = {snappy=1,choppy=2,oddly_breakable_by_hand=2,flammable=3}, - sounds = cottages.sounds.wood, - node_box = { - type = "fixed", - fixed = { - -- sitting area - {-0.5, -0.15, 0.1, 0.5, -0.05, 0.5}, - - -- stützen - {-0.4, -0.5, 0.2, -0.3, -0.15, 0.4}, - { 0.3, -0.5, 0.2, 0.4, -0.15, 0.4}, - } - }, - selection_box = { - type = "fixed", - fixed = { - {-0.5, -0.5, 0, 0.5, 0, 0.5}, - } - }, - is_ground_content = false, - on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) - return cottages.sit_on_bench( pos, node, clicker, itemstack, pointed_thing ); - end, -}) - - --- a simple table; possible replacement: 3dforniture:table -local cottages_table_def = { - description = S("table"), - drawtype = "nodebox", - -- top, bottom, side1, side2, inner, outer - tiles = {"cottages_minimal_wood.png"}, - paramtype = "light", - paramtype2 = "facedir", - groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2}, - node_box = { - type = "fixed", - fixed = { - { -0.1, -0.5, -0.1, 0.1, 0.3, 0.1}, - { -0.5, 0.48, -0.5, 0.5, 0.4, 0.5}, - }, - }, - selection_box = { - type = "fixed", - fixed = { - { -0.5, -0.5, -0.5, 0.5, 0.4, 0.5}, - }, - }, - is_ground_content = false, -} - - --- search for the workbench in AdventureTest -local workbench = minetest.registered_nodes[ "workbench:3x3"]; -if( workbench ) then - cottages_table_def.tiles = {workbench.tiles[1], cottages_table_def.tiles[1]}; - cottages_table_def.on_rightclick = workbench.on_rightclick; -end --- search for the workbench from RealTEst -workbench = minetest.registered_nodes[ "workbench:work_bench_birch"]; -if( workbench ) then - cottages_table_def.tiles = {workbench.tiles[1], cottages_table_def.tiles[1]}; - cottages_table_def.on_construct = workbench.on_construct; - cottages_table_def.can_dig = workbench.can_dig; - cottages_table_def.on_metadata_inventory_take = workbench.on_metadata_inventory_take; - cottages_table_def.on_metadata_inventory_move = workbench.on_metadata_inventory_move; - cottages_table_def.on_metadata_inventory_put = workbench.on_metadata_inventory_put; -end - -minetest.register_node("cottages:table", cottages_table_def ); - --- looks better than two slabs impersonating a shelf; also more 3d than a bookshelf --- the infotext shows if it's empty or not -minetest.register_node("cottages:shelf", { - description = S("open storage shelf"), - drawtype = "nodebox", - -- top, bottom, side1, side2, inner, outer - tiles = {"cottages_minimal_wood.png"}, - paramtype = "light", - paramtype2 = "facedir", - groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2}, - node_box = { - type = "fixed", - fixed = { - - { -0.5, -0.5, -0.3, -0.4, 0.5, 0.5}, - { 0.4, -0.5, -0.3, 0.5, 0.5, 0.5}, - - { -0.5, -0.2, -0.3, 0.5, -0.1, 0.5}, - { -0.5, 0.3, -0.3, 0.5, 0.4, 0.5}, - }, - }, - selection_box = { - type = "fixed", - fixed = { - { -0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, - }, - }, - - on_construct = function(pos) - - local meta = minetest.get_meta(pos); - - local spos = pos.x .. "," .. pos.y .. "," .. pos.z - meta:set_string("formspec", - "size[8,8]".. - "list[current_name;main;0,0;8,3;]".. - "list[current_player;main;0,4;8,4;]".. - "listring[nodemeta:" .. spos .. ";main]" .. - "listring[current_player;main]") - meta:set_string("infotext", S("open storage shelf")) - local inv = meta:get_inventory(); - inv:set_size("main", 24); - end, - - can_dig = function( pos,player ) - local meta = minetest.get_meta( pos ); - local inv = meta:get_inventory(); - return inv:is_empty("main"); - end, - - on_metadata_inventory_put = function(pos, listname, index, stack, player) - local meta = minetest.get_meta( pos ); - meta:set_string('infotext', S('open storage shelf (in use)')); - end, - on_metadata_inventory_take = function(pos, listname, index, stack, player) - local meta = minetest.get_meta( pos ); - local inv = meta:get_inventory(); - if( inv:is_empty("main")) then - meta:set_string('infotext', S('open storage shelf (empty)')); - end - end, - is_ground_content = false, - - -}) - --- so that the smoke from a furnace can get out of a building -minetest.register_node("cottages:stovepipe", { - description = S("stovepipe"), - drawtype = "nodebox", - tiles = {"cottages_steel_block.png"}, - paramtype = "light", - paramtype2 = "facedir", - groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2}, - node_box = { - type = "fixed", - fixed = { - { 0.20, -0.5, 0.20, 0.45, 0.5, 0.45}, - }, - }, - selection_box = { - type = "fixed", - fixed = { - { 0.20, -0.5, 0.20, 0.45, 0.5, 0.45}, - }, - }, - is_ground_content = false, -}) - - --- this washing place can be put over a water source (it is open at the bottom) -minetest.register_node("cottages:washing", { - description = S("washing place"), - drawtype = "nodebox", - -- top, bottom, side1, side2, inner, outer - tiles = {"cottages_clay.png"}, - paramtype = "light", - paramtype2 = "facedir", - groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2}, - node_box = { - type = "fixed", - fixed = { - { -0.5, -0.5, -0.5, 0.5, -0.2, -0.2}, - - { -0.5, -0.5, -0.2, -0.4, 0.2, 0.5}, - { 0.4, -0.5, -0.2, 0.5, 0.2, 0.5}, - - { -0.4, -0.5, 0.4, 0.4, 0.2, 0.5}, - { -0.4, -0.5, -0.2, 0.4, 0.2, -0.1}, - - }, - }, - selection_box = { - type = "fixed", - fixed = { - { -0.5, -0.5, -0.5, 0.5, 0.2, 0.5}, - }, - }, - on_rightclick = function(pos, node, player) - -- works only with water beneath - local node_under = minetest.get_node( {x=pos.x, y=(pos.y-1), z=pos.z} ); - if( not( node_under ) or node_under.name == "ignore" or (node_under.name ~= 'default:water_source' and node_under.name ~= 'default:water_flowing')) then - minetest.chat_send_player( player:get_player_name(), S("Sorry. This washing place is out of water. Please place it above water!")); - else - minetest.chat_send_player( player:get_player_name(), S("You feel much cleaner after some washing.")); - end - end, - is_ground_content = false, - -}) - - ---------------------------------------------------------------------------------------- --- functions for sitting or sleeping ---------------------------------------------------------------------------------------- - -cottages.allow_sit = function( player ) - -- no check possible - if( not( player.get_player_velocity )) then - return true; - end - local velo = player:get_player_velocity(); - if( not( velo )) then - return false; - end - local max_velo = 0.0001; - if( math.abs(velo.x) < max_velo - and math.abs(velo.y) < max_velo - and math.abs(velo.z) < max_velo ) then - return true; - end - return false; -end - -cottages.sit_on_bench = function( pos, node, clicker, itemstack, pointed_thing ) - if( not( clicker ) or not( default.player_get_animation ) or not( cottages.allow_sit( clicker ))) then - return; - end - - local animation = default.player_get_animation( clicker ); - local pname = clicker:get_player_name(); - - if( animation and animation.animation=="sit") then - default.player_attached[pname] = false - clicker:set_pos({x=pos.x,y=pos.y-0.5,z=pos.z}) - clicker:set_eye_offset({x=0,y=0,z=0}, {x=0,y=0,z=0}) - clicker:set_physics_override(1, 1, 1) - default.player_set_animation(clicker, "stand", 30) - else - -- the bench is not centered; prevent the player from sitting on air - local p2 = {x=pos.x, y=pos.y, z=pos.z}; - if not( node ) or node.param2 == 0 then - p2.z = p2.z+0.3; - elseif node.param2 == 1 then - p2.x = p2.x+0.3; - elseif node.param2 == 2 then - p2.z = p2.z-0.3; - elseif node.param2 == 3 then - p2.x = p2.x-0.3; - end - - clicker:set_eye_offset({x=0,y=-7,z=2}, {x=0,y=0,z=0}) - clicker:set_pos( p2 ) - default.player_set_animation(clicker, "sit", 30) - clicker:set_physics_override(0, 0, 0) - default.player_attached[pname] = true - end -end - -cottages.sleep_in_bed = function( pos, node, clicker, itemstack, pointed_thing ) - if( not( clicker ) or not( node ) or not( node.name ) or not( pos ) or not( cottages.allow_sit( clicker))) then - return; - end - - local animation = default.player_get_animation( clicker ); - local pname = clicker:get_player_name(); - - local p_above = minetest.get_node( {x=pos.x, y=pos.y+1, z=pos.z}); - if( not( p_above) or not( p_above.name ) or p_above.name ~= 'air' ) then - minetest.chat_send_player( pname, "This place is too narrow for sleeping. At least for you!"); - return; - end - - local place_name = 'place'; - -- if only one node is present, the player can only sit; - -- sleeping requires a bed head+foot or two sleeping mats - local allow_sleep = false; - local new_animation = 'sit'; - - -- let players get back up - if( animation and animation.animation=="lay" ) then - default.player_attached[pname] = false - clicker:set_pos({x=pos.x,y=pos.y-0.5,z=pos.z}) - clicker:set_eye_offset({x=0,y=0,z=0}, {x=0,y=0,z=0}) - clicker:set_physics_override(1, 1, 1) - default.player_set_animation(clicker, "stand", 30) - minetest.chat_send_player( pname, 'That was enough sleep for now. You stand up again.'); - return; - end - - local second_node_pos = {x=pos.x, y=pos.y, z=pos.z}; - -- the node that will contain the head of the player - local p = {x=pos.x, y=pos.y, z=pos.z}; - -- the player's head is pointing in this direction - local dir = node.param2; - -- it would be odd to sleep in half a bed - if( node.name=='cottages:bed_head' ) then - if( node.param2==0 ) then - second_node_pos.z = pos.z-1; - elseif( node.param2==1) then - second_node_pos.x = pos.x-1; - elseif( node.param2==2) then - second_node_pos.z = pos.z+1; - elseif( node.param2==3) then - second_node_pos.x = pos.x+1; - end - local node2 = minetest.get_node( second_node_pos ); - if( not( node2 ) or not( node2.param2 ) or not( node.param2 ) - or node2.name ~= 'cottages:bed_foot' - or node2.param2 ~= node.param2 ) then - allow_sleep = false; - else - allow_sleep = true; - end - place_name = 'bed'; - - -- if the player clicked on the foot of the bed, locate the head - elseif( node.name=='cottages:bed_foot' ) then - if( node.param2==2 ) then - second_node_pos.z = pos.z-1; - elseif( node.param2==3) then - second_node_pos.x = pos.x-1; - elseif( node.param2==0) then - second_node_pos.z = pos.z+1; - elseif( node.param2==1) then - second_node_pos.x = pos.x+1; - end - local node2 = minetest.get_node( second_node_pos ); - if( not( node2 ) or not( node2.param2 ) or not( node.param2 ) - or node2.name ~= 'cottages:bed_head' - or node2.param2 ~= node.param2 ) then - allow_sleep = false; - else - allow_sleep = true; - end - if( allow_sleep==true ) then - p = {x=second_node_pos.x, y=second_node_pos.y, z=second_node_pos.z}; - end - place_name = 'bed'; - - elseif( node.name=='cottages:sleeping_mat' or node.name=='cottages:straw_mat' or node.name=='cottages:sleeping_mat_head') then - place_name = 'mat'; - dir = node.param2; - allow_sleep = false; - -- search for a second mat right next to this one - local offset = {{x=0,z=-1}, {x=-1,z=0}, {x=0,z=1}, {x=1,z=0}}; - for i,off in ipairs( offset ) do - node2 = minetest.get_node( {x=pos.x+off.x, y=pos.y, z=pos.z+off.z} ); - if( node2.name == 'cottages:sleeping_mat' or node2.name=='cottages:straw_mat' or node.name=='cottages:sleeping_mat_head' ) then - -- if a second mat is found, sleeping is possible - allow_sleep = true; - dir = i-1; - end - end - end - - -- set the right height for the bed - if( place_name=='bed' ) then - p.y = p.y+0.4; - end - if( allow_sleep==true ) then - -- set the right position (middle of the bed) - if( dir==0 ) then - p.z = p.z-0.5; - elseif( dir==1 ) then - p.x = p.x-0.5; - elseif( dir==2 ) then - p.z = p.z+0.5; - elseif( dir==3 ) then - p.x = p.x+0.5; - end - end - - if( default.player_attached[pname] and animation.animation=="sit") then - -- just changing the animation... - if( allow_sleep==true ) then - default.player_set_animation(clicker, "lay", 30) - clicker:set_eye_offset({x=0,y=-14,z=2}, {x=0,y=0,z=0}) - minetest.chat_send_player( pname, 'You lie down and take a nap. A right-click will wake you up.'); - return; - -- no sleeping on this place - else - default.player_attached[pname] = false - clicker:set_pos({x=pos.x,y=pos.y-0.5,z=pos.z}) - clicker:set_eye_offset({x=0,y=0,z=0}, {x=0,y=0,z=0}) - clicker:set_physics_override(1, 1, 1) - default.player_set_animation(clicker, "stand", 30) - minetest.chat_send_player( pname, 'That was enough sitting around for now. You stand up again.'); - return; - end - end - - - clicker:set_eye_offset({x=0,y=-7,z=2}, {x=0,y=0,z=0}) - clicker:set_pos( p ); - default.player_set_animation(clicker, new_animation, 30) - clicker:set_physics_override(0, 0, 0) - default.player_attached[pname] = true - - if( allow_sleep==true) then - minetest.chat_send_player( pname, 'Aaah! What a comftable '..place_name..'. A second right-click will let you sleep.'); - else - minetest.chat_send_player( pname, 'Comftable, but not good enough for a nap. Right-click again if you want to get back up.'); - end -end - ---------------------------------------------------------------------------------------- --- crafting receipes ---------------------------------------------------------------------------------------- -minetest.register_craft({ - output = "cottages:bed_foot", - recipe = { - {cottages.craftitem_wool, "", "", }, - {cottages.craftitem_wood, "", "", }, - {cottages.craftitem_stick, "", "", } - } -}) - -minetest.register_craft({ - output = "cottages:bed_head", - recipe = { - {"", "", cottages.craftitem_wool, }, - {"", cottages.craftitem_stick, cottages.craftitem_wood, }, - {"", "", cottages.craftitem_stick, } - } -}) - -minetest.register_craft({ - output = "cottages:sleeping_mat 3", - recipe = { - {"cottages:wool_tent", "cottages:straw_mat","cottages:straw_mat" } - } -}) - - -minetest.register_craft({ - output = "cottages:sleeping_mat_head", - recipe = { - {"cottages:sleeping_mat","cottages:straw_mat" } - } -}) - -minetest.register_craft({ - output = "cottages:table", - recipe = { - {"", cottages.craftitem_slab_wood, "", }, - {"", cottages.craftitem_stick, "" } - } -}) - -minetest.register_craft({ - output = "cottages:bench", - recipe = { - {"", cottages.craftitem_wood, "", }, - {cottages.craftitem_stick, "", cottages.craftitem_stick, } - } -}) - - -minetest.register_craft({ - output = "cottages:shelf", - recipe = { - {cottages.craftitem_stick, cottages.craftitem_wood, cottages.craftitem_stick, }, - {cottages.craftitem_stick, cottages.craftitem_wood, cottages.craftitem_stick, }, - {cottages.craftitem_stick, "", cottages.craftitem_stick} - } -}) - -minetest.register_craft({ - output = "cottages:washing 2", - recipe = { - {cottages.craftitem_stick, }, - {cottages.craftitem_clay, }, - } -}) - -minetest.register_craft({ - output = "cottages:stovepipe 2", - recipe = { - {cottages.craftitem_steel, '', cottages.craftitem_steel}, - } -}) diff --git a/nodes_hay.lua b/nodes_hay.lua deleted file mode 100644 index 3d1f8b0..0000000 --- a/nodes_hay.lua +++ /dev/null @@ -1,135 +0,0 @@ --- contains hay_mat, hay and hay bale --- (gives the pitchfork some work) --- -local S = cottages.S - --- If default:dirt_with_grass is digged while wielding a pitchfork, it will --- turn into dirt and get some hay placed above it. --- The hay will disappear (decay) after a couple of minutes. -if( minetest.registered_items["default:dirt_with_grass"] - and minetest.registered_tools["cottages:pitchfork"]) then - minetest.override_item("default:dirt_with_grass", { - after_dig_node = function(pos, oldnode, oldmetadata, digger) - if( not( pos ) or not( digger )) then - return - end - local wielded = digger:get_wielded_item() - if( not( wielded ) - or not( wielded:get_name() ) - or (wielded:get_name()~="cottages:pitchfork")) then - return - end - - local pos_above = {x=pos.x, y=pos.y+1, z=pos.z} - local node_above = minetest.get_node_or_nil( pos_above) - if( not(node_above) or not(node_above.name) or node_above.name ~= "air" ) then - return nil - end - minetest.swap_node( pos, {name="default:dirt"}) - minetest.add_node( pos_above, {name="cottages:hay_mat", param2=math.random(2,25)}) - -- start a node timer so that the hay will decay after some time - local timer = minetest.get_node_timer(pos_above) - if not timer:is_started() then - timer:start(math.random(60, 300)) - end - -- TODO: prevent dirt from beeing multiplied this way (that is: give no dirt!) - return - end, - }) -end - - - --- more comparable to the straw mat than to a hay bale --- (can be created by digging dirt with grass with the pitchfork) -minetest.register_node("cottages:hay_mat", { - drawtype = "nodebox", - paramtype2 = "leveled", - description = S("Some hay"), - tiles = {cottages.straw_texture.."^[multiply:#88BB88"}, - groups = {hay=3, snappy=2, oddly_breakable_by_hand=2, flammable=3}, - sounds = cottages.sounds.leaves, - -- the bale is slightly smaller than a full node - is_ground_content = false, - node_box = { - type = "leveled", --"fixed", - fixed = { - {-0.5,-0.5,-0.5, 0.5, 0.5, 0.5}, - } - }, - -- make sure a placed hay block looks halfway reasonable - after_place_node = function(pos, placer, itemstack, pointed_thing) - minetest.swap_node( pos, {name="cottages:hay_mat", param2=math.random(2,25)}) - end, - on_timer = function(pos, elapsed) - local node = minetest.get_node(pos) - if( node and node.name=="cottages:hay_mat") then - minetest.remove_node(pos) - minetest.check_for_falling(pos) - end - end, -}) - --- hay block, similar to straw block -minetest.register_node("cottages:hay", { - description = S("Hay"), - tiles = {cottages.straw_texture.."^[multiply:#88BB88"}, - groups = {hay=3, snappy=2, oddly_breakable_by_hand=2, flammable=3}, - sounds = cottages.sounds.leaves, - is_ground_content = false, -}) - - --- hay bales for hungry animals -minetest.register_node("cottages:hay_bale", { - drawtype = "nodebox", - description = S("Hay bale"), - tiles = {"cottages_darkage_straw_bale.png^[multiply:#88BB88"}, - paramtype = "light", - groups = {hay=3, snappy=2, oddly_breakable_by_hand=2, flammable=3}, - sounds = cottages.sounds.leaves, - -- the bale is slightly smaller than a full node - node_box = { - type = "fixed", - fixed = { - {-0.45, -0.5,-0.45, 0.45, 0.45, 0.45}, - } - }, - selection_box = { - type = "fixed", - fixed = { - {-0.45, -0.5,-0.45, 0.45, 0.45, 0.45}, - } - }, - is_ground_content = false, -}) - - --- --- craft recipes --- -minetest.register_craft({ - output = "cottages:hay_mat 9", - recipe = { - {"cottages:hay"}, - }, -}) - -minetest.register_craft({ - output = "cottages:hay", - recipe = { - {"cottages:hay_mat", "cottages:hay_mat", "cottages:hay_mat"}, - {"cottages:hay_mat", "cottages:hay_mat", "cottages:hay_mat"}, - {"cottages:hay_mat", "cottages:hay_mat", "cottages:hay_mat"}, - }, -}) - -minetest.register_craft({ - output = "cottages:hay", - recipe = {{"cottages:hay_bale"}}, -}) - -minetest.register_craft({ - output = "cottages:hay_bale", - recipe = {{"cottages:hay"}}, -}) diff --git a/nodes_historic.lua b/nodes_historic.lua deleted file mode 100644 index f88703f..0000000 --- a/nodes_historic.lua +++ /dev/null @@ -1,267 +0,0 @@ ---------------------------------------------------------------------------------------- --- decoration and building material ---------------------------------------------------------------------------------------- --- * includes a wagon wheel that can be used as decoration on walls or to build (stationary) wagons --- * dirt road - those are more natural in small old villages than cobble roads --- * loam - no, old buildings are usually not built out of clay; loam was used --- * straw - useful material for roofs --- * glass pane - an improvement compared to fence posts as windows :-) ---------------------------------------------------------------------------------------- - -local S = cottages.S - --- can be used to buid real stationary wagons or attached to walls as decoration -minetest.register_node("cottages:wagon_wheel", { - description = S("wagon wheel"), - drawtype = "signlike", - tiles = {"cottages_wagonwheel.png"}, -- done by VanessaE! - inventory_image = "cottages_wagonwheel.png", - wield_image = "cottages_wagonwheel.png", - paramtype = "light", - paramtype2 = "wallmounted", - - sunlight_propagates = true, - walkable = false, - selection_box = { - type = "wallmounted", - }, - groups = {choppy=2,dig_immediate=2,attached_node=1}, - legacy_wallmounted = true, - is_ground_content = false, -}) - - --- people didn't use clay for houses; they did build with loam -minetest.register_node("cottages:loam", { - description = S("loam"), - tiles = {"cottages_loam.png"}, - groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2}, - groups = {crumbly=3}, - sounds = cottages.sounds.dirt, - is_ground_content = false, -}) - --- create stairs if possible -if( minetest.get_modpath("stairs") and stairs and stairs.register_stair_and_slab) then - - stairs.register_stair_and_slab("loam", "cottages:loam", - {snappy=2,choppy=2,oddly_breakable_by_hand=2}, - {"cottages_loam.png"}, - S("Loam Stairs"), - S("Loam Slab"), - cottages.sounds.dirt) - - if( minetest.registered_nodes["default:clay"]) then - stairs.register_stair_and_slab("clay", "default:clay", - {crumbly=3}, - {"cottages_clay.png"}, - S("Clay Stairs"), - S("Clay Slab"), - cottages.sounds.dirt) - end -end - - --- straw is a common material for places where animals are kept indoors --- right now, this block mostly serves as a placeholder -minetest.register_node("cottages:straw_ground", { - description = S("straw ground for animals"), - tiles = {cottages.straw_texture,"cottages_loam.png","cottages_loam.png","cottages_loam.png","cottages_loam.png","cottages_loam.png"}, - groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2}, - groups = {crumbly=3}, - sounds = cottages.sounds.leaves, - is_ground_content = false, -}) - - --- note: these houses look good with a single fence pile as window! the glass pane is the version for 'richer' inhabitants -minetest.register_node("cottages:glass_pane", { - description = S("simple glass pane (centered)"), - drawtype = "nodebox", - -- top, bottom, side1, side2, inner, outer - tiles = {"cottages_glass_pane.png"}, - paramtype = "light", - paramtype2 = "facedir", - use_texture_alpha = "clip", - groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2}, - node_box = { - type = "fixed", - fixed = { - { -0.5, -0.5, -0.05, 0.5, 0.5, 0.05}, - }, - }, - selection_box = { - type = "fixed", - fixed = { - { -0.5, -0.5, -0.05, 0.5, 0.5, 0.05}, - }, - }, - is_ground_content = false, -}) - - -minetest.register_node("cottages:glass_pane_side", { - description = S("simple glass pane"), - drawtype = "nodebox", - -- top, bottom, side1, side2, inner, outer - tiles = {"cottages_glass_pane.png"}, - paramtype = "light", - paramtype2 = "facedir", - use_texture_alpha = "clip", - groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2}, - node_box = { - type = "fixed", - fixed = { - { -0.5, -0.5, -0.40, 0.5, 0.5, -0.50}, - }, - }, - selection_box = { - type = "fixed", - fixed = { - { -0.5, -0.5, -0.40, 0.5, 0.5, -0.50}, - }, - }, - is_ground_content = false, -}) - - ---------------------------------------------------------------------------------------- --- a very small wooden slab ---------------------------------------------------------------------------------------- -minetest.register_node("cottages:wood_flat", { - description = S("flat wooden planks"), - drawtype = "nodebox", - -- top, bottom, side1, side2, inner, outer - tiles = {"cottages_minimal_wood.png"}, - paramtype = "light", - paramtype2 = "facedir", - groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2}, - node_box = { - type = "fixed", - fixed = { - { -0.5, -0.5, -0.50, 0.5, -0.5+1/16, 0.50}, - }, - }, - selection_box = { - type = "fixed", - fixed = { - { -0.5, -0.5, -0.50, 0.5, -0.5+1/16, 0.50}, - }, - }, - is_ground_content = false, - on_place = minetest.rotate_node, -}) - ---------------------------------------------------------------------------------------- --- useful for building tents ---------------------------------------------------------------------------------------- -minetest.register_node("cottages:wool_tent", { - description = S("wool for tents"), - drawtype = "nodebox", - -- top, bottom, side1, side2, inner, outer - tiles = {"cottages_wool.png"}, - paramtype = "light", - paramtype2 = "facedir", - groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2}, - node_box = { - type = "fixed", - fixed = { - { -0.5, -0.5, -0.50, 0.5, -0.5+1/16, 0.50}, - }, - }, - selection_box = { - type = "fixed", - fixed = { - { -0.5, -0.5, -0.50, 0.5, -0.5+1/16, 0.50}, - }, - }, - is_ground_content = false, - on_place = minetest.rotate_node, -}) - --- a fallback for cases in which there is no wool -if( not( minetest.registered_nodes["wool:white"])) then - minetest.register_node("cottages:wool", { - description = "Wool", - tiles = {"cottages_wool.png"}, - is_ground_content = false, - groups = {snappy=2,choppy=2,oddly_breakable_by_hand=3,flammable=3,wool=1}, - }) -else - minetest.register_alias("cottages:wool", "wool:white") -end - - ---------------------------------------------------------------------------------------- --- crafting receipes ---------------------------------------------------------------------------------------- -minetest.register_craft({ - output = "cottages:wagon_wheel 3", - recipe = { - {cottages.craftitem_iron, cottages.craftitem_stick, cottages.craftitem_iron }, - {cottages.craftitem_stick, cottages.craftitem_steel, cottages.craftitem_stick }, - {cottages.craftitem_iron, cottages.craftitem_stick, cottages.craftitem_iron } - } -}) - -minetest.register_craft({ - output = "cottages:loam 4", - recipe = { - {cottages.craftitem_sand}, - {cottages.craftitem_clay} - } -}) - -minetest.register_craft({ - output = "cottages:straw_ground 2", - recipe = { - {"cottages:straw_mat" }, - {"cottages:loam"} - } -}) - -minetest.register_craft({ - output = "cottages:glass_pane 4", - recipe = { - {cottages.craftitem_stick, cottages.craftitem_stick, cottages.craftitem_stick }, - {cottages.craftitem_stick, cottages.craftitem_glass, cottages.craftitem_stick }, - {cottages.craftitem_stick, cottages.craftitem_stick, cottages.craftitem_stick } - } -}) - -minetest.register_craft({ - output = "cottages:glass_pane_side", - recipe = { - {"cottages:glass_pane"}, - } -}) - -minetest.register_craft({ - output = "cottages:glass_pane", - recipe = { - {"cottages:glass_pane_side"}, - } -}) - -minetest.register_craft({ - output = "cottages:wood_flat 16", - recipe = { - {cottages.craftitem_stick, "farming:string",cottages.craftitem_stick }, - {cottages.craftitem_stick, "", cottages.craftitem_stick }, - } -}) - -minetest.register_craft({ - output = "cottages:wool_tent 2", - recipe = { - {"farming:string", "farming:string"}, - {"",cottages.craftitem_stick} - } -}) - -minetest.register_craft({ - output = "cottages:wool", - recipe = { - {"cottages:wool_tent", "cottages:wool_tent"} - } -}) diff --git a/nodes_mining.lua b/nodes_mining.lua deleted file mode 100644 index 2098afe..0000000 --- a/nodes_mining.lua +++ /dev/null @@ -1,67 +0,0 @@ - - ---------------------------------------------------------------------------------------- --- a rope that is of use to the mines ---------------------------------------------------------------------------------------- --- the rope can only be digged if there is no further rope above it; --- Note: This rope also counts as a rail node; thus, carts can move through it -minetest.register_node("cottages:rope", { - description = "rope for climbing", - tiles = {"cottages_rope.png"}, - groups = {snappy=3,choppy=3,oddly_breakable_by_hand=3,rail=1,connect_to_raillike=1},--connect_to_raillike=minetest.raillike_group("rail")}, - walkable = false, - climbable = true, - paramtype = "light", - sunlight_propagates = true, - drawtype = "plantlike", - is_ground_content = false, - can_dig = function(pos, player) - local below = minetest.get_node( {x=pos.x, y=pos.y-1, z=pos.z}); - if( below and below.name and below.name == "cottages:rope" ) then - if( player ) then - minetest.chat_send_player( player:get_player_name(), - 'The entire rope would be too heavy. Start digging at its lowest end!'); - end - return false; - end - return true; - end -}) - -minetest.register_craft({ - output = "cottages:rope", - recipe = { - {"farming:cotton","farming:cotton","farming:cotton"} - } -}) - - --- Note: This rope also counts as a rail node; thus, carts can move through it -minetest.register_node("cottages:ladder_with_rope_and_rail", { - description = "Ladder with rail support", - drawtype = "signlike", - tiles = {"default_ladder_wood.png^carts_rail_straight.png^cottages_rope.png"}, - inventory_image = "default_ladder_wood.png", - wield_image = "default_ladder_wood.png", - paramtype = "light", - paramtype2 = "wallmounted", - sunlight_propagates = true, - walkable = false, - climbable = true, - is_ground_content = false, - selection_box = { - type = "wallmounted", - }, - groups = {choppy=2,oddly_breakable_by_hand=3,rail=1,connect_to_raillike=1}, --connect_to_raillike=minetest.raillike_group("rail")}, - legacy_wallmounted = true, - sounds = cottages.sounds.wood, -}) - - - -minetest.register_craft({ - output = "cottages:ladder_with_rope_and_rail 3", - recipe = { - {"default:ladder","cottages:rope", "default:rail"} - } -}) diff --git a/nodes_pitchfork.lua b/nodes_pitchfork.lua deleted file mode 100644 index 8e0cad9..0000000 --- a/nodes_pitchfork.lua +++ /dev/null @@ -1,114 +0,0 @@ - -local S = cottages.S - --- fast tool for digging nodes with the group "hay"; --- can also be placed as a node - --- the straw node from default and similar nodes can be digged with the pitchfork as well -local add_hay_group = {"farming:straw", "dryplants:reed", "darkage:straw_bale"} -for i, v in ipairs(add_hay_group) do - if( minetest.registered_items[v]) then - new_groups = minetest.registered_items[v].groups - new_groups.hay = 3 - minetest.override_item(v, {groups = new_groups}) - end -end - --- creates hay when digging dirt_with_grass (thanks to the override above); --- useful for digging hay and straw --- can be placed as a node -minetest.register_tool("cottages:pitchfork", { - description = S("pitchfork (dig dirt with grass to get hay, place with right-click)"), - groups = {}, - inventory_image = "cottages_pitchfork.png", - wield_image = "cottages_pitchfork.png^[transformFYR180", - wield_scale = {x=1.5,y=1.5,z=0.5}, - stack_max = 1, - liquids_pointable = false, - -- very useful for digging hay, straw and bales of those materials - tool_capabilities = { - full_punch_interval = 1.0, - max_drop_level=1, - groupcaps={ - fleshy={times={[2]=0.80, [3]=0.40}, maxlevel=1, uses=1/0.002 }, - snappy={times={[2]=0.80, [3]=0.40}, maxlevel=1, uses=1/0.002 }, - hay ={times={[2]=0.10, [3]=0.10}, maxlevel=1, uses=1/0.002 }, - }, - damage_groups = {fleshy=5}, -- slightly stronger than a stone sword - }, - sound = {breaks = "default_tool_breaks"}, - -- place the pitchfork somewhere - on_place = function(itemstack, placer, pointed_thing) - if( placer == nil or pointed_thing == nil or pointed_thing.type ~= "node") then - return nil - end - local pos = minetest.get_pointed_thing_position( pointed_thing, 1 ) - local node = minetest.get_node_or_nil( pos ) - if( node == nil or not(node.name) or node.name ~= "air") then - return nil - end - if minetest.is_protected(pos, placer:get_player_name()) then - return nil - end - minetest.rotate_and_place(ItemStack("cottages:pitchfork_placed"), placer, pointed_thing) - -- did the placing succeed? - local nnode = minetest.get_node(pos) - if( not(nnode) or not(nnode.name) or nnode.name ~= "cottages:pitchfork_placed") then - return nil - end - local meta = minetest.get_meta(pos) - meta:set_int( "wear", itemstack:get_wear()) - meta:set_string("infotext", S("pitchfork (for hay and straw)")) - -- the tool has been placed; consume it - return ItemStack("") - end, -}) - - --- a ptichfork placed somewhere -minetest.register_node("cottages:pitchfork_placed", { - description = S("pitchfork (for hay and straw)"), - tiles = {"default_wood.png^[transformR90"}, --default_tree.png"}, - drawtype = "nodebox", - paramtype = "light", - paramtype2 = "facedir", - is_ground_content = false, - groups = {snappy = 2, dig_immediate = 3, falling_node = 1, attached_node = 1, not_in_creative_inventory=1}, - sounds = cottages.sounds.wood, - node_box = { - type = "fixed", - fixed = { - -- handle (goes a bit into the ground) - { -(1/32), -(11/16), -(1/32), (1/32), 16/16, (1/32)}, - -- middle connection - { -(7/32), -(4/16), -(1/32), (7/32), -(2/16), (1/32)}, - -- thongs - { -(7/32), -(11/16), -(1/32), -(5/32), -(4/16), (1/32)}, - { (5/32), -(11/16), -(1/32), (7/32), -(4/16), (1/32)}, - }, - }, - selection_box = { - type = "fixed", - fixed = { -0.3, -0.5, -0.1, 0.3, 1.0, 0.1 } - }, - drop = "cottages:pitchfork", - -- perserve wear - preserve_metadata = function(pos, oldnode, oldmeta, drops) - if(oldmeta["wear"]) then - -- the first drop is the pitchfork - drops[1]:set_wear(oldmeta["wear"]) - end - end, -}) - --- --- craft recipes --- -minetest.register_craft({ - output = 'cottages:pitchfork', - recipe = { - { 'default:stick','default:stick','default:stick' }, - { '','default:stick', '' }, - { '','default:stick','' }, - } -}) diff --git a/nodes_roof.lua b/nodes_roof.lua deleted file mode 100644 index 240f94f..0000000 --- a/nodes_roof.lua +++ /dev/null @@ -1,230 +0,0 @@ --- Boilerplate to support localized strings if intllib mod is installed. -local S = cottages.S - ---------------------------------------------------------------------------------------- --- roof parts ---------------------------------------------------------------------------------------- --- a better roof than the normal stairs; can be replaced by stairs:stair_wood - - --- create the three basic roof parts plus receipes for them; -cottages.register_roof = function( name, tiles, basic_material, homedecor_alternative ) - - minetest.register_node("cottages:roof_"..name, { - description = S("Roof "..name), - drawtype = "nodebox", - --tiles = {cottages.textures_roof_wood,cottages.texture_roof_sides,cottages.texture_roof_sides,cottages.texture_roof_sides,cottages.texture_roof_sides,cottages.textures_roof_wood}, - tiles = tiles, - paramtype = "light", - paramtype2 = "facedir", - groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2}, - node_box = { - type = "fixed", - fixed = { - {-0.5, -0.5, -0.5, 0.5, 0, 0}, - {-0.5, 0, 0, 0.5, 0.5, 0.5}, - }, - }, - selection_box = { - type = "fixed", - fixed = { - {-0.5, -0.5, -0.5, 0.5, 0, 0}, - {-0.5, 0, 0, 0.5, 0.5, 0.5}, - }, - }, - is_ground_content = false, - }) - - -- a better roof than the normal stairs; this one is for usage directly on top of walls (it has the form of a stair) - if( name~="straw" or not(minetest.registered_nodes["stairs:stair_straw"]) or not(cottages.use_farming_straw_stairs)) then - minetest.register_node("cottages:roof_connector_"..name, { - description = S("Roof connector "..name), - drawtype = "nodebox", - -- top, bottom, side1, side2, inner, outer - tiles = tiles, - paramtype = "light", - paramtype2 = "facedir", - groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2}, - node_box = { - type = "fixed", - fixed = { - {-0.5, -0.5, -0.5, 0.5, 0, 0.5}, - {-0.5, 0, 0, 0.5, 0.5, 0.5}, - }, - }, - selection_box = { - type = "fixed", - fixed = { - {-0.5, -0.5, -0.5, 0.5, 0, 0.5}, - {-0.5, 0, 0, 0.5, 0.5, 0.5}, - }, - }, - is_ground_content = false, - }) - else - minetest.register_alias("cottages:roof_connector_straw", "stairs:stair_straw") - end - - -- this one is the slab version of the above roof - if( name~="straw" or not(minetest.registered_nodes["stairs:slab_straw"]) or not(cottages.use_farming_straw_stairs)) then - minetest.register_node("cottages:roof_flat_"..name, { - description = S("Roof (flat) "..name), - drawtype = "nodebox", - -- top, bottom, side1, side2, inner, outer - -- this one is from all sides - except from the underside - of the given material - tiles = { tiles[1], tiles[2], tiles[1], tiles[1], tiles[1], tiles[1] }; - paramtype = "light", - paramtype2 = "facedir", - groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2}, - node_box = { - type = "fixed", - fixed = { - {-0.5, -0.5, -0.5, 0.5, 0, 0.5}, - }, - }, - selection_box = { - type = "fixed", - fixed = { - {-0.5, -0.5, -0.5, 0.5, 0, 0.5}, - }, - }, - is_ground_content = false, - }) - else - minetest.register_alias("cottages:roof_flat_straw", "stairs:slab_straw") - end - - - if( not( homedecor_alternative ) - or ( minetest.get_modpath("homedecor") ~= nil )) then - - minetest.register_craft({ - output = "cottages:roof_"..name.." 6", - recipe = { - {'', '', basic_material }, - {'', basic_material, '' }, - {basic_material, '', '' } - } - }) - end - - -- make those roof parts that use homedecor craftable without that mod - if( homedecor_alternative ) then - basic_material = 'cottages:roof_wood'; - - minetest.register_craft({ - output = "cottages:roof_"..name.." 3", - recipe = { - {homedecor_alternative, '', basic_material }, - {'', basic_material, '' }, - {basic_material, '', '' } - } - }) - end - - - minetest.register_craft({ - output = "cottages:roof_connector_"..name, - recipe = { - {'cottages:roof_'..name }, - {cottages.craftitem_wood }, - } - }) - - minetest.register_craft({ - output = "cottages:roof_flat_"..name..' 2', - recipe = { - {'cottages:roof_'..name, 'cottages:roof_'..name }, - } - }) - - -- convert flat roofs back to normal roofs - minetest.register_craft({ - output = "cottages:roof_"..name, - recipe = { - {"cottages:roof_flat_"..name, "cottages:roof_flat_"..name } - } - }) - -end -- of cottages.register_roof( name, tiles, basic_material ) - - - - ---------------------------------------------------------------------------------------- --- add the diffrent roof types ---------------------------------------------------------------------------------------- -cottages.register_roof( 'straw', - {cottages.straw_texture, cottages.straw_texture, - cottages.straw_texture, cottages.straw_texture, - cottages.straw_texture, cottages.straw_texture}, - 'cottages:straw_mat', nil ); -cottages.register_roof( 'reet', - {"cottages_reet.png","cottages_reet.png", - "cottages_reet.png","cottages_reet.png", - "cottages_reet.png","cottages_reet.png"}, - cottages.craftitem_papyrus, nil ); -cottages.register_roof( 'wood', - {cottages.textures_roof_wood, cottages.texture_roof_sides, - cottages.texture_roof_sides, cottages.texture_roof_sides, - cottages.texture_roof_sides, cottages.textures_roof_wood}, - cottages.craftitem_wood, nil); -cottages.register_roof( 'black', - {"cottages_homedecor_shingles_asphalt.png", cottages.texture_roof_sides, - cottages.texture_roof_sides, cottages.texture_roof_sides, - cottages.texture_roof_sides, "cottages_homedecor_shingles_asphalt.png"}, - 'homedecor:shingles_asphalt', cottages.craftitem_coal_lump); -cottages.register_roof( 'red', - {"cottages_homedecor_shingles_terracotta.png", cottages.texture_roof_sides, - cottages.texture_roof_sides, cottages.texture_roof_sides, - cottages.texture_roof_sides, "cottages_homedecor_shingles_terracotta.png"}, - 'homedecor:shingles_terracotta', cottages.craftitem_clay_brick); -cottages.register_roof( 'brown', - {"cottages_homedecor_shingles_wood.png", cottages.texture_roof_sides, - cottages.texture_roof_sides, cottages.texture_roof_sides, - cottages.texture_roof_sides, "cottages_homedecor_shingles_wood.png"}, - 'homedecor:shingles_wood', cottages.craftitem_dirt); -cottages.register_roof( 'slate', - {"cottages_slate.png", cottages.texture_roof_sides, - "cottages_slate.png", "cottages_slate.png", - cottages.texture_roof_sides,"cottages_slate.png"}, - cottages.craftitem_stone, nil); - - ---------------------------------------------------------------------------------------- --- slate roofs are sometimes on vertical fronts of houses ---------------------------------------------------------------------------------------- -minetest.register_node("cottages:slate_vertical", { - description = S("Vertical Slate"), - tiles = {"cottages_slate.png",cottages.texture_roof_sides,"cottages_slate.png","cottages_slate.png",cottages.texture_roof_sides,"cottages_slate.png"}, - paramtype2 = "facedir", - groups = {cracky=2, stone=1}, - sounds = cottages.sounds.stone, - is_ground_content = false, -}) - - -minetest.register_craft({ - output = "cottages:slate_vertical", - recipe = { {cottages.craftitem_stone, cottages.craftitem_wood, '' } - } -}); - ---------------------------------------------------------------------------------------- --- Reed might also be needed as a full block ---------------------------------------------------------------------------------------- -minetest.register_node("cottages:reet", { - description = S("Reet for thatching"), - tiles = {"cottages_reet.png"}, - groups = {hay = 3, snappy=3,choppy=3,oddly_breakable_by_hand=3,flammable=3}, - sounds = cottages.sounds.leaves, - is_ground_content = false, -}) - - -minetest.register_craft({ - output = "cottages:reet", - recipe = { {cottages.craftitem_papyrus,cottages.craftitem_papyrus}, - {cottages.craftitem_papyrus,cottages.craftitem_papyrus}, - }, -}) diff --git a/nodes_straw.lua b/nodes_straw.lua deleted file mode 100644 index 2ac2747..0000000 --- a/nodes_straw.lua +++ /dev/null @@ -1,585 +0,0 @@ ---------------------------------------------------------------------------------------- --- straw - a very basic material ---------------------------------------------------------------------------------------- --- * straw mat - for animals and very poor NPC; also basis for other straw things --- * straw bale - well, just a good source for building and decoration - -local S = cottages.S - - --- an even simpler from of bed - usually for animals --- it is a nodebox and not wallmounted because that makes it easier to replace beds with straw mats -minetest.register_node("cottages:straw_mat", { - description = S("layer of straw"), - drawtype = 'nodebox', - tiles = { cottages.straw_texture }, -- done by VanessaE - wield_image = cottages.straw_texture, - inventory_image = cottages.straw_texture, - sunlight_propagates = true, - paramtype = 'light', - paramtype2 = "facedir", - walkable = false, - groups = { hay = 3, snappy = 2, oddly_breakable_by_hand = 2, flammable=3 }, - sounds = cottages.sounds.leaves, - node_box = { - type = "fixed", - fixed = { - {-0.48, -0.5,-0.48, 0.48, -0.45, 0.48}, - } - }, - selection_box = { - type = "fixed", - fixed = { - {-0.48, -0.5,-0.48, 0.48, -0.25, 0.48}, - } - }, - is_ground_content = false, - on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) - return cottages.sleep_in_bed( pos, node, clicker, itemstack, pointed_thing ); - end -}) - --- straw bales are a must for farming environments; if you for some reason do not have the darkage mod installed, this here gets you a straw bale -minetest.register_node("cottages:straw_bale", { - drawtype = "nodebox", - description = S("straw bale"), - tiles = {"cottages_darkage_straw_bale.png"}, - paramtype = "light", - groups = { hay = 3, snappy = 2, oddly_breakable_by_hand = 2, flammable=3 }, - sounds = cottages.sounds.leaves, - -- the bale is slightly smaller than a full node - node_box = { - type = "fixed", - fixed = { - {-0.45, -0.5,-0.45, 0.45, 0.45, 0.45}, - } - }, - selection_box = { - type = "fixed", - fixed = { - {-0.45, -0.5,-0.45, 0.45, 0.45, 0.45}, - } - }, - is_ground_content = false, -}) - --- just straw -if( not(minetest.registered_nodes["farming:straw"])) then - minetest.register_node("cottages:straw", { - drawtype = "normal", - description = S("straw"), - tiles = {cottages.straw_texture}, - groups = { hay = 3, snappy = 2, oddly_breakable_by_hand = 2, flammable=3 }, - sounds = cottages.sounds.leaves, - -- the bale is slightly smaller than a full node - is_ground_content = false, - }) -else - minetest.register_alias("cottages:straw", "farming:straw") -end - - -local cottages_formspec_treshing_floor = - "size[8,8]".. - "image[1.5,0;1,1;"..cottages.texture_stick.."]".. - "image[0,1;1,1;farming_wheat.png]".. - "button_exit[6.8,0.0;1.5,0.5;public;"..S("Public?").."]".. - "list[current_name;harvest;1,1;2,1;]".. - "list[current_name;straw;5,0;2,2;]".. - "list[current_name;seeds;5,2;2,2;]".. - "label[1,0.5;"..S("Harvested wheat:").."]".. - "label[4,0.0;"..S("Straw:").."]".. - "label[4,2.0;"..S("Seeds:").."]".. - "label[0,-0.5;"..S("Threshing floor").."]".. - "label[0,2.5;"..S("Punch threshing floor with a stick").."]".. - "label[0,3.0;"..S("to get straw and seeds from wheat.").."]".. - "list[current_player;main;0,4;8,4;]"; - -minetest.register_node("cottages:threshing_floor", { - drawtype = "nodebox", - description = S("threshing floor"), --- TODO: stone also looks pretty well for this - tiles = {"cottages_junglewood.png^farming_wheat.png","cottages_junglewood.png","cottages_junglewood.png^"..cottages.texture_stick}, - paramtype = "light", - paramtype2 = "facedir", - -- can be digged with axe and pick - groups = {cracky=2, choppy=2}, - is_ground_content = false, - node_box = { - type = "fixed", - fixed = { - {-0.50, -0.5,-0.50, 0.50, -0.40, 0.50}, - - {-0.50, -0.4,-0.50,-0.45, -0.20, 0.50}, - { 0.45, -0.4,-0.50, 0.50, -0.20, 0.50}, - - {-0.45, -0.4,-0.50, 0.45, -0.20,-0.45}, - {-0.45, -0.4, 0.45, 0.45, -0.20, 0.50}, - } - }, - selection_box = { - type = "fixed", - fixed = { - {-0.50, -0.5,-0.50, 0.50, -0.20, 0.50}, - } - }, - on_construct = function(pos) - local meta = minetest.get_meta(pos); - meta:set_string("infotext", S("Public threshing floor")); - local inv = meta:get_inventory(); - inv:set_size("harvest", 2); - inv:set_size("straw", 4); - inv:set_size("seeds", 4); - meta:set_string("formspec", cottages_formspec_treshing_floor ); - meta:set_string("public", "public") - end, - - after_place_node = function(pos, placer) - local meta = minetest.get_meta(pos); - meta:set_string("owner", placer:get_player_name() or ""); - meta:set_string("infotext", S("Private threshing floor (owned by %s)"):format(meta:get_string("owner") or "")); - meta:set_string("formspec", - cottages_formspec_treshing_floor.. - "label[2.5,-0.5;"..S("Owner: %s"):format(meta:get_string("owner") or "").."]" ); - meta:set_string("public", "private") - end, - - on_receive_fields = function(pos, formname, fields, sender) - cottages.switch_public(pos, formname, fields, sender, 'threshing floor') - end, - - can_dig = function(pos,player) - - local meta = minetest.get_meta(pos); - local inv = meta:get_inventory(); - local owner = meta:get_string('owner'); - - if( not( inv:is_empty("harvest")) - or not( inv:is_empty("straw")) - or not( inv:is_empty("seeds")) - or not( player ) - or ( owner and owner ~= '' and player:get_player_name() ~= owner )) then - - return false; - end - return true; - end, - - allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player) - local meta = minetest.get_meta(pos) - if( not( cottages.player_can_use( meta, player ))) then - return 0 - end - return count; - end, - - allow_metadata_inventory_put = function(pos, listname, index, stack, player) - local meta = minetest.get_meta(pos) - -- only accept input the threshing floor can use/process - if( listname=='straw' - or listname=='seeds' - or (listname=='harvest' and stack and stack:get_name() ~= 'farming:wheat' )) then - return 0; - end - - if( not( cottages.player_can_use( meta, player ))) then - return 0 - end - return stack:get_count() - end, - - allow_metadata_inventory_take = function(pos, listname, index, stack, player) - local meta = minetest.get_meta(pos) - if( not( cottages.player_can_use( meta, player ))) then - return 0 - end - return stack:get_count() - end, - - - on_punch = function(pos, node, puncher) - if( not( pos ) or not( node ) or not( puncher )) then - return; - end - -- only punching with a normal stick is supposed to work - local wielded = puncher:get_wielded_item(); - if( not( wielded ) - or not( wielded:get_name() ) - or not( minetest.registered_items[ wielded:get_name() ]) - or not( minetest.registered_items[ wielded:get_name() ].groups ) - or not( minetest.registered_items[ wielded:get_name() ].groups.stick )) then - return; - end - local name = puncher:get_player_name(); - - local meta = minetest.get_meta(pos); - local inv = meta:get_inventory(); - - local input = inv:get_list('harvest'); - -- we have two input slots - local stack1 = inv:get_stack( 'harvest', 1); - local stack2 = inv:get_stack( 'harvest', 2); - - if( ( stack1:is_empty() and stack2:is_empty()) - or( not( stack1:is_empty()) and stack1:get_name() ~= 'farming:wheat') - or( not( stack2:is_empty()) and stack2:get_name() ~= 'farming:wheat')) then - --- minetest.chat_send_player( name, 'One of the input slots contains something else than wheat, or there is no wheat at all.'); - -- update the formspec - meta:set_string("formspec", - cottages_formspec_treshing_floor.. - "label[2.5,-0.5;"..S("Owner: %s"):format(meta:get_string("owner") or "").."]" ); - return; - end - - -- on average, process 25 wheat at each punch (10..40 are possible) - local anz_wheat = 10 + math.random( 0, 30 ); - -- we already made sure there is only wheat inside - local found_wheat = stack1:get_count() + stack2:get_count(); - - -- do not process more wheat than present in the input slots - if( found_wheat < anz_wheat ) then - anz_wheat = found_wheat; - end - - local overlay1 = "^farming_wheat.png"; - local overlay2 = "^"..cottages.straw_texture; - local overlay3 = "^"..cottages.texture_wheat_seed; - - -- this can be enlarged by a multiplicator if desired - local anz_straw = anz_wheat; - local anz_seeds = anz_wheat; - - if( inv:room_for_item('straw','cottages:straw_mat '..tostring( anz_straw )) - and inv:room_for_item('seeds',cottages.craftitem_seed_wheat..' '..tostring( anz_seeds ))) then - - -- the player gets two kind of output - inv:add_item("straw",'cottages:straw_mat '..tostring( anz_straw )); - inv:add_item("seeds",cottages.craftitem_seed_wheat..' '..tostring( anz_seeds )); - -- consume the wheat - inv:remove_item("harvest", 'farming:wheat '..tostring( anz_wheat )); - - local anz_left = found_wheat - anz_wheat; - if( anz_left > 0 ) then --- minetest.chat_send_player( name, S('You have threshed %s wheat (%s are left).'):format(anz_wheat,anz_left)); - else --- minetest.chat_send_player( name, S('You have threshed the last %s wheat.'):format(anz_wheat)); - overlay1 = ""; - end - end - - local hud0 = puncher:hud_add({ - hud_elem_type = "image", - scale = {x = 38, y = 38}, - text = "cottages_junglewood.png^[colorize:#888888:128", - position = {x = 0.5, y = 0.5}, - alignment = {x = 0, y = 0} - }); - - local hud1 = puncher:hud_add({ - hud_elem_type = "image", - scale = {x = 15, y = 15}, - text = "cottages_junglewood.png"..overlay1, - position = {x = 0.4, y = 0.5}, - alignment = {x = 0, y = 0} - }); - local hud2 = puncher:hud_add({ - hud_elem_type = "image", - scale = {x = 15, y = 15}, - text = "cottages_junglewood.png"..overlay2, - position = {x = 0.6, y = 0.35}, - alignment = {x = 0, y = 0} - }); - local hud3 = puncher:hud_add({ - hud_elem_type = "image", - scale = {x = 15, y = 15}, - text = "cottages_junglewood.png"..overlay3, - position = {x = 0.6, y = 0.65}, - alignment = {x = 0, y = 0} - }); - - local hud4 = puncher:hud_add({ - hud_elem_type = "text", - text = tostring( found_wheat-anz_wheat ), - number = 0x00CC00, - alignment = {x = 0, y = 0}, - scale = {x = 100, y = 100}, -- bounding rectangle of the text - position = {x = 0.4, y = 0.5}, - }); - if( not( anz_straw )) then - anz_straw = "0"; - end - if( not( anz_seed )) then - anz_seed = "0"; - end - local hud5 = puncher:hud_add({ - hud_elem_type = "text", - text = '+ '..tostring( anz_straw )..' straw', - number = 0x00CC00, - alignment = {x = 0, y = 0}, - scale = {x = 100, y = 100}, -- bounding rectangle of the text - position = {x = 0.6, y = 0.35}, - }); - local hud6 = puncher:hud_add({ - hud_elem_type = "text", - text = '+ '..tostring( anz_seed )..' seeds', - number = 0x00CC00, - alignment = {x = 0, y = 0}, - scale = {x = 100, y = 100}, -- bounding rectangle of the text - position = {x = 0.6, y = 0.65}, - }); - - - - minetest.after(2, function() - if( puncher ) then - if(hud1) then puncher:hud_remove(hud1); end - if(hud2) then puncher:hud_remove(hud2); end - if(hud3) then puncher:hud_remove(hud3); end - if(hud4) then puncher:hud_remove(hud4); end - if(hud5) then puncher:hud_remove(hud5); end - if(hud6) then puncher:hud_remove(hud6); end - if(hud0) then puncher:hud_remove(hud0); end - end - end) - end, -}) - - -local cottages_handmill_formspec = "size[8,8]".. - "image[0,1;1,1;"..cottages.texture_wheat_seed.."]".. - "button_exit[6.0,0.0;1.5,0.5;public;"..S("Public?").."]".. - "list[current_name;seeds;1,1;1,1;]".. - "list[current_name;flour;5,1;2,2;]".. - "label[0,0.5;"..S("Wheat seeds:").."]".. - "label[4,0.5;"..S("Flour:").."]".. - "label[0,-0.3;"..S("Mill").."]".. - "label[0,2.5;"..S("Punch this hand-driven mill").."]".. - "label[0,3.0;"..S("to convert wheat seeds into flour.").."]".. - "list[current_player;main;0,4;8,4;]"; - -minetest.register_node("cottages:handmill", { - description = S("mill, powered by punching"), - drawtype = "mesh", - mesh = "cottages_handmill.obj", - tiles = {"cottages_stone.png"}, - paramtype = "light", - paramtype2 = "facedir", - groups = {cracky=2}, - is_ground_content = false, - selection_box = { - type = "fixed", - fixed = { - {-0.50, -0.5,-0.50, 0.50, 0.25, 0.50}, - } - }, - collision_box = { - type = "fixed", - fixed = { - {-0.50, -0.5,-0.50, 0.50, 0.25, 0.50}, - } - }, - on_construct = function(pos) - local meta = minetest.get_meta(pos); - meta:set_string("infotext", S("Public mill, powered by punching")); - local inv = meta:get_inventory(); - inv:set_size("seeds", 1); - inv:set_size("flour", 4); - meta:set_string("formspec", cottages_handmill_formspec ); - meta:set_string("public", "public") - end, - - after_place_node = function(pos, placer) - local meta = minetest.get_meta(pos); - meta:set_string("owner", placer:get_player_name() or ""); - meta:set_string("infotext", S("Private mill, powered by punching (owned by %s)"):format(meta:get_string("owner") or "")); - meta:set_string("formspec", - cottages_handmill_formspec.. - "label[2.5,-0.5;"..S("Owner: %s"):format(meta:get_string('owner') or "").."]" ); - meta:set_string("public", "private") - end, - - on_receive_fields = function(pos, formname, fields, sender) - cottages.switch_public(pos, formname, fields, sender, 'mill, powered by punching') - end, - - can_dig = function(pos,player) - - local meta = minetest.get_meta(pos); - local inv = meta:get_inventory(); - local owner = meta:get_string('owner'); - - if( not( inv:is_empty("flour")) - or not( inv:is_empty("seeds")) - or not( player ) - or ( owner and owner ~= '' and player:get_player_name() ~= owner )) then - - return false; - end - return true; - end, - - allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player) - local meta = minetest.get_meta(pos) - if( not( cottages.player_can_use( meta, player ))) then - return 0 - end - return count; - end, - - allow_metadata_inventory_put = function(pos, listname, index, stack, player) - local meta = minetest.get_meta(pos) - -- only accept input the threshing floor can use/process - if( listname=='flour' - or (listname=='seeds' and stack and not( cottages.handmill_product[ stack:get_name()] ))) then - return 0; - end - - if( not( cottages.player_can_use( meta, player ))) then - return 0 - end - return stack:get_count() - end, - - allow_metadata_inventory_take = function(pos, listname, index, stack, player) - local meta = minetest.get_meta(pos) - if( not( cottages.player_can_use( meta, player ))) then - return 0 - end - return stack:get_count() - end, - - -- this code is very similar to the threshing floor; except that it has only one input- and output-slot - -- and does not require the usage of a stick - on_punch = function(pos, node, puncher) - if( not( pos ) or not( node ) or not( puncher )) then - return; - end - local name = puncher:get_player_name(); - - local meta = minetest.get_meta(pos); - local inv = meta:get_inventory(); - - local input = inv:get_list('seeds'); - local stack1 = inv:get_stack( 'seeds', 1); - - if( ( stack1:is_empty()) - or( not( stack1:is_empty()) - and not( cottages.handmill_product[ stack1:get_name() ] ))) then - - if not( stack1:is_empty() ) then - minetest.chat_send_player(name,"Nothing happens...") - end - -- update the formspec - meta:set_string("formspec", - cottages_handmill_formspec.. - "label[2.5,-0.5;"..S("Owner: %s"):format(meta:get_string('owner') or "").."]" ); - return; - end - - -- turning the mill is a slow process; 1-21 flour are generated per turn - local anz = 1 + math.random( cottages.handmill_min_per_turn, cottages.handmill_max_per_turn ); - -- we already made sure there is only wheat inside - local found = stack1:get_count(); - - -- do not process more wheat than present in the input slots - if( found < anz ) then - anz = found; - end - - local product_stack = ItemStack( cottages.handmill_product[ stack1:get_name() ]); - local anz_result = anz; - -- items that produce more - if( product_stack:get_count()> 1 ) then - anz_result = anz * product_stack:get_count(); - end - - if( inv:room_for_item('flour', product_stack:get_name()..' '..tostring( anz_result ))) then - - inv:add_item( 'flour', product_stack:get_name()..' '..tostring( anz_result )); - inv:remove_item( 'seeds', stack1:get_name()..' '..tostring( anz )); - - local anz_left = found - anz; - if( anz_left > 0 ) then - minetest.chat_send_player( name, S('You have ground a %s (%s are left).'):format(stack1:get_definition().description,(anz_left))); - else - minetest.chat_send_player( name, S('You have ground the last %s.'):format(stack1:get_definition().description)); - end - - -- if the version of MT is recent enough, rotate the mill a bit - if( minetest.swap_node ) then - node.param2 = node.param2 + 1; - if( node.param2 > 3 ) then - node.param2 = 0; - end - minetest.swap_node( pos, node ); - end - end - end, -}) - - - - ---------------------------------------------------------------------------------------- --- crafting receipes ---------------------------------------------------------------------------------------- --- this returns corn as well --- the replacements work only if the replaced slot gets empty... -minetest.register_craft({ - output = "cottages:straw_mat 6", - recipe = { - {cottages.craftitem_stone,'',''}, - {"farming:wheat", "farming:wheat", "farming:wheat", }, - }, - replacements = {{ cottages.craftitem_stone, cottages.craftitem_seed_wheat.." 3" }}, -}) - --- this is a better way to get straw mats -minetest.register_craft({ - output = "cottages:threshing_floor", - recipe = { - {cottages.craftitem_junglewood, cottages.craftitem_chest_locked, cottages.craftitem_junglewood, }, - {cottages.craftitem_junglewood, cottages.craftitem_stone, cottages.craftitem_junglewood, }, - }, -}) - --- and a way to turn wheat seeds into flour -minetest.register_craft({ - output = "cottages:handmill", - recipe = { - {cottages.craftitem_stick, cottages.craftitem_stone, "", }, - {"", cottages.craftitem_steel, "", }, - {"", cottages.craftitem_stone, "", }, - }, -}) - -minetest.register_craft({ - output = "cottages:straw_bale", - recipe = { - {"cottages:straw_mat"}, - {"cottages:straw_mat"}, - {"cottages:straw_mat"}, - }, -}) - -minetest.register_craft({ - output = "cottages:straw", - recipe = { - {"cottages:straw_bale"}, - }, -}) - -minetest.register_craft({ - output = "cottages:straw_bale", - recipe = { - {"cottages:straw"}, - }, -}) - -minetest.register_craft({ - output = "cottages:straw_mat 3", - recipe = { - {"cottages:straw_bale"}, - }, -}) diff --git a/nodes_water.lua b/nodes_water.lua deleted file mode 100644 index 1984779..0000000 --- a/nodes_water.lua +++ /dev/null @@ -1,326 +0,0 @@ - --- TODO: play sound while working --- TODO: play sound when emptying a bucket --- TODO: store correct bucket texture when loading the world anew --- TODO: show particles when running? distinguish between running/idle state? (with punch?) - --- well for getting water --- * has some storage space for buckets (filled with water, river water or empty) --- * only the owner can use the bucket store and the well --- * the bucket will be added as an entity and slowly rotate; --- once filled, the texture of the bucket is changed --- * full (water or river water) buckets can be emptied --- * by default public; but can also be made private - - --- how many seconds does it take to fill a bucket? -cottages.water_fill_time = 10 - -local S = cottages.S - --- code taken from the itemframes mod in homedecor --- (the relevant functions are sadly private there and thus cannot be reused) -local tmp = {} -minetest.register_entity("cottages:bucket_entity",{ - hp_max = 1, - visual="wielditem", - visual_size={x = 0.33, y = 0.33}, - collisionbox = {0, 0, 0, 0, 0, 0}, - physical = false, - textures = {"air"}, - on_activate = function(self, staticdata) - if tmp.nodename ~= nil and tmp.texture ~= nil then - self.nodename = tmp.nodename - tmp.nodename = nil - self.texture = tmp.texture - tmp.texture = nil - else - if staticdata ~= nil and staticdata ~= "" then - local data = staticdata:split(';') - if data and data[1] and data[2] then - self.nodename = data[1] - self.texture = data[2] - end - end - end - if self.texture ~= nil then - self.object:set_properties({textures = {self.texture}}) - end - self.object:set_properties({automatic_rotate = 1}) - if self.texture ~= nil and self.nodename ~= nil then - local entity_pos = vector.round(self.object:get_pos()) - local objs = minetest.get_objects_inside_radius(entity_pos, 0.5) - for _, obj in ipairs(objs) do - if obj ~= self.object and - obj:get_luaentity() and - obj:get_luaentity().name == "cottages:bucket_entity" and - obj:get_luaentity().nodename == self.nodename and - obj:get_properties() and - obj:get_properties().textures and - obj:get_properties().textures[1] == self.texture then - minetest.log("action","[cottages] Removing extra " .. - self.texture .. " found in " .. self.nodename .. " at " .. - minetest.pos_to_string(entity_pos)) - self.object:remove() - break - end - end - end - end, - get_staticdata = function(self) - if self.nodename ~= nil and self.texture ~= nil then - return self.nodename .. ';' .. self.texture - end - return "" - end, -}) - -cottages.water_gen_fill_bucket = function(pos) - if( not(pos)) then - return - end - local meta = minetest.get_meta(pos) - local bucket = meta:get_string("bucket") - -- nothing to do - if( not(bucket) or bucket ~= "bucket:bucket_empty") then - return - end - -- abort if the water has not been running long enough - -- (the player may have removed a bucket before it was full) - start = meta:get_string("fillstarttime") - if( (minetest.get_us_time()/1000000) - tonumber(start) < cottages.water_fill_time -2) then - return - end - - -- the bucket has been filled - meta:set_string("bucket", "bucket:bucket_river_water") - - -- change the texture of the bucket to that of one filled with river water - local objs = nil - objs = minetest.get_objects_inside_radius(pos, .5) - if objs then - for _, obj in ipairs(objs) do - if obj and obj:get_luaentity() and obj:get_luaentity().name == "cottages:bucket_entity" then - obj:set_properties( { textures = { "bucket:bucket_river_water" }}) - obj:get_luaentity().nodename = "bucket:bucket_river_water" - obj:get_luaentity().texture = "bucket:bucket_river_water" - end - end - end -end - - -minetest.register_node("cottages:water_gen", { - description = "Tree Trunk Well", - tiles = {"default_tree_top.png", "default_tree.png^[transformR90", "default_tree.png^[transformR90"}, - drawtype = "nodebox", - paramtype = "light", - paramtype2 = "facedir", - is_ground_content = false, - groups = {tree = 1, choppy = 2, cracky = 1, flammable = 2}, - sounds = cottages.sounds.wood, - node_box = { - type = "fixed", - fixed = { - -- floor of water bassin - {-0.5, -0.5+(3/16), -0.5, 0.5, -0.5+(4/16), 0.5}, - -- walls - {-0.5, -0.5+(3/16), -0.5, 0.5, (4/16), -0.5+(2/16)}, - {-0.5, -0.5+(3/16), -0.5, -0.5+(2/16), (4/16), 0.5}, - { 0.5, -0.5+(3/16), 0.5, 0.5-(2/16), (4/16), -0.5}, - { 0.5, -0.5+(3/16), 0.5, -0.5+(2/16), (4/16), 0.5-(2/16)}, - -- feet - {-0.5+(3/16), -0.5, -0.5+(3/16), -0.5+(6/16), -0.5+(3/16), 0.5-(3/16)}, - { 0.5-(3/16), -0.5, -0.5+(3/16), 0.5-(6/16), -0.5+(3/16), 0.5-(3/16)}, - -- real pump - { 0.5-(4/16), -0.5, -(2/16), 0.5, 0.5+(4/16), (2/16)}, - -- water pipe inside wooden stem - { 0.5-(8/16), 0.5+(1/16), -(1/16), 0.5, 0.5+(3/16), (1/16)}, - -- where the water comes out - { 0.5-(15/32), 0.5, -(1/32), 0.5-(12/32), 0.5+(1/16), (1/32)}, - }, - }, - selection_box = { - type = "fixed", - fixed = { -0.5, -0.5, -0.5, 0.5, 0.5+(4/16), 0.5 } - }, - on_construct = function(pos) - local meta = minetest.get_meta(pos) - local spos = pos.x .. "," .. pos.y .. "," .. pos.z - meta:set_string("formspec", - "size[8,9]" .. - "label[3.0,0.0;Tree trunk well]".. - "label[1.5,0.7;Punch the well while wielding an empty bucket.]".. - "label[1.5,1.0;Your bucket will slowly be filled with river water.]".. - "label[1.5,1.3;Punch again to get the bucket back when it is full.]".. - "label[1.0,2.9;Internal bucket storage (passive storage only):]".. - "item_image[0.2,0.7;1.0,1.0;bucket:bucket_empty]".. - "item_image[0.2,1.7;1.0,1.0;bucket:bucket_river_water]".. - "label[1.5,1.9;Punch well with full water bucket in order to empty bucket.]".. - "button_exit[6.0,0.0;2,0.5;public;"..S("Public?").."]".. - "list[nodemeta:" .. spos .. ";main;1,3.3;8,1;]" .. - "list[current_player;main;0,4.85;8,1;]" .. - "list[current_player;main;0,6.08;8,3;8]" .. - "listring[nodemeta:" .. spos .. ";main]" .. - "listring[current_player;main]") - local inv = meta:get_inventory() - inv:set_size('main', 6) - meta:set_string("infotext", S("Public tree trunk well")) -- (punch with empty bucket to fill bucket)") - end, - after_place_node = function(pos, placer) - local meta = minetest.get_meta(pos) - meta:set_string("owner", placer:get_player_name() or "") - meta:set_string("infotext", S("Public tree trunk well (owned by %s)"):format(meta:get_string("owner"))) - -- no bucket loaded - meta:set_string("bucket", "") - meta:set_string("public", "public") - end, - can_dig = function(pos,player) - local meta = minetest.get_meta(pos); - local inv = meta:get_inventory() - local bucket = meta:get_string("bucket") - local start = meta:get_string("fillstarttime") - return inv:is_empty("main") - and default.can_interact_with_node(player, pos) - and (not(bucket) or bucket == "") - and ((not(start) or start == "" or - (minetest.get_us_time()/1000000) - tonumber(start) - >= cottages.water_fill_time -2)) - end, - -- no inventory move allowed - allow_metadata_inventory_move = function(pos, from_list, from_index, - to_list, to_index, count, player) - return 0 - end, - allow_metadata_inventory_put = function(pos, listname, index, stack, player) - local meta = minetest.get_meta(pos) - if not(stack) or not cottages.player_can_use(meta, player) then - return 0 - end - local inv = meta:get_inventory() - -- only for buckets - local sname = stack:get_name() - if( sname ~= "bucket:bucket_empty" - and sname ~= "bucket:bucket_water" - and sname ~= "bucket:bucket_river_water") then - return 0 - end - return stack:get_count() - end, - allow_metadata_inventory_take = function(pos, listname, index, stack, player) - local meta = minetest.get_meta(pos) - if not(cottages.player_can_use(meta, player)) then - return 0 - end - return stack:get_count() - end, - on_blast = function() end, - on_receive_fields = function(pos, formname, fields, sender) - cottages.switch_public(pos, formname, fields, sender, 'tree trunk well') - end, - -- punch to place and retrieve bucket - on_punch = function(pos, node, puncher, pointed_thing) - if( not( pos ) or not( node ) or not( puncher )) then - return - end - -- only the owner can use the well - local name = puncher:get_player_name() - local meta = minetest.get_meta(pos) - local owner = meta:get_string("owner") - local public = meta:get_string("public") - if( name ~= owner and public~="public") then - minetest.chat_send_player( name, - S("This tree trunk well is owned by %s. You can't use it."):format(owner)) - return - end - - -- we will either add or take from the players inventory - local pinv = puncher:get_inventory() - - -- is the well working on something? (either empty or full bucket) - local bucket = meta:get_string("bucket") - -- there is a bucket loaded - either empty or full - if( bucket and bucket~="" and bucket ~= "bucket:bucket_empty") then - if( not(pinv:room_for_item("main", bucket))) then - minetest.chat_send_player( puncher:get_player_name(), - S("Sorry. You have no room for the bucket. Please free some ".. - "space in your inventory first!")) - return - end - elseif( bucket and bucket == "bucket:bucket_empty") then - minetest.chat_send_player( puncher:get_player_name(), - S("Please wait until your bucket has been filled.")) - -- do not give the empty bucket back immediately - return - end - - -- remove the old entity (either a bucket will be placed now or a bucket taken) - local objs = nil - objs = minetest.get_objects_inside_radius(pos, .5) - if objs then - for _, obj in ipairs(objs) do - if obj and obj:get_luaentity() and obj:get_luaentity().name == "cottages:bucket_entity" then - obj:remove() - end - end - end - - -- the player gets the bucket (either empty or full) into his inventory - if( bucket and bucket ~= "") then - pinv:add_item("main", bucket ) - meta:set_string("bucket", "") - -- we are done - return - end - - -- punching with empty bucket will put that bucket into the well (as an entity) - -- and will slowly fill it - local wielded = puncher:get_wielded_item() - if( wielded - and wielded:get_name() - and wielded:get_name() == "bucket:bucket_empty") then - -- remember that we got a bucket loaded - meta:set_string("bucket", "bucket:bucket_empty") - -- create the entity - tmp.nodename = "bucket:bucket_empty" - -- TODO: add a special texture with a handle for the bucket here - tmp.texture = "bucket:bucket_empty" - local e = minetest.add_entity({x=pos.x,y=pos.y+(4/16),z=pos.z},"cottages:bucket_entity") - -- fill the bucket with water - minetest.after(cottages.water_fill_time, cottages.water_gen_fill_bucket, pos) - -- the bucket will only be filled if the water ran long enough - meta:set_string("fillstarttime", tostring(minetest.get_us_time()/1000000)) - -- remove the bucket from the players inventory - pinv:remove_item( "main", "bucket:bucket_empty") - return; - end - -- buckets can also be emptied here - if( wielded - and wielded:get_name() - and (wielded:get_name() == "bucket:bucket_water" - or wielded:get_name() == "bucket:bucket_river_water") - and (pinv:room_for_item("main", "bucket:bucket_empty"))) then - -- remove the full bucket from the players inventory - pinv:remove_item( "main", wielded:get_name()) - -- add empty bucket - pinv:add_item("main", "bucket:bucket_empty") - -- TODO: play diffrent sound when pouring a bucket - return; - end - - -- else check if there is a bucket that can be retrieved - meta:set_string("bucket","") - end, -}) - - --- a well (will fill water buckets) crafted from wooden materials -minetest.register_craft({ - output = 'cottages:water_gen', - recipe = { - {'default:stick', '', ''}, - {'default:tree', 'bucket:bucket_empty', 'bucket:bucket_empty'}, - {'default:tree', 'default:tree', 'default:tree'}, - } -}) - diff --git a/resources/craftitems.lua b/resources/craftitems.lua new file mode 100644 index 0000000..45c546b --- /dev/null +++ b/resources/craftitems.lua @@ -0,0 +1,77 @@ +local has = cottages.has + +local resolve_item = futil.resolve_item + +local ci = {} + +ci.stick = "group:stick" +ci.wood = "group:wood" +ci.tree = "group:tree" + +if has.default then + ci.chest_locked = resolve_item("default:chest_locked") + ci.clay_brick = resolve_item("default:clay_brick") + ci.clay = resolve_item("default:clay") + ci.coal_lump = resolve_item("default:coal_lump") + ci.dirt = resolve_item("default:dirt") + ci.fence = resolve_item("default:fence_wood") + ci.glass = resolve_item("default:glass") + ci.iron = resolve_item("default:iron_lump") + ci.junglewood = resolve_item("default:junglewood") + ci.ladder = resolve_item("default:ladder") + ci.paper = resolve_item("default:paper") + ci.papyrus = resolve_item("default:papyrus") + ci.rail = resolve_item("default:rail") + ci.sand = resolve_item("default:sand") + ci.steel = resolve_item("default:steel_ingot") + ci.stone = resolve_item("default:stone") +end + +if has.bucket then + ci.bucket = resolve_item("bucket:bucket_empty") + ci.bucket_filled = resolve_item("bucket:bucket_river_water") +end + +if has.carts then + ci.rail = resolve_item("carts:rail") +end + +if has.doors then + ci.door = resolve_item("doors:door_wood") +end + +if has.farming then + ci.barley = resolve_item("farming:barley") + ci.cotton = resolve_item("farming:cotton") + ci.flour = resolve_item("farming:flour") + ci.oat = resolve_item("farming:oat") + ci.rice = resolve_item("farming:rice") + ci.rice_flour = resolve_item("farming:rice_flour") + ci.rye = resolve_item("farming:rye") + ci.seed_barley = resolve_item("farming:seed_barley") + ci.seed_oat = resolve_item("farming:seed_oat") + ci.seed_rye = resolve_item("farming:seed_rye") + ci.seed_wheat = resolve_item("farming:seed_wheat") + ci.string = resolve_item("farming:string") + ci.wheat = resolve_item("farming:wheat") +end + +if has.stairsplus and has.default then + ci.slab_wood = resolve_item("default:slab_wood_8") + +elseif has.moreblocks and resolve_item("moreblocks:slab_wood") then + ci.slab_wood = resolve_item("moreblocks:slab_wood") + +elseif has.stairs then + ci.slab_wood = resolve_item("stairs:slab_wood") +end + +if has.wool then + ci.wool = resolve_item("wool:white") +else + ci.wool = "cottages:wool" +end + +ci.straw_mat = "cottages:straw_mat" + +cottages.craftitems = ci diff --git a/resources/init.lua b/resources/init.lua new file mode 100644 index 0000000..f462d33 --- /dev/null +++ b/resources/init.lua @@ -0,0 +1,3 @@ +cottages.dofile("resources", "craftitems") +cottages.dofile("resources", "sounds") +cottages.dofile("resources", "textures") diff --git a/resources/sounds.lua b/resources/sounds.lua new file mode 100644 index 0000000..2a3b4d5 --- /dev/null +++ b/resources/sounds.lua @@ -0,0 +1,28 @@ +local has = cottages.has + +local sounds = {} + +if has.default then + sounds.wood = default.node_sound_wood_defaults() + sounds.dirt = default.node_sound_dirt_defaults() + sounds.stone = default.node_sound_stone_defaults() + sounds.leaves = default.node_sound_leaves_defaults() + sounds.metal = default.node_sound_metal_defaults() + + sounds.water_empty = "default_water_footstep" + sounds.water_fill = "default_water_footstep" + + sounds.tool_breaks = "default_tool_breaks" + + sounds.use_thresher = "default_grass_footstep" + sounds.use_quern = "default_gravel_footstep" +end + +if has.env_sounds then + sounds.water_empty = sounds.water_empty or "env_sounds_water" + sounds.water_fill = "env_sounds_water" + sounds.lava_fill = "env_sounds_lava" + sounds.lava_empty = "env_sounds_lava" +end + +cottages.sounds = sounds diff --git a/resources/textures.lua b/resources/textures.lua new file mode 100644 index 0000000..5f1d59a --- /dev/null +++ b/resources/textures.lua @@ -0,0 +1,36 @@ +local has = cottages.has + +local check_exists = futil.check_exists + +local textures = {} + +if has.default then + textures.furniture = "default_wood.png" + textures.roof_sides = "default_wood.png" + textures.stick = "default_stick.png" + textures.roof_wood = "default_tree.png" + textures.tree = "default_tree.png" + textures.tree_top = "default_tree_top.png" + textures.dust = "default_item_smoke.png" + +else + textures.furniture = "cottages_minimal_wood.png" + textures.roof_sides = "cottages_minimal_wood.png" + textures.stick = "cottages_minimal_wood.png" + textures.roof_wood = "cottages_minimal_wood.png" + textures.tree = "cottages_minimal_wood.png" + textures.tree_top = "cottages_minimal_wood.png" +end + +textures.straw = "cottages_darkage_straw.png" + +if has.farming then + textures.wheat_seed = "farming_wheat_seed.png" + textures.wheat = "farming_wheat.png" + + if cottages.settings.roof.use_farming_straw_stairs and check_exists("farming:straw") then + textures.straw = "farming_straw.png" + end +end + +cottages.textures = textures diff --git a/settings.lua b/settings.lua new file mode 100644 index 0000000..3275fc8 --- /dev/null +++ b/settings.lua @@ -0,0 +1,86 @@ +local s = minetest.settings + +cottages.settings = { + anvil = { + enabled = s:get_bool("cottages.anvil.enabled", true), + + disable_hammer_repair = s:get_bool("cottages.anvil.disable_hammer_repair", false), + hammer_wear = tonumber(s:get("cottages.anvil.hammer_wear")) or 100, + hud_timeout = tonumber(s:get("cottages.anvil.hud_timeout")) or 2, -- seconds + repair_amount = tonumber(s:get("cottages.anvil.repair_amount")) or 4369, + stamina = tonumber(s:get("cottages.anvil.stamina")) or 40, + formspec_enabled = s:get_bool("cottages.anvil.formspec_enabled", true), + tool_hud_enabled = s:get_bool("cottages.anvil.tool_hud_enabled", true), + tool_entity_enabled = s:get_bool("cottages.anvil.tool_entity_enabled", false), + tool_entity_displacement = tonumber(s:get("cottages.anvil.tool_entity_displacement")) or 2 / 16, + }, + + barrel = { + enabled = s:get_bool("cottages.barrel.enabled", true), + + max_liquid_amount = tonumber(s:get("cottages.barrel.max_liquid_amount")) or 99, + }, + + doorlike = { + enabled = s:get_bool("cottages.doorlike.enabled", true), + + stamina = tonumber(s:get("cottages.doorlike.stamina")) or 1, + }, + + feldweg = { + enabled = s:get_bool("cottages.feldweg.enabled", true), + }, + + fences = { + enabled = s:get_bool("cottages.fences.enabled", true), + }, + + furniture = { + enabled = s:get_bool("cottages.furniture.enabled", true), + }, + + hay = { + enabled = s:get_bool("cottages.hay.enabled", true), + }, + + historic = { + enabled = s:get_bool("cottages.historic.enabled", true), + }, + + mining = { + enabled = s:get_bool("cottages.mining.enabled", true), + }, + + pitchfork = { + enabled = s:get_bool("cottages.pitchfork.enabled", true), + + stamina = tonumber(s:get("cottages.pitchfork.stamina")) or 10, + }, + + roof = { + enabled = s:get_bool("cottages.roof.enabled", true), + + use_farming_straw_stairs = ( + s:get_bool("cottages.roof.use_farming_straw_stairs", false) and + minetest.registered_nodes["stairs:stair_straw"] + ), + }, + + straw = { + enabled = s:get_bool("cottages.straw.enabled", true), + + quern_min_per_turn = tonumber(s:get("cottages.straw.quern_min_per_turn")) or 2, + quern_max_per_turn = tonumber(s:get("cottages.straw.quern_max_per_turn")) or 5, + quern_stamina = tonumber(s:get("cottages.straw.quern_stamina")) or 20, + + threshing_min_per_punch = tonumber(s:get("cottages.straw.threshing_min_per_punch")) or 5, + threshing_max_per_punch = tonumber(s:get("cottages.straw.threshing_max_per_punch")) or 10, + threshing_stamina = tonumber(s:get("cottages.straw.threshing_stamina")) or 20, + }, + + water = { + enabled = s:get_bool("cottages.water.enabled", true), + + well_fill_time = tonumber(s:get("cottages.water.well_fill_time")) or 10 + }, +} diff --git a/settingtypes.txt b/settingtypes.txt new file mode 100644 index 0000000..03945ba --- /dev/null +++ b/settingtypes.txt @@ -0,0 +1,122 @@ +# provides an anivil and hammer which can be used to repair tools +cottages.anvil.enabled (enable the anvil module) bool true + +# disallow repairing the hammer itself in the anvil +cottages.anvil.disable_hammer_repair (disable hammer repair) bool false + +# wear added to the hammer per strike +cottages.anvil.hammer_wear (hammer wear) int 100 0 65536 + +# amount to repair the tool per strike. default is 65535/15. +cottages.anvil.repair_amount (anvil repair amount) int 4369 0 65535 + +# amount of stamina to consume per hammer strike +cottages.anvil.stamina (anvil stamina usage) int 40 0 + +# if false, right-click the anvil to place a tool on it +cottages.anvil.formspec_enabled (enable anvil formspec) bool true + +# whether to show an image of the tool being repaired in the HUD +cottages.anvil.tool_hud_enabled (enable tool HUD) bool true + +# length of time the hud will stay on the screen, in seconds +cottages.anvil.hud_timeout (hud timeout) float 2 0 + +# if true, an entity representing the tool to be repaired will appear on top of the anvil +cottages.anvil.tool_entity_enabled (tool entity enabled) bool false + +# how far above the anvil to put the entity +cottages.anvil.tool_entity_displacement (tool entity displacement) float .125 + +############################################################################### + +# provides a barrel which can be used to store liquids, and a couple decorative variants. +cottages.barrel.enabled (enable the barrel module) bool true + +# +cottages.barrel.max_liquid_amount (barrel max liquid amount) int 99 0 + +############################################################################### + +# provides shutters, half-doors, gates, and hatches +cottages.doorlike.enabled (enable the doorlike module) bool true + +# +cottages.doorlike.stamina (doorlike stamina usage) int 1 0 + +############################################################################### + +# provides variants of some nodes with a path worn into them +cottages.feldweg.enabled (enable the feldweg module) bool true + +############################################################################### + +# provides fences +cottages.fences.enabled (enable the fences module) bool true + +############################################################################### + +# provides benches, tables, shelves, beds, a sleeping mat, a wash basin, etc. +cottages.furniture.enabled (enable the furniture module) bool true + +############################################################################### + +# provides some hay nodes +cottages.hay.enabled (enable the hay module) bool true + +############################################################################### + +# a tent, glass panes, straw, loam, a wagon wheel +cottages.historic.enabled (enable the historic module) bool true + +############################################################################### + +# rope and some variants +cottages.mining.enabled (enable the mining module) bool true + +############################################################################### + +# provides a tool to gather hay from grassy dirt. +cottages.pitchfork.enabled (enable the pitchfork module) bool true + +# stamina used when using the pitchfork +cottages.pitchfork.stamina (pitchfork stamina usage) bool true + +############################################################################### + +# provides some decorative roof variants +cottages.roof.enabled (enable the roof module) bool true + +# if true, we do not register our own straw roof variants +cottages.roof.use_farming_straw_stairs (roof uses farming straw stairs) bool false + +############################################################################### + +# provides a threshing floor and quern, which can be used to process e.g. wheat into seeds into flour +cottages.straw.enabled (enable the straw module) bool true + +# minimum # of items processed when punching the quern +cottages.straw.quern_min_per_turn (quern min output) int 2 0 65535 + +# maximum # of items processed when punching the quern +cottages.straw.quern_max_per_turn (quern max output) int 5 0 65535 + +# +cottages.straw.quern_stamina (quern stamina usage) int 20 0 + +# +cottages.straw.threshing_min_per_punch (threshing min output) int 5 0 65535 + +# +cottages.straw.threshing_max_per_punch (threshing max output) int 10 0 65535 + +# +cottages.straw.threshing_stamina (threshing stamina used) int 20 0 + +############################################################################### + +# provides a well which can be used to fill buckets with river water +cottages.water.enabled (enable the water module) bool true + +# how long it takes to fill a bucket +cottages.water.well_fill_time (well fill time) int 10 0 diff --git a/sounds/anvil_clang.ogg b/sounds/anvil_clang.ogg new file mode 100644 index 0000000..f960a28 Binary files /dev/null and b/sounds/anvil_clang.ogg differ diff --git a/sounds/license.txt b/sounds/license.txt new file mode 100644 index 0000000..50047c0 --- /dev/null +++ b/sounds/license.txt @@ -0,0 +1 @@ +anvil_clang.ogg - from https://freesound.org/people/Benboncan/sounds/103631/ by Benboncan under the CC BY 3.0 license diff --git a/textures/cottages_anvil_spark.png b/textures/cottages_anvil_spark.png new file mode 100644 index 0000000..a18643a Binary files /dev/null and b/textures/cottages_anvil_spark.png differ diff --git a/textures/cottages_quern.png b/textures/cottages_quern.png new file mode 100644 index 0000000..38151e3 Binary files /dev/null and b/textures/cottages_quern.png differ diff --git a/textures/glooptest_tool_steelhammer.png b/textures/cottages_tool_steelhammer.png similarity index 100% rename from textures/glooptest_tool_steelhammer.png rename to textures/cottages_tool_steelhammer.png diff --git a/util.lua b/util.lua new file mode 100644 index 0000000..35916a9 --- /dev/null +++ b/util.lua @@ -0,0 +1,60 @@ +local util = {} + +function util.player_can_use(pos, player) + if not (pos and minetest.is_player(player)) then + return false + end + + local player_name = player:get_player_name() + local meta = minetest.get_meta(pos) + + if meta:get_string("public") == "public" then + meta:set_int("public", 2) + end + + local owner = meta:get_string("owner") + local public = meta:get_int("public") + + return ( + (owner == player_name or owner == "" or owner == " ") or + public > 0 + ) +end + +function util.toggle_public(pos, sender) + local sender_name = sender:get_player_name() + local meta = minetest.get_meta(pos) + local owner = meta:get_string("owner") + local public = meta:get_int("public") + + if owner == "" or owner == " " and not minetest.is_protected(pos, sender_name) then + meta:set_string("owner", sender_name) + end + + if public == 0 and owner == sender_name then + -- owner can switch private to protected + meta:set_int("public", 1) + return true + + elseif public == 1 and not minetest.is_protected(pos, sender_name) then + -- player of area can switch protected to public + meta:set_int("public", 2) + return true + + elseif public == 2 then + if owner == sender_name then + -- owner can switch public to private + meta:set_int("public", 0) + return true + + elseif not minetest.is_protected(pos, sender_name) then + -- player of area can switch public to protected + meta:set_int("public", 1) + return true + end + end + + return false +end + +cottages.util = util