Start repo, claude & kimi still vibing tho
This commit is contained in:
146
lib/odinsea/game/movement.ex
Normal file
146
lib/odinsea/game/movement.ex
Normal file
@@ -0,0 +1,146 @@
|
||||
defmodule Odinsea.Game.Movement do
|
||||
@moduledoc """
|
||||
Movement parsing and validation for players, mobs, pets, summons, and dragons.
|
||||
Ported from Java MovementParse.java.
|
||||
|
||||
Movement types (kind):
|
||||
- 1: Player
|
||||
- 2: Mob
|
||||
- 3: Pet
|
||||
- 4: Summon
|
||||
- 5: Dragon
|
||||
|
||||
This is a SIMPLIFIED implementation for now. The full Java version has complex
|
||||
parsing for different movement command types. We'll expand this as needed.
|
||||
"""
|
||||
|
||||
require Logger
|
||||
alias Odinsea.Net.Packet.In
|
||||
alias Odinsea.Game.Character.Position
|
||||
|
||||
@doc """
|
||||
Parses movement data from a packet.
|
||||
Returns {:ok, movements} or {:error, reason}.
|
||||
|
||||
For now, this returns a simplified structure. The full implementation
|
||||
would parse all movement fragment types.
|
||||
"""
|
||||
def parse_movement(packet, _kind) do
|
||||
num_commands = In.decode_byte(packet)
|
||||
|
||||
# For now, just skip through the movement data and extract final position
|
||||
# TODO: Implement full movement parsing with all command types
|
||||
case extract_final_position(packet, num_commands) do
|
||||
{:ok, position} ->
|
||||
{:ok, %{num_commands: num_commands, final_position: position}}
|
||||
|
||||
:error ->
|
||||
{:error, :invalid_movement}
|
||||
end
|
||||
end
|
||||
|
||||
@doc """
|
||||
Updates an entity's position from movement data.
|
||||
"""
|
||||
def update_position(_movements, character_id) do
|
||||
# TODO: Implement position update logic
|
||||
# For now, just return ok
|
||||
Logger.debug("Update position for character #{character_id}")
|
||||
:ok
|
||||
end
|
||||
|
||||
# ============================================================================
|
||||
# Private Functions
|
||||
# ============================================================================
|
||||
|
||||
# Extract the final position from movement data
|
||||
# This is a TEMPORARY simplification - we just read through the movement
|
||||
# commands and try to extract the last absolute position
|
||||
defp extract_final_position(packet, num_commands) do
|
||||
try do
|
||||
final_pos = parse_commands(packet, num_commands, nil)
|
||||
{:ok, final_pos || %{x: 0, y: 0, stance: 0, foothold: 0}}
|
||||
rescue
|
||||
_ ->
|
||||
:error
|
||||
end
|
||||
end
|
||||
|
||||
defp parse_commands(_packet, 0, last_position) do
|
||||
last_position
|
||||
end
|
||||
|
||||
defp parse_commands(packet, remaining, last_position) do
|
||||
command = In.decode_byte(packet)
|
||||
|
||||
new_position =
|
||||
case command do
|
||||
# Absolute movement commands - extract position
|
||||
cmd when cmd in [0, 37, 38, 39, 40, 41, 42] ->
|
||||
x = In.decode_short(packet)
|
||||
y = In.decode_short(packet)
|
||||
_xwobble = In.decode_short(packet)
|
||||
_ywobble = In.decode_short(packet)
|
||||
_unk = In.decode_short(packet)
|
||||
_xoffset = In.decode_short(packet)
|
||||
_yoffset = In.decode_short(packet)
|
||||
stance = In.decode_byte(packet)
|
||||
_duration = In.decode_short(packet)
|
||||
%{x: x, y: y, stance: stance, foothold: 0}
|
||||
|
||||
# Relative movement - skip for now
|
||||
cmd when cmd in [1, 2, 33, 34, 36] ->
|
||||
_xmod = In.decode_short(packet)
|
||||
_ymod = In.decode_short(packet)
|
||||
_stance = In.decode_byte(packet)
|
||||
_duration = In.decode_short(packet)
|
||||
last_position
|
||||
|
||||
# Teleport movement
|
||||
cmd when cmd in [3, 4, 8, 100, 101] ->
|
||||
x = In.decode_short(packet)
|
||||
y = In.decode_short(packet)
|
||||
_xwobble = In.decode_short(packet)
|
||||
_ywobble = In.decode_short(packet)
|
||||
stance = In.decode_byte(packet)
|
||||
%{x: x, y: y, stance: stance, foothold: 0}
|
||||
|
||||
# Chair movement
|
||||
cmd when cmd in [9, 12] ->
|
||||
x = In.decode_short(packet)
|
||||
y = In.decode_short(packet)
|
||||
_unk = In.decode_short(packet)
|
||||
stance = In.decode_byte(packet)
|
||||
_duration = In.decode_short(packet)
|
||||
%{x: x, y: y, stance: stance, foothold: 0}
|
||||
|
||||
# Aran combat step
|
||||
cmd when cmd in [21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 35] ->
|
||||
_stance = In.decode_byte(packet)
|
||||
_unk = In.decode_short(packet)
|
||||
last_position
|
||||
|
||||
# Jump down
|
||||
cmd when cmd in [13, 14] ->
|
||||
# Simplified - just skip the data
|
||||
x = In.decode_short(packet)
|
||||
y = In.decode_short(packet)
|
||||
_xwobble = In.decode_short(packet)
|
||||
_ywobble = In.decode_short(packet)
|
||||
_unk = In.decode_short(packet)
|
||||
_fh = In.decode_short(packet)
|
||||
_xoffset = In.decode_short(packet)
|
||||
_yoffset = In.decode_short(packet)
|
||||
stance = In.decode_byte(packet)
|
||||
_duration = In.decode_short(packet)
|
||||
%{x: x, y: y, stance: stance, foothold: 0}
|
||||
|
||||
# Unknown/unhandled - log and skip
|
||||
_ ->
|
||||
Logger.warning("Unhandled movement command: #{command}")
|
||||
last_position
|
||||
end
|
||||
|
||||
parse_commands(packet, remaining - 1, new_position || last_position)
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user