Пример #1
0
 void Start()
 {
     motor  = GetComponent <EnemyMotor>();
     senses = GetComponent <EnemySenses>();
     sounds = GetComponent <EnemySounds>();
     mobile = GetComponentInChildren <DaggerfallMobileUnit>();
 }
        public object GetSaveData()
        {
            if (!enemy)
            {
                return(null);
            }

            // Get entity behaviour
            DaggerfallEntityBehaviour entityBehaviour = enemy.GetComponent <DaggerfallEntityBehaviour>();

            if (!entityBehaviour)
            {
                return(null);
            }

            // Create save data
            EnemyEntity          entity      = entityBehaviour.Entity as EnemyEntity;
            EnemyMotor           motor       = enemy.GetComponent <EnemyMotor>();
            EnemySenses          senses      = enemy.GetComponent <EnemySenses>();
            DaggerfallMobileUnit mobileEnemy = enemy.GetComponentInChildren <DaggerfallMobileUnit>();
            EnemyData_v1         data        = new EnemyData_v1();

            data.loadID               = LoadID;
            data.gameObjectName       = entityBehaviour.gameObject.name;
            data.currentPosition      = enemy.transform.position;
            data.localPosition        = enemy.transform.localPosition;
            data.currentRotation      = enemy.transform.rotation;
            data.worldContext         = entity.WorldContext;
            data.worldCompensation    = GameManager.Instance.StreamingWorld.WorldCompensation;
            data.entityType           = entity.EntityType;
            data.careerName           = entity.Career.Name;
            data.careerIndex          = entity.CareerIndex;
            data.startingHealth       = entity.MaxHealth;
            data.currentHealth        = entity.CurrentHealth;
            data.currentFatigue       = entity.CurrentFatigue;
            data.currentMagicka       = entity.CurrentMagicka;
            data.isHostile            = motor.IsHostile;
            data.hasEncounteredPlayer = senses.HasEncounteredPlayer;
            data.isDead               = (entity.CurrentHealth <= 0) ? true : false;
            data.questSpawn           = enemy.QuestSpawn;
            data.mobileGender         = mobileEnemy.Summary.Enemy.Gender;
            data.items                   = entity.Items.SerializeItems();
            data.equipTable              = entity.ItemEquipTable.SerializeEquipTable();
            data.instancedEffectBundles  = GetComponent <EntityEffectManager>().GetInstancedBundlesSaveData();
            data.alliedToPlayer          = mobileEnemy.Summary.Enemy.Team == MobileTeams.PlayerAlly;
            data.questFoeSpellQueueIndex = entity.QuestFoeSpellQueueIndex;
            data.questFoeItemQueueIndex  = entity.QuestFoeItemQueueIndex;
            data.wabbajackActive         = entity.WabbajackActive;
            data.team = (int)entity.Team + 1;

            // Add quest resource data if present
            QuestResourceBehaviour questResourceBehaviour = GetComponent <QuestResourceBehaviour>();

            if (questResourceBehaviour)
            {
                data.questResource = questResourceBehaviour.GetSaveData();
            }

            return(data);
        }
Пример #3
0
 void Start()
 {
     motor = GetComponent<EnemyMotor>();
     senses = GetComponent<EnemySenses>();
     sounds = GetComponent<EnemySounds>();
     mobile = GetComponentInChildren<DaggerfallMobileUnit>();
 }
Пример #4
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>());
                }
            }
        }
Пример #5
0
        void Awake()
        {
            // Save references
            dfAudioSource = GetComponent <DaggerfallAudioSource>();
            player        = GameObject.FindGameObjectWithTag("Player");
            mobile        = GetComponentInChildren <DaggerfallMobileUnit>();

            // Setup audio source
            dfAudioSource.AudioSource.maxDistance = AttractRadius;
            if (LinearRolloff)
            {
                dfAudioSource.AudioSource.rolloffMode = AudioRolloffMode.Linear;
            }
            dfAudioSource.AudioSource.spatialBlend = 1;

            // Assign sounds from mobile
            if (SoundsFromMobile && mobile)
            {
                MoveSound   = (SoundClips)mobile.Summary.Enemy.MoveSound;
                BarkSound   = (SoundClips)mobile.Summary.Enemy.BarkSound;
                AttackSound = (SoundClips)mobile.Summary.Enemy.AttackSound;
            }

            RaceForSounds = (Entity.Races)Random.Range(1, 5 + 1);

            // Start attract timer
            StartWaiting();
        }
