Skip to content

Commit c683dc3

Browse files
committed
Add new medium for next release
1 parent b4ad33b commit c683dc3

File tree

11 files changed

+935
-39
lines changed

11 files changed

+935
-39
lines changed

TownOfUs/Assets/TouAssets.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,8 @@ public static LoadableAsset<Sprite> FoolsMenuSprite(int value)
142142
public static LoadableAsset<GameObject> MayorPostRevealPrefab { get; set; } =
143143
new LoadableBundleAsset<GameObject>("MayorPostReveal", MainBundle);
144144

145+
public static LoadableAsset<GameObject> MediumSpirit { get; } = new LoadableBundleAsset<GameObject>("MediumSpirit", MainBundle);
146+
145147
public static LoadableAsset<AnimationClip> SentryCamOffAnim { get; } =
146148
new LoadableBundleAsset<AnimationClip>("SentryCamOffAnimation", MainBundle);
147149

TownOfUs/Buttons/Classic/Crewmate/CrewmateInvestigative/MediumMediateButton.cs

Lines changed: 65 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22
using MiraAPI.Modifiers;
33
using MiraAPI.Utilities;
44
using MiraAPI.Utilities.Assets;
5+
using TownOfUs.Modifiers;
56
using TownOfUs.Modifiers.Crewmate;
7+
using TownOfUs.Modifiers.Neutral;
68
using TownOfUs.Options.Roles.Crewmate;
79
using TownOfUs.Roles.Crewmate;
810
using UnityEngine;
@@ -15,24 +17,61 @@ public sealed class MediumMediateButton : TownOfUsRoleButton<MediumRole>
1517
public override string Name => TouLocale.GetParsed("TouRoleMediumMediate", "Mediate");
1618
public override BaseKeybind Keybind => Keybinds.SecondaryAction;
1719
public override Color TextOutlineColor => TownOfUsColors.Medium;
18-
public override float Cooldown => Math.Clamp(OptionGroupSingleton<MediumOptions>.Instance.MediateCooldown + MapCooldown, 0.001f, 120f);
20+
public override float Cooldown => Math.Clamp(OptionGroupSingleton<MediumOptions>.Instance.MediateCooldown.Value + MapCooldown, 0.001f, 120f);
21+
public override float EffectDuration => OptionGroupSingleton<MediumOptions>.Instance.MediateDuration.Value;
22+
1923
public override LoadableAsset<Sprite> Sprite => TouCrewAssets.MediateSprite;
2024

2125
public override bool ZeroIsInfinite { get; set; } = true;
2226

27+
public override void ClickHandler()
28+
{
29+
if (!CanUse())
30+
{
31+
return;
32+
}
33+
34+
OnClick();
35+
Button?.SetDisabled();
36+
if (EffectActive)
37+
{
38+
Timer = Cooldown;
39+
EffectActive = false;
40+
}
41+
else if (HasEffect)
42+
{
43+
EffectActive = true;
44+
Timer = EffectDuration;
45+
}
46+
else
47+
{
48+
Timer = Cooldown;
49+
}
50+
}
51+
2352
protected override void OnClick()
2453
{
54+
if (EffectActive)
55+
{
56+
if (Role.Spirit != null)
57+
{
58+
MediumRole.RpcRemoveMediumSpirit(PlayerControl.LocalPlayer, Role.Spirit);
59+
}
60+
return;
61+
}
62+
2563
var deadPlayers = PlayerControl.AllPlayerControls.ToArray()
2664
.Where(plr => plr.Data.IsDead && !plr.Data.Disconnected &&
2765
Object.FindObjectsOfType<DeadBody>().Any(x => x.ParentId == plr.PlayerId)
2866
&& !plr.HasModifier<MediatedModifier>()).ToList();
2967

3068
if (deadPlayers.Count == 0)
3169
{
70+
MediumRole.RpcMediate(PlayerControl.LocalPlayer);
3271
return;
3372
}
3473

35-
var targets = OptionGroupSingleton<MediumOptions>.Instance.WhoIsRevealed switch
74+
var targets = (MediateRevealedTargets)OptionGroupSingleton<MediumOptions>.Instance.WhoIsRevealed.Value switch
3675
{
3776
MediateRevealedTargets.NewestDead => [deadPlayers[0]],
3877
MediateRevealedTargets.AllDead => deadPlayers,
@@ -41,9 +80,31 @@ protected override void OnClick()
4180
_ => []
4281
};
4382

44-
foreach (var plr in targets)
83+
MediumRole.RpcMultiMediate(PlayerControl.LocalPlayer, targets);
84+
}
85+
86+
public override void OnEffectEnd()
87+
{
88+
if (Role.Spirit == null)
4589
{
46-
MediumRole.RpcMediate(PlayerControl.LocalPlayer, plr);
90+
return;
4791
}
92+
MediumRole.RpcRemoveMediumSpirit(PlayerControl.LocalPlayer, Role.Spirit);
93+
}
94+
95+
public override bool CanUse()
96+
{
97+
if (HudManager.Instance.Chat.IsOpenOrOpening || MeetingHud.Instance)
98+
{
99+
return false;
100+
}
101+
102+
if (PlayerControl.LocalPlayer.HasModifier<GlitchHackedModifier>() || PlayerControl.LocalPlayer
103+
.GetModifiers<DisabledModifier>().Any(x => !x.CanUseAbilities))
104+
{
105+
return false;
106+
}
107+
108+
return ((Timer <= 0 && !EffectActive) || (EffectActive && Timer <= EffectDuration - OptionGroupSingleton<MediumOptions>.Instance.LivingSeeSpiritTimer.Value - 1f));
48109
}
49110
}

