diff --git a/sql/v01_vehicle_data.sql b/sql/v01_vehicle_data.sql
new file mode 100644
index 0000000..74dc665
--- /dev/null
+++ b/sql/v01_vehicle_data.sql
@@ -0,0 +1,21 @@
+--
+-- Table structure for table `vehicle_data`
+--
+
+DROP TABLE IF EXISTS `vehicle_data`;
+CREATE TABLE `vehicle_data` (
+  `entry` mediumint(5) unsigned NOT NULL,
+  `flags` mediumint(8) unsigned NOT NULL default '0',
+  `Spell1` mediumint(8) unsigned NOT NULL default '0',
+  `Spell2` mediumint(8) unsigned NOT NULL default '0',
+  `Spell3` mediumint(8) unsigned NOT NULL default '0',
+  `Spell4` mediumint(8) unsigned NOT NULL default '0',
+  `Spell5` mediumint(8) unsigned NOT NULL default '0',
+  `Spell6` mediumint(8) unsigned NOT NULL default '0',
+  `Spell7` mediumint(8) unsigned NOT NULL default '0',
+  `Spell8` mediumint(8) unsigned NOT NULL default '0',
+  `Spell9` mediumint(8) unsigned NOT NULL default '0',
+  `Spell10` mediumint(8) unsigned NOT NULL default '0',
+  `req_aura` mediumint(8) unsigned NOT NULL default '0',
+  PRIMARY KEY  (`entry`)
+) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Vehicle System';
\ No newline at end of file
diff --git a/sql/v02_vehicle_seat_data.sql b/sql/v02_vehicle_seat_data.sql
new file mode 100644
index 0000000..5c3a390
--- /dev/null
+++ b/sql/v02_vehicle_seat_data.sql
@@ -0,0 +1,10 @@
+--
+-- Table structure for table `vehicle_seat_data`
+--
+
+DROP TABLE IF EXISTS `vehicle_seat_data`;
+CREATE TABLE `vehicle_seat_data` (
+  `seat` mediumint(5) unsigned NOT NULL,
+  `flags` mediumint(8) unsigned NOT NULL default '0',
+  PRIMARY KEY  (`seat`)
+) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Vehicle Seat System';
\ No newline at end of file
diff --git a/sql/v03_creature_addon_tables.sql b/sql/v03_creature_addon_tables.sql
new file mode 100644
index 0000000..7240ed4
--- /dev/null
+++ b/sql/v03_creature_addon_tables.sql
@@ -0,0 +1,7 @@
+ALTER TABLE creature_addon
+  ADD COLUMN    vehicle_id           smallint(5) unsigned NOT NULL default '0' AFTER moveflags,
+  ADD COLUMN    passengers           text AFTER vehicle_id;
+
+ALTER TABLE creature_template_addon
+  ADD COLUMN    vehicle_id           smallint(5) unsigned NOT NULL default '0' AFTER moveflags,
+  ADD COLUMN    passengers           text AFTER vehicle_id;
\ No newline at end of file
diff --git a/sql/v10_vehicle_test_data.sql b/sql/v10_vehicle_test_data.sql
new file mode 100644
index 0000000..e3fee71
--- /dev/null
+++ b/sql/v10_vehicle_test_data.sql
@@ -0,0 +1,485 @@
+INSERT INTO `vehicle_data` VALUES
+('106', '4', '50896', '0', '50652', '0', '0', '0', '0', '0', '0', '0', '0'),
+('116', '5', '51362', '51421', '0', '0', '0', '0', '0', '0', '0', '0', '0'),
+('117', '4', '50652', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0'),
+('156', '24', '53114', '0', '53110', '0', '0', '0', '0', '0', '0', '0', '0'),
+('200', '30', '52362', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0'),
+('210', '166', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0'),
+('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'),
+('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'),
+('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'),
+('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'),
+('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'),
+('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'),
+('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'),
+('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'),
+('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'),
+('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'),
+('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'),
+('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'),
+('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'),
+('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'),
+('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'),
+('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'),
+('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'),
+('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'),
+('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'),
+('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'),
+('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'),
+('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'),
+('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'),
+('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'),
+('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'),
+('105', '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'),
+('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'),
+('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'),
+('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'),
+('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'),
+('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'),
+('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'),
+('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'),
+('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'),
+('134', '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'),
+('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'),
+('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'),
+('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'),
+('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'),
+('154', '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'),
+('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'),
+('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'),
+('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'),
+('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'),
+('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'),
+('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'),
+('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'),
+('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'),
+('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'),
+('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'),
+('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'),
+('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'),
+('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'),
+('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'),
+('209', '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'),
+('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'),
+('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'),
+('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'),
+('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'),
+('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'),
+('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'),
+('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'),
+('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'),
+('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'),
+('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'),
+('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'),
+('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'),
+('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'),
+('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'),
+('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'),
+('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'),
+('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'),
+('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'),
+('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'),
+('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'),
+('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'),
+('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'),
+('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'),
+('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'),
+('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'),
+('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'),
+('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'),
+('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'),
+('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'),
+('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'),
+('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'),
+('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'),
+('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'),
+('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'),
+('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'),
+('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'),
+('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'),
+('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'),
+('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'),
+('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'),
+('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'),
+('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'),
+('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'),
+('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'),
+('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'),
+('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'),
+('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'),
+('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'),
+('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'),
+('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'),
+('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'),
+('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'),
+('135', '12', '52362', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0'),
+('349', '24', '62544', '62575', '62960', '62552', '64077', '62863', '0', '0', '0', '0', '62853'),
+('68', '24', '52435', '52576', '52588', '0', '0', '0', '0', '0', '0', '0', '0');
+
+UPDATE creature_template SET maxhealth = 133525, minhealth = 133525, maxmana = 51360, minmana = 51360 WHERE entry = 28670;
+UPDATE creature_template SET maxhealth = 50000, minhealth = 50000 WHERE entry = 28094;
+UPDATE creature_template SET maxhealth = 75000, minhealth = 75000 WHERE entry IN (28312,32627);
+UPDATE creature_template SET maxhealth = 50000, minhealth = 50000 WHERE entry IN (28319,32629);
+
+UPDATE creature_template SET minlevel = 80, maxlevel = 80 WHERE entry IN (28312,32627,28319,32629,28094,28670);
+
+UPDATE creature_template SET speed = 2, InhabitType = 1 WHERE entry IN (28312,32627,28319,32629,28094,29929,28782);
+UPDATE creature_template SET speed = 2.4, InhabitType = 4 WHERE entry IN (28670);
+UPDATE creature_template SET mechanic_immune_mask = 652951551 WHERE entry IN (28670,28312,32627,28319,32629,28094,29929,28782);
+
+DELETE FROM npc_spellclick_spells WHERE npc_entry in (28670, 28312, 32629, 28319, 32627, 28094, 29929, 28782);
+INSERT INTO npc_spellclick_spells VALUES
+(28670, 52196, 0, 0, 0, 0),
+(28312, 60968, 0, 0, 0, 1),
+(32627, 60968, 0, 0, 0, 1),
+(28319, 60968, 0, 0, 0, 1),
+(32629, 60968, 0, 0, 0, 1),
+(28094, 60968, 0, 0, 0, 1),
+(29929, 58961, 0, 0, 0, 1),
+(28782, 52280, 12687, 1, 12687, 1);
+
+DELETE FROM creature_template_addon WHERE entry in (28670, 28312, 32629, 28319, 32627, 28094, 29929, 28782);
+INSERT INTO creature_template_addon VALUES
+(28670, 0, 50331648, 1, 0, 1024, 156, NULL, '53112 0 53112 1'),
+(28312, 0, 0, 0, 0, 0, 117, '28319 7', NULL),
+(32627, 0, 0, 0, 0, 0, 117, '32629 7', NULL),
+(28319, 0, 0, 0, 0, 0, 116, NULL, NULL),
+(32629, 0, 0, 0, 0, 0, 116, NULL, NULL),
+(28094, 0, 0, 0, 0, 0, 106, NULL, NULL),
+(29929, 0, 0, 0, 0, 0, 210, NULL, NULL),
+(28782, 0, 0, 0, 0, 0, 200, NULL, NULL);
+
+DELETE FROM vehicle_data WHERE entry in (106, 116, 117, 156, 200, 210);
+INSERT INTO vehicle_data VALUES (106, 4, 50896, 0, 50652, 0, 0, 0, 0, 0, 0, 0, 0),
+(116, 5, 51362, 51421, 0, 0, 0, 0, 0, 0, 0, 0, 0),
+(117, 4, 50652, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
+(156, 24, 53114, 0, 53110, 0, 0, 0, 0, 0, 0, 0, 0),
+(200, 30, 52362, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
+(210, 166, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+
+DELETE FROM vehicle_seat_data WHERE seat in (1643, 1648, 1649, 1650, 1652, 1554, 1556, 1557, 1986, 1987, 2144, 2181, 2182);
+INSERT INTO vehicle_seat_data VALUES
+(1643, 3),
+(1648, 3),
+(1649, 2),
+(1650, 2),
+(1652, 4),
+(1554, 3),
+(1556, 6),
+(1557, 6),
+(1986, 3),
+(1987, 8),
+(2144, 1),
+(2181, 1),
+(2182, 0);
+
+/* Some quests
+Argent tournament*/
+UPDATE creature_template SET speed = '1.5', unit_flags = 8 WHERE entry IN (33844,33845);
+DELETE FROM creature_addon WHERE guid IN (SELECT guid FROM creature WHERE id IN (33844,33845));
+DELETE FROM creature WHERE id IN (33844,33845);
+DELETE FROM vehicle_data WHERE entry in (349);
+INSERT INTO `vehicle_data` VALUES ('349', '24', '62544', '62575', '62960', '62552', '64077', '62863', '0', '0', '0', '0', '62853');
+DELETE FROM vehicle_seat_data WHERE seat in (3129);
+INSERT INTO `vehicle_seat_data` VALUES ('3129', '1');
+INSERT INTO `npc_spellclick_spells` VALUES ('33842', '63791', '13829', '1', '0', '3');
+INSERT INTO `npc_spellclick_spells` VALUES ('33842', '63791', '13839', '1', '0', '3');
+INSERT INTO `npc_spellclick_spells` VALUES ('33842', '63791', '13838', '1', '0', '3');
+INSERT INTO `npc_spellclick_spells` VALUES ('33843', '63792', '13828', '1', '0', '3');
+INSERT INTO `npc_spellclick_spells` VALUES ('33843', '63792', '13837', '1', '0', '3');
+INSERT INTO `npc_spellclick_spells` VALUES ('33843', '63792', '13835', '1', '0', '3');
+DELETE FROM creature_template_addon WHERE entry IN (33844,33845);
+INSERT INTO creature_template_addon (`entry`, `mount`, `bytes1`, `bytes2`, `emote`, `moveflags`, `vehicle_id`, `passengers`, `auras`) VALUES (33844, 0, 0, 2049, 0, 0, 349, '', '');
+INSERT INTO creature_template_addon (`entry`, `mount`, `bytes1`, `bytes2`, `emote`, `moveflags`, `vehicle_id`, `passengers`, `auras`) VALUES (33845, 0, 0, 2049, 0, 0, 349, '', '');
+
+/*Quest Into the Realm of Shadows (12687)*/
+UPDATE creature_template SET faction_A = 2082, faction_H = 2082, unit_flags = 0 WHERE entry = 28782;
+DELETE FROM creature_addon WHERE guid IN (SELECT guid FROM creature WHERE id = 28782);
+DELETE FROM vehicle_data WHERE entry in (135);
+INSERT INTO vehicle_data VALUES (135, 12, 52362, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+DELETE FROM vehicle_seat_data WHERE seat in (1871);
+INSERT INTO vehicle_seat_data VALUES (1871, 1);
+DELETE FROM npc_spellclick_spells WHERE npc_entry in (28782);
+INSERT INTO npc_spellclick_spells VALUES (28782, 52349, 12687, 1, 12687, 3);
+DELETE FROM creature_template_addon WHERE entry IN (28782);
+INSERT INTO creature_template_addon (`entry`, `mount`, `bytes1`, `bytes2`, `emote`, `moveflags`, `vehicle_id`, `passengers`, `auras`) VALUES (28782, 0, 0, 1, 0, 0, 135, '', '');
+
+/*Quest Grand Theft Palomino (12680)*/
+DELETE FROM creature_addon WHERE guid IN (SELECT guid FROM creature WHERE id IN (28605,28606,28607));
+REPLACE INTO spell_script_target VALUES (52264,1,28653);
+DELETE FROM vehicle_data WHERE entry in (123);
+INSERT INTO vehicle_data VALUES (123, 12, 52264, 52268, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+DELETE FROM vehicle_seat_data WHERE seat in (1782);
+INSERT INTO vehicle_seat_data VALUES (1782, 1);
+DELETE FROM npc_spellclick_spells WHERE npc_entry in (28605,28606,28607);
+INSERT INTO npc_spellclick_spells VALUES (28605, 52263, 12680, 1, 12680, 3);
+INSERT INTO npc_spellclick_spells VALUES (28606, 52263, 12680, 1, 12680, 3);
+INSERT INTO npc_spellclick_spells VALUES (28607, 52263, 12680, 1, 12680, 3);
+DELETE FROM creature_template_addon WHERE entry IN (28605,28606,28607);
+INSERT INTO creature_template_addon (`entry`, `mount`, `bytes1`, `bytes2`, `emote`, `moveflags`, `vehicle_id`, `passengers`, `auras`) VALUES (28605, 0, 0, 1, 0, 0, 123, '', '');
+INSERT INTO creature_template_addon (`entry`, `mount`, `bytes1`, `bytes2`, `emote`, `moveflags`, `vehicle_id`, `passengers`, `auras`) VALUES (28606, 0, 0, 1, 0, 0, 123, '', '');
+INSERT INTO creature_template_addon (`entry`, `mount`, `bytes1`, `bytes2`, `emote`, `moveflags`, `vehicle_id`, `passengers`, `auras`) VALUES (28607, 0, 0, 1, 0, 0, 123, '', '');
+
+/*Quest Going Bearback*/
+DELETE FROM npc_spellclick_spells WHERE npc_entry in (29598);
+INSERT INTO npc_spellclick_spells VALUES (29598, 54908, 12851, 1, 12851, 1);
+DELETE FROM creature_template_addon WHERE entry IN (29598);
+INSERT INTO creature_template_addon (`entry`, `mount`, `bytes1`, `bytes2`, `emote`, `moveflags`, `vehicle_id`, `passengers`, `auras`) VALUES (29598, 0, 0, 1, 0, 0, 308, '', '');
+DELETE FROM vehicle_data WHERE entry in (308);
+INSERT INTO `vehicle_data` VALUES ('308', '24', '54897', '54907', '0', '0', '0', '0', '0', '0', '0', '0', '0');
+REPLACE INTO vehicle_seat_data VALUES (2699, 3);
+
+/*Mamonth*/
+DELETE FROM creature_template_addon WHERE entry in (32633,32640);
+INSERT INTO creature_template_addon (`entry`, `mount`, `bytes1`, `bytes2`, `emote`, `moveflags`, `vehicle_id`, `passengers`, `auras`) VALUES (32633, 0, 0, 1, 0, 0, 312, '', '');
+INSERT INTO creature_template_addon (`entry`, `mount`, `bytes1`, `bytes2`, `emote`, `moveflags`, `vehicle_id`, `passengers`, `auras`) VALUES (32640, 0, 0, 1, 0, 0, 312, '', '');
+DELETE FROM vehicle_data WHERE entry in (312);
+
+/*Massacre At Light's Point*/
+UPDATE `creature_template` SET `minhealth` = 26140, `maxhealth` = 26140, `dynamicflags` = 0, `minmana` = 2117, `maxmana` = 2117, `unit_flags` = 772, `minlevel` = 55, `maxlevel` = 55, `unk16` = 10, `unk17` = 1, `InhabitType` = 3, `scale` = 1, `mindmg` = 685, `maxdmg` = 715, `armor` = 3232, `attackpower` = 214, `unit_class` = 2, `type` = 10  WHERE `entry` = 28833;
+UPDATE `creature_template` SET `minhealth` = 26140, `maxhealth` = 26140, `dynamicflags` = 0, `minmana` = 0, `maxmana` = 0, `unit_flags` = 772, `minlevel` = 55, `maxlevel` = 55, `unk16` = 10, `unk17` = 1, `InhabitType` = 3, `scale` = 1, `mindmg` = 685, `maxdmg` = 715, `armor` = 3232, `attackpower` = 214, `unit_class` = 2, `type` = 10  WHERE `entry` = 28887;
+
+DELETE FROM creature_addon WHERE guid IN (SELECT guid FROM creature WHERE id IN (28887,28833));
+DELETE FROM vehicle_data WHERE entry in (68);
+INSERT INTO `vehicle_data` VALUES ('68', '24', '52435', '52576', '52588', '0', '0', '0', '0', '0', '0', '0', '0');
+DELETE FROM vehicle_seat_data WHERE seat in (1301);
+INSERT INTO `vehicle_seat_data` VALUES ('1301', '3');
+INSERT INTO `npc_spellclick_spells` VALUES ('28833', '52447', '12701', '1', '12701', '1');
+INSERT INTO `npc_spellclick_spells` VALUES ('28887', '52447', '12701', '1', '12701', '1');
+
+DELETE FROM creature_template_addon WHERE entry IN (28887,28833);
+INSERT INTO creature_template_addon (`entry`, `mount`, `bytes1`, `bytes2`, `emote`, `moveflags`, `vehicle_id`, `passengers`, `auras`) VALUES (28887, 0, 0, 2049, 0, 0, 68, '', '');
+INSERT INTO creature_template_addon (`entry`, `mount`, `bytes1`, `bytes2`, `emote`, `moveflags`, `vehicle_id`, `passengers`, `auras`) VALUES (28833, 0, 0, 2049, 0, 0, 68, '', '');
+
+
+
+/*Traveler's Tundra Mammoth */
+REPLACE INTO npc_spellclick_spells VALUES (32633, 52196, 0, 0, 0, 0);
+REPLACE INTO creature_template_addon VALUES (32633, 0, 0, 0, 0, 0, 312, NULL, NULL); 
+REPLACE INTO vehicle_data VALUES (312, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+
+/* Grand Ice Mammoth */
+REPLACE INTO npc_spellclick_spells VALUES (31857, 52196, 0, 0, 0, 0);
+REPLACE INTO creature_template_addon VALUES (31857, 0, 0, 0, 0, 0, 312, NULL, NULL);
+
+/* Salvaged Chopper */
+REPLACE INTO npc_spellclick_spells VALUES (33062, 52196, 0, 0, 0, 0);
+REPLACE INTO creature_template_addon VALUES (33062, 0, 0, 0, 0, 0, 335, NULL, NULL); 
+REPLACE INTO vehicle_data VALUES (335, 12, 62974, 62286, 62299, 64660, 0, 0, 0, 0, 0, 0, 0); 
+REPLACE INTO vehicle_seat_data VALUES (3005, 1);
+ 
+/* Salvaged Demolisher */
+REPLACE INTO npc_spellclick_spells VALUES (33109, 52196, 0, 0, 0, 0);
+REPLACE INTO creature_template_addon VALUES (33109, 0, 0, 0, 0, 0, 338, NULL, NULL); 
+REPLACE INTO vehicle_data VALUES (338, 12, 62306, 62490, 62308, 62324, 0, 0, 0, 0, 0, 0, 0);
+REPLACE INTO vehicle_seat_data VALUES (3011, 1);
+ 
+/* Salvaged Siege Engine */
+REPLACE INTO npc_spellclick_spells VALUES (33060, 52196, 0, 0, 0, 0); 
+REPLACE INTO creature_template_addon VALUES (33060, 0, 0, 0, 0, 0, 336, NULL, NULL); 
+REPLACE INTO vehicle_data VALUES (336, 12, 62345, 62522, 62346, 0, 0, 0, 0, 0, 0, 0, 0);
+REPLACE INTO vehicle_seat_data VALUES (3006, 1);
\ No newline at end of file
diff --git a/src/game/AggressorAI.cpp b/src/game/AggressorAI.cpp
index 4ab9a7a..9509b1c 100644
--- a/src/game/AggressorAI.cpp
+++ b/src/game/AggressorAI.cpp
@@ -104,7 +104,7 @@ void AggressorAI::EnterEvadeMode()
         //i_tracker.Reset(TIME_INTERVAL_LOOK);
     }
 
-    if (!m_creature->isCharmed())
+    if(!m_creature->isCharmed() && !m_creature->GetVehicleGUID())
     {
         m_creature->RemoveAllAuras();
 
diff --git a/src/game/BattleGroundMgr.cpp b/src/game/BattleGroundMgr.cpp
index b1cd408..cf2870d 100644
--- a/src/game/BattleGroundMgr.cpp
+++ b/src/game/BattleGroundMgr.cpp
@@ -1379,11 +1379,15 @@ void BattleGroundMgr::BuildPvpLogDataPacket(WorldPacket *data, BattleGround *bg)
                 *data << (uint32)0x00000001;                // count of next fields
                 *data << (uint32)((BattleGroundEYScore*)itr->second)->FlagCaptures;         // flag captures
                 break;
+            case BATTLEGROUND_SA:
+                *data << (uint32)0x00000002;                // count of next fields
+                *data << (uint32)((BattleGroundSAScore*)itr->second)->DemolishersDestroyed; // demolishers destroyed
+                *data << (uint32)((BattleGroundSAScore*)itr->second)->GatesDestroyed;       // gates destroyed
+                break;
             case BATTLEGROUND_NA:
             case BATTLEGROUND_BE:
             case BATTLEGROUND_AA:
             case BATTLEGROUND_RL:
-            case BATTLEGROUND_SA:                           // wotlk
             case BATTLEGROUND_DS:                           // wotlk
             case BATTLEGROUND_RV:                           // wotlk
             case BATTLEGROUND_IC:                           // wotlk
diff --git a/src/game/BattleGroundSA.h b/src/game/BattleGroundSA.h
index 31a3ffa..9324999 100644
--- a/src/game/BattleGroundSA.h
+++ b/src/game/BattleGroundSA.h
@@ -24,8 +24,10 @@ class BattleGround;
 class BattleGroundSAScore : public BattleGroundScore
 {
     public:
-        BattleGroundSAScore() {};
+        BattleGroundSAScore(): DemolishersDestroyed(0), GatesDestroyed(0) {};
         virtual ~BattleGroundSAScore() {};
+        uint32 DemolishersDestroyed;
+        uint32 GatesDestroyed;
 };
 
 class BattleGroundSA : public BattleGround
diff --git a/src/game/Chat.cpp b/src/game/Chat.cpp
index 4f629c4..d63ca95 100644
--- a/src/game/Chat.cpp
+++ b/src/game/Chat.cpp
@@ -474,6 +474,8 @@ ChatCommand * ChatHandler::getCommandTable()
         { "spell_scripts",               SEC_ADMINISTRATOR, true,  &ChatHandler::HandleReloadSpellScriptsCommand,            "", NULL },
         { "spell_target_position",       SEC_ADMINISTRATOR, true,  &ChatHandler::HandleReloadSpellTargetPositionCommand,     "", NULL },
         { "spell_threats",               SEC_ADMINISTRATOR, true,  &ChatHandler::HandleReloadSpellThreatsCommand,            "", NULL },
+        { "vehicle_data",                SEC_ADMINISTRATOR, true,  &ChatHandler::HandleReloadVehicleDataCommand,             "", NULL },
+        { "vehicle_seat_data",           SEC_ADMINISTRATOR, true,  &ChatHandler::HandleReloadVehicleSeatDataCommand,         "", NULL },
 
         { NULL,                          0,                 false, NULL,                                                     "", NULL }
     };
@@ -1815,7 +1817,7 @@ Creature* ChatHandler::getSelectedCreature()
     if(!m_session)
         return NULL;
 
-    return m_session->GetPlayer()->GetMap()->GetCreatureOrPetOrVehicle(m_session->GetPlayer()->GetSelection());
+    return ObjectAccessor::GetCreatureOrPetOrVehicle(*m_session->GetPlayer(),m_session->GetPlayer()->GetSelection());
 }
 
 char* ChatHandler::extractKeyFromLink(char* text, char const* linkType, char** something1)
diff --git a/src/game/Chat.h b/src/game/Chat.h
index da0563e..e7ba487 100644
--- a/src/game/Chat.h
+++ b/src/game/Chat.h
@@ -396,6 +396,8 @@ class ChatHandler
         bool HandleReloadSpellTargetPositionCommand(const char* args);
         bool HandleReloadSpellThreatsCommand(const char* args);
         bool HandleReloadSpellPetAurasCommand(const char* args);
+        bool HandleReloadVehicleDataCommand(const char* args);
+        bool HandleReloadVehicleSeatDataCommand(const char* args);
 
         bool HandleResetAchievementsCommand(const char * args);
         bool HandleResetAllCommand(const char * args);
diff --git a/src/game/Creature.cpp b/src/game/Creature.cpp
index 3c09df9..cf92936 100644
--- a/src/game/Creature.cpp
+++ b/src/game/Creature.cpp
@@ -43,6 +43,7 @@
 #include "GridNotifiers.h"
 #include "GridNotifiersImpl.h"
 #include "CellImpl.h"
+#include "Vehicle.h"
 
 // apply implementation of the singletons
 #include "Policies/SingletonImp.h"
@@ -263,9 +264,10 @@ bool Creature::InitEntry(uint32 Entry, uint32 team, const CreatureData *data )
 
     SetFloatValue(UNIT_MOD_CAST_SPEED, 1.0f);
 
-    SetSpeedRate(MOVE_WALK, cinfo->speed);
-    SetSpeedRate(MOVE_RUN,  cinfo->speed);
-    SetSpeedRate(MOVE_SWIM, cinfo->speed);
+    SetSpeedRate(MOVE_WALK, cinfo->speed );
+    SetSpeedRate(MOVE_RUN,  cinfo->speed );
+    SetSpeedRate(MOVE_SWIM, cinfo->speed );
+    SetSpeedRate(MOVE_FLIGHT, cinfo->speed );
 
     SetFloatValue(OBJECT_FIELD_SCALE_X, cinfo->scale);
 
@@ -1060,7 +1062,7 @@ bool Creature::CreateFromProto(uint32 guidlow, uint32 Entry, uint32 team, const
     }
     m_originalEntry = Entry;
 
-    Object::_Create(guidlow, Entry, HIGHGUID_UNIT);
+   Object::_Create(guidlow, Entry, HIGHGUID_UNIT);
 
     if (!UpdateEntry(Entry, team, data, false))
         return false;
@@ -1286,6 +1288,8 @@ void Creature::setDeathState(DeathState s)
         }
 
         Unit::setDeathState(CORPSE);
+        if(isVehicle())
+            ((Vehicle*)this)->Die();
     }
     if (s == JUST_ALIVED)
     {
@@ -1389,6 +1393,32 @@ bool Creature::IsImmunedToSpellEffect(SpellEntry const* spellInfo, SpellEffectIn
             return true;
     }
 
+    // Heal immunity
+    if (isVehicle() && !(((Vehicle*)this)->GetVehicleFlags() & VF_CAN_BE_HEALED))
+    {
+        switch(spellInfo->Effect[index])
+        {
+            case SPELL_EFFECT_APPLY_AURA:
+                switch(spellInfo->EffectApplyAuraName[index])
+                {
+                    case SPELL_AURA_PERIODIC_HEAL:
+                    case SPELL_AURA_OBS_MOD_HEALTH:
+                    case SPELL_AURA_PERIODIC_HEALTH_FUNNEL:
+                    case SPELL_AURA_MOD_REGEN:
+                        return true;
+                    default: break;
+                }
+                break;
+            case SPELL_EFFECT_HEAL:
+            case SPELL_EFFECT_HEAL_MAX_HEALTH:
+            // NOTE : this too?
+            case SPELL_EFFECT_HEAL_MECHANICAL:
+            case SPELL_EFFECT_HEAL_PCT:
+                return true;
+            default : break;
+        }
+    }
+
     return Unit::IsImmunedToSpellEffect(spellInfo, index);
 }
 
@@ -1857,6 +1887,29 @@ bool Creature::IsInEvadeMode() const
     return !i_motionMaster.empty() && i_motionMaster.GetCurrentMovementGeneratorType() == HOME_MOTION_TYPE;
 }
 
+float Creature::GetBaseSpeed() const
+{
+    if( isPet() )
+    {
+        switch( ((Pet*)this)->getPetType() )
+        {
+            case SUMMON_PET:
+            case HUNTER_PET:
+            {
+                //fixed speed fur hunter (and summon!?) pets
+                return 1.15;
+            }
+            case GUARDIAN_PET:
+            case MINI_PET:
+            {
+                //speed of CreatureInfo for guardian- and minipets
+                break;
+            }
+        }
+    }
+    return m_creatureInfo->speed;
+}
+
 bool Creature::HasSpell(uint32 spellID) const
 {
     uint8 i;
diff --git a/src/game/Creature.h b/src/game/Creature.h
index dfbcb77..9bb7940 100644
--- a/src/game/Creature.h
+++ b/src/game/Creature.h
@@ -210,6 +210,15 @@ struct CreatureDataAddonAura
     SpellEffectIndex effect_idx;
 };
 
+struct CreatureDataAddonPassengers
+{
+    CreatureDataAddonPassengers() : entry(0), guid(0), seat_idx(-1) {}
+
+    uint32 entry;
+    uint32 guid;
+    int8 seat_idx;
+};
+
 // from `creature_addon` table
 struct CreatureDataAddon
 {
@@ -218,7 +227,9 @@ struct CreatureDataAddon
     uint32 bytes1;
     uint32 bytes2;
     uint32 emote;
-    uint32 splineFlags;
+	uint32 splineFlags;
+    uint32 vehicle_id;
+    CreatureDataAddonPassengers const* passengers;          // loaded as char* "entry1 seatid1 entry2 seatid2 ... "  
     CreatureDataAddonAura const* auras;                     // loaded as char* "spell1 eff1 spell2 eff2 ... "
 };
 
@@ -395,6 +406,9 @@ class MANGOS_DLL_SPEC Creature : public Unit
         void GetRespawnCoord(float &x, float &y, float &z, float* ori = NULL, float* dist =NULL) const;
         uint32 GetEquipmentId() const { return m_equipmentId; }
 
+        bool CreateVehicleKit(uint32 id);
+        Vehicle *GetVehicleKit()const { return m_vehicleKit; }
+
         CreatureSubtype GetSubtype() const { return m_subtype; }
         bool isPet() const { return m_subtype == CREATURE_SUBTYPE_PET; }
         bool isVehicle() const { return m_subtype == CREATURE_SUBTYPE_VEHICLE; }
@@ -558,6 +572,7 @@ class MANGOS_DLL_SPEC Creature : public Unit
 
         MovementGeneratorType GetDefaultMovementType() const { return m_defaultMovementType; }
         void SetDefaultMovementType(MovementGeneratorType mgt) { m_defaultMovementType = mgt; }
+        float GetBaseSpeed() const;
 
         // for use only in LoadHelper, Map::Add Map::CreatureCellRelocation
         Cell const& GetCurrentCell() const { return m_currentCell; }
@@ -664,7 +679,7 @@ class MANGOS_DLL_SPEC Creature : public Unit
         float CombatStartX;
         float CombatStartY;
         float CombatStartZ;
-
+        Vehicle* m_vehicleKit;
         float m_summonXpoint;
         float m_summonYpoint;
         float m_summonZpoint;
diff --git a/src/game/CreatureAI.cpp b/src/game/CreatureAI.cpp
index b650b65..944442b 100644
--- a/src/game/CreatureAI.cpp
+++ b/src/game/CreatureAI.cpp
@@ -26,6 +26,10 @@ CreatureAI::~CreatureAI()
 
 void CreatureAI::AttackedBy( Unit* attacker )
 {
+    // vehicle dont have threat list, so this is unnecessary, because it calls move chase
+    if(m_creature->isVehicle())
+        return;
+
     if(!m_creature->getVictim())
         AttackStart(attacker);
 }
diff --git a/src/game/CreatureEventAI.cpp b/src/game/CreatureEventAI.cpp
index d036e99..55798c6 100644
--- a/src/game/CreatureEventAI.cpp
+++ b/src/game/CreatureEventAI.cpp
@@ -851,6 +851,7 @@ void CreatureEventAI::JustReachedHome()
 
 void CreatureEventAI::EnterEvadeMode()
 {
+    m_creature->ExitVehicle();
     m_creature->RemoveAllAuras();
     m_creature->DeleteThreatList();
     m_creature->CombatStop(true);
diff --git a/src/game/DBCStructure.h b/src/game/DBCStructure.h
index 3df6e72..2e74b7a 100644
--- a/src/game/DBCStructure.h
+++ b/src/game/DBCStructure.h
@@ -1690,7 +1690,7 @@ struct VehicleEntry
     uint32  m_uiLocomotionType;                             // 34
     float   m_msslTrgtImpactTexRadius;                      // 35
     uint32  m_uiSeatIndicatorType;                          // 36
-                                                            // 37, new in 3.1
+    uint32  m_powerType;                                    // 37, new in 3.1                                                        // 37, new in 3.1
                                                             // 38, new in 3.1
                                                             // 39, new in 3.1
 };
diff --git a/src/game/DBCfmt.h b/src/game/DBCfmt.h
index 4743476..a7d6c3f 100644
--- a/src/game/DBCfmt.h
+++ b/src/game/DBCfmt.h
@@ -103,7 +103,7 @@ const char TaxiNodesEntryfmt[]="nifffssssssssssssssssxii";
 const char TaxiPathEntryfmt[]="niii";
 const char TaxiPathNodeEntryfmt[]="diiifffiixx";
 const char TotemCategoryEntryfmt[]="nxxxxxxxxxxxxxxxxxii";
-const char VehicleEntryfmt[]="niffffiiiiiiiifffffffffffffffssssfifixxx";
+const char VehicleEntryfmt[]="niffffiiiiiiiifffffffffffffffssssfifiixx";
 const char VehicleSeatEntryfmt[]="niiffffffffffiiiiiifffffffiiifffiiiiiiiffiiiiixxxxxxxxxxxx";
 const char WorldMapAreaEntryfmt[]="xinxffffixx";
 const char WorldMapOverlayEntryfmt[]="nxiiiixxxxxxxxxxx";
diff --git a/src/game/GameObject.cpp b/src/game/GameObject.cpp
index e146a0a..7df9bbe 100644
--- a/src/game/GameObject.cpp
+++ b/src/game/GameObject.cpp
@@ -436,11 +436,7 @@ void GameObject::Update(uint32 /*p_time*/)
             if(!m_respawnDelayTime)
                 return;
 
-            if(!m_spawnedByDefault)
-            {
-                m_respawnTime = 0;
-                return;
-            }
+            m_respawnTime = m_spawnedByDefault ? time(NULL) + m_respawnDelayTime : 0;
 
             // since pool system can fail to roll unspawned object, this one can remain spawned, so must set respawn nevertheless
             m_respawnTime = time(NULL) + m_respawnDelayTime;
@@ -1536,3 +1532,14 @@ bool GameObject::IsFriendlyTo(Unit const* unit) const
     return tester_faction->IsFriendlyTo(*target_faction);
 }
 
+void GameObject::DealSiegeDamage(uint32 damage)
+{
+    m_actualHealth -= damage;
+
+    // TODO : there are a lot of thinghts to do here
+    if(m_actualHealth < 0)
+    {
+        m_actualHealth = GetGOInfo()->destructibleBuilding.intactNumHits;
+        SetLootState(GO_JUST_DEACTIVATED);
+    }
+}
\ No newline at end of file
diff --git a/src/game/GameObject.h b/src/game/GameObject.h
index 9cf06b3..8d51222 100644
--- a/src/game/GameObject.h
+++ b/src/game/GameObject.h
@@ -691,12 +691,14 @@ class MANGOS_DLL_SPEC GameObject : public WorldObject
 
         bool isActiveObject() const { return false; }
         uint64 GetRotation() const { return m_rotation; }
+        void DealSiegeDamage(uint32 damage);
     protected:
         uint32      m_spellId;
         time_t      m_respawnTime;                          // (secs) time of next respawn (or despawn if GO have owner()),
         uint32      m_respawnDelayTime;                     // (secs) if 0 then current GO state no dependent from timer
         LootState   m_lootState;
         bool        m_spawnedByDefault;
+        int32       m_actualHealth;                         // current health state
         time_t      m_cooldownTime;                         // used as internal reaction delay time store (not state change reaction).
                                                             // For traps this: spell casting cooldown, for doors/buttons: reset time.
         std::list<uint32> m_SkillupList;
diff --git a/src/game/GridNotifiers.cpp b/src/game/GridNotifiers.cpp
index e654cc7..f3bde20 100644
--- a/src/game/GridNotifiers.cpp
+++ b/src/game/GridNotifiers.cpp
@@ -141,7 +141,10 @@ VisibleNotifier::Notify()
     {
         // target aura duration for caster show only if target exist at caster client
         if((*vItr)!=&i_player && (*vItr)->isType(TYPEMASK_UNIT))
+        {
             i_player.SendAurasForTarget((Unit*)(*vItr));
+            i_player.BuildVehicleInfo((Unit*)(*vItr));
+        }
 
         // non finished movements show to player
         if((*vItr)->GetTypeId()==TYPEID_UNIT && ((Creature*)(*vItr))->isAlive())
diff --git a/src/game/Group.h b/src/game/Group.h
index 3024438..88eda30 100644
--- a/src/game/Group.h
+++ b/src/game/Group.h
@@ -92,7 +92,8 @@ enum GroupUpdateFlags
     GROUP_UPDATE_FLAG_PET_AURAS         = 0x00040000,       // uint64 mask, for each bit set uint32 spellid + uint8 unk, pet auras...
     GROUP_UPDATE_FLAG_VEHICLE_SEAT      = 0x00080000,       // uint32 vehicle_seat_id (index from VehicleSeat.dbc)
     GROUP_UPDATE_PET                    = 0x0007FC00,       // all pet flags
-    GROUP_UPDATE_FULL                   = 0x0007FFFF,       // all known flags
+    GROUP_UPDATE_VEHICLE                = 0x000FFC00,       // all vehicle flags
+    GROUP_UPDATE_FULL                   = 0x000FFFFF,       // all known flags
 };
 
 #define GROUP_UPDATE_FLAGS_COUNT          20
diff --git a/src/game/GroupHandler.cpp b/src/game/GroupHandler.cpp
index f250925..0e9bcfb 100644
--- a/src/game/GroupHandler.cpp
+++ b/src/game/GroupHandler.cpp
@@ -28,6 +28,7 @@
 #include "Group.h"
 #include "SocialMgr.h"
 #include "Util.h"
+#include "Vehicle.h"
 
 /* differeces from off:
     -you can uninvite yourself - is is useful
@@ -690,7 +691,7 @@ void WorldSession::BuildPartyMemberStatsChangedPacket(Player *player, WorldPacke
         }
     }
 
-    Pet *pet = player->GetPet();
+    Unit *pet = player->GetCharmOrPet();
     if (mask & GROUP_UPDATE_FLAG_PET_GUID)
     {
         if(pet)
@@ -773,6 +774,11 @@ void WorldSession::BuildPartyMemberStatsChangedPacket(Player *player, WorldPacke
         else
             *data << (uint64) 0;
     }
+
+    if (mask & GROUP_UPDATE_FLAG_VEHICLE_SEAT)
+    {
+        *data << (uint32) player->m_SeatData.dbc_seat;
+    }
 }
 
 /*this procedure handles clients CMSG_REQUEST_PARTY_MEMBER_STATS request*/
@@ -794,7 +800,7 @@ void WorldSession::HandleRequestPartyMemberStatsOpcode( WorldPacket &recv_data )
         return;
     }
 
-    Pet *pet = player->GetPet();
+    Unit *pet = player->GetCharmOrPet();
 
     WorldPacket data(SMSG_PARTY_MEMBER_STATS_FULL, 4+2+2+2+1+2*6+8+1+8);
     data << uint8(0);                                       // only for SMSG_PARTY_MEMBER_STATS_FULL, probably arena/bg related
@@ -802,7 +808,7 @@ void WorldSession::HandleRequestPartyMemberStatsOpcode( WorldPacket &recv_data )
 
     uint32 mask1 = 0x00040BFF;                              // common mask, real flags used 0x000040BFF
     if(pet)
-        mask1 = 0x7FFFFFFF;                                 // for hunters and other classes with pets
+        mask1 = 0xFFFFFFFF;                                 // for hunters and other classes with pets
 
     Powers powerType = player->getPowerType();
     data << (uint32) mask1;                                 // group update mask
@@ -856,6 +862,7 @@ void WorldSession::HandleRequestPartyMemberStatsOpcode( WorldPacket &recv_data )
             }
         }
         data.put<uint64>(petMaskPos,petauramask);           // GROUP_UPDATE_FLAG_PET_AURAS
+        data << (uint32) player->m_SeatData.dbc_seat;
     }
     else
     {
diff --git a/src/game/Level3.cpp b/src/game/Level3.cpp
index 61eea24..840b092 100644
--- a/src/game/Level3.cpp
+++ b/src/game/Level3.cpp
@@ -73,6 +73,9 @@ bool ChatHandler::HandleReloadAllCommand(const char*)
     HandleReloadReservedNameCommand("");
     HandleReloadMangosStringCommand("");
     HandleReloadGameTeleCommand("");
+
+    HandleReloadVehicleDataCommand("");
+    HandleReloadVehicleSeatDataCommand("");
     return true;
 }
 
