public override bool isImmune(AbilityExecutionContext context)
        {
            if (context_checked.Contains(context))
            {
                return(true);
            }
            var ability = context?.Ability;

            if (ability == null || !ability.Blueprint.IsSpell || ability.SpellLevel == 0)
            {
                return(false);
            }

            if (remaining_levels <= 0)
            {
                return(false);
            }

            remaining_levels -= context.SpellLevel;
            context_checked.Add(context);
            if (remaining_levels <= 0)
            {
                remaining_levels = 0;
                (this.Fact as Buff)?.Remove();
            }
            Common.AddBattleLogMessage(this.Owner.CharacterName + "\'s " + this.Fact.Name + $" can absorb {remaining_levels} more spell levels");
            return(true);
        }
示例#2
0
        public override IEnumerator <AbilityDeliveryTarget> Deliver(AbilityExecutionContext context, TargetWrapper target)
        {
            UnitEntityData caster = context.MaybeCaster;

            if (caster == null)
            {
                UberDebug.LogError("Caster is missing", Array.Empty <object>());
                yield break;
            }

            RulebookEventContext rulebookContext      = context.RulebookContext;
            RuleAttackWithWeapon attackWithWeapon     = (rulebookContext != null) ? rulebookContext.AllEvents.LastOfType <RuleAttackWithWeapon>() : null;
            RuleAttackWithWeapon ruleAttackWithWeapon = attackWithWeapon;
            RuleAttackRoll       attackRoll           = (ruleAttackWithWeapon != null) ? ruleAttackWithWeapon.AttackRoll : null;

            attackRoll = (attackRoll ?? context.TriggerRule <RuleAttackRoll>(new RuleAttackRoll(caster, target.Unit, caster.GetFirstWeapon(), 0)));
            if (attackWithWeapon == null)
            {
                attackRoll.ConsumeMirrorImageIfNecessary();
            }
            yield return(new AbilityDeliveryTarget(target)
            {
                AttackRoll = attackRoll
            });

            yield break;
        }
示例#3
0
 //static public Dictionary<(MechanicsContext, UnitEntityData), bool> spell_target_map = new Dictionary<(MechanicsContext, UnitEntityData), bool>();
 static bool Prefix(OffensiveActionsController __instance, AbilityExecutionContext context, TargetWrapper target)
 {
     if (context?.SourceAbility?.GetComponent <NonOffensiveAbility>() != null)
     {
         return(false);
     }
     return(true);
 }
            private void storeSpell(SpellSlot spell_slot, AbilityExecutionContext context)
            {
                var spell = getSpellOrVariant(spell_slot.Spell);

                FactStoreSpell.storeSpell(context.MaybeOwner.Descriptor, fact, spell);
                spendSpellSlot(spell_slot);
                spell.SpendMaterialComponent();
            }
            private void applySpell(SpellSlot spell_slot, AbilityExecutionContext context, TargetWrapper target)
            {
                var spell = getSpellOrVariant(spell_slot.Spell);

                spendSpellSlot(spell_slot);
                spell.SpendMaterialComponent();
                Rulebook.Trigger <RuleCastSpell>(new RuleCastSpell(spell, target));
            }
示例#6
0
 static bool Prefix(AbilityExecutionContext context, TargetWrapper targetWrapper, ref IEnumerator <AbilityDeliveryTarget> __result)
 {
     if (IsEnabled())
     {
         __result = Deliver(context, targetWrapper);
         return(false);
     }
     return(true);
 }
示例#7
0
 static bool Prefix(AbilityExecutionContext context, TargetWrapper target)
 {
     if (Mod.Enabled && FixDweomerLeap)
     {
         UnitEntityData caster;
         return(target.Unit != null && (caster = context.MaybeCaster) != null && target.Unit.CanAttack(caster));
     }
     return(true);
 }
 internal static bool Prefix(AbilityExecutionContext context, TargetWrapper target)
 {
     try {
         return(!target.IsUnit || context.TriggerRule(new RuleSpellTargetCheck(context, target.Unit)).CanTargetUnit);
     }
     catch (Exception e) {
         Log.Error(e);
     }
     return(true);
 }
            private void applySpell(SpellSlot spell_slot, AbilityExecutionContext context, TargetWrapper target)
            {
                var spell = getSpellOrVariant(spell_slot.Spell);

                spendSpellSlot(spell_slot);
                spell.SpendMaterialComponent();
                var rule_cast_spell = new RuleCastSpell(spell, target);

                rule_cast_spell.Context.AttackRoll = Rulebook.CurrentContext.AllEvents.LastOfType <RuleAttackWithWeapon>()?.AttackRoll;
                Rulebook.Trigger <RuleCastSpell>(rule_cast_spell);
            }
        public override bool isImmune(AbilityExecutionContext context)
        {
            var ability = context?.Ability;

            if (ability == null || !ability.Blueprint.IsSpell || ability.SpellLevel == 0)
            {
                return(false);
            }

            return(ability.SpellLevel <= max_spell_level.Calculate(this.Fact.MaybeContext));
        }
示例#11
0
            public void OnEventDidTrigger(RuleCastSpell evt)
            {
                AbilityExecutionContext context = evt.Context;

                context.RemoveSpellDescriptor(SpellDescriptor.Fire);
                context.RemoveSpellDescriptor(SpellDescriptor.Cold);
                context.RemoveSpellDescriptor(SpellDescriptor.Acid);
                context.RemoveSpellDescriptor(SpellDescriptor.Electricity);
                context.AddSpellDescriptor(ChangeSpellElementalDamage.ElementToSpellDescriptor(this.Element));
                //context.Recalculate();
            }
        public bool isImmune(AbilityExecutionContext context)
        {
            foreach (var b in buffs.ToArray())
            {
                bool res = false;
                b.CallComponents <ISpellInvulnerability>(i => res = i.isImmune(context));

                if (res)
                {
                    return(true);
                }
            }
            return(false);
        }
 public override void Apply(AbilityExecutionContext context, TargetWrapper target)
 {
     if (context.Ability.ParamSpellSlot == null || context.Ability.ParamSpellSlot.Spell == (AbilityData)null)
     {
         return;
     }
     else if (context.Ability.ParamSpellSlot.Spell.Spellbook == null)
     {
         return;
     }
     else
     {
         applySpell(context.Ability.ParamSpellSlot, context, target);
     }
 }
示例#14
0
        public void HandleUnitJoinCombat(UnitEntityData unit)
        {
            //Main.logger.Log($"Unit joining combat: {unit.CharacterName}");
            var autoCastAbilities = unit.Brain.Actions.Where(action => action.Blueprint.name.StartsWith("SLE_PRECAST"));

            foreach (var autoCast in autoCastAbilities)
            {
                var spellCast   = autoCast.Blueprint as BlueprintAiCastSpell;
                var spellbook   = unit.Descriptor.Spellbooks.First();
                var abilityData = new AbilityData(spellCast.Ability, unit.Descriptor, unit.Descriptor.Spellbooks.First().Blueprint);
                //Main.logger.Log($"auto casting buff '{spellCast.Ability.name} at level {abilityData.CalculateParams().SpellLevel}' on combat join");
                //Main.logger.Log($"spellbook pre-cast: {spellbook.GetAvailableForCastSpellCount(abilityData)}");
                var proc = new AbilityExecutionContext(abilityData, abilityData.CalculateParams(), new Kingmaker.Utility.TargetWrapper(unit));
                AbilityExecutionProcess.ApplyEffectImmediate(proc, unit);
                abilityData.SpendFromSpellbook();
                //Main.logger.Log($"spellbook post-cast: {spellbook.GetAvailableForCastSpellCount(abilityData)}");
            }
        }
            public override void Apply(AbilityExecutionContext context, TargetWrapper target)
            {
                if (context.Ability.ParamSpellSlot == null || context.Ability.ParamSpellSlot.Spell == (AbilityData)null)
                {
                    return;
                }
                else if (context.Ability.ParamSpellSlot.Spell.Spellbook == null)
                {
                    return;
                }
                else
                {
                    storeSpell(context.Ability.ParamSpellSlot, context);

                    if (actions != null)
                    {
                        using (context.GetDataScope(target))
                            actions.Run();
                    }
                }
            }
