Skip to content
This repository was archived by the owner on Aug 11, 2025. It is now read-only.

Commit 462b316

Browse files
committed
v1.0.2.4 update
1 parent e758dd9 commit 462b316

28 files changed

Lines changed: 613 additions & 98 deletions

Nebula/CustomOptionHolder.cs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,10 @@ public static CustomOption GetCurrentGameModeOption()
149149
public static CustomOption additionalEmergencyCoolDown;
150150
public static CustomOption additionalEmergencyCoolDownCondition;
151151
public static CustomOption showRoleOfExiled;
152+
public static CustomOption useSpecialRoleExiledText;
153+
public static CustomOption showExtraRoles;
154+
public static CustomOption showNumberOfEvilNeutralRoles;
155+
public static CustomOption dontShowImpostorCountIfDidntExile;
152156

153157
public static CustomOption limiterOptions;
154158
public static CustomOption timeLimitOption;
@@ -372,6 +376,46 @@ public static void Load()
372376
return false;
373377
}
374378
});
379+
useSpecialRoleExiledText = CustomOption.Create(Color.white,"option.useSpecialRoleExiledText",true,meetingOptions).AddCustomPrerequisite(() => {
380+
try{
381+
return showRoleOfExiled.getBool() && GameOptionsManager.Instance.currentNormalGameOptions.ConfirmImpostor;
382+
}
383+
catch{
384+
return false;
385+
}
386+
});
387+
showExtraRoles = CustomOption.Create(Color.white,"option.showExtraRoles",true,meetingOptions).AddCustomPrerequisite(() => {
388+
try
389+
{
390+
return GameOptionsManager.Instance.currentNormalGameOptions.ConfirmImpostor && useSpecialRoleExiledText.getBool();
391+
}
392+
catch
393+
{
394+
return false;
395+
}
396+
});
397+
showNumberOfEvilNeutralRoles = CustomOption.Create(Color.white,"option.showNumberOfEvilNeutralRoles",true,meetingOptions).AddCustomPrerequisite(() =>
398+
{
399+
try
400+
{
401+
return GameOptionsManager.Instance.currentNormalGameOptions.ConfirmImpostor && useSpecialRoleExiledText.getBool();
402+
}
403+
catch
404+
{
405+
return false;
406+
}
407+
});
408+
dontShowImpostorCountIfDidntExile = CustomOption.Create(Color.white,"option.dontShowImpostorCountIfDidntExile",false,meetingOptions).AddCustomPrerequisite(() =>
409+
{
410+
try
411+
{
412+
return GameOptionsManager.Instance.currentNormalGameOptions.ConfirmImpostor && useSpecialRoleExiledText.getBool();
413+
}
414+
catch
415+
{
416+
return false;
417+
}
418+
});
375419

