Modding Code Examples

Some useful code snippets for Modders attempting to do common tasks.

## Adding a Custom Window

To add a custom window, you can create a custom class inspired by `WindowFavorites.cs`. Once you have your class ready, you can create a new window like so by copying the Favorites window and removing the attached WindowFavorites component, replacing it with your own.

Let's say we want to add a new window for religions :

```
var canvasWindows = GameObject.Find("/Canvas/CanvasWindows");
var favWindow = GameObject.Find("/Canvas/CanvasWindows/WindowFavorites");

// clone the favorite window
var religionWindow = Instantiate(favWindow);
religionWindow.gameObject.name = "WindowReligion";
// remove the WindowFavorites class/component from your new window
Destroy(religionWindow.gameObject.GetComponent<WindowFavorites>());
// attach your own WindowReligion class/component here
religionWindow.gameObject.AddComponent<WindowReligion>();
// set the screen\_id of the window, so you can open it from a button
religionWindow.gameObject.GetComponent<ScrollWindow>().screen\_id = "religion";
// add the window to the canvas windows group
religionWindow.gameObject.transform.parent = canvasWindows.transform;
// add the window id to the scrollwindows group, so you can open it from a button
ScrollWindow.allWindows.Add("religion", religionWindow.GetComponent<ScrollWindow>());

// change the window title
var religionTitle = GameObject.Find("/Canvas/CanvasWindows/WindowReligion/Background/Title");
Destroy(religionTitle.gameObject.GetComponent<LocalizedText>());
religionTitle.gameObject.GetComponent<Text>().text = "Religion";

```

Now you should be able to open this window from anywhere with `ScrollWindow.allWindows['religion'].clickShow();`

## How to load sprites from a picture file

To import and use your own pictures, you can use ToolBox.loadSprite to load directly and conveniently, or this version with options for resizing and repositioning

```
Sprite LoadSprite(string path, int resizeX, int resizeY, float offsetx, float offsety)
{
 if (string.IsNullOrEmpty(path)) return null;

 if (!File.Exists(path)) return null;

 byte[] data = File.ReadAllBytes(path);
 Texture2D texture2D = new Texture2D(1, 1);
 texture2D.anisoLevel = 0;
 texture2D.LoadImage(data);
 texture2D.filterMode = FilterMode.Point;
 TextureScale.Point(texture2D, resizeX, resizeY);
 return Sprite.Create(texture2D, new Rect(0f, 0f, (float)texture2D.width, (float)texture2D.height), new Vector2(offsetx, offsety), 1f);
}

```

After this you can load images using their file path. As an example, you could make a new folder in the game's "WorldBox\_Data" folder and name it images, put a picture into that folder and load it like this:

```
Toolbox.LoadSprite(Directory.GetCurrentDirectory() + "\\WorldBox\_Data//images//filename.png", 30, 30, 0.5f, 0f);

```

## How to add sprites to a window

To attach custom sprites to a window, we can do so by using the following helper method :

```
void addSprite(string SpritePath, Vector3 position) {
 var gameObject = new GameObject ();
 var rectTransform = gameObject.AddComponent<RectTransform>();
 gameObject.AddComponent<CanvasRenderer>(); // requirement for Image
 var imageRenderer = gameObject.AddComponent<Image>();
 var sprite = Resources.Load<Sprite> (SpritePath); // load the sprite
 imageRenderer.sprite = sprite;
 gameObject.transform.SetParent (transformContent); // attach to content window
 gameObject.transform.localScale = Vector3.one; // scale of the image reset to 1
 rectTransform.anchoredPosition3D = position; // pos based on content window
 rectTransform.sizeDelta = new Vector2(20, 20); // size of the image
}

```

And then you can add the 4 sprites from the example image like so :

```
addSprite("ui/Icons/iconDwarf", new Vector3( 0, -20, 0));
addSprite("ui/Icons/iconHumans", new Vector3( 80, -20, 0));
addSprite("ui/Icons/iconOrcs", new Vector3(-80, -20, 0));
addSprite("ui/Icons/iconElves", new Vector3( 0, -200, 0));

```

The positions in this case are based on the top/middle position ( pivot point is `0.5, 0` ). So `0,0` is basically right above the dwarf, just below the Favorites title. In the case of the orc, we want him in the far left corner - that's `-80` on the x axis. The Human in the far right corner is `80` on the x axis.
And finally to have the elf in the bottom area, we position him at `-200` on the y axis.

You could also play around by changing the pivot points of the container to e.g. `0,0`, and then all items would be added from the top left corner.

## How to group a list of objects into a circle

This example is for moving Actors into position

```
void moveFormationCircle(Vector3 centerPosition, List<Actor> formation, int radius)
{
 if (formation == null) return;

 float num = 6.28318548f / (float)formation.Count;
 for (int i = 0; i < formation.Count; i++)
 {
 float f = (float)i \* num;
 Vector3 newPosition = centerPosition + new Vector3(Mathf.Cos(f), 0f, Mathf.Sin(f)) \* (float)radius;
 formation[i].cancelEverything();
 formation[i].moveTo(MapBox.instance.GetTile((int)newPosition.x, (int)newPosition.y));
 }
}

```

In this, I use the circle to find tiles for the army to walk towards. Adapting this for another use should only require changing the type used in the list and a way to use the new positions