/// <summary> /// Generate EffectSettings from classic EffectRecordData. /// </summary> /// <param name="effectRecordData">Classic effect record data.</param> /// <returns>EffectSettings.</returns> public EffectSettings ClassicEffectRecordToEffectSettings(SpellRecord.EffectRecordData effectRecordData, bool supportDuration, bool supportChance, bool supportMagnitude) { EffectSettings effectSettings = BaseEntityEffect.DefaultEffectSettings(); if (supportDuration) { effectSettings.DurationBase = effectRecordData.durationBase; effectSettings.DurationPlus = effectRecordData.durationMod; effectSettings.DurationPerLevel = effectRecordData.durationPerLevel; } if (supportChance) { effectSettings.ChanceBase = effectRecordData.chanceBase; effectSettings.ChancePlus = effectRecordData.chanceMod; effectSettings.ChancePerLevel = effectRecordData.chancePerLevel; } if (supportMagnitude) { effectSettings.MagnitudeBaseMin = effectRecordData.magnitudeBaseLow; effectSettings.MagnitudeBaseMax = effectRecordData.magnitudeBaseHigh; effectSettings.MagnitudePlusMin = effectRecordData.magnitudeLevelBase; effectSettings.MagnitudePlusMax = effectRecordData.magnitudeLevelHigh; effectSettings.MagnitudePerLevel = effectRecordData.magnitudePerLevel; } return(effectSettings); }
void IndexEffectRecipes(BaseEntityEffect effect) { // Must have at least one recipe int recipeCount = GetEffectPotionRecipeCount(effect); if (recipeCount == 0) { return; } Debug.LogFormat("Effect '{0}' has {1} potion recipes:", effect.Key, recipeCount); // Index all recipes for this effect for (int i = 0; i < recipeCount; i++) { // Get recipe variant PotionRecipe recipe = GetEffectPotionRecipe(effect, i); if (recipe != null) { // Add potion effect or log error if collision int recipeKey = recipe.GetHashCode(); if (!potionEffectTemplates.ContainsKey(recipeKey)) { potionEffectTemplates.Add(recipeKey, effect); Debug.LogFormat("'{0}' recipe {1} [key={2}] ingredients: {3}", effect.Key, i, recipeKey, recipe.ToString()); } else { Debug.LogErrorFormat("EnityEffectBroker: Already contains potion recipe key {0} for ingredients: {1}", recipeKey, recipe.ToString()); } } } }
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); } } }
/// <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); }
void Start() { // Create a dictionary of classic spells RebuildClassicSpellsDict(); // Enumerate classes implementing an effect and create an instance to use as factory // TODO: Provide an external method for mods to register custom effects without reflections magicEffectTemplates.Clear(); IEnumerable <BaseEntityEffect> effectTemplates = ReflectiveEnumerator.GetEnumerableOfType <BaseEntityEffect>(); foreach (BaseEntityEffect effect in effectTemplates) { // Effect must present a key if (string.IsNullOrEmpty(effect.Key)) { continue; } // Store template // TODO: Allow effect overwrite for modded effects if (effect.VariantCount > 1) { // Store one template per variant for multi-effects for (int i = 0; i < effect.VariantCount; i++) { BaseEntityEffect variantEffect = CloneEffect(effect) as BaseEntityEffect; variantEffect.CurrentVariant = i; magicEffectTemplates.Add(variantEffect.Key, variantEffect); IndexEffectRecipes(variantEffect); } } else { // Just store singleton effect magicEffectTemplates.Add(effect.Key, effect); IndexEffectRecipes(effect); } // Map classic key when defined - output error in case of classic key conflict // NOTE: Mods should also be able to replace classic effect - will need to handle substitutions later // NOTE: Not mapping effect keys for non spell effects at this time byte groupIndex, subGroupIndex; BaseEntityEffect.ClassicEffectFamily family; 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); } } } }
/// <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); }
/// <summary> /// Register new effect template with broker. /// Also maps classic key and potion recipes defined by effect. /// </summary> /// <param name="effect">New effect to register.</param> /// <param name="allowReplacement">Allow replacement of existing effect with this key.</param> /// <returns>True if successful.</returns> public bool RegisterEffectTemplate(BaseEntityEffect effect, bool allowReplacement = false) { // Template cannot be null or have a null or empty key if (effect == null || string.IsNullOrEmpty(effect.Key)) { Debug.LogError("RegisterEffect: Either template is null or has a null or empty key value."); return(false); } // Check for existing template with this key if (magicEffectTemplates.ContainsKey(effect.Key)) { if (allowReplacement) { magicEffectTemplates.Remove(effect.Key); } else { Debug.LogErrorFormat("RegisterEffect: Template key '{0}' already exists. Use allowReplacement=true to replace this effect.", effect.Key); return(false); } } // Register effect template if (effect.VariantCount > 1) { // Store one template per variant for multi-effects for (int i = 0; i < effect.VariantCount; i++) { BaseEntityEffect variantEffect = CloneEffect(effect) as BaseEntityEffect; variantEffect.CurrentVariant = i; magicEffectTemplates.Add(variantEffect.Key, variantEffect); IndexEffectRecipes(variantEffect); MapClassicKey(variantEffect, allowReplacement); } } else { // Just store singleton effect magicEffectTemplates.Add(effect.Key, effect); IndexEffectRecipes(effect); MapClassicKey(effect, allowReplacement); } return(true); }
/// <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); return(GameManager.Instance.EntityEffectBroker.GetEffectTemplate(classicKey)); }
/// <summary> /// Default constructor. /// </summary> public PotionRecipe() { Settings = BaseEntityEffect.DefaultEffectSettings(); }
public EntityEffectMacroDataSource(BaseEntityEffect parent) { this.parent = parent; }