added PvP protector (PvP Enabled areas)

This commit is contained in:
Juraj Vajda 2018-10-31 17:23:41 -04:00
parent d1f9788946
commit a5c3679eda
7 changed files with 451 additions and 148 deletions

View File

@ -70,7 +70,7 @@ minetest.register_chatcommand("protector_replace", {
minetest.register_abm({
nodenames = {"protector:protect", "protector:protect2"},
nodenames = {"protector:protect", "protector:protect2", "protector:protect_pvp", "protector:protect2_pvp"},
interval = 8,
chance = 1,
catch_up = false,
@ -128,7 +128,7 @@ minetest.register_chatcommand("protector_show", {
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},
{"protector:protect", "protector:protect2"})
{"protector:protect", "protector:protect2", "protector:protect_pvp", "protector:protect2_pvp"})
local meta, owner

24
hud.lua
View File

@ -17,18 +17,35 @@ minetest.register_globalstep(function(dtime)
local name = player:get_player_name()
local pos = vector.round(player:get_pos())
local hud_text = ""
local hud_text_color = 0xFFFF22; -- lemon yellow
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},
{"protector:protect","protector:protect2"})
{"protector:protect","protector:protect2","protector:protect_pvp","protector:protect2_pvp"})
if #protectors > 0 then
local npos = protectors[1]
local meta = minetest.get_meta(npos)
local is_pvp = meta:get_int("is_pvp")
if not is_pvp then
is_pvp = 0
end
if is_pvp == 1 then
hud_text_color = 0xFF0022 -- torch red
else
hud_text_color = 0xFFFF22 -- lemon yellow
end
local nodeowner = meta:get_string("owner")
hud_text = S("Owner: @1", nodeowner)
if is_pvp == 1 then
hud_text = S("Owner: @1", nodeowner) .. " (PvP Enabled)"
else
hud_text = S("Owner: @1", nodeowner)
end
end
if not hud[name] then
@ -38,7 +55,7 @@ minetest.register_globalstep(function(dtime)
hud[name].id = player:hud_add({
hud_elem_type = "text",
name = "Protector Area",
number = 0xFFFF22,
number = hud_text_color,
position = {x=0, y=0.95},
offset = {x=8, y=-8},
text = hud_text,
@ -51,6 +68,7 @@ minetest.register_globalstep(function(dtime)
else
player:hud_change(hud[name].id, "text", hud_text)
player:hud_change(hud[name].id, "number", hud_text_color)
end
end
end)

279
init.lua
View File

@ -206,12 +206,17 @@ protector.can_dig = function(r, pos, digger, onlyowner, infolevel)
end
-- find the protector nodes
local pos = minetest.find_nodes_in_area(
local pos, nodes = 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"})
{"protector:protect", "protector:protect2","protector:protect_pvp", "protector:protect2_pvp"})
local meta, owner, members
local meta, owner, members, is_pvp
if nodes["protector:protect_pvp"] > 0 or
nodes["protector:protect2_pvp"] > 0 then
is_pvp = true
end
for n = 1, #pos do
@ -221,14 +226,14 @@ protector.can_dig = function(r, pos, digger, onlyowner, infolevel)
-- node change and digger isn't owner
if infolevel == 1 and owner ~= digger then
-- and you aren't on the member list
if onlyowner or not is_member(meta, digger) then
minetest.chat_send_player(digger,
S("This area is owned by @1", owner) .. "!")
if not is_pvp then
minetest.chat_send_player(digger, S("This area is owned by @1", owner) .. "!")
end
return false
return false, is_pvp
end
end
@ -613,6 +618,260 @@ minetest.register_craft({
})
-- protection PvP node
minetest.register_node("protector:protect_pvp", {
description = S("Protection Block") .. " PvP (" .. S("USE for area check") .. ")",
drawtype = "nodebox",
tiles = {
"protector_protect_pvp_top.png",
"protector_protect_pvp_top.png",
"protector_protect_pvp_side.png",
"protector_protect_pvp_side.png",
"protector_protect_pvp_side.png",
"protector_protect_pvp_side.png"
},
sounds = default.node_sound_stone_defaults(),
groups = {dig_immediate = 2, unbreakable = 1},
is_ground_content = false,
paramtype = "light",
light_source = 4,
node_box = {
type = "fixed",
fixed = {
{-0.375, -0.4375, -0.375, 0.375, 0.4375, 0.375},
{-0.5, 0.375, -0.5, -0.375, 0.5, 0.375},
{-0.375, 0.375, -0.5, 0.5, 0.5, -0.375},
{0.375, 0.375, -0.375, 0.5, 0.5, 0.5},
{-0.5, 0.375, 0.375, 0.375, 0.5, 0.5},
{-0.25, 0.4375, -0.25, -0.0625, 0.5, 0.0625},
{-0.25, 0.4375, 0.0625, 0.0625, 0.5, 0.25},
{0.0625, 0.4375, -0.0625, 0.25, 0.5, 0.25},
{-0.0625, 0.4375, -0.25, 0.25, 0.5, -0.0625},
{-0.5, -0.5, -0.5, -0.375, -0.375, 0.375},
{-0.375, -0.5, -0.5, 0.5, -0.375, -0.375},
{0.375, -0.5, -0.375, 0.5, -0.375, 0.5},
{-0.5, -0.5, 0.375, 0.375, -0.375, 0.5},
{0.375, -0.375, -0.5, 0.5, 0.375, -0.375},
{0.375, -0.375, 0.375, 0.5, 0.375, 0.5},
{-0.5, -0.375, -0.5, -0.375, 0.375, -0.375},
{-0.5, -0.375, 0.375, -0.375, 0.375, 0.5},
{-0.25, -0.5, -0.25, -0.0625, -0.4375, 0.0625},
{-0.25, -0.5, 0.0625, 0.0625, -0.4375, 0.25},
{0.0625, -0.5, -0.0625, 0.25, -0.4375, 0.25},
{-0.0625, -0.5, -0.25, 0.25, -0.4375, -0.0625},
{-0.0625, -0.25, -0.4375, 0.25, -0.0625, -0.375},
{-0.25, 0.0625, -0.4375, 0.0625, 0.25, -0.375},
{-0.25, -0.25, -0.4375, -0.0625, 0.0625, -0.375},
{0.0625, -0.0625, -0.4375, 0.25, 0.25, -0.375},
{0.375, -0.0625, -0.25, 0.4375, 0.25, -0.0625},
{0.375, -0.25, 0.0625, 0.4375, 0.0625001, 0.25},
{0.375, 0.0625, -0.0625, 0.4375, 0.25, 0.25},
{0.375, -0.25, -0.25, 0.4375, -0.0624999, 0.0624998},
{-0.0625, -0.25, 0.375, 0.25, -0.0625, 0.4375},
{-0.25, 0.0625, 0.375, 0.0624999, 0.25, 0.4375},
{0.0625, -0.0625, 0.375, 0.25, 0.25, 0.4375},
{-0.25, -0.25, 0.375, -0.0624999, 0.0625, 0.4375},
{-0.4375, -0.25, 0.0625, -0.375, 0.0625, 0.25},
{-0.4375, -0.0625, -0.25, -0.375, 0.25, -0.0624999},
{-0.4375, 0.0625, -0.0625, -0.375, 0.25, 0.25},
{-0.4375, -0.25, -0.25, -0.375, -0.0624999, 0.0625},
{-0.125, -0.125, 0.4375, 0.125, 0.125, 0.5},
{0.0625, 0.125, 0.4375, 0.125, 0.1875, 0.5},
{-0.125, 0.125, 0.4375, -0.0625, 0.1875, 0.5},
{-0.0625, -0.1875, 0.4375, 0.0624999, -0.125, 0.5},
{-0.125, -0.125, -0.5, 0.125, 0.125, -0.4375},
{0.0625, 0.125, -0.5, 0.125, 0.1875, -0.4375},
{-0.125, 0.125, -0.5, -0.0625, 0.1875, -0.4375},
{-0.0625, -0.1875, -0.5, 0.0624999, -0.125, -0.4375},
{-0.5, -0.125, -0.125, -0.4375, 0.125, 0.125},
{-0.5, 0.125, 0.0625, -0.4375, 0.1875, 0.125},
{-0.5, 0.125, -0.125, -0.4375, 0.1875, -0.0625003},
{-0.5, -0.1875, -0.0625, -0.4375, -0.125, 0.0625},
{0.4375, -0.125, -0.125, 0.5, 0.125, 0.125},
{0.4375, 0.125, -0.125, 0.5, 0.1875, -0.0625},
{0.4375, 0.125, 0.0625, 0.5, 0.1875, 0.125},
{0.4375, -0.1875, -0.0625, 0.5, -0.125, 0.0625},
}
},
collision_box = {
type = "fixed",
fixed = {
{-0.5 ,-0.5, -0.5, 0.5, 0.5, 0.5},
},
},
selection_box = {
type = "fixed",
fixed = {
{-0.5 ,-0.5, -0.5, 0.5, 0.5, 0.5},
},
},
on_place = check_overlap,
after_place_node = function(pos, placer)
local meta = minetest.get_meta(pos)
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_int("is_pvp", 1)
end,
on_use = function(itemstack, user, pointed_thing)
if pointed_thing.type ~= "node" then
return
end
protector.can_dig(protector_radius, pointed_thing.under, user:get_player_name(), false, 2)
end,
on_rightclick = function(pos, node, clicker, itemstack)
local meta = minetest.get_meta(pos)
local name = clicker:get_player_name()
if meta
and protector.can_dig(1, pos, name, true, 1) then
player_pos[name] = pos
minetest.show_formspec(name, "protector:node", protector_formspec(meta))
end
end,
on_punch = function(pos, node, puncher)
if minetest.is_protected(pos, puncher:get_player_name()) then
return
end
minetest.add_entity(pos, "protector:display")
end,
can_dig = function(pos, player)
return player and protector.can_dig(1, pos, player:get_player_name(), true, 1)
end,
on_blast = function() end,
after_destruct = function(pos, oldnode)
local objects = minetest.get_objects_inside_radius(pos, 0.5)
for _, v in ipairs(objects) do
v:remove()
end
end,
})
minetest.register_craft({
output = "protector:protect_pvp",
recipe = {
{"protector:protect", "dye:red"}
}
})
-- protection PvP logo
minetest.register_node("protector:protect2_pvp", {
description = S("Protection Logo") .. " PvP (" .. S("USE for area check") .. ")",
tiles = {"protector_logo.png^[colorize:#820D0C90"},
wield_image = "protector_logo.png^[colorize:#820D0C90",
inventory_image = "protector_logo.png^[colorize:#820D0C90",
sounds = default.node_sound_stone_defaults(),
groups = {dig_immediate = 2, unbreakable = 1},
paramtype = "light",
paramtype2 = "wallmounted",
legacy_wallmounted = true,
light_source = 4,
drawtype = "nodebox",
sunlight_propagates = true,
walkable = true,
node_box = {
type = "wallmounted",
wall_top = {-0.375, 0.4375, -0.5, 0.375, 0.5, 0.5},
wall_bottom = {-0.375, -0.5, -0.5, 0.375, -0.4375, 0.5},
wall_side = {-0.5, -0.5, -0.375, -0.4375, 0.5, 0.375},
},
selection_box = {type = "wallmounted"},
on_place = check_overlap,
after_place_node = function(pos, placer)
local meta = minetest.get_meta(pos)
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_int("is_pvp", 1)
end,
on_use = function(itemstack, user, pointed_thing)
if pointed_thing.type ~= "node" then
return
end
protector.can_dig(protector_radius, pointed_thing.under, user:get_player_name(), false, 2)
end,
on_rightclick = function(pos, node, clicker, itemstack)
local meta = minetest.get_meta(pos)
local name = clicker:get_player_name()
if meta
and protector.can_dig(1, pos, name, true, 1) then
player_pos[name] = pos
minetest.show_formspec(name, "protector:node", protector_formspec(meta))
end
end,
on_punch = function(pos, node, puncher)
if minetest.is_protected(pos, puncher:get_player_name()) then
return
end
minetest.add_entity(pos, "protector:display")
end,
can_dig = function(pos, player)
return player and protector.can_dig(1, pos, player:get_player_name(), true, 1)
end,
on_blast = function() end,
after_destruct = function(pos, oldnode)
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 PvP
minetest.register_craft({
type = "shapeless",
output = "protector:protect_pvp",
recipe = {"protector:protect2_pvp"}
})
minetest.register_craft({
type = "shapeless",
output = "protector:protect2_pvp",
recipe = {"protector:protect_pvp"}
})
-- check formspec buttons or when name entered
minetest.register_on_player_receive_fields(function(player, formname, fields)
@ -645,7 +904,9 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
local nod = minetest.get_node(pos).name
if nod ~= "protector:protect"
and nod ~= "protector:protect2" then
and nod ~= "protector:protect2"
and nod ~= "protector:protect_pvp"
and nod ~= "protector:protect2_pvp" then
player_pos[name] = nil
return
end
@ -748,6 +1009,8 @@ dofile(path .. "/hud.lua")
if minetest.get_modpath("mesecons_mvps") then
mesecon.register_mvps_stopper("protector:protect")
mesecon.register_mvps_stopper("protector:protect2")
mesecon.register_mvps_stopper("protector:protect_pvp")
mesecon.register_mvps_stopper("protector:protect2_pvp")
mesecon.register_mvps_stopper("protector:chest")
end

Binary file not shown.

Before

Width:  |  Height:  |  Size: 96 B

After

Width:  |  Height:  |  Size: 108 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 616 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 543 B

292
tool.lua
View File

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