mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-11 16:51: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::ChecksumVerification].log_to_console = 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
|
||||
|
||||
@ -128,6 +128,7 @@ namespace Logs {
|
||||
HTTP,
|
||||
Saylink,
|
||||
ChecksumVerification,
|
||||
CombatRecord,
|
||||
MaxCategoryID /* Don't Remove this */
|
||||
};
|
||||
|
||||
@ -214,6 +215,7 @@ namespace Logs {
|
||||
"HTTP",
|
||||
"Saylink",
|
||||
"ChecksumVerification",
|
||||
"CombatRecord",
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -706,6 +706,16 @@
|
||||
OutF(LogSys, Logs::Detail, Logs::ChecksumVerification, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} 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 {\
|
||||
if (LogSys.log_settings[log_category].is_category_enabled == 1)\
|
||||
LogSys.Out(debug_level, log_category, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
@ -1138,6 +1148,12 @@
|
||||
#define LogChecksumVerificationDetail(message, ...) do {\
|
||||
} while (0)
|
||||
|
||||
#define LogCombatRecord(message, ...) do {\
|
||||
} while (0)
|
||||
|
||||
#define LogCombatRecordDetail(message, ...) do {\
|
||||
} while (0)
|
||||
|
||||
#define Log(debug_level, log_category, message, ...) do {\
|
||||
} while (0)
|
||||
|
||||
|
||||
@ -19,6 +19,7 @@ SET(zone_sources
|
||||
client_mods.cpp
|
||||
client_packet.cpp
|
||||
client_process.cpp
|
||||
combat_record.cpp
|
||||
command.cpp
|
||||
corpse.cpp
|
||||
data_bucket.cpp
|
||||
@ -162,7 +163,7 @@ SET(zone_sources
|
||||
zone_reload.cpp
|
||||
zone_store.cpp
|
||||
zoning.cpp
|
||||
)
|
||||
)
|
||||
|
||||
SET(zone_headers
|
||||
aa.h
|
||||
@ -179,6 +180,7 @@ SET(zone_headers
|
||||
cheat_manager.h
|
||||
client.h
|
||||
client_packet.h
|
||||
combat_record.h
|
||||
command.h
|
||||
common.h
|
||||
corpse.h
|
||||
@ -283,7 +285,7 @@ SET(zone_headers
|
||||
zonedump.h
|
||||
zone_reload.h
|
||||
zone_store.h
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
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)
|
||||
);
|
||||
parse->EventNPC(EVENT_DEATH_COMPLETE, this, oos, export_string, 0);
|
||||
combat_record.Stop();
|
||||
|
||||
/* Zone controller process EVENT_DEATH_ZONE (Death events) */
|
||||
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 "../common/light_source.h"
|
||||
#include "../common/emu_constants.h"
|
||||
#include "combat_record.h"
|
||||
#include <set>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
@ -494,7 +495,7 @@ public:
|
||||
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,
|
||||
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);
|
||||
inline void SetOOCRegen(int32 newoocregen) {ooc_regen = newoocregen;}
|
||||
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 spawned_in_water;
|
||||
|
||||
CombatRecord combat_record{};
|
||||
|
||||
public:
|
||||
bool GetWasSpawnedInWater() const;
|
||||
|
||||
|
||||
@ -1955,6 +1955,8 @@ void Mob::AI_Event_Engaged(Mob *attacker, bool yell_for_help)
|
||||
if (emoteid != 0) {
|
||||
CastToNPC()->DoNPCEmote(ENTERCOMBAT, emoteid);
|
||||
}
|
||||
std::string mob_name = GetCleanName();
|
||||
combat_record.Start(mob_name);
|
||||
CastToNPC()->SetCombatEvent(true);
|
||||
}
|
||||
}
|
||||
@ -1976,19 +1978,18 @@ void Mob::AI_Event_NoLongerEngaged() {
|
||||
StopNavigation();
|
||||
ClearRampage();
|
||||
|
||||
if(IsNPC())
|
||||
{
|
||||
if (IsNPC()) {
|
||||
SetPrimaryAggro(false);
|
||||
SetAssistAggro(false);
|
||||
if(CastToNPC()->GetCombatEvent() && GetHP() > 0)
|
||||
{
|
||||
if(entity_list.GetNPCByID(GetID()))
|
||||
{
|
||||
uint16 emoteid = CastToNPC()->GetEmoteID();
|
||||
parse->EventNPC(EVENT_COMBAT, CastToNPC(), nullptr, "0", 0);
|
||||
if(emoteid != 0)
|
||||
CastToNPC()->DoNPCEmote(LEAVECOMBAT,emoteid);
|
||||
CastToNPC()->SetCombatEvent(false);
|
||||
if (CastToNPC()->GetCombatEvent() && GetHP() > 0) {
|
||||
if (entity_list.GetNPCByID(this->GetID())) {
|
||||
uint16 emoteid = CastToNPC()->GetEmoteID();
|
||||
parse->EventNPC(EVENT_COMBAT, CastToNPC(), nullptr, "0", 0);
|
||||
if (emoteid != 0) {
|
||||
CastToNPC()->DoNPCEmote(LEAVECOMBAT, emoteid);
|
||||
}
|
||||
combat_record.Stop();
|
||||
CastToNPC()->SetCombatEvent(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -102,6 +102,7 @@ Copyright (C) 2001-2002 EQEMu Development Team (http://eqemu.org)
|
||||
|
||||
#include "mob_movement_manager.h"
|
||||
#include "client.h"
|
||||
#include "mob.h"
|
||||
|
||||
|
||||
extern Zone* zone;
|
||||
@ -6773,3 +6774,17 @@ bool Mob::IsFromTriggeredSpell(CastingSlot slot, uint32 item_slot) {
|
||||
}
|
||||
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