Пример #6
0
        void Start()
        {
            mobile          = GetComponentInChildren <DaggerfallMobileUnit>();
            entityBehaviour = GetComponent <DaggerfallEntityBehaviour>();
            enemyEntity     = entityBehaviour.Entity as EnemyEntity;
            motor           = GetComponent <EnemyMotor>();
            questBehaviour  = GetComponent <QuestResourceBehaviour>();

            short[] classicSpawnXZDistArray     = { 1024, 384, 640, 768, 768, 768, 768 };
            short[] classicSpawnYDistUpperArray = { 128, 128, 128, 384, 768, 128, 256 };
            short[] classicSpawnYDistLowerArray = { 0, 0, 0, 0, -128, -768, 0 };
            short[] classicDespawnXZDistArray   = { 1024, 1024, 1024, 1024, 768, 768, 768 };
            short[] classicDespawnYDistArray    = { 384, 384, 384, 384, 768, 768, 768 };

            byte index = mobile.Summary.ClassicSpawnDistanceType;

            classicSpawnXZDist     = classicSpawnXZDistArray[index] * MeshReader.GlobalScale;
            classicSpawnYDistUpper = classicSpawnYDistUpperArray[index] * MeshReader.GlobalScale;
            classicSpawnYDistLower = classicSpawnYDistLowerArray[index] * MeshReader.GlobalScale;
            classicDespawnXZDist   = classicDespawnXZDistArray[index] * MeshReader.GlobalScale;
            classicDespawnYDist    = classicDespawnYDistArray[index] * MeshReader.GlobalScale;

            // 180 degrees is classic's value. 190 degrees is actual human FOV according to online sources.
            if (DaggerfallUnity.Settings.EnhancedCombatAI)
            {
                FieldOfView = 190;
            }
        }
Пример #7
0
 void Start()
 {
     senses     = GetComponent <EnemySenses>();
     controller = GetComponent <CharacterController>();
     mobile     = GetComponentInChildren <DaggerfallMobileUnit>();
     isHostile  = (mobile.Summary.Enemy.Reactions == MobileReactions.Hostile);
 }
Пример #8
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());
        }
Пример #9
0
 void Start()
 {
     //motor = GetComponent<EnemyMotor>();
     senses          = GetComponent <EnemySenses>();
     sounds          = GetComponent <EnemySounds>();
     mobile          = GetComponentInChildren <DaggerfallMobileUnit>();
     entityBehaviour = GetComponent <DaggerfallEntityBehaviour>();
 }
Пример #10
0
        protected override void Start()
        {
            enemyMotor = GetComponent <EnemyMotor>();
            controller = GetComponent <CharacterController>();
            mobile     = GetComponent <DaggerfallMobileUnit>();

            base.Start();
        }
Пример #11
0
        protected override void Start()
        {
            npcMotor   = GetComponent <MobilePersonNPC>();
            controller = GetComponent <CharacterController>();
            mobile     = GetComponent <DaggerfallMobileUnit>();

            base.Start();
        }
Пример #12
0
 void Start()
 {
     motor           = GetComponent <EnemyMotor>();
     senses          = GetComponent <EnemySenses>();
     sounds          = GetComponent <EnemySounds>();
     mobile          = GetComponent <DaggerfallEnemy>().MobileUnit;
     dfMobile        = mobile as DaggerfallMobileUnit;
     entityBehaviour = GetComponent <DaggerfallEntityBehaviour>();
 }
Пример #13
0
 void Start()
 {
     senses     = GetComponent <EnemySenses>();
     controller = GetComponent <CharacterController>();
     mobile     = GetComponentInChildren <DaggerfallMobileUnit>();
     isHostile  = mobile.Summary.Enemy.Reactions == MobileReactions.Hostile;
     flies      = mobile.Summary.Enemy.Behaviour == MobileBehaviour.Flying ||
                  mobile.Summary.Enemy.Behaviour == MobileBehaviour.Spectral;
     enemyLayerMask = LayerMask.GetMask("Enemies");
 }
Пример #14
0
 void Start()
 {
     senses     = GetComponent <EnemySenses>();
     controller = GetComponent <CharacterController>();
     mobile     = GetComponentInChildren <DaggerfallMobileUnit>();
     isHostile  = mobile.Summary.Enemy.Reactions == MobileReactions.Hostile;
     flies      = mobile.Summary.Enemy.Behaviour == MobileBehaviour.Flying ||
                  mobile.Summary.Enemy.Behaviour == MobileBehaviour.Spectral;
     swims                    = mobile.Summary.Enemy.Behaviour == MobileBehaviour.Aquatic;
     enemyLayerMask           = LayerMask.GetMask("Enemies");
     entityBehaviour          = GetComponent <DaggerfallEntityBehaviour>();
     isAttackFollowsPlayerSet = false;
 }
