private static void LoadLandset() { if (!DebugLoadExteriors) { return; } if (_exteriorFixtures == null) { LoadExteriorFixtures(); } if (_blueprints == null) { LoadExteriorBlueprints(); } string landSetPath = FFXIVHSPaths.GetWardLandsetJson(territory); if (!File.Exists(landSetPath)) { //Main and subdivision, 60 plots _landSet = new HousingExteriorStructure[60]; for (int i = 0; i < _landSet.Length; i++) { _landSet[i] = new HousingExteriorStructure(); int numFixtureTypes = Enum.GetValues(typeof(FixtureType)).Length; _landSet[i].fixtures = new int[numFixtureTypes]; } string jsonText = JsonConvert.SerializeObject(_landSet, Formatting.Indented); File.WriteAllText(landSetPath, jsonText); } else { string jsonText = File.ReadAllText(landSetPath); _landSet = JsonConvert.DeserializeObject <HousingExteriorStructure[]>(jsonText); } //TODO: move this, rewrite this ? for (int plotIndex = 0; plotIndex < _landSet.Length; plotIndex++) { Plot plotAt = GetPlot(_territory, plotIndex % 30 + 1, plotIndex > 29); if (_landSet[plotIndex].size == Size.s) { //Verify possibly unset size _landSet[plotIndex].size = plotAt.size; } if (_landSet[plotIndex].fixtures[(int)FixtureType.fnc - 1] == 0) { _landSet[plotIndex].fixtures[(int)FixtureType.fnc - 1] = DefaultFences.fnc[(int)_territory]; } HousingExteriorBlueprint blueprint = _blueprints.set[(int)_landSet[plotIndex].size]; //TODO: If you ever figure out how to tell which transforms are for which house size, fix this string groupName = "{0}_{1:D2}_{2}_house"; string fixedWardName = _territory.ToString().ToLower().Substring(0, _territory.ToString().Length - 1) + '0'; string strSize = _landSet[plotIndex].size.ToString(); groupName = string.Format(groupName, fixedWardName, plotIndex + 1, strSize); Debug.Log(groupName); GameObject parentPlotObject = GameObject.Find(groupName); //For each fixture in our landset element for (int fixtureIndex = 0; fixtureIndex < _landSet[plotIndex].fixtures.Length; fixtureIndex++) { if (_landSet[plotIndex].fixtures[fixtureIndex] == 0) { continue; } FixtureType fixtureType = (FixtureType)fixtureIndex + 1; FFXIVHSLib.Transform[][] transformsForModels = null; Mesh[][][] meshes = GetMeshesForExteriorFixture(_landSet[plotIndex].fixtures[fixtureIndex], ref transformsForModels); //For each variant for (int variantIndex = 0; variantIndex < meshes.Length; variantIndex++) { if (blueprint.fixtureTransforms[fixtureType][variantIndex] == null || meshes[variantIndex] == null) { continue; } //The set of gameobjects for this variant, 1 gameobject per model GameObject[] objects = new GameObject[meshes[variantIndex].Length]; for (int modelIndex = 0; modelIndex < objects.Length; modelIndex++) { objects[modelIndex] = AddMeshToNewGameObject(meshes[variantIndex][modelIndex]); } foreach (FFXIVHSLib.Transform t in blueprint.fixtureTransforms[fixtureType][variantIndex]) { GameObject variantBaseObject = new GameObject(); variantBaseObject.GetComponent <Transform>().SetParent(parentPlotObject.transform); variantBaseObject.GetComponent <Transform>().localPosition = t.translation; variantBaseObject.GetComponent <Transform>().localRotation = t.rotation; variantBaseObject.GetComponent <Transform>().localScale = t.scale; variantBaseObject.name = string.Format("bp{0}_ft{1}_v{2}", _landSet[plotIndex].size, fixtureType, variantIndex); for (int modelIndex = 0; modelIndex < objects.Length; modelIndex++) { if (objects[modelIndex] == null) { continue; } FFXIVHSLib.Transform modelTransform = transformsForModels[variantIndex][modelIndex]; GameObject addedModel = UnityEngine.Object.Instantiate(objects[modelIndex]); addedModel.GetComponent <Transform>().SetParent(variantBaseObject.GetComponent <Transform>()); addedModel.GetComponent <Transform>().localPosition = modelTransform.translation; addedModel.GetComponent <Transform>().localRotation = modelTransform.rotation; addedModel.GetComponent <Transform>().localScale = modelTransform.scale; addedModel.name = addedModel.name.Replace("(Clone)", "_") + string.Format("{0}_{1}_{2}", fixtureIndex, variantIndex, modelIndex); addedModel.SetActive(true); UnityEngine.Object.Destroy(objects[modelIndex]); } } } } } }
/// <summary> /// Returns a HousingExteriorBlueprintSet read from the small, medium, and large sgb paths in /// HousingExteriorBlueprintSet. /// </summary> /// <param name="realm"></param> /// <returns></returns> private static HousingExteriorBlueprintSet ReadExteriorBlueprintSet(ARealmReversed realm) { HousingExteriorBlueprintSet thisSet = new HousingExteriorBlueprintSet(); thisSet.set = new HousingExteriorBlueprint[HousingExteriorBlueprintSet.SgbPaths.Length]; for (int i = 0; i < HousingExteriorBlueprintSet.SgbPaths.Length; i++) { string thisPath = HousingExteriorBlueprintSet.SgbPaths[i]; HousingExteriorBlueprint thisBlueprint = new HousingExteriorBlueprint { size = (Size)i }; //These are hardcoded, double check they're there SaintCoinach.IO.File f; if (!realm.Packs.TryGetFile(thisPath, out f)) { throw new FileNotFoundException(); } SgbFile sgb = new SgbFile(f); foreach (SgbGroup group in sgb.Data.OfType <SgbGroup>()) { foreach (SgbGimmickEntry gim in group.Entries.OfType <SgbGimmickEntry>()) { string gimmickPath = gim.Gimmick.File.Path; /* * Group 1: s1h0 or opt * Group 2: size, dor/wid variant, f for fence, or opt's 2chars * Group 3: fixturetype or m for opt * Group 4: a/b/c/d for fence, . for all others */ Regex pattern = new Regex(@"asset\/(.*)?_(.{1,2})_(.{1,3})([0-9]{4})([a-z]|\.)"); Match m = pattern.Match(gimmickPath); if (!m.Success) { continue; } //Obtain fixture type string fType = m.Groups[3].Value; if (fType == "m") { fType = "o" + m.Groups[2].Value; } FixtureType fixtureType = (FixtureType)Enum.Parse(typeof(FixtureType), fType); //Obtains the variant string, examples: s, m, l, co, ca, ci, a, b, c, d string strVariant = m.Groups[5].Value == "." ? m.Groups[2].Value : m.Groups[5].Value; int variant = 0; //Attempt to parse group 2 into a Size to get variant if (!Enum.TryParse(strVariant, out Size fixtureSize)) { //If we can't parse variant to a size, we have to parse into a different fixture variant if (fixtureType == FixtureType.dor) { variant = (int)Enum.Parse(typeof(DoorVariants), strVariant); } else if (fixtureType == FixtureType.wid) { variant = (int)Enum.Parse(typeof(WindowVariants), strVariant); } else if (fixtureType == FixtureType.fnc) { variant = (int)Enum.Parse(typeof(FenceVariants), strVariant); } } else { //If rof/wal is not same size as blueprint, skip it if (fixtureSize != thisBlueprint.size) { continue; } } if (thisBlueprint.fixtureTransforms[fixtureType][variant] == null) { thisBlueprint.fixtureTransforms[fixtureType][variant] = new List <Transform>(); } List <Transform> listForVariant = thisBlueprint.fixtureTransforms[fixtureType][variant]; Transform t = TransformFromVectors(gim.Header.Translation, gim.Header.Rotation, gim.Header.Scale); listForVariant.Add(t); #region switch statement bad // switch (m.Groups[3].Value) // { // case nameof(FixtureType.rof): // if (m.Groups[2].Value == size.ToString()) // { // //exampe but cool // } // break; // case nameof(FixtureType.wal): // //Do stuff // break; // case nameof(FixtureType.wid): // //Do stuff // break; // case nameof(FixtureType.dor): // //Do stuff // break; // case "m": // switch ("o" + m.Groups[2].Value) // { // case nameof(FixtureType.orf): // //Do stuff // break; // case nameof(FixtureType.owl): // //Do stuff // break; // case nameof(FixtureType.osg): // //Do stuff // break; // } // break; // case nameof(FixtureType.fnc): // //Do stuff // break; // } #endregion } } /* * The transforms relevant to the current blueprint come first, * so figure out how many Transforms aren't for this size house * by checking how many transforms are collectively in the blueprints * below this size and variant, then remove that number of entries. */ if (i > 0) { int[][] numTransformsInSmallerBlueprints = new int[Enum.GetValues(typeof(FixtureType)).Length][]; //For every smaller blueprint for (int smallerBlueprintIndex = 0; smallerBlueprintIndex < i; smallerBlueprintIndex++) { //For every fixture type for (int fixtureTypeIndex = 0; fixtureTypeIndex < numTransformsInSmallerBlueprints.Length; fixtureTypeIndex++) { FixtureType fixtureType = (FixtureType)fixtureTypeIndex + 1; int numberOfVariants = HousingExteriorFixture.GetVariants(fixtureType); if (numTransformsInSmallerBlueprints[fixtureTypeIndex] == null) { numTransformsInSmallerBlueprints[fixtureTypeIndex] = new int[numberOfVariants]; } for (int variantIndex = 0; variantIndex < numberOfVariants; variantIndex++) { int?toAddn = thisSet.set[smallerBlueprintIndex].fixtureTransforms[fixtureType][variantIndex]?.Count; int toAdd = toAddn ?? 0; numTransformsInSmallerBlueprints[fixtureTypeIndex][variantIndex] += toAdd; } } } //Whoops, don't do it for fences for (int j = 0; j < numTransformsInSmallerBlueprints[(int)FixtureType.fnc - 1].Length; j++) { numTransformsInSmallerBlueprints[(int)FixtureType.fnc - 1][j] = 0; } //For every fixture type for (int fixtureTypeIndex = 0; fixtureTypeIndex < numTransformsInSmallerBlueprints.Length; fixtureTypeIndex++) { FixtureType fixtureType = (FixtureType)fixtureTypeIndex + 1; int numberOfVariants = HousingExteriorFixture.GetVariants(fixtureType); for (int variantIndex = 0; variantIndex < numberOfVariants; variantIndex++) { List <Transform> variantTransformsList = thisBlueprint.fixtureTransforms[fixtureType][variantIndex]; if (thisBlueprint.fixtureTransforms[fixtureType][variantIndex] == null) { continue; } if (variantTransformsList == null) { continue; } int numTransforms = variantTransformsList.Count; int difference = numTransforms - numTransformsInSmallerBlueprints[fixtureTypeIndex][variantIndex]; if (difference > 0) { List <Transform> newTransforms = new List <Transform>(); for (int tCount = 0; tCount < difference; tCount++) { newTransforms.Add(variantTransformsList[tCount]); } thisBlueprint.fixtureTransforms[fixtureType][variantIndex] = newTransforms; } } } } thisSet.set[i] = thisBlueprint; } return(thisSet); }