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; } }
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; }