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);
        }
Ejemplo n.º 2
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;
            }
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Assigns a new QuestResourceBehaviour component if this is a Questor NPC.
        /// Can happen either at runtime or during scene layout.
        /// </summary>
        public void AssignQuestResourceBehaviour()
        {
            // Static NPC data must match a known questor Person resource
            Person questorPerson = QuestMachine.Instance.ActiveQuestor(Data);

            if (questorPerson == null)
            {
                return;
            }

            // Can only have a single QuestResourceBehaviour
            if (GetComponent <QuestResourceBehaviour>())
            {
                return;
            }

            // Assign new QuestResourceBehaviour and link to Person resource in quest system
            QuestResourceBehaviour resourceBehaviour = gameObject.AddComponent <QuestResourceBehaviour>();

            if (resourceBehaviour)
            {
                resourceBehaviour.AssignResource(questorPerson);
                Debug.LogFormat("Added new QuestResourceBehaviour to object {0} and assigned Questor Person resource {1}", gameObject.name, questorPerson.DisplayName);
            }
        }
Ejemplo n.º 4
0
 // Player has clicked a GameObject with a QuestResourceBehaviour attached
 void TriggerQuestResourceBehaviourClick(QuestResourceBehaviour questResourceBehaviour)
 {
     // Handle typical quest resource click
     if (questResourceBehaviour)
     {
         questResourceBehaviour.DoClick();
     }
 }
