Ejemplo n.º 1
0
        /// <summary>
        /// Selects a touch spell from this enemy's list and returns true if it can be cast.
        /// </summary>
        bool CanCastTouchSpell()
        {
            if (entity.CurrentMagicka <= 0)
            {
                return(false);
            }

            EffectBundleSettings[]      spells      = entity.GetSpells();
            List <EffectBundleSettings> rangeSpells = new List <EffectBundleSettings>();
            int count = 0;

            foreach (EffectBundleSettings spell in spells)
            {
                // Classic AI considers ByTouch and CasterOnly here
                if (!DaggerfallUnity.Settings.EnhancedCombatAI)
                {
                    if (spell.TargetType == TargetTypes.ByTouch ||
                        spell.TargetType == TargetTypes.CasterOnly)
                    {
                        rangeSpells.Add(spell);
                        count++;
                    }
                }
                else // Enhanced AI considers ByTouch and AreaAroundCaster. TODO: CasterOnly logic
                {
                    if (spell.TargetType == TargetTypes.ByTouch ||
                        spell.TargetType == TargetTypes.AreaAroundCaster)
                    {
                        rangeSpells.Add(spell);
                        count++;
                    }
                }
            }

            if (count == 0)
            {
                return(false);
            }

            EffectBundleSettings selectedSpellSettings = rangeSpells[Random.Range(0, count)];

            selectedSpell = new EntityEffectBundle(selectedSpellSettings, entityBehaviour);

            int totalGoldCostUnused;
            int readySpellCastingCost;

            Formulas.FormulaHelper.CalculateTotalEffectCosts(selectedSpell.Settings.Effects, selectedSpell.Settings.TargetType, out totalGoldCostUnused, out readySpellCastingCost);
            if (entity.CurrentMagicka < readySpellCastingCost)
            {
                return(false);
            }

            if (EffectsAlreadyOnTarget(selectedSpell))
            {
                return(false);
            }

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

            // Validate
            if (context != EnchantmentPayloadFlags.Used || sourceEntity == null || param == null)
            {
                return(null);
            }

            // Get caster effect manager
            EntityEffectManager effectManager = sourceEntity.GetComponent <EntityEffectManager>();

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

            // Cast when used enchantment prepares a new ready spell
            if (!string.IsNullOrEmpty(param.Value.CustomParam))
            {
                // TODO: Ready a custom spell bundle
            }
            else
            {
                // Ready a classic spell bundle
                SpellRecord.SpellRecordData spell;
                EffectBundleSettings        bundleSettings;
                EntityEffectBundle          bundle;
                if (GameManager.Instance.EntityEffectBroker.GetClassicSpellRecord(param.Value.ClassicParam, out spell))
                {
                    if (GameManager.Instance.EntityEffectBroker.ClassicSpellRecordDataToEffectBundleSettings(spell, BundleTypes.Spell, out bundleSettings))
                    {
                        // Self-cast spells are all assigned directly to self, "click to cast" spells are loaded to ready spell
                        // TODO: Support multiple ready spells so all loaded spells are launched on click
                        bundle            = new EntityEffectBundle(bundleSettings, sourceEntity);
                        bundle.CastByItem = sourceItem;
                        if (bundle.Settings.TargetType == TargetTypes.CasterOnly)
                        {
                            effectManager.AssignBundle(bundle, AssignBundleFlags.BypassSavingThrows | AssignBundleFlags.BypassChance);
                        }
                        else
                        {
                            effectManager.SetReadySpell(bundle, true);
                        }
                    }
                }
            }

            return(new PayloadCallbackResults()
            {
                durabilityLoss = durabilityLossOnUse
            });
        }
Ejemplo n.º 3
0
        public override void Update(Task caller)
        {
            // Inflict disease on player
            if (diseaseType != Diseases.None)
            {
                EntityEffectBundle bundle = GameManager.Instance.PlayerEffectManager.CreateDisease(diseaseType);
                GameManager.Instance.PlayerEffectManager.AssignBundle(bundle, AssignBundleFlags.BypassSavingThrows);
            }

            SetComplete();
        }
