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:
parent
268f53e826
commit
f6c6a9d4b9
@ -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
|
||||
|
66
init.lua
66
init.lua
@ -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",
|
||||
}
|
||||
|
||||
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
BIN
textures/emote_blank.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 68 B |
Loading…
x
Reference in New Issue
Block a user