public override void RunAction()
        {
            var target    = this.Target.Unit;
            var initiator = this.Context.MaybeCaster;
            var result    = bonus + value.Calculate(this.Context);

            if (!InspectUnitsHelper.IsInspectAllow(target))
            {
                return;
            }

            BlueprintUnit blueprintForInspection = target.Descriptor.BlueprintForInspection;

            InspectUnitsManager.UnitInfo info = Game.Instance.Player.InspectUnitsManager.GetInfo(blueprintForInspection);

            if (info == null)
            {
                return;
            }



            int dc = info.DC;

            Common.AddBattleLogMessage($"{initiator.CharacterName} forced DC {dc} monster lore check: {result}");
            if (info.KnownPartsCount < 4)
            {
                info.SetCheck(result, initiator);
                EventBus.RaiseEvent <IKnowledgeHandler>((Action <IKnowledgeHandler>)(h => h.HandleKnowledgeUpdated(info)));
            }
        }
            public void storeSpell(AbilityData new_spell)
            {
                spell = new_spell;

                Common.AddBattleLogMessage($"{this.Fact.MaybeContext.MaybeOwner.CharacterName} stored {spell.Blueprint.Name} in {this.Fact.Name}.");
                (this.Fact as IFactContextOwner)?.RunActionInContext(this.actions_on_store, this.Owner.Unit);
            }
        public override void RunAction()
        {
            //relevant dominate buffs
            // guid for dominatepersonbuff c0f4e1c24c9cd334ca988ed1bd9d201f
            UnitEntityData unit = GameHelper.GetTargetsAround(this.Target.Point, 1.Feet().Meters * 0.1f, false, false).FirstOrDefault();

            if (unit != null && unit.IsPlayerFaction)
            {
                List <Buff> buffsToRemove = new List <Buff>();
                foreach (Buff buff in unit.Buffs.Enumerable)
                {
                    //UnitEntityData entity = buff.MaybeContext?.MaybeCaster;
                    //if(entity !=null)
                    //{
                    //    Common.AddBattleLogMessage($"{buff.Name} has caster {entity.CharacterName}");
                    //}
                    if (buff.Blueprint.Name == "Domination" && buff.MaybeContext?.MaybeCaster == this.Context.MaybeCaster)
                    {
                        buffsToRemove.Add(buff);
                    }
                }
                if (buffsToRemove.Count > 0)
                {
                    ChangeFaction fcf = new ChangeFaction();
                    //fcf.Fact.MaybeContext?.MaybeCaster
                    buffsToRemove[0].Remove();
                    Common.AddBattleLogMessage($"{unit.CharacterName} released from domination");
                    return;
                }
            }

            base.RunAction();
        }
Пример #4
0
        public bool canBeAttackedBy(UnitEntityData unit)
        {
            if (can_attack.Contains(unit))
            {
                return(true);
            }
            if (can_not_attack.Contains(unit))
            {
                return(false);
            }
            var spell_descriptor = this.Buff.Blueprint.GetComponent <SpellDescriptorComponent>();

            if (spell_descriptor != null &&
                (UnitDescriptionHelper.GetDescription(unit.Blueprint).Immunities.SpellDescriptorImmunity.Value & spell_descriptor.Descriptor.Value) != 0)
            {
                Common.AddBattleLogMessage($"{unit.CharacterName} is immune to {this.Fact.Name} of {Owner.CharacterName}");
                can_not_attack.Add(unit);
                return(false);
            }
            RuleSavingThrow ruleSavingThrow = this.Context.TriggerRule <RuleSavingThrow>(new RuleSavingThrow(unit, save_type, this.Context.Params.DC));

            if (ruleSavingThrow.IsPassed)
            {
                can_attack.Add(unit);
                Common.AddBattleLogMessage($"{unit.CharacterName} successfuly overcomes {this.Fact.Name} of {Owner.CharacterName}");
                return(true);
            }
            else
            {
                Common.AddBattleLogMessage($"{unit.CharacterName} fails to overcome {this.Fact.Name} of {Owner.CharacterName}");
                can_not_attack.Add(unit);
                return(false);
            }
        }
        public override void RunAction()
        {
            var target    = this.Target.Unit;
            var initiator = this.Context.MaybeCaster;
            var result    = bonus + initiator.Descriptor.Progression.GetClassLevel(character_class) + initiator.Descriptor.Stats.GetStat <ModifiableValueAttributeStat>(stat_type).Bonus;

            if (!InspectUnitsHelper.IsInspectAllow(target))
            {
                return;
            }

            BlueprintUnit blueprintForInspection = target.Descriptor.BlueprintForInspection;

            InspectUnitsManager.UnitInfo info = Game.Instance.Player.InspectUnitsManager.GetInfo(blueprintForInspection);

            if (info == null)
            {
                return;
            }

            if (info.KnownPartsCount == 4)
            {
                return;
            }

            int dc = info.DC;

            Common.AddBattleLogMessage($"{initiator.CharacterName} forced DC {dc} monster lore check: {result}");
            info.SetCheck(result, initiator);
        }
