towercrane/init.lua.org
Joachim Stolberg a6f250a862 first try
2017-06-05 14:57:26 +02:00

15 KiB
Raw Blame History

[[

Tower Crane (Liebherr) Mod by JoSt

Copyright (C) 2017 Joachim Stolberg LGPLv2.1+ See LICENSE for more information

]]

towercrane = {}

local hook = { physical = true, should be true, otherwise you dive into the underground collisionbox = {-0.2, -0.2, -0.2, 0.2, 0.2, 0.2}, Groesse des Wuerfels bei Kollisionen collide_with_objects = false, visual = "cube", Object als Wuerfel visual_size = {x=0.4, y=0.4}, Groesse des sichtbaren Wuerfels 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, }

":" methode von "hook" (self ist versteckt) function hook:on_rightclick(clicker) if self.driver and clicker == self.driver then aussteigen? clicker:set_detach() self.driver = nil elseif not self.driver then einsteigen? self.driver = clicker clicker:set_attach(self.object, "", {x=0,y=0,z=0}, {x=0,y=0,z=0}) end end

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

self.object:setvelocity({x=vx, y=self.speed_up,z=vz}) else self.object:setvelocity({x=0, y=0,z=0}) end end

LuaEntitySAO (non-player moving things): see http://dev.minetest.net/LuaEntitySAO 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) end

local function turnleft(dir) local facedir = minetest.dir_to_facedir(dir) return minetest.facedir_to_dir((facedir + 3) % 4) end

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 end

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 end

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") end

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=1}, formspec = set_formspec,

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,

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") local org_pos = table.copy(pos) 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, 24) width = math.max(width, 8) width = math.min(width, 24) meta:set_int("height", height) meta:set_int("width", width) meta:set_string("infotext", "Crane size: " .. height .. "," .. width) if dir ~= nil then construct_crane(org_pos, dir, height, width, owner) end end end end,

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")

if dir ~= nil and height ~= nil and width ~= nil then dig_crane(pos, dir, height, width) end end, })

minetest.register_on_leaveplayer(function(ObjectRef, timed_out) print("Schade") end )

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}, })

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}, })

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 else

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}, })

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 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 - 1

pos2 = far/left 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 - 4 + 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}, })

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}, })

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}, })