Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 34 additions & 8 deletions src/engine/core/obj_handler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -293,30 +293,56 @@ RoomVnum get_room_where_obj(ObjData *obj, bool deep) {
// issue #3563: единый лог о пропаже вещи у игрока. Ищет игрока-владельца
// (инвентарь/экипировка/его контейнер) и пишет в syslog причину. Звать НАДО
// до отвязки вещи от владельца, иначе get_carried_by/get_worn_by уже пустые.
// issue #3563: описание держателя вещи для лога (родительный падеж) -- игрок или
// чармис игрока. "" -> обычный моб/никто (не логируем). Для чармиса поднимаемся
// по цепочке мастеров до игрока-владельца.
std::string ObjHolderLogDesc(CharData *holder) {
if (!holder) {
return "";
}
char buf[kMaxStringLength];
if (!holder->IsNpc()) {
snprintf(buf, sizeof(buf), "игрока %s", GET_NAME(holder));
return buf;
}
if (IsCharmice(holder)) {
// чармис висит напрямую на игроке (конвенция: pk.cpp, equipment.cpp и т.п.)
CharData *m = holder->get_master();
if (m && !m->IsNpc()) {
snprintf(buf, sizeof(buf), "чармиса '%s' игрока %s", GET_NAME(holder), GET_NAME(m));
} else {
snprintf(buf, sizeof(buf), "чармиса '%s' (потерявшего владельца)", GET_NAME(holder));
}
return buf;
}
return "";
}

void LogPlayerObjLoss(ObjData *obj, const char *reason) {
if (!obj) {
return;
}
CharData *owner = obj->get_carried_by() ? obj->get_carried_by()
CharData *holder = obj->get_carried_by() ? obj->get_carried_by()
: (obj->get_worn_by() ? obj->get_worn_by() : nullptr);
if (!owner) {
// вещь в контейнере -- ищем игрока-владельца контейнера
if (!holder) {
// вещь в контейнере -- ищем владельца контейнера
for (ObjData *cont = obj->get_in_obj(); cont; cont = cont->get_in_obj()) {
if (cont->get_carried_by()) {
owner = cont->get_carried_by();
holder = cont->get_carried_by();
break;
}
if (cont->get_worn_by()) {
owner = cont->get_worn_by();
holder = cont->get_worn_by();
break;
}
}
}
if (!owner || owner->IsNpc()) {
const std::string who = ObjHolderLogDesc(holder);
if (who.empty()) { // не игрок и не чармис игрока -- не логируем
return;
}
log("[Obj loss] у игрока %s пропала вещь '%s' vnum == %d (%s), timer == %d, прочность == %d/%d",
GET_NAME(owner), obj->get_PName(grammar::ECase::kNom).c_str(), GET_OBJ_VNUM(obj),
log("[Obj loss] у %s пропала вещь '%s' vnum == %d (%s), timer == %d, прочность == %d/%d",
who.c_str(), obj->get_PName(grammar::ECase::kNom).c_str(), GET_OBJ_VNUM(obj),
reason, obj->get_timer(), obj->get_current_durability(), obj->get_maximum_durability());
}

Expand Down
4 changes: 4 additions & 0 deletions src/engine/core/obj_handler.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@

#include "engine/structs/structs.h" // RoomRnum / RoomVnum

#include <string>

class CharData;
class ObjData;

Expand All @@ -22,6 +24,8 @@ RoomVnum get_room_where_obj(ObjData *obj, bool deep = false);
void ExtractObjFromWorld(ObjData *obj, bool showlog = false);
// issue #3563: пишет в syslog о пропаже вещи у игрока; звать до отвязки от владельца.
void LogPlayerObjLoss(ObjData *obj, const char *reason);
// issue #3563: описание держателя для лога -- "игрока X" / "чармиса 'Y' игрока X" / "" (моб).
std::string ObjHolderLogDesc(CharData *holder);
void UpdateCharObjects(CharData *ch);
void DropObjOnZoneReset(CharData *ch, ObjData *obj, bool inv, bool zone_reset);
int get_object_low_rent(ObjData *obj);
Expand Down
5 changes: 4 additions & 1 deletion src/engine/ui/cmd/do_steal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include "gameplay/mechanics/mount.h"
#include "engine/entities/obj_data.h"
#include "engine/core/char_equip_flags.h"
#include "engine/core/obj_handler.h" // ObjHolderLogDesc (issue #3563)
#include "gameplay/mechanics/equipment.h"
#include "gameplay/mechanics/inventory.h"
#include "gameplay/skills/skills.h"
Expand Down Expand Up @@ -99,9 +100,11 @@ void go_steal(CharData *ch, CharData *vict, char *obj_name) {
act("$n украл$g $o3 у $N1.", false, ch, obj, vict, kToNotVict | kToArenaListen);
// issue #3563: кража НАДЕТОЙ вещи (имм или у спящей жертвы) -- она уходит
// через UnequipChar, без obj_from_char, поэтому логируем отдельно.
// Для чармиса-жертвы в описании будет имя чармиса и его владельца.
const std::string who = ObjHolderLogDesc(vict);
log("[Steal eq] %s украл надетую вещь '%s' (vnum %d) у %s",
GET_NAME(ch), obj->get_PName(grammar::ECase::kNom).c_str(),
GET_OBJ_VNUM(obj), GET_NAME(vict));
GET_OBJ_VNUM(obj), who.empty() ? GET_NAME(vict) : who.c_str());
PlaceObjToInventory(UnequipChar(vict, eq_pos, CharEquipFlags()), ch);
}
}
Expand Down
11 changes: 6 additions & 5 deletions src/gameplay/skills/punctual_style.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -648,13 +648,14 @@ void PerformPunctualHit(CharData *ch, CharData *victim, HitData &hit_data) {
if (!victim->IsNpc() && ROOM_FLAGGED(victim->in_room, ERoomFlag::kArena)) {
PlaceObjToInventory(obj, victim);
} else {
// issue #3563: точный стиль выбил вещь НА ЗЕМЛЮ (не в инвентарь). Для игрока
// логируем -- иначе потом непонятно, куда делось оружие (валяется в комнате,
// владелец не находит). Мобов не логируем, чтобы не шуметь.
if (!victim->IsNpc()) {
// issue #3563: точный стиль выбил вещь НА ЗЕМЛЮ (не в инвентарь). Логируем для
// игрока и чармиса игрока -- иначе непонятно, куда делось оружие (валяется в
// комнате, владелец не находит). Обычных мобов не логируем, чтобы не шуметь.
const std::string who = ObjHolderLogDesc(victim);
if (!who.empty()) {
log("[Punctual -> ground] %s выбил точным стилем '%s' (vnum %d) из рук %s -> комната [%d] %s",
GET_NAME(ch), obj->get_PName(grammar::ECase::kNom).c_str(), GET_OBJ_VNUM(obj),
GET_NAME(victim), world[victim->in_room]->vnum, world[victim->in_room]->name);
who.c_str(), world[victim->in_room]->vnum, world[victim->in_room]->name);
}
PlaceObjToRoom(obj, victim->in_room);
CheckObjDecay(obj);
Expand Down
Loading