Пример #6
0
        public override void RunAction()
        {
            if (required_spell_features.Empty())
            {
                var unit = GameHelper.GetTargetsAround(this.Target.Point, 1.Feet().Meters * 0.1f, false, false).FirstOrDefault();

                if (unit != null)
                {
                    var summoner = unit.Get <UnitPartSummonedMonster>()?.Summoner;
                    if (summoner == this.Context.MaybeCaster)
                    {
                        unit.Descriptor.RemoveFact(Game.Instance.BlueprintRoot.SystemMechanics.SummonedUnitBuff);
                    }
                    return;
                }
            }


            var area = Game.Instance.State.AreaEffects.Where(a => a.Context.SourceAbility != null && a.Context.MaybeCaster == this.Context.MaybeCaster &&
                                                             ((a.Context.AssociatedBlueprint as BlueprintBuff) == null) &&
                                                             Helpers.GetField <TimeSpan?>(a, "m_Duration").HasValue &&
                                                             a.View?.Shape != null && a.View.Shape.Contains(this.Target.Point, 0.0f) &&
                                                             checkFeature(a.Context.SourceAbility)).FirstOrDefault();

            if (area != null)
            {
                Common.AddBattleLogMessage($"Dismissed {area.Context.SourceAbility.Name} area effect");
                area.ForceEnd();
            }
        }
            public void ruleSavingThrowTriggered(RuleSavingThrow evt)
            {
                var context = evt.Reason?.Context;

                if (context == null)
                {
                    return;
                }

                var caster = context.MaybeCaster;

                if (caster == null)
                {
                    return;
                }

                if (caster != this.Owner.Unit)
                {
                    return;
                }

                if (context.SpellSchool == school &&
                    (save_type == SavingThrowType.Unknown || evt.Type == save_type))
                {
                    var cl_check = RulebookEvent.Dice.D(new DiceFormula(1, DiceType.D20)) + evt.Reason.Context.Params.CasterLevel;
                    if (cl_check > evt.DifficultyClass)
                    {
                        Common.AddBattleLogMessage("Changing spell DC for " + evt.Initiator.CharacterName + $" form {evt.DifficultyClass} to {cl_check} due to {this.Fact.Name}");
                        Helpers.SetField(evt, "DifficultyClass", cl_check);
                    }
                }
            }
        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);
        }
Пример #9
0
 public override void RunAction()
 {
     if (this.Target.Unit == null || this.Context.MaybeCaster == null)
     {
         UberDebug.LogError((object)"Target unit is missing", (object[])Array.Empty <object>());
     }
     else
     {
         int value = this.Target.Unit.Ensure <UnitPartSeedStorage>().getRandom(1, 100);
         if (this.Target.Unit.IsInCombat && in_combat_bonus != null)
         {
             value += in_combat_bonus.Calculate(this.Context);
         }
         //Main.logger.Log("Rolled: " + value.ToString());
         Common.AddBattleLogMessage(this.Target.Unit.CharacterName + " rolls " + value.ToString() + " on d100 for " + this.Context.Name);
         for (int i = 0; i < actions.Length; i++)
         {
             if (thresholds[i] >= value)
             {
                 if (actions[i] != null)
                 {
                     actions[i].Run();
                 }
                 return;
             }
         }
     }
 }
        public override void RunAction()
        {
            var target    = this.Target.Unit;
            var initiator = this.Context.MaybeCaster;

            if (!InspectUnitsHelper.IsInspectAllow(target))
            {
                return;
            }


            BlueprintUnit blueprintForInspection = target.Descriptor.BlueprintForInspection;

            InspectUnitsManager.UnitInfo info = Game.Instance.Player.InspectUnitsManager.GetInfo(blueprintForInspection);
            StatType statType = !(bool)((UnityEngine.Object)info.Blueprint.Type) ? StatType.SkillLoreNature : info.Blueprint.Type.KnowledgeStat;


            if (info == null)
            {
                return;
            }

            ModifiableValueSkill stat = initiator.Stats.GetStat <ModifiableValueSkill>(statType);
            int?nullable1;
            int?nullable2;

            if (stat == null)
            {
                nullable1 = new int?();
                nullable2 = nullable1;
            }
            else
            {
                nullable2 = new int?(stat.BaseValue);
            }
            nullable1 = nullable2;

            int dc    = info.DC;
            int bonus = value.Calculate(this.Context);

            if ((!nullable1.HasValue ? 0 : nullable1.Value) > 0 || (bool)initiator.Descriptor.State.Features.MakeKnowledgeCheckUntrained)
            {
                var skill_check = new RuleSkillCheck(initiator, statType, dc);
                skill_check.AddTemporaryModifier(initiator.Stats.GetStat(statType).AddModifier(bonus, null, descriptor));
                skill_check.IgnoreDifficultyBonusToDC = true;
                int rollResult = Rulebook.Trigger <RuleSkillCheck>(skill_check).RollResult;
                Common.AddBattleLogMessage($"{initiator.CharacterName} DC {dc} monster lore check: {rollResult}");

                if (dc <= rollResult && action_on_success != null)
                {
                    action_on_success.Run();
                }
                if (info.KnownPartsCount < 4)
                {
                    info.SetCheck(rollResult, initiator);
                    EventBus.RaiseEvent <IKnowledgeHandler>((Action <IKnowledgeHandler>)(h => h.HandleKnowledgeUpdated(info)));
                }
            }
        }
 public void releaseSpellOnTarget(TargetWrapper target)
 {
     if (spell != null && (spell.CanTarget(target) || ignore_target_checkers))
     {
         Rulebook.Trigger <RuleCastSpell>(new RuleCastSpell(spell, target));
         Common.AddBattleLogMessage($"{this.Owner.CharacterName} released {spell.Blueprint.Name} from {this.Fact.Name}.");
         spell = null;
     }
 }
