示例#1
0
        public static void Init(AssetBundle expandSharedAssets1)
        {
            PowBlockObject = expandSharedAssets1.LoadAsset <GameObject>("Pow Block");

            tk2dSprite m_PowBlockSprite = SpriteSerializer.AddSpriteToObject(PowBlockObject, ExpandPrefabs.EXItemCollection, "PowBlock");

            ExpandUtility.GenerateSpriteAnimator(PowBlockObject, playAutomatically: true);

            tk2dSpriteAnimator m_PowBlockAnimator = PowBlockObject.GetComponent <tk2dSpriteAnimator>();

            ExpandUtility.AddAnimation(m_PowBlockAnimator, m_PowBlockSprite.Collection, PowBlockIdleSprites, "Idle", tk2dSpriteAnimationClip.WrapMode.Loop, 8);
            ExpandUtility.AddAnimation(m_PowBlockAnimator, m_PowBlockSprite.Collection, PowBlockUsedSprites, "POW", tk2dSpriteAnimationClip.WrapMode.Loop, 2);


            PowBlock powBlock  = PowBlockObject.AddComponent <PowBlock>();
            string   shortDesc = "Shaken not stirred...";
            string   longDesc  = "A special block that when stomped on causes a violent shaking.\n\nEnemies shall lose their footing.";

            ItemBuilder.SetupItem(powBlock, shortDesc, longDesc, "ex");
            ItemBuilder.SetCooldownType(powBlock, ItemBuilder.CooldownType.Damage, 380f);
            powBlock.quality = ItemQuality.C;
            if (!ExpandSettings.EnableEXItems)
            {
                powBlock.quality = ItemQuality.EXCLUDED;
            }


            PowBlockPickupID = powBlock.PickupObjectId;
        }
        public static void Init(AssetBundle expandSharedAssets1)
        {
            TheLeadKeyObject = expandSharedAssets1.LoadAsset <GameObject>("The Lead Key");
            SpriteSerializer.AddSpriteToObject(TheLeadKeyObject, ExpandPrefabs.EXItemCollection, "theleadkey");

            TheLeadKey theleadkey = TheLeadKeyObject.AddComponent <TheLeadKey>();
            string     shortDesc  = "Ancient Dungeons Beyond Space";
            string     longDesc   = "Takes you to a space that only exists in dreams, spitting you back out into the real world somewhere... else.";

            ItemBuilder.SetupItem(theleadkey, shortDesc, longDesc, "ex");
            ItemBuilder.SetCooldownType(theleadkey, ItemBuilder.CooldownType.Damage, 450f);
            theleadkey.quality = ItemQuality.B;
            if (!ExpandSettings.EnableEXItems)
            {
                theleadkey.quality = ItemQuality.EXCLUDED;
            }

            theleadkey.passiveStatModifiers = new StatModifier[] {
                new StatModifier()
                {
                    statToBoost   = PlayerStats.StatType.Curse,
                    amount        = 1,
                    modifyType    = StatModifier.ModifyMethod.ADDITIVE,
                    isMeatBunBuff = false
                }
            };

            TheLeadKeyPickupID = theleadkey.PickupObjectId;
        }
示例#3
0
        public static void Init(AssetBundle expandSharedAssets1)
        {
            WoodCrestObject = expandSharedAssets1.LoadAsset <GameObject>("Wooden Crest");
            SpriteSerializer.AddSpriteToObject(WoodCrestObject, ExpandPrefabs.EXItemCollection, "junglecrest");

            WoodenCrest woodenCrest = WoodCrestObject.AddComponent <WoodenCrest>();

            string shortDesc = "Protection of Wood";
            string longDesc  = "A shield made of wood. Provides fleeting protection.";

            ItemBuilder.SetupItem(woodenCrest, shortDesc, longDesc, "ex");
            // woodenCrest.quality = ItemQuality.SPECIAL;
            woodenCrest.quality = ItemQuality.EXCLUDED;
            woodenCrest.ItemSpansBaseQualityTiers      = false;
            woodenCrest.additionalMagnificenceModifier = 0;
            woodenCrest.ItemRespectsHeartMagnificence  = true;
            woodenCrest.associatedItemChanceMods       = new LootModData[0];
            woodenCrest.contentSource             = ContentSource.BASE;
            woodenCrest.ShouldBeExcludedFromShops = false;
            woodenCrest.CanBeDropped = false;
            woodenCrest.PreventStartingOwnerFromDropping = false;
            woodenCrest.PersistsOnDeath            = false;
            woodenCrest.PersistsOnPurchase         = false;
            woodenCrest.RespawnsIfPitfall          = false;
            woodenCrest.PreventSaveSerialization   = false;
            woodenCrest.IgnoredByRat               = false;
            woodenCrest.SaveFlagToSetOnAcquisition = 0;
            woodenCrest.UsesCustomCost             = false;
            woodenCrest.CustomCost                 = 65;
            woodenCrest.CanBeSold                  = false;
            woodenCrest.passiveStatModifiers       = new StatModifier[0];
            woodenCrest.ArmorToGainOnInitialPickup = 0;

            WoodCrestID = woodenCrest.PickupObjectId;
        }
示例#4
0
        public static void Init(AssetBundle expandSharedAssets1)
        {
            CursedBrickObject = expandSharedAssets1.LoadAsset <GameObject>("Cursed Brick");
            SpriteSerializer.AddSpriteToObject(CursedBrickObject, ExpandPrefabs.EXItemCollection, "cursedbrick");

            CursedBrick cursedBrick = CursedBrickObject.AddComponent <CursedBrick>();

            string shortDesc = "Fragment of a living wall...";
            string longDesc  = "There seems to be sounds emanating from the walls around you!\n\nThis item can't be dropped.";

            ItemBuilder.SetupItem(cursedBrick, shortDesc, longDesc, "ex");
            cursedBrick.quality = ItemQuality.D;
            if (!ExpandSettings.EnableEXItems)
            {
                cursedBrick.quality = ItemQuality.EXCLUDED;
            }
            cursedBrick.CanBeDropped         = false;
            cursedBrick.passiveStatModifiers = new StatModifier[] {
                new StatModifier()
                {
                    statToBoost   = PlayerStats.StatType.Curse,
                    amount        = 1,
                    modifyType    = StatModifier.ModifyMethod.ADDITIVE,
                    isMeatBunBuff = false
                }
            };

            CursedBrickID = cursedBrick.PickupObjectId;
        }
        public static void Init(AssetBundle expandSharedAssets1)
        {
            // Master round for Custom Secret Floor via Hollow
            GlitchFloorMasterRound = expandSharedAssets1.LoadAsset <GameObject>("Corrupted Master Round");
            SpriteSerializer.AddSpriteToObject(GlitchFloorMasterRound, ExpandPrefabs.EXItemCollection, "glitchround");

            BasicStatPickup CanyonMasterRoundItem = GlitchFloorMasterRound.AddComponent <BasicStatPickup>();
            string          shortDesc             = "Corrupted Chamber";
            string          longDesc = "This weird artifact indicates mastery of... somewhere";

            ItemBuilder.SetupItem(CanyonMasterRoundItem, shortDesc, longDesc, "ex");
            // CanyonMasterRoundItem.quality = PickupObject.ItemQuality.SPECIAL;
            CanyonMasterRoundItem.quality = PickupObject.ItemQuality.EXCLUDED;
            CanyonMasterRoundItem.ItemSpansBaseQualityTiers      = false;
            CanyonMasterRoundItem.additionalMagnificenceModifier = 0;
            CanyonMasterRoundItem.ItemRespectsHeartMagnificence  = true;
            CanyonMasterRoundItem.associatedItemChanceMods       = new LootModData[0];
            CanyonMasterRoundItem.contentSource             = ContentSource.BASE;
            CanyonMasterRoundItem.ShouldBeExcludedFromShops = false;
            CanyonMasterRoundItem.CanBeDropped = true;
            CanyonMasterRoundItem.PreventStartingOwnerFromDropping = false;
            CanyonMasterRoundItem.PersistsOnDeath            = false;
            CanyonMasterRoundItem.RespawnsIfPitfall          = false;
            CanyonMasterRoundItem.PreventSaveSerialization   = false;
            CanyonMasterRoundItem.IgnoredByRat               = false;
            CanyonMasterRoundItem.SaveFlagToSetOnAcquisition = 0;
            // CanyonMasterRoundItem.ForcedPositionInAmmonomicon = 5;
            CanyonMasterRoundItem.UsesCustomCost             = true;
            CanyonMasterRoundItem.CustomCost                 = 90;
            CanyonMasterRoundItem.CanBeSold                  = true;
            CanyonMasterRoundItem.passiveStatModifiers       = new StatModifier[0];
            CanyonMasterRoundItem.ArmorToGainOnInitialPickup = 0;
            CanyonMasterRoundItem.modifiers                  = new List <StatModifier>()
            {
                new StatModifier()
                {
                    statToBoost   = PlayerStats.StatType.Health,
                    modifyType    = StatModifier.ModifyMethod.ADDITIVE,
                    amount        = 1,
                    isMeatBunBuff = false
                }
            };
            CanyonMasterRoundItem.ArmorToGive                     = 0;
            CanyonMasterRoundItem.ModifiesDodgeRoll               = false;
            CanyonMasterRoundItem.DodgeRollTimeMultiplier         = 0.9f;
            CanyonMasterRoundItem.DodgeRollDistanceMultiplier     = 1.25f;
            CanyonMasterRoundItem.AdditionalInvulnerabilityFrames = 0;
            CanyonMasterRoundItem.IsJunk         = false;
            CanyonMasterRoundItem.GivesCurrency  = false;
            CanyonMasterRoundItem.CurrencyToGive = 0;
            CanyonMasterRoundItem.IsMasteryToken = true;
            GtlichFloorMasterRoundID             = CanyonMasterRoundItem.PickupObjectId;

            ExpandShaders.Instance.ApplyGlitchShader(CanyonMasterRoundItem.sprite);
            CanyonMasterRoundItem.sprite.usesOverrideMaterial = true;
        }
示例#6
0
        public static void Init(AssetBundle expandSharedAssets1)
        {
            BabySitterObject = expandSharedAssets1.LoadAsset <GameObject>("Baby Sitter");
            SpriteSerializer.AddSpriteToObject(BabySitterObject, ExpandPrefabs.EXItemCollection, "babysitter");

            BabySitter babysitItem = BabySitterObject.AddComponent <BabySitter>();

            string shortDesc = "You've got a friend in me...";
            string longDesc  = "Looks like you're stuck baby sitting him today.\n\nHe'll try his best to be useful.\nTry not to get him killed.";

            ItemBuilder.SetupItem(babysitItem, shortDesc, longDesc, "ex");
            babysitItem.quality = ItemQuality.B;
            if (!ExpandSettings.EnableEXItems)
            {
                babysitItem.quality = ItemQuality.EXCLUDED;
            }
        }
