diff --git a/README.md b/README.md index 1a77929e..f247ca47 100644 --- a/README.md +++ b/README.md @@ -358,7 +358,7 @@ Some commands only work on the game server and not on the proxy server. The chat * `$si` (game server only): Shows basic information about the server. * `$ping`: Shows round-trip ping time from the server to you. On the proxy server, shows the ping time from you to the proxy and from the proxy to the server. * `$matcount` (game server only): Shows how many of each type of material you've used. - * `$rarenotifs` (game server only): Enables or disables rare drop notifications. When enabled, you'll see a message whenever a rare item drops. In private drop mode, you will only see a notification if the item is visible to you; you won't be notified of other players' rare drops. + * `$rarenotifs` (game server only): Enables or disables rare drop notifications. Only applies to server drop modes (see `$dropmode`); notifications are not supported in client drop mode. When enabled, you'll see a message whenever a rare item drops. In private drop mode, you will only see a notification if the item is visible to you; you won't be notified of other players' rare drops. * `$what` (game server only): Shows the type, name, and stats of the nearest item on the ground. * `$where` (game server only): Shows your current floor number and coordinates. Mainly useful for debugging. diff --git a/src/Main.cc b/src/Main.cc index 96acd5bc..b3bdc330 100644 --- a/src/Main.cc +++ b/src/Main.cc @@ -1477,9 +1477,15 @@ Action a_name_all_items( const auto& index = s.item_name_indexes.at(v_s); if (index) { Version version = static_cast(v_s); + auto pmt = s.item_parameter_table(version); ItemData item = ItemData::from_primary_identifier(version, primary_identifier); string name = index->describe_item(item); - fprintf(stderr, " %30s", name.c_str()); + try { + bool is_rare = pmt->is_item_rare(item); + fprintf(stderr, " %30s%s", name.c_str(), is_rare ? " (*)" : " "); + } catch (const out_of_range&) { + fprintf(stderr, " "); + } } } fputc('\n', stderr); diff --git a/src/ReceiveSubcommands.cc b/src/ReceiveSubcommands.cc index 2f7ef119..0ae4ed48 100644 --- a/src/ReceiveSubcommands.cc +++ b/src/ReceiveSubcommands.cc @@ -1574,9 +1574,10 @@ static void on_buy_shop_item(shared_ptr c, uint8_t command, uint8_t flag forward_subcommand_with_item_transcode_t(c, command, flag, cmd); } -static void send_rare_notification_if_needed(shared_ptr to_c, const ItemData& item) { +static void send_rare_notification_if_needed(shared_ptr to_c, const ItemData& item, bool is_from_rare_table) { auto s = to_c->require_server_state(); if (!to_c->config.check_flag(Client::Flag::RARE_DROP_NOTIFICATIONS_ENABLED) || + (!is_from_rare_table && (item.data1[0] != 0x03)) || !s->item_parameter_table(to_c->version())->is_item_rare(item)) { return; } @@ -1631,7 +1632,10 @@ static void on_box_or_enemy_item_drop_t(shared_ptr c, uint8_t command, u send_command_t(lc, command, flag, cmd); } } - send_rare_notification_if_needed(lc, item); + // TODO: Make rare drop notifications work in client drop mode. The problem + // is that we can't know if items are from the rare table or not when the + // client generates them, and some common items like Celestial Shield have + // 9 stars on v2 so they would be considered rare without that check. } } @@ -2227,9 +2231,7 @@ static void on_entity_drop_item_request(shared_ptr c, uint8_t command, u res.item.id.load(), cmd.floor, cmd.x.load(), cmd.z.load(), lc->channel.name.c_str()); l->add_item(cmd.floor, res.item, cmd.x, cmd.z, (1 << lc->lobby_client_id)); send_drop_item_to_channel(s, lc->channel, res.item, !is_box, cmd.floor, cmd.x, cmd.z, cmd.entity_id); - if (res.is_from_rare_table) { - send_rare_notification_if_needed(lc, res.item); - } + send_rare_notification_if_needed(lc, res.item, res.is_from_rare_table); } } @@ -2239,11 +2241,9 @@ static void on_entity_drop_item_request(shared_ptr c, uint8_t command, u res.item.id.load(), cmd.floor, cmd.x.load(), cmd.z.load()); l->add_item(cmd.floor, res.item, cmd.x, cmd.z, 0x00F); send_drop_item_to_lobby(l, res.item, !is_box, cmd.floor, cmd.x, cmd.z, cmd.entity_id); - if (res.is_from_rare_table) { - for (auto lc : l->clients) { - if (lc) { - send_rare_notification_if_needed(lc, res.item); - } + for (auto lc : l->clients) { + if (lc) { + send_rare_notification_if_needed(lc, res.item, res.is_from_rare_table); } } } @@ -2264,9 +2264,7 @@ static void on_entity_drop_item_request(shared_ptr c, uint8_t command, u res.item.id.load(), cmd.floor, cmd.x.load(), cmd.z.load(), lc->channel.name.c_str()); l->add_item(cmd.floor, res.item, cmd.x, cmd.z, (1 << lc->lobby_client_id)); send_drop_item_to_channel(s, lc->channel, res.item, !is_box, cmd.floor, cmd.x, cmd.z, cmd.entity_id); - if (res.is_from_rare_table) { - send_rare_notification_if_needed(lc, res.item); - } + send_rare_notification_if_needed(lc, res.item, res.is_from_rare_table); } } } diff --git a/system/item-tables/ItemPMT-v2.prs b/system/item-tables/ItemPMT-v2.prs old mode 100644 new mode 100755 index a61299cb..9de81097 Binary files a/system/item-tables/ItemPMT-v2.prs and b/system/item-tables/ItemPMT-v2.prs differ