private void Update()
        {
            // Ensure target resource has this behaviour assigned
            // Coupling is otherwise lost when reloading a game
            if (targetResource != null)
            {
                if (!targetResource.QuestResourceBehaviour)
                {
                    targetResource.QuestResourceBehaviour = this;
                }
            }

            // Handle enemy checks
            if (enemyEntityBehaviour)
            {
                // Get foe resource
                Foe foe = (Foe)targetResource;
                if (foe == null)
                {
                    return;
                }

                // If foe is hidden then remove self from game
                if (foe.IsHidden)
                {
                    Destroy(gameObject);
                    return;
                }

                // Handle restrained check
                // This might need some tuning in relation to injured and death checks
                if (foe.IsRestrained)
                {
                    // Make enemy non-hostile
                    EnemyMotor enemyMotor = transform.GetComponent <EnemyMotor>();
                    if (enemyMotor)
                    {
                        enemyMotor.IsHostile = false;
                    }

                    // Lower flag now this has been handled
                    foe.ClearRestrained();
                }

                // Handle injured check
                // This has to happen before death or script actions attached to injured event will not trigger
                if (enemyEntityBehaviour.Entity.CurrentHealth < enemyEntityBehaviour.Entity.MaxHealth && !foe.InjuredTrigger)
                {
                    foe.SetInjured();
                    return;
                }

                // Handle death check
                if (enemyEntityBehaviour.Entity.CurrentHealth <= 0 && !isFoeDead)
                {
                    foe.IncrementKills();
                    isFoeDead = true;
                }
            }
        }
        public override void Update(Task caller)
        {
            base.Update(caller);

            // Get related Foe resource
            Foe foe = ParentQuest.GetFoe(npcSymbol);

            if (foe == null)
            {
                return;
            }

            foreach (DaggerfallEnemy enemy in UnityEngine.Object.FindObjectsOfType <DaggerfallEnemy>())
            {
                if (enemy.QuestSpawn)
                {
                    QuestResourceBehaviour qrb = enemy.GetComponent <QuestResourceBehaviour>();
                    if (qrb && qrb.TargetSymbol == foe.Symbol)
                    {
                        qrb.IsAttackableByAI = isAttackableByAI;

                        SetComplete();
                    }
                }
            }

            return;
        }
Ejemplo n.º 3
0
        public void AddItemQueue(Foe foe, DaggerfallEntityBehaviour enemyEntityBehaviour)
        {
            // Validate
            if (!enemyEntityBehaviour || foe == null || foe.ItemQueueCount == 0 || foeItemQueuePosition == foe.ItemQueueCount)
            {
                return;
            }

            // Get item queue as cloned items with new UIDs
            DaggerfallUnityItem[] clonedItems = foe.GetClonedItemQueue();

            // Assign all items for player to find
            //  * Some quests assign item to Foe at create time, others on injured event
            //  * It's possible for target enemy to be one-shot or to be killed by other means (such as "killall")
            //  * This assignment will direct quest loot item either to live enemy or corpse loot container
            if (enemyEntityBehaviour.CorpseLootContainer)
            {
                // If enemy is already dead then place item in corpse loot container
                enemyEntityBehaviour.CorpseLootContainer.Items.AddItems(clonedItems);
            }
            else
            {
                // Otherwise add quest Item to Entity item collection
                // It will be transferred to corpse marker loot container when dropped
                enemyEntityBehaviour.Entity.Items.AddItems(clonedItems);
            }

            // Set index position to end of queue
            foeItemQueuePosition = foe.ItemQueueCount;
        }
