From b9d5ef99639ac60469d5f1f4bf645e6f2e0c63bd Mon Sep 17 00:00:00 2001 From: Aaron Kimbrell Date: Sat, 26 Sep 2026 18:45:53 -0500 Subject: [PATCH] fix: Skullkin drill credits the player who breaks it The drill only progressed missions 972, 1305 and 1308 for the player who started it, so another player breaking the drill (the usual way on a busy Crux Prime) got no credit for the drill objectives. The live script (L_SKULLKIN_DRILL.lua, notifyDie) credits the killer, then also the activator when that is someone else, which is what it does now. It also no longer dereferences a null attacker. Removes the "Missions" TODO. May account for part of #1021 (Crux Prime daily smashable objectives not tallying); needs an in-game check with two players. Refs #1021 Co-Authored-By: Claude Opus 5.5 --- dScripts/02_server/Map/AM/AmSkullkinDrill.cpp | 27 ++++++++++--------- 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/dScripts/02_server/Map/AM/AmSkullkinDrill.cpp b/dScripts/02_server/Map/AM/AmSkullkinDrill.cpp index df5a300fa..93b876cf8 100644 --- a/dScripts/02_server/Map/AM/AmSkullkinDrill.cpp +++ b/dScripts/02_server/Map/AM/AmSkullkinDrill.cpp @@ -226,7 +226,7 @@ void AmSkullkinDrill::PlayAnim(Entity* self, Entity* player, const std::string& void AmSkullkinDrill::OnHitOrHealResult(Entity* self, Entity* attacker, int32_t damage) { auto* destroyableComponent = self->GetComponent(); - if (destroyableComponent == nullptr || !attacker->IsPlayer()) { + if (destroyableComponent == nullptr || attacker == nullptr || !attacker->IsPlayer()) { return; } @@ -234,19 +234,22 @@ void AmSkullkinDrill::OnHitOrHealResult(Entity* self, Entity* attacker, int32_t return; } - const auto activaterID = self->GetVar(u"activaterID"); + const auto updateMissions = [this, self](Entity* player) { + auto* missionComponent = player->GetComponent(); + if (!missionComponent) return; - auto* activator = Game::entityManager->GetEntity(activaterID); - - // TODO: Missions - if (activator != nullptr) { - auto* missionComponent = activator->GetComponent(); - - if (missionComponent != nullptr) { - for (const auto missionID : m_MissionsToUpdate) { - missionComponent->ForceProgressValue(missionID, 1, self->GetLOT()); - } + for (const auto missionID : m_MissionsToUpdate) { + missionComponent->ForceProgressValue(missionID, 1, self->GetLOT()); } + }; + + // The player who broke the drill gets credit, and so does the player who started it if that was someone else. + updateMissions(attacker); + + const auto activaterID = self->GetVar(u"activaterID"); + if (activaterID != LWOOBJID_EMPTY && activaterID != attacker->GetObjectID()) { + auto* activator = Game::entityManager->GetEntity(activaterID); + if (activator) updateMissions(activator); } self->Smash(attacker->GetObjectID(), eKillType::SILENT);