poikilos
8 years ago
committed by
Jacob Gustafson
2 changed files with 257 additions and 0 deletions
@ -0,0 +1,256 @@ |
|||
-- Minetest 0.4 mod: bones |
|||
-- See README.txt for licensing and other information. |
|||
|
|||
local function is_owner(pos, name) |
|||
local owner = minetest.get_meta(pos):get_string("owner") |
|||
if owner == "" or owner == name or minetest.check_player_privs(name, "protection_bypass") then |
|||
return true |
|||
end |
|||
return false |
|||
end |
|||
|
|||
local bones_formspec = |
|||
"size[8,9]" .. |
|||
default.gui_bg .. |
|||
default.gui_bg_img .. |
|||
default.gui_slots .. |
|||
"list[current_name;main;0,0.3;8,4;]" .. |
|||
"list[current_player;main;0,4.85;8,1;]" .. |
|||
"list[current_player;main;0,6.08;8,3;8]" .. |
|||
"listring[current_name;main]" .. |
|||
"listring[current_player;main]" .. |
|||
default.get_hotbar_bg(0,4.85) |
|||
|
|||
local share_bones_time = tonumber(minetest.setting_get("share_bones_time")) or 1200 |
|||
local share_bones_time_early = tonumber(minetest.setting_get("share_bones_time_early")) or share_bones_time / 4 |
|||
|
|||
minetest.register_node("bones:bones", { |
|||
description = "Bones", |
|||
tiles = { |
|||
"bones_top.png^[transform2", |
|||
"bones_bottom.png", |
|||
"bones_side.png", |
|||
"bones_side.png", |
|||
"bones_rear.png", |
|||
"bones_front.png" |
|||
}, |
|||
paramtype2 = "facedir", |
|||
groups = {dig_immediate = 2}, |
|||
sounds = default.node_sound_gravel_defaults(), |
|||
|
|||
can_dig = function(pos, player) |
|||
local inv = minetest.get_meta(pos):get_inventory() |
|||
local name = "" |
|||
if player then |
|||
name = player:get_player_name() |
|||
end |
|||
return is_owner(pos, name) and inv:is_empty("main") |
|||
end, |
|||
|
|||
allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player) |
|||
if is_owner(pos, player:get_player_name()) then |
|||
return count |
|||
end |
|||
return 0 |
|||
end, |
|||
|
|||
allow_metadata_inventory_put = function(pos, listname, index, stack, player) |
|||
return 0 |
|||
end, |
|||
|
|||
allow_metadata_inventory_take = function(pos, listname, index, stack, player) |
|||
if is_owner(pos, player:get_player_name()) then |
|||
return stack:get_count() |
|||
end |
|||
return 0 |
|||
end, |
|||
|
|||
on_metadata_inventory_take = function(pos, listname, index, stack, player) |
|||
local meta = minetest.get_meta(pos) |
|||
if meta:get_inventory():is_empty("main") then |
|||
minetest.remove_node(pos) |
|||
end |
|||
end, |
|||
|
|||
on_punch = function(pos, node, player) |
|||
if not is_owner(pos, player:get_player_name()) then |
|||
return |
|||
end |
|||
|
|||
if minetest.get_meta(pos):get_string("infotext") == "" then |
|||
return |
|||
end |
|||
|
|||
local inv = minetest.get_meta(pos):get_inventory() |
|||
local player_inv = player:get_inventory() |
|||
local has_space = true |
|||
|
|||
for i = 1, inv:get_size("main") do |
|||
local stk = inv:get_stack("main", i) |
|||
if player_inv:room_for_item("main", stk) then |
|||
inv:set_stack("main", i, nil) |
|||
player_inv:add_item("main", stk) |
|||
else |
|||
has_space = false |
|||
break |
|||
end |
|||
end |
|||
|
|||
-- remove bones if player emptied them |
|||
if has_space then |
|||
if player_inv:room_for_item("main", {name = "bones:bones"}) then |
|||
player_inv:add_item("main", {name = "bones:bones"}) |
|||
else |
|||
minetest.add_item(pos,"bones:bones") |
|||
end |
|||
minetest.remove_node(pos) |
|||
end |
|||
end, |
|||
|
|||
on_timer = function(pos, elapsed) |
|||
local meta = minetest.get_meta(pos) |
|||
local time = meta:get_int("time") + elapsed |
|||
if time >= share_bones_time then |
|||
meta:set_string("infotext", meta:get_string("owner") .. "'s old bones") |
|||
meta:set_string("owner", "") |
|||
else |
|||
meta:set_int("time", time) |
|||
return true |
|||
end |
|||
end, |
|||
on_blast = function(pos) |
|||
end, |
|||
}) |
|||
|
|||
local function may_replace(pos, player) |
|||
local node_name = minetest.get_node(pos).name |
|||
local node_definition = minetest.registered_nodes[node_name] |
|||
|
|||
-- if the node is unknown, we return false |
|||
if not node_definition then |
|||
return false |
|||
end |
|||
|
|||
-- allow replacing air and liquids |
|||
if node_name == "air" or node_definition.liquidtype ~= "none" then |
|||
return true |
|||
end |
|||
|
|||
-- don't replace filled chests and other nodes that don't allow it |
|||
local can_dig_func = node_definition.can_dig |
|||
if can_dig_func and not can_dig_func(pos, player) then |
|||
return false |
|||
end |
|||
|
|||
-- default to each nodes buildable_to; if a placed block would replace it, why shouldn't bones? |
|||
-- flowers being squished by bones are more realistical than a squished stone, too |
|||
-- exception are of course any protected buildable_to |
|||
return node_definition.buildable_to and not minetest.is_protected(pos, player:get_player_name()) |
|||
end |
|||
|
|||
local drop = function(pos, itemstack) |
|||
local obj = minetest.add_item(pos, itemstack:take_item(itemstack:get_count())) |
|||
if obj then |
|||
obj:setvelocity({ |
|||
x = math.random(-10, 10) / 9, |
|||
y = 5, |
|||
z = math.random(-10, 10) / 9, |
|||
}) |
|||
end |
|||
end |
|||
|
|||
minetest.register_on_dieplayer(function(player) |
|||
|
|||
local bones_mode = minetest.setting_get("bones_mode") or "bones" |
|||
if bones_mode ~= "bones" and bones_mode ~= "drop" and bones_mode ~= "keep" then |
|||
bones_mode = "bones" |
|||
end |
|||
|
|||
-- return if keep inventory set or in creative mode |
|||
if bones_mode == "keep" or minetest.setting_getbool("creative_mode") then |
|||
print(player:get_player_name() .. "'s bones do not remain since in creative_mode -- died at " .. minetest.pos_to_string(vector.round(player:getpos()))) |
|||
minetest.chat_send_player(player:get_player_name(), player:get_player_name() .. "'s bones do not remain since in creative_mode -- died at " .. minetest.pos_to_string(pos)) --formerly ("Bones placed at %s."):format(pos) |
|||
return |
|||
end |
|||
|
|||
local player_inv = player:get_inventory() |
|||
if player_inv:is_empty("main") and |
|||
player_inv:is_empty("craft") then |
|||
print(player:get_player_name() .. "'s bones do not remain since inventory and craft are empty -- died at " .. minetest.pos_to_string(vector.round(player:getpos()))) |
|||
minetest.chat_send_player(player:get_player_name(), player:get_player_name() .. "'s bones do not remain since inventory and craft are empty -- died at " .. minetest.pos_to_string(pos)) --formerly ("Bones placed at %s."):format(pos) |
|||
return |
|||
end |
|||
|
|||
local pos = vector.round(player:getpos()) |
|||
local player_name = player:get_player_name() |
|||
|
|||
-- check if it's possible to place bones, if not find space near player |
|||
if bones_mode == "bones" and not may_replace(pos, player) then |
|||
local air = minetest.find_node_near(pos, 1, {"air"}) |
|||
if air and not minetest.is_protected(air, player_name) then |
|||
pos = air |
|||
else |
|||
bones_mode = "drop" |
|||
end |
|||
end |
|||
|
|||
if bones_mode == "drop" then |
|||
|
|||
-- drop inventory items |
|||
for i = 1, player_inv:get_size("main") do |
|||
drop(pos, player_inv:get_stack("main", i)) |
|||
end |
|||
player_inv:set_list("main", {}) |
|||
|
|||
-- drop crafting grid items |
|||
for i = 1, player_inv:get_size("craft") do |
|||
drop(pos, player_inv:get_stack("craft", i)) |
|||
end |
|||
player_inv:set_list("craft", {}) |
|||
|
|||
drop(pos, ItemStack("bones:bones")) |
|||
print(player:get_player_name() .. "'s bones do not remain since area is_protected -- died at " .. minetest.pos_to_string(pos)) |
|||
minetest.chat_send_player(player:get_player_name(), player:get_player_name() .. "'s do not remain since area is_protected -- died at " .. minetest.pos_to_string(pos)) --formerly ("Bones placed at %s."):format(pos) |
|||
return |
|||
end |
|||
|
|||
local param2 = minetest.dir_to_facedir(player:get_look_dir()) |
|||
minetest.set_node(pos, {name = "bones:bones", param2 = param2}) |
|||
print(player:get_player_name() .. "'s bones remain where died at " .. minetest.pos_to_string(pos)) |
|||
minetest.chat_send_player(player:get_player_name(), player:get_player_name() .. "'s bones remain where died at " .. minetest.pos_to_string(pos)) --formerly ("Bones placed at %s."):format(pos) |
|||
|
|||
local meta = minetest.get_meta(pos) |
|||
local inv = meta:get_inventory() |
|||
inv:set_size("main", 8 * 4) |
|||
inv:set_list("main", player_inv:get_list("main")) |
|||
|
|||
for i = 1, player_inv:get_size("craft") do |
|||
local stack = player_inv:get_stack("craft", i) |
|||
if inv:room_for_item("main", stack) then |
|||
inv:add_item("main", stack) |
|||
else |
|||
--drop if no space left |
|||
drop(pos, stack) |
|||
end |
|||
end |
|||
|
|||
player_inv:set_list("main", {}) |
|||
player_inv:set_list("craft", {}) |
|||
|
|||
meta:set_string("formspec", bones_formspec) |
|||
meta:set_string("owner", player_name) |
|||
|
|||
if share_bones_time ~= 0 then |
|||
meta:set_string("infotext", player_name .. "'s fresh bones") |
|||
|
|||
if share_bones_time_early == 0 or not minetest.is_protected(pos, player_name) then |
|||
meta:set_int("time", 0) |
|||
else |
|||
meta:set_int("time", (share_bones_time - share_bones_time_early)) |
|||
end |
|||
|
|||
minetest.get_node_timer(pos):start(10) |
|||
else |
|||
meta:set_string("infotext", player_name.."'s bones") |
|||
end |
|||
end) |
Loading…
Reference in new issue