376420
additionalEmergencyCoolDown.alternativeOptionScreenBuilder = (refresher) =>
377421
{

Nebula/Nebula.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,14 +41,14 @@ public class NebulaPlugin : BasePlugin
4141
public const string AmongUsVersion = "2023.3.28";
4242
public const string PluginGuid = "cn.zsfabtest.amongus.nebular";
4343
public const string PluginName = "TheNebula-R";
44-
public const string PluginVersion = "1.0.2.2";
44+
public const string PluginVersion = "1.0.2.4";
4545
public const bool IsSnapshot = false;
4646

4747
public static string PluginVisualVersion = IsSnapshot ? "23.03.29a" : PluginVersion;
4848
public static string PluginStage = IsSnapshot ? "Snapshot" : "";
4949

50-
public const string PluginVersionForFetch = "1.0.2.2";
51-
public byte[] PluginVersionData = new byte[] { 1, 0, 2, 2 };
50+
public const string PluginVersionForFetch = "1.0.2.4";
51+
public byte[] PluginVersionData = new byte[] { 1, 0, 2, 4 };
5252

5353
public static NebulaPlugin Instance;
5454

Nebula/Patches/ExileControllPatch.cs

Lines changed: 51 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,13 @@ class ExileControllerBeginPatch
1111

1212
public static void Postfix(ExileController __instance, [HarmonyArgument(0)] ref GameData.PlayerInfo exiled, [HarmonyArgument(1)] bool tie)
1313
{
14-
/*
15-
if (CustomOptionHolder.meetingOptions.getBool() && CustomOptionHolder.showRoleOfExiled.getBool() && GameManager.Instance.LogicOptions.GetConfirmImpostor())
16-
{
17-
var role = exiled.GetModData()?.role;
18-
if (role != null) __instance.completeString = Language.Language.GetString("game.exile.roleText").Replace("%PLAYER%", exiled.PlayerName).Replace("%ROLE%", Language.Language.GetString("role." + role.LocalizeName + ".name"));
19-
}
20-
*/
14+
try{
15+
if (CustomOptionHolder.meetingOptions.getBool() && CustomOptionHolder.showRoleOfExiled.getBool() && GameManager.Instance.LogicOptions.GetConfirmImpostor())
16+
{
17+
var role = exiled.GetModData()?.role;
18+
if (role != null) __instance.completeString = Language.Language.GetString("game.exile.roleText").Replace("%PLAYER%", exiled.PlayerName).Replace("%ROLE%", Language.Language.GetString("role." + role.LocalizeName + ".name"));
19+
}
20+
}catch{ }
2121

2222
OnExiled(exiled);
2323
}
@@ -176,11 +176,47 @@ class ExileControllerMessagePatch
176176
{
177177
static void Postfix(ref string __result, [HarmonyArgument(0)] StringNames id)
178178
{
179+
if(!CustomOptionHolder.useSpecialRoleExiledText.getBool()) return;
179180
try
180181
{
181182
if (ExileController.Instance != null && ExileController.Instance.exiled != null)
182183
{
183184
PlayerControl player = Helpers.playerById(ExileController.Instance.exiled.Object.PlayerId);
185+
if (player == null){
186+
if (id is StringNames.ImpostorsRemainP or StringNames.ImpostorsRemainS){
187+
if(CustomOptionHolder.dontShowImpostorCountIfDidntExile.getBool()) __result = "";
188+
}
189+
return;
190+
}
191+
if((id is StringNames.ImpostorsRemainP or StringNames.ImpostorsRemainS) &&
192+
CustomOptionHolder.meetingOptions.getBool() && CustomOptionHolder.showNumberOfEvilNeutralRoles.getBool()){
193+
int sums = 0;
194+
foreach (PlayerControl p in PlayerControl.AllPlayerControls)
195+
{
196+
if (p.GetModData() != null && !p.Data.IsDead && (p.GetModData().role.side == Roles.Side.Jackal ||
197+
p.GetModData().role.side == Roles.Side.Spectre ||
198+
p.GetModData().role.side == Roles.Side.Pavlov ||
199+
p.GetModData().role.side == Roles.Side.Moriarty ||
200+
p.GetModData().role.side == Roles.Side.Arsonist ||
201+
p.GetModData().role.side == Roles.Side.Vulture ||
202+
p.GetModData().role.side == Roles.Side.Madman ||
203+
p.GetModData().role.side == Roles.Side.Cascrubinter
204+
)) sums++;
205+
//Debug.LogWarning(string.Format("ExileControllPatch - {0} : {1}", p.name, p.GetModData().role.LocalizeName));
206+
}
207+
if (player.GetModData() != null && !player.Data.IsDead && (player.GetModData().role.side == Roles.Side.Jackal ||
208+
player.GetModData().role.side == Roles.Side.Spectre ||
209+
player.GetModData().role.side == Roles.Side.Pavlov ||
210+
player.GetModData().role.side == Roles.Side.Moriarty ||
211+
player.GetModData().role.side == Roles.Side.Arsonist ||
212+
player.GetModData().role.side == Roles.Side.Vulture ||
213+
player.GetModData().role.side == Roles.Side.Madman ||
214+
player.GetModData().role.side == Roles.Side.Cascrubinter
215+
)) sums--;
216+
//__result.Remove('.');
217+
//__result.Remove('。');
218+
__result += Language.Language.GetString("text.exile.evilNeutral").Replace("%COUNT%",sums.ToString());
219+
}
184220
if (id is StringNames.ImpostorsRemainP or StringNames.ImpostorsRemainS)
185221
{
186222
bool flag = false;
@@ -191,15 +227,16 @@ static void Postfix(ref string __result, [HarmonyArgument(0)] StringNames id)
191227
}
192228
if (flag) __result += "\n" + Language.Language.GetString("text.exile.bartenderAddition");
193229
}
194-
if (player == null) return;
195230
// Exile role text
196231
if ((id is StringNames.ExileTextPN or StringNames.ExileTextSN or StringNames.ExileTextPP or StringNames.ExileTextSP) &&
197232
CustomOptionHolder.meetingOptions.getBool() && CustomOptionHolder.showRoleOfExiled.getBool())
198233
{
199234
__result = Language.Language.GetString("text.exile.role").Replace("%PLAYER%",player.Data.PlayerName);
200235
string roleText = Language.Language.GetString("role." + player.GetModData().role.GetActualRole(player.GetModData()).LocalizeName + ".name");
201-
foreach(Roles.ExtraRole extra in player.GetModData().extraRole){
202-
roleText += Language.Language.GetString("text.exile.connection") + Language.Language.GetString("role." + extra.LocalizeName + ".name");
236+
if(CustomOptionHolder.showExtraRoles.getBool()){
237+
foreach(Roles.ExtraRole extra in player.GetModData().extraRole){
238+
roleText += Language.Language.GetString("text.exile.connection") + Language.Language.GetString("role." + extra.LocalizeName + ".name");
239+
}
203240
}
204241
__result = __result.Replace("%ROLE%",roleText);
205242
}
@@ -212,6 +249,10 @@ static void Postfix(ref string __result, [HarmonyArgument(0)] StringNames id)
212249
}
213250
else if (player == Roles.NeutralRoles.Cascrubinter.target) __result = Language.Language.GetString("text.exile.cascrubinterAddition");
214251
}
252+
}else{
253+
if (id is StringNames.ImpostorsRemainP or StringNames.ImpostorsRemainS){
254+
if(CustomOptionHolder.dontShowImpostorCountIfDidntExile.getBool()) __result = "";
255+
}
215256
}
216257
}
217258
catch

Nebula/Resources/Languages/SChinese.dat

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1384,6 +1384,10 @@
13841384
"option.canBeFlash" : "可以成为闪电侠"
13851385
"option.canBeSignaller" : "可以成为通讯兵"
13861386
"option.canBeSecondaryJackal" : "可以成为附加豺狼"
1387+
"option.showNumberOfEvilNeutralRoles" : "显示剩余邪恶中立"
1388+
"option.dontShowImpostorCountIfDidntExile" : "没有人被驱逐时不显示剩余伪装者(邪恶中立)数量"
1389+
"option.useSpecialRoleExiledText" : "使用NoS-R的驱逐显示"
1390+
"option.showExtraRoles" : "驱逐显示附加职业"
13871391

13881392
"role.guesser.canWinAlong" : "可以单独胜利"
13891393
"role.guesser.guessCountToWin" : "单独胜利需要的正确猜测次数"
@@ -1398,6 +1402,7 @@
13981402
"role.madmate.taskPercent" : "得知伪装者所需任务百分比"
13991403

14001404
"role.sheriff.madmateCanKillEveryone" : "叛徒警长可以任意击杀"
1405+
"role.sheriff.madmateCanKillEveryone" : "豺狼警长可以任意击杀"
14011406

14021407
"role.bountyHunter.canChangeTarget" : "可以手动更换目标"
14031408
"role.bountyHunter.changeTargetCoolDown" : "手动更换目标冷却"
@@ -1408,6 +1413,9 @@
14081413

14091414
"role.paparazzo.isGuessable" : "是否可以被猜测"
14101415

1416+
"role.chainShifter.cleanTasks" : "(实验性)交换后清除任务"
1417+
"role.chainShifter.canShiftEvenDied" : "在交换前死亡仍可以交换"
1418+
14111419
"role.lastImpostor.canSpawn" : "是否可以生成"
14121420
"role.lastImpostor.guessCount" : "最多猜测次数"
14131421

@@ -1609,6 +1617,8 @@
16091617
"role.transporter.description" : "全体目光向我看齐"
16101618
"role.transporter.info" : "我宣布个事"
16111619
"role.transporter.teleportCooldown" : "传送冷却时间"
1620+
"role.transporter.specialSetCooldownAfterTeleport" : "传送后对群体范围技能进行冷却限制"
1621+
"role.transporter.leastCooldown" : "限制冷却时间"
16121622

16131623
"role.kotwal.name" : "警察局长"
16141624
"role.kotwal.short" : "局"
@@ -1623,6 +1633,8 @@
16231633
"role.pavlov.description" : "狗子是个好东西"
16241634
"role.pavlov.info" : "舔 狗 之 王"
16251635
"role.pavlov.createDogsCooldown" : "喂食冷却时间"
1636+
"role.pavlov.dogKillCooldown" : "狗的击杀冷却时间"
1637+
"role.pavlov.dogCanUseVent" : "狗可以使用管道"
16261638

16271639
"role.dog.name" : "巴浦洛夫的狗"
16281640
"role.dog.short" : "巴狗"
@@ -1668,6 +1680,7 @@
16681680
"role.invisible.desciption" : "杀人于无形"
16691681
"role.invisibleMan.invisibleCooldown" : "隐身冷却时间"
16701682
"role.invisibleMan.invisibleDuringTime" : "隐身持续时间"
1683+
"role.invisibleMan.canUseVent" : "可以使用管道"
16711684

16721685
"role.moriarty.name" : "莫里亚蒂"
16731686
"role.moriarty.short" : "莫"
@@ -1811,12 +1824,29 @@
18111824
"role.minekeeper.setMineCooldown" : "埋雷技能冷却"
18121825
"role.minekeeper.maxMineCount" : "最大埋雷次数"
18131826

1827+
"role.chainKiller.name" : "连环杀手"
1828+
"role.chainKiller.short" : "连"
1829+
"role.chainKiller.description" : "你看什么看"
1830+
"role.chainKiller.hint" : "快速击杀一定范围内的人"
1831+
"role.chainKiller.info" : "你可以连续杀死在指定击杀范围内的N个人。\n建议你在人多时出刀。"
1832+
"role.chainKiller.killCooldown" : "击杀冷却时间"
1833+
"role.chainKiller.maxKillCountAtOnce" : "一次性最大击杀人数"
1834+
"role.chainKiller.chainKillRange" : "连续击杀半径"
1835+
1836+
"role.terrorist.name" : "恐怖分子"
1837+
"role.terrorist.short" : "恐"
1838+
"role.terrorist.description" : "自爆流!"
1839+
"role.terrorist.hint" : "艺术就是爆炸!"
1840+
"role.terrorist.info" : "你是一个移动的大规模杀伤性武器。\n趁着人多自爆吧!"
1841+
"role.terrorist.explodeCooldown" : "自爆冷却时间"
1842+
"role.terrorist.explodeRange" : "自爆半径"
1843+
18141844
"option.display.random" : "随机"
18151845

18161846
"side.pavlov.name" : "巴普洛夫团队"
18171847
"side.schrodingersCat.name" : "薛定谔的猫"
18181848
"side.madman.name" : "疯子"
1819-
"side.moran.name" : "莫里亚蒂"
1849+
"side.moriarty.name" : "莫里亚蒂"
18201850
"side.cascrubinter.name" : "行刑者"
18211851
"side.amnesiac.name" : "失忆者"
18221852

@@ -1825,6 +1855,7 @@
18251855
"text.exile.jesterAddition" : "没想到吧awa"
18261856
"text.exile.cascrubinterAddition" : "好像有不好的事情发生..."
18271857
"text.exile.bartenderAddition" : "调酒师正在调酒..."
1858+
"text.exile.evilNeutral" : "剩余%COUNT%个邪恶中立。"
18281859

18291860
"guess.team.crewmate" : "船员"
18301861
"guess.team.impostor" : "伪装者"
@@ -1850,11 +1881,12 @@
18501881
"button.label.escape" : "逃逸"
18511882
"button.label.hide" : "观察"
18521883
"button.label.snap" : "寻尸"
1853-
"button.lable.teleport" : "传送"
1884+
"button.label.teleport" : "传送"
18541885
"button.label.appoint" : "任命"
18551886
"button.label.feed" : "喂养"
18561887
"button.label.remember" : "回忆"
18571888
"button.label.saveShoot" : "储存"
18581889
"button.label.getShoot" : "取用"
18591890
"button.label.dig" : "挖掘"
1860-
"button.label.set" : "设置"
1891+
"button.label.set" : "设置"
1892+
"button.label.explode" : "爆炸"
14 KB
Loading

Nebula/Roles/Assignable.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -736,6 +736,17 @@ public virtual void StaticInitialize() { }
736736
public virtual Helpers.MurderAttemptResult OnMurdered(byte murderId, byte playerId) { return Helpers.MurderAttemptResult.PerformKill; }
737737

738738

739+
/*--------------------------------------------------------------------------------------*/
740+
/*--------------------------------------------------------------------------------------*/
741+
742+
/// <summary>
743+
/// 在传送后被调用
744+
/// </summary>
745+
/// <returns></returns>
746+
[RoleGlobalMethod]
747+
public virtual void AfterTeleport(float time) { }
748+
749+
739750
/*--------------------------------------------------------------------------------------*/
740751
/*--------------------------------------------------------------------------------------*/
741752

Nebula/Roles/CrewmateRoles/Sheriff.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ public class Sheriff : Role
1515
private Module.CustomOption canKillChainShifterOption;
1616
private Module.CustomOption numberOfShotsOption;
1717
private Module.CustomOption madmateCanKillEveryoneOption;
18+
private Module.CustomOption jackalCanKillEveryoneOption;
1819

1920
private SpriteLoader killButtonSprite = new SpriteLoader("Nebula.Resources.SheriffKillButton.png", 100f, "ui.button.sheriff.kill");
2021

@@ -36,6 +37,10 @@ private bool CanKill(PlayerControl target)
3637
if(madmateCanKillEveryoneOption.getBool()) return true;
3738
return false;
3839
}
40+
if (PlayerControl.LocalPlayer.GetModData().extraRole.Contains(Roles.SecondaryJackal)){
41+
if(jackalCanKillEveryoneOption.getBool()) return true;
42+
return false;
43+
}
3944