示例#7
0
        public static void Init(AssetBundle expandSharedAssets1)
        {
            MimiclayObject = expandSharedAssets1.LoadAsset <GameObject>("Mimiclay");
            SpriteSerializer.AddSpriteToObject(MimiclayObject, ExpandPrefabs.EXItemCollection, "ex_mimiclay");

            Mimiclay mimiClay = MimiclayObject.AddComponent <Mimiclay>();

            string shortDesc = "The Highest Form Of Flattery";
            string longDesc  = "Becomes a copy of any item.\n\nMalleable material that formed the mysterious Doppelgunner. After its defeat, it seems oddly content with applying its ability in service of Gungeoneers.";

            ItemBuilder.SetupItem(mimiClay, shortDesc, longDesc, "ex");
            ItemBuilder.SetCooldownType(mimiClay, ItemBuilder.CooldownType.Timed, 1);

            mimiClay.consumable = true;
            mimiClay.quality    = ItemQuality.SPECIAL;

            MimiclayPickupID = mimiClay.PickupObjectId;
        }
示例#8
0
        public static void Init(AssetBundle expandSharedAssets1)
        {
            TableTechAssassinHook.TableExplosionData = ExpandUtility.GenerateExplosionData(damage: 60);

            TableTechAssasinObject = expandSharedAssets1.LoadAsset <GameObject>("Table Tech Assassin");
            SpriteSerializer.AddSpriteToObject(TableTechAssasinObject, ExpandPrefabs.EXItemCollection, "tabletech_assassin");

            TableTechAssassin tableTechAssassin = TableTechAssasinObject.AddComponent <TableTechAssassin>();

            string shortDesc = "Betray the Flipper";
            string longDesc  = "A forbidden technique thought lost was recovered in the Gungeon.\n\nAll that was written was this: \n\n 'Do upon the flipper that which the flipper had done to you'";

            ItemBuilder.SetupItem(tableTechAssassin, shortDesc, longDesc, "ex");
            tableTechAssassin.quality = ItemQuality.D;
            if (!ExpandSettings.EnableEXItems)
            {
                tableTechAssassin.quality = ItemQuality.EXCLUDED;
            }
            TableTechAssasinID = tableTechAssassin.PickupObjectId;
        }
示例#9
0
        public static void Init(AssetBundle expandSharedAssets1)
        {
            SonicBoxObject = expandSharedAssets1.LoadAsset <GameObject>("EXSonicBox");
            SpriteSerializer.AddSpriteToObject(SonicBoxObject, ExpandPrefabs.EXItemCollection, "SonicBox_Idle_02");

            ExpandUtility.GenerateSpriteAnimator(SonicBoxObject, playAutomatically: true);
            ExpandUtility.AddAnimation(SonicBoxObject.GetComponent <tk2dSpriteAnimator>(), ExpandPrefabs.EXItemCollection.GetComponent <tk2dSpriteCollectionData>(), m_IdleFrames, "Idle", tk2dSpriteAnimationClip.WrapMode.Loop, 16);

            SonicBox sonicBoxItem = SonicBoxObject.AddComponent <SonicBox>();

            string name      = "Sonic Box";
            string shortDesc = "Gotta Go Fast!";
            string longDesc  = "Sonic the Hedgehog has found his way to the Gungeon and loves to spin dash into the Gundead!";

            ItemBuilder.SetupEXItem(sonicBoxItem, name, shortDesc, longDesc);
            sonicBoxItem.quality = ItemQuality.A;
            if (!ExpandSettings.EnableEXItems)
            {
                sonicBoxItem.quality = ItemQuality.EXCLUDED;
            }
            ;
        }
        public static void Init(AssetBundle expandSharedAssets1)
        {
            CronebergItemObject = expandSharedAssets1.LoadAsset <GameObject>("Cronenberg Bullets");
            SpriteSerializer.AddSpriteToObject(CronebergItemObject, ExpandPrefabs.EXItemCollection, "cronenbergbullets");

            CronenbergBullets chronenbergBullets = CronebergItemObject.AddComponent <CronenbergBullets>();

            string shortDesc = "Creates abominations...";
            string longDesc  = "Legends say a mad scientist tried to experiment on the gundead to create monsters to do his bidding.\n\nHe ultimiately parished by the hands of his own abominations. The item he crafted was thought to be lost to the Gungeon...Until some lucky (or unlucky?) Gungeoneers found it.";

            ItemBuilder.SetupItem(chronenbergBullets, shortDesc, longDesc, "ex");
            chronenbergBullets.quality = ItemQuality.B;
            if (!ExpandSettings.EnableEXItems)
            {
                chronenbergBullets.quality = ItemQuality.EXCLUDED;
            }

            chronenbergBullets.CustomCost              = 50;
            chronenbergBullets.chanceOfActivating      = 0.055f;
            chronenbergBullets.chanceFromBeamPerSecond = 0.055f;
            chronenbergBullets.TintBullets             = false;
            chronenbergBullets.TintBeams                  = false;
            chronenbergBullets.TintColor                  = new Color(0.94f, 0f, 0.992f, 1f);
            chronenbergBullets.TintPriority               = 5;
            chronenbergBullets.AddsDamageType             = false;
            chronenbergBullets.DamageTypesToAdd           = CoreDamageTypes.None;
            chronenbergBullets.AppliesSpeedModifier       = false;
            chronenbergBullets.AppliesDamageOverTime      = false;
            chronenbergBullets.AppliesCharm               = false;
            chronenbergBullets.AppliesFreeze              = false;
            chronenbergBullets.FreezeScalesWithDamage     = false;
            chronenbergBullets.FreezeAmountPerDamage      = 1;
            chronenbergBullets.AppliesFire                = false;
            chronenbergBullets.ConfersElectricityImmunity = false;
            chronenbergBullets.AppliesTransmog            = true;
            chronenbergBullets.TransmogTargetGuid         = "76bc43539fc24648bff4568c75c686d1";
            chronenbergBullets.Synergies                  = new BulletStatusEffectItemSynergy[0];
            m_CachedCronenbergBulletsItem                 = chronenbergBullets;
        }
示例#11
0
        public static void Init(AssetBundle expandSharedAssets1)
        {
            RockslideObject = expandSharedAssets1.LoadAsset <GameObject>("Rock Slide");
            SpriteSerializer.AddSpriteToObject(RockslideObject, ExpandPrefabs.EXItemCollection, "rockslide");

            RockSlide rockslide = RockslideObject.AddComponent <RockSlide>();
            string    shortDesc = "Crushing Defeat";
            string    longDesc  = "Falling rocks are a well known threat to everyone, especially within the Gungeon.\n\nIt does not help that a long gone Gungeoneer accidentally popularized the idea of using falling debris as a weapon among the Gundead.\n\nHowever, they quickly grew tired of it, seeming too easy or effortless to eliminate Gungeoneers compared to the exhilarating experience of the combat they were forged for.";

            ItemBuilder.SetupItem(rockslide, shortDesc, longDesc, "ex");
            ItemBuilder.SetCooldownType(rockslide, ItemBuilder.CooldownType.Damage, 275f);
            rockslide.quality = ItemQuality.B;
            if (!ExpandSettings.EnableEXItems)
            {
                rockslide.quality = ItemQuality.EXCLUDED;
            }

            List <string> spritePaths = new List <string>()
            {
                "plunger_fire_001",
                "plunger_fire_002",
                "plunger_fire_003",
                "plunger_fire_004",
                "plunger_fire_005",
                "plunger_fire_006"
            };

            /*tk2dSprite rockslidesprite = RockslideObject.GetComponent<tk2dSprite>();
             * foreach (string sprite in spritePaths) { SpriteBuilder.AddSpriteToCollection(expandSharedAssets1.LoadAsset<Texture2D>(sprite), rockslidesprite.Collection); }*/

            ExpandUtility.GenerateSpriteAnimator(RockslideObject);

            tk2dSpriteAnimator rockslideAnimator = RockslideObject.GetComponent <tk2dSpriteAnimator>();

            ExpandUtility.AddAnimation(rockslideAnimator, ExpandPrefabs.EXItemCollection.GetComponent <tk2dSpriteCollectionData>(), spritePaths, "Activate", frameRate: 8);

            RockSlidePickupID = rockslide.PickupObjectId;
        }
        public static void Init(AssetBundle expandSharedAssets1)
        {
            CorruptedJunkObject = expandSharedAssets1.LoadAsset <GameObject>("Corrupted Junk");

            CorruptedJunk poopSack = CorruptedJunkObject.AddComponent <CorruptedJunk>();

            SpriteSerializer.AddSpriteToObject(CorruptedJunkObject, ExpandPrefabs.EXItemCollection, "corrupted_poopsack_09");

            string shortDesc = "Next Time... What even is this!?";
            string longDesc  = "Just some corrupted junk.\n\nCarrying this around makes you question your sanity...";

            ItemBuilder.SetupItem(poopSack, shortDesc, longDesc, "ex");
            poopSack.quality = ItemQuality.A;
            if (!ExpandSettings.EnableEXItems)
            {
                poopSack.quality = ItemQuality.EXCLUDED;
            }
            poopSack.CanBeDropped = false;
            CorruptedJunkID       = poopSack.PickupObjectId;

            m_SpriteNames = new List <string> {
                "corrupted_poopsack_01",
                "corrupted_poopsack_02",
                "corrupted_poopsack_03",
                "corrupted_poopsack_04",
                "corrupted_poopsack_05",
                "corrupted_poopsack_06",
                "corrupted_poopsack_07",
                "corrupted_poopsack_08",
                "corrupted_poopsack_09",
                "corrupted_poopsack_10"
            };

            ExpandUtility.GenerateSpriteAnimator(CorruptedJunkObject, playAutomatically: true);
            ExpandUtility.AddAnimation(CorruptedJunkObject.GetComponent <tk2dSpriteAnimator>(), ExpandPrefabs.EXItemCollection.GetComponent <tk2dSpriteCollectionData>(), m_SpriteNames, "idle", tk2dSpriteAnimationClip.WrapMode.RandomLoop, 20);
        }
示例#13
0
        private static void SetupHand(AssetBundle assetBundle, out GameObject handPrefab, tk2dSpriteCollectionData collection)
        {
            var spriteDefinition = collection.GetSpriteDefinition("Western_Bros_Hand");

            // change the sprite definition so the sprite is centered, so it can be flipped without offsets
            spriteDefinition.boundsDataCenter          = Vector3.zero;
            spriteDefinition.untrimmedBoundsDataCenter = Vector3.zero;

            float val = 0.2f;

            spriteDefinition.boundsDataExtents          = new Vector3(val * 2, val * 2, 0);
            spriteDefinition.untrimmedBoundsDataExtents = new Vector3(val * 2, val * 2, 0);

            spriteDefinition.position0 = new Vector3(-val, -val, 0);
            spriteDefinition.position1 = new Vector3(val, -val, 0);
            spriteDefinition.position2 = new Vector3(-val, val, 0);
            spriteDefinition.position3 = new Vector3(val, val, 0);

            handPrefab = assetBundle.LoadAsset <GameObject>("WestBroHandObject");

            var sprite = SpriteSerializer.AddSpriteToObject(handPrefab, ExpandCustomEnemyDatabase.WestBrosCollection, spriteDefinition.name);

            handPrefab.AddComponent <PlayerHandController>();
        }