@@ -890,6 +893,22 @@ bool ChatHandler::HandleReloadMailLevelRewardCommand(const char* /*arg*/)
     return true;
 }
 
+bool ChatHandler::HandleReloadVehicleDataCommand(const char*)
+{
+    sLog.outString( "Re-Loading `vehicle_data` Table!" );
+    sObjectMgr.LoadVehicleData();
+    SendGlobalSysMessage("DB table `vehicle_data` reloaded.");
+    return true;
+}
+
+bool ChatHandler::HandleReloadVehicleSeatDataCommand(const char*)
+{
+    sLog.outString( "Re-Loading `vehicle_seat_data` Table!" );
+    sObjectMgr.LoadVehicleSeatData();
+    SendGlobalSysMessage("DB table `vehicle_seat_data` reloaded.");
+    return true;
+}
+
 bool ChatHandler::HandleLoadScriptsCommand(const char* args)
 {
     if(!LoadScriptingModule(args)) return true;
diff --git a/src/game/Map.cpp b/src/game/Map.cpp
index 7c00f9d..edabfaf 100644
--- a/src/game/Map.cpp
+++ b/src/game/Map.cpp
@@ -206,7 +206,7 @@ Map::Map(uint32 id, time_t expiry, uint32 InstanceId, uint8 SpawnMode, Map* _par
   m_VisibleDistance(DEFAULT_VISIBILITY_DISTANCE),
   m_activeNonPlayersIter(m_activeNonPlayers.end()),
   i_gridExpiry(expiry), m_parentMap(_parent ? _parent : this),
-  m_hiDynObjectGuid(1), m_hiPetGuid(1), m_hiVehicleGuid(1)
+  m_hiDynObjectGuid(1), m_hiPetGuid(1)
 {
     for(unsigned int idx=0; idx < MAX_NUMBER_OF_GRIDS; ++idx)
     {
@@ -3518,18 +3518,12 @@ Corpse* Map::GetCorpse(uint64 guid)
     return ret;
 }
 
-Creature* Map::GetCreatureOrPetOrVehicle(uint64 guid)
+Unit* Map::GetCreatureOrPet(uint64 guid)
 {
-    if (IS_PLAYER_GUID(guid))
-        return NULL;
-
-    if (IS_PET_GUID(guid))
-        return GetPet(guid);
-
-    if (IS_VEHICLE_GUID(guid))
-        return GetVehicle(guid);
+    if (Unit* ret = GetCreature(guid))
+        return ret;
 
-    return GetCreature(guid);
+    return GetPet(guid);
 }
 
 GameObject* Map::GetGameObject(uint64 guid)
@@ -3600,13 +3594,13 @@ uint32 Map::GenerateLocalLowGuid(HighGuid guidhigh)
                 World::StopNow(ERROR_EXIT_CODE);
             }
             return m_hiPetGuid++;
-        case HIGHGUID_VEHICLE:
+        /*case HIGHGUID_VEHICLE:
             if(m_hiVehicleGuid>=0x00FFFFFF)
             {
                 sLog.outError("Vehicle guid overflow!! Can't continue, shutting down server. ");
                 World::StopNow(ERROR_EXIT_CODE);
             }
-            return m_hiVehicleGuid++;
+            return m_hiVehicleGuid++;*/
         default:
             ASSERT(0);
     }
diff --git a/src/game/Map.h b/src/game/Map.h
index af153a2..72d665b 100644
--- a/src/game/Map.h
+++ b/src/game/Map.h
@@ -37,7 +37,6 @@
 #include <bitset>
 #include <list>
 
-class Creature;
 class Unit;
 class WorldPacket;
 class InstanceData;
@@ -399,7 +398,7 @@ class MANGOS_DLL_SPEC Map : public GridRefManager<NGridType>, public MaNGOS::Obj
         Creature* GetCreature(uint64 guid);
         Vehicle* GetVehicle(uint64 guid);
         Pet* GetPet(uint64 guid);
-        Creature* GetCreatureOrPetOrVehicle(uint64 guid);
+        Unit* GetCreatureOrPet(uint64 guid);
         GameObject* GetGameObject(uint64 guid);
         DynamicObject* GetDynamicObject(uint64 guid);
         Corpse* GetCorpse(uint64 guid);
@@ -497,7 +496,6 @@ class MANGOS_DLL_SPEC Map : public GridRefManager<NGridType>, public MaNGOS::Obj
         // Map local low guid counters
         uint32 m_hiDynObjectGuid;
         uint32 m_hiPetGuid;
-        uint32 m_hiVehicleGuid;
 
         // Type specific code for add/remove to/from grid
         template<class T>
diff --git a/src/game/MiscHandler.cpp b/src/game/MiscHandler.cpp
index 5559111..a608daf 100644
--- a/src/game/MiscHandler.cpp
+++ b/src/game/MiscHandler.cpp
@@ -266,6 +266,7 @@ void WorldSession::HandleLogoutRequestOpcode( WorldPacket & /*recv_data*/ )
     //Can not logout if...
     if( GetPlayer()->isInCombat() ||                        //...is in combat
         GetPlayer()->duel         ||                        //...is in Duel
+        GetPlayer()->GetVehicleGUID() ||                    //...is in vehicle
                                                             //...is jumping ...is falling
         GetPlayer()->m_movementInfo.HasMovementFlag(MovementFlags(MOVEFLAG_FALLING | MOVEFLAG_FALLINGFAR)))
     {
diff --git a/src/game/MovementHandler.cpp b/src/game/MovementHandler.cpp
index df93dde..330213e 100644
--- a/src/game/MovementHandler.cpp
+++ b/src/game/MovementHandler.cpp
@@ -249,7 +249,7 @@ void WorldSession::HandleMovementOpcodes( WorldPacket & recv_data )
     }
 
     /* handle special cases */
-    if (movementInfo.HasMovementFlag(MOVEFLAG_ONTRANSPORT))
+    if (movementInfo.HasMovementFlag(MOVEFLAG_ONTRANSPORT) && !mover->GetVehicleGUID())
     {
         // transports size limited
         // (also received at zeppelin/lift leave by some reason with t_* as absolute in continent coordinates, can be safely skipped)
@@ -297,6 +297,17 @@ void WorldSession::HandleMovementOpcodes( WorldPacket & recv_data )
         // now client not include swimming flag in case jumping under water
         plMover->SetInWater( !plMover->IsInWater() || plMover->GetBaseMap()->IsUnderWater(movementInfo.GetPos()->x, movementInfo.GetPos()->y, movementInfo.GetPos()->z) );
     }
+    if (movementInfo.HasMovementFlag(MOVEFLAG_SWIMMING))
+    {
+        if(mover->GetTypeId() == TYPEID_UNIT)
+        {
+            if(((Creature*)mover)->isVehicle() && !((Creature*)mover)->canSwim())
+            {
+                // NOTE : we should enter evade mode here, but...
+                ((Vehicle*)mover)->SetSpawnDuration(1);
+            }
+        }
+    }
 
     /*----------------------*/
 
@@ -355,7 +366,11 @@ void WorldSession::HandleMovementOpcodes( WorldPacket & recv_data )
     else                                                    // creature charmed
     {
         if(mover->IsInWorld())
+        {
             mover->GetMap()->CreatureRelocation((Creature*)mover, movementInfo.GetPos()->x, movementInfo.GetPos()->y, movementInfo.GetPos()->z, movementInfo.GetPos()->o);
+            if(((Creature*)mover)->isVehicle())
+                ((Vehicle*)mover)->RellocatePassengers(mover->GetMap());
+        }
     }
 }
 
@@ -443,6 +458,12 @@ void WorldSession::HandleSetActiveMoverOpcode(WorldPacket &recv_data)
     uint64 guid;
     recv_data >> guid;
 
