Example #1
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;
        }
Example #2
0
        public override void RunAction()
        {
            //Main.DebugLog($"[ActionDealDamage2] Target:{Target?.Unit?.CharacterName} AC:{Target?.Unit?.Stats?.AC?.ModifiedValue} Flat-AC:{Target?.Unit?.Stats?.AC?.FlatFooted} Touch-AC:{Target?.Unit?.Stats?.AC?.Touch} Caster:{Context?.MaybeCaster?.CharacterName}");
            //Main.DebugLog("Context[0] " + this.Context[AbilityRankType.Default].ToString());
            //AbilityRankType.DamageDice [1]
            //AbilitySharedValue.Damage [0]
            //AbilitySharedValue.Duration [2] only composite
            //for (int i = 0; i < 7; i++)
            //{
            //    Main.DebugLog("AbilitySharedValue:" + Context[(AbilitySharedValue)i].ToString());
            //}
            //for (int i = 0; i < 7; i++)
            //{
            //    Main.DebugLog("AbilityRankType:" + Context[(AbilityRankType)i].ToString());
            //}

            if (this.Target.Unit == null)
            {
                UberDebug.LogError(this, "Invalid target for effect '{0}'", this.GetType().Name);
            }
            else if (this.Context.MaybeCaster == null)
            {
                UberDebug.LogError(this, "Invalid caster for effect '{0}'", this.GetType().Name);
            }
            else
            {
                bool saveSuccess = this.Context.SavingThrow != null && (this.Context.SavingThrow.IsPassed || this.Context.SavingThrow.ImprovedEvasion) && this.HalfIfSaved;
                if (saveSuccess && this.Context.SavingThrow.Evasion && this.Context.SavingThrow.IsPassed)
                {
                    EventBus.RaiseEvent <IUnitEvasionHandler>(h => h.HandleEffectEvaded(this.Target.Unit, this.Context));
                }
                else
                {
                    RuleAttackRoll attackRoll;

                    if (WeaponOverride != null)
                    {
                        attackRoll = new RuleAttackRoll(Context.MaybeCaster, this.Target.Unit, WeaponOverride, 0);
                        if (this.Context[AbilitySharedValue.Heal] == 0)   // if this is the first attack this context
                        {
                            this.Context.TriggerRule(attackRoll);
                            this.Context[AbilitySharedValue.Heal] = attackRoll.Roll;    // save this for other targets
                        }
                        else
                        {
                            //attackRoll.ImmuneToCriticalHit = true; // only the first target may get a crit
                            attackRoll.SuspendCombatLog = true; // don't print, since the roll would be different
                            this.Context.TriggerRule(attackRoll);
                        }

                        int d20 = this.Context[AbilitySharedValue.Heal];    // result of attack roll
                        Main.DebugLog($"Attack:{d20} total:{d20 + attackRoll.AttackBonus} AC:{attackRoll.TargetAC} result:{attackRoll.Result.ToString()}");

                        if (attackRoll.Result == AttackResult.MirrorImage)
                        {
                            // battlelog notification that Mirror Image was hit?
                            attackRoll.ConsumeMirrorImageIfNecessary();
                            return;
                        }

                        if (!this.IsSuccessRoll(d20, attackRoll.AttackBonus, attackRoll.TargetAC))
                        {
                            return;
                        }

                        if (attackRoll.Result == AttackResult.Concealment)
                        {
                            // battlelog notification that concealment prevented hit
                            Kingmaker.Game.Instance.UI.BattleLogManager.LogView.AddLogEntry(attackRoll.AttackLogEntry);
                            return;
                        }
                    }
                    else
                    {
                        attackRoll = ElementsContext.GetData <ContextAttackData>()?.AttackRoll;
                    }

                    ContextActionDealDamage2.DamageInfo info = new ContextActionDealDamage2.DamageInfo()
                    {
                        Dices                  = new DiceFormula(this.Value.DiceCountValue.Calculate(this.Context), this.Value.DiceType),
                        Bonus                  = this.Value.BonusValue.Calculate(this.Context),
                        PreRolledValue         = !this.ReadPreRolledFromSharedValue ? new int?() : new int?(this.Context[this.PreRolledSharedValue]),
                        HalfBecauseSavingThrow = saveSuccess,
                        Empower                = this.Context.HasMetamagic(Metamagic.Empower),
                        Maximize               = this.Context.HasMetamagic(Metamagic.Maximize),
                        CriticalModifier       = this.IgnoreCritical || attackRoll == null || !attackRoll.IsCriticalConfirmed ? new DamageCriticalModifierType?() : new DamageCriticalModifierType?(this.AbilityContext == null ? attackRoll.Weapon.Blueprint.CriticalModifier : DamageCriticalModifierType.X2)
                    };

                    int num;
                    switch (this.M_Type)
                    {
                    case ContextActionDealDamage2.Type.Damage:
                        num = this.DealHitPointsDamage(info);
                        break;

                    case ContextActionDealDamage2.Type.AbilityDamage:
                        num = this.DealAbilityScoreDamage(info);
                        break;

                    case ContextActionDealDamage2.Type.EnergyDrain:
                        num = this.DrainEnergy(info);
                        break;

                    default:
                        throw new ArgumentOutOfRangeException();
                    }
                    if (this.WriteResultToSharedValue)
                    {
                        this.Context[this.ResultSharedValue] = num;
                    }
                    if (!this.WriteCriticalToSharedValue || attackRoll == null || !attackRoll.IsCriticalConfirmed)
                    {
                        return;
                    }
                    this.Context[this.CriticalSharedValue] = 1;
                }
            }
        }