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>());
                }
            }
        }
Exemple #2
0
        /// <summary>
        /// Creates enemy GameObjects based on spawn count specified in Foe resource (minimum of 1).
        /// Only use this when live enemy is to be first added to scene. Do not use when linking to site or deserializing.
        /// GameObjects created will be disabled, at origin, parentless, and have a new UID for LoadID.
        /// Caller must otherwise complete GameObject setup to suit their needs.
        /// </summary>
        /// <param name="reaction">Foe is hostile by default but can optionally set to passive.</param>
        /// <returns>GameObject[] array of 1-N foes. Array can be null or empty if create fails.</returns>
        public GameObject[] CreateFoeGameObjects(Vector3 position, int spawnOverride = -1, MobileReactions reaction = MobileReactions.Hostile)
        {
            List <GameObject> gameObjects = new List <GameObject>();

            // Get spawn count allowing for caller to override
            int totalSpawns = (spawnOverride >= 1) ? spawnOverride : spawnCount;

            // Generate GameObjects
            for (int i = 0; i < totalSpawns; i++)
            {
                // Generate enemy
                string         name       = string.Format("DaggerfallEnemy [{0}]", foeType.ToString());
                GameObject     go         = GameObjectHelper.InstantiatePrefab(DaggerfallUnity.Instance.Option_EnemyPrefab.gameObject, name, null, position);
                SetupDemoEnemy setupEnemy = go.GetComponent <SetupDemoEnemy>();
                if (setupEnemy != null)
                {
                    // Assign gender randomly
                    MobileGender gender;
                    if (UnityEngine.Random.Range(0f, 1f) < 0.5f)
                    {
                        gender = MobileGender.Male;
                    }
                    else
                    {
                        gender = MobileGender.Female;
                    }

                    // Configure enemy
                    setupEnemy.ApplyEnemySettings(foeType, reaction, gender);

                    // Align non-flying units with ground
                    DaggerfallMobileUnit mobileUnit = setupEnemy.GetMobileBillboardChild();
                    if (mobileUnit.Summary.Enemy.Behaviour != MobileBehaviour.Flying)
                    {
                        GameObjectHelper.AlignControllerToGround(go.GetComponent <CharacterController>());
                    }

                    // Add QuestResourceBehaviour to GameObject
                    QuestResourceBehaviour questResourceBehaviour = go.AddComponent <QuestResourceBehaviour>();
                    questResourceBehaviour.AssignResource(this);
                }

                // Assign load id
                DaggerfallEnemy enemy = go.GetComponent <DaggerfallEnemy>();
                if (enemy)
                {
                    enemy.LoadID     = DaggerfallUnity.NextUID;
                    enemy.QuestSpawn = true;
                }

                // Disable GameObject, caller must set active when ready
                go.SetActive(false);

                // Add to list
                gameObjects.Add(go);
            }

            return(gameObjects.ToArray());
        }
        public void RestoreSaveData(object dataIn)
        {
            if (!enemy)
            {
                return;
            }

            EnemyData_v1 data = (EnemyData_v1)dataIn;

            if (data.loadID != LoadID)
            {
                return;
            }

            DaggerfallEntityBehaviour entityBehaviour = enemy.GetComponent <DaggerfallEntityBehaviour>();
            EnemySenses senses = enemy.GetComponent <EnemySenses>();
            EnemyMotor  motor  = enemy.GetComponent <EnemyMotor>();
            EnemyEntity entity = entityBehaviour.Entity as EnemyEntity;

            // Quiesce entity during state restore
            entity.Quiesce = true;

            // Restore enemy career or class if different
            if (entity.EntityType != data.entityType || entity.CareerIndex != data.careerIndex)
            {
                SetupDemoEnemy setupEnemy = enemy.GetComponent <SetupDemoEnemy>();
                setupEnemy.ApplyEnemySettings(data.entityType, data.careerIndex, data.isHostile);
                setupEnemy.AlignToGround();
            }

            // Restore enemy position
            enemy.transform.position    = data.currentPosition;
            enemy.transform.rotation    = data.currentRotation;
            entity.MaxHealth            = data.startingHealth;
            entity.CurrentHealth        = data.currentHealth;
            entity.CurrentFatigue       = data.currentFatigue;
            entity.CurrentMagicka       = data.currentMagicka;
            motor.IsHostile             = data.isHostile;
            senses.HasEncounteredPlayer = true;

            // Disable dead enemies
            if (data.isDead)
            {
                entityBehaviour.gameObject.SetActive(false);
            }

            // Resume entity
            entity.Quiesce = false;
        }
        /// <summary>
        /// Create an enemy in the world and perform common setup tasks.
        /// </summary>
        public static GameObject CreateEnemy(string name, MobileTypes mobileType, Vector3 localPosition, Transform parent = null, MobileReactions mobileReaction = MobileReactions.Hostile)
        {
            // Create target GameObject
            string         displayName = string.Format("{0} [{1}]", name, mobileType.ToString());
            GameObject     go          = InstantiatePrefab(DaggerfallUnity.Instance.Option_EnemyPrefab.gameObject, displayName, parent, Vector3.zero);
            SetupDemoEnemy setupEnemy  = go.GetComponent <SetupDemoEnemy>();

            // Set position
            go.transform.localPosition = localPosition;

            // Assign humanoid gender randomly
            // This does not affect monsters like rats, bats, etc
            MobileGender gender;

            if (UnityEngine.Random.Range(0f, 1f) < 0.5f)
            {
                gender = MobileGender.Male;
            }
            else
            {
                gender = MobileGender.Female;
            }

            // Configure enemy
            setupEnemy.ApplyEnemySettings(mobileType, mobileReaction, gender);

            // Align non-flying units with ground
            DaggerfallMobileUnit mobileUnit = setupEnemy.GetMobileBillboardChild();

            if (mobileUnit.Summary.Enemy.Behaviour != MobileBehaviour.Flying)
            {
                AlignControllerToGround(go.GetComponent <CharacterController>());
            }

            return(go);
        }
        public void RestoreSaveData(object dataIn)
        {
            if (!enemy)
            {
                return;
            }

            EnemyData_v1 data = (EnemyData_v1)dataIn;

            if (data.loadID != LoadID)
            {
                return;
            }

            DaggerfallEntityBehaviour entityBehaviour = enemy.GetComponent <DaggerfallEntityBehaviour>();
            EnemySenses senses = enemy.GetComponent <EnemySenses>();
            EnemyMotor  motor  = enemy.GetComponent <EnemyMotor>();
            EnemyEntity entity = entityBehaviour.Entity as EnemyEntity;

            // Restore enemy career or class if different
            if (entity == null || entity.EntityType != data.entityType || entity.CareerIndex != data.careerIndex)
            {
                SetupDemoEnemy setupEnemy = enemy.GetComponent <SetupDemoEnemy>();
                setupEnemy.ApplyEnemySettings(data.entityType, data.careerIndex, data.mobileGender, data.isHostile, alliedToPlayer: data.alliedToPlayer);
                setupEnemy.AlignToGround();

                if (entity == null)
                {
                    entity = entityBehaviour.Entity as EnemyEntity;
                }
            }

            // Quiesce entity during state restore
            entity.Quiesce = true;

            // Restore enemy data
            entityBehaviour.gameObject.name = data.gameObjectName;
            enemy.transform.rotation        = data.currentRotation;
            entity.QuestFoeSpellQueueIndex  = data.questFoeSpellQueueIndex;
            entity.QuestFoeItemQueueIndex   = data.questFoeItemQueueIndex;
            entity.WabbajackActive          = data.wabbajackActive;
            entity.Items.DeserializeItems(data.items);
            entity.ItemEquipTable.DeserializeEquipTable(data.equipTable, entity.Items);
            entity.MaxHealth = data.startingHealth;
            entity.SetHealth(data.currentHealth, true);
            entity.SetFatigue(data.currentFatigue, true);
            entity.SetMagicka(data.currentMagicka, true);
            int team = data.team;

            if (team > 0)   // Added 1 to made backwards compatible. 0 = no team saved
            {
                entity.Team = (MobileTeams)(team - 1);
            }
            motor.IsHostile             = data.isHostile;
            senses.HasEncounteredPlayer = data.hasEncounteredPlayer;

            // Restore enemy position and migrate to floating y support for exteriors
            // Interiors seem to be working fine at this stage with any additional support
            // Dungeons are not involved with floating y and don't need any changes
            WorldContext enemyContext = GetEnemyWorldContext(enemy);

            if (enemyContext == WorldContext.Exterior)
            {
                RestoreExteriorPositionHandler(enemy, data, enemyContext);
            }
            else
            {
                // Everything else
                enemy.transform.position = data.currentPosition;
            }

            // Disable dead enemies
            if (data.isDead)
            {
                entityBehaviour.gameObject.SetActive(false);
            }

            // Restore quest resource link
            enemy.QuestSpawn = data.questSpawn;
            if (enemy.QuestSpawn)
            {
                // Add QuestResourceBehaviour to GameObject
                QuestResourceBehaviour questResourceBehaviour = entityBehaviour.gameObject.AddComponent <QuestResourceBehaviour>();
                questResourceBehaviour.RestoreSaveData(data.questResource);

                // Destroy QuestResourceBehaviour if no actual quest properties are restored from save
                if (questResourceBehaviour.QuestUID == 0 || questResourceBehaviour.TargetSymbol == null)
                {
                    enemy.QuestSpawn = false;
                    Destroy(questResourceBehaviour);
                }
            }

            // Restore instanced effect bundles
            GetComponent <EntityEffectManager>().RestoreInstancedBundleSaveData(data.instancedEffectBundles);

            // Resume entity
            entity.Quiesce = false;
        }