Ejemplo n.º 4
0
        public override void Update(Task caller)
        {
            base.Update(caller);

            // Get related Foe resource
            Foe foe = ParentQuest.GetFoe(npcSymbol);

            if (foe == null)
            {
                return;
            }

            foreach (DaggerfallEnemy enemy in UnityEngine.Object.FindObjectsOfType <DaggerfallEnemy>())
            {
                if (enemy.QuestSpawn)
                {
                    QuestResourceBehaviour qrb = enemy.GetComponent <QuestResourceBehaviour>();
                    if (qrb && qrb.TargetSymbol == foe.Symbol)
                    {
                        DaggerfallEntityBehaviour deb = enemy.GetComponent <DaggerfallEntityBehaviour>();
                        if (deb)
                        {
                            EnemyEntity enemyEntity = deb.Entity as EnemyEntity;
                            //Debug.Log("Changed team from " + enemyEntity.Team + " to " + (MobileTeams)teamNumber);
                            enemyEntity.Team = (MobileTeams)teamNumber;

                            SetComplete();
                        }
                    }
                }
            }
        }
Ejemplo n.º 5
0
        void CreatePendingFoeSpawn()
        {
            // Get the Foe resource
            Foe foe = ParentQuest.GetFoe(foeSymbol);

            if (foe == null)
            {
                SetComplete();
                throw new Exception(string.Format("create foe could not find Foe with symbol name {0}", Symbol.Name));
            }

            // Get foe GameObjects
            pendingFoeGameObjects = GameObjectHelper.CreateFoeGameObjects(Vector3.zero, foe.FoeType, foe.SpawnCount, MobileReactions.Hostile, foe);
            if (pendingFoeGameObjects == null || pendingFoeGameObjects.Length != foe.SpawnCount)
            {
                SetComplete();
                throw new Exception(string.Format("create foe attempted to create {0}x{1} GameObjects and failed.", foe.SpawnCount, Symbol.Name));
            }

            // Initiate deployment process
            // Usually the foe will spawn immediately but can take longer depending on available placement space
            // This process ensures these foes have all been deployed before starting next cycle
            spawnInProgress    = true;
            pendingFoesSpawned = 0;
        }
Ejemplo n.º 6
0
        public override bool CheckTrigger(Task caller)
        {
            // Always return true once owning Task is triggered
            // Another action will need to rearm/unset this task if another click is required
            if (caller.IsTriggered)
            {
                return(true);
            }

            // Get related Foe resource
            Foe foe = ParentQuest.GetFoe(npcSymbol);

            if (foe == null)
            {
                return(false);
            }

            // Check player clicked flag
            if (foe.HasPlayerClicked)
            {
                // When a gold amount and task is specified, the player must have that amount of gold or another task is called
                if (goldAmount > 0 && taskSymbol != null && !string.IsNullOrEmpty(taskSymbol.Name))
                {
                    // Does player have enough gold?
                    if (GameManager.Instance.PlayerEntity.GoldPieces >= goldAmount)
                    {
                        // Then deduct gold and fire trigger
                        GameManager.Instance.PlayerEntity.GoldPieces -= goldAmount;
                    }
                    else
                    {
                        // Otherwise trigger secondary task and exit without firing trigger
                        ParentQuest.StartTask(taskSymbol);
                        return(false);
                    }
                }

                if (id != 0)
                {
                    ParentQuest.ShowMessagePopup(id);
                }

                // Rearm foe click after current task
                ParentQuest.ScheduleClickRearm(foe);

                return(true);
            }

            return(false);
        }
Ejemplo n.º 7
0
        public override void Update(Task caller)
        {
            // Get related Foe resource
            Foe foe = ParentQuest.GetFoe(foeSymbol);

            if (foe == null)
            {
                return;
            }

            // Raise the restrained flag
            foe.ClearRestrained();

            SetComplete();
        }
Ejemplo n.º 8
0
        public override void Update(Task caller)
        {
            // Get the Foe resource
            Foe foe = ParentQuest.GetFoe(foeSymbol);

            if (foe == null)
            {
                SetComplete();
                throw new Exception(string.Format("CastSpellOnFoe could not find Foe with symbol name {0}", Symbol.Name));
            }

            // Add spell to Foe resource queue
            foe.QueueSpell(spell);

            SetComplete();
        }
