Modding Code Examples

From Worldbox Wiki
Revision as of 01:47, 5 September 2024 by imported>AvoidBored
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

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 :

<syntaxhighlight lang="csharp" line="1"> 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"; </syntaxhighlight>

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

<syntaxhighlight lang="csharp" line="1"> 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);

} </syntaxhighlight>

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:

<syntaxhighlight lang="csharp" line="1"> Toolbox.LoadSprite(Directory.GetCurrentDirectory() + "\\WorldBox_Data//images//filename.png", 30, 30, 0.5f, 0f); </syntaxhighlight>

How to add sprites to a window

File:CustomSprites.png


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

<syntaxhighlight lang="csharp" line="1"> 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

} </syntaxhighlight>

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

<syntaxhighlight lang="csharp" line="1"> 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)); </syntaxhighlight>

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

<syntaxhighlight lang="csharp" line="1"> 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));
   }

} </syntaxhighlight>

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