Пример #12
0
        static public bool makeDisbeliefSave(MechanicsContext context, UnitEntityData target)
        {
            disbelief_save_in_progress = true;
            Common.AddBattleLogMessage(target.CharacterName + " attempts a disbelief saving throw");
            RuleSavingThrow ruleSavingThrow = context.TriggerRule <RuleSavingThrow>(new RuleSavingThrow(target, SavingThrowType.Will, context.Params.DC));
            bool            res             = ruleSavingThrow.IsPassed;

            disbelief_save_in_progress = false;
            return(res);
        }
Пример #13
0
 public void HandleUnitMakeOffensiveAction(UnitEntityData target)
 {
     if (offensive_action_effect == OffensiveActionEffect.REMOVE_FROM_OWNER)
     {
         this.Buff.Remove();
     }
     else if (offensive_action_effect == OffensiveActionEffect.REMOVE_FROM_TARGET && !can_attack.Contains(target))
     {
         can_attack.Add(target);
         can_not_attack.Remove(target);
         Common.AddBattleLogMessage($"{Owner.CharacterName} invalidates {this.Fact.Name} against {target.CharacterName}");
     }
 }
Пример #14
0
        public override void RunAction()
        {
            var area = Game.Instance.State.AreaEffects.Where(a => a.Context.SourceAbility != null && a.Context.MaybeCaster == this.Context.MaybeCaster &&
                                                             ((a.Context.AssociatedBlueprint as BlueprintBuff) == null) &&
                                                             Helpers.GetField <TimeSpan?>(a, "m_Duration").HasValue &&
                                                             a.View?.Shape != null && a.View.Shape.Contains(this.Target.Point, 0.0f)).FirstOrDefault();

            if (area != null)
            {
                Common.AddBattleLogMessage($"Dismissed {area.Context.SourceAbility.Name} area effect");
                area.ForceEnd();
            }
        }
Пример #15
0
            static public bool Prefix(ContextActionKnockdownTarget __instance)
            {
                var context = ElementsContext.GetData <MechanicsContext.Data>()?.Context;

                if (context == null)
                {
                    return(true);
                }
                if (context?.AssociatedBlueprint is BlueprintBuff)
                {
                    return(true);
                }

                var unit = ElementsContext.GetData <MechanicsContext.Data>()?.CurrentTarget?.Unit;

                if (unit == null)
                {
                    return(true);
                }
                context = ShadowSpells.extractMainContext(context, context?.MaybeCaster);
                if (context == null)
                {
                    return(true);
                }
                if (!unit.Ensure <UnitPartDisbelief>().attemptedDisbelief(context))
                {
                    if (unit.Descriptor.State.HasCondition(UnitCondition.TrueSeeing))
                    {
                        unit.Ensure <UnitPartDisbelief>().register(context, true);
                    }
                    else
                    {
                        unit.Ensure <UnitPartDisbelief>().register(context, ShadowSpells.makeDisbeliefSave(context, unit));
                    }
                }

                if (unit.Ensure <UnitPartDisbelief>().disbelieved(context))
                {
                    int illusion_reality = ShadowSpells.getSpellReality(context);
                    int result           = RulebookEvent.Dice.D(new DiceFormula(1, DiceType.D100));
                    if (illusion_reality > 0 && result > illusion_reality)
                    {
                        Common.AddBattleLogMessage(unit.CharacterName + " avoids " + context.SourceAbility.Name
                                                   + $" effect due to disbelief (rolled {result} vs {illusion_reality}%)");
                        return(false);
                    }
                }

                return(true);
            }
Пример #16
0
        public void ruleSavingThrowTriggered(RuleSavingThrow evt)
        {
            var context = evt.Reason?.Context;

            if (context == null)
            {
                return;
            }

            var caster = context.MaybeCaster;

            if (caster == null)
            {
                return;
            }

            if (caster != this.Owner.Unit)
            {
                return;
            }

            if (context?.SourceAbility.GetComponent <DisbeliefSpell>() == null)
            {
                context = ShadowSpells.extractMainContext(context, caster);
                if (context == null)
                {
                    return;
                }

                if (!ShadowSpells.is_making_disbelief_save)
                {
                    return;
                }
            }


            if (context.SpellSchool == school &&
                (save_type == SavingThrowType.Unknown || evt.Type == save_type) &&
                (context?.SourceAbility.GetComponent <DisbeliefSpell>() != null || !evt.Initiator.Ensure <UnitPartDisbelief>().attemptedDisbelief(context))
                )
            {
                var cl_check = RulebookEvent.Dice.D(new DiceFormula(1, DiceType.D20)) + evt.Reason.Context.Params.CasterLevel;
                if (cl_check > evt.DifficultyClass)
                {
                    Common.AddBattleLogMessage("Changing spell DC for " + evt.Initiator.CharacterName + $" form {evt.DifficultyClass} to {cl_check} due to {this.Fact.Name}");
                    Helpers.SetField(evt, "DifficultyClass", cl_check);
                }
            }
        }
 public void releaseSpellOnTarget(TargetWrapper target)
 {
     if (spell != null && (spell.CanTarget(target) || ignore_target_checkers))
     {
         var rule_cast_spell = new RuleCastSpell(spell, target);
         rule_cast_spell.Context.AttackRoll = Rulebook.CurrentContext.AllEvents.LastOfType <RuleAttackWithWeapon>()?.AttackRoll;
         if (always_hit)
         {
             rule_cast_spell.Context.ForceAlwaysHit = true;
         }
         Rulebook.Trigger <RuleCastSpell>(rule_cast_spell);
         Common.AddBattleLogMessage($"{this.Owner.CharacterName} released {spell.Blueprint.Name} from {this.Fact.Name}.");
         spell = null;
     }
 }
