refactor, cleanup, API, bugfixes (#1)

This commit is contained in:
fluxionary 2022-10-09 14:13:47 -07:00 committed by flux
parent dbe69bcfaf
commit 846308ef5a
No known key found for this signature in database
GPG Key ID: 9333B27816848A15
106 changed files with 5594 additions and 4596 deletions

25
.github/workflows/pre-commit.yml vendored Normal file
View File

@ -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

50
.luacheckrc Normal file
View File

@ -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",
},
}

19
.pre-commit-config.yaml Normal file
View File

@ -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,.]

54
API.md Normal file
View File

@ -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"},
}
```

View File

@ -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
<http://www.gnu.org/philosophy/why-not-lgpl.html>.

View File

@ -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 <celeron55@gmail.com>
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

View File

@ -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

View File

@ -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");

5
api/init.lua Normal file
View File

@ -0,0 +1,5 @@
cottages.api = {}
cottages.dofile("api", "register_machine")
cottages.dofile("api", "legacy")

5
api/legacy.lua Normal file
View File

@ -0,0 +1,5 @@
cottages.handmill_product = {
__newindex = function(t, k, v)
cottages.straw.register_quern_craft({input = k, output = v})
end
}

261
api/register_machine.lua Normal file
View File

@ -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

10
compat/adventuretest.lua Normal file
View File

@ -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

5
compat/init.lua Normal file
View File

@ -0,0 +1,5 @@
if cottages.has.workbench then
cottages.dofile("compat", "adventuretest")
cottages.dofile("compat", "realtest")
end

15
compat/realtest.lua Normal file
View File

@ -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

View File

@ -1,8 +0,0 @@
default?
farming?
stairs?
homedecor?
intllib?
trees?
wool?
moreblocks?

View File

@ -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

139
init.lua
View File

@ -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")

View File

@ -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.

View File

@ -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. =

View File

@ -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

513
modules/anvil/anvil.lua Normal file
View File

@ -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)

15
modules/anvil/api.lua Normal file
View File

@ -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

27
modules/anvil/compat.lua Normal file
View File

@ -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

56
modules/anvil/crafts.lua Normal file
View File

@ -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

65
modules/anvil/entity.lua Normal file
View File

@ -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

22
modules/anvil/hammer.lua Normal file
View File

@ -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

8
modules/anvil/init.lua Normal file
View File

@ -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")

121
modules/barrel/api.lua Normal file
View File

@ -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

168
modules/barrel/barrel.lua Normal file
View File

@ -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,
})

41
modules/barrel/compat.lua Normal file
View File

@ -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

View File

@ -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
})

36
modules/barrel/crafts.lua Normal file
View File

@ -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"},
},
})

8
modules/barrel/init.lua Normal file
View File

@ -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")

44
modules/barrel/nodes.lua Normal file
View File

@ -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,
})

23
modules/doorlike/abms.lua Normal file
View File

@ -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
})

163
modules/doorlike/api.lua Normal file
View File

@ -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

View File

@ -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

View File

@ -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")

229
modules/doorlike/nodes.lua Normal file
View File

@ -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,
}
)

331
modules/feldweg/api.lua Normal file
View File

@ -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

View File

@ -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")

View File

@ -0,0 +1,2 @@
cottages.feldweg.register_feldweg("ethereal:bamboo_dirt", "_bamboo")

View File

@ -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
)

15
modules/feldweg/init.lua Normal file
View File

@ -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

48
modules/fences/crafts.lua Normal file
View File

@ -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"},
}
})

4
modules/fences/init.lua Normal file
View File

@ -0,0 +1,4 @@
cottages.fences = {}
cottages.dofile("modules", "fences", "nodes")
cottages.dofile("modules", "fences", "crafts")

108
modules/fences/nodes.lua Normal file
View File

@ -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,
})

294
modules/furniture/api.lua Normal file
View File

@ -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)

View File

@ -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

View File

@ -0,0 +1,5 @@
cottages.furniture = {}
cottages.dofile("modules", "furniture", "api")
cottages.dofile("modules", "furniture", "nodes")
cottages.dofile("modules", "furniture", "crafts")

326
modules/furniture/nodes.lua Normal file
View File

@ -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,
})

26
modules/hay/crafts.lua Normal file
View File

@ -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"}},
})

3
modules/hay/init.lua Normal file
View File

@ -0,0 +1,3 @@
cottages.dofile("modules", "hay", "nodes")
cottages.dofile("modules", "hay", "crafts")

57
modules/hay/nodes.lua Normal file
View File

@ -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,
})

View File

@ -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"}
}
})

View File

@ -0,0 +1,3 @@
cottages.dofile("modules", "historic", "nodes")
cottages.dofile("modules", "historic", "crafts")

155
modules/historic/nodes.lua Normal file
View File

@ -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

5
modules/init.lua Normal file
View File

@ -0,0 +1,5 @@
for module, settings in pairs(cottages.settings) do
if settings.enabled then
cottages.dofile("modules", module, "init")
end
end

19
modules/mining/crafts.lua Normal file
View File

@ -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

3
modules/mining/init.lua Normal file
View File

@ -0,0 +1,3 @@
cottages.dofile("modules", "mining", "nodes")
cottages.dofile("modules", "mining", "crafts")

70
modules/mining/nodes.lua Normal file
View File

@ -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

View File

@ -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

View File

@ -0,0 +1,3 @@
cottages.dofile("modules", "pitchfork", "tool")
cottages.dofile("modules", "pitchfork", "crafts")

105
modules/pitchfork/tool.lua Normal file
View File

@ -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")

111
modules/roof/api.lua Normal file
View File

@ -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 )

13
modules/roof/crafts.lua Normal file
View File

@ -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}}
})

5
modules/roof/init.lua Normal file
View File

@ -0,0 +1,5 @@
cottages.roof = {}
cottages.dofile("modules", "roof", "api")
cottages.dofile("modules", "roof", "nodes")
cottages.dofile("modules", "roof", "crafts")

86
modules/roof/nodes.lua Normal file
View File

@ -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,
})

55
modules/straw/api.lua Normal file
View File

@ -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

93
modules/straw/crafts.lua Normal file
View File

@ -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

7
modules/straw/init.lua Normal file
View File

@ -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")

71
modules/straw/nodes.lua Normal file
View File

@ -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,
})

180
modules/straw/quern.lua Normal file
View File

@ -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,
})

243
modules/straw/threshing.lua Normal file
View File

@ -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,
})

92
modules/water/api.lua Normal file
View File

@ -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

12
modules/water/crafts.lua Normal file
View File

@ -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

14
modules/water/entity.lua Normal file
View File

@ -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,
},
})

10
modules/water/init.lua Normal file
View File

@ -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")

174
modules/water/well.lua Normal file
View File

@ -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
})

View File

@ -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} }
})

View File

@ -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"},
},
})

View File

@ -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,
})

View File

@ -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 },
}
})

View File

@ -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

View File

@ -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" },
}
})

View File

@ -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},
}
})

View File

@ -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"}},
})

View File

@ -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"}
}
})

View File

@ -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"}
}
})

View File

@ -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','' },
}
})

View File

@ -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},
},
})

View File

@ -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"},
},
})

View File

@ -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'},
}
})

77
resources/craftitems.lua Normal file
View File

@ -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

3
resources/init.lua Normal file
View File

@ -0,0 +1,3 @@
cottages.dofile("resources", "craftitems")
cottages.dofile("resources", "sounds")
cottages.dofile("resources", "textures")

28
resources/sounds.lua Normal file
View File

@ -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

36
resources/textures.lua Normal file
View File

@ -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

86
settings.lua Normal file
View File

@ -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
},
}

122
settingtypes.txt Normal file
View File

@ -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

Some files were not shown because too many files have changed in this diff Show More