Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added .github/assets/customLobby.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
74 changes: 74 additions & 0 deletions NewMod/Buttons/Overload/FinalButton.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
using MiraAPI.GameOptions;
using MiraAPI.Hud;
using MiraAPI.Utilities.Assets;
using NewMod.Options.Roles.OverloadOptions;
using NewMod.Roles.NeutralRoles;
using Rewired;
using UnityEngine;

namespace NewMod.Buttons.Overload
{
/// <summary>
/// The Final Ability button for Overload.
/// Unlocks after reaching the required absorbed charge count.
/// </summary>
public class FinalAbilityButton : CustomActionButton
{
/// <summary>
/// The name displayed on the button (if any).
/// </summary>
public override string Name => "OVERLOAD";

/// <summary>
/// Cooldown (none for final ability).
/// </summary>
public override float Cooldown => 0f;

/// <summary>
/// One-time use. Set to 1.
/// </summary>
public override int MaxUses => 1;

/// <summary>
/// Default keybind for the Final Ability button.
/// </summary>
public override KeyboardKeyCode Defaultkeybind => KeyboardKeyCode.B;

/// <summary>
/// No duration effect.
/// </summary>
public override float EffectDuration => 0f;

/// <summary>
/// Screen location of the button on the HUD.
/// </summary>
public override ButtonLocation Location => ButtonLocation.BottomRight;

/// <summary>
/// Icon sprite
/// </summary>
public override LoadableAsset<Sprite> Sprite => NewModAsset.FinalButton;

/// <summary>
/// Determines when the button should appear.
/// Only enabled once Overload has enough absorbed abilities.
/// </summary>
public override bool Enabled(RoleBehaviour role)
{
return role is OverloadRole &&
OverloadRole.AbsorbedAbilityCount >= OptionGroupSingleton<OverloadOptions>.Instance.NeededCharge;
}

/// <summary>
/// What happens when the final ability button is clicked.
/// Ends the game with Overload win.
/// </summary>
protected override void OnClick()
{
GameManager.Instance.RpcEndGame(
(GameOverReason)NewModEndReasons.OverloadWin,
false
);
}
}
}
24 changes: 20 additions & 4 deletions NewMod/Buttons/Overload/OverloadButton.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ namespace NewMod.Buttons.Overload
/// </summary>
public class OverloadButton : CustomActionButton
{
public CustomActionButton absorbed;
/// <summary>
/// The display text shown on the button UI.
/// Set by the absorbed ability.
Expand Down Expand Up @@ -89,6 +90,8 @@ public class OverloadButton : CustomActionButton
/// <param name="target">The button to absorb.</param>
public void Absorb(CustomActionButton target)
{
absorbed = target;

absorbedText = target.Name;
absorbedCooldown = target.Cooldown;
absorbedMaxUses = target.MaxUses;
Expand All @@ -99,17 +102,29 @@ public void Absorb(CustomActionButton target)

OverrideName(absorbedText);
OverrideSprite(absorbedSprite.LoadAsset());
SetUses(absorbedMaxUses);

if (absorbedMaxUses <= 0f)
{
Button.SetInfiniteUses();
}
else
{
SetUses(absorbedMaxUses);
}

SetTimer(0f);

HudManager.Instance.SetHudActive(PlayerControl.LocalPlayer, PlayerControl.LocalPlayer.Data.Role, false);
HudManager.Instance.SetHudActive(PlayerControl.LocalPlayer, PlayerControl.LocalPlayer.Data.Role, true);
}

/// <summary>
/// Called when the player presses the button.
/// </summary>
protected override void OnClick()
{
NewMod.Instance.Log.LogError("Overload invoking absorbed action...");
absorbedOnClick?.Invoke();

}

/// <summary>
Expand All @@ -120,7 +135,7 @@ protected override void OnClick()
/// <returns>True if Overload with a valid absorbed ability.</returns>
public override bool Enabled(RoleBehaviour role)
{
return role is OverloadRole && absorbedOnClick != null;
return role is OverloadRole && absorbed != null;
}

/// <summary>
Expand All @@ -129,7 +144,8 @@ public override bool Enabled(RoleBehaviour role)
/// <returns>True if usable.</returns>
public override bool CanUse()
{
return base.CanUse() && absorbedOnClick != null;
absorbed?.FixedUpdateHandler(PlayerControl.LocalPlayer);
return base.CanUse() && absorbed != null;
}
}
}
99 changes: 99 additions & 0 deletions NewMod/Buttons/WraithCaller/CallWraith.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
using MiraAPI.GameOptions;
using MiraAPI.Hud;
using MiraAPI.Utilities.Assets;
using NewMod.Options.Roles.WraithCallerOptions;
using Wraith = NewMod.Roles.NeutralRoles.WraithCaller;
using UnityEngine;
using NewMod.Utilities;
using Rewired;
using System.Collections.Generic;
using System.Linq;

