v0.09: Crane protection area added to prevent crane clusters

This commit is contained in:
Joachim Stolberg 2017-08-19 15:21:26 +02:00
parent 89956d0674
commit dfd91b0c90

@ -3,7 +3,7 @@
Tower Crane Mod
===============
v0.08 by JoSt
v0.09 by JoSt
Copyright (C) 2017 Joachim Stolberg
LGPLv2.1+
@ -17,15 +17,83 @@
2017-06-10 v0.05 resizing bugfix, area protection added
2017-07-11 v0.06 fixed the space check bug, settingtypes added
2017-07-16 v0.07 crane remove bug fix
3017-07-16 v0.08 player times out bugfix
2017-07-16 v0.08 player times out bugfix
2017-08-19 v0.09 crane protection area to prevent crane clusters
]]--
-- crane minimum size
MIN_SIZE = 8
towercrane = {}
dofile(minetest.get_modpath("towercrane") .. "/config.lua")
local function chat(owner, text)
if owner ~= nil then
minetest.chat_send_player(owner, "[Tower Crane] "..text)
end
end
--##################################################################################################
--## Construction Area
--##################################################################################################
-- Areas = {
-- pos_key = {owner="...", pos1=pos, pos2=pos},
-- }
local storage = minetest.get_mod_storage()
local Areas = minetest.deserialize(storage:get_string("Areas")) or {}
local function update_mod_storage()
storage:set_string("Areas", minetest.serialize(Areas))
end
minetest.register_on_shutdown(function()
update_mod_storage()
end)
----------------------------------------------------------------------------------------------------
-- The same player can't place a crane within another protection area
----------------------------------------------------------------------------------------------------
local function no_area_violation(owner, pos)
local res = true
local px, py, pz = pos.x, pos.y, pos.z
for key, area in pairs(Areas) do
if owner == area.owner then
local pos1, pos2 = area.pos1, area.pos2
if (px >= pos1.x and px <= pos2.x) and (py >= pos1.y and py <= pos2.y) and
(pz >= pos1.z and pz <= pos2.z) then
res = false
break
end
end
end
return res
end
local function store_crane_data(owner, pos, pos1, pos2)
-- normalize x/z so that pos2 > pos1
if pos2.x < pos1.x then
pos2.x, pos1.x = pos1.x, pos2.x
end
if pos2.z < pos1.z then
pos2.z, pos1.z = pos1.z, pos2.z
end
-- store data
local key = minetest.pos_to_string(pos)
Areas[key] = {owner=owner, pos1=pos1, pos2=pos2}
update_mod_storage()
end
local function remove_crane_data(pos)
local key = minetest.pos_to_string(pos)
Areas[key] = nil
update_mod_storage()
end
--##################################################################################################
--## Tower Crane Hook
--##################################################################################################
@ -303,6 +371,8 @@ local function protect_area(pos, dir, height, width, owner)
pos2 = vector.add(pos2, vector.multiply(dir, width))
pos2.y = pos.y + 2 + height
store_crane_data(owner, pos, pos1, pos2)
-- add area
local canAdd, errMsg = areas:canPlayerAddArea(pos1, pos2, owner)
if canAdd then
@ -333,11 +403,9 @@ local function check_input(fields)
local height = tonumber(size[1])
local width = tonumber(size[2])
if height ~= nil and width ~= nil then
--height = math.max(height, 8)
height = math.max(height, 2)
height = math.max(height, MIN_SIZE)
height = math.min(height, towercrane.max_height)
--width = math.max(width, 8)
width = math.max(width, 2)
width = math.max(width, MIN_SIZE)
width = math.min(width, towercrane.max_width)
return height, width
end
@ -400,6 +468,7 @@ minetest.register_node("towercrane:base", {
end
-- destroy area and crane
if dir ~= nil and height ~= nil and width ~= nil then
remove_crane_data(pos)
remove_area(id, owner)
remove_crane(table.copy(pos), dir, height, width)
end
@ -410,6 +479,7 @@ minetest.register_node("towercrane:base", {
meta:set_int("height", height)
meta:set_int("width", width)
meta:set_string("infotext", "Crane size: " .. height .. "," .. width)
if no_area_violation(owner, pos) then
if dir ~= nil then
if check_space(table.copy(pos), dir, height, width) then
-- add protection area
@ -418,12 +488,15 @@ minetest.register_node("towercrane:base", {
meta:set_int("id", id)
construct_crane(table.copy(pos), table.copy(dir), height, width, owner)
else
minetest.chat_send_player(owner, "Construction area is already protected!")
chat(owner, "Construction area is already protected!")
end
else
minetest.chat_send_player(owner, "Too less space to raise up the tower crane!")
chat(owner, "Too less space to raise up the crane!")
end
end
else
chat(owner, "Too less distance to your other crane(s)!")
end
end
end,
@ -442,6 +515,7 @@ minetest.register_node("towercrane:base", {
end
-- remove crane
if dir ~= nil and height ~= nil and width ~= nil then
remove_crane_data(pos)
remove_crane(pos, dir, height, width)
end
-- remove hook