// Copy from TeleporterHelper, but uses a different strategy so they don't spawn on top of the person
        public static Vector3?FindSafeTeleportDestination(Vector3 characterFootPosition, CharacterBody characterBodyOrPrefabComponent, Xoroshiro128Plus rng)
        {
            Vector3?  result    = null;
            SpawnCard spawnCard = ScriptableObject.CreateInstance <SpawnCard>();

            spawnCard.hullSize = characterBodyOrPrefabComponent.hullClassification;
            //spawnCard.nodeGraphType = MapNodeGroup.GraphType.Ground;
            spawnCard.prefab = Resources.Load <GameObject>("SpawnCards/HelperPrefab");
            DirectorPlacementRule placementRule = new DirectorPlacementRule
            {
                placementMode = DirectorPlacementRule.PlacementMode.Approximate,
                position      = characterFootPosition
            };

            DirectorCore.GetMonsterSpawnDistance(DirectorCore.MonsterSpawnDistance.Close,
                                                 out placementRule.minDistance, out placementRule.maxDistance);
            GameObject gameObject = DirectorCore.instance.TrySpawnObject(new DirectorSpawnRequest(spawnCard, placementRule, rng));

            if (gameObject)
            {
                result = new Vector3?(gameObject.transform.position);
                Destroy(gameObject);
            }
            Destroy(spawnCard);
            return(result);
        }
Exemple #2
0
        private static void CreateEclipseDoppelganger(CharacterMaster master, Xoroshiro128Plus rng)
        {
            var card = DoppelgangerSpawnCard.FromMaster(master);

            if (card is null)
            {
                return;
            }
            if (card.prefab is null)
            {
                card.prefab = MasterCatalog.GetMasterPrefab(defaultMasterIndex);
            }

            Transform spawnOnTarget;

            DirectorCore.MonsterSpawnDistance input;
            if (TeleporterInteraction.instance)
            {
                spawnOnTarget = TeleporterInteraction.instance.transform;
                input         = DirectorCore.MonsterSpawnDistance.Close;
            }
            else
            {
                spawnOnTarget = master.GetBody().coreTransform;
                input         = DirectorCore.MonsterSpawnDistance.Far;
            }
            DirectorPlacementRule directorPlacementRule = new DirectorPlacementRule
            {
                spawnOnTarget = spawnOnTarget,
                placementMode = DirectorPlacementRule.PlacementMode.NearestNode
            };

            DirectorCore.GetMonsterSpawnDistance(input, out directorPlacementRule.minDistance, out directorPlacementRule.maxDistance);
            DirectorSpawnRequest directorSpawnRequest = new DirectorSpawnRequest(card, directorPlacementRule, rng);

            directorSpawnRequest.teamIndexOverride     = new TeamIndex?(TeamIndex.Monster);
            directorSpawnRequest.ignoreTeamMemberLimit = true;

            CombatSquad squad = null;

            DirectorSpawnRequest directorSpawnRequest2 = directorSpawnRequest;

            directorSpawnRequest2.onSpawnedServer = DelegateHelper.Combine(directorSpawnRequest2.onSpawnedServer, (res) =>
            {
                if (squad is null)
                {
                    squad = UnityEngine.Object.Instantiate <GameObject>(Resources.Load <GameObject>("Prefabs/NetworkedObjects/Encounters/ShadowCloneEncounter")).GetComponent <CombatSquad>();
                }
                squad.AddMember(res.spawnedInstance.GetComponent <CharacterMaster>());
            });

            DirectorCore.instance.TrySpawnObject(directorSpawnRequest);

            if (squad is not null)
            {
                NetworkServer.Spawn(squad.gameObject);
            }
            UnityEngine.Object.Destroy(card);
        }
Exemple #3
0
        /// <summary>
        /// Removes all NodeGraph nodes that a given GameObject occupies. See the NodeOccupationInfo component.
        /// </summary>
        /// <param name="self">The DirectorCore to perform NodeGraph operations with.</param>
        /// <param name="obj">The GameObject to remove linked nodes with.</param>
        /// <returns>True if no known nodes remain registered to the GameObject after execution; false otherwise.</returns>
        public static bool RemoveAllOccupiedNodes(this DirectorCore self, GameObject obj)
        {
            var cpt = obj.GetComponent <NodeOccupationInfo>();

            if (!cpt)
            {
                return(true);
            }
            cpt._indices.RemoveAll(i => self.RemoveOccupiedNode(i.Key, i.Value));
            return(cpt._indices.Count == 0);
        }
 GameObject TrySpawnObject(On.RoR2.DirectorCore.orig_TrySpawnObject orig, DirectorCore directorCore, DirectorSpawnRequest directorSpawnRequest)
 {
     if (directorSpawnRequest.spawnCard.name == "iscScavBackpack")
     {
         if (playerInteractables.interactablesInvalid.Contains("ScavBackpack"))
         {
             return(null);
         }
     }
     return(orig(directorCore, directorSpawnRequest));
 }
