mirror of
https://github.com/All-Of-Us-Mods/MiraAPI.git
synced 2026-10-19 15:51:48 +00:00
namespace change xd
This commit is contained in:
1 parent
4f01facd7c
commit
730b22f7ce
35 files changed
+1180
-1208
No files matched your search
@@ -3,19 +3,18 @@ using MiraAPI.Roles;
|
||||
using MiraAPI.Utilities.Assets;
|
||||
using UnityEngine;
|
||||
|
||||
namespace MiraAPI.Example
|
||||
namespace MiraAPI.Example;
|
||||
|
||||
[RegisterCustomRole]
|
||||
public class CustomRole : ImpostorRole, ICustomRole
|
||||
{
|
||||
[RegisterCustomRole]
|
||||
public class CustomRole : ImpostorRole, ICustomRole
|
||||
{
|
||||
public string RoleName => "fortnite killer";
|
||||
public string RoleLongDescription => "ok so your objective is to eliminate everyone with your fortnite tactical shotgun, good luck";
|
||||
public string RoleDescription => RoleLongDescription;
|
||||
public Color RoleColor => Palette.Orange;
|
||||
public ModdedRoleTeams Team => ModdedRoleTeams.Impostor;
|
||||
public LoadableAsset<Sprite> OptionsScreenshot => MiraAssets.Banner;
|
||||
public string RoleName => "fortnite killer";
|
||||
public string RoleLongDescription => "ok so your objective is to eliminate everyone with your fortnite tactical shotgun, good luck";
|
||||
public string RoleDescription => RoleLongDescription;
|
||||
public Color RoleColor => Palette.Orange;
|
||||
public ModdedRoleTeams Team => ModdedRoleTeams.Impostor;
|
||||
public LoadableAsset<Sprite> OptionsScreenshot => MiraAssets.Banner;
|
||||
|
||||
[ModdedNumberOption("Testing level", min: 3, max: 9, roleType: typeof(CustomRole))] public float testingLevel { get; set; } = 4;
|
||||
[ModdedNumberOption("Testing level", min: 3, max: 9, roleType: typeof(CustomRole))] public float testingLevel { get; set; } = 4;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,19 +3,18 @@ using MiraAPI.Roles;
|
||||
using MiraAPI.Utilities.Assets;
|
||||
using UnityEngine;
|
||||
|
||||
namespace MiraAPI.Example
|
||||
namespace MiraAPI.Example;
|
||||
|
||||
[RegisterCustomRole]
|
||||
public class CustomRole2 : CrewmateRole, ICustomRole
|
||||
{
|
||||
[RegisterCustomRole]
|
||||
public class CustomRole2 : CrewmateRole, ICustomRole
|
||||
{
|
||||
public string RoleName => "fortnite defender";
|
||||
public string RoleLongDescription => "ok so your objective is to save everyone from the fortnite killer";
|
||||
public string RoleDescription => RoleLongDescription;
|
||||
public Color RoleColor => Palette.AcceptedGreen;
|
||||
public ModdedRoleTeams Team => ModdedRoleTeams.Crewmate;
|
||||
public LoadableAsset<Sprite> OptionsScreenshot => MiraAssets.Banner;
|
||||
public string RoleName => "fortnite defender";
|
||||
public string RoleLongDescription => "ok so your objective is to save everyone from the fortnite killer";
|
||||
public string RoleDescription => RoleLongDescription;
|
||||
public Color RoleColor => Palette.AcceptedGreen;
|
||||
public ModdedRoleTeams Team => ModdedRoleTeams.Crewmate;
|
||||
public LoadableAsset<Sprite> OptionsScreenshot => MiraAssets.Banner;
|
||||
|
||||
[ModdedToggleOption("Teleportation ability", roleType: typeof(CustomRole2))] public bool teleport { get; set; } = true;
|
||||
[ModdedToggleOption("Teleportation ability", roleType: typeof(CustomRole2))] public bool teleport { get; set; } = true;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,17 +2,16 @@
|
||||
using MiraAPI.Utilities.Assets;
|
||||
using UnityEngine;
|
||||
|
||||
namespace MiraAPI.Example
|
||||
{
|
||||
[RegisterCustomRole]
|
||||
public class CustomRole3 : CrewmateRole, ICustomRole
|
||||
{
|
||||
public string RoleName => "fortnite helper";
|
||||
public string RoleLongDescription => "ok so your objective is to help";
|
||||
public string RoleDescription => RoleLongDescription;
|
||||
public Color RoleColor => Palette.Brown;
|
||||
public ModdedRoleTeams Team => ModdedRoleTeams.Crewmate;
|
||||
public LoadableAsset<Sprite> OptionsScreenshot => MiraAssets.Banner;
|
||||
namespace MiraAPI.Example;
|
||||
|
||||
}
|
||||
}
|
||||
[RegisterCustomRole]
|
||||
public class CustomRole3 : CrewmateRole, ICustomRole
|
||||
{
|
||||
public string RoleName => "fortnite helper";
|
||||
public string RoleLongDescription => "ok so your objective is to help";
|
||||
public string RoleDescription => RoleLongDescription;
|
||||
public Color RoleColor => Palette.Brown;
|
||||
public ModdedRoleTeams Team => ModdedRoleTeams.Crewmate;
|
||||
public LoadableAsset<Sprite> OptionsScreenshot => MiraAssets.Banner;
|
||||
|
||||
}
|
||||
@@ -2,33 +2,32 @@
|
||||
using MiraAPI.GameOptions.Attributes;
|
||||
using UnityEngine;
|
||||
|
||||
namespace MiraAPI.Example
|
||||
namespace MiraAPI.Example;
|
||||
|
||||
public class ExampleOptions : IModdedOptionGroup
|
||||
{
|
||||
public class ExampleOptions : IModdedOptionGroup
|
||||
{
|
||||
public string GroupName => "General Group";
|
||||
public Color GroupColor => Color.red;
|
||||
public string GroupName => "General Group";
|
||||
public Color GroupColor => Color.red;
|
||||
|
||||
[ModdedToggleOption("Use Thing")]
|
||||
public bool useThing { get; set; } = false;
|
||||
[ModdedToggleOption("Use Thing")]
|
||||
public bool useThing { get; set; } = false;
|
||||
|
||||
[ModdedToggleOption("Use another thing")]
|
||||
public bool useAnotherThing { get; set; } = true;
|
||||
[ModdedToggleOption("Use another thing")]
|
||||
public bool useAnotherThing { get; set; } = true;
|
||||
|
||||
[ModdedNumberOption("Sussy level", min: 0, max: 10)]
|
||||
public float sussyLevel { get; set; } = 4f;
|
||||
[ModdedNumberOption("Sussy level", min: 0, max: 10)]
|
||||
public float sussyLevel { get; set; } = 4f;
|
||||
|
||||
[ModdedStringOption("Sus choices", ["hello", "hello 2", "hello 3"])]
|
||||
public int susChoices { get; set; } = 2;
|
||||
[ModdedStringOption("Sus choices", ["hello", "hello 2", "hello 3"])]
|
||||
public int susChoices { get; set; } = 2;
|
||||
|
||||
[ModdedEnumOption("Enum test", typeof(TestEnum))]
|
||||
public TestEnum enumTest { get; set; } = TestEnum.Bye;
|
||||
}
|
||||
|
||||
public enum TestEnum
|
||||
{
|
||||
Hello,
|
||||
Hi,
|
||||
Bye
|
||||
}
|
||||
[ModdedEnumOption("Enum test", typeof(TestEnum))]
|
||||
public TestEnum enumTest { get; set; } = TestEnum.Bye;
|
||||
}
|
||||
|
||||
public enum TestEnum
|
||||
{
|
||||
Hello,
|
||||
Hi,
|
||||
Bye
|
||||
}
|
||||
@@ -1,9 +1,8 @@
|
||||
namespace MiraAPI.Example
|
||||
{
|
||||
public class ModifierExample
|
||||
{
|
||||
//name, role specific, etc
|
||||
namespace MiraAPI.Example;
|
||||
|
||||
// mono behaviour stuff here (ModdedPlayerModifier inherits monobehaviour)
|
||||
}
|
||||
}
|
||||
public class ModifierExample
|
||||
{
|
||||
//name, role specific, etc
|
||||
|
||||
// mono behaviour stuff here (ModdedPlayerModifier inherits monobehaviour)
|
||||
}
|
||||
@@ -1,10 +1,9 @@
|
||||
using MiraAPI.GameOptions.Attributes;
|
||||
|
||||
namespace MiraAPI.Example
|
||||
namespace MiraAPI.Example;
|
||||
|
||||
public class SomeRandomNonGroupClass
|
||||
{
|
||||
public class SomeRandomNonGroupClass
|
||||
{
|
||||
[ModdedStringOption("Yeah, idk", ["Idk 1", "idk 2", "idk 3", "idk 4"])] public static int yeaIdk { get; set; } = 3;
|
||||
[ModdedNumberOption("Aw man", min: 45, max: 95)] public float sussyLevel { get; set; } = 63;
|
||||
}
|
||||
}
|
||||
[ModdedStringOption("Yeah, idk", ["Idk 1", "idk 2", "idk 3", "idk 4"])] public static int yeaIdk { get; set; } = 3;
|
||||
[ModdedNumberOption("Aw man", min: 45, max: 95)] public float sussyLevel { get; set; } = 63;
|
||||
}
|
||||
@@ -2,32 +2,31 @@
|
||||
using System;
|
||||
using System.Reflection;
|
||||
|
||||
namespace MiraAPI.GameOptions.Attributes
|
||||
namespace MiraAPI.GameOptions.Attributes;
|
||||
|
||||
public class ModdedEnumOptionAttribute : ModdedOptionAttribute
|
||||
{
|
||||
public class ModdedEnumOptionAttribute : ModdedOptionAttribute
|
||||
public Type EnumType;
|
||||
public ModdedEnumOptionAttribute(string title, Type enumType, Type roleType = null) : base(title, roleType)
|
||||
{
|
||||
public Type EnumType;
|
||||
public ModdedEnumOptionAttribute(string title, Type enumType, Type roleType = null) : base(title, roleType)
|
||||
{
|
||||
EnumType = enumType;
|
||||
}
|
||||
|
||||
public override IModdedOption CreateOption(object value, PropertyInfo property)
|
||||
{
|
||||
var opt = new ModdedEnumOption(Title, (int)value, EnumType, RoleType);
|
||||
return opt;
|
||||
}
|
||||
|
||||
public override void SetValue(object value)
|
||||
{
|
||||
ModdedEnumOption opt = HolderOption as ModdedEnumOption;
|
||||
opt.SetValue((int)value);
|
||||
}
|
||||
|
||||
public override object GetValue()
|
||||
{
|
||||
ModdedEnumOption opt = HolderOption as ModdedEnumOption;
|
||||
return Enum.ToObject(EnumType.GetType(), opt.Value);
|
||||
}
|
||||
EnumType = enumType;
|
||||
}
|
||||
}
|
||||
|
||||
public override IModdedOption CreateOption(object value, PropertyInfo property)
|
||||
{
|
||||
var opt = new ModdedEnumOption(Title, (int)value, EnumType, RoleType);
|
||||
return opt;
|
||||
}
|
||||
|
||||
public override void SetValue(object value)
|
||||
{
|
||||
ModdedEnumOption opt = HolderOption as ModdedEnumOption;
|
||||
opt.SetValue((int)value);
|
||||
}
|
||||
|
||||
public override object GetValue()
|
||||
{
|
||||
ModdedEnumOption opt = HolderOption as ModdedEnumOption;
|
||||
return Enum.ToObject(EnumType.GetType(), opt.Value);
|
||||
}
|
||||
}
|
||||
@@ -2,41 +2,40 @@
|
||||
using System;
|
||||
using System.Reflection;
|
||||
|
||||
namespace MiraAPI.GameOptions.Attributes
|
||||
namespace MiraAPI.GameOptions.Attributes;
|
||||
|
||||
public class ModdedNumberOptionAttribute : ModdedOptionAttribute
|
||||
{
|
||||
public class ModdedNumberOptionAttribute : ModdedOptionAttribute
|
||||
public float Min { get; private set; }
|
||||
public float Max { get; private set; }
|
||||
public float Increment { get; private set; }
|
||||
public NumberSuffixes SuffixType { get; private set; }
|
||||
public bool ZeroInfinity { get; private set; }
|
||||
|
||||
public ModdedNumberOptionAttribute(string title, float min, float max, float increment = 1, NumberSuffixes suffixType = NumberSuffixes.None, bool zeroInfinity = false, Type roleType = null) : base(title, roleType)
|
||||
{
|
||||
public float Min { get; private set; }
|
||||
public float Max { get; private set; }
|
||||
public float Increment { get; private set; }
|
||||
public NumberSuffixes SuffixType { get; private set; }
|
||||
public bool ZeroInfinity { get; private set; }
|
||||
|
||||
public ModdedNumberOptionAttribute(string title, float min, float max, float increment = 1, NumberSuffixes suffixType = NumberSuffixes.None, bool zeroInfinity = false, Type roleType = null) : base(title, roleType)
|
||||
{
|
||||
Min = min;
|
||||
Max = max;
|
||||
Increment = increment;
|
||||
SuffixType = suffixType;
|
||||
ZeroInfinity = zeroInfinity;
|
||||
}
|
||||
|
||||
public override IModdedOption CreateOption(object value, PropertyInfo property)
|
||||
{
|
||||
var toggleOpt = new ModdedNumberOption(Title, (float)value, Min, Max, Increment, SuffixType, ZeroInfinity, RoleType);
|
||||
return toggleOpt;
|
||||
}
|
||||
|
||||
public override void SetValue(object value)
|
||||
{
|
||||
ModdedNumberOption toggleOpt = HolderOption as ModdedNumberOption;
|
||||
toggleOpt.SetValue((float)value);
|
||||
}
|
||||
|
||||
public override object GetValue()
|
||||
{
|
||||
ModdedNumberOption toggleOpt = HolderOption as ModdedNumberOption;
|
||||
return toggleOpt.Value;
|
||||
}
|
||||
Min = min;
|
||||
Max = max;
|
||||
Increment = increment;
|
||||
SuffixType = suffixType;
|
||||
ZeroInfinity = zeroInfinity;
|
||||
}
|
||||
}
|
||||
|
||||
public override IModdedOption CreateOption(object value, PropertyInfo property)
|
||||
{
|
||||
var toggleOpt = new ModdedNumberOption(Title, (float)value, Min, Max, Increment, SuffixType, ZeroInfinity, RoleType);
|
||||
return toggleOpt;
|
||||
}
|
||||
|
||||
public override void SetValue(object value)
|
||||
{
|
||||
ModdedNumberOption toggleOpt = HolderOption as ModdedNumberOption;
|
||||
toggleOpt.SetValue((float)value);
|
||||
}
|
||||
|
||||
public override object GetValue()
|
||||
{
|
||||
ModdedNumberOption toggleOpt = HolderOption as ModdedNumberOption;
|
||||
return toggleOpt.Value;
|
||||
}
|
||||
}
|
||||
@@ -1,22 +1,21 @@
|
||||
using System;
|
||||
using System.Reflection;
|
||||
|
||||
namespace MiraAPI.GameOptions.Attributes
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Property)]
|
||||
public abstract class ModdedOptionAttribute : Attribute
|
||||
{
|
||||
public IModdedOption HolderOption { get; set; }
|
||||
public string Title { get; private set; }
|
||||
public Type RoleType { get; private set; }
|
||||
public ModdedOptionAttribute(string title, Type roleType = null)
|
||||
{
|
||||
Title = title;
|
||||
RoleType = roleType;
|
||||
}
|
||||
namespace MiraAPI.GameOptions.Attributes;
|
||||
|
||||
public abstract void SetValue(object val);
|
||||
public abstract object GetValue();
|
||||
public abstract IModdedOption CreateOption(object value, PropertyInfo property);
|
||||
[AttributeUsage(AttributeTargets.Property)]
|
||||
public abstract class ModdedOptionAttribute : Attribute
|
||||
{
|
||||
public IModdedOption HolderOption { get; set; }
|
||||
public string Title { get; private set; }
|
||||
public Type RoleType { get; private set; }
|
||||
public ModdedOptionAttribute(string title, Type roleType = null)
|
||||
{
|
||||
Title = title;
|
||||
RoleType = roleType;
|
||||
}
|
||||
}
|
||||
|
||||
public abstract void SetValue(object val);
|
||||
public abstract object GetValue();
|
||||
public abstract IModdedOption CreateOption(object value, PropertyInfo property);
|
||||
}
|
||||
@@ -2,32 +2,31 @@
|
||||
using System;
|
||||
using System.Reflection;
|
||||
|
||||
namespace MiraAPI.GameOptions.Attributes
|
||||
namespace MiraAPI.GameOptions.Attributes;
|
||||
|
||||
public class ModdedStringOptionAttribute : ModdedOptionAttribute
|
||||
{
|
||||
public class ModdedStringOptionAttribute : ModdedOptionAttribute
|
||||
public string[] Values;
|
||||
public ModdedStringOptionAttribute(string title, string[] strings, Type roleType = null) : base(title, roleType)
|
||||
{
|
||||
public string[] Values;
|
||||
public ModdedStringOptionAttribute(string title, string[] strings, Type roleType = null) : base(title, roleType)
|
||||
{
|
||||
Values = strings;
|
||||
}
|
||||
|
||||
public override IModdedOption CreateOption(object value, PropertyInfo property)
|
||||
{
|
||||
var opt = new ModdedStringOption(Title, (int)value, Values, RoleType);
|
||||
return opt;
|
||||
}
|
||||
|
||||
public override void SetValue(object value)
|
||||
{
|
||||
ModdedStringOption opt = HolderOption as ModdedStringOption;
|
||||
opt.SetValue((int)value);
|
||||
}
|
||||
|
||||
public override object GetValue()
|
||||
{
|
||||
ModdedStringOption opt = HolderOption as ModdedStringOption;
|
||||
return opt.Value;
|
||||
}
|
||||
Values = strings;
|
||||
}
|
||||
}
|
||||
|
||||
public override IModdedOption CreateOption(object value, PropertyInfo property)
|
||||
{
|
||||
var opt = new ModdedStringOption(Title, (int)value, Values, RoleType);
|
||||
return opt;
|
||||
}
|
||||
|
||||
public override void SetValue(object value)
|
||||
{
|
||||
ModdedStringOption opt = HolderOption as ModdedStringOption;
|
||||
opt.SetValue((int)value);
|
||||
}
|
||||
|
||||
public override object GetValue()
|
||||
{
|
||||
ModdedStringOption opt = HolderOption as ModdedStringOption;
|
||||
return opt.Value;
|
||||
}
|
||||
}
|
||||
@@ -2,30 +2,29 @@
|
||||
using System;
|
||||
using System.Reflection;
|
||||
|
||||
namespace MiraAPI.GameOptions.Attributes
|
||||
namespace MiraAPI.GameOptions.Attributes;
|
||||
|
||||
public class ModdedToggleOptionAttribute : ModdedOptionAttribute
|
||||
{
|
||||
public class ModdedToggleOptionAttribute : ModdedOptionAttribute
|
||||
public ModdedToggleOptionAttribute(string title, Type roleType = null) : base(title, roleType)
|
||||
{
|
||||
public ModdedToggleOptionAttribute(string title, Type roleType = null) : base(title, roleType)
|
||||
{
|
||||
}
|
||||
|
||||
public override IModdedOption CreateOption(object value, PropertyInfo property)
|
||||
{
|
||||
var toggleOpt = new ModdedToggleOption(Title, (bool)value, RoleType);
|
||||
return toggleOpt;
|
||||
}
|
||||
|
||||
public override void SetValue(object value)
|
||||
{
|
||||
ModdedToggleOption toggleOpt = HolderOption as ModdedToggleOption;
|
||||
toggleOpt.SetValue((bool)value);
|
||||
}
|
||||
|
||||
public override object GetValue()
|
||||
{
|
||||
ModdedToggleOption toggleOpt = HolderOption as ModdedToggleOption;
|
||||
return toggleOpt.Value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override IModdedOption CreateOption(object value, PropertyInfo property)
|
||||
{
|
||||
var toggleOpt = new ModdedToggleOption(Title, (bool)value, RoleType);
|
||||
return toggleOpt;
|
||||
}
|
||||
|
||||
public override void SetValue(object value)
|
||||
{
|
||||
ModdedToggleOption toggleOpt = HolderOption as ModdedToggleOption;
|
||||
toggleOpt.SetValue((bool)value);
|
||||
}
|
||||
|
||||
public override object GetValue()
|
||||
{
|
||||
ModdedToggleOption toggleOpt = HolderOption as ModdedToggleOption;
|
||||
return toggleOpt.Value;
|
||||
}
|
||||
}
|
||||
@@ -3,22 +3,21 @@ using System;
|
||||
using MiraAPI.Networking;
|
||||
using UnityEngine;
|
||||
|
||||
namespace MiraAPI.GameOptions
|
||||
namespace MiraAPI.GameOptions;
|
||||
|
||||
public interface IModdedOption
|
||||
{
|
||||
public interface IModdedOption
|
||||
{
|
||||
public uint Id { get; }
|
||||
public BaseGameSetting Data { get; }
|
||||
public ModdedOptionGroup Group { get; set; }
|
||||
public IMiraPlugin ParentMod { get; set; }
|
||||
public Type AdvancedRole { get; }
|
||||
public OptionBehaviour OptionBehaviour { get; protected set; }
|
||||
public string Title { get; }
|
||||
public StringNames StringName { get; }
|
||||
public Func<bool> Visible { get; set; }
|
||||
public void ValueChanged(OptionBehaviour optionBehaviour);
|
||||
public OptionBehaviour CreateOption(ToggleOption toggleOpt, NumberOption numberOpt, StringOption stringOpt, Transform container);
|
||||
public NetData GetNetData();
|
||||
public void HandleNetData(byte[] data);
|
||||
}
|
||||
}
|
||||
public uint Id { get; }
|
||||
public BaseGameSetting Data { get; }
|
||||
public ModdedOptionGroup Group { get; set; }
|
||||
public IMiraPlugin ParentMod { get; set; }
|
||||
public Type AdvancedRole { get; }
|
||||
public OptionBehaviour OptionBehaviour { get; protected set; }
|
||||
public string Title { get; }
|
||||
public StringNames StringName { get; }
|
||||
public Func<bool> Visible { get; set; }
|
||||
public void ValueChanged(OptionBehaviour optionBehaviour);
|
||||
public OptionBehaviour CreateOption(ToggleOption toggleOpt, NumberOption numberOpt, StringOption stringOpt, Transform container);
|
||||
public NetData GetNetData();
|
||||
public void HandleNetData(byte[] data);
|
||||
}
|
||||
@@ -1,13 +1,12 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace MiraAPI.GameOptions
|
||||
namespace MiraAPI.GameOptions;
|
||||
|
||||
public interface IModdedOptionGroup
|
||||
{
|
||||
public interface IModdedOptionGroup
|
||||
{
|
||||
public string GroupName { get; }
|
||||
public Func<bool> GroupVisible => () => true;
|
||||
public Color GroupColor => Color.clear;
|
||||
public Type AdvancedRole => null;
|
||||
}
|
||||
}
|
||||
public string GroupName { get; }
|
||||
public Func<bool> GroupVisible => () => true;
|
||||
public Color GroupColor => Color.clear;
|
||||
public Type AdvancedRole => null;
|
||||
}
|
||||
@@ -1,20 +1,19 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
namespace MiraAPI.GameOptions
|
||||
{
|
||||
public class ModdedGroupSingleton<T> where T : ModdedOptionGroup
|
||||
{
|
||||
private static T _instance;
|
||||
namespace MiraAPI.GameOptions;
|
||||
|
||||
public static T Instance
|
||||
public class ModdedGroupSingleton<T> where T : ModdedOptionGroup
|
||||
{
|
||||
private static T _instance;
|
||||
|
||||
public static T Instance
|
||||
{
|
||||
get => _instance ??= ModdedOptionsManager.Groups.OfType<T>().Single();
|
||||
set
|
||||
{
|
||||
get => _instance ??= ModdedOptionsManager.Groups.OfType<T>().Single();
|
||||
set
|
||||
{
|
||||
if (_instance != null) throw new InvalidOperationException($"Instance for {typeof(T)} is already set");
|
||||
_instance = value;
|
||||
}
|
||||
if (_instance != null) throw new InvalidOperationException($"Instance for {typeof(T)} is already set");
|
||||
_instance = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,15 +2,14 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace MiraAPI.GameOptions
|
||||
namespace MiraAPI.GameOptions;
|
||||
|
||||
public class ModdedOptionGroup
|
||||
{
|
||||
public class ModdedOptionGroup
|
||||
{
|
||||
public IMiraPlugin ParentMod;
|
||||
public GameObject Header;
|
||||
public string GroupName;
|
||||
public Func<bool> GroupVisible;
|
||||
public Color GroupColor;
|
||||
public Type AdvancedRole;
|
||||
}
|
||||
}
|
||||
public IMiraPlugin ParentMod;
|
||||
public GameObject Header;
|
||||
public string GroupName;
|
||||
public Func<bool> GroupVisible;
|
||||
public Color GroupColor;
|
||||
public Type AdvancedRole;
|
||||
}
|
||||
@@ -8,104 +8,103 @@ using System.Reflection;
|
||||
using MiraAPI.Networking;
|
||||
using Reactor.Networking.Rpc;
|
||||
|
||||
namespace MiraAPI.GameOptions
|
||||
namespace MiraAPI.GameOptions;
|
||||
|
||||
public class ModdedOptionsManager
|
||||
{
|
||||
public class ModdedOptionsManager
|
||||
public static readonly Dictionary<uint, IModdedOption> ModdedOptions = new();
|
||||
public static readonly List<IModdedOption> Options = [];
|
||||
public static readonly List<ModdedOptionGroup> Groups = [];
|
||||
private static readonly Dictionary<PropertyInfo, ModdedOptionAttribute> OptionAttributes = new();
|
||||
public static readonly Dictionary<Type, ModdedOptionGroup> OriginalTypes = new();
|
||||
public static uint NextId = 1;
|
||||
|
||||
public static IModdedOption RegisterOption(Type type, ModdedOptionAttribute attribute, PropertyInfo property)
|
||||
{
|
||||
public static readonly Dictionary<uint, IModdedOption> ModdedOptions = new();
|
||||
public static readonly List<IModdedOption> Options = [];
|
||||
public static readonly List<ModdedOptionGroup> Groups = [];
|
||||
private static readonly Dictionary<PropertyInfo, ModdedOptionAttribute> OptionAttributes = new();
|
||||
public static readonly Dictionary<Type, ModdedOptionGroup> OriginalTypes = new();
|
||||
public static uint NextId = 1;
|
||||
if (OptionAttributes.ContainsKey(property)) return null;
|
||||
object newObj = Activator.CreateInstance(type);
|
||||
IModdedOption result = attribute.CreateOption(property.GetValue(newObj), property);
|
||||
|
||||
public static IModdedOption RegisterOption(Type type, ModdedOptionAttribute attribute, PropertyInfo property)
|
||||
if (result != null)
|
||||
{
|
||||
if (OptionAttributes.ContainsKey(property)) return null;
|
||||
object newObj = Activator.CreateInstance(type);
|
||||
IModdedOption result = attribute.CreateOption(property.GetValue(newObj), property);
|
||||
var setterOriginal = property.GetSetMethod();
|
||||
var setterPatch = typeof(ModdedOptionsManager).GetMethod(nameof(PropertySetterPatch));
|
||||
PluginSingleton<MiraApiPlugin>.Instance.Harmony.Patch(setterOriginal, postfix: new HarmonyMethod(setterPatch));
|
||||
|
||||
if (result != null)
|
||||
{
|
||||
var setterOriginal = property.GetSetMethod();
|
||||
var setterPatch = typeof(ModdedOptionsManager).GetMethod(nameof(PropertySetterPatch));
|
||||
PluginSingleton<MiraApiPlugin>.Instance.Harmony.Patch(setterOriginal, postfix: new HarmonyMethod(setterPatch));
|
||||
var getterOriginal = property.GetGetMethod();
|
||||
var getterPatch = typeof(ModdedOptionsManager).GetMethod(nameof(PropertyGetterPatch));
|
||||
PluginSingleton<MiraApiPlugin>.Instance.Harmony.Patch(getterOriginal, prefix: new HarmonyMethod(getterPatch));
|
||||
|
||||
var getterOriginal = property.GetGetMethod();
|
||||
var getterPatch = typeof(ModdedOptionsManager).GetMethod(nameof(PropertyGetterPatch));
|
||||
PluginSingleton<MiraApiPlugin>.Instance.Harmony.Patch(getterOriginal, prefix: new HarmonyMethod(getterPatch));
|
||||
|
||||
attribute.HolderOption = result;
|
||||
attribute.HolderOption = result;
|
||||
|
||||
OptionAttributes.Add(property, attribute);
|
||||
OptionAttributes.Add(property, attribute);
|
||||
|
||||
if (OriginalTypes.ContainsKey(type))
|
||||
{
|
||||
Logger<MiraApiPlugin>.Error($"Grouping {attribute.Title} with {OriginalTypes[type].GroupName}");
|
||||
result.Group = OriginalTypes[type];
|
||||
}
|
||||
if (OriginalTypes.ContainsKey(type))
|
||||
{
|
||||
Logger<MiraApiPlugin>.Error($"Grouping {attribute.Title} with {OriginalTypes[type].GroupName}");
|
||||
result.Group = OriginalTypes[type];
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static void SyncAllOptions(int targetId=-1)
|
||||
return result;
|
||||
}
|
||||
|
||||
public static void SyncAllOptions(int targetId=-1)
|
||||
{
|
||||
List<NetData> data = [];
|
||||
int count = 0;
|
||||
foreach (var option in ModdedOptions.Values)
|
||||
{
|
||||
List<NetData> data = [];
|
||||
int count = 0;
|
||||
foreach (var option in ModdedOptions.Values)
|
||||
{
|
||||
var netData = option.GetNetData();
|
||||
data.Add(netData);
|
||||
count += netData.GetLength();
|
||||
var netData = option.GetNetData();
|
||||
data.Add(netData);
|
||||
count += netData.GetLength();
|
||||
|
||||
if (count > 1000)
|
||||
{
|
||||
Rpc<SyncOptionsRpc>.Instance.SendTo(PlayerControl.LocalPlayer, targetId, data.ToArray());
|
||||
data.Clear();
|
||||
count = 0;
|
||||
}
|
||||
}
|
||||
if (data.Count > 0)
|
||||
if (count > 1000)
|
||||
{
|
||||
Rpc<SyncOptionsRpc>.Instance.SendTo(PlayerControl.LocalPlayer, targetId, data.ToArray());
|
||||
data.Clear();
|
||||
count = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static void HandleSyncOptions(NetData[] data)
|
||||
if (data.Count > 0)
|
||||
{
|
||||
foreach (var netData in data)
|
||||
{
|
||||
if (ModdedOptions.TryGetValue(netData.Id, out var option))
|
||||
{
|
||||
Logger<MiraApiPlugin>.Error("Handling option " + option.Title);
|
||||
option.HandleNetData(netData.Data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static void PropertySetterPatch(MethodBase __originalMethod, object value)
|
||||
{
|
||||
ModdedOptionAttribute attribute = OptionAttributes.First(pair => pair.Key.GetSetMethod().Equals(__originalMethod)).Value;
|
||||
|
||||
if (attribute != null)
|
||||
{
|
||||
attribute.SetValue(value);
|
||||
}
|
||||
}
|
||||
|
||||
public static bool PropertyGetterPatch(MethodBase __originalMethod, ref object __result)
|
||||
{
|
||||
ModdedOptionAttribute attribute = OptionAttributes.First(pair => pair.Key.GetGetMethod().Equals(__originalMethod)).Value;
|
||||
|
||||
if (attribute != null)
|
||||
{
|
||||
__result = attribute.GetValue();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
Rpc<SyncOptionsRpc>.Instance.SendTo(PlayerControl.LocalPlayer, targetId, data.ToArray());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static void HandleSyncOptions(NetData[] data)
|
||||
{
|
||||
foreach (var netData in data)
|
||||
{
|
||||
if (ModdedOptions.TryGetValue(netData.Id, out var option))
|
||||
{
|
||||
Logger<MiraApiPlugin>.Error("Handling option " + option.Title);
|
||||
option.HandleNetData(netData.Data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static void PropertySetterPatch(MethodBase __originalMethod, object value)
|
||||
{
|
||||
ModdedOptionAttribute attribute = OptionAttributes.First(pair => pair.Key.GetSetMethod().Equals(__originalMethod)).Value;
|
||||
|
||||
if (attribute != null)
|
||||
{
|
||||
attribute.SetValue(value);
|
||||
}
|
||||
}
|
||||
|
||||
public static bool PropertyGetterPatch(MethodBase __originalMethod, ref object __result)
|
||||
{
|
||||
ModdedOptionAttribute attribute = OptionAttributes.First(pair => pair.Key.GetGetMethod().Equals(__originalMethod)).Value;
|
||||
|
||||
if (attribute != null)
|
||||
{
|
||||
__result = attribute.GetValue();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -5,71 +5,70 @@ using MiraAPI.Networking;
|
||||
using UnityEngine;
|
||||
using Object = UnityEngine.Object;
|
||||
|
||||
namespace MiraAPI.GameOptions.OptionTypes
|
||||
namespace MiraAPI.GameOptions.OptionTypes;
|
||||
|
||||
public class ModdedEnumOption : ModdedOption<int>
|
||||
{
|
||||
public class ModdedEnumOption : ModdedOption<int>
|
||||
public ModdedEnumOption(string title, int defaultValue, Type enumType, Type roleType) : base(title, defaultValue, roleType)
|
||||
{
|
||||
public ModdedEnumOption(string title, int defaultValue, Type enumType, Type roleType) : base(title, defaultValue, roleType)
|
||||
{
|
||||
Values = Enum.GetNames(enumType);
|
||||
Data = ScriptableObject.CreateInstance<StringGameSetting>();
|
||||
var data = (StringGameSetting)Data;
|
||||
Values = Enum.GetNames(enumType);
|
||||
Data = ScriptableObject.CreateInstance<StringGameSetting>();
|
||||
var data = (StringGameSetting)Data;
|
||||
|
||||
data.Title = StringName;
|
||||
data.Type = global::OptionTypes.String;
|
||||
data.Values = Values.Select(CustomStringName.CreateAndRegister).ToArray();
|
||||
data.Index = Value;
|
||||
}
|
||||
data.Title = StringName;
|
||||
data.Type = global::OptionTypes.String;
|
||||
data.Values = Values.Select(CustomStringName.CreateAndRegister).ToArray();
|
||||
data.Index = Value;
|
||||
}
|
||||
|
||||
public string[] Values { get; set; }
|
||||
public string[] Values { get; set; }
|
||||
|
||||
public override OptionBehaviour CreateOption(ToggleOption toggleOpt, NumberOption numberOpt, StringOption stringOpt, Transform container)
|
||||
{
|
||||
var stringOption = Object.Instantiate(stringOpt, container);
|
||||
public override OptionBehaviour CreateOption(ToggleOption toggleOpt, NumberOption numberOpt, StringOption stringOpt, Transform container)
|
||||
{
|
||||
var stringOption = Object.Instantiate(stringOpt, container);
|
||||
|
||||
stringOption.SetUpFromData(Data, 20);
|
||||
stringOption.OnValueChanged = (Il2CppSystem.Action<OptionBehaviour>)ValueChanged;
|
||||
stringOption.SetUpFromData(Data, 20);
|
||||
stringOption.OnValueChanged = (Il2CppSystem.Action<OptionBehaviour>)ValueChanged;
|
||||
|
||||
// SetUpFromData method doesnt work correctly so we must set the values manually
|
||||
stringOption.Title = StringName;
|
||||
stringOption.Values = ((StringGameSetting)Data).Values;
|
||||
stringOption.Value = Value;
|
||||
// SetUpFromData method doesnt work correctly so we must set the values manually
|
||||
stringOption.Title = StringName;
|
||||
stringOption.Values = ((StringGameSetting)Data).Values;
|
||||
stringOption.Value = Value;
|
||||
|
||||
OptionBehaviour = stringOption;
|
||||
OptionBehaviour = stringOption;
|
||||
|
||||
return stringOption;
|
||||
}
|
||||
return stringOption;
|
||||
}
|
||||
|
||||
public override NetData GetNetData()
|
||||
{
|
||||
return new NetData(Id, BitConverter.GetBytes(Value));
|
||||
}
|
||||
public override NetData GetNetData()
|
||||
{
|
||||
return new NetData(Id, BitConverter.GetBytes(Value));
|
||||
}
|
||||
|
||||
public override void HandleNetData(byte[] data)
|
||||
{
|
||||
SetValue(BitConverter.ToInt32(data));
|
||||
}
|
||||
public override void HandleNetData(byte[] data)
|
||||
{
|
||||
SetValue(BitConverter.ToInt32(data));
|
||||
}
|
||||
|
||||
public override string GetHudStringText()
|
||||
{
|
||||
return Title + ": " + Values[Value];
|
||||
}
|
||||
public override string GetHudStringText()
|
||||
{
|
||||
return Title + ": " + Values[Value];
|
||||
}
|
||||
|
||||
public override int GetValueFromOptionBehaviour(OptionBehaviour optionBehaviour)
|
||||
{
|
||||
return optionBehaviour.GetInt();
|
||||
}
|
||||
public override int GetValueFromOptionBehaviour(OptionBehaviour optionBehaviour)
|
||||
{
|
||||
return optionBehaviour.GetInt();
|
||||
}
|
||||
|
||||
public override void OnValueChanged(int newValue)
|
||||
{
|
||||
DestroyableSingleton<HudManager>.Instance.Notifier.AddSettingsChangeMessage(StringName, Data.GetValueString(newValue), false);
|
||||
if (OptionBehaviour is null) return;
|
||||
public override void OnValueChanged(int newValue)
|
||||
{
|
||||
DestroyableSingleton<HudManager>.Instance.Notifier.AddSettingsChangeMessage(StringName, Data.GetValueString(newValue), false);
|
||||
if (OptionBehaviour is null) return;
|
||||
|
||||
var opt = OptionBehaviour as StringOption;
|
||||
if (opt)
|
||||
{
|
||||
opt.Value = newValue;
|
||||
}
|
||||
var opt = OptionBehaviour as StringOption;
|
||||
if (opt)
|
||||
{
|
||||
opt.Value = newValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,93 +5,92 @@ using MiraAPI.Utilities;
|
||||
using UnityEngine;
|
||||
using Object = UnityEngine.Object;
|
||||
|
||||
namespace MiraAPI.GameOptions.OptionTypes
|
||||
namespace MiraAPI.GameOptions.OptionTypes;
|
||||
|
||||
public class ModdedNumberOption : ModdedOption<float>
|
||||
{
|
||||
public class ModdedNumberOption : ModdedOption<float>
|
||||
public float Min { get; private set; }
|
||||
public float Max { get; private set; }
|
||||
public float Increment { get; private set; }
|
||||
public NumberSuffixes SuffixType { get; private set; }
|
||||
public bool ZeroInfinity { get; private set; }
|
||||
public ModdedNumberOption(string title, float defaultValue, float min, float max, float increment, NumberSuffixes suffixType, bool zeroInfinity, Type roleType) : base(title, defaultValue, roleType)
|
||||
{
|
||||
public float Min { get; private set; }
|
||||
public float Max { get; private set; }
|
||||
public float Increment { get; private set; }
|
||||
public NumberSuffixes SuffixType { get; private set; }
|
||||
public bool ZeroInfinity { get; private set; }
|
||||
public ModdedNumberOption(string title, float defaultValue, float min, float max, float increment, NumberSuffixes suffixType, bool zeroInfinity, Type roleType) : base(title, defaultValue, roleType)
|
||||
{
|
||||
Min = min;
|
||||
Max = max;
|
||||
Increment = increment;
|
||||
SuffixType = suffixType;
|
||||
ZeroInfinity = zeroInfinity;
|
||||
Min = min;
|
||||
Max = max;
|
||||
Increment = increment;
|
||||
SuffixType = suffixType;
|
||||
ZeroInfinity = zeroInfinity;
|
||||
|
||||
Value = Mathf.Clamp(defaultValue, min, max);
|
||||
Value = Mathf.Clamp(defaultValue, min, max);
|
||||
|
||||
Data = ScriptableObject.CreateInstance<FloatGameSetting>();
|
||||
Data = ScriptableObject.CreateInstance<FloatGameSetting>();
|
||||
|
||||
var data = (FloatGameSetting)Data;
|
||||
data.Type = global::OptionTypes.Float;
|
||||
data.Title = StringName;
|
||||
data.Value = Value;
|
||||
data.Increment = Increment;
|
||||
data.ValidRange = new FloatRange(Min, Max);
|
||||
data.FormatString = "0";
|
||||
data.ZeroIsInfinity = ZeroInfinity;
|
||||
data.SuffixType = SuffixType;
|
||||
data.OptionName = FloatOptionNames.Invalid;
|
||||
}
|
||||
var data = (FloatGameSetting)Data;
|
||||
data.Type = global::OptionTypes.Float;
|
||||
data.Title = StringName;
|
||||
data.Value = Value;
|
||||
data.Increment = Increment;
|
||||
data.ValidRange = new FloatRange(Min, Max);
|
||||
data.FormatString = "0";
|
||||
data.ZeroIsInfinity = ZeroInfinity;
|
||||
data.SuffixType = SuffixType;
|
||||
data.OptionName = FloatOptionNames.Invalid;
|
||||
}
|
||||
|
||||
public override OptionBehaviour CreateOption(ToggleOption toggleOpt, NumberOption numberOpt, StringOption stringOpt, Transform container)
|
||||
{
|
||||
var numberOption = Object.Instantiate(numberOpt, Vector3.zero, Quaternion.identity, container);
|
||||
public override OptionBehaviour CreateOption(ToggleOption toggleOpt, NumberOption numberOpt, StringOption stringOpt, Transform container)
|
||||
{
|
||||
var numberOption = Object.Instantiate(numberOpt, Vector3.zero, Quaternion.identity, container);
|
||||
|
||||
numberOption.SetUpFromData(Data, 20);
|
||||
numberOption.OnValueChanged = (Il2CppSystem.Action<OptionBehaviour>)ValueChanged;
|
||||
numberOption.SetUpFromData(Data, 20);
|
||||
numberOption.OnValueChanged = (Il2CppSystem.Action<OptionBehaviour>)ValueChanged;
|
||||
|
||||
numberOption.Title = StringName;
|
||||
numberOption.Value = Value;
|
||||
numberOption.Increment = Increment;
|
||||
numberOption.ValidRange = new FloatRange(Min, Max);
|
||||
numberOption.FormatString = "0";
|
||||
numberOption.ZeroIsInfinity = ZeroInfinity;
|
||||
numberOption.SuffixType = SuffixType;
|
||||
numberOption.floatOptionName = FloatOptionNames.Invalid;
|
||||
numberOption.Title = StringName;
|
||||
numberOption.Value = Value;
|
||||
numberOption.Increment = Increment;
|
||||
numberOption.ValidRange = new FloatRange(Min, Max);
|
||||
numberOption.FormatString = "0";
|
||||
numberOption.ZeroIsInfinity = ZeroInfinity;
|
||||
numberOption.SuffixType = SuffixType;
|
||||
numberOption.floatOptionName = FloatOptionNames.Invalid;
|
||||
|
||||
|
||||
OptionBehaviour = numberOption;
|
||||
OptionBehaviour = numberOption;
|
||||
|
||||
return numberOption;
|
||||
}
|
||||
return numberOption;
|
||||
}
|
||||
|
||||
public override NetData GetNetData()
|
||||
public override NetData GetNetData()
|
||||
{
|
||||
return new NetData(Id, BitConverter.GetBytes(Value));
|
||||
}
|
||||
|
||||
public override void HandleNetData(byte[] data)
|
||||
{
|
||||
SetValue(BitConverter.ToSingle(data));
|
||||
}
|
||||
|
||||
public override string GetHudStringText()
|
||||
{
|
||||
return Title + ": " + Value + Helpers.GetSuffix(SuffixType);
|
||||
}
|
||||
|
||||
public override float GetValueFromOptionBehaviour(OptionBehaviour optionBehaviour)
|
||||
{
|
||||
return Mathf.Clamp(optionBehaviour.GetFloat(), Min, Max);
|
||||
}
|
||||
|
||||
public override void OnValueChanged(float newValue)
|
||||
{
|
||||
Value = Mathf.Clamp(newValue, Min, Max);
|
||||
DestroyableSingleton<HudManager>.Instance.Notifier.AddSettingsChangeMessage(StringName, Data.GetValueString(Value), false);
|
||||
|
||||
if (OptionBehaviour is null) return;
|
||||
|
||||
var opt = OptionBehaviour as NumberOption;
|
||||
if (opt)
|
||||
{
|
||||
return new NetData(Id, BitConverter.GetBytes(Value));
|
||||
}
|
||||
|
||||
public override void HandleNetData(byte[] data)
|
||||
{
|
||||
SetValue(BitConverter.ToSingle(data));
|
||||
}
|
||||
|
||||
public override string GetHudStringText()
|
||||
{
|
||||
return Title + ": " + Value + Helpers.GetSuffix(SuffixType);
|
||||
}
|
||||
|
||||
public override float GetValueFromOptionBehaviour(OptionBehaviour optionBehaviour)
|
||||
{
|
||||
return Mathf.Clamp(optionBehaviour.GetFloat(), Min, Max);
|
||||
}
|
||||
|
||||
public override void OnValueChanged(float newValue)
|
||||
{
|
||||
Value = Mathf.Clamp(newValue, Min, Max);
|
||||
DestroyableSingleton<HudManager>.Instance.Notifier.AddSettingsChangeMessage(StringName, Data.GetValueString(Value), false);
|
||||
|
||||
if (OptionBehaviour is null) return;
|
||||
|
||||
var opt = OptionBehaviour as NumberOption;
|
||||
if (opt)
|
||||
{
|
||||
opt.Value = newValue;
|
||||
}
|
||||
opt.Value = newValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,77 +7,76 @@ using Reactor.Networking.Rpc;
|
||||
using Reactor.Utilities;
|
||||
using UnityEngine;
|
||||
|
||||
namespace MiraAPI.GameOptions.OptionTypes
|
||||
namespace MiraAPI.GameOptions.OptionTypes;
|
||||
|
||||
public abstract class ModdedOption<T> : IModdedOption
|
||||
{
|
||||
public abstract class ModdedOption<T> : IModdedOption
|
||||
public uint Id { get; }
|
||||
public BaseGameSetting Data { get; protected init; }
|
||||
public T Value { get; protected set; }
|
||||
public T DefaultValue { get; init; }
|
||||
public Action<T> ChangedEvent { get; set; }
|
||||
public string Title { get; }
|
||||
public StringNames StringName { get; }
|
||||
public Func<bool> Visible { get; set; }
|
||||
public Type AdvancedRole { get; }
|
||||
public OptionBehaviour OptionBehaviour { get; set; }
|
||||
public ModdedOptionGroup Group { get; set; } = null;
|
||||
public IMiraPlugin ParentMod { get; set; } = null;
|
||||
|
||||
public ModdedOption(string title, T defaultValue, Type roleType) : this()
|
||||
{
|
||||
public uint Id { get; }
|
||||
public BaseGameSetting Data { get; protected init; }
|
||||
public T Value { get; protected set; }
|
||||
public T DefaultValue { get; init; }
|
||||
public Action<T> ChangedEvent { get; set; }
|
||||
public string Title { get; }
|
||||
public StringNames StringName { get; }
|
||||
public Func<bool> Visible { get; set; }
|
||||
public Type AdvancedRole { get; }
|
||||
public OptionBehaviour OptionBehaviour { get; set; }
|
||||
public ModdedOptionGroup Group { get; set; } = null;
|
||||
public IMiraPlugin ParentMod { get; set; } = null;
|
||||
Title = title;
|
||||
DefaultValue = defaultValue;
|
||||
Value = defaultValue;
|
||||
StringName = CustomStringName.CreateAndRegister(Title);
|
||||
Visible = () => true;
|
||||
|
||||
public ModdedOption(string title, T defaultValue, Type roleType) : this()
|
||||
if (roleType is not null && roleType.IsAssignableTo(typeof(ICustomRole)))
|
||||
{
|
||||
Title = title;
|
||||
DefaultValue = defaultValue;
|
||||
Value = defaultValue;
|
||||
StringName = CustomStringName.CreateAndRegister(Title);
|
||||
Visible = () => true;
|
||||
|
||||
if (roleType is not null && roleType.IsAssignableTo(typeof(ICustomRole)))
|
||||
{
|
||||
AdvancedRole = roleType;
|
||||
}
|
||||
AdvancedRole = roleType;
|
||||
}
|
||||
|
||||
public ModdedOption()
|
||||
{
|
||||
Logger<MiraApiPlugin>.Error("created modded option");
|
||||
Id = ModdedOptionsManager.NextId++;
|
||||
ModdedOptionsManager.Options.Add(this);
|
||||
ModdedOptionsManager.ModdedOptions.Add(Id, this);
|
||||
}
|
||||
|
||||
public void ValueChanged(OptionBehaviour optionBehaviour)
|
||||
{
|
||||
SetValue(GetValueFromOptionBehaviour(optionBehaviour));
|
||||
}
|
||||
|
||||
public void SetValue(T newValue)
|
||||
{
|
||||
var oldVal = Value;
|
||||
Value = newValue;
|
||||
if (!Value.Equals(oldVal) && ChangedEvent != null)
|
||||
{
|
||||
ChangedEvent.Invoke(Value);
|
||||
}
|
||||
|
||||
if (AmongUsClient.Instance.AmHost)
|
||||
{
|
||||
Rpc<SyncOptionsRpc>.Instance.Send(PlayerControl.LocalPlayer, [GetNetData()], true);
|
||||
}
|
||||
|
||||
OnValueChanged(newValue);
|
||||
}
|
||||
|
||||
public abstract NetData GetNetData();
|
||||
|
||||
public abstract void HandleNetData(byte[] data);
|
||||
|
||||
public abstract void OnValueChanged(T newValue);
|
||||
|
||||
public abstract T GetValueFromOptionBehaviour(OptionBehaviour optionBehaviour);
|
||||
|
||||
public abstract OptionBehaviour CreateOption(ToggleOption toggleOpt, NumberOption numberOpt, StringOption stringOpt, Transform container);
|
||||
|
||||
public abstract string GetHudStringText();
|
||||
}
|
||||
}
|
||||
|
||||
public ModdedOption()
|
||||
{
|
||||
Logger<MiraApiPlugin>.Error("created modded option");
|
||||
Id = ModdedOptionsManager.NextId++;
|
||||
ModdedOptionsManager.Options.Add(this);
|
||||
ModdedOptionsManager.ModdedOptions.Add(Id, this);
|
||||
}
|
||||
|
||||
public void ValueChanged(OptionBehaviour optionBehaviour)
|
||||
{
|
||||
SetValue(GetValueFromOptionBehaviour(optionBehaviour));
|
||||
}
|
||||
|
||||
public void SetValue(T newValue)
|
||||
{
|
||||
var oldVal = Value;
|
||||
Value = newValue;
|
||||
if (!Value.Equals(oldVal) && ChangedEvent != null)
|
||||
{
|
||||
ChangedEvent.Invoke(Value);
|
||||
}
|
||||
|
||||
if (AmongUsClient.Instance.AmHost)
|
||||
{
|
||||
Rpc<SyncOptionsRpc>.Instance.Send(PlayerControl.LocalPlayer, [GetNetData()], true);
|
||||
}
|
||||
|
||||
OnValueChanged(newValue);
|
||||
}
|
||||
|
||||
public abstract NetData GetNetData();
|
||||
|
||||
public abstract void HandleNetData(byte[] data);
|
||||
|
||||
public abstract void OnValueChanged(T newValue);
|
||||
|
||||
public abstract T GetValueFromOptionBehaviour(OptionBehaviour optionBehaviour);
|
||||
|
||||
public abstract OptionBehaviour CreateOption(ToggleOption toggleOpt, NumberOption numberOpt, StringOption stringOpt, Transform container);
|
||||
|
||||
public abstract string GetHudStringText();
|
||||
}
|
||||
@@ -5,71 +5,70 @@ using MiraAPI.Networking;
|
||||
using UnityEngine;
|
||||
using Object = UnityEngine.Object;
|
||||
|
||||
namespace MiraAPI.GameOptions.OptionTypes
|
||||
namespace MiraAPI.GameOptions.OptionTypes;
|
||||
|
||||
public class ModdedStringOption : ModdedOption<int>
|
||||
{
|
||||
public class ModdedStringOption : ModdedOption<int>
|
||||
public ModdedStringOption(string title, int defaultValue, string[] values, Type roleType) : base(title, defaultValue, roleType)
|
||||
{
|
||||
public ModdedStringOption(string title, int defaultValue, string[] values, Type roleType) : base(title, defaultValue, roleType)
|
||||
{
|
||||
Values = values;
|
||||
Data = ScriptableObject.CreateInstance<StringGameSetting>();
|
||||
var data = (StringGameSetting)Data;
|
||||
Values = values;
|
||||
Data = ScriptableObject.CreateInstance<StringGameSetting>();
|
||||
var data = (StringGameSetting)Data;
|
||||
|
||||
data.Title = StringName;
|
||||
data.Type = global::OptionTypes.String;
|
||||
data.Values = Values.Select(CustomStringName.CreateAndRegister).ToArray();
|
||||
data.Index = Value;
|
||||
}
|
||||
data.Title = StringName;
|
||||
data.Type = global::OptionTypes.String;
|
||||
data.Values = Values.Select(CustomStringName.CreateAndRegister).ToArray();
|
||||
data.Index = Value;
|
||||
}
|
||||
|
||||
public string[] Values { get; set; }
|
||||
public string[] Values { get; set; }
|
||||
|
||||
public override OptionBehaviour CreateOption(ToggleOption toggleOpt, NumberOption numberOpt, StringOption stringOpt, Transform container)
|
||||
{
|
||||
var stringOption = Object.Instantiate(stringOpt, container);
|
||||
public override OptionBehaviour CreateOption(ToggleOption toggleOpt, NumberOption numberOpt, StringOption stringOpt, Transform container)
|
||||
{
|
||||
var stringOption = Object.Instantiate(stringOpt, container);
|
||||
|
||||
stringOption.SetUpFromData(Data, 20);
|
||||
stringOption.OnValueChanged = (Il2CppSystem.Action<OptionBehaviour>)ValueChanged;
|
||||
stringOption.SetUpFromData(Data, 20);
|
||||
stringOption.OnValueChanged = (Il2CppSystem.Action<OptionBehaviour>)ValueChanged;
|
||||
|
||||
// SetUpFromData method doesnt work correctly so we must set the values manually
|
||||
stringOption.Title = StringName;
|
||||
stringOption.Values = ((StringGameSetting)Data).Values;
|
||||
stringOption.Value = Value;
|
||||
// SetUpFromData method doesnt work correctly so we must set the values manually
|
||||
stringOption.Title = StringName;
|
||||
stringOption.Values = ((StringGameSetting)Data).Values;
|
||||
stringOption.Value = Value;
|
||||
|
||||
OptionBehaviour = stringOption;
|
||||
OptionBehaviour = stringOption;
|
||||
|
||||
return stringOption;
|
||||
}
|
||||
return stringOption;
|
||||
}
|
||||
|
||||
public override NetData GetNetData()
|
||||
public override NetData GetNetData()
|
||||
{
|
||||
return new NetData(Id, BitConverter.GetBytes(Value));
|
||||
}
|
||||
|
||||
public override void HandleNetData(byte[] data)
|
||||
{
|
||||
SetValue(BitConverter.ToInt32(data));
|
||||
}
|
||||
|
||||
public override string GetHudStringText()
|
||||
{
|
||||
return Title + ": " + Values[Value];
|
||||
}
|
||||
|
||||
public override int GetValueFromOptionBehaviour(OptionBehaviour optionBehaviour)
|
||||
{
|
||||
return optionBehaviour.GetInt();
|
||||
}
|
||||
|
||||
public override void OnValueChanged(int newValue)
|
||||
{
|
||||
DestroyableSingleton<HudManager>.Instance.Notifier.AddSettingsChangeMessage(StringName, Data.GetValueString(newValue), false);
|
||||
if (OptionBehaviour is null) return;
|
||||
|
||||
var opt = OptionBehaviour as StringOption;
|
||||
if (opt)
|
||||
{
|
||||
return new NetData(Id, BitConverter.GetBytes(Value));
|
||||
}
|
||||
|
||||
public override void HandleNetData(byte[] data)
|
||||
{
|
||||
SetValue(BitConverter.ToInt32(data));
|
||||
}
|
||||
|
||||
public override string GetHudStringText()
|
||||
{
|
||||
return Title + ": " + Values[Value];
|
||||
}
|
||||
|
||||
public override int GetValueFromOptionBehaviour(OptionBehaviour optionBehaviour)
|
||||
{
|
||||
return optionBehaviour.GetInt();
|
||||
}
|
||||
|
||||
public override void OnValueChanged(int newValue)
|
||||
{
|
||||
DestroyableSingleton<HudManager>.Instance.Notifier.AddSettingsChangeMessage(StringName, Data.GetValueString(newValue), false);
|
||||
if (OptionBehaviour is null) return;
|
||||
|
||||
var opt = OptionBehaviour as StringOption;
|
||||
if (opt)
|
||||
{
|
||||
opt.Value = newValue;
|
||||
}
|
||||
opt.Value = newValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,65 +3,64 @@ using MiraAPI.Networking;
|
||||
using UnityEngine;
|
||||
using Object = UnityEngine.Object;
|
||||
|
||||
namespace MiraAPI.GameOptions.OptionTypes
|
||||
namespace MiraAPI.GameOptions.OptionTypes;
|
||||
|
||||
public class ModdedToggleOption : ModdedOption<bool>
|
||||
{
|
||||
public class ModdedToggleOption : ModdedOption<bool>
|
||||
public ModdedToggleOption(string title, bool defaultValue, Type roleType) : base(title, defaultValue, roleType)
|
||||
{
|
||||
public ModdedToggleOption(string title, bool defaultValue, Type roleType) : base(title, defaultValue, roleType)
|
||||
Data = ScriptableObject.CreateInstance<CheckboxGameSetting>();
|
||||
|
||||
var data = (CheckboxGameSetting)Data;
|
||||
data.Title = StringName;
|
||||
data.Type = global::OptionTypes.Checkbox;
|
||||
}
|
||||
|
||||
public override OptionBehaviour CreateOption(ToggleOption toggleOpt, NumberOption numberOpt, StringOption stringOpt, Transform container)
|
||||
{
|
||||
var toggleOption = Object.Instantiate(toggleOpt, Vector3.zero, Quaternion.identity, container);
|
||||
|
||||
toggleOption.SetUpFromData(Data, 20);
|
||||
|
||||
toggleOption.Title = StringName;
|
||||
toggleOption.TitleText.text = Title;
|
||||
toggleOption.CheckMark.enabled = Value;
|
||||
toggleOption.OnValueChanged = (Il2CppSystem.Action<OptionBehaviour>)ValueChanged;
|
||||
|
||||
OptionBehaviour = toggleOption;
|
||||
|
||||
return toggleOption;
|
||||
}
|
||||
|
||||
public override NetData GetNetData()
|
||||
{
|
||||
return new NetData(Id, BitConverter.GetBytes(Value));
|
||||
}
|
||||
|
||||
public override void HandleNetData(byte[] data)
|
||||
{
|
||||
SetValue(BitConverter.ToBoolean(data));
|
||||
}
|
||||
|
||||
public override string GetHudStringText()
|
||||
{
|
||||
return Title + ": " + (Value ? "On" : "Off");
|
||||
}
|
||||
|
||||
public override bool GetValueFromOptionBehaviour(OptionBehaviour optionBehaviour)
|
||||
{
|
||||
return optionBehaviour.GetBool();
|
||||
}
|
||||
|
||||
public override void OnValueChanged(bool newValue)
|
||||
{
|
||||
DestroyableSingleton<HudManager>.Instance.Notifier.AddSettingsChangeMessage(StringName, newValue ? "On" : "Off", false);
|
||||
if (OptionBehaviour is null) return;
|
||||
|
||||
var toggleOpt = OptionBehaviour as ToggleOption;
|
||||
if (toggleOpt)
|
||||
{
|
||||
Data = ScriptableObject.CreateInstance<CheckboxGameSetting>();
|
||||
|
||||
var data = (CheckboxGameSetting)Data;
|
||||
data.Title = StringName;
|
||||
data.Type = global::OptionTypes.Checkbox;
|
||||
}
|
||||
|
||||
public override OptionBehaviour CreateOption(ToggleOption toggleOpt, NumberOption numberOpt, StringOption stringOpt, Transform container)
|
||||
{
|
||||
var toggleOption = Object.Instantiate(toggleOpt, Vector3.zero, Quaternion.identity, container);
|
||||
|
||||
toggleOption.SetUpFromData(Data, 20);
|
||||
|
||||
toggleOption.Title = StringName;
|
||||
toggleOption.TitleText.text = Title;
|
||||
toggleOption.CheckMark.enabled = Value;
|
||||
toggleOption.OnValueChanged = (Il2CppSystem.Action<OptionBehaviour>)ValueChanged;
|
||||
|
||||
OptionBehaviour = toggleOption;
|
||||
|
||||
return toggleOption;
|
||||
}
|
||||
|
||||
public override NetData GetNetData()
|
||||
{
|
||||
return new NetData(Id, BitConverter.GetBytes(Value));
|
||||
}
|
||||
|
||||
public override void HandleNetData(byte[] data)
|
||||
{
|
||||
SetValue(BitConverter.ToBoolean(data));
|
||||
}
|
||||
|
||||
public override string GetHudStringText()
|
||||
{
|
||||
return Title + ": " + (Value ? "On" : "Off");
|
||||
}
|
||||
|
||||
public override bool GetValueFromOptionBehaviour(OptionBehaviour optionBehaviour)
|
||||
{
|
||||
return optionBehaviour.GetBool();
|
||||
}
|
||||
|
||||
public override void OnValueChanged(bool newValue)
|
||||
{
|
||||
DestroyableSingleton<HudManager>.Instance.Notifier.AddSettingsChangeMessage(StringName, newValue ? "On" : "Off", false);
|
||||
if (OptionBehaviour is null) return;
|
||||
|
||||
var toggleOpt = OptionBehaviour as ToggleOption;
|
||||
if (toggleOpt)
|
||||
{
|
||||
toggleOpt.CheckMark.enabled = newValue;
|
||||
}
|
||||
toggleOpt.CheckMark.enabled = newValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,7 @@
|
||||
namespace MiraAPI.Networking
|
||||
namespace MiraAPI.Networking;
|
||||
|
||||
public enum MiraRpc : uint
|
||||
{
|
||||
public enum MiraRpc : uint
|
||||
{
|
||||
SyncGameOptions,
|
||||
SyncRoleOptions
|
||||
}
|
||||
}
|
||||
SyncGameOptions,
|
||||
SyncRoleOptions
|
||||
}
|
||||
@@ -5,127 +5,126 @@ using MiraAPI.Roles;
|
||||
using Reactor.Utilities.Extensions;
|
||||
using UnityEngine;
|
||||
|
||||
namespace MiraAPI.Patches
|
||||
namespace MiraAPI.Patches;
|
||||
|
||||
[HarmonyPatch(typeof(HudManager))]
|
||||
public static class HudManagerPatches
|
||||
{
|
||||
[HarmonyPatch(typeof(HudManager))]
|
||||
public static class HudManagerPatches
|
||||
/// Custom buttons parent
|
||||
private static GameObject _bottomLeft;
|
||||
|
||||
/// Custom role tab
|
||||
private static TaskPanelBehaviour _roleTab;
|
||||
|
||||
[HarmonyPostfix]
|
||||
[HarmonyPatch(nameof(HudManager.Update))]
|
||||
public static void UpdatePostfix(HudManager __instance)
|
||||
{
|
||||
/// Custom buttons parent
|
||||
private static GameObject _bottomLeft;
|
||||
var local = PlayerControl.LocalPlayer;
|
||||
|
||||
/// Custom role tab
|
||||
private static TaskPanelBehaviour _roleTab;
|
||||
|
||||
[HarmonyPostfix]
|
||||
[HarmonyPatch(nameof(HudManager.Update))]
|
||||
public static void UpdatePostfix(HudManager __instance)
|
||||
if (AmongUsClient.Instance.GameState != InnerNetClient.GameStates.Started && !ShipStatus.Instance)
|
||||
{
|
||||
var local = PlayerControl.LocalPlayer;
|
||||
return;
|
||||
}
|
||||
|
||||
if (AmongUsClient.Instance.GameState != InnerNetClient.GameStates.Started && !ShipStatus.Instance)
|
||||
//CustomGameModeManager.ActiveMode.HudUpdate(__instance);
|
||||
if (local is null || local.Data is null || local.Data.Role is null) return;
|
||||
|
||||
if (local.Data.Role is ICustomRole customRole)
|
||||
{
|
||||
customRole.HudUpdate(__instance);
|
||||
|
||||
if (customRole.SetTabText() != null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//CustomGameModeManager.ActiveMode.HudUpdate(__instance);
|
||||
if (local is null || local.Data is null || local.Data.Role is null) return;
|
||||
|
||||
if (local.Data.Role is ICustomRole customRole)
|
||||
{
|
||||
customRole.HudUpdate(__instance);
|
||||
|
||||
if (customRole.SetTabText() != null)
|
||||
if (_roleTab == null)
|
||||
{
|
||||
if (_roleTab == null)
|
||||
{
|
||||
_roleTab = CustomRoleManager.CreateRoleTab(customRole);
|
||||
}
|
||||
else
|
||||
{
|
||||
CustomRoleManager.UpdateRoleTab(_roleTab, customRole);
|
||||
}
|
||||
_roleTab = CustomRoleManager.CreateRoleTab(customRole);
|
||||
}
|
||||
else if (customRole.SetTabText() == null && _roleTab)
|
||||
else
|
||||
{
|
||||
_roleTab.gameObject.Destroy();
|
||||
CustomRoleManager.UpdateRoleTab(_roleTab, customRole);
|
||||
}
|
||||
}
|
||||
else if (_roleTab)
|
||||
else if (customRole.SetTabText() == null && _roleTab)
|
||||
{
|
||||
_roleTab.gameObject.Destroy();
|
||||
}
|
||||
}
|
||||
|
||||
/* /// <summary>
|
||||
/// Trigger hudstart on current custom gamemode
|
||||
/// </summary>
|
||||
[HarmonyPostfix]
|
||||
[HarmonyPatch("OnGameStart")]
|
||||
public static void GameStartPatch(HudManager __instance)
|
||||
{
|
||||
CustomGameModeManager.ActiveMode.HudStart(__instance);
|
||||
}*/
|
||||
|
||||
/// <summary>
|
||||
/// Create custom buttons parent
|
||||
/// </summary>
|
||||
[HarmonyPostfix]
|
||||
[HarmonyPatch(nameof(HudManager.Start))]
|
||||
public static void StartPostfix(HudManager __instance)
|
||||
else if (_roleTab)
|
||||
{
|
||||
if (!_bottomLeft)
|
||||
_roleTab.gameObject.Destroy();
|
||||
}
|
||||
}
|
||||
|
||||
/* /// <summary>
|
||||
/// Trigger hudstart on current custom gamemode
|
||||
/// </summary>
|
||||
[HarmonyPostfix]
|
||||
[HarmonyPatch("OnGameStart")]
|
||||
public static void GameStartPatch(HudManager __instance)
|
||||
{
|
||||
var buttons = __instance.transform.Find("Buttons");
|
||||
_bottomLeft = Object.Instantiate(buttons.Find("BottomRight").gameObject, buttons);
|
||||
}
|
||||
CustomGameModeManager.ActiveMode.HudStart(__instance);
|
||||
}*/
|
||||
|
||||
foreach (var t in _bottomLeft.GetComponentsInChildren<ActionButton>(true))
|
||||
{
|
||||
t.gameObject.Destroy();
|
||||
}
|
||||
|
||||
var gridArrange = _bottomLeft.GetComponent<GridArrange>();
|
||||
var aspectPosition = _bottomLeft.GetComponent<AspectPosition>();
|
||||
|
||||
_bottomLeft.name = "BottomLeft";
|
||||
gridArrange.Alignment = GridArrange.StartAlign.Right;
|
||||
aspectPosition.Alignment = AspectPosition.EdgeAlignments.LeftBottom;
|
||||
|
||||
foreach (var button in CustomButtonManager.CustomButtons)
|
||||
{
|
||||
button.CreateButton(_bottomLeft.transform);
|
||||
}
|
||||
|
||||
gridArrange.Start();
|
||||
gridArrange.ArrangeChilds();
|
||||
|
||||
aspectPosition.AdjustPosition();
|
||||
/// <summary>
|
||||
/// Create custom buttons parent
|
||||
/// </summary>
|
||||
[HarmonyPostfix]
|
||||
[HarmonyPatch(nameof(HudManager.Start))]
|
||||
public static void StartPostfix(HudManager __instance)
|
||||
{
|
||||
if (!_bottomLeft)
|
||||
{
|
||||
var buttons = __instance.transform.Find("Buttons");
|
||||
_bottomLeft = Object.Instantiate(buttons.Find("BottomRight").gameObject, buttons);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Make sure all launchpad hud elements are inactive/active when appropriate
|
||||
/// </summary>
|
||||
[HarmonyPostfix]
|
||||
[HarmonyPatch(nameof(HudManager.SetHudActive), typeof(PlayerControl), typeof(RoleBehaviour), typeof(bool))]
|
||||
public static void SetHudActivePostfix(HudManager __instance, [HarmonyArgument(0)] PlayerControl player, [HarmonyArgument(1)] RoleBehaviour roleBehaviour, [HarmonyArgument(2)] bool isActive)
|
||||
foreach (var t in _bottomLeft.GetComponentsInChildren<ActionButton>(true))
|
||||
{
|
||||
if (player.Data == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
t.gameObject.Destroy();
|
||||
}
|
||||
|
||||
if (_roleTab)
|
||||
{
|
||||
_roleTab.gameObject.SetActive(isActive);
|
||||
}
|
||||
var gridArrange = _bottomLeft.GetComponent<GridArrange>();
|
||||
var aspectPosition = _bottomLeft.GetComponent<AspectPosition>();
|
||||
|
||||
foreach (var button in CustomButtonManager.CustomButtons)
|
||||
button.SetActive(isActive, roleBehaviour);
|
||||
_bottomLeft.name = "BottomLeft";
|
||||
gridArrange.Alignment = GridArrange.StartAlign.Right;
|
||||
aspectPosition.Alignment = AspectPosition.EdgeAlignments.LeftBottom;
|
||||
|
||||
if (roleBehaviour is ICustomRole role)
|
||||
{
|
||||
__instance.ImpostorVentButton.gameObject.SetActive(isActive && role.CanUseVent);
|
||||
}
|
||||
foreach (var button in CustomButtonManager.CustomButtons)
|
||||
{
|
||||
button.CreateButton(_bottomLeft.transform);
|
||||
}
|
||||
|
||||
gridArrange.Start();
|
||||
gridArrange.ArrangeChilds();
|
||||
|
||||
aspectPosition.AdjustPosition();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Make sure all launchpad hud elements are inactive/active when appropriate
|
||||
/// </summary>
|
||||
[HarmonyPostfix]
|
||||
[HarmonyPatch(nameof(HudManager.SetHudActive), typeof(PlayerControl), typeof(RoleBehaviour), typeof(bool))]
|
||||
public static void SetHudActivePostfix(HudManager __instance, [HarmonyArgument(0)] PlayerControl player, [HarmonyArgument(1)] RoleBehaviour roleBehaviour, [HarmonyArgument(2)] bool isActive)
|
||||
{
|
||||
if (player.Data == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (_roleTab)
|
||||
{
|
||||
_roleTab.gameObject.SetActive(isActive);
|
||||
}
|
||||
|
||||
foreach (var button in CustomButtonManager.CustomButtons)
|
||||
button.SetActive(isActive, roleBehaviour);
|
||||
|
||||
if (roleBehaviour is ICustomRole role)
|
||||
{
|
||||
__instance.ImpostorVentButton.gameObject.SetActive(isActive && role.CanUseVent);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,61 +2,60 @@
|
||||
using Il2CppSystem;
|
||||
using MiraAPI.Utilities;
|
||||
|
||||
namespace MiraAPI.Patches.Options
|
||||
namespace MiraAPI.Patches.Options;
|
||||
|
||||
[HarmonyPatch]
|
||||
public static class OptionsPatches
|
||||
{
|
||||
[HarmonyPatch]
|
||||
public static class OptionsPatches
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(ToggleOption), nameof(ToggleOption.Initialize))]
|
||||
public static bool ToggleInit(ToggleOption __instance)
|
||||
{
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(ToggleOption), nameof(ToggleOption.Initialize))]
|
||||
public static bool ToggleInit(ToggleOption __instance)
|
||||
{
|
||||
if (!__instance.IsCustom()) return true;
|
||||
__instance.TitleText.text = DestroyableSingleton<TranslationController>.Instance.GetString(__instance.Title, Array.Empty<Object>());
|
||||
if (!__instance.IsCustom()) return true;
|
||||
__instance.TitleText.text = DestroyableSingleton<TranslationController>.Instance.GetString(__instance.Title, Array.Empty<Object>());
|
||||
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(ToggleOption), nameof(ToggleOption.UpdateValue))]
|
||||
public static bool ToggleUpdate(ToggleOption __instance)
|
||||
{
|
||||
return !__instance.IsCustom();
|
||||
}
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(ToggleOption), nameof(ToggleOption.UpdateValue))]
|
||||
public static bool ToggleUpdate(ToggleOption __instance)
|
||||
{
|
||||
return !__instance.IsCustom();
|
||||
}
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(NumberOption), nameof(NumberOption.Initialize))]
|
||||
public static bool NumberInit(NumberOption __instance)
|
||||
{
|
||||
if (!__instance.IsCustom()) return true;
|
||||
__instance.TitleText.text = DestroyableSingleton<TranslationController>.Instance.GetString(__instance.Title, Array.Empty<Object>());
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(NumberOption), nameof(NumberOption.Initialize))]
|
||||
public static bool NumberInit(NumberOption __instance)
|
||||
{
|
||||
if (!__instance.IsCustom()) return true;
|
||||
__instance.TitleText.text = DestroyableSingleton<TranslationController>.Instance.GetString(__instance.Title, Array.Empty<Object>());
|
||||
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(NumberOption), nameof(NumberOption.UpdateValue))]
|
||||
public static bool NumberUpdate(NumberOption __instance)
|
||||
{
|
||||
return !__instance.IsCustom();
|
||||
}
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(NumberOption), nameof(NumberOption.UpdateValue))]
|
||||
public static bool NumberUpdate(NumberOption __instance)
|
||||
{
|
||||
return !__instance.IsCustom();
|
||||
}
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(StringOption), nameof(StringOption.Initialize))]
|
||||
public static bool StringInit(StringOption __instance)
|
||||
{
|
||||
if (!__instance.IsCustom()) return true;
|
||||
__instance.TitleText.text = DestroyableSingleton<TranslationController>.Instance.GetString(__instance.Title, Array.Empty<Object>());
|
||||
__instance.ValueText.text = DestroyableSingleton<TranslationController>.Instance.GetString(__instance.Values[__instance.Value], Array.Empty<Object>());
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(StringOption), nameof(StringOption.Initialize))]
|
||||
public static bool StringInit(StringOption __instance)
|
||||
{
|
||||
if (!__instance.IsCustom()) return true;
|
||||
__instance.TitleText.text = DestroyableSingleton<TranslationController>.Instance.GetString(__instance.Title, Array.Empty<Object>());
|
||||
__instance.ValueText.text = DestroyableSingleton<TranslationController>.Instance.GetString(__instance.Values[__instance.Value], Array.Empty<Object>());
|
||||
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(StringOption), nameof(StringOption.UpdateValue))]
|
||||
public static bool StringUpdate(StringOption __instance)
|
||||
{
|
||||
return !__instance.IsCustom();
|
||||
}
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(StringOption), nameof(StringOption.UpdateValue))]
|
||||
public static bool StringUpdate(StringOption __instance)
|
||||
{
|
||||
return !__instance.IsCustom();
|
||||
}
|
||||
}
|
||||
@@ -14,206 +14,205 @@ using UnityEngine.Events;
|
||||
using static UnityEngine.UI.Button;
|
||||
using Object = UnityEngine.Object;
|
||||
|
||||
namespace MiraAPI.Patches.Options
|
||||
namespace MiraAPI.Patches.Options;
|
||||
|
||||
[HarmonyPatch(typeof(RolesSettingsMenu))]
|
||||
public static class RoleSettingMenuPatches
|
||||
{
|
||||
[HarmonyPatch(typeof(RolesSettingsMenu))]
|
||||
public static class RoleSettingMenuPatches
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(nameof(RolesSettingsMenu.SetQuotaTab))]
|
||||
public static bool PatchStart(RolesSettingsMenu __instance)
|
||||
{
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(nameof(RolesSettingsMenu.SetQuotaTab))]
|
||||
public static bool PatchStart(RolesSettingsMenu __instance)
|
||||
{
|
||||
__instance.roleChances = new Il2CppSystem.Collections.Generic.List<RoleOptionSetting>();
|
||||
__instance.advancedSettingChildren = new Il2CppSystem.Collections.Generic.List<OptionBehaviour>();
|
||||
__instance.roleChances = new Il2CppSystem.Collections.Generic.List<RoleOptionSetting>();
|
||||
__instance.advancedSettingChildren = new Il2CppSystem.Collections.Generic.List<OptionBehaviour>();
|
||||
|
||||
var maskBg = __instance.scrollBar.transform.FindChild("MaskBg");
|
||||
var maskBg = __instance.scrollBar.transform.FindChild("MaskBg");
|
||||
|
||||
if (GameSettingMenuPatches.currentSelectedMod == 0)
|
||||
{
|
||||
__instance.AllButton.transform.parent.gameObject.SetActive(true);
|
||||
__instance.AllButton.gameObject.SetActive(true);
|
||||
__instance.scrollBar.transform.localPosition = new Vector3(-1.4957f, 0.657f, -4);
|
||||
maskBg.localPosition = new Vector3(1.5353f, -.5734f, -.1f);
|
||||
maskBg.localScale = new Vector3(6.6811f, 3.3563f, 0.5598f);
|
||||
return true;
|
||||
}
|
||||
|
||||
float num = 0.522f;
|
||||
|
||||
__instance.AllButton.transform.parent.gameObject.SetActive(false);
|
||||
__instance.AllButton.gameObject.SetActive(false);
|
||||
__instance.scrollBar.transform.localPosition = new Vector3(-1.4957f, 1.5261f, -4);
|
||||
maskBg.localPosition = new Vector3(1.5353f, -1.0607f, -.1f);
|
||||
maskBg.localScale = new Vector3(6.6811f, 4.1563f, 0.5598f);
|
||||
|
||||
CategoryHeaderEditRole categoryHeaderEditRole = Object.Instantiate(__instance.categoryHeaderEditRoleOrigin, Vector3.zero, Quaternion.identity, __instance.RoleChancesSettings.transform);
|
||||
categoryHeaderEditRole.SetHeader(StringNames.CrewmateRolesHeader, 20);
|
||||
categoryHeaderEditRole.transform.localPosition = new Vector3(4.986f, num, -2f);
|
||||
num -= 0.522f;
|
||||
int num3 = 0;
|
||||
|
||||
foreach (var role in GameSettingMenuPatches.selectedMod.CustomRoles.Values.OfType<ICustomRole>().Where(role => role.Team == ModdedRoleTeams.Crewmate))
|
||||
{
|
||||
CreateQuotaOption(__instance, role as RoleBehaviour, ref num, num3);
|
||||
num3++;
|
||||
}
|
||||
|
||||
num -= 0.4f;
|
||||
CategoryHeaderEditRole categoryHeaderEditRole2 = Object.Instantiate(__instance.categoryHeaderEditRoleOrigin, Vector3.zero, Quaternion.identity, __instance.RoleChancesSettings.transform);
|
||||
categoryHeaderEditRole2.SetHeader(StringNames.ImpostorRolesHeader, 20);
|
||||
categoryHeaderEditRole2.transform.localPosition = new Vector3(4.986f, num, -2f);
|
||||
num -= 0.522f;
|
||||
|
||||
|
||||
foreach (var role in GameSettingMenuPatches.selectedMod.CustomRoles.Values.OfType<ICustomRole>().Where(role => role.Team == ModdedRoleTeams.Impostor))
|
||||
{
|
||||
CreateQuotaOption(__instance, role as RoleBehaviour, ref num, num3);
|
||||
num3++;
|
||||
}
|
||||
|
||||
num -= 0.8f;
|
||||
CategoryHeaderEditRole categoryHeaderEditRole3 = Object.Instantiate(__instance.categoryHeaderEditRoleOrigin, Vector3.zero, Quaternion.identity, __instance.RoleChancesSettings.transform);
|
||||
categoryHeaderEditRole3.SetHeader(StringNames.None, 20);
|
||||
categoryHeaderEditRole3.Title.text = "Neutral Roles";
|
||||
categoryHeaderEditRole3.transform.localPosition = new Vector3(4.986f, num, -2f);
|
||||
num -= 0.522f;
|
||||
|
||||
|
||||
foreach (var role in GameSettingMenuPatches.selectedMod.CustomRoles.Values.OfType<ICustomRole>().Where(role => role.Team == ModdedRoleTeams.Neutral))
|
||||
{
|
||||
CreateQuotaOption(__instance, role as RoleBehaviour, ref num, num3);
|
||||
num3++;
|
||||
}
|
||||
|
||||
return false;
|
||||
if (GameSettingMenuPatches.currentSelectedMod == 0)
|
||||
{
|
||||
__instance.AllButton.transform.parent.gameObject.SetActive(true);
|
||||
__instance.AllButton.gameObject.SetActive(true);
|
||||
__instance.scrollBar.transform.localPosition = new Vector3(-1.4957f, 0.657f, -4);
|
||||
maskBg.localPosition = new Vector3(1.5353f, -.5734f, -.1f);
|
||||
maskBg.localScale = new Vector3(6.6811f, 3.3563f, 0.5598f);
|
||||
return true;
|
||||
}
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(nameof(RolesSettingsMenu.Update))]
|
||||
public static bool UpdatePatch()
|
||||
{
|
||||
if (GameSettingMenuPatches.currentSelectedMod == 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
float num = 0.522f;
|
||||
|
||||
return false;
|
||||
__instance.AllButton.transform.parent.gameObject.SetActive(false);
|
||||
__instance.AllButton.gameObject.SetActive(false);
|
||||
__instance.scrollBar.transform.localPosition = new Vector3(-1.4957f, 1.5261f, -4);
|
||||
maskBg.localPosition = new Vector3(1.5353f, -1.0607f, -.1f);
|
||||
maskBg.localScale = new Vector3(6.6811f, 4.1563f, 0.5598f);
|
||||
|
||||
CategoryHeaderEditRole categoryHeaderEditRole = Object.Instantiate(__instance.categoryHeaderEditRoleOrigin, Vector3.zero, Quaternion.identity, __instance.RoleChancesSettings.transform);
|
||||
categoryHeaderEditRole.SetHeader(StringNames.CrewmateRolesHeader, 20);
|
||||
categoryHeaderEditRole.transform.localPosition = new Vector3(4.986f, num, -2f);
|
||||
num -= 0.522f;
|
||||
int num3 = 0;
|
||||
|
||||
foreach (var role in GameSettingMenuPatches.selectedMod.CustomRoles.Values.OfType<ICustomRole>().Where(role => role.Team == ModdedRoleTeams.Crewmate))
|
||||
{
|
||||
CreateQuotaOption(__instance, role as RoleBehaviour, ref num, num3);
|
||||
num3++;
|
||||
}
|
||||
|
||||
private static void ValueChanged(OptionBehaviour obj)
|
||||
num -= 0.4f;
|
||||
CategoryHeaderEditRole categoryHeaderEditRole2 = Object.Instantiate(__instance.categoryHeaderEditRoleOrigin, Vector3.zero, Quaternion.identity, __instance.RoleChancesSettings.transform);
|
||||
categoryHeaderEditRole2.SetHeader(StringNames.ImpostorRolesHeader, 20);
|
||||
categoryHeaderEditRole2.transform.localPosition = new Vector3(4.986f, num, -2f);
|
||||
num -= 0.522f;
|
||||
|
||||
|
||||
foreach (var role in GameSettingMenuPatches.selectedMod.CustomRoles.Values.OfType<ICustomRole>().Where(role => role.Team == ModdedRoleTeams.Impostor))
|
||||
{
|
||||
var roleSetting = obj.Cast<RoleOptionSetting>();
|
||||
var role = roleSetting.Role as ICustomRole;
|
||||
if (role is null or { HideSettings: true }) return;
|
||||
|
||||
PluginSingleton<MiraApiPlugin>.Instance.Config.TryGetEntry<int>(role.NumConfigDefinition, out var numEntry);
|
||||
numEntry.Value = roleSetting.RoleMaxCount;
|
||||
|
||||
PluginSingleton<MiraApiPlugin>.Instance.Config.TryGetEntry<int>(role.ChanceConfigDefinition, out var chanceEntry);
|
||||
chanceEntry.Value = roleSetting.RoleChance;
|
||||
|
||||
roleSetting.UpdateValuesAndText(GameOptionsManager.Instance.CurrentGameOptions.RoleOptions);
|
||||
DestroyableSingleton<HudManager>.Instance.Notifier.AddRoleSettingsChangeMessage(roleSetting.Role.StringName, roleSetting.RoleMaxCount, roleSetting.RoleChance, roleSetting.Role.TeamType, false);
|
||||
|
||||
if (AmongUsClient.Instance.AmHost)
|
||||
{
|
||||
Rpc<SyncRoleOptionsRpc>.Instance.Send(PlayerControl.LocalPlayer, [role.GetNetData(roleSetting.Role)], true);
|
||||
}
|
||||
GameOptionsManager.Instance.GameHostOptions = GameOptionsManager.Instance.CurrentGameOptions;
|
||||
CreateQuotaOption(__instance, role as RoleBehaviour, ref num, num3);
|
||||
num3++;
|
||||
}
|
||||
|
||||
private static void CreateAdvancedSettings(RolesSettingsMenu __instance, RoleBehaviour role)
|
||||
num -= 0.8f;
|
||||
CategoryHeaderEditRole categoryHeaderEditRole3 = Object.Instantiate(__instance.categoryHeaderEditRoleOrigin, Vector3.zero, Quaternion.identity, __instance.RoleChancesSettings.transform);
|
||||
categoryHeaderEditRole3.SetHeader(StringNames.None, 20);
|
||||
categoryHeaderEditRole3.Title.text = "Neutral Roles";
|
||||
categoryHeaderEditRole3.transform.localPosition = new Vector3(4.986f, num, -2f);
|
||||
num -= 0.522f;
|
||||
|
||||
|
||||
foreach (var role in GameSettingMenuPatches.selectedMod.CustomRoles.Values.OfType<ICustomRole>().Where(role => role.Team == ModdedRoleTeams.Neutral))
|
||||
{
|
||||
foreach (var option in __instance.advancedSettingChildren)
|
||||
{
|
||||
Object.Destroy(option.gameObject);
|
||||
}
|
||||
|
||||
__instance.advancedSettingChildren.Clear();
|
||||
|
||||
float num = -0.872f;
|
||||
foreach (var option in GameSettingMenuPatches.selectedMod.Options.Where(option => option.AdvancedRole == role.GetType()))
|
||||
{
|
||||
OptionBehaviour newOpt = option.CreateOption(__instance.checkboxOrigin, __instance.numberOptionOrigin, __instance.stringOptionOrigin, __instance.AdvancedRolesSettings.transform);
|
||||
newOpt.transform.localPosition = new Vector3(2.17f, num, -2f);
|
||||
newOpt.SetClickMask(__instance.ButtonClickMask);
|
||||
|
||||
SpriteRenderer[] componentsInChildren = newOpt.GetComponentsInChildren<SpriteRenderer>(true);
|
||||
for (int i = 0; i < componentsInChildren.Length; i++)
|
||||
{
|
||||
componentsInChildren[i].material.SetInt(PlayerMaterial.MaskLayer, 20);
|
||||
}
|
||||
foreach (TextMeshPro textMeshPro in newOpt.GetComponentsInChildren<TextMeshPro>(true))
|
||||
{
|
||||
textMeshPro.fontMaterial.SetFloat(ShaderID._StencilComp, 3f);
|
||||
textMeshPro.fontMaterial.SetFloat(ShaderID._Stencil, 20);
|
||||
}
|
||||
|
||||
newOpt.LabelBackground.enabled = false;
|
||||
__instance.advancedSettingChildren.Add(newOpt);
|
||||
|
||||
num += -0.45f;
|
||||
newOpt.Initialize();
|
||||
}
|
||||
|
||||
__instance.scrollBar.CalculateAndSetYBounds((float)(__instance.advancedSettingChildren.Count + 3), 1f, 6f, 0.45f);
|
||||
}
|
||||
private static void ChangeTab(RoleBehaviour role, RolesSettingsMenu __instance)
|
||||
{
|
||||
ICustomRole customRole = role as ICustomRole;
|
||||
__instance.roleDescriptionText.text = customRole.RoleLongDescription;
|
||||
__instance.roleTitleText.text = DestroyableSingleton<TranslationController>.Instance.GetString(role.StringName, Array.Empty<Il2CppSystem.Object>());
|
||||
__instance.roleScreenshot.sprite = Sprite.Create(role.RoleScreenshot.texture, new Rect(0, 0, 370, 230), Vector2.one / 2, 100);
|
||||
__instance.roleScreenshot.drawMode = SpriteDrawMode.Sliced;
|
||||
__instance.roleHeaderSprite.color = customRole.RoleColor;
|
||||
__instance.roleHeaderText.color = customRole.RoleColor.DarkenColor();
|
||||
|
||||
CreateAdvancedSettings(__instance, role);
|
||||
|
||||
foreach (var optionBehaviour in __instance.advancedSettingChildren)
|
||||
{
|
||||
optionBehaviour.OnValueChanged = new Action<OptionBehaviour>(__instance.ValueChanged);
|
||||
if (AmongUsClient.Instance && !AmongUsClient.Instance.AmHost)
|
||||
{
|
||||
optionBehaviour.SetAsPlayer();
|
||||
}
|
||||
}
|
||||
__instance.RoleChancesSettings.SetActive(false);
|
||||
__instance.AdvancedRolesSettings.SetActive(true);
|
||||
__instance.RefreshChildren();
|
||||
CreateQuotaOption(__instance, role as RoleBehaviour, ref num, num3);
|
||||
num3++;
|
||||
}
|
||||
|
||||
public static void CreateQuotaOption(RolesSettingsMenu __instance, RoleBehaviour role, ref float yPos, int index)
|
||||
return false;
|
||||
}
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(nameof(RolesSettingsMenu.Update))]
|
||||
public static bool UpdatePatch()
|
||||
{
|
||||
if (GameSettingMenuPatches.currentSelectedMod == 0)
|
||||
{
|
||||
ICustomRole customRole = role as ICustomRole;
|
||||
RoleOptionSetting roleOptionSetting = Object.Instantiate(__instance.roleOptionSettingOrigin, Vector3.zero, Quaternion.identity, __instance.RoleChancesSettings.transform);
|
||||
roleOptionSetting.transform.localPosition = new Vector3(-0.15f, yPos, -2f);
|
||||
roleOptionSetting.SetRole(GameOptionsManager.Instance.CurrentGameOptions.RoleOptions, role, 20);
|
||||
roleOptionSetting.labelSprite.color = customRole.RoleColor;
|
||||
roleOptionSetting.titleText.color = customRole.RoleColor.DarkenColor();
|
||||
roleOptionSetting.OnValueChanged = new Action<OptionBehaviour>(ValueChanged);
|
||||
roleOptionSetting.titleText.horizontalAlignment = HorizontalAlignmentOptions.Left;
|
||||
roleOptionSetting.SetClickMask(__instance.ButtonClickMask);
|
||||
__instance.roleChances.Add(roleOptionSetting);
|
||||
return true;
|
||||
}
|
||||
|
||||
PassiveButton newButton = Object.Instantiate(roleOptionSetting.buttons[0], roleOptionSetting.transform);
|
||||
newButton.name = "ConfigButton";
|
||||
newButton.transform.localPosition = new Vector3(0.2419f, -0.2582f, -2f);
|
||||
newButton.transform.FindChild("Plus_TMP").gameObject.DestroyImmediate();
|
||||
newButton.transform.FindChild("InactiveSprite").GetComponent<SpriteRenderer>().sprite = MiraAssets.Cog.LoadAsset();
|
||||
newButton.transform.FindChild("ActiveSprite").GetComponent<SpriteRenderer>().sprite = MiraAssets.CogActive.LoadAsset();
|
||||
return false;
|
||||
}
|
||||
|
||||
PassiveButton passiveButton = newButton.GetComponent<PassiveButton>();
|
||||
passiveButton.OnClick = new ButtonClickedEvent();
|
||||
passiveButton.OnClick.AddListener((UnityAction)(() =>
|
||||
private static void ValueChanged(OptionBehaviour obj)
|
||||
{
|
||||
var roleSetting = obj.Cast<RoleOptionSetting>();
|
||||
var role = roleSetting.Role as ICustomRole;
|
||||
if (role is null or { HideSettings: true }) return;
|
||||
|
||||
PluginSingleton<MiraApiPlugin>.Instance.Config.TryGetEntry<int>(role.NumConfigDefinition, out var numEntry);
|
||||
numEntry.Value = roleSetting.RoleMaxCount;
|
||||
|
||||
PluginSingleton<MiraApiPlugin>.Instance.Config.TryGetEntry<int>(role.ChanceConfigDefinition, out var chanceEntry);
|
||||
chanceEntry.Value = roleSetting.RoleChance;
|
||||
|
||||
roleSetting.UpdateValuesAndText(GameOptionsManager.Instance.CurrentGameOptions.RoleOptions);
|
||||
DestroyableSingleton<HudManager>.Instance.Notifier.AddRoleSettingsChangeMessage(roleSetting.Role.StringName, roleSetting.RoleMaxCount, roleSetting.RoleChance, roleSetting.Role.TeamType, false);
|
||||
|
||||
if (AmongUsClient.Instance.AmHost)
|
||||
{
|
||||
Rpc<SyncRoleOptionsRpc>.Instance.Send(PlayerControl.LocalPlayer, [role.GetNetData(roleSetting.Role)], true);
|
||||
}
|
||||
GameOptionsManager.Instance.GameHostOptions = GameOptionsManager.Instance.CurrentGameOptions;
|
||||
}
|
||||
|
||||
private static void CreateAdvancedSettings(RolesSettingsMenu __instance, RoleBehaviour role)
|
||||
{
|
||||
foreach (var option in __instance.advancedSettingChildren)
|
||||
{
|
||||
Object.Destroy(option.gameObject);
|
||||
}
|
||||
|
||||
__instance.advancedSettingChildren.Clear();
|
||||
|
||||
float num = -0.872f;
|
||||
foreach (var option in GameSettingMenuPatches.selectedMod.Options.Where(option => option.AdvancedRole == role.GetType()))
|
||||
{
|
||||
OptionBehaviour newOpt = option.CreateOption(__instance.checkboxOrigin, __instance.numberOptionOrigin, __instance.stringOptionOrigin, __instance.AdvancedRolesSettings.transform);
|
||||
newOpt.transform.localPosition = new Vector3(2.17f, num, -2f);
|
||||
newOpt.SetClickMask(__instance.ButtonClickMask);
|
||||
|
||||
SpriteRenderer[] componentsInChildren = newOpt.GetComponentsInChildren<SpriteRenderer>(true);
|
||||
for (int i = 0; i < componentsInChildren.Length; i++)
|
||||
{
|
||||
ChangeTab(role, __instance);
|
||||
}));
|
||||
|
||||
if (index < GameSettingMenuPatches.selectedMod.CustomRoles.Count - 1)
|
||||
{
|
||||
yPos += -0.43f;
|
||||
componentsInChildren[i].material.SetInt(PlayerMaterial.MaskLayer, 20);
|
||||
}
|
||||
foreach (TextMeshPro textMeshPro in newOpt.GetComponentsInChildren<TextMeshPro>(true))
|
||||
{
|
||||
textMeshPro.fontMaterial.SetFloat(ShaderID._StencilComp, 3f);
|
||||
textMeshPro.fontMaterial.SetFloat(ShaderID._Stencil, 20);
|
||||
}
|
||||
|
||||
newOpt.LabelBackground.enabled = false;
|
||||
__instance.advancedSettingChildren.Add(newOpt);
|
||||
|
||||
num += -0.45f;
|
||||
newOpt.Initialize();
|
||||
}
|
||||
|
||||
__instance.scrollBar.CalculateAndSetYBounds((float)(__instance.advancedSettingChildren.Count + 3), 1f, 6f, 0.45f);
|
||||
}
|
||||
private static void ChangeTab(RoleBehaviour role, RolesSettingsMenu __instance)
|
||||
{
|
||||
ICustomRole customRole = role as ICustomRole;
|
||||
__instance.roleDescriptionText.text = customRole.RoleLongDescription;
|
||||
__instance.roleTitleText.text = DestroyableSingleton<TranslationController>.Instance.GetString(role.StringName, Array.Empty<Il2CppSystem.Object>());
|
||||
__instance.roleScreenshot.sprite = Sprite.Create(role.RoleScreenshot.texture, new Rect(0, 0, 370, 230), Vector2.one / 2, 100);
|
||||
__instance.roleScreenshot.drawMode = SpriteDrawMode.Sliced;
|
||||
__instance.roleHeaderSprite.color = customRole.RoleColor;
|
||||
__instance.roleHeaderText.color = customRole.RoleColor.DarkenColor();
|
||||
|
||||
CreateAdvancedSettings(__instance, role);
|
||||
|
||||
foreach (var optionBehaviour in __instance.advancedSettingChildren)
|
||||
{
|
||||
optionBehaviour.OnValueChanged = new Action<OptionBehaviour>(__instance.ValueChanged);
|
||||
if (AmongUsClient.Instance && !AmongUsClient.Instance.AmHost)
|
||||
{
|
||||
optionBehaviour.SetAsPlayer();
|
||||
}
|
||||
}
|
||||
__instance.RoleChancesSettings.SetActive(false);
|
||||
__instance.AdvancedRolesSettings.SetActive(true);
|
||||
__instance.RefreshChildren();
|
||||
}
|
||||
|
||||
public static void CreateQuotaOption(RolesSettingsMenu __instance, RoleBehaviour role, ref float yPos, int index)
|
||||
{
|
||||
ICustomRole customRole = role as ICustomRole;
|
||||
RoleOptionSetting roleOptionSetting = Object.Instantiate(__instance.roleOptionSettingOrigin, Vector3.zero, Quaternion.identity, __instance.RoleChancesSettings.transform);
|
||||
roleOptionSetting.transform.localPosition = new Vector3(-0.15f, yPos, -2f);
|
||||
roleOptionSetting.SetRole(GameOptionsManager.Instance.CurrentGameOptions.RoleOptions, role, 20);
|
||||
roleOptionSetting.labelSprite.color = customRole.RoleColor;
|
||||
roleOptionSetting.titleText.color = customRole.RoleColor.DarkenColor();
|
||||
roleOptionSetting.OnValueChanged = new Action<OptionBehaviour>(ValueChanged);
|
||||
roleOptionSetting.titleText.horizontalAlignment = HorizontalAlignmentOptions.Left;
|
||||
roleOptionSetting.SetClickMask(__instance.ButtonClickMask);
|
||||
__instance.roleChances.Add(roleOptionSetting);
|
||||
|
||||
PassiveButton newButton = Object.Instantiate(roleOptionSetting.buttons[0], roleOptionSetting.transform);
|
||||
newButton.name = "ConfigButton";
|
||||
newButton.transform.localPosition = new Vector3(0.2419f, -0.2582f, -2f);
|
||||
newButton.transform.FindChild("Plus_TMP").gameObject.DestroyImmediate();
|
||||
newButton.transform.FindChild("InactiveSprite").GetComponent<SpriteRenderer>().sprite = MiraAssets.Cog.LoadAsset();
|
||||
newButton.transform.FindChild("ActiveSprite").GetComponent<SpriteRenderer>().sprite = MiraAssets.CogActive.LoadAsset();
|
||||
|
||||
PassiveButton passiveButton = newButton.GetComponent<PassiveButton>();
|
||||
passiveButton.OnClick = new ButtonClickedEvent();
|
||||
passiveButton.OnClick.AddListener((UnityAction)(() =>
|
||||
{
|
||||
ChangeTab(role, __instance);
|
||||
}));
|
||||
|
||||
if (index < GameSettingMenuPatches.selectedMod.CustomRoles.Count - 1)
|
||||
{
|
||||
yPos += -0.43f;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,8 @@
|
||||
using BepInEx.Configuration;
|
||||
|
||||
namespace MiraAPI.PluginLoading
|
||||
namespace MiraAPI.PluginLoading;
|
||||
|
||||
public interface IMiraPlugin
|
||||
{
|
||||
public interface IMiraPlugin
|
||||
{
|
||||
public ConfigFile GetConfigFile();
|
||||
}
|
||||
}
|
||||
public ConfigFile GetConfigFile();
|
||||
}
|
||||
@@ -22,6 +22,7 @@ public interface ICustomRole
|
||||
Color RoleColor { get; }
|
||||
|
||||
ModdedRoleTeams Team { get; }
|
||||
|
||||
LoadableAsset<Sprite> OptionsScreenshot { get; }
|
||||
|
||||
LoadableAsset<Sprite> Icon => MiraAssets.Empty;
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
namespace MiraAPI.Roles
|
||||
namespace MiraAPI.Roles;
|
||||
|
||||
public enum ModdedRoleTeams
|
||||
{
|
||||
public enum ModdedRoleTeams
|
||||
{
|
||||
Crewmate,
|
||||
Impostor,
|
||||
Neutral
|
||||
}
|
||||
}
|
||||
Crewmate,
|
||||
Impostor,
|
||||
Neutral
|
||||
}
|
||||
@@ -1,22 +1,21 @@
|
||||
namespace MiraAPI.Utilities.Assets
|
||||
namespace MiraAPI.Utilities.Assets;
|
||||
|
||||
/// <summary>
|
||||
/// An abstract class that provides a simple pattern for loading assets.
|
||||
/// Mira uses the <see cref="LoadableAsset{T}"/> pattern in various locations.
|
||||
/// You can create your own implementation of this class to load assets in different ways.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the asset to be loaded</typeparam>
|
||||
public abstract class LoadableAsset<T> where T : UnityEngine.Object
|
||||
{
|
||||
/// <summary>
|
||||
/// An abstract class that provides a simple pattern for loading assets.
|
||||
/// Mira uses the <see cref="LoadableAsset{T}"/> pattern in various locations.
|
||||
/// You can create your own implementation of this class to load assets in different ways.
|
||||
/// A reference to the loaded asset. Intended to be used for caching purposes.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the asset to be loaded</typeparam>
|
||||
public abstract class LoadableAsset<T> where T : UnityEngine.Object
|
||||
{
|
||||
/// <summary>
|
||||
/// A reference to the loaded asset. Intended to be used for caching purposes.
|
||||
/// </summary>
|
||||
protected T LoadedAsset;
|
||||
protected T LoadedAsset;
|
||||
|
||||
/// <summary>
|
||||
/// The method that loads the asset.
|
||||
/// </summary>
|
||||
/// <returns>The loaded asset</returns>
|
||||
public abstract T LoadAsset();
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// The method that loads the asset.
|
||||
/// </summary>
|
||||
/// <returns>The loaded asset</returns>
|
||||
public abstract T LoadAsset();
|
||||
}
|
||||
@@ -2,36 +2,35 @@
|
||||
using Reactor.Utilities.Extensions;
|
||||
using UnityEngine;
|
||||
|
||||
namespace MiraAPI.Utilities.Assets
|
||||
namespace MiraAPI.Utilities.Assets;
|
||||
|
||||
/// <summary>
|
||||
/// A utility class for loading assets from an asset bundle.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of the asset</param>
|
||||
/// <param name="bundle">The AssetBundle that contains the asset</param>
|
||||
/// <typeparam name="T">The type of the asset to be loaded</typeparam>
|
||||
public class LoadableBundleAsset<T>(string name, AssetBundle bundle) : LoadableAsset<T> where T : UnityEngine.Object
|
||||
{
|
||||
/// <summary>
|
||||
/// A utility class for loading assets from an asset bundle.
|
||||
/// Loads the asset from the asset bundle.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of the asset</param>
|
||||
/// <param name="bundle">The AssetBundle that contains the asset</param>
|
||||
/// <typeparam name="T">The type of the asset to be loaded</typeparam>
|
||||
public class LoadableBundleAsset<T>(string name, AssetBundle bundle) : LoadableAsset<T> where T : UnityEngine.Object
|
||||
/// <returns>The asset</returns>
|
||||
/// <exception cref="Exception">The asset did not load properly.</exception>
|
||||
public override T LoadAsset()
|
||||
{
|
||||
/// <summary>
|
||||
/// Loads the asset from the asset bundle.
|
||||
/// </summary>
|
||||
/// <returns>The asset</returns>
|
||||
/// <exception cref="Exception">The asset did not load properly.</exception>
|
||||
public override T LoadAsset()
|
||||
if (LoadedAsset)
|
||||
{
|
||||
if (LoadedAsset)
|
||||
{
|
||||
return LoadedAsset;
|
||||
}
|
||||
|
||||
LoadedAsset = bundle.LoadAsset<T>(name);
|
||||
|
||||
if (!LoadedAsset)
|
||||
{
|
||||
throw new Exception($"INVALID ASSET: {name}");
|
||||
}
|
||||
|
||||
return LoadedAsset;
|
||||
}
|
||||
|
||||
LoadedAsset = bundle.LoadAsset<T>(name);
|
||||
|
||||
if (!LoadedAsset)
|
||||
{
|
||||
throw new Exception($"INVALID ASSET: {name}");
|
||||
}
|
||||
|
||||
return LoadedAsset;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,25 +1,24 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace MiraAPI.Utilities.Assets
|
||||
{
|
||||
public class LoadableResourceAsset(string path) : LoadableAsset<Sprite>
|
||||
{
|
||||
public override Sprite LoadAsset()
|
||||
{
|
||||
if (LoadedAsset != null)
|
||||
{
|
||||
return LoadedAsset;
|
||||
}
|
||||
namespace MiraAPI.Utilities.Assets;
|
||||
|
||||
try
|
||||
{
|
||||
return LoadedAsset = SpriteTools.LoadSpriteFromPath(path);
|
||||
}
|
||||
catch
|
||||
{
|
||||
Debug.LogError($"Not loading, invalid asset: {path}");
|
||||
return null;
|
||||
}
|
||||
public class LoadableResourceAsset(string path) : LoadableAsset<Sprite>
|
||||
{
|
||||
public override Sprite LoadAsset()
|
||||
{
|
||||
if (LoadedAsset != null)
|
||||
{
|
||||
return LoadedAsset;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
return LoadedAsset = SpriteTools.LoadSpriteFromPath(path);
|
||||
}
|
||||
catch
|
||||
{
|
||||
Debug.LogError($"Not loading, invalid asset: {path}");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,12 @@
|
||||
namespace MiraAPI.Utilities.Assets
|
||||
{
|
||||
public static class MiraAssets
|
||||
{
|
||||
public static readonly LoadableResourceAsset Empty = new("");
|
||||
namespace MiraAPI.Utilities.Assets;
|
||||
|
||||
public static readonly LoadableResourceAsset NextButton = new("MiraAPI.Resources.NextButton.png");
|
||||
public static readonly LoadableResourceAsset NextButtonActive = new("MiraAPI.Resources.NextButtonActive.png");
|
||||
public static readonly LoadableResourceAsset Cog = new("MiraAPI.Resources.Cog.png");
|
||||
public static readonly LoadableResourceAsset CogActive = new("MiraAPI.Resources.CogActive.png");
|
||||
public static readonly LoadableResourceAsset Banner = new("MiraAPI.Resources.FortniteBanner.jpeg");
|
||||
}
|
||||
}
|
||||
public static class MiraAssets
|
||||
{
|
||||
public static readonly LoadableResourceAsset Empty = new("");
|
||||
|
||||
public static readonly LoadableResourceAsset NextButton = new("MiraAPI.Resources.NextButton.png");
|
||||
public static readonly LoadableResourceAsset NextButtonActive = new("MiraAPI.Resources.NextButtonActive.png");
|
||||
public static readonly LoadableResourceAsset Cog = new("MiraAPI.Resources.Cog.png");
|
||||
public static readonly LoadableResourceAsset CogActive = new("MiraAPI.Resources.CogActive.png");
|
||||
public static readonly LoadableResourceAsset Banner = new("MiraAPI.Resources.FortniteBanner.jpeg");
|
||||
}
|
||||
@@ -6,48 +6,47 @@ using System.Reflection;
|
||||
using Reactor.Utilities;
|
||||
using UnityEngine;
|
||||
|
||||
namespace MiraAPI.Utilities.Assets
|
||||
namespace MiraAPI.Utilities.Assets;
|
||||
|
||||
/// <summary>
|
||||
/// A utility class for various sprite-related operations.
|
||||
/// </summary>
|
||||
public static class SpriteTools
|
||||
{
|
||||
/// <summary>
|
||||
/// A utility class for various sprite-related operations.
|
||||
/// </summary>
|
||||
public static class SpriteTools
|
||||
private delegate bool DLoadImage(IntPtr tex, IntPtr data, bool markNonReadable);
|
||||
|
||||
private static DLoadImage _iCallLoadImage;
|
||||
|
||||
private static bool LoadImage(Texture2D tex, byte[] data, bool markNonReadable)
|
||||
{
|
||||
private delegate bool DLoadImage(IntPtr tex, IntPtr data, bool markNonReadable);
|
||||
_iCallLoadImage ??= IL2CPP.ResolveICall<DLoadImage>("UnityEngine.ImageConversion::LoadImage");
|
||||
|
||||
private static DLoadImage _iCallLoadImage;
|
||||
var il2CPPArray = (Il2CppStructArray<byte>)data;
|
||||
|
||||
private static bool LoadImage(Texture2D tex, byte[] data, bool markNonReadable)
|
||||
{
|
||||
_iCallLoadImage ??= IL2CPP.ResolveICall<DLoadImage>("UnityEngine.ImageConversion::LoadImage");
|
||||
|
||||
var il2CPPArray = (Il2CppStructArray<byte>)data;
|
||||
|
||||
return _iCallLoadImage.Invoke(tex.Pointer, il2CPPArray.Pointer, markNonReadable);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Load a sprite from a resource path.
|
||||
/// </summary>
|
||||
/// <param name="resourcePath">The path to the resource.</param>
|
||||
/// <returns>A sprite made from the resource</returns>
|
||||
/// <exception cref="Exception">The resource cannot be found.</exception>
|
||||
public static Sprite LoadSpriteFromPath(string resourcePath)
|
||||
{
|
||||
var tex = new Texture2D(1, 1, TextureFormat.ARGB32, false);
|
||||
var assembly = Assembly.GetExecutingAssembly();
|
||||
var myStream = assembly.GetManifestResourceStream(resourcePath);
|
||||
if (myStream != null)
|
||||
{
|
||||
var buttonTexture = myStream.ReadFully();
|
||||
LoadImage(tex, buttonTexture, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger<MiraApiPlugin>.Error($"Resource not found: {resourcePath}\nReturning empty sprite!");
|
||||
}
|
||||
|
||||
return Sprite.Create(tex, new Rect(0, 0, tex.width, tex.height), new Vector2(0.5f, 0.5f));
|
||||
}
|
||||
return _iCallLoadImage.Invoke(tex.Pointer, il2CPPArray.Pointer, markNonReadable);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Load a sprite from a resource path.
|
||||
/// </summary>
|
||||
/// <param name="resourcePath">The path to the resource.</param>
|
||||
/// <returns>A sprite made from the resource</returns>
|
||||
/// <exception cref="Exception">The resource cannot be found.</exception>
|
||||
public static Sprite LoadSpriteFromPath(string resourcePath)
|
||||
{
|
||||
var tex = new Texture2D(1, 1, TextureFormat.ARGB32, false);
|
||||
var assembly = Assembly.GetExecutingAssembly();
|
||||
var myStream = assembly.GetManifestResourceStream(resourcePath);
|
||||
if (myStream != null)
|
||||
{
|
||||
var buttonTexture = myStream.ReadFully();
|
||||
LoadImage(tex, buttonTexture, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger<MiraApiPlugin>.Error($"Resource not found: {resourcePath}\nReturning empty sprite!");
|
||||
}
|
||||
|
||||
return Sprite.Create(tex, new Rect(0, 0, tex.width, tex.height), new Vector2(0.5f, 0.5f));
|
||||
}
|
||||
}
|
||||
@@ -4,93 +4,92 @@ using Reactor.Utilities.Extensions;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
namespace MiraAPI.Utilities
|
||||
namespace MiraAPI.Utilities;
|
||||
|
||||
public static class Extensions
|
||||
{
|
||||
public static class Extensions
|
||||
public static bool IsCustom(this OptionBehaviour optionBehaviour)
|
||||
{
|
||||
public static bool IsCustom(this OptionBehaviour optionBehaviour)
|
||||
return ModdedOptionsManager.Options.Any(opt => opt.OptionBehaviour && opt.OptionBehaviour.Equals(optionBehaviour));
|
||||
}
|
||||
|
||||
public static Color DarkenColor(this Color color)
|
||||
{
|
||||
return new Color(color.r - 0.3f, color.g - 0.3f, color.b - 0.3f);
|
||||
}
|
||||
public static void UpdateBodies(this PlayerControl playerControl, Color outlineColor, ref DeadBody target)
|
||||
{
|
||||
foreach (var body in Object.FindObjectsOfType<DeadBody>())
|
||||
{
|
||||
return ModdedOptionsManager.Options.Any(opt => opt.OptionBehaviour && opt.OptionBehaviour.Equals(optionBehaviour));
|
||||
}
|
||||
|
||||
public static Color DarkenColor(this Color color)
|
||||
{
|
||||
return new Color(color.r - 0.3f, color.g - 0.3f, color.b - 0.3f);
|
||||
}
|
||||
public static void UpdateBodies(this PlayerControl playerControl, Color outlineColor, ref DeadBody target)
|
||||
{
|
||||
foreach (var body in Object.FindObjectsOfType<DeadBody>())
|
||||
foreach (var bodyRenderer in body.bodyRenderers)
|
||||
{
|
||||
foreach (var bodyRenderer in body.bodyRenderers)
|
||||
{
|
||||
bodyRenderer.SetOutline(null);
|
||||
}
|
||||
}
|
||||
|
||||
if (playerControl.Data.Role is not ICustomRole { TargetsBodies: true })
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
target = playerControl.NearestDeadBody();
|
||||
if (!target)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var renderer in target.bodyRenderers)
|
||||
{
|
||||
renderer.SetOutline(outlineColor);
|
||||
bodyRenderer.SetOutline(null);
|
||||
}
|
||||
}
|
||||
|
||||
public static DeadBody NearestDeadBody(this PlayerControl playerControl)
|
||||
if (playerControl.Data.Role is not ICustomRole { TargetsBodies: true })
|
||||
{
|
||||
var results = new Il2CppSystem.Collections.Generic.List<Collider2D>();
|
||||
Physics2D.OverlapCircle(playerControl.GetTruePosition(), playerControl.MaxReportDistance / 4f, Helpers.Filter, results);
|
||||
return results.ToArray()
|
||||
.Where(collider2D => collider2D.CompareTag("DeadBody"))
|
||||
.Select(collider2D => collider2D.GetComponent<DeadBody>())
|
||||
.FirstOrDefault(component => component && !component.Reported);
|
||||
return;
|
||||
}
|
||||
|
||||
public static PlayerControl GetClosestPlayer(this PlayerControl playerControl, bool includeImpostors, float distance)
|
||||
target = playerControl.NearestDeadBody();
|
||||
if (!target)
|
||||
{
|
||||
PlayerControl result = null;
|
||||
if (!ShipStatus.Instance)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
var truePosition = playerControl.GetTruePosition();
|
||||
|
||||
foreach (var playerInfo in GameData.Instance.AllPlayers)
|
||||
{
|
||||
if (playerInfo.Disconnected || playerInfo.PlayerId == playerControl.PlayerId ||
|
||||
playerInfo.IsDead || !includeImpostors && playerInfo.Role.IsImpostor)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var @object = playerInfo.Object;
|
||||
if (!@object)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var vector = @object.GetTruePosition() - truePosition;
|
||||
var magnitude = vector.magnitude;
|
||||
if (!(magnitude <= distance) || PhysicsHelpers.AnyNonTriggersBetween(truePosition,
|
||||
vector.normalized,
|
||||
magnitude, LayerMask.GetMask("Ship", "Objects")))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
result = @object;
|
||||
distance = magnitude;
|
||||
}
|
||||
return result;
|
||||
foreach (var renderer in target.bodyRenderers)
|
||||
{
|
||||
renderer.SetOutline(outlineColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static DeadBody NearestDeadBody(this PlayerControl playerControl)
|
||||
{
|
||||
var results = new Il2CppSystem.Collections.Generic.List<Collider2D>();
|
||||
Physics2D.OverlapCircle(playerControl.GetTruePosition(), playerControl.MaxReportDistance / 4f, Helpers.Filter, results);
|
||||
return results.ToArray()
|
||||
.Where(collider2D => collider2D.CompareTag("DeadBody"))
|
||||
.Select(collider2D => collider2D.GetComponent<DeadBody>())
|
||||
.FirstOrDefault(component => component && !component.Reported);
|
||||
}
|
||||
|
||||
public static PlayerControl GetClosestPlayer(this PlayerControl playerControl, bool includeImpostors, float distance)
|
||||
{
|
||||
PlayerControl result = null;
|
||||
if (!ShipStatus.Instance)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var truePosition = playerControl.GetTruePosition();
|
||||
|
||||
foreach (var playerInfo in GameData.Instance.AllPlayers)
|
||||
{
|
||||
if (playerInfo.Disconnected || playerInfo.PlayerId == playerControl.PlayerId ||
|
||||
playerInfo.IsDead || !includeImpostors && playerInfo.Role.IsImpostor)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var @object = playerInfo.Object;
|
||||
if (!@object)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var vector = @object.GetTruePosition() - truePosition;
|
||||
var magnitude = vector.magnitude;
|
||||
if (!(magnitude <= distance) || PhysicsHelpers.AnyNonTriggersBetween(truePosition,
|
||||
vector.normalized,
|
||||
magnitude, LayerMask.GetMask("Ship", "Objects")))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
result = @object;
|
||||
distance = magnitude;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -3,35 +3,39 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
|
||||
namespace MiraAPI.Utilities
|
||||
namespace MiraAPI.Utilities;
|
||||
|
||||
public static class Helpers
|
||||
{
|
||||
public static class Helpers
|
||||
public static readonly ContactFilter2D Filter = ContactFilter2D.CreateLegacyFilter(Constants.NotShipMask, float.MinValue, float.MaxValue);
|
||||
|
||||
public static PlainShipRoom GetRoom(Vector3 pos)
|
||||
{
|
||||
public static readonly ContactFilter2D Filter = ContactFilter2D.CreateLegacyFilter(Constants.NotShipMask, float.MinValue, float.MaxValue);
|
||||
|
||||
public static PlainShipRoom GetRoom(Vector3 pos)
|
||||
{
|
||||
return ShipStatus.Instance.AllRooms.ToList().Find(room => room.roomArea.OverlapPoint(pos));
|
||||
}
|
||||
|
||||
public static string GetSuffix(NumberSuffixes suffix)
|
||||
{
|
||||
return suffix switch
|
||||
{
|
||||
NumberSuffixes.None => string.Empty,
|
||||
NumberSuffixes.Multiplier => "x",
|
||||
NumberSuffixes.Seconds => "s",
|
||||
_ => string.Empty
|
||||
};
|
||||
}
|
||||
|
||||
public static StringBuilder CreateForRole(ICustomRole role)
|
||||
{
|
||||
var taskStringBuilder = new StringBuilder();
|
||||
taskStringBuilder.AppendLine($"{role.RoleColor.ToTextColor()}You are a <b>{role.RoleName}.</b></color>");
|
||||
taskStringBuilder.Append("<size=70%>");
|
||||
taskStringBuilder.AppendLine($"{role.RoleLongDescription}");
|
||||
return taskStringBuilder;
|
||||
}
|
||||
return ShipStatus.Instance.AllRooms.ToList().Find(room => room.roomArea.OverlapPoint(pos));
|
||||
}
|
||||
}
|
||||
|
||||
public static DeadBody GetBodyById(byte id)
|
||||
{
|
||||
return Object.FindObjectsOfType<DeadBody>().FirstOrDefault(body => body.ParentId == id);
|
||||
}
|
||||
|
||||
public static string GetSuffix(NumberSuffixes suffix)
|
||||
{
|
||||
return suffix switch
|
||||
{
|
||||
NumberSuffixes.None => string.Empty,
|
||||
NumberSuffixes.Multiplier => "x",
|
||||
NumberSuffixes.Seconds => "s",
|
||||
_ => string.Empty
|
||||
};
|
||||
}
|
||||
|
||||
public static StringBuilder CreateForRole(ICustomRole role)
|
||||
{
|
||||
var taskStringBuilder = new StringBuilder();
|
||||
taskStringBuilder.AppendLine($"{role.RoleColor.ToTextColor()}You are a <b>{role.RoleName}.</b></color>");
|
||||
taskStringBuilder.Append("<size=70%>");
|
||||
taskStringBuilder.AppendLine($"{role.RoleLongDescription}");
|
||||
return taskStringBuilder;
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user