Пример #15
0
        public object GetSaveData()
        {
            if (!enemy)
            {
                return(null);
            }

            // Get entity behaviour
            DaggerfallEntityBehaviour entityBehaviour = enemy.GetComponent <DaggerfallEntityBehaviour>();

            if (!entityBehaviour)
            {
                return(null);
            }

            // Create save data
            EnemyEntity          entity      = entityBehaviour.Entity as EnemyEntity;
            EnemyMotor           motor       = enemy.GetComponent <EnemyMotor>();
            EnemySenses          senses      = enemy.GetComponent <EnemySenses>();
            DaggerfallMobileUnit mobileEnemy = enemy.GetComponentInChildren <DaggerfallMobileUnit>();
            EnemyData_v1         data        = new EnemyData_v1();

            data.loadID               = LoadID;
            data.gameObjectName       = entityBehaviour.gameObject.name;
            data.currentPosition      = enemy.transform.position;
            data.currentRotation      = enemy.transform.rotation;
            data.entityType           = entity.EntityType;
            data.careerName           = entity.Career.Name;
            data.careerIndex          = entity.CareerIndex;
            data.startingHealth       = entity.MaxHealth;
            data.currentHealth        = entity.CurrentHealth;
            data.currentFatigue       = entity.CurrentFatigue;
            data.currentMagicka       = entity.CurrentMagicka;
            data.isHostile            = motor.IsHostile;
            data.hasEncounteredPlayer = senses.HasEncounteredPlayer;
            data.isDead               = (entity.CurrentHealth <= 0) ? true : false;
            data.questSpawn           = enemy.QuestSpawn;
            data.mobileGender         = mobileEnemy.Summary.Enemy.Gender;
            data.items      = entity.Items.SerializeItems();
            data.equipTable = entity.ItemEquipTable.SerializeEquipTable();

            // Add quest resource data if present
            QuestResourceBehaviour questResourceBehaviour = GetComponent <QuestResourceBehaviour>();

            if (questResourceBehaviour)
            {
                data.questResource = questResourceBehaviour.GetSaveData();
            }

            return(data);
        }
Пример #16
0
        void Start()
        {
            // Disable this game object if missing mobile setup
            DaggerfallMobileUnit dfMobile = GetMobileBillboardChild();

            if (dfMobile == null)
            {
                this.gameObject.SetActive(false);
            }
            if (!dfMobile.Summary.IsSetup)
            {
                this.gameObject.SetActive(false);
            }
        }
Пример #17
0
        /// <summary>
        /// Sets up enemy based on current settings.
        /// </summary>
        public void ApplyEnemySettings()
        {
            DaggerfallUnity dfUnity = DaggerfallUnity.Instance;
            Dictionary <int, MobileEnemy> enemyDict = GameObjectHelper.EnemyDict;

            // Find mobile unit in children
            DaggerfallMobileUnit dfMobile = GetMobileBillboardChild();

            if (dfMobile != null)
            {
                // Setup mobile billboard
                Vector2 size = Vector2.one;
                dfMobile.SetEnemy(dfUnity, enemyDict[(int)EnemyType], EnemyReaction);

                // Setup controller
                CharacterController controller = GetComponent <CharacterController>();
                if (controller)
                {
                    // Set base height from sprite
                    size = dfMobile.Summary.RecordSizes[0];
                    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.Summary.Enemy.Behaviour == MobileBehaviour.Flying)
                    {
                        controller.height /= 2f;
                    }

                    // Uncomment below lines to limit maximum controller height
                    // Some particularly tall sprites (e.g. giants) require this hack to get through doors
                    // However they will appear sunken into ground as a result
                    //if (controller.height > 1.9f)
                    //    controller.height = 1.9f;
                }

                // Setup sounds
                EnemySounds enemySounds = GetComponent <Demo.EnemySounds>();
                if (enemySounds)
                {
                    enemySounds.MoveSound   = (SoundClips)dfMobile.Summary.Enemy.MoveSound;
                    enemySounds.BarkSound   = (SoundClips)dfMobile.Summary.Enemy.BarkSound;
                    enemySounds.AttackSound = (SoundClips)dfMobile.Summary.Enemy.AttackSound;
                }
            }
        }
Пример #18
0
        // Handle charging into enemies.
        private void HandleCharge(GameObject hitGO, DaggerfallEntityBehaviour hitEntityBehaviour, Vector3 direction)
        {
            if (hitEntityBehaviour.Entity is EnemyEntity)
            {
                EnemyEntity hitEnemyEntity = (EnemyEntity)hitEntityBehaviour.Entity;
                if (!hitEnemyEntity.PickpocketByPlayerAttempted)
                {
                    // Play heavy hit sound.
                    EnemySounds          enemySounds      = hitGO.GetComponent <EnemySounds>();
                    DaggerfallMobileUnit entityMobileUnit = hitGO.GetComponentInChildren <DaggerfallMobileUnit>();
                    Genders gender;
                    if (entityMobileUnit.Summary.Enemy.Gender == MobileGender.Male || hitEnemyEntity.MobileEnemy.ID == (int)MobileTypes.Knight_CityWatch)
                    {
                        gender = Genders.Male;
                    }
                    else
                    {
                        gender = Genders.Female;
                    }
                    enemySounds.PlayCombatVoice(gender, false, true);

                    // Knockback the enemy.
                    EnemyMotor enemyMotor = hitGO.GetComponent <EnemyMotor>();
                    enemyMotor.KnockbackSpeed     = 100;
                    enemyMotor.KnockbackDirection = direction;

                    // Handle charge hit damage and fatigue loss.
                    PlayerEntity playerEntity = GameManager.Instance.PlayerEntity;
                    hitEnemyEntity.PickpocketByPlayerAttempted = true;
                    playerEntity.DecreaseFatigue(PlayerEntity.DefaultFatigueLoss * 15);

                    int minBaseDamage = FormulaHelper.CalculateHandToHandMinDamage(playerEntity.Skills.GetLiveSkillValue(DFCareer.Skills.HandToHand));
                    int maxBaseDamage = FormulaHelper.CalculateHandToHandMaxDamage(playerEntity.Skills.GetLiveSkillValue(DFCareer.Skills.HandToHand));
                    int damage        = UnityEngine.Random.Range(minBaseDamage, maxBaseDamage + 1);
                    damage += playerEntity.Stats.GetLiveStatValue(DFCareer.Stats.Agility) / 10;
                    damage += playerEntity.Stats.GetLiveStatValue(DFCareer.Stats.Willpower) / 10;
                    DaggerfallEntityBehaviour playerEntityBehaviour = playerEntity.EntityBehaviour;
                    hitEntityBehaviour.DamageHealthFromSource(playerEntityBehaviour, damage, true, BloodPos());

                    Debug.LogFormat("Charged down a {0} for {1} damage!", hitEntityBehaviour.name, damage);
                }
            }
        }
