mirror of
https://github.com/minetest-mods/towercrane.git
synced 2024-11-22 15:23:51 +01:00
Switched from entity model to real fly privs
This commit is contained in:
parent
01e08cbb30
commit
b8fe25c188
278
init.lua
278
init.lua
@ -21,6 +21,7 @@
|
|||||||
2017-08-19 v0.09 crane protection area to prevent crane clusters
|
2017-08-19 v0.09 crane protection area to prevent crane clusters
|
||||||
2017-08-27 v0.10 hook instance and sound switch off bug fixes
|
2017-08-27 v0.10 hook instance and sound switch off bug fixes
|
||||||
2017-09-09 v0.11 further player bugfixes
|
2017-09-09 v0.11 further player bugfixes
|
||||||
|
2017-09-20 v0.12 Switched from entity model to real fly privs
|
||||||
|
|
||||||
]]--
|
]]--
|
||||||
|
|
||||||
@ -28,7 +29,6 @@
|
|||||||
MIN_SIZE = 8
|
MIN_SIZE = 8
|
||||||
|
|
||||||
towercrane = {}
|
towercrane = {}
|
||||||
towercrane.hook = {}
|
|
||||||
|
|
||||||
dofile(minetest.get_modpath("towercrane") .. "/config.lua")
|
dofile(minetest.get_modpath("towercrane") .. "/config.lua")
|
||||||
|
|
||||||
@ -97,139 +97,95 @@ local function remove_crane_data(pos)
|
|||||||
update_mod_storage()
|
update_mod_storage()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--##################################################################################################
|
--##################################################################################################
|
||||||
--## Tower Crane Hook
|
--## Tower Crane Hook (player)
|
||||||
--##################################################################################################
|
--##################################################################################################
|
||||||
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,
|
|
||||||
}
|
|
||||||
|
|
||||||
----------------------------------------------------------------------------------------------------
|
-- give/take player fly privs
|
||||||
-- Enter/leave the Hook
|
local function fly_privs(player, enable)
|
||||||
----------------------------------------------------------------------------------------------------
|
local privs = minetest.get_player_privs(player:get_player_name())
|
||||||
function hook:on_rightclick(clicker)
|
local physics = player:get_physics_override()
|
||||||
local name = clicker:get_player_name()
|
if privs then
|
||||||
if self.driver and clicker == self.driver then -- leave?
|
if enable == true then
|
||||||
clicker:set_detach()
|
if privs["fast"] then
|
||||||
default.player_attached[name] = false
|
player:set_attribute("store_fast", "1")
|
||||||
default.player_set_animation(clicker, "stand" , 10)
|
else
|
||||||
self.driver = nil
|
player:set_attribute("store_fast", "0")
|
||||||
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 yaw == nil or pos == nil or ctrl == nil then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
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
|
|
||||||
|
|
||||||
-- 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, pos=pos,
|
|
||||||
gain=towercrane.gain, max_hear_distance=20,
|
|
||||||
loop=true})
|
|
||||||
end
|
end
|
||||||
elseif self.sound ~= nil then
|
privs["fly"] = true
|
||||||
minetest.sound_stop(self.sound)
|
privs["fast"] = nil
|
||||||
self.sound = nil
|
physics.speed = 0.5
|
||||||
|
else
|
||||||
|
privs["fly"] = nil
|
||||||
|
if player:get_attribute("store_fast") == "1" then
|
||||||
|
privs["fast"] = true
|
||||||
|
else
|
||||||
|
privs["fast"] = nil
|
||||||
|
end
|
||||||
|
physics.speed = 1
|
||||||
end
|
end
|
||||||
|
player:set_physics_override(physics)
|
||||||
self.object:setvelocity({x=vx, y=self.speed_up,z=vz})
|
minetest.set_player_privs(player:get_player_name(), privs)
|
||||||
else
|
|
||||||
self.object:setvelocity({x=0, y=0,z=0})
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
----------------------------------------------------------------------------------------------------
|
local function control_player(pos, pos1, pos2, player)
|
||||||
-- LuaEntitySAO (non-player moving things): see http://dev.minetest.net/LuaEntitySAO
|
if player then
|
||||||
----------------------------------------------------------------------------------------------------
|
local meta = minetest.get_meta(pos)
|
||||||
minetest.register_entity("towercrane:hook", hook)
|
local running = meta:get_int("running")
|
||||||
|
if running == 1 then
|
||||||
|
-- check if outside of the construction area
|
||||||
|
local correction = false
|
||||||
|
local pl_pos = player:getpos()
|
||||||
|
if pl_pos then
|
||||||
|
if pl_pos.x < pos1.x then pl_pos.x = pos1.x; correction = true end
|
||||||
|
if pl_pos.x > pos2.x then pl_pos.x = pos2.x; correction = true end
|
||||||
|
if pl_pos.y < pos1.y then pl_pos.y = pos1.y; correction = true end
|
||||||
|
if pl_pos.y > pos2.y then pl_pos.y = pos2.y; correction = true end
|
||||||
|
if pl_pos.z < pos1.z then pl_pos.z = pos1.z; correction = true end
|
||||||
|
if pl_pos.z > pos2.z then pl_pos.z = pos2.z; correction = true end
|
||||||
|
if correction == true then
|
||||||
|
player:setpos(pl_pos)
|
||||||
|
end
|
||||||
|
|
||||||
|
minetest.after(2, control_player, pos, pos1, pos2, player)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
local meta = minetest.get_meta(pos)
|
||||||
|
meta:set_int("running", 0)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Place the player in front of the base and give fly privs
|
||||||
|
local function place_hook(pos, dir, player, pos1, pos2)
|
||||||
|
if player then
|
||||||
|
local switch_pos = {x=pos.x, y=pos.y, z=pos.z}
|
||||||
|
local meta = minetest.get_meta(switch_pos)
|
||||||
|
meta:set_int("running", 1)
|
||||||
|
-- place the player
|
||||||
|
pos.y = pos.y - 1
|
||||||
|
pos.x = pos.x + dir.x
|
||||||
|
pos.z = pos.z + dir.z
|
||||||
|
player:setpos(pos)
|
||||||
|
-- set privs
|
||||||
|
fly_privs(player, true)
|
||||||
|
-- control player every 2 sec.
|
||||||
|
minetest.after(2, control_player, switch_pos, pos1, pos2, player)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Normalize the player privs
|
||||||
|
local function remove_hook(pos, player)
|
||||||
|
if player then
|
||||||
|
if pos then
|
||||||
|
local meta = minetest.get_meta(pos)
|
||||||
|
meta:set_int("running", 0)
|
||||||
|
end
|
||||||
|
fly_privs(player, nil)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
--##################################################################################################
|
--##################################################################################################
|
||||||
--## Tower Crane
|
--## Tower Crane
|
||||||
@ -329,38 +285,6 @@ local function remove_crane(pos, dir, height, width)
|
|||||||
crane_body_plan(table.copy(pos), dir, height, width, remove, {})
|
crane_body_plan(table.copy(pos), dir, height, width, remove, {})
|
||||||
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")
|
|
||||||
end
|
|
||||||
|
|
||||||
----------------------------------------------------------------------------------------------------
|
|
||||||
-- Remove hook, reset player and stop sound
|
|
||||||
----------------------------------------------------------------------------------------------------
|
|
||||||
local function remove_hook(player, pos, y_offs)
|
|
||||||
-- determine hook_key
|
|
||||||
pos = table.copy(pos)
|
|
||||||
pos.y = pos.y + y_offs
|
|
||||||
local key = minetest.hash_node_position(pos)
|
|
||||||
if player ~= nil then
|
|
||||||
default.player_set_animation(player, "stand" , 10)
|
|
||||||
end
|
|
||||||
local hook = towercrane.hook[key]
|
|
||||||
if hook then
|
|
||||||
-- remove hook
|
|
||||||
hook:remove()
|
|
||||||
if hook and hook:get_luaentity() and hook:get_luaentity().sound ~= nil then
|
|
||||||
-- stop sound
|
|
||||||
minetest.sound_stop(hook:get_luaentity().sound)
|
|
||||||
end
|
|
||||||
towercrane.hook[key] = nil
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
----------------------------------------------------------------------------------------------------
|
----------------------------------------------------------------------------------------------------
|
||||||
-- Check if the given construction area is not already protected
|
-- Check if the given construction area is not already protected
|
||||||
@ -494,8 +418,8 @@ minetest.register_node("towercrane:base", {
|
|||||||
if dir ~= nil and height ~= nil and width ~= nil then
|
if dir ~= nil and height ~= nil and width ~= nil then
|
||||||
remove_crane_data(pos)
|
remove_crane_data(pos)
|
||||||
remove_area(id, owner)
|
remove_area(id, owner)
|
||||||
remove_crane(table.copy(pos), dir, height, width)
|
--remove_crane(table.copy(pos), dir, height, width)
|
||||||
remove_hook(player, pos, 1)
|
remove_hook(pos, player)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- evaluate user input
|
-- evaluate user input
|
||||||
@ -525,6 +449,15 @@ minetest.register_node("towercrane:base", {
|
|||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
|
|
||||||
|
can_dig = function(pos, player)
|
||||||
|
local meta = minetest.get_meta(pos)
|
||||||
|
local owner = meta:get_string("owner")
|
||||||
|
if player:get_player_name() == owner then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
return false
|
||||||
|
end,
|
||||||
|
|
||||||
-- remove mast and arm if base gets destroyed
|
-- remove mast and arm if base gets destroyed
|
||||||
on_destruct = function(pos)
|
on_destruct = function(pos)
|
||||||
local meta = minetest.get_meta(pos)
|
local meta = minetest.get_meta(pos)
|
||||||
@ -545,7 +478,7 @@ minetest.register_node("towercrane:base", {
|
|||||||
end
|
end
|
||||||
-- remove hook
|
-- remove hook
|
||||||
local player = minetest.get_player_by_name(owner)
|
local player = minetest.get_player_by_name(owner)
|
||||||
remove_hook(player, pos, 1)
|
remove_hook({x=pos.x, y=pos.y+1, z=pos.z}, player)
|
||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -595,10 +528,10 @@ minetest.register_node("towercrane:mast_ctrl_on", {
|
|||||||
tiles = {
|
tiles = {
|
||||||
"towercrane_mast_ctrl.png",
|
"towercrane_mast_ctrl.png",
|
||||||
"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",
|
||||||
"towercrane_mast_ctrl.png",
|
"towercrane_mast_ctrl.png",
|
||||||
|
"towercrane_mast_ctrl_on.png",
|
||||||
|
"towercrane_mast_ctrl_on.png",
|
||||||
},
|
},
|
||||||
-- switch the crane OFF
|
-- switch the crane OFF
|
||||||
on_rightclick = function (pos, node, clicker)
|
on_rightclick = function (pos, node, clicker)
|
||||||
@ -613,7 +546,7 @@ minetest.register_node("towercrane:mast_ctrl_on", {
|
|||||||
minetest.swap_node(pos, node)
|
minetest.swap_node(pos, node)
|
||||||
|
|
||||||
local id = minetest.hash_node_position(pos)
|
local id = minetest.hash_node_position(pos)
|
||||||
remove_hook(clicker, pos, 0)
|
remove_hook(pos, clicker)
|
||||||
end,
|
end,
|
||||||
|
|
||||||
on_construct = function(pos)
|
on_construct = function(pos)
|
||||||
@ -641,10 +574,10 @@ minetest.register_node("towercrane:mast_ctrl_off", {
|
|||||||
tiles = {
|
tiles = {
|
||||||
"towercrane_mast_ctrl.png",
|
"towercrane_mast_ctrl.png",
|
||||||
"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",
|
||||||
"towercrane_mast_ctrl.png",
|
"towercrane_mast_ctrl.png",
|
||||||
|
"towercrane_mast_ctrl_off.png",
|
||||||
|
"towercrane_mast_ctrl_off.png",
|
||||||
},
|
},
|
||||||
-- switch the crane ON
|
-- switch the crane ON
|
||||||
on_rightclick = function (pos, node, clicker)
|
on_rightclick = function (pos, node, clicker)
|
||||||
@ -662,10 +595,6 @@ minetest.register_node("towercrane:mast_ctrl_off", {
|
|||||||
minetest.swap_node(pos, node)
|
minetest.swap_node(pos, node)
|
||||||
local dir = minetest.string_to_pos(meta:get_string("dir"))
|
local dir = minetest.string_to_pos(meta:get_string("dir"))
|
||||||
if pos ~= nil and dir ~= nil then
|
if pos ~= nil and dir ~= nil then
|
||||||
-- store hook instance in 'towercrane'
|
|
||||||
local id = minetest.hash_node_position(pos)
|
|
||||||
towercrane.hook[id] = place_hook(table.copy(pos), dir)
|
|
||||||
|
|
||||||
--
|
--
|
||||||
-- calculate the construction area dimension (pos1, pos2)
|
-- calculate the construction area dimension (pos1, pos2)
|
||||||
--
|
--
|
||||||
@ -676,7 +605,7 @@ minetest.register_node("towercrane:mast_ctrl_off", {
|
|||||||
dir = turnright(dir)
|
dir = turnright(dir)
|
||||||
local pos1 = vector.add(pos, vector.multiply(dir, width/2))
|
local pos1 = vector.add(pos, vector.multiply(dir, width/2))
|
||||||
dir = turnleft(dir)
|
dir = turnleft(dir)
|
||||||
local pos1 = vector.add(pos1, vector.multiply(dir, 1))
|
pos1 = vector.add(pos1, vector.multiply(dir, 1))
|
||||||
pos1.y = pos.y - 2 + height - towercrane.rope_length
|
pos1.y = pos.y - 2 + height - towercrane.rope_length
|
||||||
|
|
||||||
-- pos2 = far/left/above
|
-- pos2 = far/left/above
|
||||||
@ -693,9 +622,8 @@ minetest.register_node("towercrane:mast_ctrl_off", {
|
|||||||
pos2.z, pos1.z = pos1.z, pos2.z
|
pos2.z, pos1.z = pos1.z, pos2.z
|
||||||
end
|
end
|
||||||
|
|
||||||
-- store pos1/pos2 in the hook (LuaEntitySAO)
|
dir = minetest.string_to_pos(meta:get_string("dir"))
|
||||||
towercrane.hook[id]:get_luaentity().pos1 = pos1
|
place_hook(pos, dir, clicker, pos1, pos2)
|
||||||
towercrane.hook[id]:get_luaentity().pos2 = pos2
|
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
|
|
||||||
@ -771,4 +699,8 @@ if towercrane.recipe then
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
minetest.register_on_leaveplayer(function(player, timed_out)
|
||||||
|
remove_hook(nil, player)
|
||||||
|
end)
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user