aboutsummaryrefslogtreecommitdiff
path: root/src/game
diff options
context:
space:
mode:
Diffstat (limited to 'src/game')
-rw-r--r--src/game/Creature.cpp15
-rw-r--r--src/game/Creature.h2
-rw-r--r--src/game/GameObject.cpp2
-rw-r--r--src/game/GridNotifiers.cpp27
-rw-r--r--src/game/GridNotifiers.h2
-rw-r--r--src/game/Level3.cpp28
-rw-r--r--src/game/MiscHandler.cpp2
-rw-r--r--src/game/MovementHandler.cpp19
-rw-r--r--src/game/Player.cpp40
-rw-r--r--src/game/Player.h16
-rw-r--r--src/game/PointMovementGenerator.cpp2
-rw-r--r--src/game/RandomMovementGenerator.cpp6
-rw-r--r--src/game/SharedDefines.h2
-rw-r--r--src/game/Spell.cpp129
-rw-r--r--src/game/Spell.h5
-rw-r--r--src/game/SpellAuras.cpp102
-rw-r--r--src/game/SpellEffects.cpp8
-rw-r--r--src/game/SpellMgr.cpp13
-rw-r--r--src/game/SpellMgr.h4
-rw-r--r--src/game/TargetedMovementGenerator.cpp6
-rw-r--r--src/game/TemporarySummon.cpp3
-rw-r--r--src/game/Traveller.h4
-rw-r--r--src/game/Unit.cpp172
-rw-r--r--src/game/Unit.h35
-rw-r--r--src/game/Vehicle.cpp48
-rw-r--r--src/game/Vehicle.h2
-rw-r--r--src/game/WaypointMovementGenerator.cpp2
-rw-r--r--src/game/WorldSession.cpp2
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;