Exemple #6
0
        public void RestoreSaveData(object dataIn)
        {
            if (!enemy)
            {
                return;
            }

            EnemyData_v1 data = (EnemyData_v1)dataIn;

            if (data.loadID != LoadID)
            {
                return;
            }

            DaggerfallEntityBehaviour entityBehaviour = enemy.GetComponent <DaggerfallEntityBehaviour>();
            EnemySenses senses = enemy.GetComponent <EnemySenses>();
            EnemyMotor  motor  = enemy.GetComponent <EnemyMotor>();
            EnemyEntity entity = entityBehaviour.Entity as EnemyEntity;

            // Restore enemy career or class if different
            if (entity == null || entity.EntityType != data.entityType || entity.CareerIndex != data.careerIndex)
            {
                SetupDemoEnemy setupEnemy = enemy.GetComponent <SetupDemoEnemy>();
                setupEnemy.ApplyEnemySettings(data.entityType, data.careerIndex, data.mobileGender, data.isHostile);
                setupEnemy.AlignToGround();

                if (entity == null)
                {
                    entity = entityBehaviour.Entity as EnemyEntity;
                }
            }

            // Quiesce entity during state restore
            entity.Quiesce = true;

            // Restore enemy data
            entityBehaviour.gameObject.name = data.gameObjectName;
            enemy.transform.position        = data.currentPosition;
            enemy.transform.rotation        = data.currentRotation;
            entity.Items.DeserializeItems(data.items);
            entity.ItemEquipTable.DeserializeEquipTable(data.equipTable, entity.Items);
            entity.MaxHealth            = data.startingHealth;
            entity.CurrentHealth        = data.currentHealth;
            entity.CurrentFatigue       = data.currentFatigue;
            entity.CurrentMagicka       = data.currentMagicka;
            motor.IsHostile             = data.isHostile;
            senses.HasEncounteredPlayer = data.hasEncounteredPlayer;

            // Disable dead enemies
            if (data.isDead)
            {
                entityBehaviour.gameObject.SetActive(false);
            }

            // Restore quest resource link
            enemy.QuestSpawn = data.questSpawn;
            if (enemy.QuestSpawn)
            {
                // Add QuestResourceBehaviour to GameObject
                QuestResourceBehaviour questResourceBehaviour = entityBehaviour.gameObject.AddComponent <QuestResourceBehaviour>();
                questResourceBehaviour.RestoreSaveData(data.questResource);
            }

            // Resume entity
            entity.Quiesce = false;
        }
        public void RestoreSaveData(object dataIn)
        {
            if (!enemy)
            {
                return;
            }

            EnemyData_v1 data = (EnemyData_v1)dataIn;

            if (data.loadID != LoadID)
            {
                return;
            }

            DaggerfallEntityBehaviour entityBehaviour = enemy.GetComponent <DaggerfallEntityBehaviour>();
            EnemySenses senses = enemy.GetComponent <EnemySenses>();
            EnemyMotor  motor  = enemy.GetComponent <EnemyMotor>();
            EnemyEntity entity = entityBehaviour.Entity as EnemyEntity;

            // Restore enemy career or class if different
            if (entity == null || entity.EntityType != data.entityType || entity.CareerIndex != data.careerIndex)
            {
                SetupDemoEnemy setupEnemy = enemy.GetComponent <SetupDemoEnemy>();
                setupEnemy.ApplyEnemySettings(data.entityType, data.careerIndex, data.mobileGender, data.isHostile);
                setupEnemy.AlignToGround();

                if (entity == null)
                {
                    entity = entityBehaviour.Entity as EnemyEntity;
                }
            }

            // Quiesce entity during state restore
            entity.Quiesce = true;

            // Restore enemy data
            entityBehaviour.gameObject.name = data.gameObjectName;
            enemy.transform.rotation        = data.currentRotation;
            entity.Items.DeserializeItems(data.items);
            entity.ItemEquipTable.DeserializeEquipTable(data.equipTable, entity.Items);
            entity.MaxHealth            = data.startingHealth;
            entity.CurrentHealth        = data.currentHealth;
            entity.CurrentFatigue       = data.currentFatigue;
            entity.CurrentMagicka       = data.currentMagicka;
            motor.IsHostile             = data.isHostile;
            senses.HasEncounteredPlayer = data.hasEncounteredPlayer;

            // Restore enemy position and migrate to floating y support for exteriors
            // Interiors seem to be working fine at this stage with any additional support
            // Dungeons are not involved with floating y and don't need any changes
            WorldContext enemyContext = GetEnemyWorldContext(enemy);

            if (enemyContext == WorldContext.Exterior)
            {
                RestoreExteriorPositionHandler(enemy, data, enemyContext);
            }
            else
            {
                // Everything else
                enemy.transform.position = data.currentPosition;
            }

            // Disable dead enemies
            if (data.isDead)
            {
                entityBehaviour.gameObject.SetActive(false);
            }

            // Restore quest resource link
            enemy.QuestSpawn = data.questSpawn;
            if (enemy.QuestSpawn)
            {
                // Add QuestResourceBehaviour to GameObject
                QuestResourceBehaviour questResourceBehaviour = entityBehaviour.gameObject.AddComponent <QuestResourceBehaviour>();
                questResourceBehaviour.RestoreSaveData(data.questResource);
            }

            // Resume entity
            entity.Quiesce = false;
        }