Skip to content

Commit

Permalink
Added Unity plugin.
Browse files Browse the repository at this point in the history
  • Loading branch information
WhistleWiz committed Apr 29, 2024
1 parent 8209400 commit 4734bbe
Show file tree
Hide file tree
Showing 8 changed files with 298 additions and 5 deletions.
1 change: 0 additions & 1 deletion CL.Common/Constants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ public static class Constants
public const string LangHelper = "DVLangHelper";
public const string MainModId = "DVCustomLicenses";
public const string ModIdPrefix = "CL_";
public const string CCL = "DVCustomCarLoader";

// Localization.
public const string LocalizeRoot = "customlicenses";
Expand Down
24 changes: 20 additions & 4 deletions CL.Common/CustomLicense.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using DVLangHelper.Data;
using Newtonsoft.Json;
using System;
using UnityEngine;

Expand All @@ -9,16 +8,18 @@ namespace CL.Common
public class CustomLicense
{
[Header("License properties")]
[Tooltip("Wether this is a general license (locomotives, concurrent jobs, etc) or a job license (hazmat, train length, etc)")]
[Tooltip("Whether this is a general license (locomotives, concurrent jobs, etc) or a job license (hazmat, train length, etc)")]
public LicenseType LicenseType = LicenseType.General;
[Tooltip("The name (id) of the license")]
public string Identifier = "CL_LicenseId";

public Colour Color = new Colour(0, 0, 1, 1);
public Colour Color = Colour.FromUnity(new Color32(43, 166, 166, byte.MaxValue));
public float Price = 10000;
[Tooltip("How much copay should increase after buying this license")]
public float InsuranceFeeQuotaIncrease;
[Tooltip("How much bonus time should decrease after buying this license")]
[Tooltip("How much bonus time should decrease after buying this license\n" +
"1% is written as 0.01\n" +
"Negative values will give more bonus time instead")]
public float BonusTimeDecreasePercentage;

[Header("Requirements (Optional)")]
Expand All @@ -31,9 +32,13 @@ public class CustomLicense
public FreeRoamAvailability Availability = FreeRoamAvailability.OnlyIfUnlockedInCareer;

[Header("Localization")]
[Tooltip("The name of the license (DE2, S282, Hazmat 2)")]
public TranslationData? TranslationName;
[Tooltip("The description of the license")]
public TranslationData? TranslationDescription;
[Tooltip("The name of the inventory item for the license")]
public TranslationData? TranslationItem;
[Tooltip("The name of the inventory item for the sample version of the license")]
public TranslationData? TranslationInfoItem;

public string LocalizationKey => $"{Constants.LocalizeRoot}/{Identifier.Replace(" ", "_").ToLowerInvariant()}";
Expand All @@ -42,6 +47,7 @@ public class CustomLicense
public string LocalizationKeyInfoItem => $"{LocalizationKey}_sample_item";

// Wrapper class to avoid serialization issues.
[Serializable]
public class Colour
{
public float R, G, B, A;
Expand All @@ -60,6 +66,16 @@ public Color ToUnity()
{
return new Color(R, G, B, A);
}

public static Color ToUnity(Colour c)
{
return c.ToUnity();
}

public static Colour FromUnity(Color color)
{
return new Colour(color.r, color.g, color.b, color.a);
}
}
}
}
9 changes: 9 additions & 0 deletions CL.Game/LicenseManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -80,17 +80,26 @@ public static void LoadLicenses(UnityModManager.ModEntry mod)
}
}

bool flag = false;

// If we did load any licenses...
if (newGeneralLicenses.Count > 0)
{
CLMod.Log($"Loaded {newGeneralLicenses.Count} general licenses from {mod.Path}");
CLMod.Log(string.Join(", ", newGeneralLicenses.Select(x => x.id)));
flag = true;
}

if (newJobLicenses.Count > 0)
{
CLMod.Log($"Loaded {newJobLicenses.Count} job licenses from {mod.Path}");
CLMod.Log(string.Join(", ", newJobLicenses.Select(x => x.id)));
flag = true;
}

if (flag)
{
Globals.G.Types.RecalculateCaches();
}
}

Expand Down
23 changes: 23 additions & 0 deletions CL.Unity/CL.Unity.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<AssemblyName>$(MSBuildProjectName)</AssemblyName>
<TargetFramework>netframework4.8</TargetFramework>
<Nullable>enable</Nullable>
<LangVersion>8</LangVersion>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\CL.Common\CL.Common.csproj" />
</ItemGroup>