+    if(_player->m_mover_in_queve && _player->m_mover_in_queve->GetGUID() == guid)
+    {
+        _player->m_mover = _player->m_mover_in_queve;
+        _player->m_mover_in_queve = NULL;
+    }
+
     if(_player->m_mover->GetGUID() != guid)
     {
         sLog.outError("HandleSetActiveMoverOpcode: incorrect mover guid: mover is " I64FMT " and should be " I64FMT, _player->m_mover->GetGUID(), guid);
@@ -477,7 +498,7 @@ void WorldSession::HandleDismissControlledVehicle(WorldPacket &recv_data)
     sLog.outDebug("WORLD: Recvd CMSG_DISMISS_CONTROLLED_VEHICLE");
     recv_data.hexlike();
 
-    uint64 vehicleGUID = _player->GetCharmGUID();
+    uint64 vehicleGUID = _player->GetVehicleGUID();
 
     if(!vehicleGUID)                                        // something wrong here...
     {
@@ -494,11 +515,163 @@ void WorldSession::HandleDismissControlledVehicle(WorldPacket &recv_data)
 
     _player->m_movementInfo = mi;
 
-    // using charm guid, because we don't have vehicle guid...
-    if(Vehicle *vehicle = _player->GetMap()->GetVehicle(vehicleGUID))
+    if(Vehicle *vehicle = ObjectAccessor::GetVehicle(vehicleGUID))
+    {
+        if(vehicle->GetVehicleFlags() & VF_DESPAWN_AT_LEAVE)
+            vehicle->Dismiss();
+        else
+            _player->ExitVehicle();
+    }
+}
+
+void WorldSession::HandleRequestVehicleExit(WorldPacket &recv_data)
+{
+    sLog.outDebug("WORLD: Recvd CMSG_REQUEST_VEHICLE_EXIT");
+    recv_data.hexlike();
+
+    uint64 vehicleGUID = _player->GetVehicleGUID();
+
+    if(!vehicleGUID)                                        // something wrong here...
+        return;
+
+    if(Vehicle *vehicle = ObjectAccessor::GetVehicle(vehicleGUID))
+    {
+        _player->ExitVehicle();
+    }
+}
+
+void WorldSession::HandleRequestVehiclePrevSeat(WorldPacket &recv_data)
+{
+    sLog.outDebug("WORLD: Recvd CMSG_REQUEST_VEHICLE_PREV_SEAT");
+    recv_data.hexlike();
+
+    uint64 vehicleGUID = _player->GetVehicleGUID();
+
+    if(!vehicleGUID)                                        // something wrong here...
+        return;
+
+    if(Vehicle *vehicle = ObjectAccessor::GetVehicle(vehicleGUID))
     {
-        // Aura::HandleAuraControlVehicle will call Player::ExitVehicle
-        vehicle->RemoveSpellsCausingAura(SPELL_AURA_CONTROL_VEHICLE);
+        int8 prv_seat = _player->m_SeatData.seat;
+        if(Vehicle *v = vehicle->GetNextEmptySeat(&prv_seat, false, false))
+        {
+            vehicle->RemovePassenger(_player);
+            _player->EnterVehicle(v, prv_seat, false);
+        }
+    }
+}
+
+void WorldSession::HandleRequestVehicleNextSeat(WorldPacket &recv_data)
+{
+    sLog.outDebug("WORLD: Recvd CMSG_REQUEST_VEHICLE_NEXT_SEAT");
+    recv_data.hexlike();
+
+    uint64 vehicleGUID = _player->GetVehicleGUID();
+
+    if(!vehicleGUID)                                        // something wrong here...
+        return;
+
+    if(Vehicle *vehicle = ObjectAccessor::GetVehicle(vehicleGUID))
+    {
+        int8 nxt_seat = _player->m_SeatData.seat;
+        if(Vehicle *v = vehicle->GetNextEmptySeat(&nxt_seat, true, false))
+        {
+            vehicle->RemovePassenger(_player);
+            _player->EnterVehicle(v, nxt_seat, false);
+        }
+    }
+}
+
+void WorldSession::HandleRequestVehicleSwitchSeat(WorldPacket &recv_data)
+{
+    sLog.outDebug("WORLD: Recvd CMSG_REQUEST_VEHICLE_SWITCH_SEAT");
+    recv_data.hexlike();
+
+    uint64 vehicleGUID = _player->GetVehicleGUID();
+
+    if(!vehicleGUID)                                        // something wrong here...
+        return;
+
+    if(Vehicle *vehicle = ObjectAccessor::GetVehicle(vehicleGUID))
+    {
+        uint64 guid = 0;
+        if(!recv_data.readPackGUID(guid))
+            return;
+
+        int8 seatId = 0;
+        recv_data >> seatId;
+
+        if(guid)
+        {
+            if(vehicleGUID != guid)
+            {
+                if(Vehicle *veh = ObjectAccessor::GetVehicle(guid))
+                {
+                    if(!_player->IsWithinDistInMap(veh, 10))
+                        return;
+
+                    if(Vehicle *v = veh->FindFreeSeat(&seatId, false))
+                    {
+                        vehicle->RemovePassenger(_player);
+                        _player->EnterVehicle(v, seatId, false);
+                    }
+                }
+                return;
+            }
+        }
+        if(Vehicle *v = vehicle->FindFreeSeat(&seatId, false))
+        {
+            vehicle->RemovePassenger(_player);
+            _player->EnterVehicle(v, seatId, false);
+        }
+    }
+}
+
+void WorldSession::HandleChangeSeatsOnControlledVehicle(WorldPacket &recv_data)
+{
+    sLog.outDebug("WORLD: Recvd CMSG_CHANGE_SEATS_ON_CONTROLLED_VEHICLE");
+    recv_data.hexlike();
+
+    uint64 vehicleGUID = _player->GetVehicleGUID();
+
+    if(!vehicleGUID)                                        // something wrong here...
+        return;
+
+    if(Vehicle *vehicle = ObjectAccessor::GetVehicle(vehicleGUID))
+    {
+        MovementInfo mi(recv_data);
+        //_player->m_movementInfo = mi;
+
+        uint64 guid = 0;
+        if(!recv_data.readPackGUID(guid))
+            return;
+
+        int8 seatId = 0;
+        recv_data >> seatId;
+
+        if(guid)
+        {
+            if(vehicleGUID != guid)
+            {
+                if(Vehicle *veh = ObjectAccessor::GetVehicle(guid))
+                {
+                    if(!_player->IsWithinDistInMap(veh, 10))
+                        return;
+
+                    if(Vehicle *v = veh->FindFreeSeat(&seatId, false))
+                    {
+                        vehicle->RemovePassenger(_player);
+                        _player->EnterVehicle(v, seatId, false);
+                    }
+                }
+                return;
+            }
+        }
+        if(Vehicle *v = vehicle->FindFreeSeat(&seatId, false))
+        {
+            vehicle->RemovePassenger(_player);
+            _player->EnterVehicle(v, seatId, false);
+        }
     }
 }
 
diff --git a/src/game/Object.cpp b/src/game/Object.cpp
index 053b5bf..21d5919 100644
--- a/src/game/Object.cpp
+++ b/src/game/Object.cpp
@@ -287,6 +287,9 @@ void Object::BuildMovementUpdate(ByteBuffer * data, uint16 updateFlags) const
                         }
                     }
                 }
+                if(((Unit*)this)->GetVehicleGUID())
+                    moveFlags2 |= (MOVEFLAG_ONTRANSPORT | MOVEFLAG_ROOT);
+
             }
             break;
             case TYPEID_PLAYER:
@@ -301,6 +304,8 @@ void Object::BuildMovementUpdate(ByteBuffer * data, uint16 updateFlags) const
                 // remove unknown, unused etc flags for now
                 player->m_movementInfo.RemoveMovementFlag(MOVEFLAG_SPLINE_ENABLED);
 
+                if(((Unit*)this)->GetVehicleGUID())
+                    moveFlags2 |= (MOVEFLAG_ONTRANSPORT | MOVEFLAG_ROOT);
                 if(player->isInFlight())
                 {
                     ASSERT(player->GetMotionMaster()->GetCurrentMovementGeneratorType() == FLIGHT_MOTION_TYPE);
@@ -1678,6 +1683,42 @@ Creature* WorldObject::SummonCreature(uint32 id, float x, float y, float z, floa
     return pCreature;
 }
 
+Vehicle* WorldObject::SummonVehicle(uint32 id, float x, float y, float z, float ang, uint32 vehicleId)
+{
+    Vehicle *v = new Vehicle;
+
+    Map *map = GetMap();
+    uint32 team = 0;
+    if (GetTypeId()==TYPEID_PLAYER)
+        team = ((Player*)this)->GetTeam();
+
+    if(!v->Create(sObjectMgr.GenerateLowGuid(HIGHGUID_VEHICLE), map, GetPhaseMask(), id, vehicleId, team))
+    {
+        delete v;
+        return NULL;
+    }
+
+    if (x == 0.0f && y == 0.0f && z == 0.0f)
+        GetClosePoint(x, y, z, v->GetObjectSize());
+
+    v->Relocate(x, y, z, ang);
+
+    if(!v->IsPositionValid())
+    {
+        sLog.outError("ERROR: Vehicle (guidlow %d, entry %d) not created. Suggested coordinates isn't valid (X: %f Y: %f)",
+            v->GetGUIDLow(), v->GetEntry(), v->GetPositionX(), v->GetPositionY());
+        delete v;
+        return NULL;
+    }
+    map->Add((Creature*)v);
+    v->AIM_Initialize();
+
+    if(GetTypeId()==TYPEID_UNIT && ((Creature*)this)->AI())
+        ((Creature*)this)->AI()->JustSummoned((Creature*)v);
+
+    return v;
+}
+
 namespace MaNGOS
 {
     class NearUsedPosDo
diff --git a/src/game/Object.h b/src/game/Object.h
index 0467f51..c5c152a 100644
--- a/src/game/Object.h
+++ b/src/game/Object.h
@@ -95,6 +95,7 @@ class Unit;
 class Map;
 class UpdateMask;
 class InstanceData;
+class Vehicle;
 
 typedef UNORDERED_MAP<Player*, UpdateData> UpdateDataMapType;
 
@@ -501,6 +502,8 @@ class MANGOS_DLL_SPEC WorldObject : public Object
         void BuildUpdateData(UpdateDataMapType &);
 
         Creature* SummonCreature(uint32 id, float x, float y, float z, float ang,TempSummonType spwtype,uint32 despwtime);
+        Vehicle* SummonVehicle(uint32 id, float x, float y, float z, float ang, uint32 vehicleId = NULL);
+
     protected:
         explicit WorldObject();
 
diff --git a/src/game/ObjectAccessor.cpp b/src/game/ObjectAccessor.cpp
index eb2c395..8a3b7c4 100644
--- a/src/game/ObjectAccessor.cpp
+++ b/src/game/ObjectAccessor.cpp
@@ -53,6 +53,21 @@ ObjectAccessor::~ObjectAccessor()
     }
 }
 
+Creature*
+ObjectAccessor::GetCreatureOrPetOrVehicle(WorldObject const &u, uint64 guid)
+{
+    if(IS_PLAYER_GUID(guid) || !u.IsInWorld())
+        return NULL;
+
+    if(IS_PET_GUID(guid))
+        return u.GetMap()->GetPet(guid);
+
+    if(IS_VEHICLE_GUID(guid))
+        return u.GetMap()->GetVehicle(guid);
+
+    return u.GetMap()->GetCreature(guid);
+}
+
 Unit*
 ObjectAccessor::GetUnit(WorldObject const &u, uint64 guid)
 {
@@ -62,10 +77,7 @@ ObjectAccessor::GetUnit(WorldObject const &u, uint64 guid)
     if(IS_PLAYER_GUID(guid))
         return FindPlayer(guid);
 
-    if (!u.IsInWorld())
-        return NULL;
-
-    return u.GetMap()->GetCreatureOrPetOrVehicle(guid);
+    return GetCreatureOrPetOrVehicle(u, guid);
 }
 
 Corpse* ObjectAccessor::GetCorpseInMap( uint64 guid, uint32 mapid )
diff --git a/src/game/ObjectAccessor.h b/src/game/ObjectAccessor.h
index d704045..b87e84c 100644
--- a/src/game/ObjectAccessor.h
+++ b/src/game/ObjectAccessor.h
@@ -38,6 +38,7 @@
 class Creature;
 class Unit;
 class GameObject;
+class Vehicle;
 class WorldObject;
 class Map;
 
@@ -91,13 +92,21 @@ class MANGOS_DLL_DECL ObjectAccessor : public MaNGOS::Singleton<ObjectAccessor,
         // global (obj used for map only location local guid objects (pets currently)
         static Unit*   GetUnitInWorld(WorldObject const& obj, uint64 guid);
 
-        // FIXME: map local object with global search
+        // map local object with global search
         static Creature*   GetCreatureInWorld(uint64 guid)   { return FindHelper<Creature>(guid); }
         static GameObject* GetGameObjectInWorld(uint64 guid) { return FindHelper<GameObject>(guid); }
+        static Pet*        GetGameObjectInWorld(uint64 guid, Pet*        /*fake*/) { return FindHelper<Pet>(guid); }
+        static Vehicle*    GetGameObjectInWorld(uint64 guid, Vehicle*    /*fake*/) { return FindHelper<Vehicle>(guid); }
 
         // possible local search for specific object map
         static Object* GetObjectByTypeMask(WorldObject const &, uint64, uint32 typemask);
+        static Creature* GetCreatureOrPetOrVehicle(WorldObject const &, uint64);
         static Unit* GetUnit(WorldObject const &, uint64);
+        //static Player* GetPlayer(Unit const &, uint64 guid) { return FindPlayer(guid); }
+        //static Corpse* GetCorpse(WorldObject const &u, uint64 guid);
+        //static Pet* GetPet(uint64 guid) { return GetObjectInWorld(guid, (Pet*)NULL); }
+        static Vehicle* GetVehicle(uint64 guid) { return GetGameObjectInWorld(guid, (Vehicle*)NULL); }
+        //static Player* FindPlayer(uint64);
 
         // Player access
         static Player* FindPlayer(uint64 guid);
@@ -165,6 +174,9 @@ inline Unit* ObjectAccessor::GetUnitInWorld(WorldObject const& obj, uint64 guid)
     if (IS_PET_GUID(guid))
         return obj.IsInWorld() ? obj.GetMap()->GetPet(guid) : NULL;
 
+    if (IS_VEHICLE_GUID(guid))
+        return obj.IsInWorld() ? ((Unit*)obj.GetMap()->GetVehicle(guid)) : NULL;
+
     return GetCreatureInWorld(guid);
 }
 
diff --git a/src/game/ObjectMgr.cpp b/src/game/ObjectMgr.cpp
index 191f08d..0f2bc46 100644
--- a/src/game/ObjectMgr.cpp
+++ b/src/game/ObjectMgr.cpp
@@ -132,6 +132,7 @@ ObjectMgr::ObjectMgr()
 {
     m_hiCharGuid        = 1;
     m_hiCreatureGuid    = 1;
+	m_hiVehicleGuid     = 1;
     m_hiItemGuid        = 1;
     m_hiGoGuid          = 1;
     m_hiCorpseGuid      = 1;
@@ -819,6 +820,93 @@ void ObjectMgr::ConvertCreatureAddonAuras(CreatureDataAddon* addon, char const*
     endAura.effect_idx = EFFECT_INDEX_0;
 }
 
+void ObjectMgr::ConvertCreatureAddonPassengers(CreatureDataAddon* addon, char const* table, char const* guidEntryStr)
+{
+    // Now add the passengers, format "creature_entry/guid seatindex creature_entry/guid seatindex..."
+    char *p,*s;
+    std::vector<int> val;
+    s=p=(char*)reinterpret_cast<char const*>(addon->passengers);
+    if(p)
+    {
+        while (p[0]!=0)
+        {
+            ++p;
+            if (p[0]==' ')
+            {
+                val.push_back(atoi(s));
+                s=++p;
+            }
+        }
+        if (p!=s)
+            val.push_back(atoi(s));
+
+        // free char* loaded memory
+        delete[] (char*)reinterpret_cast<char const*>(addon->passengers);
+
+        // wrong list
+        if (val.size()%2)
+        {
+            addon->auras = NULL;
+            sLog.outErrorDb("Creature (%s: %u) has wrong `passengers` data in `%s`.",guidEntryStr,addon->guidOrEntry,table);
+            return;
+        }
+    }
+
+    // empty list
+    if(val.empty())
+    {
+        addon->passengers = NULL;
+        return;
+    }
+
+    // replace by new structures array
+    const_cast<CreatureDataAddonPassengers*&>(addon->passengers) = new CreatureDataAddonPassengers[val.size()/2+1];
+
+    int i=0;
+    for(int j=0;j<val.size()/2;++j)
+    {
+        CreatureDataAddonPassengers& cPas = const_cast<CreatureDataAddonPassengers&>(addon->passengers[i]);
+        if(guidEntryStr == "Entry")
+            cPas.entry = (uint32)val[2*j+0];
+        else
+            cPas.guid = (uint32)val[2*j+0];
+        cPas.seat_idx = (int8)val[2*j+1];
+        if ( cPas.seat_idx > 7 )
+        {
+            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);
+            continue;
+        }
+        if(cPas.entry == 0 && cPas.guid == 0)
+        {
+            sLog.outErrorDb("Creature (%s: %u) has NULL creature entry/guid in `passengers` field in `%s`.",guidEntryStr,addon->guidOrEntry,table);
+            continue;
+        }
+        if(cPas.entry > 0)
+        {
+            if(!sCreatureStorage.LookupEntry<CreatureInfo>(cPas.entry))
+            {
+                sLog.outErrorDb("Creature (%s: %u) has wrong creature entry/guid %u `passengers` field in `%s`.",guidEntryStr,addon->guidOrEntry,cPas.entry,table);
+                continue;
+            }
+        }
+        else
+        {
+            if(mCreatureDataMap.find(cPas.guid)==mCreatureDataMap.end())
+            {
+                sLog.outErrorDb("Creature (%s: %u) has wrong creature entry/guid %u `passengers` field in `%s`.",guidEntryStr,addon->guidOrEntry,cPas.guid,table);
+                continue;
+            }
+        }
+        ++i;
+    }
+
+    // fill terminator element (after last added)
+    CreatureDataAddonPassengers& endPassenger = const_cast<CreatureDataAddonPassengers&>(addon->passengers[i]);
+    endPassenger.entry = 0;
+    endPassenger.guid = 0;
+    endPassenger.seat_idx = -1;
+}
+
 void ObjectMgr::LoadCreatureAddons(SQLStorage& creatureaddons, char const* entryName, char const* comment)
 {
     creatureaddons.Load();
@@ -852,6 +940,7 @@ void ObjectMgr::LoadCreatureAddons(SQLStorage& creatureaddons, char const* entry
         }
 
         ConvertCreatureAddonAuras(const_cast<CreatureDataAddon*>(addon), creatureaddons.GetTableName(), entryName);
+        ConvertCreatureAddonPassengers(const_cast<CreatureDataAddon*>(addon), creatureaddons.GetTableName(), entryName);
     }
 }
 
@@ -5859,6 +5948,13 @@ uint32 ObjectMgr::GenerateLowGuid(HighGuid guidhigh)
                 World::StopNow(ERROR_EXIT_CODE);
             }
             return m_hiCreatureGuid++;
+        case HIGHGUID_VEHICLE:
+            if(m_hiVehicleGuid>=0x00FFFFFF)
+            {
+                sLog.outError("Vehicle guid overflow!! Can't continue, shutting down server. ");
+                World::StopNow(ERROR_EXIT_CODE);
+            }
+            return m_hiVehicleGuid++;
         case HIGHGUID_PLAYER:
             if(m_hiCharGuid>=0xFFFFFFFE)
             {
@@ -8583,6 +8679,126 @@ CreatureInfo const* GetCreatureTemplateStore(uint32 entry)
     return sCreatureStorage.LookupEntry<CreatureInfo>(entry);
 }
 
+void ObjectMgr::LoadVehicleData()
+{
+    mVehicleData.clear();
+
+    QueryResult *result = WorldDatabase.Query("SELECT entry, flags, Spell1, Spell2, Spell3, Spell4, Spell5, Spell6, Spell7, Spell8, Spell9, Spell10, req_aura FROM vehicle_data");
+    if(!result)
+    {
+        barGoLink bar( 1 );
+        bar.step();
+
+        sLog.outString();
+        sLog.outString( ">> Loaded 0 vehicle data" );
+        sLog.outErrorDb("`vehicle_data` table is empty!");
+        return;
+    }
+
+    uint32 count = 0;
+
+    barGoLink bar( result->GetRowCount() );
+    do
+    {
+        bar.step();
+
+        Field* fields = result->Fetch();
+
+        VehicleDataStructure VDS;
+        // NOTE : we can use spellid or creature id
+        uint32 v_entry      = fields[0].GetUInt32();
+        VDS.v_flags         = fields[1].GetUInt32();
+        for(uint8 j = 0; j < MAX_VEHICLE_SPELLS; j++)
+        {
+            VDS.v_spells[j] = fields[j+2].GetUInt32();
+        }
+        VDS.req_aura        = fields[12].GetUInt32();
+
+        VehicleEntry const *vehicleInfo = sVehicleStore.LookupEntry(v_entry);
+        if(!vehicleInfo)
+        {
+            sLog.outErrorDb("Vehicle id %u listed in `vehicle_data` does not exist",v_entry);
+            continue;
+        }
+        for(uint8 j = 0; j < MAX_VEHICLE_SPELLS; j++)
+        {
+            if(VDS.v_spells[j])
+            {
+                SpellEntry const* j_spell = sSpellStore.LookupEntry(VDS.v_spells[j]);
+                if(!j_spell)
+                {
+                    sLog.outErrorDb("Spell %u listed in `vehicle_data` does not exist, skipped",VDS.v_spells[j]);
+                    VDS.v_spells[j] = 0;
+                }
+            }
+        }
+        if(VDS.req_aura)
+        {
+            SpellEntry const* i_spell = sSpellStore.LookupEntry(VDS.req_aura);
+            if(!i_spell)
+            {
+                sLog.outErrorDb("Spell %u listed in `vehicle_data` does not exist, skipped",VDS.req_aura);
+                VDS.req_aura = 0;
+            }
+        }
+
+        mVehicleData[v_entry] = VDS;
+        ++count;
+    }
+    while (result->NextRow());
+
+    delete result;
+
+    sLog.outString();
+    sLog.outString( ">> Loaded %u vehicle data", count );
+}
+
+void ObjectMgr::LoadVehicleSeatData()
+{
+    mVehicleSeatData.clear();
+
+    QueryResult *result = WorldDatabase.Query("SELECT seat,flags FROM vehicle_seat_data");
+
+    if( !result )
+    {
+        barGoLink bar( 1 );
+
+        bar.step();
+
+        sLog.outString();
+        sLog.outString( ">> Loaded 0 vehicle seat data" );
+        sLog.outErrorDb("`vehicle_seat_data` table is empty!");
+        return;
+    }
+    uint32 count = 0;
+
+    barGoLink bar( result->GetRowCount() );
+    do
+    {
+        bar.step();
+
+        Field *fields = result->Fetch();
+        uint32 entry  = fields[0].GetUInt32();
+        uint32 flag   = fields[1].GetUInt32();
+
+        VehicleSeatEntry const *vsInfo = sVehicleSeatStore.LookupEntry(entry);
+        if(!vsInfo)
+        {
+            sLog.outErrorDb("Vehicle seat %u listed in `vehicle_seat_data` does not exist",entry);
+            continue;
+        }
+
+        mVehicleSeatData[entry] = flag;
+        ++count;
+    }
+    while (result->NextRow());
+
+    delete result;
+
+    sLog.outString();
+    sLog.outString( ">> Loaded %u vehicle seat data", count );
+}
+
 Quest const* GetQuestTemplateStore(uint32 entry)
 {
     return sObjectMgr.GetQuestTemplate(entry);
diff --git a/src/game/ObjectMgr.h b/src/game/ObjectMgr.h
index 4442f56..f27a49c 100644
--- a/src/game/ObjectMgr.h
+++ b/src/game/ObjectMgr.h
@@ -370,6 +370,18 @@ extern LanguageDesc lang_description[LANGUAGES_COUNT];
 MANGOS_DLL_SPEC LanguageDesc const* GetLanguageDescByID(uint32 lang);
 
 class PlayerDumpReader;
+// vehicle system
+#define MAX_VEHICLE_SPELLS 6
+
+struct VehicleDataStructure
+{
+    uint32 v_flags;                                         // vehicle flags, see enum CustomVehicleFLags
+    uint32 v_spells[MAX_VEHICLE_SPELLS];                    // spells
+    uint32 req_aura;                                        // requieres aura on player to enter (eg. in wintergrasp)
+};
+
+typedef UNORDERED_MAP<uint32, VehicleDataStructure> VehicleDataMap;
+typedef std::map<uint32,uint32> VehicleSeatDataMap;
 
 class ObjectMgr
 {
@@ -637,6 +649,9 @@ class ObjectMgr
         void LoadVendors();
         void LoadTrainerSpell();
 
+        void LoadVehicleData();
+        void LoadVehicleSeatData();
+
         std::string GeneratePetName(uint32 entry);
         uint32 GetBaseXP(uint32 level) const;
         uint32 GetXPForLevel(uint32 level) const;
@@ -865,6 +880,24 @@ class ObjectMgr
 
         int GetOrNewIndexForLocale(LocaleConstant loc);
 
+        VehicleDataMap mVehicleData;
+        VehicleSeatDataMap mVehicleSeatData;
+
+        uint32 GetSeatFlags(uint32 seatid)
+        {
+            VehicleSeatDataMap::iterator i = mVehicleSeatData.find(seatid);
+            if(i == mVehicleSeatData.end())
+                return NULL;
+            else
+                return i->second;
+        }
+        VehicleDataStructure const* GetVehicleData(uint32 entry) const
+        {
+            VehicleDataMap::const_iterator itr = mVehicleData.find(entry);
+            if(itr==mVehicleData.end()) return NULL;
+            return &itr->second;
+        }
+
         SpellClickInfoMapBounds GetSpellClickInfoMapBounds(uint32 creature_id) const
         {
             return SpellClickInfoMapBounds(mSpellClickInfoMap.lower_bound(creature_id),mSpellClickInfoMap.upper_bound(creature_id));
@@ -900,6 +933,7 @@ class ObjectMgr
         // first free low guid for selected guid type
         uint32 m_hiCharGuid;
         uint32 m_hiCreatureGuid;
+		uint32 m_hiVehicleGuid;
         uint32 m_hiItemGuid;
         uint32 m_hiGoGuid;
         uint32 m_hiCorpseGuid;
@@ -959,6 +993,7 @@ class ObjectMgr
         void CheckScripts(ScriptMapMap const& scripts,std::set<int32>& ids);
         void LoadCreatureAddons(SQLStorage& creatureaddons, char const* entryName, char const* comment);
         void ConvertCreatureAddonAuras(CreatureDataAddon* addon, char const* table, char const* guidEntryStr);
+        void ConvertCreatureAddonPassengers(CreatureDataAddon* addon, char const* table, char const* guidEntryStr);
         void LoadQuestRelationsHelper(QuestRelations& map,char const* table);
 
         MailLevelRewardMap m_mailLevelRewardMap;
diff --git a/src/game/Opcodes.cpp b/src/game/Opcodes.cpp
index 8d84bd2..f554867 100644
--- a/src/game/Opcodes.cpp
+++ b/src/game/Opcodes.cpp
@@ -1168,10 +1168,10 @@ OpcodeHandler opcodeTable[NUM_MSG_TYPES] =
     /*0x473*/ { "CMSG_CHAR_CUSTOMIZE",                          STATUS_AUTHED,   &WorldSession::HandleCharCustomize             },
     /*0x474*/ { "SMSG_CHAR_CUSTOMIZE",                          STATUS_NEVER,    &WorldSession::Handle_ServerSide               },
     /*0x475*/ { "SMSG_PET_RENAMEABLE",                          STATUS_NEVER,    &WorldSession::Handle_ServerSide               },
-    /*0x476*/ { "CMSG_REQUEST_VEHICLE_EXIT",                    STATUS_NEVER,    &WorldSession::Handle_NULL                     },
-    /*0x477*/ { "CMSG_REQUEST_VEHICLE_PREV_SEAT",               STATUS_NEVER,    &WorldSession::Handle_NULL                     },
-    /*0x478*/ { "CMSG_REQUEST_VEHICLE_NEXT_SEAT",               STATUS_NEVER,    &WorldSession::Handle_NULL                     },
-    /*0x479*/ { "CMSG_REQUEST_VEHICLE_SWITCH_SEAT",             STATUS_NEVER,    &WorldSession::Handle_NULL                     },
+    /*0x476*/ { "CMSG_REQUEST_VEHICLE_EXIT",                    STATUS_LOGGEDIN, &WorldSession::HandleRequestVehicleExit        },
+    /*0x477*/ { "CMSG_REQUEST_VEHICLE_PREV_SEAT",               STATUS_LOGGEDIN, &WorldSession::HandleRequestVehiclePrevSeat    },
+    /*0x478*/ { "CMSG_REQUEST_VEHICLE_NEXT_SEAT",               STATUS_LOGGEDIN, &WorldSession::HandleRequestVehicleNextSeat    },
+    /*0x479*/ { "CMSG_REQUEST_VEHICLE_SWITCH_SEAT",             STATUS_LOGGEDIN, &WorldSession::HandleRequestVehicleSwitchSeat  },
     /*0x47A*/ { "CMSG_PET_LEARN_TALENT",                        STATUS_LOGGEDIN, &WorldSession::HandlePetLearnTalent            },
     /*0x47B*/ { "CMSG_PET_UNLEARN_TALENTS",                     STATUS_NEVER,    &WorldSession::Handle_NULL                     },
     /*0x47C*/ { "SMSG_SET_PHASE_SHIFT",                         STATUS_NEVER,    &WorldSession::Handle_ServerSide               },
@@ -1205,7 +1205,7 @@ OpcodeHandler opcodeTable[NUM_MSG_TYPES] =
     /*0x498*/ { "SMSG_SERVER_FIRST_ACHIEVEMENT",                STATUS_NEVER,    &WorldSession::Handle_ServerSide               },
     /*0x499*/ { "SMSG_PET_LEARNED_SPELL",                       STATUS_NEVER,    &WorldSession::Handle_ServerSide               },
     /*0x49A*/ { "SMSG_PET_REMOVED_SPELL",                       STATUS_NEVER,    &WorldSession::Handle_ServerSide               },
-    /*0x49B*/ { "CMSG_CHANGE_SEATS_ON_CONTROLLED_VEHICLE",      STATUS_NEVER,    &WorldSession::Handle_NULL                     },
+    /*0x49B*/ { "CMSG_CHANGE_SEATS_ON_CONTROLLED_VEHICLE",      STATUS_LOGGEDIN, &WorldSession::HandleChangeSeatsOnControlledVehicle},                    },
     /*0x49C*/ { "CMSG_HEARTH_AND_RESURRECT",                    STATUS_LOGGEDIN, &WorldSession::HandleHearthandResurrect        },
     /*0x49D*/ { "SMSG_ON_CANCEL_EXPECTED_RIDE_VEHICLE_AURA",    STATUS_NEVER,    &WorldSession::Handle_ServerSide               },
     /*0x49E*/ { "SMSG_CRITERIA_DELETED",                        STATUS_NEVER,    &WorldSession::Handle_ServerSide               },
diff --git a/src/game/Pet.cpp b/src/game/Pet.cpp
index 9881020..294439b 100644
--- a/src/game/Pet.cpp
+++ b/src/game/Pet.cpp
@@ -39,7 +39,7 @@ char const* petTypeSuffix[MAX_PET_TYPE] =
 
 Pet::Pet(PetType type) :
 Creature(CREATURE_SUBTYPE_PET), m_removed(false), m_petType(type), m_happinessTimer(7500), m_duration(0), m_resetTalentsCost(0),
-m_bonusdamage(0), m_resetTalentsTime(0), m_usedTalentCount(0), m_auraUpdateMask(0), m_loading(false),
+m_bonusdamage(0), m_resetTalentsTime(0), m_usedTalentCount(0), m_loading(false),
 m_declinedname(NULL), m_petModeFlags(PET_MODE_DEFAULT)
 {
     m_name = "Pet";
diff --git a/src/game/Pet.h b/src/game/Pet.h
index 6852242..75ae7d6 100644
--- a/src/game/Pet.h
+++ b/src/game/Pet.h
@@ -235,10 +235,6 @@ class Pet : public Creature
         time_t  m_resetTalentsTime;
         uint32  m_usedTalentCount;
 
-        const uint64& GetAuraUpdateMask() const { return m_auraUpdateMask; }
-        void SetAuraUpdateMask(uint8 slot) { m_auraUpdateMask |= (uint64(1) << slot); }
-        void ResetAuraUpdateMask() { m_auraUpdateMask = 0; }
-
         // overwrite Creature function for name localization back to WorldObject version without localization
         const char* GetNameForLocaleIdx(int32 locale_idx) const { return WorldObject::GetNameForLocaleIdx(locale_idx); }
 
@@ -250,7 +246,6 @@ class Pet : public Creature
         PetType m_petType;
         int32   m_duration;                                 // time until unsummon (used mostly for summoned guardians and not used for controlled pets)
         int32   m_bonusdamage;
-        uint64  m_auraUpdateMask;
         bool    m_loading;
 
         DeclinedName *m_declinedname;
diff --git a/src/game/PetHandler.cpp b/src/game/PetHandler.cpp
index 82e010c..073ec75 100644
--- a/src/game/PetHandler.cpp
+++ b/src/game/PetHandler.cpp
@@ -286,7 +286,7 @@ void WorldSession::HandlePetNameQuery( WorldPacket & recv_data )
 
 void WorldSession::SendPetNameQuery( uint64 petguid, uint32 petnumber)
 {
-    Creature* pet = _player->GetMap()->GetCreatureOrPetOrVehicle(petguid);
+    Creature* pet = ObjectAccessor::GetCreatureOrPetOrVehicle(*_player, petguid);
     if(!pet || !pet->GetCharmInfo() || pet->GetCharmInfo()->GetPetNumber() != petnumber)
         return;
 
@@ -318,7 +318,12 @@ void WorldSession::HandlePetSetAction( WorldPacket & recv_data )
 
     recv_data >> petguid;
 
-    Creature* pet = _player->GetMap()->GetCreatureOrPetOrVehicle(petguid);
+    // FIXME: charmed case
+    //Pet* pet = ObjectAccessor::Instance().GetPet(petguid);
+    if(ObjectAccessor::FindPlayer(petguid))
+        return;
+
+    Creature* pet = ObjectAccessor::GetCreatureOrPetOrVehicle(*_player, petguid);
 
     if(!pet || (pet != _player->GetPet() && pet != _player->GetCharm()))
     {
@@ -506,7 +511,8 @@ void WorldSession::HandlePetAbandon( WorldPacket & recv_data )
         return;
 
     // pet/charmed
-    if (Creature* pet = _player->GetMap()->GetCreatureOrPetOrVehicle(guid))
+    Creature* pet = ObjectAccessor::GetCreatureOrPetOrVehicle(*_player, guid);
+    if(pet)
     {
         if(pet->isPet())
         {
@@ -560,29 +566,32 @@ void WorldSession::HandlePetSpellAutocastOpcode( WorldPacket& recvPacket )
     uint8  state;                                           //1 for on, 0 for off
     recvPacket >> guid >> spellid >> state;
 
-    if(!_player->GetPet() && !_player->GetCharm())
+    if (!_player->GetPet() && !_player->GetCharm())
         return;
 
-    Creature* pet = _player->GetMap()->GetCreatureOrPetOrVehicle(guid);
+    if(ObjectAccessor::FindPlayer(guid))
+        return;
 
-    if(!pet || (pet != _player->GetPet() && pet != _player->GetCharm()))
+    Creature* pet=ObjectAccessor::GetCreatureOrPetOrVehicle(*_player,guid);
+
+    if (!pet || (pet != _player->GetPet() && pet != _player->GetCharm()))
     {
         sLog.outError( "HandlePetSpellAutocastOpcode.Pet %u isn't pet of player %s .", uint32(GUID_LOPART(guid)),GetPlayer()->GetName() );
         return;
     }
 
     // do not add not learned spells/ passive spells
-    if(!pet->HasSpell(spellid) || IsPassiveSpell(spellid))
+    if (!pet->HasSpell(spellid) || IsPassiveSpell(spellid))
         return;
 
     CharmInfo *charmInfo = pet->GetCharmInfo();
-    if(!charmInfo)
+    if (!charmInfo)
     {
         sLog.outError("WorldSession::HandlePetSpellAutocastOpcod: object (GUID: %u TypeId: %u) is considered pet-like but doesn't have a charminfo!", pet->GetGUIDLow(), pet->GetTypeId());
         return;
     }
 
-    if(pet->isCharmed())
+    if (pet->isCharmed())
                                                             //state can be used as boolean
         pet->GetCharmInfo()->ToggleCreatureAutocast(spellid, state);
     else
@@ -607,7 +616,10 @@ void WorldSession::HandlePetCastSpellOpcode( WorldPacket& recvPacket )
     if (!_player->GetPet() && !_player->GetCharm())
         return;
 
-    Creature* pet = _player->GetMap()->GetCreatureOrPetOrVehicle(guid);
+    if (GUID_HIPART(guid) == HIGHGUID_PLAYER)
+        return;
+
+    Creature* pet = ObjectAccessor::GetCreatureOrPetOrVehicle(*_player,guid);
 
     if (!pet || (pet != _player->GetPet() && pet!= _player->GetCharm()))
     {
@@ -630,7 +642,7 @@ void WorldSession::HandlePetCastSpellOpcode( WorldPacket& recvPacket )
         return;
 
     SpellCastTargets targets;
-    if (!targets.read(&recvPacket,pet))
+    if (!targets.read(&recvPacket,pet,spellInfo))
         return;
 
     pet->clearUnitState(UNIT_STAT_MOVING);
diff --git a/src/game/Player.cpp b/src/game/Player.cpp
index c871be8..41dbc84 100644
--- a/src/game/Player.cpp
+++ b/src/game/Player.cpp
@@ -363,7 +363,6 @@ Player::Player (WorldSession *session): Unit(), m_achievementMgr(this), m_reputa
     // group is initialized in the reference constructor
     SetGroupInvite(NULL);
     m_groupUpdateMask = 0;
-    m_auraUpdateMask = 0;
 
     duel = NULL;
 
@@ -489,6 +488,7 @@ Player::Player (WorldSession *session): Unit(), m_achievementMgr(this), m_reputa
     m_summon_z = 0.0f;
 
     m_mover = this;
+    m_mover_in_queve = NULL;
 
     m_miniPet = 0;
     m_contestedPvPTimer = 0;
@@ -1651,6 +1651,7 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati
         m_transport = NULL;
         m_movementInfo.SetTransportData(0, 0.0f, 0.0f, 0.0f, 0.0f, 0, -1);
     }
+    ExitVehicle();
 
     // The player was ported to another map and looses the duel immediately.
     // We have to perform this check before the teleport, otherwise the
@@ -2131,7 +2132,7 @@ Creature* Player::GetNPCIfCanInteractWith(uint64 guid, uint32 npcflagmask)
         return NULL;
 
     // exist (we need look pets also for some interaction (quest/etc)
-    Creature *unit = GetMap()->GetCreatureOrPetOrVehicle(guid);
+    Creature *unit = ObjectAccessor::GetCreatureOrPetOrVehicle(*this,guid);
     if (!unit)
         return NULL;
 
@@ -7887,6 +7888,9 @@ void Player::SendInitWorldStates(uint32 zoneid, uint32 areaid)
         case 3703:
             NumberOfFields = 11;
             break;
+        case 4384:
+            NumberOfFields = 30;
+            break;
         default:
             NumberOfFields = 12;
             break;
@@ -8205,6 +8209,41 @@ void Player::SendInitWorldStates(uint32 zoneid, uint32 areaid)
             break;
         case 3703:                                          // Shattrath City
             break;
+        case 4384:                                          // SA
+            /*if (bg && bg->GetTypeID() == BATTLEGROUND_SA)
+                bg->FillInitialWorldStates(data);
+            else
+            {*/
+                // 1-3 A defend, 4-6 H defend, 7-9 unk defend, 1 - ok, 2 - half destroyed, 3 - destroyed
+                data << uint32(0xf09) << uint32(0x4);       // 7  3849 Gate of Temple
+                data << uint32(0xe36) << uint32(0x4);       // 8  3638 Gate of Yellow Moon
+                data << uint32(0xe27) << uint32(0x4);       // 9  3623 Gate of Green Emerald
+                data << uint32(0xe24) << uint32(0x4);       // 10 3620 Gate of Blue Sapphire
+                data << uint32(0xe21) << uint32(0x4);       // 11 3617 Gate of Red Sun
+                data << uint32(0xe1e) << uint32(0x4);       // 12 3614 Gate of Purple Ametyst
+
+                data << uint32(0xdf3) << uint32(0x0);       // 13 3571 bonus timer (1 - on, 0 - off)
+                data << uint32(0xded) << uint32(0x0);       // 14 3565 Horde Attacker
+                data << uint32(0xdec) << uint32(0x1);       // 15 3564 Alliance Attacker
+                // End Round (timer), better explain this by example, eg. ends in 19:59 -> A:BC
+                data << uint32(0xde9) << uint32(0x9);       // 16 3561 C
+                data << uint32(0xde8) << uint32(0x5);       // 17 3560 B
+                data << uint32(0xde7) << uint32(0x19);      // 18 3559 A
+                data << uint32(0xe35) << uint32(0x1);       // 19 3637 East g - Horde control
+                data << uint32(0xe34) << uint32(0x1);       // 20 3636 West g - Horde control
+                data << uint32(0xe33) << uint32(0x1);       // 21 3635 South g - Horde control
+                data << uint32(0xe32) << uint32(0x0);       // 22 3634 East g - Alliance control
+                data << uint32(0xe31) << uint32(0x0);       // 23 3633 West g - Alliance control
+                data << uint32(0xe30) << uint32(0x0);       // 24 3632 South g - Alliance control
+                data << uint32(0xe2f) << uint32(0x1);       // 25 3631 Chamber of Ancients - Horde control
+                data << uint32(0xe2e) << uint32(0x0);       // 26 3630 Chamber of Ancients - Alliance control
+                data << uint32(0xe2d) << uint32(0x0);       // 27 3629 Beach1 - Horde control
+                data << uint32(0xe2c) << uint32(0x0);       // 28 3628 Beach2 - Horde control
+                data << uint32(0xe2b) << uint32(0x1);       // 29 3627 Beach1 - Alliance control
+                data << uint32(0xe2a) << uint32(0x1);       // 30 3626 Beach2 - Alliance control
+                // and many unks...
+            //}
+            break;
         default:
             data << uint32(0x914) << uint32(0x0);           // 7
             data << uint32(0x913) << uint32(0x0);           // 8
@@ -12761,7 +12800,8 @@ void Player::PrepareQuestMenu( uint64 guid )
     QuestRelations* pObjectQIR;
 
     // pets also can have quests
-    if (Creature *pCreature = GetMap()->GetCreatureOrPetOrVehicle(guid))
+    Creature *pCreature = ObjectAccessor::GetCreatureOrPetOrVehicle(*this, guid);
+    if( pCreature )
     {
         pObject = (Object*)pCreature;
         pObjectQR  = &sObjectMgr.mCreatureQuestRelations;
@@ -12855,7 +12895,8 @@ void Player::SendPreparedQuest(uint64 guid)
         std::string title = "";
 
         // need pet case for some quests
-        if (Creature *pCreature = GetMap()->GetCreatureOrPetOrVehicle(guid))
+        Creature *pCreature = ObjectAccessor::GetCreatureOrPetOrVehicle(*this,guid);
+        if (pCreature)
         {
             uint32 textid = GetGossipTextId(pCreature);
 
@@ -12919,7 +12960,8 @@ Quest const * Player::GetNextQuest( uint64 guid, Quest const *pQuest )
     QuestRelations* pObjectQR;
     QuestRelations* pObjectQIR;
 
-    if (Creature *pCreature = GetMap()->GetCreatureOrPetOrVehicle(guid))
+    Creature *pCreature = ObjectAccessor::GetCreatureOrPetOrVehicle(*this,guid);
+    if( pCreature )
     {
         pObject = (Object*)pCreature;
         pObjectQR  = &sObjectMgr.mCreatureQuestRelations;
@@ -17675,7 +17717,10 @@ void Player::HandleStealthedUnitsDetection()
                 // target aura duration for caster show only if target exist at caster client
                 // send data at target visibility change (adding to client)
                 if((*i)!=this && (*i)->isType(TYPEMASK_UNIT))
+                {
                     SendAurasForTarget(*i);
+                    BuildVehicleInfo(*i);
+                }
             }
         }
         else
@@ -17710,7 +17755,7 @@ bool Player::ActivateTaxiPathTo(std::vector<uint32> const& nodes, Creature* npc
     if(npc)
     {
         // not let cheating with start flight mounted
-        if(IsMounted())
+        if(IsMounted() || GetVehicleGUID())
         {
             WorldPacket data(SMSG_ACTIVATETAXIREPLY, 4);
             data << uint32(ERR_TAXIPLAYERALREADYMOUNTED);
@@ -17739,6 +17784,7 @@ bool Player::ActivateTaxiPathTo(std::vector<uint32> const& nodes, Creature* npc
     else
     {
         RemoveSpellsCausingAura(SPELL_AURA_MOUNTED);
+        ExitVehicle();
 
         if( m_ShapeShiftFormSpellId && m_form != FORM_BATTLESTANCE && m_form != FORM_BERSERKERSTANCE && m_form != FORM_DEFENSIVESTANCE && m_form != FORM_SHADOW )
             RemoveAurasDueToSpell(m_ShapeShiftFormSpellId);
@@ -18864,7 +18910,10 @@ void Player::UpdateVisibilityOf(WorldObject const* viewPoint, WorldObject* targe
             // target aura duration for caster show only if target exist at caster client
             // send data at target visibility change (adding to client)
             if(target!=this && target->isType(TYPEMASK_UNIT))
+            {
                 SendAurasForTarget((Unit*)target);
+                BuildVehicleInfo((Unit*)target);
+            }
 
             if(target->GetTypeId()==TYPEID_UNIT && ((Creature*)target)->isAlive())
                 ((Creature*)target)->SendMonsterMoveWithSpeedToCurrentDestination(this);
@@ -18933,13 +18982,22 @@ void Player::InitPrimaryProfessions()
 void Player::SendComboPoints()
 {
     Unit *combotarget = ObjectAccessor::GetUnit(*this, m_comboTarget);
-    if (combotarget)
-    {
-        WorldPacket data(SMSG_UPDATE_COMBO_POINTS, combotarget->GetPackGUID().size()+1);
-        data.append(combotarget->GetPackGUID());
-        data << uint8(m_comboPoints);
-        GetSession()->SendPacket(&data);
-    }
+    if (!combotarget)
+        return;
+
+    WorldPacket data;
+    if(!GetVehicleGUID())
+        data.Initialize(SMSG_UPDATE_COMBO_POINTS, combotarget->GetPackGUID().size()+1);
+    else{
+       if(Unit *vehicle = ObjectAccessor::GetUnit(*this, GetVehicleGUID()))
+       {
+           data.Initialize(SMSG_PET_UPDATE_COMBO_POINTS, vehicle->GetPackGUID().size()+combotarget->GetPackGUID().size()+1);
+           data.append(vehicle->GetPackGUID());
+       }else return;
+    }
+    data.append(combotarget->GetPackGUID());
+    data << uint8(m_comboPoints);
+    GetSession()->SendPacket(&data);
 }
 
 void Player::AddComboPoints(Unit* target, int8 count)
@@ -19058,10 +19116,18 @@ void Player::SendInitialPacketsBeforeAddToMap()
         m_movementInfo.AddMovementFlag(MOVEFLAG_FLYING);
 
     m_mover = this;
+    m_mover_in_queve = NULL;
 }
 
 void Player::SendInitialPacketsAfterAddToMap()
 {
+    if(getClass() == CLASS_DEATH_KNIGHT)
+        ResyncRunes(MAX_RUNES);
+
+    WorldPacket data0(SMSG_SET_PHASE_SHIFT, 4);
+    data0 << uint32(GetPhaseMask());
+    GetSession()->SendPacket(&data0);
+
     // update zone
     uint32 newzone, newarea;
     GetZoneAndAreaId(newzone,newarea);
@@ -19101,6 +19167,14 @@ void Player::SendInitialPacketsAfterAddToMap()
         SendMessageToSet(&data2,true);
     }
 
+    if(GetVehicleGUID())
+    {
+        WorldPacket data3(SMSG_FORCE_MOVE_ROOT, 10);
+        data3.append(GetPackGUID());
+        data3 << (uint32)((m_SeatData.s_flags & SF_CAN_CAST) ? 2 : 0);
+        SendMessageToSet(&data3,true);
+    }
+
     SendAurasForTarget(this);
     SendEnchantmentDurations();                             // must be after add to map
     SendItemDurations();                                    // must be after add to map
@@ -19115,7 +19189,7 @@ void Player::SendUpdateToOutOfRangeGroupMembers()
 
     m_groupUpdateMask = GROUP_UPDATE_FLAG_NONE;
     m_auraUpdateMask = 0;
-    if(Pet *pet = GetPet())
+    if(Unit *pet = GetCharmOrPet())
         pet->ResetAuraUpdateMask();
 }
 
@@ -19367,7 +19441,10 @@ void Player::SendAurasForTarget(Unit *target)
 
                     if(!(auraFlags & AFLAG_NOT_CASTER))
                     {
-                        data << uint8(0);                   // packed GUID of someone (caster?)
+                        if(aura->GetCaster())
+                            data.append(aura->GetCaster()->GetPackGUID());
+                        else
+                            data << uint8(0);
                     }
 
                     if(auraFlags & AFLAG_DURATION)          // include aura duration
@@ -19534,7 +19611,7 @@ void Player::UpdateForQuestWorldObjects()
         }
         else if(IS_CREATURE_GUID(*itr) || IS_VEHICLE_GUID(*itr))
         {
-            Creature *obj = GetMap()->GetCreatureOrPetOrVehicle(*itr);
+            Creature *obj = ObjectAccessor::GetCreatureOrPetOrVehicle(*this, *itr);
             if(!obj)
                 continue;
 
@@ -19819,6 +19896,8 @@ bool Player::RewardPlayerAndGroupAtKill(Unit* pVictim)
         {
             /// not get Xp in PvP or no not gray players in group
             xp = (PvP || !not_gray_member_with_max_level) ? 0 : MaNGOS::XP::Gain(not_gray_member_with_max_level, pVictim);
+            if(GetVehicleGUID() && !(m_SeatData.v_flags & VF_GIVE_EXP))
+                xp = 0;
 
             /// skip in check PvP case (for speed, not used)
             bool is_raid = PvP ? false : sMapStore.LookupEntry(GetMapId())->IsRaid() && pGroup->isRaidGroup();
@@ -19872,6 +19951,8 @@ bool Player::RewardPlayerAndGroupAtKill(Unit* pVictim)
     else                                                    // if (!pGroup)
     {
         xp = PvP ? 0 : MaNGOS::XP::Gain(this, pVictim);
+        if(GetVehicleGUID() && !(m_SeatData.v_flags & VF_GIVE_EXP))
+            xp = 0;
 
         // honor can be in PvP and !PvP (racial leader) cases
         if(RewardHonor(pVictim,1))
@@ -20354,96 +20435,28 @@ void Player::ApplyGlyphs(bool apply)
         ApplyGlyph(i,apply);
 }
 
-void Player::EnterVehicle(Vehicle *vehicle)
-{
-    VehicleEntry const *ve = sVehicleStore.LookupEntry(vehicle->GetVehicleId());
-    if(!ve)
-        return;
-
-    VehicleSeatEntry const *veSeat = sVehicleSeatStore.LookupEntry(ve->m_seatID[0]);
-    if(!veSeat)
-        return;
-
-    vehicle->SetCharmerGUID(GetGUID());
-    vehicle->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK);
-    vehicle->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED);
-    vehicle->setFaction(getFaction());
-
-    SetCharm(vehicle);                                      // charm
-    SetFarSightGUID(vehicle->GetGUID());                    // set view
-
-    SetClientControl(vehicle, 1);                           // redirect controls to vehicle
-    SetMover(vehicle);
-
-    WorldPacket data(SMSG_ON_CANCEL_EXPECTED_RIDE_VEHICLE_AURA, 0);
-    GetSession()->SendPacket(&data);
-
-    data.Initialize(MSG_MOVE_TELEPORT_ACK, 30);
-    data.append(GetPackGUID());
-    data << uint32(0);                                      // counter?
-    data << uint32(MOVEFLAG_ONTRANSPORT);                   // transport
-    data << uint16(0);                                      // special flags
-    data << uint32(getMSTime());                            // time
-    data << vehicle->GetPositionX();                        // x
-    data << vehicle->GetPositionY();                        // y
-    data << vehicle->GetPositionZ();                        // z
-    data << vehicle->GetOrientation();                      // o
-    // transport part, TODO: load/calculate seat offsets
-    data << uint64(vehicle->GetGUID());                     // transport guid
-    data << float(veSeat->m_attachmentOffsetX);             // transport offsetX
-    data << float(veSeat->m_attachmentOffsetY);             // transport offsetY
-    data << float(veSeat->m_attachmentOffsetZ);             // transport offsetZ
-    data << float(0);                                       // transport orientation
-    data << uint32(getMSTime());                            // transport time
-    data << uint8(0);                                       // seat
-    // end of transport part
-    data << uint32(0);                                      // fall time
-    GetSession()->SendPacket(&data);
-
-    data.Initialize(SMSG_PET_SPELLS, 8+2+4+4+4*MAX_UNIT_ACTION_BAR_INDEX+1+1);
-    data << uint64(vehicle->GetGUID());
-    data << uint16(0);
-    data << uint32(0);
-    data << uint32(0x00000101);
-
-    for(uint32 i = 0; i < 10; ++i)
-        data << uint16(0) << uint8(0) << uint8(i+8);
-
-    data << uint8(0);
-    data << uint8(0);
-    GetSession()->SendPacket(&data);
-}
-
-void Player::ExitVehicle(Vehicle *vehicle)
+void Player::SendEnterVehicle(Vehicle *vehicle)
 {
-    vehicle->SetCharmerGUID(0);
-    vehicle->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK);
-    vehicle->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED);
-    vehicle->setFaction((GetTeam() == ALLIANCE) ? vehicle->GetCreatureInfo()->faction_A : vehicle->GetCreatureInfo()->faction_H);
+    m_movementInfo.AddMovementFlag(MOVEFLAG_ONTRANSPORT);
+    m_movementInfo.AddMovementFlag(MOVEFLAG_ROOT);
 
-    SetCharm(NULL);
-    SetFarSightGUID(0);
-
-    SetClientControl(vehicle, 0);
-    SetMover(NULL);
+    if(m_transport)                                         // if we were on a transport, leave
+    {
+        m_transport->RemovePassenger(this);
+        m_transport = NULL;
+    }
+    // vehicle is our transport from now, if we get to zeppelin or boat
+    // with vehicle, ONLY my vehicle will be passenger on that transport
+    // player ----> vehicle ----> zeppelin
 
-    WorldPacket data(MSG_MOVE_TELEPORT_ACK, 30);
-    data.append(GetPackGUID());
-    data << uint32(0);                                      // counter?
-    data << uint32(MOVEFLAG_ROOT);                          // fly unk
-    data << uint16(MOVEFLAG2_UNK4);                         // special flags
-    data << uint32(getMSTime());                            // time
-    data << vehicle->GetPositionX();                        // x
-    data << vehicle->GetPositionY();                        // y
-    data << vehicle->GetPositionZ();                        // z
-    data << vehicle->GetOrientation();                      // o
-    data << uint32(0);                                      // fall time
+    WorldPacket data(SMSG_BREAK_TARGET, 8);
+    data.append(vehicle->GetPackGUID());
     GetSession()->SendPacket(&data);
 
-    RemovePetActionBar();
-
-    // maybe called at dummy aura remove?
-    // CastSpell(this, 45472, true);                        // Parachute
+    /*data.Initialize(SMSG_UNKNOWN_1191, 12);
+    data << uint64(GetGUID());
+    data << uint64(vehicle->GetVehicleId());                      // not sure
+    SendMessageToSet(&data, true);*/
 }
 
 bool Player::isTotalImmune()
@@ -20508,7 +20521,8 @@ void Player::ConvertRune(uint8 index, RuneType newType)
 
 void Player::ResyncRunes(uint8 count)
 {
-    WorldPacket data(SMSG_RESYNC_RUNES, count * 2);
+    WorldPacket data(SMSG_RESYNC_RUNES, 4 + count * 2);
+    data << uint32(count + 1);
     for(uint32 i = 0; i < count; ++i)
     {
         data << uint8(GetCurrentRune(i));                   // rune type
diff --git a/src/game/Player.h b/src/game/Player.h
index 75ab413..04140fa 100644
--- a/src/game/Player.h
+++ b/src/game/Player.h
@@ -2124,6 +2124,10 @@ class MANGOS_DLL_SPEC Player : public Unit
         bool HasMovementFlag(MovementFlags f) const;        // for script access to m_movementInfo.HasMovementFlag
         void UpdateFallInformationIfNeed(MovementInfo const& minfo,uint16 opcode);
         Unit *m_mover;
+        Unit *m_mover_in_queve;
+
+        void SetMoverInQueve(Unit* pet) {m_mover_in_queve = pet ? pet : this; }
+
         void SetFallInformation(uint32 time, float z)
         {
             m_lastFallTime = time;
@@ -2143,8 +2147,8 @@ class MANGOS_DLL_SPEC Player : public Unit
         void SetClientControl(Unit* target, uint8 allowMove);
         void SetMover(Unit* target) { m_mover = target ? target : this; }
 
-        void EnterVehicle(Vehicle *vehicle);
-        void ExitVehicle(Vehicle *vehicle);
+        // vehicle system
+        void SendEnterVehicle(Vehicle *vehicle);
 
         uint64 GetFarSight() const { return GetUInt64Value(PLAYER_FARSIGHT); }
         void SetFarSightGUID(uint64 guid);
@@ -2245,8 +2249,6 @@ class MANGOS_DLL_SPEC Player : public Unit
         uint8 GetSubGroup() const { return m_group.getSubGroup(); }
         uint32 GetGroupUpdateFlag() const { return m_groupUpdateMask; }
         void SetGroupUpdateFlag(uint32 flag) { m_groupUpdateMask |= flag; }
-        const uint64& GetAuraUpdateMask() const { return m_auraUpdateMask; }
-        void SetAuraUpdateMask(uint8 slot) { m_auraUpdateMask |= (uint64(1) << slot); }
         Player* GetNextRandomRaidMember(float radius);
         PartyResult CanUninviteFromGroup() const;
         // BattleGround Group System
@@ -2495,7 +2497,6 @@ class MANGOS_DLL_SPEC Player : public Unit
         GroupReference m_originalGroup;
         Group *m_groupInvite;
         uint32 m_groupUpdateMask;
-        uint64 m_auraUpdateMask;
 
         uint64 m_miniPet;
 
diff --git a/src/game/QuestHandler.cpp b/src/game/QuestHandler.cpp
index fdac5cb..2ed9257 100644
--- a/src/game/QuestHandler.cpp
+++ b/src/game/QuestHandler.cpp
@@ -647,7 +647,7 @@ void WorldSession::HandleQuestgiverStatusMultipleQuery(WorldPacket& /*recvPacket
         if (IS_CREATURE_OR_PET_GUID(*itr))
         {
             // need also pet quests case support
-            Creature *questgiver = GetPlayer()->GetMap()->GetCreatureOrPetOrVehicle(*itr);
+            Creature *questgiver = ObjectAccessor::GetCreatureOrPetOrVehicle(*GetPlayer(),*itr);
             if(!questgiver || questgiver->IsHostileTo(_player))
                 continue;
             if(!questgiver->HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER))
diff --git a/src/game/ReactorAI.cpp b/src/game/ReactorAI.cpp
index 2ea08d4..0b9bdd3 100644
--- a/src/game/ReactorAI.cpp
+++ b/src/game/ReactorAI.cpp
@@ -116,6 +116,7 @@ ReactorAI::EnterEvadeMode()
         DEBUG_LOG("Creature stopped attacking, victim %s [guid=%u]", victim->isAlive() ? "out run him" : "is dead", m_creature->GetGUIDLow());
     }
 
+    m_creature->ExitVehicle();
     m_creature->RemoveAllAuras();
     m_creature->DeleteThreatList();
     i_victimGuid = 0;
diff --git a/src/game/SharedDefines.h b/src/game/SharedDefines.h
index b2b62f0..382132a 100644
--- a/src/game/SharedDefines.h
+++ b/src/game/SharedDefines.h
@@ -2446,6 +2446,29 @@ enum DiminishingGroup
     DIMINISHING_LIMITONLY
 };
 
+
+/* NOTE : vehicles and seats has their own flags in DBC,
+but for now, they are too unknown for us, to use them */
+enum CustomVehicleFLags
+{
+    VF_CANT_MOVE                    = 0x0001,                   // vehicle cant move, only turn, maybe handle by some auras?
+    VF_FACTION                      = 0x0002,                   // vehicle retain its own faction
+    VF_DESPAWN_NPC                  = 0x0004,                   // vehicle will delete npc on spellclick
+    VF_DESPAWN_AT_LEAVE             = 0x0008,                   // vehicle will be deleted when rider leaves
+    VF_CAN_BE_HEALED                = 0x0010,                   // vehicle can be healed
+    VF_GIVE_EXP                     = 0x0020,                   // vehicle will give exp for killing enemies
+    VF_MOVEMENT                     = 0x0040,                   // vehicle will move on its own, not depending on rider, however rider can cast spells
+    VF_NON_SELECTABLE               = 0x0080                    // vehicle will be not selectable after rider enter
+    //VF_HAS_FUEL                     = 0x0100,                   // TODO : find out what energy type is fuel and implement this
+};
+
+enum CustomVehicleSeatFLags
+{
+    SF_MAIN_RIDER                   = 0x0001,                   // the one who controlls vehicle, can also cast spells
+    SF_UNATTACKABLE                 = 0x0002,                   // hided inside, and unatackable until vehicle is destroyed
+    SF_CAN_CAST                     = 0x0004,                   // player/npc can rotate, and cast OWN spells
+    SF_UNACCESSIBLE                 = 0x0008                    // player cant enter this seat by normal way (only by script)
+};
 enum ResponseCodes
 {
     RESPONSE_SUCCESS                                       = 0x00,
diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp
index 0cda9dc..a782bb8 100644
--- a/src/game/Spell.cpp
+++ b/src/game/Spell.cpp
@@ -204,7 +204,7 @@ void SpellCastTargets::Update(Unit* caster)
     }
 }
 
-bool SpellCastTargets::read ( WorldPacket * data, Unit *caster )
+bool SpellCastTargets::read ( WorldPacket * data, Unit *caster, SpellEntry const* spell )
 {
     if(data->rpos() + 4 > data->size())
         return false;
@@ -216,8 +216,20 @@ bool SpellCastTargets::read ( WorldPacket * data, Unit *caster )
         m_destX = caster->GetPositionX();
         m_destY = caster->GetPositionY();
         m_destZ = caster->GetPositionZ();
-        m_unitTarget = caster;
-        m_unitTargetGUID = caster->GetGUID();
+        bool skiptarget = false;
+        if(spell)
+        {
+            for(int j=0;j<3;j++)
+            {
+                // this is requiered, otherwise it will return SPELL_FAILED_BAD_TARGETS
+                skiptarget |= (spell->EffectImplicitTargetA[j] == TARGET_IN_FRONT_OF_CASTER || spell->EffectImplicitTargetA[j] == TARGET_SCRIPT || spell->EffectImplicitTargetA[j] == TARGET_EFFECT_SELECT);
+            }
+        }
+        if(!skiptarget)
+        {
+            m_unitTarget = caster;
+            m_unitTargetGUID = caster->GetGUID();
+        }
         return true;
     }
 
@@ -1429,8 +1441,11 @@ void Spell::SetTargetMap(SpellEffectIndex effIndex, uint32 targetMode, UnitList&
         case TARGET_SELF2:
         case TARGET_AREAEFFECT_CUSTOM:
         case TARGET_AREAEFFECT_CUSTOM_2:
+        {
+            // used for targeting gameobjects
             targetUnitMap.push_back(m_caster);
             break;
+        }
         case TARGET_RANDOM_ENEMY_CHAIN_IN_AREA:
         {
             m_targets.m_targetMask = 0;
@@ -1678,6 +1693,9 @@ void Spell::SetTargetMap(SpellEffectIndex effIndex, uint32 targetMode, UnitList&
                     break;
                 default:
                     FillAreaTargets(targetUnitMap, m_targets.m_destX, m_targets.m_destY, radius, PUSH_DEST_CENTER, SPELL_TARGETS_AOE_DAMAGE);
+
+                    // exclude caster (this can be important if this not original caster, for example vehicle)
+                    targetUnitMap.remove(m_caster);
                     break;
             }
             break;
@@ -3069,7 +3087,7 @@ void Spell::finish(bool ok)
         m_caster->resetAttackTimer(RANGED_ATTACK);*/
 
     // Clear combo at finish state
-    if(m_caster->GetTypeId() == TYPEID_PLAYER && NeedsComboPoints(m_spellInfo))
+    if((m_caster->GetTypeId() == TYPEID_PLAYER || ((Creature*)m_caster)->isVehicle()) && NeedsComboPoints(m_spellInfo))
     {
         // Not drop combopoints if negative spell and if any miss on enemy exist
         bool needDrop = true;
@@ -3085,7 +3103,12 @@ void Spell::finish(bool ok)
             }
         }
         if (needDrop)
-            ((Player*)m_caster)->ClearComboPoints();
+        {
+            if(m_caster->GetTypeId() == TYPEID_PLAYER)
+                ((Player*)m_caster)->ClearComboPoints();
+            else
+                ((Player*)m_caster->GetCharmer())->ClearComboPoints();
+        }
     }
 
     // potions disabled by client, send event "not in combat" if need
@@ -4280,11 +4303,16 @@ SpellCastResult Spell::CheckCast(bool strict)
         return locRes;
 
     // not let players cast spells at mount (and let do it to creatures)
-    if (m_caster->IsMounted() && m_caster->GetTypeId()==TYPEID_PLAYER && !m_IsTriggeredSpell &&
+    if ((m_caster->IsMounted() || m_caster->GetVehicleGUID()) && m_caster->GetTypeId()==TYPEID_PLAYER && !m_IsTriggeredSpell &&
         !IsPassiveSpell(m_spellInfo->Id) && !(m_spellInfo->Attributes & SPELL_ATTR_CASTABLE_WHILE_MOUNTED))
     {
         if (m_caster->isInFlight())
             return SPELL_FAILED_NOT_ON_TAXI;
+        else if(m_caster->GetVehicleGUID())
+        {
+            if(!(m_caster->m_SeatData.s_flags & SF_CAN_CAST))
+                return SPELL_FAILED_NOT_MOUNTED;
+        }
         else
             return SPELL_FAILED_NOT_MOUNTED;
     }
@@ -5104,7 +5132,7 @@ SpellCastResult Spell::CheckPetCast(Unit* target)
                                                             //TARGET_DUELVSPLAYER is positive AND negative
                     duelvsplayertar |= (m_spellInfo->EffectImplicitTargetA[j] == TARGET_DUELVSPLAYER);
                 }
-                if(m_caster->IsFriendlyTo(target) && !duelvsplayertar)
+                if(m_caster->IsFriendlyTo(_target) && !duelvsplayertar)
                 {
                     return SPELL_FAILED_BAD_TARGETS;
                 }
@@ -5115,6 +5143,7 @@ SpellCastResult Spell::CheckPetCast(Unit* target)
             return SPELL_FAILED_NOT_READY;
     }
 
+    // NOTE : this is done twice, also in spell->prepare(&(spell->m_targets));
     return CheckCast(true);
 }
 
@@ -6047,7 +6076,8 @@ bool Spell::CheckTarget( Unit* target, SpellEffectIndex eff )
         // in case TARGET_SCRIPT target selected by server always and can't be cheated
         if( target->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE) &&
             m_spellInfo->EffectImplicitTargetA[eff] != TARGET_SCRIPT &&
-            m_spellInfo->EffectImplicitTargetB[eff] != TARGET_SCRIPT )
+            m_spellInfo->EffectImplicitTargetB[eff] != TARGET_SCRIPT &&
+            m_spellInfo->EffectImplicitTargetA[eff] != TARGET_MASTER )
             return false;
     }
 
diff --git a/src/game/Spell.h b/src/game/Spell.h
index e290e7c..c81bf3a 100644
--- a/src/game/Spell.h
+++ b/src/game/Spell.h
@@ -108,7 +108,7 @@ class SpellCastTargets
         SpellCastTargets();
         ~SpellCastTargets();
 
-        bool read ( WorldPacket * data, Unit *caster );
+        bool read ( WorldPacket * data, Unit *caster, SpellEntry const* spell = NULL );
         void write ( WorldPacket * data );
 
         SpellCastTargets& operator=(const SpellCastTargets &target)
@@ -330,6 +330,8 @@ class Spell
         void EffectPlayMusic(SpellEffectIndex eff_idx);
         void EffectSpecCount(SpellEffectIndex eff_idx);
         void EffectActivateSpec(SpellEffectIndex eff_idx);
+        void EffectSummonVehicle(SpellEffectIndex eff_idx);
+        void EffectDamageBuilding(SpellEffectIndex eff_idx);
 
         Spell( Unit* Caster, SpellEntry const *info, bool triggered, uint64 originalCasterGUID = 0, Spell** triggeringContainer = NULL );
         ~Spell();
diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp
index 3b18a72..08e471f 100644
--- a/src/game/SpellAuras.cpp
+++ b/src/game/SpellAuras.cpp
@@ -1249,7 +1249,10 @@ void Aura::SendAuraUpdate(bool remove)
 
     if(!(auraFlags & AFLAG_NOT_CASTER))
     {
-        data << uint8(0);                                   // pguid
+        if(GetCaster())
+            data.append(GetCaster()->GetPackGUID());
+        else
+            data << uint8(0);
     }
 
     if(auraFlags & AFLAG_DURATION)
@@ -3627,7 +3630,7 @@ void Aura::HandleModPossess(bool apply, bool Real)
             m_target->GetMotionMaster()->Clear();
             m_target->GetMotionMaster()->MoveIdle();
         }
-        else if(m_target->GetTypeId() == TYPEID_PLAYER)
+        else if(m_target->GetTypeId() == TYPEID_PLAYER && !m_target->GetVehicleGUID())
         {
             ((Player*)m_target)->SetClientControl(m_target, 0);
         }
@@ -3644,7 +3647,7 @@ void Aura::HandleModPossess(bool apply, bool Real)
         m_target->SetCharmerGUID(0);
         p_caster->InterruptSpell(CURRENT_CHANNELED_SPELL);  // the spell is not automatically canceled when interrupted, do it now
 
-        if(m_target->GetTypeId() == TYPEID_PLAYER)
+        if(m_target->GetTypeId() == TYPEID_PLAYER && !m_target->GetVehicleGUID())
         {
             ((Player*)m_target)->setFactionForRace(m_target->getRace());
             ((Player*)m_target)->SetClientControl(m_target, 1);
@@ -3913,10 +3916,13 @@ void Aura::HandleAuraModStun(bool apply, bool Real)
             m_target->SetStandState(UNIT_STAND_STATE_STAND);// in 1.5 client
         }
 
-        WorldPacket data(SMSG_FORCE_MOVE_ROOT, 8);
-        data.append(m_target->GetPackGUID());
-        data << uint32(0);
-        m_target->SendMessageToSet(&data, true);
+        if(!m_target->hasUnitState(UNIT_STAT_ON_VEHICLE))
+        {
+            WorldPacket data(SMSG_FORCE_MOVE_ROOT, 8);
+            data.append(m_target->GetPackGUID());
+            data << uint32(0);
+            m_target->SendMessageToSet(&data,true);
+        }
 
         // Summon the Naj'entus Spine GameObject on target if spell is Impaling Spine
         if(GetId() == 39837)
@@ -3966,7 +3972,7 @@ void Aura::HandleAuraModStun(bool apply, bool Real)
         m_target->clearUnitState(UNIT_STAT_STUNNED);
         m_target->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED);
 
-        if(!m_target->hasUnitState(UNIT_STAT_ROOT))         // prevent allow move if have also root effect
+        if(!m_target->hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_ON_VEHICLE))         // prevent allow move if have also root effect
         {
             if(m_target->getVictim() && m_target->isAlive())
                 m_target->SetTargetGUID(m_target->getVictim()->GetGUID());
@@ -4181,11 +4187,13 @@ void Aura::HandleAuraModRoot(bool apply, bool Real)
 
         if(m_target->GetTypeId() == TYPEID_PLAYER)
         {
-            WorldPacket data(SMSG_FORCE_MOVE_ROOT, 10);
-            data.append(m_target->GetPackGUID());
-            data << (uint32)2;
-            m_target->SendMessageToSet(&data, true);
-
+            if(!m_target->hasUnitState(UNIT_STAT_ON_VEHICLE))
+            {
+                WorldPacket data(SMSG_FORCE_MOVE_ROOT, 10);
+                data.append(m_target->GetPackGUID());
+                data << (uint32)2;
+                m_target->SendMessageToSet(&data,true);
+            }
             //Clear unit movement flags
             ((Player*)m_target)->m_movementInfo.SetMovementFlags(MOVEFLAG_NONE);
         }
@@ -4223,7 +4231,7 @@ void Aura::HandleAuraModRoot(bool apply, bool Real)
 
         m_target->clearUnitState(UNIT_STAT_ROOT);
 
-        if(!m_target->hasUnitState(UNIT_STAT_STUNNED))      // prevent allow move if have also stun effect
+        if(!m_target->hasUnitState(UNIT_STAT_STUNNED | UNIT_STAT_ON_VEHICLE))      // prevent allow move if have also stun effect
         {
             if(m_target->getVictim() && m_target->isAlive())
                 m_target->SetTargetGUID(m_target->getVictim()->GetGUID());
@@ -4254,7 +4262,7 @@ void Aura::HandleAuraModSilence(bool apply, bool Real)
                 if(spell->m_spellInfo->PreventionType == SPELL_PREVENTION_TYPE_SILENCE)
                     // Stop spells on prepare or casting state
                     m_target->InterruptSpell(CurrentSpellTypes(i), false);
-    }
+	}
     else
     {
         // Real remove called after current aura remove from lists, check if other similar auras active
@@ -6684,7 +6692,7 @@ void Aura::HandleModRatingFromStat(bool apply, bool Real)
 
 void Aura::HandleForceMoveForward(bool apply, bool Real)
 {
-    if(!Real || m_target->GetTypeId() != TYPEID_PLAYER)
+    if(!Real)
         return;
     if(apply)
         m_target->SetFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_FORCE_MOVE);
@@ -8039,28 +8047,36 @@ void Aura::HandleArenaPreparation(bool apply, bool Real)
  */
 void Aura::HandleAuraControlVehicle(bool apply, bool Real)
 {
-    if(!Real)
-        return;
+     if(!Real)
+         return;
 
-    Unit *player = GetCaster();
+    Unit *caster = GetCaster();
     Vehicle *vehicle = dynamic_cast<Vehicle*>(m_target);
-    if(!player || player->GetTypeId() != TYPEID_PLAYER || !vehicle)
+    if(!caster || !vehicle)
+        return;
+
+    // this can happen due to wrong caster/target spell handling
+    // note : SPELL_AURA_CONTROL_VEHICLE can have EffectImplicitTargetA
+    // TARGET_SCRIPT, TARGET_DUELVSPLAYER.. etc
+    if(caster->GetGUID() == vehicle->GetGUID())
         return;
 
     if (apply)
     {
-        if(Pet *pet = player->GetPet())
-            pet->Remove(PET_SAVE_AS_CURRENT);
-        ((Player*)player)->EnterVehicle(vehicle);
+        if(caster->GetTypeId() == TYPEID_PLAYER)
+        {
+            WorldPacket data(SMSG_ON_CANCEL_EXPECTED_RIDE_VEHICLE_AURA, 0);
+            ((Player*)caster)->GetSession()->SendPacket(&data);
+        }
+        // if we leave and enter again, this will refresh
+        int32 duration = GetSpellMaxDuration(GetSpellProto());
+        if(duration > 0)
+            vehicle->SetSpawnDuration(duration);
     }
     else
     {
-        SpellEntry const *spell = GetSpellProto();
-
         // some SPELL_AURA_CONTROL_VEHICLE auras have a dummy effect on the player - remove them
-        player->RemoveAurasDueToSpell(spell->Id);
-
-        ((Player*)player)->ExitVehicle(vehicle);
+        caster->RemoveAurasDueToSpell(GetId());
     }
 }
 
diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp
index b786e43..a1ec4f6 100644
--- a/src/game/SpellEffects.cpp
+++ b/src/game/SpellEffects.cpp
@@ -54,6 +54,7 @@
 #include "ScriptCalls.h"
 #include "SkillDiscovery.h"
 #include "Formulas.h"
+#include "Vehicle.h"
 
 pEffect SpellEffects[TOTAL_SPELL_EFFECTS]=
 {
@@ -144,9 +145,9 @@ pEffect SpellEffects[TOTAL_SPELL_EFFECTS]=
     &Spell::EffectStuck,                                    // 84 SPELL_EFFECT_STUCK
     &Spell::EffectSummonPlayer,                             // 85 SPELL_EFFECT_SUMMON_PLAYER
     &Spell::EffectActivateObject,                           // 86 SPELL_EFFECT_ACTIVATE_OBJECT
-    &Spell::EffectNULL,                                     // 87 SPELL_EFFECT_WMO_DAMAGE (57 spells in 3.3.2)
-    &Spell::EffectNULL,                                     // 88 SPELL_EFFECT_WMO_REPAIR (2 spells in 3.3.2)
-    &Spell::EffectNULL,                                     // 89 SPELL_EFFECT_WMO_CHANGE (7 spells in 3.3.2)
+    &Spell::EffectDamageBuilding,                           // 87 SPELL_EFFECT_WMO_DAMAGE
+    &Spell::EffectUnused,                                   // 88 SPELL_EFFECT_WMO_REPAIR
+    &Spell::EffectUnused,                                   // 89 SPELL_EFFECT_WMO_CHANGE
     &Spell::EffectKillCreditPersonal,                       // 90 SPELL_EFFECT_KILL_CREDIT              Kill credit but only for single person
     &Spell::EffectUnused,                                   // 91 SPELL_EFFECT_THREAT_ALL               one spell: zzOLDBrainwash
     &Spell::EffectEnchantHeldItem,                          // 92 SPELL_EFFECT_ENCHANT_HELD_ITEM
@@ -3767,7 +3768,7 @@ void Spell::EffectSummonType(SpellEffectIndex eff_idx)
                 case SUMMON_PROP_TYPE_SIEGE_VEH:
                 case SUMMON_PROP_TYPE_DRAKE_VEH:
                     // TODO
-                    // EffectSummonVehicle(i);
+                    EffectSummonVehicle(eff_idx);
                     break;
                 default:
                     sLog.outError("EffectSummonType: Unhandled summon type %u", summon_prop->Type);
@@ -3796,7 +3797,7 @@ void Spell::EffectSummonType(SpellEffectIndex eff_idx)
         case SUMMON_PROP_GROUP_VEHICLE:
         {
             // TODO
-            // EffectSummonVehicle(i);
+            EffectSummonVehicle(eff_idx);
             break;
         }
         default:
@@ -3804,7 +3805,6 @@ void Spell::EffectSummonType(SpellEffectIndex eff_idx)
             break;
     }
 }
-
 void Spell::DoSummon(SpellEffectIndex eff_idx)
 {
     if (m_caster->GetPetGUID())
@@ -6145,13 +6145,15 @@ void Spell::EffectAddComboPoints(SpellEffectIndex /*eff_idx*/)
     if(!unitTarget)
         return;
 
-    if(m_caster->GetTypeId() != TYPEID_PLAYER)
-        return;
-
     if(damage <= 0)
         return;
 
-    ((Player*)m_caster)->AddComboPoints(unitTarget, damage);
+    if(m_caster->GetTypeId() != TYPEID_PLAYER)
+    {
+        if(((Creature*)m_caster)->isVehicle())
+            ((Player*)m_caster->GetCharmer())->AddComboPoints(unitTarget, damage);
+    }else
+        ((Player*)m_caster)->AddComboPoints(unitTarget, damage);
 }
 
 void Spell::EffectDuel(SpellEffectIndex eff_idx)
@@ -7401,6 +7403,54 @@ void Spell::EffectRenamePet(SpellEffectIndex /*eff_idx*/)
     unitTarget->RemoveByteFlag(UNIT_FIELD_BYTES_2, 2, UNIT_CAN_BE_RENAMED);
 }
 
+void Spell::EffectSummonVehicle(SpellEffectIndex eff_idx)
+{
+    uint32 creature_entry = m_spellInfo->EffectMiscValue[eff_idx];
+    if(!creature_entry)
+        return;
+
+    float px, py, pz;
+    // If dest location if present
+    if (m_targets.m_targetMask & TARGET_FLAG_DEST_LOCATION)
+    {
+        // Summon unit in dest location
+        px = m_targets.m_destX;
+        py = m_targets.m_destY;
+        pz = m_targets.m_destZ;
+    }
+    // Summon if dest location not present near caster
+    else
+        m_caster->GetClosePoint(px,py,pz,3.0f);
+
+    Vehicle *v = m_caster->SummonVehicle(creature_entry, px, py, pz, m_caster->GetOrientation());
+    if(!v)
+        return;
+
+    v->SetUInt32Value(UNIT_CREATED_BY_SPELL, m_spellInfo->Id);
+    v->SetCreatorGUID(m_caster->GetGUID());
+
+    if(damage)
+    {
+        m_caster->CastSpell(v, damage, true);
+        m_caster->EnterVehicle(v, 0);
+    }
+    int32 duration = GetSpellMaxDuration(m_spellInfo);
+    if(duration > 0)
+        v->SetSpawnDuration(duration);
+}
+
+void Spell::EffectDamageBuilding(SpellEffectIndex eff_idx)
+{
+    if(!gameObjTarget)
+        return;
+
+    if(gameObjTarget->GetGoType() != GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING)
+        return;
+
+    // NOTE : this can be increased by scaling stat system in vehicles
+    gameObjTarget->DealSiegeDamage(damage);
+}
+
 void Spell::EffectPlayMusic(SpellEffectIndex eff_idx)
 {
     if(!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER)
diff --git a/src/game/SpellHandler.cpp b/src/game/SpellHandler.cpp
index 6819c0b..fd3c3c7 100644
--- a/src/game/SpellHandler.cpp
+++ b/src/game/SpellHandler.cpp
@@ -27,6 +27,7 @@
 #include "Spell.h"
 #include "ScriptCalls.h"
 #include "Totem.h"
+#include "Vehicle.h"
 #include "SpellAuras.h"
 
 void WorldSession::HandleUseItemOpcode(WorldPacket& recvPacket)
@@ -298,6 +299,11 @@ void WorldSession::HandleCastSpellOpcode(WorldPacket& recvPacket)
         return;
     }
 
+    // vehicle spells are handled by CMSG_PET_CAST_SPELL,
+    // but player is still able to cast own spells
+    if(_player->GetCharmGUID() && _player->GetCharmGUID() == _player->GetVehicleGUID())
+        mover = _player;
+
     sLog.outDebug("WORLD: got cast spell packet, spellId - %u, cast_count: %u, unk_flags %u, data length = %i",
         spellId, cast_count, unk_flags, (uint32)recvPacket.size());
 
@@ -462,7 +468,7 @@ void WorldSession::HandlePetCancelAuraOpcode( WorldPacket& recvPacket)
         return;
     }
 
-    Creature* pet = GetPlayer()->GetMap()->GetCreatureOrPetOrVehicle(guid);
+    Creature* pet=ObjectAccessor::GetCreatureOrPetOrVehicle(*_player,guid);
 
     if(!pet)
     {
@@ -550,20 +556,67 @@ void WorldSession::HandleSpellClick( WorldPacket & recv_data )
     if (_player->isInCombat())                              // client prevent click and set different icon at combat state
         return;
 
-    Creature *unit = _player->GetMap()->GetCreatureOrPetOrVehicle(guid);
+    Creature *unit = ObjectAccessor::GetCreatureOrPetOrVehicle(*_player, guid);
     if (!unit || unit->isInCombat())                        // client prevent click and set different icon at combat state
         return;
 
-    SpellClickInfoMapBounds clickPair = sObjectMgr.GetSpellClickInfoMapBounds(unit->GetEntry());
-    for(SpellClickInfoMap::const_iterator itr = clickPair.first; itr != clickPair.second; ++itr)
+    if(!_player->IsWithinDistInMap(unit, 10))
+        return;
+
+    // cheater?
+    if(!unit->HasFlag(UNIT_NPC_FLAGS,UNIT_NPC_FLAG_SPELLCLICK))
+        return;
+
+    uint32 vehicleId = 0;
+    CreatureDataAddon const *cainfo = unit->GetCreatureAddon();
+    if(cainfo)
+        vehicleId = cainfo->vehicle_id;
+
+    // handled other (hacky) way to avoid overwriting auras
+    if(vehicleId || unit->isVehicle())
     {
-        if (itr->second.IsFitToRequirements(_player))
+        if(!unit->isAlive())
+            return;
+
+        if(_player->GetVehicleGUID())
+            return;
+
+        // create vehicle if no one present and kill the original creature to avoid double, triple etc spawns
+        if(!unit->isVehicle())
         {
-            Unit *caster = (itr->second.castFlags & 0x1) ? (Unit*)_player : (Unit*)unit;
-            Unit *target = (itr->second.castFlags & 0x2) ? (Unit*)_player : (Unit*)unit;
+            Vehicle *v = _player->SummonVehicle(unit->GetEntry(), unit->GetPositionX(), unit->GetPositionY(), unit->GetPositionZ(), unit->GetOrientation(), vehicleId);
+            if(!v)
+                return;
 
-            caster->CastSpell(target, itr->second.spellId, true);
+            if(v->GetVehicleFlags() & VF_DESPAWN_NPC)
+            {
+                v->SetSpawnDuration(unit->GetRespawnDelay()*IN_MILISECONDS);
+                unit->setDeathState(JUST_DIED);
+                unit->RemoveCorpse();
+                unit->SetHealth(0);
+            }
+            unit = v;
         }
+
+        if(((Vehicle*)unit)->GetVehicleData())
+            if(uint32 r_aura = ((Vehicle*)unit)->GetVehicleData()->req_aura)
+                if(!_player->HasAura(r_aura))
+                    return;
+
+        _player->EnterVehicle((Vehicle*)unit, 0);
     }
-}
+    else
+    {
+        SpellClickInfoMapBounds clickPair = sObjectMgr.GetSpellClickInfoMapBounds(unit->GetEntry());
+        for(SpellClickInfoMap::const_iterator itr = clickPair.first; itr != clickPair.second; ++itr)
+        {
+            if (itr->second.IsFitToRequirements(_player))
+            {
+                Unit *caster = (itr->second.castFlags & 0x1) ? (Unit*)_player : (Unit*)unit;
+                Unit *target = (itr->second.castFlags & 0x2) ? (Unit*)_player : (Unit*)unit;
 
+                caster->CastSpell(target, itr->second.spellId, true);
+            }
+        }
+    }
+}
diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp
index ca9bde4..210f059 100644
--- a/src/game/Unit.cpp
+++ b/src/game/Unit.cpp
@@ -46,6 +46,7 @@
 #include "CellImpl.h"
 #include "Path.h"
 #include "Traveller.h"
+#include "Vehicle.h"
 #include "VMapFactory.h"
 #include "MovementGenerator.h"
 
@@ -272,6 +273,9 @@ Unit::Unit()
     // remove aurastates allowing special moves
     for(int i=0; i < MAX_REACTIVE; ++i)
         m_reactiveTimer[i] = 0;
+
+    m_auraUpdateMask = 0;
+    m_vehicleGUID = 0;
 }
 
 Unit::~Unit()
@@ -8037,15 +8041,10 @@ void Unit::setPowerType(Powers new_powertype)
         if(((Player*)this)->GetGroup())
             ((Player*)this)->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_POWER_TYPE);
     }
-    else if(((Creature*)this)->isPet())
+    else if(Unit* owner = GetCharmerOrOwner())
     {
-        Pet *pet = ((Pet*)this);
-        if(pet->isControlled())
-        {
-            Unit *owner = GetOwner();
-            if(owner && (owner->GetTypeId() == TYPEID_PLAYER) && ((Player*)owner)->GetGroup())
-                ((Player*)owner)->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_PET_POWER_TYPE);
-        }
+        if((owner->GetTypeId() == TYPEID_PLAYER) && ((Player*)owner)->GetGroup())
+            ((Player*)owner)->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_PET_POWER_TYPE);
     }
 
     switch(new_powertype)
@@ -8353,6 +8352,14 @@ bool Unit::Attack(Unit *victim, bool meleeAttack)
     if(GetTypeId()==TYPEID_PLAYER && IsMounted())
         return false;
 
+    // player (also npc?) cannot attack on vehicle
+    if(GetTypeId()==TYPEID_PLAYER && GetVehicleGUID())
+        return false;
+
+    // player (also npc?) cannot attack on vehicle
+    if(GetTypeId()==TYPEID_UNIT && ((Creature*)this)->isVehicle() && GetCharmerGUID())
+        return false;
+
     // nobody can attack GM in GM-mode
     if(victim->GetTypeId()==TYPEID_PLAYER)
     {
@@ -10814,6 +10821,11 @@ void Unit::UpdateSpeed(UnitMoveType mtype, bool forced)
     }
 
     float bonus = non_stack_bonus > stack_bonus ? non_stack_bonus : stack_bonus;
+
+    //apply creature's base speed
+    if(GetTypeId() == TYPEID_UNIT)
+        bonus *= ((Creature*)this)->GetBaseSpeed();
+
     // now we ready for speed calculation
     float speed  = main_speed_mod ? bonus*(100.0f + main_speed_mod)/100.0f : bonus;
 
@@ -11010,6 +11022,7 @@ void Unit::setDeathState(DeathState s)
 
     if (s == JUST_DIED)
     {
+        ExitVehicle();
         RemoveAllAurasOnDeath();
         RemoveGuardians();
         UnsummonAllTotems();
@@ -11233,7 +11246,8 @@ bool Unit::SelectHostileTarget()
     }
 
     // enter in evade mode in other case
-    ((Creature*)this)->AI()->EnterEvadeMode();
+    if(!((Creature*)this)->isVehicle())
+        ((Creature*)this)->AI()->EnterEvadeMode();
 
     return false;
 }
@@ -11244,7 +11258,14 @@ bool Unit::SelectHostileTarget()
 
 int32 Unit::CalculateSpellDamage(SpellEntry const* spellProto, SpellEffectIndex effect_index, int32 effBasePoints, Unit const* target)
 {
-    Player* unitPlayer = (GetTypeId() == TYPEID_PLAYER) ? (Player*)this : NULL;
+    Player* unitPlayer;
+
+    if(GetTypeId() == TYPEID_PLAYER)
+        unitPlayer = (Player*)this;
+    else if(((Creature*)this)->isVehicle())
+        unitPlayer = (Player*)GetCharmer();
+    else
+        unitPlayer = NULL;
 
     uint8 comboPoints = unitPlayer ? unitPlayer->GetComboPoints() : 0;
 
@@ -11299,7 +11320,14 @@ int32 Unit::CalculateSpellDamage(SpellEntry const* spellProto, SpellEffectIndex
 
 int32 Unit::CalculateSpellDuration(SpellEntry const* spellProto, SpellEffectIndex effect_index, Unit const* target)
 {
-    Player* unitPlayer = (GetTypeId() == TYPEID_PLAYER) ? (Player*)this : NULL;
+    Player* unitPlayer;
+
+    if(GetTypeId() == TYPEID_PLAYER)
+        unitPlayer = (Player*)this;
+    else if(((Creature*)this)->isVehicle())
+        unitPlayer = (Player*)GetCharmer();
+    else
+        unitPlayer = NULL;
 
     uint8 comboPoints = unitPlayer ? unitPlayer->GetComboPoints() : 0;
 
@@ -11709,15 +11737,10 @@ void Unit::SetHealth(uint32 val)
         if(((Player*)this)->GetGroup())
             ((Player*)this)->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_CUR_HP);
     }
-    else if(((Creature*)this)->isPet())
+    else if(Unit* owner = GetCharmerOrOwner())
     {
-        Pet *pet = ((Pet*)this);
-        if(pet->isControlled())
-        {
-            Unit *owner = GetOwner();
-            if(owner && (owner->GetTypeId() == TYPEID_PLAYER) && ((Player*)owner)->GetGroup())
-                ((Player*)owner)->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_PET_CUR_HP);
-        }
+        if((owner->GetTypeId() == TYPEID_PLAYER) && ((Player*)owner)->GetGroup())
+            ((Player*)owner)->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_PET_CUR_HP);
     }
 }
 
@@ -11732,15 +11755,10 @@ void Unit::SetMaxHealth(uint32 val)
         if(((Player*)this)->GetGroup())
             ((Player*)this)->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_MAX_HP);
     }
-    else if(((Creature*)this)->isPet())
+    else if(Unit* owner = GetCharmerOrOwner())
     {
-        Pet *pet = ((Pet*)this);
-        if(pet->isControlled())
-        {
-            Unit *owner = GetOwner();
-            if(owner && (owner->GetTypeId() == TYPEID_PLAYER) && ((Player*)owner)->GetGroup())
-                ((Player*)owner)->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_PET_MAX_HP);
-        }
+        if((owner->GetTypeId() == TYPEID_PLAYER) && ((Player*)owner)->GetGroup())
+            ((Player*)owner)->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_PET_MAX_HP);
     }
 
     if(val < health)
@@ -11776,20 +11794,19 @@ void Unit::SetPower(Powers power, uint32 val)
         if(((Player*)this)->GetGroup())
             ((Player*)this)->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_CUR_POWER);
     }
-    else if(((Creature*)this)->isPet())
+    else if(Unit* owner = GetCharmerOrOwner())
     {
-        Pet *pet = ((Pet*)this);
-        if(pet->isControlled())
-        {
-            Unit *owner = GetOwner();
-            if(owner && (owner->GetTypeId() == TYPEID_PLAYER) && ((Player*)owner)->GetGroup())
-                ((Player*)owner)->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_PET_CUR_POWER);
-        }
+        if((owner->GetTypeId() == TYPEID_PLAYER) && ((Player*)owner)->GetGroup())
+            ((Player*)owner)->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_PET_CUR_POWER);
 
-        // Update the pet's character sheet with happiness damage bonus
-        if(pet->getPetType() == HUNTER_PET && power == POWER_HAPPINESS)
+        if(((Creature*)this)->isPet())
         {
-            pet->UpdateDamagePhysical(BASE_ATTACK);
+            Pet *pet = ((Pet*)this);
+            // Update the pet's character sheet with happiness damage bonus
+            if(pet->getPetType() == HUNTER_PET && power == POWER_HAPPINESS)
+            {
+                pet->UpdateDamagePhysical(BASE_ATTACK);
+            }
         }
     }
 }
@@ -11805,15 +11822,10 @@ void Unit::SetMaxPower(Powers power, uint32 val)
         if(((Player*)this)->GetGroup())
             ((Player*)this)->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_MAX_POWER);
     }
-    else if(((Creature*)this)->isPet())
+    else if(Unit* owner = GetCharmerOrOwner())
     {
-        Pet *pet = ((Pet*)this);
-        if(pet->isControlled())
-        {
-            Unit *owner = GetOwner();
-            if(owner && (owner->GetTypeId() == TYPEID_PLAYER) && ((Player*)owner)->GetGroup())
-                ((Player*)owner)->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_PET_MAX_POWER);
-        }
+        if((owner->GetTypeId() == TYPEID_PLAYER) && ((Player*)owner)->GetGroup())
+            ((Player*)owner)->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_PET_MAX_POWER);
     }
 
     if(val < cur_power)
@@ -11830,15 +11842,10 @@ void Unit::ApplyPowerMod(Powers power, uint32 val, bool apply)
         if(((Player*)this)->GetGroup())
             ((Player*)this)->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_CUR_POWER);
     }
-    else if(((Creature*)this)->isPet())
+    else if(Unit* owner = GetCharmerOrOwner())
     {
-        Pet *pet = ((Pet*)this);
-        if(pet->isControlled())
-        {
-            Unit *owner = GetOwner();
-            if(owner && (owner->GetTypeId() == TYPEID_PLAYER) && ((Player*)owner)->GetGroup())
-                ((Player*)owner)->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_PET_CUR_POWER);
-        }
+        if((owner->GetTypeId() == TYPEID_PLAYER) && ((Player*)owner)->GetGroup())
+            ((Player*)owner)->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_PET_CUR_POWER);
     }
 }
 
@@ -11852,15 +11859,10 @@ void Unit::ApplyMaxPowerMod(Powers power, uint32 val, bool apply)
         if(((Player*)this)->GetGroup())
             ((Player*)this)->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_MAX_POWER);
     }
-    else if(((Creature*)this)->isPet())
+    else if(Unit* owner = GetCharmerOrOwner())
     {
-        Pet *pet = ((Pet*)this);
-        if(pet->isControlled())
-        {
-            Unit *owner = GetOwner();
-            if(owner && (owner->GetTypeId() == TYPEID_PLAYER) && ((Player*)owner)->GetGroup())
-                ((Player*)owner)->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_PET_MAX_POWER);
-        }
+        if((owner->GetTypeId() == TYPEID_PLAYER) && ((Player*)owner)->GetGroup())
+            ((Player*)owner)->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_PET_MAX_POWER);
     }
 }
 
@@ -11914,6 +11916,7 @@ void Unit::RemoveFromWorld()
 
 void Unit::CleanupsBeforeDelete()
 {
+    ExitVehicle();                                          // make sure we always leave vehicle, otherwise it will crash
     if(m_uint32Values)                                      // only for fully created object
     {
         InterruptNonMeleeSpells(true);
@@ -12651,8 +12654,12 @@ void Unit::SetFeared(bool apply, uint64 const& casterGUID, uint32 spellID, uint3
         }
     }
 
-    if (GetTypeId() == TYPEID_PLAYER)
+    if (GetTypeId() == TYPEID_PLAYER && !GetVehicleGUID())
         ((Player*)this)->SetClientControl(this, !apply);
+
+    if (Unit* owner = GetCharmer())
+        if (owner->GetTypeId() == TYPEID_PLAYER)
+            ((Player*)owner)->SetClientControl(this, !apply);
 }
 
 void Unit::SetConfused(bool apply, uint64 const& casterGUID, uint32 spellID)
@@ -12681,8 +12688,12 @@ void Unit::SetConfused(bool apply, uint64 const& casterGUID, uint32 spellID)
         }
     }
 
-    if(GetTypeId() == TYPEID_PLAYER)
+    if(GetTypeId() == TYPEID_PLAYER && !GetVehicleGUID())
         ((Player*)this)->SetClientControl(this, !apply);
+
+    if (Unit* owner = GetCharmer())
+        if (owner->GetTypeId() == TYPEID_PLAYER)
+            ((Player*)owner)->SetClientControl(this, !apply);
 }
 
 void Unit::SetFeignDeath(bool apply, uint64 const& casterGUID, uint32 /*spellID*/)
@@ -12786,13 +12797,9 @@ void Unit::SetDisplayId(uint32 modelId)
 {
     SetUInt32Value(UNIT_FIELD_DISPLAYID, modelId);
 
-    if(GetTypeId() == TYPEID_UNIT && ((Creature*)this)->isPet())
+    if(Unit *owner = GetCharmerOrOwner())
     {
-        Pet *pet = ((Pet*)this);
-        if(!pet->isControlled())
-            return;
-        Unit *owner = GetOwner();
-        if(owner && (owner->GetTypeId() == TYPEID_PLAYER) && ((Player*)owner)->GetGroup())
+        if((owner->GetTypeId() == TYPEID_PLAYER) && ((Player*)owner)->GetGroup())
             ((Player*)owner)->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_PET_MODEL_ID);
     }
 }
@@ -13091,16 +13098,14 @@ void Unit::UpdateAuraForGroup(uint8 slot)
             player->SetAuraUpdateMask(slot);
         }
     }
-    else if(GetTypeId() == TYPEID_UNIT && ((Creature*)this)->isPet())
+    else if(GetTypeId() == TYPEID_UNIT)
     {
-        Pet *pet = ((Pet*)this);
-        if(pet->isControlled())
+        if(Unit *owner = GetCharmerOrOwner())
         {
-            Unit *owner = GetOwner();
-            if(owner && (owner->GetTypeId() == TYPEID_PLAYER) && ((Player*)owner)->GetGroup())
+            if((owner->GetTypeId() == TYPEID_PLAYER) && ((Player*)owner)->GetGroup())
             {
                 ((Player*)owner)->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_PET_AURAS);
-                pet->SetAuraUpdateMask(slot);
+                SetAuraUpdateMask(slot);
             }
         }
     }
@@ -13407,6 +13412,7 @@ void Unit::NearTeleportTo( float x, float y, float z, float orientation, bool ca
         ((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));
     else
     {
+        ExitVehicle();
         Creature* c = (Creature*)this;
         // Creature relocation acts like instant movement generator, so current generator expects interrupt/reset calls to react properly
         if (!c->GetMotionMaster()->empty())
@@ -13477,6 +13483,134 @@ struct SetPvPHelper
     void operator()(Unit* unit) const { unit->SetPvP(state); }
     bool state;
 };
+void Unit::EnterVehicle(Vehicle *vehicle, int8 seat_id, bool force)
+{
+    // dont allow multiple vehicles
+    ExitVehicle();
+
+    RemoveSpellsCausingAura(SPELL_AURA_MOUNTED);
+    // NOTE : shapeshift too?
+
+    Vehicle *v = vehicle->FindFreeSeat(&seat_id, force);
+    if(!v)
+        return;
+
+    VehicleEntry const *ve = sVehicleStore.LookupEntry(v->GetVehicleId());
+    if(!ve)
+        return;
+
+    VehicleSeatEntry const *veSeat = sVehicleSeatStore.LookupEntry(ve->m_seatID[seat_id]);
+    if(!veSeat)
+        return;
+
+    m_SeatData.OffsetX = (veSeat->m_attachmentOffsetX + v->GetObjectSize()) * GetFloatValue(OBJECT_FIELD_SCALE_X);      // transport offsetX
+    m_SeatData.OffsetY = (veSeat->m_attachmentOffsetY + v->GetObjectSize()) * GetFloatValue(OBJECT_FIELD_SCALE_X);      // transport offsetY
+    m_SeatData.OffsetZ = (veSeat->m_attachmentOffsetZ + v->GetObjectSize()) * GetFloatValue(OBJECT_FIELD_SCALE_X);      // transport offsetZ
+    m_SeatData.Orientation = veSeat->m_passengerYaw;                                                                    // NOTE : needs confirmation
+    m_SeatData.c_time = v->GetCreationTime();
+    m_SeatData.dbc_seat = veSeat->m_ID;
+    m_SeatData.seat = seat_id;
+    m_SeatData.s_flags = sObjectMgr.GetSeatFlags(veSeat->m_ID);
+    m_SeatData.v_flags = v->GetVehicleFlags();
+
+    addUnitState(UNIT_STAT_ON_VEHICLE);
+    InterruptNonMeleeSpells(false);
+
+    if(Pet *pet = GetPet())
+        pet->Remove(PET_SAVE_AS_CURRENT);
+
+    if(GetTypeId() == TYPEID_PLAYER)
+        ((Player*)this)->SendEnterVehicle(v);
+
+    WorldPacket data(SMSG_MONSTER_MOVE_TRANSPORT, 60);
+    data.append(GetPackGUID());
+    data.append(v->GetPackGUID());
+    data << uint8(m_SeatData.seat);
+    data << uint8(0);                                       // new in 3.1
+    data << v->GetPositionX() << v->GetPositionY() << v->GetPositionZ();
+    data << uint32(getMSTime());
+
+    data << uint8(4);                                       // unknown
+    data << float(0);                                       // facing angle
+
+    data << uint32(SPLINEFLAG_UNKNOWN9);
+
+    data << uint32(0);                                      // Time in between points
+    data << uint32(1);                                      // 1 single waypoint
+    data << m_SeatData.OffsetX;
+    data << m_SeatData.OffsetY;
+    data << m_SeatData.OffsetZ;
+    SendMessageToSet(&data, true);
+
+    v->AddPassenger(this, seat_id, force);
+}
+
+void Unit::ExitVehicle()
+{
+    if(uint64 vehicleGUID = GetVehicleGUID())
+    {
+        float v_size = 0.0f;
+        if(Vehicle *vehicle = ObjectAccessor::GetVehicle(vehicleGUID))
+        {
+            if(m_SeatData.s_flags & SF_MAIN_RIDER)
+            {
+                if(vehicle->GetVehicleFlags() & VF_DESPAWN_AT_LEAVE)
+                {
+                    // will be deleted at next update
+                    vehicle->SetSpawnDuration(1);
+                }
+            }
+            v_size = vehicle->GetObjectSize();
+            vehicle->RemovePassenger(this);
+        }
+        SetVehicleGUID(0);
+
+        clearUnitState(UNIT_STAT_ON_VEHICLE);
+
+        if(GetTypeId() == TYPEID_PLAYER)
+        {
+            ((Player*)this)->ResummonPetTemporaryUnSummonedIfAny();
+            ((Player*)this)->m_movementInfo.RemoveMovementFlag(MOVEFLAG_ONTRANSPORT);
+            ((Player*)this)->m_movementInfo.RemoveMovementFlag(MOVEFLAG_ROOT);
+        }
+
+        float x = GetPositionX();
+        float y = GetPositionY();
+        float z = GetPositionZ() + 2.0f;
+        GetClosePoint(x, y, z, 2.0f + v_size);
+        SendMonsterMove(x, y, z, SPLINETYPE_NORMAL, SPLINEFLAG_WALKMODE, 0);
+    }
+}
+
+void Unit::BuildVehicleInfo(Unit *target)
+{
+    if(!target)
+        return;
+
+    if(!target->GetVehicleGUID())
+        return;
+
+    uint32 veh_time = getMSTimeDiff(target->m_SeatData.c_time,getMSTime());
+    WorldPacket data(MSG_MOVE_HEARTBEAT, 100);
+    data.append(target->GetPackGUID());
+    data << uint32(MOVEFLAG_ONTRANSPORT | MOVEFLAG_ROOT);
+    data << uint16(0);
+    data << uint32(getMSTime());
+    data << float(target->GetPositionX());
+    data << float(target->GetPositionY());
+    data << float(target->GetPositionZ());
+    data << float(target->GetOrientation());
+    data.appendPackGUID(target->GetVehicleGUID());
+    data << float(target->m_SeatData.OffsetX);
+    data << float(target->m_SeatData.OffsetY);
+    data << float(target->m_SeatData.OffsetZ);
+    data << float(target->m_SeatData.Orientation);
+    data << uint32(veh_time);
+    data << uint8 (target->m_SeatData.seat);
+    data << uint32(0);
+    if(GetTypeId() == TYPEID_PLAYER)
+        ((Player*)this)->GetSession()->SendPacket(&data);
+}
 
 void Unit::SetPvP( bool state )
 {
diff --git a/src/game/Unit.h b/src/game/Unit.h
index 545510b..8bb7d91 100644
--- a/src/game/Unit.h
+++ b/src/game/Unit.h
@@ -300,6 +300,7 @@ class Pet;
 class Path;
 class PetAura;
 class Totem;
+class Vehicle;
 
 struct SpellImmune
 {
@@ -433,24 +434,25 @@ enum UnitState
     UNIT_STAT_FOLLOW_MOVE     = 0x00008000,
     UNIT_STAT_FLEEING         = 0x00010000,                     // FleeMovementGenerator/TimedFleeingMovementGenerator active/onstack
     UNIT_STAT_FLEEING_MOVE    = 0x00020000,
+    UNIT_STAT_ON_VEHICLE      = 0x00040000,                     // Unit is on vehicle
 
     // masks (only for check)
 
     // can't move currently
-    UNIT_STAT_CAN_NOT_MOVE    = UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_DIED,
+    UNIT_STAT_CAN_NOT_MOVE    = UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_DIED | UNIT_STAT_ON_VEHICLE,
 
     // stay by different reasons
     UNIT_STAT_NOT_MOVE        = UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_DIED |
-                                UNIT_STAT_DISTRACTED,
+                                UNIT_STAT_DISTRACTED | UNIT_STAT_ON_VEHICLE,
 
     // stay or scripted movement for effect( = in player case you can't move by client command)
     UNIT_STAT_NO_FREE_MOVE    = UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_DIED |
                                 UNIT_STAT_IN_FLIGHT |
-                                UNIT_STAT_CONFUSED | UNIT_STAT_FLEEING,
+                                UNIT_STAT_CONFUSED | UNIT_STAT_FLEEING | UNIT_STAT_ON_VEHICLE,
 
     // not react at move in sight or other
     UNIT_STAT_CAN_NOT_REACT   = UNIT_STAT_STUNNED | UNIT_STAT_DIED |
-                                UNIT_STAT_CONFUSED | UNIT_STAT_FLEEING,
+                                UNIT_STAT_CONFUSED | UNIT_STAT_FLEEING | UNIT_STAT_ON_VEHICLE,
 
     // masks (for check or reset)
 
@@ -1063,6 +1065,24 @@ typedef std::set<uint64> GuardianPetList;
 
 struct SpellProcEventEntry;                                 // used only privately
 
+// vehicle system
+struct SeatData
+{
+    SeatData() : OffsetX(0.0f), OffsetY(0.0f),  OffsetZ(0.0f), Orientation(0.0f),
+                c_time(0), dbc_seat(0), seat(0), s_flags(0), v_flags(0) {}
+
+    float OffsetX;
+    float OffsetY;
+    float OffsetZ;
+    float Orientation;
+    uint32 c_time;
+    uint32 dbc_seat;
+    uint8 seat;
+    //custom, used as speedup
+    uint32 s_flags;
+    uint32 v_flags;
+};
+
 class MANGOS_DLL_SPEC Unit : public WorldObject
 {
     public:
@@ -1319,6 +1339,10 @@ class MANGOS_DLL_SPEC Unit : public WorldObject
         }
         bool HasAura(uint32 spellId) const;
 
+        const uint64& GetAuraUpdateMask() const { return m_auraUpdateMask; }
+        void SetAuraUpdateMask(uint8 slot) { m_auraUpdateMask |= (uint64(1) << slot); }
+        void ResetAuraUpdateMask() { m_auraUpdateMask = 0; }
+
         bool virtual HasSpell(uint32 /*spellID*/) const { return false; }
 
         bool HasStealthAura()      const { return HasAuraType(SPELL_AURA_MOD_STEALTH); }
@@ -1414,6 +1438,7 @@ class MANGOS_DLL_SPEC Unit : public WorldObject
         Unit* GetCharm() const;
         void Uncharm();
         Unit* GetCharmerOrOwner() const { return GetCharmerGUID() ? GetCharmer() : GetOwner(); }
+        Unit* GetCharmOrPet() const { return GetCharmGUID() ? GetCharm() : (Unit*)GetPet(); }
         Unit* GetCharmerOrOwnerOrSelf()
         {
             if(Unit* u = GetCharmerOrOwner())
@@ -1792,6 +1817,15 @@ class MANGOS_DLL_SPEC Unit : public WorldObject
         // Movement info
         MovementInfo m_movementInfo;
 
+         // vehicle system
+         void EnterVehicle(Vehicle *vehicle, int8 seat_id, bool force = false);
+         void ExitVehicle();
+         uint64 GetVehicleGUID() { return m_vehicleGUID; }
+         void SetVehicleGUID(uint64 guid) { m_vehicleGUID = guid; }
+         // using extra variables to avoid problems with transports
+         SeatData m_SeatData;
+         void BuildVehicleInfo(Unit *target = NULL);
+
     protected:
         explicit Unit ();
 
@@ -1839,6 +1873,8 @@ class MANGOS_DLL_SPEC Unit : public WorldObject
         uint32 m_reactiveTimer[MAX_REACTIVE];
         uint32 m_regenTimer;
         uint32 m_lastManaUseTimer;
+        uint64  m_auraUpdateMask;
+        uint64 m_vehicleGUID;
 
         uint64 m_InteractionObject;
 
diff --git a/src/game/Vehicle.cpp b/src/game/Vehicle.cpp
index b92e542..a1e50be 100644
--- a/src/game/Vehicle.cpp
+++ b/src/game/Vehicle.cpp
@@ -18,12 +18,14 @@
 
 #include "Common.h"
 #include "Log.h"
-#include "ObjectMgr.h"
 #include "Vehicle.h"
 #include "Unit.h"
 #include "Util.h"
+#include "WorldPacket.h"
+#include "InstanceData.h"
 
-Vehicle::Vehicle() : Creature(CREATURE_SUBTYPE_VEHICLE), m_vehicleId(0)
+Vehicle::Vehicle() : Creature(CREATURE_SUBTYPE_VEHICLE), m_vehicleId(0), m_vehicleInfo(NULL), m_spawnduration(0),
+                     despawn(false), m_creation_time(0), m_VehicleData(NULL)
 {
     m_updateFlag = (UPDATEFLAG_LIVING | UPDATEFLAG_HAS_POSITION | UPDATEFLAG_VEHICLE);
 }
@@ -54,42 +56,690 @@ void Vehicle::RemoveFromWorld()
 void Vehicle::setDeathState(DeathState s)                       // overwrite virtual Creature::setDeathState and Unit::setDeathState
 {
     Creature::setDeathState(s);
+    if(s == JUST_DIED)
+    {
+        if(GetVehicleFlags() & VF_DESPAWN_NPC)
+            Dismiss();
+        else
+            RemoveAllPassengers();
+    }
 }
 
 void Vehicle::Update(uint32 diff)
 {
     Creature::Update(diff);
+    InstallAllAccessories();
+
+    if(despawn)
+    {
+        m_spawnduration -= diff;
+        if(m_spawnduration < 0)
+            Dismiss();
+        despawn = false;
+    }
+
+    if(m_regenTimer <= diff)
+    {
+        RegeneratePower(getPowerType());
+        m_regenTimer = 4000;
+    }
+    else
+        m_regenTimer -= diff;
 }
 
-bool Vehicle::Create(uint32 guidlow, Map *map, uint32 Entry, uint32 vehicleId, uint32 team)
+void Vehicle::RegeneratePower(Powers power)
+{
+    uint32 curValue = GetPower(power);
+    uint32 maxValue = GetMaxPower(power);
+
+    if (curValue >= maxValue)
+        return;
+
+    float addvalue = 0.0f;
+
+    // hack: needs more research of power type from the dbc. 
+    // It must contains some info about vehicles like Salvaged Chopper.
+    if(m_vehicleInfo->m_powerType == POWER_TYPE_PYRITE)
+        return;
+
+    addvalue = 20.0f;
+
+    ModifyPower(power, (int32)addvalue);
+}
+
+bool Vehicle::Create(uint32 guidlow, Map *map, uint32 phaseMask, uint32 Entry, uint32 vehicleId, uint32 team, const CreatureData *data)
 {
     SetMap(map);
+    SetPhaseMask(phaseMask,false);
+
+    CreatureInfo const *cinfo = sObjectMgr.GetCreatureTemplate(Entry);
+    if(!cinfo)
+    {
+        sLog.outErrorDb("Creature entry %u does not exist.", Entry);
+        return false;
+    }
 
     Object::_Create(guidlow, Entry, HIGHGUID_VEHICLE);
 
-    if(!InitEntry(Entry, team))
+    if(!UpdateEntry(Entry, team, data))
         return false;
 
-    m_defaultMovementType = IDLE_MOTION_TYPE;
+    if(!vehicleId)
+    {
+        CreatureDataAddon const *cainfo = GetCreatureAddon();
+        if(!cainfo)
+            return false;
+        vehicleId = cainfo->vehicle_id;
+    }
+    if(!SetVehicleId(vehicleId))
+        return false;
 
-    AIM_Initialize();
+    LoadCreaturesAddon();
 
-    SetVehicleId(vehicleId);
+    m_regenHealth = false;
+    m_creation_time = getMSTime();
 
-    SetUInt32Value(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK);
     SetFloatValue(UNIT_FIELD_HOVERHEIGHT, 1.0f);
+    //RemoveMonsterMoveFlag(MONSTER_MOVE_WALK);
+
+    //Notify the map's instance data.
+    //Only works if you create the object in it, not if it is moves to that map.
+    //Normally non-players do not teleport to other maps.
+    if(map->IsDungeon() && ((InstanceMap*)map)->GetInstanceData())
+    {
+        ((InstanceMap*)map)->GetInstanceData()->OnCreatureCreate(this);
+    }
+    
+    if(m_vehicleInfo->m_powerType == POWER_TYPE_STEAM)
+    {
+        setPowerType(POWER_ENERGY);
+        SetMaxPower(POWER_ENERGY, 100);
+        SetPower(POWER_ENERGY, 100);
+    }
+    else if(m_vehicleInfo->m_powerType == POWER_TYPE_PYRITE)
+    {
+        setPowerType(POWER_ENERGY);
+        SetMaxPower(POWER_ENERGY, 50);
+        SetPower(POWER_ENERGY, 50);
+    }
+    else
+    {
+        for (uint32 i = 0; i < MAX_VEHICLE_SPELLS; ++i)
+        {
+            if(!GetVehicleData()->v_spells[i])
+                continue;
+            SpellEntry const *spellInfo = sSpellStore.LookupEntry(GetVehicleData()->v_spells[i]);
+            if(!spellInfo)
+                continue;
 
-    CreatureInfo const *ci = GetCreatureInfo();
-    setFaction(team == ALLIANCE ? ci->faction_A : ci->faction_H);
+            if(spellInfo->powerType == POWER_MANA)
+                break;
 
-    SelectLevel(ci);
+            if(spellInfo->powerType == POWER_ENERGY)
+            {
+                setPowerType(POWER_ENERGY);
+                SetMaxPower(POWER_ENERGY, 100);
+                SetPower(POWER_ENERGY, 100);
+                break;
+            }
+        }
+    }
+    SetHealth(GetMaxHealth());
+    InstallAllAccessories();
 
     return true;
 }
 
+bool Vehicle::SetVehicleId(uint32 vehicleid)
+{
+    VehicleEntry const *vehicleInfo = sVehicleStore.LookupEntry(vehicleid);
+    if(!vehicleInfo)
+        return false;
+
+    m_vehicleId = vehicleid;
+    m_vehicleInfo = vehicleInfo;
+
+    // can be NULL
+    VehicleDataStructure const *VDStructure = sObjectMgr.GetVehicleData(vehicleid);
+    if(VDStructure)
+        m_VehicleData = VDStructure;
+
+    InitSeats();
+    EmptySeatsCountChanged();
+    return true;
+}
+
+void Vehicle::InitSeats()
+{
+    m_Seats.clear();
+
+    for(uint32 i = 0; i < MAX_SEAT; ++i)
+    {
+        uint32 seatId = m_vehicleInfo->m_seatID[i];
+        if(seatId)
+        {
+            if(VehicleSeatEntry const *veSeat = sVehicleSeatStore.LookupEntry(seatId))
+            {
+                VehicleSeat newseat;
+                //newseat.seatInfo = veSeat;
+                newseat.passenger = NULL;
+                newseat.flags = SEAT_FREE;
+                newseat.vs_flags = sObjectMgr.GetSeatFlags(seatId);
+                m_Seats[i] = newseat;
+            }
+        }
+    }
+    // NOTE : there can be vehicles without seats (eg. 180) - probably some TEST vehicles
+}
+void Vehicle::ChangeSeatFlag(uint8 seat, uint8 flag)
+{
+    SeatMap::iterator i_seat = m_Seats.find(seat);
+    // this should never happen
+    if(i_seat == m_Seats.end())
+        return;
+
+    if(i_seat->second.flags != flag)
+    {
+        i_seat->second.flags = flag;
+        EmptySeatsCountChanged();
+    }
+}
+Vehicle* Vehicle::FindFreeSeat(int8 *seatid, bool force)
+{
+    SeatMap::const_iterator i_seat = m_Seats.find(*seatid);
+    if(i_seat == m_Seats.end())
+        return GetFirstEmptySeat(seatid, force);
+    if((i_seat->second.flags & (SEAT_FULL | SEAT_VEHICLE_FULL)) || (!force && (i_seat->second.vs_flags & SF_UNACCESSIBLE)))
+        return GetNextEmptySeat(seatid, true, force);
+    if(i_seat->second.flags & SEAT_VEHICLE_FREE)
+    {
+        // this should never be NULL
+        if(Vehicle *v = (Vehicle*)i_seat->second.passenger)
+            return v->FindFreeSeat(seatid, force);
+        return NULL;
+    }
+    return this;
+}
+
+Vehicle* Vehicle::GetFirstEmptySeat(int8 *seatId, bool force)
+{
+    for(SeatMap::iterator itr = m_Seats.begin(); itr != m_Seats.end(); ++itr)
+    {
+        if(itr->second.flags & SEAT_FREE)
+        {
+            if(!force && (itr->second.vs_flags & SF_UNACCESSIBLE))
+                continue;
+
+            *seatId = itr->first;
+            return this;
+        }
+        else if(itr->second.flags & SEAT_VEHICLE_FREE)
+        {
+            *seatId = itr->first;
+            if(Vehicle *v = (Vehicle*)itr->second.passenger)
+                return v->FindFreeSeat(seatId, force);
+        }
+    }
+
+    return NULL;
+}
+
+Vehicle* Vehicle::GetNextEmptySeat(int8 *seatId, bool next, bool force)
+{
+    SeatMap::const_iterator i_seat = m_Seats.find(*seatId);
+    if(i_seat == m_Seats.end()) return GetFirstEmptySeat(seatId, force);
+
+    while((i_seat->second.flags & (SEAT_FULL | SEAT_VEHICLE_FULL)) || (!force && (i_seat->second.vs_flags & SF_UNACCESSIBLE)))
+    {
+        if(next)
+        {
+            ++i_seat;
+            if(i_seat == m_Seats.end())
+                i_seat = m_Seats.begin();
+        }
+        else
+        {
+            if(i_seat == m_Seats.begin())
+                i_seat = m_Seats.end();
+            --i_seat;
+        }
+        if(i_seat->first == *seatId)
+            return NULL;
+    }
+    *seatId = i_seat->first;
+    if(i_seat->second.flags & SEAT_VEHICLE_FREE)
+    {
+        if(Vehicle *v = (Vehicle*)i_seat->second.passenger)
+            return v->FindFreeSeat(seatId, force);
+        return NULL;
+    }
+
+    return this;
+}
+
+int8 Vehicle::GetEmptySeatsCount(bool force)
+{
+    int8 count = 0;
+    for(SeatMap::iterator itr = m_Seats.begin(); itr != m_Seats.end(); ++itr)
+   {
+        if(itr->second.flags & (SEAT_FREE | SEAT_VEHICLE_FREE))
+        {
+            if(!force && (itr->second.vs_flags & SF_UNACCESSIBLE))
+                continue;
+
+            count++;
+        }
+    }
+
+    return count;
+}
+
+void Vehicle::EmptySeatsCountChanged()
+{
+    uint8 m_count = GetTotalSeatsCount();
+    uint8 p_count = GetEmptySeatsCount(false);
+    uint8 u_count = GetEmptySeatsCount(true);
+
+    // seats accesibles by players
+    if(p_count > 0)
+        SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK);
+    else
+        RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK);
+
+    if(u_count == m_count)
+    {
+        RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED);
+    }
+    else
+        SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED);
+
+    if(uint64 vehicleGUID = GetVehicleGUID())
+    {
+        if(Vehicle *vehicle = ObjectAccessor::GetVehicle(vehicleGUID))
+        {
+            if(u_count > 0)
+                vehicle->ChangeSeatFlag(m_SeatData.seat, SEAT_VEHICLE_FREE);
+            else
+                vehicle->ChangeSeatFlag(m_SeatData.seat, SEAT_VEHICLE_FULL);
+        }
+    }
+}
+
+
+
 void Vehicle::Dismiss()
 {
+    RemoveAllPassengers();
     SendObjectDeSpawnAnim(GetGUID());
     CombatStop();
     AddObjectToRemoveList();
 }
+
+void Vehicle::RellocatePassengers(Map *map)
+{
+    for(SeatMap::iterator itr = m_Seats.begin(); itr != m_Seats.end(); ++itr)
+    {
+        if(itr->second.flags & SEAT_FULL)
+        {
+            // passenger cant be NULL here
+            Unit *passengers = itr->second.passenger;
+            assert(passengers);
+
+            float xx = GetPositionX() + passengers->m_SeatData.OffsetX;
+            float yy = GetPositionY() + passengers->m_SeatData.OffsetY;
+            float zz = GetPositionZ() + passengers->m_SeatData.OffsetZ;
+            //float oo = passengers->m_SeatData.Orientation;
+            // this is not correct, we should recalculate
+            // actual rotation depending on vehicle
+            float oo = passengers->GetOrientation();
+
+            if(passengers->GetTypeId() == TYPEID_PLAYER)
+                ((Player*)passengers)->SetPosition(xx, yy, zz, oo);
+            else
+                map->CreatureRelocation((Creature*)passengers, xx, yy, zz, oo);
+        }
+        else if(itr->second.flags & (SEAT_VEHICLE_FULL | SEAT_VEHICLE_FREE))
+        {
+            // passenger cant be NULL here
+            Unit *passengers = itr->second.passenger;
+            assert(passengers);
+
+            float xx = GetPositionX() + passengers->m_SeatData.OffsetX;
+            float yy = GetPositionY() + passengers->m_SeatData.OffsetY;
+            float zz = GetPositionZ() + passengers->m_SeatData.OffsetZ;
+            //float oo = passengers->m_SeatData.Orientation;
+            // this is not correct, we should recalculate
+            // actual rotation depending on vehicle
+            float oo = passengers->GetOrientation();
+
+            map->CreatureRelocation((Creature*)passengers, xx, yy, zz, oo);
+            ((Vehicle*)passengers)->RellocatePassengers(map);
+        }
+    }
+}
+
+void Vehicle::AddPassenger(Unit *unit, int8 seatId, bool force)
+{
+    SeatMap::iterator seat;
+    seat = m_Seats.find(seatId);
+
+    // this should never happen
+    if(seat == m_Seats.end())
+        return;
+
+    unit->SetVehicleGUID(GetGUID());
+
+    seat->second.passenger = unit;
+    if(unit->GetTypeId() == TYPEID_UNIT && ((Creature*)unit)->isVehicle())
+    {
+        if(((Vehicle*)unit)->GetEmptySeatsCount(true) == 0)
+            seat->second.flags = SEAT_VEHICLE_FULL;
+        else
+            seat->second.flags = SEAT_VEHICLE_FREE;
+    }
+    else
+    {
+        seat->second.flags = SEAT_FULL;
+    }
+
+    if(unit->GetTypeId() == TYPEID_PLAYER)
+    {
+        WorldPacket data0(SMSG_FORCE_MOVE_ROOT, 10);
+        data0.append(unit->GetPackGUID());
+        data0 << (uint32)((seat->second.vs_flags & SF_CAN_CAST) ? 2 : 0);
+        unit->SendMessageToSet(&data0,true);
+    }
+
+    if(seat->second.vs_flags & SF_MAIN_RIDER)
+    {
+        if(!(GetVehicleFlags() & VF_MOVEMENT))
+        {
+            GetMotionMaster()->Clear(false);
+            GetMotionMaster()->MoveIdle();
+            SetCharmerGUID(unit->GetGUID());
+            unit->SetUInt64Value(UNIT_FIELD_CHARM, GetGUID());
+            if(unit->GetTypeId() == TYPEID_PLAYER)
+            {
+                ((Player*)unit)->SetMoverInQueve(this);
+                ((Player*)unit)->SetClientControl(this, 1);
+            }
+            if(canFly() || HasAuraType(SPELL_AURA_FLY) || HasAuraType(SPELL_AURA_MOD_INCREASE_FLIGHT_SPEED))
+            {
+                WorldPacket data3(SMSG_MOVE_SET_CAN_FLY, 12);
+                data3.append(GetPackGUID());
+                data3 << (uint32)(0);
+                SendMessageToSet(&data3,false);
+            }
+        }
+
+        SpellClickInfoMapBounds clickPair = sObjectMgr.GetSpellClickInfoMapBounds(GetEntry());
+        for(SpellClickInfoMap::const_iterator itr = clickPair.first; itr != clickPair.second; ++itr)
+        {
+            if (unit->GetTypeId() == TYPEID_UNIT || itr->second.IsFitToRequirements((Player*)unit))
+            {
+                Unit *caster = (itr->second.castFlags & 0x1) ? unit : this;
+                Unit *target = (itr->second.castFlags & 0x2) ? unit : this;
+
+                caster->CastSpell(target, itr->second.spellId, true);
+            }
+        }
+        if(unit->GetTypeId() == TYPEID_PLAYER)
+        {
+            // it should be added only on rider enter?
+            if(((Player*)unit)->GetGroup())
+                ((Player*)unit)->SetGroupUpdateFlag(GROUP_UPDATE_VEHICLE);
+
+            ((Player*)unit)->SetFarSightGUID(GetGUID());
+
+            BuildVehicleActionBar((Player*)unit);
+        }
+
+        if(!(GetVehicleFlags() & VF_FACTION))
+            setFaction(unit->getFaction());
+
+        if(GetVehicleFlags() & VF_CANT_MOVE)
+        {
+            WorldPacket data2(SMSG_FORCE_MOVE_ROOT, 10);
+            data2.append(GetPackGUID());
+            data2 << (uint32)(2);
+            SendMessageToSet(&data2,false);
+        }
+
+        if(GetVehicleFlags() & VF_NON_SELECTABLE)
+            SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+    }
+    if(seat->second.vs_flags & SF_UNATTACKABLE)
+        unit->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+
+    EmptySeatsCountChanged();
+}
+
+void Vehicle::RemovePassenger(Unit *unit)
+{
+    SeatMap::iterator seat;
+    for(seat = m_Seats.begin(); seat != m_Seats.end(); ++seat)
+    {
+        if((seat->second.flags & (SEAT_FULL | SEAT_VEHICLE_FREE | SEAT_VEHICLE_FULL)) && seat->second.passenger == unit)
+        {
+            unit->SetVehicleGUID(0);
+
+            if(seat->second.vs_flags & SF_MAIN_RIDER)
+            {
+                RemoveSpellsCausingAura(SPELL_AURA_CONTROL_VEHICLE);
+                if(unit->GetTypeId() == TYPEID_PLAYER)
+                {
+                    ((Player*)unit)->SetMover(unit);
+                    ((Player*)unit)->SetClientControl(unit, 1);
+                    ((Player*)unit)->SetMoverInQueve(NULL);
+                    ((Player*)unit)->RemovePetActionBar();
+
+                    if(((Player*)unit)->GetGroup())
+                        ((Player*)unit)->SetGroupUpdateFlag(GROUP_UPDATE_VEHICLE);
+                }
+                unit->SetCharm(NULL);
+                SetCharmerGUID(NULL);
+                setFaction(GetCreatureInfo()->faction_A);
+            }
+            if(GetVehicleFlags() & VF_NON_SELECTABLE)
+                RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+            if(seat->second.vs_flags & SF_UNATTACKABLE)
+                unit->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+            // restore player control
+            if(unit->GetTypeId() == TYPEID_PLAYER)
+            {
+                ((Player*)unit)->SetFarSightGUID(NULL);
+
+                if(seat->second.vs_flags & SF_CAN_CAST)
+                {
+                    WorldPacket data0(SMSG_FORCE_MOVE_UNROOT, 10);
+                    data0.append(unit->GetPackGUID());
+                    data0 << (uint32)(2);                        // can rotate
+                    unit->SendMessageToSet(&data0,true);
+                }
+                else
+                {
+                    WorldPacket data1(SMSG_FORCE_MOVE_UNROOT, 10);
+                    data1.append(unit->GetPackGUID());
+                    data1 << (uint32)(0);                        // cannot rotate
+                    unit->SendMessageToSet(&data1,true);
+                }
+            }
+            unit->m_SeatData.OffsetX = 0.0f;
+            unit->m_SeatData.OffsetY = 0.0f;
+            unit->m_SeatData.OffsetZ = 0.0f;
+            unit->m_SeatData.Orientation = 0.0f;
+            unit->m_SeatData.c_time = 0;
+            unit->m_SeatData.dbc_seat = 0;
+            unit->m_SeatData.seat = 0;
+            unit->m_SeatData.s_flags = 0;
+            unit->m_SeatData.v_flags = 0;
+
+            seat->second.passenger = NULL;
+            seat->second.flags = SEAT_FREE;
+            EmptySeatsCountChanged();
+            break;
+        }
+    }
+}
+
+void Vehicle::RemoveAllPassengers()
+{
+    for(SeatMap::iterator itr = m_Seats.begin(); itr != m_Seats.end(); ++itr)
+    {
+        if(itr->second.flags & SEAT_FULL)
+        {
+            if(Unit *passenger = itr->second.passenger)                     // this cant be NULL, but..
+                passenger->ExitVehicle();
+        }
+        else if(itr->second.flags & (SEAT_VEHICLE_FULL | SEAT_VEHICLE_FREE))
+        {
+            if(Unit *passenger = itr->second.passenger)                     // this cant be NULL, but..
+            {
+                passenger->ExitVehicle();
+                ((Vehicle*)passenger)->Dismiss();
+            }
+        }
+    }
+    // make sure everything is cleared
+    InitSeats();
+}
+
+bool Vehicle::HasSpell(uint32 spell) const
+{
+    if(!m_VehicleData)
+        return false;
+
+    for(uint8 j = 0; j < MAX_VEHICLE_SPELLS; j++)
+    {
+        if(m_VehicleData->v_spells[j] == spell)
+            return true;
+    }
+
+    return false;
+}
+
+void Vehicle::BuildVehicleActionBar(Player *plr) const
+{
+    WorldPacket data(SMSG_PET_SPELLS, 8+2+4+4+4*10+1+1);
+    data << uint64(GetGUID());
+    data << uint16(0x00000000);                     // creature family, not used in vehicles
+    data << uint32(0x00000000);                     // unk
+    data << uint32(0x00000101);                     // react state
+
+    for(uint32 i = 0; i <= MAX_VEHICLE_SPELLS; ++i)
+    {
+        data << uint16(m_VehicleData ? m_VehicleData->v_spells[i] : NULL) << uint8(0) << uint8(i+8);
+    }
+
+    data << uint8(0);                               //aditional spells in spellbook, not used in vehicles
+
+    uint8 cooldownsCount = m_CreatureSpellCooldowns.size() + m_CreatureCategoryCooldowns.size();
+    data << uint8(cooldownsCount);
+    time_t curTime = time(NULL);
+
+    for(CreatureSpellCooldowns::const_iterator itr = m_CreatureSpellCooldowns.begin(); itr != m_CreatureSpellCooldowns.end(); ++itr)
+    {
+        time_t cooldown = (itr->second > curTime) ? (itr->second - curTime) * IN_MILISECONDS : 0;
+
+        data << uint32(itr->first);                         // spellid
+        data << uint16(0);                                  // spell category?
+        data << uint32(cooldown);                           // cooldown
+        data << uint32(0);                                  // category cooldown
+    }
+
+    for(CreatureSpellCooldowns::const_iterator itr = m_CreatureCategoryCooldowns.begin(); itr != m_CreatureCategoryCooldowns.end(); ++itr)
+    {
+        time_t cooldown = (itr->second > curTime) ? (itr->second - curTime) * IN_MILISECONDS : 0;
+
+        data << uint32(itr->first);                         // spellid
+        data << uint16(0);                                  // spell category?
+        data << uint32(0);                                  // cooldown
+        data << uint32(cooldown);                           // category cooldown
+    }
+
+    plr->GetSession()->SendPacket(&data);
+
+    data.Initialize(SMSG_PET_GUIDS, 12);
+    data << uint32(1);                                        // count
+    data << uint64(GetGUID());
+    plr->GetSession()->SendPacket(&data);
+}
+void Vehicle::InstallAllAccessories()
+{
+    //TODO: Move this into DB!!!
+    switch(GetEntry())
+    {
+        //case 27850:InstallAccessory(27905,1);break;
+        case 28782:InstallAccessory(28768,0,false, false);break; // Acherus Deathcharger
+        case 28312:InstallAccessory(28319,7,true);break;
+        case 32627:InstallAccessory(32629,7,true);break;
+        case 32930:
+            InstallAccessory(32933,0);
+            InstallAccessory(32934,1);
+            break;
+        case 33109:InstallAccessory(33167,1, true);break;
+        case 33060:InstallAccessory(33067,7, true);break;
+        case 33113:
+            InstallAccessory(33114,0, true);
+            InstallAccessory(33114,1, true);
+            InstallAccessory(33114,2, true);
+            InstallAccessory(33114,3, true);
+            InstallAccessory(33139,7);
+            break;
+        case 33114:
+            InstallAccessory(33143,2); // Overload Control Device
+            InstallAccessory(33142,1); // Leviathan Defense Turret
+            break;
+        case 33214:InstallAccessory(33218,1,false,false);break; // Mechanolift 304-A
+    }
+}
+
+void Vehicle::InstallAccessory(uint32 entry, int8 seatId, bool isVehicle, bool minion)
+{
+    if(Unit *passenger = GetPassenger(seatId))
+    {
+        // already installed
+        if(passenger->GetEntry() == entry)
+        {
+            assert(passenger->GetTypeId() == TYPEID_UNIT);
+            return;
+        }
+        passenger->ExitVehicle(); // this should not happen
+    }
+
+    //TODO: accessory should be minion
+    if(isVehicle)
+    {
+        if(Vehicle *accessory = SummonVehicle(entry, 0, 0, 0, 0))
+        {
+            accessory->EnterVehicle(this, seatId);
+            // This is not good, we have to send update twice
+            WorldPacket data;
+            accessory->BuildHeartBeatMsg(&data);
+            accessory->SendMessageToSet(&data, false);
+        }
+    }else{
+        if(Creature *accessory = SummonCreature(entry, 0, 0, 0, 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 30000))
+        {
+            accessory->EnterVehicle(this, seatId);
+            // This is not good, we have to send update twice
+            WorldPacket data;
+            accessory->BuildHeartBeatMsg(&data);
+            accessory->SendMessageToSet(&data, false);
+        }
+    }
+}
+Unit *Vehicle::GetPassenger(int8 seatId) const
+{
+    SeatMap::const_iterator seat = m_Seats.find(seatId);
+    if(seat == m_Seats.end()) return NULL;
+    return seat->second.passenger;
+}
+void Vehicle::Die()
+{
+    for (SeatMap::iterator itr = m_Seats.begin(); itr != m_Seats.end(); ++itr)
+        if(Unit *passenger = itr->second.passenger)
+            if(((Creature*)passenger)->isVehicle())
+                passenger->setDeathState(JUST_DIED);
+    RemoveAllPassengers();
+}
\ No newline at end of file
diff --git a/src/game/Vehicle.h b/src/game/Vehicle.h
index 6560394..0b967d7 100644
--- a/src/game/Vehicle.h
+++ b/src/game/Vehicle.h
@@ -22,6 +22,34 @@
 #include "ObjectDefines.h"
 #include "Creature.h"
 #include "Unit.h"
+#include "ObjectMgr.h"
+
+struct VehicleSeat
+{
+    //VehicleSeatEntry const *seatInfo;
+    Unit* passenger;
+    uint8 flags;
+    uint32 vs_flags;
+};
+
+enum VehicleSeatFlags
+{
+    SEAT_FREE           = 0x01,                             // free seat
+    SEAT_FULL           = 0x02,                             // seat occupied by player/creature
+    // special cases
+    SEAT_VEHICLE_FREE   = 0x04,                             // seat occupied by vehicle, but that vehicle is free
+    SEAT_VEHICLE_FULL   = 0x08                              // seat occupied by vehicle and that vehicle is full too
+};
+
+enum PowerType
+{
+    POWER_TYPE_PYRITE = 41,
+    POWER_TYPE_STEAM  = 61
+};
+
+#define MAX_SEAT 8
+
+typedef std::map<int8, VehicleSeat> SeatMap;
 
 class Vehicle : public Creature
 {
@@ -32,19 +60,55 @@ class Vehicle : public Creature
         void AddToWorld();
         void RemoveFromWorld();
 
-        bool Create (uint32 guidlow, Map *map, uint32 Entry, uint32 vehicleId, uint32 team);
+        void Die();
+        bool Create (uint32 guidlow, Map *map, uint32 phaseMask, uint32 Entry, uint32 vehicleId, uint32 team, const CreatureData *data = NULL);
 
         void setDeathState(DeathState s);                   // overwrite virtual Creature::setDeathState and Unit::setDeathState
         void Update(uint32 diff);                           // overwrite virtual Creature::Update and Unit::Update
 
+        void RegeneratePower(Powers power);
+
         uint32 GetVehicleId() { return m_vehicleId; }
-        void SetVehicleId(uint32 vehicleid) { m_vehicleId = vehicleid; }
+        bool SetVehicleId(uint32 vehicleid);
+
+        void InitSeats();
+
+        void ChangeSeatFlag(uint8 seat, uint8 flag);
+        Vehicle* FindFreeSeat(int8 *seatid, bool force = true);
+        Vehicle* GetNextEmptySeat(int8 *seatId, bool next = true, bool force = true);
+        Vehicle* GetFirstEmptySeat(int8 *seatId, bool force = true);
+        int8 GetEmptySeatsCount(bool force = true);
+        void EmptySeatsCountChanged();
+        int8 GetTotalSeatsCount() { return m_Seats.size(); }
 
         void Dismiss();
 
+        void RellocatePassengers(Map *map);
+        void AddPassenger(Unit *unit, int8 seatId, bool force = true);
+        void RemovePassenger(Unit *unit);
+        void RemoveAllPassengers();
+
+        bool HasSpell(uint32 spell) const;
+        void SetSpawnDuration(int32 duration)
+        {
+            duration < 1 ? despawn = false : despawn = true;
+            m_spawnduration = duration;
+        }
+        VehicleDataStructure const* GetVehicleData() { return m_VehicleData; }
+        uint32 GetVehicleFlags() { return m_VehicleData ? m_VehicleData->v_flags : NULL; }
+        uint32 GetCreationTime() { return m_creation_time; }
+        void BuildVehicleActionBar(Player *plr) const;
+        void InstallAllAccessories();
+        Unit *GetPassenger(int8 seatId) const;
     protected:
         uint32 m_vehicleId;
-
+        VehicleEntry const *m_vehicleInfo;
+        VehicleDataStructure const *m_VehicleData;
+        uint32 m_creation_time;
+        SeatMap m_Seats;
+        bool despawn;
+        int32 m_spawnduration;
+        void InstallAccessory(uint32 entry, int8 seatId, bool isVehicle = false, bool minion = true);
     private:
         void SaveToDB(uint32, uint8)                        // overwrited of Creature::SaveToDB     - don't must be called
         {
diff --git a/src/game/World.cpp b/src/game/World.cpp
index ada384d..6ed5d22 100644
--- a/src/game/World.cpp
+++ b/src/game/World.cpp
@@ -1196,6 +1196,11 @@ void World::SetInitialWorldSettings()
     sLog.outString( "Loading Scripts text locales..." );    // must be after Load*Scripts calls
     sObjectMgr.LoadDbScriptStrings();
 
+    sLog.outString( "Loading VehicleData..." );
+    sObjectMgr.LoadVehicleData();
+    sLog.outString( "Loading VehicleSeatData..." );
+    sObjectMgr.LoadVehicleSeatData();
+
     sLog.outString( "Loading CreatureEventAI Texts...");
     sEventAIMgr.LoadCreatureEventAI_Texts(false);       // false, will checked in LoadCreatureEventAI_Scripts
 
diff --git a/src/game/WorldSession.h b/src/game/WorldSession.h
index 776b104..6b8d129 100644
--- a/src/game/WorldSession.h
+++ b/src/game/WorldSession.h
@@ -388,6 +388,11 @@ class MANGOS_DLL_SPEC WorldSession
         void HandleSetActiveMoverOpcode(WorldPacket &recv_data);
         void HandleMoveNotActiveMover(WorldPacket &recv_data);
         void HandleDismissControlledVehicle(WorldPacket &recv_data);
+        void HandleRequestVehicleExit(WorldPacket &recv_data);
+        void HandleRequestVehiclePrevSeat(WorldPacket &recv_data);
+        void HandleRequestVehicleNextSeat(WorldPacket &recv_data);
+        void HandleRequestVehicleSwitchSeat(WorldPacket &recv_data);
+        void HandleChangeSeatsOnControlledVehicle(WorldPacket &recv_data);
         void HandleMoveTimeSkippedOpcode(WorldPacket &recv_data);
 
         void HandleRequestRaidInfoOpcode( WorldPacket & recv_data );
diff --git a/src/game/debugcmds.cpp b/src/game/debugcmds.cpp
index c803cb4..2673e5d 100644
--- a/src/game/debugcmds.cpp
+++ b/src/game/debugcmds.cpp
@@ -627,7 +627,8 @@ bool ChatHandler::HandleDebugSpawnVehicle(const char* args)
 
     Vehicle *v = new Vehicle;
     Map *map = m_session->GetPlayer()->GetMap();
-    if (!v->Create(map->GenerateLocalLowGuid(HIGHGUID_VEHICLE), map, entry, id, m_session->GetPlayer()->GetTeam()))
+
+    if (!v->Create(sObjectMgr.GenerateLowGuid(HIGHGUID_VEHICLE), map, m_session->GetPlayer()->GetPhaseMaskForSpawn(), entry, id, m_session->GetPlayer()->GetTeam()))
     {
         delete v;
         return false;
@@ -647,6 +648,7 @@ bool ChatHandler::HandleDebugSpawnVehicle(const char* args)
     }
 
     map->Add((Creature*)v);
+    v->AIM_Initialize();
 
     return true;
 }
diff --git a/src/shared/Database/SQLStorage.cpp b/src/shared/Database/SQLStorage.cpp
index a7e9785..3c1ef05 100644
--- a/src/shared/Database/SQLStorage.cpp
+++ b/src/shared/Database/SQLStorage.cpp
@@ -27,9 +27,9 @@ extern DatabaseMysql  WorldDatabase;
 
 const char CreatureInfosrcfmt[]="iiiiiiiiiisssiiiiiiiiiiiffiffiifiiiiiiiiiiffiiiiiiiiiiiiiiiiiiisiiffliiiiiiiliiis";
 const char CreatureInfodstfmt[]="iiiiiiiiiisssiiiiiiiiiiiffiffiifiiiiiiiiiiffiiiiiiiiiiiiiiiiiiisiiffliiiiiiiliiii";
-const char CreatureDataAddonInfofmt[]="iiiiiis";
+const char CreatureDataAddonInfofmt[]="iiiiiiiss";
 const char CreatureModelfmt[]="iffbi";
-const char CreatureInfoAddonInfofmt[]="iiiiiis";
+const char CreatureInfoAddonInfofmt[]="iiiiiiiss";
 const char EquipmentInfofmt[]="iiii";
 const char GameObjectInfosrcfmt[]="iiissssiifiiiiiiiiiiiiiiiiiiiiiiiiiiiiiis";
 const char GameObjectInfodstfmt[]="iiissssiifiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii";