示例#16
0
        public override void Apply(AbilityExecutionContext context, TargetWrapper target)
        {
            UnitDescriptor unit  = context.MaybeOwner.Descriptor;
            AbilityData    spell = context.Ability.ParamSpellSlot.Spell;
            ItemEntity     item  = spell.SourceItem;
            BlueprintItemEquipmentUsable blueprintItm = spell.SourceItemUsableBlueprint;
            int spellLevel = blueprintItm.SpellLevel;

            unit.Resources.Restore(ArcaneReservoir.resource, spellLevel / 2);
            if (blueprintItm.Type == UsableItemType.Wand)
            {
                for (int i = 1; i <= 5; i++)
                {
                    item.SpendCharges(unit);
                }
            }
            else
            {
                item.SpendCharges(unit);
            }
        }
        public IEnumerable <TargetWrapper> mod_Select(AbilityExecutionContext context, TargetWrapper anchor)
        {
            if (!KingmakerPatchSettings.Cheats.NoFriendlyFireAOE)
            {
                return(this.source_Select(context, anchor));
            }

            UnitEntityData caster = context.MaybeCaster;

            IEnumerable <UnitEntityData> targets = GameHelper.GetTargetsAround(anchor.Point, this.AoERadius, true, this.alias_m_IncludeDead);

            if (caster == null)
            {
                UberDebug.LogError("Caster is missing");
                return(Enumerable.Empty <TargetWrapper>());
            }

            switch (this.alias_m_TargetType)
            {
            case TargetType.Enemy:
                targets = targets.Where(caster.IsEnemy);
                break;

            case TargetType.Ally:
                targets = targets.Where(caster.IsAlly);
                break;
            }

            if (this.alias_m_Condition.HasConditions)
            {
                targets = targets.Where(u => this.HasConditions(context, u)).ToList();
            }

            if (caster.IsPlayerFaction && context.AbilityBlueprint.EffectOnEnemy == AbilityEffectOnUnit.Harmful)
            {
                targets = targets.Where(target => !target.IsPlayerFaction);
            }

            return(targets.Select(target => new TargetWrapper(target)));
        }
示例#18
0
        static bool Prefix(TouchSpellsController __instance, AbilityExecutionContext context)
        {
            UnitEntityData maybeCaster = context.MaybeCaster;

            if (maybeCaster == null)
            {
                return(false);
            }
            UnitPartTouch unitPartTouch = maybeCaster.Get <UnitPartTouch>();

            if (!(bool)(unitPartTouch) || (unitPartTouch.Ability.Data != context.Ability))
            {
                return(false);
            }

            var charges_part = maybeCaster.Get <UnitPartTouchMultipleCharges>();

            if (charges_part != null && charges_part.hasCharges())
            {
                charges_part.consume();
                if (!charges_part.hasCharges())
                {
                    maybeCaster.Remove <UnitPartTouch>();
                }
            }
            else
            {
                maybeCaster.Remove <UnitPartTouch>();
            }
            if (maybeCaster.IsAutoUseAbility(context.Ability))
            {
                return(false);
            }
            maybeCaster.CombatState.ManualTarget = null;
            return(false);
        }