Ejemplo n.º 5
0
        void CompleteDeath()
        {
            if (!entityBehaviour)
            {
                return;
            }

            // If enemy associated with quest system, make sure quest system is done with it first
            QuestResourceBehaviour questResourceBehaviour = GetComponent <QuestResourceBehaviour>();

            if (questResourceBehaviour)
            {
                if (!questResourceBehaviour.IsFoeDead)
                {
                    return;
                }
            }

            // Play body collapse sound
            if (DaggerfallUI.Instance.DaggerfallAudioSource)
            {
                AudioClip collapseSound = DaggerfallUI.Instance.DaggerfallAudioSource.GetAudioClip((int)SoundClips.BodyFall);
                AudioSource.PlayClipAtPoint(collapseSound, entityBehaviour.transform.position);
            }

            // Disable enemy gameobject
            // Do not destroy as we must still save enemy state when dead
            gameObject.SetActive(false);

            // Show death message
            string deathMessage = HardStrings.thingJustDied;

            deathMessage = deathMessage.Replace("%s", mobile.Summary.Enemy.Name);
            DaggerfallUI.Instance.PopupMessage(deathMessage);

            // Generate lootable corpse marker
            DaggerfallLoot loot = GameObjectHelper.CreateLootableCorpseMarker(
                GameManager.Instance.PlayerObject,
                entityBehaviour.gameObject,
                enemyEntity,
                mobile.Summary.Enemy.CorpseTexture,
                DaggerfallUnity.NextUID);

            // Generate items
            loot.GenerateItems();
            entityBehaviour.CorpseLootContainer = loot;

            // Transfer any items owned by entity to loot container
            // Many quests will stash a reward in enemy inventory for player to find
            // This will be in addition to normal random loot table generation
            loot.Items.TransferAll(entityBehaviour.Entity.Items);

            // Raise static event
            if (OnEnemyDeath != null)
            {
                OnEnemyDeath(this, null);
            }
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Add a quest NPC to marker position.
        /// </summary>
        static void AddQuestNPC(SiteTypes siteType, Quest quest, QuestMarker marker, Person person, Transform parent)
        {
            // Get billboard texture data
            FactionFile.FlatData flatData;
            if (person.IsIndividualNPC)
            {
                // Individuals are always flat1 no matter gender
                flatData = FactionFile.GetFlatData(person.FactionData.flat1);
            }
            if (person.Gender == Genders.Male)
            {
                // Male has flat1
                flatData = FactionFile.GetFlatData(person.FactionData.flat1);
            }
            else
            {
                // Female has flat2
                flatData = FactionFile.GetFlatData(person.FactionData.flat2);
            }

            // Create target GameObject
            GameObject go = CreateDaggerfallBillboardGameObject(flatData.archive, flatData.record, parent);

            go.name = string.Format("Quest NPC [{0}]", person.DisplayName);

            // Set position and adjust up by half height if not inside a dungeon
            Vector3 dungeonBlockPosition = new Vector3(marker.dungeonX * RDBLayout.RDBSide, 0, marker.dungeonZ * RDBLayout.RDBSide);

            go.transform.localPosition = dungeonBlockPosition + marker.flatPosition;
            DaggerfallBillboard dfBillboard = go.GetComponent <DaggerfallBillboard>();

            if (siteType != SiteTypes.Dungeon)
            {
                go.transform.localPosition += new Vector3(0, dfBillboard.Summary.Size.y / 2, 0);
            }

            // Add people data to billboard
            dfBillboard.SetRMBPeopleData(person.FactionIndex, person.FactionData.flags);

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

            questResourceBehaviour.AssignResource(person);

            // Set QuestResourceBehaviour in Person object
            person.QuestResourceBehaviour = questResourceBehaviour;

            // Add StaticNPC behaviour
            StaticNPC npc = go.AddComponent <StaticNPC>();

            npc.SetLayoutData((int)marker.flatPosition.x, (int)marker.flatPosition.y, (int)marker.flatPosition.z, person);

            // Set tag
            go.tag = QuestMachine.questPersonTag;
        }
Ejemplo n.º 7
0
 // Check if raycast hit a QuestResource
 private bool QuestResourceBehaviourCheck(RaycastHit hitInfo, out QuestResourceBehaviour questResourceBehaviour)
 {
     questResourceBehaviour = hitInfo.transform.GetComponent <QuestResourceBehaviour>();
     if (questResourceBehaviour != null)
     {
         return(true);
     }
     else
     {
         return(false);
     }
 }
Ejemplo n.º 8
0
 // Player has clicked a GameObject with a QuestResourceBehaviour attached
 bool TriggerQuestResourceBehaviourClick(QuestResourceBehaviour questResourceBehaviour)
 {
     // Handle typical quest resource click
     if (questResourceBehaviour)
     {
         return(questResourceBehaviour.DoClick());
     }
     else
     {
         return(false);
     }
 }
Ejemplo n.º 9
0
        public override PayloadCallbackResults?EnchantmentPayloadCallback(EnchantmentPayloadFlags context, EnchantmentParam?param = null, DaggerfallEntityBehaviour sourceEntity = null, DaggerfallEntityBehaviour targetEntity = null, DaggerfallUnityItem sourceItem = null, int sourceDamage = 0)
        {
            base.EnchantmentPayloadCallback(context, param, sourceEntity, targetEntity, sourceItem, sourceDamage);

            // Validate
            if (context != EnchantmentPayloadFlags.Strikes || targetEntity == null)
            {
                return(null);
            }

            // Change target enemy
            if (targetEntity.Entity is EnemyEntity)
            {
                // Get enemy entity - cannot have Wabbajack active already
                EnemyEntity enemy = (EnemyEntity)targetEntity.Entity;
                if (enemy == null || enemy.WabbajackActive)
                {
                    return(null);
                }

                // Get new enemy career and transform
                MobileTypes enemyType = careerIDs[Random.Range(0, careerIDs.Length)];
                if ((int)enemyType == enemy.CareerIndex)
                {
                    enemyType = (MobileTypes)(((int)enemyType + 1) % careerIDs.Length);
                }
                Transform parentTransform = targetEntity.gameObject.transform.parent;

                // Do not disable enemy if in use by the quest system
                QuestResourceBehaviour questResourceBehaviour = targetEntity.GetComponent <QuestResourceBehaviour>();
                if (questResourceBehaviour && !questResourceBehaviour.IsFoeDead)
                {
                    return(null);
                }

                string[] enemyNames = TextManager.Instance.GetLocalizedTextList("enemyNames");
                if (enemyNames == null)
                {
                    throw new System.Exception("enemyNames array text not found");
                }

                // Switch entity
                targetEntity.gameObject.SetActive(false);
                GameObject gameObject = GameObjectHelper.CreateEnemy(enemyNames[(int)enemyType], enemyType, targetEntity.transform.localPosition, MobileGender.Unspecified, parentTransform);
                DaggerfallEntityBehaviour newEnemyBehaviour = gameObject.GetComponent <DaggerfallEntityBehaviour>();
                EnemyEntity newEnemy = (EnemyEntity)newEnemyBehaviour.Entity;
                newEnemy.WabbajackActive = true;
                newEnemy.CurrentHealth  -= enemy.MaxHealth - enemy.CurrentHealth; // carry over damage to new monster
            }

            return(null);
        }
Ejemplo n.º 10
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);
        }
