diff --git a/doc/script_commands.txt b/doc/script_commands.txt index 75617d420..10ec3bbf2 100644 --- a/doc/script_commands.txt +++ b/doc/script_commands.txt @@ -282,3 +282,7 @@ Where "A -> B" means that the command is executed from A with B as target. 33 SCRIPT_COMMAND_XP_USER source or target with Player * datalong=bool 0=off, 1=on + +34 SCRIPT_COMMAND_TERMINATE_COND * datalong = condition_id, datalong2 = fail-quest (if provided this quest will be failed for a player) + * !(data_flags & SCRIPT_FLAG_COMMAND_ADDITIONAL): terminate when condition is true + data_flags & SCRIPT_FLAG_COMMAND_ADDITIONAL: terminate when condition is false diff --git a/src/game/ObjectMgr.cpp b/src/game/ObjectMgr.cpp index b74a2e24b..8f706cf10 100755 --- a/src/game/ObjectMgr.cpp +++ b/src/game/ObjectMgr.cpp @@ -7827,7 +7827,8 @@ char const* conditionSourceToStr[] = "hardcoded", "vendor's item check", "spell_area check", - "npc_spellclick_spells check" + "npc_spellclick_spells check", + "DBScript engine" }; // Checks if player meets the condition diff --git a/src/game/ObjectMgr.h b/src/game/ObjectMgr.h index b0e862509..36767d014 100755 --- a/src/game/ObjectMgr.h +++ b/src/game/ObjectMgr.h @@ -421,6 +421,7 @@ enum ConditionSource // From where was th CONDITION_FROM_VENDOR = 6, // Used to check a condition from a vendor CONDITION_FROM_SPELL_AREA = 7, // Used to check a condition from spell_area table CONDITION_FROM_SPELLCLICK = 8, // Used to check a condition from npc_spellclick_spells table + CONDTION_FROM_DBSCRIPTS = 9, // Used to check a condition from DB Scripts Engine }; class PlayerCondition diff --git a/src/game/ScriptMgr.cpp b/src/game/ScriptMgr.cpp index 0f3969ae2..77206c35d 100644 --- a/src/game/ScriptMgr.cpp +++ b/src/game/ScriptMgr.cpp @@ -645,6 +645,20 @@ void ScriptMgr::LoadScripts(ScriptMapMapName& scripts, const char* tablename) break; case SCRIPT_COMMAND_XP_USER: // 33 break; + case SCRIPT_COMMAND_TERMINATE_COND: // 34 + { + if (!sConditionStorage.LookupEntry(tmp.terminateCond.conditionId)) + { + sLog.outErrorDb("Table `%s` has datalong = %u in SCRIPT_COMMAND_TERMINATE_COND for script id %u, but this condition_id does not exist.", tablename, tmp.terminateCond.conditionId, tmp.id); + continue; + } + if (tmp.terminateCond.failQuest && !sObjectMgr.GetQuestTemplate(tmp.terminateCond.failQuest)) + { + sLog.outErrorDb("Table `%s` has datalong2 = %u in SCRIPT_COMMAND_TERMINATE_COND for script id %u, but this questId does not exist.", tablename, tmp.terminateCond.failQuest, tmp.id); + continue; + } + break; + } default: { sLog.outErrorDb("Table `%s` unknown command %u, skipping.", tablename, tmp.command); @@ -1704,6 +1718,45 @@ bool ScriptAction::HandleScriptStep() pPlayer->RemoveFlag(PLAYER_FLAGS, PLAYER_FLAGS_XP_USER_DISABLED); break; } + case SCRIPT_COMMAND_TERMINATE_COND: + { + Player* player = NULL; + WorldObject* second = pSource; + // First case: target is player + if (pTarget && pTarget->GetTypeId() == TYPEID_PLAYER) + player = static_cast(pTarget); + // Second case: source is player + else if (pSource && pSource->GetTypeId() == TYPEID_PLAYER) + { + player = static_cast(pSource); + second = pTarget; + } + + bool terminateResult; + if (m_script->data_flags & SCRIPT_FLAG_COMMAND_ADDITIONAL) + terminateResult = !sObjectMgr.IsPlayerMeetToCondition(m_script->terminateCond.conditionId, player, m_map, second, CONDTION_FROM_DBSCRIPTS); + else + terminateResult = sObjectMgr.IsPlayerMeetToCondition(m_script->terminateCond.conditionId, player, m_map, second, CONDTION_FROM_DBSCRIPTS); + + if (terminateResult && m_script->terminateCond.failQuest && player) + { + if (Group* group = player->GetGroup()) + { + for (GroupReference* groupRef = group->GetFirstMember(); groupRef != NULL; groupRef = groupRef->next()) + { + Player* member = groupRef->getSource(); + if (member->GetQuestStatus(m_script->terminateCond.failQuest) == QUEST_STATUS_INCOMPLETE) + member->FailQuest(m_script->terminateCond.failQuest); + } + } + else + { + if (player->GetQuestStatus(m_script->terminateCond.failQuest) == QUEST_STATUS_INCOMPLETE) + player->FailQuest(m_script->terminateCond.failQuest); + } + } + return terminateResult; + } default: sLog.outError(" DB-SCRIPTS: Process table `%s` id %u, command %u unknown command used.", m_table, m_script->id, m_script->command); break; diff --git a/src/game/ScriptMgr.h b/src/game/ScriptMgr.h index 1ff9dc2a7..635434c34 100644 --- a/src/game/ScriptMgr.h +++ b/src/game/ScriptMgr.h @@ -99,7 +99,8 @@ enum ScriptCommand // resSource, resTar SCRIPT_COMMAND_PAUSE_WAYPOINTS = 32, // resSource = Creature // datalong = 0: unpause waypoint 1: pause waypoint SCRIPT_COMMAND_XP_USER = 33, // source or target with Player, datalong = bool (0=off, 1=on) - + SCRIPT_COMMAND_TERMINATE_COND = 34, // datalong = condition_id, datalong2 = if != 0 then quest_id of quest that will be failed for player's group if the script is terminated + // data_flags & SCRIPT_FLAG_COMMAND_ADDITIONAL terminate when condition is false ELSE terminate when condition is true }; #define MAX_TEXT_ID 4 // used for SCRIPT_COMMAND_TALK @@ -321,6 +322,12 @@ struct ScriptInfo uint32 empty; // datalong2 } xpDisabled; + struct // SCRIPT_COMMAND_TERMINATE_COND (34) + { + uint32 conditionId; // datalong + uint32 failQuest; // datalong2 + } terminateCond; + struct { uint32 data[2]; @@ -380,6 +387,7 @@ struct ScriptInfo case SCRIPT_COMMAND_MORPH_TO_ENTRY_OR_MODEL: case SCRIPT_COMMAND_MOUNT_TO_ENTRY_OR_MODEL: case SCRIPT_COMMAND_TERMINATE_SCRIPT: + case SCRIPT_COMMAND_TERMINATE_COND: return true; default: return false; diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index f5d00b7ca..08b39daff 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "12606" + #define REVISION_NR "12607" #endif // __REVISION_NR_H__