aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmake/showoptions.cmake1
-rw-r--r--sql/base/auth_database.sql4
-rw-r--r--sql/updates/world/2013_09_30_00_world_item_loot_template.sql168
-rw-r--r--sql/updates/world/2013_09_30_01_world_item_loot_template.sql8
-rw-r--r--sql/updates/world/2013_09_30_02_world_sai_335.sql5
-rw-r--r--sql/updates/world/2013_09_30_03_world_misc.sql7
-rw-r--r--sql/updates/world/2013_09_30_04_world_update.sql2
-rw-r--r--sql/updates/world/2013_10_01_00_misc.sql9
-rw-r--r--sql/updates/world/2013_10_01_00_world_sai.sql6
-rw-r--r--sql/updates/world/2013_10_05_00_world_sai.sql9
-rw-r--r--src/server/authserver/Server/AuthSocket.cpp13
-rw-r--r--src/server/game/AI/SmartScripts/SmartAI.cpp2
-rw-r--r--src/server/game/AI/SmartScripts/SmartScript.cpp24
-rw-r--r--src/server/game/AI/SmartScripts/SmartScript.h2
-rw-r--r--src/server/game/AI/SmartScripts/SmartScriptMgr.h6
-rw-r--r--src/server/game/Chat/Chat.cpp22
-rw-r--r--src/server/game/Entities/Creature/Creature.cpp43
-rw-r--r--src/server/game/Entities/Creature/Creature.h9
-rw-r--r--src/server/game/Entities/GameObject/GameObject.cpp2
-rw-r--r--src/server/game/Entities/Object/Object.cpp6
-rw-r--r--src/server/game/Entities/Player/Player.cpp15
-rw-r--r--src/server/game/Entities/Player/Player.h6
-rw-r--r--src/server/game/Entities/Unit/Unit.cpp62
-rw-r--r--src/server/game/Entities/Unit/Unit.h8
-rw-r--r--src/server/game/Grids/Notifiers/GridNotifiers.h11
-rw-r--r--src/server/game/Handlers/CalendarHandler.cpp2
-rw-r--r--src/server/game/Handlers/MiscHandler.cpp2
-rw-r--r--src/server/game/Handlers/QueryHandler.cpp1
-rw-r--r--src/server/game/Handlers/VehicleHandler.cpp2
-rw-r--r--src/server/game/Instances/InstanceSaveMgr.cpp4
-rw-r--r--src/server/game/Maps/Map.cpp2
-rwxr-xr-xsrc/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp2
-rw-r--r--src/server/game/Scripting/ScriptMgr.cpp10
-rw-r--r--src/server/game/Scripting/ScriptMgr.h8
-rw-r--r--src/server/game/Spells/Spell.cpp20
-rw-r--r--src/server/scripts/Commands/cs_account.cpp12
-rw-r--r--src/server/scripts/Commands/cs_debug.cpp2
-rw-r--r--src/server/scripts/Commands/cs_misc.cpp8
-rw-r--r--src/server/scripts/Commands/cs_npc.cpp9
-rw-r--r--src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.cpp2
-rw-r--r--src/server/shared/Database/MySQLThreading.h4
-rw-r--r--src/tools/mesh_extractor/ContinentBuilder.cpp154
-rw-r--r--src/tools/mesh_extractor/Geometry.cpp6
-rw-r--r--src/tools/mesh_extractor/MPQ.h3
-rw-r--r--src/tools/mesh_extractor/MPQManager.cpp4
-rw-r--r--src/tools/mesh_extractor/MeshExtractor.cpp64
-rw-r--r--src/tools/mesh_extractor/TileBuilder.cpp310
-rw-r--r--src/tools/mesh_extractor/TileBuilder.h6
-rw-r--r--src/tools/mesh_extractor/Utils.cpp42
-rw-r--r--src/tools/mesh_extractor/Utils.h6
-rw-r--r--src/tools/mesh_extractor/WorldModelHandler.cpp35
-rw-r--r--src/tools/mesh_extractor/WorldModelHandler.h2
52 files changed, 696 insertions, 476 deletions
diff --git a/cmake/showoptions.cmake b/cmake/showoptions.cmake
index 08dc2a0cfcb..2d21136d661 100644
--- a/cmake/showoptions.cmake
+++ b/cmake/showoptions.cmake
@@ -28,7 +28,6 @@ if( SCRIPTS )
add_definitions(-DSCRIPTS)
else()
message("* Build with scripts : No")
- set(USE_SCRIPTPCH 0)
endif()
if( TOOLS )
diff --git a/sql/base/auth_database.sql b/sql/base/auth_database.sql
index 177ad4d6e15..a52d4875314 100644
--- a/sql/base/auth_database.sql
+++ b/sql/base/auth_database.sql
@@ -2,7 +2,7 @@
--
-- Host: localhost Database: auth
-- ------------------------------------------------------
--- Server version 5.6.9-rc
+-- Server version 5.6.9-rc
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
@@ -341,7 +341,7 @@ CREATE TABLE `rbac_permissions` (
LOCK TABLES `rbac_permissions` WRITE;
/*!40000 ALTER TABLE `rbac_permissions` DISABLE KEYS */;
-INSERT INTO `rbac_permissions` VALUES (1,'Instant logout'),(2,'Skip Queue'),(3,'Join Normal Battleground'),(4,'Join Random Battleground'),(5,'Join Arenas'),(6,'Join Dungeon Finder'),(11,'Log GM trades'),(13,'Skip Instance required bosses check'),(14,'Skip character creation team mask check'),(15,'Skip character creation class mask check'),(16,'Skip character creation race mask check'),(17,'Skip character creation reserved name check'),(18,'Skip character creation heroic min level check'),(19,'Skip needed requirements to use channel check'),(20,'Skip disable map check'),(21,'Skip reset talents when used more than allowed check'),(22,'Skip spam chat check'),(23,'Skip over-speed ping check'),(24,'Two side faction characters on the same account'),(25,'Allow say chat between factions'),(26,'Allow channel chat between factions'),(27,'Two side mail interaction'),(28,'See two side who list'),(29,'Add friends of other faction'),(30,'Save character without delay with .save command'),(31,'Use params with .unstuck command'),(32,'Can be assigned tickets with .assign ticket command'),(33,'Notify if a command was not found'),(34,'Check if should appear in list using .gm ingame command'),(35,'See all security levels with who command'),(36,'Filter whispers'),(37,'Use staff badge in chat'),(38,'Resurrect with full Health Points'),(39,'Restore saved gm setting states'),(40,'Allows to add a gm to friend list'),(41,'Use Config option START_GM_LEVEL to assign new character level'),(42,'Allows to use CMSG_WORLD_TELEPORT opcode'),(43,'Allows to use CMSG_WHOIS opcode'),(44,'Receive global GM messages/texts'),(45,'Join channels without announce'),(46,'Change channel settings without being channel moderator'),(47,'Enables lower security than target check'),(48,'Enable IP, Last Login and EMail output in pinfo'),(49,'Forces to enter the email for confirmation on password change'),(50,'Allow user to check his own email with .account'),(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'),(217,'Command: account'),(218,'Command: account addon'),(219,'Command: account create'),(220,'Command: account delete'),(221,'Command: account lock'),(222,'Command: account lock country'),(223,'Command: account lock ip'),(224,'Command: account onlinelist'),(225,'Command: account password'),(226,'Command: account set'),(227,'Command: account set addon'),(228,'Command: account set gmlevel'),(229,'Command: account set password'),(230,'Command: achievement'),(231,'Command: achievement add'),(232,'Command: arena'),(233,'Command: arena captain'),(234,'Command: arena create'),(235,'Command: arena disband'),(236,'Command: arena info'),(237,'Command: arena lookup'),(238,'Command: arena rename'),(239,'Command: ban'),(240,'Command: ban account'),(241,'Command: ban character'),(242,'Command: ban ip'),(243,'Command: ban playeraccount'),(244,'Command: baninfo'),(245,'Command: baninfo account'),(246,'Command: baninfo character'),(247,'Command: baninfo ip'),(248,'Command: banlist'),(249,'Command: banlist account'),(250,'Command: banlist character'),(251,'Command: banlist ip'),(252,'Command: unban'),(253,'Command: unban account'),(254,'Command: unban character'),(255,'Command: unban ip'),(256,'Command: unban playeraccount'),(257,'Command: bf'),(258,'Command: bf start'),(259,'Command: bf stop'),(260,'Command: bf switch'),(261,'Command: bf timer'),(262,'Command: bf enable'),(263,'Command: account email'),(264,'Command: account set sec'),(265,'Command: account set sec email'),(266,'Command: account set sec regmail'),(267,'Command: cast'),(268,'Command: cast back'),(269,'Command: cast dist'),(270,'Command: cast self'),(271,'Command: cast target'),(272,'Command: cast dest'),(273,'Command: character'),(274,'Command: character customize'),(275,'Command: character changefaction'),(276,'Command: character changerace'),(277,'Command: character deleted'),(279,'Command: character deleted list'),(280,'Command: character deleted restore'),(283,'Command: character level'),(284,'Command: character rename'),(285,'Command: character reputation'),(286,'Command: character titles'),(287,'Command: levelup'),(288,'Command: pdump'),(289,'Command: pdump load'),(290,'Command: pdump write'),(291,'Command: cheat'),(292,'Command: cheat casttime'),(293,'Command: cheat cooldown'),(294,'Command: cheat explore'),(295,'Command: cheat god'),(296,'Command: cheat power'),(297,'Command: cheat status'),(298,'Command: cheat taxi'),(299,'Command: cheat waterwalk'),(300,'Command: debug'),(301,'Command: debug anim'),(302,'Command: debug areatriggers'),(303,'Command: debug arena'),(304,'Command: debug bg'),(305,'Command: debug entervehicle'),(306,'Command: debug getitemstate'),(307,'Command: debug getitemvalue'),(308,'Command: debug getvalue'),(309,'Command: debug hostil'),(310,'Command: debug itemexpire'),(311,'Command: debug lootrecipient'),(312,'Command: debug los'),(313,'Command: debug mod32value'),(314,'Command: debug moveflags'),(315,'Command: debug play'),(316,'Command: debug play cinematics'),(317,'Command: debug play movie'),(318,'Command: debug play sound'),(319,'Command: debug send'),(320,'Command: debug send buyerror'),(321,'Command: debug send channelnotify'),(322,'Command: debug send chatmessage'),(323,'Command: debug send equiperror'),(324,'Command: debug send largepacket'),(325,'Command: debug send opcode'),(326,'Command: debug send qinvalidmsg'),(327,'Command: debug send qpartymsg'),(328,'Command: debug send sellerror'),(329,'Command: debug send setphaseshift'),(330,'Command: debug send spellfail'),(331,'Command: debug setaurastate'),(332,'Command: debug setbit'),(333,'Command: debug setitemvalue'),(334,'Command: debug setvalue'),(335,'Command: debug setvid'),(336,'Command: debug spawnvehicle'),(337,'Command: debug threat'),(338,'Command: debug update'),(339,'Command: debug uws'),(340,'Command: wpgps'),(341,'Command: deserter'),(342,'Command: deserter bg'),(343,'Command: deserter bg add'),(344,'Command: deserter bg remove'),(345,'Command: deserter instance'),(346,'Command: deserter instance add'),(347,'Command: deserter instance remove'),(348,'Command: disable'),(349,'Command: disable add'),(350,'Command: disable add achievement_criteria'),(351,'Command: disable add battleground'),(352,'Command: disable add map'),(353,'Command: disable add mmap'),(354,'Command: disable add outdoorpvp'),(355,'Command: disable add quest'),(356,'Command: disable add spell'),(357,'Command: disable add vmap'),(358,'Command: disable remove'),(359,'Command: disable remove achievement_criteria'),(360,'Command: disable remove battleground'),(361,'Command: disable remove map'),(362,'Command: disable remove mmap'),(363,'Command: disable remove outdoorpvp'),(364,'Command: disable remove quest'),(365,'Command: disable remove spell'),(366,'Command: disable remove vmap'),(367,'Command: event'),(368,'Command: event activelist'),(369,'Command: event start'),(370,'Command: event stop'),(371,'Command: gm'),(372,'Command: gm chat'),(373,'Command: gm fly'),(374,'Command: gm ingame'),(375,'Command: gm list'),(376,'Command: gm visible'),(377,'Command: go'),(378,'Command: go creature'),(379,'Command: go graveyard'),(380,'Command: go grid'),(381,'Command: go object'),(382,'Command: go taxinode'),(383,'Command: go ticket'),(384,'Command: go trigger'),(385,'Command: go xyz'),(386,'Command: go zonexy'),(387,'Command: gobject'),(388,'Command: gobject activate'),(389,'Command: gobject add'),(390,'Command: gobject add temp'),(391,'Command: gobject delete'),(392,'Command: gobject info'),(393,'Command: gobject move'),(394,'Command: gobject near'),(395,'Command: gobject set'),(396,'Command: gobject set phase'),(397,'Command: gobject set state'),(398,'Command: gobject target'),(399,'Command: gobject turn'),(401,'Command: guild'),(402,'Command: guild create'),(403,'Command: guild delete'),(404,'Command: guild invite'),(405,'Command: guild uninvite'),(406,'Command: guild rank'),(407,'Command: guild rename'),(408,'Command: honor'),(409,'Command: honor add'),(410,'Command: honor add kill'),(411,'Command: honor update'),(412,'Command: instance'),(413,'Command: instance listbinds'),(414,'Command: instance unbind'),(415,'Command: instance stats'),(416,'Command: instance savedata'),(417,'Command: learn'),(418,'Command: learn all'),(419,'Command: learn all my'),(420,'Command: learn all my class'),(421,'Command: learn all my pettalents'),(422,'Command: learn all my spells'),(423,'Command: learn all my talents'),(424,'Command: learn all gm'),(425,'Command: learn all crafts'),(426,'Command: learn all default'),(427,'Command: learn all lang'),(428,'Command: learn all recipes'),(429,'Command: unlearn'),(430,'Command: lfg'),(431,'Command: lfg player'),(432,'Command: lfg group'),(433,'Command: lfg queue'),(434,'Command: lfg clean'),(435,'Command: lfg options'),(436,'Command: list'),(437,'Command: list creature'),(438,'Command: list item'),(439,'Command: list object'),(440,'Command: list auras'),(441,'Command: list mail'),(442,'Command: lookup'),(443,'Command: lookup area'),(444,'Command: lookup creature'),(445,'Command: lookup event'),(446,'Command: lookup faction'),(447,'Command: lookup item'),(448,'Command: lookup itemset'),(449,'Command: lookup object'),(450,'Command: lookup quest'),(451,'Command: lookup player'),(452,'Command: lookup player ip'),(453,'Command: lookup player account'),(454,'Command: lookup player email'),(455,'Command: lookup skill'),(456,'Command: lookup spell'),(457,'Command: lookup spell id'),(458,'Command: lookup taxinode'),(459,'Command: lookup tele'),(460,'Command: lookup title'),(461,'Command: lookup map'),(462,'Command: announce'),(463,'Command: channel'),(464,'Command: channel set'),(465,'Command: channel set ownership'),(466,'Command: gmannounce'),(467,'Command: gmnameannounce'),(468,'Command: gmnotify'),(469,'Command: nameannounce'),(470,'Command: notify'),(471,'Command: whispers'),(472,'Command: group'),(473,'Command: group leader'),(474,'Command: group disband'),(475,'Command: group remove'),(476,'Command: group join'),(477,'Command: group list'),(478,'Command: group summon'),(479,'Command: pet'),(480,'Command: pet create'),(481,'Command: pet learn'),(482,'Command: pet unlearn'),(483,'Command: send'),(484,'Command: send items'),(485,'Command: send mail'),(486,'Command: send message'),(487,'Command: send money'),(488,'Command: additem'),(489,'Command: additemset'),(490,'Command: appear'),(491,'Command: aura'),(492,'Command: bank'),(493,'Command: bindsight'),(494,'Command: combatstop'),(495,'Command: cometome'),(496,'Command: commands'),(497,'Command: cooldown'),(498,'Command: damage'),(499,'Command: dev'),(500,'Command: die'),(501,'Command: dismount'),(502,'Command: distance'),(503,'Command: flusharenapoints'),(504,'Command: freeze'),(505,'Command: gps'),(506,'Command: guid'),(507,'Command: help'),(508,'Command: hidearea'),(509,'Command: itemmove'),(510,'Command: kick'),(511,'Command: linkgrave'),(512,'Command: listfreeze'),(513,'Command: maxskill'),(514,'Command: movegens'),(515,'Command: mute'),(516,'Command: neargrave'),(517,'Command: pinfo'),(518,'Command: playall'),(519,'Command: possess'),(520,'Command: recall'),(521,'Command: repairitems'),(522,'Command: respawn'),(523,'Command: revive'),(524,'Command: saveall'),(525,'Command: save'),(526,'Command: setskill'),(527,'Command: showarea'),(528,'Command: summon'),(529,'Command: unaura'),(530,'Command: unbindsight'),(531,'Command: unfreeze'),(532,'Command: unmute'),(533,'Command: unpossess'),(534,'Command: unstuck'),(535,'Command: wchange'),(536,'Command: mmap'),(537,'Command: mmap loadedtiles'),(538,'Command: mmap loc'),(539,'Command: mmap path'),(540,'Command: mmap stats'),(541,'Command: mmap testarea'),(542,'Command: morph'),(543,'Command: demorph'),(544,'Command: modify'),(545,'Command: modify arenapoints'),(546,'Command: modify bit'),(547,'Command: modify drunk'),(548,'Command: modify energy'),(549,'Command: modify faction'),(550,'Command: modify gender'),(551,'Command: modify honor'),(552,'Command: modify hp'),(553,'Command: modify mana'),(554,'Command: modify money'),(555,'Command: modify mount'),(556,'Command: modify phase'),(557,'Command: modify rage'),(558,'Command: modify reputation'),(559,'Command: modify runicpower'),(560,'Command: modify scale'),(561,'Command: modify speed'),(562,'Command: modify speed all'),(563,'Command: modify speed backwalk'),(564,'Command: modify speed fly'),(565,'Command: modify speed walk'),(566,'Command: modify speed swim'),(567,'Command: modify spell'),(568,'Command: modify standstate'),(569,'Command: modify talentpoints'),(570,'Command: npc'),(571,'Command: npc add'),(572,'Command: npc add formation'),(573,'Command: npc add item'),(574,'Command: npc add move'),(575,'Command: npc add temp'),(576,'Command: npc add delete'),(577,'Command: npc add delete item'),(578,'Command: npc add follow'),(579,'Command: npc add follow stop'),(580,'Command: npc set'),(581,'Command: npc set allowmove'),(582,'Command: npc set entry'),(583,'Command: npc set factionid'),(584,'Command: npc set flag'),(585,'Command: npc set level'),(586,'Command: npc set link'),(587,'Command: npc set model'),(588,'Command: npc set movetype'),(589,'Command: npc set phase'),(590,'Command: npc set spawndist'),(591,'Command: npc set spawntime'),(592,'Command: npc set data'),(593,'Command: npc info'),(594,'Command: npc near'),(595,'Command: npc move'),(596,'Command: npc playemote'),(597,'Command: npc say'),(598,'Command: npc textemote'),(599,'Command: npc whisper'),(600,'Command: npc yell'),(601,'Command: npc tame'),(602,'Command: quest'),(603,'Command: quest add'),(604,'Command: quest complete'),(605,'Command: quest remove'),(606,'Command: quest reward'),(607,'Command: reload'),(608,'Command: reload access_requirement'),(609,'Command: reload achievement_criteria_data'),(610,'Command: reload achievement_reward'),(611,'Command: reload all'),(612,'Command: reload all achievement'),(613,'Command: reload all area'),(614,'Command: reload all eventai'),(615,'Command: reload all gossips'),(616,'Command: reload all item'),(617,'Command: reload all locales'),(618,'Command: reload all loot'),(619,'Command: reload all npc'),(620,'Command: reload all quest'),(621,'Command: reload all scripts'),(622,'Command: reload all spell'),(623,'Command: reload areatrigger_involvedrelation'),(624,'Command: reload areatrigger_tavern'),(625,'Command: reload areatrigger_teleport'),(626,'Command: reload auctions'),(627,'Command: reload autobroadcast'),(628,'Command: reload command'),(629,'Command: reload conditions'),(630,'Command: reload config'),(631,'Command: reload creature_text'),(632,'Command: reload creature_ai_scripts'),(633,'Command: reload creature_ai_texts'),(634,'Command: reload creature_questender'),(635,'Command: reload creature_linked_respawn'),(636,'Command: reload creature_loot_template'),(637,'Command: reload creature_onkill_reputation'),(638,'Command: reload creature_queststarter'),(639,'Command: reload creature_summon_groups'),(640,'Command: reload creature_template'),(641,'Command: reload disables'),(642,'Command: reload disenchant_loot_template'),(643,'Command: reload event_scripts'),(644,'Command: reload fishing_loot_template'),(645,'Command: reload game_graveyard_zone'),(646,'Command: reload game_tele'),(647,'Command: reload gameobject_questender'),(648,'Command: reload gameobject_loot_template'),(649,'Command: reload gameobject_queststarter'),(650,'Command: reload gm_tickets'),(651,'Command: reload gossip_menu'),(652,'Command: reload gossip_menu_option'),(653,'Command: reload item_enchantment_template'),(654,'Command: reload item_loot_template'),(655,'Command: reload item_set_names'),(656,'Command: reload lfg_dungeon_rewards'),(657,'Command: reload locales_achievement_reward'),(658,'Command: reload locales_creature'),(659,'Command: reload locales_creature_text'),(660,'Command: reload locales_gameobject'),(661,'Command: reload locales_gossip_menu_option'),(662,'Command: reload locales_item'),(663,'Command: reload locales_item_set_name'),(664,'Command: reload locales_npc_text'),(665,'Command: reload locales_page_text'),(666,'Command: reload locales_points_of_interest'),(667,'Command: reload locales_quest'),(668,'Command: reload mail_level_reward'),(669,'Command: reload mail_loot_template'),(670,'Command: reload milling_loot_template'),(671,'Command: reload npc_spellclick_spells'),(672,'Command: reload npc_trainer'),(673,'Command: reload npc_vendor'),(674,'Command: reload page_text'),(675,'Command: reload pickpocketing_loot_template'),(676,'Command: reload points_of_interest'),(677,'Command: reload prospecting_loot_template'),(678,'Command: reload quest_poi'),(679,'Command: reload quest_template'),(680,'Command: reload rbac'),(681,'Command: reload reference_loot_template'),(682,'Command: reload reserved_name'),(683,'Command: reload reputation_reward_rate'),(684,'Command: reload reputation_spillover_template'),(685,'Command: reload skill_discovery_template'),(686,'Command: reload skill_extra_item_template'),(687,'Command: reload skill_fishing_base_level'),(688,'Command: reload skinning_loot_template'),(689,'Command: reload smart_scripts'),(690,'Command: reload spell_required'),(691,'Command: reload spell_area'),(692,'Command: reload spell_bonus_data'),(693,'Command: reload spell_group'),(694,'Command: reload spell_learn_spell'),(695,'Command: reload spell_loot_template'),(696,'Command: reload spell_linked_spell'),(697,'Command: reload spell_pet_auras'),(698,'Command: reload spell_proc_event'),(699,'Command: reload spell_proc'),(700,'Command: reload spell_scripts'),(701,'Command: reload spell_target_position'),(702,'Command: reload spell_threats'),(703,'Command: reload spell_group_stack_rules'),(704,'Command: reload trinity_string'),(705,'Command: reload warden_action'),(706,'Command: reload waypoint_scripts'),(707,'Command: reload waypoint_data'),(708,'Command: reload vehicle_accessory'),(709,'Command: reload vehicle_template_accessory'),(710,'Command: reset'),(711,'Command: reset achievements'),(712,'Command: reset honor'),(713,'Command: reset level'),(714,'Command: reset spells'),(715,'Command: reset stats'),(716,'Command: reset talents'),(717,'Command: reset all'),(718,'Command: server'),(719,'Command: server corpses'),(720,'Command: server exit'),(721,'Command: server idlerestart'),(722,'Command: server idlerestart cancel'),(723,'Command: server idleshutdown'),(724,'Command: server idleshutdown cancel'),(725,'Command: server info'),(726,'Command: server plimit'),(727,'Command: server restart'),(728,'Command: server restart cancel'),(729,'Command: server set'),(730,'Command: server set closed'),(731,'Command: server set difftime'),(732,'Command: server set loglevel'),(733,'Command: server set motd'),(734,'Command: server shutdown'),(735,'Command: server shutdown cancel'),(736,'Command: server motd'),(737,'Command: tele'),(738,'Command: tele add'),(739,'Command: tele del'),(740,'Command: tele name'),(741,'Command: tele group'),(742,'Command: ticket'),(743,'Command: ticket assign'),(744,'Command: ticket close'),(745,'Command: ticket closedlist'),(746,'Command: ticket comment'),(747,'Command: ticket complete'),(748,'Command: ticket delete'),(749,'Command: ticket escalate'),(750,'Command: ticket escalatedlist'),(751,'Command: ticket list'),(752,'Command: ticket onlinelist'),(753,'Command: ticket reset'),(754,'Command: ticket response'),(755,'Command: ticket response append'),(756,'Command: ticket response appendln'),(757,'Command: ticket togglesystem'),(758,'Command: ticket unassign'),(759,'Command: ticket viewid'),(760,'Command: ticket viewname'),(761,'Command: titles'),(762,'Command: titles add'),(763,'Command: titles current'),(764,'Command: titles remove'),(765,'Command: titles set'),(766,'Command: titles set mask'),(767,'Command: wp'),(768,'Command: wp add'),(769,'Command: wp event'),(770,'Command: wp load'),(771,'Command: wp modify'),(772,'Command: wp unload'),(773,'Command: wp reload'),(774,'Command: wp show');
+INSERT INTO `rbac_permissions` VALUES (1,'Instant logout'),(2,'Skip Queue'),(3,'Join Normal Battleground'),(4,'Join Random Battleground'),(5,'Join Arenas'),(6,'Join Dungeon Finder'),(11,'Log GM trades'),(13,'Skip Instance required bosses check'),(14,'Skip character creation team mask check'),(15,'Skip character creation class mask check'),(16,'Skip character creation race mask check'),(17,'Skip character creation reserved name check'),(18,'Skip character creation heroic min level check'),(19,'Skip needed requirements to use channel check'),(20,'Skip disable map check'),(21,'Skip reset talents when used more than allowed check'),(22,'Skip spam chat check'),(23,'Skip over-speed ping check'),(24,'Two side faction characters on the same account'),(25,'Allow say chat between factions'),(26,'Allow channel chat between factions'),(27,'Two side mail interaction'),(28,'See two side who list'),(29,'Add friends of other faction'),(30,'Save character without delay with .save command'),(31,'Use params with .unstuck command'),(32,'Can be assigned tickets with .assign ticket command'),(33,'Notify if a command was not found'),(34,'Check if should appear in list using .gm ingame command'),(35,'See all security levels with who command'),(36,'Filter whispers'),(37,'Use staff badge in chat'),(38,'Resurrect with full Health Points'),(39,'Restore saved gm setting states'),(40,'Allows to add a gm to friend list'),(41,'Use Config option START_GM_LEVEL to assign new character level'),(42,'Allows to use CMSG_WORLD_TELEPORT opcode'),(43,'Allows to use CMSG_WHOIS opcode'),(44,'Receive global GM messages/texts'),(45,'Join channels without announce'),(46,'Change channel settings without being channel moderator'),(47,'Enables lower security than target check'),(48,'Enable IP, Last Login and EMail output in pinfo'),(49,'Forces to enter the email for confirmation on password change'),(50,'Allow user to check his own email with .account'),(192,'Role: Sec Level Administrator'),(193,'Role: Sec Level Gamemaster'),(194,'Role: Sec Level Moderator'),(195,'Role: Sec Level Player'),(196,'Role: Administrator Commands'),(197,'Role: Gamemaster Commands'),(198,'Role: Moderator Commands'),(199,'Role: Player Commands'),(200,'Command: rbac'),(201,'Command: rbac account'),(202,'Command: rbac account list'),(203,'Command: rbac account grant'),(204,'Command: rbac account deny'),(205,'Command: rbac account revoke'),(206,'Command: rbac list'),(217,'Command: account'),(218,'Command: account addon'),(219,'Command: account create'),(220,'Command: account delete'),(221,'Command: account lock'),(222,'Command: account lock country'),(223,'Command: account lock ip'),(224,'Command: account onlinelist'),(225,'Command: account password'),(226,'Command: account set'),(227,'Command: account set addon'),(228,'Command: account set gmlevel'),(229,'Command: account set password'),(230,'Command: achievement'),(231,'Command: achievement add'),(232,'Command: arena'),(233,'Command: arena captain'),(234,'Command: arena create'),(235,'Command: arena disband'),(236,'Command: arena info'),(237,'Command: arena lookup'),(238,'Command: arena rename'),(239,'Command: ban'),(240,'Command: ban account'),(241,'Command: ban character'),(242,'Command: ban ip'),(243,'Command: ban playeraccount'),(244,'Command: baninfo'),(245,'Command: baninfo account'),(246,'Command: baninfo character'),(247,'Command: baninfo ip'),(248,'Command: banlist'),(249,'Command: banlist account'),(250,'Command: banlist character'),(251,'Command: banlist ip'),(252,'Command: unban'),(253,'Command: unban account'),(254,'Command: unban character'),(255,'Command: unban ip'),(256,'Command: unban playeraccount'),(257,'Command: bf'),(258,'Command: bf start'),(259,'Command: bf stop'),(260,'Command: bf switch'),(261,'Command: bf timer'),(262,'Command: bf enable'),(263,'Command: account email'),(264,'Command: account set sec'),(265,'Command: account set sec email'),(266,'Command: account set sec regmail'),(267,'Command: cast'),(268,'Command: cast back'),(269,'Command: cast dist'),(270,'Command: cast self'),(271,'Command: cast target'),(272,'Command: cast dest'),(273,'Command: character'),(274,'Command: character customize'),(275,'Command: character changefaction'),(276,'Command: character changerace'),(277,'Command: character deleted'),(279,'Command: character deleted list'),(280,'Command: character deleted restore'),(283,'Command: character level'),(284,'Command: character rename'),(285,'Command: character reputation'),(286,'Command: character titles'),(287,'Command: levelup'),(288,'Command: pdump'),(289,'Command: pdump load'),(290,'Command: pdump write'),(291,'Command: cheat'),(292,'Command: cheat casttime'),(293,'Command: cheat cooldown'),(294,'Command: cheat explore'),(295,'Command: cheat god'),(296,'Command: cheat power'),(297,'Command: cheat status'),(298,'Command: cheat taxi'),(299,'Command: cheat waterwalk'),(300,'Command: debug'),(301,'Command: debug anim'),(302,'Command: debug areatriggers'),(303,'Command: debug arena'),(304,'Command: debug bg'),(305,'Command: debug entervehicle'),(306,'Command: debug getitemstate'),(307,'Command: debug getitemvalue'),(308,'Command: debug getvalue'),(309,'Command: debug hostil'),(310,'Command: debug itemexpire'),(311,'Command: debug lootrecipient'),(312,'Command: debug los'),(313,'Command: debug mod32value'),(314,'Command: debug moveflags'),(315,'Command: debug play'),(316,'Command: debug play cinematics'),(317,'Command: debug play movie'),(318,'Command: debug play sound'),(319,'Command: debug send'),(320,'Command: debug send buyerror'),(321,'Command: debug send channelnotify'),(322,'Command: debug send chatmessage'),(323,'Command: debug send equiperror'),(324,'Command: debug send largepacket'),(325,'Command: debug send opcode'),(326,'Command: debug send qinvalidmsg'),(327,'Command: debug send qpartymsg'),(328,'Command: debug send sellerror'),(329,'Command: debug send setphaseshift'),(330,'Command: debug send spellfail'),(331,'Command: debug setaurastate'),(332,'Command: debug setbit'),(333,'Command: debug setitemvalue'),(334,'Command: debug setvalue'),(335,'Command: debug setvid'),(336,'Command: debug spawnvehicle'),(337,'Command: debug threat'),(338,'Command: debug update'),(339,'Command: debug uws'),(340,'Command: wpgps'),(341,'Command: deserter'),(342,'Command: deserter bg'),(343,'Command: deserter bg add'),(344,'Command: deserter bg remove'),(345,'Command: deserter instance'),(346,'Command: deserter instance add'),(347,'Command: deserter instance remove'),(348,'Command: disable'),(349,'Command: disable add'),(350,'Command: disable add achievement_criteria'),(351,'Command: disable add battleground'),(352,'Command: disable add map'),(353,'Command: disable add mmap'),(354,'Command: disable add outdoorpvp'),(355,'Command: disable add quest'),(356,'Command: disable add spell'),(357,'Command: disable add vmap'),(358,'Command: disable remove'),(359,'Command: disable remove achievement_criteria'),(360,'Command: disable remove battleground'),(361,'Command: disable remove map'),(362,'Command: disable remove mmap'),(363,'Command: disable remove outdoorpvp'),(364,'Command: disable remove quest'),(365,'Command: disable remove spell'),(366,'Command: disable remove vmap'),(367,'Command: event'),(368,'Command: event activelist'),(369,'Command: event start'),(370,'Command: event stop'),(371,'Command: gm'),(372,'Command: gm chat'),(373,'Command: gm fly'),(374,'Command: gm ingame'),(375,'Command: gm list'),(376,'Command: gm visible'),(377,'Command: go'),(378,'Command: go creature'),(379,'Command: go graveyard'),(380,'Command: go grid'),(381,'Command: go object'),(382,'Command: go taxinode'),(383,'Command: go ticket'),(384,'Command: go trigger'),(385,'Command: go xyz'),(386,'Command: go zonexy'),(387,'Command: gobject'),(388,'Command: gobject activate'),(389,'Command: gobject add'),(390,'Command: gobject add temp'),(391,'Command: gobject delete'),(392,'Command: gobject info'),(393,'Command: gobject move'),(394,'Command: gobject near'),(395,'Command: gobject set'),(396,'Command: gobject set phase'),(397,'Command: gobject set state'),(398,'Command: gobject target'),(399,'Command: gobject turn'),(401,'Command: guild'),(402,'Command: guild create'),(403,'Command: guild delete'),(404,'Command: guild invite'),(405,'Command: guild uninvite'),(406,'Command: guild rank'),(407,'Command: guild rename'),(408,'Command: honor'),(409,'Command: honor add'),(410,'Command: honor add kill'),(411,'Command: honor update'),(412,'Command: instance'),(413,'Command: instance listbinds'),(414,'Command: instance unbind'),(415,'Command: instance stats'),(416,'Command: instance savedata'),(417,'Command: learn'),(418,'Command: learn all'),(419,'Command: learn all my'),(420,'Command: learn all my class'),(421,'Command: learn all my pettalents'),(422,'Command: learn all my spells'),(423,'Command: learn all my talents'),(424,'Command: learn all gm'),(425,'Command: learn all crafts'),(426,'Command: learn all default'),(427,'Command: learn all lang'),(428,'Command: learn all recipes'),(429,'Command: unlearn'),(430,'Command: lfg'),(431,'Command: lfg player'),(432,'Command: lfg group'),(433,'Command: lfg queue'),(434,'Command: lfg clean'),(435,'Command: lfg options'),(436,'Command: list'),(437,'Command: list creature'),(438,'Command: list item'),(439,'Command: list object'),(440,'Command: list auras'),(441,'Command: list mail'),(442,'Command: lookup'),(443,'Command: lookup area'),(444,'Command: lookup creature'),(445,'Command: lookup event'),(446,'Command: lookup faction'),(447,'Command: lookup item'),(448,'Command: lookup itemset'),(449,'Command: lookup object'),(450,'Command: lookup quest'),(451,'Command: lookup player'),(452,'Command: lookup player ip'),(453,'Command: lookup player account'),(454,'Command: lookup player email'),(455,'Command: lookup skill'),(456,'Command: lookup spell'),(457,'Command: lookup spell id'),(458,'Command: lookup taxinode'),(459,'Command: lookup tele'),(460,'Command: lookup title'),(461,'Command: lookup map'),(462,'Command: announce'),(463,'Command: channel'),(464,'Command: channel set'),(465,'Command: channel set ownership'),(466,'Command: gmannounce'),(467,'Command: gmnameannounce'),(468,'Command: gmnotify'),(469,'Command: nameannounce'),(470,'Command: notify'),(471,'Command: whispers'),(472,'Command: group'),(473,'Command: group leader'),(474,'Command: group disband'),(475,'Command: group remove'),(476,'Command: group join'),(477,'Command: group list'),(478,'Command: group summon'),(479,'Command: pet'),(480,'Command: pet create'),(481,'Command: pet learn'),(482,'Command: pet unlearn'),(483,'Command: send'),(484,'Command: send items'),(485,'Command: send mail'),(486,'Command: send message'),(487,'Command: send money'),(488,'Command: additem'),(489,'Command: additemset'),(490,'Command: appear'),(491,'Command: aura'),(492,'Command: bank'),(493,'Command: bindsight'),(494,'Command: combatstop'),(495,'Command: cometome'),(496,'Command: commands'),(497,'Command: cooldown'),(498,'Command: damage'),(499,'Command: dev'),(500,'Command: die'),(501,'Command: dismount'),(502,'Command: distance'),(503,'Command: flusharenapoints'),(504,'Command: freeze'),(505,'Command: gps'),(506,'Command: guid'),(507,'Command: help'),(508,'Command: hidearea'),(509,'Command: itemmove'),(510,'Command: kick'),(511,'Command: linkgrave'),(512,'Command: listfreeze'),(513,'Command: maxskill'),(514,'Command: movegens'),(515,'Command: mute'),(516,'Command: neargrave'),(517,'Command: pinfo'),(518,'Command: playall'),(519,'Command: possess'),(520,'Command: recall'),(521,'Command: repairitems'),(522,'Command: respawn'),(523,'Command: revive'),(524,'Command: saveall'),(525,'Command: save'),(526,'Command: setskill'),(527,'Command: showarea'),(528,'Command: summon'),(529,'Command: unaura'),(530,'Command: unbindsight'),(531,'Command: unfreeze'),(532,'Command: unmute'),(533,'Command: unpossess'),(534,'Command: unstuck'),(535,'Command: wchange'),(536,'Command: mmap'),(537,'Command: mmap loadedtiles'),(538,'Command: mmap loc'),(539,'Command: mmap path'),(540,'Command: mmap stats'),(541,'Command: mmap testarea'),(542,'Command: morph'),(543,'Command: demorph'),(544,'Command: modify'),(545,'Command: modify arenapoints'),(546,'Command: modify bit'),(547,'Command: modify drunk'),(548,'Command: modify energy'),(549,'Command: modify faction'),(550,'Command: modify gender'),(551,'Command: modify honor'),(552,'Command: modify hp'),(553,'Command: modify mana'),(554,'Command: modify money'),(555,'Command: modify mount'),(556,'Command: modify phase'),(557,'Command: modify rage'),(558,'Command: modify reputation'),(559,'Command: modify runicpower'),(560,'Command: modify scale'),(561,'Command: modify speed'),(562,'Command: modify speed all'),(563,'Command: modify speed backwalk'),(564,'Command: modify speed fly'),(565,'Command: modify speed walk'),(566,'Command: modify speed swim'),(567,'Command: modify spell'),(568,'Command: modify standstate'),(569,'Command: modify talentpoints'),(570,'Command: npc'),(571,'Command: npc add'),(572,'Command: npc add formation'),(573,'Command: npc add item'),(574,'Command: npc add move'),(575,'Command: npc add temp'),(576,'Command: npc add delete'),(577,'Command: npc add delete item'),(578,'Command: npc add follow'),(579,'Command: npc add follow stop'),(580,'Command: npc set'),(581,'Command: npc set allowmove'),(582,'Command: npc set entry'),(583,'Command: npc set factionid'),(584,'Command: npc set flag'),(585,'Command: npc set level'),(586,'Command: npc set link'),(587,'Command: npc set model'),(588,'Command: npc set movetype'),(589,'Command: npc set phase'),(590,'Command: npc set spawndist'),(591,'Command: npc set spawntime'),(592,'Command: npc set data'),(593,'Command: npc info'),(594,'Command: npc near'),(595,'Command: npc move'),(596,'Command: npc playemote'),(597,'Command: npc say'),(598,'Command: npc textemote'),(599,'Command: npc whisper'),(600,'Command: npc yell'),(601,'Command: npc tame'),(602,'Command: quest'),(603,'Command: quest add'),(604,'Command: quest complete'),(605,'Command: quest remove'),(606,'Command: quest reward'),(607,'Command: reload'),(608,'Command: reload access_requirement'),(609,'Command: reload achievement_criteria_data'),(610,'Command: reload achievement_reward'),(611,'Command: reload all'),(612,'Command: reload all achievement'),(613,'Command: reload all area'),(614,'Command: reload all eventai'),(615,'Command: reload all gossips'),(616,'Command: reload all item'),(617,'Command: reload all locales'),(618,'Command: reload all loot'),(619,'Command: reload all npc'),(620,'Command: reload all quest'),(621,'Command: reload all scripts'),(622,'Command: reload all spell'),(623,'Command: reload areatrigger_involvedrelation'),(624,'Command: reload areatrigger_tavern'),(625,'Command: reload areatrigger_teleport'),(626,'Command: reload auctions'),(627,'Command: reload autobroadcast'),(628,'Command: reload command'),(629,'Command: reload conditions'),(630,'Command: reload config'),(631,'Command: reload creature_text'),(632,'Command: reload creature_ai_scripts'),(633,'Command: reload creature_ai_texts'),(634,'Command: reload creature_questender'),(635,'Command: reload creature_linked_respawn'),(636,'Command: reload creature_loot_template'),(637,'Command: reload creature_onkill_reputation'),(638,'Command: reload creature_queststarter'),(639,'Command: reload creature_summon_groups'),(640,'Command: reload creature_template'),(641,'Command: reload disables'),(642,'Command: reload disenchant_loot_template'),(643,'Command: reload event_scripts'),(644,'Command: reload fishing_loot_template'),(645,'Command: reload game_graveyard_zone'),(646,'Command: reload game_tele'),(647,'Command: reload gameobject_questender'),(648,'Command: reload gameobject_loot_template'),(649,'Command: reload gameobject_queststarter'),(650,'Command: reload gm_tickets'),(651,'Command: reload gossip_menu'),(652,'Command: reload gossip_menu_option'),(653,'Command: reload item_enchantment_template'),(654,'Command: reload item_loot_template'),(655,'Command: reload item_set_names'),(656,'Command: reload lfg_dungeon_rewards'),(657,'Command: reload locales_achievement_reward'),(658,'Command: reload locales_creature'),(659,'Command: reload locales_creature_text'),(660,'Command: reload locales_gameobject'),(661,'Command: reload locales_gossip_menu_option'),(662,'Command: reload locales_item'),(663,'Command: reload locales_item_set_name'),(664,'Command: reload locales_npc_text'),(665,'Command: reload locales_page_text'),(666,'Command: reload locales_points_of_interest'),(667,'Command: reload locales_quest'),(668,'Command: reload mail_level_reward'),(669,'Command: reload mail_loot_template'),(670,'Command: reload milling_loot_template'),(671,'Command: reload npc_spellclick_spells'),(672,'Command: reload npc_trainer'),(673,'Command: reload npc_vendor'),(674,'Command: reload page_text'),(675,'Command: reload pickpocketing_loot_template'),(676,'Command: reload points_of_interest'),(677,'Command: reload prospecting_loot_template'),(678,'Command: reload quest_poi'),(679,'Command: reload quest_template'),(680,'Command: reload rbac'),(681,'Command: reload reference_loot_template'),(682,'Command: reload reserved_name'),(683,'Command: reload reputation_reward_rate'),(684,'Command: reload reputation_spillover_template'),(685,'Command: reload skill_discovery_template'),(686,'Command: reload skill_extra_item_template'),(687,'Command: reload skill_fishing_base_level'),(688,'Command: reload skinning_loot_template'),(689,'Command: reload smart_scripts'),(690,'Command: reload spell_required'),(691,'Command: reload spell_area'),(692,'Command: reload spell_bonus_data'),(693,'Command: reload spell_group'),(694,'Command: reload spell_learn_spell'),(695,'Command: reload spell_loot_template'),(696,'Command: reload spell_linked_spell'),(697,'Command: reload spell_pet_auras'),(698,'Command: reload spell_proc_event'),(699,'Command: reload spell_proc'),(700,'Command: reload spell_scripts'),(701,'Command: reload spell_target_position'),(702,'Command: reload spell_threats'),(703,'Command: reload spell_group_stack_rules'),(704,'Command: reload trinity_string'),(705,'Command: reload warden_action'),(706,'Command: reload waypoint_scripts'),(707,'Command: reload waypoint_data'),(708,'Command: reload vehicle_accessory'),(709,'Command: reload vehicle_template_accessory'),(710,'Command: reset'),(711,'Command: reset achievements'),(712,'Command: reset honor'),(713,'Command: reset level'),(714,'Command: reset spells'),(715,'Command: reset stats'),(716,'Command: reset talents'),(717,'Command: reset all'),(718,'Command: server'),(719,'Command: server corpses'),(720,'Command: server exit'),(721,'Command: server idlerestart'),(722,'Command: server idlerestart cancel'),(723,'Command: server idleshutdown'),(724,'Command: server idleshutdown cancel'),(725,'Command: server info'),(726,'Command: server plimit'),(727,'Command: server restart'),(728,'Command: server restart cancel'),(729,'Command: server set'),(730,'Command: server set closed'),(731,'Command: server set difftime'),(732,'Command: server set loglevel'),(733,'Command: server set motd'),(734,'Command: server shutdown'),(735,'Command: server shutdown cancel'),(736,'Command: server motd'),(737,'Command: tele'),(738,'Command: tele add'),(739,'Command: tele del'),(740,'Command: tele name'),(741,'Command: tele group'),(742,'Command: ticket'),(743,'Command: ticket assign'),(744,'Command: ticket close'),(745,'Command: ticket closedlist'),(746,'Command: ticket comment'),(747,'Command: ticket complete'),(748,'Command: ticket delete'),(749,'Command: ticket escalate'),(750,'Command: ticket escalatedlist'),(751,'Command: ticket list'),(752,'Command: ticket onlinelist'),(753,'Command: ticket reset'),(754,'Command: ticket response'),(755,'Command: ticket response append'),(756,'Command: ticket response appendln'),(757,'Command: ticket togglesystem'),(758,'Command: ticket unassign'),(759,'Command: ticket viewid'),(760,'Command: ticket viewname'),(761,'Command: titles'),(762,'Command: titles add'),(763,'Command: titles current'),(764,'Command: titles remove'),(765,'Command: titles set'),(766,'Command: titles set mask'),(767,'Command: wp'),(768,'Command: wp add'),(769,'Command: wp event'),(770,'Command: wp load'),(771,'Command: wp modify'),(772,'Command: wp unload'),(773,'Command: wp reload'),(774,'Command: wp show');
/*!40000 ALTER TABLE `rbac_permissions` ENABLE KEYS */;
UNLOCK TABLES;
diff --git a/sql/updates/world/2013_09_30_00_world_item_loot_template.sql b/sql/updates/world/2013_09_30_00_world_item_loot_template.sql
new file mode 100644
index 00000000000..354155999ce
--- /dev/null
+++ b/sql/updates/world/2013_09_30_00_world_item_loot_template.sql
@@ -0,0 +1,168 @@
+SET @Reference := 10036; -- Needs 26 reference loot template entries
+DELETE FROM `item_loot_template` WHERE `entry` BETWEEN 51999 AND 52005;
+INSERT INTO `item_loot_template` (`entry`,`item`,`ChanceOrQuestChance`,`lootmode`,`groupid`,`mincountOrRef`,`maxcount`) VALUES
+-- Satchel of Helpfull Goods (level 0-25)
+(51999,1,100,1,1,-@Reference,1), -- Cloth
+(51999,2,100,1,2,-@Reference-1,1), -- Leather
+(51999,3,100,1,3,-@Reference-2,1), -- Mail
+-- Satchel of Helpfull Goods (level 26-35)
+(52000,1,100,1,1,-@Reference-3,1), -- Cloth
+(52000,2,100,1,2,-@Reference-4,1), -- Leather
+(52000,3,100,1,3,-@Reference-5,1), -- Mail
+-- Satchel of Helpfull Goods (level 36-45)
+(52001,1,100,1,1,-@Reference-6,1), -- Cloth
+(52001,2,100,1,2,-@Reference-7,1), -- Leather
+(52001,3,100,1,3,-@Reference-8,1), -- Mail
+(52001,4,100,1,4,-@Reference-9,1), -- Plate
+-- Satchel of Helpfull Goods (level 46-55)
+(52002,1,100,1,1,-@Reference-10,1), -- Cloth
+(52002,2,100,1,2,-@Reference-11,1), -- Leather
+(52002,3,100,1,3,-@Reference-12,1), -- Mail
+(52002,4,100,1,4,-@Reference-13,1), -- Plate
+-- Satchel of Helpfull Goods (level 56-60)
+(52003,1,100,1,1,-@Reference-14,1), -- Cloth
+(52003,2,100,1,2,-@Reference-15,1), -- leather
+(52003,3,100,1,3,-@Reference-16,1), -- Mail
+(52003,4,100,1,4,-@Reference-17,1), -- Plate
+-- Satchel of Helpfull Goods (level 61-64)
+(52004,1,100,1,1,-@Reference-18,1), -- Cloth
+(52004,2,100,1,2,-@Reference-19,1), -- leather
+(52004,3,100,1,3,-@Reference-20,1), -- mail
+(52004,4,100,1,4,-@Reference-21,1), -- plate
+-- Satchel of Helpfull Goods (level 65-70)
+(52005,1,100,1,1,-@Reference-22,1), -- Cloth
+(52005,2,100,1,2,-@Reference-23,1), -- leather
+(52005,3,100,1,3,-@Reference-24,1), -- mail
+(52005,4,100,1,4,-@Reference-25,1); -- plate
+DELETE FROM `reference_loot_template` WHERE `entry` BETWEEN @Reference AND @Reference+25;
+INSERT INTO `reference_loot_template` (`entry`,`item`,`ChanceOrQuestChance`,`lootmode`,`groupid`,`mincountOrRef`,`maxcount`) VALUES
+-- Satchel of Helpfull Goods (level 0-25)
+(@Reference,51968,0,1,1,1,1), -- Enumerated Wrap
+(@Reference,51994,0,1,1,1,1), -- Tumultuous Cloak
+(@Reference+1,51964,0,1,2,1,1), -- Vigorous Belt
+(@Reference+1,51994,0,1,2,1,1), -- Tumultuous Cloak
+(@Reference+2,51978,0,1,3,1,1), -- Earthbound Girdle
+(@Reference+2,51994,0,1,3,1,1), -- Tumultuous Cloak
+-- Satchel of Helpfull Goods (level 26-35)
+(@Reference+3,51973,0,1,1,1,1), -- Enumerated Handwraps
+(@Reference+3,51996,0,1,1,1,1), -- Tumultuous Necklace
+(@Reference+4,51965,0,1,2,1,1), -- Vigorous Handguards
+(@Reference+4,51996,0,1,2,1,1), -- Tumultuous Necklace
+(@Reference+5,51980,0,1,3,1,1), -- Earthbound Handgrips
+(@Reference+5,51996,0,1,3,1,1), -- Tumultuous Necklace
+-- Satchel of Helpfull Goods (level 36-45)
+(@Reference+6,51974,0,1,1,1,1), -- Enumerated Shoulderpads
+(@Reference+6,51992,0,1,1,1,1), -- Tumultuous Ring
+(@Reference+7,51966,0,1,2,1,1), -- Vigorous Spaulders
+(@Reference+7,51992,0,1,2,1,1), -- Tumultuous Ring
+(@Reference+8,51976,0,1,3,1,1), -- Earthbound Shoulderguards
+(@Reference+8,51992,0,1,3,1,1), -- Tumultuous Ring
+(@Reference+9,51984,0,1,4,1,1), -- Stalwart Shoulderpads
+(@Reference+9,51992,0,1,4,1,1), -- Tumultuous Ring
+-- Satchel of Helpfull Goods (level 46-55)
+(@Reference+10,51967,0,1,1,1,1), -- Enumerated Sandals
+(@Reference+10,51972,0,1,1,1,1), -- Enumerated Bracers
+(@Reference+11,51962,0,1,2,1,1), -- Vigorous Bracers
+(@Reference+11,51963,0,1,2,1,1), -- Vigorous Stompers
+(@Reference+12,51981,0,1,3,1,1), -- Earthbound Wristguards
+(@Reference+12,51982,0,1,3,1,1), -- Earthbound Boots
+(@Reference+13,51989,0,1,4,1,1), -- Stalwart Bands
+(@Reference+13,51990,0,1,4,1,1), -- Stalwart Treads
+-- Satchel of Helpfull Goods (level 56-60)
+(@Reference+14,51971,0,1,1,1,1), -- Enumerated Belt
+(@Reference+14,51993,0,1,1,1,1), -- Turbulent Cloak
+(@Reference+15,51959,0,1,2,1,1), -- Vigorous Belt
+(@Reference+15,51993,0,1,2,1,1), -- Turbulent Cloak
+(@Reference+16,51977,0,1,3,1,1), -- Earthbound Girdle
+(@Reference+16,51993,0,1,3,1,1), -- Turbulent Cloak
+(@Reference+17,51985,0,1,4,1,1), -- Stalwart Belt
+(@Reference+17,51993,0,1,4,1,1), -- Turbulent Cloak
+-- Satchel of Helpfull Goods (level 61-64)
+(@Reference+18,51970,0,1,1,1,1), -- Enumerated Gloves
+(@Reference+18,51995,0,1,1,1,1), -- Turbulent Necklace
+(@Reference+19,51960,0,1,2,1,1), -- Vigorous Gloves
+(@Reference+19,51995,0,1,2,1,1), -- Turbulent Necklace
+(@Reference+20,51979,0,1,3,1,1), -- Earthbound Grips
+(@Reference+20,51995,0,1,3,1,1), -- Turbulent Necklace
+(@Reference+21,51987,0,1,4,1,1), -- Stalwart Grips
+(@Reference+21,51995,0,1,4,1,1), -- Turbulent Necklace
+-- Satchel of Helpfull Goods (level 65-70)
+(@Reference+22,51961,0,1,1,1,1), -- Vigorous Shoulderguards
+(@Reference+22,51991,0,1,1,1,1), -- Turbulent Signet
+(@Reference+23,51969,0,1,2,1,1), -- Enumerated Shoulders
+(@Reference+23,51991,0,1,2,1,1), -- Turbulent Signet
+(@Reference+24,51975,0,1,3,1,1), -- Earthbound Shoulders
+(@Reference+24,51991,0,1,3,1,1), -- Turbulent Signet
+(@Reference+25,51983,0,1,4,1,1), -- Stalwart Shoulderguards
+(@Reference+25,51991,0,1,4,1,1); -- Turbulent Signet
+
+-- -------------------------------------------------------------------
+-- Set some Parameters
+-- -------------------------------------------------------------------
+SET @Cloth := 400; -- Class Bitmask: 16 (Priest) +128 (Mage) +256 (Warlock)
+SET @Leather1 := 1100; -- Class Bitmask: 4 (Hunter) +8 (Rogue) +64 (Shaman) +1024 (Druid)
+SET @Leather2 := 1032; -- Class Bitmask: 8 (Rogue) +1024 (Druid)
+SET @Mail1 := 3; -- Class Bitmask: 1 (Warrior) +2 (Paladin)
+SET @Mail2 := 68; -- Class Bitmask: 4 (Hunter) +8 (Shaman)
+SET @Plate := 35; -- Class Bitmask: 1 (Warrior) +2 (Paladin) +32 (DeathKnight)
+-- Add conditions to make sure everyone gets beneficial loot for their class
+-- -------------------------------------------------------------------
+DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=5 AND `SourceGroup` BETWEEN 51999 AND 52005;
+DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=10 AND `SourceGroup` BETWEEN @Reference AND @Reference+25;
+INSERT INTO `conditions` (`SourceTypeOrReferenceId`,`SourceGroup`,`SourceEntry`,`SourceId`,`ElseGroup`,`ConditionTypeOrReference`,`ConditionTarget`,`ConditionValue1`,`ConditionValue2`,`ConditionValue3`,`NegativeCondition`,`ErrorTextId`,`ScriptName`,`Comment`) VALUES
+-- Cloth Items
+(10,@Reference,51968,0,0,15,0,@Cloth,0,0,0,0,'','SOHG: Enumerated Wrap only for clothusers'),
+(10,@Reference,51994,0,0,15,0,@Cloth,0,0,0,0,'','SOHG: Tumultuous Cloak only for clothusers'),
+(10,@Reference+3,51973,0,0,15,0,@Cloth,0,0,0,0,'','SOHG: Enumerated Handwraps only for clothusers'),
+(10,@Reference+3,51996,0,0,15,0,@Cloth,0,0,0,0,'','SOHG: Tumultuous Necklace only for clothusers'),
+(10,@Reference+6,51974,0,0,15,0,@Cloth,0,0,0,0,'','SOHG: Enumerated Shoulderpads only for clothusers'),
+(10,@Reference+6,51992,0,0,15,0,@Cloth,0,0,0,0,'','SOHG: Tumultuous Ring only for clothusers'),
+(10,@Reference+10,51967,0,0,15,0,@Cloth,0,0,0,0,'','SOHG: Enumerated Sandals only for clothusers'),
+(10,@Reference+10,51972,0,0,15,0,@Cloth,0,0,0,0,'','SOHG: Enumerated Bracers only for clothusers'),
+(10,@Reference+14,51971,0,0,15,0,@Cloth,0,0,0,0,'','SOHG: Enumerated Belt only for clothusers'),
+(10,@Reference+14,51993,0,0,15,0,@Cloth,0,0,0,0,'','SOHG: Turbulent Cloak only for clothusers'),
+(10,@Reference+18,51970,0,0,15,0,@Cloth,0,0,0,0,'','SOHG: Enumerated Gloves only for clothusers'),
+(10,@Reference+18,51995,0,0,15,0,@Cloth,0,0,0,0,'','SOHG: Turbulent Necklace only for clothusers'),
+(10,@Reference+22,51969,0,0,15,0,@Cloth,0,0,0,0,'','SOHG: Enumerated Shoulders only for clothusers'),
+(10,@Reference+22,51991,0,0,15,0,@Cloth,0,0,0,0,'','SOHG: Turbulent Signet only for clothusers'),
+-- Leather Items
+(10,@Reference+1,51964,0,0,15,0,@Leather1,0,0,0,0,'','SOHG: Vigorous Belt only for leatherusers'),
+(10,@Reference+1,51994,0,0,15,0,@Leather1,0,0,0,0,'','SOHG: Tumultuous Cloak only for leatherusers'),
+(10,@Reference+4,51965,0,0,15,0,@Leather1,0,0,0,0,'','SOHG: Vigorous Handguards only for leatherusers'),
+(10,@Reference+4,51996,0,0,15,0,@Leather1,0,0,0,0,'','SOHG: Tumultuous Necklace only for leatherusers'),
+(10,@Reference+7,51966,0,0,15,0,@Leather2,0,0,0,0,'','SOHG: Vigorous Spaulders only for leatherusers'),
+(10,@Reference+7,51992,0,0,15,0,@Leather2,0,0,0,0,'','SOHG: Tumultuous ring only for leatherusers'),
+(10,@Reference+11,51962,0,0,15,0,@Leather2,0,0,0,0,'','SOHG: Vigorous Bracers only for leatherusers'),
+(10,@Reference+11,51963,0,0,15,0,@Leather2,0,0,0,0,'','SOHG: Vigorous Stompers only for leatherusers'),
+(10,@Reference+15,51959,0,0,15,0,@Leather2,0,0,0,0,'','SOHG: Vigorous Belt only for leatherusers'),
+(10,@Reference+15,51993,0,0,15,0,@Leather2,0,0,0,0,'','SOHG: Turbulent Cloak only for leatherusers'),
+(10,@Reference+19,51960,0,0,15,0,@Leather2,0,0,0,0,'','SOHG: Vigorous Gloves only for leatherusers'),
+(10,@Reference+19,51995,0,0,15,0,@Leather2,0,0,0,0,'','SOHG: Turbulent Necklace only for leatherusers'),
+(10,@Reference+23,51961,0,0,15,0,@Leather2,0,0,0,0,'','SOHG: Vigorous Shoulderguards only for leatherusers'),
+(10,@Reference+23,51991,0,0,15,0,@Leather2,0,0,0,0,'','SOHG: Turbulent Signet only for leatherusers'),
+-- Mail Items
+(10,@Reference+2,51978,0,0,15,0,@Mail1,0,0,0,0,'','SOHG: Earthbound Girdle only for mail users'),
+(10,@Reference+2,51994,0,0,15,0,@Mail1,0,0,0,0,'','SOHG: Tumultuous Cloak only for mail users'),
+(10,@Reference+5,51980,0,0,15,0,@Mail1,0,0,0,0,'','SOHG: Earthbound Handgrips only for mail users'),
+(10,@Reference+5,51996,0,0,15,0,@Mail1,0,0,0,0,'','SOHG: Tumultuous Necklace only for Mail users'),
+(10,@Reference+8,51976,0,0,15,0,@Mail2,0,0,0,0,'','SOHG: Earthbound Shoulderguards only for mail users'),
+(10,@Reference+8,51992,0,0,15,0,@Mail2,0,0,0,0,'','SOHG: Tumultuous Ring only for mail users'),
+(10,@Reference+12,51982,0,0,15,0,@Mail2,0,0,0,0,'','SOHG: Earthbound Boots only for mail users'),
+(10,@Reference+12,51981,0,0,15,0,@Mail2,0,0,0,0,'','SOHG: Earthbound Wristguards only for mail users'),
+(10,@Reference+16,51977,0,0,15,0,@Mail2,0,0,0,0,'','SOHG: Earthbound Girdle only for mail users'),
+(10,@Reference+16,51993,0,0,15,0,@Mail2,0,0,0,0,'','SOHG: Turbulent Cloak only for mail users'),
+(10,@Reference+20,51979,0,0,15,0,@Mail2,0,0,0,0,'','SOHG: Earthbound Grips only for mail users'),
+(10,@Reference+20,51995,0,0,15,0,@Mail2,0,0,0,0,'','SOHG: Turbulent Necklace only for mail users'),
+(10,@Reference+24,51975,0,0,15,0,@Mail2,0,0,0,0,'','SOHG: Earthbound Shoulders only for mail users'),
+(10,@Reference+24,51991,0,0,15,0,@Mail2,0,0,0,0,'','SOHG: Turbulent Signet only for Mail users'),
+-- Plate Items
+(10,@Reference+9,51984,0,0,15,0,@Plate,0,0,0,0,'','SOHG: Stalwart Shoulderpads only for plate users'),
+(10,@Reference+9,51992,0,0,15,0,@Plate,0,0,0,0,'','SOHG: Tumultuous Ring only for plate users'),
+(10,@Reference+13,51989,0,0,15,0,@Plate,0,0,0,0,'','SOHG: Stalwart Bands only for plate users'),
+(10,@Reference+13,51990,0,0,15,0,@Plate,0,0,0,0,'','SOHG: Stalwart Treads only for plate users'),
+(10,@Reference+17,51985,0,0,15,0,@Plate,0,0,0,0,'','SOHG: Stalwart Belt only for plate users'),
+(10,@Reference+17,51993,0,0,15,0,@Plate,0,0,0,0,'','SOHG: Turbulent Cloak only for plate users'),
+(10,@Reference+21,51987,0,0,15,0,@Plate,0,0,0,0,'','SOHG: Stalwart Grips only for plate users'),
+(10,@Reference+21,51995,0,0,15,0,@Plate,0,0,0,0,'','SOHG: Turbulent Necklace only for plate users'),
+(10,@Reference+25,51983,0,0,15,0,@Plate,0,0,0,0,'','SOHG: Stalwart Shoulderguards only for plate users'),
+(10,@Reference+25,51991,0,0,15,0,@Plate,0,0,0,0,'','SOHG: Turbulent Signet only for plate users');
diff --git a/sql/updates/world/2013_09_30_01_world_item_loot_template.sql b/sql/updates/world/2013_09_30_01_world_item_loot_template.sql
new file mode 100644
index 00000000000..9c60a618139
--- /dev/null
+++ b/sql/updates/world/2013_09_30_01_world_item_loot_template.sql
@@ -0,0 +1,8 @@
+DELETE FROM `reference_loot_template` WHERE `entry`=11112;
+UPDATE `reference_loot_template` SET `entry`=11114 WHERE `item`= 34831 AND `entry`=11115;
+DELETE FROM `item_loot_template` WHERE `entry`=35348;
+INSERT INTO `item_loot_template` (`entry`,`item`,`ChanceOrQuestChance`,`lootmode`,`groupid`,`mincountOrRef`,`maxcount`) VALUES
+(35348,1,100,1,0,-11113,1), -- Garanteed Drops
+(35348,2, 60,1,0,-11116,1), -- Rare Pets
+(35348,4, 60,1,0,-11115,1), -- Junk items
+(35348,3, 5,1,0,-11114,1); -- Lesser Treasures
diff --git a/sql/updates/world/2013_09_30_02_world_sai_335.sql b/sql/updates/world/2013_09_30_02_world_sai_335.sql
new file mode 100644
index 00000000000..909f0d42b42
--- /dev/null
+++ b/sql/updates/world/2013_09_30_02_world_sai_335.sql
@@ -0,0 +1,5 @@
+-- DB/Quest: Fix: [A/H] The Summoning
+-- Note: This warrior quest was deleted in 4.0.1.
+SET @ENTRY := 6176; -- Bath'rah the Windwatcher
+DELETE FROM `waypoints` WHERE `entry` = @ENTRY AND `pointid` BETWEEN 8 AND 14;
+UPDATE `smart_scripts` SET `event_type` = 40 WHERE `entryorguid` = @ENTRY AND `id` = 1;
diff --git a/sql/updates/world/2013_09_30_03_world_misc.sql b/sql/updates/world/2013_09_30_03_world_misc.sql
new file mode 100644
index 00000000000..579958f111a
--- /dev/null
+++ b/sql/updates/world/2013_09_30_03_world_misc.sql
@@ -0,0 +1,7 @@
+DELETE FROM `command` WHERE `permission` BETWEEN 200 AND 216;
+INSERT INTO `command` (`name`, `permission`, `help`) VALUES
+('rbac account list', 202, 'Syntax: rbac account list [$account]\n\nView permissions of selected player or given account\nNote: Only those that affect current realm'),
+('rbac account grant', 203, 'Syntax: rbac account grant [$account] #id [#realmId]\n\nGrant a permission to selected player or given account.\n\n#reamID may be -1 for all realms.'),
+('rbac account deny', 204, 'Syntax: rbac account deny [$account] #id [#realmId]\n\nDeny a permission to selected player or given account.\n\n#reamID may be -1 for all realms.'),
+('rbac account revoke', 205, 'Syntax: rbac account revoke [$account] #id\n\nRemove a permission from an account\n\nNote: Removes the permission from granted or denied permissions'),
+('rbac list', 206, 'Syntax: rbac list [$id]\n\nView list of all permissions. If $id is given will show only info for that permission.');
diff --git a/sql/updates/world/2013_09_30_04_world_update.sql b/sql/updates/world/2013_09_30_04_world_update.sql
new file mode 100644
index 00000000000..a96cad21e64
--- /dev/null
+++ b/sql/updates/world/2013_09_30_04_world_update.sql
@@ -0,0 +1,2 @@
+UPDATE `creature_template_addon` SET `mount`=25678, `bytes2`=0x1 WHERE `entry`=37845;
+UPDATE `smart_scripts` SET `action_param1`=45492, `comment`='Quel''Delar Skull Target - on spell hit - Cast Shadow Nova' WHERE `entryorguid`=37852 AND `source_type`=0 AND `id`=1 AND `link`=0;
diff --git a/sql/updates/world/2013_10_01_00_misc.sql b/sql/updates/world/2013_10_01_00_misc.sql
new file mode 100644
index 00000000000..b6283dbd820
--- /dev/null
+++ b/sql/updates/world/2013_10_01_00_misc.sql
@@ -0,0 +1,9 @@
+UPDATE `creature_template` SET `npcflag`=4227 WHERE `entry`=38316;
+
+DELETE FROM `gossip_menu_option` WHERE `menu_id`=10996 AND `id`=5;
+INSERT INTO `gossip_menu_option` (`menu_id`, `id`, `option_icon`, `option_text`, `option_id`, `npc_option_npcflag`, `action_menu_id`, `action_poi_id`, `box_coded`, `box_money`, `box_text`) VALUES
+(10996, 5, 1, 'Show me the armor of Scourge lords, Ormus.', 3, 128, 0, 0, 0, 0, '');
+
+DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=15 AND `SourceGroup`=10996 AND `SourceEntry`=5;
+INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES
+(15, 10996, 5, 0, 0, 15, 0, 32, 0, 0, 0, 0, 0, '', 'Ormus the Penitent - Show gossip option if player is a Death Knight');
diff --git a/sql/updates/world/2013_10_01_00_world_sai.sql b/sql/updates/world/2013_10_01_00_world_sai.sql
new file mode 100644
index 00000000000..13f4e825e81
--- /dev/null
+++ b/sql/updates/world/2013_10_01_00_world_sai.sql
@@ -0,0 +1,6 @@
+UPDATE `creature_template` SET `AIName`= 'SmartAI' WHERE `entry` IN(10977,10978,7583);
+DELETE FROM `smart_scripts` WHERE `entryorguid` IN (10977,10978,7583);
+INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES
+(10977, 0, 0, 0, 8, 0, 100, 0, 17166, 0, 0, 0, 33, 10977 , 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 'Quixxil - On Spellhit (Release Umis Yeti) - Kill Credit'),
+(10978, 0, 0, 0, 8, 0, 100, 0, 17166, 0, 0, 0, 33, 10978 , 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 'Legacki - On Spellhit (Release Umis Yeti)- Kill Credit'),
+(7583, 0, 0, 0, 8, 0, 100, 0, 17166, 0, 0, 0, 33, 7583 , 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 'Sprinkle - On Spellhit (Release Umis Yeti)- Kill Credit');
diff --git a/sql/updates/world/2013_10_05_00_world_sai.sql b/sql/updates/world/2013_10_05_00_world_sai.sql
new file mode 100644
index 00000000000..c76916ee053
--- /dev/null
+++ b/sql/updates/world/2013_10_05_00_world_sai.sql
@@ -0,0 +1,9 @@
+DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=13 AND `SourceEntry`=48188;
+
+INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES
+(13, 1, 48188, 0, 0, 31, 0, 3, 27349, 0, 0, 0, 0, '', 'Flask of Blight Targets Scarlet Onslaught Prisoner');
+
+DELETE FROM `disables` WHERE `sourceType`=0 AND `entry`=48188;
+
+INSERT INTO `disables` (`sourceType`, `entry`, `flags`, `params_0`, `params_1`, `comment`) VALUES
+(0, 48188, 64, '', '', 'Ignore LOS on Flask of Blight');
diff --git a/src/server/authserver/Server/AuthSocket.cpp b/src/server/authserver/Server/AuthSocket.cpp
index 1ab9ae6eb62..4a9d3ce7faf 100644
--- a/src/server/authserver/Server/AuthSocket.cpp
+++ b/src/server/authserver/Server/AuthSocket.cpp
@@ -222,12 +222,25 @@ void AuthSocket::OnClose(void)
// Read the packet from the client
void AuthSocket::OnRead()
{
+ #define MAX_AUTH_LOGON_CHALLENGES_IN_A_ROW 3
+ uint32 challengesInARow = 0;
uint8 _cmd;
while (1)
{
if (!socket().recv_soft((char *)&_cmd, 1))
return;
+ if (_cmd == AUTH_LOGON_CHALLENGE)
+ {
+ ++challengesInARow;
+ if (challengesInARow == MAX_AUTH_LOGON_CHALLENGES_IN_A_ROW)
+ {
+ TC_LOG_WARN(LOG_FILTER_AUTHSERVER, "Got %u AUTH_LOGON_CHALLENGE in a row from '%s', possible ongoing DoS", challengesInARow, socket().getRemoteAddress().c_str());
+ socket().shutdown();
+ return;
+ }
+ }
+
size_t i;
// Circle through known commands and call the correct command handler
diff --git a/src/server/game/AI/SmartScripts/SmartAI.cpp b/src/server/game/AI/SmartScripts/SmartAI.cpp
index a56d0f94f2d..57fd7ea2d73 100644
--- a/src/server/game/AI/SmartScripts/SmartAI.cpp
+++ b/src/server/game/AI/SmartScripts/SmartAI.cpp
@@ -206,7 +206,7 @@ void SmartAI::EndPath(bool fail)
mLastWP = NULL;
if (mCanRepeatPath)
- StartPath(mRun, GetScript()->GetPathId(), mCanRepeatPath);
+ StartPath(mRun, GetScript()->GetPathId(), true);
else
GetScript()->SetPathId(0);
diff --git a/src/server/game/AI/SmartScripts/SmartScript.cpp b/src/server/game/AI/SmartScripts/SmartScript.cpp
index ba1e59e0cc9..3823f7ba287 100644
--- a/src/server/game/AI/SmartScripts/SmartScript.cpp
+++ b/src/server/game/AI/SmartScripts/SmartScript.cpp
@@ -942,7 +942,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
break;
instance->SetData64(e.action.setInstanceData64.field, targets->front()->GetGUID());
- TC_LOG_DEBUG(LOG_FILTER_DATABASE_AI, "SmartScript::ProcessAction: SMART_ACTION_SET_INST_DATA64: Field: %u, data: "UI64FMTD,
+ TC_LOG_DEBUG(LOG_FILTER_DATABASE_AI, "SmartScript::ProcessAction: SMART_ACTION_SET_INST_DATA64: Field: %u, data: " UI64FMTD,
e.action.setInstanceData64.field, targets->front()->GetGUID());
delete targets;
@@ -1585,8 +1585,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
break;
}
- ObjectList* targets = GetTargets(e, unit);
- if (targets)
+ if (ObjectList* targets = GetTargets(e, unit))
{
for (ObjectList::iterator itr = targets->begin(); itr != targets->end(); ++itr)
{
@@ -2551,7 +2550,7 @@ ObjectList* SmartScript::GetTargets(SmartScriptHolder const& e, Unit* invoker /*
case SMART_TARGET_CLOSEST_ENEMY:
{
if (me)
- if (Unit* target = me->SelectNearestTarget(e.target.closestAttackable.maxDist))
+ if (Unit* target = me->SelectNearestTarget(e.target.closestAttackable.maxDist, e.target.closestAttackable.playerOnly))
l->push_back(target);
break;
@@ -2559,7 +2558,7 @@ ObjectList* SmartScript::GetTargets(SmartScriptHolder const& e, Unit* invoker /*
case SMART_TARGET_CLOSEST_FRIENDLY:
{
if (me)
- if (Unit* target = DoFindClosestFriendlyInRange(e.target.closestFriendly.maxDist))
+ if (Unit* target = DoFindClosestFriendlyInRange(e.target.closestFriendly.maxDist, e.target.closestFriendly.playerOnly))
l->push_back(target);
break;
@@ -3443,13 +3442,13 @@ void SmartScript::DoFindFriendlyMissingBuff(std::list<Creature*>& list, float ra
cell.Visit(p, grid_creature_searcher, *me->GetMap(), *me, range);
}
-Unit* SmartScript::DoFindClosestFriendlyInRange(float range)
+Unit* SmartScript::DoFindClosestFriendlyInRange(float range, bool playerOnly)
{
if (!me)
return NULL;
Unit* unit = NULL;
- Trinity::AnyFriendlyUnitInObjectRangeCheck u_check(me, me, range);
+ Trinity::AnyFriendlyUnitInObjectRangeCheck u_check(me, me, range, playerOnly);
Trinity::UnitLastSearcher<Trinity::AnyFriendlyUnitInObjectRangeCheck> searcher(me, unit, u_check);
me->VisitNearbyObject(range, searcher);
return unit;
@@ -3463,16 +3462,15 @@ void SmartScript::SetScript9(SmartScriptHolder& e, uint32 entry)
return;
for (SmartAIEventList::iterator i = mTimedActionList.begin(); i != mTimedActionList.end(); ++i)
{
- if (i == mTimedActionList.begin())
- {
- i->enableTimed = true;//enable processing only for the first action
- }
- else i->enableTimed = false;
+ i->enableTimed = i == mTimedActionList.begin();//enable processing only for the first action
- if (e.action.timedActionList.timerType == 1)
+ if (e.action.timedActionList.timerType == 0)
+ i->event.type = SMART_EVENT_UPDATE_OOC;
+ else if (e.action.timedActionList.timerType == 1)
i->event.type = SMART_EVENT_UPDATE_IC;
else if (e.action.timedActionList.timerType > 1)
i->event.type = SMART_EVENT_UPDATE;
+
InitTimer((*i));
}
}
diff --git a/src/server/game/AI/SmartScripts/SmartScript.h b/src/server/game/AI/SmartScripts/SmartScript.h
index b22f2d81b26..b1b9f4d6725 100644
--- a/src/server/game/AI/SmartScripts/SmartScript.h
+++ b/src/server/game/AI/SmartScripts/SmartScript.h
@@ -89,7 +89,7 @@ class SmartScript
Unit* DoSelectLowestHpFriendly(float range, uint32 MinHPDiff);
void DoFindFriendlyCC(std::list<Creature*>& _list, float range);
void DoFindFriendlyMissingBuff(std::list<Creature*>& list, float range, uint32 spellid);
- Unit* DoFindClosestFriendlyInRange(float range);
+ Unit* DoFindClosestFriendlyInRange(float range, bool playerOnly);
void StoreTargetList(ObjectList* targets, uint32 id)
{
diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.h b/src/server/game/AI/SmartScripts/SmartScriptMgr.h
index 90819e7a2c3..56fa7ed1275 100644
--- a/src/server/game/AI/SmartScripts/SmartScriptMgr.h
+++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.h
@@ -1021,8 +1021,8 @@ enum SMARTAI_TARGETS
SMART_TARGET_ACTION_INVOKER_VEHICLE = 22, // Unit's vehicle who caused this Event to occur
SMART_TARGET_OWNER_OR_SUMMONER = 23, // Unit's owner or summoner
SMART_TARGET_THREAT_LIST = 24, // All units on creature's threat list
- SMART_TARGET_CLOSEST_ENEMY = 25, // maxDist
- SMART_TARGET_CLOSEST_FRIENDLY = 26, // maxDist
+ SMART_TARGET_CLOSEST_ENEMY = 25, // maxDist, playerOnly
+ SMART_TARGET_CLOSEST_FRIENDLY = 26, // maxDist, playerOnly
SMART_TARGET_END = 27
};
@@ -1109,11 +1109,13 @@ struct SmartTarget
struct
{
uint32 maxDist;
+ uint32 playerOnly;
} closestAttackable;
struct
{
uint32 maxDist;
+ uint32 playerOnly;
} closestFriendly;
struct
diff --git a/src/server/game/Chat/Chat.cpp b/src/server/game/Chat/Chat.cpp
index aaa630ce4b8..a5c059b30df 100644
--- a/src/server/game/Chat/Chat.cpp
+++ b/src/server/game/Chat/Chat.cpp
@@ -344,7 +344,7 @@ bool ChatHandler::ExecuteCommandInTable(ChatCommand* table, const char* text, st
Player* player = m_session->GetPlayer();
if (!AccountMgr::IsPlayerAccount(m_session->GetSecurity()))
{
- uint64 guid = player->GetSelection();
+ uint64 guid = player->GetTarget();
uint32 areaId = player->GetAreaId();
std::string areaName = "Unknown";
std::string zoneName = "Unknown";
@@ -713,12 +713,10 @@ Player* ChatHandler::getSelectedPlayer()
if (!m_session)
return NULL;
- uint64 guid = m_session->GetPlayer()->GetSelection();
+ if (Player* selected = m_session->GetPlayer()->GetSelectedPlayer())
+ return selected;
- if (guid == 0)
- return m_session->GetPlayer();
-
- return ObjectAccessor::FindPlayer(guid);
+ return m_session->GetPlayer();
}
Unit* ChatHandler::getSelectedUnit()
@@ -726,12 +724,10 @@ Unit* ChatHandler::getSelectedUnit()
if (!m_session)
return NULL;
- uint64 guid = m_session->GetPlayer()->GetSelection();
+ if (Unit* selected = m_session->GetPlayer()->GetSelectedUnit())
+ return selected;
- if (guid == 0)
- return m_session->GetPlayer();
-
- return ObjectAccessor::GetUnit(*m_session->GetPlayer(), guid);
+ return m_session->GetPlayer();
}
WorldObject* ChatHandler::getSelectedObject()
@@ -739,7 +735,7 @@ WorldObject* ChatHandler::getSelectedObject()
if (!m_session)
return NULL;
- uint64 guid = m_session->GetPlayer()->GetSelection();
+ uint64 guid = m_session->GetPlayer()->GetTarget();
if (guid == 0)
return GetNearbyGameObject();
@@ -752,7 +748,7 @@ Creature* ChatHandler::getSelectedCreature()
if (!m_session)
return NULL;
- return ObjectAccessor::GetCreatureOrPetOrVehicle(*m_session->GetPlayer(), m_session->GetPlayer()->GetSelection());
+ return ObjectAccessor::GetCreatureOrPetOrVehicle(*m_session->GetPlayer(), m_session->GetPlayer()->GetTarget());
}
char* ChatHandler::extractKeyFromLink(char* text, char const* linkType, char** something1)
diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp
index 169d5feae03..4efd78d5932 100644
--- a/src/server/game/Entities/Creature/Creature.cpp
+++ b/src/server/game/Entities/Creature/Creature.cpp
@@ -165,6 +165,7 @@ m_creatureInfo(NULL), m_creatureData(NULL), m_path_id(0), m_formation(NULL)
ResetLootMode(); // restore default loot mode
TriggerJustRespawned = false;
m_isTempWorldObject = false;
+ _focusSpell = NULL;
}
Creature::~Creature()
@@ -1709,7 +1710,7 @@ SpellInfo const* Creature::reachWithSpellCure(Unit* victim)
}
// select nearest hostile unit within the given distance (regardless of threat list).
-Unit* Creature::SelectNearestTarget(float dist) const
+Unit* Creature::SelectNearestTarget(float dist, bool playerOnly /* = false */) const
{
CellCoord p(Trinity::ComputeCellCoord(GetPositionX(), GetPositionY()));
Cell cell(p);
@@ -1721,7 +1722,7 @@ Unit* Creature::SelectNearestTarget(float dist) const
if (dist == 0.0f)
dist = MAX_VISIBILITY_DISTANCE;
- Trinity::NearestHostileUnitCheck u_check(this, dist);
+ Trinity::NearestHostileUnitCheck u_check(this, dist, playerOnly);
Trinity::UnitLastSearcher<Trinity::NearestHostileUnitCheck> searcher(this, target, u_check);
TypeContainerVisitor<Trinity::UnitLastSearcher<Trinity::NearestHostileUnitCheck>, WorldTypeMapContainer > world_unit_searcher(searcher);
@@ -2640,3 +2641,41 @@ void Creature::SetDisplayId(uint32 modelId)
SetFloatValue(UNIT_FIELD_COMBATREACH, minfo->combat_reach * GetObjectScale());
}
}
+
+void Creature::SetTarget(uint64 guid)
+{
+ if (!_focusSpell)
+ SetUInt64Value(UNIT_FIELD_TARGET, guid);
+}
+
+void Creature::FocusTarget(Spell const* focusSpell, WorldObject const* target)
+{
+ // already focused
+ if (_focusSpell)
+ return;
+
+ _focusSpell = focusSpell;
+ SetUInt64Value(UNIT_FIELD_TARGET, target->GetGUID());
+ if (focusSpell->GetSpellInfo()->AttributesEx5 & SPELL_ATTR5_DONT_TURN_DURING_CAST)
+ AddUnitState(UNIT_STATE_ROTATING);
+
+ // Set serverside orientation if needed (needs to be after attribute check)
+ SetInFront(target);
+}
+
+void Creature::ReleaseFocus(Spell const* focusSpell)
+{
+ // focused to something else
+ if (focusSpell != _focusSpell)
+ return;
+
+ _focusSpell = NULL;
+ if (Unit* victim = GetVictim())
+ SetUInt64Value(UNIT_FIELD_TARGET, victim->GetGUID());
+ else
+ SetUInt64Value(UNIT_FIELD_TARGET, 0);
+
+ if (focusSpell->GetSpellInfo()->AttributesEx5 & SPELL_ATTR5_DONT_TURN_DURING_CAST)
+ ClearUnitState(UNIT_STATE_ROTATING);
+}
+
diff --git a/src/server/game/Entities/Creature/Creature.h b/src/server/game/Entities/Creature/Creature.h
index b720a063f2d..3a07d9c101b 100644
--- a/src/server/game/Entities/Creature/Creature.h
+++ b/src/server/game/Entities/Creature/Creature.h
@@ -609,7 +609,7 @@ class Creature : public Unit, public GridObject<Creature>, public MapCreature
void SendAIReaction(AiReaction reactionType);
- Unit* SelectNearestTarget(float dist = 0) const;
+ Unit* SelectNearestTarget(float dist = 0, bool playerOnly = false) const;
Unit* SelectNearestTargetInAttackDistance(float dist = 0) const;
Player* SelectNearestPlayer(float distance = 0) const;
Unit* SelectNearestHostileUnitInAggroRange(bool useLOS = false) const;
@@ -703,6 +703,11 @@ class Creature : public Unit, public GridObject<Creature>, public MapCreature
bool m_isTempWorldObject; //true when possessed
+ // Handling caster facing during spellcast
+ void SetTarget(uint64 guid);
+ void FocusTarget(Spell const* focusSpell, WorldObject const* target);
+ void ReleaseFocus(Spell const* focusSpell);
+
protected:
bool CreateFromProto(uint32 guidlow, uint32 Entry, uint32 vehId, uint32 team, const CreatureData* data = NULL);
bool InitEntry(uint32 entry, uint32 team=ALLIANCE, const CreatureData* data=NULL);
@@ -762,6 +767,8 @@ class Creature : public Unit, public GridObject<Creature>, public MapCreature
//Formation var
CreatureGroup* m_formation;
bool TriggerJustRespawned;
+
+ Spell const* _focusSpell; ///> Locks the target during spell cast for proper facing
};
class AssistDelayEvent : public BasicEvent
diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp
index 15e7eb436e1..eef416b339d 100644
--- a/src/server/game/Entities/GameObject/GameObject.cpp
+++ b/src/server/game/Entities/GameObject/GameObject.cpp
@@ -1508,7 +1508,7 @@ void GameObject::Use(Unit* user)
Player* player = user->ToPlayer();
- Player* targetPlayer = ObjectAccessor::FindPlayer(player->GetSelection());
+ Player* targetPlayer = ObjectAccessor::FindPlayer(player->GetTarget());
// accept only use by player from same raid as caster, except caster itself
if (!targetPlayer || targetPlayer == player || !targetPlayer->IsInSameRaidWith(player))
diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp
index 5a787f910b8..9d77e144c0b 100644
--- a/src/server/game/Entities/Object/Object.cpp
+++ b/src/server/game/Entities/Object/Object.cpp
@@ -91,7 +91,7 @@ WorldObject::~WorldObject()
{
if (GetTypeId() == TYPEID_CORPSE)
{
- TC_LOG_FATAL(LOG_FILTER_GENERAL, "Object::~Object Corpse guid="UI64FMTD", type=%d, entry=%u deleted but still in map!!",
+ TC_LOG_FATAL(LOG_FILTER_GENERAL, "Object::~Object Corpse guid=" UI64FMTD ", type=%d, entry=%u deleted but still in map!!",
GetGUID(), ((Corpse*)this)->GetType(), GetEntry());
ASSERT(false);
}
@@ -103,7 +103,7 @@ Object::~Object()
{
if (IsInWorld())
{
- TC_LOG_FATAL(LOG_FILTER_GENERAL, "Object::~Object - guid="UI64FMTD", typeid=%d, entry=%u deleted but still in world!!", GetGUID(), GetTypeId(), GetEntry());
+ TC_LOG_FATAL(LOG_FILTER_GENERAL, "Object::~Object - guid=" UI64FMTD ", typeid=%d, entry=%u deleted but still in world!!", GetGUID(), GetTypeId(), GetEntry());
if (isType(TYPEMASK_ITEM))
TC_LOG_FATAL(LOG_FILTER_GENERAL, "Item slot %u", ((Item*)this)->GetSlot());
ASSERT(false);
@@ -112,7 +112,7 @@ Object::~Object()
if (m_objectUpdated)
{
- TC_LOG_FATAL(LOG_FILTER_GENERAL, "Object::~Object - guid="UI64FMTD", typeid=%d, entry=%u deleted but still in update list!!", GetGUID(), GetTypeId(), GetEntry());
+ TC_LOG_FATAL(LOG_FILTER_GENERAL, "Object::~Object - guid=" UI64FMTD ", typeid=%d, entry=%u deleted but still in update list!!", GetGUID(), GetTypeId(), GetEntry());
ASSERT(false);
sObjectAccessor->RemoveUpdateObject(this);
}
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index 8217682f103..9ada25b1c81 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -673,7 +673,6 @@ Player::Player(WorldSession* session): Unit(true)
if (!GetSession()->HasPermission(rbac::RBAC_PERM_CAN_FILTER_WHISPERS))
SetAcceptWhispers(true);
- m_curSelection = 0;
m_lootGuid = 0;
m_comboTarget = 0;
@@ -20455,7 +20454,7 @@ void Player::PossessSpellInitialize()
if (!charmInfo)
{
- TC_LOG_ERROR(LOG_FILTER_PLAYER, "Player::PossessSpellInitialize(): charm ("UI64FMTD") has no charminfo!", charm->GetGUID());
+ TC_LOG_ERROR(LOG_FILTER_PLAYER, "Player::PossessSpellInitialize(): charm (" UI64FMTD ") has no charminfo!", charm->GetGUID());
return;
}
@@ -20567,7 +20566,7 @@ void Player::CharmSpellInitialize()
CharmInfo* charmInfo = charm->GetCharmInfo();
if (!charmInfo)
{
- TC_LOG_ERROR(LOG_FILTER_PLAYER, "Player::CharmSpellInitialize(): the player's charm ("UI64FMTD") has no charminfo!", charm->GetGUID());
+ TC_LOG_ERROR(LOG_FILTER_PLAYER, "Player::CharmSpellInitialize(): the player's charm (" UI64FMTD ") has no charminfo!", charm->GetGUID());
return;
}
@@ -22397,15 +22396,15 @@ bool Player::IsQuestRewarded(uint32 quest_id) const
Unit* Player::GetSelectedUnit() const
{
- if (m_curSelection)
- return ObjectAccessor::GetUnit(*this, m_curSelection);
+ if (uint64 selectionGUID = GetUInt64Value(UNIT_FIELD_TARGET))
+ return ObjectAccessor::GetUnit(*this, selectionGUID);
return NULL;
}
Player* Player::GetSelectedPlayer() const
{
- if (m_curSelection)
- return ObjectAccessor::GetPlayer(*this, m_curSelection);
+ if (uint64 selectionGUID = GetUInt64Value(UNIT_FIELD_TARGET))
+ return ObjectAccessor::GetPlayer(*this, selectionGUID);
return NULL;
}
@@ -25416,7 +25415,7 @@ void Player::SetEquipmentSet(uint32 index, EquipmentSet eqset)
if (!found) // something wrong...
{
- TC_LOG_ERROR(LOG_FILTER_PLAYER, "Player %s tried to save equipment set "UI64FMTD" (index %u), but that equipment set not found!", GetName().c_str(), eqset.Guid, index);
+ TC_LOG_ERROR(LOG_FILTER_PLAYER, "Player %s tried to save equipment set " UI64FMTD " (index %u), but that equipment set not found!", GetName().c_str(), eqset.Guid, index);
return;
}
}
diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h
index bac794422be..fee542a752e 100644
--- a/src/server/game/Entities/Player/Player.h
+++ b/src/server/game/Entities/Player/Player.h
@@ -1506,10 +1506,11 @@ class Player : public Unit, public GridObject<Player>
size_t GetRewardedQuestCount() const { return m_RewardedQuests.size(); }
bool IsQuestRewarded(uint32 quest_id) const;
- uint64 GetSelection() const { return m_curSelection; }
Unit* GetSelectedUnit() const;
Player* GetSelectedPlayer() const;
- void SetSelection(uint64 guid) { m_curSelection = guid; SetUInt64Value(UNIT_FIELD_TARGET, guid); }
+
+ void SetTarget(uint64 /*guid*/) OVERRIDE { } /// Used for serverside target changes, does not apply to players
+ void SetSelection(uint64 guid) { SetUInt64Value(UNIT_FIELD_TARGET, guid); }
uint8 GetComboPoints() const { return m_comboPoints; }
uint64 GetComboTarget() const { return m_comboTarget; }
@@ -2424,7 +2425,6 @@ class Player : public Unit, public GridObject<Player>
bool m_itemUpdateQueueBlocked;
uint32 m_ExtraFlags;
- uint64 m_curSelection;
uint64 m_comboTarget;
int8 m_comboPoints;
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index 2a2a18eb609..0617dec179d 100644
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -259,7 +259,6 @@ Unit::Unit(bool isWorldObject) :
m_serverSideVisibility.SetValue(SERVERSIDE_VISIBILITY_GHOST, GHOST_VISIBILITY_ALIVE);
- _focusSpell = NULL;
_lastLiquid = NULL;
_isWalkingBeforeCharm = false;
}
@@ -568,6 +567,9 @@ uint32 Unit::DealDamage(Unit* victim, uint32 damage, CleanDamage const* cleanDam
if (IsAIEnabled)
GetAI()->DamageDealt(victim, damage, damagetype);
+ // Hook for OnDamage Event
+ sScriptMgr->OnDamage(this, victim, damage);
+
if (victim->GetTypeId() == TYPEID_PLAYER && this != victim)
{
// Signal to pets that their owner was attacked
@@ -5249,18 +5251,19 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere
// cast 45429 Arcane Bolt if Exalted by Scryers
case 45481:
{
- if (GetTypeId() != TYPEID_PLAYER)
+ Player* player = ToPlayer();
+ if (!player)
return false;
// Get Aldor reputation rank
- if (ToPlayer()->GetReputationRank(932) == REP_EXALTED)
+ if (player->GetReputationRank(932) == REP_EXALTED)
{
target = this;
triggered_spell_id = 45479;
break;
}
// Get Scryers reputation rank
- if (ToPlayer()->GetReputationRank(934) == REP_EXALTED)
+ if (player->GetReputationRank(934) == REP_EXALTED)
{
// triggered at positive/self casts also, current attack target used then
if (target && IsFriendlyTo(target))
@@ -5268,8 +5271,7 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere
target = GetVictim();
if (!target)
{
- uint64 selected_guid = ToPlayer()->GetSelection();
- target = ObjectAccessor::GetUnit(*this, selected_guid);
+ target = player->GetSelectedUnit();
if (!target)
return false;
}
@@ -9579,6 +9581,9 @@ int32 Unit::DealHeal(Unit* victim, uint32 addhealth)
if (addhealth)
gain = victim->ModifyHealth(int32(addhealth));
+ // Hook for OnHeal Event
+ sScriptMgr->OnHeal(this, victim, gain);
+
Unit* unit = this;
if (GetTypeId() == TYPEID_UNIT && ToCreature()->IsTotem())
@@ -15872,7 +15877,7 @@ void Unit::RemoveCharmedBy(Unit* charmer)
if (GetCharmInfo())
GetCharmInfo()->SetPetNumber(0, true);
else
- TC_LOG_ERROR(LOG_FILTER_UNITS, "Aura::HandleModCharm: target="UI64FMTD" with typeid=%d has a charm aura but no charm info!", GetGUID(), GetTypeId());
+ TC_LOG_ERROR(LOG_FILTER_UNITS, "Aura::HandleModCharm: target=" UI64FMTD " with typeid=%d has a charm aura but no charm info!", GetGUID(), GetTypeId());
}
}
break;
@@ -16895,7 +16900,7 @@ void Unit::_ExitVehicle(Position const* exitPosition)
if (vehicle->GetBase()->HasUnitTypeMask(UNIT_MASK_MINION) && vehicle->GetBase()->GetTypeId() == TYPEID_UNIT)
if (((Minion*)vehicle->GetBase())->GetOwner() == this)
- vehicle->GetBase()->ToCreature()->DespawnOrUnsummon();
+ vehicle->GetBase()->ToCreature()->DespawnOrUnsummon(1);
if (HasUnitTypeMask(UNIT_MASK_ACCESSORY))
{
@@ -17176,8 +17181,8 @@ void Unit::StopAttackFaction(uint32 faction_id)
void Unit::OutDebugInfo() const
{
TC_LOG_ERROR(LOG_FILTER_UNITS, "Unit::OutDebugInfo");
- TC_LOG_INFO(LOG_FILTER_UNITS, "GUID "UI64FMTD", entry %u, type %u, name %s", GetGUID(), GetEntry(), (uint32)GetTypeId(), GetName().c_str());
- TC_LOG_INFO(LOG_FILTER_UNITS, "OwnerGUID "UI64FMTD", MinionGUID "UI64FMTD", CharmerGUID "UI64FMTD", CharmedGUID "UI64FMTD, GetOwnerGUID(), GetMinionGUID(), GetCharmerGUID(), GetCharmGUID());
+ TC_LOG_INFO(LOG_FILTER_UNITS, "GUID " UI64FMTD ", entry %u, type %u, name %s", GetGUID(), GetEntry(), (uint32)GetTypeId(), GetName().c_str());
+ TC_LOG_INFO(LOG_FILTER_UNITS, "OwnerGUID " UI64FMTD ", MinionGUID " UI64FMTD ", CharmerGUID " UI64FMTD ", CharmedGUID "UI64FMTD, GetOwnerGUID(), GetMinionGUID(), GetCharmerGUID(), GetCharmGUID());
TC_LOG_INFO(LOG_FILTER_UNITS, "In world %u, unit type mask %u", (uint32)(IsInWorld() ? 1 : 0), m_unitTypeMask);
if (IsInWorld())
TC_LOG_INFO(LOG_FILTER_UNITS, "Mapid %u", GetMapId());
@@ -17462,43 +17467,6 @@ bool Unit::SetHover(bool enable, bool /*packetOnly = false*/)
return true;
}
-void Unit::SetTarget(uint64 guid)
-{
- if (!_focusSpell)
- SetUInt64Value(UNIT_FIELD_TARGET, guid);
-}
-
-void Unit::FocusTarget(Spell const* focusSpell, WorldObject const* target)
-{
- // already focused
- if (_focusSpell)
- return;
-
- _focusSpell = focusSpell;
- SetUInt64Value(UNIT_FIELD_TARGET, target->GetGUID());
- if (focusSpell->GetSpellInfo()->AttributesEx5 & SPELL_ATTR5_DONT_TURN_DURING_CAST)
- AddUnitState(UNIT_STATE_ROTATING);
-
- // Set serverside orientation if needed (needs to be after attribute check)
- SetInFront(target);
-}
-
-void Unit::ReleaseFocus(Spell const* focusSpell)
-{
- // focused to something else
- if (focusSpell != _focusSpell)
- return;
-
- _focusSpell = NULL;
- if (Unit* victim = GetVictim())
- SetUInt64Value(UNIT_FIELD_TARGET, victim->GetGUID());
- else
- SetUInt64Value(UNIT_FIELD_TARGET, 0);
-
- if (focusSpell->GetSpellInfo()->AttributesEx5 & SPELL_ATTR5_DONT_TURN_DURING_CAST)
- ClearUnitState(UNIT_STATE_ROTATING);
-}
-
void Unit::BuildValuesUpdate(uint8 updateType, ByteBuffer* data, Player* target) const
{
if (!target)
diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h
index 119a1dd1966..13f8c8e781f 100644
--- a/src/server/game/Entities/Unit/Unit.h
+++ b/src/server/game/Entities/Unit/Unit.h
@@ -2124,11 +2124,8 @@ class Unit : public WorldObject
TempSummon* ToTempSummon() { if (IsSummon()) return reinterpret_cast<TempSummon*>(this); else return NULL; }
TempSummon const* ToTempSummon() const { if (IsSummon()) return reinterpret_cast<TempSummon const*>(this); else return NULL; }
- void SetTarget(uint64 guid);
-
- // Handling caster facing during spellcast
- void FocusTarget(Spell const* focusSpell, WorldObject const* target);
- void ReleaseFocus(Spell const* focusSpell);
+ uint64 GetTarget() const { return GetUInt64Value(UNIT_FIELD_TARGET); }
+ virtual void SetTarget(uint64 /*guid*/) = 0;
// Movement info
Movement::MoveSpline * movespline;
@@ -2253,7 +2250,6 @@ class Unit : public WorldObject
bool m_cleanupDone; // lock made to not add stuff after cleanup before delete
bool m_duringRemoveFromWorld; // lock made to not add stuff after begining removing from world
- Spell const* _focusSpell; ///> Locks the target during spell cast for proper facing
bool _isWalkingBeforeCharm; // Are we walking before we were charmed?
time_t _lastDamagedTime; // Part of Evade mechanics
diff --git a/src/server/game/Grids/Notifiers/GridNotifiers.h b/src/server/game/Grids/Notifiers/GridNotifiers.h
index 637e0792a74..d0df63155b2 100644
--- a/src/server/game/Grids/Notifiers/GridNotifiers.h
+++ b/src/server/game/Grids/Notifiers/GridNotifiers.h
@@ -871,10 +871,10 @@ namespace Trinity
class AnyFriendlyUnitInObjectRangeCheck
{
public:
- AnyFriendlyUnitInObjectRangeCheck(WorldObject const* obj, Unit const* funit, float range) : i_obj(obj), i_funit(funit), i_range(range) {}
+ AnyFriendlyUnitInObjectRangeCheck(WorldObject const* obj, Unit const* funit, float range, bool playerOnly = false) : i_obj(obj), i_funit(funit), i_range(range), i_playerOnly(playerOnly) {}
bool operator()(Unit* u)
{
- if (u->IsAlive() && i_obj->IsWithinDistInMap(u, i_range) && i_funit->IsFriendlyTo(u))
+ if (u->IsAlive() && i_obj->IsWithinDistInMap(u, i_range) && i_funit->IsFriendlyTo(u) && (!i_playerOnly || u->GetTypeId() == TYPEID_PLAYER))
return true;
else
return false;
@@ -883,6 +883,7 @@ namespace Trinity
WorldObject const* i_obj;
Unit const* i_funit;
float i_range;
+ bool i_playerOnly;
};
class AnyGroupedUnitInObjectRangeCheck
@@ -1035,7 +1036,7 @@ namespace Trinity
class NearestHostileUnitCheck
{
public:
- explicit NearestHostileUnitCheck(Creature const* creature, float dist = 0) : me(creature)
+ explicit NearestHostileUnitCheck(Creature const* creature, float dist = 0, bool playerOnly = false) : me(creature), i_playerOnly(playerOnly)
{
m_range = (dist == 0 ? 9999 : dist);
}
@@ -1047,6 +1048,9 @@ namespace Trinity
if (!me->IsValidAttackTarget(u))
return false;
+ if (i_playerOnly && u->GetTypeId() != TYPEID_PLAYER)
+ return false;
+
m_range = me->GetDistance(u); // use found unit range as new range limit for next check
return true;
}
@@ -1054,6 +1058,7 @@ namespace Trinity
private:
Creature const* me;
float m_range;
+ bool i_playerOnly;
NearestHostileUnitCheck(NearestHostileUnitCheck const&);
};
diff --git a/src/server/game/Handlers/CalendarHandler.cpp b/src/server/game/Handlers/CalendarHandler.cpp
index b47e085ab6c..c1756311bc1 100644
--- a/src/server/game/Handlers/CalendarHandler.cpp
+++ b/src/server/game/Handlers/CalendarHandler.cpp
@@ -485,7 +485,7 @@ void WorldSession::HandleCalendarEventRsvp(WorldPacket& recvData)
uint32 status;
recvData >> eventId >> inviteId >> status;
- TC_LOG_DEBUG(LOG_FILTER_NETWORKIO, "CMSG_CALENDAR_EVENT_RSVP [" UI64FMTD"] EventId ["
+ TC_LOG_DEBUG(LOG_FILTER_NETWORKIO, "CMSG_CALENDAR_EVENT_RSVP [" UI64FMTD "] EventId ["
UI64FMTD "], InviteId [" UI64FMTD "], status %u", guid, eventId,
inviteId, status);
diff --git a/src/server/game/Handlers/MiscHandler.cpp b/src/server/game/Handlers/MiscHandler.cpp
index f65641eaa76..71453581ed0 100644
--- a/src/server/game/Handlers/MiscHandler.cpp
+++ b/src/server/game/Handlers/MiscHandler.cpp
@@ -1167,8 +1167,6 @@ void WorldSession::HandleInspectOpcode(WorldPacket& recvData)
TC_LOG_DEBUG(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_INSPECT");
- _player->SetSelection(guid);
-
Player* player = ObjectAccessor::FindPlayer(guid);
if (!player)
{
diff --git a/src/server/game/Handlers/QueryHandler.cpp b/src/server/game/Handlers/QueryHandler.cpp
index 5a94d5b391b..4638e05ee3d 100644
--- a/src/server/game/Handlers/QueryHandler.cpp
+++ b/src/server/game/Handlers/QueryHandler.cpp
@@ -267,7 +267,6 @@ void WorldSession::HandleNpcTextQueryOpcode(WorldPacket& recvData)
TC_LOG_DEBUG(LOG_FILTER_NETWORKIO, "WORLD: CMSG_NPC_TEXT_QUERY ID '%u'", textID);
recvData >> guid;
- GetPlayer()->SetSelection(guid);
GossipText const* pGossip = sObjectMgr->GetGossipText(textID);
diff --git a/src/server/game/Handlers/VehicleHandler.cpp b/src/server/game/Handlers/VehicleHandler.cpp
index c44d8a2d38e..b099ba96060 100644
--- a/src/server/game/Handlers/VehicleHandler.cpp
+++ b/src/server/game/Handlers/VehicleHandler.cpp
@@ -206,7 +206,7 @@ void WorldSession::HandleEjectPassenger(WorldPacket &data)
TC_LOG_ERROR(LOG_FILTER_NETWORKIO, "Player %u attempted to eject creature GUID %u from non-ejectable seat.", GetPlayer()->GetGUIDLow(), GUID_LOPART(guid));
}
else
- TC_LOG_ERROR(LOG_FILTER_NETWORKIO, "HandleEjectPassenger: Player %u tried to eject invalid GUID "UI64FMTD, GetPlayer()->GetGUIDLow(), guid);
+ TC_LOG_ERROR(LOG_FILTER_NETWORKIO, "HandleEjectPassenger: Player %u tried to eject invalid GUID " UI64FMTD, GetPlayer()->GetGUIDLow(), guid);
}
void WorldSession::HandleRequestVehicleExit(WorldPacket& /*recvData*/)
diff --git a/src/server/game/Instances/InstanceSaveMgr.cpp b/src/server/game/Instances/InstanceSaveMgr.cpp
index 6370eda6568..d7ffb70ccfa 100644
--- a/src/server/game/Instances/InstanceSaveMgr.cpp
+++ b/src/server/game/Instances/InstanceSaveMgr.cpp
@@ -336,7 +336,7 @@ void InstanceSaveManager::LoadResetTimes()
InstResetTimeMapDiffType::iterator itr = instResetTime.find(instance);
if (itr != instResetTime.end() && itr->second.second != resettime)
{
- CharacterDatabase.DirectPExecute("UPDATE instance SET resettime = '"UI64FMTD"' WHERE id = '%u'", uint64(resettime), instance);
+ CharacterDatabase.DirectPExecute("UPDATE instance SET resettime = '" UI64FMTD "' WHERE id = '%u'", uint64(resettime), instance);
itr->second.second = resettime;
}
}
@@ -408,7 +408,7 @@ void InstanceSaveManager::LoadResetTimes()
// calculate the next reset time
t = (t / DAY) * DAY;
t += ((today - t) / period + 1) * period + diff;
- CharacterDatabase.DirectPExecute("UPDATE instance_reset SET resettime = '"UI64FMTD"' WHERE mapid = '%u' AND difficulty= '%u'", (uint64)t, mapid, difficulty);
+ CharacterDatabase.DirectPExecute("UPDATE instance_reset SET resettime = '" UI64FMTD "' WHERE mapid = '%u' AND difficulty= '%u'", (uint64)t, mapid, difficulty);
}
SetResetTimeFor(mapid, difficulty, t);
diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp
index 04c2c22c595..4660489004d 100644
--- a/src/server/game/Maps/Map.cpp
+++ b/src/server/game/Maps/Map.cpp
@@ -360,7 +360,7 @@ void Map::EnsureGridLoadedForActiveObject(const Cell &cell, WorldObject* object)
// refresh grid state & timer
if (grid->GetGridState() != GRID_STATE_ACTIVE)
{
- TC_LOG_DEBUG(LOG_FILTER_MAPS, "Active object "UI64FMTD" triggers loading of grid [%u, %u] on map %u", object->GetGUID(), cell.GridX(), cell.GridY(), GetId());
+ TC_LOG_DEBUG(LOG_FILTER_MAPS, "Active object " UI64FMTD " triggers loading of grid [%u, %u] on map %u", object->GetGUID(), cell.GridX(), cell.GridY(), GetId());
ResetGridExpiry(*grid, 0.1f);
grid->SetGridState(GRID_STATE_ACTIVE);
}
diff --git a/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp
index 8056d6263c0..6311e629641 100755
--- a/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp
+++ b/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp
@@ -78,7 +78,7 @@ void WaypointMovementGenerator<Creature>::OnArrived(Creature* creature)
if (i_path->at(i_currentNode)->event_id && urand(0, 99) < i_path->at(i_currentNode)->event_chance)
{
- TC_LOG_DEBUG(LOG_FILTER_MAPSCRIPTS, "Creature movement start script %u at point %u for "UI64FMTD".", i_path->at(i_currentNode)->event_id, i_currentNode, creature->GetGUID());
+ TC_LOG_DEBUG(LOG_FILTER_MAPSCRIPTS, "Creature movement start script %u at point %u for " UI64FMTD ".", i_path->at(i_currentNode)->event_id, i_currentNode, creature->GetGUID());
creature->GetMap()->ScriptsStart(sWaypointScripts, i_path->at(i_currentNode)->event_id, creature, NULL);
}
diff --git a/src/server/game/Scripting/ScriptMgr.cpp b/src/server/game/Scripting/ScriptMgr.cpp
index 966b3edfcb9..fb96c327b05 100644
--- a/src/server/game/Scripting/ScriptMgr.cpp
+++ b/src/server/game/Scripting/ScriptMgr.cpp
@@ -1363,6 +1363,16 @@ void ScriptMgr::OnGroupDisband(Group* group)
}
// Unit
+void ScriptMgr::OnHeal(Unit* healer, Unit* reciever, uint32 gain)
+{
+ FOREACH_SCRIPT(UnitScript)->OnHeal(healer, reciever, gain);
+}
+
+void ScriptMgr::OnDamage(Unit* attacker, Unit* victim, uint32 damage)
+{
+ FOREACH_SCRIPT(UnitScript)->OnDamage(attacker, victim, damage);
+}
+
void ScriptMgr::ModifyPeriodicDamageAurasTick(Unit* target, Unit* attacker, uint32& damage)
{
FOREACH_SCRIPT(UnitScript)->ModifyPeriodicDamageAurasTick(target, attacker, damage);
diff --git a/src/server/game/Scripting/ScriptMgr.h b/src/server/game/Scripting/ScriptMgr.h
index e7946501616..a3eff880bb9 100644
--- a/src/server/game/Scripting/ScriptMgr.h
+++ b/src/server/game/Scripting/ScriptMgr.h
@@ -396,6 +396,12 @@ class UnitScript : public ScriptObject
UnitScript(const char* name, bool addToScripts = true);
public:
+ // Called when a unit deals damage to another unit
+ virtual void OnHeal(Unit* /*healer*/, Unit* /*reciever*/, uint32 /*gain*/) { }
+
+ // Called when a unit deals damage to another unit
+ virtual void OnDamage(Unit* /*attacker*/, Unit* /*victim*/, uint32 /*damage*/) { }
+
// Called when DoT's Tick Damage is being Dealt
virtual void ModifyPeriodicDamageAurasTick(Unit* /*target*/, Unit* /*attacker*/, uint32& /*damage*/) { }
@@ -1054,6 +1060,8 @@ class ScriptMgr
public: /* UnitScript */
+ void OnHeal(Unit* healer, Unit* reciever, uint32 gain);
+ void OnDamage(Unit* attacker, Unit* victim, uint32 damage);
void ModifyPeriodicDamageAurasTick(Unit* target, Unit* attacker, uint32& damage);
void ModifyMeleeDamage(Unit* target, Unit* attacker, uint32& damage);
void ModifySpellDamageTaken(Unit* target, Unit* attacker, int32& damage);
diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp
index 866cd888c3e..2eee80924a4 100644
--- a/src/server/game/Spells/Spell.cpp
+++ b/src/server/game/Spells/Spell.cpp
@@ -643,7 +643,7 @@ void Spell::InitExplicitTargets(SpellCastTargets const& targets)
if (Player* playerCaster = m_caster->ToPlayer())
{
// selection has to be found and to be valid target for the spell
- if (Unit* selectedUnit = ObjectAccessor::GetUnit(*m_caster, playerCaster->GetSelection()))
+ if (Unit* selectedUnit = ObjectAccessor::GetUnit(*m_caster, playerCaster->GetTarget()))
if (m_spellInfo->CheckExplicitTarget(m_caster, selectedUnit) == SPELL_CAST_OK)
unit = selectedUnit;
}
@@ -1777,9 +1777,9 @@ void Spell::SelectEffectTypeImplicitTargets(uint8 effIndex)
{
case SPELL_EFFECT_SUMMON_RAF_FRIEND:
case SPELL_EFFECT_SUMMON_PLAYER:
- if (m_caster->GetTypeId() == TYPEID_PLAYER && m_caster->ToPlayer()->GetSelection())
+ if (m_caster->GetTypeId() == TYPEID_PLAYER && m_caster->GetTarget())
{
- WorldObject* target = ObjectAccessor::FindPlayer(m_caster->ToPlayer()->GetSelection());
+ WorldObject* target = ObjectAccessor::FindPlayer(m_caster->GetTarget());
CallScriptObjectTargetSelectHandlers(target, SpellEffIndex(effIndex));
@@ -3095,7 +3095,7 @@ void Spell::prepare(SpellCastTargets const* targets, AuraEffect const* triggered
// set target for proper facing
if ((m_casttime || m_spellInfo->IsChanneled()) && !(_triggeredCastFlags & TRIGGERED_IGNORE_SET_FACING))
if (m_caster->GetTypeId() == TYPEID_UNIT && m_targets.GetObjectTarget() && m_caster != m_targets.GetObjectTarget())
- m_caster->FocusTarget(this, m_targets.GetObjectTarget());
+ m_caster->ToCreature()->FocusTarget(this, m_targets.GetObjectTarget());
if (!(_triggeredCastFlags & TRIGGERED_IGNORE_GCD))
TriggerGlobalCooldown();
@@ -3661,8 +3661,8 @@ void Spell::finish(bool ok)
((Puppet*)charm)->UnSummon();
}
- if (m_caster->GetTypeId() == TYPEID_UNIT)
- m_caster->ReleaseFocus(this);
+ if (Creature* creatureCaster = m_caster->ToCreature())
+ creatureCaster->ReleaseFocus(this);
if (!ok)
return;
@@ -5323,10 +5323,10 @@ SpellCastResult Spell::CheckCast(bool strict)
{
if (m_caster->GetTypeId() != TYPEID_PLAYER)
return SPELL_FAILED_BAD_TARGETS;
- if (!m_caster->ToPlayer()->GetSelection())
+ if (!m_caster->GetTarget())
return SPELL_FAILED_BAD_TARGETS;
- Player* target = ObjectAccessor::FindPlayer(m_caster->ToPlayer()->GetSelection());
+ Player* target = ObjectAccessor::FindPlayer(m_caster->ToPlayer()->GetTarget());
if (!target || m_caster->ToPlayer() == target || (!target->IsInSameRaidWith(m_caster->ToPlayer()) && m_spellInfo->Id != 48955)) // refer-a-friend spell
return SPELL_FAILED_BAD_TARGETS;
@@ -5358,10 +5358,10 @@ SpellCastResult Spell::CheckCast(bool strict)
Player* playerCaster = m_caster->ToPlayer();
//
- if (!(playerCaster->GetSelection()))
+ if (!(playerCaster->GetTarget()))
return SPELL_FAILED_BAD_TARGETS;
- Player* target = ObjectAccessor::FindPlayer(playerCaster->GetSelection());
+ Player* target = playerCaster->GetSelectedPlayer();
if (!target ||
!(target->GetSession()->GetRecruiterId() == playerCaster->GetSession()->GetAccountId() || target->GetSession()->GetAccountId() == playerCaster->GetSession()->GetRecruiterId()))
diff --git a/src/server/scripts/Commands/cs_account.cpp b/src/server/scripts/Commands/cs_account.cpp
index 332169ebd00..45ab88e9688 100644
--- a/src/server/scripts/Commands/cs_account.cpp
+++ b/src/server/scripts/Commands/cs_account.cpp
@@ -450,12 +450,12 @@ public:
uint32 pwConfig = sWorld->getIntConfig(CONFIG_ACC_PASSCHANGESEC); // 0 - PW_NONE, 1 - PW_EMAIL, 2 - PW_RBAC
// Command is supposed to be: .account password [$oldpassword] [$newpassword] [$newpasswordconfirmation] [$emailconfirmation]
- char* oldPassword = strtok((char*)args, " "); // This extracts [$oldpassword]
- char* newPassword = strtok(NULL, " "); // This extracts [$newpassword]
- char* passwordConfirmation = strtok(NULL, " "); // This extracts [$newpasswordconfirmation]
- const char* emailConfirmation; // This defines the emailConfirmation variable, which is optional depending on sec type.
- if (!(emailConfirmation = strtok(NULL, " "))) // This extracts [$emailconfirmation]. If it doesn't exist, however...
- emailConfirmation = ""; // ... it's simply "" for emailConfirmation.
+ char* oldPassword = strtok((char*)args, " "); // This extracts [$oldpassword]
+ char* newPassword = strtok(NULL, " "); // This extracts [$newpassword]
+ char* passwordConfirmation = strtok(NULL, " "); // This extracts [$newpasswordconfirmation]
+ char const* emailConfirmation = strtok(NULL, " "); // This defines the emailConfirmation variable, which is optional depending on sec type.
+ if (!emailConfirmation) // This extracts [$emailconfirmation]. If it doesn't exist, however...
+ emailConfirmation = ""; // ... it's simply "" for emailConfirmation.
//Is any of those variables missing for any reason ? We return false.
if (!oldPassword || !newPassword || !passwordConfirmation)
diff --git a/src/server/scripts/Commands/cs_debug.cpp b/src/server/scripts/Commands/cs_debug.cpp
index 6c831520d59..199b1e43f6c 100644
--- a/src/server/scripts/Commands/cs_debug.cpp
+++ b/src/server/scripts/Commands/cs_debug.cpp
@@ -179,7 +179,7 @@ public:
return false;
}
- if (handler->GetSession()->GetPlayer()->GetSelection())
+ if (handler->GetSession()->GetPlayer()->GetTarget())
unit->PlayDistanceSound(soundId, handler->GetSession()->GetPlayer());
else
unit->PlayDirectSound(soundId, handler->GetSession()->GetPlayer());
diff --git a/src/server/scripts/Commands/cs_misc.cpp b/src/server/scripts/Commands/cs_misc.cpp
index 513d378287b..3d531cee1f5 100644
--- a/src/server/scripts/Commands/cs_misc.cpp
+++ b/src/server/scripts/Commands/cs_misc.cpp
@@ -529,7 +529,7 @@ public:
{
Unit* target = handler->getSelectedUnit();
- if (!target || !handler->GetSession()->GetPlayer()->GetSelection())
+ if (!target || !handler->GetSession()->GetPlayer()->GetTarget())
{
handler->SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
handler->SetSentErrorMessage(true);
@@ -597,7 +597,7 @@ public:
static bool HandleGUIDCommand(ChatHandler* handler, char const* /*args*/)
{
- uint64 guid = handler->GetSession()->GetPlayer()->GetSelection();
+ uint64 guid = handler->GetSession()->GetPlayer()->GetTarget();
if (guid == 0)
{
@@ -1762,7 +1762,7 @@ public:
// accept only explicitly selected target (not implicitly self targeting case)
Unit* target = handler->getSelectedUnit();
- if (player->GetSelection() && target)
+ if (player->GetTarget() && target)
{
if (target->GetTypeId() != TYPEID_UNIT || target->IsPet())
{
@@ -2107,7 +2107,7 @@ public:
}
Unit* target = handler->getSelectedUnit();
- if (!target || !handler->GetSession()->GetPlayer()->GetSelection())
+ if (!target || !handler->GetSession()->GetPlayer()->GetTarget())
{
handler->SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
handler->SetSentErrorMessage(true);
diff --git a/src/server/scripts/Commands/cs_npc.cpp b/src/server/scripts/Commands/cs_npc.cpp
index f10a929c675..1cedeb79c22 100644
--- a/src/server/scripts/Commands/cs_npc.cpp
+++ b/src/server/scripts/Commands/cs_npc.cpp
@@ -1297,22 +1297,17 @@ public:
char* receiver_str = strtok((char*)args, " ");
char* text = strtok(NULL, "");
- uint64 guid = handler->GetSession()->GetPlayer()->GetSelection();
- Creature* creature = handler->GetSession()->GetPlayer()->GetMap()->GetCreature(guid);
-
+ Creature* creature = handler->getSelectedCreature();
if (!creature || !receiver_str || !text)
- {
return false;
- }
- uint64 receiver_guid= atol(receiver_str);
+ uint64 receiver_guid = atol(receiver_str);
// check online security
if (handler->HasLowerSecurity(ObjectAccessor::FindPlayer(receiver_guid), 0))
return false;
creature->MonsterWhisper(text, receiver_guid);
-
return true;
}
diff --git a/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.cpp b/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.cpp
index 987807c2080..9a9dfa60521 100644
--- a/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.cpp
+++ b/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.cpp
@@ -1069,7 +1069,7 @@ class npc_jaina_or_sylvanas_escape_hor : public CreatureScript
{
me->AI()->DoCast(me, SPELL_SYLVANAS_DESTROY_ICE_WALL, false);
if (_isattackingwall)
- _events.ScheduleEvent(EVENT_ESCAPE_22, 1000);
+ _events.ScheduleEvent(EVENT_ESCAPE_23, 1000);
}
break;
diff --git a/src/server/shared/Database/MySQLThreading.h b/src/server/shared/Database/MySQLThreading.h
index 3dc2add8132..4fe928dcc22 100644
--- a/src/server/shared/Database/MySQLThreading.h
+++ b/src/server/shared/Database/MySQLThreading.h
@@ -33,7 +33,7 @@ class MySQL
static void Thread_Init()
{
mysql_thread_init();
- TC_LOG_WARN(LOG_FILTER_SQL, "Core thread with ID ["UI64FMTD"] initializing MySQL thread.",
+ TC_LOG_WARN(LOG_FILTER_SQL, "Core thread with ID [" UI64FMTD "] initializing MySQL thread.",
(uint64)ACE_Based::Thread::currentId());
}
@@ -44,7 +44,7 @@ class MySQL
static void Thread_End()
{
mysql_thread_end();
- TC_LOG_WARN(LOG_FILTER_SQL, "Core thread with ID ["UI64FMTD"] shutting down MySQL thread.",
+ TC_LOG_WARN(LOG_FILTER_SQL, "Core thread with ID [" UI64FMTD "] shutting down MySQL thread.",
(uint64)ACE_Based::Thread::currentId());
}
diff --git a/src/tools/mesh_extractor/ContinentBuilder.cpp b/src/tools/mesh_extractor/ContinentBuilder.cpp
index 7708aa36617..c90a6e527f7 100644
--- a/src/tools/mesh_extractor/ContinentBuilder.cpp
+++ b/src/tools/mesh_extractor/ContinentBuilder.cpp
@@ -6,104 +6,59 @@
#include "Cache.h"
#include "ace/Task.h"
#include "Recast.h"
+#include "DetourCommon.h"
class BuilderThread : public ACE_Task_Base
{
private:
int X, Y, MapId;
- bool Instance;
std::string Continent;
dtNavMeshParams Params;
ContinentBuilder* cBuilder;
- WorldModelRoot* Model;
- const WorldModelDefinition* Definition;
public:
BuilderThread(ContinentBuilder* _cBuilder, dtNavMeshParams& params) : Params(params), cBuilder(_cBuilder), Free(true) {}
- void SetData(int x, int y, int map, const std::string& cont, bool instance, WorldModelRoot* model, const WorldModelDefinition* def)
+
+ void SetData(int x, int y, int map, const std::string& cont)
{
X = x;
Y = y;
MapId = map;
Continent = cont;
- Instance = instance;
- if (Instance)
- {
- Model = model;
- Definition = def;
- }
- else
- Model = NULL;
}
int svc()
{
- if (Instance)
+ Free = false;
+ printf("[%02i,%02i] Building tile\n", X, Y);
+ TileBuilder builder(cBuilder, Continent, X, Y, MapId);
+ char buff[100];
+ sprintf(buff, "mmaps/%03u%02i%02i.mmtile", MapId, Y, X);
+ FILE* f = fopen(buff, "r");
+ if (f) // Check if file already exists.
{
- // Build a WMO
- printf("Building WMO %s ( %u )", Continent.c_str(), MapId);
- TileBuilder builder(cBuilder, Continent, X, Y, MapId);
- char buff[100];
- sprintf(buff, "mmaps/%03u%02i%02i.mmtile", MapId, Y, X);
- FILE* f = fopen(buff, "r");
- if (f) // Check if file already exists.
- {
- printf("Instance %s ( %u ) skipped, file already exists\n", Continent.c_str(), MapId);
- fclose(f);
- return 0;
- }
-
- uint8* nav = builder.BuildInstance(Params, Model, *Definition);
- if (nav)
- {
- f = fopen(buff, "wb");
- if (!f)
- {
- printf("Could not create file %s. Check that you have write permissions to the destination folder and try again\n", buff);
- return 0;
- }
- MmapTileHeader header;
- header.size = builder.DataSize;
- fwrite(&header, sizeof(MmapTileHeader), 1, f);
- fwrite(nav, sizeof(unsigned char), builder.DataSize, f);
- fclose(f);
- }
- dtFree(nav);
+ printf("[%02i,%02i] Tile skipped, file already exists\n", X, Y);
+ fclose(f);
+ Free = true;
return 0;
}
- else
+ uint8* nav = builder.BuildTiled(Params);
+ if (nav)
{
- Free = false;
- printf("[%02i,%02i] Building tile\n", X, Y);
- TileBuilder builder(cBuilder, Continent, X, Y, MapId);
- char buff[100];
- sprintf(buff, "mmaps/%03u%02i%02i.mmtile", MapId, Y, X);
- FILE* f = fopen(buff, "r");
- if (f) // Check if file already exists.
+ f = fopen(buff, "wb");
+ if (!f)
{
- printf("[%02i,%02i] Tile skipped, file already exists\n", X, Y);
- fclose(f);
- Free = true;
+ printf("Could not create file %s. Check that you have write permissions to the destination folder and try again\n", buff);
return 0;
}
- uint8* nav = builder.Build(Params);
- if (nav)
- {
- f = fopen(buff, "wb");
- if (!f)
- {
- printf("Could not create file %s. Check that you have write permissions to the destination folder and try again\n", buff);
- return 0;
- }
- MmapTileHeader header;
- header.size = builder.DataSize;
- fwrite(&header, sizeof(MmapTileHeader), 1, f);
- fwrite(nav, sizeof(unsigned char), builder.DataSize, f);
- fclose(f);
- }
- dtFree(nav);
- printf("[%02i,%02i] Tile Built!\n", X, Y);
- Free = true;
+ MmapTileHeader header;
+ header.size = builder.DataSize;
+ fwrite(&header, sizeof(MmapTileHeader), 1, f);
+ fwrite(nav, sizeof(unsigned char), builder.DataSize, f);
+ fclose(f);
}
+ dtFree(nav);
+ printf("[%02i,%02i] Tile Built!\n", X, Y);
+ Free = true;
return 0;
}
@@ -155,26 +110,57 @@ void ContinentBuilder::Build()
CalculateTileBounds();
dtNavMeshParams params;
- params.maxPolys = 1 << STATIC_POLY_BITS;
- params.maxTiles = TileMap->TileTable.size();
- rcVcopy(params.orig, bmin);
- params.tileHeight = Constants::TileSize;
- params.tileWidth = Constants::TileSize;
- fwrite(&params, sizeof(dtNavMeshParams), 1, mmap);
- fclose(mmap);
+
std::vector<BuilderThread*> Threads;
if (TileMap->IsGlobalModel)
{
printf("Map %s ( %u ) is a WMO. Building with 1 thread.\n", Continent.c_str(), MapId);
- BuilderThread* thread = new BuilderThread(this, params);
- Threads.push_back(thread);
- thread->SetData(65, 65, MapId, Continent, true, TileMap->Model, &TileMap->ModelDefinition);
- thread->activate();
- thread->wait();
+
+ TileBuilder* builder = new TileBuilder(this, Continent, 0, 0, MapId);
+ builder->AddGeometry(TileMap->Model, TileMap->ModelDefinition);
+ uint8* nav = builder->BuildInstance(params);
+ if (nav)
+ {
+ // Set some params for the navmesh
+ dtMeshHeader* header = (dtMeshHeader*)nav;
+ dtVcopy(params.orig, header->bmin);
+ params.tileWidth = header->bmax[0] - header->bmin[0];
+ params.tileHeight = header->bmax[2] - header->bmin[2];
+ params.maxTiles = 1;
+ params.maxPolys = header->polyCount;
+ fwrite(&params, sizeof(dtNavMeshParams), 1, mmap);
+ fclose(mmap);
+
+ char buff[100];
+ sprintf(buff, "mmaps/%03u%02i%02i.mmtile", MapId, 0, 0);
+ FILE* f = fopen(buff, "wb");
+ if (!f)
+ {
+ printf("Could not create file %s. Check that you have write permissions to the destination folder and try again\n", buff);
+ return;
+ }
+
+ MmapTileHeader mheader;
+ mheader.size = builder->DataSize;
+ fwrite(&mheader, sizeof(MmapTileHeader), 1, f);
+ fwrite(nav, sizeof(unsigned char), builder->DataSize, f);
+ fclose(f);
+ }
+
+ dtFree(nav);
+ delete builder;
}
else
{
+ params.maxPolys = 32768;
+ params.maxTiles = 4096;
+ rcVcopy(params.orig, Constants::Origin);
+ params.tileHeight = Constants::TileSize;
+ params.tileWidth = Constants::TileSize;
+ fwrite(&params, sizeof(dtNavMeshParams), 1, mmap);
+ fclose(mmap);
+
for (uint32 i = 0; i < NumberOfThreads; ++i)
Threads.push_back(new BuilderThread(this, params));
printf("Map %s ( %u ) has %u tiles. Building them with %u threads\n", Continent.c_str(), MapId, uint32(TileMap->TileTable.size()), NumberOfThreads);
@@ -187,7 +173,7 @@ void ContinentBuilder::Build()
{
if ((*_th)->Free)
{
- (*_th)->SetData(itr->X, itr->Y, MapId, Continent, false, NULL, NULL);
+ (*_th)->SetData(itr->X, itr->Y, MapId, Continent);
(*_th)->activate();
next = true;
break;
diff --git a/src/tools/mesh_extractor/Geometry.cpp b/src/tools/mesh_extractor/Geometry.cpp
index 37f5c68bb6d..df828dcd573 100644
--- a/src/tools/mesh_extractor/Geometry.cpp
+++ b/src/tools/mesh_extractor/Geometry.cpp
@@ -17,7 +17,7 @@ void Geometry::CalculateBoundingBox( float*& min, float*& max )
max = new float[3];
for (int i = 0; i < 3; ++i)
{
- max[i] = std::numeric_limits<float>::min();
+ max[i] = std::numeric_limits<float>::lowest();
min[i] = std::numeric_limits<float>::max();
}
@@ -42,8 +42,8 @@ void Geometry::CalculateBoundingBox( float*& min, float*& max )
void Geometry::CalculateMinMaxHeight( float& min, float& max )
{
- min = 0.0f;
- max = 0.0f;
+ min = std::numeric_limits<float>::max();
+ max = std::numeric_limits<float>::lowest();
for (std::vector<Vector3>::iterator itr = Vertices.begin(); itr != Vertices.end(); ++itr)
{
diff --git a/src/tools/mesh_extractor/MPQ.h b/src/tools/mesh_extractor/MPQ.h
index 2f8b082f526..30e11741550 100644
--- a/src/tools/mesh_extractor/MPQ.h
+++ b/src/tools/mesh_extractor/MPQ.h
@@ -26,7 +26,8 @@ public:
libmpq__off_t size, transferred;
libmpq__file_unpacked_size(mpq_a, filenum, &size);
- char *buffer = new char[size];
+ char* buffer = new char[size + 1];
+ buffer[size] = '\0';
libmpq__file_read(mpq_a, filenum, (unsigned char*)buffer, size, &transferred);
diff --git a/src/tools/mesh_extractor/MPQManager.cpp b/src/tools/mesh_extractor/MPQManager.cpp
index 3c63aed97d0..4d3ab808a2e 100644
--- a/src/tools/mesh_extractor/MPQManager.cpp
+++ b/src/tools/mesh_extractor/MPQManager.cpp
@@ -23,7 +23,7 @@ void MPQManager::Initialize()
for (uint32 i = 0; i < size; ++i)
{
MPQArchive* arc = new MPQArchive(std::string("Data/" + std::string(Files[i])).c_str());
- Archives.push_front(arc);
+ Archives.push_front(arc); // MPQ files have to be transversed in reverse order to properly account for patched files
printf("Opened %s\n", Files[i]);
}
}
@@ -109,5 +109,7 @@ FILE* MPQManager::GetFileFrom(const std::string& path, MPQArchive* file )
exit(1);
}
fwrite(buffer, sizeof(uint8), size, ret);
+ fseek(ret, 0, SEEK_SET);
+ delete[] buffer;
return ret;
}
diff --git a/src/tools/mesh_extractor/MeshExtractor.cpp b/src/tools/mesh_extractor/MeshExtractor.cpp
index 4a312640395..0d9160a610b 100644
--- a/src/tools/mesh_extractor/MeshExtractor.cpp
+++ b/src/tools/mesh_extractor/MeshExtractor.cpp
@@ -76,7 +76,7 @@ void ExtractDBCs()
std::string component = "component.wow-" + std::string(MPQManager::Languages[*itr]) + ".txt";
// Extract the component file
- Utils::SaveToDisk(MPQHandler->GetFile(component), path + component);
+ Utils::SaveToDisk(MPQHandler->GetFileFrom(component, MPQHandler->LocaleFiles[*itr]), path + component);
// Extract the DBC files for the given locale
for (std::set<std::string>::iterator itr2 = DBCFiles.begin(); itr2 != DBCFiles.end(); ++itr2)
Utils::SaveToDisk(MPQHandler->GetFileFrom(*itr2, MPQHandler->LocaleFiles[*itr]), path + (itr2->c_str() + folderLen));
@@ -328,6 +328,8 @@ void PrintUsage()
void LoadTile(dtNavMesh*& navMesh, const char* tile)
{
FILE* f = fopen(tile, "rb");
+ if (!f)
+ return;
MmapTileHeader header;
if (fread(&header, sizeof(MmapTileHeader), 1, f) != 1)
@@ -376,37 +378,37 @@ int main(int argc, char* argv[])
if (extractFlags & Constants::EXTRACT_FLAG_TEST)
{
- float start[] = { 0.0f, 0.0f, 0.0f };
- float end[] = { 0.0f, 0.0f, 0.0f };
+ float start[] = { 16226.200195f, 16257.000000f, 13.202200f };
+ float end[] = { 16245.725586f, 16382.465820f, 47.384956f };
//
float m_spos[3];
- m_spos[0] = -1.0f * start[1];
+ m_spos[0] = -start[1];
m_spos[1] = start[2];
- m_spos[2] = -1.0f * start[0];
+ m_spos[2] = -start[0];
//
float m_epos[3];
- m_epos[0] = -1.0f * end[1];
+ m_epos[0] = -end[1];
m_epos[1] = end[2];
- m_epos[2] = -1.0f * end[0];
+ m_epos[2] = -end[0];
//
dtQueryFilter m_filter;
- m_filter.setIncludeFlags(0xffff);
- m_filter.setExcludeFlags(0);
+ m_filter.setIncludeFlags(Constants::POLY_AREA_ROAD | Constants::POLY_AREA_TERRAIN);
+ m_filter.setExcludeFlags(Constants::POLY_AREA_WATER);
//
float m_polyPickExt[3];
- m_polyPickExt[0] = 2;
- m_polyPickExt[1] = 4;
- m_polyPickExt[2] = 2;
+ m_polyPickExt[0] = 2.5f;
+ m_polyPickExt[1] = 2.5f;
+ m_polyPickExt[2] = 2.5f;
//
dtPolyRef m_startRef;
dtPolyRef m_endRef;
- FILE* mmap = fopen(".mmap", "rb");
+ FILE* mmap = fopen("mmaps/001.mmap", "rb");
dtNavMeshParams params;
int count = fread(&params, sizeof(dtNavMeshParams), 1, mmap);
fclose(mmap);
@@ -420,13 +422,16 @@ int main(int argc, char* argv[])
dtNavMeshQuery* navMeshQuery = new dtNavMeshQuery();
navMesh->init(&params);
- LoadTile(navMesh, ".mmtile");
- LoadTile(navMesh, ".mmtile");
- LoadTile(navMesh, ".mmtile");
- LoadTile(navMesh, ".mmtile");
- LoadTile(navMesh, ".mmtile");
- LoadTile(navMesh, ".mmtile");
-
+ for (int i = 0; i <= 32; ++i)
+ {
+ for (int j = 0; j <= 32; ++j)
+ {
+ char buff[100];
+ sprintf(buff, "mmaps/001%02i%02i.mmtile", i, j);
+ LoadTile(navMesh, buff);
+ }
+ }
+
navMeshQuery->init(navMesh, 2048);
float nearestPt[3];
@@ -440,7 +445,24 @@ int main(int argc, char* argv[])
return 0;
}
- printf("Found!");
+ int hops;
+ dtPolyRef* hopBuffer = new dtPolyRef[8192];
+ dtStatus status = navMeshQuery->findPath(m_startRef, m_endRef, m_spos, m_epos, &m_filter, hopBuffer, &hops, 8192);
+
+ int resultHopCount;
+ float* straightPath = new float[2048*3];
+ unsigned char* pathFlags = new unsigned char[2048];
+ dtPolyRef* pathRefs = new dtPolyRef[2048];
+
+ status = navMeshQuery->findStraightPath(m_spos, m_epos, hopBuffer, hops, straightPath, pathFlags, pathRefs, &resultHopCount, 2048);
+ std::vector<Vector3> FinalPath;
+ FinalPath.reserve(resultHopCount);
+ for (uint32 i = 0; i < resultHopCount; ++i)
+ {
+ Vector3 finalV = Utils::ToWoWCoords(Vector3(straightPath[i * 3 + 0], straightPath[i * 3 + 1], straightPath[i * 3 + 2]));
+ FinalPath.push_back(finalV);
+ printf("Point %f %f %f\n", finalV.x, finalV.y, finalV.z);
+ }
}
return 0;
diff --git a/src/tools/mesh_extractor/TileBuilder.cpp b/src/tools/mesh_extractor/TileBuilder.cpp
index 857cf7f16d8..51df91d2652 100644
--- a/src/tools/mesh_extractor/TileBuilder.cpp
+++ b/src/tools/mesh_extractor/TileBuilder.cpp
@@ -16,51 +16,25 @@
TileBuilder::TileBuilder(ContinentBuilder* _cBuilder, std::string world, int x, int y, uint32 mapId) :
World(world), X(x), Y(y), MapId(mapId), _Geometry(NULL), DataSize(0), cBuilder(_cBuilder)
{
- /*
- Test, non-working values
- // Cell Size = TileSize / TileVoxelSize
- // 1800 = TileVoxelSize
- Config.cs = Constants::TileSize / 1800;
- // Cell Height
- Config.ch = 0.4f;
- // Min Region Area = 20^2
- Config.minRegionArea = 20*20;
- // Merge Region Area = 40^2
- Config.mergeRegionArea = 40*40;
- Config.tileSize = Constants::TileSize / 4;
+ // Config for normal maps
+ memset(&Config, 0, sizeof(rcConfig));
+ Config.cs = Constants::TileSize / 1800.0f; // TileSize / voxelSize
+ Config.ch = 0.3f;
+ Config.minRegionArea = 36;
+ Config.mergeRegionArea = 144;
Config.walkableSlopeAngle = 50.0f;
Config.detailSampleDist = 3.0f;
Config.detailSampleMaxError = 1.25f;
- Config.walkableClimb = floorf(1.0f / Config.ch);
- Config.walkableHeight = ceilf(1.652778f / Config.ch);
- Config.walkableRadius = ceilf(0.2951389f / Config.cs);
+ Config.walkableClimb = 1.0f / Config.ch;
+ Config.walkableHeight = 2.1 / Config.ch;
+ Config.walkableRadius = 0.6f / Config.cs;
Config.maxEdgeLen = Config.walkableRadius * 8;
- Config.borderSize = Config.walkableRadius + 4;
- Config.width = 1800 + Config.borderSize * 2;
- Config.height = 1800 + Config.borderSize * 2;
- Config.maxVertsPerPoly = 6;
+ Config.borderSize = Config.walkableRadius + 8;
+ Config.tileSize = 1800;
Config.maxSimplificationError = 1.3f;
- */
-
- // All are in UNIT metrics!
- memset(&Config, 0, sizeof(rcConfig));
-
- Config.maxVertsPerPoly = DT_VERTS_PER_POLYGON;
- Config.cs = Constants::BaseUnitDim;
- Config.ch = Constants::BaseUnitDim;
- Config.walkableSlopeAngle = 60.0f;
- Config.tileSize = Constants::VertexPerTile;
- Config.walkableRadius = 1;
- Config.borderSize = Config.walkableRadius + 3;
- Config.maxEdgeLen = Constants::VertexPerTile + 1; //anything bigger than tileSize
- Config.walkableHeight = 3;
- Config.walkableClimb = 2; // keep less than walkableHeight
- Config.minRegionArea = rcSqr(60);
- Config.mergeRegionArea = rcSqr(50);
- Config.maxSimplificationError = 2.0f; // eliminates most jagged edges (tinny polygons)
- Config.detailSampleDist = Config.cs * 64;
- Config.detailSampleMaxError = Config.ch * 2;
+ Config.maxVertsPerPoly = 6;
+ // Config for instances
memset(&InstanceConfig, 0, sizeof(rcConfig));
InstanceConfig.cs = 0.2f;
InstanceConfig.ch = 0.3f;
@@ -90,33 +64,22 @@ void TileBuilder::CalculateTileBounds( float*& bmin, float*& bmax, dtNavMeshPara
bmax[2] = Constants::Origin[2] /*navMeshParams.orig[2]*/ + (Constants::TileSize * (Y + 1));
}
-uint8* TileBuilder::BuildInstance( dtNavMeshParams& navMeshParams, WorldModelRoot* root, const WorldModelDefinition& def )
+void TileBuilder::AddGeometry(WorldModelRoot* root, const WorldModelDefinition& def)
{
_Geometry = new Geometry();
_Geometry->Transform = true;
- WorldModelHandler::InsertModelGeometry(_Geometry->Vertices, _Geometry->Triangles, def, root);
+ WorldModelHandler::InsertModelGeometry(_Geometry->Vertices, _Geometry->Triangles, def, root, false);
- if (Constants::Debug)
- {
- char buff[100];
- sprintf(buff, "mmaps/%s_%02u%02u.obj", World.c_str(), Y, X);
- FILE* debug = fopen(buff, "wb");
- for (uint32 i = 0; i < _Geometry->Vertices.size(); ++i)
- {
- const Vector3& vector = _Geometry->Vertices[i];
- fprintf(debug, "v %f %f %f\n", vector.x, vector.y, vector.z);
- }
- for (uint32 i = 0; i < _Geometry->Triangles.size(); ++i)
- {
- const Triangle<uint32>& triangle = _Geometry->Triangles[i];
- fprintf(debug, "f %u %u %u\n", triangle.V0 + 1, triangle.V1 + 1, triangle.V2 + 1);
- }
- fclose(debug);
- }
+ OutputDebugVertices();
+}
+
+uint8* TileBuilder::BuildInstance( dtNavMeshParams& navMeshParams )
+{
+ float* bmin = NULL, *bmax = NULL;
- float* bmin, *bmax;
_Geometry->CalculateBoundingBox(bmin, bmax);
+
rcVcopy(InstanceConfig.bmax, bmax);
rcVcopy(InstanceConfig.bmin, bmin);
@@ -126,14 +89,13 @@ uint8* TileBuilder::BuildInstance( dtNavMeshParams& navMeshParams, WorldModelRoo
int* triangles;
uint8* areas;
_Geometry->GetRawData(vertices, triangles, areas);
- _Geometry->Vertices.clear();
- _Geometry->Triangles.clear();
- // this sets the dimensions of the heightfield - should maybe happen before border padding
+ // this sets the dimensions of the heightfield
rcCalcGridSize(InstanceConfig.bmin, InstanceConfig.bmax, InstanceConfig.cs, &InstanceConfig.width, &InstanceConfig.height);
+
rcHeightfield* hf = rcAllocHeightfield();
rcCreateHeightfield(Context, *hf, InstanceConfig.width, InstanceConfig.height, InstanceConfig.bmin, InstanceConfig.bmax, InstanceConfig.cs, InstanceConfig.ch);
-
+
rcClearUnwalkableTriangles(Context, InstanceConfig.walkableSlopeAngle, vertices, numVerts, triangles, numTris, areas);
rcRasterizeTriangles(Context, vertices, numVerts, triangles, areas, numTris, *hf, InstanceConfig.walkableClimb);
@@ -190,9 +152,10 @@ uint8* TileBuilder::BuildInstance( dtNavMeshParams& navMeshParams, WorldModelRoo
params.walkableClimb = InstanceConfig.walkableClimb * InstanceConfig.ch;
params.walkableHeight = InstanceConfig.walkableHeight * InstanceConfig.ch;
params.walkableRadius = InstanceConfig.walkableRadius * InstanceConfig.cs;
- params.tileX = 0;
- params.tileY = 0;
+ params.tileX = X;
+ params.tileY = Y;
params.tileLayer = 0;
+ params.buildBvTree = true;
rcVcopy(params.bmax, bmax);
rcVcopy(params.bmin, bmin);
@@ -200,7 +163,14 @@ uint8* TileBuilder::BuildInstance( dtNavMeshParams& navMeshParams, WorldModelRoo
// Offmesh-connection settings
params.offMeshConCount = 0; // none for now
- //params.tileSize = Constants::VertexPerMap;
+ rcFreeHeightField(hf);
+ rcFreeCompactHeightfield(chf);
+ rcFreeContourSet(contours);
+ delete vertices;
+ delete triangles;
+ delete areas;
+ delete bmin;
+ delete bmax;
if (!params.polyCount || !params.polys || Constants::TilesPerMap * Constants::TilesPerMap == params.polyCount)
{
@@ -208,20 +178,18 @@ uint8* TileBuilder::BuildInstance( dtNavMeshParams& navMeshParams, WorldModelRoo
// keep in mind that we do output those into debug info
// drop tiles with only exact count - some tiles may have geometry while having less tiles
printf("No polygons to build on tile, skipping.\n");
- delete areas;
- delete triangles;
- delete vertices;
+ rcFreePolyMesh(pmesh);
+ rcFreePolyMeshDetail(dmesh);
return NULL;
}
int navDataSize;
uint8* navData;
- printf("Creating the navmesh with %i vertices, %i polys, %i triangles!\n", pmesh->nverts, pmesh->npolys, dmesh->ntris);
+ printf("Creating the navmesh with %i vertices, %i polys, %i triangles!\n", params.vertCount, params.polyCount, params.detailTriCount);
bool result = dtCreateNavMeshData(&params, &navData, &navDataSize);
- delete areas;
- delete triangles;
- delete vertices;
+ rcFreePolyMesh(pmesh);
+ rcFreePolyMeshDetail(dmesh);
if (result)
{
@@ -233,7 +201,7 @@ uint8* TileBuilder::BuildInstance( dtNavMeshParams& navMeshParams, WorldModelRoo
return NULL;
}
-uint8* TileBuilder::Build(dtNavMeshParams& navMeshParams)
+uint8* TileBuilder::BuildTiled(dtNavMeshParams& navMeshParams)
{
_Geometry = new Geometry();
_Geometry->Transform = true;
@@ -245,10 +213,14 @@ uint8* TileBuilder::Build(dtNavMeshParams& navMeshParams)
if (_Geometry->Vertices.empty() && _Geometry->Triangles.empty())
return NULL;
+ float* bmin = NULL, *bmax = NULL;
+ CalculateTileBounds(bmin, bmax, navMeshParams);
+ _Geometry->CalculateMinMaxHeight(bmin[1], bmax[1]);
+
// again, we load everything - wasteful but who cares
- for (int ty = Y - 2; ty <= Y + 2; ty++)
+ for (int ty = Y - 1; ty <= Y + 1; ty++)
{
- for (int tx = X - 2; tx <= X + 2; tx++)
+ for (int tx = X - 1; tx <= X + 1; tx++)
{
// don't load main tile again
if (tx == X && ty == Y)
@@ -267,23 +239,7 @@ uint8* TileBuilder::Build(dtNavMeshParams& navMeshParams)
}
}
- if (Constants::Debug)
- {
- char buff[100];
- sprintf(buff, "mmaps/%s_%02u%02u.obj", World.c_str(), Y, X);
- FILE* debug = fopen(buff, "wb");
- for (uint32 i = 0; i < _Geometry->Vertices.size(); ++i)
- {
- const Vector3& vector = _Geometry->Vertices[i];
- fprintf(debug, "v %f %f %f\n", vector.x, vector.y, vector.z);
- }
- for (uint32 i = 0; i < _Geometry->Triangles.size(); ++i)
- {
- const Triangle<uint32>& triangle = _Geometry->Triangles[i];
- fprintf(debug, "f %u %u %u\n", triangle.V0 + 1, triangle.V1 + 1, triangle.V2 + 1);
- }
- fclose(debug);
- }
+ OutputDebugVertices();
uint32 numVerts = _Geometry->Vertices.size();
uint32 numTris = _Geometry->Triangles.size();
@@ -294,93 +250,38 @@ uint8* TileBuilder::Build(dtNavMeshParams& navMeshParams)
_Geometry->Vertices.clear();
_Geometry->Triangles.clear();
+ // add border
+ bmin[0] -= Config.borderSize * Config.cs;
+ bmin[2] -= Config.borderSize * Config.cs;
+ bmax[0] += Config.borderSize * Config.cs;
+ bmax[2] += Config.borderSize * Config.cs;
- rcVcopy(Config.bmin, cBuilder->bmin);
- rcVcopy(Config.bmax, cBuilder->bmax);
+ rcHeightfield* hf = rcAllocHeightfield();
+ int width = Config.tileSize + (Config.borderSize * 2);
+ rcCreateHeightfield(Context, *hf, width, width, bmin, bmax, Config.cs, Config.ch);
- // this sets the dimensions of the heightfield - should maybe happen before border padding
- rcCalcGridSize(Config.bmin, Config.bmax, Config.cs, &Config.width, &Config.height);
+ rcClearUnwalkableTriangles(Context, Config.walkableSlopeAngle, vertices, numVerts, triangles, numTris, areas);
+ rcRasterizeTriangles(Context, vertices, numVerts, triangles, areas, numTris, *hf, Config.walkableClimb);
- // Initialize per tile config.
- rcConfig tileCfg = Config;
- tileCfg.width = Config.tileSize + Config.borderSize * 2;
- tileCfg.height = Config.tileSize + Config.borderSize * 2;
+ rcFilterLowHangingWalkableObstacles(Context, Config.walkableClimb, *hf);
+ rcFilterLedgeSpans(Context, Config.walkableHeight, Config.walkableClimb, *hf);
+ rcFilterWalkableLowHeightSpans(Context, Config.walkableHeight, *hf);
- // merge per tile poly and detail meshes
- rcPolyMesh** pmmerge = new rcPolyMesh*[Constants::TilesPerMap * Constants::TilesPerMap];
- rcPolyMeshDetail** dmmerge = new rcPolyMeshDetail*[Constants::TilesPerMap * Constants::TilesPerMap];
+ rcCompactHeightfield* chf = rcAllocCompactHeightfield();
+ rcBuildCompactHeightfield(Context, Config.walkableHeight, Config.walkableClimb, *hf, *chf);
- int nmerge = 0;
- for (int y = 0; y < Constants::TilesPerMap; ++y)
- {
- for (int x = 0; x < Constants::TilesPerMap; ++x)
- {
- // Calculate the per tile bounding box.
- tileCfg.bmin[0] = Config.bmin[0] + float(x * Config.tileSize - Config.borderSize) * Config.cs;
- tileCfg.bmin[2] = Config.bmin[2] + float(y * Config.tileSize - Config.borderSize) * Config.cs;
- tileCfg.bmax[0] = Config.bmin[0] + float((x + 1) * Config.tileSize + Config.borderSize) * Config.cs;
- tileCfg.bmax[2] = Config.bmin[2] + float((y + 1) * Config.tileSize + Config.borderSize) * Config.cs;
-
-
- rcHeightfield* hf = rcAllocHeightfield();
- rcCreateHeightfield(Context, *hf, tileCfg.width, tileCfg.height, tileCfg.bmin, tileCfg.bmax, tileCfg.cs, tileCfg.ch);
- rcClearUnwalkableTriangles(Context, tileCfg.walkableSlopeAngle, vertices, numVerts, triangles, numTris, areas);
- rcRasterizeTriangles(Context, vertices, numVerts, triangles, areas, numTris, *hf, Config.walkableClimb);
-
- // Once all geometry is rasterized, we do initial pass of filtering to
- // remove unwanted overhangs caused by the conservative rasterization
- // as well as filter spans where the character cannot possibly stand.
- rcFilterLowHangingWalkableObstacles(Context, Config.walkableClimb, *hf);
- rcFilterLedgeSpans(Context, tileCfg.walkableHeight, tileCfg.walkableClimb, *hf);
- rcFilterWalkableLowHeightSpans(Context, tileCfg.walkableHeight, *hf);
-
- // Compact the heightfield so that it is faster to handle from now on.
- // This will result in more cache coherent data as well as the neighbours
- // between walkable cells will be calculated.
- rcCompactHeightfield* chf = rcAllocCompactHeightfield();
- rcBuildCompactHeightfield(Context, tileCfg.walkableHeight, tileCfg.walkableClimb, *hf, *chf);
-
- rcFreeHeightField(hf);
-
- // Erode the walkable area by agent radius.
- rcErodeWalkableArea(Context, Config.walkableRadius, *chf);
- // Prepare for region partitioning, by calculating distance field along the walkable surface.
- rcBuildDistanceField(Context, *chf);
- // Partition the walkable surface into simple regions without holes.
- rcBuildRegions(Context, *chf, tileCfg.borderSize, tileCfg.minRegionArea, tileCfg.mergeRegionArea);
-
- // Create contours.
- rcContourSet* cset = rcAllocContourSet();
- rcBuildContours(Context, *chf, tileCfg.maxSimplificationError, tileCfg.maxEdgeLen, *cset);
-
- // Build polygon navmesh from the contours.
- rcPolyMesh* pmesh = rcAllocPolyMesh();
- rcBuildPolyMesh(Context, *cset, tileCfg.maxVertsPerPoly, *pmesh);
-
- // Build detail mesh.
- rcPolyMeshDetail* dmesh = rcAllocPolyMeshDetail();
- rcBuildPolyMeshDetail(Context, *pmesh, *chf, tileCfg.detailSampleDist, tileCfg.detailSampleMaxError, *dmesh);
-
- // Free memory
- rcFreeCompactHeightfield(chf);
- rcFreeContourSet(cset);
-
- pmmerge[nmerge] = pmesh;
- dmmerge[nmerge] = dmesh;
- ++nmerge;
- }
- }
+ rcErodeWalkableArea(Context, Config.walkableRadius, *chf);
+ rcBuildDistanceField(Context, *chf);
+ rcBuildRegions(Context, *chf, Config.borderSize, Config.minRegionArea, Config.mergeRegionArea);
+
+ rcContourSet* contours = rcAllocContourSet();
+ rcBuildContours(Context, *chf, Config.maxSimplificationError, Config.maxEdgeLen, *contours);
rcPolyMesh* pmesh = rcAllocPolyMesh();
- rcMergePolyMeshes(Context, pmmerge, nmerge, *pmesh);
+ rcBuildPolyMesh(Context, *contours, Config.maxVertsPerPoly, *pmesh);
rcPolyMeshDetail* dmesh = rcAllocPolyMeshDetail();
- rcMergePolyMeshDetails(Context, dmmerge, nmerge, *dmesh);
-
- delete[] pmmerge;
- delete[] dmmerge;
-
- printf("[%02i,%02i] Meshes merged!\n", X, Y);
+ rcBuildPolyMeshDetail(Context, *pmesh, *chf, Config.detailSampleDist, Config.detailSampleMaxError, *dmesh);
// Set flags according to area types (e.g. Swim for Water)
for (int i = 0; i < pmesh->npolys; i++)
@@ -407,54 +308,60 @@ uint8* TileBuilder::Build(dtNavMeshParams& navMeshParams)
params.detailVertsCount = dmesh->nverts;
params.detailTris = dmesh->tris;
params.detailTriCount = dmesh->ntris;
- rcVcopy(params.bmin, pmesh->bmin);
- rcVcopy(params.bmax, pmesh->bmax);
// General settings
params.ch = Config.ch;
params.cs = Config.cs;
- params.walkableClimb = Constants::BaseUnitDim * Config.walkableClimb;
- params.walkableHeight = Constants::BaseUnitDim * Config.walkableHeight;
- params.walkableRadius = Constants::BaseUnitDim * Config.walkableRadius;
- params.tileX = (((cBuilder->bmin[0] + cBuilder->bmax[0]) / 2) - navMeshParams.orig[0]) / Constants::TileSize;
- params.tileY = (((cBuilder->bmin[2] + cBuilder->bmax[2]) / 2) - navMeshParams.orig[2]) / Constants::TileSize;
+ params.walkableClimb = Config.walkableClimb * Config.ch;
+ params.walkableHeight = Config.walkableHeight * Config.ch;
+ params.walkableRadius = Config.walkableRadius * Config.cs;
+ params.tileX = X;
+ params.tileY = Y;
+ params.tileLayer = 0;
+ params.buildBvTree = true;
+
+ // Recalculate the bounds with the added geometry
+ float* bmin2 = NULL, *bmax2 = NULL;
+ CalculateTileBounds(bmin2, bmax2, navMeshParams);
+ bmin2[1] = bmin[1];
+ bmax2[1] = bmax[1];
- rcVcopy(params.bmin, cBuilder->bmin);
- rcVcopy(params.bmax, cBuilder->bmax);
+ rcVcopy(params.bmax, bmax2);
+ rcVcopy(params.bmin, bmin2);
// Offmesh-connection settings
params.offMeshConCount = 0; // none for now
- //params.tileSize = Constants::VertexPerMap;
+ rcFreeHeightField(hf);
+ rcFreeCompactHeightfield(chf);
+ rcFreeContourSet(contours);
+ delete vertices;
+ delete triangles;
+ delete areas;
+ delete bmin;
+ delete bmax;
if (!params.polyCount || !params.polys || Constants::TilesPerMap * Constants::TilesPerMap == params.polyCount)
{
// we have flat tiles with no actual geometry - don't build those, its useless
// keep in mind that we do output those into debug info
// drop tiles with only exact count - some tiles may have geometry while having less tiles
- printf("[%02i,%02i] No polygons to build on tile, skipping.\n", X, Y);
+ printf("[%02i, %02i] No polygons to build on tile, skipping.\n", X, Y);
rcFreePolyMesh(pmesh);
rcFreePolyMeshDetail(dmesh);
- delete areas;
- delete triangles;
- delete vertices;
return NULL;
}
int navDataSize;
uint8* navData;
- printf("[%02i,%02i] Creating the navmesh with %i vertices, %i polys, %i triangles!\n", X, Y, pmesh->nverts, pmesh->npolys, dmesh->ntris);
+ printf("[%02i, %02i] Creating the navmesh with %i vertices, %i polys, %i triangles!\n", X, Y, params.vertCount, params.polyCount, params.detailTriCount);
bool result = dtCreateNavMeshData(&params, &navData, &navDataSize);
- // Free some memory
rcFreePolyMesh(pmesh);
rcFreePolyMeshDetail(dmesh);
- delete areas;
- delete triangles;
- delete vertices;
if (result)
{
- printf("[%02i,%02i] NavMesh created, size %i!\n", X, Y, navDataSize);
+ printf("[%02i, %02i] NavMesh created, size %i!\n", X, Y, navDataSize);
DataSize = navDataSize;
return navData;
}
@@ -462,6 +369,27 @@ uint8* TileBuilder::Build(dtNavMeshParams& navMeshParams)
return NULL;
}
+void TileBuilder::OutputDebugVertices()
+{
+ if (Constants::Debug)
+ {
+ char buff[100];
+ sprintf(buff, "mmaps/%s_%02u%02u.obj", World.c_str(), Y, X);
+ FILE* debug = fopen(buff, "wb");
+ for (uint32 i = 0; i < _Geometry->Vertices.size(); ++i)
+ {
+ const Vector3& vector = _Geometry->Vertices[i];
+ fprintf(debug, "v %f %f %f\n", vector.x, vector.y, vector.z);
+ }
+ for (uint32 i = 0; i < _Geometry->Triangles.size(); ++i)
+ {
+ const Triangle<uint32>& triangle = _Geometry->Triangles[i];
+ fprintf(debug, "f %u %u %u\n", triangle.V0 + 1, triangle.V1 + 1, triangle.V2 + 1);
+ }
+ fclose(debug);
+ }
+}
+
TileBuilder::~TileBuilder()
{
delete Context;
diff --git a/src/tools/mesh_extractor/TileBuilder.h b/src/tools/mesh_extractor/TileBuilder.h
index 814f989486e..165b3594ed6 100644
--- a/src/tools/mesh_extractor/TileBuilder.h
+++ b/src/tools/mesh_extractor/TileBuilder.h
@@ -16,8 +16,10 @@ public:
~TileBuilder();
void CalculateTileBounds(float*& bmin, float*& bmax, dtNavMeshParams& navMeshParams);
- uint8* Build(dtNavMeshParams& navMeshParams);
- uint8* BuildInstance(dtNavMeshParams& navMeshParams, WorldModelRoot* root, const WorldModelDefinition& def);
+ uint8* BuildTiled(dtNavMeshParams& navMeshParams);
+ uint8* BuildInstance(dtNavMeshParams& navMeshParams);
+ void AddGeometry(WorldModelRoot* root, const WorldModelDefinition& def);
+ void OutputDebugVertices();
std::string World;
int X;
int Y;
diff --git a/src/tools/mesh_extractor/Utils.cpp b/src/tools/mesh_extractor/Utils.cpp
index 10e0bdc0d04..24cfb5cd1db 100644
--- a/src/tools/mesh_extractor/Utils.cpp
+++ b/src/tools/mesh_extractor/Utils.cpp
@@ -87,7 +87,7 @@ std::string Utils::FixModelPath(const std::string& path )
return Utils::GetPathBase(path) + ".M2";
}
-Vector3 Utils::TransformDoodadVertex(const IDefinition& def, Vector3& vec)
+Vector3 Utils::TransformDoodadVertex(const IDefinition& def, Vector3& vec, bool translate)
{
// Sources of information:
/// http://www.pxr.dk/wowdev/wiki/index.php?title=ADT/v18&oldid=3715
@@ -99,15 +99,21 @@ Vector3 Utils::TransformDoodadVertex(const IDefinition& def, Vector3& vec)
Vector3 ret = Utils::VectorTransform(vec, rot);
// And finally scale and translate it to our origin
- return (ret * def.Scale()) + Vector3(Constants::MaxXY - def.Position.z, Constants::MaxXY - def.Position.x, def.Position.y);
+ ret = ret * def.Scale();
+ if (translate)
+ ret = ret + Vector3(Constants::MaxXY - def.Position.z, Constants::MaxXY - def.Position.x, def.Position.y);
+ return ret;
}
-Vector3 Utils::TransformWmoDoodad(const DoodadInstance& inst, const WorldModelDefinition& root, Vector3& vec )
+Vector3 Utils::TransformWmoDoodad(const DoodadInstance& inst, const WorldModelDefinition& root, Vector3& vec, bool translate )
{
G3D::Quat quat = G3D::Quat(-inst.QuatY, inst.QuatZ, -inst.QuatX, inst.QuatW);
Vector3 ret = Utils::VectorTransform(vec, G3D::Matrix4(quat.toRotationMatrix()));
- return (ret * (inst.Scale / 1024.0f)) + Vector3(Constants::MaxXY - inst.Position.z, Constants::MaxXY - inst.Position.x, inst.Position.y);
+ ret = ret * (inst.Scale / 1024.0f);
+ if (translate)
+ ret = ret + Vector3(Constants::MaxXY - inst.Position.z, Constants::MaxXY - inst.Position.x, inst.Position.y);
+ return ret;
}
float Utils::ToRadians( float degrees )
@@ -138,11 +144,11 @@ Vector3 Vector3::Read( FILE* file )
return ret;
}
-Vector3 Utils::GetLiquidVert(const IDefinition& def, Vector3 basePosition, float height, int /*x*/, int /*y*/)
+Vector3 Utils::GetLiquidVert(const IDefinition& def, Vector3 basePosition, float height, int x, int y, bool translate)
{
if (Utils::Distance(height, 0.0f) > 0.5f)
basePosition.z = 0.0f;
- return Utils::TransformDoodadVertex(def, basePosition + Vector3(basePosition.x * Constants::UnitSize, basePosition.y * Constants::UnitSize, height));
+ return Utils::TransformDoodadVertex(def, basePosition + Vector3(x * Constants::UnitSize, y * Constants::UnitSize, height), translate);
}
float Utils::Distance( float x, float y )
@@ -167,29 +173,43 @@ void Utils::SaveToDisk( FILE* stream, const std::string& path )
if (!disk)
{
printf("SaveToDisk: Could not save file %s to disk, please verify that you have write permissions on that directory\n", path.c_str());
+ fclose(stream);
return;
}
uint32 size = Utils::Size(stream);
uint8* data = new uint8[size];
// Read the data to an array
- if (fread(data, 1, size, stream) != 1)
+ size_t read = fread(data, size, 1, stream);
+ if (read != 1)
{
- printf("SaveToDisk: Error reading from Stream while trying to save file %s to disck.\n", path.c_str());
+ printf("SaveToDisk: Error reading from Stream while trying to save file %s to disk.\n", path.c_str());
+ fclose(disk);
+ fclose(stream);
return;
}
+
// And write it in the file
- fwrite(data, 1, size, disk);
+ size_t wrote = fwrite(data, size, 1, disk);
+ if (wrote != 1)
+ {
+ printf("SaveToDisk: Error writing to the file while trying to save %s to disk.\n", path.c_str());
+ fclose(stream);
+ fclose(disk);
+ return;
+ }
// Close the filestream
fclose(disk);
+ fclose(stream);
+
// Free the used memory
- delete [] data;
+ delete[] data;
}
Vector3 Utils::ToWoWCoords(const Vector3& vec )
{
- return Vector3(-vec.z, vec.x, vec.y);
+ return Vector3(-vec.z, -vec.x, vec.y);
}
std::string Utils::GetExtension( std::string path )
diff --git a/src/tools/mesh_extractor/Utils.h b/src/tools/mesh_extractor/Utils.h
index a307dd4f695..d6bb421a633 100644
--- a/src/tools/mesh_extractor/Utils.h
+++ b/src/tools/mesh_extractor/Utils.h
@@ -367,7 +367,7 @@ public:
}
static float ToRadians(float degrees);
static std::string GetPathBase(const std::string& path);
- static Vector3 GetLiquidVert(const IDefinition& def, Vector3 basePosition, float height, int /*x*/, int /*y*/);
+ static Vector3 GetLiquidVert(const IDefinition& def, Vector3 basePosition, float height, int /*x*/, int /*y*/, bool translate = true);
static float Distance(float x, float y);
template<typename T>
static bool IsAllZero(T* arr, uint32 size)
@@ -383,8 +383,8 @@ public:
static Vector3 ToWoWCoords(const Vector3& vec );
static std::string GetExtension( std::string path );
static char* GetPlainName(const char* FileName);
- static Vector3 TransformDoodadVertex(const IDefinition& def, Vector3& vec);
+ static Vector3 TransformDoodadVertex(const IDefinition& def, Vector3& vec, bool translate = true);
static Vector3 VectorTransform(const Vector3& vec, const G3D::Matrix4& matrix, bool normal = false );
- static Vector3 TransformWmoDoodad(const DoodadInstance& inst, const WorldModelDefinition& root, Vector3& vec );
+ static Vector3 TransformWmoDoodad(const DoodadInstance& inst, const WorldModelDefinition& root, Vector3& vec, bool translate = true );
};
#endif
diff --git a/src/tools/mesh_extractor/WorldModelHandler.cpp b/src/tools/mesh_extractor/WorldModelHandler.cpp
index 24f63dc1e33..3565a1d6af0 100644
--- a/src/tools/mesh_extractor/WorldModelHandler.cpp
+++ b/src/tools/mesh_extractor/WorldModelHandler.cpp
@@ -79,13 +79,17 @@ void WorldModelHandler::ProcessInternal( MapChunk* mcnk )
fseek(stream, mcnk->Source->Offset, SEEK_SET);
}
-void WorldModelHandler::InsertModelGeometry( std::vector<Vector3>& verts, std::vector<Triangle<uint32> >& tris, const WorldModelDefinition& def, WorldModelRoot* root )
+void WorldModelHandler::InsertModelGeometry( std::vector<Vector3>& verts, std::vector<Triangle<uint32> >& tris, const WorldModelDefinition& def, WorldModelRoot* root, bool translate )
{
for (std::vector<WorldModelGroup>::iterator group = root->Groups.begin(); group != root->Groups.end(); ++group)
{
uint32 vertOffset = verts.size();
for (std::vector<Vector3>::iterator itr2 = group->Vertices.begin(); itr2 != group->Vertices.end(); ++itr2)
- verts.push_back(Utils::TransformDoodadVertex(def, *itr2)); // Transform the vertex to world space
+ {
+ Vector3 v = Utils::TransformDoodadVertex(def, *itr2, translate);
+ // If translate is false, then we were called directly from the TileBuilder to add data to it's _Geometry member, hence, we have to manually convert the vertices to Recast format.
+ verts.push_back(translate ? v : Utils::ToRecast(v)); // Transform the vertex to world space
+ }
for (uint32 i = 0; i < group->Triangles.size(); ++i)
{
@@ -122,7 +126,10 @@ void WorldModelHandler::InsertModelGeometry( std::vector<Vector3>& verts, std::v
continue;
int vertOffset = verts.size();
for (std::vector<Vector3>::iterator itr2 = model->Vertices.begin(); itr2 != model->Vertices.end(); ++itr2)
- verts.push_back(Utils::TransformDoodadVertex(def, Utils::TransformWmoDoodad(*instance, def, *itr2)));
+ {
+ Vector3 v = Utils::TransformDoodadVertex(def, Utils::TransformWmoDoodad(*instance, def, *itr2, false), translate);
+ verts.push_back(translate ? v : Utils::ToRecast(v));
+ }
for (std::vector<Triangle<uint16> >::iterator itr2 = model->Triangles.begin(); itr2 != model->Triangles.end(); ++itr2)
tris.push_back(Triangle<uint32>(Constants::TRIANGLE_TYPE_WMO, itr2->V0 + vertOffset, itr2->V1 + vertOffset, itr2->V2 + vertOffset));
}
@@ -144,14 +151,20 @@ void WorldModelHandler::InsertModelGeometry( std::vector<Vector3>& verts, std::v
continue;
uint32 vertOffset = verts.size();
- verts.push_back(Utils::GetLiquidVert(def, liquidHeader.BaseLocation,
- liquidDataGeometry.HeightMap[x][y], x, y));
- verts.push_back(Utils::GetLiquidVert(def, liquidHeader.BaseLocation,
- liquidDataGeometry.HeightMap[x + 1][y], x + 1, y));
- verts.push_back(Utils::GetLiquidVert(def, liquidHeader.BaseLocation,
- liquidDataGeometry.HeightMap[x][y + 1], x, y + 1));
- verts.push_back(Utils::GetLiquidVert(def, liquidHeader.BaseLocation,
- liquidDataGeometry.HeightMap[x + 1][y + 1], x + 1, y + 1));
+
+ Vector3 v1 = Utils::GetLiquidVert(def, liquidHeader.BaseLocation,
+ liquidDataGeometry.HeightMap[x][y], x, y, translate);
+ Vector3 v2 = Utils::GetLiquidVert(def, liquidHeader.BaseLocation,
+ liquidDataGeometry.HeightMap[x + 1][y], x + 1, y, translate);
+ Vector3 v3 = Utils::GetLiquidVert(def, liquidHeader.BaseLocation,
+ liquidDataGeometry.HeightMap[x][y + 1], x, y + 1, translate);
+ Vector3 v4 = Utils::GetLiquidVert(def, liquidHeader.BaseLocation,
+ liquidDataGeometry.HeightMap[x + 1][y + 1], x + 1, y + 1, translate);
+
+ verts.push_back(translate ? v1 : Utils::ToRecast(v1));
+ verts.push_back(translate ? v2 : Utils::ToRecast(v2));
+ verts.push_back(translate ? v3 : Utils::ToRecast(v3));
+ verts.push_back(translate ? v4 : Utils::ToRecast(v4));
tris.push_back(Triangle<uint32>(Constants::TRIANGLE_TYPE_WATER, vertOffset, vertOffset + 2, vertOffset + 1));
tris.push_back(Triangle<uint32>(Constants::TRIANGLE_TYPE_WATER, vertOffset + 2, vertOffset + 3, vertOffset + 1));
diff --git a/src/tools/mesh_extractor/WorldModelHandler.h b/src/tools/mesh_extractor/WorldModelHandler.h
index 0611a02f764..87a5ad62938 100644
--- a/src/tools/mesh_extractor/WorldModelHandler.h
+++ b/src/tools/mesh_extractor/WorldModelHandler.h
@@ -34,7 +34,7 @@ public:
std::vector<Vector3> Vertices;
std::vector<Triangle<uint32> > Triangles;
bool IsSane() { return _definitions && _paths; }
- static void InsertModelGeometry(std::vector<Vector3>& verts, std::vector<Triangle<uint32> >& tris, const WorldModelDefinition& def, WorldModelRoot* root);
+ static void InsertModelGeometry(std::vector<Vector3>& verts, std::vector<Triangle<uint32> >& tris, const WorldModelDefinition& def, WorldModelRoot* root, bool translate = true);
protected:
void ProcessInternal(MapChunk* data);
private: