/// <summary> /// Enchantment payload callback for enchantment to perform custom execution based on context. /// These callbacks are performed directly from template, not from a live instance of effect. Do not store state in effect during callbacks. /// Not used by EnchantmentPayloadFlags.Held - rather, an effect instance bundle is assigned to entity's effect manager to execute as normal. /// </summary> public virtual PayloadCallbackResults?EnchantmentPayloadCallback(EnchantmentPayloadFlags context, EnchantmentParam?param = null, DaggerfallEntityBehaviour sourceEntity = null, DaggerfallEntityBehaviour targetEntity = null, DaggerfallUnityItem sourceItem = null, int sourceDamage = 0) { return(null); }
/// <summary> /// Helper to check if properties contain the specified enchantment payload flags /// </summary> /// <param name="flags">Flags to check.</param> /// <returns>True if flags specified.</returns> public virtual bool HasEnchantmentPayloadFlags(EnchantmentPayloadFlags flags) { return((Properties.EnchantmentPayloadFlags & flags) == flags); }
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); } // Do not activate enchantment if broken // But still return durability loss so "item has broken" message displays // If AllowMagicRepairs enabled then item will not disappear if (sourceItem != null && sourceItem.currentCondition <= 0) { return new PayloadCallbackResults() { durabilityLoss = durabilityLossOnUse } } ; // 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 }); }
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 || sourceEntity == null || targetEntity == null || sourceItem == null || sourceDamage == 0) { return(null); } // Target can saves vs magic if (FormulaHelper.SavingThrow(DFCareer.Elements.Magic, DFCareer.EffectFlags.Magic, targetEntity.Entity, 0) == 0) { return(null); } // Find live effect as EnchantmentPayloadCallback is only called on template and we need to change live data // Log error and allow effect to continue - but it will not operate fully MaceOfMolagBalEffect liveEffect = FindLiveEffect(sourceEntity); if (liveEffect == null) { Debug.LogError("MaceOfMolagBalEffect.EnchantmentPayloadCallback could not find live effect instance on source entity."); } // Seed random Random.InitState(Time.frameCount); // "The Mace of Molag Bal drains its victim's spell points and gives them to the bearer. // "If the victim has no spell points, he is drained of strength, which is also transferred to the wielder." // "Using the Mace of Molag Bal can actually give its bearer more spell points or more strength than he would have fully rested." // After considerable testing in classic unable to actually reproduce the first part of this effect (transfer of spell points) // Could be down to casters in classic dumping their spell point pool almost immediately, but even backstabs failed to transfer any spell points to wielder // Implementing spell point drain as per description rather than based on observation in classic // Assuming spell points drained are equal to damage // Testing in classic shows that strength increase is always 1-6 if (targetEntity.Entity.CurrentMagicka > 0) { // First drain spell points from target // Limit drain to available spell points on target int spellPointsDrained = targetEntity.Entity.CurrentMagicka - targetEntity.Entity.DecreaseMagicka(sourceDamage); // Then raise spell points on source equal to amount drained // If this will increase over usual spell point pool amount then increase max to by overflow amount int overflow = sourceEntity.Entity.CurrentMagicka + spellPointsDrained - sourceEntity.Entity.MaxMagicka; if (overflow > 0) { // Immediately set increase to spell point maximum to absorb all spell points drained // This also needs to be set each tick so we accumulate this overflow amount to use in live effect sourceEntity.Entity.ChangeMaxMagickaModifier(overflow); if (liveEffect != null) { liveEffect.currentMaxMagickaIncrease += overflow; } } sourceEntity.Entity.IncreaseMagicka(spellPointsDrained); } else { // If target is out of spell points then drain 1-6 strength from target int strengthDrained = Random.Range(1, 7); DrainTargetStrength(targetEntity, strengthDrained); // Accumulate drain amount as a strength buff in live effect // These modifiers are automatically serialized/deserialized as part of effect framework if (liveEffect != null) { liveEffect.ChangeStatMaxMod(DFCareer.Stats.Strength, strengthDrained); liveEffect.ChangeStatMod(DFCareer.Stats.Strength, strengthDrained); } } // Record last strike time if (liveEffect != null) { liveEffect.lastStrikeTime = DaggerfallUnity.Instance.WorldTime.DaggerfallDateTime.ToClassicDaggerfallTime(); } // Durability loss is equal to damage caused return(new PayloadCallbackResults() { durabilityLoss = sourceDamage, }); }
public override PayloadCallbackResults?EnchantmentPayloadCallback(EnchantmentPayloadFlags context, EnchantmentParam?param = null, DaggerfallEntityBehaviour sourceEntity = null, DaggerfallEntityBehaviour targetEntity = null, DaggerfallUnityItem sourceItem = null, int sourceDamage = 0) { return(base.EnchantmentPayloadCallback(context, param, sourceEntity, targetEntity, sourceItem)); }