/// <summary> /// Seek and import a GameObject from mods to replace a Daggerfall billboard. /// </summary> /// <param name="archive">Texture archive for original billboard.</param> /// <param name="record">Texture record for original billboard.</param> /// <param name="position">Position to assign to GameObject.</param> /// <param name="parent">Parent to assign to GameObject.</param> /// <param name="inDungeon">Fix position for dungeon models.</param> /// <returns>Returns the imported model or null if not found.</returns> public static GameObject ImportCustomFlatGameobject(int archive, int record, Vector3 position, Transform parent, bool inDungeon = false) { GameObject go; if (!TryImportGameObject(archive, record, true, out go)) { return(null); } go.name = GetFlatReplacementName(archive, record); go.transform.parent = parent; // Assign position AlignToBase(go.transform, position, archive, record, inDungeon); // Assign a random rotation var iObjectPositioner = go.GetComponent <IObjectPositioner>(); if (iObjectPositioner == null || iObjectPositioner.AllowFlatRotation) { Random.InitState((int)position.x); go.transform.Rotate(0, Random.Range(0f, 360f), 0); } // Add NPC trigger collider if (RDBLayout.IsNPCFlat(archive)) { Collider col = go.AddComponent <BoxCollider>(); col.isTrigger = true; } // Finalise gameobject materials FinaliseMaterials(go); return(go); }
/// <summary> /// Seek and import a GameObject from mods to replace a Daggerfall billboard. /// </summary> /// <param name="archive">Texture archive for original billboard.</param> /// <param name="record">Texture record for original billboard.</param> /// <param name="position">Position to assign to GameObject.</param> /// <param name="parent">Parent to assign to GameObject.</param> /// <param name="inDungeon">Fix position for dungeon models.</param> /// <returns>Returns the imported model or null if not found.</returns> public static GameObject ImportCustomFlatGameobject(int archive, int record, Vector3 position, Transform parent, bool inDungeon = false) { GameObject go; if (!TryImportGameObject(archive, record, true, out go)) { return(null); } go.name = string.Format("DaggerfallBillboard [Replacement] [TEXTURE.{0:000}, Index={1}]", archive, record); go.transform.parent = parent; // Assign position AlignToBase(go.transform, position, archive, record, inDungeon); // Assign a random rotation if (go.GetComponent <FaceWall>() == null) { Random.InitState((int)position.x); go.transform.Rotate(0, Random.Range(0f, 360f), 0); } // Add NPC trigger collider if (RDBLayout.IsNPCFlat(archive)) { Collider col = go.AddComponent <BoxCollider>(); col.isTrigger = true; } // Finalise gameobject materials FinaliseMaterials(go); return(go); }
private void LayoutDungeon(ref DFLocation location, bool importEnemies = true) { #if SHOW_LAYOUT_TIMES // Start timing System.Diagnostics.Stopwatch stopwatch = System.Diagnostics.Stopwatch.StartNew(); long startTime = stopwatch.ElapsedMilliseconds; #endif // Get player level - use level 1 if game not running (e.g. importing in editor mode) float playerLevel = 1; if (Application.isPlaying) { playerLevel = GameManager.Instance.PlayerEntity.Level; } // Calculate monster power - this is a clamped 0-1 value based on player's level from 1-20 float monsterPower = Mathf.Clamp01(playerLevel / 20f); // Create dungeon layout for (int i = 0; i < summary.LocationData.Dungeon.Blocks.Length; i++) { DFLocation.DungeonBlock block = summary.LocationData.Dungeon.Blocks[i]; GameObject go = GameObjectHelper.CreateRDBBlockGameObject( block.BlockName, DungeonTextureTable, block.IsStartingBlock, Summary.DungeonType, monsterPower, RandomMonsterVariance, (int)DateTime.Now.Ticks /*Summary.ID*/, // TODO: Add more options for seed dfUnity.Option_DungeonBlockPrefab, importEnemies); go.transform.parent = this.transform; go.transform.position = new Vector3(block.X * RDBLayout.RDBSide, 0, block.Z * RDBLayout.RDBSide); DaggerfallRDBBlock daggerfallBlock = go.GetComponent <DaggerfallRDBBlock>(); if (block.IsStartingBlock) { FindMarkers(daggerfallBlock, ref block, true); // Assign start marker and enter marker } else { FindMarkers(daggerfallBlock, ref block, false); // Only find water level and palaceblock info from start marker } summary.LocationData.Dungeon.Blocks[i].WaterLevel = block.WaterLevel; summary.LocationData.Dungeon.Blocks[i].CastleBlock = block.CastleBlock; // Add water blocks RDBLayout.AddWater(go, go.transform.position, block.WaterLevel); } RemoveOverlappingDoors(); #if SHOW_LAYOUT_TIMES // Show timer long totalTime = stopwatch.ElapsedMilliseconds - startTime; DaggerfallUnity.LogMessage(string.Format("Time to layout dungeon: {0}ms", totalTime), true); #endif }
/// <summary> /// Import a GameObject from mods instead of billboard. /// </summary> /// <param name="inDungeon">Fix position for dungeon models.</param> /// <returns>Returns the imported model or null.</returns> public static GameObject ImportCustomFlatGameobject(int archive, int record, Vector3 position, Transform parent, bool inDungeon = false) { // Check user settings if (!DaggerfallUnity.Settings.MeshAndTextureReplacement) { return(null); } // Get GameObject GameObject prefab; string name = archive.ToString("D3") + "_" + record.ToString(); if (!LoadGameObjectFromMods("Flats", name, out prefab)) { return(null); } // Instantiate GameObject GameObject go = GameObject.Instantiate(prefab, parent); go.name = string.Format("DaggerfallBillboard [Replacement] [TEXTURE.{0:000}, Index={1}]", archive, record); // Assign position if (inDungeon) { // Fix origin position for dungeon flats int height = ImageReader.GetImageData("TEXTURE." + archive.ToString("D3"), record, createTexture: false).height; position.y -= height / 2 * MeshReader.GlobalScale; } go.transform.localPosition = position; // Assign a random rotation if (go.GetComponent <FaceWall>() == null) { Random.InitState((int)position.x); go.transform.Rotate(0, Random.Range(0f, 360f), 0); } // Add NPC trigger collider if (RDBLayout.IsNPCFlat(archive)) { Collider col = go.AddComponent <BoxCollider>(); col.isTrigger = true; } // Finalise gameobject materials FinaliseMaterials(go); return(go); }
// Orsinium defines two blocks at [-1,-1] private void LayoutOrsinium(ref DFLocation location, bool importEnemies = true) { // Calculate monster power - this is a clamped 0-1 value based on player's level from 1-20 float monsterPower = Mathf.Clamp01(GameManager.Instance.PlayerEntity.Level / 20f); // Create dungeon layout and handle misplaced block for (int i = 0; i < summary.LocationData.Dungeon.Blocks.Length; i++) { DFLocation.DungeonBlock block = summary.LocationData.Dungeon.Blocks[i]; if (block.X == -1 && block.Z == -1 && block.BlockName == "N0000065.RDB") { continue; } GameObject go = GameObjectHelper.CreateRDBBlockGameObject( block.BlockName, DungeonTextureTable, block.IsStartingBlock, Summary.DungeonType, monsterPower, RandomMonsterVariance, (int)DateTime.Now.Ticks /*Summary.ID*/, // TODO: Add more options for seed dfUnity.Option_DungeonBlockPrefab, importEnemies); go.transform.parent = this.transform; go.transform.position = new Vector3(block.X * RDBLayout.RDBSide, 0, block.Z * RDBLayout.RDBSide); DaggerfallRDBBlock daggerfallBlock = go.GetComponent <DaggerfallRDBBlock>(); if (block.IsStartingBlock) { FindMarkers(daggerfallBlock, ref block, true); // Assign start marker and enter marker } else { FindMarkers(daggerfallBlock, ref block, false); // Only find water level and castle block info from start marker } summary.LocationData.Dungeon.Blocks[i].WaterLevel = block.WaterLevel; summary.LocationData.Dungeon.Blocks[i].CastleBlock = block.CastleBlock; // Add water blocks RDBLayout.AddWater(go, go.transform.position, block.WaterLevel); } RemoveOverlappingDoors(); }
// Orsinium defines two blocks at [-1,-1] private void LayoutOrsinium(ref DFLocation location) { // Create dungeon layout and handle misplaced block foreach (var block in location.Dungeon.Blocks) { if (block.X == -1 && block.Z == -1 && block.BlockName == "N0000065.RDB") { continue; } GameObject go = RDBLayout.CreateGameObject(block.BlockName, block.IsStartingBlock, DungeonTextureTable, Summary.DungeonType, Summary.ID); go.transform.parent = this.transform; go.transform.position = new Vector3(block.X * RDBLayout.RDBSide, 0, block.Z * RDBLayout.RDBSide); DaggerfallRDBBlock daggerfallBlock = go.GetComponent <DaggerfallRDBBlock>(); if (block.IsStartingBlock) { FindStartMarker(daggerfallBlock); } } }
/// <summary> /// Seek and import a GameObject from mods to replace a Daggerfall billboard. /// </summary> /// <param name="archive">Texture archive for original billboard.</param> /// <param name="record">Texture record for original billboard.</param> /// <param name="position">Position to assign to GameObject.</param> /// <param name="parent">Parent to assign to GameObject.</param> /// <param name="inDungeon">Fix position for dungeon models.</param> /// <returns>Returns the imported model or null if not found.</returns> public static GameObject ImportCustomFlatGameobject(int archive, int record, Vector3 position, Transform parent, bool inDungeon = false) { GameObject go; if (!TryImportGameObject(archive, record, true, out go)) { return(null); } go.name = string.Format("DaggerfallBillboard [Replacement] [TEXTURE.{0:000}, Index={1}]", archive, record); go.transform.parent = parent; // Assign position if (inDungeon) { // Fix origin position for dungeon flats int height = ImageReader.GetImageData(TextureFile.IndexToFileName(archive), record, createTexture: false).height; position.y -= height / 2 * MeshReader.GlobalScale; } go.transform.localPosition = position; // Assign a random rotation if (go.GetComponent <FaceWall>() == null) { Random.InitState((int)position.x); go.transform.Rotate(0, Random.Range(0f, 360f), 0); } // Add NPC trigger collider if (RDBLayout.IsNPCFlat(archive)) { Collider col = go.AddComponent <BoxCollider>(); col.isTrigger = true; } // Finalise gameobject materials FinaliseMaterials(go); return(go); }
/// <summary> /// Assign parent, position, rotation and texture filtermode. /// </summary> static private void InstantiateCustomFlat(GameObject go, ref Vector3 position, Transform parent, int archive, int record, bool inDungeon) { // Fix origin position for dungeon flats if (inDungeon) { // Get height int height = ImageReader.GetImageData("TEXTURE." + archive.ToString("D3"), record, createTexture: false).height; // Correct transform position.y -= height / 2 * MeshReader.GlobalScale; } // Assign transform properties go.transform.parent = parent; go.transform.localPosition = position; // Assign a random rotation so that flats in group won't look all aligned. // We use a seed becuse we want the models to have the same // rotation every time the same location is loaded. if (go.GetComponent <FaceWall>() == null) { UnityEngine.Random.InitState((int)position.x); go.transform.Rotate(0, UnityEngine.Random.Range(0f, 360f), 0); } // Assign name go.name = string.Format("DaggerfallBillboard [Replacement] [TEXTURE.{0:000}, Index={1}]", archive, record); // Finalise gameobject material FinaliseMaterials(go); // Add NPC trigger collider if (RDBLayout.IsNPCFlat(archive)) { Collider col = go.AddComponent <BoxCollider>(); col.isTrigger = true; } }
private void LayoutDungeon(ref DFLocation location) { //// Start timing //Stopwatch stopwatch = Stopwatch.StartNew(); //long startTime = stopwatch.ElapsedMilliseconds; // Create dungeon layout foreach (var block in location.Dungeon.Blocks) { GameObject go = RDBLayout.CreateGameObject(block.BlockName, block.IsStartingBlock, DungeonTextureTable, Summary.DungeonType, Summary.ID); go.transform.parent = this.transform; go.transform.position = new Vector3(block.X * RDBLayout.RDBSide, 0, block.Z * RDBLayout.RDBSide); DaggerfallRDBBlock daggerfallBlock = go.GetComponent <DaggerfallRDBBlock>(); if (block.IsStartingBlock) { FindStartMarker(daggerfallBlock); } } //// Show timer //long totalTime = stopwatch.ElapsedMilliseconds - startTime; //DaggerfallUnity.LogMessage(string.Format("Time to layout dungeon: {0}ms", totalTime), true); }
/// <summary> /// Sets new Daggerfall material and recreates mesh. /// Will use an atlas if specified in DaggerfallUnity singleton. /// </summary> /// <param name="dfUnity">DaggerfallUnity singleton. Required for content readers and settings.</param> /// <param name="archive">Texture archive index.</param> /// <param name="record">Texture record index.</param> /// <param name="frame">Frame index.</param> /// <returns>Material.</returns> public Material SetMaterial(int archive, int record, int frame = 0) { // Get DaggerfallUnity DaggerfallUnity dfUnity = DaggerfallUnity.Instance; if (!dfUnity.IsReady) { return(null); } // Get references meshRenderer = GetComponent <MeshRenderer>(); Vector2 size; Vector2 scale; Mesh mesh = null; Material material = null; if (material = TextureReplacement.GetStaticBillboardMaterial(gameObject, archive, record, ref summary, out scale)) { mesh = dfUnity.MeshReader.GetBillboardMesh(summary.Rect, archive, record, out size); size *= scale; summary.AtlasedMaterial = false; summary.AnimatedMaterial = summary.ImportedTextures.FrameCount > 1; } else if (dfUnity.MaterialReader.AtlasTextures) { material = dfUnity.MaterialReader.GetMaterialAtlas( archive, 0, 4, 2048, out summary.AtlasRects, out summary.AtlasIndices, 4, true, 0, false, true); mesh = dfUnity.MeshReader.GetBillboardMesh( summary.AtlasRects[summary.AtlasIndices[record].startIndex], archive, record, out size); summary.AtlasedMaterial = true; if (summary.AtlasIndices[record].frameCount > 1) { summary.AnimatedMaterial = true; } else { summary.AnimatedMaterial = false; } } else { material = dfUnity.MaterialReader.GetMaterial( archive, record, frame, 0, out summary.Rect, 4, true, true); mesh = dfUnity.MeshReader.GetBillboardMesh( summary.Rect, archive, record, out size); summary.AtlasedMaterial = false; summary.AnimatedMaterial = false; } // Set summary summary.FlatType = MaterialReader.GetFlatType(archive); summary.Archive = archive; summary.Record = record; summary.Size = size; // Set editor flat types if (summary.FlatType == FlatTypes.Editor) { summary.EditorFlatType = MaterialReader.GetEditorFlatType(summary.Record); } // Set NPC flat type based on archive if (RDBLayout.IsNPCFlat(summary.Archive)) { summary.FlatType = FlatTypes.NPC; } // Assign mesh and material MeshFilter meshFilter = GetComponent <MeshFilter>(); Mesh oldMesh = meshFilter.sharedMesh; if (mesh) { meshFilter.sharedMesh = mesh; meshRenderer.sharedMaterial = material; } if (oldMesh) { // The old mesh is no longer required #if UNITY_EDITOR DestroyImmediate(oldMesh); #else Destroy(oldMesh); #endif } // General billboard shadows if enabled bool isLightArchive = (archive == TextureReader.LightsTextureArchive); meshRenderer.shadowCastingMode = (DaggerfallUnity.Settings.GeneralBillboardShadows && !isLightArchive) ? ShadowCastingMode.TwoSided : ShadowCastingMode.Off; // Add NPC trigger collider if (summary.FlatType == FlatTypes.NPC) { Collider col = gameObject.AddComponent <BoxCollider>(); col.isTrigger = true; } return(material); }
public void CreateDungeonBlock() { DungeonGenerator myGen = GetComponent <DungeonRecord>().MyGenerator; Debug.LogWarning("Creating dungeon block: " + blockIndex + " isStarting block: " + isStartBlock); DaggerfallUnity dfUnity = DaggerfallUnity.Instance; if (!dfUnity.IsReady) { Debug.LogError("CreateDungeonBlock found dfUnity not ready; stopping"); return; } // Create base object DFBlock blockData = dfUnity.ContentReader.BlockFileReader.GetBlock(blockIndex); if (blockData.Type != DFBlock.BlockTypes.Rdb) { Debug.LogError(string.Format("Invalid block index : {0} | block name: {1} | block type: {2}, returning", blockIndex, blockData.Name, blockData.Type)); return; } GameObject go = RDBLayout.CreateBaseGameObject(blockData.Name, actLink, textureTable, true, cloneFrom); // Add exit doors if (isStartBlock) { StaticDoor[] doorsOut; RDBLayout.AddActionDoors(go, actLink, ref blockData, textureTable); } // Add action doors RDBLayout.AddActionDoors(go, actLink, ref blockData, textureTable); // Add lights RDBLayout.AddLights(go, ref blockData); // Add flats DFBlock.RdbObject[] editorObjectsOut = new DFBlock.RdbObject[0]; GameObject[] startMarkersOut = null; GameObject[] enterMarkersOut = null; if (myGen.GenerateTreasure) { RDBLayout.AddFlats(go, actLink, ref blockData, out editorObjectsOut, out startMarkersOut, out enterMarkersOut, dungeonType); } // Set start markers DaggerfallRDBBlock dfBlock = (cloneFrom != null) ? cloneFrom : go.GetComponent <DaggerfallRDBBlock>(); if (dfBlock != null) { dfBlock.SetMarkers(startMarkersOut, enterMarkersOut); } // Add enemies if (myGen.GenerateEnemies) { RDBLayout.AddRandomEnemies(go, editorObjectsOut, dungeonType, 0.5f, ref blockData, startMarkersOut); } go.transform.SetParent(this.transform); go.transform.localPosition = new Vector3(position.x, 0, position.y); }