mirror of
https://github.com/minetest-mods/towercrane.git
synced 2024-11-22 15:23:51 +01:00
resizing bugfix, area protection added
This commit is contained in:
parent
7ff0915a14
commit
ea38185d96
@ -1 +1,2 @@
|
||||
default
|
||||
areas?
|
170
init.lua
170
init.lua
@ -3,8 +3,8 @@
|
||||
Tower Crane Mod
|
||||
===============
|
||||
|
||||
v0.04 by JoSt
|
||||
|
||||
v0.05 by JoSt
|
||||
|
||||
Copyright (C) 2017 Joachim Stolberg
|
||||
LGPLv2.1+
|
||||
See LICENSE.txt for more information
|
||||
@ -14,7 +14,8 @@
|
||||
2017-06-06 v0.02 Hook bugfix
|
||||
2017-06-07 v0.03 fixed 2 bugs, added config.lua and sound
|
||||
2017-06-08 v0.04 recipe and rope length now configurable
|
||||
|
||||
2017-06-10 v0.05 resizing bugfix, area protection added
|
||||
|
||||
]]--
|
||||
|
||||
|
||||
@ -26,9 +27,9 @@ dofile(minetest.get_modpath("towercrane") .. "/config.lua")
|
||||
--## Tower Crane Hook
|
||||
--##################################################################################################
|
||||
local hook = {
|
||||
physical = true,
|
||||
physical = true,
|
||||
collisionbox = {-0.2, -0.2, -0.2, 0.2, 0.2, 0.2},
|
||||
collide_with_objects = false,
|
||||
collide_with_objects = false,
|
||||
visual = "cube",
|
||||
visual_size = {x=0.6, y=0.6},
|
||||
textures = {
|
||||
@ -47,6 +48,7 @@ local hook = {
|
||||
speed_up=0,
|
||||
sound=nil,
|
||||
}
|
||||
|
||||
----------------------------------------------------------------------------------------------------
|
||||
-- Enter/leave the Hook
|
||||
----------------------------------------------------------------------------------------------------
|
||||
@ -94,7 +96,7 @@ function hook:on_step(dtime)
|
||||
elseif self.speed_forward < 0 then
|
||||
self.speed_forward = self.speed_forward + velocity
|
||||
end
|
||||
|
||||
|
||||
if ctrl.right then -- right
|
||||
self.speed_right = math.min(self.speed_right + velocity, max_speed)
|
||||
elseif ctrl.left then -- left
|
||||
@ -127,6 +129,7 @@ function hook:on_step(dtime)
|
||||
if pos.z < self.pos1.z then vz= velocity end
|
||||
if pos.z > self.pos2.z then vz= -velocity end
|
||||
|
||||
-- sound control
|
||||
if vx ~= 0 or vz ~= 0 or self.speed_up ~= 0 then
|
||||
if self.sound == nil then
|
||||
self.sound = minetest.sound_play({name="crane"},{object=self.object,
|
||||
@ -137,7 +140,7 @@ function hook:on_step(dtime)
|
||||
minetest.sound_stop(self.sound)
|
||||
self.sound = nil
|
||||
end
|
||||
|
||||
|
||||
self.object:setvelocity({x=vx, y=self.speed_up,z=vz})
|
||||
else
|
||||
self.object:setvelocity({x=0, y=0,z=0})
|
||||
@ -175,7 +178,7 @@ local function check_space(pos, dir, height, width)
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
pos.x = pos.x + dir.x*2
|
||||
pos.z = pos.z + dir.z*2
|
||||
for i = 1,width+3 do
|
||||
@ -204,7 +207,7 @@ local function construct_crane(pos, dir, height, width, owner)
|
||||
pos.y = pos.y + 1
|
||||
minetest.env:add_node(pos, {name="towercrane:mast"})
|
||||
end
|
||||
|
||||
|
||||
pos.y = pos.y - 2
|
||||
pos.x = pos.x - dir.x
|
||||
pos.z = pos.z - dir.z
|
||||
@ -217,7 +220,7 @@ local function construct_crane(pos, dir, height, width, owner)
|
||||
minetest.env:add_node(pos, {name="towercrane:balance"})
|
||||
pos.x = pos.x + 3 * dir.x
|
||||
pos.z = pos.z + 3 * dir.z
|
||||
|
||||
|
||||
for i = 1,width do
|
||||
pos.x = pos.x + dir.x
|
||||
pos.z = pos.z + dir.z
|
||||
@ -232,10 +235,10 @@ end
|
||||
----------------------------------------------------------------------------------------------------
|
||||
-- Remove the crane
|
||||
----------------------------------------------------------------------------------------------------
|
||||
local function dig_crane(pos, dir, height, width)
|
||||
local function remove_crane(pos, dir, height, width)
|
||||
pos.y = pos.y + 1
|
||||
minetest.env:remove_node(pos, {name="towercrane:mast_ctrl_off"})
|
||||
|
||||
|
||||
for i = 1,height+1 do
|
||||
pos.y = pos.y + 1
|
||||
minetest.env:remove_node(pos, {name="towercrane:mast"})
|
||||
@ -253,7 +256,7 @@ local function dig_crane(pos, dir, height, width)
|
||||
minetest.env:remove_node(pos, {name="towercrane:balance"})
|
||||
pos.x = pos.x + 3 * dir.x
|
||||
pos.z = pos.z + 3 * dir.z
|
||||
|
||||
|
||||
for i = 1,width do
|
||||
pos.x = pos.x + dir.x
|
||||
pos.z = pos.z + dir.z
|
||||
@ -275,6 +278,81 @@ local function place_hook(pos, dir)
|
||||
return minetest.add_entity(pos, "towercrane:hook")
|
||||
end
|
||||
|
||||
|
||||
----------------------------------------------------------------------------------------------------
|
||||
-- Check if the given construction area is not already protected
|
||||
----------------------------------------------------------------------------------------------------
|
||||
local function check_area(pos1, pos2, owner)
|
||||
if not areas then return true end
|
||||
for id, a in ipairs(areas:getAreasIntersectingArea(pos1, pos2)) do
|
||||
print(dump(a.owner))
|
||||
if a.owner ~= owner then
|
||||
return false
|
||||
end
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
----------------------------------------------------------------------------------------------------
|
||||
-- Calculate and set the protection area (pos1, pos2)
|
||||
----------------------------------------------------------------------------------------------------
|
||||
local function protect_area(pos, dir, height, width, owner)
|
||||
if not areas then return 0 end
|
||||
-- pos1 = close/right/below
|
||||
dir = turnright(dir)
|
||||
dir = turnright(dir)
|
||||
local pos1 = vector.add(pos, vector.multiply(dir, 2))
|
||||
dir = turnleft(dir)
|
||||
pos1 = vector.add(pos1, vector.multiply(dir, width/2))
|
||||
dir = turnleft(dir)
|
||||
pos1.y = pos.y - 2
|
||||
|
||||
-- pos2 = far/left/above
|
||||
local pos2 = vector.add(pos1, vector.multiply(dir, width+2))
|
||||
dir = turnleft(dir)
|
||||
pos2 = vector.add(pos2, vector.multiply(dir, width))
|
||||
pos2.y = pos.y + 2 + height
|
||||
|
||||
-- add area
|
||||
local canAdd, errMsg = areas:canPlayerAddArea(pos1, pos2, owner)
|
||||
if canAdd then
|
||||
local id = areas:add(owner, owner .. "'s construction site", pos1, pos2, nil)
|
||||
areas:save()
|
||||
return id
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
----------------------------------------------------------------------------------------------------
|
||||
-- Remove the protection area
|
||||
----------------------------------------------------------------------------------------------------
|
||||
local function remove_area(id, owner)
|
||||
if not areas then return end
|
||||
if areas:isAreaOwner(id, owner) then
|
||||
areas:remove(id)
|
||||
areas:save()
|
||||
end
|
||||
end
|
||||
|
||||
----------------------------------------------------------------------------------------------------
|
||||
-- Check user input (height, width)
|
||||
----------------------------------------------------------------------------------------------------
|
||||
local function check_input(fields)
|
||||
local size = string.split(fields.size, ",")
|
||||
if #size == 2 then
|
||||
local height = tonumber(size[1])
|
||||
local width = tonumber(size[2])
|
||||
if height ~= nil and width ~= nil then
|
||||
height = math.max(height, 8)
|
||||
height = math.min(height, towercrane.max_height)
|
||||
width = math.max(width, 8)
|
||||
width = math.min(width, towercrane.max_width)
|
||||
return height, width
|
||||
end
|
||||
end
|
||||
return 0, 0
|
||||
end
|
||||
|
||||
----------------------------------------------------------------------------------------------------
|
||||
-- Register Crane base
|
||||
----------------------------------------------------------------------------------------------------
|
||||
@ -317,40 +395,42 @@ minetest.register_node("towercrane:base", {
|
||||
return
|
||||
end
|
||||
local meta = minetest.get_meta(pos)
|
||||
local owner = meta:get_string("owner")
|
||||
local dir = minetest.string_to_pos(meta:get_string("dir"))
|
||||
local height = meta:get_int("height")
|
||||
local width = meta:get_int("width")
|
||||
local id = meta:get_int("id")
|
||||
|
||||
if not player or not player:is_player() then
|
||||
return
|
||||
end
|
||||
local owner = meta:get_string("owner")
|
||||
if player:get_player_name() ~= owner then
|
||||
return
|
||||
end
|
||||
|
||||
local dir = minetest.string_to_pos(meta:get_string("dir"))
|
||||
local height = meta:get_int("height")
|
||||
local width = meta:get_int("width")
|
||||
-- destroy area and crane
|
||||
if dir ~= nil and height ~= nil and width ~= nil then
|
||||
dig_crane(pos, dir, height, width)
|
||||
remove_area(id, owner)
|
||||
remove_crane(table.copy(pos), dir, height, width)
|
||||
end
|
||||
--check for correct size format
|
||||
size = string.split(fields.size, ",")
|
||||
if #size == 2 then
|
||||
local height = tonumber(size[1])
|
||||
local width = tonumber(size[2])
|
||||
if height ~= nil and width ~= nil then
|
||||
height = math.max(height, 8)
|
||||
height = math.min(height, towercrane.max_height)
|
||||
width = math.max(width, 8)
|
||||
width = math.min(width, towercrane.max_width)
|
||||
meta:set_int("height", height)
|
||||
meta:set_int("width", width)
|
||||
meta:set_string("infotext", "Crane size: " .. height .. "," .. width)
|
||||
if dir ~= nil then
|
||||
if check_space(table.copy(pos), dir, height, width) then
|
||||
construct_crane(table.copy(pos), dir, height, width, owner)
|
||||
|
||||
-- evaluate user input
|
||||
height, width = check_input(fields)
|
||||
if height ~= 0 then
|
||||
meta:set_int("height", height)
|
||||
meta:set_int("width", width)
|
||||
meta:set_string("infotext", "Crane size: " .. height .. "," .. width)
|
||||
if dir ~= nil then
|
||||
if check_space(table.copy(pos), dir, height, width) then
|
||||
-- add protection area
|
||||
local id = protect_area(table.copy(pos), table.copy(dir), height, width, owner)
|
||||
if id ~= nil then
|
||||
meta:set_int("id", id)
|
||||
construct_crane(table.copy(pos), table.copy(dir), height, width, owner)
|
||||
else
|
||||
minetest.chat_send_player(owner, "Too less space to raise up the tower crane!")
|
||||
minetest.chat_send_player(owner, "Construction area is already protected!")
|
||||
end
|
||||
else
|
||||
minetest.chat_send_player(owner, "Too less space to raise up the tower crane!")
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -362,13 +442,19 @@ minetest.register_node("towercrane:base", {
|
||||
local dir = minetest.string_to_pos(meta:get_string("dir"))
|
||||
local height = meta:get_int("height")
|
||||
local width = meta:get_int("width")
|
||||
local id = meta:get_int("id")
|
||||
local owner = meta:get_string("owner")
|
||||
|
||||
-- remove protection area
|
||||
if id ~= nil then
|
||||
remove_area(id, owner)
|
||||
end
|
||||
-- remove crane
|
||||
if dir ~= nil and height ~= nil and width ~= nil then
|
||||
dig_crane(pos, dir, height, width)
|
||||
remove_crane(pos, dir, height, width)
|
||||
end
|
||||
-- remove hook
|
||||
local id = minetest.hash_node_position(pos)
|
||||
id = minetest.hash_node_position(pos)
|
||||
if towercrane.id then
|
||||
towercrane.id:remove()
|
||||
towercrane.id = nil
|
||||
@ -427,6 +513,7 @@ minetest.register_node("towercrane:mast_ctrl_on", {
|
||||
"towercrane_mast_ctrl.png",
|
||||
"towercrane_mast_ctrl.png",
|
||||
},
|
||||
-- switch the crane OFF
|
||||
on_rightclick = function (pos, node, clicker)
|
||||
local meta = minetest.get_meta(pos)
|
||||
if not clicker or not clicker:is_player() then
|
||||
@ -475,8 +562,9 @@ minetest.register_node("towercrane:mast_ctrl_off", {
|
||||
"towercrane_mast_ctrl.png",
|
||||
"towercrane_mast_ctrl.png",
|
||||
},
|
||||
-- switch the crane ON
|
||||
on_rightclick = function (pos, node, clicker)
|
||||
-- switch switch on, calculate the construction area, and place the hook
|
||||
-- calculate the construction area, and place the hook
|
||||
local meta = minetest.get_meta(pos)
|
||||
-- only the owner is allowed to switch
|
||||
if not clicker or not clicker:is_player() then
|
||||
@ -494,7 +582,9 @@ minetest.register_node("towercrane:mast_ctrl_off", {
|
||||
local id = minetest.hash_node_position(pos)
|
||||
towercrane.id = place_hook(table.copy(pos), dir)
|
||||
|
||||
-- calculate the construction area dimension (pos, pos2)
|
||||
--
|
||||
-- calculate the construction area dimension (pos1, pos2)
|
||||
--
|
||||
local height = meta:get_int("height")
|
||||
local width = meta:get_int("width")
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user