Exemple #1
0
        internal override void SetupAttributes()
        {
            myDef = CloneSkillDef(targetVariantDef);

            var nametoken = "CLASSICITEMS_SCEPCOMMANDO_GRENADENAME";

            newDescToken = "CLASSICITEMS_SCEPCOMMANDO_GRENADEDESC";
            oldDescToken = targetVariantDef.skillDescriptionToken;
            var namestr = "Carpet Bomb";

            LanguageAPI.Add(nametoken, namestr);

            myDef.skillName             = namestr;
            myDef.skillNameToken        = nametoken;
            myDef.skillDescriptionToken = newDescToken;
            myDef.icon = ClassicItemsPlugin.resources.LoadAsset <Sprite>("Assets/ClassicItems/Textures/ScepterSkillIcons/commando_grenadeicon.png");

            ContentAddition.AddSkillDef(myDef);

            projReplacer = LegacyResourcesAPI.Load <GameObject>("prefabs/projectiles/CommandoGrenadeProjectile").InstantiateClone("CIScepCommandoGrenade", true);
            var pie = projReplacer.GetComponent <ProjectileImpactExplosion>();

            pie.blastDamageCoefficient *= 0.5f;
            pie.bonusBlastForce        *= 0.5f;

            ContentAddition.AddProjectile(projReplacer);
        }
Exemple #2
0
        public override void SetupAttributes()
        {
            base.SetupAttributes();

            projectilePrefab = TinkersSatchelPlugin.resources.LoadAsset <GameObject>("Assets/TinkersSatchel/Prefabs/Misc/UnstableBombShell.prefab");
            var expl = projectilePrefab.GetComponent <ProjectileExplosion>();

            expl.explosionEffect = Addressables.LoadAssetAsync <GameObject>("RoR2/Base/FusionCellDestructible/FusionCellExplosion.prefab")
                                   .WaitForCompletion();
            projectilePrefab.GetComponent <SphereCollider>().material = Addressables.LoadAssetAsync <PhysicMaterial>("RoR2/Base/Common/physmatBouncy.physicMaterial")
                                                                        .WaitForCompletion();

            var ghost     = TinkersSatchelPlugin.resources.LoadAsset <GameObject>("Assets/TinkersSatchel/Prefabs/Misc/UnstableBombShellGhost.prefab");
            var ghostPart = ghost.GetComponent <ParticleSystemRenderer>();

            ghostPart.material = Addressables.LoadAssetAsync <Material>("RoR2/Base/Common/VFX/matOpaqueDustLargeDirectional.mat")
                                 .WaitForCompletion();
            var indFixedRen = ghostPart.transform.Find("IndicatorFixed").GetComponent <MeshRenderer>();

            indFixedRen.material = Addressables.LoadAssetAsync <Material>("RoR2/Base/Captain/matCaptainAirstrikeAltAreaIndicatorOuter.mat")
                                   .WaitForCompletion();
            var indPulseRen = ghostPart.transform.Find("IndicatorPulse").GetComponent <MeshRenderer>();

            indPulseRen.material = Addressables.LoadAssetAsync <Material>("RoR2/Base/Captain/matCaptainAirstrikeAltAreaIndicatorInner.mat")
                                   .WaitForCompletion();

            ContentAddition.AddProjectile(projectilePrefab);
        }
Exemple #3
0
        internal override void SetupAttributes()
        {
            myDef = CloneSkillDef(targetVariantDef);

            var nametoken = "CLASSICITEMS_SCEPLOADER_CHARGEZAPFISTNAME";

            newDescToken = "CLASSICITEMS_SCEPLOADER_CHARGEZAPFISTDESC";
            oldDescToken = targetVariantDef.skillDescriptionToken;
            var namestr = "Thundercrash";

            LanguageAPI.Add(nametoken, namestr);

            myDef.skillName             = namestr;
            myDef.skillNameToken        = nametoken;
            myDef.skillDescriptionToken = newDescToken;
            myDef.icon = ClassicItemsPlugin.resources.LoadAsset <Sprite>("Assets/ClassicItems/Textures/ScepterSkillIcons/loader_chargezapfisticon.png");

            ContentAddition.AddSkillDef(myDef);

            projReplacer = LegacyResourcesAPI.Load <GameObject>("prefabs/projectiles/LoaderZapCone").InstantiateClone("CIScepLoaderThundercrash", true);
            var proxb = projReplacer.GetComponent <ProjectileProximityBeamController>();

            proxb.attackFireCount *= 3;
            proxb.maxAngleFilter   = 180f;
            projReplacer.transform.Find("Effect").localScale *= 3f;

            ContentAddition.AddProjectile(projReplacer);
        }
