Skip to content

Commit

Permalink
Core/Spells: Implemented CREATURE_TYPEFLAGS_PARTY_MEMBER, creature wi…
Browse files Browse the repository at this point in the history
…th this type_flag set can be targeted by spells that require target to be in caster's party/raid
  • Loading branch information
Shauren committed Mar 19, 2012
1 parent 4665d5b commit 568e524
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 88 deletions.
93 changes: 14 additions & 79 deletions src/server/game/Entities/Unit/Unit.cpp
Expand Up @@ -12199,7 +12199,7 @@ bool Unit::_IsValidAttackTarget(Unit const* target, SpellInfo const* bySpell) co
}

Creature const* creatureAttacker = ToCreature();
if (creatureAttacker && creatureAttacker->GetCreatureTemplate()->type_flags & CREATURE_TYPEFLAGS_UNK26)
if (creatureAttacker && creatureAttacker->GetCreatureTemplate()->type_flags & CREATURE_TYPEFLAGS_PARTY_MEMBER)
return false;

Player const* playerAffectingAttacker = HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE) ? GetAffectingPlayer() : NULL;
Expand Down Expand Up @@ -12286,7 +12286,7 @@ bool Unit::_IsValidAssistTarget(Unit const* target, SpellInfo const* bySpell) co
// can't assist non-friendly targets
if (GetReactionTo(target) <= REP_NEUTRAL
&& target->GetReactionTo(this) <= REP_NEUTRAL
&& (!ToCreature() || !(ToCreature()->GetCreatureTemplate()->type_flags & CREATURE_TYPEFLAGS_UNK26)))
&& (!ToCreature() || !(ToCreature()->GetCreatureTemplate()->type_flags & CREATURE_TYPEFLAGS_PARTY_MEMBER)))
return false;

// PvP case
Expand Down Expand Up @@ -12320,7 +12320,7 @@ bool Unit::_IsValidAssistTarget(Unit const* target, SpellInfo const* bySpell) co
&& !((target->GetByteValue(UNIT_FIELD_BYTES_2, 1) & UNIT_BYTE2_FLAG_PVP)))
{
if (Creature const* creatureTarget = target->ToCreature())
return creatureTarget->GetCreatureTemplate()->type_flags & CREATURE_TYPEFLAGS_UNK26 || creatureTarget->GetCreatureTemplate()->type_flags & CREATURE_TYPEFLAGS_AID_PLAYERS;
return creatureTarget->GetCreatureTemplate()->type_flags & CREATURE_TYPEFLAGS_PARTY_MEMBER || creatureTarget->GetCreatureTemplate()->type_flags & CREATURE_TYPEFLAGS_AID_PLAYERS;
}
return true;
}
Expand Down Expand Up @@ -16160,7 +16160,10 @@ bool Unit::IsInPartyWith(Unit const* unit) const
return true;

if (u1->GetTypeId() == TYPEID_PLAYER && u2->GetTypeId() == TYPEID_PLAYER)
return u1->ToPlayer()->IsInSameGroupWith(u2->ToPlayer());
return u1->ToPlayer()->IsInSameGroupWith(u2->ToPlayer());
else if ((u2->GetTypeId() == TYPEID_PLAYER && u1->GetTypeId() == TYPEID_UNIT && u1->ToCreature()->GetCreatureTemplate()->type_flags & CREATURE_TYPEFLAGS_PARTY_MEMBER) ||
(u1->GetTypeId() == TYPEID_PLAYER && u2->GetTypeId() == TYPEID_UNIT && u2->ToCreature()->GetCreatureTemplate()->type_flags & CREATURE_TYPEFLAGS_PARTY_MEMBER))
return true;
else
return false;
}
Expand All @@ -16176,82 +16179,14 @@ bool Unit::IsInRaidWith(Unit const* unit) const
return true;

if (u1->GetTypeId() == TYPEID_PLAYER && u2->GetTypeId() == TYPEID_PLAYER)
return u1->ToPlayer()->IsInSameRaidWith(u2->ToPlayer());
return u1->ToPlayer()->IsInSameRaidWith(u2->ToPlayer());
else if ((u2->GetTypeId() == TYPEID_PLAYER && u1->GetTypeId() == TYPEID_UNIT && u1->ToCreature()->GetCreatureTemplate()->type_flags & CREATURE_TYPEFLAGS_PARTY_MEMBER) ||
(u1->GetTypeId() == TYPEID_PLAYER && u2->GetTypeId() == TYPEID_UNIT && u2->ToCreature()->GetCreatureTemplate()->type_flags & CREATURE_TYPEFLAGS_PARTY_MEMBER))
return true;
else
return false;
}