Ejemplo n.º 11
0
        /// <summary>
        /// Adds a quest item to marker position.
        /// </summary>
        static void AddQuestItem(SiteTypes siteType, Quest quest, QuestMarker marker, Item item, Transform parent = null)
        {
            // Texture indices for quest items are from world texture record
            int textureArchive = item.DaggerfallUnityItem.WorldTextureArchive;
            int textureRecord  = item.DaggerfallUnityItem.WorldTextureRecord;

            // Create billboard
            GameObject          go          = CreateDaggerfallBillboardGameObject(textureArchive, textureRecord, parent);
            DaggerfallBillboard dfBillboard = go.GetComponent <DaggerfallBillboard>();

            // Set name
            go.name = string.Format("Quest Item [{0} | {1}]", item.Symbol.Original, item.DaggerfallUnityItem.LongName);

            // Setup custom material if available
            if (AssetInjection.TextureReplacement.CustomTextureExist(textureArchive, textureRecord))
            {
                AssetInjection.TextureReplacement.SetBillboardCustomMaterial(go, textureArchive, textureRecord);
            }

            // Marker position
            Vector3 position;
            Vector3 dungeonBlockPosition = new Vector3(marker.dungeonX * RDBLayout.RDBSide, 0, marker.dungeonZ * RDBLayout.RDBSide);

            position = dungeonBlockPosition + marker.flatPosition;

            // Dungeon flats have a different origin (centre point) than elsewhere (base point)
            // Find bottom of marker in world space as it should be aligned to placement surface (e.g. ground, table, shelf, etc.)
            if (siteType == SiteTypes.Dungeon)
            {
                position.y += (-DaggerfallLoot.randomTreasureMarkerDim / 2 * MeshReader.GlobalScale);
            }

            // Now move up item icon by half own size and assign position
            position.y += (dfBillboard.Summary.Size.y / 2f);
            go.transform.localPosition = position;

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

            questResourceBehaviour.AssignResource(item);

            // Set QuestResourceBehaviour in Item object
            item.QuestResourceBehaviour = questResourceBehaviour;

            // Assign a trigger collider for clicks
            SphereCollider collider = go.AddComponent <SphereCollider>();

            collider.isTrigger = true;
        }
Ejemplo n.º 12
0
        public override void MagicRound()
        {
            base.MagicRound();
            DaggerfallEntityBehaviour entityBehaviour = GetPeeredEntityBehaviour(manager);

            if (!entityBehaviour)
            {
                return;
            }
            if (entityBehaviour.Entity is EnemyEntity)
            {
                EnemyEntity enemy = (EnemyEntity)entityBehaviour.Entity;
                if (enemy.WabbajackActive)
                {
                    return;
                }

                MobileTypes enemyType = careerIDs[Random.Range(0, careerIDs.Length)];
                if ((int)enemyType == enemy.CareerIndex)
                {
                    enemyType = (MobileTypes)(((int)enemyType + 1) % careerIDs.Length);
                }
                Transform parentTransform = entityBehaviour.gameObject.transform.parent;
                // Do not disable enemy if in use by the quest system
                QuestResourceBehaviour questResourceBehaviour = entityBehaviour.GetComponent <QuestResourceBehaviour>();
                if (questResourceBehaviour)
                {
                    if (!questResourceBehaviour.IsFoeDead)
                    {
                        return;
                    }
                }
                entityBehaviour.gameObject.SetActive(false);
                GameObject gameObject = GameObjectHelper.CreateEnemy(HardStrings.enemyNames[(int)enemyType], enemyType, entityBehaviour.transform.localPosition, parentTransform);
                DaggerfallEntityBehaviour newEnemyBehaviour = gameObject.GetComponent <DaggerfallEntityBehaviour>();
                EnemyEntity newEnemy = (EnemyEntity)newEnemyBehaviour.Entity;
                newEnemy.WabbajackActive = true;
                newEnemy.CurrentHealth  -= enemy.MaxHealth - enemy.CurrentHealth; // carry over damage to new monster
            }
        }
