diff --git a/src/server/game/AI/SmartScripts/SmartScript.cpp b/src/server/game/AI/SmartScripts/SmartScript.cpp index e5d77ca4fffccf..2502c5c6926c82 100644 --- a/src/server/game/AI/SmartScripts/SmartScript.cpp +++ b/src/server/game/AI/SmartScripts/SmartScript.cpp @@ -3282,6 +3282,16 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u sWorldState->HandleExternalEvent(static_cast(e.action.worldStateScript.eventId), e.action.worldStateScript.param); break; } + case SMART_ACTION_DISABLE_REWARD: + { + for (WorldObject* target : targets) + if (IsCreature(target)) + { + target->ToCreature()->SetReputationRewardDisabled(static_cast(e.action.reward.reputation)); + target->ToCreature()->SetLootRewardDisabled(static_cast(e.action.reward.loot)); + } + break; + } default: LOG_ERROR("sql.sql", "SmartScript::ProcessAction: Entry {} SourceType {}, Event {}, Unhandled Action type {}", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType()); break; diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp index f79ed9e14b72d4..834e48007d0453 100644 --- a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp +++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp @@ -860,6 +860,7 @@ bool SmartAIMgr::CheckUnusedActionParams(SmartScriptHolder const& e) case SMART_ACTION_MOVEMENT_PAUSE: return sizeof(SmartAction::move); case SMART_ACTION_MOVEMENT_RESUME: return sizeof(SmartAction::move); case SMART_ACTION_WORLD_SCRIPT: return sizeof(SmartAction::worldStateScript); + case SMART_ACTION_DISABLE_REWARD: return sizeof(SmartAction::reward); default: LOG_WARN("sql.sql", "SmartAIMgr: entryorguid {} source_type {} id {} action_type {} is using an action with no unused params specified in SmartAIMgr::CheckUnusedActionParams(), please report this.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType()); @@ -1894,6 +1895,9 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e) return IsSAIBoolValid(e, e.action.setHealthRegen.regenHealth); case SMART_ACTION_CALL_TIMED_ACTIONLIST: return IsSAIBoolValid(e, e.action.timedActionList.allowOverride); + case SMART_ACTION_DISABLE_REWARD: + return IsSAIBoolValid(e, e.action.reward.reputation) && + IsSAIBoolValid(e, e.action.reward.loot); case SMART_ACTION_FLEE_FOR_ASSIST: case SMART_ACTION_MOVE_TO_POS: case SMART_ACTION_EVADE: diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.h b/src/server/game/AI/SmartScripts/SmartScriptMgr.h index 159f8cb875fe71..994129ecf73944 100644 --- a/src/server/game/AI/SmartScripts/SmartScriptMgr.h +++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.h @@ -738,8 +738,9 @@ enum SMART_ACTION SMART_ACTION_MOVEMENT_PAUSE = 235, // timer SMART_ACTION_MOVEMENT_RESUME = 236, // timerOverride SMART_ACTION_WORLD_SCRIPT = 237, // eventId, param + SMART_ACTION_DISABLE_REWARD = 238, // reputation 0/1, loot 0/1 - SMART_ACTION_AC_END = 238, // placeholder + SMART_ACTION_AC_END = 239, // placeholder }; enum class SmartActionSummonCreatureFlags @@ -1501,6 +1502,12 @@ struct SmartAction uint32 param5; uint32 param6; } raw; + + struct + { + SAIBool reputation; + SAIBool loot; + } reward; }; }; diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp index 7abedcae7e02ea..cf197c7b232f04 100644 --- a/src/server/game/Entities/Creature/Creature.cpp +++ b/src/server/game/Entities/Creature/Creature.cpp @@ -286,7 +286,9 @@ Creature::Creature(bool isWorldObject): Unit(isWorldObject), MovableMapObject(), m_ProhibitSchoolTime[i] = 0; m_CreatureSpellCooldowns.clear(); - DisableReputationGain = false; + + DisableReputationReward = false; + DisableLootReward = false; m_SightDistance = sWorld->getFloatConfig(CONFIG_SIGHT_MONSTER); m_CombatDistance = 0.0f; diff --git a/src/server/game/Entities/Creature/Creature.h b/src/server/game/Entities/Creature/Creature.h index 17f69f801e8bbc..5ece4d5be54a4f 100644 --- a/src/server/game/Entities/Creature/Creature.h +++ b/src/server/game/Entities/Creature/Creature.h @@ -356,8 +356,10 @@ class Creature : public Unit, public GridObject, public MovableMapObje Unit* SelectVictim(); - void SetDisableReputationGain(bool disable) { DisableReputationGain = disable; } - [[nodiscard]] bool IsReputationGainDisabled() const { return DisableReputationGain; } + void SetReputationRewardDisabled(bool disable) { DisableReputationReward = disable; } + [[nodiscard]] bool IsReputationRewardDisabled() const { return DisableReputationReward; } + void SetLootRewardDisabled(bool disable) { DisableLootReward = disable; } + [[nodiscard]] bool IsLootRewardDisabled() const { return DisableLootReward; } [[nodiscard]] bool IsDamageEnoughForLootingAndReward() const; void LowerPlayerDamageReq(uint32 unDamage, bool damagedByPlayer = true); void ResetPlayerDamageReq(); @@ -475,7 +477,8 @@ class Creature : public Unit, public GridObject, public MovableMapObje Position m_homePosition; Position m_transportHomePosition; - bool DisableReputationGain; + bool DisableReputationReward; + bool DisableLootReward; CreatureTemplate const* m_creatureInfo; // in difficulty mode > 0 can different from sObjectMgr->GetCreatureTemplate(GetEntry()) CreatureData const* m_creatureData; diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index dfed1d21618d75..8d4efad95ac005 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -5982,7 +5982,7 @@ void Player::RewardReputation(Unit* victim) if (!victim || victim->IsPlayer()) return; - if (victim->ToCreature()->IsReputationGainDisabled()) + if (victim->ToCreature()->IsReputationRewardDisabled()) return; ReputationOnKillEntry const* Rep = sObjectMgr->GetReputationOnKilEntry(victim->ToCreature()->GetCreatureTemplate()->Entry); diff --git a/src/server/game/Entities/Player/PlayerStorage.cpp b/src/server/game/Entities/Player/PlayerStorage.cpp index 0cf697bca76968..2393dc0d2446d5 100644 --- a/src/server/game/Entities/Player/PlayerStorage.cpp +++ b/src/server/game/Entities/Player/PlayerStorage.cpp @@ -5619,7 +5619,7 @@ bool Player::LoadFromDB(ObjectGuid playerGuid, CharacterDatabaseQueryHolder cons bool Player::isAllowedToLoot(Creature const* creature) { - if (!creature->isDead() || !creature->IsDamageEnoughForLootingAndReward()) + if (!creature->isDead() || !creature->IsDamageEnoughForLootingAndReward() || creature->IsLootRewardDisabled()) return false; if (HasPendingBind()) diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 25f1c289377daf..42a80602fd7d2b 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -17748,7 +17748,7 @@ void Unit::Kill(Unit* killer, Unit* victim, bool durabilityLoss, WeaponAttackTyp bool isRewardAllowed = true; if (creature) { - isRewardAllowed = creature->IsDamageEnoughForLootingAndReward(); + isRewardAllowed = (creature->IsDamageEnoughForLootingAndReward() && !creature->IsLootRewardDisabled()); if (!isRewardAllowed) creature->SetLootRecipient(nullptr); } diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/instance_hyjal.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/instance_hyjal.cpp index c0c95f6c780bb1..2c6a3d06b9a245 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/instance_hyjal.cpp +++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/instance_hyjal.cpp @@ -191,7 +191,7 @@ class instance_hyjal : public InstanceMapScript if (creature->IsSummon() && _bossWave != TO_BE_DECIDED) { if (_currentWave == 0) - creature->SetDisableReputationGain(true); + creature->SetReputationRewardDisabled(true); DoUpdateWorldState(WORLD_STATE_ENEMYCOUNT, ++trash); // Update the instance wave count on new trash spawn _encounterNPCs.insert(creature->GetGUID()); // Used for despawning on wipe }