kimi gone wild

This commit is contained in:
ra
2026-02-14 23:12:33 -07:00
parent bbd205ecbe
commit 0222be36c5
98 changed files with 39726 additions and 309 deletions

View File

@@ -9,7 +9,7 @@ defmodule Odinsea.Channel.Handler.Player do
alias Odinsea.Net.Packet.{In, Out}
alias Odinsea.Net.Opcodes
alias Odinsea.Channel.Packets
alias Odinsea.Game.{Character, Movement, Map}
alias Odinsea.Game.{Character, Movement, Map, AttackInfo, DamageCalc}
@doc """
Handles player movement (CP_MOVE_PLAYER).
@@ -31,16 +31,22 @@ defmodule Odinsea.Channel.Handler.Player do
# Store original position
original_pos = character.position
# Parse movement
case Movement.parse_movement(packet) do
{:ok, movement_data, final_pos} ->
# Parse movement using the full movement system
case Movement.parse_player_movement(packet, original_pos) do
{:ok, movements, final_pos} ->
# Update character position
Character.update_position(character_pid, final_pos)
# Serialize movements for broadcast
movement_data = Movement.serialize_movements(movements)
# Broadcast movement to other players
move_packet =
Out.new(Opcodes.lp_move_player())
|> Out.encode_int(character.id)
|> Out.encode_short(original_pos.x)
|> Out.encode_short(original_pos.y)
|> Out.encode_int(0) # Unknown int
|> Out.encode_bytes(movement_data)
|> Out.to_data()
@@ -52,7 +58,7 @@ defmodule Odinsea.Channel.Handler.Player do
)
Logger.debug(
"Player #{character.name} moved to (#{final_pos.x}, #{final_pos.y})"
"Player #{character.name} moved from (#{original_pos.x}, #{original_pos.y}) to (#{final_pos.x}, #{final_pos.y}) with #{length(movements)} movements"
)
{:ok, client_state}
@@ -168,20 +174,39 @@ defmodule Odinsea.Channel.Handler.Player do
@doc """
Handles close-range attack (CP_CLOSE_RANGE_ATTACK).
Ported from PlayerHandler.closeRangeAttack() - STUB for now
Ported from PlayerHandler.closeRangeAttack() and DamageParse.parseDmgM()
"""
def handle_close_range_attack(packet, client_state) do
with {:ok, character_pid} <- get_character(client_state),
{:ok, character} <- Character.get_state(character_pid) do
Logger.debug("Close range attack from #{character.name} (stub)")
# TODO: Implement attack logic
# - Parse attack info
# - Validate attack
# - Calculate damage
# - Apply damage to mobs
# - Broadcast attack packet
{:ok, character} <- Character.get_state(character_pid),
{:ok, map_pid} <- get_map_pid(character.map_id, client_state.channel_id) do
# Parse attack packet
case AttackInfo.parse_melee_attack(packet) do
{:ok, attack_info} ->
Logger.debug(
"Close range attack from #{character.name}: skill=#{attack_info.skill}, targets=#{attack_info.targets}, hits=#{attack_info.hits}"
)
{:ok, client_state}
# Apply attack via DamageCalc
case DamageCalc.apply_attack(
attack_info,
character_pid,
map_pid,
client_state.channel_id
) do
{:ok, total_damage} ->
Logger.debug("Attack dealt #{total_damage} total damage")
{:ok, client_state}
{:error, reason} ->
Logger.warning("Attack failed: #{inspect(reason)}")
{:ok, client_state}
end
{:error, reason} ->
Logger.warning("Failed to parse melee attack: #{inspect(reason)}")
{:ok, client_state}
end
else
{:error, reason} ->
Logger.warning("Close range attack failed: #{inspect(reason)}")
@@ -191,15 +216,39 @@ defmodule Odinsea.Channel.Handler.Player do
@doc """
Handles ranged attack (CP_RANGED_ATTACK).
Ported from PlayerHandler.rangedAttack() - STUB for now
Ported from PlayerHandler.rangedAttack() and DamageParse.parseDmgR()
"""
def handle_ranged_attack(packet, client_state) do
with {:ok, character_pid} <- get_character(client_state),
{:ok, character} <- Character.get_state(character_pid) do
Logger.debug("Ranged attack from #{character.name} (stub)")
# TODO: Implement ranged attack logic
{:ok, character} <- Character.get_state(character_pid),
{:ok, map_pid} <- get_map_pid(character.map_id, client_state.channel_id) do
# Parse attack packet
case AttackInfo.parse_ranged_attack(packet) do
{:ok, attack_info} ->
Logger.debug(
"Ranged attack from #{character.name}: skill=#{attack_info.skill}, targets=#{attack_info.targets}, hits=#{attack_info.hits}"
)
{:ok, client_state}
# Apply attack via DamageCalc
case DamageCalc.apply_attack(
attack_info,
character_pid,
map_pid,
client_state.channel_id
) do
{:ok, total_damage} ->
Logger.debug("Attack dealt #{total_damage} total damage")
{:ok, client_state}
{:error, reason} ->
Logger.warning("Attack failed: #{inspect(reason)}")
{:ok, client_state}
end
{:error, reason} ->
Logger.warning("Failed to parse ranged attack: #{inspect(reason)}")
{:ok, client_state}
end
else
{:error, reason} ->
Logger.warning("Ranged attack failed: #{inspect(reason)}")
@@ -209,15 +258,39 @@ defmodule Odinsea.Channel.Handler.Player do
@doc """
Handles magic attack (CP_MAGIC_ATTACK).
Ported from PlayerHandler.MagicDamage() - STUB for now
Ported from PlayerHandler.MagicDamage() and DamageParse.parseDmgMa()
"""
def handle_magic_attack(packet, client_state) do
with {:ok, character_pid} <- get_character(client_state),
{:ok, character} <- Character.get_state(character_pid) do
Logger.debug("Magic attack from #{character.name} (stub)")
# TODO: Implement magic attack logic
{:ok, character} <- Character.get_state(character_pid),
{:ok, map_pid} <- get_map_pid(character.map_id, client_state.channel_id) do
# Parse attack packet
case AttackInfo.parse_magic_attack(packet) do
{:ok, attack_info} ->
Logger.debug(
"Magic attack from #{character.name}: skill=#{attack_info.skill}, targets=#{attack_info.targets}, hits=#{attack_info.hits}"
)
{:ok, client_state}
# Apply attack via DamageCalc
case DamageCalc.apply_attack(
attack_info,
character_pid,
map_pid,
client_state.channel_id
) do
{:ok, total_damage} ->
Logger.debug("Attack dealt #{total_damage} total damage")
{:ok, client_state}
{:error, reason} ->
Logger.warning("Attack failed: #{inspect(reason)}")
{:ok, client_state}
end
{:error, reason} ->
Logger.warning("Failed to parse magic attack: #{inspect(reason)}")
{:ok, client_state}
end
else
{:error, reason} ->
Logger.warning("Magic attack failed: #{inspect(reason)}")