fix Momoka item exchange via menu object
This commit is contained in:
@@ -812,8 +812,12 @@ struct SC_GameGuardCheck_BB_0022 {
|
||||
// used in the case described above; there are no other conditions that cause it to be sent.
|
||||
|
||||
// 23 (S->C): Momoka Item Exchange result (BB)
|
||||
// Sent in response to a 6xD9 command from the client. header.flag indicates if an item was exchanged: 0 means success,
|
||||
// 1 means failure. This command is not valid on BB Trial Edition.
|
||||
// Sent in response to a 6xD9 command from the client. This command is not valid on BB Trial Edition. header.flag
|
||||
// indicates the result code:
|
||||
// 0 = success
|
||||
// 1 = currency item not found
|
||||
// 2 = inventory is full
|
||||
// Anything else = generic failure
|
||||
|
||||
// 24 (S->C): Secret Lottery Ticket exchange result (BB)
|
||||
// Sent in response to a 6xDE command from the client. The client sets 8 sequential quest registers, starting with
|
||||
|
||||
+31
-18
@@ -5293,30 +5293,43 @@ static asio::awaitable<void> on_momoka_item_exchange_bb(shared_ptr<Client> c, Su
|
||||
const auto& cmd = msg.check_size_t<G_MomokaItemExchange_BB_6xD9>(0xFFFF);
|
||||
auto s = c->require_server_state();
|
||||
auto p = c->character_file();
|
||||
|
||||
const auto& limits = *s->item_stack_limits(c->version());
|
||||
|
||||
ItemData new_item = cmd.replace_item;
|
||||
assert_quest_item_create_allowed(l, new_item);
|
||||
new_item.enforce_stack_size_limits(limits);
|
||||
|
||||
bool failed = false;
|
||||
ItemData found_item;
|
||||
try {
|
||||
const auto& limits = *s->item_stack_limits(c->version());
|
||||
|
||||
ItemData new_item = cmd.replace_item;
|
||||
assert_quest_item_create_allowed(l, new_item);
|
||||
new_item.enforce_stack_size_limits(limits);
|
||||
|
||||
size_t found_index = p->inventory.find_item_by_primary_identifier(cmd.find_item.primary_identifier());
|
||||
auto found_item = p->remove_item(p->inventory.items[found_index].data.id, 1, limits);
|
||||
|
||||
G_ExchangeItemInQuest_BB_6xDB cmd_6xDB = {{0xDB, 0x04, c->lobby_client_id}, 1, found_item.id, 1};
|
||||
send_command_t(c, 0x60, 0x00, cmd_6xDB);
|
||||
|
||||
send_destroy_item_to_lobby(c, found_item.id, 1);
|
||||
found_item = p->remove_item(p->inventory.items[found_index].data.id, 1, limits);
|
||||
} catch (const std::out_of_range& e) {
|
||||
failed = true;
|
||||
}
|
||||
if (failed) {
|
||||
send_command(c, 0x23, 0x01);
|
||||
co_return;
|
||||
}
|
||||
|
||||
try {
|
||||
new_item.id = l->generate_item_id(c->lobby_client_id);
|
||||
p->add_item(new_item, limits);
|
||||
send_create_inventory_item_to_lobby(c, c->lobby_client_id, new_item);
|
||||
|
||||
send_command(c, 0x23, 0x00);
|
||||
} catch (const exception& e) {
|
||||
c->log.warning_f("Momoka item exchange failed: {}", e.what());
|
||||
send_command(c, 0x23, 0x01);
|
||||
} catch (const std::out_of_range& e) {
|
||||
failed = true;
|
||||
}
|
||||
if (failed) {
|
||||
p->add_item(found_item, limits); // Add found_item back since we're cancelling the exchange
|
||||
send_command(c, 0x23, 0x02);
|
||||
co_return;
|
||||
}
|
||||
|
||||
G_ExchangeItemInQuest_BB_6xDB cmd_6xDB = {{0xDB, 0x04, c->lobby_client_id}, 1, found_item.id, 1};
|
||||
send_command_t(c, 0x60, 0x00, cmd_6xDB);
|
||||
send_destroy_item_to_lobby(c, found_item.id, 1);
|
||||
send_create_inventory_item_to_lobby(c, c->lobby_client_id, new_item);
|
||||
send_command(c, 0x23, 0x00);
|
||||
co_return;
|
||||
}
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@ send_6xD9_start: # [std](void* this @ ecx) -> void
|
||||
call <VERS 0x00801150 0x008003E0> # send_and_handle_60[std](void* cmd @ ecx) -> void
|
||||
add esp, 0x38
|
||||
|
||||
mov dword [ebx], 6
|
||||
mov dword [ebx + 0x20], 6
|
||||
push 0
|
||||
call <VERS 0x0083746D 0x00859D2D> # time[std](void* t @ [esp + 4] = nullptr) -> uint32_t @ eax
|
||||
add esp, 4
|
||||
|
||||
Reference in New Issue
Block a user