Ejemplo n.º 4
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.Equipped || param == null || sourceEntity == null || sourceItem == null)
            {
                return(null);
            }

            // Get caster effect manager
            EntityEffectManager casterManager = sourceEntity.GetComponent <EntityEffectManager>();

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

            // Cast when held enchantment invokes a spell bundle that is permanent until item is removed
            if (!string.IsNullOrEmpty(param.Value.CustomParam))
            {
                // TODO: Instantiate a custom spell bundle
            }
            else
            {
                // Instantiate a classic spell bundle
                SpellRecord.SpellRecordData spell;
                if (GameManager.Instance.EntityEffectBroker.GetClassicSpellRecord(param.Value.ClassicParam, out spell))
                {
                    UnityEngine.Debug.LogFormat("CastWhenHeld callback found enchantment '{0}'", spell.spellName);

                    // Create effect bundle settings from classic spell
                    EffectBundleSettings bundleSettings;
                    if (GameManager.Instance.EntityEffectBroker.ClassicSpellRecordDataToEffectBundleSettings(spell, BundleTypes.HeldMagicItem, out bundleSettings))
                    {
                        // Assign bundle
                        EntityEffectBundle bundle = new EntityEffectBundle(bundleSettings, sourceEntity);
                        bundle.FromEquippedItem = sourceItem;
                        casterManager.AssignBundle(bundle, AssignBundleFlags.BypassSavingThrows);

                        // Play cast sound on equip for player only
                        if (casterManager.IsPlayerEntity)
                        {
                            casterManager.PlayCastSound(sourceEntity, casterManager.GetCastSoundID(bundle.Settings.ElementType));
                        }

                        // TODO: Apply durability loss to equipped item on equip and over time
                        // http://en.uesp.net/wiki/Daggerfall:Magical_Items#Durability_of_Magical_Items
                    }
                }
            }

            return(null);
        }
        private void DeployFullBlownVampirism()
        {
            const int deathIsNotEternalTextID = 401;

            // Cancel rest window if sleeping
            if (DaggerfallUI.Instance.UserInterfaceManager.TopWindow is DaggerfallRestWindow)
            {
                (DaggerfallUI.Instance.UserInterfaceManager.TopWindow as DaggerfallRestWindow).CloseWindow();
            }

            // Halt random enemy spawns for next playerEntity update so player isn't bombarded by spawned enemies after transform time
            GameManager.Instance.PlayerEntity.PreventEnemySpawns = true;

            // Reset legal reputation for all regions and strip player of guild memberships
            ResetLegalRepAndGuildMembership();

            // Raise game time to an evening two weeks later
            float raiseTime = (2 * DaggerfallDateTime.SecondsPerWeek) + (DaggerfallDateTime.DuskHour + 1 - DaggerfallUnity.Instance.WorldTime.DaggerfallDateTime.Hour) * 3600;

            DaggerfallUnity.Instance.WorldTime.DaggerfallDateTime.RaiseTime(raiseTime);

            // Transfer player to a random cemetery
            // Always using a small cemetery, nothing spoils that first vampire moment like being lost the guts of a massive dungeon
            // Intentionally not spawning enemies, for this time the PLAYER is the monster lurking inside the crypt
            DFLocation location = GetRandomCemetery();
            DFPosition mapPixel = MapsFile.LongitudeLatitudeToMapPixel(location.MapTableData.Longitude, location.MapTableData.Latitude);
            DFPosition worldPos = MapsFile.MapPixelToWorldCoord(mapPixel.X, mapPixel.Y);

            GameManager.Instance.PlayerEnterExit.RespawnPlayer(
                worldPos.X,
                worldPos.Y,
                true,
                false);

            // Assign vampire spells to spellbook
            GameManager.Instance.PlayerEntity.AssignPlayerVampireSpells(InfectionVampireClan);

            // Fade in from black
            DaggerfallUI.Instance.FadeBehaviour.FadeHUDFromBlack(1.0f);

            // Start permanent vampirism effect stage two
            EntityEffectBundle bundle = GameManager.Instance.PlayerEffectManager.CreateVampirismCurse();

            GameManager.Instance.PlayerEffectManager.AssignBundle(bundle, AssignBundleFlags.BypassSavingThrows);

            // Display popup
            DaggerfallMessageBox mb = DaggerfallUI.MessageBox(deathIsNotEternalTextID);

            mb.Show();

            // Terminate custom disease lifecycle
            EndDisease();
        }
        protected override void DeployFullBlownLycanthropy()
        {
            // Start permanent wereboar lycanthropy effect stage two
            EntityEffectBundle bundle = GameManager.Instance.PlayerEffectManager.CreateLycanthropyCurse();

            GameManager.Instance.PlayerEffectManager.AssignBundle(bundle, AssignBundleFlags.BypassSavingThrows);
            LycanthropyEffect lycanthropyEffect = (LycanthropyEffect)GameManager.Instance.PlayerEffectManager.FindIncumbentEffect <LycanthropyEffect>();

            if (lycanthropyEffect != null)
            {
                lycanthropyEffect.InfectionType = LycanthropyTypes.Wereboar;
            }
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Selects a ranged spell from this enemy's list and returns true if it can be cast.
        /// </summary>
        bool CanCastRangedSpell()
        {
            if (entity.CurrentMagicka <= 0)
            {
                return(false);
            }

            EffectBundleSettings[]      spells      = entity.GetSpells();
            List <EffectBundleSettings> rangeSpells = new List <EffectBundleSettings>();
            int count = 0;

            foreach (EffectBundleSettings spell in spells)
            {
                if (spell.TargetType == TargetTypes.SingleTargetAtRange ||
                    spell.TargetType == TargetTypes.AreaAtRange)
                {
                    rangeSpells.Add(spell);
                    count++;
                }
            }

            if (count == 0)
            {
                return(false);
            }

            EffectBundleSettings selectedSpellSettings = rangeSpells[Random.Range(0, count)];

            selectedSpell = new EntityEffectBundle(selectedSpellSettings, entityBehaviour);

            int totalGoldCostUnused;
            int readySpellCastingCost;

            Formulas.FormulaHelper.CalculateTotalEffectCosts(selectedSpell.Settings.Effects, selectedSpell.Settings.TargetType, out totalGoldCostUnused, out readySpellCastingCost);
            if (entity.CurrentMagicka < readySpellCastingCost)
            {
                return(false);
            }

            if (EffectsAlreadyOnTarget(selectedSpell))
            {
                return(false);
            }

            return(true);
        }
Ejemplo n.º 8
0
        protected virtual void InstantiateSpellBundle(EnchantmentParam param, DaggerfallEntityBehaviour sourceEntity, DaggerfallUnityItem sourceItem, EntityEffectManager casterManager, bool recast = false)
        {
            if (!string.IsNullOrEmpty(param.CustomParam))
            {
                // TODO: Instantiate a custom spell bundle
            }
            else
            {
                // Instantiate a classic spell bundle
                SpellRecord.SpellRecordData spell;
                if (GameManager.Instance.EntityEffectBroker.GetClassicSpellRecord(param.ClassicParam, out spell))
                {
                    UnityEngine.Debug.LogFormat("CastWhenHeld callback found enchantment '{0}'", spell.spellName);

                    // Create effect bundle settings from classic spell
                    EffectBundleSettings bundleSettings;
                    if (GameManager.Instance.EntityEffectBroker.ClassicSpellRecordDataToEffectBundleSettings(spell, BundleTypes.HeldMagicItem, out bundleSettings))
                    {
                        // Assign bundle
                        EntityEffectBundle bundle = new EntityEffectBundle(bundleSettings, sourceEntity);
                        bundle.FromEquippedItem = sourceItem;
                        bundle.AddRuntimeFlags(BundleRuntimeFlags.ItemRecastEnabled);
                        casterManager.AssignBundle(bundle, AssignBundleFlags.BypassSavingThrows);

                        // Play cast sound on equip for player only
                        if (casterManager.IsPlayerEntity)
                        {
                            casterManager.PlayCastSound(sourceEntity, casterManager.GetCastSoundID(bundle.Settings.ElementType), true);
                        }

                        // Classic uses an item last "cast when held" effect spell cost to determine its durability loss on equip
                        // Here, all effects are considered, as it seems more coherent to do so
                        if (!recast)
                        {
                            int amount = FormulaHelper.CalculateCastingCost(spell, false);
                            sourceItem.LowerCondition(amount, sourceEntity.Entity, sourceEntity.Entity.Items);
                            //UnityEngine.Debug.LogFormat("CastWhenHeld degraded '{0}' by {1} durability points on equip. {2}/{3} remaining.", sourceItem.LongName, amount, sourceItem.currentCondition, sourceItem.maxCondition);
                        }
                    }

                    // Store equip time as last reroll time
                    sourceItem.timeEffectsLastRerolled = DaggerfallUnity.Instance.WorldTime.DaggerfallDateTime.ToClassicDaggerfallTime();
                }
            }
        }
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 || param == null || sourceDamage == 0)
            {
                return(null);
            }

            // Get target effect manager
            EntityEffectManager effectManager = targetEntity.GetComponent <EntityEffectManager>();

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

            // Cast when strikes enchantment prepares a new ready spell
            if (!string.IsNullOrEmpty(param.Value.CustomParam))
            {
                // TODO: Ready a custom spell bundle
            }
            else
            {
                // Ready a classic spell bundle
                SpellRecord.SpellRecordData spell;
                EffectBundleSettings        bundleSettings;
                EntityEffectBundle          bundle;
                if (GameManager.Instance.EntityEffectBroker.GetClassicSpellRecord(param.Value.ClassicParam, out spell))
                {
                    if (GameManager.Instance.EntityEffectBroker.ClassicSpellRecordDataToEffectBundleSettings(spell, BundleTypes.Spell, out bundleSettings))
                    {
                        bundle = new EntityEffectBundle(bundleSettings, sourceEntity);
                        effectManager.AssignBundle(bundle, AssignBundleFlags.ShowNonPlayerFailures);
                    }
                }
            }

            return(new PayloadCallbackResults()
            {
                durabilityLoss = durabilityLossOnStrike
            });
        }
