Skip to content

Commit bfe34c8

Browse files
authored
fix: player summon lasthit addUnjustifiedKills (opentibiabr#3256)
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.
1 parent 828817e commit bfe34c8

File tree

1 file changed

+34
-23
lines changed

1 file changed

+34
-23
lines changed

src/creatures/creature.cpp

Lines changed: 34 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -498,13 +498,17 @@ void Creature::onDeath() {
498498
bool lastHitUnjustified = false;
499499
bool mostDamageUnjustified = false;
500500
const auto &lastHitCreature = g_game().getCreatureByID(lastHitCreatureId);
501+
const auto &thisPlayer = getPlayer();
502+
const auto &thisCreature = getCreature();
503+
const auto &thisMaster = getMaster();
504+
const auto &thisMonster = getMonster();
501505
std::shared_ptr<Creature> lastHitCreatureMaster;
502-
if (lastHitCreature && getPlayer()) {
506+
if (lastHitCreature && thisPlayer) {
503507
/**
504508
* @deprecated -- This is here to trigger the deprecated onKill events in lua
505509
*/
506-
lastHitCreature->deprecatedOnKilledCreature(getCreature(), true);
507-
lastHitUnjustified = lastHitCreature->onKilledPlayer(getPlayer(), true);
510+
lastHitCreature->deprecatedOnKilledCreature(thisCreature, true);
511+
lastHitUnjustified = lastHitCreature->onKilledPlayer(thisPlayer, true);
508512
lastHitCreatureMaster = lastHitCreature->getMaster();
509513
} else {
510514
lastHitCreatureMaster = nullptr;
@@ -517,6 +521,7 @@ void Creature::onDeath() {
517521
int32_t mostDamage = 0;
518522
std::map<std::shared_ptr<Creature>, uint64_t> experienceMap;
519523
std::unordered_set<std::shared_ptr<Player>> killers;
524+
520525
for (const auto &[creatureId, damageInfo] : damageMap) {
521526
if (creatureId == 0) {
522527
continue;
@@ -533,12 +538,10 @@ void Creature::onDeath() {
533538
mostDamageCreature = attacker;
534539
}
535540

536-
if (attacker != getCreature()) {
541+
if (attacker != thisCreature) {
537542
const uint64_t gainExp = getGainedExperience(attacker);
538543
const auto &attackerMaster = attacker->getMaster() ? attacker->getMaster() : attacker;
539-
if (auto attackerPlayer = attackerMaster->getPlayer()) {
540-
attackerPlayer->removeAttacked(getPlayer());
541-
544+
if (const auto &attackerPlayer = attackerMaster->getPlayer()) {
542545
const auto &party = attackerPlayer->getParty();
543546
killers.insert(attackerPlayer);
544547
if (party && party->getLeader() && party->isSharedExperienceActive() && party->isSharedExperienceEnabled()) {
@@ -563,36 +566,44 @@ void Creature::onDeath() {
563566
}
564567

565568
for (const auto &[creature, experience] : experienceMap) {
566-
creature->onGainExperience(experience, getCreature());
569+
creature->onGainExperience(experience, thisCreature);
567570
}
568571

569-
mostDamageCreature = mostDamageCreature && mostDamageCreature->getMaster() ? mostDamageCreature->getMaster() : mostDamageCreature;
572+
const auto &mostDamageCreatureMaster = mostDamageCreature ? mostDamageCreature->getMaster() : nullptr;
573+
mostDamageCreature = mostDamageCreatureMaster ? mostDamageCreatureMaster : mostDamageCreature;
574+
570575
for (const auto &killer : killers) {
571-
if (const auto &monster = getMonster()) {
572-
killer->onKilledMonster(monster);
573-
} else if (const auto &player = getPlayer(); player && mostDamageCreature != killer) {
574-
killer->onKilledPlayer(player, false);
576+
if (thisMonster) {
577+
killer->onKilledMonster(thisMonster);
578+
} else if (thisPlayer) {
579+
bool isResponsible = mostDamageCreature == killer || (mostDamageCreatureMaster && mostDamageCreatureMaster == killer);
580+
if (isResponsible) {
581+
killer->onKilledPlayer(thisPlayer, false);
582+
}
583+
584+
killer->removeAttacked(thisPlayer);
575585
}
576586
}
577587

578588
/**
579589
* @deprecated -- This is here to trigger the deprecated onKill events in lua
580590
*/
581-
const auto &mostDamageCreatureMaster = mostDamageCreature ? mostDamageCreature->getMaster() : nullptr;
582-
if (mostDamageCreature && (mostDamageCreature != lastHitCreature || getMonster()) && mostDamageCreature != lastHitCreatureMaster) {
591+
if (mostDamageCreature && (mostDamageCreature != lastHitCreature || thisMonster) && mostDamageCreature != lastHitCreatureMaster) {
583592
if (lastHitCreature != mostDamageCreatureMaster && (lastHitCreatureMaster == nullptr || mostDamageCreatureMaster != lastHitCreatureMaster)) {
584-
mostDamageUnjustified = mostDamageCreature->deprecatedOnKilledCreature(getCreature(), false);
593+
mostDamageUnjustified = mostDamageCreature->deprecatedOnKilledCreature(thisCreature, false);
585594
}
586595
}
587596

588-
bool killedByPlayer = (mostDamageCreature && mostDamageCreature->getPlayer()) || (mostDamageCreatureMaster && mostDamageCreatureMaster->getPlayer());
589-
if (getPlayer()) {
597+
const auto &mostDamagePlayer = mostDamageCreature ? mostDamageCreature->getPlayer() : nullptr;
598+
const auto &mostMasterPlayer = mostDamageCreatureMaster ? mostDamageCreatureMaster->getPlayer() : nullptr;
599+
bool killedByPlayer = mostDamagePlayer || mostMasterPlayer;
600+
if (thisPlayer) {
590601
g_metrics().addCounter(
591602
"player_death",
592603
1,
593604
{
594605
{ "name", getNameDescription() },
595-
{ "level", std::to_string(getPlayer()->getLevel()) },
606+
{ "level", std::to_string(thisPlayer->getLevel()) },
596607
{ "most_damage_creature", mostDamageCreature ? mostDamageCreature->getName() : "(none)" },
597608
{ "last_hit_creature", lastHitCreature ? lastHitCreature->getName() : "(none)" },
598609
{ "most_damage_dealt", std::to_string(mostDamage) },
@@ -613,7 +624,7 @@ void Creature::onDeath() {
613624
{
614625
{ "name", getName() },
615626
{ "killer", killerName },
616-
{ "is_summon", std::to_string(getMaster() ? true : false) },
627+
{ "is_summon", std::to_string(thisMaster ? true : false) },
617628
{ "by_player", std::to_string(killedByPlayer) },
618629
}
619630
);
@@ -622,11 +633,11 @@ void Creature::onDeath() {
622633
bool droppedCorpse = dropCorpse(lastHitCreature, mostDamageCreature, lastHitUnjustified, mostDamageUnjustified);
623634
death(lastHitCreature);
624635

625-
if (droppedCorpse && !getPlayer()) {
626-
g_game().removeCreature(static_self_cast<Creature>(), false);
636+
if (droppedCorpse && !thisPlayer) {
637+
g_game().removeCreature(thisCreature, false);
627638
}
628639

629-
if (getMaster()) {
640+
if (thisMaster) {
630641
removeMaster();
631642
}
632643
}

0 commit comments

Comments
 (0)