aboutsummaryrefslogtreecommitdiff
path: root/src/server/game/Entities
diff options
context:
space:
mode:
authorShauren <shauren.trinity@gmail.com>2012-07-04 22:20:21 +0200
committerShauren <shauren.trinity@gmail.com>2012-07-04 22:20:21 +0200
commited6f3e2deff55f913f9646db5f540b7704088478 (patch)
tree2212558564e685b43214a2ca80aea7014af8e200 /src/server/game/Entities
parent138375c0455fc0c7f1c2fc0e6b94930dea28ae9c (diff)
parentc3cb82b9263331ceaf68ebf69638ce3162b4a934 (diff)
Merge branch 'master' of github.com:TrinityCore/TrinityCore into 4.x
Diffstat (limited to 'src/server/game/Entities')
-rwxr-xr-xsrc/server/game/Entities/Creature/Creature.cpp22
-rwxr-xr-xsrc/server/game/Entities/Creature/Creature.h6
-rwxr-xr-xsrc/server/game/Entities/Creature/TemporarySummon.h1
-rwxr-xr-xsrc/server/game/Entities/GameObject/GameObject.cpp20
-rwxr-xr-xsrc/server/game/Entities/Item/Item.cpp4
-rwxr-xr-xsrc/server/game/Entities/Item/Item.h1
-rwxr-xr-xsrc/server/game/Entities/Item/ItemPrototype.h11
-rwxr-xr-xsrc/server/game/Entities/Object/Object.h12
-rwxr-xr-xsrc/server/game/Entities/Pet/Pet.h1
-rwxr-xr-xsrc/server/game/Entities/Player/Player.cpp207
-rwxr-xr-xsrc/server/game/Entities/Player/Player.h3
-rwxr-xr-xsrc/server/game/Entities/Transport/Transport.cpp33
-rwxr-xr-xsrc/server/game/Entities/Transport/Transport.h2
-rwxr-xr-xsrc/server/game/Entities/Unit/Unit.cpp319
-rwxr-xr-xsrc/server/game/Entities/Unit/Unit.h27
-rwxr-xr-xsrc/server/game/Entities/Vehicle/Vehicle.cpp13
16 files changed, 344 insertions, 338 deletions
diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp
index bbce6cf56c1..cbe6abbdf07 100755
--- a/src/server/game/Entities/Creature/Creature.cpp
+++ b/src/server/game/Entities/Creature/Creature.cpp
@@ -486,7 +486,7 @@ void Creature::Update(uint32 diff)
break;
uint64 dbtableHighGuid = MAKE_NEW_GUID(m_DBTableGuid, GetEntry(), HIGHGUID_UNIT);
- time_t linkedRespawntime = sObjectMgr->GetLinkedRespawnTime(dbtableHighGuid, GetMap()->GetInstanceId());
+ time_t linkedRespawntime = GetMap()->GetLinkedRespawnTime(dbtableHighGuid);
if (!linkedRespawntime) // Can respawn
Respawn();
else // the master is dead
@@ -1303,7 +1303,7 @@ bool Creature::LoadCreatureFromDB(uint32 guid, Map* map, bool addToMap)
m_respawnDelay = data->spawntimesecs;
m_deathState = ALIVE;
- m_respawnTime = sObjectMgr->GetCreatureRespawnTime(m_DBTableGuid, GetInstanceId());
+ m_respawnTime = GetMap()->GetCreatureRespawnTime(m_DBTableGuid);
if (m_respawnTime) // respawn on Update
{
m_deathState = DEAD;
@@ -1398,7 +1398,7 @@ void Creature::DeleteFromDB()
return;
}
- sObjectMgr->RemoveCreatureRespawnTime(m_DBTableGuid, GetInstanceId());
+ GetMap()->RemoveCreatureRespawnTime(m_DBTableGuid);
sObjectMgr->DeleteCreatureData(m_DBTableGuid);
SQLTransaction trans = WorldDatabase.BeginTransaction();
@@ -1598,7 +1598,7 @@ void Creature::Respawn(bool force)
if (getDeathState() == DEAD)
{
if (m_DBTableGuid)
- sObjectMgr->RemoveCreatureRespawnTime(m_DBTableGuid, GetInstanceId());
+ GetMap()->RemoveCreatureRespawnTime(m_DBTableGuid);
sLog->outStaticDebug("Respawning creature %s (GuidLow: %u, Full GUID: " UI64FMTD " Entry: %u)", GetName(), GetGUIDLow(), GetGUID(), GetEntry());
m_respawnTime = 0;
@@ -1676,11 +1676,15 @@ bool Creature::IsImmunedToSpell(SpellInfo const* spellInfo)
// the check of mechanic immunity on DB (tested) because GetCreatureTemplate()->MechanicImmuneMask and m_spellImmune[IMMUNITY_MECHANIC] don't have same data.
bool immunedToAllEffects = true;
for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
+ {
+ if (!spellInfo->Effects[i].IsEffect())
+ continue;
if (!IsImmunedToSpellEffect(spellInfo, i))
{
immunedToAllEffects = false;
break;
}
+ }
if (immunedToAllEffects)
return true;
@@ -1727,6 +1731,8 @@ SpellInfo const* Creature::reachWithSpellAttack(Unit* victim)
break;
}
}
+ if (bcontinue)
+ continue;
if (bcontinue)
continue;
@@ -2014,7 +2020,7 @@ void Creature::SaveRespawnTime()
if (isSummon() || !m_DBTableGuid || (m_creatureData && !m_creatureData->dbData))
return;
- sObjectMgr->SaveCreatureRespawnTime(m_DBTableGuid, GetInstanceId(), m_respawnTime);
+ GetMap()->SaveCreatureRespawnTime(m_DBTableGuid, m_respawnTime);
}
// this should not be called by petAI or
@@ -2458,7 +2464,7 @@ bool Creature::SetWalk(bool enable)
if (!Unit::SetWalk(enable))
return false;
- WorldPacket data(enable ? SMSG_MOVE_SPLINE_SET_WALK_MODE : SMSG_MOVE_SPLINE_SET_RUN_MODE, 9);
+ WorldPacket data(enable ? SMSG_SPLINE_MOVE_SET_WALK_MODE : SMSG_SPLINE_MOVE_SET_RUN_MODE, 9);
data.append(GetPackGUID());
SendMessageToSet(&data, false);
return true;
@@ -2474,7 +2480,7 @@ bool Creature::SetDisableGravity(bool disable, bool packetOnly/*=false*/)
if (!movespline->Initialized())
return true;
- WorldPacket data(disable ? SMSG_MOVE_SPLINE_DISABLE_GRAVITY : SMSG_MOVE_SPLINE_ENABLE_GRAVITY, 9);
+ WorldPacket data(disable ? SMSG_SPLINE_MOVE_GRAVITY_DISABLE : SMSG_SPLINE_MOVE_GRAVITY_ENABLE, 9);
data.append(GetPackGUID());
SendMessageToSet(&data, false);
return true;
@@ -2495,7 +2501,7 @@ bool Creature::SetHover(bool enable)
return true;
//! Not always a packet is sent
- WorldPacket data(enable ? SMSG_MOVE_SPLINE_SET_HOVER : SMSG_MOVE_SPLINE_UNSET_HOVER, 9);
+ WorldPacket data(enable ? SMSG_SPLINE_MOVE_SET_HOVER : SMSG_MOVE_UNSET_HOVER, 9);
data.append(GetPackGUID());
SendMessageToSet(&data, false);
return true;
diff --git a/src/server/game/Entities/Creature/Creature.h b/src/server/game/Entities/Creature/Creature.h
index 906dc827d3f..1824e2c1b44 100755
--- a/src/server/game/Entities/Creature/Creature.h
+++ b/src/server/game/Entities/Creature/Creature.h
@@ -679,6 +679,11 @@ class Creature : public Unit, public GridObject<Creature>, public MapCreature
void GetHomePosition(float &x, float &y, float &z, float &ori) { m_homePosition.GetPosition(x, y, z, ori); }
Position GetHomePosition() { return m_homePosition; }
+ void SetTransportHomePosition(float x, float y, float z, float o) { m_transportHomePosition.Relocate(x, y, z, o); }
+ void SetTransportHomePosition(const Position &pos) { m_transportHomePosition.Relocate(pos); }
+ void GetTransportHomePosition(float &x, float &y, float &z, float &ori) { m_transportHomePosition.GetPosition(x, y, z, ori); }
+ Position GetTransportHomePosition() { return m_transportHomePosition; }
+
uint32 GetWaypointPath(){return m_path_id;}
void LoadPath(uint32 pathid) { m_path_id = pathid; }
@@ -752,6 +757,7 @@ class Creature : public Unit, public GridObject<Creature>, public MapCreature
uint32 m_originalEntry;
Position m_homePosition;
+ Position m_transportHomePosition;
bool DisableReputationGain;
diff --git a/src/server/game/Entities/Creature/TemporarySummon.h b/src/server/game/Entities/Creature/TemporarySummon.h
index 829eb73bf80..537bbd9c099 100755
--- a/src/server/game/Entities/Creature/TemporarySummon.h
+++ b/src/server/game/Entities/Creature/TemporarySummon.h
@@ -36,6 +36,7 @@ class TempSummon : public Creature
Unit* GetSummoner() const;
uint64 GetSummonerGUID() { return m_summonerGUID; }
TempSummonType const& GetSummonType() { return m_type; }
+ uint32 GetTimer() { return m_timer; }
const SummonPropertiesEntry* const m_Properties;
private:
diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp
index 7591359230a..2a74d262daf 100755
--- a/src/server/game/Entities/GameObject/GameObject.cpp
+++ b/src/server/game/Entities/GameObject/GameObject.cpp
@@ -338,7 +338,7 @@ void GameObject::Update(uint32 diff)
if (m_respawnTime <= now) // timer expired
{
uint64 dbtableHighGuid = MAKE_NEW_GUID(m_DBTableGuid, GetEntry(), HIGHGUID_GAMEOBJECT);
- time_t linkedRespawntime = sObjectMgr->GetLinkedRespawnTime(dbtableHighGuid, GetMap()->GetInstanceId());
+ time_t linkedRespawntime = GetMap()->GetLinkedRespawnTime(dbtableHighGuid);
if (linkedRespawntime) // Can't respawn, the master is dead
{
uint64 targetGuid = sObjectMgr->GetLinkedRespawnGuid(dbtableHighGuid);
@@ -761,13 +761,13 @@ bool GameObject::LoadGameObjectFromDB(uint32 guid, Map* map, bool addToMap)
else
{
m_respawnDelayTime = data->spawntimesecs;
- m_respawnTime = sObjectMgr->GetGORespawnTime(m_DBTableGuid, map->GetInstanceId());
+ m_respawnTime = GetMap()->GetGORespawnTime(m_DBTableGuid);
// ready to respawn
if (m_respawnTime && m_respawnTime <= time(NULL))
{
m_respawnTime = 0;
- sObjectMgr->RemoveGORespawnTime(m_DBTableGuid, GetInstanceId());
+ GetMap()->RemoveGORespawnTime(m_DBTableGuid);
}
}
}
@@ -788,7 +788,7 @@ bool GameObject::LoadGameObjectFromDB(uint32 guid, Map* map, bool addToMap)
void GameObject::DeleteFromDB()
{
- sObjectMgr->RemoveGORespawnTime(m_DBTableGuid, GetInstanceId());
+ GetMap()->RemoveGORespawnTime(m_DBTableGuid);
sObjectMgr->DeleteGOData(m_DBTableGuid);
PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_DEL_GAMEOBJECT);
@@ -863,7 +863,7 @@ Unit* GameObject::GetOwner() const
void GameObject::SaveRespawnTime()
{
if (m_goData && m_goData->dbData && m_respawnTime > time(NULL) && m_spawnedByDefault)
- sObjectMgr->SaveGORespawnTime(m_DBTableGuid, GetInstanceId(), m_respawnTime);
+ GetMap()->SaveGORespawnTime(m_DBTableGuid, m_respawnTime);
}
bool GameObject::IsAlwaysVisibleFor(WorldObject const* seer) const
@@ -908,7 +908,7 @@ void GameObject::Respawn()
if (m_spawnedByDefault && m_respawnTime > 0)
{
m_respawnTime = time(NULL);
- sObjectMgr->RemoveGORespawnTime(m_DBTableGuid, GetInstanceId());
+ GetMap()->RemoveGORespawnTime(m_DBTableGuid);
}
}
@@ -1711,7 +1711,13 @@ bool GameObject::IsInRange(float x, float y, float z, float radius) const
void GameObject::EventInform(uint32 eventId)
{
- if (eventId && m_zoneScript)
+ if (!eventId)
+ return;
+
+ if (AI())
+ AI()->EventInform(eventId);
+
+ if (m_zoneScript)
m_zoneScript->ProcessEvent(this, eventId);
}
diff --git a/src/server/game/Entities/Item/Item.cpp b/src/server/game/Entities/Item/Item.cpp
index d973c3ba4f8..248b080bfdd 100755
--- a/src/server/game/Entities/Item/Item.cpp
+++ b/src/server/game/Entities/Item/Item.cpp
@@ -274,7 +274,7 @@ bool Item::Create(uint32 guidlow, uint32 itemid, Player const* owner)
for (uint8 i = 0; i < MAX_ITEM_PROTO_SPELLS; ++i)
SetSpellCharges(i, itemProto->Spells[i].SpellCharges);
- SetUInt32Value(ITEM_FIELD_DURATION, abs(itemProto->Duration));
+ SetUInt32Value(ITEM_FIELD_DURATION, itemProto->Duration);
SetUInt32Value(ITEM_FIELD_CREATE_PLAYED_TIME, 0);
return true;
}
@@ -420,7 +420,7 @@ bool Item::LoadFromDB(uint32 guid, uint64 owner_guid, Field* fields, uint32 entr
// update duration if need, and remove if not need
if ((proto->Duration == 0) != (duration == 0))
{
- SetUInt32Value(ITEM_FIELD_DURATION, abs(proto->Duration));
+ SetUInt32Value(ITEM_FIELD_DURATION, proto->Duration);
need_save = true;
}
diff --git a/src/server/game/Entities/Item/Item.h b/src/server/game/Entities/Item/Item.h
index 54570e9b708..d38e8c32e30 100755
--- a/src/server/game/Entities/Item/Item.h
+++ b/src/server/game/Entities/Item/Item.h
@@ -242,6 +242,7 @@ class Item : public Object
bool IsLocked() const { return !HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAG_UNLOCKED); }
bool IsBag() const { return GetTemplate()->InventoryType == INVTYPE_BAG; }
+ bool IsCurrencyToken() const { return GetTemplate()->IsCurrencyToken(); }
bool IsNotEmptyBag() const;
bool IsBroken() const { return GetUInt32Value(ITEM_FIELD_MAXDURABILITY) > 0 && GetUInt32Value(ITEM_FIELD_DURABILITY) == 0; }
bool CanBeTraded(bool mail = false, bool trade = false) const;
diff --git a/src/server/game/Entities/Item/ItemPrototype.h b/src/server/game/Entities/Item/ItemPrototype.h
index 048da0b231c..2da0e721a20 100755
--- a/src/server/game/Entities/Item/ItemPrototype.h
+++ b/src/server/game/Entities/Item/ItemPrototype.h
@@ -202,6 +202,12 @@ enum ItemFlagsExtra
ITEM_FLAGS_EXTRA_BNET_ACCOUNT_BOUND = 0x00020000,
};
+enum ItemFlagsCustom
+{
+ ITEM_FLAGS_CU_DURATION_REAL_TIME = 0x0001, // Item duration will tick even if player is offline
+ ITEM_FLAGS_CU_IGNORE_QUEST_STATUS = 0x0002, // No quest status will be checked when this item drops
+};
+
enum BAG_FAMILY_MASK
{
BAG_FAMILY_MASK_NONE = 0x00000000,
@@ -641,7 +647,7 @@ struct ItemTemplate
uint32 socketBonus; // id from SpellItemEnchantment.dbc
uint32 GemProperties; // id from GemProperties.dbc
float ArmorDamageModifier;
- int32 Duration; // negative = realtime, positive = ingame time
+ uint32 Duration;
uint32 ItemLimitCategory; // id from ItemLimitCategory.dbc
uint32 HolidayId; // id from Holidays.dbc
float StatScalingFactor;
@@ -661,6 +667,7 @@ struct ItemTemplate
uint32 FoodType;
uint32 MinMoneyLoot;
uint32 MaxMoneyLoot;
+ uint32 FlagsCu;
// helpers
bool CanChangeEquipStateInCombat() const
@@ -683,6 +690,8 @@ struct ItemTemplate
return false;
}
+ bool IsCurrencyToken() const { return BagFamily & BAG_FAMILY_MASK_CURRENCY_TOKENS; }
+
uint32 GetMaxStackSize() const
{
return (Stackable == 2147483647 || Stackable <= 0) ? uint32(0x7FFFFFFF-1) : uint32(Stackable);
diff --git a/src/server/game/Entities/Object/Object.h b/src/server/game/Entities/Object/Object.h
index 0d18a47885f..1a04f7b3053 100755
--- a/src/server/game/Entities/Object/Object.h
+++ b/src/server/game/Entities/Object/Object.h
@@ -34,11 +34,11 @@
#define CONTACT_DISTANCE 0.5f
#define INTERACTION_DISTANCE 5.0f
#define ATTACK_DISTANCE 5.0f
-#define MAX_VISIBILITY_DISTANCE 500.0f // max distance for visible objects
+#define MAX_VISIBILITY_DISTANCE SIZE_OF_GRIDS // max distance for visible objects
#define SIGHT_RANGE_UNIT 50.0f
-#define DEFAULT_VISIBILITY_DISTANCE 90.0f // default visible distance, 90 yards on continents
-#define DEFAULT_VISIBILITY_INSTANCE 120.0f // default visible distance in instances, 120 yards
-#define DEFAULT_VISIBILITY_BGARENAS 180.0f // default visible distance in BG/Arenas, 180 yards
+#define DEFAULT_VISIBILITY_DISTANCE 90.0f // default visible distance, 90 yards on continents
+#define DEFAULT_VISIBILITY_INSTANCE 170.0f // default visible distance in instances, 170 yards
+#define DEFAULT_VISIBILITY_BGARENAS 533.0f // default visible distance in BG/Arenas, roughly 533 yards
#define DEFAULT_WORLD_OBJECT_SIZE 0.388999998569489f // player size, also currently used (correctly?) for any non Unit world objects
#define DEFAULT_COMBAT_REACH 1.5f
@@ -500,13 +500,13 @@ struct MovementInfo
t_seat = -1;
}
- uint32 GetMovementFlags() { return flags; }
+ uint32 GetMovementFlags() const { return flags; }
void SetMovementFlags(uint32 flag) { flags = flag; }
void AddMovementFlag(uint32 flag) { flags |= flag; }
void RemoveMovementFlag(uint32 flag) { flags &= ~flag; }
bool HasMovementFlag(uint32 flag) const { return flags & flag; }
- uint16 GetExtraMovementFlags() { return flags2; }
+ uint16 GetExtraMovementFlags() const { return flags2; }
void AddExtraMovementFlag(uint16 flag) { flags2 |= flag; }
bool HasExtraMovementFlag(uint16 flag) const { return flags2 & flag; }
diff --git a/src/server/game/Entities/Pet/Pet.h b/src/server/game/Entities/Pet/Pet.h
index 6e988a79c29..5759a58a575 100755
--- a/src/server/game/Entities/Pet/Pet.h
+++ b/src/server/game/Entities/Pet/Pet.h
@@ -153,6 +153,7 @@ class Pet : public Guardian
bool HaveInDiet(ItemTemplate const* item) const;
uint32 GetCurrentFoodBenefitLevel(uint32 itemlevel);
void SetDuration(int32 dur) { m_duration = dur; }
+ int32 GetDuration() { return m_duration; }
/*
bool UpdateStats(Stats stat);
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index e8d89110f82..ca017a04200 100755
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -3403,7 +3403,7 @@ void Player::SendInitialSpells()
uint16 spellCooldowns = m_spellCooldowns.size();
data << uint16(spellCooldowns);
- for (SpellCooldowns::const_iterator itr=m_spellCooldowns.begin(); itr != m_spellCooldowns.end(); ++itr)
+ for (SpellCooldowns::const_iterator itr = m_spellCooldowns.begin(); itr != m_spellCooldowns.end(); ++itr)
{
SpellInfo const* sEntry = sSpellMgr->GetSpellInfo(itr->first);
if (!sEntry)
@@ -4828,7 +4828,7 @@ void Player::DeleteFromDB(uint64 playerguid, uint32 accountId, bool updateRealmC
// bones will be deleted by corpse/bones deleting thread shortly
sObjectAccessor->ConvertCorpseForPlayer(playerguid);
- if (uint32 guildId = GetGuildIdFromGuid(playerguid))
+ if (uint32 guildId = GetGuildIdFromDB(playerguid))
if (Guild* guild = sGuildMgr->GetGuildById(guildId))
guild->DeleteMember(guid);
@@ -7270,7 +7270,7 @@ bool Player::RewardHonor(Unit* victim, uint32 groupsize, int32 honor, bool pvpto
uint8 k_level = getLevel();
uint8 k_grey = Trinity::XP::GetGrayLevel(k_level);
- uint8 v_level = plrVictim->getLevel();
+ uint8 v_level = victim->getLevel();
if (v_level <= k_grey)
return false;
@@ -7281,7 +7281,7 @@ bool Player::RewardHonor(Unit* victim, uint32 groupsize, int32 honor, bool pvpto
// [15..28] Horde honor titles and player name
// [29..38] Other title and player name
// [39+] Nothing
- uint32 victim_title = plrVictim->GetUInt32Value(PLAYER_CHOSEN_TITLE);
+ uint32 victim_title = victim->GetUInt32Value(PLAYER_CHOSEN_TITLE);
// Get Killer titles, CharTitlesEntry::bit_index
// Ranks:
// title[1..14] -> rank[5..18]
@@ -7303,10 +7303,10 @@ bool Player::RewardHonor(Unit* victim, uint32 groupsize, int32 honor, bool pvpto
// and those in a lifetime
ApplyModUInt32Value(PLAYER_FIELD_LIFETIME_HONORABLE_KILLS, 1, true);
UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_EARN_HONORABLE_KILL);
- UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HK_CLASS, plrVictim->getClass());
- UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HK_RACE, plrVictim->getRace());
+ UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HK_CLASS, victim->getClass());
+ UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HK_RACE, victim->getRace());
UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILL_AT_AREA, GetAreaId());
- UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILL, 1, 0, plrVictim);
+ UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILL, 1, 0, victim);
}
else
{
@@ -7548,7 +7548,7 @@ uint32 Player::_GetCurrencyWeekCap(const CurrencyTypesEntry* currency) const
return cap;
}
-uint32 Player::GetGuildIdFromGuid(uint64 guid)
+uint32 Player::GetGuildIdFromDB(uint64 guid)
{
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_GET_GUILD_ID);
stmt->setUInt64(0, guid);
@@ -8227,7 +8227,6 @@ void Player::_ApplyItemBonuses(ItemTemplate const* proto, uint8 slot, bool apply
if (CanUseAttackType(attType))
_ApplyWeaponDamage(slot, proto, ssv, apply);
-
}
void Player::_ApplyWeaponDamage(uint8 slot, ItemTemplate const* proto, ScalingStatValuesEntry const* ssv, bool apply)
@@ -9157,7 +9156,6 @@ void Player::SendLoot(uint64 guid, LootType loot_type)
loot->loot_type = loot_type;
WorldPacket data(SMSG_LOOT_RESPONSE, 8 + 1 + 50 + 1 + 1); // we guess size
-
data << uint64(guid);
data << uint8(loot_type);
data << LootView(*loot, this, permission);
@@ -10734,7 +10732,7 @@ InventoryResult Player::CanStoreItem_InSpecificSlot(uint8 bag, uint8 slot, ItemP
return EQUIP_ERR_ITEM_DOESNT_GO_INTO_BAG;
// currencytoken case
- if (slot >= CURRENCYTOKEN_SLOT_START && slot < CURRENCYTOKEN_SLOT_END && !(pProto->BagFamily & BAG_FAMILY_MASK_CURRENCY_TOKENS))
+ if (slot >= CURRENCYTOKEN_SLOT_START && slot < CURRENCYTOKEN_SLOT_END && !(pProto->IsCurrencyToken()))
return EQUIP_ERR_ITEM_DOESNT_GO_INTO_BAG;
// prevent cheating
@@ -11087,7 +11085,7 @@ InventoryResult Player::CanStoreItem(uint8 bag, uint8 slot, ItemPosCountVec &des
return EQUIP_ERR_CANT_CARRY_MORE_OF_THIS;
}
}
- else if (pProto->BagFamily & BAG_FAMILY_MASK_CURRENCY_TOKENS)
+ else if (pProto->IsCurrencyToken())
{
res = CanStoreItem_InInventorySlots(CURRENCYTOKEN_SLOT_START, CURRENCYTOKEN_SLOT_END, dest, pProto, count, false, pItem, bag, slot);
if (res != EQUIP_ERR_OK)
@@ -11254,7 +11252,7 @@ InventoryResult Player::CanStoreItem(uint8 bag, uint8 slot, ItemPosCountVec &des
return EQUIP_ERR_CANT_CARRY_MORE_OF_THIS;
}
}
- else if (pProto->BagFamily & BAG_FAMILY_MASK_CURRENCY_TOKENS)
+ else if (pProto->IsCurrencyToken())
{
res = CanStoreItem_InInventorySlots(CURRENCYTOKEN_SLOT_START, CURRENCYTOKEN_SLOT_END, dest, pProto, count, false, pItem, bag, slot);
if (res != EQUIP_ERR_OK)
@@ -11503,7 +11501,7 @@ InventoryResult Player::CanStoreItems(Item** pItems, int count) const
if (b_found)
continue;
- if (pProto->BagFamily & BAG_FAMILY_MASK_CURRENCY_TOKENS)
+ if (pProto->IsCurrencyToken())
{
for (uint32 t = CURRENCYTOKEN_SLOT_START; t < CURRENCYTOKEN_SLOT_END; ++t)
{
@@ -12755,7 +12753,7 @@ void Player::DestroyItemCount(uint32 item, uint32 count, bool update, bool unequ
{
ItemRemovedQuestCheck(pItem->GetEntry(), count - remcount);
pItem->SetCount(pItem->GetCount() - count + remcount);
- if (IsInWorld() & update)
+ if (IsInWorld() && update)
pItem->SendUpdateToPlayer(this);
pItem->SetState(ITEM_CHANGED, this);
return;
@@ -12783,7 +12781,7 @@ void Player::DestroyItemCount(uint32 item, uint32 count, bool update, bool unequ
{
ItemRemovedQuestCheck(pItem->GetEntry(), count - remcount);
pItem->SetCount(pItem->GetCount() - count + remcount);
- if (IsInWorld() & update)
+ if (IsInWorld() && update)
pItem->SendUpdateToPlayer(this);
pItem->SetState(ITEM_CHANGED, this);
return;
@@ -12849,7 +12847,7 @@ void Player::DestroyItemCount(uint32 item, uint32 count, bool update, bool unequ
{
ItemRemovedQuestCheck(pItem->GetEntry(), count - remcount);
pItem->SetCount(pItem->GetCount() - count + remcount);
- if (IsInWorld() & update)
+ if (IsInWorld() && update)
pItem->SendUpdateToPlayer(this);
pItem->SetState(ITEM_CHANGED, this);
return;
@@ -12924,6 +12922,11 @@ Item* Player::GetItemByEntry(uint32 entry) const
if (pItem->GetEntry() == entry)
return pItem;
+ for (uint8 i = KEYRING_SLOT_START; i < CURRENCYTOKEN_SLOT_END; ++i)
+ if (Item* pItem = GetItemByPos(INVENTORY_SLOT_BAG_0, i))
+ if (pItem->GetEntry() == entry)
+ return pItem;
+
for (int i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; ++i)
if (Bag* pBag = GetBagByPos(i))
for (uint32 j = 0; j < pBag->GetBagSize(); ++j)
@@ -12957,7 +12960,7 @@ void Player::DestroyItemCount(Item* pItem, uint32 &count, bool update)
ItemRemovedQuestCheck(pItem->GetEntry(), count);
pItem->SetCount(pItem->GetCount() - count);
count = 0;
- if (IsInWorld() & update)
+ if (IsInWorld() && update)
pItem->SendUpdateToPlayer(this);
pItem->SetState(ITEM_CHANGED, this);
}
@@ -13545,9 +13548,9 @@ void Player::SendEquipError(InventoryResult msg, Item* pItem, Item* pItem2, uint
}
case EQUIP_ERR_EVENT_AUTOEQUIP_BIND_CONFIRM: // no idea about this one...
{
- data << uint64(0);
- data << uint32(0);
- data << uint64(0);
+ data << uint64(0); // item guid
+ data << uint32(0); // slot
+ data << uint64(0); // container
break;
}
case EQUIP_ERR_ITEM_MAX_LIMIT_CATEGORY_COUNT_EXCEEDED:
@@ -13653,7 +13656,7 @@ void Player::UpdateItemDuration(uint32 time, bool realtimeonly)
Item* item = *itr;
++itr; // current element can be erased in UpdateDuration
- if ((realtimeonly && item->GetTemplate()->Duration < 0) || !realtimeonly)
+ if (!realtimeonly || item->GetTemplate()->FlagsCu & ITEM_FLAGS_CU_DURATION_REAL_TIME)
item->UpdateDuration(this, time);
}
}
@@ -14226,7 +14229,7 @@ void Player::SendNewItem(Item* item, uint32 count, bool received, bool created,
data << uint64(GetGUID()); // player GUID
data << uint32(received); // 0=looted, 1=from npc
data << uint32(created); // 0=received, 1=created
- data << uint32(1); // always 0x01 (probably meant to be count of listed items)
+ data << uint32(1); // bool print error to chat
data << uint8(item->GetBagSlot()); // bagslot
// item slot, but when added to stack: 0xFFFFFFFF
data << uint32((item->GetCount() == count) ? item->GetSlot() : -1);
@@ -20160,8 +20163,10 @@ void Player::PetSpellInitialize()
WorldPacket data(SMSG_PET_SPELLS, 8+2+4+4+4*MAX_UNIT_ACTION_BAR_INDEX+1+1);
data << uint64(pet->GetGUID());
data << uint16(pet->GetCreatureTemplate()->family); // creature family (required for pet talents)
- data << uint32(0);
- data << uint8(pet->GetReactState()) << uint8(charmInfo->GetCommandState()) << uint16(0);
+ data << uint32(pet->GetDuration());
+ data << uint8(pet->GetReactState());
+ data << uint8(charmInfo->GetCommandState());
+ data << uint16(0); // Flags, mostly unknown
// action bar loop
charmInfo->BuildActionBar(&data);
@@ -20194,22 +20199,33 @@ void Player::PetSpellInitialize()
for (CreatureSpellCooldowns::const_iterator itr = pet->m_CreatureSpellCooldowns.begin(); itr != pet->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
- }
+ SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(itr->first);
+ if (!spellInfo)
+ {
+ data << uint32(0);
+ data << uint16(0);
+ data << uint32(0);
+ data << uint32(0);
+ continue;
+ }
- for (CreatureSpellCooldowns::const_iterator itr = pet->m_CreatureCategoryCooldowns.begin(); itr != pet->m_CreatureCategoryCooldowns.end(); ++itr)
- {
time_t cooldown = (itr->second > curTime) ? (itr->second - curTime) * IN_MILLISECONDS : 0;
+ data << uint32(itr->first); // spell ID
- data << uint32(itr->first); // spellid
- data << uint16(0); // spell category?
- data << uint32(0); // cooldown
- data << uint32(cooldown); // category cooldown
+ CreatureSpellCooldowns::const_iterator categoryitr = pet->m_CreatureCategoryCooldowns.find(spellInfo->Category);
+ if (categoryitr != pet->m_CreatureCategoryCooldowns.end())
+ {
+ time_t categoryCooldown = (categoryitr->second > curTime) ? (categoryitr->second - curTime) * IN_MILLISECONDS : 0;
+ data << uint16(spellInfo->Category); // spell category
+ data << uint32(cooldown); // spell cooldown
+ data << uint32(categoryCooldown); // category cooldown
+ }
+ else
+ {
+ data << uint16(0);
+ data << uint32(cooldown);
+ data << uint32(0);
+ }
}
GetSession()->SendPacket(&data);
@@ -20245,24 +20261,24 @@ void Player::PossessSpellInitialize()
void Player::VehicleSpellInitialize()
{
- Creature* veh = GetVehicleCreatureBase();
- if (!veh)
+ Creature* vehicle = GetVehicleCreatureBase();
+ if (!vehicle)
return;
- uint8 cooldownCount = veh->m_CreatureSpellCooldowns.size() + veh->m_CreatureCategoryCooldowns.size();
+ uint8 cooldownCount = vehicle->m_CreatureSpellCooldowns.size();
WorldPacket data(SMSG_PET_SPELLS, 8 + 2 + 4 + 4 + 4 * 10 + 1 + 1 + cooldownCount * (4 + 2 + 4 + 4));
- data << uint64(veh->GetGUID());
- data << uint16(veh->GetCreatureTemplate()->family);
- data << uint32(0);
- // The following three segments are read as one uint32
- data << uint8(veh->GetReactState());
- data << uint8(0); // CommandState?
- data << uint16(0); // unk
+ data << uint64(vehicle->GetGUID()); // Guid
+ data << uint16(0); // Pet Family (0 for all vehicles)
+ data << uint32(vehicle->isSummon() ? vehicle->ToTempSummon()->GetTimer() : 0); // Duration
+ // The following three segments are read by the client as one uint32
+ data << uint8(vehicle->GetReactState()); // React State
+ data << uint8(0); // Command State
+ data << uint16(0x800); // DisableActions (set for all vehicles)
for (uint32 i = 0; i < CREATURE_MAX_SPELLS; ++i)
{
- uint32 spellId = veh->m_spells[i];
+ uint32 spellId = vehicle->m_spells[i];
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId);
if (!spellInfo)
{
@@ -20270,54 +20286,59 @@ void Player::VehicleSpellInitialize()
continue;
}
- ConditionList conditions = sConditionMgr->GetConditionsForVehicleSpell(veh->GetEntry(), spellId);
- if (!sConditionMgr->IsObjectMeetToConditions(this, veh, conditions))
+ ConditionList conditions = sConditionMgr->GetConditionsForVehicleSpell(vehicle->GetEntry(), spellId);
+ if (!sConditionMgr->IsObjectMeetToConditions(this, vehicle, conditions))
{
- sLog->outDebug(LOG_FILTER_CONDITIONSYS, "VehicleSpellInitialize: conditions not met for Vehicle entry %u spell %u", veh->ToCreature()->GetEntry(), spellId);
+ sLog->outDebug(LOG_FILTER_CONDITIONSYS, "VehicleSpellInitialize: conditions not met for Vehicle entry %u spell %u", vehicle->ToCreature()->GetEntry(), spellId);
data << uint16(0) << uint8(0) << uint8(i+8);
continue;
}
if (spellInfo->IsPassive())
- {
- veh->CastSpell(veh, spellId, true);
- data << uint16(0) << uint8(0) << uint8(i+8);
- }
- else
- data << uint32(MAKE_UNIT_ACTION_BUTTON(spellId, i+8));
+ vehicle->CastSpell(vehicle, spellId, true);
+
+ data << uint32(MAKE_UNIT_ACTION_BUTTON(spellId, i+8));
}
for (uint32 i = CREATURE_MAX_SPELLS; i < MAX_SPELL_CONTROL_BAR; ++i)
- data << uint16(0) << uint8(0) << uint8(i+8);
+ data << uint32(0);
- data << uint8(0);
- /*if (v23 > 0)
- {
- for (uint32 i = 0; i < v23; ++i)
- data << uint32(v16); // Some spellid?
- }*/
+ data << uint8(0); // Auras?
// Cooldowns
- data << cooldownCount;
+ data << uint8(cooldownCount);
time_t now = sWorld->GetGameTime();
- CreatureSpellCooldowns::const_iterator itr;
- for (itr = veh->m_CreatureSpellCooldowns.begin(); itr != veh->m_CreatureSpellCooldowns.end(); ++itr)
- {
- time_t cooldown = (itr->second > now) ? (itr->second - now) * IN_MILLISECONDS : 0;
- data << uint32(itr->first); // SpellId
- data << uint16(0); // unk
- data << uint32(cooldown); // spell cooldown
- data << uint32(0); // category cooldown
- }
- for (itr = veh->m_CreatureCategoryCooldowns.begin(); itr != veh->m_CreatureCategoryCooldowns.end(); ++itr)
+ for (CreatureSpellCooldowns::const_iterator itr = vehicle->m_CreatureSpellCooldowns.begin(); itr != vehicle->m_CreatureSpellCooldowns.end(); ++itr)
{
+ SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(itr->first);
+ if (!spellInfo)
+ {
+ data << uint32(0);
+ data << uint16(0);
+ data << uint32(0);
+ data << uint32(0);
+ continue;
+ }
+
time_t cooldown = (itr->second > now) ? (itr->second - now) * IN_MILLISECONDS : 0;
- data << uint32(itr->first); // SpellId
- data << uint16(0); // unk
- data << uint32(0); // spell cooldown
- data << uint32(cooldown); // category cooldown
+ data << uint32(itr->first); // spell ID
+
+ CreatureSpellCooldowns::const_iterator categoryitr = vehicle->m_CreatureCategoryCooldowns.find(spellInfo->Category);
+ if (categoryitr != vehicle->m_CreatureCategoryCooldowns.end())
+ {
+ time_t categoryCooldown = (categoryitr->second > now) ? (categoryitr->second - now) * IN_MILLISECONDS : 0;
+ data << uint16(spellInfo->Category); // spell category
+ data << uint32(cooldown); // spell cooldown
+ data << uint32(categoryCooldown); // category cooldown
+ }
+ else
+ {
+ data << uint16(0);
+ data << uint32(cooldown);
+ data << uint32(0);
+ }
}
GetSession()->SendPacket(&data);
@@ -20356,7 +20377,7 @@ void Player::CharmSpellInitialize()
if (charm->GetTypeId() != TYPEID_PLAYER)
data << uint8(charm->ToCreature()->GetReactState()) << uint8(charmInfo->GetCommandState()) << uint16(0);
else
- data << uint8(0) << uint8(0) << uint16(0);
+ data << uint32(0);
charmInfo->BuildActionBar(&data);
@@ -20581,7 +20602,7 @@ void Player::RemovePetitionsAndSigns(uint64 guid, uint32 type)
else
{
stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_PETITION_SIG_BY_GUID_TYPE);
- stmt->setUInt8(0, uint8(type));
+ stmt->setUInt8(1, uint8(type));
}
stmt->setUInt32(0, GUID_LOPART(guid));
@@ -22319,8 +22340,8 @@ void Player::SendInstanceResetWarning(uint32 mapid, Difficulty difficulty, uint3
data << uint32(time);
if (type == RAID_INSTANCE_WELCOME)
{
- data << uint8(0); // is your (1)
- data << uint8(0); // is extended (1), ignored if prev field is 0
+ data << uint8(0); // is locked
+ data << uint8(0); // is extended, ignored if prev field is 0
}
GetSession()->SendPacket(&data);
}
@@ -23366,7 +23387,7 @@ Player* Player::GetNextRandomRaidMember(float radius)
PartyResult Player::CanUninviteFromGroup() const
{
- const Group* grp = GetGroup();
+ Group const* grp = GetGroup();
if (!grp)
return ERR_NOT_IN_GROUP;
@@ -23389,8 +23410,12 @@ PartyResult Player::CanUninviteFromGroup() const
if (grp->isRollLootActive())
return ERR_PARTY_LFG_BOOT_LOOT_ROLLS;
+ // TODO: Should also be sent when anyone has recently left combat, with an aprox ~5 seconds timer.
+ for (GroupReference const* itr = grp->GetFirstMember(); itr != NULL; itr = itr->next())
+ if (itr->getSource() && itr->getSource()->isInCombat())
+ return ERR_PARTY_LFG_BOOT_IN_COMBAT;
+
/* Missing support for these types
- return ERR_PARTY_LFG_BOOT_IN_COMBAT; // also have a cooldown (some secs after combat finish
return ERR_PARTY_LFG_BOOT_COOLDOWN_S;
return ERR_PARTY_LFG_BOOT_NOT_ELIGIBLE_S;
*/
@@ -25639,8 +25664,8 @@ void Player::SendMovementSetCanFly(bool apply)
void Player::SendMovementSetCanTransitionBetweenSwimAndFly(bool apply)
{
WorldPacket data(apply ?
- SMSG_MOVE_ENABLE_TRANSITION_BETWEEN_SWIM_AND_FLY :
- SMSG_MOVE_DISABLE_TRANSITION_BETWEEN_SWIM_AND_FLY, 12);
+ SMSG_MOVE_SET_CAN_TRANSITION_BETWEEN_SWIM_AND_FLY :
+ SMSG_MOVE_UNSET_CAN_TRANSITION_BETWEEN_SWIM_AND_FLY, 12);
data.append(GetPackGUID());
data << uint32(0); //! movement counter
SendDirectMessage(&data);
@@ -25648,7 +25673,7 @@ void Player::SendMovementSetCanTransitionBetweenSwimAndFly(bool apply)
void Player::SendMovementSetHover(bool apply)
{
- WorldPacket data(apply ? SMSG_MOVE_SET_HOVERING : SMSG_MOVE_SPLINE_UNSET_HOVER, 12);
+ WorldPacket data(apply ? SMSG_MOVE_SET_HOVER : SMSG_MOVE_UNSET_HOVER, 12);
data.append(GetPackGUID());
data << uint32(0); //! movement counter
SendDirectMessage(&data);
@@ -25656,7 +25681,7 @@ void Player::SendMovementSetHover(bool apply)
void Player::SendMovementSetWaterWalking(bool apply)
{
- WorldPacket data(apply ? SMSG_MOVE_SET_WATER_WALK : SMSG_MOVE_SET_LAND_WALK, 12);
+ WorldPacket data(apply ? SMSG_MOVE_WATER_WALK : SMSG_MOVE_LAND_WALK, 12);
data.append(GetPackGUID());
data << uint32(0); //! movement counter
SendDirectMessage(&data);
@@ -25664,7 +25689,7 @@ void Player::SendMovementSetWaterWalking(bool apply)
void Player::SendMovementSetFeatherFall(bool apply)
{
- WorldPacket data(apply ? SMSG_MOVE_SET_FEATHER_FALL : SMSG_MOVE_SET_NORMAL_FALL, 12);
+ WorldPacket data(apply ? SMSG_MOVE_FEATHER_FALL : SMSG_MOVE_NORMAL_FALL, 12);
data.append(GetPackGUID());
data << uint32(0); //! movement counter
SendDirectMessage(&data);
diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h
index 24a1c35b8e2..dbe9cd94a21 100755
--- a/src/server/game/Entities/Player/Player.h
+++ b/src/server/game/Entities/Player/Player.h
@@ -1888,7 +1888,7 @@ class Player : public Unit, public GridObject<Player>
m_guildId = GuildId;
}
uint32 GetGuildId() { return m_guildId; }
- static uint32 GetGuildIdFromGuid(uint64 guid);
+ static uint32 GetGuildIdFromDB(uint64 guid);
void SetRank(uint8 rankId) { SetUInt32Value(PLAYER_GUILDRANK, rankId); }
uint8 GetRank() { return uint8(GetUInt32Value(PLAYER_GUILDRANK)); }
@@ -2049,6 +2049,7 @@ class Player : public Unit, public GridObject<Player>
StopMirrorTimer(BREATH_TIMER);
StopMirrorTimer(FIRE_TIMER);
}
+ bool IsMirrorTimerActive(MirrorTimerType type) { return m_MirrorTimer[type] == getMaxTimer(type); }
void SetMovement(PlayerMovementType pType);
diff --git a/src/server/game/Entities/Transport/Transport.cpp b/src/server/game/Entities/Transport/Transport.cpp
index a00fcae1e09..ef3e1331a4c 100755
--- a/src/server/game/Entities/Transport/Transport.cpp
+++ b/src/server/game/Entities/Transport/Transport.cpp
@@ -656,6 +656,7 @@ uint32 Transport::AddNPCPassenger(uint32 tguid, uint32 entry, float x, float y,
o + GetOrientation());
creature->SetHomePosition(creature->GetPositionX(), creature->GetPositionY(), creature->GetPositionZ(), creature->GetOrientation());
+ creature->SetTransportHomePosition(creature->m_movementInfo.t_pos);
if (!creature->IsPositionValid())
{
@@ -698,11 +699,33 @@ void Transport::UpdateNPCPositions()
Creature* npc = *itr;
float x, y, z, o;
- o = GetOrientation() + npc->m_movementInfo.t_pos.m_orientation;
- x = GetPositionX() + (npc->m_movementInfo.t_pos.m_positionX * cos(GetOrientation()) + npc->m_movementInfo.t_pos.m_positionY * sin(GetOrientation() + M_PI));
- y = GetPositionY() + (npc->m_movementInfo.t_pos.m_positionY * cos(GetOrientation()) + npc->m_movementInfo.t_pos.m_positionX * sin(GetOrientation()));
- z = GetPositionZ() + npc->m_movementInfo.t_pos.m_positionZ;
- npc->SetHomePosition(x, y, z, o);
+ npc->m_movementInfo.t_pos.GetPosition(x, y, z, o);
+ CalculatePassengerPosition(x, y, z, o);
GetMap()->CreatureRelocation(npc, x, y, z, o, false);
+ npc->GetTransportHomePosition(x, y, z, o);
+ CalculatePassengerPosition(x, y, z, o);
+ npc->SetHomePosition(x, y, z, o);
}
}
+
+//! This method transforms supplied transport offsets into global coordinates
+void Transport::CalculatePassengerPosition(float& x, float& y, float& z, float& o)
+{
+ float inx = x, iny = y, inz = z, ino = o;
+ o = GetOrientation() + ino;
+ x = GetPositionX() + (inx * cos(GetOrientation()) + iny * sin(GetOrientation() + M_PI));
+ y = GetPositionY() + (iny * cos(GetOrientation()) + inx * sin(GetOrientation()));
+ z = GetPositionZ() + inz;
+}
+
+//! This method transforms supplied global coordinates into local offsets
+void Transport::CalculatePassengerOffset(float& x, float& y, float& z, float& o)
+{
+ o -= GetOrientation();
+ z -= GetPositionZ();
+ y -= GetPositionY(); // y = searchedY * cos(o) + searchedX * sin(o)
+ x -= GetPositionX(); // x = searchedX * cos(o) + searchedY * sin(o + pi)
+ float inx = x, iny = y;
+ y = (iny - inx * tan(GetOrientation())) / (cos(GetOrientation()) - sin(GetOrientation() + M_PI) * tan(GetOrientation()));
+ x = (inx - iny * sin(GetOrientation() + M_PI) / cos(GetOrientation())) / (cos(GetOrientation()) - tan(GetOrientation()) * sin(GetOrientation() + M_PI));
+}
diff --git a/src/server/game/Entities/Transport/Transport.h b/src/server/game/Entities/Transport/Transport.h
index 518dcf6359d..4b0c42c9071 100755
--- a/src/server/game/Entities/Transport/Transport.h
+++ b/src/server/game/Entities/Transport/Transport.h
@@ -47,6 +47,8 @@ class Transport : public GameObject
uint32 AddNPCPassenger(uint32 tguid, uint32 entry, float x, float y, float z, float o, uint32 anim=0);
void UpdatePosition(MovementInfo* mi);
void UpdateNPCPositions();
+ void CalculatePassengerPosition(float& x, float& y, float& z, float& o);
+ void CalculatePassengerOffset(float& x, float& y, float& z, float& o);
void BuildStartMovePacket(Map const* targetMap);
void BuildStopMovePacket(Map const* targetMap);
uint32 GetScriptId() const { return ScriptId; }
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index 347a51a67d9..3f1b67a4738 100755
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -396,10 +396,25 @@ void Unit::UpdateSplineMovement(uint32 t_diff)
m_movesplineTimer.Reset(POSITION_UPDATE_DELAY);
Movement::Location loc = movespline->ComputePosition();
- if (GetTypeId() == TYPEID_PLAYER)
- ((Player*)this)->UpdatePosition(loc.x,loc.y,loc.z,loc.orientation);
- else
- GetMap()->CreatureRelocation((Creature*)this,loc.x,loc.y,loc.z,loc.orientation);
+ if (HasUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT))
+ {
+ Position& pos = m_movementInfo.t_pos;
+ pos.m_positionX = loc.x;
+ pos.m_positionY = loc.y;
+ pos.m_positionZ = loc.z;
+ pos.m_orientation = loc.orientation;
+ if (Unit* vehicle = GetVehicleBase())
+ {
+ loc.x += vehicle->GetPositionX();
+ loc.y += vehicle->GetPositionY();
+ loc.z += vehicle->GetPositionZMinusOffset();
+ loc.orientation = vehicle->GetOrientation();
+ }
+ else if (Transport* trans = GetTransport())
+ trans->CalculatePassengerPosition(loc.x, loc.y, loc.z, loc.orientation);
+ }
+
+ UpdatePosition(loc.x, loc.y, loc.z, loc.orientation);
}
}
@@ -409,50 +424,6 @@ void Unit::DisableSpline()
movespline->_Interrupt();
}
-void Unit::SendMonsterMoveExitVehicle(Position const* newPos)
-{
- WorldPacket data(SMSG_MONSTER_MOVE, 1+12+4+1+4+4+4+12+GetPackGUID().size());
- data.append(GetPackGUID());
-
- data << uint8(GetTypeId() == TYPEID_PLAYER ? 1 : 0); // new in 3.1, bool
- data << GetPositionX() << GetPositionY() << GetPositionZ();
- data << getMSTime();
-
- data << uint8(SPLINETYPE_FACING_ANGLE);
- data << float(GetOrientation()); // guess
- data << uint32(SPLINEFLAG_EXIT_VEHICLE);
- data << uint32(0); // Time in between points
- data << uint32(1); // 1 single waypoint
- data << newPos->GetPositionX();
- data << newPos->GetPositionY();
- data << newPos->GetPositionZ();
-
- SendMessageToSet(&data, true);
-}
-
-void Unit::SendMonsterMoveTransport(Unit* vehicleOwner)
-{
- // TODO: Turn into BuildMonsterMoveTransport packet and allow certain variables (for npc movement aboard vehicles)
- WorldPacket data(SMSG_MONSTER_MOVE_TRANSPORT, GetPackGUID().size()+vehicleOwner->GetPackGUID().size() + 47);
- data.append(GetPackGUID());
- data.append(vehicleOwner->GetPackGUID());
- data << int8(GetTransSeat());
- data << uint8(0);
- data << GetPositionX() - vehicleOwner->GetPositionX();
- data << GetPositionY() - vehicleOwner->GetPositionY();
- data << GetPositionZ() - vehicleOwner->GetPositionZ();
- data << uint32(getMSTime()); // should be an increasing constant that indicates movement packet count
- data << uint8(SPLINETYPE_FACING_ANGLE);
- data << GetTransOffsetO(); // facing angle?
- data << uint32(SPLINEFLAG_TRANSPORT);
- data << uint32(GetTransTime()); // move time
- data << uint32(1); // amount of waypoints
- data << uint32(0); // waypoint X
- data << uint32(0); // waypoint Y
- data << uint32(0); // waypoint Z
- SendMessageToSet(&data, true);
-}
-
void Unit::resetAttackTimer(WeaponAttackType type)
{
m_attackTimer[type] = uint32(GetAttackTime(type) * m_modAttackSpeedPct[type]);
@@ -556,13 +527,7 @@ void Unit::DealDamageMods(Unit* victim, uint32 &damage, uint32* absorb)
if (absorb)
*absorb += damage;
damage = 0;
- return;
}
-
- uint32 originalDamage = damage;
-
- if (absorb && originalDamage > damage)
- *absorb += (originalDamage - damage);
}
uint32 Unit::DealDamage(Unit* victim, uint32 damage, CleanDamage const* cleanDamage, DamageEffectType damagetype, SpellSchoolMask damageSchoolMask, SpellInfo const* spellProto, bool durabilityLoss)
@@ -839,11 +804,6 @@ void Unit::CastSpell(SpellCastTargets const& targets, SpellInfo const* spellInfo
return;
}
- // TODO: this is a workaround and needs removal
- if (!originalCaster && GetTypeId() == TYPEID_UNIT && ToCreature()->isTotem() && IsControlledByPlayer())
- if (Unit* owner = GetOwner())
- originalCaster=owner->GetGUID();
-
// TODO: this is a workaround - not needed anymore, but required for some scripts :(
if (!originalCaster && triggeredByAura)
originalCaster = triggeredByAura->GetCasterGUID();
@@ -2503,12 +2463,12 @@ SpellMissInfo Unit::MagicSpellHitResult(Unit* victim, SpellInfo const* spell)
// Chance resist debuff
if (!spell->IsPositive())
{
- bool bNegativeAura = false;
+ bool bNegativeAura = true;
for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
{
- if (spell->Effects[i].ApplyAuraName != 0)
+ if (spell->Effects[i].ApplyAuraName == 0)
{
- bNegativeAura = true;
+ bNegativeAura = false;
break;
}
}
@@ -2931,9 +2891,11 @@ void Unit::SetCurrentCastedSpell(Spell* pSpell)
InterruptSpell(CURRENT_AUTOREPEAT_SPELL);
m_AutoRepeatFirstCast = true;
}
- AddUnitState(UNIT_STATE_CASTING);
- } break;
+ if (pSpell->m_spellInfo->CalcCastTime(this) > 0)
+ AddUnitState(UNIT_STATE_CASTING);
+ break;
+ }
case CURRENT_CHANNELED_SPELL:
{
// channel spells always break generic non-delayed and any channeled spells
@@ -2945,8 +2907,9 @@ void Unit::SetCurrentCastedSpell(Spell* pSpell)
m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->m_spellInfo->Id != 75)
InterruptSpell(CURRENT_AUTOREPEAT_SPELL);
AddUnitState(UNIT_STATE_CASTING);
- } break;
+ break;
+ }
case CURRENT_AUTOREPEAT_SPELL:
{
// only Auto Shoot does not break anything
@@ -2958,12 +2921,11 @@ void Unit::SetCurrentCastedSpell(Spell* pSpell)
}
// special action: set first cast flag
m_AutoRepeatFirstCast = true;
- } break;
+ break;
+ }
default:
- {
- // other spell types don't break anything now
- } break;
+ break; // other spell types don't break anything now
}
// current spell (if it is still here) may be safely deleted now
@@ -3638,87 +3600,6 @@ void Unit::RemoveAurasDueToSpellByDispel(uint32 spellId, uint32 dispellerSpellId
// Call AfterDispel hook on AuraScript
aura->CallScriptAfterDispel(&dispelInfo);
- switch (aura->GetSpellInfo()->SpellFamilyName)
- {
- case SPELLFAMILY_WARLOCK:
- {
- // Unstable Affliction (crash if before removeaura?)
- if (aura->GetSpellInfo()->SpellFamilyFlags[1] & 0x0100)
- {
- Unit* caster = aura->GetCaster();
- if (!caster)
- break;
- if (AuraEffect const* aurEff = aura->GetEffect(EFFECT_0))
- {
- int32 damage = aurEff->GetAmount() * 9;
- // backfire damage and silence
- caster->CastCustomSpell(dispeller, 31117, &damage, NULL, NULL, true, NULL, aurEff);
- }
- }
- break;
- }
- case SPELLFAMILY_DRUID:
- {
- // Lifebloom
- if (aura->GetSpellInfo()->SpellFamilyFlags[1] & 0x10)
- {
- if (AuraEffect const* aurEff = aura->GetEffect(EFFECT_1))
- {
- // final heal
- int32 healAmount = aurEff->GetAmount();
- if (Unit* caster = aura->GetCaster())
- {
- healAmount = caster->SpellHealingBonusDone(this, aura->GetSpellInfo(), healAmount, HEAL, dispelInfo.GetRemovedCharges());
- healAmount = this->SpellHealingBonusTaken(caster, aura->GetSpellInfo(), healAmount, HEAL, dispelInfo.GetRemovedCharges());
- }
- CastCustomSpell(this, 33778, &healAmount, NULL, NULL, true, NULL, NULL, aura->GetCasterGUID());
-
- // mana
- if (Unit* caster = aura->GetCaster())
- {
- int32 mana = CalculatePctU(caster->GetCreateMana(), aura->GetSpellInfo()->ManaCostPercentage) * chargesRemoved / 2;
- caster->CastCustomSpell(caster, 64372, &mana, NULL, NULL, true, NULL, NULL, aura->GetCasterGUID());
- }
- }
- }
- break;
- }
- case SPELLFAMILY_SHAMAN:
- {
- // Flame Shock
- if (aura->GetSpellInfo()->SpellFamilyFlags[0] & 0x10000000)
- {
- if (Unit* caster = aura->GetCaster())
- {
- uint32 triggeredSpellId = 0;
- // Lava Flows
- if (AuraEffect const* aurEff = caster->GetDummyAuraEffect(SPELLFAMILY_SHAMAN, 3087, 0))
- {
- switch (aurEff->GetId())
- {
- case 51482: // Rank 3
- triggeredSpellId = 65264;
- break;
- case 51481: // Rank 2
- triggeredSpellId = 65263;
- break;
- case 51480: // Rank 1
- triggeredSpellId = 64694;
- break;
- default:
- sLog->outError("Unit::RemoveAurasDueToSpellByDispel: Unknown rank of Lava Flows (%d) found", aurEff->GetId());
- }
- }
-
- if (triggeredSpellId)
- caster->CastSpell(caster, triggeredSpellId, true);
- }
- }
- break;
- }
- default:
- break;
- }
return;
}
else
@@ -8328,6 +8209,14 @@ bool Unit::HandleProcTriggerSpell(Unit* victim, uint32 damage, AuraEffect* trigg
CastSpell(victim, 27526, true, castItem, triggeredByAura);
return true;
}
+ // Evasive Maneuvers
+ case 50240:
+ {
+ // Remove a Evasive Charge
+ Aura* charge = GetAura(50241);
+ if (charge->ModStackAmount(-1, AURA_REMOVE_BY_ENEMY_SPELL))
+ RemoveAurasDueToSpell(50240);
+ }
}
break;
case SPELLFAMILY_MAGE:
@@ -8982,12 +8871,6 @@ bool Unit::HandleProcTriggerSpell(Unit* victim, uint32 damage, AuraEffect* trigg
CastSpell(this, 70721, true);
break;
}
- // Bloodthirst (($m/100)% of max health)
- case 23880:
- {
- basepoints0 = int32(CountPctFromMaxHealth(triggerAmount));
- break;
- }
// Shamanistic Rage triggered spell
case 30824:
{
@@ -10159,7 +10042,7 @@ Unit* Unit::GetMagicHitRedirectTarget(Unit* victim, SpellInfo const* spellInfo)
Unit::AuraEffectList const& magnetAuras = victim->GetAuraEffectsByType(SPELL_AURA_SPELL_MAGNET);
for (Unit::AuraEffectList::const_iterator itr = magnetAuras.begin(); itr != magnetAuras.end(); ++itr)
{
- if (Unit* magnet = (*itr)->GetBase()->GetUnitOwner())
+ if (Unit* magnet = (*itr)->GetBase()->GetCaster())
if (spellInfo->CheckExplicitTarget(this, magnet) == SPELL_CAST_OK
&& spellInfo->CheckTarget(this, magnet, false) == SPELL_CAST_OK
&& _IsValidAttackTarget(magnet, spellInfo)
@@ -10801,6 +10684,15 @@ uint32 Unit::SpellDamageBonusTaken(Unit* caster, SpellInfo const* spellProto, ui
int32 TakenTotal = 0;
float TakenTotalMod = 1.0f;
+ float TakenTotalCasterMod = 0.0f;
+
+ // get all auras from caster that allow the spell to ignore resistance (sanctified wrath)
+ AuraEffectList const& IgnoreResistAuras = caster->GetAuraEffectsByType(SPELL_AURA_MOD_IGNORE_TARGET_RESIST);
+ for (AuraEffectList::const_iterator i = IgnoreResistAuras.begin(); i != IgnoreResistAuras.end(); ++i)
+ {
+ if ((*i)->GetMiscValue() & spellProto->GetSchoolMask())
+ TakenTotalCasterMod += (float((*i)->GetAmount())/100);
+ }
// from positive and negative SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN
// multiplicative bonus, for example Dispersion + Shadowform (0.10*0.85=0.085)
@@ -10865,7 +10757,22 @@ uint32 Unit::SpellDamageBonusTaken(Unit* caster, SpellInfo const* spellProto, ui
TakenTotal+= int32(TakenAdvertisedBenefit * coeff * factorMod);
}
- float tmpDamage = (float(pdamage) + TakenTotal) * TakenTotalMod;
+ float tmpDamage = 0.0f;
+
+ if (TakenTotalCasterMod)
+ {
+ if (TakenTotal < 0)
+ {
+ if (TakenTotalMod < 1)
+ tmpDamage = ((float(CalculatePctF(pdamage, TakenTotalCasterMod) + TakenTotal) * TakenTotalMod) + CalculatePctF(pdamage, TakenTotalCasterMod));
+ else
+ tmpDamage = ((float(CalculatePctF(pdamage, TakenTotalCasterMod) + TakenTotal) + CalculatePctF(pdamage, TakenTotalCasterMod)) * TakenTotalMod);
+ }
+ else if (TakenTotalMod < 1)
+ tmpDamage = ((CalculatePctF(float(pdamage) + TakenTotal, TakenTotalCasterMod) * TakenTotalMod) + CalculatePctF(float(pdamage) + TakenTotal, TakenTotalCasterMod));
+ }
+ if (!tmpDamage)
+ tmpDamage = (float(pdamage) + TakenTotal) * TakenTotalMod;
return uint32(std::max(tmpDamage, 0.0f));
}
@@ -11575,6 +11482,8 @@ bool Unit::IsImmunedToSpell(SpellInfo const* spellInfo)
{
// State/effect immunities applied by aura expect full spell immunity
// Ignore effects with mechanic, they are supposed to be checked separately
+ if (!spellInfo->Effects[i].IsEffect())
+ continue;
if (!IsImmunedToSpellEffect(spellInfo, i))
{
immuneToAllEffects = false;
@@ -11820,6 +11729,16 @@ uint32 Unit::MeleeDamageBonusTaken(Unit* attacker, uint32 pdamage, WeaponAttackT
return 0;
int32 TakenFlatBenefit = 0;
+ float TakenTotalCasterMod = 0.0f;
+
+ // get all auras from caster that allow the spell to ignore resistance (sanctified wrath)
+ SpellSchoolMask attackSchoolMask = spellProto ? spellProto->GetSchoolMask() : SPELL_SCHOOL_MASK_NORMAL;
+ AuraEffectList const& IgnoreResistAuras = attacker->GetAuraEffectsByType(SPELL_AURA_MOD_IGNORE_TARGET_RESIST);
+ for (AuraEffectList::const_iterator i = IgnoreResistAuras.begin(); i != IgnoreResistAuras.end(); ++i)
+ {
+ if ((*i)->GetMiscValue() & attackSchoolMask)
+ TakenTotalCasterMod += (float((*i)->GetAmount())/100);
+ }
// ..taken
AuraEffectList const& mDamageTaken = GetAuraEffectsByType(SPELL_AURA_MOD_DAMAGE_TAKEN);
@@ -11904,7 +11823,22 @@ uint32 Unit::MeleeDamageBonusTaken(Unit* attacker, uint32 pdamage, WeaponAttackT
AddPctN(TakenTotalMod, (*i)->GetAmount());
}
- float tmpDamage = (float(pdamage) + TakenFlatBenefit) * TakenTotalMod;
+ float tmpDamage = 0.0f;
+
+ if (TakenTotalCasterMod)
+ {
+ if (TakenFlatBenefit < 0)
+ {
+ if (TakenTotalMod < 1)
+ tmpDamage = ((float(CalculatePctF(pdamage, TakenTotalCasterMod) + TakenFlatBenefit) * TakenTotalMod) + CalculatePctF(pdamage, TakenTotalCasterMod));
+ else
+ tmpDamage = ((float(CalculatePctF(pdamage, TakenTotalCasterMod) + TakenFlatBenefit) + CalculatePctF(pdamage, TakenTotalCasterMod)) * TakenTotalMod);
+ }
+ else if (TakenTotalMod < 1)
+ tmpDamage = ((CalculatePctF(float(pdamage) + TakenFlatBenefit, TakenTotalCasterMod) * TakenTotalMod) + CalculatePctF(float(pdamage) + TakenFlatBenefit, TakenTotalCasterMod));
+ }
+ if (!tmpDamage)
+ tmpDamage = (float(pdamage) + TakenFlatBenefit) * TakenTotalMod;
// bonus result can be negative
return uint32(std::max(tmpDamage, 0.0f));
@@ -12730,7 +12664,7 @@ void Unit::UpdateSpeed(UnitMoveType mtype, bool forced)
{
// Set creature speed rate from CreatureInfo
if (GetTypeId() == TYPEID_UNIT)
- speed *= ToCreature()->GetCreatureTemplate()->speed_walk;
+ speed *= ToCreature()->GetCreatureTemplate()->speed_run; // at this point, MOVE_WALK is never reached
// Normalize speed by 191 aura SPELL_AURA_USE_NORMAL_MOVEMENT_SPEED if need
// TODO: possible affect only on MOVE_RUN
@@ -13379,8 +13313,7 @@ void Unit::TauntFadeOut(Unit* taunter)
return;
}
- //m_ThreatManager.tauntFadeOut(taunter);
- target = m_ThreatManager.getHostilTarget();
+ target = creature->SelectVictim(); // might have more taunt auras remaining
if (target && target != taunter)
{
@@ -13464,7 +13397,7 @@ Unit* Creature::SelectVictim()
else
return NULL;
- if (target && _IsTargetAcceptable(target))
+ if (target && _IsTargetAcceptable(target) && canCreatureAttack(target))
{
SetInFront(target);
return target;
@@ -13490,7 +13423,7 @@ Unit* Creature::SelectVictim()
{
target = SelectNearestTargetInAttackDistance(m_CombatDistance ? m_CombatDistance : ATTACK_DISTANCE);
- if (target && _IsTargetAcceptable(target))
+ if (target && _IsTargetAcceptable(target) && canCreatureAttack(target))
return target;
}
@@ -13672,7 +13605,7 @@ void Unit::ModSpellCastTime(SpellInfo const* spellProto, int32 & castTime, Spell
if (Player* modOwner = GetSpellModOwner())
modOwner->ApplySpellMod(spellProto->Id, SPELLMOD_CASTING_TIME, castTime, spell);
- if (!(spellProto->Attributes & (SPELL_ATTR0_ABILITY|SPELL_ATTR0_TRADESPELL)) && spellProto->SpellFamilyName)
+ if (!(spellProto->Attributes & (SPELL_ATTR0_ABILITY|SPELL_ATTR0_TRADESPELL)) && ((GetTypeId() == TYPEID_PLAYER && spellProto->SpellFamilyName) || GetTypeId() == TYPEID_UNIT))
castTime = int32(float(castTime) * GetFloatValue(UNIT_MOD_CAST_SPEED));
else if (spellProto->Attributes & SPELL_ATTR0_REQ_AMMO && !(spellProto->AttributesEx2 & SPELL_ATTR2_AUTOREPEAT_FLAG))
castTime = int32(float(castTime) * m_modAttackSpeedPct[RANGED_ATTACK]);
@@ -15007,6 +14940,11 @@ void Unit::ProcDamageAndSpellFor(bool isVictim, Unit* target, uint32 procFlag, u
if (procSpell && (triggeredByAura->GetMiscValue() & procSpell->SchoolMask)) // School check
takeCharges = true;
break;
+ case SPELL_AURA_SPELL_MAGNET:
+ // Skip Melee hits and targets with magnet aura
+ if (procSpell && (triggeredByAura->GetBase()->GetUnitOwner()->ToUnit() == ToUnit())) // Magnet
+ takeCharges = true;
+ break;
case SPELL_AURA_MOD_POWER_COST_SCHOOL_PCT:
case SPELL_AURA_MOD_POWER_COST_SCHOOL:
// Skip melee hits and spells ws wrong school or zero cost
@@ -15235,6 +15173,7 @@ void Unit::StopMoving()
return;
Movement::MoveSplineInit init(*this);
+ init.MoveTo(GetPositionX(), GetPositionY(), GetPositionZMinusOffset());
init.SetFacing(GetOrientation());
init.Launch();
}
@@ -16747,7 +16686,7 @@ Creature* Unit::GetVehicleCreatureBase() const
uint64 Unit::GetTransGUID() const
{
if (GetVehicle())
- return GetVehicle()->GetBase()->GetGUID();
+ return GetVehicleBase()->GetGUID();
if (GetTransport())
return GetTransport()->GetGUID();
@@ -17529,7 +17468,7 @@ bool Unit::HandleSpellClick(Unit* clicker, int8 seatId)
Creature* creature = ToCreature();
if (creature && creature->IsAIEnabled)
- creature->AI()->DoAction(EVENT_SPELLCLICK);
+ creature->AI()->OnSpellClick(clicker);
return true;
}
@@ -17649,11 +17588,12 @@ void Unit::_ExitVehicle(Position const* exitPosition)
Vehicle* vehicle = m_vehicle;
m_vehicle = NULL;
- SetControlled(false, UNIT_STATE_ROOT); // SMSG_MOVE_FORCE_UNROOT, ~MOVEMENTFLAG_ROOT
+ SetControlled(false, UNIT_STATE_ROOT); // SMSG_MOVE_FORCE_UNROOT, ~MOVEMENTFLAG_ROOT
Position pos;
- if (!exitPosition) // Exit position not specified
- vehicle->GetBase()->GetPosition(&pos);
+ if (!exitPosition) // Exit position not specified
+ vehicle->GetBase()->GetPosition(&pos); // This should use passenger's current position, leaving it as it is now
+ // because we calculate positions incorrect (sometimes under map)
else
pos = *exitPosition;
@@ -17668,14 +17608,17 @@ void Unit::_ExitVehicle(Position const* exitPosition)
SendMessageToSet(&data, false);
}
- SendMonsterMoveExitVehicle(&pos);
- Relocate(&pos);
+ Movement::MoveSplineInit init(*this);
+ init.MoveTo(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ());
+ init.SetFacing(GetOrientation());
+ init.SetTransportExit();
+ init.Launch();
+
+ //GetMotionMaster()->MoveFall(); // Enable this once passenger positions are calculater properly (see above)
if (Player* player = ToPlayer())
player->ResummonPetTemporaryUnSummonedIfAny();
- SendMovementFlagUpdate();
-
if (vehicle->GetBase()->HasUnitTypeMask(UNIT_MASK_MINION))
if (((Minion*)vehicle->GetBase())->GetOwner() == this)
vehicle->Dismiss();
@@ -17693,24 +17636,13 @@ void Unit::_ExitVehicle(Position const* exitPosition)
void Unit::BuildMovementPacket(ByteBuffer *data) const
{
- switch (GetTypeId())
- {
- case TYPEID_UNIT:
- if (CanFly())
- const_cast<Unit*>(this)->AddUnitMovementFlag(MOVEMENTFLAG_DISABLE_GRAVITY);
- break;
- case TYPEID_PLAYER:
- // remove unknown, unused etc flags for now
- const_cast<Unit*>(this)->RemoveUnitMovementFlag(MOVEMENTFLAG_SPLINE_ENABLED);
- if (isInFlight())
- {
- WPAssert(const_cast<Unit*>(this)->GetMotionMaster()->GetCurrentMovementGeneratorType() == FLIGHT_MOTION_TYPE);
- const_cast<Unit*>(this)->AddUnitMovementFlag(MOVEMENTFLAG_FORWARD | MOVEMENTFLAG_SPLINE_ENABLED);
- }
- break;
- default:
- break;
- }
+ *data << uint32(GetUnitMovementFlags()); // movement flags
+ *data << uint16(GetExtraUnitMovementFlags()); // 2.3.0
+ *data << uint32(getMSTime()); // time / counter
+ *data << GetPositionX();
+ *data << GetPositionY();
+ *data << GetPositionZMinusOffset();
+ *data << GetOrientation();
bool onTransport = GetUnitMovementFlags() & MOVEMENTFLAG_ONTRANSPORT;
bool hasInterpolatedMovement = m_movementInfo.flags2 & MOVEMENTFLAG2_INTERPOLATED_MOVEMENT;
@@ -18116,6 +18048,7 @@ void Unit::SetInFront(Unit const* target)
void Unit::SetFacingTo(float ori)
{
Movement::MoveSplineInit init(*this);
+ init.MoveTo(GetPositionX(), GetPositionY(), GetPositionZMinusOffset());
init.SetFacing(ori);
init.Launch();
}
@@ -18187,7 +18120,7 @@ void Unit::SendMovementHover()
if (GetTypeId() == TYPEID_PLAYER)
ToPlayer()->SendMovementSetHover(HasUnitMovementFlag(MOVEMENTFLAG_HOVER));
- WorldPacket data(MSG_MOVE_HOVER, 64); // SMSG_MOVE_SET_HOVERING?
+ WorldPacket data(MSG_MOVE_HOVER, 64);
data.append(GetPackGUID());
BuildMovementPacket(&data);
SendMessageToSet(&data, false);
diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h
index 9d6c22ab8b5..6d188fe3593 100755
--- a/src/server/game/Entities/Unit/Unit.h
+++ b/src/server/game/Entities/Unit/Unit.h
@@ -735,19 +735,6 @@ enum MovementFlags2
MOVEMENTFLAG2_UNK16 = 0x00008000,
};
-enum SplineFlags
-{
- SPLINEFLAG_WALKMODE = 0x00001000,
- SPLINEFLAG_FLYING = 0x00002000,
- SPLINEFLAG_TRANSPORT = 0x00800000,
- SPLINEFLAG_EXIT_VEHICLE = 0x01000000,
-};
-
-enum SplineType
-{
- SPLINETYPE_FACING_ANGLE = 4,
-};
-
enum UnitTypeMask
{
UNIT_MASK_NONE = 0x00000000,
@@ -806,8 +793,8 @@ public:
m_dispeller(_dispeller), m_dispellerSpellId(_dispellerSpellId), m_chargesRemoved(_chargesRemoved) {}
Unit* GetDispeller() { return m_dispeller; }
- uint32 GetDispellerSpellId() { return m_dispellerSpellId; }
- uint8 GetRemovedCharges() { return m_chargesRemoved; }
+ uint32 GetDispellerSpellId() const { return m_dispellerSpellId; }
+ uint8 GetRemovedCharges() const { return m_chargesRemoved; }
void SetRemovedCharges(uint8 amount)
{
m_chargesRemoved = amount;
@@ -1350,10 +1337,10 @@ class Unit : public WorldObject
uint32 GetMaxHealth() const { return GetUInt32Value(UNIT_FIELD_MAXHEALTH); }
bool IsFullHealth() const { return GetHealth() == GetMaxHealth(); }
- bool HealthBelowPct(int32 pct) const { return GetHealth() * uint64(100) < GetMaxHealth() * uint64(pct); }
- bool HealthBelowPctDamaged(int32 pct, uint32 damage) const { return (int32(GetHealth()) - damage) * int64(100) < GetMaxHealth() * int64(pct); }
- bool HealthAbovePct(int32 pct) const { return GetHealth() * uint64(100) > GetMaxHealth() * uint64(pct); }
- bool HealthAbovePctHealed(int32 pct, uint32 heal) const { return (GetHealth() + heal) * uint64(100) > GetMaxHealth() * uint64(pct); }
+ bool HealthBelowPct(int32 pct) const { return GetHealth() < CountPctFromMaxHealth(pct); }
+ bool HealthBelowPctDamaged(int32 pct, uint32 damage) const { return int64(GetHealth()) - int64(damage) < int64(CountPctFromMaxHealth(pct)); }
+ bool HealthAbovePct(int32 pct) const { return GetHealth() > CountPctFromMaxHealth(pct); }
+ bool HealthAbovePctHealed(int32 pct, uint32 heal) const { return uint64(GetHealth()) + uint64(heal) > CountPctFromMaxHealth(pct); }
float GetHealthPct() const { return GetMaxHealth() ? 100.f * GetHealth() / GetMaxHealth() : 0.0f; }
uint32 CountPctFromMaxHealth(int32 pct) const { return CalculatePctN(GetMaxHealth(), pct); }
uint32 CountPctFromCurHealth(int32 pct) const { return CalculatePctN(GetHealth(), pct); }
@@ -1632,9 +1619,7 @@ class Unit : public WorldObject
void MonsterMoveWithSpeed(float x, float y, float z, float speed);
//void SetFacing(float ori, WorldObject* obj = NULL);
- void SendMonsterMoveExitVehicle(Position const* newPos);
//void SendMonsterMove(float NewPosX, float NewPosY, float NewPosZ, uint8 type, uint32 MovementFlags, uint32 Time, Player* player = NULL);
- void SendMonsterMoveTransport(Unit* vehicleOwner);
void SendMovementFlagUpdate();
/*! These methods send the same packet to the client in apply and unapply case.
diff --git a/src/server/game/Entities/Vehicle/Vehicle.cpp b/src/server/game/Entities/Vehicle/Vehicle.cpp
index 090a1db382a..eb50f3fe229 100755
--- a/src/server/game/Entities/Vehicle/Vehicle.cpp
+++ b/src/server/game/Entities/Vehicle/Vehicle.cpp
@@ -28,6 +28,7 @@
#include "ZoneScript.h"
#include "SpellMgr.h"
#include "SpellInfo.h"
+#include "MoveSplineInit.h"
Vehicle::Vehicle(Unit* unit, VehicleEntry const* vehInfo, uint32 creatureEntry) : _me(unit), _vehicleInfo(vehInfo), _usableSeatNum(0), _creatureEntry(creatureEntry)
{
@@ -338,7 +339,7 @@ bool Vehicle::AddPassenger(Unit* unit, int8 seatId)
}
}
- if (seat->second.SeatInfo->m_flags && !(seat->second.SeatInfo->m_flags & VEHICLE_SEAT_FLAG_UNK1))
+ if (seat->second.SeatInfo->m_flags && !(seat->second.SeatInfo->m_flags & VEHICLE_SEAT_FLAG_ALLOW_TURNING))
unit->AddUnitState(UNIT_STATE_ONVEHICLE);
unit->AddUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT);
@@ -364,7 +365,12 @@ bool Vehicle::AddPassenger(Unit* unit, int8 seatId)
unit->SendClearTarget(); // SMSG_BREAK_TARGET
unit->SetControlled(true, UNIT_STATE_ROOT); // SMSG_FORCE_ROOT - In some cases we send SMSG_SPLINE_MOVE_ROOT here (for creatures)
// also adds MOVEMENTFLAG_ROOT
- unit->SendMonsterMoveTransport(_me); // SMSG_MONSTER_MOVE_TRANSPORT
+ Movement::MoveSplineInit init(*unit);
+ init.DisableTransportPathTransformations();
+ init.MoveTo(veSeat->m_attachmentOffsetX, veSeat->m_attachmentOffsetY, veSeat->m_attachmentOffsetZ);
+ init.SetFacing(0.0f);
+ init.SetTransportEnter();
+ init.Launch();
if (_me->GetTypeId() == TYPEID_UNIT)
{
@@ -372,7 +378,8 @@ bool Vehicle::AddPassenger(Unit* unit, int8 seatId)
_me->ToCreature()->AI()->PassengerBoarded(unit, seat->first, true);
// update all passenger's positions
- RelocatePassengers(_me->GetPositionX(), _me->GetPositionY(), _me->GetPositionZ(), _me->GetOrientation());
+ //Passenger's spline OR vehicle movement will update positions
+ //RelocatePassengers(_me->GetPositionX(), _me->GetPositionY(), _me->GetPositionZ(), _me->GetOrientation());
}
}