예제 #1
0
        private IEnumerator EatNPC(TalkDoerLite targetNPC)
        {
            float          elapsed      = 0f;
            float          duration     = 0.5f;
            Vector3        startPos     = targetNPC.transform.position;
            Vector3        finalOffset  = CagedBabyDragun.WorldCenter - startPos.XY();
            tk2dBaseSprite targetSprite = targetNPC.GetComponentInChildren <tk2dBaseSprite>();

            Destroy(targetNPC);
            Destroy(targetNPC.specRigidbody);
            CagedBabyDragun.spriteAnimator.PlayForDuration("baby_dragun_weak_eat", -1f, "baby_dragun_weak_idle", false);
            AkSoundEngine.PostEvent("Play_NPC_BabyDragun_Munch_01", gameObject);
            while (elapsed < duration)
            {
                elapsed += BraveTime.DeltaTime;
                if (!targetSprite || !targetSprite.transform)
                {
                    m_currentlyEatingNPC = false; yield break;
                }
                targetSprite.transform.localScale = Vector3.Lerp(Vector3.one, new Vector3(0.01f, 0.01f, 1f), elapsed / duration);
                targetSprite.transform.position   = Vector3.Lerp(startPos, startPos + finalOffset, elapsed / duration);
                yield return(null);
            }
            if (!targetSprite || !targetSprite.transform)
            {
                m_currentlyEatingNPC = false; yield break;
            }
            Destroy(targetSprite.gameObject);
            yield break;
        }
        public static void CreateOverheadUI(Action <TalkDoerLite> orig, TalkDoerLite self)
        {
            bool wasActive = self.OverheadUIElementOnPreInteract != null && self.OverheadUIElementOnPreInteract.activeSelf;

            self.OverheadUIElementOnPreInteract.SetActive(true);
            orig(self);
            if (!wasActive)
            {
                self.OverheadUIElementOnPreInteract.SetActive(false);
            }
            Tools.Print("Did overhead swippity swap");
        }
        private void Update()
        {
            if (Dungeon.IsGenerating | !m_isOpen)
            {
                return;
            }
            bool PlayerEnteredRoom = false;

            for (int i = 0; i < GameManager.Instance.AllPlayers.Length; i++)
            {
                if (GameManager.Instance.AllPlayers[i].CurrentRoom == m_room)
                {
                    PlayerEnteredRoom = true; break;
                }
            }

            if (PlayerEnteredRoom)
            {
                if (!m_currentlyEatingEnemy && m_enemiesEaten < RequiredEnemies)
                {
                    for (int i = 0; i < StaticReferenceManager.AllEnemies.Count; i++)
                    {
                        AIActor targetEnemy = StaticReferenceManager.AllEnemies[i];
                        if (targetEnemy && !targetEnemy.healthHaver.IsBoss && !targetEnemy.IgnoreForRoomClear)
                        {
                            float magnitude = (targetEnemy.specRigidbody.UnitCenter - sprite.WorldCenter).magnitude;
                            if (magnitude < 3f)
                            {
                                m_currentlyEatingEnemy = true;
                                StartCoroutine(EatEnemy(targetEnemy));
                            }
                        }
                    }
                }
                if (!m_currentlyEatingNPC)
                {
                    for (int k = 0; k < StaticReferenceManager.AllNpcs.Count; k++)
                    {
                        TalkDoerLite talkDoerLite = StaticReferenceManager.AllNpcs[k];
                        if (talkDoerLite && !talkDoerLite.name.Contains("ResourcefulRat_Beaten"))
                        {
                            float magnitude = (talkDoerLite.specRigidbody.UnitCenter - sprite.WorldCenter).magnitude;
                            if (magnitude < 3f)
                            {
                                m_currentlyEatingNPC = true;
                                RoomHandler.unassignedInteractableObjects.Remove(talkDoerLite);
                                StartCoroutine(EatNPC(talkDoerLite));
                            }
                        }
                    }
                }
            }
        }
 private void Start()
 {
     SellPitDweller   = gameObject.GetComponent <SellCellController>().SellPitDweller;
     CellTopSprite    = gameObject.GetComponent <SellCellController>().CellTopSprite;
     SellExplosionVFX = gameObject.GetComponent <SellCellController>().SellExplosionVFX;
     Destroy(gameObject.GetComponent <SellCellController>());
     if (m_parentRoom == null)
     {
         m_parentRoom = GetAbsoluteParentRoom();
     }
     if (m_parentRoom != null)
     {
         m_parentRoom.RegisterInteractable(SellPitDweller);
     }
     if (SellPitDweller && SellPitDweller.spriteAnimator)
     {
         SellPitDweller.spriteAnimator.alwaysUpdateOffscreen = true;
     }
     // if (GameStatsManager.Instance.GetPlayerStatValue(TrackedStats.TIMES_REACHED_NAKATOMI) >= 1f) { StartPreExploded = true; }
 }
        /// <summary>
        /// Creates a shop object along with an npc
        /// </summary>
        /// <param name="name">Name of the npc</param>
        /// <param name="prefix">Mod prefix (for example Bot)</param>
        ///
        /// <param name="idleSpritePaths">List of *FULL* sprite paths for the idle animation</param>
        /// <param name="idleFps">Fps of the idle animation (base game tends to use around 6)</param>
        ///
        /// <param name="talkSpritePaths">List of *FULL* sprite paths for the talk animation</param>
        /// <param name="talkFps">Fps of the talk animation (base game tends to use around 8)</param>
        ///
        /// <param name="lootTable">Shop loot table</param>
        /// <param name="currency">What is used to buy items at the shop</param>
        ///
        /// <param name="runBasedMultilineGenericStringKey">String key for normal convos</param>
        /// <param name="runBasedMultilineStopperStringKey">String key for if you try talking to an npc to much</param>
        /// <param name="purchaseItemStringKey">String key for when the player buys something</param>
        /// <param name="purchaseItemFailedStringKey">String key for when the player tries but fails to buy something</param>
        /// <param name="introStringKey">String key for when the player enters the room</param>
        /// <param name="attackedStringKey">String key for when the player shoots at the npc</param>
        /// <param name="costModifier">The multiplier for shop prices</param>
        /// <param name="itemPositions">The offset for the item(s) sold by your npc, the amount of items sold is based off how many offsets you add here (if you just want the 3 normally items spots you can use ItsDaFuckinShopApi.defaultItemPositions)</param>
        /// <param name="giveStatsOnPurchase">Whether the shop modifies stats after the player buys an item for example how cursula gives curse</param>
        /// <param name="statsToGiveOnPurchase"> The stats given when the player buys an item (will be ingored if statsToGiveOnPurchase is false)</param>
        ///
        /// <param name="CustomCanBuy">The method that gets called to check if the player can buy an item (useless if currency isnt set to CUSTOM)</param>
        /// <param name="CustomRemoveCurrency">The method that gets called remove currency from the player (useless if currency isnt set to CUSTOM)</param>
        /// <param name="CustomPrice">The method that gets called to get the price of an item (useless if currency isnt set to CUSTOM)</param>
        ///
        /// <param name="currencyIconPath">Sprite path for your custom currency sprite</param>
        /// <param name="currencyName">The name you want your custom currecy sprite to have (i should probably remove this...)</param>
        ///
        /// <param name="hasCarpet">Whether the shop has a carpet or something else that they sit on</param>
        /// <param name="carpetSpritePath">Sprite path for the carpet or whatever</param>
        ///
        /// <param name="hasMinimapIcon">Whether the shop has a minimap icon to show what room theyre in</param>
        /// <param name="minimapIconSpritePath">Sprite path minimap icon leave blank to just use deafult smiley face</param>
        ///
        /// <param name="addToMainNpcPool">Whether the shop should be added to the pool of npcs that show up in the main shop a long side bello</param>
        /// <param name="percentChanceForMainPool">How likely it is for the shop to show up in the main pool base game shops use 0.1</param>
        ///
        /// <param name="prerequisites">These do unlocks and shit</param>
        /// <returns></returns>
        public static GameObject SetUpShop(string name, string prefix, List <string> idleSpritePaths, int idleFps, List <string> talkSpritePaths, int talkFps, GenericLootTable lootTable, CustomShopItemController.ShopCurrencyType currency, string runBasedMultilineGenericStringKey,
                                           string runBasedMultilineStopperStringKey, string purchaseItemStringKey, string purchaseItemFailedStringKey, string introStringKey, string attackedStringKey, Vector3 talkPointOffset, Vector3[] itemPositions = null, float costModifier = 1, bool giveStatsOnPurchase = false,
                                           StatModifier[] statsToGiveOnPurchase = null, Func <CustomShopController, PlayerController, int, bool> CustomCanBuy           = null, Func <CustomShopController, PlayerController, int, int> CustomRemoveCurrency = null, Func <CustomShopController, CustomShopItemController, PickupObject, int> CustomPrice = null,
                                           Func <PlayerController, PickupObject, int, bool> OnPurchase = null, Func <PlayerController, PickupObject, int, bool> OnSteal = null, string currencyIconPath = "", string currencyName = "", bool canBeRobbed = true, bool hasCarpet = false, string carpetSpritePath = "", bool hasMinimapIcon = false,
                                           string minimapIconSpritePath = "", bool addToMainNpcPool = false, float percentChanceForMainPool = 0.1f, DungeonPrerequisite[] prerequisites = null)
        {
            try
            {
                if (prerequisites == null)
                {
                    prerequisites = new DungeonPrerequisite[0];
                }
                //bool isBreachShop = false;
                Vector3 breachPos = Vector3.zero;

                var shared_auto_001 = ResourceManager.LoadAssetBundle("shared_auto_001");
                var shared_auto_002 = ResourceManager.LoadAssetBundle("shared_auto_002");
                var SpeechPoint     = new GameObject("SpeechPoint");
                SpeechPoint.transform.position = talkPointOffset;



                var npcObj = SpriteBuilder.SpriteFromResource(idleSpritePaths[0], new GameObject(prefix + ":" + name));

                FakePrefab.MarkAsFakePrefab(npcObj);
                UnityEngine.Object.DontDestroyOnLoad(npcObj);
                npcObj.SetActive(false);

                npcObj.layer = 22;

                var collection = npcObj.GetComponent <tk2dSprite>().Collection;
                SpeechPoint.transform.parent = npcObj.transform;

                FakePrefab.MarkAsFakePrefab(SpeechPoint);
                UnityEngine.Object.DontDestroyOnLoad(SpeechPoint);
                SpeechPoint.SetActive(true);


                var idleIdsList = new List <int>();
                var talkIdsList = new List <int>();

                foreach (string sprite in idleSpritePaths)
                {
                    idleIdsList.Add(SpriteBuilder.AddSpriteToCollection(sprite, collection));
                }

                foreach (string sprite in talkSpritePaths)
                {
                    talkIdsList.Add(SpriteBuilder.AddSpriteToCollection(sprite, collection));
                }

                tk2dSpriteAnimator spriteAnimator = npcObj.AddComponent <tk2dSpriteAnimator>();

                SpriteBuilder.AddAnimation(spriteAnimator, collection, idleIdsList, name + "_idle", tk2dSpriteAnimationClip.WrapMode.Loop, idleFps);
                SpriteBuilder.AddAnimation(spriteAnimator, collection, talkIdsList, name + "_talk", tk2dSpriteAnimationClip.WrapMode.Loop, talkFps);

                SpeculativeRigidbody rigidbody = GenerateOrAddToRigidBody(npcObj, CollisionLayer.BulletBlocker, PixelCollider.PixelColliderGeneration.Manual, true, true, true, false, false, false, false, true, new IntVector2(20, 18), new IntVector2(5, 0));

                TalkDoerLite talkDoer = npcObj.AddComponent <TalkDoerLite>();

                talkDoer.placeableWidth  = 4;
                talkDoer.placeableHeight = 3;
                talkDoer.difficulty      = 0;
                talkDoer.isPassable      = true;
                talkDoer.usesOverrideInteractionRegion = false;
                talkDoer.overrideRegionOffset          = Vector2.zero;
                talkDoer.overrideRegionDimensions      = Vector2.zero;
                talkDoer.overrideInteractionRadius     = -1;
                talkDoer.PreventInteraction            = false;
                talkDoer.AllowPlayerToPassEventually   = true;
                talkDoer.speakPoint              = SpeechPoint.transform;
                talkDoer.SpeaksGleepGlorpenese   = false;
                talkDoer.audioCharacterSpeechTag = "oldman";
                talkDoer.playerApproachRadius    = 5;
                talkDoer.conversationBreakRadius = 5;
                talkDoer.echo1 = null;
                talkDoer.echo2 = null;
                talkDoer.PreventCoopInteraction = false;
                talkDoer.IsPaletteSwapped       = false;
                talkDoer.PaletteTexture         = null;
                talkDoer.OutlineDepth           = 0.5f;
                talkDoer.OutlineLuminanceCutoff = 0.05f;
                talkDoer.MovementSpeed          = 3;
                talkDoer.PathableTiles          = CellTypes.FLOOR;


                UltraFortunesFavor dreamLuck = npcObj.AddComponent <UltraFortunesFavor>();

                dreamLuck.goopRadius          = 2;
                dreamLuck.beamRadius          = 2;
                dreamLuck.bulletRadius        = 2;
                dreamLuck.bulletSpeedModifier = 0.8f;

                dreamLuck.vfxOffset      = 0.625f;
                dreamLuck.sparkOctantVFX = shared_auto_001.LoadAsset <GameObject>("FortuneFavor_VFX_Spark");


                AIAnimator aIAnimator = GenerateBlankAIAnimator(npcObj);
                aIAnimator.spriteAnimator = spriteAnimator;
                aIAnimator.IdleAnimation  = new DirectionalAnimation
                {
                    Type      = DirectionalAnimation.DirectionType.Single,
                    Prefix    = name + "_idle",
                    AnimNames = new string[]
                    {
                        ""
                    },
                    Flipped = new DirectionalAnimation.FlipType[]
                    {
                        DirectionalAnimation.FlipType.None
                    }
                };

                aIAnimator.TalkAnimation = new DirectionalAnimation
                {
                    Type      = DirectionalAnimation.DirectionType.Single,
                    Prefix    = name + "_talk",
                    AnimNames = new string[]
                    {
                        ""
                    },
                    Flipped = new DirectionalAnimation.FlipType[]
                    {
                        DirectionalAnimation.FlipType.None
                    }
                };

                var basenpc = ResourceManager.LoadAssetBundle("shared_auto_001").LoadAsset <GameObject>("Merchant_Key").transform.Find("NPC_Key").gameObject;

                PlayMakerFSM iHaveNoFuckingClueWhatThisIs = npcObj.AddComponent <PlayMakerFSM>();

                UnityEngine.JsonUtility.FromJsonOverwrite(UnityEngine.JsonUtility.ToJson(basenpc.GetComponent <PlayMakerFSM>()), iHaveNoFuckingClueWhatThisIs);

                FieldInfo fsmStringParams = typeof(ActionData).GetField("fsmStringParams", BindingFlags.NonPublic | BindingFlags.Instance);

                (fsmStringParams.GetValue(iHaveNoFuckingClueWhatThisIs.FsmStates[1].ActionData) as List <FsmString>)[0].Value = runBasedMultilineGenericStringKey;
                (fsmStringParams.GetValue(iHaveNoFuckingClueWhatThisIs.FsmStates[1].ActionData) as List <FsmString>)[1].Value = runBasedMultilineStopperStringKey;

                (fsmStringParams.GetValue(iHaveNoFuckingClueWhatThisIs.FsmStates[4].ActionData) as List <FsmString>)[0].Value = purchaseItemStringKey;

                (fsmStringParams.GetValue(iHaveNoFuckingClueWhatThisIs.FsmStates[5].ActionData) as List <FsmString>)[0].Value = purchaseItemFailedStringKey;

                (fsmStringParams.GetValue(iHaveNoFuckingClueWhatThisIs.FsmStates[7].ActionData) as List <FsmString>)[0].Value = introStringKey;

                (fsmStringParams.GetValue(iHaveNoFuckingClueWhatThisIs.FsmStates[8].ActionData) as List <FsmString>)[0].Value = attackedStringKey;

                (fsmStringParams.GetValue(iHaveNoFuckingClueWhatThisIs.FsmStates[9].ActionData) as List <FsmString>)[0].Value = "#SUBSHOP_GENERIC_CAUGHT_STEALING";

                (fsmStringParams.GetValue(iHaveNoFuckingClueWhatThisIs.FsmStates[10].ActionData) as List <FsmString>)[0].Value = "#SHOP_GENERIC_NO_SALE_LABEL";

                (fsmStringParams.GetValue(iHaveNoFuckingClueWhatThisIs.FsmStates[12].ActionData) as List <FsmString>)[0].Value = "#COOP_REBUKE";


                npcObj.name = prefix + ":" + name;

                var posList = new List <Transform>();
                for (int i = 0; i < itemPositions.Length; i++)
                {
                    var ItemPoint = new GameObject("ItemPoint" + i);
                    ItemPoint.transform.position = itemPositions[i];
                    FakePrefab.MarkAsFakePrefab(ItemPoint);
                    UnityEngine.Object.DontDestroyOnLoad(ItemPoint);
                    ItemPoint.SetActive(true);
                    posList.Add(ItemPoint.transform);
                }

                var ItemPoint1 = new GameObject("ItemPoint1");
                ItemPoint1.transform.position = new Vector3(1.125f, 2.125f, 1);
                FakePrefab.MarkAsFakePrefab(ItemPoint1);
                UnityEngine.Object.DontDestroyOnLoad(ItemPoint1);
                ItemPoint1.SetActive(true);
                var ItemPoint2 = new GameObject("ItemPoint2");
                ItemPoint2.transform.position = new Vector3(2.625f, 1f, 1);
                FakePrefab.MarkAsFakePrefab(ItemPoint2);
                UnityEngine.Object.DontDestroyOnLoad(ItemPoint2);
                ItemPoint2.SetActive(true);
                var ItemPoint3 = new GameObject("ItemPoint3");
                ItemPoint3.transform.position = new Vector3(4.125f, 2.125f, 1);
                FakePrefab.MarkAsFakePrefab(ItemPoint3);
                UnityEngine.Object.DontDestroyOnLoad(ItemPoint3);
                ItemPoint3.SetActive(true);


                var shopObj = new GameObject(prefix + ":" + name + "_Shop").AddComponent <CustomShopController>();
                FakePrefab.MarkAsFakePrefab(shopObj.gameObject);
                UnityEngine.Object.DontDestroyOnLoad(shopObj.gameObject);

                shopObj.gameObject.SetActive(false);

                shopObj.currencyType = currency;

                shopObj.ActionAndFuncSetUp(CustomCanBuy, CustomRemoveCurrency, CustomPrice, OnPurchase, OnSteal);

                if (!string.IsNullOrEmpty(currencyIconPath))
                {
                    shopObj.customPriceSprite = AddCustomCurrencyType(currencyIconPath, $"{prefix}:{currencyName}");
                }
                else
                {
                    shopObj.customPriceSprite = currencyName;
                }


                //GungeonAPI.ToolsGAPI.AddNewItemToAtlas()

                shopObj.canBeRobbed = canBeRobbed;

                shopObj.placeableHeight = 5;
                shopObj.placeableWidth  = 5;
                shopObj.difficulty      = 0;
                shopObj.isPassable      = true;
                shopObj.baseShopType    = BaseShopController.AdditionalShopType.TRUCK;//shopType;

                shopObj.FoyerMetaShopForcedTiers = false;
                shopObj.IsBeetleMerchant         = false;
                shopObj.ExampleBlueprintPrefab   = null;
                shopObj.shopItems      = lootTable;
                shopObj.spawnPositions = posList.ToArray();//{ ItemPoint1.transform, ItemPoint2.transform, ItemPoint3.transform };

                foreach (var pos in shopObj.spawnPositions)
                {
                    pos.parent = shopObj.gameObject.transform;
                }

                shopObj.shopItemsGroup2          = null;
                shopObj.spawnPositionsGroup2     = null;
                shopObj.spawnGroupTwoItem1Chance = 0.5f;
                shopObj.spawnGroupTwoItem2Chance = 0.5f;
                shopObj.spawnGroupTwoItem3Chance = 0.5f;
                shopObj.shopkeepFSM          = npcObj.GetComponent <PlayMakerFSM>();
                shopObj.shopItemShadowPrefab = shared_auto_001.LoadAsset <GameObject>("Merchant_Key").GetComponent <BaseShopController>().shopItemShadowPrefab;

                shopObj.prerequisites = prerequisites;
                //shopObj.shopItemShadowPrefab =

                shopObj.cat = null;


                if (hasMinimapIcon)
                {
                    if (!string.IsNullOrEmpty(minimapIconSpritePath))
                    {
                        shopObj.OptionalMinimapIcon = SpriteBuilder.SpriteFromResource(minimapIconSpritePath);
                        UnityEngine.Object.DontDestroyOnLoad(shopObj.OptionalMinimapIcon);
                        FakePrefab.MarkAsFakePrefab(shopObj.OptionalMinimapIcon);
                    }
                    else
                    {
                        shopObj.OptionalMinimapIcon = ResourceCache.Acquire("Global Prefabs/Minimap_NPC_Icon") as GameObject;
                    }
                }

                shopObj.ShopCostModifier     = costModifier;
                shopObj.FlagToSetOnEncounter = GungeonFlags.NONE;

                shopObj.giveStatsOnPurchase = giveStatsOnPurchase;
                shopObj.statsToGive         = statsToGiveOnPurchase;

                //shopObj.

                /*if (isBreachShop)
                 * {
                 *  shopObj.gameObject.AddComponent<BreachShopComp>().offset = breachPos;
                 *  BreachShopTools.registeredShops.Add(prefix + ":" + name, shopObj.gameObject);
                 *
                 *  shopObj.FoyerMetaShopForcedTiers = true;
                 *
                 *  var exampleBlueprintObj = SpriteBuilder.SpriteFromResource(carpetSpritePath, new GameObject(prefix + ":" + name + "_ExampleBlueprintPrefab"));
                 *  exampleBlueprintObj.GetComponent<tk2dSprite>().SortingOrder = 2;
                 *  FakePrefab.MarkAsFakePrefab(exampleBlueprintObj);
                 *  UnityEngine.Object.DontDestroyOnLoad(exampleBlueprintObj);
                 *  exampleBlueprintObj.SetActive(false);
                 *
                 *  //var item = exampleBlueprintObj.AddComponent<ItemBlueprintItem>();
                 *  //item.quality = PickupObject.ItemQuality.SPECIAL;
                 *  //item.PickupObjectId = 99999999;
                 *
                 *
                 *
                 *  shopObj.ExampleBlueprintPrefab = shared_auto_001.LoadAsset<GameObject>("NPC_Beetle_Merchant_Foyer").GetComponent<BaseShopController>().ExampleBlueprintPrefab;
                 * }*/

                npcObj.transform.parent   = shopObj.gameObject.transform;
                npcObj.transform.position = new Vector3(1.9375f, 3.4375f, 5.9375f);



                if (hasCarpet)
                {
                    var carpetObj = SpriteBuilder.SpriteFromResource(carpetSpritePath, new GameObject(prefix + ":" + name + "_Carpet"));
                    carpetObj.GetComponent <tk2dSprite>().SortingOrder = 2;
                    FakePrefab.MarkAsFakePrefab(carpetObj);
                    UnityEngine.Object.DontDestroyOnLoad(carpetObj);
                    carpetObj.SetActive(true);

                    carpetObj.transform.position = new Vector3(0, 0, 1.7f);
                    carpetObj.transform.parent   = shopObj.gameObject.transform;
                    carpetObj.layer = 20;
                }
                npcObj.SetActive(true);

                if (addToMainNpcPool)
                {
                    shared_auto_002.LoadAsset <DungeonPlaceable>("shopannex_contents_01").variantTiers.Add(new DungeonPlaceableVariant
                    {
                        percentChance           = percentChanceForMainPool,
                        unitOffset              = new Vector2(-0.5f, -1.25f),
                        nonDatabasePlaceable    = shopObj.gameObject,
                        enemyPlaceableGuid      = "",
                        pickupObjectPlaceableId = -1,
                        forceBlackPhantom       = false,
                        addDebrisObject         = false,
                        prerequisites           = prerequisites, //shit for unlocks gose here sooner or later
                        materialRequirements    = new DungeonPlaceableRoomMaterialRequirement[0],
                    });
                }

                ItsDaFuckinShopApi.builtShops.Add(prefix + ":" + name, shopObj.gameObject);
                return(shopObj.gameObject);
            }
            catch (Exception message)
            {
                ETGModConsole.Log(message.ToString());
                return(null);
            }
        }
        private IEnumerator BecomeMimic()
        {
            if (m_hands == null)
            {
                StartCoroutine(DoIntro());
            }

            if (!ChaosConsole.WallMimicsUseRewardManager)
            {
                m_ChaosModeActive = true;
            }
            if (m_GlitchModeActive)
            {
                m_ItemDropOdds += 0.2f; m_FriendlyMimicOdds += 0.2f;
            }

            m_isHidden = false;
            SpeculativeRigidbody specRigidbody = this.specRigidbody;

            specRigidbody.OnRigidbodyCollision = (SpeculativeRigidbody.OnRigidbodyCollisionDelegate)Delegate.Remove(specRigidbody.OnRigidbodyCollision, new SpeculativeRigidbody.OnRigidbodyCollisionDelegate(HandleRigidbodyCollision));
            SpeculativeRigidbody specRigidbody2 = this.specRigidbody;

            specRigidbody2.OnBeamCollision = (SpeculativeRigidbody.OnBeamCollisionDelegate)Delegate.Remove(specRigidbody2.OnBeamCollision, new SpeculativeRigidbody.OnBeamCollisionDelegate(HandleBeamCollision));
            AIAnimator tongueAnimator = aiAnimator.ChildAnimator;

            tongueAnimator.renderer.enabled       = true;
            tongueAnimator.spriteAnimator.enabled = true;
            AIAnimator spitAnimator = tongueAnimator.ChildAnimator;

            spitAnimator.renderer.enabled       = true;
            spitAnimator.spriteAnimator.enabled = true;
            tongueAnimator.PlayUntilFinished("spawn", false, null, -1f, false);
            float delay        = tongueAnimator.CurrentClipLength;
            float timer        = 0f;
            bool  hasPlayedVFX = false;

            while (timer < delay)
            {
                yield return(null);

                timer += BraveTime.DeltaTime;
                if (!hasPlayedVFX && delay - timer < 0.1f)
                {
                    hasPlayedVFX = true;
                    if (WallDisappearVFX)
                    {
                        Vector2 zero  = Vector2.zero;
                        Vector2 zero2 = Vector2.zero;
                        DungeonData.Direction facingDirection = m_facingDirection;
                        if (facingDirection != DungeonData.Direction.SOUTH)
                        {
                            if (facingDirection != DungeonData.Direction.EAST)
                            {
                                if (facingDirection == DungeonData.Direction.WEST)
                                {
                                    zero  = new Vector2(0f, -1f);
                                    zero2 = new Vector2(0f, 1f);
                                }
                            }
                            else
                            {
                                zero  = new Vector2(0f, -1f);
                                zero2 = new Vector2(0f, 1f);
                            }
                        }
                        else
                        {
                            zero  = new Vector2(0f, -1f);
                            zero2 = new Vector2(0f, 1f);
                        }
                        Vector2 min = Vector2.Min(pos1.ToVector2(), pos2.ToVector2()) + zero;
                        Vector2 max = Vector2.Max(pos1.ToVector2(), pos2.ToVector2()) + new Vector2(1f, 1f) + zero2;
                        for (int i = 0; i < 5; i++)
                        {
                            Vector2        v              = BraveUtility.RandomVector2(min, max, new Vector2(0.25f, 0.25f)) + new Vector2(0f, 1f);
                            GameObject     gameObject     = SpawnManager.SpawnVFX(WallDisappearVFX, v, Quaternion.identity);
                            tk2dBaseSprite tk2dBaseSprite = (!gameObject) ? null : gameObject.GetComponent <tk2dBaseSprite>();
                            if (tk2dBaseSprite)
                            {
                                tk2dBaseSprite.HeightOffGround = 8f;
                                tk2dBaseSprite.UpdateZDepth();
                            }
                        }
                    }
                }
            }
            if (!m_failedWallConfigure && m_GlitchModeActive)
            {
                if (aiActor.ParentRoom != null && GlitchEnemyList != null && GlitchEnemyList.Count > 0 && UnityEngine.Random.value <= m_spawnGitchEnemyOdds)
                {
                    float RandomIntervalFloat       = UnityEngine.Random.Range(0.02f, 0.06f);
                    float RandomDispFloat           = UnityEngine.Random.Range(0.1f, 0.16f);
                    float RandomDispIntensityFloat  = UnityEngine.Random.Range(0.1f, 0.4f);
                    float RandomColorProbFloat      = UnityEngine.Random.Range(0.05f, 0.2f);
                    float RandomColorIntensityFloat = UnityEngine.Random.Range(0.1f, 0.25f);

                    int count2 = this.specRigidbody.PixelColliders.Count;
                    this.specRigidbody.PixelColliders.RemoveAt(count2 - 1);
                    this.specRigidbody.PixelColliders.RemoveAt(count2 - 2);
                    StaticReferenceManager.AllShadowSystemDepthHavers.Remove(m_fakeWall.transform);
                    Destroy(m_fakeWall);
                    Destroy(m_fakeCeiling);

                    Vector3 targetPosForSpawn = m_startingPos + DungeonData.GetIntVector2FromDirection(m_facingDirection).ToVector3();
                    while (timer < delay)
                    {
                        aiAnimator.LockFacingDirection = true;
                        aiAnimator.FacingDirection     = DungeonData.GetAngleFromDirection(m_facingDirection);
                        yield return(null);

                        timer += BraveTime.DeltaTime;
                        transform.position = Vector3.Lerp(m_startingPos, targetPosForSpawn, Mathf.InverseLerp(0.42f, 0.58f, timer));
                        this.specRigidbody.Reinitialize();
                    }
                    yield return(null);

                    Vector3 FinalSpawnLocation             = transform.position;
                    Vector3 VFXExplosionLocation           = transform.position;
                    Vector2 VFXExplosionSource             = Vector2.zero;
                    DungeonData.Direction CurrentDirection = m_facingDirection;
                    if (CurrentDirection == DungeonData.Direction.WEST)
                    {
                        FinalSpawnLocation   += new Vector3(2.5f, 3.5f);
                        VFXExplosionLocation += new Vector3(3.5f, 3.5f);
                        VFXExplosionSource    = new Vector2(1, 0);
                    }
                    else if (CurrentDirection == DungeonData.Direction.EAST)
                    {
                        FinalSpawnLocation   += new Vector3(4f, 3.5f);
                        VFXExplosionLocation += new Vector3(3f, 3.5f);
                    }
                    else if (CurrentDirection == DungeonData.Direction.NORTH)
                    {
                        FinalSpawnLocation   += new Vector3(3.5f, 4f);
                        VFXExplosionLocation += new Vector3(3.5f, 3f);
                        VFXExplosionSource    = new Vector2(0, 1);
                    }
                    else if (CurrentDirection == DungeonData.Direction.SOUTH)
                    {
                        FinalSpawnLocation   += new Vector3(3.5f, 1.5f);
                        VFXExplosionLocation += new Vector3(3.5f, 2.5f);
                    }
                    yield return(null);

                    string        SelectedEnemy          = BraveUtility.RandomElement(GlitchEnemyList);
                    ExplosionData wallMimicExplosionData = new ExplosionData();
                    wallMimicExplosionData.CopyFrom(GameManager.Instance.Dungeon.sharedSettingsPrefab.DefaultExplosionData);
                    wallMimicExplosionData.damage = 0f;
                    wallMimicExplosionData.force /= 1.6f;

                    if (SelectedEnemy != "RATCORPSE")
                    {
                        Exploder.Explode(VFXExplosionLocation, wallMimicExplosionData, VFXExplosionSource, ignoreQueues: true, damageTypes: CoreDamageTypes.None);
                        GameObject     SpawnVFXObject          = Instantiate((GameObject)ResourceCache.Acquire("Global VFX/VFX_Item_Spawn_Poof"));
                        tk2dBaseSprite SpawnVFXObjectComponent = SpawnVFXObject.GetComponent <tk2dBaseSprite>();
                        SpawnVFXObjectComponent.PlaceAtPositionByAnchor(FinalSpawnLocation + new Vector3(0f, 0.5f, 0f), tk2dBaseSprite.Anchor.MiddleCenter);
                        SpawnVFXObjectComponent.HeightOffGround = 1f;
                        SpawnVFXObjectComponent.UpdateZDepth();
                        AIActor glitchActor = AIActor.Spawn(EnemyDatabase.GetOrLoadByGuid(SelectedEnemy), FinalSpawnLocation, aiActor.ParentRoom, true, AIActor.AwakenAnimationType.Awaken, true);

                        /*if (aiActor.ParentRoom != null && !aiActor.ParentRoom.IsSealed && !glitchActor.IgnoreForRoomClear) {
                         *  if (GameManager.Instance.PrimaryPlayer.CurrentRoom == aiActor.ParentRoom && aiActor.ParentRoom.EverHadEnemies) {
                         *      aiActor.ParentRoom.SealRoom();
                         *  }
                         * }*/
                        PickupObject.ItemQuality targetGlitchEnemyItemQuality = (UnityEngine.Random.value >= 0.2f) ? ((!BraveUtility.RandomBool()) ? PickupObject.ItemQuality.C : PickupObject.ItemQuality.D) : PickupObject.ItemQuality.B;
                        GenericLootTable         glitchEnemyLootTable         = (!BraveUtility.RandomBool()) ? GameManager.Instance.RewardManager.GunsLootTable : GameManager.Instance.RewardManager.ItemsLootTable;
                        PickupObject             glitchEnemyItem = LootEngine.GetItemOfTypeAndQuality <PickupObject>(targetGlitchEnemyItemQuality, glitchEnemyLootTable, false);

                        /*if (BraveUtility.RandomBool()) {
                         *  ChaosUtility.MakeCompanion(glitchActor);
                         * } else {
                         *  ChaosShaders.Instance.ApplyGlitchShader(glitchActor, glitchActor.sprite, true, RandomIntervalFloat, RandomDispFloat, RandomDispIntensityFloat, RandomColorProbFloat, RandomColorIntensityFloat);
                         * }*/

                        ChaosShaders.Instance.ApplyGlitchShader(glitchActor, glitchActor.sprite, true, RandomIntervalFloat, RandomDispFloat, RandomDispIntensityFloat, RandomColorProbFloat, RandomColorIntensityFloat);

                        if (glitchEnemyItem)
                        {
                            glitchActor.AdditionalSafeItemDrops.Add(glitchEnemyItem);
                        }
                    }
                    else
                    {
                        Exploder.Explode(VFXExplosionLocation, wallMimicExplosionData, VFXExplosionSource, ignoreQueues: true, damageTypes: CoreDamageTypes.None);
                        GameObject     SpawnVFXObject          = Instantiate((GameObject)ResourceCache.Acquire("Global VFX/VFX_Item_Spawn_Poof"));
                        tk2dBaseSprite SpawnVFXObjectComponent = SpawnVFXObject.GetComponent <tk2dBaseSprite>();
                        SpawnVFXObjectComponent.PlaceAtPositionByAnchor(FinalSpawnLocation + new Vector3(0f, 0.5f, 0f), tk2dBaseSprite.Anchor.MiddleCenter);
                        SpawnVFXObjectComponent.HeightOffGround = 1f;
                        SpawnVFXObjectComponent.UpdateZDepth();
                        GameObject   spawnedRatCorpseObject = Instantiate(ChaosPrefabs.RatCorpseNPC, FinalSpawnLocation, Quaternion.identity);
                        TalkDoerLite talkdoerComponent      = spawnedRatCorpseObject.GetComponent <TalkDoerLite>();
                        talkdoerComponent.transform.position.XY().GetAbsoluteRoom().RegisterInteractable(talkdoerComponent);
                        talkdoerComponent.transform.position.XY().GetAbsoluteRoom().TransferInteractableOwnershipToDungeon(talkdoerComponent);
                        talkdoerComponent.playmakerFsm.SetState("Set Mode");
                        ChaosUtility.AddHealthHaver(talkdoerComponent.gameObject, 60, flashesOnDamage: false, exploderSpawnsItem: true);
                    }
                    yield return(null);

                    Destroy(aiActor.gameObject);
                    yield break;
                }
            }
            PickupObject.ItemQuality targetQuality = (UnityEngine.Random.value >= 0.2f) ? ((!BraveUtility.RandomBool()) ? PickupObject.ItemQuality.C : PickupObject.ItemQuality.D) : PickupObject.ItemQuality.B;
            GenericLootTable         lootTable     = (!BraveUtility.RandomBool()) ? GameManager.Instance.RewardManager.GunsLootTable : GameManager.Instance.RewardManager.ItemsLootTable;
            PickupObject             item          = LootEngine.GetItemOfTypeAndQuality <PickupObject>(targetQuality, lootTable, false);

            if (item)
            {
                if (m_ChaosModeActive)
                {
                    if (UnityEngine.Random.value <= m_ItemDropOdds)
                    {
                        aiActor.AdditionalSafeItemDrops.Add(item);
                    }
                    else
                    {
                        aiActor.AdditionalSafeItemDrops.Add(PickupObjectDatabase.GetById(70));
                        if (BraveUtility.RandomBool())
                        {
                            aiActor.AdditionalSafeItemDrops.Add(PickupObjectDatabase.GetById(70));
                        }
                        if (m_GlitchModeActive)
                        {
                            aiActor.AdditionalSafeItemDrops.Add(PickupObjectDatabase.GetById(70));
                        }
                    }
                    if (UnityEngine.Random.value <= m_FriendlyMimicOdds)
                    {
                        m_isFriendlyMimic = true;
                    }
                }
                else
                {
                    aiActor.AdditionalSafeItemDrops.Add(item);
                }
            }
            else
            {
                if (m_ChaosModeActive && UnityEngine.Random.value <= m_FriendlyMimicOdds)
                {
                    m_isFriendlyMimic = true;
                }
            }
            aiActor.enabled            = true;
            behaviorSpeculator.enabled = true;
            if (aiActor.ParentRoom != null && aiActor.ParentRoom.IsSealed && !m_isFriendlyMimic)
            {
                aiActor.IgnoreForRoomClear = false;
            }
            // if (m_isFriendlyMimic) { ChaosUtility.MakeCompanion(aiActor); }
            if (m_isFriendlyMimic)
            {
                aiActor.ApplyEffect(GameManager.Instance.Dungeon.sharedSettingsPrefab.DefaultPermanentCharmEffect, 1f, null);
            }
            if (!m_failedWallConfigure)
            {
                int count = this.specRigidbody.PixelColliders.Count;
                for (int j = 0; j < count - 2; j++)
                {
                    this.specRigidbody.PixelColliders[j].Enabled = true;
                }
                this.specRigidbody.PixelColliders.RemoveAt(count - 1);
                this.specRigidbody.PixelColliders.RemoveAt(count - 2);
                StaticReferenceManager.AllShadowSystemDepthHavers.Remove(m_fakeWall.transform);
                Destroy(m_fakeWall);
                Destroy(m_fakeCeiling);
            }
            else
            {
                int count = this.specRigidbody.PixelColliders.Count;
                for (int j = 0; j < count; j++)
                {
                    this.specRigidbody.PixelColliders[j].Enabled = true;
                }
            }
            for (int k = 0; k < m_hands.Length; k++)
            {
                m_hands[k].gameObject.SetActive(true);
            }
            aiActor.ToggleRenderers(true);
            if (aiShooter)
            {
                aiShooter.ToggleGunAndHandRenderers(true, "ChaosWallMimicController");
            }
            aiActor.IsGone           = false;
            healthHaver.IsVulnerable = true;
            aiActor.State            = AIActor.ActorState.Normal;
            for (int l = 0; l < m_hands.Length; l++)
            {
                m_hands[l].gameObject.SetActive(false);
            }
            m_isFinished = true;
            delay        = 0.58f;
            timer        = 0f;
            Vector3 targetPos = m_startingPos + DungeonData.GetIntVector2FromDirection(m_facingDirection).ToVector3();

            while (timer < delay)
            {
                aiAnimator.LockFacingDirection = true;
                aiAnimator.FacingDirection     = DungeonData.GetAngleFromDirection(m_facingDirection);
                yield return(null);

                timer += BraveTime.DeltaTime;
                transform.position = Vector3.Lerp(m_startingPos, targetPos, Mathf.InverseLerp(0.42f, 0.58f, timer));
                this.specRigidbody.Reinitialize();
            }
            aiAnimator.LockFacingDirection = false;
            knockbackDoer.SetImmobile(false, "ChaosWallMimicController");
            aiActor.CollisionDamage            = 0.5f;
            aiActor.CollisionKnockbackStrength = m_collisionKnockbackStrength;
            yield break;
        }
예제 #7
0
        private void SpawnObjects(GameObject[] selectedObjects)
        {
            ObjectPrefabSpawnCount = selectedObjects.Length;
            if (ObjectPrefabSpawnCount < 0 | selectedObjects == null)
            {
                if (ExpandSettings.debugMode)
                {
                    ETGModConsole.Log("[DEBUG] ERROR: Object array is empty or null! Nothing to spawn!");
                }
                return;
            }
            IntVector2 pos = specRigidbody.UnitCenter.ToIntVector2(VectorConversions.Floor);

            if (aiActor.IsFalling && !allowSpawnOverPit)
            {
                return;
            }
            if (GameManager.Instance.Dungeon.CellIsPit(specRigidbody.UnitCenter.ToVector3ZUp(0f)) && !allowSpawnOverPit)
            {
                return;
            }
            RoomHandler roomFromPosition     = GameManager.Instance.Dungeon.GetRoomFromPosition(pos);
            List <SpeculativeRigidbody> list = new List <SpeculativeRigidbody>();

            list.Add(specRigidbody);
            Vector2 unitBottomLeft = specRigidbody.UnitBottomLeft;

            for (int i = 0; i < ObjectPrefabSpawnCount; i++)
            {
                if (objectsToSpawn == null)
                {
                    return;
                }
                GameObject SelectedObject = selectedObjects[i];
                if (spawnRatCorpse)
                {
                    SelectedObject = ExpandPrefabs.RatCorpseNPC;
                }
                GameObject SpawnedObject = null;
                if (!usesExternalObjectArray)
                {
                    if (spawnRatCorpse)
                    {
                        SpawnedObject = Instantiate(SelectedObject, (specRigidbody.GetUnitCenter(ColliderType.HitBox) - new Vector2(0.6f, 0.6f)).ToVector3ZUp(), Quaternion.identity);
                    }
                    else if (SelectedObject.GetComponent <Chest>() != null)
                    {
                        if (GameManager.Instance.Dungeon.GetRoomFromPosition(aiActor.transform.PositionVector2().ToIntVector2()) != null)
                        {
                            // RoomHandler currentRoom = aiActor.GetAbsoluteParentRoom();
                            RoomHandler        currentRoom  = GameManager.Instance.Dungeon.GetRoomFromPosition(aiActor.transform.PositionVector2().ToIntVector2());
                            Chest              TruthChest   = SelectedObject.GetComponent <Chest>();
                            WeightedGameObject wChestObject = new WeightedGameObject();
                            wChestObject.rawGameObject = SelectedObject;
                            WeightedGameObjectCollection wChestObjectCollection = new WeightedGameObjectCollection();
                            wChestObjectCollection.Add(wChestObject);
                            Chest PlacedTruthChest = currentRoom.SpawnRoomRewardChest(wChestObjectCollection, aiActor.transform.PositionVector2().ToIntVector2());
                            SpawnedObject = PlacedTruthChest.gameObject;
                        }
                    }
                    else
                    {
                        SpawnedObject = Instantiate(SelectedObject, specRigidbody.UnitCenter.ToIntVector2(VectorConversions.Floor).ToVector3(), Quaternion.identity);
                    }
                    if (SpawnedObject == null)
                    {
                        return;
                    }
                }

                if (SpawnedObject == null)
                {
                    return;
                }

                if (ExpandSettings.debugMode)
                {
                    ETGModConsole.Log("About to Spawn an object after death.");
                    ETGModConsole.Log("Object: " + SpawnedObject.name);
                    ETGModConsole.Log("AIActor:" + aiActor.GetActorName());
                }

                float RandomIntervalFloat       = UnityEngine.Random.Range(0.02f, 0.06f);
                float RandomDispFloat           = UnityEngine.Random.Range(0.1f, 0.16f);
                float RandomDispIntensityFloat  = UnityEngine.Random.Range(0.1f, 0.4f);
                float RandomColorProbFloat      = UnityEngine.Random.Range(0.05f, 0.2f);
                float RandomColorIntensityFloat = UnityEngine.Random.Range(0.1f, 0.25f);

                if (!spawnRatCorpse)
                {
                    if (SpawnedObject.GetComponent <tk2dBaseSprite>() != null)
                    {
                        ExpandShaders.Instance.ApplyGlitchShader(SpawnedObject.GetComponent <tk2dBaseSprite>(), true, RandomIntervalFloat, RandomDispFloat, RandomDispIntensityFloat, RandomColorProbFloat, RandomColorProbFloat);
                    }
                    else if (SpawnedObject.GetComponentInChildren <tk2dBaseSprite>() != null && SpawnedObject.GetComponent <Chest>() == null)
                    {
                        ExpandShaders.Instance.ApplyGlitchShader(SpawnedObject.GetComponentInChildren <tk2dBaseSprite>(), true, RandomIntervalFloat, RandomDispFloat, RandomDispIntensityFloat, RandomColorProbFloat, RandomColorProbFloat);
                    }
                }
                if (SpawnedObject != null)
                {
                    if (!usesExternalObjectArray && SpawnedObject.GetComponent <MysteryMimicManController>() != null)
                    {
                        Destroy(SpawnedObject.GetComponent <MysteryMimicManController>());
                    }

                    if (!usesExternalObjectArray && SpawnedObject.GetComponent <TalkDoerLite>() != null)
                    {
                        TalkDoerLite talkdoerComponent = SpawnedObject.GetComponent <TalkDoerLite>();
                        talkdoerComponent.SpeaksGleepGlorpenese = true;
                        talkdoerComponent.transform.position.XY().GetAbsoluteRoom().RegisterInteractable(talkdoerComponent);
                        if (SpawnedObject.name == ExpandPrefabs.RatCorpseNPC.name && !usesExternalObjectArray)
                        {
                            talkdoerComponent.transform.position.XY().GetAbsoluteRoom().TransferInteractableOwnershipToDungeon(talkdoerComponent);
                        }
                        else if (spawnRatCorpse)
                        {
                            talkdoerComponent.transform.position.XY().GetAbsoluteRoom().TransferInteractableOwnershipToDungeon(talkdoerComponent);
                        }
                        if (SpawnedObject.name.StartsWith(ExpandPrefabs.RatCorpseNPC.name))
                        {
                            talkdoerComponent.playmakerFsm.SetState("Set Mode");
                            // ExpandUtility.AddHealthHaver(talkdoerComponent.gameObject, 60, flashesOnDamage: false, exploderSpawnsItem: ratCorpseSpawnsItemOnExplosion);
                            ExpandUtility.GenerateHealthHaver(talkdoerComponent.gameObject, 60, flashesOnDamage: false, exploderSpawnsItem: ratCorpseSpawnsItemOnExplosion, isCorruptedObject: false, isRatNPC: true);
                            if (ratCorpseSpawnsKey)
                            {
                                HealthHaver ratCorpseHealthHaver = talkdoerComponent.gameObject.GetComponent <HealthHaver>();
                                ratCorpseHealthHaver.gameObject.AddComponent <ExpandSpawnGlitchObjectOnDeath>();
                                ExpandSpawnGlitchObjectOnDeath ratCorpseObjectSpawnOnDeath = ratCorpseHealthHaver.gameObject.GetComponent <ExpandSpawnGlitchObjectOnDeath>();
                                ratCorpseObjectSpawnOnDeath.spawnRatKey = true;
                            }
                        }
                    }

                    if (!usesExternalObjectArray && SpawnedObject.GetComponentInChildren <KickableObject>() != null && SpawnedObject.GetComponent <TalkDoerLite>() == null)
                    {
                        KickableObject kickableObjectComponent = SpawnedObject.GetComponentInChildren <KickableObject>();
                        kickableObjectComponent.transform.position.XY().GetAbsoluteRoom().RegisterInteractable(kickableObjectComponent);
                        kickableObjectComponent.ConfigureOnPlacement(kickableObjectComponent.transform.position.XY().GetAbsoluteRoom());
                    }

                    if (!usesExternalObjectArray && SpawnedObject.GetComponent <FlippableCover>() != null)
                    {
                        FlippableCover tableComponent = SpawnedObject.GetComponent <FlippableCover>();
                        tableComponent.transform.position.XY().GetAbsoluteRoom().RegisterInteractable(tableComponent);
                        tableComponent.ConfigureOnPlacement(tableComponent.transform.position.XY().GetAbsoluteRoom());
                        SpawnedObject.AddComponent <ExpandKickableObject>();
                        ExpandKickableObject chaosKickableComponent = SpawnedObject.GetComponent <ExpandKickableObject>();
                        chaosKickableComponent.transform.position.XY().GetAbsoluteRoom().RegisterInteractable(chaosKickableComponent);
                    }

                    if (!usesExternalObjectArray && SpawnedObject.GetComponent <NoteDoer>() != null)
                    {
                        NoteDoer noteComponent = SpawnedObject.GetComponent <NoteDoer>();
                        noteComponent.transform.position.XY().GetAbsoluteRoom().RegisterInteractable(noteComponent);
                        noteComponent.alreadyLocalized     = true;
                        noteComponent.useAdditionalStrings = false;
                        noteComponent.stringKey            = ("Here lies " + aiActor.GetActorName() + "\nHe was annoying anyways....");
                    }

                    /*if (!usesExternalObjectArray && SpawnedObject.GetComponent<HeartDispenser>() != null) {
                     *  HeartDispenser heartDispenserComponent = SpawnedObject.GetComponent<HeartDispenser>();
                     *  heartDispenserComponent.transform.position.XY().GetAbsoluteRoom().RegisterInteractable(heartDispenserComponent);
                     * }*/

                    if (SpawnedObject.GetComponentInChildren <SpeculativeRigidbody>() != null &&
                        SpawnedObject.GetComponentInChildren <KickableObject>() == null &&
                        SpawnedObject.GetComponent <TrapController>() == null &&
                        SpawnedObject.GetComponent <FlippableCover>() == null &&
                        SpawnedObject.GetComponent <Chest>() == null &&
                        SelectedObject.name != "NPC_ResourcefulRat_Beaten" &&
                        !usesExternalObjectArray)
                    {
                        SpeculativeRigidbody SpawnedObjectRigidBody = SpawnedObject.GetComponentInChildren <SpeculativeRigidbody>();
                        SpawnedObjectRigidBody.PrimaryPixelCollider.Enabled = false;
                        SpawnedObjectRigidBody.HitboxPixelCollider.Enabled  = false;
                        SpawnedObjectRigidBody.CollideWithOthers            = false;
                    }
                }

                if (SpawnedObject.GetComponentInChildren <SpeculativeRigidbody>() != null && SpawnedObject.name.ToLower().StartsWith("Table"))
                {
                    try {
                        SpeculativeRigidbody objectSpecRigidBody = SpawnedObject.GetComponentInChildren <SpeculativeRigidbody>();
                        objectSpecRigidBody.Initialize();
                        Vector2 a      = unitBottomLeft - (objectSpecRigidBody.UnitBottomLeft - SpawnedObject.transform.position.XY());
                        Vector2 vector = a + new Vector2(Mathf.Max(0f, specRigidbody.UnitDimensions.x - objectSpecRigidBody.UnitDimensions.x), 0f);
                        SpawnedObject.transform.position = Vector2.Lerp(a, vector, (ObjectPrefabSpawnCount != 1) ? i / (ObjectPrefabSpawnCount - 1f) : 0f);
                        objectSpecRigidBody.Reinitialize();
                        a      -= new Vector2(PhysicsEngine.PixelToUnit(extraPixelWidth), 0f);
                        vector += new Vector2(PhysicsEngine.PixelToUnit(extraPixelWidth), 0f);
                        Vector2       a2            = Vector2.Lerp(a, vector, (ObjectPrefabSpawnCount != 1) ? i / (ObjectPrefabSpawnCount - 1f) : 0.5f);
                        IntVector2    intVector     = PhysicsEngine.UnitToPixel(a2 - SpawnedObject.transform.position.XY());
                        CollisionData collisionData = null;
                        if (PhysicsEngine.Instance.RigidbodyCastWithIgnores(objectSpecRigidBody, intVector, out collisionData, true, true, null, false, list.ToArray()))
                        {
                            intVector = collisionData.NewPixelsToMove;
                        }
                        CollisionData.Pool.Free(ref collisionData);
                        SpawnedObject.transform.position += PhysicsEngine.PixelToUnit(intVector).ToVector3ZUp(1f);
                        objectSpecRigidBody.Reinitialize();
                        list.Add(objectSpecRigidBody);
                    } catch (Exception ex) {
                        if (ExpandSettings.debugMode)
                        {
                            ETGModConsole.Log("[DEBUG]: Warning: Exception caught while setting up rigid body settings in ChaosSpawnGlitchedObjectONDeath!");
                            Debug.Log("Warning: Exception caught while setting up rigid body settings in ChaosSpawnGlitchedObjectONDeath!");
                            Debug.LogException(ex);
                        }
                    }
                }
            }
            if (list.Count > 0)
            {
                for (int j = 0; j < list.Count; j++)
                {
                    for (int k = 0; k < list.Count; k++)
                    {
                        if (j != k)
                        {
                            list[j].RegisterGhostCollisionException(list[k]);
                        }
                    }
                }
            }
        }