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:
hondacrx
2019-08-14 11:20:42 -04:00
parent e4d500f4b5
commit 125e3b3ac7
232 changed files with 12268 additions and 14670 deletions
+1 -1
View File
@@ -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);
+2 -2
View File
@@ -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);
}
+2 -2
View File
@@ -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)
+10 -10
View File
@@ -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; }
+1 -1
View File
@@ -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);
+5 -5
View File
@@ -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
+51 -17
View File
@@ -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);
+4 -4
View File
@@ -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;
+1 -1
View File
@@ -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);
+1 -33
View File
@@ -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)
{
+3 -3
View File
@@ -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;
+7 -13
View File
@@ -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);
+3 -3
View File
@@ -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);
}
}
+1 -1
View File
@@ -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;
+2 -2
View File
@@ -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))
{
+2 -2
View File
@@ -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;
-237
View File
@@ -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);
+1 -1
View File
@@ -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;
+1 -1
View File
@@ -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);
+13 -15
View File
@@ -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;
+15 -59
View File
@@ -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();
+17 -16
View File
@@ -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);
+4 -4
View File
@@ -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);
+6 -6
View File
@@ -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;
}
+6 -7
View File
@@ -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);
+6 -6
View File
@@ -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));
}
+10 -10
View File
@@ -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))
+11 -11
View File
@@ -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)]
+72 -20
View File
@@ -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>();
+4 -2
View File
@@ -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
+2 -2
View File
@@ -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;
}
+12 -1
View File
@@ -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
+1 -1
View File
@@ -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];
+3 -3
View File
@@ -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
+2 -2
View File
@@ -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
+20 -19
View File
@@ -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;
+10 -8
View File
@@ -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];
+3 -2
View File
@@ -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;
}
+6 -3
View File
@@ -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
+1 -1
View File
@@ -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;
+78 -21
View File
@@ -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;
+65 -40
View File
@@ -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;
}
}
+95 -21
View File
@@ -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;
+84 -88
View File
@@ -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;
+49 -14
View File
@@ -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;
}
+106 -156
View File
@@ -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;
+60 -17
View File
@@ -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];
}
}
File diff suppressed because it is too large Load Diff
+39 -161
View File
@@ -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>();
}
}
+3 -4
View File
@@ -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
View File
@@ -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);
}
}
+22 -32
View File
@@ -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
+7 -6
View File
@@ -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;
+2 -2
View File
@@ -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)
+88 -100
View File
@@ -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()
{
+2 -2
View File
@@ -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))
+31 -24
View File
@@ -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()
+38 -48
View File
@@ -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)
+209 -249
View File
@@ -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
+13 -16
View File
@@ -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
+22 -24
View File
@@ -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
View File
@@ -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)
+22 -25
View File
@@ -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; }
+4 -6
View File
@@ -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);
+5 -5
View File
@@ -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; }
+2 -2
View File
@@ -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)
+98 -67
View File
@@ -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)
+4
View File
@@ -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();
+29 -20
View File
@@ -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