Esempio n. 1
0
        /// <summary>
        /// Retrieves the file path to the model's base skeleton file.
        /// </summary>
        /// <param name="fullMdlPath"></param>
        private static async Task <string> GetBaseSkelbPath(XivDependencyRootInfo root, XivRace race = XivRace.All_Races)
        {
            var skelFolder = "";
            var skelFile   = "";

            if (root.PrimaryType != XivItemType.human && root.PrimaryType != XivItemType.equipment && root.PrimaryType != XivItemType.accessory)
            {
                var typeName = XivItemTypes.GetSystemName(root.PrimaryType);
                var prefix   = XivItemTypes.GetSystemPrefix(root.PrimaryType);
                var id       = root.PrimaryId.ToString().PadLeft(4, '0');
                var bodyCode = "0001";
                var path     = $"chara/{typeName}/{prefix}{id}/skeleton/base/b{bodyCode}/skl_{prefix}{id}b{bodyCode}.sklb";
                return(path);
            }
            else
            {
                // Equipment and accessories need an external race passed in.
                var raceCode = race.GetRaceCode();
                if (root.PrimaryType == XivItemType.human && race != XivRace.All_Races)
                {
                    raceCode = root.PrimaryId.ToString().PadLeft(4, '0');
                }

                var bodyCode = "0001";
                skelFolder = $"chara/human/c{raceCode}/skeleton/base/b{bodyCode}";
                skelFile   = $"skl_c{raceCode}b{bodyCode}.sklb";
                return(skelFolder + "/" + skelFile);
            }
        }
Esempio n. 2
0
        public static char GetVfxPrefix(XivDependencyRootInfo root)
        {
            var itemType = root.PrimaryType;

            if (root.PrimaryType == XivItemType.demihuman)
            {
                itemType = (XivItemType)root.SecondaryType;
            }

            if (itemType == XivItemType.equipment)
            {
                return('e');
            }
            else if (itemType == XivItemType.weapon)
            {
                return('w');
            }
            else if (itemType == XivItemType.monster)
            {
                return('m');
            }
            else
            {
                return('\0');
            }
        }
Esempio n. 3
0
        private static async Task <string> GetExtraSkelbPath(XivDependencyRootInfo root, XivRace race = XivRace.All_Races)
        {
            var type = Est.GetEstType(root);

            // Type doesn't use extra skels.
            if (type == Est.EstType.Invalid)
            {
                return(null);
            }


            var id = (ushort)root.PrimaryId;

            if (type == Est.EstType.Face || type == Est.EstType.Hair)
            {
                id = (ushort)root.SecondaryId;
            }

            // Hair and face types have a race defined at root level.
            if ((type == Est.EstType.Face || type == Est.EstType.Hair) && race == XivRace.All_Races)
            {
                var ret = new Dictionary <XivRace, ExtraSkeletonEntry>();
                race = XivRaces.GetXivRace(root.PrimaryId);
            }


            var entry = await Est.GetExtraSkeletonEntry(type, race, id);

            var skelId = entry.SkelId;

            if (skelId == 0)
            {
                if (race == XivRace.Hyur_Midlander_Male)
                {
                    return(null);
                }

                // Okay, this model, *as defined* has no EX Skeleton.  _HOWEVER_ its parent skeleton could.
                // So we need to re-call and check up the chain until we hit Hyur M.

                var parent = XivRaceTree.GetNode(race).Parent;
                if (parent == null)
                {
                    return(null);
                }

                // It's worth noting in these cases, the Skeletal bones themselves will still be using the matrices appropriate
                // for their parent race in this method, but that should be sufficient for now.
                return(await GetExtraSkelbPath(root, parent.Race));
            }

            var prefix   = Est.GetSystemPrefix(type);
            var slot     = Est.GetSystemSlot(type);
            var raceCode = XivRaces.GetRaceCode(race);
            var skelCode = skelId.ToString().PadLeft(4, '0');
            var path     = $"chara/human/c{raceCode}/skeleton/{slot}/{prefix}{skelCode}/skl_c{raceCode}{prefix}{skelCode}.sklb";

            return(path);
        }
Esempio n. 4
0
 public static bool UsesImc(XivDependencyRootInfo root)
 {
     if (root.PrimaryType == XivItemType.human)
     {
         return(false);
     }
     else if (root.PrimaryType == XivItemType.indoor || root.PrimaryType == XivItemType.outdoor)
     {
         return(false);
     }
     else
     {
         return(true);
     }
 }
