mirror of
https://github.com/Gurge44/EndlessHostRoles.git
synced 2026-10-19 15:51:58 +00:00
Add Transposer
This commit is contained in:
1 parent
01fa31824b
commit
f100926055
9 files changed
+156
-14
No files matched your search
@@ -118,6 +118,7 @@ public enum CustomRoles
|
||||
Swooper,
|
||||
Stealth,
|
||||
TimeThief,
|
||||
Transposer,
|
||||
Trapster,
|
||||
Trickster,
|
||||
Twister,
|
||||
|
||||
@@ -186,6 +186,7 @@ internal static class CustomRolesHelper
|
||||
CustomRoles.Freezer => CustomRoles.Shapeshifter,
|
||||
CustomRoles.Changeling => CustomRoles.Phantom,
|
||||
CustomRoles.Swapster => CustomRoles.Shapeshifter,
|
||||
CustomRoles.Transposer => CustomRoles.Shapeshifter,
|
||||
CustomRoles.Kamikaze => CustomRoles.Impostor,
|
||||
CustomRoles.Librarian => CustomRoles.Shapeshifter,
|
||||
CustomRoles.Cantankerous => CustomRoles.Impostor,
|
||||
@@ -802,6 +803,7 @@ internal static class CustomRolesHelper
|
||||
CustomRoles.Freezer or
|
||||
CustomRoles.Changeling or
|
||||
CustomRoles.Swapster or
|
||||
CustomRoles.Transposer or
|
||||
CustomRoles.Loner or
|
||||
CustomRoles.Kamikaze or
|
||||
CustomRoles.Librarian or
|
||||
@@ -1071,6 +1073,7 @@ internal static class CustomRolesHelper
|
||||
CustomRoles.Glitch or
|
||||
CustomRoles.Illusionist or
|
||||
CustomRoles.Swapster or
|
||||
CustomRoles.Transposer or
|
||||
CustomRoles.Echo or
|
||||
CustomRoles.Hangman or
|
||||
CustomRoles.Generator;
|
||||
@@ -1313,6 +1316,7 @@ internal static class CustomRolesHelper
|
||||
CustomRoles.Swiftclaw => RoleOptionType.Impostor_Concealing,
|
||||
CustomRoles.Swooper => RoleOptionType.Impostor_Concealing,
|
||||
CustomRoles.Stealth => RoleOptionType.Impostor_Concealing,
|
||||
CustomRoles.Transposer => RoleOptionType.Impostor_Concealing,
|
||||
CustomRoles.Trickster => RoleOptionType.Impostor_Concealing,
|
||||
CustomRoles.Undertaker => RoleOptionType.Impostor_Concealing,
|
||||
CustomRoles.Vampire => RoleOptionType.Impostor_Concealing,
|
||||
|
||||
@@ -570,6 +570,7 @@ public static class HudSpritePatch
|
||||
}
|
||||
case CustomRoles.Transporter when player.GetRoleTypes() == RoleTypes.Shapeshifter:
|
||||
case CustomRoles.Swapster:
|
||||
case CustomRoles.Transposer:
|
||||
{
|
||||
newAbilityButton = CustomButton.Get("Transport");
|
||||
break;
|
||||
|
||||
@@ -931,7 +931,7 @@ internal static class ShapeshiftPatch
|
||||
if (!shapeshifting && !shapeshifter.Is(CustomRoles.Glitch) && isSSneeded)
|
||||
LateTask.New(() => Main.Instance.StartCoroutine(NotifyEveryoneAsync()), 1.2f, "ShapeShiftNotify");
|
||||
|
||||
if (!(shapeshifting && doSSwithoutAnim) && !isSSneeded && !Swapster.FirstSwapTarget.ContainsKey(shapeshifter.PlayerId) && !Transporter.FirstSwapTarget.ContainsKey(shapeshifter.PlayerId))
|
||||
if (!(shapeshifting && doSSwithoutAnim) && !isSSneeded && !Swapster.FirstSwapTarget.ContainsKey(shapeshifter.PlayerId) && !Transporter.FirstSwapTarget.ContainsKey(shapeshifter.PlayerId) && !Transposer.FirstSwapTarget.ContainsKey(shapeshifter.PlayerId))
|
||||
LateTask.New(shapeshifter.RpcResetAbilityCooldown, 0.01f, log: false);
|
||||
|
||||
if (!isSSneeded)
|
||||
|
||||
@@ -2283,6 +2283,9 @@
|
||||
"TimeThiefDecreaseMeetingTime": "Lower Meeting Time by",
|
||||
"TimeThiefLowerLimitVotingTime": "Minimum Voting Time",
|
||||
"TimeThiefReturnStolenTimeUponDeath": "Return Stolen Time Upon Death",
|
||||
"Transposer": "Transposer",
|
||||
"TransposerInfo": "Swap Players' Appearance",
|
||||
"TransposerInfoLong": "(Impostors):\\nAs the Transposer, you can select 2 players using your shapeshift menu to forcefully shapeshift them into each other for some time.",
|
||||
"Trapster": "Trapster",
|
||||
"TrapsterInfo": "Start a killing chain",
|
||||
"TrapsterInfoLong": "(Impostors):\\nAs the Trapster, you can vanish/pet to create a fake dead body. Anyone who reports this body will die, and depending on settings, the body will be reported.\\n\\n(Legacy Version):\\nIn the game, the Trapster kills a player and then puts a trap on their body. If another player reports the dead body and it has the Trapster's trap on it, the player who reports it will die instantly without the body getting reported. The player killed by the Trapster's trap will also become a Trapster. This chain reaction continues until no more players are left to become Trapsters. However, the Trapster will die immediately after making a kill. It's worth noting that the Trapster's own dead body cannot trigger their trap.",
|
||||
|
||||
@@ -55,11 +55,7 @@ internal class Transporter : RoleBase
|
||||
{
|
||||
if (!shapeshifting) return true;
|
||||
|
||||
if (shapeshifter == null || target == null || shapeshifter == target || !shapeshifter.IsAlive() || !target.IsAlive())
|
||||
return false;
|
||||
|
||||
if (shapeshifter.GetAbilityUseLimit() < 1f)
|
||||
return false;
|
||||
if (!target.IsAlive() || shapeshifter.GetAbilityUseLimit() < 1f) return false;
|
||||
|
||||
if (FirstSwapTarget.TryGetValue(shapeshifter.PlayerId, out byte firstTargetId))
|
||||
{
|
||||
@@ -71,7 +67,7 @@ internal class Transporter : RoleBase
|
||||
|
||||
PlayerControl firstTarget = firstTargetId.GetPlayer();
|
||||
|
||||
if (firstTarget == null || !firstTarget.IsAlive())
|
||||
if (!firstTarget || !firstTarget.IsAlive())
|
||||
{
|
||||
FirstSwapTarget.Remove(shapeshifter.PlayerId);
|
||||
shapeshifter.Notify(CustomRoles.Impostor.ColoredTextByRole(Translator.GetString("ErrorTeleport")));
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
using System;
|
||||
using AmongUs.GameOptions;
|
||||
using AmongUs.GameOptions;
|
||||
using Hazel;
|
||||
using InnerNet;
|
||||
|
||||
namespace EHR.Roles;
|
||||
|
||||
|
||||
@@ -0,0 +1,134 @@
|
||||
using System.Collections.Generic;
|
||||
using AmongUs.GameOptions;
|
||||
using Hazel;
|
||||
|
||||
namespace EHR.Roles;
|
||||
|
||||
public class Transposer : RoleBase
|
||||
{
|
||||
public static bool On;
|
||||
|
||||
public static Dictionary<byte, byte> FirstSwapTarget = [];
|
||||
|
||||
private static OptionItem AbilityCooldown;
|
||||
private static OptionItem AbilityDuration;
|
||||
private static OptionItem AbilityUseLimit;
|
||||
private static OptionItem AbilityUseGainWithEachKill;
|
||||
|
||||
public override bool IsEnable => On;
|
||||
|
||||
public override void SetupCustomOption()
|
||||
{
|
||||
StartSetup(659600)
|
||||
.AutoSetupOption(ref AbilityCooldown, 30f, new FloatValueRule(0f, 120f, 0.5f), OptionFormat.Seconds)
|
||||
.AutoSetupOption(ref AbilityDuration, 15f, new FloatValueRule(0f, 120f, 0.5f), OptionFormat.Seconds)
|
||||
.AutoSetupOption(ref AbilityUseLimit, 1f, new FloatValueRule(0, 20, 0.05f), OptionFormat.Times)
|
||||
.AutoSetupOption(ref AbilityUseGainWithEachKill, 0.5f, new FloatValueRule(0f, 5f, 0.1f), OptionFormat.Times);
|
||||
}
|
||||
|
||||
public override void Init()
|
||||
{
|
||||
On = false;
|
||||
FirstSwapTarget = [];
|
||||
}
|
||||
|
||||
public override void Add(byte playerId)
|
||||
{
|
||||
On = true;
|
||||
playerId.SetAbilityUseLimit(AbilityUseLimit.GetFloat());
|
||||
}
|
||||
|
||||
public override void Remove(byte playerId)
|
||||
{
|
||||
FirstSwapTarget.Remove(playerId);
|
||||
}
|
||||
|
||||
public override void ApplyGameOptions(IGameOptions opt, byte playerId)
|
||||
{
|
||||
AURoleOptions.ShapeshifterCooldown = AbilityCooldown.GetFloat();
|
||||
AURoleOptions.ShapeshifterDuration = 1f;
|
||||
}
|
||||
|
||||
public override bool OnShapeshift(PlayerControl transposer, PlayerControl target, bool shapeshifting)
|
||||
{
|
||||
if (!shapeshifting) return true;
|
||||
|
||||
if (FirstSwapTarget.TryGetValue(transposer.PlayerId, out byte firstTargetId))
|
||||
{
|
||||
PlayerControl firstTarget = Utils.GetPlayerById(firstTargetId);
|
||||
|
||||
if (firstTarget && firstTarget.IsAlive() && target.IsAlive())
|
||||
{
|
||||
transposer.RpcRemoveAbilityUse(notify: false);
|
||||
|
||||
CustomRpcSender sender = CustomRpcSender.Create("Transposer", SendOption.Reliable);
|
||||
sender.StartMessage();
|
||||
sender.StartRpc(target.NetId, RpcCalls.Shapeshift)
|
||||
.WriteNetObject(firstTarget)
|
||||
.Write(false)
|
||||
.EndRpc();
|
||||
sender.StartRpc(firstTarget.NetId, RpcCalls.Shapeshift)
|
||||
.WriteNetObject(target)
|
||||
.Write(false)
|
||||
.EndRpc();
|
||||
sender.SendMessage();
|
||||
|
||||
try
|
||||
{
|
||||
firstTarget.Shapeshift(target, false);
|
||||
target.Shapeshift(firstTarget, false);
|
||||
}
|
||||
catch { }
|
||||
|
||||
LateTask.New(() =>
|
||||
{
|
||||
if (!GameStates.IsInTask || ExileController.Instance || AntiBlackout.SkipTasks || ReportDeadBodyPatch.MeetingStarted) return;
|
||||
|
||||
if (transposer && transposer.IsAlive())
|
||||
transposer.RpcResetAbilityCooldown();
|
||||
|
||||
bool hasValue = false;
|
||||
CustomRpcSender writer = CustomRpcSender.Create("Transposer Revert", SendOption.Reliable);
|
||||
writer.StartMessage();
|
||||
|
||||
if (firstTarget && firstTarget.IsAlive() && firstTarget.IsShifted())
|
||||
{
|
||||
hasValue = true;
|
||||
try { firstTarget.Shapeshift(firstTarget, false); } catch { }
|
||||
writer.StartRpc(firstTarget.NetId, RpcCalls.Shapeshift)
|
||||
.WriteNetObject(firstTarget)
|
||||
.Write(false)
|
||||
.EndRpc();
|
||||
}
|
||||
|
||||
if (target && target.IsAlive() && target.IsShifted())
|
||||
{
|
||||
hasValue = true;
|
||||
try { target.Shapeshift(target, false); } catch { }
|
||||
writer.StartRpc(target.NetId, RpcCalls.Shapeshift)
|
||||
.WriteNetObject(target)
|
||||
.Write(false)
|
||||
.EndRpc();
|
||||
}
|
||||
|
||||
writer.SendMessage(dispose: !hasValue);
|
||||
|
||||
}, AbilityDuration.GetFloat(), "Transposer ability");
|
||||
}
|
||||
|
||||
FirstSwapTarget.Remove(transposer.PlayerId);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (transposer.GetAbilityUseLimit() < 1f) return false;
|
||||
FirstSwapTarget[transposer.PlayerId] = target.PlayerId;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void SetButtonTexts(HudManager hud, byte id)
|
||||
{
|
||||
hud.AbilityButton?.OverrideText(Translator.GetString("BountyHunterChangeButtonText"));
|
||||
}
|
||||
}
|
||||
@@ -44,14 +44,19 @@ internal class Swapster : RoleBase
|
||||
|
||||
public override bool OnShapeshift(PlayerControl swapster, PlayerControl target, bool shapeshifting)
|
||||
{
|
||||
if (swapster == null || target == null || swapster == target || !shapeshifting) return true;
|
||||
if (!shapeshifting) return true;
|
||||
|
||||
if (FirstSwapTarget.TryGetValue(swapster.PlayerId, out byte firstTargetId))
|
||||
{
|
||||
PlayerControl firstTarget = Utils.GetPlayerById(firstTargetId);
|
||||
Vector2 pos = firstTarget.Pos();
|
||||
firstTarget.TP(target);
|
||||
target.TP(pos);
|
||||
|
||||
if (firstTarget && firstTarget.IsAlive())
|
||||
{
|
||||
Vector2 pos = firstTarget.Pos();
|
||||
firstTarget.TP(target);
|
||||
target.TP(pos);
|
||||
}
|
||||
|
||||
FirstSwapTarget.Remove(swapster.PlayerId);
|
||||
}
|
||||
else
|
||||
|
||||
Reference in new issue
Block a user