<ItemGroup>
<Reference Include="System.IO.Compression" />
<Reference Include="UnityEngine" />
<Reference Include="UnityEngine.AssetBundleModule" />
<Reference Include="UnityEngine.CoreModule" />
<Reference Include="UnityEngine.IMGUIModule" />
<Reference Include="UnityEngine.PhysicsModule" />
<Reference Include="UnityEditor" />
<Reference Include="DVLangHelper.Data" />
<Reference Include="DVLangHelper.Runtime" />
</ItemGroup>
</Project>
36 changes: 36 additions & 0 deletions CL.Unity/CustomLicenseContainer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
using CL.Common;
using Newtonsoft.Json;
using System.IO;
using UnityEditor;
using UnityEngine;

namespace CL.Unity
{
[CreateAssetMenu(menuName = "DVCustomLicenses/Custom License")]
internal class CustomLicenseContainer : ScriptableObject
{
public CustomLicense License = new CustomLicense();

public string GetFullPath()
{
string path = Application.dataPath;
string assetPath = AssetDatabase.GetAssetPath(this);
path = path + "/" + assetPath.Substring(7);
return Path.GetDirectoryName(path);
}

public void Export()
{
// Use a JsonSerializer for a cleaner output.
JsonSerializer serializer = new JsonSerializer { Formatting = Formatting.Indented };
var path = $"{GetFullPath()}\\license.json";

using var file = File.CreateText(path);
using var jsonWr = new JsonTextWriter(file);
serializer.Serialize(jsonWr, License);

EditorUtility.RevealInFinder(path);
AssetDatabase.Refresh();
}
}
}
35 changes: 35 additions & 0 deletions CL.Unity/Inspector/ColourDrawer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
using UnityEditor;
using UnityEngine;

using static CL.Common.CustomLicense;

namespace CL.Unity.Inspector
{
[CustomPropertyDrawer(typeof(Colour))]
internal class ColourDrawer : PropertyDrawer
{
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
var r = property.FindPropertyRelative(nameof(Colour.R));
var g = property.FindPropertyRelative(nameof(Colour.G));
var b = property.FindPropertyRelative(nameof(Colour.B));
var a = property.FindPropertyRelative(nameof(Colour.A));

EditorGUI.BeginProperty(position, label, property);

var result = EditorGUI.ColorField(position, label, new Color(r.floatValue, g.floatValue, b.floatValue, a.floatValue));

r.floatValue = result.r;
g.floatValue = result.g;
b.floatValue = result.b;
a.floatValue = result.a;

EditorGUI.EndProperty();
}

public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
{
return EditorGUIUtility.singleLineHeight;
}
}
}
166 changes: 166 additions & 0 deletions CL.Unity/Inspector/CustomLicenseContainerEditor.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
using CL.Common;
using DVLangHelper.Data;
using System.Collections.Generic;
using System.Linq;
using UnityEditor;
using UnityEngine;

using static CL.Common.CustomLicense;

