public override void ModifyTooltips(List <TooltipLine> tooltips) { Player player = Main.player[item.owner]; VirtuousPlayer modPlayer = player.GetModPlayer <VirtuousPlayer>(); Item storedItem = modPlayer.GobblerItem(BaseSlot); int storageFilled = modPlayer.GobblerStorageFilled(); bool hasItem = storageFilled > 0; //Removes the favorite text and critical chance text tooltips.RemoveAll(line => line.mod == "Terraria" && (line.Name.StartsWith("Favorite") || line.Name.StartsWith("CritChance"))); foreach (TooltipLine line in tooltips) { if (line.mod == "Terraria" && line.Name == "Damage") //Replaces the damage line with capacity, shot item name and shot item damage { if (player != null) { int? itemDamage = null; string itemName = null; if (hasItem) { itemDamage = ProjGobblerItem.ShotDamage(storedItem, player); itemName = storedItem.Name; } string damageTypeText = null; if (storedItem.melee) { damageTypeText = "(melee)"; } else if (storedItem.ranged) { damageTypeText = "(ranged)"; } else if (storedItem.magic) { damageTypeText = "(magic)"; } else if (storedItem.summon) { damageTypeText = "(summon)"; } else if (storedItem.thrown) { damageTypeText = "(thrown)"; } line.text = "Current capacity: " + storageFilled + "/" + StorageCapacity; //Capacity if (hasItem) { line.text += "\nNext item: " + itemName; //Item name, if there is one if (storedItem.ammo == AmmoID.Bullet) { line.text += " (The WHOLE bullet)"; } else if (storedItem.ammo == AmmoID.Rocket) { line.text += " (...Non-ignited)"; } } line.text += "\n" + (hasItem ? (" Damage: " + itemDamage) : ("Variable damage")); //Item damage if (hasItem) { line.text += " " + damageTypeText; //Item damage type } } else { line.text = "Current capacity: 0/100\nVariable damage"; //Default text if something went wrong } } else if (line.mod == "Terraria" && line.Name == "Speed") //Replaces the speed line with shot item knockback and consume chance { string defaultText = "Variable knockback"; if (player != null) { float knockBack = 0; string knockBackText = defaultText; if (hasItem) { knockBack = ProjGobblerItem.ShotKnockBack(storedItem, player); knockBackText = " Knockback: " + knockBack.ToString("0.0") + " ("; if (knockBack <= 0.0f) { knockBackText += "None"; } else if (knockBack <= 1.5f) { knockBackText += "Extremely weak"; } else if (knockBack <= 3.0f) { knockBackText += "Very weak"; } else if (knockBack <= 4.0f) { knockBackText += "Weak"; } else if (knockBack <= 6.0f) { knockBackText += "Average"; } else if (knockBack <= 7.0f) { knockBackText += "Strong"; } else if (knockBack <= 9.0f) { knockBackText += "Very strong"; } else if (knockBack <= 11.0f) { knockBackText += "Extremely strong"; } else { knockBackText += "Insane"; } knockBackText += ")"; } line.text = knockBackText; //Knockback if (hasItem) { line.text += "\n Preserve chance: " + (100 - (int)(ConsumeChance(storedItem) * 100)) + "%"; //Consume chance, if any } } else { line.text = defaultText; //Default text if something went wrong } } else if (line.mod == "Terraria" && line.Name == "Knockback") //Replaces the knockback line with use speed, and adds the tooltip below { string defaultText = "Average speed"; if (hasItem) { line.text = " "; //Space to align with the other item data if (ConsumeChance(storedItem) == 0f) { line.text += "Fast speed"; //Exception } else { line.text += defaultText; } } else { line.text = defaultText; //Moves forward to align with the item info } //At the end of the tooltip line.text += "\nRight Click to suck items from the ground, Left Click to shoot them"; line.text += "\nPress Throw" + (item.favorited ? (" ") : (" while favorited ")) + "to release the storage"; line.text += "\nProjectile damage, properties and behavior vary on the item"; line.text += "\nNon-consumable items always drop after being spent, though they may be damaged"; line.text += "\n[Warning]: Experimental technology. May carry unintended and hilarious consequences"; } } }
public override bool Shoot(Player player, ref Vector2 position, ref float speedX, ref float speedY, ref int type, ref int damage, ref float knockBack) { VirtuousPlayer modPlayer = player.GetModPlayer <VirtuousPlayer>(); position = player.Center + (Main.MouseWorld - player.Center).OfLength(item.width); //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; //Resets to the player center if the nozzle is unreachable } if (player.altFunctionUse == 2) //Right click, absorb { //A little hack to stop the bugged 1-tick delay between consecutive alternate-uses of a weapon 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 manually. Has the secondary effect of only sucking while you're actually clicking { player.itemAnimation = 0; return(false); } if (player.itemAnimation == item.useAnimation - 1) { Main.PlaySound(SoundID.Item22, position); //Once at the beginning of the animation } bool sucked = false; //Whether an item has been sucked in this tick for (int i = 0; i < Main.maxItems; i++) //Cycles through all the items in the world { Item targetItem = Main.item[i]; if (IsGobblableItem(targetItem)) //Finds a valid item { VirtuousItem targetModItem = targetItem.GetGlobalItem <VirtuousItem>(); if (targetItem.WithinRange(position, 250)) //Within sucking range { targetItem.velocity -= (targetItem.Center - position).OfLength(0.5f); //Attracts item towards the nozzle targetModItem.beingGobbled = true; //So it can't be picked up if (targetItem.WithinRange(position, 15)) //Absorb range { for (int slot = 0; slot < StorageCapacity; slot++) //Cycles through the storage { while (slot < StorageCapacity && modPlayer.GobblerStorage[slot] == Empty && targetItem.stack > 0) //If it finds an empty slot, it starts adding items from the item stack into the storage { if (!sucked) { sucked = true; Main.PlaySound(SoundID.Item3, position); } modPlayer.GobblerStorage[slot] = targetItem.type; //Adds the item to the current storage slot targetItem.stack--; //Reduces the stack of the item slot++; //Moves a slot forward if (targetItem.stack == 0) //The stack of the item has reached 0 { targetItem.active = false; //Kills it slot = StorageCapacity; //Breaks the for loop } } } } if (Main.netMode == NetmodeID.MultiplayerClient) //Syncs to multiplayer { NetMessage.SendData(MessageID.SyncItem, -1, -1, null, targetItem.whoAmI); } } } } } else //Left click, shoot { if (player.itemAnimation == item.useAnimation - 1) //Once every animation { if (modPlayer.GobblerStorage[BaseSlot] != Empty) //if there is something in the storage { Item shotItem = modPlayer.GobblerItem(BaseSlot); //For easy access Main.PlaySound(SoundID.Item5, position); bool consume = RandomFloat() < ConsumeChance(modPlayer.GobblerItem(BaseSlot)); if (shotItem.ammo == AmmoID.Arrow) //Arrows are shot just fine { Projectile newProj = Projectile.NewProjectileDirect(position, new Vector2(speedX, speedY), shotItem.shoot, ProjGobblerItem.ShotDamage(shotItem, player), ProjGobblerItem.ShotKnockBack(shotItem, player), player.whoAmI); newProj.noDropItem = true; //So the arrows don't drop and make a mess... } else //Shooting the custom projectile that takes the form of any item { int itemType = modPlayer.GobblerStorage[BaseSlot]; if (itemType == ItemID.EndlessMusketPouch) { itemType = ItemID.MusketBall; //Exception } Projectile.NewProjectileDirect(position, new Vector2(speedX, speedY), type, damage, knockBack, player.whoAmI, consume ? 1f : 0f, itemType); //Shoots the item if (itemType == ItemID.Arkhalis) //Ridiculous effect for ridiculous weapon { for (int i = 0; i < 5; i++) { Projectile.NewProjectileDirect(position, new Vector2(speedX, speedY) * RandomFloat(), type, damage, knockBack, player.whoAmI, 0f, itemType); } } } if (consume) { modPlayer.GobblerStorage[BaseSlot] = Empty; //Clears the item from the storage for (int slot = 0; slot < StorageCapacity; slot++) //Loops through the storage { //Moves the entire array one slot down if (slot < StorageCapacity - 1 && modPlayer.GobblerStorage[slot + 1] != Empty) { modPlayer.GobblerStorage[slot] = modPlayer.GobblerStorage[slot + 1]; modPlayer.GobblerStorage[slot + 1] = Empty; } if (modPlayer.GobblerStorage[slot] == Empty) { break; } } } } else //Nothing in the storage { Main.PlaySound(SoundID.Item23, position); } } } return(false); //Doesn't shoot normally }