Exemplo n.º 1
0
        public override void SetupAttributes()
        {
            base.SetupAttributes();
            rewindStateType = ContentAddition.AddEntityState <RewindState>(out _);
            R2API.Networking.NetworkingAPI.RegisterMessageType <MsgRewind>();

            blacklistedSkills = new[] {
                LegacyResourcesAPI.Load <RoR2.Skills.SkillDef>("SkillDefs/CaptainBody/CallSupplyDropHealing"),
                LegacyResourcesAPI.Load <RoR2.Skills.SkillDef>("SkillDefs/CaptainBody/CallSupplyDropHacking"),
                LegacyResourcesAPI.Load <RoR2.Skills.SkillDef>("SkillDefs/CaptainBody/CallSupplyDropShocking"),
                LegacyResourcesAPI.Load <RoR2.Skills.SkillDef>("SkillDefs/CaptainBody/CallSupplyDropEquipmentRestock"),
                LegacyResourcesAPI.Load <RoR2.Skills.SkillDef>("SkillDefs/CaptainBody/CaptainSkillUsedUp"),
                LegacyResourcesAPI.Load <RoR2.Skills.SkillDef>("SkillDefs/CaptainBody/CaptainCancelDummy")
            };

            rewindBuff            = ScriptableObject.CreateInstance <BuffDef>();
            rewindBuff.buffColor  = Color.white;
            rewindBuff.canStack   = true;
            rewindBuff.isDebuff   = false;
            rewindBuff.isCooldown = true;
            rewindBuff.name       = "TKSATRewind";
            rewindBuff.iconSprite = TinkersSatchelPlugin.resources.LoadAsset <Sprite>("Assets/TinkersSatchel/Textures/MiscIcons/rewindBuffIcon.png");
            ContentAddition.AddBuffDef(rewindBuff);

            if (Compat_ClassicItems.enabled)
            {
                LanguageAPI.Add("TKSAT_REWIND_CI_EMBRYO_APPEND", "\n<style=cStack>Beating Embryo: 50% chance to not consume stock.</style>");
                Compat_ClassicItems.RegisterEmbryoHook(equipmentDef, "TKSAT_REWIND_CI_EMBRYO_APPEND", () => "TKSAT.CausalCamera");
            }
        }
Exemplo n.º 2
0
        protected override bool PerformEquipmentAction(EquipmentSlot slot)
        {
            if (!slot || !slot.characterBody)
            {
                return(false);
            }
            var cpt = slot.characterBody.GetComponent <RewindComponent>();

            if (!cpt || cpt.frames.Count == 0)
            {
                return(false);
            }
            var esm = EntityStateMachine.FindByCustomName(slot.characterBody.gameObject, "Body");

            if (esm == null || esm.state is RewindState)
            {
                return(false);
            }
            new MsgRewind(slot.characterBody).Send(R2API.Networking.NetworkDestination.Clients);
            if (Compat_ClassicItems.enabled)
            {
                if (Util.CheckRoll(Mathf.Pow(0.5f, Compat_ClassicItems.CheckEmbryoProc(slot, equipmentDef)) * 100f))
                {
                    return(false);
                }
            }
            return(true);
        }
Exemplo n.º 3
0
        public override void SetupAttributes()
        {
            base.SetupAttributes();

            var nSpriteD = TinkersSatchelPlugin.resources.LoadAsset <Sprite>("Assets/TinkersSatchel/Textures/packBoxArrowDown.png");
            var nSpriteU = TinkersSatchelPlugin.resources.LoadAsset <Sprite>("Assets/TinkersSatchel/Textures/packBoxArrowUp.png");

            var recy = LegacyResourcesAPI.Load <GameObject>("Prefabs/RecyclerIndicator").InstantiateClone("temporary setup prefab", false);

            foreach (var spr in recy.GetComponentsInChildren <SpriteRenderer>())
            {
                if (spr.sprite.name != "texRecyclerArrow")
                {
                    continue;
                }
                spr.sprite = nSpriteD;
            }
            placeIndicatorPrefab = recy.InstantiateClone("TkSatPackBoxPlaceIndicator", false);
            GameObject.Destroy(recy);

            recy = LegacyResourcesAPI.Load <GameObject>("Prefabs/RecyclerIndicator").InstantiateClone("temporary setup prefab", false);
            foreach (var spr in recy.GetComponentsInChildren <SpriteRenderer>())
            {
                if (spr.sprite.name != "texRecyclerArrow")
                {
                    continue;
                }
                spr.sprite = nSpriteU;
            }
            packIndicatorPrefab = recy.InstantiateClone("TkSatPackBoxPackIndicator", false);
            GameObject.Destroy(recy);

            recy = LegacyResourcesAPI.Load <GameObject>("Prefabs/RecyclerBadIndicator").InstantiateClone("temporary setup prefab", false);
            foreach (var spr in recy.GetComponentsInChildren <SpriteRenderer>())
            {
                if (spr.sprite.name != "texRecyclerArrow")
                {
                    continue;
                }
                spr.sprite = nSpriteD;
            }
            placeIndicatorBadPrefab = recy.InstantiateClone("TkSatPackBoxPlaceBadIndicator", false);
            GameObject.Destroy(recy);

            R2API.Networking.NetworkingAPI.RegisterMessageType <MsgPackboxPack>();
            R2API.Networking.NetworkingAPI.RegisterMessageType <MsgPackboxPlace>();

            if (Compat_ClassicItems.enabled)
            {
                LanguageAPI.Add("TKSAT_PACKBOX_CI_EMBRYO_APPEND", "\n<style=cStack>Beating Embryo: 50% chance to not consume stock on place.</style>");
                Compat_ClassicItems.RegisterEmbryoHook(equipmentDef, "TKSAT_PACKBOX_CI_EMBRYO_APPEND", () => "TKSAT.CardboardBox");
            }
        }
Exemplo n.º 4
0
        public override void SetupAttributes()
        {
            base.SetupAttributes();

            droneMasterPrefabNames.UnionWith(masterNamesConfig.Split(',')
                                             .Select(x => x.Trim()));

            if (Compat_ClassicItems.enabled)
            {
                LanguageAPI.Add("TKSAT_REVIVEONCE_CI_EMBRYO_APPEND", "\n<style=cStack>Beating Embryo: Activates twice simultaneously.</style>");
                Compat_ClassicItems.RegisterEmbryoHook(equipmentDef, "TKSAT_REVIVEONCE_CI_EMBRYO_APPEND", () => "TKSAT.CommandTerminal");
            }
        }
Exemplo n.º 5
0
        protected override bool PerformEquipmentAction(EquipmentSlot slot)
        {
            var cpt = slot.characterBody.GetComponent <PackBoxTracker>();

            if (!cpt)
            {
                cpt = slot.characterBody.gameObject.AddComponent <PackBoxTracker>();
            }

            if (cpt.packedObject == null)
            {
                if (slot.currentTarget.rootObject && validObjectNames.Contains(slot.currentTarget.rootObject.name))
                {
                    var shopcpt = slot.currentTarget.rootObject.GetComponent <ShopTerminalBehavior>();
                    if (shopcpt && shopcpt.serverMultiShopController)
                    {
                        slot.currentTarget.rootObject = shopcpt.serverMultiShopController.transform.root.gameObject;
                    }

                    var pbh = slot.currentTarget.rootObject.GetComponent <PackBoxHandler>();
                    if (!pbh)
                    {
                        pbh = slot.currentTarget.rootObject.AddComponent <PackBoxHandler>();
                    }

                    pbh.TryPackServer(cpt);

                    return(false);
                }
            }
            else
            {
                var pbh = cpt.packedObject.GetComponent <PackBoxHandler>();
                if (!pbh)
                {
                    TinkersSatchelPlugin._logger.LogError("PackBoxTracker contains GameObject with no PackBoxHandler");
                    return(false);
                }
                if (TryGetBoxablePlacePos(slot.GetAimRay(), out Vector3 placeLoc, out _))
                {
                    var didPlace = pbh.TryPlaceServer(cpt, placeLoc);
                    if (Compat_ClassicItems.enabled)
                    {
                        if (didPlace && Util.CheckRoll(Mathf.Pow(0.5f, Compat_ClassicItems.CheckEmbryoProc(slot, equipmentDef)) * 100f))
                        {
                            return(false);
                        }
                    }
                    return(didPlace);
                }
Exemplo n.º 6
0
        ////// Hooks //////

        protected override bool PerformEquipmentAction(EquipmentSlot slot)
        {
            var retv = PerformEquipmentActionInternal(slot);

            if (Compat_ClassicItems.enabled)
            {
                var count = Compat_ClassicItems.CheckEmbryoProc(slot, equipmentDef);
                for (var i = 0; i < count; i++)
                {
                    retv |= PerformEquipmentActionInternal(slot);
                }
            }
            return(retv);
        }
Exemplo n.º 7
0
        void PullObjects(EquipmentSlot slot)
        {
            float range = objectRange;

            if (Compat_ClassicItems.enabled)
            {
                range *= 1f + (float)Compat_ClassicItems.CheckEmbryoProc(slot, equipmentDef);
            }

            var rbObjectsInRange = Physics.OverlapSphere(slot.characterBody.corePosition, range, Physics.AllLayers, QueryTriggerInteraction.Collide)
                                   .Select(x => x.gameObject)
                                   .Where(x => validObjectNamesRB.Contains(x.name))
                                   .Select(x => x.GetComponent <Rigidbody>())
                                   .Where(x => x);
            var nonRbObjectsInRange = GameObject.FindObjectsOfType <GameObject>() //TODO: add colliders to all of these prefabs
                                      .Where(x => validObjectNamesNoRB.Contains(x.name) &&
                                             Vector3.Distance(x.transform.position, slot.characterBody.corePosition) < range);

            foreach (var rb in rbObjectsInRange)
            {
                var sticky = rb.gameObject.GetComponent <RoR2.Projectile.ProjectileStickOnImpact>();
                if (sticky)
                {
                    sticky.Detach();
                    sticky.enabled = false;
                }

                var velVec = slot.characterBody.transform.position - rb.transform.position;

                if (rb.useGravity && !rb.gameObject.name.Contains("TkSatPixie"))
                {
                    var(vInitial, tFinal) = MiscUtil.CalculateVelocityForFinalPosition(rb.transform.position, slot.characterBody.transform.position, 1f);
                    velVec = vInitial;
                }
                else
                {
                    velVec.Normalize();
                    velVec *= PULL_FORCE;
                }
                rb.AddForce(velVec - rb.velocity, ForceMode.VelocityChange);
            }

            foreach (var nrb in nonRbObjectsInRange)
            {
                nrb.transform.position = slot.characterBody.corePosition;
            }
        }
Exemplo n.º 8
0
        void PullEnemies(EquipmentSlot slot)
        {
            float range  = enemyRange;
            float damage = slot.characterBody.damage * baseDamageFrac;

            if (Compat_ClassicItems.enabled)
            {
                var fac = 1f + (float)Compat_ClassicItems.CheckEmbryoProc(slot, equipmentDef);
                range  *= fac;
                damage *= fac;
            }

            var  teamMembers = new List <TeamComponent>();
            bool isFF        = FriendlyFireManager.friendlyFireMode != FriendlyFireManager.FriendlyFireMode.Off;
            var  scan        = ((TeamIndex[])Enum.GetValues(typeof(TeamIndex)));
            var  myTeam      = TeamComponent.GetObjectTeam(slot.characterBody.gameObject);

            foreach (var ind in scan)
            {
                if (isFF || myTeam != ind)
                {
                    teamMembers.AddRange(TeamComponent.GetTeamMembers(ind));
                }
            }
            teamMembers.Remove(slot.characterBody.teamComponent);
            float sqrad = range * range;

            foreach (TeamComponent tcpt in teamMembers)
            {
                var velVec = slot.characterBody.transform.position - tcpt.transform.position;
                if (velVec.sqrMagnitude <= sqrad && tcpt.body && !tcpt.body.isBoss && !tcpt.body.isChampion && tcpt.body.isActiveAndEnabled)
                {
                    var(vInitial, _) = MiscUtil.CalculateVelocityForFinalPosition(tcpt.transform.position, slot.characterBody.transform.position, 1f);
                    var mcpt = tcpt.body.GetComponent <IPhysMotor>();
                    tcpt.body.healthComponent.TakeDamage(new DamageInfo {
                        attacker         = slot.characterBody.gameObject,
                        crit             = slot.characterBody.RollCrit(),
                        damage           = damage,
                        damageColorIndex = DamageColorIndex.Default,
                        damageType       = DamageType.Generic | DamageType.AOE,
                        canRejectForce   = false,
                        force            = (vInitial - ((mcpt != null) ? mcpt.velocity : Vector3.zero)) * ((mcpt != null) ? mcpt.mass : 1f),
                        position         = tcpt.body.corePosition,
                        procChainMask    = default,
Exemplo n.º 9
0
        public override void SetupAttributes()
        {
            base.SetupAttributes();

            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/recombobulatorIcon.png");
            ContentAddition.AddUnlockableDef(unlockable);
            LanguageAPI.Add(achiNameToken, "Risktaker");
            LanguageAPI.Add(achiDescToken, "Recycle a rare or boss item.");
            equipmentDef.unlockableDef = unlockable;

            if (Compat_ClassicItems.enabled)
            {
                LanguageAPI.Add("TKSAT_RECOMBOBULATOR_CI_EMBRYO_APPEND", "\n<style=cStack>Beating Embryo: Roll twice and choose the rarer result.</style>");
                Compat_ClassicItems.RegisterEmbryoHook(equipmentDef, "TKSAT_RECOMBOBULATOR_CI_EMBRYO_APPEND", () => "TKSAT.QuantumRecombobulator");
            }
        }
Exemplo n.º 10
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.");
                }
            }
        }
Exemplo n.º 11
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");
            }
        }
Exemplo n.º 12
0
        protected override bool PerformEquipmentAction(EquipmentSlot slot)
        {
            if (slot.currentTarget.rootObject &&
                validObjectNames.Contains(slot.currentTarget.rootObject.name) &&
                !slot.currentTarget.rootObject.GetComponent <RecombobulatorFlag>() &&
                mostRecentDeck != null &&
                Run.instance)
            {
                var oldPurch = slot.currentTarget.rootObject.GetComponent <PurchaseInteraction>();
                if (oldPurch)
                {
                    if (!oldPurch.available)
                    {
                        return(false);
                    }
                }

                var shopcpt = slot.currentTarget.rootObject.GetComponent <ShopTerminalBehavior>();
                if (shopcpt && shopcpt.serverMultiShopController)
                {
                    slot.currentTarget.rootObject = shopcpt.serverMultiShopController.transform.root.gameObject;
                    foreach (var term in shopcpt.serverMultiShopController.terminalGameObjects)
                    {
                        GameObject.Destroy(term);
                    }
                }

                GameObject.Destroy(slot.currentTarget.rootObject);

                var pos = slot.currentTarget.rootObject.transform.position;

                WeightedSelection <DirectorCard> filteredDeck = new WeightedSelection <DirectorCard>(8);
                for (var i = 0; i < mostRecentDeck.Count; i++)
                {
                    var card = mostRecentDeck.GetChoice(i);
                    if (card.value != null && card.value.IsAvailable() && (validObjectNames.Contains(card.value.spawnCard.prefab.name) || validObjectNames.Contains(card.value.spawnCard.prefab.name + "(Clone)")))
                    {
                        filteredDeck.AddChoice(card);
                    }
                }
                if (filteredDeck.Count == 0)
                {
                    return(false);
                }

                var draw = filteredDeck.Evaluate(rng.nextNormalizedFloat);

                if (Compat_ClassicItems.enabled)
                {
                    var rerolls = Compat_ClassicItems.CheckEmbryoProc(slot, equipmentDef);
                    for (var i = 0; i < rerolls; i++)
                    {
                        var draw2 = filteredDeck.Evaluate(rng.nextNormalizedFloat);
                        if (draw2.selectionWeight < draw.selectionWeight)
                        {
                            draw = draw2;
                        }
                    }
                }

                var obj = DirectorCore.instance.TrySpawnObject(
                    new DirectorSpawnRequest(
                        draw.spawnCard,
                        new DirectorPlacementRule {
                    placementMode   = DirectorPlacementRule.PlacementMode.Direct,
                    position        = pos,
                    preventOverhead = false
                },
                        this.rng
                        ));
                if (!obj)
                {
                    TinkersSatchelPlugin._logger.LogError("Recombobulator failed to replace interactable!");
                    return(false);
                }
                var purch = obj.GetComponent <PurchaseInteraction>();
                if (purch && purch.costType == CostTypeIndex.Money)
                {
                    purch.Networkcost = Run.instance.GetDifficultyScaledCost(purch.cost);
                }
                obj.AddComponent <RecombobulatorFlag>();

                var shopcpt2 = obj.GetComponent <MultiShopController>();
                if (shopcpt2)
                {
                    foreach (var term in shopcpt2.terminalGameObjects)
                    {
                        term.AddComponent <RecombobulatorFlag>();
                    }
                }

                return(true);
            }
            return(false);
        }