-
Notifications
You must be signed in to change notification settings - Fork 24
Mod.Call
This page goes over how to interface Subworld Library within your own mod without adding a strong dependency, achieved via "Mod.Call". Doing so requires a more careful approach, since you have to consider two cases: Subworld Library is enabled, or disabled. See the following tModLoader guide for an introduction on "Mod.Call". Also see the ModCallExampleMod, which contains current API usage and examples. If you wish to use/test it yourself, you can clone this repository, then symlink it to your Mod Sources folder, instructions here (based on ExampleMod).
- Your mod's core isn't built around subworlds
- You want to detach your mod from this one, in case incompatibilities start arising which will stop your entire mod from loading
- Opt-in subworlds
You'll have to signal to your players that this feature exists via other means (description, homepage, ingame), because it won't be marked as a dependency in the Mods menu.
If something goes wrong, null
is returned. For "Register", only the parameters up until List<GenPass> tasks
are required.
Command | Parameters | Returns |
---|---|---|
"Register" |
Mod mod string name int width int height List<GenPass> tasks Action load = null Action unload = null ModWorld modWorld = null bool saveSubworld = false bool disablePlayerSaving = false bool saveModData = false bool noWorldUpdate = true UserInterface loadingUI = null Func<UIState> loadingUIState = null Func<UIState> votingUI = null ushort votingDuration = 1800 Action onVotedFor = null
|
string id |
"Enter" | string id |
true |
"Exit" | true |
|
"Current" |
string id , null if not in a subworld |
|
"IsActive" | string id |
true if in that subworld, false if not |
"AnyActive" | Mod mod |
true if in a subworld from that mod, false if not |
"DrawMenu" |
bool (optional) |
SLWorld.drawMenu |
"DrawUnderworldBackground" |
bool (optional) |
SLWorld.drawUnderworldBackground |
To register subworlds, you will have to do so in your MyMod.cs
file in the PostSetupContent
hook. You first check if Subworld Library is loaded, then call "Register" with the arguments you want.
To interface with some of the methods here, you would do the same procedure. in WeakRefExampleMod, we simplify that by checking for Subworld Library only once during PostSetupContent
, and reuse that in all other calls.
Minimal "Register" example. You'll see a bigger one in the ModCallExampleMod.
public static string mySubworldID = string.Empty; //An empty string will not cause any problems in Enter, IsActive etc. calls
public override void Unload()
{
mySubworldID = string.Empty;
}
public override void PostSetupContent()
{
Mod subworldLibrary = ModLoader.GetMod("SubworldLibrary");
if (subworldLibrary != null)
{
object result = subworldLibrary.Call(
"Register",
/*Mod mod*/ ModContent.GetInstance<MyMod>(),
/*string name*/ "MySubworld",
/*int width*/ 600,
/*int height*/ 400,
/*List<GenPass> tasks*/ MySubworldGenPassList() //Defined below
);
if (result != null && result is string id)
{
mySubworldID = id;
}
}
}
//Example for some GenPasses you might want to use. You can use Main.maxTilesX/Y here, they'll be the width and height you specified earlier
public static List<GenPass> MySubworldGenPassList()
{
List<GenPass> list = new List<GenPass>
{
//First pass
new PassLegacy("Adjusting",
delegate (GenerationProgress progress)
{
progress.Message = "Adjusting world levels"; //Sets the text above the worldgen progress bar
Main.worldSurface = Main.maxTilesY - 42; //Hides the underground layer just out of bounds
Main.rockLayer = Main.maxTilesY; //Hides the cavern layer way out of bounds
},
1f),
//Second pass
new PassLegacy("GeneratingDirt",
delegate (GenerationProgress progress)
{
progress.Message = "Generating a place to stand on";
//Create three tiles for the player to stand on when he spawns
for (int i = -1; i < 2; i++)
{
WorldGen.PlaceTile(Main.spawnTileX - i, Main.spawnTileY + 2, TileID.Dirt, true, true);
}
},
1f)
//Add more passes here
};
return list;
}
This will work as a helper method, you can apply the same syntax to the other ones.
public static bool? Enter(string id)
{
Mod subworldLibrary = ModLoader.GetMod("SubworldLibrary");
if (subworldLibrary != null)
{
return subworldLibrary.Call("Enter", id) as bool?;
}
return null;
}
Usage example:
bool result = Enter(mySubworldID) ?? false;
if (!result) Main.NewText("Something went wrong, not entering " + mySubworldID);