Exemple #4
0
        public override void SetupAttributes()
        {
            base.SetupAttributes();

            var tempPfb = LegacyResourcesAPI.Load <GameObject>("Prefabs/Projectiles/GravSphere").InstantiateClone("temporary setup prefab", false);
            var proj    = tempPfb.GetComponent <RoR2.Projectile.ProjectileSimple>();

            proj.desiredForwardSpeed = 0;
            proj.lifetime            = PULL_VFX_DURATION;
            var projCtrl = tempPfb.GetComponent <RoR2.Projectile.ProjectileController>();

            projCtrl.procCoefficient = 0;
            var dmg = proj.GetComponent <RoR2.Projectile.ProjectileDamage>();

            dmg.damage  = 0f;
            dmg.enabled = false;
            var force = tempPfb.GetComponent <RadialForce>();

            force.enabled = false;

            var sph = tempPfb.transform.Find("Sphere");

            sph.gameObject.SetActive(false);

            var sps     = tempPfb.transform.Find("Sparks");
            var spsPart = sps.GetComponent <ParticleSystem>();
            var spsMain = spsPart.main;

            spsMain.startSpeed = new ParticleSystem.MinMaxCurve(10f, 30f);
            var spsShape = spsPart.shape;

            spsShape.radius = 4f;

            blackHolePrefab = tempPfb.InstantiateClone("KleinBottleProcPrefab", true);
            UnityEngine.Object.Destroy(tempPfb);

            ContentAddition.AddProjectile(blackHolePrefab);

            var achiNameToken = $"ACHIEVEMENT_TKSAT_{name.ToUpper(System.Globalization.CultureInfo.InvariantCulture)}_NAME";
            var achiDescToken = $"ACHIEVEMENT_TKSAT_{name.ToUpper(System.Globalization.CultureInfo.InvariantCulture)}_DESCRIPTION";

            unlockable                 = ScriptableObject.CreateInstance <UnlockableDef>();
            unlockable.cachedName      = $"TkSat_{name}Unlockable";
            unlockable.sortScore       = 200;
            unlockable.achievementIcon = TinkersSatchelPlugin.resources.LoadAsset <Sprite>("Assets/TinkersSatchel/Textures/UnlockIcons/kleinBottleIcon.png");
            ContentAddition.AddUnlockableDef(unlockable);
            LanguageAPI.Add(achiNameToken, "Can't Touch This");
            LanguageAPI.Add(achiDescToken, "Block, or take 1 or less points of damage from, 3 attacks in a row.");
            itemDef.unlockableDef = unlockable;
        }
