Updated to 8.2.0.31429 (scripts disabled atm, they still need updated)
Code Port from TrinityCore https://github.com/TrinityCore/TrinityCore Casc from WoW-Tools https://github.com/WoW-Tools/CASCExplorer
This commit is contained in:
@@ -70,7 +70,7 @@ namespace Game.AI
|
||||
return new VehicleAI(creature);
|
||||
else if (creature.HasUnitTypeMask(UnitTypeMask.ControlableGuardian) && ((Guardian)creature).GetOwner().IsTypeId(TypeId.Player))
|
||||
return new PetAI(creature);
|
||||
else if (creature.HasFlag64(UnitFields.NpcFlags, NPCFlags.SpellClick))
|
||||
else if (creature.HasNpcFlag(NPCFlags.SpellClick))
|
||||
return new NullCreatureAI(creature);
|
||||
else if (creature.IsGuard())
|
||||
return new GuardAI(creature);
|
||||
|
||||
@@ -333,9 +333,9 @@ namespace Game.AI
|
||||
if (point)
|
||||
{
|
||||
point.SetObjectScale(SharedConst.BoundaryVisualizeCreatureScale);
|
||||
point.SetFlag(UnitFields.Flags, UnitFlags.ImmuneToPc | UnitFlags.Stunned | UnitFlags.ImmuneToNpc);
|
||||
point.AddUnitFlag(UnitFlags.ImmuneToPc | UnitFlags.Stunned | UnitFlags.ImmuneToNpc);
|
||||
if (!hasOutOfBoundsNeighbor)
|
||||
point.SetFlag(UnitFields.Flags, UnitFlags.NotSelectable);
|
||||
point.AddUnitFlag(UnitFlags.NotSelectable);
|
||||
}
|
||||
Q.Remove(front);
|
||||
}
|
||||
|
||||
@@ -65,14 +65,14 @@ namespace Game.AI
|
||||
public override void JustDied(Unit unit)
|
||||
{
|
||||
// We died while possessed, disable our loot
|
||||
me.RemoveFlag(ObjectFields.DynamicFlags, UnitDynFlags.Lootable);
|
||||
me.RemoveDynamicFlag(UnitDynFlags.Lootable);
|
||||
}
|
||||
|
||||
public override void KilledUnit(Unit victim)
|
||||
{
|
||||
// We killed a creature, disable victim's loot
|
||||
if (victim.IsTypeId(TypeId.Unit))
|
||||
victim.RemoveFlag(ObjectFields.DynamicFlags, UnitDynFlags.Lootable);
|
||||
me.RemoveDynamicFlag(UnitDynFlags.Lootable);
|
||||
}
|
||||
|
||||
public override void OnCharmed(bool apply)
|
||||
|
||||
@@ -392,7 +392,7 @@ namespace Game.AI
|
||||
public PlayerAI(Player player) : base(player)
|
||||
{
|
||||
me = player;
|
||||
_selfSpec = player.GetUInt32Value(PlayerFields.CurrentSpecId);
|
||||
_selfSpec = player.GetPrimarySpecialization();
|
||||
_isSelfHealer = IsPlayerHealer(player);
|
||||
_isSelfRangedAttacker = IsPlayerRangedAttacker(player);
|
||||
}
|
||||
@@ -414,15 +414,15 @@ namespace Game.AI
|
||||
default:
|
||||
return false;
|
||||
case Class.Paladin:
|
||||
return who.GetUInt32Value(PlayerFields.CurrentSpecId) == (uint)TalentSpecialization.PaladinHoly;
|
||||
return who.GetPrimarySpecialization() == (uint)TalentSpecialization.PaladinHoly;
|
||||
case Class.Priest:
|
||||
return who.GetUInt32Value(PlayerFields.CurrentSpecId) == (uint)TalentSpecialization.PriestDiscipline || who.GetUInt32Value(PlayerFields.CurrentSpecId) == (uint)TalentSpecialization.PriestHoly;
|
||||
return who.GetPrimarySpecialization() == (uint)TalentSpecialization.PriestDiscipline || who.GetPrimarySpecialization() == (uint)TalentSpecialization.PriestHoly;
|
||||
case Class.Shaman:
|
||||
return who.GetUInt32Value(PlayerFields.CurrentSpecId) == (uint)TalentSpecialization.ShamanRestoration;
|
||||
return who.GetPrimarySpecialization() == (uint)TalentSpecialization.ShamanRestoration;
|
||||
case Class.Monk:
|
||||
return who.GetUInt32Value(PlayerFields.CurrentSpecId) == (uint)TalentSpecialization.MonkMistweaver;
|
||||
return who.GetPrimarySpecialization() == (uint)TalentSpecialization.MonkMistweaver;
|
||||
case Class.Druid:
|
||||
return who.GetUInt32Value(PlayerFields.CurrentSpecId) == (uint)TalentSpecialization.DruidRestoration;
|
||||
return who.GetPrimarySpecialization() == (uint)TalentSpecialization.DruidRestoration;
|
||||
}
|
||||
}
|
||||
bool IsPlayerRangedAttacker(Player who)
|
||||
@@ -454,11 +454,11 @@ namespace Game.AI
|
||||
return false;
|
||||
}
|
||||
case Class.Priest:
|
||||
return who.GetUInt32Value(PlayerFields.CurrentSpecId) == (uint)TalentSpecialization.PriestShadow;
|
||||
return who.GetPrimarySpecialization() == (uint)TalentSpecialization.PriestShadow;
|
||||
case Class.Shaman:
|
||||
return who.GetUInt32Value(PlayerFields.CurrentSpecId) == (uint)TalentSpecialization.ShamanElemental;
|
||||
return who.GetPrimarySpecialization() == (uint)TalentSpecialization.ShamanElemental;
|
||||
case Class.Druid:
|
||||
return who.GetUInt32Value(PlayerFields.CurrentSpecId) == (uint)TalentSpecialization.DruidBalance;
|
||||
return who.GetPrimarySpecialization() == (uint)TalentSpecialization.DruidBalance;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -659,7 +659,7 @@ namespace Game.AI
|
||||
return (!who || who == me) ? _isSelfHealer : IsPlayerHealer(who);
|
||||
}
|
||||
public bool IsRangedAttacker(Player who = null) { return (!who || who == me) ? _isSelfRangedAttacker : IsPlayerRangedAttacker(who); }
|
||||
uint GetSpec(Player who = null) { return (!who || who == me) ? _selfSpec : who.GetUInt32Value(PlayerFields.CurrentSpecId); }
|
||||
uint GetSpec(Player who = null) { return (!who || who == me) ? _selfSpec : who.GetPrimarySpecialization(); }
|
||||
void SetIsRangedAttacker(bool state) { _isSelfRangedAttacker = state; } // this allows overriding of the default ranged attacker detection
|
||||
|
||||
public virtual Unit SelectAttackTarget() { return me.GetCharmer() ? me.GetCharmer().GetVictim() : null; }
|
||||
|
||||
@@ -125,7 +125,7 @@ namespace Game.AI
|
||||
return null;
|
||||
|
||||
//Silenced so we can't cast
|
||||
if (me.HasFlag(UnitFields.Flags, UnitFlags.Silenced))
|
||||
if (me.HasUnitFlag(UnitFlags.Silenced))
|
||||
return null;
|
||||
|
||||
//Using the extended script system we first create a list of viable spells
|
||||
|
||||
@@ -133,7 +133,7 @@ namespace Game.AI
|
||||
//add a small delay before going to first waypoint, normal in near all cases
|
||||
m_uiWPWaitTimer = 1000;
|
||||
|
||||
if (me.getFaction() != me.GetCreatureTemplate().Faction)
|
||||
if (me.GetFaction() != me.GetCreatureTemplate().Faction)
|
||||
me.RestoreFaction();
|
||||
|
||||
Reset();
|
||||
@@ -162,7 +162,7 @@ namespace Game.AI
|
||||
{
|
||||
me.GetMotionMaster().MoveTargetedHome();
|
||||
if (HasImmuneToNPCFlags)
|
||||
me.SetFlag(UnitFields.Flags, UnitFlags.ImmuneToNpc);
|
||||
me.AddUnitFlag(UnitFlags.ImmuneToNpc);
|
||||
Reset();
|
||||
}
|
||||
}
|
||||
@@ -463,11 +463,12 @@ namespace Game.AI
|
||||
}
|
||||
|
||||
//disable npcflags
|
||||
me.SetUInt64Value(UnitFields.NpcFlags, (ulong)NPCFlags.None);
|
||||
if (me.HasFlag(UnitFields.Flags, UnitFlags.ImmuneToNpc))
|
||||
me.SetNpcFlags(NPCFlags.None);
|
||||
me.SetNpcFlags2(NPCFlags2.None);
|
||||
if (me.HasUnitFlag(UnitFlags.ImmuneToNpc))
|
||||
{
|
||||
HasImmuneToNPCFlags = true;
|
||||
me.RemoveFlag(UnitFields.Flags, UnitFlags.ImmuneToNpc);
|
||||
me.RemoveUnitFlag(UnitFlags.ImmuneToNpc);
|
||||
}
|
||||
|
||||
Log.outDebug(LogFilter.Scripts, $"EscortAI started. ActiveAttacker = {m_bIsActiveAttacker}, Run = {m_bIsRunning}, PlayerGUID = {m_uiPlayerGUID.ToString()}");
|
||||
|
||||
@@ -168,7 +168,7 @@ namespace Game.AI
|
||||
if (!IsCombatMovementAllowed())
|
||||
SetCombatMovement(true);
|
||||
|
||||
if (me.getFaction() != me.GetCreatureTemplate().Faction)
|
||||
if (me.GetFaction() != me.GetCreatureTemplate().Faction)
|
||||
me.SetFaction(me.GetCreatureTemplate().Faction);
|
||||
|
||||
Reset();
|
||||
@@ -318,7 +318,8 @@ namespace Game.AI
|
||||
Log.outDebug(LogFilter.Scripts, "FollowerAI start with WAYPOINT_MOTION_TYPE, set to MoveIdle.");
|
||||
}
|
||||
|
||||
me.SetUInt64Value(UnitFields.NpcFlags, (uint)NPCFlags.None);
|
||||
me.SetNpcFlags(NPCFlags.None);
|
||||
me.SetNpcFlags2(NPCFlags2.None);
|
||||
|
||||
AddFollowState(eFollowState.Inprogress);
|
||||
|
||||
|
||||
@@ -131,8 +131,8 @@ namespace Game.AI
|
||||
|
||||
if (invoker && invoker.GetTypeId() == TypeId.Player)
|
||||
{
|
||||
mEscortNPCFlags = me.GetUInt32Value(UnitFields.NpcFlags);
|
||||
me.SetFlag(UnitFields.NpcFlags, 0);
|
||||
mEscortNPCFlags = me.m_unitData.NpcFlags[0];
|
||||
me.SetNpcFlags(NPCFlags.None);
|
||||
}
|
||||
|
||||
GetScript().ProcessEventsFor(SmartEvents.WaypointStart, null, mCurrentWPID, GetScript().GetPathId());
|
||||
@@ -227,7 +227,7 @@ namespace Game.AI
|
||||
|
||||
if (mEscortNPCFlags != 0)
|
||||
{
|
||||
me.SetFlag(UnitFields.NpcFlags, mEscortNPCFlags);
|
||||
me.SetNpcFlags((NPCFlags)mEscortNPCFlags);
|
||||
mEscortNPCFlags = 0;
|
||||
}
|
||||
|
||||
@@ -591,7 +591,7 @@ namespace Game.AI
|
||||
mDespawnState = 0;
|
||||
mEscortState = SmartEscortState.None;
|
||||
me.SetVisible(true);
|
||||
if (me.getFaction() != me.GetCreatureTemplate().Faction)
|
||||
if (me.GetFaction() != me.GetCreatureTemplate().Faction)
|
||||
me.RestoreFaction();
|
||||
mJustReset = true;
|
||||
JustReachedHome();
|
||||
@@ -646,7 +646,7 @@ namespace Game.AI
|
||||
public override void AttackStart(Unit who)
|
||||
{
|
||||
// dont allow charmed npcs to act on their own
|
||||
if (me.HasFlag(UnitFields.Flags, UnitFlags.PlayerControlled))
|
||||
if (me.HasUnitFlag(UnitFlags.PlayerControlled))
|
||||
{
|
||||
if (who && mCanAutoAttack)
|
||||
me.Attack(who, true);
|
||||
|
||||
@@ -1715,7 +1715,7 @@ namespace Game.AI
|
||||
[FieldOffset(16)]
|
||||
public Raw raw;
|
||||
|
||||
[FieldOffset(32)]
|
||||
[FieldOffset(40)]
|
||||
public string param_string;
|
||||
|
||||
#region Structs
|
||||
|
||||
@@ -221,7 +221,7 @@ namespace Game.AI
|
||||
CreatureTemplate ci = Global.ObjectMgr.GetCreatureTemplate(obj.ToCreature().GetEntry());
|
||||
if (ci != null)
|
||||
{
|
||||
if (obj.ToCreature().getFaction() != ci.Faction)
|
||||
if (obj.ToCreature().GetFaction() != ci.Faction)
|
||||
{
|
||||
obj.ToCreature().SetFaction(ci.Faction);
|
||||
Log.outDebug(LogFilter.ScriptsAi, "SmartScript.ProcessAction. SMART_ACTION_SET_FACTION: Creature entry {0}, GuidLow {1} set faction to {2}",
|
||||
@@ -647,7 +647,7 @@ namespace Game.AI
|
||||
{
|
||||
if (IsUnit(obj))
|
||||
{
|
||||
obj.ToUnit().SetUInt32Value(UnitFields.NpcEmotestate, e.Action.emote.emoteId);
|
||||
obj.ToUnit().SetEmoteState((Emote)e.Action.emote.emoteId);
|
||||
Log.outDebug(LogFilter.ScriptsAi, "SmartScript.ProcessAction. SMART_ACTION_SET_EMOTE_STATE. Unit {0} set emotestate to {1}",
|
||||
obj.GetGUID().ToString(), e.Action.emote.emoteId);
|
||||
}
|
||||
@@ -668,13 +668,13 @@ namespace Game.AI
|
||||
{
|
||||
if (e.Action.unitFlag.type == 0)
|
||||
{
|
||||
obj.ToUnit().SetFlag(UnitFields.Flags, e.Action.unitFlag.flag);
|
||||
obj.ToUnit().AddUnitFlag((UnitFlags)e.Action.unitFlag.flag);
|
||||
Log.outDebug(LogFilter.ScriptsAi, "SmartScript.ProcessAction. SMART_ACTION_SET_UNIT_FLAG. Unit {0} added flag {1} to UNIT_FIELD_FLAGS",
|
||||
obj.GetGUID().ToString(), e.Action.unitFlag.flag);
|
||||
}
|
||||
else
|
||||
{
|
||||
obj.ToUnit().SetFlag(UnitFields.Flags2, e.Action.unitFlag.flag);
|
||||
obj.ToUnit().AddUnitFlag2((UnitFlags2)e.Action.unitFlag.flag);
|
||||
Log.outDebug(LogFilter.ScriptsAi, "SmartScript.ProcessAction. SMART_ACTION_SET_UNIT_FLAG. Unit {0} added flag {1} to UNIT_FIELD_FLAGS_2",
|
||||
obj.GetGUID().ToString(), e.Action.unitFlag.flag);
|
||||
}
|
||||
@@ -696,13 +696,13 @@ namespace Game.AI
|
||||
{
|
||||
if (e.Action.unitFlag.type == 0)
|
||||
{
|
||||
obj.ToUnit().RemoveFlag(UnitFields.Flags2, e.Action.unitFlag.flag);
|
||||
obj.ToUnit().RemoveUnitFlag((UnitFlags)e.Action.unitFlag.flag);
|
||||
Log.outDebug(LogFilter.ScriptsAi, "SmartScript.ProcessAction. SMART_ACTION_REMOVE_UNIT_FLAG. Unit {0} removed flag {1} to UNIT_FIELD_FLAGS",
|
||||
obj.GetGUID().ToString(), e.Action.unitFlag.flag);
|
||||
}
|
||||
else
|
||||
{
|
||||
obj.ToUnit().RemoveFlag(UnitFields.Flags2, e.Action.unitFlag.flag);
|
||||
obj.ToUnit().RemoveUnitFlag2((UnitFlags2)e.Action.unitFlag.flag);
|
||||
Log.outDebug(LogFilter.ScriptsAi, "SmartScript.ProcessAction. SMART_ACTION_REMOVE_UNIT_FLAG. Unit {0} removed flag {1} to UNIT_FIELD_FLAGS_2",
|
||||
obj.GetGUID().ToString(), e.Action.unitFlag.flag);
|
||||
}
|
||||
@@ -1756,7 +1756,7 @@ namespace Game.AI
|
||||
|
||||
foreach (var obj in targets)
|
||||
if (IsUnit(obj))
|
||||
obj.ToUnit().SetUInt64Value(UnitFields.NpcFlags, e.Action.unitFlag.flag);
|
||||
obj.ToUnit().SetNpcFlags((NPCFlags)e.Action.unitFlag.flag);
|
||||
break;
|
||||
}
|
||||
case SmartActions.AddNpcFlag:
|
||||
@@ -1767,7 +1767,7 @@ namespace Game.AI
|
||||
|
||||
foreach (var obj in targets)
|
||||
if (IsUnit(obj))
|
||||
obj.ToUnit().SetFlag64(UnitFields.NpcFlags, e.Action.unitFlag.flag);
|
||||
obj.ToUnit().AddNpcFlag((NPCFlags)e.Action.unitFlag.flag);
|
||||
break;
|
||||
}
|
||||
case SmartActions.RemoveNpcFlag:
|
||||
@@ -1778,7 +1778,7 @@ namespace Game.AI
|
||||
|
||||
foreach (var obj in targets)
|
||||
if (IsUnit(obj))
|
||||
obj.ToUnit().RemoveFlag64(UnitFields.NpcFlags, e.Action.unitFlag.flag);
|
||||
obj.ToUnit().RemoveNpcFlag((NPCFlags)e.Action.unitFlag.flag);
|
||||
break;
|
||||
}
|
||||
case SmartActions.CrossCast:
|
||||
@@ -1937,7 +1937,25 @@ namespace Game.AI
|
||||
break;
|
||||
foreach (var obj in targets)
|
||||
if (IsUnit(obj))
|
||||
obj.ToUnit().SetByteFlag(UnitFields.Bytes1, (byte)e.Action.setunitByte.type, e.Action.setunitByte.byte1);
|
||||
{
|
||||
switch (e.Action.setunitByte.type)
|
||||
{
|
||||
case 0:
|
||||
obj.ToUnit().SetStandState((UnitStandStateType)e.Action.setunitByte.byte1);
|
||||
break;
|
||||
case 1:
|
||||
// pet talent points
|
||||
break;
|
||||
case 2:
|
||||
obj.ToUnit().AddVisFlags((UnitVisFlags)e.Action.setunitByte.byte1);
|
||||
break;
|
||||
case 3:
|
||||
// this is totally wrong to maintain compatibility with existing scripts
|
||||
// TODO: fix with animtier overhaul
|
||||
obj.ToUnit().SetAnimTier((UnitBytes1Flags)(obj.ToUnit().m_unitData.AnimTier | e.Action.setunitByte.byte1), false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SmartActions.RemoveUnitFieldBytes1:
|
||||
@@ -1948,7 +1966,23 @@ namespace Game.AI
|
||||
|
||||
foreach (var obj in targets)
|
||||
if (IsUnit(obj))
|
||||
obj.ToUnit().RemoveByteFlag(UnitFields.Bytes1, (byte)e.Action.delunitByte.type, e.Action.delunitByte.byte1);
|
||||
{
|
||||
switch (e.Action.setunitByte.type)
|
||||
{
|
||||
case 0:
|
||||
obj.ToUnit().SetStandState(UnitStandStateType.Stand);
|
||||
break;
|
||||
case 1:
|
||||
// pet talent points
|
||||
break;
|
||||
case 2:
|
||||
obj.ToUnit().RemoveVisFlags((UnitVisFlags)e.Action.setunitByte.byte1);
|
||||
break;
|
||||
case 3:
|
||||
obj.ToUnit().SetAnimTier((UnitBytes1Flags)(obj.ToUnit().m_unitData.AnimTier & ~e.Action.setunitByte.byte1), false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SmartActions.InterruptSpell:
|
||||
@@ -1981,7 +2015,7 @@ namespace Game.AI
|
||||
|
||||
foreach (var obj in targets)
|
||||
if (IsUnit(obj))
|
||||
obj.ToUnit().SetUInt32Value(ObjectFields.DynamicFlags, e.Action.unitFlag.flag);
|
||||
obj.ToUnit().SetDynamicFlags((UnitDynFlags)e.Action.unitFlag.flag);
|
||||
break;
|
||||
}
|
||||
case SmartActions.AddDynamicFlag:
|
||||
@@ -1992,7 +2026,7 @@ namespace Game.AI
|
||||
|
||||
foreach (var obj in targets)
|
||||
if (IsUnit(obj))
|
||||
obj.ToUnit().SetFlag(ObjectFields.DynamicFlags, e.Action.unitFlag.flag);
|
||||
obj.ToUnit().AddDynamicFlag((UnitDynFlags)e.Action.unitFlag.flag);
|
||||
break;
|
||||
}
|
||||
case SmartActions.RemoveDynamicFlag:
|
||||
@@ -2003,7 +2037,7 @@ namespace Game.AI
|
||||
|
||||
foreach (var obj in targets)
|
||||
if (IsUnit(obj))
|
||||
obj.ToUnit().RemoveFlag(ObjectFields.DynamicFlags, e.Action.unitFlag.flag);
|
||||
obj.ToUnit().RemoveDynamicFlag((UnitDynFlags)e.Action.unitFlag.flag);
|
||||
break;
|
||||
}
|
||||
case SmartActions.JumpToPos:
|
||||
@@ -2163,7 +2197,7 @@ namespace Game.AI
|
||||
|
||||
foreach (var obj in targets)
|
||||
if (IsGameObject(obj))
|
||||
obj.ToGameObject().SetUInt32Value(GameObjectFields.Flags, e.Action.goFlag.flag);
|
||||
obj.ToGameObject().SetFlags((GameObjectFlags)e.Action.goFlag.flag);
|
||||
break;
|
||||
}
|
||||
case SmartActions.AddGoFlag:
|
||||
@@ -2174,7 +2208,7 @@ namespace Game.AI
|
||||
|
||||
foreach (var obj in targets)
|
||||
if (IsGameObject(obj))
|
||||
obj.ToGameObject().SetFlag(GameObjectFields.Flags, e.Action.goFlag.flag);
|
||||
obj.ToGameObject().AddFlag((GameObjectFlags)e.Action.goFlag.flag);
|
||||
break;
|
||||
}
|
||||
case SmartActions.RemoveGoFlag:
|
||||
@@ -2185,7 +2219,7 @@ namespace Game.AI
|
||||
|
||||
foreach (var obj in targets)
|
||||
if (IsGameObject(obj))
|
||||
obj.ToGameObject().RemoveFlag(GameObjectFields.Flags, e.Action.goFlag.flag);
|
||||
obj.ToGameObject().RemoveFlag((GameObjectFlags)e.Action.goFlag.flag);
|
||||
break;
|
||||
}
|
||||
case SmartActions.SummonCreatureGroup:
|
||||
|
||||
@@ -514,7 +514,7 @@ namespace Game.Achievements
|
||||
//! Since no common attributes were found, (not even in titleRewardFlags field)
|
||||
//! we explicitly check by ID. Maybe in the future we could move the achievement_reward
|
||||
//! condition fields to the condition system.
|
||||
uint titleId = reward.TitleId[achievement.Id == 1793 ? _owner.GetByteValue(PlayerFields.Bytes3, PlayerFieldOffsets.Bytes3OffsetGender) : (_owner.GetTeam() == Team.Alliance ? 0 : 1)];
|
||||
uint titleId = reward.TitleId[achievement.Id == 1793 ? _owner.m_playerData.NativeSex : (_owner.GetTeam() == Team.Alliance ? 0 : 1)];
|
||||
if (titleId != 0)
|
||||
{
|
||||
CharTitlesRecord titleEntry = CliDB.CharTitlesStorage.LookupByKey(titleId);
|
||||
|
||||
@@ -284,7 +284,7 @@ namespace Game.Achievements
|
||||
SetCriteriaProgress(criteria, referencePlayer.GetReputationMgr().GetVisibleFactionCount(), referencePlayer);
|
||||
break;
|
||||
case CriteriaTypes.EarnHonorableKill:
|
||||
SetCriteriaProgress(criteria, referencePlayer.GetUInt32Value(ActivePlayerFields.LifetimeHonorableKills), referencePlayer);
|
||||
SetCriteriaProgress(criteria, referencePlayer.m_activePlayerData.LifetimeHonorableKills, referencePlayer);
|
||||
break;
|
||||
case CriteriaTypes.HighestGoldValueOwned:
|
||||
SetCriteriaProgress(criteria, referencePlayer.GetMoney(), referencePlayer, ProgressType.Highest);
|
||||
@@ -1063,12 +1063,12 @@ namespace Game.Achievements
|
||||
if (area.AreaBit < 0)
|
||||
continue;
|
||||
|
||||
int playerIndexOffset = (int)((uint)area.AreaBit / 32);
|
||||
int playerIndexOffset = (int)((uint)area.AreaBit / 64);
|
||||
if (playerIndexOffset >= PlayerConst.ExploredZonesSize)
|
||||
continue;
|
||||
|
||||
uint mask = 1u << (int)((uint)area.AreaBit % 32);
|
||||
if (Convert.ToBoolean(referencePlayer.GetUInt32Value(ActivePlayerFields.ExploredZones + playerIndexOffset) & mask))
|
||||
ulong mask = 1ul << (int)((uint)area.AreaBit % 64);
|
||||
if (Convert.ToBoolean(referencePlayer.m_activePlayerData.ExploredZones[playerIndexOffset] & mask))
|
||||
{
|
||||
matchFound = true;
|
||||
break;
|
||||
|
||||
@@ -29,7 +29,7 @@ namespace Game.Arenas
|
||||
TeamId = (int)(team == Team.Alliance ? BattlegroundTeamId.Alliance : BattlegroundTeamId.Horde);
|
||||
}
|
||||
|
||||
public override void BuildPvPLogPlayerDataPacket(out PVPLogData.PlayerData playerData)
|
||||
public override void BuildPvPLogPlayerDataPacket(out PVPLogData.PVPMatchPlayerStatistics playerData)
|
||||
{
|
||||
base.BuildPvPLogPlayerDataPacket(out playerData);
|
||||
|
||||
|
||||
@@ -555,38 +555,6 @@ namespace Game
|
||||
string name = proto.GetName(player.GetSession().GetSessionDbcLocale());
|
||||
if (string.IsNullOrEmpty(name))
|
||||
continue;
|
||||
|
||||
// DO NOT use GetItemEnchantMod(proto.RandomProperty) as it may return a result
|
||||
// that matches the search but it may not equal item.GetItemRandomPropertyId()
|
||||
// used in BuildAuctionInfo() which then causes wrong items to be listed
|
||||
int propRefID = item.GetItemRandomPropertyId();
|
||||
if (propRefID != 0)
|
||||
{
|
||||
string suffix = null;
|
||||
// Append the suffix to the name (ie: of the Monkey) if one exists
|
||||
// These are found in ItemRandomProperties.dbc, not ItemRandomSuffix.dbc
|
||||
// even though the DBC names seem misleading
|
||||
if (propRefID < 0)
|
||||
{
|
||||
ItemRandomSuffixRecord itemRandSuffix = CliDB.ItemRandomSuffixStorage.LookupByKey(-propRefID);
|
||||
if (itemRandSuffix != null)
|
||||
suffix = itemRandSuffix.Name[player.GetSession().GetSessionDbcLocale()];
|
||||
}
|
||||
else
|
||||
{
|
||||
ItemRandomPropertiesRecord itemRandProp = CliDB.ItemRandomPropertiesStorage.LookupByKey(propRefID);
|
||||
if (itemRandProp != null)
|
||||
suffix = itemRandProp.Name[player.GetSession().GetSessionDbcLocale()];
|
||||
}
|
||||
|
||||
// dbc local name
|
||||
if (!string.IsNullOrEmpty(suffix))
|
||||
{
|
||||
// Append the suffix (ie: of the Monkey) to the name using localization
|
||||
// or default enUS if localization is invalid
|
||||
name += ' ' + suffix;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add the item if no search term or if entered search term was found
|
||||
@@ -645,7 +613,7 @@ namespace Game
|
||||
}
|
||||
|
||||
byte i = 0;
|
||||
foreach (ItemDynamicFieldGems gemData in item.GetGems())
|
||||
foreach (SocketedGem gemData in item.m_itemData.Gems)
|
||||
{
|
||||
if (gemData.ItemId != 0)
|
||||
{
|
||||
|
||||
@@ -501,7 +501,7 @@ namespace Game.BattleFields
|
||||
{
|
||||
creature.CombatStop();
|
||||
creature.SetReactState(ReactStates.Passive);
|
||||
creature.SetFlag(UnitFields.Flags, UnitFlags.NonAttackable | UnitFlags.NotSelectable);
|
||||
creature.AddUnitFlag(UnitFlags.NonAttackable | UnitFlags.NotSelectable);
|
||||
creature.DisappearAndDie();
|
||||
creature.SetVisible(false);
|
||||
}
|
||||
@@ -509,14 +509,14 @@ namespace Game.BattleFields
|
||||
public void ShowNpc(Creature creature, bool aggressive)
|
||||
{
|
||||
creature.SetVisible(true);
|
||||
creature.RemoveFlag(UnitFields.Flags, UnitFlags.NonAttackable | UnitFlags.NotSelectable);
|
||||
creature.RemoveUnitFlag(UnitFlags.NonAttackable | UnitFlags.NotSelectable);
|
||||
if (!creature.IsAlive())
|
||||
creature.Respawn(true);
|
||||
if (aggressive)
|
||||
creature.SetReactState(ReactStates.Aggressive);
|
||||
else
|
||||
{
|
||||
creature.SetFlag(UnitFields.Flags, UnitFlags.NonAttackable);
|
||||
creature.AddUnitFlag(UnitFlags.NonAttackable);
|
||||
creature.SetReactState(ReactStates.Passive);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -187,7 +187,7 @@ namespace Game.BattleFields
|
||||
// Update faction of relic, only attacker can click on
|
||||
relic.SetFaction(WGConst.WintergraspFaction[GetAttackerTeam()]);
|
||||
// Set in use (not allow to click on before last door is broken)
|
||||
relic.SetFlag(GameObjectFields.Flags, GameObjectFlags.InUse | GameObjectFlags.NotSelectable);
|
||||
relic.AddFlag(GameObjectFlags.InUse | GameObjectFlags.NotSelectable);
|
||||
m_titansRelicGUID = relic.GetGUID();
|
||||
}
|
||||
else
|
||||
@@ -1157,7 +1157,7 @@ namespace Game.BattleFields
|
||||
}
|
||||
_wg.SetRelicInteractible(true);
|
||||
if (_wg.GetRelic())
|
||||
_wg.GetRelic().RemoveFlag(GameObjectFields.Flags, GameObjectFlags.InUse | GameObjectFlags.NotSelectable);
|
||||
_wg.GetRelic().RemoveFlag(GameObjectFlags.InUse | GameObjectFlags.NotSelectable);
|
||||
else
|
||||
Log.outError(LogFilter.Server, "BattlefieldWG: Titan Relic not found.");
|
||||
break;
|
||||
|
||||
@@ -426,7 +426,7 @@ namespace Game.BattleGrounds
|
||||
player.SendPacket(battlefieldStatus);
|
||||
|
||||
// Correctly display EnemyUnitFrame
|
||||
player.SetByteValue(PlayerFields.Bytes4, 3, (byte)player.GetBGTeam());
|
||||
player.SetArenaFaction((byte)player.GetBGTeam());
|
||||
|
||||
player.RemoveAurasDueToSpell(BattlegroundConst.SpellArenaPreparation);
|
||||
player.ResetAllPowers();
|
||||
@@ -974,7 +974,7 @@ namespace Game.BattleGrounds
|
||||
public virtual void AddPlayer(Player player)
|
||||
{
|
||||
// remove afk from player
|
||||
if (player.HasFlag(PlayerFields.Flags, PlayerFlags.AFK))
|
||||
if (player.isAFK())
|
||||
player.ToggleAFK();
|
||||
|
||||
// score struct must be created in inherited class
|
||||
@@ -985,7 +985,7 @@ namespace Game.BattleGrounds
|
||||
BattlegroundPlayer bp = new BattlegroundPlayer();
|
||||
bp.OfflineRemoveTime = 0;
|
||||
bp.Team = team;
|
||||
bp.ActiveSpec = player.GetInt32Value(PlayerFields.CurrentSpecId);
|
||||
bp.ActiveSpec = (int)player.GetPrimarySpecialization();
|
||||
|
||||
// Add to list/maps
|
||||
m_Players[guid] = bp;
|
||||
@@ -1221,12 +1221,9 @@ namespace Game.BattleGrounds
|
||||
{
|
||||
pvpLogData = new PVPLogData();
|
||||
|
||||
if (GetStatus() == BattlegroundStatus.WaitLeave)
|
||||
pvpLogData.Winner.Set((byte)GetWinner());
|
||||
|
||||
foreach (var score in PlayerScores)
|
||||
{
|
||||
PVPLogData.PlayerData playerData;
|
||||
PVPLogData.PVPMatchPlayerStatistics playerData;
|
||||
|
||||
score.Value.BuildPvPLogPlayerDataPacket(out playerData);
|
||||
|
||||
@@ -1234,14 +1231,14 @@ namespace Game.BattleGrounds
|
||||
if (player)
|
||||
{
|
||||
playerData.IsInWorld = true;
|
||||
playerData.PrimaryTalentTree = (int)player.GetUInt32Value(PlayerFields.CurrentSpecId);
|
||||
playerData.PrimaryTalentTree = (int)player.GetPrimarySpecialization();
|
||||
playerData.Sex = (int)player.GetGender();
|
||||
playerData.PlayerRace = player.GetRace();
|
||||
playerData.PlayerClass = (int)player.GetClass();
|
||||
playerData.HonorLevel = (int)player.GetHonorLevel();
|
||||
}
|
||||
|
||||
pvpLogData.Players.Add(playerData);
|
||||
pvpLogData.Statistics.Add(playerData);
|
||||
}
|
||||
|
||||
pvpLogData.PlayerCount[(int)BattlegroundTeamId.Horde] = (sbyte)GetPlayersCountByTeam(Team.Horde);
|
||||
@@ -1534,9 +1531,6 @@ namespace Game.BattleGrounds
|
||||
// casting visual effect
|
||||
creature.SetChannelSpellId(BattlegroundConst.SpellSpiritHealChannel);
|
||||
creature.SetChannelSpellXSpellVisualId(BattlegroundConst.SpellSpiritHealChannelVisual);
|
||||
// correct cast speed
|
||||
creature.SetFloatValue(UnitFields.ModCastSpeed, 1.0f);
|
||||
creature.SetFloatValue(UnitFields.ModCastHaste, 1.0f);
|
||||
//creature.CastSpell(creature, SPELL_SPIRIT_HEAL_CHANNEL, true);
|
||||
return true;
|
||||
}
|
||||
@@ -1649,7 +1643,7 @@ namespace Game.BattleGrounds
|
||||
if (!isArena())
|
||||
{
|
||||
// To be able to remove insignia -- ONLY IN Battlegrounds
|
||||
victim.SetFlag(UnitFields.Flags, UnitFlags.Skinnable);
|
||||
victim.AddUnitFlag(UnitFlags.Skinnable);
|
||||
RewardXPAtKill(killer, victim);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -702,7 +702,7 @@ namespace Game.BattleGrounds
|
||||
CreatureTemplate cInfo = Global.ObjectMgr.GetCreatureTemplate(entry);
|
||||
if (cInfo != null)
|
||||
{
|
||||
if (!cInfo.Npcflag.HasAnyFlag(NPCFlags.BattleMaster))
|
||||
if (!cInfo.Npcflag.HasAnyFlag((uint)NPCFlags.BattleMaster))
|
||||
Log.outError(LogFilter.Sql, "Creature (Entry: {0}) listed in `battlemaster_entry` is not a battlemaster.", entry);
|
||||
}
|
||||
else
|
||||
@@ -733,10 +733,10 @@ namespace Game.BattleGrounds
|
||||
var templates = Global.ObjectMgr.GetCreatureTemplates();
|
||||
foreach (var creature in templates)
|
||||
{
|
||||
if (creature.Value.Npcflag.HasAnyFlag(NPCFlags.BattleMaster) && !mBattleMastersMap.ContainsKey(creature.Value.Entry))
|
||||
if (creature.Value.Npcflag.HasAnyFlag((uint)NPCFlags.BattleMaster) && !mBattleMastersMap.ContainsKey(creature.Value.Entry))
|
||||
{
|
||||
Log.outError(LogFilter.Sql, "CreatureTemplate (Entry: {0}) has UNIT_NPC_FLAG_BATTLEMASTER but no data in `battlemaster_entry` table. Removing flag!", creature.Value.Entry);
|
||||
templates[creature.Key].Npcflag &= ~NPCFlags.BattleMaster;
|
||||
templates[creature.Key].Npcflag &= ~(uint)NPCFlags.BattleMaster;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,9 +57,9 @@ namespace Game.BattleGrounds
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void BuildPvPLogPlayerDataPacket(out PVPLogData.PlayerData playerData)
|
||||
public virtual void BuildPvPLogPlayerDataPacket(out PVPLogData.PVPMatchPlayerStatistics playerData)
|
||||
{
|
||||
playerData = new PVPLogData.PlayerData();
|
||||
playerData = new PVPLogData.PVPMatchPlayerStatistics();
|
||||
playerData.PlayerGUID = PlayerGuid;
|
||||
playerData.Kills = KillingBlows;
|
||||
playerData.Faction = (byte)TeamId;
|
||||
|
||||
@@ -833,7 +833,7 @@ namespace Game.BattleGrounds.Zones
|
||||
}
|
||||
}
|
||||
|
||||
public override void BuildPvPLogPlayerDataPacket(out PVPLogData.PlayerData playerData)
|
||||
public override void BuildPvPLogPlayerDataPacket(out PVPLogData.PVPMatchPlayerStatistics playerData)
|
||||
{
|
||||
base.BuildPvPLogPlayerDataPacket(out playerData);
|
||||
|
||||
|
||||
@@ -999,7 +999,7 @@ namespace Game.BattleGrounds.Zones
|
||||
}
|
||||
}
|
||||
|
||||
public override void BuildPvPLogPlayerDataPacket(out PVPLogData.PlayerData playerData)
|
||||
public override void BuildPvPLogPlayerDataPacket(out PVPLogData.PVPMatchPlayerStatistics playerData)
|
||||
{
|
||||
base.BuildPvPLogPlayerDataPacket(out playerData);
|
||||
|
||||
|
||||
@@ -689,9 +689,9 @@ namespace Game.BattleGrounds.Zones
|
||||
if (dem)
|
||||
{
|
||||
if (start)
|
||||
dem.SetFlag(UnitFields.Flags, UnitFlags.NonAttackable | UnitFlags.NotSelectable);
|
||||
dem.AddUnitFlag(UnitFlags.NonAttackable | UnitFlags.NotSelectable);
|
||||
else
|
||||
dem.RemoveFlag(UnitFields.Flags, UnitFlags.NonAttackable | UnitFlags.NotSelectable);
|
||||
dem.RemoveUnitFlag(UnitFlags.NonAttackable | UnitFlags.NotSelectable);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -768,9 +768,9 @@ namespace Game.BattleGrounds.Zones
|
||||
if (go)
|
||||
{
|
||||
if (CanInteractWithObject(objectId))
|
||||
go.RemoveFlag(GameObjectFields.Flags, GameObjectFlags.NotSelectable);
|
||||
go.RemoveFlag(GameObjectFlags.NotSelectable);
|
||||
else
|
||||
go.SetFlag(GameObjectFields.Flags, GameObjectFlags.NotSelectable);
|
||||
go.AddFlag(GameObjectFlags.NotSelectable);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1153,7 +1153,7 @@ namespace Game.BattleGrounds.Zones
|
||||
}
|
||||
}
|
||||
|
||||
public override void BuildPvPLogPlayerDataPacket(out PVPLogData.PlayerData playerData)
|
||||
public override void BuildPvPLogPlayerDataPacket(out PVPLogData.PVPMatchPlayerStatistics playerData)
|
||||
{
|
||||
base.BuildPvPLogPlayerDataPacket(out playerData);
|
||||
|
||||
|
||||
@@ -966,7 +966,7 @@ namespace Game.BattleGrounds.Zones
|
||||
}
|
||||
}
|
||||
|
||||
public override void BuildPvPLogPlayerDataPacket(out PVPLogData.PlayerData playerData)
|
||||
public override void BuildPvPLogPlayerDataPacket(out PVPLogData.PVPMatchPlayerStatistics playerData)
|
||||
{
|
||||
base.BuildPvPLogPlayerDataPacket(out playerData);
|
||||
|
||||
|
||||
@@ -406,7 +406,7 @@ namespace Game.BattlePets
|
||||
return;
|
||||
|
||||
// TODO: set proper CreatureID for spell DEFAULT_SUMMON_BATTLE_PET_SPELL (default EffectMiscValueA is 40721 - Murkimus the Gladiator)
|
||||
_owner.GetPlayer().SetGuidValue(ActivePlayerFields.SummonedBattlePetId, guid);
|
||||
_owner.GetPlayer().SetSummonedBattlePetGUID(guid);
|
||||
_owner.GetPlayer().CastSpell(_owner.GetPlayer(), speciesEntry.SummonSpellID != 0 ? speciesEntry.SummonSpellID : SharedConst.DefaultSummonBattlePetSpell);
|
||||
|
||||
// TODO: set pet level, quality... update fields
|
||||
@@ -416,10 +416,10 @@ namespace Game.BattlePets
|
||||
{
|
||||
Player ownerPlayer = _owner.GetPlayer();
|
||||
Creature pet = ObjectAccessor.GetCreatureOrPetOrVehicle(ownerPlayer, ownerPlayer.GetCritterGUID());
|
||||
if (pet && ownerPlayer.GetGuidValue(ActivePlayerFields.SummonedBattlePetId) == pet.GetGuidValue(UnitFields.BattlePetCompanionGuid))
|
||||
if (pet && ownerPlayer.m_activePlayerData.SummonedBattlePetGUID == pet.GetBattlePetCompanionGUID())
|
||||
{
|
||||
pet.DespawnOrUnsummon();
|
||||
ownerPlayer.SetGuidValue(ActivePlayerFields.SummonedBattlePetId, ObjectGuid.Empty);
|
||||
ownerPlayer.SetSummonedBattlePetGUID(ObjectGuid.Empty);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -546,7 +546,7 @@ namespace Game
|
||||
Player invitee = Global.ObjAccessor.FindPlayer(inviteeGuid);
|
||||
|
||||
uint inviteeLevel = invitee ? invitee.getLevel() : Player.GetLevelFromDB(inviteeGuid);
|
||||
uint inviteeGuildId = invitee ? invitee.GetGuildId() : Player.GetGuildIdFromDB(inviteeGuid);
|
||||
ulong inviteeGuildId = invitee ? invitee.GetGuildId() : Player.GetGuildIdFromDB(inviteeGuid);
|
||||
|
||||
CalendarEventInviteInfo inviteInfo = new CalendarEventInviteInfo();
|
||||
inviteInfo.Guid = inviteeGuid;
|
||||
|
||||
@@ -65,9 +65,9 @@ namespace Game.Chat
|
||||
LocaleConstant localeIdx = Global.WorldMgr.GetAvailableDbcLocale(locale);
|
||||
|
||||
ChannelNotifyJoined notify = new ChannelNotifyJoined();
|
||||
//notify->ChannelWelcomeMsg = "";
|
||||
//notify.ChannelWelcomeMsg = "";
|
||||
notify.ChatChannelID = (int)_source.GetChannelId();
|
||||
//notify->InstanceID = 0;
|
||||
//notify.InstanceID = 0;
|
||||
notify.ChannelFlags = _source.GetFlags();
|
||||
notify.Channel = _source.GetName(localeIdx);
|
||||
return notify;
|
||||
|
||||
@@ -750,7 +750,7 @@ namespace Game.Chat
|
||||
var ipBytes = System.Net.IPAddress.Parse(handler.GetSession().GetRemoteAddress()).GetAddressBytes();
|
||||
Array.Reverse(ipBytes);
|
||||
|
||||
PreparedStatement stmt = DB.Login.GetPreparedStatement(LoginStatements.SEL_LOGON_COUNTRY);
|
||||
/*PreparedStatement stmt = DB.Login.GetPreparedStatement(LoginStatements.SEL_LOGON_COUNTRY);
|
||||
stmt.AddValue(0, BitConverter.ToUInt32(ipBytes, 0));
|
||||
|
||||
SQLResult result = DB.Login.Query(stmt);
|
||||
@@ -767,7 +767,7 @@ namespace Game.Chat
|
||||
{
|
||||
handler.SendSysMessage("[IP2NATION] Table empty");
|
||||
Log.outDebug(LogFilter.Server, "[IP2NATION] Table empty");
|
||||
}
|
||||
}*/
|
||||
}
|
||||
else if (param == "off")
|
||||
{
|
||||
|
||||
@@ -285,7 +285,8 @@ namespace Game.Chat.Commands
|
||||
}
|
||||
|
||||
[CommandGroup("lock", RBACPermissions.CommandBnetAccount, true)]
|
||||
class LockCommands {
|
||||
class LockCommands
|
||||
{
|
||||
[Command("country", RBACPermissions.CommandBnetAccountLockCountry, true)]
|
||||
static bool HandleLockCountryCommand(StringArguments args, CommandHandler handler)
|
||||
{
|
||||
@@ -300,7 +301,7 @@ namespace Game.Chat.Commands
|
||||
{
|
||||
if (param == "on")
|
||||
{
|
||||
PreparedStatement stmt = DB.Login.GetPreparedStatement(LoginStatements.SEL_LOGON_COUNTRY);
|
||||
/*PreparedStatement stmt = DB.Login.GetPreparedStatement(LoginStatements.SEL_LOGON_COUNTRY);
|
||||
var ipBytes = System.Net.IPAddress.Parse(handler.GetSession().GetRemoteAddress()).GetAddressBytes();
|
||||
Array.Reverse(ipBytes);
|
||||
stmt.AddValue(0, BitConverter.ToUInt32(ipBytes, 0));
|
||||
@@ -318,7 +319,7 @@ namespace Game.Chat.Commands
|
||||
{
|
||||
handler.SendSysMessage("[IP2NATION] Table empty");
|
||||
Log.outDebug(LogFilter.Server, "[IP2NATION] Table empty");
|
||||
}
|
||||
}*/
|
||||
}
|
||||
else if (param == "off")
|
||||
{
|
||||
|
||||
@@ -52,7 +52,7 @@ namespace Game.Chat
|
||||
if (string.IsNullOrEmpty(name))
|
||||
continue;
|
||||
|
||||
string activeStr = target.GetUInt32Value(PlayerFields.ChosenTitle) == titleInfo.MaskID
|
||||
string activeStr = target.m_playerData.PlayerTitle == titleInfo.MaskID
|
||||
? handler.GetCypherString(CypherStrings.Active) : "";
|
||||
|
||||
string titleNameStr = string.Format(name.ConvertFormatSyntax(), targetName);
|
||||
@@ -600,7 +600,7 @@ namespace Game.Chat
|
||||
if (!int.TryParse(daysStr, out keepDays) || keepDays < 0)
|
||||
return false;
|
||||
}
|
||||
// config option value 0 -> disabled and can't be used
|
||||
// config option value 0 . disabled and can't be used
|
||||
else if (keepDays <= 0)
|
||||
return false;
|
||||
|
||||
@@ -777,7 +777,7 @@ namespace Game.Chat
|
||||
{
|
||||
player.GiveLevel((uint)newLevel);
|
||||
player.InitTalentForLevel();
|
||||
player.SetUInt32Value(ActivePlayerFields.Xp, 0);
|
||||
player.SetXP(0);
|
||||
|
||||
if (handler.needReportToTarget(player))
|
||||
{
|
||||
|
||||
@@ -245,9 +245,9 @@ namespace Game.Chat.Commands
|
||||
for (ushort i = 0; i < PlayerConst.ExploredZonesSize; ++i)
|
||||
{
|
||||
if (flag != 0)
|
||||
handler.GetSession().GetPlayer().SetFlag(ActivePlayerFields.ExploredZones + i, 0xFFFFFFFF);
|
||||
handler.GetSession().GetPlayer().AddExploredZones(i, 0xFFFFFFFFFFFFFFFF);
|
||||
else
|
||||
handler.GetSession().GetPlayer().SetFlag(ActivePlayerFields.ExploredZones + i, 0);
|
||||
handler.GetSession().GetPlayer().RemoveExploredZones(i, 0xFFFFFFFFFFFFFFFF);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
@@ -435,78 +435,6 @@ namespace Game.Chat
|
||||
return true;
|
||||
}
|
||||
|
||||
[Command("getitemvalue", RBACPermissions.CommandDebugGetitemvalue)]
|
||||
static bool HandleDebugGetItemValueCommand(StringArguments args, CommandHandler handler)
|
||||
{
|
||||
if (args.Empty())
|
||||
return false;
|
||||
|
||||
if (!ulong.TryParse(args.NextString(), out ulong guid))
|
||||
return false;
|
||||
|
||||
if (!uint.TryParse(args.NextString(), out uint index))
|
||||
return false;
|
||||
|
||||
Item item = handler.GetSession().GetPlayer().GetItemByGuid(ObjectGuid.Create(HighGuid.Item, guid));
|
||||
if (!item)
|
||||
return false;
|
||||
|
||||
if (index >= item.valuesCount)
|
||||
return false;
|
||||
|
||||
uint value = item.GetUInt32Value(index);
|
||||
|
||||
handler.SendSysMessage("Item {0}: value at {1} is {2}", guid, index, value);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
[Command("getvalue", RBACPermissions.CommandDebugGetvalue)]
|
||||
static bool HandleDebugGetValueCommand(StringArguments args, CommandHandler handler)
|
||||
{
|
||||
if (args.Empty())
|
||||
return false;
|
||||
|
||||
string fieldStr = args.NextString();
|
||||
string valueStr = args.NextString();
|
||||
|
||||
if (string.IsNullOrEmpty(fieldStr))
|
||||
return false;
|
||||
|
||||
Unit target = handler.getSelectedUnit();
|
||||
if (!target)
|
||||
{
|
||||
handler.SendSysMessage(CypherStrings.SelectCharOrCreature);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!uint.TryParse(fieldStr, out uint field))
|
||||
return false;
|
||||
|
||||
ObjectGuid guid = target.GetGUID();
|
||||
if (field >= target.valuesCount)
|
||||
{
|
||||
handler.SendSysMessage(CypherStrings.TooBigIndex, field, guid.ToString(), target.valuesCount);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!bool.TryParse(valueStr, out bool isInt32))
|
||||
isInt32 = true;
|
||||
|
||||
if (isInt32)
|
||||
{
|
||||
uint value = target.GetUInt32Value(field);
|
||||
handler.SendSysMessage(CypherStrings.GetUintField, guid.ToString(), field, value);
|
||||
}
|
||||
else
|
||||
{
|
||||
float value = target.GetFloatValue(field);
|
||||
handler.SendSysMessage(CypherStrings.GetFloatField, guid.ToString(), field, value);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
[Command("hostil", RBACPermissions.CommandDebugHostil)]
|
||||
static bool HandleDebugHostileRefListCommand(StringArguments args, CommandHandler handler)
|
||||
{
|
||||
@@ -570,31 +498,6 @@ namespace Game.Chat
|
||||
return true;
|
||||
}
|
||||
|
||||
[Command("Mod32Value", RBACPermissions.CommandDebugMod32value)]
|
||||
static bool HandleDebugMod32ValueCommand(StringArguments args, CommandHandler handler)
|
||||
{
|
||||
if (args.Empty())
|
||||
return false;
|
||||
|
||||
uint field = args.NextUInt32();
|
||||
int value = args.NextInt32();
|
||||
|
||||
if (field >= handler.GetSession().GetPlayer().valuesCount)
|
||||
{
|
||||
handler.SendSysMessage(CypherStrings.TooBigIndex, field, handler.GetSession().GetPlayer().GetGUID().ToString(), handler.GetSession().GetPlayer().valuesCount);
|
||||
return false;
|
||||
}
|
||||
|
||||
uint currentValue = handler.GetSession().GetPlayer().GetUInt32Value(field);
|
||||
|
||||
currentValue += (uint)value;
|
||||
handler.GetSession().GetPlayer().SetUInt32Value(field, currentValue);
|
||||
|
||||
handler.SendSysMessage(CypherStrings.Change32bitField, field, currentValue);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
[Command("moveflags", RBACPermissions.CommandDebugMoveflags)]
|
||||
static bool HandleDebugMoveflagsCommand(StringArguments args, CommandHandler handler)
|
||||
{
|
||||
@@ -794,103 +697,6 @@ namespace Game.Chat
|
||||
return true;
|
||||
}
|
||||
|
||||
[Command("setbit", RBACPermissions.CommandDebugSetbit)]
|
||||
static bool HandleDebugSet32BitCommand(StringArguments args, CommandHandler handler)
|
||||
{
|
||||
if (args.Empty())
|
||||
return false;
|
||||
|
||||
WorldObject target = handler.GetSelectedObject();
|
||||
if (!target)
|
||||
{
|
||||
handler.SendSysMessage(CypherStrings.SelectCharOrCreature);
|
||||
return false;
|
||||
}
|
||||
|
||||
uint field = args.NextUInt32();
|
||||
uint val = args.NextUInt32();
|
||||
if (val > 32) //uint = 32 bits
|
||||
return false;
|
||||
|
||||
uint value = (uint)(val != 0 ? 1 << ((int)val - 1) : 0);
|
||||
target.SetUInt32Value(field, value);
|
||||
|
||||
handler.SendSysMessage(CypherStrings.Set32bitField, field, value);
|
||||
return true;
|
||||
}
|
||||
|
||||
[Command("setitemvalue", RBACPermissions.CommandDebugSetitemvalue)]
|
||||
static bool HandleDebugSetItemValueCommand(StringArguments args, CommandHandler handler)
|
||||
{
|
||||
if (args.Empty())
|
||||
return false;
|
||||
|
||||
if (!ulong.TryParse(args.NextString(), out ulong guid))
|
||||
return false;
|
||||
|
||||
if (!uint.TryParse(args.NextString(), out uint index))
|
||||
return false;
|
||||
|
||||
if (!uint.TryParse(args.NextString(), out uint value))
|
||||
return false;
|
||||
|
||||
Item item = handler.GetSession().GetPlayer().GetItemByGuid(ObjectGuid.Create(HighGuid.Item, guid));
|
||||
if (!item)
|
||||
return false;
|
||||
|
||||
if (index >= item.valuesCount)
|
||||
return false;
|
||||
|
||||
item.SetUInt32Value(index, value);
|
||||
return true;
|
||||
}
|
||||
|
||||
[Command("setvalue", RBACPermissions.CommandDebugSetvalue)]
|
||||
static bool HandleDebugSetValueCommand(StringArguments args, CommandHandler handler)
|
||||
{
|
||||
if (args.Empty())
|
||||
return false;
|
||||
|
||||
WorldObject target = handler.GetSelectedObject();
|
||||
if (!target)
|
||||
{
|
||||
handler.SendSysMessage(CypherStrings.SelectCharOrCreature);
|
||||
return false;
|
||||
}
|
||||
|
||||
ObjectGuid guid = target.GetGUID();
|
||||
|
||||
uint field = args.NextUInt32();
|
||||
if (field >= target.valuesCount)
|
||||
{
|
||||
handler.SendSysMessage(CypherStrings.TooBigIndex, field, guid.ToString(), target.valuesCount);
|
||||
return false;
|
||||
}
|
||||
|
||||
string valueStr = args.NextString();
|
||||
if (!bool.TryParse(args.NextString(), out bool isInt32))
|
||||
isInt32 = true;
|
||||
|
||||
if (isInt32)
|
||||
{
|
||||
if (!uint.TryParse(valueStr, out uint value))
|
||||
return false;
|
||||
|
||||
target.SetUInt32Value(field, value);
|
||||
handler.SendSysMessage(CypherStrings.SetUintField, guid.ToString(), field, value);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!float.TryParse(valueStr, out float value))
|
||||
return false;
|
||||
|
||||
target.SetFloatValue(field, value);
|
||||
handler.SendSysMessage(CypherStrings.SetFloatField, guid.ToString(), field, value);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
[Command("setvid", RBACPermissions.CommandDebugSetvid)]
|
||||
static bool HandleDebugSetVehicleIdCommand(StringArguments args, CommandHandler handler)
|
||||
{
|
||||
@@ -992,49 +798,6 @@ namespace Game.Chat
|
||||
return true;
|
||||
}
|
||||
|
||||
[Command("update", RBACPermissions.CommandDebugUpdate)]
|
||||
static bool HandleDebugUpdateCommand(StringArguments args, CommandHandler handler)
|
||||
{
|
||||
if (args.Empty())
|
||||
return false;
|
||||
|
||||
Unit unit = handler.getSelectedUnit();
|
||||
if (!unit)
|
||||
{
|
||||
handler.SendSysMessage(CypherStrings.SelectCharOrCreature);
|
||||
return false;
|
||||
}
|
||||
|
||||
uint updateIndex = args.NextUInt32();
|
||||
|
||||
//check updateIndex
|
||||
if (unit.IsTypeId(TypeId.Player))
|
||||
{
|
||||
if (updateIndex >= (int)PlayerFields.End)
|
||||
return true;
|
||||
}
|
||||
else if (updateIndex >= (int)UnitFields.End)
|
||||
return true;
|
||||
|
||||
uint value;
|
||||
string valueStr = args.NextString();
|
||||
if (string.IsNullOrEmpty(valueStr))
|
||||
{
|
||||
value = unit.GetUInt32Value(updateIndex);
|
||||
|
||||
handler.SendSysMessage(CypherStrings.Update, unit.GetGUID().ToString(), updateIndex, value);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!uint.TryParse(valueStr, out value))
|
||||
return false;
|
||||
|
||||
handler.SendSysMessage(CypherStrings.UpdateChange, unit.GetGUID().ToString(), updateIndex, value);
|
||||
unit.SetUInt32Value(updateIndex, value);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
[Command("uws", RBACPermissions.CommandDebugUws)]
|
||||
static bool HandleDebugUpdateWorldStateCommand(StringArguments args, CommandHandler handler)
|
||||
{
|
||||
|
||||
@@ -625,19 +625,34 @@ namespace Game.Chat
|
||||
if (string.IsNullOrEmpty(state))
|
||||
return false;
|
||||
|
||||
if (!int.TryParse(state, out int objectState))
|
||||
if (!uint.TryParse(state, out uint objectState))
|
||||
return false;
|
||||
|
||||
if (objectType < 4)
|
||||
obj.SetByteValue(GameObjectFields.Bytes1, (byte)objectType, (byte)objectState);
|
||||
else if (objectType == 4)
|
||||
obj.SendCustomAnim((uint)objectState);
|
||||
else if (objectType == 5)
|
||||
switch (objectType)
|
||||
{
|
||||
if (objectState < 0 || objectState > (uint)GameObjectDestructibleState.Rebuilding)
|
||||
return false;
|
||||
case 0:
|
||||
obj.SetGoState((GameObjectState)objectState);
|
||||
break;
|
||||
case 1:
|
||||
obj.SetGoType((GameObjectTypes)objectState);
|
||||
break;
|
||||
case 2:
|
||||
obj.SetGoArtKit((byte)objectState);
|
||||
break;
|
||||
case 3:
|
||||
obj.SetGoAnimProgress(objectState);
|
||||
break;
|
||||
case 4:
|
||||
obj.SendCustomAnim(objectState);
|
||||
break;
|
||||
case 5:
|
||||
if (objectState < 0 || objectState > (uint)GameObjectDestructibleState.Rebuilding)
|
||||
return false;
|
||||
|
||||
obj.SetDestructibleState((GameObjectDestructibleState)objectState);
|
||||
obj.SetDestructibleState((GameObjectDestructibleState)objectState);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
handler.SendSysMessage("Set gobject type {0} state {1}", objectType, objectState);
|
||||
|
||||
@@ -103,7 +103,7 @@ namespace Game.Chat
|
||||
if (!handler.extractPlayerTarget(args, out target, out targetGuid))
|
||||
return false;
|
||||
|
||||
uint guildId = target != null ? target.GetGuildId() : Player.GetGuildIdFromDB(targetGuid);
|
||||
ulong guildId = target != null ? target.GetGuildId() : Player.GetGuildIdFromDB(targetGuid);
|
||||
if (guildId == 0)
|
||||
return false;
|
||||
|
||||
|
||||
@@ -834,7 +834,7 @@ namespace Game.Chat
|
||||
|
||||
string knownStr = target && target.HasTitle(titleInfo) ? handler.GetCypherString(CypherStrings.Known) : "";
|
||||
|
||||
string activeStr = target && target.GetUInt32Value(PlayerFields.ChosenTitle) == titleInfo.MaskID
|
||||
string activeStr = target && target.m_playerData.PlayerTitle == titleInfo.MaskID
|
||||
? handler.GetCypherString(CypherStrings.Active) : "";
|
||||
|
||||
string titleNameStr = string.Format(name.ConvertFormatSyntax(), targetName);
|
||||
|
||||
@@ -345,7 +345,7 @@ namespace Game.Chat
|
||||
return false;
|
||||
}
|
||||
|
||||
Item item = playerTarget.StoreNewItem(dest, itemId, true, ItemEnchantment.GenerateItemRandomPropertyId(itemId), null, 0, bonusListIDs);
|
||||
Item item = playerTarget.StoreNewItem(dest, itemId, true, ItemEnchantmentManager.GenerateItemRandomBonusListId(itemId), null, 0, bonusListIDs);
|
||||
|
||||
// remove binding (let GM give it to another player later)
|
||||
if (player == playerTarget)
|
||||
@@ -420,7 +420,7 @@ namespace Game.Chat
|
||||
InventoryResult msg = playerTarget.CanStoreNewItem(ItemConst.NullBag, ItemConst.NullSlot, dest, template.Value.GetId(), 1);
|
||||
if (msg == InventoryResult.Ok)
|
||||
{
|
||||
Item item = playerTarget.StoreNewItem(dest, template.Value.GetId(), true, ItemRandomEnchantmentId.Empty, null, 0, bonusListIDs);
|
||||
Item item = playerTarget.StoreNewItem(dest, template.Value.GetId(), true, 0, null, 0, bonusListIDs);
|
||||
|
||||
// remove binding (let GM give it to another player later)
|
||||
if (player == playerTarget)
|
||||
@@ -451,7 +451,7 @@ namespace Game.Chat
|
||||
{
|
||||
if (args.Empty())
|
||||
{
|
||||
if (handler.GetSession().GetPlayer().HasFlag(PlayerFields.Flags, PlayerFlags.Developer))
|
||||
if (handler.GetSession().GetPlayer().HasPlayerFlag(PlayerFlags.Developer))
|
||||
handler.GetSession().SendNotification(CypherStrings.DevOn);
|
||||
else
|
||||
handler.GetSession().SendNotification(CypherStrings.DevOff);
|
||||
@@ -462,14 +462,14 @@ namespace Game.Chat
|
||||
|
||||
if (argstr == "on")
|
||||
{
|
||||
handler.GetSession().GetPlayer().SetFlag(PlayerFields.Flags, PlayerFlags.Developer);
|
||||
handler.GetSession().GetPlayer().HasPlayerFlag(PlayerFlags.Developer);
|
||||
handler.GetSession().SendNotification(CypherStrings.DevOn);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (argstr == "off")
|
||||
{
|
||||
handler.GetSession().GetPlayer().RemoveFlag(PlayerFields.Flags, PlayerFlags.Developer);
|
||||
handler.GetSession().GetPlayer().RemovePlayerFlag(PlayerFlags.Developer);
|
||||
handler.GetSession().SendNotification(CypherStrings.DevOff);
|
||||
return true;
|
||||
}
|
||||
@@ -1181,16 +1181,15 @@ namespace Game.Chat
|
||||
return false;
|
||||
}
|
||||
|
||||
int offset = area.AreaBit / 32;
|
||||
uint offset = (uint)area.AreaBit / 64;
|
||||
if (offset >= PlayerConst.ExploredZonesSize)
|
||||
{
|
||||
handler.SendSysMessage(CypherStrings.BadValue);
|
||||
return false;
|
||||
}
|
||||
|
||||
uint val = (1u << (area.AreaBit % 32));
|
||||
uint currFields = playerTarget.GetUInt32Value(ActivePlayerFields.ExploredZones + offset);
|
||||
playerTarget.SetUInt32Value(ActivePlayerFields.ExploredZones + offset, (currFields | val));
|
||||
ulong val = 1ul << (area.AreaBit % 64);
|
||||
playerTarget.AddExploredZones(offset, val);
|
||||
|
||||
handler.SendSysMessage(CypherStrings.ExploreArea);
|
||||
return true;
|
||||
@@ -1222,16 +1221,15 @@ namespace Game.Chat
|
||||
return false;
|
||||
}
|
||||
|
||||
int offset = area.AreaBit / 32;
|
||||
uint offset = (uint)area.AreaBit / 64;
|
||||
if (offset >= PlayerConst.ExploredZonesSize)
|
||||
{
|
||||
handler.SendSysMessage(CypherStrings.BadValue);
|
||||
return false;
|
||||
}
|
||||
|
||||
uint val = (1u << (area.AreaBit % 32));
|
||||
uint currFields = playerTarget.GetUInt32Value(ActivePlayerFields.ExploredZones + offset);
|
||||
playerTarget.SetUInt32Value(ActivePlayerFields.ExploredZones + offset, (currFields ^ val));
|
||||
uint val = (1u << (area.AreaBit % 64));
|
||||
playerTarget.RemoveExploredZones(offset, val);
|
||||
|
||||
handler.SendSysMessage(CypherStrings.UnexploreArea);
|
||||
return true;
|
||||
@@ -1404,7 +1402,7 @@ namespace Game.Chat
|
||||
mapId = target.GetMapId();
|
||||
areaId = target.GetAreaId();
|
||||
alive = target.IsAlive() ? handler.GetCypherString(CypherStrings.Yes) : handler.GetCypherString(CypherStrings.No);
|
||||
gender = (Gender)target.GetByteValue(PlayerFields.Bytes3, PlayerFieldOffsets.Bytes3OffsetGender);
|
||||
gender = (Gender)(byte)target.m_playerData.NativeSex;
|
||||
}
|
||||
// get additional information from DB
|
||||
else
|
||||
@@ -1996,7 +1994,7 @@ namespace Game.Chat
|
||||
}
|
||||
|
||||
go.ModifyHealth(-damage, player);
|
||||
handler.SendSysMessage(CypherStrings.GameobjectDamaged, go.GetName(), guidLow, -damage, go.m_goValue.Building.Health);
|
||||
handler.SendSysMessage(CypherStrings.GameobjectDamaged, go.GetName(), guidLow, -damage, go.GetGoValue().Building.Health);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
@@ -122,22 +122,22 @@ namespace Game.Chat
|
||||
|
||||
if (!uint.TryParse(pfactionid, out uint factionid))
|
||||
{
|
||||
uint _factionid = target.getFaction();
|
||||
uint _flag = target.GetUInt32Value(UnitFields.Flags);
|
||||
ulong _npcflag = target.GetUInt64Value(UnitFields.NpcFlags);
|
||||
uint _dyflag = target.GetUInt32Value(ObjectFields.DynamicFlags);
|
||||
uint _factionid = target.GetFaction();
|
||||
uint _flag = target.m_unitData.Flags;
|
||||
ulong _npcflag = (ulong)target.m_unitData.NpcFlags[0] << 32 | target.m_unitData.NpcFlags[1];
|
||||
uint _dyflag = target.m_objectData.DynamicFlags;
|
||||
handler.SendSysMessage(CypherStrings.CurrentFaction, target.GetGUID().ToString(), _factionid, _flag, _npcflag, _dyflag);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!uint.TryParse(args.NextString(), out uint flag))
|
||||
flag = target.GetUInt32Value(UnitFields.Flags);
|
||||
flag = target.m_unitData.Flags;
|
||||
|
||||
if (!ulong.TryParse(args.NextString(), out ulong npcflag))
|
||||
npcflag = target.GetUInt64Value(UnitFields.NpcFlags);
|
||||
npcflag = (ulong)target.m_unitData.NpcFlags[0] << 32 | target.m_unitData.NpcFlags[1];
|
||||
|
||||
if (!uint.TryParse(args.NextString(), out uint dyflag))
|
||||
dyflag = target.GetUInt32Value(ObjectFields.DynamicFlags);
|
||||
dyflag = target.m_objectData.DynamicFlags;
|
||||
|
||||
if (!CliDB.FactionTemplateStorage.ContainsKey(factionid))
|
||||
{
|
||||
@@ -148,9 +148,10 @@ namespace Game.Chat
|
||||
handler.SendSysMessage(CypherStrings.YouChangeFaction, target.GetGUID().ToString(), factionid, flag, npcflag, dyflag);
|
||||
|
||||
target.SetFaction(factionid);
|
||||
target.SetUInt32Value(UnitFields.Flags, flag);
|
||||
target.SetUInt64Value(UnitFields.NpcFlags, npcflag);
|
||||
target.SetUInt32Value(ObjectFields.DynamicFlags, dyflag);
|
||||
target.SetUnitFlags((UnitFlags)flag);
|
||||
target.SetNpcFlags((NPCFlags)(npcflag & 0xFFFFFFFF));
|
||||
target.SetNpcFlags2((NPCFlags2)(npcflag >> 32));
|
||||
target.SetDynamicFlags((UnitDynFlags)dyflag);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -217,7 +218,7 @@ namespace Game.Chat
|
||||
NotifyModification(handler, target, CypherStrings.YouChangeSize, CypherStrings.YoursSizeChanged, Scale);
|
||||
Creature creatureTarget = target.ToCreature();
|
||||
if (creatureTarget)
|
||||
creatureTarget.SetFloatValue(UnitFields.DisplayScale, Scale);
|
||||
creatureTarget.SetDisplayId(creatureTarget.GetDisplayId(), Scale);
|
||||
else
|
||||
target.SetObjectScale(Scale);
|
||||
return true;
|
||||
@@ -322,51 +323,6 @@ namespace Game.Chat
|
||||
return true;
|
||||
}
|
||||
|
||||
[Command("bit", RBACPermissions.CommandModifyBit)]
|
||||
static bool HandleModifyBitCommand(StringArguments args, CommandHandler handler)
|
||||
{
|
||||
if (args.Empty())
|
||||
return false;
|
||||
|
||||
Unit target = handler.getSelectedUnit();
|
||||
if (!target)
|
||||
{
|
||||
handler.SendSysMessage(CypherStrings.NoCharSelected);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// check online security
|
||||
if (target.IsTypeId(TypeId.Player) && handler.HasLowerSecurity(target.ToPlayer(), ObjectGuid.Empty))
|
||||
return false;
|
||||
|
||||
ushort field = args.NextUInt16();
|
||||
int bit = args.NextInt32();
|
||||
|
||||
if (field < (int)ObjectFields.End || field >= target.valuesCount)
|
||||
{
|
||||
handler.SendSysMessage(CypherStrings.BadValue);
|
||||
return false;
|
||||
}
|
||||
if (bit < 1 || bit > 32)
|
||||
{
|
||||
handler.SendSysMessage(CypherStrings.BadValue);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (target.HasFlag(field, (1 << (bit - 1))))
|
||||
{
|
||||
target.RemoveFlag(field, (1 << (bit - 1)));
|
||||
handler.SendSysMessage(CypherStrings.RemoveBit, bit, field);
|
||||
}
|
||||
else
|
||||
{
|
||||
target.SetFlag(field, (1 << (bit - 1)));
|
||||
handler.SendSysMessage(CypherStrings.SetBit, bit, field);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
[Command("honor", RBACPermissions.CommandModifyHonor)]
|
||||
static bool HandleModifyHonorCommand(StringArguments args, CommandHandler handler)
|
||||
{
|
||||
@@ -591,7 +547,7 @@ namespace Game.Chat
|
||||
return false;
|
||||
|
||||
uint anim_id = args.NextUInt32();
|
||||
handler.GetSession().GetPlayer().SetUInt32Value(UnitFields.NpcEmotestate, anim_id);
|
||||
handler.GetSession().GetPlayer().SetEmoteState((Emote)anim_id);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -637,8 +593,8 @@ namespace Game.Chat
|
||||
}
|
||||
|
||||
// Set gender
|
||||
target.SetByteValue(UnitFields.Bytes0, 3, (byte)gender);
|
||||
target.SetByteValue(PlayerFields.Bytes3, PlayerFieldOffsets.Bytes3OffsetGender, (byte)gender);
|
||||
target.SetGender(gender);
|
||||
target.SetNativeSex(gender);
|
||||
|
||||
// Change display ID
|
||||
target.InitDisplayIds();
|
||||
|
||||
@@ -44,8 +44,8 @@ namespace Game.Chat
|
||||
|
||||
CreatureTemplate cInfo = target.GetCreatureTemplate();
|
||||
|
||||
uint faction = target.getFaction();
|
||||
ulong npcflags = target.GetUInt64Value(UnitFields.NpcFlags);
|
||||
uint faction = target.GetFaction();
|
||||
ulong npcflags = (ulong)target.m_unitData.NpcFlags[0] << 32 | target.m_unitData.NpcFlags[1];
|
||||
uint mechanicImmuneMask = cInfo.MechanicImmuneMask;
|
||||
uint displayid = target.GetDisplayId();
|
||||
uint nativeid = target.GetNativeDisplayId();
|
||||
@@ -63,22 +63,22 @@ namespace Game.Chat
|
||||
handler.SendSysMessage(CypherStrings.NpcinfoHealth, target.GetCreateHealth(), target.GetMaxHealth(), target.GetHealth());
|
||||
handler.SendSysMessage(CypherStrings.NpcinfoInhabitType, cInfo.InhabitType);
|
||||
|
||||
handler.SendSysMessage(CypherStrings.NpcinfoUnitFieldFlags, target.GetUInt32Value(UnitFields.Flags));
|
||||
foreach (uint value in Enum.GetValues(typeof(UnitFlags)))
|
||||
if (target.GetUInt32Value(UnitFields.Flags).HasAnyFlag(value))
|
||||
handler.SendSysMessage(CypherStrings.NpcinfoUnitFieldFlags, target.m_unitData.Flags);
|
||||
foreach (UnitFlags value in Enum.GetValues(typeof(UnitFlags)))
|
||||
if (target.HasUnitFlag(value))
|
||||
handler.SendSysMessage("{0} (0x{1:X})", (UnitFlags)value, value);
|
||||
|
||||
handler.SendSysMessage(CypherStrings.NpcinfoUnitFieldFlags2, target.GetUInt32Value(UnitFields.Flags2));
|
||||
foreach (uint value in Enum.GetValues(typeof(UnitFlags2)))
|
||||
if (target.GetUInt32Value(UnitFields.Flags2).HasAnyFlag(value))
|
||||
handler.SendSysMessage(CypherStrings.NpcinfoUnitFieldFlags2, target.m_unitData.Flags2);
|
||||
foreach (UnitFlags2 value in Enum.GetValues(typeof(UnitFlags2)))
|
||||
if (target.HasUnitFlag2(value))
|
||||
handler.SendSysMessage("{0} (0x{1:X})", (UnitFlags2)value, value);
|
||||
|
||||
handler.SendSysMessage(CypherStrings.NpcinfoUnitFieldFlags3, target.GetUInt32Value(UnitFields.Flags3));
|
||||
foreach (uint value in Enum.GetValues(typeof(UnitFlags3)))
|
||||
if (target.GetUInt32Value(UnitFields.Flags3).HasAnyFlag(value))
|
||||
handler.SendSysMessage(CypherStrings.NpcinfoUnitFieldFlags3, target.m_unitData.Flags3);
|
||||
foreach (UnitFlags3 value in Enum.GetValues(typeof(UnitFlags3)))
|
||||
if (target.HasUnitFlag3(value))
|
||||
handler.SendSysMessage("{0} (0x{1:X})", (UnitFlags3)value, value);
|
||||
|
||||
handler.SendSysMessage(CypherStrings.NpcinfoDynamicFlags, target.GetUInt32Value(ObjectFields.DynamicFlags));
|
||||
handler.SendSysMessage(CypherStrings.NpcinfoDynamicFlags, target.GetDynamicFlags());
|
||||
handler.SendSysMessage(CypherStrings.CommandRawpawntimes, defRespawnDelayStr, curRespawnDelayStr);
|
||||
handler.SendSysMessage(CypherStrings.NpcinfoLoot, cInfo.LootId, cInfo.PickPocketId, cInfo.SkinLootId);
|
||||
handler.SendSysMessage(CypherStrings.NpcinfoDungeonId, target.GetInstanceId());
|
||||
@@ -243,7 +243,7 @@ namespace Game.Chat
|
||||
return false;
|
||||
}
|
||||
|
||||
target.SetUInt32Value(UnitFields.NpcEmotestate, emote);
|
||||
target.SetEmoteState((Emote)emote);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -402,13 +402,13 @@ namespace Game.Chat
|
||||
uint level = (creatureTarget.getLevel() < (player.getLevel() - 5)) ? (player.getLevel() - 5) : creatureTarget.getLevel();
|
||||
|
||||
// prepare visual effect for levelup
|
||||
pet.SetUInt32Value(UnitFields.Level, level - 1);
|
||||
pet.SetLevel(level - 1);
|
||||
|
||||
// add to world
|
||||
pet.GetMap().AddToMap(pet.ToCreature());
|
||||
|
||||
// visual effect for levelup
|
||||
pet.SetUInt32Value(UnitFields.Level, level);
|
||||
pet.SetLevel(level);
|
||||
|
||||
// caster have pet now
|
||||
player.SetMinion(pet, true);
|
||||
@@ -685,7 +685,8 @@ namespace Game.Chat
|
||||
return false;
|
||||
}
|
||||
|
||||
creature.SetUInt64Value(UnitFields.NpcFlags, npcFlags);
|
||||
creature.SetNpcFlags((NPCFlags)(npcFlags & 0xFFFFFFFF));
|
||||
creature.SetNpcFlags2((NPCFlags2)(npcFlags >> 32));
|
||||
|
||||
PreparedStatement stmt = DB.World.GetPreparedStatement(WorldStatements.UPD_CREATURE_NPCFLAG);
|
||||
stmt.AddValue(0, npcFlags);
|
||||
|
||||
@@ -63,8 +63,8 @@ namespace Game.Chat
|
||||
creatureTarget.RemoveCorpse();
|
||||
creatureTarget.SetHealth(0); // just for nice GM-mode view
|
||||
|
||||
pet.SetGuidValue(UnitFields.CreatedBy, player.GetGUID());
|
||||
pet.SetUInt32Value(UnitFields.FactionTemplate, player.getFaction());
|
||||
pet.SetCreatorGUID(player.GetGUID());
|
||||
pet.SetFaction(player.GetFaction());
|
||||
|
||||
if (!pet.InitStatsForLevel(creatureTarget.getLevel()))
|
||||
{
|
||||
@@ -74,7 +74,7 @@ namespace Game.Chat
|
||||
}
|
||||
|
||||
// prepare visual effect for levelup
|
||||
pet.SetUInt32Value(UnitFields.Level, creatureTarget.getLevel() - 1);
|
||||
pet.SetLevel(creatureTarget.getLevel() - 1);
|
||||
|
||||
pet.GetCharmInfo().SetPetNumber(Global.ObjectMgr.GeneratePetNumber(), true);
|
||||
// this enables pet details window (Shift+P)
|
||||
@@ -84,7 +84,7 @@ namespace Game.Chat
|
||||
pet.GetMap().AddToMap(pet.ToCreature());
|
||||
|
||||
// visual effect for levelup
|
||||
pet.SetUInt32Value(UnitFields.Level, creatureTarget.getLevel());
|
||||
pet.SetLevel(creatureTarget.getLevel());
|
||||
|
||||
player.SetMinion(pet, true);
|
||||
pet.SavePetToDB(PetSaveMode.AsCurrent);
|
||||
|
||||
@@ -395,12 +395,12 @@ namespace Game.Chat
|
||||
return true;
|
||||
}
|
||||
|
||||
[Command("item_enchantment_template", RBACPermissions.CommandReloadItemEnchantmentTemplate, true)]
|
||||
static bool HandleReloadItemEnchantementsCommand(StringArguments args, CommandHandler handler)
|
||||
[Command("item_random_bonus_list_template", RBACPermissions.CommandReloadItemRandomBonusListTemplate, true)]
|
||||
static bool HandleReloadItemRandomBonusListTemplatesCommand(StringArguments args, CommandHandler handler)
|
||||
{
|
||||
Log.outInfo(LogFilter.Server, "Re-Loading Item Random Enchantments Table...");
|
||||
ItemEnchantment.LoadRandomEnchantmentsTable();
|
||||
handler.SendGlobalGMSysMessage("DB table `item_enchantment_template` reloaded.");
|
||||
Log.outInfo(LogFilter.Server, "Re-Loading Random item bonus list definitions...");
|
||||
ItemEnchantmentManager.LoadItemRandomBonusListTemplates();
|
||||
handler.SendGlobalGMSysMessage("DB table `item_random_bonus_list_template` reloaded.");
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1015,7 +1015,7 @@ namespace Game.Chat
|
||||
static bool HandleReloadAllItemCommand(StringArguments args, CommandHandler handler)
|
||||
{
|
||||
HandleReloadPageTextsCommand(null, handler);
|
||||
HandleReloadItemEnchantementsCommand(null, handler);
|
||||
HandleReloadItemRandomBonusListTemplatesCommand(null, handler);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -51,8 +51,7 @@ namespace Game.Chat
|
||||
if (!handler.extractPlayerTarget(args, out target))
|
||||
return false;
|
||||
|
||||
target.SetUInt32Value(ActivePlayerFields.Kills, 0);
|
||||
target.SetUInt32Value(ActivePlayerFields.LifetimeHonorableKills, 0);
|
||||
target.ResetHonorStats();
|
||||
target.UpdateCriteria(CriteriaTypes.EarnHonorableKill);
|
||||
|
||||
return true;
|
||||
@@ -74,18 +73,18 @@ namespace Game.Chat
|
||||
player.SetShapeshiftForm(ShapeShiftForm.None);
|
||||
|
||||
player.setFactionForRace(player.GetRace());
|
||||
player.SetUInt32Value(UnitFields.DisplayPower, (uint)powerType);
|
||||
player.SetPowerType(powerType);
|
||||
|
||||
// reset only if player not in some form;
|
||||
if (player.GetShapeshiftForm() == ShapeShiftForm.None)
|
||||
player.InitDisplayIds();
|
||||
|
||||
player.SetByteValue(UnitFields.Bytes2, UnitBytes2Offsets.PvpFlag, (byte)UnitBytes2Flags.PvP);
|
||||
player.SetPvpFlags(UnitPVPStateFlags.PvP);
|
||||
|
||||
player.SetUInt32Value(UnitFields.Flags, (uint)UnitFlags.PvpAttackable);
|
||||
player.SetUnitFlags(UnitFlags.PvpAttackable);
|
||||
|
||||
//-1 is default value
|
||||
player.SetUInt32Value(ActivePlayerFields.WatchedFactionIndex, 0xFFFFFFFF);
|
||||
player.SetWatchedFactionIndex(0xFFFFFFFF);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -110,7 +109,7 @@ namespace Game.Chat
|
||||
target.InitStatsForLevel(true);
|
||||
target.InitTaxiNodesForLevel();
|
||||
target.InitTalentForLevel();
|
||||
target.SetUInt32Value(ActivePlayerFields.Xp, 0);
|
||||
target.SetXP(0);
|
||||
|
||||
target._ApplyAllLevelScaleItemMods(true);
|
||||
|
||||
|
||||
@@ -62,7 +62,7 @@ namespace Game.Chat.Commands
|
||||
string tNameLink = handler.GetNameLink(target);
|
||||
|
||||
target.SetTitle(titleInfo); // to be sure that title now known
|
||||
target.SetUInt32Value(PlayerFields.ChosenTitle, titleInfo.MaskID);
|
||||
target.SetChosenTitle(titleInfo.MaskID);
|
||||
|
||||
handler.SendSysMessage(CypherStrings.TitleCurrentRes, id, (target.GetGender() == Gender.Male ? titleInfo.Name : titleInfo.Name1)[handler.GetSessionDbcLocale()], tNameLink);
|
||||
return true;
|
||||
@@ -150,9 +150,9 @@ namespace Game.Chat.Commands
|
||||
|
||||
handler.SendSysMessage(CypherStrings.TitleRemoveRes, id, titleNameStr, tNameLink);
|
||||
|
||||
if (!target.HasTitle(target.GetUInt32Value(PlayerFields.ChosenTitle)))
|
||||
if (!target.HasTitle(target.m_playerData.PlayerTitle))
|
||||
{
|
||||
target.SetUInt32Value(PlayerFields.ChosenTitle, 0);
|
||||
target.SetChosenTitle(0);
|
||||
handler.SendSysMessage(CypherStrings.CurrentTitleReset, tNameLink);
|
||||
}
|
||||
|
||||
@@ -189,12 +189,12 @@ namespace Game.Chat.Commands
|
||||
|
||||
titles &= ~titles2; // remove not existed titles
|
||||
|
||||
target.SetUInt64Value(ActivePlayerFields.KnownTitles, titles);
|
||||
target.SetKnownTitles(0, titles);
|
||||
handler.SendSysMessage(CypherStrings.Done);
|
||||
|
||||
if (!target.HasTitle(target.GetUInt32Value(PlayerFields.ChosenTitle)))
|
||||
if (!target.HasTitle(target.m_playerData.PlayerTitle))
|
||||
{
|
||||
target.SetUInt32Value(PlayerFields.ChosenTitle, 0);
|
||||
target.SetChosenTitle(0);
|
||||
handler.SendSysMessage(CypherStrings.CurrentTitleReset, handler.GetNameLink(target));
|
||||
}
|
||||
|
||||
|
||||
@@ -1689,7 +1689,7 @@ namespace Game
|
||||
if (condition.Gender >= 0 && (int)player.GetGender() != condition.Gender)
|
||||
return false;
|
||||
|
||||
if (condition.NativeGender >= 0 && player.GetByteValue(PlayerFields.Bytes3, PlayerFieldOffsets.Bytes3OffsetGender) != condition.NativeGender)
|
||||
if (condition.NativeGender >= 0 && player.m_playerData.NativeSex != condition.NativeGender)
|
||||
return false;
|
||||
|
||||
if (condition.PowerType != -1 && condition.PowerTypeComp != 0)
|
||||
@@ -1701,7 +1701,7 @@ namespace Game
|
||||
|
||||
if (condition.ChrSpecializationIndex >= 0 || condition.ChrSpecializationRole >= 0)
|
||||
{
|
||||
ChrSpecializationRecord spec = CliDB.ChrSpecializationStorage.LookupByKey(player.GetUInt32Value(PlayerFields.CurrentSpecId));
|
||||
ChrSpecializationRecord spec = CliDB.ChrSpecializationStorage.LookupByKey(player.GetPrimarySpecialization());
|
||||
if (spec != null)
|
||||
{
|
||||
if (condition.ChrSpecializationIndex >= 0 && spec.OrderIndex != condition.ChrSpecializationIndex)
|
||||
@@ -1785,10 +1785,10 @@ namespace Game
|
||||
}
|
||||
}
|
||||
|
||||
if (condition.PvpMedal != 0 && !Convert.ToBoolean((1 << (condition.PvpMedal - 1)) & player.GetUInt32Value(ActivePlayerFields.PvpMedals)))
|
||||
if (condition.PvpMedal != 0 && !Convert.ToBoolean((1 << (condition.PvpMedal - 1)) & player.m_activePlayerData.PvpMedals))
|
||||
return false;
|
||||
|
||||
if (condition.LifetimeMaxPVPRank != 0 && player.GetByteValue(ActivePlayerFields.Bytes, PlayerFieldOffsets.FieldBytesOffsetLifetimeMaxPvpRank) != condition.LifetimeMaxPVPRank)
|
||||
if (condition.LifetimeMaxPVPRank != 0 && player.m_activePlayerData.LifetimeMaxRank != condition.LifetimeMaxPVPRank)
|
||||
return false;
|
||||
|
||||
if (condition.MovementFlags[0] != 0 && !Convert.ToBoolean((uint)player.GetUnitMovementFlags() & condition.MovementFlags[0]))
|
||||
@@ -1841,7 +1841,7 @@ namespace Game
|
||||
{
|
||||
uint questBit = Global.DB2Mgr.GetQuestUniqueBitFlag(condition.PrevQuestID[i]);
|
||||
if (questBit != 0)
|
||||
results[i] = (player.GetUInt32Value(ActivePlayerFields.QuestCompleted + (int)((questBit - 1) >> 5)) & (1 << (int)((questBit - 1) & 31))) != 0;
|
||||
results[i] = (player.m_activePlayerData.QuestCompleted[((int)questBit - 1) >> 6] & (1ul << (((int)questBit - 1) & 63))) != 0;
|
||||
}
|
||||
|
||||
if (!PlayerConditionLogic(condition.PrevQuestLogic, results))
|
||||
@@ -1920,7 +1920,7 @@ namespace Game
|
||||
{
|
||||
AreaTableRecord area = CliDB.AreaTableStorage.LookupByKey(condition.Explored[i]);
|
||||
if (area != null)
|
||||
if (area.AreaBit != -1 && !Convert.ToBoolean(player.GetUInt32Value(ActivePlayerFields.ExploredZones + area.AreaBit / 32) & (1 << (area.AreaBit % 32))))
|
||||
if (area.AreaBit != -1 && !Convert.ToBoolean(player.m_activePlayerData.ExploredZones[area.AreaBit / 64] & (1ul << ((int)area.AreaBit % 64))))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -2014,16 +2014,16 @@ namespace Game
|
||||
}
|
||||
}
|
||||
|
||||
if (condition.MinAvgItemLevel != 0 && Math.Floor(player.GetFloatValue(PlayerFields.AvgItemLevel)) < condition.MinAvgItemLevel)
|
||||
if (condition.MinAvgItemLevel != 0 && Math.Floor(player.m_playerData.AvgItemLevel[0]) < condition.MinAvgItemLevel)
|
||||
return false;
|
||||
|
||||
if (condition.MaxAvgItemLevel != 0 && Math.Floor(player.GetFloatValue(PlayerFields.AvgItemLevel)) > condition.MaxAvgItemLevel)
|
||||
if (condition.MaxAvgItemLevel != 0 && Math.Floor(player.m_playerData.AvgItemLevel[0]) > condition.MaxAvgItemLevel)
|
||||
return false;
|
||||
|
||||
if (condition.MinAvgEquippedItemLevel != 0 && Math.Floor(player.GetFloatValue(PlayerFields.AvgItemLevel + 1)) < condition.MinAvgEquippedItemLevel)
|
||||
if (condition.MinAvgEquippedItemLevel != 0 && Math.Floor(player.m_playerData.AvgItemLevel[1]) < condition.MinAvgEquippedItemLevel)
|
||||
return false;
|
||||
|
||||
if (condition.MaxAvgEquippedItemLevel != 0 && Math.Floor(player.GetFloatValue(PlayerFields.AvgItemLevel + 1)) > condition.MaxAvgEquippedItemLevel)
|
||||
if (condition.MaxAvgEquippedItemLevel != 0 && Math.Floor(player.m_playerData.AvgItemLevel[1]) > condition.MaxAvgEquippedItemLevel)
|
||||
return false;
|
||||
|
||||
if (condition.ModifierTreeID != 0 && !player.ModifierTreeSatisfied(condition.ModifierTreeID))
|
||||
|
||||
@@ -76,6 +76,7 @@ namespace Game.DataStorage
|
||||
CinematicCameraStorage = DBReader.Read<CinematicCameraRecord>("CinematicCamera.db2", HotfixStatements.SEL_CINEMATIC_CAMERA);
|
||||
CinematicSequencesStorage = DBReader.Read<CinematicSequencesRecord>("CinematicSequences.db2", HotfixStatements.SEL_CINEMATIC_SEQUENCES);
|
||||
ContentTuningStorage = DBReader.Read<ContentTuningRecord>("ContentTuning.db2", HotfixStatements.SEL_CONTENT_TUNING);
|
||||
ContentTuningXExpectedStorage = DBReader.Read<ContentTuningXExpectedRecord>("ContentTuningXExpected.db2", HotfixStatements.SEL_CONTENT_TUNING_X_EXPECTED);
|
||||
ConversationLineStorage = DBReader.Read<ConversationLineRecord>("ConversationLine.db2", HotfixStatements.SEL_CONVERSATION_LINE);
|
||||
CreatureDisplayInfoStorage = DBReader.Read<CreatureDisplayInfoRecord>("CreatureDisplayInfo.db2", HotfixStatements.SEL_CREATURE_DISPLAY_INFO);
|
||||
CreatureDisplayInfoExtraStorage = DBReader.Read<CreatureDisplayInfoExtraRecord>("CreatureDisplayInfoExtra.db2", HotfixStatements.SEL_CREATURE_DISPLAY_INFO_EXTRA);
|
||||
@@ -153,8 +154,6 @@ namespace Game.DataStorage
|
||||
ItemLimitCategoryConditionStorage = DBReader.Read<ItemLimitCategoryConditionRecord>("ItemLimitCategoryCondition.db2", HotfixStatements.SEL_ITEM_LIMIT_CATEGORY_CONDITION);
|
||||
ItemModifiedAppearanceStorage = DBReader.Read<ItemModifiedAppearanceRecord>("ItemModifiedAppearance.db2", HotfixStatements.SEL_ITEM_MODIFIED_APPEARANCE);
|
||||
ItemPriceBaseStorage = DBReader.Read<ItemPriceBaseRecord>("ItemPriceBase.db2", HotfixStatements.SEL_ITEM_PRICE_BASE);
|
||||
ItemRandomPropertiesStorage = DBReader.Read<ItemRandomPropertiesRecord>("ItemRandomProperties.db2", HotfixStatements.SEL_ITEM_RANDOM_PROPERTIES, HotfixStatements.SEL_ITEM_RANDOM_PROPERTIES_LOCALE);
|
||||
ItemRandomSuffixStorage = DBReader.Read<ItemRandomSuffixRecord>("ItemRandomSuffix.db2", HotfixStatements.SEL_ITEM_RANDOM_SUFFIX, HotfixStatements.SEL_ITEM_RANDOM_SUFFIX_LOCALE);
|
||||
ItemSearchNameStorage = DBReader.Read<ItemSearchNameRecord>("ItemSearchName.db2", HotfixStatements.SEL_ITEM_SEARCH_NAME, HotfixStatements.SEL_ITEM_SEARCH_NAME_LOCALE);
|
||||
ItemSetStorage = DBReader.Read<ItemSetRecord>("ItemSet.db2", HotfixStatements.SEL_ITEM_SET, HotfixStatements.SEL_ITEM_SET_LOCALE);
|
||||
ItemSetSpellStorage = DBReader.Read<ItemSetSpellRecord>("ItemSetSpell.db2", HotfixStatements.SEL_ITEM_SET_SPELL);
|
||||
@@ -324,13 +323,13 @@ namespace Game.DataStorage
|
||||
}
|
||||
|
||||
// Check loaded DB2 files proper version
|
||||
if (!AreaTableStorage.ContainsKey(10048) || // last area added in 8.0.1 (28153)
|
||||
!CharTitlesStorage.ContainsKey(633) || // last char title added in 8.0.1 (28153)
|
||||
!GemPropertiesStorage.ContainsKey(3745) || // last gem property added in 8.0.1 (28153)
|
||||
!ItemStorage.ContainsKey(164760) || // last item added in 8.0.1 (28153)
|
||||
!ItemExtendedCostStorage.ContainsKey(6448) || // last item extended cost added in 8.0.1 (28153)
|
||||
!MapStorage.ContainsKey(2103) || // last map added in 8.0.1 (28153)
|
||||
!SpellNameStorage.ContainsKey(281872)) // last spell added in 8.0.1 (28153)
|
||||
if (!AreaTableStorage.ContainsKey(10521) || // last area added in 8.0.1 (28153)
|
||||
!CharTitlesStorage.ContainsKey(649) || // last char title added in 8.0.1 (28153)
|
||||
!GemPropertiesStorage.ContainsKey(3746) || // last gem property added in 8.0.1 (28153)
|
||||
!ItemStorage.ContainsKey(168279) || // last item added in 8.0.1 (28153)
|
||||
!ItemExtendedCostStorage.ContainsKey(6545) || // last item extended cost added in 8.0.1 (28153)
|
||||
!MapStorage.ContainsKey(2178) || // last map added in 8.0.1 (28153)
|
||||
!SpellNameStorage.ContainsKey(296952)) // last spell added in 8.0.1 (28153)
|
||||
{
|
||||
Log.outError(LogFilter.Misc, "You have _outdated_ DB2 files. Please extract correct versions from current using client.");
|
||||
Global.WorldMgr.ShutdownServ(10, ShutdownMask.Force, ShutdownExitCode.Error);
|
||||
@@ -420,6 +419,7 @@ namespace Game.DataStorage
|
||||
public static DB6Storage<CinematicCameraRecord> CinematicCameraStorage;
|
||||
public static DB6Storage<CinematicSequencesRecord> CinematicSequencesStorage;
|
||||
public static DB6Storage<ContentTuningRecord> ContentTuningStorage;
|
||||
public static DB6Storage<ContentTuningXExpectedRecord> ContentTuningXExpectedStorage;
|
||||
public static DB6Storage<ConversationLineRecord> ConversationLineStorage;
|
||||
public static DB6Storage<CreatureDisplayInfoRecord> CreatureDisplayInfoStorage;
|
||||
public static DB6Storage<CreatureDisplayInfoExtraRecord> CreatureDisplayInfoExtraStorage;
|
||||
@@ -497,8 +497,6 @@ namespace Game.DataStorage
|
||||
public static DB6Storage<ItemLimitCategoryConditionRecord> ItemLimitCategoryConditionStorage;
|
||||
public static DB6Storage<ItemModifiedAppearanceRecord> ItemModifiedAppearanceStorage;
|
||||
public static DB6Storage<ItemPriceBaseRecord> ItemPriceBaseStorage;
|
||||
public static DB6Storage<ItemRandomPropertiesRecord> ItemRandomPropertiesStorage;
|
||||
public static DB6Storage<ItemRandomSuffixRecord> ItemRandomSuffixStorage;
|
||||
public static DB6Storage<ItemSearchNameRecord> ItemSearchNameStorage;
|
||||
public static DB6Storage<ItemSetRecord> ItemSetStorage;
|
||||
public static DB6Storage<ItemSetSpellRecord> ItemSetSpellStorage;
|
||||
@@ -725,6 +723,8 @@ namespace Game.DataStorage
|
||||
return row.Health;
|
||||
case -8:
|
||||
return row.DamageReplaceStat;
|
||||
case -9:
|
||||
return row.DamageSecondary;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -232,34 +232,34 @@ namespace Game.DataStorage
|
||||
switch (Type.GetTypeCode(type))
|
||||
{
|
||||
case TypeCode.Boolean:
|
||||
buffer.WriteUInt8(fieldInfo.GetValue(entry));
|
||||
buffer.WriteUInt8((byte)((bool)fieldInfo.GetValue(entry) ? 1 : 0));
|
||||
break;
|
||||
case TypeCode.SByte:
|
||||
buffer.WriteInt8(fieldInfo.GetValue(entry));
|
||||
buffer.WriteInt8((sbyte)fieldInfo.GetValue(entry));
|
||||
break;
|
||||
case TypeCode.Byte:
|
||||
buffer.WriteUInt8(fieldInfo.GetValue(entry));
|
||||
buffer.WriteUInt8((byte)fieldInfo.GetValue(entry));
|
||||
break;
|
||||
case TypeCode.Int16:
|
||||
buffer.WriteInt16(fieldInfo.GetValue(entry));
|
||||
buffer.WriteInt16((short)fieldInfo.GetValue(entry));
|
||||
break;
|
||||
case TypeCode.UInt16:
|
||||
buffer.WriteUInt16(fieldInfo.GetValue(entry));
|
||||
buffer.WriteUInt16((ushort)fieldInfo.GetValue(entry));
|
||||
break;
|
||||
case TypeCode.Int32:
|
||||
buffer.WriteInt32(fieldInfo.GetValue(entry));
|
||||
buffer.WriteInt32((int)fieldInfo.GetValue(entry));
|
||||
break;
|
||||
case TypeCode.UInt32:
|
||||
buffer.WriteUInt32(fieldInfo.GetValue(entry));
|
||||
buffer.WriteUInt32((uint)fieldInfo.GetValue(entry));
|
||||
break;
|
||||
case TypeCode.Int64:
|
||||
buffer.WriteInt64(fieldInfo.GetValue(entry));
|
||||
buffer.WriteInt64((long)fieldInfo.GetValue(entry));
|
||||
break;
|
||||
case TypeCode.UInt64:
|
||||
buffer.WriteUInt64(fieldInfo.GetValue(entry));
|
||||
buffer.WriteUInt64((ulong)fieldInfo.GetValue(entry));
|
||||
break;
|
||||
case TypeCode.Single:
|
||||
buffer.WriteFloat(fieldInfo.GetValue(entry));
|
||||
buffer.WriteFloat((float)fieldInfo.GetValue(entry));
|
||||
break;
|
||||
case TypeCode.Object:
|
||||
switch (type.Name)
|
||||
@@ -294,34 +294,34 @@ namespace Game.DataStorage
|
||||
switch (Type.GetTypeCode(type))
|
||||
{
|
||||
case TypeCode.Boolean:
|
||||
buffer.WriteUInt8(array.GetValue(i));
|
||||
buffer.WriteUInt8((byte)((bool)array.GetValue(i) ? 1 : 0));
|
||||
break;
|
||||
case TypeCode.SByte:
|
||||
buffer.WriteInt8(array.GetValue(i));
|
||||
buffer.WriteInt8((sbyte)array.GetValue(i));
|
||||
break;
|
||||
case TypeCode.Byte:
|
||||
buffer.WriteUInt8(array.GetValue(i));
|
||||
buffer.WriteUInt8((byte)array.GetValue(i));
|
||||
break;
|
||||
case TypeCode.Int16:
|
||||
buffer.WriteInt16(array.GetValue(i));
|
||||
buffer.WriteInt16((short)array.GetValue(i));
|
||||
break;
|
||||
case TypeCode.UInt16:
|
||||
buffer.WriteUInt16(array.GetValue(i));
|
||||
buffer.WriteUInt16((ushort)array.GetValue(i));
|
||||
break;
|
||||
case TypeCode.Int32:
|
||||
buffer.WriteInt32(array.GetValue(i));
|
||||
buffer.WriteInt32((int)array.GetValue(i));
|
||||
break;
|
||||
case TypeCode.UInt32:
|
||||
buffer.WriteUInt32(array.GetValue(i));
|
||||
buffer.WriteUInt32((uint)array.GetValue(i));
|
||||
break;
|
||||
case TypeCode.Int64:
|
||||
buffer.WriteInt64(array.GetValue(i));
|
||||
buffer.WriteInt64((long)array.GetValue(i));
|
||||
break;
|
||||
case TypeCode.UInt64:
|
||||
buffer.WriteUInt64(array.GetValue(i));
|
||||
buffer.WriteUInt64((ulong)array.GetValue(i));
|
||||
break;
|
||||
case TypeCode.Single:
|
||||
buffer.WriteFloat(array.GetValue(i));
|
||||
buffer.WriteFloat((float)array.GetValue(i));
|
||||
break;
|
||||
case TypeCode.String:
|
||||
var str = (string)array.GetValue(i);
|
||||
|
||||
@@ -32,8 +32,8 @@ namespace Game.DataStorage
|
||||
{
|
||||
class DBReader
|
||||
{
|
||||
private const int HeaderSize = 72 + 1 * 36;
|
||||
private const uint WDC2FmtSig = 0x32434457; // WDC2
|
||||
private const int HeaderSize = 72;
|
||||
private const uint WDC3FmtSig = 0x33434457; // WDC3
|
||||
|
||||
public static DB6Storage<T> Read<T>(string fileName, HotfixStatements preparedStatement, HotfixStatements preparedStatementLocale = 0) where T : new()
|
||||
{
|
||||
@@ -71,7 +71,7 @@ namespace Game.DataStorage
|
||||
{
|
||||
Header = new WDCHeader();
|
||||
Header.Signature = reader.ReadUInt32();
|
||||
if (Header.Signature != WDC2FmtSig)
|
||||
if (Header.Signature != WDC3FmtSig)
|
||||
return false;
|
||||
|
||||
Header.RecordCount = reader.ReadUInt32();
|
||||
@@ -126,28 +126,41 @@ namespace Game.DataStorage
|
||||
}
|
||||
}
|
||||
|
||||
long previousStringTableSize = 0;
|
||||
for (int sectionIndex = 0; sectionIndex < Header.SectionsCount; sectionIndex++)
|
||||
{
|
||||
if (sections[sectionIndex].TactKeyLookup != 0)// && !hasTactKeyFunc(sections[sectionIndex].TactKeyLookup))
|
||||
{
|
||||
previousStringTableSize += sections[sectionIndex].StringTableSize;
|
||||
//Console.WriteLine("Detected db2 with encrypted section! HasKey {0}", CASC.HasKey(Sections[sectionIndex].TactKeyLookup));
|
||||
continue;
|
||||
}
|
||||
|
||||
reader.BaseStream.Position = sections[sectionIndex].FileOffset;
|
||||
|
||||
byte[] recordsData;
|
||||
Dictionary<long, string> stringsTable = null;
|
||||
List<Tuple<int, short>> offsetmap = null;
|
||||
SparseEntry[] sparseEntries = null;
|
||||
|
||||
if (!Header.HasOffsetTable())
|
||||
{
|
||||
// records data
|
||||
recordsData = reader.ReadBytes((int)(sections[sectionIndex].NumRecords * Header.RecordSize));
|
||||
|
||||
Array.Resize(ref recordsData, recordsData.Length + 8); // pad with extra zeros so we don't crash when reading
|
||||
|
||||
// string data
|
||||
stringsTable = new Dictionary<long, string>();
|
||||
|
||||
long stringDataOffset = 0;
|
||||
if (sectionIndex == 0)
|
||||
stringDataOffset = (Header.RecordCount - sections[sectionIndex].NumRecords) * Header.RecordSize;
|
||||
else
|
||||
stringDataOffset = previousStringTableSize;
|
||||
|
||||
for (int i = 0; i < sections[sectionIndex].StringTableSize;)
|
||||
{
|
||||
long oldPos = reader.BaseStream.Position;
|
||||
|
||||
stringsTable[oldPos] = reader.ReadCString();
|
||||
stringsTable[oldPos + stringDataOffset] = reader.ReadCString();
|
||||
|
||||
i += (int)(reader.BaseStream.Position - oldPos);
|
||||
}
|
||||
@@ -159,29 +172,23 @@ namespace Game.DataStorage
|
||||
|
||||
if (reader.BaseStream.Position != sections[sectionIndex].SparseTableOffset)
|
||||
throw new Exception("reader.BaseStream.Position != sections[sectionIndex].SparseTableOffset");
|
||||
|
||||
offsetmap = new List<Tuple<int, short>>();
|
||||
for (int i = 0; i < (Header.MaxId - Header.MinId + 1); i++)
|
||||
{
|
||||
int offset = reader.ReadInt32();
|
||||
short length = reader.ReadInt16();
|
||||
|
||||
if (offset == 0 || length == 0)
|
||||
continue;
|
||||
|
||||
offsetmap.Add(new Tuple<int, short>(offset, length));
|
||||
}
|
||||
}
|
||||
|
||||
Array.Resize(ref recordsData, recordsData.Length + 8); // pad with extra zeros so we don't crash when reading
|
||||
|
||||
// index data
|
||||
int[] indexData = reader.ReadArray<int>((uint)(sections[sectionIndex].IndexDataSize / 4));
|
||||
bool isIndexEmpty = Header.HasIndexTable() && indexData.Count(i => i == 0) == sections[sectionIndex].NumRecords;
|
||||
|
||||
// duplicate rows data
|
||||
Dictionary<int, int> copyData = new Dictionary<int, int>();
|
||||
|
||||
for (int i = 0; i < sections[sectionIndex].CopyTableSize / 8; i++)
|
||||
for (int i = 0; i < sections[sectionIndex].NumCopyRecords; i++)
|
||||
copyData[reader.ReadInt32()] = reader.ReadInt32();
|
||||
|
||||
if (sections[sectionIndex].NumSparseRecords > 0)
|
||||
sparseEntries = reader.ReadArray<SparseEntry>((uint)sections[sectionIndex].NumSparseRecords);
|
||||
|
||||
// reference data
|
||||
ReferenceData refData = null;
|
||||
|
||||
@@ -208,24 +215,31 @@ namespace Game.DataStorage
|
||||
};
|
||||
}
|
||||
|
||||
if (sections[sectionIndex].NumSparseRecords > 0)
|
||||
{
|
||||
// TODO: use this shit
|
||||
int[] sparseIndexData = reader.ReadArray<int>((uint)sections[sectionIndex].NumSparseRecords);
|
||||
|
||||
if (Header.HasIndexTable() && indexData.Length != sparseIndexData.Length)
|
||||
throw new Exception("indexData.Length != sparseIndexData.Length");
|
||||
|
||||
//indexData = sparseIndexData;
|
||||
}
|
||||
|
||||
BitReader bitReader = new BitReader(recordsData);
|
||||
|
||||
for (int i = 0; i < Header.RecordCount; ++i)
|
||||
for (int i = 0; i < sections[sectionIndex].NumRecords; ++i)
|
||||
{
|
||||
bitReader.Position = 0;
|
||||
if (offsetmap != null)
|
||||
bitReader.Offset = offsetmap[i].Item1 - sections[sectionIndex].FileOffset;
|
||||
if (Header.HasOffsetTable())
|
||||
bitReader.Offset = sparseEntries[i].Offset - sections[sectionIndex].FileOffset;
|
||||
else
|
||||
bitReader.Offset = i * (int)Header.RecordSize;
|
||||
|
||||
bool hasRef = refData.Entries.TryGetValue(i, out int refId);
|
||||
|
||||
var rec = new WDC2Row(this, bitReader, sections[sectionIndex].FileOffset, sections[sectionIndex].IndexDataSize != 0 ? indexData[i] : -1, hasRef ? refId : -1, stringsTable);
|
||||
|
||||
if (sections[sectionIndex].IndexDataSize != 0)
|
||||
_records.Add(indexData[i], rec);
|
||||
else
|
||||
_records.Add(rec.Id, rec);
|
||||
var rec = new WDC3Row(this, bitReader, sections[sectionIndex].FileOffset, Header.HasIndexTable() ? (isIndexEmpty ? i : indexData[i]) : -1, hasRef ? refId : -1, stringsTable);
|
||||
_records.Add(rec.Id, rec);
|
||||
}
|
||||
|
||||
foreach (var copyRow in copyData)
|
||||
@@ -234,6 +248,8 @@ namespace Game.DataStorage
|
||||
rec.Id = copyRow.Key;
|
||||
_records.Add(copyRow.Key, rec);
|
||||
}
|
||||
|
||||
previousStringTableSize += sections[sectionIndex].StringTableSize;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -246,10 +262,10 @@ namespace Game.DataStorage
|
||||
internal Value32[][] PalletData;
|
||||
internal Dictionary<int, Value32>[] CommonData;
|
||||
|
||||
Dictionary<int, WDC2Row> _records = new Dictionary<int, WDC2Row>();
|
||||
Dictionary<int, WDC3Row> _records = new Dictionary<int, WDC3Row>();
|
||||
}
|
||||
|
||||
class WDC2Row
|
||||
class WDC3Row
|
||||
{
|
||||
private BitReader _data;
|
||||
private int _dataOffset;
|
||||
@@ -265,7 +281,7 @@ namespace Game.DataStorage
|
||||
private Dictionary<int, Value32>[] _commonData;
|
||||
private Dictionary<long, string> _stringsTable;
|
||||
|
||||
public WDC2Row(DBReader reader, BitReader data, int recordsOffset, int id, int refId, Dictionary<long, string> stringsTable)
|
||||
public WDC3Row(DBReader reader, BitReader data, int recordsOffset, int id, int refId, Dictionary<long, string> stringsTable)
|
||||
{
|
||||
_data = data;
|
||||
_recordsOffset = recordsOffset;
|
||||
@@ -553,9 +569,9 @@ namespace Game.DataStorage
|
||||
return obj;
|
||||
}
|
||||
|
||||
public WDC2Row Clone()
|
||||
public WDC3Row Clone()
|
||||
{
|
||||
return (WDC2Row)MemberwiseClone();
|
||||
return (WDC3Row)MemberwiseClone();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -669,14 +685,15 @@ namespace Game.DataStorage
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct SectionHeader
|
||||
{
|
||||
public long TactKeyLookup;
|
||||
public ulong TactKeyLookup;
|
||||
public int FileOffset;
|
||||
public int NumRecords;
|
||||
public int StringTableSize;
|
||||
public int CopyTableSize;
|
||||
public int SparseTableOffset; // CatalogDataOffset, absolute value, {uint offset, ushort size}[MaxId - MinId + 1]
|
||||
public int IndexDataSize; // int indexData[IndexDataSize / 4]
|
||||
public int ParentLookupDataSize; // uint NumRecords, uint minId, uint maxId, {uint id, uint index}[NumRecords], questionable usefulness...
|
||||
public int NumSparseRecords;
|
||||
public int NumCopyRecords;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
|
||||
@@ -136,6 +136,13 @@ namespace Game.DataStorage
|
||||
_defaultChrSpecializationsByClass[(uint)chrSpec.ClassID] = chrSpec;
|
||||
}
|
||||
|
||||
foreach (ContentTuningXExpectedRecord contentTuningXExpectedStat in CliDB.ContentTuningXExpectedStorage.Values)
|
||||
{
|
||||
ExpectedStatModRecord expectedStatMod = CliDB.ExpectedStatModStorage.LookupByKey(contentTuningXExpectedStat.ExpectedStatModID);
|
||||
if (expectedStatMod != null)
|
||||
_expectedStatModsByContentTuning.Add(contentTuningXExpectedStat.ContentTuningID, expectedStatMod);
|
||||
}
|
||||
|
||||
foreach (CurvePointRecord curvePoint in CliDB.CurvePointStorage.Values)
|
||||
{
|
||||
if (CliDB.CurveStorage.ContainsKey(curvePoint.CurveID))
|
||||
@@ -396,6 +403,12 @@ namespace Game.DataStorage
|
||||
|
||||
CliDB.RulesetItemUpgradeStorage.Clear();
|
||||
|
||||
foreach (SkillLineRecord skill in CliDB.SkillLineStorage.Values)
|
||||
{
|
||||
if (skill.ParentSkillLineID != 0)
|
||||
_skillLinesByParentSkillLine.Add(skill.ParentSkillLineID, skill);
|
||||
}
|
||||
|
||||
foreach (SkillLineAbilityRecord skillLineAbility in CliDB.SkillLineAbilityStorage.Values)
|
||||
_skillLineAbilitiesBySkillupSkill.Add(skillLineAbility.SkillupSkillLineID != 0 ? skillLineAbility.SkillupSkillLineID : skillLineAbility.SkillLine, skillLineAbility);
|
||||
|
||||
@@ -969,61 +982,93 @@ namespace Game.DataStorage
|
||||
if (expectedStatRecord == null)
|
||||
return 1.0f;
|
||||
|
||||
ExpectedStatModRecord[] mods = new ExpectedStatModRecord[3];
|
||||
ContentTuningRecord contentTuning = CliDB.ContentTuningStorage.LookupByKey(contentTuningId);
|
||||
if (contentTuning != null)
|
||||
{
|
||||
mods[0] = CliDB.ExpectedStatModStorage.LookupByKey(contentTuning.ExpectedStatModID);
|
||||
mods[1] = CliDB.ExpectedStatModStorage.LookupByKey(contentTuning.DifficultyESMID);
|
||||
}
|
||||
ExpectedStatModRecord classMod = null;
|
||||
switch (unitClass)
|
||||
{
|
||||
case Class.Warrior:
|
||||
mods[2] = CliDB.ExpectedStatModStorage.LookupByKey(4);
|
||||
classMod = CliDB.ExpectedStatModStorage.LookupByKey(4);
|
||||
break;
|
||||
case Class.Paladin:
|
||||
mods[2] = CliDB.ExpectedStatModStorage.LookupByKey(2);
|
||||
classMod = CliDB.ExpectedStatModStorage.LookupByKey(2);
|
||||
break;
|
||||
case Class.Rogue:
|
||||
mods[2] = CliDB.ExpectedStatModStorage.LookupByKey(3);
|
||||
classMod = CliDB.ExpectedStatModStorage.LookupByKey(3);
|
||||
break;
|
||||
case Class.Mage:
|
||||
mods[2] = CliDB.ExpectedStatModStorage.LookupByKey(1);
|
||||
classMod = CliDB.ExpectedStatModStorage.LookupByKey(1);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
List<ExpectedStatModRecord> contentTuningMods = _expectedStatModsByContentTuning.LookupByKey(contentTuningId);
|
||||
float value = 0.0f;
|
||||
switch (stat)
|
||||
{
|
||||
case ExpectedStatType.CreatureHealth:
|
||||
value = mods.Sum(expectedStatMod => expectedStatRecord.CreatureHealth * (expectedStatMod != null ? expectedStatMod.CreatureHealthMod : 1.0f));
|
||||
value = expectedStatRecord.CreatureHealth;
|
||||
if (contentTuningMods != null)
|
||||
value *= contentTuningMods.Sum(expectedStatMod => expectedStatMod != null ? expectedStatMod.CreatureHealthMod : 1.0f);
|
||||
if (classMod != null)
|
||||
value *= classMod.CreatureHealthMod;
|
||||
break;
|
||||
case ExpectedStatType.PlayerHealth:
|
||||
value = mods.Sum(expectedStatMod => expectedStatRecord.PlayerHealth * (expectedStatMod != null ? expectedStatMod.PlayerHealthMod : 1.0f));
|
||||
value = expectedStatRecord.PlayerHealth;
|
||||
if (contentTuningMods != null)
|
||||
value *= contentTuningMods.Sum(expectedStatMod => expectedStatMod != null ? expectedStatMod.PlayerHealthMod : 1.0f);
|
||||
if (classMod != null)
|
||||
value *= classMod.PlayerHealthMod;
|
||||
break;
|
||||
case ExpectedStatType.CreatureAutoAttackDps:
|
||||
value = mods.Sum(expectedStatMod => expectedStatRecord.CreatureAutoAttackDps * (expectedStatMod != null ? expectedStatMod.CreatureAutoAttackDPSMod : 1.0f));
|
||||
value = expectedStatRecord.CreatureAutoAttackDps;
|
||||
if (contentTuningMods != null)
|
||||
value *= contentTuningMods.Sum(expectedStatMod => expectedStatMod != null ? expectedStatMod.CreatureAutoAttackDPSMod : 1.0f);
|
||||
if (classMod != null)
|
||||
value *= classMod.CreatureAutoAttackDPSMod;
|
||||
break;
|
||||
case ExpectedStatType.CreatureArmor:
|
||||
value = mods.Sum(expectedStatMod => expectedStatRecord.CreatureArmor * (expectedStatMod != null ? expectedStatMod.CreatureArmorMod : 1.0f));
|
||||
value = expectedStatRecord.CreatureArmor;
|
||||
if (contentTuningMods != null)
|
||||
value *= contentTuningMods.Sum(expectedStatMod => expectedStatMod != null ? expectedStatMod.CreatureArmorMod : 1.0f);
|
||||
if (classMod != null)
|
||||
value *= classMod.CreatureArmorMod;
|
||||
break;
|
||||
case ExpectedStatType.PlayerMana:
|
||||
value = mods.Sum(expectedStatMod => expectedStatRecord.PlayerMana * (expectedStatMod != null ? expectedStatMod.PlayerManaMod : 1.0f));
|
||||
value = expectedStatRecord.PlayerMana;
|
||||
if (contentTuningMods != null)
|
||||
value *= contentTuningMods.Sum(expectedStatMod => expectedStatMod != null ? expectedStatMod.PlayerManaMod : 1.0f);
|
||||
if (classMod != null)
|
||||
value *= classMod.PlayerManaMod;
|
||||
break;
|
||||
case ExpectedStatType.PlayerPrimaryStat:
|
||||
value = mods.Sum(expectedStatMod => expectedStatRecord.PlayerPrimaryStat * (expectedStatMod != null ? expectedStatMod.PlayerPrimaryStatMod : 1.0f));
|
||||
value = expectedStatRecord.PlayerPrimaryStat;
|
||||
if (contentTuningMods != null)
|
||||
value *= contentTuningMods.Sum(expectedStatMod => expectedStatMod != null ? expectedStatMod.PlayerPrimaryStatMod : 1.0f);
|
||||
if (classMod != null)
|
||||
value *= classMod.PlayerPrimaryStatMod;
|
||||
break;
|
||||
case ExpectedStatType.PlayerSecondaryStat:
|
||||
value = mods.Sum(expectedStatMod => expectedStatRecord.PlayerSecondaryStat * (expectedStatMod != null ? expectedStatMod.PlayerSecondaryStatMod : 1.0f));
|
||||
value = expectedStatRecord.PlayerSecondaryStat;
|
||||
if (contentTuningMods != null)
|
||||
value *= contentTuningMods.Sum(expectedStatMod => expectedStatMod != null ? expectedStatMod.PlayerSecondaryStatMod : 1.0f);
|
||||
if (classMod != null)
|
||||
value *= classMod.PlayerSecondaryStatMod;
|
||||
break;
|
||||
case ExpectedStatType.ArmorConstant:
|
||||
value = mods.Sum(expectedStatMod => expectedStatRecord.ArmorConstant * (expectedStatMod != null ? expectedStatMod.ArmorConstantMod : 1.0f));
|
||||
value = expectedStatRecord.ArmorConstant;
|
||||
if (contentTuningMods != null)
|
||||
value *= contentTuningMods.Sum(expectedStatMod => expectedStatMod != null ? expectedStatMod.ArmorConstantMod : 1.0f);
|
||||
if (classMod != null)
|
||||
value *= classMod.ArmorConstantMod;
|
||||
break;
|
||||
case ExpectedStatType.None:
|
||||
break;
|
||||
case ExpectedStatType.CreatureSpellDamage:
|
||||
value = mods.Sum(expectedStatMod => expectedStatRecord.CreatureSpellDamage * (expectedStatMod != null ? expectedStatMod.CreatureSpellDamageMod : 1.0f));
|
||||
value = expectedStatRecord.CreatureSpellDamage;
|
||||
if (contentTuningMods != null)
|
||||
value *= contentTuningMods.Sum(expectedStatMod => expectedStatMod != null ? expectedStatMod.CreatureSpellDamageMod : 1.0f);
|
||||
if (classMod != null)
|
||||
value *= classMod.CreatureSpellDamageMod;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -1479,6 +1524,11 @@ namespace Game.DataStorage
|
||||
return _rulesetItemUpgrade.LookupByKey(itemId);
|
||||
}
|
||||
|
||||
public List<SkillLineRecord> GetSkillLinesForParentSkill(uint parentSkillId)
|
||||
{
|
||||
return _skillLinesByParentSkillLine.LookupByKey(parentSkillId);
|
||||
}
|
||||
|
||||
public List<SkillLineAbilityRecord> GetSkillLineAbilitiesBySkill(uint skillId)
|
||||
{
|
||||
return _skillLineAbilitiesBySkillupSkill.LookupByKey(skillId);
|
||||
@@ -1903,6 +1953,7 @@ namespace Game.DataStorage
|
||||
MultiMap<uint, CurvePointRecord> _curvePoints = new MultiMap<uint, CurvePointRecord>();
|
||||
Dictionary<Tuple<uint, byte, byte, byte>, EmotesTextSoundRecord> _emoteTextSounds = new Dictionary<Tuple<uint, byte, byte, byte>, EmotesTextSoundRecord>();
|
||||
Dictionary<Tuple<uint, int>, ExpectedStatRecord> _expectedStatsByLevel = new Dictionary<Tuple<uint, int>, ExpectedStatRecord>();
|
||||
MultiMap<uint, ExpectedStatModRecord> _expectedStatModsByContentTuning = new MultiMap<uint, ExpectedStatModRecord>();
|
||||
MultiMap<uint, uint> _factionTeams = new MultiMap<uint, uint>();
|
||||
Dictionary<uint, HeirloomRecord> _heirlooms = new Dictionary<uint, HeirloomRecord>();
|
||||
MultiMap<uint, uint> _glyphBindableSpells = new MultiMap<uint, uint>();
|
||||
@@ -1933,6 +1984,7 @@ namespace Game.DataStorage
|
||||
MultiMap<uint, RewardPackXCurrencyTypeRecord> _rewardPackCurrencyTypes = new MultiMap<uint, RewardPackXCurrencyTypeRecord>();
|
||||
MultiMap<uint, RewardPackXItemRecord> _rewardPackItems = new MultiMap<uint, RewardPackXItemRecord>();
|
||||
Dictionary<uint, uint> _rulesetItemUpgrade = new Dictionary<uint, uint>();
|
||||
MultiMap<uint, SkillLineRecord> _skillLinesByParentSkillLine = new MultiMap<uint, SkillLineRecord>();
|
||||
MultiMap<uint, SkillLineAbilityRecord> _skillLineAbilitiesBySkillupSkill = new MultiMap<uint, SkillLineAbilityRecord>();
|
||||
MultiMap<uint, SkillRaceClassInfoRecord> _skillRaceClassInfoBySkill = new MultiMap<uint, SkillRaceClassInfoRecord>();
|
||||
MultiMap<uint, SpecializationSpellsRecord> _specializationSpellsBySpec = new MultiMap<uint, SpecializationSpellsRecord>();
|
||||
|
||||
@@ -36,6 +36,7 @@ namespace Game.DataStorage
|
||||
public AchievementFlags Flags;
|
||||
public ushort UiOrder;
|
||||
public uint IconFileID;
|
||||
public int RewardItemID;
|
||||
public uint CriteriaTree;
|
||||
public ushort SharesCriteria;
|
||||
}
|
||||
@@ -43,9 +44,9 @@ namespace Game.DataStorage
|
||||
public sealed class AnimationDataRecord
|
||||
{
|
||||
public uint Id;
|
||||
public ushort Fallback;
|
||||
public ushort BehaviorID;
|
||||
public byte BehaviorTier;
|
||||
public int BehaviorID;
|
||||
public int Fallback;
|
||||
public int[] Flags = new int[2];
|
||||
}
|
||||
|
||||
@@ -161,6 +162,7 @@ namespace Game.DataStorage
|
||||
public uint UiAltItemAppearanceID;
|
||||
public byte Flags;
|
||||
public ushort UiCameraID;
|
||||
public uint UsablePlayerConditionID;
|
||||
}
|
||||
|
||||
public sealed class ArtifactAppearanceSetRecord
|
||||
|
||||
@@ -36,7 +36,7 @@ namespace Game.DataStorage
|
||||
public string DisplayName;
|
||||
public string Description;
|
||||
public uint Id;
|
||||
public byte Type; // value 0 -> hair, value 2 -> facialhair
|
||||
public byte Type; // value 0 . hair, value 2 . facialhair
|
||||
public float CostModifier;
|
||||
public byte Race;
|
||||
public byte Sex;
|
||||
@@ -76,7 +76,7 @@ namespace Game.DataStorage
|
||||
public sealed class BattlePetSpeciesStateRecord
|
||||
{
|
||||
public uint Id;
|
||||
public byte BattlePetStateID;
|
||||
public ushort BattlePetStateID;
|
||||
public int Value;
|
||||
public uint BattlePetSpeciesID;
|
||||
}
|
||||
|
||||
@@ -102,6 +102,7 @@ namespace Game.DataStorage
|
||||
public uint IconFileDataID;
|
||||
public uint LowResScreenFileDataID;
|
||||
public int StartingLevel;
|
||||
public uint SpellTextureBlobFileDataID;
|
||||
public ushort Flags;
|
||||
public ushort CinematicSequenceID;
|
||||
public ushort DefaultSpec;
|
||||
@@ -214,8 +215,14 @@ namespace Game.DataStorage
|
||||
public int MinLevel;
|
||||
public int MaxLevel;
|
||||
public int Flags;
|
||||
public int ExpansionID;
|
||||
}
|
||||
|
||||
public sealed class ContentTuningXExpectedRecord
|
||||
{
|
||||
public uint Id;
|
||||
public int ExpectedStatModID;
|
||||
public int DifficultyESMID;
|
||||
public uint ContentTuningID;
|
||||
}
|
||||
|
||||
public sealed class ConversationLineRecord
|
||||
@@ -322,6 +329,9 @@ namespace Game.DataStorage
|
||||
public float OverrideNameScale;
|
||||
public float OverrideSelectionRadius;
|
||||
public float TamedPetBaseScale;
|
||||
public sbyte Unknown820_1; // scale related
|
||||
public float Unknown820_2; // scale related
|
||||
public float[] Unknown820_3 = new float[2]; // scale related
|
||||
}
|
||||
|
||||
public sealed class CreatureTypeRecord
|
||||
@@ -373,6 +383,7 @@ namespace Game.DataStorage
|
||||
public uint Flags;
|
||||
public sbyte Quality;
|
||||
public int FactionID;
|
||||
public int ItemGroupSoundsID;
|
||||
}
|
||||
|
||||
public sealed class CurveRecord
|
||||
|
||||
@@ -71,10 +71,12 @@ namespace Game.DataStorage
|
||||
public short MapID;
|
||||
public sbyte DifficultyID;
|
||||
public int OrderIndex;
|
||||
public int CompleteWorldStateID;
|
||||
public sbyte Bit;
|
||||
public int CreatureDisplayID;
|
||||
public byte Flags;
|
||||
public int SpellIconFileID;
|
||||
public int Faction;
|
||||
}
|
||||
|
||||
public sealed class DurabilityCostsRecord
|
||||
|
||||
@@ -29,7 +29,7 @@ namespace Game.DataStorage
|
||||
public short ReputationIndex;
|
||||
public ushort ParentFactionID;
|
||||
public byte Expansion;
|
||||
public byte FriendshipRepID;
|
||||
public uint FriendshipRepID;
|
||||
public byte Flags;
|
||||
public ushort ParagonFactionID;
|
||||
public short[] ReputationClassMask = new short[4];
|
||||
|
||||
@@ -131,8 +131,8 @@ namespace Game.DataStorage
|
||||
public int AllianceCreatureID;
|
||||
public byte HordeGarrFollRaceID;
|
||||
public byte AllianceGarrFollRaceID;
|
||||
public byte HordeGarrClassSpecID;
|
||||
public byte AllianceGarrClassSpecID;
|
||||
public uint HordeGarrClassSpecID;
|
||||
public uint AllianceGarrClassSpecID;
|
||||
public byte Quality;
|
||||
public byte FollowerLevel;
|
||||
public ushort ItemLevelWeapon;
|
||||
@@ -232,9 +232,9 @@ namespace Game.DataStorage
|
||||
{
|
||||
public uint Id;
|
||||
public uint SpellID;
|
||||
public ushort SpellIconID;
|
||||
public byte GlyphType;
|
||||
public byte GlyphExclusiveCategoryID;
|
||||
public uint SpellIconID;
|
||||
}
|
||||
|
||||
public sealed class GlyphRequiredSpecRecord
|
||||
|
||||
@@ -166,6 +166,7 @@ namespace Game.DataStorage
|
||||
public float Gem3;
|
||||
public float Health;
|
||||
public float DamageReplaceStat;
|
||||
public float DamageSecondary;
|
||||
}
|
||||
|
||||
public sealed class GtXpRecord
|
||||
|
||||
@@ -29,8 +29,8 @@ namespace Game.DataStorage
|
||||
public sbyte SourceTypeEnum;
|
||||
public byte Flags;
|
||||
public int LegacyItemID;
|
||||
public int[] UpgradeItemID = new int[3];
|
||||
public ushort[] UpgradeItemBonusListID = new ushort[3];
|
||||
public int[] UpgradeItemID = new int[4];
|
||||
public ushort[] UpgradeItemBonusListID = new ushort[4];
|
||||
}
|
||||
|
||||
public sealed class HolidaysRecord
|
||||
|
||||
@@ -102,16 +102,33 @@ namespace Game.DataStorage
|
||||
public uint Id;
|
||||
public int[] Value = new int[3];
|
||||
public ushort ParentItemBonusListID;
|
||||
public ItemBonusType Type;
|
||||
public ItemBonusType BonusType;
|
||||
public byte OrderIndex;
|
||||
}
|
||||
|
||||
public sealed class ItemBonusListGroupEntryRecord
|
||||
{
|
||||
public uint Id;
|
||||
public int ItemBonusListID;
|
||||
public int ItemLevelSelectorID;
|
||||
public int OrderIndex;
|
||||
public int ItemExtendedCostID;
|
||||
public int ItemBonusListGroupID;
|
||||
}
|
||||
|
||||
public sealed class ItemBonusListLevelDeltaRecord
|
||||
{
|
||||
public short ItemLevelDelta;
|
||||
public uint Id;
|
||||
}
|
||||
|
||||
public sealed class ItemBonusSequenceSpellRecord
|
||||
{
|
||||
public uint Id;
|
||||
public int SpellID;
|
||||
public int ItemID;
|
||||
}
|
||||
|
||||
public sealed class ItemBonusTreeNodeRecord
|
||||
{
|
||||
public uint Id;
|
||||
@@ -125,9 +142,9 @@ namespace Game.DataStorage
|
||||
public sealed class ItemChildEquipmentRecord
|
||||
{
|
||||
public uint Id;
|
||||
public uint ParentItemID;
|
||||
public uint ChildItemID;
|
||||
public byte ChildItemEquipSlot;
|
||||
public uint ParentItemID;
|
||||
}
|
||||
|
||||
public sealed class ItemClassRecord
|
||||
@@ -206,6 +223,7 @@ namespace Game.DataStorage
|
||||
public uint Id;
|
||||
public ushort MinItemLevel;
|
||||
public ushort ItemLevelSelectorQualitySetID;
|
||||
public ushort AzeriteUnlockMappingSet;
|
||||
}
|
||||
|
||||
public sealed class ItemLevelSelectorQualityRecord
|
||||
@@ -257,21 +275,6 @@ namespace Game.DataStorage
|
||||
public float Weapon;
|
||||
}
|
||||
|
||||
public sealed class ItemRandomPropertiesRecord
|
||||
{
|
||||
public uint Id;
|
||||
public LocalizedString Name;
|
||||
public ushort[] Enchantment = new ushort[ItemConst.MaxItemRandomProperties];
|
||||
}
|
||||
|
||||
public sealed class ItemRandomSuffixRecord
|
||||
{
|
||||
public uint Id;
|
||||
public LocalizedString Name;
|
||||
public ushort[] Enchantment = new ushort[ItemConst.MaxItemRandomProperties];
|
||||
public ushort[] AllocationPct = new ushort[ItemConst.MaxItemRandomProperties];
|
||||
}
|
||||
|
||||
public sealed class ItemSearchNameRecord
|
||||
{
|
||||
public long AllowableRace;
|
||||
@@ -345,8 +348,6 @@ namespace Game.DataStorage
|
||||
public ushort InstanceBound;
|
||||
public ushort ZoneBound;
|
||||
public ushort ItemSet;
|
||||
public ushort ItemRandomSuffixGroupID;
|
||||
public ushort RandomSelect;
|
||||
public ushort LockID;
|
||||
public ushort StartQuestID;
|
||||
public ushort PageID;
|
||||
|
||||
@@ -50,6 +50,7 @@ namespace Game.DataStorage
|
||||
public byte MaxPlayers;
|
||||
public short WindSettingsID;
|
||||
public int ZmpFileDataID;
|
||||
public int WdtFileDataID;
|
||||
public MapFlags[] Flags = new MapFlags[2];
|
||||
|
||||
// Helpers
|
||||
@@ -95,14 +96,14 @@ namespace Game.DataStorage
|
||||
{
|
||||
public uint Id;
|
||||
public LocalizedString Message; // m_message_lang (text showed when transfer to map failed)
|
||||
public uint ItemContextPickerID;
|
||||
public int ContentTuningID;
|
||||
public byte DifficultyID;
|
||||
public byte LockID;
|
||||
public uint DifficultyID;
|
||||
public int LockID;
|
||||
public byte ResetInterval;
|
||||
public byte MaxPlayers;
|
||||
public byte ItemContext;
|
||||
public byte Flags;
|
||||
public uint MaxPlayers;
|
||||
public int ItemContext;
|
||||
public uint ItemContextPickerID;
|
||||
public int Flags;
|
||||
public int ContentTuningID;
|
||||
public uint MapID;
|
||||
|
||||
public uint GetRaidDuration()
|
||||
@@ -121,7 +122,7 @@ namespace Game.DataStorage
|
||||
public uint Parent;
|
||||
public sbyte Operator;
|
||||
public sbyte Amount;
|
||||
public byte Type;
|
||||
public uint Type;
|
||||
public uint Asset;
|
||||
public int SecondaryAsset;
|
||||
public sbyte TertiaryAsset;
|
||||
@@ -154,6 +155,7 @@ namespace Game.DataStorage
|
||||
public uint ReqSpellKnownID;
|
||||
public uint ModSpellAuraID;
|
||||
public short ReqMapID;
|
||||
public int PlayerConditionID;
|
||||
}
|
||||
|
||||
public sealed class MountTypeXCapabilityRecord
|
||||
|
||||
@@ -21,6 +21,7 @@ namespace Game.DataStorage
|
||||
{
|
||||
public uint Id;
|
||||
public int DamageReplaceStat;
|
||||
public int DamageSecondary;
|
||||
public uint[] Epic = new uint[5];
|
||||
public uint[] Superior = new uint[5];
|
||||
public uint[] Good = new uint[5];
|
||||
|
||||
@@ -139,7 +139,7 @@ namespace Game.DataStorage
|
||||
public sealed class SoundKitRecord
|
||||
{
|
||||
public uint Id;
|
||||
public byte SoundType;
|
||||
public uint SoundType;
|
||||
public float VolumeFloat;
|
||||
public ushort Flags;
|
||||
public float MinDistance;
|
||||
@@ -331,9 +331,9 @@ namespace Game.DataStorage
|
||||
public string HordeName;
|
||||
public uint[] EffectArg = new uint[ItemConst.MaxItemEnchantmentEffects];
|
||||
public float[] EffectScalingPoints = new float[ItemConst.MaxItemEnchantmentEffects];
|
||||
public uint TransmogPlayerConditionID;
|
||||
public uint TransmogCost;
|
||||
public uint IconFileDataID;
|
||||
public uint TransmogPlayerConditionID;
|
||||
public ushort[] EffectPointsMin = new ushort[ItemConst.MaxItemEnchantmentEffects];
|
||||
public ushort ItemVisual;
|
||||
public EnchantmentSlotMask Flags;
|
||||
@@ -392,6 +392,7 @@ namespace Game.DataStorage
|
||||
public float MinDuration;
|
||||
public uint SpellIconFileDataID;
|
||||
public uint ActiveIconFileDataID;
|
||||
public uint ContentTuningID;
|
||||
public int[] Attributes = new int[14];
|
||||
public uint SpellID;
|
||||
}
|
||||
|
||||
@@ -48,10 +48,11 @@ namespace Game.DataStorage
|
||||
public Vector2 FlightMapOffset;
|
||||
public uint Id;
|
||||
public ushort ContinentID;
|
||||
public ushort ConditionID;
|
||||
public uint ConditionID;
|
||||
public ushort CharacterBitNumber;
|
||||
public TaxiNodeFlags Flags;
|
||||
public int UiTextureKitID;
|
||||
public int MinimapAtlasMemberID;
|
||||
public float Facing;
|
||||
public uint SpecialIconConditionID;
|
||||
public uint VisibilityConditionID;
|
||||
@@ -75,8 +76,8 @@ namespace Game.DataStorage
|
||||
public ushort ContinentID;
|
||||
public TaxiPathNodeFlags Flags;
|
||||
public uint Delay;
|
||||
public ushort ArrivalEventID;
|
||||
public ushort DepartureEventID;
|
||||
public uint ArrivalEventID;
|
||||
public uint DepartureEventID;
|
||||
}
|
||||
|
||||
public sealed class TotemCategoryRecord
|
||||
@@ -112,7 +113,9 @@ namespace Game.DataStorage
|
||||
public uint TransmogSetGroupID;
|
||||
public int ItemNameDescriptionID;
|
||||
public ushort ParentTransmogSetID;
|
||||
public byte Unknown810;
|
||||
public byte ExpansionID;
|
||||
public int PatchID;
|
||||
public short UiOrder;
|
||||
}
|
||||
|
||||
|
||||
@@ -58,6 +58,8 @@ namespace Game.DataStorage
|
||||
public int ParentUiMapID;
|
||||
public int OrderIndex;
|
||||
public int ChildUiMapID;
|
||||
public int OverrideHighlightFileDataID;
|
||||
public int OverrideHighlightAtlasID;
|
||||
}
|
||||
|
||||
public sealed class UiMapXMapArtRecord
|
||||
|
||||
@@ -44,7 +44,7 @@ namespace Game.DataStorage
|
||||
public uint Id;
|
||||
public uint QuestFeedbackEffectID;
|
||||
public byte WhenToDisplay;
|
||||
public byte TargetType;
|
||||
public int TargetType;
|
||||
public int TargetAsset;
|
||||
public uint PlayerConditionID;
|
||||
public ushort CombatConditionID;
|
||||
|
||||
@@ -26,6 +26,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using Game;
|
||||
using Framework.Dynamic;
|
||||
using Game.Network;
|
||||
|
||||
namespace Game.Entities
|
||||
{
|
||||
@@ -42,7 +43,7 @@ namespace Game.Entities
|
||||
m_updateFlag.Stationary = true;
|
||||
m_updateFlag.AreaTrigger = true;
|
||||
|
||||
valuesCount = (int)AreaTriggerFields.End;
|
||||
m_areaTriggerData = new AreaTriggerFieldData();
|
||||
|
||||
_spline = new Spline();
|
||||
}
|
||||
@@ -114,19 +115,35 @@ namespace Game.Entities
|
||||
|
||||
SetObjectScale(1.0f);
|
||||
|
||||
SetGuidValue(AreaTriggerFields.Caster, caster.GetGUID());
|
||||
SetGuidValue(AreaTriggerFields.CreatingEffectGuid, castId);
|
||||
SetUpdateFieldValue(m_values.ModifyValue(m_areaTriggerData).ModifyValue(m_areaTriggerData.Caster), caster.GetGUID());
|
||||
SetUpdateFieldValue(m_values.ModifyValue(m_areaTriggerData).ModifyValue(m_areaTriggerData.CreatingEffectGUID), castId);
|
||||
|
||||
SetUInt32Value(AreaTriggerFields.SpellId, spell.Id);
|
||||
SetUInt32Value(AreaTriggerFields.SpellForVisuals, spell.Id);
|
||||
SetUInt32Value(AreaTriggerFields.SpellXSpellVisualId, spellXSpellVisualId);
|
||||
SetUInt32Value(AreaTriggerFields.TimeToTargetScale, GetMiscTemplate().TimeToTargetScale != 0 ? GetMiscTemplate().TimeToTargetScale : GetUInt32Value(AreaTriggerFields.Duration));
|
||||
SetFloatValue(AreaTriggerFields.BoundsRadius2d, GetTemplate().MaxSearchRadius);
|
||||
SetUInt32Value(AreaTriggerFields.DecalPropertiesId, GetMiscTemplate().DecalPropertiesId);
|
||||
SetUpdateFieldValue(m_values.ModifyValue(m_areaTriggerData).ModifyValue(m_areaTriggerData.SpellID), spell.Id);
|
||||
SetUpdateFieldValue(m_values.ModifyValue(m_areaTriggerData).ModifyValue(m_areaTriggerData.SpellForVisuals), spell.Id);
|
||||
SetUpdateFieldValue(m_values.ModifyValue(m_areaTriggerData).ModifyValue(m_areaTriggerData.SpellXSpellVisualID), spellXSpellVisualId);
|
||||
SetUpdateFieldValue(m_values.ModifyValue(m_areaTriggerData).ModifyValue(m_areaTriggerData.TimeToTargetScale), GetMiscTemplate().TimeToTargetScale != 0 ? GetMiscTemplate().TimeToTargetScale : m_areaTriggerData.Duration);
|
||||
SetUpdateFieldValue(m_values.ModifyValue(m_areaTriggerData).ModifyValue(m_areaTriggerData.BoundsRadius2D), GetTemplate().MaxSearchRadius);
|
||||
SetUpdateFieldValue(m_values.ModifyValue(m_areaTriggerData).ModifyValue(m_areaTriggerData.DecalPropertiesID), GetMiscTemplate().DecalPropertiesId);
|
||||
|
||||
ScaleCurve extraScaleCurve = m_areaTriggerData.ModifyValue(m_areaTriggerData.ExtraScaleCurve);
|
||||
|
||||
if (GetMiscTemplate().ExtraScale.Structured.StartTimeOffset != 0)
|
||||
SetUpdateFieldValue(ref extraScaleCurve.StartTimeOffset, GetMiscTemplate().ExtraScale.Structured.StartTimeOffset);
|
||||
if (GetMiscTemplate().ExtraScale.Structured.X != 0 || GetMiscTemplate().ExtraScale.Structured.Y != 0)
|
||||
{
|
||||
Vector2 point = new Vector2(GetMiscTemplate().ExtraScale.Structured.X, GetMiscTemplate().ExtraScale.Structured.Y);
|
||||
SetUpdateFieldValue(ref extraScaleCurve.Points[0], point);
|
||||
}
|
||||
if (GetMiscTemplate().ExtraScale.Structured.Z != 0 || GetMiscTemplate().ExtraScale.Structured.W != 0)
|
||||
{
|
||||
Vector2 point = new Vector2(GetMiscTemplate().ExtraScale.Structured.Z, GetMiscTemplate().ExtraScale.Structured.W);
|
||||
SetUpdateFieldValue(ref extraScaleCurve.Points[1], point);
|
||||
}
|
||||
if (GetMiscTemplate().ExtraScale.Raw.Data[5] != 0)
|
||||
SetUpdateFieldValue(ref extraScaleCurve.ParameterCurve, GetMiscTemplate().ExtraScale.Raw.Data[5]);
|
||||
if (GetMiscTemplate().ExtraScale.Structured.OverrideActive != 0)
|
||||
SetUpdateFieldValue(ref extraScaleCurve.OverrideActive, GetMiscTemplate().ExtraScale.Structured.OverrideActive != 0 ? true : false);
|
||||
|
||||
for (byte scaleCurveIndex = 0; scaleCurveIndex < SharedConst.MaxAreatriggerScale; ++scaleCurveIndex)
|
||||
if (GetMiscTemplate().ExtraScale.Raw.Data[scaleCurveIndex] != 0)
|
||||
SetUInt32Value(AreaTriggerFields.ExtraScaleCurve + scaleCurveIndex, (uint)GetMiscTemplate().ExtraScale.Raw.Data[scaleCurveIndex]);
|
||||
|
||||
PhasingHandler.InheritPhaseShift(this, caster);
|
||||
|
||||
@@ -137,7 +154,7 @@ namespace Game.Entities
|
||||
|
||||
UpdateShape();
|
||||
|
||||
uint timeToTarget = GetMiscTemplate().TimeToTarget != 0 ? GetMiscTemplate().TimeToTarget : GetUInt32Value(AreaTriggerFields.Duration);
|
||||
uint timeToTarget = GetMiscTemplate().TimeToTarget != 0 ? GetMiscTemplate().TimeToTarget : m_areaTriggerData.Duration;
|
||||
|
||||
if (GetTemplate().HasFlag(AreaTriggerFlags.HasCircularMovement))
|
||||
{
|
||||
@@ -234,7 +251,7 @@ namespace Game.Entities
|
||||
_totalDuration = newDuration;
|
||||
|
||||
// negative duration (permanent areatrigger) sent as 0
|
||||
SetUInt32Value(AreaTriggerFields.Duration, (uint)Math.Max(newDuration, 0));
|
||||
SetUpdateFieldValue(m_values.ModifyValue(m_areaTriggerData).ModifyValue(m_areaTriggerData.Duration), (uint)Math.Max(newDuration, 0));
|
||||
}
|
||||
|
||||
void _UpdateDuration(int newDuration)
|
||||
@@ -242,7 +259,8 @@ namespace Game.Entities
|
||||
_duration = newDuration;
|
||||
|
||||
// should be sent in object create packets only
|
||||
updateValues[(int)AreaTriggerFields.Duration].SignedValue = _duration;
|
||||
SetUpdateFieldValue(m_values.ModifyValue(m_areaTriggerData).ModifyValue(m_areaTriggerData.Duration), (uint)_duration);
|
||||
m_areaTriggerData.ClearChanged(m_areaTriggerData.Duration);
|
||||
}
|
||||
|
||||
float GetProgress()
|
||||
@@ -619,7 +637,8 @@ namespace Game.Entities
|
||||
_spline.initLengths();
|
||||
|
||||
// should be sent in object create packets only
|
||||
updateValues[(int)AreaTriggerFields.TimeToTarget].UnsignedValue = timeToTarget;
|
||||
SetUpdateFieldValue(m_values.ModifyValue(m_areaTriggerData).ModifyValue(m_areaTriggerData.TimeToTarget), timeToTarget);
|
||||
m_areaTriggerData.ClearChanged(m_areaTriggerData.TimeToTarget);
|
||||
|
||||
if (IsInWorld)
|
||||
{
|
||||
@@ -648,7 +667,8 @@ namespace Game.Entities
|
||||
Cypher.Assert(cmi.Center.HasValue || cmi.PathTarget.HasValue);
|
||||
|
||||
// should be sent in object create packets only
|
||||
updateValues[(int)AreaTriggerFields.TimeToTarget].UnsignedValue = timeToTarget;
|
||||
SetUpdateFieldValue(m_values.ModifyValue(m_areaTriggerData).ModifyValue(m_areaTriggerData.TimeToTarget), timeToTarget);
|
||||
m_areaTriggerData.ClearChanged(m_areaTriggerData.TimeToTarget);
|
||||
|
||||
_circularMovementInfo.Set(cmi);
|
||||
|
||||
@@ -822,6 +842,41 @@ namespace Game.Entities
|
||||
_ai = null;
|
||||
}
|
||||
|
||||
public override void BuildValuesCreate(WorldPacket data, Player target)
|
||||
{
|
||||
UpdateFieldFlag flags = GetUpdateFieldFlagsFor(target);
|
||||
WorldPacket buffer = new WorldPacket();
|
||||
|
||||
buffer.WriteUInt8((byte)flags);
|
||||
m_objectData.WriteCreate(buffer, flags, this, target);
|
||||
m_areaTriggerData.WriteCreate(buffer, flags, this, target);
|
||||
|
||||
data.WriteUInt32(buffer.GetSize());
|
||||
data.WriteBytes(buffer);
|
||||
}
|
||||
|
||||
public override void BuildValuesUpdate(WorldPacket data, Player target)
|
||||
{
|
||||
UpdateFieldFlag flags = GetUpdateFieldFlagsFor(target);
|
||||
WorldPacket buffer = new WorldPacket();
|
||||
|
||||
buffer.WriteUInt32(m_values.GetChangedObjectTypeMask());
|
||||
if (m_values.HasChanged(TypeId.Object))
|
||||
m_objectData.WriteUpdate(buffer, flags, this, target);
|
||||
|
||||
if (m_values.HasChanged(TypeId.AreaTrigger))
|
||||
m_areaTriggerData.WriteUpdate(buffer, flags, this, target);
|
||||
|
||||
data.WriteUInt32(buffer.GetSize());
|
||||
data.WriteBytes(buffer);
|
||||
}
|
||||
|
||||
public override void ClearUpdateMask(bool remove)
|
||||
{
|
||||
m_values.ClearChangesMask(m_areaTriggerData);
|
||||
base.ClearUpdateMask(remove);
|
||||
}
|
||||
|
||||
AreaTriggerAI GetAI() { return _ai; }
|
||||
|
||||
[System.Diagnostics.Conditional("DEBUG")]
|
||||
@@ -838,11 +893,11 @@ namespace Game.Entities
|
||||
}
|
||||
|
||||
public bool IsRemoved() { return _isRemoved; }
|
||||
public uint GetSpellId() { return GetUInt32Value(AreaTriggerFields.SpellId); }
|
||||
public uint GetSpellId() { return m_areaTriggerData.SpellID; }
|
||||
public AuraEffect GetAuraEffect() { return _aurEff; }
|
||||
public uint GetTimeSinceCreated() { return _timeSinceCreated; }
|
||||
public uint GetTimeToTarget() { return GetUInt32Value(AreaTriggerFields.TimeToTarget); }
|
||||
public uint GetTimeToTargetScale() { return GetUInt32Value(AreaTriggerFields.TimeToTargetScale); }
|
||||
public uint GetTimeToTarget() { return m_areaTriggerData.TimeToTarget; }
|
||||
public uint GetTimeToTargetScale() { return m_areaTriggerData.TimeToTargetScale; }
|
||||
public int GetDuration() { return _duration; }
|
||||
public int GetTotalDuration() { return _totalDuration; }
|
||||
|
||||
@@ -852,7 +907,7 @@ namespace Game.Entities
|
||||
|
||||
public AreaTriggerMiscTemplate GetMiscTemplate() { return _areaTriggerMiscTemplate; }
|
||||
|
||||
public ObjectGuid GetCasterGuid() { return GetGuidValue(AreaTriggerFields.Caster); }
|
||||
public ObjectGuid GetCasterGuid() { return m_areaTriggerData.Caster; }
|
||||
|
||||
public Vector3 GetRollPitchYaw() { return _rollPitchYaw; }
|
||||
public Vector3 GetTargetRollPitchYaw() { return _targetRollPitchYaw; }
|
||||
@@ -863,6 +918,8 @@ namespace Game.Entities
|
||||
|
||||
public Optional<AreaTriggerCircularMovementInfo> GetCircularMovementInfo() { return _circularMovementInfo; }
|
||||
|
||||
AreaTriggerFieldData m_areaTriggerData;
|
||||
|
||||
ObjectGuid _targetGuid;
|
||||
|
||||
AuraEffect _aurEff;
|
||||
|
||||
@@ -104,10 +104,19 @@ namespace Game.Entities
|
||||
public uint StartTimeOffset;
|
||||
|
||||
[FieldOffset(4)]
|
||||
public float[] Points;
|
||||
public float X;
|
||||
|
||||
[FieldOffset(8)]
|
||||
public float Y;
|
||||
|
||||
[FieldOffset(12)]
|
||||
public float Z;
|
||||
|
||||
[FieldOffset(16)]
|
||||
public float W;
|
||||
|
||||
[FieldOffset(20)]
|
||||
public curveparameters CurveParameters;
|
||||
public uint CurveParameters;
|
||||
|
||||
[FieldOffset(24)]
|
||||
public uint OverrideActive;
|
||||
|
||||
@@ -20,6 +20,7 @@ using Game.DataStorage;
|
||||
using Game.Maps;
|
||||
using Game.Spells;
|
||||
using System.Collections.Generic;
|
||||
using Game.Network;
|
||||
|
||||
namespace Game.Entities
|
||||
{
|
||||
@@ -35,8 +36,7 @@ namespace Game.Entities
|
||||
m_updateFlag.Stationary = true;
|
||||
m_updateFlag.Conversation = true;
|
||||
|
||||
valuesCount = (int)ConversationFields.End;
|
||||
_dynamicValuesCount = (int)ConversationDynamicFields.End;
|
||||
m_conversationData = new ConversationData();
|
||||
}
|
||||
|
||||
public override void AddToWorld()
|
||||
@@ -117,7 +117,7 @@ namespace Game.Entities
|
||||
SetEntry(conversationEntry);
|
||||
SetObjectScale(1.0f);
|
||||
|
||||
SetUInt32Value(ConversationFields.LastLineEndTime, conversationTemplate.LastLineEndTime);
|
||||
SetUpdateFieldValue(m_values.ModifyValue(m_conversationData).ModifyValue(m_conversationData.LastLineEndTime), conversationTemplate.LastLineEndTime);
|
||||
_duration = conversationTemplate.LastLineEndTime;
|
||||
_textureKitId = conversationTemplate.TextureKitId;
|
||||
|
||||
@@ -126,11 +126,12 @@ namespace Game.Entities
|
||||
ConversationActorTemplate actor = conversationTemplate.Actors[actorIndex];
|
||||
if (actor != null)
|
||||
{
|
||||
ConversationDynamicFieldActor actorField = new ConversationDynamicFieldActor();
|
||||
actorField.ActorTemplate.CreatureId = actor.CreatureId;
|
||||
actorField.ActorTemplate.CreatureModelId = actor.CreatureModelId;
|
||||
actorField.Type = ConversationDynamicFieldActor.ActorType.CreatureActor;
|
||||
SetDynamicStructuredValue(ConversationDynamicFields.Actors, actorIndex, actorField);
|
||||
ConversationActor actorField = new ConversationActor();
|
||||
actorField.CreatureID = actor.CreatureId;
|
||||
actorField.CreatureDisplayInfoID = actor.CreatureModelId;
|
||||
actorField.Type = ConversationActorType.CreatureActor;
|
||||
|
||||
AddDynamicUpdateFieldValue(m_values.ModifyValue(m_conversationData).ModifyValue(m_conversationData.Actors), actorField);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -150,17 +151,30 @@ namespace Game.Entities
|
||||
Global.ScriptMgr.OnConversationCreate(this, creator);
|
||||
|
||||
List<ushort> actorIndices = new List<ushort>();
|
||||
List<ConversationLine> lines = new List<ConversationLine>();
|
||||
foreach (ConversationLineTemplate line in conversationTemplate.Lines)
|
||||
{
|
||||
actorIndices.Add(line.ActorIdx);
|
||||
AddDynamicStructuredValue(ConversationDynamicFields.Lines, line);
|
||||
|
||||
ConversationLine lineField = new ConversationLine();
|
||||
lineField.ConversationLineID = line.Id;
|
||||
lineField.StartTime = line.StartTime;
|
||||
lineField.UiCameraID = line.UiCameraID;
|
||||
lineField.ActorIndex = line.ActorIdx;
|
||||
lineField.Flags = line.Flags;
|
||||
|
||||
lines.Add(lineField);
|
||||
}
|
||||
|
||||
SetUpdateFieldValue(m_values.ModifyValue(m_conversationData).ModifyValue(m_conversationData.Lines), lines);
|
||||
|
||||
Global.ScriptMgr.OnConversationCreate(this, creator);
|
||||
|
||||
// All actors need to be set
|
||||
foreach (ushort actorIndex in actorIndices)
|
||||
{
|
||||
ConversationDynamicFieldActor actor = GetDynamicStructuredValue<ConversationDynamicFieldActor>(ConversationDynamicFields.Actors, actorIndex);
|
||||
if (actor == null || actor.IsEmpty())
|
||||
ConversationActor actor = actorIndex < m_conversationData.Actors.Size() ? m_conversationData.Actors[actorIndex] : null;
|
||||
if (actor == null || (actor.CreatureID == 0 && actor.ActorGUID.IsEmpty()))
|
||||
{
|
||||
Log.outError(LogFilter.Conversation, $"Failed to create conversation (Id: {conversationEntry}) due to missing actor (Idx: {actorIndex}).");
|
||||
return false;
|
||||
@@ -175,10 +189,9 @@ namespace Game.Entities
|
||||
|
||||
void AddActor(ObjectGuid actorGuid, ushort actorIdx)
|
||||
{
|
||||
ConversationDynamicFieldActor actorField = new ConversationDynamicFieldActor();
|
||||
actorField.ActorGuid = actorGuid;
|
||||
actorField.Type = ConversationDynamicFieldActor.ActorType.WorldObjectActor;
|
||||
SetDynamicStructuredValue(ConversationDynamicFields.Actors, actorIdx, actorField);
|
||||
ConversationActor actorField = m_values.ModifyValue(m_conversationData).ModifyValue(m_conversationData.Actors, actorIdx);
|
||||
SetUpdateFieldValue(ref actorField.ActorGUID, actorGuid);
|
||||
SetUpdateFieldValue(ref actorField.Type, ConversationActorType.WorldObjectActor);
|
||||
}
|
||||
|
||||
void AddParticipant(ObjectGuid participantGuid)
|
||||
@@ -191,6 +204,41 @@ namespace Game.Entities
|
||||
return Global.ConversationDataStorage.GetConversationTemplate(GetEntry()).ScriptId;
|
||||
}
|
||||
|
||||
public override void BuildValuesCreate(WorldPacket data, Player target)
|
||||
{
|
||||
UpdateFieldFlag flags = GetUpdateFieldFlagsFor(target);
|
||||
WorldPacket buffer = new WorldPacket();
|
||||
|
||||
m_objectData.WriteCreate(buffer, flags, this, target);
|
||||
m_conversationData.WriteCreate(buffer, flags, this, target);
|
||||
|
||||
data.WriteUInt32(buffer.GetSize());
|
||||
data.WriteUInt8((byte)flags);
|
||||
data.WriteBytes(buffer);
|
||||
}
|
||||
|
||||
public override void BuildValuesUpdate(WorldPacket data, Player target)
|
||||
{
|
||||
UpdateFieldFlag flags = GetUpdateFieldFlagsFor(target);
|
||||
WorldPacket buffer = new WorldPacket();
|
||||
|
||||
buffer.WriteUInt32(m_values.GetChangedObjectTypeMask());
|
||||
if (m_values.HasChanged(TypeId.Object))
|
||||
m_objectData.WriteUpdate(buffer, flags, this, target);
|
||||
|
||||
if (m_values.HasChanged(TypeId.Conversation))
|
||||
m_conversationData.WriteUpdate(buffer, flags, this, target);
|
||||
|
||||
data.WriteUInt32(buffer.GetSize());
|
||||
data.WriteBytes(buffer);
|
||||
}
|
||||
|
||||
public override void ClearUpdateMask(bool remove)
|
||||
{
|
||||
m_values.ClearChangesMask(m_conversationData);
|
||||
base.ClearUpdateMask(remove);
|
||||
}
|
||||
|
||||
uint GetDuration() { return _duration; }
|
||||
public uint GetTextureKitId() { return _textureKitId; }
|
||||
|
||||
@@ -202,35 +250,12 @@ namespace Game.Entities
|
||||
public override float GetStationaryO() { return _stationaryPosition.GetOrientation(); }
|
||||
void RelocateStationaryPosition(Position pos) { _stationaryPosition.Relocate(pos); }
|
||||
|
||||
ConversationData m_conversationData;
|
||||
|
||||
Position _stationaryPosition = new Position();
|
||||
ObjectGuid _creatorGuid;
|
||||
uint _duration;
|
||||
uint _textureKitId;
|
||||
List<ObjectGuid> _participants = new List<ObjectGuid>();
|
||||
}
|
||||
|
||||
class ConversationDynamicFieldActor
|
||||
{
|
||||
public enum ActorType
|
||||
{
|
||||
WorldObjectActor = 0,
|
||||
CreatureActor = 1
|
||||
}
|
||||
|
||||
public bool IsEmpty()
|
||||
{
|
||||
return ActorGuid.IsEmpty(); // this one is good enough
|
||||
}
|
||||
|
||||
public ObjectGuid ActorGuid;
|
||||
public ActorTemplateStruct ActorTemplate;
|
||||
|
||||
public struct ActorTemplateStruct
|
||||
{
|
||||
public uint CreatureId;
|
||||
public uint CreatureModelId;
|
||||
}
|
||||
|
||||
public ActorType Type;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,6 +21,9 @@ using Game.DataStorage;
|
||||
using Game.Loots;
|
||||
using Game.Maps;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Framework.Collections;
|
||||
using Game.Network;
|
||||
|
||||
namespace Game.Entities
|
||||
{
|
||||
@@ -34,7 +37,7 @@ namespace Game.Entities
|
||||
|
||||
m_updateFlag.Stationary = true;
|
||||
|
||||
valuesCount = (int)CorpseFields.End;
|
||||
m_corpseData = new CorpseData();
|
||||
|
||||
m_time = Time.UnixTime;
|
||||
}
|
||||
@@ -79,7 +82,7 @@ namespace Game.Entities
|
||||
_Create(ObjectGuid.Create(HighGuid.Corpse, owner.GetMapId(), 0, guidlow));
|
||||
|
||||
SetObjectScale(1);
|
||||
SetGuidValue(CorpseFields.Owner, owner.GetGUID());
|
||||
SetOwnerGUID(owner.GetGUID());
|
||||
|
||||
_cellCoord = GridDefines.ComputeCellCoord(GetPositionX(), GetPositionY());
|
||||
|
||||
@@ -94,6 +97,14 @@ namespace Game.Entities
|
||||
SQLTransaction trans = new SQLTransaction();
|
||||
DeleteFromDB(trans);
|
||||
|
||||
StringBuilder items = new StringBuilder();
|
||||
for (var i = 0; i < EquipmentSlot.End; ++i)
|
||||
items.Append($"{m_corpseData.Items[i]} ");
|
||||
|
||||
uint bytes1 = ((uint)m_corpseData.RaceID << 8) | ((uint)m_corpseData.Sex << 16) | ((uint)m_corpseData.SkinID << 24);
|
||||
uint bytes2 = ((uint)m_corpseData.FaceID) | ((uint)m_corpseData.HairStyleID << 8) | ((uint)m_corpseData.HairColorID << 16) | ((uint)m_corpseData.FacialHairStyleID << 24);
|
||||
|
||||
|
||||
byte index = 0;
|
||||
PreparedStatement stmt = DB.Characters.GetPreparedStatement(CharStatements.INS_CORPSE);
|
||||
stmt.AddValue(index++, GetOwnerGUID().GetCounter()); // guid
|
||||
@@ -102,14 +113,14 @@ namespace Game.Entities
|
||||
stmt.AddValue(index++, GetPositionZ()); // posZ
|
||||
stmt.AddValue(index++, GetOrientation()); // orientation
|
||||
stmt.AddValue(index++, GetMapId()); // mapId
|
||||
stmt.AddValue(index++, GetUInt32Value(CorpseFields.DisplayId)); // displayId
|
||||
stmt.AddValue(index++, _ConcatFields(CorpseFields.Item, EquipmentSlot.End)); // itemCache
|
||||
stmt.AddValue(index++, GetUInt32Value(CorpseFields.Bytes1)); // bytes1
|
||||
stmt.AddValue(index++, GetUInt32Value(CorpseFields.Bytes2)); // bytes2
|
||||
stmt.AddValue(index++, GetUInt32Value(CorpseFields.Flags)); // flags
|
||||
stmt.AddValue(index++, GetUInt32Value(CorpseFields.DynamicFlags)); // dynFlags
|
||||
stmt.AddValue(index++, (uint)m_time); // time
|
||||
stmt.AddValue(index++, (uint)GetCorpseType()); // corpseType
|
||||
stmt.AddValue(index++, (uint)m_corpseData.DisplayID); // displayId
|
||||
stmt.AddValue(index++, items.ToString()); // itemCache
|
||||
stmt.AddValue(index++, bytes1); // bytes1
|
||||
stmt.AddValue(index++, bytes2); // bytes2
|
||||
stmt.AddValue(index++, (uint)m_corpseData.Flags); // flags
|
||||
stmt.AddValue(index++, (uint)m_corpseData.DynamicFlags); // dynFlags
|
||||
stmt.AddValue(index++, (uint)m_time); // time
|
||||
stmt.AddValue(index++, (uint)GetCorpseType()); // corpseType
|
||||
stmt.AddValue(index++, GetInstanceId()); // instanceId
|
||||
trans.Append(stmt);
|
||||
|
||||
@@ -153,16 +164,24 @@ namespace Game.Entities
|
||||
_Create(ObjectGuid.Create(HighGuid.Corpse, mapId, 0, guid));
|
||||
|
||||
SetObjectScale(1.0f);
|
||||
SetUInt32Value(CorpseFields.DisplayId, field.Read<uint>(5));
|
||||
_LoadIntoDataField(field.Read<string>(6), (int)CorpseFields.Item, EquipmentSlot.End);
|
||||
SetUInt32Value(CorpseFields.Bytes1, field.Read<uint>(7));
|
||||
SetUInt32Value(CorpseFields.Bytes2, field.Read<uint>(8));
|
||||
SetUInt32Value(CorpseFields.Flags, field.Read<byte>(9));
|
||||
SetUInt32Value(CorpseFields.DynamicFlags, field.Read<byte>(10));
|
||||
SetGuidValue(CorpseFields.Owner, ObjectGuid.Create(HighGuid.Player, field.Read<ulong>(14)));
|
||||
CharacterInfo characterInfo = Global.WorldMgr.GetCharacterInfo(GetGuidValue(CorpseFields.Owner));
|
||||
if (characterInfo != null)
|
||||
SetUInt32Value(CorpseFields.FactionTemplate, CliDB.ChrRacesStorage.LookupByKey(characterInfo.RaceID).FactionID);
|
||||
SetDisplayId(field.Read<uint>(5));
|
||||
StringArray items = new StringArray(field.Read<string>(6), ' ');
|
||||
for (uint index = 0; index < EquipmentSlot.End; ++index)
|
||||
SetItem(index, uint.Parse(items[(int)index]));
|
||||
|
||||
uint bytes1 = field.Read<uint>(7);
|
||||
uint bytes2 = field.Read<uint>(8);
|
||||
SetRace((Race)((bytes1 >> 8) & 0xFF));
|
||||
SetSex((Gender)((bytes1 >> 16) & 0xFF));
|
||||
SetSkin((byte)((bytes1 >> 24) & 0xFF));
|
||||
SetFace((byte)(bytes2 & 0xFF));
|
||||
SetHairStyle((byte)((bytes2 >> 8) & 0xFF));
|
||||
SetHairColor((byte)((bytes2 >> 16) & 0xFF));
|
||||
SetFacialHairStyle((byte)((bytes2 >> 24) & 0xFF));
|
||||
SetFlags((CorpseFlags)field.Read<byte>(9));
|
||||
SetCorpseDynamicFlags((CorpseDynFlags)field.Read<byte>(10));
|
||||
SetOwnerGUID(ObjectGuid.Create(HighGuid.Player, field.Read<ulong>(14)));
|
||||
SetFactionTemplate(CliDB.ChrRacesStorage.LookupByKey(m_corpseData.RaceID).FactionID);
|
||||
|
||||
m_time = field.Read<uint>(11);
|
||||
|
||||
@@ -196,7 +215,60 @@ namespace Game.Entities
|
||||
return m_time < t - 3 * Time.Day;
|
||||
}
|
||||
|
||||
public ObjectGuid GetOwnerGUID() { return GetGuidValue(CorpseFields.Owner); }
|
||||
public override void BuildValuesCreate(WorldPacket data, Player target)
|
||||
{
|
||||
UpdateFieldFlag flags = GetUpdateFieldFlagsFor(target);
|
||||
WorldPacket buffer = new WorldPacket();
|
||||
|
||||
m_objectData.WriteCreate(buffer, flags, this, target);
|
||||
m_corpseData.WriteCreate(buffer, flags, this, target);
|
||||
|
||||
data.WriteUInt32(buffer.GetSize());
|
||||
data.WriteUInt8((byte)flags);
|
||||
data.WriteBytes(buffer);
|
||||
}
|
||||
|
||||
public override void BuildValuesUpdate(WorldPacket data, Player target)
|
||||
{
|
||||
UpdateFieldFlag flags = GetUpdateFieldFlagsFor(target);
|
||||
WorldPacket buffer = new WorldPacket();
|
||||
|
||||
buffer.WriteUInt32(m_values.GetChangedObjectTypeMask());
|
||||
if (m_values.HasChanged(TypeId.Object))
|
||||
m_objectData.WriteUpdate(buffer, flags, this, target);
|
||||
|
||||
if (m_values.HasChanged(TypeId.Corpse))
|
||||
m_corpseData.WriteUpdate(buffer, flags, this, target);
|
||||
|
||||
data.WriteUInt32(buffer.GetSize());
|
||||
data.WriteBytes(buffer);
|
||||
}
|
||||
|
||||
public override void ClearUpdateMask(bool remove)
|
||||
{
|
||||
m_values.ClearChangesMask(m_corpseData);
|
||||
base.ClearUpdateMask(remove);
|
||||
}
|
||||
|
||||
public void AddCorpseDynamicFlag(CorpseDynFlags dynamicFlags) { SetUpdateFieldFlagValue(m_values.ModifyValue(m_corpseData).ModifyValue(m_corpseData.DynamicFlags), (uint)dynamicFlags); }
|
||||
public void RemoveCorpseDynamicFlag(CorpseDynFlags dynamicFlags) { RemoveUpdateFieldFlagValue(m_values.ModifyValue(m_corpseData).ModifyValue(m_corpseData.DynamicFlags), (uint)dynamicFlags); }
|
||||
public void SetCorpseDynamicFlags(CorpseDynFlags dynamicFlags) { SetUpdateFieldValue(m_values.ModifyValue(m_corpseData).ModifyValue(m_corpseData.DynamicFlags), (uint)dynamicFlags); }
|
||||
public ObjectGuid GetOwnerGUID() { return m_corpseData.Owner; }
|
||||
public void SetOwnerGUID(ObjectGuid owner) { SetUpdateFieldValue(m_values.ModifyValue(m_corpseData).ModifyValue(m_corpseData.Owner), owner); }
|
||||
public void SetPartyGUID(ObjectGuid partyGuid) { SetUpdateFieldValue(m_values.ModifyValue(m_corpseData).ModifyValue(m_corpseData.PartyGUID), partyGuid); }
|
||||
public void SetGuildGUID(ObjectGuid guildGuid) { SetUpdateFieldValue(m_values.ModifyValue(m_corpseData).ModifyValue(m_corpseData.GuildGUID), guildGuid); }
|
||||
public void SetDisplayId(uint displayId) { SetUpdateFieldValue(m_values.ModifyValue(m_corpseData).ModifyValue(m_corpseData.DisplayID), displayId); }
|
||||
public void SetRace(Race race) { SetUpdateFieldValue(m_values.ModifyValue(m_corpseData).ModifyValue(m_corpseData.RaceID), (byte)race); }
|
||||
public void SetSex(Gender sex) { SetUpdateFieldValue(m_values.ModifyValue(m_corpseData).ModifyValue(m_corpseData.Sex), (byte)sex); }
|
||||
public void SetSkin(byte skin) { SetUpdateFieldValue(m_values.ModifyValue(m_corpseData).ModifyValue(m_corpseData.SkinID), skin); }
|
||||
public void SetFace(byte face) { SetUpdateFieldValue(m_values.ModifyValue(m_corpseData).ModifyValue(m_corpseData.FaceID), face); }
|
||||
public void SetHairStyle(byte hairStyle) { SetUpdateFieldValue(m_values.ModifyValue(m_corpseData).ModifyValue(m_corpseData.HairStyleID), hairStyle); }
|
||||
public void SetHairColor(byte hairColor) { SetUpdateFieldValue(m_values.ModifyValue(m_corpseData).ModifyValue(m_corpseData.HairColorID), hairColor); }
|
||||
public void SetFacialHairStyle(byte facialHairStyle) { SetUpdateFieldValue(m_values.ModifyValue(m_corpseData).ModifyValue(m_corpseData.FacialHairStyleID), facialHairStyle); }
|
||||
public void SetFlags(CorpseFlags flags) { SetUpdateFieldValue(m_values.ModifyValue(m_corpseData).ModifyValue(m_corpseData.Flags), (uint)flags); }
|
||||
public void SetFactionTemplate(int factionTemplate) { SetUpdateFieldValue(m_values.ModifyValue(m_corpseData).ModifyValue(m_corpseData.FactionTemplate), factionTemplate); }
|
||||
public void SetItem(uint slot, uint item) { SetUpdateFieldValue(ref m_values.ModifyValue(m_corpseData).ModifyValue(m_corpseData.Items, (int)slot), item); }
|
||||
public void SetCustomDisplayOption(uint slot, byte customDisplayOption) { SetUpdateFieldValue(ref m_values.ModifyValue(m_corpseData).ModifyValue(m_corpseData.CustomDisplayOption, (int)slot), customDisplayOption); }
|
||||
|
||||
public long GetGhostTime() { return m_time; }
|
||||
public void ResetGhostTime() { m_time = Time.UnixTime; }
|
||||
@@ -205,6 +277,8 @@ namespace Game.Entities
|
||||
public CellCoord GetCellCoord() { return _cellCoord; }
|
||||
public void SetCellCoord(CellCoord cellCoord) { _cellCoord = cellCoord; }
|
||||
|
||||
public CorpseData m_corpseData;
|
||||
|
||||
public Loot loot = new Loot();
|
||||
public Player lootRecipient;
|
||||
public bool lootForBody;
|
||||
|
||||
@@ -46,8 +46,6 @@ namespace Game.Entities
|
||||
m_meleeDamageSchoolMask = SpellSchoolMask.Normal;
|
||||
|
||||
m_regenTimer = SharedConst.CreatureRegenInterval;
|
||||
valuesCount = (int)UnitFields.End;
|
||||
_dynamicValuesCount = (int)UnitDynamicFields.End;
|
||||
|
||||
m_SightDistance = SharedConst.SightRangeUnit;
|
||||
|
||||
@@ -192,9 +190,8 @@ namespace Game.Entities
|
||||
m_creatureInfo = cinfo; // map mode related always
|
||||
|
||||
// equal to player Race field, but creature does not have race
|
||||
SetByteValue(UnitFields.Bytes0, 0, 0);
|
||||
|
||||
SetByteValue(UnitFields.Bytes0, 1, (byte)cinfo.UnitClass);
|
||||
SetRace(0);
|
||||
SetClass((Class)cinfo.UnitClass);
|
||||
|
||||
// Cancel load if no model defined
|
||||
if (cinfo.GetFirstValidModel() == null)
|
||||
@@ -213,7 +210,7 @@ namespace Game.Entities
|
||||
|
||||
SetDisplayId(model.CreatureDisplayID, model.DisplayScale);
|
||||
SetNativeDisplayId(model.CreatureDisplayID, model.DisplayScale);
|
||||
SetByteValue(UnitFields.Bytes0, 3, (byte)minfo.gender);
|
||||
SetGender((Gender)minfo.gender);
|
||||
|
||||
// Load creature equipment
|
||||
if (data == null || data.equipmentId == 0)
|
||||
@@ -226,12 +223,12 @@ namespace Game.Entities
|
||||
|
||||
SetName(normalInfo.Name); // at normal entry always
|
||||
|
||||
SetFloatValue(UnitFields.ModCastSpeed, 1.0f);
|
||||
SetFloatValue(UnitFields.ModCastHaste, 1.0f);
|
||||
SetFloatValue(UnitFields.ModHaste, 1.0f);
|
||||
SetFloatValue(UnitFields.ModRangedHaste, 1.0f);
|
||||
SetFloatValue(UnitFields.ModHasteRegen, 1.0f);
|
||||
SetFloatValue(UnitFields.ModTimeRate, 1.0f);
|
||||
SetModCastingSpeed(1.0f);
|
||||
SetModSpellHaste(1.0f);
|
||||
SetModHaste(1.0f);
|
||||
SetModRangedHaste(1.0f);
|
||||
SetModHasteRegen(1.0f);
|
||||
SetModTimeRate(1.0f);
|
||||
|
||||
SetSpeedRate(UnitMoveType.Walk, cinfo.SpeedWalk);
|
||||
SetSpeedRate(UnitMoveType.Run, cinfo.SpeedRun);
|
||||
@@ -240,7 +237,7 @@ namespace Game.Entities
|
||||
|
||||
SetObjectScale(cinfo.Scale);
|
||||
|
||||
SetFloatValue(UnitFields.HoverHeight, cinfo.HoverHeight);
|
||||
SetHoverHeight(cinfo.HoverHeight);
|
||||
|
||||
// checked at loading
|
||||
m_defaultMovementType = (MovementGeneratorType)cinfo.MovementType;
|
||||
@@ -273,19 +270,20 @@ namespace Game.Entities
|
||||
ObjectManager.ChooseCreatureFlags(cInfo, out npcFlags, out unitFlags, out unitFlags2, out unitFlags3, out dynamicFlags, data);
|
||||
|
||||
if (cInfo.FlagsExtra.HasAnyFlag(CreatureFlagsExtra.Worldevent))
|
||||
SetUInt64Value(UnitFields.NpcFlags, npcFlags | Global.GameEventMgr.GetNPCFlag(this));
|
||||
else
|
||||
SetUInt64Value(UnitFields.NpcFlags, npcFlags);
|
||||
npcFlags |= Global.GameEventMgr.GetNPCFlag(this);
|
||||
|
||||
SetUInt32Value(UnitFields.Flags, unitFlags);
|
||||
SetUInt32Value(UnitFields.Flags2, unitFlags2);
|
||||
SetUInt32Value(UnitFields.Flags3, unitFlags3);
|
||||
SetNpcFlags((NPCFlags)(npcFlags & 0xFFFFFFFF));
|
||||
SetNpcFlags2((NPCFlags2)(npcFlags >> 32));
|
||||
|
||||
SetUInt32Value(ObjectFields.DynamicFlags, dynamicFlags);
|
||||
SetUnitFlags((UnitFlags)unitFlags);
|
||||
SetUnitFlags2((UnitFlags2)unitFlags2);
|
||||
SetUnitFlags3((UnitFlags3)unitFlags3);
|
||||
|
||||
SetUInt32Value(UnitFields.StateAnimId, (uint)CliDB.AnimationDataStorage.Count);
|
||||
SetDynamicFlags((UnitDynFlags)dynamicFlags);
|
||||
|
||||
RemoveFlag(UnitFields.Flags, UnitFlags.InCombat);
|
||||
SetUpdateFieldValue(m_values.ModifyValue(m_unitData).ModifyValue(m_unitData.StateAnimID), (uint)CliDB.AnimationDataStorage.Count);
|
||||
|
||||
RemoveUnitFlag(UnitFlags.InCombat);
|
||||
|
||||
SetBaseAttackTime(WeaponAttackType.BaseAttack, cInfo.BaseAttackTime);
|
||||
SetBaseAttackTime(WeaponAttackType.OffAttack, cInfo.BaseAttackTime);
|
||||
@@ -323,14 +321,14 @@ namespace Game.Entities
|
||||
Player owner = GetCharmerOrOwnerPlayerOrPlayerItself();
|
||||
if (owner != null) // this check comes in case we don't have a player
|
||||
{
|
||||
SetFaction(owner.getFaction()); // vehicles should have same as owner faction
|
||||
SetFaction(owner.GetFaction()); // vehicles should have same as owner faction
|
||||
owner.VehicleSpellInitialize();
|
||||
}
|
||||
}
|
||||
|
||||
// trigger creature is always not selectable and can not be attacked
|
||||
if (IsTrigger())
|
||||
SetFlag(UnitFields.Flags, UnitFlags.NotSelectable);
|
||||
AddUnitFlag(UnitFlags.NotSelectable);
|
||||
|
||||
InitializeReactState();
|
||||
|
||||
@@ -411,7 +409,7 @@ namespace Game.Entities
|
||||
else if (m_corpseRemoveTime <= Time.UnixTime)
|
||||
{
|
||||
RemoveCorpse(false);
|
||||
Log.outDebug(LogFilter.Unit, "Removing corpse... {0} ", GetUInt32Value(ObjectFields.Entry));
|
||||
Log.outDebug(LogFilter.Unit, "Removing corpse... {0} ", GetEntry());
|
||||
}
|
||||
break;
|
||||
case DeathState.Alive:
|
||||
@@ -519,7 +517,7 @@ namespace Game.Entities
|
||||
if (!IsInEvadeMode() && (!bInCombat || IsPolymorphed() || CanNotReachTarget())) // regenerate health if not in combat or if polymorphed
|
||||
RegenerateHealth();
|
||||
|
||||
if (HasFlag(UnitFields.Flags2, UnitFlags2.RegeneratePower))
|
||||
if (HasUnitFlag2(UnitFlags2.RegeneratePower))
|
||||
{
|
||||
if (GetPowerType() == PowerType.Energy)
|
||||
Regenerate(PowerType.Energy);
|
||||
@@ -798,7 +796,7 @@ namespace Game.Entities
|
||||
//! Need to be called after LoadCreaturesAddon - MOVEMENTFLAG_HOVER is set there
|
||||
if (HasUnitMovementFlag(MovementFlag.Hover))
|
||||
{
|
||||
z += GetFloatValue(UnitFields.HoverHeight);
|
||||
z += m_unitData.HoverHeight;
|
||||
|
||||
//! Relocate again with updated Z coord
|
||||
Relocate(x, y, z, ang);
|
||||
@@ -810,7 +808,7 @@ namespace Game.Entities
|
||||
{
|
||||
SetDisplayId(display.CreatureDisplayID, display.DisplayScale);
|
||||
SetNativeDisplayId(display.CreatureDisplayID, display.DisplayScale);
|
||||
SetByteValue(UnitFields.Bytes0, 3, (byte)minfo.gender);
|
||||
SetGender((Gender)minfo.gender);
|
||||
}
|
||||
|
||||
LastUsedScriptID = GetScriptId();
|
||||
@@ -956,7 +954,7 @@ namespace Game.Entities
|
||||
{
|
||||
m_lootRecipient.Clear();
|
||||
m_lootRecipientGroup.Clear();
|
||||
RemoveFlag(ObjectFields.DynamicFlags, UnitDynFlags.Lootable | UnitDynFlags.Tapped);
|
||||
RemoveDynamicFlag(UnitDynFlags.Lootable | UnitDynFlags.Tapped);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -972,7 +970,7 @@ namespace Game.Entities
|
||||
if (group)
|
||||
m_lootRecipientGroup = group.GetGUID();
|
||||
|
||||
SetFlag(ObjectFields.DynamicFlags, UnitDynFlags.Tapped);
|
||||
AddDynamicFlag(UnitDynFlags.Tapped);
|
||||
}
|
||||
|
||||
public bool isTappedBy(Player player)
|
||||
@@ -1011,11 +1009,11 @@ namespace Game.Entities
|
||||
CreatureData data = Global.ObjectMgr.NewOrExistCreatureData(m_spawnId);
|
||||
|
||||
uint displayId = GetNativeDisplayId();
|
||||
ulong npcflag = GetUInt64Value(UnitFields.NpcFlags);
|
||||
uint unitFlags = GetUInt32Value(UnitFields.Flags);
|
||||
uint unitFlags2 = GetUInt32Value(UnitFields.Flags2);
|
||||
uint unitFlags3 = GetUInt32Value(UnitFields.Flags3);
|
||||
uint dynamicflags = GetUInt32Value(ObjectFields.DynamicFlags);
|
||||
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;
|
||||
UnitDynFlags dynamicflags = (UnitDynFlags)(uint)m_objectData.DynamicFlags;
|
||||
|
||||
// check if it's a custom model and if not, use 0 for displayId
|
||||
CreatureTemplate cinfo = GetCreatureTemplate();
|
||||
@@ -1037,7 +1035,7 @@ namespace Game.Entities
|
||||
if (unitFlags3 == cinfo.UnitFlags3)
|
||||
unitFlags3 = 0;
|
||||
|
||||
if (dynamicflags == cinfo.DynamicFlags)
|
||||
if (dynamicflags == (UnitDynFlags)cinfo.DynamicFlags)
|
||||
dynamicflags = 0;
|
||||
}
|
||||
|
||||
@@ -1064,7 +1062,7 @@ namespace Game.Entities
|
||||
data.unit_flags = unitFlags;
|
||||
data.unit_flags2 = unitFlags2;
|
||||
data.unit_flags3 = unitFlags3;
|
||||
data.dynamicflags = dynamicflags;
|
||||
data.dynamicflags = (uint)dynamicflags;
|
||||
|
||||
data.phaseId = GetDBPhase() > 0 ? (uint)GetDBPhase() : data.phaseId;
|
||||
data.phaseGroup = GetDBPhase() < 0 ? (uint)-GetDBPhase() : data.phaseGroup;
|
||||
@@ -1119,14 +1117,14 @@ namespace Game.Entities
|
||||
|
||||
if (HasScalableLevels())
|
||||
{
|
||||
SetUInt32Value(UnitFields.ScalingLevelMin, cInfo.levelScaling.Value.MinLevel);
|
||||
SetUInt32Value(UnitFields.ScalingLevelMax, cInfo.levelScaling.Value.MaxLevel);
|
||||
SetUpdateFieldValue(m_values.ModifyValue(m_unitData).ModifyValue(m_unitData.ScalingLevelMin), cInfo.levelScaling.Value.MinLevel);
|
||||
SetUpdateFieldValue(m_values.ModifyValue(m_unitData).ModifyValue(m_unitData.ScalingLevelMax), cInfo.levelScaling.Value.MaxLevel);
|
||||
|
||||
int mindelta = Math.Min(cInfo.levelScaling.Value.DeltaLevelMax, cInfo.levelScaling.Value.DeltaLevelMin);
|
||||
int maxdelta = Math.Max(cInfo.levelScaling.Value.DeltaLevelMax, cInfo.levelScaling.Value.DeltaLevelMin);
|
||||
int delta = mindelta == maxdelta ? mindelta : RandomHelper.IRand(mindelta, maxdelta);
|
||||
|
||||
SetInt32Value(UnitFields.ScalingLevelDelta, delta);
|
||||
SetUpdateFieldValue(m_values.ModifyValue(m_unitData).ModifyValue(m_unitData.ScalingLevelDelta), delta);
|
||||
}
|
||||
|
||||
UpdateLevelDependantStats();
|
||||
@@ -1434,9 +1432,9 @@ namespace Game.Entities
|
||||
return false;
|
||||
|
||||
// This set of checks is should be done only for creatures
|
||||
if ((HasFlag(UnitFields.Flags, UnitFlags.ImmuneToNpc) && !who.IsTypeId(TypeId.Player)) // flag is valid only for non player characters
|
||||
|| (HasFlag(UnitFields.Flags, UnitFlags.ImmuneToPc) && who.IsTypeId(TypeId.Player)) // immune to PC and target is a player, return false
|
||||
|| (who.GetOwner() && who.GetOwner().IsTypeId(TypeId.Player) && HasFlag(UnitFields.Flags, UnitFlags.ImmuneToPc))) // player pets are immune to pc as well
|
||||
if ((HasUnitFlag(UnitFlags.ImmuneToNpc) && !who.IsTypeId(TypeId.Player)) // flag is valid only for non player characters
|
||||
|| (HasUnitFlag(UnitFlags.ImmuneToPc) && who.IsTypeId(TypeId.Player)) // immune to PC and target is a player, return false
|
||||
|| (who.GetOwner() && who.GetOwner().IsTypeId(TypeId.Player) && HasUnitFlag(UnitFlags.ImmuneToPc))) // player pets are immune to pc as well
|
||||
return false;
|
||||
|
||||
// Do not attack non-combat pets
|
||||
@@ -1530,9 +1528,10 @@ namespace Game.Entities
|
||||
DoNotReacquireTarget(); // cancel delayed re-target
|
||||
SetTarget(ObjectGuid.Empty); // drop target - dead mobs shouldn't ever target things
|
||||
|
||||
SetUInt64Value(UnitFields.NpcFlags, (ulong)NPCFlags.None);
|
||||
SetNpcFlags(NPCFlags.None);
|
||||
SetNpcFlags2(NPCFlags2.None);
|
||||
|
||||
SetUInt32Value(UnitFields.MountDisplayId, 0); // if creature is mounted on a virtual mount, remove it at death
|
||||
SetMountDisplayId(0); // if creature is mounted on a virtual mount, remove it at death
|
||||
|
||||
setActive(false);
|
||||
|
||||
@@ -1576,16 +1575,17 @@ namespace Game.Entities
|
||||
ObjectManager.ChooseCreatureFlags(cInfo, out npcFlags, out unitFlags, out unitFlags2, out unitFlags3, out dynamicFlags, creatureData);
|
||||
|
||||
if (cInfo.FlagsExtra.HasAnyFlag(CreatureFlagsExtra.Worldevent))
|
||||
SetUInt64Value(UnitFields.NpcFlags, npcFlags | Global.GameEventMgr.GetNPCFlag(this));
|
||||
else
|
||||
SetUInt64Value(UnitFields.NpcFlags, npcFlags);
|
||||
npcFlags |= Global.GameEventMgr.GetNPCFlag(this);
|
||||
|
||||
SetUInt32Value(UnitFields.Flags, unitFlags);
|
||||
SetUInt32Value(UnitFields.Flags2, unitFlags2);
|
||||
SetUInt32Value(UnitFields.Flags3, unitFlags3);
|
||||
SetUInt32Value(ObjectFields.DynamicFlags, dynamicFlags);
|
||||
SetNpcFlags((NPCFlags)(npcFlags & 0xFFFFFFFF));
|
||||
SetNpcFlags2((NPCFlags2)(npcFlags >> 32));
|
||||
|
||||
RemoveFlag(UnitFields.Flags, UnitFlags.InCombat);
|
||||
SetUnitFlags((UnitFlags)unitFlags);
|
||||
SetUnitFlags2((UnitFlags2)unitFlags2);
|
||||
SetUnitFlags3((UnitFlags3)unitFlags3);
|
||||
SetDynamicFlags((UnitDynFlags)dynamicFlags);
|
||||
|
||||
RemoveUnitFlag(UnitFlags.InCombat);
|
||||
|
||||
SetMeleeDamageSchool((SpellSchools)cInfo.DmgSchool);
|
||||
}
|
||||
@@ -1633,7 +1633,7 @@ namespace Game.Entities
|
||||
{
|
||||
SetDisplayId(display.CreatureDisplayID, display.DisplayScale);
|
||||
SetNativeDisplayId(display.CreatureDisplayID, display.DisplayScale);
|
||||
SetByteValue(UnitFields.Bytes0, 3, (byte)minfo.gender);
|
||||
SetGender((Gender)minfo.gender);
|
||||
}
|
||||
|
||||
GetMotionMaster().InitDefault();
|
||||
@@ -1805,9 +1805,9 @@ namespace Game.Entities
|
||||
float dist = GetDistance(victim);
|
||||
if (dist > range || dist < minrange)
|
||||
continue;
|
||||
if (spellInfo.PreventionType.HasAnyFlag(SpellPreventionType.Silence) && HasFlag(UnitFields.Flags, UnitFlags.Silenced))
|
||||
if (spellInfo.PreventionType.HasAnyFlag(SpellPreventionType.Silence) && HasUnitFlag(UnitFlags.Silenced))
|
||||
continue;
|
||||
if (spellInfo.PreventionType.HasAnyFlag(SpellPreventionType.Pacify) && HasFlag(UnitFields.Flags, UnitFlags.Pacified))
|
||||
if (spellInfo.PreventionType.HasAnyFlag(SpellPreventionType.Pacify) && HasUnitFlag(UnitFlags.Pacified))
|
||||
continue;
|
||||
return spellInfo;
|
||||
}
|
||||
@@ -1854,9 +1854,9 @@ namespace Game.Entities
|
||||
|
||||
if (dist > range || dist < minrange)
|
||||
continue;
|
||||
if (spellInfo.PreventionType.HasAnyFlag(SpellPreventionType.Silence) && HasFlag(UnitFields.Flags, UnitFlags.Silenced))
|
||||
if (spellInfo.PreventionType.HasAnyFlag(SpellPreventionType.Silence) && HasUnitFlag(UnitFlags.Silenced))
|
||||
continue;
|
||||
if (spellInfo.PreventionType.HasAnyFlag(SpellPreventionType.Pacify) && HasFlag(UnitFields.Flags, UnitFlags.Pacified))
|
||||
if (spellInfo.PreventionType.HasAnyFlag(SpellPreventionType.Pacify) && HasUnitFlag(UnitFlags.Pacified))
|
||||
continue;
|
||||
return spellInfo;
|
||||
}
|
||||
@@ -1969,7 +1969,7 @@ namespace Game.Entities
|
||||
if (IsCivilian())
|
||||
return false;
|
||||
|
||||
if (HasFlag(UnitFields.Flags, UnitFlags.NonAttackable | UnitFlags.NotSelectable | UnitFlags.ImmuneToPc))
|
||||
if (HasUnitFlag(UnitFlags.NonAttackable | UnitFlags.NotSelectable | UnitFlags.ImmuneToPc))
|
||||
return false;
|
||||
|
||||
// skip fighting creature
|
||||
@@ -1983,7 +1983,7 @@ namespace Game.Entities
|
||||
// only from same creature faction
|
||||
if (checkfaction)
|
||||
{
|
||||
if (getFaction() != u.getFaction())
|
||||
if (GetFaction() != u.GetFaction())
|
||||
return false;
|
||||
}
|
||||
else
|
||||
@@ -2009,7 +2009,7 @@ namespace Game.Entities
|
||||
if (target.HasUnitState(UnitState.Died))
|
||||
{
|
||||
// guards can detect fake death
|
||||
if (IsGuard() && target.HasFlag(UnitFields.Flags2, UnitFlags2.FeignDeath))
|
||||
if (IsGuard() && target.HasUnitFlag2(UnitFlags2.FeignDeath))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
@@ -2099,18 +2099,16 @@ namespace Game.Entities
|
||||
// 2 StandFlags
|
||||
// 3 StandMiscFlags
|
||||
|
||||
SetByteValue(UnitFields.Bytes1, UnitBytes1Offsets.StandState, (byte)(cainfo.bytes1 & 0xFF));
|
||||
//SetByteValue(UnitFields.Bytes1, UnitBytes1Offsets.PetTalent, (byte)((cainfo.bytes1 >> 8) & 0xFF));
|
||||
SetByteValue(UnitFields.Bytes1, UnitBytes1Offsets.PetTalents, 0);
|
||||
SetByteValue(UnitFields.Bytes1, UnitBytes1Offsets.VisFlag, (byte)((cainfo.bytes1 >> 16) & 0xFF));
|
||||
SetByteValue(UnitFields.Bytes1, UnitBytes1Offsets.AnimTier, (byte)((cainfo.bytes1 >> 24) & 0xFF));
|
||||
SetStandState((UnitStandStateType)(cainfo.bytes1 & 0xFF));
|
||||
SetVisFlags((UnitVisFlags)((cainfo.bytes1 >> 16) & 0xFF));
|
||||
SetAnimTier((UnitBytes1Flags)((cainfo.bytes1 >> 24) & 0xFF), false);
|
||||
|
||||
//! Suspected correlation between UNIT_FIELD_BYTES_1, offset 3, value 0x2:
|
||||
//! If no inhabittype_fly (if no MovementFlag_DisableGravity or MovementFlag_CanFly flag found in sniffs)
|
||||
//! Check using InhabitType as movement flags are assigned dynamically
|
||||
//! basing on whether the creature is in air or not
|
||||
//! Set MovementFlag_Hover. Otherwise do nothing.
|
||||
if (Convert.ToBoolean(GetByteValue(UnitFields.Bytes1, UnitBytes1Offsets.AnimTier) & (byte)UnitBytes1Flags.Hover) && !Convert.ToBoolean(GetCreatureTemplate().InhabitType & InhabitType.Air))
|
||||
if (Convert.ToBoolean(m_unitData.AnimTier & (byte)UnitBytes1Flags.Hover) && !Convert.ToBoolean(GetCreatureTemplate().InhabitType & InhabitType.Air))
|
||||
AddUnitMovementFlag(MovementFlag.Hover);
|
||||
}
|
||||
|
||||
@@ -2121,16 +2119,14 @@ namespace Game.Entities
|
||||
// 2 PetFlags Pet only, so always 0 for default creature
|
||||
// 3 ShapeshiftForm Must be determined/set by shapeshift spell/aura
|
||||
|
||||
SetByteValue(UnitFields.Bytes2, UnitBytes2Offsets.SheathState, (byte)(cainfo.bytes2 & 0xFF));
|
||||
//SetByteValue(UnitFields.Bytes2, UnitBytes2Offsets.PvpFlag, uint8((cainfo->bytes2 >> 8) & 0xFF));
|
||||
//SetByteValue(UnitFields.Bytes2, UnitBytes2Offsets.PetFlags, uint8((cainfo->bytes2 >> 16) & 0xFF));
|
||||
SetByteValue(UnitFields.Bytes2, UnitBytes2Offsets.PetFlags, 0);
|
||||
//SetByteValue(UnitFields.Bytes2, UNIT_BYTES_2_OFFSET_SHAPESHIFT_FORM, uint8((cainfo->bytes2 >> 24) & 0xFF));
|
||||
SetByteValue(UnitFields.Bytes2, UnitBytes2Offsets.ShapeshiftForm, 0);
|
||||
SetSheath((SheathState)(cainfo.bytes2 & 0xFF));
|
||||
SetPvpFlags(UnitPVPStateFlags.None);
|
||||
SetPetFlags(UnitPetFlags.None);
|
||||
SetShapeshiftForm(ShapeShiftForm.None);
|
||||
}
|
||||
|
||||
if (cainfo.emote != 0)
|
||||
SetUInt32Value(UnitFields.NpcEmotestate, cainfo.emote);
|
||||
SetEmoteState((Emote)cainfo.emote);
|
||||
|
||||
SetAIAnimKitId(cainfo.aiAnimKit);
|
||||
SetMovementAnimKitId(cainfo.movementAnimKit);
|
||||
@@ -2289,7 +2285,7 @@ namespace Game.Entities
|
||||
{
|
||||
if (loot.loot_type != LootType.Skinning && !IsPet() && GetCreatureTemplate().SkinLootId != 0 && hasLootRecipient())
|
||||
if (LootStorage.Skinning.HaveLootFor(GetCreatureTemplate().SkinLootId))
|
||||
SetFlag(UnitFields.Flags, UnitFlags.Skinnable);
|
||||
AddUnitFlag(UnitFlags.Skinnable);
|
||||
|
||||
long now = Time.UnixTime;
|
||||
// Do not reset corpse remove time if corpse is already removed
|
||||
@@ -2380,12 +2376,12 @@ namespace Game.Entities
|
||||
// between UNIT_FIELD_SCALING_LEVEL_MIN and UNIT_FIELD_SCALING_LEVEL_MAX
|
||||
if (HasScalableLevels())
|
||||
{
|
||||
int targetLevelWithDelta = ((int)unitTarget.getLevel() + GetInt32Value(UnitFields.ScalingLevelDelta));
|
||||
int targetLevelWithDelta = (int)unitTarget.getLevel() + m_unitData.ScalingLevelDelta;
|
||||
|
||||
if (target.IsPlayer())
|
||||
targetLevelWithDelta += target.GetInt32Value(ActivePlayerFields.ScalingPlayerLevelDelta);
|
||||
targetLevelWithDelta += target.ToPlayer().m_activePlayerData.ScalingPlayerLevelDelta;
|
||||
|
||||
return (uint)MathFunctions.RoundToInterval(ref targetLevelWithDelta, GetInt32Value(UnitFields.ScalingLevelMin), GetInt32Value(UnitFields.ScalingLevelMax));
|
||||
return (uint)MathFunctions.RoundToInterval(ref targetLevelWithDelta, m_unitData.ScalingLevelMin, m_unitData.ScalingLevelMax);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -2409,7 +2405,7 @@ namespace Game.Entities
|
||||
if (creatureData != null)
|
||||
return creatureData.ScriptId;
|
||||
|
||||
return Global.ObjectMgr.GetCreatureTemplate(GetEntry()).ScriptID;
|
||||
return Global.ObjectMgr.GetCreatureTemplate(GetEntry()) != null ? Global.ObjectMgr.GetCreatureTemplate(GetEntry()).ScriptID : 0;
|
||||
}
|
||||
|
||||
public VendorItemData GetVendorItems()
|
||||
@@ -2668,8 +2664,8 @@ namespace Game.Entities
|
||||
CreatureModelInfo minfo = Global.ObjectMgr.GetCreatureModelInfo(GetDisplayId());
|
||||
if (minfo != null)
|
||||
{
|
||||
SetFloatValue(UnitFields.BoundingRadius, (IsPet() ? 1.0f : minfo.BoundingRadius) * scale);
|
||||
SetFloatValue(UnitFields.CombatReach, (IsPet() ? SharedConst.DefaultCombatReach : minfo.CombatReach) * scale);
|
||||
SetBoundingRadius((IsPet() ? 1.0f : minfo.BoundingRadius) * scale);
|
||||
SetCombatReach((IsPet() ? SharedConst.DefaultCombatReach : minfo.CombatReach) * scale);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2680,8 +2676,8 @@ namespace Game.Entities
|
||||
CreatureModelInfo minfo = Global.ObjectMgr.GetCreatureModelInfo(modelId);
|
||||
if (minfo != null)
|
||||
{
|
||||
SetFloatValue(UnitFields.BoundingRadius, (IsPet() ? 1.0f : minfo.BoundingRadius) * GetObjectScale());
|
||||
SetFloatValue(UnitFields.CombatReach, (IsPet() ? SharedConst.DefaultCombatReach : minfo.CombatReach) * GetObjectScale());
|
||||
SetBoundingRadius((IsPet() ? 1.0f : minfo.BoundingRadius) * GetObjectScale());
|
||||
SetCombatReach((IsPet() ? SharedConst.DefaultCombatReach : minfo.CombatReach) * GetObjectScale());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2697,7 +2693,7 @@ namespace Game.Entities
|
||||
if (IsFocusing(null, true))
|
||||
m_suppressedTarget = guid;
|
||||
else
|
||||
SetGuidValue(UnitFields.Target, guid);
|
||||
SetUpdateFieldValue(m_values.ModifyValue(m_unitData).ModifyValue(m_unitData.Target), guid);
|
||||
}
|
||||
|
||||
public void FocusTarget(Spell focusSpell, WorldObject target)
|
||||
@@ -2716,7 +2712,7 @@ namespace Game.Entities
|
||||
// store pre-cast values for target and orientation (used to later restore)
|
||||
if (!IsFocusing(null, true))
|
||||
{ // only overwrite these fields if we aren't transitioning from one spell focus to another
|
||||
m_suppressedTarget = GetGuidValue(UnitFields.Target);
|
||||
m_suppressedTarget = GetTarget();
|
||||
m_suppressedOrientation = GetOrientation();
|
||||
}
|
||||
|
||||
@@ -2724,9 +2720,9 @@ namespace Game.Entities
|
||||
|
||||
// set target, then force send update packet to players if it changed to provide appropriate facing
|
||||
ObjectGuid newTarget = target ? target.GetGUID() : ObjectGuid.Empty;
|
||||
if (GetGuidValue(UnitFields.Target) != newTarget)
|
||||
if (GetTarget() != newTarget)
|
||||
{
|
||||
SetGuidValue(UnitFields.Target, newTarget);
|
||||
SetUpdateFieldValue(m_values.ModifyValue(m_unitData).ModifyValue(m_unitData.Target), newTarget);
|
||||
|
||||
// here we determine if the (relatively expensive) forced update is worth it, or whether we can afford to wait until the scheduled update tick
|
||||
// only require instant update for spells that actually have a visual
|
||||
@@ -2794,7 +2790,7 @@ namespace Game.Entities
|
||||
|
||||
if (IsPet())// player pets do not use delay system
|
||||
{
|
||||
SetGuidValue(UnitFields.Target, m_suppressedTarget);
|
||||
SetUpdateFieldValue(m_values.ModifyValue(m_unitData).ModifyValue(m_unitData.Target), m_suppressedTarget);
|
||||
if (!m_suppressedTarget.IsEmpty())
|
||||
{
|
||||
WorldObject objTarget = Global.ObjAccessor.GetWorldObject(this, m_suppressedTarget);
|
||||
|
||||
@@ -42,7 +42,7 @@ namespace Game.Entities
|
||||
public uint RequiredExpansion;
|
||||
public uint VignetteID; // @todo Read Vignette.db2
|
||||
public uint Faction;
|
||||
public NPCFlags Npcflag;
|
||||
public ulong Npcflag;
|
||||
public float SpeedWalk;
|
||||
public float SpeedRun;
|
||||
public float Scale;
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
using Framework.Constants;
|
||||
using Game.Spells;
|
||||
using Game.Network;
|
||||
|
||||
namespace Game.Entities
|
||||
{
|
||||
@@ -29,7 +30,7 @@ namespace Game.Entities
|
||||
|
||||
m_updateFlag.Stationary = true;
|
||||
|
||||
valuesCount = (int)DynamicObjectFields.End;
|
||||
m_dynamicObjectData = new DynamicObjectData();
|
||||
}
|
||||
|
||||
public override void Dispose()
|
||||
@@ -77,7 +78,6 @@ namespace Game.Entities
|
||||
|
||||
public bool CreateDynamicObject(ulong guidlow, Unit caster, SpellInfo spell, Position pos, float radius, DynamicObjectType type, uint spellXSpellVisualId)
|
||||
{
|
||||
_spellXSpellVisualId = spellXSpellVisualId;
|
||||
SetMap(caster.GetMap());
|
||||
Relocate(pos);
|
||||
if (!IsPositionValid())
|
||||
@@ -91,13 +91,13 @@ namespace Game.Entities
|
||||
|
||||
SetEntry(spell.Id);
|
||||
SetObjectScale(1f);
|
||||
SetGuidValue(DynamicObjectFields.Caster, caster.GetGUID());
|
||||
|
||||
SetUInt32Value(DynamicObjectFields.Type, (uint)type);
|
||||
SetUInt32Value(DynamicObjectFields.SpellXSpellVisualId, spellXSpellVisualId);
|
||||
SetUInt32Value(DynamicObjectFields.SpellId, spell.Id);
|
||||
SetFloatValue(DynamicObjectFields.Radius, radius);
|
||||
SetUInt32Value(DynamicObjectFields.CastTime, Time.GetMSTime());
|
||||
SetUpdateFieldValue(m_values.ModifyValue(m_dynamicObjectData).ModifyValue(m_dynamicObjectData.Caster), caster.GetGUID());
|
||||
SetUpdateFieldValue(m_values.ModifyValue(m_dynamicObjectData).ModifyValue(m_dynamicObjectData.Type), (byte)type);
|
||||
SetUpdateFieldValue(m_values.ModifyValue(m_dynamicObjectData).ModifyValue(m_dynamicObjectData.SpellXSpellVisualID), spellXSpellVisualId);
|
||||
SetUpdateFieldValue(m_values.ModifyValue(m_dynamicObjectData).ModifyValue(m_dynamicObjectData.SpellID), spell.Id);
|
||||
SetUpdateFieldValue(m_values.ModifyValue(m_dynamicObjectData).ModifyValue(m_dynamicObjectData.Radius), radius);
|
||||
SetUpdateFieldValue(m_values.ModifyValue(m_dynamicObjectData).ModifyValue(m_dynamicObjectData.CastTime), Time.GetMSTime());
|
||||
|
||||
if (IsWorldObject())
|
||||
setActive(true); //must before add to map to be put in world container
|
||||
@@ -207,7 +207,7 @@ namespace Game.Entities
|
||||
if (caster != null)
|
||||
{
|
||||
caster.SetViewpoint(this, true);
|
||||
_isViewpoint = true;
|
||||
_isViewpoint = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -242,16 +242,51 @@ namespace Game.Entities
|
||||
return Global.SpellMgr.GetSpellInfo(GetSpellId());
|
||||
}
|
||||
|
||||
public Unit GetCaster() { return _caster; }
|
||||
public uint GetSpellId() { return GetUInt32Value(DynamicObjectFields.SpellId); }
|
||||
public ObjectGuid GetCasterGUID() { return GetGuidValue(DynamicObjectFields.Caster); }
|
||||
public float GetRadius() { return GetFloatValue(DynamicObjectFields.Radius); }
|
||||
public override void BuildValuesCreate(WorldPacket data, Player target)
|
||||
{
|
||||
UpdateFieldFlag flags = GetUpdateFieldFlagsFor(target);
|
||||
WorldPacket buffer = new WorldPacket();
|
||||
|
||||
buffer.WriteUInt8((byte)flags);
|
||||
m_objectData.WriteCreate(buffer, flags, this, target);
|
||||
m_dynamicObjectData.WriteCreate(buffer, flags, this, target);
|
||||
|
||||
data.WriteUInt32(buffer.GetSize());
|
||||
data.WriteBytes(buffer);
|
||||
}
|
||||
|
||||
public override void BuildValuesUpdate(WorldPacket data, Player target)
|
||||
{
|
||||
UpdateFieldFlag flags = GetUpdateFieldFlagsFor(target);
|
||||
WorldPacket buffer = new WorldPacket();
|
||||
|
||||
buffer.WriteUInt32(m_values.GetChangedObjectTypeMask());
|
||||
if (m_values.HasChanged(TypeId.Object))
|
||||
m_objectData.WriteUpdate(buffer, flags, this, target);
|
||||
|
||||
if (m_values.HasChanged(TypeId.DynamicObject))
|
||||
m_dynamicObjectData.WriteUpdate(buffer, flags, this, target);
|
||||
|
||||
data.WriteUInt32(buffer.GetSize());
|
||||
data.WriteBytes(buffer);
|
||||
}
|
||||
|
||||
public override void ClearUpdateMask(bool remove)
|
||||
{
|
||||
m_values.ClearChangesMask(m_dynamicObjectData);
|
||||
base.ClearUpdateMask(remove);
|
||||
}
|
||||
|
||||
public Unit GetCaster() { return _caster; }
|
||||
public uint GetSpellId() { return m_dynamicObjectData.SpellID; }
|
||||
public ObjectGuid GetCasterGUID() { return m_dynamicObjectData.Caster; }
|
||||
public float GetRadius() { return m_dynamicObjectData.Radius; }
|
||||
|
||||
DynamicObjectData m_dynamicObjectData;
|
||||
Aura _aura;
|
||||
Aura _removedAura;
|
||||
Unit _caster;
|
||||
int _duration; // for non-aura dynobjects
|
||||
uint _spellXSpellVisualId;
|
||||
bool _isViewpoint;
|
||||
}
|
||||
|
||||
|
||||
@@ -31,6 +31,7 @@ using Game.Spells;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Game.Network;
|
||||
|
||||
namespace Game.Entities
|
||||
{
|
||||
@@ -44,13 +45,14 @@ namespace Game.Entities
|
||||
m_updateFlag.Stationary = true;
|
||||
m_updateFlag.Rotation = true;
|
||||
|
||||
valuesCount = (int)GameObjectFields.End;
|
||||
m_respawnDelayTime = 300;
|
||||
m_lootState = LootState.NotReady;
|
||||
m_spawnedByDefault = true;
|
||||
|
||||
ResetLootMode(); // restore default loot mode
|
||||
m_stationaryPosition = new Position();
|
||||
|
||||
m_gameObjectData = new GameObjectFieldData();
|
||||
}
|
||||
|
||||
public override void Dispose()
|
||||
@@ -248,8 +250,8 @@ namespace Game.Entities
|
||||
|
||||
if (m_goTemplateAddon != null)
|
||||
{
|
||||
SetUInt32Value(GameObjectFields.Faction, m_goTemplateAddon.faction);
|
||||
SetUInt32Value(GameObjectFields.Flags, m_goTemplateAddon.flags);
|
||||
SetFaction(m_goTemplateAddon.faction);
|
||||
SetFlags((GameObjectFlags)m_goTemplateAddon.flags);
|
||||
|
||||
if (m_goTemplateAddon.WorldEffectID != 0)
|
||||
{
|
||||
@@ -267,7 +269,7 @@ namespace Game.Entities
|
||||
|
||||
m_model = CreateModel();
|
||||
if (m_model != null && m_model.isMapObject())
|
||||
SetFlag(GameObjectFields.Flags, GameObjectFlags.MapObject);
|
||||
AddFlag(GameObjectFlags.MapObject);
|
||||
|
||||
// GAMEOBJECT_BYTES_1, index at 0, 1, 2 and 3
|
||||
SetGoType(goInfo.type);
|
||||
@@ -275,7 +277,7 @@ namespace Game.Entities
|
||||
SetGoState(goState);
|
||||
SetGoArtKit((byte)artKit);
|
||||
|
||||
SetUInt32Value(GameObjectFields.StateAnimId, (uint)CliDB.AnimationDataStorage.Count);
|
||||
SetUpdateFieldValue(m_values.ModifyValue(m_gameObjectData).ModifyValue(m_gameObjectData.SpawnTrackingStateAnimID), (uint)CliDB.AnimationDataStorage.Count);
|
||||
|
||||
switch (goInfo.type)
|
||||
{
|
||||
@@ -287,7 +289,8 @@ namespace Game.Entities
|
||||
m_goValue.Building.Health = 20000;//goinfo.DestructibleBuilding.intactNumHits + goinfo.DestructibleBuilding.damagedNumHits;
|
||||
m_goValue.Building.MaxHealth = m_goValue.Building.Health;
|
||||
SetGoAnimProgress(255);
|
||||
SetUInt32Value(GameObjectFields.ParentRotation, goInfo.DestructibleBuilding.DestructibleModelRec);
|
||||
// yes, even after the updatefield rewrite this garbage hack is still in client
|
||||
SetUpdateFieldValue(m_values.ModifyValue(m_gameObjectData).ModifyValue(m_gameObjectData.ParentRotation), new Quaternion(goInfo.DestructibleBuilding.DestructibleModelRec, 0f, 0f, 0f));
|
||||
break;
|
||||
case GameObjectTypes.Transport:
|
||||
m_goValue.Transport.AnimationInfo = Global.TransportMgr.GetTransportAnimInfo(goInfo.entry);
|
||||
@@ -324,7 +327,7 @@ namespace Game.Entities
|
||||
SetGoAnimProgress(animProgress);
|
||||
break;
|
||||
case GameObjectTypes.FishingNode:
|
||||
SetUInt32Value(GameObjectFields.Level, 1);
|
||||
SetLevel(1);
|
||||
SetGoAnimProgress(255);
|
||||
break;
|
||||
case GameObjectTypes.Trap:
|
||||
@@ -341,10 +344,11 @@ namespace Game.Entities
|
||||
}
|
||||
break;
|
||||
case GameObjectTypes.PhaseableMo:
|
||||
SetByteValue(GameObjectFields.Flags, 1, (byte)(m_goInfo.PhaseableMO.AreaNameSet & 0xF));
|
||||
RemoveFlag((GameObjectFlags)0xF00);
|
||||
AddFlag((GameObjectFlags)((m_goInfo.PhaseableMO.AreaNameSet & 0xF) << 8));
|
||||
break;
|
||||
case GameObjectTypes.CapturePoint:
|
||||
SetUInt32Value(GameObjectFields.SpellVisualId, m_goInfo.CapturePoint.SpellVisual1);
|
||||
SetUpdateFieldValue(m_values.ModifyValue(m_gameObjectData).ModifyValue(m_gameObjectData.SpellVisualID), m_goInfo.CapturePoint.SpellVisual1);
|
||||
break;
|
||||
default:
|
||||
SetGoAnimProgress(animProgress);
|
||||
@@ -438,15 +442,15 @@ namespace Game.Entities
|
||||
m_goValue.Transport.PathProgress += diff;
|
||||
/* TODO: Fix movement in unloaded grid - currently GO will just disappear
|
||||
public uint timer = m_goValue.Transport.PathProgress % GetTransportPeriod();
|
||||
TransportAnimationEntry const* node = m_goValue.Transport.AnimationInfo->GetAnimNode(timer);
|
||||
if (node && m_goValue.Transport.CurrentSeg != node->TimeSeg)
|
||||
TransportAnimationEntry const* node = m_goValue.Transport.AnimationInfo.GetAnimNode(timer);
|
||||
if (node && m_goValue.Transport.CurrentSeg != node.TimeSeg)
|
||||
{
|
||||
m_goValue.Transport.CurrentSeg = node->TimeSeg;
|
||||
m_goValue.Transport.CurrentSeg = node.TimeSeg;
|
||||
|
||||
G3D.Quat rotation = m_goValue.Transport.AnimationInfo->GetAnimRotation(timer);
|
||||
G3D.Quat rotation = m_goValue.Transport.AnimationInfo.GetAnimRotation(timer);
|
||||
G3D.Vector3 pos = rotation.toRotationMatrix()
|
||||
G3D.Matrix3.fromEulerAnglesZYX(GetOrientation(), 0.0f, 0.0f)
|
||||
G3D.Vector3(node->X, node->Y, node->Z);
|
||||
G3D.Vector3(node.X, node.Y, node.Z);
|
||||
|
||||
pos += G3D.Vector3(GetStationaryX(), GetStationaryY(), GetStationaryZ());
|
||||
|
||||
@@ -454,7 +458,7 @@ namespace Game.Entities
|
||||
|
||||
TC_LOG_DEBUG("misc", "Src: {0} Dest: {1}", src.toString().c_str(), pos.toString().c_str());
|
||||
|
||||
GetMap()->GameObjectRelocation(this, pos.x, pos.y, pos.z, GetOrientation());
|
||||
GetMap().GameObjectRelocation(this, pos.x, pos.y, pos.z, GetOrientation());
|
||||
}
|
||||
*/
|
||||
if (!m_goValue.Transport.StopFrames.Empty())
|
||||
@@ -464,8 +468,9 @@ namespace Game.Entities
|
||||
uint visualStateAfter = (m_goValue.Transport.StateUpdateTimer / 20000) & 1;
|
||||
if (visualStateBefore != visualStateAfter)
|
||||
{
|
||||
ForceValuesUpdateAtIndex(GameObjectFields.Level);
|
||||
ForceValuesUpdateAtIndex(GameObjectFields.Bytes1);
|
||||
m_gameObjectData.ModifyValue(m_gameObjectData.Level);
|
||||
m_gameObjectData.ModifyValue(m_gameObjectData.State);
|
||||
ForceUpdateFieldChange();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -480,7 +485,7 @@ namespace Game.Entities
|
||||
if (caster != null && caster.IsTypeId(TypeId.Player))
|
||||
{
|
||||
SetGoState(GameObjectState.Active);
|
||||
SetUInt32Value(GameObjectFields.Flags, (uint)GameObjectFlags.NoDespawn);
|
||||
SetFlags(GameObjectFlags.NoDespawn);
|
||||
|
||||
UpdateData udata = new UpdateData(caster.GetMapId());
|
||||
UpdateObject packet;
|
||||
@@ -650,7 +655,7 @@ namespace Game.Entities
|
||||
case GameObjectTypes.Goober:
|
||||
if (m_cooldownTime < Time.UnixTime)
|
||||
{
|
||||
RemoveFlag(GameObjectFields.Flags, GameObjectFlags.InUse);
|
||||
RemoveFlag(GameObjectFlags.InUse);
|
||||
|
||||
SetLootState(LootState.JustDeactivated);
|
||||
m_cooldownTime = 0;
|
||||
@@ -770,7 +775,7 @@ namespace Game.Entities
|
||||
//reset flags
|
||||
GameObjectTemplateAddon addon = GetTemplateAddon();
|
||||
if (addon != null)
|
||||
SetUInt32Value(GameObjectFields.Flags, addon.flags);
|
||||
SetFlags((GameObjectFlags)addon.flags);
|
||||
}
|
||||
|
||||
if (m_respawnDelayTime == 0)
|
||||
@@ -823,7 +828,7 @@ namespace Game.Entities
|
||||
SetGoState(GameObjectState.Ready);
|
||||
GameObjectTemplateAddon addon = GetTemplateAddon();
|
||||
if (addon != null)
|
||||
SetUInt32Value(GameObjectFields.Flags, addon.flags);
|
||||
SetFlags((GameObjectFlags)addon.flags);
|
||||
|
||||
uint poolid = GetSpawnId() != 0 ? Global.PoolMgr.IsPartOfAPool<GameObject>(GetSpawnId()) : 0;
|
||||
if (poolid != 0)
|
||||
@@ -918,7 +923,7 @@ namespace Game.Entities
|
||||
data.animprogress = GetGoAnimProgress();
|
||||
data.go_state = GetGoState();
|
||||
data.spawnDifficulties = spawnDifficulties;
|
||||
data.artKit = GetGoArtKit();
|
||||
data.artKit = (byte)GetGoArtKit();
|
||||
Global.ObjectMgr.NewGOData(m_spawnId, data);
|
||||
|
||||
data.phaseId = GetDBPhase() > 0 ? (uint)GetDBPhase() : data.phaseId;
|
||||
@@ -980,7 +985,7 @@ namespace Game.Entities
|
||||
|
||||
if (!GetGoInfo().GetDespawnPossibility() && !GetGoInfo().IsDespawnAtAction())
|
||||
{
|
||||
SetFlag(GameObjectFields.Flags, GameObjectFlags.NoDespawn);
|
||||
AddFlag(GameObjectFlags.NoDespawn);
|
||||
m_respawnDelayTime = 0;
|
||||
m_respawnTime = 0;
|
||||
}
|
||||
@@ -1104,7 +1109,7 @@ namespace Game.Entities
|
||||
if (GetGoType() == GameObjectTypes.SpellFocus && GetGoInfo().SpellFocus.serverOnly == 1)
|
||||
return true;
|
||||
|
||||
if (GetUInt32Value(GameObjectFields.DisplayId) == 0)
|
||||
if (GetDisplayId() == 0)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
@@ -1157,7 +1162,7 @@ namespace Game.Entities
|
||||
}
|
||||
}
|
||||
|
||||
bool ActivateToQuest(Player target)
|
||||
public bool ActivateToQuest(Player target)
|
||||
{
|
||||
if (target.HasQuestForGO((int)GetEntry()))
|
||||
return true;
|
||||
@@ -1231,7 +1236,7 @@ namespace Game.Entities
|
||||
if (m_lootState == LootState.Ready || m_lootState == LootState.JustDeactivated)
|
||||
return;
|
||||
|
||||
RemoveFlag(GameObjectFields.Flags, GameObjectFlags.InUse);
|
||||
RemoveFlag(GameObjectFlags.InUse);
|
||||
SetGoState(m_prevGoState);
|
||||
|
||||
SetLootState(LootState.JustDeactivated);
|
||||
@@ -1254,7 +1259,7 @@ namespace Game.Entities
|
||||
|
||||
public void SetGoArtKit(byte kit)
|
||||
{
|
||||
SetByteValue(GameObjectFields.Bytes1, 2, kit);
|
||||
SetUpdateFieldValue(m_values.ModifyValue(m_gameObjectData).ModifyValue(m_gameObjectData.ArtKit), kit);
|
||||
GameObjectData data = Global.ObjectMgr.GetGOData(m_spawnId);
|
||||
if (data != null)
|
||||
data.artKit = kit;
|
||||
@@ -1278,9 +1283,9 @@ namespace Game.Entities
|
||||
void SwitchDoorOrButton(bool activate, bool alternative = false)
|
||||
{
|
||||
if (activate)
|
||||
SetFlag(GameObjectFields.Flags, GameObjectFlags.InUse);
|
||||
AddFlag(GameObjectFlags.InUse);
|
||||
else
|
||||
RemoveFlag(GameObjectFields.Flags, GameObjectFlags.InUse);
|
||||
RemoveFlag(GameObjectFlags.InUse);
|
||||
|
||||
if (GetGoState() == GameObjectState.Ready) //if closed . open
|
||||
SetGoState(alternative ? GameObjectState.ActiveAlternative : GameObjectState.Active);
|
||||
@@ -1423,7 +1428,7 @@ namespace Game.Entities
|
||||
{
|
||||
guid = player.GetGUID(); //this slot in now used by player
|
||||
player.TeleportTo(GetMapId(), x_lowest, y_lowest, GetPositionZ(), GetOrientation(), (TeleportToOptions.NotLeaveTransport | TeleportToOptions.NotLeaveCombat | TeleportToOptions.NotUnSummonPet));
|
||||
player.SetStandState(UnitStandStateType.SitLowChair + (int)info.Chair.chairheight);
|
||||
player.SetStandState(UnitStandStateType.SitLowChair + (byte)info.Chair.chairheight);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -1487,7 +1492,7 @@ namespace Game.Entities
|
||||
if (trapEntry != 0)
|
||||
TriggeringLinkedGameObject(trapEntry, user);
|
||||
|
||||
SetFlag(GameObjectFields.Flags, GameObjectFlags.InUse);
|
||||
AddFlag(GameObjectFlags.InUse);
|
||||
SetLootState(LootState.Activated, user);
|
||||
|
||||
// this appear to be ok, however others exist in addition to this that should have custom (ex: 190510, 188692, 187389)
|
||||
@@ -1864,7 +1869,7 @@ namespace Game.Entities
|
||||
|
||||
// fallback, will always work
|
||||
player.TeleportTo(GetMapId(), GetPositionX(), GetPositionY(), GetPositionZ(), GetOrientation(), (TeleportToOptions.NotLeaveTransport | TeleportToOptions.NotLeaveCombat | TeleportToOptions.NotUnSummonPet));
|
||||
player.SetStandState((UnitStandStateType)(UnitStandStateType.SitLowChair + (int)info.BarberChair.chairheight), info.BarberChair.SitAnimKit);
|
||||
player.SetStandState((UnitStandStateType.SitLowChair + (byte)info.BarberChair.chairheight), info.BarberChair.SitAnimKit);
|
||||
return;
|
||||
}
|
||||
case GameObjectTypes.ArtifactForge:
|
||||
@@ -1972,16 +1977,16 @@ namespace Game.Entities
|
||||
return;
|
||||
|
||||
// remove immunity flags, to allow spell to target anything
|
||||
trigger.RemoveFlag(UnitFields.Flags, UnitFlags.ImmuneToNpc | UnitFlags.ImmuneToPc);
|
||||
trigger.RemoveUnitFlag(UnitFlags.ImmuneToNpc | UnitFlags.ImmuneToPc);
|
||||
|
||||
Unit owner = GetOwner();
|
||||
if (owner)
|
||||
{
|
||||
trigger.SetFaction(owner.getFaction());
|
||||
if (owner.HasFlag(UnitFields.Flags, UnitFlags.PvpAttackable))
|
||||
trigger.SetFlag(UnitFields.Flags, UnitFlags.PvpAttackable);
|
||||
trigger.SetFaction(owner.GetFaction());
|
||||
if (owner.HasUnitFlag(UnitFlags.PvpAttackable))
|
||||
trigger.AddUnitFlag(UnitFlags.PvpAttackable);
|
||||
// copy pvp state flags from owner
|
||||
trigger.SetByteValue(UnitFields.Bytes2, UnitBytes2Offsets.PvpFlag, owner.GetByteValue(UnitFields.Bytes2, UnitBytes2Offsets.PvpFlag));
|
||||
trigger.SetPvpFlags(owner.GetPvpFlags());
|
||||
// needed for GO casts for proper target validation checks
|
||||
trigger.SetOwnerGUID(owner.GetGUID());
|
||||
trigger.CastSpell(target != null ? target : trigger, spellInfo, triggered, null, null, owner.GetGUID());
|
||||
@@ -2097,10 +2102,7 @@ namespace Game.Entities
|
||||
|
||||
public void SetParentRotation(Quaternion rotation)
|
||||
{
|
||||
SetFloatValue(GameObjectFields.ParentRotation + 0, rotation.X);
|
||||
SetFloatValue(GameObjectFields.ParentRotation + 1, rotation.Y);
|
||||
SetFloatValue(GameObjectFields.ParentRotation + 2, rotation.Z);
|
||||
SetFloatValue(GameObjectFields.ParentRotation + 3, rotation.W);
|
||||
SetUpdateFieldValue(m_values.ModifyValue(m_gameObjectData).ModifyValue(m_gameObjectData.ParentRotation), rotation);
|
||||
}
|
||||
|
||||
public void SetWorldRotationAngles(float z_rot, float y_rot, float x_rot)
|
||||
@@ -2165,7 +2167,7 @@ namespace Game.Entities
|
||||
switch (state)
|
||||
{
|
||||
case GameObjectDestructibleState.Intact:
|
||||
RemoveFlag(GameObjectFields.Flags, GameObjectFlags.Damaged | GameObjectFlags.Destroyed);
|
||||
RemoveFlag(GameObjectFlags.Damaged | GameObjectFlags.Destroyed);
|
||||
SetDisplayId(m_goInfo.displayId);
|
||||
if (setHealth)
|
||||
{
|
||||
@@ -2179,8 +2181,8 @@ namespace Game.Entities
|
||||
EventInform(m_goInfo.DestructibleBuilding.DamagedEvent, eventInvoker);
|
||||
Global.ScriptMgr.OnGameObjectDamaged(this, eventInvoker);
|
||||
|
||||
RemoveFlag(GameObjectFields.Flags, GameObjectFlags.Destroyed);
|
||||
SetFlag(GameObjectFields.Flags, GameObjectFlags.Damaged);
|
||||
RemoveFlag(GameObjectFlags.Destroyed);
|
||||
AddFlag(GameObjectFlags.Damaged);
|
||||
|
||||
uint modelId = m_goInfo.displayId;
|
||||
DestructibleModelDataRecord modelData = CliDB.DestructibleModelDataStorage.LookupByKey(m_goInfo.DestructibleBuilding.DestructibleModelRec);
|
||||
@@ -2211,8 +2213,8 @@ namespace Game.Entities
|
||||
bg.DestroyGate(eventInvoker, this);
|
||||
}
|
||||
|
||||
RemoveFlag(GameObjectFields.Flags, GameObjectFlags.Damaged);
|
||||
SetFlag(GameObjectFields.Flags, GameObjectFlags.Destroyed);
|
||||
RemoveFlag(GameObjectFlags.Damaged);
|
||||
AddFlag(GameObjectFlags.Destroyed);
|
||||
|
||||
uint modelId = m_goInfo.displayId;
|
||||
DestructibleModelDataRecord modelData = CliDB.DestructibleModelDataStorage.LookupByKey(m_goInfo.DestructibleBuilding.DestructibleModelRec);
|
||||
@@ -2232,7 +2234,7 @@ namespace Game.Entities
|
||||
case GameObjectDestructibleState.Rebuilding:
|
||||
{
|
||||
EventInform(m_goInfo.DestructibleBuilding.RebuildingEvent, eventInvoker);
|
||||
RemoveFlag(GameObjectFields.Flags, GameObjectFlags.Damaged | GameObjectFlags.Destroyed);
|
||||
RemoveFlag(GameObjectFlags.Damaged | GameObjectFlags.Destroyed);
|
||||
|
||||
uint modelId = m_goInfo.displayId;
|
||||
DestructibleModelDataRecord modelData = CliDB.DestructibleModelDataStorage.LookupByKey(m_goInfo.DestructibleBuilding.DestructibleModelRec);
|
||||
@@ -2277,7 +2279,7 @@ namespace Game.Entities
|
||||
|
||||
public void SetGoState(GameObjectState state)
|
||||
{
|
||||
SetByteValue(GameObjectFields.Bytes1, 0, (byte)state);
|
||||
SetUpdateFieldValue(m_values.ModifyValue(m_gameObjectData).ModifyValue(m_gameObjectData.State), (sbyte)state);
|
||||
Global.ScriptMgr.OnGameObjectStateChanged(this, state);
|
||||
if (m_model != null && !IsTransport())
|
||||
{
|
||||
@@ -2327,7 +2329,7 @@ namespace Game.Entities
|
||||
|
||||
public void SetDisplayId(uint displayid)
|
||||
{
|
||||
SetUInt32Value(GameObjectFields.DisplayId, displayid);
|
||||
SetUpdateFieldValue(m_values.ModifyValue(m_gameObjectData).ModifyValue(m_gameObjectData.DisplayID), displayid);
|
||||
UpdateModel();
|
||||
}
|
||||
|
||||
@@ -2357,7 +2359,8 @@ namespace Game.Entities
|
||||
case GameObjectTypes.GarrisonBuilding:
|
||||
case GameObjectTypes.GarrisonPlot:
|
||||
case GameObjectTypes.PhaseableMo:
|
||||
return (byte)(GetByteValue(GameObjectFields.Flags, 1) & 0xF);
|
||||
var flags = (GameObjectFlags)(uint)m_gameObjectData.Flags;
|
||||
return (byte)(((int)flags >> 8) & 0xF);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -2386,7 +2389,10 @@ namespace Game.Entities
|
||||
if (m_model != null)
|
||||
GetMap().InsertGameObjectModel(m_model);
|
||||
|
||||
ApplyModFlag(GameObjectFields.Flags, GameObjectFlags.MapObject, m_model != null && m_model.isMapObject());
|
||||
if (m_model != null && m_model.isMapObject())
|
||||
AddFlag(GameObjectFlags.MapObject);
|
||||
else
|
||||
RemoveFlag(GameObjectFlags.MapObject);
|
||||
}
|
||||
|
||||
Player GetLootRecipient()
|
||||
@@ -2434,7 +2440,7 @@ namespace Game.Entities
|
||||
m_lootRecipientGroup = unitGroup.GetGUID();
|
||||
}
|
||||
|
||||
bool IsLootAllowedFor(Player player)
|
||||
public bool IsLootAllowedFor(Player player)
|
||||
{
|
||||
if (m_lootRecipient.IsEmpty() && m_lootRecipientGroup.IsEmpty())
|
||||
return true;
|
||||
@@ -2455,103 +2461,39 @@ namespace Game.Entities
|
||||
return ObjectAccessor.GetGameObject(this, m_linkedTrap);
|
||||
}
|
||||
|
||||
public override void BuildValuesUpdate(UpdateType updateType, ByteBuffer data, Player target)
|
||||
public override void BuildValuesCreate(WorldPacket data, Player target)
|
||||
{
|
||||
if (!target)
|
||||
return;
|
||||
UpdateFieldFlag flags = GetUpdateFieldFlagsFor(target);
|
||||
WorldPacket buffer = new WorldPacket();
|
||||
|
||||
bool isStoppableTransport = GetGoType() == GameObjectTypes.Transport && !m_goValue.Transport.StopFrames.Empty();
|
||||
bool forcedFlags = GetGoType() == GameObjectTypes.Chest && GetGoInfo().Chest.usegrouplootrules != 0 && HasLootRecipient();
|
||||
bool targetIsGM = target.IsGameMaster();
|
||||
buffer.WriteUInt8((byte)flags);
|
||||
m_objectData.WriteCreate(buffer, flags, this, target);
|
||||
m_gameObjectData.WriteCreate(buffer, flags, this, target);
|
||||
|
||||
ByteBuffer fieldBuffer = new ByteBuffer();
|
||||
UpdateMask updateMask = new UpdateMask(valuesCount);
|
||||
data.WriteUInt32(buffer.GetSize());
|
||||
data.WriteBytes(buffer);
|
||||
}
|
||||
|
||||
uint[] flags = UpdateFieldFlags.GameObjectUpdateFieldFlags;
|
||||
uint visibleFlag = UpdateFieldFlags.Public;
|
||||
if (GetOwnerGUID() == target.GetGUID())
|
||||
visibleFlag |= UpdateFieldFlags.Owner;
|
||||
public override void BuildValuesUpdate(WorldPacket data, Player target)
|
||||
{
|
||||
UpdateFieldFlag flags = GetUpdateFieldFlagsFor(target);
|
||||
WorldPacket buffer = new WorldPacket();
|
||||
|
||||
for (int index = 0; index < valuesCount; ++index)
|
||||
{
|
||||
if (_fieldNotifyFlags.HasAnyFlag(flags[index]) ||
|
||||
((updateType == UpdateType.Values ? _changesMask.Get(index) : updateValues[index].UnsignedValue != 0) && flags[index].HasAnyFlag(visibleFlag)) ||
|
||||
(index == (int)GameObjectFields.Flags && forcedFlags))
|
||||
{
|
||||
updateMask.SetBit(index);
|
||||
buffer.WriteUInt32(m_values.GetChangedObjectTypeMask());
|
||||
if (m_values.HasChanged(TypeId.Object))
|
||||
m_objectData.WriteUpdate(buffer, flags, this, target);
|
||||
|
||||
if (index == (int)ObjectFields.DynamicFlags)
|
||||
{
|
||||
GameObjectDynamicLowFlags dynFlags = 0;
|
||||
short pathProgress = -1;
|
||||
switch (GetGoType())
|
||||
{
|
||||
case GameObjectTypes.QuestGiver:
|
||||
if (ActivateToQuest(target))
|
||||
dynFlags |= GameObjectDynamicLowFlags.Activate;
|
||||
break;
|
||||
case GameObjectTypes.Chest:
|
||||
case GameObjectTypes.Goober:
|
||||
if (ActivateToQuest(target) || targetIsGM)
|
||||
dynFlags |= GameObjectDynamicLowFlags.Activate | GameObjectDynamicLowFlags.Sparkle;
|
||||
break;
|
||||
case GameObjectTypes.Generic:
|
||||
if (ActivateToQuest(target))
|
||||
dynFlags |= GameObjectDynamicLowFlags.Sparkle;
|
||||
break;
|
||||
case GameObjectTypes.Transport:
|
||||
case GameObjectTypes.MapObjTransport:
|
||||
uint transportPeriod = GetTransportPeriod();
|
||||
if (transportPeriod != 0)
|
||||
{
|
||||
float timer = (float)m_goValue.Transport.PathProgress % transportPeriod;
|
||||
pathProgress = (short)(timer / transportPeriod * 65535.0f);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (m_values.HasChanged(TypeId.GameObject))
|
||||
m_gameObjectData.WriteUpdate(buffer, flags, this, target);
|
||||
|
||||
fieldBuffer.WriteUInt16(dynFlags);
|
||||
fieldBuffer.WriteInt16(pathProgress);
|
||||
}
|
||||
else if (index == (int)GameObjectFields.Flags)
|
||||
{
|
||||
GameObjectFlags _flags = (GameObjectFlags)GetUInt32Value(GameObjectFields.Flags);
|
||||
if (GetGoType() == GameObjectTypes.Chest)
|
||||
if (GetGoInfo().Chest.usegrouplootrules != 0 && !IsLootAllowedFor(target))
|
||||
_flags |= GameObjectFlags.Locked | GameObjectFlags.NotSelectable;
|
||||
data.WriteUInt32(buffer.GetSize());
|
||||
data.WriteBytes(buffer);
|
||||
}
|
||||
|
||||
fieldBuffer.WriteUInt32(_flags);
|
||||
}
|
||||
else if (index == (int)GameObjectFields.Level)
|
||||
{
|
||||
if (isStoppableTransport)
|
||||
fieldBuffer.WriteUInt32(m_goValue.Transport.PathProgress);
|
||||
else
|
||||
fieldBuffer.WriteUInt32(updateValues[index].UnsignedValue);
|
||||
}
|
||||
else if (index == (int)GameObjectFields.Bytes1)
|
||||
{
|
||||
uint bytes1 = GetUInt32Value(index);
|
||||
if (isStoppableTransport && GetGoState() == GameObjectState.TransportActive)
|
||||
{
|
||||
if (Convert.ToBoolean((m_goValue.Transport.StateUpdateTimer / 20000) & 1))
|
||||
{
|
||||
bytes1 &= 0xFFFFFF00;
|
||||
bytes1 |= (int)GameObjectState.TransportStopped;
|
||||
}
|
||||
}
|
||||
|
||||
fieldBuffer.WriteUInt32(bytes1);
|
||||
}
|
||||
else
|
||||
fieldBuffer.WriteUInt32(updateValues[index].UnsignedValue);
|
||||
}
|
||||
}
|
||||
|
||||
updateMask.AppendToPacket(data);
|
||||
data.WriteBytes(fieldBuffer);
|
||||
public override void ClearUpdateMask(bool remove)
|
||||
{
|
||||
m_values.ClearChangesMask(m_gameObjectData);
|
||||
base.ClearUpdateMask(remove);
|
||||
}
|
||||
|
||||
public void GetRespawnPosition(out float x, out float y, out float z, out float ori)
|
||||
@@ -2632,7 +2574,8 @@ namespace Game.Entities
|
||||
|
||||
public GameObjectTemplate GetGoInfo() { return m_goInfo; }
|
||||
public GameObjectTemplateAddon GetTemplateAddon() { return m_goTemplateAddon; }
|
||||
GameObjectData GetGoData() { return m_goData; }
|
||||
public GameObjectData GetGoData() { return m_goData; }
|
||||
public GameObjectValue GetGoValue() { return m_goValue; }
|
||||
|
||||
public ulong GetSpawnId() { return m_spawnId; }
|
||||
|
||||
@@ -2651,9 +2594,9 @@ namespace Game.Entities
|
||||
Cypher.Assert(false);
|
||||
}
|
||||
m_spawnedByDefault = false; // all object with owner is despawned after delay
|
||||
SetGuidValue(GameObjectFields.CreatedBy, owner);
|
||||
SetUpdateFieldValue(m_values.ModifyValue(m_gameObjectData).ModifyValue(m_gameObjectData.CreatedBy), owner);
|
||||
}
|
||||
public ObjectGuid GetOwnerGUID() { return GetGuidValue(GameObjectFields.CreatedBy); }
|
||||
public ObjectGuid GetOwnerGUID() { return m_gameObjectData.CreatedBy; }
|
||||
|
||||
public void SetSpellId(uint id)
|
||||
{
|
||||
@@ -2688,12 +2631,18 @@ namespace Game.Entities
|
||||
public void SetSpawnedByDefault(bool b) { m_spawnedByDefault = b; }
|
||||
public uint GetRespawnDelay() { return m_respawnDelayTime; }
|
||||
|
||||
public GameObjectTypes GetGoType() { return (GameObjectTypes)GetByteValue(GameObjectFields.Bytes1, 1); }
|
||||
public void SetGoType(GameObjectTypes type) { SetByteValue(GameObjectFields.Bytes1, 1, (byte)type); }
|
||||
public GameObjectState GetGoState() { return (GameObjectState)GetByteValue(GameObjectFields.Bytes1, 0); }
|
||||
byte GetGoArtKit() { return GetByteValue(GameObjectFields.Bytes1, 2); }
|
||||
byte GetGoAnimProgress() { return GetByteValue(GameObjectFields.Bytes1, 3); }
|
||||
public void SetGoAnimProgress(uint animprogress) { SetByteValue(GameObjectFields.Bytes1, 3, (byte)animprogress); }
|
||||
public bool HasFlag(GameObjectFlags flags) { return (m_gameObjectData.Flags & (uint)flags) != 0; }
|
||||
public void AddFlag(GameObjectFlags flags) { SetUpdateFieldFlagValue(m_values.ModifyValue(m_gameObjectData).ModifyValue(m_gameObjectData.Flags), (uint)flags); }
|
||||
public void RemoveFlag(GameObjectFlags flags) { RemoveUpdateFieldFlagValue(m_values.ModifyValue(m_gameObjectData).ModifyValue(m_gameObjectData.Flags), (uint)flags); }
|
||||
public void SetFlags(GameObjectFlags flags) { SetUpdateFieldValue(m_values.ModifyValue(m_gameObjectData).ModifyValue(m_gameObjectData.Flags), (uint)flags); }
|
||||
public void SetLevel(uint level) { SetUpdateFieldValue(m_values.ModifyValue(m_gameObjectData).ModifyValue(m_gameObjectData.Level), level); }
|
||||
|
||||
public GameObjectTypes GetGoType() { return (GameObjectTypes)(sbyte)m_gameObjectData.TypeID; }
|
||||
public void SetGoType(GameObjectTypes type) { SetUpdateFieldValue(m_values.ModifyValue(m_gameObjectData).ModifyValue(m_gameObjectData.TypeID), (sbyte)type); }
|
||||
public GameObjectState GetGoState() { return (GameObjectState)(sbyte)m_gameObjectData.State; }
|
||||
uint GetGoArtKit() { return m_gameObjectData.ArtKit; }
|
||||
byte GetGoAnimProgress() { return m_gameObjectData.PercentHealth; }
|
||||
public void SetGoAnimProgress(uint animprogress) { SetUpdateFieldValue(m_values.ModifyValue(m_gameObjectData).ModifyValue(m_gameObjectData.PercentHealth), (byte)animprogress); }
|
||||
|
||||
public LootState getLootState() { return m_lootState; }
|
||||
public LootModes GetLootMode() { return m_LootMode; }
|
||||
@@ -2732,19 +2681,19 @@ namespace Game.Entities
|
||||
|
||||
GameObjectDestructibleState GetDestructibleState()
|
||||
{
|
||||
if (HasFlag(GameObjectFields.Flags, GameObjectFlags.Destroyed))
|
||||
if ((m_gameObjectData.Flags & (uint)GameObjectFlags.Destroyed) != 0)
|
||||
return GameObjectDestructibleState.Destroyed;
|
||||
if (HasFlag(GameObjectFields.Flags, GameObjectFlags.Damaged))
|
||||
if ((m_gameObjectData.Flags & (uint)GameObjectFlags.Damaged) != 0)
|
||||
return GameObjectDestructibleState.Damaged;
|
||||
return GameObjectDestructibleState.Intact;
|
||||
}
|
||||
|
||||
public GameObjectAI GetAI() { return m_AI; }
|
||||
|
||||
public uint GetDisplayId() { return GetUInt32Value(GameObjectFields.DisplayId); }
|
||||
public uint GetDisplayId() { return m_gameObjectData.DisplayID; }
|
||||
|
||||
uint GetFaction() { return GetUInt32Value(GameObjectFields.Faction); }
|
||||
public void SetFaction(uint faction) { SetUInt32Value(GameObjectFields.Faction, faction); }
|
||||
public uint GetFaction() { return m_gameObjectData.FactionTemplate; }
|
||||
public void SetFaction(uint faction) { SetUpdateFieldValue(m_values.ModifyValue(m_gameObjectData).ModifyValue(m_gameObjectData.FactionTemplate), faction); }
|
||||
|
||||
public override float GetStationaryX() { return m_stationaryPosition.GetPositionX(); }
|
||||
public override float GetStationaryY() { return m_stationaryPosition.GetPositionY(); }
|
||||
@@ -2766,7 +2715,8 @@ namespace Game.Entities
|
||||
}
|
||||
|
||||
#region Fields
|
||||
public GameObjectValue m_goValue;
|
||||
protected GameObjectFieldData m_gameObjectData;
|
||||
protected GameObjectValue m_goValue;
|
||||
protected GameObjectTemplate m_goInfo;
|
||||
protected GameObjectTemplateAddon m_goTemplateAddon;
|
||||
GameObjectData m_goData;
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
using Framework.Constants;
|
||||
using Framework.Database;
|
||||
using Game.Network;
|
||||
|
||||
namespace Game.Entities
|
||||
{
|
||||
@@ -27,8 +28,7 @@ namespace Game.Entities
|
||||
objectTypeMask |= TypeMask.Container;
|
||||
objectTypeId = TypeId.Container;
|
||||
|
||||
valuesCount = (int)ContainerFields.End;
|
||||
_dynamicValuesCount = (int)ItemDynamicFields.End;
|
||||
m_containerData = new ContainerData();
|
||||
}
|
||||
|
||||
public override void Dispose()
|
||||
@@ -86,20 +86,20 @@ namespace Game.Entities
|
||||
|
||||
if (owner)
|
||||
{
|
||||
SetGuidValue(ItemFields.Owner, owner.GetGUID());
|
||||
SetGuidValue(ItemFields.Contained, owner.GetGUID());
|
||||
SetOwnerGUID(owner.GetGUID());
|
||||
SetContainedIn(owner.GetGUID());
|
||||
}
|
||||
|
||||
SetUInt32Value(ItemFields.MaxDurability, itemProto.MaxDurability);
|
||||
SetUInt32Value(ItemFields.Durability, itemProto.MaxDurability);
|
||||
SetUInt32Value(ItemFields.StackCount, 1);
|
||||
SetUpdateFieldValue(m_values.ModifyValue(m_itemData).ModifyValue(m_itemData.MaxDurability), itemProto.MaxDurability);
|
||||
SetDurability(itemProto.MaxDurability);
|
||||
SetCount(1);
|
||||
|
||||
// Setting the number of Slots the Container has
|
||||
SetUInt32Value(ContainerFields.NumSlots, itemProto.GetContainerSlots());
|
||||
SetBagSize(itemProto.GetContainerSlots());
|
||||
|
||||
// Cleaning 20 slots
|
||||
for (byte i = 0; i < ItemConst.MaxBagSize; ++i)
|
||||
SetGuidValue(ContainerFields.Slot1 + (i * 4), ObjectGuid.Empty);
|
||||
SetSlot(i, ObjectGuid.Empty);
|
||||
|
||||
m_bagslot = new Item[ItemConst.MaxBagSize];
|
||||
return true;
|
||||
@@ -111,11 +111,11 @@ namespace Game.Entities
|
||||
return false;
|
||||
|
||||
ItemTemplate itemProto = GetTemplate(); // checked in Item.LoadFromDB
|
||||
SetUInt32Value(ContainerFields.NumSlots, itemProto.GetContainerSlots());
|
||||
SetBagSize(itemProto.GetContainerSlots());
|
||||
// cleanup bag content related item value fields (its will be filled correctly from `character_inventory`)
|
||||
for (byte i = 0; i < ItemConst.MaxBagSize; ++i)
|
||||
{
|
||||
SetGuidValue(ContainerFields.Slot1 + (i * 4), ObjectGuid.Empty);
|
||||
SetSlot(i, ObjectGuid.Empty);
|
||||
m_bagslot[i] = null;
|
||||
}
|
||||
return true;
|
||||
@@ -144,9 +144,9 @@ namespace Game.Entities
|
||||
{
|
||||
if (m_bagslot[slot] != null)
|
||||
m_bagslot[slot].SetContainer(null);
|
||||
|
||||
|
||||
m_bagslot[slot] = null;
|
||||
SetGuidValue(ContainerFields.Slot1 + (slot * 4), ObjectGuid.Empty);
|
||||
SetSlot(slot, ObjectGuid.Empty);
|
||||
}
|
||||
|
||||
public void StoreItem(byte slot, Item pItem, bool update)
|
||||
@@ -154,9 +154,9 @@ namespace Game.Entities
|
||||
if (pItem != null && pItem.GetGUID() != GetGUID())
|
||||
{
|
||||
m_bagslot[slot] = pItem;
|
||||
SetGuidValue(ContainerFields.Slot1 + (slot * 4), pItem.GetGUID());
|
||||
pItem.SetGuidValue(ItemFields.Contained, GetGUID());
|
||||
pItem.SetGuidValue(ItemFields.Owner, GetOwnerGUID());
|
||||
SetSlot(slot, pItem.GetGUID());
|
||||
pItem.SetContainedIn(GetGUID());
|
||||
pItem.SetOwnerGUID(GetOwnerGUID());
|
||||
pItem.SetContainer(this);
|
||||
pItem.SetSlot(slot);
|
||||
}
|
||||
@@ -171,6 +171,45 @@ namespace Game.Entities
|
||||
m_bagslot[i].BuildCreateUpdateBlockForPlayer(data, target);
|
||||
}
|
||||
|
||||
public override void BuildValuesCreate(WorldPacket data, Player target)
|
||||
{
|
||||
UpdateFieldFlag flags = GetUpdateFieldFlagsFor(target);
|
||||
WorldPacket buffer = new WorldPacket();
|
||||
|
||||
buffer.WriteUInt8((byte)flags);
|
||||
m_objectData.WriteCreate(buffer, flags, this, target);
|
||||
m_itemData.WriteCreate(buffer, flags, this, target);
|
||||
m_containerData.WriteCreate(buffer, flags, this, target);
|
||||
|
||||
data.WriteUInt32(buffer.GetSize());
|
||||
data.WriteBytes(buffer);
|
||||
}
|
||||
|
||||
public override void BuildValuesUpdate(WorldPacket data, Player target)
|
||||
{
|
||||
UpdateFieldFlag flags = GetUpdateFieldFlagsFor(target);
|
||||
WorldPacket buffer = new WorldPacket();
|
||||
|
||||
buffer.WriteUInt32(m_values.GetChangedObjectTypeMask());
|
||||
if (m_values.HasChanged(TypeId.Object))
|
||||
m_objectData.WriteUpdate(buffer, flags, this, target);
|
||||
|
||||
if (m_values.HasChanged(TypeId.Item))
|
||||
m_itemData.WriteUpdate(buffer, flags, this, target);
|
||||
|
||||
if (m_values.HasChanged(TypeId.Container))
|
||||
m_containerData.WriteUpdate(buffer, flags, this, target);
|
||||
|
||||
data.WriteUInt32(buffer.GetSize());
|
||||
data.WriteBytes(buffer);
|
||||
}
|
||||
|
||||
public override void ClearUpdateMask(bool remove)
|
||||
{
|
||||
m_values.ClearChangesMask(m_containerData);
|
||||
base.ClearUpdateMask(remove);
|
||||
}
|
||||
|
||||
public bool IsEmpty()
|
||||
{
|
||||
for (var i = 0; i < GetBagSize(); ++i)
|
||||
@@ -243,13 +282,17 @@ namespace Game.Entities
|
||||
return null;
|
||||
}
|
||||
|
||||
public uint GetBagSize() { return GetUInt32Value(ContainerFields.NumSlots); }
|
||||
public uint GetBagSize() { return m_containerData.NumSlots; }
|
||||
void SetBagSize(uint numSlots) { SetUpdateFieldValue(m_values.ModifyValue(m_containerData).ModifyValue(m_containerData.NumSlots), numSlots); }
|
||||
|
||||
void SetSlot(int slot, ObjectGuid guid) { SetUpdateFieldValue(ref m_values.ModifyValue(m_containerData).ModifyValue(m_containerData.Slots, slot), guid); }
|
||||
|
||||
public static Item NewItemOrBag(ItemTemplate proto)
|
||||
{
|
||||
return (proto.GetInventoryType() == InventoryType.Bag) ? new Bag() : new Item();
|
||||
}
|
||||
|
||||
ContainerData m_containerData;
|
||||
Item[] m_bagslot = new Item[36];
|
||||
}
|
||||
}
|
||||
|
||||
+381
-356
File diff suppressed because it is too large
Load Diff
@@ -22,148 +22,79 @@ using System.Collections.Generic;
|
||||
|
||||
namespace Game.Entities
|
||||
{
|
||||
public class ItemEnchantment
|
||||
public class ItemEnchantmentManager
|
||||
{
|
||||
static ItemEnchantment()
|
||||
public static void LoadItemRandomBonusListTemplates()
|
||||
{
|
||||
RandomItemEnch = new EnchantmentStore();
|
||||
}
|
||||
uint oldMSTime = Time.GetMSTime();
|
||||
|
||||
public static void LoadRandomEnchantmentsTable()
|
||||
{
|
||||
// for reload case
|
||||
RandomItemEnch[ItemRandomEnchantmentType.Property].Clear();
|
||||
RandomItemEnch[ItemRandomEnchantmentType.Suffix].Clear();
|
||||
_storage.Clear();
|
||||
|
||||
// 0 1 2 3
|
||||
SQLResult result = DB.World.Query("SELECT entry, type, ench, chance FROM item_enchantment_template");
|
||||
// 0 1 2
|
||||
SQLResult result = DB.World.Query("SELECT Id, BonusListID, Chance FROM item_random_bonus_list_template");
|
||||
|
||||
if (result.IsEmpty())
|
||||
{
|
||||
Log.outError(LogFilter.Player, "Loaded 0 Item Enchantment definitions. DB table `item_enchantment_template` is empty.");
|
||||
return;
|
||||
}
|
||||
uint count = 0;
|
||||
|
||||
do
|
||||
{
|
||||
uint entry = result.Read<uint>(0);
|
||||
ItemRandomEnchantmentType type = (ItemRandomEnchantmentType)result.Read<byte>(1);
|
||||
uint ench = result.Read<uint>(2);
|
||||
float chance = result.Read<float>(3);
|
||||
uint id = result.Read<uint>(0);
|
||||
uint bonusListId = result.Read<uint>(1);
|
||||
float chance = result.Read<float>(2);
|
||||
|
||||
switch (type)
|
||||
if (Global.DB2Mgr.GetItemBonusList(bonusListId) == null)
|
||||
{
|
||||
case ItemRandomEnchantmentType.Property:
|
||||
if (!CliDB.ItemRandomPropertiesStorage.ContainsKey(ench))
|
||||
{
|
||||
Log.outError(LogFilter.Sql, "Property {0} used in `item_enchantment_template` by entry {1} doesn't have exist in ItemRandomProperties.db2", ench, entry);
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
case ItemRandomEnchantmentType.Suffix:
|
||||
if (!CliDB.ItemRandomSuffixStorage.ContainsKey(ench))
|
||||
{
|
||||
Log.outError(LogFilter.Sql, "Suffix {0} used in `item_enchantment_template` by entry {1} doesn't have exist in ItemRandomSuffix.db2", ench, entry);
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
case ItemRandomEnchantmentType.BonusList:
|
||||
if (Global.DB2Mgr.GetItemBonusList(ench) == null)
|
||||
{
|
||||
Log.outError(LogFilter.Sql, "Bonus list {0} used in `item_enchantment_template` by entry {1} doesn't have exist in ItemBonus.db2", ench, entry);
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
Log.outError(LogFilter.Sql, "Invalid random enchantment type specified in `item_enchantment_template` table for `entry` {0} `ench` {1}", entry, ench);
|
||||
break;
|
||||
Log.outError(LogFilter.Sql, $"Bonus list {bonusListId} used in `item_random_bonus_list_template` by id {id} doesn't have exist in ItemBonus.db2");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (chance < 0.000001f || chance > 100.0f)
|
||||
{
|
||||
Log.outError(LogFilter.Sql, "Random item enchantment for entry {0} type {1} ench {2} has invalid chance {3}", entry, type, ench, chance);
|
||||
Log.outError(LogFilter.Sql, $"Bonus list {bonusListId} used in `item_random_bonus_list_template` by id {id} has invalid chance {chance}");
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case ItemRandomEnchantmentType.Property:
|
||||
RandomItemEnch[ItemRandomEnchantmentType.Property].Add(entry, new EnchStoreItem(type, ench, chance));
|
||||
break;
|
||||
case ItemRandomEnchantmentType.Suffix:
|
||||
case ItemRandomEnchantmentType.BonusList: // random bonus lists use RandomSuffix field in Item-sparse.db2
|
||||
RandomItemEnch[ItemRandomEnchantmentType.Suffix].Add(entry, new EnchStoreItem(type, ench, chance));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (!_storage.ContainsKey(id))
|
||||
_storage[id] = new RandomBonusListIds();
|
||||
|
||||
RandomBonusListIds ids = _storage[id];
|
||||
ids.BonusListIDs.Add(bonusListId);
|
||||
ids.Chances.Add(chance);
|
||||
|
||||
++count;
|
||||
} while (result.NextRow());
|
||||
|
||||
Log.outInfo(LogFilter.Player, "Loaded {0} Item Enchantment definitions", count);
|
||||
Log.outInfo(LogFilter.Player, $"Loaded {count} Random item bonus list definitions in {Time.GetMSTimeDiffToNow(oldMSTime)} ms");
|
||||
}
|
||||
|
||||
public static ItemRandomEnchantmentId GetItemEnchantMod(int entry, ItemRandomEnchantmentType type)
|
||||
{
|
||||
if (entry == 0)
|
||||
return ItemRandomEnchantmentId.Empty;
|
||||
|
||||
if (entry == -1)
|
||||
return ItemRandomEnchantmentId.Empty;
|
||||
|
||||
var tab = RandomItemEnch[type].LookupByKey(entry);
|
||||
if (tab == null)
|
||||
{
|
||||
Log.outError(LogFilter.Player, "Item RandomProperty / RandomSuffix id #{0} used in `item_template` but it does not have records in `item_enchantment_template` table.", entry);
|
||||
return ItemRandomEnchantmentId.Empty;
|
||||
}
|
||||
|
||||
var selectedItem = tab.SelectRandomElementByWeight(enchant => enchant.chance);
|
||||
|
||||
return new ItemRandomEnchantmentId(selectedItem.type, selectedItem.ench);
|
||||
}
|
||||
|
||||
public static ItemRandomEnchantmentId GenerateItemRandomPropertyId(uint item_id)
|
||||
public static uint GenerateItemRandomBonusListId(uint item_id)
|
||||
{
|
||||
ItemTemplate itemProto = Global.ObjectMgr.GetItemTemplate(item_id);
|
||||
if (itemProto == null)
|
||||
return ItemRandomEnchantmentId.Empty;
|
||||
return 0;
|
||||
|
||||
// item must have one from this field values not null if it can have random enchantments
|
||||
if (itemProto.GetRandomProperty() == 0 && itemProto.GetRandomSuffix() == 0)
|
||||
return ItemRandomEnchantmentId.Empty;
|
||||
if (itemProto.RandomBonusListTemplateId == 0)
|
||||
return 0;
|
||||
|
||||
// item can have not null only one from field values
|
||||
if (itemProto.GetRandomProperty() != 0 && itemProto.GetRandomSuffix() != 0)
|
||||
var tab = _storage.LookupByKey(itemProto.RandomBonusListTemplateId);
|
||||
if (tab == null)
|
||||
{
|
||||
Log.outError(LogFilter.Sql, "Item template {0} have RandomProperty == {1} and RandomSuffix == {2}, but must have one from field =0", itemProto.GetId(), itemProto.GetRandomProperty(), itemProto.GetRandomSuffix());
|
||||
return ItemRandomEnchantmentId.Empty;
|
||||
Log.outError(LogFilter.Sql, $"Item RandomBonusListTemplateId id {itemProto.RandomBonusListTemplateId} used in `item_template_addon` but it does not have records in `item_random_bonus_list_template` table.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// RandomProperty case
|
||||
if (itemProto.GetRandomProperty() != 0)
|
||||
return GetItemEnchantMod((int)itemProto.GetRandomProperty(), ItemRandomEnchantmentType.Property);
|
||||
// RandomSuffix case
|
||||
else
|
||||
return GetItemEnchantMod((int)itemProto.GetRandomSuffix(), ItemRandomEnchantmentType.Suffix);
|
||||
}
|
||||
|
||||
public static uint GenerateEnchSuffixFactor(uint item_id)
|
||||
{
|
||||
ItemTemplate itemProto = Global.ObjectMgr.GetItemTemplate(item_id);
|
||||
|
||||
if (itemProto == null)
|
||||
return 0;
|
||||
if (itemProto.GetRandomSuffix() == 0)
|
||||
return 0;
|
||||
|
||||
return GetRandomPropertyPoints(itemProto.GetBaseItemLevel(), itemProto.GetQuality(), itemProto.GetInventoryType(), itemProto.GetSubClass());
|
||||
//todo fix me this is ulgy
|
||||
return tab.BonusListIDs.SelectRandomElementByWeight(x => (float)tab.Chances[tab.BonusListIDs.IndexOf(x)]);
|
||||
}
|
||||
|
||||
public static uint GetRandomPropertyPoints(uint itemLevel, ItemQuality quality, InventoryType inventoryType, uint subClass)
|
||||
{
|
||||
{
|
||||
uint propIndex;
|
||||
|
||||
switch (inventoryType)
|
||||
{
|
||||
case InventoryType.Head:
|
||||
@@ -208,11 +139,11 @@ namespace Game.Entities
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
RandPropPointsRecord randPropPointsEntry = CliDB.RandPropPointsStorage.LookupByKey(itemLevel);
|
||||
if (randPropPointsEntry == null)
|
||||
return 0;
|
||||
|
||||
// Select rare/epic modifier
|
||||
switch (quality)
|
||||
{
|
||||
case ItemQuality.Uncommon:
|
||||
@@ -225,69 +156,16 @@ namespace Game.Entities
|
||||
case ItemQuality.Artifact:
|
||||
return randPropPointsEntry.Epic[propIndex];
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static EnchantmentStore RandomItemEnch;
|
||||
|
||||
public class EnchStoreItem
|
||||
{
|
||||
public EnchStoreItem()
|
||||
{
|
||||
ench = 0;
|
||||
chance = 0;
|
||||
}
|
||||
public EnchStoreItem(ItemRandomEnchantmentType _type, uint _ench, float _chance)
|
||||
{
|
||||
type = _type;
|
||||
ench = _ench;
|
||||
chance = _chance;
|
||||
}
|
||||
|
||||
public ItemRandomEnchantmentType type;
|
||||
public uint ench;
|
||||
public float chance;
|
||||
}
|
||||
|
||||
class EnchantmentStore
|
||||
{
|
||||
public EnchantmentStore()
|
||||
{
|
||||
_data[(byte)ItemRandomEnchantmentType.Property] = new MultiMap<uint, EnchStoreItem>();
|
||||
_data[(byte)ItemRandomEnchantmentType.Suffix] = new MultiMap<uint, EnchStoreItem>();
|
||||
}
|
||||
|
||||
public MultiMap<uint, EnchStoreItem> this[ItemRandomEnchantmentType type]
|
||||
{
|
||||
get
|
||||
{
|
||||
//(type != ItemRandomEnchantmentType.BonusList, "Random bonus lists do not have their own storage, use Suffix for them");
|
||||
return _data[(byte)type];
|
||||
}
|
||||
}
|
||||
|
||||
MultiMap<uint, EnchStoreItem>[] _data = new MultiMap<uint, EnchStoreItem>[2];
|
||||
}
|
||||
static Dictionary<uint, RandomBonusListIds> _storage = new Dictionary<uint, RandomBonusListIds>();
|
||||
}
|
||||
|
||||
public struct ItemRandomEnchantmentId
|
||||
public class RandomBonusListIds
|
||||
{
|
||||
public static ItemRandomEnchantmentId Empty = default(ItemRandomEnchantmentId);
|
||||
|
||||
public ItemRandomEnchantmentId(ItemRandomEnchantmentType type, uint id)
|
||||
{
|
||||
Type = type;
|
||||
Id = id;
|
||||
}
|
||||
|
||||
public ItemRandomEnchantmentType Type;
|
||||
public uint Id;
|
||||
}
|
||||
|
||||
public enum ItemRandomEnchantmentType
|
||||
{
|
||||
Property = 0,
|
||||
Suffix = 1,
|
||||
BonusList = 2
|
||||
public List<uint> BonusListIDs = new List<uint>();
|
||||
public List<double> Chances = new List<double>();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -223,9 +223,9 @@ namespace Game.Entities
|
||||
if (GetFlags().HasAnyFlag(ItemFlags.IsBoundToAccount) && alwaysAllowBoundToAccount)
|
||||
return true;
|
||||
|
||||
uint spec = player.GetUInt32Value(ActivePlayerFields.LootSpecId);
|
||||
uint spec = player.GetLootSpecId();
|
||||
if (spec == 0)
|
||||
spec = player.GetUInt32Value(PlayerFields.CurrentSpecId);
|
||||
spec = player.GetPrimarySpecialization();
|
||||
if (spec == 0)
|
||||
spec = player.GetDefaultSpecId();
|
||||
|
||||
@@ -295,8 +295,6 @@ namespace Game.Entities
|
||||
public uint GetPageText() { return ExtendedData.PageID; }
|
||||
public uint GetStartQuest() { return ExtendedData.StartQuestID; }
|
||||
public uint GetLockID() { return ExtendedData.LockID; }
|
||||
public uint GetRandomProperty() { return ExtendedData.RandomSelect; }
|
||||
public uint GetRandomSuffix() { return ExtendedData.ItemRandomSuffixGroupID; }
|
||||
public uint GetItemSet() { return ExtendedData.ItemSet; }
|
||||
public uint GetArea() { return ExtendedData.ZoneBound; }
|
||||
public uint GetMap() { return ExtendedData.InstanceBound; }
|
||||
@@ -345,6 +343,7 @@ namespace Game.Entities
|
||||
public uint MaxMoneyLoot;
|
||||
public ItemFlagsCustom FlagsCu;
|
||||
public float SpellPPMRate;
|
||||
public uint RandomBonusListTemplateId;
|
||||
public BitArray[] Specializations = new BitArray[3];
|
||||
public uint ItemSpecClassMask;
|
||||
|
||||
|
||||
@@ -56,13 +56,13 @@ namespace Game.Entities
|
||||
if (buffer.WriteBit(!outOfRangeGUIDs.Empty()))
|
||||
{
|
||||
buffer.WriteUInt16(0); // object limit to instantly destroy - objects before this index on m_outOfRangeGUIDs list get "smoothly phased out"
|
||||
buffer.WriteUInt32(outOfRangeGUIDs.Count);
|
||||
buffer.WriteInt32(outOfRangeGUIDs.Count);
|
||||
|
||||
foreach (var guid in outOfRangeGUIDs)
|
||||
buffer.WritePackedGuid(guid);
|
||||
}
|
||||
var bytes = data.GetData();
|
||||
buffer.WriteUInt32(bytes.Length);
|
||||
buffer.WriteInt32(bytes.Length);
|
||||
buffer.WriteBytes(bytes);
|
||||
|
||||
packet.Data = buffer.GetData();
|
||||
|
||||
@@ -0,0 +1,453 @@
|
||||
/*
|
||||
* Copyright (C) 2012-2019 CypherCore <http://github.com/CypherCore>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using Framework.Constants;
|
||||
using Game.Network;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using System.Reflection;
|
||||
|
||||
namespace Game.Entities
|
||||
{
|
||||
public class UpdateFieldHolder
|
||||
{
|
||||
public UpdateFieldHolder(WorldObject owner) { _owner = owner; }
|
||||
|
||||
public BaseUpdateData<T> ModifyValue<T>(BaseUpdateData<T> updateData)
|
||||
{
|
||||
_changesMask.Set(updateData.Bit);
|
||||
return updateData;
|
||||
}
|
||||
|
||||
public void ClearChangesMask<T>(BaseUpdateData<T> updateData)
|
||||
{
|
||||
_changesMask.Reset(updateData.Bit);
|
||||
}
|
||||
|
||||
public void ClearChangesMask<T, U>(BaseUpdateData<T> updateData, ref UpdateField<U> updateField) where T : new() where U : new()
|
||||
{
|
||||
_changesMask.Reset(updateData.Bit);
|
||||
|
||||
IHasChangesMask hasChangesMask = (IHasChangesMask)updateField._value;
|
||||
if (hasChangesMask != null)
|
||||
hasChangesMask.ClearChangesMask();
|
||||
}
|
||||
|
||||
public uint GetChangedObjectTypeMask()
|
||||
{
|
||||
return _changesMask.GetBlock(0);
|
||||
}
|
||||
|
||||
public bool HasChanged(TypeId index)
|
||||
{
|
||||
return _changesMask[(int)index];
|
||||
}
|
||||
|
||||
UpdateMask _changesMask = new UpdateMask((int)TypeId.Max);
|
||||
WorldObject _owner;
|
||||
}
|
||||
|
||||
public interface IUpdateField<T>
|
||||
{
|
||||
void SetValue(T value);
|
||||
T GetValue();
|
||||
}
|
||||
|
||||
public class UpdateField<T> : IUpdateField<T> where T : new()
|
||||
{
|
||||
public T _value;
|
||||
public int BlockBit;
|
||||
public int Bit;
|
||||
|
||||
public UpdateField(int blockBit, int bit)
|
||||
{
|
||||
BlockBit = blockBit;
|
||||
Bit = bit;
|
||||
_value = new T();
|
||||
}
|
||||
|
||||
public static implicit operator T(UpdateField<T> updateField)
|
||||
{
|
||||
return updateField._value;
|
||||
}
|
||||
|
||||
public void SetValue(T value) { _value = value; }
|
||||
|
||||
public T GetValue() { return _value; }
|
||||
}
|
||||
|
||||
public class UpdateFieldArray<T> where T : new()
|
||||
{
|
||||
public T[] _values;
|
||||
public int FirstElementBit;
|
||||
public int Bit;
|
||||
|
||||
public UpdateFieldArray(uint size, int bit, int firstElementBit)
|
||||
{
|
||||
_values = new T[size];
|
||||
for (var i = 0; i < size; ++i)
|
||||
_values[i] = new T();
|
||||
|
||||
Bit = bit;
|
||||
FirstElementBit = firstElementBit;
|
||||
}
|
||||
|
||||
public T this[int index]
|
||||
{
|
||||
get
|
||||
{
|
||||
return _values[index];
|
||||
}
|
||||
set
|
||||
{
|
||||
_values[index] = value;
|
||||
}
|
||||
}
|
||||
|
||||
public int GetSize() { return _values.Length; }
|
||||
|
||||
public IEnumerator<T> GetEnumerator()
|
||||
{
|
||||
foreach (var obj in _values)
|
||||
yield return obj;
|
||||
}
|
||||
}
|
||||
|
||||
public class DynamicUpdateField<T> where T : new()
|
||||
{
|
||||
public List<T> _values;
|
||||
public List<uint> _updateMask;
|
||||
public int BlockBit;
|
||||
public int Bit;
|
||||
|
||||
public DynamicUpdateField()
|
||||
{
|
||||
_values = new List<T>();
|
||||
_updateMask = new List<uint>();
|
||||
|
||||
BlockBit = -1;
|
||||
Bit = -1;
|
||||
}
|
||||
|
||||
public DynamicUpdateField(int blockBit, int bit)
|
||||
{
|
||||
_values = new List<T>();
|
||||
_updateMask = new List<uint>();
|
||||
|
||||
BlockBit = blockBit;
|
||||
Bit = bit;
|
||||
}
|
||||
|
||||
public int FindIndex(T value)
|
||||
{
|
||||
return _values.IndexOf(value);
|
||||
}
|
||||
|
||||
public bool HasChanged(int index)
|
||||
{
|
||||
return (_updateMask[index / 32] & (1 << (index % 32))) != 0;
|
||||
}
|
||||
|
||||
public void WriteUpdateMask(WorldPacket data)
|
||||
{
|
||||
data.WriteBits(_values.Count, 32);
|
||||
if (_values.Count > 32)
|
||||
{
|
||||
if (data.HasUnfinishedBitPack())
|
||||
for (int block = 0; block < _values.Count / 32; ++block)
|
||||
data.WriteBits(_updateMask[block], 32);
|
||||
else
|
||||
for (int block = 0; block < _values.Count / 32; ++block)
|
||||
data.WriteUInt32(_updateMask[block]);
|
||||
}
|
||||
|
||||
if ((_values.Count % 32) != 0)
|
||||
data.WriteBits(_updateMask.Last(), _values.Count % 32);
|
||||
}
|
||||
|
||||
public void ClearChangesMask()
|
||||
{
|
||||
for (var i = 0; i < _updateMask.Count; ++i)
|
||||
_updateMask[i] = 0;
|
||||
}
|
||||
|
||||
public void AddValue(T value)
|
||||
{
|
||||
MarkChanged(_values.Count);
|
||||
|
||||
if (value is IHasChangesMask)
|
||||
{
|
||||
IHasChangesMask hasChanges = (IHasChangesMask)value;
|
||||
if (hasChanges != null)
|
||||
hasChanges.GetUpdateMask().SetAll();
|
||||
}
|
||||
|
||||
_values.Add(value);
|
||||
}
|
||||
|
||||
public void InsertValue(int index, T value)
|
||||
{
|
||||
_values.Insert(index, value);
|
||||
for (int i = index; i < _values.Count; ++i)
|
||||
{
|
||||
MarkChanged(i);
|
||||
// also mark all fields of value as changed
|
||||
IHasChangesMask hasChangesMask = (IHasChangesMask)_values[i];
|
||||
if (hasChangesMask != null)
|
||||
hasChangesMask.GetUpdateMask().SetAll();
|
||||
}
|
||||
}
|
||||
|
||||
public void RemoveValue(int index)
|
||||
{
|
||||
// remove by shifting entire container - client might rely on values being sorted for certain fields
|
||||
_values.RemoveAt(index);
|
||||
for (int i = index; i < _values.Count; ++i)
|
||||
{
|
||||
MarkChanged(i);
|
||||
// also mark all fields of value as changed
|
||||
IHasChangesMask hasChanges = (IHasChangesMask)_values[i];
|
||||
if (hasChanges != null)
|
||||
hasChanges.GetUpdateMask().SetAll();
|
||||
}
|
||||
if ((_values.Count % 32) != 0)
|
||||
_updateMask[UpdateMask.GetBlockIndex(_values.Count)] &= (uint)~UpdateMask.GetBlockFlag(_values.Count);
|
||||
else
|
||||
_updateMask.RemoveAt(_updateMask.Count - 1);
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
_values.Clear();
|
||||
_updateMask.Clear();
|
||||
}
|
||||
|
||||
public void MarkChanged(int index)
|
||||
{
|
||||
int block = UpdateMask.GetBlockIndex(index);
|
||||
if (block >= _updateMask.Count)
|
||||
_updateMask.Add(0);
|
||||
|
||||
_updateMask[block] |= (uint)UpdateMask.GetBlockFlag(index);
|
||||
}
|
||||
|
||||
public void ClearChanged(int index)
|
||||
{
|
||||
int block = UpdateMask.GetBlockIndex(index);
|
||||
if (block >= _updateMask.Count)
|
||||
_updateMask.Add(0);
|
||||
|
||||
_updateMask[block] &= ~(uint)UpdateMask.GetBlockFlag(index);
|
||||
}
|
||||
|
||||
public int Size()
|
||||
{
|
||||
return _values.Count;
|
||||
}
|
||||
|
||||
public T this[int index]
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_values.Count <= index)
|
||||
_values.Add(new T());
|
||||
|
||||
return _values[index];
|
||||
}
|
||||
set
|
||||
{
|
||||
_values[index] = value;
|
||||
}
|
||||
}
|
||||
|
||||
public static implicit operator List<T>(DynamicUpdateField<T> updateField)
|
||||
{
|
||||
return updateField._values;
|
||||
}
|
||||
|
||||
public IEnumerator<T> GetEnumerator()
|
||||
{
|
||||
foreach (var obj in _values)
|
||||
yield return obj;
|
||||
}
|
||||
}
|
||||
|
||||
public interface IHasChangesMask
|
||||
{
|
||||
void ClearChangesMask();
|
||||
UpdateMask GetUpdateMask();
|
||||
}
|
||||
|
||||
public abstract class BaseUpdateData<T> : IHasChangesMask
|
||||
{
|
||||
public UpdateMask _changesMask;
|
||||
public int _blockBit;
|
||||
public int Bit;
|
||||
|
||||
public BaseUpdateData(int blockBit, TypeId bit, int changeMask)
|
||||
{
|
||||
_blockBit = blockBit;
|
||||
Bit = (int)bit;
|
||||
_changesMask = new UpdateMask(changeMask);
|
||||
}
|
||||
|
||||
public BaseUpdateData(int changeMask)
|
||||
{
|
||||
_changesMask = new UpdateMask(changeMask);
|
||||
}
|
||||
|
||||
public abstract void WriteCreate(WorldPacket data, UpdateFieldFlag fieldVisibilityFlags, T owner, Player receiver);
|
||||
public abstract void WriteUpdate(WorldPacket data, UpdateFieldFlag fieldVisibilityFlags, T owner, Player receiver);
|
||||
|
||||
public abstract void ClearChangesMask();
|
||||
|
||||
public UpdateMask GetUpdateMask()
|
||||
{
|
||||
return _changesMask;
|
||||
}
|
||||
|
||||
public void ClearChanged<U>(UpdateField<U> updateField) where U : new()
|
||||
{
|
||||
_changesMask.Reset(updateField.Bit);
|
||||
}
|
||||
|
||||
public void ClearChanged<U>(UpdateFieldArray<U> updateField, int index) where U : new()
|
||||
{
|
||||
_changesMask.Reset(updateField.Bit);
|
||||
_changesMask.Reset(updateField.FirstElementBit + index);
|
||||
}
|
||||
|
||||
public void ClearChanged<U>(DynamicUpdateField<U> updateField, int index) where U : new()
|
||||
{
|
||||
_changesMask.Reset(Bit);
|
||||
updateField.ClearChanged(index);
|
||||
}
|
||||
|
||||
public void ClearChangesMask<U>(UpdateField<U> updateField) where U : new()
|
||||
{
|
||||
if (typeof(U).BaseType == typeof(IHasChangesMask))
|
||||
((IHasChangesMask)updateField._value).ClearChangesMask();
|
||||
}
|
||||
|
||||
public void ClearChangesMask<U>(UpdateFieldArray<U> updateField) where U : new()
|
||||
{
|
||||
if (typeof(U).BaseType == typeof(IHasChangesMask))
|
||||
{
|
||||
for (int i = 0; i < updateField.GetSize(); ++i)
|
||||
((IHasChangesMask)updateField[i]).ClearChangesMask();
|
||||
}
|
||||
}
|
||||
|
||||
public void ClearChangesMask<U>(DynamicUpdateField<U> updateField) where U : new()
|
||||
{
|
||||
if (typeof(U).BaseType == typeof(IHasChangesMask))
|
||||
{
|
||||
for (int i = 0; i < updateField.Size(); ++i)
|
||||
((IHasChangesMask)updateField[i]).ClearChangesMask();
|
||||
|
||||
updateField.ClearChangesMask();
|
||||
}
|
||||
}
|
||||
|
||||
public UpdateField<UU> ModifyValue<U, UU>(Expression<Func<U, UpdateField<UU>>> expression) where UU : new()
|
||||
{
|
||||
var fieldInfo = ((MemberExpression)expression.Body).Member as FieldInfo;
|
||||
if (fieldInfo == null)
|
||||
throw new ArgumentException("The lambda expression 'property' should point to a valid Property");
|
||||
|
||||
var updateField = (UpdateField<UU>)fieldInfo.GetValue(this);
|
||||
_changesMask.Set(updateField.BlockBit);
|
||||
_changesMask.Set(updateField.Bit);
|
||||
return updateField;
|
||||
}
|
||||
|
||||
public ref UU ModifyValue<U, UU>(Expression<Func<U, UpdateFieldArray<UU>>> expression, int index) where UU : new()
|
||||
{
|
||||
var fieldInfo = ((MemberExpression)expression.Body).Member as FieldInfo;
|
||||
if (fieldInfo == null)
|
||||
throw new ArgumentException("The lambda expression 'property' should point to a valid Property");
|
||||
|
||||
var updateFieldArray = (UpdateFieldArray<UU>)fieldInfo.GetValue(this);
|
||||
_changesMask.Set(updateFieldArray.Bit);
|
||||
_changesMask.Set(updateFieldArray.FirstElementBit + index);
|
||||
return ref updateFieldArray._values[index];
|
||||
}
|
||||
|
||||
public UpdateField<U> ModifyValue<U>(UpdateField<U> updateField) where U : new()
|
||||
{
|
||||
_changesMask.Set(updateField.BlockBit);
|
||||
_changesMask.Set(updateField.Bit);
|
||||
return updateField;
|
||||
}
|
||||
|
||||
public ref U ModifyValue<U>(UpdateFieldArray<U> updateField, int index) where U : new()
|
||||
{
|
||||
_changesMask.Set(updateField.Bit);
|
||||
_changesMask.Set(updateField.FirstElementBit + index);
|
||||
return ref updateField._values[index];
|
||||
}
|
||||
|
||||
public DynamicUpdateField<U> ModifyValue<U>(DynamicUpdateField<U> updateField) where U : new()
|
||||
{
|
||||
_changesMask.Set(updateField.BlockBit);
|
||||
_changesMask.Set(updateField.Bit);
|
||||
return updateField;
|
||||
}
|
||||
|
||||
public DynamicUpdateFieldSetter<U> ModifyValue<U>(DynamicUpdateField<U> updateField, int index) where U : new()
|
||||
{
|
||||
if (index >= updateField._values.Count)
|
||||
{
|
||||
// fill with zeros until reaching desired slot
|
||||
updateField._values.Resize((uint)index + 1);
|
||||
updateField._updateMask.Resize((uint)(updateField._values.Count + 31) / 32);
|
||||
}
|
||||
|
||||
_changesMask.Set(updateField.BlockBit);
|
||||
_changesMask.Set(updateField.Bit);
|
||||
updateField.MarkChanged(index);
|
||||
|
||||
return new DynamicUpdateFieldSetter<U>(updateField, index);
|
||||
}
|
||||
}
|
||||
|
||||
public class DynamicUpdateFieldSetter<T> : IUpdateField<T> where T : new()
|
||||
{
|
||||
public DynamicUpdateFieldSetter(DynamicUpdateField<T> dynamicUpdateField, int index)
|
||||
{
|
||||
_dynamicUpdateField = dynamicUpdateField;
|
||||
_index = index;
|
||||
}
|
||||
|
||||
public void SetValue(T value)
|
||||
{
|
||||
_dynamicUpdateField[_index] = value;
|
||||
}
|
||||
|
||||
public T GetValue() { return _dynamicUpdateField[_index]; }
|
||||
|
||||
public static implicit operator T(DynamicUpdateFieldSetter<T> dynamicUpdateFieldSetter)
|
||||
{
|
||||
return dynamicUpdateFieldSetter.GetValue();
|
||||
}
|
||||
|
||||
DynamicUpdateField<T> _dynamicUpdateField;
|
||||
int _index;
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -24,88 +24,127 @@ namespace Game.Entities
|
||||
{
|
||||
public class UpdateMask
|
||||
{
|
||||
public UpdateMask(uint valuesCount = 0)
|
||||
{
|
||||
_fieldCount = valuesCount;
|
||||
_blockCount = (valuesCount + 32 - 1) / 32;
|
||||
int _blockCount;
|
||||
int _blocksMaskCount;
|
||||
uint[] _blocks;
|
||||
uint[] _blocksMask;
|
||||
|
||||
_mask = new BitArray((int)valuesCount, false);
|
||||
public UpdateMask(int bits, uint[] input = null)
|
||||
{
|
||||
_blockCount = (bits + 31) / 32;
|
||||
_blocksMaskCount = (_blockCount + 31) / 32;
|
||||
|
||||
|
||||
_blocks = new uint[_blockCount];
|
||||
_blocksMask = new uint[_blocksMaskCount];
|
||||
|
||||
if (input != null)
|
||||
{
|
||||
int block = 0;
|
||||
for (; block < input.Length; ++block)
|
||||
if ((_blocks[block] = input[block]) != 0)
|
||||
_blocksMask[GetBlockIndex(block)] |= (uint)GetBlockFlag(block);
|
||||
|
||||
for (; block < _blockCount; ++block)
|
||||
_blocks[block] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
public void SetCount(int valuesCount)
|
||||
public uint GetBlocksMask(uint index)
|
||||
{
|
||||
_fieldCount = (uint)valuesCount;
|
||||
_blockCount = (uint)(valuesCount + 32 - 1) / 32;
|
||||
|
||||
_mask = new BitArray((int)valuesCount, false);
|
||||
return _blocksMask[index];
|
||||
}
|
||||
|
||||
public uint GetCount() { return _fieldCount; }
|
||||
|
||||
public virtual void AppendToPacket(ByteBuffer data)
|
||||
public uint GetBlock(uint index)
|
||||
{
|
||||
data.WriteUInt8(_blockCount);
|
||||
var maskArray = new byte[_blockCount << 2];
|
||||
|
||||
_mask.CopyTo(maskArray, 0);
|
||||
data.WriteBytes(maskArray);
|
||||
return _blocks[index];
|
||||
}
|
||||
|
||||
public bool GetBit(int index)
|
||||
public bool this[int index]
|
||||
{
|
||||
return _mask.Get(index);
|
||||
get
|
||||
{
|
||||
return (_blocks[index / 32] & (1 << (index % 32))) != 0;
|
||||
}
|
||||
}
|
||||
|
||||
public void SetBit(int index)
|
||||
public void Reset(int index)
|
||||
{
|
||||
_mask.Set(index, true);
|
||||
int blockIndex = GetBlockIndex(index);
|
||||
if ((_blocks[blockIndex] &= ~(uint)GetBlockFlag(index)) == 0)
|
||||
_blocksMask[GetBlockIndex(blockIndex)] &= ~(uint)GetBlockFlag(blockIndex);
|
||||
}
|
||||
|
||||
void UnsetBit(int index)
|
||||
public void ResetAll()
|
||||
{
|
||||
_mask.Set(index, false);
|
||||
Array.Clear(_blocks, 0, _blocks.Length);
|
||||
Array.Clear(_blocksMask, 0, _blocksMask.Length);
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
public void Set(int index)
|
||||
{
|
||||
_mask.SetAll(false);
|
||||
int blockIndex = GetBlockIndex(index);
|
||||
_blocks[blockIndex] |= (uint)GetBlockFlag(index);
|
||||
_blocksMask[GetBlockIndex(blockIndex)] |= (uint)GetBlockFlag(blockIndex);
|
||||
}
|
||||
|
||||
protected uint _fieldCount;
|
||||
protected uint _blockCount;
|
||||
protected BitArray _mask;
|
||||
}
|
||||
|
||||
public class DynamicUpdateMask : UpdateMask
|
||||
{
|
||||
public DynamicUpdateMask(uint valuesCount) : base(valuesCount) { }
|
||||
|
||||
public void EncodeDynamicFieldChangeType(DynamicFieldChangeType changeType, UpdateType updateType)
|
||||
public void SetAll()
|
||||
{
|
||||
_updateType = updateType;
|
||||
DynamicFieldChangeType = (uint)(_blockCount | ((uint)(changeType & Entities.DynamicFieldChangeType.ValueAndSizeChanged) * ((3 - (int)updateType /*this part evaluates to 0 if update type is not VALUES*/) / 3)));
|
||||
for (int i = 0; i < _blocksMaskCount; ++i)
|
||||
_blocksMask[i] = 0xFFFFFFFF;
|
||||
for (int i = 0; i < _blockCount; ++i)
|
||||
_blocks[i] = 0xFFFFFFFF;
|
||||
|
||||
if ((_blocksMaskCount % 32) != 0)
|
||||
{
|
||||
int unused = 32 - (_blocksMaskCount % 32);
|
||||
_blocksMask[_blocksMaskCount - 1] &= (0xFFFFFFFF >> unused);
|
||||
}
|
||||
|
||||
if ((_blockCount % 32) != 0)
|
||||
{
|
||||
int unused = 32 - (_blockCount % 32);
|
||||
_blocks[_blockCount - 1] &= (0xFFFFFFFF >> unused);
|
||||
}
|
||||
}
|
||||
|
||||
public override void AppendToPacket(ByteBuffer data)
|
||||
public void AND(UpdateMask right)
|
||||
{
|
||||
data.WriteUInt16(DynamicFieldChangeType);
|
||||
if (DynamicFieldChangeType.HasAnyFlag((uint)Entities.DynamicFieldChangeType.ValueAndSizeChanged) && _updateType == UpdateType.Values)
|
||||
data.WriteUInt32(_fieldCount);
|
||||
for (int i = 0; i < _blocksMaskCount; ++i)
|
||||
_blocksMask[i] &= right._blocksMask[i];
|
||||
|
||||
var maskArray = new byte[_blockCount << 2];
|
||||
|
||||
_mask.CopyTo(maskArray, 0);
|
||||
data.WriteBytes(maskArray);
|
||||
for (int i = 0; i < _blockCount; ++i)
|
||||
{
|
||||
if (!Convert.ToBoolean(_blocks[i] &= right._blocks[i]))
|
||||
_blocksMask[GetBlockIndex(i)] &= ~(uint)GetBlockFlag(i);
|
||||
}
|
||||
}
|
||||
|
||||
public uint DynamicFieldChangeType;
|
||||
public UpdateType _updateType;
|
||||
}
|
||||
public void OR(UpdateMask right)
|
||||
{
|
||||
for (int i = 0; i < _blocksMaskCount; ++i)
|
||||
_blocksMask[i] |= right._blocksMask[i];
|
||||
|
||||
public enum DynamicFieldChangeType
|
||||
{
|
||||
Unchanged = 0,
|
||||
ValueChanged = 0x7FFF,
|
||||
ValueAndSizeChanged = 0x8000
|
||||
for (int i = 0; i < _blockCount; ++i)
|
||||
_blocks[i] |= right._blocks[i];
|
||||
}
|
||||
|
||||
public static UpdateMask operator &(UpdateMask left, UpdateMask right)
|
||||
{
|
||||
UpdateMask result = left;
|
||||
result.AND(right);
|
||||
return result;
|
||||
}
|
||||
|
||||
public static UpdateMask operator |(UpdateMask left, UpdateMask right)
|
||||
{
|
||||
UpdateMask result = left;
|
||||
result.OR(right);
|
||||
return result;
|
||||
}
|
||||
|
||||
//helpers
|
||||
public static int GetBlockIndex(int bit) { return bit / 32; }
|
||||
public static int GetBlockFlag(int bit) { return 1 << (bit % 32); }
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
+37
-33
@@ -174,8 +174,8 @@ namespace Game.Entities
|
||||
PhasingHandler.InheritPhaseShift(this, owner);
|
||||
|
||||
setPetType(petType);
|
||||
SetFaction(owner.getFaction());
|
||||
SetUInt32Value(UnitFields.CreatedBySpell, summonSpellId);
|
||||
SetFaction(owner.GetFaction());
|
||||
SetCreatedBySpell(summonSpellId);
|
||||
|
||||
float px, py, pz;
|
||||
if (IsCritter())
|
||||
@@ -199,7 +199,8 @@ namespace Game.Entities
|
||||
SetDisplayId(result.Read<uint>(3));
|
||||
SetNativeDisplayId(result.Read<uint>(3));
|
||||
uint petlevel = result.Read<ushort>(4);
|
||||
SetUInt64Value(UnitFields.NpcFlags, (ulong)NPCFlags.None);
|
||||
SetNpcFlags(NPCFlags.None);
|
||||
SetNpcFlags2(NPCFlags2.None);
|
||||
SetName(result.Read<string>(8));
|
||||
|
||||
switch (getPetType())
|
||||
@@ -207,16 +208,15 @@ namespace Game.Entities
|
||||
case PetType.Summon:
|
||||
petlevel = owner.getLevel();
|
||||
|
||||
SetByteValue(UnitFields.Bytes0, 1, (byte)Class.Mage);
|
||||
SetUInt32Value(UnitFields.Flags, (uint)UnitFlags.PvpAttackable); // this enables popup window (pet dismiss, cancel)
|
||||
SetClass(Class.Mage);
|
||||
SetUnitFlags(UnitFlags.PvpAttackable); // this enables popup window (pet dismiss, cancel)
|
||||
break;
|
||||
case PetType.Hunter:
|
||||
SetByteValue(UnitFields.Bytes0, 1, (byte)Class.Warrior);
|
||||
SetByteValue(UnitFields.Bytes0, 3, (byte)Gender.None);
|
||||
SetClass(Class.Warrior);
|
||||
SetGender(Gender.None);
|
||||
SetSheath(SheathState.Melee);
|
||||
SetByteFlag(UnitFields.Bytes2, UnitBytes2Offsets.PetFlags, (result.Read<bool>(9) ? UnitPetFlags.CanBeAbandoned : UnitPetFlags.CanBeRenamed | UnitPetFlags.CanBeAbandoned));
|
||||
|
||||
SetUInt32Value(UnitFields.Flags, (uint)UnitFlags.PvpAttackable); // this enables popup window (pet abandon, cancel)
|
||||
SetPetFlags(result.Read<bool>(9) ? UnitPetFlags.CanBeAbandoned : UnitPetFlags.CanBeRenamed | UnitPetFlags.CanBeAbandoned);
|
||||
SetUnitFlags(UnitFlags.PvpAttackable); // this enables popup window (pet abandon, cancel)
|
||||
break;
|
||||
default:
|
||||
if (!IsPetGhoul())
|
||||
@@ -224,11 +224,11 @@ namespace Game.Entities
|
||||
break;
|
||||
}
|
||||
|
||||
SetUInt32Value(UnitFields.PetNameTimestamp, (uint)Time.UnixTime); // cast can't be helped here
|
||||
SetPetNameTimestamp((uint)Time.UnixTime); // cast can't be helped here
|
||||
SetCreatorGUID(owner.GetGUID());
|
||||
|
||||
InitStatsForLevel(petlevel);
|
||||
SetUInt32Value(UnitFields.PetExperience, result.Read<uint>(5));
|
||||
SetPetExperience(result.Read<uint>(5));
|
||||
|
||||
SynchronizeLevelWithOwner();
|
||||
|
||||
@@ -443,16 +443,16 @@ namespace Game.Entities
|
||||
stmt.AddValue(2, ownerLowGUID);
|
||||
stmt.AddValue(3, GetNativeDisplayId());
|
||||
stmt.AddValue(4, getLevel());
|
||||
stmt.AddValue(5, GetUInt32Value(UnitFields.PetExperience));
|
||||
stmt.AddValue(5, (uint)m_unitData.PetExperience);
|
||||
stmt.AddValue(6, GetReactState());
|
||||
stmt.AddValue(7, mode);
|
||||
stmt.AddValue(8, GetName());
|
||||
stmt.AddValue(9, HasByteFlag(UnitFields.Bytes2, UnitBytes2Offsets.PetFlags, UnitPetFlags.CanBeRenamed) ? 0 : 1);
|
||||
stmt.AddValue(9, HasPetFlag(UnitPetFlags.CanBeRenamed) ? 0 : 1);
|
||||
stmt.AddValue(10, curhealth);
|
||||
stmt.AddValue(11, curmana);
|
||||
stmt.AddValue(12, GenerateActionBarData());
|
||||
stmt.AddValue(13, Time.UnixTime);
|
||||
stmt.AddValue(14, GetUInt32Value(UnitFields.CreatedBySpell));
|
||||
stmt.AddValue(14, (uint)m_unitData.CreatedBySpell);
|
||||
stmt.AddValue(15, getPetType());
|
||||
stmt.AddValue(16, m_petSpecialization);
|
||||
trans.Append(stmt);
|
||||
@@ -510,8 +510,8 @@ namespace Game.Entities
|
||||
if (getPetType() == PetType.Hunter)
|
||||
{
|
||||
// pet corpse non lootable and non skinnable
|
||||
SetUInt32Value(ObjectFields.DynamicFlags, (uint)UnitDynFlags.None);
|
||||
RemoveFlag(UnitFields.Flags, UnitFlags.Skinnable);
|
||||
SetDynamicFlags(UnitDynFlags.None);
|
||||
RemoveUnitFlag(UnitFlags.Skinnable);
|
||||
}
|
||||
}
|
||||
else if (getDeathState() == DeathState.Alive)
|
||||
@@ -626,8 +626,8 @@ namespace Game.Entities
|
||||
if (petlevel >= maxlevel)
|
||||
return;
|
||||
|
||||
uint nextLvlXP = GetUInt32Value(UnitFields.PetNextLevelExp);
|
||||
uint curXP = GetUInt32Value(UnitFields.PetExperience);
|
||||
uint nextLvlXP = m_unitData.PetNextLevelExperience;
|
||||
uint curXP = m_unitData.PetExperience;
|
||||
uint newXP = curXP + xp;
|
||||
|
||||
// Check how much XP the pet should receive, and hand off have any left from previous levelups
|
||||
@@ -639,10 +639,10 @@ namespace Game.Entities
|
||||
|
||||
GivePetLevel((int)petlevel);
|
||||
|
||||
nextLvlXP = GetUInt32Value(UnitFields.PetNextLevelExp);
|
||||
nextLvlXP = m_unitData.PetNextLevelExperience;
|
||||
}
|
||||
// Not affected by special conditions - give it new XP
|
||||
SetUInt32Value(UnitFields.PetExperience, petlevel < maxlevel ? newXP : 0);
|
||||
SetPetExperience(petlevel < maxlevel ? newXP : 0);
|
||||
}
|
||||
|
||||
public void GivePetLevel(int level)
|
||||
@@ -652,8 +652,8 @@ namespace Game.Entities
|
||||
|
||||
if (getPetType() == PetType.Hunter)
|
||||
{
|
||||
SetUInt32Value(UnitFields.PetExperience, 0);
|
||||
SetUInt32Value(UnitFields.PetNextLevelExp, (uint)(Global.ObjectMgr.GetXPForLevel((uint)level) * PetXPFactor));
|
||||
SetPetExperience(0);
|
||||
SetPetNextLevelExperience((uint)(Global.ObjectMgr.GetXPForLevel((uint)level) * PetXPFactor));
|
||||
}
|
||||
|
||||
InitStatsForLevel((uint)level);
|
||||
@@ -712,18 +712,19 @@ namespace Game.Entities
|
||||
if (!Create(map.GenerateLowGuid(HighGuid.Pet), map, cinfo.Entry))
|
||||
return false;
|
||||
|
||||
SetUInt32Value(UnitFields.PetNameTimestamp, 0);
|
||||
SetUInt32Value(UnitFields.PetExperience, 0);
|
||||
SetUInt32Value(UnitFields.PetNextLevelExp, (uint)(Global.ObjectMgr.GetXPForLevel(getLevel() + 1) * PetXPFactor));
|
||||
SetUInt64Value(UnitFields.NpcFlags, (ulong)NPCFlags.None);
|
||||
SetPetNameTimestamp(0);
|
||||
SetPetExperience(0);
|
||||
SetPetNextLevelExperience((uint)(Global.ObjectMgr.GetXPForLevel(getLevel() + 1) * PetXPFactor));
|
||||
SetNpcFlags(NPCFlags.None);
|
||||
SetNpcFlags2(NPCFlags2.None);
|
||||
|
||||
if (cinfo.CreatureType == CreatureType.Beast)
|
||||
{
|
||||
SetByteValue(UnitFields.Bytes0, 1, (byte)Class.Warrior);
|
||||
SetByteValue(UnitFields.Bytes0, 3, (byte)Gender.None);
|
||||
SetUInt32Value(UnitFields.DisplayPower, (uint)PowerType.Focus);
|
||||
SetClass(Class.Warrior);
|
||||
SetGender(Gender.None);
|
||||
SetPowerType(PowerType.Focus);
|
||||
SetSheath(SheathState.Melee);
|
||||
SetByteFlag(UnitFields.Bytes2, UnitBytes2Offsets.PetFlags, (UnitPetFlags.CanBeRenamed | UnitPetFlags.CanBeAbandoned));
|
||||
SetPetFlags(UnitPetFlags.CanBeRenamed | UnitPetFlags.CanBeAbandoned);
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -1347,7 +1348,7 @@ namespace Game.Entities
|
||||
return false;
|
||||
|
||||
// Force regen flag for player pets, just like we do for players themselves
|
||||
SetFlag(UnitFields.Flags2, UnitFlags2.RegeneratePower);
|
||||
AddUnitFlag2(UnitFlags2.RegeneratePower);
|
||||
SetSheath(SheathState.Melee);
|
||||
|
||||
return true;
|
||||
@@ -1472,7 +1473,7 @@ namespace Game.Entities
|
||||
}
|
||||
|
||||
public PetType getPetType() { return m_petType; }
|
||||
void setPetType(PetType type) { m_petType = type; }
|
||||
public void setPetType(PetType type) { m_petType = type; }
|
||||
public bool isControlled() { return getPetType() == PetType.Summon || getPetType() == PetType.Hunter; }
|
||||
public bool isTemporarySummoned() { return m_duration > 0; }
|
||||
|
||||
@@ -1490,6 +1491,9 @@ namespace Game.Entities
|
||||
public void SetDuration(uint dur) { m_duration = (int)dur; }
|
||||
public int GetDuration() { return m_duration; }
|
||||
|
||||
public void SetPetExperience(uint xp) { SetUpdateFieldValue(m_values.ModifyValue(m_unitData).ModifyValue(m_unitData.PetExperience), xp); }
|
||||
public void SetPetNextLevelExperience(uint xp) { SetUpdateFieldValue(m_values.ModifyValue(m_unitData).ModifyValue(m_unitData.PetNextLevelExperience), xp); }
|
||||
|
||||
public ushort GetSpecialization() { return m_petSpecialization; }
|
||||
|
||||
public GroupUpdatePetFlags GetGroupUpdateFlag() { return m_groupUpdateMask; }
|
||||
|
||||
@@ -69,15 +69,15 @@ namespace Game.Entities
|
||||
|
||||
public void LoadToys()
|
||||
{
|
||||
foreach (var value in _toys.Keys)
|
||||
_owner.GetPlayer().AddDynamicValue(ActivePlayerDynamicFields.Toys, value);
|
||||
foreach (var pair in _toys)
|
||||
_owner.GetPlayer().AddToy(pair.Key, (uint)pair.Value);
|
||||
}
|
||||
|
||||
public bool AddToy(uint itemId, bool isFavourite, bool hasFanfare)
|
||||
{
|
||||
if (UpdateAccountToys(itemId, isFavourite, hasFanfare))
|
||||
{
|
||||
_owner.GetPlayer().AddDynamicValue(ActivePlayerDynamicFields.Toys, itemId);
|
||||
_owner.GetPlayer().AddToy(itemId, (uint)GetToyFlags(isFavourite, hasFanfare));
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -92,8 +92,7 @@ namespace Game.Entities
|
||||
do
|
||||
{
|
||||
uint itemId = result.Read<uint>(0);
|
||||
|
||||
_toys[itemId] = GetToyFlags(result.Read<bool>(1), result.Read<bool>(2));
|
||||
_toys.Add(itemId, GetToyFlags(result.Read<bool>(1), result.Read<bool>(2)));
|
||||
} while (result.NextRow());
|
||||
}
|
||||
|
||||
@@ -175,7 +174,9 @@ namespace Game.Entities
|
||||
|
||||
uint bonusId = 0;
|
||||
|
||||
if (flags.HasAnyFlag(HeirloomPlayerFlags.BonusLevel110))
|
||||
if (flags.HasAnyFlag(HeirloomPlayerFlags.BonusLevel120))
|
||||
bonusId = heirloom.UpgradeItemBonusListID[3];
|
||||
else if (flags.HasAnyFlag(HeirloomPlayerFlags.BonusLevel110))
|
||||
bonusId = heirloom.UpgradeItemBonusListID[2];
|
||||
else if (flags.HasAnyFlag(HeirloomPlayerFlags.BonusLevel100))
|
||||
bonusId = heirloom.UpgradeItemBonusListID[1];
|
||||
@@ -220,19 +221,13 @@ namespace Game.Entities
|
||||
public void LoadHeirlooms()
|
||||
{
|
||||
foreach (var item in _heirlooms)
|
||||
{
|
||||
_owner.GetPlayer().AddDynamicValue(ActivePlayerDynamicFields.Heirlooms, item.Key);
|
||||
_owner.GetPlayer().AddDynamicValue(ActivePlayerDynamicFields.HeirloomFlags, (uint)item.Value.flags);
|
||||
}
|
||||
_owner.GetPlayer().AddHeirloom(item.Key, (uint)item.Value.flags);
|
||||
}
|
||||
|
||||
public void AddHeirloom(uint itemId, HeirloomPlayerFlags flags)
|
||||
{
|
||||
if (UpdateAccountHeirlooms(itemId, flags))
|
||||
{
|
||||
_owner.GetPlayer().AddDynamicValue(ActivePlayerDynamicFields.Heirlooms, itemId);
|
||||
_owner.GetPlayer().AddDynamicValue(ActivePlayerDynamicFields.HeirloomFlags, (uint)flags);
|
||||
}
|
||||
_owner.GetPlayer().AddHeirloom(itemId, (uint)flags);
|
||||
}
|
||||
|
||||
public void UpgradeHeirloom(uint itemId, uint castItem)
|
||||
@@ -267,15 +262,20 @@ namespace Game.Entities
|
||||
flags |= HeirloomPlayerFlags.BonusLevel110;
|
||||
bonusId = heirloom.UpgradeItemBonusListID[2];
|
||||
}
|
||||
if (heirloom.UpgradeItemID[3] == castItem)
|
||||
{
|
||||
flags |= HeirloomPlayerFlags.BonusLevel120;
|
||||
bonusId = heirloom.UpgradeItemBonusListID[3];
|
||||
}
|
||||
|
||||
foreach (Item item in player.GetItemListByEntry(itemId, true))
|
||||
item.AddBonuses(bonusId);
|
||||
|
||||
// Get heirloom offset to update only one part of dynamic field
|
||||
var fields = player.GetDynamicValues(ActivePlayerDynamicFields.Heirlooms);
|
||||
ushort offset = (ushort)Array.IndexOf(fields, itemId);
|
||||
List<uint> heirlooms = player.m_activePlayerData.Heirlooms;
|
||||
int offset = heirlooms.IndexOf(itemId);
|
||||
|
||||
player.SetDynamicValue(ActivePlayerDynamicFields.HeirloomFlags, offset, (uint)flags);
|
||||
player.SetHeirloomFlags(offset, (uint)flags);
|
||||
data.flags = flags;
|
||||
data.bonusId = bonusId;
|
||||
}
|
||||
@@ -315,11 +315,11 @@ namespace Game.Entities
|
||||
|
||||
if (newItemId != 0)
|
||||
{
|
||||
var heirloomFields = player.GetDynamicValues(ActivePlayerDynamicFields.Heirlooms);
|
||||
ushort offset = (ushort)Array.IndexOf(heirloomFields, item.GetEntry());
|
||||
List<uint> heirlooms = player.m_activePlayerData.Heirlooms;
|
||||
int offset = heirlooms.IndexOf(item.GetEntry());
|
||||
|
||||
player.SetDynamicValue(ActivePlayerDynamicFields.Heirlooms, offset, newItemId);
|
||||
player.SetDynamicValue(ActivePlayerDynamicFields.HeirloomFlags, offset, 0);
|
||||
player.SetHeirloom(offset, newItemId);
|
||||
player.SetHeirloomFlags(offset, 0);
|
||||
|
||||
_heirlooms.Remove(item.GetEntry());
|
||||
_heirlooms[newItemId] = null;
|
||||
@@ -327,12 +327,17 @@ namespace Game.Entities
|
||||
return;
|
||||
}
|
||||
|
||||
var fields = item.GetDynamicValues(ItemDynamicFields.BonusListIds);
|
||||
foreach (uint bonusId in fields)
|
||||
List<uint> bonusListIDs = item.m_itemData.BonusListIDs;
|
||||
foreach (uint bonusId in bonusListIDs)
|
||||
{
|
||||
if (bonusId != data.bonusId)
|
||||
item.ClearDynamicValue(ItemDynamicFields.BonusListIds);
|
||||
{
|
||||
item.ClearBonuses();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!fields.Contains(data.bonusId))
|
||||
if (!bonusListIDs.Contains(data.bonusId))
|
||||
item.AddBonuses(data.bonusId);
|
||||
}
|
||||
}
|
||||
@@ -346,6 +351,8 @@ namespace Game.Entities
|
||||
if (data == null)
|
||||
return false;
|
||||
|
||||
if (data.flags.HasAnyFlag(HeirloomPlayerFlags.BonusLevel120))
|
||||
return level <= 120;
|
||||
if (data.flags.HasAnyFlag(HeirloomPlayerFlags.BonusLevel110))
|
||||
return level <= 110;
|
||||
if (data.flags.HasAnyFlag(HeirloomPlayerFlags.BonusLevel100))
|
||||
@@ -453,13 +460,12 @@ namespace Game.Entities
|
||||
|
||||
public void LoadItemAppearances()
|
||||
{
|
||||
Player owner = _owner.GetPlayer();
|
||||
foreach (uint blockValue in _appearances.ToBlockRange())
|
||||
{
|
||||
_owner.GetPlayer().AddDynamicValue(ActivePlayerDynamicFields.Transmog, blockValue);
|
||||
}
|
||||
owner.AddTransmogBlock(blockValue);
|
||||
|
||||
foreach (var value in _temporaryAppearances.Keys)
|
||||
_owner.GetPlayer().AddDynamicValue(ActivePlayerDynamicFields.ConditionalTransmog, value);
|
||||
owner.AddConditionalTransmog(value);
|
||||
}
|
||||
|
||||
public void LoadAccountItemAppearances(SQLResult knownAppearances, SQLResult favoriteAppearances)
|
||||
@@ -578,7 +584,7 @@ namespace Game.Entities
|
||||
if (!CanAddAppearance(itemModifiedAppearance))
|
||||
return;
|
||||
|
||||
if (Convert.ToBoolean(item.GetUInt32Value(ItemFields.Flags) & (uint)(ItemFieldFlags.BopTradeable | ItemFieldFlags.Refundable)))
|
||||
if (item.HasItemFlag(ItemFieldFlags.BopTradeable | ItemFieldFlags.Refundable))
|
||||
{
|
||||
AddTemporaryAppearance(item.GetGUID(), itemModifiedAppearance);
|
||||
return;
|
||||
@@ -678,24 +684,24 @@ namespace Game.Entities
|
||||
//todo check this
|
||||
void AddItemAppearance(ItemModifiedAppearanceRecord itemModifiedAppearance)
|
||||
{
|
||||
Player owner = _owner.GetPlayer();
|
||||
if (_appearances.Count <= itemModifiedAppearance.Id)
|
||||
{
|
||||
uint numBlocks = (uint)(_appearances.Count << 2);
|
||||
_appearances.Length = (int)itemModifiedAppearance.Id + 1;
|
||||
numBlocks = (uint)(_appearances.Count << 2) - numBlocks;
|
||||
while (numBlocks-- != 0)
|
||||
_owner.GetPlayer().AddDynamicValue(ActivePlayerDynamicFields.Transmog, 0);
|
||||
owner.AddTransmogBlock(0);
|
||||
}
|
||||
|
||||
_appearances.Set((int)itemModifiedAppearance.Id, true);
|
||||
uint blockIndex = itemModifiedAppearance.Id / 32;
|
||||
uint bitIndex = itemModifiedAppearance.Id % 32;
|
||||
uint currentMask = _owner.GetPlayer().GetDynamicValue(ActivePlayerDynamicFields.Transmog, (ushort)blockIndex);
|
||||
_owner.GetPlayer().SetDynamicValue(ActivePlayerDynamicFields.Transmog, (ushort)blockIndex, (uint)((int)currentMask | (1 << (int)bitIndex)));
|
||||
owner.AddTransmogFlag((int)blockIndex, 1u << (int)bitIndex);
|
||||
var temporaryAppearance = _temporaryAppearances.LookupByKey(itemModifiedAppearance.Id);
|
||||
if (!temporaryAppearance.Empty())
|
||||
{
|
||||
_owner.GetPlayer().RemoveDynamicValue(ActivePlayerDynamicFields.ConditionalTransmog, itemModifiedAppearance.Id);
|
||||
owner.RemoveConditionalTransmog(itemModifiedAppearance.Id);
|
||||
_temporaryAppearances.Remove(itemModifiedAppearance.Id);
|
||||
}
|
||||
|
||||
@@ -717,7 +723,7 @@ namespace Game.Entities
|
||||
{
|
||||
var itemsWithAppearance = _temporaryAppearances[itemModifiedAppearance.Id];
|
||||
if (itemsWithAppearance.Empty())
|
||||
_owner.GetPlayer().AddDynamicValue(ActivePlayerDynamicFields.ConditionalTransmog, itemModifiedAppearance.Id);
|
||||
_owner.GetPlayer().AddConditionalTransmog(itemModifiedAppearance.Id);
|
||||
|
||||
itemsWithAppearance.Add(itemGuid);
|
||||
}
|
||||
@@ -735,7 +741,7 @@ namespace Game.Entities
|
||||
guid.Remove(item.GetGUID());
|
||||
if (guid.Empty())
|
||||
{
|
||||
_owner.GetPlayer().RemoveDynamicValue(ActivePlayerDynamicFields.ConditionalTransmog, itemModifiedAppearance.Id);
|
||||
_owner.GetPlayer().RemoveConditionalTransmog(itemModifiedAppearance.Id);
|
||||
_temporaryAppearances.Remove(itemModifiedAppearance.Id);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,21 +88,9 @@ namespace Game.Entities
|
||||
SendPacket(packet);
|
||||
}
|
||||
|
||||
bool CanTitanGrip() { return m_canTitanGrip; }
|
||||
public override uint GetBlockPercent() { return m_activePlayerData.ShieldBlock; }
|
||||
|
||||
public override bool CanUseAttackType(WeaponAttackType attacktype)
|
||||
{
|
||||
switch (attacktype)
|
||||
{
|
||||
case WeaponAttackType.BaseAttack:
|
||||
return !HasFlag(UnitFields.Flags, UnitFlags.Disarmed);
|
||||
case WeaponAttackType.OffAttack:
|
||||
return !HasFlag(UnitFields.Flags2, UnitFlags2.DisarmOffhand);
|
||||
case WeaponAttackType.RangedAttack:
|
||||
return !HasFlag(UnitFields.Flags2, UnitFlags2.DisarmRanged);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
bool CanTitanGrip() { return m_canTitanGrip; }
|
||||
|
||||
float GetRatingMultiplier(CombatRating cr)
|
||||
{
|
||||
@@ -118,7 +106,7 @@ namespace Game.Entities
|
||||
}
|
||||
public float GetRatingBonusValue(CombatRating cr)
|
||||
{
|
||||
float baseResult = GetFloatValue(ActivePlayerFields.CombatRating + (int)cr) * GetRatingMultiplier(cr);
|
||||
float baseResult = m_activePlayerData.CombatRatings[(int)cr] * GetRatingMultiplier(cr);
|
||||
if (cr != CombatRating.ResiliencePlayerDamage)
|
||||
return baseResult;
|
||||
return (float)(1.0f - Math.Pow(0.99f, baseResult)) * 100.0f;
|
||||
@@ -189,9 +177,9 @@ namespace Game.Entities
|
||||
switch (attType)
|
||||
{
|
||||
case WeaponAttackType.BaseAttack:
|
||||
return baseExpertise + GetUInt32Value(ActivePlayerFields.Expertise) / 4.0f;
|
||||
return baseExpertise + m_activePlayerData.MainhandExpertise / 4.0f;
|
||||
case WeaponAttackType.OffAttack:
|
||||
return baseExpertise + GetUInt32Value(ActivePlayerFields.OffhandExpertise) / 4.0f;
|
||||
return baseExpertise + m_activePlayerData.OffhandExpertise / 4.0f;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -201,7 +189,7 @@ namespace Game.Entities
|
||||
public bool IsUseEquipedWeapon(bool mainhand)
|
||||
{
|
||||
// disarm applied only to mainhand weapon
|
||||
return !IsInFeralForm() && (!mainhand || !HasFlag(UnitFields.Flags, UnitFlags.Disarmed));
|
||||
return !IsInFeralForm() && (!mainhand || !HasUnitFlag(UnitFlags.Disarmed));
|
||||
}
|
||||
|
||||
public void SetCanTitanGrip(bool value, uint penaltySpellId = 0)
|
||||
@@ -321,8 +309,8 @@ namespace Game.Entities
|
||||
|
||||
Global.ScriptMgr.OnPlayerDuelStart(this, duel.opponent);
|
||||
|
||||
SetUInt32Value(PlayerFields.DuelTeam, 1);
|
||||
duel.opponent.SetUInt32Value(PlayerFields.DuelTeam, 2);
|
||||
SetDuelTeam(1);
|
||||
duel.opponent.SetDuelTeam(2);
|
||||
|
||||
duel.startTimer = 0;
|
||||
duel.startTime = currTime;
|
||||
@@ -335,7 +323,7 @@ namespace Game.Entities
|
||||
if (duel == null)
|
||||
return;
|
||||
|
||||
ObjectGuid duelFlagGUID = GetGuidValue(PlayerFields.DuelArbiter);
|
||||
ObjectGuid duelFlagGUID = m_playerData.DuelArbiter;
|
||||
GameObject obj = GetMap().GetGameObject(duelFlagGUID);
|
||||
if (!obj)
|
||||
return;
|
||||
@@ -439,7 +427,7 @@ namespace Game.Entities
|
||||
duel.opponent.CastSpell(duel.opponent, 52852, true);
|
||||
|
||||
//Remove Duel Flag object
|
||||
GameObject obj = GetMap().GetGameObject(GetGuidValue(PlayerFields.DuelArbiter));
|
||||
GameObject obj = GetMap().GetGameObject(m_playerData.DuelArbiter);
|
||||
if (obj)
|
||||
duel.initiator.RemoveGameObject(obj, true);
|
||||
|
||||
@@ -465,14 +453,16 @@ namespace Game.Entities
|
||||
duel.opponent.ClearComboPoints();
|
||||
|
||||
//cleanups
|
||||
SetGuidValue(PlayerFields.DuelArbiter, ObjectGuid.Empty);
|
||||
SetUInt32Value(PlayerFields.DuelTeam, 0);
|
||||
duel.opponent.SetGuidValue(PlayerFields.DuelArbiter, ObjectGuid.Empty);
|
||||
duel.opponent.SetUInt32Value(PlayerFields.DuelTeam, 0);
|
||||
SetDuelArbiter(ObjectGuid.Empty);
|
||||
SetDuelTeam(0);
|
||||
duel.opponent.SetDuelArbiter(ObjectGuid.Empty);
|
||||
duel.opponent.SetDuelTeam(0);
|
||||
|
||||
duel.opponent.duel = null;
|
||||
duel = null;
|
||||
}
|
||||
public void SetDuelArbiter(ObjectGuid guid) { SetUpdateFieldValue(m_values.ModifyValue(m_playerData).ModifyValue(m_playerData.DuelArbiter), guid); }
|
||||
void SetDuelTeam(uint duelTeam) { SetUpdateFieldValue(m_values.ModifyValue(m_playerData).ModifyValue(m_playerData.DuelTeam), duelTeam); }
|
||||
|
||||
//PVP
|
||||
public void SetPvPDeath(bool on)
|
||||
@@ -488,7 +478,7 @@ namespace Game.Entities
|
||||
public void ResetContestedPvP()
|
||||
{
|
||||
ClearUnitState(UnitState.AttackPlayer);
|
||||
RemoveFlag(PlayerFields.Flags, PlayerFlags.ContestedPVP);
|
||||
RemovePlayerFlag(PlayerFlags.ContestedPVP);
|
||||
m_contestedPvPTimer = 0;
|
||||
}
|
||||
void UpdateAfkReport(long currTime)
|
||||
@@ -547,16 +537,16 @@ namespace Game.Entities
|
||||
{
|
||||
if (!IsFFAPvP())
|
||||
{
|
||||
SetByteFlag(UnitFields.Bytes2, UnitBytes2Offsets.PvpFlag, UnitBytes2Flags.FFAPvp);
|
||||
AddPvpFlag(UnitPVPStateFlags.FFAPvp);
|
||||
foreach (var unit in m_Controlled)
|
||||
unit.SetByteValue(UnitFields.Bytes2, UnitBytes2Offsets.PvpFlag, (byte)UnitBytes2Flags.FFAPvp);
|
||||
unit.AddPvpFlag(UnitPVPStateFlags.FFAPvp);
|
||||
}
|
||||
}
|
||||
else if (IsFFAPvP())
|
||||
{
|
||||
RemoveByteFlag(UnitFields.Bytes2, UnitBytes2Offsets.PvpFlag, UnitBytes2Flags.FFAPvp);
|
||||
RemovePvpFlag(UnitPVPStateFlags.FFAPvp);
|
||||
foreach (var unit in m_Controlled)
|
||||
unit.RemoveByteFlag(UnitFields.Bytes2, UnitBytes2Offsets.PvpFlag, UnitBytes2Flags.FFAPvp);
|
||||
unit.RemovePvpFlag(UnitPVPStateFlags.FFAPvp);
|
||||
}
|
||||
|
||||
if (onlyFFA)
|
||||
@@ -569,7 +559,7 @@ namespace Game.Entities
|
||||
}
|
||||
else // in friendly area
|
||||
{
|
||||
if (IsPvP() && !HasFlag(PlayerFields.Flags, PlayerFlags.InPVP) && pvpInfo.EndTimer == 0)
|
||||
if (IsPvP() && !HasPlayerFlag(PlayerFlags.InPVP) && pvpInfo.EndTimer == 0)
|
||||
pvpInfo.EndTimer = Time.UnixTime; // start toggle-off
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -184,6 +184,10 @@ namespace Game.Entities
|
||||
|
||||
//Core
|
||||
WorldSession Session;
|
||||
|
||||
public PlayerData m_playerData;
|
||||
public ActivePlayerData m_activePlayerData;
|
||||
|
||||
uint m_nextSave;
|
||||
byte m_cinematic;
|
||||
|
||||
@@ -330,7 +334,6 @@ namespace Game.Entities
|
||||
public List<uint>[] Glyphs = new List<uint>[PlayerConst.MaxSpecializations];
|
||||
public uint ResetTalentsCost;
|
||||
public long ResetTalentsTime;
|
||||
public uint PrimarySpecialization;
|
||||
public byte ActiveGroup;
|
||||
}
|
||||
|
||||
@@ -442,13 +445,12 @@ namespace Game.Entities
|
||||
|
||||
public class VoidStorageItem
|
||||
{
|
||||
public VoidStorageItem(ulong id, uint entry, ObjectGuid creator, ItemRandomEnchantmentId randomPropertyId, uint suffixFactor, uint upgradeId, uint fixedScalingLevel, uint artifactKnowledgeLevel, byte context, ICollection<uint> bonuses)
|
||||
public VoidStorageItem(ulong id, uint entry, ObjectGuid creator, uint randomBonusListId, uint upgradeId, uint fixedScalingLevel, uint artifactKnowledgeLevel, byte context, List<uint> bonuses)
|
||||
{
|
||||
ItemId = id;
|
||||
ItemEntry = entry;
|
||||
CreatorGuid = creator;
|
||||
ItemRandomPropertyId = randomPropertyId;
|
||||
ItemSuffixFactor = suffixFactor;
|
||||
RandomBonusListId = randomBonusListId;
|
||||
ItemUpgradeId = upgradeId;
|
||||
FixedScalingLevel = fixedScalingLevel;
|
||||
ArtifactKnowledgeLevel = artifactKnowledgeLevel;
|
||||
@@ -461,8 +463,7 @@ namespace Game.Entities
|
||||
public ulong ItemId;
|
||||
public uint ItemEntry;
|
||||
public ObjectGuid CreatorGuid;
|
||||
public ItemRandomEnchantmentId ItemRandomPropertyId;
|
||||
public uint ItemSuffixFactor;
|
||||
public uint RandomBonusListId;
|
||||
public uint ItemUpgradeId;
|
||||
public uint FixedScalingLevel;
|
||||
public uint ArtifactKnowledgeLevel;
|
||||
|
||||
@@ -165,10 +165,10 @@ namespace Game.Entities
|
||||
public void SetPartyType(GroupCategory category, GroupType type)
|
||||
{
|
||||
Cypher.Assert(category < GroupCategory.Max);
|
||||
byte value = GetByteValue(PlayerFields.Bytes3, PlayerFieldOffsets.Bytes3OffsetPartyType);
|
||||
byte value = m_playerData.PartyType;
|
||||
value &= (byte)~((byte)0xFF << ((byte)category * 4));
|
||||
value |= (byte)((byte)type << ((byte)category * 4));
|
||||
SetByteValue(PlayerFields.Bytes3, PlayerFieldOffsets.Bytes3OffsetPartyType, value);
|
||||
SetUpdateFieldValue(m_values.ModifyValue(m_playerData).ModifyValue(m_playerData.PartyType), value);
|
||||
}
|
||||
|
||||
public void ResetGroupUpdateSequenceIfNeeded(Group group)
|
||||
|
||||
@@ -47,7 +47,7 @@ namespace Game.Entities
|
||||
}
|
||||
public void RefundItem(Item item)
|
||||
{
|
||||
if (!item.HasFlag(ItemFields.Flags, ItemFieldFlags.Refundable))
|
||||
if (!item.HasItemFlag(ItemFieldFlags.Refundable))
|
||||
{
|
||||
Log.outDebug(LogFilter.Player, "Item refund: item not refundable!");
|
||||
return;
|
||||
@@ -152,7 +152,7 @@ namespace Game.Entities
|
||||
// This function call unsets ITEM_FLAGS_REFUNDABLE if played time is over 2 hours.
|
||||
item.UpdatePlayedTime(this);
|
||||
|
||||
if (!item.HasFlag(ItemFields.Flags, ItemFieldFlags.Refundable))
|
||||
if (!item.HasItemFlag(ItemFieldFlags.Refundable))
|
||||
{
|
||||
Log.outDebug(LogFilter.Player, "Item refund: item not refundable!");
|
||||
return;
|
||||
@@ -301,7 +301,7 @@ namespace Game.Entities
|
||||
if (item == null)
|
||||
return;
|
||||
|
||||
uint pMaxDurability = item.GetUInt32Value(ItemFields.MaxDurability);
|
||||
uint pMaxDurability = item.m_itemData.MaxDurability;
|
||||
|
||||
if (pMaxDurability == 0)
|
||||
return;
|
||||
@@ -352,14 +352,14 @@ namespace Game.Entities
|
||||
if (HasAuraType(AuraType.PreventDurabilityLoss))
|
||||
return;
|
||||
|
||||
int pMaxDurability = item.GetInt32Value(ItemFields.MaxDurability);
|
||||
int pOldDurability = item.GetInt32Value(ItemFields.Durability);
|
||||
int pNewDurability = pOldDurability - points;
|
||||
uint pMaxDurability = item.m_itemData.MaxDurability;
|
||||
uint pOldDurability = item.m_itemData.Durability;
|
||||
int pNewDurability = (int)(pOldDurability - points);
|
||||
|
||||
if (pNewDurability < 0)
|
||||
pNewDurability = 0;
|
||||
else if (pNewDurability > pMaxDurability)
|
||||
pNewDurability = pMaxDurability;
|
||||
pNewDurability = (int)pMaxDurability;
|
||||
|
||||
if (pOldDurability != pNewDurability)
|
||||
{
|
||||
@@ -367,7 +367,7 @@ namespace Game.Entities
|
||||
if (pNewDurability == 0 && pOldDurability > 0 && item.IsEquipped())
|
||||
_ApplyItemMods(item, item.GetSlot(), false);
|
||||
|
||||
item.SetInt32Value(ItemFields.Durability, pNewDurability);
|
||||
item.SetDurability((uint)pNewDurability);
|
||||
|
||||
// modify item stats _after_ restore durability to pass _ApplyItemMods internal check
|
||||
if (pNewDurability > 0 && pOldDurability == 0 && item.IsEquipped())
|
||||
@@ -407,11 +407,11 @@ namespace Game.Entities
|
||||
if (item == null)
|
||||
return TotalCost;
|
||||
|
||||
uint maxDurability = item.GetUInt32Value(ItemFields.MaxDurability);
|
||||
uint maxDurability = item.m_itemData.MaxDurability;
|
||||
if (maxDurability == 0)
|
||||
return TotalCost;
|
||||
|
||||
uint curDurability = item.GetUInt32Value(ItemFields.Durability);
|
||||
uint curDurability = item.m_itemData.Durability;
|
||||
|
||||
if (cost)
|
||||
{
|
||||
@@ -474,7 +474,7 @@ namespace Game.Entities
|
||||
}
|
||||
}
|
||||
|
||||
item.SetUInt32Value(ItemFields.Durability, maxDurability);
|
||||
item.SetDurability(maxDurability);
|
||||
item.SetState(ItemUpdateState.Changed, this);
|
||||
|
||||
// reapply mods for total broken and repaired item if equipped
|
||||
@@ -644,7 +644,7 @@ namespace Game.Entities
|
||||
// search free slot in bag for place to
|
||||
if (bag == InventorySlots.Bag0) // inventory
|
||||
{
|
||||
if (pItem && pItem.HasFlag(ItemFields.Flags, ItemFieldFlags.Child))
|
||||
if (pItem && pItem.HasItemFlag(ItemFieldFlags.Child))
|
||||
{
|
||||
res = CanStoreItem_InInventorySlots(InventorySlots.ChildEquipmentStart, InventorySlots.ChildEquipmentEnd, dest, pProto, ref count, false, pItem, bag, slot);
|
||||
if (res != InventoryResult.Ok)
|
||||
@@ -662,7 +662,7 @@ namespace Game.Entities
|
||||
return InventoryResult.ItemMaxCount;
|
||||
}
|
||||
}
|
||||
else if (pProto.IsCraftingReagent() && HasFlag(PlayerFields.FlagsEx, PlayerFlagsEx.ReagentBankUnlocked))
|
||||
else if (pProto.IsCraftingReagent() && HasPlayerFlagEx(PlayerFlagsEx.ReagentBankUnlocked))
|
||||
{
|
||||
res = CanStoreItem_InInventorySlots(InventorySlots.ReagentStart, InventorySlots.ReagentEnd, dest, pProto, ref count, false, pItem, bag, slot);
|
||||
if (res != InventoryResult.Ok)
|
||||
@@ -832,7 +832,7 @@ namespace Game.Entities
|
||||
if (pItem != null && pItem.IsNotEmptyBag())
|
||||
return InventoryResult.BagInBag;
|
||||
|
||||
if (pItem && pItem.HasFlag(ItemFields.Flags, ItemFieldFlags.Child))
|
||||
if (pItem && pItem.HasItemFlag(ItemFieldFlags.Child))
|
||||
{
|
||||
res = CanStoreItem_InInventorySlots(InventorySlots.ChildEquipmentStart, InventorySlots.ChildEquipmentEnd, dest, pProto, ref count, false, pItem, bag, slot);
|
||||
if (res != InventoryResult.Ok)
|
||||
@@ -850,7 +850,7 @@ namespace Game.Entities
|
||||
return InventoryResult.ItemMaxCount;
|
||||
}
|
||||
}
|
||||
else if (pProto.IsCraftingReagent() && HasFlag(PlayerFields.FlagsEx, PlayerFlagsEx.ReagentBankUnlocked))
|
||||
else if (pProto.IsCraftingReagent() && HasPlayerFlagEx(PlayerFlagsEx.ReagentBankUnlocked))
|
||||
{
|
||||
res = CanStoreItem_InInventorySlots(InventorySlots.ReagentStart, InventorySlots.ReagentEnd, dest, pProto, ref count, false, pItem, bag, slot);
|
||||
if (res != InventoryResult.Ok)
|
||||
@@ -1132,9 +1132,9 @@ namespace Game.Entities
|
||||
if (pBag == null)
|
||||
{
|
||||
m_items[slot] = pItem;
|
||||
SetGuidValue(ActivePlayerFields.InvSlotHead + (slot * 4), pItem.GetGUID());
|
||||
pItem.SetGuidValue(ItemFields.Contained, GetGUID());
|
||||
pItem.SetGuidValue(ItemFields.Owner, GetGUID());
|
||||
SetInvSlot(slot, pItem.GetGUID());
|
||||
pItem.SetContainedIn(GetGUID());
|
||||
pItem.SetOwnerGUID(GetGUID());
|
||||
|
||||
pItem.SetSlot(slot);
|
||||
pItem.SetContainer(null);
|
||||
@@ -1251,7 +1251,7 @@ namespace Game.Entities
|
||||
msg = CanStoreNewItem(InventorySlots.Bag0, ItemConst.NullSlot, sDest, titem_id, titem_amount);
|
||||
if (msg == InventoryResult.Ok)
|
||||
{
|
||||
StoreNewItem(sDest, titem_id, true, ItemEnchantment.GenerateItemRandomPropertyId(titem_id));
|
||||
StoreNewItem(sDest, titem_id, true, ItemEnchantmentManager.GenerateItemRandomBonusListId(titem_id));
|
||||
return true; // stored
|
||||
}
|
||||
|
||||
@@ -1259,7 +1259,7 @@ namespace Game.Entities
|
||||
Log.outError(LogFilter.Player, "STORAGE: Can't equip or store initial item {0} for race {1} class {2}, error msg = {3}", titem_id, GetRace(), GetClass(), msg);
|
||||
return false;
|
||||
}
|
||||
public Item StoreNewItem(List<ItemPosCount> pos, uint itemId, bool update, ItemRandomEnchantmentId randomPropertyId = default(ItemRandomEnchantmentId), List<ObjectGuid> allowedLooters = null, byte context = 0, List<uint> bonusListIDs = null, bool addToCollection = true)
|
||||
public Item StoreNewItem(List<ItemPosCount> pos, uint itemId, bool update, uint randomPropertyId = 0, List<ObjectGuid> allowedLooters = null, byte context = 0, List<uint> bonusListIDs = null, bool addToCollection = true)
|
||||
{
|
||||
uint count = 0;
|
||||
foreach (var itemPosCount in pos)
|
||||
@@ -1272,28 +1272,24 @@ namespace Game.Entities
|
||||
UpdateCriteria(CriteriaTypes.ReceiveEpicItem, itemId, count);
|
||||
UpdateCriteria(CriteriaTypes.OwnItem, itemId, 1);
|
||||
|
||||
item.SetFlag(ItemFields.Flags, ItemFieldFlags.NewItem);
|
||||
item.AddItemFlag(ItemFieldFlags.NewItem);
|
||||
|
||||
uint upgradeID = Global.DB2Mgr.GetRulesetItemUpgrade(itemId);
|
||||
if (upgradeID != 0)
|
||||
item.SetModifier(ItemModifier.UpgradeId, upgradeID);
|
||||
|
||||
item.SetUInt32Value(ItemFields.Context, context);
|
||||
if (bonusListIDs != null)
|
||||
{
|
||||
foreach (uint bonusListID in bonusListIDs)
|
||||
item.AddBonuses(bonusListID);
|
||||
}
|
||||
item.SetContext(context);
|
||||
item.SetBonuses(bonusListIDs);
|
||||
|
||||
item = StoreItem(pos, item, update);
|
||||
|
||||
item.SetFixedLevel(getLevel());
|
||||
item.SetItemRandomProperties(randomPropertyId);
|
||||
item.SetItemRandomBonusList(randomPropertyId);
|
||||
|
||||
if (allowedLooters != null && allowedLooters.Count > 1 && item.GetTemplate().GetMaxStackSize() == 1 && item.IsSoulBound())
|
||||
{
|
||||
item.SetSoulboundTradeable(allowedLooters);
|
||||
item.SetUInt32Value(ItemFields.CreatePlayedTime, GetTotalPlayedTime());
|
||||
item.SetCreatePlayedTime(GetTotalPlayedTime());
|
||||
AddTradeableItem(item);
|
||||
|
||||
// save data
|
||||
@@ -1318,11 +1314,11 @@ namespace Game.Entities
|
||||
{
|
||||
List<ItemPosCount> childDest = new List<ItemPosCount>();
|
||||
CanStoreItem_InInventorySlots(InventorySlots.ChildEquipmentStart, InventorySlots.ChildEquipmentEnd, childDest, childTemplate, ref count, false, null, ItemConst.NullBag, ItemConst.NullSlot);
|
||||
Item childItem = StoreNewItem(childDest, childTemplate.GetId(), update, ItemRandomEnchantmentId.Empty, null, context, null, addToCollection);
|
||||
Item childItem = StoreNewItem(childDest, childTemplate.GetId(), update, 0, null, context, null, addToCollection);
|
||||
if (childItem)
|
||||
{
|
||||
childItem.SetGuidValue(ItemFields.Creator, item.GetGUID());
|
||||
childItem.SetFlag(ItemFields.Flags, ItemFieldFlags.Child);
|
||||
childItem.SetCreator(item.GetGUID());
|
||||
childItem.AddItemFlag(ItemFieldFlags.Child);
|
||||
item.SetChildItem(childItem.GetGUID());
|
||||
}
|
||||
}
|
||||
@@ -1505,7 +1501,7 @@ namespace Game.Entities
|
||||
|
||||
ArtifactRecord artifact = CliDB.ArtifactStorage.LookupByKey(proto.GetArtifactID());
|
||||
if (artifact != null)
|
||||
if (artifact.ChrSpecializationID != GetUInt32Value(PlayerFields.CurrentSpecId))
|
||||
if (artifact.ChrSpecializationID != GetPrimarySpecialization())
|
||||
return InventoryResult.CantUseItem;
|
||||
|
||||
return InventoryResult.Ok;
|
||||
@@ -1907,7 +1903,7 @@ namespace Game.Entities
|
||||
return false;
|
||||
}
|
||||
|
||||
Item item = StoreNewItem(dest, itemId, true, ItemEnchantment.GenerateItemRandomPropertyId(itemId));
|
||||
Item item = StoreNewItem(dest, itemId, true, ItemEnchantmentManager.GenerateItemRandomBonusListId(itemId));
|
||||
if (item != null)
|
||||
SendNewItem(item, count, true, false);
|
||||
else
|
||||
@@ -1947,20 +1943,7 @@ namespace Game.Entities
|
||||
{
|
||||
// remove held enchantments, update expertise
|
||||
if (slot == EquipmentSlot.MainHand)
|
||||
{
|
||||
if (pItem.GetItemSuffixFactor() != 0)
|
||||
{
|
||||
pItem.ClearEnchantment(EnchantmentSlot.Prop3);
|
||||
pItem.ClearEnchantment(EnchantmentSlot.Prop4);
|
||||
}
|
||||
else
|
||||
{
|
||||
pItem.ClearEnchantment(EnchantmentSlot.Prop0);
|
||||
pItem.ClearEnchantment(EnchantmentSlot.Prop1);
|
||||
}
|
||||
|
||||
UpdateExpertise(WeaponAttackType.BaseAttack);
|
||||
}
|
||||
else if (slot == EquipmentSlot.OffHand)
|
||||
UpdateExpertise(WeaponAttackType.OffAttack);
|
||||
// update armor penetration - passive auras may need it
|
||||
@@ -1975,7 +1958,7 @@ namespace Game.Entities
|
||||
}
|
||||
|
||||
m_items[slot] = null;
|
||||
SetGuidValue(ActivePlayerFields.InvSlotHead + (slot * 4), ObjectGuid.Empty);
|
||||
SetInvSlot(slot, ObjectGuid.Empty);
|
||||
|
||||
if (slot < EquipmentSlot.End)
|
||||
{
|
||||
@@ -1988,7 +1971,7 @@ namespace Game.Entities
|
||||
if (pBag != null)
|
||||
pBag.RemoveItem(slot, update);
|
||||
|
||||
pItem.SetGuidValue(ItemFields.Contained, ObjectGuid.Empty);
|
||||
pItem.SetContainedIn(ObjectGuid.Empty);
|
||||
pItem.SetSlot(ItemConst.NullSlot);
|
||||
if (IsInWorld && update)
|
||||
pItem.SendUpdateToPlayer(this);
|
||||
@@ -2122,9 +2105,9 @@ namespace Game.Entities
|
||||
if (pSrcItem == null)
|
||||
return;
|
||||
|
||||
if (pSrcItem.HasFlag(ItemFields.Flags, ItemFieldFlags.Child))
|
||||
if (pSrcItem.HasItemFlag(ItemFieldFlags.Child))
|
||||
{
|
||||
Item parentItem = GetItemByGuid(pSrcItem.GetGuidValue(ItemFields.Creator));
|
||||
Item parentItem = GetItemByGuid(pSrcItem.m_itemData.Creator);
|
||||
if (parentItem)
|
||||
{
|
||||
if (IsEquipmentPos(src))
|
||||
@@ -2136,9 +2119,9 @@ namespace Game.Entities
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (pDstItem && pDstItem.HasFlag(ItemFields.Flags, ItemFieldFlags.Child))
|
||||
else if (pDstItem && pDstItem.HasItemFlag(ItemFieldFlags.Child))
|
||||
{
|
||||
Item parentItem = GetItemByGuid(pDstItem.GetGuidValue(ItemFields.Creator));
|
||||
Item parentItem = GetItemByGuid(pDstItem.m_itemData.Creator);
|
||||
if (parentItem)
|
||||
{
|
||||
if (IsEquipmentPos(dst))
|
||||
@@ -2529,7 +2512,7 @@ namespace Game.Entities
|
||||
}
|
||||
}
|
||||
|
||||
Item it = bStore ? StoreNewItem(vDest, item, true, ItemEnchantment.GenerateItemRandomPropertyId(item), null, 0, crItem.BonusListIDs, false) : EquipNewItem(uiDest, item, true);
|
||||
Item it = bStore ? StoreNewItem(vDest, item, true, ItemEnchantmentManager.GenerateItemRandomBonusListId(item), null, 0, crItem.BonusListIDs, false) : EquipNewItem(uiDest, item, true);
|
||||
if (it != null)
|
||||
{
|
||||
uint new_count = pVendor.UpdateVendorItemCurrentCount(crItem, count);
|
||||
@@ -2548,7 +2531,7 @@ namespace Game.Entities
|
||||
|
||||
if (pProto.GetFlags().HasAnyFlag(ItemFlags.ItemPurchaseRecord) && crItem.ExtendedCost != 0 && pProto.GetMaxStackSize() == 1)
|
||||
{
|
||||
it.SetFlag(ItemFields.Flags, ItemFieldFlags.Refundable);
|
||||
it.AddItemFlag(ItemFieldFlags.Refundable);
|
||||
it.SetRefundRecipient(GetGUID());
|
||||
it.SetPaidMoney((uint)price);
|
||||
it.SetPaidExtendedCost(crItem.ExtendedCost);
|
||||
@@ -2604,7 +2587,7 @@ namespace Game.Entities
|
||||
}
|
||||
void AddItemDurations(Item item)
|
||||
{
|
||||
if (item.GetUInt32Value(ItemFields.Duration) != 0)
|
||||
if (item.m_itemData.Expiration != 0)
|
||||
{
|
||||
m_itemDuration.Add(item);
|
||||
item.SendTimeUpdate(this);
|
||||
@@ -3399,7 +3382,7 @@ namespace Game.Entities
|
||||
// if current back slot non-empty search oldest or free
|
||||
if (m_items[slot] != null)
|
||||
{
|
||||
uint oldest_time = GetUInt32Value(ActivePlayerFields.BuyBackTimestamp);
|
||||
uint oldest_time = m_activePlayerData.BuybackTimestamp[0];
|
||||
uint oldest_slot = InventorySlots.BuyBackStart;
|
||||
|
||||
for (byte i = InventorySlots.BuyBackStart + 1; i < InventorySlots.BuyBackEnd; ++i)
|
||||
@@ -3411,7 +3394,7 @@ namespace Game.Entities
|
||||
break;
|
||||
}
|
||||
|
||||
uint i_time = GetUInt32Value(ActivePlayerFields.BuyBackTimestamp + i - InventorySlots.BuyBackStart);
|
||||
uint i_time = m_activePlayerData.BuybackTimestamp[i - InventorySlots.BuyBackStart];
|
||||
|
||||
if (oldest_time > i_time)
|
||||
{
|
||||
@@ -3430,15 +3413,16 @@ namespace Game.Entities
|
||||
m_items[slot] = pItem;
|
||||
var time = Time.UnixTime;
|
||||
uint etime = (uint)(time - m_logintime + (30 * 3600));
|
||||
int eslot = (int)slot - InventorySlots.BuyBackStart;
|
||||
uint eslot = slot - InventorySlots.BuyBackStart;
|
||||
|
||||
SetGuidValue(ActivePlayerFields.InvSlotHead + ((int)slot * 4), pItem.GetGUID());
|
||||
SetInvSlot(slot, pItem.GetGUID());
|
||||
ItemTemplate proto = pItem.GetTemplate();
|
||||
if (proto != null)
|
||||
SetUInt32Value(ActivePlayerFields.BuyBackPrice + eslot, proto.GetSellPrice() * pItem.GetCount());
|
||||
SetBuybackPrice(eslot, proto.GetSellPrice() * pItem.GetCount());
|
||||
else
|
||||
SetUInt32Value(ActivePlayerFields.BuyBackPrice + eslot, 0);
|
||||
SetUInt32Value(ActivePlayerFields.BuyBackTimestamp + eslot, etime);
|
||||
SetBuybackPrice(eslot, 0);
|
||||
|
||||
SetBuybackTimestamp(eslot, etime);
|
||||
|
||||
// move to next (for non filled list is move most optimized choice)
|
||||
if (m_currentBuybackSlot < InventorySlots.BuyBackEnd - 1)
|
||||
@@ -3462,7 +3446,7 @@ namespace Game.Entities
|
||||
return false;
|
||||
}
|
||||
|
||||
Creature creature = GetNPCIfCanInteractWith(vendorGuid, NPCFlags.Vendor);
|
||||
Creature creature = GetNPCIfCanInteractWith(vendorGuid, NPCFlags.Vendor, NPCFlags2.None);
|
||||
if (!creature)
|
||||
{
|
||||
Log.outDebug(LogFilter.Network, "WORLD: BuyCurrencyFromVendorSlot - {0} not found or you can't interact with him.", vendorGuid.ToString());
|
||||
@@ -3629,7 +3613,7 @@ namespace Game.Entities
|
||||
if (!IsGameMaster() && ((pProto.GetFlags2().HasAnyFlag(ItemFlags2.FactionHorde) && GetTeam() == Team.Alliance) || (pProto.GetFlags2().HasAnyFlag(ItemFlags2.FactionAlliance) && GetTeam() == Team.Horde)))
|
||||
return false;
|
||||
|
||||
Creature creature = GetNPCIfCanInteractWith(vendorguid, NPCFlags.Vendor);
|
||||
Creature creature = GetNPCIfCanInteractWith(vendorguid, NPCFlags.Vendor, NPCFlags2.None);
|
||||
if (!creature)
|
||||
{
|
||||
Log.outDebug(LogFilter.Network, "WORLD: BuyItemFromVendor - {0} not found or you can't interact with him.", vendorguid.ToString());
|
||||
@@ -3866,6 +3850,8 @@ namespace Game.Entities
|
||||
draft.SendMailTo(trans, new MailReceiver(this, GetGUID().GetCounter()), sender);
|
||||
DB.Characters.CommitTransaction(trans);
|
||||
}
|
||||
public void SetBuybackPrice(uint slot, uint price) { SetUpdateFieldValue(ref m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.BuybackPrice, (int)slot), price); }
|
||||
public void SetBuybackTimestamp(uint slot, uint timestamp) { SetUpdateFieldValue(ref m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.BuybackTimestamp, (int)slot), timestamp); }
|
||||
|
||||
public Item GetItemFromBuyBackSlot(uint slot)
|
||||
{
|
||||
@@ -3889,10 +3875,10 @@ namespace Game.Entities
|
||||
|
||||
m_items[slot] = null;
|
||||
|
||||
int eslot = (int)slot - InventorySlots.BuyBackStart;
|
||||
SetGuidValue(ActivePlayerFields.InvSlotHead + (int)(slot * 4), ObjectGuid.Empty);
|
||||
SetUInt32Value(ActivePlayerFields.BuyBackPrice + eslot, 0);
|
||||
SetUInt32Value(ActivePlayerFields.BuyBackTimestamp + eslot, 0);
|
||||
uint eslot = slot - InventorySlots.BuyBackStart;
|
||||
SetInvSlot(slot, ObjectGuid.Empty);
|
||||
SetBuybackPrice(eslot, 0);
|
||||
SetBuybackTimestamp(eslot, 0);
|
||||
|
||||
// if current backslot is filled set to now free slot
|
||||
if (m_items[m_currentBuybackSlot])
|
||||
@@ -4268,7 +4254,7 @@ namespace Game.Entities
|
||||
&& Global.DB2Mgr.GetHeirloomByItemId(item.GetEntry()) != null)
|
||||
continue;
|
||||
|
||||
if (spellData.ChrSpecializationID != 0 && spellData.ChrSpecializationID != GetUInt32Value(PlayerFields.CurrentSpecId))
|
||||
if (spellData.ChrSpecializationID != 0 && spellData.ChrSpecializationID != GetPrimarySpecialization())
|
||||
continue;
|
||||
|
||||
ApplyEquipSpell(spellproto, item, apply, formChange);
|
||||
@@ -4559,10 +4545,10 @@ namespace Game.Entities
|
||||
if (pSrcItem.IsNotEmptyBag() && !IsBagPos((ushort)((ushort)bag << 8 | slot)))
|
||||
return InventoryResult.DestroyNonemptyBag;
|
||||
|
||||
if (pSrcItem.HasFlag(ItemFields.Flags, ItemFieldFlags.Child) && !IsEquipmentPos(bag, slot) && !IsChildEquipmentPos(bag, slot))
|
||||
if (pSrcItem.HasItemFlag(ItemFieldFlags.Child) && !IsEquipmentPos(bag, slot) && !IsChildEquipmentPos(bag, slot))
|
||||
return InventoryResult.WrongBagType3;
|
||||
|
||||
if (!pSrcItem.HasFlag(ItemFields.Flags, ItemFieldFlags.Child) && IsChildEquipmentPos(bag, slot))
|
||||
if (!pSrcItem.HasItemFlag(ItemFieldFlags.Child) && IsChildEquipmentPos(bag, slot))
|
||||
return InventoryResult.WrongBagType3;
|
||||
}
|
||||
|
||||
@@ -4655,7 +4641,7 @@ namespace Game.Entities
|
||||
// in case trade we already have item in other player inventory
|
||||
pLastItem.SetState(in_characterInventoryDB ? ItemUpdateState.Changed : ItemUpdateState.New, this);
|
||||
|
||||
if (pLastItem.HasFlag(ItemFields.Flags, ItemFieldFlags.BopTradeable))
|
||||
if (pLastItem.HasItemFlag(ItemFieldFlags.BopTradeable))
|
||||
AddTradeableItem(pLastItem);
|
||||
}
|
||||
}
|
||||
@@ -4903,7 +4889,7 @@ namespace Game.Entities
|
||||
if (pSrcItem.IsNotEmptyBag())
|
||||
return InventoryResult.DestroyNonemptyBag;
|
||||
|
||||
if (pSrcItem.HasFlag(ItemFields.Flags, ItemFieldFlags.Child))
|
||||
if (pSrcItem.HasItemFlag(ItemFieldFlags.Child))
|
||||
return InventoryResult.WrongBagType3;
|
||||
}
|
||||
|
||||
@@ -5305,7 +5291,7 @@ namespace Game.Entities
|
||||
return res;
|
||||
|
||||
// check unique-equipped on gems
|
||||
foreach (ItemDynamicFieldGems gemData in pItem.GetGems())
|
||||
foreach (SocketedGem gemData in pItem.m_itemData.Gems)
|
||||
{
|
||||
ItemTemplate pGem = Global.ObjectMgr.GetItemTemplate(gemData.ItemId);
|
||||
if (pGem == null)
|
||||
@@ -5400,7 +5386,7 @@ namespace Game.Entities
|
||||
//Artifact
|
||||
void ApplyArtifactPowers(Item item, bool apply)
|
||||
{
|
||||
foreach (ItemDynamicFieldArtifactPowers artifactPower in item.GetArtifactPowers())
|
||||
foreach (ArtifactPower artifactPower in item.m_itemData.ArtifactPowers)
|
||||
{
|
||||
byte rank = artifactPower.CurrentRankWithBonus;
|
||||
if (rank == 0)
|
||||
@@ -5573,16 +5559,18 @@ namespace Game.Entities
|
||||
//Visual
|
||||
public void SetVisibleItemSlot(uint slot, Item pItem)
|
||||
{
|
||||
var itemField = m_values.ModifyValue(m_playerData).ModifyValue(m_playerData.VisibleItems, (int)slot);
|
||||
if (pItem != null)
|
||||
{
|
||||
SetUInt32Value(PlayerFields.VisibleItem + (int)(slot * 2), pItem.GetVisibleEntry(this));
|
||||
SetUInt16Value(PlayerFields.VisibleItem + 1 + (int)(slot * 2), 0, pItem.GetVisibleAppearanceModId(this));
|
||||
SetUInt16Value(PlayerFields.VisibleItem + 1 + (int)(slot * 2), 1, pItem.GetVisibleItemVisual(this));
|
||||
SetUpdateFieldValue(itemField.ModifyValue(itemField.ItemID), pItem.GetVisibleEntry(this));
|
||||
SetUpdateFieldValue(itemField.ModifyValue(itemField.ItemAppearanceModID), pItem.GetVisibleAppearanceModId(this));
|
||||
SetUpdateFieldValue(itemField.ModifyValue(itemField.ItemVisual), pItem.GetVisibleItemVisual(this));
|
||||
}
|
||||
else
|
||||
{
|
||||
SetUInt32Value(PlayerFields.VisibleItem + (int)(slot * 2), 0);
|
||||
SetUInt32Value(PlayerFields.VisibleItem + 1 + (int)(slot * 2), 0);
|
||||
SetUpdateFieldValue(itemField.ModifyValue(itemField.ItemID), 0u);
|
||||
SetUpdateFieldValue(itemField.ModifyValue(itemField.ItemAppearanceModID), (ushort)0);
|
||||
SetUpdateFieldValue(itemField.ModifyValue(itemField.ItemVisual), (ushort)0);
|
||||
}
|
||||
}
|
||||
void VisualizeItem(uint slot, Item pItem)
|
||||
@@ -5601,9 +5589,9 @@ namespace Game.Entities
|
||||
Log.outDebug(LogFilter.Player, "STORAGE: EquipItem slot = {0}, item = {1}", slot, pItem.GetEntry());
|
||||
|
||||
m_items[slot] = pItem;
|
||||
SetGuidValue(ActivePlayerFields.InvSlotHead + (int)(slot * 4), pItem.GetGUID());
|
||||
pItem.SetGuidValue(ItemFields.Contained, GetGUID());
|
||||
pItem.SetGuidValue(ItemFields.Owner, GetGUID());
|
||||
SetInvSlot(slot, pItem.GetGUID());
|
||||
pItem.SetContainedIn(GetGUID());
|
||||
pItem.SetOwnerGUID(GetGUID());
|
||||
pItem.SetSlot((byte)slot);
|
||||
pItem.SetContainer(null);
|
||||
|
||||
@@ -5625,7 +5613,7 @@ namespace Game.Entities
|
||||
for (byte i = 0; i < ItemConst.MaxBagSize; ++i)
|
||||
DestroyItem(slot, i, update);
|
||||
|
||||
if (pItem.HasFlag(ItemFields.Flags, ItemFieldFlags.Wrapped))
|
||||
if (pItem.HasItemFlag(ItemFieldFlags.Wrapped))
|
||||
{
|
||||
PreparedStatement stmt = DB.Characters.GetPreparedStatement(CharStatements.DEL_GIFT);
|
||||
stmt.AddValue(0, pItem.GetGUID().GetCounter());
|
||||
@@ -5645,7 +5633,7 @@ namespace Game.Entities
|
||||
Bag pBag;
|
||||
if (bag == InventorySlots.Bag0)
|
||||
{
|
||||
SetGuidValue(ActivePlayerFields.InvSlotHead + (slot * 4), ObjectGuid.Empty);
|
||||
SetInvSlot(slot, ObjectGuid.Empty);
|
||||
|
||||
// equipment and equipped bags can have applied bonuses
|
||||
if (slot < InventorySlots.BagEnd)
|
||||
@@ -5699,7 +5687,7 @@ namespace Game.Entities
|
||||
}
|
||||
|
||||
//pItem.SetOwnerGUID(ObjectGuid.Empty);
|
||||
pItem.SetGuidValue(ItemFields.Contained, ObjectGuid.Empty);
|
||||
pItem.SetContainedIn(ObjectGuid.Empty);
|
||||
pItem.SetSlot(ItemConst.NullSlot);
|
||||
pItem.SetState(ItemUpdateState.Removed, this);
|
||||
}
|
||||
@@ -6010,12 +5998,12 @@ namespace Game.Entities
|
||||
continue;
|
||||
}
|
||||
|
||||
Item pItem = StoreNewItem(dest, lootItem.itemid, true, lootItem.randomPropertyId, null, lootItem.context, lootItem.BonusListIDs);
|
||||
Item pItem = StoreNewItem(dest, lootItem.itemid, true, lootItem.randomBonusListId, null, lootItem.context, lootItem.BonusListIDs);
|
||||
SendNewItem(pItem, lootItem.count, false, false, broadcast);
|
||||
}
|
||||
}
|
||||
|
||||
public byte GetInventorySlotCount() { return GetByteValue(ActivePlayerFields.Bytes2, PlayerFieldOffsets.FieldBytes2OffsetNumBackpackSlots); }
|
||||
public byte GetInventorySlotCount() { return m_activePlayerData.NumBackpackSlots; }
|
||||
public void SetInventorySlotCount(byte slots)
|
||||
{
|
||||
//ASSERT(slots <= (INVENTORY_SLOT_ITEM_END - INVENTORY_SLOT_ITEM_START));
|
||||
@@ -6058,15 +6046,15 @@ namespace Game.Entities
|
||||
}
|
||||
}
|
||||
|
||||
SetByteValue(ActivePlayerFields.Bytes2, PlayerFieldOffsets.FieldBytes2OffsetNumBackpackSlots, slots);
|
||||
SetUpdateFieldValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.NumBackpackSlots), slots);
|
||||
}
|
||||
|
||||
public byte GetBankBagSlotCount() { return GetByteValue(PlayerFields.Bytes3, PlayerFieldOffsets.Bytes3OffsetBankBagSlots); }
|
||||
public void SetBankBagSlotCount(byte count) { SetByteValue(PlayerFields.Bytes3, PlayerFieldOffsets.Bytes3OffsetBankBagSlots, count); }
|
||||
public byte GetBankBagSlotCount() { return m_activePlayerData.NumBankSlots; }
|
||||
public void SetBankBagSlotCount(byte count) { SetUpdateFieldValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.NumBankSlots), count); }
|
||||
|
||||
//Loot
|
||||
public ObjectGuid GetLootGUID() { return GetGuidValue(PlayerFields.LootTargetGuid); }
|
||||
public void SetLootGUID(ObjectGuid guid) { SetGuidValue(PlayerFields.LootTargetGuid, guid); }
|
||||
public ObjectGuid GetLootGUID() { return m_playerData.LootTargetGUID; }
|
||||
public void SetLootGUID(ObjectGuid guid) { SetUpdateFieldValue(m_values.ModifyValue(m_playerData).ModifyValue(m_playerData.LootTargetGUID), guid); }
|
||||
public void StoreLootItem(byte lootSlot, Loot loot, AELootResult aeResult = null)
|
||||
{
|
||||
NotNormalLootItem qitem = null;
|
||||
@@ -6104,7 +6092,7 @@ namespace Game.Entities
|
||||
InventoryResult msg = CanStoreNewItem(ItemConst.NullBag, ItemConst.NullSlot, dest, item.itemid, item.count);
|
||||
if (msg == InventoryResult.Ok)
|
||||
{
|
||||
Item newitem = StoreNewItem(dest, item.itemid, true, item.randomPropertyId, item.GetAllowedLooters(), item.context, item.BonusListIDs);
|
||||
Item newitem = StoreNewItem(dest, item.itemid, true, item.randomBonusListId, item.GetAllowedLooters(), item.context, item.BonusListIDs);
|
||||
if (qitem != null)
|
||||
{
|
||||
qitem.is_looted = true;
|
||||
@@ -6196,7 +6184,7 @@ namespace Game.Entities
|
||||
return;
|
||||
|
||||
// Now we must make bones lootable, and send player loot
|
||||
bones.SetFlag(CorpseFields.DynamicFlags, 0x01);
|
||||
bones.AddCorpseDynamicFlag(CorpseDynFlags.Lootable);
|
||||
|
||||
// We store the level of our player in the gold field
|
||||
// We retrieve this information at Player.SendLoot()
|
||||
@@ -6571,7 +6559,7 @@ namespace Game.Entities
|
||||
SendLootError(loot.GetGUID(), guid, LootError.DidntKill);
|
||||
|
||||
if (loot_type == LootType.Corpse && !guid.IsItem())
|
||||
SetFlag(UnitFields.Flags, UnitFlags.Looting);
|
||||
AddUnitFlag(UnitFlags.Looting);
|
||||
}
|
||||
|
||||
public void SendLootError(ObjectGuid lootObj, ObjectGuid owner, LootError error)
|
||||
@@ -6663,9 +6651,9 @@ namespace Game.Entities
|
||||
}
|
||||
|
||||
//Void Storage
|
||||
public bool IsVoidStorageUnlocked() { return HasFlag(PlayerFields.Flags, PlayerFlags.VoidUnlocked); }
|
||||
public void UnlockVoidStorage() { SetFlag(PlayerFields.Flags, PlayerFlags.VoidUnlocked); }
|
||||
public void LockVoidStorage() { RemoveFlag(PlayerFields.Flags, PlayerFlags.VoidUnlocked); }
|
||||
public bool IsVoidStorageUnlocked() { return HasPlayerFlag(PlayerFlags.VoidUnlocked); }
|
||||
public void UnlockVoidStorage() { AddPlayerFlag(PlayerFlags.VoidUnlocked); }
|
||||
public void LockVoidStorage() { RemovePlayerFlag(PlayerFlags.VoidUnlocked); }
|
||||
|
||||
public byte GetNextVoidStorageFreeSlot()
|
||||
{
|
||||
|
||||
@@ -125,13 +125,13 @@ namespace Game.Entities
|
||||
pvpInfo.IsInNoPvPArea = false;
|
||||
if (area != null && area.IsSanctuary()) // in sanctuary
|
||||
{
|
||||
SetByteFlag(UnitFields.Bytes2, UnitBytes2Offsets.PvpFlag, UnitBytes2Flags.Sanctuary);
|
||||
AddPvpFlag(UnitPVPStateFlags.Sanctuary);
|
||||
pvpInfo.IsInNoPvPArea = true;
|
||||
if (duel == null)
|
||||
CombatStopWithPets();
|
||||
}
|
||||
else
|
||||
RemoveByteFlag(UnitFields.Bytes2, UnitBytes2Offsets.PvpFlag, UnitBytes2Flags.Sanctuary);
|
||||
RemovePvpFlag(UnitPVPStateFlags.Sanctuary);
|
||||
|
||||
AreaFlags areaRestFlag = (GetTeam() == Team.Alliance) ? AreaFlags.RestZoneAlliance : AreaFlags.RestZoneHorde;
|
||||
if (area != null && area.Flags[0].HasAnyFlag(areaRestFlag))
|
||||
|
||||
@@ -46,16 +46,15 @@ namespace Game.Entities
|
||||
if (m_lastHonorUpdateTime >= yesterday)
|
||||
{
|
||||
// this is the first update today, reset today's contribution
|
||||
ushort killsToday = GetUInt16Value(ActivePlayerFields.Kills, 0);
|
||||
SetUInt16Value(ActivePlayerFields.Kills, 0, 0);
|
||||
SetUInt16Value(ActivePlayerFields.Kills, 1, killsToday);
|
||||
|
||||
SetUpdateFieldValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.YesterdayHonorableKills), m_activePlayerData.TodayHonorableKills);
|
||||
}
|
||||
else
|
||||
{
|
||||
// no honor/kills yesterday or today, reset
|
||||
SetUInt32Value(ActivePlayerFields.Kills, 0);
|
||||
SetUpdateFieldValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.YesterdayHonorableKills), (ushort)0);
|
||||
}
|
||||
|
||||
SetUpdateFieldValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.TodayHonorableKills), (ushort)0);
|
||||
}
|
||||
|
||||
m_lastHonorUpdateTime = now;
|
||||
@@ -116,7 +115,8 @@ namespace Game.Entities
|
||||
// [15..28] Horde honor titles and player name
|
||||
// [29..38] Other title and player name
|
||||
// [39+] Nothing
|
||||
uint victim_title = victim.GetUInt32Value(PlayerFields.ChosenTitle);
|
||||
// this is all wrong, should be going off PvpTitle, not PlayerTitle
|
||||
uint victim_title = plrVictim.m_playerData.PlayerTitle;
|
||||
// Get Killer titles, CharTitlesEntry.bit_index
|
||||
// Ranks:
|
||||
// title[1..14] . rank[5..18]
|
||||
@@ -134,9 +134,9 @@ namespace Game.Entities
|
||||
honor_f = (float)Math.Ceiling(Formulas.hk_honor_at_level_f(k_level) * (v_level - k_grey) / (k_level - k_grey));
|
||||
|
||||
// count the number of playerkills in one day
|
||||
ApplyModUInt16Value(ActivePlayerFields.Kills, 0, 1, true);
|
||||
ApplyModUpdateFieldValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.TodayHonorableKills), (ushort)1, true);
|
||||
// and those in a lifetime
|
||||
ApplyModUInt32Value(ActivePlayerFields.LifetimeHonorableKills, 1, true);
|
||||
ApplyModUpdateFieldValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.LifetimeHonorableKills), 1u, true);
|
||||
UpdateCriteria(CriteriaTypes.EarnHonorableKill);
|
||||
UpdateCriteria(CriteriaTypes.HkClass, (uint)victim.GetClass());
|
||||
UpdateCriteria(CriteriaTypes.HkRace, (uint)victim.GetRace());
|
||||
@@ -215,9 +215,16 @@ namespace Game.Entities
|
||||
return true;
|
||||
}
|
||||
|
||||
public void ResetHonorStats()
|
||||
{
|
||||
SetUpdateFieldValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.TodayHonorableKills), (ushort)0);
|
||||
SetUpdateFieldValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.YesterdayHonorableKills), (ushort)0);
|
||||
SetUpdateFieldValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.LifetimeHonorableKills), 0u);
|
||||
}
|
||||
|
||||
void _InitHonorLevelOnLoadFromDB(uint honor, uint honorLevel)
|
||||
{
|
||||
SetUInt32Value(PlayerFields.HonorLevel, honorLevel);
|
||||
SetUpdateFieldValue(m_values.ModifyValue(m_playerData).ModifyValue(m_playerData.HonorLevel), honorLevel);
|
||||
UpdateHonorNextLevel();
|
||||
|
||||
AddHonorXP(honor);
|
||||
@@ -250,8 +257,8 @@ namespace Game.Entities
|
||||
|
||||
public void AddHonorXP(uint xp)
|
||||
{
|
||||
uint currentHonorXP = GetUInt32Value(ActivePlayerFields.Honor);
|
||||
uint nextHonorLevelXP = GetUInt32Value(ActivePlayerFields.HonorNextLevel);
|
||||
uint currentHonorXP = m_activePlayerData.Honor;
|
||||
uint nextHonorLevelXP = m_activePlayerData.HonorNextLevel;
|
||||
uint newHonorXP = currentHonorXP + xp;
|
||||
uint honorLevel = GetHonorLevel();
|
||||
|
||||
@@ -266,10 +273,10 @@ namespace Game.Entities
|
||||
SetHonorLevel((byte)(honorLevel + 1));
|
||||
|
||||
honorLevel = GetHonorLevel();
|
||||
nextHonorLevelXP = GetUInt32Value(ActivePlayerFields.HonorNextLevel);
|
||||
nextHonorLevelXP = m_activePlayerData.HonorNextLevel;
|
||||
}
|
||||
|
||||
SetUInt32Value(ActivePlayerFields.Honor, IsMaxHonorLevel() ? 0 : newHonorXP);
|
||||
SetUpdateFieldValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.Honor), IsMaxHonorLevel() ? 0 : newHonorXP);
|
||||
}
|
||||
|
||||
void SetHonorLevel(byte level)
|
||||
@@ -278,7 +285,7 @@ namespace Game.Entities
|
||||
if (level == oldHonorLevel)
|
||||
return;
|
||||
|
||||
SetUInt32Value(PlayerFields.HonorLevel, level);
|
||||
SetUpdateFieldValue(m_values.ModifyValue(m_playerData).ModifyValue(m_playerData.HonorLevel), level);
|
||||
UpdateHonorNextLevel();
|
||||
|
||||
UpdateCriteria(CriteriaTypes.HonorLevelReached);
|
||||
@@ -289,10 +296,10 @@ namespace Game.Entities
|
||||
// 5500 at honor level 1
|
||||
// no idea what between here
|
||||
// 8800 at honor level ~14 (never goes above 8800)
|
||||
SetUInt32Value(ActivePlayerFields.HonorNextLevel, 8800);
|
||||
SetUpdateFieldValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.HonorNextLevel), 8800u);
|
||||
}
|
||||
|
||||
public uint GetHonorLevel() { return GetUInt32Value(PlayerFields.HonorLevel); }
|
||||
public uint GetHonorLevel() { return m_playerData.HonorLevel; }
|
||||
public bool IsMaxHonorLevel() { return GetHonorLevel() == PlayerConst.MaxHonorLevel; }
|
||||
|
||||
public void ActivatePvpItemLevels(bool activate) { _usePvpItemLevels = activate; }
|
||||
@@ -329,7 +336,7 @@ namespace Game.Entities
|
||||
if (talentInfo == null)
|
||||
return TalentLearnResult.FailedUnknown;
|
||||
|
||||
if (talentInfo.SpecID != GetInt32Value(PlayerFields.CurrentSpecId))
|
||||
if (talentInfo.SpecID != GetPrimarySpecialization())
|
||||
return TalentLearnResult.FailedUnknown;
|
||||
|
||||
if (talentInfo.LevelRequired > getLevel())
|
||||
@@ -350,7 +357,7 @@ namespace Game.Entities
|
||||
PvpTalentRecord talent = CliDB.PvpTalentStorage.LookupByKey(GetPvpTalentMap(GetActiveTalentGroup())[slot]);
|
||||
if (talent != null)
|
||||
{
|
||||
if (!HasFlag(PlayerFields.Flags, PlayerFlags.Resting) && !HasFlag(UnitFields.Flags2, UnitFlags2.AllowChangingTalents))
|
||||
if (!HasPlayerFlag(PlayerFlags.Resting) && !HasUnitFlag2(UnitFlags2.AllowChangingTalents))
|
||||
return TalentLearnResult.FailedRestArea;
|
||||
|
||||
if (GetSpellHistory().HasCooldown(talent.SpellID))
|
||||
@@ -638,7 +645,7 @@ namespace Game.Entities
|
||||
if (gameobject)
|
||||
{
|
||||
FactionTemplateRecord playerFaction = GetFactionTemplateEntry();
|
||||
FactionTemplateRecord faction = CliDB.FactionTemplateStorage.LookupByKey(gameobject.GetUInt32Value(GameObjectFields.Faction));
|
||||
FactionTemplateRecord faction = CliDB.FactionTemplateStorage.LookupByKey(gameobject.GetFaction());
|
||||
|
||||
if (playerFaction != null && faction != null && !playerFaction.IsFriendlyTo(faction))
|
||||
return false;
|
||||
@@ -705,7 +712,7 @@ namespace Game.Entities
|
||||
public void SetBGTeam(Team team)
|
||||
{
|
||||
m_bgData.bgTeam = (uint)team;
|
||||
SetByteValue(PlayerFields.Bytes4, PlayerFieldOffsets.Bytes4OffsetArenaFaction, (byte)(team == Team.Alliance ? 1 : 0));
|
||||
SetArenaFaction((byte)(team == Team.Alliance ? 1 : 0));
|
||||
}
|
||||
|
||||
public Team GetBGTeam()
|
||||
@@ -871,7 +878,7 @@ namespace Game.Entities
|
||||
//Arenas
|
||||
public void SetArenaTeamInfoField(byte slot, ArenaTeamInfoType type, uint value)
|
||||
{
|
||||
SetUInt32Value(ActivePlayerFields.ArenaTeamInfo + (slot * (int)ArenaTeamInfoType.End) + (int)type, value);
|
||||
|
||||
}
|
||||
|
||||
public void SetInArenaTeam(uint ArenaTeamId, byte slot, byte type)
|
||||
@@ -914,11 +921,11 @@ namespace Game.Entities
|
||||
}
|
||||
while (result.NextRow());
|
||||
}
|
||||
public uint GetArenaTeamId(byte slot) { return GetUInt32Value(ActivePlayerFields.ArenaTeamInfo + (slot * (int)ArenaTeamInfoType.End) + (int)ArenaTeamInfoType.Id); }
|
||||
public uint GetArenaPersonalRating(byte slot) { return GetUInt32Value(ActivePlayerFields.ArenaTeamInfo + (slot * (int)ArenaTeamInfoType.End) + (int)ArenaTeamInfoType.PersonalRating); }
|
||||
public uint GetArenaTeamId(byte slot) { return 0; }
|
||||
public uint GetArenaPersonalRating(byte slot) { return m_activePlayerData.PvpInfo[slot].Rating; }
|
||||
public void SetArenaTeamIdInvited(uint ArenaTeamId) { m_ArenaTeamIdInvited = ArenaTeamId; }
|
||||
public uint GetArenaTeamIdInvited() { return m_ArenaTeamIdInvited; }
|
||||
public uint GetRBGPersonalRating() { return 0; }
|
||||
public uint GetRBGPersonalRating() { return m_activePlayerData.PvpInfo[3].Rating; }
|
||||
|
||||
//OutdoorPVP
|
||||
public bool IsOutdoorPvPActive()
|
||||
|
||||
@@ -145,7 +145,7 @@ namespace Game.Entities
|
||||
|
||||
public void DailyReset()
|
||||
{
|
||||
foreach (uint questId in GetDynamicValues(ActivePlayerDynamicFields.DailyQuests))
|
||||
foreach (uint questId in m_activePlayerData.DailyQuestsCompleted)
|
||||
{
|
||||
uint questBit = Global.DB2Mgr.GetQuestUniqueBitFlag(questId);
|
||||
if (questBit != 0)
|
||||
@@ -153,10 +153,10 @@ namespace Game.Entities
|
||||
}
|
||||
|
||||
DailyQuestsReset dailyQuestsReset = new DailyQuestsReset();
|
||||
dailyQuestsReset.Count = GetDynamicValues(ActivePlayerDynamicFields.DailyQuests).Length;
|
||||
dailyQuestsReset.Count = m_activePlayerData.DailyQuestsCompleted.Size();
|
||||
SendPacket(dailyQuestsReset);
|
||||
|
||||
ClearDynamicValue(ActivePlayerDynamicFields.DailyQuests);
|
||||
ClearDynamicUpdateFieldValues(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.DailyQuestsCompleted));
|
||||
|
||||
m_DFQuests.Clear(); // Dungeon Finder Quests.
|
||||
|
||||
@@ -226,7 +226,7 @@ namespace Game.Entities
|
||||
switch (questGiver.GetTypeId())
|
||||
{
|
||||
case TypeId.Unit:
|
||||
return GetNPCIfCanInteractWith(questGiver.GetGUID(), NPCFlags.QuestGiver) != null;
|
||||
return GetNPCIfCanInteractWith(questGiver.GetGUID(), NPCFlags.QuestGiver, NPCFlags2.None) != null;
|
||||
case TypeId.GameObject:
|
||||
return GetGameObjectIfCanInteractWith(questGiver.GetGUID(), GameObjectTypes.QuestGiver) != null;
|
||||
case TypeId.Player:
|
||||
@@ -331,7 +331,7 @@ namespace Game.Entities
|
||||
return;
|
||||
}
|
||||
|
||||
if (!source.IsTypeId(TypeId.Unit) || source.HasFlag64(UnitFields.NpcFlags, NPCFlags.Gossip))
|
||||
if (!source.IsTypeId(TypeId.Unit) || source.ToUnit().HasNpcFlag(NPCFlags.Gossip))
|
||||
{
|
||||
if (quest.IsAutoAccept() && CanAddQuest(quest, true) && CanTakeQuest(quest, true))
|
||||
AddQuestAndCheckCompletion(quest, source);
|
||||
@@ -880,7 +880,7 @@ namespace Game.Entities
|
||||
List<ItemPosCount> dest = new List<ItemPosCount>();
|
||||
if (CanStoreNewItem(ItemConst.NullBag, ItemConst.NullSlot, dest, questPackageItem.ItemID, questPackageItem.ItemQuantity) == InventoryResult.Ok)
|
||||
{
|
||||
Item item = StoreNewItem(dest, questPackageItem.ItemID, true, ItemEnchantment.GenerateItemRandomPropertyId(questPackageItem.ItemID));
|
||||
Item item = StoreNewItem(dest, questPackageItem.ItemID, true, ItemEnchantmentManager.GenerateItemRandomBonusListId(questPackageItem.ItemID));
|
||||
SendNewItem(item, questPackageItem.ItemQuantity, true, false);
|
||||
}
|
||||
}
|
||||
@@ -900,7 +900,7 @@ namespace Game.Entities
|
||||
List<ItemPosCount> dest = new List<ItemPosCount>();
|
||||
if (CanStoreNewItem(ItemConst.NullBag, ItemConst.NullSlot, dest, questPackageItem.ItemID, questPackageItem.ItemQuantity) == InventoryResult.Ok)
|
||||
{
|
||||
Item item = StoreNewItem(dest, questPackageItem.ItemID, true, ItemEnchantment.GenerateItemRandomPropertyId(questPackageItem.ItemID));
|
||||
Item item = StoreNewItem(dest, questPackageItem.ItemID, true, ItemEnchantmentManager.GenerateItemRandomBonusListId(questPackageItem.ItemID));
|
||||
SendNewItem(item, questPackageItem.ItemQuantity, true, false);
|
||||
}
|
||||
}
|
||||
@@ -954,7 +954,7 @@ namespace Game.Entities
|
||||
List<ItemPosCount> dest = new List<ItemPosCount>();
|
||||
if (CanStoreNewItem(ItemConst.NullBag, ItemConst.NullSlot, dest, reward, quest.RewardChoiceItemCount[i]) == InventoryResult.Ok)
|
||||
{
|
||||
Item item = StoreNewItem(dest, reward, true, ItemEnchantment.GenerateItemRandomPropertyId(reward));
|
||||
Item item = StoreNewItem(dest, reward, true, ItemEnchantmentManager.GenerateItemRandomBonusListId(reward));
|
||||
SendNewItem(item, quest.RewardChoiceItemCount[i], true, false);
|
||||
}
|
||||
}
|
||||
@@ -975,7 +975,7 @@ namespace Game.Entities
|
||||
List<ItemPosCount> dest = new List<ItemPosCount>();
|
||||
if (CanStoreNewItem(ItemConst.NullBag, ItemConst.NullSlot, dest, itemId, quest.RewardItemCount[i]) == InventoryResult.Ok)
|
||||
{
|
||||
Item item = StoreNewItem(dest, itemId, true, ItemEnchantment.GenerateItemRandomPropertyId(itemId));
|
||||
Item item = StoreNewItem(dest, itemId, true, ItemEnchantmentManager.GenerateItemRandomBonusListId(itemId));
|
||||
SendNewItem(item, quest.RewardItemCount[i], true, false);
|
||||
}
|
||||
else if (quest.IsDFQuest())
|
||||
@@ -1609,12 +1609,7 @@ namespace Game.Entities
|
||||
return true;
|
||||
}
|
||||
|
||||
var dailies = GetDynamicValues(ActivePlayerDynamicFields.DailyQuests);
|
||||
foreach (var dailyQuestId in dailies)
|
||||
if (dailyQuestId == qInfo.Id)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
return m_activePlayerData.DailyQuestsCompleted.FindIndex(qInfo.Id) == -1;
|
||||
}
|
||||
|
||||
public bool SatisfyQuestWeek(Quest qInfo, bool msg)
|
||||
@@ -1977,34 +1972,37 @@ namespace Game.Entities
|
||||
|
||||
public uint GetQuestSlotQuestId(ushort slot)
|
||||
{
|
||||
return GetUInt32Value(PlayerFields.QuestLog + (slot * QuestSlotOffsets.Max) + QuestSlotOffsets.Id);
|
||||
return m_playerData.QuestLog[slot].QuestID;
|
||||
}
|
||||
|
||||
public uint GetQuestSlotState(ushort slot, byte counter)
|
||||
{
|
||||
return GetUInt32Value(PlayerFields.QuestLog + (slot * QuestSlotOffsets.Max) + QuestSlotOffsets.State);
|
||||
return m_playerData.QuestLog[slot].StateFlags;
|
||||
}
|
||||
|
||||
public ushort GetQuestSlotCounter(ushort slot, byte counter)
|
||||
{
|
||||
if (counter < SharedConst.MaxQuestCounts)
|
||||
return GetUInt16Value(PlayerFields.QuestLog + slot * QuestSlotOffsets.Max + QuestSlotOffsets.Counts + counter /2, (byte)(counter % 2));
|
||||
return m_playerData.QuestLog[slot].ObjectiveProgress[counter];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public uint GetQuestSlotTime(ushort slot)
|
||||
{
|
||||
return GetUInt32Value(PlayerFields.QuestLog + (slot * QuestSlotOffsets.Max) + QuestSlotOffsets.Time);
|
||||
return m_playerData.QuestLog[slot].EndTime;
|
||||
}
|
||||
|
||||
public void SetQuestSlot(ushort slot, uint quest_id, uint timer = 0)
|
||||
{
|
||||
SetUInt32Value(PlayerFields.QuestLog + (slot * QuestSlotOffsets.Max) + QuestSlotOffsets.Id, quest_id);
|
||||
SetUInt32Value(PlayerFields.QuestLog + (slot * QuestSlotOffsets.Max) + QuestSlotOffsets.State, 0);
|
||||
for (int i = 0; i < SharedConst.MaxQuestCounts / 2; ++i)
|
||||
SetUInt32Value(PlayerFields.QuestLog + slot * QuestSlotOffsets.Max + QuestSlotOffsets.Counts + i, 0);
|
||||
SetUInt32Value(PlayerFields.QuestLog + (slot * QuestSlotOffsets.Max) + QuestSlotOffsets.Time, timer);
|
||||
var questLogField = m_values.ModifyValue(m_playerData).ModifyValue(m_playerData.QuestLog, slot);
|
||||
SetUpdateFieldValue(questLogField.ModifyValue(questLogField.QuestID), quest_id);
|
||||
SetUpdateFieldValue(questLogField.ModifyValue(questLogField.StateFlags), 0u);
|
||||
|
||||
for (int i = 0; i < SharedConst.MaxQuestCounts; ++i)
|
||||
SetUpdateFieldValue(ref questLogField.ModifyValue(questLogField.ObjectiveProgress, i), (ushort)0);
|
||||
|
||||
SetUpdateFieldValue(questLogField.ModifyValue(questLogField.EndTime), timer);
|
||||
}
|
||||
|
||||
public void SetQuestSlotCounter(ushort slot, byte counter, ushort count)
|
||||
@@ -2012,22 +2010,24 @@ namespace Game.Entities
|
||||
if (counter >= SharedConst.MaxQuestCounts)
|
||||
return;
|
||||
|
||||
SetUInt16Value(PlayerFields.QuestLog + slot * QuestSlotOffsets.Max + QuestSlotOffsets.Counts + counter / 2, (byte)(counter % 2), count);
|
||||
SetUpdateFieldValue(ref m_playerData.ModifyValue(m_playerData.QuestLog, slot).ModifyValue((QuestLog questLogField) => questLogField.ObjectiveProgress, counter), count);
|
||||
}
|
||||
|
||||
public void SetQuestSlotState(ushort slot, QuestSlotStateMask state)
|
||||
{
|
||||
SetFlag(PlayerFields.QuestLog + (slot * QuestSlotOffsets.Max) + QuestSlotOffsets.State, state);
|
||||
QuestLog questLogField = m_playerData.ModifyValue(m_playerData.QuestLog, slot);
|
||||
SetUpdateFieldFlagValue(questLogField.ModifyValue(questLogField.StateFlags), (uint)state);
|
||||
}
|
||||
|
||||
public void RemoveQuestSlotState(ushort slot, QuestSlotStateMask state)
|
||||
{
|
||||
RemoveFlag(PlayerFields.QuestLog + (slot * QuestSlotOffsets.Max) + QuestSlotOffsets.State, state);
|
||||
QuestLog questLogField = m_playerData.ModifyValue(m_playerData.QuestLog, slot);
|
||||
RemoveUpdateFieldFlagValue(questLogField.ModifyValue(questLogField.StateFlags), (uint)state);
|
||||
}
|
||||
|
||||
public void SetQuestSlotTimer(ushort slot, uint timer)
|
||||
{
|
||||
SetUInt32Value(PlayerFields.QuestLog + (slot * QuestSlotOffsets.Max) + QuestSlotOffsets.Time, timer);
|
||||
SetUpdateFieldValue(m_values.ModifyValue(m_playerData).ModifyValue(m_playerData.QuestLog, slot).ModifyValue((QuestLog questLog) => questLog.EndTime), timer);
|
||||
}
|
||||
|
||||
void SetQuestCompletedBit(uint questBit, bool completed)
|
||||
@@ -2035,11 +2035,15 @@ namespace Game.Entities
|
||||
if (questBit == 0)
|
||||
return;
|
||||
|
||||
int fieldOffset = ((int)questBit - 1) >> 5;
|
||||
uint fieldOffset = (questBit - 1) >> 6;
|
||||
if (fieldOffset >= PlayerConst.QuestsCompletedBitsSize)
|
||||
return;
|
||||
|
||||
ApplyModFlag(ActivePlayerFields.QuestCompleted + fieldOffset, (uint)(1 << (((int)questBit - 1) & 31)), completed);
|
||||
ulong flag = 1ul << (((int)questBit - 1) & 63);
|
||||
if (completed)
|
||||
SetUpdateFieldFlagValue(ref m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.QuestCompleted, (int)fieldOffset), flag);
|
||||
else
|
||||
RemoveUpdateFieldFlagValue(ref m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.QuestCompleted, (int)fieldOffset), flag);
|
||||
}
|
||||
|
||||
public void AreaExploredOrEventHappens(uint questId)
|
||||
@@ -2885,7 +2889,7 @@ namespace Game.Entities
|
||||
if (!questgiver || questgiver.IsHostileTo(this))
|
||||
continue;
|
||||
|
||||
if (!questgiver.HasFlag64(UnitFields.NpcFlags, NPCFlags.QuestGiver))
|
||||
if (!questgiver.HasNpcFlag(NPCFlags.QuestGiver))
|
||||
continue;
|
||||
|
||||
response.QuestGiver.Add(new QuestGiverInfo(questgiver.GetGUID(), GetQuestDialogStatus(questgiver)));
|
||||
@@ -2978,7 +2982,7 @@ namespace Game.Entities
|
||||
continue;
|
||||
|
||||
// check if this unit requires quest specific flags
|
||||
if (!obj.HasFlag64(UnitFields.NpcFlags, NPCFlags.SpellClick))
|
||||
if (!obj.HasNpcFlag(NPCFlags.SpellClick))
|
||||
continue;
|
||||
|
||||
var clickPair = Global.ObjectMgr.GetSpellClickInfoMapBounds(obj.GetEntry());
|
||||
@@ -3014,7 +3018,7 @@ namespace Game.Entities
|
||||
{
|
||||
if (!qQuest.IsDFQuest())
|
||||
{
|
||||
AddDynamicValue(ActivePlayerDynamicFields.DailyQuests, quest_id);
|
||||
AddDynamicUpdateFieldValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.DailyQuestsCompleted), quest_id);
|
||||
m_lastDailyQuestTime = Time.UnixTime; // last daily quest time
|
||||
m_DailyQuestChanged = true;
|
||||
|
||||
@@ -3030,21 +3034,7 @@ namespace Game.Entities
|
||||
|
||||
public bool IsDailyQuestDone(uint quest_id)
|
||||
{
|
||||
bool found = false;
|
||||
if (Global.ObjectMgr.GetQuestTemplate(quest_id) != null)
|
||||
{
|
||||
var dailies = GetDynamicValues(ActivePlayerDynamicFields.DailyQuests);
|
||||
foreach (uint dailyQuestId in dailies)
|
||||
{
|
||||
if (dailyQuestId == quest_id)
|
||||
{
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return found;
|
||||
return m_activePlayerData.DailyQuestsCompleted.FindIndex(quest_id) >= 0;
|
||||
}
|
||||
|
||||
void SetWeeklyQuestStatus(uint quest_id)
|
||||
|
||||
@@ -32,10 +32,11 @@ namespace Game.Entities
|
||||
void UpdateSkillsForLevel()
|
||||
{
|
||||
ushort maxSkill = GetMaxSkillValueForLevel();
|
||||
SkillInfo skillInfoField = m_activePlayerData.Skill;
|
||||
|
||||
foreach (var pair in mSkillStatus)
|
||||
{
|
||||
if (pair.Value.State == SkillState.Deleted)
|
||||
if (pair.Value.State == SkillState.Deleted || skillInfoField.SkillRank[pair.Value.Pos] == 0)
|
||||
continue;
|
||||
|
||||
uint pskill = pair.Key;
|
||||
@@ -43,36 +44,35 @@ namespace Game.Entities
|
||||
if (rcEntry == null)
|
||||
continue;
|
||||
|
||||
ushort field = (ushort)(pair.Value.Pos / 2);
|
||||
byte offset = (byte)(pair.Value.Pos & 1);
|
||||
|
||||
if (Global.SpellMgr.GetSkillRangeType(rcEntry) == SkillRangeType.Level)
|
||||
{
|
||||
ushort max = GetUInt16Value(ActivePlayerFields.SkillLineMaxRank + field, offset);
|
||||
ushort max = skillInfoField.SkillMaxRank[pair.Value.Pos];
|
||||
|
||||
// update only level dependent max skill values
|
||||
if (max != 1)
|
||||
{
|
||||
SetUInt16Value(ActivePlayerFields.SkillLineRank + field, offset, maxSkill);
|
||||
SetUInt16Value(ActivePlayerFields.SkillLineMaxRank + field, offset, maxSkill);
|
||||
SetSkillRank(pair.Value.Pos, maxSkill);
|
||||
SetSkillMaxRank(pair.Value.Pos, maxSkill);
|
||||
if (pair.Value.State != SkillState.New)
|
||||
pair.Value.State = SkillState.Changed;
|
||||
}
|
||||
}
|
||||
|
||||
// Update level dependent skillline spells
|
||||
LearnSkillRewardedSpells(rcEntry.SkillID, GetUInt16Value(ActivePlayerFields.SkillLineRank + field, offset));
|
||||
LearnSkillRewardedSpells(rcEntry.SkillID, skillInfoField.SkillRank[pair.Value.Pos]);
|
||||
}
|
||||
}
|
||||
|
||||
public void UpdateSkillsToMaxSkillsForLevel()
|
||||
{
|
||||
foreach (var skill in mSkillStatus)
|
||||
SkillInfo skillInfoField = m_activePlayerData.Skill;
|
||||
|
||||
foreach (var pair in mSkillStatus)
|
||||
{
|
||||
if (skill.Value.State == SkillState.Deleted)
|
||||
if (pair.Value.State == SkillState.Deleted || skillInfoField.SkillRank[pair.Value.Pos] == 0)
|
||||
continue;
|
||||
|
||||
uint pskill = skill.Key;
|
||||
uint pskill = pair.Key;
|
||||
SkillRaceClassInfoRecord rcEntry = Global.DB2Mgr.GetSkillRaceClassInfo(pskill, GetRace(), GetClass());
|
||||
if (rcEntry == null)
|
||||
continue;
|
||||
@@ -83,16 +83,13 @@ namespace Game.Entities
|
||||
if (Global.SpellMgr.IsWeaponSkill(rcEntry.SkillID))
|
||||
continue;
|
||||
|
||||
ushort field = (ushort)(skill.Value.Pos / 2);
|
||||
byte offset = (byte)(skill.Value.Pos & 1);
|
||||
|
||||
ushort max = GetUInt16Value(ActivePlayerFields.SkillLineMaxRank + field, offset);
|
||||
ushort max = skillInfoField.SkillMaxRank[pair.Value.Pos];
|
||||
if (max > 1)
|
||||
{
|
||||
SetUInt16Value(ActivePlayerFields.SkillLineRank + field, offset, max);
|
||||
SetSkillRank(pair.Value.Pos, max);
|
||||
|
||||
if (skill.Value.State != SkillState.New)
|
||||
skill.Value.State = SkillState.Changed;
|
||||
if (pair.Value.State != SkillState.New)
|
||||
pair.Value.State = SkillState.Changed;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -102,16 +99,15 @@ namespace Game.Entities
|
||||
if (skill == 0)
|
||||
return 0;
|
||||
|
||||
SkillInfo skillInfo = m_activePlayerData.Skill;
|
||||
|
||||
var skillStatusData = mSkillStatus.LookupByKey(skill);
|
||||
if (skillStatusData == null || skillStatusData.State == SkillState.Deleted)
|
||||
if (skillStatusData == null || skillStatusData.State == SkillState.Deleted || skillInfo.SkillRank[skillStatusData.Pos] == 0)
|
||||
return 0;
|
||||
|
||||
var field = (ushort)(skillStatusData.Pos / 2);
|
||||
var offset = (byte)(skillStatusData.Pos & 1);
|
||||
|
||||
int result = GetUInt16Value(ActivePlayerFields.SkillLineRank + field, offset);
|
||||
result += GetUInt16Value(ActivePlayerFields.SkillLineTempBonus + field, offset);
|
||||
result += GetUInt16Value(ActivePlayerFields.SkillLinePermBonus + field, offset);
|
||||
int result = skillInfo.SkillRank[skillStatusData.Pos];
|
||||
result += skillInfo.SkillTempBonus[skillStatusData.Pos];
|
||||
result += skillInfo.SkillPermBonus[skillStatusData.Pos];
|
||||
return (ushort)(result < 0 ? 0 : result);
|
||||
}
|
||||
|
||||
@@ -120,16 +116,15 @@ namespace Game.Entities
|
||||
if (skill == 0)
|
||||
return 0;
|
||||
|
||||
SkillInfo skillInfo = m_activePlayerData.Skill;
|
||||
|
||||
var skillStatusData = mSkillStatus.LookupByKey(skill);
|
||||
if (skillStatusData == null || skillStatusData.State == SkillState.Deleted)
|
||||
if (skillStatusData == null || skillStatusData.State == SkillState.Deleted || skillInfo.SkillRank[skillStatusData.Pos] == 0)
|
||||
return 0;
|
||||
|
||||
var field = (ushort)(skillStatusData.Pos / 2);
|
||||
var offset = (byte)(skillStatusData.Pos & 1);
|
||||
|
||||
int result = GetUInt16Value(ActivePlayerFields.SkillLineMaxRank + field, offset);
|
||||
result += GetUInt16Value(ActivePlayerFields.SkillLineTempBonus + field, offset);
|
||||
result += GetUInt16Value(ActivePlayerFields.SkillLinePermBonus + field, offset);
|
||||
int result = skillInfo.SkillMaxRank[skillStatusData.Pos];
|
||||
result += skillInfo.SkillTempBonus[skillStatusData.Pos];
|
||||
result += skillInfo.SkillPermBonus[skillStatusData.Pos];
|
||||
return (ushort)(result < 0 ? 0 : result);
|
||||
}
|
||||
|
||||
@@ -138,14 +133,13 @@ namespace Game.Entities
|
||||
if (skill == 0)
|
||||
return 0;
|
||||
|
||||
SkillInfo skillInfo = m_activePlayerData.Skill;
|
||||
|
||||
var skillStatusData = mSkillStatus.LookupByKey((uint)skill);
|
||||
if (skillStatusData == null || skillStatusData.State == SkillState.Deleted)
|
||||
if (skillStatusData == null || skillStatusData.State == SkillState.Deleted || skillInfo.SkillRank[skillStatusData.Pos] == 0)
|
||||
return 0;
|
||||
|
||||
var field = (ushort)(skillStatusData.Pos / 2);
|
||||
var offset = (byte)(skillStatusData.Pos & 1);
|
||||
|
||||
return GetUInt16Value(ActivePlayerFields.SkillLineRank + field, offset);
|
||||
return skillInfo.SkillRank[skillStatusData.Pos];
|
||||
}
|
||||
|
||||
public ushort GetSkillStep(SkillType skill)
|
||||
@@ -153,14 +147,16 @@ namespace Game.Entities
|
||||
if (skill == 0)
|
||||
return 0;
|
||||
|
||||
SkillInfo skillInfo = m_activePlayerData.Skill;
|
||||
|
||||
var skillStatusData = mSkillStatus.LookupByKey(skill);
|
||||
if (skillStatusData == null || skillStatusData.State == SkillState.Deleted)
|
||||
if (skillStatusData == null || skillStatusData.State == SkillState.Deleted || skillInfo.SkillRank[skillStatusData.Pos] == 0)
|
||||
return 0;
|
||||
|
||||
var field = (ushort)(skillStatusData.Pos / 2);
|
||||
var offset = (byte)(skillStatusData.Pos & 1);
|
||||
|
||||
return GetUInt16Value(ActivePlayerFields.SkillLineStep + field, offset);
|
||||
return skillInfo.SkillStep[skillStatusData.Pos];
|
||||
}
|
||||
|
||||
public ushort GetPureMaxSkillValue(SkillType skill)
|
||||
@@ -168,14 +164,13 @@ namespace Game.Entities
|
||||
if (skill == 0)
|
||||
return 0;
|
||||
|
||||
SkillInfo skillInfo = m_activePlayerData.Skill;
|
||||
|
||||
var skillStatusData = mSkillStatus.LookupByKey(skill);
|
||||
if (skillStatusData == null || skillStatusData.State == SkillState.Deleted)
|
||||
if (skillStatusData == null || skillStatusData.State == SkillState.Deleted || skillInfo.SkillRank[skillStatusData.Pos] == 0)
|
||||
return 0;
|
||||
|
||||
var field = (ushort)(skillStatusData.Pos / 2);
|
||||
var offset = (byte)(skillStatusData.Pos & 1);
|
||||
|
||||
return GetUInt16Value(ActivePlayerFields.SkillLineMaxRank + field, offset);
|
||||
return skillInfo.SkillMaxRank[skillStatusData.Pos];
|
||||
}
|
||||
|
||||
public ushort GetBaseSkillValue(SkillType skill)
|
||||
@@ -183,15 +178,14 @@ namespace Game.Entities
|
||||
if (skill == 0)
|
||||
return 0;
|
||||
|
||||
SkillInfo skillInfo = m_activePlayerData.Skill;
|
||||
|
||||
var skillStatusData = mSkillStatus.LookupByKey(skill);
|
||||
if (skillStatusData == null || skillStatusData.State == SkillState.Deleted)
|
||||
if (skillStatusData == null || skillStatusData.State == SkillState.Deleted || skillInfo.SkillRank[skillStatusData.Pos] == 0)
|
||||
return 0;
|
||||
|
||||
var field = (ushort)(skillStatusData.Pos / 2);
|
||||
var offset = (byte)(skillStatusData.Pos & 1);
|
||||
|
||||
var result = (int)GetUInt16Value(ActivePlayerFields.SkillLineRank + field, offset);
|
||||
result += GetUInt16Value(ActivePlayerFields.SkillLinePermBonus + field, offset);
|
||||
int result = skillInfo.SkillRank[skillStatusData.Pos];
|
||||
result += skillInfo.SkillPermBonus[skillStatusData.Pos];
|
||||
return (ushort)(result < 0 ? 0 : result);
|
||||
}
|
||||
|
||||
@@ -200,14 +194,13 @@ namespace Game.Entities
|
||||
if (skill == 0)
|
||||
return 0;
|
||||
|
||||
SkillInfo skillInfo = m_activePlayerData.Skill;
|
||||
|
||||
var skillStatusData = mSkillStatus.LookupByKey(skill);
|
||||
if (skillStatusData == null || skillStatusData.State == SkillState.Deleted)
|
||||
if (skillStatusData == null || skillStatusData.State == SkillState.Deleted || skillInfo.SkillRank[skillStatusData.Pos] == 0)
|
||||
return 0;
|
||||
|
||||
var field = (ushort)(skillStatusData.Pos / 2);
|
||||
var offset = (byte)(skillStatusData.Pos & 1);
|
||||
|
||||
return GetUInt16Value(ActivePlayerFields.SkillLinePermBonus + field, offset);
|
||||
return skillInfo.SkillPermBonus[skillStatusData.Pos];
|
||||
}
|
||||
|
||||
public ushort GetSkillTempBonusValue(uint skill)
|
||||
@@ -215,19 +208,18 @@ namespace Game.Entities
|
||||
if (skill == 0)
|
||||
return 0;
|
||||
|
||||
SkillInfo skillInfo = m_activePlayerData.Skill;
|
||||
|
||||
var skillStatusData = mSkillStatus.LookupByKey(skill);
|
||||
if (skillStatusData == null || skillStatusData.State == SkillState.Deleted)
|
||||
if (skillStatusData == null || skillStatusData.State == SkillState.Deleted || skillInfo.SkillRank[skillStatusData.Pos] == 0)
|
||||
return 0;
|
||||
|
||||
var field = (ushort)(skillStatusData.Pos / 2);
|
||||
var offset = (byte)(skillStatusData.Pos & 1);
|
||||
|
||||
return GetUInt16Value(ActivePlayerFields.SkillLineTempBonus + field, offset);
|
||||
return skillInfo.SkillTempBonus[skillStatusData.Pos];
|
||||
}
|
||||
|
||||
void InitializeSelfResurrectionSpells()
|
||||
{
|
||||
ClearDynamicValue(ActivePlayerDynamicFields.SelfResSpells);
|
||||
ClearSelfResSpell();
|
||||
|
||||
uint[] spells = new uint[3];
|
||||
|
||||
@@ -248,7 +240,7 @@ namespace Game.Entities
|
||||
|
||||
foreach (uint selfResSpell in spells)
|
||||
if (selfResSpell != 0)
|
||||
AddDynamicValue(ActivePlayerDynamicFields.SelfResSpells, selfResSpell);
|
||||
AddSelfResSpell(selfResSpell);
|
||||
}
|
||||
|
||||
public void PetSpellInitialize()
|
||||
@@ -294,7 +286,7 @@ namespace Game.Entities
|
||||
|
||||
public bool CanSeeSpellClickOn(Creature creature)
|
||||
{
|
||||
if (!creature.HasFlag64(UnitFields.NpcFlags, NPCFlags.SpellClick))
|
||||
if (!creature.HasNpcFlag(NPCFlags.SpellClick))
|
||||
return false;
|
||||
|
||||
var clickPair = Global.ObjectMgr.GetSpellClickInfoMapBounds(creature.GetEntry());
|
||||
@@ -329,19 +321,21 @@ namespace Game.Entities
|
||||
return base.GetCastSpellInfo(spellInfo);
|
||||
}
|
||||
|
||||
void AddOverrideSpell(uint overridenSpellId, uint newSpellId)
|
||||
public void SetOverrideSpellsId(uint overrideSpellsId) { SetUpdateFieldValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.OverrideSpellsID), overrideSpellsId); }
|
||||
|
||||
public void AddOverrideSpell(uint overridenSpellId, uint newSpellId)
|
||||
{
|
||||
m_overrideSpells.Add(overridenSpellId, newSpellId);
|
||||
}
|
||||
|
||||
void RemoveOverrideSpell(uint overridenSpellId, uint newSpellId)
|
||||
public void RemoveOverrideSpell(uint overridenSpellId, uint newSpellId)
|
||||
{
|
||||
m_overrideSpells.Remove(overridenSpellId, newSpellId);
|
||||
}
|
||||
|
||||
void LearnSpecializationSpells()
|
||||
{
|
||||
var specSpells = Global.DB2Mgr.GetSpecializationSpells(GetUInt32Value(PlayerFields.CurrentSpecId));
|
||||
var specSpells = Global.DB2Mgr.GetSpecializationSpells(GetPrimarySpecialization());
|
||||
if (specSpells != null)
|
||||
{
|
||||
for (int j = 0; j < specSpells.Count; ++j)
|
||||
@@ -406,6 +400,23 @@ namespace Game.Entities
|
||||
SendPacket(cooldowns);
|
||||
}
|
||||
|
||||
void InitializeSkillFields()
|
||||
{
|
||||
uint i = 0;
|
||||
foreach (SkillLineRecord skillLine in CliDB.SkillLineStorage.Values)
|
||||
{
|
||||
SkillRaceClassInfoRecord rcEntry = Global.DB2Mgr.GetSkillRaceClassInfo(skillLine.Id, GetRace(), GetClass());
|
||||
if (rcEntry != null)
|
||||
{
|
||||
SetSkillLineId(i, (ushort)skillLine.Id);
|
||||
SetSkillStartingRank(i, 1);
|
||||
mSkillStatus.Add(skillLine.Id, new SkillStatusData(i, SkillState.Unchanged));
|
||||
if (++i >= SkillConst.MaxPlayerSkills)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool UpdateSkillPro(SkillType skillId, int chance, uint step)
|
||||
{
|
||||
return UpdateSkillPro((uint)skillId, chance, step);
|
||||
@@ -431,11 +442,10 @@ namespace Game.Entities
|
||||
if (skillStatusData == null || skillStatusData.State == SkillState.Deleted)
|
||||
return false;
|
||||
|
||||
ushort field = (ushort)(skillStatusData.Pos / 2);
|
||||
byte offset = (byte)(skillStatusData.Pos & 1);
|
||||
SkillInfo skillInfoField = m_activePlayerData.Skill;
|
||||
|
||||
ushort value = GetUInt16Value(ActivePlayerFields.SkillLineRank + field, offset);
|
||||
ushort max = GetUInt16Value(ActivePlayerFields.SkillLineMaxRank + field, offset);
|
||||
ushort value = skillInfoField.SkillRank[skillStatusData.Pos];
|
||||
ushort max = skillInfoField.SkillMaxRank[skillStatusData.Pos];
|
||||
|
||||
if (max == 0 || value == 0 || value >= max)
|
||||
return false;
|
||||
@@ -450,7 +460,7 @@ namespace Game.Entities
|
||||
if (new_value > max)
|
||||
new_value = max;
|
||||
|
||||
SetUInt16Value(ActivePlayerFields.SkillLineRank + field, offset, new_value);
|
||||
SetSkillRank(skillStatusData.Pos, new_value);
|
||||
if (skillStatusData.State != SkillState.New)
|
||||
skillStatusData.State = SkillState.Changed;
|
||||
|
||||
@@ -577,7 +587,7 @@ namespace Game.Entities
|
||||
}
|
||||
|
||||
// Cogwheel gems dont have requirement data set in SpellItemEnchantment.dbc, but they do have it in Item-sparse.db2
|
||||
ItemDynamicFieldGems gem = item.GetGem((ushort)(slot - EnchantmentSlot.Sock1));
|
||||
SocketedGem gem = item.GetGem((ushort)(slot - EnchantmentSlot.Sock1));
|
||||
if (gem != null)
|
||||
{
|
||||
ItemTemplate gemTemplate = Global.ObjectMgr.GetItemTemplate(gem.ItemId);
|
||||
@@ -617,31 +627,7 @@ namespace Game.Entities
|
||||
if (enchant_spell_id != 0)
|
||||
{
|
||||
if (apply)
|
||||
{
|
||||
int basepoints = 0;
|
||||
// Random Property Exist - try found basepoints for spell (basepoints depends from item suffix factor)
|
||||
if (item.GetItemRandomPropertyId() < 0)
|
||||
{
|
||||
ItemRandomSuffixRecord item_rand = CliDB.ItemRandomSuffixStorage.LookupByKey(Math.Abs(item.GetItemRandomPropertyId()));
|
||||
if (item_rand != null)
|
||||
{
|
||||
// Search enchant_amount
|
||||
for (int k = 0; k < ItemConst.MaxItemRandomProperties; ++k)
|
||||
{
|
||||
if (item_rand.Enchantment[k] == enchant_id)
|
||||
{
|
||||
basepoints = (int)((item_rand.AllocationPct[k] * item.GetItemSuffixFactor()) / 10000);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Cast custom spell vs all equal basepoints got from enchant_amount
|
||||
if (basepoints != 0)
|
||||
CastCustomSpell(this, enchant_spell_id, basepoints, basepoints, basepoints, true, item);
|
||||
else
|
||||
CastSpell(this, enchant_spell_id, true, item);
|
||||
}
|
||||
CastSpell(this, enchant_spell_id, true, item);
|
||||
else
|
||||
RemoveAurasDueToItemSpell(enchant_spell_id, item.GetGUID());
|
||||
}
|
||||
@@ -650,7 +636,7 @@ namespace Game.Entities
|
||||
if (pEnchant.ScalingClass != 0)
|
||||
{
|
||||
int scalingClass = pEnchant.ScalingClass;
|
||||
if ((GetUInt32Value(UnitFields.MinItemLevel) != 0 || GetUInt32Value(UnitFields.MaxItemlevel) != 0) && pEnchant.ScalingClassRestricted != 0)
|
||||
if ((m_unitData.MinItemLevel != 0 || m_unitData.MaxItemLevel != 0) && pEnchant.ScalingClassRestricted != 0)
|
||||
scalingClass = pEnchant.ScalingClassRestricted;
|
||||
|
||||
uint minLevel = ((uint)(pEnchant.Flags)).HasAnyFlag(0x20u) ? 1 : 60u;
|
||||
@@ -667,22 +653,7 @@ namespace Game.Entities
|
||||
enchant_amount = (uint)(pEnchant.EffectScalingPoints[s] * CliDB.GetSpellScalingColumnForClass(spellScaling, scalingClass));
|
||||
}
|
||||
|
||||
if (enchant_amount == 0)
|
||||
{
|
||||
ItemRandomSuffixRecord item_rand = CliDB.ItemRandomSuffixStorage.LookupByKey(Math.Abs(item.GetItemRandomPropertyId()));
|
||||
if (item_rand != null)
|
||||
{
|
||||
for (int k = 0; k < ItemConst.MaxItemRandomProperties; ++k)
|
||||
{
|
||||
if (item_rand.Enchantment[k] == enchant_id)
|
||||
{
|
||||
enchant_amount = (item_rand.AllocationPct[k] * item.GetItemSuffixFactor()) / 10000;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enchant_amount = Math.Max(enchant_amount, 1u);
|
||||
HandleStatModifier((UnitMods)((uint)UnitMods.ResistanceStart + enchant_spell_id), UnitModifierType.TotalValue, enchant_amount, apply);
|
||||
break;
|
||||
case ItemEnchantmentType.Stat:
|
||||
@@ -690,7 +661,7 @@ namespace Game.Entities
|
||||
if (pEnchant.ScalingClass != 0)
|
||||
{
|
||||
int scalingClass = pEnchant.ScalingClass;
|
||||
if ((GetUInt32Value(UnitFields.MinItemLevel) != 0 || GetUInt32Value(UnitFields.MaxItemlevel) != 0) && pEnchant.ScalingClassRestricted != 0)
|
||||
if ((m_unitData.MinItemLevel != 0 || m_unitData.MaxItemLevel != 0) && pEnchant.ScalingClassRestricted != 0)
|
||||
scalingClass = pEnchant.ScalingClassRestricted;
|
||||
|
||||
uint minLevel = ((uint)(pEnchant.Flags)).HasAnyFlag(0x20u) ? 1 : 60u;
|
||||
@@ -707,21 +678,7 @@ namespace Game.Entities
|
||||
enchant_amount = (uint)(pEnchant.EffectScalingPoints[s] * CliDB.GetSpellScalingColumnForClass(spellScaling, scalingClass));
|
||||
}
|
||||
|
||||
if (enchant_amount == 0)
|
||||
{
|
||||
ItemRandomSuffixRecord item_rand_suffix = CliDB.ItemRandomSuffixStorage.LookupByKey(Math.Abs(item.GetItemRandomPropertyId()));
|
||||
if (item_rand_suffix != null)
|
||||
{
|
||||
for (int k = 0; k < ItemConst.MaxItemRandomProperties; ++k)
|
||||
{
|
||||
if (item_rand_suffix.Enchantment[k] == enchant_id)
|
||||
{
|
||||
enchant_amount = (item_rand_suffix.AllocationPct[k] * item.GetItemSuffixFactor()) / 10000;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
enchant_amount = Math.Max(enchant_amount, 1u);
|
||||
|
||||
Log.outDebug(LogFilter.Player, "Adding {0} to stat nb {1}", enchant_amount, enchant_spell_id);
|
||||
switch ((ItemModType)enchant_spell_id)
|
||||
@@ -914,7 +871,9 @@ namespace Game.Entities
|
||||
|
||||
// visualize enchantment at player and equipped items
|
||||
if (slot == EnchantmentSlot.Perm)
|
||||
SetUInt16Value(PlayerFields.VisibleItem + 1 + (item.GetSlot() * 2), 1, item.GetVisibleItemVisual(this));
|
||||
{
|
||||
SetUpdateFieldValue(m_playerData.ModifyValue(m_playerData.VisibleItems, item.GetSlot()).ModifyValue((VisibleItem visibleItemField) => visibleItemField.ItemVisual), item.GetVisibleItemVisual(this));
|
||||
}
|
||||
|
||||
if (apply_dur)
|
||||
{
|
||||
@@ -935,16 +894,16 @@ namespace Game.Entities
|
||||
|
||||
public void ModifySkillBonus(SkillType skillid, int val, bool talent)
|
||||
{
|
||||
var skill = mSkillStatus.LookupByKey(skillid);
|
||||
if (skill == null || skill.State == SkillState.Deleted)
|
||||
SkillInfo skillInfoField = m_activePlayerData.Skill;
|
||||
|
||||
var skillStatusData = mSkillStatus.LookupByKey(skillid);
|
||||
if (skillStatusData == null || skillStatusData.State == SkillState.Deleted || skillInfoField.SkillRank[skillStatusData.Pos] == 0)
|
||||
return;
|
||||
|
||||
int field = (int)(skill.Pos / 2 + (talent ? ActivePlayerFields.SkillLinePermBonus : ActivePlayerFields.SkillLineTempBonus));
|
||||
byte offset = (byte)(skill.Pos & 1);
|
||||
|
||||
ushort bonus = GetUInt16Value(field, offset);
|
||||
|
||||
SetUInt16Value(field, offset, (ushort)(bonus + val));
|
||||
if (talent)
|
||||
SetSkillPermBonus(skillStatusData.Pos, (ushort)(skillInfoField.SkillPermBonus[skillStatusData.Pos] + val));
|
||||
else
|
||||
SetSkillTempBonus(skillStatusData.Pos, (ushort)(skillInfoField.SkillTempBonus[skillStatusData.Pos] + val));
|
||||
}
|
||||
|
||||
public void StopCastingBindSight()
|
||||
@@ -1091,7 +1050,7 @@ namespace Game.Entities
|
||||
|
||||
public bool CanUseMastery()
|
||||
{
|
||||
ChrSpecializationRecord chrSpec = CliDB.ChrSpecializationStorage.LookupByKey(GetUInt32Value(PlayerFields.CurrentSpecId));
|
||||
ChrSpecializationRecord chrSpec = CliDB.ChrSpecializationStorage.LookupByKey(GetPrimarySpecialization());
|
||||
if (chrSpec != null)
|
||||
return HasSpell(chrSpec.MasterySpellID[0]) || HasSpell(chrSpec.MasterySpellID[1]);
|
||||
|
||||
@@ -1103,8 +1062,10 @@ namespace Game.Entities
|
||||
if (skill == 0)
|
||||
return false;
|
||||
|
||||
var _skill = mSkillStatus.LookupByKey((uint)skill);
|
||||
return _skill != null && _skill.State != SkillState.Deleted;
|
||||
SkillInfo skillInfoField = m_activePlayerData.Skill;
|
||||
|
||||
var skillStatusData = mSkillStatus.LookupByKey((uint)skill);
|
||||
return skillStatusData != null && skillStatusData.State != SkillState.Deleted && skillInfoField.SkillRank[skillStatusData.Pos] != 0;
|
||||
}
|
||||
public void SetSkill(SkillType skill, uint step, uint newVal, uint maxVal)
|
||||
{
|
||||
@@ -1117,13 +1078,12 @@ namespace Game.Entities
|
||||
|
||||
ushort currVal;
|
||||
var skillStatusData = mSkillStatus.LookupByKey(id);
|
||||
SkillInfo skillInfoField = m_activePlayerData.Skill;
|
||||
|
||||
//has skill
|
||||
if (skillStatusData != null && skillStatusData.State != SkillState.Deleted)
|
||||
{
|
||||
var field = (ushort)(skillStatusData.Pos / 2);
|
||||
var offset = (byte)(skillStatusData.Pos & 1);
|
||||
currVal = GetUInt16Value(ActivePlayerFields.SkillLineRank + field, offset);
|
||||
currVal = skillInfoField.SkillRank[skillStatusData.Pos];
|
||||
if (newVal != 0)
|
||||
{
|
||||
// if skill value is going down, update enchantments before setting the new value
|
||||
@@ -1131,10 +1091,10 @@ namespace Game.Entities
|
||||
UpdateSkillEnchantments(id, currVal, (ushort)newVal);
|
||||
|
||||
// update step
|
||||
SetUInt16Value(ActivePlayerFields.SkillLineStep + field, offset, (ushort)step);
|
||||
SetSkillStep(skillStatusData.Pos, (ushort)step);
|
||||
// update value
|
||||
SetUInt16Value(ActivePlayerFields.SkillLineRank + field, offset, (ushort)newVal);
|
||||
SetUInt16Value(ActivePlayerFields.SkillLineMaxRank + field, offset, (ushort)maxVal);
|
||||
SetSkillRank(skillStatusData.Pos, (ushort)newVal);
|
||||
SetSkillMaxRank(skillStatusData.Pos, (ushort)maxVal);
|
||||
|
||||
if (skillStatusData.State != SkillState.New)
|
||||
skillStatusData.State = SkillState.Changed;
|
||||
@@ -1152,45 +1112,45 @@ namespace Game.Entities
|
||||
//remove enchantments needing this skill
|
||||
UpdateSkillEnchantments(id, currVal, 0);
|
||||
// clear skill fields
|
||||
SetUInt16Value(ActivePlayerFields.SkillLineId + field, offset, 0);
|
||||
SetUInt16Value(ActivePlayerFields.SkillLineStep + field, offset, 0);
|
||||
SetUInt16Value(ActivePlayerFields.SkillLineRank + field, offset, 0);
|
||||
SetUInt16Value(ActivePlayerFields.SkillLineMaxRank + field, offset, 0);
|
||||
SetUInt16Value(ActivePlayerFields.SkillLineTempBonus + field, offset, 0);
|
||||
SetUInt16Value(ActivePlayerFields.SkillLinePermBonus + field, offset, 0);
|
||||
SetSkillStep(skillStatusData.Pos, 0);
|
||||
SetSkillRank(skillStatusData.Pos, 0);
|
||||
SetSkillStartingRank(skillStatusData.Pos, 1);
|
||||
SetSkillMaxRank(skillStatusData.Pos, 0);
|
||||
SetSkillTempBonus(skillStatusData.Pos, 0);
|
||||
SetSkillPermBonus(skillStatusData.Pos, 0);
|
||||
|
||||
// mark as deleted or simply remove from map if not saved yet
|
||||
if (skillStatusData.State != SkillState.New)
|
||||
skillStatusData.State = SkillState.Deleted;
|
||||
else
|
||||
mSkillStatus.Remove(id);
|
||||
|
||||
// remove all spells that related to this skill
|
||||
List<SkillLineAbilityRecord> skillLineAbilities = Global.DB2Mgr.GetSkillLineAbilitiesBySkill(id);
|
||||
foreach (SkillLineAbilityRecord skillLineAbility in skillLineAbilities)
|
||||
RemoveSpell(Global.SpellMgr.GetFirstSpellInChain(skillLineAbility.Spell));
|
||||
|
||||
foreach (SkillLineRecord childSkillLine in CliDB.SkillLineStorage.Values)
|
||||
List<SkillLineRecord> childSkillLines = Global.DB2Mgr.GetSkillLinesForParentSkill(id);
|
||||
if (childSkillLines != null)
|
||||
{
|
||||
if (childSkillLine.ParentSkillLineID == id)
|
||||
SetSkill(childSkillLine.Id, 0, 0, 0);
|
||||
foreach (SkillLineRecord childSkillLine in childSkillLines)
|
||||
{
|
||||
if (childSkillLine.ParentSkillLineID == id)
|
||||
SetSkill(childSkillLine.Id, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
// Clear profession lines
|
||||
if (GetUInt32Value(ActivePlayerFields.ProfessionSkillLine) == id)
|
||||
SetUInt32Value(ActivePlayerFields.ProfessionSkillLine, 0);
|
||||
else if (GetUInt32Value(ActivePlayerFields.ProfessionSkillLine + 1) == id)
|
||||
SetUInt32Value(ActivePlayerFields.ProfessionSkillLine + 1, 0);
|
||||
if (m_activePlayerData.ProfessionSkillLine[0] == id)
|
||||
SetUpdateFieldValue(ref m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.ProfessionSkillLine, 0), 0u);
|
||||
else if (m_activePlayerData.ProfessionSkillLine[1] == id)
|
||||
SetUpdateFieldValue(ref m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.ProfessionSkillLine, 1), 0u);
|
||||
}
|
||||
}
|
||||
else if (newVal != 0) //add
|
||||
else //add
|
||||
{
|
||||
currVal = 0;
|
||||
for (int i = 0; i < SkillConst.MaxPlayerSkills; ++i)
|
||||
for (uint i = 0; i < SkillConst.MaxPlayerSkills; ++i)
|
||||
{
|
||||
var field = (ushort)(i / 2);
|
||||
var offset = (byte)(i & 1);
|
||||
if (GetUInt16Value(ActivePlayerFields.SkillLineId + field, offset) == 0)
|
||||
if (skillInfoField.SkillLineID[(int)i] == 0)
|
||||
{
|
||||
var skillEntry = CliDB.SkillLineStorage.LookupByKey(id);
|
||||
if (skillEntry == null)
|
||||
@@ -1200,7 +1160,7 @@ namespace Game.Entities
|
||||
}
|
||||
|
||||
|
||||
if (skillEntry.ParentSkillLineID != 0 && skillEntry.ParentTierIndex > 0)
|
||||
if (skillEntry.ParentSkillLineID != 0)
|
||||
{
|
||||
SkillRaceClassInfoRecord rcEntry = Global.DB2Mgr.GetSkillRaceClassInfo(skillEntry.ParentSkillLineID, GetRace(), GetClass());
|
||||
if (rcEntry != null)
|
||||
@@ -1209,25 +1169,38 @@ namespace Game.Entities
|
||||
if (tier != null)
|
||||
{
|
||||
ushort skillval = GetPureSkillValue((SkillType)skillEntry.ParentSkillLineID);
|
||||
SetSkill((SkillType)skillEntry.ParentSkillLineID, (uint)skillEntry.ParentTierIndex, Math.Max(skillval, (ushort)1), tier.Value[skillEntry.ParentTierIndex - 1]);
|
||||
SetSkill(skillEntry.ParentSkillLineID, (uint)skillEntry.ParentTierIndex, Math.Max(skillval, (ushort)1), tier.Value[skillEntry.ParentTierIndex - 1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // also learn missing child skills at 0 value
|
||||
List<SkillLineRecord> childSkillLines = Global.DB2Mgr.GetSkillLinesForParentSkill(id);
|
||||
if (childSkillLines != null)
|
||||
foreach (SkillLineRecord childSkillLine in childSkillLines)
|
||||
if (!HasSkill((SkillType)childSkillLine.Id))
|
||||
SetSkill(childSkillLine.Id, 0, 0, 0);
|
||||
|
||||
if (skillEntry.CategoryID == SkillCategory.Profession)
|
||||
{
|
||||
int freeProfessionSlot = FindProfessionSlotFor(id);
|
||||
if (freeProfessionSlot != -1)
|
||||
SetUInt32Value(ActivePlayerFields.ProfessionSkillLine + freeProfessionSlot, id);
|
||||
SetUpdateFieldValue(ref m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.ProfessionSkillLine, freeProfessionSlot), id);
|
||||
}
|
||||
}
|
||||
|
||||
SetUInt16Value(ActivePlayerFields.SkillLineId + field, offset, (ushort)id);
|
||||
SetUInt16Value(ActivePlayerFields.SkillLineStep + field, offset, (ushort)step);
|
||||
SetUInt16Value(ActivePlayerFields.SkillLineRank + field, offset, (ushort)newVal);
|
||||
SetUInt16Value(ActivePlayerFields.SkillLineMaxRank + field, offset, (ushort)maxVal);
|
||||
SetSkillLineId(i, (ushort)id);
|
||||
|
||||
SetSkillStep(i, (ushort)step);
|
||||
SetSkillRank(i, (ushort)newVal);
|
||||
SetSkillStartingRank(i, 1);
|
||||
SetSkillMaxRank(i, (ushort)maxVal);
|
||||
|
||||
// apply skill bonuses
|
||||
SetSkillTempBonus(i, 0);
|
||||
SetSkillPermBonus(i, 0);
|
||||
|
||||
UpdateSkillEnchantments(id, currVal, (ushort)newVal);
|
||||
UpdateCriteria(CriteriaTypes.ReachSkillLevel, id);
|
||||
UpdateCriteria(CriteriaTypes.LearnSkillLevel, id);
|
||||
|
||||
// insert new entry or update if not deleted old entry yet
|
||||
if (skillStatusData != null)
|
||||
@@ -1238,35 +1211,31 @@ namespace Game.Entities
|
||||
else
|
||||
mSkillStatus.Add(id, new SkillStatusData((uint)i, SkillState.New));
|
||||
|
||||
// apply skill bonuses
|
||||
SetUInt16Value(ActivePlayerFields.SkillLineTempBonus + field, offset, 0);
|
||||
SetUInt16Value(ActivePlayerFields.SkillLinePermBonus + field, offset, 0);
|
||||
|
||||
// temporary bonuses
|
||||
var mModSkill = GetAuraEffectsByType(AuraType.ModSkill);
|
||||
foreach (var j in mModSkill)
|
||||
if (newVal != 0)
|
||||
{
|
||||
if (j.GetMiscValue() == id)
|
||||
j.HandleEffect(this, AuraEffectHandleModes.Skill, true);
|
||||
}
|
||||
UpdateCriteria(CriteriaTypes.ReachSkillLevel, id);
|
||||
UpdateCriteria(CriteriaTypes.LearnSkillLevel, id);
|
||||
|
||||
var mModSkill2 = GetAuraEffectsByType(AuraType.ModSkill2);
|
||||
foreach (var j in mModSkill2)
|
||||
{
|
||||
if (j.GetMiscValue() == id)
|
||||
j.HandleEffect(this, AuraEffectHandleModes.Skill, true);
|
||||
}
|
||||
// temporary bonuses
|
||||
var mModSkill = GetAuraEffectsByType(AuraType.ModSkill);
|
||||
foreach (var auraEffect in mModSkill)
|
||||
if (auraEffect.GetMiscValue() == id)
|
||||
auraEffect.HandleEffect(this, AuraEffectHandleModes.Skill, true);
|
||||
|
||||
// permanent bonuses
|
||||
var mModSkillTalent = GetAuraEffectsByType(AuraType.ModSkillTalent);
|
||||
foreach (var eff in mModSkillTalent)
|
||||
{
|
||||
if (eff.GetMiscValue() == id)
|
||||
eff.HandleEffect(this, AuraEffectHandleModes.Skill, true);
|
||||
}
|
||||
var mModSkill2 = GetAuraEffectsByType(AuraType.ModSkill2);
|
||||
foreach (var auraEffect in mModSkill2)
|
||||
if (auraEffect.GetMiscValue() == id)
|
||||
auraEffect.HandleEffect(this, AuraEffectHandleModes.Skill, true);
|
||||
|
||||
// Learn all spells for skill
|
||||
LearnSkillRewardedSpells(id, newVal);
|
||||
// permanent bonuses
|
||||
var mModSkillTalent = GetAuraEffectsByType(AuraType.ModSkillTalent);
|
||||
foreach (var auraEffect in mModSkillTalent)
|
||||
if (auraEffect.GetMiscValue() == id)
|
||||
auraEffect.HandleEffect(this, AuraEffectHandleModes.Skill, true);
|
||||
|
||||
// Learn all spells for skill
|
||||
LearnSkillRewardedSpells(id, newVal);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -1424,7 +1393,7 @@ namespace Game.Entities
|
||||
Item pItem2 = GetItemByPos(InventorySlots.Bag0, i);
|
||||
if (pItem2 != null && !pItem2.IsBroken())
|
||||
{
|
||||
foreach (ItemDynamicFieldGems gemData in pItem2.GetGems())
|
||||
foreach (SocketedGem gemData in pItem2.m_itemData.Gems)
|
||||
{
|
||||
ItemTemplate gemProto = Global.ObjectMgr.GetItemTemplate(gemData.ItemId);
|
||||
if (gemProto == null)
|
||||
@@ -1642,7 +1611,7 @@ namespace Game.Entities
|
||||
if (ability.AcquireMethod != AbilityLearnType.OnSkillValue && ability.AcquireMethod != AbilityLearnType.OnSkillLearn)
|
||||
continue;
|
||||
|
||||
// AcquireMethod == 2 && NumSkillUps == 1 --> automatically learn riding skill spell, else we skip it (client shows riding in spellbook as trainable).
|
||||
// AcquireMethod == 2 && NumSkillUps == 1 -. automatically learn riding skill spell, else we skip it (client shows riding in spellbook as trainable).
|
||||
if (skillId == (uint)SkillType.Riding && (ability.AcquireMethod != AbilityLearnType.OnSkillLearn || ability.NumSkillUps != 1))
|
||||
continue;
|
||||
|
||||
@@ -1676,39 +1645,15 @@ namespace Game.Entities
|
||||
if (skillEntry == null)
|
||||
return -1;
|
||||
|
||||
// both free, return first slot
|
||||
if (GetUInt32Value(ActivePlayerFields.ProfessionSkillLine) == 0 && GetUInt32Value(ActivePlayerFields.ProfessionSkillLine + 1) == 0)
|
||||
return 0;
|
||||
|
||||
ActivePlayerFields professionsBegin = ActivePlayerFields.ProfessionSkillLine;
|
||||
ActivePlayerFields professionsEnd = professionsBegin + 2;
|
||||
|
||||
// when any slot is filled we need to check both - one of them might be earlier step of the same profession
|
||||
ActivePlayerFields sameProfessionSlot = professionsEnd;
|
||||
for (var slot = professionsBegin; slot < professionsEnd; ++slot)
|
||||
{
|
||||
SkillLineRecord slotProfession = CliDB.SkillLineStorage.LookupByKey(GetUInt32Value(slot));
|
||||
if (slotProfession != null)
|
||||
{
|
||||
if (slotProfession.ParentSkillLineID == skillEntry.ParentSkillLineID)
|
||||
{
|
||||
sameProfessionSlot = slot;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (sameProfessionSlot != professionsEnd)
|
||||
{
|
||||
if (CliDB.SkillLineStorage.LookupByKey(sameProfessionSlot).ParentTierIndex < skillEntry.ParentTierIndex)
|
||||
return sameProfessionSlot - professionsBegin;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int index = 0;
|
||||
// if there is no same profession, find any free slot
|
||||
for (var slot = professionsBegin; slot < professionsEnd; ++slot)
|
||||
if (GetUInt32Value(slot) == 0)
|
||||
return slot - professionsBegin;
|
||||
foreach (var b in m_activePlayerData.ProfessionSkillLine)
|
||||
{
|
||||
if (b == 0)
|
||||
return index;
|
||||
|
||||
index++;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
@@ -2288,7 +2233,7 @@ namespace Game.Entities
|
||||
|
||||
public bool IsCurrentSpecMasterySpell(SpellInfo spellInfo)
|
||||
{
|
||||
ChrSpecializationRecord chrSpec = CliDB.ChrSpecializationStorage.LookupByKey(GetUInt32Value(PlayerFields.CurrentSpecId));
|
||||
ChrSpecializationRecord chrSpec = CliDB.ChrSpecializationStorage.LookupByKey(GetPrimarySpecialization());
|
||||
if (chrSpec != null)
|
||||
return spellInfo.Id == chrSpec.MasterySpellID[0] || spellInfo.Id == chrSpec.MasterySpellID[1];
|
||||
|
||||
@@ -3107,7 +3052,7 @@ namespace Game.Entities
|
||||
{
|
||||
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(itemSetSpell.SpellID);
|
||||
|
||||
if (itemSetSpell.ChrSpecID != 0 && itemSetSpell.ChrSpecID != GetUInt32Value(PlayerFields.CurrentSpecId))
|
||||
if (itemSetSpell.ChrSpecID != 0 && itemSetSpell.ChrSpecID != GetPrimarySpecialization())
|
||||
ApplyEquipSpell(spellInfo, null, false, false); // item set aura is not for current spec
|
||||
else
|
||||
{
|
||||
@@ -3197,7 +3142,7 @@ namespace Game.Entities
|
||||
if (GetClass() != Class.Deathknight)
|
||||
return;
|
||||
|
||||
int runeIndex = (int)GetPowerIndex(PowerType.Runes);
|
||||
uint runeIndex = GetPowerIndex(PowerType.Runes);
|
||||
if (runeIndex == (int)PowerType.Max)
|
||||
return;
|
||||
|
||||
@@ -3208,8 +3153,8 @@ namespace Game.Entities
|
||||
SetRuneCooldown(i, 0); // reset cooldowns
|
||||
|
||||
// set a base regen timer equal to 10 sec
|
||||
SetStatFloatValue(UnitFields.PowerRegenFlatModifier + runeIndex, 0.0f);
|
||||
SetStatFloatValue(UnitFields.PowerRegenInterruptedFlatModifier + runeIndex, 0.0f);
|
||||
SetUpdateFieldValue(ref m_values.ModifyValue(m_unitData).ModifyValue(m_unitData.PowerRegenFlatModifier, (int)runeIndex), 0.0f);
|
||||
SetUpdateFieldValue(ref m_values.ModifyValue(m_unitData).ModifyValue(m_unitData.PowerRegenInterruptedFlatModifier, (int)runeIndex), 0.0f);
|
||||
}
|
||||
|
||||
public void UpdateAllRunesRegen()
|
||||
@@ -3217,15 +3162,15 @@ namespace Game.Entities
|
||||
if (GetClass() != Class.Deathknight)
|
||||
return;
|
||||
|
||||
int runeIndex = (int)GetPowerIndex(PowerType.Runes);
|
||||
uint runeIndex = GetPowerIndex(PowerType.Runes);
|
||||
if (runeIndex == (int)PowerType.Max)
|
||||
return;
|
||||
|
||||
PowerTypeRecord runeEntry = Global.DB2Mgr.GetPowerTypeEntry(PowerType.Runes);
|
||||
|
||||
uint cooldown = GetRuneBaseCooldown();
|
||||
SetStatFloatValue(UnitFields.PowerRegenFlatModifier + runeIndex, (float)(1 * Time.InMilliseconds) / (float)cooldown - runeEntry.RegenPeace);
|
||||
SetStatFloatValue(UnitFields.PowerRegenInterruptedFlatModifier + runeIndex, (float)(1 * Time.InMilliseconds) / (float)cooldown - runeEntry.RegenCombat);
|
||||
SetUpdateFieldValue(ref m_values.ModifyValue(m_unitData).ModifyValue(m_unitData.PowerRegenFlatModifier, (int)runeIndex), (float)(1 * Time.InMilliseconds) / cooldown - runeEntry.RegenPeace);
|
||||
SetUpdateFieldValue(ref m_values.ModifyValue(m_unitData).ModifyValue(m_unitData.PowerRegenInterruptedFlatModifier, (int)runeIndex), (float)(1 * Time.InMilliseconds) / cooldown - runeEntry.RegenCombat);
|
||||
}
|
||||
|
||||
public uint GetRuneCooldown(byte index) { return m_runes.Cooldown[index]; }
|
||||
@@ -3234,20 +3179,25 @@ namespace Game.Entities
|
||||
{
|
||||
// don't take reagents for spells with SPELL_ATTR5_NO_REAGENT_WHILE_PREP
|
||||
if (spellInfo.HasAttribute(SpellAttr5.NoReagentWhilePrep) &&
|
||||
HasFlag(UnitFields.Flags, UnitFlags.Preparation))
|
||||
HasUnitFlag(UnitFlags.Preparation))
|
||||
return true;
|
||||
|
||||
// Check no reagent use mask
|
||||
FlagArray128 noReagentMask = new FlagArray128();
|
||||
noReagentMask[0] = GetUInt32Value(ActivePlayerFields.NoReagentCost);
|
||||
noReagentMask[1] = GetUInt32Value(ActivePlayerFields.NoReagentCost + 1);
|
||||
noReagentMask[2] = GetUInt32Value(ActivePlayerFields.NoReagentCost + 2);
|
||||
noReagentMask[3] = GetUInt32Value(ActivePlayerFields.NoReagentCost + 3);
|
||||
noReagentMask[0] = m_activePlayerData.NoReagentCostMask[0];
|
||||
noReagentMask[1] = m_activePlayerData.NoReagentCostMask[1];
|
||||
noReagentMask[2] = m_activePlayerData.NoReagentCostMask[2];
|
||||
noReagentMask[3] = m_activePlayerData.NoReagentCostMask[3];
|
||||
if (spellInfo.SpellFamilyFlags & noReagentMask)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
public void SetNoRegentCostMask(FlagArray128 mask)
|
||||
{
|
||||
for (byte i = 0; i < 4; ++i)
|
||||
SetUpdateFieldValue(ref m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.NoReagentCostMask, i), mask[i]);
|
||||
}
|
||||
|
||||
public void CastItemCombatSpell(DamageInfo damageInfo)
|
||||
{
|
||||
@@ -3469,6 +3419,16 @@ namespace Game.Entities
|
||||
LearnCustomSpells();
|
||||
LearnQuestRewardedSpells();
|
||||
}
|
||||
|
||||
public void SetPetSpellPower(uint spellPower) { SetUpdateFieldValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.PetSpellPower), spellPower); }
|
||||
|
||||
public void SetSkillLineId(uint pos, ushort skillLineId) { SetUpdateFieldValue(ref m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.Skill)._value.ModifyValue((SkillInfo skillInfo) => skillInfo.SkillLineID, (int)pos), skillLineId); }
|
||||
public void SetSkillStep(uint pos, ushort step) { SetUpdateFieldValue(ref m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.Skill)._value.ModifyValue((SkillInfo skillInfo) => skillInfo.SkillStep, (int)pos), step); }
|
||||
public void SetSkillRank(uint pos, ushort rank) { SetUpdateFieldValue(ref m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.Skill)._value.ModifyValue((SkillInfo skillInfo) => skillInfo.SkillRank, (int)pos), rank); }
|
||||
public void SetSkillStartingRank(uint pos, ushort starting) { SetUpdateFieldValue(ref m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.Skill)._value.ModifyValue((SkillInfo skillInfo) => skillInfo.SkillStartingRank, (int)pos), starting); }
|
||||
public void SetSkillMaxRank(uint pos, ushort max) { SetUpdateFieldValue(ref m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.Skill)._value.ModifyValue((SkillInfo skillInfo) => skillInfo.SkillMaxRank, (int)pos), max); }
|
||||
public void SetSkillTempBonus(uint pos, ushort bonus) { SetUpdateFieldValue(ref m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.Skill)._value.ModifyValue((SkillInfo skillInfo) => skillInfo.SkillTempBonus, (int)pos), bonus); }
|
||||
public void SetSkillPermBonus(uint pos, ushort bonus) { SetUpdateFieldValue(ref m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.Skill)._value.ModifyValue((SkillInfo skillInfo) => skillInfo.SkillPermBonus, (int)pos), bonus); }
|
||||
}
|
||||
|
||||
public class PlayerSpell
|
||||
|
||||
@@ -33,7 +33,7 @@ namespace Game.Entities
|
||||
if (level < PlayerConst.MinSpecializationLevel)
|
||||
ResetTalentSpecialization();
|
||||
|
||||
uint talentTiers = (uint)Global.DB2Mgr.GetNumTalentsAtLevel(level, GetClass());
|
||||
uint talentTiers = Global.DB2Mgr.GetNumTalentsAtLevel(level, GetClass());
|
||||
if (level < 15)
|
||||
{
|
||||
// Remove all talent points
|
||||
@@ -50,7 +50,7 @@ namespace Game.Entities
|
||||
}
|
||||
}
|
||||
|
||||
SetUInt32Value(ActivePlayerFields.MaxTalentTiers, talentTiers);
|
||||
SetUpdateFieldValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.MaxTalentTiers), talentTiers);
|
||||
|
||||
if (!GetSession().PlayerLoading())
|
||||
SendTalentsInfoData(); // update at client
|
||||
@@ -112,14 +112,14 @@ namespace Game.Entities
|
||||
if (IsDead())
|
||||
return TalentLearnResult.FailedCantDoThatRightNow;
|
||||
|
||||
if (GetUInt32Value(PlayerFields.CurrentSpecId) == 0)
|
||||
if (GetPrimarySpecialization() == 0)
|
||||
return TalentLearnResult.FailedNoPrimaryTreeSelected;
|
||||
|
||||
TalentRecord talentInfo = CliDB.TalentStorage.LookupByKey(talentId);
|
||||
if (talentInfo == null)
|
||||
return TalentLearnResult.FailedUnknown;
|
||||
|
||||
if (talentInfo.SpecID != 0 && talentInfo.SpecID != GetUInt32Value(PlayerFields.CurrentSpecId))
|
||||
if (talentInfo.SpecID != 0 && talentInfo.SpecID != GetPrimarySpecialization())
|
||||
return TalentLearnResult.FailedUnknown;
|
||||
|
||||
// prevent learn talent for different class (cheating)
|
||||
@@ -127,7 +127,7 @@ namespace Game.Entities
|
||||
return TalentLearnResult.FailedUnknown;
|
||||
|
||||
// check if we have enough talent points
|
||||
if (talentInfo.TierID >= GetUInt32Value(ActivePlayerFields.MaxTalentTiers))
|
||||
if (talentInfo.TierID >= m_activePlayerData.MaxTalentTiers)
|
||||
return TalentLearnResult.FailedUnknown;
|
||||
|
||||
// TODO: prevent changing talents that are on cooldown
|
||||
@@ -144,7 +144,7 @@ namespace Game.Entities
|
||||
if (talent.SpecID == 0)
|
||||
bestSlotMatch = talent;
|
||||
|
||||
else if (talent.SpecID == GetUInt32Value(PlayerFields.CurrentSpecId))
|
||||
else if (talent.SpecID == GetPrimarySpecialization())
|
||||
{
|
||||
bestSlotMatch = talent;
|
||||
break;
|
||||
@@ -159,13 +159,13 @@ namespace Game.Entities
|
||||
{
|
||||
foreach (TalentRecord talent in Global.DB2Mgr.GetTalentsByPosition(GetClass(), talentInfo.TierID, c))
|
||||
{
|
||||
if (talent.SpecID != 0 && talent.SpecID != GetUInt32Value(PlayerFields.CurrentSpecId))
|
||||
if (talent.SpecID != 0 && talent.SpecID != GetPrimarySpecialization())
|
||||
continue;
|
||||
|
||||
if (!HasTalent(talent.Id, GetActiveTalentGroup()))
|
||||
continue;
|
||||
|
||||
if (!HasFlag(PlayerFields.Flags, PlayerFlags.Resting) && HasFlag(UnitFields.Flags2, UnitFlags2.AllowChangingTalents))
|
||||
if (!HasPlayerFlag(PlayerFlags.Resting) && HasUnitFlag2(UnitFlags2.AllowChangingTalents))
|
||||
return TalentLearnResult.FailedRestArea;
|
||||
|
||||
if (GetSpellHistory().HasCooldown(talent.SpellID))
|
||||
@@ -221,7 +221,6 @@ namespace Game.Entities
|
||||
ChrSpecializationRecord defaultSpec = Global.DB2Mgr.GetDefaultChrSpecializationForClass(GetClass());
|
||||
SetPrimarySpecialization(defaultSpec.Id);
|
||||
SetActiveTalentGroup(defaultSpec.OrderIndex);
|
||||
SetUInt32Value(PlayerFields.CurrentSpecId, defaultSpec.Id);
|
||||
|
||||
LearnSpecializationSpells();
|
||||
|
||||
@@ -238,14 +237,14 @@ namespace Game.Entities
|
||||
void SetTalentResetCost(uint cost) { _specializationInfo.ResetTalentsCost = cost; }
|
||||
long GetTalentResetTime() { return _specializationInfo.ResetTalentsTime; }
|
||||
void SetTalentResetTime(long time_) { _specializationInfo.ResetTalentsTime = time_; }
|
||||
uint GetPrimarySpecialization() { return _specializationInfo.PrimarySpecialization; }
|
||||
void SetPrimarySpecialization(uint spec) { _specializationInfo.PrimarySpecialization = spec; }
|
||||
public uint GetPrimarySpecialization() { return m_playerData.CurrentSpecID; }
|
||||
void SetPrimarySpecialization(uint spec) { SetUpdateFieldValue(m_values.ModifyValue(m_playerData).ModifyValue(m_playerData.CurrentSpecID), spec); }
|
||||
public byte GetActiveTalentGroup() { return _specializationInfo.ActiveGroup; }
|
||||
void SetActiveTalentGroup(byte group) { _specializationInfo.ActiveGroup = group; }
|
||||
|
||||
// Loot Spec
|
||||
public void SetLootSpecId(uint id) { SetUInt32Value(ActivePlayerFields.LootSpecId, id); }
|
||||
uint GetLootSpecId() { return GetUInt32Value(ActivePlayerFields.LootSpecId); }
|
||||
public void SetLootSpecId(uint id) { SetUpdateFieldValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.LootSpecID), (ushort)id); }
|
||||
public uint GetLootSpecId() { return m_activePlayerData.LootSpecID; }
|
||||
|
||||
public uint GetDefaultSpecId()
|
||||
{
|
||||
@@ -334,9 +333,7 @@ namespace Game.Entities
|
||||
RemoveAurasDueToSpell(CliDB.GlyphPropertiesStorage.LookupByKey(glyphId).SpellID);
|
||||
|
||||
SetActiveTalentGroup(spec.OrderIndex);
|
||||
SetUInt32Value(PlayerFields.CurrentSpecId, spec.Id);
|
||||
if (GetPrimarySpecialization() == 0)
|
||||
SetPrimarySpecialization(spec.Id);
|
||||
SetPrimarySpecialization(spec.Id);
|
||||
|
||||
foreach (var talentInfo in CliDB.TalentStorage.Values)
|
||||
{
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -11,9 +11,7 @@ namespace Game.Entities
|
||||
|
||||
public void SetRestBonus(RestTypes restType, float restBonus)
|
||||
{
|
||||
byte rest_rested_offset;
|
||||
byte rest_state_offset;
|
||||
ActivePlayerFields next_level_xp_field;
|
||||
uint next_level_xp;
|
||||
bool affectedByRaF = false;
|
||||
|
||||
switch (restType)
|
||||
@@ -23,9 +21,7 @@ namespace Game.Entities
|
||||
if (_player.getLevel() >= WorldConfig.GetIntValue(WorldCfg.MaxPlayerLevel))
|
||||
restBonus = 0;
|
||||
|
||||
rest_rested_offset = PlayerFieldOffsets.RestRestedXp;
|
||||
rest_state_offset = PlayerFieldOffsets.RestStateXp;
|
||||
next_level_xp_field = ActivePlayerFields.NextLevelXp;
|
||||
next_level_xp = _player.m_activePlayerData.NextLevelXP;
|
||||
affectedByRaF = true;
|
||||
break;
|
||||
case RestTypes.Honor:
|
||||
@@ -33,37 +29,39 @@ namespace Game.Entities
|
||||
if (_player.IsMaxHonorLevel())
|
||||
restBonus = 0;
|
||||
|
||||
rest_rested_offset = PlayerFieldOffsets.RestRestedHonor;
|
||||
rest_state_offset = PlayerFieldOffsets.RestStateHonor;
|
||||
next_level_xp_field = ActivePlayerFields.HonorNextLevel;
|
||||
next_level_xp = _player.m_activePlayerData.HonorNextLevel;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
float rest_bonus_max = next_level_xp * 1.5f / 2;
|
||||
|
||||
if (restBonus < 0)
|
||||
restBonus = 0;
|
||||
|
||||
float rest_bonus_max = (float)(_player.GetUInt32Value(next_level_xp_field)) * 1.5f / 2;
|
||||
|
||||
if (restBonus > rest_bonus_max)
|
||||
_restBonus[(int)restType] = rest_bonus_max;
|
||||
else
|
||||
_restBonus[(int)restType] = restBonus;
|
||||
restBonus = rest_bonus_max;
|
||||
|
||||
_restBonus[(int)restType] = restBonus;
|
||||
|
||||
uint oldBonus = (uint)_restBonus[(int)restType];
|
||||
if (oldBonus == restBonus)
|
||||
return;
|
||||
|
||||
// update data for client
|
||||
if (affectedByRaF && _player.GetsRecruitAFriendBonus(true) && (_player.GetSession().IsARecruiter() || _player.GetSession().GetRecruiterId() != 0))
|
||||
_player.SetUInt32Value(ActivePlayerFields.RestInfo + rest_state_offset, (uint)PlayerRestState.RAFLinked);
|
||||
_player.SetRestState(restType, PlayerRestState.RAFLinked);
|
||||
else
|
||||
{
|
||||
if (_restBonus[(int)restType] > 10)
|
||||
_player.SetUInt32Value(ActivePlayerFields.RestInfo + rest_state_offset, (uint)PlayerRestState.Rested);
|
||||
_player.SetRestState(restType, PlayerRestState.Rested);
|
||||
else if (_restBonus[(int)restType] <= 1)
|
||||
_player.SetUInt32Value(ActivePlayerFields.RestInfo + rest_state_offset, (uint)PlayerRestState.NotRAFLinked);
|
||||
_player.SetRestState(restType, PlayerRestState.NotRAFLinked);
|
||||
}
|
||||
|
||||
// RestTickUpdate
|
||||
_player.SetUInt32Value(ActivePlayerFields.RestInfo + rest_rested_offset, (uint)_restBonus[(int)restType]);
|
||||
_player.SetRestThreshold(restType, (uint)_restBonus[(int)restType]);
|
||||
}
|
||||
|
||||
public void AddRestBonus(RestTypes restType, float restBonus)
|
||||
@@ -84,7 +82,7 @@ namespace Game.Entities
|
||||
if (oldRestMask == 0 && _restFlagMask != 0) // only set flag/time on the first rest state
|
||||
{
|
||||
_restTime = Time.UnixTime;
|
||||
_player.SetFlag(PlayerFields.Flags, PlayerFlags.Resting);
|
||||
_player.AddPlayerFlag(PlayerFlags.Resting);
|
||||
}
|
||||
|
||||
if (triggerId != 0)
|
||||
@@ -99,7 +97,7 @@ namespace Game.Entities
|
||||
if (oldRestMask != 0 && _restFlagMask == 0) // only remove flag/time on the last rest state remove
|
||||
{
|
||||
_restTime = 0;
|
||||
_player.RemoveFlag(PlayerFields.Flags, PlayerFlags.Resting);
|
||||
_player.RemovePlayerFlag(PlayerFlags.Resting);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -135,8 +133,8 @@ namespace Game.Entities
|
||||
public void LoadRestBonus(RestTypes restType, PlayerRestState state, float restBonus)
|
||||
{
|
||||
_restBonus[(int)restType] = restBonus;
|
||||
_player.SetUInt32Value(ActivePlayerFields.RestInfo + (int)restType * 2, (uint)state);
|
||||
_player.SetUInt32Value(ActivePlayerFields.RestInfo + (int)restType * 2 + 1, (uint)restBonus);
|
||||
_player.SetRestState(restType, state);
|
||||
_player.SetRestThreshold(restType, (uint)restBonus);
|
||||
}
|
||||
|
||||
public float CalcExtraPerSec(RestTypes restType, float bubble)
|
||||
@@ -144,9 +142,9 @@ namespace Game.Entities
|
||||
switch (restType)
|
||||
{
|
||||
case RestTypes.Honor:
|
||||
return (_player.GetUInt32Value(ActivePlayerFields.HonorNextLevel)) / 72000.0f * bubble;
|
||||
return _player.m_activePlayerData.HonorNextLevel / 72000.0f * bubble;
|
||||
case RestTypes.XP:
|
||||
return (_player.GetUInt32Value(ActivePlayerFields.NextLevelXp)) / 72000.0f * bubble;
|
||||
return _player.m_activePlayerData.NextLevelXP / 72000.0f * bubble;
|
||||
default:
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
+159
-162
@@ -183,12 +183,18 @@ namespace Game.Entities
|
||||
|
||||
public void ApplyStatBuffMod(Stats stat, float val, bool apply)
|
||||
{
|
||||
ApplyModSignedFloatValue((val > 0 ? UnitFields.PosStat + (int)stat : UnitFields.NegStat + (int)stat), val, apply);
|
||||
MathFunctions.ApplyPercentModFloatVar(ref (val > 0 ? ref m_floatStatPosBuff[(int)stat] : ref m_floatStatNegBuff[(int)stat]), val, apply);
|
||||
UpdateStatBuffModForClient(stat);
|
||||
}
|
||||
public void ApplyStatPercentBuffMod(Stats stat, float val, bool apply)
|
||||
{
|
||||
ApplyPercentModFloatValue(UnitFields.PosStat + (int)stat, val, apply);
|
||||
ApplyPercentModFloatValue(UnitFields.NegStat + (int)stat, val, apply);
|
||||
MathFunctions.ApplyPercentModFloatVar(ref m_floatStatPosBuff[(int)stat], val, apply);
|
||||
MathFunctions.ApplyPercentModFloatVar(ref m_floatStatNegBuff[(int)stat], val, apply);
|
||||
}
|
||||
void UpdateStatBuffModForClient(Stats stat)
|
||||
{
|
||||
SetUpdateFieldValue(ref m_values.ModifyValue(m_unitData).ModifyValue(m_unitData.StatPosBuff, (int)stat), (int)m_floatStatPosBuff[(int)stat]);
|
||||
SetUpdateFieldValue(ref m_values.ModifyValue(m_unitData).ModifyValue(m_unitData.StatNegBuff, (int)stat), (int)m_floatStatNegBuff[(int)stat]);
|
||||
}
|
||||
|
||||
public virtual bool UpdateStats(Stats stat) { return false; }
|
||||
@@ -219,16 +225,16 @@ namespace Game.Entities
|
||||
{
|
||||
case WeaponAttackType.BaseAttack:
|
||||
default:
|
||||
SetStatFloatValue(UnitFields.MinDamage, minDamage);
|
||||
SetStatFloatValue(UnitFields.MaxDamage, maxDamage);
|
||||
SetUpdateFieldStatValue(m_values.ModifyValue(m_unitData).ModifyValue(m_unitData.MinDamage), minDamage);
|
||||
SetUpdateFieldStatValue(m_values.ModifyValue(m_unitData).ModifyValue(m_unitData.MaxDamage), maxDamage);
|
||||
break;
|
||||
case WeaponAttackType.OffAttack:
|
||||
SetStatFloatValue(UnitFields.MinOffHandDamage, minDamage);
|
||||
SetStatFloatValue(UnitFields.MaxOffHandDamage, maxDamage);
|
||||
SetUpdateFieldStatValue(m_values.ModifyValue(m_unitData).ModifyValue(m_unitData.MinOffHandDamage), minDamage);
|
||||
SetUpdateFieldStatValue(m_values.ModifyValue(m_unitData).ModifyValue(m_unitData.MaxOffHandDamage), maxDamage);
|
||||
break;
|
||||
case WeaponAttackType.RangedAttack:
|
||||
SetStatFloatValue(UnitFields.MinRangedDamage, minDamage);
|
||||
SetStatFloatValue(UnitFields.MaxRangedDamage, maxDamage);
|
||||
SetUpdateFieldStatValue(m_values.ModifyValue(m_unitData).ModifyValue(m_unitData.MinRangedDamage), minDamage);
|
||||
SetUpdateFieldStatValue(m_values.ModifyValue(m_unitData).ModifyValue(m_unitData.MaxRangedDamage), maxDamage);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -245,26 +251,10 @@ namespace Game.Entities
|
||||
}
|
||||
|
||||
//Stats
|
||||
public float GetStat(Stats stat)
|
||||
{
|
||||
return GetUInt32Value(UnitFields.Stat + (int)stat);
|
||||
}
|
||||
public void SetCreateStat(Stats stat, float val)
|
||||
{
|
||||
CreateStats[(int)stat] = val;
|
||||
}
|
||||
public void SetStat(Stats stat, int val)
|
||||
{
|
||||
SetStatInt32Value(UnitFields.Stat + (int)stat, val);
|
||||
}
|
||||
public void SetCreateMana(uint val)
|
||||
{
|
||||
SetUInt32Value(UnitFields.BaseMana, val);
|
||||
}
|
||||
public uint GetCreateMana()
|
||||
{
|
||||
return GetUInt32Value(UnitFields.BaseMana);
|
||||
}
|
||||
public float GetStat(Stats stat) { return m_unitData.Stats[(int)stat]; }
|
||||
public void SetStat(Stats stat, int val) { SetUpdateFieldValue(ref m_values.ModifyValue(m_unitData).ModifyValue(m_unitData.Stats, (int)stat), val); }
|
||||
public uint GetCreateMana() { return m_unitData.BaseMana; }
|
||||
public void SetCreateMana(uint val) { SetUpdateFieldValue(m_values.ModifyValue(m_unitData).ModifyValue(m_unitData.BaseMana), val); }
|
||||
public uint GetArmor()
|
||||
{
|
||||
return (uint)(GetResistance(SpellSchools.Normal) + GetBonusResistanceMod(SpellSchools.Normal));
|
||||
@@ -274,13 +264,23 @@ namespace Game.Entities
|
||||
SetResistance(SpellSchools.Normal, val);
|
||||
SetBonusResistanceMod(SpellSchools.Normal, bonusVal);
|
||||
}
|
||||
public float GetCreateStat(Stats stat)
|
||||
{
|
||||
return CreateStats[(int)stat];
|
||||
}
|
||||
public void SetCreateStat(Stats stat, float val)
|
||||
{
|
||||
CreateStats[(int)stat] = val;
|
||||
}
|
||||
public float GetPosStat(Stats stat) { return m_unitData.StatPosBuff[(int)stat]; }
|
||||
public float GetNegStat(Stats stat) { return m_unitData.StatNegBuff[(int)stat]; }
|
||||
public int GetResistance(SpellSchools school)
|
||||
{
|
||||
return GetInt32Value(UnitFields.Resistances + (int)school);
|
||||
return m_unitData.Resistances[(int)school];
|
||||
}
|
||||
public int GetBonusResistanceMod(SpellSchools school)
|
||||
{
|
||||
return GetInt32Value(UnitFields.BonusResistanceMods + (int)school);
|
||||
return m_unitData.BonusResistanceMods[(int)school];
|
||||
}
|
||||
public int GetResistance(SpellSchoolMask mask)
|
||||
{
|
||||
@@ -295,25 +295,22 @@ namespace Game.Entities
|
||||
// resist value will never be negative here
|
||||
return resist.HasValue ? resist.Value : 0;
|
||||
}
|
||||
public void SetResistance(SpellSchools school, int val)
|
||||
{
|
||||
SetStatInt32Value(UnitFields.Resistances + (int)school, val);
|
||||
}
|
||||
public void SetBonusResistanceMod(SpellSchools school, int val)
|
||||
{
|
||||
SetStatInt32Value(UnitFields.BonusResistanceMods + (int)school, val);
|
||||
}
|
||||
public void SetResistance(SpellSchools school, int val) { SetUpdateFieldValue(ref m_values.ModifyValue(m_unitData).ModifyValue(m_unitData.Resistances, (int)school), val); }
|
||||
public void SetBonusResistanceMod(SpellSchools school, int val) { SetUpdateFieldValue(ref m_values.ModifyValue(m_unitData).ModifyValue(m_unitData.BonusResistanceMods, (int)school), val); }
|
||||
public void SetModCastingSpeed(float castingSpeed) { SetUpdateFieldValue(m_values.ModifyValue(m_unitData).ModifyValue(m_unitData.ModCastingSpeed), castingSpeed); }
|
||||
public void SetModSpellHaste(float spellHaste) { SetUpdateFieldValue(m_values.ModifyValue(m_unitData).ModifyValue(m_unitData.ModSpellHaste), spellHaste); }
|
||||
public void SetModHaste(float haste) { SetUpdateFieldValue(m_values.ModifyValue(m_unitData).ModifyValue(m_unitData.ModHaste), haste); }
|
||||
public void SetModRangedHaste(float rangedHaste) { SetUpdateFieldValue(m_values.ModifyValue(m_unitData).ModifyValue(m_unitData.ModRangedHaste), rangedHaste); }
|
||||
public void SetModHasteRegen(float hasteRegen) { SetUpdateFieldValue(m_values.ModifyValue(m_unitData).ModifyValue(m_unitData.ModHasteRegen), hasteRegen); }
|
||||
public void SetModTimeRate(float timeRate) { SetUpdateFieldValue(m_values.ModifyValue(m_unitData).ModifyValue(m_unitData.ModTimeRate), timeRate); }
|
||||
|
||||
public float GetCreateStat(Stats stat)
|
||||
{
|
||||
return CreateStats[(int)stat];
|
||||
}
|
||||
public void InitStatBuffMods()
|
||||
{
|
||||
for (var i = Stats.Strength; i < Stats.Max; ++i)
|
||||
for (var stat = Stats.Strength; stat < Stats.Max; ++stat)
|
||||
{
|
||||
SetFloatValue(UnitFields.PosStat + (int)i, 0);
|
||||
SetFloatValue(UnitFields.NegStat + (int)i, 0);
|
||||
m_floatStatPosBuff[(int)stat] = 0.0f;
|
||||
m_floatStatNegBuff[(int)stat] = 0.0f;
|
||||
UpdateStatBuffModForClient(stat);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -341,16 +338,10 @@ namespace Game.Entities
|
||||
return value;
|
||||
}
|
||||
|
||||
//Health
|
||||
public uint GetCreateHealth() { return GetUInt32Value(UnitFields.BaseHealth); }
|
||||
public ulong GetHealth() { return GetUInt64Value(UnitFields.Health); }
|
||||
public ulong GetMaxHealth() { return GetUInt64Value(UnitFields.MaxHealth); }
|
||||
public float GetHealthPct() { return GetMaxHealth() != 0 ? 100.0f * GetHealth() / GetMaxHealth() : 0.0f; }
|
||||
|
||||
public void SetCreateHealth(uint val)
|
||||
{
|
||||
SetUInt32Value(UnitFields.BaseHealth, val);
|
||||
}
|
||||
//Health
|
||||
public uint GetCreateHealth() { return m_unitData.BaseHealth; }
|
||||
public void SetCreateHealth(uint val) { SetUpdateFieldValue(m_values.ModifyValue(m_unitData).ModifyValue(m_unitData.BaseHealth), val); }
|
||||
public ulong GetHealth() { return m_unitData.Health; }
|
||||
public void SetHealth(ulong val)
|
||||
{
|
||||
if (getDeathState() == DeathState.JustDied)
|
||||
@@ -364,7 +355,7 @@ namespace Game.Entities
|
||||
val = maxHealth;
|
||||
}
|
||||
|
||||
SetUInt64Value(UnitFields.Health, val);
|
||||
SetUpdateFieldValue(m_values.ModifyValue(m_unitData).ModifyValue(m_unitData.Health), val);
|
||||
|
||||
// group update
|
||||
Player player = ToPlayer();
|
||||
@@ -380,13 +371,14 @@ namespace Game.Entities
|
||||
pet.SetGroupUpdateFlag(GroupUpdatePetFlags.CurHp);
|
||||
}
|
||||
}
|
||||
public ulong GetMaxHealth() { return m_unitData.MaxHealth; }
|
||||
public void SetMaxHealth(ulong val)
|
||||
{
|
||||
if (val == 0)
|
||||
val = 1;
|
||||
|
||||
ulong health = GetHealth();
|
||||
SetUInt64Value(UnitFields.MaxHealth, val);
|
||||
SetUpdateFieldValue(m_values.ModifyValue(m_unitData).ModifyValue(m_unitData.MaxHealth), val);
|
||||
|
||||
// group update
|
||||
if (IsTypeId(TypeId.Player))
|
||||
@@ -404,6 +396,7 @@ namespace Game.Entities
|
||||
if (val < health)
|
||||
SetHealth(val);
|
||||
}
|
||||
public float GetHealthPct() { return GetMaxHealth() != 0 ? 100.0f * GetHealth() / GetMaxHealth() : 0.0f; }
|
||||
public void SetFullHealth() { SetHealth(GetMaxHealth()); }
|
||||
|
||||
public bool IsFullHealth() { return GetHealth() == GetMaxHealth(); }
|
||||
@@ -419,21 +412,19 @@ namespace Game.Entities
|
||||
public virtual float GetArmorMultiplierForTarget(WorldObject target) { return 1.0f; }
|
||||
|
||||
//Powers
|
||||
public PowerType GetPowerType()
|
||||
{
|
||||
return (PowerType)GetUInt32Value(UnitFields.DisplayPower);
|
||||
}
|
||||
public PowerType GetPowerType() { return (PowerType)(byte)m_unitData.DisplayPower; }
|
||||
public void SetPowerType(PowerType powerType)
|
||||
{
|
||||
if (GetPowerType() == powerType)
|
||||
return;
|
||||
|
||||
SetUInt32Value(UnitFields.DisplayPower, (uint)powerType);
|
||||
SetUpdateFieldValue(m_values.ModifyValue(m_unitData).ModifyValue(m_unitData.DisplayPower), (byte)powerType);
|
||||
|
||||
if (IsTypeId(TypeId.Player))
|
||||
Player thisPlayer = ToPlayer();
|
||||
if (thisPlayer != null)
|
||||
{
|
||||
if (ToPlayer().GetGroup())
|
||||
ToPlayer().SetGroupUpdateFlag(GroupUpdateFlags.PowerType);
|
||||
if (thisPlayer.GetGroup())
|
||||
thisPlayer.SetGroupUpdateFlag(GroupUpdateFlags.PowerType);
|
||||
}
|
||||
/*else if (IsPet()) TODO 6.x
|
||||
{
|
||||
@@ -461,6 +452,8 @@ namespace Game.Entities
|
||||
break;
|
||||
}
|
||||
}
|
||||
public void SetOverrideDisplayPowerId(uint powerDisplayId) { SetUpdateFieldValue(m_values.ModifyValue(m_unitData).ModifyValue(m_unitData.OverrideDisplayPowerID), powerDisplayId); }
|
||||
|
||||
public void SetMaxPower(PowerType powerType, int val)
|
||||
{
|
||||
uint powerIndex = GetPowerIndex(powerType);
|
||||
@@ -468,7 +461,7 @@ namespace Game.Entities
|
||||
return;
|
||||
|
||||
int cur_power = GetPower(powerType);
|
||||
SetInt32Value(UnitFields.MaxPower + (int)powerIndex, val);
|
||||
SetUpdateFieldValue(ref m_values.ModifyValue(m_unitData).ModifyValue(m_unitData.MaxPower, (int)powerIndex), (uint)val);
|
||||
|
||||
// group update
|
||||
if (IsTypeId(TypeId.Player))
|
||||
@@ -496,7 +489,7 @@ namespace Game.Entities
|
||||
if (maxPower < val)
|
||||
val = maxPower;
|
||||
|
||||
SetInt32Value(UnitFields.Power + (int)powerIndex, val);
|
||||
SetUpdateFieldValue(ref m_values.ModifyValue(m_unitData).ModifyValue(m_unitData.Power, (int)powerIndex), val);
|
||||
|
||||
if (IsInWorld)
|
||||
{
|
||||
@@ -527,7 +520,7 @@ namespace Game.Entities
|
||||
if (powerIndex == (int)PowerType.Max || powerIndex >= (int)PowerType.MaxPerClass)
|
||||
return 0;
|
||||
|
||||
return GetInt32Value(UnitFields.Power + (int)powerIndex);
|
||||
return m_unitData.Power[(int)powerIndex];
|
||||
}
|
||||
public int GetMaxPower(PowerType powerType)
|
||||
{
|
||||
@@ -535,7 +528,7 @@ namespace Game.Entities
|
||||
if (powerIndex == (int)PowerType.Max || powerIndex >= (int)PowerType.MaxPerClass)
|
||||
return 0;
|
||||
|
||||
return GetInt32Value(UnitFields.MaxPower + (int)powerIndex);
|
||||
return (int)(uint)m_unitData.MaxPower[(int)powerIndex];
|
||||
}
|
||||
public int GetCreatePowers(PowerType powerType)
|
||||
{
|
||||
@@ -597,6 +590,15 @@ namespace Game.Entities
|
||||
return MathFunctions.CalculatePct(damage, percent);
|
||||
}
|
||||
|
||||
public void SetAttackPower(int attackPower) { SetUpdateFieldValue(m_values.ModifyValue(m_unitData).ModifyValue(m_unitData.AttackPower), attackPower); }
|
||||
public void SetAttackPowerModPos(int attackPowerMod) { SetUpdateFieldValue(m_values.ModifyValue(m_unitData).ModifyValue(m_unitData.AttackPowerModPos), attackPowerMod); }
|
||||
public void SetAttackPowerModNeg(int attackPowerMod) { SetUpdateFieldValue(m_values.ModifyValue(m_unitData).ModifyValue(m_unitData.AttackPowerModNeg), attackPowerMod); }
|
||||
public void SetAttackPowerMultiplier(float attackPowerMult) { SetUpdateFieldValue(m_values.ModifyValue(m_unitData).ModifyValue(m_unitData.AttackPowerMultiplier), attackPowerMult); }
|
||||
public void SetRangedAttackPower(int attackPower) { SetUpdateFieldValue(m_values.ModifyValue(m_unitData).ModifyValue(m_unitData.RangedAttackPower), attackPower); }
|
||||
public void SetRangedAttackPowerModPos(int attackPowerMod) { SetUpdateFieldValue(m_values.ModifyValue(m_unitData).ModifyValue(m_unitData.RangedAttackPowerModPos), attackPowerMod); }
|
||||
public void SetRangedAttackPowerModNeg(int attackPowerMod) { SetUpdateFieldValue(m_values.ModifyValue(m_unitData).ModifyValue(m_unitData.RangedAttackPowerModNeg), attackPowerMod); }
|
||||
public void SetRangedAttackPowerMultiplier(float attackPowerMult) { SetUpdateFieldValue(m_values.ModifyValue(m_unitData).ModifyValue(m_unitData.RangedAttackPowerMultiplier), attackPowerMult); }
|
||||
|
||||
//Chances
|
||||
float MeleeSpellMissChance(Unit victim, WeaponAttackType attType, uint spellId)
|
||||
{
|
||||
@@ -635,18 +637,19 @@ namespace Game.Entities
|
||||
float GetUnitCriticalChance(WeaponAttackType attackType, Unit victim)
|
||||
{
|
||||
float chance = 0.0f;
|
||||
if (IsTypeId(TypeId.Player))
|
||||
Player thisPlayer = ToPlayer();
|
||||
if (thisPlayer != null)
|
||||
{
|
||||
switch (attackType)
|
||||
{
|
||||
case WeaponAttackType.BaseAttack:
|
||||
chance = GetFloatValue(ActivePlayerFields.CritPercentage);
|
||||
chance = thisPlayer.m_activePlayerData.CritPercentage;
|
||||
break;
|
||||
case WeaponAttackType.OffAttack:
|
||||
chance = GetFloatValue(ActivePlayerFields.OffhandCritPercentage);
|
||||
chance = thisPlayer.m_activePlayerData.OffhandCritPercentage;
|
||||
break;
|
||||
case WeaponAttackType.RangedAttack:
|
||||
chance = GetFloatValue(ActivePlayerFields.RangedCritPercentage);
|
||||
chance = thisPlayer.m_activePlayerData.RangedCritPercentage;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -684,8 +687,9 @@ namespace Game.Entities
|
||||
|
||||
float chance = 0.0f;
|
||||
float levelBonus = 0.0f;
|
||||
if (victim.IsTypeId(TypeId.Player))
|
||||
chance = victim.GetFloatValue(ActivePlayerFields.DodgePercentage);
|
||||
Player playerVictim = victim.ToPlayer();
|
||||
if (playerVictim)
|
||||
chance = playerVictim.m_activePlayerData.DodgePercentage;
|
||||
else
|
||||
{
|
||||
if (!victim.IsTotem())
|
||||
@@ -729,7 +733,7 @@ namespace Game.Entities
|
||||
tmpitem = playerVictim.GetWeaponForAttack(WeaponAttackType.OffAttack, true);
|
||||
|
||||
if (tmpitem)
|
||||
chance = playerVictim.GetFloatValue(ActivePlayerFields.ParryPercentage);
|
||||
chance = playerVictim.m_activePlayerData.ParryPercentage;
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -777,7 +781,7 @@ namespace Game.Entities
|
||||
{
|
||||
Item tmpitem = playerVictim.GetUseableItemByPos(InventorySlots.Bag0, EquipmentSlot.OffHand);
|
||||
if (tmpitem && !tmpitem.IsBroken() && tmpitem.GetTemplate().GetInventoryType() == InventoryType.Shield)
|
||||
chance = playerVictim.GetFloatValue(ActivePlayerFields.BlockPercentage);
|
||||
chance = playerVictim.m_activePlayerData.BlockPercentage;
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -796,7 +800,7 @@ namespace Game.Entities
|
||||
return Math.Max(chance, 0.0f);
|
||||
}
|
||||
|
||||
int GetMechanicResistChance(SpellInfo spellInfo)
|
||||
public int GetMechanicResistChance(SpellInfo spellInfo)
|
||||
{
|
||||
if (spellInfo == null)
|
||||
return 0;
|
||||
@@ -817,6 +821,9 @@ namespace Game.Entities
|
||||
}
|
||||
return Math.Max(resistMech, 0);
|
||||
}
|
||||
|
||||
public void ApplyModPowerCostModifier(SpellSchools school, int mod, bool apply) { ApplyModUpdateFieldValue(ref m_values.ModifyValue(m_unitData).ModifyValue(m_unitData.PowerCostModifier, (int)school), mod, apply); }
|
||||
public void ApplyModPowerCostMultiplier(SpellSchools school, float pct, bool apply) { ApplyModUpdateFieldValue(ref m_values.ModifyValue(m_unitData).ModifyValue(m_unitData.PowerCostMultiplier, (int)school), pct, apply); }
|
||||
}
|
||||
|
||||
public partial class Player
|
||||
@@ -925,7 +932,14 @@ namespace Game.Entities
|
||||
UpdateArmor();
|
||||
}
|
||||
|
||||
void RecalculateRating(CombatRating cr) { ApplyRatingMod(cr, 0, true); }
|
||||
public void ApplyModTargetResistance(int mod, bool apply) { ApplyModUpdateFieldValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.ModTargetResistance), mod, apply); }
|
||||
public void ApplyModTargetPhysicalResistance(int mod, bool apply) { ApplyModUpdateFieldValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.ModTargetPhysicalResistance), mod, apply); }
|
||||
|
||||
public void RecalculateRating(CombatRating cr) { ApplyRatingMod(cr, 0, true); }
|
||||
|
||||
public void ApplyModDamageDonePos(SpellSchools school, int mod, bool apply) { ApplyModUpdateFieldValue(ref m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.ModDamageDonePos, (int)school), mod, apply); }
|
||||
public void ApplyModDamageDoneNeg(SpellSchools school, int mod, bool apply) { ApplyModUpdateFieldValue(ref m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.ModDamageDoneNeg, (int)school), mod, apply); }
|
||||
public void ApplyModDamageDonePercent(SpellSchools school, float pct, bool apply) { ApplyPercentModUpdateFieldValue(ref m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.ModDamageDonePercent, (int)school), pct, apply); }
|
||||
|
||||
public void ApplyRatingMod(CombatRating combatRating, int value, bool apply)
|
||||
{
|
||||
@@ -989,7 +1003,7 @@ namespace Game.Entities
|
||||
max_damage = ((baseValue + weaponMaxDamage) * basePct + totalValue) * totalPct * versaDmgMod;
|
||||
}
|
||||
|
||||
void UpdateAllCritPercentages()
|
||||
public void UpdateAllCritPercentages()
|
||||
{
|
||||
float value = 5.0f;
|
||||
|
||||
@@ -1004,7 +1018,7 @@ namespace Game.Entities
|
||||
|
||||
public void UpdateManaRegen()
|
||||
{
|
||||
int manaIndex = (int)GetPowerIndex(PowerType.Mana);
|
||||
uint manaIndex = GetPowerIndex(PowerType.Mana);
|
||||
if (manaIndex == (int)PowerType.Max)
|
||||
return;
|
||||
|
||||
@@ -1021,8 +1035,8 @@ namespace Game.Entities
|
||||
// Apply PCT bonus from SPELL_AURA_MOD_MANA_REGEN_PCT
|
||||
base_regen *= GetTotalAuraMultiplierByMiscValue(AuraType.ModManaRegenPct, (int)PowerType.Mana);
|
||||
|
||||
SetFloatValue(UnitFields.PowerRegenInterruptedFlatModifier + manaIndex, base_regen);
|
||||
SetFloatValue(UnitFields.PowerRegenFlatModifier + manaIndex, base_regen);
|
||||
SetUpdateFieldValue(ref m_values.ModifyValue(m_unitData).ModifyValue(m_unitData.PowerRegenFlatModifier, (int)manaIndex), base_regen);
|
||||
SetUpdateFieldValue(ref m_values.ModifyValue(m_unitData).ModifyValue(m_unitData.PowerRegenInterruptedFlatModifier, (int)manaIndex), base_regen);
|
||||
}
|
||||
|
||||
public void UpdateSpellDamageAndHealingBonus()
|
||||
@@ -1030,18 +1044,19 @@ namespace Game.Entities
|
||||
// Magic damage modifiers implemented in Unit.SpellDamageBonusDone
|
||||
// This information for client side use only
|
||||
// Get healing bonus for all schools
|
||||
SetStatInt32Value(ActivePlayerFields.ModHealingDonePos, (int)SpellBaseHealingBonusDone(SpellSchoolMask.All));
|
||||
SetUpdateFieldStatValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.ModHealingDonePos), (int)SpellBaseHealingBonusDone(SpellSchoolMask.All));
|
||||
// Get damage bonus for all schools
|
||||
var modDamageAuras = GetAuraEffectsByType(AuraType.ModDamageDone);
|
||||
for (var i = SpellSchools.Holy; i < SpellSchools.Max; ++i)
|
||||
for (int i = (int)SpellSchools.Holy; i < (int)SpellSchools.Max; ++i)
|
||||
{
|
||||
SetInt32Value(ActivePlayerFields.ModDamageDoneNeg + (int)i, modDamageAuras.Aggregate(0, (negativeMod, aurEff) =>
|
||||
SetUpdateFieldValue(ref m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.ModDamageDoneNeg, i), modDamageAuras.Aggregate(0, (negativeMod, aurEff) =>
|
||||
{
|
||||
if (aurEff.GetAmount() < 0 && Convert.ToBoolean(aurEff.GetMiscValue() & (1 << (int)i)))
|
||||
if (aurEff.GetAmount() < 0 && Convert.ToBoolean(aurEff.GetMiscValue() & (1 << i)))
|
||||
negativeMod += aurEff.GetAmount();
|
||||
return negativeMod;
|
||||
}));
|
||||
SetStatInt32Value(ActivePlayerFields.ModDamageDonePos + (int)i, SpellBaseDamageBonusDone((SpellSchoolMask)(1 << (int)i)) - GetInt32Value(ActivePlayerFields.ModDamageDoneNeg + (int)i));
|
||||
SetUpdateFieldStatValue(ref m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.ModDamageDonePos, i),
|
||||
(SpellBaseDamageBonusDone((SpellSchoolMask)(1 << i)) - m_activePlayerData.ModDamageDoneNeg[i]));
|
||||
}
|
||||
|
||||
if (HasAuraType(AuraType.OverrideAttackPowerBySpPct))
|
||||
@@ -1060,17 +1075,6 @@ namespace Game.Entities
|
||||
var entry = CliDB.ChrClassesStorage.LookupByKey(GetClass());
|
||||
UnitMods unitMod = ranged ? UnitMods.AttackPowerRanged : UnitMods.AttackPower;
|
||||
|
||||
UnitFields index = UnitFields.AttackPower;
|
||||
UnitFields index_mod = UnitFields.AttackPowerModPos;
|
||||
UnitFields index_mult = UnitFields.AttackPowerMultiplier;
|
||||
|
||||
if (ranged)
|
||||
{
|
||||
index = UnitFields.RangedAttackPower;
|
||||
index_mod = UnitFields.RangedAttackPowerModPos;
|
||||
index_mult = UnitFields.RangedAttackPowerMultiplier;
|
||||
}
|
||||
|
||||
if (!HasAuraType(AuraType.OverrideAttackPowerBySpPct))
|
||||
{
|
||||
if (!ranged)
|
||||
@@ -1090,11 +1094,11 @@ namespace Game.Entities
|
||||
}
|
||||
else
|
||||
{
|
||||
int minSpellPower = GetInt32Value(ActivePlayerFields.ModHealingDonePos);
|
||||
int minSpellPower = m_activePlayerData.ModHealingDonePos;
|
||||
for (var i = SpellSchools.Holy; i < SpellSchools.Max; ++i)
|
||||
minSpellPower = Math.Min(minSpellPower, GetInt32Value(ActivePlayerFields.ModDamageDonePos + (int)i));
|
||||
minSpellPower = Math.Min(minSpellPower, m_activePlayerData.ModDamageDonePos[(int)i]);
|
||||
|
||||
val2 = MathFunctions.CalculatePct(minSpellPower, GetFloatValue(ActivePlayerFields.OverrideApBySpellPowerPercent));
|
||||
val2 = MathFunctions.CalculatePct(minSpellPower, m_activePlayerData.OverrideAPBySpellPowerPercent);
|
||||
}
|
||||
|
||||
SetModifierValue(unitMod, UnitModifierType.BaseValue, val2);
|
||||
@@ -1112,9 +1116,18 @@ namespace Game.Entities
|
||||
attPowerMod += (int)(GetArmor() / iter.GetAmount());
|
||||
}
|
||||
|
||||
SetUInt32Value(index, (uint)base_attPower); //UNIT_FIELD_(RANGED)_ATTACK_POWER field
|
||||
SetUInt32Value(index_mod, (uint)attPowerMod); //UNIT_FIELD_(RANGED)_ATTACK_POWER_MOD_POS field
|
||||
SetFloatValue(index_mult, attPowerMultiplier); //UNIT_FIELD_(RANGED)_ATTACK_POWER_MULTIPLIER field
|
||||
if (ranged)
|
||||
{
|
||||
SetRangedAttackPower((int)base_attPower);
|
||||
SetRangedAttackPowerModPos((int)attPowerMod);
|
||||
SetRangedAttackPowerMultiplier(attPowerMultiplier);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetAttackPower((int)base_attPower);
|
||||
SetAttackPowerModPos((int)attPowerMod);
|
||||
SetAttackPowerMultiplier(attPowerMultiplier);
|
||||
}
|
||||
|
||||
Pet pet = GetPet(); //update pet's AP
|
||||
Guardian guardian = GetGuardianPet();
|
||||
@@ -1220,8 +1233,8 @@ namespace Game.Entities
|
||||
if (amount < 0)
|
||||
amount = 0;
|
||||
|
||||
uint oldRating = GetUInt32Value(ActivePlayerFields.CombatRating + (int)cr);
|
||||
SetUInt32Value(ActivePlayerFields.CombatRating + (int)cr, (uint)amount);
|
||||
uint oldRating = m_activePlayerData.CombatRatings[(int)cr];
|
||||
SetUpdateFieldValue(ref m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.CombatRatings, (int)cr), (uint)amount);
|
||||
|
||||
bool affectStats = CanModifyStats();
|
||||
|
||||
@@ -1320,15 +1333,15 @@ namespace Game.Entities
|
||||
{
|
||||
if (!CanUseMastery())
|
||||
{
|
||||
SetFloatValue(ActivePlayerFields.Mastery, 0.0f);
|
||||
SetUpdateFieldValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.Mastery), 0.0f);
|
||||
return;
|
||||
}
|
||||
|
||||
float value = GetTotalAuraModifier(AuraType.Mastery);
|
||||
value += GetRatingBonusValue(CombatRating.Mastery);
|
||||
SetFloatValue(ActivePlayerFields.Mastery, value);
|
||||
SetUpdateFieldValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.Mastery), value);
|
||||
|
||||
ChrSpecializationRecord chrSpec = CliDB.ChrSpecializationStorage.LookupByKey(GetUInt32Value(PlayerFields.CurrentSpecId));
|
||||
ChrSpecializationRecord chrSpec = CliDB.ChrSpecializationStorage.LookupByKey(GetPrimarySpecialization());
|
||||
if (chrSpec == null)
|
||||
return;
|
||||
|
||||
@@ -1354,8 +1367,8 @@ namespace Game.Entities
|
||||
|
||||
public void UpdateVersatilityDamageDone()
|
||||
{
|
||||
// No proof that CR_VERSATILITY_DAMAGE_DONE is allways = PLAYER_VERSATILITY
|
||||
SetUInt32Value(ActivePlayerFields.Versatility, GetUInt32Value(ActivePlayerFields.CombatRating + (int)CombatRating.VersatilityDamageDone));
|
||||
// No proof that CR_VERSATILITY_DAMAGE_DONE is allways = ActivePlayerData::Versatility
|
||||
SetUpdateFieldValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.Versatility), (int)m_activePlayerData.CombatRatings[(int)CombatRating.VersatilityDamageDone]);
|
||||
|
||||
if (GetClass() == Class.Hunter)
|
||||
UpdateDamagePhysical(WeaponAttackType.RangedAttack);
|
||||
@@ -1372,13 +1385,13 @@ namespace Game.Entities
|
||||
foreach (AuraEffect auraEffect in GetAuraEffectsByType(AuraType.ModHealingDonePercent))
|
||||
MathFunctions.AddPct(ref value, auraEffect.GetAmount());
|
||||
|
||||
SetStatFloatValue(ActivePlayerFields.ModHealingDonePct, value);
|
||||
SetUpdateFieldStatValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.ModHealingDonePercent), value);
|
||||
}
|
||||
|
||||
void UpdateArmorPenetration(int amount)
|
||||
{
|
||||
// Store Rating Value
|
||||
SetInt32Value(ActivePlayerFields.CombatRating + (int)CombatRating.ArmorPenetration, amount);
|
||||
SetUpdateFieldValue(ref m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.CombatRatings, (int)CombatRating.ArmorPenetration), (uint)amount);
|
||||
}
|
||||
public void UpdateParryPercentage()
|
||||
{
|
||||
@@ -1413,10 +1426,8 @@ namespace Game.Entities
|
||||
|
||||
if (WorldConfig.GetBoolValue(WorldCfg.StatsLimitsEnable))
|
||||
value = value > WorldConfig.GetFloatValue(WorldCfg.StatsLimitsParry) ? WorldConfig.GetFloatValue(WorldCfg.StatsLimitsParry) : value;
|
||||
|
||||
value = value < 0.0f ? 0.0f : value;
|
||||
}
|
||||
SetFloatValue(ActivePlayerFields.ParryPercentage, value);
|
||||
SetUpdateFieldStatValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.ParryPercentage), value);
|
||||
}
|
||||
|
||||
public void UpdateDodgePercentage()
|
||||
@@ -1450,8 +1461,7 @@ namespace Game.Entities
|
||||
if (WorldConfig.GetBoolValue(WorldCfg.StatsLimitsEnable))
|
||||
value = value > WorldConfig.GetFloatValue(WorldCfg.StatsLimitsDodge) ? WorldConfig.GetFloatValue(WorldCfg.StatsLimitsDodge) : value;
|
||||
|
||||
value = value < 0.0f ? 0.0f : value;
|
||||
SetStatFloatValue(ActivePlayerFields.DodgePercentage, value);
|
||||
SetUpdateFieldStatValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.DodgePercentage), value);
|
||||
}
|
||||
public void UpdateBlockPercentage()
|
||||
{
|
||||
@@ -1468,47 +1478,35 @@ namespace Game.Entities
|
||||
|
||||
if (WorldConfig.GetBoolValue(WorldCfg.StatsLimitsEnable))
|
||||
value = value > WorldConfig.GetFloatValue(WorldCfg.StatsLimitsBlock) ? WorldConfig.GetFloatValue(WorldCfg.StatsLimitsBlock) : value;
|
||||
|
||||
value = value < 0.0f ? 0.0f : value;
|
||||
}
|
||||
SetFloatValue(ActivePlayerFields.BlockPercentage, value);
|
||||
SetUpdateFieldStatValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.BlockPercentage), value);
|
||||
}
|
||||
|
||||
public void UpdateCritPercentage(WeaponAttackType attType)
|
||||
{
|
||||
BaseModGroup modGroup;
|
||||
ActivePlayerFields index;
|
||||
CombatRating cr;
|
||||
float applyCritLimit(float value)
|
||||
{
|
||||
if (WorldConfig.GetBoolValue(WorldCfg.StatsLimitsEnable))
|
||||
value = value > WorldConfig.GetFloatValue(WorldCfg.StatsLimitsCrit) ? WorldConfig.GetFloatValue(WorldCfg.StatsLimitsCrit) : value;
|
||||
return value;
|
||||
}
|
||||
|
||||
switch (attType)
|
||||
{
|
||||
case WeaponAttackType.OffAttack:
|
||||
modGroup = BaseModGroup.OffhandCritPercentage;
|
||||
index = ActivePlayerFields.OffhandCritPercentage;
|
||||
cr = CombatRating.CritMelee;
|
||||
SetUpdateFieldStatValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.OffhandCritPercentage),
|
||||
applyCritLimit(GetTotalPercentageModValue(BaseModGroup.OffhandCritPercentage) + GetRatingBonusValue(CombatRating.CritMelee)));
|
||||
break;
|
||||
case WeaponAttackType.RangedAttack:
|
||||
modGroup = BaseModGroup.RangedCritPercentage;
|
||||
index = ActivePlayerFields.RangedCritPercentage;
|
||||
cr = CombatRating.CritRanged;
|
||||
SetUpdateFieldStatValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.RangedCritPercentage),
|
||||
applyCritLimit(GetTotalPercentageModValue(BaseModGroup.RangedCritPercentage) + GetRatingBonusValue(CombatRating.CritRanged)));
|
||||
break;
|
||||
case WeaponAttackType.BaseAttack:
|
||||
default:
|
||||
modGroup = BaseModGroup.CritPercentage;
|
||||
index = ActivePlayerFields.CritPercentage;
|
||||
cr = CombatRating.CritMelee;
|
||||
SetUpdateFieldStatValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.CritPercentage),
|
||||
applyCritLimit(GetTotalPercentageModValue(BaseModGroup.CritPercentage) + GetRatingBonusValue(CombatRating.CritMelee)));
|
||||
break;
|
||||
}
|
||||
|
||||
float value = GetTotalPercentageModValue(modGroup) + GetRatingBonusValue(cr);
|
||||
// Modify crit from weapon skill and maximized defense skill of same level victim difference
|
||||
value += (GetMaxSkillValueForLevel() - GetMaxSkillValueForLevel()) * 0.04f;
|
||||
|
||||
if (WorldConfig.GetBoolValue(WorldCfg.StatsLimitsEnable))
|
||||
value = value > WorldConfig.GetFloatValue(WorldCfg.StatsLimitsCrit) ? WorldConfig.GetFloatValue(WorldCfg.StatsLimitsCrit) : value;
|
||||
|
||||
value = value < 0.0f ? 0.0f : value;
|
||||
SetFloatValue(index, value);
|
||||
}
|
||||
|
||||
public void UpdateExpertise(WeaponAttackType attack)
|
||||
@@ -1528,10 +1526,10 @@ namespace Game.Entities
|
||||
switch (attack)
|
||||
{
|
||||
case WeaponAttackType.BaseAttack:
|
||||
SetInt32Value(ActivePlayerFields.Expertise, expertise);
|
||||
SetUpdateFieldValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.MainhandExpertise), expertise);
|
||||
break;
|
||||
case WeaponAttackType.OffAttack:
|
||||
SetInt32Value(ActivePlayerFields.OffhandExpertise, expertise);
|
||||
SetUpdateFieldValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.OffhandExpertise), expertise);
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
@@ -1623,7 +1621,7 @@ namespace Game.Entities
|
||||
crit += GetRatingBonusValue(CombatRating.CritSpell);
|
||||
|
||||
// Store crit value
|
||||
SetFloatValue(ActivePlayerFields.SpellCritPercentage1, crit);
|
||||
SetUpdateFieldValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.SpellCritPercentage), crit);
|
||||
}
|
||||
|
||||
public void UpdateMeleeHitChances()
|
||||
@@ -1688,7 +1686,7 @@ namespace Game.Entities
|
||||
|
||||
public void ApplySpellPenetrationBonus(int amount, bool apply)
|
||||
{
|
||||
ApplyModInt32Value(ActivePlayerFields.ModTargetResistance, -amount, apply);
|
||||
ApplyModTargetResistance(-amount, apply);
|
||||
m_spellPenetrationItemMod += apply ? amount : -amount;
|
||||
}
|
||||
|
||||
@@ -1711,9 +1709,9 @@ namespace Game.Entities
|
||||
apply = _ModifyUInt32(apply, ref m_baseSpellPower, ref amount);
|
||||
|
||||
// For speed just update for client
|
||||
ApplyModUInt32Value(ActivePlayerFields.ModHealingDonePos, amount, apply);
|
||||
for (int i = (int)SpellSchools.Holy; i < (int)SpellSchools.Max; ++i)
|
||||
ApplyModUInt32Value(ActivePlayerFields.ModDamageDonePos + i, amount, apply);
|
||||
ApplyModUpdateFieldValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.ModHealingDonePos), amount, apply);
|
||||
for (SpellSchools spellSchool = SpellSchools.Holy; spellSchool < SpellSchools.Max; ++spellSchool)
|
||||
ApplyModDamageDonePos(spellSchool, amount, apply);
|
||||
|
||||
if (HasAuraType(AuraType.OverrideAttackPowerBySpPct))
|
||||
{
|
||||
@@ -1826,20 +1824,19 @@ namespace Game.Entities
|
||||
{
|
||||
UnitMods unitMod = ranged ? UnitMods.AttackPowerRanged : UnitMods.AttackPower;
|
||||
|
||||
UnitFields index = UnitFields.AttackPower;
|
||||
UnitFields index_mult = UnitFields.AttackPowerMultiplier;
|
||||
float baseAttackPower = GetModifierValue(unitMod, UnitModifierType.BaseValue) * GetModifierValue(unitMod, UnitModifierType.BasePCT);
|
||||
float attackPowerMultiplier = GetModifierValue(unitMod, UnitModifierType.TotalPCT) - 1.0f;
|
||||
|
||||
if (ranged)
|
||||
{
|
||||
index = UnitFields.RangedAttackPower;
|
||||
index_mult = UnitFields.RangedAttackPowerMultiplier;
|
||||
SetRangedAttackPower((int)baseAttackPower);
|
||||
SetRangedAttackPowerMultiplier(attackPowerMultiplier);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetAttackPower((int)baseAttackPower);
|
||||
SetAttackPowerMultiplier(attackPowerMultiplier);
|
||||
}
|
||||
|
||||
float base_attPower = GetModifierValue(unitMod, UnitModifierType.BaseValue) * GetModifierValue(unitMod, UnitModifierType.BasePCT);
|
||||
float attPowerMultiplier = GetModifierValue(unitMod, UnitModifierType.TotalPCT) - 1.0f;
|
||||
|
||||
SetInt32Value(index, (int)base_attPower); //UNIT_FIELD_(RANGED)_ATTACK_POWER field
|
||||
SetFloatValue(index_mult, attPowerMultiplier); //UNIT_FIELD_(RANGED)_ATTACK_POWER_MULTIPLIER field
|
||||
|
||||
//automatically update weapon damage after attack power modification
|
||||
if (ranged)
|
||||
|
||||
@@ -187,7 +187,7 @@ namespace Game.Entities
|
||||
|
||||
if (owner != null && IsTrigger() && m_spells[0] != 0)
|
||||
{
|
||||
SetFaction(owner.getFaction());
|
||||
SetFaction(owner.GetFaction());
|
||||
SetLevel(owner.getLevel());
|
||||
if (owner.IsTypeId(TypeId.Player))
|
||||
m_ControlledByPlayer = true;
|
||||
@@ -215,7 +215,7 @@ namespace Game.Entities
|
||||
if (m_Properties.Faction != 0)
|
||||
SetFaction(m_Properties.Faction);
|
||||
else if (IsVehicle() && owner != null) // properties should be vehicle
|
||||
SetFaction(owner.getFaction());
|
||||
SetFaction(owner.GetFaction());
|
||||
}
|
||||
|
||||
public virtual void InitSummon()
|
||||
@@ -327,7 +327,7 @@ namespace Game.Entities
|
||||
SetReactState(ReactStates.Passive);
|
||||
|
||||
SetCreatorGUID(GetOwner().GetGUID());
|
||||
SetFaction(GetOwner().getFaction());
|
||||
SetFaction(GetOwner().GetFaction());
|
||||
|
||||
GetOwner().SetMinion(this, true);
|
||||
}
|
||||
@@ -448,9 +448,6 @@ namespace Game.Entities
|
||||
SetBaseAttackTime(WeaponAttackType.OffAttack, SharedConst.BaseAttackTime);
|
||||
SetBaseAttackTime(WeaponAttackType.RangedAttack, SharedConst.BaseAttackTime);
|
||||
|
||||
SetFloatValue(UnitFields.ModCastSpeed, 1.0f);
|
||||
SetFloatValue(UnitFields.ModCastHaste, 1.0f);
|
||||
|
||||
//scale
|
||||
var cFamily = CliDB.CreatureFamilyStorage.LookupByKey(cinfo.Family);
|
||||
if (cFamily != null && cFamily.MinScale > 0.0f && petType == PetType.Hunter)
|
||||
@@ -517,8 +514,8 @@ namespace Game.Entities
|
||||
case PetType.Summon:
|
||||
{
|
||||
// the damage bonus used for pets is either fire or shadow damage, whatever is higher
|
||||
int fire = GetOwner().GetInt32Value(ActivePlayerFields.ModDamageDonePos + (int)SpellSchools.Fire);
|
||||
int shadow = GetOwner().GetInt32Value(ActivePlayerFields.ModDamageDonePos + (int)SpellSchools.Shadow);
|
||||
int fire = GetOwner().ToPlayer().m_activePlayerData.ModDamageDonePos[(int)SpellSchools.Fire];
|
||||
int shadow = GetOwner().ToPlayer().m_activePlayerData.ModDamageDonePos[(int)SpellSchools.Shadow];
|
||||
int val = (fire > shadow) ? fire : shadow;
|
||||
if (val < 0)
|
||||
val = 0;
|
||||
@@ -531,7 +528,7 @@ namespace Game.Entities
|
||||
}
|
||||
case PetType.Hunter:
|
||||
{
|
||||
SetUInt32Value(UnitFields.PetNextLevelExp, (uint)(Global.ObjectMgr.GetXPForLevel(petlevel) * 0.05f));
|
||||
ToPet().SetPetNextLevelExperience((uint)(Global.ObjectMgr.GetXPForLevel(petlevel) * 0.05f));
|
||||
//these formula may not be correct; however, it is designed to be close to what it should be
|
||||
//this makes dps 0.5 of pets level
|
||||
SetBaseWeaponDamage(WeaponAttackType.BaseAttack, WeaponDamageRange.MinDamage, petlevel - (petlevel / 4));
|
||||
@@ -865,8 +862,8 @@ namespace Game.Entities
|
||||
else
|
||||
val = 2 * GetStat(Stats.Strength) - 20.0f;
|
||||
|
||||
Unit owner = GetOwner();
|
||||
if (owner != null && owner.IsTypeId(TypeId.Player))
|
||||
Player owner = GetOwner() ? GetOwner().ToPlayer() : null;
|
||||
if (owner != null)
|
||||
{
|
||||
if (IsHunterPet()) //hunter pets benefit from owner's attack power
|
||||
{
|
||||
@@ -888,8 +885,8 @@ namespace Game.Entities
|
||||
//demons benefit from warlocks shadow or fire damage
|
||||
else if (IsPet())
|
||||
{
|
||||
int fire = owner.GetInt32Value(ActivePlayerFields.ModDamageDonePos + (int)SpellSchools.Fire) - owner.GetInt32Value(ActivePlayerFields.ModDamageDoneNeg + (int)SpellSchools.Fire);
|
||||
int shadow = owner.GetInt32Value(ActivePlayerFields.ModDamageDonePos + (int)SpellSchools.Shadow) - owner.GetInt32Value(ActivePlayerFields.ModDamageDoneNeg + (int)SpellSchools.Shadow);
|
||||
int fire = owner.m_activePlayerData.ModDamageDonePos[(int)SpellSchools.Fire] - owner.m_activePlayerData.ModDamageDoneNeg[(int)SpellSchools.Fire];
|
||||
int shadow = owner.m_activePlayerData.ModDamageDonePos[(int)SpellSchools.Shadow] - owner.m_activePlayerData.ModDamageDoneNeg[(int)SpellSchools.Shadow];
|
||||
int maximum = (fire > shadow) ? fire : shadow;
|
||||
if (maximum < 0)
|
||||
maximum = 0;
|
||||
@@ -899,7 +896,7 @@ namespace Game.Entities
|
||||
//water elementals benefit from mage's frost damage
|
||||
else if (GetEntry() == ENTRY_WATER_ELEMENTAL)
|
||||
{
|
||||
int frost = owner.GetInt32Value(ActivePlayerFields.ModDamageDonePos + (int)SpellSchools.Frost) - owner.GetInt32Value(ActivePlayerFields.ModDamageDoneNeg + (int)SpellSchools.Frost);
|
||||
int frost = owner.m_activePlayerData.ModDamageDonePos[(int)SpellSchools.Frost] - owner.m_activePlayerData.ModDamageDoneNeg[(int)SpellSchools.Frost];
|
||||
if (frost < 0)
|
||||
frost = 0;
|
||||
SetBonusDamage((int)(frost * 0.4f));
|
||||
@@ -912,10 +909,8 @@ namespace Game.Entities
|
||||
float base_attPower = GetModifierValue(unitMod, UnitModifierType.BaseValue) * GetModifierValue(unitMod, UnitModifierType.BasePCT);
|
||||
float attPowerMultiplier = GetModifierValue(unitMod, UnitModifierType.TotalPCT) - 1.0f;
|
||||
|
||||
//UNIT_FIELD_(RANGED)_ATTACK_POWER field
|
||||
SetInt32Value(UnitFields.AttackPower, (int)base_attPower);
|
||||
//UNIT_FIELD_(RANGED)_ATTACK_POWER_MULTIPLIER field
|
||||
SetFloatValue(UnitFields.AttackPowerMultiplier, attPowerMultiplier);
|
||||
SetAttackPower((int)base_attPower);
|
||||
SetAttackPowerMultiplier(attPowerMultiplier);
|
||||
|
||||
//automatically update weapon damage after attack power modification
|
||||
UpdateDamagePhysical(WeaponAttackType.BaseAttack);
|
||||
@@ -927,19 +922,20 @@ namespace Game.Entities
|
||||
return;
|
||||
|
||||
float bonusDamage = 0.0f;
|
||||
if (GetOwner().IsTypeId(TypeId.Player))
|
||||
Player playerOwner = m_owner.ToPlayer();
|
||||
if (playerOwner != null)
|
||||
{
|
||||
//force of nature
|
||||
if (GetEntry() == ENTRY_TREANT)
|
||||
{
|
||||
int spellDmg = GetOwner().GetInt32Value(ActivePlayerFields.ModDamageDonePos + (int)SpellSchools.Nature) - GetOwner().GetInt32Value(ActivePlayerFields.ModDamageDoneNeg + (int)SpellSchools.Nature);
|
||||
int spellDmg = playerOwner.m_activePlayerData.ModDamageDonePos[(int)SpellSchools.Nature] - playerOwner.m_activePlayerData.ModDamageDoneNeg[(int)SpellSchools.Nature];
|
||||
if (spellDmg > 0)
|
||||
bonusDamage = spellDmg * 0.09f;
|
||||
}
|
||||
//greater fire elemental
|
||||
else if (GetEntry() == ENTRY_FIRE_ELEMENTAL)
|
||||
{
|
||||
int spellDmg = GetOwner().GetInt32Value(ActivePlayerFields.ModDamageDonePos + (int)SpellSchools.Fire) - GetOwner().GetInt32Value(ActivePlayerFields.ModDamageDoneNeg + (int)SpellSchools.Fire);
|
||||
int spellDmg = playerOwner.m_activePlayerData.ModDamageDonePos[(int)SpellSchools.Fire] - playerOwner.m_activePlayerData.ModDamageDoneNeg[(int)SpellSchools.Fire];
|
||||
if (spellDmg > 0)
|
||||
bonusDamage = spellDmg * 0.4f;
|
||||
}
|
||||
@@ -960,15 +956,16 @@ namespace Game.Entities
|
||||
float mindamage = ((base_value + weapon_mindamage) * base_pct + total_value) * total_pct;
|
||||
float maxdamage = ((base_value + weapon_maxdamage) * base_pct + total_value) * total_pct;
|
||||
|
||||
SetStatFloatValue(UnitFields.MinDamage, mindamage);
|
||||
SetStatFloatValue(UnitFields.MaxDamage, maxdamage);
|
||||
SetUpdateFieldStatValue(m_values.ModifyValue(m_unitData).ModifyValue(m_unitData.MinDamage), mindamage);
|
||||
SetUpdateFieldStatValue(m_values.ModifyValue(m_unitData).ModifyValue(m_unitData.MaxDamage), maxdamage);
|
||||
}
|
||||
|
||||
void SetBonusDamage(int damage)
|
||||
{
|
||||
m_bonusSpellDamage = damage;
|
||||
if (GetOwner().IsTypeId(TypeId.Player))
|
||||
GetOwner().SetUInt32Value(ActivePlayerFields.PetSpellPower, (uint)damage);
|
||||
Player playerOwner = GetOwner().ToPlayer();
|
||||
if (playerOwner != null)
|
||||
playerOwner.SetPetSpellPower((uint)damage);
|
||||
}
|
||||
|
||||
public int GetBonusDamage() { return m_bonusSpellDamage; }
|
||||
|
||||
@@ -63,15 +63,13 @@ namespace Game.Entities
|
||||
packet.Totem = GetGUID();
|
||||
packet.Slot = (byte)(m_Properties.Slot - (int)SummonSlot.Totem);
|
||||
packet.Duration = duration;
|
||||
packet.SpellID = GetUInt32Value(UnitFields.CreatedBySpell);
|
||||
packet.SpellID = m_unitData.CreatedBySpell;
|
||||
owner.ToPlayer().SendPacket(packet);
|
||||
}
|
||||
|
||||
// set display id depending on caster's race
|
||||
uint totemDisplayId = Global.SpellMgr.GetModelForTotem(GetUInt32Value(UnitFields.CreatedBySpell), owner.GetRace());
|
||||
if (totemDisplayId == 0)
|
||||
Log.outError(LogFilter.Spells, $"Spell {GetUInt32Value(UnitFields.CreatedBySpell)} with RaceID ({owner.GetRace()}) have no totem model data defined, set to default model.");
|
||||
else
|
||||
uint totemDisplayId = Global.SpellMgr.GetModelForTotem(m_unitData.CreatedBySpell, owner.GetRace());
|
||||
if (totemDisplayId != 0)
|
||||
SetDisplayId(totemDisplayId);
|
||||
}
|
||||
|
||||
@@ -127,7 +125,7 @@ namespace Game.Entities
|
||||
{
|
||||
owner.SendAutoRepeatCancel(this);
|
||||
|
||||
SpellInfo spell = Global.SpellMgr.GetSpellInfo(GetUInt32Value(UnitFields.CreatedBySpell));
|
||||
SpellInfo spell = Global.SpellMgr.GetSpellInfo(m_unitData.CreatedBySpell);
|
||||
if (spell != null)
|
||||
GetSpellHistory().SendCooldownEvent(spell, 0, null, false);
|
||||
|
||||
|
||||
@@ -118,11 +118,11 @@ namespace Game.Entities
|
||||
if (m_goTemplateAddon != null)
|
||||
{
|
||||
SetFaction(m_goTemplateAddon.faction);
|
||||
SetUInt32Value(GameObjectFields.Flags, m_goTemplateAddon.flags);
|
||||
SetFlags((GameObjectFlags)m_goTemplateAddon.flags);
|
||||
}
|
||||
|
||||
m_goValue.Transport.PathProgress = 0;
|
||||
SetFloatValue(ObjectFields.ScaleX, goinfo.size);
|
||||
SetObjectScale(goinfo.size);
|
||||
SetPeriod(tInfo.pathTime);
|
||||
SetEntry(goinfo.entry);
|
||||
SetDisplayId(goinfo.displayId);
|
||||
@@ -473,7 +473,7 @@ namespace Game.Entities
|
||||
|
||||
PhasingHandler.InheritPhaseShift(summon, summoner ? (WorldObject)summoner : this);
|
||||
|
||||
summon.SetUInt32Value(UnitFields.CreatedBySpell, spellId);
|
||||
summon.SetCreatedBySpell(spellId);
|
||||
|
||||
summon.SetTransport(this);
|
||||
summon.m_movementInfo.transport.guid = GetGUID();
|
||||
@@ -778,8 +778,8 @@ namespace Game.Entities
|
||||
|
||||
public HashSet<WorldObject> GetPassengers() { return _passengers; }
|
||||
|
||||
public override uint GetTransportPeriod() { return GetUInt32Value(GameObjectFields.Level); }
|
||||
public void SetPeriod(uint period) { SetUInt32Value(GameObjectFields.Level, period); }
|
||||
public override uint GetTransportPeriod() { return m_gameObjectData.Level; }
|
||||
public void SetPeriod(uint period) { SetLevel(period); }
|
||||
uint GetTimer() { return m_goValue.Transport.PathProgress; }
|
||||
|
||||
public List<KeyFrame> GetKeyFrames() { return _transportInfo.keyFrames; }
|
||||
|
||||
@@ -236,9 +236,9 @@ namespace Game.Entities
|
||||
{
|
||||
_petnumber = petnumber;
|
||||
if (statwindow)
|
||||
_unit.SetUInt32Value(UnitFields.PetNumber, _petnumber);
|
||||
_unit.SetPetNumberForClient(_petnumber);
|
||||
else
|
||||
_unit.SetUInt32Value(UnitFields.PetNumber, 0);
|
||||
_unit.SetPetNumberForClient(0);
|
||||
}
|
||||
|
||||
public void LoadPetActionBar(string data)
|
||||
|
||||
@@ -246,15 +246,15 @@ namespace Game.Entities
|
||||
public void ClearInCombat()
|
||||
{
|
||||
m_CombatTimer = 0;
|
||||
RemoveFlag(UnitFields.Flags, UnitFlags.InCombat);
|
||||
RemoveUnitFlag(UnitFlags.InCombat);
|
||||
|
||||
// Player's state will be cleared in Player.UpdateContestedPvP
|
||||
Creature creature = ToCreature();
|
||||
if (creature != null)
|
||||
{
|
||||
ClearUnitState(UnitState.AttackPlayer);
|
||||
if (HasFlag(ObjectFields.DynamicFlags, UnitDynFlags.Tapped))
|
||||
SetUInt32Value(ObjectFields.DynamicFlags, creature.GetCreatureTemplate().DynamicFlags);
|
||||
if (HasDynamicFlag(UnitDynFlags.Tapped))
|
||||
SetDynamicFlags((UnitDynFlags)creature.GetCreatureTemplate().DynamicFlags);
|
||||
|
||||
if (creature.IsPet() || creature.IsGuardian())
|
||||
{
|
||||
@@ -270,7 +270,7 @@ namespace Game.Entities
|
||||
else
|
||||
ToPlayer().OnCombatExit();
|
||||
|
||||
RemoveFlag(UnitFields.Flags, UnitFlags.PetInCombat);
|
||||
RemoveUnitFlag(UnitFlags.PetInCombat);
|
||||
RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.LeaveCombat);
|
||||
}
|
||||
|
||||
@@ -314,7 +314,7 @@ namespace Game.Entities
|
||||
if (!IsAlive())
|
||||
return false;
|
||||
|
||||
if (HasFlag(UnitFields.Flags, (UnitFlags.NonAttackable | UnitFlags.NotSelectable)))
|
||||
if (HasUnitFlag(UnitFlags.NonAttackable | UnitFlags.NotSelectable))
|
||||
return false;
|
||||
|
||||
if (IsTypeId(TypeId.Player) && ToPlayer().IsGameMaster())
|
||||
@@ -329,7 +329,7 @@ namespace Game.Entities
|
||||
}
|
||||
public bool IsInCombat()
|
||||
{
|
||||
return HasFlag(UnitFields.Flags, UnitFlags.InCombat);
|
||||
return HasUnitFlag(UnitFlags.InCombat);
|
||||
}
|
||||
public bool Attack(Unit victim, bool meleeAttack)
|
||||
{
|
||||
@@ -344,7 +344,7 @@ namespace Game.Entities
|
||||
if (IsTypeId(TypeId.Player) && IsMounted())
|
||||
return false;
|
||||
|
||||
if (HasFlag(UnitFields.Flags, UnitFlags.Pacified))
|
||||
if (HasUnitFlag(UnitFlags.Pacified))
|
||||
return false;
|
||||
|
||||
// nobody can attack GM in GM-mode
|
||||
@@ -417,7 +417,7 @@ namespace Game.Entities
|
||||
ToCreature().CallAssistance();
|
||||
|
||||
// Remove emote state - will be restored on creature reset
|
||||
SetUInt32Value(UnitFields.NpcEmotestate, (uint)Emote.OneshotNone);
|
||||
SetEmoteState(Emote.OneshotNone);
|
||||
}
|
||||
|
||||
// delay offhand weapon attack to next attack time
|
||||
@@ -455,7 +455,7 @@ namespace Game.Entities
|
||||
else
|
||||
Log.outInfo(LogFilter.Unit, "{0} {1} stopped attacking", (IsTypeId(TypeId.Player) ? "Player" : "Creature"), GetGUID().ToString());
|
||||
}
|
||||
public ObjectGuid GetTarget() { return GetGuidValue(UnitFields.Target); }
|
||||
public ObjectGuid GetTarget() { return m_unitData.Target; }
|
||||
public virtual void SetTarget(ObjectGuid guid) { }
|
||||
public bool AttackStop()
|
||||
{
|
||||
@@ -517,8 +517,10 @@ namespace Game.Entities
|
||||
return attackerList;
|
||||
}
|
||||
|
||||
public float GetCombatReach() { return GetFloatValue(UnitFields.CombatReach); }
|
||||
float GetBoundaryRadius() { return GetFloatValue(UnitFields.BoundingRadius); }
|
||||
public float GetCombatReach() { return m_unitData.CombatReach; }
|
||||
public void SetCombatReach(float combatReach) { SetUpdateFieldValue(m_values.ModifyValue(m_unitData).ModifyValue(m_unitData.CombatReach), combatReach); }
|
||||
public float GetBoundingRadius() { return m_unitData.BoundingRadius; }
|
||||
public void SetBoundingRadius(float boundingRadius) { SetUpdateFieldValue(m_values.ModifyValue(m_unitData).ModifyValue(m_unitData.BoundingRadius), boundingRadius); }
|
||||
|
||||
public bool haveOffhandWeapon()
|
||||
{
|
||||
@@ -549,7 +551,7 @@ namespace Game.Entities
|
||||
}
|
||||
public void AttackerStateUpdate(Unit victim, WeaponAttackType attType = WeaponAttackType.BaseAttack, bool extra = false)
|
||||
{
|
||||
if (HasUnitState(UnitState.CannotAutoattack) || HasFlag(UnitFields.Flags, UnitFlags.Pacified))
|
||||
if (HasUnitState(UnitState.CannotAutoattack) || HasUnitFlag(UnitFlags.Pacified))
|
||||
return;
|
||||
|
||||
if (!victim.IsAlive())
|
||||
@@ -565,7 +567,7 @@ namespace Game.Entities
|
||||
if (attType != WeaponAttackType.BaseAttack && attType != WeaponAttackType.OffAttack)
|
||||
return;
|
||||
|
||||
if (IsTypeId(TypeId.Unit) && !HasFlag(UnitFields.Flags, UnitFlags.PlayerControlled))
|
||||
if (IsTypeId(TypeId.Unit) && !HasUnitFlag(UnitFlags.PlayerControlled))
|
||||
SetFacingToObject(victim); // update client side facing to face the target (prevents visual glitches when casting untargeted spells)
|
||||
|
||||
// melee attack spell casted at main hand attack only - no normal melee dmg dealt
|
||||
@@ -598,7 +600,7 @@ namespace Game.Entities
|
||||
|
||||
public void FakeAttackerStateUpdate(Unit victim, WeaponAttackType attType = WeaponAttackType.BaseAttack)
|
||||
{
|
||||
if (HasUnitState(UnitState.CannotAutoattack) || HasFlag(UnitFields.Flags, UnitFlags.Pacified))
|
||||
if (HasUnitState(UnitState.CannotAutoattack) || HasUnitFlag(UnitFlags.Pacified))
|
||||
return;
|
||||
|
||||
if (!victim.IsAlive())
|
||||
@@ -613,7 +615,7 @@ namespace Game.Entities
|
||||
if (attType != WeaponAttackType.BaseAttack && attType != WeaponAttackType.OffAttack)
|
||||
return; // ignore ranged case
|
||||
|
||||
if (IsTypeId(TypeId.Unit) && !HasFlag(UnitFields.Flags, UnitFlags.PlayerControlled))
|
||||
if (IsTypeId(TypeId.Unit) && !HasUnitFlag(UnitFlags.PlayerControlled))
|
||||
SetFacingToObject(victim); // update client side facing to face the target (prevents visual glitches when casting untargeted spells)
|
||||
|
||||
CalcDamageInfo damageInfo = new CalcDamageInfo();
|
||||
@@ -1290,7 +1292,7 @@ namespace Game.Entities
|
||||
if (IsInCombat() || HasUnitState(UnitState.Evade))
|
||||
return;
|
||||
|
||||
SetFlag(UnitFields.Flags, UnitFlags.InCombat);
|
||||
AddUnitFlag(UnitFlags.InCombat);
|
||||
|
||||
Creature creature = ToCreature();
|
||||
if (creature != null)
|
||||
@@ -1323,7 +1325,7 @@ namespace Game.Entities
|
||||
foreach (var unit in m_Controlled)
|
||||
{
|
||||
unit.SetInCombatState(PvP, enemy);
|
||||
unit.SetFlag(UnitFields.Flags, UnitFlags.PetInCombat);
|
||||
unit.AddUnitFlag(UnitFlags.PetInCombat);
|
||||
}
|
||||
|
||||
ProcSkillsAndAuras(enemy, ProcFlags.EnterCombat, ProcFlags.None, ProcFlagsSpellType.MaskAll, ProcFlagsSpellPhase.None, ProcFlagsHit.None, null, null, null);
|
||||
@@ -1504,7 +1506,7 @@ namespace Game.Entities
|
||||
|
||||
// must be after setDeathState which resets dynamic flags
|
||||
if (!creature.loot.isLooted())
|
||||
creature.SetFlag(ObjectFields.DynamicFlags, UnitDynFlags.Lootable);
|
||||
creature.AddDynamicFlag(UnitDynFlags.Lootable);
|
||||
else
|
||||
creature.AllLootRemovedFromCorpse();
|
||||
}
|
||||
@@ -1625,7 +1627,7 @@ namespace Game.Entities
|
||||
if (!player.HasUnitState(UnitState.AttackPlayer))
|
||||
{
|
||||
player.AddUnitState(UnitState.AttackPlayer);
|
||||
player.SetFlag(PlayerFields.Flags, PlayerFlags.ContestedPVP);
|
||||
player.AddPlayerFlag(PlayerFlags.ContestedPVP);
|
||||
// call MoveInLineOfSight for nearby contested guards
|
||||
UpdateObjectVisibility();
|
||||
}
|
||||
@@ -1766,6 +1768,21 @@ namespace Game.Entities
|
||||
ToPlayer().ClearComboPoints();
|
||||
}
|
||||
|
||||
public virtual bool CanUseAttackType(WeaponAttackType attacktype)
|
||||
{
|
||||
switch (attacktype)
|
||||
{
|
||||
case WeaponAttackType.BaseAttack:
|
||||
return !HasUnitFlag(UnitFlags.Disarmed);
|
||||
case WeaponAttackType.OffAttack:
|
||||
return !HasUnitFlag2(UnitFlags2.DisarmOffhand);
|
||||
case WeaponAttackType.RangedAttack:
|
||||
return !HasUnitFlag2(UnitFlags2.DisarmRanged);
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO for melee need create structure as in
|
||||
void CalculateMeleeDamage(Unit victim, uint damage, out CalcDamageInfo damageInfo, WeaponAttackType attackType)
|
||||
{
|
||||
@@ -2082,21 +2099,21 @@ namespace Game.Entities
|
||||
switch (attType)
|
||||
{
|
||||
case WeaponAttackType.RangedAttack:
|
||||
minDamage = GetFloatValue(UnitFields.MinRangedDamage);
|
||||
maxDamage = GetFloatValue(UnitFields.MaxRangedDamage);
|
||||
minDamage = m_unitData.MinRangedDamage;
|
||||
maxDamage = m_unitData.MaxRangedDamage;
|
||||
break;
|
||||
case WeaponAttackType.BaseAttack:
|
||||
minDamage = GetFloatValue(UnitFields.MinDamage);
|
||||
maxDamage = GetFloatValue(UnitFields.MaxDamage);
|
||||
minDamage = m_unitData.MinDamage;
|
||||
maxDamage = m_unitData.MaxDamage;
|
||||
if (IsInFeralForm())
|
||||
{
|
||||
minDamage += GetFloatValue(UnitFields.MinOffHandDamage);
|
||||
maxDamage += GetFloatValue(UnitFields.MaxOffHandDamage);
|
||||
minDamage += m_unitData.MinOffHandDamage;
|
||||
maxDamage += m_unitData.MaxOffHandDamage;
|
||||
}
|
||||
break;
|
||||
case WeaponAttackType.OffAttack:
|
||||
minDamage = GetFloatValue(UnitFields.MinOffHandDamage);
|
||||
maxDamage = GetFloatValue(UnitFields.MaxOffHandDamage);
|
||||
minDamage = m_unitData.MinOffHandDamage;
|
||||
maxDamage = m_unitData.MaxOffHandDamage;
|
||||
break;
|
||||
// Just for good manner
|
||||
default:
|
||||
@@ -2169,17 +2186,17 @@ namespace Game.Entities
|
||||
{
|
||||
if (attType == WeaponAttackType.RangedAttack)
|
||||
{
|
||||
int ap = GetInt32Value(UnitFields.RangedAttackPower);
|
||||
int ap = m_unitData.RangedAttackPower;
|
||||
if (ap < 0)
|
||||
return 0.0f;
|
||||
return ap * (1.0f + GetFloatValue(UnitFields.RangedAttackPowerMultiplier));
|
||||
return ap * (1.0f + m_unitData.RangedAttackPowerMultiplier);
|
||||
}
|
||||
else
|
||||
{
|
||||
int ap = GetInt32Value(UnitFields.AttackPower);
|
||||
int ap = m_unitData.AttackPower;
|
||||
if (ap < 0)
|
||||
return 0.0f;
|
||||
return ap * (1.0f + GetFloatValue(UnitFields.AttackPowerMultiplier));
|
||||
return ap * (1.0f + m_unitData.AttackPowerMultiplier);
|
||||
}
|
||||
}
|
||||
public float GetModifierValue(UnitMods unitMod, UnitModifierType modifierType)
|
||||
@@ -2223,14 +2240,25 @@ namespace Game.Entities
|
||||
}
|
||||
void UpdateAttackTimeField(WeaponAttackType att)
|
||||
{
|
||||
SetUInt32Value(UnitFields.BaseAttackTime + (int)att, (uint)(m_baseAttackSpeed[(int)att] * m_modAttackSpeedPct[(int)att]));
|
||||
switch (att)
|
||||
{
|
||||
case WeaponAttackType.BaseAttack:
|
||||
case WeaponAttackType.OffAttack:
|
||||
SetUpdateFieldValue(ref m_values.ModifyValue(m_unitData).ModifyValue(m_unitData.AttackRoundBaseTime, (int)att), (uint)(m_baseAttackSpeed[(int)att] * m_modAttackSpeedPct[(int)att]));
|
||||
break;
|
||||
case WeaponAttackType.RangedAttack:
|
||||
SetUpdateFieldValue(m_values.ModifyValue(m_unitData).ModifyValue(m_unitData.RangedAttackRoundBaseTime), (uint)(m_baseAttackSpeed[(int)att] * m_modAttackSpeedPct[(int)att]));
|
||||
break;
|
||||
default:
|
||||
break; ;
|
||||
}
|
||||
}
|
||||
public virtual void SetPvP(bool state)
|
||||
{
|
||||
if (state)
|
||||
SetByteFlag(UnitFields.Bytes2, UnitBytes2Offsets.PvpFlag, UnitBytes2Flags.PvP);
|
||||
AddPvpFlag(UnitPVPStateFlags.PvP);
|
||||
else
|
||||
RemoveByteFlag(UnitFields.Bytes2, UnitBytes2Offsets.PvpFlag, UnitBytes2Flags.PvP);
|
||||
RemovePvpFlag(UnitPVPStateFlags.PvP);
|
||||
}
|
||||
|
||||
public bool CanHaveThreatList(bool skipAliveCheck = false)
|
||||
@@ -2697,11 +2725,17 @@ namespace Game.Entities
|
||||
if (!spellProto.GetSchoolMask().HasAnyFlag(SpellSchoolMask.Normal))
|
||||
{
|
||||
float maxModDamagePercentSchool = 0.0f;
|
||||
for (var i = SpellSchools.Holy; i < SpellSchools.Max; ++i)
|
||||
Player thisPlayer = ToPlayer();
|
||||
if (thisPlayer != null)
|
||||
{
|
||||
if (Convert.ToBoolean((int)spellProto.GetSchoolMask() & (1 << (int)i)))
|
||||
maxModDamagePercentSchool = Math.Max(maxModDamagePercentSchool, GetFloatValue(ActivePlayerFields.ModDamageDonePct + (int)i));
|
||||
for (var i = SpellSchools.Holy; i < SpellSchools.Max; ++i)
|
||||
{
|
||||
if (Convert.ToBoolean((int)spellProto.GetSchoolMask() & (1 << (int)i)))
|
||||
maxModDamagePercentSchool = Math.Max(maxModDamagePercentSchool, thisPlayer.m_activePlayerData.ModDamageDonePercent[(int)i]);
|
||||
}
|
||||
}
|
||||
else
|
||||
maxModDamagePercentSchool = GetTotalAuraMultiplierByMiscMask(AuraType.ModDamagePercentDone, (uint)spellProto.GetSchoolMask());
|
||||
|
||||
DoneTotalMod *= maxModDamagePercentSchool;
|
||||
}
|
||||
@@ -2878,18 +2912,18 @@ namespace Game.Entities
|
||||
MathFunctions.ApplyPercentModFloatVar(ref m_modAttackSpeedPct[(int)att], val, !apply);
|
||||
|
||||
if (att == WeaponAttackType.BaseAttack)
|
||||
ApplyPercentModFloatValue(UnitFields.ModHaste, val, !apply);
|
||||
ApplyPercentModUpdateFieldValue(m_values.ModifyValue(m_unitData).ModifyValue(m_unitData.ModHaste), val, !apply);
|
||||
else if (att == WeaponAttackType.RangedAttack)
|
||||
ApplyPercentModFloatValue(UnitFields.ModRangedHaste, val, !apply);
|
||||
ApplyPercentModUpdateFieldValue(m_values.ModifyValue(m_unitData).ModifyValue(m_unitData.ModRangedHaste), val, !apply);
|
||||
}
|
||||
else
|
||||
{
|
||||
MathFunctions.ApplyPercentModFloatVar(ref m_modAttackSpeedPct[(int)att], -val, apply);
|
||||
|
||||
if (att == WeaponAttackType.BaseAttack)
|
||||
ApplyPercentModFloatValue(UnitFields.ModHaste, -val, apply);
|
||||
ApplyPercentModUpdateFieldValue(m_values.ModifyValue(m_unitData).ModifyValue(m_unitData.ModHaste), -val, apply);
|
||||
else if (att == WeaponAttackType.RangedAttack)
|
||||
ApplyPercentModFloatValue(UnitFields.ModRangedHaste, -val, apply);
|
||||
ApplyPercentModUpdateFieldValue(m_values.ModifyValue(m_unitData).ModifyValue(m_unitData.ModRangedHaste), -val, apply);
|
||||
}
|
||||
|
||||
UpdateAttackTimeField(att);
|
||||
@@ -2937,30 +2971,30 @@ namespace Game.Entities
|
||||
|
||||
// can't attack untargetable
|
||||
if ((bySpell == null || !bySpell.HasAttribute(SpellAttr6.CanTargetUntargetable))
|
||||
&& target.HasFlag(UnitFields.Flags, UnitFlags.NotSelectable))
|
||||
&& target.HasUnitFlag(UnitFlags.NotSelectable))
|
||||
return false;
|
||||
|
||||
Player playerAttacker = ToPlayer();
|
||||
if (playerAttacker != null)
|
||||
{
|
||||
if (playerAttacker.HasFlag(PlayerFields.Flags, PlayerFlags.Commentator2))
|
||||
if (playerAttacker.HasPlayerFlag(PlayerFlags.Commentator2))
|
||||
return false;
|
||||
}
|
||||
|
||||
// check flags
|
||||
if (target.HasFlag(UnitFields.Flags, (UnitFlags.NonAttackable | UnitFlags.TaxiFlight | UnitFlags.NotAttackable1 | UnitFlags.Unk16))
|
||||
|| (!HasFlag(UnitFields.Flags, UnitFlags.PvpAttackable) && target.HasFlag(UnitFields.Flags, UnitFlags.ImmuneToNpc))
|
||||
|| (!target.HasFlag(UnitFields.Flags, UnitFlags.PvpAttackable) && HasFlag(UnitFields.Flags, UnitFlags.ImmuneToNpc)))
|
||||
if (target.HasUnitFlag(UnitFlags.NonAttackable | UnitFlags.TaxiFlight | UnitFlags.NotAttackable1 | UnitFlags.Unk16)
|
||||
|| (!HasUnitFlag(UnitFlags.PvpAttackable) && target.HasUnitFlag(UnitFlags.ImmuneToNpc))
|
||||
|| (!target.HasUnitFlag(UnitFlags.PvpAttackable) && HasUnitFlag(UnitFlags.ImmuneToNpc)))
|
||||
return false;
|
||||
|
||||
if ((bySpell == null || !bySpell.HasAttribute(SpellAttr8.AttackIgnoreImmuneToPCFlag))
|
||||
&& (HasFlag(UnitFields.Flags, UnitFlags.PvpAttackable) && target.HasFlag(UnitFields.Flags, UnitFlags.ImmuneToPc))
|
||||
&& (HasUnitFlag(UnitFlags.PvpAttackable) && target.HasUnitFlag(UnitFlags.ImmuneToPc))
|
||||
// check if this is a world trigger cast - GOs are using world triggers to cast their spells, so we need to ignore their immunity flag here, this is a temp workaround, needs removal when go cast is implemented properly
|
||||
&& GetEntry() != SharedConst.WorldTrigger)
|
||||
return false;
|
||||
|
||||
// CvC case - can attack each other only when one of them is hostile
|
||||
if (!HasFlag(UnitFields.Flags, UnitFlags.PvpAttackable) && !target.HasFlag(UnitFields.Flags, UnitFlags.PvpAttackable))
|
||||
if (!HasUnitFlag(UnitFlags.PvpAttackable) && !target.HasUnitFlag(UnitFlags.PvpAttackable))
|
||||
return GetReactionTo(target) <= ReputationRank.Hostile || target.GetReactionTo(this) <= ReputationRank.Hostile;
|
||||
|
||||
// PvP, PvC, CvP case
|
||||
@@ -2968,8 +3002,8 @@ namespace Game.Entities
|
||||
if (GetReactionTo(target) > ReputationRank.Neutral || target.GetReactionTo(this) > ReputationRank.Neutral)
|
||||
return false;
|
||||
|
||||
Player playerAffectingAttacker = HasFlag(UnitFields.Flags, UnitFlags.PvpAttackable) ? GetAffectingPlayer() : null;
|
||||
Player playerAffectingTarget = target.HasFlag(UnitFields.Flags, UnitFlags.PvpAttackable) ? target.GetAffectingPlayer() : null;
|
||||
Player playerAffectingAttacker = HasUnitFlag(UnitFlags.PvpAttackable) ? GetAffectingPlayer() : null;
|
||||
Player playerAffectingTarget = target.HasUnitFlag(UnitFlags.PvpAttackable) ? target.GetAffectingPlayer() : null;
|
||||
|
||||
// Not all neutral creatures can be attacked (even some unfriendly faction does not react aggresive to you, like Sporaggar)
|
||||
if ((playerAffectingAttacker && !playerAffectingTarget) || (!playerAffectingAttacker && playerAffectingTarget))
|
||||
@@ -3010,9 +3044,8 @@ namespace Game.Entities
|
||||
|
||||
// PvP case - can't attack when attacker or target are in sanctuary
|
||||
// however, 13850 client doesn't allow to attack when one of the unit's has sanctuary flag and is pvp
|
||||
if (target.HasFlag(UnitFields.Flags, UnitFlags.PvpAttackable) && HasFlag(UnitFields.Flags, UnitFlags.PvpAttackable)
|
||||
&& (Convert.ToBoolean(target.GetByteValue(UnitFields.Bytes2, UnitBytes2Offsets.PvpFlag) & (byte)UnitBytes2Flags.Sanctuary)
|
||||
|| Convert.ToBoolean(GetByteValue(UnitFields.Bytes2, UnitBytes2Offsets.PvpFlag) & (byte)UnitBytes2Flags.Sanctuary)))
|
||||
if (target.HasUnitFlag(UnitFlags.PvpAttackable) && HasUnitFlag(UnitFlags.PvpAttackable)
|
||||
&& (target.HasPvpFlag(UnitPVPStateFlags.Sanctuary) || HasPvpFlag(UnitPVPStateFlags.Sanctuary)))
|
||||
return false;
|
||||
|
||||
// additional checks - only PvP case
|
||||
@@ -3024,7 +3057,7 @@ namespace Game.Entities
|
||||
if (IsFFAPvP() && target.IsFFAPvP())
|
||||
return true;
|
||||
|
||||
return HasByteFlag(UnitFields.Bytes2, UnitBytes2Offsets.PvpFlag, UnitBytes2Flags.Unk1) || target.HasByteFlag(UnitFields.Bytes2, UnitBytes2Offsets.PvpFlag, UnitBytes2Flags.Unk1);
|
||||
return HasPvpFlag(UnitPVPStateFlags.Unk1) || target.HasPvpFlag(UnitPVPStateFlags.Unk1);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -3062,19 +3095,19 @@ namespace Game.Entities
|
||||
|
||||
// can't assist untargetable
|
||||
if ((bySpell == null || !bySpell.HasAttribute(SpellAttr6.CanTargetUntargetable))
|
||||
&& target.HasFlag(UnitFields.Flags, UnitFlags.NotSelectable))
|
||||
&& target.HasUnitFlag(UnitFlags.NotSelectable))
|
||||
return false;
|
||||
|
||||
if (bySpell == null || !bySpell.HasAttribute(SpellAttr6.AssistIgnoreImmuneFlag))
|
||||
{
|
||||
if (HasFlag(UnitFields.Flags, UnitFlags.PvpAttackable))
|
||||
if (HasUnitFlag(UnitFlags.PvpAttackable))
|
||||
{
|
||||
if (target.HasFlag(UnitFields.Flags, UnitFlags.ImmuneToPc))
|
||||
if (target.HasUnitFlag(UnitFlags.ImmuneToPc))
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (target.HasFlag(UnitFields.Flags, UnitFlags.ImmuneToNpc))
|
||||
if (target.HasUnitFlag(UnitFlags.ImmuneToNpc))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -3090,10 +3123,10 @@ namespace Game.Entities
|
||||
return true;
|
||||
|
||||
// PvP case
|
||||
else if (target.HasFlag(UnitFields.Flags, UnitFlags.PvpAttackable))
|
||||
else if (target.HasUnitFlag(UnitFlags.PvpAttackable))
|
||||
{
|
||||
Player targetPlayerOwner = target.GetAffectingPlayer();
|
||||
if (HasFlag(UnitFields.Flags, UnitFlags.PvpAttackable))
|
||||
if (HasUnitFlag(UnitFlags.PvpAttackable))
|
||||
{
|
||||
Player selfPlayerOwner = GetAffectingPlayer();
|
||||
if (selfPlayerOwner != null && targetPlayerOwner != null)
|
||||
@@ -3103,20 +3136,18 @@ namespace Game.Entities
|
||||
return false;
|
||||
}
|
||||
// can't assist player in ffa_pvp zone from outside
|
||||
if (Convert.ToBoolean(target.GetByteValue(UnitFields.Bytes2, UnitBytes2Offsets.PvpFlag) & (byte)UnitBytes2Flags.FFAPvp)
|
||||
&& !Convert.ToBoolean(GetByteValue(UnitFields.Bytes2, UnitBytes2Offsets.PvpFlag) & (byte)UnitBytes2Flags.FFAPvp))
|
||||
if (target.HasPvpFlag(UnitPVPStateFlags.FFAPvp) && !HasPvpFlag(UnitPVPStateFlags.FFAPvp))
|
||||
return false;
|
||||
// can't assist player out of sanctuary from sanctuary if has pvp enabled
|
||||
if (Convert.ToBoolean(target.GetByteValue(UnitFields.Bytes2, UnitBytes2Offsets.PvpFlag) & (byte)UnitBytes2Flags.PvP))
|
||||
if (Convert.ToBoolean(GetByteValue(UnitFields.Bytes2, UnitBytes2Offsets.PvpFlag) & (byte)UnitBytes2Flags.Sanctuary)
|
||||
&& !Convert.ToBoolean(target.GetByteValue(UnitFields.Bytes2, UnitBytes2Offsets.PvpFlag) & (byte)UnitBytes2Flags.Sanctuary))
|
||||
if (target.HasPvpFlag(UnitPVPStateFlags.PvP))
|
||||
if (HasPvpFlag(UnitPVPStateFlags.Sanctuary) && !target.HasPvpFlag(UnitPVPStateFlags.Sanctuary))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// PvC case - player can assist creature only if has specific type flags
|
||||
else if (HasFlag(UnitFields.Flags, UnitFlags.PvpAttackable)
|
||||
else if (HasUnitFlag(UnitFlags.PvpAttackable)
|
||||
&& (bySpell == null || !bySpell.HasAttribute(SpellAttr6.AssistIgnoreImmuneFlag))
|
||||
&& !Convert.ToBoolean(target.GetByteValue(UnitFields.Bytes2, UnitBytes2Offsets.PvpFlag) & (byte)UnitBytes2Flags.PvP))
|
||||
&& !target.HasPvpFlag(UnitPVPStateFlags.PvP))
|
||||
{
|
||||
Creature creatureTarget = target.ToCreature();
|
||||
if (creatureTarget != null)
|
||||
|
||||
@@ -107,11 +107,15 @@ namespace Game.Entities
|
||||
uint m_removedAurasCount;
|
||||
|
||||
//General
|
||||
public UnitData m_unitData;
|
||||
|
||||
DiminishingReturn[] m_Diminishing = new DiminishingReturn[(int)DiminishingGroup.Max];
|
||||
protected List<GameObject> m_gameObj = new List<GameObject>();
|
||||
List<AreaTrigger> m_areaTrigger = new List<AreaTrigger>();
|
||||
protected List<DynamicObject> m_dynObj = new List<DynamicObject>();
|
||||
protected float[] CreateStats = new float[(int)Stats.Max];
|
||||
float[] m_floatStatPosBuff = new float[(int)Stats.Max];
|
||||
float[] m_floatStatNegBuff = new float[(int)Stats.Max];
|
||||
public ObjectGuid[] m_SummonSlot = new ObjectGuid[7];
|
||||
public ObjectGuid[] m_ObjectSlot = new ObjectGuid[4];
|
||||
public EventSystem m_Events = new EventSystem();
|
||||
|
||||
@@ -54,13 +54,13 @@ namespace Game.Entities
|
||||
public virtual bool CanSwim()
|
||||
{
|
||||
// Mirror client behavior, if this method returns false then client will not use swimming animation and for players will apply gravity as if there was no water
|
||||
if (HasFlag(UnitFields.Flags, UnitFlags.CannotSwim))
|
||||
if (HasUnitFlag(UnitFlags.CannotSwim))
|
||||
return false;
|
||||
if (HasFlag(UnitFields.Flags, UnitFlags.PvpAttackable)) // is player
|
||||
if (HasUnitFlag(UnitFlags.PvpAttackable)) // is player
|
||||
return true;
|
||||
if (HasFlag(UnitFields.Flags2, 0x1000000))
|
||||
if (HasUnitFlag2((UnitFlags2)0x1000000))
|
||||
return false;
|
||||
return HasFlag(UnitFields.Flags, UnitFlags.PetInCombat | UnitFlags.Rename | UnitFlags.Unk15);
|
||||
return HasUnitFlag(UnitFlags.PetInCombat | UnitFlags.Rename | UnitFlags.Unk15);
|
||||
}
|
||||
public virtual bool IsInWater()
|
||||
{
|
||||
@@ -593,7 +593,7 @@ namespace Game.Entities
|
||||
if (!obj || !IsInMap(obj) || !IsInPhase(obj))
|
||||
return false;
|
||||
|
||||
float objBoundaryRadius = Math.Max(obj.GetBoundaryRadius(), SharedConst.MinMeleeReach);
|
||||
float objBoundaryRadius = Math.Max(obj.GetBoundingRadius(), SharedConst.MinMeleeReach);
|
||||
|
||||
return IsInDist(obj, objBoundaryRadius);
|
||||
}
|
||||
@@ -737,6 +737,15 @@ namespace Game.Entities
|
||||
if (mountCapability.ReqSpellKnownID != 0 && !HasSpell(mountCapability.ReqSpellKnownID))
|
||||
continue;
|
||||
|
||||
Player thisPlayer = ToPlayer();
|
||||
if (thisPlayer != null)
|
||||
{
|
||||
PlayerConditionRecord playerCondition = CliDB.PlayerConditionStorage.LookupByKey(mountCapability.PlayerConditionID);
|
||||
if (playerCondition != null)
|
||||
if (!ConditionManager.IsPlayerMeetingCondition(thisPlayer, playerCondition))
|
||||
continue;
|
||||
}
|
||||
|
||||
return mountCapability;
|
||||
}
|
||||
|
||||
@@ -944,7 +953,7 @@ namespace Game.Entities
|
||||
if (enable == HasUnitMovementFlag(MovementFlag.Hover))
|
||||
return false;
|
||||
|
||||
float hoverHeight = GetFloatValue(UnitFields.HoverHeight);
|
||||
float hoverHeight = m_unitData.HoverHeight;
|
||||
|
||||
if (enable)
|
||||
{
|
||||
@@ -1133,7 +1142,7 @@ namespace Game.Entities
|
||||
if (apply)
|
||||
{
|
||||
SetTarget(ObjectGuid.Empty);
|
||||
SetFlag(UnitFields.Flags, UnitFlags.Stunned);
|
||||
AddUnitFlag(UnitFlags.Stunned);
|
||||
|
||||
StopMoving();
|
||||
|
||||
@@ -1152,7 +1161,7 @@ namespace Game.Entities
|
||||
// don't remove UNIT_FLAG_STUNNED for pet when owner is mounted (disabled pet's interface)
|
||||
Unit owner = GetCharmerOrOwner();
|
||||
if (owner == null || !owner.IsTypeId(TypeId.Player) || !owner.ToPlayer().IsMounted())
|
||||
RemoveFlag(UnitFields.Flags, UnitFlags.Stunned);
|
||||
RemoveUnitFlag(UnitFlags.Stunned);
|
||||
|
||||
if (!HasUnitState(UnitState.Root)) // prevent moving if it also has root effect
|
||||
SetRooted(false);
|
||||
@@ -1260,9 +1269,9 @@ namespace Game.Entities
|
||||
public void Mount(uint mount, uint VehicleId = 0, uint creatureEntry = 0)
|
||||
{
|
||||
if (mount != 0)
|
||||
SetUInt32Value(UnitFields.MountDisplayId, mount);
|
||||
SetMountDisplayId(mount);
|
||||
|
||||
SetFlag(UnitFields.Flags, UnitFlags.Mount);
|
||||
AddUnitFlag(UnitFlags.Mount);
|
||||
|
||||
Player player = ToPlayer();
|
||||
if (player != null)
|
||||
@@ -1286,7 +1295,7 @@ namespace Game.Entities
|
||||
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.SetFlag(UnitFields.Flags, UnitFlags.Stunned);
|
||||
pet.AddUnitFlag(UnitFlags.Stunned);
|
||||
else
|
||||
player.UnsummonPetTemporaryIfAny();
|
||||
}
|
||||
@@ -1295,7 +1304,7 @@ namespace Game.Entities
|
||||
Unit charm = player.GetCharm();
|
||||
if (charm)
|
||||
if (charm.GetTypeId() == TypeId.Unit)
|
||||
charm.SetFlag(UnitFields.Flags, UnitFlags.Stunned);
|
||||
charm.AddUnitFlag(UnitFlags.Stunned);
|
||||
|
||||
player.SendMovementSetCollisionHeight(player.GetCollisionHeight(true));
|
||||
}
|
||||
@@ -1308,8 +1317,8 @@ namespace Game.Entities
|
||||
if (!IsMounted())
|
||||
return;
|
||||
|
||||
SetUInt32Value(UnitFields.MountDisplayId, 0);
|
||||
RemoveFlag(UnitFields.Flags, UnitFlags.Mount);
|
||||
SetMountDisplayId(0);
|
||||
RemoveUnitFlag(UnitFlags.Mount);
|
||||
|
||||
Player thisPlayer = ToPlayer();
|
||||
if (thisPlayer != null)
|
||||
@@ -1337,8 +1346,8 @@ namespace Game.Entities
|
||||
Pet pPet = player.GetPet();
|
||||
if (pPet != null)
|
||||
{
|
||||
if (pPet.HasFlag(UnitFields.Flags, UnitFlags.Stunned) && !pPet.HasUnitState(UnitState.Stunned))
|
||||
pPet.RemoveFlag(UnitFields.Flags, UnitFlags.Stunned);
|
||||
if (pPet.HasUnitFlag(UnitFlags.Stunned) && !pPet.HasUnitState(UnitState.Stunned))
|
||||
pPet.RemoveUnitFlag(UnitFlags.Stunned);
|
||||
}
|
||||
else
|
||||
player.ResummonPetTemporaryUnSummonedIfAny();
|
||||
@@ -1346,8 +1355,8 @@ namespace Game.Entities
|
||||
// if we have charmed npc, remove stun also
|
||||
Unit charm = player.GetCharm();
|
||||
if (charm)
|
||||
if (charm.GetTypeId() == TypeId.Unit && charm.HasFlag(UnitFields.Flags, UnitFlags.Stunned) && !charm.HasUnitState(UnitState.Stunned))
|
||||
charm.RemoveFlag(UnitFields.Flags, UnitFlags.Stunned);
|
||||
if (charm.GetTypeId() == TypeId.Unit && charm.HasUnitFlag(UnitFlags.Stunned) && !charm.HasUnitState(UnitState.Stunned))
|
||||
charm.RemoveUnitFlag(UnitFlags.Stunned);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1381,7 +1390,7 @@ namespace Game.Entities
|
||||
|
||||
m_updateFlag.Vehicle = false;
|
||||
m_unitTypeMask &= ~UnitTypeMask.Vehicle;
|
||||
RemoveFlag64(UnitFields.NpcFlags, NPCFlags.SpellClick | NPCFlags.PlayerVehicle);
|
||||
RemoveNpcFlag(NPCFlags.SpellClick | NPCFlags.PlayerVehicle);
|
||||
}
|
||||
|
||||
void SendSetVehicleRecId(uint vehicleId)
|
||||
@@ -1415,7 +1424,7 @@ namespace Game.Entities
|
||||
{
|
||||
float offset = 0.0f;
|
||||
if (HasUnitMovementFlag(MovementFlag.Hover))
|
||||
offset = GetFloatValue(UnitFields.HoverHeight);
|
||||
offset = m_unitData.HoverHeight;
|
||||
|
||||
return GetPositionZ() - offset;
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user