Exemple #5
0
        /// <summary>
        /// Transfers NodeOccupationInfo from one object to another. For use while destroying a GameObject and creating another one in its place (e.g. runtime replacement of a placeholder with an unknown prefab).
        /// </summary>
        /// <param name="self">The DirectorCore to perform NodeGraph operations with.</param>
        /// <param name="oldObj">The to-dispose object to retrieve NodeGraph info from.</param>
        /// <param name="newObj">The new object to add NodeGraph info to.</param>
        public static void UpdateOccupiedNodesReference(this DirectorCore self, GameObject oldObj, GameObject newObj)
        {
            var oldcpt = oldObj.GetComponent <NodeOccupationInfo>();
            var newcpt = newObj.GetComponent <NodeOccupationInfo>();

            if (!oldcpt || newcpt)
            {
                return;
            }
            newcpt = newObj.AddComponent <NodeOccupationInfo>();
            newcpt._indices.AddRange(oldcpt._indices);
        }
Exemple #6
0
        /// <summary>
        /// Removes a node from a NodeGraph. See the NodeOccupationInfo component.
        /// </summary>
        /// <param name="self">The DirectorCore to perform NodeGraph operations with.</param>
        /// <param name="nodeGraph">The NodeGraph to remove nodes from.</param>
        /// <param name="nodeIndex">The NodeIndex within the given NodeGraph to remove.</param>
        /// <returns>True on successful removals; false otherwise.</returns>
        public static bool RemoveOccupiedNode(this DirectorCore self, NodeGraph nodeGraph, NodeGraph.NodeIndex nodeIndex)
        {
            var oldLen = self.occupiedNodes.Length;

            self.occupiedNodes = self.occupiedNodes.Where(x => x.nodeGraph != nodeGraph || x.nodeIndex != nodeIndex).ToArray();

            if (oldLen == self.occupiedNodes.Length)
            {
                TILER2Plugin._logger.LogWarning("RemoveOccupiedNode was passed an already-removed or otherwise nonexistent node");
                return(false);
            }
            return(true);
        }
Exemple #7
0
        // Token: 0x06002C5A RID: 11354 RVA: 0x000BB35C File Offset: 0x000B955C
        private void AttemptDropPack()
        {
            DirectorCore instance = DirectorCore.instance;

            if (instance)
            {
                Xoroshiro128Plus      rng           = new Xoroshiro128Plus((ulong)Run.instance.stageRng.nextUint);
                DirectorPlacementRule placementRule = new DirectorPlacementRule
                {
                    placementMode = DirectorPlacementRule.PlacementMode.NearestNode,
                    position      = base.characterBody.footPosition,
                    minDistance   = 0f,
                    maxDistance   = float.PositiveInfinity
                };
                instance.TrySpawnObject(new DirectorSpawnRequest(this.spawnCard, placementRule, rng));
            }
        }
Exemple #8
0
        private GameObject OverrideTeamSpawn(On.RoR2.DirectorCore.orig_TrySpawnObject orig, DirectorCore self, DirectorSpawnRequest directorSpawnRequest)
        {
            if (directorSpawnRequest.spawnCard && directorSpawnRequest.spawnCard.prefab)
            {
                var characterMaster = directorSpawnRequest.spawnCard.prefab.GetComponent <CharacterMaster>();
                if (characterMaster)
                {
                    var bodyIndex = characterMaster.bodyPrefab.GetComponent <CharacterBody>().bodyIndex;
                    if (bodyIndex_to_teamIndex.TryGetValue(bodyIndex, out TeamIndex teamIndex))
                    {
                        //_logger.LogMessage($"Overriding teamIndex to {teamIndex}");
                        directorSpawnRequest.teamIndexOverride = teamIndex;
                    }
                }
            }
            var original = orig(self, directorSpawnRequest);

            return(original);
        }
        public bool AttemptSpawnOnTarget(On.RoR2.CombatDirector.orig_AttemptSpawnOnTarget orig, CombatDirector self, Transform spawnTarget, DirectorPlacementRule.PlacementMode placementMode)
        {
            //this.GetComponent< behaviourName as MonoBehaviour>



            if (self.gameObject == this.gameObject)
            {
                var credit       = self.monsterCredit;
                var monsterCards = self.monsterCards;


                //MoreShrines.Print("We good?");


                if (!this.cardPoolInitialized)
                {
                    List <CardPool> cardPools = new List <CardPool>();

                    foreach (var category in monsterCards.categories)
                    {
                        foreach (var card in category.cards)
                        {
                            if (cardPools.Any(pool => pool.cost == card.cost))
                            {
                                cardPools.Find(pool => pool.cost == card.cost).cards.Add(card);
                            }
                            else
                            {
                                var pool = new CardPool();
                                pool.cost = card.cost;
                                pool.cards.Add(card);
                                cardPools.Add(pool);
                            }
                        }
                    }
                    cardPoolInitialized = true;
                    cardPools.Sort((item1, item2) => { return(item1.cost.CompareTo(item2.cost)); });


                    var poolIndex = 0;

                    CardPool currentBasePool = cardPools[0];

                    foreach (var pool in cardPools)
                    {
                        if (pool.cost * countToSpawn < credit)
                        {
                            currentBasePool = pool;
                        }
                        else
                        {
                            break;
                        }
                        poolIndex++;
                    }

                    MoreShrines.Print("Preparing to spawn " + countToSpawn + " monsters.");

                    CardPool buffPool = cardPools[0];

                    var buffCount = 0;
                    for (var i = 0; i < countToSpawn; i++)
                    {
                        var count = countToSpawn - i;

                        if (cardPools.Count > poolIndex + 1)
                        {
                            if (((countToSpawn - count) * currentBasePool.cost) + (count * cardPools[poolIndex + 1].cost) < credit)
                            {
                                buffPool = cardPools[poolIndex + 1];
                                buffCount++;
                            }
                        }
                    }

                    for (var i = 0; i < countToSpawn - buffCount; i++)
                    {
                        finalSpawnOrder.Add(currentBasePool);
                    }

                    for (var i = 0; i < buffCount; i++)
                    {
                        finalSpawnOrder.Add(buffPool);
                    }
                }

                //

                if (finalSpawnOrder.Count > 0)
                {
                    self.currentMonsterCard = finalSpawnOrder[0].cards[Random.Range(0, finalSpawnOrder[0].cards.Count - 1)];
                    SpawnCard             spawnCard             = self.currentMonsterCard.spawnCard;
                    DirectorPlacementRule directorPlacementRule = new DirectorPlacementRule
                    {
                        placementMode   = placementMode,
                        spawnOnTarget   = spawnTarget,
                        preventOverhead = self.currentMonsterCard.preventOverhead
                    };
                    DirectorCore.GetMonsterSpawnDistance(self.currentMonsterCard.spawnDistance, out directorPlacementRule.minDistance, out directorPlacementRule.maxDistance);
                    directorPlacementRule.minDistance *= self.spawnDistanceMultiplier;
                    DirectorSpawnRequest directorSpawnRequest = new DirectorSpawnRequest(spawnCard, directorPlacementRule, self.rng);
                    directorSpawnRequest.ignoreTeamMemberLimit = self.ignoreTeamSizeLimit;
                    directorSpawnRequest.teamIndexOverride     = new TeamIndex?(self.teamIndex);
                    directorSpawnRequest.onSpawnedServer       = new Action <SpawnCard.SpawnResult>(onCardSpawned);
                    if (!DirectorCore.instance.TrySpawnObject(directorSpawnRequest))
                    {
                        /*
                         * Debug.LogFormat("Spawn card {0} failed to spawn. Aborting cost procedures.", new object[]
                         * {
                         * spawnCard
                         * });*/
                        self.enabled = false;
                        return(false);
                    }
                }
                else
                {
                    self.enabled = false;
                    return(false);
                }


                self.spawnCountInCurrentWave += 1;

                return(true);
            }
            else
            {
                return(orig(self, spawnTarget, placementMode));
            }
        }
Exemple #10
0
        public void Awake()//Code that runs when the game starts
        {
            string[] interactables     = { "iscBrokenDrone1", "iscBrokenDrone2", "iscBrokenMegaDrone", "iscBrokenMissileDrone", "iscBrokenTurret1", "iscBarrel1", "iscEquipmentBarrel", "iscLockbox", "iscChest1", "iscChest1Stealthed", "iscChest2", "iscGoldChest", "iscTripleShop", "iscTripleShopLarge", "iscDuplicator", "iscDuplicatorLarge", "iscDuplicatorMilitary", "iscShrineCombat", "iscShrineBoss", "iscShrineBlood", "iscShrineChance", "iscShrineHealing", "iscShrineRestack", "iscShrineGoldshoresAccess", "iscRadarTower", "iscTeleporter", "iscShopPortal", "iscMSPortal", "iscGoldshoresPortal", "iscGoldshoresBeacon" };
            string[] interactableNames = { "Gunner Drone", "Healing Drone", "Prototype Drone", "Missile Drone", "Broken Turret", "Barrel", "Equipment Barrel", "Rusty Lockbox", "Chest", "Stealthed Chest", "Large Chest", "Legendary Chest", "Triple Shop", "Triple Shop (Red and Green)", "3D Printer", "Large Printer (Green)", "Mili-tech Printer (Red)", "Shrine of Combat", "Shrine of the Mountain", "Shrine of Blood", "Shrine of Chance", "Shrine of the Forest", "Shrine of Order", "Gold Shrine", "Radar", "Teleporter", "Blue Portal", "Celestial Portal", "Gold Portal", "Halycon Beacon" };

            var addRule     = typeof(RuleCatalog).GetMethod("AddRule", BindingFlags.Static | BindingFlags.NonPublic, null, new Type[] { typeof(RuleDef) }, null);
            var addCategory = typeof(RuleCatalog).GetMethod("AddCategory", BindingFlags.Static | BindingFlags.NonPublic, null, new Type[] { typeof(string), typeof(Color), typeof(string), typeof(Func <bool>) }, null);


            addCategory.Invoke(null, new object[] { "Interactables", new Color(219 / 255, 182 / 255, 19 / 255, byte.MaxValue), "", new Func <bool>(() => false) });
            RuleDef iscruleDef3 = new RuleDef("FloodWarning.InteractableScale", "Total interactable scale");

            for (int i = 0; i < 12; i++)
            {
                float myNum = (float)(Math.Pow(2f, i)) / 4f;
                if (i == 0)
                {
                    RuleChoiceDef tempRule = iscruleDef3.AddChoice("0", 0f, false);
                    tempRule.spritePath       = "Textures/MiscIcons/texRuleBonusStartingMoney";
                    tempRule.tooltipNameToken = "" + 0f + "x Interactable spawns";
                    tempRule.tooltipBodyToken = "" + 0f + "x The amount of interactables (Shrines, Chests, Buyable drones and turrets) will appear in the world";
                }

                RuleChoiceDef myRule = iscruleDef3.AddChoice("0", myNum, false);
                if (myNum == 1)
                {
                    iscruleDef3.MakeNewestChoiceDefault();
                }
                myRule.spritePath       = "Textures/MiscIcons/texRuleBonusStartingMoney";
                myRule.tooltipNameToken = "" + myNum + "x Interactable spawns";
                myRule.tooltipBodyToken = "" + myNum + "x The amount of interactables (Shrines, Chests, Buyable drones and turrets) will appear in the world";
            }
            addRule.Invoke(null, new object[] { iscruleDef3 });

            addCategory.Invoke(null, new object[] { "Weighted Selections", new Color(94 / 255, 82 / 255, 30 / 255, byte.MaxValue), "", new Func <bool>(() => false) });
            for (int i = 0; i < interactables.Length; i++)
            {
                RuleDef ChanceRule = new RuleDef("FloodWarning." + interactables[i] + "Chance", "Chance");

                for (int o = 0; o < 8; o++)
                {
                    float myNum = (float)(Math.Pow(2f, o)) / 4f;
                    if (o == 0)
                    {
                        RuleChoiceDef tempRule = ChanceRule.AddChoice("0", 0f, false);
                        tempRule.spritePath       = "Textures/MiscIcons/texRuleBonusStartingMoney";
                        tempRule.tooltipNameToken = "0x Chance of " + interactableNames[i];
                        tempRule.tooltipBodyToken = "0x Chance that a given spawned interactable will be of type '" + interactableNames[i] + "'";
                        switch (interactables[i])
                        {
                        case "iscBrokenDrone1":
                            tempRule.spritePath = "Textures/MiscIcons/texRuleBonusStartingMoney";
                            break;

                        case "iscBrokenDrone2":
                            tempRule.spritePath = "Textures/MiscIcons/texRuleBonusStartingMoney";
                            break;

                        case "iscBrokenMegaDrone":
                            tempRule.spritePath = "Textures/MiscIcons/texRuleBonusStartingMoney";
                            break;

                        case "iscBrokenMissileDrone":
                            tempRule.spritePath = "Textures/MiscIcons/texRuleBonusStartingMoney";
                            break;

                        case "iscBrokenTurret1":
                            tempRule.spritePath = "Textures/MiscIcons/texRuleBonusStartingMoney";
                            break;

                        case "iscBarrel1":
                            tempRule.spritePath = "Textures/MiscIcons/texRuleBonusStartingMoney";
                            break;

                        case "iscEquipmentBarrel":
                            tempRule.spritePath = "Textures/MiscIcons/texRuleBonusStartingMoney";
                            break;

                        case "iscLockbox":
                            tempRule.spritePath = "Textures/MiscIcons/texRuleBonusStartingMoney";
                            break;

                        case "iscChest1":
                            tempRule.spritePath = "Textures/MiscIcons/texRuleBonusStartingMoney";
                            break;

                        case "iscChest1Stealthed":
                            tempRule.spritePath = "Textures/MiscIcons/texRuleBonusStartingMoney";
                            break;

                        case "iscChest2":
                            tempRule.spritePath = "Textures/MiscIcons/texRuleBonusStartingMoney";
                            break;

                        case "iscGoldChest":
                            tempRule.spritePath = "Textures/MiscIcons/texRuleBonusStartingMoney";
                            break;

                        case "iscTripleShop":
                            tempRule.spritePath = "Textures/MiscIcons/texRuleBonusStartingMoney";
                            break;

                        case "iscTripleShopLarge":
                            tempRule.spritePath = "Textures/MiscIcons/texRuleBonusStartingMoney";
                            break;

                        case "iscDuplicator":
                            tempRule.spritePath = "Textures/MiscIcons/texRuleBonusStartingMoney";
                            break;

                        case "iscDuplicatorLarge":
                            tempRule.spritePath = "Textures/MiscIcons/texRuleBonusStartingMoney";
                            break;

                        case "iscDuplicatorMilitary":
                            tempRule.spritePath = "Textures/MiscIcons/texRuleBonusStartingMoney";
                            break;

                        case "iscShrineCombat":
                            tempRule.spritePath = "Textures/shrinesymbols/texshrinecombatsymbol";
                            break;

                        case "iscShrineBoss":
                            tempRule.spritePath = "Textures/shrinesymbols/texshrinebosssymbole";
                            break;

                        case "iscShrineBlood":
                            tempRule.spritePath = "Textures/shrinesymbols/texshrinebloodsymbol";
                            break;

                        case "iscShrineChance":
                            tempRule.spritePath = "Textures/shrinesymbols/texshrinechancesymbol";
                            break;

                        case "iscShrineHealing":
                            tempRule.spritePath = "Textures/shrinesymbols/texshrinehealingsymbol";
                            break;

                        case "iscShrineRestack":
                            tempRule.spritePath = "Textures/shrinesymbols/texshrinerestacksymbol";
                            break;

                        case "iscShrineGoldshoresAccess":
                            tempRule.spritePath = "Textures/MiscIcons/texRuleBonusStartingMoney";
                            break;

                        case "iscRadarTower":
                            tempRule.spritePath = "Textures/MiscIcons/texRuleBonusStartingMoney";
                            break;

                        case "iscTeleporter":
                            tempRule.spritePath = "Textures/MiscIcons/texRuleBonusStartingMoney";
                            break;

                        case "iscShopPortal":
                            tempRule.spritePath = "Textures/MiscIcons/texRuleBonusStartingMoney";
                            break;

                        case "iscMSPortal":
                            tempRule.spritePath = "Textures/MiscIcons/texRuleBonusStartingMoney";
                            break;

                        case "iscGoldshoresPortal":
                            tempRule.spritePath = "Textures/MiscIcons/texRuleBonusStartingMoney";
                            break;

                        case "iscGoldshoresBeacon":
                            tempRule.spritePath = "Textures/MiscIcons/texRuleBonusStartingMoney";
                            break;
                        }
                    }
                    RuleChoiceDef myRule = ChanceRule.AddChoice("0", myNum, false);
                    if (myNum == 1)
                    {
                        ChanceRule.MakeNewestChoiceDefault();
                    }

                    myRule.spritePath       = "Textures/MiscIcons/texRuleBonusStartingMoney";
                    myRule.tooltipNameToken = "" + myNum + "x Chance of " + interactableNames[i];
                    myRule.tooltipBodyToken = "" + myNum + "x Chance that a given spawned interactable will be of type '" + interactableNames[i] + "'";
                    switch (interactables[i])
                    {
                    case "iscBrokenDrone1":
                        myRule.spritePath = "Textures/MiscIcons/texRuleBonusStartingMoney";
                        break;

                    case "iscBrokenDrone2":
                        myRule.spritePath = "Textures/MiscIcons/texRuleBonusStartingMoney";
                        break;

                    case "iscBrokenMegaDrone":
                        myRule.spritePath = "Textures/MiscIcons/texRuleBonusStartingMoney";
                        break;

                    case "iscBrokenMissileDrone":
                        myRule.spritePath = "Textures/MiscIcons/texRuleBonusStartingMoney";
                        break;

                    case "iscBrokenTurret1":
                        myRule.spritePath = "Textures/MiscIcons/texRuleBonusStartingMoney";
                        break;

                    case "iscBarrel1":
                        myRule.spritePath = "Textures/MiscIcons/texRuleBonusStartingMoney";
                        break;

                    case "iscEquipmentBarrel":
                        myRule.spritePath = "Textures/MiscIcons/texRuleBonusStartingMoney";
                        break;

                    case "iscLockbox":
                        myRule.spritePath = "Textures/MiscIcons/texRuleBonusStartingMoney";
                        break;

                    case "iscChest1":
                        myRule.spritePath = "Textures/MiscIcons/texRuleBonusStartingMoney";
                        break;

                    case "iscChest1Stealthed":
                        myRule.spritePath = "Textures/MiscIcons/texRuleBonusStartingMoney";
                        break;

                    case "iscChest2":
                        myRule.spritePath = "Textures/MiscIcons/texRuleBonusStartingMoney";
                        break;

                    case "iscGoldChest":
                        myRule.spritePath = "Textures/MiscIcons/texRuleBonusStartingMoney";
                        break;

                    case "iscTripleShop":
                        myRule.spritePath = "Textures/MiscIcons/texRuleBonusStartingMoney";
                        break;

                    case "iscTripleShopLarge":
                        myRule.spritePath = "Textures/MiscIcons/texRuleBonusStartingMoney";
                        break;

                    case "iscDuplicator":
                        myRule.spritePath = "Textures/MiscIcons/texRuleBonusStartingMoney";
                        break;

                    case "iscDuplicatorLarge":
                        myRule.spritePath = "Textures/MiscIcons/texRuleBonusStartingMoney";
                        break;

                    case "iscDuplicatorMilitary":
                        myRule.spritePath = "Textures/MiscIcons/texRuleBonusStartingMoney";
                        break;

                    case "iscShrineCombat":
                        myRule.spritePath = "Textures/shrinesymbols/texshrinecombatsymbol";
                        break;

                    case "iscShrineBoss":
                        myRule.spritePath = "Textures/shrinesymbols/texshrinebosssymbole";
                        break;

                    case "iscShrineBlood":
                        myRule.spritePath = "Textures/shrinesymbols/texshrinebloodsymbol";
                        break;

                    case "iscShrineChance":
                        myRule.spritePath = "Textures/shrinesymbols/texshrinechancesymbol";
                        break;

                    case "iscShrineHealing":
                        myRule.spritePath = "Textures/shrinesymbols/texshrinehealingsymbol";
                        break;

                    case "iscShrineRestack":
                        myRule.spritePath = "Textures/shrinesymbols/texshrinerestacksymbol";
                        break;

                    case "iscShrineGoldshoresAccess":
                        myRule.spritePath = "Textures/MiscIcons/texRuleBonusStartingMoney";
                        break;

                    case "iscRadarTower":
                        myRule.spritePath = "Textures/MiscIcons/texRuleBonusStartingMoney";
                        break;

                    case "iscTeleporter":
                        myRule.spritePath = "Textures/MiscIcons/texRuleBonusStartingMoney";
                        break;

                    case "iscShopPortal":
                        myRule.spritePath = "Textures/MiscIcons/texRuleBonusStartingMoney";
                        break;

                    case "iscMSPortal":
                        myRule.spritePath = "Textures/MiscIcons/texRuleBonusStartingMoney";
                        break;

                    case "iscGoldshoresPortal":
                        myRule.spritePath = "Textures/MiscIcons/texRuleBonusStartingMoney";
                        break;

                    case "iscGoldshoresBeacon":
                        myRule.spritePath = "Textures/MiscIcons/texRuleBonusStartingMoney";
                        break;
                    }
                }
                addRule.Invoke(null, new object[] { ChanceRule });
            }

            addCategory.Invoke(null, new object[] { "Guarantees", new Color(94 / 255, 82 / 255, 30 / 255, byte.MaxValue), "", new Func <bool>(() => false) });
            for (int i = 0; i < interactables.Length; i++)
            {
                RuleDef GuaranteeRule = new RuleDef("FloodWarning." + interactables[i] + "Guaranteed", "Guaranteed");

                for (int o = 0; o < 8; o++)
                {
                    float myNum = (float)Math.Pow(2f, o);
                    if (o == 0)
                    {
                        RuleChoiceDef tempRule = GuaranteeRule.AddChoice("0", 0f, false);
                        tempRule.spritePath       = "Textures/MiscIcons/texRuleBonusStartingMoney";
                        tempRule.tooltipNameToken = "0 Guaranteed " + interactableNames[i];
                        tempRule.tooltipBodyToken = "No Guaranteee that any " + interactableNames[i] + " will spawn";
                        switch (interactables[i])
                        {
                        case "iscBrokenDrone1":
                            tempRule.spritePath = "Textures/MiscIcons/texRuleBonusStartingMoney";
                            break;

                        case "iscBrokenDrone2":
                            tempRule.spritePath = "Textures/MiscIcons/texRuleBonusStartingMoney";
                            break;

                        case "iscBrokenMegaDrone":
                            tempRule.spritePath = "Textures/MiscIcons/texRuleBonusStartingMoney";
                            break;

                        case "iscBrokenMissileDrone":
                            tempRule.spritePath = "Textures/MiscIcons/texRuleBonusStartingMoney";
                            break;

                        case "iscBrokenTurret1":
                            tempRule.spritePath = "Textures/MiscIcons/texRuleBonusStartingMoney";
                            break;

                        case "iscBarrel1":
                            tempRule.spritePath = "Textures/MiscIcons/texRuleBonusStartingMoney";
                            break;

                        case "iscEquipmentBarrel":
                            tempRule.spritePath = "Textures/MiscIcons/texRuleBonusStartingMoney";
                            break;

                        case "iscLockbox":
                            tempRule.spritePath = "Textures/MiscIcons/texRuleBonusStartingMoney";
                            break;

                        case "iscChest1":
                            tempRule.spritePath = "Textures/MiscIcons/texRuleBonusStartingMoney";
                            break;

                        case "iscChest1Stealthed":
                            tempRule.spritePath = "Textures/MiscIcons/texRuleBonusStartingMoney";
                            break;

                        case "iscChest2":
                            tempRule.spritePath = "Textures/MiscIcons/texRuleBonusStartingMoney";
                            break;

                        case "iscGoldChest":
                            tempRule.spritePath = "Textures/MiscIcons/texRuleBonusStartingMoney";
                            break;

                        case "iscTripleShop":
                            tempRule.spritePath = "Textures/MiscIcons/texRuleBonusStartingMoney";
                            break;

                        case "iscTripleShopLarge":
                            tempRule.spritePath = "Textures/MiscIcons/texRuleBonusStartingMoney";
                            break;

                        case "iscDuplicator":
                            tempRule.spritePath = "Textures/MiscIcons/texRuleBonusStartingMoney";
                            break;

                        case "iscDuplicatorLarge":
                            tempRule.spritePath = "Textures/MiscIcons/texRuleBonusStartingMoney";
                            break;

                        case "iscDuplicatorMilitary":
                            tempRule.spritePath = "Textures/MiscIcons/texRuleBonusStartingMoney";
                            break;

                        case "iscShrineCombat":
                            tempRule.spritePath = "Textures/shrinesymbols/texshrinecombatsymbol";
                            break;

                        case "iscShrineBoss":
                            tempRule.spritePath = "Textures/shrinesymbols/texshrinebosssymbole";
                            break;

                        case "iscShrineBlood":
                            tempRule.spritePath = "Textures/shrinesymbols/texshrinebloodsymbol";
                            break;

                        case "iscShrineChance":
                            tempRule.spritePath = "Textures/shrinesymbols/texshrinechancesymbol";
                            break;

                        case "iscShrineHealing":
                            tempRule.spritePath = "Textures/shrinesymbols/texshrinehealingsymbol";
                            break;

                        case "iscShrineRestack":
                            tempRule.spritePath = "Textures/shrinesymbols/texshrinerestacksymbol";
                            break;

                        case "iscShrineGoldshoresAccess":
                            tempRule.spritePath = "Textures/MiscIcons/texRuleBonusStartingMoney";
                            break;

                        case "iscRadarTower":
                            tempRule.spritePath = "Textures/MiscIcons/texRuleBonusStartingMoney";
                            break;

                        case "iscTeleporter":
                            tempRule.spritePath = "Textures/MiscIcons/texRuleBonusStartingMoney";
                            break;

                        case "iscShopPortal":
                            tempRule.spritePath = "Textures/MiscIcons/texRuleBonusStartingMoney";
                            break;

                        case "iscMSPortal":
                            tempRule.spritePath = "Textures/MiscIcons/texRuleBonusStartingMoney";
                            break;

                        case "iscGoldshoresPortal":
                            tempRule.spritePath = "Textures/MiscIcons/texRuleBonusStartingMoney";
                            break;

                        case "iscGoldshoresBeacon":
                            tempRule.spritePath = "Textures/MiscIcons/texRuleBonusStartingMoney";
                            break;
                        }
                    }
                    RuleChoiceDef myRule = GuaranteeRule.AddChoice("0", myNum, false);
                    if (myNum == 0)
                    {
                        GuaranteeRule.MakeNewestChoiceDefault();
                    }
                    myRule.spritePath       = "Textures/MiscIcons/texRuleBonusStartingMoney";
                    myRule.tooltipNameToken = "" + myNum + " Guaranteed " + interactableNames[i];
                    myRule.tooltipBodyToken = "" + myNum + " " + interactableNames[i] + "(s) Will always spawn in your world.";
                    switch (interactables[i])
                    {
                    case "iscBrokenDrone1":
                        myRule.spritePath = "Textures/MiscIcons/texRuleBonusStartingMoney";
                        break;

                    case "iscBrokenDrone2":
                        myRule.spritePath = "Textures/MiscIcons/texRuleBonusStartingMoney";
                        break;

                    case "iscBrokenMegaDrone":
                        myRule.spritePath = "Textures/MiscIcons/texRuleBonusStartingMoney";
                        break;

                    case "iscBrokenMissileDrone":
                        myRule.spritePath = "Textures/MiscIcons/texRuleBonusStartingMoney";
                        break;

                    case "iscBrokenTurret1":
                        myRule.spritePath = "Textures/MiscIcons/texRuleBonusStartingMoney";
                        break;

                    case "iscBarrel1":
                        myRule.spritePath = "Textures/MiscIcons/texRuleBonusStartingMoney";
                        break;

                    case "iscEquipmentBarrel":
                        myRule.spritePath = "Textures/MiscIcons/texRuleBonusStartingMoney";
                        break;

                    case "iscLockbox":
                        myRule.spritePath = "Textures/MiscIcons/texRuleBonusStartingMoney";
                        break;

                    case "iscChest1":
                        myRule.spritePath = "Textures/MiscIcons/texRuleBonusStartingMoney";
                        break;

                    case "iscChest1Stealthed":
                        myRule.spritePath = "Textures/MiscIcons/texRuleBonusStartingMoney";
                        break;

                    case "iscChest2":
                        myRule.spritePath = "Textures/MiscIcons/texRuleBonusStartingMoney";
                        break;

                    case "iscGoldChest":
                        myRule.spritePath = "Textures/MiscIcons/texRuleBonusStartingMoney";
                        break;

                    case "iscTripleShop":
                        myRule.spritePath = "Textures/MiscIcons/texRuleBonusStartingMoney";
                        break;

                    case "iscTripleShopLarge":
                        myRule.spritePath = "Textures/MiscIcons/texRuleBonusStartingMoney";
                        break;

                    case "iscDuplicator":
                        myRule.spritePath = "Textures/MiscIcons/texRuleBonusStartingMoney";
                        break;

                    case "iscDuplicatorLarge":
                        myRule.spritePath = "Textures/MiscIcons/texRuleBonusStartingMoney";
                        break;

                    case "iscDuplicatorMilitary":
                        myRule.spritePath = "Textures/MiscIcons/texRuleBonusStartingMoney";
                        break;

                    case "iscShrineCombat":
                        myRule.spritePath = "Textures/shrinesymbols/texshrinecombatsymbol";
                        break;

                    case "iscShrineBoss":
                        myRule.spritePath = "Textures/shrinesymbols/texshrinebosssymbole";
                        break;

                    case "iscShrineBlood":
                        myRule.spritePath = "Textures/shrinesymbols/texshrinebloodsymbol";
                        break;

                    case "iscShrineChance":
                        myRule.spritePath = "Textures/shrinesymbols/texshrinechancesymbol";
                        break;

                    case "iscShrineHealing":
                        myRule.spritePath = "Textures/shrinesymbols/texshrinehealingsymbol";
                        break;

                    case "iscShrineRestack":
                        myRule.spritePath = "Textures/shrinesymbols/texshrinerestacksymbol";
                        break;

                    case "iscShrineGoldshoresAccess":
                        myRule.spritePath = "Textures/MiscIcons/texRuleBonusStartingMoney";
                        break;

                    case "iscRadarTower":
                        myRule.spritePath = "Textures/MiscIcons/texRuleBonusStartingMoney";
                        break;

                    case "iscTeleporter":
                        myRule.spritePath = "Textures/MiscIcons/texRuleBonusStartingMoney";
                        break;

                    case "iscShopPortal":
                        myRule.spritePath = "Textures/MiscIcons/texRuleBonusStartingMoney";
                        break;

                    case "iscMSPortal":
                        myRule.spritePath = "Textures/MiscIcons/texRuleBonusStartingMoney";
                        break;

                    case "iscGoldshoresPortal":
                        myRule.spritePath = "Textures/MiscIcons/texRuleBonusStartingMoney";
                        break;

                    case "iscGoldshoresBeacon":
                        myRule.spritePath = "Textures/MiscIcons/texRuleBonusStartingMoney";
                        break;
                    }
                }
                addRule.Invoke(null, new object[] { GuaranteeRule });
            }


            bool gotCategory = false;
            DirectorCardCategorySelection myCategorySelection = new DirectorCardCategorySelection();

            Debug.Log("IGNORE THE ABOVE WARNING, THIS IS INTENDED");


            On.RoR2.ClassicStageInfo.GenerateDirectorCardWeightedSelection += (orig, self, categorySelection) =>
            {
                if (!gotCategory)
                {
                    myCategorySelection = categorySelection;
                    gotCategory         = true;
                }

                foreach (DirectorCardCategorySelection.Category category in myCategorySelection.categories)
                {
                    Debug.Log(category.name);

                    float num = myCategorySelection.SumAllWeightsInCategory(category);
                    foreach (DirectorCard directorCard in category.cards)
                    {
                        for (int i = 0; i < interactables.Length; i++)
                        {
                            if (directorCard.spawnCard.name.ToString() == interactables[i])
                            {
                                Debug.Log("Editing weight of " + interactables[i]);
                                directorCard.selectionWeight *= (int)((float)Run.instance.ruleBook.GetRuleChoice(RuleCatalog.FindRuleDef("FloodWarning." + interactables[i] + "Chance")).extraData);
                            }
                        }
                    }
                }

                return(orig(self, categorySelection));
            };

            On.RoR2.SceneDirector.PlaceTeleporter += (orig, self) =>
            {
                int currentCredits = (int)Harmony.AccessTools.Field(Harmony.AccessTools.TypeByName("RoR2.SceneDirector"), "interactableCredit").GetValue(self);
                Harmony.AccessTools.Field(Harmony.AccessTools.TypeByName("RoR2.SceneDirector"), "interactableCredit").SetValue(self, (int)(currentCredits * (float)Run.instance.ruleBook.GetRuleChoice(RuleCatalog.FindRuleDef("FloodWarning.InteractableScale")).extraData));

                orig(self);

                Xoroshiro128Plus rng        = new Xoroshiro128Plus((ulong)Run.instance.stageRng.nextUint);;
                DirectorCore     myDirector = (DirectorCore)Harmony.AccessTools.Field(Harmony.AccessTools.TypeByName("RoR2.SceneDirector"), "directorCore").GetValue(self);
                for (int i = 0; i < interactables.Length; i++)
                {
                    for (int o = 0; o < (float)Run.instance.ruleBook.GetRuleChoice(RuleCatalog.FindRuleDef("FloodWarning." + interactables[i] + "Guaranteed")).extraData; o++)
                    {
                        GameObject myGameObject = myDirector.TrySpawnObject(Resources.Load <SpawnCard>((string)("SpawnCards/InteractableSpawnCard/" + interactables[i])), new DirectorPlacementRule
                        {
                            placementMode = DirectorPlacementRule.PlacementMode.Random
                        }, rng);

                        if (myGameObject.GetComponent <PurchaseInteraction>())
                        {
                            myGameObject.GetComponent <PurchaseInteraction>().cost = Run.instance.GetDifficultyScaledCost(myGameObject.GetComponent <PurchaseInteraction>().cost);
                        }
                    }
                }
            };
        }