init
commit
ee7bf1a1a3
|
@ -0,0 +1 @@
|
|||
bones
|
|
@ -0,0 +1,205 @@
|
|||
-- boneworld by rnd, 2016
|
||||
|
||||
-- for more interesting bone gameplay:
|
||||
|
||||
-- you no longer get extra bones if you pick bones from player with same ip address (no suicide bone farming)
|
||||
-- each player has experience points (xp)
|
||||
-- when you die you loose 20% of your xp, half of that is stored in bones
|
||||
-- when you kill other player you get 10% of his xp
|
||||
-- if you pick up bones you get xp stored in bones
|
||||
-- if you pick up other player bones you get 20% of average of your and bone owner xp award in extra bones (for example if you have 10 xp and you kill a noob you will get 2 bones instead of normally 1)
|
||||
|
||||
|
||||
local worldpath = minetest.get_worldpath();
|
||||
os.execute( "mkdir "..worldpath.. "\\boneworld") -- directory used to save xp data
|
||||
local boneworld = {};
|
||||
boneworld.xp = {};
|
||||
|
||||
|
||||
|
||||
--local share_bones_time = tonumber(minetest.setting_get("share_bones_time")) or 1200
|
||||
local share_bones_time = tonumber(minetest.setting_get("share_bones_time")) or 20;
|
||||
local share_bones_time_early = tonumber(minetest.setting_get("share_bones_time_early")) or share_bones_time / 4
|
||||
|
||||
|
||||
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 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 (died ".. meta:get_string("date") .."), xp " .. meta:get_float("xp"));
|
||||
meta:set_string("owner", "")
|
||||
|
||||
else
|
||||
if meta:get_int("active") == 0 then -- store data in bones, 1x
|
||||
meta:set_int("active",1);
|
||||
local owner = meta:get_string("owner");
|
||||
meta:set_string("date",os.date("%x"));
|
||||
meta:set_string("owner_orig",owner);
|
||||
meta:set_string("ip", tostring(minetest.get_player_ip(owner)));
|
||||
meta:set_float("xp", math.floor((boneworld.xp[owner]*1.25*0.1)*10)/10); -- xp stored in bones
|
||||
meta:set_string("infotext"," Here lies " .. owner .. ", xp " .. meta:get_float("xp"));
|
||||
end
|
||||
meta:set_int("time", time)
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
local 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
|
||||
local meta = minetest.get_meta(pos);
|
||||
local active = meta:get_int("active") == 1;
|
||||
local puncher = player:get_player_name();
|
||||
|
||||
-- award extra bones if you collect bones from different ip player
|
||||
--debug
|
||||
if active and meta:get_string("ip")~= tostring(minetest.get_player_ip(puncher)) then
|
||||
|
||||
-- average of owners xp (at time of death) and puncher xp will be awarded as extra bones
|
||||
-- with every 5 more average one bone
|
||||
local count = math.max(1,0.2*(10*meta:get_float("xp")+boneworld.xp[puncher])/2.0);
|
||||
count = math.floor(count);
|
||||
minetest.chat_send_player(puncher, "#bones: you find " .. count .. " extra bones in the corpse ");
|
||||
|
||||
if player_inv:room_for_item("main", ItemStack("bones:bones "..count)) then
|
||||
player_inv:add_item("main", ItemStack("bones:bones "..count))
|
||||
else
|
||||
minetest.add_item(pos,ItemStack("bones:bones "..count))
|
||||
end
|
||||
end
|
||||
|
||||
-- add xp from bones
|
||||
boneworld.xp[puncher] = math.floor((boneworld.xp[puncher] + meta:get_float("xp"))*10)/10;
|
||||
minetest.remove_node(pos)
|
||||
end
|
||||
end
|
||||
|
||||
-- award xp to killer
|
||||
minetest.register_on_punchplayer(
|
||||
function(player, hitter, time_from_last_punch, tool_capabilities, dir, damage)
|
||||
local hp = player:get_hp();
|
||||
|
||||
if hp>0 and hp-damage<=0 then -- hitter killed player
|
||||
local pname = player:get_player_name();
|
||||
local hname = hitter:get_player_name();
|
||||
|
||||
--award xp if you kill different ip player, 10% of his xp
|
||||
--debug
|
||||
if minetest.get_player_ip(pname)~=minetest.get_player_ip(hname) then
|
||||
local pxp = boneworld.xp[pname];
|
||||
local addxp = math.floor(pxp*0.1*10)/10;
|
||||
boneworld.xp[hname] = math.floor(boneworld.xp[hname]*10)/10 + addxp;
|
||||
minetest.chat_send_player(hname, "#You killed " .. pname .. ". As a reward you get ".. addxp .. " experience.");
|
||||
end
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
-- 20% of xp is lost upon death
|
||||
minetest.register_on_dieplayer(
|
||||
function(player)
|
||||
local name = player:get_player_name();
|
||||
local lossxp = boneworld.xp[name];
|
||||
minetest.chat_send_player(name, "#You lost ".. lossxp*0.2 .. " experience. Retrieve your bones to get 50% of lost experience back ");
|
||||
boneworld.xp[name] = math.floor(lossxp*0.8*10)/10;
|
||||
end
|
||||
)
|
||||
|
||||
|
||||
-- load xp
|
||||
minetest.register_on_joinplayer(
|
||||
function(player)
|
||||
local name = player:get_player_name();
|
||||
if not boneworld.xp[name] then -- load xp
|
||||
local filename = worldpath .. "\\boneworld\\" .. name..".xp";
|
||||
local f = io.open(filename, "r");
|
||||
if not f then -- file does not yet exist
|
||||
boneworld.xp[name] = 1;
|
||||
return
|
||||
end
|
||||
boneworld.xp[name] = f:read("*a") or 1;
|
||||
f:close();
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
-- save xp
|
||||
minetest.register_on_leaveplayer(
|
||||
function(player)
|
||||
local name = player:get_player_name();
|
||||
local xp = boneworld.xp[name];
|
||||
if true then --xp > 1.5 then -- save xp for serious players only -- must have killed at least 5 noobs
|
||||
local filename = worldpath .. "\\boneworld\\" .. name..".xp";
|
||||
|
||||
local f = io.open(filename, "w");
|
||||
if not f then return end
|
||||
f:write(xp);
|
||||
f:close();
|
||||
else
|
||||
-- dont save, player didnt do anything
|
||||
end
|
||||
end
|
||||
|
||||
)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
local tweak_bones = function()
|
||||
local name = "bones:bones";
|
||||
local table = minetest.registered_nodes[name];
|
||||
table.on_punch = on_punch;
|
||||
table.on_timer = on_timer;
|
||||
minetest.register_node(":"..name, table);
|
||||
end
|
||||
|
||||
minetest.after(0,tweak_bones);
|
||||
|
||||
minetest.register_chatcommand("xp", {
|
||||
description = "xp name - show experience of target player",
|
||||
privs = {
|
||||
interact = true
|
||||
},
|
||||
func = function(name, param)
|
||||
if param == "" then
|
||||
msg = "xp name - show experience of target player"
|
||||
else
|
||||
|
||||
msg = "# "..param .. " has " .. boneworld.xp[param] .. " experience";
|
||||
end
|
||||
minetest.chat_send_player(name, msg);
|
||||
end
|
||||
});
|
Loading…
Reference in New Issue