Exemple #1
0
        // If the item is a magic weapon it will explode when the projectile dies
        private void MagicExplode()
        {
            if (!StoredItem.magic)
            {
                return;
            }

            if (Main.myPlayer == Projectile.owner)
            {
                Tools.ResizeProjectile(Projectile.whoAmI, Projectile.width + 50, Projectile.height + 50);
                Projectile.Damage(); // Applies damage in the area
                Projectile.netUpdate = true;
            }

            SoundEngine.PlaySound(SoundID.Item14, Projectile.Center);
            for (int i = 0; i < Math.Max(4, (int)GobblerHelper.DiagonalSize(StoredItem) / 4); i++) // More dust the higher the size
            {
                Gore.NewGore(
                    Projectile.position + new Vector2(Main.rand.NextFloat(Projectile.width),
                                                      Main.rand.NextFloat(Projectile.height)), Vector2.Zero, Main.rand.Next(61, 64), Main.rand.NextFloat(0.2f, 1.2f));

                Dust.NewDust(
                    Projectile.position, Projectile.width, Projectile.height,
                    /*Type*/ 31, 0f, 0f, 0, default(Color), Main.rand.NextFloat(2));
            }
        }
Exemple #2
0
        // When the projectile dies and the stored item was set to consumed
        private void ItemConsume()
        {
            if (!Consumed)
            {
                return;
            }

            Player player = Main.player[Projectile.owner];

            if (GobblerHelper.IsDepletable(StoredItem)) // Item won't be returned
            {
                if (StoredItem.buffTime != 0)           // Buff-giving consumables
                {
                    player.AddBuff(StoredItem.buffType, StoredItem.buffTime);
                }
                if (StoredItem.makeNPC != 0 && Main.netMode != NetmodeID.MultiplayerClient) // Critters
                {
                    NPC.NewNPC((int)(Projectile.Center.X), (int)(Projectile.Center.Y), StoredItem.makeNPC);
                }
            }
            else // Drops the stored item
            {
                if (Main.netMode != NetmodeID.MultiplayerClient) // Will be synced from the server in multiplayer
                {
                    Item.NewItem(Projectile.Center, StoredItem.type, prefixGiven: StoredItem.prefix);
                }
            }
        }
Exemple #3
0
        public override bool CanUseItem(Player player)
        {
            // Right click
            if (player.altFunctionUse == 2)
            {
                Item.useTime      = 1;  // Shooting code runs every tick, but the animation is longer so I can control what's happening
                Item.useAnimation = 30; // About right for the looping sound
            }
            // Left click
            else
            {
                Item.useTime      = 1;
                Item.useAnimation = 20;

                var modPlayer = player.GetModPlayer <VirtuousPlayer>();

                if (modPlayer.GobblerStorage.Count > 0 &&
                    GobblerHelper.ConsumeChance(modPlayer.GobblerStorage.First().MakeItem()) == 0f)
                {
                    Item.useAnimation = 15; // An exception: Shoots faster with endless quiver or musket pouch
                }
            }

            return(base.CanUseItem(player));
        }
Exemple #4
0
        // If the item is a tool, it will bounce off in the direction it came from when specified
        private bool ToolBounce()
        {
            if (GobblerHelper.IsTool(StoredItem))
            {
                if (Projectile.penetrate > 1)
                {
                    if (StoredItem.UseSound != null)
                    {
                        SoundEngine.PlaySound(StoredItem.UseSound, Projectile.Center);
                    }
                    Projectile.penetrate--;
                    Projectile.velocity *= new Vector2(-0.5f, -0.5f);
                    Projectile.netUpdate = true; // Sync to multiplayer just in case
                    return(true);
                }
                else
                {
                    Projectile.Kill();
                }
            }

            return(false);
        }
Exemple #5
0
        public override void AI()
        {
            Player player = Main.player[Projectile.owner];

            // First tick
            if (Projectile.timeLeft == Lifespan && StoredItem.type != ItemID.None)
            {
                // Inherit properties from the stored item
                Tools.ResizeProjectile(Projectile.whoAmI, StoredItem.width, StoredItem.height);
                Projectile.damage    = GobblerHelper.ShotDamage(StoredItem, player);
                Projectile.knockBack = GobblerHelper.ShotKnockBack(StoredItem, player);
                Projectile.melee     = StoredItem.melee;
                Projectile.magic     = StoredItem.magic;
                Projectile.ranged    = StoredItem.ranged;
                Projectile.Name      = StoredItem.Name;

                // Transparency; copies appear translucent
                if (!Consumed && !GobblerHelper.IsDepletable(StoredItem))
                {
                    Projectile.alpha = 120;
                }

                // Items without gravity
                if (ItemID.Sets.ItemNoGravity[StoredItem.type])
                {
                    Projectile.timeLeft  = 2 * 60;
                    Projectile.penetrate = -1;
                }

                // Penetration
                if (StoredItem.melee)
                {
                    Projectile.penetrate = -1;                   // Melee weapons penetrate infinitely
                }
                if (GobblerHelper.IsTool(StoredItem))
                {
                    Projectile.penetrate = 3;                                   // But tools penetrate only a bit
                }
                else if (StoredItem.accessory)
                {
                    Projectile.penetrate = 2;
                }

                Projectile.netUpdate = true; // Sync to multiplayer
            }

            // Every tick: Projectile rotation and movement
            if (!ItemID.Sets.ItemNoGravity[StoredItem.type])
            {
                Projectile.velocity.Y += GobblerHelper.DiagonalSize(StoredItem) / 200f; // How fast they fall down depends on their size

                // Swingable weapons and projectiles point to where they're going, adjusted for sprite orientation
                if (StoredItem.useStyle == 1 && !StoredItem.consumable && !GobblerHelper.IsTool(StoredItem))
                {
                    Projectile.rotation = Projectile.velocity.ToRotation() + 45.ToRadians();
                }
                else if (StoredItem.ammo > 0)
                {
                    Projectile.rotation = Projectile.velocity.ToRotation();
                    if (StoredItem.ammo == AmmoID.Arrow)
                    {
                        Projectile.rotation += -90.ToRadians();
                    }
                    else if (StoredItem.ammo == AmmoID.Bullet || StoredItem.ammo == AmmoID.Dart)
                    {
                        Projectile.rotation += 90.ToRadians();
                    }
                    else if (StoredItem.ammo == AmmoID.StyngerBolt || StoredItem.ammo == AmmoID.CandyCorn)
                    {
                        Projectile.rotation += 45.ToRadians();
                    }
                }
                else
                {
                    Projectile.rotation += Tools.RevolutionPerSecond;  // The rest of the items spin
                }
            }
        }
Exemple #6
0
        // When this projectile dies it can shoot out what the stored item would shoot
        private void ItemShoot()
        {
            if (Projectile.owner != Main.myPlayer)
            {
                return;                                    // It'll get synced in multiplayer
            }
            Player player = Main.player[Projectile.owner];

            // Orbital behavior
            var orbitalItem = StoredItem.ModItem as OrbitalItem;

            if (orbitalItem != null)
            {
                Vector2 position = player.Center;
                Vector2 velocity = Vector2.Zero;
                int     type     = orbitalItem.Item.shoot;
                int     damage   = StoredItem.damage;
                orbitalItem.GetWeaponDamage(player, ref damage);

                orbitalItem.Shoot(player, ref position, ref velocity.X, ref velocity.Y, ref type, ref damage, ref StoredItem.knockBack);
                return;
            }

            // Shooting exceptions
            else if (StoredItem.type == ItemID.ExplosiveBunny) // I love these, and they don't have a value for shoot
            {
                var proj = Projectile.NewProjectileDirect(
                    Projectile.Center, Vector2.Zero, ProjectileID.ExplosiveBunny,
                    StoredItem.damage, Projectile.knockBack, player.whoAmI);
                proj.timeLeft = 3;
            }

            // General shooting behavior
            else if (StoredItem.shoot > 0 && StoredItem.ammo == 0 && StoredItem.type != ItemID.StardustDragonStaff) // Stardust dragon was very buggy so it's excluded
            {
                // Summon and pet behavior
                if (StoredItem.buffType != 0)
                {
                    if (player.FindBuffIndex(StoredItem.buffType) < 0)
                    {
                        player.AddBuff(StoredItem.buffType, 60); // Player doesn't have the buff active, adds it
                    }
                    else // Player has the corresponding buff active
                    {
                        var summon = Main.projectile.First(x => x.active && x.type == StoredItem.shoot && x.owner == Projectile.owner);
                        summon.Center = Projectile.Center; // Teleports the pet or summon to this projectile
                        if (StoredItem.damage <= 0)
                        {
                            return;                         // Does nothing else if it's a pet
                        }
                    }
                }


                // Get projectile amount
                int projAmount = 1;
                if (StoredItem.damage > 0 && !StoredItem.consumable && (!StoredItem.melee || StoredItem.useStyle == 1) ||
                    StoredItem.type == ItemID.Clentaminator)
                {
                    projAmount = Main.rand.Next(4, 7); // Weapons excluding non-swingable melee weapons shoot a random amount of projectiles
                }
                if (StoredItem.ranged)
                {
                    projAmount += projAmount / 2 + (int)(60f / StoredItem.useAnimation); // Ranged weapons shoot a lot more based on their speed
                }

                // Get projectile type. Some guns and dart guns don't have the right values so we overwrite them
                int projType = StoredItem.shoot;
                if (projType == 10 && StoredItem.useAmmo == AmmoID.Bullet)
                {
                    projType = ProjectileID.Bullet;
                }
                else if (StoredItem.useAmmo == AmmoID.Dart)
                {
                    projType = ProjectileID.PoisonDart;
                }

                // Get projectile damage
                float damage = StoredItem.damage;
                GobblerHelper.ApplyClassDamage(ref damage, StoredItem, player);


                // Spawning the projectiles
                Vector2 startingRotation = Main.rand.NextVector2();
                for (int i = 0; i < projAmount; i++)
                {
                    Vector2 rotation = startingRotation.RotatedBy(Tools.FullCircle * i / projAmount); // In a circle
                    Vector2 position = Projectile.Center + rotation;
                    Vector2 velocity = rotation * StoredItem.shootSpeed;

                    var proj = Projectile.NewProjectileDirect(
                        position, velocity, projType, (int)damage, StoredItem.knockBack, player.whoAmI);

                    if (GobblerHelper.IsExplosive(StoredItem))
                    {
                        proj.timeLeft = 3;     // Explodes immediately
                    }
                    if (StoredItem.sentry)     // Turrets
                    {
                        proj.position.Y -= 20; // So it doesn't sink into the ground
                        proj.position.X += Main.rand.Next(-20, 21);
                        player.UpdateMaxTurrets();
                    }
                    proj.friendly = true;
                    proj.hostile  = false;
                }
            }
        }
