public MPQCOF GetPlayerAnimation(eHero hero, eMobMode mobMode, PlayerEquipment equipment) => cache.AddOrGetExisting($"COF::{hero}{mobMode.ToToken()}{equipment.HashKey}", () => { var path = $"{ResourcePaths.PlayerAnimationBase}\\{hero.ToToken()}\\COF\\{hero.ToToken()}{mobMode.ToToken()}{equipment.WeaponClass.ToToken()}.cof"; return(MPQCOF.Load(mpqProvider.GetStream(path), Animations, hero, mobMode, equipment)); }, new System.Runtime.Caching.CacheItemPolicy { Priority = System.Runtime.Caching.CacheItemPriority.NotRemovable });
public static MPQCOF Load(Stream stream, Dictionary <string, List <AnimationData> > animations, eHero hero, eMobMode mobMode, PlayerEquipment equipment) { var result = new MPQCOF { MobMode = mobMode, Hero = hero }; var br = new BinaryReader(stream); result.NumberOfLayers = br.ReadByte(); result.FramesPerDirection = br.ReadByte(); result.NumberOfDirections = br.ReadByte(); // Number of directions br.ReadBytes(25); // Skip 25 unknown bytes... var layers = new List <COFLayer>(); result.CompositLayers = new Dictionary <eCompositType, int>(); for (var layerIdx = 0; layerIdx < result.NumberOfLayers; layerIdx++) { var layer = new COFLayer { COF = result, CompositType = (eCompositType)br.ReadByte(), Shadow = br.ReadByte() }; br.ReadByte(); // Unknown layer.IsTransparent = br.ReadByte() != 0; layer.DrawEffect = (eDrawEffect)br.ReadByte(); layer.WeaponClass = Encoding.ASCII.GetString(br.ReadBytes(4)).Trim('\0').ToWeaponClass(); layers.Add(layer); result.CompositLayers[layer.CompositType] = layerIdx; } result.Layers = layers.ToArray(); result.AnimationFrames = br.ReadBytes(result.FramesPerDirection).Select(x => (eAnimationFrame)x); result.Priority = br.ReadBytes(result.FramesPerDirection * result.NumberOfLayers * result.NumberOfDirections).Select(x => (eCompositType)x).ToArray(); var cofName = $"{hero.ToToken()}{mobMode.ToToken()}{equipment.WeaponClass.ToToken()}".ToUpper(); result.Animations = animations[cofName]; br.Dispose(); return(result); }
public string GetCharacterDccPath(eHero hero, eMobMode mobMode, eCompositType compositType, PlayerEquipment equipment) { var fileName = $@"{ResourcePaths.PlayerAnimationBase}\{hero.ToToken()}\{compositType.ToToken()}\{hero.ToToken()}{compositType.ToToken()}".ToLower(); var armorType = eArmorType.Lite; // Override default armor type based on equipped torso if (equipment.Torso != null && (equipment.Torso.Item as Armor).ArmorTypes.ContainsKey(compositType)) { armorType = (equipment.Torso.Item as Armor).ArmorTypes[compositType]; } switch (compositType) { case eCompositType.Head: fileName += $"{equipment.Head?.Item.Code ?? eArmorType.Lite.ToToken()}{mobMode.ToToken()}"; return(_mpqLookup.ContainsKey($"{fileName}{equipment.WeaponClass.ToToken()}.dcc".ToLower()) ? $"{fileName}{equipment.WeaponClass.ToToken()}.dcc".ToLower() : $"{fileName}{eWeaponClass.HandToHand.ToToken()}.dcc".ToLower()); case eCompositType.Torso: case eCompositType.Legs: case eCompositType.RightArm: case eCompositType.LeftArm: fileName += $"{armorType.ToToken()}{mobMode.ToToken()}"; return(_mpqLookup.ContainsKey($"{fileName}{equipment.WeaponClass.ToToken()}.dcc".ToLower()) ? $"{fileName}{equipment.WeaponClass.ToToken()}.dcc".ToLower() : $"{fileName}{eWeaponClass.HandToHand.ToToken()}.dcc".ToLower()); case eCompositType.RightHand: if (!(equipment.RightArm?.Item is Weapon)) { return(null); } fileName += $"{equipment.RightArm.Item.Code}{mobMode.ToToken()}{equipment.WeaponClass.ToToken()}.dcc".ToLower(); return(fileName); case eCompositType.LeftHand: if (!(equipment.LeftArm?.Item is Weapon)) { return(null); } fileName += $"{equipment.LeftArm.Item.Code}{mobMode.ToToken()}{equipment.WeaponClass.ToToken()}.dcc".ToLower(); return(fileName); case eCompositType.Shield: if (!(equipment.LeftArm?.Item is Armor)) { return(null); } fileName += $"{equipment.LeftArm.Item.Code}{mobMode.ToToken()}"; return(_mpqLookup.ContainsKey($"{fileName}{equipment.WeaponClass.ToToken()}.dcc".ToLower()) ? $"{fileName}{equipment.WeaponClass.ToToken()}.dcc".ToLower() : $"{fileName}{eWeaponClass.HandToHand.ToToken()}.dcc".ToLower()); // TODO: Figure these out... case eCompositType.Special1: case eCompositType.Special2: fileName += $"{armorType.ToToken()}{mobMode.ToToken()}{equipment.WeaponClass}.dcc".ToLower(); return(_mpqLookup.ContainsKey(fileName) ? fileName : null); // TODO: Should we silence this? case eCompositType.Special3: case eCompositType.Special4: case eCompositType.Special5: case eCompositType.Special6: case eCompositType.Special7: case eCompositType.Special8: default: return(null); } }