Tractor Mod

Tractor Mod

130k Downloads

[Lookup Anything] provide public API for mod integrations

Platonymous opened this issue ยท 2 comments

commented

Provide a public API other mods can use to integrate with Lookup Anything to provide custom information.

commented

So I was blind and missed this issue, but I'd like to bump this issue now that Pintail is soon to be a thing and we'll be able to use interfaces for APIs. Posting from my original writeup in the duplicate issue I opened and closed:

Ideally, I'd like to be able to register my own ILookupProvider(s). It shouldn't really be Lookup Anything's responsibility to know the internals of my mod, after all. However, ISubjects are fairly involved too, so thinking about that, some convenience methods in the API to create ISubject instances would be nice.

As a rough draft, maybe something like

public interface ILookupAnything
{
    #region ILookupProvider Registration

    /// <summary>
    /// Register an <see cref="ILookupProvider"/> to provide data to
    /// Lookup Anything from a mod.
    /// </summary>
    /// <param name="modManifest">Your mod's manifest</param>
    /// <param name="provider">An <c>ILookupProvider</c> instance</param>
    void RegisterLookupProvider(IManifest modManifest, ILookupProvider provider);

    /// <summary>
    /// Unregister an <see cref="ILookupProvider"/>. If no provider is
    /// given, unregister all of the mod's providers.
    /// </summary>
    /// <param name="modManifest">Your mod's manifest</param>
    /// <param name="provider">The specific <c>ILookupProvider</c> instance to remove</param>
    void UnregisterLookupProvider(IManifest modManifest, ILookupProvider provider = null);

    #endregion

    #region ISubject Helpers

    // Basically, these methods would provide access to the logic already
    // used by existing ILookupProvider instances so that external lookup
    // providers wouldn't need to reinvent the wheel for handling
    // basic types that Lookup Anything already supports.

    ISubject BuildItemSubject(Item target, ObjectContext context, GameLocation? location, bool knownQuality);

    ISubject BuildCropSubject(Crop target, ObjectContext context, HoeDirt dirt);

    ISubject BuildBuildingSubject(Building building);

    ISubject BuildNPCSubject(NPC npc);

    ISubject BuildAnimalSubject(FarmAnimal animal);

    ISubject BuildFarmerSubject(Farmer player);

    // ... etc.

    #endregion

}

Then I, as an external mod author, could use something like this for basic support:

public AlmanacProvider : ILookupProvider {

	private readonly ILookupAnything API;

	public AlmanacProvider(ILookupAnything api) {
		API = api;
	}

	public IEnumerable<ITarget> GetTargets(GameLocation location, Vector2 lookupTile) {
		yield break;
	}

	public ISubject GetSubject(IClickableMenu menu, int cursorX, int cursorY) {
		if (menu is Menus.AlmanacMenu almanac) {
			if (almanac.HoveredNPC is not null)
				return API.BuildNPCSubject(almanac.HoveredNPC);

			if (almanac.HoveredBuilding is not null)
				return API.BuildBuildingSubject(almanac.HoveredBuilding);

			// ... etc.
		}
	}

	public ISubject GetSubjectFor(object entity, GameLocation location) {
		return null;
	}

	public IEnumerable<ISubject> GetSearchSubjects() {
		yield break;
	}

}
commented

I'm going to try to take a crack at this. There are a lot of classes and enums in this, it might end up needing to be a nuget package 0_0