Esempio n. 5
0
        public static async Task <string> GetExtraSkeletonFile(XivDependencyRootInfo root, XivRace race = XivRace.All_Races)
        {
            if (root.SecondaryType == XivItemType.ear)
            {
                // Viera ears technically use their associated face's Extra Skeleton to resolve the bones.  Kinda weird, but whatever.
                // The bones are nearly identical for all the faces, so just use face 1
                var nRoot = new XivDependencyRootInfo()
                {
                    PrimaryType   = root.PrimaryType,
                    PrimaryId     = root.PrimaryId,
                    SecondaryId   = 1,
                    SecondaryType = XivItemType.face,
                    Slot          = "fac"
                };
                root = nRoot;
            }

            var file = await GetExtraSkelbPath(root, race);

            if (file == null)
            {
                return(null);
            }

            var skelName = Path.GetFileNameWithoutExtension(file).Replace("skl_", "");

            var cwd        = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetEntryAssembly().Location);
            var parsedFile = Path.Combine(cwd, SkeletonsFolder, skelName + ".skel");

            if (File.Exists(parsedFile))
            {
                return(parsedFile);
            }

            try
            {
                // In some cases, the extra skeleton doesn't actually exist, despite the
                // game files saying it should.  In these cases, SE actually intends to
                // default to the base skel.
                await ExtractAndParseSkel(file);
            }
            catch
            {
                return(null);
            }
            return(parsedFile);
        }
Esempio n. 6
0
        public static async Task <string> GetBaseSkeletonFile(XivDependencyRootInfo root, XivRace race)
        {
            var file = await GetBaseSkelbPath(root, race);

            var skelName = Path.GetFileNameWithoutExtension(file).Replace("skl_", "");

            var cwd        = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetEntryAssembly().Location);
            var parsedFile = Path.Combine(cwd, SkeletonsFolder, skelName + ".skel");

            if (File.Exists(parsedFile))
            {
                return(parsedFile);
            }
            await ExtractAndParseSkel(file);

            return(parsedFile);
        }
Esempio n. 7
0
        private void Mw_SelectedPrimaryItemValueChanged(object sender, int e)
        {
            if (_root == null)
            {
                return;
            }

            // Only human types have the weird multi-root "Item" representation thing.
            if (_root.Info.PrimaryType != XivItemType.human)
            {
                return;
            }

            // Body stuff is totally desynced.
            if (_root.Info.SecondaryType == XivItemType.body)
            {
                return;
            }

            if (e <= 0)
            {
                return;
            }
            if (e == (int)_root.Info.SecondaryId)
            {
                return;
            }


            // Change root to the new "number" root.
            var nRoot = new XivDependencyRootInfo()
            {
                PrimaryId     = _root.Info.PrimaryId,
                PrimaryType   = _root.Info.PrimaryType,
                SecondaryId   = e,
                SecondaryType = _root.Info.SecondaryType,
                Slot          = _root.Info.Slot
            };

            _lastNumber = e;

            // Switch display to that new root.
            SetRoot(nRoot.ToFullRoot());
        }
Esempio n. 8
0
 public static EstType GetEstType(XivDependencyRootInfo root)
 {
     if (root.PrimaryType == XivItemType.human)
     {
         if (root.SecondaryType == XivItemType.face)
         {
             return(EstType.Face);
         }
         else if (root.SecondaryType == XivItemType.hair)
         {
             return(EstType.Hair);
         }
         else
         {
             return(EstType.Invalid);
         }
     }
     else if (root.PrimaryType == XivItemType.equipment)
     {
         if (root.Slot == "met")
         {
             return(EstType.Head);
         }
         else if (root.Slot == "top")
         {
             return(EstType.Body);
         }
         else
         {
             return(EstType.Invalid);
         }
     }
     else
     {
         return(EstType.Invalid);
     }
 }
