Implement part of chunk sending
This commit is contained in:
parent
c880ea95f3
commit
453daa817b
@ -60,6 +60,39 @@ defmodule Amethyst.ConnectionHandler do
|
||||
{:set_version, newversion} ->
|
||||
Logger.debug("Switching to version #{newversion} from #{version}")
|
||||
loop(socket, connstate, newversion, state)
|
||||
{:set_position, position} ->
|
||||
Logger.debug("Updating client position to #{inspect(position)}")
|
||||
prev_position = Map.get(state, :position)
|
||||
state = Map.put(state, :position, position)
|
||||
# If there was no prev position, we consider that we
|
||||
# definitely moved
|
||||
prev_cp = if prev_position == nil do nil else chunk_pos(elem(prev_position, 0), elem(prev_position, 1)) end
|
||||
cp = chunk_pos(elem(position, 0), elem(position, 1))
|
||||
if prev_cp != cp do
|
||||
Logger.debug("Client entered new chunk #{inspect(cp)}")
|
||||
# We changed chunk borders, update center chunk and begin sending new chunks
|
||||
send(self(), {:send_packet, %{
|
||||
packet_type: :set_center_chunk,
|
||||
chunk_x: elem(cp, 0),
|
||||
chunk_z: elem(cp, 1)
|
||||
}})
|
||||
# Figure out which new chunks are visible
|
||||
prev_chunks =
|
||||
if prev_cp == nil do
|
||||
MapSet.new([])
|
||||
else
|
||||
MapSet.new(visible_chunks_from(elem(prev_cp, 0), elem(prev_cp, 1), Map.get(state, :view_distance, 16)))
|
||||
end
|
||||
chunks = MapSet.new(visible_chunks_from(elem(cp, 0), elem(cp, 1), Map.get(state, :view_distance, 16)))
|
||||
new_chunks = MapSet.difference(chunks, prev_chunks)
|
||||
# Process these chunks, we can process all chunks in parallel
|
||||
Task.Supervisor.async_stream(state |> Map.get(:game) |> Map.get(:refs) |> Map.get(:task_supervisor),
|
||||
new_chunks,
|
||||
fn chunk -> process_chunk(chunk, state) end,
|
||||
[ordered: false]
|
||||
) |> Stream.run()
|
||||
end
|
||||
loop(socket, connstate, version, state)
|
||||
{:send_packet, packet} ->
|
||||
Logger.debug("Sending packet #{inspect(packet)}")
|
||||
send_packet(socket, connstate, packet, version)
|
||||
@ -73,6 +106,23 @@ defmodule Amethyst.ConnectionHandler do
|
||||
end
|
||||
end
|
||||
|
||||
defp chunk_pos(x, z) do
|
||||
{div(floor(x), 16), div(floor(z), 16)}
|
||||
end
|
||||
|
||||
defp visible_chunks_from(x, z, view_distance) do
|
||||
{cx, cz} = chunk_pos(x, z)
|
||||
(cx - view_distance - 3 .. cx + view_distance + 3) |> Enum.flat_map(fn ix ->
|
||||
(cz - view_distance - 3 .. cz + view_distance + 3) |> Enum.map(fn iz ->
|
||||
{ix, iz}
|
||||
end)
|
||||
end)
|
||||
end
|
||||
|
||||
defp process_chunk(_chunk, _state) do
|
||||
# TODO: Actually ask the game for the desired chunk then send the packets.
|
||||
end
|
||||
|
||||
defp handle_packet(id, data, connstate, version, state) do
|
||||
try do
|
||||
packet = connstate.deserialize(id, version, data)
|
||||
|
@ -305,9 +305,10 @@ defmodule Amethyst.ConnectionState.Configuration do
|
||||
}})
|
||||
send(self(), {:send_packet, Amethyst.ConnectionState.Play.ge_start_waiting_for_level_chunks(767)})
|
||||
send(self(), {:send_packet, %{packet_type: :set_center_chunk,
|
||||
chunk_x: div(x, 16),
|
||||
chunk_y: div(z, 16)
|
||||
chunk_x: div(floor(x), 16),
|
||||
chunk_z: div(floor(z), 16)
|
||||
}})
|
||||
send(self(), {:set_position, {x, y, z}})
|
||||
state
|
||||
end
|
||||
end
|
||||
|
Loading…
Reference in New Issue
Block a user