Exemple #5
0
        internal override void SetupAttributes()
        {
            myDef = CloneSkillDef(targetVariantDef);

            var nametoken = "CLASSICITEMS_SCEPHUNTRESS_RAINNAME";

            newDescToken = "CLASSICITEMS_SCEPHUNTRESS_RAINDESC";
            oldDescToken = targetVariantDef.skillDescriptionToken;
            var namestr = "Burning Rain";

            LanguageAPI.Add(nametoken, namestr);

            myDef.skillName             = namestr;
            myDef.skillNameToken        = nametoken;
            myDef.skillDescriptionToken = newDescToken;
            myDef.icon = ClassicItemsPlugin.resources.LoadAsset <Sprite>("Assets/ClassicItems/Textures/ScepterSkillIcons/huntress_arrowrainicon.png");

            ContentAddition.AddSkillDef(myDef);

            projReplacer = LegacyResourcesAPI.Load <GameObject>("prefabs/projectiles/HuntressArrowRain").InstantiateClone("CIScepHuntressRain", true);
            projReplacer.GetComponent <ProjectileDamage>().damageType |= DamageType.IgniteOnHit;
            projReplacer.GetComponent <ProjectileDotZone>().lifetime  *= 1.5f;
            projReplacer.transform.localScale = new Vector3(22.5f, 15f, 22.5f);
            var fx    = projReplacer.transform.Find("FX");
            var afall = fx.Find("ArrowsFalling");

            afall.GetComponent <ParticleSystemRenderer>().material.SetVector("_TintColor", new Vector4(3f, 0.1f, 0.04f, 1.5f));
            var aimp = fx.Find("ImpaledArrow");

            aimp.GetComponent <ParticleSystemRenderer>().material.SetVector("_TintColor", new Vector4(3f, 0.1f, 0.04f, 1.5f));
            var radInd = fx.Find("RadiusIndicator");

            radInd.GetComponent <MeshRenderer>().material.SetVector("_TintColor", new Vector4(3f, 0.1f, 0.04f, 1.25f));
            var flash = fx.Find("ImpactFlashes");
            var psm   = flash.GetComponent <ParticleSystem>().main;

            psm.startColor = new Color(1f, 0.7f, 0.4f);
            flash.GetComponent <ParticleSystemRenderer>().material.SetVector("_TintColor", new Vector4(3f, 0.1f, 0.04f, 1.5f));
            var flashlight = flash.Find("Point Light");

            flashlight.GetComponent <Light>().color = new Color(1f, 0.5f, 0.3f);
            flashlight.GetComponent <Light>().range = 15f;
            flashlight.gameObject.SetActive(true);

            ContentAddition.AddProjectile(projReplacer);
        }
        internal override void SetupAttributes()
        {
            myDef = CloneSkillDef(targetVariantDef);

            var nametoken = "CLASSICITEMS_SCEPCAPTAIN_AIRSTRIKEALTNAME";

            newDescToken = "CLASSICITEMS_SCEPCAPTAIN_AIRSTRIKEALTDESC";
            oldDescToken = targetVariantDef.skillDescriptionToken;
            var namestr = "Colony Drop";

            LanguageAPI.Add(nametoken, namestr);

            myDef.skillName             = namestr;
            myDef.skillNameToken        = nametoken;
            myDef.skillDescriptionToken = newDescToken;
            myDef.icon = ClassicItemsPlugin.resources.LoadAsset <Sprite>("Assets/ClassicItems/Textures/ScepterSkillIcons/captain_airstrikealticon.png");

            ContentAddition.AddSkillDef(myDef);

            var oldCallDef = LegacyResourcesAPI.Load <SkillDef>("skilldefs/captainbody/CallAirstrikeAlt");

            myCallDef      = CloneSkillDef(oldCallDef);
            myCallDef.icon = ClassicItemsPlugin.resources.LoadAsset <Sprite>("Assets/ClassicItems/Textures/ScepterSkillIcons/captain_airstrikealticon.png");

            ContentAddition.AddSkillDef(myCallDef);

            projReplacer = LegacyResourcesAPI.Load <GameObject>("Prefabs/Projectiles/CaptainAirstrikeAltProjectile").InstantiateClone("CIScepCaptainAirstrikeAltTemp", false);
            projReplacer.GetComponent <ProjectileImpactExplosion>().blastRadius *= 8f;
            var pc = projReplacer.GetComponent <ProjectileController>();

            ghostReplacer = LegacyResourcesAPI.Load <GameObject>("Prefabs/ProjectileGhosts/CaptainAirstrikeAltGhost").InstantiateClone("CIScepCaptainAirstrikeAltGhostTemp", false);
            ghostReplacer.transform.Find("Indicator").lossyScale.Scale(new Vector3(8f, 8f, 2f));
            ghostReplacer.transform.Find("AreaIndicatorCenter").lossyScale.Scale(new Vector3(8f, 8f, 2f));
            ghostReplacer.transform.Find("AirstrikeOrientation").Find("FallingProjectile").lossyScale.Scale(new Vector3(4f, 4f, 4f));
            ghostReplacer = ghostReplacer.InstantiateClone("CIScepCaptainAirstrikeAltGhost", false);

            pc.ghostPrefab = ghostReplacer;

            projReplacer = projReplacer.InstantiateClone("CIScepCaptainAirstrikeAlt", true);

            ContentAddition.AddProjectile(projReplacer);
        }
Exemple #7
0
        internal override void SetupAttributes()
        {
            myDef = CloneSkillDef(targetVariantDef);

            var nametoken = "CLASSICITEMS_SCEPMAGE_FLAMETHROWERNAME";

            newDescToken = "CLASSICITEMS_SCEPMAGE_FLAMETHROWERDESC";
            oldDescToken = targetVariantDef.skillDescriptionToken;
            var namestr = "Dragon's Breath";

            LanguageAPI.Add(nametoken, namestr);

            myDef.skillName             = namestr;
            myDef.skillNameToken        = nametoken;
            myDef.skillDescriptionToken = newDescToken;
            myDef.icon = ClassicItemsPlugin.resources.LoadAsset <Sprite>("Assets/ClassicItems/Textures/ScepterSkillIcons/mage_flamethrowericon.png");

            ContentAddition.AddSkillDef(myDef);

            projCloud = LegacyResourcesAPI.Load <GameObject>("prefabs/projectiles/BeetleQueenAcid").InstantiateClone("CIScepMageFlamethrowerCloud", true);
            var pdz = projCloud.GetComponent <ProjectileDotZone>();

            pdz.lifetime      = 10f;
            pdz.impactEffect  = null;
            pdz.fireFrequency = 2f;
            var fxObj = projCloud.transform.Find("FX");

            fxObj.Find("Spittle").gameObject.SetActive(false);
            fxObj.Find("Decal").gameObject.SetActive(false);
            fxObj.Find("Gas").gameObject.SetActive(false);
            foreach (var x in fxObj.GetComponents <AnimateShaderAlpha>())
            {
                x.enabled = false;
            }
            var fxcloud = UnityEngine.Object.Instantiate(LegacyResourcesAPI.Load <GameObject>("prefabs/FireTrail").GetComponent <DamageTrail>().segmentPrefab, fxObj.transform);
            var psmain  = fxcloud.GetComponent <ParticleSystem>().main;

            psmain.duration        = 10f;
            psmain.gravityModifier = -0.05f;
            var pstartx = psmain.startSizeX;

            pstartx.constantMin *= 0.75f;
            pstartx.constantMax *= 0.75f;
            var pstarty = psmain.startSizeY;

            pstarty.constantMin *= 0.75f;
            pstarty.constantMax *= 0.75f;
            var pstartz = psmain.startSizeZ;

            pstartz.constantMin *= 0.75f;
            pstartz.constantMax *= 0.75f;
            var pslife = psmain.startLifetime;

            pslife.constantMin = 0.75f;
            pslife.constantMax = 1.5f;
            fxcloud.GetComponent <DestroyOnTimer>().enabled = false;
            fxcloud.transform.localPosition = Vector3.zero;
            fxcloud.transform.localScale    = Vector3.one;
            var psshape = fxcloud.GetComponent <ParticleSystem>().shape;

            psshape.shapeType = ParticleSystemShapeType.Sphere;
            psshape.scale     = Vector3.one * 1.5f;
            var psemit = fxcloud.GetComponent <ParticleSystem>().emission;

            psemit.rateOverTime = Scepter.instance.artiFlamePerformanceMode ? 4f : 20f;
            var lightObj = fxObj.Find("Point Light").gameObject;

            if (Scepter.instance.artiFlamePerformanceMode)
            {
                UnityEngine.Object.Destroy(lightObj);
            }
            else
            {
                var lightCpt = lightObj.GetComponent <Light>();
                lightCpt.color     = new Color(1f, 0.5f, 0.2f);
                lightCpt.intensity = 3.5f;
                lightCpt.range     = 5f;
            }

            ContentAddition.AddProjectile(projCloud);
        }
Exemple #8
0
        public override void SetupAttributes()
        {
            base.SetupAttributes();

            //load custom assets
            skillDef         = TinkersSatchelPlugin.resources.LoadAsset <SkillDef>("Assets/TinkersSatchel/SkillDefs/CommandoSpecialPlasmaGrenade.asset");
            scepterSkillDef  = TinkersSatchelPlugin.resources.LoadAsset <SkillDef>("Assets/TinkersSatchel/SkillDefs/CIScepter/CommandoSpecialPlasmaGrenadeScep.asset");
            projectilePrefab = TinkersSatchelPlugin.resources.LoadAsset <GameObject>("Assets/TinkersSatchel/Prefabs/Misc/CommandoPlasmaGrenadeProjectile.prefab");
            var ghostPrefab = TinkersSatchelPlugin.resources.LoadAsset <GameObject>("Assets/TinkersSatchel/Prefabs/Misc/CommandoPlasmaGrenadeGhost.prefab");

            scepterProjectilePrefab = TinkersSatchelPlugin.resources.LoadAsset <GameObject>("Assets/TinkersSatchel/Prefabs/Misc/CommandoPlasmaGrenadeProjectileScep.prefab");
            var scepterGhostPrefab = TinkersSatchelPlugin.resources.LoadAsset <GameObject>("Assets/TinkersSatchel/Prefabs/Misc/CommandoPlasmaGrenadeGhostScep.prefab");

            //load vanilla assets
            targetSkillFamily = Addressables.LoadAssetAsync <SkillFamily>("RoR2/Base/Commando/CommandoBodySpecialFamily.asset")
                                .WaitForCompletion();
            var detParticleMaterial = Addressables.LoadAssetAsync <Material>("RoR2/Base/Wisp/matWispFire.mat")
                                      .WaitForCompletion();
            var fuseParticleMaterial = Addressables.LoadAssetAsync <Material>("RoR2/Base/ClayBoss/matClayBossLightshaft.mat")
                                       .WaitForCompletion();
            var explosionPrefab = Addressables.LoadAssetAsync <GameObject>("RoR2/Base/LemurianBruiser/OmniExplosionVFXLemurianBruiserFireballImpact.prefab")
                                  .WaitForCompletion();

            //modify
            var pRen = ghostPrefab.transform.Find("RadialGlow").gameObject.GetComponent <ParticleSystemRenderer>();

            pRen.material = detParticleMaterial;
            var expl = projectilePrefab.GetComponent <ProjectileExplosion>();

            expl.explosionEffect = explosionPrefab;
            var pRen2 = projectilePrefab.transform.Find("FuseVFX").gameObject.GetComponent <ParticleSystemRenderer>();

            pRen2.material = fuseParticleMaterial;

            var scepterExplosionPrefabTmp = explosionPrefab.InstantiateClone("TkSatTempSetupPrefab", false);

            scepterExplosionPrefabTmp.transform.localScale *= 2f;

            var scepterExplosionPrefab = scepterExplosionPrefabTmp.InstantiateClone("TkSatPlasmaGrenadeScepterExplosion", false);

            pRen                 = scepterGhostPrefab.transform.Find("RadialGlow").gameObject.GetComponent <ParticleSystemRenderer>();
            pRen.material        = detParticleMaterial;
            expl                 = scepterProjectilePrefab.GetComponent <ProjectileExplosion>();
            expl.explosionEffect = scepterExplosionPrefab;
            pRen2                = scepterProjectilePrefab.transform.Find("FuseVFX").gameObject.GetComponent <ParticleSystemRenderer>();
            pRen2.material       = fuseParticleMaterial;

            //R2API catalog reg
            var astate = ContentAddition.AddEntityState <Fire>(out bool entStateDidSucceed);

            skillDef.activationState        = astate;
            scepterSkillDef.activationState = astate;

            if (!entStateDidSucceed)
            {
                TinkersSatchelPlugin._logger.LogError("EntityState setup failed on CommandoSpecialPlasmaGrenade! Skill will not appear nor function.");
            }
            else if (!ContentAddition.AddSkillDef(skillDef))
            {
                TinkersSatchelPlugin._logger.LogError("SkillDef setup failed on CommandoSpecialPlasmaGrenade! Skill will not appear nor function.");
            }
            else
            {
                setupSucceeded = true;
            }

            ContentAddition.AddEffect(scepterExplosionPrefab);
            ContentAddition.AddProjectile(projectilePrefab);
            ContentAddition.AddProjectile(scepterProjectilePrefab);

            if (Compat_ClassicItems.enabled)
            {
                if (!ContentAddition.AddSkillDef(scepterSkillDef))
                {
                    scepSetupSucceeded = false;
                }
                else
                {
                    scepSetupSucceeded = Compat_ClassicItems.RegisterScepterSkill(scepterSkillDef, "CommandoBody", SkillSlot.Special, skillDef);
                }
                if (!scepSetupSucceeded)
                {
                    TinkersSatchelPlugin._logger.LogError("ClassicItems Scepter support failed for CommandoSpecialPlasmaGrenade! Ancient Scepter will not work on this skill.");
                }
            }
        }
Exemple #9
0
        public override void SetupAttributes()
        {
            base.SetupAttributes();

            var tempPfb = LegacyResourcesAPI.Load <GameObject>("Prefabs/Projectiles/GravSphere").InstantiateClone("temporary setup prefab", false);
            var proj    = tempPfb.GetComponent <RoR2.Projectile.ProjectileSimple>();

            proj.desiredForwardSpeed = 0;
            proj.lifetime            = 0.5f;
            var projCtrl = tempPfb.GetComponent <RoR2.Projectile.ProjectileController>();

            projCtrl.procCoefficient = 0;
            var dmg = proj.GetComponent <RoR2.Projectile.ProjectileDamage>();

            dmg.damage  = 0f;
            dmg.enabled = false;
            var force = tempPfb.GetComponent <RadialForce>();

            force.enabled = false;

            var sph = tempPfb.transform.Find("Sphere");

            sph.gameObject.SetActive(false);

            var sps      = tempPfb.transform.Find("Sparks");
            var spsPart  = sps.GetComponent <ParticleSystem>();
            var spsShape = spsPart.shape;

            spsShape.radius = 30f;

            blackHolePrefab = tempPfb.InstantiateClone("LodestoneProcPrefab", true);
            UnityEngine.Object.Destroy(tempPfb);

            ContentAddition.AddProjectile(blackHolePrefab);

            validObjectNamesRB.UnionWith(new[] {
                "HealPack(Clone)",
                "StickyBomb(Clone)",
                "TkSatPixieMovePack(Clone)",
                "TkSatPixieAttackPack(Clone)",
                "TkSatPixieDamagePack(Clone)",
                "TkDatPixieArmorPack(Clone)",
                "AmmoPack(Clone)",
                "BonusMoneyPack(Clone)",
                "ShurikenProjectile(Clone)",
                "FireMeatBall(Clone)",
                "DeathProjectile(Clone)",
                "BeamSphere(Clone)",
                "GravSphere(Clone)",
                "Sawmerang(Clone)",
                "LunarSunProjectile(Clone)"
            });
            validObjectNamesNoRB.UnionWith(new[] { //may have RB, but should teleport anyways
                "DeskplantWard(Clone)",
                "CrippleWard(Clone)",
                "WarbannerWard(Clone)",
                "DamageZoneWard(Clone)"
            });

            var achiNameToken = $"ACHIEVEMENT_TKSAT_{name.ToUpper(System.Globalization.CultureInfo.InvariantCulture)}_NAME";
            var achiDescToken = $"ACHIEVEMENT_TKSAT_{name.ToUpper(System.Globalization.CultureInfo.InvariantCulture)}_DESCRIPTION";

            unlockable                 = ScriptableObject.CreateInstance <UnlockableDef>();
            unlockable.cachedName      = $"TkSat_{name}Unlockable";
            unlockable.sortScore       = 200;
            unlockable.achievementIcon = TinkersSatchelPlugin.resources.LoadAsset <Sprite>("Assets/TinkersSatchel/Textures/UnlockIcons/lodestoneIcon.png");
            ContentAddition.AddUnlockableDef(unlockable);
            LanguageAPI.Add(achiNameToken, "Drive Me Closer");
            LanguageAPI.Add(achiDescToken, "Item Set: Close-range. Have 6 or more (of 15) at once.");
            equipmentDef.unlockableDef = unlockable;

            if (Compat_ClassicItems.enabled)
            {
                LanguageAPI.Add("TKSAT_LODESTONE_CI_EMBRYO_APPEND", "\n<style=cStack>Beating Embryo: Double range and damage.</style>");
                Compat_ClassicItems.RegisterEmbryoHook(equipmentDef, "TKSAT_LODESTONE_CI_EMBRYO_APPEND", () => "TKSAT.Lodestone");
            }
        }
        public override void SetupAttributes()
        {
            base.SetupAttributes();

            //load custom assets
            projectilePrefab    = TinkersSatchelPlugin.resources.LoadAsset <GameObject>("Assets/TinkersSatchel/Prefabs/Misc/EngiFlakProjectile.prefab");
            projectileGhost     = TinkersSatchelPlugin.resources.LoadAsset <GameObject>("Assets/TinkersSatchel/Prefabs/Misc/EngiFlakGhost.prefab");
            subProjectilePrefab = TinkersSatchelPlugin.resources.LoadAsset <GameObject>("Assets/TinkersSatchel/Prefabs/Misc/EngiFlakSubProjectile.prefab");
            subProjectileGhost  = TinkersSatchelPlugin.resources.LoadAsset <GameObject>("Assets/TinkersSatchel/Prefabs/Misc/EngiFlakSubGhost.prefab");
            skillDef            = ScriptableObject.CreateInstance <SteppedSkillDef>();
            skillDef.activationStateMachineName = "Weapon";
            skillDef.skillNameToken             = "TKSAT_ENGI_PRIMARY_FLAK_NAME";
            skillDef.skillDescriptionToken      = "TKSAT_ENGI_PRIMARY_FLAK_DESCRIPTION";
            skillDef.interruptPriority          = InterruptPriority.Any;
            skillDef.icon = TinkersSatchelPlugin.resources.LoadAsset <Sprite>("Assets/TinkersSatchel/Textures/SkillIcons/EngiPrimaryFlak.png");
            skillDef.baseRechargeInterval         = 0;
            skillDef.baseMaxStock                 = 1;
            skillDef.rechargeStock                = 1;
            skillDef.requiredStock                = 1;
            skillDef.stockToConsume               = 1;
            skillDef.resetCooldownTimerOnUse      = true;
            skillDef.fullRestockOnAssign          = true;
            skillDef.dontAllowPastMaxStocks       = false;
            skillDef.beginSkillCooldownOnSkillEnd = true;
            skillDef.cancelSprintingOnActivation  = true;
            skillDef.forceSprintDuringState       = false;
            skillDef.canceledFromSprinting        = false;
            skillDef.isCombatSkill                = true;
            skillDef.mustKeyPress                 = false;
            skillDef.stepCount         = 2;
            skillDef.stepGraceDuration = 0.1f;

            //load vanilla assets
            var mainMtl = Addressables.LoadAssetAsync <Material>("RoR2/Base/Engi/matEngiTurret.mat")
                          .WaitForCompletion();
            var tracerMtl = Addressables.LoadAssetAsync <Material>("RoR2/Base/Common/VFX/matTracerBrightTransparent.mat")
                            .WaitForCompletion();
            var muzzleEffectPrefab = Addressables.LoadAssetAsync <GameObject>("RoR2/Base/Common/VFX/MuzzleflashSmokeRing.prefab")
                                     .WaitForCompletion();
            var explosionEffectPrefab = Addressables.LoadAssetAsync <GameObject>("RoR2/Base/Engi/EngiGrenadeExplosion.prefab")
                                        .WaitForCompletion();
            var shrapnelHitEffectPrefab = Addressables.LoadAssetAsync <GameObject>("RoR2/Base/Commando/HitsparkCommando.prefab")
                                          .WaitForCompletion();

            targetSkillFamily = Addressables.LoadAssetAsync <SkillFamily>("RoR2/Base/Engi/EngiBodyPrimaryFamily.asset")
                                .WaitForCompletion();

            //modify
            projectilePrefab.GetComponent <ProjectileSimple>().lifetimeExpiredEffect  = explosionEffectPrefab;
            projectilePrefab.GetComponent <ProjectileOverlapAttack>().impactEffect    = shrapnelHitEffectPrefab;
            subProjectilePrefab.GetComponent <ProjectileOverlapAttack>().impactEffect = shrapnelHitEffectPrefab;

            projectileGhost.GetComponent <MeshRenderer>().material = mainMtl;
            subProjectileGhost.transform.Find("SpikeModel").GetComponent <MeshRenderer>().material = mainMtl;
            subProjectileGhost.transform.Find("Trail").GetComponent <TrailRenderer>().material     = tracerMtl;

            FireContinuous.projectilePrefab = projectilePrefab;
            FireContinuous.effectPrefab     = muzzleEffectPrefab;

            //R2API catalog reg
            skillDef.activationState = ContentAddition.AddEntityState <FireContinuous>(out bool entStateDidSucceed);
            ContentAddition.AddProjectile(projectilePrefab);
            ContentAddition.AddProjectile(subProjectilePrefab);

            if (!entStateDidSucceed)
            {
                TinkersSatchelPlugin._logger.LogError("EntityState setup failed on EngiPrimaryFlak! Skill will not appear nor function.");
            }
            else if (!ContentAddition.AddSkillDef(skillDef))
            {
                TinkersSatchelPlugin._logger.LogError("SkillDef setup failed on EngiPrimaryFlak! Skill will not appear nor function.");
            }
            else
            {
                setupSucceeded = true;
            }
        }