Ejemplo n.º 10
0
        public override void Update(Task caller)
        {
            // Validate
            if (string.IsNullOrEmpty(effectKey) || taskSymbol == null || lastReadySpell == null)
            {
                lastReadySpell = null;
                return;
            }

            // Compare readied spell for target effect
            for (int i = 0; i < lastReadySpell.Settings.Effects.Length; i++)
            {
                if (lastReadySpell.Settings.Effects[i].Key == effectKey)
                {
                    ParentQuest.StartTask(taskSymbol);
                    SetComplete();
                    break;
                }
            }
        }
Ejemplo n.º 11
0
        public override void Update(Task caller)
        {
            // Validate
            if (spellID == -1 || classicEffects == null || classicEffects.Length == 0 || taskSymbol == null || lastReadySpell == null)
            {
                lastReadySpell = null;
                return;
            }

            // Compare readied effect properties to spell record
            int foundEffects = 0;

            for (int i = 0; i < classicEffects.Length; i++)
            {
                // Effect slot must be populated
                if (classicEffects[i].type == -1)
                {
                    continue;
                }

                // Bundle must have contain native effects matching this classic effect
                foundEffects++;
                if (!lastReadySpell.HasMatchForClassicEffect(classicEffects[i]))
                {
                    lastReadySpell = null;
                    return;
                }
            }

            // Do nothing if no effects found in spell
            if (foundEffects == 0)
            {
                SetComplete();
                return;
            }

            // Only reached here if action is running and matching spell is cast
            ParentQuest.StartTask(taskSymbol);
            SetComplete();
        }