示例#14
0
        private void ExpandSerializeCollection(string[] consoleText)
        {
            if (consoleText.Length == 3)
            {
                List <string> spritePaths = new List <string>()
                {
                    "babygoodhammer",
                    "babygoodhammer_spawn_00",
                    "babygoodhammer_spawn_01",
                    "babygoodhammer_spawn_02",
                    "babygoodhammer_spawn_03",
                    "babygoodhammer_spawn_04",
                    "babygoodhammer_spawn_05",
                    "babygoodhammer_spawn_06",
                    "babygoodhammer_spawn_07",
                    "babygoodhammer_spawn_08",
                    "babygoodhammer_spawn_09",
                    "babygoodhammer_spawn_10",
                    "babygoodhammer_spawn_11",
                    "babygoodhammer_spawn_12",
                    "babygoodhammer_spawn_13",
                    "babygoodhammer_spawn_14",
                    "babygoodhammer_spawn_15",
                    "babygoodhammer_spawn_16",
                    "babygoodhammer_spawn_17",
                    "babygoodhammer_spawn_18",
                    "babygoodhammer_spawn_19",
                    "babygoodhammer_spawn_20",
                    "babygoodhammer_spawn_21",
                    "babygoodhammer_spawn_22",
                    "babygoodhammer_spawn_23",
                    "babygoodhammer_spawn_24",
                    "babygoodhammer_spawn_25",
                    "babysitter",
                    "corrupted_poopsack_01",
                    "corrupted_poopsack_02",
                    "corrupted_poopsack_03",
                    "corrupted_poopsack_04",
                    "corrupted_poopsack_05",
                    "corrupted_poopsack_06",
                    "corrupted_poopsack_07",
                    "corrupted_poopsack_08",
                    "corrupted_poopsack_09",
                    "corrupted_poopsack_10",
                    "corruptionbomb",
                    "corruptionbomb_minimapicon",
                    "corruptionbomb_spin_01",
                    "corruptionbomb_spin_02",
                    "corruptionbomb_spin_03",
                    "corruptionbomb_spin_04",
                    "corruptionbomb_spin_05",
                    "corruptionbomb_spin_06",
                    "corruptionbomb_spin_07",
                    "corruptionbomb_spin_08",
                    "corruptionbomb_spin_09",
                    "corruptionbomb_spin_10",
                    "cronenbergbullets",
                    "cursedbrick",
                    "ex_mimiclay",
                    "glitchround",
                    "junglecrest",
                    "plunger_fire_001",
                    "plunger_fire_002",
                    "plunger_fire_003",
                    "plunger_fire_004",
                    "plunger_fire_005",
                    "plunger_fire_006",
                    "PowBlock",
                    "PowBlock_Idle_01",
                    "PowBlock_Idle_02",
                    "PowBlock_Idle_03",
                    "PowBlock_Idle_04",
                    "PowBlock_Idle_05",
                    "PowBlock_Idle_06",
                    "PowBlock_Idle_07",
                    "PowBlock_Idle_08",
                    "PowBlock_Idle_09",
                    "PowBlock_Idle_10",
                    "PowBlock_Idle_11",
                    "PowBlock_Idle_12",
                    "PowBlock_Idle_13",
                    "PowBlock_Idle_14",
                    "PowBlock_Used",
                    "rockslide",
                    "SonicBox_Idle_01",
                    "SonicBox_Idle_02",
                    "SonicBox_Idle_03",
                    "SonicBox_Broken_01",
                    "SonicRing_Idle_01",
                    "SonicRing_Idle_02",
                    "SonicRing_Idle_03",
                    "SonicRing_Idle_04",
                    "SonicRing_Idle_05",
                    "SonicRing_Idle_06",
                    "SonicRing_Idle_07",
                    "SonicRing_Idle_08",
                    "SonicRing_Idle_09",
                    "SonicRing_Idle_10",
                    "SonicRing_Idle_11",
                    "SonicRing_Idle_12",
                    "SonicRing_Idle_13",
                    "SonicRing_Idle_14",
                    "SonicRing_Idle_15",
                    "tabletech_assassin",
                    "theleadkey"
                };

                int X = int.Parse(consoleText[1]);
                int Y = int.Parse(consoleText[2]);
                SpriteSerializer.SerializeSpriteCollection(consoleText[0], spritePaths, X, Y);
            }
            else
            {
                ETGModConsole.Log("[ExpandTheGungeon] Not enough commands or too many! Must provide atlas name and resolution! Please specify a name, width, and height!");
            }
        }
        public static void Init(AssetBundle expandSharedAssets1)
        {
            Gun pistol = ETGMod.Databases.Items.NewGun("Bootleg Pistol", "bootleg_pistol");

            Game.Items.Rename("outdated_gun_mods:bootleg_pistol", "ex:bootleg_pistol");
            pistol.SetShortDescription("Of questionable quality...");
            pistol.SetLongDescription("It's a counterfeit gun.\n\nDue to low quality standards, this weapon may be prone to exploding under certain circumstances...");
            GunExt.SetupSprite(pistol, null, "bootleg_pistol_idle_001", 18);
            pistol.AddProjectileModuleFrom("Magnum", true, false);
            pistol.barrelOffset.localPosition -= new Vector3(0.3f, 0.2f, 0);
            pistol.DefaultModule.ammoCost      = 1;
            pistol.PreventOutlines             = true;
            pistol.reloadTime = 1;
            pistol.gunClass   = GunClass.PISTOL;
            pistol.ammo       = 140;
            pistol.SetBaseMaxAmmo(140);
            pistol.quality = ItemQuality.D;
            if (!ExpandSettings.EnableEXItems)
            {
                pistol.quality = ItemQuality.EXCLUDED;
            }
            pistol.UsesCustomCost = true;
            pistol.CustomCost     = 10;
            pistol.encounterTrackable.EncounterGuid = "baad9dd6d005458daf02933f6a1ba926";
            pistol.gameObject.AddComponent <ExpandRemoveGunOnAmmoDepletion>();
            pistol.gameObject.AddComponent <ExpandMaybeLoseAmmoOnDamage>();
            ETGMod.Databases.Items.Add(pistol);
            BootlegPistolID = pistol.PickupObjectId;

            PistolProjectile = expandSharedAssets1.LoadAsset <GameObject>("EXBootlegPistolProjectile");
            tk2dSprite           PistolProjectileSprite    = SpriteSerializer.AddSpriteToObject(PistolProjectile.transform.Find("Sprite").gameObject, ExpandPrefabs.EXGunCollection, "bootleg_pistol_projectile_001");
            SpeculativeRigidbody pistolProjectileRigidBody = PistolProjectile.AddComponent <SpeculativeRigidbody>();

            ExpandUtility.DuplicateRigidBody(pistolProjectileRigidBody, pistol.DefaultModule.projectiles[0].specRigidbody);
            Projectile PistolProjectileComponent = PistolProjectile.AddComponent <Projectile>();

            ExpandUtility.DuplicateComponent(PistolProjectileComponent, pistol.DefaultModule.projectiles[0]);
            pistol.DefaultModule.projectiles[0] = PistolProjectileComponent;
            PistolProjectile.gameObject.transform.localPosition = pistol.barrelOffset.localPosition;


            Gun machinepistol = ETGMod.Databases.Items.NewGun("Bootleg Machine Pistol", "bootleg_machinepistol");

            Game.Items.Rename("outdated_gun_mods:bootleg_machine_pistol", "ex:bootleg_machine_pistol");
            machinepistol.SetShortDescription("Of questionable quality...");
            machinepistol.SetLongDescription("It's a counterfeit machine gun.\n\nDue to low quality standards, this weapon may be prone to exploding under certain circumstances...");
            GunExt.SetupSprite(machinepistol, null, "bootleg_machinepistol_idle_001", 30);
            machinepistol.AddProjectileModuleFrom(PickupObjectDatabase.GetById(43).name, true, false);
            machinepistol.barrelOffset.localPosition -= new Vector3(0.3f, 0.2f, 0);
            machinepistol.PreventOutlines             = true;
            machinepistol.reloadTime = 1.2f;
            machinepistol.gunClass   = GunClass.FULLAUTO;
            machinepistol.ammo       = 600;
            machinepistol.SetBaseMaxAmmo(600);
            machinepistol.quality = ItemQuality.D;
            if (!ExpandSettings.EnableEXItems)
            {
                machinepistol.quality = ItemQuality.EXCLUDED;
            }
            machinepistol.gunSwitchGroup = "Uzi";
            machinepistol.UsesCustomCost = true;
            machinepistol.CustomCost     = 15;
            machinepistol.encounterTrackable.EncounterGuid = "e56adda5081347e5b9e0cf2556689b0e";
            machinepistol.gameObject.AddComponent <ExpandRemoveGunOnAmmoDepletion>();
            machinepistol.gameObject.AddComponent <ExpandMaybeLoseAmmoOnDamage>();
            ETGMod.Databases.Items.Add(machinepistol);
            BootlegMachinePistolID = machinepistol.PickupObjectId;

            MachinePistolProjectile = expandSharedAssets1.LoadAsset <GameObject>("EXBootlegMachinePistolProjectile");
            tk2dSprite           MachinePistolProjectileSprite    = SpriteSerializer.AddSpriteToObject(MachinePistolProjectile.transform.Find("Sprite").gameObject, ExpandPrefabs.EXGunCollection, "bootleg_pistol_projectile_001");
            SpeculativeRigidbody machinePistolProjectileRigidBody = MachinePistolProjectile.AddComponent <SpeculativeRigidbody>();

            ExpandUtility.DuplicateRigidBody(machinePistolProjectileRigidBody, machinepistol.DefaultModule.projectiles[0].specRigidbody);
            Projectile MachinePistolProjectileComponent = MachinePistolProjectile.AddComponent <Projectile>();

            ExpandUtility.DuplicateComponent(MachinePistolProjectileComponent, machinepistol.DefaultModule.projectiles[0]);
            machinepistol.DefaultModule.projectiles[0] = MachinePistolProjectileComponent;
            MachinePistolProjectile.gameObject.transform.localPosition = machinepistol.barrelOffset.localPosition;


            Gun shotgun = ETGMod.Databases.Items.NewGun("Bootleg Shotgun", "bootleg_shotgun");

            Game.Items.Rename("outdated_gun_mods:bootleg_shotgun", "ex:bootleg_shotgun");
            shotgun.SetShortDescription("Of questionable quality...");
            shotgun.SetLongDescription("It's a counterfeit shotgun.\n\nDue to low quality standards, this weapon may be prone to exploding under certain circumstances...");
            GunExt.SetupSprite(shotgun, null, "bootleg_shotgun_idle_001", 18);
            shotgun.AddProjectileModuleFrom(PickupObjectDatabase.GetById(51).name, true, false);
            shotgun.barrelOffset.localPosition -= new Vector3(0.3f, 0.2f, 0);
            shotgun.PreventOutlines             = true;
            shotgun.reloadTime = 1.8f;
            shotgun.gunClass   = GunClass.SHOTGUN;
            shotgun.ammo       = 150;
            shotgun.SetBaseMaxAmmo(150);
            shotgun.quality = ItemQuality.D;
            if (!ExpandSettings.EnableEXItems)
            {
                shotgun.quality = ItemQuality.EXCLUDED;
            }
            shotgun.gunSwitchGroup = "Shotgun";
            shotgun.UsesCustomCost = true;
            shotgun.CustomCost     = 18;
            shotgun.encounterTrackable.EncounterGuid = "fa0575b4cf0140ddb6b0ed6d962bff47";
            shotgun.gameObject.AddComponent <ExpandRemoveGunOnAmmoDepletion>();
            shotgun.gameObject.AddComponent <ExpandMaybeLoseAmmoOnDamage>();
            ETGMod.Databases.Items.Add(shotgun);
            BootlegShotgunID = shotgun.PickupObjectId;

            ShotgunProjectile = expandSharedAssets1.LoadAsset <GameObject>("EXBootlegShotgunProjectile");
            tk2dSprite           ShotgunProjectileSprite    = SpriteSerializer.AddSpriteToObject(ShotgunProjectile.transform.Find("Sprite").gameObject, ExpandPrefabs.EXGunCollection, "bootleg_pistol_projectile_001");
            SpeculativeRigidbody ShotgunProjectileRigidBody = ShotgunProjectile.AddComponent <SpeculativeRigidbody>();

            ExpandUtility.DuplicateRigidBody(ShotgunProjectileRigidBody, shotgun.DefaultModule.projectiles[0].specRigidbody);
            Projectile ShotgunProjectileComponent = ShotgunProjectile.AddComponent <Projectile>();

            ExpandUtility.DuplicateComponent(ShotgunProjectileComponent, shotgun.DefaultModule.projectiles[0]);
            shotgun.DefaultModule.projectiles[0] = ShotgunProjectileComponent;
            ProjectileVolleyData shotgunVollyData = new ProjectileVolleyData()
            {
                projectiles = new List <ProjectileModule>()
                {
                    shotgun.DefaultModule,
                    new ProjectileModule(),
                    new ProjectileModule(),
                    new ProjectileModule(),
                    new ProjectileModule(),
                    new ProjectileModule(),
                },
                UsesBeamRotationLimiter      = false,
                BeamRotationDegreesPerSecond = 30,
                ModulesAreTiers = false,
                UsesShotgunStyleVelocityRandomizer = true,
                DecreaseFinalSpeedPercentMin       = -15,
                IncreaseFinalSpeedPercentMax       = 15
            };

            JsonUtility.FromJsonOverwrite(JsonUtility.ToJson(shotgun.DefaultModule), shotgunVollyData.projectiles[1]);
            JsonUtility.FromJsonOverwrite(JsonUtility.ToJson(shotgun.DefaultModule), shotgunVollyData.projectiles[2]);
            JsonUtility.FromJsonOverwrite(JsonUtility.ToJson(shotgun.DefaultModule), shotgunVollyData.projectiles[3]);
            JsonUtility.FromJsonOverwrite(JsonUtility.ToJson(shotgun.DefaultModule), shotgunVollyData.projectiles[4]);
            JsonUtility.FromJsonOverwrite(JsonUtility.ToJson(shotgun.DefaultModule), shotgunVollyData.projectiles[5]);
            shotgunVollyData.projectiles[1].ammoType = GameUIAmmoType.AmmoType.SMALL_BULLET;
            shotgunVollyData.projectiles[2].ammoType = GameUIAmmoType.AmmoType.SMALL_BULLET;
            shotgunVollyData.projectiles[3].ammoType = GameUIAmmoType.AmmoType.SMALL_BULLET;
            shotgunVollyData.projectiles[4].ammoType = GameUIAmmoType.AmmoType.SMALL_BULLET;
            shotgunVollyData.projectiles[5].ammoType = GameUIAmmoType.AmmoType.SMALL_BULLET;
            shotgun.Volley = shotgunVollyData;
            ShotgunProjectileComponent.gameObject.transform.localPosition = shotgun.barrelOffset.localPosition;


            BootlegPistol        = pistol;
            BootlegMachinePistol = machinepistol;
            BootlegShotgun       = shotgun;
        }
        public static void InitPrefabs(AssetBundle expandSharedAssets1)
        {
            EXSecretDoorAnimation = expandSharedAssets1.LoadAsset <GameObject>("EX_SecretDoor_Animation");

            tk2dSpriteAnimation DoorSpriteAnimations = EXSecretDoorAnimation.AddComponent <tk2dSpriteAnimation>();

            ExpandUtility.AddAnimation(DoorSpriteAnimations, ExpandPrefabs.EXSecretDoorCollection.GetComponent <tk2dSpriteCollectionData>(), m_DoorOpenSprites, "door_open", frameRate: 10);
            ExpandUtility.AddAnimation(DoorSpriteAnimations, ExpandPrefabs.EXSecretDoorCollection.GetComponent <tk2dSpriteCollectionData>(), m_DoorCloseSprites, "door_close", frameRate: 10);

            EXSecretDoorMinimapIcon = expandSharedAssets1.LoadAsset <GameObject>("EXSecretDoor_MinimapIcon");
            SpriteSerializer.AddSpriteToObject(EXSecretDoorMinimapIcon, ExpandPrefabs.EXSecretDoorCollection, "EXSecretDoor_MinimapIcon");

            EXSecretDoor_Hollow = expandSharedAssets1.LoadAsset <GameObject>("EX_Secret_Door_Hollow");
            GameObject EXSecretDoorHollow_Frame_Top    = EXSecretDoor_Hollow.transform.Find("FrameTop").gameObject;
            GameObject EXSecretDoorHollow_Frame_Bottom = EXSecretDoor_Hollow.transform.Find("FrameBottom").gameObject;
            GameObject EXSecretDoorHollow_Background   = EXSecretDoor_Hollow.transform.Find("Background").gameObject;
            GameObject EXSecretDoorHollow_Light        = EXSecretDoor_Hollow.transform.Find("Light").gameObject;
            GameObject EXSecretDoorHollow_Lock         = EXSecretDoor_Hollow.transform.Find("Lock").gameObject;


            tk2dSprite m_DoorHollowSprite             = SpriteSerializer.AddSpriteToObject(EXSecretDoor_Hollow, ExpandPrefabs.EXSecretDoorCollection, "EXSecretDoor_Open_00");
            tk2dSprite m_DoorHollowBorderTopSprite    = SpriteSerializer.AddSpriteToObject(EXSecretDoorHollow_Frame_Top, ExpandPrefabs.EXSecretDoorCollection, "EXSecretDoor_Frame_Top");
            tk2dSprite m_DoorHollowBorderBottomSprite = SpriteSerializer.AddSpriteToObject(EXSecretDoorHollow_Frame_Bottom, ExpandPrefabs.EXSecretDoorCollection, "EXSecretDoor_Frame_Bottom");
            tk2dSprite m_DoorHollowBackgroundSprite   = SpriteSerializer.AddSpriteToObject(EXSecretDoorHollow_Background, ExpandPrefabs.EXSecretDoorCollection, "EXSecretDoor_Background");
            tk2dSprite m_DoorHollowLightSprite        = SpriteSerializer.AddSpriteToObject(EXSecretDoorHollow_Light, ExpandPrefabs.EXSecretDoorCollection, "EXSecretDoor_Light_Red");

            m_DoorHollowBorderTopSprite.HeightOffGround    = 3;
            m_DoorHollowBorderBottomSprite.HeightOffGround = -0.5f;
            m_DoorHollowSprite.HeightOffGround             = -1.5f;
            m_DoorHollowBackgroundSprite.HeightOffGround   = -2f;
            m_DoorHollowLightSprite.HeightOffGround        = 3.5f;

            ExpandUtility.GenerateSpriteAnimator(EXSecretDoor_Hollow, DoorSpriteAnimations, ClipFps: 10);

            ExpandUtility.GenerateOrAddToRigidBody(EXSecretDoor_Hollow, CollisionLayer.HighObstacle, PixelCollider.PixelColliderGeneration.Manual, CanBeCarried: false, UsesPixelsAsUnitSize: true, dimensions: new IntVector2(32, 64), offset: new IntVector2(16, 0));
            ExpandUtility.GenerateOrAddToRigidBody(EXSecretDoor_Hollow, CollisionLayer.HighObstacle, PixelCollider.PixelColliderGeneration.Manual, CanBeCarried: false, UsesPixelsAsUnitSize: true, dimensions: new IntVector2(32, 32), offset: new IntVector2(16, 14));
            ExpandUtility.GenerateOrAddToRigidBody(EXSecretDoor_Hollow, CollisionLayer.LowObstacle, PixelCollider.PixelColliderGeneration.Manual, CanBeCarried: false, IsTrigger: true, UsesPixelsAsUnitSize: true, dimensions: new IntVector2(32, 32), offset: new IntVector2(16, 12));

            ExpandSecretDoorPlacable m_SecretDoorHollowComponent = EXSecretDoor_Hollow.AddComponent <ExpandSecretDoorPlacable>();

            m_SecretDoorHollowComponent.DoorTopBorderObject    = EXSecretDoorHollow_Frame_Top;
            m_SecretDoorHollowComponent.DoorBottomBorderObject = EXSecretDoorHollow_Frame_Bottom;
            m_SecretDoorHollowComponent.DoorBackgroundObject   = EXSecretDoorHollow_Background;
            m_SecretDoorHollowComponent.DoorLightObject        = EXSecretDoorHollow_Light;

            GameObject m_RatLock = ExpandPrefabs.RatJailDoor.GetComponent <InteractableDoorController>().WorldLocks[0].gameObject;

            tk2dSprite EXLockSprite = EXSecretDoorHollow_Lock.AddComponent <tk2dSprite>();

            ExpandUtility.DuplicateSprite(EXLockSprite, m_RatLock.GetComponent <tk2dSprite>());
            ExpandUtility.DuplicateSpriteAnimator(EXSecretDoorHollow_Lock, m_RatLock.GetComponent <tk2dSpriteAnimator>());
            EXLockSprite.HeightOffGround = -0.3f;


            InteractableLock m_EXLockHollow = EXSecretDoorHollow_Lock.AddComponent <InteractableLock>();

            m_EXLockHollow.Suppress          = m_RatLock.GetComponent <InteractableLock>().Suppress;
            m_EXLockHollow.lockMode          = InteractableLock.InteractableLockMode.RESOURCEFUL_RAT;
            m_EXLockHollow.JailCellKeyId     = m_RatLock.GetComponent <InteractableLock>().JailCellKeyId;
            m_EXLockHollow.IdleAnimName      = m_RatLock.GetComponent <InteractableLock>().IdleAnimName;
            m_EXLockHollow.UnlockAnimName    = m_RatLock.GetComponent <InteractableLock>().UnlockAnimName;
            m_EXLockHollow.NoKeyAnimName     = m_RatLock.GetComponent <InteractableLock>().NoKeyAnimName;
            m_EXLockHollow.SpitAnimName      = m_RatLock.GetComponent <InteractableLock>().SpitAnimName;
            m_EXLockHollow.BustedAnimName    = m_RatLock.GetComponent <InteractableLock>().BustedAnimName;
            m_SecretDoorHollowComponent.Lock = m_EXLockHollow;
            EXSecretDoor_Hollow.SetLayerRecursively(LayerMask.NameToLayer("FG_Critical"));

            EXSecretDoor_Hollow_Unlocked = expandSharedAssets1.LoadAsset <GameObject>("EX_Secret_Door_Hollow_Unlocked");
            GameObject EXSecretDoorHollowUnlocked_Frame_Top    = EXSecretDoor_Hollow_Unlocked.transform.Find("FrameTop").gameObject;
            GameObject EXSecretDoorHollowUnlocked_Frame_Bottom = EXSecretDoor_Hollow_Unlocked.transform.Find("FrameBottom").gameObject;
            GameObject EXSecretDoorHollowUnlocked_Background   = EXSecretDoor_Hollow_Unlocked.transform.Find("Background").gameObject;
            GameObject EXSecretDoorHollowUnlocked_Light        = EXSecretDoor_Hollow_Unlocked.transform.Find("Light").gameObject;

            tk2dSprite m_DoorHollow_UnlockedSprite             = SpriteSerializer.AddSpriteToObject(EXSecretDoor_Hollow_Unlocked, ExpandPrefabs.EXSecretDoorCollection, "EXSecretDoor_Open_00");
            tk2dSprite m_DoorHollow_UnlockedBorderTopSprite    = SpriteSerializer.AddSpriteToObject(EXSecretDoorHollowUnlocked_Frame_Top, ExpandPrefabs.EXSecretDoorCollection, "EXSecretDoor_Frame_Top");
            tk2dSprite m_DoorHollow_UnlockedBorderBottomSprite = SpriteSerializer.AddSpriteToObject(EXSecretDoorHollowUnlocked_Frame_Bottom, ExpandPrefabs.EXSecretDoorCollection, "EXSecretDoor_Frame_Bottom");
            tk2dSprite m_DoorHollow_UnlockedBackgroundSprite   = SpriteSerializer.AddSpriteToObject(EXSecretDoorHollowUnlocked_Background, ExpandPrefabs.EXSecretDoorCollection, "EXSecretDoor_Background");
            tk2dSprite m_DoorHollow_UnlockedLightSprite        = SpriteSerializer.AddSpriteToObject(EXSecretDoorHollowUnlocked_Light, ExpandPrefabs.EXSecretDoorCollection, "EXSecretDoor_Light_Red");

            m_DoorHollow_UnlockedBorderTopSprite.HeightOffGround    = 3;
            m_DoorHollow_UnlockedBorderBottomSprite.HeightOffGround = -0.5f;
            m_DoorHollow_UnlockedSprite.HeightOffGround             = -1.5f;
            m_DoorHollow_UnlockedBackgroundSprite.HeightOffGround   = -2f;
            m_DoorHollow_UnlockedLightSprite.HeightOffGround        = 3.5f;

            ExpandUtility.GenerateSpriteAnimator(EXSecretDoor_Hollow_Unlocked, DoorSpriteAnimations, ClipFps: 10);

            ExpandUtility.GenerateOrAddToRigidBody(EXSecretDoor_Hollow_Unlocked, CollisionLayer.HighObstacle, PixelCollider.PixelColliderGeneration.Manual, CanBeCarried: false, UsesPixelsAsUnitSize: true, dimensions: new IntVector2(32, 64), offset: new IntVector2(16, 0));
            ExpandUtility.GenerateOrAddToRigidBody(EXSecretDoor_Hollow_Unlocked, CollisionLayer.HighObstacle, PixelCollider.PixelColliderGeneration.Manual, CanBeCarried: false, UsesPixelsAsUnitSize: true, dimensions: new IntVector2(32, 32), offset: new IntVector2(16, 14));
            ExpandUtility.GenerateOrAddToRigidBody(EXSecretDoor_Hollow_Unlocked, CollisionLayer.LowObstacle, PixelCollider.PixelColliderGeneration.Manual, CanBeCarried: false, IsTrigger: true, UsesPixelsAsUnitSize: true, dimensions: new IntVector2(32, 32), offset: new IntVector2(16, 12));

            ExpandSecretDoorPlacable m_SecretDoorHollow_UnlockedComponent = EXSecretDoor_Hollow_Unlocked.AddComponent <ExpandSecretDoorPlacable>();

            m_SecretDoorHollow_UnlockedComponent.DoorTopBorderObject    = EXSecretDoorHollowUnlocked_Frame_Top;
            m_SecretDoorHollow_UnlockedComponent.DoorBottomBorderObject = EXSecretDoorHollowUnlocked_Frame_Bottom;
            m_SecretDoorHollow_UnlockedComponent.DoorBackgroundObject   = EXSecretDoorHollowUnlocked_Background;
            m_SecretDoorHollow_UnlockedComponent.DoorLightObject        = EXSecretDoorHollowUnlocked_Light;
            EXSecretDoor_Hollow_Unlocked.SetLayerRecursively(LayerMask.NameToLayer("FG_Critical"));



            EXSecretDoor = expandSharedAssets1.LoadAsset <GameObject>("EX_Secret_Door");
            GameObject EXSecretDoor_Frame_Top    = EXSecretDoor.transform.Find("FrameTop").gameObject;
            GameObject EXSecretDoor_Frame_Bottom = EXSecretDoor.transform.Find("FrameBottom").gameObject;
            GameObject EXSecretDoor_Background   = EXSecretDoor.transform.Find("Background").gameObject;
            GameObject EXSecretDoor_Light        = EXSecretDoor.transform.Find("Light").gameObject;
            GameObject EXSecretDoor_Lock         = EXSecretDoor.transform.Find("Lock").gameObject;


            tk2dSprite m_DoorSprite             = SpriteSerializer.AddSpriteToObject(EXSecretDoor, ExpandPrefabs.EXSecretDoorCollection, "EXSecretDoor_Open_00");
            tk2dSprite m_DoorBorderTopSprite    = SpriteSerializer.AddSpriteToObject(EXSecretDoor_Frame_Top, ExpandPrefabs.EXSecretDoorCollection, "EXSecretDoor_Frame_NoDecal_Top");
            tk2dSprite m_DoorBorderBottomSprite = SpriteSerializer.AddSpriteToObject(EXSecretDoor_Frame_Bottom, ExpandPrefabs.EXSecretDoorCollection, "EXSecretDoor_Frame_Bottom");
            tk2dSprite m_DoorBackgroundSprite   = SpriteSerializer.AddSpriteToObject(EXSecretDoor_Background, ExpandPrefabs.EXSecretDoorCollection, "EXSecretDoor_Background");
            tk2dSprite m_DoorLightSprite        = SpriteSerializer.AddSpriteToObject(EXSecretDoor_Light, ExpandPrefabs.EXSecretDoorCollection, "EXSecretDoor_Light_Red");

            m_DoorBorderTopSprite.HeightOffGround    = 3;
            m_DoorBorderBottomSprite.HeightOffGround = -0.5f;
            m_DoorSprite.HeightOffGround             = -1.5f;
            m_DoorBackgroundSprite.HeightOffGround   = -2f;
            m_DoorLightSprite.HeightOffGround        = 3.5f;


            ExpandUtility.GenerateSpriteAnimator(EXSecretDoor, DoorSpriteAnimations, ClipFps: 10);

            ExpandUtility.GenerateOrAddToRigidBody(EXSecretDoor, CollisionLayer.HighObstacle, PixelCollider.PixelColliderGeneration.Manual, CanBeCarried: false, UsesPixelsAsUnitSize: true, dimensions: new IntVector2(32, 64), offset: new IntVector2(16, 0));
            ExpandUtility.GenerateOrAddToRigidBody(EXSecretDoor, CollisionLayer.HighObstacle, PixelCollider.PixelColliderGeneration.Manual, CanBeCarried: false, UsesPixelsAsUnitSize: true, dimensions: new IntVector2(32, 32), offset: new IntVector2(16, 14));
            ExpandUtility.GenerateOrAddToRigidBody(EXSecretDoor, CollisionLayer.LowObstacle, PixelCollider.PixelColliderGeneration.Manual, CanBeCarried: false, IsTrigger: true, UsesPixelsAsUnitSize: true, dimensions: new IntVector2(32, 32), offset: new IntVector2(16, 12));

            ExpandSecretDoorPlacable m_SecretDoorComponent = EXSecretDoor.AddComponent <ExpandSecretDoorPlacable>();

            m_SecretDoorComponent.DoorTopBorderObject    = EXSecretDoor_Frame_Top;
            m_SecretDoorComponent.DoorBottomBorderObject = EXSecretDoor_Frame_Bottom;
            m_SecretDoorComponent.DoorBackgroundObject   = EXSecretDoor_Background;
            m_SecretDoorComponent.DoorLightObject        = EXSecretDoor_Light;

            Dungeon    Base_Castle  = DungeonDatabase.GetOrLoadByName("Base_Castle");
            GameObject m_NormalLock = (Base_Castle.PatternSettings.flows[0].sharedInjectionData[1].InjectionData[0].exactRoom.placedObjects[0].nonenemyBehaviour as SecretFloorInteractableController).WorldLocks[0].gameObject;

            tk2dSprite EXLockNormalSprite = EXSecretDoor_Lock.AddComponent <tk2dSprite>();

            ExpandUtility.DuplicateSprite(EXLockNormalSprite, m_NormalLock.GetComponent <tk2dSprite>());
            ExpandUtility.DuplicateSpriteAnimator(EXSecretDoor_Lock, m_NormalLock.GetComponent <tk2dSpriteAnimator>());
            EXLockNormalSprite.HeightOffGround = 1.7f;

            InteractableLock m_EXLockNormal = EXSecretDoor_Lock.AddComponent <InteractableLock>();

            m_EXLockNormal.Suppress       = m_NormalLock.GetComponent <InteractableLock>().Suppress;
            m_EXLockNormal.lockMode       = m_NormalLock.GetComponent <InteractableLock>().lockMode;
            m_EXLockNormal.JailCellKeyId  = m_NormalLock.GetComponent <InteractableLock>().JailCellKeyId;
            m_EXLockNormal.IdleAnimName   = m_NormalLock.GetComponent <InteractableLock>().IdleAnimName;
            m_EXLockNormal.UnlockAnimName = m_NormalLock.GetComponent <InteractableLock>().UnlockAnimName;
            m_EXLockNormal.NoKeyAnimName  = m_NormalLock.GetComponent <InteractableLock>().NoKeyAnimName;
            m_EXLockNormal.SpitAnimName   = m_NormalLock.GetComponent <InteractableLock>().SpitAnimName;
            m_EXLockNormal.BustedAnimName = m_NormalLock.GetComponent <InteractableLock>().BustedAnimName;

            m_SecretDoorComponent.Lock = m_EXLockNormal;
            EXSecretDoor.SetLayerRecursively(LayerMask.NameToLayer("FG_Critical"));

            Base_Castle  = null;
            m_NormalLock = null;

            EXSecretDoor_Unlocked = expandSharedAssets1.LoadAsset <GameObject>("EX_Secret_Door_Unlocked");
            GameObject EXSecretDoorUnlocked_Frame_Top    = EXSecretDoor_Unlocked.transform.Find("FrameTop").gameObject;
            GameObject EXSecretDoorUnlocked_Frame_Bottom = EXSecretDoor_Unlocked.transform.Find("FrameBottom").gameObject;
            GameObject EXSecretDoorUnlocked_Background   = EXSecretDoor_Unlocked.transform.Find("Background").gameObject;
            GameObject EXSecretDoorUnlocked_Light        = EXSecretDoor_Unlocked.transform.Find("Light").gameObject;

            tk2dSprite m_Door_UnlockedSprite             = SpriteSerializer.AddSpriteToObject(EXSecretDoor_Unlocked, ExpandPrefabs.EXSecretDoorCollection, "EXSecretDoor_Open_00");
            tk2dSprite m_Door_UnlockedBorderTopSprite    = SpriteSerializer.AddSpriteToObject(EXSecretDoorUnlocked_Frame_Top, ExpandPrefabs.EXSecretDoorCollection, "EXSecretDoor_Frame_Top");
            tk2dSprite m_Door_UnlockedBorderBottomSprite = SpriteSerializer.AddSpriteToObject(EXSecretDoorUnlocked_Frame_Bottom, ExpandPrefabs.EXSecretDoorCollection, "EXSecretDoor_Frame_Bottom");
            tk2dSprite m_Door_UnlockedBackgroundSprite   = SpriteSerializer.AddSpriteToObject(EXSecretDoorUnlocked_Background, ExpandPrefabs.EXSecretDoorCollection, "EXSecretDoor_Background");
            tk2dSprite m_Door_UnlockedLightSprite        = SpriteSerializer.AddSpriteToObject(EXSecretDoorUnlocked_Light, ExpandPrefabs.EXSecretDoorCollection, "EXSecretDoor_Light_Red");

            m_Door_UnlockedBorderTopSprite.HeightOffGround    = 3;
            m_Door_UnlockedBorderBottomSprite.HeightOffGround = -0.5f;
            m_Door_UnlockedSprite.HeightOffGround             = -1.5f;
            m_Door_UnlockedBackgroundSprite.HeightOffGround   = -2f;
            m_Door_UnlockedLightSprite.HeightOffGround        = 3.5f;

            ExpandUtility.GenerateSpriteAnimator(EXSecretDoor_Unlocked, DoorSpriteAnimations, ClipFps: 10);

            ExpandUtility.GenerateOrAddToRigidBody(EXSecretDoor_Unlocked, CollisionLayer.HighObstacle, PixelCollider.PixelColliderGeneration.Manual, CanBeCarried: false, UsesPixelsAsUnitSize: true, dimensions: new IntVector2(32, 64), offset: new IntVector2(16, 0));
            ExpandUtility.GenerateOrAddToRigidBody(EXSecretDoor_Unlocked, CollisionLayer.HighObstacle, PixelCollider.PixelColliderGeneration.Manual, CanBeCarried: false, UsesPixelsAsUnitSize: true, dimensions: new IntVector2(32, 32), offset: new IntVector2(16, 14));
            ExpandUtility.GenerateOrAddToRigidBody(EXSecretDoor_Unlocked, CollisionLayer.LowObstacle, PixelCollider.PixelColliderGeneration.Manual, CanBeCarried: false, IsTrigger: true, UsesPixelsAsUnitSize: true, dimensions: new IntVector2(32, 32), offset: new IntVector2(16, 12));

            ExpandSecretDoorPlacable m_SecretDoor_UnlockedComponent = EXSecretDoor_Unlocked.AddComponent <ExpandSecretDoorPlacable>();

            m_SecretDoor_UnlockedComponent.DoorTopBorderObject    = EXSecretDoorUnlocked_Frame_Top;
            m_SecretDoor_UnlockedComponent.DoorBottomBorderObject = EXSecretDoorUnlocked_Frame_Bottom;
            m_SecretDoor_UnlockedComponent.DoorBackgroundObject   = EXSecretDoorUnlocked_Background;
            m_SecretDoor_UnlockedComponent.DoorLightObject        = EXSecretDoorUnlocked_Light;
            EXSecretDoor_Unlocked.SetLayerRecursively(LayerMask.NameToLayer("FG_Critical"));
        }