Пример #19
0
        void Start()
        {
            mobile             = GetComponentInChildren <DaggerfallMobileUnit>();
            lastKnownPlayerPos = ResetPlayerPos;

            short[] classicSpawnXZDistArray     = { 1024, 384, 640, 768, 768, 768, 768 };
            short[] classicSpawnYDistUpperArray = { 128, 128, 128, 384, 768, 128, 256 };
            short[] classicSpawnYDistLowerArray = { 0, 0, 0, 0, -128, -768, 0 };
            short[] classicDespawnXZDistArray   = { 1024, 1024, 1024, 1024, 768, 768, 768 };
            short[] classicDespawnYDistArray    = { 384, 384, 384, 384, 768, 768, 768 };

            byte index = mobile.Summary.ClassicSpawnDistanceType;

            classicSpawnXZDist     = classicSpawnXZDistArray[index] * MeshReader.GlobalScale;
            classicSpawnYDistUpper = classicSpawnYDistUpperArray[index] * MeshReader.GlobalScale;
            classicSpawnYDistLower = classicSpawnYDistLowerArray[index] * MeshReader.GlobalScale;
            classicDespawnXZDist   = classicDespawnXZDistArray[index] * MeshReader.GlobalScale;
            classicDespawnYDist    = classicDespawnYDistArray[index] * MeshReader.GlobalScale;
        }
Пример #20
0
        void Start()
        {
            senses     = GetComponent <EnemySenses>();
            controller = GetComponent <CharacterController>();
            mobile     = GetComponentInChildren <DaggerfallMobileUnit>();
            isHostile  = mobile.Summary.Enemy.Reactions == MobileReactions.Hostile;
            flies      = mobile.Summary.Enemy.Behaviour == MobileBehaviour.Flying ||
                         mobile.Summary.Enemy.Behaviour == MobileBehaviour.Spectral;
            swims               = mobile.Summary.Enemy.Behaviour == MobileBehaviour.Aquatic;
            entityBehaviour     = GetComponent <DaggerfallEntityBehaviour>();
            entityEffectManager = GetComponent <EntityEffectManager>();
            entity              = entityBehaviour.Entity as EnemyEntity;
            attack              = GetComponent <EnemyAttack>();

            // Classic AI moves only as close as melee range
            if (!DaggerfallUnity.Settings.EnhancedCombatAI)
            {
                stopDistance = attack.MeleeDistance;
            }
        }
Пример #21
0
        void Start()
        {
            mobile             = GetComponentInChildren <DaggerfallMobileUnit>();
            entityBehaviour    = GetComponent <DaggerfallEntityBehaviour>();
            enemyEntity        = entityBehaviour.Entity as EnemyEntity;
            motor              = GetComponent <EnemyMotor>();
            questBehaviour     = GetComponent <QuestResourceBehaviour>();
            lastKnownTargetPos = ResetPlayerPos;

            short[] classicSpawnXZDistArray     = { 1024, 384, 640, 768, 768, 768, 768 };
            short[] classicSpawnYDistUpperArray = { 128, 128, 128, 384, 768, 128, 256 };
            short[] classicSpawnYDistLowerArray = { 0, 0, 0, 0, -128, -768, 0 };
            short[] classicDespawnXZDistArray   = { 1024, 1024, 1024, 1024, 768, 768, 768 };
            short[] classicDespawnYDistArray    = { 384, 384, 384, 384, 768, 768, 768 };

            byte index = mobile.Summary.ClassicSpawnDistanceType;

            classicSpawnXZDist     = classicSpawnXZDistArray[index] * MeshReader.GlobalScale;
            classicSpawnYDistUpper = classicSpawnYDistUpperArray[index] * MeshReader.GlobalScale;
            classicSpawnYDistLower = classicSpawnYDistLowerArray[index] * MeshReader.GlobalScale;
            classicDespawnXZDist   = classicDespawnXZDistArray[index] * MeshReader.GlobalScale;
            classicDespawnYDist    = classicDespawnYDistArray[index] * MeshReader.GlobalScale;
        }
Пример #22
0
        /// <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);
        }
