port over some more

This commit is contained in:
ra
2026-02-14 23:58:01 -07:00
parent 0222be36c5
commit 61176cd416
107 changed files with 9124 additions and 375 deletions

View File

@@ -16,7 +16,7 @@ defmodule Odinsea.Game.Map do
require Logger
alias Odinsea.Game.Character
alias Odinsea.Game.{MapFactory, LifeFactory, Monster, Reactor, ReactorFactory}
alias Odinsea.Game.{Drop, MapFactory, LifeFactory, Monster, Reactor, ReactorFactory}
alias Odinsea.Channel.Packets, as: ChannelPackets
# ============================================================================
@@ -1073,11 +1073,19 @@ defmodule Odinsea.Game.Map do
@doc """
Attempts to pick up a drop.
Returns {:ok, drop} if successful, {:error, reason} if not.
"""
def pickup_drop(map_id, channel_id, drop_oid, character_id) do
GenServer.call(via_tuple(map_id, channel_id), {:pickup_drop, drop_oid, character_id})
end
@doc """
Checks if a drop is visible to a character (for quest items, individual rewards).
"""
def drop_visible_to?(map_id, channel_id, drop_oid, character_id, quest_status \\ %{}) do
GenServer.call(via_tuple(map_id, channel_id), {:drop_visible_to, drop_oid, character_id, quest_status})
end
@impl true
def handle_call(:get_drops, _from, state) do
{:reply, state.items, state}
@@ -1092,24 +1100,41 @@ defmodule Odinsea.Game.Map do
drop ->
now = System.system_time(:millisecond)
case DropSystem.pickup_drop(drop, character_id, now) do
{:ok, updated_drop} ->
# Broadcast pickup animation
remove_packet = ChannelPackets.remove_drop(drop_oid, 2, character_id)
broadcast_to_players(state.players, remove_packet)
# Remove from map
new_items = Map.delete(state.items, drop_oid)
# Return drop info for inventory addition
{:reply, {:ok, updated_drop}, %{state | items: new_items}}
{:error, reason} ->
{:reply, {:error, reason}, state}
# Validate ownership using Drop.can_loot?
if not Drop.can_loot?(drop, character_id, now) do
{:reply, {:error, :not_owner}, state}
else
case DropSystem.pickup_drop(drop, character_id, now) do
{:ok, updated_drop} ->
# Broadcast pickup animation to all players
remove_packet = ChannelPackets.remove_drop(drop_oid, 2, character_id)
broadcast_to_players(state.players, remove_packet)
# Remove from map
new_items = Map.delete(state.items, drop_oid)
# Return drop info for inventory addition
{:reply, {:ok, updated_drop}, %{state | items: new_items}}
{:error, reason} ->
{:reply, {:error, reason}, state}
end
end
end
end
@impl true
def handle_call({:drop_visible_to, drop_oid, character_id, quest_status}, _from, state) do
case Map.get(state.items, drop_oid) do
nil ->
{:reply, false, state}
drop ->
visible = Drop.visible_to?(drop, character_id, quest_status)
{:reply, visible, state}
end
end
@impl true
def handle_info(:check_drop_expiration, state) do
now = System.system_time(:millisecond)