Esempio n. 1
0
        // known issues:
        // - composite blasts consisting of two elements (ice) count as two attacks and will roll concealment/mirror-image individually. also true for crit and crit confirm
        // - "Miss" text doesn't show, if attack roll on consecutive hits was too high compared to initial roll
        // - "Miss" text shows up, if attack roll on consecutive hits was too low compared to initial roll
        // ! found "RuleAttackRoll ruleAttackRoll = Rulebook.CurrentContext.LastEvent<RuleAttackRoll>();" which might be useful for improvement!
        static public void createImpaleInfusion()
        {
            var earth_blast    = library.Get <BlueprintFeature>("7f5f82c1108b961459c9884a0fa0f5c4");      //EarthBlastFeature
            var earth_blast_ab = library.Get <BlueprintAbility>("b28c336c10eb51c4a8ded0258d5742e1");      //EarthBlastAbility
            var metal_blast    = library.Get <BlueprintFeature>("ad20bc4e586278c4996d4a81b2448998");      //MetalBlastFeature
            var metal_blast_ab = library.Get <BlueprintAbility>("665cfd3718c4f284d80538d85a2791c9");      //MetalBlastAbility
            var ice_blast      = library.Get <BlueprintFeature>("a8cc34ca1a5e55a4e8aa5394efe2678e");      //IceBlastFeature
            var ice_blast_ab   = library.Get <BlueprintAbility>("519e36decde7c964d87c2ffe4d3d8459");      //IceBlastAbility
            var icon           = library.Get <BlueprintFeature>("2aad85320d0751340a0786de073ee3d5").Icon; //TorrentInfusionFeature

            // create new impale feature
            // - add to selection of infusions
            infusion_impale_feature = Helpers.CreateFeature(
                "InfusionImpaleFeature",
                "Impale",
                "Element: earth\nType: form infusion\nLevel: 3\nBurn: 2\nAssociated Blasts: earth, metal, ice\n"
                + "You extend a long, sharp spike of elemental matter along a line, impaling multiple foes. Make a single attack roll against each creature or object in a 30-foot line.",
                "f942f82c01c34c7da5f1131f5484e8b4",
                icon,
                FeatureGroup.KineticBlastInfusion,
                Helpers.PrerequisiteFeaturesFromList(new BlueprintFeature[] { earth_blast, metal_blast, ice_blast }, true),
                Helpers.PrerequisiteClassLevel(kineticist_class, 6),
                Helpers.PrerequisiteFeature(elemental_focus)
                );
            infusion_impale_feature.IsClassFeature = true;
            Helper.AppendAndReplace(ref infusion_selection.AllFeatures, infusion_impale_feature);

            #region create impale ability - earth
            // - clone from water torrent
            // - replace EffectRunAction to a custom one: damage as usual for kineticist, only piercing, no saving throw, must roll attack, can crit
            // - replace projectile to what we want
            // - replace AbilityKineticist to fix CachedDamageInfo
            // - replace spawnFx
            // - replace requirement to need the impale feature
            // - add as variant to parent blast
            var earth_impale_ability = library.CopyAndAdd <BlueprintAbility>("93cc42235edc6824fa7d54b83ed4e1fe", "EarthImpaleAbility", "adcf52d3bc874d9a94250053b7ebf6e4"); // TorrentWaterBlastAbility
            earth_impale_ability.SetNameDescriptionIcon(infusion_impale_feature);
            earth_impale_ability.LocalizedSavingThrow = Helpers.savingThrowNone;
            earth_impale_ability.Parent = earth_base;

            //var damage_roll = Helpers.CreateActionDealDamage(PhysicalDamageForm.Piercing, damage_dice, isAoE: false, halfIfSaved: false, IgnoreCritical: false);
            var earth_damage_roll = NewComponents.ContextActionDealDamage2.CreateNew(PhysicalDamageForm.Piercing, physical_dice, isAoE: true, halfIfSaved: false, IgnoreCritical: false);
            earth_damage_roll.Half           = false;
            earth_damage_roll.WeaponOverride = new ItemEntityWeapon(weapon_blast_physical);
            var earth_actions = Helper.CreateAbilityEffectRunAction(0, earth_damage_roll);
            earth_impale_ability.ReplaceComponent <AbilityEffectRunAction>(earth_actions);

            earth_impale_ability.ReplaceComponent <AbilityDeliverProjectile>(a =>
            {
                a.Type           = AbilityProjectileType.Line;
                a.Length         = new Feet(30f);
                a.LineWidth      = new Feet(5f);
                a.NeedAttackRoll = true;
                a.Weapon         = weapon_blast_physical;
                a.Projectiles    = library.Get <BlueprintProjectile>("5d66a6c3cac5124469b2d0474e53ecab").ToArray(); // Kinetic_EarthBlastLine00: 5d66a6c3cac5124469b2d0474e53ecab
            });

            earth_impale_ability.ReplaceComponent <AbilityKineticist>(a =>
            {
                a.InfusionBurnCost = 2;
                a.BlastBurnCost    = 0;
                a.Amount           = 1;
                a.CachedDamageInfo = earth_blast_ab.GetComponent <AbilityKineticist>().CachedDamageInfo;
            });

            //earth_impale_ability.RemoveComponents<SpellDescriptorComponent>();
            earth_impale_ability.RemoveComponents <AbilitySpawnFx>(); earth_impale_ability.AddComponents(earth_blast_ab.GetComponents <AbilitySpawnFx>());
            earth_impale_ability.ReplaceComponent <AbilityCasterHasFacts>(a => a.Facts         = infusion_impale_feature.ToArray());
            earth_impale_ability.ReplaceComponent <AbilityShowIfCasterHasFact>(a => a.UnitFact = infusion_impale_feature);
            #endregion


            #region create impale ability - metal
            var metal_impale_ability = library.CopyAndAdd <BlueprintAbility>("82db79a0b4e91dc4ea2938192e6fc7af", "MetalImpaleAbility", "c25c7c8f05284317984ddcbcba69f53c");  //TorrentSandstormBlastAbility
            metal_impale_ability.SetNameDescriptionIcon(infusion_impale_feature);
            metal_impale_ability.LocalizedSavingThrow = Helpers.savingThrowNone;
            metal_impale_ability.Parent = metal_base;

            metal_impale_ability.ReplaceComponent <AbilityEffectRunAction>(earth_actions);   //this can be reused, because both deal full physical damage

            // AbilityDeliverProjectile can be kept, because the fx and form/range is the same as sandstorm-torrent

            metal_impale_ability.ReplaceComponent <AbilityKineticist>(a =>
            {
                a.InfusionBurnCost = 2;
                a.BlastBurnCost    = 2;
                a.Amount           = 1;
                a.CachedDamageInfo = metal_blast_ab.GetComponent <AbilityKineticist>().CachedDamageInfo;
            });

            // AbilitySpawnFx can be kept
            metal_impale_ability.ReplaceComponent <AbilityCasterHasFacts>(a => a.Facts         = infusion_impale_feature.ToArray());
            metal_impale_ability.ReplaceComponent <AbilityShowIfCasterHasFact>(a => a.UnitFact = infusion_impale_feature);
            #endregion


            #region create impale ability - ice
            var ice_impale_ability = library.CopyAndAdd <BlueprintAbility>("d02fba9ae78f12642b4111a4bbbdc023", "IceImpaleAbility", "50486077f898441dba7c2922a3d251ed");  //TorrentBlizzardBlastAbility
            ice_impale_ability.SetNameDescriptionIcon(infusion_impale_feature);
            ice_impale_ability.LocalizedSavingThrow = Helpers.savingThrowNone;
            ice_impale_ability.Parent = ice_base;

            //var damage_roll = Helpers.CreateActionDealDamage(PhysicalDamageForm.Piercing, damage_dice, isAoE: false, halfIfSaved: false, IgnoreCritical: false);
            var ice_damage_roll = NewComponents.ContextActionDealDamage2.CreateNew(PhysicalDamageForm.Piercing, physical_dice, isAoE: true, halfIfSaved: false, IgnoreCritical: false);
            ice_damage_roll.Half           = false;
            ice_damage_roll.WeaponOverride = new ItemEntityWeapon(weapon_blast_physical);
            var ice_damage_roll2 = NewComponents.ContextActionDealDamage2.CreateNew(DamageEnergyType.Cold, physical_dice, isAoE: true, halfIfSaved: false, IgnoreCritical: false);
            ice_damage_roll2.Half           = false;
            ice_damage_roll2.WeaponOverride = new ItemEntityWeapon(weapon_blast_physical);  //this is correct, because the bonus damage is the same as physical
            //ice_damage_roll2.ReadPreRolledFromSharedValue = true;
            //ice_damage_roll2.PreRolledSharedValue = AbilitySharedValue.Duration;
            ice_impale_ability.ReplaceComponent <AbilityEffectRunAction>(Helper.CreateAbilityEffectRunAction(0, ice_damage_roll, ice_damage_roll2));

            // AbilityDeliverProjectile can be kept, because the fx and form/range is the same as blizzard-torrent

            ice_impale_ability.ReplaceComponent <AbilityKineticist>(a =>
            {
                a.InfusionBurnCost = 2;
                a.BlastBurnCost    = 2;
                a.Amount           = 1;
                a.CachedDamageInfo = ice_blast_ab.GetComponent <AbilityKineticist>().CachedDamageInfo;
            });

            // AbilitySpawnFx can be kept
            ice_impale_ability.ReplaceComponent <AbilityCasterHasFacts>(a => a.Facts         = infusion_impale_feature.ToArray());
            ice_impale_ability.ReplaceComponent <AbilityShowIfCasterHasFact>(a => a.UnitFact = infusion_impale_feature);
            #endregion

            Helper.AppendAndReplace(ref earth_base.GetComponent <AbilityVariants>().Variants, earth_impale_ability);
            Helper.AppendAndReplace(ref metal_base.GetComponent <AbilityVariants>().Variants, metal_impale_ability);
            Helper.AppendAndReplace(ref ice_base.GetComponent <AbilityVariants>().Variants, ice_impale_ability);
        }