- thief xp
- gloves: can be used for stealing stuff, slowing other player or cloaking name
master
rnd1 2017-01-05 13:46:40 +01:00
parent c102d51b2b
commit 20f3cac9e7
7 changed files with 432 additions and 44 deletions

73
acid.lua Normal file
View File

@ -0,0 +1,73 @@
-- code borrowed from carbone mod by Calinou
minetest.register_node("boneworld:acid_flowing_active", {
description = "Flowing Acid",
inventory_image = minetest.inventorycube("mymod_acid.png"),
drawtype = "flowingliquid",
tiles = {"mymod_acid.png"},
special_tiles = {
{
image = "mymod_acid_flowing_animated.png",
backface_culling=false,
animation={type = "vertical_frames", aspect_w= 16, aspect_h = 16, length = 0.6}
},
{
image = "mymod_acid_flowing_animated.png",
backface_culling=true,
animation={type = "vertical_frames", aspect_w= 16, aspect_h = 16, length = 0.6}
},
},
alpha = WATER_ALPHA,
paramtype = "light",
param1 = 0,
light_source = 0,
paramtype2 = "flowingliquid",
walkable = false,
pointable = false,
diggable = false,
buildable_to = false, -- now you cant build over it, only the source..
drop = "",
drowning = 2,
liquidtype = "flowing",
liquid_alternative_flowing = "boneworld:acid_flowing_active",
liquid_alternative_source = "boneworld:acid_source_active",
liquid_viscosity = WATER_VISC,
damage_per_second = 5,
post_effect_color = {a = 120, r = 50, g = 90, b = 30},
groups = {water = 3, acid = 3, liquid = 3, puts_out_fire = 1, not_in_creative_inventory = 1},
})
minetest.register_node("boneworld:acid_source_active", {
description = "Acid Source",
inventory_image = minetest.inventorycube("mymod_acid.png"),
drawtype = "liquid",
tiles = {
{name = "mymod_acid_source_animated.png", animation={type = "vertical_frames", aspect_w = 16, aspect_h = 16, length = 1.5}}
},
special_tiles = {
-- New-style acid source material (mostly unused)
{
name = "mymod_acid_source_animated.png",
animation = {type = "vertical_frames", aspect_w= 16, aspect_h = 16, length = 1.5},
backface_culling = false,
}
},
alpha = WATER_ALPHA,
paramtype = "light",
param1 = 0,
light_source = 0,
walkable = false,
pointable = false,
diggable = true,
buildable_to = false, -- only fireball destroys it
drop = "",
drowning = 2,
liquidtype = "source",
liquid_alternative_flowing = "boneworld:acid_flowing_active",
liquid_alternative_source = "boneworld:acid_source_active",
liquid_viscosity = WATER_VISC,
damage_per_second = 8,
post_effect_color = {a = 120, r = 50, g = 90, b = 30},
groups = {water = 3, acid = 3, liquid = 3, puts_out_fire = 1},
})

205
gloves.lua Normal file
View File