namespace CL.Unity.Inspector
{
[CustomEditor(typeof(CustomLicenseContainer))]
internal class CustomLicenseContainerEditor : Editor
{
private static Dictionary<LicenseColour, Color32> LicenseToColour = new Dictionary<LicenseColour, Color32>()
{
{ LicenseColour.Generic, new Color32( 43, 166, 166, byte.MaxValue) },
{ LicenseColour.Locomotive, new Color32( 83, 83, 83, byte.MaxValue) },
{ LicenseColour.Concurrent, new Color32(115, 86, 146, byte.MaxValue) },
{ LicenseColour.Hazmat, new Color32(166, 43, 43, byte.MaxValue) },
{ LicenseColour.Military, new Color32(126, 152, 95, byte.MaxValue) },
{ LicenseColour.Length, new Color32(146, 98, 59, byte.MaxValue) }
};

private CustomLicenseContainer _container = null!;
private SerializedProperty _license = null!;
private LicenseColour _selectedColour;
private FillType _selectedFill;

private void OnEnable()
{
_license = serializedObject.FindProperty(nameof(CustomLicenseContainer.License));
}

public override void OnInspectorGUI()
{
var current = _license.FindPropertyRelative(nameof(CustomLicense.LicenseType));

do
{
EditorGUILayout.PropertyField(current);
} while (current.Next(false));

_container = (CustomLicenseContainer)target;
bool dirty = false;

EditorGUILayout.Space();

using (new EditorGUILayout.HorizontalScope())
{
_selectedColour = (LicenseColour)EditorGUILayout.EnumPopup(_selectedColour);

if (GUILayout.Button(new GUIContent("Set colour",
"Sets the colour to one of the base game colours"),
GUILayout.Width(EditorGUIUtility.currentViewWidth * 0.45f)))
{
_container.License.Color = Colour.FromUnity(LicenseToColour[_selectedColour]);
dirty = true;
}
}

using (new EditorGUILayout.HorizontalScope())
{
_selectedFill = (FillType)EditorGUILayout.EnumPopup(_selectedFill);

if (GUILayout.Button(new GUIContent("Autofill",
"Auto fills english translations based on the name and type\n" +
"Will not replace already written text"),
GUILayout.Width(EditorGUIUtility.currentViewWidth * 0.45f)))
{
Autofill(_container.License, _selectedFill);
dirty = true;
}
}

if (dirty)
{
EditorUtility.SetDirty(target);
AssetDatabase.SaveAssets();
serializedObject.Update();
}

if (GUILayout.Button("Export"))
{
_container.Export();
}
}

private static void Autofill(CustomLicense license, FillType fillType)
{
var translation = license.TranslationName!.Items.Where(x => x.Language == DVLanguage.English).FirstOrDefault();

if (translation == null || string.IsNullOrEmpty(translation.Value))
{
Debug.LogWarning("No english name has been assigned to the license, cannot autofill!");
return;
}

var name = translation.Value;

// Item name.
var itemName = license.TranslationItem!.Items.Where(x => x.Language == DVLanguage.English).FirstOrDefault();
itemName ??= new TranslationItem(DVLanguage.English, string.Empty);

if (string.IsNullOrEmpty(itemName.Value))
{
itemName.Value = $"License {name}";
}

// Info item name.
var infoItemName = license.TranslationInfoItem!.Items.Where(x => x.Language == DVLanguage.English).FirstOrDefault();
infoItemName ??= new TranslationItem(DVLanguage.English, string.Empty);

if (string.IsNullOrEmpty(infoItemName.Value))
{
infoItemName.Value = $"License {name} Info";
}

// Description.
var description = license.TranslationDescription!.Items.Where(x => x.Language == DVLanguage.English).FirstOrDefault();
description ??= new TranslationItem(DVLanguage.English, string.Empty);

if (string.IsNullOrEmpty(description.Value))
{
description.Value = fillType switch
{
FillType.SteamLocomotive => "This license grants you access to all the [WHYTE WHEEL ARRANGEMENT] steam-powered locomotives in Derail Valley. " +
"Use them responsibly! Refer to your vehicle catalog for detailed specifications.",
FillType.DELocomotive => "This license grants you access to all the [# AXLES]-axle diesel-electric locomotives in Derail Valley. " +
"Use them responsibly! Refer to your vehicle catalog for detailed specifications.",
FillType.DHLocomotive => "This license grants you access to all the [# AXLES]-axle diesel-hydraulic locomotives in Derail Valley. " +
"Use them responsibly! Refer to your vehicle catalog for detailed specifications.",
FillType.DMLocomotive => "This license grants you access to all the [# AXLES]-axle diesel-mechanical locomotives in Derail Valley. " +
"Use them responsibly! Refer to your vehicle catalog for detailed specifications.",
FillType.JobType => $"This license grants you access to all orders of the {name} type. This order type involves [DESCRIPTION].",
_ => string.Empty
};

if (!string.IsNullOrEmpty(description.Value))
{
Debug.Log("Please fill out the fields marked [LIKE THIS] in the description of the license!");
}
}
}

private enum LicenseColour
{
Generic,
Locomotive,
Concurrent,
Hazmat,
Military,
Length
}

private enum FillType
{
NoDescription,
SteamLocomotive,
DELocomotive,
DHLocomotive,
DMLocomotive,
JobType
}
}
}
9 changes: 9 additions & 0 deletions DVCustomLicenses.sln
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CL.Common", "CL.Common\CL.C
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CL.Game", "CL.Game\CL.Game.csproj", "{2FEE4E2B-F031-483E-AC16-7A8F3527E3B1}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CL.Unity", "CL.Unity\CL.Unity.csproj", "{77595CE5-DE0C-4EE5-BBE4-2F6B716CF9D3}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand All @@ -21,8 +23,15 @@ Global
{2FEE4E2B-F031-483E-AC16-7A8F3527E3B1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2FEE4E2B-F031-483E-AC16-7A8F3527E3B1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2FEE4E2B-F031-483E-AC16-7A8F3527E3B1}.Release|Any CPU.Build.0 = Release|Any CPU
{77595CE5-DE0C-4EE5-BBE4-2F6B716CF9D3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{77595CE5-DE0C-4EE5-BBE4-2F6B716CF9D3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{77595CE5-DE0C-4EE5-BBE4-2F6B716CF9D3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{77595CE5-DE0C-4EE5-BBE4-2F6B716CF9D3}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {AC27D2F1-A8E1-4B99-84DE-2EC15E5C05CF}
EndGlobalSection
EndGlobal

0 comments on commit 4734bbe

Please sign in to comment.