-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathmain.cs
269 lines (253 loc) · 10.5 KB
/
main.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
using BepInEx;
using BepInEx.Unity.IL2CPP;
using AmongUs.GameOptions;
using HarmonyLib;
using UnityEngine;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using Hazel;
using System.Linq;
using System;
using ContinuetoEvolve.Patches;
using static ContinuetoEvolve.RoleHelper;
namespace ContinuetoEvolve
{
[BepInPlugin(PluginGuid, PluginName, PluginVersion)]
[BepInProcess("Among Us.exe")]
public class Main : BasePlugin
{
public const string PluginName = "Continue-to-Evolve";
public const string PluginGuid = "com.nemua.cntinue-to-evolve";//なんか入れてもらて
public const string PluginVersion = "0.0.1";//バージョン
public Harmony Harmony { get; } = new Harmony(PluginGuid);
public static bool NoEndGame = true;
public static Dictionary<byte, CustomRoles> PlayerRole = new();
public static Main Instance;
public override void Load()
{
Instance = this;
Log.LogInfo($"{PluginName}Load!");
Harmony.PatchAll();
RoleLoad();
CustomOptionHolder.LoadOptions();
}
[HarmonyPatch(typeof(ModManager), nameof(ModManager.LateUpdate))]
class ModManagerLateUpdatePatch
{
public static void Prefix(ModManager __instance)
{
__instance.ShowModStamp();
}
}
[HarmonyPatch(typeof(MainMenuManager), nameof(MainMenuManager.Start))]
public static class LogoPatch
{
public static SpriteRenderer renderer;
static void Postfix(MainMenuManager __instance)
{
var cte = new GameObject("Logo-CTE");
cte.transform.localPosition = new(2f, 0.5f, 0f);
cte.transform.localScale *= 1.2f;
renderer = cte.AddComponent<SpriteRenderer>();
renderer.sprite = LoadSprite("continue-to-evolve.Resources.Logo.png", 300f);
}
//TOH参考
public static Sprite LoadSprite(string path, float pixelsPerUnit = 1f)
{
Sprite sprite = null;
try
{
var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(path);
var texture = new Texture2D(1, 1, TextureFormat.ARGB32, false);
using MemoryStream ms = new();
stream.CopyTo(ms);
ImageConversion.LoadImage(texture, ms.ToArray());
sprite = Sprite.Create(texture, new(0, 0, texture.width, texture.height), new(0.5f, 0.5f), pixelsPerUnit);
}
catch
{
Debug.LogError($"{path} ?なにそれ?");
}
return sprite;
}
}
}
static class RPC
{
public static void RpcSetNamePrivate(this PlayerControl player, string name, bool DontShowOnModdedClient = false, PlayerControl seer = null, bool force = false)
{//TOHによりお借りしました
//player: 名前の変更対象
//seer: 上の変更を確認することができるプレイヤー
if (player == null || name == null || !AmongUsClient.Instance.AmHost) return;
if (seer == null) seer = player;
var clientId = GetClientId(seer);
MessageWriter writer = AmongUsClient.Instance.StartRpcImmediately(player.NetId, (byte)RpcCalls.SetName, Hazel.SendOption.Reliable, clientId);
writer.Write(name);
writer.Write(DontShowOnModdedClient);
AmongUsClient.Instance.FinishRpcImmediately(writer);
}
public static int GetClientId(this PlayerControl player)
{
var client = GetClient(player);
return client == null ? -1 : client.Id;
}
public static InnerNet.ClientData GetClient(this PlayerControl player)
{//ここまでtoh
var client = AmongUsClient.Instance.allClients.ToArray().Where(cd => cd.Character.PlayerId == player.PlayerId).FirstOrDefault();
return client;
}
public static void RpcSetCustomRole(this PlayerControl player, CustomRoles role)
{
Main.PlayerRole[player.PlayerId] = role;
MessageWriter writer = AmongUsClient.Instance.StartRpcImmediately(PlayerControl.LocalPlayer.NetId, (byte)CustomRPC.SetCustomRole, SendOption.Reliable);
writer.Write(player.PlayerId);
writer.WritePacked((int)role);
AmongUsClient.Instance.FinishRpcImmediately(writer);
}
public enum CustomRPC
{
VersionCheck,
SetCustomRole,
}
}
[HarmonyPatch(typeof(PlayerControl), nameof(PlayerControl.HandleRpc))]
class HandleRpc
{
public static void Postfix(PlayerControl __instance, [HarmonyArgument(0)] byte callId, [HarmonyArgument(1)] MessageReader reader)
{
RPC.CustomRPC rpcType = (RPC.CustomRPC)callId;
switch (rpcType)
{
case RPC.CustomRPC.SetCustomRole:
CustomRoles role = (CustomRoles)reader.ReadPackedInt32();
byte player = reader.ReadByte();
Main.PlayerRole[player] = role;
Debug.Log($"SetCustomRoleを受け取りました。 player:{player} role:{role}");
break;
}
}
}
[HarmonyPatch(typeof(RoleManager), nameof(RoleManager.SelectRoles))]
class SelectRolesPatch
{
public static bool Prefix(RoleManager __instance)
{
List<byte> AllPlayers = new();
List<CustomRoles> ActiveRoles = new();
List<byte> Impostor = new();
var rand = new System.Random();
//var numImpostors = Math.Min(PlayerControl.AllPlayerControls.Count, GameOptionsManager.Instance.CurrentGameOptions.NumImpostors);
Main.PlayerRole.Clear();
foreach (var pc in PlayerControl.AllPlayerControls)
AllPlayers.Add(pc.PlayerId);
//プレイヤーとロール
ActiveRoles = GetActiveRole();
/*for (var i = 0; i < numImpostors; i++)
{
Impostor.Add((byte)rand.Next(0, AllPlayers.Count));
}*/
if (ActiveRoles.Count == 0 || ActiveRoles == null) return true;
for (var i = 0; i < PlayerControl.AllPlayerControls.Count; i++)
{
Console.print("!!");
PlayerControl Player = null;
CustomRoles Role;
var Playerid = AllPlayers[rand.Next(0, AllPlayers.Count)]; //この二つは一時的に使うだけ
var Roleid = rand.Next(0, ActiveRoles.Count); //↑
Debug.Log(Roleid + "," + ActiveRoles.Count);
Role = ActiveRoles[Roleid];
foreach (var pc in PlayerControl.AllPlayerControls)
if (pc.PlayerId == Playerid)
{
Player = pc;
break; //処理終了
}
if (Player == null) continue;
//pc.RpcSetRole(Role); ここは後でCustomSetRoleRPC作りますね
Player.RpcSetCustomRole(Role);
Debug.Log($"Player:{Playerid},Role:{Role}");
ActiveRoles.RemoveAt(Roleid);
AllPlayers.Remove(Playerid);
}
Main.NoEndGame = GetSetting("ゲームを終了しない") == 1;
return true;
}
}
[HarmonyPatch(typeof(GameManager), nameof(GameManager.CheckTaskCompletion))]
class CheckTaskCompletionPatch
{
public static bool Prefix(ref bool __result)
{
if (Main.NoEndGame)
{
__result = false;
return false;
}
return true;
}
}
[HarmonyPatch(typeof(LogicGameFlowNormal), nameof(LogicGameFlowNormal.CheckEndCriteria))]
class GameEndChecker
{
public static bool Prefix()
{
return !Main.NoEndGame;
}
}
[HarmonyPatch(typeof(PlayerControl), nameof(PlayerControl.CheckMurder))]
class CheckMurderPatch
{
public static bool Prefix(PlayerControl __instance, [HarmonyArgument(0)] PlayerControl target)
{
if (!AmongUsClient.Instance.AmHost) return false;
if (Main.PlayerRole[__instance.PlayerId] == CustomRoles.Sheriff)
if (Main.PlayerRole[target.PlayerId].RoleTeam() != Team.Crewmate)
{
__instance.RpcMurderPlayer(__instance, true);
return false;
}
return true;
}
}
[HarmonyPatch(typeof(IntroCutscene), nameof(IntroCutscene.BeginCrewmate))]
class BeginCrewmatePatch
{
public static void Prefix(IntroCutscene __instance, ref Il2CppSystem.Collections.Generic.List<PlayerControl> teamToDisplay)
{
if (Main.PlayerRole[PlayerControl.LocalPlayer.PlayerId].RoleTeam() == Team.Neutral)
{
var soloTeam = new Il2CppSystem.Collections.Generic.List<PlayerControl>();
soloTeam.Add(PlayerControl.LocalPlayer);
teamToDisplay = soloTeam;
}
}
}
[HarmonyPatch(typeof(IntroCutscene), nameof(IntroCutscene.ShowRole))]
class SetUpRoleTextPatch
{
public static void Postfix(IntroCutscene __instance)
{
CustomRoles role = Main.PlayerRole[PlayerControl.LocalPlayer.PlayerId];
_ = ColorUtility.TryParseHtmlString(role.GetRoleColor(), out Color rc);
__instance.TeamTitle.text = Translator.GetColorString(role);
__instance.TeamTitle.color = rc;
}
}
[HarmonyPatch(typeof(PingTracker), nameof(PingTracker.Update))]
class PingUpdatePatch
{
static void Postfix(PingTracker __instance)
{
__instance.text.text += $"\n\r{Main.PluginName} v{Main.PluginVersion}";
}
}
[HarmonyPatch(typeof(GameStartManager), nameof(GameStartManager.Update))]
class GameStartManagerUpdate
{
public static void Prefix(GameStartManager __instance)
{
__instance.MinPlayers = 1;
}
}
}