Skip to content

Commit

Permalink
Add ModPlayer.ModifyFishingAttempt hook (tModLoader#2623)
Browse files Browse the repository at this point in the history
* give ExampleBuffPotion a DrinkParticleColors entry

* ModPlayer.ModifyFishingAttempt hook

* ExampleMod: new buff/potion for ModifyFishingAttempt
  • Loading branch information
direwolf420 authored Jun 27, 2022
1 parent e01313c commit 9515325
Show file tree
Hide file tree
Showing 9 changed files with 122 additions and 3 deletions.
20 changes: 19 additions & 1 deletion ExampleMod/Common/Players/ExampleFishingPlayer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,25 @@

namespace ExampleMod.Common.Players
{
// This class showcases things you can do with fishing
public class ExampleFishingPlayer : ModPlayer
{
public bool hasExampleCrateBuff;

public override void ResetEffects() {
hasExampleCrateBuff = false;
}

public override void ModifyFishingAttempt(ref FishingAttempt attempt) {
// If the player has the Example Crate buff (given by Example Crate Potion), 10% additional chance that the catch will be a crate
// The "tier" of the crate depends on the rarity, which we don't modify here, see the comments in CatchFish for details
if (hasExampleCrateBuff && !attempt.crate) {
if (Main.rand.Next(100) < 10) {
attempt.crate = true;
}
}
}

public override void CatchFish(FishingAttempt attempt, ref int itemDrop, ref int npcSpawn, ref AdvancedPopupRequest sonar, ref Vector2 sonarPosition) {
bool inWater = !attempt.inLava && !attempt.inHoney;
bool inExampleSurfaceBiome = Player.InModBiome<ExampleSurfaceBiome>();
Expand Down Expand Up @@ -43,7 +60,8 @@ public override void CatchFish(FishingAttempt attempt, ref int itemDrop, ref int
// We don't want to replace golden/titanium crates (the highest tier crates), as they take highest priority in crate catches
// Their drop conditions are "veryrare" or "legendary"
// (After that come biome crates ("rare"), then iron/mythril ("uncommon"), then wood/pearl (none of the previous))
if (!attempt.veryrare && !attempt.legendary && attempt.rare) {
// Let's replace biome crates 50% of the time (player could be in multiple (modded) biomes, we should respect that)
if (!attempt.veryrare && !attempt.legendary && attempt.rare && Main.rand.NextBool()) {
itemDrop = ModContent.ItemType<Content.Items.Consumables.ExampleFishingCrate>();
}
}
Expand Down
19 changes: 19 additions & 0 deletions ExampleMod/Content/Buffs/ExampleCrateBuff.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using ExampleMod.Common.Players;
using Terraria;
using Terraria.ModLoader;

namespace ExampleMod.Content.Buffs
{
public class ExampleCrateBuff : ModBuff
{
public override void SetStaticDefaults() {
DisplayName.SetDefault("Example Crate");
Description.SetDefault("Greater chance of fishing up a crate");
}

public override void Update(Player player, ref int buffIndex) {
// Use a ModPlayer to keep track of the buff being active
player.GetModPlayer<ExampleFishingPlayer>().hasExampleCrateBuff = true;
}
}
}
Binary file added ExampleMod/Content/Buffs/ExampleCrateBuff.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 8 additions & 0 deletions ExampleMod/Content/Items/Consumables/ExampleBuffPotion.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using Terraria.ID;
using Terraria.GameContent.Creative;
using Terraria.ModLoader;
using Microsoft.Xna.Framework;

namespace ExampleMod.Content.Items.Consumables
{
Expand All @@ -11,6 +12,13 @@ public override void SetStaticDefaults() {
Tooltip.SetDefault("Gives a light defense buff.");

CreativeItemSacrificesCatalog.Instance.SacrificeCountNeededByItemId[Type] = 20;

// Dust that will appear in these colors when the item with ItemUseStyleID.DrinkLiquid is used
ItemID.Sets.DrinkParticleColors[Type] = new Color[3] {
new Color(240, 240, 240),
new Color(200, 200, 200),
new Color(140, 140, 140)
};
}

public override void SetDefaults() {
Expand Down
49 changes: 49 additions & 0 deletions ExampleMod/Content/Items/Consumables/ExampleCratePotion.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
using Terraria;
using Terraria.ID;
using Terraria.GameContent.Creative;
using Terraria.ModLoader;
using Microsoft.Xna.Framework;

namespace ExampleMod.Content.Items.Consumables
{
public class ExampleCratePotion : ModItem
{
public override void SetStaticDefaults() {
Tooltip.SetDefault("Increases chance to get a crate" +
"\nStacks with {$ItemName.CratePotion}");

CreativeItemSacrificesCatalog.Instance.SacrificeCountNeededByItemId[Type] = 20;

// Dust that will appear in these colors when the item with ItemUseStyleID.DrinkLiquid is used
ItemID.Sets.DrinkParticleColors[Type] = new Color[3] {
new Color(240, 240, 240),
new Color(200, 200, 200),
new Color(140, 140, 140)
};
}

public override void SetDefaults() {
Item.width = 20;
Item.height = 26;
Item.useStyle = ItemUseStyleID.DrinkLiquid;
Item.useAnimation = 15;
Item.useTime = 15;
Item.useTurn = true;
Item.UseSound = SoundID.Item3;
Item.maxStack = 30;
Item.consumable = true;
Item.rare = ItemRarityID.Green;
Item.value = Item.buyPrice(silver: 8);
Item.buffType = ModContent.BuffType<Buffs.ExampleCrateBuff>(); // Specify an existing buff to be applied when used.
Item.buffTime = 3 * 60 * 60; // The amount of time the buff declared in Item.buffType will last in ticks. Set to 3 minutes, as 60 ticks = 1 second.
}

// Please see Content/ExampleRecipes.cs for a detailed explanation of recipe creation.
public override void AddRecipes() {
CreateRecipe()
.AddIngredient(ItemID.CratePotion, 4)
.AddTile(TileID.CrystalBall)
.Register();
}
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
11 changes: 10 additions & 1 deletion patches/tModLoader/Terraria/ModLoader/ModPlayer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -714,7 +714,16 @@ public virtual void OnHitByProjectile(Projectile proj, int damage, bool crit) {
}

/// <summary>
/// Allows you to change the item or enemy the player gets when sucessfully catching a "fish". The Fishing Attempt structure contains most information about the vanilla event, including the Item Rod and Bait used by the player, the liquid it is being fished on, and so on.
/// Allows you to change information about the ongoing fishing attempt before cought items/NPCs are decided, after all vanilla information has been gathered.
/// <br/>Will not be called if various conditions for getting a catch aren't met, meaning you can't modify those.
/// <br/>Setting <see cref="FishingAttempt.rolledItemDrop"/> or <see cref="FishingAttempt.rolledEnemySpawn"/> is not allowed and will be reset, use <see cref="CatchFish"/> for that.
/// </summary>
/// <param name="attempt">The structure containing most data from the vanilla fishing attempt</param>
public virtual void ModifyFishingAttempt(ref FishingAttempt attempt) {
}

/// <summary>
/// Allows you to change the item or enemy the player gets when sucessfully catching an item or NPC. The Fishing Attempt structure contains most information about the vanilla event, including the Item Rod and Bait used by the player, the liquid it is being fished on, and so on.
/// The Sonar and Sonar position fields allow you to change the text, color, velocity and position of the catch's name (be it item or NPC) freely
/// </summary>
/// <param name="attempt">The structure containing most data from the vanilla fishing attempt</param>
Expand Down
11 changes: 11 additions & 0 deletions patches/tModLoader/Terraria/ModLoader/PlayerLoader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -824,6 +824,17 @@ public static void OnHitByProjectile(Player player, Projectile proj, int damage,
}
}

private delegate void DelegateModifyFishingAttempt(ref FishingAttempt attempt);
private static HookList HookModifyFishingAttempt = AddHook<DelegateModifyFishingAttempt>(p => p.ModifyFishingAttempt);

public static void ModifyFishingAttempt(Player player, ref FishingAttempt attempt) {
foreach (int index in HookModifyFishingAttempt.arr) {
player.modPlayers[index].ModifyFishingAttempt(ref attempt);
}

attempt.rolledItemDrop = attempt.rolledEnemySpawn = 0; // Reset, modders need to use CatchFish for this
}

private delegate void DelegateCatchFish(FishingAttempt attempt, ref int itemDrop, ref int enemySpawn, ref AdvancedPopupRequest sonar, ref Vector2 sonarPosition);
private static HookList HookCatchFish = AddHook<DelegateCatchFish>(p => p.CatchFish);

Expand Down
7 changes: 6 additions & 1 deletion patches/tModLoader/Terraria/Projectile.cs.patch
Original file line number Diff line number Diff line change
Expand Up @@ -797,7 +797,12 @@
if (wet)
position += wetVelocity;
else
@@ -13443,8 +_,17 @@
@@ -13439,12 +_,22 @@
fisher.heightLevel = 4;

FishingCheck_RollDropLevels(fisher.fishingLevel, out fisher.common, out fisher.uncommon, out fisher.rare, out fisher.veryrare, out fisher.legendary, out fisher.crate);
+ PlayerLoader.ModifyFishingAttempt(Main.player[owner], ref fisher);
FishingCheck_ProbeForQuestFish(ref fisher);
FishingCheck_RollEnemySpawns(ref fisher);
FishingCheck_RollItemDrop(ref fisher);
bool flag = false;
Expand Down

0 comments on commit 9515325

Please sign in to comment.