Ejemplo n.º 13
0
        /// <summary>
        /// Adds a single quest foe to marker position.
        /// </summary>
        static void AddQuestFoe(SiteTypes siteType, Quest quest, QuestMarker marker, Foe foe, Transform parent)
        {
            // Create enemy GameObject
            Vector3    dungeonBlockPosition = new Vector3(marker.dungeonX * RDBLayout.RDBSide, 0, marker.dungeonZ * RDBLayout.RDBSide);
            GameObject go = CreateEnemy("Quest Foe", foe.FoeType, dungeonBlockPosition + marker.flatPosition, parent);

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

            questResourceBehaviour.AssignResource(foe);

            // Set QuestResourceBehaviour in this particular instantiated Foe object
            // Each GameObject placed in world for this Foe will reference same Foe quest resource
            // Keep this one-to-many relationship in mind for Foe handling
            foe.QuestResourceBehaviour = questResourceBehaviour;

            // Rearm injured trigger at time of placement
            // Notes for later:
            //  * This should be rearmed at the beginning of each wave
            //  * Only first wounding of a wave will trigger "injured aFoe" until rearmed on next wave
            foe.RearmInjured();
        }
Ejemplo n.º 14
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;
        }
Ejemplo n.º 15
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, 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;
        }
Ejemplo n.º 16
0
        // Player has clicked on a static NPC
        void StaticNPCClick(StaticNPC npc)
        {
            // Do nothing if no NPC passed or fade in progress
            // Quest machine does not tick while fading (to prevent things happening while screen is black)
            // But this can result in player clicking a quest NPC before quest state ticks after load and breaking quest
            if (!npc || DaggerfallUI.Instance.FadeInProgress)
            {
                return;
            }

            // Store the NPC just clicked in quest engine
            QuestMachine.Instance.LastNPCClicked = npc;

            // Check if this NPC is a quest giver and show temp guild quest popup
            // This will be changed later when temp guild system replaced with real thing
            if (QuestorCheck(npc))
            {
                return;
            }

            // Handle quest NPC click and exit if linked to a Person resource
            QuestResourceBehaviour questResourceBehaviour = npc.gameObject.GetComponent <QuestResourceBehaviour>();

            if (questResourceBehaviour)
            {
                if (TriggerQuestResourceBehaviourClick(questResourceBehaviour))
                {
                    return;
                }
            }

            // Do nothing further if a quest is actively listening on this individual NPC
            // This NPC not reserved as a Person resource but has a WhenNpcIsAvailable action listening on it
            // This effectively shuts down several named NPCs during main quest, but not trivial to otherwise determine appropriate access
            // TODO: Try to find a good solution for releasing listeners when the owning action is disabled
            if (QuestMachine.Instance.HasFactionListener(npc.Data.factionID))
            {
                return;
            }

            // Get faction data.
            FactionFile.FactionData factionData;
            if (playerEnterExit.IsPlayerInsideBuilding &&
                GameManager.Instance.PlayerEntity.FactionData.GetFactionData(npc.Data.factionID, out factionData))
            {
                UserInterfaceManager uiManager = DaggerfallUI.Instance.UserInterfaceManager;
                Debug.LogFormat("faction id: {0}, social group: {1}, guild: {2}",
                                npc.Data.factionID, (FactionFile.SocialGroups)factionData.sgroup, (FactionFile.GuildGroups)factionData.ggroup);

                // Check if the NPC offers a guild service.
                if (Enum.IsDefined(typeof(GuildServices), npc.Data.factionID))
                {
                    FactionFile.GuildGroups guild   = (FactionFile.GuildGroups)factionData.ggroup;
                    GuildServices           service = (GuildServices)npc.Data.factionID;
                    Debug.Log("NPC offers guild service: " + service.ToString());
                    uiManager.PushWindow(new DaggerfallGuildServicePopupWindow(uiManager, npc, guild, service));
                }
                // Check if this NPC is a merchant.
                else if ((FactionFile.SocialGroups)factionData.sgroup == FactionFile.SocialGroups.Merchants)
                {
                    // Shop?
                    if (RMBLayout.IsShop(playerEnterExit.BuildingDiscoveryData.buildingType))
                    {
                        if (RMBLayout.IsRepairShop(playerEnterExit.BuildingDiscoveryData.buildingType))
                        {
                            uiManager.PushWindow(new DaggerfallMerchantRepairPopupWindow(uiManager, npc));
                        }
                        else
                        {
                            uiManager.PushWindow(new DaggerfallMerchantServicePopupWindow(uiManager, npc, DaggerfallMerchantServicePopupWindow.Services.Sell));
                        }
                    }
                    // Bank?
                    else if (playerEnterExit.BuildingDiscoveryData.buildingType == DFLocation.BuildingTypes.Bank)
                    {
                        uiManager.PushWindow(new DaggerfallMerchantServicePopupWindow(uiManager, npc, DaggerfallMerchantServicePopupWindow.Services.Banking));
                    }
                    // Tavern?
                    else if (playerEnterExit.BuildingDiscoveryData.buildingType == DFLocation.BuildingTypes.Tavern)
                    {
                        // for now only talk to all npc in taverns - TODO: add tavern option in here
                        GameManager.Instance.TalkManager.TalkToStaticNPC(npc);
                    }
                }
                // TODO - more checks for npc social types?
                else // if no special handling had to be done for npc with social group of type merchant: talk to the static npc
                {
                    GameManager.Instance.TalkManager.TalkToStaticNPC(npc);
                }
            }
            else // if no special handling had to be done (all remaining npcs of the remaining social groups not handled explicitely above): default is talk to the static npc
            {
                // with one exception: guards
                if (npc.Data.billboardArchiveIndex == 183 && npc.Data.billboardRecordIndex == 3) // detect if clicked guard (comment Nystul: didn't find a better mechanism than billboard texture check)
                {
                    return;                                                                      // if guard was clicked don't open talk window
                }
                // otherwise open talk window
                GameManager.Instance.TalkManager.TalkToStaticNPC(npc);
            }
        }