4045
var p = target.GetModData();
4146

@@ -126,6 +131,8 @@ public override void LoadOptionData()
126131
numberOfShotsOption = CreateOption(Color.white, "numberOfShots", 3, 1, 15, 1);
127132

128133
madmateCanKillEveryoneOption = CreateOption(Color.white, "madmateCanKillEveryone",false);
134+
135+
jackalCanKillEveryoneOption = CreateOption(Color.white, "jackalCanKillEveryone",true);
129136
}
130137

131138
public Sheriff()

Nebula/Roles/ExtraRoles/LastImpostor.cs

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,18 @@ public class LastImpostor : ExtraRole
77
public Module.CustomOption canSpawnOption;
88
public Module.CustomOption GuessCountOption;
99

10-
bool hasGuesserUI = false;
10+
private bool canUse(){
11+
if(PlayerControl.LocalPlayer.GetModData().extraRole.Contains(Roles.SecondaryGuesser)) return false;
12+
else if(PlayerControl.LocalPlayer.GetModData().role == Roles.NiceDecider ||
13+
PlayerControl.LocalPlayer.GetModData().role == Roles.EvilDecider ||
14+
PlayerControl.LocalPlayer.GetModData().role == Roles.NiceGuesser ||
15+
PlayerControl.LocalPlayer.GetModData().role == Roles.EvilGuesser ||
16+
PlayerControl.LocalPlayer.GetModData().role == Roles.NiceTracker ||
17+
PlayerControl.LocalPlayer.GetModData().role == Roles.EvilTracker ||
18+
PlayerControl.LocalPlayer.GetModData().role == Roles.NiceSwapper ||
19+
PlayerControl.LocalPlayer.GetModData().role == Roles.EvilSwapper) return false;
20+
return true;
21+
}
1122