Esempio n. 9
0
        public static async Task <(string Folder, string File)> GetVfxPath(XivDependencyRootInfo root, int vfx)
        {
            var type      = root.PrimaryType;
            var id        = root.PrimaryId.ToString().PadLeft(4, '0');
            var bodyVer   = root.SecondaryId.ToString().PadLeft(4, '0');
            var prefix    = XivItemTypes.GetSystemPrefix(type);
            var vfxPrefix = GetVfxPrefix(root);

            string vfxFolder, vfxFile;

            switch (type)
            {//
            case XivItemType.equipment:
                vfxFolder = $"chara/{type}/{prefix}{id}/vfx/eff";
                vfxFile   = $"v{vfxPrefix}{vfx.ToString().PadLeft(4, '0')}.avfx";
                break;

            case XivItemType.weapon:
            case XivItemType.monster:
                vfxFolder = $"chara/{type}/{prefix}{id}/obj/body/b{bodyVer}/vfx/eff";
                vfxFile   = $"v{vfxPrefix}{vfx.ToString().PadLeft(4, '0')}.avfx";
                break;

            case XivItemType.demihuman:
                vfxFolder = $"chara/{type}/{prefix}{id}/obj/equipment/e{bodyVer}/vfx/eff";
                vfxFile   = $"v{vfxPrefix}{vfx.ToString().PadLeft(4, '0')}.avfx";
                break;

            default:
                vfxFolder = "";
                vfxFile   = "";
                break;
            }

            return(vfxFolder, vfxFile);
        }
Esempio n. 10
0
        public static async Task <Dictionary <XivRace, ExtraSkeletonEntry> > GetExtraSkeletonEntries(XivDependencyRootInfo root, bool forceDefault = false)
        {
            var type = GetEstType(root);

            if (type == EstType.Invalid)
            {
                return(new Dictionary <XivRace, ExtraSkeletonEntry>());
            }

            var id = (ushort)root.PrimaryId;

            if (type == EstType.Face || type == EstType.Hair)
            {
                id = (ushort)root.SecondaryId;
            }
            var entries = await GetExtraSkeletonEntries(type, id, forceDefault);


            // Hair and Faces have to be further trimmed down to only the entries associated with their root.
            if (type == EstType.Face || type == EstType.Hair)
            {
                var ret  = new Dictionary <XivRace, ExtraSkeletonEntry>();
                var race = XivRaces.GetXivRace(root.PrimaryId);

                if (entries.ContainsKey(race))
                {
                    ret.Add(race, entries[race]);
                }
                else
                {
                    ret.Add(race, new ExtraSkeletonEntry(race, id));
                }
                entries = ret;
            }

            return(entries);
        }
Esempio n. 11
0
        public async Task <bool> SetRoot(XivDependencyRoot root, int defaultVariant = 0)
        {
            _root = root;
            if (_root == null)
            {
                return(false);
            }

            if (root.Info.PrimaryType == XivItemType.human)
            {
                if (_lastNumber > 0)
                {
                    if (_lastNumber != (int)root.Info.SecondaryId)
                    {
                        // Change root to the new "number" root.
                        var nRoot = new XivDependencyRootInfo()
                        {
                            PrimaryId     = _root.Info.PrimaryId,
                            PrimaryType   = _root.Info.PrimaryType,
                            SecondaryId   = _lastNumber,
                            SecondaryType = _root.Info.SecondaryType,
                            Slot          = _root.Info.Slot
                        };
                        _root = nRoot.ToFullRoot();
                    }
                }
                if (_root.Info.SecondaryId > 0)
                {
                    _lastNumber = (int)_root.Info.SecondaryId;
                }
            }

            SetLabel.Content  = XivItemTypes.GetSystemPrefix(root.Info.PrimaryType) + root.Info.PrimaryId.ToString().PadLeft(4, '0');
            SlotLabel.Content = Mdl.SlotAbbreviationDictionary.FirstOrDefault(x => x.Value == _root.Info.Slot).Key + "(" + _root.Info.Slot + ")";

            var items = await _root.GetAllItems();

            ItemNameBox.Text = "[" + items.Count + "] " + items[0].Name;

            var _modding = new Modding(XivCache.GameInfo.GameDirectory);
            var path     = _root.Info.GetRootFile();
            var mod      = await _modding.TryGetModEntry(path);

            if (mod == null)
            {
                ToggleButton.IsEnabled = false;
                ToggleButton.Content   = "Enable";
            }
            else
            {
                ToggleButton.IsEnabled = true;
                if (mod.enabled)
                {
                    ToggleButton.Content = "Disable";
                }
                else
                {
                    ToggleButton.Content = "Enable";
                }
            }

            return(await _vm.SetRoot(_root, defaultVariant));
        }