Пример #23
0
        // Fine tunes foe position slightly based on mobility and enables GameObject
        void FinalizeFoe(GameObject go)
        {
            DaggerfallMobileUnit mobileUnit = go.GetComponentInChildren <DaggerfallMobileUnit>();

            if (mobileUnit)
            {
                // Align ground creatures on surface, raise flying creatures slightly into air
                if (mobileUnit.Summary.Enemy.Behaviour != MobileBehaviour.Flying)
                {
                    GameObjectHelper.AlignControllerToGround(go.GetComponent <CharacterController>());
                }
                else
                {
                    go.transform.localPosition += Vector3.up * 1.5f;
                }
            }
            else
            {
                // Just align to ground
                GameObjectHelper.AlignControllerToGround(go.GetComponent <CharacterController>());
            }

            go.SetActive(true);
        }
Пример #24
0
        float giveUpTimer;                          // Timer before enemy gives up

        void Start()
        {
            senses     = GetComponent <EnemySenses>();
            controller = GetComponent <CharacterController>();
            mobile     = GetComponentInChildren <DaggerfallMobileUnit>();
        }
Пример #25
0
 void Start()
 {
     mobile = GetComponentInChildren<DaggerfallMobileUnit>();
 }
Пример #26
0
        // Returns true if hit an enemy entity
        public bool WeaponDamage(RaycastHit hit, Vector3 direction, bool arrowHit = false)
        {
            DaggerfallUnityItem strikingWeapon = null;

            // Check if hit has an DaggerfallAction component
            DaggerfallAction action = hit.transform.gameObject.GetComponent <DaggerfallAction>();

            if (action)
            {
                action.Receive(player, DaggerfallAction.TriggerTypes.Attack);
            }

            // Check if hit has an DaggerfallActionDoor component
            DaggerfallActionDoor actionDoor = hit.transform.gameObject.GetComponent <DaggerfallActionDoor>();

            if (actionDoor)
            {
                actionDoor.AttemptBash();
                return(false);
            }

            // Check if hit an entity and remove health
            DaggerfallEntityBehaviour entityBehaviour  = hit.transform.GetComponent <DaggerfallEntityBehaviour>();
            DaggerfallMobileUnit      entityMobileUnit = hit.transform.GetComponentInChildren <DaggerfallMobileUnit>();

            if (entityBehaviour)
            {
                if (entityBehaviour.EntityType == EntityTypes.EnemyMonster || entityBehaviour.EntityType == EntityTypes.EnemyClass)
                {
                    EnemyEntity enemyEntity = entityBehaviour.Entity as EnemyEntity;

                    // Calculate damage
                    int damage;
                    if (!arrowHit)
                    {
                        if (usingRightHand)
                        {
                            strikingWeapon = currentRightHandWeapon;
                        }
                        else
                        {
                            strikingWeapon = currentLeftHandWeapon;
                        }
                    }
                    else
                    {
                        strikingWeapon = lastBowUsed;
                    }

                    damage = FormulaHelper.CalculateAttackDamage(playerEntity, enemyEntity, strikingWeapon, entityMobileUnit.Summary.AnimStateRecord);

                    // Break any "normal power" concealment effects on player
                    if (playerEntity.IsMagicallyConcealedNormalPower && damage > 0)
                    {
                        EntityEffectManager.BreakNormalPowerConcealmentEffects(GameManager.Instance.PlayerEntityBehaviour);
                    }

                    EnemyMotor  enemyMotor  = hit.transform.GetComponent <EnemyMotor>();
                    EnemySounds enemySounds = hit.transform.GetComponent <EnemySounds>();

                    // Play arrow sound and add arrow to target's inventory
                    if (arrowHit)
                    {
                        DaggerfallUnityItem arrow = ItemBuilder.CreateItem(ItemGroups.Weapons, (int)Weapons.Arrow);
                        enemyEntity.Items.AddItem(arrow);
                    }

                    // Play hit sound and trigger blood splash at hit point
                    if (damage > 0)
                    {
                        if (usingRightHand)
                        {
                            enemySounds.PlayHitSound(currentRightHandWeapon);
                        }
                        else
                        {
                            enemySounds.PlayHitSound(currentLeftHandWeapon);
                        }

                        EnemyBlood blood = hit.transform.GetComponent <EnemyBlood>();
                        if (blood)
                        {
                            blood.ShowBloodSplash(enemyEntity.MobileEnemy.BloodIndex, hit.point);
                        }

                        // Knock back enemy based on damage and enemy weight
                        if (enemyMotor)
                        {
                            if (enemyMotor.KnockBackSpeed <= (5 / (PlayerSpeedChanger.classicToUnitySpeedUnitRatio / 10)) &&
                                entityBehaviour.EntityType == EntityTypes.EnemyClass ||
                                enemyEntity.MobileEnemy.Weight > 0)
                            {
                                float enemyWeight    = enemyEntity.GetWeightInClassicUnits();
                                float tenTimesDamage = damage * 10;
                                float twoTimesDamage = damage * 2;

                                float knockBackAmount = ((tenTimesDamage - enemyWeight) * 256) / (enemyWeight + tenTimesDamage) * twoTimesDamage;
                                float knockBackSpeed  = (tenTimesDamage / enemyWeight) * (twoTimesDamage - (knockBackAmount / 256));
                                knockBackSpeed /= (PlayerSpeedChanger.classicToUnitySpeedUnitRatio / 10);

                                if (knockBackSpeed < (15 / (PlayerSpeedChanger.classicToUnitySpeedUnitRatio / 10)))
                                {
                                    knockBackSpeed = (15 / (PlayerSpeedChanger.classicToUnitySpeedUnitRatio / 10));
                                }
                                enemyMotor.KnockBackSpeed     = knockBackSpeed;
                                enemyMotor.KnockBackDirection = direction;
                            }
                        }

                        if (DaggerfallUnity.Settings.CombatVoices && entityBehaviour.EntityType == EntityTypes.EnemyClass && UnityEngine.Random.Range(1, 101) <= 40)
                        {
                            Genders gender;
                            if (entityMobileUnit.Summary.Enemy.Gender == MobileGender.Male || enemyEntity.MobileEnemy.ID == (int)MobileTypes.Knight_CityWatch)
                            {
                                gender = Genders.Male;
                            }
                            else
                            {
                                gender = Genders.Female;
                            }

                            bool heavyDamage = damage >= enemyEntity.MaxHealth / 4;
                            enemySounds.PlayCombatVoice(gender, false, heavyDamage);
                        }
                    }
                    else
                    {
                        if ((!arrowHit && !enemyEntity.MobileEnemy.ParrySounds) || strikingWeapon == null)
                        {
                            ScreenWeapon.PlaySwingSound();
                        }
                        else if (enemyEntity.MobileEnemy.ParrySounds)
                        {
                            enemySounds.PlayParrySound();
                        }
                    }

                    // Remove health
                    enemyEntity.DecreaseHealth(damage);

                    // Assign "cast when strikes" to target entity
                    if (strikingWeapon != null && strikingWeapon.IsEnchanted)
                    {
                        EntityEffectManager enemyEffectManager = enemyEntity.EntityBehaviour.GetComponent <EntityEffectManager>();
                        if (enemyEffectManager)
                        {
                            enemyEffectManager.StrikeWithItem(strikingWeapon, GameManager.Instance.PlayerEntityBehaviour);
                        }
                    }

                    // Make foe attack their aggressor
                    // Currently this is just player, but should be expanded later
                    // for a wider variety of behaviours
                    if (enemyMotor)
                    {
                        // Make enemies in an area aggressive if player attacked a non-hostile one.
                        if (!enemyMotor.IsHostile)
                        {
                            GameManager.Instance.MakeEnemiesHostile();
                        }
                        enemyMotor.MakeEnemyHostileToAttacker(GameManager.Instance.PlayerEntityBehaviour);
                    }

                    return(true);
                }
            }

            // Check if hit a mobile NPC
            MobilePersonNPC mobileNpc = hit.transform.GetComponent <MobilePersonNPC>();

            if (mobileNpc)
            {
                EnemyBlood blood = hit.transform.GetComponent <EnemyBlood>();
                if (blood)
                {
                    blood.ShowBloodSplash(0, hit.point);
                }
                mobileNpc.Motor.gameObject.SetActive(false);
                playerEntity.TallyCrimeGuildRequirements(false, 5);
                // TODO: LOS check from each townsperson. If seen, register crime and start spawning guards as below.
                playerEntity.CrimeCommitted = PlayerEntity.Crimes.Murder;
                playerEntity.SpawnCityGuards(true);
            }

            return(false);
        }
