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>()); } } }
/// <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; }
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; }