/// <summary> /// Gets display name of an enemy from their ID. /// </summary> /// <param name="enemyID">ID of enemy. Valid IDs are 0-42 and 128-146, or values registered in Daggerfallentity.CustomCareerTemplates</param> /// <returns>Name of enemy from localization if found, or exception if not found.</returns> public string GetLocalizedEnemyName(int enemyID) { if (Enum.IsDefined(typeof(MobileTypes), (MobileTypes)enemyID)) { string[] enemyNames = GetLocalizedTextList("enemyNames", exception: true); if (enemyID < 128) { return(enemyNames[enemyID]); } else { return(enemyNames[43 + enemyID - 128]); } } // Handle custom enemies else { // TODO: maybe go through TextProvider so mods can try to offer localization? DaggerfallConnect.DFCareer career = DaggerfallEntity.GetCustomCareerTemplate(enemyID); if (career == null) { Debug.LogError($"Enemy ID '{enemyID}' did not have a registered custom career template"); return("(invalid enemy)"); } return(career.Name); } }
/// <summary> /// Sets up enemy based on current settings. /// </summary> public void ApplyEnemySettings(MobileGender gender) { DaggerfallUnity dfUnity = DaggerfallUnity.Instance; Dictionary <int, MobileEnemy> enemyDict = GameObjectHelper.EnemyDict; MobileEnemy mobileEnemy = enemyDict[(int)EnemyType]; if (AlliedToPlayer) { mobileEnemy.Team = MobileTeams.PlayerAlly; } // Find mobile unit in children MobileUnit dfMobile = GetMobileBillboardChild(); if (dfMobile != null) { // Setup mobile billboard Vector2 size = Vector2.one; mobileEnemy.Gender = gender; mobileEnemy.Reactions = EnemyReaction; dfMobile.SetEnemy(dfUnity, mobileEnemy, EnemyReaction, ClassicSpawnDistanceType); // Setup controller CharacterController controller = GetComponent <CharacterController>(); if (controller) { // Set base height from sprite size = dfMobile.GetSize(); controller.height = size.y; // Reduce height of flying creatures as their wing animation makes them taller than desired // This helps them get through doors while aiming for player eye height if (dfMobile.Enemy.Behaviour == MobileBehaviour.Flying) { // (in frame 0 wings are in high position, assume body is the lower half) AdjustControllerHeight(controller, controller.height / 2, ControllerJustification.BOTTOM); } // Limit minimum controller height // Stops very short characters like rats from being walked upon if (controller.height < 1.6f) { AdjustControllerHeight(controller, 1.6f, ControllerJustification.BOTTOM); } controller.gameObject.layer = LayerMask.NameToLayer("Enemies"); } // Setup sounds EnemySounds enemySounds = GetComponent <Game.EnemySounds>(); if (enemySounds) { enemySounds.MoveSound = (SoundClips)dfMobile.Enemy.MoveSound; enemySounds.BarkSound = (SoundClips)dfMobile.Enemy.BarkSound; enemySounds.AttackSound = (SoundClips)dfMobile.Enemy.AttackSound; } MeshRenderer meshRenderer = dfMobile.GetComponent <MeshRenderer>(); if (meshRenderer) { if (dfMobile.Enemy.Behaviour == MobileBehaviour.Spectral) { meshRenderer.material.shader = Shader.Find(MaterialReader._DaggerfallGhostShaderName); meshRenderer.material.SetFloat("_Cutoff", 0.1f); } if (dfMobile.Enemy.NoShadow) { meshRenderer.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off; } if (dfMobile.Enemy.GlowColor != null) { meshRenderer.receiveShadows = false; GameObject enemyLightGameObject = Instantiate(LightAura); enemyLightGameObject.transform.parent = dfMobile.transform; enemyLightGameObject.transform.localPosition = new Vector3(0, 0.3f, 0.2f); Light enemyLight = enemyLightGameObject.GetComponent <Light>(); enemyLight.color = (Color)dfMobile.Enemy.GlowColor; enemyLight.shadows = DaggerfallUnity.Settings.DungeonLightShadows ? LightShadows.Soft : LightShadows.None; } } // Setup entity if (entityBehaviour) { EnemyEntity entity = new EnemyEntity(entityBehaviour); entityBehaviour.Entity = entity; // Enemies are initially added to same world context as player entity.WorldContext = GameManager.Instance.PlayerEnterExit.WorldContext; int enemyIndex = (int)EnemyType; if (enemyIndex >= 0 && enemyIndex <= 42) { entityBehaviour.EntityType = EntityTypes.EnemyMonster; entity.SetEnemyCareer(mobileEnemy, entityBehaviour.EntityType); } else if (enemyIndex >= 128 && enemyIndex <= 146) { entityBehaviour.EntityType = EntityTypes.EnemyClass; entity.SetEnemyCareer(mobileEnemy, entityBehaviour.EntityType); } else if (DaggerfallEntity.GetCustomCareerTemplate(enemyIndex) != null) { // For custom enemies, we use the 7th bit to tell whether a class or monster was intended // 0-127 is monster // 128-255 is class // 256-383 is monster again // etc if ((enemyIndex & 128) != 0) { entityBehaviour.EntityType = EntityTypes.EnemyClass; } else { entityBehaviour.EntityType = EntityTypes.EnemyMonster; } entity.SetEnemyCareer(mobileEnemy, entityBehaviour.EntityType); } else { entityBehaviour.EntityType = EntityTypes.None; } } // Add special behaviour for Daedra Seducer mobiles if (dfMobile.Enemy.ID == (int)MobileTypes.DaedraSeducer) { dfMobile.gameObject.AddComponent <DaedraSeducerMobileBehaviour>(); } } }