/// <summary> /// /// </summary> public void CreateDungeon() { if (!DaggerfallWorkshop.DaggerfallUnity.Instance.IsReady) { Debug.LogError("Error: DFunity not ready"); return; } if (!blockSetup) { blockSetup = this.GetComponent <DungeonBlockSetup>(); } if (blocks == null) { Debug.LogError("no blocks for Dungeon Creation, stopping"); return; } else if (blocks.Count == 0) { Debug.LogError("no blocks for Dungeon Creation, stopping"); return; } this.transform.position = rootPosition; this.transform.rotation = rootRotation; for (int i = 0; i < blocks.Count; i++) { BlockRecord record = blocks[i]; blockSetup.SetupDungeonBlock(record, record.isStartBlock, textureTable, dungeonType); } }
/// <summary> /// Checks each possible position around internal blocks /// if not used, adds a border block record to list /// </summary> void SetupBorderBlocks() { Vector2[] usedPositions = GetUsedPositions(); if (usedPositions == null) { Debug.LogError("Error: GetUsedIndicies returned null"); } foreach (Vector2 shift in shifts) { foreach (Vector2 pos in usedPositions) { Vector2 tmp = pos + shift; if (!CheckCollisions(tmp)) { BlockRecord record = GetRandomBlock(DFBlock.RdbTypes.Border); record.position = tmp; record.isStartBlock = false; blocks.Add(record); //Need to add border blocks to avoid them colliding - all other blocks //have been added so this won't cause problems distanceLookup.Add(tmp, -1); } } } }
/// <summary> /// Grabs the relevant data from a DFBlock struct and creates a BlockRecord /// </summary> /// <param name="recordOut"></param> /// <param name="blockData"></param> public void CreateBlockRecordFromDFBlock(out BlockRecord recordOut, DFBlock blockData) { DFBlock.RdbTypes RdBType = DaggerfallUnity.Instance.ContentReader.BlockFileReader.GetRdbType(blockData.Name); bool hasStartMarkers = false; if (blockData.Type == DFBlock.BlockTypes.Rdb && !startMarkerFilter.Contains(blockData.Name) && !blockData.Name.StartsWith("B")) { hasStartMarkers = true; } recordOut = new BlockRecord(blockData.Name, blockData.Index, hasStartMarkers, blockData.Type, RdBType); }
public void SetupDungeonBlock ( BlockRecord record, bool isStartBlock, int[] textureTable, DFRegion.DungeonTypes dungeonType = DFRegion.DungeonTypes.HumanStronghold, int seed = 0, DaggerfallRDBBlock cloneFrom = null ) { this.blockIndex = record.index; actLink = new System.Collections.Generic.Dictionary <int, RDBLayout.ActionLink>(); this.isStartBlock = isStartBlock; this.textureTable = textureTable; this.dungeonType = dungeonType; this.cloneFrom = cloneFrom; this.position = record.position; CreateDungeonBlock(); }
public override bool Equals(object obj) { try { BlockRecord otherRecord = (BlockRecord)obj; if (otherRecord == null) { return(false); } if (otherRecord.name != this.name) { return(false); } if (otherRecord.index != this.index) { return(false); } if (otherRecord.hasStartFlags != this.hasStartFlags) { return(false); } if (otherRecord.blockType != this.blockType) { return(false); } if (otherRecord.RdBType != this.RdBType) { return(false); } return(true); } catch { return(false); } }
/// <summary> /// Gets a random block based on rdb type. Will recursively try and find unique block /// Returns null on error /// </summary> /// <param name="rdbType"></param> /// <param name="count"></param> /// <returns></returns> BlockRecord GetRandomBlock(DFBlock.RdbTypes rdbType = DFBlock.RdbTypes.Unknown, int count = 0) { try { count++; var usedIndices = GetUsedIndices(); if (rdbType == DFBlock.RdbTypes.Start) //get random start block { BlockRecord record = blockCollection.GetRandomBlock(blockCollection.GetStartBlocks(blockCollection.blockRecords)); if (usedIndices.Contains(record.index)) { if (count < 100) { return(GetRandomBlock(rdbType, count)); } else { Debug.LogWarning("Failed to find unique block"); record = new BlockRecord(record.name, record.index, record.hasStartFlags, record.blockType, record.RdBType); return(record); } } else { return(record); } } else if (rdbType == DFBlock.RdbTypes.Border) //Get a random border block { BlockRecord record = blockCollection.GetRandomBlock(blockCollection.FilterRDBBlocks(blockCollection.blockRecords, rdbType)); if (usedIndices.Contains(record.index)) { if (count < 100) { return(GetRandomBlock(rdbType, count)); } else { Debug.LogWarning("Failed to find unique block "); record = new BlockRecord(record.name, record.index, record.hasStartFlags, record.blockType, record.RdBType); return(record); } } else { return(record); } } else// Get non-border blocks { BlockRecord record = blockCollection.GetRandomBlock(blockCollection.FilterRDBBlocks(blockCollection.blockRecords, DFBlock.RdbTypes.Border, true)); if (usedIndices.Contains(record.index)) { if (count < 100) { return(GetRandomBlock(rdbType, count)); } else { Debug.LogWarning("Failed to find unique block"); record = new BlockRecord(record.name, record.index, record.hasStartFlags, record.blockType, record.RdBType); return(record); } } else { return(record); } } } catch (System.Exception ex) { Debug.LogError(ex.Message); return(null); } }
/// <summary> /// Creates dungeon using paramaters /// </summary> /// <returns></returns> public GameObject LayOutDungeon(int count = 10) { Debug.Log("****** DUNGEON COUNT: " + count.ToString()); StartUp(); if (!isReady) { Debug.LogError("Failed to setup DungeonGenerator, stopping"); return(null); } GameObject DungeonObject = new GameObject("DungeonObject"); DungeonRecord dungeonRecord = DungeonObject.AddComponent <DungeonRecord>(); dungeonRecord.MyGenerator = this; dungeonRecord.SetupDungeon(customRootPosition, customRootRotation, dungeonName, textureTable, dungeonType); //add the root position to dictionary to avoid collisions distanceLookup.Add(Vector2.zero, 0); bool PositionsAllValid = GetPositions(); if (!PositionsAllValid) //should never happen { Debug.LogError("GetPositions returned false"); if (count > 0) { Destroy(DungeonObject); seed = 0; count--; return(LayOutDungeon(count)); } return(null); } var x = distanceLookup.OrderBy(d => d.Value).ToList(); //if farthest distance exit block below min distance, try a new //layout if possible bool distanceCheck = (numOfExits > 0 && numOfInternalBlocks > numOfExits); if (distanceCheck) { if (x[(x.Count - 1) - numOfExits].Value < minExitDistanceFromRoot && count > 0) { Debug.LogError("exit < min distance from root.: "); Destroy(DungeonObject); count--; seed = 0; return(LayOutDungeon(count)); } } //Build up the blocks, starting w from the root, and the blocks closet to the root, and finishing //with the exit blocks, which will always be as far away as possible from root for (int i = 0; i < x.Count; i++) { Vector2 pos = Vector2.zero; BlockRecord record = null; if (i == 0) //get root block { record = GetRandomBlock(DFBlock.RdbTypes.Start); record.isStartBlock = true; } else if ((x.Count - i) <= numOfExits) //get additional starting blocks { record = GetRandomBlock(DFBlock.RdbTypes.Start); record.isStartBlock = true; } else //get internal blocks without exits { record = GetRandomBlock(DFBlock.RdbTypes.Unknown); record.isStartBlock = false; } if (record == null) { Debug.LogError("Failed to get block record"); Destroy(DungeonObject); if (count > 0) { count--; return(LayOutDungeon(count)); } return(null); } pos = x[i].Key; record.position = pos; blocks.Add(record); } SetupBorderBlocks(); dungeonRecord.blocks = blocks; FlagCreateNewDungeon = false; // Debug, not normally supposed to be here, but it hangs otherwise dungeonRecord.CreateDungeon(); return(DungeonObject); }
public void CreateBlockRecordFromDFBlock(out BlockRecord recordOut, int blockIndex) { DFBlock block = DaggerfallUnity.Instance.ContentReader.BlockFileReader.GetBlock(blockIndex); CreateBlockRecordFromDFBlock(out recordOut, block); }