aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/bindings/scripts/VC71/71ScriptDev2.vcproj2
-rw-r--r--src/bindings/scripts/VC80/80ScriptDev2.vcproj2
-rw-r--r--src/bindings/scripts/include/sc_creature.cpp46
-rw-r--r--src/game/ConfusedMovementGenerator.cpp4
-rw-r--r--src/game/DestinationHolder.h2
-rw-r--r--src/game/DestinationHolderImp.h59
-rw-r--r--src/game/FleeingMovementGenerator.cpp2
-rw-r--r--src/game/GridNotifiersImpl.h2
-rw-r--r--src/game/HomeMovementGenerator.cpp2
-rw-r--r--src/game/IdleMovementGenerator.cpp9
-rw-r--r--src/game/PetHandler.cpp2
-rw-r--r--src/game/PointMovementGenerator.cpp3
-rw-r--r--src/game/RandomMovementGenerator.cpp4
-rw-r--r--src/game/SharedDefines.h71
-rw-r--r--src/game/Spell.cpp1040
-rw-r--r--src/game/Spell.h49
-rw-r--r--src/game/SpellEffects.cpp10
-rw-r--r--src/game/SpellMgr.cpp139
-rw-r--r--src/game/SpellMgr.h20
-rw-r--r--src/game/TargetedMovementGenerator.cpp2
-rw-r--r--src/game/Unit.cpp8
-rw-r--r--src/game/Unit.h3
-rw-r--r--src/game/WaypointMovementGenerator.cpp4
23 files changed, 772 insertions, 713 deletions
diff --git a/src/bindings/scripts/VC71/71ScriptDev2.vcproj b/src/bindings/scripts/VC71/71ScriptDev2.vcproj
index 3f8ea7f0c58..eacdacec170 100644
--- a/src/bindings/scripts/VC71/71ScriptDev2.vcproj
+++ b/src/bindings/scripts/VC71/71ScriptDev2.vcproj
@@ -525,7 +525,7 @@
>
</File>
<File
- RelativePath="..\scripts\zone\eastern_plaguelands\scarlet_enclave.cpp"
+ RelativePath="..\scripts\zone\eastern_plaguelands\the_scarlet_enclave.cpp"
>
</File>
</Filter>
diff --git a/src/bindings/scripts/VC80/80ScriptDev2.vcproj b/src/bindings/scripts/VC80/80ScriptDev2.vcproj
index a1efa4952bc..ace2ac54ca3 100644
--- a/src/bindings/scripts/VC80/80ScriptDev2.vcproj
+++ b/src/bindings/scripts/VC80/80ScriptDev2.vcproj
@@ -694,7 +694,7 @@
>
</File>
<File
- RelativePath="..\scripts\zone\eastern_plaguelands\scarlet_enclave.cpp"
+ RelativePath="..\scripts\zone\eastern_plaguelands\the_scarlet_enclave.cpp"
>
</File>
</Filter>
diff --git a/src/bindings/scripts/include/sc_creature.cpp b/src/bindings/scripts/include/sc_creature.cpp
index 6d1fbc73dd5..1942fdadd71 100644
--- a/src/bindings/scripts/include/sc_creature.cpp
+++ b/src/bindings/scripts/include/sc_creature.cpp
@@ -552,49 +552,49 @@ void FillSpellSummary()
for (int j=0; j<3; j++)
{
//Spell targets self
- if ( TempSpell->EffectImplicitTargetA[j] == TARGET_SELF )
+ if ( TempSpell->EffectImplicitTargetA[j] == TARGET_UNIT_CASTER )
SpellSummary[i].Targets |= 1 << (SELECT_TARGET_SELF-1);
//Spell targets a single enemy
- if ( TempSpell->EffectImplicitTargetA[j] == TARGET_CHAIN_DAMAGE ||
- TempSpell->EffectImplicitTargetA[j] == TARGET_CURRENT_ENEMY_COORDINATES )
+ if ( TempSpell->EffectImplicitTargetA[j] == TARGET_UNIT_TARGET_ENEMY ||
+ TempSpell->EffectImplicitTargetA[j] == TARGET_DST_TARGET_ENEMY )
SpellSummary[i].Targets |= 1 << (SELECT_TARGET_SINGLE_ENEMY-1);
//Spell targets AoE at enemy
- if ( TempSpell->EffectImplicitTargetA[j] == TARGET_ALL_ENEMY_IN_AREA ||
- TempSpell->EffectImplicitTargetA[j] == TARGET_ALL_ENEMY_IN_AREA_INSTANT ||
- TempSpell->EffectImplicitTargetA[j] == TARGET_DEST_CASTER ||
+ if ( TempSpell->EffectImplicitTargetA[j] == TARGET_UNIT_AREA_ENEMY_SRC ||
+ TempSpell->EffectImplicitTargetA[j] == TARGET_UNIT_AREA_ENEMY_DST ||
+ TempSpell->EffectImplicitTargetA[j] == TARGET_SRC_CASTER ||
TempSpell->EffectImplicitTargetA[j] == TARGET_DEST_DYNOBJ_ENEMY )
SpellSummary[i].Targets |= 1 << (SELECT_TARGET_AOE_ENEMY-1);
//Spell targets an enemy
- if ( TempSpell->EffectImplicitTargetA[j] == TARGET_CHAIN_DAMAGE ||
- TempSpell->EffectImplicitTargetA[j] == TARGET_CURRENT_ENEMY_COORDINATES ||
- TempSpell->EffectImplicitTargetA[j] == TARGET_ALL_ENEMY_IN_AREA ||
- TempSpell->EffectImplicitTargetA[j] == TARGET_ALL_ENEMY_IN_AREA_INSTANT ||
- TempSpell->EffectImplicitTargetA[j] == TARGET_DEST_CASTER ||
+ if ( TempSpell->EffectImplicitTargetA[j] == TARGET_UNIT_TARGET_ENEMY ||
+ TempSpell->EffectImplicitTargetA[j] == TARGET_DST_TARGET_ENEMY ||
+ TempSpell->EffectImplicitTargetA[j] == TARGET_UNIT_AREA_ENEMY_SRC ||
+ TempSpell->EffectImplicitTargetA[j] == TARGET_UNIT_AREA_ENEMY_DST ||
+ TempSpell->EffectImplicitTargetA[j] == TARGET_SRC_CASTER ||
TempSpell->EffectImplicitTargetA[j] == TARGET_DEST_DYNOBJ_ENEMY )
SpellSummary[i].Targets |= 1 << (SELECT_TARGET_ANY_ENEMY-1);
//Spell targets a single friend(or self)
- if ( TempSpell->EffectImplicitTargetA[j] == TARGET_SELF ||
- TempSpell->EffectImplicitTargetA[j] == TARGET_SINGLE_FRIEND ||
- TempSpell->EffectImplicitTargetA[j] == TARGET_SINGLE_PARTY )
+ if ( TempSpell->EffectImplicitTargetA[j] == TARGET_UNIT_CASTER ||
+ TempSpell->EffectImplicitTargetA[j] == TARGET_UNIT_TARGET_ALLY ||
+ TempSpell->EffectImplicitTargetA[j] == TARGET_UNIT_TARGET_PARTY )
SpellSummary[i].Targets |= 1 << (SELECT_TARGET_SINGLE_FRIEND-1);
//Spell targets aoe friends
- if ( TempSpell->EffectImplicitTargetA[j] == TARGET_ALL_PARTY_AROUND_CASTER ||
- TempSpell->EffectImplicitTargetA[j] == TARGET_AREAEFFECT_PARTY ||
- TempSpell->EffectImplicitTargetA[j] == TARGET_DEST_CASTER)
+ if ( TempSpell->EffectImplicitTargetA[j] == TARGET_UNIT_PARTY_CASTER ||
+ TempSpell->EffectImplicitTargetA[j] == TARGET_UNIT_PARTY_TARGET ||
+ TempSpell->EffectImplicitTargetA[j] == TARGET_SRC_CASTER)
SpellSummary[i].Targets |= 1 << (SELECT_TARGET_AOE_FRIEND-1);
//Spell targets any friend(or self)
- if ( TempSpell->EffectImplicitTargetA[j] == TARGET_SELF ||
- TempSpell->EffectImplicitTargetA[j] == TARGET_SINGLE_FRIEND ||
- TempSpell->EffectImplicitTargetA[j] == TARGET_SINGLE_PARTY ||
- TempSpell->EffectImplicitTargetA[j] == TARGET_ALL_PARTY_AROUND_CASTER ||
- TempSpell->EffectImplicitTargetA[j] == TARGET_AREAEFFECT_PARTY ||
- TempSpell->EffectImplicitTargetA[j] == TARGET_DEST_CASTER)
+ if ( TempSpell->EffectImplicitTargetA[j] == TARGET_UNIT_CASTER ||
+ TempSpell->EffectImplicitTargetA[j] == TARGET_UNIT_TARGET_ALLY ||
+ TempSpell->EffectImplicitTargetA[j] == TARGET_UNIT_TARGET_PARTY ||
+ TempSpell->EffectImplicitTargetA[j] == TARGET_UNIT_PARTY_CASTER ||
+ TempSpell->EffectImplicitTargetA[j] == TARGET_UNIT_PARTY_TARGET ||
+ TempSpell->EffectImplicitTargetA[j] == TARGET_SRC_CASTER)
SpellSummary[i].Targets |= 1 << (SELECT_TARGET_ANY_FRIEND-1);
//Make sure that this spell includes a damage effect
diff --git a/src/game/ConfusedMovementGenerator.cpp b/src/game/ConfusedMovementGenerator.cpp
index bbb0b9ebc6a..da383cc8a07 100644
--- a/src/game/ConfusedMovementGenerator.cpp
+++ b/src/game/ConfusedMovementGenerator.cpp
@@ -114,12 +114,12 @@ ConfusedMovementGenerator<T>::Update(T &unit, const uint32 &diff)
{
// currently moving, update location
Traveller<T> traveller(unit);
- if( i_destinationHolder.UpdateTraveller(traveller, diff, false))
+ if( i_destinationHolder.UpdateTraveller(traveller, diff))
{
if( i_destinationHolder.HasArrived())
{
// arrived, stop and wait a bit
- unit.StopMoving();
+ unit.clearUnitState(UNIT_STAT_MOVE);
i_nextMove = urand(1,MAX_CONF_WAYPOINTS);
i_nextMoveTime.Reset(urand(0, 1500-1)); // TODO: check the minimum reset time, should be probably higher
diff --git a/src/game/DestinationHolder.h b/src/game/DestinationHolder.h
index 94e12a1757d..c37b60e8b54 100644
--- a/src/game/DestinationHolder.h
+++ b/src/game/DestinationHolder.h
@@ -51,7 +51,7 @@ class TRINITY_DLL_DECL DestinationHolder
bool HasDestination(void) const { return i_destSet; }
float GetDestinationDiff(float x, float y, float z) const;
bool HasArrived(void) const { return (i_totalTravelTime == 0 || i_timeElapsed >= i_totalTravelTime); }
- bool UpdateTraveller(TRAVELLER &traveller, uint32 diff, bool force_update=false, bool micro_movement=false);
+ bool UpdateTraveller(TRAVELLER &traveller, uint32 diff, bool micro_movement=false);
uint32 StartTravel(TRAVELLER &traveller, bool sendMove = true);
void GetLocationNow(uint32 mapid, float &x, float &y, float &z, bool is3D = false) const;
void GetLocationNowNoMicroMovement(float &x, float &y, float &z) const; // For use without micro movement
diff --git a/src/game/DestinationHolderImp.h b/src/game/DestinationHolderImp.h
index 384ad9621a3..0286851cbb7 100644
--- a/src/game/DestinationHolderImp.h
+++ b/src/game/DestinationHolderImp.h
@@ -93,37 +93,29 @@ DestinationHolder<TRAVELLER>::StartTravel(TRAVELLER &traveller, bool sendMove)
template<typename TRAVELLER>
bool
-DestinationHolder<TRAVELLER>::UpdateTraveller(TRAVELLER &traveller, uint32 diff, bool force_update, bool micro_movement)
+DestinationHolder<TRAVELLER>::UpdateTraveller(TRAVELLER &traveller, uint32 diff, bool micro_movement)
{
+ i_timeElapsed += diff;
+
+ // Update every TRAVELLER_UPDATE_INTERVAL
+ i_tracker.Update(diff);
+ if(!i_tracker.Passed())
+ return false;
+ else
+ ResetUpdate();
+
+ if(!i_destSet) return true;
+
+ float x, y, z;
if(!micro_movement)
{
- i_tracker.Update(diff);
- i_timeElapsed += diff;
- if( i_tracker.Passed() || force_update )
- {
- ResetUpdate();
- if(!i_destSet) return true;
- float x,y,z;
- GetLocationNowNoMicroMovement(x, y, z);
- if( x == -431602080 )
- return false;
- if( traveller.GetTraveller().GetPositionX() != x || traveller.GetTraveller().GetPositionY() != y )
- {
- float ori = traveller.GetTraveller().GetAngle(x, y);
- traveller.Relocation(x, y, z, ori);
- }
- return true;
- }
- return false;
+ GetLocationNowNoMicroMovement(x, y, z);
+
+ if( x == -431602080 )
+ return false;
}
- i_tracker.Update(diff);
- i_timeElapsed += diff;
- if( i_tracker.Passed() || force_update )
+ else
{
- ResetUpdate();
- if(!i_destSet) return true;
- float x,y,z;
-
if(!traveller.GetTraveller().hasUnitState(UNIT_STAT_MOVING | UNIT_STAT_IN_FLIGHT))
return true;
@@ -135,11 +127,6 @@ DestinationHolder<TRAVELLER>::UpdateTraveller(TRAVELLER &traveller, uint32 diff,
if( x == -431602080 )
return false;
- if( traveller.GetTraveller().GetPositionX() != x || traveller.GetTraveller().GetPositionY() != y )
- {
- float ori = traveller.GetTraveller().GetAngle(x, y);
- traveller.Relocation(x, y, z, ori);
- }
// Change movement computation to micro movement based on last tick coords, this makes system work
// even on multiple floors zones without hugh vmaps usage ;)
@@ -153,9 +140,15 @@ DestinationHolder<TRAVELLER>::UpdateTraveller(TRAVELLER &traveller, uint32 diff,
i_fromX = x; // and change origine
i_fromY = y; // then I take into account only micro movement
i_fromZ = z;
- return true;
}
- return false;
+
+ if( traveller.GetTraveller().GetPositionX() != x || traveller.GetTraveller().GetPositionY() != y )
+ {
+ float ori = traveller.GetTraveller().GetAngle(x, y);
+ traveller.Relocation(x, y, z, ori);
+ }
+
+ return true;
}
template<typename TRAVELLER>
diff --git a/src/game/FleeingMovementGenerator.cpp b/src/game/FleeingMovementGenerator.cpp
index 0b499168538..538d513b298 100644
--- a/src/game/FleeingMovementGenerator.cpp
+++ b/src/game/FleeingMovementGenerator.cpp
@@ -383,7 +383,7 @@ FleeingMovementGenerator<T>::Update(T &owner, const uint32 & time_diff)
return true;
}
- if (i_destinationHolder.UpdateTraveller(traveller, time_diff, false))
+ if (i_destinationHolder.UpdateTraveller(traveller, time_diff))
{
i_destinationHolder.ResetUpdate(50);
if(i_nextCheckTime.Passed() && i_destinationHolder.HasArrived())
diff --git a/src/game/GridNotifiersImpl.h b/src/game/GridNotifiersImpl.h
index 54cbff2c7bb..62cae5b33a0 100644
--- a/src/game/GridNotifiersImpl.h
+++ b/src/game/GridNotifiersImpl.h
@@ -181,7 +181,7 @@ inline void Trinity::DynamicObjectUpdater::VisitHelper(Unit* target)
SpellEntry const *spellInfo = sSpellStore.LookupEntry(i_dynobject.GetSpellId());
uint32 eff_index = i_dynobject.GetEffIndex();
if(spellInfo->EffectImplicitTargetB[eff_index] == TARGET_DEST_DYNOBJ_ALLY
- || spellInfo->EffectImplicitTargetB[eff_index] == TARGET_UNIT_AREA_ALLY_GROUND)
+ || spellInfo->EffectImplicitTargetB[eff_index] == TARGET_UNIT_AREA_ALLY_DST)
{
if(!i_check->IsFriendlyTo(target))
return;
diff --git a/src/game/HomeMovementGenerator.cpp b/src/game/HomeMovementGenerator.cpp
index 4f0ca2f8cec..a2bad0b0db7 100644
--- a/src/game/HomeMovementGenerator.cpp
+++ b/src/game/HomeMovementGenerator.cpp
@@ -60,7 +60,7 @@ bool
HomeMovementGenerator<Creature>::Update(Creature &owner, const uint32& time_diff)
{
CreatureTraveller traveller( owner);
- i_destinationHolder.UpdateTraveller(traveller, time_diff, false);
+ i_destinationHolder.UpdateTraveller(traveller, time_diff);
if (time_diff > i_travel_timer)
{
diff --git a/src/game/IdleMovementGenerator.cpp b/src/game/IdleMovementGenerator.cpp
index 67f89303e40..2428c49a77a 100644
--- a/src/game/IdleMovementGenerator.cpp
+++ b/src/game/IdleMovementGenerator.cpp
@@ -23,14 +23,19 @@
IdleMovementGenerator si_idleMovement;
+// StopMoving is needed to make unit stop if its last movement generator expires
+// But it should not be sent otherwise there are many redundent packets
void IdleMovementGenerator::Initialize(Unit &owner)
{
- owner.StopMoving();
+ if(owner.hasUnitState(UNIT_STAT_MOVE))
+ owner.StopMoving();
}
void
-IdleMovementGenerator::Reset(Unit& /*owner*/)
+IdleMovementGenerator::Reset(Unit& owner)
{
+ if(owner.hasUnitState(UNIT_STAT_MOVE))
+ owner.StopMoving();
}
void
diff --git a/src/game/PetHandler.cpp b/src/game/PetHandler.cpp
index 71ae527e7d7..15dac10688f 100644
--- a/src/game/PetHandler.cpp
+++ b/src/game/PetHandler.cpp
@@ -209,7 +209,7 @@ void WorldSession::HandlePetActionHelper(Unit *pet, uint64 guid1, uint16 spellid
for(uint32 i = 0; i < 3;++i)
{
- if(spellInfo->EffectImplicitTargetA[i] == TARGET_ALL_ENEMY_IN_AREA || spellInfo->EffectImplicitTargetA[i] == TARGET_ALL_ENEMY_IN_AREA_INSTANT || spellInfo->EffectImplicitTargetA[i] == TARGET_DEST_DYNOBJ_ENEMY)
+ if(spellInfo->EffectImplicitTargetA[i] == TARGET_UNIT_AREA_ENEMY_SRC || spellInfo->EffectImplicitTargetA[i] == TARGET_UNIT_AREA_ENEMY_DST || spellInfo->EffectImplicitTargetA[i] == TARGET_DEST_DYNOBJ_ENEMY)
return;
}
diff --git a/src/game/PointMovementGenerator.cpp b/src/game/PointMovementGenerator.cpp
index 084dad7cfa8..0c3758bfc5e 100644
--- a/src/game/PointMovementGenerator.cpp
+++ b/src/game/PointMovementGenerator.cpp
@@ -53,10 +53,11 @@ bool PointMovementGenerator<T>::Update(T &unit, const uint32 &diff)
Traveller<T> traveller(unit);
- i_destinationHolder.UpdateTraveller(traveller, diff, false);
+ i_destinationHolder.UpdateTraveller(traveller, diff);
if(i_destinationHolder.HasArrived())
{
+ unit.clearUnitState(UNIT_STAT_MOVE);
arrived = true;
return false;
}
diff --git a/src/game/RandomMovementGenerator.cpp b/src/game/RandomMovementGenerator.cpp
index 0081c702abd..6d147f15b8d 100644
--- a/src/game/RandomMovementGenerator.cpp
+++ b/src/game/RandomMovementGenerator.cpp
@@ -164,14 +164,14 @@ RandomMovementGenerator<Creature>::Update(Creature &creature, const uint32 &diff
i_nextMoveTime.Update(diff);
if(i_destinationHolder.HasArrived() && !creature.IsStopped() && !creature.canFly())
- creature.clearUnitState(UNIT_STAT_ROAMING);
+ creature.clearUnitState(UNIT_STAT_ROAMING | UNIT_STAT_MOVE);
if(!i_destinationHolder.HasArrived() && creature.IsStopped())
creature.addUnitState(UNIT_STAT_ROAMING);
CreatureTraveller traveller(creature);
- if( i_destinationHolder.UpdateTraveller(traveller, diff, false, true) )
+ if( i_destinationHolder.UpdateTraveller(traveller, diff, true) )
{
if(i_nextMoveTime.Passed())
{
diff --git a/src/game/SharedDefines.h b/src/game/SharedDefines.h
index 8628107b4e2..f497e4c709a 100644
--- a/src/game/SharedDefines.h
+++ b/src/game/SharedDefines.h
@@ -995,63 +995,43 @@ enum SpellImmunity
enum Targets
{
- TARGET_SELF = 1,
TARGET_UNIT_CASTER = 1,
- TARGET_UNIT_NEARBY_ENEMY = 2,
+ TARGET_UNIT_NEARBY_ENEMY = 2, // only one spell has that, but regardless, it's a target type after all
TARGET_UNIT_NEARBY_ALLY = 3,
TARGET_UNIT_NEARBY_ALLY_UNK = 4,
- TARGET_PET = 5,
TARGET_UNIT_PET = 5,
- TARGET_CHAIN_DAMAGE = 6,
TARGET_UNIT_TARGET_ENEMY = 6,
- TARGET_UNIT_AREA_ENTRY = 7,
- TARGET_AREAEFFECT_CUSTOM = 8,
- TARGET_UNIT_AREA_ENTRY_GROUND = 8,
- TARGET_INNKEEPER_COORDINATES = 9, // uses in teleport to innkeeper spells
- //TARGET_DEST_HOME
+ TARGET_UNIT_AREA_ENTRY_SRC = 7,
+ TARGET_UNIT_AREA_ENTRY_DST = 8,
+ TARGET_DST_HOME = 9, // uses in teleport to innkeeper spells
TARGET_UNIT_TARGET_DEST_CASTER = 11, // teleport target to caster
- TARGET_ALL_ENEMY_IN_AREA = 15,
- TARGET_UNIT_AREA_ENEMY = 15,
- TARGET_ALL_ENEMY_IN_AREA_INSTANT = 16,
- TARGET_UNIT_AREA_ENEMY_GROUND = 16,
- TARGET_TABLE_X_Y_Z_COORDINATES = 17, // uses in teleport spells and some other
- //TARGET_DEST_TABLE
- TARGET_EFFECT_SELECT = 18, // highly depends on the spell effect
- TARGET_DEST_CASTER_GROUND = 18,
+ TARGET_UNIT_AREA_ENEMY_SRC = 15,
+ TARGET_UNIT_AREA_ENEMY_DST = 16,
+ TARGET_DST_DB = 17, // uses in teleport spells and some other
+ TARGET_DST_CASTER = 18,
TARGET_PREV_EFFECT_SUMMON = 18,
- TARGET_ALL_PARTY_AROUND_CASTER = 20,
TARGET_UNIT_PARTY_CASTER = 20,
- TARGET_SINGLE_FRIEND = 21,
TARGET_UNIT_TARGET_ALLY = 21,
- TARGET_DEST_CASTER = 22,
+ TARGET_SRC_CASTER = 22,
TARGET_GAMEOBJECT = 23,
//TARGET_OBJECT_OPEN
- TARGET_IN_FRONT_OF_CASTER = 24,
TARGET_UNIT_CONE_ENEMY = 24,
- TARGET_DUELVSPLAYER = 25,
TARGET_UNIT_TARGET_ANY = 25,
TARGET_GAMEOBJECT_ITEM = 26,
//TARGET_OBJECT_ITEM_PICKLOCK
TARGET_UNIT_MASTER = 27,
TARGET_DEST_DYNOBJ_ENEMY = 28,
TARGET_DEST_DYNOBJ_ALLY = 29, // only for effect 27
- TARGET_ALL_FRIENDLY_UNITS_AROUND_CASTER = 30, // in TargetB used only with TARGET_ALL_AROUND_CASTER and in self casting range in TargetA
- TARGET_UNIT_AREA_ALLY = 30,
- TARGET_ALL_FRIENDLY_UNITS_IN_AREA = 31,
- TARGET_UNIT_AREA_ALLY_GROUND = 31,
+ TARGET_UNIT_AREA_ALLY_SRC = 30, // in TargetB used only with TARGET_SRC_CASTER and in self casting range in TargetA
+ TARGET_UNIT_AREA_ALLY_DST = 31,
TARGET_MINION = 32,
//TARGET_DEST_SUMMON
- TARGET_ALL_PARTY = 33,
- TARGET_UNIT_AREA_PARTY = 33,
- TARGET_ALL_PARTY_AROUND_CASTER_2 = 34, // used in Tranquility
- TARGET_UNIT_AREA_PARTY_GROUND = 34,
- TARGET_SINGLE_PARTY = 35,
+ TARGET_UNIT_AREA_PARTY_SRC = 33,
+ TARGET_UNIT_AREA_PARTY_DST = 34, // used in Tranquility
TARGET_UNIT_TARGET_PARTY = 35,
TARGET_DEST_CASTER_RANDOM_UNKNOWN = 36, //unknown
- TARGET_AREAEFFECT_PARTY = 37,
TARGET_UNIT_PARTY_TARGET = 37,
- TARGET_SCRIPT = 38,
- //TARGET_UNIT_NEARBY_ENTRY
+ TARGET_UNIT_NEARBY_ENTRY = 38,
TARGET_UNIT_CASTER_FISHING = 39,
TARGET_OBJECT_USE = 40,
TARGET_DEST_CASTER_FRONT_LEFT = 41, //earth totem
@@ -1059,28 +1039,23 @@ enum Targets
TARGET_DEST_CASTER_BACK_RIGHT = 43, //air totem
TARGET_DEST_CASTER_FRONT_RIGHT = 44, //fire totem
TARGET_UNIT_CHAINHEAL = 45,
- TARGET_SCRIPT_COORDINATES = 46,
- //TARGET_DEST_NEARBY_ENTRY
+ TARGET_DST_NEARBY_ENTRY = 46,
TARGET_DEST_CASTER_FRONT = 47,
TARGET_DEST_CASTER_BACK = 48,
TARGET_DEST_CASTER_RIGHT = 49,
TARGET_DEST_CASTER_LEFT = 50,
- TARGET_OBJECT_AREA = 51,
- TARGET_AREAEFFECT_CUSTOM_2 = 52,
- //TARGET_DUMMY
- TARGET_CURRENT_ENEMY_COORDINATES = 53, // set unit coordinates as dest, only 16 target B imlemented
- TARGET_DEST_TARGET_ENEMY = 53,
- TARGET_UNIT_CONE_ENEMY_UNKNOWN = 54,
+ TARGET_OBJECT_AREA_SRC = 51,
+ TARGET_OBJECT_AREA_DST = 52,
+ TARGET_DST_TARGET_ENEMY = 53, // set unit coordinates as dest, only 16 target B imlemented
+ TARGET_UNIT_CONE_ENEMY_UNKNOWN = 54, // 180 degree, or different angle
TARGET_DEST_CASTER_FRONT_LEAP = 55, // for a leap spell
- TARGET_UNIT_RAID = 56,
- TARGET_SINGLE_FRIEND_2 = 57,
+ TARGET_UNIT_RAID_CASTER = 56,
TARGET_UNIT_TARGET_RAID = 57,
+ TARGET_UNIT_NEARBY_RAID = 58,
TARGET_UNIT_CONE_ALLY = 59,
- TARGET_UNIT_AREA_SCRIPT = 60,
- TARGET_AREAEFFECT_PARTY_AND_CLASS = 61,
+ TARGET_UNIT_CONE_ENTRY = 60,
TARGET_UNIT_CLASS_TARGET = 61,
TARGET_TEST = 62, // for a test spell
- TARGET_DUELVSPLAYER_COORDINATES = 63,
TARGET_DEST_TARGET_ANY = 63,
TARGET_DEST_TARGET_FRONT = 64,
TARGET_DEST_TARGET_BACK = 65, // uses in teleport behind spells
@@ -1106,7 +1081,7 @@ enum Targets
TARGET_DEST_DEST_FRONT_RIGHT = 85,
TARGET_DEST_DEST_RANDOM = 86,
TARGET_DEST_DEST = 87,
- TARGET_UNIT_AREA_ALL_CHANNEL = 88,
+ TARGET_DEST_DYNOBJ_NONE = 88,
TARGET_DEST_TRAJ = 89,
TARGET_UNIT_MINIPET = 90,
TARGET_CORPSE_AREA_ENEMY_PLAYER = 93,
diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp
index 3113beac3f6..8817854971e 100644
--- a/src/game/Spell.cpp
+++ b/src/game/Spell.cpp
@@ -75,7 +75,6 @@ SpellCastTargets::SpellCastTargets()
m_itemTargetEntry = 0;
m_srcX = m_srcY = m_srcZ = m_destX = m_destY = m_destZ = 0;
- m_hasDest = false;
m_strTarget = "";
m_targetMask = 0;
}
@@ -94,38 +93,49 @@ void SpellCastTargets::setUnitTarget(Unit *target)
m_targetMask |= TARGET_FLAG_UNIT;
}
-void SpellCastTargets::setDestination(float x, float y, float z, bool send, int32 mapId)
+void SpellCastTargets::setSrc(float x, float y, float z)
+{
+ m_srcX = x;
+ m_srcY = y;
+ m_srcZ = z;
+ m_targetMask |= TARGET_FLAG_SOURCE_LOCATION;
+}
+
+void SpellCastTargets::setSrc(WorldObject *target)
+{
+ if(!target)
+ return;
+
+ target->GetPosition(m_srcX, m_srcY, m_srcZ);
+ m_targetMask |= TARGET_FLAG_SOURCE_LOCATION;
+}
+
+void SpellCastTargets::setDestination(float x, float y, float z, int32 mapId)
{
m_destX = x;
m_destY = y;
m_destZ = z;
- m_hasDest = true;
- if(send)
- m_targetMask |= TARGET_FLAG_DEST_LOCATION;
+ m_targetMask |= TARGET_FLAG_DEST_LOCATION;
if(mapId >= 0)
m_mapId = mapId;
}
-void SpellCastTargets::setDestination(Unit *target, bool send)
+void SpellCastTargets::setDestination(WorldObject *target)
{
if(!target)
return;
- m_destX = target->GetPositionX();
- m_destY = target->GetPositionY();
- m_destZ = target->GetPositionZ();
- m_hasDest = true;
- if(send)
- m_targetMask |= TARGET_FLAG_DEST_LOCATION;
+ target->GetPosition(m_destX, m_destY, m_destZ);
+ m_targetMask |= TARGET_FLAG_DEST_LOCATION;
}
-void SpellCastTargets::setSource(float x, float y, float z)
+/*void SpellCastTargets::setSource(float x, float y, float z)
{
m_srcX = x;
m_srcY = y;
m_srcZ = z;
m_targetMask |= TARGET_FLAG_SOURCE_LOCATION;
-}
+}*/
void SpellCastTargets::setGOTarget(GameObject *target)
{
@@ -211,8 +221,6 @@ bool SpellCastTargets::read ( WorldPacket * data, Unit *caster )
*data >> m_srcX >> m_srcY >> m_srcZ;
if(!Trinity::IsValidMapCoord(m_srcX, m_srcY, m_srcZ))
return false;
-
- m_hasDest = true;
}
if( m_targetMask & TARGET_FLAG_DEST_LOCATION )
@@ -226,8 +234,6 @@ bool SpellCastTargets::read ( WorldPacket * data, Unit *caster )
*data >> m_destX >> m_destY >> m_destZ;
if(!Trinity::IsValidMapCoord(m_destX, m_destY, m_destZ))
return false;
-
- m_hasDest = true;
}
if( m_targetMask & TARGET_FLAG_STRING )
@@ -435,28 +441,18 @@ void Spell::FillTargetMap()
if(effectTargetType == SPELL_REQUIRE_NONE)
continue;
- std::list<Unit*> tmpUnitMap;
uint32 targetA = m_spellInfo->EffectImplicitTargetA[i];
uint32 targetB = m_spellInfo->EffectImplicitTargetB[i];
if(targetA)
- SetTargetMap(i, targetA, tmpUnitMap);
+ SetTargetMap(i, targetA);
if(targetB) // In very rare case !A && B
- SetTargetMap(i, targetB, tmpUnitMap);
+ SetTargetMap(i, targetB);
if(effectTargetType != SPELL_REQUIRE_UNIT)
{
if(effectTargetType == SPELL_REQUIRE_CASTER)
AddUnitTarget(m_caster, i);
- /*else if(effectTargetType == SPELL_REQUIRE_DEST)
- {
- if(m_targets.HasDest() && m_spellInfo->speed > 0.0f)
- {
- float dist = m_caster->GetDistance(m_targets.m_destX, m_targets.m_destY, m_targets.m_destZ);
- if (dist < 5.0f) dist = 5.0f;
- m_delayMoment = (uint64) floor(dist / m_spellInfo->speed * 1000.0f);
- }
- }*/
else if(effectTargetType == SPELL_REQUIRE_ITEM)
{
if(m_targets.getItemTarget())
@@ -465,7 +461,7 @@ void Spell::FillTargetMap()
continue;
}
- if(tmpUnitMap.empty() && m_spellInfo->Targets & TARGET_FLAG_CASTER)
+ if(/*tmpUnitMap.empty() && */m_spellInfo->Targets & TARGET_FLAG_CASTER)
{
AddUnitTarget(m_caster, i);
continue;
@@ -507,12 +503,12 @@ void Spell::FillTargetMap()
{
case TYPEID_UNIT:
case TYPEID_PLAYER:
- tmpUnitMap.push_back((Unit*)result);
+ AddUnitTarget((Unit*)result, i);
break;
case TYPEID_CORPSE:
m_targets.setCorpseTarget((Corpse*)result);
if(Player* owner = ObjectAccessor::FindPlayer(((Corpse*)result)->GetOwnerGUID()))
- tmpUnitMap.push_back(owner);
+ AddUnitTarget(owner, i);
break;
}
}
@@ -536,7 +532,7 @@ void Spell::FillTargetMap()
}
default:
if(m_targets.getUnitTarget())
- tmpUnitMap.push_back(m_targets.getUnitTarget());
+ AddUnitTarget(m_targets.getUnitTarget(), i);
break;
}
break;
@@ -551,22 +547,22 @@ void Spell::FillTargetMap()
case SPELL_EFFECT_REPUTATION:
case SPELL_EFFECT_LEARN_SPELL:
if(m_targets.getUnitTarget())
- tmpUnitMap.push_back(m_targets.getUnitTarget());
+ AddUnitTarget(m_targets.getUnitTarget(), i);
// Triggered spells have additional spell targets - cast them even if no explicit unit target is given (required for spell 50516 for example)
else if(m_spellInfo->Effect[i] == SPELL_EFFECT_TRIGGER_SPELL)
- tmpUnitMap.push_back(m_caster);
+ AddUnitTarget(m_caster, i);
break;
case SPELL_EFFECT_SUMMON_PLAYER:
if(m_caster->GetTypeId()==TYPEID_PLAYER && ((Player*)m_caster)->GetSelection())
{
Player* target = objmgr.GetPlayer(((Player*)m_caster)->GetSelection());
if(target)
- tmpUnitMap.push_back(target);
+ AddUnitTarget(target, i);
}
break;
case SPELL_EFFECT_RESURRECT_NEW:
if(m_targets.getUnitTarget())
- tmpUnitMap.push_back(m_targets.getUnitTarget());
+ AddUnitTarget(m_targets.getUnitTarget(), i);
if(m_targets.getCorpseTargetGUID())
{
Corpse *corpse = ObjectAccessor::GetCorpse(*m_caster,m_targets.getCorpseTargetGUID());
@@ -574,7 +570,7 @@ void Spell::FillTargetMap()
{
Player* owner = ObjectAccessor::FindPlayer(corpse->GetOwnerGUID());
if(owner)
- tmpUnitMap.push_back(owner);
+ AddUnitTarget(owner, i);
}
}
break;
@@ -584,11 +580,11 @@ void Spell::FillTargetMap()
case SPELL_EFFECT_STUCK:
case SPELL_EFFECT_FEED_PET:
case SPELL_EFFECT_DESTROY_ALL_TOTEMS:
- tmpUnitMap.push_back(m_caster);
+ AddUnitTarget(m_caster, i);
break;
case SPELL_EFFECT_LEARN_PET_SPELL:
if(Guardian* pet = m_caster->GetGuardianPet())
- tmpUnitMap.push_back(pet);
+ AddUnitTarget(pet, i);
break;
/*case SPELL_EFFECT_ENCHANT_ITEM:
case SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY:
@@ -602,9 +598,9 @@ void Spell::FillTargetMap()
case SPELL_EFFECT_APPLY_AURA:
switch(m_spellInfo->EffectApplyAuraName[i])
{
- case SPELL_AURA_ADD_FLAT_MODIFIER: // some spell mods auras have 0 target modes instead expected TARGET_SELF(1) (and present for other ranks for same spell for example)
+ case SPELL_AURA_ADD_FLAT_MODIFIER: // some spell mods auras have 0 target modes instead expected TARGET_UNIT_CASTER(1) (and present for other ranks for same spell for example)
case SPELL_AURA_ADD_PCT_MODIFIER:
- tmpUnitMap.push_back(m_caster);
+ AddUnitTarget(m_caster, i);
break;
default: // apply to target in other case
break;
@@ -613,12 +609,12 @@ void Spell::FillTargetMap()
case SPELL_EFFECT_APPLY_AREA_AURA_PARTY:
// AreaAura
if(m_spellInfo->Attributes == 0x9050000 || m_spellInfo->Attributes == 0x10000)
- SetTargetMap(i,TARGET_AREAEFFECT_PARTY,tmpUnitMap);
+ SetTargetMap(i, TARGET_UNIT_PARTY_TARGET);
break;
case SPELL_EFFECT_SKIN_PLAYER_CORPSE:
if(m_targets.getUnitTarget())
{
- tmpUnitMap.push_back(m_targets.getUnitTarget());
+ AddUnitTarget(m_targets.getUnitTarget(), i);
}
else if (m_targets.getCorpseTargetGUID())
{
@@ -627,7 +623,7 @@ void Spell::FillTargetMap()
{
Player* owner = ObjectAccessor::FindPlayer(corpse->GetOwnerGUID());
if(owner)
- tmpUnitMap.push_back(owner);
+ AddUnitTarget(owner, i);
}
}
break;
@@ -636,27 +632,23 @@ void Spell::FillTargetMap()
}
}
- if(IsChanneledSpell(m_spellInfo) && !tmpUnitMap.empty())
- m_needAliveTargetMask |= (1<<i);
-
- for (std::list<Unit*>::iterator itr = tmpUnitMap.begin() ; itr != tmpUnitMap.end();)
+ if(IsChanneledSpell(m_spellInfo))
{
- if(!CheckTarget(*itr, i))
+ uint8 mask = (1<<i);
+ for(std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
{
- itr = tmpUnitMap.erase(itr);
- continue;
+ if(ihit->effectMask & mask)
+ {
+ m_needAliveTargetMask |= mask;
+ break;
+ }
}
- else
- ++itr;
}
-
- for(std::list<Unit*>::iterator iunit= tmpUnitMap.begin();iunit != tmpUnitMap.end();++iunit)
- AddUnitTarget((*iunit), i);
}
if(m_targets.m_targetMask & TARGET_FLAG_DEST_LOCATION)
{
- if(m_spellInfo->speed > 0.0f && m_targets.HasDest())
+ if(m_spellInfo->speed > 0.0f && m_targets.HasDst())
{
float dist = m_caster->GetDistance(m_targets.m_destX, m_targets.m_destY, m_targets.m_destZ);
if (dist < 5.0f) dist = 5.0f;
@@ -728,6 +720,9 @@ void Spell::AddUnitTarget(Unit* pVictim, uint32 effIndex)
if( m_spellInfo->Effect[effIndex]==0 )
return;
+ if(!CheckTarget(pVictim, effIndex))
+ return;
+
// Check for effect immune skip if immuned
bool immuned = pVictim->IsImmunedToSpellEffect(m_spellInfo, effIndex);
@@ -1375,13 +1370,13 @@ void Spell::SearchChainTarget(std::list<Unit*> &TagUnitMap, float max_range, uin
std::list<Unit*> tempUnitMap;
if(TargetType == SPELL_TARGETS_CHAINHEAL)
{
- SearchAreaTarget(tempUnitMap, max_range, PUSH_TARGET_CENTER, SPELL_TARGETS_ALLY);
+ SearchAreaTarget(tempUnitMap, max_range, PUSH_CHAIN, SPELL_TARGETS_ALLY);
tempUnitMap.sort(ChainHealingOrder(m_caster));
//if(cur->GetHealth() == cur->GetMaxHealth() && tempUnitMap.size())
// cur = tempUnitMap.front();
}
else
- SearchAreaTarget(tempUnitMap, max_range, PUSH_TARGET_CENTER, TargetType);
+ SearchAreaTarget(tempUnitMap, max_range, PUSH_CHAIN, TargetType);
tempUnitMap.remove(cur);
while(num)
@@ -1431,34 +1426,38 @@ void Spell::SearchChainTarget(std::list<Unit*> &TagUnitMap, float max_range, uin
void Spell::SearchAreaTarget(std::list<Unit*> &TagUnitMap, float radius, SpellNotifyPushType type, SpellTargets TargetType, uint32 entry)
{
float x, y, z;
- if(type == PUSH_DEST_CENTER)
- {
- if(!m_targets.HasDest())
- {
- sLog.outError( "SPELL: cannot find destination for spell ID %u\n", m_spellInfo->Id );
- return;
- }
- x = m_targets.m_destX;
- y = m_targets.m_destY;
- z = m_targets.m_destZ;
- }
- else if(type == PUSH_TARGET_CENTER)
+ switch(type)
{
- Unit *target = m_targets.getUnitTarget();
- if(!target)
+ case PUSH_DST_CENTER:
+ CheckDst();
+ x = m_targets.m_destX;
+ y = m_targets.m_destY;
+ z = m_targets.m_destZ;
+ break;
+ case PUSH_SRC_CENTER:
+ CheckSrc();
+ x = m_targets.m_srcX;
+ y = m_targets.m_srcY;
+ z = m_targets.m_srcZ;
+ break;
+ case PUSH_CHAIN:
{
- sLog.outError( "SPELL: cannot find unit target for spell ID %u\n", m_spellInfo->Id );
- return;
+ Unit *target = m_targets.getUnitTarget();
+ if(!target)
+ {
+ sLog.outError( "SPELL: cannot find unit target for spell ID %u\n", m_spellInfo->Id );
+ return;
+ }
+ x = target->GetPositionX();
+ y = target->GetPositionY();
+ z = target->GetPositionZ();
+ break;
}
- x = target->GetPositionX();
- y = target->GetPositionY();
- z = target->GetPositionZ();
- }
- else
- {
- x = m_caster->GetPositionX();
- y = m_caster->GetPositionY();
- z = m_caster->GetPositionZ();
+ default:
+ x = m_caster->GetPositionX();
+ y = m_caster->GetPositionY();
+ z = m_caster->GetPositionZ();
+ break;
}
Trinity::SpellNotifierCreatureAndPlayer notifier(*this, TagUnitMap, radius, type, TargetType, entry, x, y, z);
@@ -1469,83 +1468,112 @@ void Spell::SearchAreaTarget(std::list<Unit*> &TagUnitMap, float radius, SpellNo
m_caster->GetMap()->VisitAll(x, y, radius, notifier);
}
-Unit* Spell::SearchNearbyTarget(float radius, SpellTargets TargetType, uint32 entry)
+WorldObject* Spell::SearchNearbyTarget(float range, SpellTargets TargetType)
{
- Unit* target = NULL;
switch(TargetType)
{
case SPELL_TARGETS_ENTRY:
{
- if(entry)
+ SpellScriptTarget::const_iterator lower = spellmgr.GetBeginSpellScriptTarget(m_spellInfo->Id);
+ SpellScriptTarget::const_iterator upper = spellmgr.GetEndSpellScriptTarget(m_spellInfo->Id);
+ if(lower == upper)
{
- Creature* target = NULL;
- Trinity::NearestCreatureEntryWithLiveStateInObjectRangeCheck u_check(*m_caster, entry, true, radius);
- Trinity::CreatureLastSearcher<Trinity::NearestCreatureEntryWithLiveStateInObjectRangeCheck> searcher(m_caster, target, u_check);
- m_caster->VisitNearbyObject(radius, searcher);
- return target;
+ sLog.outErrorDb("Spell (ID: %u) (caster Entry: %u) does not have record in `spell_script_target`", m_spellInfo->Id, m_caster->GetEntry());
+ if(IsPositiveSpell(m_spellInfo->Id))
+ return SearchNearbyTarget(range, SPELL_TARGETS_ALLY);
+ else
+ return SearchNearbyTarget(range, SPELL_TARGETS_ENEMY);
}
- else
+
+ Creature* creatureScriptTarget = NULL;
+ GameObject* goScriptTarget = NULL;
+
+ for(SpellScriptTarget::const_iterator i_spellST = lower; i_spellST != upper; ++i_spellST)
{
- //TODO: nearest player
- return NULL;
+ switch(i_spellST->second.type)
+ {
+ case SPELL_TARGET_TYPE_GAMEOBJECT:
+ {
+ GameObject* p_GameObject = NULL;
+
+ if(i_spellST->second.targetEntry)
+ {
+ Trinity::NearestGameObjectEntryInObjectRangeCheck go_check(*m_caster,i_spellST->second.targetEntry,range);
+ Trinity::GameObjectLastSearcher<Trinity::NearestGameObjectEntryInObjectRangeCheck> checker(m_caster,p_GameObject,go_check);
+ m_caster->VisitNearbyGridObject(range, checker);
+
+ if(p_GameObject)
+ {
+ // remember found target and range, next attempt will find more near target with another entry
+ creatureScriptTarget = NULL;
+ goScriptTarget = p_GameObject;
+ range = go_check.GetLastRange();
+ }
+ }
+ else if( focusObject ) //Focus Object
+ {
+ float frange = m_caster->GetDistance(focusObject);
+ if(range >= frange)
+ {
+ creatureScriptTarget = NULL;
+ goScriptTarget = focusObject;
+ range = frange;
+ }
+ }
+ break;
+ }
+ case SPELL_TARGET_TYPE_CREATURE:
+ case SPELL_TARGET_TYPE_DEAD:
+ default:
+ {
+ Creature *p_Creature = NULL;
+
+ Trinity::NearestCreatureEntryWithLiveStateInObjectRangeCheck u_check(*m_caster,i_spellST->second.targetEntry,i_spellST->second.type!=SPELL_TARGET_TYPE_DEAD,range);
+ Trinity::CreatureLastSearcher<Trinity::NearestCreatureEntryWithLiveStateInObjectRangeCheck> searcher(m_caster,p_Creature, u_check);
+ m_caster->VisitNearbyObject(range, searcher);
+
+ if(p_Creature )
+ {
+ creatureScriptTarget = p_Creature;
+ goScriptTarget = NULL;
+ range = u_check.GetLastRange();
+ }
+ break;
+ }
+ }
}
+
+ if(creatureScriptTarget)
+ return creatureScriptTarget;
+ else
+ return goScriptTarget;
}
default:
case SPELL_TARGETS_ENEMY:
{
- Trinity::AnyUnfriendlyUnitInObjectRangeCheck u_check(m_caster, m_caster, radius);
+ Unit *target = NULL;
+ Trinity::AnyUnfriendlyUnitInObjectRangeCheck u_check(m_caster, m_caster, range);
Trinity::UnitLastSearcher<Trinity::AnyUnfriendlyUnitInObjectRangeCheck> searcher(m_caster, target, u_check);
- m_caster->VisitNearbyObject(radius, searcher);
- }break;
+ m_caster->VisitNearbyObject(range, searcher);
+ return target;
+ }
case SPELL_TARGETS_ALLY:
{
- Trinity::AnyFriendlyUnitInObjectRangeCheck u_check(m_caster, m_caster, radius);
+ Unit *target = NULL;
+ Trinity::AnyFriendlyUnitInObjectRangeCheck u_check(m_caster, m_caster, range);
Trinity::UnitLastSearcher<Trinity::AnyFriendlyUnitInObjectRangeCheck> searcher(m_caster, target, u_check);
- m_caster->VisitNearbyObject(radius, searcher);
- }break;
+ m_caster->VisitNearbyObject(range, searcher);
+ return target;
+ }
}
- return target;
}
-void Spell::SetTargetMap(uint32 i,uint32 cur,std::list<Unit*> &TagUnitMap)
+void Spell::SetTargetMap(uint32 i, uint32 cur)
{
- float radius_h, radius_f;
- if (m_spellInfo->EffectRadiusIndex[i])
- {
- radius_h = GetSpellRadiusForHostile(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[i])) * m_spellValue->RadiusMod;
- radius_f = GetSpellRadiusForFriend(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[i])) * m_spellValue->RadiusMod;
- }
- else
- {
- radius_h = GetSpellMaxRangeForHostile(sSpellRangeStore.LookupEntry(m_spellInfo->rangeIndex));
- radius_f = GetSpellMaxRangeForFriend(sSpellRangeStore.LookupEntry(m_spellInfo->rangeIndex));
- }
-
- //Chain: 2, 6, 22, 25, 45, 77
- uint32 EffectChainTarget = m_spellInfo->EffectChainTarget[i];
- uint32 unMaxTargets = m_spellValue->MaxAffectedTargets;
-
- Unit::AuraEffectList const& Auras = m_caster->GetAurasByType(SPELL_AURA_MOD_MAX_AFFECTED_TARGETS);
- for(Unit::AuraEffectList::const_iterator j = Auras.begin();j != Auras.end(); ++j)
- {
- if((*j)->isAffectedOnSpell(m_spellInfo))
- unMaxTargets+=(*j)->GetAmount();
- }
-
+ SpellNotifyPushType pushType = PUSH_NONE;
+ Player *modOwner = NULL;
if(m_originalCaster)
- if (Player* modOwner = m_caster->GetSpellModOwner())
- {
- modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_RADIUS, radius_f,this);
- modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_RADIUS, radius_h,this);
- modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_JUMP_TARGETS, EffectChainTarget, this);
- }
-
- if(EffectChainTarget > 1)
- {
- //otherwise, this multiplier is used for something else
- m_damageMultipliers[i] = 1.0f;
- m_applyMultiplierMask |= 1 << i;
- }
+ modOwner = m_originalCaster->GetSpellModOwner();
switch(spellmgr.SpellTargetType[cur])
{
@@ -1555,361 +1583,135 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,std::list<Unit*> &TagUnitMap)
{
case TARGET_UNIT_CASTER:
case TARGET_UNIT_CASTER_FISHING:
- TagUnitMap.push_back(m_caster);
+ AddUnitTarget(m_caster, i);
break;
case TARGET_UNIT_MASTER:
if(Unit* owner = m_caster->GetCharmerOrOwner())
- TagUnitMap.push_back(owner);
+ AddUnitTarget(owner, i);
break;
case TARGET_UNIT_PET:
if(Guardian* pet = m_caster->GetGuardianPet())
- TagUnitMap.push_back(pet);
+ AddUnitTarget(pet, i);
break;
case TARGET_UNIT_PARTY_CASTER:
- m_caster->GetPartyMember(TagUnitMap, radius_f);
- break;
- case TARGET_UNIT_RAID:
- //if(Unit *target = m_targets.getUnitTarget())
- // TagUnitMap.push_back(target);
- //else
- m_caster->GetRaidMember(TagUnitMap, radius_f);
+ case TARGET_UNIT_RAID_CASTER:
+ pushType = PUSH_CASTER_CENTER;
break;
}
- }break;
+ break;
+ }
case TARGET_TYPE_UNIT_TARGET:
{
Unit *target = m_targets.getUnitTarget();
if(!target)
{
- sLog.outError("SPELL: no unit target for spell ID %u\n", m_spellInfo->Id);
+ sLog.outError("SPELL: no unit target for spell ID %u", m_spellInfo->Id);
break;
}
- if(!IsPositiveSpell(m_spellInfo->Id))
- if(Unit *magnet = m_caster->SelectMagnetTarget(target))
- if(magnet != target)
- m_targets.setUnitTarget(magnet);
-
switch(cur)
{
- case TARGET_UNIT_MINIPET:
- if(target->GetGUID() == m_caster->m_SummonSlot[4])
- TagUnitMap.push_back(target);
+ case TARGET_UNIT_TARGET_ENEMY:
+ if(Unit *magnet = m_caster->SelectMagnetTarget(target))
+ if(magnet != target)
+ m_targets.setUnitTarget(magnet);
+ pushType = PUSH_CHAIN;
break;
- case TARGET_UNIT_TARGET_ALLY:
- case TARGET_UNIT_TARGET_RAID:
case TARGET_UNIT_TARGET_ANY:
- case TARGET_UNIT_TARGET_PARTY:
- TagUnitMap.push_back(target);
- break;
- case TARGET_UNIT_PARTY_TARGET:
- target->GetPartyMember(TagUnitMap, radius_f);
- break;
- case TARGET_UNIT_TARGET_ENEMY:
- if(EffectChainTarget <= 1)
- TagUnitMap.push_back(target);
- else
- SearchChainTarget(TagUnitMap, radius_h, EffectChainTarget, SPELL_TARGETS_ENEMY);
+ if(!IsPositiveSpell(m_spellInfo->Id))
+ if(Unit *magnet = m_caster->SelectMagnetTarget(target))
+ if(magnet != target)
+ m_targets.setUnitTarget(magnet);
+ pushType = PUSH_CHAIN;
break;
case TARGET_UNIT_CHAINHEAL:
- if(EffectChainTarget <= 1)
- TagUnitMap.push_back(target);
- else
- SearchChainTarget(TagUnitMap, radius_f, EffectChainTarget, SPELL_TARGETS_CHAINHEAL);
+ pushType = PUSH_CHAIN;
break;
- }
- }break;
-
- case TARGET_TYPE_CHANNEL:
- {
- if(!m_caster->m_currentSpells[CURRENT_CHANNELED_SPELL])
- {
- sLog.outError( "SPELL: no current channeled spell for spell ID %u\n", m_spellInfo->Id );
- break;
- }
-
- switch(cur)
- {
- case TARGET_UNIT_CHANNEL:
- if(Unit* target = m_caster->m_currentSpells[CURRENT_CHANNELED_SPELL]->m_targets.getUnitTarget())
- TagUnitMap.push_back(target);
- else
- sLog.outError( "SPELL: cannot find channel spell target for spell ID %u\n", m_spellInfo->Id );
+ case TARGET_UNIT_TARGET_ALLY:
+ case TARGET_UNIT_TARGET_RAID:
+ case TARGET_UNIT_TARGET_PARTY:
+ case TARGET_UNIT_MINIPET:
+ AddUnitTarget(target, i);
break;
- case TARGET_DEST_CHANNEL:
- if(m_caster->m_currentSpells[CURRENT_CHANNELED_SPELL]->m_targets.HasDest())
- m_targets = m_caster->m_currentSpells[CURRENT_CHANNELED_SPELL]->m_targets;
- else
- sLog.outError( "SPELL: cannot find channel spell destination for spell ID %u\n", m_spellInfo->Id );
+ case TARGET_UNIT_PARTY_TARGET:
+ case TARGET_UNIT_CLASS_TARGET:
+ pushType = PUSH_CASTER_CENTER; // not real
break;
}
- }break;
+ break;
+ }
- case TARGET_TYPE_AREA_DEST:
+ case TARGET_TYPE_UNIT_NEARBY:
{
- if(!m_targets.HasDest())
- {
- sLog.outError( "SPELL: cannot find destination for spell ID %u\n", m_spellInfo->Id );
- return;
- }
-
- // Dummy for client
- if(spellmgr.EffectTargetType[m_spellInfo->Effect[i]] == SPELL_REQUIRE_DEST)
- break;
+ WorldObject *target = NULL;
+ float range;
switch(cur)
{
- case TARGET_UNIT_AREA_ENEMY_GROUND:
- m_targets.m_targetMask |= TARGET_FLAG_DEST_LOCATION;
- case TARGET_UNIT_AREA_ENEMY:
- SearchAreaTarget(TagUnitMap, radius_h, PUSH_DEST_CENTER, SPELL_TARGETS_ENEMY);
+ case TARGET_UNIT_NEARBY_ENEMY:
+ range = GetSpellMaxRange(m_spellInfo, false);
+ if(modOwner) modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_RANGE, range, this);
+ target = SearchNearbyTarget(range, SPELL_TARGETS_ENEMY);
break;
- case TARGET_UNIT_AREA_ALLY_GROUND:
- m_targets.m_targetMask |= TARGET_FLAG_DEST_LOCATION;
- case TARGET_UNIT_AREA_ALLY:
- SearchAreaTarget(TagUnitMap, radius_f, PUSH_DEST_CENTER, SPELL_TARGETS_ALLY);
+ case TARGET_UNIT_NEARBY_ALLY:
+ case TARGET_UNIT_NEARBY_ALLY_UNK:
+ case TARGET_UNIT_NEARBY_RAID:
+ range = GetSpellMaxRange(m_spellInfo, true);
+ if(modOwner) modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_RANGE, range, this);
+ target = SearchNearbyTarget(range, SPELL_TARGETS_ALLY);
break;
- case TARGET_UNIT_AREA_PARTY_GROUND:
- m_targets.m_targetMask |= TARGET_FLAG_DEST_LOCATION;
- case TARGET_UNIT_AREA_PARTY:
- m_caster->GetPartyMember(TagUnitMap, radius_f);
+ case TARGET_UNIT_NEARBY_ENTRY:
+ range = GetSpellMaxRange(m_spellInfo, IsPositiveSpell(m_spellInfo->Id));
+ if(modOwner) modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_RANGE, range, this);
+ target = SearchNearbyTarget(range, SPELL_TARGETS_ENTRY);
break;
- case TARGET_UNIT_AREA_ENTRY_GROUND:
- m_targets.m_targetMask |= TARGET_FLAG_DEST_LOCATION;
- case TARGET_UNIT_AREA_ENTRY:
- {
- SpellScriptTarget::const_iterator lower = spellmgr.GetBeginSpellScriptTarget(m_spellInfo->Id);
- SpellScriptTarget::const_iterator upper = spellmgr.GetEndSpellScriptTarget(m_spellInfo->Id);
- if(lower==upper)
- {
- SearchAreaTarget(TagUnitMap, radius_h, PUSH_DEST_CENTER, SPELL_TARGETS_ENEMY);
- sLog.outErrorDb("Spell (ID: %u) (caster Entry: %u) does not have record in `spell_script_target`", m_spellInfo->Id, m_caster->GetEntry());
- break;
- }
- // let it be done in one check?
- for(SpellScriptTarget::const_iterator i_spellST = lower; i_spellST != upper; ++i_spellST)
- {
- if(i_spellST->second.type != SPELL_TARGET_TYPE_CREATURE)
- {
- sLog.outError( "SPELL: spell ID %u requires non-creature target\n", m_spellInfo->Id );
- continue;
- }
- SearchAreaTarget(TagUnitMap, radius_f, PUSH_DEST_CENTER, SPELL_TARGETS_ENTRY, i_spellST->second.targetEntry);
- }
- }
- break;
}
- }break;
- case TARGET_TYPE_DEFAULT:
- {
- switch(cur)
+ if(!target)
+ return;
+ else if(target->GetTypeId() == TYPEID_UNIT)
{
+ pushType = PUSH_CHAIN;
- case TARGET_GAMEOBJECT:
- {
- if(m_targets.getGOTarget())
- AddGOTarget(m_targets.getGOTarget(), i);
- }break;
- case TARGET_GAMEOBJECT_ITEM:
- {
- if(m_targets.getGOTargetGUID())
- AddGOTarget(m_targets.getGOTarget(), i);
- else if(m_targets.getItemTarget())
- AddItemTarget(m_targets.getItemTarget(), i);
- }break;
-
- case TARGET_TABLE_X_Y_Z_COORDINATES:
- if(SpellTargetPosition const* st = spellmgr.GetSpellTargetPosition(m_spellInfo->Id))
- {
- //TODO: fix this check
- if(m_spellInfo->Effect[0] == SPELL_EFFECT_TELEPORT_UNITS
- || m_spellInfo->Effect[1] == SPELL_EFFECT_TELEPORT_UNITS
- || m_spellInfo->Effect[2] == SPELL_EFFECT_TELEPORT_UNITS)
- m_targets.setDestination(st->target_X, st->target_Y, st->target_Z, true, (int32)st->target_mapId);
- else if(st->target_mapId == m_caster->GetMapId())
- m_targets.setDestination(st->target_X, st->target_Y, st->target_Z);
+ if(!m_targets.getUnitTarget())
+ m_targets.setUnitTarget((Unit*)target);
}
- else
- sLog.outError( "SPELL: unknown target coordinates for spell ID %u\n", m_spellInfo->Id );
- break;
- case TARGET_INNKEEPER_COORDINATES:
- if(m_caster->GetTypeId() == TYPEID_PLAYER)
- m_targets.setDestination(((Player*)m_caster)->m_homebindX,((Player*)m_caster)->m_homebindY,((Player*)m_caster)->m_homebindZ, true, ((Player*)m_caster)->m_homebindMapId);
- break;
+ else if(target->GetTypeId() == TYPEID_GAMEOBJECT)
+ AddGOTarget((GameObject*)target, i);
- case TARGET_IN_FRONT_OF_CASTER:
- case TARGET_UNIT_CONE_ENEMY_UNKNOWN:
- if(m_customAttr & SPELL_ATTR_CU_CONE_BACK)
- SearchAreaTarget(TagUnitMap, radius_h, PUSH_IN_BACK, SPELL_TARGETS_ENEMY);
- else if(m_customAttr & SPELL_ATTR_CU_CONE_LINE)
- SearchAreaTarget(TagUnitMap, radius_h, PUSH_IN_LINE, SPELL_TARGETS_ENEMY);
- else
- SearchAreaTarget(TagUnitMap, radius_h, PUSH_IN_FRONT, SPELL_TARGETS_ENEMY);
- break;
- case TARGET_UNIT_CONE_ALLY:
- SearchAreaTarget(TagUnitMap, radius_f, PUSH_IN_FRONT, SPELL_TARGETS_ALLY);
break;
+ }
- // nearby target
- case TARGET_UNIT_NEARBY_ALLY:
- case TARGET_UNIT_NEARBY_ALLY_UNK:
- if(!m_targets.getUnitTarget())
- m_targets.setUnitTarget(SearchNearbyTarget(radius_f, SPELL_TARGETS_ALLY));
- if(m_targets.getUnitTarget())
- {
- if(EffectChainTarget <= 1)
- TagUnitMap.push_back(m_targets.getUnitTarget());
- else
- SearchChainTarget(TagUnitMap, radius_f, EffectChainTarget, SPELL_TARGETS_ALLY);
- }
+ case TARGET_TYPE_AREA_SRC:
+ CheckSrc();
+ pushType = PUSH_SRC_CENTER;
break;
- case TARGET_UNIT_NEARBY_ENEMY:
- if(!m_targets.getUnitTarget())
- m_targets.setUnitTarget(SearchNearbyTarget(radius_h, SPELL_TARGETS_ENEMY));
- if(m_targets.getUnitTarget())
- {
- if(EffectChainTarget <= 1)
- TagUnitMap.push_back(m_targets.getUnitTarget());
- else
- SearchChainTarget(TagUnitMap, radius_h, EffectChainTarget, SPELL_TARGETS_ENEMY);
- }
- break;
- case TARGET_SCRIPT:
- case TARGET_SCRIPT_COORDINATES:
- case TARGET_UNIT_AREA_SCRIPT:
- {
- SpellScriptTarget::const_iterator lower = spellmgr.GetBeginSpellScriptTarget(m_spellInfo->Id);
- SpellScriptTarget::const_iterator upper = spellmgr.GetEndSpellScriptTarget(m_spellInfo->Id);
- if(lower==upper)
- {
- sLog.outErrorDb("Spell (ID: %u) (caster Entry: %u) does not have record in `spell_script_target`", m_spellInfo->Id, m_caster->GetEntry());
- TagUnitMap.push_back(m_caster);
- break;
- }
-
- SpellRangeEntry const* srange = sSpellRangeStore.LookupEntry(m_spellInfo->rangeIndex);
- float range = GetSpellMaxRangeForHostile(srange);
-
- Creature* creatureScriptTarget = NULL;
- GameObject* goScriptTarget = NULL;
-
- for(SpellScriptTarget::const_iterator i_spellST = lower; i_spellST != upper; ++i_spellST)
- {
- switch(i_spellST->second.type)
- {
- case SPELL_TARGET_TYPE_GAMEOBJECT:
- {
- GameObject* p_GameObject = NULL;
-
- if(i_spellST->second.targetEntry)
- {
- Trinity::NearestGameObjectEntryInObjectRangeCheck go_check(*m_caster,i_spellST->second.targetEntry,range);
- Trinity::GameObjectLastSearcher<Trinity::NearestGameObjectEntryInObjectRangeCheck> checker(m_caster, p_GameObject,go_check);
- m_caster->VisitNearbyGridObject(range, checker);
-
- if(p_GameObject)
- {
- // remember found target and range, next attempt will find more near target with another entry
- creatureScriptTarget = NULL;
- goScriptTarget = p_GameObject;
- range = go_check.GetLastRange();
- }
- }
- else if( focusObject ) //Focus Object
- {
- float frange = m_caster->GetDistance(focusObject);
- if(range >= frange)
- {
- creatureScriptTarget = NULL;
- goScriptTarget = focusObject;
- range = frange;
- }
- }
- break;
- }
- case SPELL_TARGET_TYPE_CREATURE:
- case SPELL_TARGET_TYPE_DEAD:
- default:
- {
- Creature *p_Creature = NULL;
-
- Trinity::NearestCreatureEntryWithLiveStateInObjectRangeCheck u_check(*m_caster,i_spellST->second.targetEntry,i_spellST->second.type!=SPELL_TARGET_TYPE_DEAD,range);
- Trinity::CreatureLastSearcher<Trinity::NearestCreatureEntryWithLiveStateInObjectRangeCheck> searcher(m_caster, p_Creature, u_check);
- m_caster->VisitNearbyObject(range, searcher);
-
- if(p_Creature )
- {
- creatureScriptTarget = p_Creature;
- goScriptTarget = NULL;
- range = u_check.GetLastRange();
- }
- break;
- }
- }
- }
-
- if(cur == TARGET_SCRIPT_COORDINATES)
- {
- if(creatureScriptTarget)
- m_targets.setDestination(creatureScriptTarget->GetPositionX(),creatureScriptTarget->GetPositionY(),creatureScriptTarget->GetPositionZ());
- else if(goScriptTarget)
- m_targets.setDestination(goScriptTarget->GetPositionX(),goScriptTarget->GetPositionY(),goScriptTarget->GetPositionZ());
- }
- else
- {
- if(creatureScriptTarget)
- TagUnitMap.push_back(creatureScriptTarget);
- else if(goScriptTarget)
- AddGOTarget(goScriptTarget, i);
- }
- }break;
- // dummy
- case TARGET_AREAEFFECT_CUSTOM_2:
- {
- TagUnitMap.push_back(m_caster);
+ case TARGET_TYPE_AREA_DST:
+ CheckDst();
+ pushType = PUSH_DST_CENTER;
break;
- }
- case TARGET_AREAEFFECT_PARTY_AND_CLASS:
- {
- Player* targetPlayer = m_targets.getUnitTarget() && m_targets.getUnitTarget()->GetTypeId() == TYPEID_PLAYER
- ? (Player*)m_targets.getUnitTarget() : NULL;
-
- Group* pGroup = targetPlayer ? targetPlayer->GetGroup() : NULL;
- if(pGroup)
- {
- for(GroupReference *itr = pGroup->GetFirstMember(); itr != NULL; itr = itr->next())
- {
- Player* Target = itr->getSource();
- // IsHostileTo check duel and controlled by enemy
- if( Target && targetPlayer->IsWithinDistInMap(Target, radius_f) &&
- targetPlayer->getClass() == Target->getClass() &&
- !m_caster->IsHostileTo(Target) )
- {
- TagUnitMap.push_back(Target);
- }
- }
- }
- else if(m_targets.getUnitTarget())
- TagUnitMap.push_back(m_targets.getUnitTarget());
+ case TARGET_TYPE_AREA_CONE:
+ if(m_customAttr & SPELL_ATTR_CU_CONE_BACK)
+ pushType = PUSH_IN_BACK;
+ else if(m_customAttr & SPELL_ATTR_CU_CONE_LINE)
+ pushType = PUSH_IN_LINE;
+ else
+ pushType = PUSH_IN_FRONT;
break;
- }
- }
- }break;
-
- case TARGET_TYPE_DEST_CASTER:
+
+ case TARGET_TYPE_DEST_CASTER: //4+8+2
{
- if(cur == TARGET_DEST_CASTER_GROUND)
+ if(cur == TARGET_SRC_CASTER)
{
- m_targets.setDestination(m_caster, true);
+ m_targets.setSrc(m_caster);
break;
}
- else if(cur == TARGET_DEST_CASTER)
+ else if(cur == TARGET_DST_CASTER)
{
- m_targets.setDestination(m_caster, false);
+ m_targets.setDestination(m_caster);
break;
}
@@ -1938,10 +1740,11 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,std::list<Unit*> &TagUnitMap)
}
m_caster->GetGroundPointAroundUnit(x, y, z, dist, angle);
- m_targets.setDestination(x, y, z); // do not know if has ground visual
- }break;
+ m_targets.setDestination(x, y, z);
+ break;
+ }
- case TARGET_TYPE_DEST_TARGET:
+ case TARGET_TYPE_DEST_TARGET: //2+8+2
{
Unit *target = m_targets.getUnitTarget();
if(!target)
@@ -1950,9 +1753,9 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,std::list<Unit*> &TagUnitMap)
break;
}
- if(cur == TARGET_DEST_TARGET_ENEMY || cur == TARGET_DEST_TARGET_ANY)
+ if(cur == TARGET_DST_TARGET_ENEMY || cur == TARGET_DEST_TARGET_ANY)
{
- m_targets.setDestination(target, true);
+ m_targets.setDestination(target);
break;
}
@@ -1979,12 +1782,13 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,std::list<Unit*> &TagUnitMap)
}
target->GetGroundPointAroundUnit(x, y, z, dist, angle);
- m_targets.setDestination(x, y, z); // do not know if has ground visual
- }break;
+ m_targets.setDestination(x, y, z);
+ break;
+ }
- case TARGET_TYPE_DEST_DEST:
+ case TARGET_TYPE_DEST_DEST: //5+8+1
{
- if(!m_targets.HasDest())
+ if(!m_targets.HasDst())
{
sLog.outError("SPELL: no destination for spell ID %u\n", m_spellInfo->Id);
break;
@@ -1995,7 +1799,9 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,std::list<Unit*> &TagUnitMap)
{
case TARGET_DEST_DYNOBJ_ENEMY:
case TARGET_DEST_DYNOBJ_ALLY:
+ case TARGET_DEST_DYNOBJ_NONE:
case TARGET_DEST_DEST:
+ case TARGET_DEST_TRAJ:
return;
case TARGET_DEST_DEST_FRONT: angle = 0.0f; break;
case TARGET_DEST_DEST_BACK: angle = M_PI; break;
@@ -2017,45 +1823,269 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,std::list<Unit*> &TagUnitMap)
y = m_targets.m_destY;
z = m_targets.m_destZ;
m_caster->GetGroundPoint(x, y, z, dist, angle);
- m_targets.setDestination(x, y, z); // do not know if has ground visual
- }break;
+ m_targets.setDestination(x, y, z);
+ break;
+ }
+
+ case TARGET_TYPE_DEST_SPECIAL:
+ {
+ switch(cur)
+ {
+ case TARGET_DST_DB:
+ if(SpellTargetPosition const* st = spellmgr.GetSpellTargetPosition(m_spellInfo->Id))
+ {
+ //TODO: fix this check
+ if(m_spellInfo->Effect[0] == SPELL_EFFECT_TELEPORT_UNITS
+ || m_spellInfo->Effect[1] == SPELL_EFFECT_TELEPORT_UNITS
+ || m_spellInfo->Effect[2] == SPELL_EFFECT_TELEPORT_UNITS)
+ m_targets.setDestination(st->target_X, st->target_Y, st->target_Z, (int32)st->target_mapId);
+ else if(st->target_mapId == m_caster->GetMapId())
+ m_targets.setDestination(st->target_X, st->target_Y, st->target_Z);
+ }
+ else
+ sLog.outError( "SPELL: unknown target coordinates for spell ID %u\n", m_spellInfo->Id );
+ break;
+ case TARGET_DST_HOME:
+ if(m_caster->GetTypeId() == TYPEID_PLAYER)
+ m_targets.setDestination(((Player*)m_caster)->m_homebindX,((Player*)m_caster)->m_homebindY,((Player*)m_caster)->m_homebindZ, ((Player*)m_caster)->m_homebindMapId);
+ break;
+ case TARGET_DST_NEARBY_ENTRY:
+ {
+ float range = GetSpellMaxRange(m_spellInfo, IsPositiveSpell(m_spellInfo->Id));
+ if(modOwner) modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_RANGE, range, this);
+
+ WorldObject *target = SearchNearbyTarget(range, SPELL_TARGETS_ENTRY);
+ if(target)
+ m_targets.setDestination(target);
+ break;
+ }
+ }
+ break;
+ }
+
+ case TARGET_TYPE_CHANNEL:
+ {
+ if(!m_caster->m_currentSpells[CURRENT_CHANNELED_SPELL])
+ {
+ sLog.outError( "SPELL: no current channeled spell for spell ID %u", m_spellInfo->Id );
+ break;
+ }
+
+ switch(cur)
+ {
+ case TARGET_UNIT_CHANNEL:
+ if(Unit* target = m_caster->m_currentSpells[CURRENT_CHANNELED_SPELL]->m_targets.getUnitTarget())
+ AddUnitTarget(target, i);
+ else
+ sLog.outError( "SPELL: cannot find channel spell target for spell ID %u", m_spellInfo->Id );
+ break;
+ case TARGET_DEST_CHANNEL:
+ if(m_caster->m_currentSpells[CURRENT_CHANNELED_SPELL]->m_targets.HasDst())
+ m_targets = m_caster->m_currentSpells[CURRENT_CHANNELED_SPELL]->m_targets;
+ else
+ sLog.outError( "SPELL: cannot find channel spell destination for spell ID %u", m_spellInfo->Id );
+ break;
+ }
+ break;
+ }
default:
+ {
+ switch(cur)
+ {
+ case TARGET_GAMEOBJECT:
+ case TARGET_OBJECT_USE:
+ if(m_targets.getGOTarget())
+ AddGOTarget(m_targets.getGOTarget(), i);
+ break;
+ case TARGET_GAMEOBJECT_ITEM:
+ if(m_targets.getGOTargetGUID())
+ AddGOTarget(m_targets.getGOTarget(), i);
+ else if(m_targets.getItemTarget())
+ AddItemTarget(m_targets.getItemTarget(), i);
+ break;
+ default:
+ sLog.outError("Unhandled spell target %u", cur);
+ break;
+ }
break;
+ }
}
- if(unMaxTargets && !EffectChainTarget && TagUnitMap.size() > 1)
+ if(pushType == PUSH_CHAIN) // Chain
{
- if(m_spellInfo->Id == 5246) //Intimidating Shout
- TagUnitMap.remove(m_targets.getUnitTarget());
+ Unit *target = m_targets.getUnitTarget();
+ if(!target)
+ {
+ sLog.outError("SPELL: no chain unit target for spell ID %u", m_spellInfo->Id);
+ return;
+ }
+
+ //Chain: 2, 6, 22, 25, 45, 77
+ uint32 maxTargets = m_spellInfo->EffectChainTarget[i];
+ if(modOwner)
+ modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_JUMP_TARGETS, maxTargets, this);
+
+ if(maxTargets > 1)
+ {
+ //otherwise, this multiplier is used for something else
+ m_damageMultipliers[i] = 1.0f;
+ m_applyMultiplierMask |= 1 << i;
+
+ float radius;
+ std::list<Unit*> unitList;
- Trinity::RandomResizeList(TagUnitMap, unMaxTargets);
+ switch(cur)
+ {
+ case TARGET_UNIT_NEARBY_ENEMY:
+ case TARGET_UNIT_TARGET_ENEMY:
+ case TARGET_UNIT_NEARBY_ENTRY: // fix me
+ radius = GetSpellRadius(m_spellInfo, i, false);
+ if(modOwner) modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_RADIUS, radius, this);
+ SearchChainTarget(unitList, radius, maxTargets, SPELL_TARGETS_ENEMY);
+ break;
+ case TARGET_UNIT_CHAINHEAL:
+ case TARGET_UNIT_NEARBY_ALLY: // fix me
+ case TARGET_UNIT_NEARBY_ALLY_UNK:
+ case TARGET_UNIT_NEARBY_RAID:
+ radius = GetSpellRadius(m_spellInfo, i, true);
+ if(modOwner) modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_RADIUS, radius, this);
+ SearchChainTarget(unitList, radius, maxTargets, SPELL_TARGETS_CHAINHEAL);
+ break;
+ }
+
+ for(std::list<Unit*>::iterator itr = unitList.begin(); itr != unitList.end(); ++itr)
+ AddUnitTarget(*itr, i);
+ }
+ else
+ AddUnitTarget(target, i);
}
-}
+ else if(pushType)
+ {
+ // Dummy, just for client
+ if(spellmgr.EffectTargetType[m_spellInfo->Effect[i]] == SPELL_REQUIRE_DEST)
+ return;
-class PrioritizeManaPlayerWraper
-{
- friend struct PrioritizeMana;
+ float radius;
+ SpellTargets targetType;
+ switch(cur)
+ {
+ case TARGET_UNIT_AREA_ENEMY_SRC:
+ case TARGET_UNIT_AREA_ENEMY_DST:
+ case TARGET_UNIT_CONE_ENEMY:
+ case TARGET_UNIT_CONE_ENEMY_UNKNOWN:
+ radius = GetSpellRadius(m_spellInfo, i, false);
+ targetType = SPELL_TARGETS_ENEMY;
+ break;
+ case TARGET_UNIT_AREA_ALLY_SRC:
+ case TARGET_UNIT_AREA_ALLY_DST:
+ case TARGET_UNIT_CONE_ALLY:
+ radius = GetSpellRadius(m_spellInfo, i, true);
+ targetType = SPELL_TARGETS_ALLY;
+ break;
+ case TARGET_UNIT_AREA_ENTRY_SRC:
+ case TARGET_UNIT_AREA_ENTRY_DST:
+ case TARGET_UNIT_CONE_ENTRY: // fix me
+ radius = GetSpellRadius(m_spellInfo, i, IsPositiveSpell(m_spellInfo->Id));
+ targetType = SPELL_TARGETS_ENTRY;
+ break;
+ default:
+ radius = GetSpellRadius(m_spellInfo, i, true);
+ targetType = SPELL_TARGETS_NONE;
+ break;
+ }
+
+ if(modOwner)
+ modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_RADIUS, radius, this);
- public:
- explicit PrioritizeManaPlayerWraper(Player* player) : player(player)
+ std::list<Unit*> unitList;
+ if(targetType == SPELL_TARGETS_ENTRY)
{
- uint32 maxmana = player->GetMaxPower(POWER_MANA);
- percentMana = maxmana ? player->GetPower(POWER_MANA) * 100 / maxmana : 101;
+ SpellScriptTarget::const_iterator lower = spellmgr.GetBeginSpellScriptTarget(m_spellInfo->Id);
+ SpellScriptTarget::const_iterator upper = spellmgr.GetEndSpellScriptTarget(m_spellInfo->Id);
+ if(lower == upper)
+ {
+ sLog.outErrorDb("Spell (ID: %u) (caster Entry: %u) does not have record in `spell_script_target`", m_spellInfo->Id, m_caster->GetEntry());
+
+ if(IsPositiveEffect(m_spellInfo->Id, i))
+ SearchAreaTarget(unitList, radius, PUSH_DST_CENTER, SPELL_TARGETS_ALLY);
+ else
+ SearchAreaTarget(unitList, radius, PUSH_DST_CENTER, SPELL_TARGETS_ENEMY);
+ }
+ // let it be done in one check?
+ else
+ {
+ for(SpellScriptTarget::const_iterator i_spellST = lower; i_spellST != upper; ++i_spellST)
+ {
+ if(i_spellST->second.type == SPELL_TARGET_TYPE_CREATURE)
+ SearchAreaTarget(unitList, radius, PUSH_DST_CENTER, SPELL_TARGETS_ENTRY, i_spellST->second.targetEntry);
+ }
+ }
}
- Player* getPlayer() const { return player; }
- private:
- Player* player;
- uint32 percentMana;
-};
+ else if(targetType)
+ SearchAreaTarget(unitList, radius, pushType, targetType);
+ else
+ {
+ switch(cur)
+ {
+ case TARGET_UNIT_AREA_PARTY_SRC:
+ case TARGET_UNIT_AREA_PARTY_DST:
+ m_caster->GetPartyMember(unitList, radius); //fix me
+ break;
+ case TARGET_OBJECT_AREA_SRC: // fix me
+ case TARGET_OBJECT_AREA_DST:
+ break;
+ case TARGET_UNIT_PARTY_TARGET:
+ m_targets.getUnitTarget()->GetPartyMember(unitList, radius);
+ break;
+ case TARGET_UNIT_PARTY_CASTER:
+ m_caster->GetPartyMember(unitList, radius);
+ break;
+ case TARGET_UNIT_RAID_CASTER:
+ m_caster->GetRaidMember(unitList, radius);
+ break;
+ case TARGET_UNIT_CLASS_TARGET:
+ {
+ Player* targetPlayer = m_targets.getUnitTarget() && m_targets.getUnitTarget()->GetTypeId() == TYPEID_PLAYER
+ ? (Player*)m_targets.getUnitTarget() : NULL;
-struct PrioritizeMana
-{
- int operator()( PrioritizeManaPlayerWraper const& x, PrioritizeManaPlayerWraper const& y ) const
- {
- return x.percentMana < y.percentMana;
- }
-};
+ Group* pGroup = targetPlayer ? targetPlayer->GetGroup() : NULL;
+ if(pGroup)
+ {
+ for(GroupReference *itr = pGroup->GetFirstMember(); itr != NULL; itr = itr->next())
+ {
+ Player* Target = itr->getSource();
+
+ // IsHostileTo check duel and controlled by enemy
+ if( Target && targetPlayer->IsWithinDistInMap(Target, radius) &&
+ targetPlayer->getClass() == Target->getClass() &&
+ !m_caster->IsHostileTo(Target) )
+ {
+ AddUnitTarget(Target, i);
+ }
+ }
+ }
+ else if(m_targets.getUnitTarget())
+ AddUnitTarget(m_targets.getUnitTarget(), i);
+ break;
+ }
+ }
+ }
+
+ if(!unitList.empty())
+ {
+ if(m_spellValue->MaxAffectedTargets)
+ {
+ if(m_spellInfo->Id == 5246) //Intimidating Shout
+ unitList.remove(m_targets.getUnitTarget());
+ Trinity::RandomResizeList(unitList, m_spellValue->MaxAffectedTargets);
+ }
+
+ for(std::list<Unit*>::iterator itr = unitList.begin(); itr != unitList.end(); ++itr)
+ AddUnitTarget(*itr, i);
+ }
+ } // Chain or Area
+}
void Spell::prepare(SpellCastTargets const* targets, AuraEffect* triggeredByAura)
{
@@ -2485,8 +2515,8 @@ void Spell::_handle_immediate_phase()
{
if(spellmgr.EffectTargetType[m_spellInfo->Effect[j]] == SPELL_REQUIRE_DEST)
{
- if(!m_targets.HasDest())
- m_targets.setDestination(m_caster, false);
+ if(!m_targets.HasDst())
+ m_targets.setDestination(m_caster);
HandleEffects(m_originalCaster, NULL, NULL, j);
}
else if(spellmgr.EffectTargetType[m_spellInfo->Effect[j]] == SPELL_REQUIRE_NONE)
@@ -3701,7 +3731,7 @@ SpellCastResult Spell::CheckCast(bool strict)
// If 0 spell effect empty - client not send target data (need use selection)
// TODO: check it on next client version
if (m_targets.m_targetMask == TARGET_FLAG_SELF &&
- m_spellInfo->EffectImplicitTargetA[1] == TARGET_CHAIN_DAMAGE)
+ m_spellInfo->EffectImplicitTargetA[1] == TARGET_UNIT_TARGET_ENEMY)
{
if (target = m_caster->GetUnit(*m_caster, ((Player *)m_caster)->GetSelection()))
m_targets.setUnitTarget(target);
@@ -3713,7 +3743,7 @@ SpellCastResult Spell::CheckCast(bool strict)
// check pet presents
for(int j=0;j<3;j++)
{
- if(m_spellInfo->EffectImplicitTargetA[j] == TARGET_PET)
+ if(m_spellInfo->EffectImplicitTargetA[j] == TARGET_UNIT_PET)
{
target = m_caster->GetGuardianPet();
if(!target)
@@ -3831,15 +3861,15 @@ SpellCastResult Spell::CheckCast(bool strict)
{
for(uint8 j = 0; j < 3; j++)
{
- if( m_spellInfo->EffectImplicitTargetA[j] == TARGET_SCRIPT ||
- m_spellInfo->EffectImplicitTargetB[j] == TARGET_SCRIPT && m_spellInfo->EffectImplicitTargetA[j] != TARGET_SELF ||
- m_spellInfo->EffectImplicitTargetA[j] == TARGET_SCRIPT_COORDINATES ||
- m_spellInfo->EffectImplicitTargetB[j] == TARGET_SCRIPT_COORDINATES )
+ if( m_spellInfo->EffectImplicitTargetA[j] == TARGET_UNIT_NEARBY_ENTRY ||
+ m_spellInfo->EffectImplicitTargetB[j] == TARGET_UNIT_NEARBY_ENTRY && m_spellInfo->EffectImplicitTargetA[j] != TARGET_UNIT_CASTER ||
+ m_spellInfo->EffectImplicitTargetA[j] == TARGET_DST_NEARBY_ENTRY ||
+ m_spellInfo->EffectImplicitTargetB[j] == TARGET_DST_NEARBY_ENTRY )
{
SpellScriptTarget::const_iterator lower = spellmgr.GetBeginSpellScriptTarget(m_spellInfo->Id);
SpellScriptTarget::const_iterator upper = spellmgr.GetEndSpellScriptTarget(m_spellInfo->Id);
if(lower==upper)
- sLog.outErrorDb("Spell (ID: %u) has effect EffectImplicitTargetA/EffectImplicitTargetB = TARGET_SCRIPT or TARGET_SCRIPT_COORDINATES, but does not have record in `spell_script_target`",m_spellInfo->Id);
+ sLog.outErrorDb("Spell (ID: %u) has effect EffectImplicitTargetA/EffectImplicitTargetB = TARGET_UNIT_NEARBY_ENTRY or TARGET_DST_NEARBY_ENTRY, but does not have record in `spell_script_target`",m_spellInfo->Id);
SpellRangeEntry const* srange = sSpellRangeStore.LookupEntry(m_spellInfo->rangeIndex);
float range = GetSpellMaxRange(srange);
@@ -3920,31 +3950,31 @@ SpellCastResult Spell::CheckCast(bool strict)
if(creatureScriptTarget)
{
- // store coordinates for TARGET_SCRIPT_COORDINATES
- if (m_spellInfo->EffectImplicitTargetA[j] == TARGET_SCRIPT_COORDINATES ||
- m_spellInfo->EffectImplicitTargetB[j] == TARGET_SCRIPT_COORDINATES )
+ // store coordinates for TARGET_DST_NEARBY_ENTRY
+ if (m_spellInfo->EffectImplicitTargetA[j] == TARGET_DST_NEARBY_ENTRY ||
+ m_spellInfo->EffectImplicitTargetB[j] == TARGET_DST_NEARBY_ENTRY )
{
m_targets.setDestination(creatureScriptTarget->GetPositionX(),creatureScriptTarget->GetPositionY(),creatureScriptTarget->GetPositionZ());
- if(m_spellInfo->EffectImplicitTargetA[j] == TARGET_SCRIPT_COORDINATES && m_spellInfo->EffectImplicitTargetB[j] == 0 && m_spellInfo->Effect[j]!=SPELL_EFFECT_PERSISTENT_AREA_AURA)
+ if(m_spellInfo->EffectImplicitTargetA[j] == TARGET_DST_NEARBY_ENTRY && m_spellInfo->EffectImplicitTargetB[j] == 0 && m_spellInfo->Effect[j]!=SPELL_EFFECT_PERSISTENT_AREA_AURA)
AddUnitTarget(creatureScriptTarget, j);
}
- // store explicit target for TARGET_SCRIPT
+ // store explicit target for TARGET_UNIT_NEARBY_ENTRY
else
AddUnitTarget(creatureScriptTarget, j);
}
else if(goScriptTarget)
{
- // store coordinates for TARGET_SCRIPT_COORDINATES
- if (m_spellInfo->EffectImplicitTargetA[j] == TARGET_SCRIPT_COORDINATES ||
- m_spellInfo->EffectImplicitTargetB[j] == TARGET_SCRIPT_COORDINATES )
+ // store coordinates for TARGET_DST_NEARBY_ENTRY
+ if (m_spellInfo->EffectImplicitTargetA[j] == TARGET_DST_NEARBY_ENTRY ||
+ m_spellInfo->EffectImplicitTargetB[j] == TARGET_DST_NEARBY_ENTRY )
{
m_targets.setDestination(goScriptTarget->GetPositionX(),goScriptTarget->GetPositionY(),goScriptTarget->GetPositionZ());
- if(m_spellInfo->EffectImplicitTargetA[j] == TARGET_SCRIPT_COORDINATES && m_spellInfo->EffectImplicitTargetB[j] == 0 && m_spellInfo->Effect[j]!=SPELL_EFFECT_PERSISTENT_AREA_AURA)
+ if(m_spellInfo->EffectImplicitTargetA[j] == TARGET_DST_NEARBY_ENTRY && m_spellInfo->EffectImplicitTargetB[j] == 0 && m_spellInfo->Effect[j]!=SPELL_EFFECT_PERSISTENT_AREA_AURA)
AddGOTarget(goScriptTarget, j);
}
- // store explicit target for TARGET_SCRIPT
+ // store explicit target for TARGET_UNIT_NEARBY_ENTRY
else
AddGOTarget(goScriptTarget, j);
}
@@ -4008,7 +4038,7 @@ SpellCastResult Spell::CheckCast(bool strict)
if (m_caster->GetTypeId() != TYPEID_PLAYER)
return SPELL_FAILED_BAD_TARGETS;
- if(m_spellInfo->EffectImplicitTargetA[i] != TARGET_PET)
+ if(m_spellInfo->EffectImplicitTargetA[i] != TARGET_UNIT_PET)
break;
Pet* pet = ((Player*)m_caster)->GetPet();
@@ -4430,7 +4460,7 @@ SpellCastResult Spell::CheckPetCast(Unit* target)
bool need = false;
for(uint32 i = 0;i<3;i++)
{
- if(m_spellInfo->EffectImplicitTargetA[i] == TARGET_CHAIN_DAMAGE || m_spellInfo->EffectImplicitTargetA[i] == TARGET_SINGLE_FRIEND || m_spellInfo->EffectImplicitTargetA[i] == TARGET_DUELVSPLAYER || m_spellInfo->EffectImplicitTargetA[i] == TARGET_SINGLE_PARTY || m_spellInfo->EffectImplicitTargetA[i] == TARGET_CURRENT_ENEMY_COORDINATES)
+ if(m_spellInfo->EffectImplicitTargetA[i] == TARGET_UNIT_TARGET_ENEMY || m_spellInfo->EffectImplicitTargetA[i] == TARGET_UNIT_TARGET_ALLY || m_spellInfo->EffectImplicitTargetA[i] == TARGET_UNIT_TARGET_ANY || m_spellInfo->EffectImplicitTargetA[i] == TARGET_UNIT_TARGET_PARTY || m_spellInfo->EffectImplicitTargetA[i] == TARGET_DST_TARGET_ENEMY)
{
need = true;
if(!target)
@@ -4797,8 +4827,8 @@ SpellCastResult Spell::CheckItems()
SpellCastResult failReason = SPELL_CAST_OK;
for (int i = 0; i < 3; i++)
{
- // skip check, pet not required like checks, and for TARGET_PET m_targets.getUnitTarget() is not the real target but the caster
- if (m_spellInfo->EffectImplicitTargetA[i] == TARGET_PET)
+ // skip check, pet not required like checks, and for TARGET_UNIT_PET m_targets.getUnitTarget() is not the real target but the caster
+ if (m_spellInfo->EffectImplicitTargetA[i] == TARGET_UNIT_PET)
continue;
if (m_spellInfo->Effect[i] == SPELL_EFFECT_HEAL)
@@ -5356,10 +5386,10 @@ CurrentSpellTypes Spell::GetCurrentContainer()
return(CURRENT_GENERIC_SPELL);
}
-bool Spell::CheckTarget( Unit* target, uint32 eff )
+bool Spell::CheckTarget(Unit* target, uint32 eff)
{
// Check targets for creature type mask and remove not appropriate (skip explicit self target case, maybe need other explicit targets)
- if(m_spellInfo->EffectImplicitTargetA[eff]!=TARGET_SELF)
+ if(m_spellInfo->EffectImplicitTargetA[eff]!=TARGET_UNIT_CASTER)
{
if (!CheckTargetCreatureType(target))
return false;
@@ -5379,11 +5409,11 @@ bool Spell::CheckTarget( Unit* target, uint32 eff )
if (target->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE))
return false;
- // unselectable targets skipped in all cases except TARGET_SCRIPT targeting
- // in case TARGET_SCRIPT target selected by server always and can't be cheated
+ // unselectable targets skipped in all cases except TARGET_UNIT_NEARBY_ENTRY targeting
+ // in case TARGET_UNIT_NEARBY_ENTRY target selected by server always and can't be cheated
/*if( target->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE) &&
- m_spellInfo->EffectImplicitTargetA[eff] != TARGET_SCRIPT &&
- m_spellInfo->EffectImplicitTargetB[eff] != TARGET_SCRIPT )
+ m_spellInfo->EffectImplicitTargetA[eff] != TARGET_UNIT_NEARBY_ENTRY &&
+ m_spellInfo->EffectImplicitTargetB[eff] != TARGET_UNIT_NEARBY_ENTRY )
return false;*/
}
diff --git a/src/game/Spell.h b/src/game/Spell.h
index 64aa7f24eb0..4b630ce8dc9 100644
--- a/src/game/Spell.h
+++ b/src/game/Spell.h
@@ -101,11 +101,14 @@ enum SpellRangeFlag
enum SpellNotifyPushType
{
+ PUSH_NONE = 0,
PUSH_IN_FRONT,
PUSH_IN_BACK,
PUSH_IN_LINE,
- PUSH_DEST_CENTER,
- PUSH_TARGET_CENTER,
+ PUSH_SRC_CENTER,
+ PUSH_DST_CENTER,
+ PUSH_CASTER_CENTER,
+ PUSH_CHAIN,
};
bool IsQuestTameSpell(uint32 spellId);
@@ -137,29 +140,30 @@ class SpellCastTargets
m_itemTargetEntry = target.m_itemTargetEntry;
- //m_srcX = target.m_srcX;
- //m_srcY = target.m_srcY;
- //m_srcZ = target.m_srcZ;
+ m_srcX = target.m_srcX;
+ m_srcY = target.m_srcY;
+ m_srcZ = target.m_srcZ;
- m_mapId = -1;
m_destX = target.m_destX;
m_destY = target.m_destY;
m_destZ = target.m_destZ;
- m_hasDest = target.m_hasDest;
m_strTarget = target.m_strTarget;
m_targetMask = target.m_targetMask;
+ m_mapId = -1;
+
return *this;
}
uint64 getUnitTargetGUID() const { return m_unitTargetGUID; }
Unit *getUnitTarget() const { return m_unitTarget; }
void setUnitTarget(Unit *target);
- void setDestination(float x, float y, float z, bool send = true, int32 mapId = -1);
- void setDestination(Unit *target, bool send = true);
- void setSource(float x, float y, float z);
+ void setSrc(float x, float y, float z);
+ void setSrc(WorldObject *target);
+ void setDestination(float x, float y, float z, int32 mapId = -1);
+ void setDestination(WorldObject *target);
uint64 getGOTargetGUID() const { return m_GOTargetGUID; }
GameObject *getGOTarget() const { return m_GOTarget; }
@@ -181,14 +185,14 @@ class SpellCastTargets
}
bool IsEmpty() const { return m_GOTargetGUID==0 && m_unitTargetGUID==0 && m_itemTarget==0 && m_CorpseTargetGUID==0; }
- bool HasDest() const { return m_hasDest; }
+ bool HasSrc() const { return m_targetMask & TARGET_FLAG_SOURCE_LOCATION; }
+ bool HasDst() const { return m_targetMask & TARGET_FLAG_DEST_LOCATION; }
void Update(Unit* caster);
float m_srcX, m_srcY, m_srcZ;
- int32 m_mapId;
float m_destX, m_destY, m_destZ;
- bool m_hasDest;
+ int32 m_mapId;
std::string m_strTarget;
uint32 m_targetMask;
@@ -240,6 +244,7 @@ enum ReplenishType
enum SpellTargets
{
+ SPELL_TARGETS_NONE = 0,
SPELL_TARGETS_ALLY,
SPELL_TARGETS_ENEMY,
SPELL_TARGETS_ENTRY,
@@ -405,10 +410,12 @@ class Spell
void WriteAmmoToPacket( WorldPacket * data );
void FillTargetMap();
- void SetTargetMap(uint32 i,uint32 cur,std::list<Unit*> &TagUnitMap);
+ void SetTargetMap(uint32 i, uint32 cur);
bool CheckTarget( Unit* target, uint32 eff );
bool CanAutoCast(Unit* target);
+ void CheckSrc() { if(!m_targets.HasSrc()) m_targets.setSrc(m_caster); }
+ void CheckDst() { if(!m_targets.HasDst()) m_targets.setDestination(m_caster); }
void SendCastResult(SpellCastResult result);
void SendSpellStart();
@@ -593,11 +600,9 @@ class Spell
void DoAllEffectOnTarget(GOTargetInfo *target);
void DoAllEffectOnTarget(ItemTargetInfo *target);
bool UpdateChanneledTargetList();
- void SearchAreaTarget(std::list<Unit*> &data, float radius, SpellNotifyPushType type,
- SpellTargets TargetType, uint32 entry = 0);
- void SearchChainTarget(std::list<Unit*> &data, float radius, uint32 unMaxTargets,
- SpellTargets TargetType);
- Unit* SearchNearbyTarget(float radius, SpellTargets TargetType, uint32 entry = 0);
+ void SearchAreaTarget(std::list<Unit*> &unitList, float radius, SpellNotifyPushType type, SpellTargets TargetType, uint32 entry = 0);
+ void SearchChainTarget(std::list<Unit*> &unitList, float radius, uint32 unMaxTargets, SpellTargets TargetType);
+ WorldObject* SearchNearbyTarget(float range, SpellTargets TargetType);
bool IsValidSingleTargetEffect(Unit const* target, Targets type) const;
bool IsValidSingleTargetSpell(Unit const* target) const;
void CalculateDamageDoneForAllTargets();
@@ -696,8 +701,10 @@ namespace Trinity
switch(i_push_type)
{
- case PUSH_DEST_CENTER:
- case PUSH_TARGET_CENTER:
+ case PUSH_SRC_CENTER:
+ case PUSH_DST_CENTER:
+ case PUSH_CHAIN:
+ default:
if((target->GetDistanceSq(i_x, i_y, i_z) < i_radiusSq))
i_data->push_back(target);
break;
diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp
index f749da89711..33beae157d5 100644
--- a/src/game/SpellEffects.cpp
+++ b/src/game/SpellEffects.cpp
@@ -2110,7 +2110,7 @@ void Spell::EffectTriggerSpell(uint32 i)
bool instant = false;
for(uint32 j = i+1; j < 3; ++j)
{
- if(m_spellInfo->Effect[j]==SPELL_EFFECT_INSTAKILL && m_spellInfo->EffectImplicitTargetA[j]==TARGET_SELF)
+ if(m_spellInfo->Effect[j]==SPELL_EFFECT_INSTAKILL && m_spellInfo->EffectImplicitTargetA[j]==TARGET_UNIT_CASTER)
{
instant = true;
break;
@@ -2153,7 +2153,7 @@ void Spell::EffectJump(uint32 i)
// Init dest coordinates
float x,y,z,o;
- if(m_targets.HasDest())
+ if(m_targets.HasDst())
{
x = m_targets.m_destX;
y = m_targets.m_destY;
@@ -2210,7 +2210,7 @@ void Spell::EffectTeleportUnits(uint32 i)
return;
// If not exist data for dest location - return
- if(!m_targets.HasDest())
+ if(!m_targets.HasDst())
{
sLog.outError( "Spell::EffectTeleportUnits - does not have destination for spell ID %u\n", m_spellInfo->Id );
return;
@@ -2230,7 +2230,7 @@ void Spell::EffectTeleportUnits(uint32 i)
else if(unitTarget->GetTypeId() == TYPEID_PLAYER)
((Player*)unitTarget)->TeleportTo(mapid, x, y, z, orientation, unitTarget==m_caster ? TELE_TO_SPELL : 0);
- // post effects for TARGET_TABLE_X_Y_Z_COORDINATES
+ // post effects for TARGET_DST_DB
switch ( m_spellInfo->Id )
{
// Dimensional Ripper - Everlook
@@ -5674,7 +5674,7 @@ void Spell::EffectMomentMove(uint32 i)
if(unitTarget->isInFlight())
return;
- if(!m_targets.HasDest())
+ if(!m_targets.HasDst())
return;
uint32 mapid = m_caster->GetMapId();
diff --git a/src/game/SpellMgr.cpp b/src/game/SpellMgr.cpp
index 200cc98d803..c23d6aae43f 100644
--- a/src/game/SpellMgr.cpp
+++ b/src/game/SpellMgr.cpp
@@ -94,7 +94,7 @@ SpellMgr::SpellMgr()
case TARGET_UNIT_MASTER:
case TARGET_UNIT_PET:
case TARGET_UNIT_PARTY_CASTER:
- case TARGET_UNIT_RAID:
+ case TARGET_UNIT_RAID_CASTER:
SpellTargetType[i] = TARGET_TYPE_UNIT_CASTER;
break;
case TARGET_UNIT_MINIPET:
@@ -104,24 +104,54 @@ SpellMgr::SpellMgr()
case TARGET_UNIT_TARGET_ENEMY:
case TARGET_UNIT_TARGET_PARTY:
case TARGET_UNIT_PARTY_TARGET:
+ case TARGET_UNIT_CLASS_TARGET:
case TARGET_UNIT_CHAINHEAL:
SpellTargetType[i] = TARGET_TYPE_UNIT_TARGET;
break;
- case TARGET_UNIT_CHANNEL:
- case TARGET_DEST_CHANNEL:
- SpellTargetType[i] = TARGET_TYPE_CHANNEL;
+ case TARGET_UNIT_NEARBY_ENEMY:
+ case TARGET_UNIT_NEARBY_ALLY:
+ case TARGET_UNIT_NEARBY_ALLY_UNK:
+ case TARGET_UNIT_NEARBY_ENTRY:
+ case TARGET_UNIT_NEARBY_RAID:
+ SpellTargetType[i] = TARGET_TYPE_UNIT_NEARBY;
break;
- case TARGET_UNIT_AREA_ENEMY_GROUND:
- case TARGET_UNIT_AREA_ENEMY:
- case TARGET_UNIT_AREA_ALLY_GROUND:
- case TARGET_UNIT_AREA_ALLY:
- case TARGET_UNIT_AREA_ENTRY_GROUND:
- case TARGET_UNIT_AREA_ENTRY:
- case TARGET_UNIT_AREA_PARTY_GROUND:
- case TARGET_UNIT_AREA_PARTY:
- SpellTargetType[i] = TARGET_TYPE_AREA_DEST;
+ case TARGET_UNIT_AREA_ENEMY_SRC:
+ case TARGET_UNIT_AREA_ALLY_SRC:
+ case TARGET_UNIT_AREA_ENTRY_SRC:
+ case TARGET_UNIT_AREA_PARTY_SRC:
+ case TARGET_OBJECT_AREA_SRC:
+ SpellTargetType[i] = TARGET_TYPE_AREA_SRC;
break;
- case TARGET_DEST_TARGET_ENEMY:
+ case TARGET_UNIT_AREA_ENEMY_DST:
+ case TARGET_UNIT_AREA_ALLY_DST:
+ case TARGET_UNIT_AREA_ENTRY_DST:
+ case TARGET_UNIT_AREA_PARTY_DST:
+ case TARGET_OBJECT_AREA_DST:
+ SpellTargetType[i] = TARGET_TYPE_AREA_DST;
+ break;
+ case TARGET_UNIT_CONE_ENEMY:
+ case TARGET_UNIT_CONE_ALLY:
+ case TARGET_UNIT_CONE_ENTRY:
+ case TARGET_UNIT_CONE_ENEMY_UNKNOWN:
+ SpellTargetType[i] = TARGET_TYPE_AREA_CONE;
+ break;
+ case TARGET_DST_CASTER:
+ case TARGET_SRC_CASTER:
+ case TARGET_MINION:
+ case TARGET_DEST_CASTER_FRONT_LEAP:
+ case TARGET_DEST_CASTER_FRONT:
+ case TARGET_DEST_CASTER_BACK:
+ case TARGET_DEST_CASTER_RIGHT:
+ case TARGET_DEST_CASTER_LEFT:
+ case TARGET_DEST_CASTER_FRONT_LEFT:
+ case TARGET_DEST_CASTER_BACK_LEFT:
+ case TARGET_DEST_CASTER_BACK_RIGHT:
+ case TARGET_DEST_CASTER_FRONT_RIGHT:
+ case TARGET_DEST_CASTER_RANDOM:
+ case TARGET_DEST_CASTER_RADIUS:
+ SpellTargetType[i] = TARGET_TYPE_DEST_CASTER;
+ break;
+ case TARGET_DST_TARGET_ENEMY:
case TARGET_DEST_TARGET_ANY:
case TARGET_DEST_TARGET_FRONT:
case TARGET_DEST_TARGET_BACK:
@@ -135,25 +165,11 @@ SpellMgr::SpellMgr()
case TARGET_DEST_TARGET_RADIUS:
SpellTargetType[i] = TARGET_TYPE_DEST_TARGET;
break;
- case TARGET_DEST_CASTER_GROUND:
- case TARGET_DEST_CASTER:
- case TARGET_DEST_CASTER_FRONT_LEFT:
- case TARGET_DEST_CASTER_BACK_LEFT:
- case TARGET_DEST_CASTER_BACK_RIGHT:
- case TARGET_DEST_CASTER_FRONT_RIGHT:
- case TARGET_DEST_CASTER_FRONT:
- case TARGET_MINION:
- case TARGET_DEST_CASTER_FRONT_LEAP:
- case TARGET_DEST_CASTER_BACK:
- case TARGET_DEST_CASTER_RIGHT:
- case TARGET_DEST_CASTER_LEFT:
- case TARGET_DEST_CASTER_RANDOM:
- case TARGET_DEST_CASTER_RADIUS:
- SpellTargetType[i] = TARGET_TYPE_DEST_CASTER;
- break;
case TARGET_DEST_DYNOBJ_ENEMY:
case TARGET_DEST_DYNOBJ_ALLY:
+ case TARGET_DEST_DYNOBJ_NONE:
case TARGET_DEST_DEST:
+ case TARGET_DEST_TRAJ:
case TARGET_DEST_DEST_FRONT_LEFT:
case TARGET_DEST_DEST_BACK_LEFT:
case TARGET_DEST_DEST_BACK_RIGHT:
@@ -165,6 +181,15 @@ SpellMgr::SpellMgr()
case TARGET_DEST_DEST_RANDOM:
SpellTargetType[i] = TARGET_TYPE_DEST_DEST;
break;
+ case TARGET_DST_DB:
+ case TARGET_DST_HOME:
+ case TARGET_DST_NEARBY_ENTRY:
+ SpellTargetType[i] = TARGET_TYPE_DEST_SPECIAL;
+ break;
+ case TARGET_UNIT_CHANNEL:
+ case TARGET_DEST_CHANNEL:
+ SpellTargetType[i] = TARGET_TYPE_CHANNEL;
+ break;
default:
SpellTargetType[i] = TARGET_TYPE_DEFAULT;
}
@@ -174,20 +199,20 @@ SpellMgr::SpellMgr()
{
switch(i)
{
- case TARGET_UNIT_AREA_ENEMY_GROUND:
- case TARGET_UNIT_AREA_ENEMY:
- case TARGET_UNIT_AREA_ALLY_GROUND:
- case TARGET_UNIT_AREA_ALLY:
- case TARGET_UNIT_AREA_ENTRY_GROUND:
- case TARGET_UNIT_AREA_ENTRY:
- case TARGET_UNIT_AREA_PARTY_GROUND:
- case TARGET_UNIT_AREA_PARTY:
+ case TARGET_UNIT_AREA_ENEMY_DST:
+ case TARGET_UNIT_AREA_ENEMY_SRC:
+ case TARGET_UNIT_AREA_ALLY_DST:
+ case TARGET_UNIT_AREA_ALLY_SRC:
+ case TARGET_UNIT_AREA_ENTRY_DST:
+ case TARGET_UNIT_AREA_ENTRY_SRC:
+ case TARGET_UNIT_AREA_PARTY_DST:
+ case TARGET_UNIT_AREA_PARTY_SRC:
case TARGET_UNIT_PARTY_TARGET:
case TARGET_UNIT_PARTY_CASTER:
case TARGET_UNIT_CONE_ENEMY:
case TARGET_UNIT_CONE_ALLY:
case TARGET_UNIT_CONE_ENEMY_UNKNOWN:
- case TARGET_UNIT_RAID:
+ case TARGET_UNIT_RAID_CASTER:
IsAreaEffectTarget[i] = true;
break;
default:
@@ -494,12 +519,12 @@ bool IsPositiveTarget(uint32 targetA, uint32 targetB)
// non-positive targets
switch(targetA)
{
- case TARGET_CHAIN_DAMAGE:
- case TARGET_ALL_ENEMY_IN_AREA:
- case TARGET_ALL_ENEMY_IN_AREA_INSTANT:
- case TARGET_IN_FRONT_OF_CASTER:
+ case TARGET_UNIT_TARGET_ENEMY:
+ case TARGET_UNIT_AREA_ENEMY_SRC:
+ case TARGET_UNIT_AREA_ENEMY_DST:
+ case TARGET_UNIT_CONE_ENEMY:
case TARGET_DEST_DYNOBJ_ENEMY:
- case TARGET_CURRENT_ENEMY_COORDINATES:
+ case TARGET_DST_TARGET_ENEMY:
case TARGET_UNIT_CHANNEL:
return false;
default:
@@ -622,12 +647,12 @@ bool IsPositiveEffect(uint32 spellId, uint32 effIndex, bool deep)
return false;
case SPELL_AURA_PERIODIC_DAMAGE: // used in positive spells also.
// part of negative spell if casted at self (prevent cancel)
- if(spellproto->EffectImplicitTargetA[effIndex] == TARGET_SELF)
+ if(spellproto->EffectImplicitTargetA[effIndex] == TARGET_UNIT_CASTER)
return false;
break;
case SPELL_AURA_MOD_DECREASE_SPEED: // used in positive spells also
// part of positive spell if casted at self
- if(spellproto->EffectImplicitTargetA[effIndex] != TARGET_SELF)
+ if(spellproto->EffectImplicitTargetA[effIndex] != TARGET_UNIT_CASTER)
return false;
// but not this if this first effect (don't found batter check)
if(spellproto->Attributes & 0x4000000 && effIndex==0)
@@ -918,7 +943,7 @@ void SpellMgr::LoadSpellTargetPositions()
bool found = false;
for(int i = 0; i < 3; ++i)
{
- if( spellInfo->EffectImplicitTargetA[i]==TARGET_TABLE_X_Y_Z_COORDINATES || spellInfo->EffectImplicitTargetB[i]==TARGET_TABLE_X_Y_Z_COORDINATES )
+ if( spellInfo->EffectImplicitTargetA[i]==TARGET_DST_DB || spellInfo->EffectImplicitTargetB[i]==TARGET_DST_DB )
{
found = true;
break;
@@ -926,7 +951,7 @@ void SpellMgr::LoadSpellTargetPositions()
}
if(!found)
{
- sLog.outErrorDb("Spell (Id: %u) listed in `spell_target_position` does not have target TARGET_TABLE_X_Y_Z_COORDINATES (17).",Spell_ID);
+ sLog.outErrorDb("Spell (Id: %u) listed in `spell_target_position` does not have target TARGET_DST_DB (17).",Spell_ID);
continue;
}
@@ -2023,7 +2048,7 @@ void SpellMgr::LoadSpellLearnSpells()
// talent or passive spells or skill-step spells auto-casted and not need dependent learning,
// pet teaching spells don't must be dependent learning (casted)
// other required explicit dependent learning
- dbc_node.autoLearned = entry->EffectImplicitTargetA[i]==TARGET_PET || GetTalentSpellCost(spell) > 0 || IsPassiveSpell(spell) || IsSpellHaveEffect(entry,SPELL_EFFECT_SKILL_STEP);
+ dbc_node.autoLearned = entry->EffectImplicitTargetA[i] == TARGET_UNIT_PET || GetTalentSpellCost(spell) > 0 || IsPassiveSpell(spell) || IsSpellHaveEffect(entry,SPELL_EFFECT_SKILL_STEP);
SpellLearnSpellMap::const_iterator db_node_begin = GetBeginSpellLearnSpell(spell);
SpellLearnSpellMap::const_iterator db_node_end = GetEndSpellLearnSpell(spell);
@@ -2095,10 +2120,10 @@ void SpellMgr::LoadSpellScriptTarget()
/*bool targetfound = false;
for(int i = 0; i <3; ++i)
{
- if( spellProto->EffectImplicitTargetA[i]==TARGET_SCRIPT ||
- spellProto->EffectImplicitTargetB[i]==TARGET_SCRIPT ||
- spellProto->EffectImplicitTargetA[i]==TARGET_SCRIPT_COORDINATES ||
- spellProto->EffectImplicitTargetB[i]==TARGET_SCRIPT_COORDINATES )
+ if( spellProto->EffectImplicitTargetA[i]==TARGET_UNIT_NEARBY_ENTRY ||
+ spellProto->EffectImplicitTargetB[i]==TARGET_UNIT_NEARBY_ENTRY ||
+ spellProto->EffectImplicitTargetA[i]==TARGET_DST_NEARBY_ENTRY ||
+ spellProto->EffectImplicitTargetB[i]==TARGET_DST_NEARBY_ENTRY )
{
targetfound = true;
break;
@@ -2106,7 +2131,7 @@ void SpellMgr::LoadSpellScriptTarget()
}
if(!targetfound)
{
- sLog.outErrorDb("Table `spell_script_target`: spellId %u listed for TargetEntry %u does not have any implicit target TARGET_SCRIPT(38) or TARGET_SCRIPT_COORDINATES (46).",spellId,targetEntry);
+ sLog.outErrorDb("Table `spell_script_target`: spellId %u listed for TargetEntry %u does not have any implicit target TARGET_UNIT_NEARBY_ENTRY(38) or TARGET_DST_NEARBY_ENTRY (46).",spellId,targetEntry);
continue;
}*/
@@ -2172,13 +2197,13 @@ void SpellMgr::LoadSpellScriptTarget()
bool found = false;
for(int j=0; j<3; ++j)
{
- if( spellInfo->EffectImplicitTargetA[j] == TARGET_SCRIPT || spellInfo->EffectImplicitTargetA[j] != TARGET_SELF && spellInfo->EffectImplicitTargetB[j] == TARGET_SCRIPT )
+ if( spellInfo->EffectImplicitTargetA[j] == TARGET_UNIT_NEARBY_ENTRY || spellInfo->EffectImplicitTargetA[j] != TARGET_UNIT_CASTER && spellInfo->EffectImplicitTargetB[j] == TARGET_UNIT_NEARBY_ENTRY )
{
SpellScriptTarget::const_iterator lower = spellmgr.GetBeginSpellScriptTarget(spellInfo->Id);
SpellScriptTarget::const_iterator upper = spellmgr.GetEndSpellScriptTarget(spellInfo->Id);
if(lower==upper)
{
- sLog.outErrorDb("Spell (ID: %u) has effect EffectImplicitTargetA/EffectImplicitTargetB = %u (TARGET_SCRIPT), but does not have record in `spell_script_target`",spellInfo->Id,TARGET_SCRIPT);
+ sLog.outErrorDb("Spell (ID: %u) has effect EffectImplicitTargetA/EffectImplicitTargetB = %u (TARGET_UNIT_NEARBY_ENTRY), but does not have record in `spell_script_target`",spellInfo->Id,TARGET_UNIT_NEARBY_ENTRY);
break; // effects of spell
}
}
@@ -2255,7 +2280,7 @@ void SpellMgr::LoadSpellPetAuras()
continue;
}
- PetAura pa(pet, aura, spellInfo->EffectImplicitTargetA[i] == TARGET_PET, spellInfo->CalculateSimpleValue(i));
+ PetAura pa(pet, aura, spellInfo->EffectImplicitTargetA[i] == TARGET_UNIT_PET, spellInfo->CalculateSimpleValue(i));
mSpellPetAuraMap[spell] = pa;
}
diff --git a/src/game/SpellMgr.h b/src/game/SpellMgr.h
index 8913eb84c2a..315fdc1ae17 100644
--- a/src/game/SpellMgr.h
+++ b/src/game/SpellMgr.h
@@ -89,11 +89,15 @@ enum SpellSelectTargetTypes
TARGET_TYPE_DEFAULT,
TARGET_TYPE_UNIT_CASTER,
TARGET_TYPE_UNIT_TARGET,
- TARGET_TYPE_CHANNEL,
- TARGET_TYPE_AREA_DEST,
+ TARGET_TYPE_UNIT_NEARBY,
+ TARGET_TYPE_AREA_SRC,
+ TARGET_TYPE_AREA_DST,
+ TARGET_TYPE_AREA_CONE,
TARGET_TYPE_DEST_CASTER,
TARGET_TYPE_DEST_TARGET,
TARGET_TYPE_DEST_DEST,
+ TARGET_TYPE_DEST_SPECIAL,
+ TARGET_TYPE_CHANNEL,
};
//Some SpellFamilyFlags
@@ -161,6 +165,18 @@ inline uint32 GetSpellRangeType(SpellRangeEntry const *range) { return (range ?
inline uint32 GetSpellRecoveryTime(SpellEntry const *spellInfo) { return spellInfo->RecoveryTime > spellInfo->CategoryRecoveryTime ? spellInfo->RecoveryTime : spellInfo->CategoryRecoveryTime; }
int32 GetSpellDuration(SpellEntry const *spellInfo);
int32 GetSpellMaxDuration(SpellEntry const *spellInfo);
+inline float GetSpellRadius(SpellEntry const *spellInfo, uint32 effectIdx, bool positive)
+{
+ return positive
+ ? GetSpellRadiusForFriend(sSpellRadiusStore.LookupEntry(spellInfo->EffectRadiusIndex[effectIdx]))
+ : GetSpellRadiusForHostile(sSpellRadiusStore.LookupEntry(spellInfo->EffectRadiusIndex[effectIdx]));
+}
+inline float GetSpellMaxRange(SpellEntry const *spellInfo, bool positive)
+{
+ return positive
+ ? GetSpellMaxRangeForFriend(sSpellRangeStore.LookupEntry(spellInfo->rangeIndex))
+ : GetSpellMaxRangeForHostile(sSpellRangeStore.LookupEntry(spellInfo->rangeIndex));
+}
/*struct DispelEntry
{
diff --git a/src/game/TargetedMovementGenerator.cpp b/src/game/TargetedMovementGenerator.cpp
index 6aa4be19765..fcbdb8b30e5 100644
--- a/src/game/TargetedMovementGenerator.cpp
+++ b/src/game/TargetedMovementGenerator.cpp
@@ -155,7 +155,7 @@ TargetedMovementGenerator<T>::Update(T &owner, const uint32 & time_diff)
return true;
}
- if (i_destinationHolder.UpdateTraveller(traveller, time_diff, false))
+ if (i_destinationHolder.UpdateTraveller(traveller, time_diff))
{
// put targeted movement generators on a higher priority
if (owner.GetObjectSize())
diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp
index 458fb466cef..3142e742dcf 100644
--- a/src/game/Unit.cpp
+++ b/src/game/Unit.cpp
@@ -289,6 +289,8 @@ void Unit::SendMonsterStop()
data << getMSTime();
data << uint8(1);
SendMessageToSet(&data, true);
+
+ clearUnitState(UNIT_STAT_MOVE);
}
void Unit::SendMonsterMove(float NewPosX, float NewPosY, float NewPosZ, uint32 Time, Player* player)
@@ -310,6 +312,8 @@ void Unit::SendMonsterMove(float NewPosX, float NewPosY, float NewPosZ, uint32 T
player->GetSession()->SendPacket(&data);
else
SendMessageToSet( &data, true );
+
+ addUnitState(UNIT_STAT_MOVE);
}
void Unit::SendMonsterMove(float NewPosX, float NewPosY, float NewPosZ, uint32 MoveFlags, uint32 time, float speedZ, Player *player)
@@ -399,6 +403,8 @@ void Unit::SendMonsterMoveByPath(Path const& path, uint32 start, uint32 end)
data << uint32( pathSize );
data.append( (char*)path.GetNodes(start), pathSize * 4 * 3 );
SendMessageToSet(&data, true);
+
+ addUnitState(UNIT_STAT_MOVE);
}
void Unit::resetAttackTimer(WeaponAttackType type)
@@ -11533,7 +11539,7 @@ void CharmInfo::InitCharmCreateSpells()
if(!spellInfo) onlyselfcast = false;
for(uint32 i = 0;i<3 && onlyselfcast;++i) //non existent spell will not make any problems as onlyselfcast would be false -> break right away
{
- if(spellInfo->EffectImplicitTargetA[i] != TARGET_SELF && spellInfo->EffectImplicitTargetA[i] != 0)
+ if(spellInfo->EffectImplicitTargetA[i] != TARGET_UNIT_CASTER && spellInfo->EffectImplicitTargetA[i] != 0)
onlyselfcast = false;
}
diff --git a/src/game/Unit.h b/src/game/Unit.h
index bf3f41bb1d1..82c7eb88695 100644
--- a/src/game/Unit.h
+++ b/src/game/Unit.h
@@ -443,11 +443,12 @@ enum UnitState
UNIT_STAT_CHARGING = 0x00020000,
UNIT_STAT_JUMPING = 0x00040000,
UNIT_STAT_ONVEHICLE = 0x00080000,
+ UNIT_STAT_MOVE = 0x00100000,
UNIT_STAT_UNATTACKABLE = (UNIT_STAT_IN_FLIGHT | UNIT_STAT_ONVEHICLE),
UNIT_STAT_MOVING = (UNIT_STAT_ROAMING | UNIT_STAT_CHASE),
UNIT_STAT_CONTROLLED = (UNIT_STAT_CONFUSED | UNIT_STAT_STUNNED | UNIT_STAT_FLEEING),
UNIT_STAT_LOST_CONTROL = (UNIT_STAT_CONTROLLED | UNIT_STAT_JUMPING | UNIT_STAT_CHARGING),
- UNIT_STAT_SIGHTLESS = (UNIT_STAT_LOST_CONTROL | UNIT_STAT_CHASE),
+ UNIT_STAT_SIGHTLESS = (UNIT_STAT_LOST_CONTROL),
UNIT_STAT_CANNOT_AUTOATTACK = (UNIT_STAT_LOST_CONTROL | UNIT_STAT_CASTING),
UNIT_STAT_ALL_STATE = 0xffffffff //(UNIT_STAT_STOPPED | UNIT_STAT_MOVING | UNIT_STAT_IN_COMBAT | UNIT_STAT_IN_FLIGHT)
};
diff --git a/src/game/WaypointMovementGenerator.cpp b/src/game/WaypointMovementGenerator.cpp
index 397b4adadab..6aba7def916 100644
--- a/src/game/WaypointMovementGenerator.cpp
+++ b/src/game/WaypointMovementGenerator.cpp
@@ -151,7 +151,7 @@ WaypointMovementGenerator<Creature>::Update(Creature &unit, const uint32 &diff)
Traveller<Creature> traveller(unit);
i_nextMoveTime.Update(diff);
- i_destinationHolder.UpdateTraveller(traveller, diff, false, true);
+ i_destinationHolder.UpdateTraveller(traveller, diff, true);
if(i_nextMoveTime.Passed())
{
@@ -291,7 +291,7 @@ FlightPathMovementGenerator::Update(Player &player, const uint32 &diff)
if( MovementInProgress() )
{
Traveller<Player> traveller(player);
- if( i_destinationHolder.UpdateTraveller(traveller, diff, false) )
+ if( i_destinationHolder.UpdateTraveller(traveller, diff) )
{
i_destinationHolder.ResetUpdate(FLIGHT_TRAVEL_UPDATE);
if( i_destinationHolder.HasArrived() )