Advertisement
Guest User

BallisticNG - Shield Customizer

a guest
Aug 18th, 2017
195
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 8.32 KB | None | 0 0
  1. using BallisticNG.Gamemodes;
  2. using BallisticNG.RaceUI;
  3. using Battlehub.Utils;
  4. using GameData;
  5. using GameData.Constants;
  6. using UnityEngine.SceneManagement;
  7. using Settings;
  8. using UnityEngine;
  9. using System.Collections;
  10. using System.Linq;
  11. using System.IO;
  12.  
  13. using BallisticSource.Mods;
  14.  
  15. namespace BallisticNG.ShieldCustomizer
  16. {
  17.     /* This is a simple example mod which allows you to customize the visual appearance of ingame shields.
  18.      everything has been commented for educational purposes.*/
  19.     public class ShieldCustomizerRegister : ModRegister
  20.     {
  21.         public override void OnRegistered()
  22.         {
  23.             GameObject customShield = new GameObject("[ Custom Shield ]");
  24.             customShield.AddComponent<CustomShield>();
  25.             Object.DontDestroyOnLoad(customShield);
  26.         }
  27.     }
  28.  
  29.     public class CustomShield : MonoBehaviour
  30.     {
  31.         /*---Variables---*/
  32.         public bool ModEnabled = true;
  33.         public bool UseTeamColor = false;
  34.         public bool UseHorizontalUvs = false;
  35.         public Color CustomShieldColor = new Color(1.0f, 0.5f, 0.0f, 1.0f);
  36.  
  37.         private void Start()
  38.         {
  39.             // load the settings to create the empty ini if this mod is running for the first time
  40.             LoadSettings();
  41.  
  42.             // register the scene loaded delegate so we can perform operations whenever a scene is loaded
  43.             SceneManager.sceneLoaded += OnSceneLoaded;
  44.         }
  45.  
  46.         private void OnSceneLoaded(Scene scene, LoadSceneMode loadMode)
  47.         {
  48.             // if there isn't a race manager then the loaded scene isn't a track
  49.             if (!FindObjectOfType<RaceManager>()) return;
  50.  
  51.             // if the mod is disabled then do nothing
  52.             if (!ModEnabled) return;
  53.  
  54.             LoadSettings();
  55.             StartCoroutine(SetupShields());
  56.         }
  57.  
  58.         private IEnumerator SetupShields()
  59.         {
  60.             // wait a frame so the ships can be spawned
  61.             yield return new WaitForEndOfFrame();
  62.  
  63.             // iterate through each ship and apply the changes we want
  64.             for (int i = 0; i < Ships.LoadedShips.Count; ++i)
  65.             {
  66.                 ShipRefs r = Ships.LoadedShips[i];
  67.  
  68.                 // apply color, this is the easy part
  69.                 r.Effects.TargetShieldColor = UseTeamColor ? r.Settings.REF_ENGINECOL_BRIGHT : CustomShieldColor;
  70.  
  71.                 // apply horizontal uvs, this is where it gets harder
  72.                 if (UseHorizontalUvs)
  73.                 {
  74.                     // to make life easier, we want to temporarily move the ship so we want to store the current position first
  75.                     Vector3 pos = r.T.position;
  76.                     Quaternion rot = r.T.rotation;
  77.  
  78.                     // now we can move it to a location where we can work on the verts
  79.                     r.T.position = new Vector3(0.0f, 100.0f, 0.0f);
  80.                     r.T.rotation = Quaternion.identity;
  81.  
  82.                     // first off grab the shield mesh
  83.                     MeshFilter mf = r.Settings.REF_SHIELD.GetComponent<MeshFilter>();
  84.                     Mesh m = mf.mesh;
  85.  
  86.                     // we need the verts and uvs to apply the changes we want
  87.                     Vector3[] verts = m.vertices;
  88.                     Vector2[] uvs = new Vector2[verts.Length];
  89.  
  90.                     // first we want to calculate the bounds for each vert in world space
  91.                     Vector3 minBounds = new Vector3(Mathf.Infinity, Mathf.Infinity, Mathf.Infinity), maxBounds = new Vector3(-Mathf.Infinity, -Mathf.Infinity, -Mathf.Infinity);
  92.                     Vector3[] worldVerts = new Vector3[verts.Length]; // we are going to need to transform the ship verts into world space - the default teams were rotated in Unity so this corrects that
  93.  
  94.                     Transform shipTransform = r.Settings.REF_MESH.transform; // small optimization, prevents GetComponent<Transform> on each local-world space transformation
  95.                     for (int j = 0; j < verts.Length; ++j)
  96.                     {
  97.                         worldVerts[j] = shipTransform.TransformPoint(verts[j]); // transform the current vert into world space
  98.  
  99.                         // what we're doing here is comparing the position of verts to what is initially an infinetly large position away from the ship and then increasing
  100.                         // the bounds until it reaches the furthest vert in each axis on the oposite side of the ship the min/max bounds start at
  101.                         // x bounds
  102.                         if (worldVerts[j].x > maxBounds.x) maxBounds.x = worldVerts[j].x;
  103.                         if (worldVerts[j].x < minBounds.x) minBounds.x = worldVerts[j].x;
  104.  
  105.                         // y bounds
  106.                         if (worldVerts[j].y > maxBounds.y) maxBounds.y = worldVerts[j].y;
  107.                         if (worldVerts[j].y < minBounds.y) minBounds.y = worldVerts[j].y;
  108.  
  109.                         // z bounds
  110.                         if (worldVerts[j].z > maxBounds.z) maxBounds.z = worldVerts[j].z;
  111.                         if (worldVerts[j].z < minBounds.z) minBounds.z = worldVerts[j].z;
  112.                     }
  113.  
  114.                     // now that we know the bounds we can normalize them and use them to generate the uvs
  115.                     for (int j = 0; j < verts.Length; ++j)
  116.                     {
  117.                         // normalize the bounds
  118.                         Vector3 boundsNorm = new Vector3
  119.                         (
  120.                             (worldVerts[j].x - Mathf.Abs(minBounds.x)) / (maxBounds.x - Mathf.Abs(minBounds.x)),
  121.                             (worldVerts[j].y - Mathf.Abs(minBounds.y)) / (maxBounds.y - Mathf.Abs(minBounds.y)),
  122.                             (worldVerts[j].z - Mathf.Abs(minBounds.z)) / (maxBounds.z - Mathf.Abs(minBounds.z))
  123.                         );
  124.  
  125.                         // create UV
  126.                         uvs[j] = new Vector2(0.0f, boundsNorm.z * 0.1f);
  127.                     }
  128.  
  129.                     // apply uvs back to mesh
  130.                     m.uv = uvs;
  131.  
  132.                     // finally, put the ship back to where it was originally
  133.                     r.T.position = pos;
  134.                     r.T.rotation = rot;
  135.                 }
  136.             }
  137.         }
  138.  
  139.         private void LoadSettings()
  140.         {
  141.             // make sure the target directory exists
  142.             string path = GameData.System.Directories.UserData + "ini/mods/";
  143.             if (!Directory.Exists(path)) Directory.CreateDirectory(path);
  144.             path += "shieldcustomizer.ini";
  145.  
  146.             // if the settings ini doesn't exist then create it
  147.             if (!File.Exists(path)) CreateSettings(path);
  148.  
  149.             // open a new ini parser
  150.             INIParser ini = new INIParser();
  151.             ini.Open(path);
  152.  
  153.             // load settings from the parser
  154.             ModEnabled = ini.ReadValue("Settings", "Mod Enabled", ModEnabled);
  155.             UseTeamColor = ini.ReadValue("Settings", "Use Team Color", UseTeamColor);
  156.             UseHorizontalUvs = ini.ReadValue("Settings", "Use Horizontal Uvs", UseHorizontalUvs);
  157.             CustomShieldColor.r = (float)ini.ReadValue("Settings", "Custom Shield Color R", CustomShieldColor.r);
  158.             CustomShieldColor.g = (float)ini.ReadValue("Settings", "Custom Shield Color G", CustomShieldColor.g);
  159.             CustomShieldColor.b = (float)ini.ReadValue("Settings", "Custom Shield Color B", CustomShieldColor.b);
  160.             CustomShieldColor.a = (float)ini.ReadValue("Settings", "Custom Shield Color A", CustomShieldColor.a);
  161.  
  162.             // close the ini parser
  163.             ini.Close();
  164.         }
  165.  
  166.         private void CreateSettings(string path)
  167.         {
  168.             INIParser ini = new INIParser();
  169.             ini.Open(path);
  170.  
  171.             ini.WriteValue("Settings", "Mod Enabled", ModEnabled);
  172.             ini.WriteValue("Settings", "Use Team Color", UseTeamColor);
  173.             ini.WriteValue("Settings", "Use Horizontal Uvs", UseHorizontalUvs);
  174.             ini.WriteValue("Settings", "Custom Shield Color R", CustomShieldColor.r);
  175.             ini.WriteValue("Settings", "Custom Shield Color G", CustomShieldColor.g);
  176.             ini.WriteValue("Settings", "Custom Shield Color B", CustomShieldColor.b);
  177.             ini.WriteValue("Settings", "Custom Shield Color A", CustomShieldColor.a);
  178.  
  179.             ini.Close();
  180.         }
  181.     }
  182. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement