Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- diff --git a/sql/v01_vehicle_table.sql b/sql/v01_vehicle_table.sql
- new file mode 100644
- index 0000000..55d7442
- --- /dev/null
- +++ b/sql/v01_vehicle_table.sql
- @@ -0,0 +1,36 @@
- +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';
- +
- +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';
- +
- +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;
- +
- +/* vehicle multi seat mounts */
- +ALTER TABLE creature_template
- + ADD COLUMN `VehicleEntry` mediumint(8) unsigned NOT NULL default '0' AFTER `PetSpellDataId`;
- diff --git a/sql/v02_vehicle_data.sql b/sql/v02_vehicle_data.sql
- new file mode 100644
- index 0000000..5851bc8
- --- /dev/null
- +++ b/sql/v02_vehicle_data.sql
- @@ -0,0 +1,714 @@
- +REPLACE INTO `vehicle_data` VALUES
- +(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),(68,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),(106,0,0,0,0,0,0,0,0,0,0,0,0),(107,0,0,0,0,0,0,0,0,0,0,0,0),
- +(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),(116,0,0,0,0,0,0,0,0,0,0,0,0),
- +(117,0,0,0,0,0,0,0,0,0,0,0,0),(118,0,0,0,0,0,0,0,0,0,0,0,0),(120,0,0,0,0,0,0,0,0,0,0,0,0),
- +(121,0,0,0,0,0,0,0,0,0,0,0,0),(122,0,0,0,0,0,0,0,0,0,0,0,0),(123,0,0,0,0,0,0,0,0,0,0,0,0),
- +(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),(135,0,0,0,0,0,0,0,0,0,0,0,0),(137,0,0,0,0,0,0,0,0,0,0,0,0),
- +(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),(156,0,0,0,0,0,0,0,0,0,0,0,0),(158,0,0,0,0,0,0,0,0,0,0,0,0),
- +(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),
- +(200,0,0,0,0,0,0,0,0,0,0,0,0),(201,0,0,0,0,0,0,0,0,0,0,0,0),(202,0,0,0,0,0,0,0,0,0,0,0,0),
- +(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),(210,0,0,0,0,0,0,0,0,0,0,0,0),(211,0,0,0,0,0,0,0,0,0,0,0,0),
- +(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),
- +(349,0,0,0,0,0,0,0,0,0,0,0,0),(352,0,0,0,0,0,0,0,0,0,0,0,0),(353,0,0,0,0,0,0,0,0,0,0,0,0),
- +(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),
- +(402,0,0,0,0,0,0,0,0,0,0,0,0),(405,0,0,0,0,0,0,0,0,0,0,0,0),(412,0,0,0,0,0,0,0,0,0,0,0,0),
- +(425,0,0,0,0,0,0,0,0,0,0,0,0),(430,0,0,0,0,0,0,0,0,0,0,0,0),(435,0,0,0,0,0,0,0,0,0,0,0,0),
- +(436,0,0,0,0,0,0,0,0,0,0,0,0),(437,0,0,0,0,0,0,0,0,0,0,0,0),(438,0,0,0,0,0,0,0,0,0,0,0,0),
- +(442,0,0,0,0,0,0,0,0,0,0,0,0),(443,0,0,0,0,0,0,0,0,0,0,0,0),(444,0,0,0,0,0,0,0,0,0,0,0,0),
- +(445,0,0,0,0,0,0,0,0,0,0,0,0),(446,0,0,0,0,0,0,0,0,0,0,0,0),(447,0,0,0,0,0,0,0,0,0,0,0,0),
- +(449,0,0,0,0,0,0,0,0,0,0,0,0),(452,0,0,0,0,0,0,0,0,0,0,0,0),(453,0,0,0,0,0,0,0,0,0,0,0,0),
- +(456,0,0,0,0,0,0,0,0,0,0,0,0),(461,0,0,0,0,0,0,0,0,0,0,0,0),(471,0,0,0,0,0,0,0,0,0,0,0,0),
- +(472,0,0,0,0,0,0,0,0,0,0,0,0),(477,0,0,0,0,0,0,0,0,0,0,0,0),(478,0,0,0,0,0,0,0,0,0,0,0,0),
- +(479,0,0,0,0,0,0,0,0,0,0,0,0),(480,0,0,0,0,0,0,0,0,0,0,0,0),(481,0,0,0,0,0,0,0,0,0,0,0,0),
- +(482,0,0,0,0,0,0,0,0,0,0,0,0),(483,0,0,0,0,0,0,0,0,0,0,0,0),(484,0,0,0,0,0,0,0,0,0,0,0,0),
- +(485,0,0,0,0,0,0,0,0,0,0,0,0),(486,0,0,0,0,0,0,0,0,0,0,0,0),(487,0,0,0,0,0,0,0,0,0,0,0,0),
- +(489,0,0,0,0,0,0,0,0,0,0,0,0),(492,0,0,0,0,0,0,0,0,0,0,0,0),(496,0,0,0,0,0,0,0,0,0,0,0,0),
- +(497,0,0,0,0,0,0,0,0,0,0,0,0),(498,0,0,0,0,0,0,0,0,0,0,0,0),(499,0,0,0,0,0,0,0,0,0,0,0,0),
- +(503,0,0,0,0,0,0,0,0,0,0,0,0),(509,0,0,0,0,0,0,0,0,0,0,0,0),(510,0,0,0,0,0,0,0,0,0,0,0,0),
- +(512,0,0,0,0,0,0,0,0,0,0,0,0),(514,0,0,0,0,0,0,0,0,0,0,0,0),(522,0,0,0,0,0,0,0,0,0,0,0,0),
- +(529,0,0,0,0,0,0,0,0,0,0,0,0),(531,0,0,0,0,0,0,0,0,0,0,0,0),(532,0,0,0,0,0,0,0,0,0,0,0,0),
- +(533,0,0,0,0,0,0,0,0,0,0,0,0),(535,0,0,0,0,0,0,0,0,0,0,0,0),(548,0,0,0,0,0,0,0,0,0,0,0,0),
- +(551,0,0,0,0,0,0,0,0,0,0,0,0),(554,0,0,0,0,0,0,0,0,0,0,0,0),(555,0,0,0,0,0,0,0,0,0,0,0,0),
- +(560,0,0,0,0,0,0,0,0,0,0,0,0),(562,0,0,0,0,0,0,0,0,0,0,0,0),(563,0,0,0,0,0,0,0,0,0,0,0,0),
- +(567,0,0,0,0,0,0,0,0,0,0,0,0),(586,0,0,0,0,0,0,0,0,0,0,0,0),(587,0,0,0,0,0,0,0,0,0,0,0,0),
- +(591,0,0,0,0,0,0,0,0,0,0,0,0),(599,0,0,0,0,0,0,0,0,0,0,0,0),(602,0,0,0,0,0,0,0,0,0,0,0,0),
- +(604,0,0,0,0,0,0,0,0,0,0,0,0),(610,0,0,0,0,0,0,0,0,0,0,0,0),(611,0,0,0,0,0,0,0,0,0,0,0,0),
- +(614,0,0,0,0,0,0,0,0,0,0,0,0),(615,0,0,0,0,0,0,0,0,0,0,0,0),(616,0,0,0,0,0,0,0,0,0,0,0,0),
- +(621,0,0,0,0,0,0,0,0,0,0,0,0),(622,0,0,0,0,0,0,0,0,0,0,0,0),(624,0,0,0,0,0,0,0,0,0,0,0,0),
- +(625,0,0,0,0,0,0,0,0,0,0,0,0),(636,0,0,0,0,0,0,0,0,0,0,0,0),(637,0,0,0,0,0,0,0,0,0,0,0,0),
- +(639,0,0,0,0,0,0,0,0,0,0,0,0),(647,0,0,0,0,0,0,0,0,0,0,0,0),(648,0,0,0,0,0,0,0,0,0,0,0,0),
- +(655,0,0,0,0,0,0,0,0,0,0,0,0),(700,0,0,0,0,0,0,0,0,0,0,0,0),(711,0,0,0,0,0,0,0,0,0,0,0,0),
- +(717,0,0,0,0,0,0,0,0,0,0,0,0),(718,0,0,0,0,0,0,0,0,0,0,0,0),(732,0,0,0,0,0,0,0,0,0,0,0,0),
- +(736,0,0,0,0,0,0,0,0,0,0,0,0),(745,0,0,0,0,0,0,0,0,0,0,0,0),(746,0,0,0,0,0,0,0,0,0,0,0,0),
- +(747,0,0,0,0,0,0,0,0,0,0,0,0),(753,0,0,0,0,0,0,0,0,0,0,0,0),(763,0,0,0,0,0,0,0,0,0,0,0,0),
- +(774,0,0,0,0,0,0,0,0,0,0,0,0);
- +
- +/* Mechano-hog, Mekgineer's Chopper */
- +UPDATE creature_template SET VehicleEntry = 318, IconName = 'vehichleCursor' WHERE entry IN (29929, 32286);
- +
- +/* Traveler's Tundra Mammoth, Grand Ice Mammoth, Grand Black War Mammoth, Grand Caravan Mammoth */
- +UPDATE creature_template SET VehicleEntry = 312, IconName = 'vehichleCursor' WHERE entry IN (32633, 32640, 31857, 31858, 31861, 31862, 32212, 32213);
- +
- +/* X-53 Touring Rocket */
- +UPDATE creature_template SET VehicleEntry = 774, IconName = 'vehichleCursor' WHERE entry = 40725;
- +
- +UPDATE creature_template SET minlevel = 80, maxlevel = 80 WHERE entry IN (28312,32627,28319,32629,28094,28670);
- +UPDATE creature_template SET speed_run = 2, InhabitType = 1 WHERE entry IN (28312,32627,28319,32629,28094,29929,28782);
- +UPDATE creature_template SET mechanic_immune_mask = 652951551 WHERE entry IN (28670,28312,32627,28319,32629,28094,29929,28782);
- +
- +/* Frostbrood Vanquisher */
- +UPDATE creature_template SET maxhealth = 133525, minhealth = 133525, maxmana = 51360, minmana = 51360, speed_run = 2.4, InhabitType = 3 WHERE entry = 28670;
- +DELETE FROM npc_spellclick_spells WHERE npc_entry in (28670);
- +INSERT INTO npc_spellclick_spells VALUES (28670, 52196, 12779, 1, 12779, 0);
- +REPLACE INTO creature_template_addon VALUES (28670, 0, 50331648, 1, 0, 1024, 156, NULL, '53112 0 53112 1 48602 2');
- +REPLACE INTO vehicle_data VALUES (156, 24, 53114, 0, 53110, 0, 0, 0, 0, 0, 0, 0, 0);
- +REPLACE INTO vehicle_seat_data VALUES (1986, 3),(1987, 8);
- +UPDATE quest_template SET ReqItemId1 = 39700, ReqItemCount1 = 1 WHERE entry = 12779;
- +
- +/* Argent Tournament (new) */
- +DELETE FROM creature WHERE id IN (33844,33845);
- +DELETE FROM creature_addon WHERE guid IN (SELECT guid FROM creature WHERE id IN (33844,33845));
- +REPLACE INTO vehicle_data VALUES (349, 24, 62544, 62575, 63010, 62552, 64077, 62863, 0, 0, 0, 0, 62853);
- +REPLACE INTO vehicle_seat_data VALUES ('3129', '1');
- +DELETE FROM npc_spellclick_spells WHERE npc_entry in (33842, 33843);
- +INSERT INTO npc_spellclick_spells VALUES (33842,63791,13829,1,0,3),(33842,63791,13839,1,0,3),(33842,63791,13838,1,0,3),(33843,63792,13828,1,0,3),(33843,63792,13837,1,0,3),(33843,63792,13835,1,0,3);
- +REPLACE INTO creature_template_addon VALUES (33844, 0, 0, 2049, 0, 0, 349, NULL, NULL),(33845, 0, 0, 2049, 0, 0, 349, NULL, NULL);
- +UPDATE creature_template SET AIName = 'NullAI' WHERE entry IN (33243,33229,33272);
- +/* Alliance and Horde Tournament Mounts (DaViper fixes) */
- +UPDATE creature_template SET minlevel = 80, maxlevel = 80, minhealth = 50000, maxhealth = 50000, minmana = 1000, maxmana = 1000, armor = 9730,
- +speed_run = 1.5, mindmg = 420, maxdmg = 630, attackpower = 157, dmg_multiplier = 1.4, rangeattacktime = 2000, unit_flags = 8, minrangedmg = 336,
- +maxrangedmg = 504, rangedattackpower = 126 WHERE entry IN (33217,33316,33317,33318,33319,33320,33321,33322,33323,33324,33844,33845);
- +
- +/* Quest Grand Theft Palomino (12680) */
- +REPLACE INTO spell_script_target VALUES (52264,1,28653);
- +REPLACE INTO vehicle_data VALUES (123, 4, 52264, 52268, 0, 0, 0, 0, 0, 0, 0, 0, 0);
- +REPLACE 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),(28606, 52263, 12680, 1, 12680, 3),(28607, 52263, 12680, 1, 12680, 3);
- +REPLACE INTO creature_template_addon VALUES (28605, 0, 0, 1, 0, 0, 123, NULL, NULL),(28606, 0, 0, 1, 0, 0, 123, NULL, NULL),(28607, 0, 0, 1, 0, 0, 123, NULL, NULL);
- +DELETE FROM creature_addon WHERE guid IN (SELECT guid FROM creature WHERE id IN (28605,28606,28607));
- +
- +/* Quest Into the Realm of Shadows (12687) */
- +REPLACE INTO spell_script_target VALUES (52349,1,28782);
- +UPDATE creature_template SET faction_A = 2082, faction_H = 2082, unit_flags = 32768 WHERE entry = 28782;
- +DELETE FROM creature_addon WHERE guid IN (SELECT guid FROM creature WHERE id = 28782);
- +REPLACE INTO vehicle_data VALUES (135, 4, 52362, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
- +REPLACE 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);
- +REPLACE INTO creature_template_addon VALUES (28782, 0, 0, 1, 0, 0, 135, NULL, NULL);
- +UPDATE quest_template SET SrcSpell = 52693 WHERE entry = 12687;
- +
- +/* 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);
- +REPLACE INTO creature_template_addon VALUES (29598, 0, 0, 1, 0, 0, 308, NULL, NULL);
- +REPLACE INTO `vehicle_data` VALUES (308, 24, 54897, 54907, 0, 0, 0, 0, 0, 0, 0, 0, 0);
- +REPLACE INTO vehicle_seat_data VALUES (2699, 1);
- +
- +/* Massacre At Light's Point (new) */
- +DELETE FROM npc_spellclick_spells WHERE npc_entry IN (28887,28833,28864);
- +INSERT INTO npc_spellclick_spells VALUES (28833,52447,12701,1,12701,1),(28887,52447,12701,1,12701,1),(28864,67373,0,0,0,1);
- +REPLACE INTO creature_template_addon VALUES (28887,0,0,2049,0,0,79,NULL,NULL),(28833,0,0,2049,0,0,79,NULL,NULL),(28864,0,0,0,0,0,143,NULL,'48602 0 48602 2');
- +REPLACE INTO vehicle_data VALUES (143,12,0,0,0,0,0,0,0,0,0,0,0),(79,5,52435,52576,0,52588,0,0,0,0,0,0,0);
- +REPLACE INTO vehicle_seat_data VALUES (1427, 1),(1902, 3);
- +UPDATE creature_model_info SET bounding_radius = 0 WHERE modelid = 25723;
- +UPDATE creature_template SET IconName = 'Gunner' WHERE entry IN (28887,28833);
- +UPDATE creature_template SET IconName = 'vehichleCursor', InhabitType = 3 WHERE entry IN (28864);
- +DELETE FROM creature_addon WHERE guid IN (SELECT guid FROM creature WHERE id IN (28887,28833,28864));
- +
- +/* Traveler's Tundra Mammoth, Grand Ice Mammoth */
- +DELETE FROM npc_spellclick_spells WHERE npc_entry IN (32633, 32640, 31857);
- +INSERT INTO npc_spellclick_spells VALUES (32633, 65403, 0, 0, 0, 0),(32640, 65403, 0, 0, 0, 0),(31857, 65403, 0, 0, 0, 0);
- +REPLACE INTO creature_template_addon VALUES (32633,0,0,0,0,0,312,NULL,NULL),(32640,0,0,0,0,0,312,NULL,NULL),(31857,0,0,0,0,0,312,NULL,NULL);
- +REPLACE INTO vehicle_data VALUES (312, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
- +
- +/* Salvaged Chopper */
- +DELETE FROM npc_spellclick_spells WHERE npc_entry IN (33062);
- +INSERT INTO npc_spellclick_spells VALUES (33062, 65403, 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, 4, 62974, 62286, 62299, 64660, 0, 0, 0, 0, 0, 0, 0);
- +REPLACE INTO vehicle_seat_data VALUES (3005, 3),(3004, 2);
- +UPDATE creature_model_info SET bounding_radius = '0.306' WHERE modelid IN (25870,25871);
- +
- +/* Salvaged Demolisher */
- +DELETE FROM npc_spellclick_spells WHERE npc_entry IN (33109);
- +INSERT INTO npc_spellclick_spells VALUES (33109, 65403, 0, 0, 0, 0);
- +REPLACE INTO creature_template_addon VALUES (33109, 0, 0, 0, 0, 0, 338, '33167 1', NULL);
- +REPLACE INTO vehicle_data VALUES (338, 4, 62306, 62490, 62308, 62324, 0, 0, 0, 0, 0, 0, 0);
- +REPLACE INTO vehicle_seat_data VALUES (3011, 3),(3146, 8),(3013, 8),(3147, 8);
- +
- +/* Salvaged Siege Engine */
- +DELETE FROM npc_spellclick_spells WHERE npc_entry IN (33060);
- +INSERT INTO npc_spellclick_spells VALUES (33060, 65403, 0, 0, 0, 0);
- +REPLACE INTO creature_template_addon VALUES (33060, 0, 0, 0, 0, 0, 336, '33067 7', NULL);
- +REPLACE INTO vehicle_data VALUES (336, 4, 62345, 62522, 62346, 0, 0, 0, 0, 0, 0, 0, 0);
- +REPLACE INTO vehicle_seat_data VALUES (3006, 3),(4026, 8),(4027, 8),(3009, 8);
- +
- +/* Salvaged Siege Turret */
- +DELETE FROM npc_spellclick_spells WHERE npc_entry = 33067;
- +INSERT INTO npc_spellclick_spells VALUES (33067, 65403, 0, 0, 0, 1);
- +REPLACE INTO creature_template_addon VALUES (33067, 0, 0, 0, 0, 0, 337, NULL, NULL);
- +REPLACE INTO vehicle_data VALUES (337, 5, 62358, 64677, 62359, 0, 0, 0, 0, 0, 0, 0, 0);
- +REPLACE INTO vehicle_seat_data VALUES (3010, 3);
- +UPDATE creature_template SET minhealth = 1134000, maxhealth = 1134000, unit_flags = 32768, IconName = 'Gunner' WHERE entry = 33067;
- +DELETE FROM creature WHERE id = 33067;
- +
- +/* Mechanic Seat Salvaged Demolisher */
- +DELETE FROM npc_spellclick_spells WHERE npc_entry IN (33167);
- +INSERT INTO npc_spellclick_spells VALUES (33167, 65403, 0, 0, 0, 1);
- +REPLACE INTO creature_template_addon VALUES (33167, 0, 0, 0, 0, 0, 345, NULL, NULL);
- +REPLACE INTO vehicle_data VALUES (345, 5, 62634, 64979, 62479, 62471, 0, 62428, 0, 0, 0, 0, 0);
- +REPLACE INTO vehicle_seat_data VALUES (3077, 3),(3106, 8);
- +UPDATE creature_template SET minhealth = 630000, maxhealth = 630000, unit_flags = 32768, IconName = 'Gunner' WHERE entry = 33167;
- +DELETE FROM creature WHERE id = 33167;
- +
- +/* Ulduar Salvaged vehicles (unifieddb fix) */
- +DELETE FROM creature_addon WHERE guid IN (SELECT guid FROM creature WHERE id IN (33060,33062,33109));
- +
- +/* Wintergrasp Tower Cannon (new) */
- +DELETE FROM npc_spellclick_spells WHERE npc_entry IN (28366);
- +INSERT INTO npc_spellclick_spells VALUES (28366, 60968, 0, 0, 0, 1);
- +REPLACE INTO creature_template_addon VALUES (28366, 0, 0, 0, 0, 0, 244, NULL, NULL);
- +REPLACE INTO vehicle_data VALUES (244, 5, 51362, 51421, 0, 0, 0, 0, 0, 0, 0, 0, 0);
- +REPLACE INTO vehicle_seat_data VALUES (2283, 3);
- +UPDATE creature_template SET IconName = 'Gunner' WHERE entry = 28366;
- +
- +/* the Oculus (new) */
- +DELETE FROM spell_script_target where entry IN (49460, 49346, 49464);
- +DELETE FROM npc_spellclick_spells where npc_entry IN (27755, 27692, 27756);
- +DELETE FROM creature_template_addon where entry IN (27755, 27692, 27756);
- +UPDATE creature_template SET IconName = 'vehichleCursor', InhabitType = 3 WHERE entry IN (27755,27756,27692);
- +/* Amber Drake */
- +INSERT INTO spell_script_target VALUES (49460, 1, 27755);
- +INSERT INTO npc_spellclick_spells VALUES (27755, 49459, 0, 0, 0, 1);
- +INSERT INTO creature_template_addon VALUES (27755, 0, 0, 0, 0, 0, 70, NULL, '48602 0 48602 2');
- +REPLACE INTO vehicle_data VALUES (70, 12, 49840, 49838, 49592, 0, 0, 0, 0, 0, 0, 0, 0);
- +REPLACE INTO vehicle_seat_data VALUES (1323, 3);
- +/* Emerald Drake */
- +INSERT INTO spell_script_target VALUES (49346, 1, 27692);
- +INSERT INTO npc_spellclick_spells VALUES (27692, 49427, 0, 0, 0, 1);
- +INSERT INTO creature_template_addon VALUES (27692, 0, 0, 0, 0, 0, 181, NULL, '48602 0 48602 2');
- +REPLACE INTO vehicle_data VALUES (181, 12, 50328, 50341, 50344, 0, 0, 0, 0, 0, 0, 0, 0);
- +REPLACE INTO vehicle_seat_data VALUES (2081, 3);
- +/* Ruby Drake */
- +INSERT INTO spell_script_target VALUES (49464, 1, 27756);
- +INSERT INTO npc_spellclick_spells VALUES (27756, 49463, 0, 0, 0, 1);
- +INSERT INTO creature_template_addon VALUES (27756, 0, 0, 0, 0, 0, 186, NULL, '48602 0 48602 2');
- +REPLACE INTO vehicle_data VALUES (186, 12, 50232, 50248, 50240, 0, 0, 0, 0, 0, 0, 0, 0);
- +REPLACE INTO vehicle_seat_data VALUES (2089, 3);
- +
- +/* vehicle accessory */
- +REPLACE INTO creature_template_addon (`entry`,`passengers`) values (27850,'27905 1');
- +REPLACE INTO creature_template_addon (`entry`,`vehicle_id`,`passengers`) values
- +(32930,328,'32933 1 32934 7'),(33114,341,'33142 1 33143 2'),(33214,348,'33218 1'),(33113,387,'33114 0 33114 1 33114 2 33114 3 33139 7');
- +
- +/* 7th Legion Chain Gun */
- +DELETE FROM npc_spellclick_spells WHERE npc_entry IN (27714);
- +INSERT INTO npc_spellclick_spells VALUES (27714, 65403, 0, 0, 0, 1);
- +REPLACE INTO creature_template_addon VALUES (27714, 0, 0, 0, 0, 0, 68, NULL, NULL);
- +REPLACE INTO vehicle_data VALUES (68, 5, 49190, 49550, 0, 0, 0, 0, 0, 0, 0, 0, 0);
- +REPLACE INTO vehicle_seat_data VALUES (1301, 1);
- +UPDATE creature_template SET IconName = 'Gunner' WHERE entry IN (27714);
- +
- +/* Alliance Steam Tank */
- +DELETE FROM npc_spellclick_spells WHERE npc_entry IN (27587);
- +INSERT INTO npc_spellclick_spells VALUES (27587, 43695, 0, 0, 0, 0);
- +REPLACE INTO creature_template_addon VALUES (27587, 0, 0, 0, 0, 0, 56, NULL, NULL);
- +REPLACE INTO vehicle_data VALUES (56, 4, 49315, 49333, 49109, 49081, 0, 0, 0, 0, 0, 0, 0);
- +REPLACE INTO vehicle_seat_data VALUES (945, 3),(946, 8),(949, 8),(950, 8);
- +REPLACE INTO spell_area (`spell`,`area`) VALUES (49081, 4246);
- +UPDATE creature_template SET modelid_1 = 25341, modelid_2 = 0, modelid_3 = 0, IconName = 'vehichleCursor' WHERE entry IN (27587);
- +UPDATE creature_model_info SET modelid_other_gender = 0 WHERE modelid = 25341;
- +-- UPDATE creature_template_addon SET passengers = '27163 1 27588 2 27588 3' WHERE entry = 27587;
- +
- +/* Broken-down Shredder */
- +DELETE FROM npc_spellclick_spells WHERE npc_entry IN (27354);
- +INSERT INTO npc_spellclick_spells VALUES (27354, 65403, 0, 0, 0, 1);
- +REPLACE INTO creature_template_addon VALUES (27354, 0, 0, 0, 0, 0, 49, NULL, NULL);
- +REPLACE INTO vehicle_data VALUES (49, 4, 48558, 48604, 48548, 0, 48610, 0, 0, 0, 0, 0, 0);
- +REPLACE INTO vehicle_seat_data VALUES (821, 1);
- +UPDATE creature_template SET IconName = 'vehichleCursor' WHERE entry IN (27354);
- +
- +/* Enraged Mammoth */
- +DELETE FROM npc_spellclick_spells WHERE npc_entry IN (28851);
- +INSERT INTO npc_spellclick_spells VALUES (28851, 65403, 0, 0, 0, 1);
- +REPLACE INTO creature_template_addon VALUES (28851, 0, 0, 0, 0, 0, 145, NULL, NULL);
- +REPLACE INTO vehicle_data VALUES (145, 4, 52603, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
- +REPLACE INTO vehicle_seat_data VALUES (1906, 3);
- +UPDATE creature_template SET IconName = 'vehichleCursor' WHERE entry IN (28851);
- +
- +/* Flamebringer */
- +DELETE FROM npc_spellclick_spells WHERE npc_entry IN (27292);
- +INSERT INTO npc_spellclick_spells VALUES (27292, 65403, 0, 0, 0, 1);
- +REPLACE INTO creature_template_addon VALUES (27292, 0, 0, 0, 0, 0, 50, NULL, NULL);
- +REPLACE INTO vehicle_data VALUES (50, 4, 48619, 48620, 52812, 0, 0, 0, 0, 0, 0, 0, 0);
- +REPLACE INTO vehicle_seat_data VALUES (841, 3);
- +UPDATE creature_template SET IconName = 'vehichleCursor' WHERE entry IN (27292);
- +
- +/* Forsaken Blight Spreader */
- +DELETE FROM npc_spellclick_spells WHERE npc_entry IN (26523);
- +INSERT INTO npc_spellclick_spells VALUES (26523, 47961, 0, 0, 0, 1);
- +REPLACE INTO creature_template_addon VALUES (26523, 0, 0, 0, 0, 0, 36, NULL, NULL);
- +REPLACE INTO vehicle_data VALUES (36, 4, 48211, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
- +REPLACE INTO vehicle_seat_data VALUES (644, 3);
- +UPDATE creature_template SET IconName = 'vehichleCursor' WHERE entry = 26523;
- +
- +/* Highland Mustang */
- +DELETE FROM npc_spellclick_spells WHERE npc_entry IN (26472);
- +INSERT INTO npc_spellclick_spells VALUES (26472, 65403, 0, 0, 0, 1);
- +REPLACE INTO creature_template_addon VALUES (26472, 0, 0, 0, 0, 0, 62, NULL, NULL);
- +REPLACE INTO vehicle_data VALUES (62, 4, 49285, 29577, 0, 0, 0, 0, 0, 0, 0, 0, 0);
- +REPLACE INTO vehicle_seat_data VALUES (1270, 3);
- +UPDATE creature_template SET IconName = 'vehichleCursor' WHERE entry IN (26472);
- +
- +/* Horde Siege Tank */
- +DELETE FROM npc_spellclick_spells WHERE npc_entry IN (25334);
- +INSERT INTO npc_spellclick_spells VALUES (25334, 43695, 0, 0, 0, 0);
- +REPLACE INTO creature_template_addon VALUES (25334, 0, 0, 0, 0, 0, 26, NULL, NULL);
- +REPLACE INTO vehicle_data VALUES (26, 4, 50672, 45750, 50677, 47849, 47962, 0, 0, 0, 0, 0, 0);
- +REPLACE INTO vehicle_seat_data VALUES (365,3),(366,6),(367,6),(368,6);
- +UPDATE creature_template SET IconName = 'vehichleCursor' WHERE entry = 25334;
- +
- +/* Infected Kodo Beast */
- +DELETE FROM npc_spellclick_spells WHERE npc_entry IN (25596);
- +INSERT INTO npc_spellclick_spells VALUES (25596, 45875, 11690, 1, 11690, 1);
- +REPLACE INTO creature_template_addon VALUES (25596, 0, 0, 0, 0, 0, 29, NULL, NULL);
- +REPLACE INTO vehicle_data VALUES (29, 12, 45876, 45877, 0, 0, 0, 0, 0, 0, 0, 0, 0);
- +REPLACE INTO vehicle_seat_data VALUES (422, 3);
- +UPDATE creature_template SET speed_run = 2, IconName = 'vehichleCursor' WHERE entry = 25596;
- +REPLACE INTO spell_script_target VALUES (45877, 1, 25596);
- +
- +/* Kor'kron War Rider */
- +DELETE FROM npc_spellclick_spells WHERE npc_entry IN (26813);
- +INSERT INTO npc_spellclick_spells VALUES (26813, 47424, 0, 0, 0, 1);
- +REPLACE INTO creature_template_addon VALUES (26813, 0, 0, 0, 0, 0, 80, NULL, '48602 0 48602 2');
- +REPLACE INTO vehicle_data VALUES (80, 4, 47434, 63507, 47454, 0, 0, 0, 0, 0, 0, 0, 0);
- +REPLACE INTO vehicle_seat_data VALUES (1431, 3),(1432, 2);
- +UPDATE creature_template SET modelid_2 = 0, modelid_3 = 0, IconName = 'vehichleCursor' WHERE entry IN (26813);
- +
- +/* Kor'kron War Rider II */
- +DELETE FROM npc_spellclick_spells WHERE npc_entry IN (26572);
- +INSERT INTO npc_spellclick_spells VALUES (26572, 47424, 0, 0, 0, 1);
- +REPLACE INTO creature_template_addon VALUES (26572, 0, 0, 0, 0, 0, 34, NULL, '48602 0 48602 2');
- +REPLACE INTO vehicle_data VALUES (34, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
- +REPLACE INTO vehicle_seat_data VALUES (601, 3);
- +UPDATE creature_template SET IconName = 'vehichleCursor' WHERE entry IN (26572);
- +
- +/* Onslaught Warhorse */
- +DELETE FROM npc_spellclick_spells WHERE npc_entry IN (27213);
- +INSERT INTO npc_spellclick_spells VALUES (27213, 65403, 0, 0, 0, 1);
- +REPLACE INTO creature_template_addon VALUES (27213, 0, 0, 0, 0, 0, 43, NULL, NULL);
- +REPLACE INTO vehicle_data VALUES (43, 4, 48297, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
- +REPLACE INTO vehicle_seat_data VALUES (742, 3);
- +UPDATE creature_template SET IconName = 'vehichleCursor' WHERE entry = 27213;
- +
- +/* Refurbished Shredder */
- +DELETE FROM npc_spellclick_spells WHERE npc_entry IN (27496);
- +INSERT INTO npc_spellclick_spells VALUES (27496, 60944, 0, 0, 0, 1);
- +REPLACE INTO creature_template_addon VALUES (27496, 0, 0, 0, 0, 0, 55, NULL, NULL);
- +REPLACE INTO vehicle_data VALUES (55, 4, 48548, 48604, 48558, 0, 48610, 0, 0, 0, 0, 0, 0);
- +REPLACE INTO vehicle_seat_data VALUES (922, 1);
- +UPDATE creature_template SET IconName = 'vehichleCursor' WHERE entry IN (27496);
- +
- +/* Rocket Propelled Warhead */
- +DELETE FROM npc_spellclick_spells WHERE npc_entry IN (27593);
- +INSERT INTO npc_spellclick_spells VALUES (27593, 49177, 0, 0, 0, 1);
- +REPLACE INTO creature_template_addon VALUES (27593, 0, 0, 0, 0, 0, 57, NULL, NULL);
- +REPLACE INTO vehicle_data VALUES (57, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
- +REPLACE INTO vehicle_seat_data VALUES (961, 1);
- +UPDATE creature_template SET IconName = 'vehichleCursor' WHERE entry IN (27593);
- +
- +/* Steel Gate Flying Machine */
- +DELETE FROM npc_spellclick_spells WHERE npc_entry IN (24418);
- +INSERT INTO npc_spellclick_spells VALUES (24418, 65403, 0, 0, 0, 1);
- +REPLACE INTO creature_template_addon VALUES (24418, 0, 0, 0, 0, 0, 8, NULL, '48602 0 48602 2');
- +REPLACE INTO vehicle_data VALUES (8, 4, 44009, 43770, 43799, 43769, 47769, 0, 0, 0, 0, 0, 0);
- +REPLACE INTO vehicle_seat_data VALUES (261, 1),(461, 2);
- +UPDATE creature_template SET IconName = 'vehichleCursor', InhabitType = 3 WHERE entry IN (24418);
- +
- +/* Wintergarde Gryphon */
- +DELETE FROM npc_spellclick_spells WHERE npc_entry IN (27258);
- +INSERT INTO npc_spellclick_spells VALUES (27258, 49288, 0, 0, 0, 1);
- +REPLACE INTO creature_template_addon VALUES (27258, 0, 0, 0, 0, 0, 44, NULL, '48602 0 48602 2');
- +REPLACE INTO vehicle_data VALUES (44, 4, 48363, 48397, 54170, 0, 0, 0, 0, 0, 0, 0, 0);
- +REPLACE INTO vehicle_seat_data VALUES (762, 1),(764, 2);
- +UPDATE creature_template SET IconName = 'vehichleCursor', InhabitType = 3 WHERE entry IN (27258);
- +
- +/* Wintergarde Gryphon II, Into Hostile Territory quest */
- +DELETE FROM npc_spellclick_spells WHERE npc_entry IN (27661);
- +INSERT INTO npc_spellclick_spells VALUES (27661, 48862, 0, 0, 0, 1);
- +REPLACE INTO creature_template_addon VALUES (27661, 0, 0, 0, 0, 0, 61, NULL, '48602 0 48602 2');
- +REPLACE INTO vehicle_data VALUES (61, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
- +REPLACE INTO vehicle_seat_data VALUES (1267, 1),(1268, 2);
- +UPDATE creature_template SET IconName = 'vehichleCursor', InhabitType = 3 WHERE entry IN (27661);
- +
- +/* Wooly Mammoth Bull */
- +DELETE FROM npc_spellclick_spells WHERE npc_entry IN (25743);
- +INSERT INTO npc_spellclick_spells VALUES (25743, 43695, 11879, 1, 11879, 1);
- +REPLACE INTO creature_template_addon VALUES (25743, 0, 0, 0, 0, 0, 72, NULL, NULL);
- +REPLACE INTO vehicle_data VALUES (72, 12, 46317, 46315, 46316, 0, 0, 0, 0, 0, 0, 0, 0);
- +REPLACE INTO vehicle_seat_data VALUES (1362, 3);
- +UPDATE creature_template SET faction_A = 7, faction_H = 7, IconName = 'vehichleCursor' WHERE entry IN (25743);
- +
- +/* Wyrmrest Defender */
- +DELETE FROM npc_spellclick_spells WHERE npc_entry IN (27629);
- +INSERT INTO npc_spellclick_spells VALUES (27629, 49256, 12372, 1, 12372, 1);
- +REPLACE INTO creature_template_addon VALUES (27629,0,50331648,1,0,0,60,NULL,'50069 0 50069 1 50069 2');
- +REPLACE INTO vehicle_data VALUES (60,4,49161,49243,49263,49264,49367,0,0,0,0,0,0);
- +REPLACE INTO vehicle_seat_data VALUES (1262, 3);
- +UPDATE creature_template SET IconName = 'vehichleCursor', InhabitType = 3 WHERE entry IN (27629);
- +
- +/* Wyrmrest Skytalon */
- +DELETE FROM npc_spellclick_spells WHERE npc_entry = 32535;
- +INSERT INTO npc_spellclick_spells VALUES (32535, 61245, 0, 0, 0, 1);
- +REPLACE INTO creature_template_addon VALUES (32535, 0, 0, 0, 0, 0, 165, NULL, '48602 0 48602 2');
- +REPLACE INTO vehicle_data VALUES (165, 12, 56091, 61621, 57090, 57143, 57108, 57092, 0, 0, 0, 0, 0);
- +REPLACE INTO vehicle_seat_data VALUES (2061, 3);
- +REPLACE INTO spell_script_target VALUES (61245,1,32535);
- +UPDATE creature_template SET IconName = 'vehichleCursor', InhabitType = 3 WHERE entry = 32535;
- +
- +/* Wyrmrest Vanquisher */
- +DELETE FROM npc_spellclick_spells WHERE npc_entry IN (27996);
- +INSERT INTO npc_spellclick_spells VALUES (27996, 65403, 0, 0, 0, 1);
- +REPLACE INTO creature_template_addon VALUES (27996, 0, 50331648, 1, 0, 0, 99, NULL, '48602 0 48602 2');
- +REPLACE INTO vehicle_data VALUES (99, 4, 50430, 55987, 50348, 0, 0, 0, 0, 0, 0, 0, 0);
- +REPLACE INTO vehicle_seat_data VALUES (1520, 3),(1521, 8);
- +UPDATE creature_template SET IconName = 'vehichleCursor', InhabitType = 3 WHERE entry IN (27996);
- +
- +/* Fizzcrank Bomber */
- +DELETE FROM npc_spellclick_spells WHERE npc_entry IN (25765);
- +INSERT INTO npc_spellclick_spells VALUES (25765, 65403, 0, 0, 0, 1);
- +REPLACE INTO creature_template_addon VALUES (25765, 0, 0, 0, 0, 0, 492, NULL, '48602 0 48602 2');
- +REPLACE INTO vehicle_data VALUES (492, 4, 45971, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
- +REPLACE INTO vehicle_seat_data VALUES (5506, 3);
- +UPDATE creature_template SET IconName = 'vehichleCursor', InhabitType = 3 WHERE entry IN (25765);
- +
- +/* Dusk */
- +DELETE FROM npc_spellclick_spells WHERE npc_entry IN (26191);
- +INSERT INTO npc_spellclick_spells VALUES (26191, 65403, 0, 0, 0, 1);
- +REPLACE INTO creature_template_addon VALUES (26191, 0, 0, 0, 0, 0, 200, NULL, NULL);
- +REPLACE INTO vehicle_data VALUES (200, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
- +REPLACE INTO vehicle_seat_data VALUES (2144, 3);
- +UPDATE creature_template SET IconName = 'vehichleCursor' WHERE entry IN (26191);
- +
- +/* Tatjana's Horse */
- +DELETE FROM npc_spellclick_spells WHERE npc_entry IN (27626);
- +INSERT INTO npc_spellclick_spells VALUES (27626, 65403, 0, 0, 0, 1);
- +REPLACE INTO creature_template_addon VALUES (27626, 0, 0, 0, 0, 0, 59, NULL, NULL);
- +REPLACE INTO vehicle_data VALUES (59, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
- +REPLACE INTO vehicle_seat_data VALUES (1241, 3),(1242, 2);
- +UPDATE creature_template SET IconName = 'vehichleCursor' WHERE entry IN (27626);
- +
- +/* Antipersonnel Cannon */
- +DELETE FROM npc_spellclick_spells WHERE npc_entry IN (27894);
- +INSERT INTO npc_spellclick_spells VALUES (27894, 65403, 0, 0, 0, 1);
- +REPLACE INTO creature_template_addon VALUES (27894, 0, 0, 0, 0, 0, 160, NULL, NULL);
- +REPLACE INTO vehicle_data VALUES (160, 5, 49872, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
- +REPLACE INTO vehicle_seat_data VALUES (2029, 3);
- +UPDATE creature_template SET IconName = 'Gunner' WHERE entry IN (27894);
- +
- +/* Antipersonnel Cannon II */
- +DELETE FROM npc_spellclick_spells WHERE npc_entry IN (32795);
- +INSERT INTO npc_spellclick_spells VALUES (32795, 65403, 0, 0, 0, 1);
- +REPLACE INTO creature_template_addon VALUES (32795, 0, 0, 0, 0, 0, 160, NULL, NULL);
- +REPLACE INTO vehicle_data VALUES (160, 5, 49872, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
- +REPLACE INTO vehicle_seat_data VALUES (2029, 3);
- +UPDATE creature_template SET IconName = 'Gunner' WHERE entry IN (32795);
- +
- +/* Wintergrasp Demolisher */
- +UPDATE creature_template SET maxhealth = 50000, minhealth = 50000 WHERE entry = 28094;
- +DELETE FROM npc_spellclick_spells WHERE npc_entry IN (28094);
- +INSERT INTO npc_spellclick_spells VALUES (28094, 60968, 0, 0, 0, 1);
- +REPLACE INTO creature_template_addon VALUES (28094, 0, 0, 0, 0, 0, 106, NULL, NULL);
- +REPLACE INTO vehicle_data VALUES (106, 4, 50896, 50652, 0, 0, 0, 0, 0, 0, 0, 0, 0);
- +REPLACE INTO vehicle_seat_data VALUES (1554, 3),(1556, 6),(1557, 6);
- +UPDATE creature_template SET IconName = 'vehichleCursor' WHERE entry IN (28094);
- +
- +/* Wintergrasp Siege Engine */
- +UPDATE creature_template SET maxhealth = 75000, minhealth = 75000 WHERE entry IN (28312,32627);
- +DELETE FROM npc_spellclick_spells WHERE npc_entry IN (28312);
- +INSERT INTO npc_spellclick_spells VALUES (28312, 60968, 0, 0, 0, 1);
- +REPLACE INTO creature_template_addon VALUES (28312, 0, 0, 0, 0, 0, 117, '28319 7', NULL);
- +REPLACE INTO vehicle_data VALUES (117, 4, 51678, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
- +REPLACE INTO vehicle_seat_data VALUES (1648, 3),(1649, 2),(1650, 2),(1652, 4);
- +UPDATE creature_template SET IconName = 'vehichleCursor' WHERE entry IN (28312);
- +
- +/* Wintergrasp Siege Engine II */
- +DELETE FROM npc_spellclick_spells WHERE npc_entry IN (32627);
- +INSERT INTO npc_spellclick_spells VALUES (32627, 60968, 0, 0, 0, 1);
- +REPLACE INTO creature_template_addon VALUES (32627, 0, 0, 0, 0, 0, 324, '32629 7', NULL);
- +REPLACE INTO vehicle_data VALUES (324, 4, 51678, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
- +REPLACE INTO vehicle_seat_data VALUES (2863, 3),(2864, 2),(2865, 2),(2866, 2);
- +UPDATE creature_template SET IconName = 'vehichleCursor' WHERE entry IN (32627);
- +
- +/* Wintergrasp Siege Turret */
- +UPDATE creature_template SET maxhealth = 50000, minhealth = 50000 WHERE entry IN (28319,32629);
- +DELETE FROM npc_spellclick_spells WHERE npc_entry IN (28319);
- +INSERT INTO npc_spellclick_spells VALUES (28319, 60968, 0, 0, 0, 1);
- +REPLACE INTO creature_template_addon VALUES (28319, 0, 0, 0, 0, 0, 116, NULL, NULL);
- +REPLACE INTO vehicle_data VALUES (116, 5, 51362, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
- +REPLACE INTO vehicle_seat_data VALUES (1643, 3);
- +UPDATE creature_template SET IconName = 'Gunner' WHERE entry IN (28319);
- +
- +/* Wintergrasp Siege Turret II */
- +DELETE FROM npc_spellclick_spells WHERE npc_entry IN (32629);
- +INSERT INTO npc_spellclick_spells VALUES (32629, 60968, 0, 0, 0, 1);
- +REPLACE INTO creature_template_addon VALUES (32629, 0, 0, 0, 0, 0, 116, NULL, NULL);
- +REPLACE INTO vehicle_data VALUES (116, 5, 51362, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
- +REPLACE INTO vehicle_seat_data VALUES (1643, 3);
- +UPDATE creature_template SET IconName = 'Gunner' WHERE entry IN (32629);
- +
- +/* Battleground Demolisher */
- +DELETE FROM npc_spellclick_spells WHERE npc_entry IN (28781);
- +INSERT INTO npc_spellclick_spells VALUES (28781, 65403, 0, 0, 0, 1);
- +REPLACE INTO creature_template_addon VALUES (28781, 0, 0, 0, 0, 0, 158, NULL, NULL);
- +REPLACE INTO vehicle_data VALUES (158, 4, 52338, 60206, 0, 0, 0, 0, 0, 0, 0, 0, 0);
- +REPLACE INTO vehicle_seat_data VALUES (2021, 3),(2023, 2),(2024, 2);
- +UPDATE creature_template SET IconName = 'vehichleCursor' WHERE entry IN (28781);
- +
- +/* Battleground Demolisher II */
- +DELETE FROM npc_spellclick_spells WHERE npc_entry IN (32796);
- +INSERT INTO npc_spellclick_spells VALUES (32796, 65403, 0, 0, 0, 1);
- +REPLACE INTO creature_template_addon VALUES (32796, 0, 0, 0, 0, 0, 158, NULL, NULL);
- +REPLACE INTO vehicle_data VALUES (158, 4, 52338, 60206, 0, 0, 0, 0, 0, 0, 0, 0, 0);
- +REPLACE INTO vehicle_seat_data VALUES (2021, 3),(2023, 2),(2024, 2);
- +UPDATE creature_template SET IconName = 'vehichleCursor' WHERE entry IN (32796);
- +
- +/* Frostbite */
- +DELETE FROM npc_spellclick_spells WHERE npc_entry IN (29857);
- +INSERT INTO npc_spellclick_spells VALUES (29857, 65403, 0, 0, 0, 1);
- +REPLACE INTO creature_template_addon VALUES (29857, 0, 0, 0, 0, 0, 202, NULL, NULL);
- +REPLACE INTO vehicle_data VALUES (202, 4, 54996, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
- +REPLACE INTO vehicle_seat_data VALUES (2164, 3);
- +UPDATE creature_template SET IconName = 'vehichleCursor' WHERE entry IN (29857);
- +
- +/* Valkyrion Harpoon Gun */
- +DELETE FROM npc_spellclick_spells WHERE npc_entry IN (30066);
- +INSERT INTO npc_spellclick_spells VALUES (30066, 44002, 12953, 1, 12953, 1);
- +REPLACE INTO creature_template_addon VALUES (30066, 0, 0, 0, 0, 0, 213, NULL, NULL);
- +REPLACE INTO vehicle_data VALUES (213, 5, 55812, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
- +REPLACE INTO vehicle_seat_data VALUES (2186, 1);
- +UPDATE creature_template SET IconName = 'Gunner' WHERE entry IN (30066);
- +
- +/* Argent Skytalon */
- +DELETE FROM npc_spellclick_spells WHERE npc_entry IN (30228);
- +INSERT INTO npc_spellclick_spells VALUES (30228, 65403, 0, 0, 0, 1);
- +REPLACE INTO creature_template_addon VALUES (30228, 0, 50331648, 1, 0, 0, 234, NULL, '48602 0 48602 2');
- +REPLACE INTO vehicle_data VALUES (234, 4, 56683, 56684, 56712, 0, 0, 0, 0, 0, 0, 0, 0);
- +REPLACE INTO vehicle_seat_data VALUES (2235, 1),(2236, 8);
- +UPDATE creature_template SET IconName = 'vehichleCursor', InhabitType = 3 WHERE entry IN (30228);
- +
- +/* Jotunheim Rapid-Fire Harpoon */
- +DELETE FROM npc_spellclick_spells WHERE npc_entry IN (30337);
- +INSERT INTO npc_spellclick_spells VALUES (30337, 65403, 0, 0, 0, 1);
- +REPLACE INTO creature_template_addon VALUES (30337, 0, 0, 0, 0, 0, 229, NULL, NULL);
- +REPLACE INTO vehicle_data VALUES (229, 5, 0, 0, 56570, 0, 0, 0, 0, 0, 0, 0, 0);
- +REPLACE INTO vehicle_seat_data VALUES (2229, 1);
- +UPDATE creature_template SET IconName = 'Gunner' WHERE entry IN (30337);
- +
- +/* Nergeld */
- +DELETE FROM npc_spellclick_spells WHERE npc_entry IN (30403);
- +INSERT INTO npc_spellclick_spells VALUES (30403, 56699, 0, 0, 0, 1);
- +REPLACE INTO creature_template_addon VALUES (30403, 0, 0, 0, 0, 0, 236, NULL, NULL);
- +REPLACE INTO vehicle_data VALUES (236, 4, 60540, 56746, 56748, 56747, 0, 0, 0, 0, 0, 0, 0);
- +REPLACE INTO vehicle_seat_data VALUES (2238, 3);
- +UPDATE creature_template SET IconName = 'vehichleCursor' WHERE entry IN (30403);
- +
- +/* Kor'kron Suppression Turret */
- +DELETE FROM npc_spellclick_spells WHERE npc_entry IN (31884);
- +INSERT INTO npc_spellclick_spells VALUES (31884, 65403, 0, 0, 0, 1);
- +REPLACE INTO creature_template_addon VALUES (31884, 0, 0, 0, 0, 0, 291, NULL, NULL);
- +REPLACE INTO vehicle_data VALUES (291, 5, 59880, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
- +REPLACE INTO vehicle_seat_data VALUES (2553, 3);
- +UPDATE creature_template SET IconName = 'Gunner' WHERE entry IN (31884);
- +
- +/* Flame Leviathan Seat */
- +DELETE FROM npc_spellclick_spells WHERE npc_entry IN (33114);
- +-- INSERT INTO npc_spellclick_spells VALUES (33114, 65403, 0, 0, 0, 1);
- +REPLACE INTO creature_template_addon VALUES (33114, 0, 0, 0, 0, 0, 341, NULL, NULL);
- +REPLACE INTO vehicle_data VALUES (341, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
- +REPLACE INTO vehicle_seat_data VALUES (3044, 1),(3075, 0),(3076, 0);
- +UPDATE creature_template SET IconName = 'Gunner' WHERE entry IN (33114);
- +
- +/* Brann's Flying Machine */
- +DELETE FROM npc_spellclick_spells WHERE npc_entry IN (34120);
- +INSERT INTO npc_spellclick_spells VALUES (34120, 65403, 0, 0, 0, 1);
- +REPLACE INTO creature_template_addon VALUES (34120, 0, 0, 0, 0, 0, 390, NULL, '48602 0 48602 2');
- +REPLACE INTO vehicle_data VALUES (390, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
- +REPLACE INTO vehicle_seat_data VALUES (3926, 3);
- +UPDATE creature_template SET IconName = 'vehichleCursor' WHERE entry IN (34120);
- +
- +/* Catapult */
- +DELETE FROM npc_spellclick_spells WHERE npc_entry IN (34793);
- +INSERT INTO npc_spellclick_spells VALUES (34793, 65403, 0, 0, 0, 1);
- +REPLACE INTO creature_template_addon VALUES (34793, 0, 0, 0, 0, 0, 438, NULL, NULL);
- +REPLACE INTO vehicle_data VALUES (438, 4, 66218, 66296, 0, 0, 0, 0, 0, 0, 0, 0, 0);
- +REPLACE INTO vehicle_seat_data VALUES (4706, 3),(4726, 2);
- +UPDATE creature_template SET IconName = 'vehichleCursor' WHERE entry IN (34793);
- +
- +/* Argent Warhorse */
- +DELETE FROM npc_spellclick_spells WHERE npc_entry IN (36557,35644);
- +INSERT INTO npc_spellclick_spells VALUES (36557, 65403, 0, 0, 0, 1),(35644, 65403, 0, 0, 0, 1);
- +REPLACE INTO creature_template_addon VALUES (36557, 0, 0, 0, 0, 0, 486, NULL, NULL),(35644, 0, 0, 0, 0, 0, 486, NULL, NULL);
- +REPLACE INTO vehicle_data VALUES (486, 4, 68505, 62575, 68282, 66482, 0, 0, 0, 0, 0, 0, 0);
- +REPLACE INTO vehicle_seat_data VALUES (5406, 3);
- +UPDATE creature_template SET IconName = 'vehichleCursor' WHERE entry IN (36557,35644);
- +
- +/* Argent Battleworg */
- +DELETE FROM npc_spellclick_spells WHERE npc_entry IN (36559,36558);
- +INSERT INTO npc_spellclick_spells VALUES (36559, 65403, 0, 0, 0, 1),(36558, 65403, 0, 0, 0, 1);
- +REPLACE INTO creature_template_addon VALUES (36559, 0, 0, 0, 0, 0, 529, NULL, NULL),(36558, 0, 0, 0, 0, 0, 529, NULL, NULL);
- +REPLACE INTO vehicle_data VALUES (529, 4, 68282, 62575, 0, 0, 0, 0, 0, 0, 0, 0, 0);
- +REPLACE INTO vehicle_seat_data VALUES (6126, 3);
- +UPDATE creature_template SET IconName = 'vehichleCursor' WHERE entry IN (36559,36558);
- +
- +/* Keep Cannon */
- +DELETE FROM npc_spellclick_spells WHERE npc_entry IN (34944);
- +INSERT INTO npc_spellclick_spells VALUES (34944, 65403, 0, 0, 0, 1);
- +REPLACE INTO creature_template_addon VALUES (34944, 0, 0, 0, 0, 0, 510, NULL, NULL);
- +REPLACE INTO vehicle_data VALUES (510, 5, 68169, 66541, 68170, 67452, 0, 0, 0, 0, 0, 0, 0);
- +REPLACE INTO vehicle_seat_data VALUES (5786, 3);
- +UPDATE creature_template SET IconName = 'Gunner' WHERE entry IN (34944);
- +
- +/* Alliance Gunship Cannon */
- +DELETE FROM npc_spellclick_spells WHERE npc_entry IN (34929);
- +INSERT INTO npc_spellclick_spells VALUES (34929, 65403, 0, 0, 0, 1);
- +REPLACE INTO creature_template_addon VALUES (34929, 0, 0, 0, 0, 0, 452, NULL, NULL);
- +REPLACE INTO vehicle_data VALUES (452, 5, 69495, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
- +REPLACE INTO vehicle_seat_data VALUES (4888, 3);
- +UPDATE creature_template SET IconName = 'Gunner' WHERE entry IN (34929);
- +
- +/* Alliance Gunship Cannon II */
- +DELETE FROM npc_spellclick_spells WHERE npc_entry IN (36838);
- +INSERT INTO npc_spellclick_spells VALUES (36838, 65403, 0, 0, 0, 1);
- +REPLACE INTO creature_template_addon VALUES (36838, 0, 0, 0, 0, 0, 554, NULL, NULL);
- +REPLACE INTO vehicle_data VALUES (554, 5, 70174, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
- +REPLACE INTO vehicle_seat_data VALUES (6488, 3);
- +UPDATE creature_template SET IconName = 'Gunner' WHERE entry IN (36838);
- +
- +/* Horde Gunship Cannon */
- +DELETE FROM npc_spellclick_spells WHERE npc_entry IN (34935);
- +INSERT INTO npc_spellclick_spells VALUES (34935, 65403, 0, 0, 0, 1);
- +REPLACE INTO creature_template_addon VALUES (34935, 0, 0, 0, 0, 0, 453, NULL, NULL);
- +REPLACE INTO vehicle_data VALUES (453, 5, 68825, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
- +REPLACE INTO vehicle_seat_data VALUES (4906, 3);
- +UPDATE creature_template SET IconName = 'Gunner' WHERE entry IN (34935);
- +
- +/* Demolisher */
- +DELETE FROM npc_spellclick_spells WHERE npc_entry IN (34775);
- +INSERT INTO npc_spellclick_spells VALUES (34775, 65403, 0, 0, 0, 1);
- +REPLACE INTO creature_template_addon VALUES (34775, 0, 0, 0, 0, 0, 509, NULL, NULL);
- +REPLACE INTO vehicle_data VALUES (509, 4, 68068, 67440, 67442, 67441, 0, 0, 0, 0, 0, 0, 0);
- +REPLACE INTO vehicle_seat_data VALUES (5766, 3),(5767, 2),(5768, 2);
- +UPDATE creature_template SET IconName = 'vehichleCursor' WHERE entry IN (34775);
- +
- +/* Broken Keep Cannon */
- +DELETE FROM npc_spellclick_spells WHERE npc_entry IN (35819);
- +INSERT INTO npc_spellclick_spells VALUES (35819, 65403, 0, 0, 0, 1);
- +REPLACE INTO creature_template_addon VALUES (35819, 0, 0, 0, 0, 0, 655, NULL, NULL);
- +REPLACE INTO vehicle_data VALUES (655, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
- +UPDATE creature_template SET IconName = 'Gunner' WHERE entry IN (35819);
- +
- +/* Flame Turret */
- +DELETE FROM npc_spellclick_spells WHERE npc_entry IN (36356);
- +INSERT INTO npc_spellclick_spells VALUES (36356, 65403, 0, 0, 0, 1);
- +REPLACE INTO creature_template_addon VALUES (36356, 0, 0, 0, 0, 0, 436, NULL, NULL);
- +REPLACE INTO vehicle_data VALUES (436, 5, 68832, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
- +REPLACE INTO vehicle_seat_data VALUES (4690, 3);
- +UPDATE creature_template SET IconName = 'Gunner' WHERE entry IN (36356);
- diff --git a/src/game/AggressorAI.cpp b/src/game/AggressorAI.cpp
- index 615fd3f..4391b7b 100644
- --- a/src/game/AggressorAI.cpp
- +++ b/src/game/AggressorAI.cpp
- @@ -103,7 +103,7 @@ void AggressorAI::EnterEvadeMode()
- //i_tracker.Reset(TIME_INTERVAL_LOOK);
- }
- - if (!m_creature->isCharmed())
- + if (!m_creature->isCharmed() && (!m_creature->GetVehicle() || !m_creature->GetVehicleGUID()))
- {
- m_creature->RemoveAllAuras();
- diff --git a/src/game/BattleGroundMgr.cpp b/src/game/BattleGroundMgr.cpp
- index f0bef72..26c91bd 100644
- --- a/src/game/BattleGroundMgr.cpp
- +++ b/src/game/BattleGroundMgr.cpp
- @@ -1349,11 +1349,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 ab91c6e..28fe01b 100644
- --- a/src/game/Chat.cpp
- +++ b/src/game/Chat.cpp
- @@ -527,6 +527,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 }
- };
- @@ -2039,7 +2041,7 @@ Creature* ChatHandler::getSelectedCreature()
- if(!m_session)
- return NULL;
- - return m_session->GetPlayer()->GetMap()->GetAnyTypeCreature(m_session->GetPlayer()->GetSelectionGuid());
- + return ObjectAccessor::GetAnyTypeCreature(*m_session->GetPlayer(),m_session->GetPlayer()->GetSelectionGuid());
- }
- /**
- diff --git a/src/game/Chat.h b/src/game/Chat.h
- index 9950ad4..204aa18 100644
- --- a/src/game/Chat.h
- +++ b/src/game/Chat.h
- @@ -445,6 +445,8 @@ class ChatHandler
- bool HandleReloadSpellTargetPositionCommand(char* args);
- bool HandleReloadSpellThreatsCommand(char* args);
- bool HandleReloadSpellPetAurasCommand(char* args);
- + bool HandleReloadVehicleDataCommand(char* args);
- + bool HandleReloadVehicleSeatDataCommand(char* args);
- bool HandleResetAchievementsCommand(char* args);
- bool HandleResetAllCommand(char* args);
- diff --git a/src/game/Creature.cpp b/src/game/Creature.cpp
- index eb2ed94..1082bae 100644
- --- a/src/game/Creature.cpp
- +++ b/src/game/Creature.cpp
- @@ -42,6 +42,7 @@
- #include "GridNotifiers.h"
- #include "GridNotifiersImpl.h"
- #include "CellImpl.h"
- +#include "Vehicle.h"
- // apply implementation of the singletons
- #include "Policies/SingletonImp.h"
- @@ -1401,6 +1402,8 @@ void Creature::SetDeathState(DeathState s)
- return;
- Unit::SetDeathState(CORPSE);
- + if(IsVehicle())
- + ((Vehicle*)this)->Die();
- }
- if (s == JUST_ALIVED)
- @@ -1529,6 +1532,32 @@ bool Creature::IsImmuneToSpellEffect(SpellEntry const* spellInfo, SpellEffectInd
- 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::IsImmuneToSpellEffect(spellInfo, index);
- }
- @@ -1761,7 +1790,7 @@ bool Creature::CanInitiateAttack()
- if (hasUnitState(UNIT_STAT_STUNNED | UNIT_STAT_DIED))
- return false;
- - if (HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE))
- + if (HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_PLAYER_CONTROLLED))
- return false;
- if (isPassiveToHostile())
- @@ -2044,6 +2073,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.15f;
- + }
- + case GUARDIAN_PET:
- + case MINI_PET:
- + {
- + //speed of CreatureInfo for guardian- and minipets
- + break;
- + }
- + }
- + }
- + return m_creatureInfo->speed_run;
- +}
- +
- bool Creature::HasSpell(uint32 spellID) const
- {
- uint8 i;
- diff --git a/src/game/Creature.h b/src/game/Creature.h
- index f5a2e29..2808c55 100644
- --- a/src/game/Creature.h
- +++ b/src/game/Creature.h
- @@ -117,6 +117,7 @@ struct CreatureInfo
- int32 resistance6;
- uint32 spells[CREATURE_MAX_SPELLS];
- uint32 PetSpellDataId;
- + uint32 VehicleEntry;
- uint32 mingold;
- uint32 maxgold;
- char const* AIName;
- @@ -196,6 +197,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
- {
- @@ -205,6 +215,8 @@ struct CreatureDataAddon
- uint32 bytes2;
- uint32 emote;
- 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 ... "
- };
- @@ -580,6 +592,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; }
- diff --git a/src/game/CreatureAI.cpp b/src/game/CreatureAI.cpp
- index 33cb568..5b7e320 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/CreatureAISelector.cpp b/src/game/CreatureAISelector.cpp
- index 4ddfa91..640f890 100644
- --- a/src/game/CreatureAISelector.cpp
- +++ b/src/game/CreatureAISelector.cpp
- @@ -47,7 +47,7 @@ namespace FactorySelector
- // excplicit check for isControlled() and owner type to allow guardian, mini-pets and pets controlled by NPCs to be scripted by EventAI
- Unit *owner=NULL;
- if ((creature->IsPet() && ((Pet*)creature)->isControlled() &&
- - ((owner=creature->GetOwner()) && owner->GetTypeId()==TYPEID_PLAYER)) || creature->isCharmed())
- + ((owner=creature->GetOwner()) && owner->GetTypeId()==TYPEID_PLAYER)) || (creature->isCharmed() && !creature->IsVehicle()))
- ai_factory = ai_registry.GetRegistryItem("PetAI");
- else if (creature->IsTotem())
- ai_factory = ai_registry.GetRegistryItem("TotemAI");
- diff --git a/src/game/CreatureEventAI.cpp b/src/game/CreatureEventAI.cpp
- index 21c8f68..27ae648 100644
- --- a/src/game/CreatureEventAI.cpp
- +++ b/src/game/CreatureEventAI.cpp
- @@ -913,6 +913,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/DBCEnums.h b/src/game/DBCEnums.h
- index a1fbe08..a2615b0 100644
- --- a/src/game/DBCEnums.h
- +++ b/src/game/DBCEnums.h
- @@ -437,6 +437,12 @@ enum VehicleFlags
- 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
- +
- SEAT_FLAG_HIDE_PASSENGER = 0x00000200, // Passenger is hidden
- SEAT_FLAG_CAN_CONTROL = 0x00000800, // Lua_UnitInVehicleControlSeat
- SEAT_FLAG_CAN_ATTACK = 0x00004000, // Can attack, cast spells and use items from vehicle?
- diff --git a/src/game/DBCStructure.h b/src/game/DBCStructure.h
- index c8f7489..ecefff9 100644
- --- a/src/game/DBCStructure.h
- +++ b/src/game/DBCStructure.h
- @@ -1753,7 +1753,7 @@ struct VehicleEntry
- uint32 m_uiLocomotionType; // 34
- float m_msslTrgtImpactTexRadius; // 35
- uint32 m_uiSeatIndicatorType; // 36
- - // 37, new in 3.1 - powerType
- + uint32 m_powerType; // 37, new in 3.1 - powerType
- // 38, new in 3.1
- // 39, new in 3.1
- };
- @@ -1807,6 +1807,8 @@ struct VehicleSeatEntry
- int32 m_uiSkin; // 44
- uint32 m_flagsB; // 45
- // 46-57 added in 3.1, floats mostly
- +
- + bool IsUsable() const { return m_flags & SEAT_FLAG_USABLE; }
- };
- struct WMOAreaTableEntry
- diff --git a/src/game/DBCfmt.h b/src/game/DBCfmt.h
- index a9ff44f..8033dd3 100644
- --- a/src/game/DBCfmt.h
- +++ b/src/game/DBCfmt.h
- @@ -104,7 +104,7 @@ const char TaxiNodesEntryfmt[]="nifffssssssssssssssssxii";
- const char TaxiPathEntryfmt[]="niii";
- const char TaxiPathNodeEntryfmt[]="diiifffiiii";
- const char TotemCategoryEntryfmt[]="nxxxxxxxxxxxxxxxxxii";
- -const char VehicleEntryfmt[]="niffffiiiiiiiifffffffffffffffssssfifixxx";
- +const char VehicleEntryfmt[]="niffffiiiiiiiifffffffffffffffssssfifiixx";
- const char VehicleSeatEntryfmt[]="niiffffffffffiiiiiifffffffiiifffiiiiiiiffiiiiixxxxxxxxxxxx";
- const char WMOAreaTableEntryfmt[]="niiixxxxxiixxxxxxxxxxxxxxxxx";
- const char WorldMapAreaEntryfmt[]="xinxffffixx";
- diff --git a/src/game/GameObject.cpp b/src/game/GameObject.cpp
- index d42a18c..7ca22d4 100644
- --- a/src/game/GameObject.cpp
- +++ b/src/game/GameObject.cpp
- @@ -1628,6 +1628,18 @@ float GameObject::GetObjectBoundingRadius() const
- return DEFAULT_WORLD_OBJECT_SIZE;
- }
- +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);
- + }
- +}
- +
- bool GameObject::IsInSkillupList(Player* player) const
- {
- return m_SkillupSet.find(player->GetObjectGuid()) != m_SkillupSet.end();
- diff --git a/src/game/GameObject.h b/src/game/GameObject.h
- index 6b310f9..2dc37df 100644
- --- a/src/game/GameObject.h
- +++ b/src/game/GameObject.h
- @@ -710,6 +710,7 @@ class MANGOS_DLL_SPEC GameObject : public WorldObject
- GridReference<GameObject> &GetGridRef() { return m_gridRef; }
- 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()),
- @@ -716,6 +717,7 @@ class MANGOS_DLL_SPEC GameObject : public WorldObject
- 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.
- diff --git a/src/game/GridNotifiers.cpp b/src/game/GridNotifiers.cpp
- index 3e94064..8c4f725 100644
- --- a/src/game/GridNotifiers.cpp
- +++ b/src/game/GridNotifiers.cpp
- @@ -93,7 +93,10 @@ VisibleNotifier::Notify()
- {
- // target aura duration for caster show only if target exist at caster client
- if ((*vItr) != &player && (*vItr)->isType(TYPEMASK_UNIT))
- + {
- player.SendAurasForTarget((Unit*)(*vItr));
- + ((Unit*)(*vItr))->SendHeartBeat(false);
- + }
- // 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 45a949a..453b77e 100644
- --- a/src/game/Group.h
- +++ b/src/game/Group.h
- @@ -134,7 +134,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 e541595..cc17313 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
- @@ -719,7 +720,7 @@ void WorldSession::BuildPartyMemberStatsChangedPacket(Player *player, WorldPacke
- }
- }
- - Pet *pet = player->GetPet();
- + Unit *pet = player->GetCharmOrPet();
- if (mask & GROUP_UPDATE_FLAG_PET_GUID)
- *data << (pet ? pet->GetObjectGuid() : ObjectGuid());
- @@ -797,6 +798,11 @@ void WorldSession::BuildPartyMemberStatsChangedPacket(Player *player, WorldPacke
- else
- *data << uint64(0);
- }
- +
- + if (mask & GROUP_UPDATE_FLAG_VEHICLE_SEAT)
- + {
- + *data << (uint32) player->m_movementInfo.GetTransportDBCSeat();
- + }
- }
- /*this procedure handles clients CMSG_REQUEST_PARTY_MEMBER_STATS request*/
- @@ -818,7 +824,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
- @@ -826,7 +832,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
- @@ -880,6 +886,7 @@ void WorldSession::HandleRequestPartyMemberStatsOpcode( WorldPacket &recv_data )
- }
- }
- data.put<uint64>(petMaskPos, petauramask); // GROUP_UPDATE_FLAG_PET_AURAS
- + data << (uint32) player->m_movementInfo.GetTransportDBCSeat();
- }
- else
- {
- diff --git a/src/game/Level3.cpp b/src/game/Level3.cpp
- index d8d30e2..06976a8 100644
- --- a/src/game/Level3.cpp
- +++ b/src/game/Level3.cpp
- @@ -74,6 +74,9 @@ bool ChatHandler::HandleReloadAllCommand(char* /*args*/)
- HandleReloadReservedNameCommand((char*)"");
- HandleReloadMangosStringCommand((char*)"");
- HandleReloadGameTeleCommand((char*)"");
- +
- + HandleReloadVehicleDataCommand((char*)"");
- + HandleReloadVehicleSeatDataCommand((char*)"");
- return true;
- }
- @@ -921,6 +924,22 @@ bool ChatHandler::HandleReloadMailLevelRewardCommand(char* /*args*/)
- return true;
- }
- +bool ChatHandler::HandleReloadVehicleDataCommand(char* /*args*/)
- +{
- + sLog.outString( "Re-Loading `vehicle_data` Table!" );
- + sObjectMgr.LoadVehicleData();
- + SendGlobalSysMessage("DB table `vehicle_data` reloaded.");
- + return true;
- +}
- +
- +bool ChatHandler::HandleReloadVehicleSeatDataCommand(char* /*args*/)
- +{
- + sLog.outString( "Re-Loading `vehicle_seat_data` Table!" );
- + sObjectMgr.LoadVehicleSeatData();
- + SendGlobalSysMessage("DB table `vehicle_seat_data` reloaded.");
- + return true;
- +}
- +
- bool ChatHandler::HandleLoadScriptsCommand(char* args)
- {
- if (!LoadScriptingModule(args))
- diff --git a/src/game/Map.h b/src/game/Map.h
- index d0142e8..a1c7681 100644
- --- a/src/game/Map.h
- +++ b/src/game/Map.h
- @@ -39,7 +39,6 @@
- #include <bitset>
- #include <list>
- -class Creature;
- class Unit;
- class WorldPacket;
- class InstanceData;
- diff --git a/src/game/MovementHandler.cpp b/src/game/MovementHandler.cpp
- index 9355ca9..134dfc8 100644
- --- a/src/game/MovementHandler.cpp
- +++ b/src/game/MovementHandler.cpp
- @@ -44,6 +44,9 @@ void WorldSession::HandleMoveWorldportAckOpcode()
- if(!GetPlayer()->IsBeingTeleportedFar())
- return;
- + if (_player->GetVehicleKit())
- + _player->GetVehicleKit()->RemoveAllPassengers();
- +
- // get the teleport destination
- WorldLocation &loc = GetPlayer()->GetTeleportDest();
- @@ -262,6 +265,8 @@ void WorldSession::HandleMovementOpcodes( WorldPacket & recv_data )
- data << mover->GetPackGUID(); // write guid
- movementInfo.Write(data); // write data
- mover->SendMessageToSetExcept(&data, _player);
- + mover->m_movementInfo = movementInfo;
- + mover->SetPosition(movementInfo.GetPos()->x, movementInfo.GetPos()->y, movementInfo.GetPos()->z, movementInfo.GetPos()->o);
- }
- void WorldSession::HandleForceSpeedChangeAckOpcodes(WorldPacket &recv_data)
- @@ -343,12 +348,10 @@ void WorldSession::HandleSetActiveMoverOpcode(WorldPacket &recv_data)
- ObjectGuid guid;
- recv_data >> guid;
- - if(_player->GetMover()->GetObjectGuid() != guid)
- - {
- - sLog.outError("HandleSetActiveMoverOpcode: incorrect mover guid: mover is %s and should be %s",
- - _player->GetMover()->GetObjectGuid().GetString().c_str(), guid.GetString().c_str());
- - return;
- - }
- + if (Unit *pMover = ObjectAccessor::GetUnit(*GetPlayer(), guid))
- + GetPlayer()->SetMover(pMover);
- + else
- + GetPlayer()->SetMover(NULL);
- }
- void WorldSession::HandleMoveNotActiveMoverOpcode(WorldPacket &recv_data)
- @@ -356,23 +359,13 @@ void WorldSession::HandleMoveNotActiveMoverOpcode(WorldPacket &recv_data)
- DEBUG_LOG("WORLD: Recvd CMSG_MOVE_NOT_ACTIVE_MOVER");
- recv_data.hexlike();
- - ObjectGuid old_mover_guid;
- + ObjectGuid guid;
- MovementInfo mi;
- - recv_data >> old_mover_guid.ReadAsPacked();
- + recv_data >> guid.ReadAsPacked();
- recv_data >> mi;
- - if(_player->GetMover()->GetObjectGuid() == old_mover_guid)
- - {
- - sLog.outError("HandleMoveNotActiveMover: incorrect mover guid: mover is %s and should be %s instead of %s",
- - _player->GetMover()->GetObjectGuid().GetString().c_str(),
- - _player->GetObjectGuid().GetString().c_str(),
- - old_mover_guid.GetString().c_str());
- - recv_data.rpos(recv_data.wpos()); // prevent warnings spam
- - return;
- - }
- -
- - _player->m_movementInfo = mi;
- + GetPlayer()->m_movementInfo = mi;
- }
- void WorldSession::HandleDismissControlledVehicle(WorldPacket &recv_data)
- @@ -386,18 +379,171 @@ void WorldSession::HandleDismissControlledVehicle(WorldPacket &recv_data)
- recv_data >> guid.ReadAsPacked();
- recv_data >> mi;
- - ObjectGuid vehicleGUID = _player->GetCharmGuid();
- + ObjectGuid vehicleGUID = _player->GetVehicleGUID();
- if (vehicleGUID.IsEmpty()) // something wrong here...
- return;
- _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))
- {
- - // Aura::HandleAuraControlVehicle will call Player::ExitVehicle
- - vehicle->RemoveSpellsCausingAura(SPELL_AURA_CONTROL_VEHICLE);
- + 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();
- +
- + GetPlayer()->ExitVehicle();
- +}
- +
- +void WorldSession::HandleRequestVehiclePrevSeat(WorldPacket &recv_data)
- +{
- + DEBUG_LOG("WORLD: Recvd CMSG_REQUEST_VEHICLE_PREV_SEAT");
- + recv_data.hexlike();
- +
- + GetPlayer()->ChangeSeat(-1, false);
- +}
- +
- +void WorldSession::HandleRequestVehicleNextSeat(WorldPacket &recv_data)
- +{
- + DEBUG_LOG("WORLD: Recvd CMSG_REQUEST_VEHICLE_NEXT_SEAT");
- + recv_data.hexlike();
- +
- + GetPlayer()->ChangeSeat(-1, true);
- +}
- +
- +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))
- + {
- + ObjectGuid guid;
- + recv_data >> guid.ReadAsPacked();
- +
- + int8 seatId = 0;
- + recv_data >> seatId;
- +
- + if(!guid.IsEmpty())
- + {
- + if(vehicleGUID != guid.GetRawValue())
- + {
- + if(Vehicle *veh = ObjectAccessor::GetVehicle(guid.GetRawValue()))
- + {
- + 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(recv_data.GetOpcode() == CMSG_REQUEST_VEHICLE_PREV_SEAT)
- + {
- + _player->ChangeSeat(-1, false);
- + return;
- + }
- + else if(recv_data.GetOpcode() == CMSG_REQUEST_VEHICLE_NEXT_SEAT)
- + {
- + _player->ChangeSeat(-1, true);
- + return;
- + }
- +
- + ObjectGuid guid, guid2;
- + recv_data >> guid.ReadAsPacked();
- +
- + MovementInfo mi;
- + recv_data >> mi;
- + _player->m_movementInfo = mi;
- +
- + recv_data >> guid2.ReadAsPacked(); //guid of vehicle or of vehicle in target seat
- +
- + int8 seatId;
- + recv_data >> seatId;
- +
- + if(guid.GetRawValue() == guid2.GetRawValue())
- + _player->ChangeSeat(seatId, false);
- + else if(Vehicle *vehicle = ObjectAccessor::GetVehicle(guid2.GetRawValue()))
- + {
- + if(vehicle->HasEmptySeat(seatId))
- + {
- + _player->ExitVehicle();
- + _player->EnterVehicle(vehicle, seatId);
- + }
- + }
- +}
- +
- +void WorldSession::HandleEnterPlayerVehicle(WorldPacket &recv_data)
- +{
- + DEBUG_LOG("WORLD: Recvd CMSG_PLAYER_VEHICLE_ENTER");
- + recv_data.hexlike();
- +
- + ObjectGuid guid;
- + recv_data >> guid;
- +
- + if (Player* pl = ObjectAccessor::FindPlayer(guid))
- + {
- + if (!pl->GetVehicleKit())
- + return;
- + if (!pl->IsInSameRaidWith(GetPlayer()))
- + return;
- + if (!pl->IsWithinDistInMap(GetPlayer(), INTERACTION_DISTANCE))
- + return;
- + if (pl->GetTransport())
- + return;
- + GetPlayer()->EnterVehicle(pl->GetVehicleKit());
- + }
- +}
- +
- +void WorldSession::HandleEjectPasenger(WorldPacket &recv_data)
- +{
- + DEBUG_LOG("WORLD: Recvd CMSG_EJECT_PASSENGER");
- + recv_data.hexlike();
- +
- + if(recv_data.GetOpcode()==CMSG_EJECT_PASSENGER)
- + {
- + if (GetPlayer()->GetVehicleKit())
- + {
- + ObjectGuid guid;
- + recv_data >> guid;
- + if(Player* Pl = ObjectAccessor::FindPlayer(guid))
- + Pl->ExitVehicle();
- + }
- }
- }
- @@ -495,7 +641,14 @@ bool WorldSession::VerifyMovementInfo(MovementInfo& movementInfo, ObjectGuid& gu
- if (!MaNGOS::IsValidMapCoord(movementInfo.GetPos()->x, movementInfo.GetPos()->y, movementInfo.GetPos()->z, movementInfo.GetPos()->o))
- return false;
- - if (movementInfo.HasMovementFlag(MOVEFLAG_ONTRANSPORT))
- + if((movementInfo.HasMovementFlag (MOVEFLAG_ONTRANSPORT)) && (movementInfo.HasMovementFlag (MOVEFLAG_ROOT)))
- + {
- + if(mover->GetVehicle() && mover->GetVehicleGUID() && mover->GetTypeId()==TYPEID_PLAYER)
- + {
- + _player->ExitVehicle();
- + }
- + }
- + else if (movementInfo.HasMovementFlag (MOVEFLAG_ONTRANSPORT) && !mover->GetVehicle() && !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)
- @@ -529,6 +682,9 @@ void WorldSession::HandleMoverRelocation(MovementInfo& movementInfo, Unit* mover
- {
- plMover->m_transport = (*iter);
- (*iter)->AddPassenger(plMover);
- +
- + if (plMover->GetVehicleKit())
- + plMover->GetVehicleKit()->RemoveAllPassengers();
- break;
- }
- }
- @@ -546,6 +702,17 @@ void WorldSession::HandleMoverRelocation(MovementInfo& movementInfo, Unit* mover
- // 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);
- + }
- + }
- + }
- plMover->SetPosition(movementInfo.GetPos()->x, movementInfo.GetPos()->y, movementInfo.GetPos()->z, movementInfo.GetPos()->o);
- plMover->m_movementInfo = movementInfo;
- @@ -584,6 +751,10 @@ void WorldSession::HandleMoverRelocation(MovementInfo& movementInfo, Unit* mover
- 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());
- + }
- }
- }
- diff --git a/src/game/Object.cpp b/src/game/Object.cpp
- index db44d14..8d00df5 100644
- --- a/src/game/Object.cpp
- +++ b/src/game/Object.cpp
- @@ -270,13 +270,16 @@ void Object::BuildMovementUpdate(ByteBuffer * data, uint16 updateFlags) const
- }
- }
- }
- + if (unit->GetVehicle() || unit->GetVehicleGUID())
- + unit->m_movementInfo.AddMovementFlag(MOVEFLAG_ONTRANSPORT);
- +
- }
- break;
- case TYPEID_PLAYER:
- {
- Player *player = ((Player*)unit);
- - if(player->GetTransport())
- + if(player->GetTransport() || player->GetVehicle())
- player->m_movementInfo.AddMovementFlag(MOVEFLAG_ONTRANSPORT);
- else
- player->m_movementInfo.RemoveMovementFlag(MOVEFLAG_ONTRANSPORT);
- @@ -284,6 +287,9 @@ 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())
- + player->m_movementInfo.AddMovementFlag(MOVEFLAG_ONTRANSPORT);
- +
- if(player->IsTaxiFlying())
- {
- MANGOS_ASSERT(player->GetMotionMaster()->GetCurrentMovementGeneratorType() == FLIGHT_MOTION_TYPE);
- @@ -1144,7 +1150,14 @@ void WorldObject::Relocate(float x, float y, float z, float orientation)
- m_orientation = orientation;
- if(isType(TYPEMASK_UNIT))
- + {
- ((Unit*)this)->m_movementInfo.ChangePosition(x, y, z, orientation);
- + if(GetTypeId() == TYPEID_UNIT)
- + {
- + if(((Creature*)this)->IsVehicle() && IsInWorld())
- + ((Vehicle*)this)->RellocatePassengers(GetMap());
- + }
- + }
- }
- void WorldObject::Relocate(float x, float y, float z)
- @@ -1154,7 +1167,11 @@ void WorldObject::Relocate(float x, float y, float z)
- m_positionZ = z;
- if(isType(TYPEMASK_UNIT))
- + {
- ((Unit*)this)->m_movementInfo.ChangePosition(x, y, z, GetOrientation());
- + if(((Creature*)this)->IsVehicle() && IsInWorld())
- + ((Vehicle*)this)->RellocatePassengers(GetMap());
- + }
- }
- uint32 WorldObject::GetZoneId() const
- @@ -1762,6 +1779,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->GetObjectBoundingRadius());
- +
- + 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 653b169..810a4b2 100644
- --- a/src/game/Object.h
- +++ b/src/game/Object.h
- @@ -69,6 +69,7 @@ class Unit;
- class Map;
- class UpdateMask;
- class InstanceData;
- +class Vehicle;
- typedef UNORDERED_MAP<Player*, UpdateData> UpdateDataMapType;
- @@ -492,6 +493,9 @@ class MANGOS_DLL_SPEC WorldObject : public Object
- bool isActiveObject() const { return m_isActiveObject || m_viewPoint.hasViewers(); }
- ViewPoint& GetViewPoint() { return m_viewPoint; }
- +
- + 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 a1a21df..92f39c7 100644
- --- a/src/game/ObjectAccessor.cpp
- +++ b/src/game/ObjectAccessor.cpp
- @@ -53,6 +53,21 @@ ObjectAccessor::~ObjectAccessor()
- }
- }
- +Creature*
- +ObjectAccessor::GetAnyTypeCreature(WorldObject const &u, ObjectGuid guid)
- +{
- + if(guid.IsPlayer() || !u.IsInWorld())
- + return NULL;
- +
- + if(guid.IsPet())
- + return u.GetMap()->GetPet(guid);
- +
- + if(guid.IsVehicle())
- + return u.GetMap()->GetVehicle(guid);
- +
- + return u.GetMap()->GetCreature(guid);
- +}
- +
- Unit*
- ObjectAccessor::GetUnit(WorldObject const &u, ObjectGuid guid)
- {
- @@ -62,10 +77,7 @@ ObjectAccessor::GetUnit(WorldObject const &u, ObjectGuid guid)
- if(guid.IsPlayer())
- return FindPlayer(guid);
- - if (!u.IsInWorld())
- - return NULL;
- -
- - return u.GetMap()->GetAnyTypeCreature(guid);
- + return GetAnyTypeCreature(u, guid);
- }
- Corpse* ObjectAccessor::GetCorpseInMap(ObjectGuid guid, uint32 mapid)
- diff --git a/src/game/ObjectAccessor.h b/src/game/ObjectAccessor.h
- index 5b9445f..c28d41c 100644
- --- a/src/game/ObjectAccessor.h
- +++ b/src/game/ObjectAccessor.h
- @@ -40,6 +40,7 @@
- class Creature;
- class Unit;
- class GameObject;
- +class Vehicle;
- class WorldObject;
- class Map;
- @@ -100,13 +101,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, ObjectGuid guid);
- - // FIXME: map local object with global search
- + // map local object with global search
- static Creature* GetCreatureInWorld(ObjectGuid guid) { return FindHelper<Creature>(guid); }
- static GameObject* GetGameObjectInWorld(ObjectGuid guid) { return FindHelper<GameObject>(guid); }
- + static Pet* GetGameObjectInWorld(ObjectGuid guid, Pet* /*fake*/) { return FindHelper<Pet>(guid); }
- + static Vehicle* GetGameObjectInWorld(ObjectGuid guid, Vehicle* /*fake*/) { return FindHelper<Vehicle>(guid); }
- // Search player at any map in world and other objects at same map with `obj`
- // Note: recommended use Map::GetUnit version if player also expected at same map only
- static Unit* GetUnit(WorldObject const& obj, ObjectGuid guid);
- + static Creature* GetAnyTypeCreature(WorldObject const &, ObjectGuid guid);
- + //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(ObjectGuid guid) { return GetGameObjectInWorld(guid, (Vehicle*)NULL); }
- + //static Player* FindPlayer(uint64);
- // Player access
- static Player* FindPlayer(ObjectGuid guid); // if need player at specific map better use Map::GetPlayer
- @@ -175,6 +184,9 @@ inline Unit* ObjectAccessor::GetUnitInWorld(WorldObject const& obj, ObjectGuid g
- if (guid.IsPet())
- return obj.IsInWorld() ? obj.GetMap()->GetPet(guid) : NULL;
- + if (guid.IsVehicle())
- + 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 cf4c613..f6e415d 100644
- --- a/src/game/ObjectMgr.cpp
- +++ b/src/game/ObjectMgr.cpp
- @@ -830,6 +830,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];
- +
- + uint32 i=0;
- + for(uint32 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();
- @@ -866,6 +953,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);
- }
- }
- @@ -6420,6 +6508,8 @@ uint32 ObjectMgr::GenerateLowGuid(HighGuid guidhigh)
- return m_ItemGuids.Generate();
- case HIGHGUID_UNIT:
- return m_CreatureGuids.Generate();
- + case HIGHGUID_VEHICLE:
- + return m_VehicleGuids.Generate();
- case HIGHGUID_PLAYER:
- return m_CharGuids.Generate();
- case HIGHGUID_GAMEOBJECT:
- @@ -9656,6 +9746,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 5b74ea6..9c8c136 100644
- --- a/src/game/ObjectMgr.h
- +++ b/src/game/ObjectMgr.h
- @@ -675,6 +675,8 @@ extern LanguageDesc lang_description[LANGUAGES_COUNT];
- MANGOS_DLL_SPEC LanguageDesc const* GetLanguageDescByID(uint32 lang);
- class PlayerDumpReader;
- +// vehicle system
- +#define MAX_VEHICLE_SPELLS 6
- template<typename T>
- class IdGenerator
- @@ -694,6 +696,16 @@ class IdGenerator
- T m_nextGuid;
- };
- +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
- {
- friend class PlayerDumpReader;
- @@ -984,6 +996,9 @@ class ObjectMgr
- void LoadVendors() { LoadVendors("npc_vendor", false); }
- void LoadTrainerSpell();
- + void LoadVehicleData();
- + void LoadVehicleSeatData();
- +
- std::string GeneratePetName(uint32 entry);
- uint32 GetBaseXP(uint32 level) const;
- uint32 GetXPForLevel(uint32 level) const;
- @@ -1248,6 +1263,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 mSpellClickInfoMap.equal_range(creature_id);
- @@ -1324,6 +1357,7 @@ class ObjectMgr
- ObjectGuidGenerator<HIGHGUID_GAMEOBJECT> m_GameobjectGuids;
- ObjectGuidGenerator<HIGHGUID_CORPSE> m_CorpseGuids;
- ObjectGuidGenerator<HIGHGUID_INSTANCE> m_InstanceGuids;
- + ObjectGuidGenerator<HIGHGUID_VEHICLE> m_VehicleGuids;
- QuestMap mQuestTemplates;
- @@ -1392,6 +1426,7 @@ class ObjectMgr
- void CheckScriptTexts(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(QuestRelationsMap& map, char const* table);
- MailLevelRewardMap m_mailLevelRewardMap;
- diff --git a/src/game/Opcodes.cpp b/src/game/Opcodes.cpp
- index 4f0fbe0..647f38d 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::HandleCharCustomizeOpcode },
- /*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 },
- @@ -1218,8 +1218,8 @@ OpcodeHandler opcodeTable[NUM_MSG_TYPES] =
- /*0x4A5*/ { "UMSG_UNKNOWN_1189", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x4A6*/ { "SMSG_BATTLEGROUND_INFO_THROTTLED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x4A7*/ { "SMSG_PLAYER_VEHICLE_DATA", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- - /*0x4A8*/ { "CMSG_UNKNOWN_1192", STATUS_NEVER, &WorldSession::Handle_NULL },
- - /*0x4A9*/ { "CMSG_EJECT_PASSENGER", STATUS_NEVER, &WorldSession::Handle_NULL },
- + /*0x4A8*/ { "CMSG_PLAYER_VEHICLE_ENTER", STATUS_LOGGEDIN, &WorldSession::HandleEnterPlayerVehicle },
- + /*0x4A9*/ { "CMSG_EJECT_PASSENGER", STATUS_LOGGEDIN, &WorldSession::HandleEjectPasenger },
- /*0x4AA*/ { "SMSG_PET_GUIDS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x4AB*/ { "SMSG_CLIENTCACHE_VERSION", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x4AC*/ { "UMSG_UNKNOWN_1196", STATUS_NEVER, &WorldSession::Handle_NULL },
- diff --git a/src/game/Pet.cpp b/src/game/Pet.cpp
- index 0147df0..63cfdcc 100644
- --- a/src/game/Pet.cpp
- +++ b/src/game/Pet.cpp
- @@ -40,7 +40,7 @@ Pet::Pet(PetType type) :
- Creature(CREATURE_SUBTYPE_PET),
- m_resetTalentsCost(0), m_resetTalentsTime(0), m_usedTalentCount(0),
- m_removed(false), m_happinessTimer(7500), m_petType(type), m_duration(0),
- -m_bonusdamage(0), m_auraUpdateMask(0), m_loading(false),
- +m_bonusdamage(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 1a5d473..d9aa51c 100644
- --- a/src/game/Pet.h
- +++ b/src/game/Pet.h
- @@ -237,10 +237,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); }
- @@ -252,7 +248,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 afcf297..aa24277 100644
- --- a/src/game/PetHandler.cpp
- +++ b/src/game/PetHandler.cpp
- @@ -313,7 +313,7 @@ void WorldSession::HandlePetNameQueryOpcode( WorldPacket & recv_data )
- void WorldSession::SendPetNameQuery( uint64 petguid, uint32 petnumber)
- {
- - Creature* pet = _player->GetMap()->GetAnyTypeCreature(petguid);
- + Creature* pet = ObjectAccessor::GetAnyTypeCreature(*_player, petguid);
- if(!pet || !pet->GetCharmInfo() || pet->GetCharmInfo()->GetPetNumber() != petnumber)
- {
- WorldPacket data(SMSG_PET_NAME_QUERY_RESPONSE, (4+1+4+1));
- @@ -353,7 +353,12 @@ void WorldSession::HandlePetSetAction( WorldPacket & recv_data )
- recv_data >> petguid;
- - Creature* pet = _player->GetMap()->GetAnyTypeCreature(petguid);
- + // FIXME: charmed case
- + //Pet* pet = ObjectAccessor::Instance().GetPet(petguid);
- + if(ObjectAccessor::FindPlayer(petguid))
- + return;
- +
- + Creature* pet = ObjectAccessor::GetAnyTypeCreature(*_player, petguid);
- if(!pet || (pet != _player->GetPet() && pet != _player->GetCharm()))
- {
- @@ -542,7 +547,8 @@ void WorldSession::HandlePetAbandon( WorldPacket & recv_data )
- return;
- // pet/charmed
- - if (Creature* pet = _player->GetMap()->GetAnyTypeCreature(guid))
- + Creature* pet = ObjectAccessor::GetAnyTypeCreature(*_player, guid);
- + if (pet)
- {
- if (pet->IsPet())
- {
- @@ -596,7 +602,10 @@ void WorldSession::HandlePetSpellAutocastOpcode( WorldPacket& recvPacket )
- uint8 state; //1 for on, 0 for off
- recvPacket >> guid >> spellid >> state;
- - Creature* pet = _player->GetMap()->GetAnyTypeCreature(guid);
- + if(ObjectAccessor::FindPlayer(guid))
- + return;
- +
- + Creature* pet=ObjectAccessor::GetAnyTypeCreature(*_player,guid);
- if (!pet || (guid != _player->GetPetGuid() && guid != _player->GetCharmGuid()))
- {
- sLog.outError("HandlePetSpellAutocastOpcode. %s isn't pet of %s .", guid.GetString().c_str(), GetPlayer()->GetObjectGuid().GetString().c_str());
- @@ -626,6 +635,23 @@ void WorldSession::HandlePetSpellAutocastOpcode( WorldPacket& recvPacket )
- void WorldSession::HandlePetCastSpellOpcode( WorldPacket& recvPacket )
- {
- DETAIL_LOG("WORLD: CMSG_PET_CAST_SPELL");
- + recvPacket.hexlike();
- + recvPacket.print_storage();
- +
- + //2 - 0 - 0 - 43 - 129 - 0 - 80 - 241 | - 42 - 211 - 253 - 0 | - 0 | - 2 |- 96 - 0 - 0 - 0 | - 0 - 26
- + //- 164 - 59 - 196 - 174 - 98 - 131 | - 194 - 182 - 171 - 218| - 67 - 0 - 48 - 93| - 0 - 196 - 32
- + //- 177| - 242 - 193 - 22 - 110 - 224 - 67 - 203 - 166 | - 68 - 61 - 133 - 1| - 240 - 66 - 1 - 183 |
- + //- 0 - 0 - 0 - 217| - 2 - 43 - 129 - 80 - 241 - 0 - 10 - 0 - 0 - 0 - 0 - 76 - 109 - 175 - 0
- + //- 238 - 115 - 58 - 196 - 20 - 110 - 121 - 194 - 187 - 107 - 217 - 67 - 32 - 44 - 27 - 62 - 217
- + //- 1 - 36 - 129 - 80 - 241 - 0 - 0 - 160 - 64 - 0 - 0 - 160 - 64 - 0 - 0 - 160 - 64 - 192 - 233
- + //- 172 - 62 - 4 - 0 - 0 - 0 - 7 - 230 - 0 - 0 - 0 -
- +
- + //5 - 0 - 0 - 43 - 129 - 0 - 80 - 241 | - 85 - 211 - 253 - 0 | - 0 | - 2 | - 96 - 0 - 0 - 0 | - 0 - 69 - 60 - 61
- + //- 196 - 171 - 248 - 107| - 194 - 8 - 236 - 218 | - 67 - 0 - 177 - 11 | - 46 - 196 - 89 - 16 | - 14 - 195
- + //- 5 - 38 - 231 - 67 - 23 - 221 | - 110 - 62 - 15 - 3 | - 240 - 66 -| 1 - 183 | - 0 - 0 - 0 - 217 | - 5 - 43
- + //- 129 - 80 - 241 - 0 - 10 - 0 - 0 - 0 - 0 - 233 - 41 - 203 - 0 - 106 - 207 - 59 - 196 - 179 - 173 - 83
- + //- 194 - 8 - 108 - 217 - 67 - 127 - 153 - 170 - 64 - 217 - 4 - 36 - 129 - 80 - 241 - 0 - 0 - 160 - 64
- + //- 0 - 0 - 160 - 64 - 0 - 0 - 160 - 64 - 7 - 77 - 175 - 64 - 4 - 0 - 0 - 0 - 7 - 195 - 0 - 0 - 0 -
- ObjectGuid guid;
- uint32 spellid;
- @@ -636,7 +662,10 @@ void WorldSession::HandlePetCastSpellOpcode( WorldPacket& recvPacket )
- DEBUG_LOG("WORLD: CMSG_PET_CAST_SPELL, %s, cast_count: %u, spellid %u, unk_flags %u", guid.GetString().c_str(), cast_count, spellid, unk_flags);
- - Creature* pet = _player->GetMap()->GetAnyTypeCreature(guid);
- + if (guid.IsPlayer())
- + return;
- +
- + Creature* pet = ObjectAccessor::GetAnyTypeCreature(*_player,guid);
- if (!pet || (guid != _player->GetPetGuid() && guid != _player->GetCharmGuid()))
- {
- diff --git a/src/game/Player.cpp b/src/game/Player.cpp
- index acae59c..a2be5d8 100644
- --- a/src/game/Player.cpp
- +++ b/src/game/Player.cpp
- @@ -460,7 +460,6 @@ Player::Player (WorldSession *session): Unit(), m_mover(this), m_camera(this), m
- // group is initialized in the reference constructor
- SetGroupInvite(NULL);
- m_groupUpdateMask = 0;
- - m_auraUpdateMask = 0;
- duel = NULL;
- @@ -1755,6 +1754,11 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati
- m_movementInfo.ClearTransportData();
- }
- + if (GetVehicleKit())
- + GetVehicleKit()->RemoveAllPassengers();
- +
- + ExitVehicle();
- +
- // The player was ported to another map and looses the duel immediately.
- // We have to perform this check before the teleport, otherwise the
- // ObjectAccessor won't find the flag.
- @@ -2239,7 +2243,7 @@ Creature* Player::GetNPCIfCanInteractWith(ObjectGuid guid, uint32 npcflagmask)
- return NULL;
- // exist (we need look pets also for some interaction (quest/etc)
- - Creature *unit = GetMap()->GetAnyTypeCreature(guid);
- + Creature *unit = ObjectAccessor::GetAnyTypeCreature(*this,guid);
- if (!unit)
- return NULL;
- @@ -4000,6 +4004,7 @@ void Player::InitVisibleBits()
- updateVisualBits.SetBit(PLAYER_BYTES_3);
- updateVisualBits.SetBit(PLAYER_DUEL_TEAM);
- updateVisualBits.SetBit(PLAYER_GUILD_TIMESTAMP);
- + updateVisualBits.SetBit(UNIT_NPC_FLAGS);
- // PLAYER_QUEST_LOG_x also visible bit on official (but only on party/raid)...
- for(uint16 i = PLAYER_QUEST_LOG_1_1; i < PLAYER_QUEST_LOG_25_2; i += MAX_QUEST_OFFSET)
- @@ -6026,7 +6031,9 @@ ActionButton const* Player::GetActionButton(uint8 button)
- bool Player::SetPosition(float x, float y, float z, float orientation, bool teleport)
- {
- - // prevent crash when a bad coord is sent by the client
- + if(!Unit::SetPosition(x, y, z, orientation, teleport))
- + return false;
- +
- if(!MaNGOS::IsValidMapCoord(x,y,z,orientation))
- {
- DEBUG_LOG("Player::SetPosition(%f, %f, %f, %f, %d) .. bad coordinates for player %d!",x,y,z,orientation,teleport,GetGUIDLow());
- @@ -8506,6 +8513,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:
- FillInitialWorldState(data,count, 0x914, 0x0); // 2324 7
- FillInitialWorldState(data,count, 0x913, 0x0); // 2323 8
- @@ -13095,7 +13137,8 @@ void Player::PrepareQuestMenu(ObjectGuid guid)
- QuestRelationsMapBounds irbounds;
- // pets also can have quests
- - if (Creature *pCreature = GetMap()->GetAnyTypeCreature(guid))
- + Creature *pCreature = ObjectAccessor::GetAnyTypeCreature(*this, guid);
- + if (pCreature)
- {
- rbounds = sObjectMgr.GetCreatureQuestRelationsMapBounds(pCreature->GetEntry());
- irbounds = sObjectMgr.GetCreatureQuestInvolvedRelationsMapBounds(pCreature->GetEntry());
- @@ -13197,7 +13240,8 @@ void Player::SendPreparedQuest(ObjectGuid guid)
- std::string title = "";
- // need pet case for some quests
- - if (Creature *pCreature = GetMap()->GetAnyTypeCreature(guid))
- + Creature *pCreature = ObjectAccessor::GetAnyTypeCreature(*this,guid);
- + if (pCreature)
- {
- uint32 textid = GetGossipTextId(pCreature);
- @@ -13268,7 +13312,8 @@ Quest const* Player::GetNextQuest(ObjectGuid guid, Quest const *pQuest)
- {
- QuestRelationsMapBounds rbounds;
- - if (Creature *pCreature = GetMap()->GetAnyTypeCreature(guid))
- + Creature *pCreature = ObjectAccessor::GetAnyTypeCreature(*this,guid);
- + if( pCreature )
- {
- rbounds = sObjectMgr.GetCreatureQuestRelationsMapBounds(pCreature->GetEntry());
- }
- @@ -18328,7 +18373,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);
- + (*i)->SendHeartBeat(false);
- + }
- }
- }
- else
- @@ -18363,7 +18411,7 @@ bool Player::ActivateTaxiPathTo(std::vector<uint32> const& nodes, Creature* npc
- if(npc)
- {
- // not let cheating with start flight mounted
- - if(IsMounted())
- + if(IsMounted() || GetVehicle() || GetVehicleGUID())
- {
- WorldPacket data(SMSG_ACTIVATETAXIREPLY, 4);
- data << uint32(ERR_TAXIPLAYERALREADYMOUNTED);
- @@ -18392,6 +18440,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);
- @@ -19540,7 +19589,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);
- + ((Unit*)target)->SendHeartBeat(false);
- + }
- if(target->GetTypeId()==TYPEID_UNIT && ((Creature*)target)->isAlive())
- ((Creature*)target)->SendMonsterMoveWithSpeedToCurrentDestination(this);
- @@ -19605,13 +19657,22 @@ void Player::InitPrimaryProfessions()
- void Player::SendComboPoints()
- {
- Unit *combotarget = ObjectAccessor::GetUnit(*this, m_comboTargetGuid);
- - if (combotarget)
- - {
- - WorldPacket data(SMSG_UPDATE_COMBO_POINTS, combotarget->GetPackGUID().size()+1);
- - data << 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 << vehicle->GetPackGUID();
- + }else return;
- + }
- + data << combotarget->GetPackGUID();
- + data << uint8(m_comboPoints);
- + GetSession()->SendPacket(&data);
- }
- void Player::AddComboPoints(Unit* target, int8 count)
- @@ -19734,6 +19795,13 @@ void Player::SendInitialPacketsBeforeAddToMap()
- void Player::SendInitialPacketsAfterAddToMap()
- {
- + if(getClass() == CLASS_DEATH_KNIGHT)
- + ResyncRunes();
- +
- + WorldPacket data0(SMSG_SET_PHASE_SHIFT, 4);
- + data0 << uint32(GetPhaseMask());
- + GetSession()->SendPacket(&data0);
- +
- // update zone
- uint32 newzone, newarea;
- GetZoneAndAreaId(newzone,newarea);
- @@ -19772,6 +19840,14 @@ void Player::SendInitialPacketsAfterAddToMap()
- SendMessageToSet(&data2,true);
- }
- + if(GetVehicle() || GetVehicleGUID())
- + {
- + WorldPacket data3(SMSG_FORCE_MOVE_ROOT, 10);
- + data3 << GetPackGUID();
- + data3 << (uint32)((m_movementInfo.GetVehicleSeatFlags() & SF_CAN_CAST) ? 2 : 0);
- + SendMessageToSet(&data3,true);
- + }
- +
- SendAurasForTarget(this);
- SendEnchantmentDurations(); // must be after add to map
- SendItemDurations(); // must be after add to map
- @@ -19786,7 +19862,7 @@ void Player::SendUpdateToOutOfRangeGroupMembers()
- m_groupUpdateMask = GROUP_UPDATE_FLAG_NONE;
- m_auraUpdateMask = 0;
- - if(Pet *pet = GetPet())
- + if(Unit *pet = GetCharmOrPet())
- pet->ResetAuraUpdateMask();
- }
- @@ -20250,7 +20326,7 @@ void Player::UpdateForQuestWorldObjects()
- }
- else if (itr->IsCreatureOrVehicle())
- {
- - Creature *obj = GetMap()->GetAnyTypeCreature(*itr);
- + Creature *obj = ObjectAccessor::GetAnyTypeCreature(*this, *itr);
- if(!obj)
- continue;
- @@ -20523,8 +20599,8 @@ void Player::RewardSinglePlayerAtKill(Unit* pVictim)
- // honor can be in PvP and !PvP (racial leader) cases
- RewardHonor(pVictim,1);
- - // xp and reputation only in !PvP case
- - if(!PvP)
- + // xp and reputation only in !PvP case and not in vehicle
- + if(!PvP && !(GetVehicleGUID() && (m_movementInfo.GetVehicleFlags() & VF_GIVE_EXP)))
- {
- RewardReputation(pVictim,1);
- GiveXP(xp, pVictim);
- @@ -21025,26 +21101,16 @@ void Player::ApplyGlyphs(bool apply)
- ApplyGlyph(i,apply);
- }
- -void Player::EnterVehicle(Vehicle *vehicle)
- +void Player::SendEnterVehicle(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(GetObjectGuid());
- - vehicle->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK);
- - vehicle->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED);
- - vehicle->setFaction(getFaction());
- -
- - SetCharm(vehicle); // charm
- - m_camera.SetView(vehicle); // set view
- -
- - SetClientControl(vehicle, 1); // redirect controls to vehicle
- - SetMover(vehicle);
- + 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(SMSG_ON_CANCEL_EXPECTED_RIDE_VEHICLE_AURA, 0);
- GetSession()->SendPacket(&data);
- @@ -21061,60 +21127,20 @@ void Player::EnterVehicle(Vehicle *vehicle)
- data << vehicle->GetOrientation(); // o
- // transport part, TODO: load/calculate seat offsets
- data << vehicle->GetObjectGuid(); // 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 << float(m_movementInfo.GetTransportPos()->x); // transport offsetX
- + data << float(m_movementInfo.GetTransportPos()->y); // transport offsetY
- + data << float(m_movementInfo.GetTransportPos()->z); // transport offsetZ
- + data << float(m_movementInfo.GetTransportPos()->o); // 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 << vehicle->GetObjectGuid();
- - 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)
- -{
- - vehicle->SetCharmerGuid(ObjectGuid());
- - 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);
- -
- - SetCharm(NULL);
- - m_camera.ResetView();
- -
- - SetClientControl(vehicle, 0);
- - SetMover(NULL);
- -
- - WorldPacket data(MSG_MOVE_TELEPORT_ACK, 30);
- - data << 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
- - 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()
- diff --git a/src/game/Player.h b/src/game/Player.h
- index 3257ba5..dc38be0 100644
- --- a/src/game/Player.h
- +++ b/src/game/Player.h
- @@ -2254,8 +2254,8 @@ class MANGOS_DLL_SPEC Player : public Unit
- Unit* GetMover() const { return m_mover; }
- bool IsSelfMover() const { return m_mover == this; }// normal case for player not controlling other unit
- - void EnterVehicle(Vehicle *vehicle);
- - void ExitVehicle(Vehicle *vehicle);
- + // vehicle system
- + void SendEnterVehicle(Vehicle *vehicle);
- ObjectGuid const& GetFarSightGuid() const { return GetGuidValue(PLAYER_FARSIGHT); }
- @@ -2358,8 +2358,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
- @@ -2622,7 +2620,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 cd08544..38124a6 100644
- --- a/src/game/QuestHandler.cpp
- +++ b/src/game/QuestHandler.cpp
- @@ -655,9 +655,8 @@ void WorldSession::HandleQuestgiverStatusMultipleQuery(WorldPacket& /*recvPacket
- if (itr->IsCreatureOrPet())
- {
- // need also pet quests case support
- - Creature *questgiver = GetPlayer()->GetMap()->GetAnyTypeCreature(*itr);
- -
- - if (!questgiver || questgiver->IsHostileTo(_player))
- + Creature *questgiver = ObjectAccessor::GetAnyTypeCreature(*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 5eae25a..4af62d7 100644
- --- a/src/game/ReactorAI.cpp
- +++ b/src/game/ReactorAI.cpp
- @@ -116,6 +116,7 @@ ReactorAI::EnterEvadeMode()
- DEBUG_FILTER_LOG(LOG_FILTER_AI_AND_MOVEGENSS, "Creature stopped attacking, victim %s [guid=%u]", victim->isAlive() ? "out run him" : "is dead", m_creature->GetGUIDLow());
- }
- + 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 13abe2f..462ac22 100644
- --- a/src/game/SharedDefines.h
- +++ b/src/game/SharedDefines.h
- @@ -2472,6 +2472,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 InstanceResetMethod
- {
- INSTANCE_RESET_ALL,
- diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp
- index fddd65a..be21aab 100644
- --- a/src/game/Spell.cpp
- +++ b/src/game/Spell.cpp
- @@ -115,7 +115,8 @@ SpellCastTargets::SpellCastTargets()
- m_itemTargetEntry = 0;
- - m_srcX = m_srcY = m_srcZ = m_destX = m_destY = m_destZ = 0.0f;
- + m_srcX = m_srcY = m_srcZ = m_srcO = m_destX = m_destY = m_destZ = 0.0f;
- + m_elevation = m_speed = 0.0f;
- m_strTarget = "";
- m_targetMask = 0;
- }
- @@ -252,6 +253,19 @@ void SpellCastTargets::read( ByteBuffer& data, Unit *caster )
- data >> m_destX >> m_destY >> m_destZ;
- if(!MaNGOS::IsValidMapCoord(m_destX, m_destY, m_destZ))
- throw ByteBufferException(false, data.rpos(), 0, data.size());
- +
- + if( m_targetMask & TARGET_FLAG_SOURCE_LOCATION )
- + {
- + if(data.rpos() + 4 + 4 <= data.size())
- + {
- + data >> m_elevation >> m_speed;
- + // TODO: should also read
- + m_srcO = caster->GetOrientation();
- + //*data >> uint16 >> uint8 >> uint32 >> uint32;
- + //*data >> float >> float >> float >> float...
- + }
- + }
- +
- }
- if( m_targetMask & TARGET_FLAG_STRING )
- @@ -1582,9 +1596,11 @@ void Spell::SetTargetMap(SpellEffectIndex effIndex, uint32 targetMode, UnitList&
- case TARGET_TOTEM_FIRE:
- case TARGET_SELF:
- case TARGET_SELF2:
- - 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;
- @@ -1853,6 +1869,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;
- @@ -2342,7 +2361,13 @@ void Spell::SetTargetMap(SpellEffectIndex effIndex, uint32 targetMode, UnitList&
- case TARGET_DYNAMIC_OBJECT_LEFT_SIDE:
- case TARGET_DYNAMIC_OBJECT_RIGHT_SIDE:
- {
- - if (!(m_targets.m_targetMask & TARGET_FLAG_DEST_LOCATION))
- + //This should be targeting of destructible objects by vehicles (ram spells...)
- + if(m_spellInfo->EffectImplicitTargetB[effIndex] == TARGET_AREAEFFECT_CUSTOM_2)
- + {
- + //FIXME
- + break;
- + }
- + else if (!(m_targets.m_targetMask & TARGET_FLAG_DEST_LOCATION))
- {
- float angle = m_caster->GetOrientation();
- switch(targetMode)
- @@ -3313,7 +3338,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;
- @@ -3329,7 +3354,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
- @@ -4534,11 +4564,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->GetVehicle() || m_caster->GetVehicleGUID()) && m_caster->GetTypeId()==TYPEID_PLAYER && !m_IsTriggeredSpell &&
- !IsPassiveSpell(m_spellInfo) && !(m_spellInfo->Attributes & SPELL_ATTR_CASTABLE_WHILE_MOUNTED))
- {
- if (m_caster->IsTaxiFlying())
- return SPELL_FAILED_NOT_ON_TAXI;
- + else if(m_caster->GetVehicleGUID() || m_caster->GetVehicle())
- + {
- + if(!(m_caster->m_movementInfo.GetVehicleSeatFlags() & SF_CAN_CAST))
- + return SPELL_FAILED_NOT_MOUNTED;
- + }
- else
- return SPELL_FAILED_NOT_MOUNTED;
- }
- @@ -5374,33 +5409,48 @@ SpellCastResult Spell::CheckPetCast(Unit* target)
- if(!_target->isAlive())
- return SPELL_FAILED_BAD_TARGETS;
- - if(IsPositiveSpell(m_spellInfo->Id))
- - {
- - if(m_caster->IsHostileTo(_target))
- - return SPELL_FAILED_BAD_TARGETS;
- - }
- - else
- - {
- - bool duelvsplayertar = false;
- - for(int j = 0; j < MAX_EFFECT_INDEX; ++j)
- - {
- - //TARGET_DUELVSPLAYER is positive AND negative
- - duelvsplayertar |= (m_spellInfo->EffectImplicitTargetA[j] == TARGET_DUELVSPLAYER);
- - }
- - if(m_caster->IsFriendlyTo(target) && !duelvsplayertar)
- - {
- - return SPELL_FAILED_BAD_TARGETS;
- - }
- - }
- + if(!IsValidSingleTargetSpell(_target))
- + return SPELL_FAILED_BAD_TARGETS;
- }
- //cooldown
- if(((Creature*)m_caster)->HasSpellCooldown(m_spellInfo->Id))
- return SPELL_FAILED_NOT_READY;
- }
- + // NOTE : this is done twice, also in spell->prepare(&(spell->m_targets));
- return CheckCast(true);
- }
- +bool Spell::IsValidSingleTargetEffect(Unit const* target, Targets type) const
- +{
- + switch(type)
- + {
- + case TARGET_CHAIN_DAMAGE:
- + return !m_caster->IsFriendlyTo(target);
- + case TARGET_SINGLE_FRIEND:
- + case TARGET_AREAEFFECT_PARTY:
- + return m_caster->IsFriendlyTo(target);
- + case TARGET_SINGLE_PARTY:
- + return m_caster != target && m_caster->IsInPartyWith(target);
- + case TARGET_SINGLE_FRIEND_2:
- + return m_caster->IsInRaidWith(target);
- + }
- + return true;
- +}
- +
- +bool Spell::IsValidSingleTargetSpell(Unit const* target) const
- +{
- + for(int i = 0; i < 3; ++i)
- + {
- + if(!IsValidSingleTargetEffect(target, Targets(m_spellInfo->EffectImplicitTargetA[i])))
- + return false;
- + // Need to check B?
- + //if(!IsValidSingleTargetEffect(m_spellInfo->EffectImplicitTargetB[i], target)
- + // return false;
- + }
- + return true;
- +}
- +
- SpellCastResult Spell::CheckCasterAuras() const
- {
- // Flag drop spells totally immuned to caster auras
- diff --git a/src/game/Spell.h b/src/game/Spell.h
- index 2bb7e40..a810a51 100644
- --- a/src/game/Spell.h
- +++ b/src/game/Spell.h
- @@ -165,8 +165,9 @@ class SpellCastTargets
- void Update(Unit* caster);
- - float m_srcX, m_srcY, m_srcZ;
- + float m_srcX, m_srcY, m_srcZ, m_srcO;
- float m_destX, m_destY, m_destZ;
- + float m_elevation, m_speed;
- std::string m_strTarget;
- uint32 m_targetMask;
- @@ -346,6 +347,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, ObjectGuid originalCasterGUID = ObjectGuid(), SpellEntry const* triggeredBy = NULL);
- ~Spell();
- @@ -363,6 +366,8 @@ class Spell
- SpellCastResult CheckCast(bool strict);
- SpellCastResult CheckPetCast(Unit* target);
- + bool IsValidSingleTargetEffect(Unit const* target, Targets type) const;
- + bool IsValidSingleTargetSpell(Unit const* target) const;
- // handlers
- void handle_immediate();
- diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp
- index a2892e1..9899883 100644
- --- a/src/game/SpellAuras.cpp
- +++ b/src/game/SpellAuras.cpp
- @@ -2756,7 +2756,7 @@ void Aura::HandleAuraMounted(bool apply, bool Real)
- if (minfo)
- display_id = minfo->modelid;
- - target->Mount(display_id, GetId());
- + target->Mount(display_id, GetId(), ci->VehicleEntry);
- }
- else
- {
- @@ -3455,7 +3455,7 @@ void Aura::HandleModPossess(bool apply, bool Real)
- {
- ((Creature*)target)->AIM_Initialize();
- }
- - else if(target->GetTypeId() == TYPEID_PLAYER)
- + else if(target->GetTypeId() == TYPEID_PLAYER && !target->GetVehicleGUID())
- {
- ((Player*)target)->SetClientControl(target, 0);
- }
- @@ -3488,7 +3488,7 @@ void Aura::HandleModPossess(bool apply, bool Real)
- target->SetCharmerGuid(ObjectGuid());
- - if(target->GetTypeId() == TYPEID_PLAYER)
- + if(target->GetTypeId() == TYPEID_PLAYER && !target->GetVehicleGUID())
- {
- ((Player*)target)->setFactionForRace(target->getRace());
- ((Player*)target)->SetClientControl(target, 1);
- @@ -3790,10 +3790,13 @@ void Aura::HandleAuraModStun(bool apply, bool Real)
- target->SetStandState(UNIT_STAND_STATE_STAND);// in 1.5 client
- }
- - WorldPacket data(SMSG_FORCE_MOVE_ROOT, 8);
- - data << target->GetPackGUID();
- - data << uint32(0);
- - target->SendMessageToSet(&data, true);
- + if(!target->hasUnitState(UNIT_STAT_ON_VEHICLE))
- + {
- + WorldPacket data(SMSG_FORCE_MOVE_ROOT, 8);
- + data << target->GetPackGUID();
- + data << uint32(0);
- + target->SendMessageToSet(&data,true);
- + }
- // Summon the Naj'entus Spine GameObject on target if spell is Impaling Spine
- if(GetId() == 39837)
- @@ -3843,7 +3846,7 @@ void Aura::HandleAuraModStun(bool apply, bool Real)
- target->clearUnitState(UNIT_STAT_STUNNED);
- target->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED);
- - if(!target->hasUnitState(UNIT_STAT_ROOT)) // prevent allow move if have also root effect
- + if(!target->hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_ON_VEHICLE)) // prevent allow move if have also root effect
- {
- if(target->getVictim() && target->isAlive())
- target->SetTargetGuid(target->getVictim()->GetObjectGuid());
- @@ -4071,11 +4074,13 @@ void Aura::HandleAuraModRoot(bool apply, bool Real)
- if(target->GetTypeId() == TYPEID_PLAYER)
- {
- - WorldPacket data(SMSG_FORCE_MOVE_ROOT, 10);
- - data << target->GetPackGUID();
- - data << (uint32)2;
- - target->SendMessageToSet(&data, true);
- -
- + if(!target->hasUnitState(UNIT_STAT_ON_VEHICLE))
- + {
- + WorldPacket data(SMSG_FORCE_MOVE_ROOT, 10);
- + data << target->GetPackGUID();
- + data << (uint32)2;
- + target->SendMessageToSet(&data,true);
- + }
- //Clear unit movement flags
- ((Player*)target)->m_movementInfo.SetMovementFlags(MOVEFLAG_NONE);
- }
- @@ -4113,7 +4118,7 @@ void Aura::HandleAuraModRoot(bool apply, bool Real)
- target->clearUnitState(UNIT_STAT_ROOT);
- - if(!target->hasUnitState(UNIT_STAT_STUNNED)) // prevent allow move if have also stun effect
- + if(!target->hasUnitState(UNIT_STAT_STUNNED | UNIT_STAT_ON_VEHICLE)) // prevent allow move if have also stun effect
- {
- if(target->getVictim() && target->isAlive())
- target->SetTargetGuid(target->getVictim()->GetObjectGuid());
- @@ -7556,41 +7561,6 @@ void Aura::HandleArenaPreparation(bool apply, bool Real)
- GetTarget()->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PREPARATION);
- }
- -/**
- - * Such auras are applied from a caster(=player) to a vehicle.
- - * This has been verified using spell #49256
- - */
- -void Aura::HandleAuraControlVehicle(bool apply, bool Real)
- -{
- - if(!Real)
- - return;
- -
- - Unit* target = GetTarget();
- - if (target->GetTypeId() != TYPEID_UNIT || !((Creature*)target)->IsVehicle())
- - return;
- - Vehicle* vehicle = (Vehicle*)target;
- -
- - Unit *player = GetCaster();
- - if(!player || player->GetTypeId() != TYPEID_PLAYER)
- - return;
- -
- - if (apply)
- - {
- - if(Pet *pet = player->GetPet())
- - pet->Remove(PET_SAVE_AS_CURRENT);
- - ((Player*)player)->EnterVehicle(vehicle);
- - }
- - 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);
- - }
- -}
- -
- void Aura::HandleAuraOpenStable(bool apply, bool Real)
- {
- if(!Real || GetTarget()->GetTypeId() != TYPEID_PLAYER || !GetTarget()->IsInWorld())
- @@ -7779,6 +7749,48 @@ bool Aura::IsLastAuraOnHolder()
- return false;
- return true;
- }
- +/**
- + * Such auras are applied from a caster(=player) to a vehicle.
- + * This has been verified using spell #49256
- + */
- +void Aura::HandleAuraControlVehicle(bool apply, bool Real)
- +{
- + if(!Real)
- + return;
- +
- + Unit* target = GetTarget();
- + Unit* caster = GetCaster();
- + if (target->GetTypeId() != TYPEID_UNIT || !((Creature*)target)->IsVehicle())
- + return;
- + Vehicle* vehicle = (Vehicle*)target;
- +
- + 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(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
- + {
- + // some SPELL_AURA_CONTROL_VEHICLE auras have a dummy effect on the player - remove them
- + caster->RemoveAurasDueToSpell(GetId());
- + }
- +}
- SpellAuraHolder::SpellAuraHolder(SpellEntry const* spellproto, Unit *target, WorldObject *caster, Item *castItem) :
- m_target(target), m_caster_guid(0), m_castItemGuid(castItem?castItem->GetGUID():0),
- @@ -7794,7 +7806,7 @@ m_permanent(false), m_isRemovedOnShapeLost(true), m_deleted(false), m_in_use(0)
- else
- {
- // remove this assert when not unit casters will be supported
- - MANGOS_ASSERT(caster->GetObjectGuid().IsUnit())
- + MANGOS_ASSERT(caster->GetObjectGuid().IsUnit() || caster->GetObjectGuid().IsVehicle())
- m_caster_guid = caster->GetGUID();
- }
- diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp
- index 9190bd3..a6d2d8b 100644
- --- a/src/game/SpellEffects.cpp
- +++ b/src/game/SpellEffects.cpp
- @@ -57,6 +57,7 @@
- #include "GridNotifiers.h"
- #include "GridNotifiersImpl.h"
- #include "CellImpl.h"
- +#include "Vehicle.h"
- pEffect SpellEffects[TOTAL_SPELL_EFFECTS]=
- {
- @@ -147,9 +148,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
- @@ -4080,7 +4081,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);
- @@ -4109,7 +4110,7 @@ void Spell::EffectSummonType(SpellEffectIndex eff_idx)
- case SUMMON_PROP_GROUP_VEHICLE:
- {
- // TODO
- - // EffectSummonVehicle(i);
- + EffectSummonVehicle(eff_idx);
- break;
- }
- default:
- @@ -6795,13 +6796,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)
- @@ -8069,6 +8072,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, 1.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 9fb3f32..93cc0f6 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)
- @@ -335,6 +336,11 @@ void WorldSession::HandleCastSpellOpcode(WorldPacket& recvPacket)
- DEBUG_LOG("WORLD: got cast spell packet, spellId - %u, cast_count: %u, unk_flags %u, data length = %i",
- spellId, cast_count, unk_flags, (uint32)recvPacket.size());
- + // vehicle spells are handled by CMSG_PET_CAST_SPELL,
- + // but player is still able to cast own spells
- + if(!_player->GetCharmGuid().IsEmpty() && _player->GetCharmGuid() == _player->GetVehicleGUID())
- + mover = _player;
- +
- SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellId );
- if(!spellInfo)
- @@ -501,7 +507,7 @@ void WorldSession::HandlePetCancelAuraOpcode( WorldPacket& recvPacket)
- return;
- }
- - Creature* pet = GetPlayer()->GetMap()->GetAnyTypeCreature(guid);
- + Creature* pet=ObjectAccessor::GetAnyTypeCreature(*_player,guid);
- if (!pet)
- {
- @@ -586,22 +592,68 @@ void WorldSession::HandleSpellClick( WorldPacket & recv_data )
- ObjectGuid guid;
- recv_data >> guid;
- - if (_player->isInCombat()) // client prevent click and set different icon at combat state
- + Creature *unit = ObjectAccessor::GetAnyTypeCreature(*_player, guid);
- +
- + if(!_player->IsWithinDistInMap(unit, 10))
- return;
- - Creature *unit = _player->GetMap()->GetAnyTypeCreature(guid);
- - if (!unit || unit->isInCombat()) // client prevent click and set different icon at combat state
- + // cheater?
- + if(!unit->HasFlag(UNIT_NPC_FLAGS,UNIT_NPC_FLAG_SPELLCLICK))
- return;
- - SpellClickInfoMapBounds clickPair = sObjectMgr.GetSpellClickInfoMapBounds(unit->GetEntry());
- - for(SpellClickInfoMap::const_iterator itr = clickPair.first; itr != clickPair.second; ++itr)
- + 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->GetVehicle())
- + 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_MILLISECONDS);
- + 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/Traveller.h b/src/game/Traveller.h
- index 9f8c44d..eb308c3 100644
- --- a/src/game/Traveller.h
- +++ b/src/game/Traveller.h
- @@ -84,7 +84,7 @@ inline float Traveller<Creature>::Speed()
- template<>
- inline void Traveller<Creature>::Relocation(float x, float y, float z, float orientation)
- {
- - i_traveller.GetMap()->CreatureRelocation(&i_traveller, x, y, z, orientation);
- + i_traveller.SetPosition(x, y, z, orientation);
- }
- template<>
- diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp
- index b89042e..e01e62b 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"
- @@ -267,6 +268,12 @@ 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;
- + m_vehicle = NULL;
- + m_vehicleKit = NULL;
- }
- Unit::~Unit()
- @@ -281,6 +288,9 @@ Unit::~Unit()
- }
- }
- + if(m_vehicleKit)
- + delete m_vehicleKit;
- +
- if (m_charmInfo)
- delete m_charmInfo;
- @@ -432,6 +442,65 @@ void Unit::SendMonsterMoveWithSpeed(float x, float y, float z, uint32 transitTim
- SendMonsterMove(x, y, z, SPLINETYPE_NORMAL, flags, transitTime, player);
- }
- +void Unit::SendMonsterMoveTransport(Unit *vehicle)
- +{
- + WorldPacket data(SMSG_MONSTER_MOVE_TRANSPORT, 8+8+1+1+4*3+4+1+4+4+4+4+4*3);
- + data << GetPackGUID();
- + data << vehicle->GetPackGUID();
- + data << uint8(m_movementInfo.GetTransportSeat());
- + data << uint8(0); // new in 3.1
- + data << float(vehicle->GetPositionX());
- + data << float(vehicle->GetPositionY());
- + data << float(vehicle->GetPositionZ());
- + data << uint32(getMSTime());
- +
- + data << uint8(4); // unknown
- + data << float(0); // facing angle
- +
- + data << uint32(/*SPLINEFLAG_UNKNOWN5*/0);
- +
- + data << uint32(0); // Time in between points
- + data << uint32(1); // 1 single waypoint
- +
- + data << float(m_movementInfo.GetTransportPos()->x);
- + data << float(m_movementInfo.GetTransportPos()->y);
- + data << float(m_movementInfo.GetTransportPos()->z);
- +
- + SendMessageToSet(&data, true);
- +}
- +
- +bool Unit::SetPosition(float x, float y, float z, float orientation, bool teleport)
- +{
- + // prevent crash when a bad coord is sent by the client
- + if (!MaNGOS::IsValidMapCoord(x, y, z, orientation))
- + {
- + DEBUG_LOG("Unit::SetPosition(%f, %f, %f, %f, %d) .. bad coordinates for unit %d!", x, y, z, orientation, teleport, GetGUIDLow());
- + return false;
- + }
- +
- + bool turn = GetOrientation() != orientation;
- + bool relocate = (teleport || GetPositionX() != x || GetPositionY() != y || GetPositionZ() != z);
- +
- + if (turn)
- + RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_TURNING);
- +
- + if (relocate)
- + {
- + RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_MOVE);
- + if (GetTypeId() == TYPEID_PLAYER)
- + GetMap()->PlayerRelocation((Player*)this, x, y, z, orientation);
- + else
- + GetMap()->CreatureRelocation((Creature*)this, x, y, z, orientation);
- + }
- + else if (turn)
- + SetOrientation(orientation);
- +
- + if ((relocate || turn) && GetVehicleKit())
- + GetVehicleKit()->RelocatePassengers(x, y, z, orientation);
- +
- + return relocate || turn;
- +}
- +
- void Unit::SendHeartBeat(bool toSelf)
- {
- WorldPacket data(MSG_MOVE_HEARTBEAT, 64);
- @@ -5240,15 +5309,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)
- @@ -5405,6 +5469,38 @@ bool Unit::IsHostileTo(Unit const* unit) const
- return tester_faction->IsHostileTo(*target_faction);
- }
- +bool Unit::IsInPartyWith(Unit const *unit) const
- +{
- + if(this == unit)
- + return true;
- +
- + const Unit *u1 = GetCharmerOrOwnerOrSelf();
- + const Unit *u2 = unit->GetCharmerOrOwnerOrSelf();
- + if(u1 == u2)
- + return true;
- +
- + if(u1->GetTypeId() == TYPEID_PLAYER && u2->GetTypeId() == TYPEID_PLAYER)
- + return ((Player*)u1)->IsInSameGroupWith((Player*)u2);
- + else
- + return false;
- +}
- +
- +bool Unit::IsInRaidWith(Unit const *unit) const
- +{
- + if(this == unit)
- + return true;
- +
- + const Unit *u1 = GetCharmerOrOwnerOrSelf();
- + const Unit *u2 = unit->GetCharmerOrOwnerOrSelf();
- + if(u1 == u2)
- + return true;
- +
- + if(u1->GetTypeId() == TYPEID_PLAYER && u2->GetTypeId() == TYPEID_PLAYER)
- + return ((Player*)u1)->IsInSameRaidWith((Player*)u2);
- + else
- + return false;
- +}
- +
- bool Unit::IsFriendlyTo(Unit const* unit) const
- {
- // always friendly to self
- @@ -5556,6 +5652,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().IsEmpty())
- + return false;
- +
- // nobody can attack GM in GM-mode
- if(victim->GetTypeId()==TYPEID_PLAYER)
- {
- @@ -7506,7 +7610,7 @@ float Unit::GetPPMProcChance(uint32 WeaponSpeed, float PPM) const
- return WeaponSpeed * PPM / 600.0f; // result is chance in percents (probability = Speed_in_sec * (PPM / 60))
- }
- -void Unit::Mount(uint32 mount, uint32 spellId)
- +void Unit::Mount(uint32 mount, uint32 spellId, uint32 vehicleEntry)
- {
- if (!mount)
- return;
- @@ -7541,6 +7645,18 @@ void Unit::Mount(uint32 mount, uint32 spellId)
- }
- }
- }
- +
- + if (vehicleEntry)
- + {
- + if (CreateVehicleKit(vehicleEntry))
- + {
- + GetVehicleKit()->Reset();
- + WorldPacket data(SMSG_PLAYER_VEHICLE_DATA, 8+4);
- + data << GetPackGUID();
- + data << uint32(vehicleEntry);
- + SendMessageToSet(&data, true);
- + }
- + }
- }
- void Unit::Unmount()
- @@ -7563,6 +7679,17 @@ void Unit::Unmount()
- else
- ((Player*)this)->ResummonPetTemporaryUnSummonedIfAny();
- }
- +
- + if (GetTypeId() == TYPEID_PLAYER && GetVehicleKit())
- + {
- + // Send other players that we are no longer a vehicle
- + WorldPacket data(SMSG_PLAYER_VEHICLE_DATA, 8+4);
- + data << GetPackGUID();
- + data << uint32(0);
- + ((Player*)this)->SendMessageToSet(&data, true);
- +
- + RemoveVehicleKit();
- + }
- }
- void Unit::SetInCombatWith(Unit* enemy)
- @@ -8151,6 +8278,11 @@ void Unit::UpdateSpeed(UnitMoveType mtype, bool forced, float ratio)
- }
- 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;
- @@ -8343,10 +8475,13 @@ void Unit::SetDeathState(DeathState s)
- if(IsNonMeleeSpellCasted(false))
- InterruptNonMeleeSpells(false);
- +
- + ExitVehicle();
- }
- if (s == JUST_DIED)
- {
- + ExitVehicle();
- RemoveAllAurasOnDeath();
- RemoveGuardians();
- UnsummonAllTotems();
- @@ -8371,6 +8506,9 @@ void Unit::SetDeathState(DeathState s)
- // remove aurastates allowing special moves
- ClearAllReactives();
- ClearDiminishings();
- +
- + if (GetVehicleKit())
- + GetVehicleKit()->RemoveAllPassengers();
- }
- else if(s == JUST_ALIVED)
- {
- @@ -8593,7 +8731,8 @@ bool Unit::SelectHostileTarget()
- }
- // enter in evade mode in other case
- - ((Creature*)this)->AI()->EnterEvadeMode();
- + if(!((Creature*)this)->IsVehicle())
- + ((Creature*)this)->AI()->EnterEvadeMode();
- if (InstanceData* mapInstance = GetInstanceData())
- mapInstance->OnCreatureEvade((Creature*)this);
- @@ -8607,7 +8746,14 @@ bool Unit::SelectHostileTarget()
- int32 Unit::CalculateSpellDamage(Unit const* target, SpellEntry const* spellProto, SpellEffectIndex effect_index, int32 const* effBasePoints)
- {
- - 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;
- @@ -8672,7 +8818,14 @@ int32 Unit::CalculateSpellDamage(Unit const* target, SpellEntry const* spellProt
- 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;
- @@ -9077,15 +9230,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);
- }
- }
- @@ -9100,15 +9248,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)
- @@ -9144,20 +9287,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);
- + }
- }
- }
- }
- @@ -9173,15 +9315,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)
- @@ -9198,15 +9335,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);
- }
- }
- @@ -9220,15 +9352,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);
- }
- }
- @@ -9274,6 +9401,7 @@ void Unit::RemoveFromWorld()
- RemoveGuardians();
- RemoveAllGameObjects();
- RemoveAllDynObjects();
- + ExitVehicle();
- CleanupDeletedAuras();
- GetViewPoint().Event_RemovedFromWorld();
- }
- @@ -9283,6 +9411,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);
- @@ -9866,8 +9995,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)
- @@ -9896,8 +10029,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*/)
- @@ -10003,13 +10140,8 @@ void Unit::SetDisplayId(uint32 modelId)
- UpdateModelData();
- - if(GetTypeId() == TYPEID_UNIT && ((Creature*)this)->IsPet())
- - {
- - Pet *pet = ((Pet*)this);
- - if(!pet->isControlled())
- - return;
- - Unit *owner = GetOwner();
- - if(owner && (owner->GetTypeId() == TYPEID_PLAYER) && ((Player*)owner)->GetGroup())
- + if(Unit *owner = GetCharmerOrOwner()) {
- + if((owner->GetTypeId() == TYPEID_PLAYER) && ((Player*)owner)->GetGroup())
- ((Player*)owner)->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_PET_MODEL_ID);
- }
- }
- @@ -10213,16 +10345,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);
- }
- }
- }
- @@ -10393,13 +10523,14 @@ 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())
- if (MovementGenerator *movgen = c->GetMotionMaster()->top())
- movgen->Interrupt(*c);
- - GetMap()->CreatureRelocation((Creature*)this, x, y, z, orientation);
- + SetPosition(x, y, z, orientation, true);
- SendHeartBeat(false);
- @@ -10463,6 +10594,26 @@ struct SetPvPHelper
- bool state;
- };
- +void Unit::ChangeSeat(int8 seatId, bool next)
- +{
- + Vehicle *m_vehicle = ObjectAccessor::GetVehicle(GetVehicleGUID());
- +
- + if (!m_vehicle)
- + return;
- +
- + if (seatId < 0)
- + {
- + seatId = m_vehicle->GetNextEmptySeatNum(m_movementInfo.GetTransportSeat(), next);
- + if (seatId < 0)
- + return;
- + }
- + else if (seatId == m_movementInfo.GetTransportSeat() || !m_vehicle->HasEmptySeat(seatId))
- + return;
- +
- + m_vehicle->RemovePassenger(this);
- + EnterVehicle(m_vehicle, seatId);
- +}
- +
- void Unit::SetPvP( bool state )
- {
- if(state)
- @@ -10664,6 +10815,197 @@ void Unit::CleanupDeletedAuras()
- m_deletedAuras.clear();
- }
- +Unit* Unit::GetVehicleBase()
- +{
- + return m_vehicle ? m_vehicle->GetBase() : NULL;
- +}
- +
- +bool Unit::CreateVehicleKit(uint32 vehicleEntry)
- +{
- + VehicleEntry const *vehInfo = sVehicleStore.LookupEntry(vehicleEntry);
- +
- + if (!vehInfo)
- + return false;
- +
- + m_vehicleKit = new VehicleKit(this, vehInfo);
- + m_updateFlag |= UPDATEFLAG_VEHICLE;
- + return true;
- +}
- +
- +void Unit::RemoveVehicleKit()
- +{
- + if (!m_vehicleKit)
- + return;
- +
- + m_vehicleKit->RemoveAllPassengers();
- + delete m_vehicleKit;
- +
- + m_vehicleKit = NULL;
- +
- + m_updateFlag &= ~UPDATEFLAG_VEHICLE;
- + RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK);
- + RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_PLAYER_VEHICLE);
- +}
- +
- +void Unit::EnterVehicle(VehicleKit *vehicle, int8 seatId)
- +{
- + if(!isAlive() || GetVehicleKit() == vehicle)
- + return;
- +
- + if (m_vehicle)
- + {
- + if (m_vehicle == vehicle)
- + {
- + if (seatId >= 0)
- + ChangeSeat(seatId);
- +
- + return;
- + }
- + else
- + ExitVehicle();
- + }
- +
- + InterruptNonMeleeSpells(false);
- + RemoveSpellsCausingAura(SPELL_AURA_MOUNTED);
- +
- + if (!vehicle->AddPassenger(this, seatId))
- + return;
- +
- + m_vehicle = vehicle;
- +
- + if (Pet *pet = GetPet())
- + pet->Remove(PET_SAVE_AS_CURRENT);
- +
- + if (GetTypeId() == TYPEID_PLAYER)
- + {
- + Player* player = (Player*)this;
- +
- + if (BattleGround *bg = player->GetBattleGround())
- + bg->EventPlayerDroppedFlag(player);
- +
- + WorldPacket data(SMSG_BREAK_TARGET, 8);
- + data << vehicle->GetBase()->GetPackGUID();
- + player->GetSession()->SendPacket(&data);
- + }
- +}
- +
- +void Unit::EnterVehicle(Vehicle *vehicle, int8 seat_id, bool force)
- +{
- + ExitVehicle();
- +
- + RemoveSpellsCausingAura(SPELL_AURA_MOUNTED);
- +
- + 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_movementInfo.SetTransportData(v->GetGUID(),
- + (veSeat->m_attachmentOffsetX + v->GetObjectBoundingRadius()) * GetFloatValue(OBJECT_FIELD_SCALE_X),
- + (veSeat->m_attachmentOffsetY + v->GetObjectBoundingRadius()) * GetFloatValue(OBJECT_FIELD_SCALE_X),
- + (veSeat->m_attachmentOffsetZ + v->GetObjectBoundingRadius()) * GetFloatValue(OBJECT_FIELD_SCALE_X),
- + veSeat->m_passengerYaw, v->GetCreationTime(), seat_id, NULL, 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 << GetPackGUID();
- + data << v->GetPackGUID();
- + data << uint8(seat_id);
- + data << uint8(0);
- + data << v->GetPositionX() << v->GetPositionY() << v->GetPositionZ();
- + data << uint32(getMSTime());
- +
- + data << uint8(4);
- + data << float(0);
- +
- + data << uint32(SPLINEFLAG_UNKNOWN5);
- +
- + data << uint32(0);
- + data << uint32(1);
- + data << m_movementInfo.GetTransportPos()->x;
- + data << m_movementInfo.GetTransportPos()->y;
- + data << m_movementInfo.GetTransportPos()->z;
- + SendMessageToSet(&data, true);
- +
- + v->AddPassenger(this, seat_id, force);
- +}
- +
- +void Unit::ExitVehicle()
- +{
- + if(m_vehicleKit && m_vehicleKit->GetBase() == this)
- + {
- + m_vehicleKit->RemoveAllPassengers();
- + }
- +
- + if(uint64 vehicleGUID = GetVehicleGUID())
- + {
- + float v_size = 0.0f;
- + if(Vehicle *vehicle = ObjectAccessor::GetVehicle(vehicleGUID))
- + {
- + if(m_movementInfo.GetVehicleSeatFlags() & SF_MAIN_RIDER)
- + {
- + if(vehicle->GetVehicleFlags() & VF_DESPAWN_AT_LEAVE)
- + {
- + vehicle->SetSpawnDuration(1);
- + }
- + }
- + v_size = vehicle->GetObjectBoundingRadius();
- + vehicle->RemovePassenger(this);
- + }
- + SetVehicleGUID(0);
- +
- + clearUnitState(UNIT_STAT_ON_VEHICLE);
- +
- + if(GetTypeId() == TYPEID_PLAYER)
- + {
- + ((Player*)this)->ResummonPetTemporaryUnSummonedIfAny();
- + ((Player*)this)->m_movementInfo.RemoveMovementFlag(MOVEFLAG_ROOT);
- + }
- +
- + float x = GetPositionX();
- + float y = GetPositionY();
- + float z = GetPositionZ() + 1.0f;
- + GetClosePoint(x, y, z, 1.0f + v_size);
- + SendMonsterMove(x, y, z, SPLINETYPE_NORMAL, SPLINEFLAG_WALKMODE, 0);
- + }
- + else
- + {
- + if(!m_vehicle)
- + return;
- +
- + Unit* pVehicleBase = m_vehicle->GetBase();
- +
- + float angle = pVehicleBase->GetOrientation();
- +
- + m_vehicle->RemovePassenger(this);
- + m_vehicle = NULL;
- +
- + if (GetTypeId() == TYPEID_PLAYER)
- + ((Player*)this)->ResummonPetTemporaryUnSummonedIfAny();
- +
- + float x = GetPositionX();
- + float y = GetPositionY();
- + float z = GetPositionZ() + 1.0f;
- + GetClosePoint(x, y, z, 1.0f);
- + SendMonsterMove(x, y, z, SPLINETYPE_NORMAL, SPLINEFLAG_WALKMODE, 0);
- + }
- +}
- +
- bool Unit::CheckAndIncreaseCastCounter()
- {
- uint32 maxCasts = sWorld.getConfig(CONFIG_UINT32_MAX_SPELL_CASTS_IN_CHAIN);
- diff --git a/src/game/Unit.h b/src/game/Unit.h
- index c114cff..a6bf1df 100644
- --- a/src/game/Unit.h
- +++ b/src/game/Unit.h
- @@ -303,6 +303,8 @@ class Item;
- class Pet;
- class PetAura;
- class Totem;
- +class Vehicle;
- +class VehicleKit;
- struct SpellImmune
- {
- @@ -440,24 +442,25 @@ enum UnitState
- UNIT_STAT_FOLLOW_MOVE = 0x00010000,
- UNIT_STAT_FLEEING = 0x00020000, // FleeMovementGenerator/TimedFleeingMovementGenerator active/onstack
- UNIT_STAT_FLEEING_MOVE = 0x00040000,
- + UNIT_STAT_ON_VEHICLE = 0x00080000,
- // 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_TAXI_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,
- // AI disabled by some reason
- UNIT_STAT_LOST_CONTROL = UNIT_STAT_FLEEING | UNIT_STAT_CONTROLLED,
- @@ -614,6 +617,7 @@ enum NPCFlags
- UNIT_NPC_FLAG_STABLEMASTER = 0x00400000, // 100%
- UNIT_NPC_FLAG_GUILD_BANKER = 0x00800000, // cause client to send 997 opcode
- UNIT_NPC_FLAG_SPELLCLICK = 0x01000000, // cause client to send 1015 opcode (spell click), dynamic, set at loading and don't must be set in DB
- + UNIT_NPC_FLAG_PLAYER_VEHICLE = 0x02000000, // players with mounts that have vehicle data should have it set
- UNIT_NPC_FLAG_GUARD = 0x10000000 // custom flag for guards
- };
- @@ -750,7 +754,7 @@ class MovementInfo
- {
- public:
- MovementInfo() : moveFlags(MOVEFLAG_NONE), moveFlags2(MOVEFLAG2_NONE), time(0),
- - t_time(0), t_seat(-1), t_time2(0), s_pitch(0.0f), fallTime(0), u_unk1(0.0f) {}
- + t_time(0), t_seat(-1), t_seatInfo(NULL), t_time2(0), s_pitch(0.0f), fallTime(0), u_unk1(0.0f) {}
- // Read/Write methods
- void Read(ByteBuffer &data);
- @@ -766,7 +770,7 @@ class MovementInfo
- // Position manipulations
- Position const *GetPos() const { return &pos; }
- - void SetTransportData(ObjectGuid guid, float x, float y, float z, float o, uint32 time, int8 seat)
- + void SetTransportData(ObjectGuid guid, float x, float y, float z, float o, uint32 time, int8 seat, VehicleSeatEntry const* seatInfo = NULL, uint32 vehicle_flags = 0)
- {
- t_guid = guid;
- t_pos.x = x;
- @@ -775,6 +779,8 @@ class MovementInfo
- t_pos.o = o;
- t_time = time;
- t_seat = seat;
- + t_seatInfo = seatInfo;
- + t_vehicle_flags = vehicle_flags;
- }
- void ClearTransportData()
- {
- @@ -785,11 +791,16 @@ class MovementInfo
- t_pos.o = 0.0f;
- t_time = 0;
- t_seat = -1;
- + t_seatInfo = NULL;
- + t_vehicle_flags = 0;
- }
- ObjectGuid const& GetTransportGuid() const { return t_guid; }
- Position const *GetTransportPos() const { return &t_pos; }
- int8 GetTransportSeat() const { return t_seat; }
- uint32 GetTransportTime() const { return t_time; }
- + int32 GetTransportDBCSeat() const { return t_seatInfo ? t_seatInfo->m_ID : 0; }
- + uint32 GetVehicleSeatFlags() const { return t_seatInfo ? t_seatInfo->m_flags : 0; }
- + uint32 GetVehicleFlags() const { return t_vehicle_flags; }
- uint32 GetFallTime() const { return fallTime; }
- void ChangePosition(float x, float y, float z, float o) { pos.x = x; pos.y = y; pos.z = z; pos.o = o; }
- void UpdateTime(uint32 _time) { time = _time; }
- @@ -812,7 +823,9 @@ class MovementInfo
- Position t_pos;
- uint32 t_time;
- int8 t_seat;
- + VehicleSeatEntry const* t_seatInfo;
- uint32 t_time2;
- + uint32 t_vehicle_flags;
- // swimming and flying
- float s_pitch;
- // last fall time
- @@ -1270,6 +1283,8 @@ class MANGOS_DLL_SPEC Unit : public WorldObject
- bool IsHostileTo(Unit const* unit) const;
- bool IsHostileToPlayers() const;
- bool IsFriendlyTo(Unit const* unit) const;
- + bool IsInRaidWith(Unit const* unit) const;
- + bool IsInPartyWith(Unit const* unit) const;
- bool IsNeutralToAll() const;
- bool IsContestedGuard() const
- {
- @@ -1299,7 +1314,7 @@ class MANGOS_DLL_SPEC Unit : public WorldObject
- bool IsMounted() const { return HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_MOUNT ); }
- uint32 GetMountID() const { return GetUInt32Value(UNIT_FIELD_MOUNTDISPLAYID); }
- - void Mount(uint32 mount, uint32 spellId = 0);
- + void Mount(uint32 mount, uint32 spellId = 0, uint32 vehicleEntry = 0);
- void Unmount();
- uint16 GetMaxSkillValueForLevel(Unit const* target = NULL) const { return (target ? GetLevelForTarget(target) : getLevel()) * 5; }
- @@ -1411,6 +1426,10 @@ class MANGOS_DLL_SPEC Unit : public WorldObject
- return m_spellAuraHolders.find(spellId) != m_spellAuraHolders.end();
- }
- + 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); }
- @@ -1464,6 +1483,9 @@ class MANGOS_DLL_SPEC Unit : public WorldObject
- template<typename PathElem, typename PathNode>
- void SendMonsterMoveByPath(Path<PathElem,PathNode> const& path, uint32 start, uint32 end, SplineFlags flags);
- + void SendMonsterMoveTransport(Unit *vehicle);
- +
- + virtual bool SetPosition(float x, float y, float z, float orientation, bool teleport = false);
- void SendHighestThreatUpdate(HostileReference* pHostileReference);
- void SendThreatClear();
- @@ -1512,12 +1534,13 @@ class MANGOS_DLL_SPEC Unit : public WorldObject
- Unit* GetCharm() const;
- void Uncharm();
- Unit* GetCharmerOrOwner() const { return !GetCharmerGuid().IsEmpty() ? GetCharmer() : GetOwner(); }
- - Unit* GetCharmerOrOwnerOrSelf()
- + Unit* GetCharmOrPet() const { return !GetCharmGuid().IsEmpty() ? GetCharm() : (Unit*)GetPet(); }
- + Unit* GetCharmerOrOwnerOrSelf() const
- {
- if(Unit* u = GetCharmerOrOwner())
- return u;
- - return this;
- + return (Unit*)this;
- }
- bool IsCharmerOrOwnerPlayerOrPlayerItself() const;
- Player* GetCharmerOrOwnerPlayerOrPlayerItself();
- @@ -1924,6 +1947,19 @@ class MANGOS_DLL_SPEC Unit : public WorldObject
- // Movement info
- MovementInfo m_movementInfo;
- + // vehicle system
- + void EnterVehicle(VehicleKit *vehicle, int8 seatId = -1);
- + void EnterVehicle(Vehicle *vehicle, int8 seat_id, bool force = false);
- + void ExitVehicle();
- + void ChangeSeat(int8 seatId, bool next = true);
- + uint64 GetVehicleGUID() { return m_vehicleGUID; }
- + void SetVehicleGUID(uint64 guid) { m_vehicleGUID = guid; }
- + VehicleKit* GetVehicle() { return m_vehicle; }
- + VehicleKit* GetVehicleKit() { return m_vehicleKit; }
- + Unit* GetVehicleBase();
- + bool CreateVehicleKit(uint32 vehicleEntry);
- + void RemoveVehicleKit();
- +
- protected:
- explicit Unit ();
- @@ -1973,6 +2009,11 @@ class MANGOS_DLL_SPEC Unit : public WorldObject
- uint32 m_reactiveTimer[MAX_REACTIVE];
- uint32 m_regenTimer;
- uint32 m_lastManaUseTimer;
- + uint64 m_auraUpdateMask;
- +
- + uint64 m_vehicleGUID;
- + VehicleKit* m_vehicle;
- + VehicleKit* m_vehicleKit;
- private:
- void CleanupDeletedAuras();
- diff --git a/src/game/Vehicle.cpp b/src/game/Vehicle.cpp
- index b12ae82..7e37751 100644
- --- a/src/game/Vehicle.cpp
- +++ b/src/game/Vehicle.cpp
- @@ -18,12 +18,238 @@
- #include "Common.h"
- #include "Log.h"
- -#include "ObjectMgr.h"
- #include "Vehicle.h"
- #include "Unit.h"
- #include "Util.h"
- +#include "WorldPacket.h"
- +#include "Transports.h"
- +#include "InstanceData.h"
- -Vehicle::Vehicle() : Creature(CREATURE_SUBTYPE_VEHICLE), m_vehicleId(0)
- +VehicleKit::VehicleKit(Unit* base, VehicleEntry const* vehicleInfo) : m_vehicleInfo(vehicleInfo), m_pBase(base), m_uiNumFreeSeats(0)
- +{
- + for (uint32 i = 0; i < MAX_VEHICLE_SEAT; ++i)
- + {
- + uint32 seatId = m_vehicleInfo->m_seatID[i];
- +
- + if (!seatId)
- + continue;
- +
- + if (VehicleSeatEntry const *veSeat = sVehicleSeatStore.LookupEntry(seatId))
- + {
- + m_Seats.insert(std::make_pair(i, VehicleSeat(veSeat)));
- +
- + if (veSeat->IsUsable())
- + ++m_uiNumFreeSeats;
- + }
- + }
- +}
- +
- +VehicleKit::~VehicleKit()
- +{
- +}
- +
- +void VehicleKit::RemoveAllPassengers()
- +{
- + for (SeatMap::iterator itr = m_Seats.begin(); itr != m_Seats.end(); ++itr)
- + {
- + if (Unit *passenger = itr->second.passenger)
- + passenger->ExitVehicle();
- + }
- +}
- +
- +bool VehicleKit::HasEmptySeat(int8 seatId) const
- +{
- + SeatMap::const_iterator seat = m_Seats.find(seatId);
- +
- + if (seat == m_Seats.end())
- + return false;
- +
- + return !seat->second.passenger;
- +}
- +
- +Unit *VehicleKit::GetPassenger(int8 seatId) const
- +{
- + SeatMap::const_iterator seat = m_Seats.find(seatId);
- +
- + if (seat == m_Seats.end())
- + return NULL;
- +
- + return seat->second.passenger;
- +}
- +
- +int8 VehicleKit::GetNextEmptySeat(int8 seatId, bool next) const
- +{
- + SeatMap::const_iterator seat = m_Seats.find(seatId);
- +
- + if (seat == m_Seats.end())
- + return -1;
- +
- + while (seat->second.passenger || !seat->second.seatInfo->IsUsable())
- + {
- + if (next)
- + {
- + ++seat;
- + if (seat == m_Seats.end())
- + seat = m_Seats.begin();
- + }
- + else
- + {
- + if (seat == m_Seats.begin())
- + seat = m_Seats.end();
- + --seat;
- + }
- +
- + if (seat->first == seatId)
- + return -1; // no available seat
- + }
- +
- + return seat->first;
- +}
- +
- +bool VehicleKit::AddPassenger(Unit *unit, int8 seatId)
- +{
- + SeatMap::iterator seat;
- +
- + if (seatId < 0) // no specific seat requirement
- + {
- + for (seat = m_Seats.begin(); seat != m_Seats.end(); ++seat)
- + {
- + if (!seat->second.passenger && seat->second.seatInfo->IsUsable())
- + break;
- + }
- +
- + if (seat == m_Seats.end()) // no available seat
- + return false;
- + }
- + else
- + {
- + seat = m_Seats.find(seatId);
- +
- + if (seat == m_Seats.end())
- + return false;
- +
- + if (seat->second.passenger)
- + seat->second.passenger->ExitVehicle();
- + }
- +
- + seat->second.passenger = unit;
- +
- + if (seat->second.seatInfo->IsUsable())
- + {
- + MANGOS_ASSERT(m_uiNumFreeSeats);
- + --m_uiNumFreeSeats;
- +
- + if (!m_uiNumFreeSeats)
- + {
- + if (m_pBase->GetTypeId() == TYPEID_PLAYER)
- + m_pBase->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_PLAYER_VEHICLE);
- + else
- + m_pBase->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK);
- + }
- + }
- +
- + unit->addUnitState(UNIT_STAT_ON_VEHICLE);
- +
- + VehicleSeatEntry const *veSeat = seat->second.seatInfo;
- +
- + unit->m_movementInfo.AddMovementFlag(MOVEFLAG_ONTRANSPORT);
- + unit->m_movementInfo.SetTransportData(m_pBase->GetGUID(),
- + veSeat->m_attachmentOffsetX, veSeat->m_attachmentOffsetY, veSeat->m_attachmentOffsetZ,
- + veSeat->m_passengerYaw, getMSTime(), seat->first, veSeat);
- +
- + if (unit->GetTypeId() == TYPEID_PLAYER)
- + {
- + //((Player*)unit)->GetCamera().SetView(m_pBase);
- +
- + WorldPacket data(SMSG_FORCE_MOVE_ROOT, 8+4);
- + data << unit->GetPackGUID();
- + data << uint32((unit->m_movementInfo.GetVehicleSeatFlags() & SEAT_FLAG_CAN_CAST) ? 2 : 0);
- + unit->SendMessageToSet(&data, true);
- + }
- +
- + unit->SendMonsterMoveTransport(m_pBase);
- +
- + if (m_pBase->GetTypeId() == TYPEID_UNIT)
- + RelocatePassengers(m_pBase->GetPositionX(), m_pBase->GetPositionY(), m_pBase->GetPositionZ(), m_pBase->GetOrientation());
- +
- + return true;
- +}
- +
- +void VehicleKit::RemovePassenger(Unit *unit)
- +{
- + SeatMap::iterator seat;
- + for (seat = m_Seats.begin(); seat != m_Seats.end(); ++seat)
- + {
- + if (seat->second.passenger == unit)
- + break;
- + }
- +
- + if (seat == m_Seats.end())
- + return;
- +
- + seat->second.passenger = NULL;
- +
- + if (seat->second.seatInfo->IsUsable())
- + {
- + if (!m_uiNumFreeSeats)
- + {
- + if (m_pBase->GetTypeId() == TYPEID_PLAYER)
- + m_pBase->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_PLAYER_VEHICLE);
- + else
- + m_pBase->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK);
- + }
- +
- + ++m_uiNumFreeSeats;
- + }
- +
- + unit->clearUnitState(UNIT_STAT_ON_VEHICLE);
- +
- + unit->m_movementInfo.ClearTransportData();
- + unit->m_movementInfo.RemoveMovementFlag(MOVEFLAG_ONTRANSPORT);
- +
- + if (unit->GetTypeId() == TYPEID_PLAYER)
- + {
- + //((Player*)unit)->GetCamera().ResetView();
- +
- + WorldPacket data(SMSG_FORCE_MOVE_UNROOT, 8+4);
- + data << unit->GetPackGUID();
- + data << uint32(0);
- + unit->SendMessageToSet(&data, true);
- + }
- +}
- +
- +void VehicleKit::Reset()
- +{
- + if (m_pBase->GetTypeId() == TYPEID_PLAYER)
- + {
- + if (m_uiNumFreeSeats)
- + m_pBase->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_PLAYER_VEHICLE);
- + }
- + else
- + {
- + if (m_uiNumFreeSeats)
- + m_pBase->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK);
- + }
- +}
- +
- +void VehicleKit::RelocatePassengers(float x, float y, float z, float ang)
- +{
- + for (SeatMap::const_iterator itr = m_Seats.begin(); itr != m_Seats.end(); ++itr)
- + {
- + if (Unit *passenger = itr->second.passenger)
- + {
- + float px = x + passenger->m_movementInfo.GetTransportPos()->x;
- + float py = y + passenger->m_movementInfo.GetTransportPos()->y;
- + float pz = z + passenger->m_movementInfo.GetTransportPos()->z;
- + float po = ang + passenger->m_movementInfo.GetTransportPos()->o;
- +
- + passenger->SetPosition(px, py, pz, po);
- + }
- + }
- +}
- +
- +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);
- }
- @@ -51,45 +277,735 @@ void Vehicle::RemoveFromWorld()
- Unit::RemoveFromWorld();
- }
- +void Vehicle::Respawn()
- +{
- + Creature::Respawn();
- + InstallAllAccessories();
- +}
- +
- 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);
- + 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();
- + LoadCreatureAddon();
- - 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;
- +
- + if(spellInfo->powerType == POWER_MANA)
- + break;
- +
- + 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;
- - CreatureInfo const *ci = GetCreatureInfo();
- - setFaction(team == ALLIANCE ? ci->faction_A : ci->faction_H);
- + m_vehicleId = vehicleid;
- + m_vehicleInfo = vehicleInfo;
- - SelectLevel(ci);
- + // 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;
- +}
- +
- +int8 Vehicle::GetNextEmptySeatNum(int8 seatId, bool next) const
- +{
- + SeatMap::const_iterator seat = m_Seats.find(seatId);
- + if(seat == m_Seats.end()) return -1;
- + while(seat->second.passenger || !seat->second.seatInfo->IsUsable())
- + {
- + if(next)
- + {
- + ++seat;
- + if(seat == m_Seats.end())
- + seat = m_Seats.begin();
- + }
- + else
- + {
- + if(seat == m_Seats.begin())
- + seat = m_Seats.end();
- + --seat;
- + }
- + if(seat->first == seatId)
- + return -1; // no available seat
- + }
- + return seat->first;
- +}
- +
- +bool Vehicle::HasEmptySeat(int8 seatId) const
- +{
- + SeatMap::const_iterator seat = m_Seats.find(seatId);
- + if(seat == m_Seats.end()) return false;
- + return !seat->second.passenger;
- +}
- +
- +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(vehicle->GetPassengerSeat(this), SEAT_VEHICLE_FREE);
- + else
- + vehicle->ChangeSeatFlag(vehicle->GetPassengerSeat(this), SEAT_VEHICLE_FULL);
- + }
- + }
- +}
- +
- void Vehicle::Dismiss()
- {
- + RemoveAllPassengers();
- SendObjectDeSpawnAnim(GetGUID());
- CombatStop();
- AddObjectToRemoveList();
- }
- +
- +void Vehicle::RellocatePassengers(Map *map)
- +{
- + if (m_Seats.empty())
- + return;
- +
- + 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;
- + MANGOS_ASSERT(passengers);
- +
- + float xx = GetPositionX() + passengers->m_movementInfo.GetTransportPos()->x;
- + float yy = GetPositionY() + passengers->m_movementInfo.GetTransportPos()->y;
- + float zz = GetPositionZ() + passengers->m_movementInfo.GetTransportPos()->z;
- + //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;
- + MANGOS_ASSERT(passengers);
- +
- + float xx = GetPositionX() + passengers->m_movementInfo.GetTransportPos()->x;
- + float yy = GetPositionY() + passengers->m_movementInfo.GetTransportPos()->y;
- + float zz = GetPositionZ() + passengers->m_movementInfo.GetTransportPos()->z;
- + //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);
- + }
- + }
- +}
- +
- +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());
- + unit->m_movementInfo.AddMovementFlag(MOVEFLAG_ONTRANSPORT);
- + unit->m_movementInfo.AddMovementFlag(MOVEFLAG_ROOT);
- +
- + 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 << 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)->SetMover(this);
- + ((Player*)unit)->SetClientControl(this, 1);
- + ((Player*)unit)->GetCamera().SetView(this);
- + }
- + if(CanFly() || HasAuraType(SPELL_AURA_FLY) || HasAuraType(SPELL_AURA_MOD_FLIGHT_SPEED))
- + {
- + WorldPacket data3(SMSG_MOVE_SET_CAN_FLY, 12);
- + data3 << 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);
- +
- + BuildVehicleActionBar((Player*)unit);
- + }
- +
- + if(!(GetVehicleFlags() & VF_FACTION))
- + setFaction(unit->getFaction());
- +
- + if(GetVehicleFlags() & VF_CANT_MOVE)
- + {
- + WorldPacket data2(SMSG_FORCE_MOVE_ROOT, 10);
- + data2 << 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(unit->GetTypeId() == TYPEID_PLAYER)
- + {
- + ((Player*)unit)->SetMover(unit);
- + ((Player*)unit)->SetClientControl(unit, 1);
- + ((Player*)unit)->GetCamera().SetView(unit);
- + }
- +
- + if(seat->second.vs_flags & SF_MAIN_RIDER)
- + {
- + RemoveSpellsCausingAura(SPELL_AURA_CONTROL_VEHICLE);
- + if(unit->GetTypeId() == TYPEID_PLAYER)
- + {
- + ((Player*)unit)->RemovePetActionBar();
- +
- + if(((Player*)unit)->GetGroup())
- + ((Player*)unit)->SetGroupUpdateFlag(GROUP_UPDATE_VEHICLE);
- + }
- + unit->SetCharm(NULL);
- + SetCharmerGuid(ObjectGuid());
- + 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)
- + {
- + if(seat->second.vs_flags & SF_CAN_CAST)
- + {
- + WorldPacket data0(SMSG_FORCE_MOVE_UNROOT, 10);
- + data0 << unit->GetPackGUID();
- + data0 << (uint32)(2); // can rotate
- + unit->SendMessageToSet(&data0,true);
- + }
- + else
- + {
- + WorldPacket data1(SMSG_FORCE_MOVE_UNROOT, 10);
- + data1 << unit->GetPackGUID();
- + data1 << (uint32)(0); // cannot rotate
- + unit->SendMessageToSet(&data1,true);
- + }
- + }
- + unit->m_movementInfo.RemoveMovementFlag(MOVEFLAG_ONTRANSPORT);
- + unit->m_movementInfo.RemoveMovementFlag(MOVEFLAG_ROOT);
- +
- + // only for flyable vehicles
- + if (unit->m_movementInfo.HasMovementFlag(MOVEFLAG_FLYING))
- + ((Player*)unit)->CastSpell(unit, 45472, true); // Parachute
- +
- + seat->second.passenger = NULL;
- + seat->second.flags = SEAT_FREE;
- + unit->m_movementInfo.ClearTransportData();
- +
- + 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_MILLISECONDS : 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_MILLISECONDS : 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()
- +{
- + if(!GetMap())
- + return;
- +
- + CreatureDataAddon const *cainfo = GetCreatureAddon();
- + if(!cainfo || !cainfo->passengers)
- + return;
- + for (CreatureDataAddonPassengers const* cPassanger = cainfo->passengers; cPassanger->seat_idx != -1; ++cPassanger)
- + {
- + // Continue if seat already taken
- + if(GetPassenger(cPassanger->seat_idx))
- + continue;
- +
- + uint32 guid = 0;
- + bool isVehicle = false;
- + // Set guid and check whatever it is
- + if(cPassanger->guid != 0)
- + guid = cPassanger->guid;
- + else
- + {
- + CreatureDataAddon const* passAddon;
- + passAddon = ObjectMgr::GetCreatureTemplateAddon(cPassanger->entry);
- + if(passAddon && passAddon->vehicle_id != 0)
- + isVehicle = true;
- + else
- + guid = sObjectMgr.GenerateLowGuid(HIGHGUID_UNIT);
- + }
- + // Create it
- + Creature *pPassenger = new Creature;
- + if(!isVehicle)
- + {
- + uint32 entry = cPassanger->entry;
- + if(entry == 0)
- + {
- + CreatureData const* data = sObjectMgr.GetCreatureData(guid);
- + if(!data)
- + continue;
- + entry = data->id;
- + }
- +
- + if(!pPassenger->Create(guid, GetMap(), GetPhaseMask(), entry, 0))
- + continue;
- + pPassenger->LoadFromDB(guid, GetMap());
- + pPassenger->Relocate(GetPositionX(), GetPositionY(), GetPositionZ());
- + GetMap()->Add(pPassenger);
- + pPassenger->AIM_Initialize();
- + }
- + else
- + pPassenger = (Creature*)SummonVehicle(cPassanger->entry, GetPositionX(), GetPositionY(), GetPositionZ(), 0);
- + // Enter vehicle...
- + pPassenger->EnterVehicle(this, cPassanger->seat_idx, true);
- + // ...and send update. Without this, client wont show this new creature/vehicle...
- + pPassenger->SendHeartBeat(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())
- + ((Vehicle*)passenger)->Dismiss();
- + RemoveAllPassengers();
- +}
- +
- +uint8 Vehicle::GetPassengerSeat(Unit *passenger) const
- +{
- + if(passenger)
- + for(SeatMap::const_iterator itr = m_Seats.begin(); itr != m_Seats.end(); itr++)
- + if(itr->second.passenger == passenger)
- + return itr->first;
- + return -1;
- +}
- diff --git a/src/game/Vehicle.h b/src/game/Vehicle.h
- index c191c09..e92c02d 100644
- --- a/src/game/Vehicle.h
- +++ b/src/game/Vehicle.h
- @@ -23,6 +23,58 @@
- #include "ObjectGuid.h"
- #include "Creature.h"
- #include "Unit.h"
- +#include "ObjectMgr.h"
- +
- +struct VehicleSeat
- +{
- + VehicleSeat(VehicleSeatEntry const *pSeatInfo = NULL) : seatInfo(pSeatInfo), passenger(NULL) {}
- +
- + VehicleSeatEntry const *seatInfo;
- + Unit* passenger;
- + uint8 flags;
- + uint32 vs_flags;
- +};
- +
- +typedef std::map<int8, VehicleSeat> SeatMap;
- +
- +class VehicleKit
- +{
- + public:
- +
- + explicit VehicleKit(Unit* base, VehicleEntry const* vehicleInfo);
- + ~VehicleKit();
- +
- + void Reset();
- +
- + bool HasEmptySeat(int8 seatId) const;
- + Unit *GetPassenger(int8 seatId) const;
- + int8 GetNextEmptySeat(int8 seatId, bool next) const;
- + bool AddPassenger(Unit *passenger, int8 seatId = -1);
- + void RemovePassenger(Unit *passenger);
- + void RelocatePassengers(float x, float y, float z, float ang);
- + void RemoveAllPassengers();
- +
- + uint32 GetVehicleId() const { return m_vehicleInfo->m_ID; }
- + VehicleEntry const* GetVehicleInfo() const { return m_vehicleInfo; }
- + Unit* GetBase() { return m_pBase; }
- +
- + private:
- +
- + SeatMap m_Seats;
- + uint32 m_uiNumFreeSeats;
- + VehicleEntry const *m_vehicleInfo;
- + Unit* m_pBase;
- +};
- +
- +enum PowerType
- +{
- + POWER_TYPE_PYRITE = 41,
- + POWER_TYPE_STEAM = 61
- +};
- +
- +#define MAX_SEAT 8
- +
- +typedef std::map<int8, VehicleSeat> SeatMap;
- class Vehicle : public Creature
- {
- @@ -33,18 +85,60 @@ 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 Respawn();
- void SetDeathState(DeathState s); // overwrite virtual Creature::SetDeathState and Unit::SetDeathState
- +
- + void RegeneratePower(Powers power);
- +
- void Update(uint32 diff); // overwrite virtual Creature::Update and Unit::Update
- 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(void);
- + int8 GetTotalSeatsCount() { return m_Seats.size(); }
- + bool HasEmptySeat(int8 seatId) const;
- + int8 GetNextEmptySeatNum(int8 seatId, bool next) const;
- 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;
- + uint8 GetPassengerSeat(Unit *passenger) 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;
- 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 5a58d06..d98cb0c 100644
- --- a/src/game/World.cpp
- +++ b/src/game/World.cpp
- @@ -1241,6 +1241,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 e6d6825..17b4f8b 100644
- --- a/src/game/WorldSession.h
- +++ b/src/game/WorldSession.h
- @@ -430,6 +430,13 @@ class MANGOS_DLL_SPEC WorldSession
- void HandleSetActiveMoverOpcode(WorldPacket &recv_data);
- void HandleMoveNotActiveMoverOpcode(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 HandleEnterPlayerVehicle(WorldPacket &recv_data);
- + void HandleEjectPasenger(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 6d80714..b9e69db 100644
- --- a/src/game/debugcmds.cpp
- +++ b/src/game/debugcmds.cpp
- @@ -614,7 +614,8 @@ bool ChatHandler::HandleDebugSpawnVehicleCommand(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;
- @@ -634,6 +635,7 @@ bool ChatHandler::HandleDebugSpawnVehicleCommand(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 a797cb5..5c8cde4 100644
- --- a/src/shared/Database/SQLStorage.cpp
- +++ b/src/shared/Database/SQLStorage.cpp
- @@ -25,11 +25,11 @@ extern DatabasePostgre WorldDatabase;
- extern DatabaseMysql WorldDatabase;
- #endif
- -const char CreatureInfosrcfmt[]="iiiiiiiiiisssiiiiiiiiiiifffiffiifiiiiiiiiiiffiiiiiiiiiiiiiiiiiiisiiffliiiiiiiliiiis";
- -const char CreatureInfodstfmt[]="iiiiiiiiiisssiiiiiiiiiiifffiffiifiiiiiiiiiiffiiiiiiiiiiiiiiiiiiisiiffliiiiiiiliiiii";
- -const char CreatureDataAddonInfofmt[]="iiiiiis";
- +const char CreatureInfosrcfmt[]="iiiiiiiiiisssiiiiiiiiiiifffiffiifiiiiiiiiiiffiiiiiiiiiiiiiiiiiiiisiiffliiiiiiiliiiis";
- +const char CreatureInfodstfmt[]="iiiiiiiiiisssiiiiiiiiiiifffiffiifiiiiiiiiiiffiiiiiiiiiiiiiiiiiiiisiiffliiiiiiiliiiii";
- +const char CreatureDataAddonInfofmt[]="iiiiiiiss";
- const char CreatureModelfmt[]="iffbii";
- -const char CreatureInfoAddonInfofmt[]="iiiiiis";
- +const char CreatureInfoAddonInfofmt[]="iiiiiiiss";
- const char EquipmentInfofmt[]="iiii";
- const char GameObjectInfosrcfmt[]="iiissssiifiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiis";
- const char GameObjectInfodstfmt[]="iiissssiifiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii";
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement