static public bool Prefix(UnitUseAbility __instance, UnitCommand.CommandType commandType, ref AbilityData spell, TargetWrapper target)
        {
            //base ctor

            /*this.Type = commandType;
             * this.Target = target;
             * this.Cutscene = (ElementsContext.GetData<CutsceneParametersContext.ContextData>() != null);*/

            //modify spell
            if (spell == null)
            {
                return(true);
            }
            if (spell.Spellbook == null)
            {
                return(true);
            }
            if (spell.Spellbook.Blueprint.CharacterClass != ArcanistClass.arcanist)
            {
                return(true);
            }
            UnitDescriptor unit          = spell.Caster;
            bool           hadMetamagic  = spell.MetamagicData != null;
            bool           hadMetamixing = unit.Buffs.HasFact(Metamixing.buff);

            //An arcanist can't combine prepared metamagic and spontaneous metamagic, if she doesn't have
            //the Metamixing exploit.
            if (hadMetamagic && !hadMetamixing)
            {
                return(true);
            }
            //UnityModManager.Logger.Log($"spell {spell.Name} has metamagic {(spell.MetamagicData!=null?spell.MetamagicData.MetamagicMask:0)}");
            MetamagicBuilder builder = new MetamagicBuilder(spell.Spellbook, spell);
            Dictionary <Metamagic, Feature> meta_feat = new Dictionary <Metamagic, Feature>();

            foreach (var ft in builder.SpellMetamagicFeatures)
            {
                AddMetamagicFeat comp = ft.Get <AddMetamagicFeat>();
                if (comp == null)
                {
                    continue;
                }
                Metamagic metaId = comp.Metamagic;
                meta_feat[metaId] = ft;
            }
            bool flag = false;

            foreach (var kv in SponMetamagic.buffDict)
            {
                Metamagic metaId        = (Metamagic)(kv.Key.first);
                int       HeightenLevel = kv.Key.second;
                if (!meta_feat.ContainsKey(metaId))
                {
                    continue;
                }
                BlueprintBuff buff = kv.Value;
                if (!unit.HasFact(buff))
                {
                    continue;
                }

                //If the arcanist has the Metamixing exploit, she can add ONE
                //metamagic feat to a prepared spell, without using extra time to cast.
                //(regardless if the spell had metamagic feats when prepared)
                if (metaId == Metamagic.Heighten)
                {
                    int originalLevel = spell.Spellbook.GetSpellLevel(spell.Blueprint);
                    if (HeightenLevel <= originalLevel)
                    {
                        continue;
                    }
                    builder.AddHeightenMetamagic(meta_feat[metaId], HeightenLevel - originalLevel);
                    unit.RemoveFact(buff);
                    flag = true;
                    if (hadMetamixing)
                    {
                        unit.Resources.Spend(ArcaneReservoir.resource, 1);
                        break;
                    }
                }
                else
                {
                    builder.AddMetamagic(meta_feat[metaId]);
                    unit.RemoveFact(buff);
                    flag = true;
                    if (hadMetamixing)
                    {
                        unit.Resources.Spend(ArcaneReservoir.resource, 1);
                        break;
                    }
                }
            }
            if (flag && !hadMetamixing)
            {
                unit.AddBuff(SponMetamagic.flagBuff, unit.Unit);
            }
            spell = builder.ResultAbilityData;
            //UnityModManager.Logger.Log($"new spell {spell.Name} has metamagic {(spell.MetamagicData != null ? spell.MetamagicData.MetamagicMask : 0)}");
            return(true);
        }
        private bool DoParseArgumentsCore(string[] args, object options)
        {
            bool hadError = false;
            var optionMap = OptionInfo.CreateMap(options, _settings);
            optionMap.SetDefaults();
            var target = new TargetWrapper(options);

            IArgumentEnumerator arguments = new StringArrayEnumerator(args);
            while (arguments.MoveNext())
            {
                string argument = arguments.Current;
                if (!string.IsNullOrEmpty(argument))
                {
                    ArgumentParser parser = ArgumentParser.Create(argument, _settings.IgnoreUnknownArguments);
                    if (parser != null)
                    {
                        Internal.ParserState result = parser.Parse(arguments, optionMap, options);
                        if ((result & Internal.ParserState.Failure) == Internal.ParserState.Failure)
                        {
                            SetParserStateIfNeeded(options, parser.PostParsingState);
                            hadError = true;
                            continue;
                        }

                        if ((result & Internal.ParserState.MoveOnNextElement) == Internal.ParserState.MoveOnNextElement)
                            arguments.MoveNext();
                    }
                    else if (target.IsValueListDefined)
                    {
                        if (!target.AddValueItemIfAllowed(argument))
                        {
                            hadError = true;
                        }
                    }
                }
            }

            hadError |= !optionMap.EnforceRules();

            return !hadError;
        }
Beispiel #3
0
 public MoveToTargetProvider(UnitEntityData executor, TargetWrapper move_target)
 {
     unit   = executor;
     target = move_target;
 }
Beispiel #4
0
 public override IEnumerable <TargetWrapper> Select(AbilityExecutionContext context, TargetWrapper anchor)
 {
     Log.Write($"FakeTargetsAround: anchor at {anchor}");
     return(new TargetWrapper[] { TargetCaster?context.Caster : anchor });
 }
 public bool CanTarget(UnitEntityData caster, TargetWrapper target) => GetTargetAreaEffect(caster, target) != null;
        public bool CanTarget(UnitEntityData caster, TargetWrapper target)
        {
            UnitEntityData unit = target.Unit;

            return(((bool)caster.Descriptor.State.Features.SoloTactics) || unit.Descriptor.HasFact(fact));
        }
            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));
            }
 internal static AreaEffectEntityData GetTargetAreaEffect(UnitEntityData caster, TargetWrapper target)
 {
     foreach (var area in GetCasterAreaEffects(caster))
     {
         if (area.View.Shape.Contains(target.Point) && CanDismiss(caster, area))
         {
             return(area);
         }
     }
     return(null);
 }
 static bool CanNotTarget(AbilityData ability, TargetWrapper target)
 {
     return(Mod.Enabled && target.Unit != null &&
            ((FixAbilityCanTargetUntargetableUnit && target.Unit.Descriptor.State.IsUntargetable) ||
             (FixAbilityCanTargetDeadUnit && target.Unit.Descriptor.State.IsDead && !ability.Blueprint.CanCastToDeadTarget)));
 }
 public override void Apply(AbilityExecutionContext context, TargetWrapper target)
 {
 }
Beispiel #11
0
 static void Postfix(ProjectileController __instance, UnitEntityData launcher, TargetWrapper target, BlueprintProjectile projectileBlueprint, RuleAttackRoll attackRoll, RulebookEvent ruleOnHit, Projectile __result)
 {
     if (projectileBlueprint == thrown_weapon_proj)
     {
         var        weapon     = attackRoll.Weapon;
         GameObject gameObject = UnityEngine.Object.Instantiate <GameObject>(weapon.Blueprint.VisualParameters.Model, __result.View.transform);
         gameObject.transform.localPosition = Vector3.zero;
         gameObject.transform.localRotation = Quaternion.Euler(90f, 0f, 0f);
         gameObject.transform.localScale    = Vector3.one;
         __result.MaxRange = weapon.AttackRange.Meters;
     }
 }
        public override IEnumerator <AbilityDeliveryTarget> Deliver(AbilityExecutionContext context, TargetWrapper target)
        {
            UnitEntityData        caster  = context.Caster;
            List <UnitEntityData> targets = this.GetTargets(caster);
            Vector3 tp = target.Point;

            Vector3[] points   = new Vector3[targets.Count];
            float[]   radiuses = new float[targets.Count];
            for (int i = 0; i < targets.Count; i++)
            {
                points[i]   = tp;
                radiuses[i] = targets[i].View.Corpulence;
            }
            FreePlaceSelector.RelaxPoints(points, radiuses, targets.Count, null);
            Vector3    targetPoint = points[0];
            GameObject portalFrom  = FxHelper.SpawnFxOnUnit(this.PortalFromPrefab, caster.View, null, default(Vector3));
            GameObject portalTo    = FxHelper.SpawnFxOnUnit(this.PortalToPrefab, caster.View, null, default(Vector3));

            if (portalTo != null)
            {
                portalTo.transform.position = targetPoint;
            }
            Transform portalFromBone   = (!(portalFrom != null)) ? null : portalFrom.transform.FindChildRecursive(this.PortalBone);
            Vector3   portalFromPoint  = (!(portalFromBone != null)) ? caster.Position : portalFromBone.transform.position;
            Transform portalToBone     = (!(portalTo != null)) ? null : portalTo.transform.FindChildRecursive(this.PortalBone);
            Vector3   portalToPoint    = (!(portalToBone != null)) ? targetPoint : portalToBone.transform.position;
            TimeSpan  startTime        = Game.Instance.TimeController.GameTime;
            bool      casterTeleported = false;

            for (int j = 0; j < targets.Count; j++)
            {
                UnitEntityData t = targets[j];
                t.Wake(10f);
                Vector3             teleportPosition = points[j];
                GameObject          prefab           = (j != 0) ? this.SideDisappearFx : this.CasterDisappearFx;
                GameObject          appearFx         = (j != 0) ? this.SideAppearFx : this.CasterAppearFx;
                BlueprintProjectile blueprint        = (j != 0) ? this.SideDisappearProjectile : this.CasterDisappearProjectile;
                BlueprintProjectile appearProjectile = (j != 0) ? this.SideAppearProjectile : this.CasterAppearProjectile;
                FxHelper.SpawnFxOnUnit(prefab, t.View, null, default(Vector3));
                GameHelper.LaunchProjectile(t, portalFromPoint, blueprint, delegate(Projectile dp)
                {
                    t.CombatState.PreventAttacksOfOpporunityNextFrame = true;
                    t.Position = teleportPosition;
                    t.View.StopMoving();
                    Game.Instance.ProjectileController.Launch(t, t, appearProjectile, portalToPoint, delegate(Projectile ap)
                    {
                        if (this.LookAtTarget)
                        {
                            t.ForceLookAt(target.Point);
                        }
                        FxHelper.SpawnFxOnUnit(appearFx, t.View, null, default(Vector3));
                        casterTeleported |= (caster == t);
                    });
                });
            }
            while (!casterTeleported && Game.Instance.TimeController.GameTime - startTime < 2.Seconds())
            {
                yield return(null);
            }
            if (casterTeleported)
            {
                yield return(new AbilityDeliveryTarget(target));
            }
            yield break;
        }
Beispiel #13
0
        public bool CanTarget(UnitEntityData caster, TargetWrapper target)
        {
            UnitEntityData unit = target.Unit;

            return((target.Unit == caster || caster.Descriptor.Master.Value == target.Unit) != Inverted);
        }
Beispiel #14
0
        public bool CanTarget(UnitEntityData caster, TargetWrapper target)
        {
            bool flag1 = target.Unit != null && ((target.Unit.Descriptor.State.IsDead || target.Unit.Descriptor.State.HasCondition(UnitCondition.DeathDoor)) && target.Unit.Descriptor.HasFact((BlueprintUnitFact)this.RecentlyDeadBuff)) && !target.Unit.Descriptor.State.HasCondition(UnitCondition.Petrified);

            return(flag1);
        }
Beispiel #15
0
            public static void Postfix(ref IEnumerable <TargetWrapper> __result, AbilityTargetsAround __instance, ConditionsChecker ___m_Condition, AbilityExecutionContext context, TargetWrapper anchor)
            {
                if (settings.toggleNoFriendlyFireForAOE)
                {
                    var caster  = context.MaybeCaster;
                    var targets = GameHelper.GetTargetsAround(anchor.Point, __instance.AoERadius);
                    if (caster == null)
                    {
                        __result = Enumerable.Empty <TargetWrapper>();
                        return;
                    }
                    switch (__instance.m_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.Descriptor.IsPartyOrPet() && ((context.AbilityBlueprint.EffectOnAlly == AbilityEffectOnUnit.Harmful) || (context.AbilityBlueprint.EffectOnEnemy == AbilityEffectOnUnit.Harmful)))
                    {
                        if (context.AbilityBlueprint.HasLogic <AbilityUseOnRest>())
                        {
                            var componentType = context.AbilityBlueprint.GetComponent <AbilityUseOnRest>().Type;
                            //bool healDamage = componentType == AbilityUseOnRestType.HealDamage || componentType == AbilityUseOnRestType.HealDamage;
                            var healDamage = componentType == AbilityUseOnRestType.HealDamage;
                            targets = targets.Where(target => {
                                if (target.Descriptor.IsPartyOrPet() && !healDamage)
                                {
                                    var forUndead = componentType == AbilityUseOnRestType.HealMassUndead || componentType == AbilityUseOnRestType.HealSelfUndead || componentType == AbilityUseOnRestType.HealUndead;
                                    return(forUndead == target.Descriptor.IsUndead);
                                }
                                return(true);
                            });
                        }
                        else
                        {
                            targets = targets.Where(target => !target.Descriptor.IsPartyOrPet());
                        }
                    }
                    __result = targets.Select(target => new TargetWrapper(target));
                }
            }