Exemple #7
0
        public override void ModifyTooltips(List <TooltipLine> tooltips)
        {
            string descriptionText;

            if (Language.ActiveCulture == GameCulture.FromCultureName(GameCulture.CultureName.Spanish))
            {
                descriptionText =
                    $"Click Derecho para succionar objetos en el suelo, Click Izquierdo para dispararlos\n" +
                    $"Presiona Tirar Objeto{" (con el arma en favoritos)".If(!Item.favorited)} para vaciar el arma\n" +
                    $"El daño, propiedades y comportamiento del proyectil dependerá según el objeto que dispares\n" +
                    $"Los objetos no-consumibles siempre serán recuperados una vez disparados";
            }
            else
            {
                descriptionText =
                    $"Right Click to suck items from the ground, Left Click to shoot them\n" +
                    $"Press Throw{" while favorited".If(!Item.favorited)} to release the storage\n" +
                    $"Projectile damage, properties and behavior vary on the item\n" +
                    $"Non-consumable items are never lost and will drop after use";
            }


            var player    = Main.player[Item.playerIndexTheItemIsReservedFor];
            var modPlayer = player.GetModPlayer <VirtuousPlayer>();

            Item storedItem = modPlayer.GobblerStorage.Count > 0
                ? modPlayer.GobblerStorage.First().MakeItem()
                : null;


            var nextItemTooltip = new StringBuilder();

            if (storedItem == null)
            {
                nextItemTooltip.Append("Variable damage\nVariable knockback");
            }
            else
            {
                int   damage         = GobblerHelper.ShotDamage(storedItem, player);
                float knockBack      = GobblerHelper.ShotKnockBack(storedItem, player);
                int   preserveChance = 100 - (int)(GobblerHelper.ConsumeChance(storedItem) * 100);


                nextItemTooltip.Append($"Next item: {storedItem.Name}");
                if (storedItem.ammo == AmmoID.Bullet)
                {
                    nextItemTooltip.Append(" (The WHOLE bullet)");
                }
                else if (storedItem.ammo == AmmoID.Rocket)
                {
                    nextItemTooltip.Append(" (...Non-ignited)");
                }

                nextItemTooltip.Append($"\n   Damage: {damage} ");
                if (storedItem.melee)
                {
                    nextItemTooltip.Append("(melee)");
                }
                else if (storedItem.ranged)
                {
                    nextItemTooltip.Append("(ranged)");
                }
                else if (storedItem.magic)
                {
                    nextItemTooltip.Append("(magic)");
                }
                else if (storedItem.summon)
                {
                    nextItemTooltip.Append("(summon)");
                }
                else if (storedItem.thrown)
                {
                    nextItemTooltip.Append("(thrown)");
                }

                nextItemTooltip.Append($"\n   Knockback: {knockBack.ToString("0.0")} ");
                if (knockBack <= 0.0f)
                {
                    nextItemTooltip.Append("(None)");
                }
                else if (knockBack <= 1.5f)
                {
                    nextItemTooltip.Append("(Extremely weak)");
                }
                else if (knockBack <= 3.0f)
                {
                    nextItemTooltip.Append("(Very weak)");
                }
                else if (knockBack <= 4.0f)
                {
                    nextItemTooltip.Append("(Weak)");
                }
                else if (knockBack <= 6.0f)
                {
                    nextItemTooltip.Append("(Average)");
                }
                else if (knockBack <= 7.0f)
                {
                    nextItemTooltip.Append("(Strong)");
                }
                else if (knockBack <= 9.0f)
                {
                    nextItemTooltip.Append("(Very strong)");
                }
                else if (knockBack <= 11.0f)
                {
                    nextItemTooltip.Append("(Extremely strong)");
                }
                else
                {
                    nextItemTooltip.Append("(Insane)");
                }

                nextItemTooltip.Append($"\n   Preserve chance: {preserveChance}%");
            }


            var customTooltips = new List <TooltipLine>();

            string capacityTooltip = $"Current capacity: {modPlayer.GobblerStorage.Count}/{StorageCapacity}";

            customTooltips.Add(new TooltipLine(Mod, "GobblerCapacity", capacityTooltip));
            customTooltips.Add(new TooltipLine(Mod, "GobblerItem", nextItemTooltip.ToString()));
            customTooltips.Add(new TooltipLine(Mod, "GobblerTooltip", descriptionText));

            tooltips.RemoveAll(line => line.mod == "Terraria" && TooltipsToRemove.Contains(line.Name));
            tooltips.InsertRange(1, customTooltips);
        }
