Exemplo n.º 1
0
        private static void AddEnemy(
            DFBlock.RdbObject obj,
            MobileTypes type,
            Transform parent = null,
            DFRegion.DungeonTypes dungeonType = DFRegion.DungeonTypes.HumanStronghold)
        {
            // Get default reaction
            MobileReactions reaction = MobileReactions.Hostile;

            if (obj.Resources.FlatResource.FlatData.Reaction == (int)DFBlock.EnemyReactionTypes.Passive)
            {
                reaction = MobileReactions.Passive;
            }

            // Just setup demo enemies at this time
            string         name       = string.Format("DaggerfallEnemy [{0}]", type.ToString());
            Vector3        position   = new Vector3(obj.XPos, -obj.YPos, obj.ZPos) * MeshReader.GlobalScale;
            GameObject     go         = GameObjectHelper.InstantiatePrefab(DaggerfallUnity.Instance.Option_EnemyPrefab.gameObject, name, parent, position);
            SetupDemoEnemy setupEnemy = go.GetComponent <SetupDemoEnemy>();

            if (setupEnemy != null)
            {
                // Configure enemy
                setupEnemy.ApplyEnemySettings(type, reaction);

                // Align non-flying units with ground
                DaggerfallMobileUnit mobileUnit = setupEnemy.GetMobileBillboardChild();
                if (mobileUnit.Summary.Enemy.Behaviour != MobileBehaviour.Flying)
                {
                    GameObjectHelper.AlignControllerToGround(go.GetComponent <CharacterController>());
                }
            }
        }
Exemplo n.º 2
0
        public void SetupDungeon
        (
            Vector3 rootPos,
            Quaternion rootRot,
            string name        = "",
            int[] textureTable = null,
            DFRegion.DungeonTypes dungeonType = DFRegion.DungeonTypes.HumanStronghold,
            int creationSeed = 0
        )
        {
            if (textureTable == null)
            {
                this.textureTable = defaultTextureTable;
            }
            else
            {
                this.textureTable = textureTable;
            }

            this.rootPosition = rootPos;
            this.rootRotation = rootRot;
            this.creationSeed = creationSeed;
            this.name         = name;
            this.dungeonType  = dungeonType;

            this.blocks = new List <BlockRecord>();
        }
Exemplo n.º 3
0
        private static void AddRandomRDBEnemy(
            DFBlock.RdbObject obj,
            DFRegion.DungeonTypes dungeonType,
            float monsterPower,
            int monsterVariance,
            Transform parent,
            ref DFBlock blockData,
            bool serialize)
        {
            // Must have a dungeon type
            if (dungeonType == DFRegion.DungeonTypes.NoDungeon)
            {
                return;
            }

            // Get dungeon type index
            int dungeonIndex = (int)dungeonType >> 8;

            if (dungeonIndex < RandomEncounters.EncounterTables.Length)
            {
                // Get encounter table
                RandomEncounterTable table = RandomEncounters.EncounterTables[dungeonIndex];

                // Get base monster index into table
                int baseMonsterIndex = (int)((float)table.Enemies.Length * monsterPower);

                // Set min index
                int minMonsterIndex = baseMonsterIndex - monsterVariance;
                if (minMonsterIndex < 0)
                {
                    minMonsterIndex = 0;
                }

                // Set max index
                int maxMonsterIndex = baseMonsterIndex + monsterVariance;
                if (maxMonsterIndex >= table.Enemies.Length)
                {
                    maxMonsterIndex = table.Enemies.Length;
                }

                // Get random monster from table
                MobileTypes type = table.Enemies[UnityEngine.Random.Range(minMonsterIndex, maxMonsterIndex)];

                // Create unique LoadID for save sytem
                long loadID = 0;
                if (serialize)
                {
                    loadID = (blockData.Index << 24) + obj.This;
                }

                // Add enemy
                AddEnemy(obj, type, parent, loadID);
            }
            else
            {
                DaggerfallUnity.LogMessage(string.Format("RDBLayout: Dungeon type {0} is out of range or unknown.", dungeonType), true);
            }
        }
