Advertisement
Guest User

Vehicule Mangos 10720

a guest
Nov 12th, 2010
211
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Diff 230.33 KB | None | 0 0
  1. diff --git a/sql/v01_vehicle_table.sql b/sql/v01_vehicle_table.sql
  2. new file mode 100644
  3. index 0000000..55d7442
  4. --- /dev/null
  5. +++ b/sql/v01_vehicle_table.sql
  6. @@ -0,0 +1,36 @@
  7. +DROP TABLE IF EXISTS `vehicle_data`;
  8. +CREATE TABLE `vehicle_data` (
  9. +  `entry` mediumint(5) unsigned NOT NULL,
  10. +  `flags` mediumint(8) unsigned NOT NULL default '0',
  11. +  `Spell1` mediumint(8) unsigned NOT NULL default '0',
  12. +  `Spell2` mediumint(8) unsigned NOT NULL default '0',
  13. +  `Spell3` mediumint(8) unsigned NOT NULL default '0',
  14. +  `Spell4` mediumint(8) unsigned NOT NULL default '0',
  15. +  `Spell5` mediumint(8) unsigned NOT NULL default '0',
  16. +  `Spell6` mediumint(8) unsigned NOT NULL default '0',
  17. +  `Spell7` mediumint(8) unsigned NOT NULL default '0',
  18. +  `Spell8` mediumint(8) unsigned NOT NULL default '0',
  19. +  `Spell9` mediumint(8) unsigned NOT NULL default '0',
  20. +  `Spell10` mediumint(8) unsigned NOT NULL default '0',
  21. +  `req_aura` mediumint(8) unsigned NOT NULL default '0',
  22. +  PRIMARY KEY  (`entry`)
  23. +) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Vehicle System';
  24. +
  25. +DROP TABLE IF EXISTS `vehicle_seat_data`;
  26. +CREATE TABLE `vehicle_seat_data` (
  27. +  `seat` mediumint(5) unsigned NOT NULL,
  28. +  `flags` mediumint(8) unsigned NOT NULL default '0',
  29. +  PRIMARY KEY  (`seat`)
  30. +) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Vehicle Seat System';
  31. +
  32. +ALTER TABLE creature_addon
  33. +  ADD COLUMN  vehicle_id  smallint(5) unsigned NOT NULL default '0' AFTER moveflags,
  34. +  ADD COLUMN  passengers  text AFTER vehicle_id;
  35. +
  36. +ALTER TABLE creature_template_addon
  37. +  ADD COLUMN  vehicle_id  smallint(5) unsigned NOT NULL default '0' AFTER moveflags,
  38. +  ADD COLUMN  passengers  text AFTER vehicle_id;
  39. +
  40. +/* vehicle multi seat mounts */
  41. +ALTER TABLE creature_template
  42. +  ADD COLUMN `VehicleEntry` mediumint(8) unsigned NOT NULL default '0' AFTER `PetSpellDataId`;
  43. diff --git a/sql/v02_vehicle_data.sql b/sql/v02_vehicle_data.sql
  44. new file mode 100644
  45. index 0000000..5851bc8
  46. --- /dev/null
  47. +++ b/sql/v02_vehicle_data.sql
  48. @@ -0,0 +1,714 @@
  49. +REPLACE INTO `vehicle_data` VALUES
  50. +(1,0,0,0,0,0,0,0,0,0,0,0,0),(6,0,0,0,0,0,0,0,0,0,0,0,0),(7,0,0,0,0,0,0,0,0,0,0,0,0),
  51. +(8,0,0,0,0,0,0,0,0,0,0,0,0),(14,0,0,0,0,0,0,0,0,0,0,0,0),(16,0,0,0,0,0,0,0,0,0,0,0,0),
  52. +(17,0,0,0,0,0,0,0,0,0,0,0,0),(21,0,0,0,0,0,0,0,0,0,0,0,0),(22,0,0,0,0,0,0,0,0,0,0,0,0),
  53. +(23,0,0,0,0,0,0,0,0,0,0,0,0),(24,0,0,0,0,0,0,0,0,0,0,0,0),(25,0,0,0,0,0,0,0,0,0,0,0,0),
  54. +(26,0,0,0,0,0,0,0,0,0,0,0,0),(27,0,0,0,0,0,0,0,0,0,0,0,0),(28,0,0,0,0,0,0,0,0,0,0,0,0),
  55. +(29,0,0,0,0,0,0,0,0,0,0,0,0),(30,0,0,0,0,0,0,0,0,0,0,0,0),(31,0,0,0,0,0,0,0,0,0,0,0,0),
  56. +(32,0,0,0,0,0,0,0,0,0,0,0,0),(33,0,0,0,0,0,0,0,0,0,0,0,0),(34,0,0,0,0,0,0,0,0,0,0,0,0),
  57. +(35,0,0,0,0,0,0,0,0,0,0,0,0),(36,0,0,0,0,0,0,0,0,0,0,0,0),(37,0,0,0,0,0,0,0,0,0,0,0,0),
  58. +(38,0,0,0,0,0,0,0,0,0,0,0,0),(39,0,0,0,0,0,0,0,0,0,0,0,0),(40,0,0,0,0,0,0,0,0,0,0,0,0),
  59. +(41,0,0,0,0,0,0,0,0,0,0,0,0),(42,0,0,0,0,0,0,0,0,0,0,0,0),(43,0,0,0,0,0,0,0,0,0,0,0,0),
  60. +(44,0,0,0,0,0,0,0,0,0,0,0,0),(46,0,0,0,0,0,0,0,0,0,0,0,0),(47,0,0,0,0,0,0,0,0,0,0,0,0),
  61. +(48,0,0,0,0,0,0,0,0,0,0,0,0),(49,0,0,0,0,0,0,0,0,0,0,0,0),(50,0,0,0,0,0,0,0,0,0,0,0,0),
  62. +(51,0,0,0,0,0,0,0,0,0,0,0,0),(52,0,0,0,0,0,0,0,0,0,0,0,0),(53,0,0,0,0,0,0,0,0,0,0,0,0),
  63. +(54,0,0,0,0,0,0,0,0,0,0,0,0),(55,0,0,0,0,0,0,0,0,0,0,0,0),(56,0,0,0,0,0,0,0,0,0,0,0,0),
  64. +(57,0,0,0,0,0,0,0,0,0,0,0,0),(58,0,0,0,0,0,0,0,0,0,0,0,0),(59,0,0,0,0,0,0,0,0,0,0,0,0),
  65. +(60,0,0,0,0,0,0,0,0,0,0,0,0),(61,0,0,0,0,0,0,0,0,0,0,0,0),(62,0,0,0,0,0,0,0,0,0,0,0,0),
  66. +(64,0,0,0,0,0,0,0,0,0,0,0,0),(65,0,0,0,0,0,0,0,0,0,0,0,0),(68,0,0,0,0,0,0,0,0,0,0,0,0),
  67. +(69,0,0,0,0,0,0,0,0,0,0,0,0),(70,0,0,0,0,0,0,0,0,0,0,0,0),(71,0,0,0,0,0,0,0,0,0,0,0,0),
  68. +(72,0,0,0,0,0,0,0,0,0,0,0,0),(74,0,0,0,0,0,0,0,0,0,0,0,0),(75,0,0,0,0,0,0,0,0,0,0,0,0),
  69. +(76,0,0,0,0,0,0,0,0,0,0,0,0),(77,0,0,0,0,0,0,0,0,0,0,0,0),(79,0,0,0,0,0,0,0,0,0,0,0,0),
  70. +(80,0,0,0,0,0,0,0,0,0,0,0,0),(81,0,0,0,0,0,0,0,0,0,0,0,0),(86,0,0,0,0,0,0,0,0,0,0,0,0),
  71. +(87,0,0,0,0,0,0,0,0,0,0,0,0),(88,0,0,0,0,0,0,0,0,0,0,0,0),(89,0,0,0,0,0,0,0,0,0,0,0,0),
  72. +(90,0,0,0,0,0,0,0,0,0,0,0,0),(91,0,0,0,0,0,0,0,0,0,0,0,0),(92,0,0,0,0,0,0,0,0,0,0,0,0),
  73. +(93,0,0,0,0,0,0,0,0,0,0,0,0),(97,0,0,0,0,0,0,0,0,0,0,0,0),(99,0,0,0,0,0,0,0,0,0,0,0,0),
  74. +(100,0,0,0,0,0,0,0,0,0,0,0,0),(102,0,0,0,0,0,0,0,0,0,0,0,0),(104,0,0,0,0,0,0,0,0,0,0,0,0),
  75. +(105,0,0,0,0,0,0,0,0,0,0,0,0),(106,0,0,0,0,0,0,0,0,0,0,0,0),(107,0,0,0,0,0,0,0,0,0,0,0,0),
  76. +(108,0,0,0,0,0,0,0,0,0,0,0,0),(109,0,0,0,0,0,0,0,0,0,0,0,0),(110,0,0,0,0,0,0,0,0,0,0,0,0),
  77. +(111,0,0,0,0,0,0,0,0,0,0,0,0),(112,0,0,0,0,0,0,0,0,0,0,0,0),(113,0,0,0,0,0,0,0,0,0,0,0,0),
  78. +(114,0,0,0,0,0,0,0,0,0,0,0,0),(115,0,0,0,0,0,0,0,0,0,0,0,0),(116,0,0,0,0,0,0,0,0,0,0,0,0),
  79. +(117,0,0,0,0,0,0,0,0,0,0,0,0),(118,0,0,0,0,0,0,0,0,0,0,0,0),(120,0,0,0,0,0,0,0,0,0,0,0,0),
  80. +(121,0,0,0,0,0,0,0,0,0,0,0,0),(122,0,0,0,0,0,0,0,0,0,0,0,0),(123,0,0,0,0,0,0,0,0,0,0,0,0),
  81. +(124,0,0,0,0,0,0,0,0,0,0,0,0),(125,0,0,0,0,0,0,0,0,0,0,0,0),(126,0,0,0,0,0,0,0,0,0,0,0,0),
  82. +(127,0,0,0,0,0,0,0,0,0,0,0,0),(128,0,0,0,0,0,0,0,0,0,0,0,0),(129,0,0,0,0,0,0,0,0,0,0,0,0),
  83. +(130,0,0,0,0,0,0,0,0,0,0,0,0),(131,0,0,0,0,0,0,0,0,0,0,0,0),(132,0,0,0,0,0,0,0,0,0,0,0,0),
  84. +(134,0,0,0,0,0,0,0,0,0,0,0,0),(135,0,0,0,0,0,0,0,0,0,0,0,0),(137,0,0,0,0,0,0,0,0,0,0,0,0),
  85. +(138,0,0,0,0,0,0,0,0,0,0,0,0),(139,0,0,0,0,0,0,0,0,0,0,0,0),(142,0,0,0,0,0,0,0,0,0,0,0,0),
  86. +(143,0,0,0,0,0,0,0,0,0,0,0,0),(145,0,0,0,0,0,0,0,0,0,0,0,0),(146,0,0,0,0,0,0,0,0,0,0,0,0),
  87. +(147,0,0,0,0,0,0,0,0,0,0,0,0),(148,0,0,0,0,0,0,0,0,0,0,0,0),(149,0,0,0,0,0,0,0,0,0,0,0,0),
  88. +(150,0,0,0,0,0,0,0,0,0,0,0,0),(152,0,0,0,0,0,0,0,0,0,0,0,0),(153,0,0,0,0,0,0,0,0,0,0,0,0),
  89. +(154,0,0,0,0,0,0,0,0,0,0,0,0),(156,0,0,0,0,0,0,0,0,0,0,0,0),(158,0,0,0,0,0,0,0,0,0,0,0,0),
  90. +(160,0,0,0,0,0,0,0,0,0,0,0,0),(162,0,0,0,0,0,0,0,0,0,0,0,0),(163,0,0,0,0,0,0,0,0,0,0,0,0),
  91. +(164,0,0,0,0,0,0,0,0,0,0,0,0),(165,0,0,0,0,0,0,0,0,0,0,0,0),(166,0,0,0,0,0,0,0,0,0,0,0,0),
  92. +(167,0,0,0,0,0,0,0,0,0,0,0,0),(168,0,0,0,0,0,0,0,0,0,0,0,0),(169,0,0,0,0,0,0,0,0,0,0,0,0),
  93. +(171,0,0,0,0,0,0,0,0,0,0,0,0),(173,0,0,0,0,0,0,0,0,0,0,0,0),(174,0,0,0,0,0,0,0,0,0,0,0,0),
  94. +(175,0,0,0,0,0,0,0,0,0,0,0,0),(176,0,0,0,0,0,0,0,0,0,0,0,0),(177,0,0,0,0,0,0,0,0,0,0,0,0),
  95. +(178,0,0,0,0,0,0,0,0,0,0,0,0),(179,0,0,0,0,0,0,0,0,0,0,0,0),(180,0,0,0,0,0,0,0,0,0,0,0,0),
  96. +(181,0,0,0,0,0,0,0,0,0,0,0,0),(182,0,0,0,0,0,0,0,0,0,0,0,0),(183,0,0,0,0,0,0,0,0,0,0,0,0),
  97. +(186,0,0,0,0,0,0,0,0,0,0,0,0),(188,0,0,0,0,0,0,0,0,0,0,0,0),(189,0,0,0,0,0,0,0,0,0,0,0,0),
  98. +(190,0,0,0,0,0,0,0,0,0,0,0,0),(191,0,0,0,0,0,0,0,0,0,0,0,0),(192,0,0,0,0,0,0,0,0,0,0,0,0),
  99. +(193,0,0,0,0,0,0,0,0,0,0,0,0),(194,0,0,0,0,0,0,0,0,0,0,0,0),(196,0,0,0,0,0,0,0,0,0,0,0,0),
  100. +(197,0,0,0,0,0,0,0,0,0,0,0,0),(198,0,0,0,0,0,0,0,0,0,0,0,0),(199,0,0,0,0,0,0,0,0,0,0,0,0),
  101. +(200,0,0,0,0,0,0,0,0,0,0,0,0),(201,0,0,0,0,0,0,0,0,0,0,0,0),(202,0,0,0,0,0,0,0,0,0,0,0,0),
  102. +(203,0,0,0,0,0,0,0,0,0,0,0,0),(204,0,0,0,0,0,0,0,0,0,0,0,0),(205,0,0,0,0,0,0,0,0,0,0,0,0),
  103. +(206,0,0,0,0,0,0,0,0,0,0,0,0),(207,0,0,0,0,0,0,0,0,0,0,0,0),(208,0,0,0,0,0,0,0,0,0,0,0,0),
  104. +(209,0,0,0,0,0,0,0,0,0,0,0,0),(210,0,0,0,0,0,0,0,0,0,0,0,0),(211,0,0,0,0,0,0,0,0,0,0,0,0),
  105. +(212,0,0,0,0,0,0,0,0,0,0,0,0),(213,0,0,0,0,0,0,0,0,0,0,0,0),(214,0,0,0,0,0,0,0,0,0,0,0,0),
  106. +(215,0,0,0,0,0,0,0,0,0,0,0,0),(216,0,0,0,0,0,0,0,0,0,0,0,0),(217,0,0,0,0,0,0,0,0,0,0,0,0),
  107. +(218,0,0,0,0,0,0,0,0,0,0,0,0),(219,0,0,0,0,0,0,0,0,0,0,0,0),(220,0,0,0,0,0,0,0,0,0,0,0,0),
  108. +(221,0,0,0,0,0,0,0,0,0,0,0,0),(222,0,0,0,0,0,0,0,0,0,0,0,0),(223,0,0,0,0,0,0,0,0,0,0,0,0),
  109. +(224,0,0,0,0,0,0,0,0,0,0,0,0),(225,0,0,0,0,0,0,0,0,0,0,0,0),(226,0,0,0,0,0,0,0,0,0,0,0,0),
  110. +(227,0,0,0,0,0,0,0,0,0,0,0,0),(228,0,0,0,0,0,0,0,0,0,0,0,0),(229,0,0,0,0,0,0,0,0,0,0,0,0),
  111. +(230,0,0,0,0,0,0,0,0,0,0,0,0),(231,0,0,0,0,0,0,0,0,0,0,0,0),(232,0,0,0,0,0,0,0,0,0,0,0,0),
  112. +(233,0,0,0,0,0,0,0,0,0,0,0,0),(234,0,0,0,0,0,0,0,0,0,0,0,0),(236,0,0,0,0,0,0,0,0,0,0,0,0),
  113. +(237,0,0,0,0,0,0,0,0,0,0,0,0),(238,0,0,0,0,0,0,0,0,0,0,0,0),(240,0,0,0,0,0,0,0,0,0,0,0,0),
  114. +(241,0,0,0,0,0,0,0,0,0,0,0,0),(242,0,0,0,0,0,0,0,0,0,0,0,0),(243,0,0,0,0,0,0,0,0,0,0,0,0),
  115. +(244,0,0,0,0,0,0,0,0,0,0,0,0),(245,0,0,0,0,0,0,0,0,0,0,0,0),(246,0,0,0,0,0,0,0,0,0,0,0,0),
  116. +(247,0,0,0,0,0,0,0,0,0,0,0,0),(248,0,0,0,0,0,0,0,0,0,0,0,0),(249,0,0,0,0,0,0,0,0,0,0,0,0),
  117. +(250,0,0,0,0,0,0,0,0,0,0,0,0),(252,0,0,0,0,0,0,0,0,0,0,0,0),(253,0,0,0,0,0,0,0,0,0,0,0,0),
  118. +(254,0,0,0,0,0,0,0,0,0,0,0,0),(255,0,0,0,0,0,0,0,0,0,0,0,0),(256,0,0,0,0,0,0,0,0,0,0,0,0),
  119. +(257,0,0,0,0,0,0,0,0,0,0,0,0),(258,0,0,0,0,0,0,0,0,0,0,0,0),(259,0,0,0,0,0,0,0,0,0,0,0,0),
  120. +(260,0,0,0,0,0,0,0,0,0,0,0,0),(261,0,0,0,0,0,0,0,0,0,0,0,0),(262,0,0,0,0,0,0,0,0,0,0,0,0),
  121. +(263,0,0,0,0,0,0,0,0,0,0,0,0),(264,0,0,0,0,0,0,0,0,0,0,0,0),(265,0,0,0,0,0,0,0,0,0,0,0,0),
  122. +(266,0,0,0,0,0,0,0,0,0,0,0,0),(267,0,0,0,0,0,0,0,0,0,0,0,0),(268,0,0,0,0,0,0,0,0,0,0,0,0),
  123. +(269,0,0,0,0,0,0,0,0,0,0,0,0),(270,0,0,0,0,0,0,0,0,0,0,0,0),(271,0,0,0,0,0,0,0,0,0,0,0,0),
  124. +(272,0,0,0,0,0,0,0,0,0,0,0,0),(273,0,0,0,0,0,0,0,0,0,0,0,0),(274,0,0,0,0,0,0,0,0,0,0,0,0),
  125. +(275,0,0,0,0,0,0,0,0,0,0,0,0),(276,0,0,0,0,0,0,0,0,0,0,0,0),(277,0,0,0,0,0,0,0,0,0,0,0,0),
  126. +(278,0,0,0,0,0,0,0,0,0,0,0,0),(279,0,0,0,0,0,0,0,0,0,0,0,0),(280,0,0,0,0,0,0,0,0,0,0,0,0),
  127. +(281,0,0,0,0,0,0,0,0,0,0,0,0),(282,0,0,0,0,0,0,0,0,0,0,0,0),(283,0,0,0,0,0,0,0,0,0,0,0,0),
  128. +(284,0,0,0,0,0,0,0,0,0,0,0,0),(285,0,0,0,0,0,0,0,0,0,0,0,0),(286,0,0,0,0,0,0,0,0,0,0,0,0),
  129. +(287,0,0,0,0,0,0,0,0,0,0,0,0),(288,0,0,0,0,0,0,0,0,0,0,0,0),(289,0,0,0,0,0,0,0,0,0,0,0,0),
  130. +(290,0,0,0,0,0,0,0,0,0,0,0,0),(291,0,0,0,0,0,0,0,0,0,0,0,0),(292,0,0,0,0,0,0,0,0,0,0,0,0),
  131. +(293,0,0,0,0,0,0,0,0,0,0,0,0),(294,0,0,0,0,0,0,0,0,0,0,0,0),(295,0,0,0,0,0,0,0,0,0,0,0,0),
  132. +(296,0,0,0,0,0,0,0,0,0,0,0,0),(297,0,0,0,0,0,0,0,0,0,0,0,0),(298,0,0,0,0,0,0,0,0,0,0,0,0),
  133. +(299,0,0,0,0,0,0,0,0,0,0,0,0),(300,0,0,0,0,0,0,0,0,0,0,0,0),(301,0,0,0,0,0,0,0,0,0,0,0,0),
  134. +(302,0,0,0,0,0,0,0,0,0,0,0,0),(303,0,0,0,0,0,0,0,0,0,0,0,0),(304,0,0,0,0,0,0,0,0,0,0,0,0),
  135. +(305,0,0,0,0,0,0,0,0,0,0,0,0),(308,0,0,0,0,0,0,0,0,0,0,0,0),(309,0,0,0,0,0,0,0,0,0,0,0,0),
  136. +(310,0,0,0,0,0,0,0,0,0,0,0,0),(311,0,0,0,0,0,0,0,0,0,0,0,0),(312,0,0,0,0,0,0,0,0,0,0,0,0),
  137. +(313,0,0,0,0,0,0,0,0,0,0,0,0),(314,0,0,0,0,0,0,0,0,0,0,0,0),(315,0,0,0,0,0,0,0,0,0,0,0,0),
  138. +(316,0,0,0,0,0,0,0,0,0,0,0,0),(317,0,0,0,0,0,0,0,0,0,0,0,0),(318,0,0,0,0,0,0,0,0,0,0,0,0),
  139. +(320,0,0,0,0,0,0,0,0,0,0,0,0),(321,0,0,0,0,0,0,0,0,0,0,0,0),(322,0,0,0,0,0,0,0,0,0,0,0,0),
  140. +(323,0,0,0,0,0,0,0,0,0,0,0,0),(324,0,0,0,0,0,0,0,0,0,0,0,0),(325,0,0,0,0,0,0,0,0,0,0,0,0),
  141. +(327,0,0,0,0,0,0,0,0,0,0,0,0),(328,0,0,0,0,0,0,0,0,0,0,0,0),(329,0,0,0,0,0,0,0,0,0,0,0,0),
  142. +(331,0,0,0,0,0,0,0,0,0,0,0,0),(332,0,0,0,0,0,0,0,0,0,0,0,0),(335,0,0,0,0,0,0,0,0,0,0,0,0),
  143. +(336,0,0,0,0,0,0,0,0,0,0,0,0),(337,0,0,0,0,0,0,0,0,0,0,0,0),(338,0,0,0,0,0,0,0,0,0,0,0,0),
  144. +(339,0,0,0,0,0,0,0,0,0,0,0,0),(340,0,0,0,0,0,0,0,0,0,0,0,0),(341,0,0,0,0,0,0,0,0,0,0,0,0),
  145. +(342,0,0,0,0,0,0,0,0,0,0,0,0),(343,0,0,0,0,0,0,0,0,0,0,0,0),(344,0,0,0,0,0,0,0,0,0,0,0,0),
  146. +(345,0,0,0,0,0,0,0,0,0,0,0,0),(347,0,0,0,0,0,0,0,0,0,0,0,0),(348,0,0,0,0,0,0,0,0,0,0,0,0),
  147. +(349,0,0,0,0,0,0,0,0,0,0,0,0),(352,0,0,0,0,0,0,0,0,0,0,0,0),(353,0,0,0,0,0,0,0,0,0,0,0,0),
  148. +(354,0,0,0,0,0,0,0,0,0,0,0,0),(356,0,0,0,0,0,0,0,0,0,0,0,0),(357,0,0,0,0,0,0,0,0,0,0,0,0),
  149. +(358,0,0,0,0,0,0,0,0,0,0,0,0),(359,0,0,0,0,0,0,0,0,0,0,0,0),(363,0,0,0,0,0,0,0,0,0,0,0,0),
  150. +(368,0,0,0,0,0,0,0,0,0,0,0,0),(369,0,0,0,0,0,0,0,0,0,0,0,0),(370,0,0,0,0,0,0,0,0,0,0,0,0),
  151. +(371,0,0,0,0,0,0,0,0,0,0,0,0),(372,0,0,0,0,0,0,0,0,0,0,0,0),(373,0,0,0,0,0,0,0,0,0,0,0,0),
  152. +(374,0,0,0,0,0,0,0,0,0,0,0,0),(375,0,0,0,0,0,0,0,0,0,0,0,0),(376,0,0,0,0,0,0,0,0,0,0,0,0),
  153. +(380,0,0,0,0,0,0,0,0,0,0,0,0),(381,0,0,0,0,0,0,0,0,0,0,0,0),(385,0,0,0,0,0,0,0,0,0,0,0,0),
  154. +(387,0,0,0,0,0,0,0,0,0,0,0,0),(388,0,0,0,0,0,0,0,0,0,0,0,0),(389,0,0,0,0,0,0,0,0,0,0,0,0),
  155. +(390,0,0,0,0,0,0,0,0,0,0,0,0),(392,0,0,0,0,0,0,0,0,0,0,0,0),(395,0,0,0,0,0,0,0,0,0,0,0,0),
  156. +(396,0,0,0,0,0,0,0,0,0,0,0,0),(397,0,0,0,0,0,0,0,0,0,0,0,0),(399,0,0,0,0,0,0,0,0,0,0,0,0),
  157. +(402,0,0,0,0,0,0,0,0,0,0,0,0),(405,0,0,0,0,0,0,0,0,0,0,0,0),(412,0,0,0,0,0,0,0,0,0,0,0,0),
  158. +(425,0,0,0,0,0,0,0,0,0,0,0,0),(430,0,0,0,0,0,0,0,0,0,0,0,0),(435,0,0,0,0,0,0,0,0,0,0,0,0),
  159. +(436,0,0,0,0,0,0,0,0,0,0,0,0),(437,0,0,0,0,0,0,0,0,0,0,0,0),(438,0,0,0,0,0,0,0,0,0,0,0,0),
  160. +(442,0,0,0,0,0,0,0,0,0,0,0,0),(443,0,0,0,0,0,0,0,0,0,0,0,0),(444,0,0,0,0,0,0,0,0,0,0,0,0),
  161. +(445,0,0,0,0,0,0,0,0,0,0,0,0),(446,0,0,0,0,0,0,0,0,0,0,0,0),(447,0,0,0,0,0,0,0,0,0,0,0,0),
  162. +(449,0,0,0,0,0,0,0,0,0,0,0,0),(452,0,0,0,0,0,0,0,0,0,0,0,0),(453,0,0,0,0,0,0,0,0,0,0,0,0),
  163. +(456,0,0,0,0,0,0,0,0,0,0,0,0),(461,0,0,0,0,0,0,0,0,0,0,0,0),(471,0,0,0,0,0,0,0,0,0,0,0,0),
  164. +(472,0,0,0,0,0,0,0,0,0,0,0,0),(477,0,0,0,0,0,0,0,0,0,0,0,0),(478,0,0,0,0,0,0,0,0,0,0,0,0),
  165. +(479,0,0,0,0,0,0,0,0,0,0,0,0),(480,0,0,0,0,0,0,0,0,0,0,0,0),(481,0,0,0,0,0,0,0,0,0,0,0,0),
  166. +(482,0,0,0,0,0,0,0,0,0,0,0,0),(483,0,0,0,0,0,0,0,0,0,0,0,0),(484,0,0,0,0,0,0,0,0,0,0,0,0),
  167. +(485,0,0,0,0,0,0,0,0,0,0,0,0),(486,0,0,0,0,0,0,0,0,0,0,0,0),(487,0,0,0,0,0,0,0,0,0,0,0,0),
  168. +(489,0,0,0,0,0,0,0,0,0,0,0,0),(492,0,0,0,0,0,0,0,0,0,0,0,0),(496,0,0,0,0,0,0,0,0,0,0,0,0),
  169. +(497,0,0,0,0,0,0,0,0,0,0,0,0),(498,0,0,0,0,0,0,0,0,0,0,0,0),(499,0,0,0,0,0,0,0,0,0,0,0,0),
  170. +(503,0,0,0,0,0,0,0,0,0,0,0,0),(509,0,0,0,0,0,0,0,0,0,0,0,0),(510,0,0,0,0,0,0,0,0,0,0,0,0),
  171. +(512,0,0,0,0,0,0,0,0,0,0,0,0),(514,0,0,0,0,0,0,0,0,0,0,0,0),(522,0,0,0,0,0,0,0,0,0,0,0,0),
  172. +(529,0,0,0,0,0,0,0,0,0,0,0,0),(531,0,0,0,0,0,0,0,0,0,0,0,0),(532,0,0,0,0,0,0,0,0,0,0,0,0),
  173. +(533,0,0,0,0,0,0,0,0,0,0,0,0),(535,0,0,0,0,0,0,0,0,0,0,0,0),(548,0,0,0,0,0,0,0,0,0,0,0,0),
  174. +(551,0,0,0,0,0,0,0,0,0,0,0,0),(554,0,0,0,0,0,0,0,0,0,0,0,0),(555,0,0,0,0,0,0,0,0,0,0,0,0),
  175. +(560,0,0,0,0,0,0,0,0,0,0,0,0),(562,0,0,0,0,0,0,0,0,0,0,0,0),(563,0,0,0,0,0,0,0,0,0,0,0,0),
  176. +(567,0,0,0,0,0,0,0,0,0,0,0,0),(586,0,0,0,0,0,0,0,0,0,0,0,0),(587,0,0,0,0,0,0,0,0,0,0,0,0),
  177. +(591,0,0,0,0,0,0,0,0,0,0,0,0),(599,0,0,0,0,0,0,0,0,0,0,0,0),(602,0,0,0,0,0,0,0,0,0,0,0,0),
  178. +(604,0,0,0,0,0,0,0,0,0,0,0,0),(610,0,0,0,0,0,0,0,0,0,0,0,0),(611,0,0,0,0,0,0,0,0,0,0,0,0),
  179. +(614,0,0,0,0,0,0,0,0,0,0,0,0),(615,0,0,0,0,0,0,0,0,0,0,0,0),(616,0,0,0,0,0,0,0,0,0,0,0,0),
  180. +(621,0,0,0,0,0,0,0,0,0,0,0,0),(622,0,0,0,0,0,0,0,0,0,0,0,0),(624,0,0,0,0,0,0,0,0,0,0,0,0),
  181. +(625,0,0,0,0,0,0,0,0,0,0,0,0),(636,0,0,0,0,0,0,0,0,0,0,0,0),(637,0,0,0,0,0,0,0,0,0,0,0,0),
  182. +(639,0,0,0,0,0,0,0,0,0,0,0,0),(647,0,0,0,0,0,0,0,0,0,0,0,0),(648,0,0,0,0,0,0,0,0,0,0,0,0),
  183. +(655,0,0,0,0,0,0,0,0,0,0,0,0),(700,0,0,0,0,0,0,0,0,0,0,0,0),(711,0,0,0,0,0,0,0,0,0,0,0,0),
  184. +(717,0,0,0,0,0,0,0,0,0,0,0,0),(718,0,0,0,0,0,0,0,0,0,0,0,0),(732,0,0,0,0,0,0,0,0,0,0,0,0),
  185. +(736,0,0,0,0,0,0,0,0,0,0,0,0),(745,0,0,0,0,0,0,0,0,0,0,0,0),(746,0,0,0,0,0,0,0,0,0,0,0,0),
  186. +(747,0,0,0,0,0,0,0,0,0,0,0,0),(753,0,0,0,0,0,0,0,0,0,0,0,0),(763,0,0,0,0,0,0,0,0,0,0,0,0),
  187. +(774,0,0,0,0,0,0,0,0,0,0,0,0);
  188. +
  189. +/* Mechano-hog, Mekgineer's Chopper */
  190. +UPDATE creature_template SET VehicleEntry = 318, IconName = 'vehichleCursor' WHERE entry IN (29929, 32286);
  191. +
  192. +/* Traveler's Tundra Mammoth, Grand Ice Mammoth, Grand Black War Mammoth, Grand Caravan Mammoth */
  193. +UPDATE creature_template SET VehicleEntry = 312, IconName = 'vehichleCursor' WHERE entry IN (32633, 32640, 31857, 31858, 31861, 31862, 32212, 32213);
  194. +
  195. +/* X-53 Touring Rocket */
  196. +UPDATE creature_template SET VehicleEntry = 774, IconName = 'vehichleCursor' WHERE entry = 40725;
  197. +
  198. +UPDATE creature_template SET minlevel = 80, maxlevel = 80 WHERE entry IN (28312,32627,28319,32629,28094,28670);
  199. +UPDATE creature_template SET speed_run = 2, InhabitType = 1 WHERE entry IN (28312,32627,28319,32629,28094,29929,28782);
  200. +UPDATE creature_template SET mechanic_immune_mask = 652951551 WHERE entry IN (28670,28312,32627,28319,32629,28094,29929,28782);
  201. +
  202. +/* Frostbrood Vanquisher */
  203. +UPDATE creature_template SET maxhealth = 133525, minhealth = 133525, maxmana = 51360, minmana = 51360, speed_run = 2.4, InhabitType = 3 WHERE entry = 28670;
  204. +DELETE FROM npc_spellclick_spells WHERE npc_entry in (28670);
  205. +INSERT INTO npc_spellclick_spells VALUES (28670, 52196, 12779, 1, 12779, 0);
  206. +REPLACE INTO creature_template_addon VALUES (28670, 0, 50331648, 1, 0, 1024, 156, NULL, '53112 0 53112 1 48602 2');
  207. +REPLACE INTO vehicle_data VALUES (156, 24, 53114, 0, 53110, 0, 0, 0, 0, 0, 0, 0, 0);
  208. +REPLACE INTO vehicle_seat_data VALUES (1986, 3),(1987, 8);
  209. +UPDATE quest_template SET ReqItemId1 = 39700, ReqItemCount1 = 1 WHERE entry = 12779;
  210. +
  211. +/* Argent Tournament (new) */
  212. +DELETE FROM creature WHERE id IN (33844,33845);
  213. +DELETE FROM creature_addon WHERE guid IN (SELECT guid FROM creature WHERE id IN (33844,33845));
  214. +REPLACE INTO vehicle_data VALUES (349, 24, 62544, 62575, 63010, 62552, 64077, 62863, 0, 0, 0, 0, 62853);
  215. +REPLACE INTO vehicle_seat_data VALUES ('3129', '1');
  216. +DELETE FROM npc_spellclick_spells WHERE npc_entry in (33842, 33843);
  217. +INSERT INTO npc_spellclick_spells VALUES (33842,63791,13829,1,0,3),(33842,63791,13839,1,0,3),(33842,63791,13838,1,0,3),(33843,63792,13828,1,0,3),(33843,63792,13837,1,0,3),(33843,63792,13835,1,0,3);
  218. +REPLACE INTO creature_template_addon VALUES (33844, 0, 0, 2049, 0, 0, 349, NULL, NULL),(33845, 0, 0, 2049, 0, 0, 349, NULL, NULL);
  219. +UPDATE creature_template SET AIName = 'NullAI' WHERE entry IN (33243,33229,33272);
  220. +/* Alliance and Horde Tournament Mounts (DaViper fixes) */
  221. +UPDATE creature_template SET minlevel = 80, maxlevel = 80, minhealth = 50000, maxhealth = 50000, minmana = 1000, maxmana = 1000, armor = 9730,
  222. +speed_run = 1.5, mindmg = 420, maxdmg = 630, attackpower = 157, dmg_multiplier = 1.4, rangeattacktime = 2000, unit_flags = 8, minrangedmg = 336,
  223. +maxrangedmg = 504, rangedattackpower = 126 WHERE entry IN (33217,33316,33317,33318,33319,33320,33321,33322,33323,33324,33844,33845);
  224. +
  225. +/* Quest Grand Theft Palomino (12680) */
  226. +REPLACE INTO spell_script_target VALUES (52264,1,28653);
  227. +REPLACE INTO vehicle_data VALUES (123, 4, 52264, 52268, 0, 0, 0, 0, 0, 0, 0, 0, 0);
  228. +REPLACE INTO vehicle_seat_data VALUES (1782, 1);
  229. +DELETE FROM npc_spellclick_spells WHERE npc_entry in (28605,28606,28607);
  230. +INSERT INTO npc_spellclick_spells VALUES (28605, 52263, 12680, 1, 12680, 3),(28606, 52263, 12680, 1, 12680, 3),(28607, 52263, 12680, 1, 12680, 3);
  231. +REPLACE INTO creature_template_addon VALUES (28605, 0, 0, 1, 0, 0, 123, NULL, NULL),(28606, 0, 0, 1, 0, 0, 123, NULL, NULL),(28607, 0, 0, 1, 0, 0, 123, NULL, NULL);
  232. +DELETE FROM creature_addon WHERE guid IN (SELECT guid FROM creature WHERE id IN (28605,28606,28607));
  233. +
  234. +/* Quest Into the Realm of Shadows (12687) */
  235. +REPLACE INTO spell_script_target VALUES (52349,1,28782);
  236. +UPDATE creature_template SET faction_A = 2082, faction_H = 2082, unit_flags = 32768 WHERE entry = 28782;
  237. +DELETE FROM creature_addon WHERE guid IN (SELECT guid FROM creature WHERE id = 28782);
  238. +REPLACE INTO vehicle_data VALUES (135, 4, 52362, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
  239. +REPLACE INTO vehicle_seat_data VALUES (1871, 1);
  240. +DELETE FROM npc_spellclick_spells WHERE npc_entry in (28782);
  241. +INSERT INTO npc_spellclick_spells VALUES (28782, 52349, 12687, 1, 12687, 3);
  242. +REPLACE INTO creature_template_addon VALUES (28782, 0, 0, 1, 0, 0, 135, NULL, NULL);
  243. +UPDATE quest_template SET SrcSpell = 52693 WHERE entry = 12687;
  244. +
  245. +/* Quest Going Bearback */
  246. +DELETE FROM npc_spellclick_spells WHERE npc_entry in (29598);
  247. +INSERT INTO npc_spellclick_spells VALUES (29598, 54908, 12851, 1, 12851, 1);
  248. +REPLACE INTO creature_template_addon VALUES (29598, 0, 0, 1, 0, 0, 308, NULL, NULL);
  249. +REPLACE INTO `vehicle_data` VALUES (308, 24, 54897, 54907, 0, 0, 0, 0, 0, 0, 0, 0, 0);
  250. +REPLACE INTO vehicle_seat_data VALUES (2699, 1);
  251. +
  252. +/* Massacre At Light's Point (new) */
  253. +DELETE FROM npc_spellclick_spells WHERE npc_entry IN (28887,28833,28864);
  254. +INSERT INTO npc_spellclick_spells VALUES (28833,52447,12701,1,12701,1),(28887,52447,12701,1,12701,1),(28864,67373,0,0,0,1);
  255. +REPLACE INTO creature_template_addon VALUES (28887,0,0,2049,0,0,79,NULL,NULL),(28833,0,0,2049,0,0,79,NULL,NULL),(28864,0,0,0,0,0,143,NULL,'48602 0 48602 2');
  256. +REPLACE INTO vehicle_data VALUES (143,12,0,0,0,0,0,0,0,0,0,0,0),(79,5,52435,52576,0,52588,0,0,0,0,0,0,0);
  257. +REPLACE INTO vehicle_seat_data VALUES (1427, 1),(1902, 3);
  258. +UPDATE creature_model_info SET bounding_radius = 0 WHERE modelid = 25723;
  259. +UPDATE creature_template SET IconName = 'Gunner' WHERE entry IN (28887,28833);
  260. +UPDATE creature_template SET IconName = 'vehichleCursor', InhabitType = 3 WHERE entry IN (28864);
  261. +DELETE FROM creature_addon WHERE guid IN (SELECT guid FROM creature WHERE id IN (28887,28833,28864));
  262. +
  263. +/* Traveler's Tundra Mammoth, Grand Ice Mammoth */
  264. +DELETE FROM npc_spellclick_spells WHERE npc_entry IN (32633, 32640, 31857);
  265. +INSERT INTO npc_spellclick_spells VALUES (32633, 65403, 0, 0, 0, 0),(32640, 65403, 0, 0, 0, 0),(31857, 65403, 0, 0, 0, 0);
  266. +REPLACE INTO creature_template_addon VALUES (32633,0,0,0,0,0,312,NULL,NULL),(32640,0,0,0,0,0,312,NULL,NULL),(31857,0,0,0,0,0,312,NULL,NULL);
  267. +REPLACE INTO vehicle_data VALUES (312, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
  268. +
  269. +/* Salvaged Chopper */
  270. +DELETE FROM npc_spellclick_spells WHERE npc_entry IN (33062);
  271. +INSERT INTO npc_spellclick_spells VALUES (33062, 65403, 0, 0, 0, 0);
  272. +REPLACE INTO creature_template_addon VALUES (33062, 0, 0, 0, 0, 0, 335, NULL, NULL);
  273. +REPLACE INTO vehicle_data VALUES (335, 4, 62974, 62286, 62299, 64660, 0, 0, 0, 0, 0, 0, 0);
  274. +REPLACE INTO vehicle_seat_data VALUES (3005, 3),(3004, 2);
  275. +UPDATE creature_model_info SET bounding_radius = '0.306' WHERE modelid IN (25870,25871);
  276. +
  277. +/* Salvaged Demolisher */
  278. +DELETE FROM npc_spellclick_spells WHERE npc_entry IN (33109);
  279. +INSERT INTO npc_spellclick_spells VALUES (33109, 65403, 0, 0, 0, 0);
  280. +REPLACE INTO creature_template_addon VALUES (33109, 0, 0, 0, 0, 0, 338, '33167 1', NULL);
  281. +REPLACE INTO vehicle_data VALUES (338, 4, 62306, 62490, 62308, 62324, 0, 0, 0, 0, 0, 0, 0);
  282. +REPLACE INTO vehicle_seat_data VALUES (3011, 3),(3146, 8),(3013, 8),(3147, 8);
  283. +
  284. +/* Salvaged Siege Engine */
  285. +DELETE FROM npc_spellclick_spells WHERE npc_entry IN (33060);
  286. +INSERT INTO npc_spellclick_spells VALUES (33060, 65403, 0, 0, 0, 0);
  287. +REPLACE INTO creature_template_addon VALUES (33060, 0, 0, 0, 0, 0, 336, '33067 7', NULL);
  288. +REPLACE INTO vehicle_data VALUES (336, 4, 62345, 62522, 62346, 0, 0, 0, 0, 0, 0, 0, 0);
  289. +REPLACE INTO vehicle_seat_data VALUES (3006, 3),(4026, 8),(4027, 8),(3009, 8);
  290. +
  291. +/* Salvaged Siege Turret */
  292. +DELETE FROM npc_spellclick_spells WHERE npc_entry = 33067;
  293. +INSERT INTO npc_spellclick_spells VALUES (33067, 65403, 0, 0, 0, 1);
  294. +REPLACE INTO creature_template_addon VALUES (33067, 0, 0, 0, 0, 0, 337, NULL, NULL);
  295. +REPLACE INTO vehicle_data VALUES (337, 5, 62358, 64677, 62359, 0, 0, 0, 0, 0, 0, 0, 0);
  296. +REPLACE INTO vehicle_seat_data VALUES (3010, 3);
  297. +UPDATE creature_template SET minhealth = 1134000, maxhealth = 1134000, unit_flags = 32768, IconName = 'Gunner' WHERE entry = 33067;
  298. +DELETE FROM creature WHERE id = 33067;
  299. +
  300. +/* Mechanic Seat Salvaged Demolisher */
  301. +DELETE FROM npc_spellclick_spells WHERE npc_entry IN (33167);
  302. +INSERT INTO npc_spellclick_spells VALUES (33167, 65403, 0, 0, 0, 1);
  303. +REPLACE INTO creature_template_addon VALUES (33167, 0, 0, 0, 0, 0, 345, NULL, NULL);
  304. +REPLACE INTO vehicle_data VALUES (345, 5, 62634, 64979, 62479, 62471, 0, 62428, 0, 0, 0, 0, 0);
  305. +REPLACE INTO vehicle_seat_data VALUES (3077, 3),(3106, 8);
  306. +UPDATE creature_template SET minhealth = 630000, maxhealth = 630000, unit_flags = 32768, IconName = 'Gunner' WHERE entry = 33167;
  307. +DELETE FROM creature WHERE id = 33167;
  308. +
  309. +/* Ulduar Salvaged vehicles (unifieddb fix) */
  310. +DELETE FROM creature_addon WHERE guid IN (SELECT guid FROM creature WHERE id IN (33060,33062,33109));
  311. +
  312. +/* Wintergrasp Tower Cannon (new) */
  313. +DELETE FROM npc_spellclick_spells WHERE npc_entry IN (28366);
  314. +INSERT INTO npc_spellclick_spells VALUES (28366, 60968, 0, 0, 0, 1);
  315. +REPLACE INTO creature_template_addon VALUES (28366, 0, 0, 0, 0, 0, 244, NULL, NULL);
  316. +REPLACE INTO vehicle_data VALUES (244, 5, 51362, 51421, 0, 0, 0, 0, 0, 0, 0, 0, 0);
  317. +REPLACE INTO vehicle_seat_data VALUES (2283, 3);
  318. +UPDATE creature_template SET IconName = 'Gunner' WHERE entry = 28366;
  319. +
  320. +/* the Oculus (new) */
  321. +DELETE FROM spell_script_target where entry IN (49460, 49346, 49464);
  322. +DELETE FROM npc_spellclick_spells where npc_entry IN (27755, 27692, 27756);
  323. +DELETE FROM creature_template_addon where entry IN (27755, 27692, 27756);
  324. +UPDATE creature_template SET IconName = 'vehichleCursor', InhabitType = 3 WHERE entry IN (27755,27756,27692);
  325. +/* Amber Drake */
  326. +INSERT INTO spell_script_target VALUES (49460, 1, 27755);
  327. +INSERT INTO npc_spellclick_spells VALUES (27755, 49459, 0, 0, 0, 1);
  328. +INSERT INTO creature_template_addon VALUES (27755, 0, 0, 0, 0, 0, 70, NULL, '48602 0 48602 2');
  329. +REPLACE INTO vehicle_data VALUES (70, 12, 49840, 49838, 49592, 0, 0, 0, 0, 0, 0, 0, 0);
  330. +REPLACE INTO vehicle_seat_data VALUES (1323, 3);
  331. +/* Emerald Drake */
  332. +INSERT INTO spell_script_target VALUES (49346, 1, 27692);
  333. +INSERT INTO npc_spellclick_spells VALUES (27692, 49427, 0, 0, 0, 1);
  334. +INSERT INTO creature_template_addon VALUES (27692, 0, 0, 0, 0, 0, 181, NULL, '48602 0 48602 2');
  335. +REPLACE INTO vehicle_data VALUES (181, 12, 50328, 50341, 50344, 0, 0, 0, 0, 0, 0, 0, 0);
  336. +REPLACE INTO vehicle_seat_data VALUES (2081, 3);
  337. +/* Ruby Drake */
  338. +INSERT INTO spell_script_target VALUES (49464, 1, 27756);
  339. +INSERT INTO npc_spellclick_spells VALUES (27756, 49463, 0, 0, 0, 1);
  340. +INSERT INTO creature_template_addon VALUES (27756, 0, 0, 0, 0, 0, 186, NULL, '48602 0 48602 2');
  341. +REPLACE INTO vehicle_data VALUES (186, 12, 50232, 50248, 50240, 0, 0, 0, 0, 0, 0, 0, 0);
  342. +REPLACE INTO vehicle_seat_data VALUES (2089, 3);
  343. +
  344. +/* vehicle accessory */
  345. +REPLACE INTO creature_template_addon (`entry`,`passengers`) values (27850,'27905 1');
  346. +REPLACE INTO creature_template_addon (`entry`,`vehicle_id`,`passengers`) values
  347. +(32930,328,'32933 1 32934 7'),(33114,341,'33142 1 33143 2'),(33214,348,'33218 1'),(33113,387,'33114 0 33114 1 33114 2 33114 3 33139 7');
  348. +
  349. +/* 7th Legion Chain Gun */
  350. +DELETE FROM npc_spellclick_spells WHERE npc_entry IN (27714);
  351. +INSERT INTO npc_spellclick_spells VALUES (27714, 65403, 0, 0, 0, 1);
  352. +REPLACE INTO creature_template_addon VALUES (27714, 0, 0, 0, 0, 0, 68, NULL, NULL);
  353. +REPLACE INTO vehicle_data VALUES (68, 5, 49190, 49550, 0, 0, 0, 0, 0, 0, 0, 0, 0);
  354. +REPLACE INTO vehicle_seat_data VALUES (1301, 1);
  355. +UPDATE creature_template SET IconName = 'Gunner' WHERE entry IN (27714);
  356. +
  357. +/* Alliance Steam Tank */
  358. +DELETE FROM npc_spellclick_spells WHERE npc_entry IN (27587);
  359. +INSERT INTO npc_spellclick_spells VALUES (27587, 43695, 0, 0, 0, 0);
  360. +REPLACE INTO creature_template_addon VALUES (27587, 0, 0, 0, 0, 0, 56, NULL, NULL);
  361. +REPLACE INTO vehicle_data VALUES (56, 4, 49315, 49333, 49109, 49081, 0, 0, 0, 0, 0, 0, 0);
  362. +REPLACE INTO vehicle_seat_data VALUES (945, 3),(946, 8),(949, 8),(950, 8);
  363. +REPLACE INTO spell_area (`spell`,`area`) VALUES (49081, 4246);
  364. +UPDATE creature_template SET modelid_1 = 25341, modelid_2 = 0, modelid_3 = 0, IconName = 'vehichleCursor' WHERE entry IN (27587);
  365. +UPDATE creature_model_info SET modelid_other_gender = 0 WHERE modelid = 25341;
  366. +-- UPDATE creature_template_addon SET passengers = '27163 1 27588 2 27588 3' WHERE entry = 27587;
  367. +
  368. +/* Broken-down Shredder */
  369. +DELETE FROM npc_spellclick_spells WHERE npc_entry IN (27354);
  370. +INSERT INTO npc_spellclick_spells VALUES (27354, 65403, 0, 0, 0, 1);
  371. +REPLACE INTO creature_template_addon VALUES (27354, 0, 0, 0, 0, 0, 49, NULL, NULL);
  372. +REPLACE INTO vehicle_data VALUES (49, 4, 48558, 48604, 48548, 0, 48610, 0, 0, 0, 0, 0, 0);
  373. +REPLACE INTO vehicle_seat_data VALUES (821, 1);
  374. +UPDATE creature_template SET IconName = 'vehichleCursor' WHERE entry IN (27354);
  375. +
  376. +/* Enraged Mammoth */
  377. +DELETE FROM npc_spellclick_spells WHERE npc_entry IN (28851);
  378. +INSERT INTO npc_spellclick_spells VALUES (28851, 65403, 0, 0, 0, 1);
  379. +REPLACE INTO creature_template_addon VALUES (28851, 0, 0, 0, 0, 0, 145, NULL, NULL);
  380. +REPLACE INTO vehicle_data VALUES (145, 4, 52603, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
  381. +REPLACE INTO vehicle_seat_data VALUES (1906, 3);
  382. +UPDATE creature_template SET IconName = 'vehichleCursor' WHERE entry IN (28851);
  383. +
  384. +/* Flamebringer */
  385. +DELETE FROM npc_spellclick_spells WHERE npc_entry IN (27292);
  386. +INSERT INTO npc_spellclick_spells VALUES (27292, 65403, 0, 0, 0, 1);
  387. +REPLACE INTO creature_template_addon VALUES (27292, 0, 0, 0, 0, 0, 50, NULL, NULL);
  388. +REPLACE INTO vehicle_data VALUES (50, 4, 48619, 48620, 52812, 0, 0, 0, 0, 0, 0, 0, 0);
  389. +REPLACE INTO vehicle_seat_data VALUES (841, 3);
  390. +UPDATE creature_template SET IconName = 'vehichleCursor' WHERE entry IN (27292);
  391. +
  392. +/* Forsaken Blight Spreader */
  393. +DELETE FROM npc_spellclick_spells WHERE npc_entry IN (26523);
  394. +INSERT INTO npc_spellclick_spells VALUES (26523, 47961, 0, 0, 0, 1);
  395. +REPLACE INTO creature_template_addon VALUES (26523, 0, 0, 0, 0, 0, 36, NULL, NULL);
  396. +REPLACE INTO vehicle_data VALUES (36, 4, 48211, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
  397. +REPLACE INTO vehicle_seat_data VALUES (644, 3);
  398. +UPDATE creature_template SET IconName = 'vehichleCursor' WHERE entry = 26523;
  399. +
  400. +/* Highland Mustang */
  401. +DELETE FROM npc_spellclick_spells WHERE npc_entry IN (26472);
  402. +INSERT INTO npc_spellclick_spells VALUES (26472, 65403, 0, 0, 0, 1);
  403. +REPLACE INTO creature_template_addon VALUES (26472, 0, 0, 0, 0, 0, 62, NULL, NULL);
  404. +REPLACE INTO vehicle_data VALUES (62, 4, 49285, 29577, 0, 0, 0, 0, 0, 0, 0, 0, 0);
  405. +REPLACE INTO vehicle_seat_data VALUES (1270, 3);
  406. +UPDATE creature_template SET IconName = 'vehichleCursor' WHERE entry IN (26472);
  407. +
  408. +/* Horde Siege Tank */
  409. +DELETE FROM npc_spellclick_spells WHERE npc_entry IN (25334);
  410. +INSERT INTO npc_spellclick_spells VALUES (25334, 43695, 0, 0, 0, 0);
  411. +REPLACE INTO creature_template_addon VALUES (25334, 0, 0, 0, 0, 0, 26, NULL, NULL);
  412. +REPLACE INTO vehicle_data VALUES (26, 4, 50672, 45750, 50677, 47849, 47962, 0, 0, 0, 0, 0, 0);
  413. +REPLACE INTO vehicle_seat_data VALUES (365,3),(366,6),(367,6),(368,6);
  414. +UPDATE creature_template SET IconName = 'vehichleCursor' WHERE entry = 25334;
  415. +
  416. +/* Infected Kodo Beast */
  417. +DELETE FROM npc_spellclick_spells WHERE npc_entry IN (25596);
  418. +INSERT INTO npc_spellclick_spells VALUES (25596, 45875, 11690, 1, 11690, 1);
  419. +REPLACE INTO creature_template_addon VALUES (25596, 0, 0, 0, 0, 0, 29, NULL, NULL);
  420. +REPLACE INTO vehicle_data VALUES (29, 12, 45876, 45877, 0, 0, 0, 0, 0, 0, 0, 0, 0);
  421. +REPLACE INTO vehicle_seat_data VALUES (422, 3);
  422. +UPDATE creature_template SET speed_run = 2, IconName = 'vehichleCursor' WHERE entry = 25596;
  423. +REPLACE INTO spell_script_target VALUES (45877, 1, 25596);
  424. +
  425. +/* Kor'kron War Rider */
  426. +DELETE FROM npc_spellclick_spells WHERE npc_entry IN (26813);
  427. +INSERT INTO npc_spellclick_spells VALUES (26813, 47424, 0, 0, 0, 1);
  428. +REPLACE INTO creature_template_addon VALUES (26813, 0, 0, 0, 0, 0, 80, NULL, '48602 0 48602 2');
  429. +REPLACE INTO vehicle_data VALUES (80, 4, 47434, 63507, 47454, 0, 0, 0, 0, 0, 0, 0, 0);
  430. +REPLACE INTO vehicle_seat_data VALUES (1431, 3),(1432, 2);
  431. +UPDATE creature_template SET modelid_2 = 0, modelid_3 = 0, IconName = 'vehichleCursor' WHERE entry IN (26813);
  432. +
  433. +/* Kor'kron War Rider II */
  434. +DELETE FROM npc_spellclick_spells WHERE npc_entry IN (26572);
  435. +INSERT INTO npc_spellclick_spells VALUES (26572, 47424, 0, 0, 0, 1);
  436. +REPLACE INTO creature_template_addon VALUES (26572, 0, 0, 0, 0, 0, 34, NULL, '48602 0 48602 2');
  437. +REPLACE INTO vehicle_data VALUES (34, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
  438. +REPLACE INTO vehicle_seat_data VALUES (601, 3);
  439. +UPDATE creature_template SET IconName = 'vehichleCursor' WHERE entry IN (26572);
  440. +
  441. +/* Onslaught Warhorse */
  442. +DELETE FROM npc_spellclick_spells WHERE npc_entry IN (27213);
  443. +INSERT INTO npc_spellclick_spells VALUES (27213, 65403, 0, 0, 0, 1);
  444. +REPLACE INTO creature_template_addon VALUES (27213, 0, 0, 0, 0, 0, 43, NULL, NULL);
  445. +REPLACE INTO vehicle_data VALUES (43, 4, 48297, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
  446. +REPLACE INTO vehicle_seat_data VALUES (742, 3);
  447. +UPDATE creature_template SET IconName = 'vehichleCursor' WHERE entry = 27213;
  448. +
  449. +/* Refurbished Shredder */
  450. +DELETE FROM npc_spellclick_spells WHERE npc_entry IN (27496);
  451. +INSERT INTO npc_spellclick_spells VALUES (27496, 60944, 0, 0, 0, 1);
  452. +REPLACE INTO creature_template_addon VALUES (27496, 0, 0, 0, 0, 0, 55, NULL, NULL);
  453. +REPLACE INTO vehicle_data VALUES (55, 4, 48548, 48604, 48558, 0, 48610, 0, 0, 0, 0, 0, 0);
  454. +REPLACE INTO vehicle_seat_data VALUES (922, 1);
  455. +UPDATE creature_template SET IconName = 'vehichleCursor' WHERE entry IN (27496);
  456. +
  457. +/* Rocket Propelled Warhead */
  458. +DELETE FROM npc_spellclick_spells WHERE npc_entry IN (27593);
  459. +INSERT INTO npc_spellclick_spells VALUES (27593, 49177, 0, 0, 0, 1);
  460. +REPLACE INTO creature_template_addon VALUES (27593, 0, 0, 0, 0, 0, 57, NULL, NULL);
  461. +REPLACE INTO vehicle_data VALUES (57, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
  462. +REPLACE INTO vehicle_seat_data VALUES (961, 1);
  463. +UPDATE creature_template SET IconName = 'vehichleCursor' WHERE entry IN (27593);
  464. +
  465. +/* Steel Gate Flying Machine */
  466. +DELETE FROM npc_spellclick_spells WHERE npc_entry IN (24418);
  467. +INSERT INTO npc_spellclick_spells VALUES (24418, 65403, 0, 0, 0, 1);
  468. +REPLACE INTO creature_template_addon VALUES (24418, 0, 0, 0, 0, 0, 8, NULL, '48602 0 48602 2');
  469. +REPLACE INTO vehicle_data VALUES (8, 4, 44009, 43770, 43799, 43769, 47769, 0, 0, 0, 0, 0, 0);
  470. +REPLACE INTO vehicle_seat_data VALUES (261, 1),(461, 2);
  471. +UPDATE creature_template SET IconName = 'vehichleCursor', InhabitType = 3 WHERE entry IN (24418);
  472. +
  473. +/* Wintergarde Gryphon */
  474. +DELETE FROM npc_spellclick_spells WHERE npc_entry IN (27258);
  475. +INSERT INTO npc_spellclick_spells VALUES (27258, 49288, 0, 0, 0, 1);
  476. +REPLACE INTO creature_template_addon VALUES (27258, 0, 0, 0, 0, 0, 44, NULL, '48602 0 48602 2');
  477. +REPLACE INTO vehicle_data VALUES (44, 4, 48363, 48397, 54170, 0, 0, 0, 0, 0, 0, 0, 0);
  478. +REPLACE INTO vehicle_seat_data VALUES (762, 1),(764, 2);
  479. +UPDATE creature_template SET IconName = 'vehichleCursor', InhabitType = 3 WHERE entry IN (27258);
  480. +
  481. +/* Wintergarde Gryphon II, Into Hostile Territory quest */
  482. +DELETE FROM npc_spellclick_spells WHERE npc_entry IN (27661);
  483. +INSERT INTO npc_spellclick_spells VALUES (27661, 48862, 0, 0, 0, 1);
  484. +REPLACE INTO creature_template_addon VALUES (27661, 0, 0, 0, 0, 0, 61, NULL, '48602 0 48602 2');
  485. +REPLACE INTO vehicle_data VALUES (61, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
  486. +REPLACE INTO vehicle_seat_data VALUES (1267, 1),(1268, 2);
  487. +UPDATE creature_template SET IconName = 'vehichleCursor', InhabitType = 3 WHERE entry IN (27661);
  488. +
  489. +/* Wooly Mammoth Bull */
  490. +DELETE FROM npc_spellclick_spells WHERE npc_entry IN (25743);
  491. +INSERT INTO npc_spellclick_spells VALUES (25743, 43695, 11879, 1, 11879, 1);
  492. +REPLACE INTO creature_template_addon VALUES (25743, 0, 0, 0, 0, 0, 72, NULL, NULL);
  493. +REPLACE INTO vehicle_data VALUES (72, 12, 46317, 46315, 46316, 0, 0, 0, 0, 0, 0, 0, 0);
  494. +REPLACE INTO vehicle_seat_data VALUES (1362, 3);
  495. +UPDATE creature_template SET faction_A = 7, faction_H = 7, IconName = 'vehichleCursor' WHERE entry IN (25743);
  496. +
  497. +/* Wyrmrest Defender */
  498. +DELETE FROM npc_spellclick_spells WHERE npc_entry IN (27629);
  499. +INSERT INTO npc_spellclick_spells VALUES (27629, 49256, 12372, 1, 12372, 1);
  500. +REPLACE INTO creature_template_addon VALUES (27629,0,50331648,1,0,0,60,NULL,'50069 0 50069 1 50069 2');
  501. +REPLACE INTO vehicle_data VALUES (60,4,49161,49243,49263,49264,49367,0,0,0,0,0,0);
  502. +REPLACE INTO vehicle_seat_data VALUES (1262, 3);
  503. +UPDATE creature_template SET IconName = 'vehichleCursor', InhabitType = 3 WHERE entry IN (27629);
  504. +
  505. +/* Wyrmrest Skytalon */
  506. +DELETE FROM npc_spellclick_spells WHERE npc_entry = 32535;
  507. +INSERT INTO npc_spellclick_spells VALUES (32535, 61245, 0, 0, 0, 1);
  508. +REPLACE INTO creature_template_addon VALUES (32535, 0, 0, 0, 0, 0, 165, NULL, '48602 0 48602 2');
  509. +REPLACE INTO vehicle_data VALUES (165, 12, 56091, 61621, 57090, 57143, 57108, 57092, 0, 0, 0, 0, 0);
  510. +REPLACE INTO vehicle_seat_data VALUES (2061, 3);
  511. +REPLACE INTO spell_script_target VALUES (61245,1,32535);
  512. +UPDATE creature_template SET IconName = 'vehichleCursor', InhabitType = 3 WHERE entry = 32535;
  513. +
  514. +/* Wyrmrest Vanquisher */
  515. +DELETE FROM npc_spellclick_spells WHERE npc_entry IN (27996);
  516. +INSERT INTO npc_spellclick_spells VALUES (27996, 65403, 0, 0, 0, 1);
  517. +REPLACE INTO creature_template_addon VALUES (27996, 0, 50331648, 1, 0, 0, 99, NULL, '48602 0 48602 2');
  518. +REPLACE INTO vehicle_data VALUES (99, 4, 50430, 55987, 50348, 0, 0, 0, 0, 0, 0, 0, 0);
  519. +REPLACE INTO vehicle_seat_data VALUES (1520, 3),(1521, 8);
  520. +UPDATE creature_template SET IconName = 'vehichleCursor', InhabitType = 3 WHERE entry IN (27996);
  521. +
  522. +/* Fizzcrank Bomber */
  523. +DELETE FROM npc_spellclick_spells WHERE npc_entry IN (25765);
  524. +INSERT INTO npc_spellclick_spells VALUES (25765, 65403, 0, 0, 0, 1);
  525. +REPLACE INTO creature_template_addon VALUES (25765, 0, 0, 0, 0, 0, 492, NULL, '48602 0 48602 2');
  526. +REPLACE INTO vehicle_data VALUES (492, 4, 45971, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
  527. +REPLACE INTO vehicle_seat_data VALUES (5506, 3);
  528. +UPDATE creature_template SET IconName = 'vehichleCursor', InhabitType = 3 WHERE entry IN (25765);
  529. +
  530. +/* Dusk */
  531. +DELETE FROM npc_spellclick_spells WHERE npc_entry IN (26191);
  532. +INSERT INTO npc_spellclick_spells VALUES (26191, 65403, 0, 0, 0, 1);
  533. +REPLACE INTO creature_template_addon VALUES (26191, 0, 0, 0, 0, 0, 200, NULL, NULL);
  534. +REPLACE INTO vehicle_data VALUES (200, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
  535. +REPLACE INTO vehicle_seat_data VALUES (2144, 3);
  536. +UPDATE creature_template SET IconName = 'vehichleCursor' WHERE entry IN (26191);
  537. +
  538. +/* Tatjana's Horse */
  539. +DELETE FROM npc_spellclick_spells WHERE npc_entry IN (27626);
  540. +INSERT INTO npc_spellclick_spells VALUES (27626, 65403, 0, 0, 0, 1);
  541. +REPLACE INTO creature_template_addon VALUES (27626, 0, 0, 0, 0, 0, 59, NULL, NULL);
  542. +REPLACE INTO vehicle_data VALUES (59, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
  543. +REPLACE INTO vehicle_seat_data VALUES (1241, 3),(1242, 2);
  544. +UPDATE creature_template SET IconName = 'vehichleCursor' WHERE entry IN (27626);
  545. +
  546. +/* Antipersonnel Cannon */
  547. +DELETE FROM npc_spellclick_spells WHERE npc_entry IN (27894);
  548. +INSERT INTO npc_spellclick_spells VALUES (27894, 65403, 0, 0, 0, 1);
  549. +REPLACE INTO creature_template_addon VALUES (27894, 0, 0, 0, 0, 0, 160, NULL, NULL);
  550. +REPLACE INTO vehicle_data VALUES (160, 5, 49872, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
  551. +REPLACE INTO vehicle_seat_data VALUES (2029, 3);
  552. +UPDATE creature_template SET IconName = 'Gunner' WHERE entry IN (27894);
  553. +
  554. +/* Antipersonnel Cannon II */
  555. +DELETE FROM npc_spellclick_spells WHERE npc_entry IN (32795);
  556. +INSERT INTO npc_spellclick_spells VALUES (32795, 65403, 0, 0, 0, 1);
  557. +REPLACE INTO creature_template_addon VALUES (32795, 0, 0, 0, 0, 0, 160, NULL, NULL);
  558. +REPLACE INTO vehicle_data VALUES (160, 5, 49872, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
  559. +REPLACE INTO vehicle_seat_data VALUES (2029, 3);
  560. +UPDATE creature_template SET IconName = 'Gunner' WHERE entry IN (32795);
  561. +
  562. +/* Wintergrasp Demolisher */
  563. +UPDATE creature_template SET maxhealth = 50000, minhealth = 50000 WHERE entry = 28094;
  564. +DELETE FROM npc_spellclick_spells WHERE npc_entry IN (28094);
  565. +INSERT INTO npc_spellclick_spells VALUES (28094, 60968, 0, 0, 0, 1);
  566. +REPLACE INTO creature_template_addon VALUES (28094, 0, 0, 0, 0, 0, 106, NULL, NULL);
  567. +REPLACE INTO vehicle_data VALUES (106, 4, 50896, 50652, 0, 0, 0, 0, 0, 0, 0, 0, 0);
  568. +REPLACE INTO vehicle_seat_data VALUES (1554, 3),(1556, 6),(1557, 6);
  569. +UPDATE creature_template SET IconName = 'vehichleCursor' WHERE entry IN (28094);
  570. +
  571. +/* Wintergrasp Siege Engine */
  572. +UPDATE creature_template SET maxhealth = 75000, minhealth = 75000 WHERE entry IN (28312,32627);
  573. +DELETE FROM npc_spellclick_spells WHERE npc_entry IN (28312);
  574. +INSERT INTO npc_spellclick_spells VALUES (28312, 60968, 0, 0, 0, 1);
  575. +REPLACE INTO creature_template_addon VALUES (28312, 0, 0, 0, 0, 0, 117, '28319 7', NULL);
  576. +REPLACE INTO vehicle_data VALUES (117, 4, 51678, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
  577. +REPLACE INTO vehicle_seat_data VALUES (1648, 3),(1649, 2),(1650, 2),(1652, 4);
  578. +UPDATE creature_template SET IconName = 'vehichleCursor' WHERE entry IN (28312);
  579. +
  580. +/* Wintergrasp Siege Engine II */
  581. +DELETE FROM npc_spellclick_spells WHERE npc_entry IN (32627);
  582. +INSERT INTO npc_spellclick_spells VALUES (32627, 60968, 0, 0, 0, 1);
  583. +REPLACE INTO creature_template_addon VALUES (32627, 0, 0, 0, 0, 0, 324, '32629 7', NULL);
  584. +REPLACE INTO vehicle_data VALUES (324, 4, 51678, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
  585. +REPLACE INTO vehicle_seat_data VALUES (2863, 3),(2864, 2),(2865, 2),(2866, 2);
  586. +UPDATE creature_template SET IconName = 'vehichleCursor' WHERE entry IN (32627);
  587. +
  588. +/* Wintergrasp Siege Turret */
  589. +UPDATE creature_template SET maxhealth = 50000, minhealth = 50000 WHERE entry IN (28319,32629);
  590. +DELETE FROM npc_spellclick_spells WHERE npc_entry IN (28319);
  591. +INSERT INTO npc_spellclick_spells VALUES (28319, 60968, 0, 0, 0, 1);
  592. +REPLACE INTO creature_template_addon VALUES (28319, 0, 0, 0, 0, 0, 116, NULL, NULL);
  593. +REPLACE INTO vehicle_data VALUES (116, 5, 51362, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
  594. +REPLACE INTO vehicle_seat_data VALUES (1643, 3);
  595. +UPDATE creature_template SET IconName = 'Gunner' WHERE entry IN (28319);
  596. +
  597. +/* Wintergrasp Siege Turret II */
  598. +DELETE FROM npc_spellclick_spells WHERE npc_entry IN (32629);
  599. +INSERT INTO npc_spellclick_spells VALUES (32629, 60968, 0, 0, 0, 1);
  600. +REPLACE INTO creature_template_addon VALUES (32629, 0, 0, 0, 0, 0, 116, NULL, NULL);
  601. +REPLACE INTO vehicle_data VALUES (116, 5, 51362, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
  602. +REPLACE INTO vehicle_seat_data VALUES (1643, 3);
  603. +UPDATE creature_template SET IconName = 'Gunner' WHERE entry IN (32629);
  604. +
  605. +/* Battleground Demolisher */
  606. +DELETE FROM npc_spellclick_spells WHERE npc_entry IN (28781);
  607. +INSERT INTO npc_spellclick_spells VALUES (28781, 65403, 0, 0, 0, 1);
  608. +REPLACE INTO creature_template_addon VALUES (28781, 0, 0, 0, 0, 0, 158, NULL, NULL);
  609. +REPLACE INTO vehicle_data VALUES (158, 4, 52338, 60206, 0, 0, 0, 0, 0, 0, 0, 0, 0);
  610. +REPLACE INTO vehicle_seat_data VALUES (2021, 3),(2023, 2),(2024, 2);
  611. +UPDATE creature_template SET IconName = 'vehichleCursor' WHERE entry IN (28781);
  612. +
  613. +/* Battleground Demolisher II */
  614. +DELETE FROM npc_spellclick_spells WHERE npc_entry IN (32796);
  615. +INSERT INTO npc_spellclick_spells VALUES (32796, 65403, 0, 0, 0, 1);
  616. +REPLACE INTO creature_template_addon VALUES (32796, 0, 0, 0, 0, 0, 158, NULL, NULL);
  617. +REPLACE INTO vehicle_data VALUES (158, 4, 52338, 60206, 0, 0, 0, 0, 0, 0, 0, 0, 0);
  618. +REPLACE INTO vehicle_seat_data VALUES (2021, 3),(2023, 2),(2024, 2);
  619. +UPDATE creature_template SET IconName = 'vehichleCursor' WHERE entry IN (32796);
  620. +
  621. +/* Frostbite */
  622. +DELETE FROM npc_spellclick_spells WHERE npc_entry IN (29857);
  623. +INSERT INTO npc_spellclick_spells VALUES (29857, 65403, 0, 0, 0, 1);
  624. +REPLACE INTO creature_template_addon VALUES (29857, 0, 0, 0, 0, 0, 202, NULL, NULL);
  625. +REPLACE INTO vehicle_data VALUES (202, 4, 54996, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
  626. +REPLACE INTO vehicle_seat_data VALUES (2164, 3);
  627. +UPDATE creature_template SET IconName = 'vehichleCursor' WHERE entry IN (29857);
  628. +
  629. +/* Valkyrion Harpoon Gun */
  630. +DELETE FROM npc_spellclick_spells WHERE npc_entry IN (30066);
  631. +INSERT INTO npc_spellclick_spells VALUES (30066, 44002, 12953, 1, 12953, 1);
  632. +REPLACE INTO creature_template_addon VALUES (30066, 0, 0, 0, 0, 0, 213, NULL, NULL);
  633. +REPLACE INTO vehicle_data VALUES (213, 5, 55812, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
  634. +REPLACE INTO vehicle_seat_data VALUES (2186, 1);
  635. +UPDATE creature_template SET IconName = 'Gunner' WHERE entry IN (30066);
  636. +
  637. +/* Argent Skytalon */
  638. +DELETE FROM npc_spellclick_spells WHERE npc_entry IN (30228);
  639. +INSERT INTO npc_spellclick_spells VALUES (30228, 65403, 0, 0, 0, 1);
  640. +REPLACE INTO creature_template_addon VALUES (30228, 0, 50331648, 1, 0, 0, 234, NULL, '48602 0 48602 2');
  641. +REPLACE INTO vehicle_data VALUES (234, 4, 56683, 56684, 56712, 0, 0, 0, 0, 0, 0, 0, 0);
  642. +REPLACE INTO vehicle_seat_data VALUES (2235, 1),(2236, 8);
  643. +UPDATE creature_template SET IconName = 'vehichleCursor', InhabitType = 3 WHERE entry IN (30228);
  644. +
  645. +/* Jotunheim Rapid-Fire Harpoon */
  646. +DELETE FROM npc_spellclick_spells WHERE npc_entry IN (30337);
  647. +INSERT INTO npc_spellclick_spells VALUES (30337, 65403, 0, 0, 0, 1);
  648. +REPLACE INTO creature_template_addon VALUES (30337, 0, 0, 0, 0, 0, 229, NULL, NULL);
  649. +REPLACE INTO vehicle_data VALUES (229, 5, 0, 0, 56570, 0, 0, 0, 0, 0, 0, 0, 0);
  650. +REPLACE INTO vehicle_seat_data VALUES (2229, 1);
  651. +UPDATE creature_template SET IconName = 'Gunner' WHERE entry IN (30337);
  652. +
  653. +/* Nergeld */
  654. +DELETE FROM npc_spellclick_spells WHERE npc_entry IN (30403);
  655. +INSERT INTO npc_spellclick_spells VALUES (30403, 56699, 0, 0, 0, 1);
  656. +REPLACE INTO creature_template_addon VALUES (30403, 0, 0, 0, 0, 0, 236, NULL, NULL);
  657. +REPLACE INTO vehicle_data VALUES (236, 4, 60540, 56746, 56748, 56747, 0, 0, 0, 0, 0, 0, 0);
  658. +REPLACE INTO vehicle_seat_data VALUES (2238, 3);
  659. +UPDATE creature_template SET IconName = 'vehichleCursor' WHERE entry IN (30403);
  660. +
  661. +/* Kor'kron Suppression Turret */
  662. +DELETE FROM npc_spellclick_spells WHERE npc_entry IN (31884);
  663. +INSERT INTO npc_spellclick_spells VALUES (31884, 65403, 0, 0, 0, 1);
  664. +REPLACE INTO creature_template_addon VALUES (31884, 0, 0, 0, 0, 0, 291, NULL, NULL);
  665. +REPLACE INTO vehicle_data VALUES (291, 5, 59880, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
  666. +REPLACE INTO vehicle_seat_data VALUES (2553, 3);
  667. +UPDATE creature_template SET IconName = 'Gunner' WHERE entry IN (31884);
  668. +
  669. +/* Flame Leviathan Seat */
  670. +DELETE FROM npc_spellclick_spells WHERE npc_entry IN (33114);
  671. +-- INSERT INTO npc_spellclick_spells VALUES (33114, 65403, 0, 0, 0, 1);
  672. +REPLACE INTO creature_template_addon VALUES (33114, 0, 0, 0, 0, 0, 341, NULL, NULL);
  673. +REPLACE INTO vehicle_data VALUES (341, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
  674. +REPLACE INTO vehicle_seat_data VALUES (3044, 1),(3075, 0),(3076, 0);
  675. +UPDATE creature_template SET IconName = 'Gunner' WHERE entry IN (33114);
  676. +
  677. +/* Brann's Flying Machine */
  678. +DELETE FROM npc_spellclick_spells WHERE npc_entry IN (34120);
  679. +INSERT INTO npc_spellclick_spells VALUES (34120, 65403, 0, 0, 0, 1);
  680. +REPLACE INTO creature_template_addon VALUES (34120, 0, 0, 0, 0, 0, 390, NULL, '48602 0 48602 2');
  681. +REPLACE INTO vehicle_data VALUES (390, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
  682. +REPLACE INTO vehicle_seat_data VALUES (3926, 3);
  683. +UPDATE creature_template SET IconName = 'vehichleCursor' WHERE entry IN (34120);
  684. +
  685. +/* Catapult */
  686. +DELETE FROM npc_spellclick_spells WHERE npc_entry IN (34793);
  687. +INSERT INTO npc_spellclick_spells VALUES (34793, 65403, 0, 0, 0, 1);
  688. +REPLACE INTO creature_template_addon VALUES (34793, 0, 0, 0, 0, 0, 438, NULL, NULL);
  689. +REPLACE INTO vehicle_data VALUES (438, 4, 66218, 66296, 0, 0, 0, 0, 0, 0, 0, 0, 0);
  690. +REPLACE INTO vehicle_seat_data VALUES (4706, 3),(4726, 2);
  691. +UPDATE creature_template SET IconName = 'vehichleCursor' WHERE entry IN (34793);
  692. +
  693. +/* Argent Warhorse */
  694. +DELETE FROM npc_spellclick_spells WHERE npc_entry IN (36557,35644);
  695. +INSERT INTO npc_spellclick_spells VALUES (36557, 65403, 0, 0, 0, 1),(35644, 65403, 0, 0, 0, 1);
  696. +REPLACE INTO creature_template_addon VALUES (36557, 0, 0, 0, 0, 0, 486, NULL, NULL),(35644, 0, 0, 0, 0, 0, 486, NULL, NULL);
  697. +REPLACE INTO vehicle_data VALUES (486, 4, 68505, 62575, 68282, 66482, 0, 0, 0, 0, 0, 0, 0);
  698. +REPLACE INTO vehicle_seat_data VALUES (5406, 3);
  699. +UPDATE creature_template SET IconName = 'vehichleCursor' WHERE entry IN (36557,35644);
  700. +
  701. +/* Argent Battleworg */
  702. +DELETE FROM npc_spellclick_spells WHERE npc_entry IN (36559,36558);
  703. +INSERT INTO npc_spellclick_spells VALUES (36559, 65403, 0, 0, 0, 1),(36558, 65403, 0, 0, 0, 1);
  704. +REPLACE INTO creature_template_addon VALUES (36559, 0, 0, 0, 0, 0, 529, NULL, NULL),(36558, 0, 0, 0, 0, 0, 529, NULL, NULL);
  705. +REPLACE INTO vehicle_data VALUES (529, 4, 68282, 62575, 0, 0, 0, 0, 0, 0, 0, 0, 0);
  706. +REPLACE INTO vehicle_seat_data VALUES (6126, 3);
  707. +UPDATE creature_template SET IconName = 'vehichleCursor' WHERE entry IN (36559,36558);
  708. +
  709. +/* Keep Cannon */
  710. +DELETE FROM npc_spellclick_spells WHERE npc_entry IN (34944);
  711. +INSERT INTO npc_spellclick_spells VALUES (34944, 65403, 0, 0, 0, 1);
  712. +REPLACE INTO creature_template_addon VALUES (34944, 0, 0, 0, 0, 0, 510, NULL, NULL);
  713. +REPLACE INTO vehicle_data VALUES (510, 5, 68169, 66541, 68170, 67452, 0, 0, 0, 0, 0, 0, 0);
  714. +REPLACE INTO vehicle_seat_data VALUES (5786, 3);
  715. +UPDATE creature_template SET IconName = 'Gunner' WHERE entry IN (34944);
  716. +
  717. +/* Alliance Gunship Cannon */
  718. +DELETE FROM npc_spellclick_spells WHERE npc_entry IN (34929);
  719. +INSERT INTO npc_spellclick_spells VALUES (34929, 65403, 0, 0, 0, 1);
  720. +REPLACE INTO creature_template_addon VALUES (34929, 0, 0, 0, 0, 0, 452, NULL, NULL);
  721. +REPLACE INTO vehicle_data VALUES (452, 5, 69495, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
  722. +REPLACE INTO vehicle_seat_data VALUES (4888, 3);
  723. +UPDATE creature_template SET IconName = 'Gunner' WHERE entry IN (34929);
  724. +
  725. +/* Alliance Gunship Cannon II */
  726. +DELETE FROM npc_spellclick_spells WHERE npc_entry IN (36838);
  727. +INSERT INTO npc_spellclick_spells VALUES (36838, 65403, 0, 0, 0, 1);
  728. +REPLACE INTO creature_template_addon VALUES (36838, 0, 0, 0, 0, 0, 554, NULL, NULL);
  729. +REPLACE INTO vehicle_data VALUES (554, 5, 70174, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
  730. +REPLACE INTO vehicle_seat_data VALUES (6488, 3);
  731. +UPDATE creature_template SET IconName = 'Gunner' WHERE entry IN (36838);
  732. +
  733. +/* Horde Gunship Cannon */
  734. +DELETE FROM npc_spellclick_spells WHERE npc_entry IN (34935);
  735. +INSERT INTO npc_spellclick_spells VALUES (34935, 65403, 0, 0, 0, 1);
  736. +REPLACE INTO creature_template_addon VALUES (34935, 0, 0, 0, 0, 0, 453, NULL, NULL);
  737. +REPLACE INTO vehicle_data VALUES (453, 5, 68825, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
  738. +REPLACE INTO vehicle_seat_data VALUES (4906, 3);
  739. +UPDATE creature_template SET IconName = 'Gunner' WHERE entry IN (34935);
  740. +
  741. +/* Demolisher */
  742. +DELETE FROM npc_spellclick_spells WHERE npc_entry IN (34775);
  743. +INSERT INTO npc_spellclick_spells VALUES (34775, 65403, 0, 0, 0, 1);
  744. +REPLACE INTO creature_template_addon VALUES (34775, 0, 0, 0, 0, 0, 509, NULL, NULL);
  745. +REPLACE INTO vehicle_data VALUES (509, 4, 68068, 67440, 67442, 67441, 0, 0, 0, 0, 0, 0, 0);
  746. +REPLACE INTO vehicle_seat_data VALUES (5766, 3),(5767, 2),(5768, 2);
  747. +UPDATE creature_template SET IconName = 'vehichleCursor' WHERE entry IN (34775);
  748. +
  749. +/* Broken Keep Cannon */
  750. +DELETE FROM npc_spellclick_spells WHERE npc_entry IN (35819);
  751. +INSERT INTO npc_spellclick_spells VALUES (35819, 65403, 0, 0, 0, 1);
  752. +REPLACE INTO creature_template_addon VALUES (35819, 0, 0, 0, 0, 0, 655, NULL, NULL);
  753. +REPLACE INTO vehicle_data VALUES (655, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
  754. +UPDATE creature_template SET IconName = 'Gunner' WHERE entry IN (35819);
  755. +
  756. +/* Flame Turret */
  757. +DELETE FROM npc_spellclick_spells WHERE npc_entry IN (36356);
  758. +INSERT INTO npc_spellclick_spells VALUES (36356, 65403, 0, 0, 0, 1);
  759. +REPLACE INTO creature_template_addon VALUES (36356, 0, 0, 0, 0, 0, 436, NULL, NULL);
  760. +REPLACE INTO vehicle_data VALUES (436, 5, 68832, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
  761. +REPLACE INTO vehicle_seat_data VALUES (4690, 3);
  762. +UPDATE creature_template SET IconName = 'Gunner' WHERE entry IN (36356);
  763. diff --git a/src/game/AggressorAI.cpp b/src/game/AggressorAI.cpp
  764. index 615fd3f..4391b7b 100644
  765. --- a/src/game/AggressorAI.cpp
  766. +++ b/src/game/AggressorAI.cpp
  767. @@ -103,7 +103,7 @@ void AggressorAI::EnterEvadeMode()
  768.          //i_tracker.Reset(TIME_INTERVAL_LOOK);
  769.      }
  770.  
  771. -    if (!m_creature->isCharmed())
  772. +    if (!m_creature->isCharmed() && (!m_creature->GetVehicle() || !m_creature->GetVehicleGUID()))
  773.      {
  774.          m_creature->RemoveAllAuras();
  775.  
  776. diff --git a/src/game/BattleGroundMgr.cpp b/src/game/BattleGroundMgr.cpp
  777. index f0bef72..26c91bd 100644
  778. --- a/src/game/BattleGroundMgr.cpp
  779. +++ b/src/game/BattleGroundMgr.cpp
  780. @@ -1349,11 +1349,15 @@ void BattleGroundMgr::BuildPvpLogDataPacket(WorldPacket *data, BattleGround *bg)
  781.                  *data << (uint32)0x00000001;                // count of next fields
  782.                  *data << (uint32)((BattleGroundEYScore*)itr->second)->FlagCaptures;         // flag captures
  783.                  break;
  784. +            case BATTLEGROUND_SA:
  785. +                *data << (uint32)0x00000002;                // count of next fields
  786. +                *data << (uint32)((BattleGroundSAScore*)itr->second)->DemolishersDestroyed; // demolishers destroyed
  787. +                *data << (uint32)((BattleGroundSAScore*)itr->second)->GatesDestroyed;       // gates destroyed
  788. +                break;
  789.              case BATTLEGROUND_NA:
  790.              case BATTLEGROUND_BE:
  791.              case BATTLEGROUND_AA:
  792.              case BATTLEGROUND_RL:
  793. -            case BATTLEGROUND_SA:                           // wotlk
  794.              case BATTLEGROUND_DS:                           // wotlk
  795.              case BATTLEGROUND_RV:                           // wotlk
  796.              case BATTLEGROUND_IC:                           // wotlk
  797. diff --git a/src/game/BattleGroundSA.h b/src/game/BattleGroundSA.h
  798. index 31a3ffa..9324999 100644
  799. --- a/src/game/BattleGroundSA.h
  800. +++ b/src/game/BattleGroundSA.h
  801. @@ -24,8 +24,10 @@ class BattleGround;
  802.  class BattleGroundSAScore : public BattleGroundScore
  803.  {
  804.      public:
  805. -        BattleGroundSAScore() {};
  806. +        BattleGroundSAScore(): DemolishersDestroyed(0), GatesDestroyed(0) {};
  807.          virtual ~BattleGroundSAScore() {};
  808. +        uint32 DemolishersDestroyed;
  809. +        uint32 GatesDestroyed;
  810.  };
  811.  
  812.  class BattleGroundSA : public BattleGround
  813. diff --git a/src/game/Chat.cpp b/src/game/Chat.cpp
  814. index ab91c6e..28fe01b 100644
  815. --- a/src/game/Chat.cpp
  816. +++ b/src/game/Chat.cpp
  817. @@ -527,6 +527,8 @@ ChatCommand * ChatHandler::getCommandTable()
  818.          { "spell_scripts",               SEC_ADMINISTRATOR, true,  &ChatHandler::HandleReloadSpellScriptsCommand,            "", NULL },
  819.          { "spell_target_position",       SEC_ADMINISTRATOR, true,  &ChatHandler::HandleReloadSpellTargetPositionCommand,     "", NULL },
  820.          { "spell_threats",               SEC_ADMINISTRATOR, true,  &ChatHandler::HandleReloadSpellThreatsCommand,            "", NULL },
  821. +        { "vehicle_data",                SEC_ADMINISTRATOR, true,  &ChatHandler::HandleReloadVehicleDataCommand,             "", NULL },
  822. +        { "vehicle_seat_data",           SEC_ADMINISTRATOR, true,  &ChatHandler::HandleReloadVehicleSeatDataCommand,         "", NULL },
  823.  
  824.          { NULL,                          0,                 false, NULL,                                                     "", NULL }
  825.      };
  826. @@ -2039,7 +2041,7 @@ Creature* ChatHandler::getSelectedCreature()
  827.      if(!m_session)
  828.          return NULL;
  829.  
  830. -    return m_session->GetPlayer()->GetMap()->GetAnyTypeCreature(m_session->GetPlayer()->GetSelectionGuid());
  831. +    return ObjectAccessor::GetAnyTypeCreature(*m_session->GetPlayer(),m_session->GetPlayer()->GetSelectionGuid());
  832.  }
  833.  
  834.  /**
  835. diff --git a/src/game/Chat.h b/src/game/Chat.h
  836. index 9950ad4..204aa18 100644
  837. --- a/src/game/Chat.h
  838. +++ b/src/game/Chat.h
  839. @@ -445,6 +445,8 @@ class ChatHandler
  840.          bool HandleReloadSpellTargetPositionCommand(char* args);
  841.          bool HandleReloadSpellThreatsCommand(char* args);
  842.          bool HandleReloadSpellPetAurasCommand(char* args);
  843. +        bool HandleReloadVehicleDataCommand(char* args);
  844. +        bool HandleReloadVehicleSeatDataCommand(char* args);
  845.  
  846.          bool HandleResetAchievementsCommand(char* args);
  847.          bool HandleResetAllCommand(char* args);
  848. diff --git a/src/game/Creature.cpp b/src/game/Creature.cpp
  849. index eb2ed94..1082bae 100644
  850. --- a/src/game/Creature.cpp
  851. +++ b/src/game/Creature.cpp
  852. @@ -42,6 +42,7 @@
  853.  #include "GridNotifiers.h"
  854.  #include "GridNotifiersImpl.h"
  855.  #include "CellImpl.h"
  856. +#include "Vehicle.h"
  857.  
  858.  // apply implementation of the singletons
  859.  #include "Policies/SingletonImp.h"
  860. @@ -1401,6 +1402,8 @@ void Creature::SetDeathState(DeathState s)
  861.              return;
  862.  
  863.          Unit::SetDeathState(CORPSE);
  864. +        if(IsVehicle())
  865. +            ((Vehicle*)this)->Die();
  866.      }
  867.  
  868.      if (s == JUST_ALIVED)
  869. @@ -1529,6 +1532,32 @@ bool Creature::IsImmuneToSpellEffect(SpellEntry const* spellInfo, SpellEffectInd
  870.              return true;
  871.      }
  872.  
  873. +    // Heal immunity
  874. +    if (IsVehicle() && !(((Vehicle*)this)->GetVehicleFlags() & VF_CAN_BE_HEALED))
  875. +    {
  876. +        switch(spellInfo->Effect[index])
  877. +        {
  878. +            case SPELL_EFFECT_APPLY_AURA:
  879. +                switch(spellInfo->EffectApplyAuraName[index])
  880. +                {
  881. +                    case SPELL_AURA_PERIODIC_HEAL:
  882. +                    case SPELL_AURA_OBS_MOD_HEALTH:
  883. +                    case SPELL_AURA_PERIODIC_HEALTH_FUNNEL:
  884. +                    case SPELL_AURA_MOD_REGEN:
  885. +                        return true;
  886. +                    default: break;
  887. +                }
  888. +                break;
  889. +            case SPELL_EFFECT_HEAL:
  890. +            case SPELL_EFFECT_HEAL_MAX_HEALTH:
  891. +            // NOTE : this too?
  892. +            case SPELL_EFFECT_HEAL_MECHANICAL:
  893. +            case SPELL_EFFECT_HEAL_PCT:
  894. +                return true;
  895. +            default : break;
  896. +        }
  897. +    }
  898. +
  899.      return Unit::IsImmuneToSpellEffect(spellInfo, index);
  900.  }
  901.  
  902. @@ -1761,7 +1790,7 @@ bool Creature::CanInitiateAttack()
  903.      if (hasUnitState(UNIT_STAT_STUNNED | UNIT_STAT_DIED))
  904.          return false;
  905.  
  906. -    if (HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE))
  907. +    if (HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_PLAYER_CONTROLLED))
  908.          return false;
  909.  
  910.      if (isPassiveToHostile())
  911. @@ -2044,6 +2073,29 @@ bool Creature::IsInEvadeMode() const
  912.      return !i_motionMaster.empty() && i_motionMaster.GetCurrentMovementGeneratorType() == HOME_MOTION_TYPE;
  913.  }
  914.  
  915. +float Creature::GetBaseSpeed() const
  916. +{
  917. +    if( IsPet() )
  918. +    {
  919. +        switch( ((Pet*)this)->getPetType() )
  920. +        {
  921. +            case SUMMON_PET:
  922. +            case HUNTER_PET:
  923. +            {
  924. +                //fixed speed fur hunter (and summon!?) pets
  925. +                return 1.15f;
  926. +            }
  927. +            case GUARDIAN_PET:
  928. +            case MINI_PET:
  929. +            {
  930. +                //speed of CreatureInfo for guardian- and minipets
  931. +                break;
  932. +            }
  933. +        }
  934. +    }
  935. +    return m_creatureInfo->speed_run;
  936. +}
  937. +
  938.  bool Creature::HasSpell(uint32 spellID) const
  939.  {
  940.      uint8 i;
  941. diff --git a/src/game/Creature.h b/src/game/Creature.h
  942. index f5a2e29..2808c55 100644
  943. --- a/src/game/Creature.h
  944. +++ b/src/game/Creature.h
  945. @@ -117,6 +117,7 @@ struct CreatureInfo
  946.      int32   resistance6;
  947.      uint32  spells[CREATURE_MAX_SPELLS];
  948.      uint32  PetSpellDataId;
  949. +    uint32  VehicleEntry;
  950.      uint32  mingold;
  951.      uint32  maxgold;
  952.      char const* AIName;
  953. @@ -196,6 +197,15 @@ struct CreatureDataAddonAura
  954.      SpellEffectIndex effect_idx;
  955.  };
  956.  
  957. +struct CreatureDataAddonPassengers
  958. +{
  959. +    CreatureDataAddonPassengers() : entry(0), guid(0), seat_idx(-1) {}
  960. +
  961. +    uint32 entry;
  962. +    uint32 guid;
  963. +    int8 seat_idx;
  964. +};
  965. +
  966.  // from `creature_addon` table
  967.  struct CreatureDataAddon
  968.  {
  969. @@ -205,6 +215,8 @@ struct CreatureDataAddon
  970.      uint32 bytes2;
  971.      uint32 emote;
  972.      uint32 splineFlags;
  973. +    uint32 vehicle_id;
  974. +    CreatureDataAddonPassengers const* passengers;          // loaded as char* "entry1 seatid1 entry2 seatid2 ... "
  975.      CreatureDataAddonAura const* auras;                     // loaded as char* "spell1 eff1 spell2 eff2 ... "
  976.  };
  977.  
  978. @@ -580,6 +592,7 @@ class MANGOS_DLL_SPEC Creature : public Unit
  979.  
  980.          MovementGeneratorType GetDefaultMovementType() const { return m_defaultMovementType; }
  981.          void SetDefaultMovementType(MovementGeneratorType mgt) { m_defaultMovementType = mgt; }
  982. +        float GetBaseSpeed() const;
  983.  
  984.          // for use only in LoadHelper, Map::Add Map::CreatureCellRelocation
  985.          Cell const& GetCurrentCell() const { return m_currentCell; }
  986. diff --git a/src/game/CreatureAI.cpp b/src/game/CreatureAI.cpp
  987. index 33cb568..5b7e320 100644
  988. --- a/src/game/CreatureAI.cpp
  989. +++ b/src/game/CreatureAI.cpp
  990. @@ -26,6 +26,10 @@ CreatureAI::~CreatureAI()
  991.  
  992.  void CreatureAI::AttackedBy( Unit* attacker )
  993.  {
  994. +    // vehicle dont have threat list, so this is unnecessary, because it calls move chase
  995. +    if(m_creature->IsVehicle())
  996. +        return;
  997. +
  998.      if(!m_creature->getVictim())
  999.          AttackStart(attacker);
  1000.  }
  1001. diff --git a/src/game/CreatureAISelector.cpp b/src/game/CreatureAISelector.cpp
  1002. index 4ddfa91..640f890 100644
  1003. --- a/src/game/CreatureAISelector.cpp
  1004. +++ b/src/game/CreatureAISelector.cpp
  1005. @@ -47,7 +47,7 @@ namespace FactorySelector
  1006.          // excplicit check for isControlled() and owner type to allow guardian, mini-pets and pets controlled by NPCs to be scripted by EventAI
  1007.          Unit *owner=NULL;
  1008.          if ((creature->IsPet() && ((Pet*)creature)->isControlled() &&
  1009. -            ((owner=creature->GetOwner()) && owner->GetTypeId()==TYPEID_PLAYER)) || creature->isCharmed())
  1010. +            ((owner=creature->GetOwner()) && owner->GetTypeId()==TYPEID_PLAYER)) || (creature->isCharmed() && !creature->IsVehicle()))
  1011.              ai_factory = ai_registry.GetRegistryItem("PetAI");
  1012.          else if (creature->IsTotem())
  1013.              ai_factory = ai_registry.GetRegistryItem("TotemAI");
  1014. diff --git a/src/game/CreatureEventAI.cpp b/src/game/CreatureEventAI.cpp
  1015. index 21c8f68..27ae648 100644
  1016. --- a/src/game/CreatureEventAI.cpp
  1017. +++ b/src/game/CreatureEventAI.cpp
  1018. @@ -913,6 +913,7 @@ void CreatureEventAI::JustReachedHome()
  1019.  
  1020.  void CreatureEventAI::EnterEvadeMode()
  1021.  {
  1022. +    m_creature->ExitVehicle();
  1023.      m_creature->RemoveAllAuras();
  1024.      m_creature->DeleteThreatList();
  1025.      m_creature->CombatStop(true);
  1026. diff --git a/src/game/DBCEnums.h b/src/game/DBCEnums.h
  1027. index a1fbe08..a2615b0 100644
  1028. --- a/src/game/DBCEnums.h
  1029. +++ b/src/game/DBCEnums.h
  1030. @@ -437,6 +437,12 @@ enum VehicleFlags
  1031.  
  1032.  enum VehicleSeatFlags
  1033.  {
  1034. +    SEAT_FREE                       = 0x01,                 // free seat
  1035. +    SEAT_FULL                       = 0x02,                 // seat occupied by player/creature
  1036. +    // special cases
  1037. +    SEAT_VEHICLE_FREE               = 0x04,                 // seat occupied by vehicle, but that vehicle is free
  1038. +    SEAT_VEHICLE_FULL               = 0x08,                 // seat occupied by vehicle and that vehicle is full too
  1039. +
  1040.      SEAT_FLAG_HIDE_PASSENGER        = 0x00000200,           // Passenger is hidden
  1041.      SEAT_FLAG_CAN_CONTROL           = 0x00000800,           // Lua_UnitInVehicleControlSeat
  1042.      SEAT_FLAG_CAN_ATTACK            = 0x00004000,           // Can attack, cast spells and use items from vehicle?
  1043. diff --git a/src/game/DBCStructure.h b/src/game/DBCStructure.h
  1044. index c8f7489..ecefff9 100644
  1045. --- a/src/game/DBCStructure.h
  1046. +++ b/src/game/DBCStructure.h
  1047. @@ -1753,7 +1753,7 @@ struct VehicleEntry
  1048.      uint32  m_uiLocomotionType;                             // 34
  1049.      float   m_msslTrgtImpactTexRadius;                      // 35
  1050.      uint32  m_uiSeatIndicatorType;                          // 36
  1051. -                                                            // 37, new in 3.1 - powerType
  1052. +    uint32  m_powerType;                                    // 37, new in 3.1 - powerType
  1053.                                                              // 38, new in 3.1
  1054.                                                              // 39, new in 3.1
  1055.  };
  1056. @@ -1807,6 +1807,8 @@ struct VehicleSeatEntry
  1057.      int32   m_uiSkin;                                       // 44
  1058.      uint32  m_flagsB;                                       // 45
  1059.                                                              // 46-57 added in 3.1, floats mostly
  1060. +
  1061. +    bool IsUsable() const { return m_flags & SEAT_FLAG_USABLE; }
  1062.  };
  1063.  
  1064.  struct WMOAreaTableEntry
  1065. diff --git a/src/game/DBCfmt.h b/src/game/DBCfmt.h
  1066. index a9ff44f..8033dd3 100644
  1067. --- a/src/game/DBCfmt.h
  1068. +++ b/src/game/DBCfmt.h
  1069. @@ -104,7 +104,7 @@ const char TaxiNodesEntryfmt[]="nifffssssssssssssssssxii";
  1070.  const char TaxiPathEntryfmt[]="niii";
  1071.  const char TaxiPathNodeEntryfmt[]="diiifffiiii";
  1072.  const char TotemCategoryEntryfmt[]="nxxxxxxxxxxxxxxxxxii";
  1073. -const char VehicleEntryfmt[]="niffffiiiiiiiifffffffffffffffssssfifixxx";
  1074. +const char VehicleEntryfmt[]="niffffiiiiiiiifffffffffffffffssssfifiixx";
  1075.  const char VehicleSeatEntryfmt[]="niiffffffffffiiiiiifffffffiiifffiiiiiiiffiiiiixxxxxxxxxxxx";
  1076.  const char WMOAreaTableEntryfmt[]="niiixxxxxiixxxxxxxxxxxxxxxxx";
  1077.  const char WorldMapAreaEntryfmt[]="xinxffffixx";
  1078. diff --git a/src/game/GameObject.cpp b/src/game/GameObject.cpp
  1079. index d42a18c..7ca22d4 100644
  1080. --- a/src/game/GameObject.cpp
  1081. +++ b/src/game/GameObject.cpp
  1082. @@ -1628,6 +1628,18 @@ float GameObject::GetObjectBoundingRadius() const
  1083.      return DEFAULT_WORLD_OBJECT_SIZE;
  1084.  }
  1085.  
  1086. +void GameObject::DealSiegeDamage(uint32 damage)
  1087. +{
  1088. +    m_actualHealth -= damage;
  1089. +
  1090. +    // TODO : there are a lot of thinghts to do here
  1091. +    if(m_actualHealth < 0)
  1092. +    {
  1093. +        m_actualHealth = GetGOInfo()->destructibleBuilding.intactNumHits;
  1094. +        SetLootState(GO_JUST_DEACTIVATED);
  1095. +    }
  1096. +}
  1097. +
  1098.  bool GameObject::IsInSkillupList(Player* player) const
  1099.  {
  1100.      return m_SkillupSet.find(player->GetObjectGuid()) != m_SkillupSet.end();
  1101. diff --git a/src/game/GameObject.h b/src/game/GameObject.h
  1102. index 6b310f9..2dc37df 100644
  1103. --- a/src/game/GameObject.h
  1104. +++ b/src/game/GameObject.h
  1105. @@ -710,6 +710,7 @@ class MANGOS_DLL_SPEC GameObject : public WorldObject
  1106.          GridReference<GameObject> &GetGridRef() { return m_gridRef; }
  1107.  
  1108.          uint64 GetRotation() const { return m_rotation; }
  1109. +        void DealSiegeDamage(uint32 damage);
  1110.      protected:
  1111.          uint32      m_spellId;
  1112.          time_t      m_respawnTime;                          // (secs) time of next respawn (or despawn if GO have owner()),
  1113. @@ -716,6 +717,7 @@ class MANGOS_DLL_SPEC GameObject : public WorldObject
  1114.          uint32      m_respawnDelayTime;                     // (secs) if 0 then current GO state no dependent from timer
  1115.          LootState   m_lootState;
  1116.          bool        m_spawnedByDefault;
  1117. +        int32       m_actualHealth;                         // current health state
  1118.          time_t      m_cooldownTime;                         // used as internal reaction delay time store (not state change reaction).
  1119.                                                              // For traps this: spell casting cooldown, for doors/buttons: reset time.
  1120.  
  1121. diff --git a/src/game/GridNotifiers.cpp b/src/game/GridNotifiers.cpp
  1122. index 3e94064..8c4f725 100644
  1123. --- a/src/game/GridNotifiers.cpp
  1124. +++ b/src/game/GridNotifiers.cpp
  1125. @@ -93,7 +93,10 @@ VisibleNotifier::Notify()
  1126.      {
  1127.          // target aura duration for caster show only if target exist at caster client
  1128.          if ((*vItr) != &player && (*vItr)->isType(TYPEMASK_UNIT))
  1129. +        {
  1130.              player.SendAurasForTarget((Unit*)(*vItr));
  1131. +            ((Unit*)(*vItr))->SendHeartBeat(false);
  1132. +        }
  1133.  
  1134.          // non finished movements show to player
  1135.          if ((*vItr)->GetTypeId()==TYPEID_UNIT && ((Creature*)(*vItr))->isAlive())
  1136. diff --git a/src/game/Group.h b/src/game/Group.h
  1137. index 45a949a..453b77e 100644
  1138. --- a/src/game/Group.h
  1139. +++ b/src/game/Group.h
  1140. @@ -134,7 +134,8 @@ enum GroupUpdateFlags
  1141.      GROUP_UPDATE_FLAG_PET_AURAS         = 0x00040000,       // uint64 mask, for each bit set uint32 spellid + uint8 unk, pet auras...
  1142.      GROUP_UPDATE_FLAG_VEHICLE_SEAT      = 0x00080000,       // uint32 vehicle_seat_id (index from VehicleSeat.dbc)
  1143.      GROUP_UPDATE_PET                    = 0x0007FC00,       // all pet flags
  1144. -    GROUP_UPDATE_FULL                   = 0x0007FFFF,       // all known flags
  1145. +    GROUP_UPDATE_VEHICLE                = 0x000FFC00,       // all vehicle flags
  1146. +    GROUP_UPDATE_FULL                   = 0x000FFFFF,       // all known flags
  1147.  };
  1148.  
  1149.  #define GROUP_UPDATE_FLAGS_COUNT          20
  1150. diff --git a/src/game/GroupHandler.cpp b/src/game/GroupHandler.cpp
  1151. index e541595..cc17313 100644
  1152. --- a/src/game/GroupHandler.cpp
  1153. +++ b/src/game/GroupHandler.cpp
  1154. @@ -28,6 +28,7 @@
  1155.  #include "Group.h"
  1156.  #include "SocialMgr.h"
  1157.  #include "Util.h"
  1158. +#include "Vehicle.h"
  1159.  
  1160.  /* differeces from off:
  1161.      -you can uninvite yourself - is is useful
  1162. @@ -719,7 +720,7 @@ void WorldSession::BuildPartyMemberStatsChangedPacket(Player *player, WorldPacke
  1163.          }
  1164.      }
  1165.  
  1166. -    Pet *pet = player->GetPet();
  1167. +    Unit *pet = player->GetCharmOrPet();
  1168.      if (mask & GROUP_UPDATE_FLAG_PET_GUID)
  1169.          *data << (pet ? pet->GetObjectGuid() : ObjectGuid());
  1170.  
  1171. @@ -797,6 +798,11 @@ void WorldSession::BuildPartyMemberStatsChangedPacket(Player *player, WorldPacke
  1172.          else
  1173.              *data << uint64(0);
  1174.      }
  1175. +
  1176. +    if (mask & GROUP_UPDATE_FLAG_VEHICLE_SEAT)
  1177. +    {
  1178. +        *data << (uint32) player->m_movementInfo.GetTransportDBCSeat();
  1179. +    }
  1180.  }
  1181.  
  1182.  /*this procedure handles clients CMSG_REQUEST_PARTY_MEMBER_STATS request*/
  1183. @@ -818,7 +824,7 @@ void WorldSession::HandleRequestPartyMemberStatsOpcode( WorldPacket &recv_data )
  1184.          return;
  1185.      }
  1186.  
  1187. -    Pet *pet = player->GetPet();
  1188. +    Unit *pet = player->GetCharmOrPet();
  1189.  
  1190.      WorldPacket data(SMSG_PARTY_MEMBER_STATS_FULL, 4+2+2+2+1+2*6+8+1+8);
  1191.      data << uint8(0);                                       // only for SMSG_PARTY_MEMBER_STATS_FULL, probably arena/bg related
  1192. @@ -826,7 +832,7 @@ void WorldSession::HandleRequestPartyMemberStatsOpcode( WorldPacket &recv_data )
  1193.  
  1194.      uint32 mask1 = 0x00040BFF;                              // common mask, real flags used 0x000040BFF
  1195.      if(pet)
  1196. -        mask1 = 0x7FFFFFFF;                                 // for hunters and other classes with pets
  1197. +        mask1 = 0xFFFFFFFF;                                 // for hunters and other classes with pets
  1198.  
  1199.      Powers powerType = player->getPowerType();
  1200.      data << uint32(mask1);                                  // group update mask
  1201. @@ -880,6 +886,7 @@ void WorldSession::HandleRequestPartyMemberStatsOpcode( WorldPacket &recv_data )
  1202.              }
  1203.          }
  1204.          data.put<uint64>(petMaskPos, petauramask);          // GROUP_UPDATE_FLAG_PET_AURAS
  1205. +        data << (uint32) player->m_movementInfo.GetTransportDBCSeat();
  1206.      }
  1207.      else
  1208.      {
  1209. diff --git a/src/game/Level3.cpp b/src/game/Level3.cpp
  1210. index d8d30e2..06976a8 100644
  1211. --- a/src/game/Level3.cpp
  1212. +++ b/src/game/Level3.cpp
  1213. @@ -74,6 +74,9 @@ bool ChatHandler::HandleReloadAllCommand(char* /*args*/)
  1214.      HandleReloadReservedNameCommand((char*)"");
  1215.      HandleReloadMangosStringCommand((char*)"");
  1216.      HandleReloadGameTeleCommand((char*)"");
  1217. +
  1218. +    HandleReloadVehicleDataCommand((char*)"");
  1219. +    HandleReloadVehicleSeatDataCommand((char*)"");
  1220.      return true;
  1221.  }
  1222.  
  1223. @@ -921,6 +924,22 @@ bool ChatHandler::HandleReloadMailLevelRewardCommand(char* /*args*/)
  1224.      return true;
  1225.  }
  1226.  
  1227. +bool ChatHandler::HandleReloadVehicleDataCommand(char* /*args*/)
  1228. +{
  1229. +    sLog.outString( "Re-Loading `vehicle_data` Table!" );
  1230. +    sObjectMgr.LoadVehicleData();
  1231. +    SendGlobalSysMessage("DB table `vehicle_data` reloaded.");
  1232. +    return true;
  1233. +}
  1234. +
  1235. +bool ChatHandler::HandleReloadVehicleSeatDataCommand(char* /*args*/)
  1236. +{
  1237. +    sLog.outString( "Re-Loading `vehicle_seat_data` Table!" );
  1238. +    sObjectMgr.LoadVehicleSeatData();
  1239. +    SendGlobalSysMessage("DB table `vehicle_seat_data` reloaded.");
  1240. +    return true;
  1241. +}
  1242. +
  1243.  bool ChatHandler::HandleLoadScriptsCommand(char* args)
  1244.  {
  1245.      if (!LoadScriptingModule(args))
  1246. diff --git a/src/game/Map.h b/src/game/Map.h
  1247. index d0142e8..a1c7681 100644
  1248. --- a/src/game/Map.h
  1249. +++ b/src/game/Map.h
  1250. @@ -39,7 +39,6 @@
  1251.  #include <bitset>
  1252.  #include <list>
  1253.  
  1254. -class Creature;
  1255.  class Unit;
  1256.  class WorldPacket;
  1257.  class InstanceData;
  1258. diff --git a/src/game/MovementHandler.cpp b/src/game/MovementHandler.cpp
  1259. index 9355ca9..134dfc8 100644
  1260. --- a/src/game/MovementHandler.cpp
  1261. +++ b/src/game/MovementHandler.cpp
  1262. @@ -44,6 +44,9 @@ void WorldSession::HandleMoveWorldportAckOpcode()
  1263.      if(!GetPlayer()->IsBeingTeleportedFar())
  1264.          return;
  1265.  
  1266. +    if (_player->GetVehicleKit())
  1267. +        _player->GetVehicleKit()->RemoveAllPassengers();
  1268. +
  1269.      // get the teleport destination
  1270.      WorldLocation &loc = GetPlayer()->GetTeleportDest();
  1271.  
  1272. @@ -262,6 +265,8 @@ void WorldSession::HandleMovementOpcodes( WorldPacket & recv_data )
  1273.      data << mover->GetPackGUID();             // write guid
  1274.      movementInfo.Write(data);                               // write data
  1275.      mover->SendMessageToSetExcept(&data, _player);
  1276. +    mover->m_movementInfo = movementInfo;
  1277. +    mover->SetPosition(movementInfo.GetPos()->x, movementInfo.GetPos()->y, movementInfo.GetPos()->z, movementInfo.GetPos()->o);
  1278.  }
  1279.  
  1280.  void WorldSession::HandleForceSpeedChangeAckOpcodes(WorldPacket &recv_data)
  1281. @@ -343,12 +348,10 @@ void WorldSession::HandleSetActiveMoverOpcode(WorldPacket &recv_data)
  1282.      ObjectGuid guid;
  1283.      recv_data >> guid;
  1284.  
  1285. -    if(_player->GetMover()->GetObjectGuid() != guid)
  1286. -    {
  1287. -        sLog.outError("HandleSetActiveMoverOpcode: incorrect mover guid: mover is %s and should be %s",
  1288. -            _player->GetMover()->GetObjectGuid().GetString().c_str(), guid.GetString().c_str());
  1289. -        return;
  1290. -    }
  1291. +    if (Unit *pMover = ObjectAccessor::GetUnit(*GetPlayer(), guid))
  1292. +        GetPlayer()->SetMover(pMover);
  1293. +    else
  1294. +        GetPlayer()->SetMover(NULL);
  1295.  }
  1296.  
  1297.  void WorldSession::HandleMoveNotActiveMoverOpcode(WorldPacket &recv_data)
  1298. @@ -356,23 +359,13 @@ void WorldSession::HandleMoveNotActiveMoverOpcode(WorldPacket &recv_data)
  1299.      DEBUG_LOG("WORLD: Recvd CMSG_MOVE_NOT_ACTIVE_MOVER");
  1300.      recv_data.hexlike();
  1301.  
  1302. -    ObjectGuid old_mover_guid;
  1303. +    ObjectGuid guid;
  1304.      MovementInfo mi;
  1305.  
  1306. -    recv_data >> old_mover_guid.ReadAsPacked();
  1307. +    recv_data >> guid.ReadAsPacked();
  1308.      recv_data >> mi;
  1309.  
  1310. -    if(_player->GetMover()->GetObjectGuid() == old_mover_guid)
  1311. -    {
  1312. -        sLog.outError("HandleMoveNotActiveMover: incorrect mover guid: mover is %s and should be %s instead of %s",
  1313. -            _player->GetMover()->GetObjectGuid().GetString().c_str(),
  1314. -            _player->GetObjectGuid().GetString().c_str(),
  1315. -            old_mover_guid.GetString().c_str());
  1316. -        recv_data.rpos(recv_data.wpos());                   // prevent warnings spam
  1317. -        return;
  1318. -    }
  1319. -
  1320. -    _player->m_movementInfo = mi;
  1321. +    GetPlayer()->m_movementInfo = mi;
  1322.  }
  1323.  
  1324.  void WorldSession::HandleDismissControlledVehicle(WorldPacket &recv_data)
  1325. @@ -386,18 +379,171 @@ void WorldSession::HandleDismissControlledVehicle(WorldPacket &recv_data)
  1326.      recv_data >> guid.ReadAsPacked();
  1327.      recv_data >> mi;
  1328.  
  1329. -    ObjectGuid vehicleGUID = _player->GetCharmGuid();
  1330. +    ObjectGuid vehicleGUID = _player->GetVehicleGUID();
  1331.  
  1332.      if (vehicleGUID.IsEmpty())                              // something wrong here...
  1333.          return;
  1334.  
  1335.      _player->m_movementInfo = mi;
  1336.  
  1337. -    // using charm guid, because we don't have vehicle guid...
  1338. -    if(Vehicle *vehicle = _player->GetMap()->GetVehicle(vehicleGUID))
  1339. +    if(Vehicle *vehicle = ObjectAccessor::GetVehicle(vehicleGUID))
  1340.      {
  1341. -        // Aura::HandleAuraControlVehicle will call Player::ExitVehicle
  1342. -        vehicle->RemoveSpellsCausingAura(SPELL_AURA_CONTROL_VEHICLE);
  1343. +        if(vehicle->GetVehicleFlags() & VF_DESPAWN_AT_LEAVE)
  1344. +            vehicle->Dismiss();
  1345. +        else
  1346. +            _player->ExitVehicle();
  1347. +    }
  1348. +}
  1349. +
  1350. +void WorldSession::HandleRequestVehicleExit(WorldPacket &recv_data)
  1351. +{
  1352. +    sLog.outDebug("WORLD: Recvd CMSG_REQUEST_VEHICLE_EXIT");
  1353. +    recv_data.hexlike();
  1354. +
  1355. +    GetPlayer()->ExitVehicle();
  1356. +}
  1357. +
  1358. +void WorldSession::HandleRequestVehiclePrevSeat(WorldPacket &recv_data)
  1359. +{
  1360. +    DEBUG_LOG("WORLD: Recvd CMSG_REQUEST_VEHICLE_PREV_SEAT");
  1361. +    recv_data.hexlike();
  1362. +
  1363. +    GetPlayer()->ChangeSeat(-1, false);
  1364. +}
  1365. +
  1366. +void WorldSession::HandleRequestVehicleNextSeat(WorldPacket &recv_data)
  1367. +{
  1368. +    DEBUG_LOG("WORLD: Recvd CMSG_REQUEST_VEHICLE_NEXT_SEAT");
  1369. +    recv_data.hexlike();
  1370. +
  1371. +    GetPlayer()->ChangeSeat(-1, true);
  1372. +}
  1373. +
  1374. +void WorldSession::HandleRequestVehicleSwitchSeat(WorldPacket &recv_data)
  1375. +{
  1376. +    sLog.outDebug("WORLD: Recvd CMSG_REQUEST_VEHICLE_SWITCH_SEAT");
  1377. +    recv_data.hexlike();
  1378. +
  1379. +    uint64 vehicleGUID = _player->GetVehicleGUID();
  1380. +
  1381. +    if(!vehicleGUID)                                        // something wrong here...
  1382. +        return;
  1383. +
  1384. +    if(Vehicle *vehicle = ObjectAccessor::GetVehicle(vehicleGUID))
  1385. +    {
  1386. +        ObjectGuid guid;
  1387. +        recv_data >> guid.ReadAsPacked();
  1388. +
  1389. +        int8 seatId = 0;
  1390. +        recv_data >> seatId;
  1391. +
  1392. +        if(!guid.IsEmpty())
  1393. +        {
  1394. +            if(vehicleGUID != guid.GetRawValue())
  1395. +            {
  1396. +                if(Vehicle *veh = ObjectAccessor::GetVehicle(guid.GetRawValue()))
  1397. +                {
  1398. +                    if(!_player->IsWithinDistInMap(veh, 10))
  1399. +                        return;
  1400. +
  1401. +                    if(Vehicle *v = veh->FindFreeSeat(&seatId, false))
  1402. +                    {
  1403. +                        vehicle->RemovePassenger(_player);
  1404. +                        _player->EnterVehicle(v, seatId, false);
  1405. +                    }
  1406. +                }
  1407. +                return;
  1408. +            }
  1409. +        }
  1410. +        if(Vehicle *v = vehicle->FindFreeSeat(&seatId, false))
  1411. +        {
  1412. +            vehicle->RemovePassenger(_player);
  1413. +            _player->EnterVehicle(v, seatId, false);
  1414. +        }
  1415. +    }
  1416. +}
  1417. +
  1418. +void WorldSession::HandleChangeSeatsOnControlledVehicle(WorldPacket &recv_data)
  1419. +{
  1420. +    sLog.outDebug("WORLD: Recvd CMSG_CHANGE_SEATS_ON_CONTROLLED_VEHICLE");
  1421. +    recv_data.hexlike();
  1422. +
  1423. +    uint64 vehicleGUID = _player->GetVehicleGUID();
  1424. +
  1425. +    if(!vehicleGUID)                                        // something wrong here...
  1426. +        return;
  1427. +
  1428. +    if(recv_data.GetOpcode() == CMSG_REQUEST_VEHICLE_PREV_SEAT)
  1429. +    {
  1430. +        _player->ChangeSeat(-1, false);
  1431. +        return;
  1432. +    }
  1433. +    else if(recv_data.GetOpcode() == CMSG_REQUEST_VEHICLE_NEXT_SEAT)
  1434. +    {
  1435. +        _player->ChangeSeat(-1, true);
  1436. +        return;
  1437. +    }
  1438. +
  1439. +    ObjectGuid guid, guid2;
  1440. +    recv_data >> guid.ReadAsPacked();
  1441. +
  1442. +    MovementInfo mi;
  1443. +    recv_data >> mi;
  1444. +    _player->m_movementInfo = mi;
  1445. +
  1446. +    recv_data >> guid2.ReadAsPacked(); //guid of vehicle or of vehicle in target seat
  1447. +
  1448. +    int8 seatId;
  1449. +    recv_data >> seatId;
  1450. +
  1451. +    if(guid.GetRawValue() == guid2.GetRawValue())
  1452. +        _player->ChangeSeat(seatId, false);
  1453. +    else if(Vehicle *vehicle = ObjectAccessor::GetVehicle(guid2.GetRawValue()))
  1454. +    {
  1455. +        if(vehicle->HasEmptySeat(seatId))
  1456. +        {
  1457. +            _player->ExitVehicle();
  1458. +            _player->EnterVehicle(vehicle, seatId);
  1459. +        }
  1460. +    }
  1461. +}
  1462. +
  1463. +void WorldSession::HandleEnterPlayerVehicle(WorldPacket &recv_data)
  1464. +{
  1465. +    DEBUG_LOG("WORLD: Recvd CMSG_PLAYER_VEHICLE_ENTER");
  1466. +    recv_data.hexlike();
  1467. +
  1468. +    ObjectGuid guid;
  1469. +    recv_data >> guid;
  1470. +
  1471. +    if (Player* pl = ObjectAccessor::FindPlayer(guid))
  1472. +    {
  1473. +        if (!pl->GetVehicleKit())
  1474. +            return;
  1475. +        if (!pl->IsInSameRaidWith(GetPlayer()))
  1476. +            return;
  1477. +        if (!pl->IsWithinDistInMap(GetPlayer(), INTERACTION_DISTANCE))
  1478. +            return;
  1479. +        if (pl->GetTransport())
  1480. +            return;
  1481. +        GetPlayer()->EnterVehicle(pl->GetVehicleKit());
  1482. +    }
  1483. +}
  1484. +
  1485. +void WorldSession::HandleEjectPasenger(WorldPacket &recv_data)
  1486. +{
  1487. +    DEBUG_LOG("WORLD: Recvd CMSG_EJECT_PASSENGER");
  1488. +    recv_data.hexlike();
  1489. +
  1490. +    if(recv_data.GetOpcode()==CMSG_EJECT_PASSENGER)
  1491. +    {
  1492. +        if (GetPlayer()->GetVehicleKit())
  1493. +        {
  1494. +            ObjectGuid guid;
  1495. +            recv_data >> guid;
  1496. +            if(Player* Pl = ObjectAccessor::FindPlayer(guid))
  1497. +                Pl->ExitVehicle();
  1498. +        }
  1499.      }
  1500.  }
  1501.  
  1502. @@ -495,7 +641,14 @@ bool WorldSession::VerifyMovementInfo(MovementInfo& movementInfo, ObjectGuid& gu
  1503.      if (!MaNGOS::IsValidMapCoord(movementInfo.GetPos()->x, movementInfo.GetPos()->y, movementInfo.GetPos()->z, movementInfo.GetPos()->o))
  1504.          return false;
  1505.  
  1506. -    if (movementInfo.HasMovementFlag(MOVEFLAG_ONTRANSPORT))
  1507. +    if((movementInfo.HasMovementFlag (MOVEFLAG_ONTRANSPORT)) && (movementInfo.HasMovementFlag (MOVEFLAG_ROOT)))
  1508. +    {
  1509. +        if(mover->GetVehicle() && mover->GetVehicleGUID() && mover->GetTypeId()==TYPEID_PLAYER)
  1510. +        {
  1511. +            _player->ExitVehicle();
  1512. +        }
  1513. +    }
  1514. +    else if (movementInfo.HasMovementFlag (MOVEFLAG_ONTRANSPORT) && !mover->GetVehicle() && !mover->GetVehicleGUID())
  1515.      {
  1516.          // transports size limited
  1517.          // (also received at zeppelin/lift leave by some reason with t_* as absolute in continent coordinates, can be safely skipped)
  1518. @@ -529,6 +682,9 @@ void WorldSession::HandleMoverRelocation(MovementInfo& movementInfo, Unit* mover
  1519.                      {
  1520.                          plMover->m_transport = (*iter);
  1521.                          (*iter)->AddPassenger(plMover);
  1522. +
  1523. +                        if (plMover->GetVehicleKit())
  1524. +                            plMover->GetVehicleKit()->RemoveAllPassengers();
  1525.                          break;
  1526.                      }
  1527.                  }
  1528. @@ -546,6 +702,17 @@ void WorldSession::HandleMoverRelocation(MovementInfo& movementInfo, Unit* mover
  1529.              // now client not include swimming flag in case jumping under water
  1530.              plMover->SetInWater( !plMover->IsInWater() || plMover->GetBaseMap()->IsUnderWater(movementInfo.GetPos()->x, movementInfo.GetPos()->y, movementInfo.GetPos()->z) );
  1531.          }
  1532. +        if (movementInfo.HasMovementFlag(MOVEFLAG_SWIMMING))
  1533. +        {
  1534. +            if(mover->GetTypeId() == TYPEID_UNIT)
  1535. +            {
  1536. +                if(((Creature*)mover)->IsVehicle() && !((Creature*)mover)->CanSwim())
  1537. +                {
  1538. +                    // NOTE : we should enter evade mode here, but...
  1539. +                    ((Vehicle*)mover)->SetSpawnDuration(1);
  1540. +                }
  1541. +            }
  1542. +        }
  1543.  
  1544.          plMover->SetPosition(movementInfo.GetPos()->x, movementInfo.GetPos()->y, movementInfo.GetPos()->z, movementInfo.GetPos()->o);
  1545.          plMover->m_movementInfo = movementInfo;
  1546. @@ -584,6 +751,10 @@ void WorldSession::HandleMoverRelocation(MovementInfo& movementInfo, Unit* mover
  1547.      else                                                    // creature charmed
  1548.      {
  1549.          if (mover->IsInWorld())
  1550. +        {
  1551.              mover->GetMap()->CreatureRelocation((Creature*)mover, movementInfo.GetPos()->x, movementInfo.GetPos()->y, movementInfo.GetPos()->z, movementInfo.GetPos()->o);
  1552. +            if(((Creature*)mover)->IsVehicle())
  1553. +                ((Vehicle*)mover)->RellocatePassengers(mover->GetMap());
  1554. +        }
  1555.      }
  1556.  }
  1557. diff --git a/src/game/Object.cpp b/src/game/Object.cpp
  1558. index db44d14..8d00df5 100644
  1559. --- a/src/game/Object.cpp
  1560. +++ b/src/game/Object.cpp
  1561. @@ -270,13 +270,16 @@ void Object::BuildMovementUpdate(ByteBuffer * data, uint16 updateFlags) const
  1562.                          }
  1563.                      }
  1564.                  }
  1565. +                if (unit->GetVehicle() || unit->GetVehicleGUID())
  1566. +                   unit->m_movementInfo.AddMovementFlag(MOVEFLAG_ONTRANSPORT);
  1567. +
  1568.              }
  1569.              break;
  1570.              case TYPEID_PLAYER:
  1571.              {
  1572.                  Player *player = ((Player*)unit);
  1573.  
  1574. -                if(player->GetTransport())
  1575. +                if(player->GetTransport() || player->GetVehicle())
  1576.                      player->m_movementInfo.AddMovementFlag(MOVEFLAG_ONTRANSPORT);
  1577.                  else
  1578.                      player->m_movementInfo.RemoveMovementFlag(MOVEFLAG_ONTRANSPORT);
  1579. @@ -284,6 +287,9 @@ void Object::BuildMovementUpdate(ByteBuffer * data, uint16 updateFlags) const
  1580.                  // remove unknown, unused etc flags for now
  1581.                  player->m_movementInfo.RemoveMovementFlag(MOVEFLAG_SPLINE_ENABLED);
  1582.  
  1583. +                if(((Unit*)this)->GetVehicleGUID())
  1584. +                    player->m_movementInfo.AddMovementFlag(MOVEFLAG_ONTRANSPORT);
  1585. +
  1586.                  if(player->IsTaxiFlying())
  1587.                  {
  1588.                      MANGOS_ASSERT(player->GetMotionMaster()->GetCurrentMovementGeneratorType() == FLIGHT_MOTION_TYPE);
  1589. @@ -1144,7 +1150,14 @@ void WorldObject::Relocate(float x, float y, float z, float orientation)
  1590.      m_orientation = orientation;
  1591.  
  1592.      if(isType(TYPEMASK_UNIT))
  1593. +    {
  1594.          ((Unit*)this)->m_movementInfo.ChangePosition(x, y, z, orientation);
  1595. +        if(GetTypeId() == TYPEID_UNIT)
  1596. +        {
  1597. +            if(((Creature*)this)->IsVehicle() && IsInWorld())
  1598. +                ((Vehicle*)this)->RellocatePassengers(GetMap());
  1599. +        }
  1600. +    }
  1601.  }
  1602.  
  1603.  void WorldObject::Relocate(float x, float y, float z)
  1604. @@ -1154,7 +1167,11 @@ void WorldObject::Relocate(float x, float y, float z)
  1605.      m_positionZ = z;
  1606.  
  1607.      if(isType(TYPEMASK_UNIT))
  1608. +    {
  1609.          ((Unit*)this)->m_movementInfo.ChangePosition(x, y, z, GetOrientation());
  1610. +        if(((Creature*)this)->IsVehicle() && IsInWorld())
  1611. +            ((Vehicle*)this)->RellocatePassengers(GetMap());
  1612. +    }
  1613.  }
  1614.  
  1615.  uint32 WorldObject::GetZoneId() const
  1616. @@ -1762,6 +1779,42 @@ Creature* WorldObject::SummonCreature(uint32 id, float x, float y, float z, floa
  1617.      return pCreature;
  1618.  }
  1619.  
  1620. +Vehicle* WorldObject::SummonVehicle(uint32 id, float x, float y, float z, float ang, uint32 vehicleId)
  1621. +{
  1622. +    Vehicle *v = new Vehicle;
  1623. +
  1624. +    Map *map = GetMap();
  1625. +    uint32 team = 0;
  1626. +    if (GetTypeId()==TYPEID_PLAYER)
  1627. +        team = ((Player*)this)->GetTeam();
  1628. +
  1629. +    if(!v->Create(sObjectMgr.GenerateLowGuid(HIGHGUID_VEHICLE), map, GetPhaseMask(), id, vehicleId, team))
  1630. +    {
  1631. +        delete v;
  1632. +        return NULL;
  1633. +    }
  1634. +
  1635. +    if (x == 0.0f && y == 0.0f && z == 0.0f)
  1636. +        GetClosePoint(x, y, z, v->GetObjectBoundingRadius());
  1637. +
  1638. +    v->Relocate(x, y, z, ang);
  1639. +
  1640. +    if(!v->IsPositionValid())
  1641. +    {
  1642. +        sLog.outError("ERROR: Vehicle (guidlow %d, entry %d) not created. Suggested coordinates isn't valid (X: %f Y: %f)",
  1643. +            v->GetGUIDLow(), v->GetEntry(), v->GetPositionX(), v->GetPositionY());
  1644. +        delete v;
  1645. +        return NULL;
  1646. +    }
  1647. +    map->Add((Creature*)v);
  1648. +    v->AIM_Initialize();
  1649. +
  1650. +    if(GetTypeId()==TYPEID_UNIT && ((Creature*)this)->AI())
  1651. +        ((Creature*)this)->AI()->JustSummoned((Creature*)v);
  1652. +
  1653. +    return v;
  1654. +}
  1655. +
  1656.  namespace MaNGOS
  1657.  {
  1658.      class NearUsedPosDo
  1659. diff --git a/src/game/Object.h b/src/game/Object.h
  1660. index 653b169..810a4b2 100644
  1661. --- a/src/game/Object.h
  1662. +++ b/src/game/Object.h
  1663. @@ -69,6 +69,7 @@ class Unit;
  1664.  class Map;
  1665.  class UpdateMask;
  1666.  class InstanceData;
  1667. +class Vehicle;
  1668.  
  1669.  typedef UNORDERED_MAP<Player*, UpdateData> UpdateDataMapType;
  1670.  
  1671. @@ -492,6 +493,9 @@ class MANGOS_DLL_SPEC WorldObject : public Object
  1672.          bool isActiveObject() const { return m_isActiveObject || m_viewPoint.hasViewers(); }
  1673.  
  1674.          ViewPoint& GetViewPoint() { return m_viewPoint; }
  1675. +
  1676. +        Vehicle* SummonVehicle(uint32 id, float x, float y, float z, float ang, uint32 vehicleId = NULL);
  1677. +
  1678.      protected:
  1679.          explicit WorldObject();
  1680.  
  1681. diff --git a/src/game/ObjectAccessor.cpp b/src/game/ObjectAccessor.cpp
  1682. index a1a21df..92f39c7 100644
  1683. --- a/src/game/ObjectAccessor.cpp
  1684. +++ b/src/game/ObjectAccessor.cpp
  1685. @@ -53,6 +53,21 @@ ObjectAccessor::~ObjectAccessor()
  1686.      }
  1687.  }
  1688.  
  1689. +Creature*
  1690. +ObjectAccessor::GetAnyTypeCreature(WorldObject const &u, ObjectGuid guid)
  1691. +{
  1692. +    if(guid.IsPlayer() || !u.IsInWorld())
  1693. +        return NULL;
  1694. +
  1695. +    if(guid.IsPet())
  1696. +        return u.GetMap()->GetPet(guid);
  1697. +
  1698. +    if(guid.IsVehicle())
  1699. +        return u.GetMap()->GetVehicle(guid);
  1700. +
  1701. +    return u.GetMap()->GetCreature(guid);
  1702. +}
  1703. +
  1704.  Unit*
  1705.  ObjectAccessor::GetUnit(WorldObject const &u, ObjectGuid guid)
  1706.  {
  1707. @@ -62,10 +77,7 @@ ObjectAccessor::GetUnit(WorldObject const &u, ObjectGuid guid)
  1708.      if(guid.IsPlayer())
  1709.          return FindPlayer(guid);
  1710.  
  1711. -    if (!u.IsInWorld())
  1712. -        return NULL;
  1713. -
  1714. -    return u.GetMap()->GetAnyTypeCreature(guid);
  1715. +    return GetAnyTypeCreature(u, guid);
  1716.  }
  1717.  
  1718.  Corpse* ObjectAccessor::GetCorpseInMap(ObjectGuid guid, uint32 mapid)
  1719. diff --git a/src/game/ObjectAccessor.h b/src/game/ObjectAccessor.h
  1720. index 5b9445f..c28d41c 100644
  1721. --- a/src/game/ObjectAccessor.h
  1722. +++ b/src/game/ObjectAccessor.h
  1723. @@ -40,6 +40,7 @@
  1724.  class Creature;
  1725.  class Unit;
  1726.  class GameObject;
  1727. +class Vehicle;
  1728.  class WorldObject;
  1729.  class Map;
  1730.  
  1731. @@ -100,13 +101,21 @@ class MANGOS_DLL_DECL ObjectAccessor : public MaNGOS::Singleton<ObjectAccessor,
  1732.          // global (obj used for map only location local guid objects (pets currently)
  1733.          static Unit*   GetUnitInWorld(WorldObject const& obj, ObjectGuid guid);
  1734.  
  1735. -        // FIXME: map local object with global search
  1736. +        // map local object with global search
  1737.          static Creature*   GetCreatureInWorld(ObjectGuid guid)   { return FindHelper<Creature>(guid); }
  1738.          static GameObject* GetGameObjectInWorld(ObjectGuid guid) { return FindHelper<GameObject>(guid); }
  1739. +        static Pet*        GetGameObjectInWorld(ObjectGuid guid, Pet*        /*fake*/) { return FindHelper<Pet>(guid); }
  1740. +        static Vehicle*    GetGameObjectInWorld(ObjectGuid guid, Vehicle*    /*fake*/) { return FindHelper<Vehicle>(guid); }
  1741.  
  1742.          // Search player at any map in world and other objects at same map with `obj`
  1743.          // Note: recommended use Map::GetUnit version if player also expected at same map only
  1744.          static Unit* GetUnit(WorldObject const& obj, ObjectGuid guid);
  1745. +        static Creature* GetAnyTypeCreature(WorldObject const &, ObjectGuid guid);
  1746. +        //static Player* GetPlayer(Unit const &, uint64 guid) { return FindPlayer(guid); }
  1747. +        //static Corpse* GetCorpse(WorldObject const &u, uint64 guid);
  1748. +        //static Pet* GetPet(uint64 guid) { return GetObjectInWorld(guid, (Pet*)NULL); }
  1749. +        static Vehicle* GetVehicle(ObjectGuid guid) { return GetGameObjectInWorld(guid, (Vehicle*)NULL); }
  1750. +        //static Player* FindPlayer(uint64);
  1751.  
  1752.          // Player access
  1753.          static Player* FindPlayer(ObjectGuid guid);         // if need player at specific map better use Map::GetPlayer
  1754. @@ -175,6 +184,9 @@ inline Unit* ObjectAccessor::GetUnitInWorld(WorldObject const& obj, ObjectGuid g
  1755.      if (guid.IsPet())
  1756.          return obj.IsInWorld() ? obj.GetMap()->GetPet(guid) : NULL;
  1757.  
  1758. +    if (guid.IsVehicle())
  1759. +        return obj.IsInWorld() ? ((Unit*)obj.GetMap()->GetVehicle(guid)) : NULL;
  1760. +
  1761.      return GetCreatureInWorld(guid);
  1762.  }
  1763.  
  1764. diff --git a/src/game/ObjectMgr.cpp b/src/game/ObjectMgr.cpp
  1765. index cf4c613..f6e415d 100644
  1766. --- a/src/game/ObjectMgr.cpp
  1767. +++ b/src/game/ObjectMgr.cpp
  1768. @@ -830,6 +830,93 @@ void ObjectMgr::ConvertCreatureAddonAuras(CreatureDataAddon* addon, char const*
  1769.      endAura.effect_idx = EFFECT_INDEX_0;
  1770.  }
  1771.  
  1772. +void ObjectMgr::ConvertCreatureAddonPassengers(CreatureDataAddon* addon, char const* table, char const* guidEntryStr)
  1773. +{
  1774. +    // Now add the passengers, format "creature_entry/guid seatindex creature_entry/guid seatindex..."
  1775. +    char *p,*s;
  1776. +    std::vector<int> val;
  1777. +    s=p=(char*)reinterpret_cast<char const*>(addon->passengers);
  1778. +    if(p)
  1779. +    {
  1780. +        while (p[0]!=0)
  1781. +        {
  1782. +            ++p;
  1783. +            if (p[0]==' ')
  1784. +            {
  1785. +                val.push_back(atoi(s));
  1786. +                s=++p;
  1787. +            }
  1788. +        }
  1789. +        if (p!=s)
  1790. +            val.push_back(atoi(s));
  1791. +
  1792. +        // free char* loaded memory
  1793. +        delete[] (char*)reinterpret_cast<char const*>(addon->passengers);
  1794. +
  1795. +        // wrong list
  1796. +        if (val.size()%2)
  1797. +        {
  1798. +            addon->auras = NULL;
  1799. +            sLog.outErrorDb("Creature (%s: %u) has wrong `passengers` data in `%s`.",guidEntryStr,addon->guidOrEntry,table);
  1800. +            return;
  1801. +        }
  1802. +    }
  1803. +
  1804. +    // empty list
  1805. +    if(val.empty())
  1806. +    {
  1807. +        addon->passengers = NULL;
  1808. +        return;
  1809. +    }
  1810. +
  1811. +    // replace by new structures array
  1812. +    const_cast<CreatureDataAddonPassengers*&>(addon->passengers) = new CreatureDataAddonPassengers[val.size()/2+1];
  1813. +
  1814. +    uint32 i=0;
  1815. +    for(uint32 j=0; j<val.size()/2; ++j)
  1816. +    {
  1817. +        CreatureDataAddonPassengers& cPas = const_cast<CreatureDataAddonPassengers&>(addon->passengers[i]);
  1818. +        if(guidEntryStr == "Entry")
  1819. +            cPas.entry = (uint32)val[2*j+0];
  1820. +        else
  1821. +            cPas.guid = (uint32)val[2*j+0];
  1822. +        cPas.seat_idx = (int8)val[2*j+1];
  1823. +        if ( cPas.seat_idx > 7 )
  1824. +        {
  1825. +            sLog.outErrorDb("Creature (%s: %u) has wrong seat %u for creature %u in `passengers` field in `%s`.",guidEntryStr,addon->guidOrEntry,cPas.seat_idx,cPas.entry,table);
  1826. +            continue;
  1827. +        }
  1828. +        if(cPas.entry == 0 && cPas.guid == 0)
  1829. +        {
  1830. +            sLog.outErrorDb("Creature (%s: %u) has NULL creature entry/guid in `passengers` field in `%s`.",guidEntryStr,addon->guidOrEntry,table);
  1831. +            continue;
  1832. +        }
  1833. +        if(cPas.entry > 0)
  1834. +        {
  1835. +            if(!sCreatureStorage.LookupEntry<CreatureInfo>(cPas.entry))
  1836. +            {
  1837. +                sLog.outErrorDb("Creature (%s: %u) has wrong creature entry/guid %u `passengers` field in `%s`.",guidEntryStr,addon->guidOrEntry,cPas.entry,table);
  1838. +                continue;
  1839. +            }
  1840. +        }
  1841. +        else
  1842. +        {
  1843. +            if(mCreatureDataMap.find(cPas.guid)==mCreatureDataMap.end())
  1844. +            {
  1845. +                sLog.outErrorDb("Creature (%s: %u) has wrong creature entry/guid %u `passengers` field in `%s`.",guidEntryStr,addon->guidOrEntry,cPas.guid,table);
  1846. +                continue;
  1847. +            }
  1848. +        }
  1849. +        ++i;
  1850. +    }
  1851. +
  1852. +    // fill terminator element (after last added)
  1853. +    CreatureDataAddonPassengers& endPassenger = const_cast<CreatureDataAddonPassengers&>(addon->passengers[i]);
  1854. +    endPassenger.entry = 0;
  1855. +    endPassenger.guid = 0;
  1856. +    endPassenger.seat_idx = -1;
  1857. +}
  1858. +
  1859.  void ObjectMgr::LoadCreatureAddons(SQLStorage& creatureaddons, char const* entryName, char const* comment)
  1860.  {
  1861.      creatureaddons.Load();
  1862. @@ -866,6 +953,7 @@ void ObjectMgr::LoadCreatureAddons(SQLStorage& creatureaddons, char const* entry
  1863.          }
  1864.  
  1865.          ConvertCreatureAddonAuras(const_cast<CreatureDataAddon*>(addon), creatureaddons.GetTableName(), entryName);
  1866. +        ConvertCreatureAddonPassengers(const_cast<CreatureDataAddon*>(addon), creatureaddons.GetTableName(), entryName);
  1867.      }
  1868.  }
  1869.  
  1870. @@ -6420,6 +6508,8 @@ uint32 ObjectMgr::GenerateLowGuid(HighGuid guidhigh)
  1871.              return m_ItemGuids.Generate();
  1872.          case HIGHGUID_UNIT:
  1873.              return m_CreatureGuids.Generate();
  1874. +        case HIGHGUID_VEHICLE:
  1875. +            return m_VehicleGuids.Generate();
  1876.          case HIGHGUID_PLAYER:
  1877.              return m_CharGuids.Generate();
  1878.          case HIGHGUID_GAMEOBJECT:
  1879. @@ -9656,6 +9746,126 @@ CreatureInfo const* GetCreatureTemplateStore(uint32 entry)
  1880.      return sCreatureStorage.LookupEntry<CreatureInfo>(entry);
  1881.  }
  1882.  
  1883. +void ObjectMgr::LoadVehicleData()
  1884. +{
  1885. +    mVehicleData.clear();
  1886. +
  1887. +    QueryResult *result = WorldDatabase.Query("SELECT entry, flags, Spell1, Spell2, Spell3, Spell4, Spell5, Spell6, Spell7, Spell8, Spell9, Spell10, req_aura FROM vehicle_data");
  1888. +    if(!result)
  1889. +    {
  1890. +        barGoLink bar( 1 );
  1891. +        bar.step();
  1892. +
  1893. +        sLog.outString();
  1894. +        sLog.outString( ">> Loaded 0 vehicle data" );
  1895. +        sLog.outErrorDb("`vehicle_data` table is empty!");
  1896. +        return;
  1897. +    }
  1898. +
  1899. +    uint32 count = 0;
  1900. +
  1901. +    barGoLink bar( result->GetRowCount() );
  1902. +    do
  1903. +    {
  1904. +        bar.step();
  1905. +
  1906. +        Field* fields = result->Fetch();
  1907. +
  1908. +        VehicleDataStructure VDS;
  1909. +        // NOTE : we can use spellid or creature id
  1910. +        uint32 v_entry      = fields[0].GetUInt32();
  1911. +        VDS.v_flags         = fields[1].GetUInt32();
  1912. +        for(uint8 j = 0; j < MAX_VEHICLE_SPELLS; j++)
  1913. +        {
  1914. +            VDS.v_spells[j] = fields[j+2].GetUInt32();
  1915. +        }
  1916. +        VDS.req_aura        = fields[12].GetUInt32();
  1917. +
  1918. +        VehicleEntry const *vehicleInfo = sVehicleStore.LookupEntry(v_entry);
  1919. +        if(!vehicleInfo)
  1920. +        {
  1921. +            sLog.outErrorDb("Vehicle id %u listed in `vehicle_data` does not exist",v_entry);
  1922. +            continue;
  1923. +        }
  1924. +        for(uint8 j = 0; j < MAX_VEHICLE_SPELLS; j++)
  1925. +        {
  1926. +            if(VDS.v_spells[j])
  1927. +            {
  1928. +                SpellEntry const* j_spell = sSpellStore.LookupEntry(VDS.v_spells[j]);
  1929. +                if(!j_spell)
  1930. +                {
  1931. +                    sLog.outErrorDb("Spell %u listed in `vehicle_data` does not exist, skipped",VDS.v_spells[j]);
  1932. +                    VDS.v_spells[j] = 0;
  1933. +                }
  1934. +            }
  1935. +        }
  1936. +        if(VDS.req_aura)
  1937. +        {
  1938. +            SpellEntry const* i_spell = sSpellStore.LookupEntry(VDS.req_aura);
  1939. +            if(!i_spell)
  1940. +            {
  1941. +                sLog.outErrorDb("Spell %u listed in `vehicle_data` does not exist, skipped",VDS.req_aura);
  1942. +                VDS.req_aura = 0;
  1943. +            }
  1944. +        }
  1945. +
  1946. +        mVehicleData[v_entry] = VDS;
  1947. +        ++count;
  1948. +    }
  1949. +    while (result->NextRow());
  1950. +
  1951. +    delete result;
  1952. +
  1953. +    sLog.outString();
  1954. +    sLog.outString( ">> Loaded %u vehicle data", count );
  1955. +}
  1956. +
  1957. +void ObjectMgr::LoadVehicleSeatData()
  1958. +{
  1959. +    mVehicleSeatData.clear();
  1960. +
  1961. +    QueryResult *result = WorldDatabase.Query("SELECT seat,flags FROM vehicle_seat_data");
  1962. +
  1963. +    if( !result )
  1964. +    {
  1965. +        barGoLink bar( 1 );
  1966. +
  1967. +        bar.step();
  1968. +
  1969. +        sLog.outString();
  1970. +        sLog.outString( ">> Loaded 0 vehicle seat data" );
  1971. +        sLog.outErrorDb("`vehicle_seat_data` table is empty!");
  1972. +        return;
  1973. +    }
  1974. +    uint32 count = 0;
  1975. +
  1976. +    barGoLink bar( result->GetRowCount() );
  1977. +    do
  1978. +    {
  1979. +        bar.step();
  1980. +
  1981. +        Field *fields = result->Fetch();
  1982. +        uint32 entry  = fields[0].GetUInt32();
  1983. +        uint32 flag   = fields[1].GetUInt32();
  1984. +
  1985. +        VehicleSeatEntry const *vsInfo = sVehicleSeatStore.LookupEntry(entry);
  1986. +        if(!vsInfo)
  1987. +        {
  1988. +            sLog.outErrorDb("Vehicle seat %u listed in `vehicle_seat_data` does not exist",entry);
  1989. +            continue;
  1990. +        }
  1991. +
  1992. +        mVehicleSeatData[entry] = flag;
  1993. +        ++count;
  1994. +    }
  1995. +    while (result->NextRow());
  1996. +
  1997. +    delete result;
  1998. +
  1999. +    sLog.outString();
  2000. +    sLog.outString( ">> Loaded %u vehicle seat data", count );
  2001. +}
  2002. +
  2003.  Quest const* GetQuestTemplateStore(uint32 entry)
  2004.  {
  2005.      return sObjectMgr.GetQuestTemplate(entry);
  2006. diff --git a/src/game/ObjectMgr.h b/src/game/ObjectMgr.h
  2007. index 5b74ea6..9c8c136 100644
  2008. --- a/src/game/ObjectMgr.h
  2009. +++ b/src/game/ObjectMgr.h
  2010. @@ -675,6 +675,8 @@ extern LanguageDesc lang_description[LANGUAGES_COUNT];
  2011.  MANGOS_DLL_SPEC LanguageDesc const* GetLanguageDescByID(uint32 lang);
  2012.  
  2013.  class PlayerDumpReader;
  2014. +// vehicle system
  2015. +#define MAX_VEHICLE_SPELLS 6
  2016.  
  2017.  template<typename T>
  2018.  class IdGenerator
  2019. @@ -694,6 +696,16 @@ class IdGenerator
  2020.          T m_nextGuid;
  2021.  };
  2022.  
  2023. +struct VehicleDataStructure
  2024. +{
  2025. +    uint32 v_flags;                                         // vehicle flags, see enum CustomVehicleFLags
  2026. +    uint32 v_spells[MAX_VEHICLE_SPELLS];                    // spells
  2027. +    uint32 req_aura;                                        // requieres aura on player to enter (eg. in wintergrasp)
  2028. +};
  2029. +
  2030. +typedef UNORDERED_MAP<uint32, VehicleDataStructure> VehicleDataMap;
  2031. +typedef std::map<uint32,uint32> VehicleSeatDataMap;
  2032. +
  2033.  class ObjectMgr
  2034.  {
  2035.      friend class PlayerDumpReader;
  2036. @@ -984,6 +996,9 @@ class ObjectMgr
  2037.          void LoadVendors() { LoadVendors("npc_vendor", false); }
  2038.          void LoadTrainerSpell();
  2039.  
  2040. +        void LoadVehicleData();
  2041. +        void LoadVehicleSeatData();
  2042. +
  2043.          std::string GeneratePetName(uint32 entry);
  2044.          uint32 GetBaseXP(uint32 level) const;
  2045.          uint32 GetXPForLevel(uint32 level) const;
  2046. @@ -1248,6 +1263,24 @@ class ObjectMgr
  2047.  
  2048.          int GetOrNewIndexForLocale(LocaleConstant loc);
  2049.  
  2050. +        VehicleDataMap mVehicleData;
  2051. +        VehicleSeatDataMap mVehicleSeatData;
  2052. +
  2053. +        uint32 GetSeatFlags(uint32 seatid)
  2054. +        {
  2055. +            VehicleSeatDataMap::iterator i = mVehicleSeatData.find(seatid);
  2056. +            if(i == mVehicleSeatData.end())
  2057. +                return NULL;
  2058. +            else
  2059. +                return i->second;
  2060. +        }
  2061. +        VehicleDataStructure const* GetVehicleData(uint32 entry) const
  2062. +        {
  2063. +            VehicleDataMap::const_iterator itr = mVehicleData.find(entry);
  2064. +            if(itr==mVehicleData.end()) return NULL;
  2065. +            return &itr->second;
  2066. +        }
  2067. +
  2068.          SpellClickInfoMapBounds GetSpellClickInfoMapBounds(uint32 creature_id) const
  2069.          {
  2070.              return mSpellClickInfoMap.equal_range(creature_id);
  2071. @@ -1324,6 +1357,7 @@ class ObjectMgr
  2072.          ObjectGuidGenerator<HIGHGUID_GAMEOBJECT> m_GameobjectGuids;
  2073.          ObjectGuidGenerator<HIGHGUID_CORPSE>     m_CorpseGuids;
  2074.          ObjectGuidGenerator<HIGHGUID_INSTANCE>   m_InstanceGuids;
  2075. +        ObjectGuidGenerator<HIGHGUID_VEHICLE>    m_VehicleGuids;
  2076.  
  2077.          QuestMap            mQuestTemplates;
  2078.  
  2079. @@ -1392,6 +1426,7 @@ class ObjectMgr
  2080.          void CheckScriptTexts(ScriptMapMap const& scripts,std::set<int32>& ids);
  2081.          void LoadCreatureAddons(SQLStorage& creatureaddons, char const* entryName, char const* comment);
  2082.          void ConvertCreatureAddonAuras(CreatureDataAddon* addon, char const* table, char const* guidEntryStr);
  2083. +        void ConvertCreatureAddonPassengers(CreatureDataAddon* addon, char const* table, char const* guidEntryStr);
  2084.          void LoadQuestRelationsHelper(QuestRelationsMap& map, char const* table);
  2085.  
  2086.          MailLevelRewardMap m_mailLevelRewardMap;
  2087. diff --git a/src/game/Opcodes.cpp b/src/game/Opcodes.cpp
  2088. index 4f0fbe0..647f38d 100644
  2089. --- a/src/game/Opcodes.cpp
  2090. +++ b/src/game/Opcodes.cpp
  2091. @@ -1168,10 +1168,10 @@ OpcodeHandler opcodeTable[NUM_MSG_TYPES] =
  2092.      /*0x473*/ { "CMSG_CHAR_CUSTOMIZE",                          STATUS_AUTHED,   &WorldSession::HandleCharCustomizeOpcode       },
  2093.      /*0x474*/ { "SMSG_CHAR_CUSTOMIZE",                          STATUS_NEVER,    &WorldSession::Handle_ServerSide               },
  2094.      /*0x475*/ { "SMSG_PET_RENAMEABLE",                          STATUS_NEVER,    &WorldSession::Handle_ServerSide               },
  2095. -    /*0x476*/ { "CMSG_REQUEST_VEHICLE_EXIT",                    STATUS_NEVER,    &WorldSession::Handle_NULL                     },
  2096. -    /*0x477*/ { "CMSG_REQUEST_VEHICLE_PREV_SEAT",               STATUS_NEVER,    &WorldSession::Handle_NULL                     },
  2097. -    /*0x478*/ { "CMSG_REQUEST_VEHICLE_NEXT_SEAT",               STATUS_NEVER,    &WorldSession::Handle_NULL                     },
  2098. -    /*0x479*/ { "CMSG_REQUEST_VEHICLE_SWITCH_SEAT",             STATUS_NEVER,    &WorldSession::Handle_NULL                     },
  2099. +    /*0x476*/ { "CMSG_REQUEST_VEHICLE_EXIT",                    STATUS_LOGGEDIN, &WorldSession::HandleRequestVehicleExit        },
  2100. +    /*0x477*/ { "CMSG_REQUEST_VEHICLE_PREV_SEAT",               STATUS_LOGGEDIN, &WorldSession::HandleRequestVehiclePrevSeat    },
  2101. +    /*0x478*/ { "CMSG_REQUEST_VEHICLE_NEXT_SEAT",               STATUS_LOGGEDIN, &WorldSession::HandleRequestVehicleNextSeat    },
  2102. +    /*0x479*/ { "CMSG_REQUEST_VEHICLE_SWITCH_SEAT",             STATUS_LOGGEDIN, &WorldSession::HandleRequestVehicleSwitchSeat  },
  2103.      /*0x47A*/ { "CMSG_PET_LEARN_TALENT",                        STATUS_LOGGEDIN, &WorldSession::HandlePetLearnTalent            },
  2104.      /*0x47B*/ { "CMSG_PET_UNLEARN_TALENTS",                     STATUS_NEVER,    &WorldSession::Handle_NULL                     },
  2105.      /*0x47C*/ { "SMSG_SET_PHASE_SHIFT",                         STATUS_NEVER,    &WorldSession::Handle_ServerSide               },
  2106. @@ -1205,7 +1205,7 @@ OpcodeHandler opcodeTable[NUM_MSG_TYPES] =
  2107.      /*0x498*/ { "SMSG_SERVER_FIRST_ACHIEVEMENT",                STATUS_NEVER,    &WorldSession::Handle_ServerSide               },
  2108.      /*0x499*/ { "SMSG_PET_LEARNED_SPELL",                       STATUS_NEVER,    &WorldSession::Handle_ServerSide               },
  2109.      /*0x49A*/ { "SMSG_PET_REMOVED_SPELL",                       STATUS_NEVER,    &WorldSession::Handle_ServerSide               },
  2110. -    /*0x49B*/ { "CMSG_CHANGE_SEATS_ON_CONTROLLED_VEHICLE",      STATUS_NEVER,    &WorldSession::Handle_NULL                     },
  2111. +    /*0x49B*/ { "CMSG_CHANGE_SEATS_ON_CONTROLLED_VEHICLE",      STATUS_LOGGEDIN, &WorldSession::HandleChangeSeatsOnControlledVehicle},
  2112.      /*0x49C*/ { "CMSG_HEARTH_AND_RESURRECT",                    STATUS_LOGGEDIN, &WorldSession::HandleHearthandResurrect        },
  2113.      /*0x49D*/ { "SMSG_ON_CANCEL_EXPECTED_RIDE_VEHICLE_AURA",    STATUS_NEVER,    &WorldSession::Handle_ServerSide               },
  2114.      /*0x49E*/ { "SMSG_CRITERIA_DELETED",                        STATUS_NEVER,    &WorldSession::Handle_ServerSide               },
  2115. @@ -1218,8 +1218,8 @@ OpcodeHandler opcodeTable[NUM_MSG_TYPES] =
  2116.      /*0x4A5*/ { "UMSG_UNKNOWN_1189",                            STATUS_NEVER,    &WorldSession::Handle_NULL                     },
  2117.      /*0x4A6*/ { "SMSG_BATTLEGROUND_INFO_THROTTLED",             STATUS_NEVER,    &WorldSession::Handle_ServerSide               },
  2118.      /*0x4A7*/ { "SMSG_PLAYER_VEHICLE_DATA",                     STATUS_NEVER,    &WorldSession::Handle_ServerSide               },
  2119. -    /*0x4A8*/ { "CMSG_UNKNOWN_1192",                            STATUS_NEVER,    &WorldSession::Handle_NULL                     },
  2120. -    /*0x4A9*/ { "CMSG_EJECT_PASSENGER",                         STATUS_NEVER,    &WorldSession::Handle_NULL                     },
  2121. +    /*0x4A8*/ { "CMSG_PLAYER_VEHICLE_ENTER",                    STATUS_LOGGEDIN, &WorldSession::HandleEnterPlayerVehicle        },
  2122. +    /*0x4A9*/ { "CMSG_EJECT_PASSENGER",                         STATUS_LOGGEDIN, &WorldSession::HandleEjectPasenger             },
  2123.      /*0x4AA*/ { "SMSG_PET_GUIDS",                               STATUS_NEVER,    &WorldSession::Handle_ServerSide               },
  2124.      /*0x4AB*/ { "SMSG_CLIENTCACHE_VERSION",                     STATUS_NEVER,    &WorldSession::Handle_ServerSide               },
  2125.      /*0x4AC*/ { "UMSG_UNKNOWN_1196",                            STATUS_NEVER,    &WorldSession::Handle_NULL                     },
  2126. diff --git a/src/game/Pet.cpp b/src/game/Pet.cpp
  2127. index 0147df0..63cfdcc 100644
  2128. --- a/src/game/Pet.cpp
  2129. +++ b/src/game/Pet.cpp
  2130. @@ -40,7 +40,7 @@ Pet::Pet(PetType type) :
  2131.  Creature(CREATURE_SUBTYPE_PET),
  2132.  m_resetTalentsCost(0), m_resetTalentsTime(0), m_usedTalentCount(0),
  2133.  m_removed(false), m_happinessTimer(7500), m_petType(type), m_duration(0),
  2134. -m_bonusdamage(0), m_auraUpdateMask(0), m_loading(false),
  2135. +m_bonusdamage(0), m_loading(false),
  2136.  m_declinedname(NULL), m_petModeFlags(PET_MODE_DEFAULT)
  2137.  {
  2138.      m_name = "Pet";
  2139. diff --git a/src/game/Pet.h b/src/game/Pet.h
  2140. index 1a5d473..d9aa51c 100644
  2141. --- a/src/game/Pet.h
  2142. +++ b/src/game/Pet.h
  2143. @@ -237,10 +237,6 @@ class Pet : public Creature
  2144.          time_t  m_resetTalentsTime;
  2145.          uint32  m_usedTalentCount;
  2146.  
  2147. -        const uint64& GetAuraUpdateMask() const { return m_auraUpdateMask; }
  2148. -        void SetAuraUpdateMask(uint8 slot) { m_auraUpdateMask |= (uint64(1) << slot); }
  2149. -        void ResetAuraUpdateMask() { m_auraUpdateMask = 0; }
  2150. -
  2151.          // overwrite Creature function for name localization back to WorldObject version without localization
  2152.          const char* GetNameForLocaleIdx(int32 locale_idx) const { return WorldObject::GetNameForLocaleIdx(locale_idx); }
  2153.  
  2154. @@ -252,7 +248,6 @@ class Pet : public Creature
  2155.          PetType m_petType;
  2156.          int32   m_duration;                                 // time until unsummon (used mostly for summoned guardians and not used for controlled pets)
  2157.          int32   m_bonusdamage;
  2158. -        uint64  m_auraUpdateMask;
  2159.          bool    m_loading;
  2160.  
  2161.          DeclinedName *m_declinedname;
  2162. diff --git a/src/game/PetHandler.cpp b/src/game/PetHandler.cpp
  2163. index afcf297..aa24277 100644
  2164. --- a/src/game/PetHandler.cpp
  2165. +++ b/src/game/PetHandler.cpp
  2166. @@ -313,7 +313,7 @@ void WorldSession::HandlePetNameQueryOpcode( WorldPacket & recv_data )
  2167.  
  2168.  void WorldSession::SendPetNameQuery( uint64 petguid, uint32 petnumber)
  2169.  {
  2170. -    Creature* pet = _player->GetMap()->GetAnyTypeCreature(petguid);
  2171. +    Creature* pet = ObjectAccessor::GetAnyTypeCreature(*_player, petguid);
  2172.      if(!pet || !pet->GetCharmInfo() || pet->GetCharmInfo()->GetPetNumber() != petnumber)
  2173.      {
  2174.          WorldPacket data(SMSG_PET_NAME_QUERY_RESPONSE, (4+1+4+1));
  2175. @@ -353,7 +353,12 @@ void WorldSession::HandlePetSetAction( WorldPacket & recv_data )
  2176.  
  2177.      recv_data >> petguid;
  2178.  
  2179. -    Creature* pet = _player->GetMap()->GetAnyTypeCreature(petguid);
  2180. +    // FIXME: charmed case
  2181. +    //Pet* pet = ObjectAccessor::Instance().GetPet(petguid);
  2182. +    if(ObjectAccessor::FindPlayer(petguid))
  2183. +        return;
  2184. +
  2185. +    Creature* pet = ObjectAccessor::GetAnyTypeCreature(*_player, petguid);
  2186.  
  2187.      if(!pet || (pet != _player->GetPet() && pet != _player->GetCharm()))
  2188.      {
  2189. @@ -542,7 +547,8 @@ void WorldSession::HandlePetAbandon( WorldPacket & recv_data )
  2190.          return;
  2191.  
  2192.      // pet/charmed
  2193. -    if (Creature* pet = _player->GetMap()->GetAnyTypeCreature(guid))
  2194. +    Creature* pet = ObjectAccessor::GetAnyTypeCreature(*_player, guid);
  2195. +    if (pet)
  2196.      {
  2197.          if (pet->IsPet())
  2198.          {
  2199. @@ -596,7 +602,10 @@ void WorldSession::HandlePetSpellAutocastOpcode( WorldPacket& recvPacket )
  2200.      uint8  state;                                           //1 for on, 0 for off
  2201.      recvPacket >> guid >> spellid >> state;
  2202.  
  2203. -    Creature* pet = _player->GetMap()->GetAnyTypeCreature(guid);
  2204. +    if(ObjectAccessor::FindPlayer(guid))
  2205. +        return;
  2206. +
  2207. +    Creature* pet=ObjectAccessor::GetAnyTypeCreature(*_player,guid);
  2208.      if (!pet || (guid != _player->GetPetGuid() && guid != _player->GetCharmGuid()))
  2209.      {
  2210.          sLog.outError("HandlePetSpellAutocastOpcode. %s isn't pet of %s .", guid.GetString().c_str(), GetPlayer()->GetObjectGuid().GetString().c_str());
  2211. @@ -626,6 +635,23 @@ void WorldSession::HandlePetSpellAutocastOpcode( WorldPacket& recvPacket )
  2212.  void WorldSession::HandlePetCastSpellOpcode( WorldPacket& recvPacket )
  2213.  {
  2214.      DETAIL_LOG("WORLD: CMSG_PET_CAST_SPELL");
  2215. +    recvPacket.hexlike();
  2216. +    recvPacket.print_storage();
  2217. +
  2218. +    //2 - 0 - 0 - 43 - 129 - 0 - 80 - 241 | - 42 - 211 - 253 - 0 | - 0 | - 2 |- 96 - 0 - 0 - 0 | - 0 - 26
  2219. +    //- 164 - 59 - 196 - 174 - 98 - 131 | - 194 - 182 - 171 - 218| - 67 - 0 - 48 - 93| - 0 - 196 - 32
  2220. +    //- 177| - 242 - 193 - 22 - 110 - 224 - 67 - 203 - 166 | - 68 - 61 - 133 - 1| - 240 - 66 - 1 - 183 |
  2221. +    //- 0 - 0 - 0 - 217| - 2 - 43 - 129 - 80 - 241 - 0 - 10 - 0 - 0 - 0 - 0 - 76 - 109 - 175 - 0
  2222. +    //- 238 - 115 - 58 - 196 - 20 - 110 - 121 - 194 - 187 - 107 - 217 - 67 - 32 - 44 - 27 - 62 - 217
  2223. +    //- 1 - 36 - 129 - 80 - 241 - 0 - 0 - 160 - 64 - 0 - 0 - 160 - 64 - 0 - 0 - 160 - 64 - 192 - 233
  2224. +    //- 172 - 62 - 4 - 0 - 0 - 0 - 7 - 230 - 0 - 0 - 0 -
  2225. +
  2226. +    //5 - 0 - 0 - 43 - 129 - 0 - 80 - 241 | - 85 - 211 - 253 - 0 | - 0 | - 2 | - 96 - 0 - 0 - 0 | - 0 - 69 - 60 - 61
  2227. +    //- 196 - 171 - 248 - 107| - 194 - 8 - 236 - 218 | - 67 - 0 - 177 - 11 | - 46 - 196 - 89 - 16 | - 14 - 195
  2228. +    //- 5 - 38 - 231 - 67 - 23 - 221 | - 110 - 62 - 15 - 3 | - 240 - 66 -| 1 - 183 | - 0 - 0 - 0 - 217 | - 5 - 43
  2229. +    //- 129 - 80 - 241 - 0 - 10 - 0 - 0 - 0 - 0 - 233 - 41 - 203 - 0 - 106 - 207 - 59 - 196 - 179 - 173 - 83
  2230. +    //- 194 - 8 - 108 - 217 - 67 - 127 - 153 - 170 - 64 - 217 - 4 - 36 - 129 - 80 - 241 - 0 - 0 - 160 - 64
  2231. +    //- 0 - 0 - 160 - 64 - 0 - 0 - 160 - 64 - 7 - 77 - 175 - 64 - 4 - 0 - 0 - 0 - 7 - 195 - 0 - 0 - 0 -
  2232.  
  2233.      ObjectGuid guid;
  2234.      uint32 spellid;
  2235. @@ -636,7 +662,10 @@ void WorldSession::HandlePetCastSpellOpcode( WorldPacket& recvPacket )
  2236.  
  2237.      DEBUG_LOG("WORLD: CMSG_PET_CAST_SPELL, %s, cast_count: %u, spellid %u, unk_flags %u", guid.GetString().c_str(), cast_count, spellid, unk_flags);
  2238.  
  2239. -    Creature* pet = _player->GetMap()->GetAnyTypeCreature(guid);
  2240. +    if (guid.IsPlayer())
  2241. +        return;
  2242. +
  2243. +    Creature* pet = ObjectAccessor::GetAnyTypeCreature(*_player,guid);
  2244.  
  2245.      if (!pet || (guid != _player->GetPetGuid() && guid != _player->GetCharmGuid()))
  2246.      {
  2247. diff --git a/src/game/Player.cpp b/src/game/Player.cpp
  2248. index acae59c..a2be5d8 100644
  2249. --- a/src/game/Player.cpp
  2250. +++ b/src/game/Player.cpp
  2251. @@ -460,7 +460,6 @@ Player::Player (WorldSession *session): Unit(), m_mover(this), m_camera(this), m
  2252.      // group is initialized in the reference constructor
  2253.      SetGroupInvite(NULL);
  2254.      m_groupUpdateMask = 0;
  2255. -    m_auraUpdateMask = 0;
  2256.  
  2257.      duel = NULL;
  2258.  
  2259. @@ -1755,6 +1754,11 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati
  2260.          m_movementInfo.ClearTransportData();
  2261.      }
  2262.  
  2263. +    if (GetVehicleKit())
  2264. +        GetVehicleKit()->RemoveAllPassengers();
  2265. +
  2266. +    ExitVehicle();
  2267. +
  2268.      // The player was ported to another map and looses the duel immediately.
  2269.      // We have to perform this check before the teleport, otherwise the
  2270.      // ObjectAccessor won't find the flag.
  2271. @@ -2239,7 +2243,7 @@ Creature* Player::GetNPCIfCanInteractWith(ObjectGuid guid, uint32 npcflagmask)
  2272.          return NULL;
  2273.  
  2274.      // exist (we need look pets also for some interaction (quest/etc)
  2275. -    Creature *unit = GetMap()->GetAnyTypeCreature(guid);
  2276. +    Creature *unit = ObjectAccessor::GetAnyTypeCreature(*this,guid);
  2277.      if (!unit)
  2278.          return NULL;
  2279.  
  2280. @@ -4000,6 +4004,7 @@ void Player::InitVisibleBits()
  2281.      updateVisualBits.SetBit(PLAYER_BYTES_3);
  2282.      updateVisualBits.SetBit(PLAYER_DUEL_TEAM);
  2283.      updateVisualBits.SetBit(PLAYER_GUILD_TIMESTAMP);
  2284. +    updateVisualBits.SetBit(UNIT_NPC_FLAGS);
  2285.  
  2286.      // PLAYER_QUEST_LOG_x also visible bit on official (but only on party/raid)...
  2287.      for(uint16 i = PLAYER_QUEST_LOG_1_1; i < PLAYER_QUEST_LOG_25_2; i += MAX_QUEST_OFFSET)
  2288. @@ -6026,7 +6031,9 @@ ActionButton const* Player::GetActionButton(uint8 button)
  2289.  
  2290.  bool Player::SetPosition(float x, float y, float z, float orientation, bool teleport)
  2291.  {
  2292. -    // prevent crash when a bad coord is sent by the client
  2293. +    if(!Unit::SetPosition(x, y, z, orientation, teleport))
  2294. +        return false;
  2295. +
  2296.      if(!MaNGOS::IsValidMapCoord(x,y,z,orientation))
  2297.      {
  2298.          DEBUG_LOG("Player::SetPosition(%f, %f, %f, %f, %d) .. bad coordinates for player %d!",x,y,z,orientation,teleport,GetGUIDLow());
  2299. @@ -8506,6 +8513,41 @@ void Player::SendInitWorldStates(uint32 zoneid, uint32 areaid)
  2300.              break;
  2301.          case 3703:                                          // Shattrath City
  2302.              break;
  2303. +        case 4384:                                          // SA
  2304. +            /*if (bg && bg->GetTypeID() == BATTLEGROUND_SA)
  2305. +                bg->FillInitialWorldStates(data);
  2306. +            else
  2307. +            {*/
  2308. +                // 1-3 A defend, 4-6 H defend, 7-9 unk defend, 1 - ok, 2 - half destroyed, 3 - destroyed
  2309. +                data << uint32(0xf09) << uint32(0x4);       // 7  3849 Gate of Temple
  2310. +                data << uint32(0xe36) << uint32(0x4);       // 8  3638 Gate of Yellow Moon
  2311. +                data << uint32(0xe27) << uint32(0x4);       // 9  3623 Gate of Green Emerald
  2312. +                data << uint32(0xe24) << uint32(0x4);       // 10 3620 Gate of Blue Sapphire
  2313. +                data << uint32(0xe21) << uint32(0x4);       // 11 3617 Gate of Red Sun
  2314. +                data << uint32(0xe1e) << uint32(0x4);       // 12 3614 Gate of Purple Ametyst
  2315. +
  2316. +                data << uint32(0xdf3) << uint32(0x0);       // 13 3571 bonus timer (1 - on, 0 - off)
  2317. +                data << uint32(0xded) << uint32(0x0);       // 14 3565 Horde Attacker
  2318. +                data << uint32(0xdec) << uint32(0x1);       // 15 3564 Alliance Attacker
  2319. +                // End Round (timer), better explain this by example, eg. ends in 19:59 -> A:BC
  2320. +                data << uint32(0xde9) << uint32(0x9);       // 16 3561 C
  2321. +                data << uint32(0xde8) << uint32(0x5);       // 17 3560 B
  2322. +                data << uint32(0xde7) << uint32(0x19);      // 18 3559 A
  2323. +                data << uint32(0xe35) << uint32(0x1);       // 19 3637 East g - Horde control
  2324. +                data << uint32(0xe34) << uint32(0x1);       // 20 3636 West g - Horde control
  2325. +                data << uint32(0xe33) << uint32(0x1);       // 21 3635 South g - Horde control
  2326. +                data << uint32(0xe32) << uint32(0x0);       // 22 3634 East g - Alliance control
  2327. +                data << uint32(0xe31) << uint32(0x0);       // 23 3633 West g - Alliance control
  2328. +                data << uint32(0xe30) << uint32(0x0);       // 24 3632 South g - Alliance control
  2329. +                data << uint32(0xe2f) << uint32(0x1);       // 25 3631 Chamber of Ancients - Horde control
  2330. +                data << uint32(0xe2e) << uint32(0x0);       // 26 3630 Chamber of Ancients - Alliance control
  2331. +                data << uint32(0xe2d) << uint32(0x0);       // 27 3629 Beach1 - Horde control
  2332. +                data << uint32(0xe2c) << uint32(0x0);       // 28 3628 Beach2 - Horde control
  2333. +                data << uint32(0xe2b) << uint32(0x1);       // 29 3627 Beach1 - Alliance control
  2334. +                data << uint32(0xe2a) << uint32(0x1);       // 30 3626 Beach2 - Alliance control
  2335. +                // and many unks...
  2336. +            //}
  2337. +            break;
  2338.          default:
  2339.              FillInitialWorldState(data,count, 0x914, 0x0);  // 2324 7
  2340.              FillInitialWorldState(data,count, 0x913, 0x0);  // 2323 8
  2341. @@ -13095,7 +13137,8 @@ void Player::PrepareQuestMenu(ObjectGuid guid)
  2342.      QuestRelationsMapBounds irbounds;
  2343.  
  2344.      // pets also can have quests
  2345. -    if (Creature *pCreature = GetMap()->GetAnyTypeCreature(guid))
  2346. +    Creature *pCreature = ObjectAccessor::GetAnyTypeCreature(*this, guid);
  2347. +    if (pCreature)
  2348.      {
  2349.          rbounds = sObjectMgr.GetCreatureQuestRelationsMapBounds(pCreature->GetEntry());
  2350.          irbounds = sObjectMgr.GetCreatureQuestInvolvedRelationsMapBounds(pCreature->GetEntry());
  2351. @@ -13197,7 +13240,8 @@ void Player::SendPreparedQuest(ObjectGuid guid)
  2352.          std::string title = "";
  2353.  
  2354.          // need pet case for some quests
  2355. -        if (Creature *pCreature = GetMap()->GetAnyTypeCreature(guid))
  2356. +        Creature *pCreature = ObjectAccessor::GetAnyTypeCreature(*this,guid);
  2357. +        if (pCreature)
  2358.          {
  2359.              uint32 textid = GetGossipTextId(pCreature);
  2360.  
  2361. @@ -13268,7 +13312,8 @@ Quest const* Player::GetNextQuest(ObjectGuid guid, Quest const *pQuest)
  2362.  {
  2363.      QuestRelationsMapBounds rbounds;
  2364.  
  2365. -    if (Creature *pCreature = GetMap()->GetAnyTypeCreature(guid))
  2366. +    Creature *pCreature = ObjectAccessor::GetAnyTypeCreature(*this,guid);
  2367. +    if( pCreature )
  2368.      {
  2369.          rbounds = sObjectMgr.GetCreatureQuestRelationsMapBounds(pCreature->GetEntry());
  2370.      }
  2371. @@ -18328,7 +18373,10 @@ void Player::HandleStealthedUnitsDetection()
  2372.                  // target aura duration for caster show only if target exist at caster client
  2373.                  // send data at target visibility change (adding to client)
  2374.                  if((*i)!=this && (*i)->isType(TYPEMASK_UNIT))
  2375. +                {
  2376.                      SendAurasForTarget(*i);
  2377. +                    (*i)->SendHeartBeat(false);
  2378. +                }
  2379.              }
  2380.          }
  2381.          else
  2382. @@ -18363,7 +18411,7 @@ bool Player::ActivateTaxiPathTo(std::vector<uint32> const& nodes, Creature* npc
  2383.      if(npc)
  2384.      {
  2385.          // not let cheating with start flight mounted
  2386. -        if(IsMounted())
  2387. +        if(IsMounted() || GetVehicle() || GetVehicleGUID())
  2388.          {
  2389.              WorldPacket data(SMSG_ACTIVATETAXIREPLY, 4);
  2390.              data << uint32(ERR_TAXIPLAYERALREADYMOUNTED);
  2391. @@ -18392,6 +18440,7 @@ bool Player::ActivateTaxiPathTo(std::vector<uint32> const& nodes, Creature* npc
  2392.      else
  2393.      {
  2394.          RemoveSpellsCausingAura(SPELL_AURA_MOUNTED);
  2395. +        ExitVehicle();
  2396.  
  2397.          if( m_ShapeShiftFormSpellId && m_form != FORM_BATTLESTANCE && m_form != FORM_BERSERKERSTANCE && m_form != FORM_DEFENSIVESTANCE && m_form != FORM_SHADOW )
  2398.              RemoveAurasDueToSpell(m_ShapeShiftFormSpellId);
  2399. @@ -19540,7 +19589,10 @@ void Player::UpdateVisibilityOf(WorldObject const* viewPoint, WorldObject* targe
  2400.              // target aura duration for caster show only if target exist at caster client
  2401.              // send data at target visibility change (adding to client)
  2402.              if(target!=this && target->isType(TYPEMASK_UNIT))
  2403. +            {
  2404.                  SendAurasForTarget((Unit*)target);
  2405. +                ((Unit*)target)->SendHeartBeat(false);
  2406. +            }
  2407.  
  2408.              if(target->GetTypeId()==TYPEID_UNIT && ((Creature*)target)->isAlive())
  2409.                  ((Creature*)target)->SendMonsterMoveWithSpeedToCurrentDestination(this);
  2410. @@ -19605,13 +19657,22 @@ void Player::InitPrimaryProfessions()
  2411.  void Player::SendComboPoints()
  2412.  {
  2413.      Unit *combotarget = ObjectAccessor::GetUnit(*this, m_comboTargetGuid);
  2414. -    if (combotarget)
  2415. -    {
  2416. -        WorldPacket data(SMSG_UPDATE_COMBO_POINTS, combotarget->GetPackGUID().size()+1);
  2417. -        data << combotarget->GetPackGUID();
  2418. -        data << uint8(m_comboPoints);
  2419. -        GetSession()->SendPacket(&data);
  2420. -    }
  2421. +    if (!combotarget)
  2422. +        return;
  2423. +
  2424. +    WorldPacket data;
  2425. +    if(!GetVehicleGUID())
  2426. +        data.Initialize(SMSG_UPDATE_COMBO_POINTS, combotarget->GetPackGUID().size()+1);
  2427. +    else{
  2428. +       if(Unit *vehicle = ObjectAccessor::GetUnit(*this, GetVehicleGUID()))
  2429. +       {
  2430. +           data.Initialize(SMSG_PET_UPDATE_COMBO_POINTS, vehicle->GetPackGUID().size()+combotarget->GetPackGUID().size()+1);
  2431. +           data << vehicle->GetPackGUID();
  2432. +       }else return;
  2433. +    }
  2434. +    data << combotarget->GetPackGUID();
  2435. +    data << uint8(m_comboPoints);
  2436. +    GetSession()->SendPacket(&data);
  2437.  }
  2438.  
  2439.  void Player::AddComboPoints(Unit* target, int8 count)
  2440. @@ -19734,6 +19795,13 @@ void Player::SendInitialPacketsBeforeAddToMap()
  2441.  
  2442.  void Player::SendInitialPacketsAfterAddToMap()
  2443.  {
  2444. +    if(getClass() == CLASS_DEATH_KNIGHT)
  2445. +        ResyncRunes();
  2446. +
  2447. +    WorldPacket data0(SMSG_SET_PHASE_SHIFT, 4);
  2448. +    data0 << uint32(GetPhaseMask());
  2449. +    GetSession()->SendPacket(&data0);
  2450. +
  2451.      // update zone
  2452.      uint32 newzone, newarea;
  2453.      GetZoneAndAreaId(newzone,newarea);
  2454. @@ -19772,6 +19840,14 @@ void Player::SendInitialPacketsAfterAddToMap()
  2455.          SendMessageToSet(&data2,true);
  2456.      }
  2457.  
  2458. +    if(GetVehicle() || GetVehicleGUID())
  2459. +    {
  2460. +        WorldPacket data3(SMSG_FORCE_MOVE_ROOT, 10);
  2461. +        data3 << GetPackGUID();
  2462. +        data3 << (uint32)((m_movementInfo.GetVehicleSeatFlags() & SF_CAN_CAST) ? 2 : 0);
  2463. +        SendMessageToSet(&data3,true);
  2464. +    }
  2465. +
  2466.      SendAurasForTarget(this);
  2467.      SendEnchantmentDurations();                             // must be after add to map
  2468.      SendItemDurations();                                    // must be after add to map
  2469. @@ -19786,7 +19862,7 @@ void Player::SendUpdateToOutOfRangeGroupMembers()
  2470.  
  2471.      m_groupUpdateMask = GROUP_UPDATE_FLAG_NONE;
  2472.      m_auraUpdateMask = 0;
  2473. -    if(Pet *pet = GetPet())
  2474. +    if(Unit *pet = GetCharmOrPet())
  2475.          pet->ResetAuraUpdateMask();
  2476.  }
  2477.  
  2478. @@ -20250,7 +20326,7 @@ void Player::UpdateForQuestWorldObjects()
  2479.          }
  2480.          else if (itr->IsCreatureOrVehicle())
  2481.          {
  2482. -            Creature *obj = GetMap()->GetAnyTypeCreature(*itr);
  2483. +            Creature *obj = ObjectAccessor::GetAnyTypeCreature(*this, *itr);
  2484.              if(!obj)
  2485.                  continue;
  2486.  
  2487. @@ -20523,8 +20599,8 @@ void Player::RewardSinglePlayerAtKill(Unit* pVictim)
  2488.      // honor can be in PvP and !PvP (racial leader) cases
  2489.      RewardHonor(pVictim,1);
  2490.  
  2491. -    // xp and reputation only in !PvP case
  2492. -    if(!PvP)
  2493. +    // xp and reputation only in !PvP case and not in vehicle
  2494. +    if(!PvP && !(GetVehicleGUID() && (m_movementInfo.GetVehicleFlags() & VF_GIVE_EXP)))
  2495.      {
  2496.          RewardReputation(pVictim,1);
  2497.          GiveXP(xp, pVictim);
  2498. @@ -21025,26 +21101,16 @@ void Player::ApplyGlyphs(bool apply)
  2499.          ApplyGlyph(i,apply);
  2500.  }
  2501.  
  2502. -void Player::EnterVehicle(Vehicle *vehicle)
  2503. +void Player::SendEnterVehicle(Vehicle *vehicle)
  2504.  {
  2505. -    VehicleEntry const *ve = sVehicleStore.LookupEntry(vehicle->GetVehicleId());
  2506. -    if(!ve)
  2507. -        return;
  2508. -
  2509. -    VehicleSeatEntry const *veSeat = sVehicleSeatStore.LookupEntry(ve->m_seatID[0]);
  2510. -    if(!veSeat)
  2511. -        return;
  2512. -
  2513. -    vehicle->SetCharmerGuid(GetObjectGuid());
  2514. -    vehicle->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK);
  2515. -    vehicle->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED);
  2516. -    vehicle->setFaction(getFaction());
  2517. -
  2518. -    SetCharm(vehicle);                                      // charm
  2519. -    m_camera.SetView(vehicle);                              // set view
  2520. -
  2521. -    SetClientControl(vehicle, 1);                           // redirect controls to vehicle
  2522. -    SetMover(vehicle);
  2523. +    if(m_transport)                                         // if we were on a transport, leave
  2524. +    {
  2525. +        m_transport->RemovePassenger(this);
  2526. +        m_transport = NULL;
  2527. +    }
  2528. +    // vehicle is our transport from now, if we get to zeppelin or boat
  2529. +    // with vehicle, ONLY my vehicle will be passenger on that transport
  2530. +    // player ----> vehicle ----> zeppelin
  2531.  
  2532.      WorldPacket data(SMSG_ON_CANCEL_EXPECTED_RIDE_VEHICLE_AURA, 0);
  2533.      GetSession()->SendPacket(&data);
  2534. @@ -21061,60 +21127,20 @@ void Player::EnterVehicle(Vehicle *vehicle)
  2535.      data << vehicle->GetOrientation();                      // o
  2536.      // transport part, TODO: load/calculate seat offsets
  2537.      data << vehicle->GetObjectGuid();                       // transport guid
  2538. -    data << float(veSeat->m_attachmentOffsetX);             // transport offsetX
  2539. -    data << float(veSeat->m_attachmentOffsetY);             // transport offsetY
  2540. -    data << float(veSeat->m_attachmentOffsetZ);             // transport offsetZ
  2541. -    data << float(0);                                       // transport orientation
  2542. +    data << float(m_movementInfo.GetTransportPos()->x);     // transport offsetX
  2543. +    data << float(m_movementInfo.GetTransportPos()->y);     // transport offsetY
  2544. +    data << float(m_movementInfo.GetTransportPos()->z);     // transport offsetZ
  2545. +    data << float(m_movementInfo.GetTransportPos()->o);     // transport orientation
  2546.      data << uint32(getMSTime());                            // transport time
  2547.      data << uint8(0);                                       // seat
  2548.      // end of transport part
  2549.      data << uint32(0);                                      // fall time
  2550.      GetSession()->SendPacket(&data);
  2551.  
  2552. -    data.Initialize(SMSG_PET_SPELLS, 8+2+4+4+4*MAX_UNIT_ACTION_BAR_INDEX+1+1);
  2553. -    data << vehicle->GetObjectGuid();
  2554. -    data << uint16(0);
  2555. -    data << uint32(0);
  2556. -    data << uint32(0x00000101);
  2557. -
  2558. -    for(uint32 i = 0; i < 10; ++i)
  2559. -        data << uint16(0) << uint8(0) << uint8(i+8);
  2560. -
  2561. -    data << uint8(0);
  2562. -    data << uint8(0);
  2563. -    GetSession()->SendPacket(&data);
  2564. -}
  2565. -
  2566. -void Player::ExitVehicle(Vehicle *vehicle)
  2567. -{
  2568. -    vehicle->SetCharmerGuid(ObjectGuid());
  2569. -    vehicle->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK);
  2570. -    vehicle->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED);
  2571. -    vehicle->setFaction((GetTeam() == ALLIANCE) ? vehicle->GetCreatureInfo()->faction_A : vehicle->GetCreatureInfo()->faction_H);
  2572. -
  2573. -    SetCharm(NULL);
  2574. -    m_camera.ResetView();
  2575. -
  2576. -    SetClientControl(vehicle, 0);
  2577. -    SetMover(NULL);
  2578. -
  2579. -    WorldPacket data(MSG_MOVE_TELEPORT_ACK, 30);
  2580. -    data << GetPackGUID();
  2581. -    data << uint32(0);                                      // counter?
  2582. -    data << uint32(MOVEFLAG_ROOT);                          // fly unk
  2583. -    data << uint16(MOVEFLAG2_UNK4);                         // special flags
  2584. -    data << uint32(getMSTime());                            // time
  2585. -    data << vehicle->GetPositionX();                        // x
  2586. -    data << vehicle->GetPositionY();                        // y
  2587. -    data << vehicle->GetPositionZ();                        // z
  2588. -    data << vehicle->GetOrientation();                      // o
  2589. -    data << uint32(0);                                      // fall time
  2590. -    GetSession()->SendPacket(&data);
  2591. -
  2592. -    RemovePetActionBar();
  2593. -
  2594. -    // maybe called at dummy aura remove?
  2595. -    // CastSpell(this, 45472, true);                        // Parachute
  2596. +    /*data.Initialize(SMSG_UNKNOWN_1191, 12);
  2597. +    data << uint64(GetGUID());
  2598. +    data << uint64(vehicle->GetVehicleId());                      // not sure
  2599. +    SendMessageToSet(&data, true);*/
  2600.  }
  2601.  
  2602.  bool Player::isTotalImmune()
  2603. diff --git a/src/game/Player.h b/src/game/Player.h
  2604. index 3257ba5..dc38be0 100644
  2605. --- a/src/game/Player.h
  2606. +++ b/src/game/Player.h
  2607. @@ -2254,8 +2254,8 @@ class MANGOS_DLL_SPEC Player : public Unit
  2608.          Unit* GetMover() const { return m_mover; }
  2609.          bool IsSelfMover() const { return m_mover == this; }// normal case for player not controlling other unit
  2610.  
  2611. -        void EnterVehicle(Vehicle *vehicle);
  2612. -        void ExitVehicle(Vehicle *vehicle);
  2613. +        // vehicle system
  2614. +        void SendEnterVehicle(Vehicle *vehicle);
  2615.  
  2616.          ObjectGuid const& GetFarSightGuid() const { return GetGuidValue(PLAYER_FARSIGHT); }
  2617.  
  2618. @@ -2358,8 +2358,6 @@ class MANGOS_DLL_SPEC Player : public Unit
  2619.          uint8 GetSubGroup() const { return m_group.getSubGroup(); }
  2620.          uint32 GetGroupUpdateFlag() const { return m_groupUpdateMask; }
  2621.          void SetGroupUpdateFlag(uint32 flag) { m_groupUpdateMask |= flag; }
  2622. -        const uint64& GetAuraUpdateMask() const { return m_auraUpdateMask; }
  2623. -        void SetAuraUpdateMask(uint8 slot) { m_auraUpdateMask |= (uint64(1) << slot); }
  2624.          Player* GetNextRandomRaidMember(float radius);
  2625.          PartyResult CanUninviteFromGroup() const;
  2626.          // BattleGround Group System
  2627. @@ -2622,7 +2620,6 @@ class MANGOS_DLL_SPEC Player : public Unit
  2628.          GroupReference m_originalGroup;
  2629.          Group *m_groupInvite;
  2630.          uint32 m_groupUpdateMask;
  2631. -        uint64 m_auraUpdateMask;
  2632.  
  2633.          uint64 m_miniPet;
  2634.  
  2635. diff --git a/src/game/QuestHandler.cpp b/src/game/QuestHandler.cpp
  2636. index cd08544..38124a6 100644
  2637. --- a/src/game/QuestHandler.cpp
  2638. +++ b/src/game/QuestHandler.cpp
  2639. @@ -655,9 +655,8 @@ void WorldSession::HandleQuestgiverStatusMultipleQuery(WorldPacket& /*recvPacket
  2640.          if (itr->IsCreatureOrPet())
  2641.          {
  2642.              // need also pet quests case support
  2643. -            Creature *questgiver = GetPlayer()->GetMap()->GetAnyTypeCreature(*itr);
  2644. -
  2645. -            if (!questgiver || questgiver->IsHostileTo(_player))
  2646. +            Creature *questgiver = ObjectAccessor::GetAnyTypeCreature(*GetPlayer(),*itr);
  2647. +            if(!questgiver || questgiver->IsHostileTo(_player))
  2648.                  continue;
  2649.  
  2650.              if (!questgiver->HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER))
  2651. diff --git a/src/game/ReactorAI.cpp b/src/game/ReactorAI.cpp
  2652. index 5eae25a..4af62d7 100644
  2653. --- a/src/game/ReactorAI.cpp
  2654. +++ b/src/game/ReactorAI.cpp
  2655. @@ -116,6 +116,7 @@ ReactorAI::EnterEvadeMode()
  2656.          DEBUG_FILTER_LOG(LOG_FILTER_AI_AND_MOVEGENSS, "Creature stopped attacking, victim %s [guid=%u]", victim->isAlive() ? "out run him" : "is dead", m_creature->GetGUIDLow());
  2657.      }
  2658.  
  2659. +    m_creature->ExitVehicle();
  2660.      m_creature->RemoveAllAuras();
  2661.      m_creature->DeleteThreatList();
  2662.      i_victimGuid = 0;
  2663. diff --git a/src/game/SharedDefines.h b/src/game/SharedDefines.h
  2664. index 13abe2f..462ac22 100644
  2665. --- a/src/game/SharedDefines.h
  2666. +++ b/src/game/SharedDefines.h
  2667. @@ -2472,6 +2472,29 @@ enum DiminishingGroup
  2668.      DIMINISHING_LIMITONLY
  2669.  };
  2670.  
  2671. +
  2672. +/* NOTE : vehicles and seats has their own flags in DBC,
  2673. +but for now, they are too unknown for us, to use them */
  2674. +enum CustomVehicleFLags
  2675. +{
  2676. +    VF_CANT_MOVE                    = 0x0001,                   // vehicle cant move, only turn, maybe handle by some auras?
  2677. +    VF_FACTION                      = 0x0002,                   // vehicle retain its own faction
  2678. +    VF_DESPAWN_NPC                  = 0x0004,                   // vehicle will delete npc on spellclick
  2679. +    VF_DESPAWN_AT_LEAVE             = 0x0008,                   // vehicle will be deleted when rider leaves
  2680. +    VF_CAN_BE_HEALED                = 0x0010,                   // vehicle can be healed
  2681. +    VF_GIVE_EXP                     = 0x0020,                   // vehicle will give exp for killing enemies
  2682. +    VF_MOVEMENT                     = 0x0040,                   // vehicle will move on its own, not depending on rider, however rider can cast spells
  2683. +    VF_NON_SELECTABLE               = 0x0080                    // vehicle will be not selectable after rider enter
  2684. +    //VF_HAS_FUEL                     = 0x0100,                   // TODO : find out what energy type is fuel and implement this
  2685. +};
  2686. +
  2687. +enum CustomVehicleSeatFLags
  2688. +{
  2689. +    SF_MAIN_RIDER                   = 0x0001,                   // the one who controlls vehicle, can also cast spells
  2690. +    SF_UNATTACKABLE                 = 0x0002,                   // hided inside, and unatackable until vehicle is destroyed
  2691. +    SF_CAN_CAST                     = 0x0004,                   // player/npc can rotate, and cast OWN spells
  2692. +    SF_UNACCESSIBLE                 = 0x0008                    // player cant enter this seat by normal way (only by script)
  2693. +};
  2694.  enum InstanceResetMethod
  2695.  {
  2696.      INSTANCE_RESET_ALL,
  2697. diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp
  2698. index fddd65a..be21aab 100644
  2699. --- a/src/game/Spell.cpp
  2700. +++ b/src/game/Spell.cpp
  2701. @@ -115,7 +115,8 @@ SpellCastTargets::SpellCastTargets()
  2702.  
  2703.      m_itemTargetEntry  = 0;
  2704.  
  2705. -    m_srcX = m_srcY = m_srcZ = m_destX = m_destY = m_destZ = 0.0f;
  2706. +    m_srcX = m_srcY = m_srcZ = m_srcO = m_destX = m_destY = m_destZ = 0.0f;
  2707. +    m_elevation = m_speed = 0.0f;
  2708.      m_strTarget = "";
  2709.      m_targetMask = 0;
  2710.  }
  2711. @@ -252,6 +253,19 @@ void SpellCastTargets::read( ByteBuffer& data, Unit *caster )
  2712.          data >> m_destX >> m_destY >> m_destZ;
  2713.          if(!MaNGOS::IsValidMapCoord(m_destX, m_destY, m_destZ))
  2714.              throw ByteBufferException(false, data.rpos(), 0, data.size());
  2715. +
  2716. +        if( m_targetMask & TARGET_FLAG_SOURCE_LOCATION )
  2717. +        {
  2718. +            if(data.rpos() + 4 + 4 <= data.size())
  2719. +            {
  2720. +                data >> m_elevation >> m_speed;
  2721. +                // TODO: should also read
  2722. +                m_srcO = caster->GetOrientation();
  2723. +                //*data >> uint16 >> uint8 >> uint32 >> uint32;
  2724. +                //*data >> float >> float >> float >> float...
  2725. +            }
  2726. +        }
  2727. +
  2728.      }
  2729.  
  2730.      if( m_targetMask & TARGET_FLAG_STRING )
  2731. @@ -1582,9 +1596,11 @@ void Spell::SetTargetMap(SpellEffectIndex effIndex, uint32 targetMode, UnitList&
  2732.          case TARGET_TOTEM_FIRE:
  2733.          case TARGET_SELF:
  2734.          case TARGET_SELF2:
  2735. -        case TARGET_AREAEFFECT_CUSTOM_2:
  2736. +        {
  2737. +            // used for targeting gameobjects
  2738.              targetUnitMap.push_back(m_caster);
  2739.              break;
  2740. +        }
  2741.          case TARGET_RANDOM_ENEMY_CHAIN_IN_AREA:
  2742.          {
  2743.              m_targets.m_targetMask = 0;
  2744. @@ -1853,6 +1869,9 @@ void Spell::SetTargetMap(SpellEffectIndex effIndex, uint32 targetMode, UnitList&
  2745.                      break;
  2746.                  default:
  2747.                      FillAreaTargets(targetUnitMap, m_targets.m_destX, m_targets.m_destY, radius, PUSH_DEST_CENTER, SPELL_TARGETS_AOE_DAMAGE);
  2748. +
  2749. +                    // exclude caster (this can be important if this not original caster, for example vehicle)
  2750. +                    targetUnitMap.remove(m_caster);
  2751.                      break;
  2752.              }
  2753.              break;
  2754. @@ -2342,7 +2361,13 @@ void Spell::SetTargetMap(SpellEffectIndex effIndex, uint32 targetMode, UnitList&
  2755.          case TARGET_DYNAMIC_OBJECT_LEFT_SIDE:
  2756.          case TARGET_DYNAMIC_OBJECT_RIGHT_SIDE:
  2757.          {
  2758. -            if (!(m_targets.m_targetMask & TARGET_FLAG_DEST_LOCATION))
  2759. +            //This should be targeting of destructible objects by vehicles (ram spells...)
  2760. +            if(m_spellInfo->EffectImplicitTargetB[effIndex] == TARGET_AREAEFFECT_CUSTOM_2)
  2761. +            {
  2762. +                //FIXME
  2763. +                break;
  2764. +            }
  2765. +            else if (!(m_targets.m_targetMask & TARGET_FLAG_DEST_LOCATION))
  2766.              {
  2767.                  float angle = m_caster->GetOrientation();
  2768.                  switch(targetMode)
  2769. @@ -3313,7 +3338,7 @@ void Spell::finish(bool ok)
  2770.          m_caster->resetAttackTimer(RANGED_ATTACK);*/
  2771.  
  2772.      // Clear combo at finish state
  2773. -    if(m_caster->GetTypeId() == TYPEID_PLAYER && NeedsComboPoints(m_spellInfo))
  2774. +    if((m_caster->GetTypeId() == TYPEID_PLAYER || ((Creature*)m_caster)->IsVehicle()) && NeedsComboPoints(m_spellInfo))
  2775.      {
  2776.          // Not drop combopoints if negative spell and if any miss on enemy exist
  2777.          bool needDrop = true;
  2778. @@ -3329,7 +3354,12 @@ void Spell::finish(bool ok)
  2779.              }
  2780.          }
  2781.          if (needDrop)
  2782. -            ((Player*)m_caster)->ClearComboPoints();
  2783. +        {
  2784. +            if(m_caster->GetTypeId() == TYPEID_PLAYER)
  2785. +                ((Player*)m_caster)->ClearComboPoints();
  2786. +            else
  2787. +                ((Player*)m_caster->GetCharmer())->ClearComboPoints();
  2788. +        }
  2789.      }
  2790.  
  2791.      // potions disabled by client, send event "not in combat" if need
  2792. @@ -4534,11 +4564,16 @@ SpellCastResult Spell::CheckCast(bool strict)
  2793.          return locRes;
  2794.  
  2795.      // not let players cast spells at mount (and let do it to creatures)
  2796. -    if (m_caster->IsMounted() && m_caster->GetTypeId()==TYPEID_PLAYER && !m_IsTriggeredSpell &&
  2797. +    if ((m_caster->IsMounted() || m_caster->GetVehicle() || m_caster->GetVehicleGUID()) && m_caster->GetTypeId()==TYPEID_PLAYER && !m_IsTriggeredSpell &&
  2798.          !IsPassiveSpell(m_spellInfo) && !(m_spellInfo->Attributes & SPELL_ATTR_CASTABLE_WHILE_MOUNTED))
  2799.      {
  2800.          if (m_caster->IsTaxiFlying())
  2801.              return SPELL_FAILED_NOT_ON_TAXI;
  2802. +        else if(m_caster->GetVehicleGUID() || m_caster->GetVehicle())
  2803. +        {
  2804. +            if(!(m_caster->m_movementInfo.GetVehicleSeatFlags() & SF_CAN_CAST))
  2805. +                return SPELL_FAILED_NOT_MOUNTED;
  2806. +        }
  2807.          else
  2808.              return SPELL_FAILED_NOT_MOUNTED;
  2809.      }
  2810. @@ -5374,33 +5409,48 @@ SpellCastResult Spell::CheckPetCast(Unit* target)
  2811.              if(!_target->isAlive())
  2812.                  return SPELL_FAILED_BAD_TARGETS;
  2813.  
  2814. -            if(IsPositiveSpell(m_spellInfo->Id))
  2815. -            {
  2816. -                if(m_caster->IsHostileTo(_target))
  2817. -                    return SPELL_FAILED_BAD_TARGETS;
  2818. -            }
  2819. -            else
  2820. -            {
  2821. -                bool duelvsplayertar = false;
  2822. -                for(int j = 0; j < MAX_EFFECT_INDEX; ++j)
  2823. -                {
  2824. -                                                            //TARGET_DUELVSPLAYER is positive AND negative
  2825. -                    duelvsplayertar |= (m_spellInfo->EffectImplicitTargetA[j] == TARGET_DUELVSPLAYER);
  2826. -                }
  2827. -                if(m_caster->IsFriendlyTo(target) && !duelvsplayertar)
  2828. -                {
  2829. -                    return SPELL_FAILED_BAD_TARGETS;
  2830. -                }
  2831. -            }
  2832. +            if(!IsValidSingleTargetSpell(_target))
  2833. +                return SPELL_FAILED_BAD_TARGETS;
  2834.          }
  2835.                                                              //cooldown
  2836.          if(((Creature*)m_caster)->HasSpellCooldown(m_spellInfo->Id))
  2837.              return SPELL_FAILED_NOT_READY;
  2838.      }
  2839.  
  2840. +    // NOTE : this is done twice, also in spell->prepare(&(spell->m_targets));
  2841.      return CheckCast(true);
  2842.  }
  2843.  
  2844. +bool Spell::IsValidSingleTargetEffect(Unit const* target, Targets type) const
  2845. +{
  2846. +    switch(type)
  2847. +    {
  2848. +        case TARGET_CHAIN_DAMAGE:
  2849. +            return !m_caster->IsFriendlyTo(target);
  2850. +        case TARGET_SINGLE_FRIEND:
  2851. +        case TARGET_AREAEFFECT_PARTY:
  2852. +            return m_caster->IsFriendlyTo(target);
  2853. +       case TARGET_SINGLE_PARTY:
  2854. +            return m_caster != target && m_caster->IsInPartyWith(target);
  2855. +        case TARGET_SINGLE_FRIEND_2:
  2856. +            return m_caster->IsInRaidWith(target);
  2857. +    }
  2858. +    return true;
  2859. +}
  2860. +
  2861. +bool Spell::IsValidSingleTargetSpell(Unit const* target) const
  2862. +{
  2863. +    for(int i = 0; i < 3; ++i)
  2864. +    {
  2865. +        if(!IsValidSingleTargetEffect(target, Targets(m_spellInfo->EffectImplicitTargetA[i])))
  2866. +            return false;
  2867. +        // Need to check B?
  2868. +        //if(!IsValidSingleTargetEffect(m_spellInfo->EffectImplicitTargetB[i], target)
  2869. +        //    return false;
  2870. +    }
  2871. +    return true;
  2872. +}
  2873. +
  2874.  SpellCastResult Spell::CheckCasterAuras() const
  2875.  {
  2876.      // Flag drop spells totally immuned to caster auras
  2877. diff --git a/src/game/Spell.h b/src/game/Spell.h
  2878. index 2bb7e40..a810a51 100644
  2879. --- a/src/game/Spell.h
  2880. +++ b/src/game/Spell.h
  2881. @@ -165,8 +165,9 @@ class SpellCastTargets
  2882.  
  2883.          void Update(Unit* caster);
  2884.  
  2885. -        float m_srcX, m_srcY, m_srcZ;
  2886. +        float m_srcX, m_srcY, m_srcZ, m_srcO;
  2887.          float m_destX, m_destY, m_destZ;
  2888. +        float m_elevation, m_speed;
  2889.          std::string m_strTarget;
  2890.  
  2891.          uint32 m_targetMask;
  2892. @@ -346,6 +347,8 @@ class Spell
  2893.          void EffectPlayMusic(SpellEffectIndex eff_idx);
  2894.          void EffectSpecCount(SpellEffectIndex eff_idx);
  2895.          void EffectActivateSpec(SpellEffectIndex eff_idx);
  2896. +        void EffectSummonVehicle(SpellEffectIndex eff_idx);
  2897. +        void EffectDamageBuilding(SpellEffectIndex eff_idx);
  2898.  
  2899.          Spell(Unit* caster, SpellEntry const *info, bool triggered, ObjectGuid originalCasterGUID = ObjectGuid(), SpellEntry const* triggeredBy = NULL);
  2900.          ~Spell();
  2901. @@ -363,6 +366,8 @@ class Spell
  2902.  
  2903.          SpellCastResult CheckCast(bool strict);
  2904.          SpellCastResult CheckPetCast(Unit* target);
  2905. +        bool IsValidSingleTargetEffect(Unit const* target, Targets type) const;
  2906. +        bool IsValidSingleTargetSpell(Unit const* target) const;
  2907.  
  2908.          // handlers
  2909.          void handle_immediate();
  2910. diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp
  2911. index a2892e1..9899883 100644
  2912. --- a/src/game/SpellAuras.cpp
  2913. +++ b/src/game/SpellAuras.cpp
  2914. @@ -2756,7 +2756,7 @@ void Aura::HandleAuraMounted(bool apply, bool Real)
  2915.          if (minfo)
  2916.              display_id = minfo->modelid;
  2917.  
  2918. -        target->Mount(display_id, GetId());
  2919. +        target->Mount(display_id, GetId(), ci->VehicleEntry);
  2920.      }
  2921.      else
  2922.      {
  2923. @@ -3455,7 +3455,7 @@ void Aura::HandleModPossess(bool apply, bool Real)
  2924.          {
  2925.              ((Creature*)target)->AIM_Initialize();
  2926.          }
  2927. -        else if(target->GetTypeId() == TYPEID_PLAYER)
  2928. +        else if(target->GetTypeId() == TYPEID_PLAYER && !target->GetVehicleGUID())
  2929.          {
  2930.              ((Player*)target)->SetClientControl(target, 0);
  2931.          }
  2932. @@ -3488,7 +3488,7 @@ void Aura::HandleModPossess(bool apply, bool Real)
  2933.  
  2934.          target->SetCharmerGuid(ObjectGuid());
  2935.  
  2936. -        if(target->GetTypeId() == TYPEID_PLAYER)
  2937. +        if(target->GetTypeId() == TYPEID_PLAYER &&  !target->GetVehicleGUID())
  2938.          {
  2939.              ((Player*)target)->setFactionForRace(target->getRace());
  2940.              ((Player*)target)->SetClientControl(target, 1);
  2941. @@ -3790,10 +3790,13 @@ void Aura::HandleAuraModStun(bool apply, bool Real)
  2942.              target->SetStandState(UNIT_STAND_STATE_STAND);// in 1.5 client
  2943.          }
  2944.  
  2945. -        WorldPacket data(SMSG_FORCE_MOVE_ROOT, 8);
  2946. -        data << target->GetPackGUID();
  2947. -        data << uint32(0);
  2948. -        target->SendMessageToSet(&data, true);
  2949. +        if(!target->hasUnitState(UNIT_STAT_ON_VEHICLE))
  2950. +        {
  2951. +            WorldPacket data(SMSG_FORCE_MOVE_ROOT, 8);
  2952. +            data << target->GetPackGUID();
  2953. +            data << uint32(0);
  2954. +            target->SendMessageToSet(&data,true);
  2955. +        }
  2956.  
  2957.          // Summon the Naj'entus Spine GameObject on target if spell is Impaling Spine
  2958.          if(GetId() == 39837)
  2959. @@ -3843,7 +3846,7 @@ void Aura::HandleAuraModStun(bool apply, bool Real)
  2960.          target->clearUnitState(UNIT_STAT_STUNNED);
  2961.          target->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED);
  2962.  
  2963. -        if(!target->hasUnitState(UNIT_STAT_ROOT))         // prevent allow move if have also root effect
  2964. +        if(!target->hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_ON_VEHICLE))         // prevent allow move if have also root effect
  2965.          {
  2966.              if(target->getVictim() && target->isAlive())
  2967.                  target->SetTargetGuid(target->getVictim()->GetObjectGuid());
  2968. @@ -4071,11 +4074,13 @@ void Aura::HandleAuraModRoot(bool apply, bool Real)
  2969.  
  2970.          if(target->GetTypeId() == TYPEID_PLAYER)
  2971.          {
  2972. -            WorldPacket data(SMSG_FORCE_MOVE_ROOT, 10);
  2973. -            data << target->GetPackGUID();
  2974. -            data << (uint32)2;
  2975. -            target->SendMessageToSet(&data, true);
  2976. -
  2977. +            if(!target->hasUnitState(UNIT_STAT_ON_VEHICLE))
  2978. +            {
  2979. +                WorldPacket data(SMSG_FORCE_MOVE_ROOT, 10);
  2980. +                data << target->GetPackGUID();
  2981. +                data << (uint32)2;
  2982. +                target->SendMessageToSet(&data,true);
  2983. +            }
  2984.              //Clear unit movement flags
  2985.              ((Player*)target)->m_movementInfo.SetMovementFlags(MOVEFLAG_NONE);
  2986.          }
  2987. @@ -4113,7 +4118,7 @@ void Aura::HandleAuraModRoot(bool apply, bool Real)
  2988.  
  2989.          target->clearUnitState(UNIT_STAT_ROOT);
  2990.  
  2991. -        if(!target->hasUnitState(UNIT_STAT_STUNNED))      // prevent allow move if have also stun effect
  2992. +        if(!target->hasUnitState(UNIT_STAT_STUNNED | UNIT_STAT_ON_VEHICLE))      // prevent allow move if have also stun effect
  2993.          {
  2994.              if(target->getVictim() && target->isAlive())
  2995.                  target->SetTargetGuid(target->getVictim()->GetObjectGuid());
  2996. @@ -7556,41 +7561,6 @@ void Aura::HandleArenaPreparation(bool apply, bool Real)
  2997.          GetTarget()->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PREPARATION);
  2998.  }
  2999.  
  3000. -/**
  3001. - * Such auras are applied from a caster(=player) to a vehicle.
  3002. - * This has been verified using spell #49256
  3003. - */
  3004. -void Aura::HandleAuraControlVehicle(bool apply, bool Real)
  3005. -{
  3006. -    if(!Real)
  3007. -        return;
  3008. -
  3009. -    Unit* target = GetTarget();
  3010. -    if (target->GetTypeId() != TYPEID_UNIT || !((Creature*)target)->IsVehicle())
  3011. -        return;
  3012. -    Vehicle* vehicle = (Vehicle*)target;
  3013. -
  3014. -    Unit *player = GetCaster();
  3015. -    if(!player || player->GetTypeId() != TYPEID_PLAYER)
  3016. -        return;
  3017. -
  3018. -    if (apply)
  3019. -    {
  3020. -        if(Pet *pet = player->GetPet())
  3021. -            pet->Remove(PET_SAVE_AS_CURRENT);
  3022. -        ((Player*)player)->EnterVehicle(vehicle);
  3023. -    }
  3024. -    else
  3025. -    {
  3026. -        SpellEntry const *spell = GetSpellProto();
  3027. -
  3028. -        // some SPELL_AURA_CONTROL_VEHICLE auras have a dummy effect on the player - remove them
  3029. -        player->RemoveAurasDueToSpell(spell->Id);
  3030. -
  3031. -        ((Player*)player)->ExitVehicle(vehicle);
  3032. -    }
  3033. -}
  3034. -
  3035.  void Aura::HandleAuraOpenStable(bool apply, bool Real)
  3036.  {
  3037.      if(!Real || GetTarget()->GetTypeId() != TYPEID_PLAYER || !GetTarget()->IsInWorld())
  3038. @@ -7779,6 +7749,48 @@ bool Aura::IsLastAuraOnHolder()
  3039.              return false;
  3040.      return true;
  3041.  }
  3042. +/**
  3043. + * Such auras are applied from a caster(=player) to a vehicle.
  3044. + * This has been verified using spell #49256
  3045. + */
  3046. +void Aura::HandleAuraControlVehicle(bool apply, bool Real)
  3047. +{
  3048. +     if(!Real)
  3049. +         return;
  3050. +
  3051. +    Unit* target = GetTarget();
  3052. +    Unit* caster = GetCaster();
  3053. +    if (target->GetTypeId() != TYPEID_UNIT || !((Creature*)target)->IsVehicle())
  3054. +        return;
  3055. +    Vehicle* vehicle = (Vehicle*)target;
  3056. +
  3057. +    if(!caster || !vehicle)
  3058. +        return;
  3059. +
  3060. +    // this can happen due to wrong caster/target spell handling
  3061. +    // note : SPELL_AURA_CONTROL_VEHICLE can have EffectImplicitTargetA
  3062. +    // TARGET_SCRIPT, TARGET_DUELVSPLAYER.. etc
  3063. +    if(caster->GetGUID() == vehicle->GetGUID())
  3064. +        return;
  3065. +
  3066. +    if (apply)
  3067. +    {
  3068. +        if(caster->GetTypeId() == TYPEID_PLAYER)
  3069. +        {
  3070. +            WorldPacket data(SMSG_ON_CANCEL_EXPECTED_RIDE_VEHICLE_AURA, 0);
  3071. +            ((Player*)caster)->GetSession()->SendPacket(&data);
  3072. +        }
  3073. +        // if we leave and enter again, this will refresh
  3074. +        int32 duration = GetSpellMaxDuration(GetSpellProto());
  3075. +        if(duration > 0)
  3076. +            vehicle->SetSpawnDuration(duration);
  3077. +    }
  3078. +    else
  3079. +    {
  3080. +        // some SPELL_AURA_CONTROL_VEHICLE auras have a dummy effect on the player - remove them
  3081. +        caster->RemoveAurasDueToSpell(GetId());
  3082. +    }
  3083. +}
  3084.  
  3085.  SpellAuraHolder::SpellAuraHolder(SpellEntry const* spellproto, Unit *target, WorldObject *caster, Item *castItem) :
  3086.  m_target(target), m_caster_guid(0), m_castItemGuid(castItem?castItem->GetGUID():0),
  3087. @@ -7794,7 +7806,7 @@ m_permanent(false), m_isRemovedOnShapeLost(true), m_deleted(false), m_in_use(0)
  3088.      else
  3089.      {
  3090.          // remove this assert when not unit casters will be supported
  3091. -        MANGOS_ASSERT(caster->GetObjectGuid().IsUnit())
  3092. +        MANGOS_ASSERT(caster->GetObjectGuid().IsUnit() || caster->GetObjectGuid().IsVehicle())
  3093.          m_caster_guid = caster->GetGUID();
  3094.      }
  3095.  
  3096. diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp
  3097. index 9190bd3..a6d2d8b 100644
  3098. --- a/src/game/SpellEffects.cpp
  3099. +++ b/src/game/SpellEffects.cpp
  3100. @@ -57,6 +57,7 @@
  3101.  #include "GridNotifiers.h"
  3102.  #include "GridNotifiersImpl.h"
  3103.  #include "CellImpl.h"
  3104. +#include "Vehicle.h"
  3105.  
  3106.  pEffect SpellEffects[TOTAL_SPELL_EFFECTS]=
  3107.  {
  3108. @@ -147,9 +148,9 @@ pEffect SpellEffects[TOTAL_SPELL_EFFECTS]=
  3109.      &Spell::EffectStuck,                                    // 84 SPELL_EFFECT_STUCK
  3110.      &Spell::EffectSummonPlayer,                             // 85 SPELL_EFFECT_SUMMON_PLAYER
  3111.      &Spell::EffectActivateObject,                           // 86 SPELL_EFFECT_ACTIVATE_OBJECT
  3112. -    &Spell::EffectNULL,                                     // 87 SPELL_EFFECT_WMO_DAMAGE (57 spells in 3.3.2)
  3113. -    &Spell::EffectNULL,                                     // 88 SPELL_EFFECT_WMO_REPAIR (2 spells in 3.3.2)
  3114. -    &Spell::EffectNULL,                                     // 89 SPELL_EFFECT_WMO_CHANGE (7 spells in 3.3.2)
  3115. +    &Spell::EffectDamageBuilding,                           // 87 SPELL_EFFECT_WMO_DAMAGE
  3116. +    &Spell::EffectUnused,                                   // 88 SPELL_EFFECT_WMO_REPAIR
  3117. +    &Spell::EffectUnused,                                   // 89 SPELL_EFFECT_WMO_CHANGE
  3118.      &Spell::EffectKillCreditPersonal,                       // 90 SPELL_EFFECT_KILL_CREDIT              Kill credit but only for single person
  3119.      &Spell::EffectUnused,                                   // 91 SPELL_EFFECT_THREAT_ALL               one spell: zzOLDBrainwash
  3120.      &Spell::EffectEnchantHeldItem,                          // 92 SPELL_EFFECT_ENCHANT_HELD_ITEM
  3121. @@ -4080,7 +4081,7 @@ void Spell::EffectSummonType(SpellEffectIndex eff_idx)
  3122.                  case SUMMON_PROP_TYPE_SIEGE_VEH:
  3123.                  case SUMMON_PROP_TYPE_DRAKE_VEH:
  3124.                      // TODO
  3125. -                    // EffectSummonVehicle(i);
  3126. +                    EffectSummonVehicle(eff_idx);
  3127.                      break;
  3128.                  default:
  3129.                      sLog.outError("EffectSummonType: Unhandled summon type %u", summon_prop->Type);
  3130. @@ -4109,7 +4110,7 @@ void Spell::EffectSummonType(SpellEffectIndex eff_idx)
  3131.          case SUMMON_PROP_GROUP_VEHICLE:
  3132.          {
  3133.              // TODO
  3134. -            // EffectSummonVehicle(i);
  3135. +            EffectSummonVehicle(eff_idx);
  3136.              break;
  3137.          }
  3138.          default:
  3139. @@ -6795,13 +6796,15 @@ void Spell::EffectAddComboPoints(SpellEffectIndex /*eff_idx*/)
  3140.      if(!unitTarget)
  3141.          return;
  3142.  
  3143. -    if(m_caster->GetTypeId() != TYPEID_PLAYER)
  3144. -        return;
  3145. -
  3146.      if(damage <= 0)
  3147.          return;
  3148.  
  3149. -    ((Player*)m_caster)->AddComboPoints(unitTarget, damage);
  3150. +    if(m_caster->GetTypeId() != TYPEID_PLAYER)
  3151. +    {
  3152. +        if(((Creature*)m_caster)->IsVehicle())
  3153. +            ((Player*)m_caster->GetCharmer())->AddComboPoints(unitTarget, damage);
  3154. +    }else
  3155. +        ((Player*)m_caster)->AddComboPoints(unitTarget, damage);
  3156.  }
  3157.  
  3158.  void Spell::EffectDuel(SpellEffectIndex eff_idx)
  3159. @@ -8069,6 +8072,54 @@ void Spell::EffectRenamePet(SpellEffectIndex /*eff_idx*/)
  3160.      unitTarget->RemoveByteFlag(UNIT_FIELD_BYTES_2, 2, UNIT_CAN_BE_RENAMED);
  3161.  }
  3162.  
  3163. +void Spell::EffectSummonVehicle(SpellEffectIndex eff_idx)
  3164. +{
  3165. +    uint32 creature_entry = m_spellInfo->EffectMiscValue[eff_idx];
  3166. +    if(!creature_entry)
  3167. +        return;
  3168. +
  3169. +    float px, py, pz;
  3170. +    // If dest location if present
  3171. +    if (m_targets.m_targetMask & TARGET_FLAG_DEST_LOCATION)
  3172. +    {
  3173. +        // Summon unit in dest location
  3174. +        px = m_targets.m_destX;
  3175. +        py = m_targets.m_destY;
  3176. +        pz = m_targets.m_destZ;
  3177. +    }
  3178. +    // Summon if dest location not present near caster
  3179. +    else
  3180. +        m_caster->GetClosePoint(px, py, pz, 1.0f);
  3181. +
  3182. +    Vehicle *v = m_caster->SummonVehicle(creature_entry, px, py, pz, m_caster->GetOrientation());
  3183. +    if(!v)
  3184. +        return;
  3185. +
  3186. +    v->SetUInt32Value(UNIT_CREATED_BY_SPELL, m_spellInfo->Id);
  3187. +    v->SetCreatorGuid(m_caster->GetGUID());
  3188. +
  3189. +    if(damage)
  3190. +    {
  3191. +        m_caster->CastSpell(v, damage, true);
  3192. +        m_caster->EnterVehicle(v, 0);
  3193. +    }
  3194. +    int32 duration = GetSpellMaxDuration(m_spellInfo);
  3195. +    if(duration > 0)
  3196. +        v->SetSpawnDuration(duration);
  3197. +}
  3198. +
  3199. +void Spell::EffectDamageBuilding(SpellEffectIndex eff_idx)
  3200. +{
  3201. +    if(!gameObjTarget)
  3202. +        return;
  3203. +
  3204. +    if(gameObjTarget->GetGoType() != GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING)
  3205. +        return;
  3206. +
  3207. +    // NOTE : this can be increased by scaling stat system in vehicles
  3208. +    gameObjTarget->DealSiegeDamage(damage);
  3209. +}
  3210. +
  3211.  void Spell::EffectPlayMusic(SpellEffectIndex eff_idx)
  3212.  {
  3213.      if(!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER)
  3214. diff --git a/src/game/SpellHandler.cpp b/src/game/SpellHandler.cpp
  3215. index 9fb3f32..93cc0f6 100644
  3216. --- a/src/game/SpellHandler.cpp
  3217. +++ b/src/game/SpellHandler.cpp
  3218. @@ -27,6 +27,7 @@
  3219.  #include "Spell.h"
  3220.  #include "ScriptCalls.h"
  3221.  #include "Totem.h"
  3222. +#include "Vehicle.h"
  3223.  #include "SpellAuras.h"
  3224.  
  3225.  void WorldSession::HandleUseItemOpcode(WorldPacket& recvPacket)
  3226. @@ -335,6 +336,11 @@ void WorldSession::HandleCastSpellOpcode(WorldPacket& recvPacket)
  3227.      DEBUG_LOG("WORLD: got cast spell packet, spellId - %u, cast_count: %u, unk_flags %u, data length = %i",
  3228.          spellId, cast_count, unk_flags, (uint32)recvPacket.size());
  3229.  
  3230. +    // vehicle spells are handled by CMSG_PET_CAST_SPELL,
  3231. +    // but player is still able to cast own spells
  3232. +    if(!_player->GetCharmGuid().IsEmpty() && _player->GetCharmGuid() == _player->GetVehicleGUID())
  3233. +        mover = _player;
  3234. +
  3235.      SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellId );
  3236.  
  3237.      if(!spellInfo)
  3238. @@ -501,7 +507,7 @@ void WorldSession::HandlePetCancelAuraOpcode( WorldPacket& recvPacket)
  3239.          return;
  3240.      }
  3241.  
  3242. -    Creature* pet = GetPlayer()->GetMap()->GetAnyTypeCreature(guid);
  3243. +    Creature* pet=ObjectAccessor::GetAnyTypeCreature(*_player,guid);
  3244.  
  3245.      if (!pet)
  3246.      {
  3247. @@ -586,22 +592,68 @@ void WorldSession::HandleSpellClick( WorldPacket & recv_data )
  3248.      ObjectGuid guid;
  3249.      recv_data >> guid;
  3250.  
  3251. -    if (_player->isInCombat())                              // client prevent click and set different icon at combat state
  3252. +    Creature *unit = ObjectAccessor::GetAnyTypeCreature(*_player, guid);
  3253. +
  3254. +    if(!_player->IsWithinDistInMap(unit, 10))
  3255.          return;
  3256.  
  3257. -    Creature *unit = _player->GetMap()->GetAnyTypeCreature(guid);
  3258. -    if (!unit || unit->isInCombat())                        // client prevent click and set different icon at combat state
  3259. +    // cheater?
  3260. +    if(!unit->HasFlag(UNIT_NPC_FLAGS,UNIT_NPC_FLAG_SPELLCLICK))
  3261.          return;
  3262.  
  3263. -    SpellClickInfoMapBounds clickPair = sObjectMgr.GetSpellClickInfoMapBounds(unit->GetEntry());
  3264. -    for(SpellClickInfoMap::const_iterator itr = clickPair.first; itr != clickPair.second; ++itr)
  3265. +    uint32 vehicleId = 0;
  3266. +    CreatureDataAddon const *cainfo = unit->GetCreatureAddon();
  3267. +    if(cainfo)
  3268. +        vehicleId = cainfo->vehicle_id;
  3269. +
  3270. +    // handled other (hacky) way to avoid overwriting auras
  3271. +    if(vehicleId || unit->IsVehicle())
  3272.      {
  3273. -        if (itr->second.IsFitToRequirements(_player))
  3274. +        if(!unit->isAlive())
  3275. +            return;
  3276. +
  3277. +        if(_player->GetVehicle())
  3278. +            return;
  3279. +
  3280. +        if(_player->GetVehicleGUID())
  3281. +            return;
  3282. +
  3283. +        // create vehicle if no one present and kill the original creature to avoid double, triple etc spawns
  3284. +        if(!unit->IsVehicle())
  3285.          {
  3286. -            Unit *caster = (itr->second.castFlags & 0x1) ? (Unit*)_player : (Unit*)unit;
  3287. -            Unit *target = (itr->second.castFlags & 0x2) ? (Unit*)_player : (Unit*)unit;
  3288. +            Vehicle *v = _player->SummonVehicle(unit->GetEntry(), unit->GetPositionX(), unit->GetPositionY(), unit->GetPositionZ(), unit->GetOrientation(), vehicleId);
  3289. +            if(!v)
  3290. +                return;
  3291.  
  3292. -            caster->CastSpell(target, itr->second.spellId, true);
  3293. +            if(v->GetVehicleFlags() & VF_DESPAWN_NPC)
  3294. +            {
  3295. +                v->SetSpawnDuration(unit->GetRespawnDelay()*IN_MILLISECONDS);
  3296. +                unit->SetDeathState(JUST_DIED);
  3297. +                unit->RemoveCorpse();
  3298. +                unit->SetHealth(0);
  3299. +            }
  3300. +            unit = v;
  3301. +        }
  3302. +
  3303. +        if(((Vehicle*)unit)->GetVehicleData())
  3304. +            if(uint32 r_aura = ((Vehicle*)unit)->GetVehicleData()->req_aura)
  3305. +                if(!_player->HasAura(r_aura))
  3306. +                    return;
  3307. +
  3308. +        _player->EnterVehicle((Vehicle*)unit, 0);
  3309. +    }
  3310. +    else
  3311. +    {
  3312. +        SpellClickInfoMapBounds clickPair = sObjectMgr.GetSpellClickInfoMapBounds(unit->GetEntry());
  3313. +        for(SpellClickInfoMap::const_iterator itr = clickPair.first; itr != clickPair.second; ++itr)
  3314. +        {
  3315. +            if (itr->second.IsFitToRequirements(_player))
  3316. +            {
  3317. +                Unit *caster = (itr->second.castFlags & 0x1) ? (Unit*)_player : (Unit*)unit;
  3318. +                Unit *target = (itr->second.castFlags & 0x2) ? (Unit*)_player : (Unit*)unit;
  3319. +
  3320. +                caster->CastSpell(target, itr->second.spellId, true);
  3321. +            }
  3322.          }
  3323.      }
  3324.  }
  3325. diff --git a/src/game/Traveller.h b/src/game/Traveller.h
  3326. index 9f8c44d..eb308c3 100644
  3327. --- a/src/game/Traveller.h
  3328. +++ b/src/game/Traveller.h
  3329. @@ -84,7 +84,7 @@ inline float Traveller<Creature>::Speed()
  3330.  template<>
  3331.  inline void Traveller<Creature>::Relocation(float x, float y, float z, float orientation)
  3332.  {
  3333. -    i_traveller.GetMap()->CreatureRelocation(&i_traveller, x, y, z, orientation);
  3334. +    i_traveller.SetPosition(x, y, z, orientation);
  3335.  }
  3336.  
  3337.  template<>
  3338. diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp
  3339. index b89042e..e01e62b 100644
  3340. --- a/src/game/Unit.cpp
  3341. +++ b/src/game/Unit.cpp
  3342. @@ -46,6 +46,7 @@
  3343.  #include "CellImpl.h"
  3344.  #include "Path.h"
  3345.  #include "Traveller.h"
  3346. +#include "Vehicle.h"
  3347.  #include "VMapFactory.h"
  3348.  #include "MovementGenerator.h"
  3349.  
  3350. @@ -267,6 +268,12 @@ Unit::Unit()
  3351.      // remove aurastates allowing special moves
  3352.      for(int i=0; i < MAX_REACTIVE; ++i)
  3353.          m_reactiveTimer[i] = 0;
  3354. +
  3355. +    m_auraUpdateMask = 0;
  3356. +
  3357. +    m_vehicleGUID = 0;
  3358. +    m_vehicle = NULL;
  3359. +    m_vehicleKit = NULL;
  3360.  }
  3361.  
  3362.  Unit::~Unit()
  3363. @@ -281,6 +288,9 @@ Unit::~Unit()
  3364.          }
  3365.      }
  3366.  
  3367. +    if(m_vehicleKit)
  3368. +        delete m_vehicleKit;
  3369. +
  3370.      if (m_charmInfo)
  3371.          delete m_charmInfo;
  3372.  
  3373. @@ -432,6 +442,65 @@ void Unit::SendMonsterMoveWithSpeed(float x, float y, float z, uint32 transitTim
  3374.      SendMonsterMove(x, y, z, SPLINETYPE_NORMAL, flags, transitTime, player);
  3375.  }
  3376.  
  3377. +void Unit::SendMonsterMoveTransport(Unit *vehicle)
  3378. +{
  3379. +    WorldPacket data(SMSG_MONSTER_MOVE_TRANSPORT, 8+8+1+1+4*3+4+1+4+4+4+4+4*3);
  3380. +    data << GetPackGUID();
  3381. +    data << vehicle->GetPackGUID();
  3382. +    data << uint8(m_movementInfo.GetTransportSeat());
  3383. +    data << uint8(0);                                       // new in 3.1
  3384. +    data << float(vehicle->GetPositionX());
  3385. +    data << float(vehicle->GetPositionY());
  3386. +    data << float(vehicle->GetPositionZ());
  3387. +    data << uint32(getMSTime());
  3388. +
  3389. +    data << uint8(4);                                       // unknown
  3390. +    data << float(0);                                       // facing angle
  3391. +
  3392. +    data << uint32(/*SPLINEFLAG_UNKNOWN5*/0);
  3393. +
  3394. +    data << uint32(0);                                      // Time in between points
  3395. +    data << uint32(1);                                      // 1 single waypoint
  3396. +
  3397. +    data << float(m_movementInfo.GetTransportPos()->x);
  3398. +    data << float(m_movementInfo.GetTransportPos()->y);
  3399. +    data << float(m_movementInfo.GetTransportPos()->z);
  3400. +
  3401. +    SendMessageToSet(&data, true);
  3402. +}
  3403. +
  3404. +bool Unit::SetPosition(float x, float y, float z, float orientation, bool teleport)
  3405. +{
  3406. +    // prevent crash when a bad coord is sent by the client
  3407. +    if (!MaNGOS::IsValidMapCoord(x, y, z, orientation))
  3408. +    {
  3409. +        DEBUG_LOG("Unit::SetPosition(%f, %f, %f, %f, %d) .. bad coordinates for unit %d!", x, y, z, orientation, teleport, GetGUIDLow());
  3410. +        return false;
  3411. +    }
  3412. +
  3413. +    bool turn = GetOrientation() != orientation;
  3414. +    bool relocate = (teleport || GetPositionX() != x || GetPositionY() != y || GetPositionZ() != z);
  3415. +
  3416. +    if (turn)
  3417. +        RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_TURNING);
  3418. +
  3419. +    if (relocate)
  3420. +    {
  3421. +        RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_MOVE);
  3422. +        if (GetTypeId() == TYPEID_PLAYER)
  3423. +            GetMap()->PlayerRelocation((Player*)this, x, y, z, orientation);
  3424. +        else
  3425. +            GetMap()->CreatureRelocation((Creature*)this, x, y, z, orientation);
  3426. +    }
  3427. +    else if (turn)
  3428. +        SetOrientation(orientation);
  3429. +
  3430. +    if ((relocate || turn) && GetVehicleKit())
  3431. +        GetVehicleKit()->RelocatePassengers(x, y, z, orientation);
  3432. +
  3433. +    return relocate || turn;
  3434. +}
  3435. +
  3436.  void Unit::SendHeartBeat(bool toSelf)
  3437.  {
  3438.      WorldPacket data(MSG_MOVE_HEARTBEAT, 64);
  3439. @@ -5240,15 +5309,10 @@ void Unit::setPowerType(Powers new_powertype)
  3440.          if(((Player*)this)->GetGroup())
  3441.              ((Player*)this)->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_POWER_TYPE);
  3442.      }
  3443. -    else if(((Creature*)this)->IsPet())
  3444. +    else if(Unit* owner = GetCharmerOrOwner())
  3445.      {
  3446. -        Pet *pet = ((Pet*)this);
  3447. -        if(pet->isControlled())
  3448. -        {
  3449. -            Unit *owner = GetOwner();
  3450. -            if(owner && (owner->GetTypeId() == TYPEID_PLAYER) && ((Player*)owner)->GetGroup())
  3451. -                ((Player*)owner)->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_PET_POWER_TYPE);
  3452. -        }
  3453. +        if((owner->GetTypeId() == TYPEID_PLAYER) && ((Player*)owner)->GetGroup())
  3454. +            ((Player*)owner)->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_PET_POWER_TYPE);
  3455.      }
  3456.  
  3457.      switch(new_powertype)
  3458. @@ -5405,6 +5469,38 @@ bool Unit::IsHostileTo(Unit const* unit) const
  3459.      return tester_faction->IsHostileTo(*target_faction);
  3460.  }
  3461.  
  3462. +bool Unit::IsInPartyWith(Unit const *unit) const
  3463. +{
  3464. +    if(this == unit)
  3465. +      return true;
  3466. +
  3467. +   const Unit *u1 = GetCharmerOrOwnerOrSelf();
  3468. +    const Unit *u2 = unit->GetCharmerOrOwnerOrSelf();
  3469. +    if(u1 == u2)
  3470. +        return true;
  3471. +
  3472. +    if(u1->GetTypeId() == TYPEID_PLAYER && u2->GetTypeId() == TYPEID_PLAYER)
  3473. +        return ((Player*)u1)->IsInSameGroupWith((Player*)u2);
  3474. +    else
  3475. +       return false;
  3476. +}
  3477. +
  3478. +bool Unit::IsInRaidWith(Unit const *unit) const
  3479. +{
  3480. +    if(this == unit)
  3481. +        return true;
  3482. +
  3483. +    const Unit *u1 = GetCharmerOrOwnerOrSelf();
  3484. +    const Unit *u2 = unit->GetCharmerOrOwnerOrSelf();
  3485. +    if(u1 == u2)
  3486. +        return true;
  3487. +
  3488. +    if(u1->GetTypeId() == TYPEID_PLAYER && u2->GetTypeId() == TYPEID_PLAYER)
  3489. +        return ((Player*)u1)->IsInSameRaidWith((Player*)u2);
  3490. +    else
  3491. +        return false;
  3492. +}
  3493. +
  3494.  bool Unit::IsFriendlyTo(Unit const* unit) const
  3495.  {
  3496.      // always friendly to self
  3497. @@ -5556,6 +5652,14 @@ bool Unit::Attack(Unit *victim, bool meleeAttack)
  3498.      if(GetTypeId()==TYPEID_PLAYER && IsMounted())
  3499.          return false;
  3500.  
  3501. +    // player (also npc?) cannot attack on vehicle
  3502. +    if(GetTypeId()==TYPEID_PLAYER && GetVehicleGUID())
  3503. +        return false;
  3504. +
  3505. +    // player (also npc?) cannot attack on vehicle
  3506. +    if(GetTypeId()==TYPEID_UNIT && ((Creature*)this)->IsVehicle() && !GetCharmerGuid().IsEmpty())
  3507. +        return false;
  3508. +
  3509.      // nobody can attack GM in GM-mode
  3510.      if(victim->GetTypeId()==TYPEID_PLAYER)
  3511.      {
  3512. @@ -7506,7 +7610,7 @@ float Unit::GetPPMProcChance(uint32 WeaponSpeed, float PPM) const
  3513.      return WeaponSpeed * PPM / 600.0f;                      // result is chance in percents (probability = Speed_in_sec * (PPM / 60))
  3514.  }
  3515.  
  3516. -void Unit::Mount(uint32 mount, uint32 spellId)
  3517. +void Unit::Mount(uint32 mount, uint32 spellId, uint32 vehicleEntry)
  3518.  {
  3519.      if (!mount)
  3520.          return;
  3521. @@ -7541,6 +7645,18 @@ void Unit::Mount(uint32 mount, uint32 spellId)
  3522.              }
  3523.          }
  3524.      }
  3525. +
  3526. +    if (vehicleEntry)
  3527. +    {
  3528. +        if (CreateVehicleKit(vehicleEntry))
  3529. +        {
  3530. +            GetVehicleKit()->Reset();
  3531. +            WorldPacket data(SMSG_PLAYER_VEHICLE_DATA, 8+4);
  3532. +            data << GetPackGUID();
  3533. +            data << uint32(vehicleEntry);
  3534. +            SendMessageToSet(&data, true);
  3535. +        }
  3536. +    }
  3537.  }
  3538.  
  3539.  void Unit::Unmount()
  3540. @@ -7563,6 +7679,17 @@ void Unit::Unmount()
  3541.          else
  3542.              ((Player*)this)->ResummonPetTemporaryUnSummonedIfAny();
  3543.      }
  3544. +
  3545. +    if (GetTypeId() == TYPEID_PLAYER && GetVehicleKit())
  3546. +    {
  3547. +        // Send other players that we are no longer a vehicle
  3548. +        WorldPacket data(SMSG_PLAYER_VEHICLE_DATA, 8+4);
  3549. +        data << GetPackGUID();
  3550. +        data << uint32(0);
  3551. +        ((Player*)this)->SendMessageToSet(&data, true);
  3552. +
  3553. +        RemoveVehicleKit();
  3554. +    }
  3555.  }
  3556.  
  3557.  void Unit::SetInCombatWith(Unit* enemy)
  3558. @@ -8151,6 +8278,11 @@ void Unit::UpdateSpeed(UnitMoveType mtype, bool forced, float ratio)
  3559.      }
  3560.  
  3561.      float bonus = non_stack_bonus > stack_bonus ? non_stack_bonus : stack_bonus;
  3562. +
  3563. +    //apply creature's base speed
  3564. +    if(GetTypeId() == TYPEID_UNIT)
  3565. +        bonus *= ((Creature*)this)->GetBaseSpeed();
  3566. +
  3567.      // now we ready for speed calculation
  3568.      float speed  = main_speed_mod ? bonus*(100.0f + main_speed_mod)/100.0f : bonus;
  3569.  
  3570. @@ -8343,10 +8475,13 @@ void Unit::SetDeathState(DeathState s)
  3571.  
  3572.          if(IsNonMeleeSpellCasted(false))
  3573.              InterruptNonMeleeSpells(false);
  3574. +
  3575. +        ExitVehicle();
  3576.      }
  3577.  
  3578.      if (s == JUST_DIED)
  3579.      {
  3580. +        ExitVehicle();
  3581.          RemoveAllAurasOnDeath();
  3582.          RemoveGuardians();
  3583.          UnsummonAllTotems();
  3584. @@ -8371,6 +8506,9 @@ void Unit::SetDeathState(DeathState s)
  3585.          // remove aurastates allowing special moves
  3586.          ClearAllReactives();
  3587.          ClearDiminishings();
  3588. +
  3589. +        if (GetVehicleKit())
  3590. +            GetVehicleKit()->RemoveAllPassengers();
  3591.      }
  3592.      else if(s == JUST_ALIVED)
  3593.      {
  3594. @@ -8593,7 +8731,8 @@ bool Unit::SelectHostileTarget()
  3595.      }
  3596.  
  3597.      // enter in evade mode in other case
  3598. -    ((Creature*)this)->AI()->EnterEvadeMode();
  3599. +    if(!((Creature*)this)->IsVehicle())
  3600. +        ((Creature*)this)->AI()->EnterEvadeMode();
  3601.  
  3602.      if (InstanceData* mapInstance = GetInstanceData())
  3603.          mapInstance->OnCreatureEvade((Creature*)this);
  3604. @@ -8607,7 +8746,14 @@ bool Unit::SelectHostileTarget()
  3605.  
  3606.  int32 Unit::CalculateSpellDamage(Unit const* target, SpellEntry const* spellProto, SpellEffectIndex effect_index, int32 const* effBasePoints)
  3607.  {
  3608. -    Player* unitPlayer = (GetTypeId() == TYPEID_PLAYER) ? (Player*)this : NULL;
  3609. +    Player* unitPlayer;
  3610. +
  3611. +    if(GetTypeId() == TYPEID_PLAYER)
  3612. +        unitPlayer = (Player*)this;
  3613. +    else if(((Creature*)this)->IsVehicle())
  3614. +        unitPlayer = (Player*)GetCharmer();
  3615. +    else
  3616. +        unitPlayer = NULL;
  3617.  
  3618.      uint8 comboPoints = unitPlayer ? unitPlayer->GetComboPoints() : 0;
  3619.  
  3620. @@ -8672,7 +8818,14 @@ int32 Unit::CalculateSpellDamage(Unit const* target, SpellEntry const* spellProt
  3621.  
  3622.  int32 Unit::CalculateSpellDuration(SpellEntry const* spellProto, SpellEffectIndex effect_index, Unit const* target)
  3623.  {
  3624. -    Player* unitPlayer = (GetTypeId() == TYPEID_PLAYER) ? (Player*)this : NULL;
  3625. +    Player* unitPlayer;
  3626. +
  3627. +    if(GetTypeId() == TYPEID_PLAYER)
  3628. +        unitPlayer = (Player*)this;
  3629. +    else if(((Creature*)this)->IsVehicle())
  3630. +        unitPlayer = (Player*)GetCharmer();
  3631. +    else
  3632. +        unitPlayer = NULL;
  3633.  
  3634.      uint8 comboPoints = unitPlayer ? unitPlayer->GetComboPoints() : 0;
  3635.  
  3636. @@ -9077,15 +9230,10 @@ void Unit::SetHealth(uint32 val)
  3637.          if(((Player*)this)->GetGroup())
  3638.              ((Player*)this)->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_CUR_HP);
  3639.      }
  3640. -    else if(((Creature*)this)->IsPet())
  3641. +    else if(Unit* owner = GetCharmerOrOwner())
  3642.      {
  3643. -        Pet *pet = ((Pet*)this);
  3644. -        if(pet->isControlled())
  3645. -        {
  3646. -            Unit *owner = GetOwner();
  3647. -            if(owner && (owner->GetTypeId() == TYPEID_PLAYER) && ((Player*)owner)->GetGroup())
  3648. -                ((Player*)owner)->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_PET_CUR_HP);
  3649. -        }
  3650. +        if((owner->GetTypeId() == TYPEID_PLAYER) && ((Player*)owner)->GetGroup())
  3651. +            ((Player*)owner)->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_PET_CUR_HP);
  3652.      }
  3653.  }
  3654.  
  3655. @@ -9100,15 +9248,10 @@ void Unit::SetMaxHealth(uint32 val)
  3656.          if(((Player*)this)->GetGroup())
  3657.              ((Player*)this)->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_MAX_HP);
  3658.      }
  3659. -    else if(((Creature*)this)->IsPet())
  3660. +    else if(Unit* owner = GetCharmerOrOwner())
  3661.      {
  3662. -        Pet *pet = ((Pet*)this);
  3663. -        if(pet->isControlled())
  3664. -        {
  3665. -            Unit *owner = GetOwner();
  3666. -            if(owner && (owner->GetTypeId() == TYPEID_PLAYER) && ((Player*)owner)->GetGroup())
  3667. -                ((Player*)owner)->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_PET_MAX_HP);
  3668. -        }
  3669. +        if((owner->GetTypeId() == TYPEID_PLAYER) && ((Player*)owner)->GetGroup())
  3670. +            ((Player*)owner)->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_PET_MAX_HP);
  3671.      }
  3672.  
  3673.      if(val < health)
  3674. @@ -9144,20 +9287,19 @@ void Unit::SetPower(Powers power, uint32 val)
  3675.          if(((Player*)this)->GetGroup())
  3676.              ((Player*)this)->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_CUR_POWER);
  3677.      }
  3678. -    else if(((Creature*)this)->IsPet())
  3679. +    else if(Unit* owner = GetCharmerOrOwner())
  3680.      {
  3681. -        Pet *pet = ((Pet*)this);
  3682. -        if(pet->isControlled())
  3683. -        {
  3684. -            Unit *owner = GetOwner();
  3685. -            if(owner && (owner->GetTypeId() == TYPEID_PLAYER) && ((Player*)owner)->GetGroup())
  3686. -                ((Player*)owner)->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_PET_CUR_POWER);
  3687. -        }
  3688. +        if((owner->GetTypeId() == TYPEID_PLAYER) && ((Player*)owner)->GetGroup())
  3689. +            ((Player*)owner)->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_PET_CUR_POWER);
  3690.  
  3691. -        // Update the pet's character sheet with happiness damage bonus
  3692. -        if(pet->getPetType() == HUNTER_PET && power == POWER_HAPPINESS)
  3693. +        if(((Creature*)this)->IsPet())
  3694.          {
  3695. -            pet->UpdateDamagePhysical(BASE_ATTACK);
  3696. +            Pet *pet = ((Pet*)this);
  3697. +            // Update the pet's character sheet with happiness damage bonus
  3698. +            if(pet->getPetType() == HUNTER_PET && power == POWER_HAPPINESS)
  3699. +            {
  3700. +                pet->UpdateDamagePhysical(BASE_ATTACK);
  3701. +            }
  3702.          }
  3703.      }
  3704.  }
  3705. @@ -9173,15 +9315,10 @@ void Unit::SetMaxPower(Powers power, uint32 val)
  3706.          if(((Player*)this)->GetGroup())
  3707.              ((Player*)this)->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_MAX_POWER);
  3708.      }
  3709. -    else if(((Creature*)this)->IsPet())
  3710. +    else if(Unit* owner = GetCharmerOrOwner())
  3711.      {
  3712. -        Pet *pet = ((Pet*)this);
  3713. -        if(pet->isControlled())
  3714. -        {
  3715. -            Unit *owner = GetOwner();
  3716. -            if(owner && (owner->GetTypeId() == TYPEID_PLAYER) && ((Player*)owner)->GetGroup())
  3717. -                ((Player*)owner)->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_PET_MAX_POWER);
  3718. -        }
  3719. +        if((owner->GetTypeId() == TYPEID_PLAYER) && ((Player*)owner)->GetGroup())
  3720. +            ((Player*)owner)->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_PET_MAX_POWER);
  3721.      }
  3722.  
  3723.      if(val < cur_power)
  3724. @@ -9198,15 +9335,10 @@ void Unit::ApplyPowerMod(Powers power, uint32 val, bool apply)
  3725.          if(((Player*)this)->GetGroup())
  3726.              ((Player*)this)->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_CUR_POWER);
  3727.      }
  3728. -    else if(((Creature*)this)->IsPet())
  3729. +    else if(Unit* owner = GetCharmerOrOwner())
  3730.      {
  3731. -        Pet *pet = ((Pet*)this);
  3732. -        if(pet->isControlled())
  3733. -        {
  3734. -            Unit *owner = GetOwner();
  3735. -            if(owner && (owner->GetTypeId() == TYPEID_PLAYER) && ((Player*)owner)->GetGroup())
  3736. -                ((Player*)owner)->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_PET_CUR_POWER);
  3737. -        }
  3738. +        if((owner->GetTypeId() == TYPEID_PLAYER) && ((Player*)owner)->GetGroup())
  3739. +            ((Player*)owner)->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_PET_CUR_POWER);
  3740.      }
  3741.  }
  3742.  
  3743. @@ -9220,15 +9352,10 @@ void Unit::ApplyMaxPowerMod(Powers power, uint32 val, bool apply)
  3744.          if(((Player*)this)->GetGroup())
  3745.              ((Player*)this)->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_MAX_POWER);
  3746.      }
  3747. -    else if(((Creature*)this)->IsPet())
  3748. +    else if(Unit* owner = GetCharmerOrOwner())
  3749.      {
  3750. -        Pet *pet = ((Pet*)this);
  3751. -        if(pet->isControlled())
  3752. -        {
  3753. -            Unit *owner = GetOwner();
  3754. -            if(owner && (owner->GetTypeId() == TYPEID_PLAYER) && ((Player*)owner)->GetGroup())
  3755. -                ((Player*)owner)->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_PET_MAX_POWER);
  3756. -        }
  3757. +        if((owner->GetTypeId() == TYPEID_PLAYER) && ((Player*)owner)->GetGroup())
  3758. +            ((Player*)owner)->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_PET_MAX_POWER);
  3759.      }
  3760.  }
  3761.  
  3762. @@ -9274,6 +9401,7 @@ void Unit::RemoveFromWorld()
  3763.          RemoveGuardians();
  3764.          RemoveAllGameObjects();
  3765.          RemoveAllDynObjects();
  3766. +        ExitVehicle();
  3767.          CleanupDeletedAuras();
  3768.          GetViewPoint().Event_RemovedFromWorld();
  3769.      }
  3770. @@ -9283,6 +9411,7 @@ void Unit::RemoveFromWorld()
  3771.  
  3772.  void Unit::CleanupsBeforeDelete()
  3773.  {
  3774. +    ExitVehicle();                                          // make sure we always leave vehicle, otherwise it will crash
  3775.      if(m_uint32Values)                                      // only for fully created object
  3776.      {
  3777.          InterruptNonMeleeSpells(true);
  3778. @@ -9866,8 +9995,12 @@ void Unit::SetFeared(bool apply, uint64 const& casterGUID, uint32 spellID, uint3
  3779.          }
  3780.      }
  3781.  
  3782. -    if (GetTypeId() == TYPEID_PLAYER)
  3783. +    if (GetTypeId() == TYPEID_PLAYER && !GetVehicleGUID())
  3784.          ((Player*)this)->SetClientControl(this, !apply);
  3785. +
  3786. +    if (Unit* owner = GetCharmer())
  3787. +        if (owner->GetTypeId() == TYPEID_PLAYER)
  3788. +            ((Player*)owner)->SetClientControl(this, !apply);
  3789.  }
  3790.  
  3791.  void Unit::SetConfused(bool apply, uint64 const& casterGUID, uint32 spellID)
  3792. @@ -9896,8 +10029,12 @@ void Unit::SetConfused(bool apply, uint64 const& casterGUID, uint32 spellID)
  3793.          }
  3794.      }
  3795.  
  3796. -    if(GetTypeId() == TYPEID_PLAYER)
  3797. +    if(GetTypeId() == TYPEID_PLAYER && !GetVehicleGUID())
  3798.          ((Player*)this)->SetClientControl(this, !apply);
  3799. +
  3800. +    if (Unit* owner = GetCharmer())
  3801. +        if (owner->GetTypeId() == TYPEID_PLAYER)
  3802. +            ((Player*)owner)->SetClientControl(this, !apply);
  3803.  }
  3804.  
  3805.  void Unit::SetFeignDeath(bool apply, uint64 const& casterGUID, uint32 /*spellID*/)
  3806. @@ -10003,13 +10140,8 @@ void Unit::SetDisplayId(uint32 modelId)
  3807.  
  3808.      UpdateModelData();
  3809.  
  3810. -    if(GetTypeId() == TYPEID_UNIT && ((Creature*)this)->IsPet())
  3811. -    {
  3812. -        Pet *pet = ((Pet*)this);
  3813. -        if(!pet->isControlled())
  3814. -            return;
  3815. -        Unit *owner = GetOwner();
  3816. -        if(owner && (owner->GetTypeId() == TYPEID_PLAYER) && ((Player*)owner)->GetGroup())
  3817. +    if(Unit *owner = GetCharmerOrOwner())    {
  3818. +        if((owner->GetTypeId() == TYPEID_PLAYER) && ((Player*)owner)->GetGroup())
  3819.              ((Player*)owner)->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_PET_MODEL_ID);
  3820.      }
  3821.  }
  3822. @@ -10213,16 +10345,14 @@ void Unit::UpdateAuraForGroup(uint8 slot)
  3823.              player->SetAuraUpdateMask(slot);
  3824.          }
  3825.      }
  3826. -    else if(GetTypeId() == TYPEID_UNIT && ((Creature*)this)->IsPet())
  3827. +    else if(GetTypeId() == TYPEID_UNIT)
  3828.      {
  3829. -        Pet *pet = ((Pet*)this);
  3830. -        if(pet->isControlled())
  3831. +        if(Unit *owner = GetCharmerOrOwner())
  3832.          {
  3833. -            Unit *owner = GetOwner();
  3834. -            if(owner && (owner->GetTypeId() == TYPEID_PLAYER) && ((Player*)owner)->GetGroup())
  3835. +            if((owner->GetTypeId() == TYPEID_PLAYER) && ((Player*)owner)->GetGroup())
  3836.              {
  3837.                  ((Player*)owner)->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_PET_AURAS);
  3838. -                pet->SetAuraUpdateMask(slot);
  3839. +                SetAuraUpdateMask(slot);
  3840.              }
  3841.          }
  3842.      }
  3843. @@ -10393,13 +10523,14 @@ void Unit::NearTeleportTo( float x, float y, float z, float orientation, bool ca
  3844.          ((Player*)this)->TeleportTo(GetMapId(), x, y, z, orientation, TELE_TO_NOT_LEAVE_TRANSPORT | TELE_TO_NOT_LEAVE_COMBAT | TELE_TO_NOT_UNSUMMON_PET | (casting ? TELE_TO_SPELL : 0));
  3845.      else
  3846.      {
  3847. +        ExitVehicle();
  3848.          Creature* c = (Creature*)this;
  3849.          // Creature relocation acts like instant movement generator, so current generator expects interrupt/reset calls to react properly
  3850.          if (!c->GetMotionMaster()->empty())
  3851.              if (MovementGenerator *movgen = c->GetMotionMaster()->top())
  3852.                  movgen->Interrupt(*c);
  3853.  
  3854. -        GetMap()->CreatureRelocation((Creature*)this, x, y, z, orientation);
  3855. +        SetPosition(x, y, z, orientation, true);
  3856.  
  3857.          SendHeartBeat(false);
  3858.  
  3859. @@ -10463,6 +10594,26 @@ struct SetPvPHelper
  3860.      bool state;
  3861.  };
  3862.  
  3863. +void Unit::ChangeSeat(int8 seatId, bool next)
  3864. +{
  3865. +    Vehicle *m_vehicle = ObjectAccessor::GetVehicle(GetVehicleGUID());
  3866. +
  3867. +    if (!m_vehicle)
  3868. +        return;
  3869. +
  3870. +    if (seatId < 0)
  3871. +    {
  3872. +        seatId = m_vehicle->GetNextEmptySeatNum(m_movementInfo.GetTransportSeat(), next);
  3873. +        if (seatId < 0)
  3874. +            return;
  3875. +    }
  3876. +    else if (seatId == m_movementInfo.GetTransportSeat() || !m_vehicle->HasEmptySeat(seatId))
  3877. +        return;
  3878. +
  3879. +    m_vehicle->RemovePassenger(this);
  3880. +    EnterVehicle(m_vehicle, seatId);
  3881. +}
  3882. +
  3883.  void Unit::SetPvP( bool state )
  3884.  {
  3885.      if(state)
  3886. @@ -10664,6 +10815,197 @@ void Unit::CleanupDeletedAuras()
  3887.      m_deletedAuras.clear();
  3888.  }
  3889.  
  3890. +Unit* Unit::GetVehicleBase()
  3891. +{
  3892. +    return m_vehicle ? m_vehicle->GetBase() : NULL;
  3893. +}
  3894. +
  3895. +bool Unit::CreateVehicleKit(uint32 vehicleEntry)
  3896. +{
  3897. +    VehicleEntry const *vehInfo = sVehicleStore.LookupEntry(vehicleEntry);
  3898. +
  3899. +    if (!vehInfo)
  3900. +        return false;
  3901. +
  3902. +    m_vehicleKit = new VehicleKit(this, vehInfo);
  3903. +    m_updateFlag |= UPDATEFLAG_VEHICLE;
  3904. +    return true;
  3905. +}
  3906. +
  3907. +void Unit::RemoveVehicleKit()
  3908. +{
  3909. +    if (!m_vehicleKit)
  3910. +        return;
  3911. +
  3912. +    m_vehicleKit->RemoveAllPassengers();
  3913. +    delete m_vehicleKit;
  3914. +
  3915. +    m_vehicleKit = NULL;
  3916. +
  3917. +    m_updateFlag &= ~UPDATEFLAG_VEHICLE;
  3918. +    RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK);
  3919. +    RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_PLAYER_VEHICLE);
  3920. +}
  3921. +
  3922. +void Unit::EnterVehicle(VehicleKit *vehicle, int8 seatId)
  3923. +{
  3924. +    if(!isAlive() || GetVehicleKit() == vehicle)
  3925. +        return;
  3926. +
  3927. +    if (m_vehicle)
  3928. +    {
  3929. +        if (m_vehicle == vehicle)
  3930. +        {
  3931. +            if (seatId >= 0)
  3932. +                ChangeSeat(seatId);
  3933. +
  3934. +            return;
  3935. +        }
  3936. +        else
  3937. +            ExitVehicle();
  3938. +    }
  3939. +
  3940. +    InterruptNonMeleeSpells(false);
  3941. +    RemoveSpellsCausingAura(SPELL_AURA_MOUNTED);
  3942. +
  3943. +    if (!vehicle->AddPassenger(this, seatId))
  3944. +        return;
  3945. +
  3946. +    m_vehicle = vehicle;
  3947. +
  3948. +    if (Pet *pet = GetPet())
  3949. +        pet->Remove(PET_SAVE_AS_CURRENT);
  3950. +
  3951. +    if (GetTypeId() == TYPEID_PLAYER)
  3952. +    {
  3953. +        Player* player = (Player*)this;
  3954. +
  3955. +        if (BattleGround *bg = player->GetBattleGround())
  3956. +            bg->EventPlayerDroppedFlag(player);
  3957. +
  3958. +        WorldPacket data(SMSG_BREAK_TARGET, 8);
  3959. +        data << vehicle->GetBase()->GetPackGUID();
  3960. +        player->GetSession()->SendPacket(&data);
  3961. +    }
  3962. +}
  3963. +
  3964. +void Unit::EnterVehicle(Vehicle *vehicle, int8 seat_id, bool force)
  3965. +{
  3966. +    ExitVehicle();
  3967. +
  3968. +    RemoveSpellsCausingAura(SPELL_AURA_MOUNTED);
  3969. +
  3970. +    Vehicle *v = vehicle->FindFreeSeat(&seat_id, force);
  3971. +    if(!v)
  3972. +        return;
  3973. +
  3974. +    VehicleEntry const *ve = sVehicleStore.LookupEntry(v->GetVehicleId());
  3975. +    if(!ve)
  3976. +        return;
  3977. +
  3978. +    VehicleSeatEntry const *veSeat = sVehicleSeatStore.LookupEntry(ve->m_seatID[seat_id]);
  3979. +    if(!veSeat)
  3980. +        return;
  3981. +
  3982. +    m_movementInfo.SetTransportData(v->GetGUID(),
  3983. +        (veSeat->m_attachmentOffsetX + v->GetObjectBoundingRadius()) * GetFloatValue(OBJECT_FIELD_SCALE_X),
  3984. +        (veSeat->m_attachmentOffsetY + v->GetObjectBoundingRadius()) * GetFloatValue(OBJECT_FIELD_SCALE_X),
  3985. +        (veSeat->m_attachmentOffsetZ + v->GetObjectBoundingRadius()) * GetFloatValue(OBJECT_FIELD_SCALE_X),
  3986. +        veSeat->m_passengerYaw, v->GetCreationTime(), seat_id, NULL, v->GetVehicleFlags());
  3987. +
  3988. +    addUnitState(UNIT_STAT_ON_VEHICLE);
  3989. +    InterruptNonMeleeSpells(false);
  3990. +
  3991. +    if(Pet *pet = GetPet())
  3992. +        pet->Remove(PET_SAVE_AS_CURRENT);
  3993. +
  3994. +    if(GetTypeId() == TYPEID_PLAYER)
  3995. +        ((Player*)this)->SendEnterVehicle(v);
  3996. +
  3997. +    WorldPacket data(SMSG_MONSTER_MOVE_TRANSPORT, 60);
  3998. +    data << GetPackGUID();
  3999. +    data << v->GetPackGUID();
  4000. +    data << uint8(seat_id);
  4001. +    data << uint8(0);
  4002. +    data << v->GetPositionX() << v->GetPositionY() << v->GetPositionZ();
  4003. +    data << uint32(getMSTime());
  4004. +
  4005. +    data << uint8(4);
  4006. +    data << float(0);
  4007. +
  4008. +    data << uint32(SPLINEFLAG_UNKNOWN5);
  4009. +
  4010. +    data << uint32(0);
  4011. +    data << uint32(1);
  4012. +    data << m_movementInfo.GetTransportPos()->x;
  4013. +    data << m_movementInfo.GetTransportPos()->y;
  4014. +    data << m_movementInfo.GetTransportPos()->z;
  4015. +    SendMessageToSet(&data, true);
  4016. +
  4017. +    v->AddPassenger(this, seat_id, force);
  4018. +}
  4019. +
  4020. +void Unit::ExitVehicle()
  4021. +{
  4022. +    if(m_vehicleKit && m_vehicleKit->GetBase() == this)
  4023. +    {
  4024. +        m_vehicleKit->RemoveAllPassengers();
  4025. +    }
  4026. +
  4027. +    if(uint64 vehicleGUID = GetVehicleGUID())
  4028. +    {
  4029. +        float v_size = 0.0f;
  4030. +        if(Vehicle *vehicle = ObjectAccessor::GetVehicle(vehicleGUID))
  4031. +        {
  4032. +            if(m_movementInfo.GetVehicleSeatFlags() & SF_MAIN_RIDER)
  4033. +            {
  4034. +                if(vehicle->GetVehicleFlags() & VF_DESPAWN_AT_LEAVE)
  4035. +                {
  4036. +                    vehicle->SetSpawnDuration(1);
  4037. +                }
  4038. +            }
  4039. +            v_size = vehicle->GetObjectBoundingRadius();
  4040. +            vehicle->RemovePassenger(this);
  4041. +        }
  4042. +        SetVehicleGUID(0);
  4043. +
  4044. +        clearUnitState(UNIT_STAT_ON_VEHICLE);
  4045. +
  4046. +        if(GetTypeId() == TYPEID_PLAYER)
  4047. +        {
  4048. +            ((Player*)this)->ResummonPetTemporaryUnSummonedIfAny();
  4049. +            ((Player*)this)->m_movementInfo.RemoveMovementFlag(MOVEFLAG_ROOT);
  4050. +        }
  4051. +
  4052. +        float x = GetPositionX();
  4053. +        float y = GetPositionY();
  4054. +        float z = GetPositionZ() + 1.0f;
  4055. +        GetClosePoint(x, y, z, 1.0f + v_size);
  4056. +        SendMonsterMove(x, y, z, SPLINETYPE_NORMAL, SPLINEFLAG_WALKMODE, 0);
  4057. +    }
  4058. +    else
  4059. +    {
  4060. +        if(!m_vehicle)
  4061. +            return;
  4062. +
  4063. +        Unit* pVehicleBase = m_vehicle->GetBase();
  4064. +
  4065. +        float angle = pVehicleBase->GetOrientation();
  4066. +
  4067. +        m_vehicle->RemovePassenger(this);
  4068. +        m_vehicle = NULL;
  4069. +
  4070. +        if (GetTypeId() == TYPEID_PLAYER)
  4071. +            ((Player*)this)->ResummonPetTemporaryUnSummonedIfAny();
  4072. +
  4073. +        float x = GetPositionX();
  4074. +        float y = GetPositionY();
  4075. +        float z = GetPositionZ() + 1.0f;
  4076. +        GetClosePoint(x, y, z, 1.0f);
  4077. +        SendMonsterMove(x, y, z, SPLINETYPE_NORMAL, SPLINEFLAG_WALKMODE, 0);
  4078. +    }
  4079. +}
  4080. +
  4081.  bool Unit::CheckAndIncreaseCastCounter()
  4082.  {
  4083.      uint32 maxCasts = sWorld.getConfig(CONFIG_UINT32_MAX_SPELL_CASTS_IN_CHAIN);
  4084. diff --git a/src/game/Unit.h b/src/game/Unit.h
  4085. index c114cff..a6bf1df 100644
  4086. --- a/src/game/Unit.h
  4087. +++ b/src/game/Unit.h
  4088. @@ -303,6 +303,8 @@ class Item;
  4089.  class Pet;
  4090.  class PetAura;
  4091.  class Totem;
  4092. +class Vehicle;
  4093. +class VehicleKit;
  4094.  
  4095.  struct SpellImmune
  4096.  {
  4097. @@ -440,24 +442,25 @@ enum UnitState
  4098.      UNIT_STAT_FOLLOW_MOVE     = 0x00010000,
  4099.      UNIT_STAT_FLEEING         = 0x00020000,                     // FleeMovementGenerator/TimedFleeingMovementGenerator active/onstack
  4100.      UNIT_STAT_FLEEING_MOVE    = 0x00040000,
  4101. +    UNIT_STAT_ON_VEHICLE      = 0x00080000,
  4102.  
  4103.      // masks (only for check)
  4104.  
  4105.      // can't move currently
  4106. -    UNIT_STAT_CAN_NOT_MOVE    = UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_DIED,
  4107. +    UNIT_STAT_CAN_NOT_MOVE    = UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_DIED | UNIT_STAT_ON_VEHICLE,
  4108.  
  4109.      // stay by different reasons
  4110.      UNIT_STAT_NOT_MOVE        = UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_DIED |
  4111. -                                UNIT_STAT_DISTRACTED,
  4112. +                                UNIT_STAT_DISTRACTED | UNIT_STAT_ON_VEHICLE,
  4113.  
  4114.      // stay or scripted movement for effect( = in player case you can't move by client command)
  4115.      UNIT_STAT_NO_FREE_MOVE    = UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_DIED |
  4116.                                  UNIT_STAT_TAXI_FLIGHT |
  4117. -                                UNIT_STAT_CONFUSED | UNIT_STAT_FLEEING,
  4118. +                                UNIT_STAT_CONFUSED | UNIT_STAT_FLEEING | UNIT_STAT_ON_VEHICLE,
  4119.  
  4120.      // not react at move in sight or other
  4121.      UNIT_STAT_CAN_NOT_REACT   = UNIT_STAT_STUNNED | UNIT_STAT_DIED |
  4122. -                                UNIT_STAT_CONFUSED | UNIT_STAT_FLEEING,
  4123. +                                UNIT_STAT_CONFUSED | UNIT_STAT_FLEEING | UNIT_STAT_ON_VEHICLE,
  4124.  
  4125.      // AI disabled by some reason
  4126.      UNIT_STAT_LOST_CONTROL    = UNIT_STAT_FLEEING | UNIT_STAT_CONTROLLED,
  4127. @@ -614,6 +617,7 @@ enum NPCFlags
  4128.      UNIT_NPC_FLAG_STABLEMASTER          = 0x00400000,       // 100%
  4129.      UNIT_NPC_FLAG_GUILD_BANKER          = 0x00800000,       // cause client to send 997 opcode
  4130.      UNIT_NPC_FLAG_SPELLCLICK            = 0x01000000,       // cause client to send 1015 opcode (spell click), dynamic, set at loading and don't must be set in DB
  4131. +    UNIT_NPC_FLAG_PLAYER_VEHICLE        = 0x02000000,       // players with mounts that have vehicle data should have it set
  4132.      UNIT_NPC_FLAG_GUARD                 = 0x10000000        // custom flag for guards
  4133.  };
  4134.  
  4135. @@ -750,7 +754,7 @@ class MovementInfo
  4136.  {
  4137.      public:
  4138.          MovementInfo() : moveFlags(MOVEFLAG_NONE), moveFlags2(MOVEFLAG2_NONE), time(0),
  4139. -            t_time(0), t_seat(-1), t_time2(0), s_pitch(0.0f), fallTime(0), u_unk1(0.0f) {}
  4140. +            t_time(0), t_seat(-1), t_seatInfo(NULL), t_time2(0), s_pitch(0.0f), fallTime(0), u_unk1(0.0f) {}
  4141.  
  4142.          // Read/Write methods
  4143.          void Read(ByteBuffer &data);
  4144. @@ -766,7 +770,7 @@ class MovementInfo
  4145.  
  4146.          // Position manipulations
  4147.          Position const *GetPos() const { return &pos; }
  4148. -        void SetTransportData(ObjectGuid guid, float x, float y, float z, float o, uint32 time, int8 seat)
  4149. +        void SetTransportData(ObjectGuid guid, float x, float y, float z, float o, uint32 time, int8 seat, VehicleSeatEntry const* seatInfo = NULL, uint32 vehicle_flags = 0)
  4150.          {
  4151.              t_guid = guid;
  4152.              t_pos.x = x;
  4153. @@ -775,6 +779,8 @@ class MovementInfo
  4154.              t_pos.o = o;
  4155.              t_time = time;
  4156.              t_seat = seat;
  4157. +            t_seatInfo = seatInfo;
  4158. +            t_vehicle_flags = vehicle_flags;
  4159.          }
  4160.          void ClearTransportData()
  4161.          {
  4162. @@ -785,11 +791,16 @@ class MovementInfo
  4163.              t_pos.o = 0.0f;
  4164.              t_time = 0;
  4165.              t_seat = -1;
  4166. +            t_seatInfo = NULL;
  4167. +            t_vehicle_flags = 0;
  4168.          }
  4169.          ObjectGuid const& GetTransportGuid() const { return t_guid; }
  4170.          Position const *GetTransportPos() const { return &t_pos; }
  4171.          int8 GetTransportSeat() const { return t_seat; }
  4172.          uint32 GetTransportTime() const { return t_time; }
  4173. +        int32 GetTransportDBCSeat() const { return t_seatInfo ? t_seatInfo->m_ID : 0; }
  4174. +        uint32 GetVehicleSeatFlags() const { return t_seatInfo ? t_seatInfo->m_flags : 0; }
  4175. +        uint32 GetVehicleFlags() const { return t_vehicle_flags; }
  4176.          uint32 GetFallTime() const { return fallTime; }
  4177.          void ChangePosition(float x, float y, float z, float o) { pos.x = x; pos.y = y; pos.z = z; pos.o = o; }
  4178.          void UpdateTime(uint32 _time) { time = _time; }
  4179. @@ -812,7 +823,9 @@ class MovementInfo
  4180.          Position t_pos;
  4181.          uint32   t_time;
  4182.          int8     t_seat;
  4183. +        VehicleSeatEntry const* t_seatInfo;
  4184.          uint32   t_time2;
  4185. +        uint32   t_vehicle_flags;
  4186.          // swimming and flying
  4187.          float    s_pitch;
  4188.          // last fall time
  4189. @@ -1270,6 +1283,8 @@ class MANGOS_DLL_SPEC Unit : public WorldObject
  4190.          bool IsHostileTo(Unit const* unit) const;
  4191.          bool IsHostileToPlayers() const;
  4192.          bool IsFriendlyTo(Unit const* unit) const;
  4193. +        bool IsInRaidWith(Unit const* unit) const;
  4194. +        bool IsInPartyWith(Unit const* unit) const;
  4195.          bool IsNeutralToAll() const;
  4196.          bool IsContestedGuard() const
  4197.          {
  4198. @@ -1299,7 +1314,7 @@ class MANGOS_DLL_SPEC Unit : public WorldObject
  4199.  
  4200.          bool IsMounted() const { return HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_MOUNT ); }
  4201.          uint32 GetMountID() const { return GetUInt32Value(UNIT_FIELD_MOUNTDISPLAYID); }
  4202. -        void Mount(uint32 mount, uint32 spellId = 0);
  4203. +        void Mount(uint32 mount, uint32 spellId = 0, uint32 vehicleEntry = 0);
  4204.          void Unmount();
  4205.  
  4206.          uint16 GetMaxSkillValueForLevel(Unit const* target = NULL) const { return (target ? GetLevelForTarget(target) : getLevel()) * 5; }
  4207. @@ -1411,6 +1426,10 @@ class MANGOS_DLL_SPEC Unit : public WorldObject
  4208.              return m_spellAuraHolders.find(spellId) != m_spellAuraHolders.end();
  4209.          }
  4210.  
  4211. +        const uint64& GetAuraUpdateMask() const { return m_auraUpdateMask; }
  4212. +        void SetAuraUpdateMask(uint8 slot) { m_auraUpdateMask |= (uint64(1) << slot); }
  4213. +        void ResetAuraUpdateMask() { m_auraUpdateMask = 0; }
  4214. +
  4215.          bool virtual HasSpell(uint32 /*spellID*/) const { return false; }
  4216.  
  4217.          bool HasStealthAura()      const { return HasAuraType(SPELL_AURA_MOD_STEALTH); }
  4218. @@ -1464,6 +1483,9 @@ class MANGOS_DLL_SPEC Unit : public WorldObject
  4219.  
  4220.          template<typename PathElem, typename PathNode>
  4221.          void SendMonsterMoveByPath(Path<PathElem,PathNode> const& path, uint32 start, uint32 end, SplineFlags flags);
  4222. +        void SendMonsterMoveTransport(Unit *vehicle);
  4223. +
  4224. +        virtual bool SetPosition(float x, float y, float z, float orientation, bool teleport = false);
  4225.  
  4226.          void SendHighestThreatUpdate(HostileReference* pHostileReference);
  4227.          void SendThreatClear();
  4228. @@ -1512,12 +1534,13 @@ class MANGOS_DLL_SPEC Unit : public WorldObject
  4229.          Unit* GetCharm() const;
  4230.          void Uncharm();
  4231.          Unit* GetCharmerOrOwner() const { return !GetCharmerGuid().IsEmpty() ? GetCharmer() : GetOwner(); }
  4232. -        Unit* GetCharmerOrOwnerOrSelf()
  4233. +        Unit* GetCharmOrPet() const { return !GetCharmGuid().IsEmpty() ? GetCharm() : (Unit*)GetPet(); }
  4234. +        Unit* GetCharmerOrOwnerOrSelf() const
  4235.          {
  4236.              if(Unit* u = GetCharmerOrOwner())
  4237.                  return u;
  4238.  
  4239. -            return this;
  4240. +            return (Unit*)this;
  4241.          }
  4242.          bool IsCharmerOrOwnerPlayerOrPlayerItself() const;
  4243.          Player* GetCharmerOrOwnerPlayerOrPlayerItself();
  4244. @@ -1924,6 +1947,19 @@ class MANGOS_DLL_SPEC Unit : public WorldObject
  4245.          // Movement info
  4246.          MovementInfo m_movementInfo;
  4247.  
  4248. +         // vehicle system
  4249. +         void EnterVehicle(VehicleKit *vehicle, int8 seatId = -1);
  4250. +         void EnterVehicle(Vehicle *vehicle, int8 seat_id, bool force = false);
  4251. +         void ExitVehicle();
  4252. +         void ChangeSeat(int8 seatId, bool next = true);
  4253. +         uint64 GetVehicleGUID() { return m_vehicleGUID; }
  4254. +         void SetVehicleGUID(uint64 guid) { m_vehicleGUID = guid; }
  4255. +        VehicleKit* GetVehicle() { return m_vehicle; }
  4256. +        VehicleKit* GetVehicleKit() { return m_vehicleKit; }
  4257. +        Unit* GetVehicleBase();
  4258. +        bool CreateVehicleKit(uint32 vehicleEntry);
  4259. +        void RemoveVehicleKit();
  4260. +
  4261.      protected:
  4262.          explicit Unit ();
  4263.  
  4264. @@ -1973,6 +2009,11 @@ class MANGOS_DLL_SPEC Unit : public WorldObject
  4265.          uint32 m_reactiveTimer[MAX_REACTIVE];
  4266.          uint32 m_regenTimer;
  4267.          uint32 m_lastManaUseTimer;
  4268. +        uint64  m_auraUpdateMask;
  4269. +
  4270. +        uint64 m_vehicleGUID;
  4271. +        VehicleKit* m_vehicle;
  4272. +        VehicleKit* m_vehicleKit;
  4273.  
  4274.      private:
  4275.          void CleanupDeletedAuras();
  4276. diff --git a/src/game/Vehicle.cpp b/src/game/Vehicle.cpp
  4277. index b12ae82..7e37751 100644
  4278. --- a/src/game/Vehicle.cpp
  4279. +++ b/src/game/Vehicle.cpp
  4280. @@ -18,12 +18,238 @@
  4281.  
  4282.  #include "Common.h"
  4283.  #include "Log.h"
  4284. -#include "ObjectMgr.h"
  4285.  #include "Vehicle.h"
  4286.  #include "Unit.h"
  4287.  #include "Util.h"
  4288. +#include "WorldPacket.h"
  4289. +#include "Transports.h"
  4290. +#include "InstanceData.h"
  4291.  
  4292. -Vehicle::Vehicle() : Creature(CREATURE_SUBTYPE_VEHICLE), m_vehicleId(0)
  4293. +VehicleKit::VehicleKit(Unit* base, VehicleEntry const* vehicleInfo) : m_vehicleInfo(vehicleInfo), m_pBase(base), m_uiNumFreeSeats(0)
  4294. +{
  4295. +    for (uint32 i = 0; i < MAX_VEHICLE_SEAT; ++i)
  4296. +    {
  4297. +        uint32 seatId = m_vehicleInfo->m_seatID[i];
  4298. +
  4299. +        if (!seatId)
  4300. +            continue;
  4301. +
  4302. +        if (VehicleSeatEntry const *veSeat = sVehicleSeatStore.LookupEntry(seatId))
  4303. +        {
  4304. +            m_Seats.insert(std::make_pair(i, VehicleSeat(veSeat)));
  4305. +
  4306. +            if (veSeat->IsUsable())
  4307. +                ++m_uiNumFreeSeats;
  4308. +        }
  4309. +    }
  4310. +}
  4311. +
  4312. +VehicleKit::~VehicleKit()
  4313. +{
  4314. +}
  4315. +
  4316. +void VehicleKit::RemoveAllPassengers()
  4317. +{
  4318. +    for (SeatMap::iterator itr = m_Seats.begin(); itr != m_Seats.end(); ++itr)
  4319. +    {
  4320. +        if (Unit *passenger = itr->second.passenger)
  4321. +            passenger->ExitVehicle();
  4322. +    }
  4323. +}
  4324. +
  4325. +bool VehicleKit::HasEmptySeat(int8 seatId) const
  4326. +{
  4327. +    SeatMap::const_iterator seat = m_Seats.find(seatId);
  4328. +
  4329. +    if (seat == m_Seats.end())
  4330. +        return false;
  4331. +
  4332. +    return !seat->second.passenger;
  4333. +}
  4334. +
  4335. +Unit *VehicleKit::GetPassenger(int8 seatId) const
  4336. +{
  4337. +    SeatMap::const_iterator seat = m_Seats.find(seatId);
  4338. +
  4339. +    if (seat == m_Seats.end())
  4340. +        return NULL;
  4341. +
  4342. +    return seat->second.passenger;
  4343. +}
  4344. +
  4345. +int8 VehicleKit::GetNextEmptySeat(int8 seatId, bool next) const
  4346. +{
  4347. +    SeatMap::const_iterator seat = m_Seats.find(seatId);
  4348. +
  4349. +    if (seat == m_Seats.end())
  4350. +        return -1;
  4351. +
  4352. +    while (seat->second.passenger || !seat->second.seatInfo->IsUsable())
  4353. +    {
  4354. +        if (next)
  4355. +        {
  4356. +            ++seat;
  4357. +            if (seat == m_Seats.end())
  4358. +                seat = m_Seats.begin();
  4359. +        }
  4360. +        else
  4361. +        {
  4362. +            if (seat == m_Seats.begin())
  4363. +                seat = m_Seats.end();
  4364. +            --seat;
  4365. +        }
  4366. +
  4367. +        if (seat->first == seatId)
  4368. +            return -1; // no available seat
  4369. +    }
  4370. +
  4371. +    return seat->first;
  4372. +}
  4373. +
  4374. +bool VehicleKit::AddPassenger(Unit *unit, int8 seatId)
  4375. +{
  4376. +    SeatMap::iterator seat;
  4377. +
  4378. +    if (seatId < 0) // no specific seat requirement
  4379. +    {
  4380. +        for (seat = m_Seats.begin(); seat != m_Seats.end(); ++seat)
  4381. +        {
  4382. +            if (!seat->second.passenger && seat->second.seatInfo->IsUsable())
  4383. +                break;
  4384. +        }
  4385. +
  4386. +        if (seat == m_Seats.end()) // no available seat
  4387. +            return false;
  4388. +    }
  4389. +    else
  4390. +    {
  4391. +        seat = m_Seats.find(seatId);
  4392. +
  4393. +        if (seat == m_Seats.end())
  4394. +            return false;
  4395. +
  4396. +        if (seat->second.passenger)
  4397. +            seat->second.passenger->ExitVehicle();
  4398. +    }
  4399. +
  4400. +    seat->second.passenger = unit;
  4401. +
  4402. +    if (seat->second.seatInfo->IsUsable())
  4403. +    {
  4404. +        MANGOS_ASSERT(m_uiNumFreeSeats);
  4405. +        --m_uiNumFreeSeats;
  4406. +
  4407. +        if (!m_uiNumFreeSeats)
  4408. +        {
  4409. +            if (m_pBase->GetTypeId() == TYPEID_PLAYER)
  4410. +                m_pBase->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_PLAYER_VEHICLE);
  4411. +            else
  4412. +                m_pBase->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK);
  4413. +        }
  4414. +    }
  4415. +
  4416. +    unit->addUnitState(UNIT_STAT_ON_VEHICLE);
  4417. +
  4418. +    VehicleSeatEntry const *veSeat = seat->second.seatInfo;
  4419. +
  4420. +    unit->m_movementInfo.AddMovementFlag(MOVEFLAG_ONTRANSPORT);
  4421. +    unit->m_movementInfo.SetTransportData(m_pBase->GetGUID(),
  4422. +        veSeat->m_attachmentOffsetX, veSeat->m_attachmentOffsetY, veSeat->m_attachmentOffsetZ,
  4423. +        veSeat->m_passengerYaw, getMSTime(), seat->first, veSeat);
  4424. +
  4425. +    if (unit->GetTypeId() == TYPEID_PLAYER)
  4426. +    {
  4427. +        //((Player*)unit)->GetCamera().SetView(m_pBase);
  4428. +
  4429. +        WorldPacket data(SMSG_FORCE_MOVE_ROOT, 8+4);
  4430. +        data << unit->GetPackGUID();
  4431. +        data << uint32((unit->m_movementInfo.GetVehicleSeatFlags() & SEAT_FLAG_CAN_CAST) ? 2 : 0);
  4432. +        unit->SendMessageToSet(&data, true);
  4433. +    }
  4434. +
  4435. +    unit->SendMonsterMoveTransport(m_pBase);
  4436. +
  4437. +    if (m_pBase->GetTypeId() == TYPEID_UNIT)
  4438. +        RelocatePassengers(m_pBase->GetPositionX(), m_pBase->GetPositionY(), m_pBase->GetPositionZ(), m_pBase->GetOrientation());
  4439. +
  4440. +    return true;
  4441. +}
  4442. +
  4443. +void VehicleKit::RemovePassenger(Unit *unit)
  4444. +{
  4445. +    SeatMap::iterator seat;
  4446. +    for (seat = m_Seats.begin(); seat != m_Seats.end(); ++seat)
  4447. +    {
  4448. +        if (seat->second.passenger == unit)
  4449. +            break;
  4450. +    }
  4451. +
  4452. +    if (seat == m_Seats.end())
  4453. +        return;
  4454. +
  4455. +    seat->second.passenger = NULL;
  4456. +
  4457. +    if (seat->second.seatInfo->IsUsable())
  4458. +    {
  4459. +        if (!m_uiNumFreeSeats)
  4460. +        {
  4461. +            if (m_pBase->GetTypeId() == TYPEID_PLAYER)
  4462. +                m_pBase->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_PLAYER_VEHICLE);
  4463. +            else
  4464. +                m_pBase->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK);
  4465. +        }
  4466. +
  4467. +        ++m_uiNumFreeSeats;
  4468. +    }
  4469. +
  4470. +    unit->clearUnitState(UNIT_STAT_ON_VEHICLE);
  4471. +
  4472. +    unit->m_movementInfo.ClearTransportData();
  4473. +    unit->m_movementInfo.RemoveMovementFlag(MOVEFLAG_ONTRANSPORT);
  4474. +
  4475. +    if (unit->GetTypeId() == TYPEID_PLAYER)
  4476. +    {
  4477. +        //((Player*)unit)->GetCamera().ResetView();
  4478. +
  4479. +        WorldPacket data(SMSG_FORCE_MOVE_UNROOT, 8+4);
  4480. +        data << unit->GetPackGUID();
  4481. +        data << uint32(0);
  4482. +        unit->SendMessageToSet(&data, true);
  4483. +    }
  4484. +}
  4485. +
  4486. +void VehicleKit::Reset()
  4487. +{
  4488. +    if (m_pBase->GetTypeId() == TYPEID_PLAYER)
  4489. +    {
  4490. +        if (m_uiNumFreeSeats)
  4491. +            m_pBase->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_PLAYER_VEHICLE);
  4492. +    }
  4493. +    else
  4494. +    {
  4495. +        if (m_uiNumFreeSeats)
  4496. +            m_pBase->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK);
  4497. +    }
  4498. +}
  4499. +
  4500. +void VehicleKit::RelocatePassengers(float x, float y, float z, float ang)
  4501. +{
  4502. +    for (SeatMap::const_iterator itr = m_Seats.begin(); itr != m_Seats.end(); ++itr)
  4503. +    {
  4504. +        if (Unit *passenger = itr->second.passenger)
  4505. +        {
  4506. +            float px = x + passenger->m_movementInfo.GetTransportPos()->x;
  4507. +            float py = y + passenger->m_movementInfo.GetTransportPos()->y;
  4508. +            float pz = z + passenger->m_movementInfo.GetTransportPos()->z;
  4509. +            float po = ang + passenger->m_movementInfo.GetTransportPos()->o;
  4510. +
  4511. +            passenger->SetPosition(px, py, pz, po);
  4512. +        }
  4513. +    }
  4514. +}
  4515. +
  4516. +Vehicle::Vehicle() : Creature(CREATURE_SUBTYPE_VEHICLE), m_vehicleId(0), m_vehicleInfo(NULL), m_spawnduration(0),
  4517. +                     despawn(false), m_creation_time(0), m_VehicleData(NULL)
  4518.  {
  4519.      m_updateFlag = (UPDATEFLAG_LIVING | UPDATEFLAG_HAS_POSITION | UPDATEFLAG_VEHICLE);
  4520.  }
  4521. @@ -51,45 +277,735 @@ void Vehicle::RemoveFromWorld()
  4522.      Unit::RemoveFromWorld();
  4523.  }
  4524.  
  4525. +void Vehicle::Respawn()
  4526. +{
  4527. +    Creature::Respawn();
  4528. +    InstallAllAccessories();
  4529. +}
  4530. +
  4531.  void Vehicle::SetDeathState(DeathState s)                       // overwrite virtual Creature::SetDeathState and Unit::SetDeathState
  4532.  {
  4533.      Creature::SetDeathState(s);
  4534. +    if(s == JUST_DIED)
  4535. +    {
  4536. +        if(GetVehicleFlags() & VF_DESPAWN_NPC)
  4537. +            Dismiss();
  4538. +        else
  4539. +            RemoveAllPassengers();
  4540. +    }
  4541.  }
  4542.  
  4543.  void Vehicle::Update(uint32 diff)
  4544.  {
  4545.      Creature::Update(diff);
  4546. +    if(despawn)
  4547. +    {
  4548. +        m_spawnduration -= diff;
  4549. +        if(m_spawnduration < 0)
  4550. +            Dismiss();
  4551. +        despawn = false;
  4552. +    }
  4553. +
  4554. +    if(m_regenTimer <= diff)
  4555. +    {
  4556. +        RegeneratePower(getPowerType());
  4557. +        m_regenTimer = 4000;
  4558. +    }
  4559. +    else
  4560. +        m_regenTimer -= diff;
  4561.  }
  4562.  
  4563. -bool Vehicle::Create(uint32 guidlow, Map *map, uint32 Entry, uint32 vehicleId, uint32 team)
  4564. +void Vehicle::RegeneratePower(Powers power)
  4565. +{
  4566. +    uint32 curValue = GetPower(power);
  4567. +    uint32 maxValue = GetMaxPower(power);
  4568. +
  4569. +    if (curValue >= maxValue)
  4570. +        return;
  4571. +
  4572. +    float addvalue = 0.0f;
  4573. +
  4574. +    // hack: needs more research of power type from the dbc.
  4575. +    // It must contains some info about vehicles like Salvaged Chopper.
  4576. +    if(m_vehicleInfo->m_powerType == POWER_TYPE_PYRITE)
  4577. +        return;
  4578. +
  4579. +    addvalue = 20.0f;
  4580. +
  4581. +    ModifyPower(power, (int32)addvalue);
  4582. +}
  4583. +
  4584. +bool Vehicle::Create(uint32 guidlow, Map *map, uint32 phaseMask, uint32 Entry, uint32 vehicleId, uint32 team, const CreatureData *data)
  4585.  {
  4586.      SetMap(map);
  4587. +    SetPhaseMask(phaseMask,false);
  4588. +
  4589. +    CreatureInfo const *cinfo = sObjectMgr.GetCreatureTemplate(Entry);
  4590. +    if(!cinfo)
  4591. +    {
  4592. +        sLog.outErrorDb("Creature entry %u does not exist.", Entry);
  4593. +        return false;
  4594. +    }
  4595.  
  4596.      Object::_Create(guidlow, Entry, HIGHGUID_VEHICLE);
  4597.  
  4598. -    if(!InitEntry(Entry, team))
  4599. +    if(!UpdateEntry(Entry, team, data))
  4600.          return false;
  4601.  
  4602. -    m_defaultMovementType = IDLE_MOTION_TYPE;
  4603. +    if(!vehicleId)
  4604. +    {
  4605. +        CreatureDataAddon const *cainfo = GetCreatureAddon();
  4606. +        if(!cainfo)
  4607. +            return false;
  4608. +        vehicleId = cainfo->vehicle_id;
  4609. +    }
  4610. +    if(!SetVehicleId(vehicleId))
  4611. +        return false;
  4612.  
  4613. -    AIM_Initialize();
  4614. +    LoadCreatureAddon();
  4615.  
  4616. -    SetVehicleId(vehicleId);
  4617. +    m_regenHealth = false;
  4618. +    m_creation_time = getMSTime();
  4619.  
  4620. -    SetUInt32Value(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK);
  4621.      SetFloatValue(UNIT_FIELD_HOVERHEIGHT, 1.0f);
  4622. +    //RemoveMonsterMoveFlag(MONSTER_MOVE_WALK);
  4623. +
  4624. +    //Notify the map's instance data.
  4625. +    //Only works if you create the object in it, not if it is moves to that map.
  4626. +    //Normally non-players do not teleport to other maps.
  4627. +    if(map->IsDungeon() && ((InstanceMap*)map)->GetInstanceData())
  4628. +    {
  4629. +        ((InstanceMap*)map)->GetInstanceData()->OnCreatureCreate(this);
  4630. +    }
  4631. +
  4632. +    if(m_vehicleInfo->m_powerType == POWER_TYPE_STEAM)
  4633. +    {
  4634. +        setPowerType(POWER_ENERGY);
  4635. +        SetMaxPower(POWER_ENERGY, 100);
  4636. +        SetPower(POWER_ENERGY, 100);
  4637. +    }
  4638. +    else if(m_vehicleInfo->m_powerType == POWER_TYPE_PYRITE)
  4639. +    {
  4640. +        setPowerType(POWER_ENERGY);
  4641. +        SetMaxPower(POWER_ENERGY, 50);
  4642. +        SetPower(POWER_ENERGY, 50);
  4643. +    }
  4644. +    else
  4645. +    {
  4646. +        for (uint32 i = 0; i < MAX_VEHICLE_SPELLS; ++i)
  4647. +        {
  4648. +            if(!GetVehicleData()->v_spells[i])
  4649. +                continue;
  4650. +            SpellEntry const *spellInfo = sSpellStore.LookupEntry(GetVehicleData()->v_spells[i]);
  4651. +            if(!spellInfo)
  4652. +                continue;
  4653. +
  4654. +            if(spellInfo->powerType == POWER_MANA)
  4655. +                break;
  4656. +
  4657. +            if(spellInfo->powerType == POWER_ENERGY)
  4658. +            {
  4659. +                setPowerType(POWER_ENERGY);
  4660. +                SetMaxPower(POWER_ENERGY, 100);
  4661. +                SetPower(POWER_ENERGY, 100);
  4662. +                break;
  4663. +            }
  4664. +        }
  4665. +    }
  4666. +    SetHealth(GetMaxHealth());
  4667. +    InstallAllAccessories();
  4668. +
  4669. +    return true;
  4670. +}
  4671. +
  4672. +bool Vehicle::SetVehicleId(uint32 vehicleid)
  4673. +{
  4674. +    VehicleEntry const *vehicleInfo = sVehicleStore.LookupEntry(vehicleid);
  4675. +    if(!vehicleInfo)
  4676. +        return false;
  4677.  
  4678. -    CreatureInfo const *ci = GetCreatureInfo();
  4679. -    setFaction(team == ALLIANCE ? ci->faction_A : ci->faction_H);
  4680. +    m_vehicleId = vehicleid;
  4681. +    m_vehicleInfo = vehicleInfo;
  4682.  
  4683. -    SelectLevel(ci);
  4684. +    // can be NULL
  4685. +    VehicleDataStructure const *VDStructure = sObjectMgr.GetVehicleData(vehicleid);
  4686. +    if(VDStructure)
  4687. +        m_VehicleData = VDStructure;
  4688.  
  4689. +    InitSeats();
  4690. +    EmptySeatsCountChanged();
  4691.      return true;
  4692.  }
  4693.  
  4694. +void Vehicle::InitSeats()
  4695. +{
  4696. +    m_Seats.clear();
  4697. +
  4698. +    for(uint32 i = 0; i < MAX_SEAT; ++i)
  4699. +    {
  4700. +        uint32 seatId = m_vehicleInfo->m_seatID[i];
  4701. +        if(seatId)
  4702. +        {
  4703. +            if(VehicleSeatEntry const *veSeat = sVehicleSeatStore.LookupEntry(seatId))
  4704. +            {
  4705. +                VehicleSeat newseat;
  4706. +                newseat.seatInfo = veSeat;
  4707. +                newseat.passenger = NULL;
  4708. +                newseat.flags = SEAT_FREE;
  4709. +                newseat.vs_flags = sObjectMgr.GetSeatFlags(seatId);
  4710. +                m_Seats[i] = newseat;
  4711. +            }
  4712. +        }
  4713. +    }
  4714. +    // NOTE : there can be vehicles without seats (eg. 180) - probably some TEST vehicles
  4715. +}
  4716. +
  4717. +void Vehicle::ChangeSeatFlag(uint8 seat, uint8 flag)
  4718. +{
  4719. +    SeatMap::iterator i_seat = m_Seats.find(seat);
  4720. +    // this should never happen
  4721. +    if(i_seat == m_Seats.end())
  4722. +        return;
  4723. +
  4724. +    if(i_seat->second.flags != flag)
  4725. +    {
  4726. +        i_seat->second.flags = flag;
  4727. +        EmptySeatsCountChanged();
  4728. +    }
  4729. +}
  4730. +
  4731. +Vehicle* Vehicle::FindFreeSeat(int8 *seatid, bool force)
  4732. +{
  4733. +    SeatMap::const_iterator i_seat = m_Seats.find(*seatid);
  4734. +    if(i_seat == m_Seats.end())
  4735. +        return GetFirstEmptySeat(seatid, force);
  4736. +    if((i_seat->second.flags & (SEAT_FULL | SEAT_VEHICLE_FULL)) || (!force && (i_seat->second.vs_flags & SF_UNACCESSIBLE)))
  4737. +        return GetNextEmptySeat(seatid, true, force);
  4738. +    if(i_seat->second.flags & SEAT_VEHICLE_FREE)
  4739. +    {
  4740. +        // this should never be NULL
  4741. +        if(Vehicle *v = (Vehicle*)i_seat->second.passenger)
  4742. +            return v->FindFreeSeat(seatid, force);
  4743. +        return NULL;
  4744. +    }
  4745. +    return this;
  4746. +}
  4747. +
  4748. +Vehicle* Vehicle::GetFirstEmptySeat(int8 *seatId, bool force)
  4749. +{
  4750. +    for(SeatMap::iterator itr = m_Seats.begin(); itr != m_Seats.end(); ++itr)
  4751. +    {
  4752. +        if(itr->second.flags & SEAT_FREE)
  4753. +        {
  4754. +            if(!force && (itr->second.vs_flags & SF_UNACCESSIBLE))
  4755. +                continue;
  4756. +
  4757. +            *seatId = itr->first;
  4758. +            return this;
  4759. +        }
  4760. +        else if(itr->second.flags & SEAT_VEHICLE_FREE)
  4761. +        {
  4762. +            *seatId = itr->first;
  4763. +            if(Vehicle *v = (Vehicle*)itr->second.passenger)
  4764. +                return v->FindFreeSeat(seatId, force);
  4765. +        }
  4766. +    }
  4767. +
  4768. +    return NULL;
  4769. +}
  4770. +
  4771. +Vehicle* Vehicle::GetNextEmptySeat(int8 *seatId, bool next, bool force)
  4772. +{
  4773. +    SeatMap::const_iterator i_seat = m_Seats.find(*seatId);
  4774. +    if(i_seat == m_Seats.end()) return GetFirstEmptySeat(seatId, force);
  4775. +
  4776. +    while((i_seat->second.flags & (SEAT_FULL | SEAT_VEHICLE_FULL)) || (!force && (i_seat->second.vs_flags & SF_UNACCESSIBLE)))
  4777. +    {
  4778. +        if(next)
  4779. +        {
  4780. +            ++i_seat;
  4781. +            if(i_seat == m_Seats.end())
  4782. +                i_seat = m_Seats.begin();
  4783. +        }
  4784. +        else
  4785. +        {
  4786. +            if(i_seat == m_Seats.begin())
  4787. +                i_seat = m_Seats.end();
  4788. +            --i_seat;
  4789. +        }
  4790. +        if(i_seat->first == *seatId)
  4791. +            return NULL;
  4792. +    }
  4793. +    *seatId = i_seat->first;
  4794. +    if(i_seat->second.flags & SEAT_VEHICLE_FREE)
  4795. +    {
  4796. +        if(Vehicle *v = (Vehicle*)i_seat->second.passenger)
  4797. +            return v->FindFreeSeat(seatId, force);
  4798. +        return NULL;
  4799. +    }
  4800. +
  4801. +    return this;
  4802. +}
  4803. +
  4804. +int8 Vehicle::GetEmptySeatsCount(bool force)
  4805. +{
  4806. +    int8 count = 0;
  4807. +    for(SeatMap::iterator itr = m_Seats.begin(); itr != m_Seats.end(); ++itr)
  4808. +   {
  4809. +        if(itr->second.flags & (SEAT_FREE | SEAT_VEHICLE_FREE))
  4810. +        {
  4811. +            if(!force && (itr->second.vs_flags & SF_UNACCESSIBLE))
  4812. +                continue;
  4813. +
  4814. +            count++;
  4815. +        }
  4816. +    }
  4817. +
  4818. +    return count;
  4819. +}
  4820. +
  4821. +int8 Vehicle::GetNextEmptySeatNum(int8 seatId, bool next) const
  4822. +{
  4823. +    SeatMap::const_iterator seat = m_Seats.find(seatId);
  4824. +    if(seat == m_Seats.end()) return -1;
  4825. +    while(seat->second.passenger || !seat->second.seatInfo->IsUsable())
  4826. +    {
  4827. +        if(next)
  4828. +        {
  4829. +            ++seat;
  4830. +            if(seat == m_Seats.end())
  4831. +                seat = m_Seats.begin();
  4832. +        }
  4833. +        else
  4834. +        {
  4835. +            if(seat == m_Seats.begin())
  4836. +                seat = m_Seats.end();
  4837. +            --seat;
  4838. +        }
  4839. +        if(seat->first == seatId)
  4840. +            return -1; // no available seat
  4841. +    }
  4842. +    return seat->first;
  4843. +}
  4844. +
  4845. +bool Vehicle::HasEmptySeat(int8 seatId) const
  4846. +{
  4847. +    SeatMap::const_iterator seat = m_Seats.find(seatId);
  4848. +    if(seat == m_Seats.end()) return false;
  4849. +    return !seat->second.passenger;
  4850. +}
  4851. +
  4852. +void Vehicle::EmptySeatsCountChanged()
  4853. +{
  4854. +    uint8 m_count = GetTotalSeatsCount();
  4855. +    uint8 p_count = GetEmptySeatsCount(false);
  4856. +    uint8 u_count = GetEmptySeatsCount(true);
  4857. +
  4858. +    // seats accesibles by players
  4859. +    if(p_count > 0)
  4860. +        SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK);
  4861. +    else
  4862. +        RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK);
  4863. +
  4864. +    if(u_count == m_count)
  4865. +    {
  4866. +        RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED);
  4867. +    }
  4868. +    else
  4869. +        SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED);
  4870. +
  4871. +    if(uint64 vehicleGUID = GetVehicleGUID())
  4872. +    {
  4873. +        if(Vehicle *vehicle = ObjectAccessor::GetVehicle(vehicleGUID))
  4874. +        {
  4875. +            if(u_count > 0)
  4876. +                vehicle->ChangeSeatFlag(vehicle->GetPassengerSeat(this), SEAT_VEHICLE_FREE);
  4877. +            else
  4878. +                vehicle->ChangeSeatFlag(vehicle->GetPassengerSeat(this), SEAT_VEHICLE_FULL);
  4879. +        }
  4880. +    }
  4881. +}
  4882. +
  4883.  void Vehicle::Dismiss()
  4884.  {
  4885. +    RemoveAllPassengers();
  4886.      SendObjectDeSpawnAnim(GetGUID());
  4887.      CombatStop();
  4888.      AddObjectToRemoveList();
  4889.  }
  4890. +
  4891. +void Vehicle::RellocatePassengers(Map *map)
  4892. +{
  4893. +    if (m_Seats.empty())
  4894. +        return;
  4895. +
  4896. +    for(SeatMap::iterator itr = m_Seats.begin(); itr != m_Seats.end(); ++itr)
  4897. +    {
  4898. +        if(itr->second.flags & SEAT_FULL)
  4899. +        {
  4900. +            // passenger cant be NULL here
  4901. +            Unit *passengers = itr->second.passenger;
  4902. +            MANGOS_ASSERT(passengers);
  4903. +
  4904. +            float xx = GetPositionX() + passengers->m_movementInfo.GetTransportPos()->x;
  4905. +            float yy = GetPositionY() + passengers->m_movementInfo.GetTransportPos()->y;
  4906. +            float zz = GetPositionZ() + passengers->m_movementInfo.GetTransportPos()->z;
  4907. +            //float oo = passengers->m_SeatData.Orientation;
  4908. +            // this is not correct, we should recalculate
  4909. +            // actual rotation depending on vehicle
  4910. +            float oo = passengers->GetOrientation();
  4911. +
  4912. +            if(passengers->GetTypeId() == TYPEID_PLAYER)
  4913. +                ((Player*)passengers)->SetPosition(xx, yy, zz, oo);
  4914. +            else
  4915. +                map->CreatureRelocation((Creature*)passengers, xx, yy, zz, oo);
  4916. +        }
  4917. +        else if(itr->second.flags & (SEAT_VEHICLE_FULL | SEAT_VEHICLE_FREE))
  4918. +        {
  4919. +            // passenger cant be NULL here
  4920. +            Unit *passengers = itr->second.passenger;
  4921. +            MANGOS_ASSERT(passengers);
  4922. +
  4923. +            float xx = GetPositionX() + passengers->m_movementInfo.GetTransportPos()->x;
  4924. +            float yy = GetPositionY() + passengers->m_movementInfo.GetTransportPos()->y;
  4925. +            float zz = GetPositionZ() + passengers->m_movementInfo.GetTransportPos()->z;
  4926. +            //float oo = passengers->m_SeatData.Orientation;
  4927. +            // this is not correct, we should recalculate
  4928. +            // actual rotation depending on vehicle
  4929. +            float oo = passengers->GetOrientation();
  4930. +
  4931. +            map->CreatureRelocation((Creature*)passengers, xx, yy, zz, oo);
  4932. +        }
  4933. +    }
  4934. +}
  4935. +
  4936. +void Vehicle::AddPassenger(Unit *unit, int8 seatId, bool force)
  4937. +{
  4938. +    SeatMap::iterator seat;
  4939. +    seat = m_Seats.find(seatId);
  4940. +
  4941. +    // this should never happen
  4942. +    if(seat == m_Seats.end())
  4943. +        return;
  4944. +
  4945. +    unit->SetVehicleGUID(GetGUID());
  4946. +    unit->m_movementInfo.AddMovementFlag(MOVEFLAG_ONTRANSPORT);
  4947. +    unit->m_movementInfo.AddMovementFlag(MOVEFLAG_ROOT);
  4948. +
  4949. +    seat->second.passenger = unit;
  4950. +    if(unit->GetTypeId() == TYPEID_UNIT && ((Creature*)unit)->IsVehicle())
  4951. +    {
  4952. +        if(((Vehicle*)unit)->GetEmptySeatsCount(true) == 0)
  4953. +            seat->second.flags = SEAT_VEHICLE_FULL;
  4954. +        else
  4955. +            seat->second.flags = SEAT_VEHICLE_FREE;
  4956. +    }
  4957. +    else
  4958. +    {
  4959. +        seat->second.flags = SEAT_FULL;
  4960. +    }
  4961. +
  4962. +    if(unit->GetTypeId() == TYPEID_PLAYER)
  4963. +    {
  4964. +        WorldPacket data0(SMSG_FORCE_MOVE_ROOT, 10);
  4965. +        data0 << unit->GetPackGUID();
  4966. +        data0 << (uint32)((seat->second.vs_flags & SF_CAN_CAST) ? 2 : 0);
  4967. +        unit->SendMessageToSet(&data0,true);
  4968. +    }
  4969. +
  4970. +    if(seat->second.vs_flags & SF_MAIN_RIDER)
  4971. +    {
  4972. +        if(!(GetVehicleFlags() & VF_MOVEMENT))
  4973. +        {
  4974. +            GetMotionMaster()->Clear(false);
  4975. +            GetMotionMaster()->MoveIdle();
  4976. +            SetCharmerGuid(unit->GetGUID());
  4977. +            unit->SetUInt64Value(UNIT_FIELD_CHARM, GetGUID());
  4978. +            if(unit->GetTypeId() == TYPEID_PLAYER)
  4979. +            {
  4980. +                ((Player*)unit)->SetMover(this);
  4981. +                ((Player*)unit)->SetClientControl(this, 1);
  4982. +                ((Player*)unit)->GetCamera().SetView(this);
  4983. +            }
  4984. +            if(CanFly() || HasAuraType(SPELL_AURA_FLY) || HasAuraType(SPELL_AURA_MOD_FLIGHT_SPEED))
  4985. +            {
  4986. +                WorldPacket data3(SMSG_MOVE_SET_CAN_FLY, 12);
  4987. +                data3 << GetPackGUID();
  4988. +                data3 << (uint32)(0);
  4989. +                SendMessageToSet(&data3,false);
  4990. +            }
  4991. +        }
  4992. +
  4993. +        SpellClickInfoMapBounds clickPair = sObjectMgr.GetSpellClickInfoMapBounds(GetEntry());
  4994. +        for(SpellClickInfoMap::const_iterator itr = clickPair.first; itr != clickPair.second; ++itr)
  4995. +        {
  4996. +            if (unit->GetTypeId() == TYPEID_UNIT || itr->second.IsFitToRequirements((Player*)unit))
  4997. +            {
  4998. +                Unit *caster = (itr->second.castFlags & 0x1) ? unit : this;
  4999. +                Unit *target = (itr->second.castFlags & 0x2) ? unit : this;
  5000. +
  5001. +                caster->CastSpell(target, itr->second.spellId, true);
  5002. +            }
  5003. +        }
  5004. +        if(unit->GetTypeId() == TYPEID_PLAYER)
  5005. +        {
  5006. +            // it should be added only on rider enter?
  5007. +            if(((Player*)unit)->GetGroup())
  5008. +                ((Player*)unit)->SetGroupUpdateFlag(GROUP_UPDATE_VEHICLE);
  5009. +
  5010. +            BuildVehicleActionBar((Player*)unit);
  5011. +        }
  5012. +
  5013. +        if(!(GetVehicleFlags() & VF_FACTION))
  5014. +            setFaction(unit->getFaction());
  5015. +
  5016. +        if(GetVehicleFlags() & VF_CANT_MOVE)
  5017. +        {
  5018. +            WorldPacket data2(SMSG_FORCE_MOVE_ROOT, 10);
  5019. +            data2 << GetPackGUID();
  5020. +            data2 << (uint32)(2);
  5021. +            SendMessageToSet(&data2,false);
  5022. +        }
  5023. +
  5024. +        if(GetVehicleFlags() & VF_NON_SELECTABLE)
  5025. +            SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
  5026. +    }
  5027. +    if(seat->second.vs_flags & SF_UNATTACKABLE)
  5028. +        unit->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
  5029. +
  5030. +    EmptySeatsCountChanged();
  5031. +}
  5032. +
  5033. +void Vehicle::RemovePassenger(Unit *unit)
  5034. +{
  5035. +    SeatMap::iterator seat;
  5036. +    for(seat = m_Seats.begin(); seat != m_Seats.end(); ++seat)
  5037. +    {
  5038. +        if((seat->second.flags & (SEAT_FULL | SEAT_VEHICLE_FREE | SEAT_VEHICLE_FULL)) && seat->second.passenger == unit)
  5039. +        {
  5040. +            unit->SetVehicleGUID(0);
  5041. +            if(unit->GetTypeId() == TYPEID_PLAYER)
  5042. +            {
  5043. +                ((Player*)unit)->SetMover(unit);
  5044. +                ((Player*)unit)->SetClientControl(unit, 1);
  5045. +                ((Player*)unit)->GetCamera().SetView(unit);
  5046. +            }
  5047. +
  5048. +            if(seat->second.vs_flags & SF_MAIN_RIDER)
  5049. +            {
  5050. +                RemoveSpellsCausingAura(SPELL_AURA_CONTROL_VEHICLE);
  5051. +                if(unit->GetTypeId() == TYPEID_PLAYER)
  5052. +                {
  5053. +                    ((Player*)unit)->RemovePetActionBar();
  5054. +
  5055. +                    if(((Player*)unit)->GetGroup())
  5056. +                        ((Player*)unit)->SetGroupUpdateFlag(GROUP_UPDATE_VEHICLE);
  5057. +                }
  5058. +                unit->SetCharm(NULL);
  5059. +                SetCharmerGuid(ObjectGuid());
  5060. +                setFaction(GetCreatureInfo()->faction_A);
  5061. +            }
  5062. +            if(GetVehicleFlags() & VF_NON_SELECTABLE)
  5063. +                RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
  5064. +            if(seat->second.vs_flags & SF_UNATTACKABLE)
  5065. +                unit->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
  5066. +            // restore player control
  5067. +            if(unit->GetTypeId() == TYPEID_PLAYER)
  5068. +            {
  5069. +                if(seat->second.vs_flags & SF_CAN_CAST)
  5070. +                {
  5071. +                    WorldPacket data0(SMSG_FORCE_MOVE_UNROOT, 10);
  5072. +                    data0 << unit->GetPackGUID();
  5073. +                    data0 << (uint32)(2);                        // can rotate
  5074. +                    unit->SendMessageToSet(&data0,true);
  5075. +                }
  5076. +                else
  5077. +                {
  5078. +                    WorldPacket data1(SMSG_FORCE_MOVE_UNROOT, 10);
  5079. +                    data1 << unit->GetPackGUID();
  5080. +                    data1 << (uint32)(0);                        // cannot rotate
  5081. +                    unit->SendMessageToSet(&data1,true);
  5082. +                }
  5083. +            }
  5084. +            unit->m_movementInfo.RemoveMovementFlag(MOVEFLAG_ONTRANSPORT);
  5085. +            unit->m_movementInfo.RemoveMovementFlag(MOVEFLAG_ROOT);
  5086. +
  5087. +            // only for flyable vehicles
  5088. +            if (unit->m_movementInfo.HasMovementFlag(MOVEFLAG_FLYING))
  5089. +            ((Player*)unit)->CastSpell(unit, 45472, true);               // Parachute
  5090. +
  5091. +            seat->second.passenger = NULL;
  5092. +            seat->second.flags = SEAT_FREE;
  5093. +            unit->m_movementInfo.ClearTransportData();
  5094. +
  5095. +            EmptySeatsCountChanged();
  5096. +
  5097. +            break;
  5098. +        }
  5099. +    }
  5100. +}
  5101. +
  5102. +void Vehicle::RemoveAllPassengers()
  5103. +{
  5104. +    for(SeatMap::iterator itr = m_Seats.begin(); itr != m_Seats.end(); ++itr)
  5105. +    {
  5106. +        if(itr->second.flags & SEAT_FULL)
  5107. +        {
  5108. +            if(Unit *passenger = itr->second.passenger)                     // this cant be NULL, but..
  5109. +                passenger->ExitVehicle();
  5110. +        }
  5111. +        else if(itr->second.flags & (SEAT_VEHICLE_FULL | SEAT_VEHICLE_FREE))
  5112. +        {
  5113. +            if(Unit *passenger = itr->second.passenger)                     // this cant be NULL, but..
  5114. +            {
  5115. +                passenger->ExitVehicle();
  5116. +                ((Vehicle*)passenger)->Dismiss();
  5117. +            }
  5118. +        }
  5119. +    }
  5120. +    // make sure everything is cleared
  5121. +    InitSeats();
  5122. +}
  5123. +
  5124. +bool Vehicle::HasSpell(uint32 spell) const
  5125. +{
  5126. +    if(!m_VehicleData)
  5127. +        return false;
  5128. +
  5129. +    for(uint8 j = 0; j < MAX_VEHICLE_SPELLS; j++)
  5130. +    {
  5131. +        if(m_VehicleData->v_spells[j] == spell)
  5132. +            return true;
  5133. +    }
  5134. +
  5135. +    return false;
  5136. +}
  5137. +
  5138. +void Vehicle::BuildVehicleActionBar(Player *plr) const
  5139. +{
  5140. +    WorldPacket data(SMSG_PET_SPELLS, 8+2+4+4+4*10+1+1);
  5141. +    data << uint64(GetGUID());
  5142. +    data << uint16(0x00000000);                     // creature family, not used in vehicles
  5143. +    data << uint32(0x00000000);                     // unk
  5144. +    data << uint32(0x00000101);                     // react state
  5145. +
  5146. +    for(uint32 i = 0; i <= MAX_VEHICLE_SPELLS; ++i)
  5147. +    {
  5148. +        data << uint16(m_VehicleData ? m_VehicleData->v_spells[i] : NULL) << uint8(0) << uint8(i+8);
  5149. +    }
  5150. +
  5151. +    data << uint8(0);                               //aditional spells in spellbook, not used in vehicles
  5152. +
  5153. +    uint8 cooldownsCount = m_CreatureSpellCooldowns.size() + m_CreatureCategoryCooldowns.size();
  5154. +    data << uint8(cooldownsCount);
  5155. +    time_t curTime = time(NULL);
  5156. +
  5157. +    for(CreatureSpellCooldowns::const_iterator itr = m_CreatureSpellCooldowns.begin(); itr != m_CreatureSpellCooldowns.end(); ++itr)
  5158. +    {
  5159. +        time_t cooldown = (itr->second > curTime) ? (itr->second - curTime) * IN_MILLISECONDS : 0;
  5160. +
  5161. +        data << uint32(itr->first);                         // spellid
  5162. +        data << uint16(0);                                  // spell category?
  5163. +        data << uint32(cooldown);                           // cooldown
  5164. +        data << uint32(0);                                  // category cooldown
  5165. +    }
  5166. +
  5167. +    for(CreatureSpellCooldowns::const_iterator itr = m_CreatureCategoryCooldowns.begin(); itr != m_CreatureCategoryCooldowns.end(); ++itr)
  5168. +    {
  5169. +        time_t cooldown = (itr->second > curTime) ? (itr->second - curTime) * IN_MILLISECONDS : 0;
  5170. +
  5171. +        data << uint32(itr->first);                         // spellid
  5172. +        data << uint16(0);                                  // spell category?
  5173. +        data << uint32(0);                                  // cooldown
  5174. +        data << uint32(cooldown);                           // category cooldown
  5175. +    }
  5176. +
  5177. +    plr->GetSession()->SendPacket(&data);
  5178. +
  5179. +    data.Initialize(SMSG_PET_GUIDS, 12);
  5180. +    data << uint32(1);                                        // count
  5181. +    data << uint64(GetGUID());
  5182. +    plr->GetSession()->SendPacket(&data);
  5183. +}
  5184. +
  5185. +void Vehicle::InstallAllAccessories()
  5186. +{
  5187. +    if(!GetMap())
  5188. +       return;
  5189. +
  5190. +    CreatureDataAddon const *cainfo = GetCreatureAddon();
  5191. +    if(!cainfo || !cainfo->passengers)
  5192. +        return;
  5193. +    for (CreatureDataAddonPassengers const* cPassanger = cainfo->passengers; cPassanger->seat_idx != -1; ++cPassanger)
  5194. +    {
  5195. +        // Continue if seat already taken
  5196. +        if(GetPassenger(cPassanger->seat_idx))
  5197. +            continue;
  5198. +
  5199. +        uint32 guid = 0;
  5200. +        bool isVehicle = false;
  5201. +        // Set guid and check whatever it is
  5202. +        if(cPassanger->guid != 0)
  5203. +            guid = cPassanger->guid;
  5204. +        else
  5205. +        {
  5206. +            CreatureDataAddon const* passAddon;
  5207. +            passAddon = ObjectMgr::GetCreatureTemplateAddon(cPassanger->entry);
  5208. +            if(passAddon && passAddon->vehicle_id != 0)
  5209. +                isVehicle = true;
  5210. +            else
  5211. +                guid = sObjectMgr.GenerateLowGuid(HIGHGUID_UNIT);
  5212. +        }
  5213. +        // Create it
  5214. +        Creature *pPassenger = new Creature;
  5215. +        if(!isVehicle)
  5216. +        {
  5217. +            uint32 entry = cPassanger->entry;
  5218. +            if(entry == 0)
  5219. +            {
  5220. +                CreatureData const* data = sObjectMgr.GetCreatureData(guid);
  5221. +                if(!data)
  5222. +                    continue;
  5223. +                entry = data->id;
  5224. +            }
  5225. +
  5226. +            if(!pPassenger->Create(guid, GetMap(), GetPhaseMask(), entry, 0))
  5227. +                continue;
  5228. +            pPassenger->LoadFromDB(guid, GetMap());
  5229. +            pPassenger->Relocate(GetPositionX(), GetPositionY(), GetPositionZ());
  5230. +            GetMap()->Add(pPassenger);
  5231. +            pPassenger->AIM_Initialize();
  5232. +        }
  5233. +        else
  5234. +            pPassenger = (Creature*)SummonVehicle(cPassanger->entry, GetPositionX(), GetPositionY(), GetPositionZ(), 0);
  5235. +        // Enter vehicle...
  5236. +        pPassenger->EnterVehicle(this, cPassanger->seat_idx, true);
  5237. +        // ...and send update. Without this, client wont show this new creature/vehicle...
  5238. +        pPassenger->SendHeartBeat(false);
  5239. +    }
  5240. +}
  5241. +
  5242. +Unit *Vehicle::GetPassenger(int8 seatId) const
  5243. +{
  5244. +    SeatMap::const_iterator seat = m_Seats.find(seatId);
  5245. +    if(seat == m_Seats.end()) return NULL;
  5246. +    return seat->second.passenger;
  5247. +}
  5248. +
  5249. +void Vehicle::Die()
  5250. +{
  5251. +    for (SeatMap::iterator itr = m_Seats.begin(); itr != m_Seats.end(); ++itr)
  5252. +        if(Unit *passenger = itr->second.passenger)
  5253. +            if(((Creature*)passenger)->IsVehicle())
  5254. +                ((Vehicle*)passenger)->Dismiss();
  5255. +    RemoveAllPassengers();
  5256. +}
  5257. +
  5258. +uint8 Vehicle::GetPassengerSeat(Unit *passenger) const
  5259. +{
  5260. +    if(passenger)
  5261. +        for(SeatMap::const_iterator itr = m_Seats.begin(); itr != m_Seats.end(); itr++)
  5262. +            if(itr->second.passenger == passenger)
  5263. +                return itr->first;
  5264. +    return -1;
  5265. +}
  5266. diff --git a/src/game/Vehicle.h b/src/game/Vehicle.h
  5267. index c191c09..e92c02d 100644
  5268. --- a/src/game/Vehicle.h
  5269. +++ b/src/game/Vehicle.h
  5270. @@ -23,6 +23,58 @@
  5271.  #include "ObjectGuid.h"
  5272.  #include "Creature.h"
  5273.  #include "Unit.h"
  5274. +#include "ObjectMgr.h"
  5275. +
  5276. +struct VehicleSeat
  5277. +{
  5278. +    VehicleSeat(VehicleSeatEntry const *pSeatInfo = NULL) : seatInfo(pSeatInfo), passenger(NULL) {}
  5279. +
  5280. +    VehicleSeatEntry const *seatInfo;
  5281. +    Unit* passenger;
  5282. +    uint8 flags;
  5283. +    uint32 vs_flags;
  5284. +};
  5285. +
  5286. +typedef std::map<int8, VehicleSeat> SeatMap;
  5287. +
  5288. +class VehicleKit
  5289. +{
  5290. +    public:
  5291. +
  5292. +    explicit VehicleKit(Unit* base, VehicleEntry const* vehicleInfo);
  5293. +    ~VehicleKit();
  5294. +
  5295. +    void Reset();
  5296. +
  5297. +    bool HasEmptySeat(int8 seatId) const;
  5298. +    Unit *GetPassenger(int8 seatId) const;
  5299. +    int8 GetNextEmptySeat(int8 seatId, bool next) const;
  5300. +    bool AddPassenger(Unit *passenger, int8 seatId = -1);
  5301. +    void RemovePassenger(Unit *passenger);
  5302. +    void RelocatePassengers(float x, float y, float z, float ang);
  5303. +    void RemoveAllPassengers();
  5304. +
  5305. +    uint32 GetVehicleId() const { return m_vehicleInfo->m_ID; }
  5306. +    VehicleEntry const* GetVehicleInfo() const { return m_vehicleInfo; }
  5307. +    Unit* GetBase() { return m_pBase; }
  5308. +
  5309. +    private:
  5310. +
  5311. +    SeatMap m_Seats;
  5312. +    uint32 m_uiNumFreeSeats;
  5313. +    VehicleEntry const *m_vehicleInfo;
  5314. +    Unit* m_pBase;
  5315. +};
  5316. +
  5317. +enum PowerType
  5318. +{
  5319. +    POWER_TYPE_PYRITE = 41,
  5320. +    POWER_TYPE_STEAM  = 61
  5321. +};
  5322. +
  5323. +#define MAX_SEAT 8
  5324. +
  5325. +typedef std::map<int8, VehicleSeat> SeatMap;
  5326.  
  5327.  class Vehicle : public Creature
  5328.  {
  5329. @@ -33,18 +85,60 @@ class Vehicle : public Creature
  5330.          void AddToWorld();
  5331.          void RemoveFromWorld();
  5332.  
  5333. -        bool Create (uint32 guidlow, Map *map, uint32 Entry, uint32 vehicleId, uint32 team);
  5334. +        void Die();
  5335. +        bool Create (uint32 guidlow, Map *map, uint32 phaseMask, uint32 Entry, uint32 vehicleId, uint32 team, const CreatureData *data = NULL);
  5336. +        void Respawn();
  5337.  
  5338.          void SetDeathState(DeathState s);                   // overwrite virtual Creature::SetDeathState and Unit::SetDeathState
  5339. +      
  5340. +        void RegeneratePower(Powers power);
  5341. +
  5342.          void Update(uint32 diff);                           // overwrite virtual Creature::Update and Unit::Update
  5343.  
  5344.          uint32 GetVehicleId() { return m_vehicleId; }
  5345. -        void SetVehicleId(uint32 vehicleid) { m_vehicleId = vehicleid; }
  5346. +        bool SetVehicleId(uint32 vehicleid);
  5347. +
  5348. +        void InitSeats();
  5349. +
  5350. +        void ChangeSeatFlag(uint8 seat, uint8 flag);
  5351. +        Vehicle* FindFreeSeat(int8 *seatid, bool force = true);
  5352. +        Vehicle* GetNextEmptySeat(int8 *seatId, bool next = true, bool force = true);
  5353. +        Vehicle* GetFirstEmptySeat(int8 *seatId, bool force = true);
  5354. +        int8 GetEmptySeatsCount(bool force = true);
  5355. +        void EmptySeatsCountChanged(void);
  5356. +        int8 GetTotalSeatsCount() { return m_Seats.size(); }
  5357. +        bool HasEmptySeat(int8 seatId) const;
  5358. +        int8 GetNextEmptySeatNum(int8 seatId, bool next) const;
  5359.  
  5360.          void Dismiss();
  5361.  
  5362. +        void RellocatePassengers(Map *map);
  5363. +        void AddPassenger(Unit *unit, int8 seatId, bool force = true);
  5364. +        void RemovePassenger(Unit *unit);
  5365. +        void RemoveAllPassengers();
  5366. +
  5367. +        bool HasSpell(uint32 spell) const;
  5368. +        void SetSpawnDuration(int32 duration)
  5369. +        {
  5370. +            duration < 1 ? despawn = false : despawn = true;
  5371. +            m_spawnduration = duration;
  5372. +        }
  5373. +        VehicleDataStructure const* GetVehicleData() { return m_VehicleData; }
  5374. +        uint32 GetVehicleFlags() { return m_VehicleData ? m_VehicleData->v_flags : NULL; }
  5375. +        uint32 GetCreationTime() { return m_creation_time; }
  5376. +        void BuildVehicleActionBar(Player *plr) const;
  5377. +        void InstallAllAccessories();
  5378. +        Unit *GetPassenger(int8 seatId) const;
  5379. +        uint8 GetPassengerSeat(Unit *passenger) const;
  5380. +
  5381.      protected:
  5382.          uint32 m_vehicleId;
  5383. +        VehicleEntry const *m_vehicleInfo;
  5384. +        VehicleDataStructure const *m_VehicleData;
  5385. +        uint32 m_creation_time;
  5386. +        SeatMap m_Seats;
  5387. +        bool despawn;
  5388. +        int32 m_spawnduration;
  5389.  
  5390.      private:
  5391.          void SaveToDB(uint32, uint8)                        // overwrited of Creature::SaveToDB     - don't must be called
  5392. diff --git a/src/game/World.cpp b/src/game/World.cpp
  5393. index 5a58d06..d98cb0c 100644
  5394. --- a/src/game/World.cpp
  5395. +++ b/src/game/World.cpp
  5396. @@ -1241,6 +1241,11 @@ void World::SetInitialWorldSettings()
  5397.      sLog.outString( "Loading Scripts text locales..." );    // must be after Load*Scripts calls
  5398.      sObjectMgr.LoadDbScriptStrings();
  5399.  
  5400. +    sLog.outString( "Loading VehicleData..." );
  5401. +    sObjectMgr.LoadVehicleData();
  5402. +    sLog.outString( "Loading VehicleSeatData..." );
  5403. +    sObjectMgr.LoadVehicleSeatData();
  5404. +
  5405.      sLog.outString( "Loading CreatureEventAI Texts...");
  5406.      sEventAIMgr.LoadCreatureEventAI_Texts(false);       // false, will checked in LoadCreatureEventAI_Scripts
  5407.  
  5408. diff --git a/src/game/WorldSession.h b/src/game/WorldSession.h
  5409. index e6d6825..17b4f8b 100644
  5410. --- a/src/game/WorldSession.h
  5411. +++ b/src/game/WorldSession.h
  5412. @@ -430,6 +430,13 @@ class MANGOS_DLL_SPEC WorldSession
  5413.          void HandleSetActiveMoverOpcode(WorldPacket &recv_data);
  5414.          void HandleMoveNotActiveMoverOpcode(WorldPacket &recv_data);
  5415.          void HandleDismissControlledVehicle(WorldPacket &recv_data);
  5416. +        void HandleRequestVehicleExit(WorldPacket &recv_data);
  5417. +        void HandleRequestVehiclePrevSeat(WorldPacket &recv_data);
  5418. +        void HandleRequestVehicleNextSeat(WorldPacket &recv_data);
  5419. +        void HandleRequestVehicleSwitchSeat(WorldPacket &recv_data);
  5420. +        void HandleChangeSeatsOnControlledVehicle(WorldPacket &recv_data);
  5421. +        void HandleEnterPlayerVehicle(WorldPacket &recv_data);
  5422. +        void HandleEjectPasenger(WorldPacket &recv_data);
  5423.          void HandleMoveTimeSkippedOpcode(WorldPacket &recv_data);
  5424.  
  5425.          void HandleRequestRaidInfoOpcode( WorldPacket & recv_data );
  5426. diff --git a/src/game/debugcmds.cpp b/src/game/debugcmds.cpp
  5427. index 6d80714..b9e69db 100644
  5428. --- a/src/game/debugcmds.cpp
  5429. +++ b/src/game/debugcmds.cpp
  5430. @@ -614,7 +614,8 @@ bool ChatHandler::HandleDebugSpawnVehicleCommand(char* args)
  5431.  
  5432.      Vehicle *v = new Vehicle;
  5433.      Map *map = m_session->GetPlayer()->GetMap();
  5434. -    if (!v->Create(map->GenerateLocalLowGuid(HIGHGUID_VEHICLE), map, entry, id, m_session->GetPlayer()->GetTeam()))
  5435. +
  5436. +    if (!v->Create(sObjectMgr.GenerateLowGuid(HIGHGUID_VEHICLE), map, m_session->GetPlayer()->GetPhaseMaskForSpawn(), entry, id, m_session->GetPlayer()->GetTeam()))
  5437.      {
  5438.          delete v;
  5439.          return false;
  5440. @@ -634,6 +635,7 @@ bool ChatHandler::HandleDebugSpawnVehicleCommand(char* args)
  5441.      }
  5442.  
  5443.      map->Add((Creature*)v);
  5444. +    v->AIM_Initialize();
  5445.  
  5446.      return true;
  5447.  }
  5448. diff --git a/src/shared/Database/SQLStorage.cpp b/src/shared/Database/SQLStorage.cpp
  5449. index a797cb5..5c8cde4 100644
  5450. --- a/src/shared/Database/SQLStorage.cpp
  5451. +++ b/src/shared/Database/SQLStorage.cpp
  5452. @@ -25,11 +25,11 @@ extern DatabasePostgre  WorldDatabase;
  5453.  extern DatabaseMysql  WorldDatabase;
  5454.  #endif
  5455.  
  5456. -const char CreatureInfosrcfmt[]="iiiiiiiiiisssiiiiiiiiiiifffiffiifiiiiiiiiiiffiiiiiiiiiiiiiiiiiiisiiffliiiiiiiliiiis";
  5457. -const char CreatureInfodstfmt[]="iiiiiiiiiisssiiiiiiiiiiifffiffiifiiiiiiiiiiffiiiiiiiiiiiiiiiiiiisiiffliiiiiiiliiiii";
  5458. -const char CreatureDataAddonInfofmt[]="iiiiiis";
  5459. +const char CreatureInfosrcfmt[]="iiiiiiiiiisssiiiiiiiiiiifffiffiifiiiiiiiiiiffiiiiiiiiiiiiiiiiiiiisiiffliiiiiiiliiiis";
  5460. +const char CreatureInfodstfmt[]="iiiiiiiiiisssiiiiiiiiiiifffiffiifiiiiiiiiiiffiiiiiiiiiiiiiiiiiiiisiiffliiiiiiiliiiii";
  5461. +const char CreatureDataAddonInfofmt[]="iiiiiiiss";
  5462.  const char CreatureModelfmt[]="iffbii";
  5463. -const char CreatureInfoAddonInfofmt[]="iiiiiis";
  5464. +const char CreatureInfoAddonInfofmt[]="iiiiiiiss";
  5465.  const char EquipmentInfofmt[]="iiii";
  5466.  const char GameObjectInfosrcfmt[]="iiissssiifiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiis";
  5467.  const char GameObjectInfodstfmt[]="iiissssiifiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii";
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement