mirror of
https://github.com/minetest-mods/towercrane.git
synced 2025-02-16 18:02:32 +01:00
resizing bugfix, area protection added
This commit is contained in:
@ -1 +1,2 @@
|
|||||||
default
|
default
|
||||||
|
areas?
|
170
init.lua
170
init.lua
@ -3,8 +3,8 @@
|
|||||||
Tower Crane Mod
|
Tower Crane Mod
|
||||||
===============
|
===============
|
||||||
|
|
||||||
v0.04 by JoSt
|
v0.05 by JoSt
|
||||||
|
|
||||||
Copyright (C) 2017 Joachim Stolberg
|
Copyright (C) 2017 Joachim Stolberg
|
||||||
LGPLv2.1+
|
LGPLv2.1+
|
||||||
See LICENSE.txt for more information
|
See LICENSE.txt for more information
|
||||||
@ -14,7 +14,8 @@
|
|||||||
2017-06-06 v0.02 Hook bugfix
|
2017-06-06 v0.02 Hook bugfix
|
||||||
2017-06-07 v0.03 fixed 2 bugs, added config.lua and sound
|
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-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
|
--## Tower Crane Hook
|
||||||
--##################################################################################################
|
--##################################################################################################
|
||||||
local hook = {
|
local hook = {
|
||||||
physical = true,
|
physical = true,
|
||||||
collisionbox = {-0.2, -0.2, -0.2, 0.2, 0.2, 0.2},
|
collisionbox = {-0.2, -0.2, -0.2, 0.2, 0.2, 0.2},
|
||||||
collide_with_objects = false,
|
collide_with_objects = false,
|
||||||
visual = "cube",
|
visual = "cube",
|
||||||
visual_size = {x=0.6, y=0.6},
|
visual_size = {x=0.6, y=0.6},
|
||||||
textures = {
|
textures = {
|
||||||
@ -47,6 +48,7 @@ local hook = {
|
|||||||
speed_up=0,
|
speed_up=0,
|
||||||
sound=nil,
|
sound=nil,
|
||||||
}
|
}
|
||||||
|
|
||||||
----------------------------------------------------------------------------------------------------
|
----------------------------------------------------------------------------------------------------
|
||||||
-- Enter/leave the Hook
|
-- Enter/leave the Hook
|
||||||
----------------------------------------------------------------------------------------------------
|
----------------------------------------------------------------------------------------------------
|
||||||
@ -94,7 +96,7 @@ function hook:on_step(dtime)
|
|||||||
elseif self.speed_forward < 0 then
|
elseif self.speed_forward < 0 then
|
||||||
self.speed_forward = self.speed_forward + velocity
|
self.speed_forward = self.speed_forward + velocity
|
||||||
end
|
end
|
||||||
|
|
||||||
if ctrl.right then -- right
|
if ctrl.right then -- right
|
||||||
self.speed_right = math.min(self.speed_right + velocity, max_speed)
|
self.speed_right = math.min(self.speed_right + velocity, max_speed)
|
||||||
elseif ctrl.left then -- left
|
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.pos1.z then vz= velocity end
|
||||||
if pos.z > self.pos2.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 vx ~= 0 or vz ~= 0 or self.speed_up ~= 0 then
|
||||||
if self.sound == nil then
|
if self.sound == nil then
|
||||||
self.sound = minetest.sound_play({name="crane"},{object=self.object,
|
self.sound = minetest.sound_play({name="crane"},{object=self.object,
|
||||||
@ -137,7 +140,7 @@ function hook:on_step(dtime)
|
|||||||
minetest.sound_stop(self.sound)
|
minetest.sound_stop(self.sound)
|
||||||
self.sound = nil
|
self.sound = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
self.object:setvelocity({x=vx, y=self.speed_up,z=vz})
|
self.object:setvelocity({x=vx, y=self.speed_up,z=vz})
|
||||||
else
|
else
|
||||||
self.object:setvelocity({x=0, y=0,z=0})
|
self.object:setvelocity({x=0, y=0,z=0})
|
||||||
@ -175,7 +178,7 @@ local function check_space(pos, dir, height, width)
|
|||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
pos.x = pos.x + dir.x*2
|
pos.x = pos.x + dir.x*2
|
||||||
pos.z = pos.z + dir.z*2
|
pos.z = pos.z + dir.z*2
|
||||||
for i = 1,width+3 do
|
for i = 1,width+3 do
|
||||||
@ -204,7 +207,7 @@ local function construct_crane(pos, dir, height, width, owner)
|
|||||||
pos.y = pos.y + 1
|
pos.y = pos.y + 1
|
||||||
minetest.env:add_node(pos, {name="towercrane:mast"})
|
minetest.env:add_node(pos, {name="towercrane:mast"})
|
||||||
end
|
end
|
||||||
|
|
||||||
pos.y = pos.y - 2
|
pos.y = pos.y - 2
|
||||||
pos.x = pos.x - dir.x
|
pos.x = pos.x - dir.x
|
||||||
pos.z = pos.z - dir.z
|
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"})
|
minetest.env:add_node(pos, {name="towercrane:balance"})
|
||||||
pos.x = pos.x + 3 * dir.x
|
pos.x = pos.x + 3 * dir.x
|
||||||
pos.z = pos.z + 3 * dir.z
|
pos.z = pos.z + 3 * dir.z
|
||||||
|
|
||||||
for i = 1,width do
|
for i = 1,width do
|
||||||
pos.x = pos.x + dir.x
|
pos.x = pos.x + dir.x
|
||||||
pos.z = pos.z + dir.z
|
pos.z = pos.z + dir.z
|
||||||
@ -232,10 +235,10 @@ end
|
|||||||
----------------------------------------------------------------------------------------------------
|
----------------------------------------------------------------------------------------------------
|
||||||
-- Remove the crane
|
-- Remove the crane
|
||||||
----------------------------------------------------------------------------------------------------
|
----------------------------------------------------------------------------------------------------
|
||||||
local function dig_crane(pos, dir, height, width)
|
local function remove_crane(pos, dir, height, width)
|
||||||
pos.y = pos.y + 1
|
pos.y = pos.y + 1
|
||||||
minetest.env:remove_node(pos, {name="towercrane:mast_ctrl_off"})
|
minetest.env:remove_node(pos, {name="towercrane:mast_ctrl_off"})
|
||||||
|
|
||||||
for i = 1,height+1 do
|
for i = 1,height+1 do
|
||||||
pos.y = pos.y + 1
|
pos.y = pos.y + 1
|
||||||
minetest.env:remove_node(pos, {name="towercrane:mast"})
|
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"})
|
minetest.env:remove_node(pos, {name="towercrane:balance"})
|
||||||
pos.x = pos.x + 3 * dir.x
|
pos.x = pos.x + 3 * dir.x
|
||||||
pos.z = pos.z + 3 * dir.z
|
pos.z = pos.z + 3 * dir.z
|
||||||
|
|
||||||
for i = 1,width do
|
for i = 1,width do
|
||||||
pos.x = pos.x + dir.x
|
pos.x = pos.x + dir.x
|
||||||
pos.z = pos.z + dir.z
|
pos.z = pos.z + dir.z
|
||||||
@ -275,6 +278,81 @@ local function place_hook(pos, dir)
|
|||||||
return minetest.add_entity(pos, "towercrane:hook")
|
return minetest.add_entity(pos, "towercrane:hook")
|
||||||
end
|
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
|
-- Register Crane base
|
||||||
----------------------------------------------------------------------------------------------------
|
----------------------------------------------------------------------------------------------------
|
||||||
@ -317,40 +395,42 @@ minetest.register_node("towercrane:base", {
|
|||||||
return
|
return
|
||||||
end
|
end
|
||||||
local meta = minetest.get_meta(pos)
|
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
|
if not player or not player:is_player() then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
local owner = meta:get_string("owner")
|
|
||||||
if player:get_player_name() ~= owner then
|
if player:get_player_name() ~= owner then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
-- destroy area and crane
|
||||||
local dir = minetest.string_to_pos(meta:get_string("dir"))
|
|
||||||
local height = meta:get_int("height")
|
|
||||||
local width = meta:get_int("width")
|
|
||||||
if dir ~= nil and height ~= nil and width ~= nil then
|
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
|
end
|
||||||
--check for correct size format
|
|
||||||
size = string.split(fields.size, ",")
|
-- evaluate user input
|
||||||
if #size == 2 then
|
height, width = check_input(fields)
|
||||||
local height = tonumber(size[1])
|
if height ~= 0 then
|
||||||
local width = tonumber(size[2])
|
meta:set_int("height", height)
|
||||||
if height ~= nil and width ~= nil then
|
meta:set_int("width", width)
|
||||||
height = math.max(height, 8)
|
meta:set_string("infotext", "Crane size: " .. height .. "," .. width)
|
||||||
height = math.min(height, towercrane.max_height)
|
if dir ~= nil then
|
||||||
width = math.max(width, 8)
|
if check_space(table.copy(pos), dir, height, width) then
|
||||||
width = math.min(width, towercrane.max_width)
|
-- add protection area
|
||||||
meta:set_int("height", height)
|
local id = protect_area(table.copy(pos), table.copy(dir), height, width, owner)
|
||||||
meta:set_int("width", width)
|
if id ~= nil then
|
||||||
meta:set_string("infotext", "Crane size: " .. height .. "," .. width)
|
meta:set_int("id", id)
|
||||||
if dir ~= nil then
|
construct_crane(table.copy(pos), table.copy(dir), height, width, owner)
|
||||||
if check_space(table.copy(pos), dir, height, width) then
|
|
||||||
construct_crane(table.copy(pos), dir, height, width, owner)
|
|
||||||
else
|
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
|
end
|
||||||
|
else
|
||||||
|
minetest.chat_send_player(owner, "Too less space to raise up the tower crane!")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -362,13 +442,19 @@ minetest.register_node("towercrane:base", {
|
|||||||
local dir = minetest.string_to_pos(meta:get_string("dir"))
|
local dir = minetest.string_to_pos(meta:get_string("dir"))
|
||||||
local height = meta:get_int("height")
|
local height = meta:get_int("height")
|
||||||
local width = meta:get_int("width")
|
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
|
-- remove crane
|
||||||
if dir ~= nil and height ~= nil and width ~= nil then
|
if dir ~= nil and height ~= nil and width ~= nil then
|
||||||
dig_crane(pos, dir, height, width)
|
remove_crane(pos, dir, height, width)
|
||||||
end
|
end
|
||||||
-- remove hook
|
-- remove hook
|
||||||
local id = minetest.hash_node_position(pos)
|
id = minetest.hash_node_position(pos)
|
||||||
if towercrane.id then
|
if towercrane.id then
|
||||||
towercrane.id:remove()
|
towercrane.id:remove()
|
||||||
towercrane.id = nil
|
towercrane.id = nil
|
||||||
@ -427,6 +513,7 @@ minetest.register_node("towercrane:mast_ctrl_on", {
|
|||||||
"towercrane_mast_ctrl.png",
|
"towercrane_mast_ctrl.png",
|
||||||
"towercrane_mast_ctrl.png",
|
"towercrane_mast_ctrl.png",
|
||||||
},
|
},
|
||||||
|
-- switch the crane OFF
|
||||||
on_rightclick = function (pos, node, clicker)
|
on_rightclick = function (pos, node, clicker)
|
||||||
local meta = minetest.get_meta(pos)
|
local meta = minetest.get_meta(pos)
|
||||||
if not clicker or not clicker:is_player() then
|
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",
|
||||||
"towercrane_mast_ctrl.png",
|
"towercrane_mast_ctrl.png",
|
||||||
},
|
},
|
||||||
|
-- switch the crane ON
|
||||||
on_rightclick = function (pos, node, clicker)
|
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)
|
local meta = minetest.get_meta(pos)
|
||||||
-- only the owner is allowed to switch
|
-- only the owner is allowed to switch
|
||||||
if not clicker or not clicker:is_player() then
|
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)
|
local id = minetest.hash_node_position(pos)
|
||||||
towercrane.id = place_hook(table.copy(pos), dir)
|
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 height = meta:get_int("height")
|
||||||
local width = meta:get_int("width")
|
local width = meta:get_int("width")
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user