-
Notifications
You must be signed in to change notification settings - Fork 2
Implementing Autofisher mod integration
Welcome! This guide is meant to teach you how to add Autofisher support to your mod. If you want a code example to go along with the tutorial, check out the Fishing 2.0 mod source here: https://github.com/rayman89/Fishing3.
Unfortunately, Miscellania doesn't support the standard tModLoader fishing-related hooks, since it's a TileEntity and it doesn't use a ModPlayer. But, Miscellania provides alternative fishing hooks, which are meant to be similar to the tML methods.
In order to use Miscellania's hooks, you need to define at least one of these methods:
public static void AutofisherGetFishingLevel(Vector2 position, Item fishingRod, Item bait, ref int fishingLevel)
public static void AutofisherCatchFish(Vector2 position, int zoneInfo, Item fishingRod, Item bait, int power, int liquidType, int poolSize, int worldLayer, ref int caughtType, ref bool junk)
(the tModLoader ModItem.CaughtItemStack
hook is natively supported)
Note that these methods can have any name you want and can be in any class, but they must be public static
and they must have this exact parameter list. For this example, let's assume these methods are inside of a class called MyFishingTweaks
.
Once you have your hooks ready, you have to register them via mod.Call()
like so:
public override void PostSetupContent()
{
var miscellaniaMod = ModLoader.GetMod("GoldensMisc");
if(miscellaniaMod != null)
{
//you should probably use nameof() instead if your version of C# supports it
miscellaniaMod.Call("RegisterHookGetFishingLevel", typeof(MyFishingTweaks), "AutofisherGetFishingLevel");
miscellaniaMod.Call("RegisterHookCatchFish", typeof(MyFishingTweaks), "AutofisherCatchFish");
}
}
While these methods are similar to the usual ModPlayer
fishing hooks, there are some differences. Specifically, you don't have access to any Player
objects! Instead, you are given a Vector2 position
parameter, as well as a weird int zoneInfo
parameter. It is meant to replace the player.Zone*
properties for determining biomes.
To actually get any useful information out of this integer, you must define an enum like this:
[Flags]
public enum Zone
{
None = 0,
Corrupt = 1,
Crimson = 2,
Holy = 4,
Snow = 8,
Jungle = 16,
Shroom = 32,
Dungeon = 64,
Desert = 128
}
You'll then be able to do this:
Zone zone = (Zone)zoneInfo;
if(zone.HasFlag(Zone.Jungle))
{
...
You can use that alongside the int worldLayer
parameter to detect any Vanilla biome. The worldLayer
parameter works the same as the tML one:
The worldLayer parameter is 0 if the player is in the sky, 1 if the player is on the surface, 2 if the player is underground, 3 if the player is in the caverns, and 4 if the player is in the underworld.
Unfortunately, adding Autofisher support for custom modded biomes is tricky. You'll have to manually count all the tiles around the given position
, and determine whether or not you're in the correct biome. Here's an example implementation of this (it's what Miscellania uses to determine the Vanilla biomes):
//results[0] = My Superbiome #1, results[1] = My Superbiome #2
int[] CountBiomeTiles(int x, int y)
{
int[] results = new int[2];
int startX = Math.Max(0, x - Main.zoneX / 2);
int startY = Math.Max(0, y - Main.zoneY / 2);
int endX = Math.Min(Main.maxTilesX, x + Main.zoneX / 2);
int endY = Math.Min(Main.maxTilesY, y + Main.zoneY / 2);
for(int i = startX; i < endX; i++)
{
for(int j = startY; j < endY; j++)
{
var tile = Main.tile[i, j];
if(tile == null || !tile.active())
continue;
if(tile.type == mod.TileType("BiomeTile") ||
tile.type == mod.TileType("AnotherBiomeTile"))
//My Superbiome #1
results[0]++;
else ...
}
}
return results;
}
- The
Item fishingRod
parameter is always a Mechanic's Rod (this might change in the future if I decide to add Autofisher upgrades, but just keep that in mind). - If you're using the custom biome detection algorithm, don't worry about lag as it will only be called once every 10-20 seconds or so.