void Unit::GetRaidMember(std::list<Unit*> &nearMembers, float radius)
{
Player* owner = GetCharmerOrOwnerPlayerOrPlayerItself();
if (!owner)
return;

Group* group = owner->GetGroup();
if (group)
{
for (GroupReference* itr = group->GetFirstMember(); itr != NULL; itr = itr->next())
{
Player* Target = itr->getSource();

if (Target && !IsHostileTo(Target))
{
if (Target->isAlive() && IsWithinDistInMap(Target, radius))
nearMembers.push_back(Target);

if (Guardian* pet = Target->GetGuardianPet())
if (pet->isAlive() && IsWithinDistInMap(pet, radius))
nearMembers.push_back(pet);
}
}
}
else
{
if (owner->isAlive() && (owner == this || IsWithinDistInMap(owner, radius)))
nearMembers.push_back(owner);
if (Guardian* pet = owner->GetGuardianPet())
if (pet->isAlive() && (pet == this || IsWithinDistInMap(pet, radius)))
nearMembers.push_back(pet);
}
}

void Unit::GetPartyMemberInDist(std::list<Unit*> &TagUnitMap, float radius)
{
Unit* owner = GetCharmerOrOwnerOrSelf();
Group* group = NULL;
if (owner->GetTypeId() == TYPEID_PLAYER)
group = owner->ToPlayer()->GetGroup();

if (group)
{
uint8 subgroup = owner->ToPlayer()->GetSubGroup();

for (GroupReference* itr = group->GetFirstMember(); itr != NULL; itr = itr->next())
{
Player* Target = itr->getSource();

// IsHostileTo check duel and controlled by enemy
if (Target && Target->GetSubGroup() == subgroup && !IsHostileTo(Target))
{
if (Target->isAlive() && IsWithinDistInMap(Target, radius))
TagUnitMap.push_back(Target);

if (Guardian* pet = Target->GetGuardianPet())
if (pet->isAlive() && IsWithinDistInMap(pet, radius))
TagUnitMap.push_back(pet);
}
}
}
else
{
if (owner->isAlive() && (owner == this || IsWithinDistInMap(owner, radius)))
TagUnitMap.push_back(owner);
if (Guardian* pet = owner->GetGuardianPet())
if (pet->isAlive() && (pet == this || IsWithinDistInMap(pet, radius)))
TagUnitMap.push_back(pet);
}
}

