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

@@ -0,0 +1,158 @@
defmodule Odinsea.Channel.Handler.UI do
@moduledoc """
Handles user interface interaction packets.
Ported from: src/handling/channel/handler/UserInterfaceHandler.java
## Main Handlers
- handle_cygnus_summon/2 - Cygnus/Aran first job advancement
- handle_game_poll/2 - In-game poll
- handle_ship_object/2 - Ship/boat object requests
"""
require Logger
alias Odinsea.Net.Packet.In
alias Odinsea.Game.{Character, Map}
alias Odinsea.Channel.Packets
# ============================================================================
# Job Advancement
# ============================================================================
@doc """
Handles Cygnus/Aran summon NPC request (CP_CYGNUS_SUMMON / 0xC5).
Opens the first job advancement NPC for Cygnus and Aran characters.
- Job 2000 (Aran) → NPC 1202000
- Job 1000 (Cygnus Knight) → NPC 1101008
Reference: UserInterfaceHandler.CygnusSummon_NPCRequest()
"""
def handle_cygnus_summon(_packet, client_pid) do
case Character.get_state_by_client(client_pid) do
{:ok, character_id, char_state} ->
npc_id = case char_state.job do
2000 -> 1202000 # Aran
1000 -> 1101008 # Cygnus Knight
_ -> nil
end
if npc_id do
# TODO: Start NPC script
# NPCScriptManager.getInstance().start(c, npc_id)
Logger.debug("Cygnus/Aran summon NPC: #{npc_id} for character #{character_id}")
else
Logger.debug("Invalid job for Cygnus summon: #{char_state.job}, character #{character_id}")
end
:ok
{:error, reason} ->
Logger.warn("Failed to handle Cygnus summon: #{inspect(reason)}")
end
end
# ============================================================================
# Game Poll
# ============================================================================
@doc """
Handles in-game poll (CP_GAME_POLL / 0xD4).
Player submits response to server poll/questionnaire.
Reference: UserInterfaceHandler.InGame_Poll()
"""
def handle_game_poll(packet, client_pid) do
# tick = In.decode_int(packet)
selection = In.decode_int(packet)
case Character.get_state_by_client(client_pid) do
{:ok, character_id, char_state} ->
# TODO: Validate poll is enabled
# TODO: Validate selection is valid
# TODO: Record poll response
# TODO: Send reply packet
Logger.debug("Game poll response: #{selection}, character #{character_id}")
:ok
{:error, reason} ->
Logger.warn("Failed to handle game poll: #{inspect(reason)}")
end
end
# ============================================================================
# Ship/Boat Objects
# ============================================================================
@doc """
Handles ship object request (CP_SHIP_OBJECT / 0x127).
Client requests ship/boat status for station maps.
Used for boats between continents (Ellinia-Orbis, etc.)
Packet format varies by map:
- BB 00 6C 24 05 06 00 - Ellinia
- BB 00 6E 1C 4E 0E 00 - Leafre
Reference: UserInterfaceHandler.ShipObjectRequest()
"""
def handle_ship_object(packet, client_pid) do
# Map ID is encoded in the packet in various ways
# The full packet structure varies by client version
case Character.get_state_by_client(client_pid) do
{:ok, character_id, char_state} ->
map_id = char_state.map
# Determine ship effect based on map
effect = get_ship_effect(map_id)
# TODO: Check event manager for actual docked status
# Boats/Trains/Geenie/Flight managers
Logger.debug("Ship object request: map #{map_id}, effect #{effect}, character #{character_id}")
# TODO: Send boat packet with effect
# c.sendPacket(MaplePacketCreator.boatPacket(effect))
:ok
{:error, reason} ->
Logger.warn("Failed to handle ship object: #{inspect(reason)}")
end
end
# ============================================================================
# Helper Functions
# ============================================================================
# Returns the ship effect value for a given map
# Effect: 1 = Coming, 3 = Going, 1034 = Balrog
defp get_ship_effect(map_id) do
case map_id do
# Ellinia Station >> Orbis
101000300 -> 3
# Orbis Station >> Ellinia
200000111 -> 3
# Orbis Station >> Ludi
200000121 -> 3
# Ludi Station >> Orbis
220000110 -> 3
# Orbis Station >> Ariant
200000151 -> 3
# Ariant Station >> Orbis
260000100 -> 3
# Leafre Station >> Orbis
240000110 -> 3
# Orbis Station >> Leafre
200000131 -> 3
# During boat rides
200090010 -> 1 # To Orbis
200090000 -> 1 # To Ellinia
_ -> 3 # Default: going
end
end
end