Пример #27
0
 void Awake()
 {
     mobile = GetComponentInChildren<DaggerfallMobileUnit>();
 }
Пример #28
0
 void Start()
 {
     player             = GameObject.FindGameObjectWithTag("Player");
     mobile             = GetComponentInChildren <DaggerfallMobileUnit>();
     lastKnownPlayerPos = ResetPlayerPos;
 }
Пример #29
0
 void Start()
 {
     motor = GetComponent<EnemyMotor>();
     mobile = GetComponentInChildren<DaggerfallMobileUnit>();
     blood = GetComponent<EnemyBlood>();
 }
 void Start()
 {
     senses = GetComponent<EnemySenses>();
     controller = GetComponent<CharacterController>();
     mobile = GetComponentInChildren<DaggerfallMobileUnit>();
     isHostile = (mobile.Summary.Enemy.Reactions == MobileReactions.Hostile);
 }
 void Awake()
 {
     mobile = GetComponentInChildren<DaggerfallMobileUnit>();
     entityBehaviour = GetComponent<DaggerfallEntityBehaviour>();
     entityBehaviour.OnSetEntity += EntityBehaviour_OnSetEntity;
 }
Пример #32
0
        void Start()
        {
            // Save references
            dfAudioSource = GetComponent<DaggerfallAudioSource>();
            player = GameObject.FindGameObjectWithTag("Player");
            mobile = GetComponentInChildren<DaggerfallMobileUnit>();

            // Setup audio source
            dfAudioSource.AudioSource.maxDistance = AttractRadius;
            if (LinearRolloff)
                dfAudioSource.AudioSource.rolloffMode = AudioRolloffMode.Linear;
            dfAudioSource.AudioSource.spatialBlend = 1;

            // Assign sounds from mobile
            if (SoundsFromMobile && mobile)
            {
                MoveSound = (SoundClips)mobile.Summary.Enemy.MoveSound;
                BarkSound = (SoundClips)mobile.Summary.Enemy.BarkSound;
                AttackSound = (SoundClips)mobile.Summary.Enemy.AttackSound;
            }

            // Start attrack timer
            StartWaiting();
        }
