diff options
Diffstat (limited to 'src/game')
28 files changed, 442 insertions, 256 deletions
diff --git a/src/game/Creature.cpp b/src/game/Creature.cpp index bfa185010fd..24fd970bddf 100644 --- a/src/game/Creature.cpp +++ b/src/game/Creature.cpp @@ -1648,9 +1648,13 @@ bool Creature::IsWithinSightDist(Unit const* u) const bool Creature::canStartAttack(Unit const* who, bool force) const { - if(isCivilian() - || !who->isInAccessiblePlaceFor(this) - || !canFly() && GetDistanceZ(who) > CREATURE_Z_ATTACK_RANGE) + if(isCivilian() || !who->isInAccessiblePlaceFor(this)) + return false; + + if(!canFly() && (GetDistanceZ(who) > CREATURE_Z_ATTACK_RANGE)) + //|| who->IsControlledByPlayer() && who->IsFlying())) + // we cannot check flying for other creatures, too much map/vmap calculation + // TODO: should switch to range attack return false; if(!force && (IsNeutralToAll() || !IsWithinDistInMap(who, GetAttackDistance(who)))) @@ -2190,6 +2194,9 @@ bool Creature::LoadCreaturesAddon(bool reload) if (cainfo->move_flags != 0) SetUnitMovementFlags(cainfo->move_flags); + if(GetCreatureInfo()->InhabitType & INHABIT_AIR) + AddUnitMovementFlag(MOVEMENTFLAG_FLY_MODE); + if(cainfo->auras) { for (CreatureDataAddonAura const* cAura = cainfo->auras; cAura->spell_id; ++cAura) @@ -2504,4 +2511,4 @@ time_t Creature::GetLinkedCreatureRespawnTime() const } return 0; -}
\ No newline at end of file +} diff --git a/src/game/Creature.h b/src/game/Creature.h index d7d070fc526..954259d8846 100644 --- a/src/game/Creature.h +++ b/src/game/Creature.h @@ -516,7 +516,7 @@ class TRINITY_DLL_SPEC Creature : public Unit bool isTrigger() const { return GetCreatureInfo()->flags_extra & CREATURE_FLAG_EXTRA_TRIGGER; } bool canWalk() const { return GetCreatureInfo()->InhabitType & INHABIT_GROUND; } bool canSwim() const { return GetCreatureInfo()->InhabitType & INHABIT_WATER; } - bool canFly() const { return GetCreatureInfo()->InhabitType & INHABIT_AIR; } + //bool canFly() const { return GetCreatureInfo()->InhabitType & INHABIT_AIR; } void SetReactState(ReactStates st) { m_reactState = st; } ReactStates GetReactState() { return m_reactState; } bool HasReactState(ReactStates state) const { return (m_reactState == state); } diff --git a/src/game/GameObject.cpp b/src/game/GameObject.cpp index 1ee7c817c6d..19acc73820b 100644 --- a/src/game/GameObject.cpp +++ b/src/game/GameObject.cpp @@ -1395,7 +1395,7 @@ void GameObject::CastSpell(Unit* target, uint32 spellId) trigger->setFaction(14); // Set owner guid for target if no owner avalible - needed by trigger auras // - trigger gets despawned and there's no caster avalible (see AuraEffect::TriggerSpell()) - trigger->CastSpell(target, spellInfo, true, 0, 0, target->GetGUID()); + trigger->CastSpell(target, spellInfo, true, 0, 0, target ? target->GetGUID() : 0); } //trigger->setDeathState(JUST_DIED); //trigger->RemoveCorpse(); diff --git a/src/game/GridNotifiers.cpp b/src/game/GridNotifiers.cpp index b87d57563af..858c807e386 100644 --- a/src/game/GridNotifiers.cpp +++ b/src/game/GridNotifiers.cpp @@ -38,10 +38,37 @@ VisibleChangesNotifier::Visit(PlayerMapType &m) continue; iter->getSource()->UpdateVisibilityOf(&i_object); + + if(!iter->getSource()->GetSharedVisionList().empty()) + for(SharedVisionList::const_iterator i = iter->getSource()->GetSharedVisionList().begin(); + i != iter->getSource()->GetSharedVisionList().end(); ++i) + if((*i)->m_seer == iter->getSource()) + (*i)->UpdateVisibilityOf(&i_object); } } void +VisibleChangesNotifier::Visit(CreatureMapType &m) +{ + for(CreatureMapType::iterator iter = m.begin(); iter != m.end(); ++iter) + if(!iter->getSource()->GetSharedVisionList().empty()) + for(SharedVisionList::const_iterator i = iter->getSource()->GetSharedVisionList().begin(); + i != iter->getSource()->GetSharedVisionList().end(); ++i) + if((*i)->m_seer == iter->getSource()) + (*i)->UpdateVisibilityOf(&i_object); +} + +void +VisibleChangesNotifier::Visit(DynamicObjectMapType &m) +{ + for(DynamicObjectMapType::iterator iter = m.begin(); iter != m.end(); ++iter) + if(IS_PLAYER_GUID(iter->getSource()->GetCasterGUID())) + if(Player* caster = (Player*)iter->getSource()->GetCaster()) + if(caster->m_seer == iter->getSource()) + caster->UpdateVisibilityOf(&i_object); +} + +void PlayerVisibilityNotifier::Notify() { // at this moment i_clientGUIDs have guids that not iterate at grid level checks diff --git a/src/game/GridNotifiers.h b/src/game/GridNotifiers.h index 5418bd09b16..64deb0d3123 100644 --- a/src/game/GridNotifiers.h +++ b/src/game/GridNotifiers.h @@ -81,6 +81,8 @@ namespace Trinity explicit VisibleChangesNotifier(WorldObject &object) : i_object(object) {} template<class T> void Visit(GridRefManager<T> &) {} void Visit(PlayerMapType &); + void Visit(CreatureMapType &); + void Visit(DynamicObjectMapType &); }; struct TRINITY_DLL_DECL GridUpdater diff --git a/src/game/Level3.cpp b/src/game/Level3.cpp index 77c81144d48..959e5dec7d3 100644 --- a/src/game/Level3.cpp +++ b/src/game/Level3.cpp @@ -697,7 +697,7 @@ bool ChatHandler::HandleReloadAchievementCriteriaDataCommand(const char*) { sLog.outString( "Re-Loading Additional Achievement Criteria Data..." ); achievementmgr.LoadAchievementCriteriaData(); - SendGlobalSysMessage("DB table `achievement_criteria_data` reloaded."); + SendGlobalGMSysMessage("DB table `achievement_criteria_data` reloaded."); return true; } @@ -705,7 +705,7 @@ bool ChatHandler::HandleReloadAchievementRewardCommand(const char*) { sLog.outString( "Re-Loading Achievement Reward Data..." ); achievementmgr.LoadRewards(); - SendGlobalSysMessage("DB table `achievement_reward` reloaded."); + SendGlobalGMSysMessage("DB table `achievement_reward` reloaded."); return true; } @@ -851,7 +851,7 @@ bool ChatHandler::HandleReloadLootTemplatesMillingCommand(const char*) sLog.outString( "Re-Loading Loot Tables... (`milling_loot_template`)" ); LoadLootTemplates_Milling(); LootTemplates_Milling.CheckLootRefs(); - SendGlobalSysMessage("DB table `milling_loot_template` reloaded."); + SendGlobalGMSysMessage("DB table `milling_loot_template` reloaded."); return true; } @@ -904,7 +904,7 @@ bool ChatHandler::HandleReloadLootTemplatesSpellCommand(const char*) sLog.outString( "Re-Loading Loot Tables... (`spell_loot_template`)" ); LoadLootTemplates_Spell(); LootTemplates_Spell.CheckLootRefs(); - SendGlobalSysMessage("DB table `spell_loot_template` reloaded."); + SendGlobalGMSysMessage("DB table `spell_loot_template` reloaded."); return true; } @@ -952,7 +952,7 @@ bool ChatHandler::HandleReloadPointsOfInterestCommand(const char*) { sLog.outString( "Re-Loading `points_of_interest` Table!" ); objmgr.LoadPointsOfInterest(); - SendGlobalSysMessage("DB table `points_of_interest` reloaded."); + SendGlobalGMSysMessage("DB table `points_of_interest` reloaded."); return true; } @@ -960,7 +960,7 @@ bool ChatHandler::HandleReloadSpellClickSpellsCommand(const char*) { sLog.outString( "Re-Loading `npc_spellclick_spells` Table!" ); objmgr.LoadNPCSpellClickSpells(); - SendGlobalSysMessage("DB table `npc_spellclick_spells` reloaded."); + SendGlobalGMSysMessage("DB table `npc_spellclick_spells` reloaded."); return true; } @@ -1008,7 +1008,7 @@ bool ChatHandler::HandleReloadSpellAreaCommand(const char*) { sLog.outString( "Re-Loading SpellArea Data..." ); spellmgr.LoadSpellAreas(); - SendGlobalSysMessage("DB table `spell_area` (spell dependences from area/quest/auras state) reloaded."); + SendGlobalGMSysMessage("DB table `spell_area` (spell dependences from area/quest/auras state) reloaded."); return true; } @@ -1056,7 +1056,7 @@ bool ChatHandler::HandleReloadSpellBonusesCommand(const char*) { sLog.outString( "Re-Loading Spell Bonus Data..." ); spellmgr.LoadSpellBonusess(); - SendGlobalSysMessage("DB table `spell_bonus_data` (spell damage/healing coefficients) reloaded."); + SendGlobalGMSysMessage("DB table `spell_bonus_data` (spell damage/healing coefficients) reloaded."); return true; } @@ -1112,7 +1112,7 @@ bool ChatHandler::HandleReloadItemRequiredTragetCommand(const char*) { sLog.outString( "Re-Loading Item Required Targets Table..." ); objmgr.LoadItemRequiredTarget(); - SendGlobalSysMessage("DB table `item_required_target` reloaded."); + SendGlobalGMSysMessage("DB table `item_required_target` reloaded."); return true; } @@ -1181,7 +1181,7 @@ bool ChatHandler::HandleReloadEventAITextsCommand(const char* arg) sLog.outString( "Re-Loading Texts from `creature_ai_texts`..."); CreatureEAI_Mgr.LoadCreatureEventAI_Texts(); - SendGlobalSysMessage("DB table `creature_ai_texts` reloaded."); + SendGlobalGMSysMessage("DB table `creature_ai_texts` reloaded."); return true; } @@ -1189,7 +1189,7 @@ bool ChatHandler::HandleReloadEventAISummonsCommand(const char* arg) { sLog.outString( "Re-Loading Summons from `creature_ai_summons`..."); CreatureEAI_Mgr.LoadCreatureEventAI_Summons(); - SendGlobalSysMessage("DB table `creature_ai_summons` reloaded."); + SendGlobalGMSysMessage("DB table `creature_ai_summons` reloaded."); return true; } @@ -1197,7 +1197,7 @@ bool ChatHandler::HandleReloadEventAIScriptsCommand(const char* arg) { sLog.outString( "Re-Loading Scripts from `creature_ai_scripts`..."); CreatureEAI_Mgr.LoadCreatureEventAI_Scripts(); - SendGlobalSysMessage("DB table `creature_ai_scripts` reloaded."); + SendGlobalGMSysMessage("DB table `creature_ai_scripts` reloaded."); return true; } @@ -1306,7 +1306,7 @@ bool ChatHandler::HandleReloadLocalesAchievementRewardCommand(const char*) { sLog.outString( "Re-Loading Locales Achievement Reward Data..." ); achievementmgr.LoadRewardLocales(); - SendGlobalSysMessage("DB table `locales_achievement_reward` reloaded."); + SendGlobalGMSysMessage("DB table `locales_achievement_reward` reloaded."); return true; } @@ -1354,7 +1354,7 @@ bool ChatHandler::HandleReloadLocalesPointsOfInterestCommand(const char* /*arg*/ { sLog.outString( "Re-Loading Locales Points Of Interest ... "); objmgr.LoadPointOfInterestLocales(); - SendGlobalSysMessage("DB table `locales_points_of_interest` reloaded."); + SendGlobalGMSysMessage("DB table `locales_points_of_interest` reloaded."); return true; } diff --git a/src/game/MiscHandler.cpp b/src/game/MiscHandler.cpp index 043397f9c48..f5a1013f085 100644 --- a/src/game/MiscHandler.cpp +++ b/src/game/MiscHandler.cpp @@ -1609,7 +1609,7 @@ void WorldSession::HandleMoveSetCanFlyAckOpcode( WorldPacket & recv_data ) recv_data >> guid >> unk >> flags; - _player->m_movementInfo.flags = flags; + _player->m_mover->m_movementInfo.flags = flags; } void WorldSession::HandleRequestPetInfoOpcode( WorldPacket & /*recv_data */) diff --git a/src/game/MovementHandler.cpp b/src/game/MovementHandler.cpp index 775cef0edca..1a483a8869d 100644 --- a/src/game/MovementHandler.cpp +++ b/src/game/MovementHandler.cpp @@ -293,16 +293,12 @@ void WorldSession::HandleMovementOpcodes( WorldPacket & recv_data ) GetPlayer()->SendMessageToSet(&data, false); mover->m_movementInfo = movementInfo; - mover->SetUnitMovementFlags(movementInfo.flags); if(plMover) // nothing is charmed, or player charmed { plMover->SetPosition(movementInfo.x, movementInfo.y, movementInfo.z, movementInfo.o); plMover->UpdateFallInformationIfNeed(movementInfo, recv_data.GetOpcode()); - if(plMover->isMovingOrTurning()) - plMover->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH); - if(movementInfo.z < -500.0f) { if(plMover->InBattleGround() @@ -340,6 +336,13 @@ void WorldSession::HandleMovementOpcodes( WorldPacket & recv_data ) if(mover->m_Vehicle) return; mover->GetMap()->CreatureRelocation((Creature*)mover, movementInfo.x, movementInfo.y, movementInfo.z, movementInfo.o); + + /*if(mover->canFly()) + { + bool flying = mover->IsFlying(); + if(flying != ((mover->GetByteValue(UNIT_FIELD_BYTES_1, 3) & 0x02) ? true : false)) + mover->SetFlying(flying); + }*/ } //sLog.outString("Receive Movement Packet %s:", opcodeTable[recv_data.GetOpcode()]); @@ -462,9 +465,7 @@ void WorldSession::HandleMoveNotActiveMover(WorldPacket &recv_data) return; }*/ - MovementInfo mi; - ReadMovementInfo(recv_data, &mi); - _player->m_movementInfo = mi; + ReadMovementInfo(recv_data, &_player->m_mover->m_movementInfo); } void WorldSession::HandleDismissControlledVehicle(WorldPacket &recv_data) @@ -477,9 +478,7 @@ void WorldSession::HandleDismissControlledVehicle(WorldPacket &recv_data) if(!vehicleGUID) // something wrong here... return; - MovementInfo mi; - ReadMovementInfo(recv_data, &mi); - _player->m_movementInfo = mi; + ReadMovementInfo(recv_data, &_player->m_mover->m_movementInfo); _player->ExitVehicle(); } diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 54c86fa874a..68545b6a379 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -1654,7 +1654,6 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati // reset movement flags at teleport, because player will continue move with these flags after teleport SetUnitMovementFlags(0); - m_movementInfo.flags = 0; if (m_transport) { @@ -5636,38 +5635,35 @@ bool Player::SetPosition(float x, float y, float z, float orientation, bool tele return false; } - Map *m = GetMap(); + //if(movementInfo.flags & MOVEMENTFLAG_MOVING) + // mover->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_MOVE); + //if(movementInfo.flags & MOVEMENTFLAG_TURNING) + // mover->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_TURNING); + //AURA_INTERRUPT_FLAG_JUMP not sure - const float old_x = GetPositionX(); - const float old_y = GetPositionY(); - const float old_z = GetPositionZ(); - const float old_r = GetOrientation(); + if(GetOrientation() != orientation) + RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_TURNING); - if( teleport || old_x != x || old_y != y || old_z != z || old_r != orientation ) + bool move2d = (teleport || GetPositionX() != x || GetPositionY() != y); + if(move2d || GetPositionZ() != z) { - if (teleport || old_x != x || old_y != y || old_z != z) - RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_MOVE | AURA_INTERRUPT_FLAG_TURNING); - else - RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_TURNING); + RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_MOVE); // move and update visible state if need - m->PlayerRelocation(this, x, y, z, orientation); + GetMap()->PlayerRelocation(this, x, y, z, orientation); // reread after Map::Relocation - m = GetMap(); - x = GetPositionX(); - y = GetPositionY(); - z = GetPositionZ(); + GetPosition(x, y, z); // group update - if(GetGroup() && (old_x != x || old_y != y)) + if(move2d && GetGroup()) SetGroupUpdateFlag(GROUP_UPDATE_FLAG_POSITION); - } - // code block for underwater state update - UpdateUnderwaterState(m, x, y, z); + // code block for underwater state update + UpdateUnderwaterState(GetMap(), x, y, z); - CheckExploreSystem(); + CheckExploreSystem(); + } return true; } @@ -6416,7 +6412,7 @@ void Player::CheckDuelDistance(time_t currTime) bool Player::IsOutdoorPvPActive() { - return (isAlive() && !HasInvisibilityAura() && !HasStealthAura() && (HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_IN_PVP) || sWorld.IsPvPRealm()) && !HasUnitMovementFlag(MOVEMENTFLAG_FLYING2) && !isInFlight()); + return (isAlive() && !HasInvisibilityAura() && !HasStealthAura() && (HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_IN_PVP) || sWorld.IsPvPRealm()) && !HasUnitMovementFlag(MOVEMENTFLAG_FLYING) && !isInFlight()); } void Player::DuelComplete(DuelCompleteType type) diff --git a/src/game/Player.h b/src/game/Player.h index 9dcad34f0e8..c879222d8d8 100644 --- a/src/game/Player.h +++ b/src/game/Player.h @@ -689,17 +689,6 @@ enum InstanceResetWarningType RAID_INSTANCE_EXPIRED = 5 }; -// flags that use in movement check for example at spell casting -MovementFlags const movementFlagsMask = MovementFlags( - MOVEMENTFLAG_FORWARD |MOVEMENTFLAG_BACKWARD |MOVEMENTFLAG_STRAFE_LEFT|MOVEMENTFLAG_STRAFE_RIGHT| - MOVEMENTFLAG_PITCH_UP|MOVEMENTFLAG_PITCH_DOWN|MOVEMENTFLAG_FLY_UNK1 | - MOVEMENTFLAG_JUMPING |MOVEMENTFLAG_FALLING |MOVEMENTFLAG_FLY_UP | - MOVEMENTFLAG_FLYING |MOVEMENTFLAG_SPLINE -); - -MovementFlags const movementOrTurningFlagsMask = MovementFlags( - movementFlagsMask | MOVEMENTFLAG_LEFT | MOVEMENTFLAG_RIGHT -); class InstanceSave; enum RestType @@ -1951,11 +1940,6 @@ class TRINITY_DLL_SPEC Player : public Unit } void HandleFall(MovementInfo const& movementInfo); - bool isMoving() const { return m_movementInfo.HasMovementFlag(movementFlagsMask); } - bool isMovingOrTurning() const { return m_movementInfo.HasMovementFlag(movementOrTurningFlagsMask); } - - bool CanFly() const { return m_movementInfo.HasMovementFlag(MOVEMENTFLAG_CAN_FLY); } - bool IsFlying() const { return m_movementInfo.HasMovementFlag(MOVEMENTFLAG_FLYING); } bool IsAllowUseFlyMountsHere() const; void SetClientControl(Unit* target, uint8 allowMove); diff --git a/src/game/PointMovementGenerator.cpp b/src/game/PointMovementGenerator.cpp index c972683ce0b..ed057854aaa 100644 --- a/src/game/PointMovementGenerator.cpp +++ b/src/game/PointMovementGenerator.cpp @@ -35,7 +35,7 @@ void PointMovementGenerator<T>::Initialize(T &unit) i_destinationHolder.SetDestination(traveller,i_x,i_y,i_z, !unit.hasUnitState(UNIT_STAT_JUMPING)); if (unit.GetTypeId() == TYPEID_UNIT && ((Creature*)&unit)->canFly()) - unit.AddUnitMovementFlag(MOVEMENTFLAG_FLYING2); + unit.AddUnitMovementFlag(MOVEMENTFLAG_FLYING); } template<class T> diff --git a/src/game/RandomMovementGenerator.cpp b/src/game/RandomMovementGenerator.cpp index 6d3648d51e4..e354e41827c 100644 --- a/src/game/RandomMovementGenerator.cpp +++ b/src/game/RandomMovementGenerator.cpp @@ -124,7 +124,7 @@ RandomMovementGenerator<Creature>::_setRandomLocation(Creature &creature) if (is_air_ok) { i_nextMoveTime.Reset(i_destinationHolder.GetTotalTravelTime()); - creature.AddUnitMovementFlag(MOVEMENTFLAG_FLYING2); + creature.AddUnitMovementFlag(MOVEMENTFLAG_FLYING); } //else if (is_water_ok) // Swimming mode to be done with more than this check else @@ -151,7 +151,7 @@ RandomMovementGenerator<Creature>::Initialize(Creature &creature) wander_distance = creature.GetRespawnRadius(); if (creature.canFly()) - creature.AddUnitMovementFlag(MOVEMENTFLAG_FLYING2); + creature.AddUnitMovementFlag(MOVEMENTFLAG_FLYING); else if(irand(0,RUNNING_CHANCE_RANDOMMV) > 0) creature.AddUnitMovementFlag(MOVEMENTFLAG_WALK_MODE); _setRandomLocation(creature); @@ -194,7 +194,7 @@ RandomMovementGenerator<Creature>::Update(Creature &creature, const uint32 &diff if(i_nextMoveTime.Passed()) { if (creature.canFly()) - creature.AddUnitMovementFlag(MOVEMENTFLAG_FLYING2); + creature.AddUnitMovementFlag(MOVEMENTFLAG_FLYING); else if(irand(0,RUNNING_CHANCE_RANDOMMV) > 0) creature.AddUnitMovementFlag(MOVEMENTFLAG_WALK_MODE); _setRandomLocation(creature); diff --git a/src/game/SharedDefines.h b/src/game/SharedDefines.h index e1440d45454..b6ac8054ce2 100644 --- a/src/game/SharedDefines.h +++ b/src/game/SharedDefines.h @@ -344,7 +344,7 @@ enum SpellCategory #define SPELL_ATTR_EX3_REQ_OFFHAND 0x01000000 // 24 Req offhand weapon #define SPELL_ATTR_EX3_UNK25 0x02000000 // 25 no cause spell pushback ? #define SPELL_ATTR_EX3_CAN_PROC_TRIGGERED 0x04000000 // 26 -#define SPELL_ATTR_EX3_UNK27 0x08000000 // 27 +#define SPELL_ATTR_EX3_DRAIN_SOUL 0x08000000 // 27 only drain soul has this flag #define SPELL_ATTR_EX3_UNK28 0x10000000 // 28 #define SPELL_ATTR_EX3_UNK29 0x20000000 // 29 #define SPELL_ATTR_EX3_UNK30 0x40000000 // 30 diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp index 2f641c43c35..d97bd11842d 100644 --- a/src/game/Spell.cpp +++ b/src/game/Spell.cpp @@ -423,7 +423,6 @@ Spell::Spell( Unit* Caster, SpellEntry const *info, bool triggered, uint64 origi m_spellState = SPELL_STATE_NULL; - m_castPositionX = m_castPositionY = m_castPositionZ = 0; m_TriggerSpells.clear(); m_IsTriggeredSpell = triggered; //m_AreaAura = false; @@ -1209,7 +1208,7 @@ SpellMissInfo Spell::DoSpellHitOnUnit(Unit *unit, const uint32 effectMask) if(m_spellInfo->speed > 0.0f && unit == m_targets.getUnitTarget() && (unit->HasAuraType(SPELL_AURA_MOD_INVISIBILITY) || unit->HasAuraTypeWithFamilyFlags(SPELL_AURA_MOD_STEALTH, SPELLFAMILY_ROGUE, SPELLFAMILYFLAG_ROGUE_VANISH)) - && !unit->isVisibleForOrDetect(m_caster, true)) + && !m_caster->canSeeOrDetect(unit, true)) { // that was causing CombatLog errors // return SPELL_MISS_EVADE; @@ -1410,12 +1409,20 @@ bool Spell::UpdateChanneledTargetList() uint8 needAliveTargetMask = m_needAliveTargetMask; uint8 needAuraMask = 0; - for (uint8 i=0;i<MAX_SPELL_EFFECTS;++i) + for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) if (m_spellInfo->Effect[i] == SPELL_EFFECT_APPLY_AURA) needAuraMask |= 1<<i; needAuraMask &= needAliveTargetMask; + float range; + if(needAuraMask) + { + range = GetSpellMaxRange(m_spellInfo, IsPositiveSpell(m_spellInfo->Id)); + if(Player * modOwner = m_caster->GetSpellModOwner()) + modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_RANGE, range, this); + } + for(std::list<TargetInfo>::iterator ihit= m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit) { if( ihit->missCondition == SPELL_MISS_NONE && (needAliveTargetMask & ihit->effectMask) ) @@ -1428,9 +1435,6 @@ bool Spell::UpdateChanneledTargetList() { if(Aura * aur = unit->GetAura(m_spellInfo->Id, m_originalCasterGUID)) { - float range = m_caster->GetSpellMaxRangeForTarget(unit,GetSpellRangeStore()->LookupEntry(m_spellInfo->rangeIndex)); - if(Player * modOwner = m_caster->GetSpellModOwner()) - modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_RANGE, range, this); if (m_caster != unit && !m_caster->IsWithinDistInMap(unit,range)) { ihit->effectMask &= ~aur->GetEffectMask(); @@ -1438,7 +1442,7 @@ bool Spell::UpdateChanneledTargetList() continue; } } - else + else // aura is dispelled continue; } @@ -2280,46 +2284,56 @@ void Spell::SetTargetMap(uint32 i, uint32 cur) } else { - if(m_spellInfo->Id == 27285) // Seed of Corruption proc spell - unitList.remove(m_targets.getUnitTarget()); - else if (m_spellInfo->Id==57699) //Replenishment (special target selection) 10 targets with lowest mana + switch (m_spellInfo->Id) { - typedef std::priority_queue<PrioritizeManaWraper, std::vector<PrioritizeManaWraper>, PrioritizeMana> TopMana; - TopMana manaUsers; - for (std::list<Unit*>::iterator itr = unitList.begin() ; itr != unitList.end();++itr) + case 27285: // Seed of Corruption proc spell + unitList.remove(m_targets.getUnitTarget()); + break; + case 55789: // Improved Icy Talons + case 59725: // Improved Spell Reflection - aoe aura + unitList.remove(m_caster); + break; + case 57699: //Replenishment (special target selection) 10 targets with lowest mana { - if ((*itr)->getPowerType() == POWER_MANA) + typedef std::priority_queue<PrioritizeManaWraper, std::vector<PrioritizeManaWraper>, PrioritizeMana> TopMana; + TopMana manaUsers; + for (std::list<Unit*>::iterator itr = unitList.begin() ; itr != unitList.end();++itr) { - PrioritizeManaWraper WTarget(*itr); - manaUsers.push(WTarget); + if ((*itr)->getPowerType() == POWER_MANA) + { + PrioritizeManaWraper WTarget(*itr); + manaUsers.push(WTarget); + } } - } - unitList.clear(); - while(!manaUsers.empty() && unitList.size()<10) - { - unitList.push_back(manaUsers.top().getUnit()); - manaUsers.pop(); + unitList.clear(); + while(!manaUsers.empty() && unitList.size()<10) + { + unitList.push_back(manaUsers.top().getUnit()); + manaUsers.pop(); + } + break; } - } - else if (m_spellInfo->Id==52759)// Ancestral Awakening - { - typedef std::priority_queue<PrioritizeHealthWraper, std::vector<PrioritizeHealthWraper>, PrioritizeHealth> TopHealth; - TopHealth healedMembers; - for (std::list<Unit*>::iterator itr = unitList.begin() ; itr != unitList.end();++itr) + case 52759: // Ancestral Awakening { - PrioritizeHealthWraper WTarget(*itr); - healedMembers.push(WTarget); - } + typedef std::priority_queue<PrioritizeHealthWraper, std::vector<PrioritizeHealthWraper>, PrioritizeHealth> TopHealth; + TopHealth healedMembers; + for (std::list<Unit*>::iterator itr = unitList.begin() ; itr != unitList.end();++itr) + { + PrioritizeHealthWraper WTarget(*itr); + healedMembers.push(WTarget); + } - unitList.clear(); - while(!healedMembers.empty() && unitList.size()<1) - { - unitList.push_back(healedMembers.top().getUnit()); - healedMembers.pop(); + unitList.clear(); + while(!healedMembers.empty() && unitList.size()<1) + { + unitList.push_back(healedMembers.top().getUnit()); + healedMembers.pop(); + } + break; } } - else if (m_spellInfo->EffectImplicitTargetA[i] == TARGET_DEST_TARGET_ANY + if (m_spellInfo->EffectImplicitTargetA[i] == TARGET_DEST_TARGET_ANY && m_spellInfo->EffectImplicitTargetB[i] == TARGET_UNIT_AREA_ALLY_DST)// Wild Growth, Circle of Healing, Glyph of holy light target special selection { typedef std::priority_queue<PrioritizeHealthWraper, std::vector<PrioritizeHealthWraper>, PrioritizeHealth> TopHealth; @@ -2376,9 +2390,6 @@ void Spell::prepare(SpellCastTargets const* targets, AuraEffect* triggeredByAura m_spellState = SPELL_STATE_PREPARING; - m_caster->GetPosition(m_castPositionX, m_castPositionY, m_castPositionZ); - m_castOrientation = m_caster->GetOrientation(); - if(triggeredByAura) m_triggeredByAuraSpell = triggeredByAura->GetSpellProto(); @@ -2510,16 +2521,12 @@ void Spell::cancel() case SPELL_STATE_CASTING: { - for(std::list<TargetInfo>::iterator ihit= m_UniqueTargetInfo.begin();ihit != m_UniqueTargetInfo.end();++ihit) - { - if( ihit->missCondition == SPELL_MISS_NONE ) - { - Unit* unit = m_caster->GetGUID()==(*ihit).targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID); - if( unit && unit->isAlive() ) - unit->RemoveAurasDueToSpell(m_spellInfo->Id, m_originalCasterGUID, AURA_REMOVE_BY_CANCEL); - } - } - m_caster->RemoveAurasDueToSpell(m_spellInfo->Id, m_originalCasterGUID, AURA_REMOVE_BY_CANCEL); + for(std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit) + if(ihit->missCondition == SPELL_MISS_NONE) + if(Unit* unit = m_caster->GetGUID() == ihit->targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID)) + if(unit->isAlive()) + unit->RemoveAurasDueToSpell(m_spellInfo->Id, m_originalCasterGUID, AURA_REMOVE_BY_CANCEL); + SendChannelUpdate(0); SendInterrupted(0); SendCastResult(SPELL_FAILED_INTERRUPTED); @@ -2902,21 +2909,18 @@ void Spell::update(uint32 difftime) if(m_targets.getUnitTargetGUID() && !m_targets.getUnitTarget()) { + sLog.outDebug("Spell %u is cancelled due to removal of target.", m_spellInfo->Id); cancel(); return; } // check if the player caster has moved before the spell finished if ((m_caster->GetTypeId() == TYPEID_PLAYER && m_timer != 0) && - (m_castPositionX != m_caster->GetPositionX() || m_castPositionY != m_caster->GetPositionY() || m_castPositionZ != m_caster->GetPositionZ()) && + m_caster->isMoving() && (m_spellInfo->InterruptFlags & SPELL_INTERRUPT_FLAG_MOVEMENT) && (m_spellInfo->Effect[0] != SPELL_EFFECT_STUCK || !m_caster->HasUnitMovementFlag(MOVEMENTFLAG_FALLING))) { - // always cancel for channeled spells - //if( m_spellState == SPELL_STATE_CASTING ) - // cancel(); // don't cancel for melee, autorepeat, triggered and instant spells - //else - if(!IsNextMeleeSwingSpell() && !IsAutoRepeat() && !m_IsTriggeredSpell && (m_spellInfo->InterruptFlags & SPELL_INTERRUPT_FLAG_MOVEMENT)) + if(!IsNextMeleeSwingSpell() && !IsAutoRepeat() && !m_IsTriggeredSpell) cancel(); } @@ -2939,17 +2943,6 @@ void Spell::update(uint32 difftime) { if(m_timer > 0) { - if( m_caster->GetTypeId() == TYPEID_PLAYER ) - { - // check if player has jumped before the channeling finished - if(m_caster->HasUnitMovementFlag(MOVEMENTFLAG_JUMPING)) - cancel(); - - // check for incapacitating player states - //if( m_caster->hasUnitState(UNIT_STAT_STUNNED | UNIT_STAT_CONFUSED)) - // cancel(); - } - // check if there are alive targets left if (!UpdateChanneledTargetList()) { @@ -5924,6 +5917,7 @@ bool SpellEvent::Execute(uint64 e_time, uint32 p_time) { // no, we aren't, do the typical update // check, if we have channeled spell on our hands + /* if (IsChanneledSpell(m_Spell->m_spellInfo)) { // evented channeled spell is processed separately, casted once after delay, and not destroyed till finish @@ -5946,6 +5940,7 @@ bool SpellEvent::Execute(uint64 e_time, uint32 p_time) // event will be re-added automatically at the end of routine) } else + */ { // run the spell handler and think about what we can do next uint64 t_offset = e_time - m_Spell->GetDelayStart(); diff --git a/src/game/Spell.h b/src/game/Spell.h index 5309d881990..5d108f48fa1 100644 --- a/src/game/Spell.h +++ b/src/game/Spell.h @@ -274,7 +274,6 @@ class Spell void EffectDualWield(uint32 i); void EffectPickPocket(uint32 i); void EffectAddFarsight(uint32 i); - void EffectSummonWild(uint32 i); void EffectHealMechanical(uint32 i); void EffectJump(uint32 i); void EffectJump2(uint32 i); @@ -622,10 +621,6 @@ class Spell uint32 m_spellState; uint32 m_timer; - float m_castPositionX; - float m_castPositionY; - float m_castPositionZ; - float m_castOrientation; bool m_IsTriggeredSpell; // if need this can be replaced by Aura copy diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index f7eb73c7b72..471209e8f77 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -2478,6 +2478,10 @@ void AuraEffect::HandleAuraDummy(bool apply, bool Real, bool changeAmount) if(m_target->GetTypeId()==TYPEID_PLAYER) ((Player*)m_target)->RemoveAmmo(); // not use ammo and not allow use return; + case 52916: // Honor Among Thieves + if (Unit * target = ObjectAccessor::GetUnit(*m_target, m_target->GetUInt64Value(UNIT_FIELD_TARGET))) + m_target->CastSpell(target, 51699, true); + return; } // Earth Shield @@ -4593,6 +4597,20 @@ void AuraEffect::HandlePeriodicDamage(bool apply, bool Real, bool changeAmount) // For prevent double apply bonuses bool loading = (m_target->GetTypeId() == TYPEID_PLAYER && ((Player*)m_target)->GetSession()->PlayerLoading()); + // Curse of Doom + // This is a hack - this aura should be handled by passive aura and proc doomguard spawn on kill, however there is no such aura in dbcs + if(m_spellProto->SpellFamilyName==SPELLFAMILY_WARLOCK && m_spellProto->SpellFamilyFlags.IsEqual(0,0x02,0)) + { + if (Real && !apply && GetParentAura()->GetRemoveMode()==AURA_REMOVE_BY_DEATH) + { + if (Unit * caster = GetCaster()) + { + if (caster->GetTypeId()==TYPEID_PLAYER && ((Player*)caster)->isHonorOrXPTarget(m_target)) + caster->CastSpell(m_target, 18662, true); + } + } + } + // Custom damage calculation after if (!apply || loading) return; @@ -5654,26 +5672,15 @@ void AuraEffect::HandleAuraAllowFlight(bool apply, bool Real, bool /*changeAmoun if(!Real) return; + if(m_target->GetTypeId() == TYPEID_UNIT) + m_target->SetFlying(apply); + // allow fly WorldPacket data; if(apply) - { data.Initialize(SMSG_MOVE_SET_CAN_FLY, 12); - if(m_target->GetTypeId() == TYPEID_UNIT) - { - m_target->SetByteFlag(UNIT_FIELD_BYTES_1, 3, 0x02); - m_target->AddUnitMovementFlag(MOVEMENTFLAG_FLYING2); - } - } else - { data.Initialize(SMSG_MOVE_UNSET_CAN_FLY, 12); - if(m_target->GetTypeId() == TYPEID_UNIT) - { - m_target->RemoveByteFlag(UNIT_FIELD_BYTES_1, 3, 0x02); - m_target->RemoveUnitMovementFlag(MOVEMENTFLAG_FLYING2); - } - } data.append(m_target->GetPackGUID()); data << uint32(0); // unk m_target->SendMessageToSet(&data, true); @@ -5824,7 +5831,7 @@ void AuraEffect::HandleSchoolAbsorb(bool apply, bool Real, bool changeAmount) switch(m_spellProto->SpellFamilyName) { case SPELLFAMILY_PRIEST: - // PW: S + // Power Word: Shield if(m_spellProto->SpellFamilyFlags.IsEqual(0x1, 0, 0x400)) { // +80.68% from sp bonus @@ -5856,6 +5863,14 @@ void AuraEffect::HandleSchoolAbsorb(bool apply, bool Real, bool changeAmount) DoneActualBenefit = caster->SpellBaseDamageBonus(GetSpellSchoolMask(m_spellProto)) * 0.3f; } break; + case SPELLFAMILY_PALADIN: + // Sacred Shield + if (m_spellProto->SpellFamilyFlags[1] & 0x80000) + { + // 0.75 from sp bonus + DoneActualBenefit = caster->SpellBaseDamageBonus(GetSpellSchoolMask(m_spellProto)) * 0.75f; + } + break; default: break; } @@ -5994,9 +6009,9 @@ void AuraEffect::PeriodicTick() SpellEntry const* spellProto = GetSpellProto(); // Set trigger flag - uint32 procAttacker = PROC_FLAG_ON_DO_PERIODIC | PROC_FLAG_SUCCESSFUL_DAMAGING_SPELL_HIT; - uint32 procVictim = PROC_FLAG_ON_TAKE_PERIODIC | PROC_FLAG_TAKEN_DAMAGING_SPELL_HIT; - uint32 procEx = PROC_EX_NORMAL_HIT; + uint32 procAttacker = PROC_FLAG_ON_DO_PERIODIC; + uint32 procVictim = PROC_FLAG_ON_TAKE_PERIODIC; + uint32 procEx = PROC_EX_NORMAL_HIT | PROC_EX_INTERNAL_DOT; pdamage = (pdamage <= absorb+resist) ? 0 : (pdamage-absorb-resist); if (pdamage) procVictim|=PROC_FLAG_TAKEN_ANY_DAMAGE; @@ -6006,7 +6021,6 @@ void AuraEffect::PeriodicTick() break; } case SPELL_AURA_PERIODIC_LEECH: - case SPELL_AURA_PERIODIC_HEALTH_FUNNEL: { Unit *pCaster = GetCaster(); if(!pCaster) @@ -6060,9 +6074,9 @@ void AuraEffect::PeriodicTick() int32 stackAmount = GetParentAura()->GetStackAmount(); // Set trigger flag - uint32 procAttacker = PROC_FLAG_ON_DO_PERIODIC | PROC_FLAG_SUCCESSFUL_DAMAGING_SPELL_HIT; - uint32 procVictim = PROC_FLAG_ON_TAKE_PERIODIC | PROC_FLAG_TAKEN_DAMAGING_SPELL_HIT; - uint32 procEx = PROC_EX_NORMAL_HIT; + uint32 procAttacker = PROC_FLAG_ON_DO_PERIODIC; + uint32 procVictim = PROC_FLAG_ON_TAKE_PERIODIC; + uint32 procEx = PROC_EX_NORMAL_HIT | PROC_EX_INTERNAL_DOT; pdamage = (pdamage <= absorb+resist) ? 0 : (pdamage-absorb-resist); if (pdamage) procVictim|=PROC_FLAG_TAKEN_ANY_DAMAGE; @@ -6087,6 +6101,30 @@ void AuraEffect::PeriodicTick() pCaster->getHostilRefManager().threatAssist(pCaster, gain * 0.5f, spellProto); break; } + case SPELL_AURA_PERIODIC_HEALTH_FUNNEL: // only three spells + { + Unit *donator = GetCaster(); + if(!donator || !donator->GetHealth()) + return; + + uint32 pdamage = GetAmount() * GetParentAura()->GetStackAmount(); + if(donator->GetHealth() < pdamage) + pdamage = donator->GetHealth() - 1; + if(!pdamage) + return; + + Unit* target = m_target; // aura can be deleted in DealDamage + SpellEntry const* spellProto = GetSpellProto(); + //donator->SendSpellNonMeleeDamageLog(donator, GetId(), pdamage, GetSpellSchoolMask(spellProto), 0, 0, false, 0); + donator->ModifyHealth(-(int32)pdamage); + sLog.outDetail("PeriodicTick: donator %u target %u damage %u.", donator->GetEntry(), target->GetEntry(), pdamage); + + if(spellProto->EffectMultipleValue[GetEffIndex()] > 0) + pdamage *= spellProto->EffectMultipleValue[GetEffIndex()]; + + donator->DealHeal(target, pdamage, spellProto); + break; + } case SPELL_AURA_PERIODIC_HEAL: case SPELL_AURA_OBS_MOD_HEALTH: { @@ -6161,9 +6199,9 @@ void AuraEffect::PeriodicTick() } } - uint32 procAttacker = PROC_FLAG_ON_DO_PERIODIC | PROC_FLAG_SUCCESSFUL_HEALING_SPELL; - uint32 procVictim = PROC_FLAG_ON_TAKE_PERIODIC | PROC_FLAG_TAKEN_HEALING_SPELL; - uint32 procEx = PROC_EX_NORMAL_HIT; + uint32 procAttacker = PROC_FLAG_ON_DO_PERIODIC; + uint32 procVictim = PROC_FLAG_ON_TAKE_PERIODIC; + uint32 procEx = PROC_EX_NORMAL_HIT | PROC_EX_INTERNAL_HOT; // ignore item heals if(!haveCastItem) pCaster->ProcDamageAndSpell(target, procAttacker, procVictim, procEx, pdamage, BASE_ATTACK, spellProto); @@ -6358,9 +6396,9 @@ void AuraEffect::PeriodicTick() pCaster->SendSpellNonMeleeDamageLog(&damageInfo); // Set trigger flag - uint32 procAttacker = PROC_FLAG_ON_DO_PERIODIC | PROC_FLAG_SUCCESSFUL_DAMAGING_SPELL_HIT; - uint32 procVictim = PROC_FLAG_ON_TAKE_PERIODIC | PROC_FLAG_TAKEN_DAMAGING_SPELL_HIT; - uint32 procEx = createProcExtendMask(&damageInfo, SPELL_MISS_NONE); + uint32 procAttacker = PROC_FLAG_ON_DO_PERIODIC; + uint32 procVictim = PROC_FLAG_ON_TAKE_PERIODIC; + uint32 procEx = createProcExtendMask(&damageInfo, SPELL_MISS_NONE) | PROC_EX_INTERNAL_DOT; if (damageInfo.damage) procVictim|=PROC_FLAG_TAKEN_ANY_DAMAGE; @@ -7003,9 +7041,15 @@ void AuraEffect::HandleAuraControlVehicle(bool apply, bool Real, bool /*changeAm } else { + if(GetId() == 53111) // Devour Humanoid + { + vehicle->Kill(caster); + if(caster->GetTypeId() == TYPEID_UNIT) + ((Creature*)caster)->RemoveCorpse(); + } + // some SPELL_AURA_CONTROL_VEHICLE auras have a dummy effect on the player - remove them caster->RemoveAurasDueToSpell(GetId()); - caster->ExitVehicle(); } } diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp index 24274cf19dd..f29c883a5f4 100644 --- a/src/game/SpellEffects.cpp +++ b/src/game/SpellEffects.cpp @@ -3364,6 +3364,8 @@ void Spell::EffectSummonType(uint32 i) float radius = GetSpellRadiusForHostile(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[i])); int32 amount = damage > 0 ? damage : 1; + if (m_spellInfo->Id == 18662) // Curse of Doom + amount = 1; for(int32 count = 0; count < amount; ++count) { @@ -4938,6 +4940,10 @@ void Spell::EffectScriptEffect(uint32 effIndex) unitTarget->CastSpell(unitTarget, damage, false); break; } + case 53110: // Devour Humanoid + if(unitTarget) + unitTarget->CastSpell(m_caster, damage, true); + return; // Winged Steed of the Ebon Blade case 54729: { @@ -6651,8 +6657,6 @@ void Spell::SummonGuardian(uint32 entry, SummonPropertiesEntry const *properties switch(m_spellInfo->Id) { case 1122: // Inferno - case 18662: // Curse of Doom - amount = 1; break; } int32 duration = GetSpellDuration(m_spellInfo); diff --git a/src/game/SpellMgr.cpp b/src/game/SpellMgr.cpp index 14f7033cfc6..5998933afc1 100644 --- a/src/game/SpellMgr.cpp +++ b/src/game/SpellMgr.cpp @@ -583,6 +583,7 @@ bool IsPositiveEffect(uint32 spellId, uint32 effIndex, bool deep) case 34700: // Allergic Reaction case 31719: // Suspension case 61987: // Avenging Wrath Marker + case 11196: // Recently Bandadged return false; case 12042: // Arcane Power return true; @@ -1275,11 +1276,11 @@ bool SpellMgr::IsSpellProcEventCanTriggeredBy(SpellProcEventEntry const* spellPr { if (EventProcFlag & PROC_FLAG_SUCCESSFUL_DAMAGING_SPELL_HIT) { - if (!(procFlags & PROC_FLAG_SUCCESSFUL_DAMAGING_SPELL_HIT)) + if (!(procExtra & PROC_EX_INTERNAL_DOT)) return false; } else if (EventProcFlag & PROC_FLAG_SUCCESSFUL_HEALING_SPELL - && !(procFlags & PROC_FLAG_SUCCESSFUL_HEALING_SPELL)) + && !(procExtra & PROC_EX_INTERNAL_HOT)) return false; } @@ -1287,11 +1288,11 @@ bool SpellMgr::IsSpellProcEventCanTriggeredBy(SpellProcEventEntry const* spellPr { if (EventProcFlag & PROC_FLAG_TAKEN_DAMAGING_SPELL_HIT) { - if (!(procFlags & PROC_FLAG_TAKEN_DAMAGING_SPELL_HIT)) + if (!(procExtra & PROC_EX_INTERNAL_DOT)) return false; } else if (EventProcFlag & PROC_FLAG_TAKEN_HEALING_SPELL - && !(procFlags & PROC_FLAG_TAKEN_HEALING_SPELL)) + && !(procExtra & PROC_EX_INTERNAL_HOT)) return false; } @@ -3351,10 +3352,8 @@ void SpellMgr::LoadSpellCustomAttr() // Target entry seems to be wrong for this spell :/ spellInfo->EffectImplicitTargetA[0] = TARGET_UNIT_PARTY_CASTER; spellInfo->EffectRadiusIndex[0] = 45; - //mSpellCustomAttr[i] |= SPELL_ATTR_CU_EXCLUDE_SELF; - //break; + break; case 27820: // Mana Detonation - case 55789: // Improved Icy Talons //case 28062: case 39090: // Positive/Negative Charge //case 28085: case 39093: mSpellCustomAttr[i] |= SPELL_ATTR_CU_EXCLUDE_SELF; diff --git a/src/game/SpellMgr.h b/src/game/SpellMgr.h index 330dfd56eee..c479a57d7f6 100644 --- a/src/game/SpellMgr.h +++ b/src/game/SpellMgr.h @@ -424,7 +424,7 @@ enum ProcFlags PROC_FLAG_ON_TRAP_ACTIVATION = 0x00200000, // 21 On trap activation PROC_FLAG_TAKEN_OFFHAND_HIT = 0x00400000, // 22 Taken off-hand melee attacks(not used) - PROC_FLAG_SUCCESSFUL_OFFHAND_HIT = 0x00800000, // 23 Successful off-hand melee attacks + PROC_FLAG_SUCCESSFUL_OFFHAND_HIT = 0x00800000, // 23 Successful off-hand melee attacks ( this is probably wrong ) PROC_FLAG_DEATH = 0x01000000 // 24 Died in any way }; @@ -459,6 +459,8 @@ enum ProcFlagsEx PROC_EX_EX_TRIGGER_ALWAYS = 0x0010000, // If set trigger always ( no matter another flags) used for drop charges PROC_EX_EX_ONE_TIME_TRIGGER = 0x0020000, // If set trigger always but only one time (not used) PROC_EX_INTERNAL_CANT_PROC = 0x0800000, + PROC_EX_INTERNAL_DOT = 0x1000000, // Only for internal use + PROC_EX_INTERNAL_HOT = 0x2000000, // Only for internal use PROC_EX_INTERNAL_TRIGGERED = 0x4000000, // Only for internal use PROC_EX_INTERNAL_REQ_FAMILY = 0x8000000 // Only for internal use }; diff --git a/src/game/TargetedMovementGenerator.cpp b/src/game/TargetedMovementGenerator.cpp index 54c99ee90dd..c40568318d4 100644 --- a/src/game/TargetedMovementGenerator.cpp +++ b/src/game/TargetedMovementGenerator.cpp @@ -132,7 +132,7 @@ TargetedMovementGenerator<T>::_setTargetLocation(T &owner) i_destinationHolder.SetDestination(traveller, x, y, z); owner.addUnitState(UNIT_STAT_CHASE); if (owner.GetTypeId() == TYPEID_UNIT && ((Creature*)&owner)->canFly()) - owner.AddUnitMovementFlag(MOVEMENTFLAG_FLYING2); + owner.AddUnitMovementFlag(MOVEMENTFLAG_FLYING); i_destinationHolder.StartTravel(traveller); return true; } @@ -147,7 +147,7 @@ TargetedMovementGenerator<T>::Initialize(T &owner) owner.RemoveUnitMovementFlag(MOVEMENTFLAG_WALK_MODE); if (owner.GetTypeId() == TYPEID_UNIT && ((Creature*)&owner)->canFly()) - owner.AddUnitMovementFlag(MOVEMENTFLAG_FLYING2); + owner.AddUnitMovementFlag(MOVEMENTFLAG_FLYING); _setTargetLocation(owner); } @@ -199,7 +199,7 @@ TargetedMovementGenerator<T>::Update(T &owner, const uint32 & time_diff) { owner.addUnitState(UNIT_STAT_CHASE); if (owner.GetTypeId() == TYPEID_UNIT && ((Creature*)&owner)->canFly()) - owner.AddUnitMovementFlag(MOVEMENTFLAG_FLYING2); + owner.AddUnitMovementFlag(MOVEMENTFLAG_FLYING); i_destinationHolder.StartTravel(traveller); return true; diff --git a/src/game/TemporarySummon.cpp b/src/game/TemporarySummon.cpp index b481afb4bce..724d68c568b 100644 --- a/src/game/TemporarySummon.cpp +++ b/src/game/TemporarySummon.cpp @@ -345,7 +345,10 @@ void Puppet::Update(uint32 time) if(IsInWorld()) { if(!isAlive()) + { UnSummon(); + // TODO: why long distance .die does not remove it + } } } diff --git a/src/game/Traveller.h b/src/game/Traveller.h index dfa4913a4cc..b5d0fb28ecc 100644 --- a/src/game/Traveller.h +++ b/src/game/Traveller.h @@ -79,7 +79,7 @@ inline float Traveller<Creature>::Speed() return i_traveller.m_TempSpeed; else if(i_traveller.HasUnitMovementFlag(MOVEMENTFLAG_WALK_MODE)) return i_traveller.GetSpeed(MOVE_WALK); - else if(i_traveller.HasUnitMovementFlag(MOVEMENTFLAG_FLYING2)) + else if(i_traveller.HasUnitMovementFlag(MOVEMENTFLAG_FLYING)) return i_traveller.GetSpeed(MOVE_FLIGHT); else return i_traveller.GetSpeed(MOVE_RUN); @@ -98,7 +98,7 @@ inline float Traveller<Creature>::GetMoveDestinationTo(float x, float y, float z float dy = y - GetPositionY(); float dz = z - GetPositionZ(); - if(i_traveller.HasUnitMovementFlag(MOVEMENTFLAG_FLYING2)) + if(i_traveller.HasUnitMovementFlag(MOVEMENTFLAG_FLYING)) return sqrt((dx*dx) + (dy*dy) + (dz*dz)); else //Walking on the ground return sqrt((dx*dx) + (dy*dy)); diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 944a92ae755..dd1307e7ef4 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -417,7 +417,7 @@ void Unit::SendMonsterMoveByPath(Path const& path, uint32 start, uint32 end) addUnitState(UNIT_STAT_MOVE); } -void Unit::SendMonsterMoveTransport(Vehicle *vehicle, bool apply) +void Unit::SendMonsterMoveTransport(Vehicle *vehicle) { WorldPacket data(SMSG_MONSTER_MOVE_TRANSPORT, GetPackGUID().size()+vehicle->GetPackGUID().size()); data.append(GetPackGUID()); @@ -432,9 +432,9 @@ void Unit::SendMonsterMoveTransport(Vehicle *vehicle, bool apply) data << GetTransOffsetO(); data << uint32(MOVEFLAG_ENTER_TRANSPORT); data << uint32(0); // move time - data << GetTransOffsetX(); - data << GetTransOffsetY(); - data << GetTransOffsetZ(); + data << uint32(0);//GetTransOffsetX(); + data << uint32(0);//GetTransOffsetY(); + data << uint32(0);//GetTransOffsetZ(); SendMessageToSet(&data, true); } @@ -3508,6 +3508,7 @@ void Unit::InterruptSpell(uint32 spellType, bool withDelayed, bool withInstant) { assert(spellType < CURRENT_MAX_SPELL); + //sLog.outDebug("Interrupt spell for unit %u.", GetEntry()); Spell *spell = m_currentSpells[spellType]; if(spell && (withDelayed || spell->getState() != SPELL_STATE_DELAYED) @@ -7035,6 +7036,32 @@ bool Unit::HandleModDamagePctTakenAuraProc(Unit *pVictim, uint32 damage, AuraEff return true; } +// Used in case when access to whole aura is needed +// All procs should be handled like this... +bool Unit::HandleAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAura, SpellEntry const * procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown, bool * handled) +{ + SpellEntry const *dummySpell = triggeredByAura->GetSpellProto(); + + switch(dummySpell->SpellFamilyName) + { + case SPELLFAMILY_DEATHKNIGHT: + { + switch(dummySpell->Id) + { + // Hungering Cold aura drop + case 51209: + *handled = true; + // Drop only in disease case + if (procSpell && procSpell->Dispel == DISPEL_DISEASE) + return false; + return true; + } + break; + } + } + return false; +} + bool Unit::HandleProcTriggerSpell(Unit *pVictim, uint32 damage, AuraEffect* triggeredByAura, SpellEntry const *procSpell, uint32 procFlags, uint32 procEx, uint32 cooldown) { // Get triggered aura spell info @@ -7248,15 +7275,16 @@ bool Unit::HandleProcTriggerSpell(Unit *pVictim, uint32 damage, AuraEffect* trig trigger_spell_id = 18093; } - // Drain Soul + // Improved Drain Soul else if (auraSpellInfo->SpellFamilyFlags[0] & 0x4000) { - Unit::AuraEffectList const& mAddFlatModifier = GetAurasByType(SPELL_AURA_ADD_FLAT_MODIFIER); + Unit::AuraEffectList const& mAddFlatModifier = GetAurasByType(SPELL_AURA_DUMMY); for(Unit::AuraEffectList::const_iterator i = mAddFlatModifier.begin(); i != mAddFlatModifier.end(); ++i) { if ((*i)->GetMiscValue() == SPELLMOD_CHANCE_OF_SUCCESS && (*i)->GetSpellProto()->SpellIconID == 113) { int32 value2 = CalculateSpellDamage((*i)->GetSpellProto(),2,(*i)->GetSpellProto()->EffectBasePoints[2],this); + basepoints0 = value2 * GetMaxPower(POWER_MANA) / 100; // Drain Soul CastCustomSpell(this, 18371, &basepoints0, NULL, NULL, true, castItem, triggeredByAura); break; @@ -7651,6 +7679,27 @@ bool Unit::HandleProcTriggerSpell(Unit *pVictim, uint32 damage, AuraEffect* trig // dummy basepoints or other customs switch(trigger_spell_id) { + // Auras which should proc on area aura source (caster in this case): + // Turn the Tables + case 52914: + case 52915: + case 52910: + // Honor Among Thieves + case 52916: + { + target = triggeredByAura->GetParentAura()->GetCaster(); + if(!target) + return false; + + if( cooldown && GetTypeId()==TYPEID_PLAYER && ((Player*)target)->HasSpellCooldown(trigger_spell_id)) + return false; + + target->CastSpell(target,trigger_spell_id,true,castItem,triggeredByAura); + + if( cooldown && GetTypeId()==TYPEID_PLAYER ) + ((Player*)this)->AddSpellCooldown(trigger_spell_id,0,time(NULL) + cooldown); + return true; + } // Cast positive spell on enemy target case 7099: // Curse of Mending case 39647: // Curse of Mending @@ -7729,6 +7778,11 @@ bool Unit::HandleProcTriggerSpell(Unit *pVictim, uint32 damage, AuraEffect* trig ((Player*)this)->RemoveCategoryCooldown(1209); break; } + case 63375: // Improved Stormstrike + { + basepoints0 = GetCreateMana() * 0.20f; + break; + } // Brain Freeze case 57761: { @@ -12451,7 +12505,7 @@ void Unit::ProcDamageAndSpellFor( bool isVictim, Unit * pTarget, uint32 procFlag // Fill procTriggered list for(AuraMap::const_iterator itr = GetAuras().begin(); itr!= GetAuras().end(); ++itr) { - // Do not allow auras to proc from effect of itself + // Do not allow auras to proc from effect triggered by itself if (procAura && procAura->Id == itr->first) continue; ProcTriggeredData triggerData(itr->second); @@ -12498,8 +12552,16 @@ void Unit::ProcDamageAndSpellFor( bool isVictim, Unit * pTarget, uint32 procFlag if (GetTypeId() == TYPEID_PLAYER && i->spellProcEvent && i->spellProcEvent->cooldown) cooldown = i->spellProcEvent->cooldown; - uint32 procDebug = 0; + // This bool is needed till separate aura effect procs are still here + bool handled = false; + if (HandleAuraProc(pTarget, damage, i->aura, procSpell, procFlag, procExtra, cooldown, &handled)) + { + sLog.outDebug("ProcDamageAndSpell: casting spell %u (triggered with value by %s aura of spell %u)", spellInfo->Id,(isVictim?"a victim's":"an attacker's"), Id); + takeCharges = true; + } + uint32 procDebug = 0; + if (!handled) for (uint8 effIndex = 0; effIndex<MAX_SPELL_EFFECTS;++effIndex) { if (!(i->effMask & (1<<effIndex))) @@ -13330,8 +13392,9 @@ bool Unit::IsTriggeredAtSpellProcEvent(Unit *pVictim, Aura * aura, SpellEntry co return false; } // Aura added by spell can`t trogger from self (prevent drop charges/do triggers) - // But except periodic triggers (can triggered from self) - if(procSpell && procSpell->Id == spellProto->Id && !(spellProto->procFlags&PROC_FLAG_ON_TAKE_PERIODIC)) + // But except periodic and kill triggers (can triggered from self) + if(procSpell && procSpell->Id == spellProto->Id + && !(spellProto->procFlags&(PROC_FLAG_ON_TAKE_PERIODIC | PROC_FLAG_KILL))) return false; // Check if current equipment allows aura to proc @@ -13500,6 +13563,9 @@ void Unit::Kill(Unit *pVictim, bool durabilityLoss) // Prevent killing unit twice (and giving reward from kill twice) if (!pVictim->GetHealth()) return; + + //sLog.outError("%u kill %u", GetEntry(), pVictim->GetEntry()); + pVictim->SetHealth(0); // find player: owner of controlled `this` or `this` itself maybe @@ -13699,7 +13765,7 @@ void Unit::SetControlled(bool apply, UnitState state) { case UNIT_STAT_STUNNED: if(HasAuraType(SPELL_AURA_MOD_STUN)) return; else SetStunned(false); break; - case UNIT_STAT_ROOT: if(HasAuraType(SPELL_AURA_MOD_ROOT)) return; + case UNIT_STAT_ROOT: if(HasAuraType(SPELL_AURA_MOD_ROOT) || m_Vehicle) return; else SetRooted(false); break; case UNIT_STAT_CONFUSED:if(HasAuraType(SPELL_AURA_MOD_CONFUSE)) return; else SetConfused(false); break; @@ -13732,13 +13798,13 @@ void Unit::SetStunned(bool apply) SetUInt64Value(UNIT_FIELD_TARGET, 0); SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED); CastStop(); + AddUnitMovementFlag(MOVEMENTFLAG_ROOT); // Creature specific if(GetTypeId() != TYPEID_PLAYER) ((Creature*)this)->StopMoving(); else SetStandState(UNIT_STAND_STATE_STAND); - // SetUnitMovementFlags(0); //Clear movement flags WorldPacket data(SMSG_FORCE_MOVE_ROOT, 8); data.append(GetPackGUID()); @@ -13761,21 +13827,20 @@ void Unit::SetStunned(bool apply) data.append(GetPackGUID()); data << uint32(0); SendMessageToSet(&data,true); + + RemoveUnitMovementFlag(MOVEMENTFLAG_ROOT); } } } void Unit::SetRooted(bool apply) { - uint32 apply_stat = UNIT_STAT_ROOT; if(apply) { - //SetFlag(UNIT_FIELD_FLAGS,(apply_stat<<16)); // probably wrong + AddUnitMovementFlag(MOVEMENTFLAG_ROOT); if(GetTypeId() == TYPEID_PLAYER) { - //SetUnitMovementFlags(0); - WorldPacket data(SMSG_FORCE_MOVE_ROOT, 10); data.append(GetPackGUID()); data << (uint32)2; @@ -13786,8 +13851,6 @@ void Unit::SetRooted(bool apply) } else { - //RemoveFlag(UNIT_FIELD_FLAGS,(apply_stat<<16)); // probably wrong - if(!hasUnitState(UNIT_STAT_STUNNED)) // prevent allow move if have also stun effect { if(GetTypeId() == TYPEID_PLAYER) @@ -13797,6 +13860,8 @@ void Unit::SetRooted(bool apply) data << (uint32)2; SendMessageToSet(&data,true); } + + RemoveUnitMovementFlag(MOVEMENTFLAG_ROOT); } } } @@ -13805,6 +13870,8 @@ void Unit::SetFeared(bool apply) { if(apply) { + SetUInt64Value(UNIT_FIELD_TARGET, 0); + Unit *caster = NULL; Unit::AuraEffectList const& fearAuras = GetAurasByType(SPELL_AURA_MOD_FEAR); if(!fearAuras.empty()) @@ -13815,8 +13882,13 @@ void Unit::SetFeared(bool apply) } else { - if(isAlive() && GetMotionMaster()->GetCurrentMovementGeneratorType() == FLEEING_MOTION_TYPE) - GetMotionMaster()->MovementExpired(); + if(isAlive()) + { + if(GetMotionMaster()->GetCurrentMovementGeneratorType() == FLEEING_MOTION_TYPE) + GetMotionMaster()->MovementExpired(); + if(getVictim()) + SetUInt64Value(UNIT_FIELD_TARGET, getVictim()->GetGUID()); + } } if (GetTypeId() == TYPEID_PLAYER) @@ -13827,12 +13899,18 @@ void Unit::SetConfused(bool apply) { if(apply) { + SetUInt64Value(UNIT_FIELD_TARGET, 0); GetMotionMaster()->MoveConfused(); } else { - if(isAlive() && GetMotionMaster()->GetCurrentMovementGeneratorType() == CONFUSED_MOTION_TYPE) - GetMotionMaster()->MovementExpired(); + if(isAlive()) + { + if(GetMotionMaster()->GetCurrentMovementGeneratorType() == CONFUSED_MOTION_TYPE) + GetMotionMaster()->MovementExpired(); + if(getVictim()) + SetUInt64Value(UNIT_FIELD_TARGET, getVictim()->GetGUID()); + } } if(GetTypeId() == TYPEID_PLAYER) @@ -13909,6 +13987,8 @@ void Unit::SetCharmedBy(Unit* charmer, CharmType type) switch(type) { case CHARM_TYPE_VEHICLE: + SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNK_24); + ((Player*)charmer)->SetClientControl(this, 1); ((Player*)charmer)->SetViewpoint(this, true); ((Player*)charmer)->VehicleSpellInitialize(); break; @@ -14009,6 +14089,7 @@ void Unit::RemoveCharmedBy(Unit *charmer) switch(type) { case CHARM_TYPE_VEHICLE: + ((Player*)charmer)->SetClientControl(charmer, 1); ((Player*)charmer)->SetViewpoint(this, false); break; case CHARM_TYPE_POSSESS: @@ -14472,16 +14553,14 @@ void Unit::EnterVehicle(Vehicle *vehicle, int8 seatId) return; } - m_Vehicle->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNK_24); - //m_Vehicle->setFaction(getFaction()); - addUnitState(UNIT_STAT_ONVEHICLE); + SetControlled(true, UNIT_STAT_ROOT); //movementInfo is set in AddPassenger //packets are sent in AddPassenger if(GetTypeId() == TYPEID_PLAYER) { - ((Player*)this)->SetClientControl(vehicle, 1); + //((Player*)this)->SetClientControl(vehicle, 1); WorldPacket data(SMSG_ON_CANCEL_EXPECTED_RIDE_VEHICLE_AURA, 0); ((Player*)this)->GetSession()->SendPacket(&data); } @@ -14511,17 +14590,18 @@ void Unit::ExitVehicle() if(!m_Vehicle) return; - m_Vehicle->RemovePassenger(this); + //sLog.outError("exit vehicle"); - m_Vehicle->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNK_24); - //setFaction((GetTeam() == ALLIANCE) ? GetCreatureInfo()->faction_A : GetCreatureInfo()->faction_H); + m_Vehicle->RemovePassenger(this); // This should be done before dismiss, because there may be some aura removal Vehicle *vehicle = m_Vehicle; m_Vehicle = NULL; clearUnitState(UNIT_STAT_ONVEHICLE); - RemoveUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT + MOVEMENTFLAG_FLY_UNK1); + SetControlled(false, UNIT_STAT_ROOT); + + RemoveUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT); m_movementInfo.t_x = 0; m_movementInfo.t_y = 0; m_movementInfo.t_z = 0; @@ -14529,18 +14609,16 @@ void Unit::ExitVehicle() m_movementInfo.t_time = 0; m_movementInfo.t_seat = 0; - //Send leave vehicle + //Send leave vehicle, not correct if(GetTypeId() == TYPEID_PLAYER) { - ((Player*)this)->SetClientControl(this, 1); + //((Player*)this)->SetClientControl(this, 1); ((Player*)this)->SendTeleportAckMsg(); } WorldPacket data; BuildHeartBeatMsg(&data); SendMessageToSet(&data, false); - //SendMonsterMoveTransport(m_Vehicle, false); - if(vehicle->GetOwnerGUID() == GetGUID()) vehicle->Dismiss(); } @@ -14593,7 +14671,7 @@ void Unit::BuildMovementPacket(ByteBuffer *data) const } // 0x02200000 - if((GetUnitMovementFlags() & (MOVEMENTFLAG_SWIMMING | MOVEMENTFLAG_FLYING2)) + if((GetUnitMovementFlags() & (MOVEMENTFLAG_SWIMMING | MOVEMENTFLAG_FLYING)) || (m_movementInfo.unk1 & 0x20)) *data << (float)m_movementInfo.s_pitch; @@ -14611,14 +14689,20 @@ void Unit::BuildMovementPacket(ByteBuffer *data) const // 0x04000000 if(GetUnitMovementFlags() & MOVEMENTFLAG_SPLINE) *data << (float)m_movementInfo.u_unk1; + + /*if(GetTypeId() == TYPEID_PLAYER) + { + sLog.outString("Send MovementInfo:"); + OutMovementInfo(); + }*/ } void Unit::OutMovementInfo() const { - sLog.outString("MovementInfo: Flag %u, Unk1 %u, Time %u, Pos %f %f %f %f, Fall %u", m_movementInfo.flags, (uint32)m_movementInfo.unk1, m_movementInfo.time, GetPositionX(), GetPositionY(), GetPositionZ(), GetOrientation(), m_movementInfo.fallTime); + sLog.outString("MovementInfo for %u: Flag %u, Unk1 %u, Time %u, Pos %f %f %f %f, Fall %u", GetEntry(), m_movementInfo.flags, (uint32)m_movementInfo.unk1, m_movementInfo.time, GetPositionX(), GetPositionY(), GetPositionZ(), GetOrientation(), m_movementInfo.fallTime); if(m_movementInfo.flags & MOVEMENTFLAG_ONTRANSPORT) sLog.outString("Transport: GUID " UI64FMTD ", Pos %f %f %f %f, Time %u, Seat %d", m_movementInfo.t_guid, m_movementInfo.t_x, m_movementInfo.t_y, m_movementInfo.t_z, m_movementInfo.t_o, m_movementInfo.t_time, (int32)m_movementInfo.t_seat); - if((m_movementInfo.flags & (MOVEMENTFLAG_SWIMMING | MOVEMENTFLAG_FLYING2)) || (m_movementInfo.unk1 & 0x20)) + if((m_movementInfo.flags & (MOVEMENTFLAG_SWIMMING | MOVEMENTFLAG_FLYING)) || (m_movementInfo.unk1 & 0x20)) sLog.outString("Pitch: %f", m_movementInfo.s_pitch); if(m_movementInfo.flags & MOVEMENTFLAG_JUMPING) sLog.outString("Jump: speedz %f, sin %f, cos %f, speedxy %f", m_movementInfo.j_zspeed, m_movementInfo.j_sinAngle, m_movementInfo.j_cosAngle, m_movementInfo.j_xyspeed); @@ -14626,6 +14710,20 @@ void Unit::OutMovementInfo() const sLog.outString("Spline: %f", m_movementInfo.u_unk1); } +void Unit::SetFlying(bool apply) +{ + if(apply) + { + SetByteFlag(UNIT_FIELD_BYTES_1, 3, 0x02); + AddUnitMovementFlag(MOVEMENTFLAG_FLYING); + } + else + { + RemoveByteFlag(UNIT_FIELD_BYTES_1, 3, 0x02); + RemoveUnitMovementFlag(MOVEMENTFLAG_FLYING); + } +} + void Unit::NearTeleportTo( float x, float y, float z, float orientation, bool casting /*= false*/ ) { if(GetTypeId() == TYPEID_PLAYER) diff --git a/src/game/Unit.h b/src/game/Unit.h index 65492676175..00478a74acd 100644 --- a/src/game/Unit.h +++ b/src/game/Unit.h @@ -36,6 +36,8 @@ #include "DBCStructure.h" #include <list> +class Vehicle; + #define WORLD_TRIGGER 12999 enum SpellInterruptFlags @@ -354,8 +356,8 @@ enum DamageTypeToSchool enum AuraRemoveMode { - AURA_REMOVE_BY_DEFAULT=0, - AURA_REMOVE_BY_STACK, // change stack, single aura remove, + AURA_REMOVE_BY_DEFAULT=0, // scripted remove, remove by stack with aura with different ids and sc aura remove + AURA_REMOVE_BY_STACK, // replace by aura with same id AURA_REMOVE_BY_CANCEL, AURA_REMOVE_BY_ENEMY_SPELL, // dispel and absorb aura destroy AURA_REMOVE_BY_EXPIRE, // dispel and absorb aura destroy @@ -640,21 +642,29 @@ enum MovementFlags MOVEMENTFLAG_WALK_MODE = 0x00000100, // Walking MOVEMENTFLAG_ONTRANSPORT = 0x00000200, // Used for flying on some creatures MOVEMENTFLAG_LEVITATING = 0x00000400, - MOVEMENTFLAG_FLY_UNK1 = 0x00000800, + MOVEMENTFLAG_ROOT = 0x00000800, MOVEMENTFLAG_JUMPING = 0x00001000, - MOVEMENTFLAG_UNK4 = 0x00002000, + MOVEMENTFLAG_FALL_DAMAGE = 0x00002000, // newZ < oldZ MOVEMENTFLAG_FALLING = 0x00004000, // 0x8000, 0x10000, 0x20000, 0x40000, 0x80000, 0x100000 MOVEMENTFLAG_SWIMMING = 0x00200000, // appears with fly flag also - MOVEMENTFLAG_FLY_UP = 0x00400000, // press "space" when flying + MOVEMENTFLAG_ASCEND = 0x00400000, // press "space" when flying MOVEMENTFLAG_CAN_FLY = 0x00800000, - MOVEMENTFLAG_FLYING = 0x01000000, // fly land - MOVEMENTFLAG_FLYING2 = 0x02000000, // fly hover + MOVEMENTFLAG_FLY_MODE = 0x01000000, // can fly + MOVEMENTFLAG_FLYING = 0x02000000, // hover MOVEMENTFLAG_SPLINE = 0x04000000, // used for flight paths MOVEMENTFLAG_SPLINE2 = 0x08000000, // used for flight paths MOVEMENTFLAG_WATERWALKING = 0x10000000, // prevent unit from falling through water MOVEMENTFLAG_SAFE_FALL = 0x20000000, // active rogue safe fall spell (passive) - MOVEMENTFLAG_UNK3 = 0x40000000 + MOVEMENTFLAG_HOVER = 0x40000000, // hover, cannot jump + + MOVEMENTFLAG_MOVING = + MOVEMENTFLAG_FORWARD |MOVEMENTFLAG_BACKWARD |MOVEMENTFLAG_STRAFE_LEFT|MOVEMENTFLAG_STRAFE_RIGHT| + MOVEMENTFLAG_PITCH_UP|MOVEMENTFLAG_PITCH_DOWN|MOVEMENTFLAG_FALL_DAMAGE| + MOVEMENTFLAG_JUMPING |MOVEMENTFLAG_FALLING |MOVEMENTFLAG_ASCEND | + MOVEMENTFLAG_SPLINE, + MOVEMENTFLAG_TURNING = + MOVEMENTFLAG_LEFT | MOVEMENTFLAG_RIGHT, }; /* @@ -1311,7 +1321,7 @@ class TRINITY_DLL_SPEC Unit : public WorldObject void SendMonsterMove(float NewPosX, float NewPosY, float NewPosZ, uint32 MoveFlags, uint32 time, float speedZ, Player *player = NULL); //void SendMonsterMove(float NewPosX, float NewPosY, float NewPosZ, uint8 type, uint32 MovementFlags, uint32 Time, Player* player = NULL); void SendMonsterMoveByPath(Path const& path, uint32 start, uint32 end); - void SendMonsterMoveTransport(Vehicle *vehicle, bool apply); + void SendMonsterMoveTransport(Vehicle *vehicle); void SendMonsterMoveWithSpeed(float x, float y, float z, uint32 transitTime = 0, Player* player = NULL); void SendMonsterMoveWithSpeedToCurrentDestination(Player* player = NULL); void SendMovementFlagUpdate(); @@ -1765,6 +1775,12 @@ class TRINITY_DLL_SPEC Unit : public WorldObject void SetTransport(Transport * t) { m_transport = t; } void BuildMovementPacket(ByteBuffer *data) const; + + bool isMoving() const { return m_movementInfo.HasMovementFlag(MOVEMENTFLAG_MOVING); } + bool isTurning() const { return m_movementInfo.HasMovementFlag(MOVEMENTFLAG_TURNING); } + bool canFly() const { return m_movementInfo.HasMovementFlag(MOVEMENTFLAG_FLY_MODE); } + bool IsFlying() const { return m_movementInfo.HasMovementFlag(MOVEMENTFLAG_FLYING); } + void SetFlying(bool apply); protected: explicit Unit (); @@ -1834,6 +1850,7 @@ class TRINITY_DLL_SPEC Unit : public WorldObject bool HandleDummyAuraProc( Unit *pVictim, uint32 damage, AuraEffect* triggeredByAura, SpellEntry const *procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown); bool HandleObsModEnergyAuraProc( Unit *pVictim, uint32 damage, AuraEffect* triggeredByAura, SpellEntry const *procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown); bool HandleModDamagePctTakenAuraProc(Unit *pVictim, uint32 damage, AuraEffect* triggeredByAura, SpellEntry const *procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown); + bool HandleAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAura, SpellEntry const * procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown, bool * handled); bool HandleHasteAuraProc( Unit *pVictim, uint32 damage, AuraEffect* triggeredByAura, SpellEntry const *procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown); bool HandleProcTriggerSpell(Unit *pVictim, uint32 damage, AuraEffect* triggeredByAura, SpellEntry const *procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown); bool HandleOverrideClassScriptAuraProc(Unit *pVictim, uint32 damage, AuraEffect* triggeredByAura, SpellEntry const *procSpell, uint32 cooldown); diff --git a/src/game/Vehicle.cpp b/src/game/Vehicle.cpp index 2271bcc3c4a..0464c52705e 100644 --- a/src/game/Vehicle.cpp +++ b/src/game/Vehicle.cpp @@ -44,8 +44,7 @@ void Vehicle::AddToWorld() if(m_zoneScript) m_zoneScript->OnCreatureCreate(this, true); ObjectAccessor::Instance().AddObject(this); - Unit::AddToWorld(); - AIM_Initialize(); + switch(GetEntry()) { //case 27850:InstallAccessory(27905,1);break; @@ -66,11 +65,28 @@ void Vehicle::AddToWorld() InstallAccessory(33142,2); break; } - if(!GetMaxPower(POWER_MANA)) // m_vehicleInfo->36 + for(uint32 i = 0; i < MAX_SPELL_VEHICLE; ++i) { - setPowerType(POWER_ENERGY); - SetMaxPower(POWER_ENERGY, 100); + if(!m_spells[i]) + continue; + + SpellEntry const *spellInfo = sSpellStore.LookupEntry(m_spells[i]); + if(!spellInfo) + continue; + + if(spellInfo->powerType == POWER_MANA) + break; + + if(spellInfo->powerType == POWER_ENERGY) + { + setPowerType(POWER_ENERGY); + SetMaxPower(POWER_ENERGY, 100); + break; + } } + + Unit::AddToWorld(); + AIM_Initialize(); } } @@ -114,7 +130,7 @@ void Vehicle::Update(uint32 diff) { Creature::Update(diff); //310 - if(getPowerType() == POWER_ENERGY) + if(getPowerType() == POWER_ENERGY) // m_vehicleInfo->36 ModifyPower(POWER_ENERGY, 100); } @@ -224,6 +240,8 @@ void Vehicle::InstallAccessory(uint32 entry, int8 seatId) accessory->m_Vehicle = this; AddPassenger(accessory, seatId); + // This is not good, we have to send update twice + accessory->SendMovementFlagUpdate(); } bool Vehicle::AddPassenger(Unit *unit, int8 seatId) @@ -266,7 +284,7 @@ bool Vehicle::AddPassenger(Unit *unit, int8 seatId) //SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNK_24); - unit->AddUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT + MOVEMENTFLAG_FLY_UNK1); + unit->AddUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT); VehicleSeatEntry const *veSeat = seat->second.seatInfo; unit->m_movementInfo.t_x = veSeat->m_attachmentOffsetX; unit->m_movementInfo.t_y = veSeat->m_attachmentOffsetY; @@ -278,16 +296,12 @@ bool Vehicle::AddPassenger(Unit *unit, int8 seatId) if(unit->GetTypeId() == TYPEID_PLAYER && seat->first == 0 && seat->second.seatInfo->IsUsable()) // not right SetCharmedBy(unit, CHARM_TYPE_VEHICLE); - if(false) - { - unit->SendMonsterMoveTransport(this, true); - } - else - { - if(unit->GetTypeId() == TYPEID_PLAYER) - ((Player*)unit)->SendTeleportAckMsg(); - unit->SendMovementFlagUpdate(); - } + if(IsInWorld()) + unit->SendMonsterMoveTransport(this); + + //if(unit->GetTypeId() == TYPEID_PLAYER) + // ((Player*)unit)->SendTeleportAckMsg(); + //unit->SendMovementFlagUpdate(); return true; } diff --git a/src/game/Vehicle.h b/src/game/Vehicle.h index e0473c45560..309e8a5f02c 100644 --- a/src/game/Vehicle.h +++ b/src/game/Vehicle.h @@ -35,7 +35,7 @@ struct VehicleSeat typedef std::map<int8, VehicleSeat> SeatMap; -class Vehicle : public Creature +class TRINITY_DLL_SPEC Vehicle : public Creature { public: explicit Vehicle(); diff --git a/src/game/WaypointMovementGenerator.cpp b/src/game/WaypointMovementGenerator.cpp index 49d38799fe3..d256b01bd5d 100644 --- a/src/game/WaypointMovementGenerator.cpp +++ b/src/game/WaypointMovementGenerator.cpp @@ -86,7 +86,7 @@ void WaypointMovementGenerator<Creature>::InitTraveller(Creature &unit, const Wa unit.SetUInt32Value(UNIT_FIELD_BYTES_1, 0); if(unit.canFly()) - unit.AddUnitMovementFlag(MOVEMENTFLAG_FLYING2); + unit.AddUnitMovementFlag(MOVEMENTFLAG_FLYING); unit.addUnitState(UNIT_STAT_ROAMING); } diff --git a/src/game/WorldSession.cpp b/src/game/WorldSession.cpp index 6c2b9cd9932..91d1e6e018a 100644 --- a/src/game/WorldSession.cpp +++ b/src/game/WorldSession.cpp @@ -654,7 +654,7 @@ void WorldSession::ReadMovementInfo(WorldPacket &data, MovementInfo *mi) data >> mi->t_seat; } - if((mi->flags & (MOVEMENTFLAG_SWIMMING | MOVEMENTFLAG_FLYING2)) || (mi->unk1 & 0x20)) + if((mi->flags & (MOVEMENTFLAG_SWIMMING | MOVEMENTFLAG_FLYING)) || (mi->unk1 & 0x20)) { CHECK_PACKET_SIZE(data, data.rpos()+4); data >> mi->s_pitch; |