TownOfUs/Modifiers/Crewmate/MediatedModifier.cs

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
using MiraAPI.Events;
22
using MiraAPI.GameOptions;
33
using MiraAPI.Hud;
4-
using MiraAPI.Modifiers;
4+
using MiraAPI.Modifiers.Types;
55
using Reactor.Utilities;
66
using Reactor.Utilities.Extensions;
77
using TownOfUs.Buttons.Crewmate;
@@ -13,7 +13,7 @@
1313

1414
namespace TownOfUs.Modifiers.Crewmate;
1515

16-
public sealed class MediatedModifier(byte mediumId) : BaseModifier
16+
public sealed class MediatedModifier(byte mediumId) : TimedModifier
1717
{
1818
private ArrowBehaviour? _arrow;
1919

@@ -22,6 +22,7 @@ public sealed class MediatedModifier(byte mediumId) : BaseModifier
2222
public override string ModifierName => "Mediated";
2323
public override bool HideOnUi => true;
2424
public byte MediumId { get; } = mediumId;
25+
public override float Duration => OptionGroupSingleton<MediumOptions>.Instance.MediateDuration.Value + 1f;
2526

2627
public override void OnMeetingStart()
2728
{
@@ -33,7 +34,7 @@ public override void OnActivate()
3334
_medium = GameData.Instance.GetPlayerById(MediumId).Role as MediumRole;
3435
_mediumPlayer = _medium?.Player;
3536

36-
if (_mediumPlayer == null || _medium == null || !Player.Data.IsDead)
37+
if (_mediumPlayer == null || _medium == null || !Player.Data.IsDead || _medium.Spirit == null)
3738
{
3839
ModifierComponent?.RemoveModifier(this);
3940
return;
@@ -44,23 +45,26 @@ public override void OnActivate()
4445

4546
_medium.MediatedPlayers.Add(this);
4647

47-
switch (OptionGroupSingleton<MediumOptions>.Instance.ArrowVisibility)
48+
switch ((MediumVisibility)OptionGroupSingleton<MediumOptions>.Instance.ArrowVisibility.Value)
4849
{
4950
case MediumVisibility.Both:
50-
var ownerTransform = Player.AmOwner ? _mediumPlayer.transform : Player.transform;
51+
var ownerTransform = Player.AmOwner ? _medium.Spirit.transform : Player.transform;
5152
_arrow = MiscUtils.CreateArrow(ownerTransform, TownOfUsColors.Medium);
5253
break;
5354

5455
case MediumVisibility.ShowMedium when Player.AmOwner:
55-
_arrow = MiscUtils.CreateArrow(_mediumPlayer.transform, TownOfUsColors.Medium);
56+
_arrow = MiscUtils.CreateArrow(_medium.Spirit.transform, TownOfUsColors.Medium);
5657
break;
5758

5859
case MediumVisibility.ShowMediate when _mediumPlayer.AmOwner:
5960
_arrow = MiscUtils.CreateArrow(Player.transform, TownOfUsColors.Medium);
6061
break;
6162
}
6263

63-
if (_mediumPlayer.AmOwner && !OptionGroupSingleton<MediumOptions>.Instance.RevealMediateAppearance)
64+
var hidden =
65+
(AppearanceVisibility)OptionGroupSingleton<MediumOptions>.Instance.PlayerVisibility.Value is
66+
AppearanceVisibility.None or AppearanceVisibility.Living;
67+
if (_mediumPlayer.AmOwner && hidden)
6468
{
6569
Player.SetCamouflage();
6670
}
@@ -85,7 +89,11 @@ public override void OnDeactivate()
8589
CustomButtonSingleton<MediumMediateButton>.Instance.SetTimerPaused(false);
8690
CustomButtonSingleton<MediumMediateButton>.Instance.ResetCooldownAndOrEffect();
8791

88-
if (!OptionGroupSingleton<MediumOptions>.Instance.RevealMediateAppearance)
92+
var hidden =
93+
(AppearanceVisibility)OptionGroupSingleton<MediumOptions>.Instance.PlayerVisibility.Value is
94+
AppearanceVisibility.None or AppearanceVisibility.Living;
95+
96+
if (hidden)
8997
{
9098
Player.SetCamouflage(false);
9199
}
@@ -114,5 +122,7 @@ public override void FixedUpdate()
114122
{
115123
_arrow.target = _arrow.transform.parent.position;
116124
}
125+
126+
base.FixedUpdate();
117127
}
118-
}
128+
}
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
using MiraAPI.GameOptions;
2+
using MiraAPI.Modifiers;
3+
using TownOfUs.Options.Maps;
4+
using TownOfUs.Options.Roles.Crewmate;
5+
using TownOfUs.Patches;
6+
using TownOfUs.Utilities.Appearances;
7+
using UnityEngine;
8+
9+
namespace TownOfUs.Modifiers.Crewmate;
10+
11+
public sealed class MediumHiddenModifier : ConcealedModifier, IVisualAppearance
12+
{
13+
public override float Duration => OptionGroupSingleton<MediumOptions>.Instance.MediateDuration.Value + 1f;
14+
public override string ModifierName => "Hidden";
15+
public override bool HideOnUi => true;
16+
public override bool AutoStart => true;
17+
public override bool VisibleToOthers => true;
18+
public bool VisualPriority => true;
19+
20+
public VisualAppearance GetVisualAppearance()
21+
{
22+
var playerColor = new Color(0.3f, 0f, 0.7f, 0.5f);
23+
24+
return new VisualAppearance(PlayerControl.LocalPlayer.GetDefaultAppearance(), TownOfUsAppearances.Camouflage)
25+
{
26+
HatId = string.Empty,
27+
SkinId = string.Empty,
28+
VisorId = string.Empty,
29+
PlayerName = string.Empty,
30+
PetId = string.Empty,
31+
RendererColor = playerColor,
32+
NameColor = Color.clear,
33+
ColorBlindTextColor = Color.clear
34+
};
35+
}
36+
37+
public override void OnDeath(DeathReason reason)
38+
{
39+
Player.RemoveModifier(this);
40+
}
41+
42+
public override void OnMeetingStart()
43+
{
44+
Player.RemoveModifier(this);
45+
}
46+
47+
public override void OnActivate()
48+
{
49+
Player.RawSetAppearance(this);
50+
Player.cosmetics.ToggleNameVisible(false);
51+
}
52+
53+
public override void FixedUpdate()
54+
{
55+
base.FixedUpdate();
56+
57+
var mushroom = UnityEngine.Object.FindObjectOfType<MushroomMixupSabotageSystem>();
58+
if (mushroom && mushroom.IsActive)
59+
{
60+
Player.RawSetAppearance(this);
61+
Player.cosmetics.ToggleNameVisible(false);
62+
}
63+
}
64+
65+
public override void OnDeactivate()
66+
{
67+
Player.ResetAppearance();
68+
Player.cosmetics.ToggleNameVisible(true);
69+
70+
if (HudManagerPatches.CamouflageCommsEnabled)
71+
{
72+
Player.RawSetAppearance(new VisualAppearance(Player.GetDefaultAppearance(), TownOfUsAppearances.Camouflage)
73+
{
74+
ColorId = Player.Data.DefaultOutfit.ColorId,
75+
HatId = string.Empty,
76+
SkinId = string.Empty,
77+
VisorId = string.Empty,
78+
PlayerName = string.Empty,
79+
PetId = string.Empty,
80+
NameVisible = false,
81+
PlayerMaterialColor = Color.grey,
82+
Size = (OptionGroupSingleton<AdvancedSabotageOptions>.Instance.HidePlayerSizeInCamo) ? new Vector3(0.7f, 0.7f, 1f) : Player.GetAppearance().Size
83+
});
84+
Player.cosmetics.ToggleNameVisible(false);
85+
}
86+
87+
var mushroom = UnityEngine.Object.FindObjectOfType<MushroomMixupSabotageSystem>();
88+
if (mushroom && mushroom.IsActive)
89+
{
90+
MushroomMixUp(mushroom, Player);
91+
}
92+
}
93+
94+
public static void MushroomMixUp(MushroomMixupSabotageSystem instance, PlayerControl player)
95+
{
96+
if (player != null && !player.Data.IsDead && instance.currentMixups.ContainsKey(player.PlayerId))
97+
{
98+
var condensedOutfit = instance.currentMixups[player.PlayerId];
99+
var playerOutfit = instance.ConvertToPlayerOutfit(condensedOutfit);
100+
playerOutfit.NamePlateId = player.Data.DefaultOutfit.NamePlateId;
101+
102+
player.MixUpOutfit(playerOutfit);
103+
}
104+
}
105+
}

0 commit comments

Comments
 (0)