Core/Objects
* Split BuildValuesUpdate into separate virtual methods for every object type that does something special with update fields * Removed _SetCreateBits/_SetUpdateBits to halve the amount of checks if field needs to be sent
This commit is contained in:
1 parent
a8a5239aad
commit
fa75fe78bd
8 files changed
+302
-333
No files matched your search
@@ -17549,3 +17549,177 @@ void Unit::ReleaseFocus(Spell const* focusSpell)
|
||||
if (focusSpell->GetSpellInfo()->AttributesEx5 & SPELL_ATTR5_DONT_TURN_DURING_CAST)
|
||||
ClearUnitState(UNIT_STATE_ROTATING);
|
||||
}
|
||||
|
||||
void Unit::BuildValuesUpdate(uint8 updateType, ByteBuffer* data, Player* target) const
|
||||
{
|
||||
if (!target)
|
||||
return;
|
||||
|
||||
ByteBuffer fieldBuffer;
|
||||
|
||||
UpdateMask updateMask;
|
||||
updateMask.SetCount(m_valuesCount);
|
||||
|
||||
uint32* flags = UnitUpdateFieldFlags;
|
||||
uint32 visibleFlag = UF_FLAG_PUBLIC;
|
||||
|
||||
if (target == this)
|
||||
visibleFlag |= UF_FLAG_PRIVATE;
|
||||
|
||||
Player* plr = GetCharmerOrOwnerPlayerOrPlayerItself();
|
||||
if (GetOwnerGUID() == target->GetGUID())
|
||||
visibleFlag |= UF_FLAG_OWNER;
|
||||
|
||||
if (HasFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_SPECIALINFO))
|
||||
if (HasAuraTypeWithCaster(SPELL_AURA_EMPATHY, target->GetGUID()))
|
||||
visibleFlag |= UF_FLAG_SPECIAL_INFO;
|
||||
|
||||
if (plr && plr->IsInSameRaidWith(target))
|
||||
visibleFlag |= UF_FLAG_PARTY_MEMBER;
|
||||
|
||||
Creature const* creature = ToCreature();
|
||||
for (uint16 index = 0; index < m_valuesCount; ++index)
|
||||
{
|
||||
if (_fieldNotifyFlags & flags[index] ||
|
||||
((flags[index] & visibleFlag) & UF_FLAG_SPECIAL_INFO) ||
|
||||
((updateType == UPDATETYPE_VALUES ? _changesMask.GetBit(index) : m_uint32Values[index]) && (flags[index] & visibleFlag)) ||
|
||||
(index == UNIT_FIELD_AURASTATE && HasFlag(UNIT_FIELD_AURASTATE, PER_CASTER_AURA_STATE_MASK)))
|
||||
{
|
||||
updateMask.SetBit(index);
|
||||
|
||||
if (index == UNIT_NPC_FLAGS)
|
||||
{
|
||||
uint32 appendValue = m_uint32Values[UNIT_NPC_FLAGS];
|
||||
|
||||
if (creature)
|
||||
if (!target->CanSeeSpellClickOn(creature))
|
||||
appendValue &= ~UNIT_NPC_FLAG_SPELLCLICK;
|
||||
|
||||
fieldBuffer << uint32(appendValue);
|
||||
}
|
||||
else if (index == UNIT_FIELD_AURASTATE)
|
||||
{
|
||||
// Check per caster aura states to not enable using a spell in client if specified aura is not by target
|
||||
fieldBuffer << BuildAuraStateUpdateForTarget(target);
|
||||
}
|
||||
// FIXME: Some values at server stored in float format but must be sent to client in uint32 format
|
||||
else if (index >= UNIT_FIELD_BASEATTACKTIME && index <= UNIT_FIELD_RANGEDATTACKTIME)
|
||||
{
|
||||
// convert from float to uint32 and send
|
||||
fieldBuffer << uint32(m_floatValues[index] < 0 ? 0 : m_floatValues[index]);
|
||||
}
|
||||
// there are some float values which may be negative or can't get negative due to other checks
|
||||
else if ((index >= UNIT_FIELD_NEGSTAT0 && index <= UNIT_FIELD_NEGSTAT4) ||
|
||||
(index >= UNIT_FIELD_RESISTANCEBUFFMODSPOSITIVE && index <= (UNIT_FIELD_RESISTANCEBUFFMODSPOSITIVE + 6)) ||
|
||||
(index >= UNIT_FIELD_RESISTANCEBUFFMODSNEGATIVE && index <= (UNIT_FIELD_RESISTANCEBUFFMODSNEGATIVE + 6)) ||
|
||||
(index >= UNIT_FIELD_POSSTAT0 && index <= UNIT_FIELD_POSSTAT4))
|
||||
{
|
||||
fieldBuffer << uint32(m_floatValues[index]);
|
||||
}
|
||||
// Gamemasters should be always able to select units - remove not selectable flag
|
||||
else if (index == UNIT_FIELD_FLAGS)
|
||||
{
|
||||
uint32 appendValue = m_uint32Values[UNIT_FIELD_FLAGS];
|
||||
if (target->IsGameMaster())
|
||||
appendValue &= ~UNIT_FLAG_NOT_SELECTABLE;
|
||||
|
||||
fieldBuffer << uint32(appendValue);
|
||||
}
|
||||
// use modelid_a if not gm, _h if gm for CREATURE_FLAG_EXTRA_TRIGGER creatures
|
||||
else if (index == UNIT_FIELD_DISPLAYID)
|
||||
{
|
||||
uint32 displayId = m_uint32Values[UNIT_FIELD_DISPLAYID];
|
||||
if (creature)
|
||||
{
|
||||
CreatureTemplate const* cinfo = creature->GetCreatureTemplate();
|
||||
|
||||
// this also applies for transform auras
|
||||
if (SpellInfo const* transform = sSpellMgr->GetSpellInfo(getTransForm()))
|
||||
for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
|
||||
if (transform->Effects[i].IsAura(SPELL_AURA_TRANSFORM))
|
||||
if (CreatureTemplate const* transformInfo = sObjectMgr->GetCreatureTemplate(transform->Effects[i].MiscValue))
|
||||
{
|
||||
cinfo = transformInfo;
|
||||
break;
|
||||
}
|
||||
|
||||
if (cinfo->flags_extra & CREATURE_FLAG_EXTRA_TRIGGER)
|
||||
{
|
||||
if (target->IsGameMaster())
|
||||
{
|
||||
if (cinfo->Modelid1)
|
||||
displayId = cinfo->Modelid1; // Modelid1 is a visible model for gms
|
||||
else
|
||||
displayId = 17519; // world visible trigger's model
|
||||
}
|
||||
else
|
||||
{
|
||||
if (cinfo->Modelid2)
|
||||
displayId = cinfo->Modelid2; // Modelid2 is an invisible model for players
|
||||
else
|
||||
displayId = 11686; // world invisible trigger's model
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fieldBuffer << uint32(displayId);
|
||||
}
|
||||
// hide lootable animation for unallowed players
|
||||
else if (index == UNIT_DYNAMIC_FLAGS)
|
||||
{
|
||||
uint32 dynamicFlags = m_uint32Values[UNIT_DYNAMIC_FLAGS] & ~(UNIT_DYNFLAG_TAPPED | UNIT_DYNFLAG_TAPPED_BY_PLAYER);
|
||||
|
||||
if (creature)
|
||||
{
|
||||
if (creature->hasLootRecipient())
|
||||
{
|
||||
dynamicFlags |= UNIT_DYNFLAG_TAPPED;
|
||||
if (creature->isTappedBy(target))
|
||||
dynamicFlags |= UNIT_DYNFLAG_TAPPED_BY_PLAYER;
|
||||
}
|
||||
|
||||
if (!target->isAllowedToLoot(creature))
|
||||
dynamicFlags &= ~UNIT_DYNFLAG_LOOTABLE;
|
||||
}
|
||||
|
||||
// unit UNIT_DYNFLAG_TRACK_UNIT should only be sent to caster of SPELL_AURA_MOD_STALKED auras
|
||||
if (dynamicFlags & UNIT_DYNFLAG_TRACK_UNIT)
|
||||
if (!HasAuraTypeWithCaster(SPELL_AURA_MOD_STALKED, target->GetGUID()))
|
||||
dynamicFlags &= ~UNIT_DYNFLAG_TRACK_UNIT;
|
||||
|
||||
fieldBuffer << dynamicFlags;
|
||||
}
|
||||
// FG: pretend that OTHER players in own group are friendly ("blue")
|
||||
else if (index == UNIT_FIELD_BYTES_2 || index == UNIT_FIELD_FACTIONTEMPLATE)
|
||||
{
|
||||
if (IsControlledByPlayer() && target != this && sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP) && IsInRaidWith(target))
|
||||
{
|
||||
FactionTemplateEntry const* ft1 = GetFactionTemplateEntry();
|
||||
FactionTemplateEntry const* ft2 = target->GetFactionTemplateEntry();
|
||||
if (ft1 && ft2 && !ft1->IsFriendlyTo(*ft2))
|
||||
{
|
||||
if (index == UNIT_FIELD_BYTES_2)
|
||||
// Allow targetting opposite faction in party when enabled in config
|
||||
fieldBuffer << (m_uint32Values[UNIT_FIELD_BYTES_2] & ((UNIT_BYTE2_FLAG_SANCTUARY /*| UNIT_BYTE2_FLAG_AURAS | UNIT_BYTE2_FLAG_UNK5*/) << 8)); // this flag is at uint8 offset 1 !!
|
||||
else
|
||||
// pretend that all other HOSTILE players have own faction, to allow follow, heal, rezz (trade wont work)
|
||||
fieldBuffer << uint32(target->getFaction());
|
||||
}
|
||||
else
|
||||
fieldBuffer << m_uint32Values[index];
|
||||
}
|
||||
else
|
||||
fieldBuffer << m_uint32Values[index];
|
||||
}
|
||||
else
|
||||
{
|
||||
// send in current format (float as float, uint32 as uint32)
|
||||
fieldBuffer << m_uint32Values[index];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*data << uint8(updateMask.GetBlockCount());
|
||||
updateMask.AppendToPacket(data);
|
||||
data->append(fieldBuffer);
|
||||
}
|
||||
Reference in new issue
Block a user