Core/DataStores: Updated db2 structures to 9.0.2

Port From (https://github.com/TrinityCore/TrinityCore/commit/b82a3a557a7bf13d48342ea189325550059b622d)
This commit is contained in:
hondacrx
2020-12-12 23:20:41 -05:00
parent 18d2b7bb80
commit f0037ab99f
86 changed files with 12653 additions and 2811 deletions
@@ -78,7 +78,7 @@ namespace Game.Entities
}
}
bool Create(uint spellMiscId, Unit caster, Unit target, SpellInfo spell, Position pos, int duration, SpellCastVisual spellVisual, ObjectGuid castId, AuraEffect aurEff)
bool Create(uint spellMiscId, Unit caster, Unit target, SpellInfo spell, Position pos, int duration, SpellCastVisualField spellVisual, ObjectGuid castId, AuraEffect aurEff)
{
_targetGuid = target ? target.GetGUID() : ObjectGuid.Empty;
_aurEff = aurEff;
@@ -110,7 +110,11 @@ namespace Game.Entities
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), spellVisual.SpellXSpellVisualID);
SpellCastVisualField spellCastVisual = m_values.ModifyValue(m_areaTriggerData).ModifyValue(m_areaTriggerData.SpellVisual);
SetUpdateFieldValue(ref spellCastVisual.SpellXSpellVisualID, spellVisual.SpellXSpellVisualID);
SetUpdateFieldValue(ref spellCastVisual.ScriptVisualID, spellVisual.ScriptVisualID);
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);
@@ -197,7 +201,7 @@ namespace Game.Entities
return true;
}
public static AreaTrigger CreateAreaTrigger(uint spellMiscId, Unit caster, Unit target, SpellInfo spell, Position pos, int duration, SpellCastVisual spellVisual, ObjectGuid castId = default, AuraEffect aurEff = null)
public static AreaTrigger CreateAreaTrigger(uint spellMiscId, Unit caster, Unit target, SpellInfo spell, Position pos, int duration, SpellCastVisualField spellVisual, ObjectGuid castId = default, AuraEffect aurEff = null)
{
AreaTrigger at = new AreaTrigger();
if (!at.Create(spellMiscId, caster, target, spell, pos, duration, spellVisual, castId, aurEff))
+1 -1
View File
@@ -174,7 +174,7 @@ namespace Game.Entities
foreach (ushort actorIndex in actorIndices)
{
ConversationActor actor = actorIndex < m_conversationData.Actors.Size() ? m_conversationData.Actors[actorIndex] : null;
if (actor == null || (actor.CreatureID == 0 && actor.ActorGUID.IsEmpty()))
if (actor == null || (actor.CreatureID == 0 && actor.ActorGUID.IsEmpty() && actor.NoActorObject == 0))
{
Log.outError(LogFilter.Conversation, $"Failed to create conversation (Id: {conversationEntry}) due to missing actor (Idx: {actorIndex}).");
return false;
+33 -22
View File
@@ -101,10 +101,6 @@ namespace Game.Entities
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
@@ -115,8 +111,8 @@ namespace Game.Entities
stmt.AddValue(index++, GetMapId()); // mapId
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++, m_corpseData.RaceID); // race
stmt.AddValue(index++, m_corpseData.Sex); // gender
stmt.AddValue(index++, (uint)m_corpseData.Flags); // flags
stmt.AddValue(index++, (uint)m_corpseData.DynamicFlags); // dynFlags
stmt.AddValue(index++, (uint)m_time); // time
@@ -132,6 +128,18 @@ namespace Game.Entities
stmt.AddValue(index++, phaseId); // PhaseId
trans.Append(stmt);
}
foreach (var customization in m_corpseData.Customizations)
{
index = 0;
stmt = DB.Characters.GetPreparedStatement(CharStatements.INS_CORPSE_CUSTOMIZATIONS);
stmt.AddValue(index++, GetOwnerGUID().GetCounter()); // OwnerGuid
stmt.AddValue(index++, customization.ChrCustomizationOptionID);
stmt.AddValue(index++, customization.ChrCustomizationChoiceID);
trans.Append(stmt);
}
DB.Characters.CommitTransaction(trans);
}
public void DeleteFromDB(SQLTransaction trans)
@@ -148,12 +156,16 @@ namespace Game.Entities
stmt = DB.Characters.GetPreparedStatement(CharStatements.DEL_CORPSE_PHASES);
stmt.AddValue(0, ownerGuid.GetCounter());
DB.Characters.ExecuteOrAppend(trans, stmt);
stmt = DB.Characters.GetPreparedStatement(CharStatements.DEL_CORPSE_CUSTOMIZATIONS);
stmt.AddValue(0, ownerGuid.GetCounter());
DB.Characters.ExecuteOrAppend(trans, stmt);
}
public bool LoadCorpseFromDB(ulong guid, SQLFields field)
{
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
// SELECT posX, posY, posZ, orientation, mapId, displayId, itemCache, bytes1, bytes2, flags, dynFlags, time, corpseType, instanceId, guid FROM corpse WHERE mapId = ? AND instanceId = ?
// SELECT posX, posY, posZ, orientation, mapId, displayId, itemCache, race, gender, flags, dynFlags, time, corpseType, instanceId, guid FROM corpse WHERE mapId = ? AND instanceId = ?
float posX = field.Read<float>(0);
float posY = field.Read<float>(1);
@@ -169,15 +181,8 @@ namespace Game.Entities
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));
SetRace((Race)field.Read<byte>(7));
SetSex((Gender)field.Read<byte>(8));
SetFlags((CorpseFlags)field.Read<byte>(9));
SetCorpseDynamicFlags((CorpseDynFlags)field.Read<byte>(10));
SetOwnerGUID(ObjectGuid.Create(HighGuid.Player, field.Read<ulong>(14)));
@@ -287,15 +292,21 @@ namespace Game.Entities
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 void SetCustomizations(List<ChrCustomizationChoice> customizations)
{
ClearDynamicUpdateFieldValues(m_values.ModifyValue(m_corpseData).ModifyValue(m_corpseData.Customizations));
foreach (var customization in customizations)
{
var newChoice = new ChrCustomizationChoice();
newChoice.ChrCustomizationOptionID = customization.ChrCustomizationOptionID;
newChoice.ChrCustomizationChoiceID = customization.ChrCustomizationChoiceID;
AddDynamicUpdateFieldValue(m_values.ModifyValue(m_corpseData).ModifyValue(m_corpseData.Customizations), newChoice);
}
}
public long GetGhostTime() { return m_time; }
public void ResetGhostTime() { m_time = Time.UnixTime; }
+6 -2
View File
@@ -77,7 +77,7 @@ namespace Game.Entities
}
}
public bool CreateDynamicObject(ulong guidlow, Unit caster, SpellInfo spell, Position pos, float radius, DynamicObjectType type, SpellCastVisual spellVisual)
public bool CreateDynamicObject(ulong guidlow, Unit caster, SpellInfo spell, Position pos, float radius, DynamicObjectType type, SpellCastVisualField spellVisual)
{
SetMap(caster.GetMap());
Relocate(pos);
@@ -95,7 +95,11 @@ namespace Game.Entities
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), spellVisual.SpellXSpellVisualID);
SpellCastVisualField spellCastVisual = m_values.ModifyValue(m_dynamicObjectData).ModifyValue(m_dynamicObjectData.SpellVisual);
SetUpdateFieldValue(ref spellCastVisual.SpellXSpellVisualID, spellVisual.SpellXSpellVisualID);
SetUpdateFieldValue(ref spellCastVisual.ScriptVisualID, spellVisual.ScriptVisualID);
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), GameTime.GetGameTimeMS());
+2 -2
View File
@@ -82,7 +82,7 @@ namespace Game.Entities
for (int j = 0; j < SharedConst.MaxAzeriteEssenceSlot; ++j)
stmt.AddValue(5 + specIndex * 5 + j, m_azeriteItemData.SelectedEssences[specIndex].AzeriteEssenceID[j]);
}
for (; specIndex < PlayerConst.MaxSpecializations; ++specIndex)
for (; specIndex < 4; ++specIndex)
{
stmt.AddValue(4 + specIndex * 5, 0);
for (int j = 0; j < SharedConst.MaxAzeriteEssenceSlot; ++j)
@@ -557,6 +557,6 @@ namespace Game.Entities
public uint KnowledgeLevel;
public List<uint> AzeriteItemMilestonePowers = new List<uint>();
public List<AzeriteEssencePowerRecord> UnlockedAzeriteEssences = new List<AzeriteEssencePowerRecord>();
public AzeriteItemSelectedEssencesData[] SelectedAzeriteEssences = new AzeriteItemSelectedEssencesData[PlayerConst.MaxSpecializations];
public AzeriteItemSelectedEssencesData[] SelectedAzeriteEssences = new AzeriteItemSelectedEssencesData[4];
}
}
+90 -79
View File
@@ -1009,10 +1009,9 @@ namespace Game.Entities
gemBonus.AddBonusList(bonusListId);
uint gemBaseItemLevel = gemTemplate.GetBaseItemLevel();
ScalingStatDistributionRecord ssd = CliDB.ScalingStatDistributionStorage.LookupByKey(gemBonus.ScalingStatDistribution);
if (ssd != null)
if (gemBonus.PlayerLevelToItemLevelCurveId != 0)
{
uint scaledIlvl = (uint)Global.DB2Mgr.GetCurveValueAt(ssd.PlayerLevelToItemLevelCurveID, gemScalingLevel);
uint scaledIlvl = (uint)Global.DB2Mgr.GetCurveValueAt(gemBonus.PlayerLevelToItemLevelCurveId, gemScalingLevel);
if (scaledIlvl != 0)
gemBaseItemLevel = scaledIlvl;
}
@@ -1446,7 +1445,7 @@ namespace Game.Entities
Player owner = GetOwner();
for (byte i = 0; i < ItemConst.MaxStats; ++i)
{
if ((owner ? GetItemStatValue(i, owner) : proto.GetItemStatAllocation(i)) != 0)
if ((owner ? GetItemStatValue(i, owner) : proto.GetStatPercentEditor(i)) != 0)
return true;
}
@@ -1457,7 +1456,7 @@ namespace Game.Entities
{
for (byte i = 0; i < ItemConst.MaxStats; ++i)
{
if (bonus.ItemStatAllocation[i] != 0)
if (bonus.StatPercentEditor[i] != 0)
return true;
}
@@ -1767,22 +1766,18 @@ namespace Game.Entities
if (azeriteLevelInfo != null)
itemLevel = azeriteLevelInfo.ItemLevel;
ScalingStatDistributionRecord ssd = CliDB.ScalingStatDistributionStorage.LookupByKey(bonusData.ScalingStatDistribution);
if (ssd != null)
if (bonusData.PlayerLevelToItemLevelCurveId != 0)
{
if (fixedLevel != 0)
level = fixedLevel;
else
level = (uint)Math.Min(Math.Max(level, ssd.MinLevel), ssd.MaxLevel);
{
var levels = Global.DB2Mgr.GetContentTuningData(bonusData.ContentTuningId, 0, true);
if (levels.HasValue)
level = (uint)Math.Min(Math.Max((ushort)level, levels.Value.MinLevel), levels.Value.MaxLevel);
}
ContentTuningRecord contentTuning = CliDB.ContentTuningStorage.LookupByKey(bonusData.ContentTuningId);
if (contentTuning != null)
if ((Convert.ToBoolean(contentTuning.Flags & 2) || contentTuning.MinLevel != 0 || contentTuning.MaxLevel != 0) && !Convert.ToBoolean(contentTuning.Flags & 4))
level = (uint)Math.Min(Math.Max(level, contentTuning.MinLevel), contentTuning.MaxLevel);
uint heirloomIlvl = (uint)Global.DB2Mgr.GetCurveValueAt(ssd.PlayerLevelToItemLevelCurveID, level);
if (heirloomIlvl != 0)
itemLevel = heirloomIlvl;
itemLevel = (uint)Global.DB2Mgr.GetCurveValueAt(bonusData.PlayerLevelToItemLevelCurveId, level);
}
itemLevel += (uint)bonusData.ItemLevelBonus;
@@ -1814,7 +1809,7 @@ namespace Game.Entities
{
case ItemModType.Corruption:
case ItemModType.CorruptionResistance:
return _bonusData.ItemStatAllocation[index];
return _bonusData.StatPercentEditor[index];
default:
break;
}
@@ -1823,7 +1818,7 @@ namespace Game.Entities
uint randomPropPoints = ItemEnchantmentManager.GetRandomPropertyPoints(itemLevel, GetQuality(), GetTemplate().GetInventoryType(), GetTemplate().GetSubClass());
if (randomPropPoints != 0)
{
float statValue = (_bonusData.ItemStatAllocation[index] * randomPropPoints) * 0.0001f;
float statValue = (_bonusData.StatPercentEditor[index] * randomPropPoints) * 0.0001f;
GtItemSocketCostPerLevelRecord gtCost = CliDB.ItemSocketCostPerLevelGameTable.GetRow(itemLevel);
if (gtCost != null)
statValue -= (_bonusData.ItemStatSocketCostMultiplier[index] * gtCost.SocketCost);
@@ -1881,11 +1876,11 @@ namespace Game.Entities
public uint GetDisplayId(Player owner)
{
ItemModifier transmogModifier = ItemModifier.TransmogAppearanceAllSpecs;
if ((m_itemData.ModifiersMask & ItemConst.AppearanceModifierMaskSpecSpecific) != 0)
transmogModifier = ItemConst.AppearanceModifierSlotBySpec[owner.GetActiveTalentGroup()];
uint itemModifiedAppearanceId = GetModifier(ItemConst.AppearanceModifierSlotBySpec[owner.GetActiveTalentGroup()]);
if (itemModifiedAppearanceId == 0)
itemModifiedAppearanceId = GetModifier(ItemModifier.TransmogAppearanceAllSpecs);
ItemModifiedAppearanceRecord transmog = CliDB.ItemModifiedAppearanceStorage.LookupByKey(GetModifier(transmogModifier));
ItemModifiedAppearanceRecord transmog = CliDB.ItemModifiedAppearanceStorage.LookupByKey(itemModifiedAppearanceId);
if (transmog != null)
{
ItemAppearanceRecord itemAppearance = CliDB.ItemAppearanceStorage.LookupByKey(transmog.ItemAppearanceID);
@@ -1903,51 +1898,57 @@ namespace Game.Entities
public uint GetModifier(ItemModifier modifier)
{
if ((m_itemData.ModifiersMask & (1 << (int)modifier)) == 0)
return 0;
int modifierIndex = m_itemData.Modifiers._value.Values.FindIndexIf(mod =>
{
return mod.Type == (byte)modifier;
});
int valueIndex = 0;
uint mask = m_itemData.ModifiersMask;
for (int i = 0; i < (int)modifier; ++i)
if ((mask & (1 << i)) != 0)
++valueIndex;
if (modifierIndex != -1)
return m_itemData.Modifiers._value.Values[modifierIndex].Value;
return m_itemData.Modifiers[valueIndex];
return 0;
}
public void SetModifier(ItemModifier modifier, uint value)
{
int valueIndex = 0;
uint mask = m_itemData.ModifiersMask;
for (int i = 0; i < (int)modifier; ++i)
if ((mask & (1 << i)) != 0)
++valueIndex;
int modifierIndex = m_itemData.Modifiers._value.Values.FindIndexIf(mod =>
{
return mod.Type == (byte)modifier;
});
if (value != 0)
{
if ((mask & (1 << (int)modifier)) != 0)
return;
if (modifierIndex == -1)
{
ItemMod mod = new ItemMod();
mod.Value = value;
mod.Type = (byte)modifier;
SetUpdateFieldFlagValue(m_values.ModifyValue(m_itemData).ModifyValue(m_itemData.ModifiersMask), 1u << (int)modifier);
InsertDynamicUpdateFieldValue(m_values.ModifyValue(m_itemData).ModifyValue(m_itemData.Modifiers), valueIndex, value);
AddDynamicUpdateFieldValue(m_values.ModifyValue(m_itemData).ModifyValue(m_itemData.Modifiers)._value.ModifyValue(m_itemData.Modifiers._value.Values), mod);
}
else
{
ItemModList itemModList = m_values.ModifyValue(m_itemData).ModifyValue(m_itemData.Modifiers);
itemModList.ModifyValue(itemModList.Values, modifierIndex);
SetUpdateFieldValue(ref itemModList.ModifyValue(itemModList.Values, modifierIndex).GetValue().Value, value);
}
}
else
{
if ((mask & (1 << (int)modifier)) == 0)
if (modifierIndex == -1)
return;
RemoveUpdateFieldFlagValue(m_values.ModifyValue(m_itemData).ModifyValue(m_itemData.ModifiersMask), 1u << (int)modifier);
RemoveDynamicUpdateFieldValue(m_values.ModifyValue(m_itemData).ModifyValue(m_itemData.Modifiers), valueIndex);
RemoveDynamicUpdateFieldValue(m_values.ModifyValue(m_itemData).ModifyValue(m_itemData.Modifiers)._value.ModifyValue(m_itemData.Modifiers._value.Values), modifierIndex);
}
}
public uint GetVisibleEntry(Player owner)
{
ItemModifier transmogModifier = ItemModifier.TransmogAppearanceAllSpecs;
if ((m_itemData.ModifiersMask & ItemConst.AppearanceModifierMaskSpecSpecific) != 0)
transmogModifier = ItemConst.AppearanceModifierSlotBySpec[owner.GetActiveTalentGroup()];
uint itemModifiedAppearanceId = GetModifier(ItemConst.AppearanceModifierSlotBySpec[owner.GetActiveTalentGroup()]);
if (itemModifiedAppearanceId == 0)
itemModifiedAppearanceId = GetModifier(ItemModifier.TransmogAppearanceAllSpecs);
ItemModifiedAppearanceRecord transmog = CliDB.ItemModifiedAppearanceStorage.LookupByKey(GetModifier(transmogModifier));
ItemModifiedAppearanceRecord transmog = CliDB.ItemModifiedAppearanceStorage.LookupByKey(itemModifiedAppearanceId);
if (transmog != null)
return transmog.ItemID;
@@ -1956,11 +1957,11 @@ namespace Game.Entities
public ushort GetVisibleAppearanceModId(Player owner)
{
ItemModifier transmogModifier = ItemModifier.TransmogAppearanceAllSpecs;
if ((m_itemData.ModifiersMask & ItemConst.AppearanceModifierMaskSpecSpecific) != 0)
transmogModifier = ItemConst.AppearanceModifierSlotBySpec[owner.GetActiveTalentGroup()];
uint itemModifiedAppearanceId = GetModifier(ItemConst.AppearanceModifierSlotBySpec[owner.GetActiveTalentGroup()]);
if (itemModifiedAppearanceId == 0)
itemModifiedAppearanceId = GetModifier(ItemModifier.TransmogAppearanceAllSpecs);
ItemModifiedAppearanceRecord transmog = CliDB.ItemModifiedAppearanceStorage.LookupByKey(GetModifier(transmogModifier));
ItemModifiedAppearanceRecord transmog = CliDB.ItemModifiedAppearanceStorage.LookupByKey(itemModifiedAppearanceId);
if (transmog != null)
return transmog.ItemAppearanceModifierID;
@@ -1969,15 +1970,14 @@ namespace Game.Entities
public uint GetVisibleEnchantmentId(Player owner)
{
ItemModifier illusionModifier = ItemModifier.EnchantIllusionAllSpecs;
if ((m_itemData.ModifiersMask & ItemConst.IllusionModifierMaskSpecSpecific) != 0)
illusionModifier = ItemConst.IllusionModifierSlotBySpec[owner.GetActiveTalentGroup()];
uint enchantmentId = GetModifier(ItemConst.IllusionModifierSlotBySpec[owner.GetActiveTalentGroup()]);
if (enchantmentId == 0)
enchantmentId = GetModifier(ItemModifier.EnchantIllusionAllSpecs);
uint enchantIllusion = GetModifier(illusionModifier);
if (enchantIllusion != 0)
return enchantIllusion;
if (enchantmentId == 0)
enchantmentId = GetEnchantmentId(EnchantmentSlot.Perm);
return (uint)GetEnchantmentId(EnchantmentSlot.Perm);
return enchantmentId;
}
public ushort GetVisibleItemVisual(Player owner)
@@ -2255,15 +2255,11 @@ namespace Game.Entities
if (!_bonusData.HasFixedLevel || GetModifier(ItemModifier.TimewalkerLevel) != 0)
return;
ScalingStatDistributionRecord ssd = CliDB.ScalingStatDistributionStorage.LookupByKey(_bonusData.ScalingStatDistribution);
if (ssd != null)
if (_bonusData.PlayerLevelToItemLevelCurveId != 0)
{
level = (uint)Math.Min(Math.Max(level, ssd.MinLevel), ssd.MaxLevel);
ContentTuningRecord contentTuning = CliDB.ContentTuningStorage.LookupByKey(_bonusData.ContentTuningId);
if (contentTuning != null)
if ((contentTuning.Flags.HasAnyFlag(2) || contentTuning.MinLevel != 0 || contentTuning.MaxLevel != 0) && !contentTuning.Flags.HasAnyFlag(4))
level = (uint)Math.Min(Math.Max(level, contentTuning.MinLevel), contentTuning.MaxLevel);
var levels = Global.DB2Mgr.GetContentTuningData(_bonusData.ContentTuningId, 0, true);
if (levels.HasValue)
level = (uint)Math.Min(Math.Max((short)level, levels.Value.MinLevel), levels.Value.MaxLevel);
SetModifier(ItemModifier.TimewalkerLevel, level);
}
@@ -2271,12 +2267,14 @@ namespace Game.Entities
public int GetRequiredLevel()
{
int fixedLevel = (int)GetModifier(ItemModifier.TimewalkerLevel);
if (_bonusData.RequiredLevelCurve != 0)
return (int)Global.DB2Mgr.GetCurveValueAt(_bonusData.RequiredLevelCurve, fixedLevel);
if (_bonusData.RequiredLevelOverride != 0)
return _bonusData.RequiredLevelOverride;
else if (_bonusData.HasFixedLevel)
return (int)GetModifier(ItemModifier.TimewalkerLevel);
else
return _bonusData.RequiredLevel;
if (_bonusData.HasFixedLevel && _bonusData.PlayerLevelToItemLevelCurveId != 0)
return fixedLevel;
return _bonusData.RequiredLevel;
}
public static Item NewItemOrBag(ItemTemplate proto)
@@ -2515,7 +2513,7 @@ namespace Game.Entities
public uint GetAppearanceModId() { return m_itemData.ItemAppearanceModID; }
public void SetAppearanceModId(uint appearanceModId) { SetUpdateFieldValue(m_values.ModifyValue(m_itemData).ModifyValue(m_itemData.ItemAppearanceModID), (byte)appearanceModId); }
public float GetRepairCostMultiplier() { return _bonusData.RepairCostMultiplier; }
public uint GetScalingStatDistribution() { return _bonusData.ScalingStatDistribution; }
public uint GetScalingContentTuningId() { return _bonusData.ContentTuningId; }
public void SetRefundRecipient(ObjectGuid guid) { m_refundRecipient = guid; }
public void SetPaidMoney(ulong money) { m_paidMoney = money; }
@@ -2685,13 +2683,13 @@ namespace Game.Entities
ItemLevelBonus = 0;
RequiredLevel = proto.GetBaseRequiredLevel();
for (uint i = 0; i < ItemConst.MaxStats; ++i)
ItemStatType[i] = proto.GetItemStatType(i);
ItemStatType[i] = proto.GetStatModifierBonusStat(i);
for (uint i = 0; i < ItemConst.MaxStats; ++i)
ItemStatAllocation[i] = proto.GetItemStatAllocation(i);
StatPercentEditor[i] = proto.GetStatPercentEditor(i);
for (uint i = 0; i < ItemConst.MaxStats; ++i)
ItemStatSocketCostMultiplier[i] = proto.GetItemStatSocketCostMultiplier(i);
ItemStatSocketCostMultiplier[i] = proto.GetStatPercentageOfSocket(i);
for (uint i = 0; i < ItemConst.MaxGemSockets; ++i)
{
@@ -2705,7 +2703,8 @@ namespace Game.Entities
AppearanceModID = 0;
RepairCostMultiplier = 1.0f;
ScalingStatDistribution = proto.GetScalingStatDistribution();
ContentTuningId = proto.GetScalingStatContentTuning();
PlayerLevelToItemLevelCurveId = proto.GetPlayerLevelToItemLevelCurveId();
RelicType = -1;
HasFixedLevel = false;
RequiredLevelOverride = 0;
@@ -2729,6 +2728,7 @@ namespace Game.Entities
_state.AppearanceModPriority = int.MaxValue;
_state.ScalingStatDistributionPriority = int.MaxValue;
_state.AzeriteTierUnlockSetPriority = int.MaxValue;
_state.RequiredLevelCurvePriority = int.MaxValue;
_state.HasQualityBonus = false;
}
@@ -2766,7 +2766,7 @@ namespace Game.Entities
if (statIndex < ItemConst.MaxStats)
{
ItemStatType[statIndex] = values[0];
ItemStatAllocation[statIndex] += values[1];
StatPercentEditor[statIndex] += values[1];
}
break;
}
@@ -2816,8 +2816,8 @@ namespace Game.Entities
case ItemBonusType.ScalingStatDistributionFixed:
if (values[1] < _state.ScalingStatDistributionPriority)
{
ScalingStatDistribution = (uint)values[0];
ContentTuningId = (uint)values[2];
PlayerLevelToItemLevelCurveId = (uint)values[3];
_state.ScalingStatDistributionPriority = values[1];
HasFixedLevel = type == ItemBonusType.ScalingStatDistributionFixed;
}
@@ -2849,6 +2849,15 @@ namespace Game.Entities
if (itemEffect != null)
Effects[EffectCount++] = itemEffect;
break;
case ItemBonusType.RequiredLevelCurve:
if (values[2] < _state.RequiredLevelCurvePriority)
{
RequiredLevelCurve = (uint)values[0];
_state.RequiredLevelCurvePriority = values[2];
if (values[1] != 0)
ContentTuningId = (uint)values[1];
}
break;
}
}
@@ -2856,14 +2865,14 @@ namespace Game.Entities
public int ItemLevelBonus;
public int RequiredLevel;
public int[] ItemStatType = new int[ItemConst.MaxStats];
public int[] ItemStatAllocation = new int[ItemConst.MaxStats];
public int[] StatPercentEditor = new int[ItemConst.MaxStats];
public float[] ItemStatSocketCostMultiplier = new float[ItemConst.MaxStats];
public SocketColor[] socketColor = new SocketColor[ItemConst.MaxGemSockets];
public ItemBondingType Bonding;
public uint AppearanceModID;
public float RepairCostMultiplier;
public uint ScalingStatDistribution;
public uint ContentTuningId;
public uint PlayerLevelToItemLevelCurveId;
public uint DisenchantLootId;
public uint[] GemItemLevelBonus = new uint[ItemConst.MaxGemSockets];
public int[] GemRelicType = new int[ItemConst.MaxGemSockets];
@@ -2872,6 +2881,7 @@ namespace Game.Entities
public int RequiredLevelOverride;
public uint AzeriteTierUnlockSetId;
public uint Suffix;
public uint RequiredLevelCurve;
public ItemEffectRecord[] Effects = new ItemEffectRecord[13];
public int EffectCount;
public bool CanDisenchant;
@@ -2885,6 +2895,7 @@ namespace Game.Entities
public int AppearanceModPriority;
public int ScalingStatDistributionPriority;
public int AzeriteTierUnlockSetPriority;
public int RequiredLevelCurvePriority;
public bool HasQualityBonus;
}
}
@@ -2972,7 +2983,7 @@ namespace Game.Entities
info.AzeriteItem.Xp = azeriteItemResult.Read<ulong>(1);
info.AzeriteItem.Level = azeriteItemResult.Read<uint>(2);
info.AzeriteItem.KnowledgeLevel = azeriteItemResult.Read<uint>(3);
for (int i = 0; i < PlayerConst.MaxSpecializations; ++i)
for (int i = 0; i < info.AzeriteItem.SelectedAzeriteEssences.Length; ++i)
{
uint specializationId = azeriteItemResult.Read<uint>(4 + i * 4);
if (!CliDB.ChrSpecializationStorage.ContainsKey(specializationId))
+5 -16
View File
@@ -277,22 +277,11 @@ namespace Game.Entities
public uint GetRequiredReputationRank() { return ExtendedData.MinReputation; }
public uint GetMaxCount() { return ExtendedData.MaxCount; }
public uint GetContainerSlots() { return ExtendedData.ContainerSlots; }
public int GetItemStatType(uint index)
{
Cypher.Assert(index < ItemConst.MaxStats);
return ExtendedData.StatModifierBonusStat[index];
}
public int GetItemStatAllocation(uint index)
{
Cypher.Assert(index < ItemConst.MaxStats);
return ExtendedData.StatPercentEditor[index];
}
public float GetItemStatSocketCostMultiplier(uint index)
{
Cypher.Assert(index < ItemConst.MaxStats);
return ExtendedData.StatPercentageOfSocket[index];
}
public uint GetScalingStatDistribution() { return ExtendedData.ScalingStatDistributionID; }
public int GetStatModifierBonusStat(uint index) { Cypher.Assert(index < ItemConst.MaxStats); return ExtendedData.StatModifierBonusStat[index]; }
public int GetStatPercentEditor(uint index) { Cypher.Assert(index < ItemConst.MaxStats); return ExtendedData.StatPercentEditor[index]; }
public float GetStatPercentageOfSocket(uint index) { Cypher.Assert(index < ItemConst.MaxStats); return ExtendedData.StatPercentageOfSocket[index]; }
public uint GetScalingStatContentTuning() { return ExtendedData.ContentTuningID; }
public uint GetPlayerLevelToItemLevelCurveId() { return ExtendedData.PlayerLevelToItemLevelCurveID; }
public uint GetDamageType() { return ExtendedData.DamageType; }
public uint GetDelay() { return ExtendedData.ItemDelay; }
public float GetRangedModRange() { return ExtendedData.ItemRange; }
File diff suppressed because it is too large Load Diff
+207 -131
View File
@@ -1832,6 +1832,38 @@ namespace Game.Entities
pair.Value.state = PlayerCurrencyState.Unchanged;
}
}
public static void SavePlayerCustomizations(SQLTransaction trans, ulong guid, List<ChrCustomizationChoice> customizations)
{
PreparedStatement stmt = DB.Characters.GetPreparedStatement(CharStatements.DEL_CHARACTER_CUSTOMIZATIONS);
stmt.AddValue(0, guid);
trans.Append(stmt);
foreach (var customization in customizations)
{
stmt = DB.Characters.GetPreparedStatement(CharStatements.INS_CHARACTER_CUSTOMIZATION);
stmt.AddValue(0, guid);
stmt.AddValue(1, customization.ChrCustomizationOptionID);
stmt.AddValue(2, customization.ChrCustomizationChoiceID);
trans.Append(stmt);
}
}
public static void SaveCustomizations(SQLTransaction trans, ulong guid, List<ChrCustomizationChoice> customizations)
{
SavePlayerCustomizations(trans, guid, customizations);
}
void _SaveCustomizations(SQLTransaction trans)
{
if (!m_customizationsChanged)
return;
m_customizationsChanged = false;
SavePlayerCustomizations(trans, GetGUID().GetCounter(), m_playerData.Customizations);
}
void _SaveActions(SQLTransaction trans)
{
PreparedStatement stmt = null;
@@ -2418,19 +2450,86 @@ namespace Game.Entities
SQLResult result = holder.GetResult(PlayerLoginQueryLoad.From);
if (result.IsEmpty())
{
string name;
Global.CharacterCacheStorage.GetCharacterNameByGuid(guid, out name);
Log.outError(LogFilter.Player, "Player {0} {1} not found in table `characters`, can't load. ", name, guid.ToString());
Global.CharacterCacheStorage.GetCharacterNameByGuid(guid, out string cacheName);
Log.outError(LogFilter.Player, "Player {0} {1} not found in table `characters`, can't load. ", cacheName, guid.ToString());
return false;
}
uint dbAccountId = result.Read<uint>(1);
int fieldIndex = 1;
uint accountId = result.Read<uint>(fieldIndex++);
string name = result.Read<string>(fieldIndex++);
Race race = (Race)result.Read<byte>(fieldIndex++);
Class class_ = (Class)result.Read<byte>(fieldIndex++);
Gender gender = (Gender)result.Read<byte>(fieldIndex++);
byte level = result.Read<byte>(fieldIndex++);
uint xp = result.Read<uint>(fieldIndex++);
ulong money = result.Read<ulong>(fieldIndex++);
byte inventorySlots = result.Read<byte>(fieldIndex++);
byte bankSlots = result.Read<byte>(fieldIndex++);
PlayerRestState restState = (PlayerRestState)result.Read<byte>(fieldIndex++);
PlayerFlags playerFlags = (PlayerFlags)result.Read<uint>(fieldIndex++);
PlayerFlagsEx playerFlagsEx = (PlayerFlagsEx)result.Read<uint>(fieldIndex++);
float position_x = result.Read<float>(fieldIndex++);
float position_y = result.Read<float>(fieldIndex++);
float position_z = result.Read<float>(fieldIndex++);
uint mapId = result.Read<ushort>(fieldIndex++);
float orientation = result.Read<float>(fieldIndex++);
string taximask = result.Read<string>(fieldIndex++);
byte cinematic = result.Read<byte>(fieldIndex++);
uint totaltime = result.Read<uint> (fieldIndex++);
uint leveltime = result.Read<uint>(fieldIndex++);
float rest_bonus = result.Read<float>(fieldIndex++);
uint logout_time = result.Read<uint>(fieldIndex++);
byte is_logout_resting = result.Read<byte>(fieldIndex++);
uint resettalents_cost = result.Read<uint>(fieldIndex++);
uint resettalents_time = result.Read<uint>(fieldIndex++);
uint primarySpecialization = result.Read<uint>(fieldIndex++);
float trans_x = result.Read<float>(fieldIndex++);
float trans_y = result.Read<float>(fieldIndex++);
float trans_z = result.Read<float>(fieldIndex++);
float trans_o = result.Read<float>(fieldIndex++);
ulong transguid = result.Read<ulong>(fieldIndex++);
PlayerExtraFlags extra_flags = (PlayerExtraFlags)result.Read<ushort>(fieldIndex++);
byte stable_slots = result.Read<byte>(fieldIndex++);
ushort at_login = result.Read<ushort>(fieldIndex++);
ushort zone = result.Read<ushort>(fieldIndex++);
byte online = result.Read<byte>(fieldIndex++);
uint death_expire_time = result.Read<uint>(fieldIndex++);
string taxi_path = result.Read<string>(fieldIndex++);
Difficulty dungeonDifficulty = (Difficulty)result.Read<byte>(fieldIndex++);
uint totalKills = result.Read<uint>(fieldIndex++);
ushort todayKills = result.Read<ushort>(fieldIndex++);
ushort yesterdayKills = result.Read<ushort>(fieldIndex++);
uint chosenTitle = result.Read<uint>(fieldIndex++);
uint watchedFaction = result.Read<uint>(fieldIndex++);
byte drunk = result.Read<byte>(fieldIndex++);
uint health = result.Read<uint>(fieldIndex++);
uint[] powers = new uint[(int)PowerType.MaxPerClass];
for (var i = 0; fieldIndex < powers.Length; ++i)
powers[i] = result.Read<uint>(fieldIndex++);
uint instance_id = result.Read<uint>(fieldIndex++);
byte activeTalentGroup = result.Read<byte>(fieldIndex++);
uint lootSpecId = result.Read<uint>(fieldIndex++);
string exploredZones = result.Read<string>(fieldIndex++);
string knownTitles = result.Read<string>(fieldIndex++);
byte actionBars = result.Read<byte>(fieldIndex++);
Difficulty raidDifficulty = (Difficulty)result.Read<byte>(fieldIndex++);
Difficulty legacyRaidDifficulty = (Difficulty)result.Read<byte>(fieldIndex++);
byte fishingSteps = result.Read<byte>(fieldIndex++);
uint honor = result.Read<uint>(fieldIndex++);
uint honorLevel = result.Read<uint>(fieldIndex++);
PlayerRestState honorRestState = (PlayerRestState)result.Read<byte>(fieldIndex++);
float honorRestBonus = result.Read<float>(fieldIndex++);
byte numRespecs = result.Read<byte>(fieldIndex++);
// check if the character's account in the db and the logged in account match.
// player should be able to load/delete character only with correct account!
if (dbAccountId != GetSession().GetAccountId())
if (accountId != GetSession().GetAccountId())
{
Log.outError(LogFilter.Player, "Player (GUID: {0}) loading from wrong account (is: {1}, should be: {2})", GetGUID().ToString(), GetSession().GetAccountId(), dbAccountId);
Log.outError(LogFilter.Player, "Player (GUID: {0}) loading from wrong account (is: {1}, should be: {2})", GetGUID().ToString(), GetSession().GetAccountId(), accountId);
return false;
}
@@ -2443,7 +2542,7 @@ namespace Game.Entities
_Create(guid);
SetName(result.Read<string>(2));
SetName(name);
// check name limitations
if (ObjectManager.CheckPlayerName(GetName(), GetSession().GetSessionDbcLocale()) != ResponseCodes.CharNameSuccess ||
@@ -2456,18 +2555,18 @@ namespace Game.Entities
return false;
}
// overwrite possible wrong/corrupted guid
SetUpdateFieldValue(m_values.ModifyValue(m_playerData).ModifyValue(m_playerData.WowAccount), GetSession().GetAccountGUID());
Gender gender = (Gender)result.Read<byte>(5);
SetUpdateFieldValue(m_values.ModifyValue(m_playerData).ModifyValue(m_playerData.WowAccount), GetSession().GetAccountGUID());
SetUpdateFieldValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.BnetAccount), GetSession().GetBattlenetAccountGUID());
if (gender >= Gender.None)
{
Log.outError(LogFilter.Player, "Player {0} has wrong gender ({1}), can't be loaded.", guid.ToString(), gender);
return false;
}
SetRace((Race)result.Read<byte>(3));
SetClass((Class)result.Read<byte>(4));
SetRace(race);
SetClass(class_);
SetGender(gender);
// check if race/class combination is valid
@@ -2478,19 +2577,19 @@ namespace Game.Entities
return false;
}
SetLevel(result.Read<uint>(6));
SetXP(result.Read<uint>(7));
SetLevel(level);
SetXP(xp);
StringArray exploredZones = new StringArray(result.Read<string>(66), ' ');
if (exploredZones.Length == PlayerConst.ExploredZonesSize * 2)
for (int i = 0; i < exploredZones.Length; ++i)
SetUpdateFieldFlagValue(ref m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.ExploredZones, i / 2), (ulong)((long.Parse(exploredZones[i])) << (32 * (i % 2))));
StringArray exploredZonesStrings = new StringArray(exploredZones, ' ');
if (exploredZonesStrings.Length == PlayerConst.ExploredZonesSize * 2)
for (int i = 0; i < exploredZonesStrings.Length; ++i)
SetUpdateFieldFlagValue(ref m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.ExploredZones, i / 2), (ulong)((long.Parse(exploredZonesStrings[i])) << (32 * (i % 2))));
StringArray knownTitles = new StringArray(result.Read<string>(67), ' ');
if ((knownTitles.Length % 2) == 0)
StringArray knownTitlesStrings = new StringArray(knownTitles, ' ');
if ((knownTitlesStrings.Length % 2) == 0)
{
for (int i = 0; i < knownTitles.Length; ++i)
SetUpdateFieldFlagValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.KnownTitles, i / 2), (ulong)((long.Parse(knownTitles[i])) << (32 * (i % 2))));
for (int i = 0; i < knownTitlesStrings.Length; ++i)
SetUpdateFieldFlagValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.KnownTitles, i / 2), (ulong)((long.Parse(knownTitlesStrings[i])) << (32 * (i % 2))));
}
SetObjectScale(1.0f);
@@ -2500,42 +2599,42 @@ namespace Game.Entities
m_achievementSys.LoadFromDB(holder.GetResult(PlayerLoginQueryLoad.Achievements), holder.GetResult(PlayerLoginQueryLoad.CriteriaProgress));
m_questObjectiveCriteriaMgr.LoadFromDB(holder.GetResult(PlayerLoginQueryLoad.QuestStatusObjectivesCriteria), holder.GetResult(PlayerLoginQueryLoad.QuestStatusObjectivesCriteriaProgress));
ulong money = result.Read<ulong>(8);
if (money > PlayerConst.MaxMoneyAmount)
money = PlayerConst.MaxMoneyAmount;
SetMoney(money);
SetMoney(Math.Min(money, PlayerConst.MaxMoneyAmount));
Array<byte> customDisplay = new Array<byte>(PlayerConst.CustomDisplaySize);
customDisplay[0] = result.Read<byte>(14);
customDisplay[1] = result.Read<byte>(15);
customDisplay[2] = result.Read<byte>(16);
List<ChrCustomizationChoice> customizations = new List<ChrCustomizationChoice>();
SQLResult customizationsResult = holder.GetResult(PlayerLoginQueryLoad.Customizations);
if (!customizationsResult.IsEmpty())
{
do
{
SetSkinId(result.Read<byte>(9));
SetFaceId(result.Read<byte>(10));
SetHairStyleId(result.Read<byte>(11));
SetHairColorId(result.Read<byte>(12));
SetFacialHairStyleId(result.Read<byte>(13));
for (byte i = 0; i < PlayerConst.CustomDisplaySize; ++i)
SetCustomDisplayOption(i, customDisplay[i]);
SetInventorySlotCount(result.Read<byte>(17));
SetBankBagSlotCount(result.Read<byte>(18));
ChrCustomizationChoice choice;
choice.ChrCustomizationOptionID = customizationsResult.Read<uint>(0);
choice.ChrCustomizationChoiceID = customizationsResult.Read<uint>(1);
customizations.Add(choice);
} while (customizationsResult.NextRow());
}
SetCustomizations(customizations, false);
SetInventorySlotCount(inventorySlots);
SetBankBagSlotCount(bankSlots);
SetNativeSex(gender);
SetUpdateFieldValue(m_values.ModifyValue(m_playerData).ModifyValue(m_playerData.Inebriation), result.Read<byte>(55));
SetPlayerFlags((PlayerFlags)result.Read<uint>(20));
SetPlayerFlagsEx((PlayerFlagsEx)result.Read<uint>(21));
SetWatchedFactionIndex(result.Read<uint>(54));
SetUpdateFieldValue(m_values.ModifyValue(m_playerData).ModifyValue(m_playerData.Inebriation), drunk);
SetPlayerFlags(playerFlags);
SetPlayerFlagsEx(playerFlagsEx);
SetWatchedFactionIndex(watchedFaction);
if (!ValidateAppearance((Race)result.Read<byte>(3), (Class)result.Read<byte>(4), (Gender)gender,
m_playerData.HairStyleID, m_playerData.HairColorID, m_playerData.FaceID, m_playerData.FacialHairStyleID, m_playerData.SkinID, customDisplay))
if (!GetSession().ValidateAppearance(GetRace(), GetClass(), gender, customizations))
{
Log.outError(LogFilter.Player, "Player {0} has wrong Appearance values (Hair/Skin/Color), can't be loaded.", guid.ToString());
return false;
}
// set which actionbars the client has active - DO NOT REMOVE EVER AGAIN (can be changed though, if it does change fieldwise)
SetMultiActionBars(result.Read<byte>(68));
SetMultiActionBars(actionBars);
m_fishingSteps = result.Read<byte>(71);
m_fishingSteps = fishingSteps;
InitDisplayIds();
@@ -2560,27 +2659,20 @@ namespace Game.Entities
InitPrimaryProfessions(); // to max set before any spell loaded
// init saved position, and fix it later if problematic
ulong transLowGUID = result.Read<ulong>(41);
Relocate(position_x, position_y, position_z, orientation);
Relocate(result.Read<float>(22), result.Read<float>(23), result.Read<float>(24), result.Read<float>(26));
SetDungeonDifficultyID(CheckLoadedDungeonDifficultyID(dungeonDifficulty));
SetRaidDifficultyID(CheckLoadedRaidDifficultyID(raidDifficulty));
SetLegacyRaidDifficultyID(CheckLoadedLegacyRaidDifficultyID(legacyRaidDifficulty));
uint mapId = result.Read<uint>(25);
uint instanceId = result.Read<uint>(63);
var RelocateToHomebind = new Action(() => { mapId = homebind.GetMapId(); instanceId = 0; Relocate(homebind); });
SetDungeonDifficultyID(CheckLoadedDungeonDifficultyID((Difficulty)result.Read<byte>(49)));
SetRaidDifficultyID(CheckLoadedRaidDifficultyID((Difficulty)result.Read<byte>(69)));
SetLegacyRaidDifficultyID(CheckLoadedLegacyRaidDifficultyID((Difficulty)result.Read<byte>(70)));
string taxi_nodes = result.Read<string>(48);
var RelocateToHomebind = new Action(() => { mapId = (ushort)homebind.GetMapId(); instance_id = 0; Relocate(homebind); });
_LoadGroup(holder.GetResult(PlayerLoginQueryLoad.Group));
_LoadCurrency(holder.GetResult(PlayerLoginQueryLoad.Currency));
SetUpdateFieldValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.LifetimeHonorableKills), result.Read<uint>(50));
SetUpdateFieldValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.TodayHonorableKills), result.Read<ushort>(51));
SetUpdateFieldValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.YesterdayHonorableKills), result.Read<ushort>(52));
SetUpdateFieldValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.LifetimeHonorableKills), totalKills);
SetUpdateFieldValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.TodayHonorableKills), todayKills);
SetUpdateFieldValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.YesterdayHonorableKills), yesterdayKills);
_LoadBoundInstances(holder.GetResult(PlayerLoginQueryLoad.BoundInstances));
_LoadInstanceTimeRestrictions(holder.GetResult(PlayerLoginQueryLoad.InstanceLockTimes));
@@ -2632,7 +2724,7 @@ namespace Game.Entities
// Do not look for instance if bg not found
WorldLocation _loc = GetBattlegroundEntryPoint();
mapId = _loc.GetMapId();
instanceId = 0;
instance_id = 0;
if (mapId == 0xFFFFFFFF) // BattlegroundEntry Point not found (???)
{
@@ -2647,9 +2739,9 @@ namespace Game.Entities
}
}
// currently we do not support transport in bg
else if (transLowGUID != 0)
else if (transguid != 0)
{
ObjectGuid transGUID = ObjectGuid.Create(HighGuid.Transport, transLowGUID);
ObjectGuid transGUID = ObjectGuid.Create(HighGuid.Transport, transguid);
Transport transport = null;
Transport go = Global.ObjAccessor.FindTransport(transGUID);
@@ -2658,10 +2750,11 @@ namespace Game.Entities
if (transport)
{
float x = result.Read<float>(37);
float y = result.Read<float>(38);
float z = result.Read<float>(39);
float o = result.Read<float>(40);
float x = trans_x;
float y = trans_y;
float z = trans_z;
float o = trans_o;
m_movementInfo.transport.pos = new Position(x, y, z, o);
transport.CalculatePassengerPosition(ref x, ref y, ref z, ref o);
@@ -2671,8 +2764,7 @@ namespace Game.Entities
Math.Abs(m_movementInfo.transport.pos.posY) > 250.0f ||
Math.Abs(m_movementInfo.transport.pos.posZ) > 250.0f)
{
Log.outError(LogFilter.Player, "Player (guidlow {0}) have invalid transport coordinates (X: {1} Y: {2} Z: {3} O: {4}). Teleport to bind location.",
guid.ToString(), x, y, z, o);
Log.outError(LogFilter.Player, "Player (guidlow {0}) have invalid transport coordinates (X: {1} Y: {2} Z: {3} O: {4}). Teleport to bind location.", guid.ToString(), x, y, z, o);
m_movementInfo.transport.Reset();
RelocateToHomebind();
@@ -2687,16 +2779,15 @@ namespace Game.Entities
}
else
{
Log.outError(LogFilter.Player, "Player (guidlow {0}) have problems with transport guid ({1}). Teleport to bind location.",
guid.ToString(), transLowGUID);
Log.outError(LogFilter.Player, "Player (guidlow {0}) have problems with transport guid ({1}). Teleport to bind location.", guid.ToString(), transguid);
RelocateToHomebind();
}
}
// currently we do not support taxi in instance
else if (!string.IsNullOrEmpty(taxi_nodes))
else if (!taxi_path.IsEmpty())
{
instanceId = 0;
instance_id = 0;
// Not finish taxi flight path
if (m_bgData.HasTaxiPath())
@@ -2704,7 +2795,7 @@ namespace Game.Entities
for (int i = 0; i < 2; ++i)
m_taxi.AddTaxiDestination(m_bgData.taxiPath[i]);
}
if (!m_taxi.LoadTaxiDestinationsFromString(taxi_nodes, GetTeam()))
if (!m_taxi.LoadTaxiDestinationsFromString(taxi_path, GetTeam()))
{
// problems with taxi path loading
TaxiNodesRecord nodeEntry = null;
@@ -2753,19 +2844,20 @@ namespace Game.Entities
}
// fix crash (because of if (Map* map = _FindMap(instanceId)) in MapInstanced.CreateInstance)
if (instanceId != 0)
if (instance_id != 0)
{
InstanceSave save = GetInstanceSave(mapId);
if (save != null)
if (save.GetInstanceId() != instanceId)
instanceId = 0;
if (save.GetInstanceId() != instance_id)
instance_id = 0;
}
}
// NOW player must have valid map
// load the player's map here if it's not already loaded
if (!map)
map = Global.MapMgr.CreateMap(mapId, this, instanceId);
map = Global.MapMgr.CreateMap(mapId, this, instance_id);
AreaTriggerStruct areaTrigger = null;
bool check = false;
@@ -2802,7 +2894,7 @@ namespace Game.Entities
areaTrigger = Global.ObjectMgr.GetGoBackTrigger(mapId);
check = true;
}
else if (instanceId != 0 && Global.InstanceSaveMgr.GetInstanceSave(instanceId) == null) // ... and instance is reseted then look for entrance.
else if (instance_id != 0 && Global.InstanceSaveMgr.GetInstanceSave(instance_id) == null) // ... and instance is reseted then look for entrance.
{
areaTrigger = Global.ObjectMgr.GetMapEntranceTrigger(mapId);
check = true;
@@ -2857,7 +2949,7 @@ namespace Game.Entities
SaveRecallPosition();
long now = Time.UnixTime;
long logoutTime = result.Read<int>(32);
long logoutTime = logout_time;
// since last logout (in seconds)
uint time_diff = (uint)(now - logoutTime);
@@ -2870,32 +2962,30 @@ namespace Game.Entities
SetDrunkValue(newDrunkValue);
m_cinematic = result.Read<byte>(28);
m_PlayedTimeTotal = result.Read<uint>(29);
m_PlayedTimeLevel = result.Read<uint>(30);
m_cinematic = cinematic;
m_PlayedTimeTotal = totaltime;
m_PlayedTimeLevel = leveltime;
SetTalentResetCost(result.Read<uint>(34));
SetTalentResetTime(result.Read<uint>(35));
SetTalentResetCost(resettalents_cost);
SetTalentResetTime(resettalents_time);
m_taxi.LoadTaxiMask(result.Read<string>(27)); // must be before InitTaxiNodesForLevel
m_taxi.LoadTaxiMask(taximask); // must be before InitTaxiNodesForLevel
PlayerExtraFlags extraflags = (PlayerExtraFlags)result.Read<uint>(42);
m_stableSlots = result.Read<byte>(43);
m_stableSlots = stable_slots;
if (m_stableSlots > 4)
{
Log.outError(LogFilter.Player, "Player can have not more {0} stable slots, but have in DB {1}", 4, m_stableSlots);
m_stableSlots = 4;
}
atLoginFlags = (AtLoginFlags)result.Read<uint>(44);
atLoginFlags = (AtLoginFlags)at_login;
// Honor system
// Update Honor kills data
m_lastHonorUpdateTime = logoutTime;
UpdateHonorFields();
m_deathExpireTime = result.Read<uint>(47);
m_deathExpireTime = death_expire_time;
if (m_deathExpireTime > now + PlayerConst.MaxDeathCount * PlayerConst.DeathExpireStep)
m_deathExpireTime = now + PlayerConst.MaxDeathCount * PlayerConst.DeathExpireStep - 1;
@@ -2910,20 +3000,19 @@ namespace Game.Entities
InitRunes();
// rest bonus can only be calculated after InitStatsForLevel()
_restMgr.LoadRestBonus(RestTypes.XP, (PlayerRestState)result.Read<byte>(19), result.Read<float>(31));
_restMgr.LoadRestBonus(RestTypes.XP, restState, rest_bonus);
// load skills after InitStatsForLevel because it triggering aura apply also
_LoadSkills(holder.GetResult(PlayerLoginQueryLoad.Skills));
UpdateSkillsForLevel();
SetNumRespecs(result.Read<byte>(76));
SetPrimarySpecialization(result.Read<uint>(36));
SetActiveTalentGroup(result.Read<byte>(64));
SetNumRespecs(numRespecs);
SetPrimarySpecialization(primarySpecialization);
SetActiveTalentGroup(activeTalentGroup);
ChrSpecializationRecord primarySpec = CliDB.ChrSpecializationStorage.LookupByKey(GetPrimarySpecialization());
if (primarySpec == null || primarySpec.ClassID != (byte)GetClass() || GetActiveTalentGroup() >= PlayerConst.MaxSpecializations)
ResetTalentSpecialization();
uint lootSpecId = result.Read<byte>(65);
ChrSpecializationRecord chrSpec = CliDB.ChrSpecializationStorage.LookupByKey(lootSpecId);
if (chrSpec != null)
{
@@ -2986,11 +3075,10 @@ namespace Game.Entities
// check PLAYER_CHOSEN_TITLE compatibility with PLAYER__FIELD_KNOWN_TITLES
// note: PLAYER__FIELD_KNOWN_TITLES updated at quest status loaded
uint curTitle = result.Read<uint>(53);
if (curTitle != 0 && !HasTitle(curTitle))
curTitle = 0;
if (chosenTitle != 0 && !HasTitle(chosenTitle))
chosenTitle = 0;
SetChosenTitle(curTitle);
SetChosenTitle(chosenTitle);
// has to be called after last Relocate() in Player.LoadFromDB
SetFallInformation(0, GetPositionZ());
@@ -3009,14 +3097,13 @@ namespace Game.Entities
UpdateAllStats();
// restore remembered power/health values (but not more max values)
uint savedHealth = result.Read<uint>(56);
SetHealth(savedHealth > GetMaxHealth() ? GetMaxHealth() : savedHealth);
SetHealth(health > GetMaxHealth() ? GetMaxHealth() : health);
int loadedPowers = 0;
for (PowerType i = 0; i < PowerType.Max; ++i)
{
if (Global.DB2Mgr.GetPowerIndexByClass(i, GetClass()) != (int)PowerType.Max)
{
uint savedPower = result.Read<uint>(56 + loadedPowers);
uint savedPower = powers[loadedPowers];
uint maxPower = m_unitData.MaxPower[loadedPowers];
SetPower(i, (int)(savedPower > maxPower ? maxPower : savedPower));
if (++loadedPowers >= (int)PowerType.MaxPerClass)
@@ -3025,7 +3112,7 @@ namespace Game.Entities
}
for (; loadedPowers < (int)PowerType.MaxPerClass; ++loadedPowers)
SetUpdateFieldValue(ref m_values.ModifyValue(m_unitData).ModifyValue(m_unitData.Power, (int)loadedPowers), 0);
SetUpdateFieldValue(ref m_values.ModifyValue(m_unitData).ModifyValue(m_unitData.Power, loadedPowers), 0);
SetPower(PowerType.LunarPower, 0);
// Init rune recharge
@@ -3054,7 +3141,7 @@ namespace Game.Entities
case 1: SetGameMaster(true);
break; // enable
case 2: // save state
if (extraflags.HasAnyFlag(PlayerExtraFlags.GMOn))
if (extra_flags.HasAnyFlag(PlayerExtraFlags.GMOn))
SetGameMaster(true);
break;
}
@@ -3067,7 +3154,7 @@ namespace Game.Entities
case 1:
break; // visible
case 2: // save state
if (extraflags.HasAnyFlag(PlayerExtraFlags.GMInvisible))
if (extra_flags.HasAnyFlag(PlayerExtraFlags.GMInvisible))
SetGMVisible(false);
break;
}
@@ -3080,7 +3167,7 @@ namespace Game.Entities
case 1: SetGMChat(true);
break; // enable
case 2: // save state
if (extraflags.HasAnyFlag(PlayerExtraFlags.GMChat))
if (extra_flags.HasAnyFlag(PlayerExtraFlags.GMChat))
SetGMChat(true);
break;
}
@@ -3093,7 +3180,7 @@ namespace Game.Entities
case 1: SetAcceptWhispers(true);
break; // enable
case 2: // save state
if (extraflags.HasAnyFlag(PlayerExtraFlags.AcceptWhispers))
if (extra_flags.HasAnyFlag(PlayerExtraFlags.AcceptWhispers))
SetAcceptWhispers(true);
break;
}
@@ -3118,16 +3205,16 @@ namespace Game.Entities
holder.GetResult(PlayerLoginQueryLoad.GarrisonFollowerAbilities)))
_garrison = garrison;
_InitHonorLevelOnLoadFromDB(result.Read<uint>(72), result.Read<uint>(73));
_InitHonorLevelOnLoadFromDB(honor, honorLevel);
_restMgr.LoadRestBonus(RestTypes.Honor, (PlayerRestState)result.Read<byte>(74), result.Read<float>(75));
_restMgr.LoadRestBonus(RestTypes.Honor, honorRestState, honorRestBonus);
if (time_diff > 0)
{
//speed collect rest bonus in offline, in logout, far from tavern, city (section/in hour)
float bubble0 = 0.031f;
//speed collect rest bonus in offline, in logout, in tavern, city (section/in hour)
float bubble1 = 0.125f;
float bubble = result.Read<byte>(33) > 0
float bubble = is_logout_resting > 0
? bubble1 * WorldConfig.GetFloatValue(WorldCfg.RateRestOfflineInTavernOrCity)
: bubble0 * WorldConfig.GetFloatValue(WorldCfg.RateRestOfflineInWilderness);
@@ -3191,15 +3278,8 @@ namespace Game.Entities
stmt.AddValue(index++, (byte)GetClass());
stmt.AddValue(index++, (byte)m_playerData.NativeSex); // save gender from PLAYER_BYTES_3, UNIT_BYTES_0 changes with every transform effect
stmt.AddValue(index++, GetLevel());
stmt.AddValue(index++, (uint)m_activePlayerData.XP);
stmt.AddValue(index++, (uint)GetNativeSex());
stmt.AddValue(index++, GetMoney());
stmt.AddValue(index++, (byte)m_playerData.SkinID);
stmt.AddValue(index++, (byte)m_playerData.FaceID);
stmt.AddValue(index++, (byte)m_playerData.HairStyleID);
stmt.AddValue(index++, (byte)m_playerData.HairColorID);
stmt.AddValue(index++, (byte)m_playerData.FacialHairStyleID);
for (int i = 0; i < PlayerConst.CustomDisplaySize; ++i)
stmt.AddValue(index++, m_playerData.CustomDisplayOption[i]);
stmt.AddValue(index++, GetInventorySlotCount());
stmt.AddValue(index++, GetBankBagSlotCount());
stmt.AddValue(index++, (byte)m_activePlayerData.RestInfo[(int)RestTypes.XP].StateID);
@@ -3321,17 +3401,8 @@ namespace Game.Entities
stmt.AddValue(index++, (byte)GetClass());
stmt.AddValue(index++, (byte)m_playerData.NativeSex); // save gender from PLAYER_BYTES_3, UNIT_BYTES_0 changes with every transform effect
stmt.AddValue(index++, GetLevel());
stmt.AddValue(index++, (uint)m_activePlayerData.XP);
stmt.AddValue(index++, (uint)GetNativeSex());
stmt.AddValue(index++, GetMoney());
stmt.AddValue(index++, (byte)m_playerData.SkinID);
stmt.AddValue(index++, (byte)m_playerData.FaceID);
stmt.AddValue(index++, (byte)m_playerData.HairStyleID);
stmt.AddValue(index++, (byte)m_playerData.HairColorID);
stmt.AddValue(index++, (byte)m_playerData.FacialHairStyleID);
for (int i = 0; i < PlayerConst.CustomDisplaySize; ++i)
stmt.AddValue(index++, m_playerData.CustomDisplayOption[i]);
stmt.AddValue(index++, GetInventorySlotCount());
stmt.AddValue(index++, GetBankBagSlotCount());
stmt.AddValue(index++, (byte)m_activePlayerData.RestInfo[(int)RestTypes.XP].StateID);
@@ -3485,6 +3556,7 @@ namespace Game.Entities
if (m_mailsUpdated) //save mails only when needed
_SaveMail(characterTransaction);
_SaveCustomizations(characterTransaction);
_SaveBGData(characterTransaction);
_SaveInventory(characterTransaction);
_SaveVoidStorage(characterTransaction);
@@ -3807,6 +3879,10 @@ namespace Game.Entities
stmt.AddValue(0, guid);
trans.Append(stmt);
stmt = DB.Characters.GetPreparedStatement(CharStatements.DEL_CHARACTER_CUSTOMIZATIONS);
stmt.AddValue(0, guid);
trans.Append(stmt);
stmt = DB.Characters.GetPreparedStatement(CharStatements.DEL_PLAYER_ACCOUNT_DATA);
stmt.AddValue(0, guid);
trans.Append(stmt);
@@ -196,6 +196,7 @@ namespace Game.Entities
byte m_cinematic;
uint m_movie;
bool m_customizationsChanged;
SpecializationInfo _specializationInfo;
public List<ObjectGuid> m_clientGUIDs = new List<ObjectGuid>();
+8 -2
View File
@@ -32,6 +32,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using Game.BattleFields;
using Framework.Dynamic;
namespace Game.Entities
{
@@ -3848,6 +3849,8 @@ namespace Game.Entities
if (guild != null)
guild.AddGuildNews(GuildNews.ItemPurchased, GetGUID(), 0, item);
}
UpdateCriteria(CriteriaTypes.BoughtItemFromVendor, 1);
return true;
}
@@ -5186,9 +5189,12 @@ namespace Game.Entities
return InventoryResult.ClientLockedOut;
}
ScalingStatDistributionRecord ssd = CliDB.ScalingStatDistributionStorage.LookupByKey(pItem.GetScalingStatDistribution());
ContentTuningLevels? requiredLevels = null;
// check allowed level (extend range to upper values if MaxLevel more or equal max player level, this let GM set high level with 1...max range items)
if (ssd != null && ssd.MaxLevel < WorldConfig.GetIntValue(WorldCfg.MaxPlayerLevel) && ssd.MaxLevel < GetLevel() && Global.DB2Mgr.GetHeirloomByItemId(pProto.GetId()) == null)
if (pItem.GetQuality() == ItemQuality.Heirloom)
requiredLevels = Global.DB2Mgr.GetContentTuningData(pItem.GetScalingContentTuningId(), 0, true);
if (requiredLevels.HasValue && requiredLevels.Value.MaxLevel < SharedConst.DefaultMaxLevel && requiredLevels.Value.MaxLevel < GetLevel() && Global.DB2Mgr.GetHeirloomByItemId(pProto.GetId()) == null)
return InventoryResult.NotEquippable;
byte eslot = FindEquipSlot(pProto, slot, swap);
@@ -144,6 +144,8 @@ namespace Game.Entities
_restMgr.SetRestFlag(RestFlag.FactionArea);
else
_restMgr.RemoveRestFlag(RestFlag.FactionArea);
UpdateCriteria(CriteriaTypes.TravelledToArea, newArea);
}
public void UpdateZone(uint newZone, uint newArea)
+14 -7
View File
@@ -49,14 +49,18 @@ namespace Game.Entities
public int GetQuestMinLevel(Quest quest)
{
if (quest.Level == -1 && quest.ScalingFactionGroup != 0)
var questLevels = Global.DB2Mgr.GetContentTuningData(quest.ContentTuningId, m_playerData.CtrOptions.GetValue().ContentTuningConditionMask);
if (questLevels.HasValue)
{
ChrRacesRecord race = CliDB.ChrRacesStorage.LookupByKey(GetRace());
FactionTemplateRecord raceFaction = CliDB.FactionTemplateStorage.LookupByKey(race.FactionID);
if (raceFaction == null || raceFaction.FactionGroup != quest.ScalingFactionGroup)
return quest.MaxScalingLevel;
if (raceFaction == null || raceFaction.FactionGroup != CliDB.ContentTuningStorage.LookupByKey(quest.ContentTuningId).GetScalingFactionGroup())
return questLevels.Value.MaxLevel;
return questLevels.Value.MinLevelWithDelta;
}
return quest.MinLevel;
return 0;
}
public int GetQuestLevel(Quest quest)
@@ -64,16 +68,18 @@ namespace Game.Entities
if (quest == null)
return 0;
if (quest.Level == -1)
var questLevels = Global.DB2Mgr.GetContentTuningData(quest.ContentTuningId, m_playerData.CtrOptions.GetValue().ContentTuningConditionMask);
if (questLevels.HasValue)
{
int minLevel = GetQuestMinLevel(quest);
int maxLevel = quest.MaxScalingLevel;
int maxLevel = questLevels.Value.MaxLevel;
int level = (int)GetLevel();
if (level >= minLevel)
return Math.Min(level, maxLevel);
return minLevel;
}
return quest.Level;
return 0;
}
public int GetRewardedQuestCount() { return m_RewardedQuests.Count; }
@@ -1153,6 +1159,7 @@ namespace Game.Entities
UpdateCriteria(CriteriaTypes.CompleteQuestCount);
UpdateCriteria(CriteriaTypes.CompleteQuest, quest.Id);
UpdateCriteria(CriteriaTypes.CompleteQuestAccumulate, 1);
// make full db save
SaveToDB(false);
+78 -245
View File
@@ -59,6 +59,7 @@ namespace Game.Entities
m_zoneUpdateId = 0xffffffff;
m_nextSave = WorldConfig.GetUIntValue(WorldCfg.IntervalSave);
m_customizationsChanged = false;
SetGroupInvite(null);
@@ -184,7 +185,7 @@ namespace Game.Entities
return false;
}
if (!ValidateAppearance(createInfo.RaceId, createInfo.ClassId, createInfo.Sex, createInfo.HairStyle, createInfo.HairColor, createInfo.Face, createInfo.FacialHairStyle, createInfo.Skin, createInfo.CustomDisplay, true))
if (!GetSession().ValidateAppearance(createInfo.RaceId, createInfo.ClassId, createInfo.Sex, createInfo.Customizations))
{
Log.outError(LogFilter.Player, "Player.Create: Possible hacking-attempt: Account {0} tried creating a character named '{1}' with invalid appearance attributes - refusing to do so",
GetSession().GetAccountId(), GetName());
@@ -223,14 +224,7 @@ namespace Game.Entities
SetWatchedFactionIndex(0xFFFFFFFF);
SetSkinId(createInfo.Skin);
SetFaceId(createInfo.Face);
SetHairStyleId(createInfo.HairStyle);
SetHairColorId(createInfo.HairColor);
SetFacialHairStyleId(createInfo.FacialHairStyle);
for (byte i = 0; i < PlayerConst.CustomDisplaySize; ++i)
SetCustomDisplayOption(i, createInfo.CustomDisplay[i]);
SetCustomizations(createInfo.Customizations);
SetRestState(RestTypes.XP, ((GetSession().IsARecruiter() || GetSession().GetRecruiterId() != 0) ? PlayerRestState.RAFLinked : PlayerRestState.NotRAFLinked));
SetRestState(RestTypes.Honor, PlayerRestState.NotRAFLinked);
SetNativeSex(createInfo.Sex);
@@ -308,46 +302,8 @@ namespace Game.Entities
}
// original items
CharStartOutfitRecord oEntry = Global.DB2Mgr.GetCharStartOutfitEntry((byte)createInfo.RaceId, (byte)createInfo.ClassId, (byte)createInfo.Sex);
if (oEntry != null)
{
for (int j = 0; j < ItemConst.MaxOutfitItems - 1; ++j)
{
if (oEntry.ItemID[j] <= 0)
continue;
uint itemId = (uint)oEntry.ItemID[j];
ItemTemplate iProto = Global.ObjectMgr.GetItemTemplate(itemId);
if (iProto == null)
continue;
// BuyCount by default
uint count = iProto.GetBuyCount();
// special amount for food/drink
if (iProto.GetClass() == ItemClass.Consumable && iProto.GetSubClass() == (uint)ItemSubClassConsumable.FoodDrink)
{
if (!iProto.Effects.Empty())
{
switch (iProto.Effects[0].SpellCategoryID)
{
case 11: // food
count = (uint)(GetClass() == Class.Deathknight ? 10 : 4);
break;
case 59: // drink
count = 2;
break;
}
}
if (iProto.GetMaxStackSize() < count)
count = iProto.GetMaxStackSize();
}
StoreNewItemInBestSlots(itemId, count);
}
}
foreach (var item in info.item)
StoreNewItemInBestSlots(item.item_id, item.item_amount);
foreach (PlayerCreateInfoItem initialItem in info.item)
StoreNewItemInBestSlots(initialItem.item_id, initialItem.item_amount);
// bags and main-hand weapon must equipped at this moment
// now second pass for not equipped (offhand weapon/shield if it attempt equipped before main-hand weapon)
@@ -1193,7 +1149,7 @@ namespace Game.Entities
FactionRecord factionEntry = CliDB.FactionStorage.LookupByKey(currency.FactionID);
if (factionEntry != null)
{
if (currency.Flags.HasAnyFlag((uint)CurrencyFlags.HighPrecision))
if (currency.Flags[0].HasAnyFlag((int)CurrencyFlags.HighPrecision))
count /= 100;
GetReputationMgr().ModifyReputation(factionEntry, count, false, true);
return;
@@ -1582,8 +1538,12 @@ namespace Game.Entities
{
LFGDungeonsRecord dungeon = Global.DB2Mgr.GetLfgDungeon(map.GetId(), map.GetDifficultyID());
if (dungeon != null)
if (dungeon.TargetLevel == 80)
ChampioningFaction = GetChampioningFaction();
{
var dungeonLevels = Global.DB2Mgr.GetContentTuningData(dungeon.ContentTuningID, m_playerData.CtrOptions.GetValue().ContentTuningConditionMask);
if (dungeonLevels.HasValue)
if (dungeonLevels.Value.TargetLevelMax == Global.ObjectMgr.GetMaxLevelForExpansion(Expansion.WrathOfTheLichKing))
ChampioningFaction = GetChampioningFaction();
}
}
}
@@ -2613,6 +2573,9 @@ namespace Game.Entities
if (channel.Flags.HasAnyFlag(ChannelDBCFlags.GuildReq) && GetGuildId() != 0)
return false;
if (channel.Flags.HasAnyFlag(ChannelDBCFlags.NoClientJoin))
return false;
return true;
}
public void JoinedChannel(Channel c)
@@ -2658,6 +2621,9 @@ namespace Game.Entities
foreach (var channelEntry in CliDB.ChatChannelsStorage.Values)
{
if (!channelEntry.Flags.HasAnyFlag(ChannelDBCFlags.Initial))
continue;
Channel usedChannel = null;
foreach (var channel in m_channels)
{
@@ -3467,51 +3433,27 @@ namespace Game.Entities
SendBattlefieldWorldStates();
}
public uint GetBarberShopCost(BarberShopStyleRecord newHairStyle, uint newHairColor, BarberShopStyleRecord newFacialHair, BarberShopStyleRecord newSkin, BarberShopStyleRecord newFace, Array<BarberShopStyleRecord> newCustomDisplay)
public long GetBarberShopCost(List<ChrCustomizationChoice> newCustomizations)
{
byte hairstyle = m_playerData.HairStyleID;
byte haircolor = m_playerData.HairColorID;
byte facialhair = m_playerData.FacialHairStyleID;
byte skincolor = m_playerData.SkinID;
byte face = m_playerData.FaceID;
Array<byte> customDisplay = new Array<byte>(PlayerConst.CustomDisplaySize);
for (int i = 0; i < PlayerConst.CustomDisplaySize; ++i)
customDisplay[i] = m_playerData.CustomDisplayOption[i];
if ((hairstyle == newHairStyle.Data) &&
(haircolor == newHairColor) &&
(facialhair == newFacialHair.Data) &&
(newSkin == null || (newSkin.Data == skincolor)) &&
(newFace == null || (newFace.Data == face)) &&
(newCustomDisplay[0] == null || (newCustomDisplay[0].Data == customDisplay[0])) &&
(newCustomDisplay[1] == null || (newCustomDisplay[1].Data == customDisplay[1])) &&
(newCustomDisplay[2] == null || (newCustomDisplay[2].Data == customDisplay[2])))
return 0;
GtBarberShopCostBaseRecord bsc = CliDB.BarberShopCostBaseGameTable.GetRow(GetLevel());
if (bsc == null) // shouldn't happen
return 0xFFFFFFFF;
return 0;
uint cost = 0;
if (hairstyle != newHairStyle.Data)
cost += (uint)(bsc.Cost * newHairStyle.CostModifier);
long cost = 0;
foreach (ChrCustomizationChoice newChoice in newCustomizations)
{
int currentCustomizationIndex = m_playerData.Customizations.FindIndexIf(currentCustomization =>
{
return currentCustomization.ChrCustomizationOptionID == newChoice.ChrCustomizationOptionID;
});
if ((haircolor != newHairColor) && (hairstyle == newHairStyle.Data))
cost += (uint)(bsc.Cost * 0.5f); // +1/2 of price
if (facialhair != newFacialHair.Data)
cost += (uint)(bsc.Cost * newFacialHair.CostModifier);
if (newSkin != null && skincolor != newSkin.Data)
cost += (uint)(bsc.Cost * newSkin.CostModifier);
if (newFace != null && face != newFace.Data)
cost += (uint)(bsc.Cost * newFace.CostModifier);
for (int i = 0; i < PlayerConst.CustomDisplaySize; ++i)
if (newCustomDisplay[i] != null && customDisplay[i] != newCustomDisplay[i].Data)
cost += (uint)(bsc.Cost * newCustomDisplay[i].CostModifier);
if (currentCustomizationIndex == -1 || m_playerData.Customizations[currentCustomizationIndex].ChrCustomizationChoiceID != newChoice.ChrCustomizationChoiceID)
{
ChrCustomizationOptionRecord customizationOption = CliDB.ChrCustomizationOptionStorage.LookupByKey(newChoice.ChrCustomizationOptionID);
if (customizationOption != null)
cost += (long)(bsc.Cost * customizationOption.BarberShopCostModifier);
}
}
return cost;
}
@@ -3950,139 +3892,10 @@ namespace Game.Entities
return null;
}
static uint GetSelectionFromContext(uint context, Class playerClass)
{
switch (context)
{
case 1:
if (playerClass == Class.Deathknight)
return 1;
if (playerClass == Class.DemonHunter)
return 3;
return 0;
case 2:
if (playerClass == Class.Deathknight)
return 5;
if (playerClass == Class.DemonHunter)
return 6;
return 4;
case 3:
return 7;
case 4:
if (playerClass == Class.Deathknight)
return 9;
if (playerClass == Class.DemonHunter)
return 10;
return 8;
default:
if (playerClass == Class.Deathknight)
return 1;
if (playerClass == Class.DemonHunter)
return 2;
return 0;
}
}
static bool ComponentFlagsMatch(CharSectionsRecord entry, uint selection)
{
switch (selection)
{
case 0:
if (!entry.Flags.HasAnyFlag((short)1))
return false;
return !entry.Flags.HasAnyFlag((short)0x2C);
case 1:
if (!entry.Flags.HasAnyFlag((short)1))
return false;
if (!entry.Flags.HasAnyFlag((short)0x94))
return false;
return !entry.Flags.HasAnyFlag((short)8);
case 2:
if (!entry.Flags.HasAnyFlag((short)1))
return false;
if (!entry.Flags.HasAnyFlag((short)0x70))
return false;
return !entry.Flags.HasAnyFlag((short)8);
case 3:
if (!entry.Flags.HasAnyFlag((short)1))
return false;
if (!entry.Flags.HasAnyFlag((short)0x20))
return false;
return !entry.Flags.HasAnyFlag((short)8);
case 4:
case 8:
if (!entry.Flags.HasAnyFlag((short)3))
return false;
return !entry.Flags.HasAnyFlag((short)0x2C);
case 5:
case 9:
if (!entry.Flags.HasAnyFlag((short)3))
return false;
if (!entry.Flags.HasAnyFlag((short)0x94))
return false;
return !entry.Flags.HasAnyFlag((short)8);
case 6:
case 10:
if (!entry.Flags.HasAnyFlag((short)3))
return false;
if (!entry.Flags.HasAnyFlag((short)0x70))
return false;
return !entry.Flags.HasAnyFlag((short)8);
case 7:
return true;
default:
break;
}
return false;
}
static bool IsSectionFlagValid(CharSectionsRecord entry, Class class_, bool create)
{
if (create)
return ComponentFlagsMatch(entry, GetSelectionFromContext(0, class_));
return ComponentFlagsMatch(entry, GetSelectionFromContext(2, class_));
}
static bool IsSectionValid(Race race, Class class_, Gender gender, CharBaseSectionVariation variation, byte variationIndex, byte colorIndex, bool create)
{
CharSectionsRecord section = Global.DB2Mgr.GetCharSectionEntry(race, gender, variation, variationIndex, colorIndex);
if (section != null)
return IsSectionFlagValid(section, class_, create);
return false;
}
public static bool IsValidGender(Gender _gender) { return _gender <= Gender.Female; }
public static bool IsValidClass(Class _class) { return Convert.ToBoolean((1 << ((int)_class - 1)) & (int)Class.ClassMaskAllPlayable); }
public static bool IsValidRace(Race _race) { return Convert.ToBoolean((1 << ((int)_race - 1)) & (int)Race.RaceMaskAllPlayable); }
public static bool ValidateAppearance(Race race, Class class_, Gender gender, byte hairID, byte hairColor, byte faceID, byte facialHairId, byte skinColor, Array<byte> customDisplay, bool create = false)
{
if (!IsSectionValid(race, class_, gender, CharBaseSectionVariation.Skin, 0, skinColor, create))
return false;
if (!IsSectionValid(race, class_, gender, CharBaseSectionVariation.Face, faceID, skinColor, create))
return false;
if (!IsSectionValid(race, class_, gender, CharBaseSectionVariation.Hair, hairID, hairColor, create))
return false;
if (!IsSectionValid(race, class_, gender, CharBaseSectionVariation.FacialHair, facialHairId, hairColor, create))
if (Global.DB2Mgr.HasCharSections(race, gender, CharBaseSectionVariation.FacialHair) || !Global.DB2Mgr.HasCharacterFacialHairStyle(race, gender, facialHairId))
return false;
if (!IsSectionValid(race, class_, gender, CharBaseSectionVariation.CustomDisplay1, customDisplay[0], 0, create))
return false;
if (!IsSectionValid(race, class_, gender, CharBaseSectionVariation.CustomDisplay2, customDisplay[1], 0, create))
return false;
if (!IsSectionValid(race, class_, gender, CharBaseSectionVariation.CustomDisplay3, customDisplay[2], 0, create))
return false;
return true;
}
public void OnCombatExit()
{
UpdatePotionCooldown();
@@ -4594,12 +4407,8 @@ namespace Game.Entities
flags |= CorpseFlags.FFAPvP;
corpse.SetRace(GetRace());
corpse.SetSex((Gender)(byte)m_playerData.NativeSex);
corpse.SetSkin(m_playerData.SkinID);
corpse.SetFace(m_playerData.FaceID);
corpse.SetHairStyle(m_playerData.HairStyleID);
corpse.SetHairColor(m_playerData.HairColorID);
corpse.SetFacialHairStyle(m_playerData.FacialHairStyleID);
corpse.SetSex(GetNativeSex());
corpse.SetCustomizations(m_playerData.Customizations);
corpse.SetFlags(flags);
corpse.SetDisplayId(GetNativeDisplayId());
corpse.SetFactionTemplate(CliDB.ChrRacesStorage.LookupByKey(GetRace()).FactionID);
@@ -5475,8 +5284,7 @@ namespace Game.Entities
return;
}
byte gender = m_playerData.NativeSex;
switch ((Gender)gender)
switch (GetNativeSex())
{
case Gender.Female:
SetDisplayId(info.DisplayId_f);
@@ -5487,7 +5295,7 @@ namespace Game.Entities
SetNativeDisplayId(info.DisplayId_m);
break;
default:
Log.outError(LogFilter.Player, "Player {0} ({1}) has invalid gender {2}", GetName(), GetGUID().ToString(), (Gender)gender);
Log.outError(LogFilter.Player, "Player {0} ({1}) has invalid gender {2}", GetName(), GetGUID().ToString(), GetNativeSex());
return;
}
@@ -5883,13 +5691,13 @@ namespace Game.Entities
SetUpdateFieldValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.ModHealingDonePos), 0);
SetUpdateFieldValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.ModHealingPercent), 1.0f);
SetUpdateFieldValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.ModHealingDonePercent), 1.0f);
SetUpdateFieldValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.ModPeriodicHealingDonePercent), 1.0f);
for (byte i = 0; i < 7; ++i)
for (byte i = 0; i < (int)SpellSchools.Max; ++i)
{
SetUpdateFieldValue(ref m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.ModDamageDoneNeg, i), 0);
SetUpdateFieldValue(ref m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.ModDamageDonePos, i), 0);
SetUpdateFieldValue(ref m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.ModDamageDonePercent, i), 1.0f);
SetUpdateFieldValue(ref m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.ModHealingDonePercent, i), 1.0f);
}
SetUpdateFieldValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.ModSpellPowerPercent), 1.0f);
@@ -6324,7 +6132,8 @@ namespace Game.Entities
UpdateCriteria(CriteriaTypes.ExploreArea, GetAreaId());
if (areaEntry.ExplorationLevel > 0)
var areaLevels = Global.DB2Mgr.GetContentTuningData(areaEntry.ContentTuningID, m_playerData.CtrOptions.GetValue().ContentTuningConditionMask);
if (areaLevels.HasValue)
{
if (GetLevel() >= WorldConfig.GetIntValue(WorldCfg.MaxPlayerLevel))
{
@@ -6332,7 +6141,8 @@ namespace Game.Entities
}
else
{
int diff = (int)(GetLevel() - areaEntry.ExplorationLevel);
ushort areaLevel = (ushort)Math.Min(Math.Max((ushort)GetLevel(), areaLevels.Value.MinLevel), areaLevels.Value.MaxLevel);
int diff = (int)(GetLevel()) - areaLevel;
uint XP = 0;
if (diff < -5)
{
@@ -6344,11 +6154,11 @@ namespace Game.Entities
if (exploration_percent < 0)
exploration_percent = 0;
XP = (uint)(Global.ObjectMgr.GetBaseXP((byte)areaEntry.ExplorationLevel) * exploration_percent / 100 * WorldConfig.GetFloatValue(WorldCfg.RateXpExplore));
XP = (uint)(Global.ObjectMgr.GetBaseXP(areaLevel) * exploration_percent / 100 * WorldConfig.GetFloatValue(WorldCfg.RateXpExplore));
}
else
{
XP = (uint)(Global.ObjectMgr.GetBaseXP((byte)areaEntry.ExplorationLevel) * WorldConfig.GetFloatValue(WorldCfg.RateXpExplore));
XP = (uint)(Global.ObjectMgr.GetBaseXP(areaLevel) * WorldConfig.GetFloatValue(WorldCfg.RateXpExplore));
}
GiveXP(XP, null);
@@ -7477,17 +7287,40 @@ namespace Game.Entities
public void RemovePlayerFlagEx(PlayerFlagsEx flags) { RemoveUpdateFieldFlagValue(m_values.ModifyValue(m_playerData).ModifyValue(m_playerData.PlayerFlagsEx), (uint)flags); }
public void SetPlayerFlagsEx(PlayerFlagsEx flags) { SetUpdateFieldValue(m_values.ModifyValue(m_playerData).ModifyValue(m_playerData.PlayerFlagsEx), (uint)flags); }
public void SetSkinId(byte skinId) { SetUpdateFieldValue(m_values.ModifyValue(m_playerData).ModifyValue(m_playerData.SkinID), skinId); }
public void SetFaceId(byte faceId) { SetUpdateFieldValue(m_values.ModifyValue(m_playerData).ModifyValue(m_playerData.FaceID), faceId); }
public void SetHairStyleId(byte hairStyleId) { SetUpdateFieldValue(m_values.ModifyValue(m_playerData).ModifyValue(m_playerData.HairStyleID), hairStyleId); }
public void SetHairColorId(byte hairColorId) { SetUpdateFieldValue(m_values.ModifyValue(m_playerData).ModifyValue(m_playerData.HairColorID), hairColorId); }
public void SetFacialHairStyleId(byte facialHairStyleId) { SetUpdateFieldValue(m_values.ModifyValue(m_playerData).ModifyValue(m_playerData.FacialHairStyleID), facialHairStyleId); }
public uint GetCustomizationChoice(uint chrCustomizationOptionId)
{
int choiceIndex = m_playerData.Customizations.FindIndexIf(choice =>
{
return choice.ChrCustomizationOptionID == chrCustomizationOptionId;
});
if (choiceIndex >= 0)
return m_playerData.Customizations[choiceIndex].ChrCustomizationChoiceID;
return 0;
}
public void SetCustomizations(List<ChrCustomizationChoice> customizations, bool markChanged = true)
{
if (markChanged)
m_customizationsChanged = true;
ClearDynamicUpdateFieldValues(m_values.ModifyValue(m_playerData).ModifyValue(m_playerData.Customizations));
foreach (var customization in customizations)
{
ChrCustomizationChoice newChoice = new ChrCustomizationChoice();
newChoice.ChrCustomizationOptionID = customization.ChrCustomizationOptionID;
newChoice.ChrCustomizationChoiceID = customization.ChrCustomizationChoiceID;
AddDynamicUpdateFieldValue(m_values.ModifyValue(m_playerData).ModifyValue(m_playerData.Customizations), newChoice);
}
}
public Gender GetNativeSex() { return (Gender)(byte)m_playerData.NativeSex; }
public void SetNativeSex(Gender sex) { SetUpdateFieldValue(m_values.ModifyValue(m_playerData).ModifyValue(m_playerData.NativeSex), (byte)sex); }
public void SetPvpTitle(byte pvpTitle) { SetUpdateFieldValue(m_values.ModifyValue(m_playerData).ModifyValue(m_playerData.PvpTitle), pvpTitle); }
public void SetArenaFaction(byte arenaFaction) { SetUpdateFieldValue(m_values.ModifyValue(m_playerData).ModifyValue(m_playerData.ArenaFaction), arenaFaction); }
public void ApplyModFakeInebriation(int mod, bool apply) { ApplyModUpdateFieldValue(m_values.ModifyValue(m_playerData).ModifyValue(m_playerData.FakeInebriation), mod, apply); }
public void SetVirtualPlayerRealm(uint virtualRealmAddress) { SetUpdateFieldValue(m_values.ModifyValue(m_playerData).ModifyValue(m_playerData.VirtualPlayerRealm), virtualRealmAddress); }
public void SetCustomDisplayOption(int slot, byte customDisplayOption) { SetUpdateFieldValue(ref m_values.ModifyValue(m_playerData).ModifyValue(m_playerData.CustomDisplayOption, slot), customDisplayOption); }
public void AddHeirloom(uint itemId, uint flags)
{
@@ -7537,9 +7370,9 @@ namespace Game.Entities
public void ApplyModOverrideAPBySpellPowerPercent(float mod, bool apply) { ApplyModUpdateFieldValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.OverrideAPBySpellPowerPercent), mod, apply); }
public bool HasPlayerLocalFlag(PlayerLocalFlags flags) { return (m_activePlayerData.LocalFlags & (int)flags) != 0; }
public void AddPlayerLocalFlag(PlayerLocalFlags flags) { SetUpdateFieldFlagValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.LocalFlags), (int)flags); }
public void RemovePlayerLocalFlag(PlayerLocalFlags flags) { RemoveUpdateFieldFlagValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.LocalFlags), (int)flags); }
public void SetPlayerLocalFlags(PlayerLocalFlags flags) { SetUpdateFieldValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.LocalFlags), (int)flags); }
public void AddPlayerLocalFlag(PlayerLocalFlags flags) { SetUpdateFieldFlagValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.LocalFlags), (uint)flags); }
public void RemovePlayerLocalFlag(PlayerLocalFlags flags) { RemoveUpdateFieldFlagValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.LocalFlags), (uint)flags); }
public void SetPlayerLocalFlags(PlayerLocalFlags flags) { SetUpdateFieldValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.LocalFlags), (uint)flags); }
public byte GetNumRespecs() { return m_activePlayerData.NumRespecs; }
public void SetNumRespecs(byte numRespecs) { SetUpdateFieldValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.NumRespecs), numRespecs); }
+5 -1
View File
@@ -114,7 +114,11 @@ namespace Game.Entities
if (rested_bonus > xp) // max rested_bonus == xp or (r+x) = 200% xp
rested_bonus = xp;
SetRestBonus(restType, GetRestBonus(restType) - rested_bonus);
uint rested_loss = rested_bonus;
if (restType == RestTypes.XP)
MathFunctions.AddPct(ref rested_loss, _player.GetTotalAuraModifier(AuraType.ModRestedXpConsumption));
SetRestBonus(restType, GetRestBonus(restType) - rested_loss);
Log.outDebug(LogFilter.Player, "RestMgr.GetRestBonus: Player '{0}' ({1}) gain {2} xp (+{3} Rested Bonus). Rested points={4}",
_player.GetGUID().ToString(), _player.GetName(), xp + rested_bonus, rested_bonus, GetRestBonus(restType));
+2 -1
View File
@@ -1493,7 +1493,8 @@ namespace Game.Entities
foreach (AuraEffect auraEffect in GetAuraEffectsByType(AuraType.ModHealingDonePercent))
MathFunctions.AddPct(ref value, auraEffect.GetAmount());
SetUpdateFieldStatValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.ModHealingDonePercent), value);
for (int i = 0; i < (int)SpellSchools.Max; ++i)
SetUpdateFieldStatValue(ref m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.ModHealingDonePercent, i), value);
}
void UpdateCorruption()
+1 -1
View File
@@ -77,7 +77,7 @@ namespace Game.Entities
// Get spell cast by totem
SpellInfo totemSpell = Global.SpellMgr.GetSpellInfo(GetSpell(), GetMap().GetDifficultyID());
if (totemSpell != null)
if (totemSpell.CalcCastTime(GetLevel()) != 0) // If spell has cast time . its an active totem
if (totemSpell.CalcCastTime() != 0) // If spell has cast time -> its an active totem
m_type = TotemType.Active;
m_duration = duration;
+19 -17
View File
@@ -516,7 +516,14 @@ namespace Game.Entities
Player thisPlayer = ToPlayer();
if (thisPlayer != null)
return thisPlayer.m_activePlayerData.ModHealingDonePercent;
{
float maxModDamagePercentSchool = 0.0f;
for (int i = 0; i < (int)SpellSchools.Max; ++i)
if (((int)spellProto.GetSchoolMask() & (1 << i)) != 0)
maxModDamagePercentSchool = Math.Max(maxModDamagePercentSchool, thisPlayer.m_activePlayerData.ModHealingDonePercent[i]);
return maxModDamagePercentSchool;
}
float DoneTotalMod = 1.0f;
@@ -1201,8 +1208,10 @@ namespace Game.Entities
{
// mainly for DoTs which are 3500 here otherwise
int OriginalCastTime = spellProto.CalcCastTime();
if (OriginalCastTime > 7000) OriginalCastTime = 7000;
if (OriginalCastTime < 1500) OriginalCastTime = 1500;
if (OriginalCastTime > 7000)
OriginalCastTime = 7000;
if (OriginalCastTime < 1500)
OriginalCastTime = 1500;
// Portion to Over Time
float PtOT = (overTime / 15000.0f) / ((overTime / 15000.0f) + (OriginalCastTime / 3500.0f));
@@ -2068,7 +2077,7 @@ namespace Game.Entities
InterruptSpell(CurrentSpellTypes.AutoRepeat);
m_AutoRepeatFirstCast = true;
}
if (pSpell.m_spellInfo.CalcCastTime(GetLevel()) > 0)
if (pSpell.m_spellInfo.CalcCastTime() > 0)
AddUnitState(UnitState.Casting);
break;
@@ -2152,26 +2161,19 @@ namespace Game.Entities
public uint SpellCriticalDamageBonus(SpellInfo spellProto, uint damage, Unit victim = null)
{
// Calculate critical bonus
int crit_bonus = (int)damage;
int crit_bonus = (int)damage * 2;
float crit_mod = 0.0f;
switch (spellProto.DmgClass)
{
case SpellDmgClass.Melee: // for melee based spells is 100%
case SpellDmgClass.Ranged:
// @todo write here full calculation for melee/ranged spells
crit_bonus += (int)damage;
break;
default:
crit_bonus += (int)damage / 2; // for spells is 50%
break;
}
crit_mod += (GetTotalAuraMultiplierByMiscMask(AuraType.ModCritDamageBonus, (uint)spellProto.GetSchoolMask()) - 1.0f) * 100;
if (crit_bonus != 0)
MathFunctions.AddPct(ref crit_bonus, (int)crit_mod);
MathFunctions.AddPct(ref crit_bonus, victim.GetTotalAuraModifier(AuraType.ModCriticalDamageTakenFromCaster, aurEff =>
{
return aurEff.GetCasterGUID() == GetGUID();
}));
crit_bonus -= (int)damage;
if (damage > crit_bonus)
+69 -382
View File
@@ -1207,7 +1207,7 @@ namespace Game.Entities
if (artifactAura != null)
{
Item artifact = ToPlayer().GetItemByGuid(artifactAura.GetCastItemGUID());
if (artifact)
if (artifact != null)
{
ArtifactAppearanceRecord artifactAppearance = CliDB.ArtifactAppearanceStorage.LookupByKey(artifact.GetModifier(ItemModifier.ArtifactAppearanceId));
if (artifactAppearance != null)
@@ -1216,398 +1216,84 @@ namespace Game.Entities
}
}
byte hairColor = thisPlayer.m_playerData.HairColorID;
byte skinColor = thisPlayer.m_playerData.SkinID;
ShapeshiftFormModelData formModelData = Global.DB2Mgr.GetShapeshiftFormModelData(GetRace(), thisPlayer.GetNativeSex(), form);
if (formModelData != null)
{
bool useRandom = false;
switch (form)
{
case ShapeShiftForm.CatForm:
useRandom = HasAura(210333);
break; // Glyph of the Feral Chameleon
case ShapeShiftForm.TravelForm:
useRandom = HasAura(344336);
break; // Glyph of the Swift Chameleon
case ShapeShiftForm.AquaticForm:
useRandom = HasAura(344338);
break; // Glyph of the Aquatic Chameleon
case ShapeShiftForm.BearForm:
useRandom = HasAura(107059);
break; // Glyph of the Ursol Chameleon
case ShapeShiftForm.FlightForm:
useRandom = HasAura(344342);
break; // Glyph of the Aerial Chameleon
default:
break;
}
if (useRandom)
{
List<uint> displayIds = new List<uint>();
for (var i = 0; i < formModelData.Choices.Count; ++i)
{
ChrCustomizationDisplayInfoRecord displayInfo = formModelData.Displays[i];
if (displayInfo != null)
{
ChrCustomizationReqRecord choiceReq = CliDB.ChrCustomizationReqStorage.LookupByKey(formModelData.Choices[i].ChrCustomizationReqID);
if (choiceReq == null || thisPlayer.GetSession().MeetsChrCustomizationReq(choiceReq, GetClass(), false, thisPlayer.m_playerData.Customizations))
displayIds.Add(displayInfo.DisplayID);
}
}
if (!displayIds.Empty())
return displayIds.SelectRandom();
}
else
{
uint formChoice = thisPlayer.GetCustomizationChoice(formModelData.OptionID);
if (formChoice != 0)
{
var choiceIndex = formModelData.Choices.FindIndex(choice =>
{
return choice.Id == formChoice;
});
if (choiceIndex != -1)
{
ChrCustomizationDisplayInfoRecord displayInfo = formModelData.Displays[choiceIndex];
if (displayInfo != null)
return displayInfo.DisplayID;
}
}
}
}
switch (form)
{
case ShapeShiftForm.CatForm:
{
if (GetRace() == Race.NightElf)
{
if (HasAura(210333)) // Glyph of the Feral Chameleon
hairColor = (byte)RandomHelper.URand(0, 10);
switch (hairColor)
{
case 7: // Violet
case 8:
return 29405;
case 3: // Light Blue
return 29406;
case 0: // Green
case 1: // Light Green
case 2: // Dark Green
return 29407;
case 4: // White
return 29408;
default: // original - Dark Blue
return 892;
}
}
else if (GetRace() == Race.Troll)
{
if (HasAura(210333)) // Glyph of the Feral Chameleon
hairColor = (byte)RandomHelper.URand(0, 12);
switch (hairColor)
{
case 0: // Red
case 1:
return 33668;
case 2: // Yellow
case 3:
return 33667;
case 4: // Blue
case 5:
case 6:
return 33666;
case 7: // Purple
case 10:
return 33665;
default: // original - white
return 33669;
}
}
else if (GetRace() == Race.Worgen)
{
if (HasAura(210333)) // Glyph of the Feral Chameleon
skinColor = (byte)RandomHelper.URand(0, 9);
// Male
if (GetGender() == Gender.Male)
{
switch (skinColor)
{
case 1: // Brown
return 33662;
case 2: // Black
case 7:
return 33661;
case 4: // yellow
return 33664;
case 3: // White
case 5:
return 33663;
default: // original - Gray
return 33660;
}
}
// Female
else
{
switch (skinColor)
{
case 5: // Brown
case 6:
return 33662;
case 7: // Black
case 8:
return 33661;
case 3: // yellow
case 4:
return 33664;
case 2: // White
return 33663;
default: // original - Gray
return 33660;
}
}
}
else if (GetRace() == Race.Tauren)
{
if (HasAura(210333)) // Glyph of the Feral Chameleon
skinColor = (byte)RandomHelper.URand(0, 20);
if (GetGender() == Gender.Male)
{
switch (skinColor)
{
case 12: // White
case 13:
case 14:
case 18: // Completly White
return 29409;
case 9: // Light Brown
case 10:
case 11:
return 29410;
case 6: // Brown
case 7:
case 8:
return 29411;
case 0: // Dark
case 1:
case 2:
case 3: // Dark Grey
case 4:
case 5:
return 29412;
default: // original - Grey
return 8571;
}
}
// Female
else
{
switch (skinColor)
{
case 10: // White
return 29409;
case 6: // Light Brown
case 7:
return 29410;
case 4: // Brown
case 5:
return 29411;
case 0: // Dark
case 1:
case 2:
case 3:
return 29412;
default: // original - Grey
return 8571;
}
}
}
else if (Player.TeamForRace(GetRace()) == Team.Alliance)
return 892;
else
return 8571;
}
case ShapeShiftForm.BearForm:
{
if (GetRace() == Race.NightElf)
{
if (HasAura(210333)) // Glyph of the Feral Chameleon
hairColor = (byte)RandomHelper.URand(0, 8);
switch (hairColor)
{
case 0: // Green
case 1: // Light Green
case 2: // Dark Green
return 29413; // 29415?
case 6: // Dark Blue
return 29414;
case 4: // White
return 29416;
case 3: // Light Blue
return 29417;
default: // original - Violet
return 29415;
}
}
else if (GetRace() == Race.Troll)
{
if (HasAura(210333)) // Glyph of the Feral Chameleon
hairColor = (byte)RandomHelper.URand(0, 14);
switch (hairColor)
{
case 0: // Red
case 1:
return 33657;
case 2: // Yellow
case 3:
return 33659;
case 7: // Purple
case 10:
return 33656;
case 8: // White
case 9:
case 11:
case 12:
return 33658;
default: // original - Blue
return 33655;
}
}
else if (GetRace() == Race.Worgen)
{
if (HasAura(210333)) // Glyph of the Feral Chameleon
skinColor = (byte)RandomHelper.URand(0, 8);
// Male
if (GetGender() == Gender.Male)
{
switch (skinColor)
{
case 1: // Brown
return 33652;
case 2: // Black
case 7:
return 33651;
case 4: // Yellow
return 33653;
case 3: // White
case 5:
return 33654;
default: // original - Gray
return 33650;
}
}
// Female
else
{
switch (skinColor)
{
case 5: // Brown
case 6:
return 33652;
case 7: // Black
case 8:
return 33651;
case 3: // yellow
case 4:
return 33654;
case 2: // White
return 33653;
default: // original - Gray
return 33650;
}
}
}
else if (GetRace() == Race.Tauren)
{
if (HasAura(210333)) // Glyph of the Feral Chameleon
skinColor = (byte)RandomHelper.URand(0, 20);
if (GetGender() == Gender.Male)
{
switch (skinColor)
{
case 0: // Dark (Black)
case 1:
case 2:
return 29418;
case 3: // White
case 4:
case 5:
case 12:
case 13:
case 14:
return 29419;
case 9: // Light Brown/Grey
case 10:
case 11:
case 15:
case 16:
case 17:
return 29420;
case 18: // Completly White
return 29421;
default: // original - Brown
return 2289;
}
}
// Female
else
{
switch (skinColor)
{
case 0: // Dark (Black)
case 1:
return 29418;
case 2: // White
case 3:
return 29419;
case 6: // Light Brown/Grey
case 7:
case 8:
case 9:
return 29420;
case 10: // Completly White
return 29421;
default: // original - Brown
return 2289;
}
}
}
else if (Player.TeamForRace(GetRace()) == Team.Alliance)
return 29415;
else
return 2289;
}
case ShapeShiftForm.FlightForm:
if (Player.TeamForRace(GetRace()) == Team.Alliance)
return 20857;
return 20872;
case ShapeShiftForm.FlightFormEpic:
if (HasAura(219062)) // Glyph of the Sentinel
{
switch (GetRace())
{
case Race.NightElf: // Blue
return 64328;
case Race.Tauren: // Brown
return 64329;
case Race.Worgen: // Purple
return 64330;
case Race.Troll: // White
return 64331;
default:
break;
}
}
if (Player.TeamForRace(GetRace()) == Team.Alliance)
return (GetRace() == Race.Worgen ? 37729 : 21243u);
if (GetRace() == Race.Troll)
return 37730;
return 21244;
case ShapeShiftForm.MoonkinForm:
switch (GetRace())
{
case Race.NightElf:
return 15374;
case Race.Tauren:
return 15375;
case Race.Worgen:
return 37173;
case Race.Troll:
return 37174;
default:
break;
}
break;
case ShapeShiftForm.AquaticForm:
if (HasAura(114333)) // Glyph of the Orca
return 4591;
return 2428;
case ShapeShiftForm.TravelForm:
{
if (HasAura(131113)) // Glyph of the Cheetah
return 1043;
if (HasAura(224122)) // Glyph of the Doe
return 70450;
switch (GetRace())
{
case Race.NightElf:
case Race.Worgen:
return 40816;
case Race.Troll:
case Race.Tauren:
return 45339;
default:
break;
}
break;
}
case ShapeShiftForm.GhostWolf:
if (HasAura(58135)) // Glyph of Spectral Wolf
return 60247;
break;
default:
break;
}
}
uint modelid = 0;
SpellShapeshiftFormRecord formEntry = CliDB.SpellShapeshiftFormStorage.LookupByKey((uint)form);
SpellShapeshiftFormRecord formEntry = CliDB.SpellShapeshiftFormStorage.LookupByKey(form);
if (formEntry != null && formEntry.CreatureDisplayID[0] != 0)
{
// Take the alliance modelid as default
if (!IsTypeId(TypeId.Player))
if (GetTypeId() != TypeId.Player)
return formEntry.CreatureDisplayID[0];
else
{
@@ -2673,11 +2359,12 @@ namespace Game.Entities
{
SetUpdateFieldValue(ref m_values.ModifyValue(m_unitData).ModifyValue(m_unitData.ChannelData)._value.SpellID, channelSpellId);
}
public uint GetChannelSpellXSpellVisualId() { return ((UnitChannel)m_unitData.ChannelData).SpellXSpellVisualID; }
public void SetChannelSpellXSpellVisualId(SpellCastVisual channelVisual)
public uint GetChannelSpellXSpellVisualId() { return m_unitData.ChannelData.GetValue().SpellVisual.SpellXSpellVisualID; }
public uint GetChannelScriptVisualId() { return m_unitData.ChannelData.GetValue().SpellVisual.ScriptVisualID; }
public void SetChannelVisual(SpellCastVisualField channelVisual)
{
UnitChannel unitChannel = m_unitData.ModifyValue(m_unitData.ChannelData);
SetUpdateFieldValue(ref unitChannel.SpellXSpellVisualID, channelVisual.SpellXSpellVisualID);
SetUpdateFieldValue(ref unitChannel.SpellVisual, channelVisual);
}
public void AddChannelObject(ObjectGuid guid) { AddDynamicUpdateFieldValue(m_values.ModifyValue(m_unitData).ModifyValue(m_unitData.ChannelObjects), guid); }
public void SetChannelObject(int slot, ObjectGuid guid) { SetUpdateFieldValue(m_values.ModifyValue(m_unitData).ModifyValue(m_unitData.ChannelObjects, slot), guid); }