@ -0,0 +1,205 @@
----------------------------------------------------
-- GLOVES FOR STEALING
local stealt = {};
minetest.register_tool("boneworld:gloves", {
description = "thief gloves",
inventory_image = "stealgloves.png",
tool_capabilities = {
full_punch_interval = 2,
},
on_use = function(itemstack, user, pointed_thing)
local player1 = user;
local name = player1:get_player_name();
if not pointed_thing.type == "object" then return end
local player2 = pointed_thing.ref;
local pjump = player1:get_player_control().jump
if not player2 then
if not pjump then -- CLOAK
local t = minetest.get_gametime();
if not stealt[name] then stealt[name]={t,0,"",{},t-20}; end -- time, state, target name, target position, cloak time
local data = stealt[name];
if (t - data[5])<20 then
minetest.chat_send_player(name,"#THIEF: wait " .. 20 -(t-data[5]) .. " s before cloaking ");
return
end
data[5]=t;
local ncolor = player1:get_nametag_attributes().color;
player1:set_nametag_attributes({color = "0x0"});
local cloaktime = 7+14*boneworld.thiefxp[name]/10;
if cloaktime>19 then cloaktime = 19 end
minetest.chat_send_player(name,"#THIEF: cloak engaged for " .. math.floor(10*cloaktime)/10 .. " s");
minetest.after(cloaktime, function() -- decloak
player1:set_nametag_attributes({color = ncolor})
minetest.chat_send_player(name,"#THIEF: decloaking");
end)
end
return
end
if not player2:is_player() then return end
if pjump then -- SLOW
local speed0 = player2:get_physics_override().speed;
if speed0<0.8 then return end -- normal player speed
player2:set_physics_override({speed=0.33*speed0});
minetest.chat_send_player(name,"#THIEF: target slowed down for 10 s");
minetest.after(10, function() player2:set_physics_override({speed=speed0}); end)
return
end
local pos1 = player1:getpos();
local pos2 = player2:getpos();
local t = minetest.get_gametime();
if not stealt[name] then stealt[name]={t,0,"",{},t}; end -- time, state, target name, target position, cloak time
local data = stealt[name];
local v = {x=pos2.x-pos1.x,y=pos2.y-pos1.y,z=pos2.z-pos1.z};
local vm = math.sqrt(v.x^2+v.y^2+v.z^2);
if vm~=0 then v.x=v.x/vm; v.y=v.y/vm; v.z=v.z/vm end
local caught = false;
if data[2]==0 then -- init
local dir2 = player2:get_look_dir();
if v.x*dir2.x+v.z*dir2.z<=0.5 then caught = true end
if not caught then
minetest.chat_send_player(name,"#STEALING: attempting to steal. Stand behind player, wait for 5s and then use gloves again.")
data[3] = player2:get_player_name();
data[4] = pos2;
data[1] = t;
data[2]=1;
end
elseif data[2] == 1 then -- stealing second step
local pos20 = data[4];
if (pos20.x-pos2.x)^2 +(pos20.z-pos2.z)^2>4 then
--if pos20.x~=pos2.x or pos20.z~=pos2.z then
minetest.chat_send_player(name,"#STEALING: aborting. target moved.")
data[2]=0
return
end
if t-data[1]<5 then return end -- too soon
if t-data[1]>10 then data[2]=0 return end -- timeout
data[2]=0
local dir2 = player2:get_look_dir();
if v.x*dir2.x+v.z*dir2.z<=0.5 then caught = true end
if not caught then -- display inventory of items from target hands
local selected = 1;
local inv = player2:get_inventory();
local textlist = "";
for i = 1,8 do
textlist = textlist .. inv:get_stack("main", i):get_name() ..",";
end
local form = "size [3,2.5]"..
"label[0,-0.4;Select item to steal]"..
"textlist[0,0;2.8,2.6;craft;" .. textlist .. ";" .. selected .."]";
minetest.show_formspec(name, "stealform", form)
--local sel = tonumber(string.sub(fields.craft,5)) or 1
else
local xp = boneworld.thiefxp[name];
xp=xp-0.5; if xp<0 then xp = 0 end
boneworld.thiefxp[name]=xp;
minetest.chat_send_all("#THIEF "..name .. " tried to steal from " .. data[3] .. " but was caught ")
end
end
end,
})
-- STEALING: final step
minetest.register_on_player_receive_fields(
function(player, formname, fields)
if formname == "stealform" then
if fields.craft then
if string.sub(fields.craft,1,3)=="DCL" then
local sel = tonumber(string.sub(fields.craft,5));
if not sel then return end
local name = player:get_player_name();
local data= stealt[name];
if not data then return end
data[2]=0
local tname = data[3];
local player2 = minetest.get_player_by_name(tname);
if not player2 then return end
local pos1 = player:getpos();
local pos2 = player2:getpos();
local v = {x=pos2.x-pos1.x,y=pos2.y-pos1.y,z=pos2.z-pos1.z};
local pos20 = data[4];
if (pos20.x-pos2.x)^2 +(pos20.z-pos2.z)^2>4 then
local text = "stealing aborted. target moved too far";
local form = "size [6,2] textarea[0,0;6.5,3.5;stealform1;THIEF;".. text.."]"
minetest.show_formspec(name, "stealfom1", form)
return
end
local privs = minetest.get_player_privs(tname);
if privs.privs then return end -- no stealing from admin
local tinv = player2:get_inventory();
local inv = player:get_inventory();
local txp = boneworld.thiefxp[tname]; -- steal xp from victim
if not txp then txp = 0.1 elseif txp<0.1 then txp = 0.1 end
boneworld.thiefxp[tname] = txp - 0.1;
local item = tinv:get_stack("main", sel):get_name();
if item == "" then return end
local dir2 = player2:get_look_dir();
if v.x*dir2.x+v.z*dir2.z<=0.5 then
minetest.chat_send_all("#THIEF: " .. name .. " has been caught trying to steal " .. item .. " from " .. tname)
local xp = boneworld.thiefxp[name];
xp=xp-0.5; if xp<0 then xp = 0 end
boneworld.thiefxp[name]=xp;
return
end
tinv:remove_item("main", ItemStack(item));
inv:add_item("main",ItemStack(item));
boneworld.thiefxp[name] = boneworld.thiefxp[name] + 0.1;
local text = "#THIEF: successfuly stole " .. item;
minetest.after(15, function() minetest.chat_send_all("#THIEF: someone has been robbed of " .. item) end);
local form = "size [6,2] textarea[0,0;6.5,3.5;stealform1;THIEF;".. text.."]"
minetest.show_formspec(name, "stealfom1", form)
end
end
end
end
)
minetest.register_craft({
output = "boneworld:gloves",
recipe = {
{"default:diamondblock","default:goldblock","wool:white"},
}
})
---------------------------------------------

