This commit is contained in:
Milan2018 2021-05-16 18:37:45 +02:00
parent 29d57bc728
commit 84668505d4
104 changed files with 3105 additions and 1636 deletions

File diff suppressed because it is too large Load Diff

3
crops/.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
## Generic ignorable patterns and files
*~
debug.txt

View File

@ -184,9 +184,8 @@ minetest.register_abm({
return return
end end
if minetest.registered_nodes[n.name] and if minetest.registered_nodes[n.name].drawtype == "plantlike" or
(minetest.registered_nodes[n.name].drawtype == "plantlike" or minetest.registered_nodes[n.name].groups.flora == 1 or
minetest.registered_nodes[n.name].groups.flora == 1) or
n.name == "air" then n.name == "air" then
minetest.set_node(t, {name = "crops:pumpkin", param2 = faces[r].m}) minetest.set_node(t, {name = "crops:pumpkin", param2 = faces[r].m})

View File

@ -55,6 +55,12 @@ Change log:
- 2.5 - Added HUD text to show when player is inside a protected area (updates every 5 seconds) - 2.5 - Added HUD text to show when player is inside a protected area (updates every 5 seconds)
- 2.6 - Add protection against CSM tampering, updated Intllib support (thanks codexp), tweaked block textures - 2.6 - Add protection against CSM tampering, updated Intllib support (thanks codexp), tweaked block textures
- 2.7 - Remove protection field entity when protector has been dug - 2.7 - Remove protection field entity when protector has been dug
- 2.8 - Added 'protector_show_interval' setting to minetest.conf [default is 5], make protection field glow in dark.
- 2.9 - Added MineClone2 recipes for protection block but no official support as yet
- 3.0 - Added PlayerFactions support, 'protector_hud_interval' setting and listing in advanced settings for mod values.
- 3.1 - Ability to hide protection blocks using /protector_hide and /protector_show , italian local added (thanks Hamlet)
- 3.2 - Defaults to Minetest translation if found, otherwise intllib fallback if loaded, locale files updated for both. Added 'protector_msg' setting for player text.
- 3.3 - Added support for playerfactions new api (thanks louisroyer), added limiter to protection radius of 22.
Lucky Blocks: 10 Lucky Blocks: 10
@ -91,6 +97,11 @@ reset name list
show protected areas of your nearby protectors (max of 5) show protected areas of your nearby protectors (max of 5)
/protector_show_area
A players own protection blocks can be hidden and shown using the following:
/protector_hide
/protector_show /protector_show
@ -114,6 +125,15 @@ protector_hurt = 2
protector_flip = true protector_flip = true
- When true players who dig inside a protected area will flipped around to stop them using lag to grief into someone else's build - When true players who dig inside a protected area will flipped around to stop them using lag to grief into someone else's build
protector_show_interval
- Number of seconds the protection field is visible, defaults to 5 seconds.
protector_recipe = true
- When true allows players to craft protection blocks
protector_msg = true
- When true shows protection messages in players chat when trying to interact in someone else's area
Protector Tool Protector Tool

View File

@ -29,7 +29,6 @@ minetest.register_chatcommand("protector_remove", {
end end
removal_names = param removal_names = param
end, end,
}) })
@ -57,20 +56,19 @@ minetest.register_chatcommand("protector_replace", {
local names = replace_names:split(" ") local names = replace_names:split(" ")
minetest.chat_send_player(name, minetest.chat_send_player(name,
S("Replacing Protector name '@1' with '@2'", S("Replacing Protector name @1 with @2",
names[1] or "", names[2] or "")) names[1] or "", names[2] or ""))
return return
end end
replace_names = param replace_names = param
end, end,
}) })
minetest.register_abm({ minetest.register_abm({
nodenames = {"protector:protect", "protector:protect2"}, nodenames = {"protector:protect", "protector:protect2", "protector:protect_hidden"},
interval = 8, interval = 8,
chance = 1, chance = 1,
catch_up = false, catch_up = false,
@ -106,7 +104,6 @@ minetest.register_abm({
meta:set_string("owner", names[2]) meta:set_string("owner", names[2])
meta:set_string("infotext", S("Protection (owned by @1)", names[2])) meta:set_string("infotext", S("Protection (owned by @1)", names[2]))
end end
end end
end end
}) })
@ -115,7 +112,7 @@ minetest.register_abm({
local r = tonumber(minetest.settings:get("protector_radius")) or 5 local r = tonumber(minetest.settings:get("protector_radius")) or 5
-- show protection areas of nearby protectors owned by you (thanks agaran) -- show protection areas of nearby protectors owned by you (thanks agaran)
minetest.register_chatcommand("protector_show", { minetest.register_chatcommand("protector_show_area", {
params = "", params = "",
description = S("Show protected areas of your nearby protectors"), description = S("Show protected areas of your nearby protectors"),
privs = {}, privs = {},
@ -128,7 +125,7 @@ minetest.register_chatcommand("protector_show", {
local pos = minetest.find_nodes_in_area( local pos = minetest.find_nodes_in_area(
{x = pos.x - r, y = pos.y - r, z = pos.z - r}, {x = pos.x - r, y = pos.y - r, z = pos.z - r},
{x = pos.x + r, y = pos.y + r, z = pos.z + r}, {x = pos.x + r, y = pos.y + r, z = pos.z + r},
{"protector:protect", "protector:protect2"}) {"protector:protect", "protector:protect2", "protector:protect_hidden"})
local meta, owner local meta, owner
@ -138,9 +135,105 @@ minetest.register_chatcommand("protector_show", {
meta = minetest.get_meta(pos[n]) meta = minetest.get_meta(pos[n])
owner = meta:get_string("owner") or "" owner = meta:get_string("owner") or ""
if owner == name then if owner == name
or minetest.check_player_privs(name, {protection_bypass = true}) then
minetest.add_entity(pos[n], "protector:display") minetest.add_entity(pos[n], "protector:display")
end end
end end
end end
}) })
-- ability to hide protection blocks (borrowed from doors mod :)
minetest.register_node("protector:protect_hidden", {
description = "Hidden Protector",
drawtype = "airlike",
paramtype = "light",
paramtype2 = "facedir",
sunlight_propagates = true,
-- has to be walkable for falling nodes to stop falling
walkable = true,
pointable = false,
diggable = false,
buildable_to = false,
floodable = false,
drop = "",
groups = {not_in_creative_inventory = 1, unbreakable = 1},
on_blast = function() end,
-- 1px block inside door hinge near node top
collision_box = {
type = "fixed",
fixed = {-15/32, 13/32, -15/32, -13/32, 1/2, -13/32},
},
})
minetest.register_chatcommand("protector_show", {
params = "",
description = S("Show your nearby protection blocks"),
privs = {interact = true},
func = function(name, param)
local player = minetest.get_player_by_name(name)
if not player then
return false, "Player not found"
end
local pos = player:get_pos()
local a = minetest.find_nodes_in_area(
{x = pos.x - r, y = pos.y - r, z = pos.z - r},
{x = pos.x + r, y = pos.y + r, z = pos.z + r},
{"protector:protect_hidden"})
local meta, owner
for _, row in pairs(a) do
meta = minetest.get_meta(row)
owner = meta:get_string("owner") or ""
if owner == name
or minetest.check_player_privs(name, {protection_bypass = true}) then
minetest.swap_node(row, {name = "protector:protect"})
end
end
end
})
minetest.register_chatcommand("protector_hide", {
params = "",
description = S("Hide your nearby protection blocks"),
privs = {interact = true},
func = function(name, param)
local player = minetest.get_player_by_name(name)
if not player then
return false, "Player not found"
end
local pos = player:get_pos()
local a = minetest.find_nodes_in_area(
{x = pos.x - r, y = pos.y - r, z = pos.z - r},
{x = pos.x + r, y = pos.y + r, z = pos.z + r},
{"protector:protect", "protector:protect2"})
local meta, owner
for _, row in pairs(a) do
meta = minetest.get_meta(row)
owner = meta:get_string("owner") or ""
if owner == name
or minetest.check_player_privs(name, {protection_bypass = true}) then
minetest.swap_node(row, {name = "protector:protect_hidden"})
end
end
end
})

View File

@ -1,4 +1,5 @@
default default?
intllib? intllib?
lucky_block? lucky_block?
mesecons_mvps? mesecons_mvps?
playerfactions?

View File

@ -6,6 +6,9 @@
local S = protector.intllib local S = protector.intllib
local F = minetest.formspec_escape local F = minetest.formspec_escape
-- MineClone2 support
local mcl = not minetest.registered_items["default:steel_ingot"]
-- Registers a door -- Registers a door
function register_door(name, def) function register_door(name, def)
def.groups.not_in_creative_inventory = 1 def.groups.not_in_creative_inventory = 1
@ -74,7 +77,7 @@ function register_door(name, def)
minetest.get_meta(pt2):set_int("right", 1) minetest.get_meta(pt2):set_int("right", 1)
end end
if not minetest.setting_getbool("creative_mode") then if not minetest.settings:get_bool("creative_mode") then
itemstack:take_item() itemstack:take_item()
end end
return itemstack return itemstack
@ -147,6 +150,7 @@ function register_door(name, def)
tiles = {tb[2], tb[2], tb[2], tb[2], tb[1], tb[1].."^[transformfx"}, tiles = {tb[2], tb[2], tb[2], tb[2], tb[1], tb[1].."^[transformfx"},
paramtype = "light", paramtype = "light",
paramtype2 = "facedir", paramtype2 = "facedir",
use_texture_alpha = "clip",
is_ground_content = false, is_ground_content = false,
drop = name, drop = name,
drawtype = "nodebox", drawtype = "nodebox",
@ -184,6 +188,7 @@ function register_door(name, def)
tiles = {tt[2], tt[2], tt[2], tt[2], tt[1], tt[1].."^[transformfx"}, tiles = {tt[2], tt[2], tt[2], tt[2], tt[1], tt[1].."^[transformfx"},
paramtype = "light", paramtype = "light",
paramtype2 = "facedir", paramtype2 = "facedir",
use_texture_alpha = "clip",
is_ground_content = false, is_ground_content = false,
drop = "", drop = "",
drawtype = "nodebox", drawtype = "nodebox",
@ -221,6 +226,7 @@ function register_door(name, def)
tiles = {tb[2], tb[2], tb[2], tb[2], tb[1].."^[transformfx", tb[1]}, tiles = {tb[2], tb[2], tb[2], tb[2], tb[1].."^[transformfx", tb[1]},
paramtype = "light", paramtype = "light",
paramtype2 = "facedir", paramtype2 = "facedir",
use_texture_alpha = "clip",
is_ground_content = false, is_ground_content = false,
drop = name, drop = name,
drawtype = "nodebox", drawtype = "nodebox",
@ -258,6 +264,7 @@ function register_door(name, def)
tiles = {tt[2], tt[2], tt[2], tt[2], tt[1].."^[transformfx", tt[1]}, tiles = {tt[2], tt[2], tt[2], tt[2], tt[1].."^[transformfx", tt[1]},
paramtype = "light", paramtype = "light",
paramtype2 = "facedir", paramtype2 = "facedir",
use_texture_alpha = "clip",
is_ground_content = false, is_ground_content = false,
drop = "", drop = "",
drawtype = "nodebox", drawtype = "nodebox",
@ -310,6 +317,14 @@ register_door(name, {
sunlight = false, sunlight = false,
}) })
if mcl then
minetest.register_craft({
output = name,
recipe = {
{"mcl_doors:wooden_door", "mcl_core:gold_ingot"}
}
})
else
minetest.register_craft({ minetest.register_craft({
output = name, output = name,
recipe = { recipe = {
@ -325,6 +340,7 @@ minetest.register_craft({
{"doors:door_wood", "default:copper_ingot"} {"doors:door_wood", "default:copper_ingot"}
} }
}) })
end
-- Protected Steel Door -- Protected Steel Door
@ -343,6 +359,14 @@ register_door(name, {
sunlight = false, sunlight = false,
}) })
if mcl then
minetest.register_craft({
output = name,
recipe = {
{"mcl_doors:iron_door", "mcl_core:gold_ingot"}
}
})
else
minetest.register_craft({ minetest.register_craft({
output = name, output = name,
recipe = { recipe = {
@ -358,6 +382,7 @@ minetest.register_craft({
{"doors:door_steel", "default:copper_ingot"} {"doors:door_steel", "default:copper_ingot"}
} }
}) })
end
----trapdoor---- ----trapdoor----
@ -383,6 +408,7 @@ function register_trapdoor(name, def)
def.drawtype = "nodebox" def.drawtype = "nodebox"
def.paramtype = "light" def.paramtype = "light"
def.paramtype2 = "facedir" def.paramtype2 = "facedir"
def.use_texture_alpha = "clip"
def.is_ground_content = false def.is_ground_content = false
local def_opened = table.copy(def) local def_opened = table.copy(def)
@ -408,8 +434,8 @@ function register_trapdoor(name, def)
fixed = {-0.5, -0.5, 6/16, 0.5, 0.5, 0.5} fixed = {-0.5, -0.5, 6/16, 0.5, 0.5, 0.5}
} }
def_opened.tiles = { def.tile_side, def.tile_side, def_opened.tiles = { def.tile_side, def.tile_side,
def.tile_side .. '^[transform3', def.tile_side .. "^[transform3",
def.tile_side .. '^[transform1', def.tile_side .. "^[transform1",
def.tile_front, def.tile_front } def.tile_front, def.tile_front }
def_opened.drop = name_closed def_opened.drop = name_closed
@ -434,12 +460,19 @@ register_trapdoor("protector:trapdoor", {
sounds = default.node_sound_wood_defaults(), sounds = default.node_sound_wood_defaults(),
}) })
if mcl then
minetest.register_craft({ minetest.register_craft({
output = 'protector:trapdoor 2', output = "protector:trapdoor",
recipe = { recipe = {
{'group:wood', 'default:copper_ingot', 'group:wood'}, {"mcl_doors:trapdoor", "mcl_core:gold_ingot"}
{'group:wood', 'group:wood', 'group:wood'}, }
{'', '', ''}, })
else
minetest.register_craft({
output = "protector:trapdoor 2",
recipe = {
{"group:wood", "default:copper_ingot", "group:wood"},
{"group:wood", "group:wood", "group:wood"},
} }
}) })
@ -449,6 +482,7 @@ minetest.register_craft({
{"doors:trapdoor", "default:copper_ingot"} {"doors:trapdoor", "default:copper_ingot"}
} }
}) })
end
-- Protected Steel Trapdoor -- Protected Steel Trapdoor
@ -465,11 +499,19 @@ register_trapdoor("protector:trapdoor_steel", {
sounds = default.node_sound_wood_defaults(), sounds = default.node_sound_wood_defaults(),
}) })
if mcl then
minetest.register_craft({ minetest.register_craft({
output = 'protector:trapdoor_steel', output = "protector:trapdoor_steel",
recipe = { recipe = {
{'default:copper_ingot', 'default:steel_ingot'}, {"mcl_doors:iron_trapdoor", "mcl_core:gold_ingot"}
{'default:steel_ingot', 'default:steel_ingot'}, }
})
else
minetest.register_craft({
output = "protector:trapdoor_steel",
recipe = {
{"default:copper_ingot", "default:steel_ingot"},
{"default:steel_ingot", "default:steel_ingot"},
} }
}) })
@ -479,6 +521,7 @@ minetest.register_craft({
{"doors:trapdoor_steel", "default:copper_ingot"} {"doors:trapdoor_steel", "default:copper_ingot"}
} }
}) })
end
-- Protected Chest -- Protected Chest
@ -501,7 +544,7 @@ minetest.register_node("protector:chest", {
local inv = meta:get_inventory() local inv = meta:get_inventory()
meta:set_string("infotext", S("Protected Chest")) meta:set_string("infotext", S("Protected Chest"))
meta:set_string("name", "") meta:set_string("name", S("Protected Chest"))
inv:set_size("main", 8 * 4) inv:set_size("main", 8 * 4)
end, end,
@ -520,20 +563,24 @@ minetest.register_node("protector:chest", {
on_metadata_inventory_put = function(pos, listname, index, stack, player) on_metadata_inventory_put = function(pos, listname, index, stack, player)
minetest.log("action", S("@1 moves stuff to protected chest at @2", minetest.log("action", player:get_player_name() ..
player:get_player_name(), minetest.pos_to_string(pos))) " moves stuff to protected chest at " ..
minetest.pos_to_string(pos))
end, end,
on_metadata_inventory_take = function(pos, listname, index, stack, player) on_metadata_inventory_take = function(pos, listname, index, stack, player)
minetest.log("action", S("@1 takes stuff from protected chest at @2", minetest.log("action", player:get_player_name() ..
player:get_player_name(), minetest.pos_to_string(pos))) " takes stuff from protected chest at " ..
minetest.pos_to_string(pos))
end, end,
on_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player) on_metadata_inventory_move = function(
pos, from_list, from_index, to_list, to_index, count, player)
minetest.log("action", S("@1 moves stuff inside protected chest at @2", minetest.log("action", player:get_player_name() ..
player:get_player_name(), minetest.pos_to_string(pos))) " moves stuff inside protected chest at " ..
minetest.pos_to_string(pos))
end, end,
allow_metadata_inventory_put = function(pos, listname, index, stack, player) allow_metadata_inventory_put = function(pos, listname, index, stack, player)
@ -554,7 +601,8 @@ minetest.register_node("protector:chest", {
return stack:get_count() return stack:get_count()
end, end,
allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player) allow_metadata_inventory_move = function(
pos, from_list, from_index, to_list, to_index, count, player)
if minetest.is_protected(pos, player:get_player_name()) then if minetest.is_protected(pos, player:get_player_name()) then
return 0 return 0
@ -577,9 +625,9 @@ minetest.register_node("protector:chest", {
local spos = pos.x .. "," .. pos.y .. "," ..pos.z local spos = pos.x .. "," .. pos.y .. "," ..pos.z
local formspec = "size[8,9]" local formspec = "size[8,9]"
.. default.gui_bg -- .. default.gui_bg
.. default.gui_bg_img -- .. default.gui_bg_img
.. default.gui_slots -- .. default.gui_slots
.. "list[nodemeta:".. spos .. ";main;0,0.3;8,4;]" .. "list[nodemeta:".. spos .. ";main;0,0.3;8,4;]"
.. "button[0,4.5;2,0.25;toup;" .. F(S("To Chest")) .. "]" .. "button[0,4.5;2,0.25;toup;" .. F(S("To Chest")) .. "]"
.. "field[2.3,4.8;4,0.25;chestname;;" .. "field[2.3,4.8;4,0.25;chestname;;"
@ -599,15 +647,39 @@ minetest.register_node("protector:chest", {
on_blast = function() end, on_blast = function() end,
}) })
-- Container transfer helper
local to_from = function(src, dst)
local stack, item, leftover
local size = dst:get_size("main")
for i = 1, size do
stack = src:get_stack("main", i)
item = stack:get_name()
if item ~= "" and dst:room_for_item("main", item) then
leftover = dst:add_item("main", stack)
if leftover and not leftover:is_empty() then
src:set_stack("main", i, leftover)
else
src:set_stack("main", i, nil)
end
end
end
end
-- Protected Chest formspec buttons -- Protected Chest formspec buttons
minetest.register_on_player_receive_fields(function(player, formname, fields) minetest.register_on_player_receive_fields(function(player, formname, fields)
if string.sub(formname, 0, string.len("protector:chest_")) ~= "protector:chest_" then if string.sub(formname, 0, 16) ~= "protector:chest_" then
return return
end end
local pos_s = string.sub(formname,string.len("protector:chest_") + 1) local pos_s = string.sub(formname, 17)
local pos = minetest.string_to_pos(pos_s) local pos = minetest.string_to_pos(pos_s)
if minetest.is_protected(pos, player:get_player_name()) then if minetest.is_protected(pos, player:get_player_name()) then
@ -617,43 +689,16 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
local meta = minetest.get_meta(pos) ; if not meta then return end local meta = minetest.get_meta(pos) ; if not meta then return end
local chest_inv = meta:get_inventory() ; if not chest_inv then return end local chest_inv = meta:get_inventory() ; if not chest_inv then return end
local player_inv = player:get_inventory() local player_inv = player:get_inventory()
local leftover
-- copy contents of player inventory to chest
if fields.toup then if fields.toup then
-- copy contents of players inventory to chest to_from(player_inv, chest_inv)
for i, v in ipairs(player_inv:get_list("main") or {}) do
if chest_inv:room_for_item("main", v) then
leftover = chest_inv:add_item("main", v)
player_inv:remove_item("main", v)
if leftover
and not leftover:is_empty() then
player_inv:add_item("main", v)
end
end
end
-- copy contents of chest to player inventory
elseif fields.todn then elseif fields.todn then
-- copy contents of chest to players inventory to_from(chest_inv, player_inv)
for i, v in ipairs(chest_inv:get_list("main") or {}) do
if player_inv:room_for_item("main", v) then
leftover = player_inv:add_item("main", v)
chest_inv:remove_item("main", v)
if leftover
and not leftover:is_empty() then
chest_inv:add_item("main", v)
end
end
end
elseif fields.chestname then elseif fields.chestname then
@ -661,9 +706,9 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
if fields.chestname ~= "" then if fields.chestname ~= "" then
meta:set_string("name", fields.chestname) meta:set_string("name", fields.chestname)
meta:set_string("infotext", meta:set_string("infotext", fields.chestname)
S("Protected Chest (@1)", fields.chestname))
else else
meta:set_string("name", S("Protected Chest"))
meta:set_string("infotext", S("Protected Chest")) meta:set_string("infotext", S("Protected Chest"))
end end
@ -672,18 +717,27 @@ end)
-- Protected Chest recipes -- Protected Chest recipes
if mcl then
minetest.register_craft({ minetest.register_craft({
output = 'protector:chest', output = "protector:chest",
recipe = { recipe = {
{'group:wood', 'group:wood', 'group:wood'}, {"mcl_chests:chest", "mcl_core:gold_ingot"},
{'group:wood', 'default:copper_ingot', 'group:wood'}, }
{'group:wood', 'group:wood', 'group:wood'}, })
else
minetest.register_craft({
output = "protector:chest",
recipe = {
{"group:wood", "group:wood", "group:wood"},
{"group:wood", "default:copper_ingot", "group:wood"},
{"group:wood", "group:wood", "group:wood"},
} }
}) })
minetest.register_craft({ minetest.register_craft({
output = 'protector:chest', output = "protector:chest",
recipe = { recipe = {
{'default:chest', 'default:copper_ingot', ''}, {"default:chest", "default:copper_ingot"},
} }
}) })
end

View File

@ -1,14 +1,20 @@
local S = protector.intllib local S = protector.intllib
local radius = (tonumber(minetest.setting_get("protector_radius")) or 5) local radius = (tonumber(minetest.settings:get("protector_radius")) or 5)
-- radius limiter (minetest cannot handle node volume of more than 4096000)
if radius > 22 then radius = 22 end
local hud = {} local hud = {}
local hud_timer = 0 local hud_timer = 0
local hud_interval = (tonumber(minetest.settings:get("protector_hud_interval")) or 5)
if hud_interval > 0 then
minetest.register_globalstep(function(dtime) minetest.register_globalstep(function(dtime)
-- every 5 seconds -- every 5 seconds
hud_timer = hud_timer + dtime hud_timer = hud_timer + dtime
if hud_timer < 5 then if hud_timer < hud_interval then
return return
end end
hud_timer = 0 hud_timer = 0
@ -22,7 +28,7 @@ minetest.register_globalstep(function(dtime)
local protectors = minetest.find_nodes_in_area( local protectors = minetest.find_nodes_in_area(
{x = pos.x - radius , y = pos.y - radius , z = pos.z - radius}, {x = pos.x - radius , y = pos.y - radius , z = pos.z - radius},
{x = pos.x + radius , y = pos.y + radius , z = pos.z + radius}, {x = pos.x + radius , y = pos.y + radius , z = pos.z + radius},
{"protector:protect","protector:protect2"}) {"protector:protect","protector:protect2", "protector:protect_hidden"})
if #protectors > 0 then if #protectors > 0 then
local npos = protectors[1] local npos = protectors[1]
@ -40,17 +46,15 @@ minetest.register_globalstep(function(dtime)
hud_elem_type = "text", hud_elem_type = "text",
name = "Protector Area", name = "Protector Area",
number = 0xFFFF22, number = 0xFFFF22,
position = {x=0, y=0.95}, position = {x = 0, y = 0.95},
offset = {x=8, y=-8}, offset = {x = 8, y = -8},
text = hud_text, text = hud_text,
scale = {x=200, y=60}, scale = {x = 200, y = 60},
alignment = {x=1, y=-1}, alignment = {x = 1, y = -1},
}) })
return return
else else
player:hud_change(hud[name].id, "text", hud_text) player:hud_change(hud[name].id, "text", hud_text)
end end
end end
@ -59,3 +63,5 @@ end)
minetest.register_on_leaveplayer(function(player) minetest.register_on_leaveplayer(function(player)
hud[player:get_player_name()] = nil hud[player:get_player_name()] = nil
end) end)
end

View File

@ -1,14 +1,27 @@
-- default support (for use with MineClone2 and other [games]
default = default or {
node_sound_stone_defaults = function(table) end,
node_sound_wood_defaults = function(table) end,
gui_bg = "",
gui_bg_img = "",
gui_slots = "",
}
-- Load support for intllib. -- Load support for intllib.
local MP = minetest.get_modpath(minetest.get_current_modname()) local MP = minetest.get_modpath(minetest.get_current_modname())
local S = dofile(MP .. "/intllib.lua")
local F = minetest.formspec_escape local F = minetest.formspec_escape
local S = minetest.get_translator and minetest.get_translator("protector") or
dofile(MP .. "/intllib.lua")
-- Load support for factions
local factions_available = minetest.global_exists("factions")
protector = {} protector = {
protector.mod = "redo" mod = "redo",
protector.modpath = MP modpath = MP,
protector.intllib = S intllib = S
}
local protector_max_share_count = 12 local protector_max_share_count = 12
-- get minetest.conf settings -- get minetest.conf settings
@ -17,6 +30,13 @@ local protector_flip = minetest.settings:get_bool("protector_flip") or false
local protector_hurt = tonumber(minetest.settings:get("protector_hurt")) or 0 local protector_hurt = tonumber(minetest.settings:get("protector_hurt")) or 0
local protector_spawn = tonumber(minetest.settings:get("protector_spawn") local protector_spawn = tonumber(minetest.settings:get("protector_spawn")
or minetest.settings:get("protector_pvp_spawn")) or 0 or minetest.settings:get("protector_pvp_spawn")) or 0
local protector_show = tonumber(minetest.settings:get("protector_show_interval")) or 5
local protector_recipe = minetest.settings:get_bool("protector_recipe") ~= false
local protector_msg = minetest.settings:get_bool("protector_msg") ~= false
-- radius limiter (minetest cannot handle node volume of more than 4096000)
if protector_radius > 22 then protector_radius = 22 end
-- get static spawn position -- get static spawn position
local statspawn = minetest.string_to_pos(minetest.settings:get("static_spawnpoint")) local statspawn = minetest.string_to_pos(minetest.settings:get("static_spawnpoint"))
@ -45,7 +65,35 @@ end
-- check for member name -- check for member name
local is_member = function (meta, name) local is_member = function(meta, name)
if factions_available
and meta:get_int("faction_members") == 1 then
if factions.version == nil then
-- backward compatibility
if factions.get_player_faction(name) ~= nil
and factions.get_player_faction(meta:get_string("owner")) ==
factions.get_player_faction(name) then
return true
end
else
-- is member if player and owner share at least one faction
local owner_factions = factions.get_player_factions(name)
local owner = meta:get_string("owner")
if owner_factions ~= nil and owner_factions ~= false then
for _, f in ipairs(owner_factions) do
if factions.player_is_in_faction(f, owner) then
return true
end
end
end
end
end
for _, n in pairs(get_member_list(meta)) do for _, n in pairs(get_member_list(meta)) do
@ -117,6 +165,36 @@ local protector_formspec = function(meta)
local members = get_member_list(meta) local members = get_member_list(meta)
local npp = protector_max_share_count -- max users added to protector list local npp = protector_max_share_count -- max users added to protector list
local i = 0 local i = 0
local checkbox_faction = false
-- Display the checkbox only if the owner is member of at least 1 faction
if factions_available then
if factions.version == nil then
-- backward compatibility
if factions.get_player_faction(meta:get_string("owner")) then
checkbox_faction = true
end
else
local player_factions = factions.get_player_factions(meta:get_string("owner"))
if player_factions ~= nil and #player_factions >= 1 then
checkbox_faction = true
end
end
end
if checkbox_faction then
formspec = formspec .. "checkbox[0,5;faction_members;"
.. F(S("Allow faction access"))
.. ";" .. (meta:get_int("faction_members") == 1 and
"true" or "false") .. "]"
if npp > 8 then
npp = 8
end
end
for n = 1, #members do for n = 1, #members do
@ -174,6 +252,18 @@ local inside_spawn = function(pos, radius)
end end
-- show protection message if enabled
local show_msg = function(player, msg)
-- if messages disabled or no player name provided
if protector_msg == false or not player or player == "" then
return
end
minetest.chat_send_player(player, msg)
end
-- Infolevel: -- Infolevel:
-- 0 for no info -- 0 for no info
-- 1 for "This area is owned by <owner> !" if you can't dig -- 1 for "This area is owned by <owner> !" if you can't dig
@ -198,7 +288,7 @@ protector.can_dig = function(r, pos, digger, onlyowner, infolevel)
-- is spawn area protected ? -- is spawn area protected ?
if inside_spawn(pos, protector_spawn) then if inside_spawn(pos, protector_spawn) then
minetest.chat_send_player(digger, show_msg(digger,
S("Spawn @1 has been protected up to a @2 block radius.", S("Spawn @1 has been protected up to a @2 block radius.",
minetest.pos_to_string(statspawn), protector_spawn)) minetest.pos_to_string(statspawn), protector_spawn))
@ -209,7 +299,7 @@ protector.can_dig = function(r, pos, digger, onlyowner, infolevel)
local pos = minetest.find_nodes_in_area( local pos = minetest.find_nodes_in_area(
{x = pos.x - r, y = pos.y - r, z = pos.z - r}, {x = pos.x - r, y = pos.y - r, z = pos.z - r},
{x = pos.x + r, y = pos.y + r, z = pos.z + r}, {x = pos.x + r, y = pos.y + r, z = pos.z + r},
{"protector:protect", "protector:protect2"}) {"protector:protect", "protector:protect2", "protector:protect_hidden"})
local meta, owner, members local meta, owner, members
@ -225,7 +315,7 @@ protector.can_dig = function(r, pos, digger, onlyowner, infolevel)
-- and you aren't on the member list -- and you aren't on the member list
if onlyowner or not is_member(meta, digger) then if onlyowner or not is_member(meta, digger) then
minetest.chat_send_player(digger, show_msg(digger,
S("This area is owned by @1", owner) .. "!") S("This area is owned by @1", owner) .. "!")
return false return false
@ -282,7 +372,11 @@ function minetest.is_protected(pos, digger)
-- hurt player if protection violated -- hurt player if protection violated
if protector_hurt > 0 and player:get_hp() > 0 then if protector_hurt > 0 and player:get_hp() > 0 then
player:set_hp(player:get_hp() - protector_hurt)
-- This delay fixes item duplication bug (thanks luk3yx)
minetest.after(0.1, function()
player:set_hp(player:get_hp() - protector_hurt)
end)
end end
-- flip player when protection violated -- flip player when protection violated
@ -356,6 +450,20 @@ local check_overlap = function(itemstack, placer, pointed_thing)
end end
-- remove protector display entities
local del_display = function(pos)
local objects = minetest.get_objects_inside_radius(pos, 0.5)
for _, v in ipairs(objects) do
if v and v:get_luaentity()
and v:get_luaentity().name == "protector:display" then
v:remove()
end
end
end
-- temporary pos store -- temporary pos store
local player_pos = {} local player_pos = {}
@ -388,8 +496,9 @@ minetest.register_node("protector:protect", {
local meta = minetest.get_meta(pos) local meta = minetest.get_meta(pos)
meta:set_string("owner", placer:get_player_name() or "") meta:set_string("owner", placer:get_player_name() or "")
meta:set_string("infotext", S("Protection (owned by @1)", meta:get_string("owner")))
meta:set_string("members", "") meta:set_string("members", "")
meta:set_string("infotext",
S("Protection (owned by @1)", meta:get_string("owner")))
end, end,
on_use = function(itemstack, user, pointed_thing) on_use = function(itemstack, user, pointed_thing)
@ -398,7 +507,8 @@ minetest.register_node("protector:protect", {
return return
end end
protector.can_dig(protector_radius, pointed_thing.under, user:get_player_name(), false, 2) protector.can_dig(protector_radius, pointed_thing.under,
user:get_player_name(), false, 2)
end, end,
on_rightclick = function(pos, node, clicker, itemstack) on_rightclick = function(pos, node, clicker, itemstack)
@ -431,23 +541,34 @@ minetest.register_node("protector:protect", {
on_blast = function() end, on_blast = function() end,
after_destruct = function(pos, oldnode) after_destruct = del_display
local objects = minetest.get_objects_inside_radius(pos, 0.5)
for _, v in ipairs(objects) do
v:remove()
end
end,
}) })
minetest.register_craft({ -- default recipe and alternative for MineClone2
output = "protector:protect", if protector_recipe then
recipe = {
{"default:stone", "default:stone", "default:stone"},
{"default:stone", "default:gold_ingot", "default:stone"},
{"default:stone", "default:stone", "default:stone"},
}
})
if minetest.registered_items["default:stone"] then
minetest.register_craft({
output = "protector:protect",
recipe = {
{"default:stone", "default:stone", "default:stone"},
{"default:stone", "default:gold_ingot", "default:stone"},
{"default:stone", "default:stone", "default:stone"},
}
})
else
minetest.register_craft({
output = "protector:protect",
recipe = {
{"mcl_core:stone", "mcl_core:stone", "mcl_core:stone"},
{"mcl_core:stone", "mcl_core:gold_ingot", "mcl_core:stone"},
{"mcl_core:stone", "mcl_core:stone", "mcl_core:stone"},
}
})
end
end
-- protection logo -- protection logo
minetest.register_node("protector:protect2", { minetest.register_node("protector:protect2", {
@ -457,6 +578,7 @@ minetest.register_node("protector:protect2", {
inventory_image = "protector_logo.png", inventory_image = "protector_logo.png",
sounds = default.node_sound_stone_defaults(), sounds = default.node_sound_stone_defaults(),
groups = {dig_immediate = 2, unbreakable = 1}, groups = {dig_immediate = 2, unbreakable = 1},
use_texture_alpha = "clip",
paramtype = "light", paramtype = "light",
paramtype2 = "wallmounted", paramtype2 = "wallmounted",
legacy_wallmounted = true, legacy_wallmounted = true,
@ -479,8 +601,9 @@ minetest.register_node("protector:protect2", {
local meta = minetest.get_meta(pos) local meta = minetest.get_meta(pos)
meta:set_string("owner", placer:get_player_name() or "") meta:set_string("owner", placer:get_player_name() or "")
meta:set_string("infotext", S("Protection (owned by @1)", meta:get_string("owner")))
meta:set_string("members", "") meta:set_string("members", "")
meta:set_string("infotext",
S("Protection (owned by @1)", meta:get_string("owner")))
end, end,
on_use = function(itemstack, user, pointed_thing) on_use = function(itemstack, user, pointed_thing)
@ -489,7 +612,8 @@ minetest.register_node("protector:protect2", {
return return
end end
protector.can_dig(protector_radius, pointed_thing.under, user:get_player_name(), false, 2) protector.can_dig(protector_radius, pointed_thing.under,
user:get_player_name(), false, 2)
end, end,
on_rightclick = function(pos, node, clicker, itemstack) on_rightclick = function(pos, node, clicker, itemstack)
@ -522,12 +646,7 @@ minetest.register_node("protector:protect2", {
on_blast = function() end, on_blast = function() end,
after_destruct = function(pos, oldnode) after_destruct = del_display
local objects = minetest.get_objects_inside_radius(pos, 0.5)
for _, v in ipairs(objects) do
v:remove()
end
end,
}) })
-- recipes to switch between protectors -- recipes to switch between protectors
@ -587,6 +706,11 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
return return
end end
-- add faction members
if factions_available then
meta:set_int("faction_members", fields.faction_members == "true" and 1 or 0)
end
-- add member [+] -- add member [+]
if add_member_input then if add_member_input then
@ -616,16 +740,17 @@ minetest.register_entity("protector:display", {
collisionbox = {0, 0, 0, 0, 0, 0}, collisionbox = {0, 0, 0, 0, 0, 0},
visual = "wielditem", visual = "wielditem",
-- wielditem seems to be scaled to 1.5 times original node size -- wielditem seems to be scaled to 1.5 times original node size
visual_size = {x = 1.0 / 1.5, y = 1.0 / 1.5}, visual_size = {x = 0.67, y = 0.67},
textures = {"protector:display_node"}, textures = {"protector:display_node"},
timer = 0, timer = 0,
glow = 10,
on_step = function(self, dtime) on_step = function(self, dtime)
self.timer = self.timer + dtime self.timer = self.timer + dtime
-- remove after 5 seconds -- remove after set number of seconds
if self.timer > 5 then if self.timer > protector_show then
self.object:remove() self.object:remove()
end end
end, end,
@ -638,7 +763,7 @@ minetest.register_entity("protector:display", {
local x = protector_radius local x = protector_radius
minetest.register_node("protector:display_node", { minetest.register_node("protector:display_node", {
tiles = {"protector_display.png"}, tiles = {"protector_display.png"},
use_texture_alpha = true, use_texture_alpha = "clip", -- true,
walkable = false, walkable = false,
drawtype = "nodebox", drawtype = "nodebox",
node_box = { node_box = {

View File

@ -19,10 +19,8 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
#: admin.lua #: admin.lua
#, fuzzy
msgid "Remove Protectors around players (separate names with spaces)" msgid "Remove Protectors around players (separate names with spaces)"
msgstr "" msgstr "Entferne Störschützer von bestimmten Namen in der Nähe von Spielern (trenne "
"Entferne Störschützer von bestimmten Namen in der Nähe von Spielern (trenne "
"Namen durch Leerzeichen)" "Namen durch Leerzeichen)"
#: admin.lua #: admin.lua
@ -73,18 +71,6 @@ msgstr "Geschützte Stahlfalltür"
msgid "Protected Chest" msgid "Protected Chest"
msgstr "Geschützte Truhe" msgstr "Geschützte Truhe"
#: doors_chest.lua
msgid "@1 moves stuff to protected chest at @2"
msgstr "@1 verlagert Dinge in geschützte Truhe bei @2"
#: doors_chest.lua
msgid "@1 takes stuff from protected chest at @2"
msgstr "@1 nimmt Dinge aus geschützter Truhe bei @2"
#: doors_chest.lua
msgid "@1 moves stuff inside protected chest at @2"
msgstr "@1 verschiebt Dinge innerhalb der geschützten Truhe bei @2"
#: doors_chest.lua #: doors_chest.lua
msgid "To Chest" msgid "To Chest"
msgstr "Zur Truhe" msgstr "Zur Truhe"

177
protector/locale/es.po Normal file
View File

@ -0,0 +1,177 @@
# Spanish translation for PROTECTOR MOD.
# Copyright (C) 2018 universales
# This file is distributed under the same license as the PROTECTOR MOD package.
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PROTECTOR MOD\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2018-07-10 17:33+0200\n"
"PO-Revision-Date: 2020-02-27\n"
"Last-Translator: Universales\n"
"Language-Team: \n"
"Language: es\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
#: admin.lua
msgid "Remove Protectors around players (separate names with spaces)"
msgstr "Eliminar protectores alrededor de los jugadores (nombres separados con espacios)"
#: admin.lua
msgid "<names list>"
msgstr "<Lista de nombres>"
#: admin.lua
msgid "Replace Protector Owner with name provided"
msgstr "Reemplace el propietario del protector con el nombre proporcionado"
#: admin.lua
msgid "<owner name> <name to replace with>"
msgstr "<Nombre del propietario> <Nombre del nuevo propietario>"
#: admin.lua
msgid "Replacing Protector name '@1' with '@2'"
msgstr "Reemplazando el nombre del protector '@1' a '@2'"
#: admin.lua
msgid "Show protected areas of your nearby protectors"
msgstr "Mostrar áreas protegidas de sus protectores cercanos"
#: admin.lua
msgid "Protector Names to remove: @1"
msgstr "Nombres de protectores para eliminar: @1"
#: admin.lua
msgid "Name List Reset"
msgstr "Restablecer lista de nombres"
#: doors_chest.lua
msgid "Protected Wooden Door"
msgstr "Puerta de madera protegida"
#: doors_chest.lua
msgid "Protected Steel Door"
msgstr "Puerta de hierro protegida"
#: doors_chest.lua
msgid "Protected Trapdoor"
msgstr "Trampilla Protegida"
#: doors_chest.lua
msgid "Protected Steel Trapdoor"
msgstr "Trampilla de hierro protegida"
#: doors_chest.lua
msgid "Protected Chest"
msgstr "Cofre protegido"
#: doors_chest.lua
msgid "To Chest"
msgstr "Al cofre"
#: doors_chest.lua
msgid "To Inventory"
msgstr "Al inventario"
#: doors_chest.lua
msgid "Protected Chest (@1)"
msgstr "Cofre protegido (@1)"
#: init.lua
msgid "-- Protector interface --"
msgstr "-- Interfaz del protector --"
#: init.lua
msgid "PUNCH node to show protected area"
msgstr "nodo de perforación para mostrar el área protegida"
#: init.lua
msgid "USE for area check"
msgstr "Usar para chequeo del área"
#: init.lua
msgid "Members:"
msgstr "Miembros:"
#: init.lua
msgid "Close"
msgstr "Cerrar"
#: init.lua
msgid "Protection located at: @1"
msgstr "Protección ubicada en: @1"
#: init.lua
msgid "Members: @1."
msgstr "Miembros: @1."
#: init.lua
msgid "This area is not protected."
msgstr "Esta área no está protegida."
#: init.lua
msgid "You can build here."
msgstr "Puedes construir aquí."
#: init.lua tool.lua
msgid "Overlaps into above players protected area"
msgstr "Se superpone en el área protegida de los jugadores anteriores"
#: init.lua
msgid "Protection Block"
msgstr "Bloque de protección"
#: admin.lua init.lua tool.lua
msgid "Protection (owned by @1)"
msgstr "Protegido (Propiedad de @1)"
#: init.lua
msgid "Protection Logo"
msgstr "Logotipo de la protección"
#: init.lua
msgid "[MOD] Protector Redo loaded"
msgstr "[MOD] Protector recargado"
#: init.lua
msgid "Spawn @1 has been protected up to a @2 block radius."
msgstr "Spawn @1 ha sido protegido hasta un radio de bloque @2."
#: init.lua
msgid "This area is owned by @1"
msgstr "Esta área es propiedad de @1"
#: pvp.lua
msgid "[Protector] on_punchplayer called with nil objects"
msgstr "[Protector] on_punchplayer llamado con objetos nulos."
#: pvp.lua
msgid "[Protector] pvp_protect not active, update your version of Minetest"
msgstr "[Protector] pvp_protect no está activo, actualiza tu versión de Minetest"
#: pvp.lua
msgid "[Protector] pvp_protect is disabled"
msgstr "[Protector] pvp_protect está deshabilitado"
#: hud.lua
msgid "Owner: @1"
msgstr "Propietario: @1"
#: tool.lua
msgid "Protector Placer Tool (stand near protector, face direction and use)"
msgstr ""
"Herramienta de colocación del protector (pararse cerca del protector, dirección de la cara y uso) "
#: tool.lua
msgid "Protector already in place!"
msgstr "¡El protector ya está en este lugar!"
#: tool.lua
msgid "No protectors available to place!"
msgstr "¡No hay protectores disponibles para colocar!"
#: tool.lua
msgid "Protector placed at @1"
msgstr "Protector colocado en @1"

View File

@ -19,10 +19,8 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
#: admin.lua #: admin.lua
#, fuzzy
msgid "Remove Protectors around players (separate names with spaces)" msgid "Remove Protectors around players (separate names with spaces)"
msgstr "" msgstr "Retirer les protecteurs près des joueurs avec les noms fournis (noms séparés "
"Retirer les protecteurs près des joueurs avec les noms fournis (noms séparés "
"avec des espaces)" "avec des espaces)"
#: admin.lua #: admin.lua
@ -73,19 +71,6 @@ msgstr "Trap en acier protégé"
msgid "Protected Chest" msgid "Protected Chest"
msgstr "Coffre protégé" msgstr "Coffre protégé"
#: doors_chest.lua
msgid "@1 moves stuff to protected chest at @2"
msgstr "@1 déplace des objets vers le coffre protégée à @2"
#: doors_chest.lua
msgid "@1 takes stuff from protected chest at @2"
msgstr "@1 prend des objets du coffre protégée à @2"
#: doors_chest.lua
#, fuzzy
msgid "@1 moves stuff inside protected chest at @2"
msgstr "@1 déplace des objets à l'intérieur de du coffre protégé à @2"
#: doors_chest.lua #: doors_chest.lua
msgid "To Chest" msgid "To Chest"
msgstr "Vers le coffre" msgstr "Vers le coffre"

180
protector/locale/it.po Normal file
View File

@ -0,0 +1,180 @@
# Italian translation for PROTECTOR MOD.
# Copyright (C) 2020 Hamlet
# This file is distributed under the same license as the PROTECTOR MOD package.
# Xanthin <xanthin@wiuwiu.de>, 2016.
# CodeXP <codexp@gmx.net>, 2018.
#
msgid ""
msgstr ""
"Project-Id-Version: PROTECTOR MOD\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2018-07-10 17:33+0200\n"
"PO-Revision-Date: \n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: Poedit 2.2.1\n"
"Last-Translator: Hamlet <hamlatgitlab@riseup.net>\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"Language: it\n"
#: admin.lua
msgid "Remove Protectors around players (separate names with spaces)"
msgstr "Elimina i protettori attorno ai giocatori (separa i nomi con gli spazi)"
#: admin.lua
msgid "<names list>"
msgstr "<elenco nomi>"
#: admin.lua
msgid "Replace Protector Owner with name provided"
msgstr "Sostituisci il proprietario del protettore col nome fornito"
#: admin.lua
msgid "<owner name> <name to replace with>"
msgstr "<nome proprietario> <nome con cui sostituirlo>"
#: admin.lua
msgid "Replacing Protector name '@1' with '@2'"
msgstr "Sostituzione del nome del protettore '@1' con '@2'"
#: admin.lua
msgid "Show protected areas of your nearby protectors"
msgstr "Mostra le aree protette dei protettori vicino a te"
#: admin.lua
msgid "Protector Names to remove: @1"
msgstr "Nomi dei protettori da eliminare: @1"
#: admin.lua
msgid "Name List Reset"
msgstr "Azzera l'elenco dei nomi"
#: doors_chest.lua
msgid "Protected Wooden Door"
msgstr "Porta di legno protetta"
#: doors_chest.lua
msgid "Protected Steel Door"
msgstr "Porta d'acciaio protetta"
#: doors_chest.lua
msgid "Protected Trapdoor"
msgstr "Botola protetta"
#: doors_chest.lua
msgid "Protected Steel Trapdoor"
msgstr "Botola d'acciaio protetta"
#: doors_chest.lua
msgid "Protected Chest"
msgstr "Baule protetto"
#: doors_chest.lua
msgid "To Chest"
msgstr "Al baule"
#: doors_chest.lua
msgid "To Inventory"
msgstr "All'inventario"
#: doors_chest.lua
msgid "Protected Chest (@1)"
msgstr "Baule protetto (@1)"
#: init.lua
msgid "-- Protector interface --"
msgstr "-- Interfaccia protettore --"
#: init.lua
msgid "PUNCH node to show protected area"
msgstr "COLPISCI il nodo per mostrare l'area protetta"
#: init.lua
msgid "USE for area check"
msgstr "USA per controllare l'area"
#: init.lua
msgid "Members:"
msgstr "Membri:"
#: init.lua
msgid "Close"
msgstr "Chiudi"
#: init.lua
msgid "Protection located at: @1"
msgstr "Protezione collocata a: @1"
#: init.lua
msgid "Members: @1."
msgstr "Membri: @1."
#: init.lua
msgid "This area is not protected."
msgstr "Quest'area non è protetta."
#: init.lua
msgid "You can build here."
msgstr "Qui puoi costruire."
#: init.lua tool.lua
msgid "Overlaps into above players protected area"
msgstr "Si sovrappone ad un'area sovrastante protetta dai giocatori"
#: init.lua
msgid "Protection Block"
msgstr "Blocco di protezione"
#: admin.lua init.lua tool.lua
msgid "Protection (owned by @1)"
msgstr "Protezione (di proprietà di @1)"
#: init.lua
msgid "Protection Logo"
msgstr "Logo di protezione"
#: init.lua
msgid "[MOD] Protector Redo loaded"
msgstr "[MOD] Protector Redo caricato"
#: init.lua
msgid "Spawn @1 has been protected up to a @2 block radius."
msgstr "Lo spawn @1 è stato protetto fino a un raggio di @2 blocchi."
#: init.lua
msgid "This area is owned by @1"
msgstr "Quest'area è di proprietà di @1"
#: pvp.lua
msgid "[Protector] on_punchplayer called with nil objects"
msgstr "[Protector] on_punchplayer chiamato con oggetti nil"
#: pvp.lua
msgid "[Protector] pvp_protect not active, update your version of Minetest"
msgstr "[Protector] pvp_protect non attiva, aggiorna la tua versione di Minetest"
#: pvp.lua
msgid "[Protector] pvp_protect is disabled"
msgstr "[Protector] pvp_protect è disattivato"
#: hud.lua
msgid "Owner: @1"
msgstr "Proprietario: @1"
#: tool.lua
msgid "Protector Placer Tool (stand near protector, face direction and use)"
msgstr "Strumento di posizionamento protettore (stai vicino al protettore, guarda la direzione e usa)"
#: tool.lua
msgid "Protector already in place!"
msgstr "Protettore già presente!"
#: tool.lua
msgid "No protectors available to place!"
msgstr "Nessun protettore disponibile da posizionare!"
#: tool.lua
msgid "Protector placed at @1"
msgstr "Protettore posizionato a @1"

View File

@ -0,0 +1,55 @@
# textdomain: protector
# author: Xanthin and CodeXP
# last update: 2020/Jul/12
### admin.lua ###
Remove Protectors around players (separate names with spaces)=Entferne Störschützer von bestimmten Namen in der Nähe von Spielern (trenne Namen durch Leerzeichen)
<names list>=<Namensliste der Spieler>
Replace Protector Owner with name provided=Ersetze Besitzer der Störschützer mit neuem Besitzer
<owner name> <name to replace with>=<Name des Besitzers> <Name des neuen Besitzers>
Replacing Protector name '@1' with '@2'=Ersetze Besitzer der Störschützer von '@1' mit '@2'
Show protected areas of your nearby protectors=Zeige geschützte Bereiche der Störschützer in der Nähe
Protector Names to remove: @1=Störschutznamen zum Entfernen: @1
Name List Reset=Namensliste zurückgesetzt
### doors_chest.lua ###
Protected Wooden Door=Geschützte Holztür
Protected Steel Door=Geschützte Stahltür
Protected Trapdoor=Geschützte Falltür
Protected Steel Trapdoor=Geschützte Stahlfalltür
Protected Chest=Geschützte Truhe
To Chest=Zur Truhe
To Inventory=Zum Inventar
Protected Chest (@1)=Geschützte Truhe (@1)
### init.lua ###
-- Protector interface --=-- Störschutz-Interface --
PUNCH node to show protected area=SCHLAGE Node, um geschützten Bereich anzuzeigen oder
USE for area check=BENUTZE für Bereichsprüfung
Members:=Mitglieder:
Close=Schließen
Protection located at: @1=Störschutz befindet sich bei: @1
Members: @1.=Mitglieder: @1.
This area is not protected.=Dieser Bereich ist nicht geschützt.
You can build here.=Du kannst hier bauen.
Overlaps into above players protected area=Überlappung im geschützen Bereich eines Spielers
Protection Block=Störschutzblock
Protection (owned by @1)=Störschutz (gehört @1)
Protection Logo=Störschutzlogo
[MOD] Protector Redo loaded=[MOD] Protector Redo geladen
Spawn @1 has been protected up to a @2 block radius.=Spawn @1 ist geschützt mit einem Radius von @2 Blöcke.
This area is owned by @1=Dieser Bereich gehört @1
### pvp.lua ###
[Protector] on_punchplayer called with nil objects=on_punchplayer wurde durch \"nil objects\" aufgerufen
[Protector] pvp_protect not active, update your version of Minetest=pvp_protect ist nicht aktiv, aktualisiere deine Minetestversion
[Protector] pvp_protect is disabled=pvp_protect ist ausgeschaltet
### hud.lua ###
Owner: @1=Besitzer: @1
### tool.lua ###
Protector Placer Tool (stand near protector, face direction and use)=Störschutz Platzier-Werkzeug (stehe neben Störschutz, schaue in die gewünschte Richtung und anwenden)
Protector already in place!=Störschutz is bereits platziert!
No protectors available to place!=Keine Störschützer mehr im Inventar!
"Protector placed at @1"=Störschutz befindet sich bei: @1

View File

@ -0,0 +1,55 @@
# textdomain: protector
# author: universales
# last update: 2020-02-27
### admin.lua ###
Remove Protectors around players (separate names with spaces)=Eliminar protectores alrededor de los jugadores (nombres separados con espacios)
<names list>=<Lista de nombres>
Replace Protector Owner with name provided=Reemplace el propietario del protector con el nombre proporcionado
<owner name> <name to replace with>=<Nombre del propietario> <Nombre del nuevo propietario>
Replacing Protector name '@1' with '@2'=Reemplazando el nombre del protector '@1' a '@2'
Show protected areas of your nearby protectors=Mostrar áreas protegidas de sus protectores cercanos
Protector Names to remove: @1=Nombres de protectores para eliminar: @1
Name List Reset=Restablecer lista de nombres
### doors_chest.lua ###
Protected Wooden Door=Puerta de madera protegida
Protected Steel Door=Puerta de hierro protegida
Protected Trapdoor=Trampilla Protegida
Protected Steel Trapdoor=Trampilla de hierro protegida
Protected Chest=Cofre protegido
To Chest=Al cofre
To Inventory=Al inventario
Protected Chest (@1)=Cofre protegido (@1)
### init.lua ###
-- Protector interface --=-- Interfaz del protector --
PUNCH node to show protected area=nodo de perforación para mostrar el área protegida
USE for area check=Usar para chequeo del área
Members:=Miembros:
Close=Cerrar
Protection located at: @1=Protección ubicada en: @1
Members: @1.=Miembros: @1.
This area is not protected.=Esta área no está protegida.
You can build here.=Puedes construir aquí.
Overlaps into above players protected area=Se superpone en el área protegida de los jugadores anteriores
Protection Block=Bloque de protección
Protection (owned by @1)=Protegido (Propiedad de @1)
Protection Logo=Logotipo de la protección
[MOD] Protector Redo loaded=[MOD] Protector recargado
Spawn @1 has been protected up to a @2 block radius.=Spawn @1 ha sido protegido hasta un radio de bloque @2.
This area is owned by @1=Esta área es propiedad de @1
### pvp.lua ###
[Protector] on_punchplayer called with nil objects=[Protector] on_punchplayer llamado con objetos nulos.
[Protector] pvp_protect not active, update your version of Minetest=[Protector] pvp_protect no está activo, actualiza tu versión de Minetest
[Protector] pvp_protect is disabled=[Protector] pvp_protect está deshabilitado
### hud.lua ###
Owner: @1=Propietario: @1
### tool.lua ###
Protector Placer Tool (stand near protector, face direction and use)=Herramienta de colocación del protector (pararse cerca del protector, dirección de la cara y uso)
Protector already in place!=¡El protector ya está en este lugar!
No protectors available to place!=¡No hay protectores disponibles para colocar!
Protector placed at @1=Protector colocado en @1

View File

@ -0,0 +1,55 @@
# textdomain: protector
# author: CodeXP and TenPlus1
# last update: 2020/Jul/12
### admin.lua ###
Remove Protectors around players (separate names with spaces)=Retirer les protecteurs près des joueurs avec les noms fournis (noms séparés avec des espaces)
<names list>=<liste de noms>
Replace Protector Owner with name provided=Remplacer le propriétaire du protecteur par le nom fourni
<owner name> <name to replace with>=<nom du propriétaire> <nom à remplacer>
Replacing Protector name '@1' with '@2'=
Show protected areas of your nearby protectors=Affichez les zones protégées de vos protecteurs à proximité
Protector Names to remove: @1=Noms de protecteurs à supprimer: @1
Name List Reset=Liste de noms réinitialiser
### doors_chest.lua ###
Protected Wooden Door=Porte en bois protégée
Protected Steel Door=Porte en acier protégée
Protected Trapdoor=Trappe protégé
Protected Steel Trapdoor=Trap en acier protégé
Protected Chest=Coffre protégé
To Chest=Vers le coffre
To Inventory=Vers l'inventaire
Protected Chest (@1)=Coffre protégé (@1)
### init.lua ###
-- Protector interface --=-- Interface Protector --
PUNCH node to show protected area=TAPÉ le bloc pour afficher la zone protégée
USE for area check=UTILISER pour vérifier la zone
Members:=Membres:
Close=Fermer
Protection located at: @1=Protection située à: @1
Members: @1.=Membres: @1.
This area is not protected.=msgstr "Cette zone n'est pas protégée.
You can build here.=Vous pouvez construire ici.
Overlaps into above players protected area=Vous chevauché une zone protégé.
Protection Block=Bloc de protection
Protection (owned by @1)=Protection (détenue par @1)
Protection Logo=Logo de protection
[MOD] Protector Redo loaded=[MOD] Protector Redo chargé
Spawn @1 has been protected up to a @2 block radius.=
This area is owned by @1=Cette zone appartient à @1!
### pvp.lua ###
[Protector] on_punchplayer called with nil objects=[Protector] on_punchplayer appelé avec des objets nil
[Protector] pvp_protect not active, update your version of Minetest=[Protector] pvp_protect est désactivé, mettez à jour votre version de Minetest
[Protector] pvp_protect is disabled=[Protector] pvp_protect est désactivé
### hud.lua ###
Owner: @1=Propriétaire: @1
### tool.lua ###
Protector Placer Tool (stand near protector, face direction and use)=Outil de placement du protecteur (se tenir près du protecteur, direction du visage et utilisation)
Protector already in place!=Protecteur déjà en place!
No protectors available to place!=Aucun protecteur disponible à placer!
Protector placed at @1=Protection située à: @1

View File

@ -0,0 +1,55 @@
# textdomain: protector
# author: Xanthin and CodeXP
# last update: 2018/Jul/10
### admin.lua ###
Remove Protectors around players (separate names with spaces)=Elimina i protettori attorno ai giocatori (separa i nomi con gli spazi)
<names list>=<elenco nomi>
Replace Protector Owner with name provided=Sostituisci il proprietario del protettore col nome fornito
<owner name> <name to replace with>=<nome proprietario> <nome con cui sostituirlo>
Replacing Protector name '@1' with '@2'=Sostituzione del nome del protettore '@1' con '@2'
Show protected areas of your nearby protectors=Mostra le aree protette dei protettori vicino a te
Protector Names to remove: @1=Nomi dei protettori da eliminare: @1
Name List Reset=Azzera l'elenco dei nomi
### doors_chest.lua ###
Protected Wooden Door=Porta di legno protetta
Protected Steel Door=Porta d'acciaio protetta
Protected Trapdoor=Botola protetta
Protected Steel Trapdoor=Botola d'acciaio protetta
Protected Chest=Baule protetto
To Chest=Al baule
To Inventory=All'inventario
Protected Chest (@1)=Baule protetto (@1)
### init.lua ###
-- Protector interface --=-- Interfaccia protettore --
PUNCH node to show protected area=COLPISCI il nodo per mostrare l'area protetta
USE for area check=USA per controllare l'area
Members:=Membri:
Close=Chiudi
Protection located at: @1=Protezione collocata a: @1
Members: @1.=Membri: @1.
This area is not protected.=Quest'area non è protetta.
You can build here.=Qui puoi costruire.
Overlaps into above players protected area=Si sovrappone ad un'area sovrastante protetta dai giocatori
Protection Block=Blocco di protezione
Protection (owned by @1)=Protezione (di proprietà di @1)
Protection Logo=Logo di protezione
[MOD] Protector Redo loaded=[MOD] Protector Redo caricato
Spawn @1 has been protected up to a @2 block radius.=Lo spawn @1 è stato protetto fino a un raggio di @2 blocchi.
This area is owned by @1=Quest'area è di proprietà di @1
### pvp.lua ###
[Protector] on_punchplayer called with nil objects=[Protector] on_punchplayer chiamato con oggetti nil
[Protector] pvp_protect not active, update your version of Minetest=[Protector] pvp_protect non attiva, aggiorna la tua versione di Minetest
[Protector] pvp_protect is disabled=[Protector] pvp_protect è disattivato
### hud.lua ###
Owner: @1=Proprietario: @1
### tool.lua ###
Protector Placer Tool (stand near protector, face direction and use)=Strumento di posizionamento protettore (stai vicino al protettore, guarda la direzione e usa)
Protector already in place!=Protettore già presente!
No protectors available to place!=Nessun protettore disponibile da posizionare!
Protector placed at @1=Protettore posizionato a @1

View File

@ -0,0 +1,55 @@
# textdomain: protector
# author: CodeXP
# last update: 2018/Jul/10
### admin.lua ###
Remove Protectors around players (separate names with spaces)=Удалить защиту рядом с игроками (перечислить имена, разделяя пробелами)
<names list>=<список имён>
Replace Protector Owner with name provided=Заменить владельца защиты новым владельцем
<owner name> <name to replace with>=<имя владельца> <имя нового владельца>
Replacing Protector name '@1' with '@2'=Заменяется владелец защиты с '@1' на '@2'
Show protected areas of your nearby protectors=Показать ближайшие защищённые территории
Protector Names to remove: @1=Имена, подлежащие удалению: @1
Name List Reset=Очистить список имён
### doors_chest.lua ###
Protected Wooden Door=Защищённая яблоневая дверь
Protected Steel Door=Защищённая стальная дверь
Protected Trapdoor=Защищённый яблоневый люк
Protected Steel Trapdoor=Защищённый стальной люк
Protected Chest=Защищённый сундук
To Chest=В сундук
To Inventory=В инвентрарь
Protected Chest (@1)=Защищённый сундук (@1)
### init.lua ###
-- Protector interface --=-- Настройка защиты --
PUNCH node to show protected area=СТУКНУТЬ узел для подсветки защищённой территории
USE for area check=ЛКМ для проверки защищённой территории
Members:=Участники:
Close=Закрыть
Protection located at: @1=Защита находится на координатах @1
Members: @1.=Участники: @1.
This area is not protected.=Территория свободна.
You can build here.=Здесь можно ставить блоки.
Overlaps into above players protected area=Защитный блок не может быть установлен: пересечение с областями, защищёнными другими игроками
Protection Block=Защитный блок
Protection (owned by @1)=Защита игрока @1
Protection Logo=Защитный знак
[MOD] Protector Redo loaded=[МОД] Protector Redo загружен
Spawn @1 has been protected up to a @2 block radius.=Спаун @1 защищён в радиусе @2 блока.
This area is owned by @1=Эта территория пренадлежит @1
### pvp.lua ###
[Protector] on_punchplayer called with nil objects=[Защита] on_punchplayer вызвана с нулевыми объектами
[Protector] pvp_protect not active, update your version of Minetest=[Защита] pvp_protect неактивен, обновите версию Minetest
[Protector] pvp_protect is disabled=[Защита] pvp_protect отключён
### hud.lua ###
Owner: @1=Владелец: @1
### tool.lua ###
Protector Placer Tool (stand near protector, face direction and use)=Инструмент установки защиты (встаньте рядом с защитой, повернитесь в нужном направлении и используйте)
Protector already in place!=Защита уже установлена!
No protectors available to place!=У вас нет защитных блоков в инвентаре!
Protector placed at @1=Защита находится на координатах @1

View File

@ -0,0 +1,55 @@
# textdomain: protector
# author: CodeXP and TenPlus1
# last update: 2020/Jul/12
### admin.lua ###
Remove Protectors around players (separate names with spaces)=Ismi verilen oyuncuların yanındaki korumaları kaldır. (İsimleri boşlukla ayır)
<names list>=<isim listesi>
Replace Protector Owner with name provided=Koruyucu Sahibini belirtilen adla değiştirin
<owner name> <name to replace with>=<sahip adı> <değiştirilecek ad>
Replacing Protector name '@1' with '@2'='@ 1' Koruyucu adını '@ 2' ile değiştirin
Show protected areas of your nearby protectors=Yakındaki koruyucuların korunan alanlarını göster
Protector Names to remove: @1=Silinecek korumaların isimleri: @1
Name List Reset=İsim listesini sıfırla
### doors_chest.lua ###
Protected Wooden Door=Korumalı ahşap kapı
Protected Steel Door=Korumalı çelik kapı
Protected Trapdoor=Korumalı tuzak kapısı
Protected Steel Trapdoor=Korumalı çelik tuzak kapısı
Protected Chest=Korumalı sandık
To Chest=Sandığa
To Inventory=Envantere
Protected Chest (@1)=Korumalı sandık (@1)
### init.lua ###
-- Protector interface --=-- Koruyucu arayüz --
PUNCH node to show protected area=Korunan alanı göstermek için yumruk
USE for area check=Bölge kontrolü için kullan
Members:=Üyeler
Close=Kapat
Protection located at: @1=Korumanın bulunduğu yer @1
Members: @1.=Üyeler @1.
This area is not protected.=Bu alan korumalı değildir.
You can build here.=Buraya inşaa edebilirsiniz.
Overlaps into above players protected area=Yukarıdaki oyuncuların koruma alanı ile çakışıyor
Protection Block=Koruma kutusu
Protection (owned by @1)=Koruma (@1 sahibidir)
Protection Logo=Koruma arması
[MOD] Protector Redo loaded=[MOD] Protector Redo yüklendi
Spawn @1 has been protected up to a @2 block radius.=Spawn @1, @2 blok yarıçapa kadar korunur.
This area is owned by @1=Burasının sahibi @1!
### pvp.lua ###
[Protector] on_punchplayer called with nil objects=[Protector] on_punchplayer boş objelerle çağrıldı
[Protector] pvp_protect not active, update your version of Minetest=[Protector] pvp_protect aktif değil, Minetest sürümünüzü güncelleyin.
[Protector] pvp_protect is disabled=[Protector] pvp_protect kapatıldı.
### hud.lua ###
Owner: @1=Sahip: @1
### tool.lua ###
Protector Placer Tool (stand near protector, face direction and use)=Koruyucu Yerleştirme Aleti (koruyucunun yanında durun, yüz yönü ve kullanım)
Protector already in place!=Koruyucu zaten yerinde!
No protectors available to place!=Yerleştirilecek koruyucu yok!
Protector placed at @1=Korumanın bulunduğu yer @1

View File

@ -19,10 +19,8 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
#: admin.lua #: admin.lua
#, fuzzy
msgid "Remove Protectors around players (separate names with spaces)" msgid "Remove Protectors around players (separate names with spaces)"
msgstr "" msgstr "Удалить защиту рядом с игроками (перечислить имена, разделяя пробелами)"
"Удалить защиту рядом с игроками (перечислить имена, разделяя пробелами)"
#: admin.lua #: admin.lua
msgid "<names list>" msgid "<names list>"
@ -72,18 +70,6 @@ msgstr "Защищенный стальной люк"
msgid "Protected Chest" msgid "Protected Chest"
msgstr "Защищенный сундук" msgstr "Защищенный сундук"
#: doors_chest.lua
msgid "@1 moves stuff to protected chest at @2"
msgstr "@1 перемещает вещи в защищенный сундук на координатах @2"
#: doors_chest.lua
msgid "@1 takes stuff from protected chest at @2"
msgstr "@1 берет вещи из защищенного сундука на координатах @2"
#: doors_chest.lua
msgid "@1 moves stuff inside protected chest at @2"
msgstr "@1 перемещает вещи внутри защищенного сундука на координатах @2"
#: doors_chest.lua #: doors_chest.lua
msgid "To Chest" msgid "To Chest"
msgstr "В сундук" msgstr "В сундук"

View File

@ -70,18 +70,6 @@ msgstr ""
msgid "Protected Chest" msgid "Protected Chest"
msgstr "" msgstr ""
#: doors_chest.lua
msgid "@1 moves stuff to protected chest at @2"
msgstr ""
#: doors_chest.lua
msgid "@1 takes stuff from protected chest at @2"
msgstr ""
#: doors_chest.lua
msgid "@1 moves stuff inside protected chest at @2"
msgstr ""
#: doors_chest.lua #: doors_chest.lua
msgid "To Chest" msgid "To Chest"
msgstr "" msgstr ""

View File

@ -19,10 +19,8 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
#: admin.lua #: admin.lua
#, fuzzy
msgid "Remove Protectors around players (separate names with spaces)" msgid "Remove Protectors around players (separate names with spaces)"
msgstr "" msgstr "Ismi verilen oyuncuların yanındaki korumaları kaldır. (İsimleri boşlukla "
"Ismi verilen oyuncuların yanındaki korumaları kaldır. (İsimleri boşlukla "
"ayır)" "ayır)"
#: admin.lua #: admin.lua
@ -73,19 +71,6 @@ msgstr "Korumalı çelik tuzak kapısı"
msgid "Protected Chest" msgid "Protected Chest"
msgstr "Korumalı sandık" msgstr "Korumalı sandık"
#: doors_chest.lua
msgid "@1 moves stuff to protected chest at @2"
msgstr "@1 korumalı sandığa birşeyler koydu @2"
#: doors_chest.lua
msgid "@1 takes stuff from protected chest at @2"
msgstr "@1 korumalı sandıktan birşeyler aldı @2"
#: doors_chest.lua
#, fuzzy
msgid "@1 moves stuff inside protected chest at @2"
msgstr "@1 korumalı sandığa içinde bir şeyler taşındı @2"
#: doors_chest.lua #: doors_chest.lua
msgid "To Chest" msgid "To Chest"
msgstr "Sandığa" msgstr "Sandığa"

View File

@ -1 +1,3 @@
name = protector name = protector
description = Lets players craft special blocks to protect their builds or disable PVP in areas.
optional_depends = default, intllib, lucky_block, mesecons_mvps, playerfactions

View File

@ -0,0 +1,32 @@
# Size of protected area around protection node limiting player interaction
protector_radius (Protector Radius [max 22]) int 5
# Flips player around when accessing protected area to stop lag griefing
protector_flip (Protector Flip) bool false
# Hurts player by amount entered when accessing protected area, 0 to disable
protector_hurt (Protector Hurt) int 0
# Sets a protected area around spawn by node radius given
protector_spawn (Protector Spawn) int 0
# Enables PVP inside of protected areas
protector_pvp (Protector PVP) bool false
# When true will allow PVP inside protected spawn area
protector_pvp_spawn (Protector PVP Spawn) int 0
# When true will allow PVP inside all protected areas at night time only
protector_night_pvp (Protector Night PVP) bool false
# Interval in seconds that protection field is shown
protector_show_interval (Protector Show Interval) int 5
# Interval in seconds that HUD ownership text is updated, 0 to disable
protector_hud_interval (Protector HUD Interval) int 5
# Enables craft recipe for protection block
protector_recipe (Enable Protector recipe) bool true
# Enables protection messages in player chat
protector_msg (Enable Protector Messages) bool true

View File

@ -1,135 +1,164 @@
-- protector placement tool (thanks to Shara for code and idea) -- protector placement tool (thanks to Shara for code and idea)
-- get protection radius local S = protector.intllib
local r = tonumber(minetest.settings:get("protector_radius")) or 5
-- get protection radius
minetest.register_craftitem("protector:tool", { local r = tonumber(minetest.settings:get("protector_radius")) or 5
description = "Protector Placer Tool (stand near protector, face direction and use)",
inventory_image = "protector_display.png^protector_logo.png", -- radius limiter (minetest cannot handle node volume of more than 4096000)
stack_max = 1, if r > 22 then r = 22 end
on_use = function(itemstack, user, pointed_thing) minetest.register_craftitem("protector:tool", {
description = S("Protector Placer Tool (stand near protector, face direction and use)"),
local name = user:get_player_name() inventory_image = "protector_display.png^protector_logo.png",
stack_max = 1,
-- check for protector near player (2 block radius)
local pos = user:get_pos() on_use = function(itemstack, user, pointed_thing)
local pp = minetest.find_nodes_in_area(
vector.subtract(pos, 2), vector.add(pos, 2), local name = user:get_player_name()
{"protector:protect", "protector:protect2"})
-- check for protector near player (2 block radius)
if #pp == 0 then return end -- none found local pos = user:get_pos()
local pp = minetest.find_nodes_in_area(
pos = pp[1] -- take position of first protector found vector.subtract(pos, 2), vector.add(pos, 2),
{"protector:protect", "protector:protect2", "protector:protect_hidden"})
-- get members on protector
local meta = minetest.get_meta(pos) if #pp == 0 then return end -- none found
local members = meta:get_string("members") or ""
pos = pp[1] -- take position of first protector found
-- get direction player is facing
local dir = minetest.dir_to_facedir( user:get_look_dir() ) -- get members on protector
local vec = {x = 0, y = 0, z = 0} local meta = minetest.get_meta(pos)
local gap = (r * 2) + 1 local members = meta:get_string("members") or ""
local pit = user:get_look_pitch()
-- get direction player is facing
-- set placement coords local dir = minetest.dir_to_facedir( user:get_look_dir() )
if pit > 1.2 then local vec = {x = 0, y = 0, z = 0}
vec.y = gap -- up local gap = (r * 2) + 1
elseif pit < -1.2 then local pit = user:get_look_vertical()
vec.y = -gap -- down
elseif dir == 0 then -- set placement coords
vec.z = gap -- north if pit > 1.2 then
elseif dir == 1 then vec.y = -gap -- up
vec.x = gap -- east elseif pit < -1.2 then
elseif dir == 2 then vec.y = gap -- down
vec.z = -gap -- south elseif dir == 0 then
elseif dir == 3 then vec.z = gap -- north
vec.x = -gap -- west elseif dir == 1 then
end vec.x = gap -- east
elseif dir == 2 then
-- new position vec.z = -gap -- south
pos.x = pos.x + vec.x elseif dir == 3 then
pos.y = pos.y + vec.y vec.x = -gap -- west
pos.z = pos.z + vec.z end
-- does placing a protector overlap existing area -- new position
if not protector.can_dig(r * 2, pos, user:get_player_name(), true, 3) then pos.x = pos.x + vec.x
pos.y = pos.y + vec.y
minetest.chat_send_player(name, pos.z = pos.z + vec.z
"Overlaps into above players protected area")
-- does placing a protector overlap existing area
return if not protector.can_dig(r * 2, pos, user:get_player_name(), true, 3) then
end
minetest.chat_send_player(name,
-- does a protector already exist ? S("Overlaps into above players protected area"))
if #minetest.find_nodes_in_area(
vector.subtract(pos, 1), vector.add(pos, 1), return
{"protector:protect", "protector:protect2"}) > 0 then end
minetest.chat_send_player(name, "Protector already in place!") -- does a protector already exist ?
return if #minetest.find_nodes_in_area(
end vector.subtract(pos, 1), vector.add(pos, 1),
{"protector:protect", "protector:protect2",
-- do we have protectors to use ? "protector:protect_hidden"}) > 0 then
local nod
local inv = user:get_inventory() minetest.chat_send_player(name, S("Protector already in place!"))
if not inv:contains_item("main", "protector:protect") return
and not inv:contains_item("main", "protector:protect2") then end
minetest.chat_send_player(name, "No protectors available to place!")
return -- do we have protectors to use ?
end local nod
local inv = user:get_inventory()
-- take protector (block first then logo)
if inv:contains_item("main", "protector:protect") then if not inv:contains_item("main", "protector:protect")
and not inv:contains_item("main", "protector:protect2") then
inv:remove_item("main", "protector:protect")
nod = "protector:protect" minetest.chat_send_player(name,
S("No protectors available to place!"))
elseif inv:contains_item("main", "protector:protect2") then
return
inv:remove_item("main", "protector:protect2") end
nod = "protector:protect2"
end -- take protector (block first then logo)
if inv:contains_item("main", "protector:protect") then
-- do not replace containers with inventory space
local inv = minetest.get_inventory({type = "node", pos = pos}) inv:remove_item("main", "protector:protect")
if inv then nod = "protector:protect"
minetest.chat_send_player(name,
"Cannot place protector, container at " .. minetest.pos_to_string(pos)) elseif inv:contains_item("main", "protector:protect2") then
return
end inv:remove_item("main", "protector:protect2")
-- place protector nod = "protector:protect2"
minetest.set_node(pos, {name = nod, param2 = 1}) end
-- set protector metadata -- do not replace containers with inventory space
local meta = minetest.get_meta(pos) local inv = minetest.get_inventory({type = "node", pos = pos})
meta:set_string("owner", name) if inv then
meta:set_string("infotext", "Protection (owned by " .. name .. ")") minetest.chat_send_player(name,
S("Cannot place protector, container at") ..
-- copy members across if holding sneak when using tool " " .. minetest.pos_to_string(pos))
if user:get_player_control().sneak then return
meta:set_string("members", members) end
else
meta:set_string("members", "") -- protection check for other mods like Areas
end if minetest.is_protected(pos, name) then
minetest.chat_send_player(name,
minetest.chat_send_player(name, S("Cannot place protector, already protected at") ..
"Protector placed at " .. minetest.pos_to_string(pos)) " " .. minetest.pos_to_string(pos))
return
end, end
})
-- place protector
-- tool recipe minetest.set_node(pos, {name = nod, param2 = 1})
minetest.register_craft({
output = "protector:tool", -- set protector metadata
recipe = { local meta = minetest.get_meta(pos)
{"default:steel_ingot", "default:steel_ingot", "default:steel_ingot"},
{"default:steel_ingot", "protector:protect", "default:steel_ingot"}, meta:set_string("owner", name)
{"default:steel_ingot", "default:steel_ingot", "default:steel_ingot"}, meta:set_string("infotext", "Protection (owned by " .. name .. ")")
}
}) -- copy members across if holding sneak when using tool
if user:get_player_control().sneak then
meta:set_string("members", members)
else
meta:set_string("members", "")
end
minetest.chat_send_player(name,
S("Protector placed at") ..
" " .. minetest.pos_to_string(pos))
end,
})
-- tool recipe
local df = "default:steel_ingot"
if not minetest.registered_items[df] then
df = "mcl_core:iron_ingot"
end
minetest.register_craft({
output = "protector:tool",
recipe = {
{df, df, df},
{df, "protector:protect", df},
{df, df, df},
}
})

View File

@ -7,7 +7,8 @@ https://forum.minetest.net/viewtopic.php?f=9&t=9234
Change log: Change log:
- 1.1 - Using 0.4.16+ code changes, can only teleport players now - 1.2 - New teleport pad texture, code tweaks to work with minetest 5.x
- 1.1 - Using 0.4.16+ code changes, can only teleport players now, added MineClone2 crafts and spanish translation
- 1.0 - Added changes by maybe_dragon to bookmark teleport destination before using pads and potions - 1.0 - Added changes by maybe_dragon to bookmark teleport destination before using pads and potions
- 0.9 - Update to newer functions, requires Minetest 0.4.16 to work. - 0.9 - Update to newer functions, requires Minetest 0.4.16 to work.
- 0.8 - Teleport pads now have arrows showing direction player will face after use - 0.8 - Teleport pads now have arrows showing direction player will face after use

View File

@ -1,3 +1,4 @@
default default?
intllib? intllib?
lucky_block? lucky_block?
mcl_core?

View File

@ -1,24 +1,30 @@
--= Teleport Potion mod by TenPlus1 --= Teleport Potion mod by TenPlus1 (SFX are license free)
-- Craft teleport potion or pad, use to bookmark location, place to open
-- portal or place pad, portals show a blue flame that you can walk into
-- before it closes (10 seconds), potions can also be thrown for local teleport.
-- Create teleport potion or pad, place then right-click to enter coords
-- and step onto pad or walk into the blue portal light, portal closes after
-- 10 seconds, pad remains, potions are throwable... SFX are license Free...
-- Load support for intllib. -- Load support for intllib.
local MP = minetest.get_modpath(minetest.get_current_modname()) local MP = minetest.get_modpath(minetest.get_current_modname())
local S, NS = dofile(MP.."/intllib.lua") local S = minetest.get_translator and minetest.get_translator("teleport_potion") or
dofile(MP .. "/intllib.lua")
-- check for MineClone2
local mcl = minetest.get_modpath("mcl_core")
-- max teleport distance -- max teleport distance
local dist = tonumber(minetest.settings:get("map_generation_limit") or 31000) local dist = tonumber(minetest.settings:get("map_generation_limit") or 31000)
-- creative check -- creative check
local creative_mode_cache = minetest.settings:get_bool("creative_mode") local creative_mode_cache = minetest.settings:get_bool("creative_mode")
local function is_creative(name) local function is_creative(name)
return creative_mode_cache or minetest.check_player_privs(name, {creative = true}) return creative_mode_cache or minetest.check_player_privs(name, {creative = true})
end end
-- make sure coordinates are valid
local check_coordinates = function(str) local check_coordinates = function(str)
if not str or str == "" then if not str or str == "" then
@ -51,9 +57,9 @@ local check_coordinates = function(str)
return {x = x, y = y, z = z} return {x = x, y = y, z = z}
end end
-- particle effects -- particle effects
local function tp_effect(pos) local function tp_effect(pos)
minetest.add_particlespawner({ minetest.add_particlespawner({
amount = 20, amount = 20,
time = 0.25, time = 0.25,
@ -67,7 +73,7 @@ local function tp_effect(pos)
maxexptime = 1, maxexptime = 1,
minsize = 0.5, minsize = 0.5,
maxsize = 1.5, maxsize = 1.5,
texture = "particle.png", texture = "teleport_potion_particle.png",
glow = 15, glow = 15,
}) })
end end
@ -75,22 +81,21 @@ end
local teleport_destinations = {} local teleport_destinations = {}
local function set_teleport_destination(playername, dest) local function set_teleport_destination(playername, dest)
teleport_destinations[playername] = dest teleport_destinations[playername] = dest
tp_effect(dest) tp_effect(dest)
minetest.sound_play("portal_open", { minetest.sound_play("portal_open", {
pos = dest, pos = dest, gain = 1.0, max_hear_distance = 10}, true)
gain = 1.0,
max_hear_distance = 10
})
end end
--------------------------------------------------------------------------------
--- Teleport portal --- Teleport portal
--------------------------------------------------------------------------------
minetest.register_node("teleport_potion:portal", { minetest.register_node("teleport_potion:portal", {
drawtype = "plantlike", drawtype = "plantlike",
tiles = { tiles = {
{name="portal.png", {
name = "teleport_potion_portal.png",
animation = { animation = {
type = "vertical_frames", type = "vertical_frames",
aspect_w = 16, aspect_w = 16,
@ -107,6 +112,7 @@ minetest.register_node("teleport_potion:portal", {
waving = 1, waving = 1,
sunlight_propagates = true, sunlight_propagates = true,
damage_per_second = 1, -- walking into portal hurts player damage_per_second = 1, -- walking into portal hurts player
groups = {not_in_creative_inventory = 1},
-- start timer when portal appears -- start timer when portal appears
on_construct = function(pos) on_construct = function(pos)
@ -117,18 +123,14 @@ minetest.register_node("teleport_potion:portal", {
on_timer = function(pos) on_timer = function(pos)
minetest.sound_play("portal_close", { minetest.sound_play("portal_close", {
pos = pos, pos = pos, gain = 1.0, max_hear_distance = 10}, true)
gain = 1.0,
max_hear_distance = 10
})
minetest.remove_node(pos) minetest.remove_node(pos)
end, end,
on_blast = function() end, on_blast = function() end,
drop = {}, drop = {}
}) })
-- Throwable potion -- Throwable potion
local function throw_potion(itemstack, player) local function throw_potion(itemstack, player)
@ -159,21 +161,23 @@ local function throw_potion(itemstack, player)
obj:get_luaentity().player = player obj:get_luaentity().player = player
end end
-- potion entity
local potion_entity = { local potion_entity = {
physical = true, physical = true,
visual = "sprite", visual = "sprite",
visual_size = {x = 1.0, y = 1.0}, visual_size = {x = 1.0, y = 1.0},
textures = {"potion.png"}, textures = {"teleport_potion_potion.png"},
collisionbox = {0,0,0,0,0,0}, collisionbox = {-0.1,-0.1,-0.1,0.1,0.1,0.1},
lastpos = {}, lastpos = {},
player = "", player = ""
} }
potion_entity.on_step = function(self, dtime) potion_entity.on_step = function(self, dtime)
if not self.player then if not self.player then
self.object:remove() self.object:remove()
return return
end end
@ -199,7 +203,7 @@ potion_entity.on_step = function(self, dtime)
pos = self.lastpos, pos = self.lastpos,
gain = 1.0, gain = 1.0,
max_hear_distance = 5 max_hear_distance = 5
}) }, true)
tp_effect(self.lastpos) tp_effect(self.lastpos)
end end
@ -216,61 +220,76 @@ end
minetest.register_entity("teleport_potion:potion_entity", potion_entity) minetest.register_entity("teleport_potion:potion_entity", potion_entity)
--------------------------------------------------------------------------------
--- Teleport potion --- Teleport potion
--------------------------------------------------------------------------------
minetest.register_node("teleport_potion:potion", { minetest.register_node("teleport_potion:potion", {
tiles = {"pad.png"}, tiles = {"teleport_potion_potion.png"},
drawtype = "signlike", drawtype = "signlike",
paramtype = "light", paramtype = "light",
paramtype2 = "wallmounted", paramtype2 = "wallmounted",
walkable = false, walkable = false,
sunlight_propagates = true, sunlight_propagates = true,
description = S("Teleport Potion (use to set destination; place to open portal)"), description = S("Teleport Potion (use to set destination; place to open portal)"),
inventory_image = "potion.png", inventory_image = "teleport_potion_potion.png",
wield_image = "potion.png", wield_image = "teleport_potion_potion.png",
groups = {dig_immediate = 3, vessel = 1}, groups = {dig_immediate = 3, vessel = 1},
selection_box = {type = "wallmounted"}, selection_box = {type = "wallmounted"},
on_use = function(itemstack, user, pointed_thing) on_use = function(itemstack, user, pointed_thing)
if pointed_thing.type == "node" then if pointed_thing.type == "node" then
set_teleport_destination(user:get_player_name(), pointed_thing.above) set_teleport_destination(user:get_player_name(), pointed_thing.above)
else else
throw_potion(itemstack, user) throw_potion(itemstack, user)
if not is_creative(user:get_player_name()) then if not is_creative(user:get_player_name()) then
itemstack:take_item() itemstack:take_item()
return itemstack return itemstack
end end
end end
end, end,
after_place_node = function(pos, placer, itemstack, pointed_thing) after_place_node = function(pos, placer, itemstack, pointed_thing)
local name = placer:get_player_name() local name = placer:get_player_name()
local dest = teleport_destinations[name] local dest = teleport_destinations[name]
if dest then if dest then
minetest.set_node(pos, {name = "teleport_potion:portal"}) minetest.set_node(pos, {name = "teleport_potion:portal"})
local meta = minetest.get_meta(pos) local meta = minetest.get_meta(pos)
-- Set portal destination -- Set portal destination
meta:set_int("x", dest.x) meta:set_int("x", dest.x)
meta:set_int("y", dest.y) meta:set_int("y", dest.y)
meta:set_int("z", dest.z) meta:set_int("z", dest.z)
-- Portal open effect and sound -- Portal open effect and sound
tp_effect(pos) tp_effect(pos)
minetest.sound_play("portal_open", { minetest.sound_play("portal_open", {
pos = pos, pos = pos, gain = 1.0, max_hear_distance = 10}, true)
gain = 1.0,
max_hear_distance = 10
})
else else
minetest.chat_send_player(name, S("Potion failed!")) minetest.chat_send_player(name, S("Potion failed!"))
minetest.remove_node(pos) minetest.remove_node(pos)
minetest.add_item(pos, "teleport_potion:potion") minetest.add_item(pos, "teleport_potion:potion")
end end
end, end
}) })
-- teleport potion recipe -- teleport potion recipe
if mcl then
minetest.register_craft({
output = "teleport_potion:potion",
recipe = {
{"", "mcl_core:diamond", ""},
{"mcl_core:diamond", "mcl_potions:glass_bottle", "mcl_core:diamond"},
{"", "mcl_core:diamond", ""},
},
})
else
minetest.register_craft({ minetest.register_craft({
output = "teleport_potion:potion", output = "teleport_potion:potion",
recipe = { recipe = {
@ -279,14 +298,13 @@ minetest.register_craft({
{"", "default:diamond", ""}, {"", "default:diamond", ""},
}, },
}) })
end
--------------------------------------------------------------------------------
--- Teleport pad --- Teleport pad
--------------------------------------------------------------------------------
local teleport_formspec_context = {} local teleport_formspec_context = {}
minetest.register_node("teleport_potion:pad", { minetest.register_node("teleport_potion:pad", {
tiles = {"padd.png", "padd.png^[transformFY"}, tiles = {"teleport_potion_pad.png", "teleport_potion_pad.png^[transformFY"},
drawtype = "nodebox", drawtype = "nodebox",
paramtype = "light", paramtype = "light",
paramtype2 = "facedir", paramtype2 = "facedir",
@ -294,8 +312,8 @@ minetest.register_node("teleport_potion:pad", {
walkable = true, walkable = true,
sunlight_propagates = true, sunlight_propagates = true,
description = S("Teleport Pad (use to set destination; place to open portal)"), description = S("Teleport Pad (use to set destination; place to open portal)"),
inventory_image = "padd.png", inventory_image = "teleport_potion_pad.png",
wield_image = "padd.png", wield_image = "teleport_potion_pad.png",
light_source = 5, light_source = 5,
groups = {snappy = 3}, groups = {snappy = 3},
node_box = { node_box = {
@ -309,6 +327,7 @@ minetest.register_node("teleport_potion:pad", {
-- Save pointed nodes coordinates as destination for further portals -- Save pointed nodes coordinates as destination for further portals
on_use = function(itemstack, user, pointed_thing) on_use = function(itemstack, user, pointed_thing)
if pointed_thing.type == "node" then if pointed_thing.type == "node" then
set_teleport_destination(user:get_player_name(), pointed_thing.above) set_teleport_destination(user:get_player_name(), pointed_thing.above)
end end
@ -316,12 +335,15 @@ minetest.register_node("teleport_potion:pad", {
-- Initialize teleport to saved location or the current position -- Initialize teleport to saved location or the current position
after_place_node = function(pos, placer, itemstack, pointed_thing) after_place_node = function(pos, placer, itemstack, pointed_thing)
local meta = minetest.get_meta(pos) local meta = minetest.get_meta(pos)
local name = placer:get_player_name() local name = placer:get_player_name()
local dest = teleport_destinations[name] local dest = teleport_destinations[name]
if not dest then if not dest then
dest = pos dest = pos
end end
-- Set coords -- Set coords
meta:set_int("x", dest.x) meta:set_int("x", dest.x)
meta:set_int("y", dest.y) meta:set_int("y", dest.y)
@ -331,18 +353,18 @@ minetest.register_node("teleport_potion:pad", {
dest.x, dest.y, dest.z)) dest.x, dest.y, dest.z))
minetest.sound_play("portal_open", { minetest.sound_play("portal_open", {
pos = pos, pos = pos, gain = 1.0, max_hear_distance = 10}, true)
gain = 1.0,
max_hear_distance = 10
})
end, end,
-- Show formspec depending on the players privileges. -- Show formspec depending on the players privileges.
on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) on_rightclick = function(pos, node, clicker, itemstack, pointed_thing)
local name = clicker:get_player_name() local name = clicker:get_player_name()
if minetest.is_protected(pos, name) then if minetest.is_protected(pos, name) then
minetest.record_protection_violation(pos, name) minetest.record_protection_violation(pos, name)
return return
end end
@ -354,8 +376,10 @@ minetest.register_node("teleport_potion:pad", {
} }
local coords = coords.x .. "," .. coords.y .. "," .. coords.z local coords = coords.x .. "," .. coords.y .. "," .. coords.z
local desc = meta:get_string("desc") local desc = meta:get_string("desc")
formspec = "field[desc;" .. S("Description") .. ";" formspec = "field[desc;" .. S("Description") .. ";"
.. minetest.formspec_escape(desc) .. "]" .. minetest.formspec_escape(desc) .. "]"
-- Only allow privileged players to change coordinates -- Only allow privileged players to change coordinates
if minetest.check_player_privs(name, "teleport") then if minetest.check_player_privs(name, "teleport") then
formspec = formspec .. formspec = formspec ..
@ -367,23 +391,32 @@ minetest.register_node("teleport_potion:pad", {
coords = coords, coords = coords,
desc = desc, desc = desc,
} }
minetest.show_formspec(name, "teleport_potion:set_destination", formspec) minetest.show_formspec(name, "teleport_potion:set_destination", formspec)
end, end
}) })
-- Check and set coordinates -- Check and set coordinates
minetest.register_on_player_receive_fields(function(player, formname, fields) minetest.register_on_player_receive_fields(function(player, formname, fields)
if formname ~= "teleport_potion:set_destination" then if formname ~= "teleport_potion:set_destination" then
return false return false
end end
local name = player:get_player_name() local name = player:get_player_name()
local context = teleport_formspec_context[name] local context = teleport_formspec_context[name]
if not context then return false end if not context then return false end
teleport_formspec_context[name] = nil teleport_formspec_context[name] = nil
local meta = minetest.get_meta(context.pos) local meta = minetest.get_meta(context.pos)
-- Coordinates were changed -- Coordinates were changed
if fields.coords and fields.coords ~= context.coords then if fields.coords and fields.coords ~= context.coords then
local coords = check_coordinates(fields.coords) local coords = check_coordinates(fields.coords)
if coords then if coords then
meta:set_int("x", coords.x) meta:set_int("x", coords.x)
meta:set_int("y", coords.y) meta:set_int("y", coords.y)
@ -392,19 +425,32 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
minetest.chat_send_player(name, S("Teleport Pad coordinates failed!")) minetest.chat_send_player(name, S("Teleport Pad coordinates failed!"))
end end
end end
-- Update infotext -- Update infotext
if fields.desc and fields.desc ~= "" then if fields.desc and fields.desc ~= "" then
meta:set_string("desc", fields.desc) meta:set_string("desc", fields.desc)
meta:set_string("infotext", S("Teleport to @1", fields.desc)) meta:set_string("infotext", S("Teleport to @1", fields.desc))
else else
local coords = minetest.string_to_pos("(" .. context.coords .. ")") local coords = minetest.string_to_pos("(" .. context.coords .. ")")
meta:set_string("infotext", S("Pad Active (@1,@2,@3)", meta:set_string("infotext", S("Pad Active (@1,@2,@3)",
coords.x, coords.y, coords.z)) coords.x, coords.y, coords.z))
end end
return true return true
end) end)
-- teleport pad recipe -- teleport pad recipe
if mcl then
minetest.register_craft({
output = "teleport_potion:pad",
recipe = {
{"teleport_potion:potion", "mcl_core:glass", "teleport_potion:potion"},
{"mcl_core:glass", "mesecons:redstone", "mcl_core:glass"},
{"teleport_potion:potion", "mcl_core:glass", "teleport_potion:potion"},
},
})
else
minetest.register_craft({ minetest.register_craft({
output = "teleport_potion:pad", output = "teleport_potion:pad",
recipe = { recipe = {
@ -413,7 +459,7 @@ minetest.register_craft({
{"teleport_potion:potion", "default:glass", "teleport_potion:potion"} {"teleport_potion:potion", "default:glass", "teleport_potion:potion"}
} }
}) })
end
-- check portal & pad, teleport any entities on top -- check portal & pad, teleport any entities on top
minetest.register_abm({ minetest.register_abm({
@ -452,7 +498,7 @@ minetest.register_abm({
pos = pos, pos = pos,
gain = 1.0, gain = 1.0,
max_hear_distance = 5 max_hear_distance = 5
}) }, true)
-- move player -- move player
objs[n]:set_pos(target_coords) objs[n]:set_pos(target_coords)
@ -465,7 +511,7 @@ minetest.register_abm({
pos = target_coords, pos = target_coords,
gain = 1.0, gain = 1.0,
max_hear_distance = 5 max_hear_distance = 5
}) }, true)
-- rotate player to look in pad placement direction -- rotate player to look in pad placement direction
local rot = node.param2 local rot = node.param2
@ -481,22 +527,21 @@ minetest.register_abm({
yaw = 1.57 -- east yaw = 1.57 -- east
end end
objs[n]:set_look_yaw(yaw) objs[n]:set_look_horizontal(yaw)
end end
end end
end end
}) })
-- add lucky blocks -- lucky blocks
-- Teleport Potion mod
if minetest.get_modpath("lucky_block") then if minetest.get_modpath("lucky_block") then
lucky_block:add_blocks({ lucky_block:add_blocks({
{"dro", {"teleport_potion:potion"}, 2}, {"dro", {"teleport_potion:potion"}, 2},
{"tel"}, {"tel"},
{"dro", {"teleport_potion:pad"}, 1}, {"dro", {"teleport_potion:pad"}, 1},
{"lig"}, {"lig"}
}) })
end end

View File

@ -1,45 +1,3 @@
-- Support for the old multi-load method
dofile(minetest.get_modpath("intllib").."/init.lua")
-- Fallback functions for when `intllib` is not installed.
-- Code released under Unlicense <http://unlicense.org>.
-- Get the latest version of this file at:
-- https://raw.githubusercontent.com/minetest-mods/intllib/master/lib/intllib.lua
local function format(str, ...)
local args = { ... }
local function repl(escape, open, num, close)
if escape == "" then
local replacement = tostring(args[tonumber(num)])
if open == "" then
replacement = replacement..close
end
return replacement
else
return "@"..open..num..close
end
end
return (str:gsub("(@?)@(%(?)(%d+)(%)?)", repl))
end
local gettext, ngettext
if minetest.get_modpath("intllib") then
if intllib.make_gettext_pair then
-- New method using gettext.
gettext, ngettext = intllib.make_gettext_pair()
else
-- Old method using text files.
gettext = intllib.Getter()
end
end
-- Fill in missing functions.
gettext = gettext or function(msgid, ...)
return format(msgid, ...)
end
ngettext = ngettext or function(msgid, msgid_plural, n, ...)
return format(n==1 and msgid or msgid_plural, ...)
end
return gettext, ngettext

View File

@ -19,36 +19,36 @@ msgstr ""
#: init.lua #: init.lua
msgid "Teleport Potion (place and right-click to enchant location)" msgid "Teleport Potion (place and right-click to enchant location)"
msgstr "" msgstr "Poción de teletransporte (colocar y hacer clic derecho para encantar la ubicación)"
#: init.lua #: init.lua
msgid "Enter teleport coords (e.g. 200,20,-200)" msgid "Enter teleport coords (e.g. 200,20,-200)"
msgstr "" msgstr "Inserta las coordenadas del teletransporte (Por ejemplo, 200,20, -200)"
#: init.lua #: init.lua
msgid "Right-click to enchant teleport location" msgid "Right-click to enchant teleport location"
msgstr "" msgstr "Haga clic derecho para encantar la ubicación de teletransporte"
#: init.lua #: init.lua
msgid "Potion failed!" msgid "Potion failed!"
msgstr "" msgstr "¡Poción fallida!"
#: init.lua #: init.lua
msgid "Teleport Pad (place and right-click to enchant location)" msgid "Teleport Pad (place and right-click to enchant location)"
msgstr "" msgstr "Teleport Pad (Colocalo y haz clic derecho para encantar la ubicación)"
#: init.lua #: init.lua
msgid "Enter teleport coords (e.g. 200,20,-200,Home)" msgid "Enter teleport coords (e.g. 200,20,-200,Home)"
msgstr "" msgstr "Inserte las coordenadas del teletransporte (por ejemplo, 200,20, -200, Inicio)"
#: init.lua #: init.lua
msgid "Teleport to @1" msgid "Teleport to @1"
msgstr "" msgstr "Teletransportarse a @1"
#: init.lua #: init.lua
msgid "Pad Active (@1,@2,@3)" msgid "Pad Active (@1,@2,@3)"
msgstr "" msgstr "Pad activo"
#: init.lua #: init.lua
msgid "Teleport Pad coordinates failed!" msgid "Teleport Pad coordinates failed!"
msgstr "" msgstr "¡Coordenadas del Teleport Pad erroneas!"

View File

@ -0,0 +1,11 @@
# textdomain: teleport_potion
Teleport Potion (place and right-click to enchant location)=Teleportationstrank (platzieren und rechtsklicken,\n um Standort zu verzaubern)
Enter teleport coords (e.g. 200,20,-200)=Koordinaten eingeben (z.B. 200,20,-200)
Right-click to enchant teleport location=Rechtsklick um Teleportationsort zu verzaubern
Potion failed!=Trank misslungen!
Teleport Pad (place and right-click to enchant location)=Teleportationsfeld (platzieren und rechtsklicken,\n um Standort zu verzaubern)
Enter teleport coords (e.g. 200,20,-200,Home)=Koordinaten eingeben (z.B. 200,20,-200,Haus)
Teleport to @1=Teleportiere nach @1
Pad Active (@1,@2,@3)=Feld aktiv (@1,@2,@3)
Teleport Pad coordinates failed!=Teleportationsfeldkoordinaten fehlgeschlagen!

View File

@ -0,0 +1,11 @@
# textdomain: teleport_potion
Teleport Potion (place and right-click to enchant location)=Poción de teletransporte (colocar y hacer clic derecho para encantar la ubicación)
Enter teleport coords (e.g. 200,20,-200)=Inserta las coordenadas del teletransporte (Por ejemplo, 200,20, -200)
Right-click to enchant teleport location=Haga clic derecho para encantar la ubicación de teletransporte
Potion failed!=¡Poción fallida!
Teleport Pad (place and right-click to enchant location)=Teleport Pad (Colocalo y haz clic derecho para encantar la ubicación)
Enter teleport coords (e.g. 200,20,-200,Home)=Inserte las coordenadas del teletransporte (por ejemplo, 200,20, -200, Inicio)
Teleport to @1=Teletransportarse a @1
Pad Active (@1,@2,@3)=Pad activo
Teleport Pad coordinates failed!=¡Coordenadas del Teleport Pad erroneas!

View File

@ -0,0 +1,11 @@
# textdomain: teleport_potion
Teleport Potion (place and right-click to enchant location)=Potion de téléportation (poser puis clic-droit pour enchanter l'emplacement)
Enter teleport coords (e.g. 200,20,-200)=Saisissez les coordonnées de téléportation (ex : 200,20,-200)
Right-click to enchant teleport location=Clic-droit pour enchanter l'emplacement de téléportation
Potion failed!=La potion n'a pas fonctionné !
Teleport Pad (place and right-click to enchant location)=Pad de téléportation (poser puis clic-droit pour enchanter l'emplacement)
Enter teleport coords (e.g. 200,20,-200,Home)=Saisissez les coordonnées de téléportation (ex : 200,20,-200,Maison)
Teleport to @1=Téléportation vers @1
Pad Active (@1,@2,@3)=Pad activé (@1,@,2,@3)
Teleport Pad coordinates failed!=Les coordonnées du pad sont inchangées !

View File

@ -0,0 +1,9 @@
# textdomain: teleport_potion
Teleport Potion (place and right-click to enchant location)=
Enter teleport coords (e.g. 200,20,-200)=
Right-click to enchant teleport location=
Teleport Pad (place and right-click to enchant location)=
Enter teleport coords (e.g. 200,20,-200,Home)=
Pad Active (@1,@2,@3)=
Teleport Pad coordinates failed!=

View File

@ -1 +1,4 @@
name = teleport_potion name = teleport_potion
depends =
optional_depends = default, intllib, lucky_block, mcl_core
description = Adds craftable teleport potions (throwable) and teleport pads.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 334 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 201 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 266 B

View File

Before

Width:  |  Height:  |  Size: 173 B

After

Width:  |  Height:  |  Size: 173 B

View File

Before

Width:  |  Height:  |  Size: 458 B

After

Width:  |  Height:  |  Size: 458 B

View File

Before

Width:  |  Height:  |  Size: 171 B

After

Width:  |  Height:  |  Size: 171 B

26
throwing/.luacheckrc Normal file
View File

@ -0,0 +1,26 @@
std = "lua51+minetest"
unused_args = false
allow_defined_top = true
max_line_length = 999
stds.minetest = {
read_globals = {
"minetest",
"VoxelManip",
"VoxelArea",
"PseudoRandom",
"ItemStack",
"default",
table = {
fields = {
"copy",
},
},
}
}
read_globals = {
"toolranks",
"toolranks_extras",
"wielded_light",
}

View File

@ -7,20 +7,47 @@ This mod is an API for registering throwing and throwable things.
Mods based on this API: Mods based on this API:
* [throwing_arrows](https://github.com/minetest-mods/throwing_arrows) is a compatible replacement for the throwing mod by PilzAdam. * [throwing_arrows](https://github.com/minetest-mods/throwing_arrows) is a compatible replacement for the throwing mod by PilzAdam.
* [sling](https://github.com/minetest-mods/sling) is a mod written by @tacotexmex that enables item stack and single item throwing of any item. * [sling](https://github.com/minetest-mods/sling) is a mod written by @tacotexmex that enables item stack and single item throwing of any item.
* [Native American Village](https://github.com/Steamed-Punk/Native-American-Village), by Steamed-Punk, adds, among many other various items, a tomahawk that can be thrown.
## Configuration ## Configuration
The settings are the following: The settings are the following:
``` ```
throwing.velocity_factor = 19 # Trajectory parameters
throwing.horizontal_acceleration_factor = -3
throwing.vertical_acceleration = -10 throwing.vertical_acceleration = -10
throwing.realistic_trajectory = false
throwing.frictional_coefficient = -.5
# How the initial velocity of arrows is computed: simple, strength, or momentum
throwing.velocity_mode = strength
throwing.velocity_factor = 19
# Whether to allow placing an arrow as a node
throwing.allow_arrow_placing = false throwing.allow_arrow_placing = false
# Minimum time between two shots
throwing.bow_cooldown = 0.2 throwing.bow_cooldown = 0.2
# Whether to enable toolranks for bows
throwing.toolranks = true
``` ```
### Trajectory parameters
By default, the trajectory of the arrow is a simple parabola. You can set the vertical acceleration (acceleration of gravity) using `throwing.vertical_acceleration`.
If you want a more realistic trajectory that uses a first-order modelling of air friction, you can set `throwing.realistic_trajectory` to true. In this mode, `throwing.frictional_coefficient` indicates the ratio between the friction force on the arrow and its velocity. It should be negative. The acceleration of the arrow is subsequently determined by dividing the force by the "mass" of the arrow, the reference mass of 1 being the mass of the steel arrow in `throwing_arrows`. Generally, the frictional coefficient should be quite small; a value of -1 will already drastically shorten the range of the arrow. The default is -0.5.
### Initial velocity computation
The mod provides three modes to compute the initial velocity of an arrow after it is shot: simple, strength and momentum.
In simple mode, the initial velocity of the arrow is always the same. The value of this velocity is controlled by the `throwing.velocity_factor` setting, which defaults to 19.
In strength mode (the default), the initial velocity of the arrow only depends on the bow that is used---the more expensive the bow, the faster the arrow. The bow strength is multiplied by the velocity factor to compute the speed of the arrow. For reference, the steel bow in `throwing_arrows` has a strength of about 1.
Finally, momentum mode is the most realistic. It computes the velocity of the arrow based on the bow strength, as in the strength mode, and on the mass of the arrow: the heavier the arrow, the slower it will be shot. It is called the momentum mode because, in this mode, the strength of a bow indicates the initial momentum of the arrow rather than its initial speed.
## API ## API
There are two available functions in the mod API: There are two available functions in the mod API:
@ -29,11 +56,10 @@ function throwing.register_bow(name, definition)
--[[ --[[
Name: Bow name. If it doesn't contain ":", the "throwing:" prefix will be added. Name: Bow name. If it doesn't contain ":", the "throwing:" prefix will be added.
Definition: definition table, containing: Definition: definition table, containing:
* itemcraft (optional, you may want to register your own craft or to make the bow uncraftable): item used to craft the bow.
* description (highly recommended): description of the bow. * description (highly recommended): description of the bow.
* texture (essential): texture of the bow, shown in inventory. * texture (essential): texture of the bow, shown in inventory.
* groups (optional): groups of the item. * groups (optional): groups of the item.
* uses: number of uses of the bow (default is 50). * uses: number of uses of the bow (the default is 50).
* allow_shot (optional): function(player, itemstack, index, last_run): * allow_shot (optional): function(player, itemstack, index, last_run):
- player: the player using the bow - player: the player using the bow
- itemstack: the itemstack of the bow - itemstack: the itemstack of the bow
@ -42,16 +68,15 @@ Definition: definition table, containing:
Currently, `allow_shot` is actually run twice (once before the delay, and once after). Currently, `allow_shot` is actually run twice (once before the delay, and once after).
- should return true if the shot can be made, and false otherwise - should return true if the shot can be made, and false otherwise
- the default function checks that the arrow to be thrown is a registered arrow - the default function checks that the arrow to be thrown is a registered arrow
- it can return a second return value, which is the new itemstack - it can return a second return value, which is the new itemstack to replace the arrow after the shot
* throw_itself (optional): whether the bow should throw itself instead of the arrow next to it in the inventory. * throw_itself (optional): whether the bow should throw itself instead of the arrow next to it in the inventory.
If present, allow_shot is ignored. The default is false.
Default is false.
*Warning*: this field is not known to be currently used by a mod. If you encounter bugs using it, please open
an issue!
* cooldown: bow cooldown. Default is setting throwing.bow_cooldown * cooldown: bow cooldown. Default is setting throwing.bow_cooldown
* function spawn_arrow_entity(position, arrow, player): defaults to throwing.spawn_arrow_entity * function spawn_arrow_entity(position, arrow, player): defaults to throwing.spawn_arrow_entity
* sound: sound to be played when the bow is used * sound: sound to be played when the bow is used
* delay: delay before throwing the arrow * delay: delay before throwing the arrow
* no_toolranks: If true, toolranks support is disabled for this item. Defaults to false.
* strength: strength of the bow, see above. Defaults to 1.
]] ]]
-- Example: -- Example:
@ -66,11 +91,10 @@ function throwing.register_arrow(name, definition table)
--[[ --[[
Name: Arrow name. If it doesn't contain ":", the "throwing:" prefix will be added. Name: Arrow name. If it doesn't contain ":", the "throwing:" prefix will be added.
Definition: definition table, containing: Definition: definition table, containing:
* itemcraft (optional, you may want to register your own craft or to make the arrow uncraftable): item used to craft the arrow.
* craft_quantity (optional, defaulting to 1 if itemcraft is non-nil, pointless otherwise): quantity of arrows in the craft output.
* tiles (essential): tiles of the arrow. * tiles (essential): tiles of the arrow.
* target (optional, defaulting to throwing.target_both): what the arrow is able to hit (throwing.target_node, throwing.target_object, throwing.target_both). * target (optional, defaulting to throwing.target_both): what the arrow is able to hit (throwing.target_node, throwing.target_object, throwing.target_both).
* allow_protected (optional, defaulting to false): whether the arrow can be throw in a protected area * allow_protected (optional, defaulting to false): whether the arrow can be throw in a protected area
* mass (optional, defaulting to 1): the mass of the arrow (see above)
* on_hit_sound (optional): sound played when the arrow hits a node or an object. * on_hit_sound (optional): sound played when the arrow hits a node or an object.
* on_hit(self, pos, last_pos, node, object, hitter, data) (optional but very useful): callback function: * on_hit(self, pos, last_pos, node, object, hitter, data) (optional but very useful): callback function:
- pos: the position of the hit node or object. - pos: the position of the hit node or object.

View File

@ -1,3 +0,0 @@
mesecons?
mesecons_button?
wielded_light?

View File

@ -1 +0,0 @@
Throwing, formally throwing_redo - This mod provides an API for registering throwing and throwable things

View File

@ -7,6 +7,8 @@ throwing.target_node = 2
throwing.target_both = 3 throwing.target_both = 3
throwing.modname = minetest.get_current_modname() throwing.modname = minetest.get_current_modname()
local S = minetest.get_translator("throwing")
local use_toolranks = minetest.get_modpath("toolranks") and minetest.settings:get_bool("throwing.toolranks", true)
--------- Arrows functions --------- --------- Arrows functions ---------
function throwing.is_arrow(itemstack) function throwing.is_arrow(itemstack)
@ -23,74 +25,112 @@ function throwing.spawn_arrow_entity(pos, arrow, player)
return minetest.registered_items[arrow].throwing_entity(pos, player) return minetest.registered_items[arrow].throwing_entity(pos, player)
end end
else else
obj = minetest.add_entity(pos, "__builtin:item", arrow) return minetest.add_entity(pos, "__builtin:item", arrow)
end end
end end
local function shoot_arrow(itemstack, player, index, throw_itself, new_stack) local function apply_realistic_acceleration(obj, mass)
if not minetest.settings:get_bool("throwing.realistic_trajectory", false) then
return
end
local vertical_acceleration = tonumber(minetest.settings:get("throwing.vertical_acceleration")) or -10
local friction_coef = tonumber(minetest.settings:get("throwing.frictional_coefficient")) or -3
local velocity = obj:get_velocity()
obj:set_acceleration({
x = friction_coef * velocity.x / mass,
y = friction_coef * velocity.y / mass + vertical_acceleration,
z = friction_coef * velocity.z / mass
})
end
local function shoot_arrow(def, toolranks_data, player, bow_index, throw_itself, new_stack)
local inventory = player:get_inventory() local inventory = player:get_inventory()
if not throw_itself then local arrow_index
if index >= player:get_inventory():get_size("main") then if throw_itself then
arrow_index = bow_index
else
if bow_index >= player:get_inventory():get_size("main") then
return false return false
end end
index = index + 1 arrow_index = bow_index + 1
end end
local arrow_stack = inventory:get_stack("main", index) local arrow_stack = inventory:get_stack("main", arrow_index)
local arrow = arrow_stack:get_name() local arrow = arrow_stack:get_name()
local playerpos = player:getpos() local playerpos = player:get_pos()
local pos = {x=playerpos.x,y=playerpos.y+1.5,z=playerpos.z} local pos = {x=playerpos.x,y=playerpos.y+1.5,z=playerpos.z}
local obj = (minetest.registered_items[itemstack:get_name()].spawn_arrow_entity or throwing.spawn_arrow_entity)(pos, arrow, player) local obj = (def.spawn_arrow_entity or throwing.spawn_arrow_entity)(pos, arrow, player)
local luaentity = obj:get_luaentity() local luaentity = obj:get_luaentity()
-- Set custom data in the entity
luaentity.player = player:get_player_name() luaentity.player = player:get_player_name()
if not luaentity.item then if not luaentity.item then
luaentity.item = arrow luaentity.item = arrow
end end
luaentity.data = {}
luaentity.timer = 0
luaentity.toolranks = toolranks_data -- May be nil if toolranks is disabled
if luaentity.on_throw then if luaentity.on_throw then
if luaentity:on_throw(pos, player, arrow_stack, index, luaentity.data) == false then if luaentity:on_throw(pos, player, arrow_stack, arrow_index, luaentity.data) == false then
obj:remove() obj:remove()
return false return false
end end
end end
local dir = player:get_look_dir() local dir = player:get_look_dir()
local velocity_factor = tonumber(minetest.settings:get("throwing.velocity_factor")) or 19
local horizontal_acceleration_factor = tonumber(minetest.settings:get("throwing.horizontal_acceleration_factor")) or -3
local vertical_acceleration = tonumber(minetest.settings:get("throwing.vertical_acceleration")) or -10 local vertical_acceleration = tonumber(minetest.settings:get("throwing.vertical_acceleration")) or -10
local velocity_factor = tonumber(minetest.settings:get("throwing.velocity_factor")) or 19
local velocity_mode = minetest.settings:get("throwing.velocity_mode") or "strength"
obj:setvelocity({x=dir.x*velocity_factor, y=dir.y*velocity_factor, z=dir.z*velocity_factor}) local velocity
obj:setacceleration({x=dir.x*horizontal_acceleration_factor, y=vertical_acceleration, z=dir.z*horizontal_acceleration_factor}) if velocity_mode == "simple" then
obj:setyaw(player:get_look_horizontal()-math.pi/2) velocity = velocity_factor
elseif velocity_mode == "momentum" then
velocity = def.strength * velocity_factor / luaentity.mass
else
velocity = def.strength * velocity_factor
end
obj:set_velocity({
x = dir.x * velocity,
y = dir.y * velocity,
z = dir.z * velocity
})
obj:set_acceleration({x = 0, y = vertical_acceleration, z = 0})
obj:set_yaw(player:get_look_horizontal()-math.pi/2)
apply_realistic_acceleration(obj, luaentity.mass)
if luaentity.on_throw_sound ~= "" then if luaentity.on_throw_sound ~= "" then
minetest.sound_play(luaentity.on_throw_sound or "throwing_sound", {pos=playerpos, gain = 0.5}) minetest.sound_play(luaentity.on_throw_sound or "throwing_sound", {pos=playerpos, gain = 0.5})
end end
if not minetest.settings:get_bool("creative_mode") then if not minetest.settings:get_bool("creative_mode") then
if new_stack then inventory:set_stack("main", arrow_index, new_stack)
inventory:set_stack("main", index, new_stack)
else
local stack = inventory:get_stack("main", index)
stack:take_item()
inventory:set_stack("main", index, stack)
end
end end
return true return true
end end
local function arrow_step(self, dtime) function throwing.arrow_step(self, dtime)
if not self.timer or not self.player then
self.object:remove()
return
end
self.timer = self.timer + dtime self.timer = self.timer + dtime
local pos = self.object:getpos() local pos = self.object:get_pos()
local node = minetest.get_node(pos) local node = minetest.get_node(pos)
local logging = function(message, level) local logging = function(message, level)
minetest.log(level or "action", "[throwing] Arrow "..(self.item or self.name).." throwed by player "..self.player.." "..tostring(self.timer).."s ago "..message) minetest.log(level or "action", "[throwing] Arrow "..(self.item or self.name).." throwed by player "..self.player.." "..tostring(self.timer).."s ago "..message)
end end
local hit = function(pos, node, obj) local hit = function(pos1, node1, obj)
if obj then if obj then
if obj:is_player() then if obj:is_player() then
if obj:get_player_name() == self.player then -- Avoid hitting the hitter if obj:get_player_name() == self.player then -- Avoid hitting the hitter
@ -109,7 +149,7 @@ local function arrow_step(self, dtime)
player:get_inventory():add_item("main", self.item) player:get_inventory():add_item("main", self.item)
end end
if self.on_hit_fails then if self.on_hit_fails then
self:on_hit_fails(pos, player, self.data) self:on_hit_fails(pos1, player, self.data)
end end
end end
@ -119,14 +159,14 @@ local function arrow_step(self, dtime)
return return
end end
if node and minetest.is_protected(pos, self.player) and not self.allow_protected then -- Forbid hitting nodes in protected areas if node1 and minetest.is_protected(pos1, self.player) and not self.allow_protected then -- Forbid hitting nodes in protected areas
minetest.record_protection_violation(pos, self.player) minetest.record_protection_violation(pos1, self.player)
logging("hitted a node into a protected area") logging("hitted a node into a protected area")
return return
end end
if self.on_hit then if self.on_hit then
local ret, reason = self:on_hit(pos, self.last_pos, node, obj, player, self.data) local ret, reason = self:on_hit(pos1, self.last_pos, node1, obj, player, self.data)
if ret == false then if ret == false then
if reason then if reason then
logging(": on_hit function failed for reason: "..reason) logging(": on_hit function failed for reason: "..reason)
@ -140,17 +180,33 @@ local function arrow_step(self, dtime)
end end
if self.on_hit_sound then if self.on_hit_sound then
minetest.sound_play(self.on_hit_sound, {pos = pos, gain = 0.8}) minetest.sound_play(self.on_hit_sound, {pos = pos1, gain = 0.8})
end end
if node then
logging("collided with node "..node.name.." at ("..pos.x..","..pos.y..","..pos.z..")") local identifier
if node1 then
identifier = "node " .. node1.name
elseif obj then elseif obj then
if obj:get_luaentity() then if obj:get_luaentity() then
logging("collided with luaentity "..obj:get_luaentity().name.." at ("..pos.x..","..pos.y..","..pos.z..")") identifier = "luaentity " .. obj:get_luaentity().name
elseif obj:is_player() then elseif obj:is_player() then
logging("collided with player "..obj:get_player_name().." at ("..pos.x..","..pos.y..","..pos.z..")") identifier = "player " .. obj:get_player_name()
else else
logging("collided with object at ("..pos.x..","..pos.y..","..pos.z..")") identifier = "unknown object"
end
end
if identifier then
logging("collided with " .. identifier .. " at " .. minetest.pos_to_string(pos1) .. ")")
end
-- Toolranks support: update bow uses
if self.toolranks then
local inventory = player:get_inventory()
-- Check that the player did not move the bow
local current_stack = inventory:get_stack("main", self.toolranks.index)
if current_stack:get_name() == self.toolranks.name then
local new_itemstack = toolranks.new_afteruse(current_stack, player, nil, {wear = self.toolranks.wear})
inventory:set_stack("main", self.toolranks.index, new_itemstack)
end end
end end
end end
@ -200,14 +256,14 @@ local function arrow_step(self, dtime)
wielded_light.update_light_by_item(self.item, self.object:get_pos()) wielded_light.update_light_by_item(self.item, self.object:get_pos())
end end
apply_realistic_acceleration(self.object, self.mass) -- Physics: air friction
self.last_pos = pos -- Used by the build arrow self.last_pos = pos -- Used by the build arrow
end end
-- Backwards compatibility
function throwing.make_arrow_def(def) function throwing.make_arrow_def(def)
def.timer = 0 def.on_step = throwing.arrow_step
def.player = ""
def.on_step = arrow_step
def.data = {}
return def return def
end end
@ -234,17 +290,18 @@ function throwing.register_arrow(name, def)
if not def.groups.dig_immediate then if not def.groups.dig_immediate then
def.groups.dig_immediate = 3 def.groups.dig_immediate = 3
end end
def.inventory_image = def.tiles[1] def.inventory_image = def.tiles[1]
def.on_place = function(itemstack, placer, pointed_thing) def.on_place = function(itemstack, placer, pointed_thing)
if minetest.settings:get_bool("throwing.allow_arrow_placing") and pointed_thing.above then if minetest.settings:get_bool("throwing.allow_arrow_placing") and pointed_thing.above then
local playername = placer:get_player_name() local playername = placer:get_player_name()
if not minetest.is_protected(pointed_thing.above, playername) then if not minetest.is_protected(pointed_thing.above, playername) then
minetest.log("action", "Player "..playername.." placed arrow "..name.." at ("..pointed_thing.above.x..","..pointed_thing.above.y..","..pointed_thing.above.z..")") minetest.log("action", "Player "..playername.." placed arrow "..name.." at "..minetest.pos_to_string(pointed_thing.above))
minetest.set_node(pointed_thing.above, {name = name}) minetest.set_node(pointed_thing.above, {name = name})
itemstack:take_item() itemstack:take_item()
return itemstack return itemstack
else else
minetest.log("warning", "Player "..playername.." tried to place arrow "..name.." into a protected area at ("..pointed_thing.above.x..","..pointed_thing.above.y..","..pointed_thing.above.z..")") minetest.log("warning", "Player "..playername.." tried to place arrow "..name.." into a protected area at "..minetest.pos_to_string(pointed_thing.above))
minetest.record_protection_violation(pointed_thing.above, playername) minetest.record_protection_violation(pointed_thing.above, playername)
return itemstack return itemstack
end end
@ -276,7 +333,7 @@ function throwing.register_arrow(name, def)
} }
minetest.register_node(registration_name, def) minetest.register_node(registration_name, def)
minetest.register_entity(registration_name.."_entity", throwing.make_arrow_def{ minetest.register_entity(registration_name.."_entity", {
physical = false, physical = false,
visual = "wielditem", visual = "wielditem",
visual_size = {x = 0.125, y = 0.125}, visual_size = {x = 0.125, y = 0.125},
@ -289,39 +346,40 @@ function throwing.register_arrow(name, def)
allow_protected = def.allow_protected, allow_protected = def.allow_protected,
target = def.target, target = def.target,
on_hit_fails = def.on_hit_fails, on_hit_fails = def.on_hit_fails,
on_step = throwing.arrow_step,
item = name, item = name,
mass = def.mass or 1,
}) })
if def.itemcraft then
minetest.register_craft({
output = name.." "..tostring(def.craft_quantity or 1),
recipe = {
{def.itemcraft, "default:stick", "default:stick"}
}
})
minetest.register_craft({
output = name.." "..tostring(def.craft_quantity or 1),
recipe = {
{ "default:stick", "default:stick", def.itemcraft}
}
})
end
end end
---------- Bows ----------- ---------- Bows -----------
if use_toolranks and minetest.get_modpath("toolranks_extras") and toolranks_extras.register_tool_type then
toolranks_extras.register_tool_type("bow", S("bow"), S("Arrows thrown"))
end
function throwing.register_bow(name, def) function throwing.register_bow(name, def)
local enable_toolranks = use_toolranks and not def.no_toolranks
def.name = name
if not def.allow_shot then if not def.allow_shot then
def.allow_shot = function(player, itemstack, index) def.allow_shot = function(player, itemstack, index)
if index >= player:get_inventory():get_size("main") and not def.throw_itself then if index >= player:get_inventory():get_size("main") and not def.throw_itself then
return false return false
end end
return throwing.is_arrow(itemstack) return throwing.is_arrow(itemstack) or def.throw_itself
end end
end end
if not def.inventory_image then if not def.inventory_image then
def.inventory_image = def.texture def.inventory_image = def.texture
end end
if not def.strength then
def.strength = 20
end
def.on_use = function(itemstack, user, pointed_thing) def.on_use = function(itemstack, user, pointed_thing)
-- Cooldown -- Cooldown
local meta = itemstack:get_meta() local meta = itemstack:get_meta()
@ -348,25 +406,42 @@ function throwing.register_bow(name, def)
minetest.after(def.delay or 0, function() minetest.after(def.delay or 0, function()
-- Re-check that the arrow can be thrown. Overwrite the new_stack -- Re-check that the arrow can be thrown. Overwrite the new_stack
local old_new_stack = new_stack local old_new_stack = new_stack
res, new_stack = def.allow_shot(user, user:get_inventory():get_stack("main", arrow_index), arrow_index, true)
if not new_stack then local arrow_stack = user:get_inventory():get_stack("main", arrow_index)
new_stack = old_new_stack
end res, new_stack = def.allow_shot(user, arrow_stack, arrow_index, true)
if not res then if not res then
return return
end end
if not new_stack then
new_stack = old_new_stack
end
if not new_stack then
arrow_stack:take_item()
new_stack = arrow_stack
end
-- Shoot arrow -- Shoot arrow
if shoot_arrow(itemstack, user, bow_index, def.throw_itself, new_stack) then local uses = 65535 / (def.uses or 50)
local toolranks_data
if enable_toolranks then
toolranks_data = {
name = itemstack:get_name(),
index = bow_index,
wear = uses
}
end
if shoot_arrow(def, toolranks_data, user, bow_index, def.throw_itself, new_stack) then
if not minetest.settings:get_bool("creative_mode") then if not minetest.settings:get_bool("creative_mode") then
itemstack:add_wear(65535 / (def.uses or 50)) itemstack:add_wear(uses)
end end
end end
if def.throw_itself then if def.throw_itself then
-- This is a bug. If we return ItemStack(nil), the player punches the entity, -- This is a bug. If we return ItemStack(nil), the player punches the entity,
-- and if the entity if a __builtin:item, it gets back to his inventory. -- and if the entity is a __builtin:item, it gets back to his inventory.
minetest.after(0.1, function() minetest.after(0.1, function()
user:get_inventory():remove_item("main", itemstack) user:get_inventory():remove_item("main", itemstack)
end) end)
@ -377,22 +452,11 @@ function throwing.register_bow(name, def)
end) end)
return itemstack return itemstack
end end
minetest.register_tool(name, def)
if def.itemcraft then if enable_toolranks then
-- Check for an override name def.original_description = def.original_description or def.description
-- because an ``output = ":name"'' can't exist in a recipe def.description = toolranks.create_description(def.description)
local output_name = name
if name:sub(1,1) == ":" then
output_name = name:sub(2)
end
minetest.register_craft({
output = output_name,
recipe = {
{"farming:cotton", def.itemcraft, ""},
{"farming:cotton", "", def.itemcraft},
{"farming:cotton", def.itemcraft, ""},
}
})
end end
minetest.register_tool(name, def)
end end

View File

@ -0,0 +1,7 @@
# textdomain: throwing
### init.lua ###
Arrows thrown=
bow=

View File

@ -0,0 +1,7 @@
# textdomain: throwing
### init.lua ###
Arrows thrown=Flèches lancées
bow=arc

View File

@ -1 +1,3 @@
name = throwing name = throwing
optional_depends = wielded_light, toolranks, toolranks_extras
description = Throwing library: provides an API for registering throwing and throwable things

View File

@ -8,6 +8,7 @@ The settings are the following:
``` ```
throwing.enable_arrow = true throwing.enable_arrow = true
throwing.enable_golden_arrow = true throwing.enable_golden_arrow = true
throwing.enable_diamond_arrow = true
throwing.enable_fire_arrow = true throwing.enable_fire_arrow = true
throwing.enable_teleport_arrow = true throwing.enable_teleport_arrow = true
throwing.enable_dig_arrow = true throwing.enable_dig_arrow = true

View File

@ -1,5 +0,0 @@
throwing
default
farming
mesecons?
mesecons_button?

View File

@ -1,45 +1,72 @@
-- Translation support
local S = minetest.get_translator("throwing_arrows")
local function register_bow_craft(name, itemcraft)
minetest.register_craft({
output = "throwing:" .. name,
recipe = {
{"farming:string", itemcraft, ""},
{"farming:string", "", itemcraft},
{"farming:string", itemcraft, ""},
}
})
end
throwing.register_bow(":throwing:bow_wood", { throwing.register_bow(":throwing:bow_wood", {
itemcraft = "default:wood", description = S("Wooden Bow"),
description = "Wooden Bow",
texture = "throwing_bow_wood.png", texture = "throwing_bow_wood.png",
uses = 50 uses = 50,
strength = .5
}) })
register_bow_craft("bow_wood", "default:wood")
throwing.register_bow(":throwing:bow_stone", { throwing.register_bow(":throwing:bow_stone", {
itemcraft = "default:cobble", description = S("Stone Bow"),
description = "Stone Bow",
texture = "throwing_bow_stone.png", texture = "throwing_bow_stone.png",
uses = 100 uses = 100,
strength = .65
}) })
register_bow_craft("bow_stone", "default:cobble")
throwing.register_bow(":throwing:bow_steel", { throwing.register_bow(":throwing:bow_steel", {
itemcraft = "default:steel_ingot", description = S("Steel Bow"),
description = "Steel Bow",
texture = "throwing_bow_steel.png", texture = "throwing_bow_steel.png",
uses = 150 uses = 150,
strength = .8
}) })
register_bow_craft("bow_steel", "default:steel_ingot")
throwing.register_bow(":throwing:bow_bronze", { throwing.register_bow(":throwing:bow_bronze", {
itemcraft = "default:bronze_ingot", description = S("Bronze Bow"),
description = "Bronze Bow",
texture = "throwing_bow_bronze.png", texture = "throwing_bow_bronze.png",
uses = 200 uses = 200,
strength = .95
}) })
register_bow_craft("bow_bronze", "default:bronze_ingot")
throwing.register_bow(":throwing:bow_gold", { throwing.register_bow(":throwing:bow_gold", {
itemcraft = "default:gold_ingot", description = S("Gold Bow"),
description = "Gold Bow",
texture = "throwing_bow_gold.png", texture = "throwing_bow_gold.png",
uses = 250 uses = 250,
strength = 1.1
}) })
register_bow_craft("bow_gold", "default:gold_ingot")
throwing.register_bow(":throwing:bow_mese", { throwing.register_bow(":throwing:bow_mese", {
itemcraft = "default:mese_crystal", description = S("Mese Bow"),
description = "Mese Bow",
texture = "throwing_bow_mese.png", texture = "throwing_bow_mese.png",
uses = 300 uses = 300,
strength = 1.25
}) })
register_bow_craft("bow_mese", "default:mese_crystal")
throwing.register_bow(":throwing:bow_diamond", { throwing.register_bow(":throwing:bow_diamond", {
itemcraft = "default:diamond", description = S("Diamond Bow"),
description = "Diamond Bow",
texture = "throwing_bow_diamond.png", texture = "throwing_bow_diamond.png",
uses = 320 uses = 320,
strength = 1.4
}) })
register_bow_craft("bow_diamond", "default:diamond")
local function get_setting(name) local function get_setting(name)
local value = minetest.settings:get_bool("throwing.enable_"..name) local value = minetest.settings:get_bool("throwing.enable_"..name)
@ -50,19 +77,53 @@ local function get_setting(name)
end end
end end
local function register_arrow_craft(name, itemcraft, craft_quantity)
minetest.register_craft({
output = "throwing:"..name.." "..tostring(craft_quantity or 1),
recipe = {
{itemcraft, "default:stick", "default:stick"}
}
})
minetest.register_craft({
output = "throwing:"..name.." "..tostring(craft_quantity or 1),
recipe = {
{ "default:stick", "default:stick", itemcraft}
}
})
end
local last_punch_times = {}
local function arrow_punch(object, hitter, caps)
local time_from_last_punch = caps.full_punch_interval or 1
local hitter_name = hitter:get_player_name()
local player_name = object:get_player_name()
if last_punch_times[hitter_name] then
if last_punch_times[hitter_name][player_name] then
time_from_last_punch = os.difftime(os.time(), last_punch_times[hitter_name][player_name])
end
else
last_punch_times[hitter_name] = {}
end
if time_from_last_punch >= (caps.full_punch_interval or 1) then
last_punch_times[hitter_name][player_name] = os.time()
end
object:punch(hitter, time_from_last_punch, caps, nil)
end
if get_setting("arrow") then if get_setting("arrow") then
throwing.register_arrow("throwing:arrow", { throwing.register_arrow("throwing:arrow", {
itemcraft = "default:steel_ingot", description = S("Arrow"),
craft_quantity = 16,
description = "Arrow",
tiles = {"throwing_arrow.png", "throwing_arrow.png", "throwing_arrow_back.png", "throwing_arrow_front.png", "throwing_arrow_2.png", "throwing_arrow.png"}, tiles = {"throwing_arrow.png", "throwing_arrow.png", "throwing_arrow_back.png", "throwing_arrow_front.png", "throwing_arrow_2.png", "throwing_arrow.png"},
target = throwing.target_both, target = throwing.target_both,
allow_protected = true, allow_protected = true,
mass = 1,
on_hit_sound = "throwing_arrow", on_hit_sound = "throwing_arrow",
on_hit = function(self, pos, _, node, object, hitter) on_hit = function(self, pos, _, node, object, hitter)
if object then if object then
object:punch(hitter, 1, { arrow_punch(object, hitter, {
full_punch_interval = 1, full_punch_interval = 0.7,
max_drop_level = 1,
damage_groups = {fleshy = 3} damage_groups = {fleshy = 3}
}) })
elseif node then elseif node then
@ -72,44 +133,67 @@ if get_setting("arrow") then
end end
end end
}) })
register_arrow_craft("arrow", "default:steel_ingot", 16)
end end
if get_setting("golden_arrow") then if get_setting("golden_arrow") then
throwing.register_arrow("throwing:arrow_gold", { throwing.register_arrow("throwing:arrow_gold", {
itemcraft = "default:gold_ingot", description = S("Golden Arrow"),
craft_quantity = 16,
description = "Golden Arrow",
tiles = {"throwing_arrow_gold.png", "throwing_arrow_gold.png", "throwing_arrow_gold_back.png", "throwing_arrow_gold_front.png", "throwing_arrow_gold_2.png", "throwing_arrow_gold.png"}, tiles = {"throwing_arrow_gold.png", "throwing_arrow_gold.png", "throwing_arrow_gold_back.png", "throwing_arrow_gold_front.png", "throwing_arrow_gold_2.png", "throwing_arrow_gold.png"},
target = throwing.target_object, target = throwing.target_object,
allow_protected = true, allow_protected = true,
on_hit_sound = "throwing_arrow", on_hit_sound = "throwing_arrow",
mass = 2,
on_hit = function(self, pos, _, _, object, hitter) on_hit = function(self, pos, _, _, object, hitter)
object:punch(hitter, 1, { arrow_punch(object, hitter, {
full_punch_interval = 1, full_punch_interval = 0.6,
max_drop_level = 1,
damage_groups = {fleshy = 5} damage_groups = {fleshy = 5}
}) })
end end
}) })
register_arrow_craft("arrow_gold", "default:gold_ingot", 16)
end
if get_setting("diamond_arrow") then
throwing.register_arrow("throwing:arrow_diamond", {
description = S("Diamond Arrow"),
tiles = {"throwing_arrow_diamond.png", "throwing_arrow_diamond.png", "throwing_arrow_diamond_back.png", "throwing_arrow_diamond_front.png", "throwing_arrow_diamond_2.png", "throwing_arrow_diamond.png"},
target = throwing.target_object,
allow_protected = true,
on_hit_sound = "throwing_arrow",
mass = .7,
on_hit = function(self, pos, _, _, object, hitter)
arrow_punch(object, hitter, {
full_punch_interval = 0.5,
max_drop_level = 1,
damage_groups = {fleshy = 7}
})
end
})
register_arrow_craft("arrow_diamond", "default:diamond", 4)
end end
if get_setting("dig_arrow") then if get_setting("dig_arrow") then
throwing.register_arrow("throwing:arrow_dig", { throwing.register_arrow("throwing:arrow_dig", {
itemcraft = "default:pick_wood", description = S("Dig Arrow"),
description = "Dig Arrow",
tiles = {"throwing_arrow_dig.png", "throwing_arrow_dig.png", "throwing_arrow_dig_back.png", "throwing_arrow_dig_front.png", "throwing_arrow_dig_2.png", "throwing_arrow_dig.png"}, tiles = {"throwing_arrow_dig.png", "throwing_arrow_dig.png", "throwing_arrow_dig_back.png", "throwing_arrow_dig_front.png", "throwing_arrow_dig_2.png", "throwing_arrow_dig.png"},
target = throwing.target_node, target = throwing.target_node,
mass = 1,
on_hit_sound = "throwing_dig_arrow", on_hit_sound = "throwing_dig_arrow",
on_hit = function(self, pos, _, node, _, hitter) on_hit = function(self, pos, _, node, _, hitter)
return minetest.dig_node(pos) return minetest.dig_node(pos)
end end
}) })
register_arrow_craft("arrow_dig", "default:pick_wood")
end end
if get_setting("dig_arrow_admin") then if get_setting("dig_arrow_admin") then
throwing.register_arrow("throwing:arrow_dig_admin", { throwing.register_arrow("throwing:arrow_dig_admin", {
description = "Admin Dig Arrow", description = S("Admin Dig Arrow"),
tiles = {"throwing_arrow_dig.png", "throwing_arrow_dig.png", "throwing_arrow_dig_back.png", "throwing_arrow_dig_front.png", "throwing_arrow_dig_2.png", "throwing_arrow_dig.png"}, tiles = {"throwing_arrow_dig.png", "throwing_arrow_dig.png", "throwing_arrow_dig_back.png", "throwing_arrow_dig_front.png", "throwing_arrow_dig_2.png", "throwing_arrow_dig.png"},
target = throwing.target_node, target = throwing.target_node,
mass = 1,
on_hit = function(self, pos, _, node, _, _) on_hit = function(self, pos, _, node, _, _)
minetest.remove_node(pos) minetest.remove_node(pos)
end, end,
@ -119,35 +203,36 @@ end
if get_setting("teleport_arrow") then if get_setting("teleport_arrow") then
throwing.register_arrow("throwing:arrow_teleport", { throwing.register_arrow("throwing:arrow_teleport", {
itemcraft = "default:diamond", description = S("Teleport Arrow"),
description = "Teleport Arrow",
tiles = {"throwing_arrow_teleport.png", "throwing_arrow_teleport.png", "throwing_arrow_teleport_back.png", "throwing_arrow_teleport_front.png", "throwing_arrow_teleport_2.png", "throwing_arrow_teleport.png"}, tiles = {"throwing_arrow_teleport.png", "throwing_arrow_teleport.png", "throwing_arrow_teleport_back.png", "throwing_arrow_teleport_front.png", "throwing_arrow_teleport_2.png", "throwing_arrow_teleport.png"},
allow_protected = true, allow_protected = true,
mass = 1,
on_hit_sound = "throwing_teleport_arrow", on_hit_sound = "throwing_teleport_arrow",
on_hit = function(self, _, last_pos, _, _, hitter) on_hit = function(self, _, last_pos, _, _, hitter)
if minetest.get_node(last_pos).name ~= "air" then if minetest.get_node(last_pos).name ~= "air" then
minetest.log("warning", "[throwing] BUG: node at last_pos was not air") minetest.log("warning", "[throwing] BUG: node at "..minetest.pos_to_string(last_pos).." was not air")
return return
end end
if minetest.setting_getbool("throwing.allow_teleport_in_protected") == false then if minetest.settings:get_bool("throwing.allow_teleport_in_protected") == false then
return false return false
end end
hitter:moveto(last_pos) hitter:move_to(last_pos)
end end
}) })
register_arrow_craft("arrow_teleport", "default:mese_crystal")
end end
if get_setting("fire_arrow") then if get_setting("fire_arrow") then
throwing.register_arrow("throwing:arrow_fire", { throwing.register_arrow("throwing:arrow_fire", {
itemcraft = "default:torch", description = S("Torch Arrow"),
description = "Torch Arrow",
tiles = {"throwing_arrow_fire.png", "throwing_arrow_fire.png", "throwing_arrow_fire_back.png", "throwing_arrow_fire_front.png", "throwing_arrow_fire_2.png", "throwing_arrow_fire.png"}, tiles = {"throwing_arrow_fire.png", "throwing_arrow_fire.png", "throwing_arrow_fire_back.png", "throwing_arrow_fire_front.png", "throwing_arrow_fire_2.png", "throwing_arrow_fire.png"},
mass = 1,
on_hit_sound = "default_place_node", on_hit_sound = "default_place_node",
on_hit = function(self, pos, last_pos, _, _, hitter) on_hit = function(self, pos, last_pos, _, _, hitter)
if minetest.get_node(last_pos).name ~= "air" then if minetest.get_node(last_pos).name ~= "air" then
minetest.log("warning", "[throwing] BUG: node at last_pos was not air") minetest.log("warning", "[throwing] BUG: node at "..minetest.pos_to_string(last_pos).." was not air")
return return
end end
@ -165,17 +250,18 @@ if get_setting("fire_arrow") then
{type="node", under=r_pos, above=r_last_pos}) {type="node", under=r_pos, above=r_last_pos})
end end
}) })
register_arrow_craft("arrow_fire", "default:torch")
end end
if get_setting("build_arrow") then if get_setting("build_arrow") then
throwing.register_arrow("throwing:arrow_build", { throwing.register_arrow("throwing:arrow_build", {
itemcraft = "default:obsidian_glass", description = S("Build Arrow"),
description = "Build Arrow",
tiles = {"throwing_arrow_build.png", "throwing_arrow_build.png", "throwing_arrow_build_back.png", "throwing_arrow_build_front.png", "throwing_arrow_build_2.png", "throwing_arrow_build.png"}, tiles = {"throwing_arrow_build.png", "throwing_arrow_build.png", "throwing_arrow_build_back.png", "throwing_arrow_build_front.png", "throwing_arrow_build_2.png", "throwing_arrow_build.png"},
mass = 1,
on_hit_sound = "throwing_build_arrow", on_hit_sound = "throwing_build_arrow",
on_hit = function(self, pos, last_pos, _, _, hitter) on_hit = function(self, pos, last_pos, _, _, hitter)
if minetest.get_node(last_pos).name ~= "air" then if minetest.get_node(last_pos).name ~= "air" then
minetest.log("warning", "[throwing] BUG: node at last_pos was not air") minetest.log("warning", "[throwing] BUG: node at "..minetest.pos_to_string(last_pos).." was not air")
return return
end end
@ -193,16 +279,16 @@ if get_setting("build_arrow") then
{type="node", under=r_pos, above=r_last_pos}) {type="node", under=r_pos, above=r_last_pos})
end end
}) })
register_arrow_craft("arrow_build", "default:obsidian_glass")
end end
if get_setting("drop_arrow") then if get_setting("drop_arrow") then
throwing.register_arrow("throwing:arrow_drop", { throwing.register_arrow("throwing:arrow_drop", {
itemcraft = "default:copper_ingot", description = S("Drop Arrow"),
craft_quantity = 16,
description = "Drop Arrow",
tiles = {"throwing_arrow_drop.png", "throwing_arrow_drop.png", "throwing_arrow_drop_back.png", "throwing_arrow_drop_front.png", "throwing_arrow_drop_2.png", "throwing_arrow_drop.png"}, tiles = {"throwing_arrow_drop.png", "throwing_arrow_drop.png", "throwing_arrow_drop_back.png", "throwing_arrow_drop_front.png", "throwing_arrow_drop_2.png", "throwing_arrow_drop.png"},
on_hit_sound = "throwing_build_arrow", on_hit_sound = "throwing_build_arrow",
allow_protected = true, allow_protected = true,
mass = 1,
on_throw = function(self, _, thrower, _, index, data) on_throw = function(self, _, thrower, _, index, data)
local inventory = thrower:get_inventory() local inventory = thrower:get_inventory()
if index >= inventory:get_size("main") or inventory:get_stack("main", index+1):get_name() == "" then if index >= inventory:get_size("main") or inventory:get_stack("main", index+1):get_name() == "" then
@ -216,9 +302,10 @@ if get_setting("drop_arrow") then
minetest.item_drop(ItemStack(data.itemstack), hitter, last_pos) minetest.item_drop(ItemStack(data.itemstack), hitter, last_pos)
end, end,
on_hit_fails = function(self, _, thrower, data) on_hit_fails = function(self, _, thrower, data)
if not minetest.setting_getbool("creative_mode") then if not minetest.settings:get_bool("creative_mode") then
thrower:get_inventory():set_stack("main", data.index, data.itemstack) thrower:get_inventory():set_stack("main", data.index, data.itemstack)
end end
end end
}) })
register_arrow_craft("arrow_drop", "default:copper_ingot", 16)
end end

View File

@ -0,0 +1,25 @@
# textdomain: throwing_arrows
# Translation template (replace this line with credits)
# Licence: MPL-2.0
## Bows
Wooden Bow=
Stone Bow=
Steel Bow=
Bronze Bow=
Gold Bow=
Mese Bow=
Diamond Bow=
## Arrows
Arrow=
Golden Arrow=
Diamond Arrow=
Dig Arrow=
Admin Dig Arrow=
Teleport Arrow=
Torch Arrow=
Build Arrow=
Drop Arrow=

View File

@ -0,0 +1,25 @@
# textdomain: throwing_arrows
# Translation template (replace this line with credits)
# Licence: MPL-2.0
## Bows
Wooden Bow=Arc en bois
Stone Bow=Arc en pierre
Steel Bow=Arc en fer
Bronze Bow=Arc en bronze
Gold Bow=Arc en or
Mese Bow=Arc en mese
Diamond Bow=Arc en diamant
## Arrows
Arrow=Flèche
Golden Arrow=Flèche en or
Diamond Arrow=Flèche en diamant
Dig Arrow=Flèche creuseuse
Admin Dig Arrow=Flèche creuseuse dadministrateur
Teleport Arrow=Flèche de téléportation
Torch Arrow=Flèche-torche
Build Arrow=Flèche de construction
Drop Arrow=Flèche de livraison

View File

@ -1 +1,4 @@
name = throwing_arrows name = throwing_arrows
depends = throwing, default, farming
optional_depends = mesecons, mesecons_button
description = Bows and Arrows for the throwing mod

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 139 B

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 141 B

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 141 B

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 119 B

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@ -8,7 +8,7 @@
This mod adds a wooden trash can, and a dumpster to the game. Right click it, put in your trash, and click the empty trash button. This mod adds a wooden trash can, and a dumpster to the game. Right click it, put in your trash, and click the empty trash button.
You can also throw things in the wooden trash can by pressing "q" or throwing them out of your inventory. You can also throw things in the wooden trash can by pressing "q" or throwing them out of your inventory.
Version: 0.2.2 Version: 0.2.3
License: MIT (see LICENSE.txt) License: MIT (see LICENSE.txt)
Dependencies: Dependencies:
@ -46,4 +46,5 @@ Mossmanikin:
Made the nodeboxes for the dumpster, the textures for the wooden trash can, and the texture for the dumpster node. Made the nodeboxes for the dumpster, the textures for the wooden trash can, and the texture for the dumpster node.
(with some editing by me). (old) (with some editing by me). (old)
Minerdudetest(Minertestdude on Github):
compatibility with MCL2

View File

@ -1 +0,0 @@
default

View File

@ -1 +0,0 @@
This mod adds a wooden trash can, and a dumpster to the game. Right click it, put in your trash, and click the empty trash button.

View File

@ -1,7 +1,39 @@
-- standard compatibility switcher block.
local moditems = {} -- switcher
local mineclone_path = minetest.get_modpath("mcl_core") and mcl_core
if mineclone_path then -- means MineClone 2 is loaded
moditems.iron_item = "mcl_core:iron_ingot" -- MCL version of iron ingot
moditems.coal_item = "mcl_core:coalblock" -- MCL version of coal block
moditems.green_dye = "mcl_dye:green" -- MCL version of green dye
moditems.sounds = mcl_sounds.node_sound_defaults
moditems.trashcan_infotext = nil
moditems.dumpster_infotext = nil
-- trying to imitate MCL boxart (no getter API)
moditems.boxart = "bgcolor[#d0d0d0;false]listcolors[#9d9d9d;#9d9d9d;#5c5c5c;#000000;#ffffff]"
moditems.trashbin_groups = {pickaxey=1,axey=1,handy=1,swordy=1,flammable=1,destroy_by_lava_flow=1,craftitem=1}
moditems.dumpster_groups = {pickaxey=1,axey=1,handy=1,swordy=1,flammable=0,destroy_by_lava_flow=0,craftitem=1}
else -- fallback, assume default (Minetest Game) is loaded
moditems.iron_item = "default:steel_ingot" -- MTG iron ingot
moditems.coal_item = "default:coalblock" -- MTG coal block
moditems.green_dye = "dye:dark_green" -- MTG version of green dye
moditems.sounds = default.node_sound_defaults
moditems.trashcan_infotext = "Trash Can"
moditems.dumpster_infotext = "Dumpster"
moditems.boxart = ""
moditems.trashbin_groups = {snappy=1,choppy=2,oddly_breakable_by_hand=2,flammable=3}
moditems.dumpster_groups = {cracky=3,oddly_breakable_by_hand=1}
end
-- --
-- Functions -- Functions
-- --
local trash_can_throw_in = minetest.settings:get_bool("trash_can_throw_in") or false
local fdir_to_front = { local fdir_to_front = {
{x=0, z=1}, {x=0, z=1},
{x=1, z=0}, {x=1, z=0},
@ -25,16 +57,15 @@ end
-- --
-- Custom Sounds -- Custom Sounds
-- --
function default.node_sound_metal_defaults(table) local function get_dumpster_sound()
table = table or {} local sndtab = {
table.footstep = table.footstep or {name="default_hard_footstep", gain=0.4} footstep = {name="default_hard_footstep", gain=0.4},
table.dig = table.dig or {name="metal_bang", gain=0.6} dig = {name="metal_bang", gain=0.6},
table.dug = table.dug or {name="default_dug_node", gain=1.0} dug = {name="default_dug_node", gain=1.0}
}
default.node_sound_defaults(table) moditems.sounds(sndtab)
return table return sndtab
end end
-- --
-- Nodeboxes -- Nodeboxes
-- --
@ -79,21 +110,20 @@ minetest.register_node("trash_can:trash_can_wooden",{
type = "fixed", type = "fixed",
fixed = trash_can_nodebox fixed = trash_can_nodebox
}, },
groups = { groups = moditems.trashbin_groups,
snappy=1, _mcl_blast_resistance = 5,
choppy=2, _mcl_hardness = 1,
oddly_breakable_by_hand=2,
flammable=3
},
on_construct = function(pos) on_construct = function(pos)
local meta = minetest.get_meta(pos) local meta = minetest.get_meta(pos)
meta:set_string("formspec", meta:set_string("formspec",
"size[8,9]" .. "size[8,9]" ..
"button[0,0;2,1;empty;Empty Trash]" .. "button[0,0;2,1;empty;Empty Trash]" ..
"list[context;trashlist;3,1;2,3;]" .. "list[context;trashlist;3,1;2,3;]" ..
"list[current_player;main;0,5;8,4;]" "list[current_player;main;0,5;8,4;]" ..
"listring[]" ..
moditems.boxart
) )
meta:set_string("infotext", "Trash Can") meta:set_string("infotext", moditems.trashcan_infotext)
local inv = meta:get_inventory() local inv = meta:get_inventory()
inv:set_size("main", 8*4) inv:set_size("main", 8*4)
inv:set_size("trashlist", 2*3) inv:set_size("trashlist", 2*3)
@ -150,22 +180,21 @@ minetest.register_node("trash_can:dumpster", {
type = "fixed", type = "fixed",
fixed = dumpster_nodebox, fixed = dumpster_nodebox,
}, },
groups = { _mcl_blast_resistance = 10,
cracky = 3, _mcl_hardness = 3,
oddly_breakable_by_hand = 1, groups = moditems.dumpster_groups,
}, sounds = get_dumpster_sound(),
sounds = default.node_sound_metal_defaults(),
on_construct = function(pos) on_construct = function(pos)
local meta = minetest.get_meta(pos) local meta = minetest.get_meta(pos)
meta:set_string("formspec", meta:set_string("formspec",
"size[8,9]" .. "size[8,9]" ..
"button[0,0;2,1;empty;Empty Trash]" .. "button[0,0;2,1;empty;Empty Trash]" ..
"list[context;main;1,1;6,3;]" .. "list[context;main;1,1;6,3;]" ..
"list[current_player;main;0,5;8,4;]" "list[current_player;main;0,5;8,4;]"..
"listring[]" ..
moditems.boxart
) )
meta:set_string("infotext", "Dumpster") meta:set_string("infotext", moditems.dumpster_infotext)
local inv = meta:get_inventory() local inv = meta:get_inventory()
inv:set_size("main", 8*4) inv:set_size("main", 8*4)
end, end,
@ -199,7 +228,7 @@ minetest.register_node("trash_can:dumpster", {
inv:set_list("main", {}) inv:set_list("main", {})
minetest.sound_play("trash", {to_player=sender:get_player_name(), gain = 2.0}) minetest.sound_play("trash", {to_player=sender:get_player_name(), gain = 2.0})
end end
end end,
}) })
-- --
@ -220,9 +249,9 @@ minetest.register_craft({
minetest.register_craft({ minetest.register_craft({
output = 'trash_can:dumpster', output = 'trash_can:dumpster',
recipe = { recipe = {
{'default:coalblock', 'default:coalblock', 'default:coalblock'}, {moditems.coal_item,moditems.coal_item,moditems.coal_item},
{'default:steel_ingot', 'dye:dark_green', 'default:steel_ingot'}, {moditems.iron_item,moditems.green_dye,moditems.iron_item},
{'default:steel_ingot', 'default:steel_ingot', 'default:steel_ingot'}, {moditems.iron_item,moditems.iron_item,moditems.iron_item},
} }
}) })
@ -230,28 +259,30 @@ minetest.register_craft({
-- Misc -- Misc
-- --
-- Remove any items thrown in trash can. if trash_can_throw_in then
local old_on_step = minetest.registered_entities["__builtin:item"].on_step -- Remove any items thrown in trash can.
minetest.registered_entities["__builtin:item"].on_step = function(self, dtime) local old_on_step = minetest.registered_entities["__builtin:item"].on_step
local item_pos = self.object:getpos() minetest.registered_entities["__builtin:item"].on_step = function(self, dtime)
-- Round the values. Not essential, but makes logging look nicer. local item_pos = self.object:getpos()
for key, value in pairs(item_pos) do item_pos[key] = math.floor(value + 0.5) end -- Round the values. Not essential, but makes logging look nicer.
if minetest.get_node(item_pos).name == "trash_can:trash_can_wooden" then for key, value in pairs(item_pos) do item_pos[key] = math.floor(value + 0.5) end
local item_stack = ItemStack(self.itemstring) if minetest.get_node(item_pos).name == "trash_can:trash_can_wooden" then
local inv = minetest.get_inventory({type="node", pos=item_pos}) local item_stack = ItemStack(self.itemstring)
local leftover = inv:add_item("trashlist", item_stack) local inv = minetest.get_inventory({type="node", pos=item_pos})
if leftover:get_count() == 0 then local leftover = inv:add_item("trashlist", item_stack)
self.object:remove() if leftover:get_count() == 0 then
minetest.log("action", item_stack:to_string() .. self.object:remove()
" added to trash can at " .. minetest.pos_to_string(item_pos)) minetest.log("action", item_stack:to_string() ..
elseif item_stack:get_count() - leftover:get_count() ~= 0 then " added to trash can at " .. minetest.pos_to_string(item_pos))
self.set_item(self, leftover:to_string()) elseif item_stack:get_count() - leftover:get_count() ~= 0 then
minetest.log("action", item_stack:to_string() .. self.set_item(self, leftover:to_string())
" added to trash can at " .. minetest.pos_to_string(item_pos) .. minetest.log("action", item_stack:to_string() ..
" with " .. leftover:to_string() .. " left over" " added to trash can at " .. minetest.pos_to_string(item_pos) ..
) " with " .. leftover:to_string() .. " left over"
)
end
return
end end
return old_on_step(self, dtime)
end end
old_on_step(self, dtime)
end end

View File

@ -1 +1,3 @@
name = trash_can name = trash_can
description = This mod adds a wooden trash can, and a dumpster to the game. Right click it, put in your trash, and click the empty trash button.
optional_depends = default,mcl_core

View File

@ -0,0 +1,2 @@
# Requires some additional processing to check all items in the world each server step
trash_can_throw_in (Allow throwing trash into the trash can) bool true

View File

@ -4,7 +4,7 @@ by TenPlus1
Depends: Farming Redo Depends: Farming Redo
This mod adds a barrel used to ferment grapes into glasses of wine, 9 of which can then be crafted into a bottle of wine. It can also ferment honey into mead, barley into beer, wheat into weizen (wheat beer), and apples into cider. This mod adds a barrel used to ferment grapes into glasses of wine, 9 of which can then be crafted into a bottle of wine. It can also ferment honey into mead, barley into beer, wheat into weizen (wheat beer), corn into bourbon and apples into cider.
Change log: Change log:
@ -16,8 +16,19 @@ Change log:
- 0.6 - Added API so drinks can easily be added, also added wheat beer thanks to h-v-smacker and support for pipeworks/tubelib - 0.6 - Added API so drinks can easily be added, also added wheat beer thanks to h-v-smacker and support for pipeworks/tubelib
- 0.7 - Blue Agave now appears in desert areas and spreads very slowly, can me fermented into tequila - 0.7 - Blue Agave now appears in desert areas and spreads very slowly, can me fermented into tequila
- 0.8 - Barrel and Agave both use node timers now thanks to h-v-smacker, added sake - 0.8 - Barrel and Agave both use node timers now thanks to h-v-smacker, added sake
- 0.9 - Added Glass of Rum and Bottle of Rum thanks to acm :) Added {alcohol=1} groups
- 1.0 - Added glass and bottle or Bourbon made by fermenting corn
- 1.1 - Added glass and bottle of Vodka made by fermenting baked potato, Added MineClone2 support and spanish translation
- 1.2 - Added Unified Inventory support for barrel recipes (thanks to realmicu)
- 1.3 - Translations updated and French added thanks to TheDarkTiger
- 1.4 - Added bottle of beer and bottle of wheat beer (thanks Darkstalker for textures)
- 1.5 - Added bottle of sake (texture by Darkstalker), code tidy & tweaks, resized bottles and glasses, added some new lucky blocks, support for Thirst mod
- 1.6 - Added bottle of Mead, Cider and Mint-Julep (textures by Darkstalker),
re-arranged code, tweaked lucky blocks, updated translations
- 1.7 - Added more uses for blue agave (fuel, paper, food, agave syrup)
- 1.8 - Added glass and bottles for Champagne, Brandy and Coffee Liquor (thanks Felfa)
Lucky Blocks: 9 Lucky Blocks: 18
Wine Mod API Wine Mod API

View File

@ -1,5 +1,12 @@
default default?
intllib? intllib?
lucky_block? lucky_block?
pipeworks? pipeworks?
bonemeal? bonemeal?
mcl_core?
mcl_sounds?
mcl_loot?
doc?
unified_inventory?
thirsty?
farming?

View File

@ -1,9 +1,36 @@
wine = {} wine = {}
-- Intllib local def = minetest.get_modpath("default")
local snd_d = def and default.node_sound_defaults()
local snd_g = def and default.node_sound_glass_defaults()
local snd_l = def and default.node_sound_leaves_defaults()
local sand = "default:desert_sand"
-- check for MineClone2
local mcl = minetest.get_modpath("mcl_core")
if mcl then
snd_d = mcl_sounds.node_sound_glass_defaults()
snd_g = mcl_sounds.node_sound_defaults()
snd_l = mcl_sounds.node_sound_leaves_defaults()
sand = "mcl_core:sand"
end
-- check for Unified Inventory
local is_uninv = minetest.global_exists("unified_inventory") or false
-- is thirsty mod active
local thirsty_mod = minetest.get_modpath("thirsty")
-- Intllib support
local S local S
if minetest.get_modpath("intllib") then if minetest.get_translator then
S = minetest.get_translator("wine")
elseif minetest.get_modpath("intllib") then
S = intllib.Getter() S = intllib.Getter()
else else
S = function(s, a, ...) S = function(s, a, ...)
@ -23,248 +50,222 @@ else
end end
-- Unified Inventory hints
if is_uninv then
unified_inventory.register_craft_type("barrel", {
description = "Barrel",
icon = 'wine_barrel.png',
width = 1,
height = 1
})
end
local ferment = { local ferment = {
{"farming:grapes", "wine:glass_wine"}, {"farming:grapes", "wine:glass_wine"},
{"farming:barley", "wine:glass_beer"}, {"farming:barley", "wine:glass_beer"},
{"mobs:honey", "wine:glass_mead"}, {"mobs:honey", "wine:glass_mead"},
{"default:apple", "wine:glass_cider"}, {"default:apple", "wine:glass_cider"},
{"default:papyrus", "wine:glass_rum"},
{"wine:blue_agave", "wine:glass_tequila"}, {"wine:blue_agave", "wine:glass_tequila"},
{"farming:wheat", "wine:glass_wheat_beer"}, {"farming:wheat", "wine:glass_wheat_beer"},
{"farming:rice", "wine:glass_sake"}, {"farming:rice", "wine:glass_sake"},
{"xdecor:honey", "wine:glass_mead"}, {"farming:corn", "wine:glass_bourbon"},
{"farming:baked_potato", "wine:glass_vodka"},
{"farming:coffee_beans", "wine:glass_coffee_liquor"},
{"wine:glass_champagne_raw", "wine:glass_champagne"}
} }
function wine:add_item(list) if mcl then
ferment[4] = {"mcl_core:apple", "wine:glass_cider"}
ferment[5] = {"mcl_core:paper", "wine:glass_rum"}
end
for n = 1, #list do
table.insert(ferment, list[n]) if is_uninv then
for _, f in pairs(ferment) do
unified_inventory.register_craft({
type = "barrel",
items = {f[1]},
output = f[2]
})
end end
end end
-- glass of wine -- add item and resulting beverage to list
minetest.register_node("wine:glass_wine", { function wine:add_item(list)
description = S("Glass of Wine"),
drawtype = "plantlike",
visual_scale = 0.8,
tiles = {"wine_glass.png"},
inventory_image = "wine_glass.png",
wield_image = "wine_glass.png",
paramtype = "light",
is_ground_content = false,
sunlight_propagates = true,
walkable = false,
selection_box = {
type = "fixed",
fixed = {-0.2, -0.5, -0.2, 0.2, 0.3, 0.2}
},
groups = {food_wine = 1, vessel = 1, dig_immediate = 3, attached_node = 1},
sounds = default.node_sound_glass_defaults(),
on_use = minetest.item_eat(2),
})
-- bottle of wine for n = 1, #list do
minetest.register_node("wine:bottle_wine", {
description = S("Bottle of Wine"),
drawtype = "plantlike",
tiles = {"wine_bottle.png"},
inventory_image = "wine_bottle.png",
paramtype = "light",
sunlight_propagates = true,
walkable = false,
selection_box = {
type = "fixed",
fixed = { -0.15, -0.5, -0.15, 0.15, 0.25, 0.15 }
},
groups = {dig_immediate = 3, attached_node = 1, vessel = 1},
sounds = default.node_sound_defaults(),
})
table.insert(ferment, list[n])
if is_uninv then
unified_inventory.register_craft({
type = "barrel",
items = {list[n][1]},
output = list[n][2]
})
end
end
end
-- list of beverages (name, desc, has bottle, hunger, thirst)
local beverages = {
{"wine", "Wine", true, 2, 5},
{"beer", "Beer", true, 2, 8},
{"rum", "Rum", true, 2, 5},
{"tequila", "Tequila", true, 2, 3},
{"wheat_beer", "Wheat Beer", true, 2, 8},
{"sake", "Sake", true, 2, 3},
{"bourbon", "Bourbon", true, 2, 3},
{"vodka", "Vodka", true, 2, 3},
{"cider", "Cider", true, 2, 6},
{"mead", "Honey-Mead", true, 4, 5},
{"mint", "Mint Julep", true, 4, 3},
{"brandy", "Brandy", true, 3, 4},
{"coffee_liquor", "Coffee Liquor", true, 3, 4},
{"champagne", "Champagne", true, 4, 5}
}
-- create glasses and bottles
for n = 1, #beverages do
local name = beverages[n][1]
local desc = beverages[n][2]
local has_bottle = beverages[n][3]
local num_hunger = beverages[n][4]
local num_thirst = beverages[n][5]
-- glass
minetest.register_node("wine:glass_" .. name, {
description = S("Glass of " .. desc),
drawtype = "plantlike",
visual_scale = 0.5,
tiles = {"wine_" .. name .. "_glass.png"},
inventory_image = "wine_" .. name .. "_glass.png",
wield_image = "wine_" .. name .. "_glass.png",
paramtype = "light",
is_ground_content = false,
sunlight_propagates = true,
walkable = false,
selection_box = {
type = "fixed",
fixed = {-0.15, -0.5, -0.15, 0.15, 0, 0.15}
},
groups = {
vessel = 1, dig_immediate = 3,
attached_node = 1, alcohol = 1, drink = 1
},
sounds = snd_g,
on_use = function(itemstack, user, pointed_thing)
if user then
if thirsty_mod then
thirsty.drink(user, num_thirst)
end
return minetest.do_item_eat(num_hunger, nil,
itemstack, user, pointed_thing)
end
end
})
-- bottle
if has_bottle then
minetest.register_node("wine:bottle_" .. name, {
description = S("Bottle of " .. desc),
drawtype = "plantlike",
visual_scale = 0.7,
tiles = {"wine_" .. name .. "_bottle.png"},
inventory_image = "wine_" .. name .. "_bottle.png",
paramtype = "light",
sunlight_propagates = true,
walkable = false,
selection_box = {
type = "fixed",
fixed = {-0.15, -0.5, -0.15, 0.15, 0.25, 0.15}
},
groups = {dig_immediate = 3, attached_node = 1, vessel = 1},
sounds = snd_d,
})
local glass = "wine:glass_" .. name
minetest.register_craft({
output = "wine:bottle_" .. name,
recipe = {
{glass, glass, glass},
{glass, glass, glass},
{glass, glass, glass},
},
})
minetest.register_craft({
-- type = "shapeless",
output = glass .. " 9",
recipe = {{"wine:bottle_" .. name}}
})
end
end
-- brandy recipe
minetest.register_craft({ minetest.register_craft({
output = "wine:bottle_wine", type = "cooking",
recipe = { cooktime = 15,
{"wine:glass_wine", "wine:glass_wine", "wine:glass_wine"}, output = "wine:glass_brandy",
{"wine:glass_wine", "wine:glass_wine", "wine:glass_wine"}, recipe = "wine:glass_wine"
{"wine:glass_wine", "wine:glass_wine", "wine:glass_wine"},
},
})
minetest.register_craft({
type = "shapeless",
output = "wine:glass_wine 9",
recipe = {"wine:bottle_wine"},
}) })
-- glass of weizen, or wheat beer -- Raw champagne
-- The image is a lighter version of the one from RiverKpocc @ deviantart.com if minetest.get_modpath("farming")
minetest.register_node("wine:glass_wheat_beer", { and farming.mod and (farming.mod == "undo" or farming.mod == "redo") then
description = S("Wheat Beer"),
drawtype = "torchlike", --"plantlike", minetest.register_craftitem("wine:glass_champagne_raw", {
visual_scale = 0.8, description = "Raw Champagne",
tiles = {"wine_wheat_beer_glass.png"}, inventory_image = "wine_champagne_raw_glass.png",
inventory_image = "wine_wheat_beer_glass.png", groups = {vessel = 1, flammable = 3}
wield_image = "wine_wheat_beer_glass.png", })
paramtype = "light",
is_ground_content = false, minetest.register_craft({
sunlight_propagates = true, -- type = "shapeless",
walkable = false, output = "wine:glass_champagne_raw",
selection_box = { recipe = {
type = "fixed", {"wine:glass_wine", "farming:sugar"}
fixed = {-0.2, -0.5, -0.2, 0.2, 0.3, 0.2} }
}, })
groups = {food_beer = 1, vessel = 1, dig_immediate = 3, attached_node = 1}, end
sounds = default.node_sound_glass_defaults(),
on_use = minetest.item_eat(2),
-- override to add food group to wine and brandy glass
minetest.override_item("wine:glass_wine", {
groups = {
food_wine = 1, vessel = 1, dig_immediate = 3,
attached_node = 1, alcohol = 1, drink = 1
}
}) })
minetest.override_item("wine:glass_brandy", {
-- glass of beer (thanks to RiverKpocc @ deviantart.com for image) groups = {
minetest.register_node("wine:glass_beer", { food_brandy = 1, vessel = 1, dig_immediate = 3,
description = S("Beer"), attached_node = 1, alcohol = 1, drink = 1
drawtype = "torchlike", --"plantlike", }
visual_scale = 0.8,
tiles = {"wine_beer_glass.png"},
inventory_image = "wine_beer_glass.png",
wield_image = "wine_beer_glass.png",
paramtype = "light",
is_ground_content = false,
sunlight_propagates = true,
walkable = false,
selection_box = {
type = "fixed",
fixed = {-0.2, -0.5, -0.2, 0.2, 0.3, 0.2}
},
groups = {food_beer = 1, vessel = 1, dig_immediate = 3, attached_node = 1},
sounds = default.node_sound_glass_defaults(),
on_use = minetest.item_eat(2),
})
-- glass of honey mead
minetest.register_node("wine:glass_mead", {
description = S("Honey-Mead"),
drawtype = "plantlike",
visual_scale = 0.8,
tiles = {"wine_mead_glass.png"},
inventory_image = "wine_mead_glass.png",
wield_image = "wine_mead_glass.png",
paramtype = "light",
is_ground_content = false,
sunlight_propagates = true,
walkable = false,
selection_box = {
type = "fixed",
fixed = {-0.2, -0.5, -0.2, 0.2, 0.3, 0.2}
},
groups = {food_mead = 1, vessel = 1, dig_immediate = 3, attached_node = 1},
sounds = default.node_sound_glass_defaults(),
on_use = minetest.item_eat(4),
})
-- glass of apple cider
minetest.register_node("wine:glass_cider", {
description = S("Apple Cider"),
drawtype = "plantlike",
visual_scale = 0.8,
tiles = {"wine_cider_glass.png"},
inventory_image = "wine_cider_glass.png",
wield_image = "wine_cider_glass.png",
paramtype = "light",
is_ground_content = false,
sunlight_propagates = true,
walkable = false,
selection_box = {
type = "fixed",
fixed = {-0.2, -0.5, -0.2, 0.2, 0.3, 0.2}
},
groups = {food_cider = 1, vessel = 1, dig_immediate = 3, attached_node = 1},
sounds = default.node_sound_glass_defaults(),
on_use = minetest.item_eat(2),
})
-- glass of tequila
minetest.register_node("wine:glass_tequila", {
description = "Tequila",
drawtype = "plantlike",
visual_scale = 0.8,
tiles = {"wine_tequila.png"},
inventory_image = "wine_tequila.png",
wield_image = "wine_tequila.png",
paramtype = "light",
is_ground_content = false,
sunlight_propagates = true,
walkable = false,
selection_box = {
type = "fixed",
fixed = {-0.2, -0.5, -0.2, 0.2, 0.3, 0.2}
},
groups = {food_tequila = 1, vessel = 1, dig_immediate = 3, attached_node = 1},
sounds = default.node_sound_glass_defaults(),
on_use = minetest.item_eat(2),
})
-- bottle of tequila
minetest.register_node("wine:bottle_tequila", {
description = "Bottle of Tequila",
drawtype = "plantlike",
tiles = {"wine_tequila_bottle.png"},
inventory_image = "wine_tequila_bottle.png",
paramtype = "light",
sunlight_propagates = true,
walkable = false,
selection_box = {
type = "fixed",
fixed = { -0.15, -0.5, -0.15, 0.15, 0.25, 0.15 }
},
groups = {dig_immediate = 3, attached_node = 1, vessel = 1},
sounds = default.node_sound_defaults(),
})
minetest.register_craft({
output = "wine:bottle_tequila",
recipe = {
{"wine:glass_tequila", "wine:glass_tequila", "wine:glass_tequila"},
{"wine:glass_tequila", "wine:glass_tequila", "wine:glass_tequila"},
{"wine:glass_tequila", "wine:glass_tequila", "wine:glass_tequila"},
},
})
minetest.register_craft({
type = "shapeless",
output = "wine:glass_tequila 9",
recipe = {"wine:bottle_tequila"},
})
-- glass of sake
minetest.register_node("wine:glass_sake", {
description = "Sake",
drawtype = "plantlike",
visual_scale = 0.8,
tiles = {"wine_sake.png"},
inventory_image = "wine_sake.png",
wield_image = "wine_sake.png",
paramtype = "light",
is_ground_content = false,
sunlight_propagates = true,
walkable = false,
selection_box = {
type = "fixed",
fixed = {-0.2, -0.5, -0.2, 0.2, 0.3, 0.2}
},
groups = {food_sake = 1, vessel = 1, dig_immediate = 3, attached_node = 1},
sounds = default.node_sound_glass_defaults(),
on_use = minetest.item_eat(2),
}) })
-- blue agave -- blue agave
minetest.register_node("wine:blue_agave", { minetest.register_node("wine:blue_agave", {
description = "Blue Agave", description = S("Blue Agave"),
drawtype = "plantlike", drawtype = "plantlike",
visual_scale = 0.8, visual_scale = 0.8,
tiles = {"wine_blue_agave.png"}, tiles = {"wine_blue_agave.png"},
@ -279,7 +280,9 @@ minetest.register_node("wine:blue_agave", {
fixed = {-0.2, -0.5, -0.2, 0.2, 0.3, 0.2} fixed = {-0.2, -0.5, -0.2, 0.2, 0.3, 0.2}
}, },
groups = {snappy = 3, attached_node = 1, plant = 1}, groups = {snappy = 3, attached_node = 1, plant = 1},
sounds = default.node_sound_leaves_defaults(), sounds = snd_l,
on_use = minetest.item_eat(2),
on_construct = function(pos) on_construct = function(pos)
@ -310,7 +313,7 @@ minetest.register_node("wine:blue_agave", {
n = minetest.find_nodes_in_area_under_air( n = minetest.find_nodes_in_area_under_air(
{x = pos.x + 1, y = pos.y - 1, z = pos.z + 1}, {x = pos.x + 1, y = pos.y - 1, z = pos.z + 1},
{x = pos.x - 1, y = pos.y - 2, z = pos.z - 1}, {x = pos.x - 1, y = pos.y - 2, z = pos.z - 1},
{"default:desert_sand"}) {sand})
-- place blue agave -- place blue agave
if n and #n > 0 then if n and #n > 0 then
@ -326,35 +329,84 @@ minetest.register_node("wine:blue_agave", {
end end
}) })
-- blue agave into cyan dye
minetest.register_craft( { minetest.register_craft( {
type = "shapeless", -- type = "shapeless",
output = "dye:cyan 4", output = "dye:cyan 4",
recipe = {"wine:blue_agave"} recipe = {{"wine:blue_agave"}}
}) })
-- blue agave as fuel
minetest.register_craft({
type = "fuel",
recipe = "wine:blue_agave",
burntime = 10,
})
-- cook blue agave into a sugar syrup
minetest.register_craftitem("wine:agave_syrup", {
description = "Agave Syrup",
inventory_image = "wine_agave_syrup.png",
groups = {food_sugar = 1, vessel = 1, flammable = 3}
})
minetest.register_craft({
type = "cooking",
cooktime = 7,
output = "wine:agave_syrup 2",
recipe = "wine:blue_agave"
})
-- blue agave into paper
minetest.register_craft( {
output = "default:paper 3",
recipe = {
{"wine:blue_agave", "wine:blue_agave", "wine:blue_agave"},
}
})
-- register blue agave on mapgen
minetest.register_decoration({ minetest.register_decoration({
deco_type = "simple", deco_type = "simple",
place_on = {"default:desert_sand"}, place_on = {sand},
sidelen = 16, sidelen = 16,
fill_ratio = 0.001, fill_ratio = 0.001,
biomes = {"desert"}, biomes = {"desert"},
decoration = {"wine:blue_agave"}, decoration = {"wine:blue_agave"},
y_min = 15, y_min = 15,
y_max = 50, y_max = 50,
spawn_by = "default:desert_sand", spawn_by = sand,
num_spawn_by = 6, num_spawn_by = 6
}) })
-- add to bonemeal as decoration if available
if minetest.get_modpath("bonemeal") then if minetest.get_modpath("bonemeal") then
bonemeal:add_deco({ bonemeal:add_deco({
{"default:desert_sand", {}, {"default:dry_shrub", "wine:blue_agave", "", ""} } {sand, {}, {"default:dry_shrub", "wine:blue_agave", "", ""} }
}) })
end end
-- Wine barrel -- Mint Julep recipe
if minetest.get_modpath("farming")
and farming.mod and (farming.mod == "redo" or farming.mod == "undo") then
minetest.register_craft({
-- type = "shapeless",
output = "wine:glass_mint",
recipe = {
{"farming:mint_leaf", "farming:mint_leaf", "farming:mint_leaf"},
{"wine:glass_bourbon", "farming:sugar", ""}
}
})
end
-- Wine barrel formspec
winebarrel_formspec = "size[8,9]" winebarrel_formspec = "size[8,9]"
.. default.gui_bg..default.gui_bg_img..default.gui_slots
.. "list[current_name;src;2,1;1,1;]" .. "list[current_name;src;2,1;1,1;]"
.. "list[current_name;dst;5,1;1,1;]" .. "list[current_name;dst;5,1;1,1;]"
.. "list[current_player;main;0,5;8,4;]" .. "list[current_player;main;0,5;8,4;]"
@ -364,6 +416,8 @@ winebarrel_formspec = "size[8,9]"
.. "listring[current_player;main]" .. "listring[current_player;main]"
.. "image[3.5,1;1,1;gui_furnace_arrow_bg.png^[transformR270]" .. "image[3.5,1;1,1;gui_furnace_arrow_bg.png^[transformR270]"
-- Wine barrel node
minetest.register_node("wine:wine_barrel", { minetest.register_node("wine:wine_barrel", {
description = S("Fermenting Barrel"), description = S("Fermenting Barrel"),
tiles = {"wine_barrel.png" }, tiles = {"wine_barrel.png" },
@ -406,7 +460,8 @@ minetest.register_node("wine:wine_barrel", {
return true return true
end, end,
allow_metadata_inventory_take = function(pos, listname, index, stack, player) allow_metadata_inventory_take = function(
pos, listname, index, stack, player)
if minetest.is_protected(pos, player:get_player_name()) then if minetest.is_protected(pos, player:get_player_name()) then
return 0 return 0
@ -415,7 +470,8 @@ minetest.register_node("wine:wine_barrel", {
return stack:get_count() return stack:get_count()
end, end,
allow_metadata_inventory_put = function(pos, listname, index, stack, player) allow_metadata_inventory_put = function(
pos, listname, index, stack, player)
if minetest.is_protected(pos, player:get_player_name()) then if minetest.is_protected(pos, player:get_player_name()) then
return 0 return 0
@ -431,7 +487,8 @@ minetest.register_node("wine:wine_barrel", {
end end
end, end,
allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player) allow_metadata_inventory_move = function(
pos, from_list, from_index, to_list, to_index, count, player)
if minetest.is_protected(pos, player:get_player_name()) then if minetest.is_protected(pos, player:get_player_name()) then
return 0 return 0
@ -481,8 +538,9 @@ minetest.register_node("wine:wine_barrel", {
-- the default stack, from which objects will be taken -- the default stack, from which objects will be taken
input_inventory = "dst", input_inventory = "dst",
connect_sides = {left = 1, right = 1, back = 1, front = 1, bottom = 1, top = 1} connect_sides = {
} end end)(), left = 1, right = 1, back = 1,
front = 1, bottom = 1, top = 1} } end end)(),
on_timer = function(pos) on_timer = function(pos)
@ -542,14 +600,22 @@ minetest.register_node("wine:wine_barrel", {
end end
return true return true
end, end
}) })
-- wine barrel craft recipe (with mineclone2 check)
local ingot = "default:steel_ingot"
if mcl then
ingot = "mcl_core:iron_ingot"
end
minetest.register_craft({ minetest.register_craft({
output = "wine:wine_barrel", output = "wine:wine_barrel",
recipe = { recipe = {
{"group:wood", "group:wood", "group:wood"}, {"group:wood", "group:wood", "group:wood"},
{"default:steel_ingot", "", "default:steel_ingot"}, {ingot, "", ingot},
{"group:wood", "group:wood", "group:wood"}, {"group:wood", "group:wood", "group:wood"},
}, },
}) })
@ -585,19 +651,42 @@ minetest.register_lbm({
if minetest.get_modpath("lucky_block") then if minetest.get_modpath("lucky_block") then
lucky_block:add_blocks({ lucky_block:add_blocks({
{"fal", {"default:water_source"}, 1, true, 4},
{"dro", {"wine:glass_wine"}, 5}, {"dro", {"wine:glass_wine"}, 5},
{"dro", {"wine:glass_beer"}, 5}, {"dro", {"wine:glass_beer"}, 5},
{"dro", {"wine:glass_wheat_beer"}, 5}, {"dro", {"wine:glass_wheat_beer"}, 5},
{"dro", {"wine:glass_mead"}, 5}, {"dro", {"wine:glass_mead"}, 5},
{"dro", {"wine:glass_cider"}, 5}, {"dro", {"wine:glass_cider"}, 5},
{"dro", {"wine:glass_rum"}, 5},
{"dro", {"wine:glass_sake"}, 5},
{"dro", {"wine:glass_tequila"}, 5}, {"dro", {"wine:glass_tequila"}, 5},
{"dro", {"wine:glass_bourbon"}, 5},
{"dro", {"wine:glass_vodka"}, 5},
{"dro", {"wine:glass_mint"}, 5},
{"dro", {"wine:glass_coffee_liquor"}, 5},
{"dro", {"wine:glass_brandy"}, 5},
{"dro", {"wine:glass_champagne"}, 5},
{"dro", {"wine:wine_barrel"}, 1}, {"dro", {"wine:wine_barrel"}, 1},
{"tel", 5, 1}, {"tel", 5, 1},
{"nod", "default:chest", 0, { {"nod", "default:chest", 0, {
{name = "wine:bottle_wine", max = 1}, {name = "wine:bottle_wine", max = 1},
{name = "wine:bottle_tequila", max = 1}, {name = "wine:bottle_tequila", max = 1},
{name = "wine:bottle_rum", max = 1},
{name = "wine:bottle_cider", max = 1},
{name = "wine:bottle_bourbon", max = 1},
{name = "wine:bottle_vodka", max = 1},
{name = "wine:wine_barrel", max = 1},
{name = "wine:bottle_sake", max = 1},
{name = "wine:bottle_mint", max = 1},
{name = "wine:bottle_mead", max = 1},
{name = "wine:bottle_beer", max = 1},
{name = "wine:bottle_wheat_beer", max = 1},
{name = "wine:bottle_coffee_liquor", max = 1},
{name = "wine:bottle_brandy", max = 1},
{name = "wine:bottle_champagne", max = 1},
{name = "wine:blue_agave", max = 4}}}, {name = "wine:blue_agave", max = 4}}},
}) })
end end
print (S("[MOD] Wine loaded")) print (S("[MOD] Wine loaded"))

View File

@ -19,3 +19,28 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE. THE SOFTWARE.
Textures by TenPlus1 unless listed below (CC-By-3.0)
Mikhail Miroscnichenko @ dreamstime.com (royalty free license)
wine_bourbon_bottle.png
RiverKpocc @ deviantart.com
wine_beer_glass.png
wine_wheat_beer_glass.png
Textures by Darkstalker (cc-by-3.0 license)
wine_mint_bottle.png
wine_mint_glass.png
Textures by Darkstalker and edited by Felfa (cc-by-3.0 license)
wine_beer_bottle.png
wine_wheat_beer_bottle.png
wine_cider.bottle.png
wine_mead_bottle.png
Textures by Felfa (CC0)
wine_champagne*.png
wine_coffee*.png
wine_brandy*.png
wine_sake_bottle.png

View File

@ -1,14 +0,0 @@
# German Translation for wine mod
# Deutsche Übersetzung der wine Mod
# last update: 2016/May/26
# Author: Xanthin
Glass of Wine = Glas Wein
Bottle of Wine = Flasche Wein
Beer = Bier
Honey-Mead = Honigwein
Apple Cider = Apfelwein
Fermenting Barrel = Gärfass
Fermenting Barrel (FULL) = Gärfass (VOLL)
Fermenting Barrel (@1% Done) = Gärfass (@1% erledigt)
[MOD] Wine loaded = [MOD] Wine geladen

View File

@ -1,12 +1,33 @@
# Template for translations of wine mod # Template for translations of wine mod
# last update: 2016/May/26 # textdomain: wine
# author: ?
# last update: 2020/October/27
Glass of Wine = Glass of Wine=
Bottle of Wine = Bottle of Wine=
Beer = Glass of Beer=
Honey-Mead = Bottle of Beer=
Apple Cider = Glass of Rum=
Fermenting Barrel = Bottle of Rum=
Fermenting Barrel (FULL) = Glass of Tequila=
Fermenting Barrel (@1% Done) = Bottle of Tequila=
[MOD] Wine loaded = Glass of Wheat Beer=
Bottle of Wheat Beer=
Glass of Sake=
Bottle of Sake=
Glass of Bourbon=
Bottle of Bourbon=
Glass of Vodka=
Bottle of Vodka=
Glass of Cider=
Bottle of Cider=
Glass of Honey-Mead=
Bottle of Honey-Mead=
Glass of Mint Julep=
Bottle of Mint Julep=
Blue Agave=
Agave Syrup=
Fermenting Barrel=
Fermenting Barrel (FULL)=
Fermenting Barrel (@1% Done)=
[MOD] Wine loaded=

34
wine/locale/wine.de.tr Normal file
View File

@ -0,0 +1,34 @@
# Deutsche Übersetzung der wine Mod
# textdomain: wine
# author: Xanthin
# author: TheDarkTiger
# last update: 2020/October/27
Glass of Wine=Glas Wein
Bottle of Wine=Flasche Wein
Glass of Beer=Bier
Bottle of Beer=Flasche Bier
Glass of Rum=Rum
Bottle of Rum=Flasche Rum
Glass of Tequila=Tequila
Bottle of Tequila=Flasche Tequilla
Glass of Wheat Beer=Weizenbier
Bottle of Wheat Beer=Flasche Weizenbier
Glass of Sake=Sake
Bottle of Sake=Flasche Sake
Glass of Bourbon=Glas Bourbon
Bottle of Bourbon=Flasche Bourbon
Glass of Vodka=Glas Wodka
Bottle of Vodka=Flasche Wodka
Glass of Cider=Apfelwein
Bottle of Cider=Flasche Apfelwein
Glass of Honey-Mead=Honigwein
Bottle of Honey-Mead=Flasche Honigwein
Glass of Mint Julep=Minze Julep
Bottle of Mint Julep=Flasch Minze Julep
Blue Agave=Agave
Agave Syrup=Agavendicksaft
Fermenting Barrel=Gärfass
Fermenting Barrel (FULL)=Gärfass (VOLL)
Fermenting Barrel (@1% Done)=Gärfass (@1% erledigt)
[MOD] Wine loaded=[MOD] Wine geladen

35
wine/locale/wine.es.tr Normal file
View File

@ -0,0 +1,35 @@
# Traducción al español del mod Wine por TenPlus1
# textdomain: wine
# author: Unknown
# author: TenPlus1
# author: TheDarkTiger
# last update: 2020/October/27
Glass of Wine=Copa de vino
Bottle of Wine=Botella de vino
Glass of Beer=Cerveza
Bottle of Beer=Botella de Cerveza
Glass of Rum=Ron
Bottle of Rum=Botella de Ron
Glass of Tequila=Tequíla
Bottle of Tequila=Botella de Tequíla
Glass of Wheat Beer=Cerveza de Trigo
Bottle of Wheat Beer=Botella de Cerveza de Trigo
Glass of Sake=Sake
Bottle of Sake=Botella de Sake
Glass of Bourbon=Copa de Borbón
Bottle of Bourbon=Botella de Borbón
Glass of Vodka=Copa de Vodka
Bottle of Vodka=Botella de Vodka
Glass of Cider=Sidra de Manzana
Bottle of Cider=Botella de Sidra de Manzana
Glass of Honey-Mead=Bebida de Miel
Bottle of Honey-Mead=Botella de Bebida de Miel
Glass of Mint Julep=Julepe de menta
Bottle of Mint Julep=Botella de Julepe de menta
Blue Agave=Agave Tequilana
Agave Syrup=jarabe de agave
Fermenting Barrel=Barril de fermentación
Fermenting Barrel (FULL)=Barril de fermentación (Lleno)
Fermenting Barrel (@1% Done)=Barril de fermentación (@1% completado)
[MOD] Wine loaded=[MOD] Wine cargado

33
wine/locale/wine.fr.tr Normal file
View File

@ -0,0 +1,33 @@
# Traduction Française du mod Wine par TenPlus1
# textdomain: wine
# author: TheDarkTiger
# last update: 2020/October/27
Glass of Wine=Verre de Vin
Bottle of Wine=Bouteille de Vin
Glass of Beer=Bière
Bottle of Beer=Bouteille de Bière
Glass of Rum=Rhum
Bottle of Rum=Bouteille de Rhum
Glass of Tequila=Tequila
Bottle of Tequila=Bouteille de Tequila
Glass of Wheat Beer=Bière de Blé
Bottle of Wheat Beer=Bouteille de Bière de Blé
Glass of Sake=Saké
Bottle of Sake=Bouteille de Saké
Glass of Bourbon=Bourbon
Bottle of Bourbon=Bouteille de Bourbon
Glass of Vodka=Vodka
Bottle of Vodka=Bouteille de Vodka
Glass of Cider=Cidre
Bottle of Cider=Bouteille de Cidre
Glass of Honey-Mead=Hydromel
Bottle of Honey-Mead=Bouteille d'Hydromel
Glass of Mint Julep=Mint Julep
Bottle of Mint Julep=Bouteille de Mint Julep
Blue Agave=Agave Bleue
Agave Syrup=Sirop d'Agave
Fermenting Barrel=Baril de fermentation
Fermenting Barrel (FULL)=Baril de fermentation (PLEIN)
Fermenting Barrel (@1% Done)=Baril de fermentation (En cours @1%)
[MOD] Wine loaded=[MOD] Wine chargé

4
wine/mod.conf Normal file
View File

@ -0,0 +1,4 @@
name = wine
depends =
optional_depends = default, intllib, lucky_block, pipeworks, bonemeal, mcl_core, mcl_sounds, mcl_loot, doc, unified_inventory, thirsty, farming
description = Adds many alcoholic beverages and barrel to ferment them in.

Binary file not shown.

After

Width:  |  Height:  |  Size: 190 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 426 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 214 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 197 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 318 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 169 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 330 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 199 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 212 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 438 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 218 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 323 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 191 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 198 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 379 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 389 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 205 B

View File

Before

Width:  |  Height:  |  Size: 145 B

After

Width:  |  Height:  |  Size: 145 B

View File

Before

Width:  |  Height:  |  Size: 147 B

After

Width:  |  Height:  |  Size: 147 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 237 B

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