Content Patcher

Content Patcher

378k Downloads

[Lookup Anything] Could we get an API now that Pintail will soon be a thing?

KhloeLeclair opened this issue ยท 0 comments

commented

Hello, I am interested in an API for Lookup Anything for better integration with my mod Almanac. Currently, I'm using a HoveredItem field to support looking up items in my menu, but I'd like to be able to let users look up other sorts of content too. And now that we have Pintail coming and APIs can have interfaces, this seems like a good time to look into it.

Ideally, I'd like to be able to register my own ILookupProvider(s) I think. 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;
	}

}

Edit: Just noticed that this is a duplicate issue. I swear I looked through the issue list twice before posting this. I must be blind. Seriously. Sorry, closing this and posting to #172 instead.