示例#19
0
        internal static bool Prefix(AbilityExecutionContext context, TargetWrapper target)
        {
            if (!target.IsUnit)
            {
                return(true);
            }
            if (context?.Params == null || context.MaybeCaster == null)
            {
                return(true);
            }

            if (!(target.Unit.Get <UnitPartSaveAgainstHarmlessSpells>()?.active()).GetValueOrDefault())
            {
                return(true);
            }

            if (target.Unit == context.MaybeCaster || !target.Unit.IsAlly(context.MaybeCaster))
            {
                return(true);
            }

            if (context.AbilityBlueprint?.GetComponent <HarmlessSpell>() == null || !context.AbilityBlueprint.IsSpell)
            {
                return(true);
            }

            RuleSavingThrow ruleSavingThrow = new RuleSavingThrow(target.Unit, context.AbilityBlueprint.GetComponent <HarmlessSpell>().save_type, context.Params.DC);

            ruleSavingThrow.Reason = (RuleReason)((MechanicsContext)context);
            if (context.TriggerRule <RuleSavingThrow>(ruleSavingThrow).IsPassed)
            {
                return(false);
            }

            return(true);
        }
        public override void Apply(AbilityExecutionContext context, TargetWrapper target)
        {
            UnitDescriptor unit       = context.MaybeOwner.Descriptor;
            AbilityData    spell      = context.Ability.ParamSpellSlot.Spell;
            Spellbook      spellbook  = context.Ability.ParamSpellbook;
            int            spellLevel = context.Ability.ParamSpellLevel.Value;

            if (spellLevel < 1 || spellLevel > spellbook.MaxSpellLevel)
            {
                return;
            }
            foreach (var slot in spellbook.GetMemorizedSpells(spellLevel))
            {
                if (slot.Spell == spell)
                {
                    spellbook.ForgetMemorized(slot);
                }
            }
            unit.AddBuff(flagBuff, unit.Unit);
            UnityModManager.Logger.Log("Rua1?");
            FastStudy.RefreshSubAbls(spellbook, spellLevel);
            UnityModManager.Logger.Log("Rua1?>");
            FastStudy.AddMasterAbls(unit);
        }
示例#21
0
            public static IEnumerator <AbilityDeliveryTarget> Deliver(AbilityExecutionContext context, TargetWrapper targetWrapper)
            {
                UnitEntityData target = targetWrapper.Unit;

                if (target == null)
                {
                    UberDebug.LogError("Target unit is missing");
                    yield break;
                }

                UnitEntityData caster = context.Caster;

                if (caster.GetThreatHand() == null)
                {
                    UberDebug.LogError("Invalid caster's weapon");
                    yield break;
                }

                UnitMovementAgent agentASP = caster.View.AgentASP;

                caster.View.StopMoving();
                agentASP.IsCharging = true;
                agentASP.ForcePath(new ForcedPath(new List <Vector3> {
                    caster.Position, target.Position
                }));
                caster.Descriptor.State.IsCharging = true;
                caster.Descriptor.AddBuff(BlueprintRoot.Instance.SystemMechanics.ChargeBuff, context, 1.Rounds().Seconds);
                UnitAttack unitAttack = new UnitAttack(target);

                unitAttack.Init(caster);

                float timeSinceStart = 0f;

                while (unitAttack.ShouldUnitApproach)
                {
                    timeSinceStart += Game.Instance.TimeController.GameDeltaTime;
                    if (timeSinceStart > 6f)
                    {
                        UberDebug.Log("Charge: timeSinceStart > 6f");
                        yield break;
                    }
                    else if (caster.GetThreatHand() == null)
                    {
                        UberDebug.Log("Charge: caster.GetThreatHand() == null");
                        yield break;
                    }
                    else if (!caster.Descriptor.State.CanMove)
                    {
                        UberDebug.Log("Charge: !caster.Descriptor.State.CanMove");
                        yield break;
                    }
                    else if (!(bool)agentASP)
                    {
                        UberDebug.Log("Charge: !(bool)caster.View.AgentASP");
                        yield break;
                    }
                    else if (!agentASP.IsReallyMoving)
                    {
                        agentASP.ForcePath(new ForcedPath(new List <Vector3> {
                            caster.Position, target.Position
                        }));
                        if (!agentASP.IsReallyMoving)
                        {
                            UberDebug.Log("Charge: !caster.View.AgentASP.IsReallyMoving");
                            yield break;
                        }
                    }

                    agentASP.MaxSpeedOverride = Math.Max(agentASP.MaxSpeedOverride ?? 0f, caster.CombatSpeedMps * 2f);
                    yield return(null);
                }

                caster.View.StopMoving();
                unitAttack.IgnoreCooldown(null);
                unitAttack.IsCharge = true;
                caster.Commands.AddToQueueFirst(unitAttack);
            }
