Fixed appearance validation
Implemented proper facial hair validation Implemented transmog Set fix interaction of spells like Shadowmeld with Threat reducing effects
This commit is contained in:
@@ -60,6 +60,8 @@ namespace Game.DataStorage
|
||||
BattlePetSpeciesStateStorage = DB6Reader.Read<BattlePetSpeciesStateRecord>("BattlePetSpeciesState.db2", DB6Metas.BattlePetSpeciesStateMeta, HotfixStatements.SEL_BATTLE_PET_SPECIES_STATE);
|
||||
BattlemasterListStorage = DB6Reader.Read<BattlemasterListRecord>("BattlemasterList.db2", DB6Metas.BattlemasterListMeta, HotfixStatements.SEL_BATTLEMASTER_LIST, HotfixStatements.SEL_BATTLEMASTER_LIST_LOCALE);
|
||||
BroadcastTextStorage = DB6Reader.Read<BroadcastTextRecord>("BroadcastText.db2", DB6Metas.BroadcastTextMeta, HotfixStatements.SEL_BROADCAST_TEXT, HotfixStatements.SEL_BROADCAST_TEXT_LOCALE);
|
||||
CharacterFacialHairStylesStorage = DB6Reader.Read<CharacterFacialHairStylesRecord>("CharacterFacialHairStyles.db2", DB6Metas.CharacterFacialHairStylesMeta, HotfixStatements.SEL_CHARACTER_FACIAL_HAIR_STYLES);
|
||||
CharBaseSectionStorage = DB6Reader.Read<CharBaseSectionRecord>("CharBaseSection.db2", DB6Metas.CharBaseSectionMeta, HotfixStatements.SEL_CHAR_BASE_SECTION);
|
||||
CharSectionsStorage = DB6Reader.Read<CharSectionsRecord>("CharSections.db2", DB6Metas.CharSectionsMeta, HotfixStatements.SEL_CHAR_SECTIONS);
|
||||
CharStartOutfitStorage = DB6Reader.Read<CharStartOutfitRecord>("CharStartOutfit.db2", DB6Metas.CharStartOutfitMeta, HotfixStatements.SEL_CHAR_START_OUTFIT);
|
||||
CharTitlesStorage = DB6Reader.Read<CharTitlesRecord>("CharTitles.db2", DB6Metas.CharTitlesMeta, HotfixStatements.SEL_CHAR_TITLES, HotfixStatements.SEL_CHAR_TITLES_LOCALE);
|
||||
@@ -239,6 +241,10 @@ namespace Game.DataStorage
|
||||
TaxiPathNodeStorage = DB6Reader.Read<TaxiPathNodeRecord>("TaxiPathNode.db2", DB6Metas.TaxiPathNodeMeta, HotfixStatements.SEL_TAXI_PATH_NODE);
|
||||
TotemCategoryStorage = DB6Reader.Read<TotemCategoryRecord>("TotemCategory.db2", DB6Metas.TotemCategoryMeta, HotfixStatements.SEL_TOTEM_CATEGORY, HotfixStatements.SEL_TOTEM_CATEGORY_LOCALE);
|
||||
ToyStorage = DB6Reader.Read<ToyRecord>("Toy.db2", DB6Metas.ToyMeta, HotfixStatements.SEL_TOY, HotfixStatements.SEL_TOY_LOCALE);
|
||||
TransmogHolidayStorage = DB6Reader.Read<TransmogHolidayRecord>("TransmogHoliday.db2", DB6Metas.TransmogHolidayMeta, HotfixStatements.SEL_TRANSMOG_HOLIDAY);
|
||||
TransmogSetStorage = DB6Reader.Read<TransmogSetRecord>("TransmogSet.db2", DB6Metas.TransmogSetMeta, HotfixStatements.SEL_TRANSMOG_SET, HotfixStatements.SEL_TRANSMOG_SET_LOCALE);
|
||||
TransmogSetGroupStorage = DB6Reader.Read<TransmogSetGroupRecord>("TransmogSetGroup.db2", DB6Metas.TransmogSetGroupMeta, HotfixStatements.SEL_TRANSMOG_SET_GROUP, HotfixStatements.SEL_TRANSMOG_SET_GROUP_LOCALE);
|
||||
TransmogSetItemStorage = DB6Reader.Read<TransmogSetItemRecord>("TransmogSetItem.db2", DB6Metas.TransmogSetItemMeta, HotfixStatements.SEL_TRANSMOG_SET_ITEM);
|
||||
TransportAnimationStorage = DB6Reader.Read<TransportAnimationRecord>("TransportAnimation.db2", DB6Metas.TransportAnimationMeta, HotfixStatements.SEL_TRANSPORT_ANIMATION);
|
||||
TransportRotationStorage = DB6Reader.Read<TransportRotationRecord>("TransportRotation.db2", DB6Metas.TransportRotationMeta, HotfixStatements.SEL_TRANSPORT_ROTATION);
|
||||
UnitPowerBarStorage = DB6Reader.Read<UnitPowerBarRecord>("UnitPowerBar.db2", DB6Metas.UnitPowerBarMeta, HotfixStatements.SEL_UNIT_POWER_BAR, HotfixStatements.SEL_UNIT_POWER_BAR_LOCALE);
|
||||
@@ -378,6 +384,8 @@ namespace Game.DataStorage
|
||||
public static DB6Storage<BattlePetSpeciesStateRecord> BattlePetSpeciesStateStorage;
|
||||
public static DB6Storage<BattlemasterListRecord> BattlemasterListStorage;
|
||||
public static DB6Storage<BroadcastTextRecord> BroadcastTextStorage;
|
||||
public static DB6Storage<CharacterFacialHairStylesRecord> CharacterFacialHairStylesStorage;
|
||||
public static DB6Storage<CharBaseSectionRecord> CharBaseSectionStorage;
|
||||
public static DB6Storage<CharSectionsRecord> CharSectionsStorage;
|
||||
public static DB6Storage<CharStartOutfitRecord> CharStartOutfitStorage;
|
||||
public static DB6Storage<CharTitlesRecord> CharTitlesStorage;
|
||||
@@ -557,6 +565,10 @@ namespace Game.DataStorage
|
||||
public static DB6Storage<TaxiPathNodeRecord> TaxiPathNodeStorage;
|
||||
public static DB6Storage<TotemCategoryRecord> TotemCategoryStorage;
|
||||
public static DB6Storage<ToyRecord> ToyStorage;
|
||||
public static DB6Storage<TransmogHolidayRecord> TransmogHolidayStorage;
|
||||
public static DB6Storage<TransmogSetRecord> TransmogSetStorage;
|
||||
public static DB6Storage<TransmogSetGroupRecord> TransmogSetGroupStorage;
|
||||
public static DB6Storage<TransmogSetItemRecord> TransmogSetItemStorage;
|
||||
public static DB6Storage<TransportAnimationRecord> TransportAnimationStorage;
|
||||
public static DB6Storage<TransportRotationRecord> TransportRotationStorage;
|
||||
public static DB6Storage<UnitPowerBarRecord> UnitPowerBarStorage;
|
||||
|
||||
@@ -59,44 +59,25 @@ namespace Game.DataStorage
|
||||
foreach (ArtifactPowerRankRecord artifactPowerRank in CliDB.ArtifactPowerRankStorage.Values)
|
||||
_artifactPowerRanks[Tuple.Create((uint)artifactPowerRank.ArtifactPowerID, artifactPowerRank.Rank)] = artifactPowerRank;
|
||||
|
||||
MultiMap<uint, Tuple<byte, byte>> addedSections = new MultiMap<uint, Tuple<byte, byte>>();
|
||||
foreach (CharacterFacialHairStylesRecord characterFacialStyle in CliDB.CharacterFacialHairStylesStorage.Values)
|
||||
_characterFacialHairStyles.Add(Tuple.Create(characterFacialStyle.RaceID, characterFacialStyle.SexID, (uint)characterFacialStyle.VariationID));
|
||||
|
||||
CharBaseSectionVariation[] sectionToBase = new CharBaseSectionVariation[(int)CharSectionType.Max];
|
||||
foreach (CharBaseSectionRecord charBaseSection in CliDB.CharBaseSectionStorage.Values)
|
||||
{
|
||||
Contract.Assert(charBaseSection.ResolutionVariation < (byte)CharSectionType.Max, $"SECTION_TYPE_MAX ({(byte)CharSectionType.Max}) must be equal to or greater than {charBaseSection.ResolutionVariation + 1}");
|
||||
Contract.Assert(charBaseSection.Variation < CharBaseSectionVariation.Max, $"CharBaseSectionVariation.Max {(byte)CharBaseSectionVariation.Max} must be equal to or greater than {charBaseSection.Variation + 1}");
|
||||
|
||||
sectionToBase[charBaseSection.ResolutionVariation] = (CharBaseSectionVariation)charBaseSection.Variation;
|
||||
}
|
||||
|
||||
MultiMap<Tuple<byte, byte, CharBaseSectionVariation>, Tuple<byte, byte>> addedSections = new MultiMap<Tuple<byte, byte, CharBaseSectionVariation>, Tuple<byte, byte>>();
|
||||
foreach (CharSectionsRecord charSection in CliDB.CharSectionsStorage.Values)
|
||||
{
|
||||
if (charSection.Race == 0 || !Convert.ToBoolean((1 << (charSection.Race - 1)) & (int)Race.RaceMaskAllPlayable)) //ignore Nonplayable races
|
||||
continue;
|
||||
Contract.Assert(charSection.BaseSection < (byte)CharSectionType.Max, $"SECTION_TYPE_MAX ({(byte)CharSectionType.Max}) must be equal to or greater than {charSection.BaseSection + 1}");
|
||||
|
||||
// Not all sections are used for low-res models but we need to get all sections for validation since its viewer dependent
|
||||
byte baseSection = charSection.GenType;
|
||||
switch ((CharSectionType)baseSection)
|
||||
{
|
||||
case CharSectionType.SkinLowRes:
|
||||
case CharSectionType.FaceLowRes:
|
||||
case CharSectionType.FacialHairLowRes:
|
||||
case CharSectionType.HairLowRes:
|
||||
case CharSectionType.UnderwearLowRes:
|
||||
baseSection = (byte)(baseSection + (byte)CharSectionType.Skin);
|
||||
break;
|
||||
case CharSectionType.Skin:
|
||||
case CharSectionType.Face:
|
||||
case CharSectionType.FacialHair:
|
||||
case CharSectionType.Hair:
|
||||
case CharSectionType.Underwear:
|
||||
break;
|
||||
case CharSectionType.CustomDisplay1LowRes:
|
||||
case CharSectionType.CustomDisplay2LowRes:
|
||||
case CharSectionType.CustomDisplay3LowRes:
|
||||
++baseSection;
|
||||
break;
|
||||
case CharSectionType.CustomDisplay1:
|
||||
case CharSectionType.CustomDisplay2:
|
||||
case CharSectionType.CustomDisplay3:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
uint sectionKey = (uint)(baseSection | (charSection.Gender << 8) | (charSection.Race << 16));
|
||||
Tuple<byte, byte> sectionCombination = Tuple.Create(charSection.Type, charSection.Color);
|
||||
Tuple<byte, byte, CharBaseSectionVariation> sectionKey = Tuple.Create(charSection.RaceID, charSection.SexID, sectionToBase[charSection.BaseSection]);
|
||||
Tuple<byte, byte> sectionCombination = Tuple.Create(charSection.VariationIndex, charSection.ColorIndex);
|
||||
if (addedSections.Contains(sectionKey, sectionCombination))
|
||||
continue;
|
||||
|
||||
@@ -382,6 +363,16 @@ namespace Game.DataStorage
|
||||
foreach (ToyRecord toy in CliDB.ToyStorage.Values)
|
||||
_toys.Add(toy.ItemID);
|
||||
|
||||
foreach (TransmogSetItemRecord transmogSetItem in CliDB.TransmogSetItemStorage.Values)
|
||||
{
|
||||
TransmogSetRecord set = CliDB.TransmogSetStorage.LookupByKey(transmogSetItem.TransmogSetID);
|
||||
if (set == null)
|
||||
continue;
|
||||
|
||||
_transmogSetsByItemModifiedAppearance.Add(transmogSetItem.ItemModifiedAppearanceID, set);
|
||||
_transmogSetItemsByTransmogSet.Add(transmogSetItem.TransmogSetID, transmogSetItem);
|
||||
}
|
||||
|
||||
foreach (WMOAreaTableRecord entry in CliDB.WMOAreaTableStorage.Values)
|
||||
_wmoAreaTableLookup[Tuple.Create(entry.WMOID, entry.NameSet, entry.WMOGroupID)] = entry;
|
||||
|
||||
@@ -523,11 +514,21 @@ namespace Game.DataStorage
|
||||
return broadcastText.MaleText[SharedConst.DefaultLocale];
|
||||
}
|
||||
|
||||
public CharSectionsRecord GetCharSectionEntry(Race race, CharSectionType genType, Gender gender, byte type, byte color)
|
||||
public bool HasCharacterFacialHairStyle(Race race, Gender gender, uint variationId)
|
||||
{
|
||||
var list = _charSections.LookupByKey((byte)genType | ((byte)gender << 8) | ((byte)race << 16));
|
||||
return _characterFacialHairStyles.Contains(Tuple.Create((byte)race, (byte)gender, variationId));
|
||||
}
|
||||
|
||||
public bool HasCharSections(Race race, Gender gender, CharBaseSectionVariation variation)
|
||||
{
|
||||
return _charSections.ContainsKey(Tuple.Create(race, gender, variation));
|
||||
}
|
||||
|
||||
public CharSectionsRecord GetCharSectionEntry(Race race, Gender gender, CharBaseSectionVariation variation, byte variationIndex, byte colorIndex)
|
||||
{
|
||||
var list = _charSections.LookupByKey(Tuple.Create(race, gender, variation));
|
||||
foreach (var charSection in list)
|
||||
if (charSection.Type == type && charSection.Color == color)
|
||||
if (charSection.VariationIndex == variationIndex && charSection.ColorIndex == colorIndex)
|
||||
return charSection;
|
||||
|
||||
return null;
|
||||
@@ -1200,6 +1201,16 @@ namespace Game.DataStorage
|
||||
return _toys.Contains(toy);
|
||||
}
|
||||
|
||||
public List<TransmogSetRecord> GetTransmogSetsForItemModifiedAppearance(uint itemModifiedAppearanceId)
|
||||
{
|
||||
return _transmogSetsByItemModifiedAppearance.LookupByKey(itemModifiedAppearanceId);
|
||||
}
|
||||
|
||||
public List<TransmogSetItemRecord> GetTransmogSetItems(uint transmogSetId)
|
||||
{
|
||||
return _transmogSetItemsByTransmogSet.LookupByKey(transmogSetId);
|
||||
}
|
||||
|
||||
public WMOAreaTableRecord GetWMOAreaTable(int rootId, int adtId, int groupId)
|
||||
{
|
||||
var wmoAreaTable = _wmoAreaTableLookup.LookupByKey(Tuple.Create((short)rootId, (sbyte)adtId, groupId));
|
||||
@@ -1307,7 +1318,8 @@ namespace Game.DataStorage
|
||||
MultiMap<uint, ArtifactPowerRecord> _artifactPowers = new MultiMap<uint, ArtifactPowerRecord>();
|
||||
MultiMap<uint, uint> _artifactPowerLinks = new MultiMap<uint, uint>();
|
||||
Dictionary<Tuple<uint, byte>, ArtifactPowerRankRecord> _artifactPowerRanks = new Dictionary<Tuple<uint, byte>, ArtifactPowerRankRecord>();
|
||||
MultiMap<uint, CharSectionsRecord> _charSections = new MultiMap<uint, CharSectionsRecord>();
|
||||
List<Tuple<byte, byte, uint>> _characterFacialHairStyles = new List<Tuple<byte, byte, uint>>();
|
||||
MultiMap<Tuple<byte, byte, CharBaseSectionVariation>, CharSectionsRecord> _charSections = new MultiMap<Tuple<byte, byte, CharBaseSectionVariation>, CharSectionsRecord>();
|
||||
Dictionary<uint, CharStartOutfitRecord> _charStartOutfits = new Dictionary<uint, CharStartOutfitRecord>();
|
||||
uint[][] _powersByClass = new uint[(int)Class.Max][];
|
||||
ChrSpecializationRecord[][] _chrSpecializationsByIndex = new ChrSpecializationRecord[(int)Class.Max + 1][];
|
||||
@@ -1348,6 +1360,8 @@ namespace Game.DataStorage
|
||||
MultiMap<uint, SpellProcsPerMinuteModRecord> _spellProcsPerMinuteMods = new MultiMap<uint, SpellProcsPerMinuteModRecord>();
|
||||
List<TalentRecord>[][][] _talentsByPosition = new List<TalentRecord>[(int)Class.Max][][];
|
||||
List<uint> _toys = new List<uint>();
|
||||
MultiMap<uint, TransmogSetRecord> _transmogSetsByItemModifiedAppearance = new MultiMap<uint, TransmogSetRecord>();
|
||||
MultiMap<uint, TransmogSetItemRecord> _transmogSetItemsByTransmogSet = new MultiMap<uint, TransmogSetItemRecord>();
|
||||
Dictionary<Tuple<short, sbyte, int>, WMOAreaTableRecord> _wmoAreaTableLookup = new Dictionary<Tuple<short, sbyte, int>, WMOAreaTableRecord>();
|
||||
Dictionary<uint, WorldMapAreaRecord> _worldMapAreaByAreaID = new Dictionary<uint, WorldMapAreaRecord>();
|
||||
}
|
||||
|
||||
@@ -20,16 +20,33 @@ using Framework.GameMath;
|
||||
|
||||
namespace Game.DataStorage
|
||||
{
|
||||
public sealed class CharacterFacialHairStylesRecord
|
||||
{
|
||||
public uint ID;
|
||||
public uint[] Geoset = new uint[5];
|
||||
public byte RaceID;
|
||||
public byte SexID;
|
||||
public byte VariationID;
|
||||
}
|
||||
|
||||
public sealed class CharBaseSectionRecord
|
||||
{
|
||||
public uint ID;
|
||||
public CharBaseSectionVariation Variation;
|
||||
public byte ResolutionVariation;
|
||||
public byte Resolution;
|
||||
}
|
||||
|
||||
public sealed class CharSectionsRecord
|
||||
{
|
||||
public uint Id;
|
||||
public uint[] TextureFileDataID = new uint[3];
|
||||
public ushort Flags;
|
||||
public byte Race;
|
||||
public byte Gender;
|
||||
public byte GenType;
|
||||
public byte Type;
|
||||
public byte Color;
|
||||
public byte RaceID;
|
||||
public byte SexID;
|
||||
public byte BaseSection;
|
||||
public byte VariationIndex;
|
||||
public byte ColorIndex;
|
||||
}
|
||||
|
||||
public sealed class CharStartOutfitRecord
|
||||
|
||||
@@ -91,6 +91,40 @@ namespace Game.DataStorage
|
||||
public uint Id;
|
||||
}
|
||||
|
||||
public sealed class TransmogHolidayRecord
|
||||
{
|
||||
public uint Id;
|
||||
public int HolidayID;
|
||||
}
|
||||
|
||||
public sealed class TransmogSetRecord
|
||||
{
|
||||
public LocalizedString Name;
|
||||
public ushort BaseSetID;
|
||||
public ushort UIOrder;
|
||||
public byte ExpansionID;
|
||||
public uint Id;
|
||||
public int Flags;
|
||||
public int QuestID;
|
||||
public int ClassMask;
|
||||
public int ItemNameDescriptionID;
|
||||
public uint TransmogSetGroupID;
|
||||
}
|
||||
|
||||
public sealed class TransmogSetGroupRecord
|
||||
{
|
||||
public LocalizedString Label;
|
||||
public uint Id;
|
||||
}
|
||||
|
||||
public sealed class TransmogSetItemRecord
|
||||
{
|
||||
public uint Id;
|
||||
public uint TransmogSetID;
|
||||
public uint ItemModifiedAppearanceID;
|
||||
public int Flags;
|
||||
}
|
||||
|
||||
public sealed class TransportAnimationRecord
|
||||
{
|
||||
public uint Id;
|
||||
|
||||
Reference in New Issue
Block a user