示例#17
0
        public static void Init(AssetBundle expandSharedAssets1)
        {
            SonicRingObject = expandSharedAssets1.LoadAsset <GameObject>("EXSonicRing");
            SpriteSerializer.AddSpriteToObject(SonicRingObject, ExpandPrefabs.EXItemCollection, "SonicRing_Idle_05");

            List <string> m_RingFrames = new List <string>();

            for (int i = 1; i < 16; i++)
            {
                if (i < 10)
                {
                    m_RingFrames.Add("SonicRing_Idle_0" + i.ToString());
                }
                else
                {
                    m_RingFrames.Add("SonicRing_Idle_" + i.ToString());
                }
            }

            ExpandUtility.GenerateSpriteAnimator(SonicRingObject, playAutomatically: true);

            ExpandUtility.AddAnimation(SonicRingObject.GetComponent <tk2dSpriteAnimator>(), ExpandPrefabs.EXItemCollection.GetComponent <tk2dSpriteCollectionData>(), m_RingFrames, "idle", tk2dSpriteAnimationClip.WrapMode.Loop);

            ExpandUtility.GenerateOrAddToRigidBody(SonicRingObject, CollisionLayer.Pickup, PixelCollider.PixelColliderGeneration.Manual, UsesPixelsAsUnitSize: true, offset: new IntVector2(0, 1), dimensions: new IntVector2(15, 14));

            SonicRingObject.GetComponent <SpeculativeRigidbody>().PixelColliders[0].IsTrigger = true;

            PickupMover pickupMover = SonicRingObject.AddComponent <PickupMover>();

            pickupMover.pathInterval = 0.25f;
            pickupMover.acceleration = 7;
            pickupMover.maxSpeed     = 15;
            pickupMover.minRadius    = 0;

            SonicRing sonicRing = SonicRingObject.AddComponent <SonicRing>();

            string name      = "Sonic Ring";
            string shortDesc = "A Ring";
            string longDesc  = "A Simple Ring. Equilivent to one casing.";

            ItemBuilder.SetupEXItem(sonicRing, name, shortDesc, longDesc, "ex", false);
            sonicRing.quality = ItemQuality.COMMON;
            sonicRing.ItemSpansBaseQualityTiers      = false;
            sonicRing.additionalMagnificenceModifier = 0;
            sonicRing.ItemRespectsHeartMagnificence  = false;
            sonicRing.associatedItemChanceMods       = new LootModData[0];
            sonicRing.contentSource             = ContentSource.BASE;
            sonicRing.ShouldBeExcludedFromShops = false;
            sonicRing.CanBeDropped = true;
            sonicRing.PreventStartingOwnerFromDropping = false;
            sonicRing.PersistsOnDeath            = false;
            sonicRing.PersistsOnPurchase         = false;
            sonicRing.RespawnsIfPitfall          = true;
            sonicRing.PreventSaveSerialization   = false;
            sonicRing.IgnoredByRat               = false;
            sonicRing.SaveFlagToSetOnAcquisition = 0;
            sonicRing.UsesCustomCost             = false;
            sonicRing.CustomCost = 0;
            sonicRing.CanBeSold  = true;
            sonicRing.ForcedPositionInAmmonomicon = -1;
            sonicRing.currencyValue           = 1;
            sonicRing.IsMetaCurrency          = false;
            sonicRing.overrideBloopSpriteName = "SonicRing_Idle_05";

            RingID = sonicRing.PickupObjectId;
        }
        public static void Init(AssetBundle expandSharedAssets1)
        {
            hammerItemObject = expandSharedAssets1.LoadAsset <GameObject>("Baby Good Hammer");
            BabyGoodHammer babyGoodHammer = hammerItemObject.AddComponent <BabyGoodHammer>();

            SpriteSerializer.AddSpriteToObject(hammerItemObject, ExpandPrefabs.EXItemCollection, "babygoodhammer");

            string shortDesc = "It's Hammer Time!";
            string longDesc  = "Summons a Dead Blow Hammer.\n\nIt's cry sounds a lot like a whistle.\n\nThe closer you are to the Forge, the more powerful the hammers will be.";

            // ItemBuilder.SetupItem(babyGoodHammer, shortDesc, longDesc, "ex");
            ItemBuilder.SetupItem(babyGoodHammer, shortDesc, longDesc, "ex");
            ItemBuilder.SetCooldownType(babyGoodHammer, ItemBuilder.CooldownType.Damage, 350f);
            babyGoodHammer.quality = ItemQuality.B;
            if (!ExpandSettings.EnableEXItems)
            {
                babyGoodHammer.quality = ItemQuality.EXCLUDED;
            }

            // Hammer Spawn FX Object
            hammerSpawnFX = expandSharedAssets1.LoadAsset <GameObject>("HammerSpawningFX");
            tk2dSprite hammerSpawnFXSprite = SpriteSerializer.AddSpriteToObject(hammerSpawnFX, ExpandPrefabs.EXItemCollection, "babygoodhammer_spawn_00");

            List <string> spritePaths = new List <string>()
            {
                "babygoodhammer_spawn_00",
                "babygoodhammer_spawn_00",
                "babygoodhammer_spawn_01",
                "babygoodhammer_spawn_01",
                "babygoodhammer_spawn_01",
                "babygoodhammer_spawn_01",
                "babygoodhammer_spawn_02",
                "babygoodhammer_spawn_03",
                "babygoodhammer_spawn_04",
                "babygoodhammer_spawn_05",
                "babygoodhammer_spawn_06",
                "babygoodhammer_spawn_07",
                "babygoodhammer_spawn_08",
                "babygoodhammer_spawn_09",
                "babygoodhammer_spawn_10",
                "babygoodhammer_spawn_11",
                "babygoodhammer_spawn_12",
                "babygoodhammer_spawn_13",
                "babygoodhammer_spawn_14",
                "babygoodhammer_spawn_15",
                "babygoodhammer_spawn_16",
                "babygoodhammer_spawn_17",
                "babygoodhammer_spawn_18",
                "babygoodhammer_spawn_19",
                "babygoodhammer_spawn_20",
                "babygoodhammer_spawn_21",
                "babygoodhammer_spawn_22",
                "babygoodhammer_spawn_23",
                "babygoodhammer_spawn_24",
                "babygoodhammer_spawn_25"
            };

            /*foreach (string spriteName in spritePaths) {
             *  if (spriteName != "babygoodhammer_spawn_00") {
             *      SpriteBuilder.AddSpriteToCollection(expandSharedAssets1.LoadAsset<Texture2D>(spriteName), hammerSpawnFXSprite.Collection);
             *  }
             * }*/

            ExpandUtility.GenerateSpriteAnimator(hammerSpawnFX);
            tk2dSpriteAnimator hammerAnimator = hammerSpawnFX.GetComponent <tk2dSpriteAnimator>();

            List <string> spritePaths_reversed = new List <string>()
            {
                "babygoodhammer_spawn_25",
                "babygoodhammer_spawn_24",
                "babygoodhammer_spawn_23",
                "babygoodhammer_spawn_22",
                "babygoodhammer_spawn_21",
                "babygoodhammer_spawn_20",
                "babygoodhammer_spawn_19",
                "babygoodhammer_spawn_18",
                "babygoodhammer_spawn_17",
                "babygoodhammer_spawn_16",
                "babygoodhammer_spawn_15",
                "babygoodhammer_spawn_14",
                "babygoodhammer_spawn_13",
                "babygoodhammer_spawn_12",
                "babygoodhammer_spawn_11",
                "babygoodhammer_spawn_10",
                "babygoodhammer_spawn_09",
                "babygoodhammer_spawn_08",
                "babygoodhammer_spawn_07",
                "babygoodhammer_spawn_06",
                "babygoodhammer_spawn_05",
                "babygoodhammer_spawn_04",
                "babygoodhammer_spawn_03",
                "babygoodhammer_spawn_02",
                "babygoodhammer_spawn_01",
                "babygoodhammer_spawn_01",
                "babygoodhammer_spawn_01",
                "babygoodhammer_spawn_01",
                "babygoodhammer_spawn_00"
            };


            ExpandUtility.AddAnimation(hammerAnimator, ExpandPrefabs.EXItemCollection.GetComponent <tk2dSpriteCollectionData>(), spritePaths, "HammerSpawn", tk2dSpriteAnimationClip.WrapMode.Once);
            ExpandUtility.AddAnimation(hammerAnimator, ExpandPrefabs.EXItemCollection.GetComponent <tk2dSpriteCollectionData>(), spritePaths_reversed, "HammerReturnSpawn", tk2dSpriteAnimationClip.WrapMode.Once);

            HammerPickupID = babyGoodHammer.PickupObjectId;
        }
        public static void BuildPrefab(AssetBundle expandSharedAssets1)
        {
            ExpandPrefabs.EXBootlegRoomObject       = expandSharedAssets1.LoadAsset <GameObject>("BootlegRoomPrefab");
            ExpandPrefabs.EXBootlegRoomDoorTriggers = expandSharedAssets1.LoadAsset <GameObject>("BootlegRoomDoorTriggers");
            GameObject m_BorderObject_West     = expandSharedAssets1.LoadAsset <GameObject>("BootlegRoomBorder_West");
            GameObject m_BorderObject_East     = expandSharedAssets1.LoadAsset <GameObject>("BootlegRoomBorder_East");
            GameObject m_BorderObject_North    = expandSharedAssets1.LoadAsset <GameObject>("BootlegRoomBorder_North");
            GameObject m_BorderObject_South    = expandSharedAssets1.LoadAsset <GameObject>("BootlegRoomBorder_South");
            GameObject m_DoorFrameObject       = expandSharedAssets1.LoadAsset <GameObject>("BootlegRoomDoorFramesTop");
            GameObject m_DoorObject            = expandSharedAssets1.LoadAsset <GameObject>("BootlegRoomDoorFrames");
            GameObject m_DoorBlockObject_West  = expandSharedAssets1.LoadAsset <GameObject>("BootlegRoomDoorBlocker_West");
            GameObject m_DoorBlockObject_East  = expandSharedAssets1.LoadAsset <GameObject>("BootlegRoomDoorBlocker_East");
            GameObject m_DoorBlockObject_South = expandSharedAssets1.LoadAsset <GameObject>("BootlegRoomDoorBlocker_South");
            GameObject m_DoorBlockObject_North = expandSharedAssets1.LoadAsset <GameObject>("BootlegRoomDoorBlocker_North");

            m_BorderObject_West.transform.SetParent(ExpandPrefabs.EXBootlegRoomObject.transform);
            m_BorderObject_East.transform.SetParent(ExpandPrefabs.EXBootlegRoomObject.transform);
            m_BorderObject_North.transform.SetParent(ExpandPrefabs.EXBootlegRoomObject.transform);
            m_BorderObject_South.transform.SetParent(ExpandPrefabs.EXBootlegRoomObject.transform);
            m_DoorFrameObject.transform.SetParent(ExpandPrefabs.EXBootlegRoomObject.transform);
            m_BorderObject_West.transform.localPosition  -= new Vector3(3, 3);
            m_BorderObject_East.transform.localPosition  -= new Vector3(3, 3);
            m_BorderObject_North.transform.localPosition -= new Vector3(3, 3);
            m_BorderObject_South.transform.localPosition -= new Vector3(3, 3);

            m_DoorObject.transform.SetParent(ExpandPrefabs.EXBootlegRoomDoorTriggers.transform);
            m_DoorBlockObject_West.transform.SetParent(ExpandPrefabs.EXBootlegRoomDoorTriggers.transform);
            m_DoorBlockObject_East.transform.SetParent(ExpandPrefabs.EXBootlegRoomDoorTriggers.transform);
            m_DoorBlockObject_South.transform.SetParent(ExpandPrefabs.EXBootlegRoomDoorTriggers.transform);
            m_DoorBlockObject_North.transform.SetParent(ExpandPrefabs.EXBootlegRoomDoorTriggers.transform);

            SpriteSerializer.AddSpriteToObject(m_DoorFrameObject, ExpandPrefabs.EXBootlegRoomCollection, "BootlegRoom_TopLayer");
            SpriteSerializer.AddSpriteToObject(m_DoorBlockObject_West, ExpandPrefabs.EXBootlegRoomCollection, "BootlegRoom_DoorBlock_West");
            SpriteSerializer.AddSpriteToObject(m_DoorBlockObject_East, ExpandPrefabs.EXBootlegRoomCollection, "BootlegRoom_DoorBlock_East");
            SpriteSerializer.AddSpriteToObject(m_DoorBlockObject_South, ExpandPrefabs.EXBootlegRoomCollection, "BootlegRoom_DoorBlock_South");
            SpriteSerializer.AddSpriteToObject(m_DoorBlockObject_North, ExpandPrefabs.EXBootlegRoomCollection, "BootlegRoom_DoorBlock_North");

            tk2dSprite m_BootlegRoomSprite = SpriteSerializer.AddSpriteToObject(ExpandPrefabs.EXBootlegRoomObject, ExpandPrefabs.EXBootlegRoomCollection, "BootlegRoom_BottomLayer");

            m_BootlegRoomSprite.HeightOffGround = -3f;
            tk2dSprite m_BorderSprite_West = SpriteSerializer.AddSpriteToObject(m_BorderObject_West, ExpandPrefabs.EXBootlegRoomCollection, "BootlegRoom_ExitTiles_West");

            m_BorderSprite_West.HeightOffGround = -3f;
            tk2dSprite m_BorderSprite_East = SpriteSerializer.AddSpriteToObject(m_BorderObject_East, ExpandPrefabs.EXBootlegRoomCollection, "BootlegRoom_ExitTiles_East");

            m_BorderSprite_East.HeightOffGround = -3f;
            tk2dSprite m_BorderSprite_North = SpriteSerializer.AddSpriteToObject(m_BorderObject_North, ExpandPrefabs.EXBootlegRoomCollection, "BootlegRoom_ExitTiles_North");

            m_BorderSprite_North.HeightOffGround = -3f;
            tk2dSprite m_BorderSprite_South = SpriteSerializer.AddSpriteToObject(m_BorderObject_South, ExpandPrefabs.EXBootlegRoomCollection, "BootlegRoom_ExitTiles_South");

            m_BorderSprite_South.HeightOffGround = -3f;
            tk2dSprite m_DoorSprites = SpriteSerializer.AddSpriteToObject(m_DoorObject, ExpandPrefabs.EXBootlegRoomCollection, "BootlegRoom_Doors");

            m_DoorSprites.HeightOffGround = -2.5f;

            ExpandUtility.GenerateOrAddToRigidBody(ExpandPrefabs.EXBootlegRoomObject, CollisionLayer.HighObstacle, PixelCollider.PixelColliderGeneration.Manual, dimensions: new IntVector2(1, 6));
            ExpandUtility.GenerateOrAddToRigidBody(ExpandPrefabs.EXBootlegRoomObject, CollisionLayer.HighObstacle, PixelCollider.PixelColliderGeneration.Manual, dimensions: new IntVector2(1, 6), offset: new IntVector2(0, 8));
            ExpandUtility.GenerateOrAddToRigidBody(ExpandPrefabs.EXBootlegRoomObject, CollisionLayer.HighObstacle, PixelCollider.PixelColliderGeneration.Manual, dimensions: new IntVector2(1, 6), offset: new IntVector2(19, 0));
            ExpandUtility.GenerateOrAddToRigidBody(ExpandPrefabs.EXBootlegRoomObject, CollisionLayer.HighObstacle, PixelCollider.PixelColliderGeneration.Manual, dimensions: new IntVector2(1, 6), offset: new IntVector2(19, 8));
            ExpandUtility.GenerateOrAddToRigidBody(ExpandPrefabs.EXBootlegRoomObject, CollisionLayer.HighObstacle, PixelCollider.PixelColliderGeneration.Manual, dimensions: new IntVector2(8, 1), offset: new IntVector2(1, 0));
            ExpandUtility.GenerateOrAddToRigidBody(ExpandPrefabs.EXBootlegRoomObject, CollisionLayer.HighObstacle, PixelCollider.PixelColliderGeneration.Manual, dimensions: new IntVector2(8, 1), offset: new IntVector2(11, 0));
            ExpandUtility.GenerateOrAddToRigidBody(ExpandPrefabs.EXBootlegRoomObject, CollisionLayer.HighObstacle, PixelCollider.PixelColliderGeneration.Manual, dimensions: new IntVector2(8, 1), offset: new IntVector2(1, 13));
            ExpandUtility.GenerateOrAddToRigidBody(ExpandPrefabs.EXBootlegRoomObject, CollisionLayer.HighObstacle, PixelCollider.PixelColliderGeneration.Manual, dimensions: new IntVector2(8, 1), offset: new IntVector2(11, 13));
            ExpandUtility.GenerateOrAddToRigidBody(ExpandPrefabs.EXBootlegRoomObject, CollisionLayer.LowObstacle, PixelCollider.PixelColliderGeneration.Manual, UsesPixelsAsUnitSize: true, dimensions: new IntVector2(8, 80), offset: new IntVector2(16, 16));
            ExpandUtility.GenerateOrAddToRigidBody(ExpandPrefabs.EXBootlegRoomObject, CollisionLayer.LowObstacle, PixelCollider.PixelColliderGeneration.Manual, UsesPixelsAsUnitSize: true, dimensions: new IntVector2(8, 80), offset: new IntVector2(16, 128));
            ExpandUtility.GenerateOrAddToRigidBody(ExpandPrefabs.EXBootlegRoomObject, CollisionLayer.LowObstacle, PixelCollider.PixelColliderGeneration.Manual, UsesPixelsAsUnitSize: true, dimensions: new IntVector2(8, 80), offset: new IntVector2(296, 16));
            ExpandUtility.GenerateOrAddToRigidBody(ExpandPrefabs.EXBootlegRoomObject, CollisionLayer.LowObstacle, PixelCollider.PixelColliderGeneration.Manual, UsesPixelsAsUnitSize: true, dimensions: new IntVector2(8, 80), offset: new IntVector2(296, 128));
            ExpandUtility.GenerateOrAddToRigidBody(ExpandPrefabs.EXBootlegRoomObject, CollisionLayer.LowObstacle, PixelCollider.PixelColliderGeneration.Manual, UsesPixelsAsUnitSize: true, dimensions: new IntVector2(120, 8), offset: new IntVector2(24, 16));
            ExpandUtility.GenerateOrAddToRigidBody(ExpandPrefabs.EXBootlegRoomObject, CollisionLayer.LowObstacle, PixelCollider.PixelColliderGeneration.Manual, UsesPixelsAsUnitSize: true, dimensions: new IntVector2(120, 8), offset: new IntVector2(176, 16));
            ExpandUtility.GenerateOrAddToRigidBody(ExpandPrefabs.EXBootlegRoomObject, CollisionLayer.LowObstacle, PixelCollider.PixelColliderGeneration.Manual, UsesPixelsAsUnitSize: true, dimensions: new IntVector2(120, 8), offset: new IntVector2(24, 200));
            ExpandUtility.GenerateOrAddToRigidBody(ExpandPrefabs.EXBootlegRoomObject, CollisionLayer.LowObstacle, PixelCollider.PixelColliderGeneration.Manual, UsesPixelsAsUnitSize: true, dimensions: new IntVector2(120, 8), offset: new IntVector2(176, 200));
            ExpandUtility.GenerateOrAddToRigidBody(ExpandPrefabs.EXBootlegRoomDoorTriggers, CollisionLayer.Trap, PixelCollider.PixelColliderGeneration.Manual, IsTrigger: true, dimensions: new IntVector2(16, 10), offset: new IntVector2(2, 2));

            ExpandBootlegRoomPlaceable m_BootlegRoomPlacable = ExpandPrefabs.EXBootlegRoomObject.AddComponent <ExpandBootlegRoomPlaceable>();

            m_BootlegRoomPlacable.ExitTiles_West  = m_BorderObject_West;
            m_BootlegRoomPlacable.ExitTiles_East  = m_BorderObject_East;
            m_BootlegRoomPlacable.ExitTiles_North = m_BorderObject_North;
            m_BootlegRoomPlacable.ExitTiles_South = m_BorderObject_South;
            m_BootlegRoomPlacable.DoorFrames      = m_DoorFrameObject;

            ExpandBootlegRoomDoorsPlacables m_BootlegDoorBlockersPlacable = ExpandPrefabs.EXBootlegRoomDoorTriggers.AddComponent <ExpandBootlegRoomDoorsPlacables>();

            m_BootlegDoorBlockersPlacable.Doors             = m_DoorObject;
            m_BootlegDoorBlockersPlacable.DoorBlocker_West  = m_DoorBlockObject_West;
            m_BootlegDoorBlockersPlacable.DoorBlocker_East  = m_DoorBlockObject_East;
            m_BootlegDoorBlockersPlacable.DoorBlocker_South = m_DoorBlockObject_South;
            m_BootlegDoorBlockersPlacable.DoorBlocker_North = m_DoorBlockObject_North;
        }
        private static void Add(bool isGoldenVersion)
        {
            string upperColor = isGoldenVersion ? "Golden" : "Black";
            string lowerColor = isGoldenVersion ? "golden" : "black";

            Gun gun = ETGMod.Databases.Items.NewGun($"{upperColor} Revolver", $"gr_{lowerColor}_revolver");

            Game.Items.Rename($"outdated_gun_mods:{lowerColor}_revolver", $"ex:{lowerColor}_revolver");

            gun.gameObject.AddComponent <BlackAndGoldenRevolver>();
            gun.SetShortDescription("Six Deep");

            string longDescription = "Bullets fired from this cursed revolver jam enemies on hit, but also completely ignore their increased strength, damaging them as if they were unjammed.";

            if (isGoldenVersion)
            {
                longDescription += "\n\nThree bullet kin, that were completely unalike each other, set aside their differences to obtain this revolver, that was once carried by the bearer of a terrible curse. Their presence can still be felt while wielding it.";
            }
            else
            {
                longDescription += "\n\nThis revolver was once carried by the bearer of a terrible curse. It is cold to the touch. A dark wind blows.";
            }

            gun.SetLongDescription(longDescription);

            // frame rate can be adjusted if we don't like the current idle animation speed
            gun.SetupSprite(null, $"gr_{lowerColor}_revolver_idle_001", 5);

            var idleAnimation = gun.GetComponent <tk2dSpriteAnimator>().GetClipByName(gun.idleAnimation);

            var list = idleAnimation.frames.ToList();

            // manually add the reversal of the animation so we don't load the same sprite multiple times for no reason (these frames don't really need to be duplicated)
            list.Add(list[2]);
            list.Add(list[1]);

            // add a few more frames of the idle frame so the animation has a slight pause before looping
            for (int i = 0; i < 5; i++)
            {
                list.Add(list[0]);
            }

            idleAnimation.frames = list.ToArray();

            gun.SetAnimationFPS(gun.shootAnimation, 12);
            gun.SetAnimationFPS(gun.reloadAnimation, 14);

            // Every modded gun has base projectile it works with that is borrowed from other guns in the game.
            // The gun names are the names from the JSON dump! While most are the same, some guns named completely different things. If you need help finding gun names, ask a modder on the Gungeon discord.
            // which means its the ETGMod.Databases.Items / PickupObjectDatabase.Instance.InternalGetByName name, aka the pickupobject.name

            var defaultGun = PickupObjectDatabase.GetById(22) as Gun;

            gun.AddProjectileModuleFrom(defaultGun, true, false);

            // move the gun up with the hand in the second frame of the shooting animation (hand movement was done in GAE with a y offset of 1)
            //gun.GetComponent<tk2dSpriteAnimator>().GetClipByName(gun.shootAnimation).frames[1].FrameToDefinition().MakeOffset(new Vector2(0, 1));

            gun.gunSwitchGroup     = defaultGun.gunSwitchGroup;
            gun.muzzleFlashEffects = defaultGun.muzzleFlashEffects;

            gun.AddMuzzle();
            gun.muzzleOffset.localPosition = new Vector3(1.2f, 0.8f, 0f);
            gun.barrelOffset.localPosition = new Vector3(1.4f, 0.8f, 0f);

            gun.DefaultModule.shootStyle          = ProjectileModule.ShootStyle.SemiAutomatic;
            gun.DefaultModule.sequenceStyle       = ProjectileModule.ProjectileSequenceStyle.Random;
            gun.DefaultModule.cooldownTime        = 0.07f;
            gun.DefaultModule.numberOfShotsInClip = 6;
            gun.DefaultModule.angleVariance       = 0;
            gun.DefaultModule.ammoCost            = 1;

            var curseWhileHeld = new StatModifier
            {
                amount      = 2,
                statToBoost = PlayerStats.StatType.Curse,
                modifyType  = StatModifier.ModifyMethod.ADDITIVE
            };

            gun.currentGunStatModifiers = new StatModifier[] { curseWhileHeld };

            gun.shellCasing            = defaultGun.shellCasing;
            gun.shellsToLaunchOnFire   = 0;
            gun.shellsToLaunchOnReload = gun.DefaultModule.numberOfShotsInClip;
            gun.reloadShellLaunchFrame = defaultGun.reloadShellLaunchFrame;

            gun.reloadTime = 1f;
            gun.gunClass   = GunClass.PISTOL;
            gun.SetBaseMaxAmmo(666);
            gun.quality = PickupObject.ItemQuality.EXCLUDED;

            gun.encounterTrackable.EncounterGuid = $"this is the {lowerColor} skull revolver";

            Projectile projectile      = isGoldenVersion ? WestBrosGoldenRevolverProjectile.AddComponent <Projectile>() : WestBrosBlackRevolverProjectile.AddComponent <Projectile>();
            GameObject projectileChild = projectile.transform.Find("Sprite").gameObject;
            tk2dSprite projetileSprite = SpriteSerializer.AddSpriteToObject(projectileChild, ExpandCustomEnemyDatabase.WestBrosCollection, "gr_black_revolver_projectile_001");

            ExpandUtility.GenerateSpriteAnimator(projectileChild, playAutomatically: true);
            ExpandUtility.AddAnimation(projectileChild.GetComponent <tk2dSpriteAnimator>(), projetileSprite.Collection, ProjectileSpriteList, "idle", tk2dSpriteAnimationClip.WrapMode.Loop, 13);

            SpeculativeRigidbody projectileRigidBody = projectile.gameObject.AddComponent <SpeculativeRigidbody>();

            ExpandUtility.DuplicateRigidBody(projectileRigidBody, defaultGun.DefaultModule.projectiles[0].specRigidbody);
            ExpandUtility.DuplicateComponent(projectile, defaultGun.DefaultModule.projectiles[0]);
            gun.DefaultModule.projectiles[0] = projectile;
            projectile.baseData.damage       = 14f;
            projectile.baseData.speed        = 25f;
            projectile.baseData.force        = 14f;


            // projectile.transform.parent = gun.barrelOffset;
            projectile.transform.localPosition = gun.barrelOffset.localPosition;

            projectile.shouldRotate = true;
            var comp = projectile.gameObject.AddComponent <SkullRevolverBullet>();

            comp.jamsEnemies = true;

            ETGMod.Databases.Items.Add(gun, null, "ANY");

            if (isGoldenVersion)
            {
                AddHoveringGunComponent(gun);
                GoldenRevolverID = gun.PickupObjectId;
            }
            else
            {
                BlackRevolverID = gun.PickupObjectId;
            }
        }