Exemple #8
0
        public override bool Shoot(Player player, EntitySource_ItemUse_WithAmmo source, Vector2 position, Vector2 velocity, int type, int damage, float knockback)
        {
            var modPlayer = player.GetModPlayer <VirtuousPlayer>();

            position  = player.Center + (Main.MouseWorld - player.Center).OfLength(Item.width); // Tip of the nozzle
            position += position.Perpendicular(10);                                             // Moves it up to be centered

            if (!Collision.CanHit(player.Center, 0, 0, position, 0, 0))
            {
                position = player.Center;                                                         // So it doesn't shoot through walls
            }
            // Right click, absorb
            if (player.altFunctionUse == 2)
            {
                if (player.itemAnimation == 1) // Resets the animation so it doesn't return to resting position
                {
                    player.itemAnimation = Item.useAnimation;
                }

                if (PlayerInput.Triggers.JustReleased.MouseRight) // Stops the item use immediately
                {
                    player.itemAnimation = 0;

                    foreach (var item in Main.item.Where(x => x.active))
                    {
                        item.GetGlobalItem <VirtuousItem>().beingGobbled = false; // Makes items able to be picked up again
                    }

                    return(false);
                }


                if (player.itemAnimation == Item.useAnimation - 1)
                {
                    SoundEngine.PlaySound(SoundID.Item22, position); // Once at the beginning of the animation
                }


                bool sucked = false; // Whether an item has been sucked in this tick

                foreach (Item item in Main.item)
                {
                    if (IsGobblableItem(item))
                    {
                        if (item.WithinRange(position, AttractRange))
                        {
                            item.GetGlobalItem <VirtuousItem>().beingGobbled = true;  // So it can't be picked up
                            item.velocity -= (item.Center - position).OfLength(0.5f); // Drawn toward the nozzle

                            if (item.WithinRange(position, StoreRange))
                            {
                                while (item.stack > 0 && modPlayer.GobblerStorage.Count < StorageCapacity)
                                {
                                    if (!sucked)
                                    {
                                        sucked = true;
                                        SoundEngine.PlaySound(SoundID.Item3, position);
                                    }

                                    modPlayer.GobblerStorage.Add(new GobblerStoredItem(item));

                                    if (--item.stack == 0)
                                    {
                                        item.active = false;
                                    }
                                }
                            }

                            if (Main.netMode == NetmodeID.MultiplayerClient) // Syncs to multiplayer
                            {
                                NetMessage.SendData(MessageID.SyncItem, -1, -1, null, item.whoAmI);
                            }
                        }
                    }
                }
            }
            // Left click, shoot
            else
            {
                if (player.itemAnimation == Item.useAnimation - 1) // Once every animation
                {
                    if (modPlayer.GobblerStorage.Count == 0)
                    {
                        SoundEngine.PlaySound(SoundID.Item23, position);
                    }
                    else
                    {
                        SoundEngine.PlaySound(SoundID.Item5, position);

                        var  gobblerItem = modPlayer.GobblerStorage.First();
                        var  item        = gobblerItem.MakeItem();
                        bool consume     = Main.rand.NextFloat() < GobblerHelper.ConsumeChance(item);

                        if (item.ammo == AmmoID.Arrow) // Arrows are shot just fine
                        {
                            var proj = Projectile.NewProjectileDirect(
                                position, new Vector2(speedX, speedY), item.shoot,
                                GobblerHelper.ShotDamage(item, player), GobblerHelper.ShotKnockBack(item, player),
                                player.whoAmI);
                            proj.noDropItem = true;
                            proj.netUpdate  = true;
                        }
                        else // Shooting the custom projectile that takes the form of any item
                        {
                            if (gobblerItem.type == ItemID.EndlessMusketPouch)
                            {
                                gobblerItem.type = ItemID.MusketBall;                                                // Exception
                            }
                            var proj = Projectile.NewProjectileDirect(
                                position, new Vector2(speedX, speedY), type, damage, knockBack, player.whoAmI);
                            var gobblerProj = proj.ModProjectile as ProjGobblerItem;
                            gobblerProj.Consumed    = consume;
                            gobblerProj.GobblerItem = gobblerItem;
                            proj.netUpdate          = true;


                            if (gobblerItem.type == ItemID.Arkhalis) // Ridiculous effect for ridiculous weapon
                            {
                                for (int i = 0; i < 5; i++)
                                {
                                    proj = Projectile.NewProjectileDirect(
                                        position, new Vector2(speedX, speedY) * Main.rand.NextFloat(),
                                        type, damage, knockBack, player.whoAmI);
                                    gobblerProj             = proj.ModProjectile as ProjGobblerItem;
                                    gobblerProj.Consumed    = false;
                                    gobblerProj.GobblerItem = gobblerItem;
                                    proj.netUpdate          = true;
                                }
                            }
                        }

                        if (consume)
                        {
                            modPlayer.GobblerStorage.RemoveAt(0);
                        }
                    }
                }
            }

            return(false);
        }