Ejemplo n.º 9
0
        private void Update()
        {
            // Handle enemy checks
            if (enemyEntityBehaviour)
            {
                // Handle injured check
                // This has to happen before death or script actions attached to injured event will not trigger
                Foe foe = (Foe)targetResource;
                if (enemyEntityBehaviour.Entity.CurrentHealth < enemyEntityBehaviour.Entity.MaxHealth && !foe.InjuredTrigger)
                {
                    foe.SetInjured();
                    return;
                }

                // Handle death check
                if (enemyEntityBehaviour.Entity.CurrentHealth <= 0 && !isFoeDead)
                {
                    foe.IncrementKills();
                    isFoeDead = true;
                }
            }
        }
Ejemplo n.º 10
0
        void SpawnFoe()
        {
            // Roll for spawn chance
            float chance = spawnChance / 100f;

            if (UnityEngine.Random.Range(0f, 1f) < chance)
            {
                return;
            }

            // Get the Foe resource
            Foe foe = ParentQuest.GetFoe(foeSymbol);

            if (foe == null)
            {
                throw new Exception(string.Format("create foe could not find Foe with symbol name {0}", Symbol.Name));
            }

            // Get game objects
            GameObject[] gameObjects = foe.CreateFoeGameObjects(Vector3.zero);
            if (gameObjects == null || gameObjects.Length != foe.SpawnCount)
            {
                throw new Exception(string.Format("create foe attempted to spawn {0}x{1} and failed.", foe.SpawnCount, Symbol.Name));
            }

            // For simple initial testing just place enemies 2m behind player
            // Will eventually need to spawn enemy within a certain radius of player
            // and ensure not dropped into the void for dungeons and building interiors
            GameObject player   = GameManager.Instance.PlayerObject;
            Vector3    position = player.transform.position + (-player.transform.forward * 2);

            for (int i = 0; i < gameObjects.Length; i++)
            {
                gameObjects[i].transform.position = position;
                gameObjects[i].SetActive(true);
            }
        }
Ejemplo n.º 11
0
        public override void Update(Task caller)
        {
            ulong gameSeconds = DaggerfallUnity.Instance.WorldTime.DaggerfallDateTime.ToSeconds();

            // Init spawn timer on first update
            if (lastSpawnTime == 0)
            {
                lastSpawnTime = gameSeconds + (uint)UnityEngine.Random.Range(0, spawnInterval + 1);
            }

            // Do nothing if max foes already spawned
            // This can be cleared on next set/rearm
            if (spawnCounter >= spawnMaxTimes && spawnMaxTimes != -1)
            {
                return;
            }

            // Clear pending foes if all have been spawned
            if (spawnInProgress && pendingFoesSpawned >= pendingFoeGameObjects.Length)
            {
                spawnInProgress = false;
                spawnCounter++;
                return;
            }

            // Check for a new spawn event - only one spawn event can be running at a time
            if (gameSeconds > lastSpawnTime + spawnInterval && !spawnInProgress)
            {
                // Update last spawn time
                lastSpawnTime = gameSeconds;

                // Roll for spawn chance
                float chance = spawnChance / 100f;
                if (UnityEngine.Random.Range(0f, 1f) > chance)
                {
                    return;
                }

                // Get the Foe resource
                Foe foe = ParentQuest.GetFoe(foeSymbol);
                if (foe == null)
                {
                    SetComplete();
                    throw new Exception(string.Format("create foe could not find Foe with symbol name {0}", Symbol.Name));
                }

                // Do not spawn if foe is hidden
                if (foe.IsHidden)
                {
                    return;
                }

                // Start deploying GameObjects
                CreatePendingFoeSpawn(foe);
            }

            // Try to deploy a pending spawns
            if (spawnInProgress)
            {
                TryPlacement();
                GameManager.Instance.RaiseOnEncounterEvent();
            }
        }