198
init.lua
View File

@ -9,15 +9,25 @@
-- 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 pick noob bone will get 2 bones instead of normally 1)
local version = "10/22/16"
dofile(minetest.get_modpath("boneworld").."/acid.lua") -- acid surprise when mining :)
dofile(minetest.get_modpath("boneworld").."/gloves.lua") -- acid surprise when mining :)
local version = "12/18/16"
local worldpath = minetest.get_worldpath();
--os.execute( "mkdir "..worldpath.. "\\boneworld")
minetest.mkdir(worldpath .. "\\boneworld") -- directory used to save xp data
boneworld = {};
boneworld.xp = {}; -- [name] = bonexp, bone collect xp
boneworld.digxp = {}; -- [name] = xp, mining xp
boneworld.thiefxp = {};
boneworld.killxp = {};
boneworld.bounty = {}; --[name]=1
boneworld.protect = {}; -- [name] = {timer, position}: time of last dig in unprotected area, position
@ -75,7 +85,16 @@ local on_timer = function(pos, elapsed)
end
boneworld.wastedxp = boneworld.wastedxp + meta:get_float("xp");
meta:set_string("infotext"," Here lies " .. owner .. ", bone xp " .. math.floor(meta:get_float("xp")*100)/100);
if boneworld.bounty[owner] then
meta:set_string("owner","");
meta:set_string("infotext"," Here lies the KILLER " .. owner .. ", bone xp " .. math.floor(meta:get_float("xp")*100)/100 .. ". get his bones !");
else
meta:set_string("infotext"," Here lies " .. owner .. ", bone xp " .. math.floor(meta:get_float("xp")*100)/100);
end
end
@ -143,6 +162,12 @@ local on_punch = function(pos, node, player)
boneworld.wastedxp = boneworld.wastedxp - meta:get_float("xp");
end
local owner_orig = meta:get_string("owner_orig")
if boneworld.bounty[owner_orig] and owner_orig~="" and owner_orig~= puncher then
boneworld.bounty[owner_orig]=false;
minetest.chat_send_all("*** BOUNTY *** for killer " .. owner_orig .. " has been cleared ! ")
end
minetest.remove_node(pos)
end
@ -159,6 +184,9 @@ minetest.register_on_joinplayer(
if not f then -- file does not yet exist
boneworld.xp[name] = 1;
boneworld.digxp[name] = 0;
boneworld.thiefxp[name] = 0;
boneworld.killxp[name] = 0;
else
local str = f:read("*a") or 1;
local words = {};
@ -167,6 +195,8 @@ minetest.register_on_joinplayer(
end
boneworld.xp[name] = tonumber(words[1] or 1);
boneworld.digxp[name] = tonumber(words[2] or 0);
boneworld.thiefxp[name] = tonumber(words[3] or 0);
boneworld.killxp[name] = tonumber(words[4] or 0);
f:close();
end
end
@ -186,13 +216,16 @@ minetest.register_on_leaveplayer(
local name = player:get_player_name();
local bonexp = boneworld.xp[name] or 1;
local digxp = boneworld.digxp[name] or 0;
local thiefxp = boneworld.thiefxp[name] or 0;
local killxp = boneworld.killxp[name] or 0;
--debug
if bonexp > 2 or digxp>1 then -- save xp for serious players only
if bonexp > 1.5 or digxp>0.25 then -- save xp for serious players only
local filename = worldpath .. "\\boneworld\\" .. name..".xp";
local f = io.open(filename, "w");
if not f then return end
f:write(bonexp .. " " .. digxp);
f:write(bonexp .. " " .. digxp .. " " .. thiefxp .. " " .. killxp );
f:close();
else
-- dont save, player didnt do anything
@ -201,6 +234,37 @@ minetest.register_on_leaveplayer(
)
boneworld.save_xp = function(player)
if not player then return end
local name = player:get_player_name();
local bonexp = boneworld.xp[name] or 1;
local digxp = boneworld.digxp[name] or 0;
local thiefxp = boneworld.thiefxp[name] or 0;
--debug
if bonexp > 1.5 or digxp>0.25 then -- save xp for serious players only
local filename = worldpath .. "\\boneworld\\" .. name..".xp";
local f = io.open(filename, "w");
if not f then return end
f:write(bonexp .. " " .. digxp .. " " .. thiefxp );
f:close();
else
-- dont save, player didnt do anything
end
end
boneworld.save_all_xp = function()
local players = minetest.get_connected_players();
for _,player in pairs(players) do
boneworld.save_xp(player)
end
end
minetest.register_on_leaveplayer(boneworld.save_xp)
minetest.register_on_shutdown(boneworld.save_all_xp)
minetest.register_on_dieplayer( -- -1 bone xp each time you die; otherwise no motivation to be careful
function(player)
local name = player:get_player_name();
@ -214,6 +278,35 @@ minetest.register_on_dieplayer( -- -1 bone xp each time you die; otherwise no mo
end
)
minetest.register_on_punchplayer(
function(player, hitter, time_from_last_punch, tool_capabilities, dir, damage)
local php = player:get_hp();
--minetest.chat_send_all(" HIT " .. php .. " " .. damage)
if php>0 and php-damage<=0 then -- killed
local hname = hitter:get_player_name();
local killxp = boneworld.killxp[hname] or 0;
boneworld.killxp[hname] = killxp + 0.01;
local pname = player:get_player_name();
if boneworld.bounty[pname] and boneworld.bounty[pname]>0 then
boneworld.bounty[pname] = -1
minetest.chat_send_all("**** BOUNTY **** killer " .. pname .. " has been killed! You can now get his bones as a reward!");
local killxp = boneworld.killxp[pname] or 0;
killxp = killxp-0.1; if killxp <0 then killxp = 0 end
boneworld.killxp[pname] = killxp;
end
end
end
)
local tweak_bones = function()
local name = "bones:bones";
@ -227,7 +320,7 @@ end
minetest.after(0,tweak_bones);
minetest.register_chatcommand("xp", {
description = "xp name - show bone collecting experience of target player " .. version,
description = "xp name - show experience of target player " .. version,
privs = {
interact = true
},
@ -235,19 +328,24 @@ minetest.register_chatcommand("xp", {
local msg;
if param == "" then
local xp = math.floor((boneworld.xp[name])*100)/100;
local digxp = math.floor((boneworld.digxp[name])*100)/100;
--local killxp = math.floor((boneworld.killxp[name])*100)/100;
local xp = math.floor((boneworld.xp[name] or 1)*100)/100;
local digxp = math.floor((boneworld.digxp[name] or 0)*100)/100;
local thiefxp = math.floor((boneworld.thiefxp[name] or 0)*100)/100;
local killxp = math.floor((boneworld.killxp[name] or 0)*100)/100;
msg = "xp name - show experience of target player"
.."\n# "..name .. " has " .. xp .. " bone collecting experience, ".. digxp .. " digging experience"
.. " (can dig to ".. math.floor(200+50*math.sqrt(digxp)) .. ")"
.. "\nTotal xp stored in bones in world is " .. math.floor(boneworld.wastedxp*100)/100;
.."\n# "..name .. " has " .. xp .. " bone collecting experience, ".. digxp .. " digging experience" ..
" (can dig to ".. math.floor(200+50*math.sqrt(digxp)) .. "), " .. thiefxp.. " thief experience, "..
killxp .. " kill experience "..
"\nTotal xp stored in bones in world is " .. math.floor(boneworld.wastedxp*100)/100;
else
local xp = math.floor((boneworld.xp[param] or 1)*100)/100;
local digxp = math.floor((boneworld.digxp[param] or 0)*100)/100;
--local killxp = math.floor((boneworld.killxp[name])*100)/100;
local thiefxp = math.floor((boneworld.thiefxp[param] or 0)*100)/100;
local killxp = math.floor((boneworld.killxp[param] or 0)*100)/100;
msg = "xp name - show experience of target player (10.04.16)"
.."\n# "..param .. " has " .. xp .. " bone collecting experience, ".. digxp .. " digging experience";
.."\n# "..param .. " has " .. xp .. " bone collecting experience, ".. digxp .. " digging experience, " .. thiefxp .. " thief experience, " .. killxp .. " kill experience ";
end
minetest.chat_send_player(name, msg);
@ -270,41 +368,42 @@ function minetest.is_protected(pos, name)
if pos.y<-maxdepth then
minetest.chat_send_player(name, "You can only dig above -"..math.floor(maxdepth) .. ". Get more dig experience to dig deeper");
local player = minetest.get_player_by_name(name); if not player then return true end
if pos.y<-maxdepth-5 then player:setpos({x=0,y=1,z=0}) end
if pos.y<-maxdepth-5 then
player:setpos({x=0,y=1,z=0})
minetest.chat_send_player(name, "You tried to dig too deep. Get more dig experience to dig deeper");
end
is_protected_new = true
--local player = minetest.get_player_by_name(name); if not player then return true end
--local protect_data = boneworld.protect[name];
--local tpos;
-- if not protect_data then -- safety check
-- boneworld.protect[name] = {t=minetest.get_gametime(), pos=pos};
-- tpos = pos
-- else
-- tpos = boneworld.protect[name].pos;
-- end
-- player:setpos({x=tpos.x,y=tpos.y+1,z=tpos.z});
end
end
if not is_protected_new then -- remember time, pos of last dig in unprotected area
local t1 = minetest.get_gametime();
local t0;
local protect_data = boneworld.protect[name];
if not protect_data then
boneworld.protect[name] = {t=t1, pos=pos};
t0 = t1;
else
t0 = boneworld.protect[name].t;
end
-- if not is_protected_new then -- remember time, pos of last dig in unprotected area
-- local t1 = minetest.get_gametime();
-- local t0;
-- local protect_data = boneworld.protect[name];
-- if not protect_data then
-- boneworld.protect[name] = {t=t1, pos=pos};
-- t0 = t1;
-- else
-- t0 = boneworld.protect[name].t;
-- end
if t1-t0>10 then -- "time" to remember new time, pos
boneworld.protect[name].t = t1;
boneworld.protect[name].pos = pos;
end
else -- tried to dig in protected area, teleport to last good position
local player = minetest.get_player_by_name(name); if not player then return true end
local protect_data = boneworld.protect[name];
local tpos;
if not protect_data then -- safety check
boneworld.protect[name] = {t=minetest.get_gametime(), pos=pos};
tpos = pos
else
tpos = boneworld.protect[name].pos;
end
player:setpos({x=tpos.x,y=tpos.y+1,z=tpos.z});
end
-- if t1-t0>10 then -- "time" to remember new time, pos
-- boneworld.protect[name].t = t1;
-- boneworld.protect[name].pos = pos;
-- end
-- end
return is_protected_new;
end
@ -320,6 +419,10 @@ boneworld.mineralxp = {
["default:stone_with_gold"] = 0.2,
["default:stone_with_mese"] = 0.5,
["default:stone_with_diamond"] = 1,
["moreores:mineral_silver"] = 0.2,
["moreores:mineral_tin"] = 0.1,
["moreores:mineral_mithril"] = 2,
}
@ -331,6 +434,12 @@ local after_dig_node = function(pos, oldnode, oldmetadata, digger)
xp = xp + digxp;
boneworld.digxp[name] = xp;
if digxp>0 and pos.y<-100 then -- only underground; acid surprise :)
if math.random(100) == 1 then
minetest.set_node(pos, {name="boneworld:acid_source_active"})
end
end
-- extra reward with small probability
if xp<100 or nodename == "default:stone" or digxp == 0 then return end
@ -355,7 +464,8 @@ local after_dig_node = function(pos, oldnode, oldmetadata, digger)
end
end
--minetest.chat_send_all(name .. " digged " .. nodename .. " for " .. digxp .. " mining xp ")
end
local set_after_dig_node = function(name)

BIN
textures/mymod_acid.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 360 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

BIN
textures/stealgloves.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB