void SortForcedEnchantments(EnchantmentSettings parentEnchantment, ForcedEnchantmentSet set, out EnchantmentSettings[] forcedPowersOut, out EnchantmentSettings[] forcedSideEffectsOut) { List <EnchantmentSettings> forcedPowers = new List <EnchantmentSettings>(); List <EnchantmentSettings> forcedSideEffects = new List <EnchantmentSettings>(); foreach (ForcedEnchantment forcedEnchantment in set.forcedEffects) { IEntityEffect effect = GameManager.Instance.EntityEffectBroker.GetEffectTemplate(forcedEnchantment.key); if (effect == null) { continue; } EnchantmentSettings?enchantmentSettings = effect.GetEnchantmentSettings(forcedEnchantment.param); if (enchantmentSettings == null) { continue; } EnchantmentSettings forcedSettings = enchantmentSettings.Value; forcedSettings.ParentEnchantment = parentEnchantment.GetHashCode(); if (forcedSettings.EnchantCost > 0) { forcedPowers.Add(forcedSettings); } else { forcedSideEffects.Add(forcedSettings); } } forcedPowersOut = forcedPowers.ToArray(); forcedSideEffectsOut = forcedSideEffects.ToArray(); }
/// <summary> /// Checks whether the target already is affected by all of the effects of the given spell. /// </summary> bool EffectsAlreadyOnTarget(EntityEffectBundle spell) { if (entityBehaviour.Target) { EntityEffectManager targetEffectManager = entityBehaviour.Target.GetComponent <EntityEffectManager>(); LiveEffectBundle[] bundles = targetEffectManager.EffectBundles; for (int i = 0; i < spell.Settings.Effects.Length; i++) { bool foundEffect = false; // Get effect template IEntityEffect effectTemplate = GameManager.Instance.EntityEffectBroker.GetEffectTemplate(spell.Settings.Effects[i].Key); for (int j = 0; j < bundles.Length && !foundEffect; j++) { for (int k = 0; k < bundles[j].liveEffects.Count && !foundEffect; k++) { if (bundles[j].liveEffects[k].GetType() == effectTemplate.GetType()) { foundEffect = true; } } } if (!foundEffect) { return(false); } } } return(true); }
void UpdateAllowedButtons() { // Set defaults when no effects added if (GetFirstUsedEffectSlotIndex() == -1) { allowedTargets = defaultTargetFlags; allowedElements = defaultElementFlags; SetSpellTarget(TargetTypes.CasterOnly); SetSpellElement(ElementTypes.Magic); EnforceSelectedButtons(); return; } // Combine flags allowedTargets = EntityEffectBroker.TargetFlags_All; allowedElements = EntityEffectBroker.ElementFlags_MagicOnly; for (int i = 0; i < maxEffectsPerSpell; i++) { // Must be a valid entry if (!string.IsNullOrEmpty(effectEntries[i].Key)) { // Get effect template IEntityEffect effectTemplate = GameManager.Instance.EntityEffectBroker.GetEffectTemplate(effectEntries[i].Key); // Allowed targets are least permissive result set from combined target flags allowedTargets = allowedTargets & effectTemplate.Properties.AllowedTargets; // Allowed elements are most permissive result set from combined element flags (magic always allowed) allowedElements = allowedElements | effectTemplate.Properties.AllowedElements; } } // Ensure a valid button is selected EnforceSelectedButtons(); }
void MapClassicKey(IEntityEffect effect, bool allowReplacement) { byte groupIndex, subGroupIndex; BaseEntityEffect.ClassicEffectFamily family; // Must be an effect with classic key if (effect == null || effect.Properties.ClassicKey == 0) { return; } // Remove existing mapping if required if (classicEffectMapping.ContainsKey(effect.Properties.ClassicKey) && allowReplacement) { classicEffectMapping.Remove(effect.Properties.ClassicKey); } // Map classic key when defined - output error in case of classic key conflict BaseEntityEffect.ReverseClasicKey(effect.Properties.ClassicKey, out groupIndex, out subGroupIndex, out family); if (effect.Properties.ClassicKey != 0 && family == BaseEntityEffect.ClassicEffectFamily.Spells) { if (classicEffectMapping.ContainsKey(effect.Properties.ClassicKey)) { Debug.LogErrorFormat("EntityEffectBroker: Detected duplicate classic effect key for {0} ({1}, {2})", effect.Key, groupIndex, subGroupIndex); } else { classicEffectMapping.Add(effect.Properties.ClassicKey, effect.Key); } } }
void SetEffectLabels(string key, int effectIndex) { int labelIndex = effectIndex * 2; // Just clear labels if no effect key if (string.IsNullOrEmpty(key)) { spellEffectLabels[labelIndex].Text = string.Empty; spellEffectLabels[labelIndex + 1].Text = string.Empty; return; } // Get interface to effect IEntityEffect effect = GameManager.Instance.EntityEffectBroker.GetEffectTemplate(key); if (effect == null) { // Handle effect not found spellEffectLabels[labelIndex].Text = TextManager.Instance.GetText(textDatabase, "effectNotFoundError"); spellEffectLabels[labelIndex + 1].Text = key; return; } // Update labels spellEffectLabels[labelIndex].Text = effect.Properties.GroupName; spellEffectLabels[labelIndex + 1].Text = effect.Properties.SubGroupName; }
bool TryCareerBasedAbsorption(IEntityEffect effect, DaggerfallEntity casterEntity) { // Always resists DFCareer.SpellAbsorptionFlags spellAbsorption = casterEntity.Career.SpellAbsorption; if (spellAbsorption == DFCareer.SpellAbsorptionFlags.Always) { return(true); } // Resist in darkness (inside building or dungeon or outside at night) // Use player for inside/outside context - everything is where the player is if (spellAbsorption == DFCareer.SpellAbsorptionFlags.InDarkness) { if (GameManager.Instance.PlayerEnterExit.IsPlayerInside) { return(true); } else if (DaggerfallUnity.Instance.WorldTime.Now.IsNight) { return(true); } } // Resist in light (outside during the day) if (spellAbsorption == DFCareer.SpellAbsorptionFlags.InLight) { if (!GameManager.Instance.PlayerEnterExit.IsPlayerInside && DaggerfallUnity.Instance.WorldTime.Now.IsDay) { return(true); } } return(false); }
void MergeSkillMods(IEntityEffect effect, ref int[] combinedSkillMods) { for (int i = 0; i < effect.SkillMods.Length; i++) { combinedSkillMods[i] += effect.SkillMods[i]; } }
/// <summary> /// Gets effect template from classic effect record data, if one is available. /// </summary> /// <param name="effectRecordData">Classic effect record data.</param> /// <returns>IEntityEffect of template found or null if no matching template found.</returns> public IEntityEffect GetEffectTemplateFromClassicEffectRecordData(SpellRecord.EffectRecordData effectRecordData) { // Ignore unused effect if (effectRecordData.type == -1) { return(null); } // Get effect type/subtype int type, subType; type = effectRecordData.type; subType = (effectRecordData.subType < 0) ? 255 : effectRecordData.subType; // Entity effect keys use 255 instead of -1 for subtype // Check if effect template is implemented for this slot - instant fail if effect not implemented int classicKey = BaseEntityEffect.MakeClassicKey((byte)type, (byte)subType); // Attempt to find the effect template IEntityEffect result = GameManager.Instance.EntityEffectBroker.GetEffectTemplate(classicKey); if (result == null) { Debug.LogWarningFormat("Could not find effect template for type={0} subType={1}", type, subType); } return(result); }
/// <summary> /// Checks if all classic effects map to an implemented IEntityEffect template. /// </summary> /// <param name="spellRecordData">Classic spell record data.</param> /// <returns>True if all classic effects map to an effect template.</returns> public bool AllEffectsImplemented(SpellRecord.SpellRecordData spellRecordData) { // There are up to 3 effects per spell int foundEffects = 0; for (int i = 0; i < spellRecordData.effects.Length; i++) { // Try to get effect template IEntityEffect effectTemplate = GetEffectTemplateFromClassicEffectRecordData(spellRecordData.effects[i]); if (effectTemplate == null) { continue; } // Otherwise effect is implemented and can be counted foundEffects++; } // Must have at least one effect counted (handles all 3 slots being -1/-1) if (foundEffects == 0) { return(false); } return(true); }
void SpellEffectPanelClick(BaseScreenComponent sender, Vector2 position) { // Get spell and exit if spell index not found EffectBundleSettings spellSettings; if (!GameManager.Instance.PlayerEntity.GetSpell(spellsListBox.SelectedIndex, out spellSettings)) { return; } // Get effect index of panel clicked int effectIndex; if (sender.Name == spellEffectPanels[0].Name && spellSettings.Effects.Length >= 1) { effectIndex = 0; } else if (sender.Name == spellEffectPanels[1].Name && spellSettings.Effects.Length >= 2) { effectIndex = 1; } else if (sender.Name == spellEffectPanels[2].Name && spellSettings.Effects.Length >= 3) { effectIndex = 2; } else { return; } // Create effect instance with settings and show popup IEntityEffect effect = GameManager.Instance.EntityEffectBroker.InstantiateEffect(spellSettings.Effects[effectIndex]); ShowEffectPopup(effect); }
/// <summary> /// Clone an effect and its settings. /// </summary> /// <param name="effect">Effect to clone.</param> /// <returns>Interface to cloned effect.</returns> public IEntityEffect CloneEffect(IEntityEffect effect) { IEntityEffect clone = Activator.CreateInstance(effect.GetType()) as IEntityEffect; clone.Settings = effect.Settings; return(clone); }
/// <summary> /// Cancels all remaining rounds of any active incumbent effect of type T and calls End() on that effect. /// If incumbent effect T is only live effect in bundle then whole bundle will be removed. /// If other effects remain in bundle then incumbent effect will stop operation and bundle will expire when other effects allow it. /// Does nothing if no incumbent effect of type T found. /// </summary> /// <typeparam name="T">IncumbentEffect type T to end.</typeparam> public void EndIncumbentEffect <T>() { IEntityEffect effect = FindIncumbentEffect <T>(); if (effect != null) { effect.RoundsRemaining = 0; effect.End(); } }
void AddAndEditSlot(IEntityEffect effectTemplate) { effectEditor.EffectTemplate = effectTemplate; int slot = GetFirstFreeEffectSlotIndex(); effectEntries[slot] = effectEditor.EffectEntry; UpdateSlotText(slot, effectEditor.EffectTemplate.DisplayName); UpdateAllowedButtons(); editOrDeleteSlot = slot; uiManager.PushWindow(effectEditor); }
/// <summary> /// Gets number of potion properties assigned to this effect. /// Effect must allow the potion maker crafting station and define potion recipes. /// Effect /// </summary> /// <param name="effect">Input effect.</param> /// <returns>Number of recipes for this effect.</returns> public int GetEffectPotionRecipeCount(IEntityEffect effect) { // Effect must be valid and support potion crafting if (effect != null && effect.PotionProperties.Recipes != null && (effect.Properties.AllowedCraftingStations & MagicCraftingStations.PotionMaker) == MagicCraftingStations.PotionMaker) { return(effect.PotionProperties.Recipes.Length); } return(0); }
int GetEffectCastingCost(IEntityEffect effect, TargetTypes targetType, DaggerfallEntity casterEntity) { int goldCost, spellPointCost; FormulaHelper.CalculateEffectCosts(effect, effect.Settings, out goldCost, out spellPointCost, casterEntity); spellPointCost = FormulaHelper.ApplyTargetCostMultiplier(spellPointCost, targetType); //Debug.LogFormat("Calculated {0} spell point cost for effect {1}", spellPointCost, effect.Key); return(spellPointCost); }
/// <summary> /// Gets PotionRecipe from IEntityEffect. /// Effect must allow the potion maker crafting station and define a potion recipe. /// </summary> /// <param name="effect">Input effect.</param> /// <returns>PotionRecipe if the effect has one, otherwise null.</returns> public PotionRecipe GetEffectPotionRecipe(IEntityEffect effect) { if (effect != null && (effect.Properties.AllowedCraftingStations & MagicCraftingStations.PotionMaker) == MagicCraftingStations.PotionMaker && effect.PotionProperties.Recipe != null && effect.PotionProperties.Recipe.HasRecipe()) { return(effect.PotionProperties.Recipe); } return(null); }
private void EnchantmentPrimaryPicker_OnUseSelectedItem() { // Clear existing enchantmentSecondaryPicker.ListBox.ClearItems(); // Get the effect template tagged to selected item ListBox.ListItem listItem = enchantmentPrimaryPicker.ListBox.SelectedValue; IEntityEffect effect = listItem.tag as IEntityEffect; if (effect == null) { throw new Exception(string.Format("ListItem '{0}' has no IEntityEffect tag", listItem.textLabel.Text)); } // Filter enchantments based on effect key EnchantmentSettings[] filteredEnchantments = enumeratedEnchantments.Where(e => e.EffectKey == effect.Key).ToArray(); if (filteredEnchantments == null || filteredEnchantments.Length == 0) { throw new Exception(string.Format("Found no enchantments for effect key '{0}'", effect.Key)); } // If this is a singleton effect with no secondary options then add directly to powers/side-effects if (filteredEnchantments.Length == 1) { AddEnchantmentSettings(filteredEnchantments[0]); enchantmentPrimaryPicker.CloseWindow(); return; } // Order filtered list by alpha when requested by effect flags if (effect.HasItemMakerFlags(ItemMakerFlags.AlphaSortSecondaryList)) { filteredEnchantments = filteredEnchantments.OrderBy(o => o.SecondaryDisplayName).ToArray(); } // User must select from available secondary enchantment types foreach (EnchantmentSettings enchantment in filteredEnchantments) { // Filter out enchantment when multiple instances not allowed if (!effect.HasItemMakerFlags(ItemMakerFlags.AllowMultipleSecondaryInstances)) { if (ContainsEnchantmentSettings(enchantment)) { continue; } } enchantmentSecondaryPicker.ListBox.AddItem(enchantment.SecondaryDisplayName, -1, enchantment); } enchantmentSecondaryPicker.ListBox.SelectedIndex = 0; uiManager.PushWindow(enchantmentSecondaryPicker); }
void ShowEffectPopup(IEntityEffect effect) { if (effect == null) { return; } DaggerfallMessageBox spellEffectPopup = new DaggerfallMessageBox(uiManager, this); spellEffectPopup.ClickAnywhereToClose = true; spellEffectPopup.SetTextTokens(effect.Properties.SpellBookDescription, effect); spellEffectPopup.Show(); }
/// <summary> /// Tests incoming effect for spell absorption. If absorption succeeds the entity will /// block effect and recover spell points equal to the casting cost of blocked effect. /// If target does not have enough spell points free to absorb effect cost then effect will NOT be absorbed. /// For example if player has 0 of 50 spell points available, they can absorb an incoming effect costing up to 50 spell points. /// An effect costing 51 spell points cannot be absorbed. It's "all or nothing". /// Notes: /// - There are two variants of spell absorption in Daggerfall. /// - Career-based: This is the "none / in light / in darkness / always" assigned to entity career kit. /// - Effect-based: Generated by having an active Spell Absorption effect from a spell or item. /// - In classic effect-based absorption from spells/items will override career-based absorption. Not sure if bug. /// - Career-based absorption will always succeed chance check. /// - Spell-based will roll for check on each absorb attempt. /// </summary> /// <param name="effect">Incoming effect.</param> /// <param name="targetType">Source bundle target type for spell cost calculation.</param> /// <param name="casterEntity">Source caster entity behaviour for spell cost calculation.</param> /// <param name="absorbSpellPointsOut">Number of spell points absorbed. Only valid when returning true.</param> /// <returns>True if absorbed.</returns> bool TryAbsorption(IEntityEffect effect, TargetTypes targetType, DaggerfallEntity casterEntity, out int absorbSpellPointsOut) { absorbSpellPointsOut = 0; // Effect cannot be null if (effect == null) { return(false); } // Currently only absorbing Destruction magic - not sure on status of absorbing other magic schools // This is to prevent something as benign as a self-heal from player being blocked and absorbed // With current design, absorption is checked for ALL incoming effects to entity so require some sanity checks if (effect.Properties.MagicSkill != DFCareer.MagicSkills.Destruction) { return(false); } // Get casting cost for this effect // Costs are calculated as if target cast the spell, not the actual caster // Note that if player self-absorbs a spell this will be equal anyway int effectCastingCost = GetEffectCastingCost(effect, targetType, entityBehaviour.Entity); // The entity must have enough spell points free to absorb incoming effect int availableSpellPoints = entityBehaviour.Entity.MaxMagicka - entityBehaviour.Entity.CurrentMagicka; if (effectCastingCost > availableSpellPoints) { return(false); } else { absorbSpellPointsOut = effectCastingCost; } // Check if entity has an absorb incumbent running SpellAbsorption absorbEffect = FindIncumbentEffect <SpellAbsorption>() as SpellAbsorption; if (absorbEffect != null) { return(TryEffectBasedAbsorption(effect, absorbEffect, casterEntity)); } // Handle career-based absorption if (entityBehaviour.Entity.Career.SpellAbsorption != DFCareer.SpellAbsorptionFlags.None) { return(TryCareerBasedAbsorption(effect, casterEntity)); } return(false); }
/// <summary> /// Creates a new instance of effect with specified settings. /// Use this to create a new effect with unique settings for actual use. /// </summary> /// <param name="key">Effect key.</param> /// <param name="settings">Effect settings.</param> /// <returns>Interface to new effect instance.</returns> public IEntityEffect InstantiateEffect(string key, EffectSettings settings) { if (!HasEffectTemplate(key)) { return(null); } IEntityEffect effectTemplate = magicEffectTemplates[key]; IEntityEffect effectInstance = Activator.CreateInstance(effectTemplate.GetType()) as IEntityEffect; effectInstance.Settings = settings; return(effectInstance); }
/// <summary> /// Cause fatigue damage to entity with additional logic. /// </summary> /// <param name="sourceEffect">Source effect.</param> /// <param name="amount">Amount to damage fatigue.</param> /// <param name="assignMultiplier">Optionally assign fatigue multiplier.</param> public void DamageFatigueFromSource(IEntityEffect sourceEffect, int amount, bool assignMultiplier = false) { // Skip fatigue damage from effects if this is a non-hostile enemy // This is a hack to support N0B00Y08 otherwise warrior will aggro if player casts Sleep on them // Warrior does not aggro in classic and it seems impossible to cast this class of spell on non-hostiles in classic // Would prefer a better system such as a quest action to whitelist certain spells on a Foe resource // But this will get job done in this case and we can expand/improve later if (!IsHostileEnemy()) { return; } DamageFatigueFromSource(sourceEffect.Caster, amount, assignMultiplier); }
void SpellEffectPanelClick(BaseScreenComponent sender, Vector2 position) { // Get spell settings EffectBundleSettings spellSettings; if (buyMode) { DaggerfallUI.Instance.PlayOneShot(SoundClips.ButtonClick); spellSettings = offeredSpells[spellsListBox.SelectedIndex]; } else { if (!GameManager.Instance.PlayerEntity.GetSpell(spellsListBox.SelectedIndex, out spellSettings)) { return; } } // Settings must look valid if (spellSettings.Version < EntityEffectBroker.MinimumSupportedSpellVersion) { return; } // Get effect index of panel clicked int effectIndex; if (sender.Name == spellEffectPanels[0].Name && spellSettings.Effects.Length >= 1) { effectIndex = 0; } else if (sender.Name == spellEffectPanels[1].Name && spellSettings.Effects.Length >= 2) { effectIndex = 1; } else if (sender.Name == spellEffectPanels[2].Name && spellSettings.Effects.Length >= 3) { effectIndex = 2; } else { return; } // Create effect instance with settings and show popup IEntityEffect effect = GameManager.Instance.EntityEffectBroker.InstantiateEffect(spellSettings.Effects[effectIndex]); ShowEffectPopup(effect); }
/// <summary> /// Checks if effect bundle contains an effect matching a classic effect record. /// </summary> /// <param name="effectRecord">Effect record to compare with native bundle effects.</param> /// <returns>True if bundle contains effect matching classic effect record.</returns> public bool HasMatchForClassicEffect(SpellRecord.EffectRecordData effectRecord) { int classicKey = BaseEntityEffect.MakeClassicKey((byte)effectRecord.type, (byte)effectRecord.subType); foreach (EffectEntry entry in settings.Effects) { IEntityEffect effectTemplate = GameManager.Instance.EntityEffectBroker.GetEffectTemplate(entry.Key); if (effectTemplate.Properties.ClassicKey == classicKey) { return(true); } } return(false); }
private void AddEffectSubGroup_OnUseSelectedItem() { // Close effect pickers effectGroupPicker.CloseWindow(); effectSubGroupPicker.CloseWindow(); // Get selected effect from those on offer IEntityEffect effectTemplate = enumeratedEffectTemplates[effectSubGroupPicker.ListBox.SelectedIndex]; if (effectTemplate != null) { AddAndEditSlot(effectTemplate); //Debug.LogFormat("Selected effect {0} {1} with key {2}", effectTemplate.GroupName, effectTemplate.SubGroupName, effectTemplate.Key); } }
/// <summary> /// Get full effect save data including effect specific data. /// </summary> public EffectSaveData_v1 GetEffectSaveData(IEntityEffect effect) { EffectSaveData_v1 effectData = new EffectSaveData_v1(); effectData.key = effect.Key; effectData.effectSettings = effect.Settings; effectData.roundsRemaining = effect.RoundsRemaining; effectData.chanceSuccess = effect.ChanceSuccess; effectData.statMods = effect.StatMods; effectData.skillMods = effect.SkillMods; effectData.isIncumbent = (effect is IncumbentEffect) ? (effect as IncumbentEffect).IsIncumbent : false; effectData.effectSpecific = effect.GetSaveData(); return(effectData); }
private void EnchantmentSecondaryPicker_OnUseSelectedItem() { // Get enchantment tagged to selected item ListBox.ListItem listItem = enchantmentSecondaryPicker.ListBox.SelectedValue; if (listItem.tag == null) { throw new Exception(string.Format("ListItem '{0}' has no EnchantmentSettings tag", listItem.textLabel.Text)); } // Get enchantment settings EnchantmentSettings enchantmentSettings = (EnchantmentSettings)listItem.tag; IEntityEffect enchantmentEffect = GameManager.Instance.EntityEffectBroker.GetEffectTemplate(enchantmentSettings.EffectKey); EnchantmentParam enchantmentParam = new EnchantmentParam() { ClassicParam = enchantmentSettings.ClassicParam, CustomParam = enchantmentSettings.CustomParam }; // Get forced enchantments for this effect EnchantmentSettings[] forcedPowers = null; EnchantmentSettings[] forcedSideEffects = null; ForcedEnchantmentSet? forcedEnchantmentSet = enchantmentEffect.GetForcedEnchantments(enchantmentParam); if (forcedEnchantmentSet != null) { // Sort forced enchantments into powers and side effects SortForcedEnchantments(enchantmentSettings, forcedEnchantmentSet.Value, out forcedPowers, out forcedSideEffects); // Check for overflow from automatic enchantments and display "no room in item..." // Also adding +1 to account for incoming enchantment if (powersList.EnchantmentCount + sideEffectsList.EnchantmentCount + forcedPowers.Length + forcedSideEffects.Length + 1 > 10) { DaggerfallUI.MessageBox(TextManager.Instance.GetText(textDatabase, "noRoomInItem")); return; } } // Add selected enchantment settings to powers/side-effects AddEnchantmentSettings(enchantmentSettings); AddForcedPowers(forcedPowers); AddForcedSideEffects(forcedSideEffects); // Close effect pickers enchantmentPrimaryPicker.CloseWindow(); enchantmentSecondaryPicker.CloseWindow(); }
/// <summary> /// Restore instanced bundles save data. /// </summary> public void RestoreInstancedBundleSaveData(EffectBundleSaveData_v1[] data) { ClearBundles(); if (data == null || data.Length == 0) { return; } foreach (EffectBundleSaveData_v1 bundleData in data) { InstancedBundle instancedBundle = new InstancedBundle(); instancedBundle.version = bundleData.version; instancedBundle.bundleType = bundleData.bundleType; instancedBundle.targetType = bundleData.targetType; instancedBundle.elementType = bundleData.elementType; instancedBundle.name = bundleData.name; instancedBundle.iconIndex = bundleData.iconIndex; instancedBundle.casterEntityType = bundleData.casterEntityType; instancedBundle.casterLoadID = bundleData.casterLoadID; instancedBundle.liveEffects = new List <IEntityEffect>(); instancedBundle.caster = GetCasterReference(bundleData.casterEntityType, bundleData.casterLoadID); // Resume effects foreach (EffectSaveData_v1 effectData in bundleData.liveEffects) { IEntityEffect effect = GameManager.Instance.EntityEffectBroker.InstantiateEffect(effectData.key, effectData.effectSettings); if (effect == null) { Debug.LogWarningFormat("RestoreInstancedBundleSaveData() could not restore effect as key '{0}' was not found by broker."); continue; } // Resume effect effect.Resume(effectData, this, instancedBundle.caster); effect.RestoreSaveData(effectData.effectSpecific); instancedBundle.liveEffects.Add(effect); } instancedBundles.Add(instancedBundle); } }
EnchantmentSettings[] GetFilteredEnchantments(IEntityEffect effect) { EnchantmentSettings[] filteredEnchantments = null; if (selectingPowers) { filteredEnchantments = enumeratedPowerEnchantments.Where(e => e.EffectKey == effect.Key).ToArray(); if (filteredEnchantments == null || filteredEnchantments.Length == 0) { throw new Exception(string.Format("Found no power enchantments for effect key '{0}'", effect.Key)); } } else { filteredEnchantments = enumeratedSideEffectEnchantments.Where(e => e.EffectKey == effect.Key).ToArray(); if (filteredEnchantments == null || filteredEnchantments.Length == 0) { throw new Exception(string.Format("Found no side-effect enchantments for effect key '{0}'", effect.Key)); } } return(filteredEnchantments); }
/// <summary> /// Generate EffectEntry from classic EffectRecordData. /// </summary> /// <param name="effectRecordData">Classic effect record data.</param> /// <returns>EffectEntry.</returns> public bool ClassicEffectRecordToEffectEntry(SpellRecord.EffectRecordData effectRecordData, out EffectEntry effectEntryOut) { // Get template IEntityEffect effectTemplate = GetEffectTemplateFromClassicEffectRecordData(effectRecordData); if (effectTemplate == null) { effectEntryOut = new EffectEntry(); return(false); } // Get settings and create entry EffectSettings effectSettings = ClassicEffectRecordToEffectSettings( effectRecordData, effectTemplate.Properties.SupportDuration, effectTemplate.Properties.SupportChance, effectTemplate.Properties.SupportMagnitude); effectEntryOut = new EffectEntry(effectTemplate.Key, effectSettings); return(true); }
/// <summary> /// Gets PotionRecipe from IEntityEffect. /// Effect must allow the potion maker crafting station and define potion recipes. /// </summary> /// <param name="effect">Input effect.</param> /// <param name="variant">Variant index, if more than one exists.</param> /// <returns>PotionRecipe if the effect has one, otherwise null.</returns> public PotionRecipe GetEffectPotionRecipe(IEntityEffect effect, int variant = 0) { // Effect must be valid and support potion crafting if (effect != null && effect.PotionProperties.Recipes != null && (effect.Properties.AllowedCraftingStations & MagicCraftingStations.PotionMaker) == MagicCraftingStations.PotionMaker) { // Check variant index does not exceed length of recipes array if (effect.PotionProperties.Recipes.Length - 1 < variant) { return(null); } // Variant index must have a recipe assigned if (!effect.PotionProperties.Recipes[variant].HasRecipe()) { return(null); } return(effect.PotionProperties.Recipes[variant]); } return(null); }