Exemplo n.º 4
0
        /// <summary>
        /// Layout a complete RDB block game object.
        /// </summary>
        /// <param name="blockName">Name of block to create.</param>
        /// <param name="textureTable">Optional texture table for dungeon.</param>
        /// <param name="allowExitDoors">Add exit doors to block (for start blocks).</param>
        /// <param name="dungeonType">Dungeon type for random encounters.</param>
        /// <param name="seed">Seed for random encounters.</param>
        /// <param name="cloneFrom">Clone and build on a prefab object template.</param>
        public static GameObject CreateRDBBlockGameObject(
            string blockName,
            int[] textureTable  = null,
            bool allowExitDoors = true,
            DFRegion.DungeonTypes dungeonType = DFRegion.DungeonTypes.HumanStronghold,
            float monsterPower           = 0.5f,
            int monsterVariance          = 4,
            int seed                     = 0,
            DaggerfallRDBBlock cloneFrom = null)
        {
            // Get DaggerfallUnity
            DaggerfallUnity dfUnity = DaggerfallUnity.Instance;

            if (!dfUnity.IsReady)
            {
                return(null);
            }

            Dictionary <int, RDBLayout.ActionLink> actionLinkDict = new Dictionary <int, RDBLayout.ActionLink>();

            // Create base object
            DFBlock    blockData;
            GameObject go = RDBLayout.CreateBaseGameObject(blockName, actionLinkDict, out blockData, textureTable, allowExitDoors, cloneFrom);

            // Add action doors
            RDBLayout.AddActionDoors(go, actionLinkDict, ref blockData, textureTable);

            // Add lights
            RDBLayout.AddLights(go, ref blockData);

            // Add flats
            DFBlock.RdbObject[] editorObjects;
            GameObject[]        startMarkers;
            GameObject[]        enterMarkers;
            RDBLayout.AddFlats(go, actionLinkDict, ref blockData, out editorObjects, out startMarkers, out enterMarkers);

            // Set start and enter markers
            DaggerfallRDBBlock dfBlock = go.GetComponent <DaggerfallRDBBlock>();

            if (dfBlock != null)
            {
                dfBlock.SetMarkers(startMarkers, enterMarkers);
            }

            // Add treasure
            RDBLayout.AddTreasure(go, editorObjects, ref blockData);

            // Add enemies
            RDBLayout.AddFixedEnemies(go, editorObjects, ref blockData);
            RDBLayout.AddRandomEnemies(go, editorObjects, dungeonType, monsterPower, ref blockData, monsterVariance, seed);

            // Link action nodes
            RDBLayout.LinkActionNodes(actionLinkDict);

            return(go);
        }
Exemplo n.º 5
0
        /// <summary>
        /// Add random enemies from encounter tables based on dungeon type, monster power, and seed.
        /// </summary>
        /// <param name="go">GameObject to add monsters to.</param>
        /// <param name="editorObjects">Editor objects containing flats.</param>
        /// <param name="dungeonType">Dungeon type selects the encounter table.</param>
        /// <param name="monsterPower">Value between 0-1 for lowest monster power to highest.</param>
        /// <param name="monsterVariance">Adjust final index +/- this value in encounter table.</param>
        /// <param name="seed">Random seed for encounters.</param>
        /// <param name="serialize">Allow for serialization when available.</param>
        public static void AddRandomEnemies(
            GameObject go,
            DFBlock.RdbObject[] editorObjects,
            DFRegion.DungeonTypes dungeonType,
            float monsterPower,
            ref DFBlock blockData,
            int monsterVariance = 4,
            int seed            = 0,
            bool serialize      = true)
        {
            const int randomMonsterFlatIndex = 15;

            DaggerfallUnity dfUnity = DaggerfallUnity.Instance;

            if (!dfUnity.IsReady)
            {
                return;
            }

            // Must have import enabled and prefab set
            if (!dfUnity.Option_ImportEnemyPrefabs || dfUnity.Option_EnemyPrefab == null)
            {
                return;
            }

            // Editor objects array must be populated
            if (editorObjects == null || editorObjects.Length == 0)
            {
                return;
            }

            // Add parent node
            GameObject randomEnemiesNode = new GameObject("Random Enemies");

            randomEnemiesNode.transform.parent = go.transform;

            // Seed random generator
            UnityEngine.Random.seed = seed;

            // Iterate editor flats for enemies
            for (int i = 0; i < editorObjects.Length; i++)
            {
                // Add random enemy objects
                if (editorObjects[i].Resources.FlatResource.TextureRecord == randomMonsterFlatIndex)
                {
                    AddRandomRDBEnemy(editorObjects[i], dungeonType, monsterPower, monsterVariance, randomEnemiesNode.transform, ref blockData, serialize);
                }
            }
        }
 public void SetupDungeonBlock
 (
     int index,
     bool isStartBlock,
     int[] textureTable,
     DFRegion.DungeonTypes dungeonType = DFRegion.DungeonTypes.HumanStronghold,
     int seed = 0,
     DaggerfallRDBBlock cloneFrom = null
 )
 {
     this.blockIndex   = index;
     this.isStartBlock = isStartBlock;
     this.textureTable = textureTable;
     this.dungeonType  = dungeonType;
     this.cloneFrom    = cloneFrom;
     CreateDungeonBlock();
 }
        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.º 8
