Guest User

Vehicle for mangos 10818

a guest
Dec 16th, 2010
121
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Diff 64.00 KB | None | 0 0
  1. diff --git a/src/game/AggressorAI.cpp b/src/game/AggressorAI.cpp
  2. index 615fd3f..4391b7b 100644
  3. --- a/src/game/AggressorAI.cpp
  4. +++ b/src/game/AggressorAI.cpp
  5. @@ -103,7 +103,7 @@ void AggressorAI::EnterEvadeMode()
  6.          //i_tracker.Reset(TIME_INTERVAL_LOOK);
  7.      }
  8.  
  9. -    if (!m_creature->isCharmed())
  10. +    if (!m_creature->isCharmed() && (!m_creature->GetVehicle() || !m_creature->GetVehicleGUID()))
  11.      {
  12.          m_creature->RemoveAllAuras();
  13.  
  14. diff --git a/src/game/BattleGroundMgr.cpp b/src/game/BattleGroundMgr.cpp
  15. index fc1c96e..e9fd8f0 100644
  16. --- a/src/game/BattleGroundMgr.cpp
  17. +++ b/src/game/BattleGroundMgr.cpp
  18. @@ -1348,11 +1348,15 @@ void BattleGroundMgr::BuildPvpLogDataPacket(WorldPacket *data, BattleGround *bg)
  19.                  *data << (uint32)0x00000001;                // count of next fields
  20.                  *data << (uint32)((BattleGroundEYScore*)itr->second)->FlagCaptures;         // flag captures
  21.                  break;
  22. +            case BATTLEGROUND_SA:
  23. +                *data << (uint32)0x00000002;                // count of next fields
  24. +                *data << (uint32)((BattleGroundSAScore*)itr->second)->DemolishersDestroyed; // demolishers destroyed
  25. +                *data << (uint32)((BattleGroundSAScore*)itr->second)->GatesDestroyed;       // gates destroyed
  26. +                break;
  27.              case BATTLEGROUND_NA:
  28.              case BATTLEGROUND_BE:
  29.              case BATTLEGROUND_AA:
  30.              case BATTLEGROUND_RL:
  31. -            case BATTLEGROUND_SA:                           // wotlk
  32.              case BATTLEGROUND_DS:                           // wotlk
  33.              case BATTLEGROUND_RV:                           // wotlk
  34.              case BATTLEGROUND_IC:                           // wotlk
  35. diff --git a/src/game/BattleGroundSA.h b/src/game/BattleGroundSA.h
  36. index 31a3ffa..9324999 100644
  37. --- a/src/game/BattleGroundSA.h
  38. +++ b/src/game/BattleGroundSA.h
  39. @@ -24,8 +24,10 @@ class BattleGround;
  40.  class BattleGroundSAScore : public BattleGroundScore
  41.  {
  42.      public:
  43. -        BattleGroundSAScore() {};
  44. +        BattleGroundSAScore(): DemolishersDestroyed(0), GatesDestroyed(0) {};
  45.          virtual ~BattleGroundSAScore() {};
  46. +        uint32 DemolishersDestroyed;
  47. +        uint32 GatesDestroyed;
  48.  };
  49.  
  50.  class BattleGroundSA : public BattleGround
  51. diff --git a/src/game/Chat.cpp b/src/game/Chat.cpp
  52. index 3539a2a..213d2cd 100644
  53. --- a/src/game/Chat.cpp
  54. +++ b/src/game/Chat.cpp
  55. @@ -528,6 +528,8 @@ ChatCommand * ChatHandler::getCommandTable()
  56.          { "spell_scripts",               SEC_ADMINISTRATOR, true,  &ChatHandler::HandleReloadSpellScriptsCommand,            "", NULL },
  57.          { "spell_target_position",       SEC_ADMINISTRATOR, true,  &ChatHandler::HandleReloadSpellTargetPositionCommand,     "", NULL },
  58.          { "spell_threats",               SEC_ADMINISTRATOR, true,  &ChatHandler::HandleReloadSpellThreatsCommand,            "", NULL },
  59. +        { "vehicle_data",                SEC_ADMINISTRATOR, true,  &ChatHandler::HandleReloadVehicleDataCommand,             "", NULL },
  60. +        { "vehicle_seat_data",           SEC_ADMINISTRATOR, true,  &ChatHandler::HandleReloadVehicleSeatDataCommand,         "", NULL },
  61.  
  62.          { NULL,                          0,                 false, NULL,                                                     "", NULL }
  63.      };
  64. @@ -2040,7 +2042,7 @@ Creature* ChatHandler::getSelectedCreature()
  65.      if(!m_session)
  66.          return NULL;
  67.  
  68. -    return m_session->GetPlayer()->GetMap()->GetAnyTypeCreature(m_session->GetPlayer()->GetSelectionGuid());
  69. +    return ObjectAccessor::GetAnyTypeCreature(*m_session->GetPlayer(),m_session->GetPlayer()->GetSelectionGuid());
  70.  }
  71.  
  72.  /**
  73. diff --git a/src/game/Chat.h b/src/game/Chat.h
  74. index 5b56d0b..c1ead9e 100644
  75. --- a/src/game/Chat.h
  76. +++ b/src/game/Chat.h
  77. @@ -446,6 +446,8 @@ class ChatHandler
  78.          bool HandleReloadSpellTargetPositionCommand(char* args);
  79.          bool HandleReloadSpellThreatsCommand(char* args);
  80.          bool HandleReloadSpellPetAurasCommand(char* args);
  81. +        bool HandleReloadVehicleDataCommand(char* args);
  82. +        bool HandleReloadVehicleSeatDataCommand(char* args);
  83.  
  84.          bool HandleResetAchievementsCommand(char* args);
  85.          bool HandleResetAllCommand(char* args);
  86. diff --git a/src/game/Creature.cpp b/src/game/Creature.cpp
  87. index 75d314b..77a2277 100644
  88. --- a/src/game/Creature.cpp
  89. +++ b/src/game/Creature.cpp
  90. @@ -42,6 +42,7 @@
  91.  #include "GridNotifiers.h"
  92.  #include "GridNotifiersImpl.h"
  93.  #include "CellImpl.h"
  94. +#include "Vehicle.h"
  95.  
  96.  // apply implementation of the singletons
  97.  #include "Policies/SingletonImp.h"
  98. @@ -1408,6 +1409,8 @@ void Creature::SetDeathState(DeathState s)
  99.              return;
  100.  
  101.          Unit::SetDeathState(CORPSE);
  102. +        if(IsVehicle())
  103. +            ((Vehicle*)this)->Die();
  104.      }
  105.  
  106.      if (s == JUST_ALIVED)
  107. @@ -1536,6 +1539,32 @@ bool Creature::IsImmuneToSpellEffect(SpellEntry const* spellInfo, SpellEffectInd
  108.              return true;
  109.      }
  110.  
  111. +    // Heal immunity
  112. +    if (IsVehicle() && !(((Vehicle*)this)->GetVehicleFlags() & VF_CAN_BE_HEALED))
  113. +    {
  114. +        switch(spellInfo->Effect[index])
  115. +        {
  116. +            case SPELL_EFFECT_APPLY_AURA:
  117. +                switch(spellInfo->EffectApplyAuraName[index])
  118. +                {
  119. +                    case SPELL_AURA_PERIODIC_HEAL:
  120. +                    case SPELL_AURA_OBS_MOD_HEALTH:
  121. +                    case SPELL_AURA_PERIODIC_HEALTH_FUNNEL:
  122. +                    case SPELL_AURA_MOD_REGEN:
  123. +                        return true;
  124. +                    default: break;
  125. +                }
  126. +                break;
  127. +            case SPELL_EFFECT_HEAL:
  128. +            case SPELL_EFFECT_HEAL_MAX_HEALTH:
  129. +            // NOTE : this too?
  130. +            case SPELL_EFFECT_HEAL_MECHANICAL:
  131. +            case SPELL_EFFECT_HEAL_PCT:
  132. +                return true;
  133. +            default : break;
  134. +        }
  135. +    }
  136. +
  137.      return Unit::IsImmuneToSpellEffect(spellInfo, index);
  138.  }
  139.  
  140. @@ -1768,7 +1797,7 @@ bool Creature::CanInitiateAttack()
  141.      if (hasUnitState(UNIT_STAT_STUNNED | UNIT_STAT_DIED))
  142.          return false;
  143.  
  144. -    if (HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE))
  145. +    if (HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_PLAYER_CONTROLLED))
  146.          return false;
  147.  
  148.      if (isPassiveToHostile())
  149. @@ -2050,6 +2079,29 @@ bool Creature::IsInEvadeMode() const
  150.      return !i_motionMaster.empty() && i_motionMaster.GetCurrentMovementGeneratorType() == HOME_MOTION_TYPE;
  151.  }
  152.  
  153. +float Creature::GetBaseSpeed() const
  154. +{
  155. +    if( IsPet() )
  156. +    {
  157. +        switch( ((Pet*)this)->getPetType() )
  158. +        {
  159. +            case SUMMON_PET:
  160. +            case HUNTER_PET:
  161. +            {
  162. +                //fixed speed fur hunter (and summon!?) pets
  163. +                return 1.15f;
  164. +            }
  165. +            case GUARDIAN_PET:
  166. +            case MINI_PET:
  167. +            {
  168. +                //speed of CreatureInfo for guardian- and minipets
  169. +                break;
  170. +            }
  171. +        }
  172. +    }
  173. +    return m_creatureInfo->speed_run;
  174. +}
  175. +
  176.  bool Creature::HasSpell(uint32 spellID) const
  177.  {
  178.      uint8 i;
  179. diff --git a/src/game/Creature.h b/src/game/Creature.h
  180. index 70200da..26b6a9d 100644
  181. --- a/src/game/Creature.h
  182. +++ b/src/game/Creature.h
  183. @@ -118,6 +118,7 @@ struct CreatureInfo
  184.      int32   resistance6;
  185.      uint32  spells[CREATURE_MAX_SPELLS];
  186.      uint32  PetSpellDataId;
  187. +    uint32  VehicleEntry;
  188.      uint32  mingold;
  189.      uint32  maxgold;
  190.      char const* AIName;
  191. @@ -197,6 +198,16 @@ struct CreatureDataAddonAura
  192.      SpellEffectIndex effect_idx;
  193.  };
  194.  
  195. +struct CreatureDataAddonPassengers
  196. +{
  197. +    CreatureDataAddonPassengers() : entry(0), guid(0), seat_idx(-1) {}
  198. +
  199. +    uint32 entry;
  200. +    uint32 guid;
  201. +    int8 seat_idx;
  202. +};
  203. +
  204. +// from `creature_addon` table
  205.  // from `creature_addon` and `creature_template_addon`tables
  206.  struct CreatureDataAddon
  207.  {
  208. @@ -207,6 +218,8 @@ struct CreatureDataAddon
  209.      uint8  pvp_state;                                       // UnitPVPStateFlags
  210.      uint32 emote;
  211.      uint32 splineFlags;
  212. +    uint32 vehicle_id;
  213. +    CreatureDataAddonPassengers const* passengers;          // loaded as char* "entry1 seatid1 entry2 seatid2 ... "
  214.      CreatureDataAddonAura const* auras;                     // loaded as char* "spell1 eff1 spell2 eff2 ... "
  215.  };
  216.  
  217. @@ -576,6 +589,7 @@ class MANGOS_DLL_SPEC Creature : public Unit
  218.  
  219.          MovementGeneratorType GetDefaultMovementType() const { return m_defaultMovementType; }
  220.          void SetDefaultMovementType(MovementGeneratorType mgt) { m_defaultMovementType = mgt; }
  221. +        float GetBaseSpeed() const;
  222.  
  223.          // for use only in LoadHelper, Map::Add Map::CreatureCellRelocation
  224.          Cell const& GetCurrentCell() const { return m_currentCell; }
  225. diff --git a/src/game/CreatureAI.cpp b/src/game/CreatureAI.cpp
  226. index da481e2..00dced4 100644
  227. --- a/src/game/CreatureAI.cpp
  228. +++ b/src/game/CreatureAI.cpp
  229. @@ -27,6 +27,10 @@ CreatureAI::~CreatureAI()
  230.  
  231.  void CreatureAI::AttackedBy( Unit* attacker )
  232.  {
  233. +    // vehicle dont have threat list, so this is unnecessary, because it calls move chase
  234. +    if(m_creature->IsVehicle())
  235. +        return;
  236. +
  237.      if(!m_creature->getVictim())
  238.          AttackStart(attacker);
  239.  }
  240. diff --git a/src/game/CreatureAISelector.cpp b/src/game/CreatureAISelector.cpp
  241. index 4ddfa91..640f890 100644
  242. --- a/src/game/CreatureAISelector.cpp
  243. +++ b/src/game/CreatureAISelector.cpp
  244. @@ -47,7 +47,7 @@ namespace FactorySelector
  245.          // excplicit check for isControlled() and owner type to allow guardian, mini-pets and pets controlled by NPCs to be scripted by EventAI
  246.          Unit *owner=NULL;
  247.          if ((creature->IsPet() && ((Pet*)creature)->isControlled() &&
  248. -            ((owner=creature->GetOwner()) && owner->GetTypeId()==TYPEID_PLAYER)) || creature->isCharmed())
  249. +            ((owner=creature->GetOwner()) && owner->GetTypeId()==TYPEID_PLAYER)) || (creature->isCharmed() && !creature->IsVehicle()))
  250.              ai_factory = ai_registry.GetRegistryItem("PetAI");
  251.          else if (creature->IsTotem())
  252.              ai_factory = ai_registry.GetRegistryItem("TotemAI");
  253. diff --git a/src/game/CreatureEventAI.cpp b/src/game/CreatureEventAI.cpp
  254. index a3856be..77a5d78 100644
  255. --- a/src/game/CreatureEventAI.cpp
  256. +++ b/src/game/CreatureEventAI.cpp
  257. @@ -913,6 +913,7 @@ void CreatureEventAI::JustReachedHome()
  258.  
  259.  void CreatureEventAI::EnterEvadeMode()
  260.  {
  261. +    m_creature->ExitVehicle();
  262.      m_creature->RemoveAllAuras();
  263.      m_creature->DeleteThreatList();
  264.      m_creature->CombatStop(true);
  265. diff --git a/src/game/DBCEnums.h b/src/game/DBCEnums.h
  266. index f0a7bac..d39089a 100644
  267. --- a/src/game/DBCEnums.h
  268. +++ b/src/game/DBCEnums.h
  269. @@ -441,6 +441,12 @@ enum VehicleFlags
  270.  
  271.  enum VehicleSeatFlags
  272.  {
  273. +    SEAT_FREE                       = 0x01,                 // free seat
  274. +    SEAT_FULL                       = 0x02,                 // seat occupied by player/creature
  275. +    // special cases
  276. +    SEAT_VEHICLE_FREE               = 0x04,                 // seat occupied by vehicle, but that vehicle is free
  277. +    SEAT_VEHICLE_FULL               = 0x08,                 // seat occupied by vehicle and that vehicle is full too
  278. +
  279.      SEAT_FLAG_HIDE_PASSENGER        = 0x00000200,           // Passenger is hidden
  280.      SEAT_FLAG_CAN_CONTROL           = 0x00000800,           // Lua_UnitInVehicleControlSeat
  281.      SEAT_FLAG_CAN_ATTACK            = 0x00004000,           // Can attack, cast spells and use items from vehicle?
  282. diff --git a/src/game/DBCStructure.h b/src/game/DBCStructure.h
  283. index 2d3fb78..d01d1f3 100644
  284. --- a/src/game/DBCStructure.h
  285. +++ b/src/game/DBCStructure.h
  286. @@ -1762,7 +1762,7 @@ struct VehicleEntry
  287.      uint32  m_uiLocomotionType;                             // 34
  288.      float   m_msslTrgtImpactTexRadius;                      // 35
  289.      uint32  m_uiSeatIndicatorType;                          // 36
  290. -                                                            // 37, new in 3.1 - powerType
  291. +    uint32  m_powerType;                                    // 37, new in 3.1 - powerType
  292.                                                              // 38, new in 3.1
  293.                                                              // 39, new in 3.1
  294.  };
  295. @@ -1816,6 +1816,8 @@ struct VehicleSeatEntry
  296.      int32   m_uiSkin;                                       // 44
  297.      uint32  m_flagsB;                                       // 45
  298.                                                              // 46-57 added in 3.1, floats mostly
  299. +
  300. +    bool IsUsable() const { return m_flags & SEAT_FLAG_USABLE; }
  301.  };
  302.  
  303.  struct WMOAreaTableEntry
  304. diff --git a/src/game/DBCfmt.h b/src/game/DBCfmt.h
  305. index c26acd8..ef6a443 100644
  306. --- a/src/game/DBCfmt.h
  307. +++ b/src/game/DBCfmt.h
  308. @@ -106,7 +106,7 @@ const char TaxiPathEntryfmt[]="niii";
  309.  const char TaxiPathNodeEntryfmt[]="diiifffiiii";
  310.  const char TeamContributionPointsfmt[]="df";
  311.  const char TotemCategoryEntryfmt[]="nxxxxxxxxxxxxxxxxxii";
  312. -const char VehicleEntryfmt[]="niffffiiiiiiiifffffffffffffffssssfifixxx";
  313. +const char VehicleEntryfmt[]="niffffiiiiiiiifffffffffffffffssssfifiixx";
  314.  const char VehicleSeatEntryfmt[]="niiffffffffffiiiiiifffffffiiifffiiiiiiiffiiiiixxxxxxxxxxxx";
  315.  const char WMOAreaTableEntryfmt[]="niiixxxxxiixxxxxxxxxxxxxxxxx";
  316.  const char WorldMapAreaEntryfmt[]="xinxffffixx";
  317. diff --git a/src/game/GameObject.cpp b/src/game/GameObject.cpp
  318. index a1c836b..1413a77 100644
  319. --- a/src/game/GameObject.cpp
  320. +++ b/src/game/GameObject.cpp
  321. @@ -1628,6 +1628,18 @@ float GameObject::GetObjectBoundingRadius() const
  322.      return DEFAULT_WORLD_OBJECT_SIZE;
  323.  }
  324.  
  325. +void GameObject::DealSiegeDamage(uint32 damage)
  326. +{
  327. +    m_actualHealth -= damage;
  328. +
  329. +    // TODO : there are a lot of thinghts to do here
  330. +    if(m_actualHealth < 0)
  331. +    {
  332. +        m_actualHealth = GetGOInfo()->destructibleBuilding.intactNumHits;
  333. +        SetLootState(GO_JUST_DEACTIVATED);
  334. +    }
  335. +}
  336. +
  337.  bool GameObject::IsInSkillupList(Player* player) const
  338.  {
  339.      return m_SkillupSet.find(player->GetObjectGuid()) != m_SkillupSet.end();
  340. diff --git a/src/game/GameObject.h b/src/game/GameObject.h
  341. index b6e69f7..3750f09 100644
  342. --- a/src/game/GameObject.h
  343. +++ b/src/game/GameObject.h
  344. @@ -704,12 +704,14 @@ class MANGOS_DLL_SPEC GameObject : public WorldObject
  345.          GridReference<GameObject> &GetGridRef() { return m_gridRef; }
  346.  
  347.          uint64 GetRotation() const { return m_rotation; }
  348. +        void DealSiegeDamage(uint32 damage);
  349.      protected:
  350.          uint32      m_spellId;
  351.          time_t      m_respawnTime;                          // (secs) time of next respawn (or despawn if GO have owner()),
  352.          uint32      m_respawnDelayTime;                     // (secs) if 0 then current GO state no dependent from timer
  353.          LootState   m_lootState;
  354.          bool        m_spawnedByDefault;
  355. +        int32       m_actualHealth;                         // current health state
  356.          time_t      m_cooldownTime;                         // used as internal reaction delay time store (not state change reaction).
  357.                                                              // For traps this: spell casting cooldown, for doors/buttons: reset time.
  358.  
  359. diff --git a/src/game/GridNotifiers.cpp b/src/game/GridNotifiers.cpp
  360. index ba2eb06..ac6a654 100644
  361. --- a/src/game/GridNotifiers.cpp
  362. +++ b/src/game/GridNotifiers.cpp
  363. @@ -93,7 +93,10 @@ VisibleNotifier::Notify()
  364.      {
  365.          // target aura duration for caster show only if target exist at caster client
  366.          if ((*vItr) != &player && (*vItr)->isType(TYPEMASK_UNIT))
  367. +        {
  368.              player.SendAurasForTarget((Unit*)(*vItr));
  369. +            ((Unit*)(*vItr))->SendHeartBeat(false);
  370. +        }
  371.  
  372.          // non finished movements show to player
  373.          if ((*vItr)->GetTypeId()==TYPEID_UNIT && ((Creature*)(*vItr))->isAlive())
  374. diff --git a/src/game/Group.h b/src/game/Group.h
  375. index c1a87cf..d809916 100644
  376. --- a/src/game/Group.h
  377. +++ b/src/game/Group.h
  378. @@ -135,7 +135,8 @@ enum GroupUpdateFlags
  379.      GROUP_UPDATE_FLAG_PET_AURAS         = 0x00040000,       // uint64 mask, for each bit set uint32 spellid + uint8 unk, pet auras...
  380.      GROUP_UPDATE_FLAG_VEHICLE_SEAT      = 0x00080000,       // uint32 vehicle_seat_id (index from VehicleSeat.dbc)
  381.      GROUP_UPDATE_PET                    = 0x0007FC00,       // all pet flags
  382. -    GROUP_UPDATE_FULL                   = 0x0007FFFF,       // all known flags
  383. +    GROUP_UPDATE_VEHICLE                = 0x000FFC00,       // all vehicle flags
  384. +    GROUP_UPDATE_FULL                   = 0x000FFFFF,       // all known flags
  385.  };
  386.  
  387.  #define GROUP_UPDATE_FLAGS_COUNT          20
  388. diff --git a/src/game/GroupHandler.cpp b/src/game/GroupHandler.cpp
  389. index d340b1a..27d6b77 100644
  390. --- a/src/game/GroupHandler.cpp
  391. +++ b/src/game/GroupHandler.cpp
  392. @@ -28,6 +28,7 @@
  393.  #include "Group.h"
  394.  #include "SocialMgr.h"
  395.  #include "Util.h"
  396. +#include "Vehicle.h"
  397.  
  398.  /* differeces from off:
  399.      -you can uninvite yourself - is is useful
  400. @@ -719,7 +720,7 @@ void WorldSession::BuildPartyMemberStatsChangedPacket(Player *player, WorldPacke
  401.          }
  402.      }
  403.  
  404. -    Pet *pet = player->GetPet();
  405. +    Unit *pet = player->GetCharmOrPet();
  406.      if (mask & GROUP_UPDATE_FLAG_PET_GUID)
  407.          *data << (pet ? pet->GetObjectGuid() : ObjectGuid());
  408.  
  409. @@ -797,6 +798,11 @@ void WorldSession::BuildPartyMemberStatsChangedPacket(Player *player, WorldPacke
  410.          else
  411.              *data << uint64(0);
  412.      }
  413. +
  414. +    if (mask & GROUP_UPDATE_FLAG_VEHICLE_SEAT)
  415. +    {
  416. +        *data << (uint32) player->m_movementInfo.GetTransportDBCSeat();
  417. +    }
  418.  }
  419.  
  420.  /*this procedure handles clients CMSG_REQUEST_PARTY_MEMBER_STATS request*/
  421. @@ -818,7 +824,7 @@ void WorldSession::HandleRequestPartyMemberStatsOpcode( WorldPacket &recv_data )
  422.          return;
  423.      }
  424.  
  425. -    Pet *pet = player->GetPet();
  426. +    Unit *pet = player->GetCharmOrPet();
  427.  
  428.      WorldPacket data(SMSG_PARTY_MEMBER_STATS_FULL, 4+2+2+2+1+2*6+8+1+8);
  429.      data << uint8(0);                                       // only for SMSG_PARTY_MEMBER_STATS_FULL, probably arena/bg related
  430. @@ -826,7 +832,7 @@ void WorldSession::HandleRequestPartyMemberStatsOpcode( WorldPacket &recv_data )
  431.  
  432.      uint32 mask1 = 0x00040BFF;                              // common mask, real flags used 0x000040BFF
  433.      if(pet)
  434. -        mask1 = 0x7FFFFFFF;                                 // for hunters and other classes with pets
  435. +        mask1 = 0xFFFFFFFF;                                 // for hunters and other classes with pets
  436.  
  437.      Powers powerType = player->getPowerType();
  438.      data << uint32(mask1);                                  // group update mask
  439. @@ -880,6 +886,7 @@ void WorldSession::HandleRequestPartyMemberStatsOpcode( WorldPacket &recv_data )
  440.              }
  441.          }
  442.          data.put<uint64>(petMaskPos, petauramask);          // GROUP_UPDATE_FLAG_PET_AURAS
  443. +        data << (uint32) player->m_movementInfo.GetTransportDBCSeat();
  444.      }
  445.      else
  446.      {
  447. diff --git a/src/game/Level3.cpp b/src/game/Level3.cpp
  448. index bad1513..60e71ae 100644
  449. --- a/src/game/Level3.cpp
  450. +++ b/src/game/Level3.cpp
  451. @@ -74,6 +74,9 @@ bool ChatHandler::HandleReloadAllCommand(char* /*args*/)
  452.      HandleReloadReservedNameCommand((char*)"");
  453.      HandleReloadMangosStringCommand((char*)"");
  454.      HandleReloadGameTeleCommand((char*)"");
  455. +
  456. +    HandleReloadVehicleDataCommand((char*)"");
  457. +    HandleReloadVehicleSeatDataCommand((char*)"");
  458.      return true;
  459.  }
  460.  
  461. @@ -921,6 +924,22 @@ bool ChatHandler::HandleReloadMailLevelRewardCommand(char* /*args*/)
  462.      return true;
  463.  }
  464.  
  465. +bool ChatHandler::HandleReloadVehicleDataCommand(char* /*args*/)
  466. +{
  467. +    sLog.outString( "Re-Loading `vehicle_data` Table!" );
  468. +    sObjectMgr.LoadVehicleData();
  469. +    SendGlobalSysMessage("DB table `vehicle_data` reloaded.");
  470. +    return true;
  471. +}
  472. +
  473. +bool ChatHandler::HandleReloadVehicleSeatDataCommand(char* /*args*/)
  474. +{
  475. +    sLog.outString( "Re-Loading `vehicle_seat_data` Table!" );
  476. +    sObjectMgr.LoadVehicleSeatData();
  477. +    SendGlobalSysMessage("DB table `vehicle_seat_data` reloaded.");
  478. +    return true;
  479. +}
  480. +
  481.  bool ChatHandler::HandleLoadScriptsCommand(char* args)
  482.  {
  483.      if (!LoadScriptingModule(args))
  484. diff --git a/src/game/Map.h b/src/game/Map.h
  485. index 3f1ee0f..82f59ed 100644
  486. --- a/src/game/Map.h
  487. +++ b/src/game/Map.h
  488. @@ -39,7 +39,6 @@
  489.  #include <bitset>
  490.  #include <list>
  491.  
  492. -class Creature;
  493.  class Unit;
  494.  class WorldPacket;
  495.  class InstanceData;
  496. diff --git a/src/game/MovementHandler.cpp b/src/game/MovementHandler.cpp
  497. index b4f632a..7774b60 100644
  498. --- a/src/game/MovementHandler.cpp
  499. +++ b/src/game/MovementHandler.cpp
  500. @@ -44,6 +44,9 @@ void WorldSession::HandleMoveWorldportAckOpcode()
  501.      if(!GetPlayer()->IsBeingTeleportedFar())
  502.          return;
  503.  
  504. +    if (_player->GetVehicleKit())
  505. +        _player->GetVehicleKit()->RemoveAllPassengers();
  506. +
  507.      // get the teleport destination
  508.      WorldLocation &loc = GetPlayer()->GetTeleportDest();
  509.  
  510. @@ -262,6 +265,8 @@ void WorldSession::HandleMovementOpcodes( WorldPacket & recv_data )
  511.      data << mover->GetPackGUID();             // write guid
  512.      movementInfo.Write(data);                               // write data
  513.      mover->SendMessageToSetExcept(&data, _player);
  514. +    mover->m_movementInfo = movementInfo;
  515. +    mover->SetPosition(movementInfo.GetPos()->x, movementInfo.GetPos()->y, movementInfo.GetPos()->z, movementInfo.GetPos()->o);
  516.  }
  517.  
  518.  void WorldSession::HandleForceSpeedChangeAckOpcodes(WorldPacket &recv_data)
  519. @@ -348,12 +353,10 @@ void WorldSession::HandleSetActiveMoverOpcode(WorldPacket &recv_data)
  520.      ObjectGuid guid;
  521.      recv_data >> guid;
  522.  
  523. -    if(_player->GetMover()->GetObjectGuid() != guid)
  524. -    {
  525. -        sLog.outError("HandleSetActiveMoverOpcode: incorrect mover guid: mover is %s and should be %s",
  526. -            _player->GetMover()->GetGuidStr().c_str(), guid.GetString().c_str());
  527. -        return;
  528. -    }
  529. +    if (Unit *pMover = ObjectAccessor::GetUnit(*GetPlayer(), guid))
  530. +        GetPlayer()->SetMover(pMover);
  531. +    else
  532. +        GetPlayer()->SetMover(NULL);
  533.  }
  534.  
  535.  void WorldSession::HandleMoveNotActiveMoverOpcode(WorldPacket &recv_data)
  536. @@ -359,23 +364,13 @@ void WorldSession::HandleMoveNotActiveMoverOpcode(WorldPacket &recv_data)
  537.      DEBUG_LOG("WORLD: Recvd CMSG_MOVE_NOT_ACTIVE_MOVER");
  538.      recv_data.hexlike();
  539.  
  540. -    ObjectGuid old_mover_guid;
  541. +    ObjectGuid guid;
  542.      MovementInfo mi;
  543.  
  544. -    recv_data >> old_mover_guid.ReadAsPacked();
  545. +    recv_data >> guid.ReadAsPacked();
  546.      recv_data >> mi;
  547.  
  548. -    if(_player->GetMover()->GetObjectGuid() == old_mover_guid)
  549. -    {
  550. -        sLog.outError("HandleMoveNotActiveMover: incorrect mover guid: mover is %s and should be %s instead of %s",
  551. -            _player->GetMover()->GetGuidStr().c_str(),
  552. -            _player->GetGuidStr().c_str(),
  553. -            old_mover_guid.GetString().c_str());
  554. -        recv_data.rpos(recv_data.wpos());                   // prevent warnings spam
  555. -        return;
  556. -    }
  557. -
  558. -    _player->m_movementInfo = mi;
  559. +    GetPlayer()->m_movementInfo = mi;
  560.  }
  561.  
  562.  void WorldSession::HandleDismissControlledVehicle(WorldPacket &recv_data)
  563. @@ -386,18 +379,171 @@ void WorldSession::HandleDismissControlledVehicle(WorldPacket &recv_data)
  564.      recv_data >> guid.ReadAsPacked();
  565.      recv_data >> mi;
  566.  
  567. -    ObjectGuid vehicleGUID = _player->GetCharmGuid();
  568. +    ObjectGuid vehicleGUID = _player->GetVehicleGUID();
  569.  
  570.      if (vehicleGUID.IsEmpty())                              // something wrong here...
  571.          return;
  572.  
  573.      _player->m_movementInfo = mi;
  574.  
  575. -    // using charm guid, because we don't have vehicle guid...
  576. -    if(Vehicle *vehicle = _player->GetMap()->GetVehicle(vehicleGUID))
  577. +    if(Vehicle *vehicle = ObjectAccessor::GetVehicle(vehicleGUID))
  578. +    {
  579. +        if(vehicle->GetVehicleFlags() & VF_DESPAWN_AT_LEAVE)
  580. +            vehicle->Dismiss();
  581. +        else
  582. +            _player->ExitVehicle();
  583. +    }
  584. +}
  585. +
  586. +void WorldSession::HandleRequestVehicleExit(WorldPacket &recv_data)
  587. +{
  588. +    sLog.outDebug("WORLD: Recvd CMSG_REQUEST_VEHICLE_EXIT");
  589. +    recv_data.hexlike();
  590. +
  591. +    GetPlayer()->ExitVehicle();
  592. +}
  593. +
  594. +void WorldSession::HandleRequestVehiclePrevSeat(WorldPacket &recv_data)
  595. +{
  596. +    DEBUG_LOG("WORLD: Recvd CMSG_REQUEST_VEHICLE_PREV_SEAT");
  597. +    recv_data.hexlike();
  598. +
  599. +    GetPlayer()->ChangeSeat(-1, false);
  600. +}
  601. +
  602. +void WorldSession::HandleRequestVehicleNextSeat(WorldPacket &recv_data)
  603. +{
  604. +    DEBUG_LOG("WORLD: Recvd CMSG_REQUEST_VEHICLE_NEXT_SEAT");
  605. +    recv_data.hexlike();
  606. +
  607. +    GetPlayer()->ChangeSeat(-1, true);
  608. +}
  609. +
  610. +void WorldSession::HandleRequestVehicleSwitchSeat(WorldPacket &recv_data)
  611. +{
  612. +    sLog.outDebug("WORLD: Recvd CMSG_REQUEST_VEHICLE_SWITCH_SEAT");
  613. +    recv_data.hexlike();
  614. +
  615. +    uint64 vehicleGUID = _player->GetVehicleGUID();
  616. +
  617. +    if(!vehicleGUID)                                        // something wrong here...
  618. +        return;
  619. +
  620. +    if(Vehicle *vehicle = ObjectAccessor::GetVehicle(vehicleGUID))
  621.      {
  622. -        // Aura::HandleAuraControlVehicle will call Player::ExitVehicle
  623. -        vehicle->RemoveSpellsCausingAura(SPELL_AURA_CONTROL_VEHICLE);
  624. +        ObjectGuid guid;
  625. +        recv_data >> guid.ReadAsPacked();
  626. +
  627. +        int8 seatId = 0;
  628. +        recv_data >> seatId;
  629. +
  630. +        if(!guid.IsEmpty())
  631. +        {
  632. +            if(vehicleGUID != guid.GetRawValue())
  633. +            {
  634. +                if(Vehicle *veh = ObjectAccessor::GetVehicle(guid.GetRawValue()))
  635. +                {
  636. +                    if(!_player->IsWithinDistInMap(veh, 10))
  637. +                        return;
  638. +
  639. +                    if(Vehicle *v = veh->FindFreeSeat(&seatId, false))
  640. +                    {
  641. +                        vehicle->RemovePassenger(_player);
  642. +                        _player->EnterVehicle(v, seatId, false);
  643. +                    }
  644. +                }
  645. +                return;
  646. +            }
  647. +        }
  648. +        if(Vehicle *v = vehicle->FindFreeSeat(&seatId, false))
  649. +        {
  650. +            vehicle->RemovePassenger(_player);
  651. +            _player->EnterVehicle(v, seatId, false);
  652. +        }
  653. +    }
  654. +}
  655. +
  656. +void WorldSession::HandleChangeSeatsOnControlledVehicle(WorldPacket &recv_data)
  657. +{
  658. +    sLog.outDebug("WORLD: Recvd CMSG_CHANGE_SEATS_ON_CONTROLLED_VEHICLE");
  659. +    recv_data.hexlike();
  660. +
  661. +    uint64 vehicleGUID = _player->GetVehicleGUID();
  662. +
  663. +    if(!vehicleGUID)                                        // something wrong here...
  664. +        return;
  665. +
  666. +    if(recv_data.GetOpcode() == CMSG_REQUEST_VEHICLE_PREV_SEAT)
  667. +    {
  668. +        _player->ChangeSeat(-1, false);
  669. +        return;
  670. +    }
  671. +    else if(recv_data.GetOpcode() == CMSG_REQUEST_VEHICLE_NEXT_SEAT)
  672. +    {
  673. +        _player->ChangeSeat(-1, true);
  674. +        return;
  675. +    }
  676. +
  677. +    ObjectGuid guid, guid2;
  678. +    recv_data >> guid.ReadAsPacked();
  679. +
  680. +    MovementInfo mi;
  681. +    recv_data >> mi;
  682. +    _player->m_movementInfo = mi;
  683. +
  684. +    recv_data >> guid2.ReadAsPacked(); //guid of vehicle or of vehicle in target seat
  685. +
  686. +    int8 seatId;
  687. +    recv_data >> seatId;
  688. +
  689. +    if(guid.GetRawValue() == guid2.GetRawValue())
  690. +        _player->ChangeSeat(seatId, false);
  691. +    else if(Vehicle *vehicle = ObjectAccessor::GetVehicle(guid2.GetRawValue()))
  692. +    {
  693. +        if(vehicle->HasEmptySeat(seatId))
  694. +        {
  695. +            _player->ExitVehicle();
  696. +            _player->EnterVehicle(vehicle, seatId);
  697. +        }
  698. +    }
  699. +}
  700. +
  701. +void WorldSession::HandleEnterPlayerVehicle(WorldPacket &recv_data)
  702. +{
  703. +    DEBUG_LOG("WORLD: Recvd CMSG_PLAYER_VEHICLE_ENTER");
  704. +    recv_data.hexlike();
  705. +
  706. +    ObjectGuid guid;
  707. +    recv_data >> guid;
  708. +
  709. +    if (Player* pl = ObjectAccessor::FindPlayer(guid))
  710. +    {
  711. +        if (!pl->GetVehicleKit())
  712. +            return;
  713. +        if (!pl->IsInSameRaidWith(GetPlayer()))
  714. +            return;
  715. +        if (!pl->IsWithinDistInMap(GetPlayer(), INTERACTION_DISTANCE))
  716. +            return;
  717. +        if (pl->GetTransport())
  718. +            return;
  719. +        GetPlayer()->EnterVehicle(pl->GetVehicleKit());
  720. +    }
  721. +}
  722. +
  723. +void WorldSession::HandleEjectPasenger(WorldPacket &recv_data)
  724. +{
  725. +    DEBUG_LOG("WORLD: Recvd CMSG_EJECT_PASSENGER");
  726. +    recv_data.hexlike();
  727. +
  728. +    if(recv_data.GetOpcode()==CMSG_EJECT_PASSENGER)
  729. +    {
  730. +        if (GetPlayer()->GetVehicleKit())
  731. +        {
  732. +            ObjectGuid guid;
  733. +            recv_data >> guid;
  734. +            if(Player* Pl = ObjectAccessor::FindPlayer(guid))
  735. +                Pl->ExitVehicle();
  736. +        }
  737.      }
  738.  }
  739.  
  740. @@ -489,13 +635,21 @@ void WorldSession::HandleSummonResponseOpcode(WorldPacket& recv_data)
  741.  bool WorldSession::VerifyMovementInfo(MovementInfo const& movementInfo, ObjectGuid const& guid) const
  742.  {
  743.      // ignore wrong guid (player attempt cheating own session for not own guid possible...)
  744. -    if (guid != _player->GetMover()->GetObjectGuid())
  745. +    Unit *mover = _player->GetMover();
  746. +   if (guid != _player->GetMover()->GetObjectGuid())
  747.          return false;
  748.  
  749.      if (!MaNGOS::IsValidMapCoord(movementInfo.GetPos()->x, movementInfo.GetPos()->y, movementInfo.GetPos()->z, movementInfo.GetPos()->o))
  750.          return false;
  751.  
  752. -    if (movementInfo.HasMovementFlag(MOVEFLAG_ONTRANSPORT))
  753. +    if((movementInfo.HasMovementFlag (MOVEFLAG_ONTRANSPORT)) && (movementInfo.HasMovementFlag (MOVEFLAG_ROOT)))
  754. +    {
  755. +        if(mover->GetVehicle() && mover->GetVehicleGUID() && mover->GetTypeId()==TYPEID_PLAYER)
  756. +        {
  757. +            _player->ExitVehicle();
  758. +        }
  759. +    }
  760. +    else if (movementInfo.HasMovementFlag (MOVEFLAG_ONTRANSPORT) && !mover->GetVehicle() && !mover->GetVehicleGUID())
  761.      {
  762.          // transports size limited
  763.          // (also received at zeppelin/lift leave by some reason with t_* as absolute in continent coordinates, can be safely skipped)
  764. @@ -531,6 +685,9 @@ void WorldSession::HandleMoverRelocation(MovementInfo& movementInfo)
  765.                      {
  766.                          plMover->m_transport = (*iter);
  767.                          (*iter)->AddPassenger(plMover);
  768. +
  769. +                        if (plMover->GetVehicleKit())
  770. +                            plMover->GetVehicleKit()->RemoveAllPassengers();
  771.                          break;
  772.                      }
  773.                  }
  774. @@ -549,6 +706,18 @@ void WorldSession::HandleMoverRelocation(MovementInfo& movementInfo)
  775.              plMover->SetInWater( !plMover->IsInWater() || plMover->GetTerrain()->IsUnderWater(movementInfo.GetPos()->x, movementInfo.GetPos()->y, movementInfo.GetPos()->z) );
  776.          }
  777.  
  778. +        if (movementInfo.HasMovementFlag(MOVEFLAG_SWIMMING))
  779. +        {
  780. +            if(mover->GetTypeId() == TYPEID_UNIT)
  781. +            {
  782. +                if(((Creature*)mover)->IsVehicle() && !((Creature*)mover)->CanSwim())
  783. +                {
  784. +                    // NOTE : we should enter evade mode here, but...
  785. +                    ((Vehicle*)mover)->SetSpawnDuration(1);
  786. +                }
  787. +            }
  788. +        }
  789. +
  790.          plMover->SetPosition(movementInfo.GetPos()->x, movementInfo.GetPos()->y, movementInfo.GetPos()->z, movementInfo.GetPos()->o);
  791.          plMover->m_movementInfo = movementInfo;
  792.  
  793. @@ -586,6 +755,10 @@ void WorldSession::HandleMoverRelocation(MovementInfo& movementInfo)
  794.      else                                                    // creature charmed
  795.      {
  796.          if (mover->IsInWorld())
  797. +        {
  798.              mover->GetMap()->CreatureRelocation((Creature*)mover, movementInfo.GetPos()->x, movementInfo.GetPos()->y, movementInfo.GetPos()->z, movementInfo.GetPos()->o);
  799. +            if(((Creature*)mover)->IsVehicle())
  800. +                ((Vehicle*)mover)->RellocatePassengers(mover->GetMap());
  801. +        }
  802.      }
  803.  }
  804. diff --git a/src/game/Object.cpp b/src/game/Object.cpp
  805. index c334551..da1f69e 100644
  806. --- a/src/game/Object.cpp
  807. +++ b/src/game/Object.cpp
  808. @@ -270,13 +270,16 @@ void Object::BuildMovementUpdate(ByteBuffer * data, uint16 updateFlags) const
  809.                          }
  810.                      }
  811.                  }
  812. +                if (unit->GetVehicle() || unit->GetVehicleGUID())
  813. +                   unit->m_movementInfo.AddMovementFlag(MOVEFLAG_ONTRANSPORT);
  814. +
  815.              }
  816.              break;
  817.              case TYPEID_PLAYER:
  818.              {
  819.                  Player *player = ((Player*)unit);
  820.  
  821. -                if(player->GetTransport())
  822. +                if(player->GetTransport() || player->GetVehicle())
  823.                      player->m_movementInfo.AddMovementFlag(MOVEFLAG_ONTRANSPORT);
  824.                  else
  825.                      player->m_movementInfo.RemoveMovementFlag(MOVEFLAG_ONTRANSPORT);
  826. @@ -284,6 +287,9 @@ void Object::BuildMovementUpdate(ByteBuffer * data, uint16 updateFlags) const
  827.                  // remove unknown, unused etc flags for now
  828.                  player->m_movementInfo.RemoveMovementFlag(MOVEFLAG_SPLINE_ENABLED);
  829.  
  830. +                if(((Unit*)this)->GetVehicleGUID())
  831. +                    player->m_movementInfo.AddMovementFlag(MOVEFLAG_ONTRANSPORT);
  832. +
  833.                  if(player->IsTaxiFlying())
  834.                  {
  835.                      MANGOS_ASSERT(player->GetMotionMaster()->GetCurrentMovementGeneratorType() == FLIGHT_MOTION_TYPE);
  836. @@ -1145,7 +1151,14 @@ void WorldObject::Relocate(float x, float y, float z, float orientation)
  837.      m_orientation = orientation;
  838.  
  839.      if(isType(TYPEMASK_UNIT))
  840. +    {
  841.          ((Unit*)this)->m_movementInfo.ChangePosition(x, y, z, orientation);
  842. +        if(GetTypeId() == TYPEID_UNIT)
  843. +        {
  844. +            if(((Creature*)this)->IsVehicle() && IsInWorld())
  845. +                ((Vehicle*)this)->RellocatePassengers(GetMap());
  846. +        }
  847. +    }
  848.  }
  849.  
  850.  void WorldObject::Relocate(float x, float y, float z)
  851. @@ -1155,7 +1168,11 @@ void WorldObject::Relocate(float x, float y, float z)
  852.      m_positionZ = z;
  853.  
  854.      if(isType(TYPEMASK_UNIT))
  855. +    {
  856.          ((Unit*)this)->m_movementInfo.ChangePosition(x, y, z, GetOrientation());
  857. +        if(((Creature*)this)->IsVehicle() && IsInWorld())
  858. +            ((Vehicle*)this)->RellocatePassengers(GetMap());
  859. +    }
  860.  }
  861.  
  862.  void WorldObject::SetOrientation(float orientation)
  863. @@ -1770,6 +1787,42 @@ Creature* WorldObject::SummonCreature(uint32 id, float x, float y, float z, floa
  864.      return pCreature;
  865.  }
  866.  
  867. +Vehicle* WorldObject::SummonVehicle(uint32 id, float x, float y, float z, float ang, uint32 vehicleId)
  868. +{
  869. +    Vehicle *v = new Vehicle;
  870. +
  871. +    Map *map = GetMap();
  872. +    Team team = TEAM_NONE;
  873. +    if (GetTypeId()==TYPEID_PLAYER)
  874. +        team = ((Player*)this)->GetTeam();
  875. +
  876. +    if(!v->Create(sObjectMgr.GenerateLowGuid(HIGHGUID_VEHICLE), map, GetPhaseMask(), id, vehicleId, team))
  877. +    {
  878. +        delete v;
  879. +        return NULL;
  880. +    }
  881. +
  882. +    if (x == 0.0f && y == 0.0f && z == 0.0f)
  883. +        GetClosePoint(x, y, z, v->GetObjectBoundingRadius());
  884. +
  885. +    v->Relocate(x, y, z, ang);
  886. +
  887. +    if(!v->IsPositionValid())
  888. +    {
  889. +        sLog.outError("ERROR: Vehicle (guidlow %d, entry %d) not created. Suggested coordinates isn't valid (X: %f Y: %f)",
  890. +            v->GetGUIDLow(), v->GetEntry(), v->GetPositionX(), v->GetPositionY());
  891. +        delete v;
  892. +        return NULL;
  893. +    }
  894. +    map->Add((Creature*)v);
  895. +    v->AIM_Initialize();
  896. +
  897. +    if(GetTypeId()==TYPEID_UNIT && ((Creature*)this)->AI())
  898. +        ((Creature*)this)->AI()->JustSummoned((Creature*)v);
  899. +
  900. +    return v;
  901. +}
  902. +
  903.  namespace MaNGOS
  904.  {
  905.      class NearUsedPosDo
  906. diff --git a/src/game/Object.h b/src/game/Object.h
  907. index 84df5f4..b1fb271 100644
  908. --- a/src/game/Object.h
  909. +++ b/src/game/Object.h
  910. @@ -70,6 +70,7 @@ class Map;
  911.  class UpdateMask;
  912.  class InstanceData;
  913.  class TerrainInfo;
  914. +class Vehicle;
  915.  
  916.  typedef UNORDERED_MAP<Player*, UpdateData> UpdateDataMapType;
  917.  
  918. @@ -493,6 +494,9 @@ class MANGOS_DLL_SPEC WorldObject : public Object
  919.          bool isActiveObject() const { return m_isActiveObject || m_viewPoint.hasViewers(); }
  920.  
  921.          ViewPoint& GetViewPoint() { return m_viewPoint; }
  922. +
  923. +        Vehicle* SummonVehicle(uint32 id, float x, float y, float z, float ang, uint32 vehicleId = NULL);
  924. +
  925.      protected:
  926.          explicit WorldObject();
  927.  
  928. diff --git a/src/game/ObjectAccessor.cpp b/src/game/ObjectAccessor.cpp
  929. index 56176ae..ae27f87 100644
  930. --- a/src/game/ObjectAccessor.cpp
  931. +++ b/src/game/ObjectAccessor.cpp
  932. @@ -52,6 +52,21 @@ ObjectAccessor::~ObjectAccessor()
  933.      }
  934.  }
  935.  
  936. +Creature*
  937. +ObjectAccessor::GetAnyTypeCreature(WorldObject const &u, ObjectGuid guid)
  938. +{
  939. +    if(guid.IsPlayer() || !u.IsInWorld())
  940. +        return NULL;
  941. +
  942. +    if(guid.IsPet())
  943. +        return u.GetMap()->GetPet(guid);
  944. +
  945. +    if(guid.IsVehicle())
  946. +        return u.GetMap()->GetVehicle(guid);
  947. +
  948. +    return u.GetMap()->GetCreature(guid);
  949. +}
  950. +
  951.  Unit*
  952.  ObjectAccessor::GetUnit(WorldObject const &u, ObjectGuid guid)
  953.  {
  954. @@ -61,10 +76,7 @@ ObjectAccessor::GetUnit(WorldObject const &u, ObjectGuid guid)
  955.      if(guid.IsPlayer())
  956.          return FindPlayer(guid);
  957.  
  958. -    if (!u.IsInWorld())
  959. -        return NULL;
  960. -
  961. -    return u.GetMap()->GetAnyTypeCreature(guid);
  962. +    return GetAnyTypeCreature(u, guid);
  963.  }
  964.  
  965.  Corpse* ObjectAccessor::GetCorpseInMap(ObjectGuid guid, uint32 mapid)
  966. diff --git a/src/game/ObjectAccessor.h b/src/game/ObjectAccessor.h
  967. index 5b9445f..c28d41c 100644
  968. --- a/src/game/ObjectAccessor.h
  969. +++ b/src/game/ObjectAccessor.h
  970. @@ -40,6 +40,7 @@
  971.  class Creature;
  972.  class Unit;
  973.  class GameObject;
  974. +class Vehicle;
  975.  class WorldObject;
  976.  class Map;
  977.  
  978. @@ -100,13 +101,21 @@ class MANGOS_DLL_DECL ObjectAccessor : public MaNGOS::Singleton<ObjectAccessor,
  979.          // global (obj used for map only location local guid objects (pets currently)
  980.          static Unit*   GetUnitInWorld(WorldObject const& obj, ObjectGuid guid);
  981.  
  982. -        // FIXME: map local object with global search
  983. +        // map local object with global search
  984.          static Creature*   GetCreatureInWorld(ObjectGuid guid)   { return FindHelper<Creature>(guid); }
  985.          static GameObject* GetGameObjectInWorld(ObjectGuid guid) { return FindHelper<GameObject>(guid); }
  986. +        static Pet*        GetGameObjectInWorld(ObjectGuid guid, Pet*        /*fake*/) { return FindHelper<Pet>(guid); }
  987. +        static Vehicle*    GetGameObjectInWorld(ObjectGuid guid, Vehicle*    /*fake*/) { return FindHelper<Vehicle>(guid); }
  988.  
  989.          // Search player at any map in world and other objects at same map with `obj`
  990.          // Note: recommended use Map::GetUnit version if player also expected at same map only
  991.          static Unit* GetUnit(WorldObject const& obj, ObjectGuid guid);
  992. +        static Creature* GetAnyTypeCreature(WorldObject const &, ObjectGuid guid);
  993. +        //static Player* GetPlayer(Unit const &, uint64 guid) { return FindPlayer(guid); }
  994. +        //static Corpse* GetCorpse(WorldObject const &u, uint64 guid);
  995. +        //static Pet* GetPet(uint64 guid) { return GetObjectInWorld(guid, (Pet*)NULL); }
  996. +        static Vehicle* GetVehicle(ObjectGuid guid) { return GetGameObjectInWorld(guid, (Vehicle*)NULL); }
  997. +        //static Player* FindPlayer(uint64);
  998.  
  999.          // Player access
  1000.          static Player* FindPlayer(ObjectGuid guid);         // if need player at specific map better use Map::GetPlayer
  1001. @@ -175,6 +184,9 @@ inline Unit* ObjectAccessor::GetUnitInWorld(WorldObject const& obj, ObjectGuid g
  1002.      if (guid.IsPet())
  1003.          return obj.IsInWorld() ? obj.GetMap()->GetPet(guid) : NULL;
  1004.  
  1005. +    if (guid.IsVehicle())
  1006. +        return obj.IsInWorld() ? ((Unit*)obj.GetMap()->GetVehicle(guid)) : NULL;
  1007. +
  1008.      return GetCreatureInWorld(guid);
  1009.  }
  1010.  
  1011. diff --git a/src/game/ObjectMgr.cpp b/src/game/ObjectMgr.cpp
  1012. index 462c673..9f5091e 100644
  1013. --- a/src/game/ObjectMgr.cpp
  1014. +++ b/src/game/ObjectMgr.cpp
  1015. @@ -830,6 +830,93 @@ void ObjectMgr::ConvertCreatureAddonAuras(CreatureDataAddon* addon, char const*
  1016.      endAura.effect_idx = EFFECT_INDEX_0;
  1017.  }
  1018.  
  1019. +void ObjectMgr::ConvertCreatureAddonPassengers(CreatureDataAddon* addon, char const* table, char const* guidEntryStr)
  1020. +{
  1021. +    // Now add the passengers, format "creature_entry/guid seatindex creature_entry/guid seatindex..."
  1022. +    char *p,*s;
  1023. +    std::vector<int> val;
  1024. +    s=p=(char*)reinterpret_cast<char const*>(addon->passengers);
  1025. +    if(p)
  1026. +    {
  1027. +        while (p[0]!=0)
  1028. +        {
  1029. +            ++p;
  1030. +            if (p[0]==' ')
  1031. +            {
  1032. +                val.push_back(atoi(s));
  1033. +                s=++p;
  1034. +            }
  1035. +        }
  1036. +        if (p!=s)
  1037. +            val.push_back(atoi(s));
  1038. +
  1039. +        // free char* loaded memory
  1040. +        delete[] (char*)reinterpret_cast<char const*>(addon->passengers);
  1041. +
  1042. +        // wrong list
  1043. +        if (val.size()%2)
  1044. +        {
  1045. +            addon->auras = NULL;
  1046. +            sLog.outErrorDb("Creature (%s: %u) has wrong `passengers` data in `%s`.",guidEntryStr,addon->guidOrEntry,table);
  1047. +            return;
  1048. +        }
  1049. +    }
  1050. +
  1051. +    // empty list
  1052. +    if(val.empty())
  1053. +    {
  1054. +        addon->passengers = NULL;
  1055. +        return;
  1056. +    }
  1057. +
  1058. +    // replace by new structures array
  1059. +    const_cast<CreatureDataAddonPassengers*&>(addon->passengers) = new CreatureDataAddonPassengers[val.size()/2+1];
  1060. +
  1061. +    uint32 i=0;
  1062. +    for(uint32 j=0; j<val.size()/2; ++j)
  1063. +    {
  1064. +        CreatureDataAddonPassengers& cPas = const_cast<CreatureDataAddonPassengers&>(addon->passengers[i]);
  1065. +        if(guidEntryStr == "Entry")
  1066. +            cPas.entry = (uint32)val[2*j+0];
  1067. +        else
  1068. +            cPas.guid = (uint32)val[2*j+0];
  1069. +        cPas.seat_idx = (int8)val[2*j+1];
  1070. +        if ( cPas.seat_idx > 7 )
  1071. +        {
  1072. +            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);
  1073. +            continue;
  1074. +        }
  1075. +        if(cPas.entry == 0 && cPas.guid == 0)
  1076. +        {
  1077. +            sLog.outErrorDb("Creature (%s: %u) has NULL creature entry/guid in `passengers` field in `%s`.",guidEntryStr,addon->guidOrEntry,table);
  1078. +            continue;
  1079. +        }
  1080. +        if(cPas.entry > 0)
  1081. +        {
  1082. +            if(!sCreatureStorage.LookupEntry<CreatureInfo>(cPas.entry))
  1083. +            {
  1084. +                sLog.outErrorDb("Creature (%s: %u) has wrong creature entry/guid %u `passengers` field in `%s`.",guidEntryStr,addon->guidOrEntry,cPas.entry,table);
  1085. +                continue;
  1086. +            }
  1087. +        }
  1088. +        else
  1089. +        {
  1090. +            if(mCreatureDataMap.find(cPas.guid)==mCreatureDataMap.end())
  1091. +            {
  1092. +                sLog.outErrorDb("Creature (%s: %u) has wrong creature entry/guid %u `passengers` field in `%s`.",guidEntryStr,addon->guidOrEntry,cPas.guid,table);
  1093. +                continue;
  1094. +            }
  1095. +        }
  1096. +        ++i;
  1097. +    }
  1098. +
  1099. +    // fill terminator element (after last added)
  1100. +    CreatureDataAddonPassengers& endPassenger = const_cast<CreatureDataAddonPassengers&>(addon->passengers[i]);
  1101. +    endPassenger.entry = 0;
  1102. +    endPassenger.guid = 0;
  1103. +    endPassenger.seat_idx = -1;
  1104. +}
  1105. +
  1106.  void ObjectMgr::LoadCreatureAddons(SQLStorage& creatureaddons, char const* entryName, char const* comment)
  1107.  {
  1108.      creatureaddons.Load();
  1109. @@ -866,6 +953,7 @@ void ObjectMgr::LoadCreatureAddons(SQLStorage& creatureaddons, char const* entry
  1110.          }
  1111.  
  1112.          ConvertCreatureAddonAuras(const_cast<CreatureDataAddon*>(addon), creatureaddons.GetTableName(), entryName);
  1113. +        ConvertCreatureAddonPassengers(const_cast<CreatureDataAddon*>(addon), creatureaddons.GetTableName(), entryName);
  1114.      }
  1115.  }
  1116.  
  1117. @@ -6420,6 +6508,8 @@ uint32 ObjectMgr::GenerateLowGuid(HighGuid guidhigh)
  1118.              return m_ItemGuids.Generate();
  1119.          case HIGHGUID_UNIT:
  1120.              return m_CreatureGuids.Generate();
  1121. +        case HIGHGUID_VEHICLE:
  1122. +            return m_VehicleGuids.Generate();
  1123.          case HIGHGUID_PLAYER:
  1124.              return m_CharGuids.Generate();
  1125.          case HIGHGUID_GAMEOBJECT:
  1126. @@ -9656,6 +9746,126 @@ CreatureInfo const* GetCreatureTemplateStore(uint32 entry)
  1127.      return sCreatureStorage.LookupEntry<CreatureInfo>(entry);
  1128.  }
  1129.  
  1130. +void ObjectMgr::LoadVehicleData()
  1131. +{
  1132. +    mVehicleData.clear();
  1133. +
  1134. +    QueryResult *result = WorldDatabase.Query("SELECT entry, flags, Spell1, Spell2, Spell3, Spell4, Spell5, Spell6, Spell7, Spell8, Spell9, Spell10, req_aura FROM vehicle_data");
  1135. +    if(!result)
  1136. +    {
  1137. +        barGoLink bar( 1 );
  1138. +        bar.step();
  1139. +
  1140. +        sLog.outString();
  1141. +        sLog.outString( ">> Loaded 0 vehicle data" );
  1142. +        sLog.outErrorDb("`vehicle_data` table is empty!");
  1143. +        return;
  1144. +    }
  1145. +
  1146. +    uint32 count = 0;
  1147. +
  1148. +    barGoLink bar( result->GetRowCount() );
  1149. +    do
  1150. +    {
  1151. +        bar.step();
  1152. +
  1153. +        Field* fields = result->Fetch();
  1154. +
  1155. +        VehicleDataStructure VDS;
  1156. +        // NOTE : we can use spellid or creature id
  1157. +        uint32 v_entry      = fields[0].GetUInt32();
  1158. +        VDS.v_flags         = fields[1].GetUInt32();
  1159. +        for(uint8 j = 0; j < MAX_VEHICLE_SPELLS; j++)
  1160. +        {
  1161. +            VDS.v_spells[j] = fields[j+2].GetUInt32();
  1162. +        }
  1163. +        VDS.req_aura        = fields[12].GetUInt32();
  1164. +
  1165. +        VehicleEntry const *vehicleInfo = sVehicleStore.LookupEntry(v_entry);
  1166. +        if(!vehicleInfo)
  1167. +        {
  1168. +            sLog.outErrorDb("Vehicle id %u listed in `vehicle_data` does not exist",v_entry);
  1169. +            continue;
  1170. +        }
  1171. +        for(uint8 j = 0; j < MAX_VEHICLE_SPELLS; j++)
  1172. +        {
  1173. +            if(VDS.v_spells[j])
  1174. +            {
  1175. +                SpellEntry const* j_spell = sSpellStore.LookupEntry(VDS.v_spells[j]);
  1176. +                if(!j_spell)
  1177. +                {
  1178. +                    sLog.outErrorDb("Spell %u listed in `vehicle_data` does not exist, skipped",VDS.v_spells[j]);
  1179. +                    VDS.v_spells[j] = 0;
  1180. +                }
  1181. +            }
  1182. +        }
  1183. +        if(VDS.req_aura)
  1184. +        {
  1185. +            SpellEntry const* i_spell = sSpellStore.LookupEntry(VDS.req_aura);
  1186. +            if(!i_spell)
  1187. +            {
  1188. +                sLog.outErrorDb("Spell %u listed in `vehicle_data` does not exist, skipped",VDS.req_aura);
  1189. +                VDS.req_aura = 0;
  1190. +            }
  1191. +        }
  1192. +
  1193. +        mVehicleData[v_entry] = VDS;
  1194. +        ++count;
  1195. +    }
  1196. +    while (result->NextRow());
  1197. +
  1198. +    delete result;
  1199. +
  1200. +    sLog.outString();
  1201. +    sLog.outString( ">> Loaded %u vehicle data", count );
  1202. +}
  1203. +
  1204. +void ObjectMgr::LoadVehicleSeatData()
  1205. +{
  1206. +    mVehicleSeatData.clear();
  1207. +
  1208. +    QueryResult *result = WorldDatabase.Query("SELECT seat,flags FROM vehicle_seat_data");
  1209. +
  1210. +    if( !result )
  1211. +    {
  1212. +        barGoLink bar( 1 );
  1213. +
  1214. +        bar.step();
  1215. +
  1216. +        sLog.outString();
  1217. +        sLog.outString( ">> Loaded 0 vehicle seat data" );
  1218. +        sLog.outErrorDb("`vehicle_seat_data` table is empty!");
  1219. +        return;
  1220. +    }
  1221. +    uint32 count = 0;
  1222. +
  1223. +    barGoLink bar( result->GetRowCount() );
  1224. +    do
  1225. +    {
  1226. +        bar.step();
  1227. +
  1228. +        Field *fields = result->Fetch();
  1229. +        uint32 entry  = fields[0].GetUInt32();
  1230. +        uint32 flag   = fields[1].GetUInt32();
  1231. +
  1232. +        VehicleSeatEntry const *vsInfo = sVehicleSeatStore.LookupEntry(entry);
  1233. +        if(!vsInfo)
  1234. +        {
  1235. +            sLog.outErrorDb("Vehicle seat %u listed in `vehicle_seat_data` does not exist",entry);
  1236. +            continue;
  1237. +        }
  1238. +
  1239. +        mVehicleSeatData[entry] = flag;
  1240. +        ++count;
  1241. +    }
  1242. +    while (result->NextRow());
  1243. +
  1244. +    delete result;
  1245. +
  1246. +    sLog.outString();
  1247. +    sLog.outString( ">> Loaded %u vehicle seat data", count );
  1248. +}
  1249. +
  1250.  Quest const* GetQuestTemplateStore(uint32 entry)
  1251.  {
  1252.      return sObjectMgr.GetQuestTemplate(entry);
  1253. diff --git a/src/game/ObjectMgr.h b/src/game/ObjectMgr.h
  1254. index ab56405..da2cbd6 100644
  1255. --- a/src/game/ObjectMgr.h
  1256. +++ b/src/game/ObjectMgr.h
  1257. @@ -675,6 +675,8 @@ extern LanguageDesc lang_description[LANGUAGES_COUNT];
  1258.  MANGOS_DLL_SPEC LanguageDesc const* GetLanguageDescByID(uint32 lang);
  1259.  
  1260.  class PlayerDumpReader;
  1261. +// vehicle system
  1262. +#define MAX_VEHICLE_SPELLS 6
  1263.  
  1264.  template<typename T>
  1265.  class IdGenerator
  1266. @@ -694,6 +696,16 @@ class IdGenerator
  1267.          T m_nextGuid;
  1268.  };
  1269.  
  1270. +struct VehicleDataStructure
  1271. +{
  1272. +    uint32 v_flags;                                         // vehicle flags, see enum CustomVehicleFLags
  1273. +    uint32 v_spells[MAX_VEHICLE_SPELLS];                    // spells
  1274. +    uint32 req_aura;                                        // requieres aura on player to enter (eg. in wintergrasp)
  1275. +};
  1276. +
  1277. +typedef UNORDERED_MAP<uint32, VehicleDataStructure> VehicleDataMap;
  1278. +typedef std::map<uint32,uint32> VehicleSeatDataMap;
  1279. +
  1280.  class ObjectMgr
  1281.  {
  1282.      friend class PlayerDumpReader;
  1283. @@ -984,6 +996,9 @@ class ObjectMgr
  1284.          void LoadVendors() { LoadVendors("npc_vendor", false); }
  1285.          void LoadTrainerSpell();
  1286.  
  1287. +        void LoadVehicleData();
  1288. +        void LoadVehicleSeatData();
  1289. +
  1290.          std::string GeneratePetName(uint32 entry);
  1291.          uint32 GetBaseXP(uint32 level) const;
  1292.          uint32 GetXPForLevel(uint32 level) const;
  1293. @@ -1248,6 +1263,24 @@ class ObjectMgr
  1294.  
  1295.          int GetOrNewIndexForLocale(LocaleConstant loc);
  1296.  
  1297. +        VehicleDataMap mVehicleData;
  1298. +        VehicleSeatDataMap mVehicleSeatData;
  1299. +
  1300. +        uint32 GetSeatFlags(uint32 seatid)
  1301. +        {
  1302. +            VehicleSeatDataMap::iterator i = mVehicleSeatData.find(seatid);
  1303. +            if(i == mVehicleSeatData.end())
  1304. +                return NULL;
  1305. +            else
  1306. +                return i->second;
  1307. +        }
  1308. +        VehicleDataStructure const* GetVehicleData(uint32 entry) const
  1309. +        {
  1310. +            VehicleDataMap::const_iterator itr = mVehicleData.find(entry);
  1311. +            if(itr==mVehicleData.end()) return NULL;
  1312. +            return &itr->second;
  1313. +        }
  1314. +
  1315.          SpellClickInfoMapBounds GetSpellClickInfoMapBounds(uint32 creature_id) const
  1316.          {
  1317.              return mSpellClickInfoMap.equal_range(creature_id);
  1318. @@ -1324,6 +1357,7 @@ class ObjectMgr
  1319.          ObjectGuidGenerator<HIGHGUID_GAMEOBJECT> m_GameobjectGuids;
  1320.          ObjectGuidGenerator<HIGHGUID_CORPSE>     m_CorpseGuids;
  1321.          ObjectGuidGenerator<HIGHGUID_INSTANCE>   m_InstanceGuids;
  1322. +        ObjectGuidGenerator<HIGHGUID_VEHICLE>    m_VehicleGuids;
  1323.  
  1324.          QuestMap            mQuestTemplates;
  1325.  
  1326. @@ -1392,6 +1426,7 @@ class ObjectMgr
  1327.          void CheckScriptTexts(ScriptMapMap const& scripts,std::set<int32>& ids);
  1328.          void LoadCreatureAddons(SQLStorage& creatureaddons, char const* entryName, char const* comment);
  1329.          void ConvertCreatureAddonAuras(CreatureDataAddon* addon, char const* table, char const* guidEntryStr);
  1330. +        void ConvertCreatureAddonPassengers(CreatureDataAddon* addon, char const* table, char const* guidEntryStr);
  1331.          void LoadQuestRelationsHelper(QuestRelationsMap& map, char const* table);
  1332.          void LoadVendors(char const* tableName, bool isTemplates);
  1333.  
  1334. diff --git a/src/game/Opcodes.cpp b/src/game/Opcodes.cpp
  1335. index 4f0fbe0..647f38d 100644
  1336. --- a/src/game/Opcodes.cpp
  1337. +++ b/src/game/Opcodes.cpp
  1338. @@ -1168,10 +1168,10 @@ OpcodeHandler opcodeTable[NUM_MSG_TYPES] =
  1339.      /*0x473*/ { "CMSG_CHAR_CUSTOMIZE",                          STATUS_AUTHED,   &WorldSession::HandleCharCustomizeOpcode       },
  1340.      /*0x474*/ { "SMSG_CHAR_CUSTOMIZE",                          STATUS_NEVER,    &WorldSession::Handle_ServerSide               },
  1341.      /*0x475*/ { "SMSG_PET_RENAMEABLE",                          STATUS_NEVER,    &WorldSession::Handle_ServerSide               },
  1342. -    /*0x476*/ { "CMSG_REQUEST_VEHICLE_EXIT",                    STATUS_NEVER,    &WorldSession::Handle_NULL                     },
  1343. -    /*0x477*/ { "CMSG_REQUEST_VEHICLE_PREV_SEAT",               STATUS_NEVER,    &WorldSession::Handle_NULL                     },
  1344. -    /*0x478*/ { "CMSG_REQUEST_VEHICLE_NEXT_SEAT",               STATUS_NEVER,    &WorldSession::Handle_NULL                     },
  1345. -    /*0x479*/ { "CMSG_REQUEST_VEHICLE_SWITCH_SEAT",             STATUS_NEVER,    &WorldSession::Handle_NULL                     },
  1346. +    /*0x476*/ { "CMSG_REQUEST_VEHICLE_EXIT",                    STATUS_LOGGEDIN, &WorldSession::HandleRequestVehicleExit        },
  1347. +    /*0x477*/ { "CMSG_REQUEST_VEHICLE_PREV_SEAT",               STATUS_LOGGEDIN, &WorldSession::HandleRequestVehiclePrevSeat    },
  1348. +    /*0x478*/ { "CMSG_REQUEST_VEHICLE_NEXT_SEAT",               STATUS_LOGGEDIN, &WorldSession::HandleRequestVehicleNextSeat    },
  1349. +    /*0x479*/ { "CMSG_REQUEST_VEHICLE_SWITCH_SEAT",             STATUS_LOGGEDIN, &WorldSession::HandleRequestVehicleSwitchSeat  },
  1350.      /*0x47A*/ { "CMSG_PET_LEARN_TALENT",                        STATUS_LOGGEDIN, &WorldSession::HandlePetLearnTalent            },
  1351.      /*0x47B*/ { "CMSG_PET_UNLEARN_TALENTS",                     STATUS_NEVER,    &WorldSession::Handle_NULL                     },
  1352.      /*0x47C*/ { "SMSG_SET_PHASE_SHIFT",                         STATUS_NEVER,    &WorldSession::Handle_ServerSide               },
  1353. @@ -1205,7 +1205,7 @@ OpcodeHandler opcodeTable[NUM_MSG_TYPES] =
  1354.      /*0x498*/ { "SMSG_SERVER_FIRST_ACHIEVEMENT",                STATUS_NEVER,    &WorldSession::Handle_ServerSide               },
  1355.      /*0x499*/ { "SMSG_PET_LEARNED_SPELL",                       STATUS_NEVER,    &WorldSession::Handle_ServerSide               },
  1356.      /*0x49A*/ { "SMSG_PET_REMOVED_SPELL",                       STATUS_NEVER,    &WorldSession::Handle_ServerSide               },
  1357. -    /*0x49B*/ { "CMSG_CHANGE_SEATS_ON_CONTROLLED_VEHICLE",      STATUS_NEVER,    &WorldSession::Handle_NULL                     },
  1358. +    /*0x49B*/ { "CMSG_CHANGE_SEATS_ON_CONTROLLED_VEHICLE",      STATUS_LOGGEDIN, &WorldSession::HandleChangeSeatsOnControlledVehicle},
  1359.      /*0x49C*/ { "CMSG_HEARTH_AND_RESURRECT",                    STATUS_LOGGEDIN, &WorldSession::HandleHearthandResurrect        },
  1360.      /*0x49D*/ { "SMSG_ON_CANCEL_EXPECTED_RIDE_VEHICLE_AURA",    STATUS_NEVER,    &WorldSession::Handle_ServerSide               },
  1361.      /*0x49E*/ { "SMSG_CRITERIA_DELETED",                        STATUS_NEVER,    &WorldSession::Handle_ServerSide               },
  1362. @@ -1218,8 +1218,8 @@ OpcodeHandler opcodeTable[NUM_MSG_TYPES] =
  1363.      /*0x4A5*/ { "UMSG_UNKNOWN_1189",                            STATUS_NEVER,    &WorldSession::Handle_NULL                     },
  1364.      /*0x4A6*/ { "SMSG_BATTLEGROUND_INFO_THROTTLED",             STATUS_NEVER,    &WorldSession::Handle_ServerSide               },
  1365.      /*0x4A7*/ { "SMSG_PLAYER_VEHICLE_DATA",                     STATUS_NEVER,    &WorldSession::Handle_ServerSide               },
  1366. -    /*0x4A8*/ { "CMSG_UNKNOWN_1192",                            STATUS_NEVER,    &WorldSession::Handle_NULL                     },
  1367. -    /*0x4A9*/ { "CMSG_EJECT_PASSENGER",                         STATUS_NEVER,    &WorldSession::Handle_NULL                     },
  1368. +    /*0x4A8*/ { "CMSG_PLAYER_VEHICLE_ENTER",                    STATUS_LOGGEDIN, &WorldSession::HandleEnterPlayerVehicle        },
  1369. +    /*0x4A9*/ { "CMSG_EJECT_PASSENGER",                         STATUS_LOGGEDIN, &WorldSession::HandleEjectPasenger             },
  1370.      /*0x4AA*/ { "SMSG_PET_GUIDS",                               STATUS_NEVER,    &WorldSession::Handle_ServerSide               },
  1371.      /*0x4AB*/ { "SMSG_CLIENTCACHE_VERSION",                     STATUS_NEVER,    &WorldSession::Handle_ServerSide               },
  1372.      /*0x4AC*/ { "UMSG_UNKNOWN_1196",                            STATUS_NEVER,    &WorldSession::Handle_NULL                     },
  1373. diff --git a/src/game/Pet.cpp b/src/game/Pet.cpp
  1374. index 4c7410d..37d8db4 100644
  1375. --- a/src/game/Pet.cpp
  1376. +++ b/src/game/Pet.cpp
  1377. @@ -32,7 +32,7 @@ Pet::Pet(PetType type) :
  1378.  Creature(CREATURE_SUBTYPE_PET),
  1379.  m_resetTalentsCost(0), m_resetTalentsTime(0), m_usedTalentCount(0),
  1380.  m_removed(false), m_happinessTimer(7500), m_petType(type), m_duration(0),
  1381. -m_bonusdamage(0), m_auraUpdateMask(0), m_loading(false),
  1382. +m_bonusdamage(0), m_loading(false),
  1383.  m_declinedname(NULL), m_petModeFlags(PET_MODE_DEFAULT)
  1384.  {
  1385.      m_name = "Pet";
  1386. diff --git a/src/game/Pet.h b/src/game/Pet.h
  1387. index 620791d..92ae7b5 100644
  1388. --- a/src/game/Pet.h
  1389. +++ b/src/game/Pet.h
  1390. @@ -237,10 +237,6 @@ class Pet : public Creature
  1391.          time_t  m_resetTalentsTime;
  1392.          uint32  m_usedTalentCount;
  1393.  
  1394. -        const uint64& GetAuraUpdateMask() const { return m_auraUpdateMask; }
  1395. -        void SetAuraUpdateMask(uint8 slot) { m_auraUpdateMask |= (uint64(1) << slot); }
  1396. -        void ResetAuraUpdateMask() { m_auraUpdateMask = 0; }
  1397. -
  1398.          // overwrite Creature function for name localization back to WorldObject version without localization
  1399.          const char* GetNameForLocaleIdx(int32 locale_idx) const { return WorldObject::GetNameForLocaleIdx(locale_idx); }
  1400.  
  1401. @@ -252,7 +248,6 @@ class Pet : public Creature
  1402.          PetType m_petType;
  1403.          int32   m_duration;                                 // time until unsummon (used mostly for summoned guardians and not used for controlled pets)
  1404.          int32   m_bonusdamage;
  1405. -        uint64  m_auraUpdateMask;
  1406.          bool    m_loading;
  1407.  
  1408.          DeclinedName *m_declinedname;
  1409. diff --git a/src/game/PetHandler.cpp b/src/game/PetHandler.cpp
  1410. index f1ce925..3d65220 100644
  1411. --- a/src/game/PetHandler.cpp
  1412. +++ b/src/game/PetHandler.cpp
  1413. @@ -313,7 +313,7 @@ void WorldSession::HandlePetNameQueryOpcode( WorldPacket & recv_data )
  1414.  
  1415.  void WorldSession::SendPetNameQuery( uint64 petguid, uint32 petnumber)
  1416.  {
  1417. -    Creature* pet = _player->GetMap()->GetAnyTypeCreature(petguid);
  1418. +    Creature* pet = ObjectAccessor::GetAnyTypeCreature(*_player, petguid);
  1419.      if(!pet || !pet->GetCharmInfo() || pet->GetCharmInfo()->GetPetNumber() != petnumber)
  1420.      {
  1421.          WorldPacket data(SMSG_PET_NAME_QUERY_RESPONSE, (4+1+4+1));
  1422. @@ -353,7 +353,12 @@ void WorldSession::HandlePetSetAction( WorldPacket & recv_data )
  1423.  
  1424.      recv_data >> petguid;
  1425.  
  1426. -    Creature* pet = _player->GetMap()->GetAnyTypeCreature(petguid);
  1427. +    // FIXME: charmed case
  1428. +    //Pet* pet = ObjectAccessor::Instance().GetPet(petguid);
  1429. +    if(ObjectAccessor::FindPlayer(petguid))
  1430. +        return;
  1431. +
  1432. +    Creature* pet = ObjectAccessor::GetAnyTypeCreature(*_player, petguid);
  1433.  
  1434.      if(!pet || (pet != _player->GetPet() && pet != _player->GetCharm()))
  1435.      {
  1436. @@ -542,7 +547,8 @@ void WorldSession::HandlePetAbandon( WorldPacket & recv_data )
  1437.          return;
  1438.  
  1439.      // pet/charmed
  1440. -    if (Creature* pet = _player->GetMap()->GetAnyTypeCreature(guid))
  1441. +    Creature* pet = ObjectAccessor::GetAnyTypeCreature(*_player, guid);
  1442. +    if (pet)
  1443.      {
  1444.          if (pet->IsPet())
  1445.          {
  1446. @@ -596,7 +602,10 @@ void WorldSession::HandlePetSpellAutocastOpcode( WorldPacket& recvPacket )
  1447.      uint8  state;                                           //1 for on, 0 for off
  1448.      recvPacket >> guid >> spellid >> state;
  1449.  
  1450. -    Creature* pet = _player->GetMap()->GetAnyTypeCreature(guid);
  1451. +    if(ObjectAccessor::FindPlayer(guid))
  1452. +        return;
  1453. +
  1454. +    Creature* pet=ObjectAccessor::GetAnyTypeCreature(*_player,guid);
  1455.      if (!pet || (guid != _player->GetPetGuid() && guid != _player->GetCharmGuid()))
  1456.      {
  1457.          sLog.outError("HandlePetSpellAutocastOpcode. %s isn't pet of %s .", guid.GetString().c_str(), GetPlayer()->GetObjectGuid().GetString().c_str());
  1458. @@ -626,6 +635,23 @@ void WorldSession::HandlePetSpellAutocastOpcode( WorldPacket& recvPacket )
  1459.  void WorldSession::HandlePetCastSpellOpcode( WorldPacket& recvPacket )
  1460.  {
  1461.      DETAIL_LOG("WORLD: CMSG_PET_CAST_SPELL");
  1462. +    recvPacket.hexlike();
  1463. +    recvPacket.print_storage();
  1464. +
  1465. +    //2 - 0 - 0 - 43 - 129 - 0 - 80 - 241 | - 42 - 211 - 253 - 0 | - 0 | - 2 |- 96 - 0 - 0 - 0 | - 0 - 26
  1466. +    //- 164 - 59 - 196 - 174 - 98 - 131 | - 194 - 182 - 171 - 218| - 67 - 0 - 48 - 93| - 0 - 196 - 32
  1467. +    //- 177| - 242 - 193 - 22 - 110 - 224 - 67 - 203 - 166 | - 68 - 61 - 133 - 1| - 240 - 66 - 1 - 183 |
  1468. +    //- 0 - 0 - 0 - 217| - 2 - 43 - 129 - 80 - 241 - 0 - 10 - 0 - 0 - 0 - 0 - 76 - 109 - 175 - 0
  1469. +    //- 238 - 115 - 58 - 196 - 20 - 110 - 121 - 194 - 187 - 107 - 217 - 67 - 32 - 44 - 27 - 62 - 217
  1470. +    //- 1 - 36 - 129 - 80 - 241 - 0 - 0 - 160 - 64 - 0 - 0 - 160 - 64 - 0 - 0 - 160 - 64 - 192 - 233
  1471. +    //- 172 - 62 - 4 - 0 - 0 - 0 - 7 - 230 - 0 - 0 - 0 -
  1472. +
  1473. +    //5 - 0 - 0 - 43 - 129 - 0 - 80 - 241 | - 85 - 211 - 253 - 0 | - 0 | - 2 | - 96 - 0 - 0 - 0 | - 0 - 69 - 60 - 61
  1474. +    //- 196 - 171 - 248 - 107| - 194 - 8 - 236 - 218 | - 67 - 0 - 177 - 11 | - 46 - 196 - 89 - 16 | - 14 - 195
  1475. +    //- 5 - 38 - 231 - 67 - 23 - 221 | - 110 - 62 - 15 - 3 | - 240 - 66 -| 1 - 183 | - 0 - 0 - 0 - 217 | - 5 - 43
  1476. +    //- 129 - 80 - 241 - 0 - 10 - 0 - 0 - 0 - 0 - 233 - 41 - 203 - 0 - 106 - 207 - 59 - 196 - 179 - 173 - 83
  1477. +    //- 194 - 8 - 108 - 217 - 67 - 127 - 153 - 170 - 64 - 217 - 4 - 36 - 129 - 80 - 241 - 0 - 0 - 160 - 64
  1478. +    //- 0 - 0 - 160 - 64 - 0 - 0 - 160 - 64 - 7 - 77 - 175 - 64 - 4 - 0 - 0 - 0 - 7 - 195 - 0 - 0 - 0 -
  1479.  
  1480.      ObjectGuid guid;
  1481.      uint32 spellid;
  1482. @@ -636,7 +662,10 @@ void WorldSession::HandlePetCastSpellOpcode( WorldPacket& recvPacket )
  1483.  
  1484.      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);
  1485.  
  1486. -    Creature* pet = _player->GetMap()->GetAnyTypeCreature(guid);
  1487. +    if (guid.IsPlayer())
  1488. +        return;
  1489. +
  1490. +    Creature* pet = ObjectAccessor::GetAnyTypeCreature(*_player,guid);
  1491.  
  1492.      if (!pet || (guid != _player->GetPetGuid() && guid != _player->GetCharmGuid()))
  1493.      {
  1494. diff --git a/src/game/Player.cpp b/src/game/Player.cpp
  1495. index 444cf99..4626896 100644
  1496. --- a/src/game/Player.cpp
  1497. +++ b/src/game/Player.cpp
  1498. @@ -459,7 +459,6 @@ Player::Player (WorldSession *session): Unit(), m_mover(this), m_camera(this), m
  1499.      // group is initialized in the reference constructor
  1500.      SetGroupInvite(NULL);
  1501.      m_groupUpdateMask = 0;
  1502. -    m_auraUpdateMask = 0;
  1503.  
  1504.      duel = NULL;
  1505.  
  1506. @@ -1747,6 +1746,11 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati
  1507.          m_movementInfo.ClearTransportData();
  1508.      }
  1509.  
  1510. +    if (GetVehicleKit())
  1511. +        GetVehicleKit()->RemoveAllPassengers();
  1512. +
  1513. +    ExitVehicle();
  1514. +
  1515.      // The player was ported to another map and looses the duel immediately.
  1516.      // We have to perform this check before the teleport, otherwise the
  1517.      // ObjectAccessor won't find the flag.
  1518. @@ -2223,7 +2227,7 @@ Creature* Player::GetNPCIfCanInteractWith(ObjectGuid guid, uint32 npcflagmask)
  1519.          return NULL;
  1520.  
  1521.      // exist (we need look pets also for some interaction (quest/etc)
  1522. -    Creature *unit = GetMap()->GetAnyTypeCreature(guid);
  1523. +    Creature *unit = ObjectAccessor::GetAnyTypeCreature(*this,guid);
  1524.      if (!unit)
  1525.          return NULL;
  1526.  
  1527. @@ -3984,6 +3988,7 @@ void Player::InitVisibleBits()
  1528.      updateVisualBits.SetBit(PLAYER_BYTES_3);
  1529.      updateVisualBits.SetBit(PLAYER_DUEL_TEAM);
  1530.      updateVisualBits.SetBit(PLAYER_GUILD_TIMESTAMP);
  1531. +    updateVisualBits.SetBit(UNIT_NPC_FLAGS);
  1532.  
  1533.      // PLAYER_QUEST_LOG_x also visible bit on official (but only on party/raid)...
  1534.      for(uint16 i = PLAYER_QUEST_LOG_1_1; i < PLAYER_QUEST_LOG_25_2; i += MAX_QUEST_OFFSET)
  1535. @@ -6012,7 +6017,9 @@ ActionButton const* Player::GetActionButton(uint8 button)
  1536.  
  1537.  bool Player::SetPosition(float x, float y, float z, float orientation, bool teleport)
  1538.  {
  1539. -    // prevent crash when a bad coord is sent by the client
  1540. +    if(!Unit::SetPosition(x, y, z, orientation, teleport))
  1541. +        return false;
  1542. +
  1543.      if(!MaNGOS::IsValidMapCoord(x,y,z,orientation))
  1544.      {
  1545.          DEBUG_LOG("Player::SetPosition(%f, %f, %f, %f, %d) .. bad coordinates for player %d!",x,y,z,orientation,teleport,GetGUIDLow());
  1546. @@ -8493,6 +8500,41 @@ void Player::SendInitWorldStates(uint32 zoneid, uint32 areaid)
  1547.              break;
  1548.          case 3703:                                          // Shattrath City
  1549.              break;
  1550. +        case 4384:                                          // SA
  1551. +            /*if (bg && bg->GetTypeID() == BATTLEGROUND_SA)
  1552. +                bg->FillInitialWorldStates(data);
  1553. +            else
  1554. +            {*/
  1555. +                // 1-3 A defend, 4-6 H defend, 7-9 unk defend, 1 - ok, 2 - half destroyed, 3 - destroyed
  1556. +                data << uint32(0xf09) << uint32(0x4);       // 7  3849 Gate of Temple
  1557. +                data << uint32(0xe36) << uint32(0x4);       // 8  3638 Gate of Yellow Moon
  1558. +                data << uint32(0xe27) << uint32(0x4);       // 9  3623 Gate of Green Emerald
  1559. +                data << uint32(0xe24) << uint32(0x4);       // 10 3620 Gate of Blue Sapphire
  1560. +                data << uint32(0xe21) << uint32(0x4);       // 11 3617 Gate of Red Sun
  1561. +                data << uint32(0xe1e) << uint32(0x4);       // 12 3614 Gate of Purple Ametyst
  1562. +
  1563. +                data << uint32(0xdf3) << uint32(0x0);       // 13 3571 bonus timer (1 - on, 0 - off)
  1564. +                data << uint32(0xded) << uint32(0x0);       // 14 3565
Advertisement
Add Comment
Please, Sign In to add comment