aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CONTRIBUTING.md2
-rw-r--r--issue_template.md2
-rw-r--r--sql/base/auth_database.sql6
-rw-r--r--sql/updates/auth/3.3.5/2016_05_11_00_auth.sql6
-rw-r--r--sql/updates/world/3.3.5/2016_04_25_02_world.sql48
-rw-r--r--sql/updates/world/3.3.5/2016_04_25_03_world.sql47
-rw-r--r--sql/updates/world/3.3.5/2016_04_26_00_world.sql9
-rw-r--r--sql/updates/world/3.3.5/2016_04_26_01_world.sql57
-rw-r--r--sql/updates/world/3.3.5/2016_04_26_02_world.sql16
-rw-r--r--sql/updates/world/3.3.5/2016_04_26_03_world.sql99
-rw-r--r--sql/updates/world/3.3.5/2016_04_28_00_world.sql3
-rw-r--r--sql/updates/world/3.3.5/2016_04_29_00_world.sql55
-rw-r--r--sql/updates/world/3.3.5/2016_04_29_01_world.sql5
-rw-r--r--sql/updates/world/3.3.5/2016_05_01_00_world.sql1
-rw-r--r--sql/updates/world/3.3.5/2016_05_01_01_world.sql68
-rw-r--r--sql/updates/world/3.3.5/2016_05_02_00_world.sql14
-rw-r--r--sql/updates/world/3.3.5/2016_05_02_01_world.sql18
-rw-r--r--sql/updates/world/3.3.5/2016_05_04_00_world.sql1
-rw-r--r--sql/updates/world/3.3.5/2016_05_04_01_world.sql69
-rw-r--r--sql/updates/world/3.3.5/2016_05_04_02_world.sql2
-rw-r--r--sql/updates/world/3.3.5/2016_05_05_00_world.sql13
-rw-r--r--sql/updates/world/3.3.5/2016_05_05_01_world.sql71
-rw-r--r--sql/updates/world/3.3.5/2016_05_07_00_world.sql2
-rw-r--r--sql/updates/world/3.3.5/2016_05_07_01_world.sql31
-rw-r--r--sql/updates/world/3.3.5/2016_05_08_00_world.sql11
-rw-r--r--sql/updates/world/3.3.5/2016_05_09_00_world.sql2
-rw-r--r--sql/updates/world/3.3.5/2016_05_09_01_world.sql21
-rw-r--r--sql/updates/world/3.3.5/2016_05_09_02_world.sql41
-rw-r--r--sql/updates/world/3.3.5/2016_05_09_03_world.sql3
-rw-r--r--sql/updates/world/3.3.5/2016_05_09_04_world.sql41
-rw-r--r--sql/updates/world/3.3.5/2016_05_11_00_world.sql33
-rw-r--r--sql/updates/world/3.3.5/2016_05_11_01_world.sql16
-rw-r--r--src/common/Utilities/StartProcess.cpp4
-rw-r--r--src/common/Utilities/Timer.h4
-rw-r--r--src/server/authserver/Server/AuthSession.h2
-rw-r--r--src/server/authserver/authserver.conf.dist1
-rw-r--r--src/server/database/Database/DatabaseWorkerPool.h6
-rw-r--r--src/server/database/Database/QueryCallback.h (renamed from src/common/Threading/Callback.h)6
-rw-r--r--src/server/game/AI/CoreAI/CombatAI.cpp2
-rw-r--r--src/server/game/AI/CoreAI/PassiveAI.cpp6
-rw-r--r--src/server/game/AI/CoreAI/PassiveAI.h2
-rw-r--r--src/server/game/AI/CoreAI/PetAI.cpp6
-rw-r--r--src/server/game/AI/CoreAI/PetAI.h2
-rw-r--r--src/server/game/AI/CoreAI/UnitAI.h1
-rw-r--r--src/server/game/AI/CreatureAI.cpp33
-rw-r--r--src/server/game/AI/CreatureAI.h5
-rw-r--r--src/server/game/AI/ScriptedAI/ScriptedCreature.cpp60
-rw-r--r--src/server/game/AI/ScriptedAI/ScriptedCreature.h4
-rw-r--r--src/server/game/AI/SmartScripts/SmartAI.cpp11
-rw-r--r--src/server/game/Accounts/RBAC.h4
-rw-r--r--src/server/game/Achievements/AchievementMgr.cpp11
-rw-r--r--src/server/game/DataStores/DBCEnums.h16
-rw-r--r--src/server/game/DataStores/DBCStores.cpp245
-rw-r--r--src/server/game/DataStores/DBCStores.h4
-rw-r--r--src/server/game/DataStores/DBCStructure.h12
-rw-r--r--src/server/game/DataStores/M2Stores.cpp266
-rw-r--r--src/server/game/DataStores/M2Stores.h36
-rw-r--r--src/server/game/DataStores/M2Structure.h133
-rw-r--r--src/server/game/Entities/Creature/Creature.cpp57
-rw-r--r--src/server/game/Entities/Creature/Creature.h27
-rw-r--r--src/server/game/Entities/GameObject/GameObject.cpp42
-rw-r--r--src/server/game/Entities/Item/ItemEnchantmentMgr.cpp6
-rw-r--r--src/server/game/Entities/Object/Object.cpp4
-rw-r--r--src/server/game/Entities/Object/Object.h12
-rw-r--r--src/server/game/Entities/Player/CinematicMgr.cpp171
-rw-r--r--src/server/game/Entities/Player/CinematicMgr.h60
-rw-r--r--src/server/game/Entities/Player/Player.cpp197
-rw-r--r--src/server/game/Entities/Player/Player.h47
-rw-r--r--src/server/game/Entities/Unit/Unit.cpp26
-rw-r--r--src/server/game/Entities/Unit/Unit.h1
-rw-r--r--src/server/game/Globals/ObjectMgr.cpp6
-rw-r--r--src/server/game/Grids/Notifiers/GridNotifiers.h4
-rw-r--r--src/server/game/Handlers/MiscHandler.cpp18
-rw-r--r--src/server/game/Handlers/QueryHandler.cpp4
-rw-r--r--src/server/game/Miscellaneous/Language.h6
-rwxr-xr-xsrc/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.cpp5
-rw-r--r--src/server/game/Movement/MovementGenerators/RandomMovementGenerator.cpp4
-rw-r--r--src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp11
-rwxr-xr-xsrc/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp2
-rwxr-xr-xsrc/server/game/Movement/MovementGenerators/WaypointMovementGenerator.h2
-rw-r--r--src/server/game/Scripting/ScriptMgr.cpp2
-rw-r--r--src/server/game/Server/Protocol/PacketLog.cpp4
-rw-r--r--src/server/game/Spells/Auras/SpellAuraEffects.cpp5
-rw-r--r--src/server/game/Spells/Auras/SpellAuras.cpp14
-rw-r--r--src/server/game/Spells/Auras/SpellAuras.h2
-rw-r--r--src/server/game/Spells/Spell.cpp29
-rw-r--r--src/server/game/Spells/Spell.h8
-rw-r--r--src/server/game/Spells/SpellEffects.cpp15
-rw-r--r--src/server/game/Spells/SpellHistory.cpp2
-rw-r--r--src/server/game/Spells/SpellMgr.cpp130
-rw-r--r--src/server/game/Spells/SpellMgr.h26
-rw-r--r--src/server/game/World/World.cpp7
-rw-r--r--src/server/game/World/World.h7
-rw-r--r--src/server/scripts/Commands/cs_character.cpp2
-rw-r--r--src/server/scripts/Commands/cs_debug.cpp3
-rw-r--r--src/server/scripts/Commands/cs_misc.cpp2
-rw-r--r--src/server/scripts/Commands/cs_modify.cpp456
-rw-r--r--src/server/scripts/Commands/cs_npc.cpp117
-rw-r--r--src/server/scripts/Commands/cs_pet.cpp59
-rw-r--r--src/server/scripts/Commands/cs_server.cpp78
-rw-r--r--src/server/scripts/EasternKingdoms/ScarletMonastery/boss_headless_horseman.cpp12
-rw-r--r--src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kiljaeden.cpp4
-rw-r--r--src/server/scripts/EasternKingdoms/SunwellPlateau/boss_muru.cpp833
-rw-r--r--src/server/scripts/EasternKingdoms/SunwellPlateau/sunwell_plateau.h3
-rw-r--r--src/server/scripts/Kalimdor/BlackfathomDeeps/instance_blackfathom_deeps.cpp2
-rw-r--r--src/server/scripts/Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/old_hillsbrad.cpp12
-rw-r--r--src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/boss_aeonus.cpp46
-rw-r--r--src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/boss_temporus.cpp52
-rw-r--r--src/server/scripts/Kalimdor/zone_the_barrens.cpp43
-rw-r--r--src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp49
-rw-r--r--src/server/scripts/Northrend/IsleOfConquest/boss_ioc_horde_alliance.cpp132
-rw-r--r--src/server/scripts/Northrend/IsleOfConquest/isle_of_conquest.cpp (renamed from src/server/scripts/Northrend/isle_of_conquest.cpp)0
-rw-r--r--src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp4
-rw-r--r--src/server/scripts/Northrend/northrend_script_loader.cpp6
-rw-r--r--src/server/scripts/Northrend/zone_grizzly_hills.cpp254
-rw-r--r--src/server/scripts/Outland/BlackTemple/boss_illidan.cpp32
-rw-r--r--src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/boss_nethekurse.cpp19
-rw-r--r--src/server/scripts/Outland/TempestKeep/Eye/boss_astromancer.cpp151
-rw-r--r--src/server/scripts/World/go_scripts.cpp2
-rw-r--r--src/server/scripts/World/item_scripts.cpp14
-rw-r--r--src/server/shared/DataStores/DBCStore.h115
-rw-r--r--src/server/worldserver/worldserver.conf.dist15
-rw-r--r--src/tools/map_extractor/System.cpp2
123 files changed, 3327 insertions, 1850 deletions
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 4baa1197965..e7bd9263a70 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -8,7 +8,7 @@ Issues
======
Read [this](http://www.trinitycore.org/f/topic/37-the-trinitycore-issuetracker-and-you/) before creating a ticket.
-If you have problems with TrinityCore instalation, read [this](http://www.trinitycore.org/f/topic/1518-trouble-with-your-trinity-install-readme-1st-faqs/)
+If you have problems with TrinityCore installation, read [this](http://www.trinitycore.org/f/topic/1518-trouble-with-your-trinity-install-readme-1st-faqs/).
Mandatory things when creating a ticket:
========================================
diff --git a/issue_template.md b/issue_template.md
index 8653726f830..1bcd91ae766 100644
--- a/issue_template.md
+++ b/issue_template.md
@@ -18,8 +18,6 @@
**Operating system**:
-**Linking model**: static/dynamic
-
[//]: # (This template is for problem reports, for other type of reports edit it accordingly)
[//]: # (If this is a crash report, include the crashlog with https://gist.github.com/)
diff --git a/sql/base/auth_database.sql b/sql/base/auth_database.sql
index fd47a349f01..b0a120bae63 100644
--- a/sql/base/auth_database.sql
+++ b/sql/base/auth_database.sql
@@ -375,7 +375,7 @@ CREATE TABLE `rbac_linked_permissions` (
LOCK TABLES `rbac_linked_permissions` WRITE;
/*!40000 ALTER TABLE `rbac_linked_permissions` DISABLE KEYS */;
-INSERT INTO `rbac_linked_permissions` VALUES (192,21),(192,42),(192,43),(192,193),(192,196),(192,778),(192,779),(192,780),(192,781),(192,782),(192,783),(192,784),(192,785),(192,786),(192,787),(192,788),(192,789),(192,790),(192,791),(192,792),(192,793),(192,794),(192,795),(192,796),(192,835),(193,48),(193,194),(193,197),(194,1),(194,2),(194,11),(194,13),(194,14),(194,15),(194,16),(194,17),(194,18),(194,19),(194,20),(194,22),(194,23),(194,25),(194,26),(194,27),(194,28),(194,29),(194,30),(194,31),(194,32),(194,33),(194,34),(194,35),(194,36),(194,37),(194,38),(194,39),(194,40),(194,41),(194,44),(194,46),(194,47),(194,51),(194,195),(194,198),(194,632),(194,798),(195,3),(195,4),(195,5),(195,6),(195,24),(195,49),(195,199),(196,200),(196,201),(196,226),(196,227),(196,230),(196,231),(196,233),(196,234),(196,235),(196,238),(196,239),(196,240),(196,241),(196,242),(196,243),(196,244),(196,245),(196,246),(196,247),(196,248),(196,249),(196,250),(196,251),(196,252),(196,253),(196,254),(196,255),(196,256),(196,257),(196,258),(196,259),(196,260),(196,261),(196,262),(196,264),(196,265),(196,266),(196,267),(196,268),(196,269),(196,270),(196,271),(196,272),(196,279),(196,280),(196,283),(196,287),(196,288),(196,289),(196,290),(196,291),(196,292),(196,293),(196,294),(196,295),(196,296),(196,297),(196,298),(196,299),(196,302),(196,303),(196,304),(196,305),(196,306),(196,307),(196,308),(196,309),(196,310),(196,313),(196,314),(196,319),(196,320),(196,321),(196,322),(196,323),(196,324),(196,325),(196,326),(196,327),(196,328),(196,329),(196,330),(196,331),(196,332),(196,333),(196,334),(196,335),(196,336),(196,337),(196,338),(196,339),(196,340),(196,341),(196,342),(196,343),(196,344),(196,345),(196,346),(196,347),(196,348),(196,349),(196,350),(196,351),(196,352),(196,353),(196,354),(196,355),(196,356),(196,357),(196,358),(196,359),(196,360),(196,361),(196,362),(196,363),(196,364),(196,365),(196,366),(196,373),(196,375),(196,400),(196,401),(196,402),(196,403),(196,404),(196,405),(196,406),(196,407),(196,417),(196,418),(196,419),(196,420),(196,421),(196,422),(196,423),(196,424),(196,425),(196,426),(196,427),(196,428),(196,429),(196,434),(196,435),(196,436),(196,437),(196,438),(196,439),(196,440),(196,441),(196,442),(196,443),(196,444),(196,445),(196,446),(196,447),(196,448),(196,449),(196,450),(196,451),(196,452),(196,453),(196,454),(196,455),(196,456),(196,457),(196,458),(196,459),(196,461),(196,463),(196,464),(196,465),(196,472),(196,473),(196,474),(196,475),(196,476),(196,477),(196,478),(196,488),(196,489),(196,491),(196,492),(196,493),(196,495),(196,497),(196,498),(196,499),(196,500),(196,502),(196,503),(196,505),(196,508),(196,511),(196,513),(196,514),(196,516),(196,519),(196,522),(196,523),(196,526),(196,527),(196,529),(196,530),(196,533),(196,535),(196,536),(196,537),(196,538),(196,539),(196,540),(196,541),(196,556),(196,581),(196,582),(196,592),(196,593),(196,596),(196,602),(196,603),(196,604),(196,605),(196,606),(196,607),(196,608),(196,609),(196,610),(196,611),(196,612),(196,613),(196,614),(196,615),(196,616),(196,617),(196,618),(196,619),(196,620),(196,621),(196,622),(196,623),(196,624),(196,625),(196,626),(196,627),(196,628),(196,629),(196,630),(196,631),(196,633),(196,634),(196,635),(196,636),(196,637),(196,638),(196,639),(196,640),(196,641),(196,642),(196,643),(196,644),(196,645),(196,646),(196,647),(196,648),(196,649),(196,650),(196,651),(196,652),(196,653),(196,654),(196,655),(196,656),(196,657),(196,658),(196,659),(196,660),(196,661),(196,662),(196,663),(196,664),(196,665),(196,666),(196,667),(196,668),(196,669),(196,670),(196,671),(196,672),(196,673),(196,674),(196,675),(196,676),(196,677),(196,678),(196,679),(196,680),(196,681),(196,682),(196,683),(196,684),(196,685),(196,686),(196,687),(196,688),(196,689),(196,690),(196,691),(196,692),(196,693),(196,694),(196,695),(196,696),(196,697),(196,698),(196,699),(196,700),(196,701),(196,702),(196,703),(196,704),(196,705),(196,706),(196,707),(196,708),(196,709),(196,710),(196,711),(196,712),(196,713),(196,714),(196,715),(196,716),(196,717),(196,718),(196,719),(196,721),(196,722),(196,723),(196,724),(196,725),(196,726),(196,727),(196,728),(196,729),(196,730),(196,733),(196,734),(196,735),(196,736),(196,738),(196,739),(196,748),(196,753),(196,757),(196,773),(196,777),(196,836),(197,232),(197,236),(197,237),(197,273),(197,274),(197,275),(197,276),(197,277),(197,284),(197,285),(197,286),(197,301),(197,311),(197,387),(197,388),(197,389),(197,390),(197,391),(197,392),(197,393),(197,394),(197,395),(197,396),(197,397),(197,398),(197,399),(197,479),(197,480),(197,481),(197,482),(197,485),(197,486),(197,487),(197,494),(197,506),(197,509),(197,510),(197,517),(197,518),(197,521),(197,542),(197,543),(197,550),(197,558),(197,568),(197,571),(197,572),(197,573),(197,574),(197,575),(197,576),(197,577),(197,578),(197,579),(197,580),(197,583),(197,584),(197,585),(197,586),(197,587),(197,588),(197,589),(197,590),(197,591),(197,594),(197,595),(197,601),(197,743),(197,750),(197,758),(197,761),(197,762),(197,763),(197,764),(197,765),(197,766),(197,767),(197,768),(197,769),(197,770),(197,771),(197,772),(197,774),(198,218),(198,300),(198,312),(198,315),(198,316),(198,317),(198,318),(198,367),(198,368),(198,369),(198,370),(198,371),(198,372),(198,374),(198,376),(198,377),(198,378),(198,379),(198,380),(198,381),(198,382),(198,383),(198,384),(198,385),(198,386),(198,408),(198,409),(198,410),(198,411),(198,412),(198,413),(198,414),(198,415),(198,416),(198,430),(198,431),(198,432),(198,433),(198,462),(198,466),(198,467),(198,468),(198,469),(198,470),(198,471),(198,483),(198,484),(198,490),(198,504),(198,512),(198,515),(198,520),(198,524),(198,528),(198,531),(198,532),(198,544),(198,545),(198,546),(198,547),(198,548),(198,549),(198,551),(198,552),(198,553),(198,554),(198,555),(198,557),(198,559),(198,560),(198,561),(198,562),(198,563),(198,564),(198,565),(198,566),(198,567),(198,569),(198,570),(198,597),(198,598),(198,599),(198,600),(198,737),(198,740),(198,741),(198,742),(198,744),(198,745),(198,746),(198,747),(198,749),(198,751),(198,752),(198,754),(198,755),(198,756),(198,759),(198,760),(199,217),(199,221),(199,222),(199,223),(199,225),(199,263),(199,496),(199,501),(199,507),(199,525),(199,534),(199,797);
+INSERT INTO `rbac_linked_permissions` VALUES (192,21),(192,42),(192,43),(192,193),(192,196),(192,778),(192,779),(192,780),(192,781),(192,782),(192,783),(192,784),(192,785),(192,786),(192,787),(192,788),(192,789),(192,790),(192,791),(192,792),(192,793),(192,794),(192,795),(192,796),(192,835),(193,48),(193,194),(193,197),(194,1),(194,2),(194,11),(194,13),(194,14),(194,15),(194,16),(194,17),(194,18),(194,19),(194,20),(194,22),(194,23),(194,25),(194,26),(194,27),(194,28),(194,29),(194,30),(194,31),(194,32),(194,33),(194,34),(194,35),(194,36),(194,37),(194,38),(194,39),(194,40),(194,41),(194,44),(194,46),(194,47),(194,51),(194,195),(194,198),(194,632),(194,798),(195,3),(195,4),(195,5),(195,6),(195,24),(195,49),(195,199),(196,200),(196,201),(196,226),(196,227),(196,230),(196,231),(196,233),(196,234),(196,235),(196,238),(196,239),(196,240),(196,241),(196,242),(196,243),(196,244),(196,245),(196,246),(196,247),(196,248),(196,249),(196,250),(196,251),(196,252),(196,253),(196,254),(196,255),(196,256),(196,257),(196,258),(196,259),(196,260),(196,261),(196,262),(196,264),(196,265),(196,266),(196,267),(196,268),(196,269),(196,270),(196,271),(196,272),(196,279),(196,280),(196,283),(196,287),(196,288),(196,289),(196,290),(196,291),(196,292),(196,293),(196,294),(196,295),(196,296),(196,297),(196,298),(196,299),(196,302),(196,303),(196,304),(196,305),(196,306),(196,307),(196,308),(196,309),(196,310),(196,313),(196,314),(196,319),(196,320),(196,321),(196,322),(196,323),(196,324),(196,325),(196,326),(196,327),(196,328),(196,329),(196,330),(196,331),(196,332),(196,333),(196,334),(196,335),(196,336),(196,337),(196,338),(196,339),(196,340),(196,341),(196,342),(196,343),(196,344),(196,345),(196,346),(196,347),(196,348),(196,349),(196,350),(196,351),(196,352),(196,353),(196,354),(196,355),(196,356),(196,357),(196,358),(196,359),(196,360),(196,361),(196,362),(196,363),(196,364),(196,365),(196,366),(196,373),(196,375),(196,400),(196,401),(196,402),(196,403),(196,404),(196,405),(196,406),(196,407),(196,417),(196,418),(196,419),(196,420),(196,421),(196,422),(196,423),(196,424),(196,425),(196,426),(196,427),(196,428),(196,429),(196,434),(196,435),(196,436),(196,437),(196,438),(196,439),(196,440),(196,441),(196,442),(196,443),(196,444),(196,445),(196,446),(196,447),(196,448),(196,449),(196,450),(196,451),(196,452),(196,453),(196,454),(196,455),(196,456),(196,457),(196,458),(196,459),(196,461),(196,463),(196,464),(196,465),(196,472),(196,473),(196,474),(196,475),(196,476),(196,477),(196,478),(196,488),(196,489),(196,491),(196,492),(196,493),(196,495),(196,497),(196,498),(196,499),(196,500),(196,502),(196,503),(196,505),(196,508),(196,511),(196,513),(196,514),(196,516),(196,519),(196,522),(196,523),(196,526),(196,527),(196,529),(196,530),(196,533),(196,535),(196,536),(196,537),(196,538),(196,539),(196,540),(196,541),(196,556),(196,581),(196,582),(196,592),(196,593),(196,596),(196,602),(196,603),(196,604),(196,605),(196,606),(196,607),(196,608),(196,609),(196,610),(196,611),(196,612),(196,613),(196,614),(196,615),(196,616),(196,617),(196,618),(196,619),(196,620),(196,621),(196,622),(196,623),(196,624),(196,625),(196,626),(196,627),(196,628),(196,629),(196,630),(196,631),(196,633),(196,634),(196,635),(196,636),(196,637),(196,638),(196,639),(196,640),(196,641),(196,642),(196,643),(196,644),(196,645),(196,646),(196,647),(196,648),(196,649),(196,650),(196,651),(196,652),(196,653),(196,654),(196,655),(196,656),(196,657),(196,658),(196,659),(196,660),(196,661),(196,662),(196,663),(196,664),(196,665),(196,666),(196,667),(196,668),(196,669),(196,670),(196,671),(196,672),(196,673),(196,674),(196,675),(196,676),(196,677),(196,678),(196,679),(196,680),(196,681),(196,682),(196,683),(196,684),(196,685),(196,686),(196,687),(196,688),(196,689),(196,690),(196,691),(196,692),(196,693),(196,694),(196,695),(196,696),(196,697),(196,698),(196,699),(196,700),(196,701),(196,702),(196,703),(196,704),(196,705),(196,706),(196,707),(196,708),(196,709),(196,710),(196,711),(196,712),(196,713),(196,714),(196,715),(196,716),(196,717),(196,718),(196,719),(196,721),(196,722),(196,723),(196,724),(196,725),(196,726),(196,727),(196,728),(196,729),(196,730),(196,733),(196,734),(196,735),(196,736),(196,738),(196,739),(196,748),(196,753),(196,757),(196,773),(196,777),(196,836),(196,837),(196,838),(196,839),(196,840),(197,232),(197,236),(197,237),(197,273),(197,274),(197,275),(197,276),(197,277),(197,284),(197,285),(197,286),(197,301),(197,311),(197,387),(197,388),(197,389),(197,390),(197,391),(197,392),(197,393),(197,394),(197,395),(197,396),(197,397),(197,398),(197,399),(197,479),(197,480),(197,481),(197,482),(197,485),(197,486),(197,487),(197,494),(197,506),(197,509),(197,510),(197,517),(197,518),(197,521),(197,542),(197,543),(197,550),(197,558),(197,568),(197,571),(197,572),(197,573),(197,574),(197,575),(197,576),(197,577),(197,578),(197,579),(197,580),(197,583),(197,584),(197,585),(197,586),(197,587),(197,588),(197,589),(197,590),(197,591),(197,594),(197,595),(197,601),(197,743),(197,750),(197,758),(197,761),(197,762),(197,763),(197,764),(197,765),(197,766),(197,767),(197,768),(197,769),(197,770),(197,771),(197,772),(197,774),(198,218),(198,300),(198,312),(198,315),(198,316),(198,317),(198,318),(198,367),(198,368),(198,369),(198,370),(198,371),(198,372),(198,374),(198,376),(198,377),(198,378),(198,379),(198,380),(198,381),(198,382),(198,383),(198,384),(198,385),(198,386),(198,408),(198,409),(198,410),(198,411),(198,412),(198,413),(198,414),(198,415),(198,416),(198,430),(198,431),(198,432),(198,433),(198,462),(198,466),(198,467),(198,468),(198,469),(198,470),(198,471),(198,483),(198,484),(198,490),(198,504),(198,512),(198,515),(198,520),(198,524),(198,528),(198,531),(198,532),(198,544),(198,545),(198,546),(198,547),(198,548),(198,549),(198,551),(198,552),(198,553),(198,554),(198,555),(198,557),(198,559),(198,560),(198,561),(198,562),(198,563),(198,564),(198,565),(198,566),(198,567),(198,569),(198,570),(198,597),(198,598),(198,599),(198,600),(198,737),(198,740),(198,741),(198,742),(198,744),(198,745),(198,746),(198,747),(198,749),(198,751),(198,752),(198,754),(198,755),(198,756),(198,759),(198,760),(199,217),(199,221),(199,222),(199,223),(199,225),(199,263),(199,496),(199,501),(199,507),(199,525),(199,534),(199,797);
/*!40000 ALTER TABLE `rbac_linked_permissions` ENABLE KEYS */;
UNLOCK TABLES;
@@ -399,7 +399,7 @@ CREATE TABLE `rbac_permissions` (
LOCK TABLES `rbac_permissions` WRITE;
/*!40000 ALTER TABLE `rbac_permissions` DISABLE KEYS */;
-INSERT INTO `rbac_permissions` VALUES (1,'Instant logout'),(2,'Skip Queue'),(3,'Join Normal Battleground'),(4,'Join Random Battleground'),(5,'Join Arenas'),(6,'Join Dungeon Finder'),(11,'Log GM trades'),(13,'Skip Instance required bosses check'),(14,'Skip character creation team mask check'),(15,'Skip character creation class mask check'),(16,'Skip character creation race mask check'),(17,'Skip character creation reserved name check'),(18,'Skip character creation heroic min level check'),(19,'Skip needed requirements to use channel check'),(20,'Skip disable map check'),(21,'Skip reset talents when used more than allowed check'),(22,'Skip spam chat check'),(23,'Skip over-speed ping check'),(24,'Two side faction characters on the same account'),(25,'Allow say chat between factions'),(26,'Allow channel chat between factions'),(27,'Two side mail interaction'),(28,'See two side who list'),(29,'Add friends of other faction'),(30,'Save character without delay with .save command'),(31,'Use params with .unstuck command'),(32,'Can be assigned tickets with .assign ticket command'),(33,'Notify if a command was not found'),(34,'Check if should appear in list using .gm ingame command'),(35,'See all security levels with who command'),(36,'Filter whispers'),(37,'Use staff badge in chat'),(38,'Resurrect with full Health Points'),(39,'Restore saved gm setting states'),(40,'Allows to add a gm to friend list'),(41,'Use Config option START_GM_LEVEL to assign new character level'),(42,'Allows to use CMSG_WORLD_TELEPORT opcode'),(43,'Allows to use CMSG_WHOIS opcode'),(44,'Receive global GM messages/texts'),(45,'Join channels without announce'),(46,'Change channel settings without being channel moderator'),(47,'Enables lower security than target check'),(48,'Enable IP, Last Login and EMail output in pinfo'),(49,'Forces to enter the email for confirmation on password change'),(50,'Allow user to check his own email with .account'),(51,'Allow trading between factions'),(192,'Role: Sec Level Administrator'),(193,'Role: Sec Level Gamemaster'),(194,'Role: Sec Level Moderator'),(195,'Role: Sec Level Player'),(196,'Role: Administrator Commands'),(197,'Role: Gamemaster Commands'),(198,'Role: Moderator Commands'),(199,'Role: Player Commands'),(200,'Command: rbac'),(201,'Command: rbac account'),(202,'Command: rbac account list'),(203,'Command: rbac account grant'),(204,'Command: rbac account deny'),(205,'Command: rbac account revoke'),(206,'Command: rbac list'),(217,'Command: account'),(218,'Command: account addon'),(219,'Command: account create'),(220,'Command: account delete'),(221,'Command: account lock'),(222,'Command: account lock country'),(223,'Command: account lock ip'),(224,'Command: account onlinelist'),(225,'Command: account password'),(226,'Command: account set'),(227,'Command: account set addon'),(228,'Command: account set gmlevel'),(229,'Command: account set password'),(230,'Command: achievement'),(231,'Command: achievement add'),(232,'Command: arena'),(233,'Command: arena captain'),(234,'Command: arena create'),(235,'Command: arena disband'),(236,'Command: arena info'),(237,'Command: arena lookup'),(238,'Command: arena rename'),(239,'Command: ban'),(240,'Command: ban account'),(241,'Command: ban character'),(242,'Command: ban ip'),(243,'Command: ban playeraccount'),(244,'Command: baninfo'),(245,'Command: baninfo account'),(246,'Command: baninfo character'),(247,'Command: baninfo ip'),(248,'Command: banlist'),(249,'Command: banlist account'),(250,'Command: banlist character'),(251,'Command: banlist ip'),(252,'Command: unban'),(253,'Command: unban account'),(254,'Command: unban character'),(255,'Command: unban ip'),(256,'Command: unban playeraccount'),(257,'Command: bf'),(258,'Command: bf start'),(259,'Command: bf stop'),(260,'Command: bf switch'),(261,'Command: bf timer'),(262,'Command: bf enable'),(263,'Command: account email'),(264,'Command: account set sec'),(265,'Command: account set sec email'),(266,'Command: account set sec regmail'),(267,'Command: cast'),(268,'Command: cast back'),(269,'Command: cast dist'),(270,'Command: cast self'),(271,'Command: cast target'),(272,'Command: cast dest'),(273,'Command: character'),(274,'Command: character customize'),(275,'Command: character changefaction'),(276,'Command: character changerace'),(277,'Command: character deleted'),(279,'Command: character deleted list'),(280,'Command: character deleted restore'),(283,'Command: character level'),(284,'Command: character rename'),(285,'Command: character reputation'),(286,'Command: character titles'),(287,'Command: levelup'),(288,'Command: pdump'),(289,'Command: pdump load'),(290,'Command: pdump write'),(291,'Command: cheat'),(292,'Command: cheat casttime'),(293,'Command: cheat cooldown'),(294,'Command: cheat explore'),(295,'Command: cheat god'),(296,'Command: cheat power'),(297,'Command: cheat status'),(298,'Command: cheat taxi'),(299,'Command: cheat waterwalk'),(300,'Command: debug'),(301,'Command: debug anim'),(302,'Command: debug areatriggers'),(303,'Command: debug arena'),(304,'Command: debug bg'),(305,'Command: debug entervehicle'),(306,'Command: debug getitemstate'),(307,'Command: debug getitemvalue'),(308,'Command: debug getvalue'),(309,'Command: debug hostil'),(310,'Command: debug itemexpire'),(311,'Command: debug lootrecipient'),(312,'Command: debug los'),(313,'Command: debug mod32value'),(314,'Command: debug moveflags'),(315,'Command: debug play'),(316,'Command: debug play cinematics'),(317,'Command: debug play movie'),(318,'Command: debug play sound'),(319,'Command: debug send'),(320,'Command: debug send buyerror'),(321,'Command: debug send channelnotify'),(322,'Command: debug send chatmessage'),(323,'Command: debug send equiperror'),(324,'Command: debug send largepacket'),(325,'Command: debug send opcode'),(326,'Command: debug send qinvalidmsg'),(327,'Command: debug send qpartymsg'),(328,'Command: debug send sellerror'),(329,'Command: debug send setphaseshift'),(330,'Command: debug send spellfail'),(331,'Command: debug setaurastate'),(332,'Command: debug setbit'),(333,'Command: debug setitemvalue'),(334,'Command: debug setvalue'),(335,'Command: debug setvid'),(336,'Command: debug spawnvehicle'),(337,'Command: debug threat'),(338,'Command: debug update'),(339,'Command: debug uws'),(340,'Command: wpgps'),(341,'Command: deserter'),(342,'Command: deserter bg'),(343,'Command: deserter bg add'),(344,'Command: deserter bg remove'),(345,'Command: deserter instance'),(346,'Command: deserter instance add'),(347,'Command: deserter instance remove'),(348,'Command: disable'),(349,'Command: disable add'),(350,'Command: disable add achievement_criteria'),(351,'Command: disable add battleground'),(352,'Command: disable add map'),(353,'Command: disable add mmap'),(354,'Command: disable add outdoorpvp'),(355,'Command: disable add quest'),(356,'Command: disable add spell'),(357,'Command: disable add vmap'),(358,'Command: disable remove'),(359,'Command: disable remove achievement_criteria'),(360,'Command: disable remove battleground'),(361,'Command: disable remove map'),(362,'Command: disable remove mmap'),(363,'Command: disable remove outdoorpvp'),(364,'Command: disable remove quest'),(365,'Command: disable remove spell'),(366,'Command: disable remove vmap'),(367,'Command: event'),(368,'Command: event activelist'),(369,'Command: event start'),(370,'Command: event stop'),(371,'Command: gm'),(372,'Command: gm chat'),(373,'Command: gm fly'),(374,'Command: gm ingame'),(375,'Command: gm list'),(376,'Command: gm visible'),(377,'Command: go'),(378,'Command: go creature'),(379,'Command: go graveyard'),(380,'Command: go grid'),(381,'Command: go object'),(382,'Command: go taxinode'),(383,'Command: go ticket'),(384,'Command: go trigger'),(385,'Command: go xyz'),(386,'Command: go zonexy'),(387,'Command: gobject'),(388,'Command: gobject activate'),(389,'Command: gobject add'),(390,'Command: gobject add temp'),(391,'Command: gobject delete'),(392,'Command: gobject info'),(393,'Command: gobject move'),(394,'Command: gobject near'),(395,'Command: gobject set'),(396,'Command: gobject set phase'),(397,'Command: gobject set state'),(398,'Command: gobject target'),(399,'Command: gobject turn'),(400,'debug transport'),(401,'Command: guild'),(402,'Command: guild create'),(403,'Command: guild delete'),(404,'Command: guild invite'),(405,'Command: guild uninvite'),(406,'Command: guild rank'),(407,'Command: guild rename'),(408,'Command: honor'),(409,'Command: honor add'),(410,'Command: honor add kill'),(411,'Command: honor update'),(412,'Command: instance'),(413,'Command: instance listbinds'),(414,'Command: instance unbind'),(415,'Command: instance stats'),(416,'Command: instance savedata'),(417,'Command: learn'),(418,'Command: learn all'),(419,'Command: learn all my'),(420,'Command: learn all my class'),(421,'Command: learn all my pettalents'),(422,'Command: learn all my spells'),(423,'Command: learn all my talents'),(424,'Command: learn all gm'),(425,'Command: learn all crafts'),(426,'Command: learn all default'),(427,'Command: learn all lang'),(428,'Command: learn all recipes'),(429,'Command: unlearn'),(430,'Command: lfg'),(431,'Command: lfg player'),(432,'Command: lfg group'),(433,'Command: lfg queue'),(434,'Command: lfg clean'),(435,'Command: lfg options'),(436,'Command: list'),(437,'Command: list creature'),(438,'Command: list item'),(439,'Command: list object'),(440,'Command: list auras'),(441,'Command: list mail'),(442,'Command: lookup'),(443,'Command: lookup area'),(444,'Command: lookup creature'),(445,'Command: lookup event'),(446,'Command: lookup faction'),(447,'Command: lookup item'),(448,'Command: lookup itemset'),(449,'Command: lookup object'),(450,'Command: lookup quest'),(451,'Command: lookup player'),(452,'Command: lookup player ip'),(453,'Command: lookup player account'),(454,'Command: lookup player email'),(455,'Command: lookup skill'),(456,'Command: lookup spell'),(457,'Command: lookup spell id'),(458,'Command: lookup taxinode'),(459,'Command: lookup tele'),(460,'Command: lookup title'),(461,'Command: lookup map'),(462,'Command: announce'),(463,'Command: channel'),(464,'Command: channel set'),(465,'Command: channel set ownership'),(466,'Command: gmannounce'),(467,'Command: gmnameannounce'),(468,'Command: gmnotify'),(469,'Command: nameannounce'),(470,'Command: notify'),(471,'Command: whispers'),(472,'Command: group'),(473,'Command: group leader'),(474,'Command: group disband'),(475,'Command: group remove'),(476,'Command: group join'),(477,'Command: group list'),(478,'Command: group summon'),(479,'Command: pet'),(480,'Command: pet create'),(481,'Command: pet learn'),(482,'Command: pet unlearn'),(483,'Command: send'),(484,'Command: send items'),(485,'Command: send mail'),(486,'Command: send message'),(487,'Command: send money'),(488,'Command: additem'),(489,'Command: additemset'),(490,'Command: appear'),(491,'Command: aura'),(492,'Command: bank'),(493,'Command: bindsight'),(494,'Command: combatstop'),(495,'Command: cometome'),(496,'Command: commands'),(497,'Command: cooldown'),(498,'Command: damage'),(499,'Command: dev'),(500,'Command: die'),(501,'Command: dismount'),(502,'Command: distance'),(503,'Command: flusharenapoints'),(504,'Command: freeze'),(505,'Command: gps'),(506,'Command: guid'),(507,'Command: help'),(508,'Command: hidearea'),(509,'Command: itemmove'),(510,'Command: kick'),(511,'Command: linkgrave'),(512,'Command: listfreeze'),(513,'Command: maxskill'),(514,'Command: movegens'),(515,'Command: mute'),(516,'Command: neargrave'),(517,'Command: pinfo'),(518,'Command: playall'),(519,'Command: possess'),(520,'Command: recall'),(521,'Command: repairitems'),(522,'Command: respawn'),(523,'Command: revive'),(524,'Command: saveall'),(525,'Command: save'),(526,'Command: setskill'),(527,'Command: showarea'),(528,'Command: summon'),(529,'Command: unaura'),(530,'Command: unbindsight'),(531,'Command: unfreeze'),(532,'Command: unmute'),(533,'Command: unpossess'),(534,'Command: unstuck'),(535,'Command: wchange'),(536,'Command: mmap'),(537,'Command: mmap loadedtiles'),(538,'Command: mmap loc'),(539,'Command: mmap path'),(540,'Command: mmap stats'),(541,'Command: mmap testarea'),(542,'Command: morph'),(543,'Command: demorph'),(544,'Command: modify'),(545,'Command: modify arenapoints'),(546,'Command: modify bit'),(547,'Command: modify drunk'),(548,'Command: modify energy'),(549,'Command: modify faction'),(550,'Command: modify gender'),(551,'Command: modify honor'),(552,'Command: modify hp'),(553,'Command: modify mana'),(554,'Command: modify money'),(555,'Command: modify mount'),(556,'Command: modify phase'),(557,'Command: modify rage'),(558,'Command: modify reputation'),(559,'Command: modify runicpower'),(560,'Command: modify scale'),(561,'Command: modify speed'),(562,'Command: modify speed all'),(563,'Command: modify speed backwalk'),(564,'Command: modify speed fly'),(565,'Command: modify speed walk'),(566,'Command: modify speed swim'),(567,'Command: modify spell'),(568,'Command: modify standstate'),(569,'Command: modify talentpoints'),(570,'Command: npc'),(571,'Command: npc add'),(572,'Command: npc add formation'),(573,'Command: npc add item'),(574,'Command: npc add move'),(575,'Command: npc add temp'),(576,'Command: npc add delete'),(577,'Command: npc add delete item'),(578,'Command: npc add follow'),(579,'Command: npc add follow stop'),(580,'Command: npc set'),(581,'Command: npc set allowmove'),(582,'Command: npc set entry'),(583,'Command: npc set factionid'),(584,'Command: npc set flag'),(585,'Command: npc set level'),(586,'Command: npc set link'),(587,'Command: npc set model'),(588,'Command: npc set movetype'),(589,'Command: npc set phase'),(590,'Command: npc set spawndist'),(591,'Command: npc set spawntime'),(592,'Command: npc set data'),(593,'Command: npc info'),(594,'Command: npc near'),(595,'Command: npc move'),(596,'Command: npc playemote'),(597,'Command: npc say'),(598,'Command: npc textemote'),(599,'Command: npc whisper'),(600,'Command: npc yell'),(601,'Command: npc tame'),(602,'Command: quest'),(603,'Command: quest add'),(604,'Command: quest complete'),(605,'Command: quest remove'),(606,'Command: quest reward'),(607,'Command: reload'),(608,'Command: reload access_requirement'),(609,'Command: reload achievement_criteria_data'),(610,'Command: reload achievement_reward'),(611,'Command: reload all'),(612,'Command: reload all achievement'),(613,'Command: reload all area'),(614,'Command: broadcast_text'),(615,'Command: reload all gossips'),(616,'Command: reload all item'),(617,'Command: reload all locales'),(618,'Command: reload all loot'),(619,'Command: reload all npc'),(620,'Command: reload all quest'),(621,'Command: reload all scripts'),(622,'Command: reload all spell'),(623,'Command: reload areatrigger_involvedrelation'),(624,'Command: reload areatrigger_tavern'),(625,'Command: reload areatrigger_teleport'),(626,'Command: reload auctions'),(627,'Command: reload autobroadcast'),(628,'Command: reload command'),(629,'Command: reload conditions'),(630,'Command: reload config'),(631,'Command: reload battleground_template'),(632,'Command: .mutehistory'),(633,'Command: reload creature_linked_respawn'),(634,'Command: reload creature_loot_template'),(635,'Command: reload creature_onkill_reputation'),(636,'Command: reload creature_questender'),(637,'Command: reload creature_queststarter'),(638,'Command: reload creature_summon_groups'),(639,'Command: reload creature_template'),(640,'Command: reload creature_text'),(641,'Command: reload disables'),(642,'Command: reload disenchant_loot_template'),(643,'Command: reload event_scripts'),(644,'Command: reload fishing_loot_template'),(645,'Command: reload game_graveyard_zone'),(646,'Command: reload game_tele'),(647,'Command: reload gameobject_questender'),(648,'Command: reload gameobject_loot_template'),(649,'Command: reload gameobject_queststarter'),(650,'Command: reload gm_tickets'),(651,'Command: reload gossip_menu'),(652,'Command: reload gossip_menu_option'),(653,'Command: reload item_enchantment_template'),(654,'Command: reload item_loot_template'),(655,'Command: reload item_set_names'),(656,'Command: reload lfg_dungeon_rewards'),(657,'Command: reload locales_achievement_reward'),(658,'Command: reload locales_creature'),(659,'Command: reload locales_creature_text'),(660,'Command: reload locales_gameobject'),(661,'Command: reload locales_gossip_menu_option'),(662,'Command: reload locales_item'),(663,'Command: reload locales_item_set_name'),(664,'Command: reload locales_npc_text'),(665,'Command: reload locales_page_text'),(666,'Command: reload locales_points_of_interest'),(667,'Command: reload locales_quest'),(668,'Command: reload mail_level_reward'),(669,'Command: reload mail_loot_template'),(670,'Command: reload milling_loot_template'),(671,'Command: reload npc_spellclick_spells'),(672,'Command: reload npc_trainer'),(673,'Command: reload npc_vendor'),(674,'Command: reload page_text'),(675,'Command: reload pickpocketing_loot_template'),(676,'Command: reload points_of_interest'),(677,'Command: reload prospecting_loot_template'),(678,'Command: reload quest_poi'),(679,'Command: reload quest_template'),(680,'Command: reload rbac'),(681,'Command: reload reference_loot_template'),(682,'Command: reload reserved_name'),(683,'Command: reload reputation_reward_rate'),(684,'Command: reload reputation_spillover_template'),(685,'Command: reload skill_discovery_template'),(686,'Command: reload skill_extra_item_template'),(687,'Command: reload skill_fishing_base_level'),(688,'Command: reload skinning_loot_template'),(689,'Command: reload smart_scripts'),(690,'Command: reload spell_required'),(691,'Command: reload spell_area'),(692,'Command: reload spell_bonus_data'),(693,'Command: reload spell_group'),(694,'Command: reload spell_learn_spell'),(695,'Command: reload spell_loot_template'),(696,'Command: reload spell_linked_spell'),(697,'Command: reload spell_pet_auras'),(698,'Command: reload spell_proc_event'),(699,'Command: reload spell_proc'),(700,'Command: reload spell_scripts'),(701,'Command: reload spell_target_position'),(702,'Command: reload spell_threats'),(703,'Command: reload spell_group_stack_rules'),(704,'Command: reload trinity_string'),(705,'Command: reload warden_action'),(706,'Command: reload waypoint_scripts'),(707,'Command: reload waypoint_data'),(708,'Command: reload vehicle_accessory'),(709,'Command: reload vehicle_template_accessory'),(710,'Command: reset'),(711,'Command: reset achievements'),(712,'Command: reset honor'),(713,'Command: reset level'),(714,'Command: reset spells'),(715,'Command: reset stats'),(716,'Command: reset talents'),(717,'Command: reset all'),(718,'Command: server'),(719,'Command: server corpses'),(720,'Command: server exit'),(721,'Command: server idlerestart'),(722,'Command: server idlerestart cancel'),(723,'Command: server idleshutdown'),(724,'Command: server idleshutdown cancel'),(725,'Command: server info'),(726,'Command: server plimit'),(727,'Command: server restart'),(728,'Command: server restart cancel'),(729,'Command: server set'),(730,'Command: server set closed'),(731,'Command: server set difftime'),(732,'Command: server set loglevel'),(733,'Command: server set motd'),(734,'Command: server shutdown'),(735,'Command: server shutdown cancel'),(736,'Command: server motd'),(737,'Command: tele'),(738,'Command: tele add'),(739,'Command: tele del'),(740,'Command: tele name'),(741,'Command: tele group'),(742,'Command: ticket'),(743,'Command: ticket assign'),(744,'Command: ticket close'),(745,'Command: ticket closedlist'),(746,'Command: ticket comment'),(747,'Command: ticket complete'),(748,'Command: ticket delete'),(749,'Command: ticket escalate'),(750,'Command: ticket escalatedlist'),(751,'Command: ticket list'),(752,'Command: ticket onlinelist'),(753,'Command: ticket reset'),(754,'Command: ticket response'),(755,'Command: ticket response append'),(756,'Command: ticket response appendln'),(757,'Command: ticket togglesystem'),(758,'Command: ticket unassign'),(759,'Command: ticket viewid'),(760,'Command: ticket viewname'),(761,'Command: titles'),(762,'Command: titles add'),(763,'Command: titles current'),(764,'Command: titles remove'),(765,'Command: titles set'),(766,'Command: titles set mask'),(767,'Command: wp'),(768,'Command: wp add'),(769,'Command: wp event'),(770,'Command: wp load'),(771,'Command: wp modify'),(772,'Command: wp unload'),(773,'Command: wp reload'),(774,'Command: wp show'),(777,'Command: mailbox'),(778,'Command: ahbot'),(779,'Command: ahbot items'),(780,'Command: ahbot items gray'),(781,'Command: ahbot items white'),(782,'Command: ahbot items green'),(783,'Command: ahbot items blue'),(784,'Command: ahbot items purple'),(785,'Command: ahbot items orange'),(786,'Command: ahbot items yellow'),(787,'Command: ahbot ratio'),(788,'Command: ahbot ratio alliance'),(789,'Command: ahbot ratio horde'),(790,'Command: ahbot ratio neutral'),(791,'Command: ahbot rebuild'),(792,'Command: ahbot reload'),(793,'Command: ahbot status'),(794,'Command: .guild info'),(795,'Command: .instance setbossstate'),(796,'Command: instance getbossstate'),(797,'Command: pvpstats'),(798,'Command: .mod xp'),(835,'Command: debug loadcells'),(836,'Command: .debug boundary');
+INSERT INTO `rbac_permissions` VALUES (1,'Instant logout'),(2,'Skip Queue'),(3,'Join Normal Battleground'),(4,'Join Random Battleground'),(5,'Join Arenas'),(6,'Join Dungeon Finder'),(11,'Log GM trades'),(13,'Skip Instance required bosses check'),(14,'Skip character creation team mask check'),(15,'Skip character creation class mask check'),(16,'Skip character creation race mask check'),(17,'Skip character creation reserved name check'),(18,'Skip character creation heroic min level check'),(19,'Skip needed requirements to use channel check'),(20,'Skip disable map check'),(21,'Skip reset talents when used more than allowed check'),(22,'Skip spam chat check'),(23,'Skip over-speed ping check'),(24,'Two side faction characters on the same account'),(25,'Allow say chat between factions'),(26,'Allow channel chat between factions'),(27,'Two side mail interaction'),(28,'See two side who list'),(29,'Add friends of other faction'),(30,'Save character without delay with .save command'),(31,'Use params with .unstuck command'),(32,'Can be assigned tickets with .assign ticket command'),(33,'Notify if a command was not found'),(34,'Check if should appear in list using .gm ingame command'),(35,'See all security levels with who command'),(36,'Filter whispers'),(37,'Use staff badge in chat'),(38,'Resurrect with full Health Points'),(39,'Restore saved gm setting states'),(40,'Allows to add a gm to friend list'),(41,'Use Config option START_GM_LEVEL to assign new character level'),(42,'Allows to use CMSG_WORLD_TELEPORT opcode'),(43,'Allows to use CMSG_WHOIS opcode'),(44,'Receive global GM messages/texts'),(45,'Join channels without announce'),(46,'Change channel settings without being channel moderator'),(47,'Enables lower security than target check'),(48,'Enable IP, Last Login and EMail output in pinfo'),(49,'Forces to enter the email for confirmation on password change'),(50,'Allow user to check his own email with .account'),(51,'Allow trading between factions'),(192,'Role: Sec Level Administrator'),(193,'Role: Sec Level Gamemaster'),(194,'Role: Sec Level Moderator'),(195,'Role: Sec Level Player'),(196,'Role: Administrator Commands'),(197,'Role: Gamemaster Commands'),(198,'Role: Moderator Commands'),(199,'Role: Player Commands'),(200,'Command: rbac'),(201,'Command: rbac account'),(202,'Command: rbac account list'),(203,'Command: rbac account grant'),(204,'Command: rbac account deny'),(205,'Command: rbac account revoke'),(206,'Command: rbac list'),(217,'Command: account'),(218,'Command: account addon'),(219,'Command: account create'),(220,'Command: account delete'),(221,'Command: account lock'),(222,'Command: account lock country'),(223,'Command: account lock ip'),(224,'Command: account onlinelist'),(225,'Command: account password'),(226,'Command: account set'),(227,'Command: account set addon'),(228,'Command: account set gmlevel'),(229,'Command: account set password'),(230,'Command: achievement'),(231,'Command: achievement add'),(232,'Command: arena'),(233,'Command: arena captain'),(234,'Command: arena create'),(235,'Command: arena disband'),(236,'Command: arena info'),(237,'Command: arena lookup'),(238,'Command: arena rename'),(239,'Command: ban'),(240,'Command: ban account'),(241,'Command: ban character'),(242,'Command: ban ip'),(243,'Command: ban playeraccount'),(244,'Command: baninfo'),(245,'Command: baninfo account'),(246,'Command: baninfo character'),(247,'Command: baninfo ip'),(248,'Command: banlist'),(249,'Command: banlist account'),(250,'Command: banlist character'),(251,'Command: banlist ip'),(252,'Command: unban'),(253,'Command: unban account'),(254,'Command: unban character'),(255,'Command: unban ip'),(256,'Command: unban playeraccount'),(257,'Command: bf'),(258,'Command: bf start'),(259,'Command: bf stop'),(260,'Command: bf switch'),(261,'Command: bf timer'),(262,'Command: bf enable'),(263,'Command: account email'),(264,'Command: account set sec'),(265,'Command: account set sec email'),(266,'Command: account set sec regmail'),(267,'Command: cast'),(268,'Command: cast back'),(269,'Command: cast dist'),(270,'Command: cast self'),(271,'Command: cast target'),(272,'Command: cast dest'),(273,'Command: character'),(274,'Command: character customize'),(275,'Command: character changefaction'),(276,'Command: character changerace'),(277,'Command: character deleted'),(279,'Command: character deleted list'),(280,'Command: character deleted restore'),(283,'Command: character level'),(284,'Command: character rename'),(285,'Command: character reputation'),(286,'Command: character titles'),(287,'Command: levelup'),(288,'Command: pdump'),(289,'Command: pdump load'),(290,'Command: pdump write'),(291,'Command: cheat'),(292,'Command: cheat casttime'),(293,'Command: cheat cooldown'),(294,'Command: cheat explore'),(295,'Command: cheat god'),(296,'Command: cheat power'),(297,'Command: cheat status'),(298,'Command: cheat taxi'),(299,'Command: cheat waterwalk'),(300,'Command: debug'),(301,'Command: debug anim'),(302,'Command: debug areatriggers'),(303,'Command: debug arena'),(304,'Command: debug bg'),(305,'Command: debug entervehicle'),(306,'Command: debug getitemstate'),(307,'Command: debug getitemvalue'),(308,'Command: debug getvalue'),(309,'Command: debug hostil'),(310,'Command: debug itemexpire'),(311,'Command: debug lootrecipient'),(312,'Command: debug los'),(313,'Command: debug mod32value'),(314,'Command: debug moveflags'),(315,'Command: debug play'),(316,'Command: debug play cinematics'),(317,'Command: debug play movie'),(318,'Command: debug play sound'),(319,'Command: debug send'),(320,'Command: debug send buyerror'),(321,'Command: debug send channelnotify'),(322,'Command: debug send chatmessage'),(323,'Command: debug send equiperror'),(324,'Command: debug send largepacket'),(325,'Command: debug send opcode'),(326,'Command: debug send qinvalidmsg'),(327,'Command: debug send qpartymsg'),(328,'Command: debug send sellerror'),(329,'Command: debug send setphaseshift'),(330,'Command: debug send spellfail'),(331,'Command: debug setaurastate'),(332,'Command: debug setbit'),(333,'Command: debug setitemvalue'),(334,'Command: debug setvalue'),(335,'Command: debug setvid'),(336,'Command: debug spawnvehicle'),(337,'Command: debug threat'),(338,'Command: debug update'),(339,'Command: debug uws'),(340,'Command: wpgps'),(341,'Command: deserter'),(342,'Command: deserter bg'),(343,'Command: deserter bg add'),(344,'Command: deserter bg remove'),(345,'Command: deserter instance'),(346,'Command: deserter instance add'),(347,'Command: deserter instance remove'),(348,'Command: disable'),(349,'Command: disable add'),(350,'Command: disable add achievement_criteria'),(351,'Command: disable add battleground'),(352,'Command: disable add map'),(353,'Command: disable add mmap'),(354,'Command: disable add outdoorpvp'),(355,'Command: disable add quest'),(356,'Command: disable add spell'),(357,'Command: disable add vmap'),(358,'Command: disable remove'),(359,'Command: disable remove achievement_criteria'),(360,'Command: disable remove battleground'),(361,'Command: disable remove map'),(362,'Command: disable remove mmap'),(363,'Command: disable remove outdoorpvp'),(364,'Command: disable remove quest'),(365,'Command: disable remove spell'),(366,'Command: disable remove vmap'),(367,'Command: event'),(368,'Command: event activelist'),(369,'Command: event start'),(370,'Command: event stop'),(371,'Command: gm'),(372,'Command: gm chat'),(373,'Command: gm fly'),(374,'Command: gm ingame'),(375,'Command: gm list'),(376,'Command: gm visible'),(377,'Command: go'),(378,'Command: go creature'),(379,'Command: go graveyard'),(380,'Command: go grid'),(381,'Command: go object'),(382,'Command: go taxinode'),(383,'Command: go ticket'),(384,'Command: go trigger'),(385,'Command: go xyz'),(386,'Command: go zonexy'),(387,'Command: gobject'),(388,'Command: gobject activate'),(389,'Command: gobject add'),(390,'Command: gobject add temp'),(391,'Command: gobject delete'),(392,'Command: gobject info'),(393,'Command: gobject move'),(394,'Command: gobject near'),(395,'Command: gobject set'),(396,'Command: gobject set phase'),(397,'Command: gobject set state'),(398,'Command: gobject target'),(399,'Command: gobject turn'),(400,'debug transport'),(401,'Command: guild'),(402,'Command: guild create'),(403,'Command: guild delete'),(404,'Command: guild invite'),(405,'Command: guild uninvite'),(406,'Command: guild rank'),(407,'Command: guild rename'),(408,'Command: honor'),(409,'Command: honor add'),(410,'Command: honor add kill'),(411,'Command: honor update'),(412,'Command: instance'),(413,'Command: instance listbinds'),(414,'Command: instance unbind'),(415,'Command: instance stats'),(416,'Command: instance savedata'),(417,'Command: learn'),(418,'Command: learn all'),(419,'Command: learn all my'),(420,'Command: learn all my class'),(421,'Command: learn all my pettalents'),(422,'Command: learn all my spells'),(423,'Command: learn all my talents'),(424,'Command: learn all gm'),(425,'Command: learn all crafts'),(426,'Command: learn all default'),(427,'Command: learn all lang'),(428,'Command: learn all recipes'),(429,'Command: unlearn'),(430,'Command: lfg'),(431,'Command: lfg player'),(432,'Command: lfg group'),(433,'Command: lfg queue'),(434,'Command: lfg clean'),(435,'Command: lfg options'),(436,'Command: list'),(437,'Command: list creature'),(438,'Command: list item'),(439,'Command: list object'),(440,'Command: list auras'),(441,'Command: list mail'),(442,'Command: lookup'),(443,'Command: lookup area'),(444,'Command: lookup creature'),(445,'Command: lookup event'),(446,'Command: lookup faction'),(447,'Command: lookup item'),(448,'Command: lookup itemset'),(449,'Command: lookup object'),(450,'Command: lookup quest'),(451,'Command: lookup player'),(452,'Command: lookup player ip'),(453,'Command: lookup player account'),(454,'Command: lookup player email'),(455,'Command: lookup skill'),(456,'Command: lookup spell'),(457,'Command: lookup spell id'),(458,'Command: lookup taxinode'),(459,'Command: lookup tele'),(460,'Command: lookup title'),(461,'Command: lookup map'),(462,'Command: announce'),(463,'Command: channel'),(464,'Command: channel set'),(465,'Command: channel set ownership'),(466,'Command: gmannounce'),(467,'Command: gmnameannounce'),(468,'Command: gmnotify'),(469,'Command: nameannounce'),(470,'Command: notify'),(471,'Command: whispers'),(472,'Command: group'),(473,'Command: group leader'),(474,'Command: group disband'),(475,'Command: group remove'),(476,'Command: group join'),(477,'Command: group list'),(478,'Command: group summon'),(479,'Command: pet'),(480,'Command: pet create'),(481,'Command: pet learn'),(482,'Command: pet unlearn'),(483,'Command: send'),(484,'Command: send items'),(485,'Command: send mail'),(486,'Command: send message'),(487,'Command: send money'),(488,'Command: additem'),(489,'Command: additemset'),(490,'Command: appear'),(491,'Command: aura'),(492,'Command: bank'),(493,'Command: bindsight'),(494,'Command: combatstop'),(495,'Command: cometome'),(496,'Command: commands'),(497,'Command: cooldown'),(498,'Command: damage'),(499,'Command: dev'),(500,'Command: die'),(501,'Command: dismount'),(502,'Command: distance'),(503,'Command: flusharenapoints'),(504,'Command: freeze'),(505,'Command: gps'),(506,'Command: guid'),(507,'Command: help'),(508,'Command: hidearea'),(509,'Command: itemmove'),(510,'Command: kick'),(511,'Command: linkgrave'),(512,'Command: listfreeze'),(513,'Command: maxskill'),(514,'Command: movegens'),(515,'Command: mute'),(516,'Command: neargrave'),(517,'Command: pinfo'),(518,'Command: playall'),(519,'Command: possess'),(520,'Command: recall'),(521,'Command: repairitems'),(522,'Command: respawn'),(523,'Command: revive'),(524,'Command: saveall'),(525,'Command: save'),(526,'Command: setskill'),(527,'Command: showarea'),(528,'Command: summon'),(529,'Command: unaura'),(530,'Command: unbindsight'),(531,'Command: unfreeze'),(532,'Command: unmute'),(533,'Command: unpossess'),(534,'Command: unstuck'),(535,'Command: wchange'),(536,'Command: mmap'),(537,'Command: mmap loadedtiles'),(538,'Command: mmap loc'),(539,'Command: mmap path'),(540,'Command: mmap stats'),(541,'Command: mmap testarea'),(542,'Command: morph'),(543,'Command: demorph'),(544,'Command: modify'),(545,'Command: modify arenapoints'),(546,'Command: modify bit'),(547,'Command: modify drunk'),(548,'Command: modify energy'),(549,'Command: modify faction'),(550,'Command: modify gender'),(551,'Command: modify honor'),(552,'Command: modify hp'),(553,'Command: modify mana'),(554,'Command: modify money'),(555,'Command: modify mount'),(556,'Command: modify phase'),(557,'Command: modify rage'),(558,'Command: modify reputation'),(559,'Command: modify runicpower'),(560,'Command: modify scale'),(561,'Command: modify speed'),(562,'Command: modify speed all'),(563,'Command: modify speed backwalk'),(564,'Command: modify speed fly'),(565,'Command: modify speed walk'),(566,'Command: modify speed swim'),(567,'Command: modify spell'),(568,'Command: modify standstate'),(569,'Command: modify talentpoints'),(570,'Command: npc'),(571,'Command: npc add'),(572,'Command: npc add formation'),(573,'Command: npc add item'),(574,'Command: npc add move'),(575,'Command: npc add temp'),(576,'Command: npc add delete'),(577,'Command: npc add delete item'),(578,'Command: npc add follow'),(579,'Command: npc add follow stop'),(580,'Command: npc set'),(581,'Command: npc set allowmove'),(582,'Command: npc set entry'),(583,'Command: npc set factionid'),(584,'Command: npc set flag'),(585,'Command: npc set level'),(586,'Command: npc set link'),(587,'Command: npc set model'),(588,'Command: npc set movetype'),(589,'Command: npc set phase'),(590,'Command: npc set spawndist'),(591,'Command: npc set spawntime'),(592,'Command: npc set data'),(593,'Command: npc info'),(594,'Command: npc near'),(595,'Command: npc move'),(596,'Command: npc playemote'),(597,'Command: npc say'),(598,'Command: npc textemote'),(599,'Command: npc whisper'),(600,'Command: npc yell'),(601,'Command: npc tame'),(602,'Command: quest'),(603,'Command: quest add'),(604,'Command: quest complete'),(605,'Command: quest remove'),(606,'Command: quest reward'),(607,'Command: reload'),(608,'Command: reload access_requirement'),(609,'Command: reload achievement_criteria_data'),(610,'Command: reload achievement_reward'),(611,'Command: reload all'),(612,'Command: reload all achievement'),(613,'Command: reload all area'),(614,'Command: broadcast_text'),(615,'Command: reload all gossips'),(616,'Command: reload all item'),(617,'Command: reload all locales'),(618,'Command: reload all loot'),(619,'Command: reload all npc'),(620,'Command: reload all quest'),(621,'Command: reload all scripts'),(622,'Command: reload all spell'),(623,'Command: reload areatrigger_involvedrelation'),(624,'Command: reload areatrigger_tavern'),(625,'Command: reload areatrigger_teleport'),(626,'Command: reload auctions'),(627,'Command: reload autobroadcast'),(628,'Command: reload command'),(629,'Command: reload conditions'),(630,'Command: reload config'),(631,'Command: reload battleground_template'),(632,'Command: .mutehistory'),(633,'Command: reload creature_linked_respawn'),(634,'Command: reload creature_loot_template'),(635,'Command: reload creature_onkill_reputation'),(636,'Command: reload creature_questender'),(637,'Command: reload creature_queststarter'),(638,'Command: reload creature_summon_groups'),(639,'Command: reload creature_template'),(640,'Command: reload creature_text'),(641,'Command: reload disables'),(642,'Command: reload disenchant_loot_template'),(643,'Command: reload event_scripts'),(644,'Command: reload fishing_loot_template'),(645,'Command: reload game_graveyard_zone'),(646,'Command: reload game_tele'),(647,'Command: reload gameobject_questender'),(648,'Command: reload gameobject_loot_template'),(649,'Command: reload gameobject_queststarter'),(650,'Command: reload gm_tickets'),(651,'Command: reload gossip_menu'),(652,'Command: reload gossip_menu_option'),(653,'Command: reload item_enchantment_template'),(654,'Command: reload item_loot_template'),(655,'Command: reload item_set_names'),(656,'Command: reload lfg_dungeon_rewards'),(657,'Command: reload locales_achievement_reward'),(658,'Command: reload locales_creature'),(659,'Command: reload locales_creature_text'),(660,'Command: reload locales_gameobject'),(661,'Command: reload locales_gossip_menu_option'),(662,'Command: reload locales_item'),(663,'Command: reload locales_item_set_name'),(664,'Command: reload locales_npc_text'),(665,'Command: reload locales_page_text'),(666,'Command: reload locales_points_of_interest'),(667,'Command: reload locales_quest'),(668,'Command: reload mail_level_reward'),(669,'Command: reload mail_loot_template'),(670,'Command: reload milling_loot_template'),(671,'Command: reload npc_spellclick_spells'),(672,'Command: reload npc_trainer'),(673,'Command: reload npc_vendor'),(674,'Command: reload page_text'),(675,'Command: reload pickpocketing_loot_template'),(676,'Command: reload points_of_interest'),(677,'Command: reload prospecting_loot_template'),(678,'Command: reload quest_poi'),(679,'Command: reload quest_template'),(680,'Command: reload rbac'),(681,'Command: reload reference_loot_template'),(682,'Command: reload reserved_name'),(683,'Command: reload reputation_reward_rate'),(684,'Command: reload reputation_spillover_template'),(685,'Command: reload skill_discovery_template'),(686,'Command: reload skill_extra_item_template'),(687,'Command: reload skill_fishing_base_level'),(688,'Command: reload skinning_loot_template'),(689,'Command: reload smart_scripts'),(690,'Command: reload spell_required'),(691,'Command: reload spell_area'),(692,'Command: reload spell_bonus_data'),(693,'Command: reload spell_group'),(694,'Command: reload spell_learn_spell'),(695,'Command: reload spell_loot_template'),(696,'Command: reload spell_linked_spell'),(697,'Command: reload spell_pet_auras'),(698,'Command: reload spell_proc_event'),(699,'Command: reload spell_proc'),(700,'Command: reload spell_scripts'),(701,'Command: reload spell_target_position'),(702,'Command: reload spell_threats'),(703,'Command: reload spell_group_stack_rules'),(704,'Command: reload trinity_string'),(705,'Command: reload warden_action'),(706,'Command: reload waypoint_scripts'),(707,'Command: reload waypoint_data'),(708,'Command: reload vehicle_accessory'),(709,'Command: reload vehicle_template_accessory'),(710,'Command: reset'),(711,'Command: reset achievements'),(712,'Command: reset honor'),(713,'Command: reset level'),(714,'Command: reset spells'),(715,'Command: reset stats'),(716,'Command: reset talents'),(717,'Command: reset all'),(718,'Command: server'),(719,'Command: server corpses'),(720,'Command: server exit'),(721,'Command: server idlerestart'),(722,'Command: server idlerestart cancel'),(723,'Command: server idleshutdown'),(724,'Command: server idleshutdown cancel'),(725,'Command: server info'),(726,'Command: server plimit'),(727,'Command: server restart'),(728,'Command: server restart cancel'),(729,'Command: server set'),(730,'Command: server set closed'),(731,'Command: server set difftime'),(732,'Command: server set loglevel'),(733,'Command: server set motd'),(734,'Command: server shutdown'),(735,'Command: server shutdown cancel'),(736,'Command: server motd'),(737,'Command: tele'),(738,'Command: tele add'),(739,'Command: tele del'),(740,'Command: tele name'),(741,'Command: tele group'),(742,'Command: ticket'),(743,'Command: ticket assign'),(744,'Command: ticket close'),(745,'Command: ticket closedlist'),(746,'Command: ticket comment'),(747,'Command: ticket complete'),(748,'Command: ticket delete'),(749,'Command: ticket escalate'),(750,'Command: ticket escalatedlist'),(751,'Command: ticket list'),(752,'Command: ticket onlinelist'),(753,'Command: ticket reset'),(754,'Command: ticket response'),(755,'Command: ticket response append'),(756,'Command: ticket response appendln'),(757,'Command: ticket togglesystem'),(758,'Command: ticket unassign'),(759,'Command: ticket viewid'),(760,'Command: ticket viewname'),(761,'Command: titles'),(762,'Command: titles add'),(763,'Command: titles current'),(764,'Command: titles remove'),(765,'Command: titles set'),(766,'Command: titles set mask'),(767,'Command: wp'),(768,'Command: wp add'),(769,'Command: wp event'),(770,'Command: wp load'),(771,'Command: wp modify'),(772,'Command: wp unload'),(773,'Command: wp reload'),(774,'Command: wp show'),(777,'Command: mailbox'),(778,'Command: ahbot'),(779,'Command: ahbot items'),(780,'Command: ahbot items gray'),(781,'Command: ahbot items white'),(782,'Command: ahbot items green'),(783,'Command: ahbot items blue'),(784,'Command: ahbot items purple'),(785,'Command: ahbot items orange'),(786,'Command: ahbot items yellow'),(787,'Command: ahbot ratio'),(788,'Command: ahbot ratio alliance'),(789,'Command: ahbot ratio horde'),(790,'Command: ahbot ratio neutral'),(791,'Command: ahbot rebuild'),(792,'Command: ahbot reload'),(793,'Command: ahbot status'),(794,'Command: .guild info'),(795,'Command: .instance setbossstate'),(796,'Command: instance getbossstate'),(797,'Command: pvpstats'),(798,'Command: .mod xp'),(835,'Command: debug loadcells'),(836,'Command: .debug boundary'),(837,'Command: .npc evade'),(838,'Command: .pet level'),(839,'Command: .server shutdown force'),(840,'Command: .server restart force');
/*!40000 ALTER TABLE `rbac_permissions` ENABLE KEYS */;
UNLOCK TABLES;
@@ -486,7 +486,7 @@ CREATE TABLE `updates` (
LOCK TABLES `updates` WRITE;
/*!40000 ALTER TABLE `updates` DISABLE KEYS */;
-INSERT INTO `updates` VALUES ('2014_11_10_00_auth.sql','0E3CB119442D09DD88E967015319BBC8DAFBBFE0','ARCHIVED','2015-03-21 21:44:12',0),('2014_11_10_01_auth.sql','327E77A1DA3546D5275AB249915DD57EDD6FDD3D','ARCHIVED','2015-03-21 21:44:12',0),('2014_12_10_00_auth.sql','821703A96D80F9080074852B5A46E2909C9562EA','ARCHIVED','2015-03-21 21:44:12',0),('2014_12_21_00_auth.sql','CE2E5D2CD82E79C25294539ADED27A1429105B43','ARCHIVED','2015-03-21 21:44:12',0),('2015_03_20_00_auth.sql','E8C5B74BB45F0F35DEC182C72BACF435C7066FB0','ARCHIVED','2015-03-21 21:44:12',0),('2015_03_20_01_auth.sql','862961815354DA2746F5F71FBC8155F57CBE75AB','ARCHIVED','2015-03-21 21:44:12',0),('2015_03_20_02_auth.sql','33E4F94086590768EF5D4855DD43D7DE7C06ADA4','ARCHIVED','2015-03-21 21:44:51',0),('2015_08_21_00_auth.sql','C31A9E1D28E11B60BE8F8198637DD51F6D75123F','ARCHIVED','2015-10-05 23:16:19',0),('2015_11_07_00_auth.sql','0ACDD35EC9745231BCFA701B78056DEF94D0CC53','ARCHIVED','2016-04-11 00:42:36',92),('2016_01_13_00_auth.sql','24615CC69B3CD7BB4699874647C35BA86E8A93FD','ARCHIVED','2016-01-13 00:00:00',0),('2016_04_11_00_auth.sql','0ACDD35EC9745231BCFA701B78056DEF94D0CC53','RELEASED','2016-04-11 03:18:17',0);
+INSERT INTO `updates` VALUES ('2014_11_10_00_auth.sql','0E3CB119442D09DD88E967015319BBC8DAFBBFE0','ARCHIVED','2015-03-21 21:44:12',0),('2014_11_10_01_auth.sql','327E77A1DA3546D5275AB249915DD57EDD6FDD3D','ARCHIVED','2015-03-21 21:44:12',0),('2014_12_10_00_auth.sql','821703A96D80F9080074852B5A46E2909C9562EA','ARCHIVED','2015-03-21 21:44:12',0),('2014_12_21_00_auth.sql','CE2E5D2CD82E79C25294539ADED27A1429105B43','ARCHIVED','2015-03-21 21:44:12',0),('2015_03_20_00_auth.sql','E8C5B74BB45F0F35DEC182C72BACF435C7066FB0','ARCHIVED','2015-03-21 21:44:12',0),('2015_03_20_01_auth.sql','862961815354DA2746F5F71FBC8155F57CBE75AB','ARCHIVED','2015-03-21 21:44:12',0),('2015_03_20_02_auth.sql','33E4F94086590768EF5D4855DD43D7DE7C06ADA4','ARCHIVED','2015-03-21 21:44:51',0),('2015_08_21_00_auth.sql','C31A9E1D28E11B60BE8F8198637DD51F6D75123F','ARCHIVED','2015-10-05 23:16:19',0),('2015_11_07_00_auth.sql','0ACDD35EC9745231BCFA701B78056DEF94D0CC53','ARCHIVED','2016-04-11 00:42:36',92),('2016_01_13_00_auth.sql','24615CC69B3CD7BB4699874647C35BA86E8A93FD','ARCHIVED','2016-01-13 00:00:00',0),('2016_04_11_00_auth.sql','0ACDD35EC9745231BCFA701B78056DEF94D0CC53','RELEASED','2016-04-11 03:18:17',0),('2016_05_11_00_auth.sql','95B66235B8D67BF1CA216EB09F313C1F8F393B47','RELEASED','2016-04-16 13:17:11',0);
/*!40000 ALTER TABLE `updates` ENABLE KEYS */;
UNLOCK TABLES;
diff --git a/sql/updates/auth/3.3.5/2016_05_11_00_auth.sql b/sql/updates/auth/3.3.5/2016_05_11_00_auth.sql
new file mode 100644
index 00000000000..254f3d801d6
--- /dev/null
+++ b/sql/updates/auth/3.3.5/2016_05_11_00_auth.sql
@@ -0,0 +1,6 @@
+--
+DELETE FROM `rbac_permissions` WHERE `id` IN (837,838,839,840);
+INSERT INTO `rbac_permissions` (`id`,`name`) VALUES (837,"Command: .npc evade"), (838,"Command: .pet level"), (839,"Command: .server shutdown force"), (840,"Command: .server restart force");
+
+DELETE FROM `rbac_linked_permissions` WHERE `linkedId` IN (837,838,839,840);
+INSERT INTO `rbac_linked_permissions` (`id`,`linkedId`) VALUES (196,837),(196,838),(196,839),(196,840);
diff --git a/sql/updates/world/3.3.5/2016_04_25_02_world.sql b/sql/updates/world/3.3.5/2016_04_25_02_world.sql
new file mode 100644
index 00000000000..31d98dd616c
--- /dev/null
+++ b/sql/updates/world/3.3.5/2016_04_25_02_world.sql
@@ -0,0 +1,48 @@
+--
+SET @Aura1:=44880;
+SET @Flare:=24916;
+SET @Grow:=44944;
+SET @Visual:=44877;
+SET @MiniExplosion:=44943;
+SET @Unstable:=24958;
+SET @Aura2:=46196;
+SET @Explosion:=46225;
+SET @credit:=44947;
+SET @Flame:=22323;
+
+UPDATE `creature_template` SET `unit_flags`=776, `faction`=1629, `InhabitType`=4, `AIName`='SmartAI' WHERE `entry`in (@Flare, @Unstable);
+UPDATE `creature_template` SET `AIName`='SmartAI' WHERE `entry`in (@Flame);
+
+DELETE FROM `creature_template_addon` WHERE `entry`=@Flare;
+INSERT INTO `creature_template_addon` (`entry`,`bytes2`,`auras`) VALUES (@Flare,1,@Aura1);
+
+DELETE FROM `smart_scripts` WHERE `entryorguid` = @Flame AND `source_type` = 0;
+DELETE FROM `smart_scripts` WHERE `entryorguid` = @Flare AND `source_type` = 0;
+DELETE FROM `smart_scripts` WHERE `entryorguid` = @Flare*100 AND `source_type` = 9;
+DELETE FROM `smart_scripts` WHERE `entryorguid` = @Flare*100+1 AND `source_type` = 9;
+INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES
+(@Flare, 0, 0, 0, 54, 0, 100, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Flare - Just summoned - React passif'),
+(@Flare, 0, 1, 0, 23, 0, 100, 1, @Grow, 8, 0, 0, 80, @Flare*100, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Flare - has aura x 8 - Action list'),
+(@Flare*100, 9, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 11, @MiniExplosion, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Flare - Action list - cast'),
+(@Flare*100, 9, 1, 0, 0, 0, 100, 0, 0, 0, 0, 0, 3, @Unstable, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Flare - Action list - morph'),
+(@Flare*100, 9, 2, 0, 0, 0, 100, 0, 0, 0, 0, 0, 28, @Aura1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Flare - Action list - Remove aura'),
+(@Flare*100, 9, 3, 0, 0, 0, 100, 0, 0, 0, 0, 0, 11, @Aura2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Flare - Action list - Add aura'),
+(@Flare*100, 9, 4, 0, 0, 0, 100, 0, 1000, 1000, 0, 0, 53, 1, @Flare, 0, 0, 500, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Flare - Action list - Start way point'),
+(@Flare, 0, 2, 0, 58, 0, 100, 0, 0, 0, 0, 0, 80, @Flare*100+1, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Unstable - On way point Ended - Action list'),
+(@Flare*100+1, 9, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 11, @Explosion, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Flare - Action list - Cast'),
+(@Flare*100+1, 9, 1, 0, 0, 0, 100, 0, 0, 0, 0, 0, 11, @credit, 0, 0, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 'Unstable - Action list - Cast'),
+(@Flare*100+1, 9, 2, 0, 0, 0, 100, 0, 500, 500, 0, 0, 41, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Flare - Action list - despawn'),
+(@Flare, 0, 3, 0, 38, 0, 100, 0, 1, 1, 0, 0, 11, @Visual, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Flare - On data set- cast'),
+(@Flame, 0, 0, 0, 0, 0, 100, 0, 3000, 3000, 5000, 5000, 11, 36247, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 'Flare - IC - Cast'),
+(@Flame, 0, 1, 0, 6, 0, 100, 0, 0, 0, 0, 0, 45, 1, 1, 0, 0, 0, 0, 19, @Flare, 40, 0, 0, 0, 0, 0, 'Flare - On death - Set Data');
+
+DELETE FROM `waypoints` WHERE `entry`=@Flare;
+INSERT INTO `waypoints` (`entry`,`pointid`,`position_x`,`position_y`,`position_z`,`point_comment`) VALUES
+(@Flare,1, 828.737000, 2509.100098, 300.700012,'Flare');
+
+DELETE FROM `spell_linked_spell` WHERE `spell_trigger` = @Visual;
+INSERT INTO `spell_linked_spell` VALUES (@Visual, @Grow, 0, 'Flare Aura');
+
+DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=13 AND `SourceEntry`=@Visual;
+INSERT INTO `conditions` (`SourceTypeOrReferenceId`,`SourceGroup`,`SourceEntry`,`SourceId`,`ElseGroup`,`ConditionTypeOrReference`,`ConditionTarget`,`ConditionValue1`,`ConditionValue2`,`ConditionValue3`,`NegativeCondition`,`ErrorType`,`ErrorTextId`,`ScriptName`,`Comment`) VALUES
+(13,1,@Visual,0,0,31,0,3,@Flare,0,0,0,0,'','Only the Flare is a target for the spell.');
diff --git a/sql/updates/world/3.3.5/2016_04_25_03_world.sql b/sql/updates/world/3.3.5/2016_04_25_03_world.sql
new file mode 100644
index 00000000000..7bbd279e943
--- /dev/null
+++ b/sql/updates/world/3.3.5/2016_04_25_03_world.sql
@@ -0,0 +1,47 @@
+SET @CGUID := 145119;
+
+DELETE FROM `creature` WHERE `id`=21788;
+INSERT INTO `creature` (`guid`, `id`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`, `modelid`, `equipment_id`, `position_x`, `position_y`, `position_z`, `orientation`, `spawntimesecs`, `spawndist`, `currentwaypoint`, `curhealth`, `curmana`, `MovementType`, `npcflag`, `unit_flags`, `dynamicflags`, `VerifiedBuild`) VALUES
+(@CGUID+0, 21788, 530, 0, 0, 1, 1, 0, 0, -3090.62, 2402.483, 63.14528, 4.310963, 120, 0, 0, 0, 0, 0, 0, 0, 0, 21463), -- 21788 (Area: 0) (Auras: 37509 - 37509)
+(@CGUID+1, 21788, 530, 0, 0, 1, 1, 0, 0, -3115.362, 2440.234, 64.67137, 1.902409, 120, 0, 0, 0, 0, 0, 0, 0, 0, 21463), -- 21788 (Area: 0) (Auras: 37509 - 37509)
+(@CGUID+2, 21788, 530, 0, 0, 1, 1, 0, 0, -3138.009, 2452.761, 63.82878, 4.153883, 120, 0, 0, 0, 0, 0, 0, 0, 0, 21463), -- 21788 (Area: 0) (Auras: 37509 - 37509)
+(@CGUID+3, 21788, 530, 0, 0, 1, 1, 0, 0, -3068.807, 2447.557, 64.62611, 1.380292, 120, 0, 0, 0, 0, 0, 0, 0, 0, 21463), -- 21788 (Area: 0) (Auras: 37509 - 37509)
+(@CGUID+4, 21788, 530, 0, 0, 1, 1, 0, 0, -3125.387, 2489.521, 62.06233, 5.113815, 120, 0, 0, 0, 0, 0, 0, 0, 0, 21463), -- 21788 (Area: 0) (Auras: 37509 - 37509)
+(@CGUID+5, 21788, 530, 0, 0, 1, 1, 0, 0, -3061.514, 2459.645, 65.18143, 4.520403, 120, 0, 0, 0, 0, 0, 0, 0, 0, 21463), -- 21788 (Area: 0) (Auras: 37509 - 37509)
+(@CGUID+6, 21788, 530, 0, 0, 1, 1, 0, 0, -3122.754, 2501.015, 62.70392, 5.51524, 120, 0, 0, 0, 0, 0, 0, 0, 0, 21463), -- 21788 (Area: 0) (Auras: 37509 - 37509)
+(@CGUID+7, 21788, 530, 0, 0, 1, 1, 0, 0, -3034.208, 2499.923, 63.14324, 1.48353, 120, 0, 0, 0, 0, 0, 0, 0, 0, 21463), -- 21788 (Area: 0) (Auras: 37509 - 37509)
+(@CGUID+8, 21788, 530, 0, 0, 1, 1, 0, 0, -3079.527, 2527.942, 62.65857, 0.1570796, 120, 0, 0, 0, 0, 0, 0, 0, 0, 21463), -- 21788 (Area: 0) (Auras: 37509 - 37509)
+(@CGUID+9, 21788, 530, 0, 0, 1, 1, 0, 0, -3067.415, 2495.909, 64.73977, 1.570796, 120, 0, 0, 0, 0, 0, 0, 0, 0, 21463), -- 21788 (Area: 0) (Auras: 37509 - 37509)
+(@CGUID+10, 21788, 530, 0, 0, 1, 1, 0, 0, -3130.252, 2537.187, 61.81245, 0.9250245, 120, 0, 0, 0, 0, 0, 0, 0, 0, 21463), -- 21788 (Area: 3744) (Auras: 37509 - 37509)
+(@CGUID+11, 21788, 530, 0, 0, 1, 1, 0, 0, -3036.085, 2528.19, 63.41149, 5.166174, 120, 0, 0, 0, 0, 0, 0, 0, 0, 21463), -- 21788 (Area: 3744) (Auras: 37509 - 37509)
+(@CGUID+12, 21788, 530, 0, 0, 1, 1, 0, 0, -3001.511, 2507.445, 61.33947, 1.553343, 120, 0, 0, 0, 0, 0, 0, 0, 0, 21463), -- 21788 (Area: 3744) (Auras: 37509 - 37509)
+(@CGUID+13, 21788, 530, 0, 0, 1, 1, 0, 0, -3020.436, 2502.759, 62.7676, 0.296706, 120, 0, 0, 0, 0, 0, 0, 0, 0, 21463), -- 21788 (Area: 3744) (Auras: 37509 - 37509)
+(@CGUID+14, 21788, 530, 0, 0, 1, 1, 0, 0, -3061.437, 2541.203, 62.35847, 4.361612, 120, 0, 0, 0, 0, 0, 0, 0, 0, 21463), -- 21788 (Area: 3744) (Auras: 37509 - 37509)
+(@CGUID+15, 21788, 530, 0, 0, 1, 1, 0, 0, -3022.704, 2512.111, 68.65653, 0.3839724, 120, 0, 0, 0, 0, 0, 0, 0, 0, 21463), -- 21788 (Area: 3744) (Auras: 37509 - 37509)
+(@CGUID+16, 21788, 530, 0, 0, 1, 1, 0, 0, -3016.363, 2549.719, 79.11957, 1.291544, 120, 0, 0, 0, 0, 0, 0, 0, 0, 21463), -- 21788 (Area: 3744) (Auras: 37509 - 37509)
+(@CGUID+17, 21788, 530, 0, 0, 1, 1, 0, 0, -3104.333, 2552.007, 61.75181, 5.380099, 120, 0, 0, 0, 0, 0, 0, 0, 0, 21463), -- 21788 (Area: 3744) (Auras: 37509 - 37509)
+(@CGUID+18, 21788, 530, 0, 0, 1, 1, 0, 0, -3115.356, 2556.791, 61.91945, 0.3141593, 120, 0, 0, 0, 0, 0, 0, 0, 0, 21463), -- 21788 (Area: 3744) (Auras: 37509 - 37509)
+(@CGUID+19, 21788, 530, 0, 0, 1, 1, 0, 0, -3133.627, 2548.74, 62.05401, 6.195919, 120, 0, 0, 0, 0, 0, 0, 0, 0, 21463), -- 21788 (Area: 3744) (Auras: 37509 - 37509)
+(@CGUID+20, 21788, 530, 0, 0, 1, 1, 0, 0, -2985.531, 2556.819, 76.62669, 3.961897, 120, 0, 0, 0, 0, 0, 0, 0, 0, 21463), -- 21788 (Area: 3744) (Auras: 37509 - 37509)
+(@CGUID+21, 21788, 530, 0, 0, 1, 1, 0, 0, -2987.325, 2568.416, 76.62669, 5.846853, 120, 0, 0, 0, 0, 0, 0, 0, 0, 21463), -- 21788 (Area: 3744) (Auras: 37509 - 37509)
+(@CGUID+22, 21788, 530, 0, 0, 1, 1, 0, 0, -3116.468, 2572.71, 61.88921, 0.1047198, 120, 0, 0, 0, 0, 0, 0, 0, 0, 21463), -- 21788 (Area: 3744) (Auras: 37509 - 37509)
+(@CGUID+23, 21788, 530, 0, 0, 1, 1, 0, 0, -3090.439, 2579.877, 61.85312, 4.817109, 120, 0, 0, 0, 0, 0, 0, 0, 0, 21463), -- 21788 (Area: 3744) (Auras: 37509 - 37509)
+(@CGUID+24, 21788, 530, 0, 0, 1, 1, 0, 0, -3147.669, 2577.585, 62.38097, 1.867502, 120, 0, 0, 0, 0, 0, 0, 0, 0, 21463), -- 21788 (Area: 3744) (Auras: 37509 - 37509)
+(@CGUID+25, 21788, 530, 0, 0, 1, 1, 0, 0, -3133.15, 2585.913, 61.80721, 2.86234, 120, 0, 0, 0, 0, 0, 0, 0, 0, 21463), -- 21788 (Area: 3744) (Auras: 37509 - 37509)
+(@CGUID+26, 21788, 530, 0, 0, 1, 1, 0, 0, -3073.789, 2609.983, 61.81239, 1.117011, 120, 0, 0, 0, 0, 0, 0, 0, 0, 21463), -- 21788 (Area: 3744) (Auras: 37509 - 37509)
+(@CGUID+27, 21788, 530, 0, 0, 1, 1, 0, 0, -3163.902, 2579.588, 62.70355, 0.4886922, 120, 0, 0, 0, 0, 0, 0, 0, 0, 21463), -- 21788 (Area: 3744) (Auras: 37509 - 37509)
+(@CGUID+28, 21788, 530, 0, 0, 1, 1, 0, 0, -3144.146, 2617.151, 61.85558, 3.752458, 120, 0, 0, 0, 0, 0, 0, 0, 0, 21463), -- 21788 (Area: 3744) (Auras: 37509 - 37509)
+(@CGUID+29, 21788, 530, 0, 0, 1, 1, 0, 0, -2963.017, 2518.091, 78.19579, 0.1047198, 120, 0, 0, 0, 0, 0, 0, 0, 0, 21463), -- 21788 (Area: 3744) (Auras: 37509 - 37509)
+(@CGUID+30, 21788, 530, 0, 0, 1, 1, 0, 0, -2965.681, 2540.958, 76.62669, 4.45059, 120, 0, 0, 0, 0, 0, 0, 0, 0, 21463), -- 21788 (Area: 3744) (Auras: 37509 - 37509)
+(@CGUID+31, 21788, 530, 0, 0, 1, 1, 0, 0, -2977.325, 2574.976, 76.62669, 1.413717, 120, 0, 0, 0, 0, 0, 0, 0, 0, 21463), -- 21788 (Area: 3744) (Auras: 37509 - 37509)
+(@CGUID+32, 21788, 530, 0, 0, 1, 1, 0, 0, -2999.423, 2619.978, 76.7438, 1.658063, 120, 0, 0, 0, 0, 0, 0, 0, 0, 21463), -- 21788 (Area: 3744) (Auras: 37509 - 37509)
+(@CGUID+33, 21788, 530, 0, 0, 1, 1, 0, 0, -3046.553, 2641.27, 76.62669, 5.916666, 120, 0, 0, 0, 0, 0, 0, 0, 0, 21463), -- 21788 (Area: 3744) (Auras: 37509 - 37509)
+(@CGUID+34, 21788, 530, 0, 0, 1, 1, 0, 0, -3028.977, 2656.449, 77.04675, 4.206244, 120, 0, 0, 0, 0, 0, 0, 0, 0, 21463), -- 21788 (Area: 3744) (Auras: 37509 - 37509)
+(@CGUID+35, 21788, 530, 0, 0, 1, 1, 0, 0, -2945.421, 2632.53, 91.97811, 3.910418, 120, 0, 0, 0, 0, 0, 0, 0, 0, 21463), -- 21788 (Area: 3744) (Auras: 37509 - 37509)
+(@CGUID+36, 21788, 530, 0, 0, 1, 1, 0, 0, -2907.585, 2603.013, 93.76357, 2.426008, 120, 0, 0, 0, 0, 0, 0, 0, 0, 21463), -- 21788 (Area: 3744) (Auras: 37509 - 37509)
+(@CGUID+37, 21788, 530, 0, 0, 1, 1, 0, 0, -2903.634, 2615.304, 93.76357, 3.071779, 120, 0, 0, 0, 0, 0, 0, 0, 0, 21463), -- 21788 (Area: 3744) (Auras: 37509 - 37509)
+(@CGUID+38, 21788, 530, 0, 0, 1, 1, 0, 0, -2926.175, 2646.125, 93.73645, 3.682645, 120, 0, 0, 0, 0, 0, 0, 0, 0, 21463), -- 21788 (Area: 3744) (Auras: 37509 - 37509)
+(@CGUID+39, 21788, 530, 0, 0, 1, 1, 0, 0, -2932.268, 2652.535, 93.76186, 3.961897, 120, 0, 0, 0, 0, 0, 0, 0, 0, 21463), -- 21788 (Area: 3744) (Auras: 37509 - 37509)
+(@CGUID+40, 21788, 530, 0, 0, 1, 1, 0, 0, -2939.042, 2675.208, 93.76357, 4.433136, 120, 0, 0, 0, 0, 0, 0, 0, 0, 21463); -- 21788 (Area: 3744) (Auras: 37509 - 37509)
+
+UPDATE `creature_template_addon` SET `bytes1`=65536, `bytes2`=1 WHERE `entry`=21788;
diff --git a/sql/updates/world/3.3.5/2016_04_26_00_world.sql b/sql/updates/world/3.3.5/2016_04_26_00_world.sql
new file mode 100644
index 00000000000..72201221944
--- /dev/null
+++ b/sql/updates/world/3.3.5/2016_04_26_00_world.sql
@@ -0,0 +1,9 @@
+--
+UPDATE `creature_template` SET `flags_extra`=`flags_extra`|128 WHERE `entry` IN (33395,14031,22586,22585,14030,22584,14027,22583,14028,14029,22581,14026,33402,31878,33691,33942,34189,31462,37634,34153,39011,39012,39013,20654,31461,31670,33907,33906,33353,33352,34228,31875,30757,21584,34131,26337);
+UPDATE `creature_template` SET `flags_extra`=`flags_extra`|2 WHERE `entry`=30777;
+
+UPDATE `creature_template` SET `flags_extra`=`flags_extra`|130 WHERE `entry` IN (21625,31874);
+
+UPDATE `creature_template` SET `flags_extra`=`flags_extra`|256 WHERE `entry` IN (20596,20745);
+
+UPDATE `creature_template` SET `flags_extra`=`flags_extra`&~1 WHERE `entry` IN (27309,27308,27307,27303);
diff --git a/sql/updates/world/3.3.5/2016_04_26_01_world.sql b/sql/updates/world/3.3.5/2016_04_26_01_world.sql
new file mode 100644
index 00000000000..2021a40a9e7
--- /dev/null
+++ b/sql/updates/world/3.3.5/2016_04_26_01_world.sql
@@ -0,0 +1,57 @@
+SET @CGUID := 145160;
+
+DELETE FROM `creature` WHERE `id`=21795;
+INSERT INTO `creature` (`guid`, `id`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`, `modelid`, `equipment_id`, `position_x`, `position_y`, `position_z`, `orientation`, `spawntimesecs`, `spawndist`, `currentwaypoint`, `curhealth`, `curmana`, `MovementType`, `npcflag`, `unit_flags`, `dynamicflags`, `VerifiedBuild`) VALUES
+(@CGUID+0, 21795, 530, 0, 0, 1, 1, 0, 0, -3942.646, 2125.487, 96.96626, 5.357957, 120, 5, 0, 0, 0, 1, 0, 0, 0, 21463), -- 21795 (Area: 3745) (Auras: 37509 - 37509)
+(@CGUID+1, 21795, 530, 0, 0, 1, 1, 0, 0, -3943.109, 2193.898, 102.1291, 3.368572, 120, 5, 0, 0, 0, 1, 0, 0, 0, 21463), -- 21795 (Area: 3745) (Auras: 37509 - 37509)
+(@CGUID+2, 21795, 530, 0, 0, 1, 1, 0, 0, -4037.24, 2260.579, 113.4364, 3.5118, 120, 5, 0, 0, 0, 1, 0, 0, 0, 21463), -- 21795 (Area: 3745) (Auras: 37509 - 37509)
+(@CGUID+3, 21795, 530, 0, 0, 1, 1, 0, 0, -4023.835, 2206.558, 109.6129, 4.895111, 120, 5, 0, 0, 0, 1, 0, 0, 0, 21463), -- 21795 (Area: 3745) (Auras: 37509 - 37509)
+(@CGUID+4, 21795, 530, 0, 0, 1, 1, 0, 0, -4030.965, 2168.763, 107.4985, 2.480213, 120, 5, 0, 0, 0, 1, 0, 0, 0, 21463), -- 21795 (Area: 3745) (Auras: 37509 - 37509)
+(@CGUID+5, 21795, 530, 0, 0, 1, 1, 0, 0, -3951.485, 2265.172, 99.24145, 2.606144, 120, 5, 0, 0, 0, 1, 0, 0, 0, 21463), -- 21795 (Area: 3745) (Auras: 37509 - 37509)
+(@CGUID+6, 21795, 530, 0, 0, 1, 1, 0, 0, -4042.551, 2183.728, 109.3237, 3.009561, 120, 5, 0, 0, 0, 1, 0, 0, 0, 21463), -- 21795 (Area: 3745) (Auras: 37509 - 37509)
+(@CGUID+7, 21795, 530, 0, 0, 1, 1, 0, 0, -3984.742, 2197.148, 102.0214, 4.5442, 120, 5, 0, 0, 0, 1, 0, 0, 0, 21463), -- 21795 (Area: 3745) (Auras: 37509 - 37509)
+(@CGUID+8, 21795, 530, 0, 0, 1, 1, 0, 0, -3956.684, 2233.825, 101.9551, 1.479018, 120, 5, 0, 0, 0, 1, 0, 0, 0, 21463), -- 21795 (Area: 3745) (Auras: 37509 - 37509)
+(@CGUID+9, 21795, 530, 0, 0, 1, 1, 0, 0, -4019.452, 2140.292, 104.274, 0.1288698, 120, 5, 0, 0, 0, 1, 0, 0, 0, 21463), -- 21795 (Area: 3745) (Auras: 37509 - 37509)
+(@CGUID+10, 21795, 530, 0, 0, 1, 1, 0, 0, -4006.475, 2120.42, 115.6417, 1.27439, 120, 5, 0, 0, 0, 1, 0, 0, 0, 21463), -- 21795 (Area: 3745) (Auras: 37509 - 37509)
+(@CGUID+11, 21795, 530, 0, 0, 1, 1, 0, 0, -3940.616, 2152.896, 100.4848, 2.463561, 120, 5, 0, 0, 0, 1, 0, 0, 0, 21463), -- 21795 (Area: 3745) (Auras: 37509 - 37509)
+(@CGUID+12, 21795, 530, 0, 0, 1, 1, 0, 0, -4053.673, 2245.217, 112.0474, 0.036458, 120, 5, 0, 0, 0, 1, 0, 0, 0, 21463), -- 21795 (Area: 3745) (Auras: 37509 - 37509)
+(@CGUID+13, 21795, 530, 0, 0, 1, 1, 0, 0, -3939.613, 2223.242, 101.9156, 3.891035, 120, 5, 0, 0, 0, 1, 0, 0, 0, 21463), -- 21795 (Area: 3745) (Auras: 37509 - 37509)
+(@CGUID+14, 21795, 530, 0, 0, 1, 1, 0, 0, -3973.463, 2119.737, 103.7858, 2.866639, 120, 5, 0, 0, 0, 1, 0, 0, 0, 21463), -- 21795 (Area: 3745) (Auras: 37509 - 37509)
+(@CGUID+15, 21795, 530, 0, 0, 1, 1, 0, 0, -3988.523, 2153.718, 104.368, 6.001884, 120, 5, 0, 0, 0, 1, 0, 0, 0, 21463), -- 21795 (Area: 3745) (Auras: 37509 - 37509)
+(@CGUID+16, 21795, 530, 0, 0, 1, 1, 0, 0, -4070.058, 2227.373, 113.4363, 3.759574, 120, 5, 0, 0, 0, 1, 0, 0, 0, 21463), -- 21795 (Area: 3745) (Auras: 37509 - 37509)
+(@CGUID+17, 21795, 530, 0, 0, 1, 1, 0, 0, -4075.326, 2180.252, 107.5067, 3.183229, 120, 5, 0, 0, 0, 1, 0, 0, 0, 21463), -- 21795 (Area: 3745) (Auras: 37509 - 37509)
+(@CGUID+18, 21795, 530, 0, 0, 1, 1, 0, 0, -4054.947, 2124.536, 137.2578, 2.750937, 120, 5, 0, 0, 0, 1, 0, 0, 0, 21463), -- 21795 (Area: 3745) (Auras: 37509 - 37509)
+(@CGUID+19, 21795, 530, 0, 0, 1, 1, 0, 0, -4087.524, 2167.491, 111.391, 5.241858, 120, 5, 0, 0, 0, 1, 0, 0, 0, 21463), -- 21795 (Area: 3745) (Auras: 37509 - 37509)
+(@CGUID+20, 21795, 530, 0, 0, 1, 1, 0, 0, -4089.124, 2203.606, 97.22453, 5.805306, 120, 5, 0, 0, 0, 1, 0, 0, 0, 21463), -- 21795 (Area: 3745) (Auras: 37509 - 37509)
+(@CGUID+21, 21795, 530, 0, 0, 1, 1, 0, 0, -4080.437, 2179.819, 100.2801, 5.450742, 120, 5, 0, 0, 0, 1, 0, 0, 0, 21463), -- 21795 (Area: 3745) (Auras: 37509 - 37509)
+(@CGUID+22, 21795, 530, 0, 0, 1, 1, 0, 0, -4092.307, 2185.567, 100.2807, 0.1027414, 120, 5, 0, 0, 0, 1, 0, 0, 0, 21463), -- 21795 (Area: 3745) (Auras: 37509 - 37509)
+(@CGUID+23, 21795, 530, 0, 0, 1, 1, 0, 0, -4092.907, 2184.13, 106.9471, 5.606272, 120, 5, 0, 0, 0, 1, 0, 0, 0, 21463), -- 21795 (Area: 3745) (Auras: 37509 - 37509)
+(@CGUID+24, 21795, 530, 0, 0, 1, 1, 0, 0, -3918.483, 2046.919, 95.28484, 6.051655, 120, 5, 0, 0, 0, 1, 0, 0, 0, 21463), -- 21795 (Area: 3745) (Auras: 37509 - 37509)
+(@CGUID+25, 21795, 530, 0, 0, 1, 1, 0, 0, -3913.848, 2107.107, 96.72884, 4.46708, 120, 5, 0, 0, 0, 1, 0, 0, 0, 21463), -- 21795 (Area: 3745) (Auras: 37509 - 37509)
+(@CGUID+26, 21795, 530, 0, 0, 1, 1, 0, 0, -3947.833, 2040.741, 95.10477, 1.199215, 120, 5, 0, 0, 0, 1, 0, 0, 0, 21463), -- 21795 (Area: 3745) (Auras: 37509 - 37509)
+(@CGUID+27, 21795, 530, 0, 0, 1, 1, 0, 0, -3915.87, 2102.719, 96.12863, 1.258105, 120, 5, 0, 0, 0, 1, 0, 0, 0, 21463), -- 21795 (Area: 3745) (Auras: 37509 - 37509)
+(@CGUID+28, 21795, 530, 0, 0, 1, 1, 0, 0, -3839.461, 2121.8, 94.53188, 4.859396, 120, 5, 0, 0, 0, 1, 0, 0, 0, 21463), -- 21795 (Area: 3745) (Auras: 37509 - 37509)
+(@CGUID+29, 21795, 530, 0, 0, 1, 1, 0, 0, -3862.718, 2217.159, 95.1391, 3.999115, 120, 5, 0, 0, 0, 1, 0, 0, 0, 21463), -- 21795 (Area: 3745) (Auras: 37509 - 37509)
+(@CGUID+30, 21795, 530, 0, 0, 1, 1, 0, 0, -3849.665, 2175.306, 95.58624, 3.913765, 120, 5, 0, 0, 0, 1, 0, 0, 0, 21463), -- 21795 (Area: 3745) (Auras: 37509 - 37509)
+(@CGUID+31, 21795, 530, 0, 0, 1, 1, 0, 0, -4053.544, 2279.983, 112.0487, 4.612492, 120, 5, 0, 0, 0, 1, 0, 0, 0, 21463), -- 21795 (Area: 3745) (Auras: 37509 - 37509)
+(@CGUID+32, 21795, 530, 0, 0, 1, 1, 0, 0, -4066.031, 2258.548, 94.8257, 1.571143, 120, 5, 0, 0, 0, 1, 0, 0, 0, 21463), -- 21795 (Area: 3745) (Auras: 37509 - 37509)
+(@CGUID+33, 21795, 530, 0, 0, 1, 1, 0, 0, -4054.627, 2277.048, 121.7723, 4.634171, 120, 5, 0, 0, 0, 1, 0, 0, 0, 21463), -- 21795 (Area: 3745) (Auras: 37509 - 37509)
+(@CGUID+34, 21795, 530, 0, 0, 1, 1, 0, 0, -4070.104, 2263.355, 112.0474, 5.739568, 120, 5, 0, 0, 0, 1, 0, 0, 0, 21463), -- 21795 (Area: 3745) (Auras: 37509 - 37509)
+(@CGUID+35, 21795, 530, 0, 0, 1, 1, 0, 0, -4084.999, 2245.3, 121.7718, 5.480127, 120, 5, 0, 0, 0, 1, 0, 0, 0, 21463), -- 21795 (Area: 3745) (Auras: 37509 - 37509)
+(@CGUID+36, 21795, 530, 0, 0, 1, 1, 0, 0, -4087.486, 2244.981, 112.0474, 2.109367, 120, 5, 0, 0, 0, 1, 0, 0, 0, 21463), -- 21795 (Area: 3745) (Auras: 37509 - 37509)
+(@CGUID+37, 21795, 530, 0, 0, 1, 1, 0, 0, -4073.188, 2267.943, 94.82581, 1.50432, 120, 5, 0, 0, 0, 1, 0, 0, 0, 21463), -- 21795 (Area: 3745) (Auras: 37509 - 37509)
+(@CGUID+38, 21795, 530, 0, 0, 1, 1, 0, 0, -4071.124, 2294.895, 110.6591, 0.204018, 120, 5, 0, 0, 0, 1, 0, 0, 0, 21463), -- 21795 (Area: 3745) (Auras: 37509 - 37509)
+(@CGUID+39, 21795, 530, 0, 0, 1, 1, 0, 0, -4101.815, 2259.789, 110.659, 4.624498, 120, 5, 0, 0, 0, 1, 0, 0, 0, 21463), -- 21795 (Area: 3745) (Auras: 37509 - 37509)
+(@CGUID+40, 21795, 530, 0, 0, 1, 1, 0, 0, -4075.109, 2296.344, 121.7728, 2.60921, 120, 5, 0, 0, 0, 1, 0, 0, 0, 21463), -- 21795 (Area: 3745) (Auras: 37509 - 37509)
+(@CGUID+41, 21795, 530, 0, 0, 1, 1, 0, 0, -4094.75, 2260.984, 103.9927, 0.0229529, 120, 5, 0, 0, 0, 1, 0, 0, 0, 21463), -- 21795 (Area: 3745) (Auras: 37509 - 37509)
+(@CGUID+42, 21795, 530, 0, 0, 1, 1, 0, 0, -4088.135, 2265.592, 103.9921, 3.303511, 120, 5, 0, 0, 0, 1, 0, 0, 0, 21463), -- 21795 (Area: 3745) (Auras: 37509 - 37509)
+(@CGUID+43, 21795, 530, 0, 0, 1, 1, 0, 0, -4087.79, 2283.696, 103.9927, 1.226644, 120, 5, 0, 0, 0, 1, 0, 0, 0, 21463), -- 21795 (Area: 3745) (Auras: 37509 - 37509)
+(@CGUID+44, 21795, 530, 0, 0, 1, 1, 0, 0, -4094.398, 2277.201, 112.0475, 1.09602, 120, 5, 0, 0, 0, 1, 0, 0, 0, 21463), -- 21795 (Area: 3745) (Auras: 37509 - 37509)
+(@CGUID+45, 21795, 530, 0, 0, 1, 1, 0, 0, -4071.222, 2290.098, 103.9934, 0.974121, 120, 5, 0, 0, 0, 1, 0, 0, 0, 21463), -- 21795 (Area: 3745) (Auras: 37509 - 37509)
+(@CGUID+46, 21795, 530, 0, 0, 1, 1, 0, 0, -3823.303, 2124.582, 93.3121, 5.473604, 120, 5, 0, 0, 0, 1, 0, 0, 0, 21463), -- 21795 (Area: 3745) (Auras: 37509 - 37509)
+(@CGUID+47, 21795, 530, 0, 0, 1, 1, 0, 0, -3982.052, 1996.922, 95.26698, 6.067729, 120, 5, 0, 0, 0, 1, 0, 0, 0, 21463), -- 21795 (Area: 3745) (Auras: 37509 - 37509)
+(@CGUID+48, 21795, 530, 0, 0, 1, 1, 0, 0, -3830.084, 2177.76, 93.64696, 5.581445, 120, 5, 0, 0, 0, 1, 0, 0, 0, 21463), -- 21795 (Area: 3745) (Auras: 37509 - 37509)
+(@CGUID+49, 21795, 530, 0, 0, 1, 1, 0, 0, -3821.952, 2218.491, 92.7454, 2.951487, 120, 5, 0, 0, 0, 1, 0, 0, 0, 21463), -- 21795 (Area: 3745) (Auras: 37509 - 37509)
+(@CGUID+50, 21795, 530, 0, 0, 1, 1, 0, 0, -3856.967, 2241.917, 97.24121, 0.3141558, 120, 5, 0, 0, 0, 1, 0, 0, 0, 21463); -- 21795 (Area: 3745) (Auras: 37509 - 37509)
+
+UPDATE `creature_template_addon` SET `bytes1`=65536, `bytes2`=1 WHERE `entry`=21795;
diff --git a/sql/updates/world/3.3.5/2016_04_26_02_world.sql b/sql/updates/world/3.3.5/2016_04_26_02_world.sql
new file mode 100644
index 00000000000..4df837e0d8f
--- /dev/null
+++ b/sql/updates/world/3.3.5/2016_04_26_02_world.sql
@@ -0,0 +1,16 @@
+--
+SET @ENTRY := 8035;
+-- Apply taunt sound effect instead of the Avatar of Hakkar's aggro sound
+UPDATE `creature_text` SET `sound`=3216 WHERE `entry` = @ENTRY AND `groupid` = 1 AND `id` = 0;
+-- Apply UNIT_FLAG_DISABLE_MOVE, UNIT_FLAG_PACIFIED, and UNIT_FLAG_DISARMED
+-- Extra OR's are for at-a-glance convenience
+UPDATE `creature_template` SET `unit_flags`= `unit_flags` | 4 | 131072 | 2097152 WHERE `Entry`= @ENTRY;
+-- Inserting an SAI event to make Dark Iron Land Mines not detonate prematurely.
+DELETE FROM `smart_scripts` WHERE `entryorguid` = @ENTRY AND `source_type`=0;
+INSERT INTO `smart_scripts` (`entryorguid`,`source_type`,`id`,`link`,`event_type`,`event_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action_type`,`action_param1`,`action_param2`,`action_param3`,`action_param4`,`action_param5`,`action_param6`,`target_type`,`target_param1`,`target_param2`,`target_param3`,`target_x`,`target_y`,`target_z`,`target_o`,`comment`) VALUES
+(@ENTRY,0,0,0,1,0,100,3,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,'Dark Iron Land Mine - Out of Combat - Say Line 0'),
+(@ENTRY,0,1,0,1,0,100,3,5000,5000,0,0,1,1,0,0,0,0,0,1,0,0,0,0,0,0,0,'Dark Iron Land Mine - Out of Combat - Say Line 1'),
+(@ENTRY,0,2,0,1,0,100,3,10000,10000,0,0,1,2,0,0,0,0,0,1,0,0,0,0,0,0,0,'Dark Iron Land Mine - Out of Combat - Say Line 2'),
+(@ENTRY,0,3,0,1,0,100,3,10000,10000,0,0,19,131072,0,0,0,0,0,1,0,0,0,0,0,0,0,'Dark Iron Land Mine - Out of Combat - Remove Pacified Flag after 10s'),
+(@ENTRY,0,4,0,9,0,100,3,0,8,0,0,11,4043,0,0,0,0,0,1,0,0,0,0,0,0,0,'Dark Iron Land Mine - Within 0-8 Range - Cast \'Detonation\''),
+(@ENTRY,0,5,0,9,0,100,3,0,8,0,0,41,0,0,0,0,0,0,1,0,0,0,0,0,0,0,'Dark Iron Land Mine - Within 0-8 Range - Despawn Instant');
diff --git a/sql/updates/world/3.3.5/2016_04_26_03_world.sql b/sql/updates/world/3.3.5/2016_04_26_03_world.sql
new file mode 100644
index 00000000000..659006afcef
--- /dev/null
+++ b/sql/updates/world/3.3.5/2016_04_26_03_world.sql
@@ -0,0 +1,99 @@
+
+DELETE FROM creature WHERE `id` IN(24277,24516,24517);
+INSERT INTO creature (`guid`, `id`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`, `modelid`, `equipment_id`, `position_x`, `position_y`, `position_z`, `orientation`, `spawntimesecs`, `spawndist`, `currentwaypoint`, `curhealth`, `curmana`, `MovementType`, `npcflag`, `unit_flags`, `dynamicflags`, `VerifiedBuild`) VALUES
+(45211, 24277, 571, 0, 0, 1, 1, 0, 0, 2578.047, -3028.564, 115.3411, 0, 120, 0, 0, 0, 0, 2, 0, 0, 0, 21463), -- 24277 (Area: 4054) (Auras: )
+(114439, 24516, 571, 0, 0, 1, 1, 0, 0, 2245.904, -3021.815, 135.1308, 1.318242, 120, 0, 0, 0, 0, 2, 0, 0, 0, 21463), -- 24516 (Area: 0)
+(114637, 24517, 571, 0, 0, 1, 1, 0, 0, 1886.899, -3555.015, 147.7859, 2.676408, 120, 0, 0, 0, 0, 2, 0, 0, 0, 21463); -- 24517 (Area: 3999) (Auras: 52071 - 52071)
+
+DELETE FROM `waypoint_data` WHERE `id` IN(452110,1144390,1146370);
+
+INSERT INTO `waypoint_data` (`id`, `point`, `position_x`, `position_y`, `position_z`, `orientation`, `delay`, `move_type`, `action`, `action_chance`, `wpguid`) VALUES
+(452110, 1, 2603.876, -3028.025, 117.0937, 0, 0, 0, 0, 100, 0),
+(452110, 2, 2643.243, -3014.203, 104.8926, 0, 0, 0, 0, 100, 0),
+(452110, 3, 2667.486, -3001.944, 99.91364, 0, 0, 0, 0, 100, 0),
+(452110, 4, 2686.615, -2995.257, 94.60037, 0, 0, 0, 0, 100, 0),
+(452110, 5, 2708.851, -2996.379, 92.56187, 0, 0, 0, 0, 100, 0),
+(452110, 6, 2731.851, -2997.098, 91.55309, 0, 0, 0, 0, 100, 0),
+(452110, 7, 2751.252, -3001.074, 89.84369, 0, 0, 0, 0, 100, 0),
+(452110, 8, 2779.356, -3012.149, 91.26218, 0, 0, 0, 0, 100, 0),
+(452110, 9, 2790.117, -3024.486, 94.64268, 0, 0, 0, 0, 100, 0),
+(452110, 10, 2793.189, -3046.271, 97.1767, 0, 0, 0, 0, 100, 0),
+(452110, 11, 2787.66, -3063.327, 99.79316, 0, 0, 0, 0, 100, 0),
+(452110, 12, 2768.723, -3078.092, 104.6359, 0, 0, 0, 0, 100, 0),
+(452110, 13, 2744.823, -3091.001, 111.5423, 0, 0, 0, 0, 100, 0),
+(452110, 14, 2725.268, -3106.576, 111.8766, 0, 0, 0, 0, 100, 0),
+(452110, 15, 2697.289, -3117.357, 110.0175, 0, 0, 0, 0, 100, 0),
+(452110, 16, 2671.67, -3121.725, 118.3925, 0, 0, 0, 0, 100, 0),
+(452110, 17, 2647.262, -3119.072, 123.8932, 0, 0, 0, 0, 100, 0),
+(452110, 18, 2621.482, -3114.164, 127.1552, 0, 0, 0, 0, 100, 0),
+(452110, 19, 2597.5, -3107.631, 127.1276, 0, 0, 0, 0, 100, 0),
+(452110, 20, 2562.354, -3115.057, 123.5328, 0, 0, 0, 0, 100, 0),
+(452110, 21, 2547.443, -3131.256, 128.2941, 0, 0, 0, 0, 100, 0),
+(452110, 22, 2537.48, -3152.528, 130.5185, 0, 0, 0, 0, 100, 0),
+(452110, 23, 2523.183, -3170.009, 137.3546, 0, 0, 0, 0, 100, 0),
+(452110, 24, 2499.98, -3176.15, 146.2999, 0, 0, 0, 0, 100, 0),
+(452110, 25, 2477.218, -3173.943, 146.8427, 0, 0, 0, 0, 100, 0),
+(452110, 26, 2466.798, -3181.938, 148.4451, 0, 0, 0, 0, 100, 0),
+(452110, 27, 2449.986, -3186.217, 148.8962, 0, 0, 0, 0, 100, 0),
+(452110, 28, 2435.967, -3212.301, 150.5083, 0, 0, 0, 0, 100, 0),
+(452110, 29, 2430.812, -3224.802, 150.1544, 0, 0, 0, 0, 100, 0),
+(452110, 30, 2427.15, -3236.885, 149.6805, 0, 0, 0, 0, 100, 0),
+(452110, 31, 2420.321, -3249.048, 148.5472, 0, 0, 0, 0, 100, 0),
+(452110, 32, 2403.638, -3257.211, 150.8997, 0, 0, 0, 0, 100, 0),
+(452110, 33, 2386.398, -3251.84, 150.9332, 0, 0, 0, 0, 100, 0),
+(452110, 34, 2376.512, -3235.288, 151.3786, 0, 0, 0, 0, 100, 0),
+(452110, 35, 2375.435, -3213.906, 154.4518, 0, 0, 0, 0, 100, 0),
+(452110, 36, 2368.87, -3195.879, 154.6864, 0, 0, 0, 0, 100, 0),
+(452110, 37, 2383.123, -3178.886, 155.935, 0, 0, 0, 0, 100, 0),
+(452110, 38, 2398.307, -3176.602, 155.8448, 0, 0, 0, 0, 100, 0),
+(452110, 39, 2412.706, -3183.355, 153.6713, 0, 0, 0, 0, 100, 0),
+(452110, 40, 2436.154, -3172.414, 148.4366, 0, 0, 0, 0, 100, 0),
+(452110, 41, 2439.1, -3152.812, 145.9067, 0, 0, 0, 0, 100, 0),
+(452110, 42, 2423.416, -3137.387, 147.4658, 0, 0, 0, 0, 100, 0),
+(452110, 43, 2420.221, -3122.801, 146.8984, 0, 0, 0, 0, 100, 0),
+(452110, 44, 2432.173, -3109.894, 147.6966, 0, 0, 0, 0, 100, 0),
+(452110, 45, 2443.513, -3098.615, 147.4875, 0, 0, 0, 0, 100, 0),
+(452110, 46, 2458.256, -3078.243, 142.1544, 0, 0, 0, 0, 100, 0),
+(452110, 47, 2475.883, -3064.164, 139.0425, 0, 0, 0, 0, 100, 0),
+(452110, 48, 2507.794, -3040.304, 124.8166, 0, 0, 0, 0, 100, 0),
+(452110, 49, 2531.649, -3026.078, 119.3878, 0, 0, 0, 0, 100, 0),
+(452110, 50, 2560.749, -3028.565, 114.5343, 0, 0, 0, 0, 100, 0),
+(452110, 51, 2582.748, -3028.564, 115.9288, 0, 0, 0, 0, 100, 0),
+(1144390, 1, 2261.844 , -2975.589 , 137.7219, 0, 0, 0, 0, 100, 0),
+(1144390, 2, 2288.57 , -2967.957 , 134.1304, 0, 0, 0, 0, 100, 0),
+(1144390, 3, 2312.078 , -2973.851 , 131.6859, 0, 0, 0, 0, 100, 0),
+(1144390, 4, 2327.24 , -2996.011 , 135.0435, 0, 0, 0, 0, 100, 0),
+(1144390, 5, 2319.611 , -3020.818 , 136.6337, 0, 0, 0, 0, 100, 0),
+(1144390, 6, 2293.551 , -3033.061 , 136.8072, 0, 0, 0, 0, 100, 0),
+(1144390, 7, 2270.958 , -3049.189 , 136.8092, 0, 0, 0, 0, 100, 0),
+(1144390, 8, 2261.982 , -3069.591 , 137.1458, 0, 0, 0, 0, 100, 0),
+(1144390, 9, 2244.48 , -3111.4 , 136.8513, 0, 0, 0, 0, 100, 0),
+(1144390, 10, 2234.337 , -3129.741 , 138.2859, 0, 0, 0, 0, 100, 0),
+(1144390, 11, 2205.15 , -3149.454 , 140.4617, 0, 0, 0, 0, 100, 0),
+(1144390, 12, 2178.708 , -3143.635 , 139.101, 0, 0, 0, 0, 100, 0),
+(1144390, 13, 2159.131 , -3118.843 , 139.0326, 0, 0, 0, 0, 100, 0),
+(1144390, 14, 2157.424 , -3090.945 , 138.6674, 0, 0, 0, 0, 100, 0),
+(1144390, 15, 2184.693 , -3076.778 , 137.7539, 0, 0, 0, 0, 100, 0),
+(1144390, 16, 2205.282 , -3067.448 , 138.6362, 0, 0, 0, 0, 100, 0),
+(1144390, 17, 2241.108 , -3040.399 , 136.0237, 0, 0, 0, 0, 100, 0),
+(1144390, 18, 2251.254 , -3001.044 , 135.3165, 0, 0, 0, 0, 100, 0),
+(1146370, 1, 1851.814 , -3531.93 , 143.9488, 0, 0, 0, 0, 100, 0),
+(1146370, 2, 1845.242 , -3513.312 , 143.5822, 0, 0, 0, 0, 100, 0),
+(1146370, 3, 1850.21 , -3485.009 , 141.7585, 0, 0, 0, 0, 100, 0),
+(1146370, 4, 1876.234 , -3453.859 , 139.5074, 0, 0, 0, 0, 100, 0),
+(1146370, 5, 1914.745 , -3432.741 , 140.1635, 0, 0, 0, 0, 100, 0),
+(1146370, 6, 1944.544 , -3444.092 , 139.0286, 0, 0, 0, 0, 100, 0),
+(1146370, 7, 1957.72 , -3473.06 , 139.4977, 0, 0, 0, 0, 100, 0),
+(1146370, 8, 1961.842 , -3512.568 , 142.8533, 0, 0, 0, 0, 100, 0),
+(1146370, 9, 1954.096 , -3543.72 , 147.4886, 0, 0, 0, 0, 100, 0),
+(1146370, 10, 1939.206 , -3558.753 , 147.6136, 0, 0, 0, 0, 100, 0),
+(1146370, 11, 1923.051 , -3563.351 , 147.5182, 0, 0, 0, 0, 100, 0),
+(1146370, 12, 1899.894 , -3561.537 , 147.5989, 0, 0, 0, 0, 100, 0),
+(1146370, 13, 1876.972 , -3550.032 , 147.9288, 0, 0, 0, 0, 100, 0);
+
+DELETE FROM `creature_template_addon` WHERE `entry` IN(24516,24517);
+INSERT INTO `creature_template_addon` (`entry`, `path_id`, `mount`, `bytes1`, `bytes2`, `emote`, `auras`) VALUES
+(24516, 1144390, 0, 0, 4097, 0, NULL),
+(24517, 1146370, 0, 0, 4097, 0, NULL);
+
+
diff --git a/sql/updates/world/3.3.5/2016_04_28_00_world.sql b/sql/updates/world/3.3.5/2016_04_28_00_world.sql
new file mode 100644
index 00000000000..377f019f899
--- /dev/null
+++ b/sql/updates/world/3.3.5/2016_04_28_00_world.sql
@@ -0,0 +1,3 @@
+--
+UPDATE `creature_template` SET `ScriptName`="" WHERE `entry`=28033;
+UPDATE `creature_template` SET `ScriptName`="npc_the_etymidian" WHERE `entry`=28092;
diff --git a/sql/updates/world/3.3.5/2016_04_29_00_world.sql b/sql/updates/world/3.3.5/2016_04_29_00_world.sql
new file mode 100644
index 00000000000..14c700c0795
--- /dev/null
+++ b/sql/updates/world/3.3.5/2016_04_29_00_world.sql
@@ -0,0 +1,55 @@
+--
+UPDATE `creature_template` SET `AIName`='SmartAI' WHERE `entry`=29796;
+DELETE FROM `smart_scripts` WHERE `entryorguid`=29796 AND `source_type` = 0;
+INSERT INTO `smart_scripts` (`entryorguid`,`source_type`,`id`,`link`,`event_type`,`event_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action_type`,`action_param1`,`action_param2`,`action_param3`,`action_param4`,`action_param5`,`action_param6`,`target_type`,`target_param1`,`target_param2`,`target_param3`,`target_x`,`target_y`,`target_z`,`target_o`,`comment`) VALUES
+(29796,0,0,0,19,0,100,0,12886,0,0,0,85,55253,0,0,0,0,0,7,0,0,0,0,0,0,0,'Gretta the Arbiter - On quest accept - cast Spell');
+
+DELETE FROM `smart_scripts` WHERE `entryorguid`=29694 AND `source_type` = 0;
+INSERT INTO `smart_scripts` (`entryorguid`,`source_type`,`id`,`link`,`event_type`,`event_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action_type`,`action_param1`,`action_param2`,`action_param3`,`action_param4`,`action_param5`,`action_param6`,`target_type`,`target_param1`,`target_param2`,`target_param3`,`target_x`,`target_y`,`target_z`,`target_o`,`comment`) VALUES
+(29694, 0, 0, 0, 0, 0, 100, 0, 2000, 5000, 10000, 15000, 11, 32736, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, "Hyldsmeet Drakerider - In Combat - Cast 'Mortal Strike'"),
+(29694, 0, 1, 0, 6, 0, 100, 0, 0, 0, 0, 0, 33, 29800, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, "Hyldsmeet Drakerider - On Death - Kill credit Spell");
+
+UPDATE `creature_template` SET `AIName`='SmartAI', `InhabitType`=4, `speed_run`=3.2 WHERE `entry` IN (29679);
+DELETE FROM `smart_scripts` WHERE `entryorguid`=29679 AND `source_type` = 0;
+INSERT INTO `smart_scripts` (`entryorguid`,`source_type`,`id`,`link`,`event_type`,`event_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action_type`,`action_param1`,`action_param2`,`action_param3`,`action_param4`,`action_param5`,`action_param6`,`target_type`,`target_param1`,`target_param2`,`target_param3`,`target_x`,`target_y`,`target_z`,`target_o`,`comment`) VALUES
+(29679, 0, 0, 0, 27, 0, 100, 0, 0, 0, 0, 0, 53, 1, 29679, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Hyldsmeet Proto-Drake - ON PASSENGER_BOARDED - Start waypoint');
+
+DELETE FROM `creature_template_addon` WHERE `entry`=29679;
+INSERT INTO `creature_template_addon` (`entry`, `path_id`, `mount`, `bytes1`, `bytes2`, `emote`, `auras`) VALUES
+(29679, 0, 0, 33554432, 0, 0, '55971');
+
+DELETE FROM `waypoints` WHERE `entry`=29679;
+INSERT INTO `waypoints` (`entry`,`pointid`,`position_x`,`position_y`,`position_z`,`point_comment`) VALUES
+(29679,1,6985.165039, -1662.842163, 868.941956, 'Hyldsmeet Proto-Drake'),
+(29679,2,6935.585449, -1516.853760, 968.493896, 'Hyldsmeet Proto-Drake'),
+(29679,3,6926.762207, -1282.424927, 1127.864380, 'Hyldsmeet Proto-Drake'),
+(29679,4,7365.684082, -644.429688, 1928.750610, 'Hyldsmeet Proto-Drake'),
+(29679,5,7388.145508, -652.783569, 1909.863647, 'Hyldsmeet Proto-Drake'),
+(29679,6,7439.698730, -661.380981, 1887.756714, 'Hyldsmeet Proto-Drake'),
+(29679,7,7494.946777, -650.403015, 1883.039795, 'Hyldsmeet Proto-Drake'),
+(29679,8,7548.416992, -601.006348, 1882.505737, 'Hyldsmeet Proto-Drake'),
+(29679,9,7575.110352, -541.134949, 1881.668701, 'Hyldsmeet Proto-Drake'),
+(29679,10,7550.558594, -458.574036, 1877.870972, 'Hyldsmeet Proto-Drake'),
+(29679,11,7482.576172, -404.054077, 1878.095581, 'Hyldsmeet Proto-Drake'),
+(29679,12,7390.999023, -404.312683, 1882.240234, 'Hyldsmeet Proto-Drake'),
+(29679,13,7324.988770, -455.605713, 1874.051270, 'Hyldsmeet Proto-Drake'),
+(29679,14,7289.477051, -552.180786, 1879.989258, 'Hyldsmeet Proto-Drake'),
+(29679,15,7332.199707, -623.493713, 1887.427734, 'Hyldsmeet Proto-Drake'),
+(29679,16,7367.857910, -647.534546, 1895.689453, 'Hyldsmeet Proto-Drake'),
+(29679,17,7388.145508, -652.783569, 1909.863647, 'Hyldsmeet Proto-Drake'),
+(29679,18,7439.698730, -661.380981, 1887.756714, 'Hyldsmeet Proto-Drake'),
+(29679,19,7494.946777, -650.403015, 1883.039795, 'Hyldsmeet Proto-Drake'),
+(29679,20,7548.416992, -601.006348, 1882.505737, 'Hyldsmeet Proto-Drake'),
+(29679,21,7575.110352, -541.134949, 1881.668701, 'Hyldsmeet Proto-Drake'),
+(29679,22,7550.558594, -458.574036, 1877.870972, 'Hyldsmeet Proto-Drake'),
+(29679,23,7482.576172, -404.054077, 1878.095581, 'Hyldsmeet Proto-Drake'),
+(29679,24,7390.999023, -404.312683, 1882.240234, 'Hyldsmeet Proto-Drake'),
+(29679,25,7324.988770, -455.605713, 1874.051270, 'Hyldsmeet Proto-Drake'),
+(29679,26,7289.477051, -552.180786, 1879.989258, 'Hyldsmeet Proto-Drake'),
+(29679,27,7332.199707, -623.493713, 1887.427734, 'Hyldsmeet Proto-Drake'),
+(29679,28,6926.762207, -1282.424927, 1127.864380, 'Hyldsmeet Proto-Drake'),
+(29679,29,6935.585449, -1516.853760, 968.493896, 'Hyldsmeet Proto-Drake'),
+(29679,30,6985.165039, -1662.842163, 868.941956, 'Hyldsmeet Proto-Drake'),
+(29679,31,6998.042969, -1664.234253, 867.953247, 'Hyldsmeet Proto-Drake'),
+(29679,32,7037.400879, -1725.409302, 838.695618, 'Hyldsmeet Proto-Drake'),
+(29679,33,7076.637695, -1770.263184, 825.775391, 'Hyldsmeet Proto-Drake');
diff --git a/sql/updates/world/3.3.5/2016_04_29_01_world.sql b/sql/updates/world/3.3.5/2016_04_29_01_world.sql
new file mode 100644
index 00000000000..c5b0311e1bc
--- /dev/null
+++ b/sql/updates/world/3.3.5/2016_04_29_01_world.sql
@@ -0,0 +1,5 @@
+DELETE FROM `vehicle_template_accessory` WHERE `entry`=29460;
+INSERT INTO `vehicle_template_accessory` (`entry`, `accessory_entry`, `seat_id`, `minion`, `description`, `summontype`, `summontimer`) VALUES
+(29460, 29458, 0, 1, "Brunnhildar Drakerider", 8, 0);
+
+UPDATE `npc_spellclick_spells` SET `spell_id`=46598 WHERE `npc_entry`=29460;
diff --git a/sql/updates/world/3.3.5/2016_05_01_00_world.sql b/sql/updates/world/3.3.5/2016_05_01_00_world.sql
new file mode 100644
index 00000000000..5a4d6c3197e
--- /dev/null
+++ b/sql/updates/world/3.3.5/2016_05_01_00_world.sql
@@ -0,0 +1 @@
+DELETE FROM `trinity_string` WHERE `entry`=5007;
diff --git a/sql/updates/world/3.3.5/2016_05_01_01_world.sql b/sql/updates/world/3.3.5/2016_05_01_01_world.sql
new file mode 100644
index 00000000000..30096e55335
--- /dev/null
+++ b/sql/updates/world/3.3.5/2016_05_01_01_world.sql
@@ -0,0 +1,68 @@
+DELETE FROM `waypoints` WHERE `entry`=28308;
+INSERT INTO `waypoints` (`entry`, `pointid`, `position_x`, `position_y`, `position_z`, `point_comment`) VALUES
+(28308, 1, 5268.226 ,4425.439 ,-95.55899, 'Captive Crocolisk'),
+(28308, 2, 5249.557 ,4405.892 ,-96.04365, 'Captive Crocolisk'),
+(28308, 3, 5266.678 ,4365.464 ,-98.19455, 'Captive Crocolisk'),
+(28308, 4, 5289.138 ,4366.553 ,-102.234, 'Captive Crocolisk'),
+(28308, 5, 5330.018 ,4363.27 ,-121.0311, 'Captive Crocolisk'),
+(28308, 6, 5349.229 ,4341.059 ,-134.0126, 'Captive Crocolisk'),
+(28308, 7, 5365.038 ,4333.716 ,-141.5817, 'Captive Crocolisk'),
+(28308, 8, 5405.443 ,4307.841 ,-142.03, 'Captive Crocolisk'),
+(28308, 9, 5434.999 ,4305.659 ,-136.4706, 'Captive Crocolisk'),
+(28308, 10, 5464.708 ,4302.066 ,-133.1981, 'Captive Crocolisk'),
+(28308, 11, 5490.555 ,4294.395 ,-127.5203, 'Captive Crocolisk'),
+(28308, 12, 5503.808 ,4269.717 ,-110.3168, 'Captive Crocolisk'),
+(28308, 13, 5518.324 ,4255.308 ,-103.0638, 'Captive Crocolisk'),
+(28308, 14, 5540.53 ,4259.77 ,-102.3979, 'Captive Crocolisk'),
+(28308, 15, 5564.194 ,4263.45 ,-102.7574, 'Captive Crocolisk'),
+(28308, 16, 5585.45 ,4261.137 ,-99.54807, 'Captive Crocolisk'),
+(28308, 17, 5609.614 ,4259.657 ,-98.87333, 'Captive Crocolisk'),
+(28308, 18, 5633.434 ,4259.228 ,-98.53442, 'Captive Crocolisk'),
+(28308, 19, 5660.568 ,4260.985 ,-98.63537, 'Captive Crocolisk'),
+(28308, 20, 5681.639 ,4266.31 ,-99.26748, 'Captive Crocolisk'),
+(28308, 21, 5708.126 ,4273.348 ,-102.9183, 'Captive Crocolisk'),
+(28308, 22, 5748.732 ,4284.135 ,-112.0557, 'Captive Crocolisk'),
+(28308, 23, 5839.82 ,4368.61 ,-112.0805, 'Captive Crocolisk'),
+(28308, 24, 5897.276 ,4408.44 ,-95.25065, 'Captive Crocolisk'),
+(28308, 25, 5925.311 ,4440.624 ,-94.77592, 'Captive Crocolisk'),
+(28308, 26, 5953.005 ,4476.29 ,-94.3763, 'Captive Crocolisk'),
+(28308, 27, 5964.229 ,4503.729 ,-92.81553, 'Captive Crocolisk'),
+(28308, 28, 5960.583 ,4546.558 ,-95.65462, 'Captive Crocolisk'),
+(28308, 29, 5965.167 ,4579.141 ,-97.39779, 'Captive Crocolisk'),
+(28308, 30, 5969.295 ,4613.739 ,-98.05751, 'Captive Crocolisk'),
+(28308, 31, 5975.809 ,4659.289 ,-99.27143, 'Captive Crocolisk'),
+(28308, 32, 5992.961 ,4699.554 ,-99.30317, 'Captive Crocolisk'),
+(28308, 33, 6015.139 ,4743.752 ,-97.52377, 'Captive Crocolisk'),
+(28308, 34, 6035.183 ,4788.787 ,-94.66938, 'Captive Crocolisk'),
+(28308, 35, 6064.951 ,4827.502 ,-94.54885, 'Captive Crocolisk'),
+(28308, 36, 6065.57 ,4870.553 ,-94.47726, 'Captive Crocolisk'),
+(28308, 37, 6096.612 ,4885.741 ,-94.44479, 'Captive Crocolisk'),
+(28308, 38, 6120.387 ,4902.048 ,-95.06882, 'Captive Crocolisk'),
+(28308, 39, 6139.616 ,4913.349 ,-94.8635, 'Captive Crocolisk'),
+(28308, 40, 6141.208, 4914.293, -92.7175, 'Captive Crocolisk');
+
+UPDATE `creature_template` SET `AIName`='SmartAI', `InhabitType`=4 WHERE `entry`=28307;
+UPDATE `smart_scripts` SET `link`=1 WHERE `entryorguid`=28298 AND `source_type`=0 AND `id`=0 AND `link`=0;
+
+DELETE FROM `smart_scripts` WHERE `entryorguid`IN(28307,28308) AND `source_type`=0;
+DELETE FROM `smart_scripts` WHERE `entryorguid`IN(28216) AND `source_type`=0 AND `id`>17;
+DELETE FROM `smart_scripts` WHERE `entryorguid`IN(28298) AND `source_type`=0 AND `id`=1;
+
+INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES
+(28216, 0, 18, 19, 38, 0, 100, 0, 1, 3, 0, 0, 1, 6, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Zepik the Gorloc Hunter - On Data Set 1 3 - Say Line 6'),
+(28216, 0, 19, 0, 61, 0, 100, 0, 0, 0, 0, 0, 41, 3000, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Zepik the Gorloc Hunter - On Data Set 1 3 - Despawn'),
+(28298, 0, 1, 0, 61, 0, 100, 0, 0, 0, 0, 0, 45, 1, 3, 0, 0, 0, 0, 19, 28216, 0, 0, 0, 0, 0, 0, 'Captive Crocolisk - On Gossip Option 0 Selected - Set Data on Zepik'),
+(28307, 0, 0, 0, 1, 0, 100, 0, 0, 0, 3000, 3000, 11, 51256, 0, 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Croclisk Chain Bunny - OOC - Cast Captive Crocolisk Chains'),
+(28308, 0, 0, 0, 54, 0, 100, 0, 0, 0, 0, 0, 80, 2830800, 0, 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Captive Crocolisk - On Just Summoned - Run Script (Phase 1) (No Repeat)'),
+(28308, 0, 1, 2, 40, 0, 100, 0, 39, 0, 0, 0, 11, 50630, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Captive Crocolisk - On reached WP42 - Cast Eject All Passengers'),
+(28308, 0, 2, 3, 61, 0, 100, 0, 0, 0, 0, 0, 15, 12536, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 'Captive Crocolisk - On reached WP42 - Quest Credit \'A Rough Ride\''),
+(28308, 0, 3, 0, 61, 0, 100, 0, 0, 0, 0, 0, 85, 52545, 2, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 'Captive Crocolisk - On reached WP42 - Cast Forceitem Zepik'),
+(28308, 0, 4, 0, 40, 0, 100, 0, 40, 0, 0, 0, 41, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Captive Crocolisk - On reached WP43 - Despawn');
+
+DELETE FROM `creature_text` WHERE `entry`=28216 AND `groupid`=6;
+INSERT INTO `creature_text` (`entry`, `groupid`, `id`, `text`, `type`, `language`, `probability`, `emote`, `duration`, `sound`, `BroadcastTextId`, `TextRange`, `comment`) VALUES
+(28216, 6, 0, 'Enjoy ride! Call me when you get there.', 12, 0, 100, 0, 0, 0, 28881, 0, 'Zepik');
+
+DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=13 AND `SourceEntry`=51256;
+INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES
+(13, 1, 51256, 0, 0, 31, 0, 3, 28298, 0, 0, 0, 0, '', 'Captive Crocolisk Chains targets captive crocolisk');
diff --git a/sql/updates/world/3.3.5/2016_05_02_00_world.sql b/sql/updates/world/3.3.5/2016_05_02_00_world.sql
new file mode 100644
index 00000000000..2063baf1ad7
--- /dev/null
+++ b/sql/updates/world/3.3.5/2016_05_02_00_world.sql
@@ -0,0 +1,14 @@
+UPDATE `smart_scripts` SET `link`=5 WHERE `entryorguid`=28082 AND `source_type`=0 AND `id` IN(0,1) AND `link`=0;
+UPDATE `smart_scripts` SET `link`=6 WHERE `entryorguid`=28082 AND `source_type`=0 AND `id` IN(2,3) AND `link`=0;
+UPDATE `smart_scripts` SET `link`=7 WHERE `entryorguid`=28082 AND `source_type`=0 AND `id` IN(4) AND `link`=0;
+
+DELETE FROM `smart_scripts` WHERE `entryorguid`=28082 AND `source_type`=0 AND `id` IN(5,6,7);
+DELETE FROM `smart_scripts` WHERE `entryorguid`=28027 AND `source_type`=0 AND `id` IN(9,10,11);
+
+INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES
+(28082, 0, 5, 0, 61, 0, 100, 0, 0, 0, 0, 0, 85, 51186, 2, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 'High-Shaman Rakjak - Link - Cast Summon Goregek the Bristlepine Hunter'),
+(28082, 0, 6, 0, 61, 0, 100, 0, 0, 0, 0, 0, 85, 51188, 2, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 'High-Shaman Rakjak - Link - Cast Summon Dajik the Wasp Hunter'),
+(28082, 0, 7, 0, 61, 0, 100, 0, 0, 0, 0, 0, 85, 51189, 2, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 'High-Shaman Rakjak - Link - Cast Summon Zepik the Gorloc Hunter'),
+(28027, 0, 9, 0, 19, 0, 100, 0, 12571, 0, 0, 0, 85, 51190, 2, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 'High-Oracle Soo-say - On Quest Accept - Cast Summon Lafoo'),
+(28027, 0, 10, 0, 19, 0, 100, 0, 12574, 0, 0, 0, 85, 51191, 2, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 'High-Oracle Soo-say - On Quest Accept - Cast Summon Jaloot'),
+(28027, 0, 11, 0, 19, 0, 100, 0, 12578, 0, 0, 0, 85, 51192, 2, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 'High-Oracle Soo-say - On Quest Accept - Cast Summon Moodle');
diff --git a/sql/updates/world/3.3.5/2016_05_02_01_world.sql b/sql/updates/world/3.3.5/2016_05_02_01_world.sql
new file mode 100644
index 00000000000..1671abee38f
--- /dev/null
+++ b/sql/updates/world/3.3.5/2016_05_02_01_world.sql
@@ -0,0 +1,18 @@
+-- Beaten Corpse (Mankrik's wife) in quest 4921 "Lost in Battle":
+UPDATE `creature_template` SET `gossip_menu_id`= 2871 WHERE `entry`= 10668;
+
+-- new gossip_menu.entry for creature 10668 (Beaten Corpse):
+DELETE FROM `gossip_menu` WHERE `entry` IN (2871,2872) AND `text_id` IN (3557,3558);
+INSERT INTO `gossip_menu` (`entry`,`text_id`) VALUES
+(2871, 3557),
+(2872, 3558);
+
+-- new gossip_menu_option for creature 10668 (Beaten Corpse):
+DELETE FROM `gossip_menu_option` WHERE `menu_id`= 2871 AND `OptionBroadcastTextID`= 5964;
+INSERT INTO `gossip_menu_option` (`menu_id`,`id`,`option_icon`,`option_text`,`OptionBroadcastTextID`,`option_id`,`npc_option_npcflag`,`action_menu_id`,`action_poi_id`,`box_coded`,`box_money`,`box_text`,`BoxBroadcastTextID`) VALUES
+(2871, 0, 0, 'I inspect the body further.', 5964, 1, 1, 2872, 0, 0, 0, '', 0);
+
+-- condition for gossip_menu_option 2871 in Quest ID 4921 "Lost in Battle":
+DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`= 15 AND `SourceGroup`= 2871;
+INSERT INTO `conditions` (`SourceTypeOrReferenceId`,`SourceGroup`,`SourceEntry`,`SourceId`,`ElseGroup`,`ConditionTypeOrReference`,`ConditionTarget`,`ConditionValue1`,`ConditionValue2`,`ConditionValue3`,`NegativeCondition`,`ErrorType`,`ErrorTextId`,`ScriptName`,`Comment`) VALUES
+(15, 2871,0, 0,0, 9,0, 4921, 0,0,0,0,0, '', 'Show gossip menu option 2871 only if Quest 4921 is taken (active)');
diff --git a/sql/updates/world/3.3.5/2016_05_04_00_world.sql b/sql/updates/world/3.3.5/2016_05_04_00_world.sql
new file mode 100644
index 00000000000..e4043768774
--- /dev/null
+++ b/sql/updates/world/3.3.5/2016_05_04_00_world.sql
@@ -0,0 +1 @@
+DELETE FROM `spell_linked_spell` WHERE `spell_trigger`=70157 AND `spell_effect`=69700 AND `type`=2;
diff --git a/sql/updates/world/3.3.5/2016_05_04_01_world.sql b/sql/updates/world/3.3.5/2016_05_04_01_world.sql
new file mode 100644
index 00000000000..8a40bd66b2a
--- /dev/null
+++ b/sql/updates/world/3.3.5/2016_05_04_01_world.sql
@@ -0,0 +1,69 @@
+SET @CGUID := 84723;
+
+UPDATE `creature_template` SET `InhabitType`=4 WHERE `entry`in(29066);
+
+DELETE FROM creature WHERE `id` IN(28069,28840);
+INSERT INTO creature (`guid`, `id`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`, `modelid`, `equipment_id`, `position_x`, `position_y`, `position_z`, `orientation`, `spawntimesecs`, `spawndist`, `currentwaypoint`, `curhealth`, `curmana`, `MovementType`, `npcflag`, `unit_flags`, `dynamicflags`, `VerifiedBuild`) VALUES
+(@CGUID+0, 28069, 571, 0, 0, 1, 1, 0, 0, 5734.697, 3308.838, 299.8264, 1.867502, 120, 0, 0, 0, 0, 0, 0, 0, 0, 21463), -- 28069 (Area: 0)
+(@CGUID+1, 28069, 571, 0, 0, 1, 1, 0, 0, 5728.474, 3438.191, 300.8422, 0.1060605, 120, 0, 0, 0, 0, 2, 0, 0, 0, 21463), -- 28069 (Area: 0)
+(@CGUID+2, 28069, 571, 0, 0, 1, 1, 0, 0, 5717.042, 3428.265, 300.9259, 1.797689, 120, 0, 0, 0, 0, 0, 0, 0, 0, 21463), -- 28069 (Area: 0)
+(@CGUID+3, 28069, 571, 0, 0, 1, 1, 0, 0, 5697.737, 3426.803, 300.9259, 1.570796, 120, 0, 0, 0, 0, 0, 0, 0, 0, 21463), -- 28069 (Area: 0)
+(@CGUID+4, 28069, 571, 0, 0, 1, 1, 0, 0, 5738.866, 3156.665, 293.8326, 4.814398, 120, 0, 0, 0, 0, 2, 0, 0, 0, 21463), -- 28069 (Area: -1) (Auras: )
+(@CGUID+5, 28069, 571, 0, 0, 1, 1, 0, 0, 5706.989, 3306.817, 299.718, 1.518436, 120, 0, 0, 0, 0, 0, 0, 0, 0, 21463), -- 28069 (Area: 4412)
+(@CGUID+6, 28840, 571, 0, 0, 1, 1, 0, 0, 5737.756, 3273.594, 299.117, 2.794445, 120, 0, 0, 0, 0, 2, 0, 0, 0, 21463), -- 28840 (Area: 4412) (Auras: 55030 - 55030)
+(@CGUID+7, 28069, 571, 0, 0, 1, 1, 0, 0, 5752.529, 3141.505, 294.1674, 3.351032, 120, 0, 0, 0, 0, 0, 0, 0, 0, 21463), -- 28069 (Area: 4412)
+(@CGUID+8, 28069, 571, 0, 0, 1, 1, 0, 0, 5728.323, 3137.707, 294.1627, 0.715585, 120, 0, 0, 0, 0, 0, 0, 0, 0, 21463), -- 28069 (Area: 4412)
+(@CGUID+9, 28069, 571, 0, 0, 1, 1, 0, 0, 5737.385, 3051.348, 288.0696, 1.239184, 120, 0, 0, 0, 0, 0, 0, 0, 0, 21463), -- 28069 (Area: -1)
+(@CGUID+10, 28069, 571, 0, 0, 1, 1, 0, 0, 5781.281, 3081.078, 288.0696, 3.089233, 120, 0, 0, 0, 0, 0, 0, 0, 0, 21463), -- 28069 (Area: 4412)
+(@CGUID+11, 28069, 571, 0, 0, 1, 1, 0, 0, 5717.863, 3074.304, 288.0696, 0.4014257, 120, 0, 0, 0, 0, 0, 0, 0, 0, 21463), -- 28069 (Area: 4412)
+(@CGUID+12, 28069, 571, 0, 0, 1, 1, 0, 0, 5767.666, 3052.907, 288.0696, 2.181662, 120, 0, 0, 0, 0, 0, 0, 0, 0, 21463), -- 28069 (Area: 4412)
+(@CGUID+13, 28069, 571, 0, 0, 1, 1, 0, 0, 5704.075, 3429.402, 300.8421, 1.239184, 120, 0, 0, 0, 0, 2, 0, 0, 0, 21463); -- 28069 (Area: 4412)
+
+DELETE FROM `waypoint_data` WHERE `id` =(@CGUID*10)+1;
+DELETE FROM `waypoint_data` WHERE `id` =(@CGUID*10)+4;
+DELETE FROM `waypoint_data` WHERE `id` =(@CGUID*10)+6;
+DELETE FROM `waypoint_data` WHERE `id` =(@CGUID*10)+13;
+
+
+INSERT INTO `waypoint_data` (`id`, `point`, `position_x`, `position_y`, `position_z`, `orientation`, `delay`, `move_type`, `action`, `action_chance`, `wpguid`) VALUES
+((@CGUID*10)+6, 1, 5712.777, 3273.745, 299.1278, 0, 0, 0, 0, 100, 0),
+((@CGUID*10)+6, 2, 5705.582, 3264.395, 299.1169, 0, 0, 0, 0, 100, 0),
+((@CGUID*10)+6, 3, 5704.035, 3252.411, 299.1169, 0, 0, 0, 0, 100, 0),
+((@CGUID*10)+6, 4, 5711.498, 3241.038, 299.117, 0, 0, 0, 0, 100, 0),
+((@CGUID*10)+6, 5, 5725.473, 3233.009, 299.1144, 0, 0, 0, 0, 100, 0),
+((@CGUID*10)+6, 6, 5738.392, 3238.95, 299.1152, 0, 0, 0, 0, 100, 0),
+((@CGUID*10)+6, 7, 5744.125, 3248.184, 299.1169, 0, 0, 0, 0, 100, 0),
+((@CGUID*10)+6, 8, 5747.937, 3262.18, 299.1169, 0, 0, 0, 0, 100, 0),
+((@CGUID*10)+6, 9, 5737.756, 3273.594, 299.117, 0, 0, 0, 0, 100, 0),
+((@CGUID*10)+6, 10, 5723.768, 3278.654, 299.138, 0, 0, 0, 0, 100, 0),
+((@CGUID*10)+4, 1, 5737.638, 3168.66, 293.8326, 0, 0, 0, 0, 100, 0),
+((@CGUID*10)+4, 2, 5734.833, 3190.47, 294.0836, 0, 0, 0, 0, 100, 0),
+((@CGUID*10)+4, 3, 5733.381, 3205.572, 295.6976, 0, 0, 0, 0, 100, 0),
+((@CGUID*10)+4, 4, 5734.833, 3190.47, 294.0836, 0, 0, 0, 0, 100, 0),
+((@CGUID*10)+4, 5, 5737.638, 3168.66, 293.8326, 0, 0, 0, 0, 100, 0),
+((@CGUID*10)+4, 6, 5739.323, 3152.199, 293.8326, 0, 0, 0, 0, 100, 0),
+((@CGUID*10)+4, 7, 5742.777, 3128.636, 294.0135, 0, 0, 0, 0, 100, 0),
+((@CGUID*10)+4, 8, 5744.988, 3100.412, 287.9503, 0, 0, 0, 0, 100, 0),
+((@CGUID*10)+4, 9, 5746.909, 3085.88, 287.758, 0, 0, 0, 0, 100, 0),
+((@CGUID*10)+4, 10, 5744.988, 3100.412, 287.9503, 0, 0, 0, 0, 100, 0),
+((@CGUID*10)+4, 11, 5742.777, 3128.636, 294.0135, 0, 0, 0, 0, 100, 0),
+((@CGUID*10)+4, 12, 5739.323, 3152.199, 293.8326, 0, 0, 0, 0, 100, 0),
+((@CGUID*10)+1, 1, 5754.452, 3440.957, 300.8421, 0, 0, 0, 0, 100, 0),
+((@CGUID*10)+1, 2, 5721.435, 3437.441, 300.8421, 0, 0, 0, 0, 100, 0),
+((@CGUID*10)+1, 3, 5690.508, 3433.794, 300.8422, 0, 0, 0, 0, 100, 0),
+((@CGUID*10)+1, 4, 5655.392, 3430.241, 300.8421, 0, 0, 0, 0, 100, 0),
+((@CGUID*10)+1, 5, 5690.508, 3433.794, 300.8422, 0, 0, 0, 0, 100, 0),
+((@CGUID*10)+1, 6, 5721.435, 3437.441, 300.8421, 0, 0, 0, 0, 100, 0),
+((@CGUID*10)+13, 1, 5709.812, 3394.623, 300.8422, 0, 0, 0, 0, 100, 0),
+((@CGUID*10)+13, 2, 5713.209, 3367.164, 300.2528, 0, 0, 0, 0, 100, 0),
+((@CGUID*10)+13, 3, 5715.425, 3346.877, 300.0398, 0, 0, 0, 0, 100, 0),
+((@CGUID*10)+13, 4, 5718.081, 3324.582, 299.8054, 0, 0, 0, 0, 100, 0),
+((@CGUID*10)+13, 5, 5715.425, 3346.877, 300.0398, 0, 0, 0, 0, 100, 0),
+((@CGUID*10)+13, 6, 5713.209, 3367.164, 300.2528, 0, 0, 0, 0, 100, 0);
+
+DELETE FROM `creature_addon` WHERE `guid` IN(@CGUID+1,@CGUID+4,@CGUID+6,@CGUID+13);
+INSERT INTO `creature_addon` (`guid`, `path_id`, `mount`, `bytes1`, `bytes2`, `emote`, `auras`) VALUES
+(@CGUID+1, (@CGUID*10)+1, 0, 0, 4097, 0, NULL),
+(@CGUID+4, (@CGUID*10)+4, 0, 0, 4097, 0, NULL),
+(@CGUID+6, (@CGUID*10)+6, 0, 0, 4097, 0, NULL),
+(@CGUID+13, (@CGUID*10)+13, 0, 0, 4097, 0, NULL);
diff --git a/sql/updates/world/3.3.5/2016_05_04_02_world.sql b/sql/updates/world/3.3.5/2016_05_04_02_world.sql
new file mode 100644
index 00000000000..4bb7870a4ea
--- /dev/null
+++ b/sql/updates/world/3.3.5/2016_05_04_02_world.sql
@@ -0,0 +1,2 @@
+UPDATE `quest_template_addon` SET `RewardMailTemplateID`=184, `RewardMailDelay`=900 WHERE `ID`=10966;
+UPDATE `quest_template_addon` SET `RewardMailTemplateID`=185, `RewardMailDelay`=900 WHERE `ID`=10967;
diff --git a/sql/updates/world/3.3.5/2016_05_05_00_world.sql b/sql/updates/world/3.3.5/2016_05_05_00_world.sql
new file mode 100644
index 00000000000..ba99f5df1a6
--- /dev/null
+++ b/sql/updates/world/3.3.5/2016_05_05_00_world.sql
@@ -0,0 +1,13 @@
+DELETE FROM `smart_scripts` WHERE `entryorguid`=27292 AND `source_type`=0;
+INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES
+(27292, 0, 0, 1, 62, 0, 100, 0, 9512, 0, 0, 0, 11, 48606, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 'Flamebringer - On gossip select - Cast Summon Flamebringer Cue'),
+(27292, 0, 1, 0, 61, 0, 100, 0, 0, 0, 0, 0, 72, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 'Flamebringer - On gossip select - Close gossip'),
+(27292, 0, 2, 3, 54, 0, 100, 0, 0, 0, 0, 0, 83, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Flamebringer - On summon - Remove npcflag'),
+(27292, 0, 3, 4, 61, 0, 100, 0, 0, 0, 0, 0, 11, 48598, 2, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 'Flamebringer - On Just Summoned -Cast Ride Flamebringer Cue'),
+(27292, 0, 4, 0, 61, 0, 100, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Flamebringer - Linked with previous Event -Set Passive'),
+(27292, 0, 5, 6, 27, 0, 100, 0, 0, 0, 0, 0, 11, 48602, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Flamebringer - On passenger Boarded - Cast Flight'),
+(27292, 0, 6, 0, 61, 0, 100, 0, 0, 0, 0, 0, 19, 768, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Flamebringer - On passenger Boarded - Enable Combat'),
+(27292, 0, 7, 8, 28, 0, 100, 0, 0, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Flamebringer - On passenger removed - Evade'),
+(27292, 0, 8, 0, 61, 0, 100, 0, 0, 0, 0, 0, 41, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Flamebringer - On passenger removed - Despawn');
+
+UPDATE `creature_template_addon` SET `auras`='' WHERE `entry`=27292;
diff --git a/sql/updates/world/3.3.5/2016_05_05_01_world.sql b/sql/updates/world/3.3.5/2016_05_05_01_world.sql
new file mode 100644
index 00000000000..d1e0ebcadb0
--- /dev/null
+++ b/sql/updates/world/3.3.5/2016_05_05_01_world.sql
@@ -0,0 +1,71 @@
+SET @CGUID := 10998;
+
+DELETE FROM creature WHERE `guid` IN(@CGUID,@CGUID+1);
+INSERT INTO creature (`guid`, `id`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`, `modelid`, `equipment_id`, `position_x`, `position_y`, `position_z`, `orientation`, `spawntimesecs`, `spawndist`, `currentwaypoint`, `curhealth`, `curmana`, `MovementType`, `npcflag`, `unit_flags`, `dynamicflags`, `VerifiedBuild`) VALUES
+(@CGUID+0, 28139, 571, 0, 0, 1, 1, 0, 0, 5268.422, 4522.266, -83.79454, 4.956735, 120, 0, 0, 0, 0, 0, 0, 0, 0, 21463), -- 28069 (Area: 0)
+(@CGUID+1, 28139, 571, 0, 0, 1, 1, 0, 0, 5257.281, 4501.662, -85.16033, 0.296706, 120, 0, 0, 0, 0, 0, 0, 0, 0, 21463); -- 28069 (Area: 0)
+
+UPDATE `creature_template` SET `ainame`='SmartAI', `scriptname`='' WHERE `entry` IN(29043,28139,29116);
+DELETE FROM `smart_scripts` WHERE `entryorguid` IN(29043,28139,29116) AND `source_type`=0;
+DELETE FROM `smart_scripts` WHERE `entryorguid` IN(-@CGUID,-@CGUID-1) AND `source_type`=0;
+
+DELETE FROM `smart_scripts` WHERE `entryorguid` =2904300 AND `source_type`=9;
+
+INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES
+(29043, 0, 0, 0, 11, 0, 100, 0, 0, 0, 0, 0, 22, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Rejek - On Spawn - Set Phase 1'),
+(29043, 0, 1, 0, 20, 1, 100, 0, 12758, 0, 0, 0, 80, 2904300, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Rejek - On Quest Reward 12758 (Phase 1) - Run Script'),
+(29116, 0, 0, 0, 54, 0, 100, 0, 0, 0, 0, 0, 11, 53170, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Stormwatcher Head - On Just Summoned - Cast Ride Rejek'),
+(29116, 0, 1, 0, 38, 0, 100, 0, 1, 1, 0, 0, 28, 53170, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Stormwatcher Head - On Data Set - Remove Aura Ride Rejek'),
+(-@CGUID-0, 0, 0, 1, 38, 0, 100, 0, 1, 1, 0, 0, 47, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Frenzyheart Pup - On Data set - Set Visible'),
+(-@CGUID-1, 0, 0, 1, 38, 0, 100, 0, 1, 1, 0, 0, 47, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Frenzyheart Pup - On Data set - Set Visible'),
+(-@CGUID-0, 0, 1, 0, 61, 0, 100, 0, 1, 1, 0, 0, 53, 1, (@CGUID*10)+0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Frenzyheart Pup - On Data set - start WP'),
+(-@CGUID-1, 0, 1, 0, 61, 0, 100, 0, 1, 1, 0, 0, 53, 1, (@CGUID*10)+1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Frenzyheart Pup - On Data set - start WP'),
+(-@CGUID-0, 0, 3, 0, 40, 0, 100, 0, 2, (@CGUID*10)+0, 0, 0, 47, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Frenzyheart Pup - On Reached WP - Set Invisible'),
+(-@CGUID-1, 0, 3, 0, 40, 0, 100, 0, 2, (@CGUID*10)+1, 0, 0, 47, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Frenzyheart Pup - On Reached WP - Set Invisible'),
+(-@CGUID-0, 0, 3, 4, 40, 0, 100, 0, 1, (@CGUID*10)+0, 0, 0, 66, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 5.585053, 'Frenzyheart Pup - On Reached WP - Set Orientation'),
+(-@CGUID-1, 0, 3, 4, 40, 0, 100, 0, 1, (@CGUID*10)+1, 0, 0, 66, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 5.986479, 'Frenzyheart Pup - On Reached WP - Set Orientation'),
+(-@CGUID-0, 0, 4, 6, 61, 0, 100, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Frenzyheart Pup - On Reached WP - Say'),
+(-@CGUID-1, 0, 4, 6, 61, 0, 100, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Frenzyheart Pup - On Reached WP - Say'),
+(-@CGUID-0, 0, 5, 0, 38, 0, 100, 0, 3, 3, 0, 0, 11, 42963, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Frenzyheart Pup - On Data set - Cast Cosmetic - Combat Knockdown Self'),
+(-@CGUID-1, 0, 5, 0, 38, 0, 100, 0, 3, 3, 0, 0, 11, 42963, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Frenzyheart Pup - On Data set - Cast Cosmetic - Combat Knockdown Self'),
+(-@CGUID-0, 0, 6, 0, 61, 0, 100, 0, 0, 0, 0, 0, 54, 22500, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Frenzyheart Pup - On Reached WP - Pause WP'),
+(-@CGUID-1, 0, 6, 0, 61, 0, 100, 0, 0, 0, 0, 0, 54, 22500, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Frenzyheart Pup - On Reached WP - Pause WP'),
+(-@CGUID-0, 0, 7, 0, 11, 0, 100, 0, 0, 0, 0, 0, 47, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Frenzyheart Pup - On Spawn - Set Invisible'),
+(-@CGUID-1, 0, 7, 0, 11, 0, 100, 0, 0, 0, 0, 0, 47, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Frenzyheart Pup - On Spawn - Set Invisible'),
+(2904300, 9, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 22, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Rejek - Script - Set Phase 2'), -- 16:44:29.469
+(2904300, 9, 1, 0, 0, 0, 100, 0, 2000, 2000, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Rejek - Script - Say Line 0'), -- 16:44:31.812
+(2904300, 9, 2, 0, 0, 0, 100, 0, 0, 0, 0, 0, 45, 1, 1, 0, 0, 0, 0, 10, @CGUID+0, 28139, 0, 0, 0, 0, 0, 'Rejek - Script - Set Data'),
+(2904300, 9, 3, 0, 0, 0, 100, 0, 0, 0, 0, 0, 45, 1, 1, 0, 0, 0, 0, 10, @CGUID+1, 28139, 0, 0, 0, 0, 0, 'Rejek - Script - Set Data'),
+(2904300, 9, 4, 0, 0, 0, 100, 0, 10000, 10000, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Rejek - Script - Say Line 1'), -- 16:44:41.562
+(2904300, 9, 5, 0, 0, 0, 100, 0, 4000, 4000, 0, 0, 66, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 5.410521, 'Rejek - Script - Set Orientation'), -- 16:44:45.109
+(2904300, 9, 6, 0, 0, 0, 100, 0, 1000, 1000, 0, 0, 5, 35, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Rejek - Script - Play emote OneShotAttackUnarmed'), -- 16:44:46.344
+(2904300, 9, 7, 0, 0, 0, 100, 0, 0, 0, 0, 0, 11, 53171, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Rejek - Script - Cast Summon Stormwatcher Head'), -- 16:44:46.344
+(2904300, 9, 8, 0, 0, 0, 100, 0, 3000, 3000, 0, 0, 66, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 2.460914, 'Rejek - Script - Set Orientation'), -- 16:44:47.531
+(2904300, 9, 9, 0, 0, 0, 100, 0, 1500, 1500, 0, 0, 1, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Rejek - Script - Say Line 2'), -- 16:44:48.844
+(2904300, 9, 10, 0, 0, 0, 100, 0, 3000, 3000, 0, 0, 45, 3, 3, 0, 0, 0, 0, 10, @CGUID+0, 28139, 0, 0, 0, 0, 0, 'Rejek - Script - Set Data'), -- 16:44:51.359
+(2904300, 9, 11, 0, 0, 0, 100, 0, 0, 0, 0, 0, 45, 3, 3, 0, 0, 0, 0, 10, @CGUID+1, 28139, 0, 0, 0, 0, 0, 'Rejek - Script - Set Data'), -- 16:44:51.359
+(2904300, 9, 12, 0, 0, 0, 100, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 19, 28139, 0, 0, 0, 0, 0, 0, 'Rejek - Script - Say Line 2 on Frenzyheart Pup'), -- 16:44:51.359
+(2904300, 9, 13, 0, 0, 0, 100, 0, 6000, 6000, 0, 0, 1, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Rejek - Script - Say Line 3'), -- 16:44:57.312
+(2904300, 9, 14, 0, 0, 0, 100, 0, 9000, 9000, 0, 0, 45, 1, 1, 0, 0, 0, 0, 19, 29116, 0, 0, 0, 0, 0, 0, 'Rejek - Script - Say Line 3'), -- 16:45:06.937
+(2904300, 9, 15, 0, 0, 0, 100, 0, 0, 0, 0, 0, 22, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Rejek - Script - Set Phase 1');
+
+DELETE FROM `creature_text` WHERE `entry` IN(29043,28139);
+INSERT INTO `creature_text` (`entry`, `groupid`, `id`, `text`, `type`, `language`, `probability`, `emote`, `duration`, `sound`, `BroadcastTextId`, `TextRange`, `comment`) VALUES
+(29043, 0, 0, 'Who wants to see Rejek''s new helmet?', 12, 0, 100, 1, 0, 0, 29460, 0, 'Rejek'),
+(29043, 1, 0, 'Ok, Rejek show!', 12, 0, 100, 1, 0, 0, 29463, 0, 'Rejek'),
+(29043, 2, 0, 'What you think?', 12, 0, 100, 1, 0, 0, 29464, 0, 'Rejek'),
+(29043, 3, 0, 'Rejek like! If helmet scares pups, Rejek can''t wait to see what it does to big-tongue cowards!', 12, 0, 100, 35, 0, 0, 29466, 0, 'Rejek'),
+(28139, 0, 0, 'I wanna see!', 12, 0, 100, 396, 0, 0, 29461, 0, 'Frenzyheart Pup'),
+(28139, 1, 0, 'Show me too!', 12, 0, 100, 1, 0, 0, 29462, 0, 'Frenzyheart Pup'),
+(28139, 2, 0, 'Metalhead ate Rejek! Run!', 12, 0, 100, 1, 0, 0, 29465, 0, 'Frenzyheart Pup');
+
+DELETE FROM `waypoints` WHERE `entry` IN((@CGUID*10)+0,(@CGUID*10)+1);
+INSERT INTO `waypoints` (`entry`, `pointid`, `position_x`, `position_y`, `position_z`, `point_comment`) VALUES
+((@CGUID*10)+0, 1, 5267.188, 4506.771, -84.47479, 'Frenzyheart Pup'),
+((@CGUID*10)+0, 2, 5267.754, 4522.471, -83.85757, 'Frenzyheart Pup'),
+((@CGUID*10)+1, 1, 5264.369, 4503.333, -84.65268, 'Frenzyheart Pup'),
+((@CGUID*10)+1, 2, 5243.813, 4501.6, -84.7424, 'Frenzyheart Pup');
+
+DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=13 AND `SourceEntry`=53170;
+INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES
+(13, 1, 53170, 0, 0, 31, 0, 3, 29043, 0, 0, 0, 0, '', 'Ride Rejek');
diff --git a/sql/updates/world/3.3.5/2016_05_07_00_world.sql b/sql/updates/world/3.3.5/2016_05_07_00_world.sql
new file mode 100644
index 00000000000..41a35083921
--- /dev/null
+++ b/sql/updates/world/3.3.5/2016_05_07_00_world.sql
@@ -0,0 +1,2 @@
+--
+UPDATE `smart_scripts` SET `action_param3`=1 WHERE `entryorguid`=3296 AND `source_type`=0 AND `id`=1;
diff --git a/sql/updates/world/3.3.5/2016_05_07_01_world.sql b/sql/updates/world/3.3.5/2016_05_07_01_world.sql
new file mode 100644
index 00000000000..1479c1bfba2
--- /dev/null
+++ b/sql/updates/world/3.3.5/2016_05_07_01_world.sql
@@ -0,0 +1,31 @@
+DELETE FROM `smart_scripts` WHERE `entryorguid` IN(29043) AND `source_type`=0 AND `id`>1;
+DELETE FROM `smart_scripts` WHERE `entryorguid` =2904301 AND `source_type`=9;
+DELETE FROM `creature_text` WHERE `entry` IN(29043) AND `groupid`>3;
+
+INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES
+(29043, 0, 2, 3, 20, 1, 100, 0, 12732, 0, 0, 0, 64, 1, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 'Rejek - On Quest Reward 12732 (Phase 1) - Store Target'),
+(29043, 0, 3, 0, 61, 1, 100, 0, 0, 0, 0, 0, 80, 2904301, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Rejek - On Quest Reward 12732 (Phase 1) - Run Script 2'),
+(2904301, 9, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 22, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Rejek - Script 2 - Set Phase 2'), -- 09:55:57.422
+(2904301, 9, 1, 0, 0, 0, 100, 0, 3000, 3000, 0, 0, 1, 4, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Rejek - Script 2 - Say Line 4'), -- 09:56:00.703
+(2904301, 9, 2, 0, 0, 0, 100, 0, 5000, 5000, 0, 0, 5, 7, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Rejek - Script 2 - Play Emote OneShotEat'), -- 09:56:05.469
+(2904301, 9, 3, 0, 0, 0, 100, 0, 0, 0, 0, 0, 11, 52968, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Rejek - Script 2 - Cast Heartblood Rage'), -- 09:56:05.469
+(2904301, 9, 4, 0, 0, 0, 100, 0, 2000, 2000, 0, 0, 1, 5, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Rejek - Script 2 - Say Line 5'), -- 09:56:07.891
+(2904301, 9, 5, 0, 0, 0, 100, 0, 4000, 4000, 0, 0, 5, 36, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Rejek - Script 2 - Play Emote OneShotAttack1H'), -- 09:56:11.578
+(2904301, 9, 6, 0, 0, 0, 100, 0, 2000, 2000, 0, 0, 5, 35, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Rejek - Script 2 - Play Emote OneShotAttackUnarmed'), -- 09:56:13.984
+(2904301, 9, 7, 0, 0, 0, 100, 0, 3000, 3000, 0, 0, 1, 6, 0, 0, 0, 0, 0, 12, 1, 0, 0, 0, 0, 0, 0, 'Rejek - Script 2 - Say Line 6'), -- 09:56:16.500
+(2904301, 9, 8, 0, 0, 0, 100, 0, 0, 0, 0, 0, 22, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Rejek - Script 2 - Set Phase 1');
+
+INSERT INTO `creature_text` (`entry`, `groupid`, `id`, `text`, `type`, `language`, `probability`, `emote`, `duration`, `sound`, `BroadcastTextId`, `TextRange`, `comment`) VALUES
+(29043, 4, 0, 'Still warm, just the way Rejek likes it.', 12, 0, 100, 1, 0, 0, 0, 0, 'Rejek'),
+(29043, 5, 0, 'Rejek feel strong! Rejek crush big-tongue skulls between his hands!', 12, 0, 100, 34, 0, 0, 0, 0, 'Rejek'),
+(29043, 6, 0, 'Rejek and $n will teach the enemies of the Frenzyheart to fear us!', 12, 0, 100, 53, 0, 0, 0, 0, 'Rejek');
+
+DELETE FROM `smart_scripts` WHERE `entryorguid`=2816100 AND `source_type`=9 AND `id`=0 AND `link`=0;
+DELETE FROM `smart_scripts` WHERE `entryorguid`=28161 AND `source_type`=0 AND `id`=4 AND `link`=0;
+UPDATE `smart_scripts` SET `link`=0 WHERE `entryorguid`=28161 AND `source_type`=0 AND `id`=0 AND `link`=4;
+
+DELETE FROM `smart_scripts` WHERE `entryorguid` IN(4968) AND `source_type`=0 AND `id`=1;
+UPDATE `smart_scripts` SET `link`=1 WHERE `entryorguid`=4968 AND `source_type`=0 AND `id`=0 AND `link`=0;
+
+INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES
+(4968, 0, 1, 0, 61, 0, 100, 0, 0, 0, 0, 0, 11, 23122, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 'Lady Jaina Proudmoore - On Gossip Select - Cast Jaina''s Autograph');
diff --git a/sql/updates/world/3.3.5/2016_05_08_00_world.sql b/sql/updates/world/3.3.5/2016_05_08_00_world.sql
new file mode 100644
index 00000000000..cfbe1f6b9ad
--- /dev/null
+++ b/sql/updates/world/3.3.5/2016_05_08_00_world.sql
@@ -0,0 +1,11 @@
+SET @CGUID:=84737;
+
+-- Add missing Caravan Mule & Guard Didier <Brotherhood of the Light> spawns
+DELETE FROM `creature` WHERE `guid` BETWEEN @CGUID+0 AND @CGUID+5;
+INSERT INTO `creature` (`guid`, `id`, `map`, `position_x`, `position_y`, `position_z`, `orientation`, `spawntimesecs`, `curhealth`) VALUES
+(@CGUID+0, 16232, 0, 2308.195, -5297.163, 82.0796, 1.780236, 120, 0), -- [65] Caravan Mule
+(@CGUID+1, 16232, 0, 2309.498, -5294.246, 82.07687, 1.727876, 120, 0), -- [66] Caravan Mule
+(@CGUID+2, 16232, 0, 2306.324, -5294.137, 82.07687, 1.815142, 120, 0), -- [67] Caravan Mule
+(@CGUID+3, 16232, 0, 2308.93, -5290.619, 82.10618, 1.797689, 120, 0), -- [68] Caravan Mule
+(@CGUID+4, 16232, 0, 2305.878, -5290.338, 82.33588, 1.832596, 120, 0), -- [69] Caravan Mule
+(@CGUID+5, 16226, 0, 2305.295, -5286.124, 82.02069, 4.834562, 120, 0); -- [70] Guard Didier <Brotherhood of the Light>
diff --git a/sql/updates/world/3.3.5/2016_05_09_00_world.sql b/sql/updates/world/3.3.5/2016_05_09_00_world.sql
new file mode 100644
index 00000000000..3c21ed52350
--- /dev/null
+++ b/sql/updates/world/3.3.5/2016_05_09_00_world.sql
@@ -0,0 +1,2 @@
+--
+UPDATE `creature` SET `unit_flags` = 4104 WHERE `id` = 12430;
diff --git a/sql/updates/world/3.3.5/2016_05_09_01_world.sql b/sql/updates/world/3.3.5/2016_05_09_01_world.sql
new file mode 100644
index 00000000000..b75eb63dd2b
--- /dev/null
+++ b/sql/updates/world/3.3.5/2016_05_09_01_world.sql
@@ -0,0 +1,21 @@
+DELETE FROM creature_text WHERE `entry` in(28116,28115);
+INSERT INTO creature_text (`entry`, `groupid`, `id`, `text`, `type`, `language`, `probability`, `emote`, `duration`, `sound`, `BroadcastTextId`, `comment`) VALUES
+(28115, 0, 0, 'You feel a massive jolt of energy as your body binds with that of Soo-holu.', 42, 0, 100, 0, 0, 0, 29003, 'Soo-holu to Player'),
+(28116, 0, 0, 'You feel rage rise within you as your body binds with Kartak.', 42, 0, 100, 0, 0, 0, 29005, 'Kartak the Abominable to Player');
+
+UPDATE `creature_template` SET `spell1`=52316, `spell2`=52271, `spell3`=52311, `spell4`=52272, `spell5`=52274, `VehicleId`=257 WHERE `entry`=28116;
+UPDATE `creature_template` SET `spell1`=52331, `spell2`=52358, `spell3`=53032, `spell4`=52321, `spell5`=0, `VehicleId`=257 WHERE `entry`=28115;
+
+UPDATE `creature_template` SET `ainame`='SmartAI', `scriptname`='' WHERE `entry` IN(28115,28116);
+DELETE FROM `smart_scripts` WHERE `entryorguid` IN(28115,28116) AND `source_type`=0;
+
+INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES
+(28115, 0, 0, 1, 54, 0, 100, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Soo-holu <Will of the Titans> - On Just Summoned - Set Passive'),
+(28115, 0, 1, 0, 61, 0, 100, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Soo-holu <Will of the Titans> - On Just Summoned - Say'),
+(28116, 0, 0, 1, 54, 0, 100, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Kartak the Abominable - On Just Summoned - Set Passive'),
+(28116, 0, 1, 0, 61, 0, 100, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Kartak the Abominable - On Just Summoned - Say');
+
+UPDATE `gameobject` SET `position_x`=5110.322754, `position_y`=5466.666504, `position_z`=-91.836319 WHERE `guid`=99745;
+UPDATE `creature_text` SET `BroadcastTextId`=29247 WHERE `entry`=29043 AND `groupid`=4 AND `id`=0;
+UPDATE `creature_text` SET `BroadcastTextId`=29248 WHERE `entry`=29043 AND `groupid`=5 AND `id`=0;
+UPDATE `creature_text` SET `BroadcastTextId`=29249 WHERE `entry`=29043 AND `groupid`=6 AND `id`=0;
diff --git a/sql/updates/world/3.3.5/2016_05_09_02_world.sql b/sql/updates/world/3.3.5/2016_05_09_02_world.sql
new file mode 100644
index 00000000000..968ac92561e
--- /dev/null
+++ b/sql/updates/world/3.3.5/2016_05_09_02_world.sql
@@ -0,0 +1,41 @@
+UPDATE `creature_template` SET `ScriptName`='npc_rocket_propelled_warhead' WHERE `entry`=27593;
+
+DELETE FROM `spell_script_names` WHERE `ScriptName` IN ('spell_z_check', 'spell_vehicle_warhead_fuse', 'spell_warhead_detonate','spell_warhead_fuse');
+INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES
+(61678, 'spell_z_check'),
+(49107, 'spell_vehicle_warhead_fuse'),
+(49250, 'spell_warhead_detonate'),
+(49181, 'spell_warhead_fuse');
+
+DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=13 AND `SourceEntry`=49332;
+INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES
+(13,1,49332,0,1,31,0,3,27702,0,0,0,0,'',"Spell 'Warhead Seeking Mine' can hit 'Horde Lumberboat'"),
+(13,1,49332,0,2,31,0,3,27688,0,0,0,0,'',"Spell 'Warhead Seeking Mine' can hit 'Alliance Lumberboat'");
+
+-- Warhead Explosion Bunny SAI
+UPDATE `creature_template` SET `InhabitType`=4, `AIName`='SmartAI' WHERE `entry`=27663;
+DELETE FROM `smart_scripts` WHERE `entryorguid`=27663 AND `source_type`=0;
+INSERT INTO `smart_scripts` (`entryorguid`,`source_type`,`id`,`link`,`event_type`,`event_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action_type`,`action_param1`,`action_param2`,`action_param3`,`action_param4`,`action_param5`,`action_param6`,`target_type`,`target_param1`,`target_param2`,`target_param3`,`target_x`,`target_y`,`target_z`,`target_o`,`comment`) VALUES
+(27663,0,0,0,54,0,100,0,0,0,0,0,11,49290,0,0,0,0,0,1,0,0,0,0,0,0,0,'Warhead Explosion Bunny - Just Summoned - Cast \'Torpedo Explosion\'');
+
+-- Alliance Lumberboat Explosions SAI
+UPDATE `creature_template` SET `AIName`='SmartAI' WHERE `entry`=27689;
+DELETE FROM `smart_scripts` WHERE `entryorguid`=27689 AND `source_type`=0;
+DELETE FROM `smart_scripts` WHERE `entryorguid`=2768900 AND `source_type`=9;
+INSERT INTO `smart_scripts` (`entryorguid`,`source_type`,`id`,`link`,`event_type`,`event_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action_type`,`action_param1`,`action_param2`,`action_param3`,`action_param4`,`action_param5`,`action_param6`,`target_type`,`target_param1`,`target_param2`,`target_param3`,`target_x`,`target_y`,`target_z`,`target_o`,`comment`) VALUES
+(27689,0,0,0,8,0,100,0,49290,0,0,0,80,2768900,0,0,0,0,0,1,0,0,0,0,0,0,0,'Alliance Lumberboat Explosions - On SpellHit \'Warhead Seeking Mine\' - Cast \'Horde Boat to Torpedo\''),
+(2768900,9,0,0,0,0,100,0,0,0,0,0,11,42344,0,0,0,0,0,1,0,0,0,0,0,0,0,'Alliance Lumberboat Explosions - ActionList - Cast \'Cosmetic - Flame Patch 0.5\''),
+(2768900,9,1,0,0,0,50,0,11000,11000,0,0,11,42345,0,0,0,0,0,1,0,0,0,0,0,0,0,'Alliance Lumberboat Explosions - ActionList - Cast \'Cosmetic - Flame Patch\''),
+(2768900,9,2,0,0,0,50,0,11000,11000,0,0,11,42346,0,0,0,0,0,1,0,0,0,0,0,0,0,'Alliance Lumberboat Explosions - ActionList - Cast \'Cosmetic - Flame Patch 2.0\'');
+
+-- Horde Lumberboat SAI
+UPDATE `creature_template` SET `InhabitType`=4, `AIName`='SmartAI' WHERE `entry`=27702;
+DELETE FROM `smart_scripts` WHERE `entryorguid`=27702 AND `source_type`=0;
+INSERT INTO `smart_scripts` (`entryorguid`,`source_type`,`id`,`link`,`event_type`,`event_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action_type`,`action_param1`,`action_param2`,`action_param3`,`action_param4`,`action_param5`,`action_param6`,`target_type`,`target_param1`,`target_param2`,`target_param3`,`target_x`,`target_y`,`target_z`,`target_o`,`comment`) VALUES
+(27702,0,0,0,8,0,100,0,49332,0,0,0,11,49372,0,0,0,0,0,9,27593,0,100,0,0,0,0,'Horde Lumberboat - On SpellHit \'Warhead Seeking Mine\' - Cast \'Horde Boat to Torpedo\'');
+
+-- Alliance Lumberboat SAI
+UPDATE `creature_template` SET `InhabitType`=4, `AIName`='SmartAI' WHERE `entry`=27688;
+DELETE FROM `smart_scripts` WHERE `entryorguid`=27688 AND `source_type`=0;
+INSERT INTO `smart_scripts` (`entryorguid`,`source_type`,`id`,`link`,`event_type`,`event_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action_type`,`action_param1`,`action_param2`,`action_param3`,`action_param4`,`action_param5`,`action_param6`,`target_type`,`target_param1`,`target_param2`,`target_param3`,`target_x`,`target_y`,`target_z`,`target_o`,`comment`) VALUES
+(27688,0,0,0,8,0,100,0,49332,0,0,0,11,49257,0,0,0,0,0,9,27593,0,100,0,0,0,0,'Alliance Lumberboat - On SpellHit \'Warhead Seeking Mine\' - Cast \'Alliance Boat to Torpedo\'');
diff --git a/sql/updates/world/3.3.5/2016_05_09_03_world.sql b/sql/updates/world/3.3.5/2016_05_09_03_world.sql
new file mode 100644
index 00000000000..149d829c9f7
--- /dev/null
+++ b/sql/updates/world/3.3.5/2016_05_09_03_world.sql
@@ -0,0 +1,3 @@
+SET @MODIFIER := 50;
+UPDATE `creature_template` SET `mechanic_immune_mask`=617299839, `DamageModifier`=@MODIFIER WHERE `entry` IN (35403,35405);
+UPDATE `creature_template` SET `mechanic_immune_mask`=617299839, `ScriptName`='boss_ioc_horde_alliance' WHERE `entry` IN (34922,34924);
diff --git a/sql/updates/world/3.3.5/2016_05_09_04_world.sql b/sql/updates/world/3.3.5/2016_05_09_04_world.sql
new file mode 100644
index 00000000000..111b000efeb
--- /dev/null
+++ b/sql/updates/world/3.3.5/2016_05_09_04_world.sql
@@ -0,0 +1,41 @@
+UPDATE `creature_template` SET `unit_flags`=33554432, `flags_extra`=0 WHERE `entry`=25744;
+DELETE FROM `creature_summon_groups` WHERE `summonerId`=25741;
+
+DELETE FROM `spell_script_names` WHERE `ScriptName` IN
+('spell_summon_blood_elves_script',
+'spell_muru_darkness',
+'spell_dark_fiend_skin',
+'spell_transform_visual_missile_periodic',
+'spell_summon_blood_elves_periodic');
+INSERT INTO `spell_script_names` (`spell_id`,`ScriptName`) VALUES
+(46050,'spell_summon_blood_elves_script'),
+(45996,'spell_muru_darkness'),
+(45934,'spell_dark_fiend_skin'),
+(46205,'spell_transform_visual_missile_periodic'),
+(46041,'spell_summon_blood_elves_periodic');
+
+DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=13 AND `SourceEntry` IN (46208,46178);
+INSERT INTO `conditions` (`SourceTypeOrReferenceId`,`SourceGroup`,`SourceEntry`,`SourceId`,`ElseGroup`,`ConditionTypeOrReference`,`ConditionTarget`,`ConditionValue1`,`ConditionValue2`,`ConditionValue3`,`NegativeCondition` ,`ErrorTextId`,`ScriptName`,`Comment`) VALUES
+(13,1,46208,0,0,31,0,3,25741,0,0,0,'','Spell \'Transform Visual Missile\' targets M\'uru'),
+(13,1,46178,0,0,31,0,3,25741,0,0,0,'','Spell \'Transform Visual Missile\' targets M\'uru');
+
+UPDATE `creature_model_info` SET `BoundingRadius`=1, `CombatReach`=2 WHERE `DisplayID`=23842;
+UPDATE `creature_model_info` SET `BoundingRadius`=6, `CombatReach`=6 WHERE `DisplayID`=23428;
+UPDATE `creature_model_info` SET `BoundingRadius`=1, `CombatReach`=1.5 WHERE `DisplayID`=22471;
+UPDATE `creature_model_info` SET `BoundingRadius`=0.48, `CombatReach`=11.2 WHERE `DisplayID`=22838;
+UPDATE `creature_model_info` SET `BoundingRadius`=0.8893, `CombatReach`=2.5 WHERE `DisplayID`=23177;
+UPDATE `creature_model_info` SET `BoundingRadius`=6, `CombatReach`=15 WHERE `DisplayID`=23200;
+UPDATE `creature_model_info` SET `BoundingRadius`=0.8893, `CombatReach`=2.5 WHERE `DisplayID`=23334;
+UPDATE `creature_model_info` SET `BoundingRadius`=0.612, `CombatReach`=3 WHERE `DisplayID`=23350;
+UPDATE `creature_model_info` SET `BoundingRadius`=0.75, `CombatReach`=3.75 WHERE `DisplayID`=23473;
+UPDATE `creature_model_info` SET `BoundingRadius`=0.6, `CombatReach`=3 WHERE `DisplayID`=23474;
+UPDATE `creature_model_info` SET `BoundingRadius`=0.6, `CombatReach`=3 WHERE `DisplayID`=23476;
+UPDATE `creature_model_info` SET `BoundingRadius`=0.6, `CombatReach`=3 WHERE `DisplayID`=23477;
+UPDATE `creature_model_info` SET `BoundingRadius`=0.6, `CombatReach`=3 WHERE `DisplayID`=23478;
+UPDATE `creature_model_info` SET `BoundingRadius`=0.754676, `CombatReach`=3 WHERE `DisplayID`=23479;
+UPDATE `creature_model_info` SET `BoundingRadius`=0.51705, `CombatReach`=2.025 WHERE `DisplayID`=23531;
+UPDATE `creature_model_info` SET `BoundingRadius`=0.51705, `CombatReach`=2.025 WHERE `DisplayID`=23533;
+UPDATE `creature_model_info` SET `BoundingRadius`=0.51705, `CombatReach`=2.025 WHERE `DisplayID`=23537;
+UPDATE `creature_model_info` SET `BoundingRadius`=1, `CombatReach`=1.5 WHERE `DisplayID`=23717;
+UPDATE `creature_model_info` SET `BoundingRadius`=3, `CombatReach`=4.5 WHERE `DisplayID`=26628;
+UPDATE `creature_model_info` SET `BoundingRadius`=0.25, `CombatReach`=0.375 WHERE `DisplayID`=29280;
diff --git a/sql/updates/world/3.3.5/2016_05_11_00_world.sql b/sql/updates/world/3.3.5/2016_05_11_00_world.sql
new file mode 100644
index 00000000000..9be7c8d3a0d
--- /dev/null
+++ b/sql/updates/world/3.3.5/2016_05_11_00_world.sql
@@ -0,0 +1,33 @@
+--
+DELETE FROM `command` WHERE `name` IN ('server shutdown force','server restart force');
+INSERT INTO `command` (`name`,`permission`) VALUES ('server shutdown force', 839),('server restart force', 840);
+UPDATE `command` SET `help`="Syntax: .server shutdown [force] #delay [#exit_code] [reason]
+
+Shut the server down after #delay seconds. Use #exit_code or 0 as program exit code. Specify 'force' to allow short-term shutdown despite other players being connected." WHERE `name` IN ('server shutdown','server shutdown force');
+UPDATE `command` SET `help`="Syntax: .server restart [force] #delay [#exit_code] [reason]
+
+Restart the server after #delay seconds. Use #exit_code or 2 as program exit code. Specify 'force' to allow short-term shutdown despite other players being connected." WHERE `name` IN ('server restart','server restart force');
+
+
+DELETE FROM `command` WHERE `permission` IN (571,575);
+INSERT INTO `command` (`name`,`permission`,`help`) VALUES
+("npc add", 571, "Syntax: .npc add #entry
+ Spawn a creature using template #entry and save it to the database.
+ If you want a temporary spawn that is not saved to the database, use .npc add temp instead."),
+("npc add temp", 575, "Syntax: .npc add temp [loot/noloot] #entry
+Adds temporary NPC, not saved to database.
+ Specify 'loot' to have the NPC's corpse stick around for some time after death, allowing it to be looted.
+ Specify 'noloot' to have the corpse disappear immediately.");
+
+DELETE FROM `command` WHERE `permission`=837;
+INSERT INTO `command` (`name`,`permission`,`help`) VALUES ("npc evade",837,"Syntax: .npc evade [reason] [force]
+Makes the targeted NPC enter evade mode.\nDefaults to specifying EVADE_REASON_OTHER, override this by providing the reason string (ex.: .npc evade EVADE_REASON_BOUNDARY).\nSpecify 'force' to clear any pre-existing evade state before evading - this may cause weirdness, use at your own risk.");
+
+DELETE FROM `command` WHERE `permission`=838;
+INSERT INTO `command` (`name`,`permission`,`help`) VALUES ("pet level",838,"Syntax: .pet level #dLevel
+Increases/decreases the pet's level by #dLevel. Pet's level cannot exceed the owner's level.");
+
+DELETE FROM `trinity_string` WHERE `entry` IN (11015,11016);
+INSERT INTO `trinity_string` (`entry`,`content_default`) VALUES
+(11015,"This creature does not have an active CreatureAI assigned to it."),
+(11016,"Select a player or player pet.");
diff --git a/sql/updates/world/3.3.5/2016_05_11_01_world.sql b/sql/updates/world/3.3.5/2016_05_11_01_world.sql
new file mode 100644
index 00000000000..95fa08ab742
--- /dev/null
+++ b/sql/updates/world/3.3.5/2016_05_11_01_world.sql
@@ -0,0 +1,16 @@
+ALTER TABLE `spell_proc`
+ CHANGE `spellId` `SpellId` int(11) NOT NULL DEFAULT 0 FIRST,
+ CHANGE `schoolMask` `SchoolMask` tinyint(3) unsigned NOT NULL DEFAULT 0 AFTER `SpellId`,
+ CHANGE `spellFamilyName` `SpellFamilyName` smallint(5) unsigned NOT NULL DEFAULT 0 AFTER `SchoolMask`,
+ CHANGE `spellFamilyMask0` `SpellFamilyMask0` int(10) unsigned NOT NULL DEFAULT 0 AFTER `SpellFamilyName`,
+ CHANGE `spellFamilyMask1` `SpellFamilyMask1` int(10) unsigned NOT NULL DEFAULT 0 AFTER `SpellFamilyMask0`,
+ CHANGE `spellFamilyMask2` `SpellFamilyMask2` int(10) unsigned NOT NULL DEFAULT 0 AFTER `SpellFamilyMask1`,
+ CHANGE `typeMask` `ProcFlags` int(10) unsigned NOT NULL DEFAULT 0 AFTER `SpellFamilyMask2`,
+ CHANGE `spellTypeMask` `SpellTypeMask` int(10) unsigned NOT NULL DEFAULT 0 AFTER `ProcFlags`,
+ CHANGE `spellPhaseMask` `SpellPhaseMask` int(10) unsigned NOT NULL DEFAULT 0 AFTER `SpellTypeMask`,
+ CHANGE `hitMask` `HitMask` int(10) unsigned NOT NULL DEFAULT 0 AFTER `SpellPhaseMask`,
+ CHANGE `attributesMask` `AttributesMask` int(10) unsigned NOT NULL DEFAULT 0 AFTER `HitMask`,
+ CHANGE `ratePerMinute` `ProcsPerMinute` float NOT NULL DEFAULT 0 AFTER `AttributesMask`,
+ CHANGE `chance` `Chance` float NOT NULL DEFAULT 0 AFTER `ProcsPerMinute`,
+ CHANGE `cooldown` `Cooldown` int(10) unsigned NOT NULL DEFAULT 0 AFTER `Chance`,
+ CHANGE `charges` `Charges` tinyint(3) unsigned NOT NULL DEFAULT 0 AFTER `Cooldown`;
diff --git a/src/common/Utilities/StartProcess.cpp b/src/common/Utilities/StartProcess.cpp
index 29feeaa2714..f35c6de3b5c 100644
--- a/src/common/Utilities/StartProcess.cpp
+++ b/src/common/Utilities/StartProcess.cpp
@@ -92,6 +92,7 @@ static int CreateChildProcess(T waiter, std::string const& executable,
// With binding stdin
return execute(run_exe(boost::filesystem::absolute(executable)),
set_args(args),
+ inherit_env(),
bind_stdin(*inputSource),
bind_stdout(file_descriptor_sink(outPipe.sink, close_handle)),
bind_stderr(file_descriptor_sink(errPipe.sink, close_handle)));
@@ -101,6 +102,7 @@ static int CreateChildProcess(T waiter, std::string const& executable,
// Without binding stdin
return execute(run_exe(boost::filesystem::absolute(executable)),
set_args(args),
+ inherit_env(),
bind_stdout(file_descriptor_sink(outPipe.sink, close_handle)),
bind_stderr(file_descriptor_sink(errPipe.sink, close_handle)));
}
@@ -237,7 +239,7 @@ public:
}
};
-TC_COMMON_API std::shared_ptr<AsyncProcessResult>
+std::shared_ptr<AsyncProcessResult>
StartAsyncProcess(std::string executable, std::vector<std::string> args,
std::string logger, std::string input_file, bool secure)
{
diff --git a/src/common/Utilities/Timer.h b/src/common/Utilities/Timer.h
index cdce08caaf0..f66bb90c98e 100644
--- a/src/common/Utilities/Timer.h
+++ b/src/common/Utilities/Timer.h
@@ -25,9 +25,9 @@ inline uint32 getMSTime()
{
using namespace std::chrono;
- static const system_clock::time_point ApplicationStartTime = system_clock::now();
+ static const steady_clock::time_point ApplicationStartTime = steady_clock::now();
- return uint32(duration_cast<milliseconds>(system_clock::now() - ApplicationStartTime).count());
+ return uint32(duration_cast<milliseconds>(steady_clock::now() - ApplicationStartTime).count());
}
inline uint32 getMSTimeDiff(uint32 oldMSTime, uint32 newMSTime)
diff --git a/src/server/authserver/Server/AuthSession.h b/src/server/authserver/Server/AuthSession.h
index 1babb7407a9..027011629eb 100644
--- a/src/server/authserver/Server/AuthSession.h
+++ b/src/server/authserver/Server/AuthSession.h
@@ -23,7 +23,7 @@
#include "ByteBuffer.h"
#include "Socket.h"
#include "BigNumber.h"
-#include "Callback.h"
+#include "QueryCallback.h"
#include <memory>
#include <boost/asio/ip/tcp.hpp>
diff --git a/src/server/authserver/authserver.conf.dist b/src/server/authserver/authserver.conf.dist
index db60e3b3ece..1d3b48839a8 100644
--- a/src/server/authserver/authserver.conf.dist
+++ b/src/server/authserver/authserver.conf.dist
@@ -179,6 +179,7 @@ LoginDatabaseInfo = "127.0.0.1;3306;trinity;trinity;auth"
# LoginDatabase.WorkerThreads
# Description: The amount of worker threads spawned to handle asynchronous (delayed) MySQL
# statements. Each worker thread is mirrored with its own connection to the
+# MySQL server and their own thread on the MySQL server.
# Default: 1
LoginDatabase.WorkerThreads = 1
diff --git a/src/server/database/Database/DatabaseWorkerPool.h b/src/server/database/Database/DatabaseWorkerPool.h
index d883366237f..ffdde91c0a6 100644
--- a/src/server/database/Database/DatabaseWorkerPool.h
+++ b/src/server/database/Database/DatabaseWorkerPool.h
@@ -19,7 +19,7 @@
#define _DATABASEWORKERPOOL_H
#include "Common.h"
-#include "Callback.h"
+#include "QueryCallback.h"
#include "MySQLConnection.h"
#include "Transaction.h"
#include "DatabaseWorker.h"
@@ -120,7 +120,7 @@ class DatabaseWorkerPool
//! This method should only be used for queries that are only executed once, e.g during startup.
void DirectExecute(const char* sql)
{
- if (!sql)
+ if (Trinity::IsFormatEmptyOrNull(sql))
return;
T* connection = GetFreeConnection();
@@ -175,7 +175,7 @@ class DatabaseWorkerPool
template<typename Format, typename... Args>
QueryResult PQuery(Format&& sql, Args&&... args)
{
- if (!sql)
+ if (Trinity::IsFormatEmptyOrNull(sql))
return QueryResult(nullptr);
return Query(Trinity::StringFormat(std::forward<Format>(sql), std::forward<Args>(args)...).c_str());
diff --git a/src/common/Threading/Callback.h b/src/server/database/Database/QueryCallback.h
index f7eab57ddda..5f6ae74da4f 100644
--- a/src/common/Threading/Callback.h
+++ b/src/server/database/Database/QueryCallback.h
@@ -15,8 +15,8 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef _CALLBACK_H
-#define _CALLBACK_H
+#ifndef _QUERY_CALLBACK_H
+#define _QUERY_CALLBACK_H
#include <future>
#include "QueryResult.h"
@@ -206,4 +206,4 @@ class QueryCallback_2
QueryCallback_2& operator=(QueryCallback_2 const& right) = delete;
};
-#endif
+#endif // _QUERY_CALLBACK_H
diff --git a/src/server/game/AI/CoreAI/CombatAI.cpp b/src/server/game/AI/CoreAI/CombatAI.cpp
index 716ac13c666..4d0247d9fb5 100644
--- a/src/server/game/AI/CoreAI/CombatAI.cpp
+++ b/src/server/game/AI/CoreAI/CombatAI.cpp
@@ -50,7 +50,7 @@ void AggressorAI::UpdateAI(uint32 /*diff*/)
void CombatAI::InitializeAI()
{
- for (uint32 i = 0; i < CREATURE_MAX_SPELLS; ++i)
+ for (uint32 i = 0; i < MAX_CREATURE_SPELLS; ++i)
if (me->m_spells[i] && sSpellMgr->GetSpellInfo(me->m_spells[i]))
spells.push_back(me->m_spells[i]);
diff --git a/src/server/game/AI/CoreAI/PassiveAI.cpp b/src/server/game/AI/CoreAI/PassiveAI.cpp
index aafde3c1d9a..3ed2f927645 100644
--- a/src/server/game/AI/CoreAI/PassiveAI.cpp
+++ b/src/server/game/AI/CoreAI/PassiveAI.cpp
@@ -58,6 +58,12 @@ void PossessedAI::KilledUnit(Unit* victim)
victim->RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
}
+void PossessedAI::OnCharmed(bool /*apply*/)
+{
+ me->NeedChangeAI = true;
+ me->IsAIEnabled = false;
+}
+
void CritterAI::DamageTaken(Unit* /*done_by*/, uint32&)
{
if (!me->HasUnitState(UNIT_STATE_FLEEING))
diff --git a/src/server/game/AI/CoreAI/PassiveAI.h b/src/server/game/AI/CoreAI/PassiveAI.h
index 5a6dba7046d..9ca9e75bd9f 100644
--- a/src/server/game/AI/CoreAI/PassiveAI.h
+++ b/src/server/game/AI/CoreAI/PassiveAI.h
@@ -46,6 +46,8 @@ class TC_GAME_API PossessedAI : public CreatureAI
void JustDied(Unit*) override;
void KilledUnit(Unit* victim) override;
+ void OnCharmed(bool /*apply*/) override;
+
static int Permissible(const Creature*) { return PERMIT_BASE_IDLE; }
};
diff --git a/src/server/game/AI/CoreAI/PetAI.cpp b/src/server/game/AI/CoreAI/PetAI.cpp
index 68554722db6..2abe20f0ae6 100644
--- a/src/server/game/AI/CoreAI/PetAI.cpp
+++ b/src/server/game/AI/CoreAI/PetAI.cpp
@@ -588,6 +588,12 @@ void PetAI::ReceiveEmote(Player* player, uint32 emote)
}
}
+void PetAI::OnCharmed(bool /*apply*/)
+{
+ me->NeedChangeAI = true;
+ me->IsAIEnabled = false;
+}
+
void PetAI::ClearCharmInfoFlags()
{
// Quick access to set all flags to FALSE
diff --git a/src/server/game/AI/CoreAI/PetAI.h b/src/server/game/AI/CoreAI/PetAI.h
index 3ad34047b01..93ee6c41ece 100644
--- a/src/server/game/AI/CoreAI/PetAI.h
+++ b/src/server/game/AI/CoreAI/PetAI.h
@@ -49,6 +49,8 @@ class TC_GAME_API PetAI : public CreatureAI
void MoveInLineOfSight_Safe(Unit* /*who*/) { } // CreatureAI interferes with returning pets
void EnterEvadeMode(EvadeReason /*why*/) override { } // For fleeing, pets don't use this type of Evade mechanic
+ void OnCharmed(bool /*apply*/) override;
+
private:
bool _isVisible(Unit*) const;
bool _needToStop(void);
diff --git a/src/server/game/AI/CoreAI/UnitAI.h b/src/server/game/AI/CoreAI/UnitAI.h
index 344ccc06249..20a986c0483 100644
--- a/src/server/game/AI/CoreAI/UnitAI.h
+++ b/src/server/game/AI/CoreAI/UnitAI.h
@@ -242,6 +242,7 @@ class TC_GAME_API UnitAI
void DoAddAuraToAllHostilePlayers(uint32 spellid);
void DoCast(uint32 spellId);
void DoCast(Unit* victim, uint32 spellId, bool triggered = false);
+ void DoCastSelf(uint32 spellId, bool triggered = false) { DoCast(me, spellId, triggered); }
void DoCastToAllHostilePlayers(uint32 spellid, bool triggered = false);
void DoCastVictim(uint32 spellId, bool triggered = false);
void DoCastAOE(uint32 spellId, bool triggered = false);
diff --git a/src/server/game/AI/CreatureAI.cpp b/src/server/game/AI/CreatureAI.cpp
index 6ceb4f01c48..15bbff2793f 100644
--- a/src/server/game/AI/CreatureAI.cpp
+++ b/src/server/game/AI/CreatureAI.cpp
@@ -29,11 +29,13 @@
#include "Language.h"
//Disable CreatureAI when charmed
-void CreatureAI::OnCharmed(bool /*apply*/)
+void CreatureAI::OnCharmed(bool apply)
{
- //me->IsAIEnabled = !apply;*/
- me->NeedChangeAI = true;
- me->IsAIEnabled = false;
+ if (apply)
+ {
+ me->NeedChangeAI = true;
+ me->IsAIEnabled = false;
+ }
}
AISpellInfoType* UnitAI::AISpellInfo;
@@ -44,7 +46,7 @@ void CreatureAI::Talk(uint8 id, WorldObject const* whisperTarget /*= nullptr*/)
sCreatureTextMgr->SendChat(me, id, whisperTarget);
}
-void CreatureAI::DoZoneInCombat(Creature* creature /*= NULL*/, float maxRangeToNearestTarget /* = 50.0f*/)
+void CreatureAI::DoZoneInCombat(Creature* creature /*= nullptr*/, float maxRangeToNearestTarget /* = 250.0f*/)
{
if (!creature)
creature = me;
@@ -263,9 +265,10 @@ bool CreatureAI::_EnterEvadeMode(EvadeReason /*why*/)
me->DeleteThreatList();
me->CombatStop(true);
me->LoadCreaturesAddon();
- me->SetLootRecipient(NULL);
+ me->SetLootRecipient(nullptr);
me->ResetPlayerDamageReq();
me->SetLastDamagedTime(0);
+ me->SetCannotReachTarget(false);
if (me->IsInEvadeMode())
return false;
@@ -273,11 +276,11 @@ bool CreatureAI::_EnterEvadeMode(EvadeReason /*why*/)
return true;
}
-#define BOUNDARY_VISUALIZE_CREATURE 15425
-#define BOUNDARY_VISUALIZE_CREATURE_SCALE 0.25f
-#define BOUNDARY_VISUALIZE_STEP_SIZE 1
-#define BOUNDARY_VISUALIZE_FAILSAFE_LIMIT 750
-#define BOUNDARY_VISUALIZE_SPAWN_HEIGHT 5
+static const uint32 BOUNDARY_VISUALIZE_CREATURE = 15425;
+static const float BOUNDARY_VISUALIZE_CREATURE_SCALE = 0.25f;
+static const int8 BOUNDARY_VISUALIZE_STEP_SIZE = 1;
+static const int32 BOUNDARY_VISUALIZE_FAILSAFE_LIMIT = 750;
+static const float BOUNDARY_VISUALIZE_SPAWN_HEIGHT = 5.0f;
int32 CreatureAI::VisualizeBoundary(uint32 duration, Unit* owner, bool fill) const
{
typedef std::pair<int32, int32> coordinate;
@@ -293,13 +296,13 @@ int32 CreatureAI::VisualizeBoundary(uint32 duration, Unit* owner, bool fill) con
std::unordered_set<coordinate> outOfBounds;
Position startPosition = owner->GetPosition();
- if (!CheckBoundary(&startPosition)) // fall back to creature position
- {
+ if (!CheckBoundary(&startPosition))
+ { // fall back to creature position
startPosition = me->GetPosition();
if (!CheckBoundary(&startPosition))
- {
+ { // fall back to creature home position
startPosition = me->GetHomePosition();
- if (!CheckBoundary(&startPosition)) // fall back to creature home position
+ if (!CheckBoundary(&startPosition))
return LANG_CREATURE_NO_INTERIOR_POINT_FOUND;
}
}
diff --git a/src/server/game/AI/CreatureAI.h b/src/server/game/AI/CreatureAI.h
index f175050e107..f8fa6ba532b 100644
--- a/src/server/game/AI/CreatureAI.h
+++ b/src/server/game/AI/CreatureAI.h
@@ -87,6 +87,7 @@ class TC_GAME_API CreatureAI : public UnitAI
{
EVADE_REASON_NO_HOSTILES, // the creature's threat list is empty
EVADE_REASON_BOUNDARY, // the creature has moved outside its evade boundary
+ EVADE_REASON_NO_PATH, // the creature was unable to reach its target for over 5 seconds
EVADE_REASON_SEQUENCE_BREAK, // this is a boss and the pre-requisite encounters for engaging it are not defeated yet
EVADE_REASON_OTHER
};
@@ -111,7 +112,7 @@ class TC_GAME_API CreatureAI : public UnitAI
// Called for reaction at stopping attack at no attackers or targets
virtual void EnterEvadeMode(EvadeReason why = EVADE_REASON_OTHER);
- // Called for reaction at enter to combat if not in combat yet (enemy can be NULL)
+ // Called for reaction at enter to combat if not in combat yet (enemy can be nullptr)
virtual void EnterCombat(Unit* /*victim*/) { }
// Called when the creature is killed
@@ -148,7 +149,7 @@ class TC_GAME_API CreatureAI : public UnitAI
// Called at reaching home after evade
virtual void JustReachedHome() { }
- void DoZoneInCombat(Creature* creature = NULL, float maxRangeToNearestTarget = 50.0f);
+ void DoZoneInCombat(Creature* creature = nullptr, float maxRangeToNearestTarget = 250.0f);
// Called at text emote receive from player
virtual void ReceiveEmote(Player* /*player*/, uint32 /*emoteId*/) { }
diff --git a/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp b/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp
index 6f04a852b61..6475cc8117e 100644
--- a/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp
+++ b/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp
@@ -32,7 +32,7 @@ struct TSpellSummary
uint8 Effects; // set of enum SelectEffect
} extern* SpellSummary;
-void SummonList::DoZoneInCombat(uint32 entry)
+void SummonList::DoZoneInCombat(uint32 entry, float maxRangeToNearestTarget)
{
for (StorageType::iterator i = storage_.begin(); i != storage_.end();)
{
@@ -41,7 +41,7 @@ void SummonList::DoZoneInCombat(uint32 entry)
if (summon && summon->IsAIEnabled
&& (!entry || summon->GetEntry() == entry))
{
- summon->AI()->DoZoneInCombat();
+ summon->AI()->DoZoneInCombat(nullptr, maxRangeToNearestTarget);
}
}
}
@@ -183,22 +183,22 @@ SpellInfo const* ScriptedAI::SelectSpell(Unit* target, uint32 school, uint32 mec
{
//No target so we can't cast
if (!target)
- return NULL;
+ return nullptr;
//Silenced so we can't cast
if (me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SILENCED))
- return NULL;
+ return nullptr;
//Using the extended script system we first create a list of viable spells
- SpellInfo const* apSpell[CREATURE_MAX_SPELLS];
- memset(apSpell, 0, CREATURE_MAX_SPELLS * sizeof(SpellInfo*));
+ SpellInfo const* apSpell[MAX_CREATURE_SPELLS];
+ memset(apSpell, 0, MAX_CREATURE_SPELLS * sizeof(SpellInfo*));
uint32 spellCount = 0;
- SpellInfo const* tempSpell = NULL;
+ SpellInfo const* tempSpell = nullptr;
//Check if each spell is viable(set it to null if not)
- for (uint32 i = 0; i < CREATURE_MAX_SPELLS; i++)
+ for (uint32 i = 0; i < MAX_CREATURE_SPELLS; i++)
{
tempSpell = sSpellMgr->GetSpellInfo(me->m_spells[i]);
@@ -251,7 +251,7 @@ SpellInfo const* ScriptedAI::SelectSpell(Unit* target, uint32 school, uint32 mec
//We got our usable spells so now lets randomly pick one
if (!spellCount)
- return NULL;
+ return nullptr;
return apSpell[urand(0, spellCount - 1)];
}
@@ -327,7 +327,7 @@ void ScriptedAI::DoTeleportAll(float x, float y, float z, float o)
Unit* ScriptedAI::DoSelectLowestHpFriendly(float range, uint32 minHPDiff)
{
- Unit* unit = NULL;
+ Unit* unit = nullptr;
Trinity::MostHPMissingInRange u_check(me, range, minHPDiff);
Trinity::UnitLastSearcher<Trinity::MostHPMissingInRange> searcher(me, unit, u_check);
me->VisitNearbyObject(range, searcher);
@@ -357,7 +357,7 @@ std::list<Creature*> ScriptedAI::DoFindFriendlyMissingBuff(float range, uint32 u
Player* ScriptedAI::GetPlayerAtMinimumRange(float minimumRange)
{
- Player* player = NULL;
+ Player* player = nullptr;
CellCoord pair(Trinity::ComputeCellCoord(me->GetPositionX(), me->GetPositionY()));
Cell cell(pair);
@@ -547,7 +547,7 @@ void BossAI::UpdateAI(uint32 diff)
DoMeleeAttackIfReady();
}
-void BossAI::_DespawnAtEvade(uint32 delayToRespawn)
+void BossAI::_DespawnAtEvade(uint32 delayToRespawn, Creature* who)
{
if (delayToRespawn < 2)
{
@@ -555,18 +555,28 @@ void BossAI::_DespawnAtEvade(uint32 delayToRespawn)
delayToRespawn = 2;
}
- uint32 corpseDelay = me->GetCorpseDelay();
- uint32 respawnDelay = me->GetRespawnDelay();
+ if (!who)
+ who = me;
- me->SetCorpseDelay(1);
- me->SetRespawnDelay(delayToRespawn - 1);
+ if (TempSummon* whoSummon = who->ToTempSummon())
+ {
+ TC_LOG_WARN("scripts", "_DespawnAtEvade called on a temporary summon.");
+ whoSummon->UnSummon();
+ return;
+ }
- me->DespawnOrUnsummon();
+ uint32 corpseDelay = who->GetCorpseDelay();
+ uint32 respawnDelay = who->GetRespawnDelay();
- me->SetCorpseDelay(corpseDelay);
- me->SetRespawnDelay(respawnDelay);
+ who->SetCorpseDelay(1);
+ who->SetRespawnDelay(delayToRespawn - 1);
- if (instance)
+ who->DespawnOrUnsummon();
+
+ who->SetCorpseDelay(corpseDelay);
+ who->SetRespawnDelay(respawnDelay);
+
+ if (instance && who == me)
instance->SetBossState(_bossId, FAIL);
}
@@ -628,27 +638,27 @@ void WorldBossAI::UpdateAI(uint32 diff)
}
// SD2 grid searchers.
-TC_GAME_API Creature* GetClosestCreatureWithEntry(WorldObject* source, uint32 entry, float maxSearchRange, bool alive /*= true*/)
+Creature* GetClosestCreatureWithEntry(WorldObject* source, uint32 entry, float maxSearchRange, bool alive /*= true*/)
{
return source->FindNearestCreature(entry, maxSearchRange, alive);
}
-TC_GAME_API GameObject* GetClosestGameObjectWithEntry(WorldObject* source, uint32 entry, float maxSearchRange)
+GameObject* GetClosestGameObjectWithEntry(WorldObject* source, uint32 entry, float maxSearchRange)
{
return source->FindNearestGameObject(entry, maxSearchRange);
}
-TC_GAME_API void GetCreatureListWithEntryInGrid(std::list<Creature*>& list, WorldObject* source, uint32 entry, float maxSearchRange)
+void GetCreatureListWithEntryInGrid(std::list<Creature*>& list, WorldObject* source, uint32 entry, float maxSearchRange)
{
source->GetCreatureListWithEntryInGrid(list, entry, maxSearchRange);
}
-TC_GAME_API void GetGameObjectListWithEntryInGrid(std::list<GameObject*>& list, WorldObject* source, uint32 entry, float maxSearchRange)
+void GetGameObjectListWithEntryInGrid(std::list<GameObject*>& list, WorldObject* source, uint32 entry, float maxSearchRange)
{
source->GetGameObjectListWithEntryInGrid(list, entry, maxSearchRange);
}
-TC_GAME_API void GetPlayerListInGrid(std::list<Player*>& list, WorldObject* source, float maxSearchRange)
+void GetPlayerListInGrid(std::list<Player*>& list, WorldObject* source, float maxSearchRange)
{
source->GetPlayerListInGrid(list, maxSearchRange);
}
diff --git a/src/server/game/AI/ScriptedAI/ScriptedCreature.h b/src/server/game/AI/ScriptedAI/ScriptedCreature.h
index 42befa26a23..6144a4e5203 100644
--- a/src/server/game/AI/ScriptedAI/ScriptedCreature.h
+++ b/src/server/game/AI/ScriptedAI/ScriptedCreature.h
@@ -114,7 +114,7 @@ public:
}
}
- void DoZoneInCombat(uint32 entry = 0);
+ void DoZoneInCombat(uint32 entry = 0, float maxRangeToNearestTarget = 250.0f);
void RemoveNotExisting();
bool HasEntry(uint32 entry) const;
@@ -367,7 +367,7 @@ class TC_GAME_API BossAI : public ScriptedAI
void _EnterCombat();
void _JustDied();
void _JustReachedHome() { me->setActive(false); }
- void _DespawnAtEvade(uint32 delayToRespawn = 30);
+ void _DespawnAtEvade(uint32 delayToRespawn = 30, Creature* who = nullptr);
void TeleportCheaters();
diff --git a/src/server/game/AI/SmartScripts/SmartAI.cpp b/src/server/game/AI/SmartScripts/SmartAI.cpp
index 8e9bd7cdff7..60df4fe6d5a 100644
--- a/src/server/game/AI/SmartScripts/SmartAI.cpp
+++ b/src/server/game/AI/SmartScripts/SmartAI.cpp
@@ -416,12 +416,7 @@ void SmartAI::EnterEvadeMode(EvadeReason /*why*/)
me->RemoveAurasOnEvade();
me->AddUnitState(UNIT_STATE_EVADE);
- me->DeleteThreatList();
- me->CombatStop(true);
- me->LoadCreaturesAddon();
- me->SetLootRecipient(NULL);
- me->ResetPlayerDamageReq();
- me->SetLastDamagedTime(0);
+ _EnterEvadeMode();
GetScript()->ProcessEventsFor(SMART_EVENT_EVADE);//must be after aura clear so we can cast spells from db
@@ -653,8 +648,8 @@ void SmartAI::OnCharmed(bool apply)
{
GetScript()->ProcessEventsFor(SMART_EVENT_CHARMED, NULL, 0, 0, apply);
- if (!apply && !me->IsInEvadeMode() && me->GetCharmerGUID())
- if (Unit* charmer = ObjectAccessor::GetUnit(*me, me->GetCharmerGUID()))
+ if (!apply && !me->IsInEvadeMode())
+ if (Unit* charmer = me->GetCharmer())
AttackStart(charmer);
}
diff --git a/src/server/game/Accounts/RBAC.h b/src/server/game/Accounts/RBAC.h
index 5f883175157..9dd56ec8180 100644
--- a/src/server/game/Accounts/RBAC.h
+++ b/src/server/game/Accounts/RBAC.h
@@ -697,6 +697,10 @@ enum RBACPermissions
// 799 - 834 6.x only
RBAC_PERM_COMMAND_DEBUG_LOADCELLS = 835,
RBAC_PERM_COMMAND_DEBUG_BOUNDARY = 836,
+ RBAC_PERM_COMMAND_NPC_EVADE = 837,
+ RBAC_PERM_COMMAND_PET_LEVEL = 838,
+ RBAC_PERM_COMMAND_SERVER_SHUTDOWN_FORCE = 839,
+ RBAC_PERM_COMMAND_SERVER_RESTART_FORCE = 840,
// custom permissions 1000+
RBAC_PERM_MAX
diff --git a/src/server/game/Achievements/AchievementMgr.cpp b/src/server/game/Achievements/AchievementMgr.cpp
index 87f5ff6ce5c..11c2635da33 100644
--- a/src/server/game/Achievements/AchievementMgr.cpp
+++ b/src/server/game/Achievements/AchievementMgr.cpp
@@ -646,13 +646,20 @@ void AchievementMgr::SendAchievementEarned(AchievementEntry const* achievement)
if (achievement->flags & (ACHIEVEMENT_FLAG_REALM_FIRST_KILL | ACHIEVEMENT_FLAG_REALM_FIRST_REACH))
{
+ uint32 team = GetPlayer()->GetTeam();
+
// broadcast realm first reached
WorldPacket data(SMSG_SERVER_FIRST_ACHIEVEMENT, GetPlayer()->GetName().size() + 1 + 8 + 4 + 4);
data << GetPlayer()->GetName();
data << uint64(GetPlayer()->GetGUID());
data << uint32(achievement->ID);
- data << uint32(0); // 1=link supplied string as player name, 0=display plain string
- sWorld->SendGlobalMessage(&data);
+
+ std::size_t linkTypePos = data.wpos();
+ data << uint32(1); // display name as clickable link in chat
+ sWorld->SendGlobalMessage(&data, nullptr, team);
+
+ data.put<uint32>(linkTypePos, 0); // display name as plain string in chat
+ sWorld->SendGlobalMessage(&data, nullptr, team == ALLIANCE ? HORDE : ALLIANCE);
}
// if player is in world he can tell his friends about new achievement
else if (GetPlayer()->IsInWorld())
diff --git a/src/server/game/DataStores/DBCEnums.h b/src/server/game/DataStores/DBCEnums.h
index f0ea5b4a5f1..cb2f26e567f 100644
--- a/src/server/game/DataStores/DBCEnums.h
+++ b/src/server/game/DataStores/DBCEnums.h
@@ -19,6 +19,22 @@
#ifndef DBCENUMS_H
#define DBCENUMS_H
+#pragma pack(push, 1)
+
+struct DBCPosition2D
+{
+ float X;
+ float Y;
+};
+
+struct DBCPosition3D
+{
+ float X;
+ float Y;
+ float Z;
+};
+
+#pragma pack(pop)
enum LevelLimit
{
// Client expected level limitation, like as used in DBC item max levels for "until max player level"
diff --git a/src/server/game/DataStores/DBCStores.cpp b/src/server/game/DataStores/DBCStores.cpp
index 5ede70da2a3..36ec418ed56 100644
--- a/src/server/game/DataStores/DBCStores.cpp
+++ b/src/server/game/DataStores/DBCStores.cpp
@@ -27,9 +27,6 @@
#include <boost/regex.hpp>
#include <map>
-#include <fstream>
-#include <iostream>
-#include <iomanip>
typedef std::map<uint16, uint32> AreaFlagByAreaID;
typedef std::map<uint32, uint32> AreaFlagByMapID;
@@ -221,8 +218,6 @@ DBCStorage <WorldMapAreaEntry> sWorldMapAreaStore(WorldMapAreaEntryfmt);
DBCStorage <WorldMapOverlayEntry> sWorldMapOverlayStore(WorldMapOverlayEntryfmt);
DBCStorage <WorldSafeLocsEntry> sWorldSafeLocsStore(WorldSafeLocsEntryfmt);
-std::unordered_map<uint32, FlyByCameraCollection> sFlyByCameraStore;
-
typedef std::list<std::string> StoreProblemList;
uint32 DBCFileCount = 0;
@@ -724,250 +719,10 @@ void LoadDBCStores(const std::string& dataPath)
exit(1);
}
- LoadM2Cameras(dataPath);
-
TC_LOG_INFO("server.loading", ">> Initialized %d data stores in %u ms", DBCFileCount, GetMSTimeDiffToNow(oldMSTime));
}
-// Convert the geomoetry from a spline value, to an actual WoW XYZ
-G3D::Vector3 TranslateLocation(G3D::Vector4 const* DBCPosition, G3D::Vector3 const* basePosition, G3D::Vector3 const* splineVector)
-{
- G3D::Vector3 work;
- float x = basePosition->x + splineVector->x;
- float y = basePosition->y + splineVector->y;
- float z = basePosition->z + splineVector->z;
- float const distance = sqrt((x * x) + (y * y));
- float angle = std::atan2(x, y) - DBCPosition->w;
-
- if (angle < 0)
- angle += 2 * float(M_PI);
-
- work.x = DBCPosition->x + (distance * sin(angle));
- work.y = DBCPosition->y + (distance * cos(angle));
- work.z = DBCPosition->z + z;
- return work;
-}
-
-// Number of cameras not used. Multiple cameras never used in 3.3.5
-bool readCamera(M2Camera const* cam, uint32 buffSize, M2Header const* header, CinematicCameraEntry const* dbcentry)
-{
- char const* buffer = reinterpret_cast<char const*>(header);
-
- FlyByCameraCollection cameras;
- FlyByCameraCollection targetcam;
-
- G3D::Vector4 DBCData;
- DBCData.x = dbcentry->base_x;
- DBCData.y = dbcentry->base_y;
- DBCData.z = dbcentry->base_z;
- DBCData.w = dbcentry->base_o;
-
- // Read target locations, only so that we can calculate orientation
- for (uint32 k = 0; k < cam->target_positions.timestamps.number; ++k)
- {
- // Extract Target positions
- if (cam->target_positions.timestamps.offset_elements + sizeof(M2Array) > buffSize)
- return false;
- M2Array const* targTsArray = reinterpret_cast<M2Array const*>(buffer + cam->target_positions.timestamps.offset_elements);
- if (targTsArray->offset_elements + sizeof(uint32) > buffSize || cam->target_positions.values.offset_elements + sizeof(M2Array) > buffSize)
- return false;
- uint32 const* targTimestamps = reinterpret_cast<uint32 const*>(buffer + targTsArray->offset_elements);
- M2Array const* targArray = reinterpret_cast<M2Array const*>(buffer + cam->target_positions.values.offset_elements);
-
- if (targArray->offset_elements + sizeof(M2SplineKey<G3D::Vector3>) > buffSize)
- return false;
- M2SplineKey<G3D::Vector3> const* targPositions = reinterpret_cast<M2SplineKey<G3D::Vector3> const*>(buffer + targArray->offset_elements);
-
- // Read the data for this set
- uint32 currPos = targArray->offset_elements;
- for (uint32 i = 0; i < targTsArray->number; ++i)
- {
- if (currPos + sizeof(M2SplineKey<G3D::Vector3>) > buffSize)
- return false;
- // Translate co-ordinates
- G3D::Vector3 newPos = TranslateLocation(&DBCData, &cam->target_position_base, &targPositions->p0);
-
- // Add to vector
- FlyByCamera thisCam;
- thisCam.timeStamp = targTimestamps[i];
- thisCam.locations.x = newPos.x;
- thisCam.locations.y = newPos.y;
- thisCam.locations.z = newPos.z;
- thisCam.locations.w = 0.0f;
- targetcam.push_back(thisCam);
- targPositions++;
- currPos += sizeof(M2SplineKey<G3D::Vector3>);
- }
- }
-
- // Read camera positions and timestamps (translating first position of 3 only, we don't need to translate the whole spline)
- for (uint32 k = 0; k < cam->positions.timestamps.number; ++k)
- {
- // Extract Camera positions for this set
- if (cam->positions.timestamps.offset_elements + sizeof(M2Array) > buffSize)
- return false;
- M2Array const* posTsArray = reinterpret_cast<M2Array const*>(buffer + cam->positions.timestamps.offset_elements);
- if (posTsArray->offset_elements + sizeof(uint32) > buffSize || cam->positions.values.offset_elements + sizeof(M2Array) > buffSize)
- return false;
- uint32 const* posTimestamps = reinterpret_cast<uint32 const*>(buffer + posTsArray->offset_elements);
- M2Array const* posArray = reinterpret_cast<M2Array const*>(buffer + cam->positions.values.offset_elements);
- if (posArray->offset_elements + sizeof(M2SplineKey<G3D::Vector3>) > buffSize)
- return false;
- M2SplineKey<G3D::Vector3> const* positions = reinterpret_cast<M2SplineKey<G3D::Vector3> const*>(buffer + posArray->offset_elements);
-
- // Read the data for this set
- uint32 currPos = posArray->offset_elements;
- for (uint32 i = 0; i < posTsArray->number; ++i)
- {
- if (currPos + sizeof(M2SplineKey<G3D::Vector3>) > buffSize)
- return false;
- // Translate co-ordinates
- G3D::Vector3 newPos = TranslateLocation(&DBCData, &cam->position_base, &positions->p0);
-
- // Add to vector
- FlyByCamera thisCam;
- thisCam.timeStamp = posTimestamps[i];
- thisCam.locations.x = newPos.x;
- thisCam.locations.y = newPos.y;
- thisCam.locations.z = newPos.z;
-
- if (targetcam.size() > 0)
- {
- // Find the target camera before and after this camera
- FlyByCamera lastTarget;
- FlyByCamera nextTarget;
-
- // Pre-load first item
- lastTarget = targetcam[0];
- nextTarget = targetcam[0];
- for (uint32 j = 0; j < targetcam.size(); ++j)
- {
- nextTarget = targetcam[j];
- if (targetcam[j].timeStamp > posTimestamps[i])
- break;
-
- lastTarget = targetcam[j];
- }
-
- float x = lastTarget.locations.x;
- float y = lastTarget.locations.y;
- float z = lastTarget.locations.z;
-
- // Now, the timestamps for target cam and position can be different. So, if they differ we interpolate
- if (lastTarget.timeStamp != posTimestamps[i])
- {
- uint32 timeDiffTarget = nextTarget.timeStamp - lastTarget.timeStamp;
- uint32 timeDiffThis = posTimestamps[i] - lastTarget.timeStamp;
- float xDiff = nextTarget.locations.x - lastTarget.locations.x;
- float yDiff = nextTarget.locations.y - lastTarget.locations.y;
- float zDiff = nextTarget.locations.z - lastTarget.locations.z;
- x = lastTarget.locations.x + (xDiff * (float(timeDiffThis) / float(timeDiffTarget)));
- y = lastTarget.locations.y + (yDiff * (float(timeDiffThis) / float(timeDiffTarget)));
- z = lastTarget.locations.z + (zDiff * (float(timeDiffThis) / float(timeDiffTarget)));
- }
- float xDiff = x - thisCam.locations.x;
- float yDiff = y - thisCam.locations.y;
- thisCam.locations.w = std::atan2(yDiff, xDiff);
-
- if (thisCam.locations.w < 0)
- thisCam.locations.w += 2 * float(M_PI);
- }
-
- cameras.push_back(thisCam);
- positions++;
- currPos += sizeof(M2SplineKey<G3D::Vector3>);
- }
- }
-
- sFlyByCameraStore[dbcentry->id] = cameras;
- return true;
-}
-
-void LoadM2Cameras(const std::string& dataPath)
-{
- sFlyByCameraStore.clear();
- TC_LOG_INFO("server.loading", ">> Loading Cinematic Camera files");
-
- uint32 oldMSTime = getMSTime();
- for (uint32 i = 0; i < sCinematicCameraStore.GetNumRows(); ++i)
- {
- if (CinematicCameraEntry const* dbcentry = sCinematicCameraStore.LookupEntry(i))
- {
- std::string filename = dataPath.c_str();
- filename.append(dbcentry->filename);
-
- // Replace slashes
- size_t loc = filename.find("\\");
- while (loc != std::string::npos)
- {
- filename.replace(loc, 1, "/");
- loc = filename.find("\\");
- }
-
- // Replace mdx to .m2
- loc = filename.find(".mdx");
- if (loc != std::string::npos)
- filename.replace(loc, 4, ".m2");
-
- std::ifstream m2file(filename.c_str(), std::ios::in | std::ios::binary);
- if (!m2file.is_open())
- continue;
-
- // Get file size
- m2file.seekg(0, std::ios::end);
- std::streamoff const fileSize = m2file.tellg();
-
- // Reject if not at least the size of the header
- if (static_cast<uint32 const>(fileSize) < sizeof(M2Header))
- {
- TC_LOG_ERROR("server.loading", "Camera file %s is damaged. File is smaller than header size", filename.c_str());
- m2file.close();
- continue;
- }
-
- // Read 4 bytes (signature)
- m2file.seekg(0, std::ios::beg);
- char fileCheck[5];
- m2file.read(fileCheck, 4);
- fileCheck[4] = 0;
-
- // Check file has correct magic (MD20)
- if (strcmp(fileCheck, "MD20"))
- {
- TC_LOG_ERROR("server.loading", "Camera file %s is damaged. File identifier not found", filename.c_str());
- m2file.close();
- continue;
- }
-
- // Now we have a good file, read it all into a vector of char's, then close the file.
- std::vector<char> buffer(fileSize);
- m2file.seekg(0, std::ios::beg);
- if (!m2file.read(buffer.data(), fileSize))
- {
- m2file.close();
- continue;
- }
- m2file.close();
-
- // Read header
- M2Header const* header = reinterpret_cast<M2Header const*>(buffer.data());
-
- if (header->ofsCameras + sizeof(M2Camera) > static_cast<uint32 const>(fileSize))
- {
- TC_LOG_ERROR("server.loading", "Camera file %s is damaged. Camera references position beyond file end", filename.c_str());
- continue;
- }
-
- // Get camera(s) - Main header, then dump them.
- M2Camera const* cam = reinterpret_cast<M2Camera const*>(buffer.data() + header->ofsCameras);
- if (!readCamera(cam, fileSize, header, dbcentry))
- TC_LOG_ERROR("server.loading", "Camera file %s is damaged. Camera references position beyond file end", filename.c_str());
- }
- }
- TC_LOG_INFO("server.loading", ">> Loaded %u cinematic waypoint sets in %u ms", (uint32)sFlyByCameraStore.size(), GetMSTimeDiffToNow(oldMSTime));
-}
-
SimpleFactionsList const* GetFactionTeamList(uint32 faction)
{
FactionTeamMap::const_iterator itr = sFactionTeamMap.find(faction);
diff --git a/src/server/game/DataStores/DBCStores.h b/src/server/game/DataStores/DBCStores.h
index 6cad13fdf9a..00b4141555f 100644
--- a/src/server/game/DataStores/DBCStores.h
+++ b/src/server/game/DataStores/DBCStores.h
@@ -27,8 +27,6 @@
#include <list>
typedef std::list<uint32> SimpleFactionsList;
-typedef std::vector<FlyByCamera> FlyByCameraCollection;
-
TC_GAME_API SimpleFactionsList const* GetFactionTeamList(uint32 faction);
TC_GAME_API char* GetPetName(uint32 petfamily, uint32 dbclang);
@@ -196,9 +194,7 @@ TC_GAME_API extern DBCStorage <WMOAreaTableEntry> sWMOAreaTableStore;
//TC_GAME_API extern DBCStorage <WorldMapAreaEntry> sWorldMapAreaStore; -- use Zone2MapCoordinates and Map2ZoneCoordinates
TC_GAME_API extern DBCStorage <WorldMapOverlayEntry> sWorldMapOverlayStore;
TC_GAME_API extern DBCStorage <WorldSafeLocsEntry> sWorldSafeLocsStore;
-TC_GAME_API extern std::unordered_map<uint32, FlyByCameraCollection> sFlyByCameraStore;
TC_GAME_API void LoadDBCStores(const std::string& dataPath);
-TC_GAME_API void LoadM2Cameras(const std::string& dataPath);
#endif
diff --git a/src/server/game/DataStores/DBCStructure.h b/src/server/game/DataStores/DBCStructure.h
index 51b3dcbd38b..13f0198a5e7 100644
--- a/src/server/game/DataStores/DBCStructure.h
+++ b/src/server/game/DataStores/DBCStructure.h
@@ -727,13 +727,11 @@ struct ChrRacesEntry
struct CinematicCameraEntry
{
- uint32 id; // 0 index
- char* filename; // 1
- uint32 soundid; // 2 in SoundEntries.dbc or 0
- float base_x; // 3
- float base_y; // 4
- float base_z; // 5
- float base_o; // 6
+ uint32 ID; // 0
+ char const* Model; // 1 Model filename (translate .mdx to .m2)
+ uint32 SoundID; // 2 Sound ID (voiceover for cinematic)
+ DBCPosition3D Origin; // 3-5 Position in map used for basis for M2 co-ordinates
+ float OriginFacing; // 6 Orientation in map used for basis for M2 co-ordinates
};
struct CinematicSequencesEntry
diff --git a/src/server/game/DataStores/M2Stores.cpp b/src/server/game/DataStores/M2Stores.cpp
new file mode 100644
index 00000000000..5cff66e6107
--- /dev/null
+++ b/src/server/game/DataStores/M2Stores.cpp
@@ -0,0 +1,266 @@
+/*
+* Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/>
+*
+* This program is free software; you can redistribute it and/or modify it
+* under the terms of the GNU General Public License as published by the
+* Free Software Foundation; either version 2 of the License, or (at your
+* option) any later version.
+*
+* This program is distributed in the hope that it will be useful, but WITHOUT
+* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+* more details.
+*
+* You should have received a copy of the GNU General Public License along
+* with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "DBCStores.h"
+#include "M2Structure.h"
+#include "M2Stores.h"
+#include "Common.h"
+#include "Containers.h"
+#include "Log.h"
+#include "World.h"
+#include <fstream>
+#include <iostream>
+#include <iomanip>
+#include <boost/filesystem/path.hpp>
+
+std::unordered_map<uint32, FlyByCameraCollection> sFlyByCameraStore;
+
+// Convert the geomoetry from a spline value, to an actual WoW XYZ
+G3D::Vector3 TranslateLocation(G3D::Vector4 const* DBCPosition, G3D::Vector3 const* basePosition, G3D::Vector3 const* splineVector)
+{
+ G3D::Vector3 work;
+ float x = basePosition->x + splineVector->x;
+ float y = basePosition->y + splineVector->y;
+ float z = basePosition->z + splineVector->z;
+ float const distance = sqrt((x * x) + (y * y));
+ float angle = std::atan2(x, y) - DBCPosition->w;
+
+ if (angle < 0)
+ angle += 2 * float(M_PI);
+
+ work.x = DBCPosition->x + (distance * sin(angle));
+ work.y = DBCPosition->y + (distance * cos(angle));
+ work.z = DBCPosition->z + z;
+ return work;
+}
+
+// Number of cameras not used. Multiple cameras never used in 3.3.5
+bool readCamera(M2Camera const* cam, uint32 buffSize, M2Header const* header, CinematicCameraEntry const* dbcentry)
+{
+ char const* buffer = reinterpret_cast<char const*>(header);
+
+ FlyByCameraCollection cameras;
+ FlyByCameraCollection targetcam;
+
+ G3D::Vector4 DBCData;
+ DBCData.x = dbcentry->Origin.X;
+ DBCData.y = dbcentry->Origin.Y;
+ DBCData.z = dbcentry->Origin.Z;
+ DBCData.w = dbcentry->OriginFacing;
+
+ // Read target locations, only so that we can calculate orientation
+ for (uint32 k = 0; k < cam->target_positions.timestamps.number; ++k)
+ {
+ // Extract Target positions
+ if (cam->target_positions.timestamps.offset_elements + sizeof(M2Array) > buffSize)
+ return false;
+ M2Array const* targTsArray = reinterpret_cast<M2Array const*>(buffer + cam->target_positions.timestamps.offset_elements);
+ if (targTsArray->offset_elements + sizeof(uint32) > buffSize || cam->target_positions.values.offset_elements + sizeof(M2Array) > buffSize)
+ return false;
+ uint32 const* targTimestamps = reinterpret_cast<uint32 const*>(buffer + targTsArray->offset_elements);
+ M2Array const* targArray = reinterpret_cast<M2Array const*>(buffer + cam->target_positions.values.offset_elements);
+
+ if (targArray->offset_elements + sizeof(M2SplineKey<G3D::Vector3>) > buffSize)
+ return false;
+ M2SplineKey<G3D::Vector3> const* targPositions = reinterpret_cast<M2SplineKey<G3D::Vector3> const*>(buffer + targArray->offset_elements);
+
+ // Read the data for this set
+ uint32 currPos = targArray->offset_elements;
+ for (uint32 i = 0; i < targTsArray->number; ++i)
+ {
+ if (currPos + sizeof(M2SplineKey<G3D::Vector3>) > buffSize)
+ return false;
+ // Translate co-ordinates
+ G3D::Vector3 newPos = TranslateLocation(&DBCData, &cam->target_position_base, &targPositions->p0);
+
+ // Add to vector
+ FlyByCamera thisCam;
+ thisCam.timeStamp = targTimestamps[i];
+ thisCam.locations.x = newPos.x;
+ thisCam.locations.y = newPos.y;
+ thisCam.locations.z = newPos.z;
+ thisCam.locations.w = 0.0f;
+ targetcam.push_back(thisCam);
+ targPositions++;
+ currPos += sizeof(M2SplineKey<G3D::Vector3>);
+ }
+ }
+
+ // Read camera positions and timestamps (translating first position of 3 only, we don't need to translate the whole spline)
+ for (uint32 k = 0; k < cam->positions.timestamps.number; ++k)
+ {
+ // Extract Camera positions for this set
+ if (cam->positions.timestamps.offset_elements + sizeof(M2Array) > buffSize)
+ return false;
+ M2Array const* posTsArray = reinterpret_cast<M2Array const*>(buffer + cam->positions.timestamps.offset_elements);
+ if (posTsArray->offset_elements + sizeof(uint32) > buffSize || cam->positions.values.offset_elements + sizeof(M2Array) > buffSize)
+ return false;
+ uint32 const* posTimestamps = reinterpret_cast<uint32 const*>(buffer + posTsArray->offset_elements);
+ M2Array const* posArray = reinterpret_cast<M2Array const*>(buffer + cam->positions.values.offset_elements);
+ if (posArray->offset_elements + sizeof(M2SplineKey<G3D::Vector3>) > buffSize)
+ return false;
+ M2SplineKey<G3D::Vector3> const* positions = reinterpret_cast<M2SplineKey<G3D::Vector3> const*>(buffer + posArray->offset_elements);
+
+ // Read the data for this set
+ uint32 currPos = posArray->offset_elements;
+ for (uint32 i = 0; i < posTsArray->number; ++i)
+ {
+ if (currPos + sizeof(M2SplineKey<G3D::Vector3>) > buffSize)
+ return false;
+ // Translate co-ordinates
+ G3D::Vector3 newPos = TranslateLocation(&DBCData, &cam->position_base, &positions->p0);
+
+ // Add to vector
+ FlyByCamera thisCam;
+ thisCam.timeStamp = posTimestamps[i];
+ thisCam.locations.x = newPos.x;
+ thisCam.locations.y = newPos.y;
+ thisCam.locations.z = newPos.z;
+
+ if (targetcam.size() > 0)
+ {
+ // Find the target camera before and after this camera
+ FlyByCamera lastTarget;
+ FlyByCamera nextTarget;
+
+ // Pre-load first item
+ lastTarget = targetcam[0];
+ nextTarget = targetcam[0];
+ for (uint32 j = 0; j < targetcam.size(); ++j)
+ {
+ nextTarget = targetcam[j];
+ if (targetcam[j].timeStamp > posTimestamps[i])
+ break;
+
+ lastTarget = targetcam[j];
+ }
+
+ float x = lastTarget.locations.x;
+ float y = lastTarget.locations.y;
+ float z = lastTarget.locations.z;
+
+ // Now, the timestamps for target cam and position can be different. So, if they differ we interpolate
+ if (lastTarget.timeStamp != posTimestamps[i])
+ {
+ uint32 timeDiffTarget = nextTarget.timeStamp - lastTarget.timeStamp;
+ uint32 timeDiffThis = posTimestamps[i] - lastTarget.timeStamp;
+ float xDiff = nextTarget.locations.x - lastTarget.locations.x;
+ float yDiff = nextTarget.locations.y - lastTarget.locations.y;
+ float zDiff = nextTarget.locations.z - lastTarget.locations.z;
+ x = lastTarget.locations.x + (xDiff * (float(timeDiffThis) / float(timeDiffTarget)));
+ y = lastTarget.locations.y + (yDiff * (float(timeDiffThis) / float(timeDiffTarget)));
+ z = lastTarget.locations.z + (zDiff * (float(timeDiffThis) / float(timeDiffTarget)));
+ }
+ float xDiff = x - thisCam.locations.x;
+ float yDiff = y - thisCam.locations.y;
+ thisCam.locations.w = std::atan2(yDiff, xDiff);
+
+ if (thisCam.locations.w < 0)
+ thisCam.locations.w += 2 * float(M_PI);
+ }
+
+ cameras.push_back(thisCam);
+ positions++;
+ currPos += sizeof(M2SplineKey<G3D::Vector3>);
+ }
+ }
+
+ sFlyByCameraStore[dbcentry->ID] = cameras;
+ return true;
+}
+
+void LoadM2Cameras(std::string const& dataPath)
+{
+ sFlyByCameraStore.clear();
+ TC_LOG_INFO("server.loading", ">> Loading Cinematic Camera files");
+
+ uint32 oldMSTime = getMSTime();
+ for (uint32 i = 0; i < sCinematicCameraStore.GetNumRows(); ++i)
+ {
+ if (CinematicCameraEntry const* dbcentry = sCinematicCameraStore.LookupEntry(i))
+ {
+ std::string filenameWork = dataPath.c_str();
+ filenameWork.append(dbcentry->Model);
+
+ // Replace slashes (always to forward slash, because boost!)
+ std::replace(filenameWork.begin(), filenameWork.end(), '\\', '/');
+
+ boost::filesystem::path filename = filenameWork;
+
+ // Convert to native format
+ filename.make_preferred();
+
+ // Replace mdx to .m2
+ filename.replace_extension("m2");
+
+ std::ifstream m2file(filename.string().c_str(), std::ios::in | std::ios::binary);
+ if (!m2file.is_open())
+ continue;
+
+ // Get file size
+ m2file.seekg(0, std::ios::end);
+ std::streamoff const fileSize = m2file.tellg();
+
+ // Reject if not at least the size of the header
+ if (static_cast<uint32 const>(fileSize) < sizeof(M2Header))
+ {
+ TC_LOG_ERROR("server.loading", "Camera file %s is damaged. File is smaller than header size", filename.string().c_str());
+ m2file.close();
+ continue;
+ }
+
+ // Read 4 bytes (signature)
+ m2file.seekg(0, std::ios::beg);
+ char fileCheck[5];
+ m2file.read(fileCheck, 4);
+ fileCheck[4] = 0;
+
+ // Check file has correct magic (MD20)
+ if (strcmp(fileCheck, "MD20"))
+ {
+ TC_LOG_ERROR("server.loading", "Camera file %s is damaged. File identifier not found", filename.string().c_str());
+ m2file.close();
+ continue;
+ }
+
+ // Now we have a good file, read it all into a vector of char's, then close the file.
+ std::vector<char> buffer(fileSize);
+ m2file.seekg(0, std::ios::beg);
+ if (!m2file.read(buffer.data(), fileSize))
+ {
+ m2file.close();
+ continue;
+ }
+ m2file.close();
+
+ // Read header
+ M2Header const* header = reinterpret_cast<M2Header const*>(buffer.data());
+
+ if (header->ofsCameras + sizeof(M2Camera) > static_cast<uint32 const>(fileSize))
+ {
+ TC_LOG_ERROR("server.loading", "Camera file %s is damaged. Camera references position beyond file end", filename.string().c_str());
+ continue;
+ }
+
+ // Get camera(s) - Main header, then dump them.
+ M2Camera const* cam = reinterpret_cast<M2Camera const*>(buffer.data() + header->ofsCameras);
+ if (!readCamera(cam, fileSize, header, dbcentry))
+ TC_LOG_ERROR("server.loading", "Camera file %s is damaged. Camera references position beyond file end", filename.string().c_str());
+ }
+ }
+ TC_LOG_INFO("server.loading", ">> Loaded %u cinematic waypoint sets in %u ms", (uint32)sFlyByCameraStore.size(), GetMSTimeDiffToNow(oldMSTime));
+}
diff --git a/src/server/game/DataStores/M2Stores.h b/src/server/game/DataStores/M2Stores.h
new file mode 100644
index 00000000000..97224475e5d
--- /dev/null
+++ b/src/server/game/DataStores/M2Stores.h
@@ -0,0 +1,36 @@
+/*
+* Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/>
+*
+* This program is free software; you can redistribute it and/or modify it
+* under the terms of the GNU General Public License as published by the
+* Free Software Foundation; either version 2 of the License, or (at your
+* option) any later version.
+*
+* This program is distributed in the hope that it will be useful, but WITHOUT
+* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+* more details.
+*
+* You should have received a copy of the GNU General Public License along
+* with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef TRINITY_M2STORES_H
+#define TRINITY_M2STORES_H
+
+#include "SharedDefines.h"
+#include "Common.h"
+
+struct FlyByCamera
+{
+ uint32 timeStamp;
+ G3D::Vector4 locations;
+};
+
+typedef std::vector<FlyByCamera> FlyByCameraCollection;
+
+TC_GAME_API extern std::unordered_map<uint32, FlyByCameraCollection> sFlyByCameraStore;
+
+TC_GAME_API void LoadM2Cameras(std::string const& dataPath);
+
+#endif \ No newline at end of file
diff --git a/src/server/game/DataStores/M2Structure.h b/src/server/game/DataStores/M2Structure.h
new file mode 100644
index 00000000000..43e8d008b9f
--- /dev/null
+++ b/src/server/game/DataStores/M2Structure.h
@@ -0,0 +1,133 @@
+/*
+* Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/>
+*
+* This program is free software; you can redistribute it and/or modify it
+* under the terms of the GNU General Public License as published by the
+* Free Software Foundation; either version 2 of the License, or (at your
+* option) any later version.
+*
+* This program is distributed in the hope that it will be useful, but WITHOUT
+* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+* more details.
+*
+* You should have received a copy of the GNU General Public License along
+* with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef TRINITY_M2STRUCTURE_H
+#define TRINITY_M2STRUCTURE_H
+
+#include <G3D/Vector3.h>
+#include <G3D/AABox.h>
+
+// Structures for M2 file. Source: https://wowdev.wiki
+#pragma pack(push, 1)
+template<typename T>
+struct M2SplineKey
+{
+ T p0;
+ T p1;
+ T p2;
+};
+
+struct M2Header
+{
+ char Magic[4]; // "MD20"
+ uint32 Version; // The version of the format.
+ uint32 lName; // Length of the model's name including the trailing \0
+ uint32 ofsName; // Offset to the name, it seems like models can get reloaded by this name.should be unique, i guess.
+ uint32 GlobalModelFlags; // 0x0001: tilt x, 0x0002: tilt y, 0x0008: add 2 fields in header, 0x0020: load .phys data (MoP+), 0x0080: has _lod .skin files (MoP?+), 0x0100: is camera related.
+ uint32 nGlobalSequences;
+ uint32 ofsGlobalSequences; // A list of timestamps.
+ uint32 nAnimations;
+ uint32 ofsAnimations; // Information about the animations in the model.
+ uint32 nAnimationLookup;
+ uint32 ofsAnimationLookup; // Mapping of global IDs to the entries in the Animation sequences block.
+ uint32 nBones; // MAX_BONES = 0x100
+ uint32 ofsBones; // Information about the bones in this model.
+ uint32 nKeyBoneLookup;
+ uint32 ofsKeyBoneLookup; // Lookup table for key skeletal bones.
+ uint32 nVertices;
+ uint32 ofsVertices; // Vertices of the model.
+ uint32 nViews; // Views (LOD) are now in .skins.
+ uint32 nSubmeshAnimations;
+ uint32 ofsSubmeshAnimations; // Submesh color and alpha animations definitions.
+ uint32 nTextures;
+ uint32 ofsTextures; // Textures of this model.
+ uint32 nTransparency;
+ uint32 ofsTransparency; // Transparency of textures.
+ uint32 nUVAnimation;
+ uint32 ofsUVAnimation;
+ uint32 nTexReplace;
+ uint32 ofsTexReplace; // Replaceable Textures.
+ uint32 nRenderFlags;
+ uint32 ofsRenderFlags; // Blending modes / render flags.
+ uint32 nBoneLookupTable;
+ uint32 ofsBoneLookupTable; // A bone lookup table.
+ uint32 nTexLookup;
+ uint32 ofsTexLookup; // The same for textures.
+ uint32 nTexUnits; // possibly removed with cata?!
+ uint32 ofsTexUnits; // And texture units. Somewhere they have to be too.
+ uint32 nTransLookup;
+ uint32 ofsTransLookup; // Everything needs its lookup. Here are the transparencies.
+ uint32 nUVAnimLookup;
+ uint32 ofsUVAnimLookup;
+ G3D::AABox BoundingBox; // min/max( [1].z, 2.0277779f ) - 0.16f seems to be the maximum camera height
+ float BoundingSphereRadius;
+ G3D::AABox CollisionBox;
+ float CollisionSphereRadius;
+ uint32 nBoundingTriangles;
+ uint32 ofsBoundingTriangles; // Our bounding volumes. Similar structure like in the old ofsViews.
+ uint32 nBoundingVertices;
+ uint32 ofsBoundingVertices;
+ uint32 nBoundingNormals;
+ uint32 ofsBoundingNormals;
+ uint32 nAttachments;
+ uint32 ofsAttachments; // Attachments are for weapons etc.
+ uint32 nAttachLookup;
+ uint32 ofsAttachLookup; // Of course with a lookup.
+ uint32 nEvents;
+ uint32 ofsEvents; // Used for playing sounds when dying and a lot else.
+ uint32 nLights;
+ uint32 ofsLights; // Lights are mainly used in loginscreens but in wands and some doodads too.
+ uint32 nCameras; // Format of Cameras changed with version 271!
+ uint32 ofsCameras; // The cameras are present in most models for having a model in the Character-Tab.
+ uint32 nCameraLookup;
+ uint32 ofsCameraLookup; // And lookup-time again.
+ uint32 nRibbonEmitters;
+ uint32 ofsRibbonEmitters; // Things swirling around. See the CoT-entrance for light-trails.
+ uint32 nParticleEmitters;
+ uint32 ofsParticleEmitters; // Spells and weapons, doodads and loginscreens use them. Blood dripping of a blade? Particles.
+ uint32 nBlendMaps; // This has to deal with blending. Exists IFF (flags & 0x8) != 0. When set, textures blending is overriden by the associated array. See M2/WotLK#Blend_mode_overrides
+ uint32 ofsBlendMaps; // Same as above. Points to an array of uint16 of nBlendMaps entries -- From WoD information.};
+};
+
+struct M2Array
+{
+ uint32_t number;
+ uint32 offset_elements;
+};
+struct M2Track
+{
+ uint16_t interpolation_type;
+ uint16_t global_sequence;
+ M2Array timestamps;
+ M2Array values;
+};
+
+struct M2Camera
+{
+ uint32_t type; // 0: portrait, 1: characterinfo; -1: else (flyby etc.); referenced backwards in the lookup table.
+ float fov; // No radians, no degrees. Multiply by 35 to get degrees.
+ float far_clip;
+ float near_clip;
+ M2Track positions; // How the camera's position moves. Should be 3*3 floats.
+ G3D::Vector3 position_base;
+ M2Track target_positions; // How the target moves. Should be 3*3 floats.
+ G3D::Vector3 target_position_base;
+ M2Track rolldata; // The camera can have some roll-effect. Its 0 to 2*Pi.
+};
+#pragma pack(pop)
+
+#endif \ No newline at end of file
diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp
index d3843c86aa4..450cf2396a8 100644
--- a/src/server/game/Entities/Creature/Creature.cpp
+++ b/src/server/game/Entities/Creature/Creature.cpp
@@ -182,13 +182,13 @@ m_groupLootTimer(0), lootingGroupLowGUID(0), m_PlayerDamageReq(0),
m_lootRecipient(), m_lootRecipientGroup(0), _skinner(), _pickpocketLootRestore(0), m_corpseRemoveTime(0), m_respawnTime(0),
m_respawnDelay(300), m_corpseDelay(60), m_respawnradius(0.0f), m_boundaryCheckTime(2500), m_combatPulseTime(0), m_combatPulseDelay(0), m_reactState(REACT_AGGRESSIVE),
m_defaultMovementType(IDLE_MOTION_TYPE), m_spawnId(0), m_equipmentId(0), m_originalEquipmentId(0), m_AlreadyCallAssistance(false),
-m_AlreadySearchedAssistance(false), m_regenHealth(true), m_AI_locked(false), m_meleeDamageSchoolMask(SPELL_SCHOOL_MASK_NORMAL),
+m_AlreadySearchedAssistance(false), m_regenHealth(true), m_cannotReachTarget(false), m_cannotReachTimer(0), m_AI_locked(false), m_meleeDamageSchoolMask(SPELL_SCHOOL_MASK_NORMAL),
m_originalEntry(0), m_homePosition(), m_transportHomePosition(), m_creatureInfo(nullptr), m_creatureData(nullptr), m_waypointID(0), m_path_id(0), m_formation(nullptr), m_focusSpell(nullptr), m_focusDelay(0)
{
m_regenTimer = CREATURE_REGEN_INTERVAL;
m_valuesCount = UNIT_END;
- for (uint8 i = 0; i < CREATURE_MAX_SPELLS; ++i)
+ for (uint8 i = 0; i < MAX_CREATURE_SPELLS; ++i)
m_spells[i] = 0;
DisableReputationGain = false;
@@ -394,7 +394,7 @@ bool Creature::InitEntry(uint32 entry, CreatureData const* data /*= nullptr*/)
if (!m_respawnradius && m_defaultMovementType == RANDOM_MOTION_TYPE)
m_defaultMovementType = IDLE_MOTION_TYPE;
- for (uint8 i=0; i < CREATURE_MAX_SPELLS; ++i)
+ for (uint8 i=0; i < MAX_CREATURE_SPELLS; ++i)
m_spells[i] = GetCreatureTemplate()->spells[i];
return true;
@@ -648,33 +648,32 @@ void Creature::Update(uint32 diff)
m_regenTimer -= diff;
}
- if (m_regenTimer != 0)
- break;
-
- bool bInCombat = IsInCombat() && (!GetVictim() || // if IsInCombat() is true and this has no victim
- !EnsureVictim()->GetCharmerOrOwnerPlayerOrPlayerItself() || // or the victim/owner/charmer is not a player
- !EnsureVictim()->GetCharmerOrOwnerPlayerOrPlayerItself()->IsGameMaster()); // or the victim/owner/charmer is not a GameMaster
+ if (m_regenTimer == 0)
+ {
+ bool bInCombat = IsInCombat() && (!GetVictim() || // if IsInCombat() is true and this has no victim
+ !EnsureVictim()->GetCharmerOrOwnerPlayerOrPlayerItself() || // or the victim/owner/charmer is not a player
+ !EnsureVictim()->GetCharmerOrOwnerPlayerOrPlayerItself()->IsGameMaster()); // or the victim/owner/charmer is not a GameMaster
- /*if (m_regenTimer <= diff)
- {*/
- if (!IsInEvadeMode() && (!bInCombat || IsPolymorphed())) // regenerate health if not in combat or if polymorphed
- RegenerateHealth();
+ if (!IsInEvadeMode() && (!bInCombat || IsPolymorphed() || CanNotReachTarget())) // regenerate health if not in combat or if polymorphed
+ RegenerateHealth();
- if (HasFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_REGENERATE_POWER))
- {
- if (getPowerType() == POWER_ENERGY)
- Regenerate(POWER_ENERGY);
- else
- RegenerateMana();
+ if (HasFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_REGENERATE_POWER))
+ {
+ if (getPowerType() == POWER_ENERGY)
+ Regenerate(POWER_ENERGY);
+ else
+ RegenerateMana();
+ }
+ m_regenTimer = CREATURE_REGEN_INTERVAL;
}
- /*if (!bIsPolymorphed) // only increase the timer if not polymorphed
- m_regenTimer += CREATURE_REGEN_INTERVAL - diff;
+ if (CanNotReachTarget() && !IsInEvadeMode() && !GetMap()->IsRaid())
+ {
+ m_cannotReachTimer += diff;
+ if (m_cannotReachTimer >= CREATURE_NOPATH_EVADE_TIME)
+ if (IsAIEnabled)
+ AI()->EnterEvadeMode(CreatureAI::EVADE_REASON_NO_PATH);
}
- else
- if (!bIsPolymorphed) // if polymorphed, skip the timer
- m_regenTimer -= diff;*/
- m_regenTimer = CREATURE_REGEN_INTERVAL;
break;
}
default:
@@ -1832,7 +1831,7 @@ SpellInfo const* Creature::reachWithSpellAttack(Unit* victim)
if (!victim)
return nullptr;
- for (uint32 i=0; i < CREATURE_MAX_SPELLS; ++i)
+ for (uint32 i=0; i < MAX_CREATURE_SPELLS; ++i)
{
if (!m_spells[i])
continue;
@@ -1880,7 +1879,7 @@ SpellInfo const* Creature::reachWithSpellCure(Unit* victim)
if (!victim)
return nullptr;
- for (uint32 i=0; i < CREATURE_MAX_SPELLS; ++i)
+ for (uint32 i=0; i < MAX_CREATURE_SPELLS; ++i)
{
if (!m_spells[i])
continue;
@@ -2325,10 +2324,10 @@ uint32 Creature::GetShieldBlockValue() const //dunno mob block
bool Creature::HasSpell(uint32 spellID) const
{
uint8 i;
- for (i = 0; i < CREATURE_MAX_SPELLS; ++i)
+ for (i = 0; i < MAX_CREATURE_SPELLS; ++i)
if (spellID == m_spells[i])
break;
- return i < CREATURE_MAX_SPELLS; //broke before end of iteration of known spells
+ return i < MAX_CREATURE_SPELLS; //broke before end of iteration of known spells
}
time_t Creature::GetRespawnTimeEx() const
diff --git a/src/server/game/Entities/Creature/Creature.h b/src/server/game/Entities/Creature/Creature.h
index 8466dad9e95..bb43bcb5ff1 100644
--- a/src/server/game/Entities/Creature/Creature.h
+++ b/src/server/game/Entities/Creature/Creature.h
@@ -67,12 +67,13 @@ enum CreatureFlagsExtra
CREATURE_FLAG_EXTRA_NO_SKILLGAIN | CREATURE_FLAG_EXTRA_TAUNT_DIMINISH | CREATURE_FLAG_EXTRA_ALL_DIMINISH | \
CREATURE_FLAG_EXTRA_GUARD | CREATURE_FLAG_EXTRA_IGNORE_PATHFINDING | CREATURE_FLAG_EXTRA_NO_PLAYER_DAMAGE_REQ | CREATURE_FLAG_EXTRA_IMMUNITY_KNOCKBACK)
-#define CREATURE_REGEN_INTERVAL 2 * IN_MILLISECONDS
+static const uint32 CREATURE_REGEN_INTERVAL = 2 * IN_MILLISECONDS;
+static const uint32 CREATURE_NOPATH_EVADE_TIME = 5 * IN_MILLISECONDS;
-#define MAX_KILL_CREDIT 2
-#define MAX_CREATURE_MODELS 4
-#define MAX_CREATURE_QUEST_ITEMS 6
-#define CREATURE_MAX_SPELLS 8
+static const uint8 MAX_KILL_CREDIT = 2;
+static const uint32 MAX_CREATURE_MODELS = 4;
+static const uint32 MAX_CREATURE_QUEST_ITEMS = 6;
+static const uint32 MAX_CREATURE_SPELLS = 8;
// from `creature_template` table
struct TC_GAME_API CreatureTemplate
@@ -117,7 +118,7 @@ struct TC_GAME_API CreatureTemplate
uint32 pickpocketLootId;
uint32 SkinLootId;
int32 resistance[MAX_SPELL_SCHOOL];
- uint32 spells[CREATURE_MAX_SPELLS];
+ uint32 spells[MAX_CREATURE_SPELLS];
uint32 PetSpellDataId;
uint32 VehicleId;
uint32 mingold;
@@ -475,6 +476,7 @@ class TC_GAME_API Creature : public Unit, public GridObject<Creature>, public Ma
uint8 getLevelForTarget(WorldObject const* target) const override; // overwrite Unit::getLevelForTarget for boss level support
bool IsInEvadeMode() const { return HasUnitState(UNIT_STATE_EVADE); }
+ bool IsEvadingAttacks() const { return IsInEvadeMode() || CanNotReachTarget(); }
bool AIM_Destroy();
bool AIM_Initialize(CreatureAI* ai = NULL);
@@ -567,7 +569,7 @@ class TC_GAME_API Creature : public Unit, public GridObject<Creature>, public Ma
SpellInfo const* reachWithSpellAttack(Unit* victim);
SpellInfo const* reachWithSpellCure(Unit* victim);
- uint32 m_spells[CREATURE_MAX_SPELLS];
+ uint32 m_spells[MAX_CREATURE_SPELLS];
bool CanStartAttack(Unit const* u, bool force) const;
float GetAttackDistance(Unit const* player) const;
@@ -632,6 +634,15 @@ class TC_GAME_API Creature : public Unit, public GridObject<Creature>, public Ma
virtual uint8 GetPetAutoSpellSize() const { return MAX_SPELL_CHARM; }
virtual uint32 GetPetAutoSpellOnPos(uint8 pos) const;
+ void SetCannotReachTarget(bool cannotReach)
+ {
+ if (cannotReach == m_cannotReachTarget)
+ return;
+ m_cannotReachTarget = cannotReach;
+ m_cannotReachTimer = 0;
+ }
+ bool CanNotReachTarget() const { return m_cannotReachTarget; }
+
void SetPosition(float x, float y, float z, float o);
void SetPosition(const Position &pos) { SetPosition(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), pos.GetOrientation()); }
@@ -719,6 +730,8 @@ class TC_GAME_API Creature : public Unit, public GridObject<Creature>, public Ma
bool m_AlreadyCallAssistance;
bool m_AlreadySearchedAssistance;
bool m_regenHealth;
+ bool m_cannotReachTarget;
+ uint32 m_cannotReachTimer;
bool m_AI_locked;
SpellSchoolMask m_meleeDamageSchoolMask;
diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp
index 7f922f89572..d7e478bb4e5 100644
--- a/src/server/game/Entities/GameObject/GameObject.cpp
+++ b/src/server/game/Entities/GameObject/GameObject.cpp
@@ -34,7 +34,7 @@
#include "Transport.h"
GameObject::GameObject() : WorldObject(false), MapObject(),
- m_model(NULL), m_goValue(), m_AI(NULL)
+ m_model(nullptr), m_goValue(), m_AI(nullptr)
{
m_objectType |= TYPEMASK_GAMEOBJECT;
m_objectTypeId = TYPEID_GAMEOBJECT;
@@ -49,8 +49,8 @@ GameObject::GameObject() : WorldObject(false), MapObject(),
m_usetimes = 0;
m_spellId = 0;
m_cooldownTime = 0;
- m_goInfo = NULL;
- m_goData = NULL;
+ m_goInfo = nullptr;
+ m_goData = nullptr;
m_spawnId = 0;
m_rotation = 0;
@@ -496,7 +496,7 @@ void GameObject::Update(uint32 diff)
radius = goInfo->trap.diameter / 2.f;
// Pointer to appropriate target if found any
- Unit* target = NULL;
+ Unit* target = nullptr;
/// @todo this hack with search required until GO casting not implemented
if (Unit* owner = GetOwner())
@@ -511,7 +511,7 @@ void GameObject::Update(uint32 diff)
else
{
// Environmental trap: Any player
- Player* player = NULL;
+ Player* player = nullptr;
Trinity::AnyPlayerInObjectRangeCheck checker(this, radius);
Trinity::PlayerSearcher<Trinity::AnyPlayerInObjectRangeCheck> searcher(this, player, checker);
VisitNearbyWorldObject(radius, searcher);
@@ -571,8 +571,8 @@ void GameObject::Update(uint32 diff)
GameObjectTemplate const* goInfo = GetGOInfo();
if (goInfo->trap.type == 2 && goInfo->trap.spellId)
{
- /// @todo NULL target won't work for target type 1
- CastSpell(NULL, goInfo->trap.spellId);
+ /// @todo nullptr target won't work for target type 1
+ CastSpell(nullptr, goInfo->trap.spellId);
SetLootState(GO_JUST_DEACTIVATED);
}
else if (Unit* target = ObjectAccessor::GetUnit(*this, m_lootStateUnitGUID))
@@ -1093,7 +1093,7 @@ void GameObject::TriggeringLinkedGameObject(uint32 trapEntry, Unit* target)
float range = float(target->GetSpellMaxRangeForTarget(GetOwner(), trapSpell));
// search nearest linked GO
- GameObject* trapGO = NULL;
+ GameObject* trapGO = nullptr;
{
// using original GO distance
CellCoord p(Trinity::ComputeCellCoord(GetPositionX(), GetPositionY()));
@@ -1113,7 +1113,7 @@ void GameObject::TriggeringLinkedGameObject(uint32 trapEntry, Unit* target)
GameObject* GameObject::LookupFishingHoleAround(float range)
{
- GameObject* ok = NULL;
+ GameObject* ok = nullptr;
CellCoord p(Trinity::ComputeCellCoord(GetPositionX(), GetPositionY()));
Cell cell(p);
@@ -1136,7 +1136,7 @@ void GameObject::ResetDoorOrButton()
m_cooldownTime = 0;
}
-void GameObject::UseDoorOrButton(uint32 time_to_restore, bool alternative /* = false */, Unit* user /*=NULL*/)
+void GameObject::UseDoorOrButton(uint32 time_to_restore, bool alternative /* = false */, Unit* user /*=nullptr*/)
{
if (m_lootState != GO_READY)
return;
@@ -1160,7 +1160,7 @@ void GameObject::SetGoArtKit(uint8 kit)
void GameObject::SetGoArtKit(uint8 artkit, GameObject* go, ObjectGuid::LowType lowguid)
{
- const GameObjectData* data = NULL;
+ const GameObjectData* data = nullptr;
if (go)
{
go->SetGoArtKit(artkit);
@@ -1386,7 +1386,7 @@ void GameObject::Use(Unit* user)
// cast this spell later if provided
spellId = info->goober.spellId;
- spellCaster = NULL;
+ spellCaster = nullptr;
break;
}
@@ -1505,7 +1505,7 @@ void GameObject::Use(Unit* user)
GameObjectTemplate const* info = GetGOInfo();
- Player* m_ritualOwner = NULL;
+ Player* m_ritualOwner = nullptr;
if (m_ritualOwnerGUID)
m_ritualOwner = ObjectAccessor::FindPlayer(m_ritualOwnerGUID);
@@ -1869,7 +1869,7 @@ bool GameObject::IsInRange(float x, float y, float z, float radius) const
&& dz < info->maxZ + radius && dz > info->minZ - radius;
}
-void GameObject::EventInform(uint32 eventId, WorldObject* invoker /*= NULL*/)
+void GameObject::EventInform(uint32 eventId, WorldObject* invoker /*= nullptr*/)
{
if (!eventId)
return;
@@ -1929,7 +1929,7 @@ void GameObject::UpdateRotationFields(float rotation2 /*=0.0f*/, float rotation3
SetFloatValue(GAMEOBJECT_PARENTROTATION+3, rotation3);
}
-void GameObject::ModifyHealth(int32 change, Unit* attackerOrHealer /*= NULL*/, uint32 spellId /*= 0*/)
+void GameObject::ModifyHealth(int32 change, Unit* attackerOrHealer /*= nullptr*/, uint32 spellId /*= 0*/)
{
if (!m_goValue.Building.MaxHealth || !change)
return;
@@ -1948,7 +1948,7 @@ void GameObject::ModifyHealth(int32 change, Unit* attackerOrHealer /*= NULL*/, u
// Set the health bar, value = 255 * healthPct;
SetGoAnimProgress(m_goValue.Building.Health * 255 / m_goValue.Building.MaxHealth);
- Player* player = attackerOrHealer ? attackerOrHealer->GetCharmerOrOwnerPlayerOrPlayerItself() : NULL;
+ Player* player = attackerOrHealer ? attackerOrHealer->GetCharmerOrOwnerPlayerOrPlayerItself() : nullptr;
// dealing damage, send packet
if (player)
@@ -1979,7 +1979,7 @@ void GameObject::ModifyHealth(int32 change, Unit* attackerOrHealer /*= NULL*/, u
SetDestructibleState(newState, player, false);
}
-void GameObject::SetDestructibleState(GameObjectDestructibleState state, Player* eventInvoker /*= NULL*/, bool setHealth /*= false*/)
+void GameObject::SetDestructibleState(GameObjectDestructibleState state, Player* eventInvoker /*= nullptr*/, bool setHealth /*= false*/)
{
// the user calling this must know he is already operating on destructible gameobject
ASSERT(GetGoType() == GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING);
@@ -2161,14 +2161,14 @@ void GameObject::UpdateModel()
Player* GameObject::GetLootRecipient() const
{
if (!m_lootRecipient)
- return NULL;
+ return nullptr;
return ObjectAccessor::FindConnectedPlayer(m_lootRecipient);
}
Group* GameObject::GetLootRecipientGroup() const
{
if (!m_lootRecipientGroup)
- return NULL;
+ return nullptr;
return sGroupMgr->GetGroupByGUID(m_lootRecipientGroup);
}
@@ -2176,7 +2176,7 @@ void GameObject::SetLootRecipient(Unit* unit)
{
// set the player whose group should receive the right
// to loot the creature after it dies
- // should be set to NULL after the loot disappears
+ // should be set to nullptr after the loot disappears
if (!unit)
{
@@ -2295,7 +2295,7 @@ void GameObject::BuildValuesUpdate(uint8 updateType, ByteBuffer* data, Player* t
data->append(fieldBuffer);
}
-void GameObject::GetRespawnPosition(float &x, float &y, float &z, float* ori /* = NULL*/) const
+void GameObject::GetRespawnPosition(float &x, float &y, float &z, float* ori /* = nullptr*/) const
{
if (m_spawnId)
{
diff --git a/src/server/game/Entities/Item/ItemEnchantmentMgr.cpp b/src/server/game/Entities/Item/ItemEnchantmentMgr.cpp
index b44a3e7ad7b..a7b410bc04b 100644
--- a/src/server/game/Entities/Item/ItemEnchantmentMgr.cpp
+++ b/src/server/game/Entities/Item/ItemEnchantmentMgr.cpp
@@ -44,7 +44,7 @@ typedef std::unordered_map<uint32, EnchStoreList> EnchantmentStore;
static EnchantmentStore RandomItemEnch;
-TC_GAME_API void LoadRandomEnchantmentsTable()
+void LoadRandomEnchantmentsTable()
{
uint32 oldMSTime = getMSTime();
@@ -77,7 +77,7 @@ TC_GAME_API void LoadRandomEnchantmentsTable()
TC_LOG_ERROR("server.loading", ">> Loaded 0 Item Enchantment definitions. DB table `item_enchantment_template` is empty.");
}
-TC_GAME_API uint32 GetItemEnchantMod(int32 entry)
+uint32 GetItemEnchantMod(int32 entry)
{
if (!entry)
return 0;
@@ -118,7 +118,7 @@ TC_GAME_API uint32 GetItemEnchantMod(int32 entry)
return 0;
}
-TC_GAME_API uint32 GenerateEnchSuffixFactor(uint32 item_id)
+uint32 GenerateEnchSuffixFactor(uint32 item_id)
{
ItemTemplate const* itemProto = sObjectMgr->GetItemTemplate(item_id);
diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp
index 45952ba51ac..a2f519a681c 100644
--- a/src/server/game/Entities/Object/Object.cpp
+++ b/src/server/game/Entities/Object/Object.cpp
@@ -1471,7 +1471,7 @@ float WorldObject::GetGridActivationRange() const
{
if (ToPlayer())
{
- if (ToPlayer()->IsOnCinematic())
+ if (ToPlayer()->GetCinematicMgr()->IsOnCinematic())
return DEFAULT_VISIBILITY_INSTANCE;
return GetMap()->GetVisibilityRange();
}
@@ -1504,7 +1504,7 @@ float WorldObject::GetSightRange(const WorldObject* target) const
{
if (target && target->isActiveObject() && !target->ToPlayer())
return MAX_VISIBILITY_DISTANCE;
- else if (ToPlayer()->IsOnCinematic())
+ else if (ToPlayer()->GetCinematicMgr()->IsOnCinematic())
return DEFAULT_VISIBILITY_INSTANCE;
else
return GetMap()->GetVisibilityRange();
diff --git a/src/server/game/Entities/Object/Object.h b/src/server/game/Entities/Object/Object.h
index d4c8fc35451..5c8a84453c3 100644
--- a/src/server/game/Entities/Object/Object.h
+++ b/src/server/game/Entities/Object/Object.h
@@ -550,8 +550,8 @@ class TC_GAME_API WorldObject : public Object, public WorldLocation
GameObject* FindNearestGameObject(uint32 entry, float range) const;
GameObject* FindNearestGameObjectOfType(GameobjectTypes type, float range) const;
- void GetGameObjectListWithEntryInGrid(std::list<GameObject*>& lList, uint32 uiEntry, float fMaxSearchRange) const;
- void GetCreatureListWithEntryInGrid(std::list<Creature*>& lList, uint32 uiEntry, float fMaxSearchRange) const;
+ void GetGameObjectListWithEntryInGrid(std::list<GameObject*>& lList, uint32 uiEntry = 0, float fMaxSearchRange = 250.0f) const;
+ void GetCreatureListWithEntryInGrid(std::list<Creature*>& lList, uint32 uiEntry = 0, float fMaxSearchRange = 250.0f) const;
void GetPlayerListInGrid(std::list<Player*>& lList, float fMaxSearchRange) const;
void DestroyForNearbyPlayers();
@@ -584,14 +584,6 @@ class TC_GAME_API WorldObject : public Object, public WorldLocation
template<class NOTIFIER> void VisitNearbyGridObject(float const& radius, NOTIFIER& notifier) const { if (IsInWorld()) GetMap()->VisitGrid(GetPositionX(), GetPositionY(), radius, notifier); }
template<class NOTIFIER> void VisitNearbyWorldObject(float const& radius, NOTIFIER& notifier) const { if (IsInWorld()) GetMap()->VisitWorld(GetPositionX(), GetPositionY(), radius, notifier); }
-#ifdef MAP_BASED_RAND_GEN
- int32 irand(int32 min, int32 max) const { return int32 (GetMap()->mtRand.randInt(max - min)) + min; }
- uint32 urand(uint32 min, uint32 max) const { return GetMap()->mtRand.randInt(max - min) + min;}
- int32 rand32() const { return GetMap()->mtRand.randInt();}
- double rand_norm() const { return GetMap()->mtRand.randExc();}
- double rand_chance() const { return GetMap()->mtRand.randExc(100.0);}
-#endif
-
uint32 LastUsedScriptID;
// Transports
diff --git a/src/server/game/Entities/Player/CinematicMgr.cpp b/src/server/game/Entities/Player/CinematicMgr.cpp
new file mode 100644
index 00000000000..07bf733c9ff
--- /dev/null
+++ b/src/server/game/Entities/Player/CinematicMgr.cpp
@@ -0,0 +1,171 @@
+/*
+* Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/>
+* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
+*
+* This program is free software; you can redistribute it and/or modify it
+* under the terms of the GNU General Public License as published by the
+* Free Software Foundation; either version 2 of the License, or (at your
+* option) any later version.
+*
+* This program is distributed in the hope that it will be useful, but WITHOUT
+* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+* more details.
+*
+* You should have received a copy of the GNU General Public License along
+* with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "CinematicMgr.h"
+#include "Creature.h"
+#include "Player.h"
+#include "TemporarySummon.h"
+
+CinematicMgr::CinematicMgr(Player* playerref)
+{
+ player = playerref;
+ m_cinematicDiff = 0;
+ m_lastCinematicCheck = 0;
+ m_activeCinematicCameraId = 0;
+ m_cinematicCamera = nullptr;
+ m_remoteSightPosition = Position(0.0f, 0.0f, 0.0f);
+ m_CinematicObject = nullptr;
+}
+
+CinematicMgr::~CinematicMgr()
+{
+ if (m_cinematicCamera && m_activeCinematicCameraId)
+ EndCinematic();
+}
+
+void CinematicMgr::BeginCinematic()
+{
+ // Sanity check for active camera set
+ if (m_activeCinematicCameraId == 0)
+ return;
+
+ auto itr = sFlyByCameraStore.find(m_activeCinematicCameraId);
+ if (itr != sFlyByCameraStore.end())
+ {
+ // Initialize diff, and set camera
+ m_cinematicDiff = 0;
+ m_cinematicCamera = &itr->second;
+
+ auto camitr = m_cinematicCamera->begin();
+ if (camitr != m_cinematicCamera->end())
+ {
+ Position pos(camitr->locations.x, camitr->locations.y, camitr->locations.z, camitr->locations.w);
+ if (!pos.IsPositionValid())
+ return;
+
+ player->GetMap()->LoadGrid(camitr->locations.x, camitr->locations.y);
+ m_CinematicObject = player->SummonCreature(VISUAL_WAYPOINT, pos.m_positionX, pos.m_positionY, pos.m_positionZ, 0.0f, TEMPSUMMON_TIMED_DESPAWN, 5 * MINUTE * IN_MILLISECONDS);
+ if (m_CinematicObject)
+ {
+ m_CinematicObject->setActive(true);
+ player->SetViewpoint(m_CinematicObject, true);
+ }
+
+ // Get cinematic length
+ FlyByCameraCollection::const_reverse_iterator camrevitr = m_cinematicCamera->rbegin();
+ if (camrevitr != m_cinematicCamera->rend())
+ m_cinematicLength = camrevitr->timeStamp;
+ }
+ }
+}
+
+void CinematicMgr::EndCinematic()
+{
+ if (m_activeCinematicCameraId == 0)
+ return;
+
+ m_cinematicDiff = 0;
+ m_cinematicCamera = nullptr;
+ m_activeCinematicCameraId = 0;
+ if (m_CinematicObject)
+ {
+ if (WorldObject* vpObject = player->GetViewpoint())
+ if (vpObject == m_CinematicObject)
+ player->SetViewpoint(m_CinematicObject, false);
+
+ m_CinematicObject->AddObjectToRemoveList();
+ }
+}
+
+void CinematicMgr::UpdateCinematicLocation(uint32 /*diff*/)
+{
+ if (m_activeCinematicCameraId == 0 || !m_cinematicCamera || m_cinematicCamera->size() == 0)
+ return;
+
+ Position lastPosition;
+ uint32 lastTimestamp = 0;
+ Position nextPosition;
+ uint32 nextTimestamp = 0;
+
+ // Obtain direction of travel
+ for (FlyByCamera cam : *m_cinematicCamera)
+ {
+ if (cam.timeStamp > m_cinematicDiff)
+ {
+ nextPosition = Position(cam.locations.x, cam.locations.y, cam.locations.z, cam.locations.w);
+ nextTimestamp = cam.timeStamp;
+ break;
+ }
+ lastPosition = Position(cam.locations.x, cam.locations.y, cam.locations.z, cam.locations.w);
+ lastTimestamp = cam.timeStamp;
+ }
+ float angle = lastPosition.GetAngle(&nextPosition);
+ angle -= lastPosition.GetOrientation();
+ if (angle < 0)
+ angle += 2 * float(M_PI);
+
+ // Look for position around 2 second ahead of us.
+ int32 workDiff = m_cinematicDiff;
+
+ // Modify result based on camera direction (Humans for example, have the camera point behind)
+ workDiff += static_cast<int32>(float(CINEMATIC_LOOKAHEAD) * cos(angle));
+
+ // Get an iterator to the last entry in the cameras, to make sure we don't go beyond the end
+ FlyByCameraCollection::const_reverse_iterator endItr = m_cinematicCamera->rbegin();
+ if (endItr != m_cinematicCamera->rend() && workDiff > static_cast<int32>(endItr->timeStamp))
+ workDiff = endItr->timeStamp;
+
+ // Never try to go back in time before the start of cinematic!
+ if (workDiff < 0)
+ workDiff = m_cinematicDiff;
+
+ // Obtain the previous and next waypoint based on timestamp
+ for (FlyByCamera cam : *m_cinematicCamera)
+ {
+ if (static_cast<int32>(cam.timeStamp) >= workDiff)
+ {
+ nextPosition = Position(cam.locations.x, cam.locations.y, cam.locations.z, cam.locations.w);
+ nextTimestamp = cam.timeStamp;
+ break;
+ }
+ lastPosition = Position(cam.locations.x, cam.locations.y, cam.locations.z, cam.locations.w);
+ lastTimestamp = cam.timeStamp;
+ }
+
+ // Never try to go beyond the end of the cinematic
+ if (workDiff > static_cast<int32>(nextTimestamp))
+ workDiff = static_cast<int32>(nextTimestamp);
+
+ // Interpolate the position for this moment in time (or the adjusted moment in time)
+ uint32 timeDiff = nextTimestamp - lastTimestamp;
+ uint32 interDiff = workDiff - lastTimestamp;
+ float xDiff = nextPosition.m_positionX - lastPosition.m_positionX;
+ float yDiff = nextPosition.m_positionY - lastPosition.m_positionY;
+ float zDiff = nextPosition.m_positionZ - lastPosition.m_positionZ;
+ Position interPosition(lastPosition.m_positionX + (xDiff * (float(interDiff) / float(timeDiff))), lastPosition.m_positionY +
+ (yDiff * (float(interDiff) / float(timeDiff))), lastPosition.m_positionZ + (zDiff * (float(interDiff) / float(timeDiff))));
+
+ // Advance (at speed) to this position. The remote sight object is used
+ // to send update information to player in cinematic
+ if (m_CinematicObject && interPosition.IsPositionValid())
+ m_CinematicObject->MonsterMoveWithSpeed(interPosition.m_positionX, interPosition.m_positionY, interPosition.m_positionZ, 500.0f, false, true);
+
+ // If we never received an end packet 10 seconds after the final timestamp then force an end
+ if (m_cinematicDiff > m_cinematicLength + 10 * IN_MILLISECONDS)
+ EndCinematic();
+}
diff --git a/src/server/game/Entities/Player/CinematicMgr.h b/src/server/game/Entities/Player/CinematicMgr.h
new file mode 100644
index 00000000000..ab067afa042
--- /dev/null
+++ b/src/server/game/Entities/Player/CinematicMgr.h
@@ -0,0 +1,60 @@
+/*
+* Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/>
+* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
+*
+* This program is free software; you can redistribute it and/or modify it
+* under the terms of the GNU General Public License as published by the
+* Free Software Foundation; either version 2 of the License, or (at your
+* option) any later version.
+*
+* This program is distributed in the hope that it will be useful, but WITHOUT
+* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+* more details.
+*
+* You should have received a copy of the GNU General Public License along
+* with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef CinematicMgr_h__
+#define CinematicMgr_h__
+
+#include "Define.h"
+#include "Object.h"
+#include "M2Stores.h"
+
+#define CINEMATIC_LOOKAHEAD (2 * IN_MILLISECONDS)
+#define CINEMATIC_UPDATEDIFF 500
+
+class Player;
+
+class TC_GAME_API CinematicMgr
+{
+ friend class Player;
+public:
+ explicit CinematicMgr(Player* playerref);
+ ~CinematicMgr();
+
+ // Cinematic camera data and remote sight functions
+ uint32 GetActiveCinematicCamera() const { return m_activeCinematicCameraId; }
+ void SetActiveCinematicCamera(uint32 cinematicCameraId = 0) { m_activeCinematicCameraId = cinematicCameraId; }
+ bool IsOnCinematic() const { return (m_cinematicCamera != nullptr); }
+ void BeginCinematic();
+ void EndCinematic();
+ void UpdateCinematicLocation(uint32 diff);
+
+private:
+ // Remote location information
+ Player* player;
+
+protected:
+ uint32 m_cinematicDiff;
+ uint32 m_lastCinematicCheck;
+ uint32 m_activeCinematicCameraId;
+ uint32 m_cinematicLength;
+ FlyByCameraCollection* m_cinematicCamera;
+ Position m_remoteSightPosition;
+ TempSummon* m_CinematicObject;
+};
+
+#endif \ No newline at end of file
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index 503b6277963..9ed101bf52e 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -96,9 +96,6 @@
#define SKILL_PERM_BONUS(x) int16(PAIR32_HIPART(x))
#define MAKE_SKILL_BONUS(t, p) MAKE_PAIR32(t, p)
-#define CINEMATIC_LOOKAHEAD (2 * IN_MILLISECONDS)
-#define CINEMATIC_UPDATEDIFF 500
-
enum CharacterFlags
{
CHARACTER_FLAG_NONE = 0x00000000,
@@ -477,21 +474,11 @@ Player::Player(WorldSession* session): Unit(true)
// Player summoning
m_summon_expire = 0;
- m_summon_mapid = 0;
- m_summon_x = 0.0f;
- m_summon_y = 0.0f;
- m_summon_z = 0.0f;
m_mover = this;
m_movedPlayer = this;
m_seer = this;
- m_recallMap = 0;
- m_recallX = 0;
- m_recallY = 0;
- m_recallZ = 0;
- m_recallO = 0;
-
m_homebindMapId = 0;
m_homebindAreaId = 0;
m_homebindX = 0;
@@ -539,12 +526,7 @@ Player::Player(WorldSession* session): Unit(true)
healthBeforeDuel = 0;
manaBeforeDuel = 0;
- m_cinematicDiff = 0;
- m_lastCinematicCheck = 0;
- m_activeCinematicCameraId = 0;
- m_cinematicCamera = nullptr;
- m_remoteSightPosition = Position(0.0f, 0.0f, 0.0f);
- m_CinematicObject = nullptr;
+ _cinematicMgr = new CinematicMgr(this);
m_achievementMgr = new AchievementMgr(this);
m_reputationMgr = new ReputationMgr(this);
@@ -1236,11 +1218,11 @@ void Player::Update(uint32 p_time)
}
// Update cinematic location, if 500ms have passed and we're doing a cinematic now.
- m_cinematicDiff += p_time;
- if (m_cinematicCamera && m_activeCinematicCameraId && GetMSTimeDiffToNow(m_lastCinematicCheck) > CINEMATIC_UPDATEDIFF)
+ _cinematicMgr->m_cinematicDiff += p_time;
+ if (_cinematicMgr->m_cinematicCamera && _cinematicMgr->m_activeCinematicCameraId && GetMSTimeDiffToNow(_cinematicMgr->m_lastCinematicCheck) > CINEMATIC_UPDATEDIFF)
{
- m_lastCinematicCheck = getMSTime();
- UpdateCinematicLocation(p_time);
+ _cinematicMgr->m_lastCinematicCheck = getMSTime();
+ _cinematicMgr->UpdateCinematicLocation(p_time);
}
//used to implement delayed far teleports
@@ -6374,15 +6356,6 @@ bool Player::UpdatePosition(float x, float y, float z, float orientation, bool t
return true;
}
-void Player::SaveRecallPosition()
-{
- m_recallMap = GetMapId();
- m_recallX = GetPositionX();
- m_recallY = GetPositionY();
- m_recallZ = GetPositionZ();
- m_recallO = GetOrientation();
-}
-
void Player::SendMessageToSetInRange(WorldPacket* data, float dist, bool self)
{
if (self)
@@ -6417,13 +6390,13 @@ void Player::SendDirectMessage(WorldPacket const* data) const
m_session->SendPacket(data);
}
-void Player::SendCinematicStart(uint32 CinematicSequenceId)
+void Player::SendCinematicStart(uint32 CinematicSequenceId) const
{
WorldPacket data(SMSG_TRIGGER_CINEMATIC, 4);
data << uint32(CinematicSequenceId);
SendDirectMessage(&data);
- if (const CinematicSequencesEntry* sequence = sCinematicSequencesStore.LookupEntry(CinematicSequenceId))
- SetActiveCinematicCamera(sequence->cinematicCamera);
+ if (CinematicSequencesEntry const* sequence = sCinematicSequencesStore.LookupEntry(CinematicSequenceId))
+ _cinematicMgr->SetActiveCinematicCamera(sequence->cinematicCamera);
}
void Player::SendMovieStart(uint32 MovieId) const
@@ -20535,7 +20508,7 @@ void Player::VehicleSpellInitialize()
data << uint8(0); // Command State
data << uint16(0x800); // DisableActions (set for all vehicles)
- for (uint32 i = 0; i < CREATURE_MAX_SPELLS; ++i)
+ for (uint32 i = 0; i < MAX_CREATURE_SPELLS; ++i)
{
uint32 spellId = vehicle->m_spells[i];
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId);
@@ -20559,7 +20532,7 @@ void Player::VehicleSpellInitialize()
data << uint32(MAKE_UNIT_ACTION_BUTTON(spellId, i+8));
}
- for (uint32 i = CREATURE_MAX_SPELLS; i < MAX_SPELL_CONTROL_BAR; ++i)
+ for (uint32 i = MAX_CREATURE_SPELLS; i < MAX_SPELL_CONTROL_BAR; ++i)
data << uint32(0);
data << uint8(0); // Auras?
@@ -23209,13 +23182,32 @@ void Player::UpdateForQuestWorldObjects()
GetSession()->SendPacket(&packet);
}
-void Player::SetSummonPoint(uint32 mapid, float x, float y, float z)
+bool Player::HasSummonPending() const
+{
+ return m_summon_expire >= time(nullptr);
+}
+
+void Player::SendSummonRequestFrom(Unit* summoner)
{
+ if (!summoner)
+ return;
+
+ // Player already has active summon request
+ if (HasSummonPending())
+ return;
+
+ // Evil Twin (ignore player summon, but hide this for summoner)
+ if (HasAura(23445))
+ return;
+
m_summon_expire = time(nullptr) + MAX_PLAYER_SUMMON_DELAY;
- m_summon_mapid = mapid;
- m_summon_x = x;
- m_summon_y = y;
- m_summon_z = z;
+ m_summon_location.WorldRelocate(*summoner);
+
+ WorldPacket data(SMSG_SUMMON_REQUEST, 8 + 4 + 4);
+ data << uint64(summoner->GetGUID()); // summoner guid
+ data << uint32(summoner->GetZoneId()); // summoner zone
+ data << uint32(MAX_PLAYER_SUMMON_DELAY*IN_MILLISECONDS); // auto decline after msecs
+ GetSession()->SendPacket(&data);
}
void Player::SummonIfPossible(bool agree)
@@ -23246,7 +23238,7 @@ void Player::SummonIfPossible(bool agree)
UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_ACCEPTED_SUMMONINGS, 1);
- TeleportTo(m_summon_mapid, m_summon_x, m_summon_y, m_summon_z, GetOrientation());
+ TeleportTo(m_summon_location);
}
void Player::RemoveItemDurations(Item* item)
@@ -26243,125 +26235,6 @@ float Player::GetCollisionHeight(bool mounted) const
}
}
-void Player::BeginCinematic()
-{
- // Sanity check for active camera set
- if (m_activeCinematicCameraId == 0)
- return;
-
- auto itr = sFlyByCameraStore.find(m_activeCinematicCameraId);
- if (itr != sFlyByCameraStore.end())
- {
- // Initialize diff, and set camera
- m_cinematicDiff = 0;
- m_cinematicCamera = &itr->second;
-
- auto camitr = m_cinematicCamera->begin();
- if (camitr != m_cinematicCamera->end())
- {
- Position pos(camitr->locations.x, camitr->locations.y, camitr->locations.z, camitr->locations.w);
- if (!pos.IsPositionValid())
- return;
-
- m_mapRef->LoadGrid(camitr->locations.x, camitr->locations.y);
- m_CinematicObject = SummonCreature(VISUAL_WAYPOINT, pos.m_positionX, pos.m_positionY, pos.m_positionZ, 0.0f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 120000);
- if (m_CinematicObject)
- {
- m_CinematicObject->setActive(true);
- SetViewpoint(m_CinematicObject, true);
- }
- }
- }
-}
-
-void Player::EndCinematic()
-{
- m_cinematicDiff = 0;
- m_cinematicCamera = nullptr;
- m_activeCinematicCameraId = 0;
- if (m_CinematicObject)
- {
- if (m_seer && m_seer == m_CinematicObject)
- SetViewpoint(m_CinematicObject, false);
- m_CinematicObject->AddObjectToRemoveList();
- }
-}
-
-void Player::UpdateCinematicLocation(uint32 /*diff*/)
-{
- Position lastPosition;
- uint32 lastTimestamp = 0;
- Position nextPosition;
- uint32 nextTimestamp = 0;
-
- if (m_cinematicCamera->size() == 0)
- return;
-
- // Obtain direction of travel
- for (FlyByCamera cam : *m_cinematicCamera)
- {
- if (cam.timeStamp > m_cinematicDiff)
- {
- nextPosition = Position(cam.locations.x, cam.locations.y, cam.locations.z, cam.locations.w);
- nextTimestamp = cam.timeStamp;
- break;
- }
- lastPosition = Position(cam.locations.x, cam.locations.y, cam.locations.z, cam.locations.w);
- lastTimestamp = cam.timeStamp;
- }
- float angle = lastPosition.GetAngle(&nextPosition);
- angle -= lastPosition.GetOrientation();
- if (angle < 0)
- angle += 2 * float(M_PI);
-
- // Look for position around 2 second ahead of us.
- int32 workDiff = m_cinematicDiff;
-
- // Modify result based on camera direction (Humans for example, have the camera point behind)
- workDiff += static_cast<int32>(float(CINEMATIC_LOOKAHEAD) * cos(angle));
-
- // Get an iterator to the last entry in the cameras, to make sure we don't go beyond the end
- FlyByCameraCollection::const_reverse_iterator endItr = m_cinematicCamera->rbegin();
- if (endItr != m_cinematicCamera->rend() && workDiff > static_cast<int32>(endItr->timeStamp))
- workDiff = endItr->timeStamp;
-
- // Never try to go back in time before the start of cinematic!
- if (workDiff < 0)
- workDiff = m_cinematicDiff;
-
- // Obtain the previous and next waypoint based on timestamp
- for (FlyByCamera cam : *m_cinematicCamera)
- {
- if (static_cast<int32>(cam.timeStamp) >= workDiff)
- {
- nextPosition = Position(cam.locations.x, cam.locations.y, cam.locations.z, cam.locations.w);
- nextTimestamp = cam.timeStamp;
- break;
- }
- lastPosition = Position(cam.locations.x, cam.locations.y, cam.locations.z, cam.locations.w);
- lastTimestamp = cam.timeStamp;
- }
-
- // Never try to go beyond the end of the cinematic
- if (workDiff > static_cast<int32>(nextTimestamp))
- workDiff = static_cast<int32>(nextTimestamp);
-
- // Interpolate the position for this moment in time (or the adjusted moment in time)
- uint32 timeDiff = nextTimestamp - lastTimestamp;
- uint32 interDiff = workDiff - lastTimestamp;
- float xDiff = nextPosition.m_positionX - lastPosition.m_positionX;
- float yDiff = nextPosition.m_positionY - lastPosition.m_positionY;
- float zDiff = nextPosition.m_positionZ - lastPosition.m_positionZ;
- Position interPosition(lastPosition.m_positionX + (xDiff * (float(interDiff)/float(timeDiff))), lastPosition.m_positionY +
- (yDiff * (float(interDiff) / float(timeDiff))), lastPosition.m_positionZ + (zDiff * (float(interDiff) / float(timeDiff))));
-
- // Advance (at speed) to this position. The remote sight object is used
- // to send update information to player in cinematic
- if (m_CinematicObject && interPosition.IsPositionValid())
- m_CinematicObject->MonsterMoveWithSpeed(interPosition.m_positionX, interPosition.m_positionY, interPosition.m_positionZ, 200.0f, false, true);
-}
-
-
std::string Player::GetMapAreaAndZoneString() const
{
uint32 areaId = GetAreaId();
diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h
index 51443ce8939..372a49b4f9d 100644
--- a/src/server/game/Entities/Player/Player.h
+++ b/src/server/game/Entities/Player/Player.h
@@ -30,6 +30,7 @@
#include "SpellHistory.h"
#include "Unit.h"
#include "TradeData.h"
+#include "CinematicMgr.h"
#include <limits>
#include <string>
@@ -1026,6 +1027,7 @@ struct ResurrectionData
class TC_GAME_API Player : public Unit, public GridObject<Player>
{
friend class WorldSession;
+ friend class CinematicMgr;
friend void Item::AddToUpdateQueueOf(Player* player);
friend void Item::RemoveFromUpdateQueueOf(Player* player);
public:
@@ -1050,7 +1052,8 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
bool TeleportTo(WorldLocation const &loc, uint32 options = 0);
bool TeleportToBGEntryPoint();
- void SetSummonPoint(uint32 mapid, float x, float y, float z);
+ bool HasSummonPending() const;
+ void SendSummonRequestFrom(Unit* summoner);
void SummonIfPossible(bool agree);
bool Create(ObjectGuid::LowType guidlow, CharacterCreateInfo* createInfo);
@@ -1273,6 +1276,8 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
TradeData* GetTradeData() const { return m_trade; }
void TradeCancel(bool sendback);
+ CinematicMgr* GetCinematicMgr() const { return _cinematicMgr; }
+
void UpdateEnchantTime(uint32 time);
void UpdateSoulboundTradeItems();
void AddTradeableItem(Item* item);
@@ -2077,13 +2082,8 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
uint32 GetSaveTimer() const { return m_nextSave; }
void SetSaveTimer(uint32 timer) { m_nextSave = timer; }
- // Recall position
- uint32 m_recallMap;
- float m_recallX;
- float m_recallY;
- float m_recallZ;
- float m_recallO;
- void SaveRecallPosition();
+ void SaveRecallPosition() { m_recall_location.WorldRelocate(*this); }
+ void Recall() { TeleportTo(m_recall_location); }
void SetHomebind(WorldLocation const& loc, uint32 areaId);
@@ -2133,7 +2133,7 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
void ResummonPetTemporaryUnSummonedIfAny();
bool IsPetNeedBeTemporaryUnsummoned() const;
- void SendCinematicStart(uint32 CinematicSequenceId);
+ void SendCinematicStart(uint32 CinematicSequenceId) const;
void SendMovieStart(uint32 MovieId) const;
uint32 DoRandomRoll(uint32 minimum, uint32 maximum);
@@ -2271,17 +2271,6 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
std::string GetMapAreaAndZoneString() const;
std::string GetCoordsMapAreaAndZoneString() const;
- // Cinematic camera data and remote sight functions
- uint32 GetActiveCinematicCamera() const { return m_activeCinematicCameraId; }
- void SetActiveCinematicCamera(uint32 cinematicCameraId = 0) { m_activeCinematicCameraId = cinematicCameraId; }
- bool IsOnCinematic() const { return (m_cinematicCamera != nullptr); }
- void BeginCinematic();
- void EndCinematic();
- void UpdateCinematicLocation(uint32 diff);
-
- std::string GetMapAreaAndZoneString();
- std::string GetCoordsMapAreaAndZoneString();
-
protected:
// Gamemaster whisper whitelist
GuidList WhisperList;
@@ -2516,10 +2505,10 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
// Player summoning
time_t m_summon_expire;
- uint32 m_summon_mapid;
- float m_summon_x;
- float m_summon_y;
- float m_summon_z;
+ WorldLocation m_summon_location;
+
+ // Recall position
+ WorldLocation m_recall_location;
DeclinedName *m_declinedname;
Runes *m_runes;
@@ -2541,6 +2530,8 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
Item* _StoreItem(uint16 pos, Item* pItem, uint32 count, bool clone, bool update);
Item* _LoadItem(SQLTransaction& trans, uint32 zoneId, uint32 timeDiff, Field* fields);
+ CinematicMgr* _cinematicMgr;
+
GuidSet m_refundableItems;
void SendRefundInfo(Item* item);
void RefundItem(Item* item);
@@ -2607,14 +2598,6 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
uint32 manaBeforeDuel;
WorldLocation _corpseLocation;
-
- // Remote location information
- uint32 m_cinematicDiff;
- uint32 m_lastCinematicCheck;
- uint32 m_activeCinematicCameraId;
- FlyByCameraCollection* m_cinematicCamera;
- Position m_remoteSightPosition;
- Creature* m_CinematicObject;
};
TC_GAME_API void AddItemsSetItem(Player* player, Item* item);
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index 9ec55343e7d..0e9aa4395a3 100644
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -578,7 +578,7 @@ bool Unit::HasBreakableByDamageCrowdControlAura(Unit* excludeCasterChannel) cons
void Unit::DealDamageMods(Unit* victim, uint32 &damage, uint32* absorb)
{
- if (!victim || !victim->IsAlive() || victim->HasUnitState(UNIT_STATE_IN_FLIGHT) || (victim->GetTypeId() == TYPEID_UNIT && victim->ToCreature()->IsInEvadeMode()))
+ if (!victim || !victim->IsAlive() || victim->HasUnitState(UNIT_STATE_IN_FLIGHT) || (victim->GetTypeId() == TYPEID_UNIT && victim->ToCreature()->IsEvadingAttacks()))
{
if (absorb)
*absorb += damage;
@@ -1120,7 +1120,7 @@ void Unit::DealSpellDamage(SpellNonMeleeDamage* damageInfo, bool durabilityLoss)
if (!victim)
return;
- if (!victim->IsAlive() || victim->HasUnitState(UNIT_STATE_IN_FLIGHT) || (victim->GetTypeId() == TYPEID_UNIT && victim->ToCreature()->IsInEvadeMode()))
+ if (!victim->IsAlive() || victim->HasUnitState(UNIT_STATE_IN_FLIGHT) || (victim->GetTypeId() == TYPEID_UNIT && victim->ToCreature()->IsEvadingAttacks()))
return;
SpellInfo const* spellProto = sSpellMgr->GetSpellInfo(damageInfo->SpellID);
@@ -1346,7 +1346,7 @@ void Unit::DealMeleeDamage(CalcDamageInfo* damageInfo, bool durabilityLoss)
{
Unit* victim = damageInfo->target;
- if (!victim->IsAlive() || victim->HasUnitState(UNIT_STATE_IN_FLIGHT) || (victim->GetTypeId() == TYPEID_UNIT && victim->ToCreature()->IsInEvadeMode()))
+ if (!victim->IsAlive() || victim->HasUnitState(UNIT_STATE_IN_FLIGHT) || (victim->GetTypeId() == TYPEID_UNIT && victim->ToCreature()->IsEvadingAttacks()))
return;
// Hmmmm dont like this emotes client must by self do all animations
@@ -2044,7 +2044,7 @@ MeleeHitOutcome Unit::RollMeleeOutcomeAgainst(const Unit* victim, WeaponAttackTy
MeleeHitOutcome Unit::RollMeleeOutcomeAgainst (const Unit* victim, WeaponAttackType attType, int32 crit_chance, int32 miss_chance, int32 dodge_chance, int32 parry_chance, int32 block_chance) const
{
- if (victim->GetTypeId() == TYPEID_UNIT && victim->ToCreature()->IsInEvadeMode())
+ if (victim->GetTypeId() == TYPEID_UNIT && victim->ToCreature()->IsEvadingAttacks())
return MELEE_HIT_EVADE;
int32 attackerMaxSkillValueForLevel = GetMaxSkillValueForLevel(victim);
@@ -2656,7 +2656,7 @@ SpellMissInfo Unit::SpellHitResult(Unit* victim, SpellInfo const* spellInfo, boo
return SPELL_MISS_NONE;
// Return evade for units in evade mode
- if (victim->GetTypeId() == TYPEID_UNIT && victim->ToCreature()->IsInEvadeMode())
+ if (victim->GetTypeId() == TYPEID_UNIT && victim->ToCreature()->IsEvadingAttacks())
return SPELL_MISS_EVADE;
// Try victim reflect spell
@@ -7868,6 +7868,10 @@ bool Unit::HandleProcTriggerSpell(Unit* victim, uint32 damage, AuraEffect* trigg
RemoveAurasDueToSpell(50240);
break;
}
+ // Battle Experience
+ // already handled in gunship battle script
+ case 71201:
+ return false;
}
break;
case SPELLFAMILY_MAGE:
@@ -9009,7 +9013,7 @@ bool Unit::Attack(Unit* victim, bool meleeAttack)
}
else
{
- if (victim->ToCreature()->IsInEvadeMode())
+ if (victim->ToCreature()->IsEvadingAttacks())
return false;
}
@@ -11944,6 +11948,7 @@ void Unit::ClearInCombat()
ToPlayer()->UpdatePotionCooldown();
RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PET_IN_COMBAT);
+ RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_LEAVE_COMBAT);
}
bool Unit::isTargetableForAttack(bool checkFakeDeath) const
@@ -12521,7 +12526,7 @@ void Unit::SetSpeedRate(UnitMoveType mtype, float rate)
WorldPacket self;
self.Initialize(moveTypeToOpcode[mtype][1], mtype != MOVE_RUN ? 8 + 4 + 4 : 8 + 4 + 1 + 4);
self << GetPackGUID();
- self << (uint32)0; // Movement counter. Unimplemented at the moment! NUM_PMOVE_EVTS = 0x39Z.
+ self << (uint32)0; // Movement counter. Unimplemented at the moment! NUM_PMOVE_EVTS = 0x39Z.
if (mtype == MOVE_RUN)
self << uint8(1); // unknown byte added in 2.1.0
self << float(GetSpeed(mtype));
@@ -13721,6 +13726,9 @@ void Unit::UpdateCharmAI()
delete i_AI;
i_AI = i_disabledAI;
i_disabledAI = nullptr;
+
+ if (GetTypeId() == TYPEID_UNIT)
+ ToCreature()->AI()->OnCharmed(false);
}
}
else
@@ -13868,7 +13876,7 @@ void CharmInfo::InitPossessCreateSpells()
break;
}
- for (uint8 i = 0; i < CREATURE_MAX_SPELLS; ++i)
+ for (uint8 i = 0; i < MAX_CREATURE_SPELLS; ++i)
{
uint32 spellId = _unit->ToCreature()->m_spells[i];
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId);
@@ -17666,7 +17674,7 @@ void Unit::SetFacingToObject(WorldObject const* object)
/// @todo figure out under what conditions creature will move towards object instead of facing it where it currently is.
Movement::MoveSplineInit init(this);
- init.MoveTo(GetPositionX(), GetPositionY(), GetPositionZMinusOffset());
+ init.MoveTo(GetPositionX(), GetPositionY(), GetPositionZMinusOffset(), false);
init.SetFacing(GetAngle(object)); // when on transport, GetAngle will still return global coordinates (and angle) that needs transforming
init.Launch();
}
diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h
index 47193cd0c45..b1571e4379f 100644
--- a/src/server/game/Entities/Unit/Unit.h
+++ b/src/server/game/Entities/Unit/Unit.h
@@ -76,6 +76,7 @@ enum SpellAuraInterruptFlags
AURA_INTERRUPT_FLAG_ENTER_PVP_COMBAT = 0x00800000, // 23 removed by entering pvp combat
AURA_INTERRUPT_FLAG_DIRECT_DAMAGE = 0x01000000, // 24 removed by any direct damage
AURA_INTERRUPT_FLAG_LANDING = 0x02000000, // 25 removed by hitting the ground
+ AURA_INTERRUPT_FLAG_LEAVE_COMBAT = 0x80000000, // 31 removed by leaving combat
AURA_INTERRUPT_FLAG_NOT_VICTIM = (AURA_INTERRUPT_FLAG_HITBYSPELL | AURA_INTERRUPT_FLAG_TAKE_DAMAGE | AURA_INTERRUPT_FLAG_DIRECT_DAMAGE)
};
diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp
index 3efeb1ca273..fc0abf5a8c7 100644
--- a/src/server/game/Globals/ObjectMgr.cpp
+++ b/src/server/game/Globals/ObjectMgr.cpp
@@ -487,7 +487,7 @@ void ObjectMgr::LoadCreatureTemplate(Field* fields)
for (uint8 i = SPELL_SCHOOL_HOLY; i < MAX_SPELL_SCHOOL; ++i)
creatureTemplate.resistance[i] = fields[42 + i - 1].GetInt16();
- for (uint8 i = 0; i < CREATURE_MAX_SPELLS; ++i)
+ for (uint8 i = 0; i < MAX_CREATURE_SPELLS; ++i)
creatureTemplate.spells[i] = fields[48 + i].GetUInt32();
creatureTemplate.PetSpellDataId = fields[56].GetUInt32();
@@ -833,7 +833,7 @@ void ObjectMgr::CheckCreatureTemplate(CreatureTemplate const* cInfo)
if (!displayScaleEntry)
TC_LOG_ERROR("sql.sql", "Creature (Entry: %u) does not have any existing display id in Modelid1/Modelid2/Modelid3/Modelid4.", cInfo->Entry);
- for (int k = 0; k < MAX_KILL_CREDIT; ++k)
+ for (uint8 k = 0; k < MAX_KILL_CREDIT; ++k)
{
if (cInfo->KillCredit[k])
{
@@ -920,7 +920,7 @@ void ObjectMgr::CheckCreatureTemplate(CreatureTemplate const* cInfo)
TC_LOG_ERROR("sql.sql", "Creature (Entry: %u) has non-existing PetSpellDataId (%u).", cInfo->Entry, cInfo->PetSpellDataId);
}
- for (uint8 j = 0; j < CREATURE_MAX_SPELLS; ++j)
+ for (uint8 j = 0; j < MAX_CREATURE_SPELLS; ++j)
{
if (cInfo->spells[j] && !sSpellMgr->GetSpellInfo(cInfo->spells[j]))
{
diff --git a/src/server/game/Grids/Notifiers/GridNotifiers.h b/src/server/game/Grids/Notifiers/GridNotifiers.h
index 84aa29f96b7..1d2b0bd33cf 100644
--- a/src/server/game/Grids/Notifiers/GridNotifiers.h
+++ b/src/server/game/Grids/Notifiers/GridNotifiers.h
@@ -1237,7 +1237,7 @@ namespace Trinity
AllGameObjectsWithEntryInRange(const WorldObject* object, uint32 entry, float maxRange) : m_pObject(object), m_uiEntry(entry), m_fRange(maxRange) { }
bool operator() (GameObject* go)
{
- if (go->GetEntry() == m_uiEntry && m_pObject->IsWithinDist(go, m_fRange, false))
+ if ((!m_uiEntry || go->GetEntry() == m_uiEntry) && m_pObject->IsWithinDist(go, m_fRange, false))
return true;
return false;
@@ -1254,7 +1254,7 @@ namespace Trinity
AllCreaturesOfEntryInRange(const WorldObject* object, uint32 entry, float maxRange) : m_pObject(object), m_uiEntry(entry), m_fRange(maxRange) { }
bool operator() (Unit* unit)
{
- if (unit->GetEntry() == m_uiEntry && m_pObject->IsWithinDist(unit, m_fRange, false))
+ if ((!m_uiEntry || unit->GetEntry() == m_uiEntry) && m_pObject->IsWithinDist(unit, m_fRange, false))
return true;
return false;
diff --git a/src/server/game/Handlers/MiscHandler.cpp b/src/server/game/Handlers/MiscHandler.cpp
index 467d3730ab2..52b36d80202 100644
--- a/src/server/game/Handlers/MiscHandler.cpp
+++ b/src/server/game/Handlers/MiscHandler.cpp
@@ -884,15 +884,15 @@ void WorldSession::HandleAreaTriggerOpcode(WorldPacket& recvData)
player->SendTransferAborted(entry->MapID, TRANSFER_ABORT_DIFFICULTY, player->GetDifficulty(entry->IsRaid()));
break;
case Map::CANNOT_ENTER_NOT_IN_RAID:
- if (MapEntry const* entry = sMapStore.LookupEntry(at->target_mapId))
- {
- char const* mapName = entry->name[player->GetSession()->GetSessionDbcLocale()];
- TC_LOG_DEBUG("maps", "MAP: Player '%s' must be in a raid group to enter instance '%s'", player->GetName().c_str(), mapName);
- // probably there must be special opcode, because client has this string constant in GlobalStrings.lua
- player->GetSession()->SendAreaTriggerMessage(player->GetSession()->GetTrinityString(LANG_INSTANCE_RAID_GROUP_ONLY), mapName);
- }
+ {
+ WorldPacket data(SMSG_RAID_GROUP_ONLY, 4 + 4);
+ data << uint32(0);
+ data << uint32(2); // You must be in a raid group to enter this instance.
+ player->GetSession()->SendPacket(&data);
+ TC_LOG_DEBUG("maps", "MAP: Player '%s' must be in a raid group to enter instance map %d", player->GetName().c_str(), at->target_mapId);
reviveAtTrigger = true;
break;
+ }
case Map::CANNOT_ENTER_CORPSE_IN_DIFFERENT_INSTANCE:
{
WorldPacket data(SMSG_CORPSE_NOT_IN_INSTANCE);
@@ -1057,13 +1057,13 @@ void WorldSession::HandleSetActionButtonOpcode(WorldPacket& recvData)
void WorldSession::HandleCompleteCinematic(WorldPacket& /*recvData*/)
{
// If player has sight bound to visual waypoint NPC we should remove it
- GetPlayer()->EndCinematic();
+ GetPlayer()->GetCinematicMgr()->EndCinematic();
}
void WorldSession::HandleNextCinematicCamera(WorldPacket& /*recvData*/)
{
// Sent by client when cinematic actually begun. So we begin the server side process
- GetPlayer()->BeginCinematic();
+ GetPlayer()->GetCinematicMgr()->BeginCinematic();
}
void WorldSession::HandleMoveTimeSkippedOpcode(WorldPacket& recvData)
diff --git a/src/server/game/Handlers/QueryHandler.cpp b/src/server/game/Handlers/QueryHandler.cpp
index ebc9ebde994..1eee9e0d9fe 100644
--- a/src/server/game/Handlers/QueryHandler.cpp
+++ b/src/server/game/Handlers/QueryHandler.cpp
@@ -133,10 +133,10 @@ void WorldSession::HandleCreatureQueryOpcode(WorldPacket& recvData)
CreatureQuestItemList const* items = sObjectMgr->GetCreatureQuestItemList(entry);
if (items)
- for (size_t i = 0; i < MAX_CREATURE_QUEST_ITEMS; ++i)
+ for (uint32 i = 0; i < MAX_CREATURE_QUEST_ITEMS; ++i)
data << (i < items->size() ? uint32((*items)[i]) : uint32(0));
else
- for (size_t i = 0; i < MAX_CREATURE_QUEST_ITEMS; ++i)
+ for (uint32 i = 0; i < MAX_CREATURE_QUEST_ITEMS; ++i)
data << uint32(0);
data << uint32(ci->movementId); // CreatureMovementInfo.dbc
diff --git a/src/server/game/Miscellaneous/Language.h b/src/server/game/Miscellaneous/Language.h
index ca63137ac93..d6af5d81432 100644
--- a/src/server/game/Miscellaneous/Language.h
+++ b/src/server/game/Miscellaneous/Language.h
@@ -1063,7 +1063,7 @@ enum TrinityStrings
LANG_COMMAND_NO_FROZEN_PLAYERS = 5004,
LANG_COMMAND_LIST_FREEZE = 5005,
LANG_COMMAND_PERMA_FROZEN_PLAYER = 5006,
- LANG_INSTANCE_RAID_GROUP_ONLY = 5007,
+ // = 5007, unused
LANG_INSTANCE_CLOSED = 5008,
LANG_COMMAND_PLAYED_TO_ALL = 5009,
LANG_NPCINFO_LINKGUID = 5010,
@@ -1212,6 +1212,8 @@ enum TrinityStrings
LANG_CREATURE_NO_INTERIOR_POINT_FOUND = 11011,
LANG_CREATURE_MOVEMENT_NOT_BOUNDED = 11012,
LANG_CREATURE_MOVEMENT_MAYBE_UNBOUNDED = 11013,
- LANG_INSTANCE_BIND_MISMATCH = 11014
+ LANG_INSTANCE_BIND_MISMATCH = 11014,
+ LANG_CREATURE_NOT_AI_ENABLED = 11015,
+ LANG_SELECT_PLAYER_OR_PET = 11016,
};
#endif
diff --git a/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.cpp
index 108276c951a..6f6a8037d47 100755
--- a/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.cpp
+++ b/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.cpp
@@ -23,11 +23,6 @@
#include "MoveSpline.h"
#include "Player.h"
-#ifdef MAP_BASED_RAND_GEN
-#define rand_norm() unit.rand_norm()
-#define urand(a, b) unit.urand(a, b)
-#endif
-
template<class T>
void ConfusedMovementGenerator<T>::DoInitialize(T* unit)
{
diff --git a/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.cpp
index 2e013c44ae8..421678ded17 100644
--- a/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.cpp
+++ b/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.cpp
@@ -26,10 +26,6 @@
#define RUNNING_CHANCE_RANDOMMV 20 //will be "1 / RUNNING_CHANCE_RANDOMMV"
-#ifdef MAP_BASED_RAND_GEN
-#define rand_norm() creature.rand_norm()
-#endif
-
template<>
void RandomMovementGenerator<Creature>::_setRandomLocation(Creature* creature)
{
diff --git a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp
index 533b087c7a1..3fd3b702ba5 100644
--- a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp
+++ b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp
@@ -40,7 +40,10 @@ void TargetedMovementGeneratorMedium<T, D>::_setTargetLocation(T* owner, bool up
return;
if (owner->GetTypeId() == TYPEID_UNIT && !i_target->isInAccessiblePlaceFor(owner->ToCreature()))
+ {
+ owner->ToCreature()->SetCannotReachTarget(true);
return;
+ }
if (owner->GetTypeId() == TYPEID_UNIT && owner->ToCreature()->IsFocusing(nullptr, true))
return;
@@ -105,8 +108,10 @@ void TargetedMovementGeneratorMedium<T, D>::_setTargetLocation(T* owner, bool up
bool result = i_path->CalculatePath(x, y, z, forceDest);
if (!result || (i_path->GetPathType() & PATHFIND_NOPATH))
{
- // Cant reach target
+ // can't reach target
i_recalculateTravel = true;
+ if (owner->GetTypeId() == TYPEID_UNIT)
+ owner->ToCreature()->SetCannotReachTarget(true);
return;
}
@@ -114,6 +119,8 @@ void TargetedMovementGeneratorMedium<T, D>::_setTargetLocation(T* owner, bool up
i_targetReached = false;
i_recalculateTravel = false;
owner->AddUnitState(UNIT_STATE_CHASE);
+ if (owner->GetTypeId() == TYPEID_UNIT)
+ owner->ToCreature()->SetCannotReachTarget(false);
Movement::MoveSplineInit init(owner);
init.MovebyPath(i_path->GetPath());
@@ -204,6 +211,8 @@ void ChaseMovementGenerator<T>::_reachTarget(T* owner)
{
if (owner->IsWithinMeleeRange(this->i_target.getTarget()))
owner->Attack(this->i_target.getTarget(), true);
+ if (owner->GetTypeId() == TYPEID_UNIT)
+ owner->ToCreature()->SetCannotReachTarget(false);
}
template<>
diff --git a/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp
index 48d29b3259b..dd1cf494325 100755
--- a/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp
+++ b/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp
@@ -213,7 +213,7 @@ bool WaypointMovementGenerator<Creature>::DoUpdate(Creature* creature, uint32 di
creature->SetHomePosition(creature->GetPosition());
if (creature->IsStopped())
- Stop(STOP_TIME_FOR_PLAYER);
+ Stop(sWorld->getIntConfig(CONFIG_CREATURE_STOP_FOR_PLAYER));
else if (creature->movespline->Finalized())
{
OnArrived(creature);
diff --git a/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.h b/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.h
index 1dd4611d53b..72309822dab 100755
--- a/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.h
+++ b/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.h
@@ -28,9 +28,9 @@
#include "MovementGenerator.h"
#include "WaypointManager.h"
#include "Player.h"
+#include "World.h"
#define FLIGHT_TRAVEL_UPDATE 100
-#define STOP_TIME_FOR_PLAYER 3 * MINUTE * IN_MILLISECONDS // 3 Minutes
#define TIMEDIFF_NEXT_WP 250
template<class T, class P>
diff --git a/src/server/game/Scripting/ScriptMgr.cpp b/src/server/game/Scripting/ScriptMgr.cpp
index ca1cd71363e..ac440da3f24 100644
--- a/src/server/game/Scripting/ScriptMgr.cpp
+++ b/src/server/game/Scripting/ScriptMgr.cpp
@@ -368,6 +368,8 @@ class CreatureGameObjectScriptRegistrySwapHooks
// Hook which is called before a creature is swapped
static void UnloadStage1(Creature* creature)
{
+ creature->m_Events.KillAllEvents(true);
+
if (creature->IsCharmed())
creature->RemoveCharmedBy(nullptr);
diff --git a/src/server/game/Server/Protocol/PacketLog.cpp b/src/server/game/Server/Protocol/PacketLog.cpp
index 11a02828998..114b2ae0ecc 100644
--- a/src/server/game/Server/Protocol/PacketLog.cpp
+++ b/src/server/game/Server/Protocol/PacketLog.cpp
@@ -45,7 +45,7 @@ struct PacketHeader
uint32 SocketPort;
};
- char Direction[4];
+ uint32 Direction;
uint32 ConnectionId;
uint32 ArrivalTicks;
uint32 OptionalDataSize;
@@ -109,7 +109,7 @@ void PacketLog::LogPacket(WorldPacket const& packet, Direction direction, boost:
std::lock_guard<std::mutex> lock(_logPacketLock);
PacketHeader header;
- *reinterpret_cast<uint32*>(header.Direction) = direction == CLIENT_TO_SERVER ? 0x47534d43 : 0x47534d53;
+ header.Direction = direction == CLIENT_TO_SERVER ? 0x47534d43 : 0x47534d53;
header.ConnectionId = 0;
header.ArrivalTicks = getMSTime();
diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
index a8adda3ad58..ffe79293430 100644
--- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp
+++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
@@ -4686,7 +4686,7 @@ void AuraEffect::HandleAuraDummy(AuraApplication const* aurApp, uint8 mode, bool
case 71563:
if (Aura* newAura = target->AddAura(71564, target))
newAura->SetStackAmount(newAura->GetSpellInfo()->StackAmount);
- break;
+ break;
}
}
// AT REMOVE
@@ -5979,9 +5979,6 @@ void AuraEffect::HandlePeriodicHealthLeechAuraTick(Unit* target, Unit* caster) c
caster->SendSpellNonMeleeDamageLog(target, GetId(), damage, GetSpellInfo()->GetSchoolMask(), absorb, resist, false, 0, crit);
- if (target->GetHealth() < damage)
- damage = uint32(target->GetHealth());
-
// Set trigger flag
uint32 procAttacker = PROC_FLAG_DONE_PERIODIC;
uint32 procVictim = PROC_FLAG_TAKEN_PERIODIC;
diff --git a/src/server/game/Spells/Auras/SpellAuras.cpp b/src/server/game/Spells/Auras/SpellAuras.cpp
index 1ca5df6b327..74a94a63594 100644
--- a/src/server/game/Spells/Auras/SpellAuras.cpp
+++ b/src/server/game/Spells/Auras/SpellAuras.cpp
@@ -789,7 +789,7 @@ uint8 Aura::CalcMaxCharges(Unit* caster) const
{
uint32 maxProcCharges = m_spellInfo->ProcCharges;
if (SpellProcEntry const* procEntry = sSpellMgr->GetSpellProcEntry(GetId()))
- maxProcCharges = procEntry->charges;
+ maxProcCharges = procEntry->Charges;
if (caster)
if (Player* modOwner = caster->GetSpellModOwner())
@@ -1861,9 +1861,9 @@ bool Aura::IsProcOnCooldown() const
return false;
}
-void Aura::AddProcCooldown(uint32 /*msec*/)
+void Aura::AddProcCooldown(Milliseconds /*msec*/)
{
- //m_procCooldown = time(NULL) + msec;
+ //m_procCooldown = std::chrono::steady_clock::now() + msec;
}
void Aura::PrepareProcToTrigger(AuraApplication* aurApp, ProcEventInfo& eventInfo)
@@ -1884,7 +1884,7 @@ void Aura::PrepareProcToTrigger(AuraApplication* aurApp, ProcEventInfo& eventInf
ASSERT(procEntry);
// cooldowns should be added to the whole aura (see 51698 area aura)
- AddProcCooldown(procEntry->cooldown);
+ AddProcCooldown(procEntry->Cooldown);
}
bool Aura::IsProcTriggeredOnEvent(AuraApplication* aurApp, ProcEventInfo& eventInfo) const
@@ -1963,16 +1963,16 @@ bool Aura::IsProcTriggeredOnEvent(AuraApplication* aurApp, ProcEventInfo& eventI
float Aura::CalcProcChance(SpellProcEntry const& procEntry, ProcEventInfo& eventInfo) const
{
- float chance = procEntry.chance;
+ float chance = procEntry.Chance;
// calculate chances depending on unit with caster's data
// so talents modifying chances and judgements will have properly calculated proc chance
if (Unit* caster = GetCaster())
{
// calculate ppm chance if present and we're using weapon
- if (eventInfo.GetDamageInfo() && procEntry.ratePerMinute != 0)
+ if (eventInfo.GetDamageInfo() && procEntry.ProcsPerMinute != 0)
{
uint32 WeaponSpeed = caster->GetAttackTime(eventInfo.GetDamageInfo()->GetAttackType());
- chance = caster->GetPPMProcChance(WeaponSpeed, procEntry.ratePerMinute, GetSpellInfo());
+ chance = caster->GetPPMProcChance(WeaponSpeed, procEntry.ProcsPerMinute, GetSpellInfo());
}
// apply chance modifer aura, applies also to ppm chance (see improved judgement of light spell)
if (Player* modOwner = caster->GetSpellModOwner())
diff --git a/src/server/game/Spells/Auras/SpellAuras.h b/src/server/game/Spells/Auras/SpellAuras.h
index 750110dc146..f792581c86d 100644
--- a/src/server/game/Spells/Auras/SpellAuras.h
+++ b/src/server/game/Spells/Auras/SpellAuras.h
@@ -204,7 +204,7 @@ class TC_GAME_API Aura
// and some dependant problems fixed before it can replace old proc system (for example cooldown handling)
// currently proc system functionality is implemented in Unit::ProcDamageAndSpell
bool IsProcOnCooldown() const;
- void AddProcCooldown(uint32 msec);
+ void AddProcCooldown(Milliseconds msec);
bool IsUsingCharges() const { return m_isUsingCharges; }
void SetUsingCharges(bool val) { m_isUsingCharges = val; }
void PrepareProcToTrigger(AuraApplication* aurApp, ProcEventInfo& eventInfo);
diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp
index 8329e0f3ca1..4176e8fb20e 100644
--- a/src/server/game/Spells/Spell.cpp
+++ b/src/server/game/Spells/Spell.cpp
@@ -1302,18 +1302,30 @@ void Spell::SelectImplicitCasterDestTargets(SpellEffIndex effIndex, SpellImplici
}
default:
{
- float dist;
+ float dist = m_spellInfo->Effects[effIndex].CalcRadius(m_caster);
float angle = targetType.CalcDirectionAngle();
float objSize = m_caster->GetObjectSize();
- if (targetType.GetTarget() == TARGET_DEST_CASTER_SUMMON)
- dist = PET_FOLLOW_DIST;
- else
- dist = m_spellInfo->Effects[effIndex].CalcRadius(m_caster);
if (dist < objSize)
dist = objSize;
- else if (targetType.GetTarget() == TARGET_DEST_CASTER_RANDOM)
- dist = objSize + (dist - objSize) * float(rand_norm());
+
+ switch (targetType.GetTarget())
+ {
+ case TARGET_DEST_CASTER_SUMMON:
+ dist = PET_FOLLOW_DIST;
+ break;
+ case TARGET_DEST_CASTER_RANDOM:
+ dist = objSize + (dist - objSize) * float(rand_norm());
+ break;
+ case TARGET_DEST_CASTER_FRONT_LEFT:
+ case TARGET_DEST_CASTER_BACK_LEFT:
+ case TARGET_DEST_CASTER_FRONT_RIGHT:
+ case TARGET_DEST_CASTER_BACK_RIGHT:
+ dist = dist + objSize;
+ break;
+ default:
+ break;
+ }
Position pos = dest._position;
m_caster->MovePositionToFirstCollision(pos, dist, angle);
@@ -5329,6 +5341,9 @@ SpellCastResult Spell::CheckCast(bool strict)
if (!target || m_caster->ToPlayer() == target || (!target->IsInSameRaidWith(m_caster->ToPlayer()) && m_spellInfo->Id != 48955)) // refer-a-friend spell
return SPELL_FAILED_BAD_TARGETS;
+ if (target->HasSummonPending())
+ return SPELL_FAILED_SUMMON_PENDING;
+
// check if our map is dungeon
MapEntry const* map = sMapStore.LookupEntry(m_caster->GetMapId());
if (map->IsDungeon())
diff --git a/src/server/game/Spells/Spell.h b/src/server/game/Spells/Spell.h
index e634aa62a1c..b7134283ccb 100644
--- a/src/server/game/Spells/Spell.h
+++ b/src/server/game/Spells/Spell.h
@@ -694,14 +694,6 @@ class TC_GAME_API Spell
ByteBuffer * m_effectExecuteData[MAX_SPELL_EFFECTS];
-#ifdef MAP_BASED_RAND_GEN
- int32 irand(int32 min, int32 max) { return int32 (m_caster->GetMap()->mtRand.randInt(max - min)) + min; }
- uint32 urand(uint32 min, uint32 max) { return m_caster->GetMap()->mtRand.randInt(max - min) + min; }
- int32 rand32() { return m_caster->GetMap()->mtRand.randInt(); }
- double rand_norm() { return m_caster->GetMap()->mtRand.randExc(); }
- double rand_chance() { return m_caster->GetMap()->mtRand.randExc(100.0); }
-#endif
-
Spell(Spell const& right) = delete;
Spell& operator=(Spell const& right) = delete;
};
diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp
index 1c2b2743a6d..51b6db197db 100644
--- a/src/server/game/Spells/SpellEffects.cpp
+++ b/src/server/game/Spells/SpellEffects.cpp
@@ -4212,20 +4212,7 @@ void Spell::EffectSummonPlayer(SpellEffIndex /*effIndex*/)
if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER)
return;
- // Evil Twin (ignore player summon, but hide this for summoner)
- if (unitTarget->HasAura(23445))
- return;
-
- float x, y, z;
- m_caster->GetPosition(x, y, z);
-
- unitTarget->ToPlayer()->SetSummonPoint(m_caster->GetMapId(), x, y, z);
-
- WorldPacket data(SMSG_SUMMON_REQUEST, 8+4+4);
- data << uint64(m_caster->GetGUID()); // summoner guid
- data << uint32(m_caster->GetZoneId()); // summoner zone
- data << uint32(MAX_PLAYER_SUMMON_DELAY*IN_MILLISECONDS); // auto decline after msecs
- unitTarget->ToPlayer()->GetSession()->SendPacket(&data);
+ unitTarget->ToPlayer()->SendSummonRequestFrom(m_caster);
}
void Spell::EffectActivateObject(SpellEffIndex /*effIndex*/)
diff --git a/src/server/game/Spells/SpellHistory.cpp b/src/server/game/Spells/SpellHistory.cpp
index 4f74197fed2..31490bea29b 100644
--- a/src/server/game/Spells/SpellHistory.cpp
+++ b/src/server/game/Spells/SpellHistory.cpp
@@ -533,7 +533,7 @@ void SpellHistory::LockSpellSchool(SpellSchoolMask schoolMask, uint32 lockoutTim
else
{
Creature* creatureOwner = _owner->ToCreature();
- for (uint8 i = 0; i < CREATURE_MAX_SPELLS; ++i)
+ for (uint8 i = 0; i < MAX_CREATURE_SPELLS; ++i)
if (creatureOwner->m_spells[i])
knownSpells.insert(creatureOwner->m_spells[i]);
}
diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp
index 50f750f2ca5..56042e05257 100644
--- a/src/server/game/Spells/SpellMgr.cpp
+++ b/src/server/game/Spells/SpellMgr.cpp
@@ -955,11 +955,11 @@ SpellProcEntry const* SpellMgr::GetSpellProcEntry(uint32 spellId) const
bool SpellMgr::CanSpellTriggerProcOnEvent(SpellProcEntry const& procEntry, ProcEventInfo& eventInfo) const
{
// proc type doesn't match
- if (!(eventInfo.GetTypeMask() & procEntry.typeMask))
+ if (!(eventInfo.GetTypeMask() & procEntry.ProcFlags))
return false;
// check XP or honor target requirement
- if (procEntry.attributesMask & PROC_ATTR_REQ_EXP_OR_HONOR)
+ if (procEntry.AttributesMask & PROC_ATTR_REQ_EXP_OR_HONOR)
if (Player* actor = eventInfo.GetActor()->ToPlayer())
if (eventInfo.GetActionTarget() && !actor->isHonorOrXPTarget(eventInfo.GetActionTarget()))
return false;
@@ -969,7 +969,7 @@ bool SpellMgr::CanSpellTriggerProcOnEvent(SpellProcEntry const& procEntry, ProcE
return true;
// check school mask (if set) for other trigger types
- if (procEntry.schoolMask && !(eventInfo.GetSchoolMask() & procEntry.schoolMask))
+ if (procEntry.SchoolMask && !(eventInfo.GetSchoolMask() & procEntry.SchoolMask))
return false;
// check spell family name/flags (if set) for spells
@@ -977,31 +977,31 @@ bool SpellMgr::CanSpellTriggerProcOnEvent(SpellProcEntry const& procEntry, ProcE
{
SpellInfo const* eventSpellInfo = eventInfo.GetSpellInfo();
- if (procEntry.spellFamilyName && eventSpellInfo && (procEntry.spellFamilyName != eventSpellInfo->SpellFamilyName))
+ if (procEntry.SpellFamilyName && eventSpellInfo && (procEntry.SpellFamilyName != eventSpellInfo->SpellFamilyName))
return false;
- if (procEntry.spellFamilyMask && eventSpellInfo && !(procEntry.spellFamilyMask & eventSpellInfo->SpellFamilyFlags))
+ if (procEntry.SpellFamilyMask && eventSpellInfo && !(procEntry.SpellFamilyMask & eventSpellInfo->SpellFamilyFlags))
return false;
}
// check spell type mask (if set)
if (eventInfo.GetTypeMask() & (SPELL_PROC_FLAG_MASK | PERIODIC_PROC_FLAG_MASK))
{
- if (procEntry.spellTypeMask && !(eventInfo.GetSpellTypeMask() & procEntry.spellTypeMask))
+ if (procEntry.SpellTypeMask && !(eventInfo.GetSpellTypeMask() & procEntry.SpellTypeMask))
return false;
}
// check spell phase mask
if (eventInfo.GetTypeMask() & REQ_SPELL_PHASE_PROC_FLAG_MASK)
{
- if (!(eventInfo.GetSpellPhaseMask() & procEntry.spellPhaseMask))
+ if (!(eventInfo.GetSpellPhaseMask() & procEntry.SpellPhaseMask))
return false;
}
// check hit mask (on taken hit or on done hit, but not on spell cast phase)
if ((eventInfo.GetTypeMask() & TAKEN_HIT_PROC_FLAG_MASK) || ((eventInfo.GetTypeMask() & DONE_HIT_PROC_FLAG_MASK) && !(eventInfo.GetSpellPhaseMask() & PROC_SPELL_PHASE_CAST)))
{
- uint32 hitMask = procEntry.hitMask;
+ uint32 hitMask = procEntry.HitMask;
// get default values if hit mask not set
if (!hitMask)
{
@@ -1929,8 +1929,11 @@ void SpellMgr::LoadSpellProcs()
mSpellProcMap.clear(); // need for reload case
- // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
- QueryResult result = WorldDatabase.Query("SELECT spellId, schoolMask, spellFamilyName, spellFamilyMask0, spellFamilyMask1, spellFamilyMask2, typeMask, spellTypeMask, spellPhaseMask, hitMask, attributesMask, ratePerMinute, chance, cooldown, charges FROM spell_proc");
+ // 0 1 2 3 4 5
+ QueryResult result = WorldDatabase.Query("SELECT SpellId, SchoolMask, SpellFamilyName, SpellFamilyMask0, SpellFamilyMask1, SpellFamilyMask2, "
+ // 6 7 8 9 10 11 12 13 14
+ "ProcFlags, SpellTypeMask, SpellPhaseMask, HitMask, AttributesMask, ProcsPerMinute, Chance, Cooldown, Charges FROM spell_proc");
+
if (!result)
{
TC_LOG_INFO("server.loading", ">> Loaded 0 spell proc conditions and data. DB table `spell_proc` is empty.");
@@ -1972,21 +1975,20 @@ void SpellMgr::LoadSpellProcs()
SpellProcEntry baseProcEntry;
- baseProcEntry.schoolMask = fields[1].GetInt8();
- baseProcEntry.spellFamilyName = fields[2].GetUInt16();
- baseProcEntry.spellFamilyMask[0] = fields[3].GetUInt32();
- baseProcEntry.spellFamilyMask[1] = fields[4].GetUInt32();
- baseProcEntry.spellFamilyMask[2] = fields[5].GetUInt32();
- baseProcEntry.typeMask = fields[6].GetUInt32();
- baseProcEntry.spellTypeMask = fields[7].GetUInt32();
- baseProcEntry.spellPhaseMask = fields[8].GetUInt32();
- baseProcEntry.hitMask = fields[9].GetUInt32();
- baseProcEntry.attributesMask = fields[10].GetUInt32();
- baseProcEntry.ratePerMinute = fields[11].GetFloat();
- baseProcEntry.chance = fields[12].GetFloat();
- float cooldown = fields[13].GetFloat();
- baseProcEntry.cooldown = uint32(cooldown);
- baseProcEntry.charges = fields[14].GetUInt32();
+ baseProcEntry.SchoolMask = fields[1].GetInt8();
+ baseProcEntry.SpellFamilyName = fields[2].GetUInt16();
+ baseProcEntry.SpellFamilyMask[0] = fields[3].GetUInt32();
+ baseProcEntry.SpellFamilyMask[1] = fields[4].GetUInt32();
+ baseProcEntry.SpellFamilyMask[2] = fields[5].GetUInt32();
+ baseProcEntry.ProcFlags = fields[6].GetUInt32();
+ baseProcEntry.SpellTypeMask = fields[7].GetUInt32();
+ baseProcEntry.SpellPhaseMask = fields[8].GetUInt32();
+ baseProcEntry.HitMask = fields[9].GetUInt32();
+ baseProcEntry.AttributesMask = fields[10].GetUInt32();
+ baseProcEntry.ProcsPerMinute = fields[11].GetFloat();
+ baseProcEntry.Chance = fields[12].GetFloat();
+ baseProcEntry.Cooldown = Milliseconds(fields[13].GetUInt32());
+ baseProcEntry.Charges = fields[14].GetUInt8();
while (spellInfo)
{
@@ -1999,56 +2001,46 @@ void SpellMgr::LoadSpellProcs()
SpellProcEntry procEntry = SpellProcEntry(baseProcEntry);
// take defaults from dbcs
- if (!procEntry.typeMask)
- procEntry.typeMask = spellInfo->ProcFlags;
- if (!procEntry.charges)
- procEntry.charges = spellInfo->ProcCharges;
- if (!procEntry.chance && !procEntry.ratePerMinute)
- procEntry.chance = float(spellInfo->ProcChance);
+ if (!procEntry.ProcFlags)
+ procEntry.ProcFlags = spellInfo->ProcFlags;
+ if (!procEntry.Charges)
+ procEntry.Charges = spellInfo->ProcCharges;
+ if (!procEntry.Chance && !procEntry.ProcsPerMinute)
+ procEntry.Chance = float(spellInfo->ProcChance);
// validate data
- if (procEntry.schoolMask & ~SPELL_SCHOOL_MASK_ALL)
- TC_LOG_ERROR("sql.sql", "`spell_proc` table entry for spellId %u has wrong `schoolMask` set: %u", spellInfo->Id, procEntry.schoolMask);
- if (procEntry.spellFamilyName && (procEntry.spellFamilyName < 3 || procEntry.spellFamilyName > 17 || procEntry.spellFamilyName == 14 || procEntry.spellFamilyName == 16))
- TC_LOG_ERROR("sql.sql", "`spell_proc` table entry for spellId %u has wrong `spellFamilyName` set: %u", spellInfo->Id, procEntry.spellFamilyName);
- if (procEntry.chance < 0)
- {
- TC_LOG_ERROR("sql.sql", "`spell_proc` table entry for spellId %u has negative value in the `chance` field", spellInfo->Id);
- procEntry.chance = 0;
- }
- if (procEntry.ratePerMinute < 0)
- {
- TC_LOG_ERROR("sql.sql", "`spell_proc` table entry for spellId %u has negative value in the `ratePerMinute` field", spellInfo->Id);
- procEntry.ratePerMinute = 0;
- }
- if (cooldown < 0)
+ if (procEntry.SchoolMask & ~SPELL_SCHOOL_MASK_ALL)
+ TC_LOG_ERROR("sql.sql", "`spell_proc` table entry for spellId %u has wrong `SchoolMask` set: %u", spellInfo->Id, procEntry.SchoolMask);
+ if (procEntry.SpellFamilyName && (procEntry.SpellFamilyName < 3 || procEntry.SpellFamilyName > 17 || procEntry.SpellFamilyName == 14 || procEntry.SpellFamilyName == 16))
+ TC_LOG_ERROR("sql.sql", "`spell_proc` table entry for spellId %u has wrong `SpellFamilyName` set: %u", spellInfo->Id, procEntry.SpellFamilyName);
+ if (procEntry.Chance < 0)
{
- TC_LOG_ERROR("sql.sql", "`spell_proc` table entry for spellId %u has negative value in the `cooldown` field", spellInfo->Id);
- procEntry.cooldown = 0;
+ TC_LOG_ERROR("sql.sql", "`spell_proc` table entry for spellId %u has negative value in the `Chance` field", spellInfo->Id);
+ procEntry.Chance = 0;
}
- if (procEntry.chance == 0 && procEntry.ratePerMinute == 0)
- TC_LOG_ERROR("sql.sql", "`spell_proc` table entry for spellId %u doesn't have any `chance` and `ratePerMinute` values defined, proc will not be triggered", spellInfo->Id);
- if (procEntry.charges > 99)
+ if (procEntry.ProcsPerMinute < 0)
{
- TC_LOG_ERROR("sql.sql", "The `spell_proc` table entry for spellId %u has a too big `charges` field value.", spellInfo->Id);
- procEntry.charges = 99;
+ TC_LOG_ERROR("sql.sql", "`spell_proc` table entry for spellId %u has negative value in the `ProcsPerMinute` field", spellInfo->Id);
+ procEntry.ProcsPerMinute = 0;
}
- if (!procEntry.typeMask)
- TC_LOG_ERROR("sql.sql", "The `spell_proc` table entry for spellId %u doesn't have any `typeMask` value defined, proc will not be triggered.", spellInfo->Id);
- if (procEntry.spellTypeMask & ~PROC_SPELL_TYPE_MASK_ALL)
- TC_LOG_ERROR("sql.sql", "`spell_proc` table entry for spellId %u has wrong `spellTypeMask` set: %u", spellInfo->Id, procEntry.spellTypeMask);
- if (procEntry.spellTypeMask && !(procEntry.typeMask & (SPELL_PROC_FLAG_MASK | PERIODIC_PROC_FLAG_MASK)))
- TC_LOG_ERROR("sql.sql", "The `spell_proc` table entry for spellId %u has `spellTypeMask` value defined, but it will not be used for the defined `typeMask` value.", spellInfo->Id);
- if (!procEntry.spellPhaseMask && procEntry.typeMask & REQ_SPELL_PHASE_PROC_FLAG_MASK)
- TC_LOG_ERROR("sql.sql", "The `spell_proc` table entry for spellId %u doesn't have any `spellPhaseMask` value defined, but it is required for the defined `typeMask` value. Proc will not be triggered.", spellInfo->Id);
- if (procEntry.spellPhaseMask & ~PROC_SPELL_PHASE_MASK_ALL)
- TC_LOG_ERROR("sql.sql", "The `spell_proc` table entry for spellId %u has wrong `spellPhaseMask` set: %u", spellInfo->Id, procEntry.spellPhaseMask);
- if (procEntry.spellPhaseMask && !(procEntry.typeMask & REQ_SPELL_PHASE_PROC_FLAG_MASK))
- TC_LOG_ERROR("sql.sql", "The `spell_proc` table entry for spellId %u has a `spellPhaseMask` value defined, but it will not be used for the defined `typeMask` value.", spellInfo->Id);
- if (procEntry.hitMask & ~PROC_HIT_MASK_ALL)
- TC_LOG_ERROR("sql.sql", "The `spell_proc` table entry for spellId %u has wrong `hitMask` set: %u", spellInfo->Id, procEntry.hitMask);
- if (procEntry.hitMask && !(procEntry.typeMask & TAKEN_HIT_PROC_FLAG_MASK || (procEntry.typeMask & DONE_HIT_PROC_FLAG_MASK && (!procEntry.spellPhaseMask || procEntry.spellPhaseMask & (PROC_SPELL_PHASE_HIT | PROC_SPELL_PHASE_FINISH)))))
- TC_LOG_ERROR("sql.sql", "The `spell_proc` table entry for spellId %u has `hitMask` value defined, but it will not be used for defined `typeMask` and `spellPhaseMask` values.", spellInfo->Id);
+ if (procEntry.Chance == 0 && procEntry.ProcsPerMinute == 0)
+ TC_LOG_ERROR("sql.sql", "`spell_proc` table entry for spellId %u doesn't have any `Chance` and `ProcsPerMinute` values defined, proc will not be triggered", spellInfo->Id);
+ if (!procEntry.ProcFlags)
+ TC_LOG_ERROR("sql.sql", "The `spell_proc` table entry for spellId %u doesn't have any `ProcFlags` value defined, proc will not be triggered.", spellInfo->Id);
+ if (procEntry.SpellTypeMask & ~PROC_SPELL_TYPE_MASK_ALL)
+ TC_LOG_ERROR("sql.sql", "`spell_proc` table entry for spellId %u has wrong `SpellTypeMask` set: %u", spellInfo->Id, procEntry.SpellTypeMask);
+ if (procEntry.SpellTypeMask && !(procEntry.ProcFlags & (SPELL_PROC_FLAG_MASK | PERIODIC_PROC_FLAG_MASK)))
+ TC_LOG_ERROR("sql.sql", "The `spell_proc` table entry for spellId %u has `SpellTypeMask` value defined, but it will not be used for the defined `ProcFlags` value.", spellInfo->Id);
+ if (!procEntry.SpellPhaseMask && procEntry.ProcFlags & REQ_SPELL_PHASE_PROC_FLAG_MASK)
+ TC_LOG_ERROR("sql.sql", "The `spell_proc` table entry for spellId %u doesn't have any `SpellPhaseMask` value defined, but it is required for the defined `ProcFlags` value. Proc will not be triggered.", spellInfo->Id);
+ if (procEntry.SpellPhaseMask & ~PROC_SPELL_PHASE_MASK_ALL)
+ TC_LOG_ERROR("sql.sql", "The `spell_proc` table entry for spellId %u has wrong `SpellPhaseMask` set: %u", spellInfo->Id, procEntry.SpellPhaseMask);
+ if (procEntry.SpellPhaseMask && !(procEntry.ProcFlags & REQ_SPELL_PHASE_PROC_FLAG_MASK))
+ TC_LOG_ERROR("sql.sql", "The `spell_proc` table entry for spellId %u has a `SpellPhaseMask` value defined, but it will not be used for the defined `ProcFlags` value.", spellInfo->Id);
+ if (procEntry.HitMask & ~PROC_HIT_MASK_ALL)
+ TC_LOG_ERROR("sql.sql", "The `spell_proc` table entry for spellId %u has wrong `HitMask` set: %u", spellInfo->Id, procEntry.HitMask);
+ if (procEntry.HitMask && !(procEntry.ProcFlags & TAKEN_HIT_PROC_FLAG_MASK || (procEntry.ProcFlags & DONE_HIT_PROC_FLAG_MASK && (!procEntry.SpellPhaseMask || procEntry.SpellPhaseMask & (PROC_SPELL_PHASE_HIT | PROC_SPELL_PHASE_FINISH)))))
+ TC_LOG_ERROR("sql.sql", "The `spell_proc` table entry for spellId %u has `HitMask` value defined, but it will not be used for defined `ProcFlags` and `SpellPhaseMask` values.", spellInfo->Id);
mSpellProcMap[spellInfo->Id] = procEntry;
diff --git a/src/server/game/Spells/SpellMgr.h b/src/server/game/Spells/SpellMgr.h
index fea7513b092..75da933636c 100644
--- a/src/server/game/Spells/SpellMgr.h
+++ b/src/server/game/Spells/SpellMgr.h
@@ -266,7 +266,7 @@ enum ProcFlagsHit
PROC_HIT_REFLECT = 0x0000800,
PROC_HIT_INTERRUPT = 0x0001000, // (not used atm)
PROC_HIT_FULL_BLOCK = 0x0002000,
- PROC_HIT_MASK_ALL = 0x2FFF
+ PROC_HIT_MASK_ALL = 0x0002FFF
};
enum ProcAttributes
@@ -290,18 +290,18 @@ typedef std::unordered_map<uint32, SpellProcEventEntry> SpellProcEventMap;
struct SpellProcEntry
{
- uint32 schoolMask; // if nonzero - bitmask for matching proc condition based on spell's school
- uint32 spellFamilyName; // if nonzero - for matching proc condition based on candidate spell's SpellFamilyName
- flag96 spellFamilyMask; // if nonzero - bitmask for matching proc condition based on candidate spell's SpellFamilyFlags
- uint32 typeMask; // if nonzero - owerwrite procFlags field for given Spell.dbc entry, bitmask for matching proc condition, see enum ProcFlags
- uint32 spellTypeMask; // if nonzero - bitmask for matching proc condition based on candidate spell's damage/heal effects, see enum ProcFlagsSpellType
- uint32 spellPhaseMask; // if nonzero - bitmask for matching phase of a spellcast on which proc occurs, see enum ProcFlagsSpellPhase
- uint32 hitMask; // if nonzero - bitmask for matching proc condition based on hit result, see enum ProcFlagsHit
- uint32 attributesMask; // bitmask, see ProcAttributes
- float ratePerMinute; // if nonzero - chance to proc is equal to value * aura caster's weapon speed / 60
- float chance; // if nonzero - owerwrite procChance field for given Spell.dbc entry, defines chance of proc to occur, not used if perMinuteRate set
- uint32 cooldown; // if nonzero - cooldown in secs for aura proc, applied to aura
- uint32 charges; // if nonzero - owerwrite procCharges field for given Spell.dbc entry, defines how many times proc can occur before aura remove, 0 - infinite
+ uint32 SchoolMask; // if nonzero - bitmask for matching proc condition based on spell's school
+ uint32 SpellFamilyName; // if nonzero - for matching proc condition based on candidate spell's SpellFamilyName
+ flag96 SpellFamilyMask; // if nonzero - bitmask for matching proc condition based on candidate spell's SpellFamilyFlags
+ uint32 ProcFlags; // if nonzero - owerwrite procFlags field for given Spell.dbc entry, bitmask for matching proc condition, see enum ProcFlags
+ uint32 SpellTypeMask; // if nonzero - bitmask for matching proc condition based on candidate spell's damage/heal effects, see enum ProcFlagsSpellType
+ uint32 SpellPhaseMask; // if nonzero - bitmask for matching phase of a spellcast on which proc occurs, see enum ProcFlagsSpellPhase
+ uint32 HitMask; // if nonzero - bitmask for matching proc condition based on hit result, see enum ProcFlagsHit
+ uint32 AttributesMask; // bitmask, see ProcAttributes
+ float ProcsPerMinute; // if nonzero - chance to proc is equal to value * aura caster's weapon speed / 60
+ float Chance; // if nonzero - owerwrite procChance field for given Spell.dbc entry, defines chance of proc to occur, not used if ProcsPerMinute set
+ Milliseconds Cooldown; // if nonzero - cooldown in secs for aura proc, applied to aura
+ uint32 Charges; // if nonzero - owerwrite procCharges field for given Spell.dbc entry, defines how many times proc can occur before aura remove, 0 - infinite
};
typedef std::unordered_map<uint32, SpellProcEntry> SpellProcMap;
diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp
index 4b64ef0bbd8..d84fe11383f 100644
--- a/src/server/game/World/World.cpp
+++ b/src/server/game/World/World.cpp
@@ -66,7 +66,7 @@
#include "WaypointMovementGenerator.h"
#include "WeatherMgr.h"
#include "WorldSession.h"
-
+#include "M2Stores.h"
TC_GAME_API std::atomic<bool> World::m_stopEvent(false);
TC_GAME_API uint8 World::m_ExitCode = SHUTDOWN_EXIT_CODE;
@@ -900,6 +900,7 @@ void World::LoadConfigSettings(bool reload)
m_bool_configs[CONFIG_ALLOW_GM_GROUP] = sConfigMgr->GetBoolDefault("GM.AllowInvite", false);
m_bool_configs[CONFIG_GM_LOWER_SECURITY] = sConfigMgr->GetBoolDefault("GM.LowerSecurity", false);
m_float_configs[CONFIG_CHANCE_OF_GM_SURVEY] = sConfigMgr->GetFloatDefault("GM.TicketSystem.ChanceOfGMSurvey", 50.0f);
+ m_int_configs[CONFIG_FORCE_SHUTDOWN_THRESHOLD] = sConfigMgr->GetIntDefault("GM.ForceShutdownThreshold", 30);
m_int_configs[CONFIG_GROUP_VISIBILITY] = sConfigMgr->GetIntDefault("Visibility.GroupMode", 1);
@@ -1082,6 +1083,7 @@ void World::LoadConfigSettings(bool reload)
m_bool_configs[CONFIG_OFFHAND_CHECK_AT_SPELL_UNLEARN] = sConfigMgr->GetBoolDefault("OffhandCheckAtSpellUnlearn", true);
m_int_configs[CONFIG_CREATURE_PICKPOCKET_REFILL] = sConfigMgr->GetIntDefault("Creature.PickPocketRefillDelay", 10 * MINUTE);
+ m_int_configs[CONFIG_CREATURE_STOP_FOR_PLAYER] = sConfigMgr->GetIntDefault("Creature.MovingStopTimeForPlayer", 3 * MINUTE * IN_MILLISECONDS);
if (int32 clientCacheId = sConfigMgr->GetIntDefault("ClientCacheVersion", 0))
{
@@ -1402,6 +1404,9 @@ void World::SetInitialWorldSettings()
LoadDBCStores(m_dataPath);
DetectDBCLang();
+ // Load cinematic cameras
+ LoadM2Cameras(m_dataPath);
+
std::vector<uint32> mapIds;
for (uint32 mapId = 0; mapId < sMapStore.GetNumRows(); mapId++)
if (sMapStore.LookupEntry(mapId))
diff --git a/src/server/game/World/World.h b/src/server/game/World/World.h
index abc0ea452ac..330e78cf510 100644
--- a/src/server/game/World/World.h
+++ b/src/server/game/World/World.h
@@ -28,7 +28,7 @@
#include "Timer.h"
#include "SharedDefines.h"
#include "QueryResult.h"
-#include "Callback.h"
+#include "QueryCallback.h"
#include "Realm/Realm.h"
#include <atomic>
@@ -56,7 +56,8 @@ enum ServerMessageType
enum ShutdownMask
{
SHUTDOWN_MASK_RESTART = 1,
- SHUTDOWN_MASK_IDLE = 2
+ SHUTDOWN_MASK_IDLE = 2,
+ SHUTDOWN_MASK_FORCE = 4
};
enum ShutdownExitCode
@@ -252,6 +253,7 @@ enum WorldIntConfigs
CONFIG_GM_LEVEL_IN_GM_LIST,
CONFIG_GM_LEVEL_IN_WHO_LIST,
CONFIG_START_GM_LEVEL,
+ CONFIG_FORCE_SHUTDOWN_THRESHOLD,
CONFIG_GROUP_VISIBILITY,
CONFIG_MAIL_DELIVERY_DELAY,
CONFIG_UPTIME_UPDATE,
@@ -357,6 +359,7 @@ enum WorldIntConfigs
CONFIG_BG_REWARD_LOSER_HONOR_LAST,
CONFIG_BIRTHDAY_TIME,
CONFIG_CREATURE_PICKPOCKET_REFILL,
+ CONFIG_CREATURE_STOP_FOR_PLAYER,
CONFIG_AHBOT_UPDATE_INTERVAL,
CONFIG_CHARTER_COST_GUILD,
CONFIG_CHARTER_COST_ARENA_2v2,
diff --git a/src/server/scripts/Commands/cs_character.cpp b/src/server/scripts/Commands/cs_character.cpp
index 9557d182df1..01602e2f24c 100644
--- a/src/server/scripts/Commands/cs_character.cpp
+++ b/src/server/scripts/Commands/cs_character.cpp
@@ -436,7 +436,7 @@ public:
if (isalpha(levelStr[0]))
{
nameStr = levelStr;
- levelStr = NULL; // current level will used
+ levelStr = nullptr; // current level will used
}
Player* target;
diff --git a/src/server/scripts/Commands/cs_debug.cpp b/src/server/scripts/Commands/cs_debug.cpp
index 1d8094885d4..ca4dd814e01 100644
--- a/src/server/scripts/Commands/cs_debug.cpp
+++ b/src/server/scripts/Commands/cs_debug.cpp
@@ -34,6 +34,7 @@ EndScriptData */
#include "Transport.h"
#include "Language.h"
#include "MapManager.h"
+#include "M2Stores.h"
#include <fstream>
@@ -847,7 +848,7 @@ public:
if (Unit* unit = ref->GetSource()->GetOwner())
{
++count;
- handler->PSendSysMessage(" %u. %s (guid %u) - threat %f", count, unit->GetName().c_str(), unit->GetGUID().GetCounter(), ref->getThreat());
+ handler->PSendSysMessage(" %u. %s (current guid %u, DB guid %u) - threat %f", count, unit->GetName().c_str(), unit->GetGUID().GetCounter(), unit->GetTypeId() == TYPEID_UNIT ? unit->ToCreature()->GetSpawnId() : 0, ref->getThreat());
}
ref = ref->next();
}
diff --git a/src/server/scripts/Commands/cs_misc.cpp b/src/server/scripts/Commands/cs_misc.cpp
index 3e35a721162..a98f9f4bf9c 100644
--- a/src/server/scripts/Commands/cs_misc.cpp
+++ b/src/server/scripts/Commands/cs_misc.cpp
@@ -796,7 +796,7 @@ public:
target->CleanupAfterTaxiFlight();
}
- target->TeleportTo(target->m_recallMap, target->m_recallX, target->m_recallY, target->m_recallZ, target->m_recallO);
+ target->Recall();
return true;
}
diff --git a/src/server/scripts/Commands/cs_modify.cpp b/src/server/scripts/Commands/cs_modify.cpp
index f1ddb448b35..e25018cf1bd 100644
--- a/src/server/scripts/Commands/cs_modify.cpp
+++ b/src/server/scripts/Commands/cs_modify.cpp
@@ -80,23 +80,32 @@ public:
return commandTable;
}
- //Edit Player HP
- static bool HandleModifyHPCommand(ChatHandler* handler, const char* args)
+ template<typename... Args>
+ static void NotifyModification(ChatHandler* handler, Unit* target, TrinityStrings resourceMessage, TrinityStrings resourceReportMessage, Args&&... args)
+ {
+ if (Player* player = target->ToPlayer())
+ {
+ handler->PSendSysMessage(resourceMessage, handler->GetNameLink(player).c_str(), args...);
+ if (handler->needReportToTarget(player))
+ ChatHandler(player->GetSession()).PSendSysMessage(resourceReportMessage, handler->GetNameLink().c_str(), std::forward<Args>(args)...);
+ }
+ }
+
+ static bool CheckModifyResources(ChatHandler* handler, const char* args, Player* target, int32& res, int32& resmax, int8 const multiplier = 1)
{
if (!*args)
return false;
- int32 hp = atoi((char*)args);
- int32 hpm = atoi((char*)args);
+ res = atoi((char*)args) * multiplier;
+ resmax = atoi((char*)args) * multiplier;
- if (hp < 1 || hpm < 1 || hpm < hp)
+ if (res < 1 || resmax < 1 || resmax < res)
{
handler->SendSysMessage(LANG_BAD_VALUE);
handler->SetSentErrorMessage(true);
return false;
}
- Player* target = handler->getSelectedPlayerOrSelf();
if (!target)
{
handler->SendSysMessage(LANG_NO_CHAR_SELECTED);
@@ -107,164 +116,87 @@ public:
if (handler->HasLowerSecurity(target, ObjectGuid::Empty))
return false;
- handler->PSendSysMessage(LANG_YOU_CHANGE_HP, handler->GetNameLink(target).c_str(), hp, hpm);
- if (handler->needReportToTarget(target))
- ChatHandler(target->GetSession()).PSendSysMessage(LANG_YOURS_HP_CHANGED, handler->GetNameLink().c_str(), hp, hpm);
-
- target->SetMaxHealth(hpm);
- target->SetHealth(hp);
-
return true;
}
- //Edit Player Mana
- static bool HandleModifyManaCommand(ChatHandler* handler, const char* args)
+ //Edit Player HP
+ static bool HandleModifyHPCommand(ChatHandler* handler, const char* args)
{
- if (!*args)
- return false;
-
- int32 mana = atoi((char*)args);
- int32 manam = atoi((char*)args);
-
- if (mana <= 0 || manam <= 0 || manam < mana)
+ int32 hp, hpmax;
+ Player* target = handler->getSelectedPlayerOrSelf();
+ if (CheckModifyResources(handler, args, target, hp, hpmax))
{
- handler->SendSysMessage(LANG_BAD_VALUE);
- handler->SetSentErrorMessage(true);
- return false;
+ NotifyModification(handler, target, LANG_YOU_CHANGE_HP, LANG_YOURS_HP_CHANGED, hp, hpmax);
+ target->SetMaxHealth(hpmax);
+ target->SetHealth(hp);
+ return true;
}
+ return false;
+ }
+ //Edit Player Mana
+ static bool HandleModifyManaCommand(ChatHandler* handler, const char* args)
+ {
+ int32 mana, manamax;
Player* target = handler->getSelectedPlayerOrSelf();
- if (!target)
+
+ if (CheckModifyResources(handler, args, target, mana, manamax))
{
- handler->SendSysMessage(LANG_NO_CHAR_SELECTED);
- handler->SetSentErrorMessage(true);
- return false;
+ NotifyModification(handler, target, LANG_YOU_CHANGE_MANA, LANG_YOURS_MANA_CHANGED, mana, manamax);
+ target->SetMaxPower(POWER_MANA, manamax);
+ target->SetPower(POWER_MANA, mana);
+ return true;
}
-
- // check online security
- if (handler->HasLowerSecurity(target, ObjectGuid::Empty))
- return false;
-
- handler->PSendSysMessage(LANG_YOU_CHANGE_MANA, handler->GetNameLink(target).c_str(), mana, manam);
- if (handler->needReportToTarget(target))
- ChatHandler(target->GetSession()).PSendSysMessage(LANG_YOURS_MANA_CHANGED, handler->GetNameLink().c_str(), mana, manam);
-
- target->SetMaxPower(POWER_MANA, manam);
- target->SetPower(POWER_MANA, mana);
-
- return true;
+ return false;
}
//Edit Player Energy
static bool HandleModifyEnergyCommand(ChatHandler* handler, const char* args)
{
- if (!*args)
- return false;
-
- int32 energy = atoi((char*)args)*10;
- int32 energym = atoi((char*)args)*10;
-
- if (energy <= 0 || energym <= 0 || energym < energy)
- {
- handler->SendSysMessage(LANG_BAD_VALUE);
- handler->SetSentErrorMessage(true);
- return false;
- }
-
+ int32 energy, energymax;
Player* target = handler->getSelectedPlayerOrSelf();
- if (!target)
+ int8 const energyMultiplier = 10;
+ if (CheckModifyResources(handler, args, target, energy, energymax, energyMultiplier))
{
- handler->SendSysMessage(LANG_NO_CHAR_SELECTED);
- handler->SetSentErrorMessage(true);
- return false;
+ NotifyModification(handler, target, LANG_YOU_CHANGE_ENERGY, LANG_YOURS_ENERGY_CHANGED, energy / energyMultiplier, energymax / energyMultiplier);
+ target->SetMaxPower(POWER_ENERGY, energymax);
+ target->SetPower(POWER_ENERGY, energy);
+ TC_LOG_DEBUG("misc", handler->GetTrinityString(LANG_CURRENT_ENERGY), target->GetMaxPower(POWER_ENERGY));
+ return true;
}
-
- // check online security
- if (handler->HasLowerSecurity(target, ObjectGuid::Empty))
- return false;
-
- handler->PSendSysMessage(LANG_YOU_CHANGE_ENERGY, handler->GetNameLink(target).c_str(), energy/10, energym/10);
- if (handler->needReportToTarget(target))
- ChatHandler(target->GetSession()).PSendSysMessage(LANG_YOURS_ENERGY_CHANGED, handler->GetNameLink().c_str(), energy/10, energym/10);
-
- target->SetMaxPower(POWER_ENERGY, energym);
- target->SetPower(POWER_ENERGY, energy);
-
- TC_LOG_DEBUG("misc", handler->GetTrinityString(LANG_CURRENT_ENERGY), target->GetMaxPower(POWER_ENERGY));
-
- return true;
+ return false;
}
//Edit Player Rage
static bool HandleModifyRageCommand(ChatHandler* handler, const char* args)
{
- if (!*args)
- return false;
-
- int32 rage = atoi((char*)args)*10;
- int32 ragem = atoi((char*)args)*10;
-
- if (rage <= 0 || ragem <= 0 || ragem < rage)
- {
- handler->SendSysMessage(LANG_BAD_VALUE);
- handler->SetSentErrorMessage(true);
- return false;
- }
-
+ int32 rage, ragemax;
Player* target = handler->getSelectedPlayerOrSelf();
- if (!target)
+ int8 const rageMultiplier = 10;
+ if (CheckModifyResources(handler, args, target, rage, ragemax, rageMultiplier))
{
- handler->SendSysMessage(LANG_NO_CHAR_SELECTED);
- handler->SetSentErrorMessage(true);
- return false;
+ NotifyModification(handler, target, LANG_YOU_CHANGE_RAGE, LANG_YOURS_RAGE_CHANGED, rage / rageMultiplier, ragemax / rageMultiplier);
+ target->SetMaxPower(POWER_RAGE, ragemax);
+ target->SetPower(POWER_RAGE, rage);
+ return true;
}
-
- // check online security
- if (handler->HasLowerSecurity(target, ObjectGuid::Empty))
- return false;
-
- handler->PSendSysMessage(LANG_YOU_CHANGE_RAGE, handler->GetNameLink(target).c_str(), rage/10, ragem/10);
- if (handler->needReportToTarget(target))
- ChatHandler(target->GetSession()).PSendSysMessage(LANG_YOURS_RAGE_CHANGED, handler->GetNameLink().c_str(), rage/10, ragem/10);
-
- target->SetMaxPower(POWER_RAGE, ragem);
- target->SetPower(POWER_RAGE, rage);
-
- return true;
+ return false;
}
// Edit Player Runic Power
static bool HandleModifyRunicPowerCommand(ChatHandler* handler, const char* args)
{
- if (!*args)
- return false;
-
- int32 rune = atoi((char*)args)*10;
- int32 runem = atoi((char*)args)*10;
-
- if (rune <= 0 || runem <= 0 || runem < rune)
- {
- handler->SendSysMessage(LANG_BAD_VALUE);
- handler->SetSentErrorMessage(true);
- return false;
- }
-
+ int32 rune, runemax;
Player* target = handler->getSelectedPlayerOrSelf();
- if (!target)
+ int8 const runeMultiplier = 10;
+ if (CheckModifyResources(handler, args, target, rune, runemax, runeMultiplier))
{
- handler->SendSysMessage(LANG_NO_CHAR_SELECTED);
- handler->SetSentErrorMessage(true);
- return false;
+ NotifyModification(handler, target, LANG_YOU_CHANGE_RUNIC_POWER, LANG_YOURS_RUNIC_POWER_CHANGED, rune / runeMultiplier, runemax / runeMultiplier);
+ target->SetMaxPower(POWER_RUNIC_POWER, runemax);
+ target->SetPower(POWER_RUNIC_POWER, rune);
+ return true;
}
-
- handler->PSendSysMessage(LANG_YOU_CHANGE_RUNIC_POWER, handler->GetNameLink(target).c_str(), rune/10, runem/10);
- if (handler->needReportToTarget(target))
- ChatHandler(target->GetSession()).PSendSysMessage(LANG_YOURS_RUNIC_POWER_CHANGED, handler->GetNameLink().c_str(), rune/10, runem/10);
-
- target->SetMaxPower(POWER_RUNIC_POWER, runem);
- target->SetPower(POWER_RUNIC_POWER, rune);
-
- return true;
+ return false;
}
//Edit Player Faction
@@ -437,22 +369,20 @@ public:
return false;
}
- //Edit Player Aspeed
- static bool HandleModifyASpeedCommand(ChatHandler* handler, const char* args)
+ static bool CheckModifySpeed(ChatHandler* handler, const char* args, Unit* target, float& speed, float minimumBound, float maximumBound, bool checkInFlight = true)
{
if (!*args)
return false;
- float ASpeed = (float)atof((char*)args);
+ speed = (float)atof((char*)args);
- if (ASpeed > 50.0f || ASpeed < 0.1f)
+ if (speed > maximumBound || speed < minimumBound)
{
handler->SendSysMessage(LANG_BAD_VALUE);
handler->SetSentErrorMessage(true);
return false;
}
- Player* target = handler->getSelectedPlayerOrSelf();
if (!target)
{
handler->SendSysMessage(LANG_NO_CHAR_SELECTED);
@@ -460,238 +390,107 @@ public:
return false;
}
- // check online security
- if (handler->HasLowerSecurity(target, ObjectGuid::Empty))
- return false;
-
- std::string targetNameLink = handler->GetNameLink(target);
-
- if (target->IsInFlight())
+ if (Player* player = target->ToPlayer())
{
- handler->PSendSysMessage(LANG_CHAR_IN_FLIGHT, targetNameLink.c_str());
- handler->SetSentErrorMessage(true);
- return false;
- }
-
- handler->PSendSysMessage(LANG_YOU_CHANGE_ASPEED, targetNameLink.c_str(), ASpeed);
- if (handler->needReportToTarget(target))
- ChatHandler(target->GetSession()).PSendSysMessage(LANG_YOURS_ASPEED_CHANGED, handler->GetNameLink().c_str(), ASpeed);
+ // check online security
+ if (handler->HasLowerSecurity(player, ObjectGuid::Empty))
+ return false;
- target->SetSpeedRate(MOVE_WALK, ASpeed);
- target->SetSpeedRate(MOVE_RUN, ASpeed);
- target->SetSpeedRate(MOVE_SWIM, ASpeed);
- //target->SetSpeedRate(MOVE_TURN, ASpeed);
- target->SetSpeedRate(MOVE_FLIGHT, ASpeed);
+ if (player->IsInFlight() && checkInFlight)
+ {
+ handler->PSendSysMessage(LANG_CHAR_IN_FLIGHT, handler->GetNameLink(player).c_str());
+ handler->SetSentErrorMessage(true);
+ return false;
+ }
+ }
return true;
}
- //Edit Player Speed
- static bool HandleModifySpeedCommand(ChatHandler* handler, const char* args)
+ //Edit Player Aspeed
+ static bool HandleModifyASpeedCommand(ChatHandler* handler, const char* args)
{
- if (!*args)
- return false;
-
- float Speed = (float)atof((char*)args);
-
- if (Speed > 50.0f || Speed < 0.1f)
- {
- handler->SendSysMessage(LANG_BAD_VALUE);
- handler->SetSentErrorMessage(true);
- return false;
- }
-
+ float allSpeed;
Player* target = handler->getSelectedPlayerOrSelf();
- if (!target)
+ if (CheckModifySpeed(handler, args, target, allSpeed, 0.1f, 50.0f))
{
- handler->SendSysMessage(LANG_NO_CHAR_SELECTED);
- handler->SetSentErrorMessage(true);
- return false;
+ NotifyModification(handler, target, LANG_YOU_CHANGE_ASPEED, LANG_YOURS_ASPEED_CHANGED, allSpeed);
+ target->SetSpeedRate(MOVE_WALK, allSpeed);
+ target->SetSpeedRate(MOVE_RUN, allSpeed);
+ target->SetSpeedRate(MOVE_SWIM, allSpeed);
+ target->SetSpeedRate(MOVE_FLIGHT, allSpeed);
+ return true;
}
+ return false;
+ }
- // check online security
- if (handler->HasLowerSecurity(target, ObjectGuid::Empty))
- return false;
-
- std::string targetNameLink = handler->GetNameLink(target);
-
- if (target->IsInFlight())
+ //Edit Player Speed
+ static bool HandleModifySpeedCommand(ChatHandler* handler, const char* args)
+ {
+ float Speed;
+ Player* target = handler->getSelectedPlayerOrSelf();
+ if (CheckModifySpeed(handler, args, target, Speed, 0.1f, 50.0f))
{
- handler->PSendSysMessage(LANG_CHAR_IN_FLIGHT, targetNameLink.c_str());
- handler->SetSentErrorMessage(true);
- return false;
+ NotifyModification(handler, target, LANG_YOU_CHANGE_SPEED, LANG_YOURS_SPEED_CHANGED, Speed);
+ target->SetSpeedRate(MOVE_RUN, Speed);
+ return true;
}
-
- handler->PSendSysMessage(LANG_YOU_CHANGE_SPEED, targetNameLink.c_str(), Speed);
- if (handler->needReportToTarget(target))
- ChatHandler(target->GetSession()).PSendSysMessage(LANG_YOURS_SPEED_CHANGED, handler->GetNameLink().c_str(), Speed);
-
- target->SetSpeedRate(MOVE_RUN, Speed);
-
- return true;
+ return false;
}
//Edit Player Swim Speed
static bool HandleModifySwimCommand(ChatHandler* handler, const char* args)
{
- if (!*args)
- return false;
-
- float Swim = (float)atof((char*)args);
-
- if (Swim > 50.0f || Swim < 0.1f)
- {
- handler->SendSysMessage(LANG_BAD_VALUE);
- handler->SetSentErrorMessage(true);
- return false;
- }
-
+ float swimSpeed;
Player* target = handler->getSelectedPlayerOrSelf();
- if (!target)
+ if (CheckModifySpeed(handler, args, target, swimSpeed, 0.1f, 50.0f))
{
- handler->SendSysMessage(LANG_NO_CHAR_SELECTED);
- handler->SetSentErrorMessage(true);
- return false;
- }
-
- // check online security
- if (handler->HasLowerSecurity(target, ObjectGuid::Empty))
- return false;
-
- std::string targetNameLink = handler->GetNameLink(target);
-
- if (target->IsInFlight())
- {
- handler->PSendSysMessage(LANG_CHAR_IN_FLIGHT, targetNameLink.c_str());
- handler->SetSentErrorMessage(true);
- return false;
+ NotifyModification(handler, target, LANG_YOU_CHANGE_SWIM_SPEED, LANG_YOURS_SWIM_SPEED_CHANGED, swimSpeed);
+ target->SetSpeedRate(MOVE_SWIM, swimSpeed);
+ return true;
}
-
- handler->PSendSysMessage(LANG_YOU_CHANGE_SWIM_SPEED, targetNameLink.c_str(), Swim);
- if (handler->needReportToTarget(target))
- ChatHandler(target->GetSession()).PSendSysMessage(LANG_YOURS_SWIM_SPEED_CHANGED, handler->GetNameLink().c_str(), Swim);
-
- target->SetSpeedRate(MOVE_SWIM, Swim);
-
- return true;
+ return false;
}
- //Edit Player Walk Speed
+ //Edit Player Backwards Walk Speed
static bool HandleModifyBWalkCommand(ChatHandler* handler, const char* args)
{
- if (!*args)
- return false;
-
- float BSpeed = (float)atof((char*)args);
-
- if (BSpeed > 50.0f || BSpeed < 0.1f)
- {
- handler->SendSysMessage(LANG_BAD_VALUE);
- handler->SetSentErrorMessage(true);
- return false;
- }
-
+ float backSpeed;
Player* target = handler->getSelectedPlayerOrSelf();
- if (!target)
+ if (CheckModifySpeed(handler, args, target, backSpeed, 0.1f, 50.0f))
{
- handler->SendSysMessage(LANG_NO_CHAR_SELECTED);
- handler->SetSentErrorMessage(true);
- return false;
- }
-
- // check online security
- if (handler->HasLowerSecurity(target, ObjectGuid::Empty))
- return false;
-
- std::string targetNameLink = handler->GetNameLink(target);
-
- if (target->IsInFlight())
- {
- handler->PSendSysMessage(LANG_CHAR_IN_FLIGHT, targetNameLink.c_str());
- handler->SetSentErrorMessage(true);
- return false;
+ NotifyModification(handler, target, LANG_YOU_CHANGE_BACK_SPEED, LANG_YOURS_BACK_SPEED_CHANGED, backSpeed);
+ target->SetSpeedRate(MOVE_RUN_BACK, backSpeed);
+ return true;
}
-
- handler->PSendSysMessage(LANG_YOU_CHANGE_BACK_SPEED, targetNameLink.c_str(), BSpeed);
- if (handler->needReportToTarget(target))
- ChatHandler(target->GetSession()).PSendSysMessage(LANG_YOURS_BACK_SPEED_CHANGED, handler->GetNameLink().c_str(), BSpeed);
-
- target->SetSpeedRate(MOVE_RUN_BACK, BSpeed);
-
- return true;
+ return false;
}
//Edit Player Fly
static bool HandleModifyFlyCommand(ChatHandler* handler, const char* args)
{
- if (!*args)
- return false;
-
- float FSpeed = (float)atof((char*)args);
-
- if (FSpeed > 50.0f || FSpeed < 0.1f)
- {
- handler->SendSysMessage(LANG_BAD_VALUE);
- handler->SetSentErrorMessage(true);
- return false;
- }
-
+ float flySpeed;
Player* target = handler->getSelectedPlayerOrSelf();
- if (!target)
+ if (CheckModifySpeed(handler, args, target, flySpeed, 0.1f, 50.0f, false))
{
- handler->SendSysMessage(LANG_NO_CHAR_SELECTED);
- handler->SetSentErrorMessage(true);
- return false;
+ NotifyModification(handler, target, LANG_YOU_CHANGE_FLY_SPEED, LANG_YOURS_FLY_SPEED_CHANGED, flySpeed);
+ target->SetSpeedRate(MOVE_FLIGHT, flySpeed);
+ return true;
}
-
- // check online security
- if (handler->HasLowerSecurity(target, ObjectGuid::Empty))
- return false;
-
- handler->PSendSysMessage(LANG_YOU_CHANGE_FLY_SPEED, handler->GetNameLink(target).c_str(), FSpeed);
- if (handler->needReportToTarget(target))
- ChatHandler(target->GetSession()).PSendSysMessage(LANG_YOURS_FLY_SPEED_CHANGED, handler->GetNameLink().c_str(), FSpeed);
-
- target->SetSpeedRate(MOVE_FLIGHT, FSpeed);
-
- return true;
+ return false;
}
//Edit Player or Creature Scale
static bool HandleModifyScaleCommand(ChatHandler* handler, const char* args)
{
- if (!*args)
- return false;
-
- float Scale = (float)atof((char*)args);
- if (Scale > 10.0f || Scale < 0.1f)
- {
- handler->SendSysMessage(LANG_BAD_VALUE);
- handler->SetSentErrorMessage(true);
- return false;
- }
-
+ float Scale;
Unit* target = handler->getSelectedUnit();
- if (!target)
+ if (CheckModifySpeed(handler, args, target, Scale, 0.1f, 10.0f, false))
{
- handler->SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
- handler->SetSentErrorMessage(true);
- return false;
- }
-
- if (Player* player = target->ToPlayer())
- {
- // check online security
- if (handler->HasLowerSecurity(player, ObjectGuid::Empty))
- return false;
-
- handler->PSendSysMessage(LANG_YOU_CHANGE_SIZE, handler->GetNameLink(player).c_str(), Scale);
- if (handler->needReportToTarget(player))
- ChatHandler(player->GetSession()).PSendSysMessage(LANG_YOURS_SIZE_CHANGED, handler->GetNameLink().c_str(), Scale);
+ NotifyModification(handler, target, LANG_YOU_CHANGE_SIZE, LANG_YOURS_SIZE_CHANGED, Scale);
+ target->SetObjectScale(Scale);
+ return true;
}
-
- target->SetObjectScale(Scale);
-
- return true;
+ return false;
}
//Enable Player mount
@@ -932,9 +731,7 @@ public:
if (handler->HasLowerSecurity(target, ObjectGuid::Empty))
return false;
- handler->PSendSysMessage(LANG_YOU_GIVE_MOUNT, handler->GetNameLink(target).c_str());
- if (handler->needReportToTarget(target))
- ChatHandler(target->GetSession()).PSendSysMessage(LANG_MOUNT_GIVED, handler->GetNameLink().c_str());
+ NotifyModification(handler, target, LANG_YOU_GIVE_MOUNT, LANG_MOUNT_GIVED);
target->SetUInt32Value(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP);
target->Mount(mId);
@@ -988,10 +785,7 @@ public:
TC_LOG_DEBUG("misc", handler->GetTrinityString(LANG_CURRENT_MONEY), targetMoney, moneyToAdd, newmoney);
if (newmoney <= 0)
{
- handler->PSendSysMessage(LANG_YOU_TAKE_ALL_MONEY, handler->GetNameLink(target).c_str());
- if (handler->needReportToTarget(target))
- ChatHandler(target->GetSession()).PSendSysMessage(LANG_YOURS_ALL_MONEY_GONE, handler->GetNameLink().c_str());
-
+ NotifyModification(handler, target, LANG_YOU_TAKE_ALL_MONEY, LANG_YOURS_ALL_MONEY_GONE);
target->SetMoney(0);
}
else
diff --git a/src/server/scripts/Commands/cs_npc.cpp b/src/server/scripts/Commands/cs_npc.cpp
index fbd199b99db..438d05c5687 100644
--- a/src/server/scripts/Commands/cs_npc.cpp
+++ b/src/server/scripts/Commands/cs_npc.cpp
@@ -220,14 +220,15 @@ public:
{ "whisper", rbac::RBAC_PERM_COMMAND_NPC_WHISPER, false, &HandleNpcWhisperCommand, "" },
{ "yell", rbac::RBAC_PERM_COMMAND_NPC_YELL, false, &HandleNpcYellCommand, "" },
{ "tame", rbac::RBAC_PERM_COMMAND_NPC_TAME, false, &HandleNpcTameCommand, "" },
- { "add", rbac::RBAC_PERM_COMMAND_NPC_ADD, false, NULL, "", npcAddCommandTable },
- { "delete", rbac::RBAC_PERM_COMMAND_NPC_DELETE, false, NULL, "", npcDeleteCommandTable },
- { "follow", rbac::RBAC_PERM_COMMAND_NPC_FOLLOW, false, NULL, "", npcFollowCommandTable },
- { "set", rbac::RBAC_PERM_COMMAND_NPC_SET, false, NULL, "", npcSetCommandTable },
+ { "add", rbac::RBAC_PERM_COMMAND_NPC_ADD, false, nullptr, "", npcAddCommandTable },
+ { "delete", rbac::RBAC_PERM_COMMAND_NPC_DELETE, false, nullptr, "", npcDeleteCommandTable },
+ { "follow", rbac::RBAC_PERM_COMMAND_NPC_FOLLOW, false, nullptr, "", npcFollowCommandTable },
+ { "set", rbac::RBAC_PERM_COMMAND_NPC_SET, false, nullptr, "", npcSetCommandTable },
+ { "evade", rbac::RBAC_PERM_COMMAND_NPC_EVADE, false, &HandleNpcEvadeCommand, "" },
};
static std::vector<ChatCommand> commandTable =
{
- { "npc", rbac::RBAC_PERM_COMMAND_NPC, false, NULL, "", npcCommandTable },
+ { "npc", rbac::RBAC_PERM_COMMAND_NPC, false, nullptr, "", npcCommandTable },
};
return commandTable;
}
@@ -318,17 +319,17 @@ public:
uint32 itemId = item_int;
- char* fmaxcount = strtok(NULL, " "); //add maxcount, default: 0
+ char* fmaxcount = strtok(nullptr, " "); //add maxcount, default: 0
uint32 maxcount = 0;
if (fmaxcount)
maxcount = atoul(fmaxcount);
- char* fincrtime = strtok(NULL, " "); //add incrtime, default: 0
+ char* fincrtime = strtok(nullptr, " "); //add incrtime, default: 0
uint32 incrtime = 0;
if (fincrtime)
incrtime = atoul(fincrtime);
- char* fextendedcost = strtok(NULL, " "); //add ExtendedCost, default: 0
+ char* fextendedcost = strtok(nullptr, " "); //add ExtendedCost, default: 0
uint32 extendedcost = fextendedcost ? atoul(fextendedcost) : 0;
Creature* vendor = handler->getSelectedCreature();
if (!vendor)
@@ -361,7 +362,7 @@ public:
return false;
char* guidStr = strtok((char*)args, " ");
- char* waitStr = strtok((char*)NULL, " ");
+ char* waitStr = strtok((char*)nullptr, " ");
ObjectGuid::LowType lowGuid = atoi((char*)guidStr);
@@ -446,36 +447,24 @@ public:
}
Creature* creature = handler->getSelectedCreature();
- if (!creature)
+ if (!creature || creature->IsPet())
{
handler->SendSysMessage(LANG_SELECT_CREATURE);
handler->SetSentErrorMessage(true);
return false;
}
- if (creature->IsPet())
- {
- if (((Pet*)creature)->getPetType() == HUNTER_PET)
- {
- creature->SetUInt32Value(UNIT_FIELD_PETNEXTLEVELEXP, sObjectMgr->GetXPForLevel(lvl)/4);
- creature->SetUInt32Value(UNIT_FIELD_PETEXPERIENCE, 0);
- }
- ((Pet*)creature)->GivePetLevel(lvl);
- }
- else
- {
- creature->SetMaxHealth(100 + 30*lvl);
- creature->SetHealth(100 + 30*lvl);
- creature->SetLevel(lvl);
- creature->SaveToDB();
- }
+ creature->SetMaxHealth(100 + 30*lvl);
+ creature->SetHealth(100 + 30*lvl);
+ creature->SetLevel(lvl);
+ creature->SaveToDB();
return true;
}
static bool HandleNpcDeleteCommand(ChatHandler* handler, char const* args)
{
- Creature* unit = NULL;
+ Creature* unit = nullptr;
if (*args)
{
@@ -628,7 +617,7 @@ public:
return false;
char* arg1 = strtok((char*)args, " ");
- char* arg2 = strtok((char*)NULL, "");
+ char* arg2 = strtok((char*)nullptr, "");
if (!arg1 || !arg2)
return false;
@@ -926,8 +915,8 @@ public:
// later switched on/off according to special events (like escort
// quests, etc)
char* guid_str = strtok((char*)args, " ");
- char* type_str = strtok((char*)NULL, " ");
- char* dontdel_str = strtok((char*)NULL, " ");
+ char* type_str = strtok((char*)nullptr, " ");
+ char* dontdel_str = strtok((char*)nullptr, " ");
bool doNotDelete = false;
@@ -935,7 +924,7 @@ public:
return false;
ObjectGuid::LowType lowguid = 0;
- Creature* creature = NULL;
+ Creature* creature = nullptr;
if (dontdel_str)
{
@@ -961,7 +950,7 @@ public:
{
//TC_LOG_ERROR("misc", "DEBUG: type_str, NODEL ");
doNotDelete = true;
- type_str = NULL;
+ type_str = nullptr;
}
}
}
@@ -1001,7 +990,7 @@ public:
}
// now lowguid is low guid really existed creature
- // and creature point (maybe) to this creature or NULL
+ // and creature point (maybe) to this creature or nullptr
MovementGeneratorType move_type;
@@ -1260,7 +1249,7 @@ public:
}
char* receiver_str = strtok((char*)args, " ");
- char* text = strtok(NULL, "");
+ char* text = strtok(nullptr, "");
if (!receiver_str || !text)
{
@@ -1319,7 +1308,16 @@ public:
if (!*args)
return false;
- char* charID = handler->extractKeyFromLink((char*)args, "Hcreature_entry");
+ bool loot = false;
+ char const* spawntype_str = strtok((char*)args, " ");
+ char const* entry_str = strtok(nullptr, "");
+ if (stricmp(spawntype_str, "LOOT") == 0)
+ loot = true;
+ else if (stricmp(spawntype_str, "NOLOOT") == 0)
+ loot = false;
+ else
+ entry_str = args;
+ char* charID = handler->extractKeyFromLink((char*)entry_str, "Hcreature_entry");
if (!charID)
return false;
@@ -1332,7 +1330,7 @@ public:
if (!sObjectMgr->GetCreatureTemplate(id))
return false;
- chr->SummonCreature(id, *chr, TEMPSUMMON_CORPSE_DESPAWN, 120);
+ chr->SummonCreature(id, *chr, loot ? TEMPSUMMON_CORPSE_TIMED_DESPAWN : TEMPSUMMON_CORPSE_DESPAWN, 30 * IN_MILLISECONDS);
return true;
}
@@ -1404,6 +1402,51 @@ public:
return true;
}
+ static bool HandleNpcEvadeCommand(ChatHandler* handler, char const* args)
+ {
+ Creature* creatureTarget = handler->getSelectedCreature();
+ if (!creatureTarget || creatureTarget->IsPet())
+ {
+ handler->PSendSysMessage(LANG_SELECT_CREATURE);
+ handler->SetSentErrorMessage(true);
+ return false;
+ }
+
+ if (!creatureTarget->IsAIEnabled)
+ {
+ handler->PSendSysMessage(LANG_CREATURE_NOT_AI_ENABLED);
+ handler->SetSentErrorMessage(true);
+ return false;
+ }
+
+ char* type_str = args ? strtok((char*)args, " ") : nullptr;
+ char* force_str = args ? strtok(nullptr, " ") : nullptr;
+
+ CreatureAI::EvadeReason why = CreatureAI::EVADE_REASON_OTHER;
+ bool force = false;
+ if (type_str)
+ {
+ if (stricmp(type_str, "NO_HOSTILES") == 0 || stricmp(type_str, "EVADE_REASON_NO_HOSTILES") == 0)
+ why = CreatureAI::EVADE_REASON_NO_HOSTILES;
+ else if (stricmp(type_str, "BOUNDARY") == 0 || stricmp(type_str, "EVADE_REASON_BOUNDARY") == 0)
+ why = CreatureAI::EVADE_REASON_BOUNDARY;
+ else if (stricmp(type_str, "SEQUENCE_BREAK") == 0 || stricmp(type_str, "EVADE_REASON_SEQUENCE_BREAK") == 0)
+ why = CreatureAI::EVADE_REASON_SEQUENCE_BREAK;
+ else if (stricmp(type_str, "FORCE") == 0)
+ force = true;
+
+ if (!force && force_str)
+ if (stricmp(force_str, "FORCE") == 0)
+ force = true;
+ }
+
+ if (force)
+ creatureTarget->ClearUnitState(UNIT_STATE_EVADE);
+ creatureTarget->AI()->EnterEvadeMode(why);
+
+ return true;
+ }
+
static bool HandleNpcAddFormationCommand(ChatHandler* handler, char const* args)
{
if (!*args)
@@ -1515,7 +1558,7 @@ public:
if (!pSlotID)
return false;
- char* pItemID = strtok(NULL, " ");
+ char* pItemID = strtok(nullptr, " ");
if (!pItemID)
return false;
diff --git a/src/server/scripts/Commands/cs_pet.cpp b/src/server/scripts/Commands/cs_pet.cpp
index 4f0a179142d..787265cc19b 100644
--- a/src/server/scripts/Commands/cs_pet.cpp
+++ b/src/server/scripts/Commands/cs_pet.cpp
@@ -22,6 +22,19 @@
#include "ObjectMgr.h"
#include "ScriptMgr.h"
+static inline Pet* GetSelectedPlayerPetOrOwn(ChatHandler* handler)
+{
+ if (Unit* target = handler->getSelectedUnit())
+ {
+ if (target->GetTypeId() == TYPEID_PLAYER)
+ return target->ToPlayer()->GetPet();
+ if (target->IsPet())
+ return target->ToPet();
+ return nullptr;
+ }
+ Player* player = handler->GetSession()->GetPlayer();
+ return player ? player->GetPet() : nullptr;
+}
class pet_commandscript : public CommandScript
{
public:
@@ -34,6 +47,7 @@ public:
{ "create", rbac::RBAC_PERM_COMMAND_PET_CREATE, false, &HandlePetCreateCommand, "" },
{ "learn", rbac::RBAC_PERM_COMMAND_PET_LEARN, false, &HandlePetLearnCommand, "" },
{ "unlearn", rbac::RBAC_PERM_COMMAND_PET_UNLEARN, false, &HandlePetUnlearnCommand, "" },
+ { "level", rbac::RBAC_PERM_COMMAND_PET_LEVEL, false, &HandlePetLevelCommand, "" },
};
static std::vector<ChatCommand> commandTable =
@@ -54,9 +68,9 @@ public:
return false;
}
- CreatureTemplate const* creatrueTemplate = creatureTarget->GetCreatureTemplate();
+ CreatureTemplate const* creatureTemplate = creatureTarget->GetCreatureTemplate();
// Creatures with family 0 crashes the server
- if (!creatrueTemplate->family)
+ if (!creatureTemplate->family)
{
handler->PSendSysMessage("This creature cannot be tamed. (family id: 0).");
handler->SetSentErrorMessage(true);
@@ -119,12 +133,11 @@ public:
if (!*args)
return false;
- Player* player = handler->GetSession()->GetPlayer();
- Pet* pet = player->GetPet();
+ Pet* pet = GetSelectedPlayerPetOrOwn(handler);
if (!pet)
{
- handler->PSendSysMessage("You have no pet");
+ handler->SendSysMessage(LANG_SELECT_PLAYER_OR_PET);
handler->SetSentErrorMessage(true);
return false;
}
@@ -162,11 +175,10 @@ public:
if (!*args)
return false;
- Player* player = handler->GetSession()->GetPlayer();
- Pet* pet = player->GetPet();
+ Pet* pet = GetSelectedPlayerPetOrOwn(handler);
if (!pet)
{
- handler->PSendSysMessage("You have no pet");
+ handler->SendSysMessage(LANG_SELECT_PLAYER_OR_PET);
handler->SetSentErrorMessage(true);
return false;
}
@@ -180,6 +192,37 @@ public:
return true;
}
+
+ static bool HandlePetLevelCommand(ChatHandler* handler, char const* args)
+ {
+ Pet* pet = GetSelectedPlayerPetOrOwn(handler);
+ Player* owner = pet ? pet->GetOwner() : nullptr;
+ if (!pet || !owner)
+ {
+ handler->SendSysMessage(LANG_SELECT_PLAYER_OR_PET);
+ handler->SetSentErrorMessage(true);
+ return false;
+ }
+
+ int32 level = args ? atoi(args) : 0;
+ if (level == 0)
+ level = owner->getLevel() - pet->getLevel();
+ if (level == 0 || level < -STRONG_MAX_LEVEL || level > STRONG_MAX_LEVEL)
+ {
+ handler->SendSysMessage(LANG_BAD_VALUE);
+ handler->SetSentErrorMessage(true);
+ return false;
+ }
+
+ int32 newLevel = pet->getLevel() + level;
+ if (newLevel < 1)
+ newLevel = 1;
+ else if (newLevel > owner->getLevel())
+ newLevel = owner->getLevel();
+
+ pet->GivePetLevel(newLevel);
+ return true;
+ }
};
void AddSC_pet_commandscript()
diff --git a/src/server/scripts/Commands/cs_server.cpp b/src/server/scripts/Commands/cs_server.cpp
index 83bc2e47674..e0e52d4e1f5 100644
--- a/src/server/scripts/Commands/cs_server.cpp
+++ b/src/server/scripts/Commands/cs_server.cpp
@@ -29,6 +29,7 @@ EndScriptData */
#include "Player.h"
#include "ScriptMgr.h"
#include "GitRevision.h"
+#include "Util.h"
class server_commandscript : public CommandScript
{
@@ -52,12 +53,14 @@ public:
static std::vector<ChatCommand> serverRestartCommandTable =
{
{ "cancel", rbac::RBAC_PERM_COMMAND_SERVER_RESTART_CANCEL, true, &HandleServerShutDownCancelCommand, "" },
+ { "force", rbac::RBAC_PERM_COMMAND_SERVER_RESTART_FORCE, true, &HandleServerForceRestartCommand, "" },
{ "" , rbac::RBAC_PERM_COMMAND_SERVER_RESTART, true, &HandleServerRestartCommand, "" },
};
static std::vector<ChatCommand> serverShutdownCommandTable =
{
{ "cancel", rbac::RBAC_PERM_COMMAND_SERVER_SHUTDOWN_CANCEL, true, &HandleServerShutDownCancelCommand, "" },
+ { "force", rbac::RBAC_PERM_COMMAND_SERVER_SHUTDOWN_FORCE, true, &HandleServerForceShutDownCommand, "" },
{ "" , rbac::RBAC_PERM_COMMAND_SERVER_SHUTDOWN, true, &HandleServerShutDownCommand, "" },
};
@@ -73,19 +76,19 @@ public:
{
{ "corpses", rbac::RBAC_PERM_COMMAND_SERVER_CORPSES, true, &HandleServerCorpsesCommand, "" },
{ "exit", rbac::RBAC_PERM_COMMAND_SERVER_EXIT, true, &HandleServerExitCommand, "" },
- { "idlerestart", rbac::RBAC_PERM_COMMAND_SERVER_IDLERESTART, true, NULL, "", serverIdleRestartCommandTable },
- { "idleshutdown", rbac::RBAC_PERM_COMMAND_SERVER_IDLESHUTDOWN, true, NULL, "", serverIdleShutdownCommandTable },
+ { "idlerestart", rbac::RBAC_PERM_COMMAND_SERVER_IDLERESTART, true, nullptr, "", serverIdleRestartCommandTable },
+ { "idleshutdown", rbac::RBAC_PERM_COMMAND_SERVER_IDLESHUTDOWN, true, nullptr, "", serverIdleShutdownCommandTable },
{ "info", rbac::RBAC_PERM_COMMAND_SERVER_INFO, true, &HandleServerInfoCommand, "" },
{ "motd", rbac::RBAC_PERM_COMMAND_SERVER_MOTD, true, &HandleServerMotdCommand, "" },
{ "plimit", rbac::RBAC_PERM_COMMAND_SERVER_PLIMIT, true, &HandleServerPLimitCommand, "" },
- { "restart", rbac::RBAC_PERM_COMMAND_SERVER_RESTART, true, NULL, "", serverRestartCommandTable },
- { "shutdown", rbac::RBAC_PERM_COMMAND_SERVER_SHUTDOWN, true, NULL, "", serverShutdownCommandTable },
- { "set", rbac::RBAC_PERM_COMMAND_SERVER_SET, true, NULL, "", serverSetCommandTable },
+ { "restart", rbac::RBAC_PERM_COMMAND_SERVER_RESTART, true, nullptr, "", serverRestartCommandTable },
+ { "shutdown", rbac::RBAC_PERM_COMMAND_SERVER_SHUTDOWN, true, nullptr, "", serverShutdownCommandTable },
+ { "set", rbac::RBAC_PERM_COMMAND_SERVER_SET, true, nullptr, "", serverSetCommandTable },
};
static std::vector<ChatCommand> commandTable =
{
- { "server", rbac::RBAC_PERM_COMMAND_SERVER, true, NULL, "", serverCommandTable },
+ { "server", rbac::RBAC_PERM_COMMAND_SERVER, true, nullptr, "", serverCommandTable },
};
return commandTable;
}
@@ -192,19 +195,34 @@ public:
return true;
}
- static bool HandleServerShutDownCommand(ChatHandler* /*handler*/, char const* args)
+ static inline bool IsOnlyUser(WorldSession* mySession)
{
- return ShutdownServer(args, 0, SHUTDOWN_EXIT_CODE);
+ // check if there is any session connected from a different address
+ std::string myAddr = mySession ? mySession->GetRemoteAddress() : "";
+ SessionMap const& sessions = sWorld->GetAllSessions();
+ for (SessionMap::value_type const& session : sessions)
+ if (session.second && myAddr != session.second->GetRemoteAddress())
+ return false;
+ return true;
+ }
+ static bool HandleServerShutDownCommand(ChatHandler* handler, char const* args)
+ {
+ return ShutdownServer(args, IsOnlyUser(handler->GetSession()) ? SHUTDOWN_MASK_FORCE : 0, SHUTDOWN_EXIT_CODE);
}
- static bool HandleServerRestartCommand(ChatHandler* /*handler*/, char const* args)
+ static bool HandleServerRestartCommand(ChatHandler* handler, char const* args)
{
- return ShutdownServer(args, SHUTDOWN_MASK_RESTART, RESTART_EXIT_CODE);
+ return ShutdownServer(args, IsOnlyUser(handler->GetSession()) ? (SHUTDOWN_MASK_FORCE | SHUTDOWN_MASK_RESTART) : SHUTDOWN_MASK_RESTART, RESTART_EXIT_CODE);
}
- static bool HandleServerIdleRestartCommand(ChatHandler* /*handler*/, char const* args)
+ static bool HandleServerForceShutDownCommand(ChatHandler* /*handler*/, char const* args)
{
- return ShutdownServer(args, SHUTDOWN_MASK_RESTART | SHUTDOWN_MASK_IDLE, RESTART_EXIT_CODE);
+ return ShutdownServer(args, SHUTDOWN_MASK_FORCE, SHUTDOWN_EXIT_CODE);
+ }
+
+ static bool HandleServerForceRestartCommand(ChatHandler* /*handler*/, char const* args)
+ {
+ return ShutdownServer(args, SHUTDOWN_MASK_FORCE | SHUTDOWN_MASK_RESTART, RESTART_EXIT_CODE);
}
static bool HandleServerIdleShutDownCommand(ChatHandler* /*handler*/, char const* args)
@@ -212,6 +230,11 @@ public:
return ShutdownServer(args, SHUTDOWN_MASK_IDLE, SHUTDOWN_EXIT_CODE);
}
+ static bool HandleServerIdleRestartCommand(ChatHandler* /*handler*/, char const* args)
+ {
+ return ShutdownServer(args, SHUTDOWN_MASK_RESTART | SHUTDOWN_MASK_IDLE, RESTART_EXIT_CODE);
+ }
+
// Exit the realm
static bool HandleServerExitCommand(ChatHandler* handler, char const* /*args*/)
{
@@ -256,8 +279,8 @@ public:
return false;
char* type = strtok((char*)args, " ");
- char* name = strtok(NULL, " ");
- char* level = strtok(NULL, " ");
+ char* name = strtok(nullptr, " ");
+ char* level = strtok(nullptr, " ");
if (!type || !name || !level || *name == '\0' || *level == '\0' || (*type != 'a' && *type != 'l'))
return false;
@@ -313,10 +336,26 @@ private:
return false;
// #delay [#exit_code] [reason]
+ int32 delay = 0;
char* delayStr = strtok((char*)args, " ");
- if (!delayStr || !isNumeric(delayStr))
+ if (!delayStr)
return false;
+ if (isNumeric(delayStr))
+ {
+ delay = atoi(delayStr);
+ // Prevent interpret wrong arg value as 0 secs shutdown time
+ if ((delay == 0 && (delayStr[0] != '0' || delayStr[1] != '\0')) || delay < 0)
+ return false;
+ }
+ else
+ {
+ delay = TimeStringToSecs(std::string(delayStr));
+
+ if (delay == 0)
+ return false;
+ }
+
char* exitCodeStr = nullptr;
char reason[256] = { 0 };
@@ -337,17 +376,14 @@ private:
}
}
- int32 delay = atoi(delayStr);
-
- // Prevent interpret wrong arg value as 0 secs shutdown time
- if ((delay == 0 && (delayStr[0] != '0' || delayStr[1] != '\0')) || delay < 0)
- return false;
-
int32 exitCode = defaultExitCode;
if (exitCodeStr)
if (!ParseExitCode(exitCodeStr, exitCode))
return false;
+ if (delay < (int32)sWorld->getIntConfig(CONFIG_FORCE_SHUTDOWN_THRESHOLD) && !(shutdownMask & SHUTDOWN_MASK_FORCE))
+ return false;
+
sWorld->ShutdownServ(delay, shutdownMask, static_cast<uint8>(exitCode), std::string(reason));
return true;
diff --git a/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_headless_horseman.cpp b/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_headless_horseman.cpp
index f7a1c18c234..734b70933aa 100644
--- a/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_headless_horseman.cpp
+++ b/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_headless_horseman.cpp
@@ -894,12 +894,12 @@ public:
if (instance->GetBossState(DATA_HORSEMAN_EVENT) == IN_PROGRESS)
return false;
- player->AreaExploredOrEventHappens(11405);
- if (Creature* horseman = go->SummonCreature(HH_MOUNTED, FlightPoint[20].x, FlightPoint[20].y, FlightPoint[20].z, 0, TEMPSUMMON_MANUAL_DESPAWN, 0))
- {
- ENSURE_AI(boss_headless_horseman::boss_headless_horsemanAI, horseman->AI())->PlayerGUID = player->GetGUID();
- ENSURE_AI(boss_headless_horseman::boss_headless_horsemanAI, horseman->AI())->FlyMode();
- }
+ player->AreaExploredOrEventHappens(11405);
+ if (Creature* horseman = go->SummonCreature(HH_MOUNTED, FlightPoint[20].x, FlightPoint[20].y, FlightPoint[20].z, 0, TEMPSUMMON_MANUAL_DESPAWN, 0))
+ {
+ ENSURE_AI(boss_headless_horseman::boss_headless_horsemanAI, horseman->AI())->PlayerGUID = player->GetGUID();
+ ENSURE_AI(boss_headless_horseman::boss_headless_horsemanAI, horseman->AI())->FlyMode();
+ }
return true;
}
};
diff --git a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kiljaeden.cpp b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kiljaeden.cpp
index d86b3707606..7563a880f0a 100644
--- a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kiljaeden.cpp
+++ b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kiljaeden.cpp
@@ -143,11 +143,7 @@ enum Spells
SPELL_RING_OF_BLUE_FLAMES = 45825 //Cast this spell when the go is activated
};
-/*** Error messages ***/
-#define ERROR_KJ_NOT_SUMMONED "TSCR ERROR: Unable to summon Kil'Jaeden for some reason"
-
/*** Others ***/
-#define FLOOR_Z 28.050388f
#define SHIELD_ORB_Z 45.000f
enum Phase
diff --git a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_muru.cpp b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_muru.cpp
index 04d23cd7d4e..6c84677708e 100644
--- a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_muru.cpp
+++ b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_muru.cpp
@@ -15,88 +15,119 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-/* ScriptData
-SDName: Boss_Muru
-SD%Complete: 80
-SDComment: all sounds, black hole effect triggers to often (46228)
-*/
-
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "sunwell_plateau.h"
-#include "Player.h"
-#include "SpellInfo.h"
+#include "SpellScript.h"
+#include "SpellAuraEffects.h"
-// Muru & Entropius's spells
enum Spells
{
- SPELL_ENRAGE = 26662,
-
// Muru's spells
- SPELL_NEGATIVE_ENERGY = 46009, //(this trigger 46008)
- SPELL_DARKNESS = 45999,
- SPELL_OPEN_ALL_PORTALS = 46177,
- SPELL_OPEN_PORTAL = 45977,
- SPELL_OPEN_PORTAL_2 = 45976,
- SPELL_SUMMON_BERSERKER = 46037,
- SPELL_SUMNON_FURY_MAGE = 46038,
- SPELL_SUMMON_VOID_SENTINEL = 45988,
- SPELL_SUMMON_ENTROPIUS = 46217,
+ SPELL_OPEN_PORTAL_PERIODIC = 45994,
+ SPELL_DARKNESS_PERIODIC = 45998,
+ SPELL_NEGATIVE_ENERGY_PERIODIC = 46009,
+ SPELL_SUMMON_VOID_SPAWN = 46071,
+ SPELL_SUMMON_BLOOD_ELVES_SCRIPT = 46050,
+ SPELL_SUMMON_BLOOD_ELVES_PERIODIC = 46041,
+ SPELL_OPEN_ALL_PORTALS = 46177,
+ SPELL_SUMMON_ENTROPIUS = 46217,
+ SPELL_ENRAGE = 26662,
+ SPELL_SUMMON_DARK_FIEND_0 = 46000,
+ SPELL_SUMMON_DARK_FIEND_1 = 46001,
+ SPELL_SUMMON_DARK_FIEND_2 = 46002,
+ SPELL_SUMMON_DARK_FIEND_3 = 46003,
+ SPELL_SUMMON_DARK_FIEND_4 = 46004,
+ SPELL_SUMMON_DARK_FIEND_5 = 46005,
+ SPELL_SUMMON_DARK_FIEND_6 = 46006,
+ SPELL_SUMMON_DARK_FIEND_7 = 46007,
+ SPELL_SUMMON_BERSERKER = 46037,
+ SPELL_SUMMON_BERSERKER_2 = 46040,
+ SPELL_SUMMON_FURY_MAGE = 46038,
+ SPELL_SUMMON_FURY_MAGE_2 = 46039,
// Entropius's spells
- SPELL_DARKNESS_E = 46269,
- SPELL_BLACKHOLE = 46282,
- SPELL_NEGATIVE_ENERGY_E = 46284,
- SPELL_ENTROPIUS_SPAWN = 46223,
-
- // Shadowsword Berserker's spells
- SPELL_FLURRY = 46160,
- SPELL_DUAL_WIELD = 29651,
+ SPELL_ENTROPIUS_COSMETIC_SPAWN = 46223,
+ SPELL_DARKNESS_E = 46269,
+ SPELL_NEGATIVE_ENERGY_PERIODIC_E = 46284,
+ SPELL_BLACKHOLE = 46282,
+ SPELL_SUMMON_DARKFIEND_E = 46263,
+
+ // Myruu's Portal Target
+ SPELL_SUMMON_VOID_SENTINEL_SUMMONER = 45978,
+ SPELL_SUMMON_VOID_SENTINEL_SUMMONER_VISUAL = 45989,
+ SPELL_SUMMON_VOID_SENTINEL = 45988,
+ SPELL_TRANSFORM_VISUAL_MISSILE = 46205,
+ TRANSFORM_VISUAL_MISSILE_1 = 46208,
+ TRANSFORM_VISUAL_MISSILE_2 = 46178,
+ SPELL_OPEN_PORTAL = 45977,
+ SPELL_OPEN_PORTAL_2 = 45976,
- // Shadowsword Fury Mage's spells
- SPELL_FEL_FIREBALL = 46101,
- SPELL_SPELL_FURY = 46102,
+ //Dark Fiend Spells
+ SPELL_DARKFIEND_DAMAGE = 45944,
+ SPELL_DARKFIEND_VISUAL = 45936,
+ SPELL_DARKFIEND_SKIN = 45934,
// Void Sentinel's spells
- SPELL_SHADOW_PULSE = 46087,
- SPELL_VOID_BLAST = 46161,
+ SPELL_SHADOW_PULSE_PERIODIC = 46086,
+ SPELL_VOID_BLAST = 46161,
- // Void Spawn's spells
- SPELL_SHADOW_BOLT_VOLLEY = 46082,
+ //Black Hole Spells
+ SPELL_BLACKHOLE_SUMMON_VISUAL = 46242,
+ SPELL_BLACKHOLE_SUMMON_VISUAL_2 = 46247,
+ SPELL_BLACKHOLE_PASSIVE = 46228,
+ SPELL_BLACK_HOLE_VISUAL_2 = 46235
+};
- //Dark Fiend Spells
- SPELL_DARKFIEND_AOE = 45944,
- SPELL_DARKFIEND_VISUAL = 45936,
- SPELL_DARKFIEND_SKIN = 45934,
+enum Phases
+{
+ PHASE_ONE = 1,
+ PHASE_TWO = 2
+};
- //Black Hole Spells
- SPELL_BLACKHOLE_SPAWN = 46242,
- SPELL_BLACKHOLE_GROW = 46228
+enum Misc
+{
+ MAX_VOID_SPAWNS = 6,
+ MAX_SUMMON_BLOOD_ELVES = 4,
+ MAX_SUMMON_DARK_FIEND = 8
};
-enum Events
+uint32 const SummonDarkFiendSpells[MAX_SUMMON_DARK_FIEND] =
{
- // M'uru
- EVENT_DARKNESS = 1,
- EVENT_SUMMON_HUMANOIDS,
- EVENT_SUMMON_SENTINEL,
- EVENT_PHASE_TRANSITION, // Delayed phase transition.
- EVENT_ENRAGE,
-
- // Entropius
- EVENT_SUMMON_BLACK_HOLE
+ SPELL_SUMMON_DARK_FIEND_0,
+ SPELL_SUMMON_DARK_FIEND_1,
+ SPELL_SUMMON_DARK_FIEND_2,
+ SPELL_SUMMON_DARK_FIEND_3,
+ SPELL_SUMMON_DARK_FIEND_4,
+ SPELL_SUMMON_DARK_FIEND_5,
+ SPELL_SUMMON_DARK_FIEND_6,
+ SPELL_SUMMON_DARK_FIEND_7
};
-enum Phases
+uint32 const SummonBloodElvesSpells[MAX_SUMMON_BLOOD_ELVES] =
{
- PHASE_ONE = 1,
- PHASE_TWO,
+ SPELL_SUMMON_BERSERKER,
+ SPELL_SUMMON_BERSERKER_2,
+ SPELL_SUMMON_FURY_MAGE,
+ SPELL_SUMMON_FURY_MAGE_2
};
-enum CreatureGroups
+class VoidSpawnSummon : public BasicEvent
{
- CREATURE_GROUP_HUMANOIDS,
- CREATURE_GROUP_DARKFIENDS
+ public:
+ explicit VoidSpawnSummon(Creature* owner)
+ : _owner(owner)
+ {
+ }
+
+ bool Execute(uint64 /*time*/, uint32 /*diff*/)
+ {
+ _owner->CastSpell((Unit*)nullptr, SPELL_SUMMON_VOID_SENTINEL, true);
+ return true;
+ }
+
+ private:
+ Creature* _owner;
};
class boss_entropius : public CreatureScript
@@ -110,53 +141,78 @@ public:
void Reset() override
{
- DoCastAOE(SPELL_NEGATIVE_ENERGY_E);
+ _Reset();
+ DoCast(me, SPELL_ENTROPIUS_COSMETIC_SPAWN, true);
}
- void EnterCombat(Unit* /*who*/) override
+ void ScheduleTasks() override
{
- _EnterCombat();
- DoCastAOE(SPELL_NEGATIVE_ENERGY_E, true);
- DoCast(me, SPELL_ENTROPIUS_SPAWN);
- events.ScheduleEvent(EVENT_SUMMON_BLACK_HOLE, 15000);
+ scheduler.Schedule(Milliseconds(2000), [this](TaskContext /*context*/)
+ {
+ DoResetPortals();
+ DoCastAOE(SPELL_NEGATIVE_ENERGY_PERIODIC_E, true);
+ });
+
+ scheduler.Schedule(Seconds(15), [this](TaskContext context)
+ {
+ DoCastAOE(SPELL_DARKNESS_E, true);
+ DoCastAOE(SPELL_BLACKHOLE, true);
+
+ context.Repeat();
+ });
}
- void JustSummoned(Creature* summoned) override
+ void JustSummoned(Creature* summon) override
{
- switch (summoned->GetEntry())
+ switch (summon->GetEntry())
{
case NPC_DARK_FIENDS:
- summoned->CastSpell(summoned, SPELL_DARKFIEND_VISUAL);
+ summon->CastSpell(summon, SPELL_DARKFIEND_VISUAL);
break;
case NPC_DARKNESS:
- summoned->AddUnitState(UNIT_STATE_STUNNED);
- float x, y, z, o;
- summoned->GetHomePosition(x, y, z, o);
- me->SummonCreature(NPC_DARK_FIENDS, x, y, z, o, TEMPSUMMON_CORPSE_DESPAWN, 0);
+ summon->SetReactState(REACT_PASSIVE);
+ summon->CastSpell(summon, SPELL_BLACKHOLE);
+ summon->CastSpell(summon, SPELL_SUMMON_DARKFIEND_E, true);
break;
}
- summoned->AI()->AttackStart(SelectTarget(SELECT_TARGET_RANDOM, 0, 50, true));
- summons.Summon(summoned);
+ summons.Summon(summon);
}
- void ExecuteEvent(uint32 eventId) override
+ void EnterEvadeMode(EvadeReason /*why*/) override
{
- if (eventId == EVENT_SUMMON_BLACK_HOLE)
- {
- if (Unit* random = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
- DoCast(random, SPELL_DARKNESS_E);
- if (Unit* random = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
- random->CastSpell(random, SPELL_BLACKHOLE);
- events.ScheduleEvent(EVENT_SUMMON_BLACK_HOLE, 15000);
- }
+ if (Creature* muru = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_MURU)))
+ muru->AI()->EnterEvadeMode();
+
+ DoResetPortals();
+ summons.DespawnAll();
+ me->DespawnOrUnsummon();
}
- void EnterEvadeMode(EvadeReason /*why*/) override
+ void JustDied(Unit* /*killer*/) override
{
+ _JustDied();
+
if (Creature* muru = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_MURU)))
- muru->AI()->Reset(); // Reset encounter.
- me->DisappearAndDie();
- summons.DespawnAll();
+ muru->DisappearAndDie();
+ }
+
+ void UpdateAI(uint32 diff) override
+ {
+ if (!UpdateVictim())
+ return;
+
+ scheduler.Update(diff, [this]
+ {
+ DoMeleeAttackIfReady();
+ });
+ }
+
+ void DoResetPortals()
+ {
+ std::list<Creature*> portals;
+ me->GetCreatureListWithEntryInGrid(portals, NPC_MURU_PORTAL_TARGET, 100.0f);
+ for (Creature* portal : portals)
+ portal->RemoveAllAuras();
}
};
@@ -181,101 +237,96 @@ public:
void Initialize()
{
- DarkFiend = false;
- HasEnraged = false;
- EntropiusGUID.Clear();
+ _hasEnraged = false;
+ _phase = PHASE_ONE;
+ _entropiusGUID.Clear();
}
void Reset() override
{
- Initialize();
_Reset();
+ Initialize();
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
me->SetVisible(true);
}
+ void EnterEvadeMode(EvadeReason /*why*/) override
+ {
+ BossAI::EnterEvadeMode();
+ if (Creature* entropius = ObjectAccessor::GetCreature(*me, _entropiusGUID))
+ entropius->AI()->EnterEvadeMode();
+ }
+
+ void ScheduleTasks() override
+ {
+ scheduler.Schedule(Minutes(10), [this](TaskContext /*context*/)
+ {
+ if (Creature* entropius = ObjectAccessor::GetCreature(*me, _entropiusGUID))
+ entropius->CastSpell(entropius, SPELL_ENRAGE);
+ DoCast(me, SPELL_ENRAGE);
+ _hasEnraged = true;
+ });
+
+ scheduler.Schedule(Seconds(10), [this](TaskContext /*context*/)
+ {
+ DoCast(me, SPELL_SUMMON_BLOOD_ELVES_SCRIPT, true);
+ DoCast(me, SPELL_SUMMON_BLOOD_ELVES_PERIODIC, true);
+ });
+ }
+
void EnterCombat(Unit* /*who*/) override
{
_EnterCombat();
- events.SetPhase(PHASE_ONE);
- events.ScheduleEvent(EVENT_ENRAGE, 600000);
- events.ScheduleEvent(EVENT_DARKNESS, 45000, 0, PHASE_ONE);
- events.ScheduleEvent(EVENT_SUMMON_HUMANOIDS, 10000, 0, PHASE_ONE);
- events.ScheduleEvent(EVENT_SUMMON_SENTINEL, 31500, 0, PHASE_ONE);
- DoCastAOE(SPELL_NEGATIVE_ENERGY);
+ DoCast(me, SPELL_OPEN_PORTAL_PERIODIC, true);
+ DoCast(me, SPELL_DARKNESS_PERIODIC, true);
+ DoCast(me, SPELL_NEGATIVE_ENERGY_PERIODIC, true);
}
void DamageTaken(Unit* /*done_by*/, uint32 &damage) override
{
- if (damage >= me->GetHealth() && events.IsInPhase(PHASE_ONE))
+ if (damage >= me->GetHealth())
{
- damage = 0;
+ damage = me->GetHealth() - 1;
+ if (_phase != PHASE_ONE)
+ return;
+
+ _phase = PHASE_TWO;
me->RemoveAllAuras();
- DoCast(me, SPELL_OPEN_ALL_PORTALS);
+ DoCast(me, SPELL_OPEN_ALL_PORTALS, true);
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
- events.SetPhase(PHASE_TWO);
- events.ScheduleEvent(EVENT_PHASE_TRANSITION, 2000);
+
+ scheduler.Schedule(Seconds(6), [this](TaskContext /*context*/)
+ {
+ DoCast(me, SPELL_SUMMON_ENTROPIUS, true);
+ });
}
}
- void JustSummoned(Creature* summoned) override
+ void JustSummoned(Creature* summon) override
{
- switch (summoned->GetEntry())
+ if (summon->GetEntry() == NPC_ENTROPIUS)
{
- case NPC_ENTROPIUS:
- me->SetVisible(false);
- EntropiusGUID = summoned->GetGUID();
- if (HasEnraged) // If we hit phase transition while enraged, enrage Entropius as well.
- summoned->CastSpell(summoned, SPELL_ENRAGE);
- break;
- case NPC_DARK_FIENDS:
- summoned->CastSpell(summoned, SPELL_DARKFIEND_VISUAL);
- break;
+ me->SetVisible(false);
+ _entropiusGUID = summon->GetGUID();
+ if (_hasEnraged)
+ summon->CastSpell(summon, SPELL_ENRAGE, true);
+ return;
}
- summoned->AI()->AttackStart(SelectTarget(SELECT_TARGET_RANDOM, 0, 50, true));
- summons.Summon(summoned);
+ BossAI::JustSummoned(summon);
}
- void ExecuteEvent(uint32 eventId) override
+ void UpdateAI(uint32 diff) override
{
- switch (eventId)
- {
- case EVENT_DARKNESS:
- if (!DarkFiend)
- {
- DarkFiend = true;
- DoCastAOE(SPELL_DARKNESS);
- }
- else
- me->SummonCreatureGroup(CREATURE_GROUP_DARKFIENDS);
- events.ScheduleEvent(EVENT_DARKNESS, DarkFiend ? 3000 : 42000, 0, PHASE_ONE);
- break;
- case EVENT_SUMMON_HUMANOIDS:
- me->SummonCreatureGroup(CREATURE_GROUP_HUMANOIDS);
- events.ScheduleEvent(EVENT_SUMMON_HUMANOIDS, 60000, 0, PHASE_ONE);
- break;
- case EVENT_SUMMON_SENTINEL:
- DoCastAOE(SPELL_OPEN_PORTAL_2);
- events.ScheduleEvent(EVENT_SUMMON_SENTINEL, 30000, 0, PHASE_ONE);
- break;
- case EVENT_PHASE_TRANSITION:
- DoCast(me, SPELL_SUMMON_ENTROPIUS);
- break;
- case EVENT_ENRAGE:
- if (Creature* entropius = ObjectAccessor::GetCreature(*me, EntropiusGUID))
- entropius->CastSpell(entropius, SPELL_ENRAGE);
- DoCast(me, SPELL_ENRAGE);
- HasEnraged = true;
- break;
- default:
- break;
- }
+ if (!UpdateVictim())
+ return;
+
+ scheduler.Update(diff);
}
private:
- bool DarkFiend;
- bool HasEnraged;
- ObjectGuid EntropiusGUID;
+ ObjectGuid _entropiusGUID;
+ bool _hasEnraged;
+ uint8 _phase;
};
CreatureAI* GetAI(Creature* creature) const override
@@ -289,89 +340,50 @@ class npc_muru_portal : public CreatureScript
public:
npc_muru_portal() : CreatureScript("npc_muru_portal") { }
- CreatureAI* GetAI(Creature* creature) const override
- {
- return GetInstanceAI<npc_muru_portalAI>(creature);
- }
-
struct npc_muru_portalAI : public ScriptedAI
{
- npc_muru_portalAI(Creature* creature) : ScriptedAI(creature), Summons(creature)
- {
- Initialize();
- SetCombatMovement(false);
- instance = creature->GetInstanceScript();
- }
-
- void Initialize()
- {
- SummonTimer = 5000;
-
- InAction = false;
- SummonSentinel = false;
- }
-
- InstanceScript* instance;
-
- SummonList Summons;
-
- bool SummonSentinel;
- bool InAction;
-
- uint32 SummonTimer;
-
- void Reset() override
- {
- Initialize();
+ npc_muru_portalAI(Creature* creature) : ScriptedAI(creature) { }
- me->AddUnitState(UNIT_STATE_STUNNED);
-
- Summons.DespawnAll();
- }
-
- void JustSummoned(Creature* summoned) override
+ void JustSummoned(Creature* summon) override
{
- if (Player* target = ObjectAccessor::GetPlayer(*me, instance->GetGuidData(DATA_PLAYER_GUID)))
- summoned->AI()->AttackStart(target);
+ DoCast(summon, SPELL_SUMMON_VOID_SENTINEL_SUMMONER_VISUAL, true);
- Summons.Summon(summoned);
+ summon->m_Events.AddEvent(new VoidSpawnSummon(summon), summon->m_Events.CalculateTime(1500));
}
- void SpellHit(Unit* /*caster*/, const SpellInfo* Spell) override
+ void SpellHit(Unit* /*caster*/, SpellInfo const* spell) override
{
- float x, y, z, o;
- me->GetHomePosition(x, y, z, o);
- me->NearTeleportTo(x, y, z, o);
- InAction = true;
- switch (Spell->Id)
+ switch (spell->Id)
{
case SPELL_OPEN_ALL_PORTALS:
- DoCastAOE(SPELL_OPEN_PORTAL);
+ DoCastAOE(SPELL_OPEN_PORTAL, true);
+ DoCastAOE(SPELL_TRANSFORM_VISUAL_MISSILE, true);
break;
case SPELL_OPEN_PORTAL_2:
- DoCastAOE(SPELL_OPEN_PORTAL);
- SummonSentinel = true;
+ DoCastAOE(SPELL_OPEN_PORTAL, true);
+ _scheduler.Schedule(Seconds(6), [this](TaskContext /*context*/)
+ {
+ DoCastAOE(SPELL_SUMMON_VOID_SENTINEL_SUMMONER, true);
+ });
+ break;
+ default:
break;
}
}
void UpdateAI(uint32 diff) override
{
- if (!SummonSentinel)
- {
- if (InAction && instance->GetBossState(DATA_MURU) == NOT_STARTED)
- Reset();
- return;
- }
-
- if (SummonTimer <= diff)
- {
- DoCastAOE(SPELL_SUMMON_VOID_SENTINEL, false);
- SummonTimer = 5000;
- SummonSentinel = false;
- } else SummonTimer -= diff;
+ _scheduler.Update(diff);
}
+
+ private:
+ TaskScheduler _scheduler;
};
+
+ CreatureAI* GetAI(Creature* creature) const override
+ {
+ return GetSunwellPlateauAI<npc_muru_portalAI>(creature);
+ }
};
class npc_dark_fiend : public CreatureScript
@@ -379,11 +391,6 @@ class npc_dark_fiend : public CreatureScript
public:
npc_dark_fiend() : CreatureScript("npc_dark_fiend") { }
- CreatureAI* GetAI(Creature* creature) const override
- {
- return new npc_dark_fiendAI(creature);
- }
-
struct npc_dark_fiendAI : public ScriptedAI
{
npc_dark_fiendAI(Creature* creature) : ScriptedAI(creature)
@@ -393,54 +400,56 @@ public:
void Initialize()
{
- WaitTimer = 2000;
- InAction = false;
- }
+ me->SetDisplayId(me->GetCreatureTemplate()->Modelid2);
+ me->SetReactState(REACT_PASSIVE);
+ DoCast(me, SPELL_DARKFIEND_SKIN, true);
- uint32 WaitTimer;
- bool InAction;
+ _scheduler.Schedule(Seconds(2), [this](TaskContext /*context*/)
+ {
+ me->SetReactState(REACT_AGGRESSIVE);
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
- void Reset() override
- {
- Initialize();
+ if (Creature* _summoner = ObjectAccessor::GetCreature(*me, _summonerGUID))
+ if (Unit* target = _summoner->AI()->SelectTarget(SELECT_TARGET_RANDOM, 0))
+ AttackStart(target);
+ });
- me->AddUnitState(UNIT_STATE_STUNNED);
+ _scheduler.Schedule(Seconds(3), [this](TaskContext context)
+ {
+ if (me->IsWithinDist(me->GetVictim(), 5.0f) && me->HasAura(SPELL_DARKFIEND_SKIN))
+ {
+ DoCastAOE(SPELL_DARKFIEND_DAMAGE, false);
+ me->DisappearAndDie();
+ }
+
+ context.Repeat(Milliseconds(500));
+ });
}
- void SpellHit(Unit* /*caster*/, const SpellInfo* Spell) override
+ void IsSummonedBy(Unit* summoner) override
{
- for (uint8 i = 0; i < 3; ++i)
- if (Spell->Effects[i].Effect == 38)
- me->DisappearAndDie();
+ _summonerGUID = summoner->GetGUID();
}
- void UpdateAI(uint32 diff) override
+ bool CanAIAttack(Unit const* /*target*/) const override
{
- if (!UpdateVictim())
- return;
+ return me->HasAura(SPELL_DARKFIEND_SKIN);
+ }
- if (WaitTimer <= diff)
- {
- if (!InAction)
- {
- me->ClearUnitState(UNIT_STATE_STUNNED);
- DoCastAOE(SPELL_DARKFIEND_SKIN, false);
- AttackStart(SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true));
- InAction = true;
- WaitTimer = 500;
- }
- else
- {
- if (me->IsWithinDist(me->GetVictim(), 5))
- {
- DoCastAOE(SPELL_DARKFIEND_AOE, false);
- me->DisappearAndDie();
- }
- WaitTimer = 500;
- }
- } else WaitTimer -= diff;
+ void UpdateAI(uint32 diff) override
+ {
+ _scheduler.Update(diff);
}
+
+ private:
+ TaskScheduler _scheduler;
+ ObjectGuid _summonerGUID;
};
+
+ CreatureAI* GetAI(Creature* creature) const override
+ {
+ return GetSunwellPlateauAI<npc_dark_fiendAI>(creature);
+ }
};
class npc_void_sentinel : public CreatureScript
@@ -448,63 +457,54 @@ class npc_void_sentinel : public CreatureScript
public:
npc_void_sentinel() : CreatureScript("npc_void_sentinel") { }
- CreatureAI* GetAI(Creature* creature) const override
- {
- return new npc_void_sentinelAI(creature);
- }
-
struct npc_void_sentinelAI : public ScriptedAI
{
npc_void_sentinelAI(Creature* creature) : ScriptedAI(creature)
{
- Initialize();
+ _instance = me->GetInstanceScript();
}
- void Initialize()
+ void IsSummonedBy(Unit* /*summoner*/) override
{
- PulseTimer = 3000;
- VoidBlastTimer = 45000; //is this a correct timer?
+ if (Creature* muru = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_MURU)))
+ muru->AI()->JustSummoned(me);
}
- uint32 PulseTimer;
- uint32 VoidBlastTimer;
-
- void Reset() override
+ void EnterCombat(Unit* /*who*/) override
{
- Initialize();
+ DoCast(me, SPELL_SHADOW_PULSE_PERIODIC, true);
- float x, y, z, o;
- me->GetHomePosition(x, y, z, o);
- me->NearTeleportTo(x, y, 71, o);
+ _scheduler.Schedule(Seconds(45), [this](TaskContext context)
+ {
+ DoCastVictim(SPELL_VOID_BLAST, false);
+
+ context.Repeat();
+ });
}
- void JustDied(Unit* killer) override
+ void JustDied(Unit* /*killer*/) override
{
- for (uint8 i = 0; i < 8; ++i)
- if (Creature* temp = me->SummonCreature(NPC_VOID_SPAWN, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), float(rand32() % 6), TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 180000))
- temp->AI()->AttackStart(killer);
+ for (uint8 i = 0; i < MAX_VOID_SPAWNS; ++i)
+ DoCastAOE(SPELL_SUMMON_VOID_SPAWN, true);
}
void UpdateAI(uint32 diff) override
{
- if (!UpdateVictim())
- return;
-
- if (PulseTimer <= diff)
- {
- DoCastAOE(SPELL_SHADOW_PULSE, true);
- PulseTimer = 3000;
- } else PulseTimer -= diff;
-
- if (VoidBlastTimer <= diff)
+ _scheduler.Update(diff, [this]
{
- DoCastVictim(SPELL_VOID_BLAST, false);
- VoidBlastTimer = 45000;
- } else VoidBlastTimer -= diff;
-
- DoMeleeAttackIfReady();
+ DoMeleeAttackIfReady();
+ });
}
+
+ private:
+ TaskScheduler _scheduler;
+ InstanceScript* _instance;
};
+
+ CreatureAI* GetAI(Creature* creature) const override
+ {
+ return GetSunwellPlateauAI<npc_void_sentinelAI>(creature);
+ }
};
class npc_blackhole : public CreatureScript
@@ -512,84 +512,220 @@ class npc_blackhole : public CreatureScript
public:
npc_blackhole() : CreatureScript("npc_blackhole") { }
- CreatureAI* GetAI(Creature* creature) const override
- {
- return GetInstanceAI<npc_blackholeAI>(creature);
- }
-
struct npc_blackholeAI : public ScriptedAI
{
npc_blackholeAI(Creature* creature) : ScriptedAI(creature)
{
- Initialize();
- instance = creature->GetInstanceScript();
+ _instance = creature->GetInstanceScript();
}
- void Initialize()
- {
- DespawnTimer = 15000;
- SpellTimer = 5000;
- Phase = 0;
- NeedForAHack = 0;
- }
-
- InstanceScript* instance;
-
- uint32 DespawnTimer;
- uint32 SpellTimer;
- uint8 Phase;
- uint8 NeedForAHack;
-
void Reset() override
{
- Initialize();
+ me->SetReactState(REACT_PASSIVE);
+ DoCast(SPELL_BLACKHOLE_SUMMON_VISUAL);
- me->AddUnitState(UNIT_STATE_STUNNED);
- DoCastAOE(SPELL_BLACKHOLE_SPAWN, true);
- }
+ _scheduler.Schedule(Seconds(15), [this](TaskContext /*context*/)
+ {
+ me->DisappearAndDie();
+ });
- void UpdateAI(uint32 diff) override
- {
- if (SpellTimer <= diff)
+ _scheduler.Schedule(Seconds(1), [this](TaskContext context)
{
- Unit* Victim = ObjectAccessor::GetUnit(*me, instance->GetGuidData(DATA_PLAYER_GUID));
- switch (NeedForAHack)
+ switch (context.GetRepeatCounter())
{
case 0:
- me->ClearUnitState(UNIT_STATE_STUNNED);
- DoCastAOE(SPELL_BLACKHOLE_GROW, false);
- if (Victim)
- AttackStart(Victim);
- SpellTimer = 700;
- NeedForAHack = 2;
+ me->SetReactState(REACT_AGGRESSIVE);
+ DoCast(SPELL_BLACKHOLE_SUMMON_VISUAL_2);
+ if (Unit* victim = ObjectAccessor::GetUnit(*me, _instance->GetGuidData(DATA_PLAYER_GUID)))
+ AttackStart(victim);
+ context.Repeat(Milliseconds(1200));
break;
case 1:
- me->AddAura(SPELL_BLACKHOLE_GROW, me);
- NeedForAHack = 2;
- SpellTimer = 600;
+ DoCast(SPELL_BLACKHOLE_SUMMON_VISUAL);
+ context.Repeat(Seconds(2));
break;
case 2:
- SpellTimer = 400;
- NeedForAHack = 3;
- me->RemoveAura(SPELL_BLACKHOLE_GROW);
+ DoCast(SPELL_BLACKHOLE_PASSIVE);
+ DoCast(SPELL_BLACK_HOLE_VISUAL_2);
+ break;
+ default:
break;
- case 3:
- SpellTimer = urand(400, 900);
- NeedForAHack = 1;
- if (Unit* Temp = me->GetVictim())
- {
- if (Temp->GetPositionZ() > 73 && Victim)
- AttackStart(Victim);
- } else
- return;
}
- } else SpellTimer -= diff;
+ });
+ }
- if (DespawnTimer <= diff)
- me->DisappearAndDie();
- else DespawnTimer -= diff;
+ void UpdateAI(uint32 diff) override
+ {
+ _scheduler.Update(diff);
}
+
+ private:
+ TaskScheduler _scheduler;
+ InstanceScript* _instance;
};
+
+ CreatureAI* GetAI(Creature* creature) const override
+ {
+ return GetSunwellPlateauAI<npc_blackholeAI>(creature);
+ }
+};
+
+class spell_summon_blood_elves_script : SpellScriptLoader
+{
+ public:
+ spell_summon_blood_elves_script() : SpellScriptLoader("spell_summon_blood_elves_script") { }
+
+ class spell_summon_blood_elves_script_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_summon_blood_elves_script_SpellScript);
+
+ bool Validate(SpellInfo const* /*spell*/) override
+ {
+ for (uint8 i = 0; i < MAX_SUMMON_BLOOD_ELVES; ++i)
+ if (!sSpellMgr->GetSpellInfo(SummonBloodElvesSpells[i]))
+ return false;
+ return true;
+ }
+
+ void HandleScript(SpellEffIndex /*effIndex*/)
+ {
+ for (uint8 i = 0; i < MAX_SUMMON_BLOOD_ELVES; ++i)
+ GetCaster()->CastSpell((Unit*)nullptr, SummonBloodElvesSpells[urand(0,3)], true);
+ }
+
+ void Register() override
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_summon_blood_elves_script_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
+ }
+ };
+
+ SpellScript* GetSpellScript() const override
+ {
+ return new spell_summon_blood_elves_script_SpellScript();
+ }
+};
+
+class spell_muru_darkness : SpellScriptLoader
+{
+ public:
+ spell_muru_darkness() : SpellScriptLoader("spell_muru_darkness") { }
+
+ class spell_muru_darkness_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_muru_darkness_SpellScript);
+
+ bool Validate(SpellInfo const* /*spell*/) override
+ {
+ for (uint8 i = 0; i < MAX_SUMMON_DARK_FIEND; ++i)
+ if (!sSpellMgr->GetSpellInfo(SummonDarkFiendSpells[i]))
+ return false;
+ return true;
+ }
+
+ void HandleAfterCast()
+ {
+ for (uint8 i = 0; i < MAX_SUMMON_DARK_FIEND; ++i)
+ GetCaster()->CastSpell((Unit*)nullptr, SummonDarkFiendSpells[i], true);
+ }
+
+ void Register() override
+ {
+ AfterCast += SpellCastFn(spell_muru_darkness_SpellScript::HandleAfterCast);
+ }
+ };
+
+ SpellScript* GetSpellScript() const override
+ {
+ return new spell_muru_darkness_SpellScript();
+ }
+};
+
+class spell_dark_fiend_skin : public SpellScriptLoader
+{
+ public:
+ spell_dark_fiend_skin() : SpellScriptLoader("spell_dark_fiend_skin") { }
+
+ class spell_dark_fiend_skin_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_dark_fiend_skin_AuraScript);
+
+ void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
+ {
+ if (GetTargetApplication()->GetRemoveMode() != AURA_REMOVE_BY_ENEMY_SPELL)
+ return;
+
+ if (Creature* target = GetTarget()->ToCreature())
+ {
+ target->SetReactState(REACT_PASSIVE);
+ target->AttackStop();
+ target->StopMoving();
+ target->CastSpell(target, SPELL_DARKFIEND_VISUAL, true);
+ target->DespawnOrUnsummon(3000);
+ }
+ }
+
+ void Register() override
+ {
+ AfterEffectRemove += AuraEffectRemoveFn(spell_dark_fiend_skin_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
+ }
+ };
+
+ AuraScript* GetAuraScript() const override
+ {
+ return new spell_dark_fiend_skin_AuraScript();
+ }
+};
+
+class spell_transform_visual_missile_periodic : public SpellScriptLoader
+{
+ public:
+ spell_transform_visual_missile_periodic() : SpellScriptLoader("spell_transform_visual_missile_periodic") { }
+
+ class spell_transform_visual_missile_periodic_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_transform_visual_missile_periodic_AuraScript);
+
+ void OnPeriodic(AuraEffect const* /*aurEff*/)
+ {
+ GetTarget()->CastSpell((Unit*)nullptr, RAND(TRANSFORM_VISUAL_MISSILE_1, TRANSFORM_VISUAL_MISSILE_2), true);
+ }
+
+ void Register() override
+ {
+ OnEffectPeriodic += AuraEffectPeriodicFn(spell_transform_visual_missile_periodic_AuraScript::OnPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY);
+ }
+ };
+
+ AuraScript* GetAuraScript() const override
+ {
+ return new spell_transform_visual_missile_periodic_AuraScript();
+ }
+};
+
+class spell_summon_blood_elves_periodic : public SpellScriptLoader
+{
+ public:
+ spell_summon_blood_elves_periodic() : SpellScriptLoader("spell_summon_blood_elves_periodic") { }
+
+ class spell_summon_blood_elves_periodic_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_summon_blood_elves_periodic_AuraScript);
+
+ void OnPeriodic(AuraEffect const* /*aurEff*/)
+ {
+ GetTarget()->CastSpell((Unit*)nullptr, SPELL_SUMMON_BLOOD_ELVES_SCRIPT, true);
+ }
+
+ void Register() override
+ {
+ OnEffectPeriodic += AuraEffectPeriodicFn(spell_summon_blood_elves_periodic_AuraScript::OnPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY);
+ }
+ };
+
+ AuraScript* GetAuraScript() const override
+ {
+ return new spell_summon_blood_elves_periodic_AuraScript();
+ }
};
void AddSC_boss_muru()
@@ -600,4 +736,9 @@ void AddSC_boss_muru()
new npc_dark_fiend();
new npc_void_sentinel();
new npc_blackhole();
+ new spell_summon_blood_elves_script();
+ new spell_muru_darkness();
+ new spell_dark_fiend_skin();
+ new spell_transform_visual_missile_periodic();
+ new spell_summon_blood_elves_periodic();
}
diff --git a/src/server/scripts/EasternKingdoms/SunwellPlateau/sunwell_plateau.h b/src/server/scripts/EasternKingdoms/SunwellPlateau/sunwell_plateau.h
index c6b4ae753a5..7ea0fc4bc7d 100644
--- a/src/server/scripts/EasternKingdoms/SunwellPlateau/sunwell_plateau.h
+++ b/src/server/scripts/EasternKingdoms/SunwellPlateau/sunwell_plateau.h
@@ -97,7 +97,8 @@ enum CreatureIds
NPC_FURY_MAGE = 25799,
NPC_VOID_SENTINEL = 25772,
NPC_VOID_SPAWN = 25824,
- NPC_BLACK_HOLE = 25855
+ NPC_BLACK_HOLE = 25855,
+ NPC_MURU_PORTAL_TARGET = 25770
};
enum GameObjectIds
diff --git a/src/server/scripts/Kalimdor/BlackfathomDeeps/instance_blackfathom_deeps.cpp b/src/server/scripts/Kalimdor/BlackfathomDeeps/instance_blackfathom_deeps.cpp
index b0d6e782052..03c957fa221 100644
--- a/src/server/scripts/Kalimdor/BlackfathomDeeps/instance_blackfathom_deeps.cpp
+++ b/src/server/scripts/Kalimdor/BlackfathomDeeps/instance_blackfathom_deeps.cpp
@@ -174,7 +174,7 @@ public:
if (state == DONE)
if (GameObject* go = instance->GetGameObject(shrineOfGelihastGUID))
go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
- break;
+ break;
case DATA_AKU_MAI:
if (state == DONE)
if (GameObject* go = instance->GetGameObject(altarOfTheDeepsGUID))
diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/old_hillsbrad.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/old_hillsbrad.cpp
index 0526dcfa630..8e53ab06ca5 100644
--- a/src/server/scripts/Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/old_hillsbrad.cpp
+++ b/src/server/scripts/Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/old_hillsbrad.cpp
@@ -535,12 +535,12 @@ public:
if (!UpdateVictim())
return;
- /// @todo add his abilities'n-crap here
- if (!LowHp && HealthBelowPct(20))
- {
- Talk(SAY_TH_RANDOM_LOW_HP);
- LowHp = true;
- }
+ /// @todo add his abilities'n-crap here
+ if (!LowHp && HealthBelowPct(20))
+ {
+ Talk(SAY_TH_RANDOM_LOW_HP);
+ LowHp = true;
+ }
}
};
diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/boss_aeonus.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/boss_aeonus.cpp
index 8715f3ca0f6..4d0f80d502d 100644
--- a/src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/boss_aeonus.cpp
+++ b/src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/boss_aeonus.cpp
@@ -106,33 +106,33 @@ public:
if (!UpdateVictim())
return;
- events.Update(diff);
+ events.Update(diff);
- if (me->HasUnitState(UNIT_STATE_CASTING))
- return;
+ if (me->HasUnitState(UNIT_STATE_CASTING))
+ return;
- while (uint32 eventId = events.ExecuteEvent())
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch (eventId)
{
- switch (eventId)
- {
- case EVENT_SANDBREATH:
- DoCastVictim(SPELL_SAND_BREATH);
- events.ScheduleEvent(EVENT_SANDBREATH, urand(15000, 25000));
- break;
- case EVENT_TIMESTOP:
- DoCastVictim(SPELL_TIME_STOP);
- events.ScheduleEvent(EVENT_TIMESTOP, urand(20000, 35000));
- break;
- case EVENT_FRENZY:
- Talk(EMOTE_FRENZY);
- DoCast(me, SPELL_ENRAGE);
- events.ScheduleEvent(EVENT_FRENZY, urand(20000, 35000));
- break;
- default:
- break;
- }
+ case EVENT_SANDBREATH:
+ DoCastVictim(SPELL_SAND_BREATH);
+ events.ScheduleEvent(EVENT_SANDBREATH, urand(15000, 25000));
+ break;
+ case EVENT_TIMESTOP:
+ DoCastVictim(SPELL_TIME_STOP);
+ events.ScheduleEvent(EVENT_TIMESTOP, urand(20000, 35000));
+ break;
+ case EVENT_FRENZY:
+ Talk(EMOTE_FRENZY);
+ DoCast(me, SPELL_ENRAGE);
+ events.ScheduleEvent(EVENT_FRENZY, urand(20000, 35000));
+ break;
+ default:
+ break;
}
- DoMeleeAttackIfReady();
+ }
+ DoMeleeAttackIfReady();
}
};
diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/boss_temporus.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/boss_temporus.cpp
index 2befdabe550..844ce239bdf 100644
--- a/src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/boss_temporus.cpp
+++ b/src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/boss_temporus.cpp
@@ -107,36 +107,36 @@ public:
if (!UpdateVictim())
return;
- events.Update(diff);
+ events.Update(diff);
- if (me->HasUnitState(UNIT_STATE_CASTING))
- return;
+ if (me->HasUnitState(UNIT_STATE_CASTING))
+ return;
- while (uint32 eventId = events.ExecuteEvent())
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch (eventId)
{
- switch (eventId)
- {
- case EVENT_HASTE:
- DoCast(me, SPELL_HASTE);
- events.ScheduleEvent(EVENT_HASTE, urand(20000, 25000));
- break;
- case EVENT_MORTAL_WOUND:
- DoCast(me, SPELL_MORTAL_WOUND);
- events.ScheduleEvent(EVENT_MORTAL_WOUND, urand(10000, 20000));
- break;
- case EVENT_WING_BUFFET:
- DoCast(me, SPELL_WING_BUFFET);
- events.ScheduleEvent(EVENT_WING_BUFFET, urand(20000, 30000));
- break;
- case EVENT_SPELL_REFLECTION: // Only in Heroic
- DoCast(me, SPELL_REFLECT);
- events.ScheduleEvent(EVENT_SPELL_REFLECTION, urand(25000, 35000));
- break;
- default:
- break;
- }
+ case EVENT_HASTE:
+ DoCast(me, SPELL_HASTE);
+ events.ScheduleEvent(EVENT_HASTE, urand(20000, 25000));
+ break;
+ case EVENT_MORTAL_WOUND:
+ DoCast(me, SPELL_MORTAL_WOUND);
+ events.ScheduleEvent(EVENT_MORTAL_WOUND, urand(10000, 20000));
+ break;
+ case EVENT_WING_BUFFET:
+ DoCast(me, SPELL_WING_BUFFET);
+ events.ScheduleEvent(EVENT_WING_BUFFET, urand(20000, 30000));
+ break;
+ case EVENT_SPELL_REFLECTION: // Only in Heroic
+ DoCast(me, SPELL_REFLECT);
+ events.ScheduleEvent(EVENT_SPELL_REFLECTION, urand(25000, 35000));
+ break;
+ default:
+ break;
}
- DoMeleeAttackIfReady();
+ }
+ DoMeleeAttackIfReady();
}
};
diff --git a/src/server/scripts/Kalimdor/zone_the_barrens.cpp b/src/server/scripts/Kalimdor/zone_the_barrens.cpp
index b113615ca50..7a963d066b6 100644
--- a/src/server/scripts/Kalimdor/zone_the_barrens.cpp
+++ b/src/server/scripts/Kalimdor/zone_the_barrens.cpp
@@ -43,38 +43,37 @@ EndContentData */
## npc_beaten_corpse
######*/
-#define GOSSIP_CORPSE "Examine corpse in detail..."
-
enum BeatenCorpse
{
- QUEST_LOST_IN_BATTLE = 4921
+ GOSSIP_OPTION_ID_BEATEN_CORPSE = 0,
+ GOSSIP_MENU_OPTION_INSPECT_BODY = 2871
};
class npc_beaten_corpse : public CreatureScript
{
-public:
- npc_beaten_corpse() : CreatureScript("npc_beaten_corpse") { }
+ public:
+ npc_beaten_corpse() : CreatureScript("npc_beaten_corpse") { }
- bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) override
- {
- player->PlayerTalkClass->ClearMenus();
- if (action == GOSSIP_ACTION_INFO_DEF +1)
+ struct npc_beaten_corpseAI : public ScriptedAI
{
- player->SEND_GOSSIP_MENU(3558, creature->GetGUID());
- player->TalkedToCreature(creature->GetEntry(), creature->GetGUID());
- }
- return true;
- }
-
- bool OnGossipHello(Player* player, Creature* creature) override
- {
- if (player->GetQuestStatus(QUEST_LOST_IN_BATTLE) == QUEST_STATUS_INCOMPLETE || player->GetQuestStatus(QUEST_LOST_IN_BATTLE) == QUEST_STATUS_COMPLETE)
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_CORPSE, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
+ npc_beaten_corpseAI(Creature* creature) : ScriptedAI(creature)
+ {
+ }
- player->SEND_GOSSIP_MENU(3557, creature->GetGUID());
- return true;
- }
+ void sGossipSelect(Player* player, uint32 menuId, uint32 gossipListId) override
+ {
+ if (menuId == GOSSIP_MENU_OPTION_INSPECT_BODY && gossipListId == GOSSIP_OPTION_ID_BEATEN_CORPSE)
+ {
+ player->CLOSE_GOSSIP_MENU();
+ player->TalkedToCreature(me->GetEntry(), me->GetGUID());
+ }
+ }
+ };
+ CreatureAI* GetAI(Creature* creature) const override
+ {
+ return new npc_beaten_corpseAI(creature);
+ }
};
/*######
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp
index caa37465165..1a37d5238d2 100644
--- a/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp
@@ -604,6 +604,7 @@ class npc_ice_tomb : public CreatureScript
_trappedPlayerGUID.Clear();
player->RemoveAurasDueToSpell(SPELL_ICE_TOMB_DAMAGE);
player->RemoveAurasDueToSpell(SPELL_ASPHYXIATION);
+ player->RemoveAurasDueToSpell(SPELL_ICE_TOMB_UNTARGETABLE);
}
}
@@ -1284,9 +1285,9 @@ class spell_sindragosa_ice_tomb : public SpellScriptLoader
public:
spell_sindragosa_ice_tomb() : SpellScriptLoader("spell_sindragosa_ice_tomb_trap") { }
- class spell_sindragosa_ice_tomb_SpellScript : public SpellScript
+ class spell_sindragosa_ice_tomb_AuraScript : public AuraScript
{
- PrepareSpellScript(spell_sindragosa_ice_tomb_SpellScript);
+ PrepareAuraScript(spell_sindragosa_ice_tomb_AuraScript);
bool Validate(SpellInfo const* /*spell*/) override
{
@@ -1297,46 +1298,42 @@ class spell_sindragosa_ice_tomb : public SpellScriptLoader
return true;
}
- void SummonTomb()
+ void PeriodicTick(AuraEffect const* aurEff)
{
- Position pos = GetHitUnit()->GetPosition();
- if (TempSummon* summon = GetCaster()->SummonCreature(NPC_ICE_TOMB, pos))
+ PreventDefaultAction();
+
+ if (aurEff->GetTickNumber() == 1)
{
- summon->AI()->SetGUID(GetHitUnit()->GetGUID(), DATA_TRAPPED_PLAYER);
- if (GameObject* go = summon->SummonGameObject(GO_ICE_BLOCK, pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), pos.GetOrientation(), 0.0f, 0.0f, 0.0f, 0.0f, 0))
+ if (Unit* caster = GetCaster())
{
- go->SetSpellId(SPELL_ICE_TOMB_DAMAGE);
- summon->AddGameObject(go);
+ Position pos = GetTarget()->GetPosition();
+
+ if (TempSummon* summon = caster->SummonCreature(NPC_ICE_TOMB, pos))
+ {
+ summon->AI()->SetGUID(GetTarget()->GetGUID(), DATA_TRAPPED_PLAYER);
+ GetTarget()->CastSpell(GetTarget(), SPELL_ICE_TOMB_UNTARGETABLE);
+ if (GameObject* go = summon->SummonGameObject(GO_ICE_BLOCK, pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), pos.GetOrientation(), 0.0f, 0.0f, 0.0f, 0.0f, 0))
+ {
+ go->SetSpellId(SPELL_ICE_TOMB_DAMAGE);
+ summon->AddGameObject(go);
+ }
+ }
}
}
}
- void Register() override
- {
- AfterHit += SpellHitFn(spell_sindragosa_ice_tomb_SpellScript::SummonTomb);
- }
- };
-
- class spell_sindragosa_ice_tomb_AuraScript : public AuraScript
- {
- PrepareAuraScript(spell_sindragosa_ice_tomb_AuraScript);
-
- void PeriodicTick(AuraEffect const* /*aurEff*/)
+ void HandleRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
- PreventDefaultAction();
+ GetTarget()->RemoveAurasDueToSpell(SPELL_ICE_TOMB_UNTARGETABLE);
}
void Register() override
{
OnEffectPeriodic += AuraEffectPeriodicFn(spell_sindragosa_ice_tomb_AuraScript::PeriodicTick, EFFECT_2, SPELL_AURA_PERIODIC_TRIGGER_SPELL);
+ AfterEffectRemove += AuraEffectRemoveFn(spell_sindragosa_ice_tomb_AuraScript::HandleRemove, EFFECT_2, SPELL_AURA_PERIODIC_TRIGGER_SPELL, AURA_EFFECT_HANDLE_REAL);
}
};
- SpellScript* GetSpellScript() const override
- {
- return new spell_sindragosa_ice_tomb_SpellScript();
- }
-
AuraScript* GetAuraScript() const override
{
return new spell_sindragosa_ice_tomb_AuraScript();
diff --git a/src/server/scripts/Northrend/IsleOfConquest/boss_ioc_horde_alliance.cpp b/src/server/scripts/Northrend/IsleOfConquest/boss_ioc_horde_alliance.cpp
new file mode 100644
index 00000000000..71d90da21a1
--- /dev/null
+++ b/src/server/scripts/Northrend/IsleOfConquest/boss_ioc_horde_alliance.cpp
@@ -0,0 +1,132 @@
+/*
+ * Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "ScriptMgr.h"
+#include "ScriptedCreature.h"
+#include "BattlegroundIC.h"
+
+enum BossSpells
+{
+ SPELL_BRUTAL_STRIKE = 58460,
+ SPELL_DAGGER_THROW = 67280,
+ SPELL_CRUSHING_LEAP = 68506,
+ SPELL_RAGE = 66776
+};
+
+enum BossEvents
+{
+ EVENT_BRUTAL_STRIKE = 1,
+ EVENT_DAGGER_THROW = 2,
+ EVENT_CRUSHING_LEAP = 3,
+ EVENT_CHECK_RANGE = 4
+};
+
+class boss_ioc_horde_alliance : public CreatureScript
+{
+public:
+ boss_ioc_horde_alliance() : CreatureScript("boss_ioc_horde_alliance") { }
+
+ struct boss_ioc_horde_allianceAI : public ScriptedAI
+ {
+ boss_ioc_horde_allianceAI(Creature* creature) : ScriptedAI(creature) { }
+
+ void Reset() override
+ {
+ _events.Reset();
+
+ uint32 _npcGuard;
+ if (me->GetEntry() == NPC_HIGH_COMMANDER_HALFORD_WYRMBANE)
+ _npcGuard = NPC_SEVEN_TH_LEGION_INFANTRY;
+ else
+ _npcGuard = NPC_KOR_KRON_GUARD;
+
+ std::list<Creature*> guardsList;
+ me->GetCreatureListWithEntryInGrid(guardsList, _npcGuard, 100.0f);
+ for (std::list<Creature*>::const_iterator itr = guardsList.begin(); itr != guardsList.end(); ++itr)
+ (*itr)->Respawn();
+ };
+
+ void EnterCombat(Unit* /*who*/) override
+ {
+ _events.ScheduleEvent(EVENT_BRUTAL_STRIKE, 5 * IN_MILLISECONDS);
+ _events.ScheduleEvent(EVENT_DAGGER_THROW, 7 * IN_MILLISECONDS);
+ _events.ScheduleEvent(EVENT_CHECK_RANGE, 1 * IN_MILLISECONDS);
+ _events.ScheduleEvent(EVENT_CRUSHING_LEAP, 15 * IN_MILLISECONDS);
+ }
+
+ void SpellHit(Unit* caster, SpellInfo const* /*spell*/) override
+ {
+ if (caster->IsVehicle())
+ me->Kill(caster);
+ }
+
+ void UpdateAI(uint32 diff) override
+ {
+ if (!UpdateVictim())
+ return;
+
+ if (me->HasUnitState(UNIT_STATE_CASTING))
+ return;
+
+ _events.Update(diff);
+
+ while (uint32 eventId = _events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_BRUTAL_STRIKE:
+ DoCastVictim(SPELL_BRUTAL_STRIKE);
+ _events.ScheduleEvent(EVENT_BRUTAL_STRIKE, 5 * IN_MILLISECONDS);
+ break;
+ case EVENT_DAGGER_THROW:
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1))
+ DoCast(target, SPELL_DAGGER_THROW);
+ _events.ScheduleEvent(EVENT_DAGGER_THROW, 7 * IN_MILLISECONDS);
+ break;
+ case EVENT_CRUSHING_LEAP:
+ DoCastVictim(SPELL_CRUSHING_LEAP);
+ _events.ScheduleEvent(EVENT_CRUSHING_LEAP, 25 * IN_MILLISECONDS);
+ break;
+ case EVENT_CHECK_RANGE:
+ if (me->GetDistance(me->GetHomePosition()) > 25.0f)
+ DoCast(me, SPELL_RAGE);
+ else
+ me->RemoveAurasDueToSpell(SPELL_RAGE);
+ _events.ScheduleEvent(EVENT_CHECK_RANGE, 1 * IN_MILLISECONDS);
+ break;
+ default:
+ break;
+ }
+ }
+
+ DoMeleeAttackIfReady();
+ }
+
+ private:
+ EventMap _events;
+ };
+
+ CreatureAI* GetAI(Creature* creature) const
+ {
+ return new boss_ioc_horde_allianceAI(creature);
+ }
+};
+
+void AddSC_boss_ioc_horde_alliance()
+{
+ new boss_ioc_horde_alliance();
+}
diff --git a/src/server/scripts/Northrend/isle_of_conquest.cpp b/src/server/scripts/Northrend/IsleOfConquest/isle_of_conquest.cpp
index 11cc645f0cb..11cc645f0cb 100644
--- a/src/server/scripts/Northrend/isle_of_conquest.cpp
+++ b/src/server/scripts/Northrend/IsleOfConquest/isle_of_conquest.cpp
diff --git a/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp b/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp
index f000d7a3ef7..3d5a6ee8dfb 100644
--- a/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp
+++ b/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp
@@ -1224,13 +1224,15 @@ public:
void DoAction(int32 /*action*/) override
{
if (Vehicle* vehicleTemp = me->GetVehicleKit())
+ {
if (vehicleTemp->GetPassenger(0) && vehicleTemp->GetPassenger(0)->GetTypeId() == TYPEID_PLAYER)
{
vehicleTemp->RemoveAllPassengers();
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
}
+ }
- me->DespawnOrUnsummon(3*IN_MILLISECONDS);
+ me->DespawnOrUnsummon(3*IN_MILLISECONDS);
}
void MovementInform(uint32 type, uint32 id) override
diff --git a/src/server/scripts/Northrend/northrend_script_loader.cpp b/src/server/scripts/Northrend/northrend_script_loader.cpp
index 7d104b85f6d..d84bb1c4072 100644
--- a/src/server/scripts/Northrend/northrend_script_loader.cpp
+++ b/src/server/scripts/Northrend/northrend_script_loader.cpp
@@ -178,6 +178,8 @@ void AddSC_boss_baltharus_the_warborn();
void AddSC_boss_saviana_ragefire();
void AddSC_boss_general_zarithrian();
void AddSC_boss_halion();
+void AddSC_isle_of_conquest(); // Isle of Conquest
+void AddSC_boss_ioc_horde_alliance();
void AddSC_dalaran();
void AddSC_borean_tundra();
@@ -190,7 +192,6 @@ void AddSC_storm_peaks();
void AddSC_wintergrasp();
void AddSC_zuldrak();
void AddSC_crystalsong_forest();
-void AddSC_isle_of_conquest();
// The name of this function should match:
// void Add${NameOfDirectory}Scripts()
@@ -358,6 +359,8 @@ void AddNorthrendScripts()
AddSC_boss_saviana_ragefire();
AddSC_boss_general_zarithrian();
AddSC_boss_halion();
+ AddSC_isle_of_conquest(); // Isle of Conquest
+ AddSC_boss_ioc_horde_alliance();
AddSC_dalaran();
AddSC_borean_tundra();
@@ -370,5 +373,4 @@ void AddNorthrendScripts()
AddSC_wintergrasp();
AddSC_zuldrak();
AddSC_crystalsong_forest();
- AddSC_isle_of_conquest();
}
diff --git a/src/server/scripts/Northrend/zone_grizzly_hills.cpp b/src/server/scripts/Northrend/zone_grizzly_hills.cpp
index 59802165a94..4eafc1cd94e 100644
--- a/src/server/scripts/Northrend/zone_grizzly_hills.cpp
+++ b/src/server/scripts/Northrend/zone_grizzly_hills.cpp
@@ -22,6 +22,7 @@
#include "Player.h"
#include "SpellScript.h"
#include "CreatureTextMgr.h"
+#include "CombatAI.h"
/*######
## Quest 12027: Mr. Floppy's Perilous Adventure
@@ -854,6 +855,254 @@ class spell_infected_worgen_bite : public SpellScriptLoader
}
};
+/*######
+## Quest: Riding the Red Rocket
+######*/
+
+enum RedRocket
+{
+ SPELL_VEHICLE_WARHEAD_FUSE = 49107,
+ SPELL_ALLIANCE_KILL_CREDIT_TORPEDO = 49510,
+ SPELL_HORDE_KILL_CREDIT_TORPEDO = 49340,
+ NPC_HORDE_LUMBERBOAT = 27702,
+ NPC_ALLIANCE_LUMBERBOAT = 27688,
+ SPELL_DETONATE = 49250
+};
+
+class npc_rocket_propelled_warhead : public CreatureScript
+{
+public:
+ npc_rocket_propelled_warhead() : CreatureScript("npc_rocket_propelled_warhead") { }
+
+ struct npc_rocket_propelled_warheadAI : public VehicleAI
+ {
+ npc_rocket_propelled_warheadAI(Creature* creature) : VehicleAI(creature)
+ {
+ _finished = false;
+ _faction = ALLIANCE;
+ }
+
+ void PassengerBoarded(Unit* who, int8 /*seatId*/, bool apply) override
+ {
+ if (apply && who->ToPlayer())
+ {
+ DoCast(me, SPELL_VEHICLE_WARHEAD_FUSE);
+ _faction = who->ToPlayer()->GetTeam();
+ }
+ }
+
+ void JustReachedHome() override
+ {
+ _finished = false;
+ me->SetVisible(true);
+ me->GetMotionMaster()->Clear(true);
+ }
+
+ void DoAction(int32 /*action*/) override
+ {
+ FinishQuest(false, _faction);
+ }
+
+ void SpellHit(Unit* caster, SpellInfo const* /*spellInfo*/) override
+ {
+ if (caster->GetEntry() == NPC_HORDE_LUMBERBOAT || caster->GetEntry() == NPC_ALLIANCE_LUMBERBOAT)
+ FinishQuest(true, _faction);
+ }
+
+ void FinishQuest(bool success, uint32 faction)
+ {
+ if (_finished)
+ return;
+
+ _finished = true;
+
+ if (success)
+ DoCast(me, faction == ALLIANCE ? SPELL_ALLIANCE_KILL_CREDIT_TORPEDO : SPELL_HORDE_KILL_CREDIT_TORPEDO);
+
+ DoCast(me, SPELL_DETONATE);
+ me->RemoveAllAuras();
+ me->SetVisible(false);
+ me->GetMotionMaster()->MoveTargetedHome();
+ }
+
+ private:
+ uint32 _faction;
+ bool _finished;
+ };
+
+ CreatureAI* GetAI(Creature* creature) const override
+ {
+ return new npc_rocket_propelled_warheadAI(creature);
+ }
+};
+
+enum WarheadSpells
+{
+ SPELL_WARHEAD_Z_CHECK = 61678,
+ SPELL_WARHEAD_SEEKING_LUMBERSHIP = 49331,
+ SPELL_WARHEAD_FUSE = 49181
+};
+// 49107 - Vehicle: Warhead Fuse
+class spell_vehicle_warhead_fuse : public SpellScriptLoader
+{
+public:
+ spell_vehicle_warhead_fuse() : SpellScriptLoader("spell_vehicle_warhead_fuse") { }
+
+ class spell_vehicle_warhead_fuse_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_vehicle_warhead_fuse_SpellScript);
+
+ bool Validate(SpellInfo const* /*spellInfo*/) override
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_WARHEAD_Z_CHECK) || !sSpellMgr->GetSpellInfo(SPELL_WARHEAD_SEEKING_LUMBERSHIP) || !sSpellMgr->GetSpellInfo(SPELL_WARHEAD_FUSE))
+ return false;
+ return true;
+ }
+
+ void HandleDummy(SpellEffIndex /*effIndex*/)
+ {
+ Unit* caster = GetCaster();
+
+ caster->CastSpell(caster, SPELL_WARHEAD_Z_CHECK, true);
+ caster->CastSpell(caster, SPELL_WARHEAD_SEEKING_LUMBERSHIP, true);
+ caster->CastSpell(caster, SPELL_WARHEAD_FUSE, true);
+ }
+
+ void Register() override
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_vehicle_warhead_fuse_SpellScript::HandleDummy, EFFECT_1, SPELL_EFFECT_SCRIPT_EFFECT);
+ }
+ };
+
+ SpellScript* GetSpellScript() const override
+ {
+ return new spell_vehicle_warhead_fuse_SpellScript();
+ }
+};
+
+enum WarheadDenonate
+{
+ SPELL_PARACHUTE = 66154,
+ SPELL_TORPEDO_EXPLOSION = 49290,
+ NPC_ALLIANCE_LUMBERBOAT_EXPLOSIONS = 27689
+};
+// 49250 - Detonate
+class spell_warhead_detonate : public SpellScriptLoader
+{
+public:
+ spell_warhead_detonate() : SpellScriptLoader("spell_warhead_detonate") { }
+
+ class spell_warhead_detonate_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_warhead_detonate_SpellScript);
+
+ bool Validate(SpellInfo const* /*spellInfo*/) override
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_PARACHUTE) || !sSpellMgr->GetSpellInfo(SPELL_TORPEDO_EXPLOSION))
+ return false;
+ return true;
+ }
+
+ void HandleDummy(SpellEffIndex /*effIndex*/)
+ {
+ Unit* caster = GetCaster();
+ Player* player = GetHitPlayer();
+ if (!player)
+ return;
+
+ player->ExitVehicle();
+ float horizontalSpeed = 3.0f;
+ float verticalSpeed = 40.0f;
+ player->KnockbackFrom(caster->GetPositionX(), caster->GetPositionY(), horizontalSpeed, verticalSpeed);
+ caster->CastSpell(player, SPELL_PARACHUTE, true);
+
+ std::list<Creature*> explosionBunnys;
+ caster->GetCreatureListWithEntryInGrid(explosionBunnys, NPC_ALLIANCE_LUMBERBOAT_EXPLOSIONS, 90.0f);
+ for (std::list<Creature*>::const_iterator itr = explosionBunnys.begin(); itr != explosionBunnys.end(); ++itr)
+ (*itr)->CastSpell((*itr), SPELL_TORPEDO_EXPLOSION, true);
+ }
+
+ void Register() override
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_warhead_detonate_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
+ }
+ };
+
+ SpellScript* GetSpellScript() const override
+ {
+ return new spell_warhead_detonate_SpellScript();
+ }
+};
+
+// 61678 - Z Check
+class spell_z_check : public SpellScriptLoader
+{
+public:
+ spell_z_check() : SpellScriptLoader("spell_z_check") { }
+
+ class spell_z_check_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_z_check_AuraScript);
+
+ void HandleEffectApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
+ {
+ _posZ = GetTarget()->GetPositionZ();
+ }
+
+ void HandleEffectPeriodic(AuraEffect const* /*aurEff*/)
+ {
+ PreventDefaultAction();
+
+ if (_posZ != GetTarget()->GetPositionZ())
+ if (Creature* target = GetTarget()->ToCreature())
+ target->AI()->DoAction(0);
+ }
+
+ private:
+ float _posZ;
+
+ void Register() override
+ {
+ OnEffectApply += AuraEffectApplyFn(spell_z_check_AuraScript::HandleEffectApply, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL, AURA_EFFECT_HANDLE_REAL);
+ OnEffectPeriodic += AuraEffectPeriodicFn(spell_z_check_AuraScript::HandleEffectPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL);
+ }
+ };
+
+ AuraScript* GetAuraScript() const override
+ {
+ return new spell_z_check_AuraScript();
+ }
+};
+
+// 49181 - Warhead Fuse
+class spell_warhead_fuse : public SpellScriptLoader
+{
+public:
+ spell_warhead_fuse() : SpellScriptLoader("spell_warhead_fuse") { }
+
+ class spell_warhead_fuse_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_warhead_fuse_AuraScript);
+
+ void HandleOnEffectRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
+ {
+ if (Unit* rocketUnit = GetTarget()->GetVehicleBase())
+ if (Creature* rocketCrea = rocketUnit->ToCreature())
+ rocketCrea->AI()->DoAction(0);
+ }
+
+ void Register() override
+ {
+ OnEffectRemove += AuraEffectRemoveFn(spell_warhead_fuse_AuraScript::HandleOnEffectRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
+ }
+ };
+
+ AuraScript* GetAuraScript() const override
+ {
+ return new spell_warhead_fuse_AuraScript();
+ }
+};
+
void AddSC_grizzly_hills()
{
new npc_emily();
@@ -866,4 +1115,9 @@ void AddSC_grizzly_hills()
new npc_lake_frog();
new spell_shredder_delivery();
new spell_infected_worgen_bite();
+ new npc_rocket_propelled_warhead();
+ new spell_z_check();
+ new spell_warhead_detonate();
+ new spell_vehicle_warhead_fuse();
+ new spell_warhead_fuse();
}
diff --git a/src/server/scripts/Outland/BlackTemple/boss_illidan.cpp b/src/server/scripts/Outland/BlackTemple/boss_illidan.cpp
index 3c651e10a1e..14aeda04a7e 100644
--- a/src/server/scripts/Outland/BlackTemple/boss_illidan.cpp
+++ b/src/server/scripts/Outland/BlackTemple/boss_illidan.cpp
@@ -1301,15 +1301,17 @@ public:
EventMaiev Event = EVENT_MAIEV_NULL;
for (uint8 i = 1; i <= MaxTimer; ++i)
+ {
if (Timer[i])
{
if (Timer[i] <= diff)
Event = (EventMaiev)i;
else Timer[i] -= diff;
}
+ }
- switch (Event)
- {
+ switch (Event)
+ {
case EVENT_MAIEV_STEALTH:
{
me->SetFullHealth();
@@ -1345,21 +1347,21 @@ public:
break;
default:
break;
- }
+ }
- if (HealthBelowPct(50))
- {
- me->SetVisible(false);
- me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
- if (Creature* illidan = ObjectAccessor::GetCreature(*me, IllidanGUID))
- ENSURE_AI(boss_illidan_stormrage::boss_illidan_stormrageAI, illidan->AI())->DeleteFromThreatList(me->GetGUID());
- me->AttackStop();
- Timer[EVENT_MAIEV_STEALTH] = 60000; // reappear after 1 minute
- MaxTimer = 1;
- }
+ if (HealthBelowPct(50))
+ {
+ me->SetVisible(false);
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ if (Creature* illidan = ObjectAccessor::GetCreature(*me, IllidanGUID))
+ ENSURE_AI(boss_illidan_stormrage::boss_illidan_stormrageAI, illidan->AI())->DeleteFromThreatList(me->GetGUID());
+ me->AttackStop();
+ Timer[EVENT_MAIEV_STEALTH] = 60000; // reappear after 1 minute
+ MaxTimer = 1;
+ }
- if (Phase == PHASE_NORMAL_MAIEV)
- DoMeleeAttackIfReady();
+ if (Phase == PHASE_NORMAL_MAIEV)
+ DoMeleeAttackIfReady();
}
private:
diff --git a/src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/boss_nethekurse.cpp b/src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/boss_nethekurse.cpp
index 499550945c6..2592ed3b262 100644
--- a/src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/boss_nethekurse.cpp
+++ b/src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/boss_nethekurse.cpp
@@ -180,24 +180,23 @@ class boss_grand_warlock_nethekurse : public CreatureScript
}
void MoveInLineOfSight(Unit* who) override
-
{
if (!IntroOnce && me->IsWithinDistInMap(who, 30.0f))
- {
+ {
if (who->GetTypeId() != TYPEID_PLAYER)
return;
- Talk(SAY_INTRO);
- IntroOnce = true;
- IsIntroEvent = true;
+ Talk(SAY_INTRO);
+ IntroOnce = true;
+ IsIntroEvent = true;
- instance->SetBossState(DATA_NETHEKURSE, IN_PROGRESS);
- }
+ instance->SetBossState(DATA_NETHEKURSE, IN_PROGRESS);
+ }
- if (IsIntroEvent || !IsMainEvent)
- return;
+ if (IsIntroEvent || !IsMainEvent)
+ return;
- ScriptedAI::MoveInLineOfSight(who);
+ ScriptedAI::MoveInLineOfSight(who);
}
void EnterCombat(Unit* /*who*/) override
diff --git a/src/server/scripts/Outland/TempestKeep/Eye/boss_astromancer.cpp b/src/server/scripts/Outland/TempestKeep/Eye/boss_astromancer.cpp
index 9fd1c5c7388..30b3fd67687 100644
--- a/src/server/scripts/Outland/TempestKeep/Eye/boss_astromancer.cpp
+++ b/src/server/scripts/Outland/TempestKeep/Eye/boss_astromancer.cpp
@@ -325,86 +325,85 @@ class boss_high_astromancer_solarian : public CreatureScript
else
Phase1_Timer-=diff;
}
- else
- if (Phase == 2)
+ else if (Phase == 2)
+ {
+ //10 seconds after Solarian disappears, 12 mobs spawn out of the three portals.
+ me->AttackStop();
+ me->StopMoving();
+ if (Phase2_Timer <= diff)
{
- //10 seconds after Solarian disappears, 12 mobs spawn out of the three portals.
- me->AttackStop();
- me->StopMoving();
- if (Phase2_Timer <= diff)
- {
- Phase = 3;
- for (int i=0; i <= 2; ++i)
- for (int j=1; j <= 4; j++)
- SummonMinion(NPC_SOLARIUM_AGENT, Portals[i][0], Portals[i][1], Portals[i][2]);
+ Phase = 3;
+ for (int i=0; i <= 2; ++i)
+ for (int j=1; j <= 4; j++)
+ SummonMinion(NPC_SOLARIUM_AGENT, Portals[i][0], Portals[i][1], Portals[i][2]);
- Talk(SAY_SUMMON1);
- Phase2_Timer = 10000;
- }
- else
- Phase2_Timer -= diff;
+ Talk(SAY_SUMMON1);
+ Phase2_Timer = 10000;
}
else
- if (Phase == 3)
- {
- me->AttackStop();
- me->StopMoving();
- //Check Phase3_Timer
- if (Phase3_Timer <= diff)
- {
- Phase = 1;
- //15 seconds later Solarian reappears out of one of the 3 portals. Simultaneously, 2 healers appear in the two other portals.
- int i = rand32() % 3;
- me->GetMotionMaster()->Clear();
- me->SetPosition(Portals[i][0], Portals[i][1], Portals[i][2], CENTER_O);
-
- for (int j=0; j <= 2; j++)
- if (j != i)
- SummonMinion(NPC_SOLARIUM_PRIEST, Portals[j][0], Portals[j][1], Portals[j][2]);
-
- me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
- me->SetVisible(true);
-
- Talk(SAY_SUMMON2);
- AppearDelay = true;
- Phase3_Timer = 15000;
- }
- else
- Phase3_Timer -= diff;
- }
- else
- if (Phase == 4)
- {
- //Fear_Timer
- if (Fear_Timer <= diff)
- {
- DoCast(me, SPELL_FEAR);
- Fear_Timer = 20000;
- }
- else
- Fear_Timer -= diff;
- //VoidBolt_Timer
- if (VoidBolt_Timer <= diff)
- {
- DoCastVictim(SPELL_VOID_BOLT);
- VoidBolt_Timer = 10000;
- }
- else
- VoidBolt_Timer -= diff;
- }
- //When Solarian reaches 20% she will transform into a huge void walker.
- if (Phase != 4 && me->HealthBelowPct(20))
- {
- Phase = 4;
- //To make sure she wont be invisible or not selecatble
- me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
- me->SetVisible(true);
- Talk(SAY_VOIDA);
- Talk(SAY_VOIDB);
- me->SetArmor(WV_ARMOR);
- me->SetDisplayId(MODEL_VOIDWALKER);
- me->SetObjectScale(defaultsize*2.5f);
- }
+ Phase2_Timer -= diff;
+ }
+ else if (Phase == 3)
+ {
+ me->AttackStop();
+ me->StopMoving();
+ //Check Phase3_Timer
+ if (Phase3_Timer <= diff)
+ {
+ Phase = 1;
+ //15 seconds later Solarian reappears out of one of the 3 portals. Simultaneously, 2 healers appear in the two other portals.
+ int i = rand32() % 3;
+ me->GetMotionMaster()->Clear();
+ me->SetPosition(Portals[i][0], Portals[i][1], Portals[i][2], CENTER_O);
+
+ for (int j=0; j <= 2; j++)
+ if (j != i)
+ SummonMinion(NPC_SOLARIUM_PRIEST, Portals[j][0], Portals[j][1], Portals[j][2]);
+
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ me->SetVisible(true);
+
+ Talk(SAY_SUMMON2);
+ AppearDelay = true;
+ Phase3_Timer = 15000;
+ }
+ else
+ Phase3_Timer -= diff;
+ }
+ else if (Phase == 4)
+ {
+ //Fear_Timer
+ if (Fear_Timer <= diff)
+ {
+ DoCast(me, SPELL_FEAR);
+ Fear_Timer = 20000;
+ }
+ else
+ Fear_Timer -= diff;
+ //VoidBolt_Timer
+ if (VoidBolt_Timer <= diff)
+ {
+ DoCastVictim(SPELL_VOID_BOLT);
+ VoidBolt_Timer = 10000;
+ }
+ else
+ VoidBolt_Timer -= diff;
+ }
+
+ //When Solarian reaches 20% she will transform into a huge void walker.
+ if (Phase != 4 && me->HealthBelowPct(20))
+ {
+ Phase = 4;
+ //To make sure she wont be invisible or not selecatble
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ me->SetVisible(true);
+ Talk(SAY_VOIDA);
+ Talk(SAY_VOIDB);
+ me->SetArmor(WV_ARMOR);
+ me->SetDisplayId(MODEL_VOIDWALKER);
+ me->SetObjectScale(defaultsize*2.5f);
+ }
+
DoMeleeAttackIfReady();
}
};
diff --git a/src/server/scripts/World/go_scripts.cpp b/src/server/scripts/World/go_scripts.cpp
index 3094ecd660a..8f2ea5887d2 100644
--- a/src/server/scripts/World/go_scripts.cpp
+++ b/src/server/scripts/World/go_scripts.cpp
@@ -1171,7 +1171,7 @@ public:
player->CastSpell(player, SPELL_CLEANSING_SOUL);
player->SetStandState(UNIT_STAND_STATE_SIT);
}
- return true;
+ return true;
}
};
diff --git a/src/server/scripts/World/item_scripts.cpp b/src/server/scripts/World/item_scripts.cpp
index f4241ba0819..52174e1b012 100644
--- a/src/server/scripts/World/item_scripts.cpp
+++ b/src/server/scripts/World/item_scripts.cpp
@@ -57,18 +57,18 @@ public:
//for special scripts
switch (itemId)
{
- case 24538:
+ case 24538:
if (player->GetAreaId() != 3628)
disabled = true;
- break;
- case 34489:
+ break;
+ case 34489:
if (player->GetZoneId() != 4080)
disabled = true;
- break;
- case 34475:
- if (const SpellInfo* spellInfo = sSpellMgr->GetSpellInfo(SPELL_ARCANE_CHARGES))
+ break;
+ case 34475:
+ if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(SPELL_ARCANE_CHARGES))
Spell::SendCastResult(player, spellInfo, 1, SPELL_FAILED_NOT_ON_GROUND);
- break;
+ break;
}
// allow use in flight only
diff --git a/src/server/shared/DataStores/DBCStore.h b/src/server/shared/DataStores/DBCStore.h
index 7c2cab1e36a..b93bbdaea12 100644
--- a/src/server/shared/DataStores/DBCStore.h
+++ b/src/server/shared/DataStores/DBCStore.h
@@ -25,121 +25,6 @@
#include "DatabaseWorkerPool.h"
#include "Implementation/WorldDatabase.h"
#include "DatabaseEnv.h"
-#include <G3D/Vector3.h>
-#include <G3D/AABox.h>
-
- // Structures for M4 file. Source: https://wowdev.wiki
-template<typename T>
-struct M2SplineKey
-{
- T p0;
- T p1;
- T p2;
-};
-
-struct M2Header
-{
- char Magic[4]; // "MD20"
- uint32 Version; // The version of the format.
- uint32 lName; // Length of the model's name including the trailing \0
- uint32 ofsName; // Offset to the name, it seems like models can get reloaded by this name.should be unique, i guess.
- uint32 GlobalModelFlags; // 0x0001: tilt x, 0x0002: tilt y, 0x0008: add 2 fields in header, 0x0020: load .phys data (MoP+), 0x0080: has _lod .skin files (MoP?+), 0x0100: is camera related.
- uint32 nGlobalSequences;
- uint32 ofsGlobalSequences; // A list of timestamps.
- uint32 nAnimations;
- uint32 ofsAnimations; // Information about the animations in the model.
- uint32 nAnimationLookup;
- uint32 ofsAnimationLookup; // Mapping of global IDs to the entries in the Animation sequences block.
- uint32 nBones; // MAX_BONES = 0x100
- uint32 ofsBones; // Information about the bones in this model.
- uint32 nKeyBoneLookup;
- uint32 ofsKeyBoneLookup; // Lookup table for key skeletal bones.
- uint32 nVertices;
- uint32 ofsVertices; // Vertices of the model.
- uint32 nViews; // Views (LOD) are now in .skins.
- uint32 nSubmeshAnimations;
- uint32 ofsSubmeshAnimations; // Submesh color and alpha animations definitions.
- uint32 nTextures;
- uint32 ofsTextures; // Textures of this model.
- uint32 nTransparency;
- uint32 ofsTransparency; // Transparency of textures.
- uint32 nUVAnimation;
- uint32 ofsUVAnimation;
- uint32 nTexReplace;
- uint32 ofsTexReplace; // Replaceable Textures.
- uint32 nRenderFlags;
- uint32 ofsRenderFlags; // Blending modes / render flags.
- uint32 nBoneLookupTable;
- uint32 ofsBoneLookupTable; // A bone lookup table.
- uint32 nTexLookup;
- uint32 ofsTexLookup; // The same for textures.
- uint32 nTexUnits; // possibly removed with cata?!
- uint32 ofsTexUnits; // And texture units. Somewhere they have to be too.
- uint32 nTransLookup;
- uint32 ofsTransLookup; // Everything needs its lookup. Here are the transparencies.
- uint32 nUVAnimLookup;
- uint32 ofsUVAnimLookup;
- G3D::AABox BoundingBox; // min/max( [1].z, 2.0277779f ) - 0.16f seems to be the maximum camera height
- float BoundingSphereRadius;
- G3D::AABox CollisionBox;
- float CollisionSphereRadius;
- uint32 nBoundingTriangles;
- uint32 ofsBoundingTriangles; // Our bounding volumes. Similar structure like in the old ofsViews.
- uint32 nBoundingVertices;
- uint32 ofsBoundingVertices;
- uint32 nBoundingNormals;
- uint32 ofsBoundingNormals;
- uint32 nAttachments;
- uint32 ofsAttachments; // Attachments are for weapons etc.
- uint32 nAttachLookup;
- uint32 ofsAttachLookup; // Of course with a lookup.
- uint32 nEvents;
- uint32 ofsEvents; // Used for playing sounds when dying and a lot else.
- uint32 nLights;
- uint32 ofsLights; // Lights are mainly used in loginscreens but in wands and some doodads too.
- uint32 nCameras; // Format of Cameras changed with version 271!
- uint32 ofsCameras; // The cameras are present in most models for having a model in the Character-Tab.
- uint32 nCameraLookup;
- uint32 ofsCameraLookup; // And lookup-time again.
- uint32 nRibbonEmitters;
- uint32 ofsRibbonEmitters; // Things swirling around. See the CoT-entrance for light-trails.
- uint32 nParticleEmitters;
- uint32 ofsParticleEmitters; // Spells and weapons, doodads and loginscreens use them. Blood dripping of a blade? Particles.
- uint32 nBlendMaps; // This has to deal with blending. Exists IFF (flags & 0x8) != 0. When set, textures blending is overriden by the associated array. See M2/WotLK#Blend_mode_overrides
- uint32 ofsBlendMaps; // Same as above. Points to an array of uint16 of nBlendMaps entries -- From WoD information.};
-};
-
-struct M2Array
-{
- uint32_t number;
- uint32 offset_elements;
-};
-struct M2Track
-{
- uint16_t interpolation_type;
- uint16_t global_sequence;
- M2Array timestamps;
- M2Array values;
-};
-
-struct M2Camera
-{
- uint32_t type; // 0: portrait, 1: characterinfo; -1: else (flyby etc.); referenced backwards in the lookup table.
- float fov; // No radians, no degrees. Multiply by 35 to get degrees.
- float far_clip;
- float near_clip;
- M2Track positions; // How the camera's position moves. Should be 3*3 floats.
- G3D::Vector3 position_base;
- M2Track target_positions; // How the target moves. Should be 3*3 floats.
- G3D::Vector3 target_position_base;
- M2Track rolldata; // The camera can have some roll-effect. Its 0 to 2*Pi.
-};
-
-struct FlyByCamera
-{
- uint32 timeStamp;
- G3D::Vector4 locations;
-};
struct SqlDbc
{
diff --git a/src/server/worldserver/worldserver.conf.dist b/src/server/worldserver/worldserver.conf.dist
index 9e0e1cbada5..ccb784f8c2b 100644
--- a/src/server/worldserver/worldserver.conf.dist
+++ b/src/server/worldserver/worldserver.conf.dist
@@ -1658,6 +1658,14 @@ ListenRange.TextEmote = 40
ListenRange.Yell = 300
#
+# Creature.MovingStopTimeForPlayer
+# Description: Time (in milliseconds) during which creature will not move after
+# interaction with player.
+# Default: 180000
+
+Creature.MovingStopTimeForPlayer = 180000
+
+#
###################################################################################################
###################################################################################################
@@ -1869,6 +1877,13 @@ GM.LowerSecurity = 0
GM.TicketSystem.ChanceOfGMSurvey = 50
#
+# GM.ForceShutdownThreshold
+# Description: Minimum shutdown time in seconds before 'force' is required if other players are connected.
+# Default: 30
+
+GM.ForceShutdownThreshold = 30
+
+#
###################################################################################################
###################################################################################################
diff --git a/src/tools/map_extractor/System.cpp b/src/tools/map_extractor/System.cpp
index 1d84fc75d27..9d3dc47bce0 100644
--- a/src/tools/map_extractor/System.cpp
+++ b/src/tools/map_extractor/System.cpp
@@ -1041,7 +1041,7 @@ void ExtractCameraFiles(int locale, bool basicLocale)
std::vector<std::string> camerafiles;
size_t cam_count = camdbc.getRecordCount();
- for (uint32 i = 0; i < cam_count; ++i)
+ for (size_t i = 0; i < cam_count; ++i)
{
std::string camFile(camdbc.getRecord(i).getString(1));
size_t loc = camFile.find(".mdx");