namespace NewMod.Buttons.WraithCaller
{
/// <summary>
/// Defines the Call Wraith ability button for the Wraith Caller role.
/// </summary>
public class CallWraithButton : CustomActionButton
{
/// <summary>
/// The name displayed on the button.
/// </summary>
public override string Name => "Call Wraith";

/// <summary>
/// The cooldown time for the Call Wraith ability, as set in <see cref="WraithCallerOptions"/>.
/// </summary>
public override float Cooldown => OptionGroupSingleton<WraithCallerOptions>.Instance.CallWraithCooldown;

/// <summary>
/// The maximum uses for the Call Wraith ability, as set in <see cref="WraithCallerOptions"/>.
/// </summary>
public override int MaxUses => (int)OptionGroupSingleton<WraithCallerOptions>.Instance.CallWraithMaxUses;

/// <summary>
/// Location on the screen for the Call Wraith button.
/// </summary>
public override ButtonLocation Location => ButtonLocation.BottomRight;

/// <summary>
/// Default keybind for the Call Wraith ability.
/// </summary>
public override KeyboardKeyCode Defaultkeybind => KeyboardKeyCode.M;

/// <summary>
/// The duration of any effect triggered by this ability.
/// </summary>
public override float EffectDuration => 0f;

/// <summary>
/// The icon for the Call Wraith button.
/// </summary>
public override LoadableAsset<Sprite> Sprite => NewModAsset.CallWraith;

/// <summary>
/// Enables the button for the Wraith Caller role only.
/// </summary>
/// <param name="role">Current player's role</param>
/// <returns>True if role is Wraith Caller, otherwise false</returns>
public override bool Enabled(RoleBehaviour role)
{
return role is Wraith;
}

/// <summary>
/// Triggered when the Call Wraith button is clicked.
/// </summary>
protected override void OnClick()
{
//TODO: Replace this with the custom minigame once it’s fixed
CustomPlayerMenu menu = CustomPlayerMenu.Create();

SetTimerPaused(true);

var allowedPlayers = new HashSet<byte>();

foreach (var info in GameData.Instance.AllPlayers)
{
if (info.PlayerId == PlayerControl.LocalPlayer.PlayerId) continue;
if (info.IsDead || info.Disconnected) continue;

allowedPlayers.Add(info.PlayerId);
}

menu.Begin(player => allowedPlayers.Contains(player.PlayerId) && !player.notRealPlayer,
player =>
{
menu.Close();
WraithCallerUtilities.RpcSummonNPC(PlayerControl.LocalPlayer, player);
SetTimerPaused(false);
});

foreach (var panel in menu.potentialVictims)
{
var icon = panel.GetComponentsInChildren<SpriteRenderer>(true).FirstOrDefault(sr => sr.name == "ShapeshifterIcon");
icon.sprite = NewModAsset.WraithIcon.LoadAsset();
}
}
}
}
67 changes: 67 additions & 0 deletions NewMod/Components/Birthday/Toast.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
using System;
using System.Collections;
using Reactor.Utilities;
using TMPro;
using UnityEngine;
using NewMod;
using NewMod.Utilities;
using Reactor.Utilities.Attributes;
using Il2CppInterop.Runtime.Attributes;

[RegisterInIl2Cpp]
public class Toast(IntPtr ptr) : MonoBehaviour(ptr)
{
public SpriteRenderer toastRend;
public TextMeshPro TimerText;
public bool isExpanded = false;
public void Awake()
{
toastRend = transform.Find("Background").GetComponent<SpriteRenderer>();
TimerText = transform.Find("Timer").GetComponent<TextMeshPro>();
}
public static Toast CreateToast()
{
var gameObject = Instantiate(NewModAsset.Toast.LoadAsset(), HudManager.Instance.transform);
var toast = gameObject.AddComponent<Toast>();
return toast;
}
[HideFromIl2Cpp]
public void SetText(string msg)
{
if (TimerText) TimerText.text = msg;
}

[HideFromIl2Cpp]
public void StartCountdown(TimeSpan duration)
{
Coroutines.Start(CoCountdown(duration));
}
[HideFromIl2Cpp]
public IEnumerator CoCountdown(TimeSpan span)
{
var end = DateTime.UtcNow + span;
while (true)
{
var left = end - DateTime.UtcNow;
if (left.TotalSeconds <= 0) break;

if (TimerText)
TimerText.text = Utils.FormatSpan(left);

yield return new WaitForSecondsRealtime(0.2f);
}
if (TimerText) TimerText.text = "00:00:00:00";

DisconnectAllPlayers();
}
[HideFromIl2Cpp]
public static void DisconnectAllPlayers()
{
var client = AmongUsClient.Instance;
if (client.GameState == InnerNet.InnerNetClient.GameStates.Started) return;

client.LastCustomDisconnect =
"The Birthday Update is now live! Please restart to see the new lobby and menu style.";
client.HandleDisconnect(DisconnectReasons.Custom);
}
}
Loading
Loading