Ejemplo n.º 17
0
        void CompleteDeath()
        {
            if (!entityBehaviour)
            {
                return;
            }

            // If enemy associated with quest system, make sure quest system is done with it first
            QuestResourceBehaviour questResourceBehaviour = GetComponent <QuestResourceBehaviour>();

            if (questResourceBehaviour)
            {
                if (!questResourceBehaviour.IsFoeDead)
                {
                    return;
                }
            }

            // Play body collapse sound
            if (DaggerfallUI.Instance.DaggerfallAudioSource)
            {
                AudioClip collapseSound = DaggerfallUI.Instance.DaggerfallAudioSource.GetAudioClip((int)SoundClips.BodyFall);
                AudioSource.PlayClipAtPoint(collapseSound, entityBehaviour.transform.position, 1.05f);
            }

            // Disable enemy gameobject
            // Do not destroy as we must still save enemy state when dead
            gameObject.SetActive(false);

            // Show death message
            string deathMessage = HardStrings.thingJustDied;

            deathMessage = deathMessage.Replace("%s", mobile.Summary.Enemy.Name);
            DaggerfallUI.Instance.PopupMessage(deathMessage);

            // Generate lootable corpse marker
            DaggerfallLoot loot = GameObjectHelper.CreateLootableCorpseMarker(
                GameManager.Instance.PlayerObject,
                entityBehaviour.gameObject,
                enemyEntity,
                mobile.Summary.Enemy.CorpseTexture,
                DaggerfallUnity.NextUID);

            // Generate items
            loot.GenerateItems();

            // This is still required so enemy equipment is not marked as equipped
            // This item collection is transferred to loot container below
            for (int i = (int)Items.EquipSlots.Head; i <= (int)Items.EquipSlots.Feet; i++)
            {
                Items.DaggerfallUnityItem item = enemyEntity.ItemEquipTable.GetItem((Items.EquipSlots)i);
                if (item != null)
                {
                    enemyEntity.ItemEquipTable.UnequipItem((Items.EquipSlots)i);
                }
            }

            // Chance of adding map
            loot.RandomlyAddMap(mobile.Summary.Enemy.MapChance);

            if (!string.IsNullOrEmpty(mobile.Summary.Enemy.LootTableKey))
            {
                // Chance of adding potion
                loot.RandomlyAddPotion(3);
                // Chance of adding potion recipe
                loot.RandomlyAddPotionRecipe(2);
            }

            entityBehaviour.CorpseLootContainer = loot;

            // Transfer any items owned by entity to loot container
            // Many quests will stash a reward in enemy inventory for player to find
            // This will be in addition to normal random loot table generation
            loot.Items.TransferAll(entityBehaviour.Entity.Items);

            // Raise static event
            if (OnEnemyDeath != null)
            {
                OnEnemyDeath(this, null);
            }
        }