Ejemplo n.º 12
0
        void ParseQBN(Quest quest, List <string> lines)
        {
            bool foundHeadlessTask = false;

            for (int i = 0; i < lines.Count; i++)
            {
                // Skip empty lines while scanning for next QBN item
                if (string.IsNullOrEmpty(lines[i].Trim()))
                {
                    continue;
                }

                // Simple way to identify certain lines
                // This is just to get started on some basics for now
                if (lines[i].StartsWith("clock", StringComparison.InvariantCultureIgnoreCase))
                {
                    Clock clock = new Clock(quest, lines[i]);
                    quest.AddResource(clock);
                }
                else if (lines[i].StartsWith("item", StringComparison.InvariantCultureIgnoreCase))
                {
                    Item item = new Item(quest, lines[i]);
                    quest.AddResource(item);
                }
                else if (lines[i].StartsWith("person", StringComparison.InvariantCultureIgnoreCase))
                {
                    // This is a person declaration
                    Person person = new Person(quest, lines[i]);
                    quest.AddResource(person);
                }
                else if (lines[i].StartsWith("foe", StringComparison.InvariantCultureIgnoreCase))
                {
                    // This is an enemy declaration
                    Foe foe = new Foe(quest, lines[i]);
                    quest.AddResource(foe);
                }
                else if (lines[i].StartsWith("place", StringComparison.InvariantCultureIgnoreCase))
                {
                    // This is a place declaration
                    Place place = new Place(quest, lines[i]);
                    quest.AddResource(place);
                }
                else if (lines[i].StartsWith("variable", StringComparison.InvariantCultureIgnoreCase))
                {
                    // This is a single-line variable declaration task
                    string[] variableLines = new string[1];
                    variableLines[0] = lines[i];
                    Task task = new Task(quest, variableLines);
                    quest.AddTask(task);
                }
                else if (lines[i].Contains("task:") ||
                         (lines[i].StartsWith("until", StringComparison.InvariantCultureIgnoreCase) && lines[i].Contains("performed:")))
                {
                    // This is a standard or repeating task declaration
                    List <string> taskLines = ReadBlock(lines, ref i);
                    Task          task      = new Task(quest, taskLines.ToArray());
                    quest.AddTask(task);
                }
                else if (IsGlobalReference(lines[i]))
                {
                    // Check if following line is another task or a line break
                    bool hasBody = false;
                    if (i + 1 != lines.Count)
                    {
                        hasBody = !IsNewTaskOrLineBreak(lines[i + 1]);
                    }

                    // This is a global variable link task
                    Task task;
                    int  globalVar = GetGlobalReference(lines[i]);
                    if (hasBody)
                    {
                        List <string> taskLines = ReadBlock(lines, ref i);
                        task = new Task(quest, taskLines.ToArray(), globalVar);
                    }
                    else
                    {
                        string[] variableLines = new string[1];
                        variableLines[0] = lines[i];
                        task             = new Task(quest, variableLines, globalVar);
                    }
                    quest.AddTask(task);
                }
                else if (foundHeadlessTask == false)
                {
                    // The first QBN line found that is not a resource declaration should be our headless entry point
                    // Currently only a single headless task is expected for startup task
                    // May be expanded later to allow multiple headless tasks
                    List <string> taskLines = ReadBlock(lines, ref i);
                    Task          task      = new Task(quest, taskLines.ToArray());
                    quest.AddTask(task);
                    foundHeadlessTask = true;
                }
                else
                {
                    // Something went wrong
                    throw new Exception(string.Format("Unknown line signature encounted '{0}'.", lines[i]));
                }
            }
        }