Ejemplo n.º 12
0
        void InstantiateSpellBundle(EnchantmentParam param, DaggerfallEntityBehaviour sourceEntity, DaggerfallUnityItem sourceItem, EntityEffectManager casterManager)
        {
            if (!string.IsNullOrEmpty(param.CustomParam))
            {
                // TODO: Instantiate a custom spell bundle
            }
            else
            {
                // Instantiate a classic spell bundle
                SpellRecord.SpellRecordData spell;
                if (GameManager.Instance.EntityEffectBroker.GetClassicSpellRecord(param.ClassicParam, out spell))
                {
                    UnityEngine.Debug.LogFormat("CastWhenHeld callback found enchantment '{0}'", spell.spellName);

                    // Create effect bundle settings from classic spell
                    EffectBundleSettings bundleSettings;
                    if (GameManager.Instance.EntityEffectBroker.ClassicSpellRecordDataToEffectBundleSettings(spell, BundleTypes.HeldMagicItem, out bundleSettings))
                    {
                        // Assign bundle
                        EntityEffectBundle bundle = new EntityEffectBundle(bundleSettings, sourceEntity);
                        bundle.FromEquippedItem = sourceItem;
                        bundle.AddRuntimeFlags(BundleRuntimeFlags.ItemRecastEnabled);
                        casterManager.AssignBundle(bundle, AssignBundleFlags.BypassSavingThrows);

                        // Play cast sound on equip for player only
                        if (casterManager.IsPlayerEntity)
                        {
                            casterManager.PlayCastSound(sourceEntity, casterManager.GetCastSoundID(bundle.Settings.ElementType), true);
                        }

                        // TODO: Apply durability loss to equipped item on equip
                        // http://en.uesp.net/wiki/Daggerfall:Magical_Items#Durability_of_Magical_Items
                    }

                    // Store equip time as last reroll time
                    sourceItem.timeEffectsLastRerolled = DaggerfallUnity.Instance.WorldTime.DaggerfallDateTime.ToClassicDaggerfallTime();
                }
            }
        }
Ejemplo n.º 13
0
 private void PlayerEffectManager_OnNewReadySpell(EntityEffectBundle spell)
 {
     // Store last ready spell to evaluate on next tick
     lastReadySpell = spell;
 }
Ejemplo n.º 14
0
        void StartFromClassicSave()
        {
            DaggerfallUnity.ResetUID();
            QuestMachine.Instance.ClearState();
            RaiseOnNewGameEvent();
            ResetWeaponManager();

            // Save index must be in range
            if (classicSaveIndex < 0 || classicSaveIndex >= 6)
            {
                throw new IndexOutOfRangeException("classicSaveIndex out of range.");
            }

            // Open saves in parent path of Arena2 folder
            string    path      = SaveLoadManager.Instance.DaggerfallSavePath;
            SaveGames saveGames = new SaveGames(path);

            if (!saveGames.IsPathOpen)
            {
                throw new Exception(string.Format("Could not open Daggerfall saves path {0}", path));
            }

            // Open save index
            if (!saveGames.TryOpenSave(classicSaveIndex))
            {
                string error = string.Format("Could not open classic save index {0}.", classicSaveIndex);
                DaggerfallUI.MessageBox(error);
                DaggerfallUnity.LogMessage(string.Format(error), true);
                return;
            }

            // Get required save data
            SaveTree saveTree = saveGames.SaveTree;
            SaveVars saveVars = saveGames.SaveVars;

            SaveTreeBaseRecord positionRecord = saveTree.FindRecord(RecordTypes.CharacterPositionRecord);

            if (NoWorld)
            {
                playerEnterExit.DisableAllParents();
            }
            else
            {
                // Set player to world position
                playerEnterExit.EnableExteriorParent();
                StreamingWorld streamingWorld = FindStreamingWorld();
                int            worldX         = positionRecord.RecordRoot.Position.WorldX;
                int            worldZ         = positionRecord.RecordRoot.Position.WorldZ;
                streamingWorld.TeleportToWorldCoordinates(worldX, worldZ);
                streamingWorld.suppressWorld = false;
            }

            GameObject      cameraObject = GameObject.FindGameObjectWithTag("MainCamera");
            PlayerMouseLook mouseLook    = cameraObject.GetComponent <PlayerMouseLook>();

            if (mouseLook)
            {
                // Classic save value ranges from -256 (looking up) to 256 (looking down).
                // The maximum up and down range of view in classic is similar to 45 degrees up and down in DF Unity.
                float pitch = positionRecord.RecordRoot.Pitch;
                if (pitch != 0)
                {
                    pitch = (pitch * 45 / 256);
                }
                mouseLook.Pitch = pitch;

                float yaw = positionRecord.RecordRoot.Yaw;
                // In classic saves 2048 units of yaw is 360 degrees.
                if (yaw != 0)
                {
                    yaw = (yaw * 360 / 2048);
                }
                mouseLook.Yaw = yaw;
            }

            // Set whether the player's weapon is drawn
            WeaponManager weaponManager = GameManager.Instance.WeaponManager;

            weaponManager.Sheathed = (!saveVars.WeaponDrawn);

            // Set game time
            DaggerfallUnity.Instance.WorldTime.Now.FromClassicDaggerfallTime(saveVars.GameTime);

            // Get character record
            List <SaveTreeBaseRecord> records = saveTree.FindRecords(RecordTypes.Character);

            if (records.Count != 1)
            {
                throw new Exception("SaveTree CharacterRecord not found.");
            }

            // Get prototypical character document data
            CharacterRecord characterRecord = (CharacterRecord)records[0];

            characterDocument = characterRecord.ToCharacterDocument();

            // Assign data to player entity
            PlayerEntity playerEntity = FindPlayerEntity();

            playerEntity.AssignCharacter(characterDocument, characterRecord.ParsedData.level, characterRecord.ParsedData.maxHealth, false);
            playerEntity.SetCurrentLevelUpSkillSum();

            // Assign biography modifiers
            playerEntity.BiographyResistDiseaseMod = saveVars.BiographyResistDiseaseMod;
            playerEntity.BiographyResistMagicMod   = saveVars.BiographyResistMagicMod;
            playerEntity.BiographyAvoidHitMod      = saveVars.BiographyAvoidHitMod;
            playerEntity.BiographyResistPoisonMod  = saveVars.BiographyResistPoisonMod;
            playerEntity.BiographyFatigueMod       = saveVars.BiographyFatigueMod;

            // Assign faction data
            playerEntity.FactionData.ImportClassicReputation(saveVars);

            // Assign global variables
            playerEntity.GlobalVars.ImportClassicGlobalVars(saveVars);

            // Set time of last check for raising skills
            playerEntity.TimeOfLastSkillIncreaseCheck = saveVars.LastSkillCheckTime;

            // Assign classic items and spells to player entity
            playerEntity.AssignItemsAndSpells(saveTree);

            // Assign guild memberships
            playerEntity.AssignGuildMemberships(saveTree);

            // Assign diseases and poisons to player entity
            playerEntity.AssignDiseasesAndPoisons(saveTree);

            // Assign gold pieces
            playerEntity.GoldPieces = (int)characterRecord.ParsedData.physicalGold;

            // Assign weapon hand being used
            weaponManager.UsingRightHand = !saveVars.UsingLeftHandWeapon;

            // GodMode setting
            playerEntity.GodMode = saveVars.GodMode;

            // Setup bank accounts
            var bankRecords = saveTree.FindRecord(RecordTypes.BankAccount);

            Banking.DaggerfallBankManager.ReadNativeBankData(bankRecords);

            // Ship ownership
            Banking.DaggerfallBankManager.AssignShipToPlayer(saveVars.PlayerOwnedShip);

            // Get regional data.
            playerEntity.RegionData = saveVars.RegionData;

            // Set time tracked by playerEntity for game minute-based updates
            playerEntity.LastGameMinutes = saveVars.GameTime;

            // Get breath remaining if player was submerged (0 if they were not in the water)
            playerEntity.CurrentBreath = saveVars.BreathRemaining;

            // Get last type of crime committed
            playerEntity.CrimeCommitted = (PlayerEntity.Crimes)saveVars.CrimeCommitted;

            // Get weather
            byte[] climateWeathers = saveVars.ClimateWeathers;

            // Enums for thunder and snow are reversed in classic and Unity, so they are converted here.
            for (int i = 0; i < climateWeathers.Length; i++)
            {
                // TODO: 0x80 flag can be set for snow or rain, to add fog to these weathers. This isn't in DF Unity yet, so
                // temporarily removing the flag.
                climateWeathers[i] &= 0x7f;
                if (climateWeathers[i] == 5)
                {
                    climateWeathers[i] = 6;
                }
                else if (climateWeathers[i] == 6)
                {
                    climateWeathers[i] = 5;
                }
            }
            GameManager.Instance.WeatherManager.PlayerWeather.ClimateWeathers = climateWeathers;

            // Load character biography text
            playerEntity.BackStory = saveGames.BioFile.Lines;

            // Validate spellbook item
            DaggerfallUnity.Instance.ItemHelper.ValidateSpellbookItem(playerEntity);

            // Restore old class specials
            RestoreOldClassSpecials(saveTree, characterDocument.classicTransformedRace);

            // Restore vampirism if classic character was a vampire
            if (characterDocument.classicTransformedRace == Races.Vampire)
            {
                // Restore effect
                Debug.Log("Restoring vampirism to classic character.");
                EntityEffectBundle bundle = GameManager.Instance.PlayerEffectManager.CreateVampirismCurse();
                GameManager.Instance.PlayerEffectManager.AssignBundle(bundle, AssignBundleFlags.BypassSavingThrows);

                // Assign correct clan from classic save
                VampirismEffect vampireEffect = (VampirismEffect)GameManager.Instance.PlayerEffectManager.FindIncumbentEffect <VampirismEffect>();
                if (vampireEffect != null)
                {
                    Debug.LogFormat("Setting vampire clan to {0}", (VampireClans)characterDocument.vampireClan);
                    vampireEffect.VampireClan = (VampireClans)characterDocument.vampireClan;
                }
            }

            // TODO: Restore lycanthropy if classic character was a werewolf/wereboar

            // Start game
            DaggerfallUI.Instance.PopToHUD();
            GameManager.Instance.PauseGame(false);
            DaggerfallUI.Instance.FadeBehaviour.FadeHUDFromBlack();
            DaggerfallUI.PostMessage(PostStartMessage);

            lastStartMethod = StartMethods.LoadClassicSave;
            SaveIndex       = -1;

            if (OnStartGame != null)
            {
                OnStartGame(this, null);
            }
        }
Ejemplo n.º 15
0
 private void PlayerEffectManager_OnCastReadySpell(EntityEffectBundle spell)
 {
     // Clear last ready spell so player can't queue it up before entering location
     lastReadySpell = null;
 }
Ejemplo n.º 16
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;
        }
Ejemplo n.º 17
0
        /// <summary>
        /// Selects a ranged spell from this enemy's list and returns true if it can be cast.
        /// </summary>
        bool CanCastRangedSpell()
        {
            if (entity.CurrentMagicka <= 0)
            {
                return(false);
            }

            EffectBundleSettings[]      spells      = entity.GetSpells();
            List <EffectBundleSettings> rangeSpells = new List <EffectBundleSettings>();
            int count = 0;

            foreach (EffectBundleSettings spell in spells)
            {
                if (spell.TargetType == TargetTypes.SingleTargetAtRange ||
                    spell.TargetType == TargetTypes.AreaAtRange)
                {
                    rangeSpells.Add(spell);
                    count++;
                }
            }

            if (count == 0)
            {
                return(false);
            }

            EffectBundleSettings selectedSpellSettings = rangeSpells[Random.Range(0, count)];

            selectedSpell = new EntityEffectBundle(selectedSpellSettings, entityBehaviour);

            int totalGoldCostUnused;
            int readySpellCastingCost;

            Formulas.FormulaHelper.CalculateTotalEffectCosts(selectedSpell.Settings.Effects, selectedSpell.Settings.TargetType, out totalGoldCostUnused, out readySpellCastingCost);
            if (entity.CurrentMagicka < readySpellCastingCost)
            {
                return(false);
            }

            if (EffectsAlreadyOnTarget(selectedSpell))
            {
                return(false);
            }

            // Check that there is a clear path to shoot a spell
            float   spellMovementSpeed = 15; // All range spells are currently 15 speed
            Vector3 sphereCastDir      = senses.PredictNextTargetPos(spellMovementSpeed);

            if (sphereCastDir == EnemySenses.ResetPlayerPos)
            {
                return(false);
            }

            float sphereCastDist = (sphereCastDir - transform.position).magnitude;

            sphereCastDir = (sphereCastDir - transform.position).normalized;

            RaycastHit hit;

            if (Physics.SphereCast(transform.position, 0.45f, sphereCastDir, out hit, sphereCastDist))
            {
                DaggerfallEntityBehaviour hitTarget = hit.transform.GetComponent <DaggerfallEntityBehaviour>();

                // Clear path to target
                if (hitTarget == senses.Target)
                {
                    return(true);
                }

                // Something in the way
                return(false);
            }

            // Clear path to predicted target position
            return(true);
        }