Пример #18
0
        static bool Prefix(RuleRollD20 __instance, ref int?___m_PreRolledResult, ref int __result)
        {
            int?preRolledResult = ___m_PreRolledResult;
            int val1            = !preRolledResult.HasValue ? RulebookEvent.Dice.D20 : preRolledResult.Value;

            for (int rerollsAmount = __instance.RerollsAmount; rerollsAmount > 0; --rerollsAmount)
            {
                int old_value = val1;
                int new_value = RulebookEvent.Dice.D20;
                val1 = !__instance.TakeBest ? Math.Min(val1, new_value) : Math.Max(val1, new_value);
                Common.AddBattleLogMessage(__instance.Initiator.CharacterName + " rerolls: " + $"({old_value}  >>  {new_value}, retains {(__instance.TakeBest ? "best" : "worst")})");
            }
            __result = val1;
            return(false);
        }
Пример #19
0
        static bool Prefix(RuleRollD20 __instance, ref int?___m_PreRolledResult, ref int __result)
        {
            int?preRolledResult = ___m_PreRolledResult;
            int val1            = !preRolledResult.HasValue ? RulebookEvent.Dice.D20 : preRolledResult.Value;

            int rerollsAmount = __instance.RerollsAmount;

            if (__instance.TakeBest && rerollsAmount > 0 && (__instance.Initiator.Get <ExtraTakeBestRerollUnitPart>()?.active()).GetValueOrDefault())
            {
                rerollsAmount++;
            }


            if (!__instance.TakeBest && rerollsAmount > 0 && (__instance.Initiator.Get <IgnoreTakeWorstRerollsUnitPart>()?.active()).GetValueOrDefault())
            {
                rerollsAmount = 0;
            }

            List <int> rerolls_history = new List <int>()
            {
                val1
            };

            for (; rerollsAmount > 0; --rerollsAmount)
            {
                int old_value = val1;
                int new_value = RulebookEvent.Dice.D20;
                rerolls_history.Add(new_value);
                val1 = !__instance.TakeBest ? Math.Min(val1, new_value) : Math.Max(val1, new_value);
                Common.AddBattleLogMessage(__instance.Initiator.CharacterName + " rerolls: " + $"({old_value}  >>  {new_value}, retains {(__instance.TakeBest ? "best" : "worst")})");
            }

            if (!__instance.TakeBest && rerolls_history.Count > 1 && (__instance.Initiator.Get <ExtraGoodRerollOnTakeWorstUnitPart>()?.active()).GetValueOrDefault())
            {
                int old_value = val1;
                int new_value = RulebookEvent.Dice.D20;
                rerolls_history.Add(new_value);
                rerolls_history.Sort();
                int retained_value = rerolls_history[1];
                val1 = retained_value;
                Common.AddBattleLogMessage(__instance.Initiator.CharacterName + " rerolls: " + $"({old_value}  >>  {new_value}, retains {retained_value})");
            }


            __result = val1;
            return(false);
        }
Пример #20
0
        public override void RunAction()
        {
            var areas = Game.Instance.State.AreaEffects;
            var units = GameHelper.GetTargetsAround(this.Target.Point, 1.Feet() * .1f, false, false);

            foreach (UnitEntityData entity in units)
            {
                if (entity.Descriptor.HasFact(Game.Instance.BlueprintRoot.SystemMechanics.SummonedUnitBuff))
                {
                    Common.AddBattleLogMessage($"{entity.CharacterName} dismissed");
                    entity.Descriptor.RemoveFact(Game.Instance.BlueprintRoot.SystemMechanics.SummonedUnitBuff);
                }
                List <Buff> buffsToRemove = new List <Buff>();
                foreach (Buff b in entity.Buffs.Enumerable)
                {
                    if (b.IsFromSpell && !b.IsNotDispelable)
                    {
                        buffsToRemove.Add(b);
                    }
                }
                foreach (Buff b in buffsToRemove)
                {
                    Common.AddBattleLogMessage($"Dispelled {b.Name} from {entity.CharacterName}");
                    b.Remove();
                }
                foreach (AreaEffectEntityData area in areas)
                {
                    if (area.Context.SourceAbility != null &&
                        area.Context.SourceAbility.IsSpell &&
                        (area.Context.AssociatedBlueprint as BlueprintBuff == null) &&
                        Helpers.GetField <TimeSpan?>(area, "m_Duration").HasValue &&
                        area.View?.Shape != null &&
                        area.View.Shape.Contains(entity.Position, 0.0f)
                        )
                    {
                        if (!area.IsEnded)
                        {
                            Common.AddBattleLogMessage($"Disjunctive energy has fractured the magic of {area.Context.SourceAbility.Name}");
                        }
                        area.ForceEnd();
                        //area.ForceEnd();
                    }
                }
            }
        }
Пример #21
0
            static public bool Prefix(RuleHealDamage __instance, RulebookEventContext context)
            {
                if (__instance.Target == null)
                {
                    return(true);
                }

                var context2 = __instance.Reason.Context;

                if (context2?.AssociatedBlueprint != null && context2.AssociatedBlueprint is BlueprintBuff)
                {//do not apply shadow twice
                    return(true);
                }
                context2 = ShadowSpells.extractMainContext(context2, __instance.Initiator);
                if (context2 == null)
                {
                    return(true);
                }

                if (!__instance.Target.Ensure <UnitPartDisbelief>().attemptedDisbelief(context2))
                {
                    if (__instance.Target.Descriptor.State.HasCondition(UnitCondition.TrueSeeing))
                    {
                        __instance.Target.Ensure <UnitPartDisbelief>().register(context2, true);
                    }
                    else
                    {
                        __instance.Target.Ensure <UnitPartDisbelief>().register(context2, ShadowSpells.makeDisbeliefSave(context2, __instance.Target));
                    }
                }

                if (__instance.Target.Ensure <UnitPartDisbelief>().disbelieved(context2))
                {
                    int illusion_reality = ShadowSpells.getSpellReality(context2);

                    if (illusion_reality > 0)
                    {
                        __instance.Modifier = new float?((__instance.Modifier.HasValue ? __instance.Modifier.GetValueOrDefault() : 1f) * 0.01f * illusion_reality);
                        Common.AddBattleLogMessage(__instance.Target.CharacterName + " reduces healing from "
                                                   + context2.SourceAbility.Name + " to " + illusion_reality.ToString() + "% due to disbelief");
                    }
                }
                return(true);
            }
Пример #22
0
            static public bool Prefix(AreaEffectPit __instance, MechanicsContext context, AreaEffectEntityData areaEffect, UnitEntityData unit)
            {
                var source_context = context?.SourceAbilityContext;
                var context2       = ShadowSpells.extractMainContext(source_context, source_context?.MaybeCaster);

                if (context2 == null)
                {
                    return(true);
                }

                if (!unit.Ensure <UnitPartDisbelief>().attemptedDisbelief(context2))
                {
                    if (unit.Descriptor.State.HasCondition(UnitCondition.TrueSeeing))
                    {
                        unit.Ensure <UnitPartDisbelief>().register(context2, true);
                    }
                    else
                    {
                        unit.Ensure <UnitPartDisbelief>().register(context2, ShadowSpells.makeDisbeliefSave(context2, unit));
                    }
                }

                if (unit.Ensure <UnitPartDisbelief>().disbelieved(context2))
                {
                    int illusion_reality = ShadowSpells.getSpellReality(context2);
                    int result           = RulebookEvent.Dice.D(new DiceFormula(1, DiceType.D100));
                    if (illusion_reality > 0 && result > illusion_reality)
                    {
                        Common.AddBattleLogMessage(unit.CharacterName + " avoids " + context2.SourceAbility.Name
                                                   + $" effect due to disbelief (rolled {result} vs {illusion_reality}%)");
                        return(false);
                    }
                }

                return(true);
            }
Пример #23
0
            static public bool Prefix(RuleApplyBuff __instance, RulebookEventContext context)
            {
                /*if (ShadowSpells.isShadowBuff(__instance.Blueprint))
                 * {
                 *  return true;
                 * }*/
                var rule_summon = Rulebook.CurrentContext.AllEvents.LastOfType <RuleSummonUnit>();

                if (rule_summon != null)
                {//do not interrupt summon buffs
                    return(true);
                }

                var context2 = __instance.Reason.Context;
                //there are also actions after summon that should not be affected
                //we need to check if we are still inside SpawnMonsterComponent
                var summon_context = __instance.Initiator.Buffs?.GetBuff(Game.Instance.BlueprintRoot.SystemMechanics.SummonedUnitBuff)?.MaybeContext?.ParentContext;

                if (summon_context == context2)
                {
                    return(true);
                }


                if (context2?.AssociatedBlueprint != null && context2.AssociatedBlueprint is BlueprintBuff)
                {//do not apply shadow twice
                    return(true);
                }
                var summoned_context = ShadowSpells.getShadowBuff(__instance.Initiator.Descriptor)?.MaybeContext;

                if (context2 == null && summoned_context == null)
                {
                    return(true);
                }


                var shadow_descriptor2 = (context2?.SpellDescriptor).GetValueOrDefault() & (SpellDescriptor)AdditionalSpellDescriptors.ExtraSpellDescriptor.Shadow;
                var shadow_summon      = (summoned_context?.SpellDescriptor).GetValueOrDefault() & (SpellDescriptor)AdditionalSpellDescriptors.ExtraSpellDescriptor.Shadow;

                if (shadow_summon == SpellDescriptor.None && shadow_descriptor2 == SpellDescriptor.None)
                {
                    return(true);
                }


                if (shadow_summon > shadow_descriptor2)
                {
                    context2 = summoned_context;
                }

                if (__instance.Initiator == null)
                {
                    return(true);
                }

                if (!__instance.Initiator.Ensure <UnitPartDisbelief>().disbelief_contexts.ContainsKey(context2))
                {
                    RuleSavingThrow ruleSavingThrow = context2.TriggerRule <RuleSavingThrow>(new RuleSavingThrow(__instance.Initiator, SavingThrowType.Will, context2.Params.DC));
                    __instance.Initiator.Ensure <UnitPartDisbelief>().disbelief_contexts[context2] = ruleSavingThrow.IsPassed;
                }

                if (__instance.Initiator.Ensure <UnitPartDisbelief>().disbelief_contexts[context2])
                {
                    if ((context2.SpellDescriptor & (SpellDescriptor)AdditionalSpellDescriptors.ExtraSpellDescriptor.Shadow) == (SpellDescriptor)AdditionalSpellDescriptors.ExtraSpellDescriptor.Shadow20)
                    {
                        if (RulebookEvent.Dice.D(new DiceFormula(1, DiceType.D100)) > 20)
                        {
                            __instance.CanApply = false;
                            Common.AddBattleLogMessage(__instance.Initiator.CharacterName + " avoids " + context2.SourceAbility.Name + " effect due to disbelief");
                            return(false);
                        }
                    }
                    else if ((context2.SpellDescriptor & (SpellDescriptor)AdditionalSpellDescriptors.ExtraSpellDescriptor.Shadow) == (SpellDescriptor)AdditionalSpellDescriptors.ExtraSpellDescriptor.Shadow60)
                    {
                        if (RulebookEvent.Dice.D(new DiceFormula(1, DiceType.D100)) > 60)
                        {
                            __instance.CanApply = false;
                            Common.AddBattleLogMessage(__instance.Initiator.CharacterName + " avoids " + context2.SourceAbility.Name + " effect due to disbelief");
                            return(false);
                        }
                    }
                    else if ((context2.SpellDescriptor & (SpellDescriptor)AdditionalSpellDescriptors.ExtraSpellDescriptor.Shadow) == (SpellDescriptor)AdditionalSpellDescriptors.ExtraSpellDescriptor.Shadow80)
                    {
                        if (RulebookEvent.Dice.D(new DiceFormula(1, DiceType.D100)) > 80)
                        {
                            __instance.CanApply = false;
                            Common.AddBattleLogMessage(__instance.Initiator.CharacterName + " avoids " + context2.SourceAbility.Name + " effect due to disbelief");
                            return(false);
                        }
                    }
                }

                return(true);
            }
Пример #24
0
            static public bool Prefix(RuleApplyBuff __instance, RulebookEventContext context)
            {
                if (__instance.Blueprint?.GetComponent <IgnoreShadowReality>() != null)
                {
                    return(true);
                }
                var rule_summon = Rulebook.CurrentContext.AllEvents.LastOfType <RuleSummonUnit>();

                if (rule_summon != null)
                {//do not interrupt summon buffs
                    return(true);
                }

                var context2 = __instance.Reason.Context;
                //there are also actions after summon that should not be affected
                //we need to check if we are still inside SpawnMonsterComponent
                var summon_context = __instance.Initiator.Buffs?.GetBuff(Game.Instance.BlueprintRoot.SystemMechanics.SummonedUnitBuff)?.MaybeContext?.ParentContext;

                if (summon_context == context2)
                {
                    return(true);
                }

                if (context2?.AssociatedBlueprint != null && context2.AssociatedBlueprint is BlueprintBuff)
                {//do not apply shadow twice
                    return(true);
                }

                context2 = ShadowSpells.extractMainContext(context2, context2?.MaybeCaster);
                if (context2 == null)
                {
                    return(true);
                }

                if (__instance.Initiator == null)
                {
                    return(true);
                }

                if (!__instance.Initiator.Ensure <UnitPartDisbelief>().attemptedDisbelief(context2))
                {
                    if (__instance.Initiator.Descriptor.State.HasCondition(UnitCondition.TrueSeeing))
                    {
                        __instance.Initiator.Ensure <UnitPartDisbelief>().register(context2, true);
                    }
                    else
                    {
                        __instance.Initiator.Ensure <UnitPartDisbelief>().register(context2, ShadowSpells.makeDisbeliefSave(context2, __instance.Initiator));
                    }
                }

                if (__instance.Initiator.Ensure <UnitPartDisbelief>().disbelieved(context2))
                {
                    int illusion_reality = ShadowSpells.getSpellReality(context2);
                    int result           = RulebookEvent.Dice.D(new DiceFormula(1, DiceType.D100));
                    if (illusion_reality > 0 && result > illusion_reality)
                    {
                        __instance.CanApply = false;
                        Common.AddBattleLogMessage(__instance.Initiator.CharacterName + " avoids " + context2.SourceAbility.Name
                                                   + $" effect due to disbelief (rolled {result} vs {illusion_reality}%)");
                        return(false);
                    }
                }

                return(true);
            }
        public override void RunAction()
        {
            UnitEntityData caster = this.Context.MaybeCaster;

            if (caster == null)
            {
                UberDebug.LogError((UnityEngine.Object) this, (object)"Caster is missing", (object[])Array.Empty <object>());
            }
            var unit = this.Target.Unit;

            if (unit == null || !unit.Descriptor.State.IsDead || unit.Descriptor.State.HasCondition(UnitCondition.Petrified))
            {
                return;
            }

            Rounds duration = this.DurationValue.Calculate(this.Context);

            int level   = Math.Max(Math.Min(getRacialHD(this.Target.Unit.Descriptor), 20), Blueprint.GetComponent <AddClassLevels>().Levels);
            int max_lvl = this.Context.Params.CasterLevel * hd_cl_multiplier * (this.Context.MaybeCaster.Descriptor.HasFact(ChannelEnergyEngine.desecrate_buff) ? 2 : 1);

            if (level > max_lvl)
            {
                Common.AddBattleLogMessage($"{unit.CharacterName} corpse HD ({level}) is beyond {caster.CharacterName}'s capacity to animate ({max_lvl}).");
                return;
            }

            //Main.logger.Log("Animate Dead: Remaining HD limit: " + getUsedHD(this.Context, SummonPool).ToString() + "/" + (this.Context.Params.CasterLevel * max_hd_cl_multiplier).ToString());
            int max_total_hd           = this.Context.Params.CasterLevel * max_hd_cl_multiplier;
            var unit_part_max_hd_bonus = this.Context.MaybeCaster?.Get <UnitPartIncreaseMaxUndeadHD>();

            if (unit_part_max_hd_bonus != null)
            {
                max_total_hd += unit_part_max_hd_bonus.getBonus();
            }
            int used_hd      = getUsedHD(this.Context, SummonPool);
            int remaining_hd = max_total_hd - used_hd;

            if (level > remaining_hd)
            {
                Common.AddBattleLogMessage($"{unit.CharacterName} corpse HD ({level}) does not fit into {caster.CharacterName}'s animate dead HD limit ({remaining_hd}/{max_total_hd})");
                return;
            }
            Vector3        clampedPosition = ObstacleAnalyzer.GetNearestNode(this.Target.Point).clampedPosition;
            UnitEntityView unitEntityView  = this.Blueprint.Prefab.Load(false);

            var target_size = unit.Descriptor.OriginalSize;

            float radius = !((UnityEngine.Object)unitEntityView != (UnityEngine.Object)null) ? 0.5f : unitEntityView.Corpulence;

            FreePlaceSelector.PlaceSpawnPlaces(1, radius, clampedPosition);

            Vector3        relaxedPosition = FreePlaceSelector.GetRelaxedPosition(0, true);
            UnitEntityData animated_unit   = this.Context.TriggerRule <RuleSummonUnit>(new RuleSummonUnit(caster, this.Blueprint, relaxedPosition, duration, 0)
            {
                Context           = this.Context,
                DoNotLinkToCaster = this.do_not_link_to_caster
            }).SummonedUnit;

            if (this.SummonPool != null)
            {
                GameHelper.RegisterUnitInSummonPool(this.SummonPool, animated_unit);
            }

            var level_up_component = animated_unit.Blueprint.GetComponent <AddClassLevels>();

            int current_level = level_up_component.Levels;

            animated_unit.Stats.Strength.BaseValue  = unit.Stats.Strength.BaseValue + str_bonus;
            animated_unit.Stats.Dexterity.BaseValue = unit.Stats.Dexterity.BaseValue + dex_bonus;

            if (adapt_size)
            {
                animated_unit.Descriptor.AddFact(Common.size_override_facts[target_size], null, null);
            }

            if (current_level < level)
            {
                level_up_component.LevelUp(animated_unit.Descriptor, level - current_level);
            }

            if (transfer_equipment && unit.Body.HandsAreEnabled)
            {
                List <ItemSlot> list1 = unit.Body.EquipmentSlots.ToList <ItemSlot>();
                List <ItemSlot> list2 = animated_unit.Body.EquipmentSlots.ToList <ItemSlot>();
                for (int index = 0; index < list1.Count && index < list2.Count; ++index)
                {
                    ItemEntity maybeItem = list1[index].MaybeItem;
                    if (maybeItem != null)
                    {
                        animated_unit.Body.TryInsertItem(maybeItem.Blueprint, list2[index]);
                    }
                }
                animated_unit.Body.CurrentHandEquipmentSetIndex = unit.Body.CurrentHandEquipmentSetIndex;
            }
            animated_unit.Descriptor.State.AddCondition(UnitCondition.Unlootable, (Kingmaker.UnitLogic.Buffs.Buff)null);


            using (this.Context.GetDataScope(animated_unit))
            {
                this.AfterSpawn.Run();
            }

            unit.Descriptor.AddFact(Common.no_animate_feature);

            animated_unit.Descriptor.CustomName = "Animated " + unit.Descriptor.CharacterName + $" ({level} HD)";
            EventBus.RaiseEvent <IUnitNameHandler>((Action <IUnitNameHandler>)(h => h.OnUnitNameChanged(animated_unit)));
        }
        public override void RunAction()
        {
            UnitEntityData caster = this.Context.MaybeCaster;

            if (caster == null)
            {
                UberDebug.LogError((UnityEngine.Object) this, (object)"Caster is missing", (object[])Array.Empty <object>());
            }
            var unit = this.Target.Unit;

            if (unit == null || !unit.Descriptor.State.IsDead || unit.Descriptor.State.HasCondition(UnitCondition.Petrified))
            {
                return;
            }

            var total_units = getUsedUnits(this.Context, this.SummonPool);

            if (total_units >= max_units.Calculate(this.Context))
            {
                Common.AddBattleLogMessage($"{caster.CharacterName} can not animate more corpses.");
                return;
            }

            Rounds duration = this.DurationValue.Calculate(this.Context);

            int level = hd.Calculate(this.Context);

            Vector3        clampedPosition = ObstacleAnalyzer.GetNearestNode(this.Target.Point).clampedPosition;
            UnitEntityView unitEntityView  = this.Blueprint.Prefab.Load(false);

            var target_size = unit.Descriptor.OriginalSize;

            float radius = !((UnityEngine.Object)unitEntityView != (UnityEngine.Object)null) ? 0.5f : unitEntityView.Corpulence;

            FreePlaceSelector.PlaceSpawnPlaces(1, radius, clampedPosition);

            Vector3        relaxedPosition = FreePlaceSelector.GetRelaxedPosition(0, true);
            UnitEntityData animated_unit   = this.Context.TriggerRule <RuleSummonUnit>(new RuleSummonUnit(caster, this.Blueprint, relaxedPosition, duration, 0)
            {
                Context           = this.Context,
                DoNotLinkToCaster = this.do_not_link_to_caster
            }).SummonedUnit;

            if (this.SummonPool != null)
            {
                GameHelper.RegisterUnitInSummonPool(this.SummonPool, animated_unit);
            }

            var level_up_component = animated_unit.Blueprint.GetComponent <AddClassLevels>();

            int current_level = level_up_component.Levels;

            animated_unit.Stats.Strength.BaseValue  = unit.Stats.Strength.BaseValue + str_bonus;
            animated_unit.Stats.Dexterity.BaseValue = unit.Stats.Dexterity.BaseValue + dex_bonus;

            if (adapt_size)
            {
                animated_unit.Descriptor.AddFact(Common.size_override_facts[target_size], null, null);
            }

            if (current_level < level)
            {
                level_up_component.LevelUp(animated_unit.Descriptor, level - current_level);
            }

            if (transfer_equipment && unit.Body.HandsAreEnabled)
            {
                List <ItemSlot> list1 = unit.Body.EquipmentSlots.ToList <ItemSlot>();
                List <ItemSlot> list2 = animated_unit.Body.EquipmentSlots.ToList <ItemSlot>();
                for (int index = 0; index < list1.Count && index < list2.Count; ++index)
                {
                    ItemEntity maybeItem = list1[index].MaybeItem;
                    if (maybeItem != null)
                    {
                        animated_unit.Body.TryInsertItem(maybeItem.Blueprint, list2[index]);
                    }
                }
                animated_unit.Body.CurrentHandEquipmentSetIndex = unit.Body.CurrentHandEquipmentSetIndex;
            }
            animated_unit.Descriptor.State.AddCondition(UnitCondition.Unlootable, (Kingmaker.UnitLogic.Buffs.Buff)null);


            using (this.Context.GetDataScope(animated_unit))
            {
                this.AfterSpawn.Run();
            }

            unit.Descriptor.AddFact(Common.no_animate_feature);

            animated_unit.Descriptor.CustomName = "Animated " + unit.Descriptor.CharacterName + $" ({level} HD)";
            EventBus.RaiseEvent <IUnitNameHandler>((Action <IUnitNameHandler>)(h => h.OnUnitNameChanged(animated_unit)));
        }
Пример #27
0
            static public bool Prefix(RuleApplyBuff __instance, RulebookEventContext context)
            {
                if (ShadowSpells.isShadowBuff(__instance.Blueprint))
                {
                    return(true);
                }
                var context2 = __instance.Reason.Context;

                if (context2?.AssociatedBlueprint != null && context2.AssociatedBlueprint is BlueprintBuff)
                {//do not apply shadow twice
                    return(true);
                }
                var summoned_context = ShadowSpells.getShadowBuff(__instance.Initiator.Descriptor)?.MaybeContext;

                if (context2 == null && summoned_context == null)
                {
                    return(true);
                }


                var shadow_descriptor2 = (context2?.SpellDescriptor).GetValueOrDefault() & (SpellDescriptor)AdditionalSpellDescriptors.ExtraSpellDescriptor.Shadow;
                var shadow_summon      = (summoned_context?.SpellDescriptor).GetValueOrDefault() & (SpellDescriptor)AdditionalSpellDescriptors.ExtraSpellDescriptor.Shadow;

                if (shadow_summon == SpellDescriptor.None && shadow_descriptor2 == SpellDescriptor.None)
                {
                    return(true);
                }


                if (shadow_summon > shadow_descriptor2)
                {
                    context2 = summoned_context;
                }

                if (__instance.Initiator == null)
                {
                    return(true);
                }

                if (!__instance.Initiator.Ensure <UnitPartDisbelief>().disbelief_contexts.ContainsKey(context2))
                {
                    RuleSavingThrow ruleSavingThrow = context2.TriggerRule <RuleSavingThrow>(new RuleSavingThrow(__instance.Initiator, SavingThrowType.Will, context2.Params.DC));
                    __instance.Initiator.Ensure <UnitPartDisbelief>().disbelief_contexts[context2] = ruleSavingThrow.IsPassed;
                }

                if (__instance.Initiator.Ensure <UnitPartDisbelief>().disbelief_contexts[context2])
                {
                    if ((context2.SpellDescriptor & (SpellDescriptor)AdditionalSpellDescriptors.ExtraSpellDescriptor.Shadow) == (SpellDescriptor)AdditionalSpellDescriptors.ExtraSpellDescriptor.Shadow20)
                    {
                        if (RulebookEvent.Dice.D(new DiceFormula(1, DiceType.D100)) > 20)
                        {
                            __instance.CanApply = false;
                            Common.AddBattleLogMessage(__instance.Initiator.CharacterName + " avoids " + context2.SourceAbility.Name + " effect due to disbelief");
                            return(false);
                        }
                    }
                    else if ((context2.SpellDescriptor & (SpellDescriptor)AdditionalSpellDescriptors.ExtraSpellDescriptor.Shadow) == (SpellDescriptor)AdditionalSpellDescriptors.ExtraSpellDescriptor.Shadow60)
                    {
                        if (RulebookEvent.Dice.D(new DiceFormula(1, DiceType.D100)) > 60)
                        {
                            __instance.CanApply = false;
                            Common.AddBattleLogMessage(__instance.Initiator.CharacterName + " avoids " + context2.SourceAbility.Name + " effect due to disbelief");
                            return(false);
                        }
                    }
                    else if ((context2.SpellDescriptor & (SpellDescriptor)AdditionalSpellDescriptors.ExtraSpellDescriptor.Shadow) == (SpellDescriptor)AdditionalSpellDescriptors.ExtraSpellDescriptor.Shadow80)
                    {
                        if (RulebookEvent.Dice.D(new DiceFormula(1, DiceType.D100)) > 80)
                        {
                            __instance.CanApply = false;
                            Common.AddBattleLogMessage(__instance.Initiator.CharacterName + " avoids " + context2.SourceAbility.Name + " effect due to disbelief");
                            return(false);
                        }
                    }
                }

                return(true);
            }