Ejemplo n.º 13
0
        private void Update()
        {
            // Ensure target resource has this behaviour assigned
            // Coupling is otherwise lost when reloading a game
            if (targetResource != null)
            {
                if (!targetResource.QuestResourceBehaviour)
                {
                    targetResource.QuestResourceBehaviour = this;
                }
            }

            // Handle NPC checks
            if (targetResource is Person && targetResource.QuestResourceBehaviour)
            {
                // Disable person resource if hidden or destroyed
                // Normally this is done via QuestResource.Tick() but this stops receiving ticks when quest terminates
                // Sometimes a quest person is hidden at same time quest is ended, e.g. $CUREWER when spawning lycanthrope foe
                // Also disabling here to handle this situation
                Person targetPerson = (Person)targetResource;
                if (targetPerson.IsHidden || targetPerson.IsDestroyed)
                {
                    targetPerson.QuestResourceBehaviour.gameObject.SetActive(false);
                }
            }

            // Handle enemy checks
            if (enemyEntityBehaviour)
            {
                // Get foe resource
                Foe foe = (Foe)targetResource;
                if (foe == null)
                {
                    return;
                }

                // If foe is hidden then remove self from game
                if (foe.IsHidden)
                {
                    Destroy(gameObject);
                    return;
                }

                // Handle restrained check
                // This might need some tuning in relation to injured and death checks
                if (foe.IsRestrained)
                {
                    // Make enemy non-hostile
                    EnemyMotor enemyMotor = transform.GetComponent <EnemyMotor>();
                    if (enemyMotor)
                    {
                        enemyMotor.IsHostile = false;
                    }

                    // Lower flag now this has been handled
                    foe.ClearRestrained();
                }

                // Handle injured check
                // This has to happen before death or script actions attached to injured event will not trigger
                if (enemyEntityBehaviour.Entity.CurrentHealth < enemyEntityBehaviour.Entity.MaxHealth && !foe.InjuredTrigger)
                {
                    foe.SetInjured();
                    return;
                }

                // Handle death check
                if (enemyEntityBehaviour.Entity.CurrentHealth <= 0 && !isFoeDead)
                {
                    foe.IncrementKills();
                    isFoeDead = true;
                }
            }
        }
Ejemplo n.º 14
0
        public void CastSpellQueue(Foe foe, DaggerfallEntityBehaviour enemyEntityBehaviour)
        {
            // Validate
            if (!enemyEntityBehaviour || foe == null || foe.SpellQueue == null || foeSpellQueuePosition == foe.SpellQueue.Count)
            {
                return;
            }

            // Target entity must be alive
            if (enemyEntityBehaviour.Entity.CurrentHealth == 0)
            {
                return;
            }

            // Get effect manager on enemy
            EntityEffectManager enemyEffectManager = enemyEntityBehaviour.GetComponent <EntityEffectManager>();

            if (!enemyEffectManager)
            {
                return;
            }

            // Cast queued spells on foe from current position
            for (int i = foeSpellQueuePosition; i < foe.SpellQueue.Count; i++)
            {
                SpellReference     spell       = foe.SpellQueue[i];
                EntityEffectBundle spellBundle = null;

                // Create classic or custom spell bundle
                if (string.IsNullOrEmpty(spell.CustomKey))
                {
                    // Get classic spell data
                    SpellRecord.SpellRecordData spellData;
                    if (!GameManager.Instance.EntityEffectBroker.GetClassicSpellRecord(spell.ClassicID, out spellData))
                    {
                        continue;
                    }

                    // Create classic spell bundle settings
                    EffectBundleSettings bundleSettings;
                    if (!GameManager.Instance.EntityEffectBroker.ClassicSpellRecordDataToEffectBundleSettings(spellData, BundleTypes.Spell, out bundleSettings))
                    {
                        continue;
                    }

                    // Create classic spell bundle
                    spellBundle = new EntityEffectBundle(bundleSettings, enemyEntityBehaviour);
                }
                else
                {
                    // Create custom spell bundle - must be previously registered to broker
                    try
                    {
                        EntityEffectBroker.CustomSpellBundleOffer offer = GameManager.Instance.EntityEffectBroker.GetCustomSpellBundleOffer(spell.CustomKey);
                        spellBundle = new EntityEffectBundle(offer.BundleSetttings, enemyEntityBehaviour);
                    }
                    catch (Exception ex)
                    {
                        Debug.LogErrorFormat("QuestResourceBehaviour.CastSpellQueue() could not find custom spell offer with key: {0}, exception: {1}", spell.CustomKey, ex.Message);
                    }
                }

                // Assign spell bundle to enemy
                if (spellBundle != null)
                {
                    enemyEffectManager.AssignBundle(spellBundle, AssignBundleFlags.BypassSavingThrows);
                }
            }

            // Set index positon to end of queue
            foeSpellQueuePosition = foe.SpellQueue.Count;
        }