Messed up the commit history, so here is all the files rip, Credit to TrinityCore
This commit is contained in:
@@ -246,13 +246,26 @@ namespace Game.Entities
|
||||
SetEntry(areaTriggerTemplate.Id.Id);
|
||||
|
||||
SetObjectScale(1.0f);
|
||||
SetDuration(-1);
|
||||
|
||||
SetUpdateFieldValue(m_areaTriggerData.ModifyValue(m_areaTriggerData.BoundsRadius2D), GetMaxSearchRadius());
|
||||
SetUpdateFieldValue(m_areaTriggerData.ModifyValue(m_areaTriggerData.DecalPropertiesID), 24u); // blue decal, for .debug areatrigger visibility
|
||||
if (position.SpellForVisuals.HasValue)
|
||||
{
|
||||
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(position.SpellForVisuals.Value, Difficulty.None);
|
||||
SetUpdateFieldValue(m_areaTriggerData.ModifyValue(m_areaTriggerData.SpellForVisuals), position.SpellForVisuals.Value);
|
||||
|
||||
ScaleCurve extraScaleCurve = m_areaTriggerData.ModifyValue(m_areaTriggerData.ExtraScaleCurve);
|
||||
SetUpdateFieldValue(extraScaleCurve.ModifyValue(extraScaleCurve.ParameterCurve), (uint)1.0000001f);
|
||||
SetUpdateFieldValue(extraScaleCurve.ModifyValue(extraScaleCurve.OverrideActive), true);
|
||||
SpellCastVisualField spellCastVisual = m_areaTriggerData.ModifyValue(m_areaTriggerData.SpellVisual);
|
||||
SetUpdateFieldValue(ref spellCastVisual.SpellXSpellVisualID, spellInfo.GetSpellXSpellVisualId());
|
||||
SetUpdateFieldValue(ref spellCastVisual.ScriptVisualID, 0u);
|
||||
}
|
||||
|
||||
if (IsServerSide())
|
||||
SetUpdateFieldValue(m_areaTriggerData.ModifyValue(m_areaTriggerData.DecalPropertiesID), 24u); // blue decal, for .debug areatrigger visibility
|
||||
|
||||
SetScaleCurve(m_areaTriggerData.ModifyValue(m_areaTriggerData.ExtraScaleCurve), new AreaTriggerScaleCurveTemplate());
|
||||
|
||||
VisualAnim visualAnim = m_areaTriggerData.ModifyValue(m_areaTriggerData.VisualAnim);
|
||||
SetUpdateFieldValue(visualAnim.ModifyValue(visualAnim.AnimationDataID), -1);
|
||||
|
||||
_shape = position.Shape;
|
||||
_maxSearchRadius = _shape.GetMaxSearchRadius();
|
||||
@@ -289,16 +302,16 @@ namespace Game.Entities
|
||||
}
|
||||
else
|
||||
UpdateSplinePosition(diff);
|
||||
}
|
||||
|
||||
if (GetDuration() != -1)
|
||||
if (GetDuration() != -1)
|
||||
{
|
||||
if (GetDuration() > diff)
|
||||
_UpdateDuration((int)(_duration - diff));
|
||||
else
|
||||
{
|
||||
if (GetDuration() > diff)
|
||||
_UpdateDuration((int)(_duration - diff));
|
||||
else
|
||||
{
|
||||
Remove(); // expired
|
||||
return;
|
||||
}
|
||||
Remove(); // expired
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -368,7 +381,7 @@ namespace Game.Entities
|
||||
SetUpdateFieldValue(scaleCurve.ModifyValue(scaleCurve.OverrideActive), true);
|
||||
SetUpdateFieldValue(scaleCurve.ModifyValue(scaleCurve.StartTimeOffset), curve.StartTimeOffset);
|
||||
|
||||
Position point = null;
|
||||
Position point = new Position();
|
||||
// ParameterCurve packing information
|
||||
// (not_using_points & 1) | ((interpolation_mode & 0x7) << 1) | ((first_point_offset & 0xFFFFF) << 4) | ((point_count & 0xFF) << 24)
|
||||
// if not_using_points is set then the entire field is simply read as a float (ignoring that lowest bit)
|
||||
|
||||
@@ -292,6 +292,7 @@ namespace Game.Entities
|
||||
{
|
||||
public AreaTriggerId TriggerId;
|
||||
public AreaTriggerShapeInfo Shape = new();
|
||||
public uint? SpellForVisuals;
|
||||
|
||||
public AreaTriggerSpawn() : base(SpawnObjectType.AreaTrigger) { }
|
||||
}
|
||||
|
||||
@@ -1315,10 +1315,11 @@ namespace Game.Entities
|
||||
CreatureData data = Global.ObjectMgr.NewOrExistCreatureData(m_spawnId);
|
||||
|
||||
uint displayId = GetNativeDisplayId();
|
||||
ulong npcflag = ((ulong)m_unitData.NpcFlags[1] << 32) | m_unitData.NpcFlags[0];
|
||||
uint unitFlags = m_unitData.Flags;
|
||||
uint unitFlags2 = m_unitData.Flags2;
|
||||
uint unitFlags3 = m_unitData.Flags3;
|
||||
ulong spawnNpcFlags = ((ulong)m_unitData.NpcFlags[1] << 32) | m_unitData.NpcFlags[0];
|
||||
ulong? npcflag = null;
|
||||
uint? unitFlags = null;
|
||||
uint? unitFlags2 = null;
|
||||
uint? unitFlags3 = null;
|
||||
|
||||
// check if it's a custom model and if not, use 0 for displayId
|
||||
CreatureTemplate cinfo = GetCreatureTemplate();
|
||||
@@ -1328,17 +1329,17 @@ namespace Game.Entities
|
||||
if (displayId != 0 && displayId == model.CreatureDisplayID)
|
||||
displayId = 0;
|
||||
|
||||
if (npcflag == (uint)cinfo.Npcflag)
|
||||
npcflag = 0;
|
||||
if (spawnNpcFlags != cinfo.Npcflag)
|
||||
npcflag = spawnNpcFlags;
|
||||
|
||||
if (unitFlags == (uint)cinfo.UnitFlags)
|
||||
unitFlags = 0;
|
||||
if (m_unitData.Flags == (uint)cinfo.UnitFlags)
|
||||
unitFlags = m_unitData.Flags;
|
||||
|
||||
if (unitFlags2 == cinfo.UnitFlags2)
|
||||
unitFlags2 = 0;
|
||||
if (m_unitData.Flags2 == cinfo.UnitFlags2)
|
||||
unitFlags2 = m_unitData.Flags2;
|
||||
|
||||
if (unitFlags3 == cinfo.UnitFlags3)
|
||||
unitFlags3 = 0;
|
||||
if (m_unitData.Flags3 == cinfo.UnitFlags3)
|
||||
unitFlags3 = m_unitData.Flags3;
|
||||
}
|
||||
|
||||
if (data.SpawnId == 0)
|
||||
@@ -1408,10 +1409,25 @@ namespace Game.Entities
|
||||
stmt.AddValue(index++, GetHealth());
|
||||
stmt.AddValue(index++, GetPower(PowerType.Mana));
|
||||
stmt.AddValue(index++, (byte)GetDefaultMovementType());
|
||||
stmt.AddValue(index++, npcflag);
|
||||
stmt.AddValue(index++, unitFlags);
|
||||
stmt.AddValue(index++, unitFlags2);
|
||||
stmt.AddValue(index++, unitFlags3);
|
||||
if (npcflag.HasValue)
|
||||
stmt.AddValue(index++, npcflag.Value);
|
||||
else
|
||||
stmt.AddNull(index++);
|
||||
|
||||
if (unitFlags.HasValue)
|
||||
stmt.AddValue(index++, unitFlags.Value);
|
||||
else
|
||||
stmt.AddNull(index++);
|
||||
|
||||
if (unitFlags2.HasValue)
|
||||
stmt.AddValue(index++, unitFlags2.Value);
|
||||
else
|
||||
stmt.AddNull(index++);
|
||||
|
||||
if (unitFlags3.HasValue)
|
||||
stmt.AddValue(index++, unitFlags3.Value);
|
||||
else
|
||||
stmt.AddNull(index++);
|
||||
trans.Append(stmt);
|
||||
|
||||
DB.World.CommitTransaction(trans);
|
||||
|
||||
@@ -266,10 +266,10 @@ namespace Game.Entities
|
||||
public uint curhealth;
|
||||
public uint curmana;
|
||||
public byte movementType;
|
||||
public ulong npcflag;
|
||||
public uint unit_flags; // enum UnitFlags mask values
|
||||
public uint unit_flags2; // enum UnitFlags2 mask values
|
||||
public uint unit_flags3; // enum UnitFlags3 mask values
|
||||
public ulong? npcflag;
|
||||
public uint? unit_flags; // enum UnitFlags mask values
|
||||
public uint? unit_flags2; // enum UnitFlags2 mask values
|
||||
public uint? unit_flags3; // enum UnitFlags3 mask values
|
||||
|
||||
public CreatureData() : base(SpawnObjectType.Creature) { }
|
||||
}
|
||||
|
||||
@@ -716,7 +716,7 @@ namespace Game.Entities
|
||||
loot?.Update();
|
||||
|
||||
// Non-consumable chest was partially looted and restock time passed, restock all loot now
|
||||
if (GetGoInfo().Chest.consumable == 0 && GetGoInfo().Chest.chestRestockTime != 0 && GameTime.GetGameTime() >= m_restockTime)
|
||||
if (GetGoInfo().Chest.consumable == 0 && m_restockTime != 0 && GameTime.GetGameTime() >= m_restockTime)
|
||||
{
|
||||
m_restockTime = 0;
|
||||
m_lootState = LootState.Ready;
|
||||
@@ -2361,7 +2361,11 @@ namespace Game.Entities
|
||||
if (info == null)
|
||||
return;
|
||||
|
||||
if (!user.IsPlayer())
|
||||
Player player = user.ToPlayer();
|
||||
if (player == null)
|
||||
return;
|
||||
|
||||
if (!player.CanUseBattlegroundObject(this))
|
||||
return;
|
||||
|
||||
GameObjectType.NewFlag newFlag = (GameObjectType.NewFlag)m_goTypeImpl;
|
||||
@@ -2384,12 +2388,15 @@ namespace Game.Entities
|
||||
if (!user.IsPlayer())
|
||||
return;
|
||||
|
||||
if (!user.IsAlive())
|
||||
return;
|
||||
|
||||
GameObject owner = GetMap().GetGameObject(GetOwnerGUID());
|
||||
if (owner != null)
|
||||
{
|
||||
if (owner.GetGoType() == GameObjectTypes.NewFlag)
|
||||
{
|
||||
GameObjectType.NewFlag newFlag = (GameObjectType.NewFlag)m_goTypeImpl;
|
||||
GameObjectType.NewFlag newFlag = (GameObjectType.NewFlag)owner.m_goTypeImpl;
|
||||
if (newFlag == null)
|
||||
return;
|
||||
|
||||
|
||||
@@ -47,187 +47,187 @@ namespace Game.Entities
|
||||
[FieldOffset(64)]
|
||||
public uint ScriptId;
|
||||
|
||||
[FieldOffset(68)]
|
||||
[FieldOffset(72)]
|
||||
public string StringId;
|
||||
|
||||
[FieldOffset(72)]
|
||||
[FieldOffset(80)]
|
||||
public door Door;
|
||||
|
||||
[FieldOffset(72)]
|
||||
[FieldOffset(80)]
|
||||
public button Button;
|
||||
|
||||
[FieldOffset(72)]
|
||||
[FieldOffset(80)]
|
||||
public questgiver QuestGiver;
|
||||
|
||||
[FieldOffset(72)]
|
||||
[FieldOffset(80)]
|
||||
public chest Chest;
|
||||
|
||||
[FieldOffset(72)]
|
||||
[FieldOffset(80)]
|
||||
public binder Binder;
|
||||
|
||||
[FieldOffset(72)]
|
||||
[FieldOffset(80)]
|
||||
public generic Generic;
|
||||
|
||||
[FieldOffset(72)]
|
||||
[FieldOffset(80)]
|
||||
public trap Trap;
|
||||
|
||||
[FieldOffset(72)]
|
||||
[FieldOffset(80)]
|
||||
public chair Chair;
|
||||
|
||||
[FieldOffset(72)]
|
||||
[FieldOffset(80)]
|
||||
public spellFocus SpellFocus;
|
||||
|
||||
[FieldOffset(72)]
|
||||
[FieldOffset(80)]
|
||||
public text Text;
|
||||
|
||||
[FieldOffset(72)]
|
||||
[FieldOffset(80)]
|
||||
public goober Goober;
|
||||
|
||||
[FieldOffset(72)]
|
||||
[FieldOffset(80)]
|
||||
public transport Transport;
|
||||
|
||||
[FieldOffset(72)]
|
||||
[FieldOffset(80)]
|
||||
public areadamage AreaDamage;
|
||||
|
||||
[FieldOffset(72)]
|
||||
[FieldOffset(80)]
|
||||
public camera Camera;
|
||||
|
||||
[FieldOffset(72)]
|
||||
[FieldOffset(80)]
|
||||
public moTransport MoTransport;
|
||||
|
||||
[FieldOffset(72)]
|
||||
[FieldOffset(80)]
|
||||
public duelflag DuelFlag;
|
||||
|
||||
[FieldOffset(72)]
|
||||
[FieldOffset(80)]
|
||||
public fishingnode FishingNode;
|
||||
|
||||
[FieldOffset(72)]
|
||||
[FieldOffset(80)]
|
||||
public ritual Ritual;
|
||||
|
||||
[FieldOffset(72)]
|
||||
[FieldOffset(80)]
|
||||
public mailbox MailBox;
|
||||
|
||||
[FieldOffset(72)]
|
||||
[FieldOffset(80)]
|
||||
public guardpost GuardPost;
|
||||
|
||||
[FieldOffset(72)]
|
||||
[FieldOffset(80)]
|
||||
public spellcaster SpellCaster;
|
||||
|
||||
[FieldOffset(72)]
|
||||
[FieldOffset(80)]
|
||||
public meetingstone MeetingStone;
|
||||
|
||||
[FieldOffset(72)]
|
||||
[FieldOffset(80)]
|
||||
public flagstand FlagStand;
|
||||
|
||||
[FieldOffset(72)]
|
||||
[FieldOffset(80)]
|
||||
public fishinghole FishingHole;
|
||||
|
||||
[FieldOffset(72)]
|
||||
[FieldOffset(80)]
|
||||
public flagdrop FlagDrop;
|
||||
|
||||
[FieldOffset(72)]
|
||||
[FieldOffset(80)]
|
||||
public controlzone ControlZone;
|
||||
|
||||
[FieldOffset(72)]
|
||||
[FieldOffset(80)]
|
||||
public auraGenerator AuraGenerator;
|
||||
|
||||
[FieldOffset(72)]
|
||||
[FieldOffset(80)]
|
||||
public dungeonDifficulty DungeonDifficulty;
|
||||
|
||||
[FieldOffset(72)]
|
||||
[FieldOffset(80)]
|
||||
public barberChair BarberChair;
|
||||
|
||||
[FieldOffset(72)]
|
||||
[FieldOffset(80)]
|
||||
public destructiblebuilding DestructibleBuilding;
|
||||
|
||||
[FieldOffset(72)]
|
||||
[FieldOffset(80)]
|
||||
public guildbank GuildBank;
|
||||
|
||||
[FieldOffset(72)]
|
||||
[FieldOffset(80)]
|
||||
public trapDoor TrapDoor;
|
||||
|
||||
[FieldOffset(72)]
|
||||
[FieldOffset(80)]
|
||||
public newflag NewFlag;
|
||||
|
||||
[FieldOffset(72)]
|
||||
[FieldOffset(80)]
|
||||
public newflagdrop NewFlagDrop;
|
||||
|
||||
[FieldOffset(72)]
|
||||
[FieldOffset(80)]
|
||||
public garrisonbuilding GarrisonBuilding;
|
||||
|
||||
[FieldOffset(72)]
|
||||
[FieldOffset(80)]
|
||||
public garrisonplot GarrisonPlot;
|
||||
|
||||
[FieldOffset(72)]
|
||||
[FieldOffset(80)]
|
||||
public clientcreature ClientCreature;
|
||||
|
||||
[FieldOffset(72)]
|
||||
[FieldOffset(80)]
|
||||
public clientitem ClientItem;
|
||||
|
||||
[FieldOffset(72)]
|
||||
[FieldOffset(80)]
|
||||
public capturepoint CapturePoint;
|
||||
|
||||
[FieldOffset(72)]
|
||||
[FieldOffset(80)]
|
||||
public phaseablemo PhaseableMO;
|
||||
|
||||
[FieldOffset(72)]
|
||||
[FieldOffset(80)]
|
||||
public garrisonmonument GarrisonMonument;
|
||||
|
||||
[FieldOffset(72)]
|
||||
[FieldOffset(80)]
|
||||
public garrisonshipment GarrisonShipment;
|
||||
|
||||
[FieldOffset(72)]
|
||||
[FieldOffset(80)]
|
||||
public garrisonmonumentplaque GarrisonMonumentPlaque;
|
||||
|
||||
[FieldOffset(72)]
|
||||
[FieldOffset(80)]
|
||||
public itemforge ItemForge;
|
||||
|
||||
[FieldOffset(72)]
|
||||
[FieldOffset(80)]
|
||||
public uilink UILink;
|
||||
|
||||
[FieldOffset(72)]
|
||||
[FieldOffset(80)]
|
||||
public keystonereceptacle KeystoneReceptacle;
|
||||
|
||||
[FieldOffset(72)]
|
||||
[FieldOffset(80)]
|
||||
public gatheringnode GatheringNode;
|
||||
|
||||
[FieldOffset(72)]
|
||||
[FieldOffset(80)]
|
||||
public challengemodereward ChallengeModeReward;
|
||||
|
||||
[FieldOffset(72)]
|
||||
[FieldOffset(80)]
|
||||
public multi Multi;
|
||||
|
||||
[FieldOffset(72)]
|
||||
[FieldOffset(80)]
|
||||
public siegeableMulti SiegeableMulti;
|
||||
|
||||
[FieldOffset(72)]
|
||||
[FieldOffset(80)]
|
||||
public siegeableMO SiegeableMO;
|
||||
|
||||
[FieldOffset(72)]
|
||||
[FieldOffset(80)]
|
||||
public pvpReward PvpReward;
|
||||
|
||||
[FieldOffset(72)]
|
||||
[FieldOffset(80)]
|
||||
public playerchoicechest PlayerChoiceChest;
|
||||
|
||||
[FieldOffset(72)]
|
||||
[FieldOffset(80)]
|
||||
public legendaryforge LegendaryForge;
|
||||
|
||||
[FieldOffset(72)]
|
||||
[FieldOffset(80)]
|
||||
public garrtalenttree GarrTalentTree;
|
||||
|
||||
[FieldOffset(72)]
|
||||
[FieldOffset(80)]
|
||||
public weeklyrewardchest WeeklyRewardChest;
|
||||
|
||||
[FieldOffset(72)]
|
||||
[FieldOffset(80)]
|
||||
public clientmodel ClientModel;
|
||||
|
||||
[FieldOffset(72)]
|
||||
[FieldOffset(80)]
|
||||
public craftingTable CraftingTable;
|
||||
|
||||
[FieldOffset(72)]
|
||||
[FieldOffset(80)]
|
||||
public raw Raw;
|
||||
|
||||
[FieldOffset(208)]
|
||||
[FieldOffset(224)]
|
||||
public QueryGameObjectResponse QueryData;
|
||||
|
||||
// helpers
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -2638,9 +2638,13 @@ namespace Game.Entities
|
||||
if (IsFriendlyTo(target) || target.IsFriendlyTo(this))
|
||||
return false;
|
||||
|
||||
Player playerAffectingAttacker = unit != null && unit.HasUnitFlag(UnitFlags.PlayerControlled) ? GetAffectingPlayer() : go != null ? GetAffectingPlayer() : null;
|
||||
Player playerAffectingAttacker = (unit != null && unit.HasUnitFlag(UnitFlags.PlayerControlled)) || go != null ? GetAffectingPlayer() : null;
|
||||
Player playerAffectingTarget = unitTarget != null && unitTarget.HasUnitFlag(UnitFlags.PlayerControlled) ? unitTarget.GetAffectingPlayer() : null;
|
||||
|
||||
// Pets of mounted players are immune to NPCs
|
||||
if (playerAffectingAttacker == null && unitTarget != null && unitTarget.IsPet() && playerAffectingTarget != null && playerAffectingTarget.IsMounted())
|
||||
return false;
|
||||
|
||||
// Not all neutral creatures can be attacked (even some unfriendly faction does not react aggresive to you, like Sporaggar)
|
||||
if ((playerAffectingAttacker && !playerAffectingTarget) || (!playerAffectingAttacker && playerAffectingTarget))
|
||||
{
|
||||
|
||||
@@ -176,6 +176,8 @@ namespace Game.Entities
|
||||
return false;
|
||||
}
|
||||
|
||||
owner.SetTemporaryUnsummonedPetNumber(0);
|
||||
|
||||
Map map = owner.GetMap();
|
||||
ulong guid = map.GenerateLowGuid(HighGuid.Pet);
|
||||
|
||||
@@ -290,9 +292,6 @@ namespace Game.Entities
|
||||
|
||||
Cypher.Assert(activePetIndex != -1);
|
||||
|
||||
// Check that we either have no pet (unsummoned by player) or it matches temporarily unsummoned pet by server (for example on flying mount)
|
||||
Cypher.Assert(!petStable.CurrentPetIndex.HasValue || petStable.CurrentPetIndex == activePetIndex);
|
||||
|
||||
petStable.SetCurrentActivePetIndex((uint)activePetIndex);
|
||||
}
|
||||
|
||||
@@ -384,6 +383,9 @@ namespace Game.Entities
|
||||
}
|
||||
}
|
||||
|
||||
if (owner.IsMounted())
|
||||
owner.DisablePetControlsOnMount(ReactStates.Passive, CommandStates.Follow);
|
||||
|
||||
// must be after SetMinion (owner guid check)
|
||||
LoadTemplateImmunities();
|
||||
m_loading = false;
|
||||
@@ -458,7 +460,7 @@ namespace Game.Entities
|
||||
string actionBar = GenerateActionBarData();
|
||||
|
||||
Cypher.Assert(owner.GetPetStable().GetCurrentPet() != null && owner.GetPetStable().GetCurrentPet().PetNumber == GetCharmInfo().GetPetNumber());
|
||||
FillPetInfo(owner.GetPetStable().GetCurrentPet());
|
||||
FillPetInfo(owner.GetPetStable().GetCurrentPet(), owner.GetTemporaryPetReactState());
|
||||
|
||||
stmt = CharacterDatabase.GetPreparedStatement(CharStatements.INS_PET);
|
||||
stmt.AddValue(0, GetCharmInfo().GetPetNumber());
|
||||
@@ -467,7 +469,7 @@ namespace Game.Entities
|
||||
stmt.AddValue(3, GetNativeDisplayId());
|
||||
stmt.AddValue(4, GetLevel());
|
||||
stmt.AddValue(5, m_unitData.PetExperience);
|
||||
stmt.AddValue(6, (byte)GetReactState());
|
||||
stmt.AddValue(6, (byte)owner.GetTemporaryPetReactState().GetValueOrDefault(GetReactState()));
|
||||
stmt.AddValue(7, (owner.GetPetStable().GetCurrentActivePetIndex().HasValue ? (short)owner.GetPetStable().GetCurrentActivePetIndex().Value : (short)PetSaveMode.NotInSlot));
|
||||
stmt.AddValue(8, GetName());
|
||||
stmt.AddValue(9, HasPetFlag(UnitPetFlags.CanBeRenamed) ? 0 : 1);
|
||||
@@ -492,14 +494,14 @@ namespace Game.Entities
|
||||
}
|
||||
}
|
||||
|
||||
public void FillPetInfo(PetStable.PetInfo petInfo)
|
||||
public void FillPetInfo(PetStable.PetInfo petInfo, ReactStates? forcedReactState = null)
|
||||
{
|
||||
petInfo.PetNumber = GetCharmInfo().GetPetNumber();
|
||||
petInfo.CreatureId = GetEntry();
|
||||
petInfo.DisplayId = GetNativeDisplayId();
|
||||
petInfo.Level = (byte)GetLevel();
|
||||
petInfo.Experience = m_unitData.PetExperience;
|
||||
petInfo.ReactState = GetReactState();
|
||||
petInfo.ReactState = forcedReactState.GetValueOrDefault(GetReactState());
|
||||
petInfo.Name = GetName();
|
||||
petInfo.WasRenamed = !HasPetFlag(UnitPetFlags.CanBeRenamed);
|
||||
petInfo.Health = (uint)GetHealth();
|
||||
|
||||
@@ -122,6 +122,7 @@ namespace Game.Entities
|
||||
PetStable m_petStable;
|
||||
public List<PetAura> m_petAuras = new();
|
||||
uint m_temporaryUnsummonedPetNumber;
|
||||
ReactStates? m_temporaryPetReactState;
|
||||
uint m_lastpetnumber;
|
||||
|
||||
// Player summoning
|
||||
|
||||
@@ -35,9 +35,9 @@ namespace Game.Entities
|
||||
return nearMembers[randTarget];
|
||||
}
|
||||
|
||||
public PartyResult CanUninviteFromGroup(ObjectGuid guidMember = default)
|
||||
public PartyResult CanUninviteFromGroup(ObjectGuid guidMember, byte? partyIndex)
|
||||
{
|
||||
Group grp = GetGroup();
|
||||
Group grp = GetGroup(partyIndex);
|
||||
if (!grp)
|
||||
return PartyResult.NotInGroup;
|
||||
|
||||
@@ -58,7 +58,7 @@ namespace Game.Entities
|
||||
return PartyResult.PartyLfgBootDungeonComplete;
|
||||
|
||||
Player player = Global.ObjAccessor.FindConnectedPlayer(guidMember);
|
||||
if (!player.m_lootRolls.Empty())
|
||||
if (player != null && !player.m_lootRolls.Empty())
|
||||
return PartyResult.PartyLfgBootLootRolls;
|
||||
|
||||
// @todo Should also be sent when anyone has recently left combat, with an aprox ~5 seconds timer.
|
||||
@@ -150,6 +150,23 @@ namespace Game.Entities
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public Group GetGroup(byte? partyIndex)
|
||||
{
|
||||
Group group = GetGroup();
|
||||
if (!partyIndex.HasValue)
|
||||
return group;
|
||||
|
||||
GroupCategory category = (GroupCategory)partyIndex;
|
||||
if (group != null && group.GetGroupCategory() == category)
|
||||
return group;
|
||||
|
||||
Group originalGroup = GetOriginalGroup();
|
||||
if (originalGroup && originalGroup.GetGroupCategory() == category)
|
||||
return originalGroup;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public void SetGroup(Group group, byte subgroup = 0)
|
||||
{
|
||||
@@ -167,10 +184,7 @@ namespace Game.Entities
|
||||
public void SetPartyType(GroupCategory category, GroupType type)
|
||||
{
|
||||
Cypher.Assert(category < GroupCategory.Max);
|
||||
byte value = m_playerData.PartyType;
|
||||
value &= (byte)~((byte)0xFF << ((byte)category * 4));
|
||||
value |= (byte)((byte)type << ((byte)category * 4));
|
||||
SetUpdateFieldValue(m_values.ModifyValue(m_playerData).ModifyValue(m_playerData.PartyType), value);
|
||||
SetUpdateFieldValue(ref m_values.ModifyValue(m_playerData).ModifyValue(m_playerData.PartyType, (int)category), (byte)type);
|
||||
}
|
||||
|
||||
public void ResetGroupUpdateSequenceIfNeeded(Group group)
|
||||
@@ -207,12 +221,19 @@ namespace Game.Entities
|
||||
}
|
||||
|
||||
public Group GetGroupInvite() { return m_groupInvite; }
|
||||
|
||||
public void SetGroupInvite(Group group) { m_groupInvite = group; }
|
||||
|
||||
public Group GetGroup() { return m_group.GetTarget(); }
|
||||
|
||||
public GroupReference GetGroupRef() { return m_group; }
|
||||
|
||||
public byte GetSubGroup() { return m_group.GetSubGroup(); }
|
||||
|
||||
public GroupUpdateFlags GetGroupUpdateFlag() { return m_groupUpdateMask; }
|
||||
|
||||
public void SetGroupUpdateFlag(GroupUpdateFlags flag) { m_groupUpdateMask |= flag; }
|
||||
|
||||
public void RemoveGroupUpdateFlag(GroupUpdateFlags flag) { m_groupUpdateMask &= ~flag; }
|
||||
|
||||
public Group GetOriginalGroup() { return m_originalGroup.GetTarget(); }
|
||||
|
||||
@@ -109,8 +109,8 @@ namespace Game.Entities
|
||||
m_questObjectiveCriteriaMgr = new QuestObjectiveCriteriaManager(this);
|
||||
m_sceneMgr = new SceneMgr(this);
|
||||
|
||||
m_bgBattlegroundQueueID[0] = new BgBattlegroundQueueID_Rec();
|
||||
m_bgBattlegroundQueueID[1] = new BgBattlegroundQueueID_Rec();
|
||||
for (var i = 0; i < SharedConst.MaxPlayerBGQueues; ++i)
|
||||
m_bgBattlegroundQueueID[i] = new BgBattlegroundQueueID_Rec();
|
||||
|
||||
m_bgData = new BGData();
|
||||
|
||||
@@ -1057,6 +1057,55 @@ namespace Game.Entities
|
||||
public void SetLastPetNumber(uint petnumber) { m_lastpetnumber = petnumber; }
|
||||
public uint GetTemporaryUnsummonedPetNumber() { return m_temporaryUnsummonedPetNumber; }
|
||||
public void SetTemporaryUnsummonedPetNumber(uint petnumber) { m_temporaryUnsummonedPetNumber = petnumber; }
|
||||
|
||||
public ReactStates? GetTemporaryPetReactState() { return m_temporaryPetReactState; }
|
||||
|
||||
public void DisablePetControlsOnMount(ReactStates reactState, CommandStates commandState)
|
||||
{
|
||||
Pet pet = GetPet();
|
||||
if (pet == null)
|
||||
return;
|
||||
|
||||
m_temporaryPetReactState = pet.GetReactState();
|
||||
pet.SetReactState(reactState);
|
||||
CharmInfo charmInfo = pet.GetCharmInfo();
|
||||
if (charmInfo != null)
|
||||
charmInfo.SetCommandState(commandState);
|
||||
|
||||
pet.GetMotionMaster().MoveFollow(this, SharedConst.PetFollowDist, pet.GetFollowAngle());
|
||||
|
||||
PetMode petMode = new();
|
||||
petMode.PetGUID = pet.GetGUID();
|
||||
petMode.ReactState = reactState;
|
||||
petMode.CommandState = commandState;
|
||||
petMode.Flag = 0;
|
||||
SendPacket(petMode);
|
||||
}
|
||||
|
||||
public void EnablePetControlsOnDismount()
|
||||
{
|
||||
Pet pet = GetPet();
|
||||
if (pet != null)
|
||||
{
|
||||
PetMode petMode = new();
|
||||
petMode.PetGUID = pet.GetGUID();
|
||||
if (m_temporaryPetReactState.HasValue)
|
||||
{
|
||||
petMode.ReactState = m_temporaryPetReactState.Value;
|
||||
pet.SetReactState(m_temporaryPetReactState.Value);
|
||||
}
|
||||
|
||||
CharmInfo charmInfo = pet.GetCharmInfo();
|
||||
if (charmInfo != null)
|
||||
petMode.CommandState = charmInfo.GetCommandState();
|
||||
|
||||
petMode.Flag = 0;
|
||||
SendPacket(petMode);
|
||||
}
|
||||
|
||||
m_temporaryPetReactState = null;
|
||||
}
|
||||
|
||||
public void UnsummonPetTemporaryIfAny()
|
||||
{
|
||||
Pet pet = GetPet();
|
||||
@@ -1091,7 +1140,7 @@ namespace Game.Entities
|
||||
|
||||
public bool IsPetNeedBeTemporaryUnsummoned()
|
||||
{
|
||||
return !IsInWorld || !IsAlive() || IsMounted();
|
||||
return !IsInWorld || !IsAlive() || HasUnitMovementFlag(MovementFlag.Flying) || HasExtraUnitMovementFlag2(MovementFlags3.AdvFlying);
|
||||
}
|
||||
|
||||
public void SendRemoveControlBar()
|
||||
@@ -6400,8 +6449,8 @@ namespace Game.Entities
|
||||
public void SendSellError(SellResult msg, Creature creature, ObjectGuid guid)
|
||||
{
|
||||
SellResponse sellResponse = new();
|
||||
sellResponse.VendorGUID = (creature ? creature.GetGUID() : ObjectGuid.Empty);
|
||||
sellResponse.ItemGUID = guid;
|
||||
sellResponse.VendorGUID = creature ? creature.GetGUID() : ObjectGuid.Empty;
|
||||
sellResponse.ItemGUIDs.Add(guid);
|
||||
sellResponse.Reason = msg;
|
||||
SendPacket(sellResponse);
|
||||
}
|
||||
|
||||
@@ -175,7 +175,7 @@ namespace Game.Entities
|
||||
m_lifetime = duration;
|
||||
|
||||
if (m_type == TempSummonType.ManualDespawn)
|
||||
m_type = (duration == TimeSpan.Zero) ? TempSummonType.DeadDespawn : TempSummonType.TimedDespawn;
|
||||
m_type = (duration <= TimeSpan.Zero) ? TempSummonType.DeadDespawn : TempSummonType.TimedDespawn;
|
||||
|
||||
if (summoner != null && summoner.IsPlayer())
|
||||
{
|
||||
|
||||
@@ -1430,23 +1430,8 @@ namespace Game.Entities
|
||||
}
|
||||
}
|
||||
|
||||
// unsummon pet
|
||||
Pet pet = player.GetPet();
|
||||
if (pet != null)
|
||||
{
|
||||
Battleground bg = ToPlayer().GetBattleground();
|
||||
// don't unsummon pet in arena but SetFlag UNIT_FLAG_STUNNED to disable pet's interface
|
||||
if (bg && bg.IsArena())
|
||||
pet.SetUnitFlag(UnitFlags.Stunned);
|
||||
else
|
||||
player.UnsummonPetTemporaryIfAny();
|
||||
}
|
||||
|
||||
// if we have charmed npc, stun him also (everywhere)
|
||||
Unit charm = player.GetCharmed();
|
||||
if (charm)
|
||||
if (charm.GetTypeId() == TypeId.Unit)
|
||||
charm.SetUnitFlag(UnitFlags.Stunned);
|
||||
// disable pet controls
|
||||
player.DisablePetControlsOnMount(ReactStates.Passive, CommandStates.Follow);
|
||||
|
||||
player.SendMovementSetCollisionHeight(player.GetCollisionHeight(), UpdateCollisionHeightReason.Mount);
|
||||
}
|
||||
@@ -1483,20 +1468,8 @@ namespace Game.Entities
|
||||
Player player = ToPlayer();
|
||||
if (player != null)
|
||||
{
|
||||
Pet pPet = player.GetPet();
|
||||
if (pPet != null)
|
||||
{
|
||||
if (pPet.HasUnitFlag(UnitFlags.Stunned) && !pPet.HasUnitState(UnitState.Stunned))
|
||||
pPet.RemoveUnitFlag(UnitFlags.Stunned);
|
||||
}
|
||||
else
|
||||
player.ResummonPetTemporaryUnSummonedIfAny();
|
||||
|
||||
// if we have charmed npc, remove stun also
|
||||
Unit charm = player.GetCharmed();
|
||||
if (charm)
|
||||
if (charm.GetTypeId() == TypeId.Unit && charm.HasUnitFlag(UnitFlags.Stunned) && !charm.HasUnitState(UnitState.Stunned))
|
||||
charm.RemoveUnitFlag(UnitFlags.Stunned);
|
||||
player.EnablePetControlsOnDismount();
|
||||
player.ResummonPetTemporaryUnSummonedIfAny();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -589,18 +589,39 @@ namespace Game.Entities
|
||||
return GetTransport();
|
||||
}
|
||||
|
||||
public void AtStartOfEncounter()
|
||||
public void AtStartOfEncounter(EncounterType type)
|
||||
{
|
||||
RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags2.StartOfEncounter);
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case EncounterType.DungeonEncounter:
|
||||
RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags2.StartOfDungeonEncounter);
|
||||
break;
|
||||
case EncounterType.MythicPlusRun:
|
||||
RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags2.StartOfMythicPlusRun);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (IsAlive())
|
||||
Unit.ProcSkillsAndAuras(this, null, new ProcFlagsInit(ProcFlags.EncounterStart), new ProcFlagsInit(), ProcFlagsSpellType.MaskAll, ProcFlagsSpellPhase.None, ProcFlagsHit.None, null, null, null);
|
||||
}
|
||||
|
||||
public void AtEndOfEncounter()
|
||||
public void AtEndOfEncounter(EncounterType type)
|
||||
{
|
||||
RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags2.EndOfEncounter);
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case EncounterType.DungeonEncounter:
|
||||
RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags2.EndOfDungeonEncounter);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
GetSpellHistory().ResetCooldowns(pair =>
|
||||
{
|
||||
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(pair.Key, Difficulty.None);
|
||||
|
||||
@@ -188,6 +188,15 @@ namespace Game.Entities
|
||||
// We just remove the aura and the unapply handler will make the target leave the vehicle.
|
||||
// We don't need to iterate over Seats
|
||||
_me.RemoveAurasByType(AuraType.ControlVehicle);
|
||||
|
||||
// Aura script might cause the vehicle to be despawned in the middle of handling SPELL_AURA_CONTROL_VEHICLE removal
|
||||
// In that case, aura effect has already been unregistered but passenger may still be found in Seats
|
||||
foreach (var (_, seat) in Seats)
|
||||
{
|
||||
Unit passenger = Global.ObjAccessor.GetUnit(_me, seat.Passenger.Guid);
|
||||
if (passenger != null)
|
||||
passenger._ExitVehicle();
|
||||
}
|
||||
}
|
||||
|
||||
public bool HasEmptySeat(sbyte seatId)
|
||||
|
||||
Reference in New Issue
Block a user