Пример #33
0
 void Awake()
 {
     mobile                       = GetComponentInChildren <DaggerfallMobileUnit>();
     entityBehaviour              = GetComponent <DaggerfallEntityBehaviour>();
     entityBehaviour.OnSetEntity += EntityBehaviour_OnSetEntity;
 }
Пример #34
0
        private int ApplyDamageToNonPlayer(Items.DaggerfallUnityItem weapon, Vector3 direction, bool bowAttack = false)
        {
            if (senses.Target == null)
            {
                return(0);
            }
            // TODO: Merge with hit code in WeaponManager to eliminate duplicate code
            EnemyEntity entity       = entityBehaviour.Entity as EnemyEntity;
            EnemyEntity targetEntity = senses.Target.Entity as EnemyEntity;
            EnemySounds targetSounds = senses.Target.GetComponent <EnemySounds>();
            EnemyMotor  targetMotor  = senses.Target.transform.GetComponent <EnemyMotor>();

            // Calculate damage
            damage = FormulaHelper.CalculateAttackDamage(entity, targetEntity, false, 0, weapon);

            // Break any "normal power" concealment effects on enemy
            if (entity.IsMagicallyConcealedNormalPower && damage > 0)
            {
                EntityEffectManager.BreakNormalPowerConcealmentEffects(entityBehaviour);
            }

            // Play hit sound and trigger blood splash at hit point
            if (damage > 0)
            {
                targetSounds.PlayHitSound(weapon);

                EnemyBlood          blood            = senses.Target.transform.GetComponent <EnemyBlood>();
                CharacterController targetController = senses.Target.transform.GetComponent <CharacterController>();
                Vector3             bloodPos         = senses.Target.transform.position + targetController.center;
                bloodPos.y += targetController.height / 8;

                if (blood)
                {
                    blood.ShowBloodSplash(targetEntity.MobileEnemy.BloodIndex, bloodPos);
                }

                // Knock back enemy based on damage and enemy weight
                if (targetMotor && (targetMotor.KnockbackSpeed <= (5 / (PlayerSpeedChanger.classicToUnitySpeedUnitRatio / 10)) &&
                                    (entityBehaviour.EntityType == EntityTypes.EnemyClass || targetEntity.MobileEnemy.Weight > 0)))
                {
                    float enemyWeight    = targetEntity.GetWeightInClassicUnits();
                    float tenTimesDamage = damage * 10;
                    float twoTimesDamage = damage * 2;

                    float knockBackAmount = ((tenTimesDamage - enemyWeight) * 256) / (enemyWeight + tenTimesDamage) * twoTimesDamage;
                    float KnockbackSpeed  = (tenTimesDamage / enemyWeight) * (twoTimesDamage - (knockBackAmount / 256));
                    KnockbackSpeed /= (PlayerSpeedChanger.classicToUnitySpeedUnitRatio / 10);

                    if (KnockbackSpeed < (15 / (PlayerSpeedChanger.classicToUnitySpeedUnitRatio / 10)))
                    {
                        KnockbackSpeed = (15 / (PlayerSpeedChanger.classicToUnitySpeedUnitRatio / 10));
                    }
                    targetMotor.KnockbackSpeed     = KnockbackSpeed;
                    targetMotor.KnockbackDirection = direction;
                }

                if (DaggerfallUnity.Settings.CombatVoices && senses.Target.EntityType == EntityTypes.EnemyClass && Dice100.SuccessRoll(40))
                {
                    DaggerfallMobileUnit targetMobileUnit = senses.Target.GetComponentInChildren <DaggerfallMobileUnit>();
                    Genders gender;
                    if (targetMobileUnit.Summary.Enemy.Gender == MobileGender.Male || targetEntity.MobileEnemy.ID == (int)MobileTypes.Knight_CityWatch)
                    {
                        gender = Genders.Male;
                    }
                    else
                    {
                        gender = Genders.Female;
                    }

                    targetSounds.PlayCombatVoice(gender, false, damage >= targetEntity.MaxHealth / 4);
                }
            }
            else
            {
                WeaponTypes weaponType = WeaponTypes.Melee;
                if (weapon != null)
                {
                    weaponType = DaggerfallUnity.Instance.ItemHelper.ConvertItemToAPIWeaponType(weapon);
                }

                if ((!bowAttack && !targetEntity.MobileEnemy.ParrySounds) || weaponType == WeaponTypes.Melee)
                {
                    sounds.PlayMissSound(weapon);
                }
                else if (targetEntity.MobileEnemy.ParrySounds)
                {
                    targetSounds.PlayParrySound();
                }
            }

            // Handle Strikes payload from enemy to non-player target - this could change damage amount
            if (weapon != null && weapon.IsEnchanted)
            {
                EntityEffectManager effectManager = GetComponent <EntityEffectManager>();
                if (effectManager)
                {
                    damage = effectManager.DoItemEnchantmentPayloads(EnchantmentPayloadFlags.Strikes, weapon, entity.Items, targetEntity.EntityBehaviour, damage);
                }
            }

            targetEntity.DecreaseHealth(damage);

            if (targetMotor)
            {
                targetMotor.MakeEnemyHostileToAttacker(entityBehaviour);
            }

            return(damage);
        }
