diff options
| -rw-r--r-- | config.lua | 6 | ||||
| -rw-r--r-- | init.lua | 965 | 
2 files changed, 490 insertions, 481 deletions
| @@ -4,5 +4,11 @@ towercrane.max_height = 24  -- Maximum crane width in blocks (12..n)  towercrane.max_width = 24 +-- Crane rope lenght in block (max_height .. max_height+x) +towercrane.rope_length = 24 +  -- Gain factor for the crane sound (0.0 to 1)  towercrane.gain = 1 + +-- Recipe available (true/false) +towercrane.recipe = true @@ -1,19 +1,20 @@  --[[ -    Tower Crane Mod -    =============== - -    v0.03 by JoSt -     -    Copyright (C) 2017 Joachim Stolberg -    LGPLv2.1+ -    See LICENSE.txt for more information - -    History: -    2017-06-04  v0.01  first version -    2017-06-06  v0.02  Hook bugfix -    2017-06-07  v0.03  fixed 2 bugs, added config.lua and sound -     +	Tower Crane Mod +	=============== + +	v0.04 by JoSt +	 +	Copyright (C) 2017 Joachim Stolberg +	LGPLv2.1+ +	See LICENSE.txt for more information + +	History: +	2017-06-04  v0.01  first version +	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 +	  ]]-- @@ -25,122 +26,122 @@ dofile(minetest.get_modpath("towercrane") .. "/config.lua")  --##  Tower Crane Hook  --##################################################################################################  local hook = { -    physical = true,  -    collisionbox = {-0.2, -0.2, -0.2, 0.2, 0.2, 0.2}, -    collide_with_objects = false,    -    visual = "cube", -    visual_size = {x=0.6, y=0.6}, -    textures = { -        "towercrane_hook.png", -        "towercrane_hook.png", -        "towercrane_hook.png", -        "towercrane_hook.png", -        "towercrane_hook.png", -        "towercrane_hook.png", -    }, -    groups = {cracky=1}, -    -- local variabels -    driver = nil, -    speed_forward=0, -    speed_right=0, -    speed_up=0, -    sound=nil, +	physical = true,  +	collisionbox = {-0.2, -0.2, -0.2, 0.2, 0.2, 0.2}, +	collide_with_objects = false,    +	visual = "cube", +	visual_size = {x=0.6, y=0.6}, +	textures = { +		"towercrane_hook.png", +		"towercrane_hook.png", +		"towercrane_hook.png", +		"towercrane_hook.png", +		"towercrane_hook.png", +		"towercrane_hook.png", +	}, +	groups = {cracky=1}, +	-- local variabels +	driver = nil, +	speed_forward=0, +	speed_right=0, +	speed_up=0, +	sound=nil,  }  ----------------------------------------------------------------------------------------------------  -- Enter/leave the Hook  ----------------------------------------------------------------------------------------------------  function hook:on_rightclick(clicker) -    local name = clicker:get_player_name() -    if self.driver and clicker == self.driver then  -- leave? -        clicker:set_detach() -        default.player_attached[name] = false -        default.player_set_animation(clicker, "stand" , 10) -        self.driver = nil -        if self.sound ~= nil then -            minetest.sound_stop(self.sound) -            self.sound = nil -        end -    elseif not self.driver then                     -- enter? -        self.driver = clicker -        clicker:set_attach(self.object, "", {x=0,y=15,z=-3}, {x=0,y=0,z=0}) -        default.player_attached[name] = true -        default.player_set_animation(clicker, "sit" , 10) -    end +	local name = clicker:get_player_name() +	if self.driver and clicker == self.driver then  -- leave? +		clicker:set_detach() +		default.player_attached[name] = false +		default.player_set_animation(clicker, "stand" , 10) +		self.driver = nil +		if self.sound ~= nil then +			minetest.sound_stop(self.sound) +			self.sound = nil +		end +	elseif not self.driver then                     -- enter? +		self.driver = clicker +		clicker:set_attach(self.object, "", {x=0,y=15,z=-3}, {x=0,y=0,z=0}) +		default.player_attached[name] = true +		default.player_set_animation(clicker, "sit" , 10) +	end  end  ----------------------------------------------------------------------------------------------------  -- Hook control  ----------------------------------------------------------------------------------------------------  function hook:on_step(dtime) -    -- remove hook from  last visit -    if self.pos1 == nil or self.pos2 == nil then -        self.object:remove() -        return -    end -    if self.driver then -        local ctrl = self.driver:get_player_control() -        local yaw = self.driver:get_look_horizontal() -        local pos = self.driver:getpos() -        local max_speed = 5 -        local velocity = 0.5 - -        if ctrl.up then             -- forward -            self.speed_forward = math.min(self.speed_forward + velocity, max_speed) -        elseif ctrl.down then       -- backward -            self.speed_forward = math.max(self.speed_forward - velocity, -max_speed) -        elseif self.speed_forward > 0 then -            self.speed_forward = self.speed_forward - velocity -        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 -            self.speed_right = math.max(self.speed_right - velocity, -max_speed) -        elseif self.speed_right > 0 then -            self.speed_right = self.speed_right - velocity -        elseif self.speed_right < 0 then -            self.speed_right = self.speed_right + velocity -        end - -        if ctrl.jump then           -- up -            self.speed_up = math.min(self.speed_up + velocity, 5) -        elseif ctrl.sneak then      -- down -            self.speed_up = math.max(self.speed_up - velocity, -5) -        elseif self.speed_up > 0 then -            self.speed_up = self.speed_up - velocity -        elseif self.speed_up < 0 then -            self.speed_up = self.speed_up + velocity -        end - -        -- calculate the direction vector -        local vx = math.cos(yaw+math.pi/2) * self.speed_forward + math.cos(yaw) * self.speed_right -        local vz = math.sin(yaw+math.pi/2) * self.speed_forward + math.sin(yaw) * self.speed_right - -        -- check if outside of the construction area -        if pos.x < self.pos1.x then vx= velocity end -        if pos.x > self.pos2.x then vx= -velocity end -        if pos.y < self.pos1.y then self.speed_up=  velocity end -        if pos.y > self.pos2.y then self.speed_up= -velocity end -        if pos.z < self.pos1.z then vz=  velocity end -        if pos.z > self.pos2.z then vz= -velocity end - -        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, -                                                 gain=towercrane.gain, max_hear_distance=20, -                                                 loop=true}) -            end -        elseif self.sound ~= nil then -            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}) -    end +	-- remove hook from  last visit +	if self.pos1 == nil or self.pos2 == nil then +		self.object:remove() +		return +	end +	if self.driver then +		local ctrl = self.driver:get_player_control() +		local yaw = self.driver:get_look_horizontal() +		local pos = self.driver:getpos() +		local max_speed = 5 +		local velocity = 0.5 + +		if ctrl.up then             -- forward +			self.speed_forward = math.min(self.speed_forward + velocity, max_speed) +		elseif ctrl.down then       -- backward +			self.speed_forward = math.max(self.speed_forward - velocity, -max_speed) +		elseif self.speed_forward > 0 then +			self.speed_forward = self.speed_forward - velocity +		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 +			self.speed_right = math.max(self.speed_right - velocity, -max_speed) +		elseif self.speed_right > 0 then +			self.speed_right = self.speed_right - velocity +		elseif self.speed_right < 0 then +			self.speed_right = self.speed_right + velocity +		end + +		if ctrl.jump then           -- up +			self.speed_up = math.min(self.speed_up + velocity, 5) +		elseif ctrl.sneak then      -- down +			self.speed_up = math.max(self.speed_up - velocity, -5) +		elseif self.speed_up > 0 then +			self.speed_up = self.speed_up - velocity +		elseif self.speed_up < 0 then +			self.speed_up = self.speed_up + velocity +		end + +		-- calculate the direction vector +		local vx = math.cos(yaw+math.pi/2) * self.speed_forward + math.cos(yaw) * self.speed_right +		local vz = math.sin(yaw+math.pi/2) * self.speed_forward + math.sin(yaw) * self.speed_right + +		-- check if outside of the construction area +		if pos.x < self.pos1.x then vx= velocity end +		if pos.x > self.pos2.x then vx= -velocity end +		if pos.y < self.pos1.y then self.speed_up=  velocity end +		if pos.y > self.pos2.y then self.speed_up= -velocity end +		if pos.z < self.pos1.z then vz=  velocity end +		if pos.z > self.pos2.z then vz= -velocity end + +		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, +												 gain=towercrane.gain, max_hear_distance=20, +												 loop=true}) +			end +		elseif self.sound ~= nil then +			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}) +	end  end  ---------------------------------------------------------------------------------------------------- @@ -155,443 +156,445 @@ minetest.register_entity("towercrane:hook", hook)  --##################################################################################################  local function turnright(dir) -    local facedir = minetest.dir_to_facedir(dir) -    return minetest.facedir_to_dir((facedir + 1) % 4) +	local facedir = minetest.dir_to_facedir(dir) +	return minetest.facedir_to_dir((facedir + 1) % 4)  end  local function turnleft(dir) -    local facedir = minetest.dir_to_facedir(dir) -    return minetest.facedir_to_dir((facedir + 3) % 4) +	local facedir = minetest.dir_to_facedir(dir) +	return minetest.facedir_to_dir((facedir + 3) % 4)  end  ----------------------------------------------------------------------------------------------------  -- Check space for mast and arm  ----------------------------------------------------------------------------------------------------  local function check_space(pos, dir, height, width) -    for i = 1,height+2 do -        pos.y = pos.y + 1 -        if minetest.get_node_or_nil(pos).name ~= "air" then -            return false -        end -    end -     -    pos.x = pos.x + dir.x*2 -    pos.z = pos.z + dir.z*2 -    for i = 1,width+3 do -        pos.x = pos.x + dir.x -        pos.z = pos.z + dir.z -        if minetest.get_node_or_nil(pos).name ~= "air" then -            return false -        end -    end -    return true +	for i = 1,height+2 do +		pos.y = pos.y + 1 +		if minetest.get_node_or_nil(pos).name ~= "air" then +			return false +		end +	end +	 +	pos.x = pos.x + dir.x*2 +	pos.z = pos.z + dir.z*2 +	for i = 1,width+3 do +		pos.x = pos.x + dir.x +		pos.z = pos.z + dir.z +		if minetest.get_node_or_nil(pos).name ~= "air" then +			return false +		end +	end +	return true  end  ----------------------------------------------------------------------------------------------------  -- Constuct mast and arm  ----------------------------------------------------------------------------------------------------  local function construct_crane(pos, dir, height, width, owner) -    pos.y = pos.y + 1 -    minetest.env:add_node(pos, {name="towercrane:mast_ctrl_off", param2=minetest.dir_to_facedir(dir)}) -    local meta = minetest.get_meta(pos) -    meta:set_string("dir", minetest.pos_to_string(dir)) -    meta:set_string("owner", owner) -    meta:set_int("height", height) -    meta:set_int("width", width) - -    for i = 1,height+1 do -        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 -    minetest.env:add_node(pos, {name="towercrane:arm2"}) -    pos.x = pos.x - dir.x -    pos.z = pos.z - dir.z -    minetest.env:add_node(pos, {name="towercrane:arm"}) -    pos.x = pos.x - dir.x -    pos.z = pos.z - dir.z -    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 -        if i % 2 == 0 then -            minetest.env:add_node(pos, {name="towercrane:arm2"}) -        else -            minetest.env:add_node(pos, {name="towercrane:arm"}) -        end -    end +	pos.y = pos.y + 1 +	minetest.env:add_node(pos, {name="towercrane:mast_ctrl_off", param2=minetest.dir_to_facedir(dir)}) +	local meta = minetest.get_meta(pos) +	meta:set_string("dir", minetest.pos_to_string(dir)) +	meta:set_string("owner", owner) +	meta:set_int("height", height) +	meta:set_int("width", width) + +	for i = 1,height+1 do +		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 +	minetest.env:add_node(pos, {name="towercrane:arm2"}) +	pos.x = pos.x - dir.x +	pos.z = pos.z - dir.z +	minetest.env:add_node(pos, {name="towercrane:arm"}) +	pos.x = pos.x - dir.x +	pos.z = pos.z - dir.z +	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 +		if i % 2 == 0 then +			minetest.env:add_node(pos, {name="towercrane:arm2"}) +		else +			minetest.env:add_node(pos, {name="towercrane:arm"}) +		end +	end  end  ----------------------------------------------------------------------------------------------------  -- Remove the crane  ----------------------------------------------------------------------------------------------------  local function dig_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"}) -    end - -    pos.y = pos.y - 2 -    pos.x = pos.x - dir.x -    pos.z = pos.z - dir.z -    minetest.env:remove_node(pos, {name="towercrane:arm2"}) -    pos.x = pos.x - dir.x -    pos.z = pos.z - dir.z -    minetest.env:remove_node(pos, {name="towercrane:arm"}) -    pos.x = pos.x - dir.x -    pos.z = pos.z - dir.z -    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 -        if i % 2 == 0 then -            minetest.env:remove_node(pos, {name="towercrane:arm2"}) -        else -            minetest.env:remove_node(pos, {name="towercrane:arm"}) -        end -    end +	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"}) +	end + +	pos.y = pos.y - 2 +	pos.x = pos.x - dir.x +	pos.z = pos.z - dir.z +	minetest.env:remove_node(pos, {name="towercrane:arm2"}) +	pos.x = pos.x - dir.x +	pos.z = pos.z - dir.z +	minetest.env:remove_node(pos, {name="towercrane:arm"}) +	pos.x = pos.x - dir.x +	pos.z = pos.z - dir.z +	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 +		if i % 2 == 0 then +			minetest.env:remove_node(pos, {name="towercrane:arm2"}) +		else +			minetest.env:remove_node(pos, {name="towercrane:arm"}) +		end +	end  end  ----------------------------------------------------------------------------------------------------  -- Place the hook in front of the base  ----------------------------------------------------------------------------------------------------  local function place_hook(pos, dir) -    pos.y = pos.y - 1 -    pos.x = pos.x + dir.x -    pos.z = pos.z + dir.z -    return minetest.add_entity(pos, "towercrane:hook") +	pos.y = pos.y - 1 +	pos.x = pos.x + dir.x +	pos.z = pos.z + dir.z +	return minetest.add_entity(pos, "towercrane:hook")  end  ----------------------------------------------------------------------------------------------------  -- Register Crane base  ----------------------------------------------------------------------------------------------------  minetest.register_node("towercrane:base", { -    description = "Tower Crane Base", -    inventory_image = "towercrane_invent.png", -    tiles = { -        "towercrane_base_top.png", -        "towercrane_base.png", -        "towercrane_base.png", -        "towercrane_base.png", -        "towercrane_base.png", -        "towercrane_base.png", -    }, -    paramtype2 = "facedir", -    is_ground_content = false, -    groups = {cracky=2}, -    formspec = set_formspec, - -    -- set meta data (form for crane height and width, dir of the arm) -    after_place_node = function(pos, placer) -        local meta = minetest.get_meta(pos) -        local owner = placer:get_player_name() -        meta:set_string("owner", owner) -        local formspec = "size[5,4]".. -            "label[0,0;Construction area size]" .. -            "field[1,1.5;3,1;size;height,width;]" .. -            "button_exit[1,2;2,1;exit;Save]" -        meta:set_string("formspec", formspec) - -        local fdir = minetest.dir_to_facedir(placer:get_look_dir(), false) -        local dir = minetest.facedir_to_dir(fdir) -        meta:set_string("dir", minetest.pos_to_string(dir)) -    end, - -    -- evaluate user input (height, width), destroyed old crane and build a new one with -    -- the given size -    on_receive_fields = function(pos, formname, fields, player) -        if fields.size == nil then -            return -        end -        local meta = minetest.get_meta(pos) - -        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") -        if dir ~= nil and height ~= nil and width ~= nil then -           dig_crane(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) -                    else -                        minetest.chat_send_player(owner, "Too less space to raise up the tower crane!") -                    end -                end -            end -        end -    end, - -    -- remove mast and arm if base gets destroyed -    on_destruct = function(pos) -        local meta = minetest.get_meta(pos) -        local dir = minetest.string_to_pos(meta:get_string("dir")) -        local height = meta:get_int("height") -        local width = meta:get_int("width") - -        -- remove crane -        if dir ~= nil and height ~= nil and width ~= nil then -           dig_crane(pos, dir, height, width) -        end -        -- remove hook -        local id = minetest.hash_node_position(pos) -        if towercrane.id then -            towercrane.id:remove() -            towercrane.id = nil -        end -    end, +	description = "Tower Crane Base", +	inventory_image = "towercrane_invent.png", +	tiles = { +		"towercrane_base_top.png", +		"towercrane_base.png", +		"towercrane_base.png", +		"towercrane_base.png", +		"towercrane_base.png", +		"towercrane_base.png", +	}, +	paramtype2 = "facedir", +	is_ground_content = false, +	groups = {cracky=2}, +	formspec = set_formspec, + +	-- set meta data (form for crane height and width, dir of the arm) +	after_place_node = function(pos, placer) +		local meta = minetest.get_meta(pos) +		local owner = placer:get_player_name() +		meta:set_string("owner", owner) +		local formspec = "size[5,4]".. +			"label[0,0;Construction area size]" .. +			"field[1,1.5;3,1;size;height,width;]" .. +			"button_exit[1,2;2,1;exit;Save]" +		meta:set_string("formspec", formspec) + +		local fdir = minetest.dir_to_facedir(placer:get_look_dir(), false) +		local dir = minetest.facedir_to_dir(fdir) +		meta:set_string("dir", minetest.pos_to_string(dir)) +	end, + +	-- evaluate user input (height, width), destroyed old crane and build a new one with +	-- the given size +	on_receive_fields = function(pos, formname, fields, player) +		if fields.size == nil then +			return +		end +		local meta = minetest.get_meta(pos) + +		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") +		if dir ~= nil and height ~= nil and width ~= nil then +		   dig_crane(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) +					else +						minetest.chat_send_player(owner, "Too less space to raise up the tower crane!") +					end +				end +			end +		end +	end, + +	-- remove mast and arm if base gets destroyed +	on_destruct = function(pos) +		local meta = minetest.get_meta(pos) +		local dir = minetest.string_to_pos(meta:get_string("dir")) +		local height = meta:get_int("height") +		local width = meta:get_int("width") + +		-- remove crane +		if dir ~= nil and height ~= nil and width ~= nil then +		   dig_crane(pos, dir, height, width) +		end +		-- remove hook +		local id = minetest.hash_node_position(pos) +		if towercrane.id then +			towercrane.id:remove() +			towercrane.id = nil +		end +	end,  })  ----------------------------------------------------------------------------------------------------  -- Register Crane balance  ----------------------------------------------------------------------------------------------------  minetest.register_node("towercrane:balance", { -    description = "Tower Crane Balance", -    tiles = { -        "towercrane_base.png", -        "towercrane_base.png", -        "towercrane_base.png", -        "towercrane_base.png", -        "towercrane_base.png", -        "towercrane_base.png", -    }, -    paramtype2 = "facedir", -    is_ground_content = false, -    groups = {crumbly=0, not_in_creative_inventory=1}, +	description = "Tower Crane Balance", +	tiles = { +		"towercrane_base.png", +		"towercrane_base.png", +		"towercrane_base.png", +		"towercrane_base.png", +		"towercrane_base.png", +		"towercrane_base.png", +	}, +	paramtype2 = "facedir", +	is_ground_content = false, +	groups = {crumbly=0, not_in_creative_inventory=1},  })  ----------------------------------------------------------------------------------------------------  -- Register Crane mast  ----------------------------------------------------------------------------------------------------  minetest.register_node("towercrane:mast", { -    description = "Tower Crane Mast", -    drawtype = "glasslike_framed", -    tiles = { -        "towercrane_mast.png", -        "towercrane_mast.png", -        "towercrane_mast.png", -        "towercrane_mast.png", -        "towercrane_mast.png", -        "towercrane_mast.png", -    }, -    paramtype2 = "facedir", -    is_ground_content = false, -    groups = {crumbly=0, not_in_creative_inventory=1}, +	description = "Tower Crane Mast", +	drawtype = "glasslike_framed", +	tiles = { +		"towercrane_mast.png", +		"towercrane_mast.png", +		"towercrane_mast.png", +		"towercrane_mast.png", +		"towercrane_mast.png", +		"towercrane_mast.png", +	}, +	paramtype2 = "facedir", +	is_ground_content = false, +	groups = {crumbly=0, not_in_creative_inventory=1},  })  ----------------------------------------------------------------------------------------------------  -- Register Crane Switch (on)  ----------------------------------------------------------------------------------------------------  minetest.register_node("towercrane:mast_ctrl_on", { -    description = "Tower Crane Mast Ctrl On", -    drawtype = "node", -    tiles = { -        "towercrane_mast_ctrl.png", -        "towercrane_mast_ctrl.png", -        "towercrane_mast_ctrl_on.png", -        "towercrane_mast_ctrl_on.png", -        "towercrane_mast_ctrl.png", -        "towercrane_mast_ctrl.png", -    }, -    on_rightclick = function (pos, node, clicker) -        local meta = minetest.get_meta(pos) -        if not clicker or not clicker:is_player() then -            return -        end -        if clicker:get_player_name() ~= meta:get_string("owner") then -            return -        end -        node.name = "towercrane:mast_ctrl_off" -        minetest.swap_node(pos, node) - -        local id = minetest.hash_node_position(pos) -        if towercrane.id then -            towercrane.id:remove() -            towercrane.id = nil -        end -    end, - -    on_construct = function(pos) -        local meta = minetest.get_meta(pos) -        meta:set_string("infotext", "Switch crane on/off") -    end, - -    after_place_node = function(pos, placer, itemstack, pointed_thing) -        local meta = minetest.get_meta(pos) -        local owner = placer:get_player_name() -        meta:set_string("owner", owner) -    end, - -    paramtype2 = "facedir", -    is_ground_content = false, -    groups = {crumbly=0, not_in_creative_inventory=1}, +	description = "Tower Crane Mast Ctrl On", +	drawtype = "node", +	tiles = { +		"towercrane_mast_ctrl.png", +		"towercrane_mast_ctrl.png", +		"towercrane_mast_ctrl_on.png", +		"towercrane_mast_ctrl_on.png", +		"towercrane_mast_ctrl.png", +		"towercrane_mast_ctrl.png", +	}, +	on_rightclick = function (pos, node, clicker) +		local meta = minetest.get_meta(pos) +		if not clicker or not clicker:is_player() then +			return +		end +		if clicker:get_player_name() ~= meta:get_string("owner") then +			return +		end +		node.name = "towercrane:mast_ctrl_off" +		minetest.swap_node(pos, node) + +		local id = minetest.hash_node_position(pos) +		if towercrane.id then +			towercrane.id:remove() +			towercrane.id = nil +		end +	end, + +	on_construct = function(pos) +		local meta = minetest.get_meta(pos) +		meta:set_string("infotext", "Switch crane on/off") +	end, + +	after_place_node = function(pos, placer, itemstack, pointed_thing) +		local meta = minetest.get_meta(pos) +		local owner = placer:get_player_name() +		meta:set_string("owner", owner) +	end, + +	paramtype2 = "facedir", +	is_ground_content = false, +	groups = {crumbly=0, not_in_creative_inventory=1},  })  ----------------------------------------------------------------------------------------------------  -- Register Crane Switch (off)  ----------------------------------------------------------------------------------------------------  minetest.register_node("towercrane:mast_ctrl_off", { -    description = "Tower Crane Mast Ctrl Off", -    drawtype = "node", -    tiles = { -        "towercrane_mast_ctrl.png", -        "towercrane_mast_ctrl.png", -        "towercrane_mast_ctrl_off.png", -        "towercrane_mast_ctrl_off.png", -        "towercrane_mast_ctrl.png", -      "towercrane_mast_ctrl.png", -    }, -    on_rightclick = function (pos, node, clicker) -        -- switch switch on, 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 -            return -        end -        if clicker:get_player_name() ~= meta:get_string("owner") then -            return -        end -        -- swap to the other node -        node.name = "towercrane:mast_ctrl_on" -        minetest.swap_node(pos, node) -        local dir = minetest.string_to_pos(meta:get_string("dir")) -        if pos ~= nil and dir ~= nil then -            -- store hook instance in 'towercrane' -            local id = minetest.hash_node_position(pos) -            towercrane.id = place_hook(table.copy(pos), dir) - -            -- calculate the construction area dimension (pos, pos2) -            local height = meta:get_int("height") -            local width = meta:get_int("width") - -            -- pos1 = close/right/below -            dir = turnright(dir) -            local pos1 = vector.add(pos, vector.multiply(dir, width/2)) -            dir = turnleft(dir) -            local pos1 = vector.add(pos1, vector.multiply(dir, 1)) -            pos1.y = pos.y - 2 - height - -            -- pos2 = far/left/above -            local pos2 = vector.add(pos1, vector.multiply(dir, width-1)) -            dir = turnleft(dir) -            pos2 = vector.add(pos2, vector.multiply(dir, width)) -            pos2.y = pos.y - 3 + height - -            -- 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 pos1/pos2 in the hook (LuaEntitySAO) -            towercrane.id:get_luaentity().pos1 = pos1 -            towercrane.id:get_luaentity().pos2 = pos2 -        end -    end, - -    on_construct = function(pos) -        -- add infotext -        local meta = minetest.get_meta(pos) -        meta:set_string("infotext", "Switch crane on/off") -    end, - -    after_place_node = function(pos, placer, itemstack, pointed_thing) -        -- store owner for dig protection -        local meta = minetest.get_meta(pos) -        local owner = placer:get_player_name() -        meta:set_string("owner", owner) -    end, - -    paramtype2 = "facedir", -    is_ground_content = false, -    groups = {crumbly=0, not_in_creative_inventory=1}, +	description = "Tower Crane Mast Ctrl Off", +	drawtype = "node", +	tiles = { +		"towercrane_mast_ctrl.png", +		"towercrane_mast_ctrl.png", +		"towercrane_mast_ctrl_off.png", +		"towercrane_mast_ctrl_off.png", +		"towercrane_mast_ctrl.png", +	  "towercrane_mast_ctrl.png", +	}, +	on_rightclick = function (pos, node, clicker) +		-- switch switch on, 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 +			return +		end +		if clicker:get_player_name() ~= meta:get_string("owner") then +			return +		end +		-- swap to the other node +		node.name = "towercrane:mast_ctrl_on" +		minetest.swap_node(pos, node) +		local dir = minetest.string_to_pos(meta:get_string("dir")) +		if pos ~= nil and dir ~= nil then +			-- store hook instance in 'towercrane' +			local id = minetest.hash_node_position(pos) +			towercrane.id = place_hook(table.copy(pos), dir) + +			-- calculate the construction area dimension (pos, pos2) +			local height = meta:get_int("height") +			local width = meta:get_int("width") + +			-- pos1 = close/right/below +			dir = turnright(dir) +			local pos1 = vector.add(pos, vector.multiply(dir, width/2)) +			dir = turnleft(dir) +			local pos1 = vector.add(pos1, vector.multiply(dir, 1)) +			pos1.y = pos.y - 2 + height - towercrane.rope_length + +			-- pos2 = far/left/above +			local pos2 = vector.add(pos1, vector.multiply(dir, width-1)) +			dir = turnleft(dir) +			pos2 = vector.add(pos2, vector.multiply(dir, width)) +			pos2.y = pos.y - 3 + height + +			-- 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 pos1/pos2 in the hook (LuaEntitySAO) +			towercrane.id:get_luaentity().pos1 = pos1 +			towercrane.id:get_luaentity().pos2 = pos2 +		end +	end, + +	on_construct = function(pos) +		-- add infotext +		local meta = minetest.get_meta(pos) +		meta:set_string("infotext", "Switch crane on/off") +	end, + +	after_place_node = function(pos, placer, itemstack, pointed_thing) +		-- store owner for dig protection +		local meta = minetest.get_meta(pos) +		local owner = placer:get_player_name() +		meta:set_string("owner", owner) +	end, + +	paramtype2 = "facedir", +	is_ground_content = false, +	groups = {crumbly=0, not_in_creative_inventory=1},  })  ----------------------------------------------------------------------------------------------------  -- Register Crane arm 1  ----------------------------------------------------------------------------------------------------  minetest.register_node("towercrane:arm", { -    description = "Tower Crane Arm", -    drawtype = "glasslike_framed", -    tiles = { -        "towercrane_arm.png", -        "towercrane_arm.png", -        "towercrane_arm.png", -        "towercrane_arm.png", -        "towercrane_arm.png", -        "towercrane_arm.png", -    }, -    paramtype2 = "facedir", -    is_ground_content = false, -    groups = {crumbly=0, not_in_creative_inventory=1}, +	description = "Tower Crane Arm", +	drawtype = "glasslike_framed", +	tiles = { +		"towercrane_arm.png", +		"towercrane_arm.png", +		"towercrane_arm.png", +		"towercrane_arm.png", +		"towercrane_arm.png", +		"towercrane_arm.png", +	}, +	paramtype2 = "facedir", +	is_ground_content = false, +	groups = {crumbly=0, not_in_creative_inventory=1},  })  ----------------------------------------------------------------------------------------------------  -- Register Crane arm 2  ----------------------------------------------------------------------------------------------------  minetest.register_node("towercrane:arm2", { -    description = "Tower Crane Arm2", -    drawtype = "glasslike_framed", -    tiles = { -        "towercrane_arm2.png", -        "towercrane_arm2.png", -        "towercrane_arm2.png", -        "towercrane_arm2.png", -        "towercrane_arm2.png", -        "towercrane_arm2.png", -    }, -    paramtype2 = "facedir", -    is_ground_content = false, -    groups = {crumbly=0, not_in_creative_inventory=1}, +	description = "Tower Crane Arm2", +	drawtype = "glasslike_framed", +	tiles = { +		"towercrane_arm2.png", +		"towercrane_arm2.png", +		"towercrane_arm2.png", +		"towercrane_arm2.png", +		"towercrane_arm2.png", +		"towercrane_arm2.png", +	}, +	paramtype2 = "facedir", +	is_ground_content = false, +	groups = {crumbly=0, not_in_creative_inventory=1},  })  ----------------------------------------------------------------------------------------------------  -- Register Recipe  ---------------------------------------------------------------------------------------------------- -minetest.register_craft({ -	output = "towercrane:base", -	recipe = { -		{"default:steel_ingot", "default:steel_ingot", "default:steel_ingot"}, -		{"default:steel_ingot", "", ""}, -		{"default:steel_ingot", "dye:yellow", ""} -	} -}) +if towercrane.recipe then +	minetest.register_craft({ +		output = "towercrane:base", +		recipe = { +			{"default:steel_ingot", "default:steel_ingot", "default:steel_ingot"}, +			{"default:steel_ingot", "", ""}, +			{"default:steel_ingot", "dye:yellow", ""} +		} +	}) +end | 
