mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-13 10:31:29 +00:00
[Combat] Basic Combat Recording (#2090)
* Basic combat recording * Update combat_record.h
This commit is contained in:
parent
759f9bd007
commit
c7dbdfae58
@ -134,6 +134,7 @@ EQEmuLogSys *EQEmuLogSys::LoadLogSettingsDefaults()
|
|||||||
log_settings[Logs::HTTP].log_to_gmsay = static_cast<uint8>(Logs::General);
|
log_settings[Logs::HTTP].log_to_gmsay = static_cast<uint8>(Logs::General);
|
||||||
log_settings[Logs::ChecksumVerification].log_to_console = static_cast<uint8>(Logs::General);
|
log_settings[Logs::ChecksumVerification].log_to_console = static_cast<uint8>(Logs::General);
|
||||||
log_settings[Logs::ChecksumVerification].log_to_gmsay = static_cast<uint8>(Logs::General);
|
log_settings[Logs::ChecksumVerification].log_to_gmsay = static_cast<uint8>(Logs::General);
|
||||||
|
log_settings[Logs::CombatRecord].log_to_gmsay = static_cast<uint8>(Logs::General);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* RFC 5424
|
* RFC 5424
|
||||||
|
|||||||
@ -128,6 +128,7 @@ namespace Logs {
|
|||||||
HTTP,
|
HTTP,
|
||||||
Saylink,
|
Saylink,
|
||||||
ChecksumVerification,
|
ChecksumVerification,
|
||||||
|
CombatRecord,
|
||||||
MaxCategoryID /* Don't Remove this */
|
MaxCategoryID /* Don't Remove this */
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -214,6 +215,7 @@ namespace Logs {
|
|||||||
"HTTP",
|
"HTTP",
|
||||||
"Saylink",
|
"Saylink",
|
||||||
"ChecksumVerification",
|
"ChecksumVerification",
|
||||||
|
"CombatRecord",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -706,6 +706,16 @@
|
|||||||
OutF(LogSys, Logs::Detail, Logs::ChecksumVerification, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
OutF(LogSys, Logs::Detail, Logs::ChecksumVerification, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
#define LogCombatRecord(message, ...) do {\
|
||||||
|
if (LogSys.log_settings[Logs::CombatRecord].is_category_enabled == 1)\
|
||||||
|
OutF(LogSys, Logs::General, Logs::CombatRecord, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define LogCombatRecordDetail(message, ...) do {\
|
||||||
|
if (LogSys.log_settings[Logs::CombatRecord].is_category_enabled == 1)\
|
||||||
|
OutF(LogSys, Logs::Detail, Logs::CombatRecord, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||||
|
} while (0)
|
||||||
|
|
||||||
#define Log(debug_level, log_category, message, ...) do {\
|
#define Log(debug_level, log_category, message, ...) do {\
|
||||||
if (LogSys.log_settings[log_category].is_category_enabled == 1)\
|
if (LogSys.log_settings[log_category].is_category_enabled == 1)\
|
||||||
LogSys.Out(debug_level, log_category, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
LogSys.Out(debug_level, log_category, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||||
@ -1138,6 +1148,12 @@
|
|||||||
#define LogChecksumVerificationDetail(message, ...) do {\
|
#define LogChecksumVerificationDetail(message, ...) do {\
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
#define LogCombatRecord(message, ...) do {\
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define LogCombatRecordDetail(message, ...) do {\
|
||||||
|
} while (0)
|
||||||
|
|
||||||
#define Log(debug_level, log_category, message, ...) do {\
|
#define Log(debug_level, log_category, message, ...) do {\
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
|||||||
@ -19,6 +19,7 @@ SET(zone_sources
|
|||||||
client_mods.cpp
|
client_mods.cpp
|
||||||
client_packet.cpp
|
client_packet.cpp
|
||||||
client_process.cpp
|
client_process.cpp
|
||||||
|
combat_record.cpp
|
||||||
command.cpp
|
command.cpp
|
||||||
corpse.cpp
|
corpse.cpp
|
||||||
data_bucket.cpp
|
data_bucket.cpp
|
||||||
@ -162,7 +163,7 @@ SET(zone_sources
|
|||||||
zone_reload.cpp
|
zone_reload.cpp
|
||||||
zone_store.cpp
|
zone_store.cpp
|
||||||
zoning.cpp
|
zoning.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
SET(zone_headers
|
SET(zone_headers
|
||||||
aa.h
|
aa.h
|
||||||
@ -179,6 +180,7 @@ SET(zone_headers
|
|||||||
cheat_manager.h
|
cheat_manager.h
|
||||||
client.h
|
client.h
|
||||||
client_packet.h
|
client_packet.h
|
||||||
|
combat_record.h
|
||||||
command.h
|
command.h
|
||||||
common.h
|
common.h
|
||||||
corpse.h
|
corpse.h
|
||||||
@ -283,7 +285,7 @@ SET(zone_headers
|
|||||||
zonedump.h
|
zonedump.h
|
||||||
zone_reload.h
|
zone_reload.h
|
||||||
zone_store.h
|
zone_store.h
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
ADD_EXECUTABLE(zone ${zone_sources} ${zone_headers})
|
ADD_EXECUTABLE(zone ${zone_sources} ${zone_headers})
|
||||||
|
|||||||
@ -2724,6 +2724,7 @@ bool NPC::Death(Mob* killer_mob, int32 damage, uint16 spell, EQ::skills::SkillTy
|
|||||||
static_cast<int>(attack_skill)
|
static_cast<int>(attack_skill)
|
||||||
);
|
);
|
||||||
parse->EventNPC(EVENT_DEATH_COMPLETE, this, oos, export_string, 0);
|
parse->EventNPC(EVENT_DEATH_COMPLETE, this, oos, export_string, 0);
|
||||||
|
combat_record.Stop();
|
||||||
|
|
||||||
/* Zone controller process EVENT_DEATH_ZONE (Death events) */
|
/* Zone controller process EVENT_DEATH_ZONE (Death events) */
|
||||||
if (RuleB(Zone, UseZoneController)) {
|
if (RuleB(Zone, UseZoneController)) {
|
||||||
|
|||||||
60
zone/combat_record.cpp
Normal file
60
zone/combat_record.cpp
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
#include "combat_record.h"
|
||||||
|
#include "../common/eqemu_logsys.h"
|
||||||
|
#include "../common/string_util.h"
|
||||||
|
|
||||||
|
void CombatRecord::Start(std::string in_mob_name)
|
||||||
|
{
|
||||||
|
start_time = std::time(nullptr);
|
||||||
|
end_time = 0;
|
||||||
|
damage_received = 0;
|
||||||
|
heal_received = 0;
|
||||||
|
mob_name = in_mob_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CombatRecord::Stop()
|
||||||
|
{
|
||||||
|
end_time = std::time(nullptr);
|
||||||
|
|
||||||
|
double time_in_combat = TimeInCombat();
|
||||||
|
|
||||||
|
LogCombatRecord(
|
||||||
|
"[Summary] Mob [{}] [Received] DPS [{:.0f}] Heal/s [{:.0f}] Duration [{}] ({}s)",
|
||||||
|
mob_name,
|
||||||
|
time_in_combat > 0 ? (damage_received / time_in_combat) : damage_received,
|
||||||
|
time_in_combat > 0 ? (heal_received / time_in_combat) : heal_received,
|
||||||
|
time_in_combat > 0 ? ConvertSecondsToTime(time_in_combat) : "",
|
||||||
|
time_in_combat
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CombatRecord::InCombat()
|
||||||
|
{
|
||||||
|
return start_time > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CombatRecord::ProcessHPEvent(int hp, int current_hp)
|
||||||
|
{
|
||||||
|
// damage
|
||||||
|
if (hp < current_hp) {
|
||||||
|
damage_received = damage_received + abs(current_hp - hp);
|
||||||
|
}
|
||||||
|
|
||||||
|
// heal
|
||||||
|
if (hp > current_hp && current_hp > 0) {
|
||||||
|
heal_received = heal_received + abs(current_hp - hp);
|
||||||
|
}
|
||||||
|
|
||||||
|
LogCombatRecordDetail(
|
||||||
|
"damage_received [{}] heal_received [{}] current_hp [{}] hp [{}] calc [{}]",
|
||||||
|
damage_received,
|
||||||
|
heal_received,
|
||||||
|
current_hp,
|
||||||
|
hp,
|
||||||
|
abs(current_hp - hp)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
double CombatRecord::TimeInCombat() const
|
||||||
|
{
|
||||||
|
return difftime(end_time, start_time);
|
||||||
|
}
|
||||||
23
zone/combat_record.h
Normal file
23
zone/combat_record.h
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
#ifndef EQEMU_COMBAT_RECORD_H
|
||||||
|
#define EQEMU_COMBAT_RECORD_H
|
||||||
|
|
||||||
|
#include <ctime>
|
||||||
|
#include <string>
|
||||||
|
#include "../common/types.h"
|
||||||
|
|
||||||
|
class CombatRecord {
|
||||||
|
public:
|
||||||
|
void Start(std::string in_mob_name);
|
||||||
|
void Stop();
|
||||||
|
bool InCombat();
|
||||||
|
void ProcessHPEvent(int hp, int current_hp);
|
||||||
|
double TimeInCombat() const;
|
||||||
|
private:
|
||||||
|
std::string mob_name;
|
||||||
|
time_t start_time = 0;
|
||||||
|
time_t end_time = 0;
|
||||||
|
int64 damage_received = 0;
|
||||||
|
int64 heal_received = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //EQEMU_COMBAT_RECORD_H
|
||||||
@ -28,6 +28,7 @@
|
|||||||
#include "aa.h"
|
#include "aa.h"
|
||||||
#include "../common/light_source.h"
|
#include "../common/light_source.h"
|
||||||
#include "../common/emu_constants.h"
|
#include "../common/emu_constants.h"
|
||||||
|
#include "combat_record.h"
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
@ -494,7 +495,7 @@ public:
|
|||||||
virtual bool Death(Mob* killerMob, int32 damage, uint16 spell_id, EQ::skills::SkillType attack_skill) = 0;
|
virtual bool Death(Mob* killerMob, int32 damage, uint16 spell_id, EQ::skills::SkillType attack_skill) = 0;
|
||||||
virtual void Damage(Mob* from, int32 damage, uint16 spell_id, EQ::skills::SkillType attack_skill,
|
virtual void Damage(Mob* from, int32 damage, uint16 spell_id, EQ::skills::SkillType attack_skill,
|
||||||
bool avoidable = true, int8 buffslot = -1, bool iBuffTic = false, eSpecialAttacks special = eSpecialAttacks::None) = 0;
|
bool avoidable = true, int8 buffslot = -1, bool iBuffTic = false, eSpecialAttacks special = eSpecialAttacks::None) = 0;
|
||||||
inline virtual void SetHP(int32 hp) { if (hp >= max_hp) current_hp = max_hp; else current_hp = hp;}
|
virtual void SetHP(int32 hp);
|
||||||
bool ChangeHP(Mob* other, int32 amount, uint16 spell_id = 0, int8 buffslot = -1, bool iBuffTic = false);
|
bool ChangeHP(Mob* other, int32 amount, uint16 spell_id = 0, int8 buffslot = -1, bool iBuffTic = false);
|
||||||
inline void SetOOCRegen(int32 newoocregen) {ooc_regen = newoocregen;}
|
inline void SetOOCRegen(int32 newoocregen) {ooc_regen = newoocregen;}
|
||||||
virtual void Heal();
|
virtual void Heal();
|
||||||
@ -1643,6 +1644,8 @@ protected:
|
|||||||
bool degenerating_effects; // true if we have a buff that needs to be recalced every tick
|
bool degenerating_effects; // true if we have a buff that needs to be recalced every tick
|
||||||
bool spawned_in_water;
|
bool spawned_in_water;
|
||||||
|
|
||||||
|
CombatRecord combat_record{};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
bool GetWasSpawnedInWater() const;
|
bool GetWasSpawnedInWater() const;
|
||||||
|
|
||||||
|
|||||||
@ -1955,6 +1955,8 @@ void Mob::AI_Event_Engaged(Mob *attacker, bool yell_for_help)
|
|||||||
if (emoteid != 0) {
|
if (emoteid != 0) {
|
||||||
CastToNPC()->DoNPCEmote(ENTERCOMBAT, emoteid);
|
CastToNPC()->DoNPCEmote(ENTERCOMBAT, emoteid);
|
||||||
}
|
}
|
||||||
|
std::string mob_name = GetCleanName();
|
||||||
|
combat_record.Start(mob_name);
|
||||||
CastToNPC()->SetCombatEvent(true);
|
CastToNPC()->SetCombatEvent(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1976,19 +1978,18 @@ void Mob::AI_Event_NoLongerEngaged() {
|
|||||||
StopNavigation();
|
StopNavigation();
|
||||||
ClearRampage();
|
ClearRampage();
|
||||||
|
|
||||||
if(IsNPC())
|
if (IsNPC()) {
|
||||||
{
|
|
||||||
SetPrimaryAggro(false);
|
SetPrimaryAggro(false);
|
||||||
SetAssistAggro(false);
|
SetAssistAggro(false);
|
||||||
if(CastToNPC()->GetCombatEvent() && GetHP() > 0)
|
if (CastToNPC()->GetCombatEvent() && GetHP() > 0) {
|
||||||
{
|
if (entity_list.GetNPCByID(this->GetID())) {
|
||||||
if(entity_list.GetNPCByID(GetID()))
|
uint16 emoteid = CastToNPC()->GetEmoteID();
|
||||||
{
|
parse->EventNPC(EVENT_COMBAT, CastToNPC(), nullptr, "0", 0);
|
||||||
uint16 emoteid = CastToNPC()->GetEmoteID();
|
if (emoteid != 0) {
|
||||||
parse->EventNPC(EVENT_COMBAT, CastToNPC(), nullptr, "0", 0);
|
CastToNPC()->DoNPCEmote(LEAVECOMBAT, emoteid);
|
||||||
if(emoteid != 0)
|
}
|
||||||
CastToNPC()->DoNPCEmote(LEAVECOMBAT,emoteid);
|
combat_record.Stop();
|
||||||
CastToNPC()->SetCombatEvent(false);
|
CastToNPC()->SetCombatEvent(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -102,6 +102,7 @@ Copyright (C) 2001-2002 EQEMu Development Team (http://eqemu.org)
|
|||||||
|
|
||||||
#include "mob_movement_manager.h"
|
#include "mob_movement_manager.h"
|
||||||
#include "client.h"
|
#include "client.h"
|
||||||
|
#include "mob.h"
|
||||||
|
|
||||||
|
|
||||||
extern Zone* zone;
|
extern Zone* zone;
|
||||||
@ -6773,3 +6774,17 @@ bool Mob::IsFromTriggeredSpell(CastingSlot slot, uint32 item_slot) {
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Mob::SetHP(int32 hp)
|
||||||
|
{
|
||||||
|
if (hp >= max_hp) {
|
||||||
|
current_hp = max_hp;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (combat_record.InCombat()) {
|
||||||
|
combat_record.ProcessHPEvent(hp, current_hp);
|
||||||
|
}
|
||||||
|
|
||||||
|
current_hp = hp;
|
||||||
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user