diff options
| author | Shauren <shauren.trinity@gmail.com> | 2012-07-04 22:20:21 +0200 |
|---|---|---|
| committer | Shauren <shauren.trinity@gmail.com> | 2012-07-04 22:20:21 +0200 |
| commit | ed6f3e2deff55f913f9646db5f540b7704088478 (patch) | |
| tree | 2212558564e685b43214a2ca80aea7014af8e200 /src/server/game/Entities | |
| parent | 138375c0455fc0c7f1c2fc0e6b94930dea28ae9c (diff) | |
| parent | c3cb82b9263331ceaf68ebf69638ce3162b4a934 (diff) | |
Merge branch 'master' of github.com:TrinityCore/TrinityCore into 4.x
Diffstat (limited to 'src/server/game/Entities')
| -rwxr-xr-x | src/server/game/Entities/Creature/Creature.cpp | 22 | ||||
| -rwxr-xr-x | src/server/game/Entities/Creature/Creature.h | 6 | ||||
| -rwxr-xr-x | src/server/game/Entities/Creature/TemporarySummon.h | 1 | ||||
| -rwxr-xr-x | src/server/game/Entities/GameObject/GameObject.cpp | 20 | ||||
| -rwxr-xr-x | src/server/game/Entities/Item/Item.cpp | 4 | ||||
| -rwxr-xr-x | src/server/game/Entities/Item/Item.h | 1 | ||||
| -rwxr-xr-x | src/server/game/Entities/Item/ItemPrototype.h | 11 | ||||
| -rwxr-xr-x | src/server/game/Entities/Object/Object.h | 12 | ||||
| -rwxr-xr-x | src/server/game/Entities/Pet/Pet.h | 1 | ||||
| -rwxr-xr-x | src/server/game/Entities/Player/Player.cpp | 207 | ||||
| -rwxr-xr-x | src/server/game/Entities/Player/Player.h | 3 | ||||
| -rwxr-xr-x | src/server/game/Entities/Transport/Transport.cpp | 33 | ||||
| -rwxr-xr-x | src/server/game/Entities/Transport/Transport.h | 2 | ||||
| -rwxr-xr-x | src/server/game/Entities/Unit/Unit.cpp | 319 | ||||
| -rwxr-xr-x | src/server/game/Entities/Unit/Unit.h | 27 | ||||
| -rwxr-xr-x | src/server/game/Entities/Vehicle/Vehicle.cpp | 13 |
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()); } } |
