-
Notifications
You must be signed in to change notification settings - Fork 2
Examples
- Lategame Upgrades mod currently has two implementations of applications from this API:
- Its upgrade store
- And its Weather Probe feature
- You can use these two as an example of creating your own application as it pretty much uses most of the API for the intended effect.
- Lategame Upgrades mod currently has one implementation of a custom text element:
- Its Upgrade Cursor element used in its upgrade store application.
InteractiveTerminalManager.RegisterApplication<UpgradeStoreApplication>(["lgu", "lategame store"]);
InteractiveTerminalManager.RegisterApplication<WeatherProbeApplication>("probe");
Let's make a simple application where it will display "Hello world!" on top of the screen with "Hope you're having such a lovely day!" text displayed inside with a prompt for the user saying "I absolutely am!" which will trigger exit of the application. The way for the user to access this application will be through "hello".
Let's start by making our screen. From what we described, we will need to have one text element to display the "lovely day" message and one cursor element for the user to select. Since we don't have much complexity in the screen itself, we will just use the good old default "BoxedScreen"
IScreen screen = new BoxedScreen()
{
Title = "Hello World!", // Title is the text that is displayed in the box on top of the screen
elements =
[
new TextElement()
{
Text = "Hope you're having such a lovely day!"
}
]
}
Lovely! We now have a screen to display. But it currently doesn't have the prompt for our user to interact with. We will need to create a cursor menu!
CursorElement[] elements = new CursorElement[1]; // Since we will only have one user prompt to interact
elements[0] = new CursorElement()
{
Name = "I absolutely am!", // Text that will be highlighted when selected
Action = () => UnityEngine.Object.Destroy(InteractiveTerminalManager.Instance) // The action that happens when the user confirms the prompt
};
CursorMenu cursorMenu = new CursorMenu()
{
cursorIndex = 0, // Whatever prompt we want the cursor to be selecting when the screen appears, since we only have one, it will use that one
elements = elements // The collection of cursor elements we wish to have in this menu
};
After building the cursor menu, we shall now build our screen properly.
IScreen screen = new BoxedScreen()
{
Title = "Hello World!", // Title is the text that is displayed in the box on top of the screen
elements =
[
new TextElement()
{
Text = "Hope you're having such a lovely day!"
},
new TextElement() // This text element is here to give space between the text and the user prompt
{
Text = " "
},
cursorMenu
]
};
There, now our screen is properly built! Now we need to use it in an application!
For the simplicity of this example, we shall use InteractiveTerminalApplication
as the base class for our application
internal class ExampleApplication : InteractiveTerminalApplication
{
// ...
}
Once derived, it will ask us to implement the Initialization
method which is where we prepare our application to display the correct screens. This is where we shall insert the screen and cursor menu logic.
public override void Initialization()
{
CursorElement[] elements = new CursorElement[1]; // Since we will only have one user prompt to interact
elements[0] = new CursorElement()
{
Name = "I absolutely am!", // Text that will be highlighted when selected
Action = () => UnityEngine.Object.Destroy(InteractiveTerminalManager.Instance) // The action that happens when the user confirms the prompt
};
CursorMenu cursorMenu = new CursorMenu()
{
cursorIndex = 0, // Whatever prompt we want the cursor to be selecting when the screen appears, since we only have one, it will use that one
elements = elements // The collection of cursor elements we wish to have in this menu
};
IScreen screen = new BoxedScreen()
{
Title = "Hello World!", // Title is the text that is displayed in the box on top of the screen
elements =
[
new TextElement()
{
Text = "Hope you're having such a lovely day!"
},
new TextElement() // This text element is here to give space between the text and the user prompt
{
Text = " "
},
cursorMenu
]
};
currentCursorMenu = cursorMenu; // To tell the application which cursor menu it should start using
currentScreen = screen; // To tell the application which screen to display
}
After creating our application, we will just need to register it to the API with the specified keyword for the application to appear.
InteractiveTerminalManager.RegisterApplication<ExampleApplication>("hello", caseSensitive: true); // If we wanted to accept cases like "HELLO" as input for the application prompt, caseSensitive would have to be false.
And after booting up the plugin with this application class and registration of said class, we will be able to access the application by typing "hello" in the terminal which will show the following result:
Hope this example helped understand better the basics of the applications provided to you to create your own. :)
Sometimes, our intended application may grow to have too many prompts shown to the user, leading to some difficulty reading the information in one screen.
So we would like split these up through different screens where the user can just switch between to show the ideal amount of entries per each screen.
This is where PageApplication
is most ideal.
The difference here is that PageApplication
has a couple of helper functions which helps us construct our screens according to our needs (if we want x pages total, if we want y entries per page). We will just need to override them for the application to satisfy our needs.
We will have to change a bit how we construct our cursor menus and screens as well as we will need to have an array with the desired prompts we want to show to the user.
So let's get started by making our array! Since all entries show the same prompt, we will just make a string array for our example with the same on all entries.
string[] texts = new string[100]; // It doesn't have to be an array of string type, it can be any other type
for(int i = 0; i < texts.Length; i++)
{
texts[i] = "I absolutely am!";
}
Now, let's start dividing these entries through our pages by calling PageApplication.GetPageEntries<T>(T[] entries)
.
This will return a tuple which contains:
- Our list of strings split between screens/pages;
- List of cursor menus dedicated to each screen;
- List of screens which are considered the pages;
(string[][], CursorMenu[], IScreen[]) entries = GetPageEntries(texts);
string[][] pagesTexts = entries.Item1;
CursorMenu[] cursorMenus = entries.Item2;
IScreen[] screens = entries.Item3;
So now, we will iterate through our elements that were split between screens and start building their corresponding screen and cursor menu like we were building a simple screen.
for(int i = 0; i < pagesTexts.Length;i++)
{
// This code is essentialy the same as the previous example, only difference being is that it manipulates a collection to construct our entries
CursorElement[] elements = new CursorElement[pagesTexts[i].Length];
for(int j = 0; j < elements.Length; j++)
{
if (pagesTexts[i][j] == null) continue; // It's normal to have null entries when we change our distribution
elements[j] = new CursorElement()
{
Name = pagesTexts[i][j],
Action = () => UnityEngine.Object.Destroy(InteractiveTerminalManager.Instance)
};
}
cursorMenus[i] = new CursorMenu()
{
cursorIndex = 0, // Whatever prompt we want the cursor to be selecting when the screen appears, since we only have one, it will use that one
elements = elements // The collection of cursor elements we wish to have in this menu
};
CursorMenu cursorMenu = cursorMenus[i];
screens[i] = new BoxedScreen()
{
Title = "Hello World!", // Title is the text that is displayed in the box on top of the screen
elements =
[
new TextElement()
{
Text = "Hope you're having such a lovely day!"
},
new TextElement() // This text element is here to give space between the text and the user prompt
{
Text = " "
},
cursorMenu
]
};
}
After building our screens, we will just need to update our current variables for the application to show the screens correctly.
currentPage = initialPage; // initialPage was initialized by ``GetPageEntries`` call
currentCursorMenu = initialPage.GetCurrentCursorMenu(); // To tell the application which cursor menu it should start using
currentScreen = initialPage.GetCurrentScreen(); // To tell the application which screen to display
Now let's test our boy out..
It's still too big! Maybe the default amount of entries and pages won't be enough to put all 100 entries into readable screens. Let's change that then!
protected override int GetEntriesPerPage<T>(T[] entries)
{
// 12 entries per page sounds like a reasonable amount to not make our screen too big
return 12;
}
Success! We have made our application be split between different pages and now the users will not have screens be too big in our application. :D