示例#22
0
        public override IEnumerator <AbilityDeliveryTarget> Deliver(AbilityExecutionContext context, TargetWrapper target)
        {
            UnitEntityData caster = context.MaybeCaster;
            bool           flag   = caster == null;

            if (flag)
            {
                UberDebug.LogError(this, "Caster is missing", Array.Empty <object>());
                yield break;
            }
            WeaponSlot threatHand = caster.GetThreatHand();
            bool       flag2      = threatHand == null;

            if (flag2)
            {
                UberDebug.LogError("Caster can't attack", Array.Empty <object>());
                yield break;
            }
            UnitEntityData targetUnit = target.Unit;
            bool           flag3      = targetUnit == null;

            if (flag3)
            {
                UberDebug.LogError("Can't be applied to point", Array.Empty <object>());
                yield break;
            }
            int attackPenalty = 0;

            AbilityEffectCoupDeGrace.EventHandlers handlers = new AbilityEffectCoupDeGrace.EventHandlers();
            handlers.Add(new AbilityEffectCoupDeGrace.Coup(caster));
            RuleAttackWithWeapon rule = new RuleAttackWithWeapon(caster, targetUnit, threatHand.Weapon, attackPenalty)
            {
                AutoHit = true,
                AutoCriticalConfirmation = true,
                AutoCriticalThreat       = true
            };

            using (handlers.Activate())
            {
                context.TriggerRule <RuleAttackWithWeapon>(rule);
            }
            AbilityEffectCoupDeGrace.EventHandlers eventHandlers = null;
            yield return(new AbilityDeliveryTarget(target));

            RuleSavingThrow rule3 = new RuleSavingThrow(targetUnit, SavingThrowType.Fortitude, AbilityEffectCoupDeGrace.m_coupDamage + 10);

            context.TriggerRule <RuleSavingThrow>(rule3);
            bool flag6 = !rule3.IsPassed;

            if (flag6)
            {
                targetUnit.Descriptor.State.MarkedForDeath = true;
            }
            using (context.GetDataScope(target))
            {
                this.Actions.Run();
            }
            ElementsContextData elementsContextData = null;

            rule3 = null;
            yield break;
        }
示例#23
0
 public override void Cleanup(AbilityExecutionContext context)
 {
 }
示例#24
0
        public override IEnumerator <AbilityDeliveryTarget> Deliver(AbilityExecutionContext context, TargetWrapper target)
        {
            if (target.Unit == null)
            {
                UberDebug.LogError("Target unit is missing", Array.Empty <object>());
                yield break;
            }
            UnitAttack cmd = new UnitAttack(target.Unit)
            {
                IsSingleAttack = true
            };

            cmd.Init(context.Caster);
            cmd.Start();
            AttackHandInfo   attackHandInfo = cmd.AllAttacks.FirstOrDefault <AttackHandInfo>();
            ItemEntityWeapon weapon         = (attackHandInfo != null) ? attackHandInfo.Weapon : null;

            if (weapon == null)
            {
                UberDebug.LogError("Has no weapon for attack", Array.Empty <object>());
                cmd.Interrupt();
                yield break;
            }
            bool hitHandled = false;
            bool isMelee    = weapon.Blueprint.IsMelee;

            for (; ;)
            {
                if (cmd.IsFinished)
                {
                    RuleAttackWithWeapon lastAttackRule = cmd.LastAttackRule;
                    if (((lastAttackRule != null) ? lastAttackRule.Projectile : null) == null || cmd.LastAttackRule.Projectile.IsHit || cmd.LastAttackRule.Projectile.Cleared || cmd.LastAttackRule.Projectile.Destroyed)
                    {
                        break;
                    }
                }
                bool wasActed = cmd.IsActed;
                if (!cmd.IsFinished)
                {
                    cmd.Tick();
                }
                RuleAttackWithWeapon lastAttackRule2 = cmd.LastAttackRule;
                if (!wasActed && cmd.IsActed && isMelee)
                {
                    hitHandled = true;
                    if (lastAttackRule2.AttackRoll.IsHit)
                    {
                        yield return(new AbilityDeliveryTarget(target));
                    }
                }
                yield return(null);
            }
            if (!hitHandled && !isMelee)
            {
                RuleAttackWithWeapon lastAttackRule3 = cmd.LastAttackRule;
                bool?flag3 = (lastAttackRule3 != null) ? new bool?(lastAttackRule3.AttackRoll.IsHit) : null;
                if (flag3 != null && flag3.Value)
                {
                    yield return(new AbilityDeliveryTarget(target));
                }
            }
            yield break;
        }
 public override void Apply(AbilityExecutionContext context, TargetWrapper target)
 {
 }
