#
Example Mod
This is the Example Mod. It should be auto-installed with NCMS
.
There is one new button:
- Any Tile To Draw button, which shows window where you can select any tile presented in game and draw with it
using System;
using NCMS;
using UnityEngine;
using ReflectionUtility;
namespace ExampleMod{
[ModEntry]
class Main : MonoBehaviour{
void Awake(){
// Initializing Tiles Window
TilesWindow.init();
// Initializing Tiles Button
TilesPowerButton.init();
}
}
}
using System;
using NCMS.Utils;
using UnityEngine;
using ReflectionUtility;
namespace ExampleMod{
class TilesPowerButton{
// Defining power and button as internal static, because we will use it in TilesWindow class
internal static GodPower power;
internal static PowerButton button;
// Initializing Tiles Button
public static void init(){
// Creating new drawing god's power by cloning prepared _terraformTiles power.
power = AssetManager.powers.clone("anyTile", "_terraformTiles");
power.name = "anyTile";
// Setting deep_ocean as default tile type
power.tileType = "deep_ocean";
// creating new PowerButton
button = PowerButtons.CreateButton(
// should be the same as power.id
"anyTile",
// using ingame sprite for our new button
Resources.Load<Sprite>("ui/icons/icontilesoil"),
"Select Tile To Draw",
"Select any tile which represents in game and draw with it",
Vector2.zero,
// Type of our power: GodPower.
ButtonType.GodPower,
/*
This button shows window, so basicaly it should be ButtonType.Click.
But it will be also power, so we need to make it with ButtonType.GodPower
Even if it will be ButtonType.GodPower, we still be able to set on click action
*/
null,
// On click action
OpenWindow
);
// Adding our button to the tab
PowerButtons.AddButtonToTab(
button,
// Drawings tab
PowerTab.Drawing,
// Position of button in this tab. 511.2f by x, 18 by y means this button will be on first row.
new Vector2(511.2f, 18));
}
private static void OpenWindow()
{
if (MapBox.instance.isSelectedPower("anyTile"))
{
// Showing tilesWindow window
Windows.ShowWindow("tilesWindow");
}
else
{
TilesWindow.pbsInstance.unselectAll();
}
}
}
}
using System;
using NCMS.Utils;
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using System.Reflection;
using ReflectionUtility;
namespace ExampleMod
{
class TilesWindow
{
private static ScrollWindow window;
private static GameObject content;
// Defining as internal static, because we using it in TilesPowerButton class
internal static PowerButtonSelector pbsInstance;
// Initializing Tiles Window
public static void init()
{
// Creating new window
window = Windows.CreateNewWindow("tilesWindow", "Select Tile");
// Activating Scroll View object
var scrollView = GameObject.Find($"/Canvas Container Main/Canvas - Windows/windows/{window.name}/Background/Scroll View");
scrollView.gameObject.SetActive(true);
// Fixing size to fit
var viewport = GameObject.Find($"/Canvas Container Main/Canvas - Windows/windows/{window.name}/Background/Scroll View/Viewport");
var viewportRect = viewport.GetComponent<RectTransform>();
viewportRect.sizeDelta = new Vector2(0, 17);
// Getting Content object
content = GameObject.Find($"/Canvas Container Main/Canvas - Windows/windows/{window.name}/Background/Scroll View/Viewport/Content");
// Getting power button selector using reflections with ReflectionUtility
pbsInstance = Reflection.GetField(typeof(PowerButtonSelector), null, "instance") as PowerButtonSelector;
initTiles(); // Initializing tiles buttons inside window
}
private static void initTiles()
{
// Getting tiles sprites from game resources
var sprites = Resources.LoadAll($"tilemap/tiles", typeof(Sprite)).Cast<Sprite>().ToList();
//tilesDictBoth.AddRange(AssetManager.tiles.list);
//tilesListBoth.AddRange(AssetManager.topTiles.list);
// Preparing list of valid sprites
var preparedTiles = new List<Sprite>();
foreach (var pair in AssetManager.tiles.dict)
{
//var sprite = sprites.Find(c => c.name == $"{pair.Key}_0");
var sprite = Resources.Load<Sprite>($"tiles/{pair.Key}/tile_0");
if (sprite == null)
{
continue;
}
preparedTiles.Add(sprite);
}
foreach (var pair in AssetManager.topTiles.dict)
{
//var sprite = sprites.Find(c => c.name == $"{pair.Key}_0");
var sprite = Resources.Load<Sprite>($"tiles/{pair.Key}/tile_0");
if (sprite == null)
{
continue;
}
preparedTiles.Add(sprite);
}
// To make our window content scrollable, we need to change its RectTransform.sizeDelta
var rect = content.GetComponent<RectTransform>();
rect.pivot = new Vector2(0, 1);
rect.sizeDelta = new Vector2(0, Mathf.Abs(getPositionByIndex(preparedTiles.Count).y) + 40);
// Adding tile buttons to window
int i = 0;
foreach (var pair in AssetManager.tiles.dict)
{
//var sprite = preparedTiles.Find(c => c.name == $"{pair.Key}_0");
var sprite = Resources.Load<Sprite>($"tiles/{pair.Key}/tile_0");
if (sprite == null)
{
continue;
}
createTileButton(pair.Key, "tileType", sprite, i); // Creating tile button
i++;
}
foreach (var pair in AssetManager.topTiles.dict)
{
//var sprite = preparedTiles.Find(c => c.name == $"{pair.Key}_0");
var sprite = Resources.Load<Sprite>($"tiles/{pair.Key}/tile_0");
if (sprite == null)
{
continue;
}
createTileButton(pair.Value.id, "topTileType", sprite, i); // Creating tile button
i++;
}
}
private static void createTileButton(string tileName, string tileTypeType, Sprite sprite, int index)
{
// Making all first char in each string upper
string name = String.Join(" ", tileName.Split('_').ToList().Select(c => { c = $"{c[0].ToString().ToUpper()}{c.Substring(1)}"; return c; }).ToList());
// Creating new button
var button = PowerButtons.CreateButton(
tileName,
sprite,
name,
"",
// Getting button position by its index
getPositionByIndex(index),
ButtonType.Click,
content.transform,
// Setting on click callback with parameter
() => tileButtonClick(tileName, tileTypeType)
);
}
/*
Getting button position by its index
By this formules we dont need any additional if-else constructions.
*/
private static Vector2 getPositionByIndex(int index)
{
// Starting position by x
float startX = 50;
// Starting position by y
float startY = -20;
// Buttons size + gap between
float sizeWithGap = 40;
// Buttons per row
int buttonsPerRow = 5;
// Calculating points
float positionX = startX + (index * sizeWithGap) - ((Mathf.Floor(index / buttonsPerRow) * sizeWithGap) * buttonsPerRow);
float positionY = startY - (Mathf.Floor(index / buttonsPerRow) * sizeWithGap);
return new Vector2(positionX, positionY);
}
// On click callback with parameter
private static void tileButtonClick(string tileName, string tileTypeType)
{
// Setting new tile type
if (tileTypeType == "topTileType")
{
TilesPowerButton.power.tileType = String.Empty;
TilesPowerButton.power.topTileType = tileName;
TilesPowerButton.power.cached_tile_type_asset = null;
TilesPowerButton.power.cached_top_tile_type_asset = AssetManager.topTiles.get(TilesPowerButton.power.topTileType);
if (tileName.Contains("high"))
{
TilesPowerButton.power.tileType = "soil_low";
TilesPowerButton.power.cached_tile_type_asset = AssetManager.tiles.get(TilesPowerButton.power.tileType);
}
else if (tileName.Contains("low"))
{
TilesPowerButton.power.tileType = "soil_high";
TilesPowerButton.power.cached_tile_type_asset = AssetManager.tiles.get(TilesPowerButton.power.tileType);
}
}
else
{
TilesPowerButton.power.tileType = tileName;
TilesPowerButton.power.topTileType = String.Empty;
TilesPowerButton.power.cached_tile_type_asset = AssetManager.tiles.get(TilesPowerButton.power.tileType);
TilesPowerButton.power.cached_top_tile_type_asset = null;
}
// Setting actions for power in our button
//TilesPowerButton.power.click_action = null;
TilesPowerButton.power.click_action = new PowerActionWithID((WorldTile pTile, string pPower) => { return (bool)AssetManager.powers.CallMethod("drawTiles", pTile, pPower); });
TilesPowerButton.power.click_action += new PowerActionWithID((WorldTile pTile, string pPower) => { return (bool)AssetManager.powers.CallMethod("cleanBurnedTile", pTile, pPower); });
TilesPowerButton.power.click_action += new PowerActionWithID((WorldTile pTile, string pPower) => { return (bool)AssetManager.powers.CallMethod("stopFire", pTile, pPower); });
TilesPowerButton.power.click_action += new PowerActionWithID((WorldTile pTile, string pPower) => { return (bool)AssetManager.powers.CallMethod("destroyBuildings", pTile, pPower); });
TilesPowerButton.power.click_brush_action = new PowerActionWithID((WorldTile pTile, string pPower) => { return (bool)AssetManager.powers.CallMethod("loopWithCurrentBrush", pTile, pPower); });
//Setting cached_tile_type_asset
//AssetManager.powers.checkCache();
// When tile button clicked, hidding current window
window.clickHide();
// Activating power
pbsInstance.clickPowerButton(TilesPowerButton.button);
}
}
}
Result: