Skip to content

Commit

Permalink
Merge pull request #178 from JieGeLovesDengDuaLang/main
Browse files Browse the repository at this point in the history
更改
  • Loading branch information
JieGeLovesDengDuaLang authored Aug 13, 2024
2 parents c19a993 + 5364c96 commit 3689e1d
Show file tree
Hide file tree
Showing 10 changed files with 113 additions and 46 deletions.
6 changes: 3 additions & 3 deletions COG/Game/CustomWinner/Winnable/CrewmatesCustomWinner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ public class CrewmatesCustomWinner : IWinnable
{
public void CheckWin(WinnableData data)
{
var taskComplete = PlayerUtils.GetAllPlayers().All(player => player.Data.IsIncomplete);
var taskComplete = PlayerUtils.GetAllPlayers().All(player => player.AllTasksCompleted());
if (taskComplete ||
PlayerUtils.AllImpostors.Where(pair => pair.Player && !pair.Player.Data.IsDead)
.Select(pair => pair.Player).ToList().Count <= 0
PlayerUtils.AllImpostors.Where(pair => pair.Player.IsAlive())
.Select(pair => pair.Player).ToList().Count <= 0
&& PlayerUtils.GetAllAlivePlayers().Select(p => p.GetMainRole()).Where(role => role.CanKill).ToArray().Length <= 0)
{
data.GameOverReason = taskComplete ? GameOverReason.HumansByTask : GameOverReason.HumansByVote;
Expand Down
14 changes: 6 additions & 8 deletions COG/Game/CustomWinner/Winnable/ImpostorsCustomWinner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,16 @@ public class ImpostorsCustomWinner : IWinnable
public void CheckWin(WinnableData data)
{
var aliveImpostors = PlayerUtils.AllImpostors.Select(pair => pair.Player).Where
(p => p && p.IsAlive()).ToList();
(p => p.IsAlive()).ToList();
var aliveNeutrals = PlayerUtils.AllNeutrals.Select(pair => pair.Player).Where
(p => p && p.IsAlive()).ToList();
(p => p.IsAlive()).ToList();
var aliveCrewmates = PlayerUtils.AllCrewmates.Select(pair => pair.Player).Where
(p => p.IsAlive()).ToList();
GameUtils.PlayerData.Where
(pair => pair.Role.CampType == CampType.Impostor).ToList()
.ForEach(pair => aliveImpostors.Add(pair.Player));
if (aliveImpostors.Count >= PlayerUtils.AllCrewmates
.Select(pair => pair.Player).Where
(p => p && p.IsAlive())
.ToList().Count
&& aliveNeutrals.Where
(p => p.GetMainRole().CanKill).ToList().Count <= 0)
if (aliveImpostors.Count >= aliveCrewmates.Count &&
aliveNeutrals.Where(p => p.GetMainRole().CanKill).ToList().Count <= 0)
{
EndGame(data, true);
}
Expand Down
30 changes: 2 additions & 28 deletions COG/Listener/Impl/GameListener.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ public void OnRpcReceived(PlayerHandleRpcEvent @event)
var bytes = reader.ReadBytesAndSize().ToArray();
var data = bytes.DeserializeToData<SerializablePlayerData>().AsPlayerData();
GameUtils.PlayerData.Add(data);
data.Player.SetCustomRole(data.Role, data.SubRoles);
}
/*
var originalText = reader.ReadString()!;
Expand Down Expand Up @@ -371,42 +372,15 @@ private static void SelectRoles()

var subRoles = subRolesList.Any() ? subRolesList[0] : Array.Empty<CustomRole>();

target.SetCustomRole(mainRoleData.Values.ToArray()[i], subRoles);
target.SetCustomRole(mainRoleData.Values.ToArray()[i], subRoles); // 先本地设置职业,后面ShareRole会把职业发出去的
}

GameUtils.PlayerData.ForEach(data =>
{
var player = data.Player;
var role = data.Role;
RoleManager.Instance.SetRole(player, role.BaseRoleType);

player.RpcMark(BaseRoleSetPrefix + (ushort) role.BaseRoleType);
});

// 打印职业分配信息
foreach (var playerRole in GameUtils.PlayerData)
Main.Logger.LogInfo($"{playerRole.Player.name}({playerRole.Player.Data.FriendCode})" +
$" => {playerRole.Role.GetNormalName()}" +
$"{playerRole.SubRoles.Select(subRole => subRole.GetNormalName()).ToList().AsString()}");
}

private const string BaseRoleSetPrefix = "BASE_ROLE_SET_";

[EventHandler(EventHandlerType.Postfix)]
public void OnPlayerFixedUpdate(PlayerFixedUpdateEvent @event)
{
if (AmongUsClient.Instance.AmHost) return;
foreach (var player in PlayerUtils.GetAllPlayers())
{
var marks = player.GetMarks().Where(mark => mark.StartsWith(BaseRoleSetPrefix));
var enumerable = marks as string[] ?? marks.ToArray();
if (!enumerable.Any()) continue;
var mark = enumerable[0];
var baseRole = (RoleTypes) ushort.Parse(mark.Replace(BaseRoleSetPrefix, ""));
RoleManager.Instance.SetRole(player, baseRole);
player.GetPlayerData()?.Tags.Remove(mark);
}
}

[EventHandler(EventHandlerType.Postfix)]
public void OnSelectRoles(RoleManagerSelectRolesEvent @event)
Expand Down
1 change: 1 addition & 0 deletions COG/Main.cs
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ public override void Load()
new Sheriff(),
new Vigilante(),
new SoulHunter(),
new Technician(),

// Impostor
new Impostor(),
Expand Down
4 changes: 4 additions & 0 deletions COG/Resources/InDLL/Config/language.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@ role:
description: "从地狱归来,将邪恶一同带去"
long-description: "拥有一次无代价击杀。被击杀后指定秒在鸡腿处复活(如果鸡腿还存在的话)并获得一次执法机会,下轮会议召开时将立刻出局。"
revive-after: "复活秒数"
technician:
name: "技术员"
description: "解决飞船的一切疑难杂症"
long-description: "可以进行2次修复,立刻结束破坏或封锁。完成所有任务后可以使用通风口。"
neutral:
jester:
name: "小丑"
Expand Down
Binary file added COG/Resources/InDLL/Images/Buttons/Repair.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion COG/Role/CustomRole.cs
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ protected CustomOption CreateOptionWithoutRegister(Func<string> nameGetter, IVal
public void AddButton(CustomButton button, Func<bool>? hasButton = null)
{
hasButton ??= () => PlayerControl.LocalPlayer.IsRole(this);
button.HasButton = hasButton;
button.HasButton += hasButton;
CustomButtonManager.GetManager().RegisterCustomButton(button);
}

Expand Down
90 changes: 90 additions & 0 deletions COG/Role/Impl/Crewmate/Technician.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
using COG.Listener;
using COG.Listener.Event.Impl.Player;
using COG.Rpc;
using COG.UI.CustomButton;
using COG.Utils;
using COG.Utils.Coding;
using System.Linq;
using UnityEngine;

namespace COG.Role.Impl.Crewmate;

[WorkInProgress]
public class Technician : CustomRole
{
public Technician() : base(Palette.Orange, CampType.Crewmate)
{
RepairButton = CustomButton.Create(() =>
{
RpcUtils.StartRpcImmediately(PlayerControl.LocalPlayer, KnownRpc.ClearSabotages).Finish();
RepairSabotages();
},
() => RepairButton.ResetCooldown(),

Check warning on line 22 in COG/Role/Impl/Crewmate/Technician.cs

View workflow job for this annotation

GitHub Actions / build

Dereference of a possibly null reference.
() => true,
() => true,
ResourceUtils.LoadSprite("COG.Resources.InDLL.Images.Buttons.Repair.png")!,
2,
KeyCode.F,
"REPAIR",
() => 0f,
2
);

AddButton(RepairButton);
}

private CustomButton RepairButton { get; }

[EventHandler(EventHandlerType.Postfix)]
public void OnPlayerFixedUpdate(PlayerFixedUpdateEvent _)
{
var ventButton = HudManager.Instance.ImpostorVentButton;
if (PlayerControl.LocalPlayer.AllTasksCompleted())
{

}
}

[EventHandler(EventHandlerType.Postfix)]
public void OnRpcReceived(PlayerHandleRpcEvent @event)
{
if ((KnownRpc)@event.CallId == KnownRpc.ClearSabotages)
{
RepairSabotages();
}
}

public void RepairSabotages()
{
var ship = ShipStatus.Instance;
var mapId = (MapNames)(AmongUsClient.Instance.NetworkMode == NetworkModes.FreePlay ?
AmongUsClient.Instance.TutorialMapId :
GameUtils.GetGameOptions().MapId);

ship.RepairCriticalSabotages();
if (ship.Systems.TryGetValueSafeIl2Cpp(SystemTypes.Electrical, out var system))
{
var elecSystem = system.TryCast<SwitchSystem>();
if (elecSystem != null)
elecSystem.ActualSwitches = elecSystem.ExpectedSwitches;
}

ship.UpdateSystem(SystemTypes.Comms, PlayerControl.LocalPlayer, 16 | 0);
ship.UpdateSystem(SystemTypes.Comms, PlayerControl.LocalPlayer, 16 | 1);

if (mapId != MapNames.Mira)
ship.AllDoors.ForEach(d => d.SetDoorway(true));

if (mapId == MapNames.Fungle)
{
var mixup = ship.Cast<FungleShipStatus>().specialSabotage;
if (mixup.IsActive)
mixup.currentSecondsUntilHeal = 0.1f;
}
}

public override CustomRole NewInstance()
{
return new Technician();
}
}
3 changes: 2 additions & 1 deletion COG/Rpc/KnownRpc.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,6 @@ public enum KnownRpc : uint
Revive = 104,
NotifySettingChange = 105,
Mark = 106,
ShareOptions = 107
ShareOptions = 107,
ClearSabotages = 108
}
9 changes: 4 additions & 5 deletions COG/Utils/PlayerUtils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,13 @@ public static class PlayerUtils
public static PoolablePlayer? PoolablePlayerPrefab { get; set; }

public static IEnumerable<PlayerData> AllImpostors =>
GameUtils.PlayerData.Where(pair => pair.Role.CampType == CampType.Impostor);
GameUtils.PlayerData.Where(pair => pair.Player && pair.Role.CampType == CampType.Impostor);

public static IEnumerable<PlayerData> AllCrewmates =>
GameUtils.PlayerData.Where(pair => pair.Role.CampType == CampType.Crewmate);
GameUtils.PlayerData.Where(pair => pair.Player && pair.Role.CampType == CampType.Crewmate);

public static IEnumerable<PlayerData> AllNeutrals =>
GameUtils.PlayerData.Where(pair => pair.Role.CampType == CampType.Neutral);
GameUtils.PlayerData.Where(pair => pair.Player && pair.Role.CampType == CampType.Neutral);

/// <summary>
/// 获取距离目标玩家位置最近的玩家
Expand Down Expand Up @@ -357,9 +357,8 @@ public static void SetCustomRole(this PlayerControl pc, CustomRole role, CustomR

GameUtils.PlayerData.Add(new PlayerData(pc, role, subRoles));
RoleManager.Instance.SetRole(pc, role.BaseRoleType);
pc.RpcSetRole(role.BaseRoleType, true);

Main.Logger.LogInfo($"The role of player {pc.Data.PlayerName} has set to {role.GetType().Name}");
Main.Logger.LogInfo($"The role of player {pc.Data.PlayerName} has set to {role.GetNormalName()}");
}

public static void SetCustomRole<T>(this PlayerControl pc) where T : CustomRole
Expand Down

0 comments on commit 3689e1d

Please sign in to comment.