示例#26
0
            public static void Postfix(ref IEnumerable <TargetWrapper> __result, AbilityTargetsAround __instance, ConditionsChecker ___m_Condition, AbilityExecutionContext context, TargetWrapper anchor)
            {
                if (settings.toggleNoFriendlyFireForAOE)
                {
                    UnitEntityData caster = context.MaybeCaster;
                    IEnumerable <UnitEntityData> targets = GameHelper.GetTargetsAround(anchor.Point, __instance.AoERadius);
                    if (caster == null)
                    {
                        __result = Enumerable.Empty <TargetWrapper>();
                        return;
                    }
                    switch (__instance.TargetType)
                    {
                    case TargetType.Enemy:
                        targets = targets.Where(caster.IsEnemy);
                        break;

                    case TargetType.Ally:
                        targets = targets.Where(caster.IsAlly);
                        break;

                    default:
                        throw new ArgumentOutOfRangeException();

                    case TargetType.Any:
                        break;
                    }
                    if (___m_Condition.HasConditions)
                    {
                        targets = targets.Where(u => { using (context.GetDataScope(u)) { return(___m_Condition.Check()); } }).ToList();
                    }
                    if (caster.IsPlayerFaction && ((context.AbilityBlueprint.EffectOnAlly == AbilityEffectOnUnit.Harmful) || (context.AbilityBlueprint.EffectOnEnemy == AbilityEffectOnUnit.Harmful)))
                    {
                        if (context.AbilityBlueprint.HasLogic <AbilityUseOnRest>())
                        {
                            AbilityUseOnRestType componentType = context.AbilityBlueprint.GetComponent <AbilityUseOnRest>().Type;
                            //bool healDamage = componentType == AbilityUseOnRestType.HealDamage || componentType == AbilityUseOnRestType.HealDamage;
                            bool healDamage = componentType == AbilityUseOnRestType.HealDamage;
                            targets = targets.Where(target => {
                                if (target.IsPlayerFaction && !healDamage)
                                {
                                    bool forUndead = componentType == AbilityUseOnRestType.HealMassUndead || componentType == AbilityUseOnRestType.HealSelfUndead || componentType == AbilityUseOnRestType.HealUndead;
                                    return(forUndead == target.Descriptor.IsUndead);
                                }
                                return(true);
                            });
                        }
                        else
                        {
                            targets = targets.Where(target => !target.IsPlayerFaction);
                        }
                    }
                    __result = targets.Select(target => new TargetWrapper(target));
                }
            }
 public override IEnumerable <TargetWrapper> Select(AbilityExecutionContext context, TargetWrapper anchor)
 {
     Log.Write($"FakeTargetsAround: anchor at {anchor}");
     return(new TargetWrapper[] { TargetCaster?context.Caster : anchor });
 }
 public IEnumerable <TargetWrapper> source_Select(AbilityExecutionContext context, TargetWrapper anchor)
 {
     throw new DeadEndException("source_Select");
 }
示例#29
0
 static bool Prefix(AbilityExecutionContext context) => AbilityEffectRunAction_Apply_Patch.Prefix(context, context.MainTarget);
示例#30
0
        static void Postfix(UnitPartTouch __instance, BlueprintAbility ability, AbilityData source, AbilityExecutionContext context)
        {
            var multiple_charges = source.Blueprint.GetComponent <AbilityEffectStickyTouchMultiple>();

            if (multiple_charges != null)
            {
                int charges = multiple_charges.num_charges.Calculate(context);
                __instance.Owner.Ensure <UnitPartTouchMultipleCharges>().init(charges);
            }
        }