Skip to content

Commit

Permalink
fix: player summon lasthit addUnjustifiedKills (#3256)
Browse files Browse the repository at this point in the history
This addresses an issue where unjustified kills were not being properly activated when the last hit on a player was caused by a summon.
The issue occurred because the master of the summon was not being correctly treated as responsible for the kill in certain scenarios. 
This fix ensures that the master of the summon is correctly identified and unjustified kills are processed appropriately.
  • Loading branch information
dudantas authored Jan 25, 2025
1 parent 5781de7 commit 6127fbf
Showing 1 changed file with 34 additions and 23 deletions.
57 changes: 34 additions & 23 deletions src/creatures/creature.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -498,13 +498,17 @@ void Creature::onDeath() {
bool lastHitUnjustified = false;
bool mostDamageUnjustified = false;
const auto &lastHitCreature = g_game().getCreatureByID(lastHitCreatureId);
const auto &thisPlayer = getPlayer();
const auto &thisCreature = getCreature();
const auto &thisMaster = getMaster();
const auto &thisMonster = getMonster();
std::shared_ptr<Creature> lastHitCreatureMaster;
if (lastHitCreature && getPlayer()) {
if (lastHitCreature && thisPlayer) {
/**
* @deprecated -- This is here to trigger the deprecated onKill events in lua
*/
lastHitCreature->deprecatedOnKilledCreature(getCreature(), true);
lastHitUnjustified = lastHitCreature->onKilledPlayer(getPlayer(), true);
lastHitCreature->deprecatedOnKilledCreature(thisCreature, true);
lastHitUnjustified = lastHitCreature->onKilledPlayer(thisPlayer, true);
lastHitCreatureMaster = lastHitCreature->getMaster();
} else {
lastHitCreatureMaster = nullptr;
Expand All @@ -517,6 +521,7 @@ void Creature::onDeath() {
int32_t mostDamage = 0;
std::map<std::shared_ptr<Creature>, uint64_t> experienceMap;
std::unordered_set<std::shared_ptr<Player>> killers;

for (const auto &[creatureId, damageInfo] : damageMap) {
if (creatureId == 0) {
continue;
Expand All @@ -533,12 +538,10 @@ void Creature::onDeath() {
mostDamageCreature = attacker;
}

if (attacker != getCreature()) {
if (attacker != thisCreature) {
const uint64_t gainExp = getGainedExperience(attacker);
const auto &attackerMaster = attacker->getMaster() ? attacker->getMaster() : attacker;
if (auto attackerPlayer = attackerMaster->getPlayer()) {
attackerPlayer->removeAttacked(getPlayer());

if (const auto &attackerPlayer = attackerMaster->getPlayer()) {
const auto &party = attackerPlayer->getParty();
killers.insert(attackerPlayer);
if (party && party->getLeader() && party->isSharedExperienceActive() && party->isSharedExperienceEnabled()) {
Expand All @@ -563,36 +566,44 @@ void Creature::onDeath() {
}

for (const auto &[creature, experience] : experienceMap) {
creature->onGainExperience(experience, getCreature());
creature->onGainExperience(experience, thisCreature);
}

mostDamageCreature = mostDamageCreature && mostDamageCreature->getMaster() ? mostDamageCreature->getMaster() : mostDamageCreature;
const auto &mostDamageCreatureMaster = mostDamageCreature ? mostDamageCreature->getMaster() : nullptr;
mostDamageCreature = mostDamageCreatureMaster ? mostDamageCreatureMaster : mostDamageCreature;

for (const auto &killer : killers) {
if (const auto &monster = getMonster()) {
killer->onKilledMonster(monster);
} else if (const auto &player = getPlayer(); player && mostDamageCreature != killer) {
killer->onKilledPlayer(player, false);
if (thisMonster) {
killer->onKilledMonster(thisMonster);
} else if (thisPlayer) {
bool isResponsible = mostDamageCreature == killer || (mostDamageCreatureMaster && mostDamageCreatureMaster == killer);
if (isResponsible) {
killer->onKilledPlayer(thisPlayer, false);
}

killer->removeAttacked(thisPlayer);
}
}

/**
* @deprecated -- This is here to trigger the deprecated onKill events in lua
*/
const auto &mostDamageCreatureMaster = mostDamageCreature ? mostDamageCreature->getMaster() : nullptr;
if (mostDamageCreature && (mostDamageCreature != lastHitCreature || getMonster()) && mostDamageCreature != lastHitCreatureMaster) {
if (mostDamageCreature && (mostDamageCreature != lastHitCreature || thisMonster) && mostDamageCreature != lastHitCreatureMaster) {
if (lastHitCreature != mostDamageCreatureMaster && (lastHitCreatureMaster == nullptr || mostDamageCreatureMaster != lastHitCreatureMaster)) {
mostDamageUnjustified = mostDamageCreature->deprecatedOnKilledCreature(getCreature(), false);
mostDamageUnjustified = mostDamageCreature->deprecatedOnKilledCreature(thisCreature, false);
}
}

bool killedByPlayer = (mostDamageCreature && mostDamageCreature->getPlayer()) || (mostDamageCreatureMaster && mostDamageCreatureMaster->getPlayer());
if (getPlayer()) {
const auto &mostDamagePlayer = mostDamageCreature ? mostDamageCreature->getPlayer() : nullptr;
const auto &mostMasterPlayer = mostDamageCreatureMaster ? mostDamageCreatureMaster->getPlayer() : nullptr;
bool killedByPlayer = mostDamagePlayer || mostMasterPlayer;
if (thisPlayer) {
g_metrics().addCounter(
"player_death",
1,
{
{ "name", getNameDescription() },
{ "level", std::to_string(getPlayer()->getLevel()) },
{ "level", std::to_string(thisPlayer->getLevel()) },
{ "most_damage_creature", mostDamageCreature ? mostDamageCreature->getName() : "(none)" },
{ "last_hit_creature", lastHitCreature ? lastHitCreature->getName() : "(none)" },
{ "most_damage_dealt", std::to_string(mostDamage) },
Expand All @@ -613,7 +624,7 @@ void Creature::onDeath() {
{
{ "name", getName() },
{ "killer", killerName },
{ "is_summon", std::to_string(getMaster() ? true : false) },
{ "is_summon", std::to_string(thisMaster ? true : false) },
{ "by_player", std::to_string(killedByPlayer) },
}
);
Expand All @@ -622,11 +633,11 @@ void Creature::onDeath() {
bool droppedCorpse = dropCorpse(lastHitCreature, mostDamageCreature, lastHitUnjustified, mostDamageUnjustified);
death(lastHitCreature);

if (droppedCorpse && !getPlayer()) {
g_game().removeCreature(static_self_cast<Creature>(), false);
if (droppedCorpse && !thisPlayer) {
g_game().removeCreature(thisCreature, false);
}

if (getMaster()) {
if (thisMaster) {
removeMaster();
}
}
Expand Down

0 comments on commit 6127fbf

Please sign in to comment.