diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/server/game/AI/SmartScripts/SmartScript.cpp | 70 | ||||
-rw-r--r-- | src/server/game/AI/SmartScripts/SmartScriptMgr.cpp | 37 | ||||
-rw-r--r-- | src/server/game/AI/SmartScripts/SmartScriptMgr.h | 7 | ||||
-rw-r--r-- | src/server/game/Spells/SpellEffects.cpp | 16 |
4 files changed, 61 insertions, 69 deletions
diff --git a/src/server/game/AI/SmartScripts/SmartScript.cpp b/src/server/game/AI/SmartScripts/SmartScript.cpp index ad0e71c2c83..f1294299752 100644 --- a/src/server/game/AI/SmartScripts/SmartScript.cpp +++ b/src/server/game/AI/SmartScripts/SmartScript.cpp @@ -575,27 +575,6 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u } break; } - case SMART_ACTION_CALL_AREAEXPLOREDOREVENTHAPPENS: - { - for (WorldObject* target : targets) - { - // Special handling for vehicles - if (IsUnit(target)) - if (Vehicle* vehicle = target->ToUnit()->GetVehicleKit()) - for (std::pair<int8 const, VehicleSeat>& seat : vehicle->Seats) - if (Player* player = ObjectAccessor::GetPlayer(*target, seat.second.Passenger.Guid)) - player->AreaExploredOrEventHappens(e.action.quest.quest); - - if (IsPlayer(target)) - { - target->ToPlayer()->AreaExploredOrEventHappens(e.action.quest.quest); - - TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_CALL_AREAEXPLOREDOREVENTHAPPENS: Player {} credited quest {}", - target->GetGUID().ToString(), e.action.quest.quest); - } - } - break; - } case SMART_ACTION_CAST: { if (targets.empty()) @@ -869,27 +848,6 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_FLEE_FOR_ASSIST: Creature {} DoFleeToGetAssistance", me->GetGUID().ToString()); break; } - case SMART_ACTION_CALL_GROUPEVENTHAPPENS: - { - if (!unit) - break; - - // If invoker was pet or charm - Player* playerCharmed = unit->GetCharmerOrOwnerPlayerOrPlayerItself(); - if (playerCharmed && GetBaseObject()) - { - playerCharmed->GroupEventHappens(e.action.quest.quest, GetBaseObject()); - TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction: SMART_ACTION_CALL_GROUPEVENTHAPPENS: Player {}, group credit for quest {}", - unit->GetGUID().ToString(), e.action.quest.quest); - } - - // Special handling for vehicles - if (Vehicle* vehicle = unit->GetVehicleKit()) - for (std::pair<int8 const, VehicleSeat>& seat : vehicle->Seats) - if (Player* passenger = ObjectAccessor::GetPlayer(*unit, seat.second.Passenger.Guid)) - passenger->GroupEventHappens(e.action.quest.quest, GetBaseObject()); - break; - } case SMART_ACTION_COMBAT_STOP: { if (!me) @@ -2637,6 +2595,34 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u break; } + case SMART_ACTION_COMPLETE_QUEST: + { + uint32 questId = e.action.quest.quest; + Quest const* quest = sObjectMgr->GetQuestTemplate(questId); + if (!quest) + break; + + for (WorldObject* target : targets) + { + Player* player = Object::ToPlayer(target); + if (!player) + continue; + + QuestStatus questStatus = player->GetQuestStatus(questId); + if (questStatus == QUEST_STATUS_REWARDED) + continue; + + if (quest->HasFlag(QUEST_FLAGS_COMPLETION_EVENT) || quest->HasFlag(QUEST_FLAGS_COMPLETION_AREA_TRIGGER)) + { + if (questStatus == QUEST_STATUS_INCOMPLETE) + player->AreaExploredOrEventHappens(questId); + } + else if (quest->HasFlag(QUEST_FLAGS_TRACKING_EVENT)) // Check if the quest is used as a serverside flag + player->CompleteQuest(questId); + } + + break; + } default: TC_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 c9e1cb072fe..49b61246894 100644 --- a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp +++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp @@ -340,7 +340,6 @@ void SmartAIMgr::LoadSmartAIFromDB() } break; case SMART_EVENT_VICTIM_CASTING: - case SMART_EVENT_IS_BEHIND_TARGET: if (temp.event.minMaxRepeat.min == 0 && temp.event.minMaxRepeat.max == 0 && !(temp.event.event_flags & SMART_EVENT_FLAG_NOT_REPEATABLE) && temp.source_type != SMART_SCRIPT_TYPE_TIMED_ACTIONLIST) { temp.event.event_flags |= SMART_EVENT_FLAG_NOT_REPEATABLE; @@ -910,7 +909,6 @@ bool SmartAIMgr::CheckUnusedActionParams(SmartScriptHolder const& e) case SMART_ACTION_SUMMON_CREATURE: return sizeof(SmartAction::summonCreature); case SMART_ACTION_THREAT_SINGLE_PCT: return sizeof(SmartAction::threatPCT); case SMART_ACTION_THREAT_ALL_PCT: return sizeof(SmartAction::threatPCT); - case SMART_ACTION_CALL_AREAEXPLOREDOREVENTHAPPENS: return sizeof(SmartAction::quest); case SMART_ACTION_SET_INGAME_PHASE_GROUP: return sizeof(SmartAction::ingamePhaseGroup); case SMART_ACTION_SET_EMOTE_STATE: return sizeof(SmartAction::emote); case SMART_ACTION_AUTO_ATTACK: return sizeof(SmartAction::autoAttack); @@ -919,7 +917,6 @@ bool SmartAIMgr::CheckUnusedActionParams(SmartScriptHolder const& e) case SMART_ACTION_INC_EVENT_PHASE: return sizeof(SmartAction::incEventPhase); case SMART_ACTION_EVADE: return sizeof(SmartAction::evade); case SMART_ACTION_FLEE_FOR_ASSIST: return sizeof(SmartAction::fleeAssist); - case SMART_ACTION_CALL_GROUPEVENTHAPPENS: return sizeof(SmartAction::quest); case SMART_ACTION_COMBAT_STOP: return NO_PARAMS; case SMART_ACTION_REMOVEAURASFROMSPELL: return sizeof(SmartAction::removeAura); case SMART_ACTION_FOLLOW: return sizeof(SmartAction::follow); @@ -1028,6 +1025,7 @@ bool SmartAIMgr::CheckUnusedActionParams(SmartScriptHolder const& e) case SMART_ACTION_BECOME_PERSONAL_CLONE_FOR_PLAYER: return sizeof(SmartAction::becomePersonalClone); case SMART_ACTION_TRIGGER_GAME_EVENT: return sizeof(SmartAction::triggerGameEvent); case SMART_ACTION_DO_ACTION: return sizeof(SmartAction::doAction); + case SMART_ACTION_COMPLETE_QUEST: return sizeof(SmartAction::quest); default: TC_LOG_WARN("sql.sql", "SmartAIMgr: Entry {} SourceType {} Event {} Action {} is using an action with no unused params specified in SmartAIMgr::CheckUnusedActionParams(), please report this.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType()); @@ -1792,22 +1790,6 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e) return false; } break; - case SMART_ACTION_CALL_AREAEXPLOREDOREVENTHAPPENS: - case SMART_ACTION_CALL_GROUPEVENTHAPPENS: - if (Quest const* qid = sObjectMgr->GetQuestTemplate(e.action.quest.quest)) - { - if (!qid->HasFlag(QUEST_FLAGS_COMPLETION_EVENT) && !qid->HasFlag(QUEST_FLAGS_COMPLETION_AREA_TRIGGER)) - { - TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry {} SourceType {} Event {} Action {} Flags for Quest entry {} does not include QUEST_FLAGS_COMPLETION_EVENT or QUEST_FLAGS_COMPLETION_AREA_TRIGGER, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), e.action.quest.quest); - return false; - } - } - else - { - TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry {} SourceType {} Event {} Action {} uses non-existent Quest entry {}, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), e.action.quest.quest); - return false; - } - break; case SMART_ACTION_SET_EVENT_PHASE: if (e.action.setEventPhase.phase >= SMART_EVENT_PHASE_MAX) { @@ -2465,7 +2447,24 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e) TC_SAI_IS_BOOLEAN_VALID(e, e.action.triggerGameEvent.useSaiTargetAsGameEventSource); break; } + case SMART_ACTION_COMPLETE_QUEST: + if (Quest const* quest = sObjectMgr->GetQuestTemplate(e.action.quest.quest)) + { + if (!quest->HasFlag(QUEST_FLAGS_COMPLETION_EVENT) && !quest->HasFlag(QUEST_FLAGS_COMPLETION_AREA_TRIGGER) && !quest->HasFlag(QUEST_FLAGS_TRACKING_EVENT)) + { + TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry {} SourceType {} Event {} Action {} Flags for Quest entry {} does not include QUEST_FLAGS_COMPLETION_EVENT or QUEST_FLAGS_COMPLETION_AREA_TRIGGER or QUEST_FLAGS_TRACKING_EVENT, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), e.action.quest.quest); + return false; + } + } + else + { + TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry {} SourceType {} Event {} Action {} uses non-existent Quest entry {}, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), e.action.quest.quest); + return false; + } + break; // Unused + case SMART_ACTION_CALL_AREAEXPLOREDOREVENTHAPPENS: + case SMART_ACTION_CALL_GROUPEVENTHAPPENS: case SMART_ACTION_SET_UNIT_FLAG: case SMART_ACTION_REMOVE_UNIT_FLAG: case SMART_ACTION_INSTALL_AI_TEMPLATE: diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.h b/src/server/game/AI/SmartScripts/SmartScriptMgr.h index 50b8ade0fef..23c449ab34e 100644 --- a/src/server/game/AI/SmartScripts/SmartScriptMgr.h +++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.h @@ -472,7 +472,7 @@ enum SMART_ACTION SMART_ACTION_SUMMON_CREATURE = 12, // CreatureID, summonType, duration in ms, attackInvoker, flags(SmartActionSummonCreatureFlags) SMART_ACTION_THREAT_SINGLE_PCT = 13, // Threat% SMART_ACTION_THREAT_ALL_PCT = 14, // Threat% - SMART_ACTION_CALL_AREAEXPLOREDOREVENTHAPPENS = 15, // QuestID + SMART_ACTION_CALL_AREAEXPLOREDOREVENTHAPPENS = 15, // UNUSED, DO NOT REUSE SMART_ACTION_SET_INGAME_PHASE_GROUP = 16, // phaseGroupId, apply SMART_ACTION_SET_EMOTE_STATE = 17, // emoteID SMART_ACTION_SET_UNIT_FLAG = 18, // UNUSED, DO NOT REUSE @@ -483,7 +483,7 @@ enum SMART_ACTION SMART_ACTION_INC_EVENT_PHASE = 23, // Value (may be negative to decrement phase, should not be 0) SMART_ACTION_EVADE = 24, // toRespawnPosition (0 = Move to RespawnPosition, 1 = Move to last stored home position) SMART_ACTION_FLEE_FOR_ASSIST = 25, // With Emote - SMART_ACTION_CALL_GROUPEVENTHAPPENS = 26, // QuestID + SMART_ACTION_CALL_GROUPEVENTHAPPENS = 26, // UNUSED, DO NOT REUSE SMART_ACTION_COMBAT_STOP = 27, // SMART_ACTION_REMOVEAURASFROMSPELL = 28, // Spellid (0 removes all auras), charges (0 removes aura) SMART_ACTION_FOLLOW = 29, // Distance (0 = default), Angle (0 = default), EndCreatureEntry, credit, creditType (0monsterkill, 1event) @@ -609,7 +609,8 @@ enum SMART_ACTION SMART_ACTION_BECOME_PERSONAL_CLONE_FOR_PLAYER = 149, // summonType 1-8, duration in ms SMART_ACTION_TRIGGER_GAME_EVENT = 150, // eventId, useSaiTargetAsGameEventSource SMART_ACTION_DO_ACTION = 151, // actionId - SMART_ACTION_END = 152 + SMART_ACTION_COMPLETE_QUEST = 152, // QuestId. Regular quests with objectives can't be completed with this action (only quests with QUEST_FLAGS_COMPLETION_EVENT, QUEST_FLAGS_COMPLETION_AREA_TRIGGER or QUEST_FLAGS_TRACKING_EVENT) + SMART_ACTION_END = 153 }; enum class SmartActionSummonCreatureFlags diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp index 54d36d7f24e..c74646f42c0 100644 --- a/src/server/game/Spells/SpellEffects.cpp +++ b/src/server/game/Spells/SpellEffects.cpp @@ -3690,11 +3690,17 @@ void Spell::EffectQuestComplete() if (!quest) return; - uint16 logSlot = player->FindQuestSlot(questId); - if (logSlot < MAX_QUEST_LOG_SIZE) - player->AreaExploredOrEventHappens(questId); - else if (quest->HasFlag(QUEST_FLAGS_TRACKING_EVENT)) // Check if the quest is used as a serverside flag. - player->SetRewardedQuest(questId); // If so, set status to rewarded without broadcasting it to client. + QuestStatus questStatus = player->GetQuestStatus(questId); + if (questStatus == QUEST_STATUS_REWARDED) + return; + + if (quest->HasFlag(QUEST_FLAGS_COMPLETION_EVENT) || quest->HasFlag(QUEST_FLAGS_COMPLETION_AREA_TRIGGER)) + { + if (questStatus == QUEST_STATUS_INCOMPLETE) + player->AreaExploredOrEventHappens(questId); + } + else if (quest->HasFlag(QUEST_FLAGS_TRACKING_EVENT)) // Check if the quest is used as a serverside flag + player->CompleteQuest(questId); } } |