public void SetLocation(DFLocation location, bool performLayout = true) { if (!ReadyCheck()) { return; } // Validate if (this.isSet) { throw new Exception("This location has already been set."); } if (!location.Loaded) { throw new Exception("DFLocation not loaded."); } // Set summary summary = new LocationSummary(); summary.MapID = location.MapTableData.MapId; summary.Longitude = (int)location.MapTableData.Longitude; summary.Latitude = (int)location.MapTableData.Latitude; DFPosition mapPixel = MapsFile.LongitudeLatitudeToMapPixel(summary.Longitude, summary.Latitude); DFPosition worldCoord = MapsFile.MapPixelToWorldCoord(mapPixel.X, mapPixel.Y); summary.MapPixelX = mapPixel.X; summary.MapPixelY = mapPixel.Y; summary.WorldCoordX = worldCoord.X; summary.WorldCoordZ = worldCoord.Y; summary.RegionName = location.RegionName; summary.LocationName = location.Name; summary.WorldClimate = (MapsFile.Climates)location.Climate.WorldClimate; summary.LocationType = location.MapTableData.LocationType; summary.DungeonType = location.MapTableData.DungeonType; summary.HasDungeon = location.HasDungeon; summary.Climate = ClimateSwaps.FromAPIClimateBase(location.Climate.ClimateType); summary.Nature = ClimateSwaps.FromAPITextureSet(location.Climate.NatureSet); summary.SkyBase = location.Climate.SkyBase; summary.BlockWidth = location.Exterior.ExteriorData.Width; summary.BlockHeight = location.Exterior.ExteriorData.Height; summary.LegacyLocation = location; // Assign starting climate CurrentSeason = ClimateSeason.Summer; CurrentClimate = summary.Climate; CurrentNatureSet = summary.Nature; // Perform layout if (performLayout) { LayoutLocation(ref location); ApplyClimateSettings(); } // Set location rect SetLocationRect(); // Seal location isSet = true; }
public static void AddNatureFlats( DaggerfallUnity dfUnity, ref DFBlock blockData, Transform parent = null, ClimateNatureSets climateNature = ClimateNatureSets.SubTropical, ClimateSeason climateSeason = ClimateSeason.Summer) { int archive = ClimateSwaps.GetNatureArchive(climateNature, climateSeason); // Add block scenery for (int y = 0; y < 16; y++) { for (int x = 0; x < 16; x++) { // Get scenery item DFBlock.RmbGroundScenery scenery = blockData.RmbBlock.FldHeader.GroundData.GroundScenery[x, 15 - y]; // Ignore 0 as this appears to be a marker/waypoint of some kind if (scenery.TextureRecord > 0) { // Spawn billboard gameobject GameObject go = GameObjectHelper.CreateDaggerfallBillboardGameObject(archive, scenery.TextureRecord, parent); Vector3 billboardPosition = new Vector3( x * BlocksFile.TileDimension, NatureFlatsOffsetY, y * BlocksFile.TileDimension + BlocksFile.TileDimension) * MeshReader.GlobalScale; // Set transform go.transform.position = billboardPosition; } } } }
/// <summary> /// Add nature billboards. /// </summary> public static void AddNatureFlats( ref DFBlock blockData, Transform flatsParent, DaggerfallBillboardBatch billboardBatch = null, ClimateNatureSets climateNature = ClimateNatureSets.TemperateWoodland, ClimateSeason climateSeason = ClimateSeason.Summer) { DaggerfallUnity dfUnity = DaggerfallUnity.Instance; if (!dfUnity.IsReady) { return; } for (int y = 0; y < 16; y++) { for (int x = 0; x < 16; x++) { // Get scenery item - ignore indices -1 (empty) and 0 (marker/waypoint of some kind) DFBlock.RmbGroundScenery scenery = blockData.RmbBlock.FldHeader.GroundData.GroundScenery[x, 15 - y]; if (scenery.TextureRecord < 1) { continue; } // Calculate position Vector3 billboardPosition = new Vector3( x * BlocksFile.TileDimension, natureFlatsOffsetY, y * BlocksFile.TileDimension + BlocksFile.TileDimension) * MeshReader.GlobalScale; // Get Archive int natureArchive = ClimateSwaps.GetNatureArchive(climateNature, climateSeason); // Import custom 3d gameobject instead of flat if (MeshReplacement.ImportCustomFlatGameobject(natureArchive, scenery.TextureRecord, billboardPosition, flatsParent) != null) { continue; } // Add billboard to batch or standalone if (billboardBatch != null) { billboardBatch.AddItem(scenery.TextureRecord, billboardPosition); } else { GameObject go = GameObjectHelper.CreateDaggerfallBillboardGameObject(natureArchive, scenery.TextureRecord, flatsParent); go.transform.position = billboardPosition; AlignBillboardToBase(go); } } } }
public static int GetNatureArchive(DFLocation.ClimateTextureSet climateTextureSet, DaggerfallDateTime.Seasons worldSeason) { ClimateNatureSets natureSet = FromAPITextureSet(climateTextureSet); ClimateSeason climateSeason = ClimateSeason.Summer; if (worldSeason == DaggerfallDateTime.Seasons.Winter) { climateSeason = ClimateSeason.Winter; } return(GetNatureArchive(natureSet, climateSeason)); }
/// <summary> /// Layout RMB block gamne object from name only. /// This will be missing information like building data and should only be used standalone. /// </summary> public static GameObject CreateRMBBlockGameObject( string blockName, int layoutX, int layoutY, bool addGroundPlane = true, DaggerfallRMBBlock cloneFrom = null, DaggerfallBillboardBatch natureBillboardBatch = null, DaggerfallBillboardBatch lightsBillboardBatch = null, DaggerfallBillboardBatch animalsBillboardBatch = null, TextureAtlasBuilder miscBillboardAtlas = null, DaggerfallBillboardBatch miscBillboardBatch = null, ClimateNatureSets climateNature = ClimateNatureSets.TemperateWoodland, ClimateSeason climateSeason = ClimateSeason.Summer) { // Get block data from name DFBlock blockData; if (!RMBLayout.GetBlockData(blockName, out blockData)) { return(null); } // Create base object from block data GameObject go = CreateRMBBlockGameObject( blockData, layoutX, layoutY, addGroundPlane, cloneFrom, natureBillboardBatch, lightsBillboardBatch, animalsBillboardBatch, miscBillboardAtlas, miscBillboardBatch, climateNature, climateSeason); return(go); }
public static int GetNatureArchive(ClimateNatureSets natureSet, ClimateSeason climateSeason) { // Get base set DFLocation.ClimateTextureSet textureSet; switch (natureSet) { case ClimateNatureSets.RainForest: textureSet = DFLocation.ClimateTextureSet.Nature_RainForest; break; case ClimateNatureSets.SubTropical: textureSet = DFLocation.ClimateTextureSet.Nature_SubTropical; break; case ClimateNatureSets.Swamp: textureSet = DFLocation.ClimateTextureSet.Nature_Swamp; break; case ClimateNatureSets.Desert: textureSet = DFLocation.ClimateTextureSet.Nature_Desert; break; case ClimateNatureSets.TemperateWoodland: textureSet = DFLocation.ClimateTextureSet.Nature_TemperateWoodland; break; case ClimateNatureSets.WoodlandHills: textureSet = DFLocation.ClimateTextureSet.Nature_WoodlandHills; break; case ClimateNatureSets.HauntedWoodlands: textureSet = DFLocation.ClimateTextureSet.Nature_HauntedWoodlands; break; case ClimateNatureSets.Mountains: textureSet = DFLocation.ClimateTextureSet.Nature_Mountains; break; default: textureSet = DFLocation.ClimateTextureSet.Nature_TemperateWoodland; break; } var archive = (int)textureSet; // Winter modifier if (climateSeason == ClimateSeason.Winter) { // Only certain sets have a winter archive switch (natureSet) { case ClimateNatureSets.TemperateWoodland: case ClimateNatureSets.WoodlandHills: case ClimateNatureSets.HauntedWoodlands: case ClimateNatureSets.Mountains: archive += 1; break; } } return(archive); }
public static int GetNatureArchive(ClimateNatureSets natureSet, ClimateSeason climateSeason) { // Get base set int archive; switch (natureSet) { case ClimateNatureSets.RainForest: archive = 500; break; case ClimateNatureSets.SubTropical: archive = 501; break; case ClimateNatureSets.Swamp: archive = 502; break; case ClimateNatureSets.Desert: archive = 503; break; case ClimateNatureSets.TemperateWoodland: archive = 504; break; case ClimateNatureSets.WoodlandHills: archive = 506; break; case ClimateNatureSets.HauntedWoodlands: archive = 508; break; case ClimateNatureSets.Mountains: archive = 510; break; default: archive = 504; break; } // Winter modifier if (climateSeason == ClimateSeason.Winter) { // Only certain sets have a winter archive switch (natureSet) { case ClimateNatureSets.TemperateWoodland: case ClimateNatureSets.WoodlandHills: case ClimateNatureSets.HauntedWoodlands: case ClimateNatureSets.Mountains: archive += 1; break; } } return(archive); }
public static int GetNatureArchive(ClimateNatureSets natureSet, ClimateSeason climateSeason) { // Get base set int archive; switch (natureSet) { case ClimateNatureSets.RainForest: archive = 500; break; case ClimateNatureSets.SubTropical: archive = 501; break; case ClimateNatureSets.Swamp: archive = 502; break; case ClimateNatureSets.Desert: archive = 503; break; case ClimateNatureSets.TemperateWoodland: archive = 504; break; case ClimateNatureSets.WoodlandHills: archive = 506; break; case ClimateNatureSets.HauntedWoodlands: archive = 508; break; case ClimateNatureSets.Mountains: archive = 510; break; default: archive = 504; break; } // Winter modifier if (climateSeason == ClimateSeason.Winter) { // Only certain sets have a winter archive switch (natureSet) { case ClimateNatureSets.TemperateWoodland: case ClimateNatureSets.WoodlandHills: case ClimateNatureSets.HauntedWoodlands: case ClimateNatureSets.Mountains: archive += 1; break; } } return archive; }
/// <summary> /// Layout a complete RMB block game object. /// Can be used standalone or as part of a city build. /// </summary> public static GameObject CreateRMBBlockGameObject( string blockName, bool addGroundPlane = true, DaggerfallRMBBlock cloneFrom = null, DaggerfallBillboardBatch natureBillboardBatch = null, DaggerfallBillboardBatch lightsBillboardBatch = null, DaggerfallBillboardBatch animalsBillboardBatch = null, TextureAtlasBuilder miscBillboardAtlas = null, DaggerfallBillboardBatch miscBillboardBatch = null, ClimateNatureSets climateNature = ClimateNatureSets.TemperateWoodland, ClimateSeason climateSeason = ClimateSeason.Summer) { // Get DaggerfallUnity DaggerfallUnity dfUnity = DaggerfallUnity.Instance; if (!dfUnity.IsReady) return null; // Create base object DFBlock blockData; GameObject go = RMBLayout.CreateBaseGameObject(blockName, out blockData, cloneFrom); // Create flats node GameObject flatsNode = new GameObject("Flats"); flatsNode.transform.parent = go.transform; // Create lights node GameObject lightsNode = new GameObject("Lights"); lightsNode.transform.parent = go.transform; // If billboard batching is enabled but user has not specified // a batch, then make our own auto batch for this block bool autoLightsBatch = false; bool autoNatureBatch = false; bool autoAnimalsBatch = false; if (dfUnity.Option_BatchBillboards) { if (natureBillboardBatch == null) { autoNatureBatch = true; int natureArchive = ClimateSwaps.GetNatureArchive(climateNature, climateSeason); natureBillboardBatch = GameObjectHelper.CreateBillboardBatchGameObject(natureArchive, flatsNode.transform); } if (lightsBillboardBatch == null) { autoLightsBatch = true; lightsBillboardBatch = GameObjectHelper.CreateBillboardBatchGameObject(TextureReader.LightsTextureArchive, flatsNode.transform); } if (animalsBillboardBatch == null) { autoAnimalsBatch = true; animalsBillboardBatch = GameObjectHelper.CreateBillboardBatchGameObject(TextureReader.AnimalsTextureArchive, flatsNode.transform); } } // Layout light billboards and gameobjects RMBLayout.AddLights(ref blockData, flatsNode.transform, lightsNode.transform, lightsBillboardBatch); // Layout nature billboards RMBLayout.AddNatureFlats(ref blockData, flatsNode.transform, natureBillboardBatch, climateNature, climateSeason); // Layout all other flats RMBLayout.AddMiscBlockFlats(ref blockData, flatsNode.transform, animalsBillboardBatch, miscBillboardAtlas, miscBillboardBatch); // Add ground plane if (addGroundPlane) RMBLayout.AddGroundPlane(ref blockData, go.transform); // Apply auto batches if (autoNatureBatch) natureBillboardBatch.Apply(); if (autoLightsBatch) lightsBillboardBatch.Apply(); if (autoAnimalsBatch) animalsBillboardBatch.Apply(); return go; }
public void SetLocation(DFLocation location, bool performLayout = true) { if (!ReadyCheck()) return; // Validate if (this.isSet) throw new Exception("This location has already been set."); if (!location.Loaded) throw new Exception("DFLocation not loaded."); // Set summary summary = new LocationSummary(); summary.ID = location.MapTableData.MapId; summary.Longitude = (int)location.MapTableData.Longitude; summary.Latitude = (int)location.MapTableData.Latitude; DFPosition mapPixel = MapsFile.LongitudeLatitudeToMapPixel(summary.Longitude, summary.Latitude); DFPosition worldCoord = MapsFile.MapPixelToWorldCoord(mapPixel.X, mapPixel.Y); summary.MapPixelX = mapPixel.X; summary.MapPixelY = mapPixel.Y; summary.WorldCoordX = worldCoord.X; summary.WorldCoordZ = worldCoord.Y; summary.RegionName = location.RegionName; summary.LocationName = location.Name; summary.WorldClimate = location.Climate.WorldClimate; summary.LocationType = location.MapTableData.LocationType; summary.DungeonType = location.MapTableData.DungeonType; summary.HasDungeon = location.HasDungeon; summary.Climate = ClimateSwaps.FromAPIClimateBase(location.Climate.ClimateType); summary.Nature = ClimateSwaps.FromAPITextureSet(location.Climate.NatureSet); summary.SkyBase = location.Climate.SkyBase; summary.BlockWidth = location.Exterior.ExteriorData.Width; summary.BlockHeight = location.Exterior.ExteriorData.Height; // Assign starting climate CurrentSeason = ClimateSeason.Summer; CurrentClimate = summary.Climate; CurrentNatureSet = summary.Nature; // Perform layout if (performLayout) { LayoutLocation(ref location); ApplyClimateSettings(); } // Seal location isSet = true; }
/// <summary> /// Add nature billboards. /// </summary> public static void AddNatureFlats( ref DFBlock blockData, Transform flatsParent, DaggerfallBillboardBatch billboardBatch = null, ClimateNatureSets climateNature = ClimateNatureSets.TemperateWoodland, ClimateSeason climateSeason = ClimateSeason.Summer) { DaggerfallUnity dfUnity = DaggerfallUnity.Instance; if (!dfUnity.IsReady) return; for (int y = 0; y < 16; y++) { for (int x = 0; x < 16; x++) { // Get scenery item - ignore indices -1 (empty) and 0 (marker/waypoint of some kind) DFBlock.RmbGroundScenery scenery = blockData.RmbBlock.FldHeader.GroundData.GroundScenery[x, 15 - y]; if (scenery.TextureRecord < 1) continue; // Calculate position Vector3 billboardPosition = new Vector3( x * BlocksFile.TileDimension, natureFlatsOffsetY, y * BlocksFile.TileDimension + BlocksFile.TileDimension) * MeshReader.GlobalScale; // Add billboard to batch or standalone if (billboardBatch != null) { billboardBatch.AddItem(scenery.TextureRecord, billboardPosition); } else { int natureArchive = ClimateSwaps.GetNatureArchive(climateNature, climateSeason); GameObject go = GameObjectHelper.CreateDaggerfallBillboardGameObject(natureArchive, scenery.TextureRecord, flatsParent); go.transform.position = billboardPosition; } } } }
/// <summary> /// Layout a complete RMB block game object. /// Can be used standalone or as part of a city build. /// </summary> public static GameObject CreateRMBBlockGameObject( string blockName, bool addGroundPlane = true, DaggerfallRMBBlock cloneFrom = null, DaggerfallBillboardBatch natureBillboardBatch = null, DaggerfallBillboardBatch lightsBillboardBatch = null, DaggerfallBillboardBatch animalsBillboardBatch = null, TextureAtlasBuilder miscBillboardAtlas = null, DaggerfallBillboardBatch miscBillboardBatch = null, ClimateNatureSets climateNature = ClimateNatureSets.TemperateWoodland, ClimateSeason climateSeason = ClimateSeason.Summer) { // Get DaggerfallUnity DaggerfallUnity dfUnity = DaggerfallUnity.Instance; if (!dfUnity.IsReady) { return(null); } // Create base object DFBlock blockData; GameObject go = RMBLayout.CreateBaseGameObject(blockName, out blockData, cloneFrom); // Create flats node GameObject flatsNode = new GameObject("Flats"); flatsNode.transform.parent = go.transform; // Create lights node GameObject lightsNode = new GameObject("Lights"); lightsNode.transform.parent = go.transform; // If billboard batching is enabled but user has not specified // a batch, then make our own auto batch for this block bool autoLightsBatch = false; bool autoNatureBatch = false; bool autoAnimalsBatch = false; if (dfUnity.Option_BatchBillboards) { if (natureBillboardBatch == null) { autoNatureBatch = true; int natureArchive = ClimateSwaps.GetNatureArchive(climateNature, climateSeason); natureBillboardBatch = GameObjectHelper.CreateBillboardBatchGameObject(natureArchive, flatsNode.transform); } if (lightsBillboardBatch == null) { autoLightsBatch = true; lightsBillboardBatch = GameObjectHelper.CreateBillboardBatchGameObject(TextureReader.LightsTextureArchive, flatsNode.transform); } if (animalsBillboardBatch == null) { autoAnimalsBatch = true; animalsBillboardBatch = GameObjectHelper.CreateBillboardBatchGameObject(TextureReader.AnimalsTextureArchive, flatsNode.transform); } } // Layout light billboards and gameobjects RMBLayout.AddLights(ref blockData, flatsNode.transform, lightsNode.transform, lightsBillboardBatch); // Layout nature billboards RMBLayout.AddNatureFlats(ref blockData, flatsNode.transform, natureBillboardBatch, climateNature, climateSeason); // Layout all other flats RMBLayout.AddMiscBlockFlats(ref blockData, flatsNode.transform, animalsBillboardBatch, miscBillboardAtlas, miscBillboardBatch); // Add ground plane if (addGroundPlane) { RMBLayout.AddGroundPlane(ref blockData, go.transform); } // Apply auto batches if (autoNatureBatch) { natureBillboardBatch.Apply(); } if (autoLightsBatch) { lightsBillboardBatch.Apply(); } if (autoAnimalsBatch) { animalsBillboardBatch.Apply(); } return(go); }
/// <summary> /// Add subrecord (building) exterior block flats. /// </summary> public static void AddExteriorBlockFlats( ref DFBlock blockData, Transform flatsParent, Transform lightsParent, int mapId, int locationIndex, ClimateNatureSets climateNature = ClimateNatureSets.TemperateWoodland, ClimateSeason climateSeason = ClimateSeason.Summer) { DaggerfallUnity dfUnity = DaggerfallUnity.Instance; if (!dfUnity.IsReady) { return; } // Get Nature Archive int natureArchive = ClimateSwaps.GetNatureArchive(climateNature, climateSeason); foreach (DFBlock.RmbSubRecord subRecord in blockData.RmbBlock.SubRecords) { Vector3 subRecordPosition = new Vector3(subRecord.XPos, 0, -subRecord.ZPos) * MeshReader.GlobalScale; foreach (DFBlock.RmbBlockFlatObjectRecord obj in subRecord.Exterior.BlockFlatObjectRecords) { // Don't add building exterior editor flats since they can't be used by any DFU systems int archive = obj.TextureArchive; if (archive == TextureReader.EditorFlatsTextureArchive) { continue; } // Calculate position Vector3 billboardPosition = new Vector3( obj.XPos, -obj.YPos + blockFlatsOffsetY, obj.ZPos + BlocksFile.RMBDimension) * MeshReader.GlobalScale; billboardPosition += subRecordPosition; // Add natures using correct climate set archive if (archive >= (int)DFLocation.ClimateTextureSet.Nature_RainForest && archive <= (int)DFLocation.ClimateTextureSet.Nature_Mountains_Snow) { archive = natureArchive; billboardPosition.z = natureFlatsOffsetY; } GameObject go = MeshReplacement.ImportCustomFlatGameobject(archive, obj.TextureRecord, billboardPosition, flatsParent); bool isImported = go != null; if (!isImported) { // Add standalone billboard gameobject go = GameObjectHelper.CreateDaggerfallBillboardGameObject(archive, obj.TextureRecord, flatsParent); go.transform.position = billboardPosition; AlignBillboardToBase(go); } // Add animal sound if (archive == TextureReader.AnimalsTextureArchive) { AddAnimalAudioSource(go, obj.TextureRecord); } // If flat record has a non-zero faction id, then it's an exterior NPC if (obj.FactionID != 0) { // Add RMB data to billboard Billboard dfBillboard = go.GetComponent <Billboard>(); if (dfBillboard != null) { dfBillboard.SetRMBPeopleData(obj.FactionID, obj.Flags, obj.Position); } // Add StaticNPC behaviour StaticNPC npc = go.AddComponent <StaticNPC>(); npc.SetLayoutData(obj, mapId, locationIndex); } // If this is a light flat, import light prefab if (archive == TextureReader.LightsTextureArchive && !isImported) { if (dfUnity.Option_CityLightPrefab == null) { return; } Vector2 size = dfUnity.MeshReader.GetScaledBillboardSize(210, obj.TextureRecord); Vector3 position = new Vector3( obj.XPos, -obj.YPos + size.y, obj.ZPos + BlocksFile.RMBDimension) * MeshReader.GlobalScale; position += subRecordPosition; GameObjectHelper.InstantiatePrefab(dfUnity.Option_CityLightPrefab.gameObject, string.Empty, lightsParent, position); } } } }