make $killcount work for units too
This commit is contained in:
+30
-20
@@ -1302,7 +1302,7 @@ ChatCommandDefinition cc_item(
|
||||
}
|
||||
}
|
||||
|
||||
string name = s->describe_item(a.c->version(), item, true);
|
||||
string name = s->describe_item(a.c->version(), item, ItemNameIndex::Flag::INCLUDE_PSO_COLOR_ESCAPES);
|
||||
send_text_message(a.c, "$C7Item created:\n" + name);
|
||||
co_return;
|
||||
});
|
||||
@@ -1364,28 +1364,38 @@ ChatCommandDefinition cc_killcount(
|
||||
a.check_is_proxy(false);
|
||||
|
||||
auto p = a.c->character();
|
||||
size_t item_index;
|
||||
try {
|
||||
item_index = p->inventory.find_equipped_item(EquipSlot::WEAPON);
|
||||
} catch (const out_of_range&) {
|
||||
throw precondition_failed("No weapon equipped");
|
||||
vector<size_t> item_indexes;
|
||||
for (size_t z = 0; z < p->inventory.num_items; z++) {
|
||||
const auto& item = p->inventory.items[z];
|
||||
if (item.is_equipped() && item.data.has_kill_count()) {
|
||||
item_indexes.emplace_back(z);
|
||||
}
|
||||
}
|
||||
|
||||
const auto& item = p->inventory.items.at(item_index);
|
||||
if (!item.data.has_kill_count()) {
|
||||
throw precondition_failed("Weapon does not\nhave a kill count");
|
||||
}
|
||||
if (item_indexes.empty()) {
|
||||
throw precondition_failed("No equipped items\nhave kill counts");
|
||||
|
||||
// Kill counts are only accurate on the server side at all times on BB. On
|
||||
// other versions, we update the server's view of the client's inventory
|
||||
// during games, but we can't track kills because the client doesn't inform
|
||||
// the server whether it counted a kill for any individual enemy. So, on
|
||||
// non-BB versions, the kill count is accurate at all times in the lobby
|
||||
// (since kills can't occur there), or at the beginning of a game.
|
||||
if ((a.c->version() == Version::BB_V4) || !a.c->require_lobby()->is_game()) {
|
||||
send_text_message_fmt(a.c, "{} kills", item.data.get_kill_count());
|
||||
} else {
|
||||
send_text_message_fmt(a.c, "{} kills as of\ngame join", item.data.get_kill_count());
|
||||
// Kill counts are only accurate on the server side at all times on BB.
|
||||
// On other versions, we update the server's view of the client's
|
||||
// inventory during games, but we can't track kills because the client
|
||||
// doesn't inform the server whether it counted a kill for any
|
||||
// individual enemy. So, on non-BB versions, the kill count is accurate
|
||||
// at all times in the lobby (since kills can't occur there), or at the
|
||||
// beginning of a game.
|
||||
if ((a.c->version() == Version::BB_V4) || !a.c->require_lobby()->is_game()) {
|
||||
send_text_message(a.c, "As of now:");
|
||||
} else {
|
||||
send_text_message(a.c, "As of game join:");
|
||||
}
|
||||
|
||||
auto s = a.c->require_server_state();
|
||||
for (size_t z : item_indexes) {
|
||||
const auto& item = p->inventory.items[z];
|
||||
string name = s->describe_item(
|
||||
a.c->version(), item.data, ItemNameIndex::Flag::INCLUDE_PSO_COLOR_ESCAPES | ItemNameIndex::Flag::NAME_ONLY);
|
||||
send_text_message_fmt(a.c, "{}$C7: {} kills", name, item.data.get_kill_count());
|
||||
}
|
||||
}
|
||||
co_return;
|
||||
});
|
||||
@@ -2768,7 +2778,7 @@ ChatCommandDefinition cc_what(
|
||||
throw precondition_failed("$C4No items are near you");
|
||||
} else {
|
||||
auto s = a.c->require_server_state();
|
||||
string name = s->describe_item(a.c->version(), nearest_fi->data, true);
|
||||
string name = s->describe_item(a.c->version(), nearest_fi->data, ItemNameIndex::Flag::INCLUDE_PSO_COLOR_ESCAPES);
|
||||
send_text_message(a.c, name);
|
||||
}
|
||||
co_return;
|
||||
|
||||
+2
-2
@@ -1058,7 +1058,7 @@ void Client::print_inventory() const {
|
||||
for (size_t x = 0; x < p->inventory.num_items; x++) {
|
||||
const auto& item = p->inventory.items[x];
|
||||
auto hex = item.data.hex();
|
||||
auto name = s->describe_item(this->version(), item.data, false);
|
||||
auto name = s->describe_item(this->version(), item.data);
|
||||
this->log.info_f("[PlayerInventory] {:2}: [+{:08X}] {} ({})", x, item.flags, hex, name);
|
||||
}
|
||||
}
|
||||
@@ -1072,7 +1072,7 @@ void Client::print_bank() const {
|
||||
const auto& item = bank.items[x];
|
||||
const char* present_token = item.present ? "" : " (missing present flag)";
|
||||
auto hex = item.data.hex();
|
||||
auto name = s->describe_item(this->version(), item.data, false);
|
||||
auto name = s->describe_item(this->version(), item.data);
|
||||
this->log.info_f("[PlayerBank] {:3}: {} ({}) (x{}){}", x, hex, name, item.amount, present_token);
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -193,7 +193,7 @@ std::shared_ptr<phosg::JSON> HTTPServer::generate_client_json(
|
||||
{"ItemID", item.data.id.load()},
|
||||
});
|
||||
if (item_name_index) {
|
||||
item_dict.emplace("Description", item_name_index->describe_item(item.data, false));
|
||||
item_dict.emplace("Description", item_name_index->describe_item(item.data));
|
||||
}
|
||||
items_json.emplace_back(std::move(item_dict));
|
||||
}
|
||||
@@ -431,7 +431,7 @@ std::shared_ptr<phosg::JSON> HTTPServer::generate_lobby_json(
|
||||
{"ItemID", item->data.id.load()},
|
||||
});
|
||||
if (item_name_index) {
|
||||
item_dict.emplace("Description", item_name_index->describe_item(item->data, false));
|
||||
item_dict.emplace("Description", item_name_index->describe_item(item->data));
|
||||
}
|
||||
floor_items_json.emplace_back(std::move(item_dict));
|
||||
}
|
||||
|
||||
+20
-15
@@ -97,7 +97,10 @@ const array<const char*, 0x11> name_for_s_rank_special = {
|
||||
"King\'s",
|
||||
};
|
||||
|
||||
std::string ItemNameIndex::describe_item(const ItemData& item, bool include_color_escapes, bool hide_mag_stats) const {
|
||||
std::string ItemNameIndex::describe_item(const ItemData& item, uint8_t flags) const {
|
||||
bool include_color_escapes = flags & ItemNameIndex::Flag::INCLUDE_PSO_COLOR_ESCAPES;
|
||||
bool name_only = flags & ItemNameIndex::Flag::NAME_ONLY;
|
||||
|
||||
if (item.data1[0] == 0x04) {
|
||||
return std::format("{}{} Meseta", include_color_escapes ? "$C7" : "", item.data2d);
|
||||
}
|
||||
@@ -108,13 +111,14 @@ std::string ItemNameIndex::describe_item(const ItemData& item, bool include_colo
|
||||
bool is_unidentified = false;
|
||||
if ((item.data1[0] == 0x00) && (item.data1[4] != 0x00) && !item.is_s_rank_weapon()) {
|
||||
is_unidentified = item.data1[4] & 0x80;
|
||||
bool is_present = item.data1[4] & 0x40;
|
||||
uint8_t special_id = item.data1[4] & 0x3F;
|
||||
if (is_present) {
|
||||
ret_tokens.emplace_back("Wrapped");
|
||||
}
|
||||
if (is_unidentified) {
|
||||
ret_tokens.emplace_back("????");
|
||||
if (!name_only) {
|
||||
if (item.data1[4] & 0x40) {
|
||||
ret_tokens.emplace_back("Wrapped");
|
||||
}
|
||||
if (is_unidentified) {
|
||||
ret_tokens.emplace_back("????");
|
||||
}
|
||||
}
|
||||
if (special_id) {
|
||||
try {
|
||||
@@ -124,7 +128,7 @@ std::string ItemNameIndex::describe_item(const ItemData& item, bool include_colo
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((item.data1[0] == 0x00) && (item.data1[2] != 0x00) && item.is_s_rank_weapon()) {
|
||||
if (!name_only && (item.data1[0] == 0x00) && (item.data1[2] != 0x00) && item.is_s_rank_weapon()) {
|
||||
try {
|
||||
ret_tokens.emplace_back(name_for_s_rank_special.at(item.data1[2]));
|
||||
} catch (const out_of_range&) {
|
||||
@@ -135,9 +139,10 @@ std::string ItemNameIndex::describe_item(const ItemData& item, bool include_colo
|
||||
// Armors, shields, and units (0x01) can be wrapped, as can mags (0x02) and
|
||||
// non-stackable tools (0x03). However, each of these item classes has its
|
||||
// flags in a different location.
|
||||
if (((item.data1[0] == 0x01) && (item.data1[4] & 0x40)) ||
|
||||
((item.data1[0] == 0x02) && (item.data2[2] & 0x40)) ||
|
||||
((item.data1[0] == 0x03) && !item.is_stackable(*this->limits) && (item.data1[3] & 0x40))) {
|
||||
if (!name_only &&
|
||||
(((item.data1[0] == 0x01) && (item.data1[4] & 0x40)) ||
|
||||
((item.data1[0] == 0x02) && (item.data2[2] & 0x40)) ||
|
||||
((item.data1[0] == 0x03) && !item.is_stackable(*this->limits) && (item.data1[3] & 0x40)))) {
|
||||
ret_tokens.emplace_back("Wrapped");
|
||||
}
|
||||
|
||||
@@ -168,7 +173,7 @@ std::string ItemNameIndex::describe_item(const ItemData& item, bool include_colo
|
||||
|
||||
if (item.data1[0] == 0x00) {
|
||||
// For weapons, add the grind and bonuses, or S-rank name if applicable
|
||||
if (item.data1[3] > 0) {
|
||||
if (!name_only && item.data1[3] > 0) {
|
||||
ret_tokens.emplace_back(std::format("+{}", item.data1[3]));
|
||||
}
|
||||
|
||||
@@ -210,7 +215,7 @@ std::string ItemNameIndex::describe_item(const ItemData& item, bool include_colo
|
||||
}
|
||||
}
|
||||
|
||||
} else { // Not S-rank (extended name bits not set)
|
||||
} else if (!name_only) { // Not S-rank (extended name bits not set)
|
||||
parray<int8_t, 5> bonuses(0);
|
||||
for (size_t x = 0; x < 3; x++) {
|
||||
uint8_t which = item.data1[6 + 2 * x];
|
||||
@@ -258,7 +263,7 @@ std::string ItemNameIndex::describe_item(const ItemData& item, bool include_colo
|
||||
ret_tokens.emplace_back(std::format("!MD:{:04X}", modifier));
|
||||
}
|
||||
|
||||
} else { // Armor/shields
|
||||
} else if (!name_only) { // Armor/shields
|
||||
if (item.data1[5] > 0) {
|
||||
if (item.data1[5] == 1) {
|
||||
ret_tokens.emplace_back("(1 slot)");
|
||||
@@ -276,7 +281,7 @@ std::string ItemNameIndex::describe_item(const ItemData& item, bool include_colo
|
||||
}
|
||||
}
|
||||
|
||||
} else if (!hide_mag_stats && (item.data1[0] == 0x02)) {
|
||||
} else if (!name_only && (item.data1[0] == 0x02)) {
|
||||
// For mags, add tons of info
|
||||
ret_tokens.emplace_back(std::format("LV{}", item.data1[2]));
|
||||
|
||||
|
||||
@@ -38,7 +38,12 @@ public:
|
||||
inline bool exists(const ItemData& item) const {
|
||||
return this->primary_identifier_index.count(item.primary_identifier());
|
||||
}
|
||||
std::string describe_item(const ItemData& item, bool include_color_escapes = false, bool hide_mag_stats = false) const;
|
||||
|
||||
enum Flag : uint8_t {
|
||||
INCLUDE_PSO_COLOR_ESCAPES = 0x01,
|
||||
NAME_ONLY = 0x02,
|
||||
};
|
||||
std::string describe_item(const ItemData& item, uint8_t flags = 0) const;
|
||||
ItemData parse_item_description(const std::string& description) const;
|
||||
|
||||
void print_table(FILE* stream) const;
|
||||
|
||||
+1
-1
@@ -2158,7 +2158,7 @@ Action a_describe_item(
|
||||
}
|
||||
|
||||
string desc = name_index->describe_item(item);
|
||||
string desc_colored = name_index->describe_item(item, true);
|
||||
string desc_colored = name_index->describe_item(item, ItemNameIndex::Flag::INCLUDE_PSO_COLOR_ESCAPES);
|
||||
|
||||
phosg::log_info_f("Data (decoded): {:02X}{:02X}{:02X}{:02X} {:02X}{:02X}{:02X}{:02X} {:02X}{:02X}{:02X}{:02X} -------- {:02X}{:02X}{:02X}{:02X}",
|
||||
item.data1[0], item.data1[1], item.data1[2], item.data1[3],
|
||||
|
||||
@@ -77,6 +77,10 @@ struct PlayerInventoryItemT {
|
||||
ret.data.id.store_raw(phosg::bswap32(ret.data.id.load_raw()));
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool is_equipped() const {
|
||||
return (this->flags & 8);
|
||||
}
|
||||
} __attribute__((packed));
|
||||
using PlayerInventoryItem = PlayerInventoryItemT<false>;
|
||||
using PlayerInventoryItemBE = PlayerInventoryItemT<true>;
|
||||
|
||||
@@ -884,7 +884,7 @@ static asio::awaitable<HandlerResult> SC_6x60_6xA2(shared_ptr<Client> c, Channel
|
||||
c->log.info_f("No item was created");
|
||||
} else {
|
||||
auto s = c->require_server_state();
|
||||
string name = s->describe_item(c->version(), res.item, false);
|
||||
string name = s->describe_item(c->version(), res.item);
|
||||
c->log.info_f("Entity {:04X} (area {:02X}) created item {}", cmd.entity_index, cmd.effective_area, name);
|
||||
res.item.id = c->proxy_session->next_item_id++;
|
||||
c->log.info_f("Creating item {:08X} at {:02X}:{:g},{:g} for all clients",
|
||||
|
||||
+1
-1
@@ -722,7 +722,7 @@ string RareItemSet::serialize_html(
|
||||
}
|
||||
|
||||
string hex = example_item.short_hex();
|
||||
string desc = name_index->describe_item(example_item, false, true);
|
||||
string desc = name_index->describe_item(example_item, ItemNameIndex::Flag::NAME_ONLY);
|
||||
tokens.emplace_back(std::format("<span class=\"item\" title=\"Hex: {}\">{}</span>", hex, desc));
|
||||
|
||||
float denom = static_cast<float>(frac.second) / static_cast<double>(frac.first);
|
||||
|
||||
@@ -4088,7 +4088,7 @@ static asio::awaitable<void> on_DF_BB(shared_ptr<Client> c, Channel::Message& ms
|
||||
award_state.rank_award_flags |= cmd.rank_bitmask;
|
||||
p->add_item(cmd.item, *s->item_stack_limits(c->version()));
|
||||
l->on_item_id_generated_externally(cmd.item.id);
|
||||
string desc = s->describe_item(Version::BB_V4, cmd.item, false);
|
||||
string desc = s->describe_item(Version::BB_V4, cmd.item);
|
||||
l->log.info_f("(Challenge mode) Item awarded to player {}: {}", c->lobby_client_id, desc);
|
||||
break;
|
||||
}
|
||||
|
||||
+28
-28
@@ -1947,7 +1947,7 @@ static asio::awaitable<void> on_player_drop_item(shared_ptr<Client> c, Subcomman
|
||||
|
||||
if (l->log.should_log(phosg::LogLevel::L_INFO)) {
|
||||
auto s = c->require_server_state();
|
||||
auto name = s->describe_item(c->version(), item, false);
|
||||
auto name = s->describe_item(c->version(), item);
|
||||
l->log.info_f("Player {} dropped item {:08X} ({}) at {}:({:g}, {:g})",
|
||||
cmd.header.client_id, cmd.item_id, name, cmd.floor, cmd.pos.x, cmd.pos.z);
|
||||
c->print_inventory();
|
||||
@@ -1985,7 +1985,7 @@ static asio::awaitable<void> on_create_inventory_item_t(shared_ptr<Client> c, Su
|
||||
}
|
||||
|
||||
if (l->log.should_log(phosg::LogLevel::L_INFO)) {
|
||||
auto name = s->describe_item(c->version(), item, false);
|
||||
auto name = s->describe_item(c->version(), item);
|
||||
l->log.info_f("Player {} created inventory item {:08X} ({}) in inventory of NPC {:02X}; ignoring", c->lobby_client_id, item.id, name, cmd.header.client_id);
|
||||
}
|
||||
|
||||
@@ -1993,7 +1993,7 @@ static asio::awaitable<void> on_create_inventory_item_t(shared_ptr<Client> c, Su
|
||||
c->character()->add_item(item, *s->item_stack_limits(c->version()));
|
||||
|
||||
if (l->log.should_log(phosg::LogLevel::L_INFO)) {
|
||||
auto name = s->describe_item(c->version(), item, false);
|
||||
auto name = s->describe_item(c->version(), item);
|
||||
l->log.info_f("Player {} created inventory item {:08X} ({})", c->lobby_client_id, item.id, name);
|
||||
c->print_inventory();
|
||||
}
|
||||
@@ -2036,7 +2036,7 @@ static void on_drop_partial_stack_t(shared_ptr<Client> c, SubcommandMessage& msg
|
||||
|
||||
if (l->log.should_log(phosg::LogLevel::L_INFO)) {
|
||||
auto s = c->require_server_state();
|
||||
auto name = s->describe_item(c->version(), item, false);
|
||||
auto name = s->describe_item(c->version(), item);
|
||||
l->log.info_f("Player {} split stack to create floor item {:08X} ({}) at {}:({:g},{:g})",
|
||||
cmd.header.client_id, item.id, name, cmd.floor, cmd.pos.x, cmd.pos.z);
|
||||
c->print_inventory();
|
||||
@@ -2091,7 +2091,7 @@ static asio::awaitable<void> on_drop_partial_stack_bb(shared_ptr<Client> c, Subc
|
||||
|
||||
if (l->log.should_log(phosg::LogLevel::L_INFO)) {
|
||||
auto s = c->require_server_state();
|
||||
auto name = s->describe_item(c->version(), item, false);
|
||||
auto name = s->describe_item(c->version(), item);
|
||||
l->log.info_f("Player {} split stack {:08X} (removed: {}) at {}:({:g}, {:g})",
|
||||
cmd.header.client_id, cmd.item_id, name, cmd.floor, cmd.pos.x, cmd.pos.z);
|
||||
c->print_inventory();
|
||||
@@ -2124,7 +2124,7 @@ static asio::awaitable<void> on_buy_shop_item(shared_ptr<Client> c, SubcommandMe
|
||||
p->remove_meseta(price, c->version() != Version::BB_V4);
|
||||
|
||||
if (l->log.should_log(phosg::LogLevel::L_INFO)) {
|
||||
auto name = s->describe_item(c->version(), item, false);
|
||||
auto name = s->describe_item(c->version(), item);
|
||||
l->log.info_f("Player {} bought item {:08X} ({}) from shop ({} Meseta)",
|
||||
cmd.header.client_id, item.id, name, price);
|
||||
c->print_inventory();
|
||||
@@ -2156,7 +2156,7 @@ void send_item_notification_if_needed(shared_ptr<Client> c, const ItemData& item
|
||||
}
|
||||
|
||||
if (should_notify) {
|
||||
string name = s->describe_item(c->version(), item, true);
|
||||
string name = s->describe_item(c->version(), item, ItemNameIndex::Flag::INCLUDE_PSO_COLOR_ESCAPES);
|
||||
const char* rare_header = (should_include_rare_header ? "$C6Rare item dropped:\n" : "");
|
||||
send_text_message_fmt(c, "{}{}", rare_header, name);
|
||||
}
|
||||
@@ -2199,7 +2199,7 @@ static void on_box_or_enemy_item_drop_t(shared_ptr<Client> c, SubcommandMessage&
|
||||
l->on_item_id_generated_externally(item.id);
|
||||
l->add_item(cmd.item.floor, item, cmd.item.pos, obj_st, ene_st, should_notify ? 0x100F : 0x000F);
|
||||
|
||||
auto name = s->describe_item(c->version(), item, false);
|
||||
auto name = s->describe_item(c->version(), item);
|
||||
l->log.info_f("Player {} (leader) created floor item {:08X} ({}){} at {}:({:g}, {:g})",
|
||||
l->leader_id,
|
||||
item.id,
|
||||
@@ -2279,7 +2279,7 @@ static asio::awaitable<void> on_pick_up_item_generic(
|
||||
|
||||
if (l->log.should_log(phosg::LogLevel::L_INFO)) {
|
||||
auto s = c->require_server_state();
|
||||
auto name = s->describe_item(c->version(), fi->data, false);
|
||||
auto name = s->describe_item(c->version(), fi->data);
|
||||
l->log.info_f("Player {} picked up {:08X} ({})", client_id, item_id, name);
|
||||
c->print_inventory();
|
||||
}
|
||||
@@ -2313,8 +2313,8 @@ static asio::awaitable<void> on_pick_up_item_generic(
|
||||
|
||||
if (should_send_game_notif || should_send_global_notif) {
|
||||
string p_name = p->disp.name.decode();
|
||||
string desc_ingame = s->describe_item(c->version(), fi->data, true);
|
||||
string desc_http = s->describe_item(c->version(), fi->data, false);
|
||||
string desc_ingame = s->describe_item(c->version(), fi->data, ItemNameIndex::Flag::INCLUDE_PSO_COLOR_ESCAPES);
|
||||
string desc_http = s->describe_item(c->version(), fi->data);
|
||||
|
||||
if (s->http_server) {
|
||||
auto message = make_shared<phosg::JSON>(phosg::JSON::dict({
|
||||
@@ -2407,7 +2407,7 @@ static asio::awaitable<void> on_use_item(shared_ptr<Client> c, SubcommandMessage
|
||||
// Note: We do this weird scoping thing because player_use_item will
|
||||
// likely delete the item, which will break the reference here.
|
||||
const auto& item = p->inventory.items[index].data;
|
||||
name = s->describe_item(c->version(), item, false);
|
||||
name = s->describe_item(c->version(), item);
|
||||
}
|
||||
player_use_item(c, index, l->rand_crypt);
|
||||
|
||||
@@ -2438,9 +2438,9 @@ static asio::awaitable<void> on_feed_mag(shared_ptr<Client> c, SubcommandMessage
|
||||
// Note: We do this weird scoping thing because player_feed_mag will
|
||||
// likely delete the items, which will break the references here.
|
||||
const auto& fed_item = p->inventory.items[fed_index].data;
|
||||
fed_name = s->describe_item(c->version(), fed_item, false);
|
||||
fed_name = s->describe_item(c->version(), fed_item);
|
||||
const auto& mag_item = p->inventory.items[mag_index].data;
|
||||
mag_name = s->describe_item(c->version(), mag_item, false);
|
||||
mag_name = s->describe_item(c->version(), mag_item);
|
||||
}
|
||||
player_feed_mag(c, mag_index, fed_index);
|
||||
|
||||
@@ -2699,7 +2699,7 @@ static asio::awaitable<void> on_ep3_private_word_select_bb_bank_action(
|
||||
send_destroy_item_to_lobby(c, cmd.item_id, cmd.item_amount, true);
|
||||
|
||||
if (l->log.should_log(phosg::LogLevel::L_INFO)) {
|
||||
string name = s->describe_item(Version::BB_V4, item, false);
|
||||
string name = s->describe_item(Version::BB_V4, item);
|
||||
l->log.info_f("Player {} deposited item {:08X} (x{}) ({}) in the bank",
|
||||
c->lobby_client_id, cmd.item_id, cmd.item_amount, name);
|
||||
c->print_inventory();
|
||||
@@ -2729,7 +2729,7 @@ static asio::awaitable<void> on_ep3_private_word_select_bb_bank_action(
|
||||
send_create_inventory_item_to_lobby(c, c->lobby_client_id, item);
|
||||
|
||||
if (l->log.should_log(phosg::LogLevel::L_INFO)) {
|
||||
string name = s->describe_item(Version::BB_V4, item, false);
|
||||
string name = s->describe_item(Version::BB_V4, item);
|
||||
l->log.info_f("Player {} withdrew item {:08X} (x{}) ({}) from the bank",
|
||||
c->lobby_client_id, item.id, cmd.item_amount, name);
|
||||
c->print_inventory();
|
||||
@@ -3024,7 +3024,7 @@ static asio::awaitable<void> on_entity_drop_item_request(shared_ptr<Client> c, S
|
||||
if (res.item.empty()) {
|
||||
l->log.info_f("No item was created");
|
||||
} else {
|
||||
string name = s->describe_item(c->version(), res.item, false);
|
||||
string name = s->describe_item(c->version(), res.item);
|
||||
l->log.info_f("Entity {:04X} (area {:02X}) created item {}", cmd.entity_index, cmd.effective_area, name);
|
||||
if (drop_mode == Lobby::DropMode::SERVER_DUPLICATE) {
|
||||
for (const auto& lc : l->clients) {
|
||||
@@ -3062,7 +3062,7 @@ static asio::awaitable<void> on_entity_drop_item_request(shared_ptr<Client> c, S
|
||||
if (res.item.empty()) {
|
||||
l->log.info_f("No item was created for {}", lc->channel->name);
|
||||
} else {
|
||||
string name = s->describe_item(lc->version(), res.item, false);
|
||||
string name = s->describe_item(lc->version(), res.item);
|
||||
l->log.info_f("Entity {:04X} (area {:02X}) created item {}", cmd.entity_index, cmd.effective_area, name);
|
||||
res.item.id = l->generate_item_id(0xFF);
|
||||
l->log.info_f("Creating item {:08X} at {:02X}:{:g},{:g} for {}",
|
||||
@@ -4045,7 +4045,7 @@ static asio::awaitable<void> on_item_reward_request_bb(shared_ptr<Client> c, Sub
|
||||
c->character()->add_item(item, limits);
|
||||
send_create_inventory_item_to_lobby(c, c->lobby_client_id, item);
|
||||
if (l->log.should_log(phosg::LogLevel::L_INFO)) {
|
||||
auto name = s->describe_item(c->version(), item, false);
|
||||
auto name = s->describe_item(c->version(), item);
|
||||
l->log.info_f("Player {} created inventory item {:08X} ({}) via quest command",
|
||||
c->lobby_client_id, item.id, name);
|
||||
c->print_inventory();
|
||||
@@ -4053,7 +4053,7 @@ static asio::awaitable<void> on_item_reward_request_bb(shared_ptr<Client> c, Sub
|
||||
|
||||
} catch (const out_of_range&) {
|
||||
if (l->log.should_log(phosg::LogLevel::L_INFO)) {
|
||||
auto name = s->describe_item(c->version(), item, false);
|
||||
auto name = s->describe_item(c->version(), item);
|
||||
l->log.info_f("Player {} attempted to create inventory item {:08X} ({}) via quest command, but it cannot be placed in their inventory",
|
||||
c->lobby_client_id, item.id, name);
|
||||
}
|
||||
@@ -4084,7 +4084,7 @@ asio::awaitable<void> on_transfer_item_via_mail_message_bb(shared_ptr<Client> c,
|
||||
auto item = p->remove_item(cmd.item_id, cmd.amount, limits);
|
||||
|
||||
if (l->log.should_log(phosg::LogLevel::L_INFO)) {
|
||||
auto name = s->describe_item(c->version(), item, false);
|
||||
auto name = s->describe_item(c->version(), item);
|
||||
l->log.info_f("Player {} sent inventory item {}:{:08X} ({}) x{} to player {:08X}",
|
||||
c->lobby_client_id, cmd.header.client_id, cmd.item_id, name, cmd.amount, cmd.target_guild_card_number);
|
||||
c->print_inventory();
|
||||
@@ -4151,7 +4151,7 @@ static asio::awaitable<void> on_exchange_item_for_team_points_bb(shared_ptr<Clie
|
||||
s->team_index->add_member_points(c->login->account->account_id, points);
|
||||
|
||||
if (l->log.should_log(phosg::LogLevel::L_INFO)) {
|
||||
auto name = s->describe_item(c->version(), item, false);
|
||||
auto name = s->describe_item(c->version(), item);
|
||||
l->log.info_f("Player {} exchanged inventory item {}:{:08X} ({}) for {} team points",
|
||||
c->lobby_client_id, cmd.header.client_id, cmd.item_id, name, points);
|
||||
c->print_inventory();
|
||||
@@ -4184,7 +4184,7 @@ static asio::awaitable<void> on_destroy_inventory_item(shared_ptr<Client> c, Sub
|
||||
auto item = p->remove_item(cmd.item_id, cmd.amount, *s->item_stack_limits(c->version()));
|
||||
|
||||
if (l->log.should_log(phosg::LogLevel::L_INFO)) {
|
||||
auto name = s->describe_item(c->version(), item, false);
|
||||
auto name = s->describe_item(c->version(), item);
|
||||
l->log.info_f("Player {} destroyed inventory item {}:{:08X} ({})",
|
||||
c->lobby_client_id, cmd.header.client_id, cmd.item_id, name);
|
||||
c->print_inventory();
|
||||
@@ -4236,7 +4236,7 @@ static asio::awaitable<void> on_destroy_floor_item(shared_ptr<Client> c, Subcomm
|
||||
c->lobby_client_id, cmd.item_id);
|
||||
|
||||
} else {
|
||||
auto name = s->describe_item(c->version(), fi->data, false);
|
||||
auto name = s->describe_item(c->version(), fi->data);
|
||||
l->log.info_f("Player {} destroyed floor item {:08X} ({})", c->lobby_client_id, cmd.item_id, name);
|
||||
|
||||
// Only forward to players for whom the item was visible
|
||||
@@ -4342,7 +4342,7 @@ static asio::awaitable<void> on_sell_item_at_shop_bb(shared_ptr<Client> c, Subco
|
||||
p->add_meseta(price);
|
||||
|
||||
if (l->log.should_log(phosg::LogLevel::L_INFO)) {
|
||||
auto name = s->describe_item(c->version(), item, false);
|
||||
auto name = s->describe_item(c->version(), item);
|
||||
l->log.info_f("Player {} sold inventory item {:08X} ({}) for {} Meseta",
|
||||
c->lobby_client_id, cmd.item_id, name, price);
|
||||
c->print_inventory();
|
||||
@@ -4385,7 +4385,7 @@ static asio::awaitable<void> on_buy_shop_item_bb(shared_ptr<Client> c, Subcomman
|
||||
|
||||
if (l->log.should_log(phosg::LogLevel::L_INFO)) {
|
||||
auto s = c->require_server_state();
|
||||
auto name = s->describe_item(c->version(), item, false);
|
||||
auto name = s->describe_item(c->version(), item);
|
||||
l->log.info_f("Player {} purchased item {:08X} ({}) for {} meseta",
|
||||
c->lobby_client_id, item.id, name, price);
|
||||
c->print_inventory();
|
||||
@@ -5048,12 +5048,12 @@ static asio::awaitable<void> on_quest_F960_result_bb(shared_ptr<Client> c, Subco
|
||||
p->add_item(item, *s->item_stack_limits(c->version()));
|
||||
send_create_inventory_item_to_lobby(c, c->lobby_client_id, item);
|
||||
if (c->log.should_log(phosg::LogLevel::L_INFO)) {
|
||||
string name = s->describe_item(c->version(), item, false);
|
||||
string name = s->describe_item(c->version(), item);
|
||||
c->log.info_f("Awarded item {}", name);
|
||||
}
|
||||
} catch (const out_of_range&) {
|
||||
if (c->log.should_log(phosg::LogLevel::L_INFO)) {
|
||||
string name = s->describe_item(c->version(), item, false);
|
||||
string name = s->describe_item(c->version(), item);
|
||||
c->log.info_f("Attempted to award item {}, but inventory was full", name);
|
||||
}
|
||||
}
|
||||
|
||||
+3
-3
@@ -501,13 +501,13 @@ shared_ptr<const ItemNameIndex> ServerState::item_name_index(Version version) co
|
||||
return ret;
|
||||
}
|
||||
|
||||
string ServerState::describe_item(Version version, const ItemData& item, bool include_color_codes) const {
|
||||
string ServerState::describe_item(Version version, const ItemData& item, uint8_t flags) const {
|
||||
if (is_v1(version)) {
|
||||
ItemData encoded = item;
|
||||
encoded.encode_for_version(version, this->item_parameter_table(version));
|
||||
return this->item_name_index(version)->describe_item(encoded, include_color_codes);
|
||||
return this->item_name_index(version)->describe_item(encoded, flags);
|
||||
} else {
|
||||
return this->item_name_index(version)->describe_item(item, include_color_codes);
|
||||
return this->item_name_index(version)->describe_item(item, flags);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -351,7 +351,7 @@ struct ServerState : public std::enable_shared_from_this<ServerState> {
|
||||
std::shared_ptr<const ItemData::StackLimits> item_stack_limits(Version version) const;
|
||||
std::shared_ptr<const ItemNameIndex> item_name_index_opt(Version version) const; // Returns null if missing
|
||||
std::shared_ptr<const ItemNameIndex> item_name_index(Version version) const; // Throws if missing
|
||||
std::string describe_item(Version version, const ItemData& item, bool include_color_codes) const;
|
||||
std::string describe_item(Version version, const ItemData& item, uint8_t flags = 0) const;
|
||||
ItemData parse_item_description(Version version, const std::string& description) const;
|
||||
|
||||
const std::vector<uint32_t>& public_lobby_search_order(Version version, bool is_client_customization) const;
|
||||
|
||||
@@ -1072,7 +1072,7 @@ ShellCommand c_create_item(
|
||||
send_drop_stacked_item_to_channel(args.s, c->channel, item, c->floor, c->pos);
|
||||
send_drop_stacked_item_to_channel(args.s, c->proxy_session->server_channel, item, c->floor, c->pos);
|
||||
|
||||
string name = args.s->describe_item(c->version(), item, true);
|
||||
string name = args.s->describe_item(c->version(), item, ItemNameIndex::Flag::INCLUDE_PSO_COLOR_ESCAPES);
|
||||
send_text_message(c->channel, "$C7Item created:\n" + name);
|
||||
co_return deque<string>{};
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user