Add Custom Icons for Adventurer + Cleanup Code

This commit is contained in:
Gurge44 committed 2024-05-24 15:18:13 +02:00
1 parent 9de147a22c
commit bda1b8a405
5 files changed
+169 -149

No files matched your search

+1 -1
View File
@@ -7,7 +7,7 @@
<Description>EHR</Description>
<Authors>Gurge44</Authors>
<langVersion>preview</langVersion>
<AmongUs>D:\Epic Games\AmongUs</AmongUs>
<AmongUs>E:\Program Files\AmongUs</AmongUs>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<Optimize>True</Optimize>
<AssemblyName>$(MSBuildProjectName)</AssemblyName>
+22 -22
View File
@@ -11,9 +11,9 @@ using UnityEngine;
namespace EHR
{
public class CustomNetObject
internal class CustomNetObject
{
private static readonly Dictionary<int, CustomNetObject> AllObjects = [];
public static readonly Dictionary<int, CustomNetObject> AllObjects = [];
protected readonly int Id = Enumerable.Range(0, int.MaxValue).First(id => !AllObjects.ContainsKey(id));
private PlayerControl PC;
@@ -135,7 +135,7 @@ namespace EHR
public static void FixedUpdate() => AllObjects.Values.Do(x => x.OnFixedUpdate());
}
public class Explosion : CustomNetObject
internal sealed class Explosion : CustomNetObject
{
private readonly float Duration;
@@ -186,7 +186,7 @@ namespace EHR
}
}
public class TrapArea : CustomNetObject
internal sealed class TrapArea : CustomNetObject
{
private readonly float Size;
private readonly float WaitDuration;
@@ -200,11 +200,7 @@ namespace EHR
WaitDuration = waitDuration;
State = 0;
CreateNetObject($"<size={Size}><font=\"VCR SDF\"><#c7c7c769>●", position);
foreach (var pc in Main.AllAlivePlayerControls)
{
if (!visibleList.Contains(pc.PlayerId))
Hide(pc);
}
Main.AllAlivePlayerControls.ExceptBy(visibleList, x => x.PlayerId).Do(Hide);
}
protected override void OnFixedUpdate()
@@ -224,7 +220,7 @@ namespace EHR
}
}
public class TornadoObject : CustomNetObject
internal sealed class TornadoObject : CustomNetObject
{
private readonly long SpawnTimeStamp;
@@ -232,11 +228,7 @@ namespace EHR
{
SpawnTimeStamp = Utils.TimeStamp;
CreateNetObject("<size=100%><font=\"VCR SDF\"><line-height=85%><alpha=#00>\u2588<alpha=#00>\u2588<#bababa>\u2588<#bababa>\u2588<#bababa>\u2588<#bababa>\u2588<alpha=#00>\u2588<alpha=#00>\u2588<br><alpha=#00>\u2588<#bababa>\u2588<#bababa>\u2588<#8c8c8c>\u2588<#8c8c8c>\u2588<#bababa>\u2588<#bababa>\u2588<alpha=#00>\u2588<br><#bababa>\u2588<#bababa>\u2588<#8c8c8c>\u2588<#8c8c8c>\u2588<#8c8c8c>\u2588<#8c8c8c>\u2588<#bababa>\u2588<#bababa>\u2588<br><#bababa>\u2588<#8c8c8c>\u2588<#8c8c8c>\u2588<#636363>\u2588<#636363>\u2588<#8c8c8c>\u2588<#8c8c8c>\u2588<#bababa>\u2588<br><#bababa>\u2588<#8c8c8c>\u2588<#8c8c8c>\u2588<#636363>\u2588<#636363>\u2588<#8c8c8c>\u2588<#8c8c8c>\u2588<#bababa>\u2588<br><#bababa>\u2588<#bababa>\u2588<#8c8c8c>\u2588<#8c8c8c>\u2588<#8c8c8c>\u2588<#8c8c8c>\u2588<#bababa>\u2588<#bababa>\u2588<br><alpha=#00>\u2588<#bababa>\u2588<#bababa>\u2588<#8c8c8c>\u2588<#8c8c8c>\u2588<#bababa>\u2588<#bababa>\u2588<alpha=#00>\u2588<br><alpha=#00>\u2588<alpha=#00>\u2588<#bababa>\u2588<#bababa>\u2588<#bababa>\u2588<#bababa>\u2588<alpha=#00>\u2588<alpha=#00>\u2588<br></color></line-height></font></size>", position);
foreach (var pc in Main.AllAlivePlayerControls)
{
if (!visibleList.Contains(pc.PlayerId))
Hide(pc);
}
Main.AllAlivePlayerControls.ExceptBy(visibleList, x => x.PlayerId).Do(Hide);
}
protected override void OnFixedUpdate()
@@ -246,18 +238,26 @@ namespace EHR
}
}
public class PlayerDetector : CustomNetObject
internal sealed class PlayerDetector : CustomNetObject
{
public PlayerDetector(Vector2 position, List<byte> visibleList, out int id)
{
CreateNetObject("<size=100%><font=\"VCR SDF\"><line-height=85%><alpha=#00>\u2588<alpha=#00>\u2588<#33e6b0>\u2588<alpha=#00>\u2588<alpha=#00>\u2588<#33e6b0>\u2588<alpha=#00>\u2588<alpha=#00>\u2588<br><alpha=#00>\u2588<#33e6b0>\u2588<alpha=#00>\u2588<alpha=#00>\u2588<alpha=#00>\u2588<alpha=#00>\u2588<#33e6b0>\u2588<alpha=#00>\u2588<br><#33e6b0>\u2588<alpha=#00>\u2588<alpha=#00>\u2588<#33e6b0>\u2588<#33e6b0>\u2588<alpha=#00>\u2588<alpha=#00>\u2588<#33e6b0>\u2588<br><#33e6b0>\u2588<alpha=#00>\u2588<#33e6b0>\u2588<#000000>\u2588<#000000>\u2588<#33e6b0>\u2588<alpha=#00>\u2588<#33e6b0>\u2588<br><#33e6b0>\u2588<alpha=#00>\u2588<#33e6b0>\u2588<#000000>\u2588<#000000>\u2588<#33e6b0>\u2588<alpha=#00>\u2588<#33e6b0>\u2588<br><#33e6b0>\u2588<alpha=#00>\u2588<alpha=#00>\u2588<#33e6b0>\u2588<#33e6b0>\u2588<alpha=#00>\u2588<alpha=#00>\u2588<#33e6b0>\u2588<br><alpha=#00>\u2588<#33e6b0>\u2588<alpha=#00>\u2588<alpha=#00>\u2588<alpha=#00>\u2588<alpha=#00>\u2588<#33e6b0>\u2588<alpha=#00>\u2588<br><alpha=#00>\u2588<alpha=#00>\u2588<#33e6b0>\u2588<alpha=#00>\u2588<alpha=#00>\u2588<#33e6b0>\u2588<alpha=#00>\u2588<alpha=#00>\u2588<br></color></line-height></font></size>", position);
foreach (var pc in Main.AllAlivePlayerControls)
{
if (!visibleList.Contains(pc.PlayerId))
Hide(pc);
}
Main.AllAlivePlayerControls.ExceptBy(visibleList, x => x.PlayerId).Do(Hide);
id = Id;
}
}
internal sealed class AdventurerItem : CustomNetObject
{
public readonly Adventurer.Resource Resource;
internal AdventurerItem(Vector2 position, Adventurer.Resource resource, List<byte> visibleList)
{
Resource = resource;
var data = Adventurer.ResourceDisplayData[resource];
CreateNetObject($"<size=300%><font=\"VCR SDF\"><line-height=85%>{Utils.ColorString(data.Color, data.Icon.ToString())}</line-height></font></size>", position);
Main.AllAlivePlayerControls.ExceptBy(visibleList, x => x.PlayerId).Do(Hide);
}
}
}
+108 -110
View File
@@ -9,32 +9,28 @@ namespace EHR;
public class CustomRpcSender
{
public MessageWriter stream;
public readonly string name;
public readonly SendOption sendOption;
public bool isUnsafe;
public delegate void onSendDelegateType();
public onSendDelegateType onSendDelegate;
public State CurrentState
public enum State
{
get { return currentState; }
set
{
if (isUnsafe) currentState = value;
else Logger.Warn("CurrentStateはisUnsafeがtrueの時のみ上書きできます", "CustomRpcSender");
}
BeforeInit = 0, // Cannot do anything before initialization
Ready, // Ready to send StartMessage and SendMessage can be executed
InRootMessage, // State between StartMessage and EndMessage StartRpc and EndMessage can be executed
InRpc, // State between StartRpc and EndRpc Write and EndRpc can be executed
Finished // Nothing can be done after sending
}
private State currentState = State.BeforeInit;
private readonly bool isUnsafe;
private readonly string name;
//0~: targetClientId (GameDataTo)
//-1: 全プレイヤー (GameData)
//-2: 未設定
private readonly OnSendDelegateType onSendDelegate;
public readonly MessageWriter stream;
// 0~: targetClientId (GameDataTo)
// -1: All players (GameData)
// -2: Not set
private int currentRpcTarget;
private State currentState = State.BeforeInit;
private CustomRpcSender()
{
}
@@ -44,7 +40,6 @@ public class CustomRpcSender
stream = MessageWriter.Get(sendOption);
this.name = name;
this.sendOption = sendOption;
this.isUnsafe = isUnsafe;
currentRpcTarget = -2;
onSendDelegate = () => Logger.Info($"{this.name}'s onSendDelegate =>", "CustomRpcSender");
@@ -53,18 +48,104 @@ public class CustomRpcSender
Logger.Info($"\"{name}\" is ready", "CustomRpcSender");
}
public State CurrentState
{
get { return currentState; }
set
{
if (isUnsafe) currentState = value;
else Logger.Warn("CurrentState can only be overwritten when isUnsafe is true", "CustomRpcSender");
}
}
public static CustomRpcSender Create(string name = "No Name Sender", SendOption sendOption = SendOption.None, bool isUnsafe = false)
{
return new(name, sendOption, isUnsafe);
}
public CustomRpcSender AutoStartRpc(
uint targetNetId,
byte callId,
int targetClientId = -1)
{
if (targetClientId == -2) targetClientId = -1;
if (currentState is not State.Ready and not State.InRootMessage)
{
string errorMsg = $"Tried to start RPC automatically, but State is not Ready or InRootMessage (in: \"{name}\")";
if (isUnsafe)
{
Logger.Warn(errorMsg, "CustomRpcSender.Warn");
}
else
{
throw new InvalidOperationException(errorMsg);
}
}
if (currentRpcTarget != targetClientId)
{
// StartMessage processing
if (currentState == State.InRootMessage) EndMessage();
StartMessage(targetClientId);
}
StartRpc(targetNetId, callId);
return this;
}
public void SendMessage()
{
if (currentState == State.InRootMessage) EndMessage();
if (currentState != State.Ready)
{
string errorMsg = $"Tried to send RPC but State is not Ready (in: \"{name}\")";
if (isUnsafe)
{
Logger.Warn(errorMsg, "CustomRpcSender.Warn");
}
else
{
throw new InvalidOperationException(errorMsg);
}
}
AmongUsClient.Instance.SendOrDisconnect(stream);
onSendDelegate();
currentState = State.Finished;
Logger.Info($"\"{name}\" is finished", "CustomRpcSender");
stream.Recycle();
}
private CustomRpcSender Write(Action<MessageWriter> action)
{
if (currentState != State.InRpc)
{
string errorMsg = $"Tried to write RPC, but State is not Write (in: \"{name}\")";
if (isUnsafe)
{
Logger.Warn(errorMsg, "CustomRpcSender.Warn");
}
else
{
throw new InvalidOperationException(errorMsg);
}
}
action(stream);
return this;
}
private delegate void OnSendDelegateType();
#region Start/End Message
public CustomRpcSender StartMessage(int targetClientId = -1)
{
if (currentState != State.Ready)
{
string errorMsg = $"Messageを開始しようとしましたが、StateがReadyではありません (in: \"{name}\")";
string errorMsg = $"Tried to start Message but State is not Ready (in: \"{name}\")";
if (isUnsafe)
{
Logger.Warn(errorMsg, "CustomRpcSender.Warn");
@@ -77,13 +158,13 @@ public class CustomRpcSender
if (targetClientId < 0)
{
// 全員に対するRPC
// RPC for everyone
stream.StartMessage(5);
stream.Write(AmongUsClient.Instance.GameId);
}
else
{
// 特定のクライアントに対するRPC (Desync)
// RPC (Desync) to a specific client
stream.StartMessage(6);
stream.Write(AmongUsClient.Instance.GameId);
stream.WritePacked(targetClientId);
@@ -99,7 +180,7 @@ public class CustomRpcSender
{
if (currentState != State.InRootMessage)
{
string errorMsg = $"Messageを終了しようとしましたが、StateがInRootMessageではありません (in: \"{name}\")";
string errorMsg = $"Tried to exit Message but State is not InRootMessage (in: \"{name}\")";
if (isUnsafe)
{
Logger.Warn(errorMsg, "CustomRpcSender.Warn");
@@ -130,7 +211,7 @@ public class CustomRpcSender
{
if (currentState != State.InRootMessage)
{
string errorMsg = $"RPCを開始しようとしましたが、StateがInRootMessageではありません (in: \"{name}\")";
string errorMsg = $"Tried to start RPC but State is not InRootMessage (in: \"{name}\")";
if (isUnsafe)
{
Logger.Warn(errorMsg, "CustomRpcSender.Warn");
@@ -153,7 +234,7 @@ public class CustomRpcSender
{
if (currentState != State.InRpc)
{
string errorMsg = $"RPCを終了しようとしましたが、StateがInRpcではありません (in: \"{name}\")";
string errorMsg = $"Tried to terminate RPC but State is not InRpc (in: \"{name}\")";
if (isUnsafe)
{
Logger.Warn(errorMsg, "CustomRpcSender.Warn");
@@ -171,60 +252,6 @@ public class CustomRpcSender
#endregion
public CustomRpcSender AutoStartRpc(
uint targetNetId,
byte callId,
int targetClientId = -1)
{
if (targetClientId == -2) targetClientId = -1;
if (currentState is not State.Ready and not State.InRootMessage)
{
string errorMsg = $"RPCを自動で開始しようとしましたが、StateがReadyまたはInRootMessageではありません (in: \"{name}\")";
if (isUnsafe)
{
Logger.Warn(errorMsg, "CustomRpcSender.Warn");
}
else
{
throw new InvalidOperationException(errorMsg);
}
}
if (currentRpcTarget != targetClientId)
{
//StartMessage処理
if (currentState == State.InRootMessage) EndMessage();
StartMessage(targetClientId);
}
StartRpc(targetNetId, callId);
return this;
}
public void SendMessage()
{
if (currentState == State.InRootMessage) EndMessage();
if (currentState != State.Ready)
{
string errorMsg = $"RPCを送信しようとしましたが、StateがReadyではありません (in: \"{name}\")";
if (isUnsafe)
{
Logger.Warn(errorMsg, "CustomRpcSender.Warn");
}
else
{
throw new InvalidOperationException(errorMsg);
}
}
AmongUsClient.Instance.SendOrDisconnect(stream);
onSendDelegate();
currentState = State.Finished;
Logger.Info($"\"{name}\" is finished", "CustomRpcSender");
stream.Recycle();
}
// Write
#region PublicWriteMethods
@@ -246,35 +273,6 @@ public class CustomRpcSender
public CustomRpcSender WriteNetObject(InnerNetObject obj) => Write(w => w.WriteNetObject(obj));
#endregion
private CustomRpcSender Write(Action<MessageWriter> action)
{
if (currentState != State.InRpc)
{
string errorMsg = $"RPCを書き込もうとしましたが、StateがWrite(書き込み中)ではありません (in: \"{name}\")";
if (isUnsafe)
{
Logger.Warn(errorMsg, "CustomRpcSender.Warn");
}
else
{
throw new InvalidOperationException(errorMsg);
}
}
action(stream);
return this;
}
public enum State
{
BeforeInit = 0, //初期化前 何もできない
Ready, //送信準備完了 StartMessageとSendMessageを実行可能
InRootMessage, //StartMessage~EndMessageの間の状態 StartRpcとEndMessageを実行可能
InRpc, //StartRpc~EndRpcの間の状態 WriteとEndRpcを実行可能
Finished, //送信後 何もできない
}
}
public static class CustomRpcSenderExtensions
+36 -13
View File
@@ -10,6 +10,16 @@ namespace EHR.Roles.Crewmate
{
internal class Adventurer : RoleBase
{
public enum Resource
{
TaskCompletion,
Random,
DeadBody,
ShapeshiftSkin,
LightsFix,
Grouping
}
public enum Weapon
{
Gun,
@@ -24,7 +34,7 @@ namespace EHR.Roles.Crewmate
public static bool On;
private static readonly Dictionary<Resource, (char Icon, Color Color)> ResourceDisplayData = new()
public static readonly Dictionary<Resource, (char Icon, Color Color)> ResourceDisplayData = new()
{
{ Resource.TaskCompletion, ('\u2756', Color.blue) },
{ Resource.Random, ('Θ', Color.cyan) },
@@ -67,6 +77,8 @@ namespace EHR.Roles.Crewmate
public HashSet<byte> ShieldedPlayers;
public override bool IsEnable => On;
static void HideObject(Resource resource) => CustomNetObject.AllObjects.Values.FirstOrDefault(x => x is AdventurerItem a && a.Resource == resource)?.Despawn();
static OptionItem CreateWeaponEnabledSetting(int id, Weapon weapon) => BooleanOptionItem.Create(id, $"AdventurerWeaponEnabled.{weapon}", true, TabGroup.CrewmateRoles).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Adventurer]);
public static void SetupCustomOption()
@@ -249,18 +261,32 @@ namespace EHR.Roles.Crewmate
if (LastRandomResourceTimeStamp + 20 <= now && pc.PlayerId != AdventurerPC.PlayerId && IRandom.Instance.Next(50) == 0)
{
if (ResourceLocations.TryGetValue(Resource.Random, out var location))
{
LocateArrow.Remove(AdventurerPC.PlayerId, location);
HideObject(Resource.Random);
}
var pos = pc.Pos();
LocateArrow.Add(AdventurerPC.PlayerId, pos);
ResourceLocations[Resource.Random] = pos;
_ = new AdventurerItem(pos, Resource.Random, [AdventurerPC.PlayerId]);
LastRandomResourceTimeStamp = now;
Utils.NotifyRoles(SpecifySeer: AdventurerPC, SpecifyTarget: AdventurerPC);
}
if (LastGroupingResourceTimeStamp + 20 <= now && Main.AllAlivePlayerControls.Count(x => x.PlayerId != pc.PlayerId && Vector2.Distance(x.Pos(), pc.Pos()) < 2f) >= 2)
{
if (ResourceLocations.TryGetValue(Resource.Grouping, out var location))
{
LocateArrow.Remove(AdventurerPC.PlayerId, location);
HideObject(Resource.Grouping);
}
var pos = pc.Pos();
LocateArrow.Add(AdventurerPC.PlayerId, pos);
ResourceLocations[Resource.Grouping] = pos;
_ = new AdventurerItem(pos, Resource.Grouping, [AdventurerPC.PlayerId]);
LastGroupingResourceTimeStamp = now;
Utils.NotifyRoles(SpecifySeer: AdventurerPC, SpecifyTarget: AdventurerPC);
}
@@ -275,6 +301,7 @@ namespace EHR.Roles.Crewmate
ResourceCounts[resource]++;
Utils.SendRPC(CustomRPC.SyncAdventurer, pc.PlayerId, 3, (int)resource);
ResourceLocations.Remove(resource);
HideObject(resource);
LocateArrow.Remove(pc.PlayerId, location);
var displayData = ResourceDisplayData[resource];
@@ -297,7 +324,10 @@ namespace EHR.Roles.Crewmate
public static void OnAnyoneShapeshiftLoop(Adventurer av, PlayerControl shapeshifter)
{
av.ResourceLocations[Resource.ShapeshiftSkin] = shapeshifter.Pos();
var pos = shapeshifter.Pos();
av.ResourceLocations[Resource.ShapeshiftSkin] = pos;
HideObject(Resource.ShapeshiftSkin);
_ = new AdventurerItem(pos, Resource.ShapeshiftSkin, [av.AdventurerPC.PlayerId]);
}
public static void OnAnyoneDead(PlayerControl target)
@@ -306,7 +336,10 @@ namespace EHR.Roles.Crewmate
{
if (state.Role is Adventurer { IsEnable: true } av)
{
av.ResourceLocations[Resource.DeadBody] = target.Pos();
var pos = target.Pos();
av.ResourceLocations[Resource.DeadBody] = pos;
HideObject(Resource.DeadBody);
_ = new AdventurerItem(pos, Resource.DeadBody, [av.AdventurerPC.PlayerId]);
}
}
}
@@ -380,15 +413,5 @@ namespace EHR.Roles.Crewmate
return finalText;
}
enum Resource
{
TaskCompletion,
Random,
DeadBody,
ShapeshiftSkin,
LightsFix,
Grouping
}
}
}
+2 -3
View File
@@ -235,11 +235,11 @@ public class Main : BasePlugin
EHR.Logger.Disable("NotifyRoles");
EHR.Logger.Disable("SwitchSystem");
EHR.Logger.Disable("ModNews");
EHR.Logger.Disable("CustomRpcSender");
if (!DebugModeManager.AmDebugger)
{
EHR.Logger.Disable("2018k");
EHR.Logger.Disable("Github");
EHR.Logger.Disable("CustomRpcSender");
//EHR.Logger.Disable("ReceiveRPC");
EHR.Logger.Disable("SendRPC");
EHR.Logger.Disable("SetRole");
@@ -258,10 +258,9 @@ public class Main : BasePlugin
}
//EHR.Logger.isDetail = true;
// 認証関連-初期化
// Authentication related - Initialization
DebugKeyAuth = new(DebugKeyHash, DebugKeySalt);
// 認証関連-認証
DebugModeManager.Auth(DebugKeyAuth, DebugKeyInput.Value);
Preset1 = Config.Bind("Preset Name Options", "Preset1", "Preset_1");