Ejemplo n.º 18
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;
        }
Ejemplo n.º 19
0
        void CompleteDeath()
        {
            if (!entityBehaviour)
            {
                return;
            }

            // If enemy associated with quest system, make sure quest system is done with it first
            QuestResourceBehaviour questResourceBehaviour = GetComponent <QuestResourceBehaviour>();

            if (questResourceBehaviour)
            {
                if (!questResourceBehaviour.IsFoeDead)
                {
                    return;
                }
            }

            // Disable enemy gameobject
            // Do not destroy as we must still save enemy state when dead
            gameObject.SetActive(false);

            // Show death message
            string deathMessage = TextManager.Instance.GetLocalizedText("thingJustDied");

            deathMessage = deathMessage.Replace("%s", TextManager.Instance.GetLocalizedEnemyName(mobile.Summary.Enemy.ID));
            DaggerfallUI.Instance.PopupMessage(deathMessage);

            // Generate lootable corpse marker
            DaggerfallLoot loot = GameObjectHelper.CreateLootableCorpseMarker(
                GameManager.Instance.PlayerObject,
                entityBehaviour.gameObject,
                enemyEntity,
                mobile.Summary.Enemy.CorpseTexture,
                DaggerfallUnity.NextUID);

            // This is still required so enemy equipment is not marked as equipped
            // This item collection is transferred to loot container below
            for (int i = (int)Items.EquipSlots.Head; i <= (int)Items.EquipSlots.Feet; i++)
            {
                Items.DaggerfallUnityItem item = enemyEntity.ItemEquipTable.GetItem((Items.EquipSlots)i);
                if (item != null)
                {
                    enemyEntity.ItemEquipTable.UnequipItem((Items.EquipSlots)i);
                }
            }

            entityBehaviour.CorpseLootContainer = loot;

            // Transfer any items owned by entity to loot container
            // Many quests will stash a reward in enemy inventory for player to find
            // This will be in addition to normal random loot table generation
            loot.Items.TransferAll(entityBehaviour.Entity.Items);

            // Play body collapse sound
            if (DaggerfallUI.Instance.DaggerfallAudioSource)
            {
                DaggerfallUI.Instance.DaggerfallAudioSource.PlayClipAtPoint(SoundClips.BodyFall, loot.transform.position, 1f);
            }

            // Lower enemy alert state on player now that enemy is dead
            // If this is final enemy targeting player then alert state will remain clear
            // Other enemies still targeting player will continue to raise alert state every update
            EnemySenses senses = entityBehaviour.GetComponent <EnemySenses>();

            if (senses && senses.Target == GameManager.Instance.PlayerEntityBehaviour)
            {
                GameManager.Instance.PlayerEntity.SetEnemyAlert(false);
            }

            // Raise static event
            if (OnEnemyDeath != null)
            {
                OnEnemyDeath(this, null);
            }
        }
Ejemplo n.º 20
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.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;
        }