aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTraesh <Traesh@users.noreply.github.com>2017-01-29 00:00:43 +0100
committerjoschiwald <joschiwald.trinity@gmail.com>2017-01-29 00:00:43 +0100
commit6ab3877c91c9440b81cf1c7c66a1275ee04ea26a (patch)
tree9930d19512eef247d1c0a23284caa446ceef21c8
parent5818dd364ca6a8b0cb068710291adf26b571aa23 (diff)
Core/Entities: Basic AreaTrigger System (#18035)
* Implemented AreaTrigger Templates * Implemented AreaTrigger Splines * Implemented SPELL_AURA_AREA_TRIGGER * and many more
-rw-r--r--sql/base/auth_database.sql6
-rw-r--r--sql/updates/auth/master/2017_01_29_00_auth.sql9
-rw-r--r--sql/updates/world/master/2017_01_29_00_world.sql62
-rw-r--r--src/server/game/AI/CreatureAI.h4
-rw-r--r--src/server/game/Accounts/RBAC.h1
-rw-r--r--src/server/game/DataStores/DB2Stores.h1
-rw-r--r--src/server/game/Entities/AreaTrigger/AreaTrigger.cpp610
-rw-r--r--src/server/game/Entities/AreaTrigger/AreaTrigger.h77
-rw-r--r--src/server/game/Entities/AreaTrigger/AreaTriggerTemplate.cpp58
-rw-r--r--src/server/game/Entities/AreaTrigger/AreaTriggerTemplate.h187
-rw-r--r--src/server/game/Entities/Object/Object.cpp236
-rw-r--r--src/server/game/Entities/Object/Updates/UpdateData.h2
-rw-r--r--src/server/game/Entities/Player/Player.cpp3
-rw-r--r--src/server/game/Entities/Transport/Transport.cpp4
-rw-r--r--src/server/game/Entities/Unit/Unit.cpp54
-rw-r--r--src/server/game/Entities/Unit/Unit.h11
-rw-r--r--src/server/game/Globals/AreaTriggerDataStore.cpp230
-rw-r--r--src/server/game/Globals/AreaTriggerDataStore.h39
-rw-r--r--src/server/game/Globals/ObjectMgr.cpp2
-rw-r--r--src/server/game/Grids/Notifiers/GridNotifiers.h5
-rw-r--r--src/server/game/Grids/ObjectGridLoader.cpp4
-rw-r--r--src/server/game/Handlers/MiscHandler.cpp5
-rw-r--r--src/server/game/Maps/Map.cpp165
-rw-r--r--src/server/game/Maps/Map.h8
-rw-r--r--src/server/game/Scripting/ScriptMgr.cpp107
-rw-r--r--src/server/game/Scripting/ScriptMgr.h44
-rw-r--r--src/server/game/Server/Packets/AllPackets.h1
-rw-r--r--src/server/game/Server/Packets/AreaTriggerPackets.cpp97
-rw-r--r--src/server/game/Server/Packets/AreaTriggerPackets.h107
-rw-r--r--src/server/game/Server/Packets/MiscPackets.cpp7
-rw-r--r--src/server/game/Server/Packets/MiscPackets.h22
-rw-r--r--src/server/game/Server/Protocol/Opcodes.cpp6
-rw-r--r--src/server/game/Server/WorldSession.h8
-rw-r--r--src/server/game/Spells/Auras/SpellAuraEffects.cpp22
-rw-r--r--src/server/game/Spells/Auras/SpellAuraEffects.h1
-rw-r--r--src/server/game/Spells/SpellEffects.cpp32
-rw-r--r--src/server/game/Spells/SpellInfo.cpp11
-rw-r--r--src/server/game/Spells/SpellInfo.h1
-rw-r--r--src/server/game/World/World.cpp4
-rw-r--r--src/server/scripts/Commands/cs_reload.cpp9
-rw-r--r--src/server/worldserver/worldserver.conf.dist1
41 files changed, 2086 insertions, 177 deletions
diff --git a/sql/base/auth_database.sql b/sql/base/auth_database.sql
index 06546c08a24..b9d87870b69 100644
--- a/sql/base/auth_database.sql
+++ b/sql/base/auth_database.sql
@@ -644,7 +644,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,776),(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,835),(192,844),(192,845),(192,846),(192,847),(192,848),(192,849),(192,850),(193,48),(193,194),(193,197),(194,1),(194,2),(194,11),(194,12),(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,10),(196,200),(196,201),(196,208),(196,212),(196,213),(196,214),(196,215),(196,216),(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,615),(196,616),(196,617),(196,618),(196,619),(196,620),(196,621),(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,663),(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,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,753),(196,757),(196,773),(196,777),(196,809),(196,817),(196,825),(196,829),(196,830),(196,831),(196,832),(196,833),(196,836),(196,837),(196,838),(196,839),(196,840),(196,842),(196,843),(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,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),(197,805),(197,811),(197,813),(197,819),(197,821),(197,827),(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,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,799),(198,800),(198,801),(198,802),(198,803),(198,804),(198,806),(198,807),(198,808),(198,810),(198,812),(198,814),(198,815),(198,816),(198,818),(198,820),(198,822),(198,823),(198,824),(198,826),(198,828),(198,834),(199,207),(199,209),(199,210),(199,211),(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,776),(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,835),(192,844),(192,845),(192,846),(192,847),(192,848),(192,849),(192,850),(192,851),(193,48),(193,194),(193,197),(194,1),(194,2),(194,11),(194,12),(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,10),(196,200),(196,201),(196,208),(196,212),(196,213),(196,214),(196,215),(196,216),(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,615),(196,616),(196,617),(196,618),(196,619),(196,620),(196,621),(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,663),(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,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,753),(196,757),(196,773),(196,777),(196,809),(196,817),(196,825),(196,829),(196,830),(196,831),(196,832),(196,833),(196,836),(196,837),(196,838),(196,839),(196,840),(196,842),(196,843),(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,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),(197,805),(197,811),(197,813),(197,819),(197,821),(197,827),(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,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,799),(198,800),(198,801),(198,802),(198,803),(198,804),(198,806),(198,807),(198,808),(198,810),(198,812),(198,814),(198,815),(198,816),(198,818),(198,820),(198,822),(198,823),(198,824),(198,826),(198,828),(198,834),(199,207),(199,209),(199,210),(199,211),(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;
@@ -668,7 +668,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'),(10,'Use character templates'),(11,'Log GM trades'),(12,'Skip character creation demon hunter min level check'),(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'),(207,'Command: battlenetaccount'),(208,'Command: battlenetaccount create'),(209,'Command: battlenetaccount lock country'),(210,'Command: battlenetaccount lock ip'),(211,'Command: battlenetaccount password'),(212,'Command: battlenetaccount set'),(213,'Command: battlenetaccount set password'),(214,'Command: bnetaccount link'),(215,'Command: bnetaccount unlink'),(216,'Command: bnetaccount gameaccountcreate'),(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 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 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'),(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 criteria_data'),(610,'Command: reload achievement_reward'),(611,'Command: reload all'),(612,'Command: reload all achievement'),(613,'Command: reload all area'),(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'),(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 support'),(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'),(663,'Command: reload locales_item_set_name'),(665,'Command: reload locales_page_text'),(666,'Command: reload locales_points_of_interest'),(667,'Command: reload quest_locale'),(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'),(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'),(753,'Command: ticket reset'),(757,'Command: ticket togglesystem'),(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'),(776,'Command: debug phase'),(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'),(797,'Command: pvpstats'),(798,'Command: .mod xp'),(799,'Command: .go bugticket'),(800,'Command: .go complaintticket'),(801,'Command: .go suggestionticket'),(802,'Command: .ticket bug'),(803,'Command: .ticket complaint'),(804,'Command: .ticket suggestion'),(805,'Command: .ticket bug assign'),(806,'Command: .ticket bug close'),(807,'Command: .ticket bug closedlist'),(808,'Command: .ticket bug comment'),(809,'Command: .ticket bug delete'),(810,'Command: .ticket bug list'),(811,'Command: .ticket bug unassign'),(812,'Command: .ticket bug view'),(813,'Command: .ticket complaint assign'),(814,'Command: .ticket complaint close'),(815,'Command: .ticket complaint closedlist'),(816,'Command: .ticket complaint comment'),(817,'Command: .ticket complaint delete'),(818,'Command: .ticket complaint list'),(819,'Command: .ticket complaint unassign'),(820,'Command: .ticket complaint view'),(821,'Command: .ticket suggestion assign'),(822,'Command: .ticket suggestion close'),(823,'Command: .ticket suggestion closedlist'),(824,'Command: .ticket suggestion comment'),(825,'Command: .ticket suggestion delete'),(826,'Command: .ticket suggestion list'),(827,'Command: .ticket suggestion unassign'),(828,'Command: .ticket suggestion view'),(829,'Command: .ticket reset all'),(830,'Command: .bnetaccount listgameaccounts'),(831,'Command: .ticket reset bug'),(832,'Command: .ticket reset complaint'),(833,'Command: .ticket reset suggestion'),(834,'Command: go quest'),(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'),(841,'Command: .debug neargraveyard'),(842,'Command: reload character_template'),(843,'Command: reload quest_greeting'),(844,'Command: scene'),(845,'Command: scene debug'),(846,'Command: scene play'),(847,'Command: scene play package'),(848,'Command: scene cancel'),(849,'Command: list scenes'),(850,'Command: reload scenes');
+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'),(10,'Use character templates'),(11,'Log GM trades'),(12,'Skip character creation demon hunter min level check'),(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'),(207,'Command: battlenetaccount'),(208,'Command: battlenetaccount create'),(209,'Command: battlenetaccount lock country'),(210,'Command: battlenetaccount lock ip'),(211,'Command: battlenetaccount password'),(212,'Command: battlenetaccount set'),(213,'Command: battlenetaccount set password'),(214,'Command: bnetaccount link'),(215,'Command: bnetaccount unlink'),(216,'Command: bnetaccount gameaccountcreate'),(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 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 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'),(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 criteria_data'),(610,'Command: reload achievement_reward'),(611,'Command: reload all'),(612,'Command: reload all achievement'),(613,'Command: reload all area'),(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'),(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 support'),(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'),(663,'Command: reload locales_item_set_name'),(665,'Command: reload locales_page_text'),(666,'Command: reload locales_points_of_interest'),(667,'Command: reload quest_locale'),(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'),(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'),(753,'Command: ticket reset'),(757,'Command: ticket togglesystem'),(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'),(776,'Command: debug phase'),(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'),(797,'Command: pvpstats'),(798,'Command: .mod xp'),(799,'Command: .go bugticket'),(800,'Command: .go complaintticket'),(801,'Command: .go suggestionticket'),(802,'Command: .ticket bug'),(803,'Command: .ticket complaint'),(804,'Command: .ticket suggestion'),(805,'Command: .ticket bug assign'),(806,'Command: .ticket bug close'),(807,'Command: .ticket bug closedlist'),(808,'Command: .ticket bug comment'),(809,'Command: .ticket bug delete'),(810,'Command: .ticket bug list'),(811,'Command: .ticket bug unassign'),(812,'Command: .ticket bug view'),(813,'Command: .ticket complaint assign'),(814,'Command: .ticket complaint close'),(815,'Command: .ticket complaint closedlist'),(816,'Command: .ticket complaint comment'),(817,'Command: .ticket complaint delete'),(818,'Command: .ticket complaint list'),(819,'Command: .ticket complaint unassign'),(820,'Command: .ticket complaint view'),(821,'Command: .ticket suggestion assign'),(822,'Command: .ticket suggestion close'),(823,'Command: .ticket suggestion closedlist'),(824,'Command: .ticket suggestion comment'),(825,'Command: .ticket suggestion delete'),(826,'Command: .ticket suggestion list'),(827,'Command: .ticket suggestion unassign'),(828,'Command: .ticket suggestion view'),(829,'Command: .ticket reset all'),(830,'Command: .bnetaccount listgameaccounts'),(831,'Command: .ticket reset bug'),(832,'Command: .ticket reset complaint'),(833,'Command: .ticket reset suggestion'),(834,'Command: go quest'),(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'),(841,'Command: .debug neargraveyard'),(842,'Command: reload character_template'),(843,'Command: reload quest_greeting'),(844,'Command: scene'),(845,'Command: scene debug'),(846,'Command: scene play'),(847,'Command: scene play package'),(848,'Command: scene cancel'),(849,'Command: list scenes'),(850,'Command: reload scenes'),(851,'Command: reload areatrigger_templates');
/*!40000 ALTER TABLE `rbac_permissions` ENABLE KEYS */;
UNLOCK TABLES;
@@ -757,7 +757,7 @@ CREATE TABLE `updates` (
LOCK TABLES `updates` WRITE;
/*!40000 ALTER TABLE `updates` DISABLE KEYS */;
-INSERT INTO `updates` VALUES ('2014_10_04_00_auth.sql','C3BC70A6EC381474B7308F442346F1E721176BC6','ARCHIVED','2015-03-21 16:55:52',0),('2014_10_19_00_auth.sql','7472B490A4F86C9D3DA609CDD3197499CB80C87C','ARCHIVED','2015-03-21 16:55:52',0),('2014_10_26_00_auth.sql','75CC67ADE2A3B2E54FD57D6B0DCAA8FE50F4EE35','ARCHIVED','2015-03-21 16:55:52',0),('2014_11_03_00_auth.sql','5948C9F286CF0FEA8E241785C0259FF36B73BDC5','ARCHIVED','2015-03-21 16:55:52',0),('2014_11_04_00_auth.sql','3AFC68B2375C2A417DDEA94583C53AFF83DE50DF','ARCHIVED','2015-03-21 16:55:52',0),('2014_11_09_00_auth.sql','B8DD1A7047C0FDDB80344B239343EC33BF1A0D97','ARCHIVED','2015-03-21 16:55:52',0),('2014_11_10_00_auth.sql','8FBA737A1D3FF4631A1E662A5B500A8BD304EC63','ARCHIVED','2015-03-21 16:55:52',0),('2014_11_10_00_auth_from_335.sql','0E3CB119442D09DD88E967015319BBC8DAFBBFE0','ARCHIVED','2015-03-21 16:55:52',0),('2014_11_10_01_auth.sql','327E77A1DA3546D5275AB249915DD57EDD6FDD3D','ARCHIVED','2015-03-21 16:55:52',0),('2014_11_23_00_auth.sql','0BBEB3EB3AED0FEF277A062819B6B2C00084A742','ARCHIVED','2015-03-21 16:55:52',0),('2014_11_25_00_auth.sql','4F45CDB26BDBB3EE83F1988E3D7818C5926ADC02','ARCHIVED','2015-03-21 16:55:52',0),('2014_12_05_00_auth.sql','6A7BBCEF43111C73A2D2C3CCB6911BE50DE7DD94','ARCHIVED','2015-03-21 16:55:52',0),('2014_12_10_00_auth.sql','821703A96D80F9080074852B5A46E2909C9562EA','ARCHIVED','2015-03-21 16:55:52',0),('2014_12_19_00_auth.sql','44D8E12FFF327AD07878FBDF8D9C16B6B7DCB122','ARCHIVED','2015-03-21 16:55:52',0),('2014_12_20_00_auth.sql','4DAA02AE285C02AE6C82EA2C8B97AC71990F1085','ARCHIVED','2015-03-21 16:55:52',0),('2014_12_25_00_auth.sql','61411930F482BC73FC7FD2C370C811E944F5FF92','ARCHIVED','2015-03-21 16:55:52',0),('2014_12_27_00_auth.sql','CE2E5D2CD82E79C25294539ADED27A1429105B43','ARCHIVED','2015-03-21 16:55:52',0),('2014_12_28_00_auth.sql','0A913217610E76AFF119C27259737BBC523090E6','ARCHIVED','2015-03-21 16:55:52',0),('2015_02_22_00_auth.sql','21CCCF8B01252E16CA3D6C9E3E8DAA4C9B28ED6E','ARCHIVED','2015-03-21 16:55:52',0),('2015_03_01_00_auth.sql','911881E273207FF6182D1FDAC8C85FFAE8F1C852','ARCHIVED','2015-03-21 16:55:52',0),('2015_03_10_00_auth.sql','2CC8502C11412EFEB5C11BE166761A8754A59009','ARCHIVED','2015-03-21 16:55:52',0),('2015_03_20_00_auth.sql','B761760804EA73BD297F296C5C1919687DF7191C','ARCHIVED','2015-03-21 16:55:52',0),('2015_03_20_01_auth.sql','5CCEDF20C8189FB1E8DF064A9F0DDC342841FBF0','ARCHIVED','2015-03-21 16:55:52',0),('2015_03_20_02_auth.sql','85E4ACD9AA099C0C4AC034575F2BB07D348EAC72','ARCHIVED','2015-03-21 16:56:46',0),('2015_03_15_00_auth.sql','1D8E107FBEFE5E7F47E09F45240DFF499B77CDED','ARCHIVED','2015-05-02 13:57:57',0),('2015_03_26_00_auth.sql','34AC8543E6A9C6C832DE58EAB33618EEEF70B9F9','ARCHIVED','2015-05-02 13:57:57',0),('2015_04_04_00_auth.sql','57146B35E54A2EC7869C945034AB078358020311','ARCHIVED','2015-05-02 13:57:57',0),('2015_04_06_00_auth.sql','2A8049DC2923420A002D42FB6F02C2FFCC5CDD22','ARCHIVED','2015-05-02 13:57:57',0),('2015_04_08_00_auth.sql','4D7D8EEF285C982BB676836602266501BEC26764','ARCHIVED','2015-05-02 13:57:57',0),('2015_04_10_00_auth.sql','4AE68FD97A95CEE5143EA20FD33F5D557367AC1F','ARCHIVED','2015-05-02 13:57:57',0),('2015_04_11_00_auth.sql','80A71C8921CFEBB547D264558B6DE27201685B84','ARCHIVED','2015-05-02 13:57:57',0),('2015_04_11_01_auth.sql','3E88183E1A85D11BFD74CF9A32A725C44AE02EEC','ARCHIVED','2015-05-02 13:57:57',0),('2015_04_21_00_auth.sql','1B3B48DBA06368B985C548D166C515C9DD598CB9','ARCHIVED','2015-05-02 13:57:57',0),('2015_05_02_00_auth.sql','96AB595E0D2A088750E3F48B0AF0A8A14F3CFE1E','ARCHIVED','2015-05-02 13:57:57',0),('2015_05_02_01_auth.sql','FB11FB834E488B0FD3AFDABCC1A3113092E7C2E5','ARCHIVED','2015-05-02 13:57:57',0),('2015_07_02_00_auth.sql','E5EE3842AB9B01851E49B360FBAF6FFEEAB2A8DA','ARCHIVED','2015-07-10 19:30:56',0),('2015_07_06_00_auth.sql','6D1ADBA496DC6E6D7B3BF887DA8D4D17D3FBACE0','ARCHIVED','2015-07-10 19:30:56',0),('2015_07_08_00_auth.sql','CB54020AFD1E31742FD8BF9CE16879625E289788','ARCHIVED','2015-07-10 19:30:56',0),('2015_07_08_01_auth.sql','74D281CB82E0DA36D628BDC7AC797AE5498DB461','ARCHIVED','2015-07-10 19:30:56',0),('2015_07_16_00_auth.sql','A057E95B5553B6A57A1642FE3FEC8E2E62EDE3C6','ARCHIVED','2015-10-10 08:30:48',0),('2015_07_29_00_auth.sql','0000FECBC413E96C7C45F303D162E263EFBA7116','ARCHIVED','2015-10-10 08:30:48',0),('2015_08_26_00_auth.sql','3071C02A2EB7DCBF4CEE10279FEFAB7C29A43A3A','ARCHIVED','2015-10-10 08:30:48',0),('2015_09_05_00_auth.sql','F765D82B37873FA67447347D5B83C99C159FB452','ARCHIVED','2015-10-10 08:30:48',0),('2015_09_05_01_auth.sql','97A72DBCBF14D27A1863834A22296905FF276086','ARCHIVED','2015-10-10 08:30:48',0),('2015_09_09_00_auth.sql','495A0CF1B1C49205D4A5D3C25A4E1EB95616D6B4','ARCHIVED','2015-10-10 08:30:48',0),('2015_09_15_00_auth.sql','D1FEFDA4C98F30384DF4B64D5A53187303EB5786','ARCHIVED','2015-10-10 08:30:48',0),('2015_10_09_00_auth.sql','B6D643D444C6AE711503F73B96B6252A852913D6','ARCHIVED','2015-10-10 08:30:48',0),('2015_10_16_00_auth.sql','366AFFD1088762866091A81CE1EC64138B8B35F1','ARCHIVED','2015-11-08 00:46:02',62),('2015_10_17_00_auth.sql','AC0D45E905033F42093852D2C4476663BDACCB3D','ARCHIVED','2015-10-17 12:39:12',0),('2015_11_01_00_auth_2015_08_21_00.sql','C31A9E1D28E11B60BE8F8198637DD51F6D75123F','ARCHIVED','2015-11-01 14:50:26',0),('2015_11_08_00_auth.sql','0ACDD35EC9745231BCFA701B78056DEF94D0CC53','ARCHIVED','2015-11-08 00:51:45',0),('2015_11_21_00_auth.sql','575A1D697CC6C7C517F7CCB950988267C99CE7FA','ARCHIVED','2015-11-21 21:25:38',0),('2015_12_07_00_auth.sql','24A07AC1F38E5D26A3599FC06D29E267418F69F3','ARCHIVED','2015-12-07 20:55:48',0),('2016_01_13_00_auth.sql','114527BCCB0DE286CBE6FDA3029DD0523D1037FA','ARCHIVED','2016-01-13 21:39:13',0),('2016_03_22_01_auth_2016_01_13_00_auth.sql','24615CC69B3CD7BB4699874647C35BA86E8A93FD','ARCHIVED','2016-03-22 22:55:13',0),('2016_03_28_00_auth.sql','BA14D23D81FA24565F04A359090DE86C5E195209','ARCHIVED','2016-03-28 16:49:32',0),('2016_04_11_00_auth.sql','0ACDD35EC9745231BCFA701B78056DEF94D0CC53','ARCHIVED','2016-04-11 02:24:14',30),('2016_04_17_00_auth.sql','83399B64D1221B56F73A0FFB51889F11A70521BC','ARCHIVED','2016-04-17 00:22:05',0),('2016_05_07_00_auth.sql','7E36DCC4F06FCDCDA7155AF3C5EDF8D3A720565F','ARCHIVED','2016-05-07 01:00:21',0),('2016_05_19_00_auth.sql','FB52E6BF35682CE6FA667B552B551F4FBD72AC30','ARCHIVED','2016-05-19 22:18:06',0),('2016_07_19_00_auth.sql','D5498F28A1E21F4AD0E0D7C2B96FCF7292C14C4D','ARCHIVED','2016-07-19 14:00:28',0),('2016_07_19_01_auth.sql','EBFE5D7D7E7CFA0CDA76AC49A1E8D4FA461A12BE','ARCHIVED','2016-07-19 16:06:39',0),('2016_07_23_00_auth.sql','1048F6A922ACD9BFC2E4518A71AF7037F79A85C4','ARCHIVED','2016-07-23 14:39:21',0),('2016_07_23_01_auth.sql','5897C7D8B8DE15895286FBCD1535FC75E1B70F62','ARCHIVED','2016-07-23 17:35:11',0),('2016_07_30_00_auth.sql','0FD4147840F7F02E2F1828A904B269F5B66097E0','ARCHIVED','2016-07-30 15:07:02',0),('2016_08_07_00_auth.sql','D9DD23851822E32E1312FFABEE2DB721C8651443','ARCHIVED','2016-08-07 15:33:42',0),('2016_08_11_00_auth.sql','0C79A86A4DFC53746BECF3D8A145482F94AE5FC9','ARCHIVED','2016-08-11 17:02:20',0),('2016_08_13_00_auth.sql','ED2286C4FF3D80D0F4DEE3D3121BCC15544470BE','ARCHIVED','2016-08-13 01:11:49',0),('2016_08_26_00_auth.sql','3C566371B6026EFEEA19CD215EC9F02C6DA9EAB3','ARCHIVED','2016-08-26 14:09:52',19),('2016_08_27_00_auth.sql','65ABEF7ACBCEA974C744ED42F95FBBD29226917B','ARCHIVED','2016-08-27 07:02:45',0),('2016_08_30_00_auth.sql','E16C19A938FE6370921658D2B713EE28A633FD56','ARCHIVED','2016-08-30 00:00:00',0),('2016_09_02_00_auth.sql','08932DAC4BDE74D3C39A43DDE404522F23EDD035','ARCHIVED','2016-09-02 00:00:00',0),('2016_09_03_00_auth_2016_05_11_00_auth.sql','401EFD3586772BDED66B4A944C20A1AC18A22D3A','ARCHIVED','2016-09-03 11:29:38',0),('2016_09_03_01_auth.sql','08B5ABCB74BBF25A30D37AF639F0EA1B10640673','ARCHIVED','2016-09-03 13:24:32',0),('2016_09_03_02_auth_2016_06_06_00_auth.sql','A0A8D73A952D0618833416513D53F73A70E7EA25','ARCHIVED','2016-09-03 15:56:50',0),('2016_09_03_03_auth.sql','9BF1C03EE39B6DC7E817BA46BE7D12A41AFBFDF7','ARCHIVED','2016-09-03 15:56:50',0),('2016_09_15_00_auth.sql','CD65F822AF1B5B7776E39804D0362F3E34AA6445','ARCHIVED','2016-09-15 16:30:36',0),('2016_09_21_00_auth.sql','57219A16B88080240EED94CDD41FC2764B8A32C5','ARCHIVED','2016-09-21 17:08:43',0),('2016_09_25_00_auth.sql','E811EFD8CE92ABEC5B8C02A09E643035939CF96D','ARCHIVED','2016-09-25 15:56:58',0),('2016_10_01_00_auth.sql','7C444FF1B03BA3C83472BDA409854754D052D6FB','ARCHIVED','2016-10-01 13:32:43',0),('2016_10_06_00_auth.sql','6A415F9813EFB5B95EB2AA2B326E1A6791E25EDB','ARCHIVED','2016-10-06 23:16:24',0),('2016_10_12_00_auth.sql','671D57BBA183AC70B9580DEE19B7EC046AF2EA87','ARCHIVED','2016-10-12 00:01:05',0),('2016_10_17_00_auth.sql','A0EF594CD73690D46A46031137DB0E895F079235','RELEASED','2016-10-16 16:33:05',19),('2016_10_25_00_auth.sql','5743FB1AC3F564FE4192DCFA90260BAD5E501882','RELEASED','2016-10-25 19:27:02',0),('2016_10_28_00_auth.sql','C1B9B1DD20B2183C6CB44CAED9B91BA7C63B8C49','RELEASED','2016-10-28 00:07:48',0),('2016_11_04_00_auth.sql','3F4FE06DCE019EB3223B5A6E0F80E2239078967F','RELEASED','2016-11-04 20:25:23',0),('2016_11_09_00_auth.sql','56432F8AEC2943A398A5B8B77843138B5B704257','RELEASED','2016-11-09 18:46:48',0),('2016_11_17_00_auth.sql','18E8F8FC93CC38755AB571638960AAFB98C0F3F1','RELEASED','2016-11-17 23:47:51',0),('2016_12_04_00_auth.sql','B1623681EAB651D2A091E3F4D4D4E476CF6D3AEA','RELEASED','2016-12-04 00:41:36',0),('2016_12_11_00_auth.sql','24CA34537DB697962DDD69EEE4BB5E79D2A573DA','RELEASED','2016-12-11 18:18:59',0),('2016_12_18_00_auth.sql','7AB53E033680CF7439F142EF83CD13E6F5D0ACB9','RELEASED','2016-12-18 12:15:48',0),('2017_01_14_00_auth.sql','1B514D1364042DB4CE68929EB54A94F86983441D','RELEASED','2017-01-14 20:50:47',0),('2017_01_26_00_auth.sql','723E1B69981A32A2F28A67C64902BA1AE7E98E48','RELEASED','2017-01-26 17:10:15',0);
+INSERT INTO `updates` VALUES ('2014_10_04_00_auth.sql','C3BC70A6EC381474B7308F442346F1E721176BC6','ARCHIVED','2015-03-21 16:55:52',0),('2014_10_19_00_auth.sql','7472B490A4F86C9D3DA609CDD3197499CB80C87C','ARCHIVED','2015-03-21 16:55:52',0),('2014_10_26_00_auth.sql','75CC67ADE2A3B2E54FD57D6B0DCAA8FE50F4EE35','ARCHIVED','2015-03-21 16:55:52',0),('2014_11_03_00_auth.sql','5948C9F286CF0FEA8E241785C0259FF36B73BDC5','ARCHIVED','2015-03-21 16:55:52',0),('2014_11_04_00_auth.sql','3AFC68B2375C2A417DDEA94583C53AFF83DE50DF','ARCHIVED','2015-03-21 16:55:52',0),('2014_11_09_00_auth.sql','B8DD1A7047C0FDDB80344B239343EC33BF1A0D97','ARCHIVED','2015-03-21 16:55:52',0),('2014_11_10_00_auth.sql','8FBA737A1D3FF4631A1E662A5B500A8BD304EC63','ARCHIVED','2015-03-21 16:55:52',0),('2014_11_10_00_auth_from_335.sql','0E3CB119442D09DD88E967015319BBC8DAFBBFE0','ARCHIVED','2015-03-21 16:55:52',0),('2014_11_10_01_auth.sql','327E77A1DA3546D5275AB249915DD57EDD6FDD3D','ARCHIVED','2015-03-21 16:55:52',0),('2014_11_23_00_auth.sql','0BBEB3EB3AED0FEF277A062819B6B2C00084A742','ARCHIVED','2015-03-21 16:55:52',0),('2014_11_25_00_auth.sql','4F45CDB26BDBB3EE83F1988E3D7818C5926ADC02','ARCHIVED','2015-03-21 16:55:52',0),('2014_12_05_00_auth.sql','6A7BBCEF43111C73A2D2C3CCB6911BE50DE7DD94','ARCHIVED','2015-03-21 16:55:52',0),('2014_12_10_00_auth.sql','821703A96D80F9080074852B5A46E2909C9562EA','ARCHIVED','2015-03-21 16:55:52',0),('2014_12_19_00_auth.sql','44D8E12FFF327AD07878FBDF8D9C16B6B7DCB122','ARCHIVED','2015-03-21 16:55:52',0),('2014_12_20_00_auth.sql','4DAA02AE285C02AE6C82EA2C8B97AC71990F1085','ARCHIVED','2015-03-21 16:55:52',0),('2014_12_25_00_auth.sql','61411930F482BC73FC7FD2C370C811E944F5FF92','ARCHIVED','2015-03-21 16:55:52',0),('2014_12_27_00_auth.sql','CE2E5D2CD82E79C25294539ADED27A1429105B43','ARCHIVED','2015-03-21 16:55:52',0),('2014_12_28_00_auth.sql','0A913217610E76AFF119C27259737BBC523090E6','ARCHIVED','2015-03-21 16:55:52',0),('2015_02_22_00_auth.sql','21CCCF8B01252E16CA3D6C9E3E8DAA4C9B28ED6E','ARCHIVED','2015-03-21 16:55:52',0),('2015_03_01_00_auth.sql','911881E273207FF6182D1FDAC8C85FFAE8F1C852','ARCHIVED','2015-03-21 16:55:52',0),('2015_03_10_00_auth.sql','2CC8502C11412EFEB5C11BE166761A8754A59009','ARCHIVED','2015-03-21 16:55:52',0),('2015_03_20_00_auth.sql','B761760804EA73BD297F296C5C1919687DF7191C','ARCHIVED','2015-03-21 16:55:52',0),('2015_03_20_01_auth.sql','5CCEDF20C8189FB1E8DF064A9F0DDC342841FBF0','ARCHIVED','2015-03-21 16:55:52',0),('2015_03_20_02_auth.sql','85E4ACD9AA099C0C4AC034575F2BB07D348EAC72','ARCHIVED','2015-03-21 16:56:46',0),('2015_03_15_00_auth.sql','1D8E107FBEFE5E7F47E09F45240DFF499B77CDED','ARCHIVED','2015-05-02 13:57:57',0),('2015_03_26_00_auth.sql','34AC8543E6A9C6C832DE58EAB33618EEEF70B9F9','ARCHIVED','2015-05-02 13:57:57',0),('2015_04_04_00_auth.sql','57146B35E54A2EC7869C945034AB078358020311','ARCHIVED','2015-05-02 13:57:57',0),('2015_04_06_00_auth.sql','2A8049DC2923420A002D42FB6F02C2FFCC5CDD22','ARCHIVED','2015-05-02 13:57:57',0),('2015_04_08_00_auth.sql','4D7D8EEF285C982BB676836602266501BEC26764','ARCHIVED','2015-05-02 13:57:57',0),('2015_04_10_00_auth.sql','4AE68FD97A95CEE5143EA20FD33F5D557367AC1F','ARCHIVED','2015-05-02 13:57:57',0),('2015_04_11_00_auth.sql','80A71C8921CFEBB547D264558B6DE27201685B84','ARCHIVED','2015-05-02 13:57:57',0),('2015_04_11_01_auth.sql','3E88183E1A85D11BFD74CF9A32A725C44AE02EEC','ARCHIVED','2015-05-02 13:57:57',0),('2015_04_21_00_auth.sql','1B3B48DBA06368B985C548D166C515C9DD598CB9','ARCHIVED','2015-05-02 13:57:57',0),('2015_05_02_00_auth.sql','96AB595E0D2A088750E3F48B0AF0A8A14F3CFE1E','ARCHIVED','2015-05-02 13:57:57',0),('2015_05_02_01_auth.sql','FB11FB834E488B0FD3AFDABCC1A3113092E7C2E5','ARCHIVED','2015-05-02 13:57:57',0),('2015_07_02_00_auth.sql','E5EE3842AB9B01851E49B360FBAF6FFEEAB2A8DA','ARCHIVED','2015-07-10 19:30:56',0),('2015_07_06_00_auth.sql','6D1ADBA496DC6E6D7B3BF887DA8D4D17D3FBACE0','ARCHIVED','2015-07-10 19:30:56',0),('2015_07_08_00_auth.sql','CB54020AFD1E31742FD8BF9CE16879625E289788','ARCHIVED','2015-07-10 19:30:56',0),('2015_07_08_01_auth.sql','74D281CB82E0DA36D628BDC7AC797AE5498DB461','ARCHIVED','2015-07-10 19:30:56',0),('2015_07_16_00_auth.sql','A057E95B5553B6A57A1642FE3FEC8E2E62EDE3C6','ARCHIVED','2015-10-10 08:30:48',0),('2015_07_29_00_auth.sql','0000FECBC413E96C7C45F303D162E263EFBA7116','ARCHIVED','2015-10-10 08:30:48',0),('2015_08_26_00_auth.sql','3071C02A2EB7DCBF4CEE10279FEFAB7C29A43A3A','ARCHIVED','2015-10-10 08:30:48',0),('2015_09_05_00_auth.sql','F765D82B37873FA67447347D5B83C99C159FB452','ARCHIVED','2015-10-10 08:30:48',0),('2015_09_05_01_auth.sql','97A72DBCBF14D27A1863834A22296905FF276086','ARCHIVED','2015-10-10 08:30:48',0),('2015_09_09_00_auth.sql','495A0CF1B1C49205D4A5D3C25A4E1EB95616D6B4','ARCHIVED','2015-10-10 08:30:48',0),('2015_09_15_00_auth.sql','D1FEFDA4C98F30384DF4B64D5A53187303EB5786','ARCHIVED','2015-10-10 08:30:48',0),('2015_10_09_00_auth.sql','B6D643D444C6AE711503F73B96B6252A852913D6','ARCHIVED','2015-10-10 08:30:48',0),('2015_10_16_00_auth.sql','366AFFD1088762866091A81CE1EC64138B8B35F1','ARCHIVED','2015-11-08 00:46:02',62),('2015_10_17_00_auth.sql','AC0D45E905033F42093852D2C4476663BDACCB3D','ARCHIVED','2015-10-17 12:39:12',0),('2015_11_01_00_auth_2015_08_21_00.sql','C31A9E1D28E11B60BE8F8198637DD51F6D75123F','ARCHIVED','2015-11-01 14:50:26',0),('2015_11_08_00_auth.sql','0ACDD35EC9745231BCFA701B78056DEF94D0CC53','ARCHIVED','2015-11-08 00:51:45',0),('2015_11_21_00_auth.sql','575A1D697CC6C7C517F7CCB950988267C99CE7FA','ARCHIVED','2015-11-21 21:25:38',0),('2015_12_07_00_auth.sql','24A07AC1F38E5D26A3599FC06D29E267418F69F3','ARCHIVED','2015-12-07 20:55:48',0),('2016_01_13_00_auth.sql','114527BCCB0DE286CBE6FDA3029DD0523D1037FA','ARCHIVED','2016-01-13 21:39:13',0),('2016_03_22_01_auth_2016_01_13_00_auth.sql','24615CC69B3CD7BB4699874647C35BA86E8A93FD','ARCHIVED','2016-03-22 22:55:13',0),('2016_03_28_00_auth.sql','BA14D23D81FA24565F04A359090DE86C5E195209','ARCHIVED','2016-03-28 16:49:32',0),('2016_04_11_00_auth.sql','0ACDD35EC9745231BCFA701B78056DEF94D0CC53','ARCHIVED','2016-04-11 02:24:14',30),('2016_04_17_00_auth.sql','83399B64D1221B56F73A0FFB51889F11A70521BC','ARCHIVED','2016-04-17 00:22:05',0),('2016_05_07_00_auth.sql','7E36DCC4F06FCDCDA7155AF3C5EDF8D3A720565F','ARCHIVED','2016-05-07 01:00:21',0),('2016_05_19_00_auth.sql','FB52E6BF35682CE6FA667B552B551F4FBD72AC30','ARCHIVED','2016-05-19 22:18:06',0),('2016_07_19_00_auth.sql','D5498F28A1E21F4AD0E0D7C2B96FCF7292C14C4D','ARCHIVED','2016-07-19 14:00:28',0),('2016_07_19_01_auth.sql','EBFE5D7D7E7CFA0CDA76AC49A1E8D4FA461A12BE','ARCHIVED','2016-07-19 16:06:39',0),('2016_07_23_00_auth.sql','1048F6A922ACD9BFC2E4518A71AF7037F79A85C4','ARCHIVED','2016-07-23 14:39:21',0),('2016_07_23_01_auth.sql','5897C7D8B8DE15895286FBCD1535FC75E1B70F62','ARCHIVED','2016-07-23 17:35:11',0),('2016_07_30_00_auth.sql','0FD4147840F7F02E2F1828A904B269F5B66097E0','ARCHIVED','2016-07-30 15:07:02',0),('2016_08_07_00_auth.sql','D9DD23851822E32E1312FFABEE2DB721C8651443','ARCHIVED','2016-08-07 15:33:42',0),('2016_08_11_00_auth.sql','0C79A86A4DFC53746BECF3D8A145482F94AE5FC9','ARCHIVED','2016-08-11 17:02:20',0),('2016_08_13_00_auth.sql','ED2286C4FF3D80D0F4DEE3D3121BCC15544470BE','ARCHIVED','2016-08-13 01:11:49',0),('2016_08_26_00_auth.sql','3C566371B6026EFEEA19CD215EC9F02C6DA9EAB3','ARCHIVED','2016-08-26 14:09:52',19),('2016_08_27_00_auth.sql','65ABEF7ACBCEA974C744ED42F95FBBD29226917B','ARCHIVED','2016-08-27 07:02:45',0),('2016_08_30_00_auth.sql','E16C19A938FE6370921658D2B713EE28A633FD56','ARCHIVED','2016-08-30 00:00:00',0),('2016_09_02_00_auth.sql','08932DAC4BDE74D3C39A43DDE404522F23EDD035','ARCHIVED','2016-09-02 00:00:00',0),('2016_09_03_00_auth_2016_05_11_00_auth.sql','401EFD3586772BDED66B4A944C20A1AC18A22D3A','ARCHIVED','2016-09-03 11:29:38',0),('2016_09_03_01_auth.sql','08B5ABCB74BBF25A30D37AF639F0EA1B10640673','ARCHIVED','2016-09-03 13:24:32',0),('2016_09_03_02_auth_2016_06_06_00_auth.sql','A0A8D73A952D0618833416513D53F73A70E7EA25','ARCHIVED','2016-09-03 15:56:50',0),('2016_09_03_03_auth.sql','9BF1C03EE39B6DC7E817BA46BE7D12A41AFBFDF7','ARCHIVED','2016-09-03 15:56:50',0),('2016_09_15_00_auth.sql','CD65F822AF1B5B7776E39804D0362F3E34AA6445','ARCHIVED','2016-09-15 16:30:36',0),('2016_09_21_00_auth.sql','57219A16B88080240EED94CDD41FC2764B8A32C5','ARCHIVED','2016-09-21 17:08:43',0),('2016_09_25_00_auth.sql','E811EFD8CE92ABEC5B8C02A09E643035939CF96D','ARCHIVED','2016-09-25 15:56:58',0),('2016_10_01_00_auth.sql','7C444FF1B03BA3C83472BDA409854754D052D6FB','ARCHIVED','2016-10-01 13:32:43',0),('2016_10_06_00_auth.sql','6A415F9813EFB5B95EB2AA2B326E1A6791E25EDB','ARCHIVED','2016-10-06 23:16:24',0),('2016_10_12_00_auth.sql','671D57BBA183AC70B9580DEE19B7EC046AF2EA87','ARCHIVED','2016-10-12 00:01:05',0),('2016_10_17_00_auth.sql','A0EF594CD73690D46A46031137DB0E895F079235','RELEASED','2016-10-16 16:33:05',19),('2016_10_25_00_auth.sql','5743FB1AC3F564FE4192DCFA90260BAD5E501882','RELEASED','2016-10-25 19:27:02',0),('2016_10_28_00_auth.sql','C1B9B1DD20B2183C6CB44CAED9B91BA7C63B8C49','RELEASED','2016-10-28 00:07:48',0),('2016_11_04_00_auth.sql','3F4FE06DCE019EB3223B5A6E0F80E2239078967F','RELEASED','2016-11-04 20:25:23',0),('2016_11_09_00_auth.sql','56432F8AEC2943A398A5B8B77843138B5B704257','RELEASED','2016-11-09 18:46:48',0),('2016_11_17_00_auth.sql','18E8F8FC93CC38755AB571638960AAFB98C0F3F1','RELEASED','2016-11-17 23:47:51',0),('2016_12_04_00_auth.sql','B1623681EAB651D2A091E3F4D4D4E476CF6D3AEA','RELEASED','2016-12-04 00:41:36',0),('2016_12_11_00_auth.sql','24CA34537DB697962DDD69EEE4BB5E79D2A573DA','RELEASED','2016-12-11 18:18:59',0),('2016_12_18_00_auth.sql','7AB53E033680CF7439F142EF83CD13E6F5D0ACB9','RELEASED','2016-12-18 12:15:48',0),('2017_01_14_00_auth.sql','1B514D1364042DB4CE68929EB54A94F86983441D','RELEASED','2017-01-14 20:50:47',0),('2017_01_26_00_auth.sql','723E1B69981A32A2F28A67C64902BA1AE7E98E48','RELEASED','2017-01-26 17:10:15',0),('2017_01_29_00_auth.sql','B76C514678903F540302505AF66886F7D2C89E30','RELEASED','2017-01-29 00:00:00',0);
/*!40000 ALTER TABLE `updates` ENABLE KEYS */;
UNLOCK TABLES;
diff --git a/sql/updates/auth/master/2017_01_29_00_auth.sql b/sql/updates/auth/master/2017_01_29_00_auth.sql
new file mode 100644
index 00000000000..53397d5d880
--- /dev/null
+++ b/sql/updates/auth/master/2017_01_29_00_auth.sql
@@ -0,0 +1,9 @@
+SET @PERMISSION := 851;
+
+DELETE FROM `rbac_permissions` WHERE `id` = @PERMISSION;
+INSERT INTO `rbac_permissions` (`id`, `name`) VALUES
+(@PERMISSION, 'Command: reload areatrigger_templates' );
+
+DELETE FROM `rbac_linked_permissions` WHERE `id` = 192 AND `linkedId` = @PERMISSION;
+INSERT INTO `rbac_linked_permissions` (`id`, `linkedId`) VALUES
+(192, @PERMISSION);
diff --git a/sql/updates/world/master/2017_01_29_00_world.sql b/sql/updates/world/master/2017_01_29_00_world.sql
new file mode 100644
index 00000000000..6d99c38435f
--- /dev/null
+++ b/sql/updates/world/master/2017_01_29_00_world.sql
@@ -0,0 +1,62 @@
+DROP TABLE IF EXISTS `areatrigger_template`;
+CREATE TABLE `areatrigger_template` (
+ `Id` int(10) unsigned NOT NULL,
+ `Type` tinyint(3) unsigned NOT NULL DEFAULT '0',
+ `Flags` int(10) unsigned NOT NULL DEFAULT '0',
+ `Data0` float NOT NULL DEFAULT '0',
+ `Data1` float NOT NULL DEFAULT '0',
+ `Data2` float NOT NULL DEFAULT '0',
+ `Data3` float NOT NULL DEFAULT '0',
+ `Data4` float NOT NULL DEFAULT '0',
+ `Data5` float NOT NULL DEFAULT '0',
+ `ScriptName` char(64) NOT NULL DEFAULT '',
+ `VerifiedBuild` int(10) unsigned NOT NULL DEFAULT '0',
+ PRIMARY KEY (`Id`)
+) ENGINE=MyISAM DEFAULT CHARSET=utf8;
+
+DROP TABLE IF EXISTS `areatrigger_template_polygon_vertices`;
+CREATE TABLE `areatrigger_template_polygon_vertices` (
+ `AreaTriggerId` int(10) unsigned NOT NULL,
+ `Idx` int(10) unsigned NOT NULL,
+ `VerticeX` float NOT NULL DEFAULT '0',
+ `VerticeY` float NOT NULL DEFAULT '0',
+ `VerticeTargetX` float NULL,
+ `VerticeTargetY` float NULL,
+ `VerifiedBuild` int(10) unsigned NOT NULL DEFAULT '0',
+ PRIMARY KEY (`AreaTriggerId`,`Idx`)
+) ENGINE=MyISAM DEFAULT CHARSET=utf8;
+
+DROP TABLE IF EXISTS `areatrigger_template_actions`;
+CREATE TABLE `areatrigger_template_actions` (
+ `AreaTriggerId` int(10) unsigned NOT NULL,
+ `ActionType` int(10) unsigned NOT NULL,
+ `ActionParam` int(10) unsigned NOT NULL,
+ `TargetType` int(10) unsigned NOT NULL DEFAULT '0',
+ PRIMARY KEY (`AreaTriggerId`, `ActionType`, `ActionParam`)
+) ENGINE=MyISAM DEFAULT CHARSET=utf8;
+
+DROP TABLE IF EXISTS `spell_areatrigger`;
+CREATE TABLE `spell_areatrigger` (
+ `SpellMiscId` int(10) unsigned NOT NULL,
+ `AreaTriggerId` int(10) unsigned NOT NULL,
+ `MoveCurveId` int(10) unsigned NOT NULL DEFAULT '0',
+ `ScaleCurveId` int(10) unsigned NOT NULL DEFAULT '0',
+ `MorphCurveId` int(10) unsigned NOT NULL DEFAULT '0',
+ `FacingCurveId` int(10) unsigned NOT NULL DEFAULT '0',
+ `DecalPropertiesId` int(10) unsigned NOT NULL DEFAULT '0',
+ `TimeToTarget` int(10) unsigned NOT NULL DEFAULT '0',
+ `TimeToTargetScale` int(10) unsigned NOT NULL DEFAULT '0',
+ `VerifiedBuild` int(10) unsigned NOT NULL DEFAULT '0',
+ PRIMARY KEY (`SpellMiscId`)
+) ENGINE=MyISAM DEFAULT CHARSET=utf8;
+
+DROP TABLE IF EXISTS `spell_areatrigger_splines`;
+CREATE TABLE `spell_areatrigger_splines` (
+ `SpellMiscId` int(10) unsigned NOT NULL,
+ `Idx` int(10) unsigned NOT NULL,
+ `X` float NOT NULL DEFAULT '0',
+ `Y` float NOT NULL DEFAULT '0',
+ `Z` float NOT NULL DEFAULT '0',
+ `VerifiedBuild` int(10) unsigned NOT NULL DEFAULT '0',
+ PRIMARY KEY (`SpellMiscId`,`Idx`)
+) ENGINE=MyISAM DEFAULT CHARSET=utf8;
diff --git a/src/server/game/AI/CreatureAI.h b/src/server/game/AI/CreatureAI.h
index c9c43ef7d9d..007f6ceabc8 100644
--- a/src/server/game/AI/CreatureAI.h
+++ b/src/server/game/AI/CreatureAI.h
@@ -136,6 +136,10 @@ class TC_GAME_API CreatureAI : public UnitAI
virtual void JustRegisteredDynObject(DynamicObject* /*dynObject*/) { }
virtual void JustUnregisteredDynObject(DynamicObject* /*dynObject*/) { }
+ // Called when the creature successfully registers an areatrigger
+ virtual void JustRegisteredAreaTrigger(AreaTrigger* /*areaTrigger*/) { }
+ virtual void JustUnregisteredAreaTrigger(AreaTrigger* /*areaTrigger*/) { }
+
// Called when hit by a spell
virtual void SpellHit(Unit* /*caster*/, SpellInfo const* /*spell*/) { }
diff --git a/src/server/game/Accounts/RBAC.h b/src/server/game/Accounts/RBAC.h
index a053a9e86bf..9fd7d4d3a70 100644
--- a/src/server/game/Accounts/RBAC.h
+++ b/src/server/game/Accounts/RBAC.h
@@ -755,6 +755,7 @@ enum RBACPermissions
RBAC_PERM_COMMAND_SCENE_CANCEL = 848,
RBAC_PERM_COMMAND_LIST_SCENES = 849,
RBAC_PERM_COMMAND_RELOAD_SCENE_TEMPLATE = 850,
+ RBAC_PERM_COMMAND_RELOAD_AREATRIGGER_TEMPLATE = 851,
// custom permissions 1000+
RBAC_PERM_MAX
diff --git a/src/server/game/DataStores/DB2Stores.h b/src/server/game/DataStores/DB2Stores.h
index f20ba89a6c0..94999b10ba6 100644
--- a/src/server/game/DataStores/DB2Stores.h
+++ b/src/server/game/DataStores/DB2Stores.h
@@ -58,6 +58,7 @@ TC_GAME_API extern DB2Storage<CreatureTypeEntry> sCreatureTyp
TC_GAME_API extern DB2Storage<CriteriaEntry> sCriteriaStore;
TC_GAME_API extern DB2Storage<CriteriaTreeEntry> sCriteriaTreeStore;
TC_GAME_API extern DB2Storage<CurrencyTypesEntry> sCurrencyTypesStore;
+TC_GAME_API extern DB2Storage<CurveEntry> sCurveStore;
TC_GAME_API extern DB2Storage<DestructibleModelDataEntry> sDestructibleModelDataStore;
TC_GAME_API extern DB2Storage<DifficultyEntry> sDifficultyStore;
TC_GAME_API extern DB2Storage<DungeonEncounterEntry> sDungeonEncounterStore;
diff --git a/src/server/game/Entities/AreaTrigger/AreaTrigger.cpp b/src/server/game/Entities/AreaTrigger/AreaTrigger.cpp
index 8de274cb4bd..4393d15a401 100644
--- a/src/server/game/Entities/AreaTrigger/AreaTrigger.cpp
+++ b/src/server/game/Entities/AreaTrigger/AreaTrigger.cpp
@@ -16,18 +16,33 @@
*/
#include "AreaTrigger.h"
+#include "AreaTriggerDataStore.h"
+#include "AreaTriggerPackets.h"
+#include "AreaTriggerTemplate.h"
+#include "CellImpl.h"
+#include "Chat.h"
#include "DB2Stores.h"
+#include "GridNotifiersImpl.h"
+#include "Language.h"
#include "Log.h"
+#include "Object.h"
+#include "ObjectAccessor.h"
+#include "Player.h"
+#include "ScriptMgr.h"
#include "SpellInfo.h"
+#include "Transport.h"
#include "Unit.h"
#include "UpdateData.h"
-AreaTrigger::AreaTrigger() : WorldObject(false), _duration(0), _spellXSpellVisualId(0)
+AreaTrigger::AreaTrigger() : WorldObject(false), MapObject(),
+ _duration(0), _totalDuration(0), _timeSinceCreated(0), _previousCheckOrientation(std::numeric_limits<float>::infinity()),
+ _isRemoved(false), _reachedDestination(true), _lastSplineIndex(0), _movementTime(0),
+ _areaTriggerMiscTemplate(nullptr)
{
m_objectType |= TYPEMASK_AREATRIGGER;
m_objectTypeId = TYPEID_AREATRIGGER;
- m_updateFlag = UPDATEFLAG_STATIONARY_POSITION;
+ m_updateFlag = UPDATEFLAG_STATIONARY_POSITION | UPDATEFLAG_AREATRIGGER;
m_valuesCount = AREATRIGGER_END;
_dynamicValuesCount = AREATRIGGER_DYNAMIC_END;
@@ -57,52 +72,619 @@ void AreaTrigger::RemoveFromWorld()
}
}
-bool AreaTrigger::CreateAreaTrigger(ObjectGuid::LowType guidlow, uint32 triggerEntry, Unit* caster, SpellInfo const* spell, Position const& pos, uint32 spellXSpellVisualId)
+bool AreaTrigger::CreateAreaTrigger(uint32 spellMiscId, Unit* caster, Unit* target, SpellInfo const* spell, Position const& pos, int32 duration, uint32 spellXSpellVisualId, ObjectGuid const& castId /*= ObjectGuid::Empty*/)
{
- _spellXSpellVisualId = spellXSpellVisualId;
+ _targetGuid = target ? target->GetGUID() : ObjectGuid::Empty;
+
SetMap(caster->GetMap());
Relocate(pos);
if (!IsPositionValid())
{
- TC_LOG_ERROR("misc", "AreaTrigger (spell %u) not created. Invalid coordinates (X: %f Y: %f)", spell->Id, GetPositionX(), GetPositionY());
+ TC_LOG_ERROR("entities.areatrigger", "AreaTrigger (spellMiscId %u) not created. Invalid coordinates (X: %f Y: %f)", spellMiscId, GetPositionX(), GetPositionY());
return false;
}
- Object::_Create(ObjectGuid::Create<HighGuid::AreaTrigger>(GetMapId(), triggerEntry, guidlow));
+ _areaTriggerMiscTemplate = sAreaTriggerDataStore->GetAreaTriggerMiscTemplate(spellMiscId);
+ if (!_areaTriggerMiscTemplate)
+ {
+ TC_LOG_ERROR("entities.areatrigger", "AreaTrigger (spellMiscId %u) not created. Invalid areatrigger miscid (%u)", spellMiscId, spellMiscId);
+ return false;
+ }
+
+ Object::_Create(ObjectGuid::Create<HighGuid::AreaTrigger>(GetMapId(), GetTemplate()->Id, caster->GetMap()->GenerateLowGuid<HighGuid::AreaTrigger>()));
SetPhaseMask(caster->GetPhaseMask(), false);
- SetEntry(triggerEntry);
- SetDuration(spell->GetDuration());
- SetObjectScale(1);
+ SetEntry(GetTemplate()->Id);
+ SetDuration(duration);
+
+ SetObjectScale(1.0f);
SetGuidValue(AREATRIGGER_CASTER, caster->GetGUID());
+ SetGuidValue(AREATRIGGER_CREATING_EFFECT_GUID, castId);
+
SetUInt32Value(AREATRIGGER_SPELLID, spell->Id);
SetUInt32Value(AREATRIGGER_SPELL_X_SPELL_VISUAL_ID, spellXSpellVisualId);
- SetUInt32Value(AREATRIGGER_DURATION, spell->GetDuration());
+ uint32 timeToTarget = GetMiscTemplate()->TimeToTarget != 0 ? GetMiscTemplate()->TimeToTarget : GetUInt32Value(AREATRIGGER_DURATION);
+ SetUInt32Value(AREATRIGGER_TIME_TO_TARGET_SCALE, GetMiscTemplate()->TimeToTargetScale != 0 ? GetMiscTemplate()->TimeToTargetScale : GetUInt32Value(AREATRIGGER_DURATION));
+ SetFloatValue(AREATRIGGER_BOUNDS_RADIUS_2D, GetTemplate()->MaxSearchRadius);
+ SetUInt32Value(AREATRIGGER_DECAL_PROPERTIES_ID, GetMiscTemplate()->DecalPropertiesId);
CopyPhaseFrom(caster);
+ if (target && GetTemplate()->HasFlag(AREATRIGGER_FLAG_HAS_ATTACHED))
+ {
+ m_movementInfo.transport.guid = target->GetGUID();
+ }
+
+ UpdateShape();
+
+ if (GetMiscTemplate()->HasSplines())
+ InitSplineOffsets(GetMiscTemplate()->SplinePoints, timeToTarget);
+
+ sScriptMgr->OnAreaTriggerEntityInitialize(this);
+
+ // movement on transport of areatriggers on unit is handled by themself
+ Transport* transport = m_movementInfo.transport.guid.IsEmpty() ? caster->GetTransport() : nullptr;
+ if (transport)
+ {
+ float x, y, z, o;
+ pos.GetPosition(x, y, z, o);
+ transport->CalculatePassengerOffset(x, y, z, &o);
+ m_movementInfo.transport.pos.Relocate(x, y, z, o);
+
+ // This object must be added to transport before adding to map for the client to properly display it
+ transport->AddPassenger(this);
+ }
+
if (!GetMap()->AddToMap(this))
+ {
+ // Returning false will cause the object to be deleted - remove from transport
+ if (transport)
+ transport->RemovePassenger(this);
return false;
+ }
+
+ caster->_RegisterAreaTrigger(this);
+
+ sScriptMgr->OnAreaTriggerEntityCreate(this);
return true;
}
void AreaTrigger::Update(uint32 p_time)
{
- if (GetDuration() > int32(p_time))
- _duration -= p_time;
+ WorldObject::Update(p_time);
+ _timeSinceCreated += p_time;
+
+ if (GetTemplate()->HasFlag(AREATRIGGER_FLAG_HAS_ATTACHED))
+ {
+ if (Unit* target = GetTarget())
+ GetMap()->AreaTriggerRelocation(this, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), target->GetOrientation());
+ }
else
- Remove(); // expired
+ UpdateSplinePosition(p_time);
- WorldObject::Update(p_time);
+ sScriptMgr->OnAreaTriggerEntityUpdate(this, p_time);
+
+ if (GetDuration() != -1)
+ {
+ if (GetDuration() > int32(p_time))
+ _UpdateDuration(_duration - p_time);
+ else
+ {
+ Remove(); // expired
+ return;
+ }
+ }
+
+ UpdateTargetList();
}
void AreaTrigger::Remove()
{
if (IsInWorld())
{
+ _isRemoved = true;
+
+ if (Unit* caster = GetCaster())
+ caster->_UnregisterAreaTrigger(this);
+
+ // Handle removal of all units, calling OnUnitExit & deleting auras if needed
+ HandleUnitEnterExit({});
+
+ sScriptMgr->OnAreaTriggerEntityRemove(this);
+
RemoveFromWorld();
AddObjectToRemoveList();
}
}
+
+void AreaTrigger::SetDuration(int32 newDuration)
+{
+ _duration = newDuration;
+ _totalDuration = newDuration;
+
+ // negative duration (permanent areatrigger) sent as 0
+ SetUInt32Value(AREATRIGGER_DURATION, std::max(newDuration, 0));
+}
+
+void AreaTrigger::_UpdateDuration(int32 newDuration)
+{
+ _duration = newDuration;
+
+ // should be sent in object create packets only
+ m_uint32Values[AREATRIGGER_DURATION] = _duration;
+}
+
+float AreaTrigger::GetProgress() const
+{
+ return GetTimeSinceCreated() < GetTimeToTargetScale() ? float(GetTimeSinceCreated()) / float(GetTimeToTargetScale()) : 1.0f;
+}
+
+void AreaTrigger::UpdateTargetList()
+{
+ std::list<Unit*> targetList;
+
+ switch (GetTemplate()->Type)
+ {
+ case AREATRIGGER_TYPE_SPHERE:
+ SearchUnitInSphere(targetList);
+ break;
+ case AREATRIGGER_TYPE_BOX:
+ SearchUnitInBox(targetList);
+ break;
+ case AREATRIGGER_TYPE_POLYGON:
+ SearchUnitInPolygon(targetList);
+ break;
+ case AREATRIGGER_TYPE_CYLINDER:
+ SearchUnitInCylinder(targetList);
+ break;
+ default:
+ break;
+ }
+
+ HandleUnitEnterExit(targetList);
+}
+
+void AreaTrigger::SearchUnitInSphere(std::list<Unit*>& targetList)
+{
+ float radius = GetTemplate()->SphereDatas.Radius;
+ if (GetTemplate()->HasFlag(AREATRIGGER_FLAG_HAS_DYNAMIC_SHAPE))
+ {
+ if (GetMiscTemplate()->MorphCurveId)
+ {
+ radius = G3D::lerp(GetTemplate()->SphereDatas.Radius,
+ GetTemplate()->SphereDatas.RadiusTarget,
+ sDB2Manager.GetCurveValueAt(GetMiscTemplate()->MorphCurveId, GetProgress()));
+ }
+ }
+
+ Trinity::AnyUnitInObjectRangeCheck check(this, radius);
+ Trinity::UnitListSearcher<Trinity::AnyUnitInObjectRangeCheck> searcher(this, targetList, check);
+ VisitNearbyObject(GetTemplate()->MaxSearchRadius, searcher);
+}
+
+void AreaTrigger::SearchUnitInBox(std::list<Unit*>& targetList)
+{
+ float extentsX = GetTemplate()->BoxDatas.Extents[0];
+ float extentsY = GetTemplate()->BoxDatas.Extents[1];
+ float extentsZ = GetTemplate()->BoxDatas.Extents[2];
+
+ Trinity::AnyUnitInObjectRangeCheck check(this, GetTemplate()->MaxSearchRadius, false);
+ Trinity::UnitListSearcher<Trinity::AnyUnitInObjectRangeCheck> searcher(this, targetList, check);
+ VisitNearbyObject(GetTemplate()->MaxSearchRadius, searcher);
+
+ float halfExtentsX = extentsX / 2.0f;
+ float halfExtentsY = extentsY / 2.0f;
+ float halfExtentsZ = extentsZ / 2.0f;
+
+ float minX = GetPositionX() - halfExtentsX;
+ float maxX = GetPositionX() + halfExtentsX;
+
+ float minY = GetPositionY() - halfExtentsY;
+ float maxY = GetPositionY() + halfExtentsY;
+
+ float minZ = GetPositionZ() - halfExtentsZ;
+ float maxZ = GetPositionZ() + halfExtentsZ;
+
+ G3D::AABox const box({ minX, minY, minZ }, { maxX, maxY, maxZ });
+
+ targetList.remove_if([&box](Unit* unit) -> bool
+ {
+ return !box.contains({ unit->GetPositionX(), unit->GetPositionY(), unit->GetPositionZ() });
+ });
+}
+
+void AreaTrigger::SearchUnitInPolygon(std::list<Unit*>& targetList)
+{
+ Trinity::AnyUnitInObjectRangeCheck check(this, GetTemplate()->MaxSearchRadius, false);
+ Trinity::UnitListSearcher<Trinity::AnyUnitInObjectRangeCheck> searcher(this, targetList, check);
+ VisitNearbyObject(GetTemplate()->MaxSearchRadius, searcher);
+
+ float height = GetTemplate()->PolygonDatas.Height;
+ float minZ = GetPositionZ() - height;
+ float maxZ = GetPositionZ() + height;
+
+ targetList.remove_if([this, minZ, maxZ](Unit* unit) -> bool
+ {
+ return !CheckIsInPolygon2D(unit)
+ || unit->GetPositionZ() < minZ
+ || unit->GetPositionZ() > maxZ;
+ });
+}
+
+void AreaTrigger::SearchUnitInCylinder(std::list<Unit*>& targetList)
+{
+ Trinity::AnyUnitInObjectRangeCheck check(this, GetTemplate()->MaxSearchRadius, false);
+ Trinity::UnitListSearcher<Trinity::AnyUnitInObjectRangeCheck> searcher(this, targetList, check);
+ VisitNearbyObject(GetTemplate()->MaxSearchRadius, searcher);
+
+ float height = GetTemplate()->CylinderDatas.Height;
+ float minZ = GetPositionZ() - height;
+ float maxZ = GetPositionZ() + height;
+
+ targetList.remove_if([minZ, maxZ](Unit* unit) -> bool
+ {
+ return unit->GetPositionZ() < minZ
+ || unit->GetPositionZ() > maxZ;
+ });
+}
+
+void AreaTrigger::HandleUnitEnterExit(std::list<Unit*> const& newTargetList)
+{
+ GuidUnorderedSet exitUnits = _insideUnits;
+ _insideUnits.clear();
+
+ std::vector<Unit*> enteringUnits;
+
+ for (Unit* unit : newTargetList)
+ {
+ if (exitUnits.erase(unit->GetGUID()) == 0) // erase(key_type) returns number of elements erased
+ enteringUnits.push_back(unit);
+
+ _insideUnits.insert(unit->GetGUID());
+ }
+
+ // Handle after _insideUnits have been reinserted so we can use GetInsideUnits() in hooks
+ for (Unit* unit : enteringUnits)
+ {
+ if (Player* player = unit->ToPlayer())
+ if (player->isDebugAreaTriggers)
+ ChatHandler(player->GetSession()).PSendSysMessage(LANG_DEBUG_AREATRIGGER_ENTERED, GetTemplate()->Id);
+
+ DoActions(unit);
+ sScriptMgr->OnAreaTriggerEntityUnitEnter(this, unit);
+ }
+
+ for (ObjectGuid const& exitUnitGuid : exitUnits)
+ {
+ if (Unit* leavingUnit = ObjectAccessor::GetUnit(*this, exitUnitGuid))
+ {
+ if (Player* player = leavingUnit->ToPlayer())
+ if (player->isDebugAreaTriggers)
+ ChatHandler(player->GetSession()).PSendSysMessage(LANG_DEBUG_AREATRIGGER_LEFT, GetTemplate()->Id);
+
+ UndoActions(leavingUnit);
+ sScriptMgr->OnAreaTriggerEntityUnitExit(this, leavingUnit);
+ }
+ }
+}
+
+AreaTriggerTemplate const* AreaTrigger::GetTemplate() const
+{
+ return _areaTriggerMiscTemplate->Template;
+}
+
+uint32 AreaTrigger::GetScriptId() const
+{
+ return GetTemplate()->ScriptId;
+}
+
+Unit* AreaTrigger::GetCaster() const
+{
+ return ObjectAccessor::GetUnit(*this, GetCasterGuid());
+}
+
+Unit* AreaTrigger::GetTarget() const
+{
+ return ObjectAccessor::GetUnit(*this, _targetGuid);
+}
+
+void AreaTrigger::UpdatePolygonOrientation()
+{
+ float newOrientation = GetOrientation();
+
+ // No need to recalculate, orientation didn't change
+ if (G3D::fuzzyEq(_previousCheckOrientation, newOrientation))
+ return;
+
+ _polygonVertices = GetTemplate()->PolygonVertices;
+
+ float angleSin = std::sin(newOrientation);
+ float angleCos = std::cos(newOrientation);
+
+ // This is needed to rotate the vertices, following orientation
+ for (G3D::Vector2& vertice : _polygonVertices)
+ {
+ float tempX = vertice.x;
+ float tempY = vertice.y;
+
+ vertice.x = tempX * angleCos - tempY * angleSin;
+ vertice.y = tempX * angleSin + tempY * angleCos;
+ }
+
+ _previousCheckOrientation = newOrientation;
+}
+
+bool AreaTrigger::CheckIsInPolygon2D(Position const* pos) const
+{
+ float testX = pos->GetPositionX();
+ float testY = pos->GetPositionY();
+
+ //this method uses the ray tracing algorithm to determine if the point is in the polygon
+ int nPoints = _polygonVertices.size();
+ bool locatedInPolygon = false;
+
+ for (int i = 0; i < nPoints; ++i)
+ {
+ int j = -999;
+
+ //repeat loop for all sets of points
+ if (i == (nPoints - 1))
+ {
+ //if i is the last vertex, let j be the first vertex
+ j = 0;
+ }
+ else
+ {
+ //for all-else, let j=(i+1)th vertex
+ j = i + 1;
+ }
+
+ float vertX_i = GetPositionX() + _polygonVertices[i].x;
+ float vertY_i = GetPositionY() + _polygonVertices[i].y;
+ float vertX_j = GetPositionX() + _polygonVertices[j].x;
+ float vertY_j = GetPositionY() + _polygonVertices[j].y;
+
+ // following statement checks if testPoint.Y is below Y-coord of i-th vertex
+ bool belowLowY = vertY_i > testY;
+ // following statement checks if testPoint.Y is below Y-coord of i+1-th vertex
+ bool belowHighY = vertY_j > testY;
+
+ /* following statement is true if testPoint.Y satisfies either (only one is possible)
+ -->(i).Y < testPoint.Y < (i+1).Y OR
+ -->(i).Y > testPoint.Y > (i+1).Y
+
+ (Note)
+ Both of the conditions indicate that a point is located within the edges of the Y-th coordinate
+ of the (i)-th and the (i+1)- th vertices of the polygon. If neither of the above
+ conditions is satisfied, then it is assured that a semi-infinite horizontal line draw
+ to the right from the testpoint will NOT cross the line that connects vertices i and i+1
+ of the polygon
+ */
+ bool withinYsEdges = belowLowY != belowHighY;
+
+ if (withinYsEdges)
+ {
+ // this is the slope of the line that connects vertices i and i+1 of the polygon
+ float slopeOfLine = (vertX_j - vertX_i) / (vertY_j - vertY_i);
+
+ // this looks up the x-coord of a point lying on the above line, given its y-coord
+ float pointOnLine = (slopeOfLine* (testY - vertY_i)) + vertX_i;
+
+ //checks to see if x-coord of testPoint is smaller than the point on the line with the same y-coord
+ bool isLeftToLine = testX < pointOnLine;
+
+ if (isLeftToLine)
+ {
+ //this statement changes true to false (and vice-versa)
+ locatedInPolygon = !locatedInPolygon;
+ }//end if (isLeftToLine)
+ }//end if (withinYsEdges
+ }
+
+ return locatedInPolygon;
+}
+
+void AreaTrigger::UpdateShape()
+{
+ if (GetTemplate()->IsPolygon())
+ UpdatePolygonOrientation();
+}
+
+bool UnitFitToActionRequirement(Unit* unit, Unit* caster, AreaTriggerActionUserTypes targetType)
+{
+ switch (targetType)
+ {
+ case AREATRIGGER_ACTION_USER_FRIEND:
+ {
+ return caster->IsFriendlyTo(unit);
+ }
+ case AREATRIGGER_ACTION_USER_ENEMY:
+ {
+ return !caster->IsFriendlyTo(unit);
+ }
+ case AREATRIGGER_ACTION_USER_RAID:
+ {
+ return caster->IsInRaidWith(unit);
+ }
+ case AREATRIGGER_ACTION_USER_PARTY:
+ {
+ return caster->IsInPartyWith(unit);
+ }
+ case AREATRIGGER_ACTION_USER_CASTER:
+ {
+ return unit->GetGUID() == caster->GetGUID();
+ }
+ case AREATRIGGER_ACTION_USER_ANY:
+ default:
+ break;
+ }
+
+ return true;
+}
+
+void AreaTrigger::DoActions(Unit* unit)
+{
+ if (Unit* caster = GetCaster())
+ {
+ for (AreaTriggerAction const& action : GetTemplate()->Actions)
+ {
+ if (UnitFitToActionRequirement(unit, caster, action.TargetType))
+ {
+ switch (action.ActionType)
+ {
+ case AREATRIGGER_ACTION_CAST:
+ caster->CastSpell(unit, action.Param, true);
+ break;
+ case AREATRIGGER_ACTION_ADDAURA:
+ caster->AddAura(action.Param, unit);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ }
+}
+
+void AreaTrigger::UndoActions(Unit* unit)
+{
+ for (AreaTriggerAction const& action : GetTemplate()->Actions)
+ {
+ if (action.ActionType == AREATRIGGER_ACTION_CAST || action.ActionType == AREATRIGGER_ACTION_ADDAURA)
+ unit->RemoveAurasDueToSpell(action.Param, GetCasterGuid());
+ }
+}
+
+void AreaTrigger::InitSplineOffsets(std::vector<G3D::Vector3> splinePoints, uint32 timeToTarget)
+{
+ float angleSin = std::sin(GetOrientation());
+ float angleCos = std::cos(GetOrientation());
+
+ // This is needed to rotate the spline, following caster orientation
+ for (G3D::Vector3& spline : splinePoints)
+ {
+ float tempX = spline.x;
+ float tempY = spline.y;
+ float tempZ = GetPositionZ();
+
+ spline.x = (tempX * angleCos - tempY * angleSin) + GetPositionX();
+ spline.y = (tempX * angleSin + tempY * angleCos) + GetPositionY();
+ UpdateAllowedPositionZ(spline.x, spline.y, tempZ);
+ spline.z += tempZ;
+ }
+
+ InitSplines(splinePoints, timeToTarget);
+}
+
+void AreaTrigger::InitSplines(std::vector<G3D::Vector3> const& splinePoints, uint32 timeToTarget)
+{
+ if (splinePoints.size() < 2)
+ return;
+
+ _movementTime = 0;
+
+ _spline.init_spline(&splinePoints[0], splinePoints.size(), ::Movement::SplineBase::ModeLinear);
+ _spline.initLengths();
+
+ // should be sent in object create packets only
+ m_uint32Values[AREATRIGGER_TIME_TO_TARGET] = timeToTarget;
+
+ if (IsInWorld())
+ {
+ if (_reachedDestination)
+ {
+ WorldPackets::AreaTrigger::AreaTriggerReShape reshape;
+ reshape.TriggerGUID = GetGUID();
+ SendMessageToSet(reshape.Write(), true);
+ }
+
+ WorldPackets::AreaTrigger::AreaTriggerReShape reshape;
+ reshape.TriggerGUID = GetGUID();
+ reshape.AreaTriggerSpline = boost::in_place();
+ reshape.AreaTriggerSpline->ElapsedTimeForMovement = GetElapsedTimeForMovement();
+ reshape.AreaTriggerSpline->TimeToTarget = timeToTarget;
+ reshape.AreaTriggerSpline->Points = splinePoints;
+ SendMessageToSet(reshape.Write(), true);
+ }
+
+ _reachedDestination = false;
+}
+
+void AreaTrigger::UpdateSplinePosition(uint32 diff)
+{
+ if (_reachedDestination)
+ return;
+
+ if (!HasSplines())
+ return;
+
+ _movementTime += diff;
+
+ if (_movementTime >= GetTimeToTarget())
+ {
+ _reachedDestination = true;
+ _lastSplineIndex = int32(_spline.last());
+
+ G3D::Vector3 lastSplinePosition = _spline.getPoint(_lastSplineIndex);
+ GetMap()->AreaTriggerRelocation(this, lastSplinePosition.x, lastSplinePosition.y, lastSplinePosition.z, GetOrientation());
+#ifdef TRINITY_DEBUG
+ DebugVisualizePosition();
+#endif
+
+ sScriptMgr->OnAreaTriggerEntitySplineIndexReached(this, _lastSplineIndex);
+ sScriptMgr->OnAreaTriggerEntityDestinationReached(this);
+ return;
+ }
+
+ float currentTimePercent = float(_movementTime) / float(GetTimeToTarget());
+
+ if (currentTimePercent <= 0.f)
+ return;
+
+ if (GetMiscTemplate()->MoveCurveId)
+ {
+ float progress = sDB2Manager.GetCurveValueAt(GetMiscTemplate()->MoveCurveId, currentTimePercent);
+ if (progress < 0.f || progress > 1.f)
+ {
+ TC_LOG_ERROR("entities.areatrigger", "AreaTrigger (Id: %u, SpellMiscId: %u) has wrong progress (%f) caused by curve calculation (MoveCurveId: %u)",
+ GetTemplate()->Id, GetMiscTemplate()->MiscId, progress, GetMiscTemplate()->MorphCurveId);
+ }
+ else
+ currentTimePercent = progress;
+ }
+
+ int lastPositionIndex = 0;
+ float percentFromLastPoint = 0;
+ _spline.computeIndex(currentTimePercent, lastPositionIndex, percentFromLastPoint);
+
+ G3D::Vector3 currentPosition;
+ _spline.evaluate_percent(lastPositionIndex, percentFromLastPoint, currentPosition);
+
+ float orientation = GetOrientation();
+ if (GetTemplate()->HasFlag(AREATRIGGER_FLAG_HAS_FACE_MOVEMENT_DIR))
+ {
+ G3D::Vector3 const& nextPoint = _spline.getPoint(lastPositionIndex + 1);
+ orientation = GetAngle(nextPoint.x, nextPoint.y);
+ }
+
+ GetMap()->AreaTriggerRelocation(this, currentPosition.x, currentPosition.y, currentPosition.z, orientation);
+#ifdef TRINITY_DEBUG
+ DebugVisualizePosition();
+#endif
+
+ if (_lastSplineIndex != lastPositionIndex)
+ {
+ _lastSplineIndex = lastPositionIndex;
+ sScriptMgr->OnAreaTriggerEntitySplineIndexReached(this, _lastSplineIndex);
+ }
+}
+
+void AreaTrigger::DebugVisualizePosition()
+{
+ if (Unit* caster = GetCaster())
+ if (Player* player = caster->ToPlayer())
+ if (player->isDebugAreaTriggers)
+ player->SummonCreature(1, *this, TEMPSUMMON_TIMED_DESPAWN, GetTimeToTarget());
+}
diff --git a/src/server/game/Entities/AreaTrigger/AreaTrigger.h b/src/server/game/Entities/AreaTrigger/AreaTrigger.h
index e6396544cd7..57ea7b4e704 100644
--- a/src/server/game/Entities/AreaTrigger/AreaTrigger.h
+++ b/src/server/game/Entities/AreaTrigger/AreaTrigger.h
@@ -19,11 +19,16 @@
#define TRINITYCORE_AREATRIGGER_H
#include "Object.h"
+#include "Position.h"
+#include "Spline.h"
-class Unit;
+class AreaTriggerTemplate;
+class AreaTriggerMiscTemplate;
class SpellInfo;
+class Unit;
+struct AreaTriggerPolygonVertice;
-class TC_GAME_API AreaTrigger : public WorldObject, public GridObject<AreaTrigger>
+class TC_GAME_API AreaTrigger : public WorldObject, public GridObject<AreaTrigger>, public MapObject
{
public:
AreaTrigger();
@@ -32,16 +37,78 @@ class TC_GAME_API AreaTrigger : public WorldObject, public GridObject<AreaTrigge
void AddToWorld() override;
void RemoveFromWorld() override;
- bool CreateAreaTrigger(ObjectGuid::LowType guidlow, uint32 triggerEntry, Unit* caster, SpellInfo const* spell, Position const& pos, uint32 spellXSpellVisualId);
+ bool CreateAreaTrigger(uint32 triggerEntry, Unit* caster, Unit* target, SpellInfo const* spell, Position const& pos, int32 duration, uint32 spellXSpellVisualId, ObjectGuid const& castId = ObjectGuid::Empty);
void Update(uint32 p_time) override;
void Remove();
+ bool IsRemoved() const { return _isRemoved; }
uint32 GetSpellId() const { return GetUInt32Value(AREATRIGGER_SPELLID); }
+ uint32 GetTimeSinceCreated() const { return _timeSinceCreated; }
+ uint32 GetTimeToTarget() const { return GetUInt32Value(AREATRIGGER_TIME_TO_TARGET); }
+ uint32 GetTimeToTargetScale() const { return GetUInt32Value(AREATRIGGER_TIME_TO_TARGET_SCALE); }
int32 GetDuration() const { return _duration; }
- void SetDuration(int32 newDuration) { _duration = newDuration; }
+ int32 GetTotalDuration() const { return _totalDuration; }
+ void SetDuration(int32 newDuration);
void Delay(int32 delaytime) { SetDuration(GetDuration() - delaytime); }
+ GuidUnorderedSet const& GetInsideUnits() const { return _insideUnits; }
+
+ AreaTriggerMiscTemplate const* GetMiscTemplate() const { return _areaTriggerMiscTemplate; }
+ AreaTriggerTemplate const* GetTemplate() const;
+ uint32 GetScriptId() const;
+
+ ObjectGuid const& GetCasterGuid() const { return GetGuidValue(AREATRIGGER_CASTER); }
+ Unit* GetCaster() const;
+ Unit* GetTarget() const;
+
+ G3D::Vector3 const& GetRollPitchYaw() const { return _rollPitchYaw; }
+ G3D::Vector3 const& GetTargetRollPitchYaw() const { return _targetRollPitchYaw; }
+ void InitSplineOffsets(std::vector<G3D::Vector3> splinePoints, uint32 timeToTarget);
+ void InitSplines(std::vector<G3D::Vector3> const& splinePoints, uint32 timeToTarget);
+ bool HasSplines() const { return !_spline.empty(); }
+ ::Movement::Spline<int32> const& GetSpline() const { return _spline; }
+ uint32 GetElapsedTimeForMovement() const { return GetTimeSinceCreated(); } /// @todo: research the right value, in sniffs both timers are nearly identical
+
+ void UpdateShape();
+
protected:
+ void _UpdateDuration(int32 newDuration);
+ float GetProgress() const;
+
+ void UpdateTargetList();
+ void SearchUnitInSphere(std::list<Unit*>& targetList);
+ void SearchUnitInBox(std::list<Unit*>& targetList);
+ void SearchUnitInPolygon(std::list<Unit*>& targetList);
+ void SearchUnitInCylinder(std::list<Unit*>& targetList);
+ bool CheckIsInPolygon2D(Position const* pos) const;
+ void HandleUnitEnterExit(std::list<Unit*> const& targetList);
+
+ void DoActions(Unit* unit);
+ void UndoActions(Unit* unit);
+
+ void UpdatePolygonOrientation();
+ void UpdateSplinePosition(uint32 diff);
+
+ void DebugVisualizePosition(); // Debug purpose only
+
+ ObjectGuid _targetGuid;
+
int32 _duration;
- uint32 _spellXSpellVisualId;
+ int32 _totalDuration;
+ uint32 _timeSinceCreated;
+ float _previousCheckOrientation;
+ bool _isRemoved;
+
+ G3D::Vector3 _rollPitchYaw;
+ G3D::Vector3 _targetRollPitchYaw;
+ std::vector<G3D::Vector2> _polygonVertices;
+ ::Movement::Spline<int32> _spline;
+
+ bool _reachedDestination;
+ int32 _lastSplineIndex;
+ uint32 _movementTime;
+
+ AreaTriggerMiscTemplate const* _areaTriggerMiscTemplate;
+ GuidUnorderedSet _insideUnits;
};
+
#endif
diff --git a/src/server/game/Entities/AreaTrigger/AreaTriggerTemplate.cpp b/src/server/game/Entities/AreaTrigger/AreaTriggerTemplate.cpp
new file mode 100644
index 00000000000..81b1b8c7900
--- /dev/null
+++ b/src/server/game/Entities/AreaTrigger/AreaTriggerTemplate.cpp
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2008-2017 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 "AreaTriggerTemplate.h"
+
+// Init the MaxSearchRadius that will be used in TrinitySearcher, avoiding calculate it at each update
+void AreaTriggerTemplate::InitMaxSearchRadius()
+{
+ switch (Type)
+ {
+ case AREATRIGGER_TYPE_SPHERE:
+ {
+ MaxSearchRadius = std::max(SphereDatas.Radius, SphereDatas.RadiusTarget);
+ break;
+ }
+ case AREATRIGGER_TYPE_BOX:
+ {
+ MaxSearchRadius = std::sqrt(BoxDatas.Extents[0] * BoxDatas.Extents[0] / 4 + BoxDatas.Extents[1] * BoxDatas.Extents[1] / 4);
+ break;
+ }
+ case AREATRIGGER_TYPE_POLYGON:
+ {
+ if (PolygonDatas.Height <= 0.0f)
+ PolygonDatas.Height = 1.0f;
+
+ for (G3D::Vector2 const& vertice : PolygonVertices)
+ {
+ float pointDist = vertice.length();
+
+ if (pointDist > MaxSearchRadius)
+ MaxSearchRadius = pointDist;
+ }
+
+ break;
+ }
+ case AREATRIGGER_TYPE_CYLINDER:
+ {
+ MaxSearchRadius = CylinderDatas.Radius;
+ break;
+ }
+ default:
+ break;
+ }
+}
diff --git a/src/server/game/Entities/AreaTrigger/AreaTriggerTemplate.h b/src/server/game/Entities/AreaTrigger/AreaTriggerTemplate.h
new file mode 100644
index 00000000000..c4701567abe
--- /dev/null
+++ b/src/server/game/Entities/AreaTrigger/AreaTriggerTemplate.h
@@ -0,0 +1,187 @@
+/*
+ * Copyright (C) 2008-2017 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 TRINITYCORE_AREATRIGGER_TEMPLATE_H
+#define TRINITYCORE_AREATRIGGER_TEMPLATE_H
+
+#include <G3D/Vector3.h>
+
+#define MAX_AREATRIGGER_ENTITY_DATA 6
+
+enum AreaTriggerFlags
+{
+ AREATRIGGER_FLAG_HAS_ABSOLUTE_ORIENTATION = 0x00001, // NYI
+ AREATRIGGER_FLAG_HAS_DYNAMIC_SHAPE = 0x00002, // Implemented for Spheres
+ AREATRIGGER_FLAG_HAS_ATTACHED = 0x00004,
+ AREATRIGGER_FLAG_HAS_FACE_MOVEMENT_DIR = 0x00008,
+ AREATRIGGER_FLAG_HAS_FOLLOWS_TERRAIN = 0x00010, // NYI
+ AREATRIGGER_FLAG_UNK1 = 0x00020,
+ AREATRIGGER_FLAG_HAS_TARGET_ROLL_PITCH_YAW = 0x00040, // NYI
+ AREATRIGGER_FLAG_UNK2 = 0x00080,
+ AREATRIGGER_FLAG_UNK3 = 0x00100,
+ AREATRIGGER_FLAG_UNK4 = 0x00200,
+ AREATRIGGER_FLAG_UNK5 = 0x00400
+};
+
+enum AreaTriggerTypes
+{
+ AREATRIGGER_TYPE_SPHERE = 0,
+ AREATRIGGER_TYPE_BOX = 1,
+ AREATRIGGER_TYPE_UNK = 2,
+ AREATRIGGER_TYPE_POLYGON = 3,
+ AREATRIGGER_TYPE_CYLINDER = 4,
+ AREATRIGGER_TYPE_MAX = 5
+};
+
+enum AreaTriggerActionTypes
+{
+ AREATRIGGER_ACTION_CAST = 0,
+ AREATRIGGER_ACTION_ADDAURA = 1,
+ AREATRIGGER_ACTION_MAX = 2
+};
+
+enum AreaTriggerActionUserTypes
+{
+ AREATRIGGER_ACTION_USER_ANY = 0,
+ AREATRIGGER_ACTION_USER_FRIEND = 1,
+ AREATRIGGER_ACTION_USER_ENEMY = 2,
+ AREATRIGGER_ACTION_USER_RAID = 3,
+ AREATRIGGER_ACTION_USER_PARTY = 4,
+ AREATRIGGER_ACTION_USER_CASTER = 5,
+ AREATRIGGER_ACTION_USER_MAX = 6
+};
+
+struct AreaTriggerAction
+{
+ uint32 Param;
+ AreaTriggerActionTypes ActionType;
+ AreaTriggerActionUserTypes TargetType;
+};
+
+class AreaTriggerTemplate
+{
+public:
+ AreaTriggerTemplate()
+ {
+ Id = 0;
+ Flags = 0;
+ ScriptId = 0;
+ MaxSearchRadius = 0.0f;
+
+ memset(DefaultDatas.Data, 0, sizeof(DefaultDatas.Data));
+ }
+
+ bool HasFlag(uint32 flag) const { return (Flags & flag) != 0; }
+
+ bool IsSphere() const { return Type == AREATRIGGER_TYPE_SPHERE; }
+ bool IsBox() const { return Type == AREATRIGGER_TYPE_BOX; }
+ bool IsPolygon() const { return Type == AREATRIGGER_TYPE_POLYGON; }
+ bool IsCylinder() const { return Type == AREATRIGGER_TYPE_CYLINDER; }
+
+ void InitMaxSearchRadius();
+
+ uint32 Id;
+ AreaTriggerTypes Type;
+ uint32 Flags;
+ uint32 ScriptId;
+ float MaxSearchRadius;
+ std::vector<G3D::Vector2> PolygonVertices;
+ std::vector<G3D::Vector2> PolygonVerticesTarget;
+ std::vector<AreaTriggerAction> Actions;
+
+ union
+ {
+ struct
+ {
+ float Data[MAX_AREATRIGGER_ENTITY_DATA];
+ } DefaultDatas;
+
+ // AREATRIGGER_TYPE_SPHERE
+ struct
+ {
+ float Radius;
+ float RadiusTarget;
+ } SphereDatas;
+
+ // AREATRIGGER_TYPE_BOX
+ struct
+ {
+ float Extents[3];
+ float ExtentsTarget[3];
+ } BoxDatas;
+
+ // AREATRIGGER_TYPE_POLYGON
+ struct
+ {
+ float Height;
+ float HeightTarget;
+ } PolygonDatas;
+
+ // AREATRIGGER_TYPE_CYLINDER
+ struct
+ {
+ float Radius;
+ float RadiusTarget;
+ float Height;
+ float HeightTarget;
+ float LocationZOffset;
+ float LocationZOffsetTarget;
+ } CylinderDatas;
+ };
+};
+
+class AreaTriggerMiscTemplate
+{
+public:
+ AreaTriggerMiscTemplate()
+ {
+ MiscId = 0;
+ AreaTriggerEntry = 0;
+
+ MoveCurveId = 0;
+ ScaleCurveId = 0;
+ MorphCurveId = 0;
+ FacingCurveId = 0;
+
+ DecalPropertiesId = 0;
+
+ TimeToTarget = 0;
+ TimeToTargetScale = 0;
+
+ Template = nullptr;
+ }
+
+ bool HasSplines() const { return SplinePoints.size() >= 2; }
+
+ uint32 MiscId;
+ uint32 AreaTriggerEntry;
+
+ uint32 MoveCurveId;
+ uint32 ScaleCurveId;
+ uint32 MorphCurveId;
+ uint32 FacingCurveId;
+
+ uint32 DecalPropertiesId;
+
+ uint32 TimeToTarget;
+ uint32 TimeToTargetScale;
+
+ AreaTriggerTemplate const* Template;
+ std::vector<G3D::Vector3> SplinePoints;
+};
+
+#endif
diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp
index ef42f5a3f68..fcbb82708b0 100644
--- a/src/server/game/Entities/Object/Object.cpp
+++ b/src/server/game/Entities/Object/Object.cpp
@@ -45,6 +45,7 @@
#include "BattlefieldMgr.h"
#include "MiscPackets.h"
#include "InstanceScenario.h"
+#include "AreaTriggerTemplate.h"
Object::Object()
{
@@ -346,7 +347,7 @@ void Object::BuildMovementUpdate(ByteBuffer* data, uint32 flags) const
bool VehicleCreate = (flags & UPDATEFLAG_VEHICLE) != 0;
bool AnimKitCreate = (flags & UPDATEFLAG_ANIMKITS) != 0;
bool Rotation = (flags & UPDATEFLAG_ROTATION) != 0;
- bool HasAreaTrigger = false;
+ bool HasAreaTrigger = (flags & UPDATEFLAG_AREATRIGGER) != 0;
bool HasGameObject = false;
bool ThisIsYou = (flags & UPDATEFLAG_SELF) != 0;
bool SmoothPhasing = false;
@@ -509,111 +510,160 @@ void Object::BuildMovementUpdate(ByteBuffer* data, uint32 flags) const
*data << self->m_movementInfo.transport;
}
- //if (AreaTrigger)
- //{
- // *data << uint32(ElapsedMs);
- // *data << Vector3(RollPitchYaw);
- // data->WriteBit(HasAbsoluteOrientation);
- // data->WriteBit(HasDynamicShape);
- // data->WriteBit(HasAttached);
- // data->WriteBit(HasFaceMovementDir);
- // data->WriteBit(HasFollowsTerrain);
- // data->WriteBit(Unknown_1);
- // data->WriteBit(HasTargetRollPitchYaw);
- // data->WriteBit(HasScaleCurveID);
- // data->WriteBit(HasMorphCurveID);
- // data->WriteBit(HasFacingCurveID);
- // data->WriteBit(HasMoveCurveID);
- // data->WriteBit(HasAreaTriggerSphere);
- // data->WriteBit(HasAreaTriggerBox);
- // data->WriteBit(HasAreaTriggerPolygon);
- // data->WriteBit(HasAreaTriggerCylinder);
- // data->WriteBit(HasAreaTriggerSpline);
- // data->WriteBit(HasAreaTriggerUnkType);
-
- // if (HasAreaTriggerUnkType)
- // {
- // data->WriteBit(Unk_1);
- // data->WriteBit(HasCenter);
- // data->WriteBit(Unk_3);
- // data->WriteBit(Unk_4);
-
- // *data << uint32();
- // *data << int32();
- // *data << uint32();
- // *data << float(Radius);
- // *data << float(BlendFromRadius);
- // *data << float(InitialAngel);
- // *data << float(ZOffset);
-
- // if (Unk_1)
- // *data << ObjectGuid();
-
- // if (HasCenter)
- // *data << Vector3(Center);
- // }
+ if (HasAreaTrigger)
+ {
+ AreaTrigger const* areaTrigger = ToAreaTrigger();
+ AreaTriggerMiscTemplate const* areaTriggerMiscTemplate = areaTrigger->GetMiscTemplate();
+ AreaTriggerTemplate const* areaTriggerTemplate = areaTrigger->GetTemplate();
+
+ *data << uint32(areaTrigger->GetTimeSinceCreated());
+
+ *data << areaTrigger->GetRollPitchYaw();
+
+ bool hasAbsoluteOrientation = areaTriggerTemplate->HasFlag(AREATRIGGER_FLAG_HAS_ABSOLUTE_ORIENTATION);
+ bool hasDynamicShape = areaTriggerTemplate->HasFlag(AREATRIGGER_FLAG_HAS_DYNAMIC_SHAPE);
+ bool hasAttached = areaTriggerTemplate->HasFlag(AREATRIGGER_FLAG_HAS_ATTACHED);
+ bool hasFaceMovementDir = areaTriggerTemplate->HasFlag(AREATRIGGER_FLAG_HAS_FACE_MOVEMENT_DIR);
+ bool hasFollowsTerrain = areaTriggerTemplate->HasFlag(AREATRIGGER_FLAG_HAS_FOLLOWS_TERRAIN);
+ bool hasUnk1 = areaTriggerTemplate->HasFlag(AREATRIGGER_FLAG_UNK1);
+ bool hasTargetRollPitchYaw = areaTriggerTemplate->HasFlag(AREATRIGGER_FLAG_HAS_TARGET_ROLL_PITCH_YAW);
+ bool hasScaleCurveID = areaTriggerMiscTemplate->ScaleCurveId != 0;
+ bool hasMorphCurveID = areaTriggerMiscTemplate->MorphCurveId != 0;
+ bool hasFacingCurveID = areaTriggerMiscTemplate->FacingCurveId != 0;
+ bool hasMoveCurveID = areaTriggerMiscTemplate->MoveCurveId != 0;
+ bool hasUnk2 = areaTriggerTemplate->HasFlag(AREATRIGGER_FLAG_UNK2);
+ bool hasUnk3 = areaTriggerTemplate->HasFlag(AREATRIGGER_FLAG_UNK3);
+ bool hasUnk4 = areaTriggerTemplate->HasFlag(AREATRIGGER_FLAG_UNK4);
+ bool hasAreaTriggerSphere = areaTriggerTemplate->IsSphere();
+ bool hasAreaTriggerBox = areaTriggerTemplate->IsBox();
+ bool hasAreaTriggerPolygon = areaTriggerTemplate->IsPolygon();
+ bool hasAreaTriggerCylinder = areaTriggerTemplate->IsCylinder();
+ bool hasAreaTriggerSpline = areaTrigger->HasSplines();
+ bool hasAreaTriggerUnkType = false; // areaTriggerTemplate->HasFlag(AREATRIGGER_FLAG_UNK5);
+
+ data->WriteBit(hasAbsoluteOrientation);
+ data->WriteBit(hasDynamicShape);
+ data->WriteBit(hasAttached);
+ data->WriteBit(hasFaceMovementDir);
+ data->WriteBit(hasFollowsTerrain);
+ data->WriteBit(hasUnk1);
+ data->WriteBit(hasTargetRollPitchYaw);
+ data->WriteBit(hasScaleCurveID);
+ data->WriteBit(hasMorphCurveID);
+ data->WriteBit(hasFacingCurveID);
+ data->WriteBit(hasMoveCurveID);
+ data->WriteBit(hasUnk2);
+ data->WriteBit(hasUnk3);
+ data->WriteBit(hasUnk4);
+ data->WriteBit(hasAreaTriggerSphere);
+ data->WriteBit(hasAreaTriggerBox);
+ data->WriteBit(hasAreaTriggerPolygon);
+ data->WriteBit(hasAreaTriggerCylinder);
+ data->WriteBit(hasAreaTriggerSpline);
+ data->WriteBit(hasAreaTriggerUnkType);
+
+ if (hasUnk3)
+ data->WriteBit(0);
- // if (HasTargetRollPitchYaw)
- // *data << Vector3(TargetRollPitchYaw);
+ data->FlushBits();
- // if (HasScaleCurveID)
- // *data << uint32(ScaleCurveID);
+ if (hasAreaTriggerSpline)
+ {
+ std::vector<G3D::Vector3> const& splinePoints = areaTrigger->GetSpline().getPoints();
- // if (HasMorphCurveID)
- // *data << uint32(MorphCurveID);
+ *data << uint32(areaTrigger->GetTimeToTarget());
+ *data << uint32(areaTrigger->GetElapsedTimeForMovement());
- // if (HasFacingCurveID)
- // *data << uint32(FacingCurveID);
+ data->WriteBits(splinePoints.size(), 16);
- // if (HasMoveCurveID)
- // *data << uint32(MoveCurveID);
+ for (G3D::Vector3 const& spline : splinePoints)
+ *data << spline;
+ }
- // if (HasAreaTriggerSphere)
- // {
- // *data << float(Radius);
- // *data << float(RadiusTarget);
- // }
+ if (hasTargetRollPitchYaw)
+ *data << areaTrigger->GetTargetRollPitchYaw();
- // if (HasAreaTriggerBox)
- // {
- // *data << Vector3(Extents);
- // *data << Vector3(ExtentsTarget);
- // }
+ if (hasScaleCurveID)
+ *data << uint32(areaTriggerMiscTemplate->ScaleCurveId);
- // if (HasAreaTriggerPolygon)
- // {
- // *data << uint32(Vertices.size());
- // *data << uint32(VerticesTarget.size());
- // *data << float(Height);
- // *data << float(HeightTarget);
+ if (hasMorphCurveID)
+ *data << uint32(areaTriggerMiscTemplate->MorphCurveId);
- // for (std::size_t i = 0; i < Vertices.size(); ++i)
- // *data << Vector2(Vertices[i]);
+ if (hasFacingCurveID)
+ *data << uint32(areaTriggerMiscTemplate->FacingCurveId);
- // for (std::size_t i = 0; i < VerticesTarget.size(); ++i)
- // *data << Vector2(VerticesTarget[i]);
- // }
+ if (hasMoveCurveID)
+ *data << uint32(areaTriggerMiscTemplate->MoveCurveId);
- // if (HasAreaTriggerCylinder)
- // {
- // *data << float(Radius);
- // *data << float(RadiusTarget);
- // *data << float(Height);
- // *data << float(HeightTarget);
- // *data << float(LocationZOffset);
- // *data << float(LocationZOffsetTarget);
- // }
+ if (hasUnk2)
+ *data << int32(0);
- // if (HasAreaTriggerSpline)
- // {
- // *data << uint32(TimeToTarget);
- // *data << uint32(ElapsedTimeForMovement);
- // *data << uint32(Points.size());
+ if (hasUnk4)
+ *data << uint32(0);
- // for (std::size_t i = 0; i < Points.size(); ++i)
- // *data << Vector3(Points[i]);
- // }
- //}
+ if (hasAreaTriggerSphere)
+ {
+ *data << float(areaTriggerTemplate->SphereDatas.Radius);
+ *data << float(areaTriggerTemplate->SphereDatas.RadiusTarget);
+ }
+
+ if (hasAreaTriggerBox)
+ {
+ *data << float(areaTriggerTemplate->BoxDatas.Extents[0]);
+ *data << float(areaTriggerTemplate->BoxDatas.Extents[1]);
+ *data << float(areaTriggerTemplate->BoxDatas.Extents[2]);
+ *data << float(areaTriggerTemplate->BoxDatas.ExtentsTarget[0]);
+ *data << float(areaTriggerTemplate->BoxDatas.ExtentsTarget[1]);
+ *data << float(areaTriggerTemplate->BoxDatas.ExtentsTarget[2]);
+ }
+
+ if (hasAreaTriggerPolygon)
+ {
+ *data << int32(areaTriggerTemplate->PolygonVertices.size());
+ *data << int32(areaTriggerTemplate->PolygonVerticesTarget.size());
+ *data << float(areaTriggerTemplate->PolygonDatas.Height);
+ *data << float(areaTriggerTemplate->PolygonDatas.HeightTarget);
+
+ for (G3D::Vector2 const& vertice : areaTriggerTemplate->PolygonVertices)
+ *data << vertice;
+
+ for (G3D::Vector2 const& vertice : areaTriggerTemplate->PolygonVerticesTarget)
+ *data << vertice;
+ }
+
+ if (hasAreaTriggerCylinder)
+ {
+ *data << float(areaTriggerTemplate->CylinderDatas.Radius);
+ *data << float(areaTriggerTemplate->CylinderDatas.RadiusTarget);
+ *data << float(areaTriggerTemplate->CylinderDatas.Height);
+ *data << float(areaTriggerTemplate->CylinderDatas.HeightTarget);
+ *data << float(areaTriggerTemplate->CylinderDatas.LocationZOffset);
+ *data << float(areaTriggerTemplate->CylinderDatas.LocationZOffsetTarget);
+ }
+
+ if (hasAreaTriggerUnkType)
+ {
+ /*packet.ResetBitReader();
+ var unk1 = packet.ReadBit("AreaTriggerUnk1");
+ var hasCenter = packet.ReadBit("HasCenter", index);
+ packet.ReadBit("Unk bit 703 1", index);
+ packet.ReadBit("Unk bit 703 2", index);
+
+ packet.ReadUInt32();
+ packet.ReadInt32();
+ packet.ReadUInt32();
+ packet.ReadSingle("Radius", index);
+ packet.ReadSingle("BlendFromRadius", index);
+ packet.ReadSingle("InitialAngel", index);
+ packet.ReadSingle("ZOffset", index);
+
+ if (unk1)
+ packet.ReadPackedGuid128("AreaTriggerUnkGUID", index);
+
+ if (hasCenter)
+ packet.ReadVector3("Center", index);*/
+ }
+ }
//if (GameObject)
//{
diff --git a/src/server/game/Entities/Object/Updates/UpdateData.h b/src/server/game/Entities/Object/Updates/UpdateData.h
index 27042f3c6a1..7e7d86590d9 100644
--- a/src/server/game/Entities/Object/Updates/UpdateData.h
+++ b/src/server/game/Entities/Object/Updates/UpdateData.h
@@ -45,7 +45,7 @@ enum OBJECT_UPDATE_FLAGS
UPDATEFLAG_TRANSPORT_POSITION = 0x0040,
UPDATEFLAG_ROTATION = 0x0080,
UPDATEFLAG_ANIMKITS = 0x0100,
- //UPDATEFLAG_AREATRIGGER = 0x0200,
+ UPDATEFLAG_AREATRIGGER = 0x0200,
//UPDATEFLAG_GAMEOBJECT = 0x0400,
//UPDATEFLAG_REPLACE_ACTIVE = 0x0800,
//UPDATEFLAG_NO_BIRTH_ANIM = 0x1000,
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index 23f845feee1..bfb0bc377f2 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -1606,6 +1606,9 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati
// remove all dyn objects
RemoveAllDynObjects();
+ // remove all areatriggers entities
+ RemoveAllAreaTriggers();
+
// stop spellcasting
// not attempt interrupt teleportation spell at caster teleport
if (!(options & TELE_TO_SPELL))
diff --git a/src/server/game/Entities/Transport/Transport.cpp b/src/server/game/Entities/Transport/Transport.cpp
index c24f1e375e3..e9b850530e3 100644
--- a/src/server/game/Entities/Transport/Transport.cpp
+++ b/src/server/game/Entities/Transport/Transport.cpp
@@ -670,6 +670,7 @@ void Transport::DelayedTeleportTransport()
RemovePassenger(obj);
break;
case TYPEID_DYNAMICOBJECT:
+ case TYPEID_AREATRIGGER:
obj->AddObjectToRemoveList();
break;
default:
@@ -725,6 +726,9 @@ void Transport::UpdatePassengerPositions(PassengerSet& passengers)
case TYPEID_DYNAMICOBJECT:
GetMap()->DynamicObjectRelocation(passenger->ToDynObject(), x, y, z, o);
break;
+ case TYPEID_AREATRIGGER:
+ GetMap()->AreaTriggerRelocation(passenger->ToAreaTrigger(), x, y, z, o);
+ break;
default:
break;
}
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index 2ff096d2d27..4fc38747f96 100644
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -4911,6 +4911,59 @@ void Unit::RemoveAllGameObjects()
}
}
+void Unit::_RegisterAreaTrigger(AreaTrigger* areaTrigger)
+{
+ m_areaTrigger.push_back(areaTrigger);
+ if (GetTypeId() == TYPEID_UNIT && IsAIEnabled)
+ ToCreature()->AI()->JustRegisteredAreaTrigger(areaTrigger);
+}
+
+void Unit::_UnregisterAreaTrigger(AreaTrigger* areaTrigger)
+{
+ m_areaTrigger.erase(std::remove(m_areaTrigger.begin(), m_areaTrigger.end(), areaTrigger));
+ if (GetTypeId() == TYPEID_UNIT && IsAIEnabled)
+ ToCreature()->AI()->JustUnregisteredAreaTrigger(areaTrigger);
+}
+
+AreaTrigger* Unit::GetAreaTrigger(uint32 spellId) const
+{
+ std::vector<AreaTrigger*> areaTriggers = GetAreaTriggers(spellId);
+ return areaTriggers.empty() ? nullptr : areaTriggers.front();
+}
+
+std::vector<AreaTrigger*> Unit::GetAreaTriggers(uint32 spellId) const
+{
+ std::vector<AreaTrigger*> areaTriggers;
+ for (AreaTriggerList::const_iterator i = m_areaTrigger.begin(); i != m_areaTrigger.end(); ++i)
+ if ((*i)->GetSpellId() == spellId)
+ areaTriggers.push_back(*i);
+
+ return areaTriggers;
+}
+
+void Unit::RemoveAreaTrigger(uint32 spellId)
+{
+ if (m_areaTrigger.empty())
+ return;
+ for (AreaTriggerList::iterator i = m_areaTrigger.begin(); i != m_areaTrigger.end();)
+ {
+ AreaTrigger* areaTrigger = *i;
+ if (areaTrigger->GetSpellId() == spellId)
+ {
+ areaTrigger->Remove();
+ i = m_areaTrigger.begin();
+ }
+ else
+ ++i;
+ }
+}
+
+void Unit::RemoveAllAreaTriggers()
+{
+ while (!m_areaTrigger.empty())
+ m_areaTrigger.front()->Remove();
+}
+
void Unit::SendSpellNonMeleeDamageLog(SpellNonMeleeDamage const* log)
{
WorldPackets::CombatLog::SpellNonMeleeDamageLog packet;
@@ -10953,6 +11006,7 @@ void Unit::RemoveFromWorld()
RemoveAllGameObjects();
RemoveAllDynObjects();
+ RemoveAllAreaTriggers();
ExitVehicle(); // Remove applied auras with SPELL_AURA_CONTROL_VEHICLE
UnsummonAllTotems();
diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h
index 793bb07c52e..2efca610c1e 100644
--- a/src/server/game/Entities/Unit/Unit.h
+++ b/src/server/game/Entities/Unit/Unit.h
@@ -2073,6 +2073,14 @@ class TC_GAME_API Unit : public WorldObject
void RemoveGameObject(uint32 spellid, bool del);
void RemoveAllGameObjects();
+ // AreaTrigger management
+ void _RegisterAreaTrigger(AreaTrigger* areaTrigger);
+ void _UnregisterAreaTrigger(AreaTrigger* areaTrigger);
+ AreaTrigger* GetAreaTrigger(uint32 spellId) const;
+ std::vector<AreaTrigger*> GetAreaTriggers(uint32 spellId) const;
+ void RemoveAreaTrigger(uint32 spellId);
+ void RemoveAllAreaTriggers();
+
void ModifyAuraState(AuraStateType flag, bool apply);
uint32 BuildAuraStateUpdateForTarget(Unit* target) const;
bool HasAuraState(AuraStateType flag, SpellInfo const* spellProto = NULL, Unit const* Caster = NULL) const;
@@ -2309,6 +2317,9 @@ class TC_GAME_API Unit : public WorldObject
typedef std::list<GameObject*> GameObjectList;
GameObjectList m_gameObj;
+ typedef std::vector<AreaTrigger*> AreaTriggerList;
+ AreaTriggerList m_areaTrigger;
+
uint32 m_transform;
Spell* m_currentSpells[CURRENT_MAX_SPELL];
diff --git a/src/server/game/Globals/AreaTriggerDataStore.cpp b/src/server/game/Globals/AreaTriggerDataStore.cpp
new file mode 100644
index 00000000000..d93cc54bf76
--- /dev/null
+++ b/src/server/game/Globals/AreaTriggerDataStore.cpp
@@ -0,0 +1,230 @@
+/*
+ * Copyright (C) 2008-2017 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 "AreaTriggerDataStore.h"
+#include "AreaTriggerTemplate.h"
+#include "DatabaseEnv.h"
+#include "Log.h"
+#include "ObjectMgr.h"
+#include "Timer.h"
+
+namespace
+{
+ std::unordered_map<uint32, AreaTriggerTemplate> _areaTriggerTemplateStore;
+ std::unordered_map<uint32, AreaTriggerMiscTemplate> _areaTriggerTemplateSpellMisc;
+}
+
+void AreaTriggerDataStore::LoadAreaTriggerTemplates()
+{
+ uint32 oldMSTime = getMSTime();
+ std::unordered_map<uint32, std::vector<G3D::Vector2>> verticesByAreaTrigger;
+ std::unordered_map<uint32, std::vector<G3D::Vector2>> verticesTargetByAreaTrigger;
+ std::unordered_map<uint32, std::vector<G3D::Vector3>> splinesBySpellMisc;
+ std::unordered_map<uint32, std::vector<AreaTriggerAction>> actionsByAreaTrigger;
+
+ // 0 1 2 3
+ if (QueryResult templateActions = WorldDatabase.Query("SELECT AreaTriggerId, ActionType, ActionParam, TargetType FROM `areatrigger_template_actions`"))
+ {
+ do
+ {
+ Field* templateActionFields = templateActions->Fetch();
+ uint32 areaTriggerId = templateActionFields[0].GetUInt32();
+
+ AreaTriggerAction action;
+ action.Param = templateActionFields[2].GetUInt32();
+ uint32 actionType = templateActionFields[1].GetUInt32();
+ uint32 targetType = templateActionFields[3].GetUInt32();
+
+ if (actionType >= AREATRIGGER_ACTION_MAX)
+ {
+ TC_LOG_ERROR("sql.sql", "Table `areatrigger_template_actions` has invalid ActionType (%u) for AreaTriggerId %u and Param %u", actionType, areaTriggerId, action.Param);
+ continue;
+ }
+
+ if (targetType >= AREATRIGGER_ACTION_USER_MAX)
+ {
+ TC_LOG_ERROR("sql.sql", "Table `areatrigger_template_actions` has invalid TargetType (%u) for AreaTriggerId %u and Param %u", targetType, areaTriggerId, action.Param);
+ continue;
+ }
+
+ action.TargetType = AreaTriggerActionUserTypes(targetType);
+ action.ActionType = AreaTriggerActionTypes(actionType);
+
+ actionsByAreaTrigger[areaTriggerId].push_back(action);
+ }
+ while (templateActions->NextRow());
+ }
+ else
+ {
+ TC_LOG_INFO("server.loading", ">> Loaded 0 AreaTrigger templates actions. DB table `areatrigger_template_actions` is empty.");
+ }
+
+ // 0 1 2 3 4 5
+ if (QueryResult vertices = WorldDatabase.Query("SELECT AreaTriggerId, Idx, VerticeX, VerticeY, VerticeTargetX, VerticeTargetY FROM `areatrigger_template_polygon_vertices` ORDER BY `AreaTriggerId`, `Idx`"))
+ {
+ do
+ {
+ Field* verticeFields = vertices->Fetch();
+ uint32 areaTriggerId = verticeFields[0].GetUInt32();
+
+ verticesByAreaTrigger[areaTriggerId].emplace_back(verticeFields[2].GetFloat(), verticeFields[3].GetFloat());
+
+ if (!verticeFields[4].IsNull() && !verticeFields[5].IsNull())
+ verticesTargetByAreaTrigger[areaTriggerId].emplace_back(verticeFields[4].GetFloat(), verticeFields[5].GetFloat());
+ else if (verticeFields[4].IsNull() != !verticeFields[5].IsNull())
+ TC_LOG_ERROR("sql.sql", "Table `areatrigger_template_polygon_vertices` has listed invalid target vertices (AreaTrigger: %u, Index: %u).", areaTriggerId, verticeFields[1].GetUInt32());
+ }
+ while (vertices->NextRow());
+ }
+ else
+ {
+ TC_LOG_INFO("server.loading", ">> Loaded 0 AreaTrigger templates polygon vertices. DB table `areatrigger_template_polygon_vertices` is empty.");
+ }
+
+ // 0 1 2 3
+ if (QueryResult splines = WorldDatabase.Query("SELECT SpellMiscId, X, Y, Z FROM `spell_areatrigger_splines` ORDER BY `SpellMiscId`, `Idx`"))
+ {
+ do
+ {
+ Field* splineFields = splines->Fetch();
+ uint32 spellMiscId = splineFields[0].GetUInt32();
+
+ G3D::Vector3 spline;
+ spline.x = splineFields[1].GetFloat();
+ spline.y = splineFields[2].GetFloat();
+ spline.z = splineFields[3].GetFloat();
+
+ splinesBySpellMisc[spellMiscId].push_back(spline);
+ }
+ while (splines->NextRow());
+ }
+ else
+ {
+ TC_LOG_INFO("server.loading", ">> Loaded 0 AreaTrigger templates splines. DB table `spell_areatrigger_splines` is empty.");
+ }
+
+ // 0 1 2 3 4 5 6 7 8 9
+ if (QueryResult templates = WorldDatabase.Query("SELECT Id, Type, Flags, Data0, Data1, Data2, Data3, Data4, Data5, ScriptName FROM `areatrigger_template`"))
+ {
+ do
+ {
+ Field* fields = templates->Fetch();
+
+ AreaTriggerTemplate areaTriggerTemplate;
+ areaTriggerTemplate.Id = fields[0].GetUInt32();
+ uint8 type = fields[1].GetUInt8();
+
+ if (type >= AREATRIGGER_TYPE_MAX)
+ {
+ TC_LOG_ERROR("sql.sql", "Table `areatrigger_template` has listed areatrigger (Id: %u) with invalid type %u.", areaTriggerTemplate.Id, type);
+ continue;
+ }
+
+ areaTriggerTemplate.Type = static_cast<AreaTriggerTypes>(type);
+ areaTriggerTemplate.Flags = fields[2].GetUInt32();
+
+ for (uint8 i = 0; i < MAX_AREATRIGGER_ENTITY_DATA; ++i)
+ areaTriggerTemplate.DefaultDatas.Data[i] = fields[3 + i].GetFloat();
+
+ areaTriggerTemplate.ScriptId = sObjectMgr->GetScriptId(fields[9].GetString());
+ areaTriggerTemplate.PolygonVertices = std::move(verticesByAreaTrigger[areaTriggerTemplate.Id]);
+ areaTriggerTemplate.PolygonVerticesTarget = std::move(verticesTargetByAreaTrigger[areaTriggerTemplate.Id]);
+ areaTriggerTemplate.Actions = std::move(actionsByAreaTrigger[areaTriggerTemplate.Id]);
+
+ areaTriggerTemplate.InitMaxSearchRadius();
+ _areaTriggerTemplateStore[areaTriggerTemplate.Id] = areaTriggerTemplate;
+ }
+ while (templates->NextRow());
+ }
+
+ // 0 1 2 3 4 5 6 7 8
+ if (QueryResult areatriggerSpellMiscs = WorldDatabase.Query("SELECT SpellMiscId, AreaTriggerId, MoveCurveId, ScaleCurveId, MorphCurveId, FacingCurveId, DecalPropertiesId, TimeToTarget, TimeToTargetScale FROM `spell_areatrigger`"))
+ {
+ do
+ {
+ AreaTriggerMiscTemplate miscTemplate;
+
+ Field* areatriggerSpellMiscFields = areatriggerSpellMiscs->Fetch();
+ miscTemplate.MiscId = areatriggerSpellMiscFields[0].GetUInt32();
+
+ uint32 areatriggerId = areatriggerSpellMiscFields[1].GetUInt32();
+ miscTemplate.Template = GetAreaTriggerTemplate(areatriggerId);
+
+ if (!miscTemplate.Template)
+ {
+ TC_LOG_ERROR("sql.sql", "Table `spell_areatrigger` reference invalid AreaTriggerId %u for miscId %u", areatriggerId, miscTemplate.MiscId);
+ continue;
+ }
+
+#define VALIDATE_AND_SET_CURVE(Curve, Value) \
+ miscTemplate.Curve = Value; \
+ if (miscTemplate.Curve && !sCurveStore.LookupEntry(miscTemplate.Curve)) \
+ { \
+ TC_LOG_ERROR("sql.sql", "Table `spell_areatrigger` has listed areatrigger (MiscId: %u, Id: %u) with invalid " #Curve " (%u), set to 0!", \
+ miscTemplate.MiscId, areatriggerId, miscTemplate.Curve); \
+ miscTemplate.Curve = 0; \
+ }
+
+ VALIDATE_AND_SET_CURVE(MoveCurveId, areatriggerSpellMiscFields[2].GetUInt32());
+ VALIDATE_AND_SET_CURVE(ScaleCurveId, areatriggerSpellMiscFields[3].GetUInt32());
+ VALIDATE_AND_SET_CURVE(MorphCurveId, areatriggerSpellMiscFields[4].GetUInt32());
+ VALIDATE_AND_SET_CURVE(FacingCurveId, areatriggerSpellMiscFields[5].GetUInt32());
+
+#undef VALIDATE_AND_SET_CURVE
+
+ miscTemplate.DecalPropertiesId = areatriggerSpellMiscFields[6].GetUInt32();
+
+ miscTemplate.TimeToTarget = areatriggerSpellMiscFields[7].GetUInt32();
+ miscTemplate.TimeToTargetScale = areatriggerSpellMiscFields[8].GetUInt32();
+
+ miscTemplate.SplinePoints = splinesBySpellMisc[miscTemplate.MiscId];
+
+ _areaTriggerTemplateSpellMisc[miscTemplate.MiscId] = miscTemplate;
+ }
+ while (areatriggerSpellMiscs->NextRow());
+ }
+ else
+ {
+ TC_LOG_INFO("server.loading", ">> Loaded 0 Spell AreaTrigger templates. DB table `spell_areatrigger` is empty.");
+ }
+
+ TC_LOG_INFO("server.loading", ">> Loaded " SZFMTD " spell areatrigger templates in %u ms.", _areaTriggerTemplateStore.size(), GetMSTimeDiffToNow(oldMSTime));
+}
+
+AreaTriggerTemplate const* AreaTriggerDataStore::GetAreaTriggerTemplate(uint32 areaTriggerId) const
+{
+ auto itr = _areaTriggerTemplateStore.find(areaTriggerId);
+ if (itr != _areaTriggerTemplateStore.end())
+ return &itr->second;
+
+ return nullptr;
+}
+
+AreaTriggerMiscTemplate const* AreaTriggerDataStore::GetAreaTriggerMiscTemplate(uint32 spellMiscValue) const
+{
+ auto itr = _areaTriggerTemplateSpellMisc.find(spellMiscValue);
+ if (itr != _areaTriggerTemplateSpellMisc.end())
+ return &itr->second;
+
+ return nullptr;
+}
+
+AreaTriggerDataStore* AreaTriggerDataStore::Instance()
+{
+ static AreaTriggerDataStore instance;
+ return &instance;
+}
diff --git a/src/server/game/Globals/AreaTriggerDataStore.h b/src/server/game/Globals/AreaTriggerDataStore.h
new file mode 100644
index 00000000000..7b4707327f3
--- /dev/null
+++ b/src/server/game/Globals/AreaTriggerDataStore.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2008-2017 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 AreaTriggerDataStore_h__
+#define AreaTriggerDataStore_h__
+
+#include "Define.h"
+
+class AreaTriggerTemplate;
+class AreaTriggerMiscTemplate;
+
+class TC_GAME_API AreaTriggerDataStore
+{
+public:
+ void LoadAreaTriggerTemplates();
+
+ AreaTriggerTemplate const* GetAreaTriggerTemplate(uint32 areaTriggerId) const;
+ AreaTriggerMiscTemplate const* GetAreaTriggerMiscTemplate(uint32 spellMiscValue) const;
+
+ static AreaTriggerDataStore* Instance();
+};
+
+#define sAreaTriggerDataStore AreaTriggerDataStore::Instance()
+
+#endif // AreaTriggerDataStore_h__
diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp
index fc19f9ebad1..1ee182f4273 100644
--- a/src/server/game/Globals/ObjectMgr.cpp
+++ b/src/server/game/Globals/ObjectMgr.cpp
@@ -8763,6 +8763,8 @@ void ObjectMgr::LoadScriptNames()
"UNION "
"SELECT DISTINCT(ScriptName) FROM areatrigger_scripts WHERE ScriptName <> '' "
"UNION "
+ "SELECT DISTINCT(ScriptName) FROM areatrigger_template WHERE ScriptName <> '' "
+ "UNION "
"SELECT DISTINCT(ScriptName) FROM spell_script_names WHERE ScriptName <> '' "
"UNION "
"SELECT DISTINCT(ScriptName) FROM transports WHERE ScriptName <> '' "
diff --git a/src/server/game/Grids/Notifiers/GridNotifiers.h b/src/server/game/Grids/Notifiers/GridNotifiers.h
index 311bb9dee48..f97f5ac298a 100644
--- a/src/server/game/Grids/Notifiers/GridNotifiers.h
+++ b/src/server/game/Grids/Notifiers/GridNotifiers.h
@@ -902,11 +902,11 @@ namespace Trinity
class AnyUnitInObjectRangeCheck
{
public:
- AnyUnitInObjectRangeCheck(WorldObject const* obj, float range) : i_obj(obj), i_range(range) { }
+ AnyUnitInObjectRangeCheck(WorldObject const* obj, float range, bool check3D = true) : i_obj(obj), i_range(range), i_check3D(check3D) { }
bool operator()(Unit* u) const
{
- if (u->IsAlive() && i_obj->IsWithinDistInMap(u, i_range))
+ if (u->IsAlive() && i_obj->IsWithinDistInMap(u, i_range, i_check3D))
return true;
return false;
@@ -915,6 +915,7 @@ namespace Trinity
private:
WorldObject const* i_obj;
float i_range;
+ bool i_check3D;
};
// Success at unit in range, range update for next check (this can be use with UnitLastSearcher to find nearest unit)
diff --git a/src/server/game/Grids/ObjectGridLoader.cpp b/src/server/game/Grids/ObjectGridLoader.cpp
index 13de080ca2b..eab7573f552 100644
--- a/src/server/game/Grids/ObjectGridLoader.cpp
+++ b/src/server/game/Grids/ObjectGridLoader.cpp
@@ -213,10 +213,12 @@ void ObjectGridUnloader::Visit(GridRefManager<T> &m)
void ObjectGridStoper::Visit(CreatureMapType &m)
{
- // stop any fights at grid de-activation and remove dynobjects created at cast by creatures
+ // stop any fights at grid de-activation and remove dynobjects/areatriggers created at cast by creatures
for (CreatureMapType::iterator iter = m.begin(); iter != m.end(); ++iter)
{
iter->GetSource()->RemoveAllDynObjects();
+ iter->GetSource()->RemoveAllAreaTriggers();
+
if (iter->GetSource()->IsInCombat())
{
iter->GetSource()->CombatStop();
diff --git a/src/server/game/Handlers/MiscHandler.cpp b/src/server/game/Handlers/MiscHandler.cpp
index 813cd1fe84c..036c4a01fe6 100644
--- a/src/server/game/Handlers/MiscHandler.cpp
+++ b/src/server/game/Handlers/MiscHandler.cpp
@@ -48,6 +48,7 @@
#include "WhoPackets.h"
#include "InstancePackets.h"
#include "InstanceScript.h"
+#include "AreaTriggerPackets.h"
void WorldSession::HandleRepopRequest(WorldPackets::Misc::RepopRequest& /*packet*/)
{
@@ -464,7 +465,7 @@ void WorldSession::HandleResurrectResponse(WorldPackets::Misc::ResurrectResponse
GetPlayer()->ResurrectUsingRequestData();
}
-void WorldSession::HandleAreaTriggerOpcode(WorldPackets::Misc::AreaTrigger& packet)
+void WorldSession::HandleAreaTriggerOpcode(WorldPackets::AreaTrigger::AreaTrigger& packet)
{
Player* player = GetPlayer();
if (player->IsInFlight())
@@ -567,7 +568,7 @@ void WorldSession::HandleAreaTriggerOpcode(WorldPackets::Misc::AreaTrigger& pack
reviveAtTrigger = true;
break;
case Map::CANNOT_ENTER_CORPSE_IN_DIFFERENT_INSTANCE:
- player->GetSession()->SendPacket(WorldPackets::Misc::AreaTriggerNoCorpse().Write());
+ player->GetSession()->SendPacket(WorldPackets::AreaTrigger::AreaTriggerNoCorpse().Write());
TC_LOG_DEBUG("maps", "MAP: Player '%s' does not have a corpse in instance map %d and cannot enter", player->GetName().c_str(), at->target_mapId);
break;
case Map::CANNOT_ENTER_INSTANCE_BIND_MISMATCH:
diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp
index 6c759662c83..807232b88a1 100644
--- a/src/server/game/Maps/Map.cpp
+++ b/src/server/game/Maps/Map.cpp
@@ -234,7 +234,7 @@ void Map::DeleteStateMachine()
}
Map::Map(uint32 id, time_t expiry, uint32 InstanceId, uint8 SpawnMode, Map* _parent):
-_creatureToMoveLock(false), _gameObjectsToMoveLock(false), _dynamicObjectsToMoveLock(false),
+_creatureToMoveLock(false), _gameObjectsToMoveLock(false), _dynamicObjectsToMoveLock(false), _areaTriggersToMoveLock(false),
i_mapEntry(sMapStore.LookupEntry(id)), i_spawnMode(SpawnMode), i_InstanceId(InstanceId),
m_unloadTimer(0), m_VisibleDistance(DEFAULT_VISIBILITY_DISTANCE),
m_VisibilityNotifyPeriod(DEFAULT_VISIBILITY_NOTIFY_PERIOD),
@@ -310,6 +310,15 @@ void Map::AddToGrid(DynamicObject* obj, Cell const& cell)
}
template<>
+void Map::AddToGrid(AreaTrigger* obj, Cell const& cell)
+{
+ NGridType* grid = getNGrid(cell.GridX(), cell.GridY());
+ grid->GetGridType(cell.CellX(), cell.CellY()).AddGridObject(obj);
+
+ obj->SetCurrentCell(cell);
+}
+
+template<>
void Map::AddToGrid(Corpse* obj, Cell const& cell)
{
NGridType* grid = getNGrid(cell.GridX(), cell.GridY());
@@ -784,6 +793,7 @@ void Map::Update(const uint32 t_diff)
MoveAllCreaturesInMoveList();
MoveAllGameObjectsInMoveList();
+ MoveAllAreaTriggersInMoveList();
if (!m_mapRefManager.isEmpty() || !m_activeNonPlayers.empty())
ProcessRelocationNotifies(t_diff);
@@ -1092,6 +1102,39 @@ void Map::DynamicObjectRelocation(DynamicObject* dynObj, float x, float y, float
ASSERT(integrity_check == old_cell);
}
+void Map::AreaTriggerRelocation(AreaTrigger* at, float x, float y, float z, float orientation)
+{
+ Cell integrity_check(at->GetPositionX(), at->GetPositionY());
+ Cell old_cell = at->GetCurrentCell();
+
+ ASSERT(integrity_check == old_cell);
+ Cell new_cell(x, y);
+
+ if (!getNGrid(new_cell.GridX(), new_cell.GridY()))
+ return;
+
+ // delay areatrigger move for grid/cell to grid/cell moves
+ if (old_cell.DiffCell(new_cell) || old_cell.DiffGrid(new_cell))
+ {
+#ifdef TRINITY_DEBUG
+ TC_LOG_DEBUG("maps", "AreaTrigger (%s) added to moving list from grid[%u, %u]cell[%u, %u] to grid[%u, %u]cell[%u, %u].", at->GetGUID().ToString().c_str(), old_cell.GridX(), old_cell.GridY(), old_cell.CellX(), old_cell.CellY(), new_cell.GridX(), new_cell.GridY(), new_cell.CellX(), new_cell.CellY());
+#endif
+ AddAreaTriggerToMoveList(at, x, y, z, orientation);
+ // in diffcell/diffgrid case notifiers called at finishing move at in Map::MoveAllAreaTriggersInMoveList
+ }
+ else
+ {
+ at->Relocate(x, y, z, orientation);
+ at->UpdateShape();
+ at->UpdateObjectVisibility(false);
+ RemoveAreaTriggerFromMoveList(at);
+ }
+
+ old_cell = at->GetCurrentCell();
+ integrity_check = Cell(at->GetPositionX(), at->GetPositionY());
+ ASSERT(integrity_check == old_cell);
+}
+
void Map::AddCreatureToMoveList(Creature* c, float x, float y, float z, float ang)
{
if (_creatureToMoveLock) //can this happen?
@@ -1149,6 +1192,25 @@ void Map::RemoveDynamicObjectFromMoveList(DynamicObject* dynObj)
dynObj->_moveState = MAP_OBJECT_CELL_MOVE_INACTIVE;
}
+void Map::AddAreaTriggerToMoveList(AreaTrigger* at, float x, float y, float z, float ang)
+{
+ if (_areaTriggersToMoveLock) //can this happen?
+ return;
+
+ if (at->_moveState == MAP_OBJECT_CELL_MOVE_NONE)
+ _areaTriggersToMove.push_back(at);
+ at->SetNewCellPosition(x, y, z, ang);
+}
+
+void Map::RemoveAreaTriggerFromMoveList(AreaTrigger* at)
+{
+ if (_areaTriggersToMoveLock) //can this happen?
+ return;
+
+ if (at->_moveState == MAP_OBJECT_CELL_MOVE_ACTIVE)
+ at->_moveState = MAP_OBJECT_CELL_MOVE_INACTIVE;
+}
+
void Map::MoveAllCreaturesInMoveList()
{
_creatureToMoveLock = true;
@@ -1288,6 +1350,44 @@ void Map::MoveAllDynamicObjectsInMoveList()
_dynamicObjectsToMoveLock = false;
}
+void Map::MoveAllAreaTriggersInMoveList()
+{
+ _areaTriggersToMoveLock = true;
+ for (std::vector<AreaTrigger*>::iterator itr = _areaTriggersToMove.begin(); itr != _areaTriggersToMove.end(); ++itr)
+ {
+ AreaTrigger* at = *itr;
+ if (at->FindMap() != this) //transport is teleported to another map
+ continue;
+
+ if (at->_moveState != MAP_OBJECT_CELL_MOVE_ACTIVE)
+ {
+ at->_moveState = MAP_OBJECT_CELL_MOVE_NONE;
+ continue;
+ }
+
+ at->_moveState = MAP_OBJECT_CELL_MOVE_NONE;
+ if (!at->IsInWorld())
+ continue;
+
+ // do move or do move to respawn or remove creature if previous all fail
+ if (AreaTriggerCellRelocation(at, Cell(at->_newPosition.m_positionX, at->_newPosition.m_positionY)))
+ {
+ // update pos
+ at->Relocate(at->_newPosition);
+ at->UpdateObjectVisibility(false);
+ }
+ else
+ {
+#ifdef TRINITY_DEBUG
+ TC_LOG_DEBUG("maps", "AreaTrigger (%s) cannot be moved to unloaded grid.", at->GetGUID().ToString().c_str());
+#endif
+ }
+ }
+
+ _areaTriggersToMove.clear();
+ _areaTriggersToMoveLock = false;
+}
+
bool Map::CreatureCellRelocation(Creature* c, Cell new_cell)
{
Cell const& old_cell = c->GetCurrentCell();
@@ -1471,6 +1571,67 @@ bool Map::DynamicObjectCellRelocation(DynamicObject* go, Cell new_cell)
return false;
}
+bool Map::AreaTriggerCellRelocation(AreaTrigger* at, Cell new_cell)
+{
+ Cell const& old_cell = at->GetCurrentCell();
+ if (!old_cell.DiffGrid(new_cell)) // in same grid
+ {
+ // if in same cell then none do
+ if (old_cell.DiffCell(new_cell))
+ {
+#ifdef TRINITY_DEBUG
+ TC_LOG_DEBUG("maps", "AreaTrigger (%s) moved in grid[%u, %u] from cell[%u, %u] to cell[%u, %u].", at->GetGUID().ToString().c_str(), old_cell.GridX(), old_cell.GridY(), old_cell.CellX(), old_cell.CellY(), new_cell.CellX(), new_cell.CellY());
+#endif
+
+ at->RemoveFromGrid();
+ AddToGrid(at, new_cell);
+ }
+ else
+ {
+#ifdef TRINITY_DEBUG
+ TC_LOG_DEBUG("maps", "AreaTrigger (%s) moved in same grid[%u, %u]cell[%u, %u].", at->GetGUID().ToString().c_str(), old_cell.GridX(), old_cell.GridY(), old_cell.CellX(), old_cell.CellY());
+#endif
+ }
+
+ return true;
+ }
+
+ // in diff. grids but active AreaTrigger
+ if (at->isActiveObject())
+ {
+ EnsureGridLoadedForActiveObject(new_cell, at);
+
+#ifdef TRINITY_DEBUG
+ TC_LOG_DEBUG("maps", "Active AreaTrigger (%s) moved from grid[%u, %u]cell[%u, %u] to grid[%u, %u]cell[%u, %u].", at->GetGUID().ToString().c_str(), old_cell.GridX(), old_cell.GridY(), old_cell.CellX(), old_cell.CellY(), new_cell.GridX(), new_cell.GridY(), new_cell.CellX(), new_cell.CellY());
+#endif
+
+ at->RemoveFromGrid();
+ AddToGrid(at, new_cell);
+
+ return true;
+ }
+
+ // in diff. loaded grid normal AreaTrigger
+ if (IsGridLoaded(GridCoord(new_cell.GridX(), new_cell.GridY())))
+ {
+#ifdef TRINITY_DEBUG
+ TC_LOG_DEBUG("maps", "AreaTrigger (%s) moved from grid[%u, %u]cell[%u, %u] to grid[%u, %u]cell[%u, %u].", at->GetGUID().ToString().c_str(), old_cell.GridX(), old_cell.GridY(), old_cell.CellX(), old_cell.CellY(), new_cell.GridX(), new_cell.GridY(), new_cell.CellX(), new_cell.CellY());
+#endif
+
+ at->RemoveFromGrid();
+ EnsureGridCreated(GridCoord(new_cell.GridX(), new_cell.GridY()));
+ AddToGrid(at, new_cell);
+
+ return true;
+ }
+
+ // fail to move: normal AreaTrigger attempt move to unloaded grid
+#ifdef TRINITY_DEBUG
+ TC_LOG_DEBUG("maps", "AreaTrigger (%s) attempted to move from grid[%u, %u]cell[%u, %u] to unloaded grid[%u, %u]cell[%u, %u].", at->GetGUID().ToString().c_str(), old_cell.GridX(), old_cell.GridY(), old_cell.CellX(), old_cell.CellY(), new_cell.GridX(), new_cell.GridY(), new_cell.CellX(), new_cell.CellY());
+#endif
+ return false;
+}
+
bool Map::CreatureRespawnRelocation(Creature* c, bool diffGridOnly)
{
float resp_x, resp_y, resp_z, resp_o;
@@ -1550,6 +1711,7 @@ bool Map::UnloadGrid(NGridType& ngrid, bool unloadAll)
// Must know real mob position before move
MoveAllCreaturesInMoveList();
MoveAllGameObjectsInMoveList();
+ MoveAllAreaTriggersInMoveList();
// move creatures to respawn grids if this is diff.grid or to remove list
ObjectGridEvacuator worker;
@@ -1559,6 +1721,7 @@ bool Map::UnloadGrid(NGridType& ngrid, bool unloadAll)
// Finish creature moves, remove and delete all creatures with delayed remove before unload
MoveAllCreaturesInMoveList();
MoveAllGameObjectsInMoveList();
+ MoveAllAreaTriggersInMoveList();
}
{
diff --git a/src/server/game/Maps/Map.h b/src/server/game/Maps/Map.h
index b209f83189a..913128f818d 100644
--- a/src/server/game/Maps/Map.h
+++ b/src/server/game/Maps/Map.h
@@ -299,6 +299,7 @@ class TC_GAME_API Map : public GridRefManager<NGridType>
void CreatureRelocation(Creature* creature, float x, float y, float z, float ang, bool respawnRelocationOnFail = true);
void GameObjectRelocation(GameObject* go, float x, float y, float z, float orientation, bool respawnRelocationOnFail = true);
void DynamicObjectRelocation(DynamicObject* go, float x, float y, float z, float orientation);
+ void AreaTriggerRelocation(AreaTrigger* at, float x, float y, float z, float orientation);
template<class T, class CONTAINER>
void Visit(const Cell& cell, TypeContainerVisitor<T, CONTAINER> &visitor);
@@ -359,6 +360,7 @@ class TC_GAME_API Map : public GridRefManager<NGridType>
void MoveAllCreaturesInMoveList();
void MoveAllGameObjectsInMoveList();
void MoveAllDynamicObjectsInMoveList();
+ void MoveAllAreaTriggersInMoveList();
void RemoveAllObjectsInRemoveList();
virtual void RemoveAllPlayers();
@@ -588,6 +590,7 @@ class TC_GAME_API Map : public GridRefManager<NGridType>
bool CreatureCellRelocation(Creature* creature, Cell new_cell);
bool GameObjectCellRelocation(GameObject* go, Cell new_cell);
bool DynamicObjectCellRelocation(DynamicObject* go, Cell new_cell);
+ bool AreaTriggerCellRelocation(AreaTrigger* at, Cell new_cell);
template<class T> void InitializeObject(T* obj);
void AddCreatureToMoveList(Creature* c, float x, float y, float z, float ang);
@@ -596,6 +599,8 @@ class TC_GAME_API Map : public GridRefManager<NGridType>
void RemoveGameObjectFromMoveList(GameObject* go);
void AddDynamicObjectToMoveList(DynamicObject* go, float x, float y, float z, float ang);
void RemoveDynamicObjectFromMoveList(DynamicObject* go);
+ void AddAreaTriggerToMoveList(AreaTrigger* at, float x, float y, float z, float ang);
+ void RemoveAreaTriggerFromMoveList(AreaTrigger* at);
bool _creatureToMoveLock;
std::vector<Creature*> _creaturesToMove;
@@ -606,6 +611,9 @@ class TC_GAME_API Map : public GridRefManager<NGridType>
bool _dynamicObjectsToMoveLock;
std::vector<DynamicObject*> _dynamicObjectsToMove;
+ bool _areaTriggersToMoveLock;
+ std::vector<AreaTrigger*> _areaTriggersToMove;
+
bool IsGridLoaded(const GridCoord &) const;
void EnsureGridCreated(const GridCoord &);
void EnsureGridCreated_i(const GridCoord &);
diff --git a/src/server/game/Scripting/ScriptMgr.cpp b/src/server/game/Scripting/ScriptMgr.cpp
index 2e48d791525..7c94aa3ed55 100644
--- a/src/server/game/Scripting/ScriptMgr.cpp
+++ b/src/server/game/Scripting/ScriptMgr.cpp
@@ -97,6 +97,10 @@ struct is_script_database_bound<AchievementCriteriaScript>
: std::true_type { };
template<>
+struct is_script_database_bound<AreaTriggerEntityScript>
+ : std::true_type { };
+
+template<>
struct is_script_database_bound<SceneScript>
: std::true_type { };
@@ -662,6 +666,35 @@ private:
bool swapped;
};
+/// This hook is responsible for swapping AreaTriggerEntityScript's
+template<typename Base>
+class ScriptRegistrySwapHooks<AreaTriggerEntityScript, Base>
+ : public ScriptRegistrySwapHookBase
+{
+public:
+ ScriptRegistrySwapHooks() : swapped(false) { }
+
+ void BeforeReleaseContext(std::string const& context) final override
+ {
+ auto const bounds = static_cast<Base*>(this)->_ids_of_contexts.equal_range(context);
+ if (bounds.first != bounds.second)
+ swapped = true;
+ }
+
+ void BeforeSwapContext(bool /*initialize*/) override
+ {
+ swapped = false;
+ }
+
+ void BeforeUnload() final override
+ {
+ ASSERT(!swapped);
+ }
+
+private:
+ bool swapped;
+};
+
/// This hook is responsible for swapping SceneScript's
template<typename Base>
class ScriptRegistrySwapHooks<SceneScript, Base>
@@ -2337,6 +2370,73 @@ void ScriptMgr::ModifySpellDamageTaken(Unit* target, Unit* attacker, int32& dama
FOREACH_SCRIPT(PlayerScript)->ModifySpellDamageTaken(target, attacker, damage);
}
+// AreaTriggerEntityScript
+void ScriptMgr::OnAreaTriggerEntityInitialize(AreaTrigger* areaTrigger)
+{
+ ASSERT(areaTrigger);
+
+ GET_SCRIPT(AreaTriggerEntityScript, areaTrigger->GetScriptId(), tmpscript);
+ tmpscript->OnInitialize(areaTrigger);
+}
+
+void ScriptMgr::OnAreaTriggerEntityCreate(AreaTrigger* areaTrigger)
+{
+ ASSERT(areaTrigger);
+
+ GET_SCRIPT(AreaTriggerEntityScript, areaTrigger->GetScriptId(), tmpscript);
+ tmpscript->OnCreate(areaTrigger);
+}
+
+void ScriptMgr::OnAreaTriggerEntityUpdate(AreaTrigger* areaTrigger, uint32 diff)
+{
+ ASSERT(areaTrigger);
+
+ GET_SCRIPT(AreaTriggerEntityScript, areaTrigger->GetScriptId(), tmpscript);
+ tmpscript->OnUpdate(areaTrigger, diff);
+}
+
+void ScriptMgr::OnAreaTriggerEntitySplineIndexReached(AreaTrigger* areaTrigger, int splineIndex)
+{
+ ASSERT(areaTrigger);
+
+ GET_SCRIPT(AreaTriggerEntityScript, areaTrigger->GetScriptId(), tmpscript);
+ tmpscript->OnSplineIndexReached(areaTrigger, splineIndex);
+}
+
+void ScriptMgr::OnAreaTriggerEntityDestinationReached(AreaTrigger* areaTrigger)
+{
+ ASSERT(areaTrigger);
+
+ GET_SCRIPT(AreaTriggerEntityScript, areaTrigger->GetScriptId(), tmpscript);
+ tmpscript->OnDestinationReached(areaTrigger);
+}
+
+void ScriptMgr::OnAreaTriggerEntityUnitEnter(AreaTrigger* areaTrigger, Unit* unit)
+{
+ ASSERT(areaTrigger);
+ ASSERT(unit);
+
+ GET_SCRIPT(AreaTriggerEntityScript, areaTrigger->GetScriptId(), tmpscript);
+ tmpscript->OnUnitEnter(areaTrigger, unit);
+}
+
+void ScriptMgr::OnAreaTriggerEntityUnitExit(AreaTrigger* areaTrigger, Unit* unit)
+{
+ ASSERT(areaTrigger);
+ ASSERT(unit);
+
+ GET_SCRIPT(AreaTriggerEntityScript, areaTrigger->GetScriptId(), tmpscript);
+ tmpscript->OnUnitExit(areaTrigger, unit);
+}
+
+void ScriptMgr::OnAreaTriggerEntityRemove(AreaTrigger* areaTrigger)
+{
+ ASSERT(areaTrigger);
+
+ GET_SCRIPT(AreaTriggerEntityScript, areaTrigger->GetScriptId(), tmpscript);
+ tmpscript->OnRemove(areaTrigger);
+}
+
// Scene
void ScriptMgr::OnSceneStart(Player* player, uint32 sceneInstanceID, SceneTemplate const* sceneTemplate)
{
@@ -2546,6 +2646,12 @@ GroupScript::GroupScript(const char* name)
ScriptRegistry<GroupScript>::Instance()->AddScript(this);
}
+AreaTriggerEntityScript::AreaTriggerEntityScript(const char* name)
+ : ScriptObject(name)
+{
+ ScriptRegistry<AreaTriggerEntityScript>::Instance()->AddScript(this);
+}
+
// Specialize for each script type class like so:
template class TC_GAME_API ScriptRegistry<SpellScriptLoader>;
template class TC_GAME_API ScriptRegistry<ServerScript>;
@@ -2573,4 +2679,5 @@ template class TC_GAME_API ScriptRegistry<GuildScript>;
template class TC_GAME_API ScriptRegistry<GroupScript>;
template class TC_GAME_API ScriptRegistry<UnitScript>;
template class TC_GAME_API ScriptRegistry<AccountScript>;
+template class TC_GAME_API ScriptRegistry<AreaTriggerEntityScript>;
template class TC_GAME_API ScriptRegistry<SceneScript>;
diff --git a/src/server/game/Scripting/ScriptMgr.h b/src/server/game/Scripting/ScriptMgr.h
index 6c0b660fb0b..76a5f663f82 100644
--- a/src/server/game/Scripting/ScriptMgr.h
+++ b/src/server/game/Scripting/ScriptMgr.h
@@ -28,6 +28,7 @@
#include "Weather.h"
class AccountMgr;
+class AreaTrigger;
class AuctionHouseObject;
class Aura;
class AuraScript;
@@ -836,6 +837,38 @@ class TC_GAME_API GroupScript : public ScriptObject
virtual void OnDisband(Group* /*group*/) { }
};
+class TC_GAME_API AreaTriggerEntityScript : public ScriptObject
+{
+ protected:
+
+ AreaTriggerEntityScript(const char* name);
+
+ public:
+ // Called when the AreaTrigger has just been initialized, just before added to map
+ virtual void OnInitialize(AreaTrigger* /*areaTrigger*/) { }
+
+ // Called when the AreaTrigger has just been created
+ virtual void OnCreate(AreaTrigger* /*areaTrigger*/) { }
+
+ // Called on each AreaTrigger update
+ virtual void OnUpdate(AreaTrigger* /*areaTrigger*/, uint32 /*diff*/) { }
+
+ // Called when the AreaTrigger reach splineIndex
+ virtual void OnSplineIndexReached(AreaTrigger* /*areaTrigger*/, int /*splineIndex*/) { }
+
+ // Called when the AreaTrigger reach its destination
+ virtual void OnDestinationReached(AreaTrigger* /*areaTrigger*/) { }
+
+ // Called when an unit enter the AreaTrigger
+ virtual void OnUnitEnter(AreaTrigger* /*areaTrigger*/, Unit* /*unit*/) { }
+
+ // Called when an unit exit the AreaTrigger, or when the AreaTrigger is removed
+ virtual void OnUnitExit(AreaTrigger* /*areaTrigger*/, Unit* /*unit*/) { }
+
+ // Called when the AreaTrigger is removed
+ virtual void OnRemove(AreaTrigger* /*areaTrigger*/) { }
+};
+
class TC_GAME_API SceneScript : public ScriptObject
{
protected:
@@ -1133,6 +1166,17 @@ class TC_GAME_API ScriptMgr
void ModifyMeleeDamage(Unit* target, Unit* attacker, uint32& damage);
void ModifySpellDamageTaken(Unit* target, Unit* attacker, int32& damage);
+ public: /* AreaTriggerEntityScript */
+
+ void OnAreaTriggerEntityInitialize(AreaTrigger* areaTrigger);
+ void OnAreaTriggerEntityCreate(AreaTrigger* areaTrigger);
+ void OnAreaTriggerEntityUpdate(AreaTrigger* areaTrigger, uint32 diff);
+ void OnAreaTriggerEntitySplineIndexReached(AreaTrigger* areaTrigger, int splineIndex);
+ void OnAreaTriggerEntityDestinationReached(AreaTrigger* areaTrigger);
+ void OnAreaTriggerEntityUnitEnter(AreaTrigger* areaTrigger, Unit* unit);
+ void OnAreaTriggerEntityUnitExit(AreaTrigger* areaTrigger, Unit* unit);
+ void OnAreaTriggerEntityRemove(AreaTrigger* areaTrigger);
+
public: /* SceneScript */
void OnSceneStart(Player* player, uint32 sceneInstanceID, SceneTemplate const* sceneTemplate);
void OnSceneTrigger(Player* player, uint32 sceneInstanceID, SceneTemplate const* sceneTemplate, std::string const& triggerName);
diff --git a/src/server/game/Server/Packets/AllPackets.h b/src/server/game/Server/Packets/AllPackets.h
index 034496d027d..732a8c1d081 100644
--- a/src/server/game/Server/Packets/AllPackets.h
+++ b/src/server/game/Server/Packets/AllPackets.h
@@ -19,6 +19,7 @@
#define AllPackets_h__
#include "AchievementPackets.h"
+#include "AreaTriggerPackets.h"
#include "ArtifactPackets.h"
#include "AuctionHousePackets.h"
#include "AuthenticationPackets.h"
diff --git a/src/server/game/Server/Packets/AreaTriggerPackets.cpp b/src/server/game/Server/Packets/AreaTriggerPackets.cpp
new file mode 100644
index 00000000000..446a37534a9
--- /dev/null
+++ b/src/server/game/Server/Packets/AreaTriggerPackets.cpp
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2008-2017 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 "AreaTriggerPackets.h"
+
+ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::AreaTrigger::AreaTriggerSplineInfo const& areaTriggerSpline)
+{
+ data << uint32(areaTriggerSpline.TimeToTarget);
+ data << uint32(areaTriggerSpline.ElapsedTimeForMovement);
+
+ data.WriteBits(areaTriggerSpline.Points.size(), 16);
+ data.FlushBits();
+
+ for (G3D::Vector3 const& point : areaTriggerSpline.Points)
+ data << point;
+
+ return data;
+}
+
+ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::AreaTrigger::AreaTriggerUnkTypeInfo const& areaTriggerUnkType)
+{
+ data.WriteBit(areaTriggerUnkType.AreaTriggerUnkGUID.is_initialized());
+ data.WriteBit(areaTriggerUnkType.Center.is_initialized());
+ data.WriteBit(areaTriggerUnkType.UnkBit1);
+ data.WriteBit(areaTriggerUnkType.UnkBit2);
+
+ data << uint32(areaTriggerUnkType.UnkUInt1);
+ data << int32(areaTriggerUnkType.UnkInt1);
+ data << uint32(areaTriggerUnkType.UnkUInt2);
+ data << float(areaTriggerUnkType.Radius);
+ data << float(areaTriggerUnkType.BlendFromRadius);
+ data << float(areaTriggerUnkType.InitialAngel);
+ data << float(areaTriggerUnkType.ZOffset);
+
+ if (areaTriggerUnkType.AreaTriggerUnkGUID)
+ data << *areaTriggerUnkType.AreaTriggerUnkGUID;
+
+ if (areaTriggerUnkType.Center)
+ data << *areaTriggerUnkType.Center;
+
+ return data;
+}
+
+void WorldPackets::AreaTrigger::AreaTrigger::Read()
+{
+ _worldPacket >> AreaTriggerID;
+ Entered = _worldPacket.ReadBit();
+ FromClient = _worldPacket.ReadBit();
+}
+
+WorldPacket const* WorldPackets::AreaTrigger::AreaTriggerDenied::Write()
+{
+ _worldPacket << int32(AreaTriggerID);
+ _worldPacket.WriteBit(Entered);
+ _worldPacket.FlushBits();
+
+ return &_worldPacket;
+}
+
+WorldPacket const* WorldPackets::AreaTrigger::AreaTriggerRePath::Write()
+{
+ _worldPacket << TriggerGUID;
+ _worldPacket << AreaTriggerSpline;
+
+ return &_worldPacket;
+}
+
+WorldPacket const* WorldPackets::AreaTrigger::AreaTriggerReShape::Write()
+{
+ _worldPacket << TriggerGUID;
+
+ _worldPacket.WriteBit(AreaTriggerSpline.is_initialized());
+ _worldPacket.WriteBit(AreaTriggerUnkType.is_initialized());
+ _worldPacket.FlushBits();
+
+ if (AreaTriggerSpline)
+ _worldPacket << *AreaTriggerSpline;
+
+ if (AreaTriggerUnkType)
+ _worldPacket << *AreaTriggerUnkType;
+
+ return &_worldPacket;
+}
diff --git a/src/server/game/Server/Packets/AreaTriggerPackets.h b/src/server/game/Server/Packets/AreaTriggerPackets.h
new file mode 100644
index 00000000000..967a8ba0f5f
--- /dev/null
+++ b/src/server/game/Server/Packets/AreaTriggerPackets.h
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2008-2017 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 AreaTriggerPackets_h__
+#define AreaTriggerPackets_h__
+
+#include "Packet.h"
+#include "PacketUtilities.h"
+#include "ObjectGuid.h"
+
+namespace WorldPackets
+{
+ namespace AreaTrigger
+ {
+ struct AreaTriggerSplineInfo
+ {
+ uint32 TimeToTarget = 0;
+ uint32 ElapsedTimeForMovement = 0;
+ std::vector<G3D::Vector3> Points;
+ };
+
+ struct AreaTriggerUnkTypeInfo
+ {
+ Optional<ObjectGuid> AreaTriggerUnkGUID;
+ Optional<G3D::Vector3> Center;
+ bool UnkBit1 = false;
+ bool UnkBit2 = false;
+ uint32 UnkUInt1 = 0;
+ int32 UnkInt1 = 0;
+ uint32 UnkUInt2 = 0;
+ float Radius = 0.0;
+ float BlendFromRadius = 0.0f;
+ float InitialAngel = 0.0f;
+ float ZOffset = 0.0f;
+ };
+
+ class AreaTrigger final : public ClientPacket
+ {
+ public:
+ AreaTrigger(WorldPacket&& packet) : ClientPacket(CMSG_AREA_TRIGGER, std::move(packet)) { }
+
+ void Read() override;
+
+ int32 AreaTriggerID = 0;
+ bool Entered = false;
+ bool FromClient = false;
+ };
+
+ class AreaTriggerDenied final : public ServerPacket
+ {
+ public:
+ AreaTriggerDenied() : ServerPacket(SMSG_AREA_TRIGGER_DENIED, 5) { }
+
+ int32 AreaTriggerID = 0;
+ bool Entered = false;
+
+ WorldPacket const* Write() override;
+ };
+
+ class AreaTriggerNoCorpse final : public ServerPacket
+ {
+ public:
+ AreaTriggerNoCorpse() : ServerPacket(SMSG_AREA_TRIGGER_NO_CORPSE, 0) { }
+
+ WorldPacket const* Write() override { return &_worldPacket; }
+ };
+
+ class AreaTriggerRePath final : public ServerPacket
+ {
+ public:
+ AreaTriggerRePath() : ServerPacket(SMSG_AREA_TRIGGER_RE_PATH, 50) { }
+
+ WorldPacket const* Write() override;
+
+ AreaTriggerSplineInfo AreaTriggerSpline;
+ ObjectGuid TriggerGUID;
+ };
+
+ class AreaTriggerReShape final : public ServerPacket
+ {
+ public:
+ AreaTriggerReShape() : ServerPacket(SMSG_AREA_TRIGGER_RE_SHAPE, 17) { }
+
+ WorldPacket const* Write() override;
+
+ Optional<AreaTriggerSplineInfo> AreaTriggerSpline;
+ Optional<AreaTriggerUnkTypeInfo> AreaTriggerUnkType;
+ ObjectGuid TriggerGUID;
+ };
+ }
+}
+
+#endif // AreaTriggerPackets_h__
diff --git a/src/server/game/Server/Packets/MiscPackets.cpp b/src/server/game/Server/Packets/MiscPackets.cpp
index 18e46e81356..4880b750319 100644
--- a/src/server/game/Server/Packets/MiscPackets.cpp
+++ b/src/server/game/Server/Packets/MiscPackets.cpp
@@ -178,13 +178,6 @@ WorldPacket const* WorldPackets::Misc::WorldServerInfo::Write()
return &_worldPacket;
}
-void WorldPackets::Misc::AreaTrigger::Read()
-{
- _worldPacket >> AreaTriggerID;
- Entered = _worldPacket.ReadBit();
- FromClient = _worldPacket.ReadBit();
-}
-
void WorldPackets::Misc::SetDungeonDifficulty::Read()
{
_worldPacket >> DifficultyID;
diff --git a/src/server/game/Server/Packets/MiscPackets.h b/src/server/game/Server/Packets/MiscPackets.h
index becb5c81661..b9ee1dd0480 100644
--- a/src/server/game/Server/Packets/MiscPackets.h
+++ b/src/server/game/Server/Packets/MiscPackets.h
@@ -247,18 +247,6 @@ namespace WorldPackets
Optional<uint32> InstanceGroupSize;
};
- class AreaTrigger final : public ClientPacket
- {
- public:
- AreaTrigger(WorldPacket&& packet) : ClientPacket(CMSG_AREA_TRIGGER, std::move(packet)) { }
-
- void Read() override;
-
- int32 AreaTriggerID = 0;
- bool Entered = false;
- bool FromClient = false;
- };
-
class SetDungeonDifficulty final : public ClientPacket
{
public:
@@ -390,15 +378,7 @@ namespace WorldPackets
uint32 Response = 0;
};
- class AreaTriggerNoCorpse final : public ServerPacket
- {
- public:
- AreaTriggerNoCorpse() : ServerPacket(SMSG_AREA_TRIGGER_NO_CORPSE, 0) { }
-
- WorldPacket const* Write() override { return &_worldPacket; }
- };
-
- class TC_GAME_API Weather final : public ServerPacket
+ class TC_GAME_API Weather final : public ServerPacket
{
public:
Weather();
diff --git a/src/server/game/Server/Protocol/Opcodes.cpp b/src/server/game/Server/Protocol/Opcodes.cpp
index 26f151a5d2b..7bc9b2c59d0 100644
--- a/src/server/game/Server/Protocol/Opcodes.cpp
+++ b/src/server/game/Server/Protocol/Opcodes.cpp
@@ -857,10 +857,10 @@ void OpcodeTable::Initialize()
DEFINE_SERVER_OPCODE_HANDLER(SMSG_ALL_GUILD_ACHIEVEMENTS, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_ARCHAEOLOGY_SURVERY_CAST, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_AREA_SPIRIT_HEALER_TIME, STATUS_NEVER, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_AREA_TRIGGER_DENIED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_AREA_TRIGGER_DENIED, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_AREA_TRIGGER_NO_CORPSE, STATUS_NEVER, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_AREA_TRIGGER_RE_PATH, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_AREA_TRIGGER_RE_SHAPE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_AREA_TRIGGER_RE_PATH, STATUS_NEVER, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_AREA_TRIGGER_RE_SHAPE, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_ARENA_ERROR, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_ARENA_PREP_OPPONENT_SPECIALIZATIONS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_ARTIFACT_APPEARANCE_CHANGED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h
index dd5c32133c3..1469a1f1d4f 100644
--- a/src/server/game/Server/WorldSession.h
+++ b/src/server/game/Server/WorldSession.h
@@ -81,6 +81,11 @@ namespace WorldPackets
class GuildGetAchievementMembers;
}
+ namespace AreaTrigger
+ {
+ class AreaTrigger;
+ }
+
namespace Artifact
{
class ArtifactAddPower;
@@ -405,7 +410,6 @@ namespace WorldPackets
namespace Misc
{
- class AreaTrigger;
class SetSelection;
class ViolenceLevel;
class TimeSyncResponse;
@@ -1228,7 +1232,7 @@ class TC_GAME_API WorldSession
void HandleDelIgnoreOpcode(WorldPackets::Social::DelIgnore& packet);
void HandleSetContactNotesOpcode(WorldPackets::Social::SetContactNotes& packet);
- void HandleAreaTriggerOpcode(WorldPackets::Misc::AreaTrigger& packet);
+ void HandleAreaTriggerOpcode(WorldPackets::AreaTrigger::AreaTrigger& packet);
void HandleSetFactionAtWar(WorldPackets::Character::SetFactionAtWar& packet);
void HandleSetFactionNotAtWar(WorldPackets::Character::SetFactionNotAtWar& packet);
diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
index 14b2e5eb607..856d8e586d0 100644
--- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp
+++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
@@ -454,7 +454,7 @@ pAuraEffectHandler AuraEffectHandler[TOTAL_AURAS]=
&AuraEffect::HandleNULL, //392
&AuraEffect::HandleNULL, //393
&AuraEffect::HandleShowConfirmationPrompt, //394 SPELL_AURA_SHOW_CONFIRMATION_PROMPT
- &AuraEffect::HandleNULL, //395 SPELL_AURA_AREA_TRIGGER
+ &AuraEffect::HandleCreateAreaTrigger, //395 SPELL_AURA_AREA_TRIGGER
&AuraEffect::HandleNoImmediateEffect, //396 SPELL_AURA_PROC_ON_POWER_AMOUNT_2 implemented in Unit::HandleAuraProcOnPowerAmount
&AuraEffect::HandleNULL, //397
&AuraEffect::HandleNULL, //398
@@ -6573,3 +6573,23 @@ void AuraEffect::HandlePlayScene(AuraApplication const* aurApp, uint8 mode, bool
player->GetSceneMgr().CancelSceneByPackageId(sceneTemplate->ScenePackageId);
}
}
+
+void AuraEffect::HandleCreateAreaTrigger(AuraApplication const* aurApp, uint8 mode, bool apply) const
+{
+ if (!(mode & AURA_EFFECT_HANDLE_REAL))
+ return;
+
+ Unit* target = aurApp->GetTarget();
+
+ if (apply)
+ {
+ AreaTrigger* areaTrigger = new AreaTrigger();
+ if (!areaTrigger->CreateAreaTrigger(GetMiscValue(), GetCaster(), target, GetSpellInfo(), *target, GetBase()->GetDuration(), GetBase()->GetSpellXSpellVisualId()))
+ delete areaTrigger;
+ }
+ else
+ {
+ if (Unit* caster = GetCaster())
+ caster->RemoveAreaTrigger(GetSpellInfo()->Id);
+ }
+}
diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.h b/src/server/game/Spells/Auras/SpellAuraEffects.h
index eb7dc1f3448..494884f355e 100644
--- a/src/server/game/Spells/Auras/SpellAuraEffects.h
+++ b/src/server/game/Spells/Auras/SpellAuraEffects.h
@@ -310,6 +310,7 @@ class TC_GAME_API AuraEffect
void HandleOverridePetSpecs(AuraApplication const* aurApp, uint8 mode, bool apply) const;
void HandleAllowUsingGameobjectsWhileMounted(AuraApplication const* aurApp, uint8 mode, bool apply) const;
void HandlePlayScene(AuraApplication const* aurApp, uint8 mode, bool apply) const;
+ void HandleCreateAreaTrigger(AuraApplication const* aurApp, uint8 mode, bool apply) const;
// aura effect periodic tick handlers
void HandlePeriodicDummyAuraTick(Unit* target, Unit* caster) const;
diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp
index 12b56dc1ccf..2bd23ee79dc 100644
--- a/src/server/game/Spells/SpellEffects.cpp
+++ b/src/server/game/Spells/SpellEffects.cpp
@@ -2021,9 +2021,7 @@ void Spell::EffectSummonType(SpellEffIndex effIndex)
if (!m_originalCaster)
return;
- int32 duration = m_spellInfo->GetDuration();
- if (Player* modOwner = m_originalCaster->GetSpellModOwner())
- modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_DURATION, duration);
+ int32 duration = m_spellInfo->CalcDuration(m_originalCaster);
TempSummon* summon = NULL;
@@ -2377,7 +2375,7 @@ void Spell::EffectAddFarsight(SpellEffIndex /*effIndex*/)
return;
float radius = effectInfo->CalcRadius();
- int32 duration = m_spellInfo->GetDuration();
+ int32 duration = m_spellInfo->CalcDuration(m_caster);
// Caster not in world, might be spell triggered from aura removal
if (!m_caster->IsInWorld())
return;
@@ -3168,7 +3166,7 @@ void Spell::EffectSummonObjectWild(SpellEffIndex effIndex)
pGameObj->CopyPhaseFrom(m_caster);
- int32 duration = m_spellInfo->GetDuration();
+ int32 duration = m_spellInfo->CalcDuration(m_caster);
pGameObj->SetRespawnTime(duration > 0 ? duration/IN_MILLISECONDS : 0);
pGameObj->SetSpellId(m_spellInfo->Id);
@@ -3794,7 +3792,7 @@ void Spell::EffectDuel(SpellEffIndex effIndex)
pGameObj->SetUInt32Value(GAMEOBJECT_FACTION, m_caster->getFaction());
pGameObj->SetUInt32Value(GAMEOBJECT_LEVEL, m_caster->getLevel()+1);
- int32 duration = m_spellInfo->GetDuration();
+ int32 duration = m_spellInfo->CalcDuration(m_caster);
pGameObj->SetRespawnTime(duration > 0 ? duration/IN_MILLISECONDS : 0);
pGameObj->SetSpellId(m_spellInfo->Id);
@@ -4128,7 +4126,7 @@ void Spell::EffectSummonObject(SpellEffIndex effIndex)
go->CopyPhaseFrom(m_caster);
//pGameObj->SetUInt32Value(GAMEOBJECT_LEVEL, m_caster->getLevel());
- int32 duration = m_spellInfo->GetDuration();
+ int32 duration = m_spellInfo->CalcDuration(m_caster);
go->SetRespawnTime(duration > 0 ? duration/IN_MILLISECONDS : 0);
go->SetSpellId(m_spellInfo->Id);
m_caster->AddGameObject(go);
@@ -4785,7 +4783,7 @@ void Spell::EffectTransmitted(SpellEffIndex effIndex)
pGameObj->CopyPhaseFrom(m_caster);
- int32 duration = m_spellInfo->GetDuration();
+ int32 duration = m_spellInfo->CalcDuration(m_caster);
switch (goinfo->type)
{
@@ -5296,10 +5294,7 @@ void Spell::SummonGuardian(uint32 i, uint32 entry, SummonPropertiesEntry const*
level = skill202 / 5;
float radius = 5.0f;
- int32 duration = m_spellInfo->GetDuration();
-
- if (Player* modOwner = m_originalCaster->GetSpellModOwner())
- modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_DURATION, duration);
+ int32 duration = m_spellInfo->CalcDuration(m_originalCaster);
//TempSummonType summonType = (duration == 0) ? TEMPSUMMON_DEAD_DESPAWN : TEMPSUMMON_TIMED_DESPAWN;
Map* map = caster->GetMap();
@@ -5612,17 +5607,12 @@ void Spell::EffectCreateAreaTrigger(SpellEffIndex /*effIndex*/)
if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT)
return;
- Position pos;
if (!m_targets.HasDst())
- pos = GetCaster()->GetPosition();
- else
- pos = destTarget->GetPosition();
-
- // trigger entry/miscvalue relation is currently unknown, for now use MiscValue as trigger entry
- uint32 triggerEntry = effectInfo->MiscValue;
+ return;
- AreaTrigger * areaTrigger = new AreaTrigger;
- if (!areaTrigger->CreateAreaTrigger(GetCaster()->GetMap()->GenerateLowGuid<HighGuid::AreaTrigger>(), triggerEntry, GetCaster(), GetSpellInfo(), pos, m_SpellVisual))
+ int32 duration = GetSpellInfo()->CalcDuration(GetCaster());
+ AreaTrigger* areaTrigger = new AreaTrigger();
+ if (!areaTrigger->CreateAreaTrigger(effectInfo->MiscValue, GetCaster(), nullptr, GetSpellInfo(), destTarget->GetPosition(), duration, m_SpellVisual, m_castId))
delete areaTrigger;
}
diff --git a/src/server/game/Spells/SpellInfo.cpp b/src/server/game/Spells/SpellInfo.cpp
index ccc5d81d5c8..c08a0c43374 100644
--- a/src/server/game/Spells/SpellInfo.cpp
+++ b/src/server/game/Spells/SpellInfo.cpp
@@ -2445,6 +2445,17 @@ float SpellInfo::GetMaxRange(bool positive, Unit* caster, Spell* spell) const
return range;
}
+int32 SpellInfo::CalcDuration(Unit* caster /*= nullptr*/) const
+{
+ int32 duration = GetDuration();
+
+ if (caster)
+ if (Player* modOwner = caster->GetSpellModOwner())
+ modOwner->ApplySpellMod(Id, SPELLMOD_DURATION, duration);
+
+ return duration;
+}
+
int32 SpellInfo::GetDuration() const
{
if (!DurationEntry)
diff --git a/src/server/game/Spells/SpellInfo.h b/src/server/game/Spells/SpellInfo.h
index 3f8a4dc38dd..2c5049dd4ae 100644
--- a/src/server/game/Spells/SpellInfo.h
+++ b/src/server/game/Spells/SpellInfo.h
@@ -503,6 +503,7 @@ public:
float GetMinRange(bool positive = false) const;
float GetMaxRange(bool positive = false, Unit* caster = NULL, Spell* spell = NULL) const;
+ int32 CalcDuration(Unit* caster = nullptr) const;
int32 GetDuration() const;
int32 GetMaxDuration() const;
diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp
index c2da938cfa8..382d1cd3b65 100644
--- a/src/server/game/World/World.cpp
+++ b/src/server/game/World/World.cpp
@@ -22,6 +22,7 @@
#include "World.h"
#include "AchievementMgr.h"
+#include "AreaTriggerDataStore.h"
#include "ArenaTeamMgr.h"
#include "AuctionHouseBot.h"
#include "AuctionHouseMgr.h"
@@ -1794,6 +1795,9 @@ void World::SetInitialWorldSettings()
TC_LOG_INFO("server.loading", "Loading Pet Name Parts...");
sObjectMgr->LoadPetNames();
+ TC_LOG_INFO("server.loading", "Loading AreaTrigger Templates...");
+ sAreaTriggerDataStore->LoadAreaTriggerTemplates();
+
TC_LOG_INFO("server.loading", "Loading Scenes Templates...");
sObjectMgr->LoadSceneTemplates();
diff --git a/src/server/scripts/Commands/cs_reload.cpp b/src/server/scripts/Commands/cs_reload.cpp
index 0f1325be444..4bc97623254 100644
--- a/src/server/scripts/Commands/cs_reload.cpp
+++ b/src/server/scripts/Commands/cs_reload.cpp
@@ -24,6 +24,7 @@ EndScriptData */
#include "AccountMgr.h"
#include "AchievementMgr.h"
+#include "AreaTriggerDataStore.h"
#include "AuctionHouseMgr.h"
#include "BattlegroundMgr.h"
#include "Chat.h"
@@ -72,6 +73,7 @@ public:
{ "areatrigger_involvedrelation", rbac::RBAC_PERM_COMMAND_RELOAD_AREATRIGGER_INVOLVEDRELATION, true, &HandleReloadQuestAreaTriggersCommand, "" },
{ "areatrigger_tavern", rbac::RBAC_PERM_COMMAND_RELOAD_AREATRIGGER_TAVERN, true, &HandleReloadAreaTriggerTavernCommand, "" },
{ "areatrigger_teleport", rbac::RBAC_PERM_COMMAND_RELOAD_AREATRIGGER_TELEPORT, true, &HandleReloadAreaTriggerTeleportCommand, "" },
+ { "areatrigger_template", rbac::RBAC_PERM_COMMAND_RELOAD_AREATRIGGER_TEMPLATE, true, &HandleReloadAreaTriggerTemplateCommand, "" },
{ "autobroadcast", rbac::RBAC_PERM_COMMAND_RELOAD_AUTOBROADCAST, true, &HandleReloadAutobroadcastCommand, "" },
{ "battleground_template", rbac::RBAC_PERM_COMMAND_RELOAD_BATTLEGROUND_TEMPLATE, true, &HandleReloadBattlegroundTemplate, "" },
{ "character_template", rbac::RBAC_PERM_COMMAND_RELOAD_CHARACTER_TEMPLATE, true, &HandleReloadCharacterTemplate, "" },
@@ -1127,6 +1129,13 @@ public:
return true;
}
+ static bool HandleReloadAreaTriggerTemplateCommand(ChatHandler* handler, const char* /*args*/)
+ {
+ TC_LOG_INFO("misc", "Reloading areatrigger_template table...");
+ sAreaTriggerDataStore->LoadAreaTriggerTemplates();
+ handler->SendGlobalGMSysMessage("AreaTrigger templates reloaded. Already spawned AT won't be affected. New scriptname need a reboot.");
+ return true;
+ }
static bool HandleReloadSceneTemplateCommand(ChatHandler* handler, const char* /*args*/)
{
diff --git a/src/server/worldserver/worldserver.conf.dist b/src/server/worldserver/worldserver.conf.dist
index 0a26196ccc3..96b8aace805 100644
--- a/src/server/worldserver/worldserver.conf.dist
+++ b/src/server/worldserver/worldserver.conf.dist
@@ -3778,6 +3778,7 @@ Logger.mmaps=3,Server
#Logger.condition=3,Console Server
#Logger.criteria=3,Console Server
#Logger.criteria.achievement=3,Console Server
+#Logger.entities.areatrigger=3,Console Server
#Logger.entities.pet=3,Console Server
#Logger.entities.player.character=3,Console Server
#Logger.entities.player.dump=3,Console Server