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.
|
||||
"""
|
||||
@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
|
||||
meta = Keyword.get(opts, :meta, [])
|
||||
@ -54,6 +55,12 @@ defmodule Amethyst.API.Game do
|
||||
send(caller, :refuse)
|
||||
loop(mod, state)
|
||||
end
|
||||
{:player_position, caller, pos} ->
|
||||
case mod.player_position(caller, pos, state) do
|
||||
{pos, state} ->
|
||||
send(caller, pos)
|
||||
loop(mod, state)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -64,4 +71,12 @@ defmodule Amethyst.API.Game do
|
||||
:refuse -> :refuse
|
||||
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
|
||||
|
@ -35,6 +35,26 @@ defmodule Amethyst.Server.Play do
|
||||
{[channel], data} = Read.start(data) |> Read.string |> Read.stop
|
||||
{:serverbound_plugin_message, channel, data}
|
||||
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
|
||||
raise RuntimeError, "Got unknown packet type #{type}!"
|
||||
end
|
||||
@ -80,8 +100,25 @@ defmodule Amethyst.Server.Play do
|
||||
Logger.debug("Got plugin message #{channel} with data #{inspect(data)}")
|
||||
{:ok, state}
|
||||
end
|
||||
def handle(tuple, _, state) do
|
||||
Logger.error("Unhandled but known packet #{elem(tuple, 0)}")
|
||||
def handle({:set_player_position, x, y, z, _on_ground}, _client, state) do
|
||||
# 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}
|
||||
end
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user