init
This commit is contained in:
commit
83fe8afa0b
8 changed files with 278 additions and 0 deletions
12
README.md
Normal file
12
README.md
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
Bell that rings every hour as many times as the hour counts (1-12 times)
|
||||||
|
Works like a church bell.
|
||||||
|
|
||||||
|
The positions of placed bells are saved. Thus, each bell can ring independently of the load status of the area the bell is in.
|
||||||
|
|
||||||
|
You can ring a bell manually.
|
||||||
|
|
||||||
|
There is also a small bell (looks like the normal one) that can be crafted from gold blocks. Unlike the normal bell, this craftable one won't ring automaticly and has a much smaller hear distance.
|
||||||
|
|
||||||
|
If you actually want to use this mod, you need to create a folder sounds/ in it (on the same level as textures/) and put sound files named bell_bell.ogg (for the large, uncraftable bell) and bell_small.ogg (for the craftable one) into the folder.
|
||||||
|
|
||||||
|
License: GPLv3
|
||||||
1
depends.txt
Normal file
1
depends.txt
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
default?
|
||||||
260
init.lua
Normal file
260
init.lua
Normal file
|
|
@ -0,0 +1,260 @@
|
||||||
|
|
||||||
|
-- bell_positions are saved through server restart
|
||||||
|
-- bells ring every hour
|
||||||
|
-- they ring as many times as a bell ought to
|
||||||
|
|
||||||
|
bell = {};
|
||||||
|
|
||||||
|
bell.RING_INTERVAL = 3600; --60*60; -- ring each hour
|
||||||
|
|
||||||
|
bell.BELL_SAVE_FILE = minetest.get_worldpath().."/bell_positions.data";
|
||||||
|
|
||||||
|
local bell_positions = {};
|
||||||
|
|
||||||
|
|
||||||
|
bell.save_bell_positions = function( player )
|
||||||
|
|
||||||
|
str = minetest.serialize( ({ bell_data = bell_positions}) );
|
||||||
|
|
||||||
|
local file, err = io.open( bell.BELL_SAVE_FILE, "wb");
|
||||||
|
if (err ~= nil) then
|
||||||
|
if( player ) then
|
||||||
|
minetest.chat_send_player(player:get_player_name(), "Error: Could not save bell data");
|
||||||
|
end
|
||||||
|
return
|
||||||
|
end
|
||||||
|
file:write( str );
|
||||||
|
file:flush();
|
||||||
|
file:close();
|
||||||
|
--minetest.chat_send_all("Wrote data to savefile "..tostring( bell.BELL_SAVE_FILE ));
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
bell.restore_bell_data = function()
|
||||||
|
|
||||||
|
local bell_position_table;
|
||||||
|
|
||||||
|
local file, err = io.open(bell.BELL_SAVE_FILE, "rb");
|
||||||
|
if (err ~= nil) then
|
||||||
|
print("Error: Could not open bell data savefile (ignore this message on first start)");
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local str = file:read();
|
||||||
|
file:close();
|
||||||
|
|
||||||
|
local bell_positions_table = minetest.deserialize( str );
|
||||||
|
if( bell_positions_table and bell_positions_table.bell_data ) then
|
||||||
|
bell_positions = bell_positions_table.bell_data;
|
||||||
|
print("[bell] Read positions of bells from savefile.");
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
-- actually ring the bell
|
||||||
|
bell.ring_bell_once = function()
|
||||||
|
|
||||||
|
for i,v in ipairs( bell_positions ) do
|
||||||
|
-- print("Ringing bell at "..tostring( minetest.pos_to_string( v )));
|
||||||
|
minetest.sound_play( "bell_bell",
|
||||||
|
{ pos = v, gain = 1.5, max_hear_distance = 300,});
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bell.ring_bell = function()
|
||||||
|
|
||||||
|
-- figure out if this is the right time to ring
|
||||||
|
local sekunde = tonumber( os.date( "%S"));
|
||||||
|
local minute = tonumber( os.date( "%M"));
|
||||||
|
local stunde = tonumber( os.date( "%I")); -- in 12h-format (a bell that rings 24x at once would not survive long...)
|
||||||
|
local delay = bell.RING_INTERVAL;
|
||||||
|
|
||||||
|
--print("[bells]It is now H:"..tostring( stunde ).." M:"..tostring(minute).." S:"..tostring( sekunde ));
|
||||||
|
|
||||||
|
--local datum = os.date( "Stunde:%l Minute:%M Sekunde:%S");
|
||||||
|
--print('[bells] ringing bells at '..tostring( datum ))
|
||||||
|
|
||||||
|
delay = bell.RING_INTERVAL - sekunde - (minute*60);
|
||||||
|
|
||||||
|
-- make sure the bell rings the next hour
|
||||||
|
minetest.after( delay, bell.ring_bell );
|
||||||
|
|
||||||
|
-- if no bells are around then don't ring
|
||||||
|
if( bell_positions == nil or #bell_positions < 1 ) then
|
||||||
|
return;
|
||||||
|
end
|
||||||
|
|
||||||
|
if( sekunde > 10 ) then
|
||||||
|
-- print("[bells] Too late. Waiting for "..tostring( delay ).." seconds.");
|
||||||
|
return;
|
||||||
|
end
|
||||||
|
|
||||||
|
-- ring the bell for each hour once
|
||||||
|
for i=1,stunde do
|
||||||
|
minetest.after( (i-1)*5, bell.ring_bell_once );
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
-- first call (after the server has been started)
|
||||||
|
minetest.after( 10, bell.ring_bell );
|
||||||
|
-- read data about bell positions
|
||||||
|
bell.restore_bell_data();
|
||||||
|
|
||||||
|
-- Ein kleiner Helfer, um zu prüfen, ob ein Werkzeug eine Spitzhacke ist.
|
||||||
|
-- Diese Funktion wird von der Glocke unten benötigt.
|
||||||
|
local function is_pickaxe(itemstack)
|
||||||
|
-- Prüfen, ob der Spieler überhaupt etwas in der Hand hält
|
||||||
|
if not itemstack or itemstack:is_empty() then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
-- Die korrekte Funktion, um die Werkzeug-Fähigkeiten abzufragen
|
||||||
|
local capabilities = itemstack:get_tool_capabilities()
|
||||||
|
if capabilities and capabilities.groupcaps and capabilities.groupcaps.cracky then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
-- Registrierung der überarbeiteten Glocke
|
||||||
|
minetest.register_node("bell:bell", {
|
||||||
|
description = "Automatic hour bell",
|
||||||
|
|
||||||
|
-- KORRIGIERT: Notwendig für korrekte Physik und Form
|
||||||
|
drawtype = "nodebox",
|
||||||
|
paramtype = "facedir",
|
||||||
|
|
||||||
|
tiles = {"bell_bell.png"},
|
||||||
|
inventory_image = 'bell_bell.png',
|
||||||
|
wield_image = 'bell_bell.png',
|
||||||
|
stack_max = 1, -- Beachte: stack_max=1 kann unpraktisch sein, aber ich habe es beibehalten.
|
||||||
|
|
||||||
|
-- HINZUGEFÜGT: Die detaillierte Form der kleinen Glocke
|
||||||
|
node_box = {
|
||||||
|
type = "fixed",
|
||||||
|
fixed = {
|
||||||
|
{-0.3, -0.5, -0.3, 0.3, -0.35, 0.3}, -- Rand
|
||||||
|
{-0.2, -0.35, -0.2, 0.2, 0.0, 0.2}, -- Unterer Körper
|
||||||
|
{-0.15, 0.0, -0.15, 0.15, 0.3, 0.15}, -- Oberer Körper
|
||||||
|
{-0.1, 0.3, -0.1, 0.1, 0.4, 0.1}, -- Aufhängung
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
groups = {
|
||||||
|
cracky = 3, -- Härte 4 ist jetzt sinnvoll, da der Abbau kontrolliert wird
|
||||||
|
disable_punch_damage = 1
|
||||||
|
},
|
||||||
|
|
||||||
|
-- HINZUGEFÜGT: Die neue, robuste Abbaulogik
|
||||||
|
on_dig = function(pos, node, digger)
|
||||||
|
if is_pickaxe(digger:get_wielded_item()) then
|
||||||
|
minetest.node_dig(pos, node, digger)
|
||||||
|
end
|
||||||
|
-- Ansonsten passiert nichts
|
||||||
|
end,
|
||||||
|
|
||||||
|
-- #################################################
|
||||||
|
-- ## DEINE BISHERIGE LOGIK WURDE VOLL ÜBERNOMMEN ##
|
||||||
|
-- #################################################
|
||||||
|
|
||||||
|
on_punch = function (pos,node,puncher)
|
||||||
|
minetest.sound_play( "bell_bell",
|
||||||
|
{ pos = pos, gain = 1.5, max_hear_distance = 300,});
|
||||||
|
minetest.chat_send_all(puncher:get_player_name().." hat die Glocke geläutet!")
|
||||||
|
end,
|
||||||
|
|
||||||
|
after_place_node = function(pos, placer)
|
||||||
|
if( placer ~= nil ) then
|
||||||
|
minetest.chat_send_all(placer:get_player_name().." hat eine neue Glocke an "..tostring( minetest.pos_to_string( pos )).." aufgehängt.");
|
||||||
|
end
|
||||||
|
-- remember that there is a bell at that position
|
||||||
|
table.insert( bell_positions, pos );
|
||||||
|
bell.save_bell_positions( placer );
|
||||||
|
end,
|
||||||
|
|
||||||
|
after_dig_node = function(pos, oldnode, oldmetadata, digger)
|
||||||
|
if( digger ~= nil ) then
|
||||||
|
minetest.chat_send_all(digger:get_player_name().." hat die Glocke bei "..tostring( minetest.pos_to_string( pos )).." entfernt.");
|
||||||
|
end
|
||||||
|
|
||||||
|
local found = 0;
|
||||||
|
-- actually remove the bell from the list
|
||||||
|
for i,v in ipairs( bell_positions ) do
|
||||||
|
if( v ~= nil and v.x == pos.x and v.y == pos.y and v.z == pos.z ) then
|
||||||
|
found = i;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
-- actually remove the bell
|
||||||
|
if( found > 0 ) then
|
||||||
|
table.remove( bell_positions, found );
|
||||||
|
bell.save_bell_positions( digger );
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
-- Registrierung der kleinen Glocke
|
||||||
|
minetest.register_node("bell:bell_small", {
|
||||||
|
description = "Manual small bell",
|
||||||
|
drawtype = "nodebox",
|
||||||
|
paramtype = "facedir", -- Erlaubt das Drehen beim Platzieren
|
||||||
|
|
||||||
|
tiles = {"bell_small.png"},
|
||||||
|
inventory_image = 'bell_small.png',
|
||||||
|
wield_image = 'bell_small.png',
|
||||||
|
stack_max = 10,
|
||||||
|
|
||||||
|
-- Die finale Nodebox-Form für die kleine Glocke
|
||||||
|
node_box = {
|
||||||
|
type = "fixed",
|
||||||
|
fixed = {
|
||||||
|
-- 1. Der breite untere Rand
|
||||||
|
{-0.3, -0.5, -0.3, 0.3, -0.35, 0.3},
|
||||||
|
-- 2. Unterer, breiter Körper
|
||||||
|
{-0.2, -0.35, -0.2, 0.2, 0.0, 0.2},
|
||||||
|
-- 3. Oberer, schmaler Körper
|
||||||
|
{-0.15, 0.0, -0.15, 0.15, 0.3, 0.15},
|
||||||
|
-- 4. Die Aufhängung
|
||||||
|
{-0.1, 0.3, -0.1, 0.1, 0.4, 0.1},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
groups = {
|
||||||
|
cracky = 3, -- Robuste Härte, die ein gutes Werkzeug erfordert
|
||||||
|
disable_punch_damage = 1 -- Sicherheitshalber beibehalten
|
||||||
|
},
|
||||||
|
|
||||||
|
-- Spielt nur den Sound bei einem kurzen Klick
|
||||||
|
on_punch = function (pos, node, puncher)
|
||||||
|
-- Hier kannst du den Sound für die kleine Glocke anpassen, falls gewünscht
|
||||||
|
minetest.sound_play("bell_small" , {
|
||||||
|
pos = pos,
|
||||||
|
gain = 1.0, -- Etwas leiser als die große Glocke
|
||||||
|
max_hear_distance = 200
|
||||||
|
});
|
||||||
|
minetest.chat_send_all(puncher:get_player_name().." has rung the small bell!")
|
||||||
|
end,
|
||||||
|
|
||||||
|
-- Diese Funktion gibt uns die volle Kontrolle über den Abbauvorgang
|
||||||
|
on_dig = function(pos, node, digger)
|
||||||
|
-- Erlaube den Abbau nur, wenn der Spieler eine Spitzhacke benutzt
|
||||||
|
if is_pickaxe(digger:get_wielded_item()) then
|
||||||
|
-- Wenn ja, führe den normalen Abbauvorgang aus.
|
||||||
|
-- Dieser beachtet die Härte "cracky=4" und die Werkzeug-Qualität.
|
||||||
|
minetest.node_dig(pos, node, digger)
|
||||||
|
end
|
||||||
|
-- Wenn der Spieler die Hand oder ein falsches Werkzeug benutzt, passiert nichts.
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
minetest.register_craft({
|
||||||
|
output = "bell:bell_small",
|
||||||
|
recipe = {
|
||||||
|
{"", "default:goldblock", "" },
|
||||||
|
{"default:goldblock", "default:goldblock", "default:goldblock"},
|
||||||
|
{"default:goldblock", "", "default:goldblock"},
|
||||||
|
},
|
||||||
|
})
|
||||||
5
mod.conf
Normal file
5
mod.conf
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
release = 398
|
||||||
|
author = Sokomine
|
||||||
|
name = bell
|
||||||
|
description = A bell that sounds each hour - like a historic bell in a church or town hall
|
||||||
|
title = Bell
|
||||||
BIN
sounds/bell_bell.ogg
Normal file
BIN
sounds/bell_bell.ogg
Normal file
Binary file not shown.
BIN
sounds/bell_small.ogg
Normal file
BIN
sounds/bell_small.ogg
Normal file
Binary file not shown.
BIN
textures/bell_bell.png
Normal file
BIN
textures/bell_bell.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 732 B |
BIN
textures/bell_small.png
Normal file
BIN
textures/bell_small.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 715 B |
Loading…
Add table
Add a link
Reference in a new issue