mirror of
https://github.com/Gurge44/EndlessHostRoles.git
synced 2026-10-28 09:39:20 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e9f3e02248 | ||
|
|
120a3acd70 | ||
|
|
9493b533d3 | ||
|
|
a738c1e4d7 | ||
|
|
568c09b90d | ||
|
|
4ec1e7367d | ||
|
|
837ee1311d | ||
|
|
814c24e26b | ||
|
|
a4354c56f2 | ||
|
|
e2afc86283 | ||
|
|
a699031050 | ||
|
|
6fc0496b20 | ||
|
|
ab4b15c3f4 | ||
|
|
247a6a8dc9 | ||
|
|
0bd0656abd | ||
|
|
4e80042324 | ||
|
|
e135e75efc | ||
|
|
ed02400090 | ||
|
|
15f229e458 | ||
|
|
f7dffc84e8 | ||
|
|
3c0b86ab14 | ||
|
|
ef8f0e1337 | ||
|
|
28da21dfb4 | ||
|
|
81e2d4e2d5 | ||
|
|
2c05cd6b99 | ||
|
|
c458d15c02 | ||
|
|
4ba0049bf3 | ||
|
|
a962374eeb | ||
|
|
7e7f30b75e | ||
|
|
15e073c932 | ||
|
|
14229f6a53 | ||
|
|
fdffd045db | ||
|
|
6e25888b7f | ||
|
|
def0087782 | ||
|
|
df18bb1064 |
No files matched your search
@@ -113,35 +113,48 @@ jobs:
|
||||
name: ehr
|
||||
path: artifacts/ehr
|
||||
|
||||
- name: Prepare release folder
|
||||
run: mkdir -p release
|
||||
- name: Prepare release folders
|
||||
run: |
|
||||
mkdir -p epic
|
||||
mkdir -p steam
|
||||
|
||||
- name: Download BepInEx 6 pre-release 735
|
||||
run: |
|
||||
curl -L https://builds.bepinex.dev/projects/bepinex_be/735/BepInEx-Unity.IL2CPP-win-x64-6.0.0-be.735%2B5fef357.zip -o bepinex.zip
|
||||
unzip bepinex.zip -d release
|
||||
chmod -R u+rwX,go+rX release
|
||||
curl -L https://builds.bepinex.dev/projects/bepinex_be/735/BepInEx-Unity.IL2CPP-win-x64-6.0.0-be.735%2B5fef357.zip -o bepinex-x64.zip
|
||||
unzip bepinex-x64.zip -d epic
|
||||
chmod -R u+rwX,go+rX epic
|
||||
curl -L https://builds.bepinex.dev/projects/bepinex_be/735/BepInEx-Unity.IL2CPP-win-x86-6.0.0-be.735%2B5fef357.zip -o bepinex-x86.zip
|
||||
unzip bepinex-x86.zip -d steam
|
||||
chmod -R u+rwX,go+rX steam
|
||||
|
||||
- name: Copy EHR dll to plugins
|
||||
run: cp artifacts/ehr/EHR.dll release/BepInEx/plugins/
|
||||
run: |
|
||||
cp artifacts/ehr/EHR.dll epic/BepInEx/plugins/
|
||||
cp artifacts/ehr/EHR.dll steam/BepInEx/plugins/
|
||||
|
||||
- name: Copy configs to BepInEx config
|
||||
run: |
|
||||
mkdir -p release/BepInEx/config/
|
||||
cp packaging/* release/BepInEx/config/
|
||||
mkdir -p epic/BepInEx/config/
|
||||
mkdir -p steam/BepInEx/config/
|
||||
cp packaging/* epic/BepInEx/config/
|
||||
cp packaging/* steam/BepInEx/config/
|
||||
|
||||
- name: Download modded regions DLL to plugins
|
||||
run: curl -L https://github.com/miniduikboot/Mini.RegionInstall/releases/download/v1.2.0/Mini.RegionInstall.dll -o release/BepInEx/plugins/Mini.RegionInstall.dll
|
||||
run: |
|
||||
curl -L https://github.com/miniduikboot/Mini.RegionInstall/releases/download/v1.2.0/Mini.RegionInstall.dll -o epic/BepInEx/plugins/Mini.RegionInstall.dll
|
||||
cp epic/BepInEx/plugins/Mini.RegionInstall.dll steam/BepInEx/plugins/Mini.RegionInstall.dll
|
||||
|
||||
- name: Steam App ID
|
||||
run : echo "945360" > steam_appid.txt
|
||||
|
||||
- name: Create Epic/MS Store ZIP
|
||||
run: |
|
||||
cd release
|
||||
cd epic
|
||||
zip -r "../EHR.v${{ github.event.inputs.version }}_Epic-Games_Microsoft-Store.zip" .
|
||||
|
||||
- name: Create Steam ZIP
|
||||
run: |
|
||||
cd release
|
||||
echo "945360" > steam_appid.txt
|
||||
cd steam
|
||||
zip -r "../EHR.v${{ github.event.inputs.version }}_Steam.zip" .
|
||||
|
||||
- name: Upload release artifacts
|
||||
@@ -213,3 +226,12 @@ jobs:
|
||||
MODNEWS_API_URL: ${{ secrets.MODNEWS_API_URL }}
|
||||
MODNEWS_API_TOKEN: ${{ secrets.MODNEWS_API_TOKEN }}
|
||||
run: python release_to_modnews.py
|
||||
# -----------------------------
|
||||
# Ping Release Channel
|
||||
# -----------------------------
|
||||
- name: Notify Discord
|
||||
run: |
|
||||
curl -H "Content-Type: application/json" \
|
||||
-X POST \
|
||||
-d "{\"content\": \"<@&1170671991343288391>\nEHR v${{ github.event.inputs.version }}\nhttps://github.com/${{ github.repository }}/releases/tag/v${{ github.event.inputs.version }}\"}" \
|
||||
${{ secrets.DISCORD_RELEASE_WEBHOOK_URL }}
|
||||
+3
-1
@@ -1,5 +1,7 @@
|
||||
# Thank you so much for finding and using EHR!
|
||||
|
||||
- An attempt at fixing the host getting kicked on vanilla regions
|
||||
- Fixed numbers appearing as * in messages on vanilla servers
|
||||
|
||||
(you better not complain about the frequency of updates)
|
||||
|
||||
---
|
||||
@@ -445,11 +445,11 @@ public static class BedWars
|
||||
.Flatten()
|
||||
.ToDictionary(x => x.Key, x => x.Value);
|
||||
|
||||
yield return new WaitForSeconds(0.2f);
|
||||
yield return new WaitForSecondsRealtime(0.2f);
|
||||
|
||||
Utils.SetChatVisibleForAll();
|
||||
|
||||
yield return new WaitForSeconds(0.2f);
|
||||
yield return new WaitForSecondsRealtime(0.2f);
|
||||
|
||||
MapNames map = Main.CurrentMap;
|
||||
Dictionary<BedWarsTeam, Base> bases = Bases[map];
|
||||
@@ -512,10 +512,10 @@ public static class BedWars
|
||||
|
||||
Data[pc.PlayerId] = data;
|
||||
|
||||
yield return new WaitForSeconds(0.2f);
|
||||
yield return new WaitForSecondsRealtime(0.2f);
|
||||
}
|
||||
|
||||
yield return new WaitForSeconds(0.5f);
|
||||
yield return new WaitForSecondsRealtime(0.5f);
|
||||
|
||||
if (GameStates.IsEnded || !GameStates.InGame || GameStates.IsLobby)
|
||||
{
|
||||
@@ -542,14 +542,14 @@ public static class BedWars
|
||||
if (bed != null) AllNetObjects[team] = new(bed, new(itemShop), new(upgradeShop));
|
||||
rooms.Add(Utils.ColorString(team.GetColor(), Translator.GetString($"{room}")));
|
||||
|
||||
yield return new WaitForSeconds(0.2f);
|
||||
yield return new WaitForSecondsRealtime(0.2f);
|
||||
}
|
||||
|
||||
yield return new WaitForSeconds(0.2f);
|
||||
yield return new WaitForSecondsRealtime(0.2f);
|
||||
|
||||
players.NotifyPlayers($"{rooms[0]}\n{string.Join(" | ", rooms.Skip(1))}", 20f, setName: false);
|
||||
|
||||
yield return new WaitForSeconds(0.2f);
|
||||
yield return new WaitForSecondsRealtime(0.2f);
|
||||
|
||||
foreach ((Item item, List<Vector2> positions) in ItemGeneratorPositions[map])
|
||||
{
|
||||
@@ -570,7 +570,7 @@ public static class BedWars
|
||||
if (generator != null) ItemGenerators.Add(generator);
|
||||
});
|
||||
|
||||
yield return new WaitForSeconds(0.2f);
|
||||
yield return new WaitForSecondsRealtime(0.2f);
|
||||
}
|
||||
|
||||
GracePeriodEnd = Utils.TimeStamp + GracePeriod;
|
||||
@@ -808,7 +808,7 @@ public static class BedWars
|
||||
if (pc == null) yield break;
|
||||
|
||||
pc.Notify(string.Format(Translator.GetString("Bedwars.ReviveCountdown"), time), overrideAll: true, sendOption: SendOption.None);
|
||||
yield return new WaitForSeconds(1f);
|
||||
yield return new WaitForSecondsRealtime(1f);
|
||||
time--;
|
||||
}
|
||||
|
||||
|
||||
@@ -297,7 +297,7 @@ public static class CaptureTheFlag
|
||||
|
||||
public static IEnumerator OnGameStart()
|
||||
{
|
||||
yield return new WaitForSeconds(0.2f);
|
||||
yield return new WaitForSecondsRealtime(0.2f);
|
||||
|
||||
Main.AllPlayerKillCooldown.SetAllValues(TagCooldown.GetFloat());
|
||||
|
||||
@@ -330,7 +330,7 @@ public static class CaptureTheFlag
|
||||
yield return null;
|
||||
}
|
||||
|
||||
yield return new WaitForSeconds(0.5f);
|
||||
yield return new WaitForSecondsRealtime(0.5f);
|
||||
|
||||
// Create flags
|
||||
(Vector2 Position, string RoomName) blueFlagBase = BlueFlagBase;
|
||||
@@ -367,7 +367,7 @@ public static class CaptureTheFlag
|
||||
yield return null;
|
||||
}
|
||||
|
||||
yield return new WaitForSeconds(0.2f);
|
||||
yield return new WaitForSecondsRealtime(0.2f);
|
||||
|
||||
try
|
||||
{
|
||||
@@ -412,7 +412,7 @@ public static class CaptureTheFlag
|
||||
}
|
||||
catch (Exception e) { Utils.ThrowException(e); }
|
||||
|
||||
yield return new WaitForSeconds(0.2f);
|
||||
yield return new WaitForSecondsRealtime(0.2f);
|
||||
|
||||
ValidTag = true;
|
||||
GameStartTS = Utils.TimeStamp;
|
||||
|
||||
@@ -198,7 +198,7 @@ public static class Deathrace
|
||||
|
||||
public static System.Collections.IEnumerator GameStart()
|
||||
{
|
||||
yield return new WaitForSeconds(2f);
|
||||
yield return new WaitForSecondsRealtime(2f);
|
||||
|
||||
Track = Tracks[Main.CurrentMap].ToList();
|
||||
Logger.Info($"Track: {string.Join(" » ", Track)}", "Deathrace");
|
||||
@@ -225,20 +225,20 @@ public static class Deathrace
|
||||
if (showTutorial)
|
||||
{
|
||||
players.NotifyPlayers("<#ffffff>" + Translator.GetString("Deathrace.Tutorial.Basics"), 100f);
|
||||
yield return new WaitForSeconds(Main.CurrentMap == MapNames.Airship ? 10f : 5f);
|
||||
yield return new WaitForSecondsRealtime(Main.CurrentMap == MapNames.Airship ? 10f : 5f);
|
||||
NameNotifyManager.Reset();
|
||||
}
|
||||
|
||||
var track = Track.ToList();
|
||||
if (!Clockwise) track.Reverse();
|
||||
players.NotifyPlayers("<#ffffff>" + string.Format(Translator.GetString("Deathrace.Tutorial.Track"), string.Join(" » ", track.ConvertAll(x => Translator.GetString(x.ToString())))), 100f);
|
||||
yield return new WaitForSeconds(Track.Count);
|
||||
yield return new WaitForSecondsRealtime(Track.Count);
|
||||
NameNotifyManager.Reset();
|
||||
|
||||
if (showTutorial && SpawnPowerUps)
|
||||
{
|
||||
players.NotifyPlayers("<#ffffff>" + Translator.GetString("Deathrace.Tutorial.PowerUps"), 100f);
|
||||
yield return new WaitForSeconds(4f);
|
||||
yield return new WaitForSecondsRealtime(4f);
|
||||
NameNotifyManager.Reset();
|
||||
}
|
||||
|
||||
@@ -247,7 +247,7 @@ public static class Deathrace
|
||||
}
|
||||
else if (Main.CurrentMap == MapNames.Airship)
|
||||
{
|
||||
yield return new WaitForSeconds(3f);
|
||||
yield return new WaitForSecondsRealtime(3f);
|
||||
players.MassTP(new RandomSpawn.AirshipSpawnMap().Positions[Clockwise ? Track[^1] : Track[0]]);
|
||||
}
|
||||
|
||||
@@ -255,7 +255,7 @@ public static class Deathrace
|
||||
{
|
||||
NameNotifyManager.Reset();
|
||||
players.NotifyPlayers("<#ffffff>" + string.Format(Translator.GetString("RR_ReadyQM"), i));
|
||||
yield return new WaitForSeconds(1f);
|
||||
yield return new WaitForSecondsRealtime(1f);
|
||||
}
|
||||
|
||||
NameNotifyManager.Reset();
|
||||
|
||||
@@ -356,7 +356,7 @@ public static class KingOfTheZones
|
||||
yield return null;
|
||||
}
|
||||
|
||||
yield return new WaitForSeconds(showTutorial ? 8f : 2f);
|
||||
yield return new WaitForSecondsRealtime(showTutorial ? 8f : 2f);
|
||||
NameNotifyManager.Reset();
|
||||
if (!GameStates.InGame || !Main.IntroDestroyed) goto End;
|
||||
|
||||
@@ -382,14 +382,14 @@ public static class KingOfTheZones
|
||||
};
|
||||
|
||||
aapc.NotifyPlayers($"<#ffffff>{gameEnd}</color>", 100f);
|
||||
yield return new WaitForSeconds(4f);
|
||||
yield return new WaitForSecondsRealtime(4f);
|
||||
NameNotifyManager.Reset();
|
||||
if (!GameStates.InGame || !Main.IntroDestroyed) goto End;
|
||||
|
||||
string tags = string.Format(GetString("KOTZ.Notify.Tutorial.Tagging"), tagCooldown, respawnTime);
|
||||
|
||||
aapc.NotifyPlayers($"<#ffffff>{tags}</color>", 100f);
|
||||
yield return new WaitForSeconds(4f);
|
||||
yield return new WaitForSecondsRealtime(4f);
|
||||
NameNotifyManager.Reset();
|
||||
if (!GameStates.InGame || !Main.IntroDestroyed) goto End;
|
||||
|
||||
@@ -398,7 +398,7 @@ public static class KingOfTheZones
|
||||
string zoneMovement = string.Format(GetString(AllZonesMoveAtOnce.GetBool() ? "KOTZ.Notify.Tutorial.ZonesMoving.AllAtOnce" : "KOTZ.Notify.Tutorial.ZonesMoving.Separately"), ZoneMoveTime.GetInt());
|
||||
|
||||
aapc.NotifyPlayers($"<#ffffff>{zoneMovement}</color>", 100f);
|
||||
yield return new WaitForSeconds(4f);
|
||||
yield return new WaitForSecondsRealtime(4f);
|
||||
NameNotifyManager.Reset();
|
||||
if (!GameStates.InGame || !Main.IntroDestroyed) goto End;
|
||||
|
||||
@@ -409,7 +409,7 @@ public static class KingOfTheZones
|
||||
string downTimeInfo = string.Format(GetString("KOTZ.Notify.Tutorial.ZonesMoving.Downtime"), downTime);
|
||||
|
||||
aapc.NotifyPlayers($"<#ffffff>{downTimeInfo}</color>", 100f);
|
||||
yield return new WaitForSeconds(4f);
|
||||
yield return new WaitForSecondsRealtime(4f);
|
||||
NameNotifyManager.Reset();
|
||||
if (!GameStates.InGame || !Main.IntroDestroyed) goto End;
|
||||
}
|
||||
@@ -425,7 +425,7 @@ public static class KingOfTheZones
|
||||
{
|
||||
LastShortInfo = info;
|
||||
aapc.NotifyPlayers($"<#ffffff>{info}</color>", 100f);
|
||||
yield return new WaitForSeconds(4f);
|
||||
yield return new WaitForSecondsRealtime(4f);
|
||||
NameNotifyManager.Reset();
|
||||
if (!GameStates.InGame || !Main.IntroDestroyed) goto End;
|
||||
}
|
||||
@@ -470,7 +470,7 @@ public static class KingOfTheZones
|
||||
{
|
||||
NameNotifyManager.Reset();
|
||||
aapc.NotifyPlayers($"<#ffffff>{string.Format(GetString("RR_ReadyQM"), i)}</color>", 100f);
|
||||
yield return new WaitForSeconds(1f);
|
||||
yield return new WaitForSecondsRealtime(1f);
|
||||
}
|
||||
|
||||
NameNotifyManager.Reset();
|
||||
|
||||
+3
-3
@@ -241,7 +241,7 @@ public static class Mingle
|
||||
AllRooms.RemoveWhere(x => x.ToString().Contains("Decontamination"));
|
||||
if (SubmergedCompatibility.IsSubmerged()) AllRooms.RemoveWhere(x => (byte)x > 135);
|
||||
|
||||
yield return new WaitForSeconds(Main.CurrentMap == MapNames.Airship ? 8f : 3f);
|
||||
yield return new WaitForSecondsRealtime(Main.CurrentMap == MapNames.Airship ? 8f : 3f);
|
||||
|
||||
List<PlayerControl> players = Main.AllAlivePlayerControls.ToList();
|
||||
if (Main.GM.Value) players.RemoveAll(x => x.IsHost());
|
||||
@@ -252,7 +252,7 @@ public static class Mingle
|
||||
if (showTutorial)
|
||||
{
|
||||
players.NotifyPlayers("<#ffffff>" + Translator.GetString("Mingle.Tutorial"), 100f);
|
||||
yield return new WaitForSeconds(12f);
|
||||
yield return new WaitForSecondsRealtime(12f);
|
||||
NameNotifyManager.Reset();
|
||||
}
|
||||
|
||||
@@ -260,7 +260,7 @@ public static class Mingle
|
||||
{
|
||||
NameNotifyManager.Reset();
|
||||
players.NotifyPlayers(string.Format(Translator.GetString("RR_ReadyQM"), i));
|
||||
yield return new WaitForSeconds(1f);
|
||||
yield return new WaitForSecondsRealtime(1f);
|
||||
}
|
||||
|
||||
NameNotifyManager.Reset();
|
||||
|
||||
+18
-18
@@ -270,7 +270,7 @@ public static class Quiz
|
||||
|
||||
public static IEnumerator OnGameStart()
|
||||
{
|
||||
if (Chat) yield return new WaitForSeconds(1f);
|
||||
if (Chat) yield return new WaitForSecondsRealtime(1f);
|
||||
|
||||
NoSuffix = true;
|
||||
PlayerControl[] aapc = Main.AllAlivePlayerControls;
|
||||
@@ -278,14 +278,14 @@ public static class Quiz
|
||||
|
||||
var usedRooms = string.Join('\n', UsedRooms[Main.CurrentMap].Select(x => $"{x.Key}: {GetString(x.Value.ToString())}"));
|
||||
aapc.NotifyPlayers(string.Format(GetString("Quiz.Tutorial.Basics"), usedRooms), 11f);
|
||||
yield return new WaitForSeconds(showTutorial ? 9f : 5f);
|
||||
yield return new WaitForSecondsRealtime(showTutorial ? 9f : 5f);
|
||||
if (GameStates.IsMeeting || ExileController.Instance || !GameStates.InGame || GameStates.IsLobby) yield break;
|
||||
NameNotifyManager.Reset();
|
||||
|
||||
if (showTutorial)
|
||||
{
|
||||
aapc.NotifyPlayers(GetString("Quiz.Tutorial.TestRound"));
|
||||
yield return new WaitForSeconds(3f);
|
||||
yield return new WaitForSecondsRealtime(3f);
|
||||
if (GameStates.IsMeeting || ExileController.Instance || !GameStates.InGame || GameStates.IsLobby) yield break;
|
||||
NameNotifyManager.Reset();
|
||||
|
||||
@@ -296,27 +296,27 @@ public static class Quiz
|
||||
|
||||
while (QuestionTimeLimitEndTS != 0)
|
||||
{
|
||||
yield return new WaitForSeconds(1f);
|
||||
yield return new WaitForSecondsRealtime(1f);
|
||||
if (GameStates.IsMeeting || ExileController.Instance || !GameStates.InGame || GameStates.IsLobby) yield break;
|
||||
}
|
||||
|
||||
yield return new WaitForSeconds(3f);
|
||||
yield return new WaitForSecondsRealtime(3f);
|
||||
NoSuffix = true;
|
||||
|
||||
aapc.NotifyPlayers(GetString("Quiz.Tutorial.OnWrongAnswer"), 10f);
|
||||
yield return new WaitForSeconds(3f);
|
||||
yield return new WaitForSecondsRealtime(3f);
|
||||
if (GameStates.IsMeeting || ExileController.Instance || !GameStates.InGame || GameStates.IsLobby) yield break;
|
||||
NameNotifyManager.Reset();
|
||||
|
||||
aapc.NotifyPlayers(GetString("Quiz.Tutorial.OnCorrectAnswer"));
|
||||
yield return new WaitForSeconds(2f);
|
||||
yield return new WaitForSecondsRealtime(2f);
|
||||
}
|
||||
else
|
||||
{
|
||||
NoSuffix = true;
|
||||
var settings = Settings[CurrentDifficulty];
|
||||
Main.AllAlivePlayerControls.NotifyPlayers(string.Format(GetString("Quiz.Notify.NextStage"), (int)CurrentDifficulty, settings.Rounds.GetInt(), settings.QuestionsAsked.GetInt(), settings.CorrectRequirement.GetInt(), settings.QuestionsAsked.GetInt(), settings.TimeLimit.GetInt()), 8f);
|
||||
yield return new WaitForSeconds(6f);
|
||||
yield return new WaitForSecondsRealtime(6f);
|
||||
}
|
||||
|
||||
if (GameStates.IsMeeting || ExileController.Instance || !GameStates.InGame || GameStates.IsLobby) yield break;
|
||||
@@ -334,7 +334,7 @@ public static class Quiz
|
||||
NoSuffix = true;
|
||||
var settings = Settings[CurrentDifficulty];
|
||||
Main.AllAlivePlayerControls.NotifyPlayers(string.Format(GetString("Quiz.Notify.NextStage"), (int)CurrentDifficulty, settings.Rounds.GetInt(), settings.QuestionsAsked.GetInt(), settings.CorrectRequirement.GetInt(), settings.QuestionsAsked.GetInt(), settings.TimeLimit.GetInt()), 8f);
|
||||
yield return new WaitForSeconds(6f);
|
||||
yield return new WaitForSecondsRealtime(6f);
|
||||
if (GameStates.IsMeeting || ExileController.Instance || !GameStates.InGame || GameStates.IsLobby) yield break;
|
||||
NameNotifyManager.Reset();
|
||||
}
|
||||
@@ -345,7 +345,7 @@ public static class Quiz
|
||||
|
||||
NoSuffix = true;
|
||||
Main.AllAlivePlayerControls.NotifyPlayers(string.Format(GetString("Quiz.Notify.NextRound"), Round + 1));
|
||||
yield return new WaitForSeconds(3f);
|
||||
yield return new WaitForSecondsRealtime(3f);
|
||||
if (GameStates.IsMeeting || ExileController.Instance || !GameStates.InGame || GameStates.IsLobby) yield break;
|
||||
NameNotifyManager.Reset();
|
||||
}
|
||||
@@ -459,7 +459,7 @@ public static class Quiz
|
||||
if (everyoneWasWrong) QuestionsAsked--;
|
||||
Utils.NotifyRoles();
|
||||
|
||||
yield return new WaitForSeconds(everyoneWasWrong ? aapc.Length <= 3 ? 4f : 6f : 3f);
|
||||
yield return new WaitForSecondsRealtime(everyoneWasWrong ? aapc.Length <= 3 ? 4f : 6f : 3f);
|
||||
if (GameStates.IsMeeting || ExileController.Instance || !GameStates.InGame || GameStates.IsLobby) yield break;
|
||||
|
||||
var settings = Settings[CurrentDifficulty];
|
||||
@@ -470,7 +470,7 @@ public static class Quiz
|
||||
yield break;
|
||||
}
|
||||
|
||||
yield return new WaitForSeconds(2f);
|
||||
yield return new WaitForSecondsRealtime(2f);
|
||||
|
||||
var correctRequirement = settings.CorrectRequirement.GetInt();
|
||||
List<byte> dyingPlayers = NumCorrectAnswers.Where(x => x.Value[CurrentDifficulty][Round] < correctRequirement).Select(x => x.Key).Where(x => Main.PlayerStates.TryGetValue(x, out var s) && !s.IsDead).ToList();
|
||||
@@ -496,19 +496,19 @@ public static class Quiz
|
||||
goto case 0;
|
||||
default:
|
||||
if (aapc.Length is 3 or 2) aapc.Do(x => x.RpcMakeVisible());
|
||||
yield return new WaitForSeconds(2f);
|
||||
yield return new WaitForSecondsRealtime(2f);
|
||||
AllowKills = true;
|
||||
FFAEndTS = Utils.TimeStamp + FFAEventLength.GetInt();
|
||||
var spectators = aapc.ExceptBy(dyingPlayers, x => x.PlayerId).ToArray();
|
||||
spectators.Do(x => x.ExileTemporarily());
|
||||
yield return new WaitForSeconds(0.2f);
|
||||
yield return new WaitForSecondsRealtime(0.2f);
|
||||
var stillLiving = dyingPlayers.ToValidPlayers().FindAll(x => x.IsAlive());
|
||||
stillLiving.ForEach(x => x.RpcChangeRoleBasis(CustomRoles.SerialKiller));
|
||||
Utils.SendRPC(CustomRPC.QuizSync, AllowKills);
|
||||
|
||||
while (Utils.TimeStamp < FFAEndTS)
|
||||
{
|
||||
yield return new WaitForSeconds(1f);
|
||||
yield return new WaitForSecondsRealtime(1f);
|
||||
if (GameStates.IsMeeting || ExileController.Instance || !GameStates.InGame || GameStates.IsLobby) yield break;
|
||||
Utils.NotifyRoles(SendOption: SendOption.None);
|
||||
stillLiving.RemoveAll(x => x == null || !x.IsAlive());
|
||||
@@ -535,17 +535,17 @@ public static class Quiz
|
||||
break;
|
||||
}
|
||||
|
||||
yield return new WaitForSeconds(1f);
|
||||
yield return new WaitForSecondsRealtime(1f);
|
||||
|
||||
if (Chat)
|
||||
{
|
||||
Utils.SetChatVisibleForAll();
|
||||
yield return new WaitForSeconds(1f);
|
||||
yield return new WaitForSecondsRealtime(1f);
|
||||
}
|
||||
|
||||
spectators.Do(x => x.TP(location));
|
||||
|
||||
yield return new WaitForSeconds(2f);
|
||||
yield return new WaitForSecondsRealtime(2f);
|
||||
if (GameStates.IsMeeting || ExileController.Instance || !GameStates.InGame || GameStates.IsLobby) yield break;
|
||||
|
||||
FFAEndTS = 0;
|
||||
|
||||
@@ -210,7 +210,7 @@ public static class RoomRush
|
||||
|
||||
Map = RandomSpawn.SpawnMap.GetSpawnMap();
|
||||
|
||||
yield return new WaitForSeconds(Main.CurrentMap == MapNames.Airship ? 8f : 3f);
|
||||
yield return new WaitForSecondsRealtime(Main.CurrentMap == MapNames.Airship ? 8f : 3f);
|
||||
|
||||
PlayerControl[] aapc = Main.AllAlivePlayerControls;
|
||||
aapc.Do(x => x.RpcSetCustomRole(CustomRoles.RRPlayer));
|
||||
@@ -288,7 +288,7 @@ public static class RoomRush
|
||||
}
|
||||
|
||||
aapc.NotifyPlayers(sb.Insert(0, "<#ffffff>").Append("</color>").ToString().Trim(), 100f);
|
||||
yield return new WaitForSeconds(readingTime);
|
||||
yield return new WaitForSecondsRealtime(readingTime);
|
||||
if (!GameStates.InGame) yield break;
|
||||
}
|
||||
|
||||
@@ -296,7 +296,7 @@ public static class RoomRush
|
||||
{
|
||||
NameNotifyManager.Reset();
|
||||
aapc.NotifyPlayers(string.Format(Translator.GetString("RR_ReadyQM"), i));
|
||||
yield return new WaitForSeconds(1f);
|
||||
yield return new WaitForSecondsRealtime(1f);
|
||||
}
|
||||
|
||||
if (ventLimit > 0)
|
||||
|
||||
+18
-15
@@ -389,7 +389,7 @@ public static class TheMindGame
|
||||
pc.Notify(string.Format(Translator.GetString(sameAsSomeoneElse ? "TMG.Notify.SamePick" : "TMG.Notify.Pick"), pick, sameAsSomeoneElse ? otherId.ColoredPlayerName() : string.Empty));
|
||||
}
|
||||
|
||||
yield return new WaitForSeconds(3f);
|
||||
yield return new WaitForSecondsRealtime(3f);
|
||||
if (Stop) yield break;
|
||||
NameNotifyManager.Reset();
|
||||
|
||||
@@ -533,7 +533,7 @@ public static class TheMindGame
|
||||
pc.Notify(string.Format(Translator.GetString(sameAsSomeoneElse ? "TMG.Notify.SamePick" : "TMG.Notify.Pick"), pick, sameAsSomeoneElse ? otherPc.PlayerId.ColoredPlayerName() : string.Empty));
|
||||
}
|
||||
|
||||
yield return new WaitForSeconds(3f);
|
||||
yield return new WaitForSecondsRealtime(3f);
|
||||
if (Stop) yield break;
|
||||
NameNotifyManager.Reset();
|
||||
|
||||
@@ -559,7 +559,7 @@ public static class TheMindGame
|
||||
while (true)
|
||||
{
|
||||
PlayerControl.LocalPlayer.NoCheckStartMeeting(null, true);
|
||||
yield return new WaitForSeconds(8f);
|
||||
yield return new WaitForSecondsRealtime(8f);
|
||||
if (!GameStates.InGame || GameStates.IsLobby || GameStates.IsEnded) yield break;
|
||||
|
||||
WinningBriefcaseHolderId = Main.AllAlivePlayerControls.RandomElement().PlayerId;
|
||||
@@ -569,27 +569,27 @@ public static class TheMindGame
|
||||
|
||||
while (GameStates.IsMeeting || ExileController.Instance || AntiBlackout.SkipTasks)
|
||||
{
|
||||
yield return new WaitForSeconds(1f);
|
||||
yield return new WaitForSecondsRealtime(1f);
|
||||
if (!GameStates.InGame || GameStates.IsLobby || GameStates.IsEnded) yield break;
|
||||
}
|
||||
|
||||
yield return new WaitForSeconds(1f);
|
||||
yield return new WaitForSecondsRealtime(1f);
|
||||
|
||||
while (GameStates.IsMeeting || ExileController.Instance || AntiBlackout.SkipTasks)
|
||||
{
|
||||
yield return new WaitForSeconds(1f);
|
||||
yield return new WaitForSecondsRealtime(1f);
|
||||
if (!GameStates.InGame || GameStates.IsLobby || GameStates.IsEnded) yield break;
|
||||
}
|
||||
|
||||
yield return new WaitForSeconds(1f);
|
||||
yield return new WaitForSecondsRealtime(1f);
|
||||
|
||||
while (GameStates.IsMeeting || ExileController.Instance || AntiBlackout.SkipTasks)
|
||||
{
|
||||
yield return new WaitForSeconds(1f);
|
||||
yield return new WaitForSecondsRealtime(1f);
|
||||
if (!GameStates.InGame || GameStates.IsLobby || GameStates.IsEnded) yield break;
|
||||
}
|
||||
|
||||
yield return new WaitForSeconds(1f);
|
||||
yield return new WaitForSecondsRealtime(1f);
|
||||
|
||||
aapc = Main.AllAlivePlayerControls;
|
||||
|
||||
@@ -627,7 +627,7 @@ public static class TheMindGame
|
||||
NameNotifyManager.Reset();
|
||||
Main.AllAlivePlayerControls.NotifyPlayers(join, 100f);
|
||||
ProceedingInCountdownEndTS = Utils.TimeStamp + 5;
|
||||
yield return new WaitForSeconds(5f);
|
||||
yield return new WaitForSecondsRealtime(5f);
|
||||
if (Stop) yield break;
|
||||
|
||||
Dictionary<byte, int> round4Points = ranking.ToDictionary(x => x, x => (ranking.Count - ranking.IndexOf(x)) * 10);
|
||||
@@ -675,7 +675,7 @@ public static class TheMindGame
|
||||
string str = Translator.GetString(key);
|
||||
Main.AllAlivePlayerControls.NotifyPlayers(args.Length == 0 ? str : string.Format(str, args), 100f);
|
||||
ProceedingInCountdownEndTS = Utils.TimeStamp + time;
|
||||
yield return new WaitForSeconds(time);
|
||||
yield return new WaitForSecondsRealtime(time);
|
||||
NameNotifyManager.Reset();
|
||||
}
|
||||
|
||||
@@ -692,7 +692,7 @@ public static class TheMindGame
|
||||
pc.TP(RandomSpawn.SpawnMap.GetSpawnMap().Positions[groupRoom]);
|
||||
}
|
||||
|
||||
yield return new WaitForSeconds(2f);
|
||||
yield return new WaitForSecondsRealtime(2f);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -790,11 +790,14 @@ public static class TheMindGame
|
||||
{
|
||||
WinningBriefcaseLastHolderId = id;
|
||||
WinningBriefcaseHolderId = pc.PlayerId;
|
||||
Utils.SendMessage(string.Format(Translator.GetString("TMG.Message.LassoedWinningBriefcaseSelf"), id.ColoredPlayerName()), pc.PlayerId, "<#00ff00>✓</color>");
|
||||
Utils.SendMessage(Translator.GetString("TMG.Message.LassoedWinningBriefcase"), id, "<#ffff00>⚠</color>");
|
||||
LateTask.New(() =>
|
||||
{
|
||||
Utils.SendMessage(string.Format(Translator.GetString("TMG.Message.LassoedWinningBriefcaseSelf"), id.ColoredPlayerName()), pc.PlayerId, "<#00ff00>✓</color>");
|
||||
Utils.SendMessage(Translator.GetString("TMG.Message.LassoedWinningBriefcase"), id, "<#ffff00>⚠</color>");
|
||||
}, 0.2f);
|
||||
}
|
||||
else
|
||||
Utils.SendMessage(string.Format(Translator.GetString("TMG.Message.LassoedEmptyBriefcase"), id.ColoredPlayerName()), pc.PlayerId, "<#ffa500>-</color>");
|
||||
LateTask.New(() => Utils.SendMessage(string.Format(Translator.GetString("TMG.Message.LassoedEmptyBriefcase"), id.ColoredPlayerName()), pc.PlayerId, "<#ffa500>-</color>"), 0.2f);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -42,8 +42,8 @@ public class Main : BasePlugin
|
||||
private const string DebugKeyHash = "c0fd562955ba56af3ae20d7ec9e64c664f0facecef4b3e366e109306adeae29d";
|
||||
private const string DebugKeySalt = "59687b";
|
||||
private const string PluginGuid = "com.gurge44.endlesshostroles";
|
||||
public const string PluginVersion = "7.1.1";
|
||||
public const string PluginDisplayVersion = "7.1.1";
|
||||
public const string PluginVersion = "7.1.6";
|
||||
public const string PluginDisplayVersion = "7.1.6";
|
||||
public const bool TestBuild = false;
|
||||
|
||||
public const string NeutralColor = "#ffab1b";
|
||||
|
||||
@@ -260,7 +260,7 @@ public static class Achievements
|
||||
IEnumerator FetchAchievementsFromApiAsync()
|
||||
{
|
||||
while (PlayerControl.LocalPlayer == null) yield return null;
|
||||
yield return new WaitForSeconds(3f);
|
||||
yield return new WaitForSecondsRealtime(3f);
|
||||
|
||||
string userId = PlayerControl.LocalPlayer.GetClient().GetHashedPuid();
|
||||
var url = $"{ApiLoadEndpoint}?userId={userId}";
|
||||
|
||||
@@ -25,7 +25,7 @@ public static class AntiBlackout
|
||||
|
||||
PlayerControl[] players = Main.AllAlivePlayerControls;
|
||||
if (CheckForEndVotingPatch.TempExiledPlayer != null) players = players.Where(x => x.PlayerId != CheckForEndVotingPatch.TempExiledPlayer.PlayerId).ToArray();
|
||||
PlayerControl dummyImp = players.OrderByDescending(x => x.GetRoleMap().RoleType != RoleTypes.Detective).ThenByDescending(x => x.IsModdedClient()).MinBy(x => x.PlayerId);
|
||||
PlayerControl dummyImp = players.OrderByDescending(x => x.GetCustomRole() is not (CustomRoles.DetectiveEHR or CustomRoles.Detective) && !x.Is(CustomRoles.Examiner)).ThenByDescending(x => x.IsModdedClient()).MinBy(x => x.PlayerId);
|
||||
|
||||
if (players.Length == 2)
|
||||
{
|
||||
@@ -49,9 +49,9 @@ public static class AntiBlackout
|
||||
}
|
||||
|
||||
dummyImp.RpcSetRoleGlobal(RoleTypes.Impostor);
|
||||
players.Without(dummyImp).Where(x => x.GetRoleMap().RoleType != RoleTypes.Detective).Do(x => x.RpcSetRoleGlobal(RoleTypes.Crewmate));
|
||||
players.Without(dummyImp).Where(x => x.GetCustomRole() is not (CustomRoles.DetectiveEHR or CustomRoles.Detective) && !x.Is(CustomRoles.Examiner)).Do(x => x.RpcSetRoleGlobal(RoleTypes.Crewmate));
|
||||
|
||||
Main.AllPlayerControls.DoIf(x => !x.IsAlive() && x.Data != null && x.Data.IsDead, x => x.RpcSetRoleGlobal(GhostRolesManager.AssignedGhostRoles.TryGetValue(x.PlayerId, out var ghostRole) ? ghostRole.Instance.RoleTypes : RoleTypes.CrewmateGhost));
|
||||
Main.AllPlayerControls.DoIf(x => !x.IsAlive() && x.Data != null && x.Data.IsDead && (!x.AmOwner || !Utils.TempReviveHostRunning), x => x.RpcSetRoleGlobal(GhostRolesManager.AssignedGhostRoles.TryGetValue(x.PlayerId, out var ghostRole) ? ghostRole.Instance.RoleTypes : RoleTypes.CrewmateGhost));
|
||||
}
|
||||
|
||||
// After the ejection screen, we revert the role types to their actual values.
|
||||
@@ -69,6 +69,8 @@ public static class AntiBlackout
|
||||
{
|
||||
try
|
||||
{
|
||||
if (pc.AmOwner && Utils.TempReviveHostRunning) continue;
|
||||
|
||||
NetworkedPlayerInfo data = pc.Data;
|
||||
|
||||
if (data != null && !data.IsDead && !data.Disconnected && !pc.IsAlive())
|
||||
@@ -87,7 +89,7 @@ public static class AntiBlackout
|
||||
{
|
||||
PlayerControl seer = seerId.GetPlayer();
|
||||
PlayerControl target = targetId.GetPlayer();
|
||||
if (seer == null || target == null) continue;
|
||||
if (seer == null || target == null || (seerId == targetId && seer.AmOwner && Utils.TempReviveHostRunning)) continue;
|
||||
|
||||
if (target.IsAlive()) target.RpcSetRoleDesync(roleType, seer.OwnerId);
|
||||
else target.RpcSetRoleDesync(GhostRolesManager.AssignedGhostRoles.TryGetValue(targetId, out var ghostRole) ? ghostRole.Instance.RoleTypes : seerId == targetId && !(target.Is(CustomRoleTypes.Impostor) && Options.DeadImpCantSabotage.GetBool()) && Main.PlayerStates.TryGetValue(targetId, out var state) && state.Role.CanUseSabotage(target) ? RoleTypes.ImpostorGhost : RoleTypes.CrewmateGhost, seer.OwnerId);
|
||||
@@ -123,6 +125,8 @@ public static class AntiBlackout
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pc.AmOwner && Utils.TempReviveHostRunning) continue;
|
||||
|
||||
// Ensure that the players who are considered dead by the mod are actually dead in the game.
|
||||
pc.Exiled();
|
||||
MessageWriter writer = AmongUsClient.Instance.StartRpcImmediately(pc.NetId, 4, SendOption.Reliable);
|
||||
|
||||
@@ -55,7 +55,7 @@ public static class AutoHaunt
|
||||
HudManager.Instance.AbilityButton.DoClick();
|
||||
}
|
||||
|
||||
yield return new WaitForSeconds(5f);
|
||||
yield return new WaitForSecondsRealtime(5f);
|
||||
}
|
||||
|
||||
if (GameStates.IsInTask && !ExileController.Instance && !AntiBlackout.SkipTasks && !PlayerControl.LocalPlayer.IsAlive() && HauntMenuMinigameStartPatch.Instance != null)
|
||||
|
||||
@@ -77,11 +77,11 @@ public static class ChatBubbleShower
|
||||
isColor1 = !isColor1;
|
||||
var text = $"<b>{title}</b>\n<size=80%><color={color}>{message}</color></size>";
|
||||
HudManagerPatch.AchievementUnlockedText = text;
|
||||
yield return new WaitForSeconds(0.2f);
|
||||
yield return new WaitForSecondsRealtime(0.2f);
|
||||
}
|
||||
|
||||
HudManagerPatch.AchievementUnlockedText = $"<b>{title}</b>\n<size=80%>{message}</size>";
|
||||
yield return new WaitForSeconds(7.25f);
|
||||
yield return new WaitForSecondsRealtime(7.25f);
|
||||
HudManagerPatch.AchievementUnlockedText = string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -191,7 +191,7 @@ namespace EHR
|
||||
{
|
||||
Logger.Info("Delaying CNO Spawn", "CustomNetObject.CreateNetObject");
|
||||
while (GameStates.InGame && !GameStates.IsEnded && (!Main.IntroDestroyed || Utils.TimeStamp - IntroCutsceneDestroyPatch.IntroDestroyTS < 10)) yield return null;
|
||||
yield return new WaitForSeconds(3f);
|
||||
yield return new WaitForSecondsRealtime(3f);
|
||||
if (!GameStates.InGame || GameStates.IsEnded || GameStates.IsMeeting || ExileController.Instance || AntiBlackout.SkipTasks) yield break;
|
||||
CreateNetObject(sprite, position);
|
||||
}
|
||||
@@ -369,7 +369,7 @@ namespace EHR
|
||||
System.Collections.IEnumerator WaitForMeetingEnd()
|
||||
{
|
||||
while (ReportDeadBodyPatch.MeetingStarted || GameStates.IsMeeting || ExileController.Instance || AntiBlackout.SkipTasks) yield return null;
|
||||
yield return new WaitForSeconds(1f);
|
||||
yield return new WaitForSecondsRealtime(1f);
|
||||
while (ReportDeadBodyPatch.MeetingStarted || GameStates.IsMeeting || ExileController.Instance || AntiBlackout.SkipTasks) yield return null;
|
||||
if (GameStates.IsEnded || !GameStates.InGame || GameStates.IsLobby) yield break;
|
||||
|
||||
@@ -420,7 +420,7 @@ namespace EHR
|
||||
}
|
||||
catch (Exception e) { Utils.ThrowException(e); }
|
||||
|
||||
yield return new WaitForSeconds(0.1f);
|
||||
yield return new WaitForSecondsRealtime(0.1f);
|
||||
|
||||
try
|
||||
{
|
||||
@@ -457,7 +457,7 @@ namespace EHR
|
||||
}
|
||||
catch (Exception e) { Utils.ThrowException(e); }
|
||||
|
||||
yield return new WaitForSeconds(0.1f);
|
||||
yield return new WaitForSecondsRealtime(0.1f);
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
@@ -103,8 +103,9 @@ internal static class CustomRoleSelector
|
||||
|
||||
switch (role)
|
||||
{
|
||||
case CustomRoles.Ventriloquist when GameStates.CurrentServerType == GameStates.ServerType.Vanilla:
|
||||
case CustomRoles.Weatherman when Main.LIMap || GameStates.CurrentServerType == GameStates.ServerType.Vanilla:
|
||||
case CustomRoles.RoomRusher when Main.LIMap:
|
||||
case CustomRoles.Weatherman when Main.LIMap:
|
||||
case CustomRoles.Doctor when Options.EveryoneSeesDeathReasons.GetBool():
|
||||
case CustomRoles.LovingCrewmate or CustomRoles.LovingImpostor when !loversData.Spawning:
|
||||
case CustomRoles.Commander when optImpNum <= 1 && Commander.CannotSpawnAsSoloImp.GetBool():
|
||||
|
||||
@@ -114,6 +114,12 @@ public class CustomRpcSender
|
||||
// StartMessage processing
|
||||
if (currentState == State.InRootMessage)
|
||||
EndMessage(startNew: true);
|
||||
else if (messages > 0) // state is Ready
|
||||
{
|
||||
doneStreams.Add(stream);
|
||||
stream = MessageWriter.Get(sendOption);
|
||||
messages = 0;
|
||||
}
|
||||
|
||||
StartMessage(targetClientId);
|
||||
}
|
||||
@@ -205,6 +211,7 @@ public class CustomRpcSender
|
||||
{
|
||||
doneStreams.Add(stream);
|
||||
stream = MessageWriter.Get(sendOption);
|
||||
messages = 0;
|
||||
}
|
||||
|
||||
if (targetClientId < 0)
|
||||
@@ -244,6 +251,7 @@ public class CustomRpcSender
|
||||
{
|
||||
doneStreams.Add(stream);
|
||||
stream = MessageWriter.Get(sendOption);
|
||||
messages = 0;
|
||||
}
|
||||
|
||||
currentRpcTarget = -2;
|
||||
@@ -274,10 +282,10 @@ public class CustomRpcSender
|
||||
throw new InvalidOperationException(errorMsg);
|
||||
}
|
||||
|
||||
if (messages >= AmongUsClient.Instance.GetMaxMessagePackingLimit())
|
||||
if (messages >= 10)
|
||||
{
|
||||
doneStreams.Add(stream);
|
||||
stream = MessageWriter.Get(sendOption);
|
||||
EndMessage(startNew: true);
|
||||
StartMessage(currentRpcTarget);
|
||||
}
|
||||
|
||||
messages++;
|
||||
|
||||
@@ -38,7 +38,7 @@ public static class DevManager
|
||||
if (request.result != UnityWebRequest.Result.Success)
|
||||
{
|
||||
Logger.Error($"Error fetching tags: {request.error}", "DevManager.FetchTags");
|
||||
yield return new WaitForSeconds(300f);
|
||||
yield return new WaitForSecondsRealtime(300f);
|
||||
yield return FetchTags();
|
||||
}
|
||||
else
|
||||
|
||||
@@ -496,7 +496,7 @@ internal static class ExtendedPlayerControl
|
||||
IEnumerator DelayBasisChange()
|
||||
{
|
||||
while (AntiBlackout.SkipTasks || ExileController.Instance) yield return null;
|
||||
yield return new WaitForSeconds(1f);
|
||||
yield return new WaitForSecondsRealtime(1f);
|
||||
Logger.Msg($"Now that the anti-blackout processing or ejection screen showing is complete, the role basis of {player.GetNameWithRole()} will be changed", "RpcChangeRoleBasis");
|
||||
player.RpcChangeRoleBasis(newCustomRole, loggerRoleMap);
|
||||
}
|
||||
@@ -674,9 +674,9 @@ internal static class ExtendedPlayerControl
|
||||
}
|
||||
|
||||
// https://github.com/Ultradragon005/TownofHost-Enhanced/blob/ea5f1e8ea87e6c19466231c305d6d36d511d5b2d/Modules/Utils.cs
|
||||
public static void SyncGeneralOptions(this CustomRpcSender sender, PlayerControl player)
|
||||
public static bool SyncGeneralOptions(this CustomRpcSender sender, PlayerControl player)
|
||||
{
|
||||
if (!AmongUsClient.Instance.AmHost || !GameStates.IsInGame || !DoRPC) return;
|
||||
if (!AmongUsClient.Instance.AmHost || !GameStates.IsInGame || !DoRPC) return false;
|
||||
|
||||
sender.AutoStartRpc(PlayerControl.LocalPlayer.NetId, (byte)CustomRPC.SyncGeneralOptions);
|
||||
sender.Write(player.PlayerId);
|
||||
@@ -686,6 +686,8 @@ internal static class ExtendedPlayerControl
|
||||
sender.Write(Main.AllPlayerKillCooldown[player.PlayerId]);
|
||||
sender.Write(Main.AllPlayerSpeed[player.PlayerId]);
|
||||
sender.EndRpc();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Next 3: https://github.com/0xDrMoe/TownofHost-Enhanced/blob/12487ce1aa7e4f5087f2300be452b5af7c04d1ff/Modules/ExtendedPlayerControl.cs#L239
|
||||
@@ -1154,7 +1156,7 @@ internal static class ExtendedPlayerControl
|
||||
yield break;
|
||||
}
|
||||
|
||||
yield return new WaitForSeconds(pc.IsAlive() ? 1f : 3f);
|
||||
yield return new WaitForSecondsRealtime(pc.IsAlive() ? 1f : 3f);
|
||||
|
||||
if (!GameStates.InGame || GameStates.IsEnded)
|
||||
{
|
||||
|
||||
@@ -594,7 +594,7 @@ public sealed class PlayerGameOptionsSender(PlayerControl player) : GameOptionsS
|
||||
}
|
||||
|
||||
state.TaskState.HasTasks = Utils.HasTasks(player.Data, false);
|
||||
if (Options.GhostCanSeeOtherVotes.GetBool() && player.Data.IsDead) opt.SetBool(BoolOptionNames.AnonymousVotes, false);
|
||||
if (Options.GhostCanSeeOtherVotes.GetBool() && !player.IsAlive()) opt.SetBool(BoolOptionNames.AnonymousVotes, false);
|
||||
|
||||
if (Options.AdditionalEmergencyCooldown.GetBool() &&
|
||||
Options.AdditionalEmergencyCooldownThreshold.GetInt() <= Utils.AllAlivePlayersCount)
|
||||
|
||||
@@ -1361,7 +1361,7 @@ public static class GuessManager
|
||||
int textIndex = 0;
|
||||
|
||||
int messages = 0;
|
||||
int packingLimit = AmongUsClient.Instance.GetMaxMessagePackingLimit();
|
||||
int packingLimit = 10;
|
||||
|
||||
var skipped = false;
|
||||
PlayerControl guesser = guesserId.GetPlayer();
|
||||
|
||||
+2
-2
@@ -22,7 +22,7 @@ internal static class LateTask
|
||||
|
||||
IEnumerator CoLateTask()
|
||||
{
|
||||
yield return new WaitForSeconds(time);
|
||||
yield return new WaitForSecondsRealtime(time);
|
||||
|
||||
try
|
||||
{
|
||||
@@ -31,7 +31,7 @@ internal static class LateTask
|
||||
if (name is not "" and not "No Name Task" && log)
|
||||
Logger.Info($"\"{name}\" is finished", "LateTask");
|
||||
}
|
||||
catch (Exception ex) { Logger.Error($"{ex.GetType()}: {ex.Message}\n in \"{name}\"\n (created at {path.Split('\\')[^1]}, by member {member}, at line {line})\n {ex.StackTrace}".Replace("\r\n", "\n"), "LateTask.Error", false, multiLine: true); }
|
||||
catch (Exception ex) { Logger.Error($"{ex.GetType()}: {ex.Message}\n in \"{name}\"\n (created at {path.Split('\\')[^1].Split('/')[^1]}, by member {member}, at line {line})\n {ex.StackTrace}".Replace("\r\n", "\n"), "LateTask.Error", false, multiLine: true); }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,7 @@ using System.Collections;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
using System.Text.RegularExpressions;
|
||||
using HarmonyLib;
|
||||
using InnerNet;
|
||||
using UnityEngine;
|
||||
@@ -41,7 +42,7 @@ public static class LobbySharingAPI
|
||||
private static IEnumerator SendLobbyCreatedRequest(string roomCode, string serverName, string language, string version, int gameId, string hostName, string map, string gameMode, string hostHashedPuid)
|
||||
{
|
||||
long timeSinceLastRequest = Utils.TimeStamp - LastRequestTimeStamp;
|
||||
if (timeSinceLastRequest < BufferTime) yield return new WaitForSeconds(BufferTime);
|
||||
if (timeSinceLastRequest < BufferTime) yield return new WaitForSecondsRealtime(BufferTime);
|
||||
LastRequestTimeStamp = Utils.TimeStamp;
|
||||
|
||||
var jsonData = $"{{\"roomCode\":\"{roomCode}\",\"serverName\":\"{serverName}\",\"language\":\"{language}\",\"version\":\"{version}\",\"gameId\":\"{gameId}\",\"hostName\":\"{hostName}\",\"map\":\"{map}\",\"gameMode\":\"{gameMode}\",\"hostHashedPuid\":\"{hostHashedPuid}\"}}";
|
||||
@@ -54,7 +55,7 @@ public static class LobbySharingAPI
|
||||
};
|
||||
|
||||
request.SetRequestHeader("Content-Type", "application/json");
|
||||
request.SetRequestHeader("User-Agent", $"{Main.ModName} v{Main.PluginVersion} - {hostName}");
|
||||
request.SetRequestHeader("User-Agent", $"{Main.ModName} v{Main.PluginVersion} - {Regex.Replace(hostName, @"[^\x20-\x7E]", "")}");
|
||||
yield return request.SendWebRequest();
|
||||
|
||||
LastRequestTimeStamp = Utils.TimeStamp;
|
||||
@@ -108,7 +109,7 @@ public static class LobbySharingAPI
|
||||
if (string.IsNullOrWhiteSpace(Token)) yield break;
|
||||
|
||||
long timeSinceLastRequest = Utils.TimeStamp - LastRequestTimeStamp;
|
||||
if (timeSinceLastRequest < BufferTime) yield return new WaitForSeconds(BufferTime);
|
||||
if (timeSinceLastRequest < BufferTime) yield return new WaitForSecondsRealtime(BufferTime);
|
||||
LastRequestTimeStamp = Utils.TimeStamp;
|
||||
|
||||
var jsonData = $"{{\"roomCode\":\"{roomCode}\",\"token\":\"{Token}\",\"newStatus\":\"{newStatus}\",\"players\":\"{players}\",\"map\":\"{map}\",\"gameMode\":\"{gameMode}\"}}";
|
||||
|
||||
+138
-16
@@ -718,7 +718,7 @@ public static class Utils
|
||||
StackFrame firstFrame = stFrames.FirstOrDefault();
|
||||
|
||||
StringBuilder sb = new();
|
||||
sb.Append($" {ex.GetType().Name}: {ex.Message}\n thrown by {ex.Source}\n at {ex.TargetSite}\n in {fileName.Split('\\')[^1]}\n at line {lineNumber}\n in method \"{callerMemberName}\"\n------ Method Stack Trace ------");
|
||||
sb.Append($" {ex.GetType().Name}: {ex.Message}\n thrown by {ex.Source}\n at {ex.TargetSite}\n in {fileName.Split('\\')[^1].Split('/')[^1]}\n at line {lineNumber}\n in method \"{callerMemberName}\"\n------ Method Stack Trace ------");
|
||||
|
||||
var skip = true;
|
||||
|
||||
@@ -1037,7 +1037,7 @@ public static class Utils
|
||||
return true;
|
||||
}
|
||||
|
||||
if ((Main.VisibleTasksCount && !PlayerControl.LocalPlayer.IsAlive() && Options.GhostCanSeeOtherRoles.GetBool() && (!IsRevivingRoleAlive() || !Main.DiedThisRound.Contains(PlayerControl.LocalPlayer.PlayerId))) || (PlayerControl.LocalPlayer.Is(CustomRoles.Mimic) && Main.VisibleTasksCount && __instance.Data.IsDead && Options.MimicCanSeeDeadRoles.GetBool())) return true;
|
||||
if ((Main.VisibleTasksCount && !PlayerControl.LocalPlayer.IsAlive() && Options.GhostCanSeeOtherRoles.GetBool() && (!IsRevivingRoleAlive() || !Main.DiedThisRound.Contains(PlayerControl.LocalPlayer.PlayerId))) || (PlayerControl.LocalPlayer.Is(CustomRoles.Mimic) && Main.VisibleTasksCount && !__instance.IsAlive() && Options.MimicCanSeeDeadRoles.GetBool())) return true;
|
||||
|
||||
if (__instance.AmOwner) return true;
|
||||
|
||||
@@ -1796,19 +1796,26 @@ public static class Utils
|
||||
catch (Exception e) { ThrowException(e); }
|
||||
}
|
||||
|
||||
public static bool TempReviveHostRunning;
|
||||
private static Stopwatch TempReviveHostRevertStopwatch = new();
|
||||
private static Stopwatch TempReviveHostTimeSinceRevivalStopwatch = new();
|
||||
|
||||
public static void SendMultipleMessages(this IEnumerable<Message> messages, SendOption sendOption = SendOption.Reliable)
|
||||
{
|
||||
var sender = CustomRpcSender.Create("Utils.SendMultipleMessages", sendOption);
|
||||
sender = messages.Aggregate(sender, (current, message) => SendMessage(message.Text, message.SendTo, message.Title, writer: current, multiple: true, sendOption: sendOption));
|
||||
sender.SendMessage(dispose: sender.stream.Length <= 3);
|
||||
messages.Do(x => SendMessage(x.Text, x.SendTo, x.Title, sendOption: sendOption));
|
||||
}
|
||||
|
||||
public static CustomRpcSender SendMessage(string text, byte sendTo = byte.MaxValue, string title = "", bool noSplit = false, CustomRpcSender writer = null, bool final = false, bool multiple = false, SendOption sendOption = SendOption.Reliable, bool addtoHistory = true)
|
||||
public static CustomRpcSender SendMessage(string text, byte sendTo = byte.MaxValue, string title = "", bool noSplit = false, CustomRpcSender writer = null, bool final = false, bool multiple = false, SendOption sendOption = SendOption.Reliable, bool addToHistory = true, bool force = false, bool noNumberSplit = false, bool numberSplitFinal = false, [CallerFilePath] string callerFilePath = "", [CallerLineNumber] int callerLineNumber = 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
Logger.Info($"SendMessage called from {callerFilePath.Split('\\')[^1].Split('/')[^1]} at line {callerLineNumber}", "SendMessage");
|
||||
|
||||
if (GameStates.CurrentServerType == GameStates.ServerType.Vanilla)
|
||||
text = text.RemoveHtmlTags();
|
||||
|
||||
PlayerControl receiver = GetPlayerById(sendTo, false);
|
||||
if (sendTo != byte.MaxValue && receiver == null || title.RemoveHtmlTags().Trim().Length == 0 && text.RemoveHtmlTags().Trim().Length == 0) return writer;
|
||||
if (sendTo != byte.MaxValue && receiver == null || !force && title.RemoveHtmlTags().Trim().Length == 0 && text.RemoveHtmlTags().Trim().Length == 0) return writer;
|
||||
|
||||
if (!AmongUsClient.Instance.AmHost)
|
||||
{
|
||||
@@ -1838,7 +1845,7 @@ public static class Utils
|
||||
text = text.Replace("color=", string.Empty);
|
||||
title = title.Replace("color=", string.Empty);
|
||||
|
||||
PlayerControl sender = !addtoHistory ? PlayerControl.LocalPlayer : Main.AllAlivePlayerControls.MinBy(x => x.PlayerId) ?? Main.AllPlayerControls.MinBy(x => x.PlayerId) ?? PlayerControl.LocalPlayer;
|
||||
PlayerControl sender = !addToHistory || GameStates.CurrentServerType == GameStates.ServerType.Vanilla ? PlayerControl.LocalPlayer : Main.AllAlivePlayerControls.MinBy(x => x.PlayerId) ?? Main.AllPlayerControls.MinBy(x => x.PlayerId) ?? PlayerControl.LocalPlayer;
|
||||
|
||||
if (sendTo != byte.MaxValue && receiver.AmOwner)
|
||||
{
|
||||
@@ -1858,10 +1865,81 @@ public static class Utils
|
||||
}
|
||||
catch { Logger.Info(" Message sent", "SendMessage"); }
|
||||
|
||||
if (addtoHistory) ChatUpdatePatch.LastMessages.Add((text, sendTo, title, TimeStamp));
|
||||
if (addToHistory) ChatUpdatePatch.LastMessages.Add((text, sendTo, title, TimeStamp));
|
||||
return writer;
|
||||
}
|
||||
|
||||
if (sender.AmOwner && sender.Data.IsDead)
|
||||
{
|
||||
bool delayMessage = false;
|
||||
|
||||
if (!TempReviveHostRunning)
|
||||
{
|
||||
delayMessage = true;
|
||||
Main.Instance.StartCoroutine(TempReviveHost());
|
||||
}
|
||||
else
|
||||
{
|
||||
if (TempReviveHostTimeSinceRevivalStopwatch.ElapsedMilliseconds < 250)
|
||||
delayMessage = true;
|
||||
|
||||
TempReviveHostRevertStopwatch.Restart();
|
||||
}
|
||||
|
||||
if (delayMessage)
|
||||
{
|
||||
Main.Instance.StartCoroutine(DelaySend());
|
||||
return writer;
|
||||
|
||||
IEnumerator DelaySend()
|
||||
{
|
||||
yield return new WaitForSecondsRealtime(0.3f);
|
||||
SendMessage(text, sendTo, title, noSplit, writer, final, multiple, sendOption, addToHistory);
|
||||
}
|
||||
}
|
||||
|
||||
IEnumerator TempReviveHost()
|
||||
{
|
||||
TempReviveHostRunning = true;
|
||||
TempReviveHostRevertStopwatch = Stopwatch.StartNew();
|
||||
TempReviveHostTimeSinceRevivalStopwatch = Stopwatch.StartNew();
|
||||
|
||||
Logger.Msg("Temporarily reviving host to send message....", "TempReviveHost");
|
||||
|
||||
sender.Data.IsDead = false;
|
||||
sender.Data.SendGameData();
|
||||
|
||||
while (TempReviveHostRevertStopwatch.ElapsedMilliseconds < 1000)
|
||||
yield return null;
|
||||
|
||||
Logger.Msg("Re-killing host after message sent.", "TempReviveHost");
|
||||
|
||||
TempReviveHostTimeSinceRevivalStopwatch.Reset();
|
||||
|
||||
if (!AmongUsClient.Instance.AmHost || GameStates.IsEnded || GameStates.IsLobby)
|
||||
{
|
||||
TempReviveHostRunning = false;
|
||||
yield break;
|
||||
}
|
||||
|
||||
sender.Data.IsDead = true;
|
||||
sender.Data.SendGameData();
|
||||
|
||||
TempReviveHostRunning = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (GameStates.CurrentServerType == GameStates.ServerType.Vanilla && !noSplit && !noNumberSplit)
|
||||
{
|
||||
var parts = SplitByNumberLimit();
|
||||
|
||||
if (parts.Count > 1)
|
||||
{
|
||||
writer = parts.Take(parts.Count - 1).Aggregate(writer, (current, part) => SendMessage(part, sendTo, title, writer: current, final: false, multiple: true, sendOption: sendOption, addToHistory: addToHistory, noNumberSplit: true));
|
||||
return SendMessage(parts[^1], sendTo, title, false, writer, final, multiple, sendOption, addToHistory, noNumberSplit: true, numberSplitFinal: true);
|
||||
}
|
||||
}
|
||||
|
||||
int targetClientId = sendTo == byte.MaxValue ? -1 : receiver.OwnerId;
|
||||
|
||||
if (writer == null || writer.CurrentState == CustomRpcSender.State.Finished)
|
||||
@@ -1967,7 +2045,7 @@ public static class Utils
|
||||
}
|
||||
catch { Logger.Info(" Message sent", "SendMessage"); }
|
||||
|
||||
if (addtoHistory) ChatUpdatePatch.LastMessages.Add(("\n", sendTo, tempTitle, TimeStamp));
|
||||
if (addToHistory) ChatUpdatePatch.LastMessages.Add(("\n", sendTo, tempTitle, TimeStamp));
|
||||
return writer;
|
||||
}
|
||||
}
|
||||
@@ -2060,7 +2138,7 @@ public static class Utils
|
||||
sender.SetName(name);
|
||||
}
|
||||
|
||||
if ((noSplit && final) || !noSplit)
|
||||
if ((noSplit && final) || (!noSplit && (!noNumberSplit || numberSplitFinal)))
|
||||
{
|
||||
writer.AutoStartRpc(sender.NetId, RpcCalls.SetName, targetClientId)
|
||||
.Write(sender.Data.NetId)
|
||||
@@ -2075,7 +2153,7 @@ public static class Utils
|
||||
}
|
||||
catch (Exception e) { ThrowException(e); }
|
||||
|
||||
if (addtoHistory) ChatUpdatePatch.LastMessages.Add((text, sendTo, title, TimeStamp));
|
||||
if (addToHistory) ChatUpdatePatch.LastMessages.Add((text, sendTo, title, TimeStamp));
|
||||
return writer;
|
||||
|
||||
void RestartMessageIfTooLong()
|
||||
@@ -2086,6 +2164,47 @@ public static class Utils
|
||||
writer = CustomRpcSender.Create("Utils.SendMessage", sendOption);
|
||||
}
|
||||
}
|
||||
|
||||
List<string> SplitByNumberLimit()
|
||||
{
|
||||
List<string> result = [];
|
||||
StringBuilder sb = new();
|
||||
|
||||
int digitCount = 0;
|
||||
|
||||
foreach (char c in text)
|
||||
{
|
||||
if (char.IsDigit(c))
|
||||
{
|
||||
digitCount++;
|
||||
|
||||
if (digitCount > 5)
|
||||
{
|
||||
int lastNewline = sb.ToString().LastIndexOf('\n');
|
||||
|
||||
if (lastNewline >= 0)
|
||||
{
|
||||
result.Add(sb.ToString(0, lastNewline + 1));
|
||||
sb.Remove(0, lastNewline + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
result.Add(sb.ToString());
|
||||
sb.Clear();
|
||||
}
|
||||
|
||||
digitCount = 1;
|
||||
}
|
||||
}
|
||||
|
||||
sb.Append(c);
|
||||
}
|
||||
|
||||
if (sb.Length > 0)
|
||||
result.Add(sb.ToString());
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
public static HashSet<byte> DirtyName = [];
|
||||
@@ -3197,7 +3316,7 @@ public static class Utils
|
||||
public static void SendGameData()
|
||||
{
|
||||
int messages = 0;
|
||||
int packingLimit = AmongUsClient.Instance.GetMaxMessagePackingLimit();
|
||||
int packingLimit = 10;
|
||||
|
||||
MessageWriter writer = MessageWriter.Get(SendOption.Reliable);
|
||||
writer.StartMessage(5);
|
||||
@@ -3231,7 +3350,7 @@ public static class Utils
|
||||
public static void SendGameDataTo(int targetClientId)
|
||||
{
|
||||
int messages = 0;
|
||||
int packingLimit = AmongUsClient.Instance.GetMaxMessagePackingLimit();
|
||||
int packingLimit = 10;
|
||||
|
||||
MessageWriter writer = MessageWriter.Get(SendOption.Reliable);
|
||||
writer.StartMessage(6);
|
||||
@@ -3618,6 +3737,9 @@ public static class Utils
|
||||
AmongUsClient.Instance.SendOrDisconnect(writer);
|
||||
writer.Recycle();
|
||||
}, 3f, "Repeat Lobby Despawn");
|
||||
|
||||
if (GameStates.CurrentServerType == GameStates.ServerType.Vanilla && !PlayerControl.LocalPlayer.IsAlive())
|
||||
PlayerControl.LocalPlayer.RpcMakeInvisible();
|
||||
}
|
||||
|
||||
public static void AfterPlayerDeathTasks(PlayerControl target, bool onMeeting = false, bool disconnect = false)
|
||||
@@ -4261,7 +4383,7 @@ public static class Utils
|
||||
|
||||
string ip = region.Servers.FirstOrDefault()?.Ip ?? string.Empty;
|
||||
|
||||
if (ip.Contains("aumods.us", StringComparison.Ordinal) || ip.Contains("duikbo.at", StringComparison.Ordinal))
|
||||
if (ip.Contains("aumods.org", StringComparison.Ordinal) || ip.Contains("duikbo.at", StringComparison.Ordinal))
|
||||
{
|
||||
// Official Modded Server
|
||||
if (ip.Contains("au-eu"))
|
||||
@@ -4275,7 +4397,7 @@ public static class Utils
|
||||
}
|
||||
|
||||
if (name.Contains("Niko", StringComparison.OrdinalIgnoreCase))
|
||||
name = name.Replace("233(", "-").TrimEnd(')');
|
||||
name = name.Replace("233(", "-").Replace("233 (", "-").TrimEnd(')');
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
@@ -125,6 +125,8 @@ internal static class ChatCommands
|
||||
|
||||
public static bool HasMessageDuringEjectionScreen;
|
||||
|
||||
private static bool WaitingToSend;
|
||||
|
||||
public static void LoadCommands()
|
||||
{
|
||||
Command.AllCommands = new Dictionary<string, Command>
|
||||
@@ -451,7 +453,7 @@ internal static class ChatCommands
|
||||
if (!Main.AllPlayerNames.TryGetValue(PlayerControl.LocalPlayer.PlayerId, out string name))
|
||||
Utils.ApplySuffix(PlayerControl.LocalPlayer, out name);
|
||||
|
||||
Utils.SendMessage(text.Insert(0, new('\n', name.Count(x => x == '\n'))), title: name, addtoHistory: false);
|
||||
Utils.SendMessage(text.Insert(0, new('\n', name.Count(x => x == '\n'))), title: name, addToHistory: false);
|
||||
|
||||
canceled = true;
|
||||
__instance.freeChatField.textArea.Clear();
|
||||
@@ -466,6 +468,22 @@ internal static class ChatCommands
|
||||
if (text.Contains("666") && PlayerControl.LocalPlayer.Is(CustomRoles.Demon))
|
||||
Achievements.Type.WhatTheHell.Complete();
|
||||
|
||||
if (!canceled && AmongUsClient.Instance.AmHost && Utils.TempReviveHostRunning)
|
||||
{
|
||||
if (!WaitingToSend) Main.Instance.StartCoroutine(Wait());
|
||||
return false;
|
||||
|
||||
IEnumerator Wait()
|
||||
{
|
||||
WaitingToSend = true;
|
||||
while (Utils.TempReviveHostRunning && AmongUsClient.Instance.AmHost) yield return null;
|
||||
yield return new WaitForSecondsRealtime(0.5f);
|
||||
if (GameStates.IsEnded || GameStates.IsLobby) yield break;
|
||||
WaitingToSend = false;
|
||||
if (HudManager.InstanceExists) HudManager.Instance.Chat.SendChat();
|
||||
}
|
||||
}
|
||||
|
||||
return !canceled;
|
||||
}
|
||||
|
||||
@@ -1447,7 +1465,7 @@ internal static class ChatCommands
|
||||
|
||||
messages.SendMultipleMessages(index == 0 ? SendOption.Reliable : SendOption.None);
|
||||
|
||||
yield return new WaitForSeconds(20f);
|
||||
yield return new WaitForSecondsRealtime(20f);
|
||||
if (DraftResult.Count >= DraftRoles.Count || !GameStates.IsLobby || GameStates.InGame) yield break;
|
||||
}
|
||||
}
|
||||
@@ -1691,7 +1709,7 @@ internal static class ChatCommands
|
||||
while (!GameStates.IsMeeting && GameStates.InGame) yield return null;
|
||||
if (!GameStates.InGame) yield break;
|
||||
|
||||
if (!meeting) yield return new WaitForSeconds(7f);
|
||||
if (!meeting) yield return new WaitForSecondsRealtime(7f);
|
||||
|
||||
PlayerControl killer = player.GetRealKiller();
|
||||
if (killer == null && id != 3) yield break;
|
||||
@@ -3706,7 +3724,7 @@ internal static class ChatUpdatePatch
|
||||
|
||||
internal static bool SendLastMessages(ref CustomRpcSender sender)
|
||||
{
|
||||
PlayerControl player = GameStates.IsLobby ? Main.AllPlayerControls.Without(PlayerControl.LocalPlayer).RandomElement() : Main.AllAlivePlayerControls.MinBy(x => x.PlayerId) ?? Main.AllPlayerControls.MinBy(x => x.PlayerId) ?? PlayerControl.LocalPlayer;
|
||||
PlayerControl player = GameStates.CurrentServerType == GameStates.ServerType.Vanilla ? PlayerControl.LocalPlayer : GameStates.IsLobby ? Main.AllPlayerControls.Without(PlayerControl.LocalPlayer).RandomElement() : Main.AllAlivePlayerControls.MinBy(x => x.PlayerId) ?? Main.AllPlayerControls.MinBy(x => x.PlayerId) ?? PlayerControl.LocalPlayer;
|
||||
if (player == null) return false;
|
||||
|
||||
bool wasCleared = false;
|
||||
|
||||
@@ -222,6 +222,26 @@ public static class ChatManager
|
||||
PlayerControl[] aapc = Main.AllAlivePlayerControls;
|
||||
if (aapc.Length == 0) return;
|
||||
|
||||
if (GameStates.CurrentServerType == GameStates.ServerType.Vanilla)
|
||||
{
|
||||
ClearChat();
|
||||
|
||||
StringBuilder sb = new();
|
||||
ChatHistory.ForEach(x =>
|
||||
{
|
||||
string[] split = x.Split(':');
|
||||
byte id = byte.Parse(split[0].Trim());
|
||||
string msg = string.Join(':', split[1..]).Trim();
|
||||
sb.Append(id.ColoredPlayerName());
|
||||
sb.Append(':');
|
||||
sb.Append(' ');
|
||||
sb.AppendLine(msg);
|
||||
});
|
||||
LateTask.New(() => Utils.SendMessage("\n", title: sb.ToString().Trim()), 0.2f);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
string[] filtered = ChatHistory.Where(a => Utils.GetPlayerById(Convert.ToByte(a.Split(':')[0].Trim())).IsAlive()).ToArray();
|
||||
ChatController chat = HudManager.Instance.Chat;
|
||||
var writer = CustomRpcSender.Create("SendPreviousMessagesToAll", SendOption.Reliable);
|
||||
@@ -257,8 +277,8 @@ public static class ChatManager
|
||||
|
||||
private static void SendRPC(CustomRpcSender writer, PlayerControl senderPlayer, string senderMessage, int targetClientId = -1)
|
||||
{
|
||||
if (GameStates.IsLobby && senderPlayer.IsHost())
|
||||
senderMessage = senderMessage.Insert(0, new('\n', senderPlayer.GetRealName().Count(x => x == '\n')));
|
||||
if (GameStates.IsLobby && senderPlayer.AmOwner)
|
||||
senderMessage = senderMessage.Insert(0, new('\n', PlayerControl.LocalPlayer.name.Count(x => x == '\n')));
|
||||
|
||||
writer.AutoStartRpc(senderPlayer.NetId, RpcCalls.SendChat, targetClientId)
|
||||
.Write(senderMessage)
|
||||
@@ -269,9 +289,19 @@ public static class ChatManager
|
||||
public static void ClearChat(params PlayerControl[] targets)
|
||||
{
|
||||
if (!AmongUsClient.Instance.AmHost) return;
|
||||
PlayerControl player = Main.AllAlivePlayerControls.MinBy(x => x.PlayerId) ?? Main.AllPlayerControls.MinBy(x => x.PlayerId) ?? PlayerControl.LocalPlayer;
|
||||
PlayerControl player = GameStates.CurrentServerType == GameStates.ServerType.Vanilla ? PlayerControl.LocalPlayer : Main.AllAlivePlayerControls.MinBy(x => x.PlayerId) ?? Main.AllPlayerControls.MinBy(x => x.PlayerId) ?? PlayerControl.LocalPlayer;
|
||||
if (player == null) return;
|
||||
|
||||
if (GameStates.CurrentServerType == GameStates.ServerType.Vanilla)
|
||||
{
|
||||
if (targets.Length <= 1 || targets.Length >= Main.AllAlivePlayerControls.Length)
|
||||
Loop.Times(30, _ => Utils.SendMessage(string.Empty, targets.Length == 1 ? targets[0].PlayerId : byte.MaxValue, "", force: true, sendOption: SendOption.None));
|
||||
else
|
||||
targets.Do(x => Loop.Times(30, _ => Utils.SendMessage(string.Empty, x.PlayerId, "", force: true, sendOption: SendOption.None)));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (targets.Length == 0 || targets.Length == PlayerControl.AllPlayerControls.Count) SendEmptyMessage(null);
|
||||
else targets.Do(SendEmptyMessage);
|
||||
return;
|
||||
|
||||
@@ -359,13 +359,6 @@ internal static class GameEndChecker
|
||||
try { LobbySharingAPI.NotifyLobbyStatusChanged(LobbyStatus.Ended); }
|
||||
catch (Exception e) { ThrowException(e); }
|
||||
|
||||
string msg = GetString("NotifyGameEnding");
|
||||
|
||||
Main.AllPlayerControls
|
||||
.Where(x => x.GetClient() != null && !x.Data.Disconnected)
|
||||
.Select(x => new Message("\n", x.PlayerId, msg))
|
||||
.SendMultipleMessages();
|
||||
|
||||
SetEverythingUpPatch.LastWinsReason = WinnerTeam is CustomWinner.Crewmate or CustomWinner.Impostor ? GetString($"GameOverReason.{reason}") : string.Empty;
|
||||
var self = AmongUsClient.Instance;
|
||||
self.StartCoroutine(CoEndGame(self, reason).WrapToIl2Cpp());
|
||||
@@ -415,7 +408,7 @@ internal static class GameEndChecker
|
||||
self.FinishRpcImmediately(winnerWriter);
|
||||
|
||||
// Delay to ensure that resuscitation is delivered after the ghost roll setting
|
||||
yield return new WaitForSeconds(EndGameDelay);
|
||||
yield return new WaitForSecondsRealtime(EndGameDelay);
|
||||
|
||||
if (playersToRevive.Count > 0)
|
||||
{
|
||||
@@ -431,7 +424,7 @@ internal static class GameEndChecker
|
||||
}
|
||||
|
||||
// Delay to ensure that the end of the game is delivered at the end of the game
|
||||
yield return new WaitForSeconds(EndGameDelay);
|
||||
yield return new WaitForSecondsRealtime(EndGameDelay);
|
||||
}
|
||||
|
||||
// Start End Game
|
||||
@@ -623,7 +616,7 @@ internal static class GameEndChecker
|
||||
|
||||
foreach (PlayerState playerState in statesCoutingAsCrew)
|
||||
{
|
||||
if (!Options.CrewAdvancedGameEndCheckingSettings.TryGetValue(playerState.MainRole, out var option) || !option.GetBool()) continue;
|
||||
if (!Options.CrewAdvancedGameEndCheckingSettings.TryGetValue(playerState.MainRole, out var option) || !option.GetBool() || playerState.SubRoles.Exists(x => x == CustomRoles.Madmate || x.IsConverted())) continue;
|
||||
playerState.Role.ManipulateGameEndCheckCrew(playerState, out bool keepGameGoing, out int countsAs);
|
||||
crewKeepsGameGoing |= keepGameGoing;
|
||||
crew += countsAs - 1;
|
||||
|
||||
@@ -175,7 +175,7 @@ internal static class ControllerManagerUpdatePatch
|
||||
|
||||
IEnumerator Reset()
|
||||
{
|
||||
yield return new WaitForSeconds(0.1f);
|
||||
yield return new WaitForSecondsRealtime(0.1f);
|
||||
|
||||
string format = GetString("ResettingOptions");
|
||||
HudManager hudManager = HudManager.Instance;
|
||||
|
||||
@@ -788,7 +788,7 @@ public static class StringOptionPatch
|
||||
IEnumerator CoRoutine()
|
||||
{
|
||||
while (HelpShowEndTS > Utils.TimeStamp)
|
||||
yield return new WaitForSeconds(1f);
|
||||
yield return new WaitForSecondsRealtime(1f);
|
||||
|
||||
GameObject gameObject = GameObject.Find("PlayerOptionsMenu(Clone)");
|
||||
|
||||
@@ -1182,8 +1182,17 @@ public static class GameSettingMenuPatch
|
||||
|
||||
if (SubmergedCompatibility.Loaded && Main.NormalOptions.MapId == 6)
|
||||
gms.RemoveAll(SubmergedCompatibility.IsNotSupported);
|
||||
|
||||
if (Main.LIMap)
|
||||
{
|
||||
gms.Remove(CustomGameMode.CaptureTheFlag);
|
||||
gms.Remove(CustomGameMode.Quiz);
|
||||
gms.Remove(CustomGameMode.TheMindGame);
|
||||
gms.Remove(CustomGameMode.BedWars);
|
||||
gms.Remove(CustomGameMode.Deathrace);
|
||||
}
|
||||
|
||||
int totalCols = Mathf.Max(1, Mathf.CeilToInt(gms.Count / 7f));
|
||||
int totalCols = 3;
|
||||
|
||||
GMButtons = [];
|
||||
|
||||
|
||||
+1
-1
@@ -716,7 +716,7 @@ internal static class HudManagerStartPatch
|
||||
while (!HudManager.Instance)
|
||||
yield return null;
|
||||
|
||||
yield return new WaitForSeconds(0.01f);
|
||||
yield return new WaitForSecondsRealtime(0.01f);
|
||||
ResizeUI(Main.UIScaleFactor.Value);
|
||||
}
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ public class FallFromLadder
|
||||
|
||||
if (TargetLadderData.TryGetValue(player.PlayerId, out Vector3 targetLadderData) && Vector2.Distance(targetLadderData, player.Pos()) < 0.5f)
|
||||
{
|
||||
if (player.Data.IsDead) return;
|
||||
if (player.Data.IsDead || !player.IsAlive()) return;
|
||||
|
||||
// To insert LateTask, first enter the death judgment.
|
||||
player.Data.IsDead = true;
|
||||
|
||||
@@ -22,7 +22,7 @@ public static class CredentialsPatch
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
yield return new WaitForSeconds(1f);
|
||||
yield return new WaitForSecondsRealtime(1f);
|
||||
|
||||
if (__instance != null)
|
||||
{
|
||||
|
||||
@@ -181,7 +181,16 @@ public static class MainMenuManagerPatch
|
||||
buttonText.text = Translator.GetString($"MainMenu.{buttonName.Replace(" ", "")}");
|
||||
}
|
||||
|
||||
__instance.PlayOnlineButton.OnClick.AddListener((UnityAction)(() => GameOptionsManager.Instance.Initialize()));
|
||||
__instance.PlayOnlineButton.OnClick.AddListener((UnityAction)(() =>
|
||||
{
|
||||
GameOptionsManager.Instance.Initialize();
|
||||
|
||||
if (GameOptionsManager.Instance.normalGameHostOptions.MapId is 3 or > 5)
|
||||
{
|
||||
GameOptionsManager.Instance.normalGameHostOptions.MapId = 0;
|
||||
GameOptionsManager.Instance.SaveNormalHostOptions();
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
private static PassiveButton CreateButton(string name, Vector3 localPosition, Color32 normalColor, Color32 hoverColor, Action action, string label, Vector2? scale = null)
|
||||
|
||||
+20
-14
@@ -44,7 +44,7 @@ internal static class CheckForEndVotingPatch
|
||||
// Dictators who are not dead have already voted.
|
||||
|
||||
// Take the initiative to rebel
|
||||
if (pva.DidVote && pc.PlayerId == pva.VotedFor && pva.VotedFor < 253 && !pc.Data.IsDead)
|
||||
if (pva.DidVote && pc.PlayerId == pva.VotedFor && pva.VotedFor < 253 && pc.IsAlive())
|
||||
{
|
||||
if (Options.MadmateSpawnMode.GetInt() == 2 && Main.MadmateNum < CustomRoles.Madmate.GetCount() && pc.CanBeMadmate())
|
||||
{
|
||||
@@ -121,7 +121,7 @@ internal static class CheckForEndVotingPatch
|
||||
|
||||
if (Options.VoteMode.GetBool())
|
||||
{
|
||||
if (ps.VotedFor == 253 && !voter.Data.IsDead &&
|
||||
if (ps.VotedFor == 253 && voter.IsAlive() &&
|
||||
!(Options.WhenSkipVoteIgnoreFirstMeeting.GetBool() && MeetingStates.FirstMeeting) &&
|
||||
!(Options.WhenSkipVoteIgnoreNoDeadBody.GetBool() && !MeetingStates.IsExistDeadBody) &&
|
||||
!(Options.WhenSkipVoteIgnoreEmergency.GetBool() && MeetingStates.IsEmergencyMeeting)
|
||||
@@ -140,7 +140,7 @@ internal static class CheckForEndVotingPatch
|
||||
}
|
||||
}
|
||||
|
||||
if (ps.VotedFor == 254 && !voter.Data.IsDead)
|
||||
if (ps.VotedFor == 254 && voter.IsAlive())
|
||||
{
|
||||
switch (Options.GetWhenNonVote())
|
||||
{
|
||||
@@ -160,7 +160,7 @@ internal static class CheckForEndVotingPatch
|
||||
}
|
||||
}
|
||||
|
||||
if (ps.VotedFor == 254 && !voter.Data.IsDead && voter.Is(CustomRoles.Compelled))
|
||||
if (ps.VotedFor == 254 && voter.IsAlive() && voter.Is(CustomRoles.Compelled))
|
||||
TryAddAfterMeetingDeathPlayers(PlayerState.DeathReason.DidntVote, ps.TargetPlayerId);
|
||||
|
||||
if (CheckRole(ps.TargetPlayerId, CustomRoles.FortuneTeller) && FortuneTeller.HideVote.GetBool()) continue;
|
||||
@@ -886,9 +886,9 @@ internal static class MeetingHudStartPatch
|
||||
|
||||
roleTextMeeting.enabled =
|
||||
target.AmOwner ||
|
||||
(Main.VisibleTasksCount && seer.Data.IsDead && Options.GhostCanSeeOtherRoles.GetBool()) ||
|
||||
(seer.Is(CustomRoles.Mimic) && Main.VisibleTasksCount && target.Data.IsDead && Options.MimicCanSeeDeadRoles.GetBool()) ||
|
||||
(target.Is(CustomRoles.Gravestone) && Main.VisibleTasksCount && target.Data.IsDead) ||
|
||||
(Main.VisibleTasksCount && !seer.IsAlive() && Options.GhostCanSeeOtherRoles.GetBool()) ||
|
||||
(seer.Is(CustomRoles.Mimic) && Main.VisibleTasksCount && !target.IsAlive() && Options.MimicCanSeeDeadRoles.GetBool()) ||
|
||||
(target.Is(CustomRoles.Gravestone) && Main.VisibleTasksCount && !target.IsAlive()) ||
|
||||
(Main.LoversPlayers.TrueForAll(x => x.PlayerId == target.PlayerId || x.PlayerId == seer.PlayerId) && Main.LoversPlayers.Count == 2 && Lovers.LoverKnowRoles.GetBool()) ||
|
||||
(seer.Is(CustomRoleTypes.Coven) && target.Is(CustomRoleTypes.Coven)) ||
|
||||
(target.Is(CustomRoleTypes.Impostor) && seer.Is(CustomRoleTypes.Impostor) && Options.ImpKnowAlliesRole.GetBool() && CustomTeamManager.ArentInCustomTeam(seer.PlayerId, target.PlayerId)) ||
|
||||
@@ -914,7 +914,7 @@ internal static class MeetingHudStartPatch
|
||||
Main.GodMode.Value;
|
||||
|
||||
|
||||
if (!seer.Data.IsDead && seer.IsRevealedPlayer(target) && target.Is(CustomRoles.Trickster))
|
||||
if (seer.IsAlive() && seer.IsRevealedPlayer(target) && target.Is(CustomRoles.Trickster))
|
||||
{
|
||||
roleTextMeeting.text = Investigator.RandomRole[seer.PlayerId];
|
||||
roleTextMeeting.text += Investigator.GetTaskState();
|
||||
@@ -984,7 +984,7 @@ internal static class MeetingHudStartPatch
|
||||
{
|
||||
TemplateManager.SendTemplate("OnMeeting", noErr: true, sendOption: SendOption.None);
|
||||
if (MeetingStates.FirstMeeting) TemplateManager.SendTemplate("OnFirstMeeting", noErr: true, sendOption: SendOption.None);
|
||||
}, 2f, log: false);
|
||||
}, 6f, log: false);
|
||||
|
||||
NotifyRoleSkillOnMeetingStart();
|
||||
|
||||
@@ -1086,7 +1086,7 @@ internal static class MeetingHudStartPatch
|
||||
case CustomRoles.Revolutionist when seer.IsDrawPlayer(target):
|
||||
sb.Append(Utils.ColorString(Utils.GetRoleColor(CustomRoles.Revolutionist), "●"));
|
||||
break;
|
||||
case CustomRoles.Psychic when Psychic.IsRedForPsy(target, seer) && !seer.Data.IsDead:
|
||||
case CustomRoles.Psychic when Psychic.IsRedForPsy(target, seer) && seer.IsAlive():
|
||||
pva.NameText.text = Utils.ColorString(Utils.GetRoleColor(CustomRoles.Impostor), pva.NameText.text);
|
||||
break;
|
||||
case CustomRoles.Demon:
|
||||
@@ -1101,7 +1101,7 @@ internal static class MeetingHudStartPatch
|
||||
if (Silencer.ForSilencer.Contains(target.PlayerId))
|
||||
sb.Append(Utils.ColorString(Utils.GetRoleColor(CustomRoles.Silencer), "╳"));
|
||||
|
||||
if (Main.LoversPlayers.Exists(x => x.PlayerId == target.PlayerId) && (Main.LoversPlayers.Exists(x => x.PlayerId == seer.PlayerId) || seer.Data.IsDead))
|
||||
if (Main.LoversPlayers.Exists(x => x.PlayerId == target.PlayerId) && (Main.LoversPlayers.Exists(x => x.PlayerId == seer.PlayerId) || !seer.IsAlive()))
|
||||
sb.Append(Utils.ColorString(Utils.GetRoleColor(CustomRoles.Lovers), "♥"));
|
||||
|
||||
sb.Append(Executioner.TargetMark(seer, target));
|
||||
@@ -1122,7 +1122,7 @@ internal static class MeetingHudStartPatch
|
||||
if (seer.Is(CustomRoles.Medic) && (Medic.InProtect(target.PlayerId) || Medic.TempMarkProtectedList.Contains(target.PlayerId)) && Medic.WhoCanSeeProtect.GetInt() is 0 or 1)
|
||||
sb.Append(Utils.ColorString(Utils.GetRoleColor(CustomRoles.Medic), " ●"));
|
||||
|
||||
if (seer.Data.IsDead && Medic.InProtect(target.PlayerId) && !seer.Is(CustomRoles.Medic))
|
||||
if (!seer.IsAlive() && Medic.InProtect(target.PlayerId) && !seer.Is(CustomRoles.Medic))
|
||||
sb.Append(Utils.ColorString(Utils.GetRoleColor(CustomRoles.Medic), " ●"));
|
||||
|
||||
sb.Append(Follower.TargetMark(seer, target));
|
||||
@@ -1206,7 +1206,7 @@ internal static class MeetingHudUpdatePatch
|
||||
{
|
||||
PlayerControl player = Utils.GetPlayerById(x.TargetPlayerId);
|
||||
|
||||
if (player != null && !player.Data.IsDead)
|
||||
if (player != null && player.IsAlive())
|
||||
{
|
||||
Main.PlayerStates[player.PlayerId].deathReason = PlayerState.DeathReason.Execution;
|
||||
player.RpcExileV2();
|
||||
@@ -1321,7 +1321,7 @@ internal static class MeetingHudOnDestroyPatch
|
||||
while (!ExileController.Instance && !GameStates.IsEnded) yield return null;
|
||||
if (GameStates.IsEnded) yield break;
|
||||
|
||||
yield return new WaitForSeconds(1f);
|
||||
yield return new WaitForSecondsRealtime(1f);
|
||||
if (!ExileController.Instance || GameStates.IsEnded) yield break;
|
||||
|
||||
if (CheckForEndVotingPatch.EjectionText.EndsWith("<size=0>") && Options.CurrentGameMode is CustomGameMode.Standard or CustomGameMode.TheMindGame && CheckForEndVotingPatch.TempExiledPlayer != null)
|
||||
@@ -1381,6 +1381,12 @@ internal static class MeetingHudCastVotePatch
|
||||
skip = true;
|
||||
}
|
||||
|
||||
if (!pcSrc.IsAlive())
|
||||
{
|
||||
ShouldCancelVoteList.TryAdd(srcPlayerId, (__instance, pvaSrc, pcSrc));
|
||||
return false;
|
||||
}
|
||||
|
||||
var voteCanceled = false;
|
||||
|
||||
if (!Main.DontCancelVoteList.Contains(srcPlayerId) && !skip && pcSrc.GetCustomRole().CancelsVote() && !pcSrc.UsesMeetingShapeshift() && Main.PlayerStates[srcPlayerId].Role.OnVote(pcSrc, pcTarget))
|
||||
|
||||
@@ -1174,7 +1174,7 @@ internal static class StartGameHostPatch
|
||||
RpcSetRoleReplacer.EndReplace();
|
||||
|
||||
|
||||
yield return new WaitForSeconds(1.2f);
|
||||
yield return new WaitForSecondsRealtime(1.2f);
|
||||
|
||||
foreach (PlayerControl pc in PlayerControl.AllPlayerControls)
|
||||
{
|
||||
|
||||
@@ -641,7 +641,7 @@ internal static class SetEverythingUpPatch
|
||||
|
||||
static IEnumerator SlideAndFadeIn(RectTransform rect, TextMeshPro text, float delay)
|
||||
{
|
||||
yield return new WaitForSeconds(delay);
|
||||
yield return new WaitForSecondsRealtime(delay);
|
||||
|
||||
Vector2 start = rect.anchoredPosition;
|
||||
Vector2 end = start + new Vector2(5f, 0); // target pos
|
||||
|
||||
@@ -224,7 +224,7 @@ internal static class ExternalRpcPetPatch
|
||||
{
|
||||
HudManagerPatch.CooldownTimerFlashColor = yellow ? Color.red : Color.yellow;
|
||||
yellow = !yellow;
|
||||
yield return new WaitForSeconds(0.2f);
|
||||
yield return new WaitForSecondsRealtime(0.2f);
|
||||
}
|
||||
|
||||
HudManagerPatch.CooldownTimerFlashColor = null;
|
||||
|
||||
@@ -105,7 +105,7 @@ public static class PhantomRoleUseAbilityPatch
|
||||
{
|
||||
if (!AmongUsClient.Instance.AmHost || !HudManager.InstanceExists) return true;
|
||||
|
||||
if (__instance.Player.AmOwner && !__instance.Player.Data.IsDead && __instance.Player.moveable && !Minigame.Instance && !__instance.IsCoolingDown && !__instance.fading)
|
||||
if (__instance.Player.AmOwner && !__instance.Player.Data.IsDead && __instance.Player.IsAlive() && __instance.Player.moveable && !Minigame.Instance && !__instance.IsCoolingDown && !__instance.fading)
|
||||
{
|
||||
bool RoleEffectAnimation(RoleEffectAnimation x) => x.effectType == global::RoleEffectAnimation.EffectType.Vanish_Charge;
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ internal static class CheckProtectPatch
|
||||
{
|
||||
public static bool Prefix(PlayerControl __instance, [HarmonyArgument(0)] PlayerControl target)
|
||||
{
|
||||
if (!AmongUsClient.Instance.AmHost || target.Data.IsDead) return false;
|
||||
if (!AmongUsClient.Instance.AmHost || target.Data.IsDead || !target.IsAlive()) return false;
|
||||
|
||||
Logger.Info($"CheckProtect: {__instance.GetNameWithRole().RemoveHtmlTags()} => {target.GetNameWithRole().RemoveHtmlTags()}", "CheckProtect");
|
||||
|
||||
@@ -990,7 +990,7 @@ internal static class ReportDeadBodyPatch
|
||||
try
|
||||
{
|
||||
// If the caller is dead, this process will cancel the meeting, so stop here.
|
||||
if (__instance.Data.IsDead) return false;
|
||||
if (__instance.Data.IsDead || !__instance.IsAlive()) return false;
|
||||
|
||||
//=============================================
|
||||
// Next, check whether this meeting is allowed
|
||||
@@ -1201,7 +1201,7 @@ internal static class ReportDeadBodyPatch
|
||||
try { Main.AllAlivePlayerControls.DoIf(x => x.Is(CustomRoles.Lazy), x => Lazy.BeforeMeetingPositions[x.PlayerId] = x.Pos()); }
|
||||
catch (Exception e) { ThrowException(e); }
|
||||
|
||||
try { if (Lovers.PrivateChat.GetBool()) ChatManager.ClearChat(Main.AllAlivePlayerControls.ExceptBy(Main.LoversPlayers.ConvertAll(x => x.PlayerId), x => x.PlayerId).ToArray()); }
|
||||
try { if (Lovers.PrivateChat.GetBool() && Main.LoversPlayers.Exists(x => x != null && x.IsAlive())) LateTask.New(() => ChatManager.ClearChat(Main.AllAlivePlayerControls.ExceptBy(Main.LoversPlayers.ConvertAll(x => x.PlayerId), x => x.PlayerId).ToArray()), GameStates.CurrentServerType == GameStates.ServerType.Vanilla && !PlayerControl.LocalPlayer.IsAlive() ? 3f : 0f); }
|
||||
catch (Exception e) { ThrowException(e); }
|
||||
|
||||
CustomSabotage.Reset();
|
||||
@@ -1378,7 +1378,7 @@ internal static class ReportDeadBodyPatch
|
||||
if (Main.CheckShapeshift.ContainsKey(pc.PlayerId))
|
||||
pc.RpcShapeshift(pc, false);
|
||||
}
|
||||
else if (!pc.Data.IsDead)
|
||||
else if (!pc.Data.IsDead && (!pc.AmOwner || !TempReviveHostRunning))
|
||||
pc.RpcExileV2();
|
||||
}
|
||||
catch (Exception e) { ThrowException(e); }
|
||||
@@ -1818,7 +1818,7 @@ internal static class FixedUpdatePatch
|
||||
|
||||
additionalSuffixes.Add(AFKDetector.GetSuffix(seer, target));
|
||||
|
||||
if (!GameStates.IsMeeting && Options.CurrentGameMode == CustomGameMode.Standard && Main.Invisible.Contains(target.PlayerId) && ((self && target.GetCustomRole() is not (CustomRoles.Swooper or CustomRoles.Wraith or CustomRoles.Chameleon)) || (seer.IsImpostor() && target.IsImpostor())))
|
||||
if (!GameStates.IsMeeting && Options.CurrentGameMode == CustomGameMode.Standard && Main.Invisible.Contains(target.PlayerId) && ((self && seer.IsAlive() && target.GetCustomRole() is not (CustomRoles.Swooper or CustomRoles.Wraith or CustomRoles.Chameleon)) || (seer.IsImpostor() && target.IsImpostor())))
|
||||
additionalSuffixes.Add(ColorString(Palette.White_75Alpha, "\n" + GetString("Invisible")));
|
||||
|
||||
switch (target.GetCustomRole())
|
||||
@@ -2301,7 +2301,44 @@ public static class PlayerControlDiePatch
|
||||
|
||||
public static void Postfix(PlayerControl __instance)
|
||||
{
|
||||
if (AmongUsClient.Instance.AmHost) PetsHelper.RpcRemovePet(__instance);
|
||||
if (!AmongUsClient.Instance.AmHost) return;
|
||||
|
||||
PetsHelper.RpcRemovePet(__instance);
|
||||
|
||||
if (!Main.LIMap) return;
|
||||
|
||||
LateTask.New(() =>
|
||||
{
|
||||
if (Main.PlayerStates.TryGetValue(__instance.PlayerId, out var state) && !state.IsDead)
|
||||
{
|
||||
state.IsDead = true;
|
||||
var sender = CustomRpcSender.Create($"LIDeathSync:{__instance.GetRealName()}", SendOption.Reliable);
|
||||
var hasValue = sender.SyncGeneralOptions(__instance);
|
||||
sender.SendMessage(dispose: !hasValue);
|
||||
}
|
||||
}, 0.2f);
|
||||
}
|
||||
}
|
||||
|
||||
[HarmonyPatch(typeof(PlayerControl), nameof(PlayerControl.Revive))]
|
||||
static class PlayerControlRevivePatch
|
||||
{
|
||||
public static void Postfix(PlayerControl __instance)
|
||||
{
|
||||
if (!AmongUsClient.Instance.AmHost || !Main.LIMap) return;
|
||||
|
||||
LateTask.New(() =>
|
||||
{
|
||||
if (Main.PlayerStates.TryGetValue(__instance.PlayerId, out var state) && state.IsDead)
|
||||
{
|
||||
state.IsDead = false;
|
||||
var sender = CustomRpcSender.Create($"LIReviveSync:{__instance.GetRealName()}", SendOption.Reliable);
|
||||
var hasValue = sender.SyncGeneralOptions(__instance);
|
||||
sender.SendMessage(dispose: !hasValue);
|
||||
Vector2 pos = __instance.Pos();
|
||||
__instance.TP(Main.AllAlivePlayerControls.Without(__instance).Select(x => x.Pos()).Concat(ShipStatus.Instance.AllVents.Select(x => new Vector2(x.transform.position.x, x.transform.position.y + 0.3636f))).MinBy(x => Vector2.Distance(pos, x)));
|
||||
}
|
||||
}, 0.2f);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -60,7 +60,7 @@ internal static class OnGameJoinedPatch
|
||||
Prompt.Show(string.Format(GetString("Promt.DeleteOldLogs"), result.Files, result.Folders), () =>
|
||||
{
|
||||
result = CleanOldItems(false);
|
||||
HudManager.Instance.ShowPopUp(string.Format(GetString("LogDeletionResults"), result.Files, result.Folders));
|
||||
LateTask.New(() => HudManager.Instance.ShowPopUp(string.Format(GetString("LogDeletionResults"), result.Files, result.Folders)), 0.01f);
|
||||
}, () => { });
|
||||
}
|
||||
|
||||
@@ -210,7 +210,7 @@ internal static class OnGameJoinedPatch
|
||||
|
||||
IEnumerator CoRoutine()
|
||||
{
|
||||
yield return new WaitForSeconds(10f);
|
||||
yield return new WaitForSecondsRealtime(10f);
|
||||
|
||||
try { Utils.SendMessage(HudManagerPatch.BuildAutoGMRotationStatusText(true), title: GetString("AutoGMRotationStatusText")); }
|
||||
catch (Exception e) { Utils.ThrowException(e); }
|
||||
|
||||
+10
-10
@@ -2,7 +2,7 @@
|
||||
"LanguageID": "0",
|
||||
"TextBelowVersionText": "",
|
||||
"HostText": "مضيف - EHR",
|
||||
"IconColor": "",
|
||||
"IconColor": "00a5ff",
|
||||
"HostColor": "#00ffa5",
|
||||
"Icon": " | ",
|
||||
"NameColor": "#00ffff",
|
||||
@@ -59,19 +59,19 @@
|
||||
"ROT.Impostor_Killing": "★ الأدوار القاتلة",
|
||||
"ROT.Impostor_Support": "★ الأدوار الداعمة",
|
||||
"ROT.Impostor_Concealing": "أدوار الإخفاء",
|
||||
"ROT.Impostor_Miscellaneous": "★ Miscellaneous Roles",
|
||||
"ROT.Impostor_Miscellaneous": "أدوار متنوعة",
|
||||
"ROT.Impostor_Madmate": "ادوار الطاقم الغاضب",
|
||||
"ROT.Crewmate_Investigate": "★ أدوار التحقق",
|
||||
"ROT.Crewmate_Support": "★ أدوار الدعم",
|
||||
"ROT.Crewmate_Power": "★ أدوار القوة",
|
||||
"ROT.Crewmate_Killing": "★ الأدوار القاتلة",
|
||||
"ROT.Crewmate_Chaos": "★ أدوار الفوضى",
|
||||
"ROT.Crewmate_Miscellaneous": "★ Miscellaneous Roles",
|
||||
"ROT.Crewmate_Miscellaneous": "أدوار متنوعة",
|
||||
"ROT.Neutral_Evil": "★ الأدوار الشريرة",
|
||||
"ROT.Neutral_Pariah": "★ Pariah Roles",
|
||||
"ROT.Neutral_Benign": "★ Benign Roles",
|
||||
"ROT.Neutral_Killing": "★ الأدوار القاتلة",
|
||||
"ROT.Coven_Miscellaneous": "★ Miscellaneous Roles",
|
||||
"ROT.Coven_Miscellaneous": "أدوار متنوعة",
|
||||
"ROT.Vanilla": "★ Vanilla Roles",
|
||||
"ROT.Basic": "★ الأدوار العادية",
|
||||
"ROT.AddonType.ImpOnly": "★ زوائد المحتال-فقط",
|
||||
@@ -121,8 +121,8 @@
|
||||
"RoleSubCategoryLimitOptions.Neutral_Pariah.Max": "Maximum Neutral Pariah Roles",
|
||||
"RoleSubCategoryLimitOptions.Neutral_Benign.Min": "Minimum Neutral Benign Roles",
|
||||
"RoleSubCategoryLimitOptions.Neutral_Benign.Max": "Maximum Neutral Benign Roles",
|
||||
"RoleSubCategoryLimitOptions.Neutral_Killing.Min": "Minimum Neutral Killing Roles",
|
||||
"RoleSubCategoryLimitOptions.Neutral_Killing.Max": "Maximum Neutral Killing Roles",
|
||||
"RoleSubCategoryLimitOptions.Neutral_Killing.Min": "أدنى حد للأدوار القاتلين المحايدين",
|
||||
"RoleSubCategoryLimitOptions.Neutral_Killing.Max": "أقصى حد للأدوار القاتلين المحايدين",
|
||||
"FactionLimits.Impostor.Min": "<#00ffa5>Minimum</color> <#ffffff>amount of</color> Impostor Roles",
|
||||
"FactionLimits.Impostor.Max": "<#00a5ff>Maximum</color> <#ffffff>amount of</color> Impostor Roles",
|
||||
"FactionLimits.Neutral.Min": "<#00ffa5>Minimum</color> <#ffffff>amount of</color> Neutral Roles",
|
||||
@@ -10180,9 +10180,9 @@
|
||||
"WinnerRoleText.Bubble": "Bubble Wins!",
|
||||
"WinnerRoleText.Hookshot": "Hookshot Wins!",
|
||||
"WinnerRoleText.Sprayer": "Sprayer Wins!",
|
||||
"WinnerRoleText.SoulHunter": "Soul Hunter Wins!",
|
||||
"WinnerRoleText.SoulHunter": "صائد الروح يفوز!",
|
||||
"WinnerRoleText.Tiger": "Tiger Wins!",
|
||||
"WinnerRoleText.Beehive": "Beehive Wins!",
|
||||
"WinnerRoleText.Beehive": "فوز خلية النحل!",
|
||||
"WinnerRoleText.Phantasm": "Phantasm Wins!",
|
||||
"WinnerRoleText.Hider": "Hiders Win!",
|
||||
"WinnerRoleText.Seeker": "Seekers Win!",
|
||||
@@ -10232,7 +10232,7 @@
|
||||
"EnableAutoFactionMinMaxSettings": "Enable Automatic Team Size Adjustment Based on Player Count",
|
||||
"AutoFactionMinMaxSettings.PlayerCap": "Minimum Player Threshold for These Settings to Apply (0 = unused)",
|
||||
"AutoFactionMinMaxSettings.Applied": "[Auto Team Sizes] {0} players (>={1}) = {2} (<#ffff00>NNK</color>: <#ffffff>{3}-{4}</color>)",
|
||||
"GMPoll.Allow": "Show {gm} in /gmpoll choices",
|
||||
"GMPoll.Allow": "عرض {gm} في خيارات /gmpoll",
|
||||
"MPoll.Allow": "Show {m} in /mpoll choices",
|
||||
"MenuTitle.GMPoll": "Game Mode Poll",
|
||||
"MenuTitle.MPoll": "Map Poll",
|
||||
@@ -10268,6 +10268,6 @@
|
||||
"Hungarian": "Hungarian",
|
||||
"Polish": "Polish",
|
||||
"Indonesian": "Indonesian",
|
||||
"Persian": "Persian",
|
||||
"Persian": "الفارسية",
|
||||
"NotAssigned": "-"
|
||||
}
|
||||
@@ -2210,7 +2210,7 @@
|
||||
"MediumHelp": "<b>/ms yes</b> to agree\\n<b>/ms no</b> to disagree",
|
||||
"MediumYes": "You thought you heard a quiet voice from another world affirming the answer to your question.",
|
||||
"MediumNo": "You thought you heard a quiet voice from another world denying the answer to your question.",
|
||||
"MediumDone": "You successfully responded to the Medium.",
|
||||
"MediumDone": "Du hast erfolgreich dem Medium geantwortet.",
|
||||
"MediumNotifyTarget": "<b>{0}</b>, the Medium, has established contact with you. Before the end of this meeting, you have a chance to respond to their question. Type one of the following commands to answer:\\nConfirm: /ms yes\\nDeny: /ms no",
|
||||
"MediumNotifySelf": "You established contact with <b>{0}</b>, please ask questions to them and wait for them to respond.\\n\\nRemaining ability uses: {1}",
|
||||
"ByBard": "Von <color=#ff1919>Barde</color>",
|
||||
@@ -2386,7 +2386,7 @@
|
||||
"Message.MadmateSelfVoteModeNotify": "Please note: The current Madness generation mode is <b>{0}</b>\\n Voting for yourself means you want to be Madmate. If you meet the conditions to become Madmate and there are still spaces left, you will immediately become Madmate",
|
||||
"Message.HostLeftGameInGame": "★ WARNUNG★ Der Host hat das Spiel verlassen. Bitte verlasse die Lobby oder warte bis ein neuer Host eine neue Lobby erstellt, da das Spiel nicht mehr normal starten wird.",
|
||||
"Message.HostLeftGameInLobby": "★ WARNUNG★ Der Host hat das Spiel verlassen. Wenn der neue Host EHR besitzt, musst du der Lobby neu beitreten.",
|
||||
"Message.LobbyShared": "The lobby has successfully been shared!",
|
||||
"Message.LobbyShared": "Die Lobby wurde erfolgreich geteilt!",
|
||||
"Message.LobbyShareFailed": "EHR-Chan does not seem to be online (failed to share lobby)",
|
||||
"Message.YTPlanSelected": "In the next game, your role will be <b>{0}</b>",
|
||||
"Message.YTPlanSelectFailed": "You cannot be assigned as <b>{0}</b>.\\nIt may be because you don't have this role enabled, or this role does not support being assigned.",
|
||||
@@ -2394,7 +2394,7 @@
|
||||
"Message.YTPlanNotice": "Note: The [YouTuber Plan] is enabled in this lobby, which means the Host can specify their role in the next game to make it easier to get content. In case the Host abuses this feature, please exit the game or report it.\\nCurrent Creator Credentials:",
|
||||
"Warning.InvalidRpc": "Kicked <b>{0}</b> because an invalid RPC was received. Please check that no mods other than EHR are installed.",
|
||||
"Warning.TooManyRPCs": "Kicked <b>{0}</b> because too many RPCs were received from them.",
|
||||
"Warning.NoModHost": "EHR is not installed on the host",
|
||||
"Warning.NoModHost": "Der Host hat nicht EHR installiert",
|
||||
"Warning.MismatchedVersion": "<b>{0}</b> has a different version than <b>{1}</b>",
|
||||
"Warning.AutoExitAtMismatchedVersion": "The host has no or a different version of {0}\\nYou will be kicked in {1}",
|
||||
"IncompatibleMod": "Inkompatible Mod",
|
||||
@@ -2885,7 +2885,7 @@
|
||||
"Achievement.ImUnstoppable.Description": "Get Medic's shield as Snitch",
|
||||
"Achievement.ThereCanOnlyBeOne.Description": "Kill someone who had the same role as you",
|
||||
"Achievement.CantTouchThis.Description": "As Detour, redirect at least 3 interactions",
|
||||
"Achievement.ItsMorbinTime.Description": "Shapeshift into someone",
|
||||
"Achievement.ItsMorbinTime.Description": "Verwandle dich in jemanden",
|
||||
"Achievement.WhatHaveIDone.Description": "Kill your Lover, Romantic, Lawyer or Follower",
|
||||
"Achievement.BetrayalLevel100.Description": "Kill Madmate as Impostor or Impostor as Madmate",
|
||||
"Achievement.TheRealTraitor.Description": "Kill Renegade as Traitor",
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
"SubText.GM": "혼돈을 구경하세요!",
|
||||
"SubText.Crewmate": "임포스터를 찾고, <color=#ff1919>방출, 처치 </color> 하세요.",
|
||||
"SubText.Impostor": "방해공작을 펼치고, 모두를 처치하세요!",
|
||||
"SubText.Neutral": "Work alone to achieve your victory",
|
||||
"SubText.Neutral": "혼자 이기세요",
|
||||
"SubText.Coven": "Eliminate everyone with your team",
|
||||
"SubText.Madmate": "임포스터를 <color=#ff1919>도우세요!</color>",
|
||||
"SubText.LovingCrewmate": "당신은 {0}님과 사랑에 빠졌습니다❤️",
|
||||
@@ -269,16 +269,16 @@
|
||||
"Grenadier": "폭탄병",
|
||||
"Lighter": "라이터",
|
||||
"Medic": "메딕",
|
||||
"FortuneTeller": "Fortune Teller",
|
||||
"FortuneTeller": "점술가",
|
||||
"Glitch": "글리치",
|
||||
"Judge": "판사",
|
||||
"Mortician": "장의사",
|
||||
"Medium": "Medium",
|
||||
"Pacifist": "Pacifist",
|
||||
"Medium": "영매",
|
||||
"Pacifist": "평화주의자",
|
||||
"Observer": "관찰자",
|
||||
"Monarch": "군주",
|
||||
"Investigator": "Investigator",
|
||||
"Coroner": "Coroner",
|
||||
"Investigator": "조사관",
|
||||
"Coroner": "검사관",
|
||||
"Scout": "정찰병",
|
||||
"Merchant": "상인",
|
||||
"Deputy": "매니저",
|
||||
@@ -1229,8 +1229,8 @@
|
||||
"CTA.PlayersCanSeeEachOthersRoles": "Custom Teamed Players Can See Each Other's Roles",
|
||||
"AirshipVariableElectrical": "Variable Electrical (<color=#ed0007>Airship</color>)",
|
||||
"ApplyDenyNameList": "Apply DenyName List",
|
||||
"KickPlayerFriendCodeNotExist": "Kick players who are not logged in",
|
||||
"ApplyBanList": "Apply BanList",
|
||||
"KickPlayerFriendCodeNotExist": "로그인되지 않은 인원을 추방",
|
||||
"ApplyBanList": "금지 목록 적용",
|
||||
"EndWhenPlayerBug": "Force Game End on Critical Errors to Prevent Black Screen",
|
||||
"KillFlashDuration": "Kill-Flash Duration",
|
||||
"ConfirmEjectionsMode": "Confirm Ejections Mode",
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -32,11 +32,9 @@ public abstract class CovenBase : RoleBase
|
||||
|
||||
LateTask.New(() =>
|
||||
{
|
||||
var sender = CustomRpcSender.Create("CovenGiveNecronomicon", SendOption.Reliable);
|
||||
string[] holders = Main.PlayerStates.Where(s => s.Value.Role is CovenBase { HasNecronomicon: true }).Select(s => s.Key.ColoredPlayerName()).ToArray();
|
||||
Main.AllPlayerControls.Where(x => x.Is(Team.Coven)).Select(x => x.PlayerId).Without(receiver.Key).Do(x => sender = Utils.SendMessage("\n", x, string.Format(Translator.GetString("PlayerReceivedTheNecronomicon"), receiver.Key.ColoredPlayerName(), Main.CovenColor, holders.Length, string.Join(", ", holders)), writer: sender, multiple: true));
|
||||
sender = Utils.SendMessage("\n", receiver.Key, string.Format(Translator.GetString("YouReceivedTheNecronomicon"), Main.CovenColor), writer: sender, multiple: true);
|
||||
sender.SendMessage(dispose: sender.stream.Length <= 3);
|
||||
Main.AllPlayerControls.Where(x => x.Is(Team.Coven)).Select(x => x.PlayerId).Without(receiver.Key).Do(x => Utils.SendMessage("\n", x, string.Format(Translator.GetString("PlayerReceivedTheNecronomicon"), receiver.Key.ColoredPlayerName(), Main.CovenColor, holders.Length, string.Join(", ", holders))));
|
||||
Utils.SendMessage("\n", receiver.Key, string.Format(Translator.GetString("YouReceivedTheNecronomicon"), Main.CovenColor));
|
||||
}, 12f, log: false);
|
||||
}
|
||||
|
||||
|
||||
@@ -108,7 +108,7 @@ public class Car : RoleBase
|
||||
if (PhysicsHelpers.AnythingBetween(collider, collider.bounds.center, newPos + (addVector * 2), Constants.ShipOnlyMask, false)) break;
|
||||
|
||||
target.TP(newPos, log: false);
|
||||
yield return new WaitForSeconds(0.05f);
|
||||
yield return new WaitForSecondsRealtime(0.05f);
|
||||
}
|
||||
|
||||
Main.AllPlayerSpeed[target.PlayerId] = oldSpeed;
|
||||
|
||||
@@ -105,18 +105,18 @@ internal class Spiritualist : RoleBase
|
||||
var writer = CustomRpcSender.Create("SpiritualistSendMessage", SendOption.Reliable);
|
||||
writer.StartMessage(target.OwnerId);
|
||||
|
||||
writer.StartRpc(target.NetId, RpcCalls.SetName)
|
||||
.Write(target.Data.NetId)
|
||||
writer.StartRpc(PlayerControl.LocalPlayer.NetId, RpcCalls.SetName)
|
||||
.Write(PlayerControl.LocalPlayer.Data.NetId)
|
||||
.Write(GetString("SpiritualistNoticeTitle"))
|
||||
.EndRpc();
|
||||
|
||||
writer.StartRpc(target.NetId, RpcCalls.SendChat)
|
||||
writer.StartRpc(PlayerControl.LocalPlayer.NetId, RpcCalls.SendChat)
|
||||
.Write(GetString("SpiritualistNoticeMessage"))
|
||||
.EndRpc();
|
||||
|
||||
writer.StartRpc(target.NetId, RpcCalls.SetName)
|
||||
.Write(target.Data.NetId)
|
||||
.Write(target.Data.PlayerName)
|
||||
writer.StartRpc(PlayerControl.LocalPlayer.NetId, RpcCalls.SetName)
|
||||
.Write(PlayerControl.LocalPlayer.Data.NetId)
|
||||
.Write(PlayerControl.LocalPlayer.Data.PlayerName)
|
||||
.EndRpc();
|
||||
|
||||
writer.EndMessage();
|
||||
|
||||
@@ -31,11 +31,15 @@ public class Swapper : RoleBase
|
||||
{
|
||||
Options.SetupSingleRoleOptions(Id, TabGroup.CrewmateRoles, CustomRoles.Swapper);
|
||||
|
||||
SwapMax = new IntegerOptionItem(Id + 3, "SwapperMax", new(0, 20, 1), 1, TabGroup.CrewmateRoles).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Swapper])
|
||||
SwapMax = new IntegerOptionItem(Id + 3, "SwapperMax", new(0, 20, 1), 1, TabGroup.CrewmateRoles)
|
||||
.SetParent(Options.CustomRoleSpawnChances[CustomRoles.Swapper])
|
||||
.SetValueFormat(OptionFormat.Times);
|
||||
|
||||
CanSwapSelf = new BooleanOptionItem(Id + 2, "CanSwapSelfVotes", true, TabGroup.CrewmateRoles).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Swapper]);
|
||||
CanStartMeeting = new BooleanOptionItem(Id + 4, "JesterCanUseButton", true, TabGroup.CrewmateRoles).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Swapper]);
|
||||
CanSwapSelf = new BooleanOptionItem(Id + 2, "CanSwapSelfVotes", false, TabGroup.CrewmateRoles)
|
||||
.SetParent(Options.CustomRoleSpawnChances[CustomRoles.Swapper]);
|
||||
|
||||
CanStartMeeting = new BooleanOptionItem(Id + 4, "JesterCanUseButton", true, TabGroup.CrewmateRoles)
|
||||
.SetParent(Options.CustomRoleSpawnChances[CustomRoles.Swapper]);
|
||||
|
||||
SwapperAbilityUseGainWithEachTaskCompleted = new FloatOptionItem(Id + 6, "AbilityUseGainWithEachTaskCompleted", new(0f, 5f, 0.05f), 0.3f, TabGroup.CrewmateRoles)
|
||||
.SetParent(Options.CustomRoleSpawnChances[CustomRoles.Swapper])
|
||||
@@ -45,7 +49,8 @@ public class Swapper : RoleBase
|
||||
.SetParent(Options.CustomRoleSpawnChances[CustomRoles.Swapper])
|
||||
.SetValueFormat(OptionFormat.Times);
|
||||
|
||||
HideMsg = new BooleanOptionItem(Id + 5, "SwapperHideMsg", true, TabGroup.CrewmateRoles).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Swapper]);
|
||||
HideMsg = new BooleanOptionItem(Id + 5, "SwapperHideMsg", true, TabGroup.CrewmateRoles)
|
||||
.SetParent(Options.CustomRoleSpawnChances[CustomRoles.Swapper]);
|
||||
}
|
||||
|
||||
public override void Init()
|
||||
@@ -248,8 +253,11 @@ public class Swapper : RoleBase
|
||||
{
|
||||
if (Starspawn.IsDayBreak) return;
|
||||
|
||||
if (CNO == null) CNO = CanSwapSelf.GetBool() ? new ShapeshiftMenuElement(shapeshifter.PlayerId) : null;
|
||||
else if (CNO.playerControl.NetId == target.NetId) target = shapeshifter;
|
||||
if (GameStates.CurrentServerType != GameStates.ServerType.Vanilla)
|
||||
{
|
||||
if (CNO == null) CNO = CanSwapSelf.GetBool() ? new ShapeshiftMenuElement(shapeshifter.PlayerId) : null;
|
||||
else if (CNO.playerControl.NetId == target.NetId) target = shapeshifter;
|
||||
}
|
||||
|
||||
SwapMsg(shapeshifter, $"/sw {target.PlayerId}");
|
||||
}
|
||||
|
||||
@@ -152,7 +152,7 @@ internal class TimeMaster : RoleBase
|
||||
player.MarkDirtySettings();
|
||||
}
|
||||
|
||||
yield return new WaitForSeconds(0.55f);
|
||||
yield return new WaitForSecondsRealtime(0.55f);
|
||||
|
||||
for (long i = now - 1; i >= now - length; i--)
|
||||
{
|
||||
@@ -166,7 +166,7 @@ internal class TimeMaster : RoleBase
|
||||
player.TP(pos);
|
||||
}
|
||||
|
||||
yield return new WaitForSeconds(delay);
|
||||
yield return new WaitForSecondsRealtime(delay);
|
||||
}
|
||||
|
||||
if (TimeMasterCanRevive.GetBool())
|
||||
|
||||
@@ -140,7 +140,7 @@ public class Stasis : RoleBase
|
||||
try { imps.NotifyPlayers($"<#00ffa5>{Translator.GetString("Stasis.TimeFrozenNotify")}</color> <#888888>-</color> <#ffffff>{time - i}</color>", overrideAll: true); }
|
||||
catch (Exception e) { Utils.ThrowException(e); }
|
||||
|
||||
yield return new WaitForSeconds(1f);
|
||||
yield return new WaitForSecondsRealtime(1f);
|
||||
}
|
||||
|
||||
UsingAbility = false;
|
||||
|
||||
@@ -149,7 +149,7 @@ public class Venerer : RoleBase
|
||||
});
|
||||
frozenPlayers = nearbyPlayers;
|
||||
|
||||
yield return new WaitForSeconds(1f);
|
||||
yield return new WaitForSecondsRealtime(1f);
|
||||
timer--;
|
||||
}
|
||||
|
||||
|
||||
@@ -100,7 +100,7 @@ public class Disperser : RoleBase
|
||||
|
||||
foreach (PlayerControl pc in PlayerControl.AllPlayerControls)
|
||||
{
|
||||
if (player.PlayerId == pc.PlayerId || pc.Data.IsDead || pc.onLadder || pc.inMovingPlat || pc.inVent || GameStates.IsMeeting)
|
||||
if (player.PlayerId == pc.PlayerId || pc.Data.IsDead || !pc.IsAlive() || pc.onLadder || pc.inMovingPlat || pc.inVent || GameStates.IsMeeting)
|
||||
{
|
||||
if (!pc.Is(CustomRoles.Disperser)) pc.Notify(ColorString(GetRoleColor(CustomRoles.Disperser), string.Format(GetString("ErrorTeleport"), pc.GetRealName())));
|
||||
continue;
|
||||
|
||||
@@ -193,7 +193,7 @@ internal class Revolutionist : RoleBase
|
||||
}
|
||||
}
|
||||
|
||||
if (GameStates.IsInTask && player.IsDrawDone() && player.IsAlive() && !player.Data.IsDead)
|
||||
if (GameStates.IsInTask && player.IsDrawDone() && player.IsAlive())
|
||||
{
|
||||
if (RevolutionistStart.TryGetValue(playerId, out var start))
|
||||
{
|
||||
|
||||
@@ -119,18 +119,18 @@ public class Spiritcaller : RoleBase
|
||||
var writer = CustomRpcSender.Create("SpiritCallerSendMessage", SendOption.Reliable);
|
||||
writer.StartMessage(target.OwnerId);
|
||||
|
||||
writer.StartRpc(target.NetId, RpcCalls.SetName)
|
||||
.Write(target.Data.NetId)
|
||||
writer.StartRpc(PlayerControl.LocalPlayer.NetId, RpcCalls.SetName)
|
||||
.Write(PlayerControl.LocalPlayer.Data.NetId)
|
||||
.Write(GetString("SpiritcallerNoticeTitle"))
|
||||
.EndRpc();
|
||||
|
||||
writer.StartRpc(target.NetId, RpcCalls.SendChat)
|
||||
writer.StartRpc(PlayerControl.LocalPlayer.NetId, RpcCalls.SendChat)
|
||||
.Write(GetString("SpiritcallerNoticeMessage"))
|
||||
.EndRpc();
|
||||
|
||||
writer.StartRpc(target.NetId, RpcCalls.SetName)
|
||||
.Write(target.Data.NetId)
|
||||
.Write(target.Data.PlayerName)
|
||||
writer.StartRpc(PlayerControl.LocalPlayer.NetId, RpcCalls.SetName)
|
||||
.Write(PlayerControl.LocalPlayer.Data.NetId)
|
||||
.Write(PlayerControl.LocalPlayer.Data.PlayerName)
|
||||
.EndRpc();
|
||||
|
||||
writer.EndMessage();
|
||||
|
||||
Reference in new issue
Block a user