Keen:Search Conditions

From Medieval Engineers Wiki
Revision as of 21:35, 15 December 2017 by CptTwinkie (talk | contribs)
Jump to navigation Jump to search

The search system is a Session Component, and it powers the general search screen (also known as G-Screen). It is, however, completely detached from the actual screen, and can be used just about anywhere. The system works by loading all relevant definitions, extracting whatever data it needs from the (tag, recipes, items, etc.), and then constructing internal searchable definition database. Since the database is constructed during loading, it works with mods out-of-the-box.


Version: 0.6.1

Script Access

You can access the search system from your scripts, to find whatever it is that you need. The string you send to the search system can also include a prefix for the various search conditions, including a custom one if you happen to have one. The Search method returns a collection of MyVisualDefinitionBase, which is a common base class used for all searchable definitions.

Example:

public void SearchForStuff()
{
	var search = MySession.Static.Components.Get<MySearchSystem>();
	if (search == null)
		return;

	var results = search.Search("Hello, is it me you're looking for?");
}

Search Conditions

While the system itself is responsible for creating the database of whatever it wants to be searchable, the actual search mechanism is implemented via so-called search conditions. These conditions are typically very lightweight classes that implement the IMySearchCondition interface and are registered with the search system.

Each condition has a different use-case, and in order for the system to know which of them we want to use with the current search term, we need to include a prefix in the search. The prefix is a single character, and once the system identifies the condition associated with the prefix, it will remove the prefix and send the rest of the search term to the appropriate condition.

Split String Condition

This is the default search condition and is the only one that is used without any prefix. As the name implies, this condition splits the search term into smaller strings, using the space character as the separator. Any definition's display name, that includes all of the sub-strings, is returned as a valid search result.

Single String Condition

Prefix: %

Unlike Split String, this condition uses the whole search term to find the matching definitions. This means that in order to be a valid definition for the search, the display name of the definition must include the whole search term.

Category Condition

Prefix: $

Categories are special definitions of type MySearchCategoryDefinition, which can contain any amount of definition ids of other things, like items, blocks, weapons, voxel hands, etc. In order for a definition to satisfy this condition, it needs to be in one of the eligible categories. A category is eligible when its subtype or display name contains the search term.

Example Category:

<Definition xsi:type="MyObjectBuilder_SearchCategoryDefinition">
  <Id Type="SearchCategoryDefinition" Subtype="Coins" />
  <DisplayName>Coins</DisplayName>

  <Entry Type="InventoryItem" Subtype="CoinCopper" />
  <Entry Type="InventoryItem" Subtype="CoinSilver" />
  <Entry Type="InventoryItem" Subtype="CoinGold" />
  <Entry Type="ToolheadItem" Subtype="PatternCoin" />
  <Entry Type="CubeBlock" Subtype="PressMechanical" />
</Definition>

Id: definition Id of the category. All categories are of type SearchCategoryDefinition.

DisplayName: this is actually not displayed in the game as of now, but it is important because it is used for condition matching.

Entry: a definition Id entry, where Type is the definition type, and Subtype is its subtype.

Tag Condition

Prefix: #

Tag condition allows you to search for items based on their Tag. An item matches this condition when one of its tags contains the search term in its subtype or display name.

Block Condition

Prefix: =

As the name already suggests, this condition can only be used to search for blocks. It tries to match the search term against small or large, and then it proceeds to match any blocks that are either small or large. If neither of the sizes is specified, all blocks are considered valid.

ObjectBuilderType Condition

Prefix: ~

This is a very straightforward, and mostly technical search condition. If checks the definition type to see if it includes the search term.

Mod Condition

Prefix: @

The mod condition is currently the only search condition that does not provide any meaningful results without mods. Once there are mods present, it will check the name of the mod where the definition comes from, to see whether or not it includes the search term.

Usage Condition

Prefix: !

Usage is the most complex search condition, simply due to returning a large number of definitions that might not seem connected at first glance. First, this condition matches definitions that include the search term in their display name. Then it returns all items and blocks, that are built or crafted from the items that match the condition.

Custom Condition

There a possibility to implement custom search conditions in a mod, by implementing the IMySearchCondition interface.

public interface IMySearchCondition
{
    void Init(string searchString);

    bool Match(MyVisualDefinitionBase definition);

    string DisplayName { get; }

    string Description { get; }
}

Init: This is called each time the search term is changed. It is the best place to set inner variables, that need to be changed for each search.

Match: Each searchable definition will be sent here, to determine whether it matches the condition, based on the search term.

DisplayName: Name of this condition, used in the GUI.

Description: Description of this condition, used in the GUI. A good place to provide a short explanation of how the condition works, and possibly provide an example.


Once the condition has been implemented, there is one more thing to do, and that is the registration of the condition within the search system.

Example:

public class CustomSearchCondition: IMySearchCondition {
	...
}

public void RegisterSeach() {
    var search = MySession.Static.Components.Get<MySearchSystem>();
    if (search == null)
        return;

    var condition = new CustomSearchCondition();
    search.RegisterSearchCondition('^', condition);
}


NOTICE: If multiple conditions are registered with the same prefix (the '^' in the example above), the one that is registered last will prevail.


If you, for whatever reason, wish to unregister a search condition, you can do so by calling the UnregisterSearch() method.

Example:

public void UnregisterSearch() {
    var search = MySession.Static.Components.Get<MySearchSystem>();
    if (search == null)
        return;

    search.UnregisterSearchCondition('^');
}


NOTICE: You can also call UnregisterSearchCondition with the instance of your search condition. This will unregister it from all prefixes it was usable with.