0
        /// <summary>
        /// Creates a new RDB GameObject and performs block layout.
        /// Can pass information about dungeon for texture swaps and random enemies.
        /// </summary>
        /// <param name="dfUnity">DaggerfallUnity singleton. Required for content readers and settings.</param>
        /// <param name="blockName">Name of RDB block to build.</param>
        /// <param name="isStartingBlock">True if this is the starting block. Controls exit doors.</param>
        /// <param name="textureTable">Dungeon texture table.</param>
        /// <param name="dungeonType">Type of dungeon for random encounter tables.</param>
        /// <param name="seed">Seed for random encounters.</param>
        /// <returns>GameObject.</returns>
        public static GameObject CreateGameObject(
            string blockName,
            bool isStartingBlock,
            int[] textureTable = null,
            DFRegion.DungeonTypes dungeonType = DFRegion.DungeonTypes.HumanStronghold,
            int seed = 0)
        {
            // Validate
            if (string.IsNullOrEmpty(blockName))
            {
                return(null);
            }
            if (!blockName.ToUpper().EndsWith(".RDB"))
            {
                return(null);
            }
            DaggerfallUnity dfUnity = DaggerfallUnity.Instance;

            if (!dfUnity.IsReady)
            {
                return(null);
            }

            // Create gameobject
            GameObject         go      = new GameObject(string.Format("DaggerfallBlock [Name={0}]", blockName));
            DaggerfallRDBBlock dfBlock = go.AddComponent <DaggerfallRDBBlock>();

            // Start new layout
            RDBLayout layout = new RDBLayout(blockName);

            layout.isStartingBlock  = isStartingBlock;
            layout.textureTable     = textureTable;
            layout.dungeonType      = dungeonType;
            layout.staticModelsNode = new GameObject("Static Models");
            layout.actionModelsNode = new GameObject("Action Models");
            layout.doorsNode        = new GameObject("Doors");
            layout.flatsNode        = new GameObject("Flats");
            layout.lightsNode       = new GameObject("Lights");
            layout.enemiesNode      = new GameObject("Enemies");

            // Parent child game objects
            layout.staticModelsNode.transform.parent = go.transform;
            layout.actionModelsNode.transform.parent = go.transform;
            layout.doorsNode.transform.parent        = go.transform;
            layout.flatsNode.transform.parent        = go.transform;
            layout.lightsNode.transform.parent       = go.transform;
            layout.enemiesNode.transform.parent      = go.transform;

            // List to receive any exit doors found
            List <StaticDoor> allDoors = new List <StaticDoor>();

            // Seed random generator
            UnityEngine.Random.seed = seed;

            // Iterate object groups
            layout.groupIndex = 0;
            DFBlock blockData = dfUnity.ContentReader.BlockFileReader.GetBlock(blockName);

            foreach (DFBlock.RdbObjectRoot group in blockData.RdbBlock.ObjectRootList)
            {
                // Skip empty object groups
                if (null == group.RdbObjects)
                {
                    layout.groupIndex++;
                    continue;
                }

                // Iterate objects in this group
                List <StaticDoor> modelDoors;
                foreach (DFBlock.RdbObject obj in group.RdbObjects)
                {
                    // Handle by object type
                    switch (obj.Type)
                    {
                    case DFBlock.RdbResourceTypes.Model:
                        layout.AddRDBModel(obj, out modelDoors, layout.staticModelsNode.transform);
                        if (modelDoors.Count > 0)
                        {
                            allDoors.AddRange(modelDoors);
                        }
                        break;

                    case DFBlock.RdbResourceTypes.Flat:
                        layout.AddRDBFlat(obj, layout.flatsNode.transform);
                        break;

                    case DFBlock.RdbResourceTypes.Light:
                        layout.AddRDBLight(obj, layout.lightsNode.transform);
                        break;

                    default:
                        break;
                    }
                }

                // Increment group index
                layout.groupIndex++;
            }

            // Link action nodes
            layout.LinkActionNodes();

            // Combine meshes
            if (dfUnity.Option_CombineRDB)
            {
                layout.combiner.Apply();
                GameObject cgo = GameObjectHelper.CreateCombinedMeshGameObject(layout.combiner, "CombinedMeshes", layout.staticModelsNode.transform, dfUnity.Option_SetStaticFlags);
                cgo.GetComponent <DaggerfallMesh>().SetDungeonTextures(textureTable);
            }

            // Fix enemy standing positions for this block
            // Some enemies are floating in air or sunk into ground
            // Can only adjust this after geometry instantiated
            layout.FixEnemyStanding(go);

            // Store start markers in block
            dfBlock.SetStartMarkers(layout.startMarkers.ToArray());

            // Add doors
            if (allDoors.Count > 0)
            {
                layout.AddDoors(allDoors.ToArray(), go);
            }

            return(go);
        }