void Unit::GetPartyMembers(std::list<Unit*> &TagUnitMap)
{
Unit* owner = GetCharmerOrOwnerOrSelf();
Expand Down Expand Up @@ -17486,7 +17421,7 @@ bool Unit::SetDisableGravity(bool disable)
{
if (disable == IsLevitating())
return false;

if (disable)
AddUnitMovementFlag(MOVEMENTFLAG_DISABLE_GRAVITY);
else
Expand Down Expand Up @@ -17529,7 +17464,7 @@ void Unit::SendMovementHover()
SendMessageToSet(&data, true);
}

void Unit::SendMovementWaterWalking()
void Unit::SendMovementWaterWalking()
{
WorldPacket data(MSG_MOVE_WATER_WALK, 64);
data.append(GetPackGUID());
Expand All @@ -17544,7 +17479,7 @@ void Unit::SendMovementFeatherFall()
BuildMovementPacket(&data);
SendMessageToSet(&data, true);
}

void Unit::SendMovementGravityChange()
{
WorldPacket data(MSG_MOVE_GRAVITY_CHNG, 64);
Expand Down
6 changes: 2 additions & 4 deletions src/server/game/Entities/Unit/Unit.h
Expand Up @@ -708,7 +708,7 @@ enum MovementFlags
MOVEMENTFLAG_LEFT | MOVEMENTFLAG_RIGHT,

//! TODO if needed: add more flags to this masks that are exclusive to players
MOVEMENTFLAG_MASK_PLAYER_ONLY =
MOVEMENTFLAG_MASK_PLAYER_ONLY =
MOVEMENTFLAG_FLYING,
};
enum MovementFlags2
Expand Down Expand Up @@ -1398,9 +1398,7 @@ class Unit : public WorldObject
bool IsNeutralToAll() const;
bool IsInPartyWith(Unit const* unit) const;
bool IsInRaidWith(Unit const* unit) const;
void GetPartyMemberInDist(std::list<Unit*> &units, float dist);
void GetPartyMembers(std::list<Unit*> &units);
void GetRaidMember(std::list<Unit*> &units, float dist);
bool IsContestedGuard() const
{
if (FactionTemplateEntry const* entry = getFactionTemplateEntry())
Expand Down Expand Up @@ -1635,7 +1633,7 @@ class Unit : public WorldObject
/*! These methods send the same packet to the client in apply and unapply case.
The client-side interpretation of this packet depends on the presence of relevant movementflags
which are sent with movementinfo. Furthermore, these packets are broadcast to nearby players as well
as the current unit.
as the current unit.
*/
void SendMovementHover();
void SendMovementFeatherFall();
Expand Down
24 changes: 24 additions & 0 deletions src/server/game/Grids/Notifiers/GridNotifiers.h
Expand Up @@ -858,6 +858,30 @@ namespace Trinity
float i_range;
};

class AnyGroupedUnitInObjectRangeCheck
{
public:
AnyGroupedUnitInObjectRangeCheck(WorldObject const* obj, Unit const* funit, float range, bool raid) : _source(obj), _refUnit(funit), _range(range), _raid(raid) {}
bool operator()(Unit* u)
{
if (_raid)
{
if (!_refUnit->IsInRaidWith(u))
return false;
}
else if (!_refUnit->IsInPartyWith(u))
return false;

return !_refUnit->IsHostileTo(u) && u->isAlive() && _source->IsWithinDistInMap(u, _range);
}

private:
WorldObject const* _source;
Unit const* _refUnit;
float _range;
bool _raid;
};

class AnyUnitInObjectRangeCheck
{
public:
Expand Down
2 changes: 1 addition & 1 deletion src/server/game/Miscellaneous/SharedDefines.h
Expand Up @@ -2589,7 +2589,7 @@ enum CreatureTypeFlags
CREATURE_TYPEFLAGS_UNK23 = 0x00800000, // ? First seen in 3.2.2. Related to banner/backpack of creature/companion?
CREATURE_TYPEFLAGS_UNK24 = 0x01000000,
CREATURE_TYPEFLAGS_UNK25 = 0x02000000,
CREATURE_TYPEFLAGS_UNK26 = 0x04000000,
CREATURE_TYPEFLAGS_PARTY_MEMBER = 0x04000000, //! Creature can be targeted by spells that require target to be in caster's party/raid
CREATURE_TYPEFLAGS_UNK27 = 0x08000000,
CREATURE_TYPEFLAGS_UNK28 = 0x10000000,
CREATURE_TYPEFLAGS_UNK29 = 0x20000000,
Expand Down
9 changes: 5 additions & 4 deletions src/server/game/Spells/Auras/SpellAuras.cpp
Expand Up @@ -2357,13 +2357,14 @@ void UnitAura::FillTargetMap(std::map<Unit*, uint8> & targets, Unit* caster)
switch (GetSpellInfo()->Effects[effIndex].Effect)
{
case SPELL_EFFECT_APPLY_AREA_AURA_PARTY:
targetList.push_back(GetUnitOwner());
GetUnitOwner()->GetPartyMemberInDist(targetList, radius);
break;
case SPELL_EFFECT_APPLY_AREA_AURA_RAID:
{
targetList.push_back(GetUnitOwner());
GetUnitOwner()->GetRaidMember(targetList, radius);
Trinity::AnyGroupedUnitInObjectRangeCheck u_check(GetUnitOwner(), GetUnitOwner(), radius, GetSpellInfo()->Effects[effIndex].Effect == SPELL_EFFECT_APPLY_AREA_AURA_RAID);
Trinity::UnitListSearcher<Trinity::AnyGroupedUnitInObjectRangeCheck> searcher(GetUnitOwner(), targetList, u_check);
GetUnitOwner()->VisitNearbyObject(radius, searcher);
break;
}
case SPELL_EFFECT_APPLY_AREA_AURA_FRIEND:
{
targetList.push_back(GetUnitOwner());
Expand Down

0 comments on commit 568e524

Please sign in to comment.