1223
public override void LoadOptionData()
1324
{
@@ -17,15 +28,11 @@ public override void LoadOptionData()
1728
}
1829

1930
public override void SetupMeetingButton(MeetingHud __instance){
20-
ComplexRoles.GuesserSystem.SetupMeetingButton(__instance);
31+
if(canUse()) ComplexRoles.GuesserSystem.SetupMeetingButton(__instance);
2132
}
2233

2334
public override void GlobalInitialize(PlayerControl __instance){
24-
hasGuesserUI = false;
2535
__instance.GetModData().SetExtraRoleData(Roles.SecondaryGuesser.id, (ulong)GuessCountOption.getFloat());
26-
if(PlayerControl.LocalPlayer.GetModData().extraRole.Contains(Roles.SecondaryGuesser)){
27-
hasGuesserUI = true;
28-
}
2936
}
3037

3138
public override void EditDisplayName(byte playerId, ref string displayName, bool hideFlag)
@@ -41,7 +48,7 @@ public override void EditDisplayNameForcely(byte playerId, ref string displayNam
4148

4249
public override void MeetingUpdate(MeetingHud __instance, TextMeshPro meetingInfo)
4350
{
44-
if(!hasGuesserUI) ComplexRoles.GuesserSystem.MeetingUpdate(__instance, meetingInfo);
51+
if(canUse()) ComplexRoles.GuesserSystem.MeetingUpdate(__instance, meetingInfo);
4552
}
4653

4754
public override bool IsSpawnable()

0 commit comments

Comments
 (0)