Add node attachment locking.

Uses an entity to prevent player from moving away. Only `space` will
allow the player to move again. The player is put on top of the node
when detaching. While attached, the player can't move and the player
model can not rotate.
This commit is contained in:
Auke Kok 2016-12-16 21:40:05 -08:00
parent 268f53e826
commit f6c6a9d4b9
3 changed files with 75 additions and 7 deletions

View File

@ -24,7 +24,7 @@ Stops any emote for the named player.
Lists known emotestring values.
`emote.attach_to_node(player, pos)`
`emote.attach_to_node(player, pos, locked)`
Attach the player to the node at pos. The attachment will be made using the
parameters provided in the `emote` table in the nodedef:
@ -37,6 +37,10 @@ nodedef.emote = {
}
```
if `locked` is `true`, then the player is fixed to the node and can only
move until he presses `jump`. While sitting the player can look around but
his character does not turn.
The player offset vector will be rotated to account for the node facedir.
## Commands

View File

@ -23,6 +23,7 @@ local emotes = {
}
local emoting = {}
local attached = {}
-- helper functions
local function facedir_to_look_horizontal(dir)
@ -48,6 +49,45 @@ local function vector_rotate_xz(vec, angle)
}
end
-- entity for locked emotes (attached to nodes, etc)
local attacher = {
description = "Attachment entity for emotes",
physical = false,
visual = "upright_sprite",
visual_size = {x = 1/16, y = 1/16},
spritediv = {x = 1/16, y = 1/16},
collisionbox = {-1/16, -1/16, -1/16, 1/16, 1/16, 1/16},
textures = {"emote_blank.png"},
init = function(self, player)
self.player = player
end,
}
function attacher:on_step(dtime)
if not self.player then
self.object:remove()
return
end
local ctrl = self.player:get_player_control()
if ctrl.jump then
self:detach()
return
end
end
function attacher:detach()
attached[self.player] = nil
self.player:set_detach()
self.player:set_animation(unpack(emotes["stand"]))
self.object:remove()
default.player_attached[self.player:get_player_name()] = nil
end
minetest.register_entity("emote:attacher", attacher)
-- API functions
function emote.start(player, emotestring)
emote.stop(player)
if emotes[emotestring] then
@ -79,12 +119,16 @@ function emote.list()
return r
end
function emote.attach_to_node(player, pos)
function emote.attach_to_node(player, pos, locked)
local node = minetest.get_node(pos)
if node.name == "ignore" then
return false
end
if attached[player] then
return
end
local def = minetest.registered_nodes[node.name].emote or {}
local emotedef = {
@ -94,11 +138,28 @@ function emote.attach_to_node(player, pos)
emotestring = def.emotestring or "sit",
}
player:setpos(vector.add(pos, vector_rotate_xz(emotedef.player_offset, facedir_to_look_horizontal(node.param2))))
player:set_eye_offset(emotedef.eye_offset, {x = 0, y = 0, z = 0})
player:set_look_horizontal(facedir_to_look_horizontal(node.param2) + emotedef.look_horizontal_offset)
player:set_animation(unpack(emotes[emotedef.emotestring]))
player:set_physics_override(0, 0, 0)
if locked then
player:set_animation(unpack(emotes[emotedef.emotestring]))
local offset = vector_rotate_xz(emotedef.player_offset,facedir_to_look_horizontal(node.param2))
local object = minetest.add_entity(vector.add(pos, offset), "emote:attacher")
object:get_luaentity():init(player)
local rotation = facedir_to_look_horizontal(node.param2) + emotedef.look_horizontal_offset
object:setyaw(rotation)
player:set_attach(object, "", emotedef.eye_offset, minetest.facedir_to_dir(node.param2))
player:set_look_horizontal(rotation)
-- this is highly unreliable!
minetest.after(0, function()
player:set_animation(unpack(emotes[emotedef.emotestring]))
end)
attached[player] = object
default.player_attached[player:get_player_name()] = true
else
player:setpos(vector.add(pos, vector_rotate_xz(emotedef.player_offset, facedir_to_look_horizontal(node.param2))))
player:set_eye_offset(emotedef.eye_offset, {x = 0, y = 0, z = 0})
player:set_look_horizontal(facedir_to_look_horizontal(node.param2) + emotedef.look_horizontal_offset)
player:set_animation(unpack(emotes[emotedef.emotestring]))
player:set_physics_override(0, 0, 0)
end
end
function emote.attach_to_entity(player, emotestring, obj)
@ -106,6 +167,9 @@ function emote.attach_to_entity(player, emotestring, obj)
end
function emote.detach(player)
if attached[player] then
attached[player]:detach()
end
-- check if attached?
player:set_eye_offset(vector.new(), vector.new())
player:set_physics_override(1, 1, 1)

BIN
textures/emote_blank.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 B