mirror of
https://github.com/Gurge44/EndlessHostRoles.git
synced 2026-10-19 15:51:58 +00:00
256 lines
13 KiB
C#
256 lines
13 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using EHR.Roles;
|
|
using HarmonyLib;
|
|
using Hazel;
|
|
using UnityEngine;
|
|
using static EHR.Modules.LevelImposterCompatibility;
|
|
|
|
namespace EHR;
|
|
|
|
// Reference: https://github.com/ykundesu/SuperNewRoles/blob/master/SuperNewRoles/Mode/SuperHostRoles/BlockTool.cs
|
|
internal static class DisableDevice
|
|
{
|
|
public static readonly List<byte> DesyncComms = [];
|
|
private static int Frame;
|
|
|
|
public static readonly Dictionary<string, Vector2> DevicePos = new()
|
|
{
|
|
["SkeldAdmin"] = new(3.48f, -8.62f),
|
|
["SkeldCamera"] = new(-13.06f, -2.45f),
|
|
["MiraHQAdmin"] = new(21.02f, 19.09f),
|
|
["MiraHQDoorLog"] = new(16.22f, 5.82f),
|
|
["PolusLeftAdmin"] = new(22.80f, -21.52f),
|
|
["PolusRightAdmin"] = new(24.66f, -21.52f),
|
|
["PolusCamera"] = new(2.96f, -12.74f),
|
|
["PolusVital"] = new(26.70f, -15.94f),
|
|
["DleksAdmin"] = new(-3.48f, -8.62f),
|
|
["DleksCamera"] = new(13.06f, -2.45f),
|
|
["AirshipCockpitAdmin"] = new(-22.32f, 0.91f),
|
|
["AirshipRecordsAdmin"] = new(19.89f, 12.60f),
|
|
["AirshipCamera"] = new(8.10f, -9.63f),
|
|
["AirshipVital"] = new(25.24f, -7.94f),
|
|
["FungleCamera"] = new(6.20f, 0.10f),
|
|
["FungleVital"] = new(-2.50f, -9.80f),
|
|
["SubmergedVital"] = new(5f, 32.54f),
|
|
["SubmergedLeftAdmin"] = new(-9.45f, 10.16f),
|
|
["SubmergedRightAdmin"] = new(-7.07f, 10.16f),
|
|
["SubmergedCamera"] = new(-3.41f, -34.56f)
|
|
};
|
|
|
|
public static void AddCustomDevicesPos()
|
|
{
|
|
var keysToRemove = DevicePos.Keys
|
|
.Where(k => k.StartsWith("LI", StringComparison.OrdinalIgnoreCase))
|
|
.ToList();
|
|
|
|
foreach (var key in keysToRemove)
|
|
DevicePos.Remove(key);
|
|
|
|
int adminId = 0;
|
|
int cameraId = 0;
|
|
int binoId = 0;
|
|
int vitalId = 0;
|
|
|
|
foreach (var admin in AllAdminTables)
|
|
DevicePos[$"LIAdmin{adminId++}"] = admin.transform.position;
|
|
|
|
foreach (var camera in AllCameraPanels)
|
|
DevicePos[$"LICamera{cameraId++}"] = camera.transform.position;
|
|
|
|
foreach (var bino in AllBinoculars)
|
|
DevicePos[$"LIBinocular{binoId++}"] = bino.transform.position;
|
|
|
|
foreach (var vital in AllVitals)
|
|
DevicePos[$"LIVital{vitalId++}"] = vital.transform.position;
|
|
}
|
|
|
|
private static bool DoDisable => Options.DisableDevices.GetBool();
|
|
|
|
public static float UsableDistance => Main.CurrentMap switch
|
|
{
|
|
MapNames.Skeld => 1.8f,
|
|
MapNames.MiraHQ => 2.4f,
|
|
MapNames.Polus => 1.8f,
|
|
MapNames.Dleks => 1.5f,
|
|
MapNames.Airship => 1.8f,
|
|
MapNames.Fungle => 1.8f,
|
|
_ => 2f
|
|
};
|
|
|
|
public static void FixedUpdate(PlayerControl pc)
|
|
{
|
|
Frame = Frame == 3 ? 0 : ++Frame;
|
|
if (Frame != 0) return;
|
|
if (pc.IsModdedClient()) return;
|
|
|
|
bool rogueForce = false;
|
|
if (Rogue.On)
|
|
foreach (var ps in Main.PlayerStates.Values)
|
|
{
|
|
var role = ps.Role;
|
|
if (role is Rogue { DisableDevices: true })
|
|
{
|
|
rogueForce = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!DoDisable && !rogueForce) return;
|
|
|
|
try
|
|
{
|
|
var doComms = false;
|
|
var mapId = Main.NormalOptions.MapId;
|
|
Vector2 PlayerPos = pc.Pos();
|
|
|
|
bool ignore = Options.DisableDevicesIgnoreImpostors.GetBool() && pc.Is(CustomRoleTypes.Impostor) ||
|
|
Options.DisableDevicesIgnoreNeutrals.GetBool() && pc.Is(CustomRoleTypes.Neutral) ||
|
|
Options.DisableDevicesIgnoreCrewmates.GetBool() && pc.Is(CustomRoleTypes.Crewmate) ||
|
|
Options.DisableDevicesIgnoreAfterAnyoneDied.GetBool() && GameStates.AlreadyDied;
|
|
|
|
ignore &= !rogueForce;
|
|
|
|
if (pc.IsAlive() && !Utils.IsActive(SystemTypes.Comms))
|
|
{
|
|
switch (mapId)
|
|
{
|
|
case 0:
|
|
if (Options.DisableSkeldAdmin.GetBool() || rogueForce) doComms |= FastVector2.DistanceWithinRange(PlayerPos, DevicePos["SkeldAdmin"], UsableDistance);
|
|
if (Options.DisableSkeldCamera.GetBool() || rogueForce) doComms |= FastVector2.DistanceWithinRange(PlayerPos, DevicePos["SkeldCamera"], UsableDistance);
|
|
break;
|
|
case 1:
|
|
if (Options.DisableMiraHQAdmin.GetBool() || rogueForce) doComms |= FastVector2.DistanceWithinRange(PlayerPos, DevicePos["MiraHQAdmin"], UsableDistance);
|
|
if (Options.DisableMiraHQDoorLog.GetBool() || rogueForce) doComms |= FastVector2.DistanceWithinRange(PlayerPos, DevicePos["MiraHQDoorLog"], UsableDistance);
|
|
break;
|
|
case 2:
|
|
if (Options.DisablePolusAdmin.GetBool() || rogueForce)
|
|
{
|
|
doComms |= FastVector2.DistanceWithinRange(PlayerPos, DevicePos["PolusLeftAdmin"], UsableDistance);
|
|
doComms |= FastVector2.DistanceWithinRange(PlayerPos, DevicePos["PolusRightAdmin"], UsableDistance);
|
|
}
|
|
|
|
if (Options.DisablePolusCamera.GetBool() || rogueForce) doComms |= FastVector2.DistanceWithinRange(PlayerPos, DevicePos["PolusCamera"], UsableDistance);
|
|
if (Options.DisablePolusVital.GetBool() || rogueForce) doComms |= FastVector2.DistanceWithinRange(PlayerPos, DevicePos["PolusVital"], UsableDistance);
|
|
break;
|
|
case 3:
|
|
if (Options.DisableSkeldAdmin.GetBool() || rogueForce) doComms |= FastVector2.DistanceWithinRange(PlayerPos, DevicePos["DleksAdmin"], UsableDistance);
|
|
if (Options.DisableSkeldCamera.GetBool() || rogueForce) doComms |= FastVector2.DistanceWithinRange(PlayerPos, DevicePos["DleksCamera"], UsableDistance);
|
|
break;
|
|
case 4:
|
|
if (Options.DisableAirshipCockpitAdmin.GetBool() || rogueForce) doComms |= FastVector2.DistanceWithinRange(PlayerPos, DevicePos["AirshipCockpitAdmin"], UsableDistance);
|
|
if (Options.DisableAirshipRecordsAdmin.GetBool() || rogueForce) doComms |= FastVector2.DistanceWithinRange(PlayerPos, DevicePos["AirshipRecordsAdmin"], UsableDistance);
|
|
if (Options.DisableAirshipCamera.GetBool() || rogueForce) doComms |= FastVector2.DistanceWithinRange(PlayerPos, DevicePos["AirshipCamera"], UsableDistance);
|
|
if (Options.DisableAirshipVital.GetBool() || rogueForce) doComms |= FastVector2.DistanceWithinRange(PlayerPos, DevicePos["AirshipVital"], UsableDistance);
|
|
break;
|
|
case 5:
|
|
/*if (Options.DisableFungleCamera.GetBool() || rogueForce) doComms |= FastVector2.DistanceWithinRange(PlayerPos, DevicePos["FungleCamera"], UsableDistance);*/
|
|
if (Options.DisableFungleVital.GetBool() || rogueForce) doComms |= FastVector2.DistanceWithinRange(PlayerPos, DevicePos["FungleVital"], UsableDistance);
|
|
break;
|
|
}
|
|
}
|
|
|
|
doComms &= !ignore;
|
|
|
|
var hasValue = false;
|
|
var activateSabComms = false;
|
|
|
|
if (doComms && !pc.inVent)
|
|
{
|
|
if (!DesyncComms.Contains(pc.PlayerId)) DesyncComms.Add(pc.PlayerId);
|
|
hasValue = true;
|
|
activateSabComms = true;
|
|
}
|
|
else if (!Utils.IsActive(SystemTypes.Comms) && DesyncComms.Contains(pc.PlayerId))
|
|
{
|
|
DesyncComms.Remove(pc.PlayerId);
|
|
hasValue = true;
|
|
}
|
|
|
|
if (!hasValue) return;
|
|
|
|
var sender = CustomRpcSender.Create("DisableDevice.FixedUpdate", SendOption.Reliable, log: false);
|
|
|
|
if (activateSabComms)
|
|
sender.RpcDesyncUpdateSystem(pc, SystemTypes.Comms, 128);
|
|
else
|
|
{
|
|
sender.RpcDesyncUpdateSystem(pc, SystemTypes.Comms, 16);
|
|
|
|
if (mapId is 1 or 5) // Mira HQ or The Fungle
|
|
sender.RpcDesyncUpdateSystem(pc, SystemTypes.Comms, 17);
|
|
}
|
|
|
|
sender.SendMessage();
|
|
}
|
|
catch (Exception ex) { Logger.Exception(ex, "DisableDevice"); }
|
|
}
|
|
}
|
|
|
|
[HarmonyPatch(typeof(ShipStatus), nameof(ShipStatus.Start))]
|
|
public class RemoveDisableDevicesPatch
|
|
{
|
|
public static void Postfix()
|
|
{
|
|
if (Main.LIMap) LateTask.New(() => DisableDevice.AddCustomDevicesPos(), 10f, "DisableDevice");
|
|
|
|
bool rogueForce = Rogue.On && Main.PlayerStates.Values.Any(x => x.Role is Rogue { DisableDevices: true });
|
|
if (!Options.DisableDevices.GetBool() && !rogueForce) return;
|
|
|
|
UpdateDisableDevices();
|
|
}
|
|
|
|
public static void UpdateDisableDevices()
|
|
{
|
|
PlayerControl player = PlayerControl.LocalPlayer;
|
|
bool rogueForce = Rogue.On && Main.PlayerStates.Values.Any(x => x.Role is Rogue { DisableDevices: true });
|
|
|
|
bool ignore = player.Is(CustomRoles.GM) ||
|
|
!player.IsAlive() ||
|
|
Options.DisableDevicesIgnoreImpostors.GetBool() && player.Is(CustomRoleTypes.Impostor) ||
|
|
Options.DisableDevicesIgnoreNeutrals.GetBool() && player.Is(CustomRoleTypes.Neutral) ||
|
|
Options.DisableDevicesIgnoreCrewmates.GetBool() && player.Is(CustomRoleTypes.Crewmate) ||
|
|
Options.DisableDevicesIgnoreAfterAnyoneDied.GetBool() && GameStates.AlreadyDied;
|
|
|
|
ignore &= !rogueForce;
|
|
var admins = Object.FindObjectsOfType<MapConsole>(true);
|
|
var consoles = Object.FindObjectsOfType<SystemConsole>(true);
|
|
if (admins == null || consoles == null) return;
|
|
|
|
switch (Main.NormalOptions.MapId)
|
|
{
|
|
case 3:
|
|
case 0:
|
|
if (Options.DisableSkeldAdmin.GetBool() || rogueForce) admins[0].gameObject.GetComponent<CircleCollider2D>().enabled = ignore;
|
|
if (Options.DisableSkeldCamera.GetBool() || rogueForce) consoles.DoIf(x => x.name == "SurvConsole", x => x.gameObject.GetComponent<PolygonCollider2D>().enabled = ignore);
|
|
break;
|
|
case 1:
|
|
if (Options.DisableMiraHQAdmin.GetBool() || rogueForce) admins[0].gameObject.GetComponent<CircleCollider2D>().enabled = ignore;
|
|
if (Options.DisableMiraHQDoorLog.GetBool() || rogueForce) consoles.DoIf(x => x.name == "SurvLogConsole", x => x.gameObject.GetComponent<BoxCollider2D>().enabled = ignore);
|
|
|
|
break;
|
|
case 2:
|
|
if (Options.DisablePolusAdmin.GetBool() || rogueForce) admins.Do(x => x.gameObject.GetComponent<BoxCollider2D>().enabled = ignore);
|
|
if (Options.DisablePolusCamera.GetBool() || rogueForce) consoles.DoIf(x => x.name == "Surv_Panel", x => x.gameObject.GetComponent<BoxCollider2D>().enabled = ignore);
|
|
if (Options.DisablePolusVital.GetBool() || rogueForce) consoles.DoIf(x => x.name == "panel_vitals", x => x.gameObject.GetComponent<BoxCollider2D>().enabled = ignore);
|
|
break;
|
|
case 4:
|
|
admins.Do(x =>
|
|
{
|
|
if (Options.DisableAirshipCockpitAdmin.GetBool() && x.name == "panel_cockpit_map" ||
|
|
Options.DisableAirshipRecordsAdmin.GetBool() && x.name == "records_admin_map" || rogueForce)
|
|
x.gameObject.GetComponent<BoxCollider2D>().enabled = ignore;
|
|
});
|
|
|
|
if (Options.DisableAirshipCamera.GetBool() || rogueForce) consoles.DoIf(x => x.name == "task_cams", x => x.gameObject.GetComponent<BoxCollider2D>().enabled = ignore);
|
|
if (Options.DisableAirshipVital.GetBool() || rogueForce) consoles.DoIf(x => x.name == "panel_vitals", x => x.gameObject.GetComponent<CircleCollider2D>().enabled = ignore);
|
|
break;
|
|
case 5:
|
|
/*if (Options.DisableFungleCamera.GetBool() || rogueForce) consoles.DoIf(x => x.name == "BinocularsSecurityConsole", x => x.gameObject.GetComponent<PolygonCollider2D>().enabled = ignore);*/
|
|
if (Options.DisableFungleVital.GetBool() || rogueForce) consoles.DoIf(x => x.name == "VitalsConsole", x => x.gameObject.GetComponent<BoxCollider2D>().enabled = ignore);
|
|
break;
|
|
}
|
|
}
|
|
}
|