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            blueprint       = unit.Blueprint;
            Rounds         duration        = this.DurationValue.Calculate(this.Context);
            Vector3        clampedPosition = ObstacleAnalyzer.GetNearestNode(this.Target.Point).clampedPosition;
            UnitEntityView unitEntityView  = 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, 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.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);
        }
        public override void RunAction()
        {
            UnitEntityData maybeCaster = this.Context.MaybeCaster;

            if (maybeCaster == null)
            {
                UberDebug.LogError((UnityEngine.Object) this, (object)"Caster is missing", (object[])Array.Empty <object>());
            }
            else
            {
                Rounds         duration        = this.DurationValue.Calculate(this.Context);
                int            count           = this.CountValue.Calculate(this.Context);
                int            level           = this.LevelValue.Calculate(this.Context);
                Vector3        clampedPosition = ObstacleAnalyzer.GetNearestNode(this.Target.Point).clampedPosition;
                UnitEntityView unitEntityView  = this.Blueprint.Prefab.Load(false);
                float          radius          = (UnityEngine.Object)unitEntityView != (UnityEngine.Object)null ? unitEntityView.Corpulence : 0.5f;
                FreePlaceSelector.PlaceSpawnPlaces(count, radius, clampedPosition);
                for (int index = 0; index < count; ++index)
                {
                    Vector3        relaxedPosition = FreePlaceSelector.GetRelaxedPosition(index, true);
                    UnitEntityData summonedUnit    = this.Context.TriggerRule <RuleSummonUnit>(new RuleSummonUnit(maybeCaster, this.Blueprint, relaxedPosition, duration, level)
                    {
                        Context           = this.Context,
                        DoNotLinkToCaster = this.DoNotLinkToCaster
                    }).SummonedUnit;
                    var weapon = getWeapon();
                    if (weapon != null)
                    {
                        ItemsCollection.DoWithoutEvents((Action)(() => summonedUnit.Body.PrimaryHand.InsertItem(weapon.CreateEntity())));
                    }

                    if (attack_mark_buff != null)
                    {
                        summonedUnit.Ensure <UnitPartSpiritualWeaponTargetMark>().buff = attack_mark_buff;
                    }
                    if ((UnityEngine.Object) this.SummonPool != (UnityEngine.Object)null)
                    {
                        GameHelper.RegisterUnitInSummonPool(this.SummonPool, summonedUnit);
                    }
                    using (this.Context.GetDataScope((TargetWrapper)summonedUnit))
                        this.AfterSpawn.Run();

                    summonedUnit.Descriptor.CustomName = custom_name;
                    EventBus.RaiseEvent <IUnitNameHandler>((Action <IUnitNameHandler>)(h => h.OnUnitNameChanged(summonedUnit)));
                }
            }
        }
        public override void RunAction()
        {
            UnitEntityData maybeCaster = base.Context.MaybeCaster;

            if (maybeCaster == null)
            {
                UberDebug.LogError(this, "Caster is missing", Array.Empty <object>());
                return;
            }
            Vector3 vector = base.Target.Point;

            vector += new Vector3(-3, 0, -2);
            vector  = ObstacleAnalyzer.GetNearestNode(vector).clampedPosition;
            UnitEntityView unitEntityView = this.Blueprint.Prefab.Load(false);
            float          radius         = (unitEntityView != null) ? unitEntityView.Corpulence : 0.5f;

            FreePlaceSelector.PlaceSpawnPlaces(3, radius, vector);
            Game.Instance.EntityCreator.SpawnUnit(this.Blueprint, vector, Quaternion.identity, maybeCaster.HoldingState);
        }
        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)));
        }
Esempio n. 6
0
        internal static void HealMagic()
        {
            // code copied from RestController.UseSpells()
            foreach (UnitEntityData unitEntityData in Game.Instance.Player.PartyCharacters)
            {
                if (unitEntityData.Descriptor.State.IsFinallyDead)
                {
                    if (unitEntityData.Descriptor.State.ResurrectOnRest)
                    {
                        unitEntityData.Descriptor.Resurrect(0f, true);
                        unitEntityData.Descriptor.State.LifeState = UnitLifeState.Conscious;
                        unitEntityData.Damage = unitEntityData.Stats.HitPoints - Math.Min(1, unitEntityData.Descriptor.Progression.CharacterLevel);
                        if (unitEntityData.Descriptor.IsPet)
                        {
                            Vector3 vector = unitEntityData.Descriptor.Master.Value.Position;
                            if (AstarPath.active)
                            {
                                FreePlaceSelector.PlaceSpawnPlaces(2, unitEntityData.View.Corpulence, vector);
                                vector = FreePlaceSelector.GetRelaxedPosition(1, true);
                            }

                            unitEntityData.Position = vector;
                        }
                    }
                }
            }

            if (RestController.Instance.m_ScriptedRest || Game.Instance.Player.Camping.UseSpells)
            {
                var fx = Resources.FindObjectsOfTypeAll <GameObject>().First(x => x.name == "SpellHeal00");
                RestController.Instance.UpdateCharactersToBeHealedOnRest();
                var partyHP = new Dictionary <string, int>();
                foreach (var u in Game.Instance.Player.ControllableCharacters)
                {
                    partyHP.Add(u.UniqueId, u.HPLeft);
                }

                // specific healers
                if (SelectionManager.Instance.SelectedUnits.Count > 0)
                {
                    foreach (var unit in SelectionManager.Instance.SelectedUnits)
                    {
                        unit.UseSpellsOnRest();
                    }
                }
                // nobody is selected
                else
                {
                    foreach (UnitEntityData unit in RestController.Instance.CharactersToBeHealedOnRest)
                    {
                        try
                        {
                            if (unit.UseSpellsOnRest())
                            {
                                FxHelper.SpawnFxOnUnit(fx, unit.View);
                            }
                        }
                        catch (Exception ex)
                        {
                            Log(ex);
                        }
                    }
                }

                foreach (var u in Game.Instance.Player.ControllableCharacters)
                {
                    if (u.HPLeft > partyHP[u.UniqueId])
                    {
                        FxHelper.SpawnFxOnUnit(fx, u.View);
                    }
                }
            }
        }