Exemplo n.º 1
0
        /// <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();
        }
Exemplo n.º 5
0
        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);
        }