feat(B.5): pickup feedback chat line + toast ("You pick up the X.")

After B.5 shipped, the actual pickup was invisible feedback-wise: the
item left the ground, ACE despawned it via PickupEvent (0xF74A), and
the ItemRepository got updated — but the player had no visual
acknowledgement that anything happened. The M1 demo's "pick up an
item" target visually felt like the item just vanished into the void.

Add a new EntityPickedUp event to WorldSession that fires from the
PickupEvent (0xF74A) dispatch branch BEFORE EntityDeleted, so the
subscriber can still read the entity's display name from
_entitiesByServerGuid before the despawn handler clears it.

GameWindow subscribes during the live-session wiring block and emits
a retail-style system chat line plus a debug toast on every successful
pickup, mirroring retail behavior (retail synthesized this line
client-side; ACE doesn't echo it).

Closes the M1 demo "pick up" target's visible-payoff gap.
This commit is contained in:
Erik 2026-05-14 16:54:17 +02:00
parent cf22f9c031
commit 87ba5c9a98
2 changed files with 32 additions and 2 deletions

View file

@ -1921,6 +1921,17 @@ public sealed class GameWindow : IDisposable
_liveSession.PlayerKilledReceived += pk =>
Chat.OnPlayerKilled(pk.DeathMessage, pk.VictimGuid, pk.KillerGuid);
// B.5 polish (2026-05-14): surface successful pickups as a
// retail-style "You pick up the X." system chat line plus a
// toast. PickupEvent fires BEFORE the EntityDeleted despawn
// chain so the entity-name lookup still hits.
_liveSession.EntityPickedUp += parsed =>
{
string name = DescribeLiveEntity(parsed.Guid);
Chat.OnSystemMessage($"You pick up the {name}.", chatType: 0);
_debugVm?.AddToast($"Picked up: {name}");
};
_liveSession.TurbineChatReceived += parsed =>
{
if (parsed.Body is AcDream.Core.Net.Messages.TurbineChat.Payload.EventSendToRoom ev)