From cac61e676300b2a5c6bab181e6782012c1468754 Mon Sep 17 00:00:00 2001 From: Martin Michelsen Date: Thu, 1 Jan 2026 10:55:45 -0800 Subject: [PATCH] add ability to delay $item until next drop on proxy --- src/ChatCommands.cc | 22 +++++++++++++++++----- src/ProxyCommands.cc | 16 +++++++++++++++- src/ProxySession.hh | 1 + 3 files changed, 33 insertions(+), 6 deletions(-) diff --git a/src/ChatCommands.cc b/src/ChatCommands.cc index 371874aa..a99c71c6 100644 --- a/src/ChatCommands.cc +++ b/src/ChatCommands.cc @@ -1224,17 +1224,25 @@ ChatCommandDefinition cc_item( a.check_cheats_enabled_or_allowed(s->cheat_flags.create_items); ItemData item; + bool was_enqueued = false; if (a.c->proxy_session) { if (a.c->version() == Version::BB_V4) { throw precondition_failed("$C6This command cannot\nbe used in proxy\nsessions in BB games"); } a.check_is_leader(); - item = s->parse_item_description(a.c->version(), a.text); - item.id = phosg::random_object() | 0x80000000; + if (a.text.starts_with("!")) { + item = s->parse_item_description(a.c->version(), a.text.substr(1)); + a.c->proxy_session->next_drop_item = item; + was_enqueued = true; - send_drop_stacked_item_to_channel(s, a.c->channel, item, a.c->floor, a.c->pos); - send_drop_stacked_item_to_channel(s, a.c->proxy_session->server_channel, item, a.c->floor, a.c->pos); + } else { + item = s->parse_item_description(a.c->version(), a.text); + item.id = phosg::random_object() | 0x80000000; + + send_drop_stacked_item_to_channel(s, a.c->channel, item, a.c->floor, a.c->pos); + send_drop_stacked_item_to_channel(s, a.c->proxy_session->server_channel, item, a.c->floor, a.c->pos); + } } else { auto l = a.c->require_lobby(); @@ -1251,7 +1259,11 @@ ChatCommandDefinition cc_item( } string name = s->describe_item(a.c->version(), item, ItemNameIndex::Flag::INCLUDE_PSO_COLOR_ESCAPES); - send_text_message(a.c, "$C7Item created:\n" + name); + if (was_enqueued) { + send_text_message(a.c, "$C7Next item:\n" + name); + } else { + send_text_message(a.c, "$C7Item created:\n" + name); + } co_return; }); diff --git a/src/ProxyCommands.cc b/src/ProxyCommands.cc index 3c8d4532..48fa3ad3 100644 --- a/src/ProxyCommands.cc +++ b/src/ProxyCommands.cc @@ -823,6 +823,21 @@ static asio::awaitable SC_6x60_6xA2(shared_ptr c, Channel co_return HandlerResult::FORWARD; } + G_SpecializableItemDropRequest_6xA2 cmd = normalize_drop_request(msg.data.data(), msg.data.size()); + + if (!c->proxy_session->next_drop_item.empty()) { + c->log.info_f("An override item is waiting; creating it"); + auto s = c->require_server_state(); + bool is_obj = (cmd.rt_index == 0x30); + c->proxy_session->next_drop_item.id = 0x06010000 | cmd.entity_index | (is_obj ? 0x4000 : 0x1000); + send_drop_item_to_channel( + s, c->channel, c->proxy_session->next_drop_item, is_obj ? 2 : 1, cmd.floor, cmd.pos, cmd.entity_index); + send_drop_item_to_channel( + s, c->proxy_session->server_channel, c->proxy_session->next_drop_item, is_obj ? 2 : 1, cmd.floor, cmd.pos, cmd.entity_index); + c->proxy_session->next_drop_item.clear(); + co_return HandlerResult::SUPPRESS; + } + switch (c->proxy_session->drop_mode) { case ProxyDropMode::DISABLED: co_return HandlerResult::SUPPRESS; @@ -843,7 +858,6 @@ static asio::awaitable SC_6x60_6xA2(shared_ptr c, Channel co_return HandlerResult::FORWARD; } - G_SpecializableItemDropRequest_6xA2 cmd = normalize_drop_request(msg.data.data(), msg.data.size()); auto rec = reconcile_drop_request_with_map( c, cmd, c->proxy_session->lobby_difficulty, c->proxy_session->lobby_event, c->proxy_session->map_state, false); diff --git a/src/ProxySession.hh b/src/ProxySession.hh index c88fe550..19f6d7ce 100644 --- a/src/ProxySession.hh +++ b/src/ProxySession.hh @@ -58,6 +58,7 @@ struct ProxySession { // Note: We intentionally don't use the client's item ID space because the client may create items at the same time // as the proxy, so server/client state could go out of sync uint32_t next_item_id = 0x44000000; + ItemData next_drop_item; struct PersistentConfig { uint32_t account_id;