Begin implementing :set_player_position packet in Play
Some checks failed
Build & Test / nix-build (push) Failing after 17s
Some checks failed
Build & Test / nix-build (push) Failing after 17s
This commit is contained in:
parent
c7d3b139fe
commit
ec7119251c
@ -20,7 +20,8 @@ defmodule Amethyst.API.Game do
|
|||||||
a game with Amethyst.
|
a game with Amethyst.
|
||||||
"""
|
"""
|
||||||
@callback instantiate() :: {:ok, new_state :: term} | {:error, reason :: term}
|
@callback instantiate() :: {:ok, new_state :: term} | {:error, reason :: term}
|
||||||
@callback login(connection_process :: pid(), player_cfg :: keyword(), state :: term) :: {:ok, new_state :: term} | {:refuse, new_state :: term}
|
@callback login(from :: pid(), player_cfg :: keyword(), state :: term) :: {:ok, new_state :: term} | {:refuse, new_state :: term}
|
||||||
|
@callback player_position(from :: pid(), {x :: float(), y :: float(), z :: float()}, state :: term) :: {{x :: float(), y :: float(), z :: float()}, state :: term}
|
||||||
|
|
||||||
defmacro __using__(opts) do
|
defmacro __using__(opts) do
|
||||||
meta = Keyword.get(opts, :meta, [])
|
meta = Keyword.get(opts, :meta, [])
|
||||||
@ -54,6 +55,12 @@ defmodule Amethyst.API.Game do
|
|||||||
send(caller, :refuse)
|
send(caller, :refuse)
|
||||||
loop(mod, state)
|
loop(mod, state)
|
||||||
end
|
end
|
||||||
|
{:player_position, caller, pos} ->
|
||||||
|
case mod.player_position(caller, pos, state) do
|
||||||
|
{pos, state} ->
|
||||||
|
send(caller, pos)
|
||||||
|
loop(mod, state)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -64,4 +71,12 @@ defmodule Amethyst.API.Game do
|
|||||||
:refuse -> :refuse
|
:refuse -> :refuse
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@spec player_position(atom() | pid() | port() | reference() | {atom(), atom()}, {float(), float(), float()}) :: {float(), float(), float()}
|
||||||
|
def player_position(pid, pos) do
|
||||||
|
send(pid, {:player_position, self(), pos})
|
||||||
|
receive do
|
||||||
|
pos -> pos
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
@ -35,6 +35,26 @@ defmodule Amethyst.Server.Play do
|
|||||||
{[channel], data} = Read.start(data) |> Read.string |> Read.stop
|
{[channel], data} = Read.start(data) |> Read.string |> Read.stop
|
||||||
{:serverbound_plugin_message, channel, data}
|
{:serverbound_plugin_message, channel, data}
|
||||||
end
|
end
|
||||||
|
@impl true
|
||||||
|
def deserialize(0x1A, data) do
|
||||||
|
{[x, feet_y, z, on_ground], ""} = Read.start(data) |> Read.double |> Read.double |> Read.double |> Read.bool |> Read.stop
|
||||||
|
{:set_player_position, x, feet_y, z, on_ground}
|
||||||
|
end
|
||||||
|
@impl true
|
||||||
|
def deserialize(0x1B, data) do
|
||||||
|
{[x, feet_y, z, yaw, pitch, on_ground], ""} = Read.start(data) |> Read.double |> Read.double |> Read.double |> Read.float |> Read.float |> Read.bool |> Read.stop
|
||||||
|
{:set_position_position_and_rotation, x, feet_y, z, yaw, pitch, on_ground}
|
||||||
|
end
|
||||||
|
@impl true
|
||||||
|
def deserialize(0x1C, data) do
|
||||||
|
{[yaw, pitch, on_ground], ""} = Read.start(data) |> Read.float |> Read.float |> Read.bool |> Read.stop()
|
||||||
|
{:set_player_rotation, yaw, pitch, on_ground}
|
||||||
|
end
|
||||||
|
@impl true
|
||||||
|
def deserialize(0x1D, data) do
|
||||||
|
{[on_ground], ""} = Read.start(data) |> Read.bool |> Read.stop()
|
||||||
|
{:set_player_on_ground, on_ground}
|
||||||
|
end
|
||||||
def deserialize(type, _) do
|
def deserialize(type, _) do
|
||||||
raise RuntimeError, "Got unknown packet type #{type}!"
|
raise RuntimeError, "Got unknown packet type #{type}!"
|
||||||
end
|
end
|
||||||
@ -80,8 +100,25 @@ defmodule Amethyst.Server.Play do
|
|||||||
Logger.debug("Got plugin message #{channel} with data #{inspect(data)}")
|
Logger.debug("Got plugin message #{channel} with data #{inspect(data)}")
|
||||||
{:ok, state}
|
{:ok, state}
|
||||||
end
|
end
|
||||||
def handle(tuple, _, state) do
|
def handle({:set_player_position, x, y, z, _on_ground}, _client, state) do
|
||||||
Logger.error("Unhandled but known packet #{elem(tuple, 0)}")
|
# We do not accept movement packets until we get a :confirm_teleportation
|
||||||
|
if Keyword.fetch(state, :awaiting_tp_confirm) != :error do
|
||||||
|
Logger.warning("Got :set_player_position packet while waiting for :confirm_teleportation!")
|
||||||
|
{:ok, state}
|
||||||
|
else
|
||||||
|
game = Keyword.fetch!(state, :game)
|
||||||
|
{nx, ny, nz} = Amethyst.API.Game.player_position(game, {x, y, z})
|
||||||
|
# If pos is not very close to the position the client wants, synchronize them
|
||||||
|
# TODO: Make a general-purpose distance function
|
||||||
|
dist = :math.sqrt((nx - x)**2 + (ny - y)**2 + (nz - z)**2)
|
||||||
|
if dist > 0.01 do
|
||||||
|
# TODO: Implement synchronization
|
||||||
|
raise "The game wants to resynchronize the player, but I haven't implemented that yet"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
def handle(tuple, _, state) do # TODO: These error cases should be somehow moved into some shared area? Maybe even moved out of the modules themselves
|
||||||
|
Logger.error("Unhandled but known packet #{inspect(tuple)}")
|
||||||
{:unhandled, state}
|
{:unhandled, state}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user