Пример #35
0
 void Start()
 {
     motor  = GetComponent <EnemyMotor>();
     mobile = GetComponentInChildren <DaggerfallMobileUnit>();
     blood  = GetComponent <EnemyBlood>();
 }
Пример #36
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;
            DaggerfallMobileUnit mobileEnemy = enemy.GetComponentInChildren <DaggerfallMobileUnit>();

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

            // Restore special transformation state if completed
            if (data.specialTransformationCompleted && mobileEnemy)
            {
                mobileEnemy.SetSpecialTransformationCompleted();
            }

            // Resume entity
            entity.Quiesce = false;
        }
Пример #37
0
        public static GameObject CreateDaggerfallEnemyGameObject(MobileTypes type, Transform parent, MobileReactions reaction)
        {
            DaggerfallUnity dfUnity = DaggerfallUnity.Instance;

            // Ensure enemy dict is loaded
            if (enemyDict == null)
            {
                enemyDict = EnemyBasics.GetEnemyDict();
            }

            GameObject go = new GameObject(string.Format("DaggerfallEnemy [{0}]", type.ToString()));

            if (parent)
            {
                go.transform.parent = parent;
            }
            go.transform.forward = Vector3.forward;

            // Add custom tag and script
            go.tag = dfUnity.Option_EnemyTag;
#if UNITY_EDITOR
            if (dfUnity.Option_CustomEnemyScript != null)
            {
                go.AddComponent(dfUnity.Option_CustomEnemyScript.GetClass());
            }
#endif

            // Add child object for enemy billboard
            GameObject mobileObject = new GameObject("DaggerfallMobileUnit");
            mobileObject.transform.parent = go.transform;

            // Add mobile enemy
            Vector2 size = Vector2.one;
            DaggerfallMobileUnit dfMobile = mobileObject.AddComponent <DaggerfallMobileUnit>();
            dfMobile.SetEnemy(dfUnity, enemyDict[(int)type], reaction);
            size = dfMobile.Summary.RecordSizes[0];

            // Add character controller
            if (dfUnity.Option_EnemyCharacterController || dfUnity.Option_EnemyExampleAI)
            {
                CharacterController controller = go.AddComponent <CharacterController>();
                controller.radius     = dfUnity.Option_EnemyRadius;
                controller.height     = size.y;
                controller.slopeLimit = dfUnity.Option_EnemySlopeLimit;
                controller.stepOffset = dfUnity.Option_EnemyStepOffset;

                // 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.Summary.Enemy.Behaviour == MobileBehaviour.Flying)
                {
                    controller.height /= 2f;
                }

                // Limit maximum height to ensure controller can fit through doors
                // For some reason Unity 4.5 doesn't let you set SkinWidth from code >.<
                if (controller.height > 1.9f)
                {
                    controller.height = 1.9f;
                }
            }

            // Add rigidbody
            if (dfUnity.Option_EnemyRigidbody)
            {
                Rigidbody rigidbody = go.AddComponent <Rigidbody>();
                rigidbody.useGravity  = dfUnity.Option_EnemyUseGravity;
                rigidbody.isKinematic = dfUnity.Option_EnemyIsKinematic;
            }

            // Add capsule collider
            if (dfUnity.Option_EnemyCapsuleCollider)
            {
                CapsuleCollider collider = go.AddComponent <CapsuleCollider>();
                collider.radius = dfUnity.Option_EnemyRadius;
                collider.height = size.y;
            }

            // Add navmesh agent
            if (dfUnity.Option_EnemyNavMeshAgent)
            {
                NavMeshAgent agent = go.AddComponent <NavMeshAgent>();
                agent.radius     = dfUnity.Option_EnemyRadius;
                agent.height     = size.y;
                agent.baseOffset = size.y * 0.5f;
            }

            // Add example AI
            if (dfUnity.Option_EnemyExampleAI)
            {
                // EnemyMotor will also add other required components
                go.AddComponent <Demo.EnemyMotor>();

                // Set sounds
                Demo.EnemySounds enemySounds = go.GetComponent <Demo.EnemySounds>();
                if (enemySounds)
                {
                    enemySounds.MoveSound   = (SoundClips)dfMobile.Summary.Enemy.MoveSound;
                    enemySounds.BarkSound   = (SoundClips)dfMobile.Summary.Enemy.BarkSound;
                    enemySounds.AttackSound = (SoundClips)dfMobile.Summary.Enemy.AttackSound;
                }
            }

            return(go);
        }
Пример #38
0
 void Start()
 {
     player = GameObject.FindGameObjectWithTag("Player");
     mobile = GetComponentInChildren<DaggerfallMobileUnit>();
     lastKnownPlayerPos = ResetPlayerPos;
 }