From 5b72eda5724bcec36b5e452bb7e24cd490518166 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=99=9E=E6=82=96=E3=80=8CYu=20Bell=E3=80=8D?= <73875008+zlzhaidou@users.noreply.github.com> Date: Mon, 10 Aug 2026 10:24:19 +0800 Subject: [PATCH 01/12] added boss defeated toggle config to debug configs --- Configs.cs | 7 ++++++- Localization/TranslationsNeeded.txt | 18 +++++++++--------- Localization/de-DE.hjson | 5 +++++ Localization/en-US.hjson | 11 ++++++++++- Localization/es-ES.hjson | 5 +++++ Localization/fr-FR.hjson | 5 +++++ Localization/it-IT.hjson | 5 +++++ Localization/pl-PL.hjson | 5 +++++ Localization/pt-BR.hjson | 5 +++++ Localization/ru-RU.hjson | 5 +++++ Localization/zh-Hans.hjson | 11 ++++++++++- 11 files changed, 70 insertions(+), 12 deletions(-) diff --git a/Configs.cs b/Configs.cs index 9649227..0c630f7 100644 --- a/Configs.cs +++ b/Configs.cs @@ -35,7 +35,12 @@ public class BossLogConfiguration : ModConfig { [Expand(false)] [BackgroundColor(100, 70, 60)] public DebugTools Debug { get; set; } = new DebugTools(); - public class DebugTools { + public class DebugTools + { + [BackgroundColor(250, 235, 215)] + [DefaultValue(false)] + public bool EnableBossStateToggle { get; set; } + [BackgroundColor(250, 235, 215)] [DefaultValue(false)] public bool ModCallLogVerbose { get; set; } diff --git a/Localization/TranslationsNeeded.txt b/Localization/TranslationsNeeded.txt index eccb034..f5901f3 100644 --- a/Localization/TranslationsNeeded.txt +++ b/Localization/TranslationsNeeded.txt @@ -1,9 +1,9 @@ -en-US, 336/336, 100%, missing 0 -de-DE, 319/336, 95%, missing 17 -it-IT, 3/336, 1%, missing 333 -fr-FR, 316/336, 94%, missing 20 -es-ES, 79/336, 24%, missing 257 -ru-RU, 317/336, 94%, missing 19 -zh-Hans, 336/336, 100%, missing 0 -pt-BR, 64/336, 19%, missing 272 -pl-PL, 3/336, 1%, missing 333 +en-US, 338/338, 100%, missing 0 +de-DE, 319/338, 94%, missing 19 +it-IT, 3/338, 1%, missing 335 +fr-FR, 316/338, 93%, missing 22 +es-ES, 79/338, 23%, missing 259 +ru-RU, 317/338, 94%, missing 21 +zh-Hans, 336/338, 99%, missing 2 +pt-BR, 64/338, 19%, missing 274 +pl-PL, 3/338, 1%, missing 335 diff --git a/Localization/de-DE.hjson b/Localization/de-DE.hjson index 40da152..cec8e23 100644 --- a/Localization/de-DE.hjson +++ b/Localization/de-DE.hjson @@ -579,6 +579,11 @@ Mods: { Diese Nachrichten sollten erscheinen, wenn ein Boss besiegt wurde oder ein Boss despawnt ist. ''' } + + EnableBossStateToggle: { + // Label: Enable Boss State Toggle + // Tooltip: "" + } } FeatureConfiguration: { diff --git a/Localization/en-US.hjson b/Localization/en-US.hjson index 5a92da4..0cd3149 100644 --- a/Localization/en-US.hjson +++ b/Localization/en-US.hjson @@ -1,4 +1,4 @@ -Mods: { +Mods: { BossChecklist: { Log: { Common: { @@ -583,6 +583,15 @@ Mods: { These messages should appear when a boss has been defeated or a boss has despawned, respectively. ''' } + + EnableBossStateToggle: { + Label: Enable Boss defeated State Toggle + Tooltip: + ''' + While enabled,Shift + Right Click a boss in the Boss Log UI toggles its real defeated state + rather than merely marking it as defeated. + ''' + } } FeatureConfiguration: { diff --git a/Localization/es-ES.hjson b/Localization/es-ES.hjson index f1be78e..12624ce 100644 --- a/Localization/es-ES.hjson +++ b/Localization/es-ES.hjson @@ -579,6 +579,11 @@ Mods: { These messages should appear when a boss has been defeated or a boss has despawned, respectively. ''' */ } + + EnableBossStateToggle: { + // Label: Enable Boss State Toggle + // Tooltip: "" + } } FeatureConfiguration: { diff --git a/Localization/fr-FR.hjson b/Localization/fr-FR.hjson index 1bf22ee..e930ac7 100644 --- a/Localization/fr-FR.hjson +++ b/Localization/fr-FR.hjson @@ -586,6 +586,11 @@ Mods: { Ces messages devraient apparaître lorsqu'un boss a été vaincu ou lorsqu'un boss a disparu, respectivement. ''' } + + EnableBossStateToggle: { + // Label: Enable Boss State Toggle + // Tooltip: "" + } } FeatureConfiguration: { diff --git a/Localization/it-IT.hjson b/Localization/it-IT.hjson index abc7eeb..dc6adf4 100644 --- a/Localization/it-IT.hjson +++ b/Localization/it-IT.hjson @@ -583,6 +583,11 @@ Mods: { These messages should appear when a boss has been defeated or a boss has despawned, respectively. ''' */ } + + EnableBossStateToggle: { + // Label: Enable Boss State Toggle + // Tooltip: "" + } } FeatureConfiguration: { diff --git a/Localization/pl-PL.hjson b/Localization/pl-PL.hjson index abc7eeb..dc6adf4 100644 --- a/Localization/pl-PL.hjson +++ b/Localization/pl-PL.hjson @@ -583,6 +583,11 @@ Mods: { These messages should appear when a boss has been defeated or a boss has despawned, respectively. ''' */ } + + EnableBossStateToggle: { + // Label: Enable Boss State Toggle + // Tooltip: "" + } } FeatureConfiguration: { diff --git a/Localization/pt-BR.hjson b/Localization/pt-BR.hjson index a91b0af..d9d434d 100644 --- a/Localization/pt-BR.hjson +++ b/Localization/pt-BR.hjson @@ -583,6 +583,11 @@ Mods: { These messages should appear when a boss has been defeated or a boss has despawned, respectively. ''' */ } + + EnableBossStateToggle: { + // Label: Enable Boss State Toggle + // Tooltip: "" + } } FeatureConfiguration: { diff --git a/Localization/ru-RU.hjson b/Localization/ru-RU.hjson index 95af5b2..ff84021 100644 --- a/Localization/ru-RU.hjson +++ b/Localization/ru-RU.hjson @@ -582,6 +582,11 @@ Mods: { Эти сообщения должны появляться при победе над боссом или при его исчезновении, соответственно. ''' } + + EnableBossStateToggle: { + // Label: Enable Boss State Toggle + // Tooltip: "" + } } FeatureConfiguration: { diff --git a/Localization/zh-Hans.hjson b/Localization/zh-Hans.hjson index 9331703..60259c7 100644 --- a/Localization/zh-Hans.hjson +++ b/Localization/zh-Hans.hjson @@ -1,4 +1,4 @@ -Mods: { +Mods: { BossChecklist: { Log: { Common: { @@ -583,6 +583,15 @@ Mods: { 这些信息应该分别在Boss被击败或Boss消失时出现. ''' } + + EnableBossStateToggle: { + Label: 启用Boss击败状态切换功能 + Tooltip: + ''' + 启用后,如果在Boss日志UI中 Shift + 右键 Boss可以切换其真实击败状态 + 而非仅仅标记为击败 + ''' + } } FeatureConfiguration: { From 8a3d181279b92fc8c3025a8af2ae90aa0fcdbae5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=99=9E=E6=82=96=E3=80=8CYu=20Bell=E3=80=8D?= <73875008+zlzhaidou@users.noreply.github.com> Date: Mon, 10 Aug 2026 10:24:53 +0800 Subject: [PATCH 02/12] fixed the issue can mark already downed boss down --- UIElements/BossLogUIElements.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/UIElements/BossLogUIElements.cs b/UIElements/BossLogUIElements.cs index 3079d2d..92dd2d2 100644 --- a/UIElements/BossLogUIElements.cs +++ b/UIElements/BossLogUIElements.cs @@ -1298,13 +1298,14 @@ public override void RightClick(UIMouseEvent evt) { } } else { - // Entries must not already be downed to add/remove them from the MarkedEntries list + // Entries must not already be downed to add/remove them from the MarkedEntries list [YuBell: fixed this] // Entries that are downed will automatically be removed from the lsit when the TableOfContents list is generated if (BossLogSystem.MarkedEntries.Contains(entry.Key)) { BossLogSystem.MarkedEntries.Remove(entry.Key); } else { - BossLogSystem.MarkedEntries.Add(entry.Key); + if (!entry.downed()) + BossLogSystem.MarkedEntries.Add(entry.Key); } Networking.RequestMarkedEntryUpdate(entry.Key, entry.MarkedAsDowned); From cfd47dc5ca82bbb018018569bb03d95868d7e494 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=99=9E=E6=82=96=E3=80=8CYu=20Bell=E3=80=8D?= <73875008+zlzhaidou@users.noreply.github.com> Date: Mon, 10 Aug 2026 11:38:50 +0800 Subject: [PATCH 03/12] Vanilla support --- BossChecklist.cs | 5 +- BossTracker.cs | 123 ++++++++++++++++++---------- EntryInfo.cs | 13 ++- Localization/TranslationsNeeded.txt | 2 +- Localization/de-DE.hjson | 8 +- Localization/en-US.hjson | 4 +- Localization/es-ES.hjson | 8 +- Localization/fr-FR.hjson | 8 +- Localization/it-IT.hjson | 8 +- Localization/pl-PL.hjson | 8 +- Localization/pt-BR.hjson | 8 +- Localization/ru-RU.hjson | 8 +- Localization/zh-Hans.hjson | 4 +- UIElements/BossLogUIElements.cs | 33 ++++++-- 14 files changed, 167 insertions(+), 73 deletions(-) diff --git a/BossChecklist.cs b/BossChecklist.cs index 292569e..a1480d1 100644 --- a/BossChecklist.cs +++ b/BossChecklist.cs @@ -175,8 +175,9 @@ public override object Call(params object[] args) { internalName, // Internal Name Convert.ToSingle(args[3]), // Prog args[4] as Func, // Downed - InterpretObjectAsListOfInt(args[5]), // NPC IDs - args[6] as Dictionary + args[5] as Action, // SetDowned + InterpretObjectAsListOfInt(args[6]), // NPC IDs + args[7] as Dictionary ); return "Success"; } diff --git a/BossTracker.cs b/BossTracker.cs index 34caee0..d840dd2 100644 --- a/BossTracker.cs +++ b/BossTracker.cs @@ -117,102 +117,141 @@ public BossTracker() { private void InitializeVanillaEntries() { SortedEntries = new List { // Bosses -- Vanilla - EntryInfo.MakeVanillaBoss(EntryType.Boss, KingSlime, "NPCName.KingSlime", NPCID.KingSlime, () => NPC.downedSlimeKing) + EntryInfo.MakeVanillaBoss(EntryType.Boss, KingSlime, "NPCName.KingSlime", NPCID.KingSlime, () => NPC.downedSlimeKing,(@new) => {NPC.downedSlimeKing = @new; }) .WithCustomPortrait($"BossChecklist/Resources/BossTextures/Boss{NPCID.KingSlime}"), - EntryInfo.MakeVanillaBoss(EntryType.Boss, EyeOfCthulhu, "NPCName.EyeofCthulhu", NPCID.EyeofCthulhu, () => NPC.downedBoss1), - EntryInfo.MakeVanillaBoss(EntryType.Boss, EaterOfWorlds, "NPCName.EaterofWorldsHead", new List() { NPCID.EaterofWorldsHead, NPCID.EaterofWorldsBody, NPCID.EaterofWorldsTail }, () => NPC.downedBoss2) + + EntryInfo.MakeVanillaBoss(EntryType.Boss, EyeOfCthulhu, "NPCName.EyeofCthulhu", NPCID.EyeofCthulhu, () => NPC.downedBoss1,(@new) => {NPC.downedBoss1 = @new; }), + + EntryInfo.MakeVanillaBoss(EntryType.Boss, EaterOfWorlds, "NPCName.EaterofWorldsHead", new List() { NPCID.EaterofWorldsHead, NPCID.EaterofWorldsBody, NPCID.EaterofWorldsTail }, () => NPC.downedBoss2,(@new) => {NPC.downedBoss2 = @new; }) .WithCustomAvailability(() => !WorldGen.crimson || Main.drunkWorld) .WithCustomPortrait($"BossChecklist/Resources/BossTextures/Boss{NPCID.EaterofWorldsHead}"), - EntryInfo.MakeVanillaBoss(EntryType.Boss, EaterOfWorlds, "NPCName.BrainofCthulhu", NPCID.BrainofCthulhu, () => NPC.downedBoss2) + + EntryInfo.MakeVanillaBoss(EntryType.Boss, EaterOfWorlds, "NPCName.BrainofCthulhu", NPCID.BrainofCthulhu, () => NPC.downedBoss2,(@new) => {NPC.downedBoss2 = @new; }) .WithCustomAvailability(() => WorldGen.crimson || Main.drunkWorld), - EntryInfo.MakeVanillaBoss(EntryType.Boss, QueenBee, "NPCName.QueenBee", NPCID.QueenBee, () => NPC.downedQueenBee), - EntryInfo.MakeVanillaBoss(EntryType.Boss, Skeletron, "NPCName.SkeletronHead", new List() { NPCID.SkeletronHead }, () => NPC.downedBoss3) + + EntryInfo.MakeVanillaBoss(EntryType.Boss, QueenBee, "NPCName.QueenBee", NPCID.QueenBee, () => NPC.downedQueenBee,(@new) => {NPC.downedQueenBee = @new; }), + + EntryInfo.MakeVanillaBoss(EntryType.Boss, Skeletron, "NPCName.SkeletronHead", new List() { NPCID.SkeletronHead }, () => NPC.downedBoss3,(@new) => {NPC.downedBoss3 = @new; }) .WithCustomLimbs(new List() { NPCID.SkeletronHand }) .WithCustomPortrait($"BossChecklist/Resources/BossTextures/Boss{NPCID.SkeletronHead}"), - EntryInfo.MakeVanillaBoss(EntryType.Boss, DeerClops, "NPCName.Deerclops", NPCID.Deerclops, () => NPC.downedDeerclops) + + EntryInfo.MakeVanillaBoss(EntryType.Boss, DeerClops, "NPCName.Deerclops", NPCID.Deerclops, () => NPC.downedDeerclops,(@new) => {NPC.downedDeerclops = @new; }) .WithCustomPortrait($"BossChecklist/Resources/BossTextures/Boss{NPCID.Deerclops}"), - EntryInfo.MakeVanillaBoss(EntryType.Boss, WallOfFlesh, "NPCName.WallofFlesh", new List() { NPCID.WallofFlesh }, () => Main.hardMode) + + EntryInfo.MakeVanillaBoss(EntryType.Boss, WallOfFlesh, "NPCName.WallofFlesh", new List() { NPCID.WallofFlesh }, () => Main.hardMode,(@new) => {Main.hardMode = @new; }) .WithCustomPortrait($"BossChecklist/Resources/BossTextures/Boss{NPCID.WallofFlesh}"), - EntryInfo.MakeVanillaBoss(EntryType.Boss, QueenSlime, "NPCName.QueenSlimeBoss", NPCID.QueenSlimeBoss, () => NPC.downedQueenSlime) + + EntryInfo.MakeVanillaBoss(EntryType.Boss, QueenSlime, "NPCName.QueenSlimeBoss", NPCID.QueenSlimeBoss, () => NPC.downedQueenSlime, (@new) => { NPC.downedQueenSlime = @new; }) .WithCustomPortrait($"BossChecklist/Resources/BossTextures/Boss{NPCID.QueenSlimeBoss}"), - EntryInfo.MakeVanillaBoss(EntryType.Boss, TheTwins, "Enemies.TheTwins", new List() { NPCID.Retinazer, NPCID.Spazmatism }, () => NPC.downedMechBoss2) + + EntryInfo.MakeVanillaBoss(EntryType.Boss, TheTwins, "Enemies.TheTwins", new List() { NPCID.Retinazer, NPCID.Spazmatism }, () => NPC.downedMechBoss2, (@new) => { NPC.downedMechBoss2 = @new; }) .WithCustomLimbs(new List() { NPCID.Retinazer, NPCID.Spazmatism }) .WithCustomPortrait($"BossChecklist/Resources/BossTextures/Boss{NPCID.Retinazer}"), - EntryInfo.MakeVanillaBoss(EntryType.Boss, TheDestroyer, "NPCName.TheDestroyer", NPCID.TheDestroyer, () => NPC.downedMechBoss1) + + EntryInfo.MakeVanillaBoss(EntryType.Boss, TheDestroyer, "NPCName.TheDestroyer", NPCID.TheDestroyer, () => NPC.downedMechBoss1, (@new) => { NPC.downedMechBoss1 = @new; }) .WithCustomPortrait($"BossChecklist/Resources/BossTextures/Boss{NPCID.TheDestroyer}"), - EntryInfo.MakeVanillaBoss(EntryType.Boss, SkeletronPrime, "NPCName.SkeletronPrime", NPCID.SkeletronPrime, () => NPC.downedMechBoss3) + + EntryInfo.MakeVanillaBoss(EntryType.Boss, SkeletronPrime, "NPCName.SkeletronPrime", NPCID.SkeletronPrime, () => NPC.downedMechBoss3, (@new) => { NPC.downedMechBoss3 = @new; }) .WithCustomLimbs(new List() { NPCID.PrimeCannon, NPCID.PrimeSaw, NPCID.PrimeVice, NPCID.PrimeLaser }) .WithCustomPortrait($"BossChecklist/Resources/BossTextures/Boss{NPCID.SkeletronPrime}"), - EntryInfo.MakeVanillaBoss(EntryType.Boss, Plantera, "NPCName.Plantera", NPCID.Plantera, () => NPC.downedPlantBoss), - EntryInfo.MakeVanillaBoss(EntryType.Boss, Golem, "NPCName.Golem", new List() { NPCID.Golem }, () => NPC.downedGolemBoss) + + EntryInfo.MakeVanillaBoss(EntryType.Boss, Plantera, "NPCName.Plantera", NPCID.Plantera, () => NPC.downedPlantBoss, (@new) => { NPC.downedPlantBoss = @new; }), + + EntryInfo.MakeVanillaBoss(EntryType.Boss, Golem, "NPCName.Golem", new List() { NPCID.Golem }, () => NPC.downedGolemBoss, (@new) => { NPC.downedGolemBoss = @new; }) .WithCustomLimbs(new List() { NPCID.GolemFistLeft, NPCID.GolemFistRight, NPCID.GolemHead }) .WithCustomPortrait($"BossChecklist/Resources/BossTextures/Boss{NPCID.Golem}") .WithCustomHeadIcon($"Terraria/Images/NPC_Head_Boss_5"), - EntryInfo.MakeVanillaBoss(EntryType.Boss, Betsy, "NPCName.DD2Betsy", NPCID.DD2Betsy, () => DD2Event.DownedInvasionT3) + + EntryInfo.MakeVanillaBoss(EntryType.Boss, Betsy, "NPCName.DD2Betsy", NPCID.DD2Betsy, () => DD2Event.DownedInvasionT3, (@new) => { DD2Event.DownedInvasionT3 = @new; }) .WithCustomPortrait($"BossChecklist/Resources/BossTextures/Boss{NPCID.DD2Betsy}"), // No despawn message due to being in an event - EntryInfo.MakeVanillaBoss(EntryType.Boss, EmpressOfLight, "NPCName.HallowBoss", NPCID.HallowBoss, () => NPC.downedEmpressOfLight) + + EntryInfo.MakeVanillaBoss(EntryType.Boss, EmpressOfLight, "NPCName.HallowBoss", NPCID.HallowBoss, () => NPC.downedEmpressOfLight, (@new) => { NPC.downedEmpressOfLight = @new; }) .WithCustomPortrait($"BossChecklist/Resources/BossTextures/Boss{NPCID.HallowBoss}"), - EntryInfo.MakeVanillaBoss(EntryType.Boss, DukeFishron, "NPCName.DukeFishron", NPCID.DukeFishron, () => NPC.downedFishron), - EntryInfo.MakeVanillaBoss(EntryType.Boss, LunaticCultist, "NPCName.CultistBoss", NPCID.CultistBoss, () => NPC.downedAncientCultist) + + EntryInfo.MakeVanillaBoss(EntryType.Boss, DukeFishron, "NPCName.DukeFishron", NPCID.DukeFishron, () => NPC.downedFishron, (@new) => { NPC.downedFishron = @new; }), + + EntryInfo.MakeVanillaBoss(EntryType.Boss, LunaticCultist, "NPCName.CultistBoss", NPCID.CultistBoss, () => NPC.downedAncientCultist, (@new) => { NPC.downedAncientCultist = @new; }) .WithCustomPortrait($"BossChecklist/Resources/BossTextures/Boss{NPCID.CultistBoss}"), - EntryInfo.MakeVanillaBoss(EntryType.Boss, Moonlord, "Enemies.MoonLord", new List() { NPCID.MoonLordHead, NPCID.MoonLordCore }, () => NPC.downedMoonlord) + + EntryInfo.MakeVanillaBoss(EntryType.Boss, Moonlord, "Enemies.MoonLord", new List() { NPCID.MoonLordHead, NPCID.MoonLordCore }, () => NPC.downedMoonlord, (@new) => { NPC.downedMoonlord = @new; }) .WithCustomLimbs(new List() { NPCID.MoonLordHead, NPCID.MoonLordHand }) .WithCustomPortrait($"BossChecklist/Resources/BossTextures/Boss{NPCID.MoonLordHead}"), // Minibosses and Events -- Vanilla - EntryInfo.MakeVanillaEvent(TorchGod, "NPCName.TorchGod", () => Main.LocalPlayer.unlockedBiomeTorches) + EntryInfo.MakeVanillaEvent(TorchGod, "NPCName.TorchGod", () => Main.LocalPlayer.unlockedBiomeTorches,(@new) => {Main.LocalPlayer.unlockedBiomeTorches = @new; }) .WithCustomHeadIcon($"Terraria/Images/Item_{ItemID.TorchGodsFavor}"), - EntryInfo.MakeVanillaEvent(BloodMoon, "Bestiary_Events.BloodMoon", () => Systems.DownedSystem.downedBloodMoon) + + EntryInfo.MakeVanillaEvent(BloodMoon, "Bestiary_Events.BloodMoon", () => DownedSystem.downedBloodMoon, (@new) => { DownedSystem.downedBloodMoon = @new; }) .WithCustomPortrait($"BossChecklist/Resources/BossTextures/EventBloodMoon") .WithCustomHeadIcon($"BossChecklist/Resources/BossTextures/EventBloodMoon_Head"), - // EntryInfo.MakeVanillaBoss(BossChecklistType.MiniBoss,WallOfFlesh + 0.1f, "Clown", new List() { NPCID.Clown}, () => NPC.downedClown, new List() { }, $"Spawns during Hardmode Bloodmoon"), - EntryInfo.MakeVanillaEvent(GoblinArmy, "Goblin Army", () => NPC.downedGoblins) + + // EntryInfo.MakeVanillaBoss(BossChecklistType.MiniBoss,WallOfFlesh + 0.1f, "Clown", new List() { NPCID.Clown}, () => NPC.downedClown,(@new) => {NPC.downedClown = @new;} new List() { }, $"Spawns during Hardmode Bloodmoon"), + + EntryInfo.MakeVanillaEvent(GoblinArmy, "Goblin Army", () => NPC.downedGoblins,(@new) => {NPC.downedGoblins = @new; }) .WithCustomTranslationKey("LegacyInterface.88") .WithCustomPortrait($"BossChecklist/Resources/BossTextures/EventGoblinArmy") .WithCustomHeadIcon("Terraria/Images/Extra_9"), - EntryInfo.MakeVanillaEvent(OldOnesArmy, "Old One's Army", () => DD2Event.DownedInvasionAnyDifficulty) + + // TODO:Split this to three event + EntryInfo.MakeVanillaEvent(OldOnesArmy, "Old One's Army", () => DD2Event.DownedInvasionAnyDifficulty,(@new) => { Main.NewText("Old One's Army do not support changed defeat state now!"); }) .WithCustomTranslationKey("DungeonDefenders2.InvasionProgressTitle") .WithCustomPortrait($"BossChecklist/Resources/BossTextures/EventOldOnesArmy") .WithCustomHeadIcon("Terraria/Images/Extra_79"), - EntryInfo.MakeVanillaBoss(EntryType.MiniBoss, DarkMage, "NPCName.DD2DarkMageT3", new List() { NPCID.DD2DarkMageT3, NPCID.DD2DarkMageT1 }, () => Systems.DownedSystem.downedDarkMage) + + EntryInfo.MakeVanillaBoss(EntryType.MiniBoss, DarkMage, "NPCName.DD2DarkMageT3", new List() { NPCID.DD2DarkMageT3, NPCID.DD2DarkMageT1 }, () => DownedSystem.downedDarkMage,(@new) => { DownedSystem.downedDarkMage = @new; }) .WithCustomPortrait($"BossChecklist/Resources/BossTextures/Boss{NPCID.DD2DarkMageT3}"), - EntryInfo.MakeVanillaBoss(EntryType.MiniBoss, Ogre, "NPCName.DD2OgreT3", new List() { NPCID.DD2OgreT3, NPCID.DD2OgreT2 }, () => Systems.DownedSystem.downedOgre) + + EntryInfo.MakeVanillaBoss(EntryType.MiniBoss, Ogre, "NPCName.DD2OgreT3", new List() { NPCID.DD2OgreT3, NPCID.DD2OgreT2 }, () => DownedSystem.downedOgre, (@new) => { DownedSystem.downedOgre = @new; }) .WithCustomPortrait($"BossChecklist/Resources/BossTextures/Boss{NPCID.DD2OgreT3}"), - EntryInfo.MakeVanillaEvent(FrostLegion, "Frost Legion", () => NPC.downedFrost) + + EntryInfo.MakeVanillaEvent(FrostLegion, "Frost Legion", () => NPC.downedFrost,(@new) => { NPC.downedFrost = @new; }) .WithCustomTranslationKey("LegacyInterface.87") .WithCustomAvailability(() => Main.xMas) .WithCustomPortrait($"BossChecklist/Resources/BossTextures/EventFrostLegion") .WithCustomHeadIcon("Terraria/Images/Extra_7"), - EntryInfo.MakeVanillaEvent(PirateInvasion, "Pirate Invasion", () => NPC.downedPirates) + + EntryInfo.MakeVanillaEvent(PirateInvasion, "Pirate Invasion", () => NPC.downedPirates, (@new) => { NPC.downedPirates = @new; }) .WithCustomTranslationKey("LegacyInterface.86") .WithCustomPortrait($"BossChecklist/Resources/BossTextures/EventPirateInvasion") .WithCustomHeadIcon("Terraria/Images/Extra_11"), - EntryInfo.MakeVanillaBoss(EntryType.MiniBoss, PirateShip, "NPCName.PirateShip", new List() { NPCID.PirateShip }, () => Systems.DownedSystem.downedFlyingDutchman) + + EntryInfo.MakeVanillaBoss(EntryType.MiniBoss, PirateShip, "NPCName.PirateShip", new List() { NPCID.PirateShip }, () => DownedSystem.downedFlyingDutchman, (@new) => { DownedSystem.downedFlyingDutchman = @new; }) .WithCustomPortrait($"BossChecklist/Resources/BossTextures/Boss{NPCID.PirateShip}"), - EntryInfo.MakeVanillaEvent(SolarEclipse, "Bestiary_Events.Eclipse", () => Systems.DownedSystem.downedSolarEclipse) + + EntryInfo.MakeVanillaEvent(SolarEclipse, "Bestiary_Events.Eclipse", () => DownedSystem.downedSolarEclipse, (@new) => { DownedSystem.downedSolarEclipse = @new; }) .WithCustomPortrait($"BossChecklist/Resources/BossTextures/EventSolarEclipse") .WithCustomHeadIcon($"BossChecklist/Resources/BossTextures/EventSolarEclipse_Head"), - EntryInfo.MakeVanillaEvent(PumpkinMoon, "Pumpkin Moon", () => Systems.DownedSystem.downedPumpkinMoon) + + EntryInfo.MakeVanillaEvent(PumpkinMoon, "Pumpkin Moon", () => DownedSystem.downedPumpkinMoon, (@new) => { DownedSystem.downedPumpkinMoon = @new; }) .WithCustomTranslationKey("LegacyInterface.84") .WithCustomPortrait($"BossChecklist/Resources/BossTextures/EventPumpkinMoon") .WithCustomHeadIcon($"Terraria/Images/Extra_12"), - EntryInfo.MakeVanillaBoss(EntryType.MiniBoss, MourningWood, "NPCName.MourningWood", new List() { NPCID.MourningWood }, () => NPC.downedHalloweenTree), - EntryInfo.MakeVanillaBoss(EntryType.MiniBoss, Pumpking, "NPCName.Pumpking", new List() { NPCID.Pumpking }, () => NPC.downedHalloweenKing) + + EntryInfo.MakeVanillaBoss(EntryType.MiniBoss, MourningWood, "NPCName.MourningWood", new List() { NPCID.MourningWood }, () => NPC.downedHalloweenTree, (@new) => { NPC.downedHalloweenTree = @new; }), + + EntryInfo.MakeVanillaBoss(EntryType.MiniBoss, Pumpking, "NPCName.Pumpking", new List() { NPCID.Pumpking }, () => NPC.downedHalloweenKing, (@new) => { NPC.downedHalloweenKing = @new; }) .WithCustomPortrait($"BossChecklist/Resources/BossTextures/Boss{NPCID.Pumpking}"), - EntryInfo.MakeVanillaEvent(FrostMoon, "Frost Moon", () => Systems.DownedSystem.downedFrostMoon) + + EntryInfo.MakeVanillaEvent(FrostMoon, "Frost Moon", () => DownedSystem.downedFrostMoon, (@new) => { DownedSystem.downedFrostMoon = @new; }) .WithCustomTranslationKey("LegacyInterface.83") .WithCustomPortrait($"BossChecklist/Resources/BossTextures/EventFrostMoon") .WithCustomHeadIcon($"Terraria/Images/Extra_8"), - EntryInfo.MakeVanillaBoss(EntryType.MiniBoss, Everscream, "NPCName.Everscream", new List() { NPCID.Everscream }, () => NPC.downedChristmasTree), - EntryInfo.MakeVanillaBoss(EntryType.MiniBoss, SantaNK1, "NPCName.SantaNK1", new List() { NPCID.SantaNK1 }, () => NPC.downedChristmasSantank), - EntryInfo.MakeVanillaBoss(EntryType.MiniBoss, IceQueen, "NPCName.IceQueen", new List() { NPCID.IceQueen }, () => NPC.downedChristmasIceQueen), - EntryInfo.MakeVanillaEvent(MartianMadness, "Martian Madness", () => NPC.downedMartians) + + EntryInfo.MakeVanillaBoss(EntryType.MiniBoss, Everscream, "NPCName.Everscream", new List() { NPCID.Everscream }, () => NPC.downedChristmasTree, (@new) => { NPC.downedChristmasTree = @new; }), + + EntryInfo.MakeVanillaBoss(EntryType.MiniBoss, SantaNK1, "NPCName.SantaNK1", new List() { NPCID.SantaNK1 }, () => NPC.downedChristmasSantank, (@new) => { NPC.downedChristmasSantank = @new; }), + + EntryInfo.MakeVanillaBoss(EntryType.MiniBoss, IceQueen, "NPCName.IceQueen", new List() { NPCID.IceQueen }, () => NPC.downedChristmasIceQueen, (@new) => { NPC.downedChristmasIceQueen = @new; }), + + EntryInfo.MakeVanillaEvent(MartianMadness, "Martian Madness", () => NPC.downedMartians, (@new) => { NPC.downedMartians = @new; }) .WithCustomTranslationKey("LegacyInterface.85") .WithCustomPortrait($"BossChecklist/Resources/BossTextures/EventMartianMadness") .WithCustomHeadIcon($"Terraria/Images/Extra_10"), - EntryInfo.MakeVanillaBoss(EntryType.MiniBoss, MartianSaucer, "NPCName.MartianSaucer", new List() { NPCID.MartianSaucer, NPCID.MartianSaucerCore }, () => Systems.DownedSystem.downedMartianSaucer), - EntryInfo.MakeVanillaEvent(LunarEvent, "Lunar Event", () => NPC.downedTowers) + + EntryInfo.MakeVanillaBoss(EntryType.MiniBoss, MartianSaucer, "NPCName.MartianSaucer", new List() { NPCID.MartianSaucer, NPCID.MartianSaucerCore }, () => DownedSystem.downedMartianSaucer, (@new) => { DownedSystem.downedMartianSaucer = @new; }), + + EntryInfo.MakeVanillaEvent(LunarEvent, "Lunar Event", () => NPC.downedTowers,(@new) => { NPC.downedTowerSolar = @new; NPC.downedTowerNebula = @new;NPC.downedTowerVortex = @new; NPC.downedTowerStardust = @new; }) .WithCustomTranslationKey("Mods.BossChecklist.Checklist.CelestialPillars") .WithCustomLimbs(new List() { NPCID.LunarTowerVortex, NPCID.LunarTowerStardust, NPCID.LunarTowerNebula, NPCID.LunarTowerSolar }) .WithCustomPortrait($"BossChecklist/Resources/BossTextures/EventLunarEvent") @@ -1096,9 +1135,9 @@ internal static bool[] GetBelongsToInvasionSet(string Key) { ItemID.MusicBoxOWHallow, }; - internal void AddEntry(EntryType type, Mod mod, string iName, float val, Func down, List id, Dictionary extra = null) { + internal void AddEntry(EntryType type, Mod mod, string iName, float val, Func down,Action setDowned, List id, Dictionary extra = null) { EnsureBossIsNotDuplicate(mod?.Name ?? "Unknown", iName); - SortedEntries.Add(new EntryInfo(type, mod?.Name ?? "Unknown", iName, out string key, val, down, id, extra)); + SortedEntries.Add(new EntryInfo(type, mod?.Name ?? "Unknown", iName, out string key, val, down,setDowned, id, extra)); LogNewBoss(mod?.DisplayName ?? "Unknown", iName, key); } diff --git a/EntryInfo.cs b/EntryInfo.cs index 8784488..42584c4 100644 --- a/EntryInfo.cs +++ b/EntryInfo.cs @@ -42,6 +42,7 @@ internal class EntryInfo { internal Dictionary npcLimbs; internal float progression; internal Func downed; + internal Action setDowned; internal Func available; internal bool hidden; internal Func customDespawnMessages; @@ -210,7 +211,7 @@ internal bool VisibleOnPageContent() { return VisibleOnChecklist(); } - internal EntryInfo(EntryType entryType, string modSource, string internalName, out string KeyOutput, float progression, Func downed, List npcIDs, Dictionary extraData = null) { + internal EntryInfo(EntryType entryType, string modSource, string internalName, out string KeyOutput, float progression, Func downed,Action setDowned, List npcIDs, Dictionary extraData = null) { // Add the mod source to the opted mods list of the credits page if its not already and add the entry type if (modSource != "Terraria" && modSource != "Unknown") { BossChecklist.bossTracker.RegisteredMods.TryAdd(modSource, new int[3]); @@ -224,6 +225,7 @@ internal EntryInfo(EntryType entryType, string modSource, string internalName, o this.progression = progression; this.downed = downed ?? throw new ArgumentNullException(nameof(downed), BossChecklist.instance.GetLocalization("LogMessage.DownedIsNull").Format(this.Key)); this.npcIDs = npcIDs ?? new List(); + this.setDowned = setDowned; // Localization checks LocalizedText name = extraData?.ContainsKey("displayName") == true ? extraData["displayName"] as LocalizedText : null; @@ -381,7 +383,7 @@ internal EntryInfo WithCustomHeadIcon(List texturePaths) { return this; } - internal static EntryInfo MakeVanillaBoss(EntryType type, float val, string key, int npcID, Func downed) { + internal static EntryInfo MakeVanillaBoss(EntryType type, float val, string key, int npcID, Func downed,Action setDowned) { string nameKey = key.Substring(key.LastIndexOf(".") + 1); // BossChecklist only has despawn messages for vanilla Bosses @@ -415,6 +417,7 @@ internal static EntryInfo MakeVanillaBoss(EntryType type, float val, string key, out string generatedKey, progression: val, downed: downed, + setDowned: setDowned, npcIDs: new List() { npcID }, extraData: new Dictionary() { { "displayName", Language.GetText(key) }, @@ -426,7 +429,7 @@ internal static EntryInfo MakeVanillaBoss(EntryType type, float val, string key, ); } - internal static EntryInfo MakeVanillaBoss(EntryType type, float val, string key, List ids, Func downed) { + internal static EntryInfo MakeVanillaBoss(EntryType type, float val, string key, List ids, Func downed, Action setDowned) { string nameKey = key.Substring(key.LastIndexOf(".") + 1).Replace(" ", "").Replace("'", ""); if (nameKey.EndsWith("Head")) nameKey = nameKey.Substring(0, nameKey.Length - 4); @@ -460,6 +463,7 @@ internal static EntryInfo MakeVanillaBoss(EntryType type, float val, string key, out string generatedKey, progression: val, downed: downed, + setDowned: setDowned, npcIDs: ids, extraData: new Dictionary() { { "displayName", Language.GetText(key) }, @@ -471,7 +475,7 @@ internal static EntryInfo MakeVanillaBoss(EntryType type, float val, string key, ); } - internal static EntryInfo MakeVanillaEvent(float val, string key, Func downed) { + internal static EntryInfo MakeVanillaEvent(float val, string key, Func downed, Action setDowned) { string nameKey = key.Substring(key.LastIndexOf(".") + 1).Replace(" ", "").Replace("'", ""); return new EntryInfo( entryType: EntryType.Event, @@ -480,6 +484,7 @@ internal static EntryInfo MakeVanillaEvent(float val, string key, Func dow out string generatedKey, progression: val, downed: downed, + setDowned:setDowned, npcIDs: BossTracker.EventNPCs.GetValueOrDefault($"Terraria {nameKey}"), extraData: new Dictionary() { { "displayName", Language.GetText(key) }, diff --git a/Localization/TranslationsNeeded.txt b/Localization/TranslationsNeeded.txt index f5901f3..b55b997 100644 --- a/Localization/TranslationsNeeded.txt +++ b/Localization/TranslationsNeeded.txt @@ -4,6 +4,6 @@ it-IT, 3/338, 1%, missing 335 fr-FR, 316/338, 93%, missing 22 es-ES, 79/338, 23%, missing 259 ru-RU, 317/338, 94%, missing 21 -zh-Hans, 336/338, 99%, missing 2 +zh-Hans, 338/338, 100%, missing 0 pt-BR, 64/338, 19%, missing 274 pl-PL, 3/338, 1%, missing 335 diff --git a/Localization/de-DE.hjson b/Localization/de-DE.hjson index cec8e23..aeed1ac 100644 --- a/Localization/de-DE.hjson +++ b/Localization/de-DE.hjson @@ -581,8 +581,12 @@ Mods: { } EnableBossStateToggle: { - // Label: Enable Boss State Toggle - // Tooltip: "" + // Label: Enable Boss defeated State Toggle + /* Tooltip: + ''' + While enabled,Shift + Right Click a boss in the Boss Log UI toggles its real defeated state + rather than merely marking it as defeated. + ''' */ } } diff --git a/Localization/en-US.hjson b/Localization/en-US.hjson index 0cd3149..bedf641 100644 --- a/Localization/en-US.hjson +++ b/Localization/en-US.hjson @@ -1,4 +1,4 @@ -Mods: { +Mods: { BossChecklist: { Log: { Common: { @@ -586,7 +586,7 @@ EnableBossStateToggle: { Label: Enable Boss defeated State Toggle - Tooltip: + Tooltip: ''' While enabled,Shift + Right Click a boss in the Boss Log UI toggles its real defeated state rather than merely marking it as defeated. diff --git a/Localization/es-ES.hjson b/Localization/es-ES.hjson index 12624ce..4cd66c3 100644 --- a/Localization/es-ES.hjson +++ b/Localization/es-ES.hjson @@ -581,8 +581,12 @@ Mods: { } EnableBossStateToggle: { - // Label: Enable Boss State Toggle - // Tooltip: "" + // Label: Enable Boss defeated State Toggle + /* Tooltip: + ''' + While enabled,Shift + Right Click a boss in the Boss Log UI toggles its real defeated state + rather than merely marking it as defeated. + ''' */ } } diff --git a/Localization/fr-FR.hjson b/Localization/fr-FR.hjson index e930ac7..d567bef 100644 --- a/Localization/fr-FR.hjson +++ b/Localization/fr-FR.hjson @@ -588,8 +588,12 @@ Mods: { } EnableBossStateToggle: { - // Label: Enable Boss State Toggle - // Tooltip: "" + // Label: Enable Boss defeated State Toggle + /* Tooltip: + ''' + While enabled,Shift + Right Click a boss in the Boss Log UI toggles its real defeated state + rather than merely marking it as defeated. + ''' */ } } diff --git a/Localization/it-IT.hjson b/Localization/it-IT.hjson index dc6adf4..79da791 100644 --- a/Localization/it-IT.hjson +++ b/Localization/it-IT.hjson @@ -585,8 +585,12 @@ Mods: { } EnableBossStateToggle: { - // Label: Enable Boss State Toggle - // Tooltip: "" + // Label: Enable Boss defeated State Toggle + /* Tooltip: + ''' + While enabled,Shift + Right Click a boss in the Boss Log UI toggles its real defeated state + rather than merely marking it as defeated. + ''' */ } } diff --git a/Localization/pl-PL.hjson b/Localization/pl-PL.hjson index dc6adf4..79da791 100644 --- a/Localization/pl-PL.hjson +++ b/Localization/pl-PL.hjson @@ -585,8 +585,12 @@ Mods: { } EnableBossStateToggle: { - // Label: Enable Boss State Toggle - // Tooltip: "" + // Label: Enable Boss defeated State Toggle + /* Tooltip: + ''' + While enabled,Shift + Right Click a boss in the Boss Log UI toggles its real defeated state + rather than merely marking it as defeated. + ''' */ } } diff --git a/Localization/pt-BR.hjson b/Localization/pt-BR.hjson index d9d434d..a7b9562 100644 --- a/Localization/pt-BR.hjson +++ b/Localization/pt-BR.hjson @@ -585,8 +585,12 @@ Mods: { } EnableBossStateToggle: { - // Label: Enable Boss State Toggle - // Tooltip: "" + // Label: Enable Boss defeated State Toggle + /* Tooltip: + ''' + While enabled,Shift + Right Click a boss in the Boss Log UI toggles its real defeated state + rather than merely marking it as defeated. + ''' */ } } diff --git a/Localization/ru-RU.hjson b/Localization/ru-RU.hjson index ff84021..6d7ec26 100644 --- a/Localization/ru-RU.hjson +++ b/Localization/ru-RU.hjson @@ -584,8 +584,12 @@ Mods: { } EnableBossStateToggle: { - // Label: Enable Boss State Toggle - // Tooltip: "" + // Label: Enable Boss defeated State Toggle + /* Tooltip: + ''' + While enabled,Shift + Right Click a boss in the Boss Log UI toggles its real defeated state + rather than merely marking it as defeated. + ''' */ } } diff --git a/Localization/zh-Hans.hjson b/Localization/zh-Hans.hjson index 60259c7..e38cdb1 100644 --- a/Localization/zh-Hans.hjson +++ b/Localization/zh-Hans.hjson @@ -1,4 +1,4 @@ -Mods: { +Mods: { BossChecklist: { Log: { Common: { @@ -586,7 +586,7 @@ EnableBossStateToggle: { Label: 启用Boss击败状态切换功能 - Tooltip: + Tooltip: ''' 启用后,如果在Boss日志UI中 Shift + 右键 Boss可以切换其真实击败状态 而非仅仅标记为击败 diff --git a/UIElements/BossLogUIElements.cs b/UIElements/BossLogUIElements.cs index 92dd2d2..2b5c5c0 100644 --- a/UIElements/BossLogUIElements.cs +++ b/UIElements/BossLogUIElements.cs @@ -1298,14 +1298,35 @@ public override void RightClick(UIMouseEvent evt) { } } else { - // Entries must not already be downed to add/remove them from the MarkedEntries list [YuBell: fixed this] - // Entries that are downed will automatically be removed from the lsit when the TableOfContents list is generated - if (BossLogSystem.MarkedEntries.Contains(entry.Key)) { - BossLogSystem.MarkedEntries.Remove(entry.Key); + + bool shiftHeld = + Main.keyState.IsKeyDown(Microsoft.Xna.Framework.Input.Keys.LeftShift) + || + Main.keyState.IsKeyDown(Microsoft.Xna.Framework.Input.Keys.RightShift); + + if (shiftHeld && BossChecklist.BossLogConfig.Debug.EnableBossStateToggle) { + // call the method that to set the downed value provided by source mods + // vanilla boss will call the build in delegate + entry.setDowned(entry.downed() ? false : true); + + // if mark as defeated,when toggled,it shouldn't be mark as defeat + // if not mark as defeat,when toggled,it shouldn't be mark down by the codes above + if (BossLogSystem.MarkedEntries.Contains(entry.Key)) { + BossLogSystem.MarkedEntries.Remove(entry.Key); + } + + Main.NewText("Works Good!"); } else { - if (!entry.downed()) - BossLogSystem.MarkedEntries.Add(entry.Key); + // Entries must not already be downed to add/remove them from the MarkedEntries list [YuBell: fixed this] + // Entries that are downed will automatically be removed from the lsit when the TableOfContents list is generated + if (BossLogSystem.MarkedEntries.Contains(entry.Key)) { + BossLogSystem.MarkedEntries.Remove(entry.Key); + } + else { + if (!entry.downed()) // if this boss is already downed,it shouldn't be mark as downed + BossLogSystem.MarkedEntries.Add(entry.Key); + } } Networking.RequestMarkedEntryUpdate(entry.Key, entry.MarkedAsDowned); From dc933ea8051216f42ae56e04fd965fe092197bb0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=99=9E=E6=82=96=E3=80=8CYu=20Bell=E3=80=8D?= <73875008+zlzhaidou@users.noreply.github.com> Date: Mon, 10 Aug 2026 18:02:39 +0800 Subject: [PATCH 04/12] multiplayer sync stuffs --- BossChecklist.cs | 36 +++++++++++++++++++++++++++++++++ BossTracker.cs | 8 ++++++-- Localization/en-US.hjson | 5 +++++ Localization/zh-Hans.hjson | 5 +++++ Networking.cs | 34 ++++++++++++++++++++++++++++++- UIElements/BossLogUIElements.cs | 12 +++-------- 6 files changed, 88 insertions(+), 12 deletions(-) diff --git a/BossChecklist.cs b/BossChecklist.cs index a1480d1..163330e 100644 --- a/BossChecklist.cs +++ b/BossChecklist.cs @@ -1,10 +1,12 @@ using BossChecklist.Systems; +using Microsoft.Xna.Framework; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Reflection; using Terraria; +using Terraria.Chat; using Terraria.ID; using Terraria.Localization; using Terraria.ModLoader; @@ -175,6 +177,7 @@ public override object Call(params object[] args) { internalName, // Internal Name Convert.ToSingle(args[3]), // Prog args[4] as Func, // Downed + // WARN: ADAPT MULTIPLAYER args[5] as Action, // SetDowned InterpretObjectAsListOfInt(args[6]), // NPC IDs args[7] as Dictionary @@ -447,6 +450,39 @@ public override void HandlePacket(BinaryReader reader, int whoAmI) { recordIndex = reader.ReadInt32(); Main.LocalPlayer.GetModPlayer().RecordsForWorld?[recordIndex].StartTracking(); break; + case PacketMessageType.RequestBossStateToggle: + if (Main.netMode == NetmodeID.Server) { + string bossKey1 = reader.ReadString(); + bool downed1 = reader.ReadBoolean(); + + if (!Networking.TryApplyBossStateToggle(bossKey1, downed1)) { + ChatHelper.BroadcastChatMessage(NetworkText.FromKey(""), Color.Red); + break; + } + + NetMessage.SendData(MessageID.WorldData); + + // show text let other player know which boss's defeat state toggled + ChatHelper.BroadcastChatMessage(NetworkText.FromKey("Mods.BossChecklist.Configs.DebugTools.Successed",), Color.LightGreen); + + // in case some mod's data can not be sent + ModPacket packet1 = GetPacket(); + packet1.Write((byte)PacketMessageType.SyncBossState); + packet1.Write(bossKey1); + packet1.Write(downed1); + packet1.Send(); // Server --> All Clients + } + break; + + case PacketMessageType.SyncBossState: + if (Main.netMode == NetmodeID.MultiplayerClient) { + string bossKey2 = reader.ReadString(); + bool downed2 = reader.ReadBoolean(); + + if (Networking.TryApplyBossStateToggle(bossKey2, downed2)) + BossLogSystem.Instance?.BossLog?.RefreshPageContent(); + } + break; default: Logger.Error($"Unknown Message type: {msgType}"); break; diff --git a/BossTracker.cs b/BossTracker.cs index d840dd2..9dd4d38 100644 --- a/BossTracker.cs +++ b/BossTracker.cs @@ -117,7 +117,7 @@ public BossTracker() { private void InitializeVanillaEntries() { SortedEntries = new List { // Bosses -- Vanilla - EntryInfo.MakeVanillaBoss(EntryType.Boss, KingSlime, "NPCName.KingSlime", NPCID.KingSlime, () => NPC.downedSlimeKing,(@new) => {NPC.downedSlimeKing = @new; }) + EntryInfo.MakeVanillaBoss(EntryType.Boss, KingSlime, "NPCName.KingSlime", NPCID.KingSlime, () => NPC.downedSlimeKing,(@new) => {NPC.downedSlimeKing = @new;}) .WithCustomPortrait($"BossChecklist/Resources/BossTextures/Boss{NPCID.KingSlime}"), EntryInfo.MakeVanillaBoss(EntryType.Boss, EyeOfCthulhu, "NPCName.EyeofCthulhu", NPCID.EyeofCthulhu, () => NPC.downedBoss1,(@new) => {NPC.downedBoss1 = @new; }), @@ -179,7 +179,11 @@ private void InitializeVanillaEntries() { .WithCustomPortrait($"BossChecklist/Resources/BossTextures/Boss{NPCID.MoonLordHead}"), // Minibosses and Events -- Vanilla - EntryInfo.MakeVanillaEvent(TorchGod, "NPCName.TorchGod", () => Main.LocalPlayer.unlockedBiomeTorches,(@new) => {Main.LocalPlayer.unlockedBiomeTorches = @new; }) + EntryInfo.MakeVanillaEvent(TorchGod, "NPCName.TorchGod", () => Main.LocalPlayer.unlockedBiomeTorches,(@new) => + { + foreach (Player p in Main.player) + p.unlockedBiomeTorches = @new; + }) .WithCustomHeadIcon($"Terraria/Images/Item_{ItemID.TorchGodsFavor}"), EntryInfo.MakeVanillaEvent(BloodMoon, "Bestiary_Events.BloodMoon", () => DownedSystem.downedBloodMoon, (@new) => { DownedSystem.downedBloodMoon = @new; }) diff --git a/Localization/en-US.hjson b/Localization/en-US.hjson index bedf641..b05bea4 100644 --- a/Localization/en-US.hjson +++ b/Localization/en-US.hjson @@ -592,6 +592,11 @@ Mods: { rather than merely marking it as defeated. ''' } + + Failed: Failed to toggle defeat state of [{0}]! + Successed: Toggled [{0}] -> [{1}] ! + Defeated: Defeated + Alive: Alive } FeatureConfiguration: { diff --git a/Localization/zh-Hans.hjson b/Localization/zh-Hans.hjson index e38cdb1..f905028 100644 --- a/Localization/zh-Hans.hjson +++ b/Localization/zh-Hans.hjson @@ -592,6 +592,11 @@ Mods: { 而非仅仅标记为击败 ''' } + + Failed: 右键切换失败:无法定位 [{0}] 的真实击败状态 + Successed: 右键切换成功:[{0}] -> [{1}] + Defeated: 已击败 + Alive: 未击败 } FeatureConfiguration: { diff --git a/Networking.cs b/Networking.cs index 6bd7a0a..9cd9dfb 100644 --- a/Networking.cs +++ b/Networking.cs @@ -18,7 +18,9 @@ enum PacketMessageType : byte { SendWorldRecordsFromServerToPlayer, UpdateWorldRecordsToAllPlayers, ResetPlayerRecordForServer, - ResetTrackers + ResetTrackers, + RequestBossStateToggle, // Client --> Server + SyncBossState, // Server --> All Clients } internal enum ClientMessageType : byte { @@ -65,5 +67,35 @@ public static void RequestMarkedEntryUpdate(string Key = null, bool mark = true) } packet.Send(); // Multiplayer --> Server } + + + internal static bool TryApplyBossStateToggle(string bossKey, bool downed) { + + EntryInfo entry = BossChecklist.bossTracker.FindEntryFromKey(bossKey); + + if (entry is null || entry.setDowned is null) + return false; + + entry.setDowned(downed); + BossLogSystem.MarkedEntries.Remove(bossKey); + + return true; // if true means toggle success + } + + public static void RequestBossStateToggle(string bossKey, bool downed) { + if (Main.netMode == NetmodeID.SinglePlayer) { + TryApplyBossStateToggle(bossKey, downed); + return; + } + + if (Main.netMode != NetmodeID.MultiplayerClient) + return; + + ModPacket packet = BossChecklist.instance.GetPacket(); + packet.Write((byte)PacketMessageType.RequestBossStateToggle); + packet.Write(bossKey); + packet.Write(downed); + packet.Send(); + } } } diff --git a/UIElements/BossLogUIElements.cs b/UIElements/BossLogUIElements.cs index 2b5c5c0..4fd0045 100644 --- a/UIElements/BossLogUIElements.cs +++ b/UIElements/BossLogUIElements.cs @@ -1305,16 +1305,10 @@ public override void RightClick(UIMouseEvent evt) { Main.keyState.IsKeyDown(Microsoft.Xna.Framework.Input.Keys.RightShift); if (shiftHeld && BossChecklist.BossLogConfig.Debug.EnableBossStateToggle) { - // call the method that to set the downed value provided by source mods - // vanilla boss will call the build in delegate - entry.setDowned(entry.downed() ? false : true); - - // if mark as defeated,when toggled,it shouldn't be mark as defeat - // if not mark as defeat,when toggled,it shouldn't be mark down by the codes above - if (BossLogSystem.MarkedEntries.Contains(entry.Key)) { - BossLogSystem.MarkedEntries.Remove(entry.Key); - } + bool newState = !entry.downed(); + Networking.RequestBossStateToggle(entry.Key, newState); + Main.NewText("Works Good!"); } else { From 23ac1be5cb3cd2c5dafc85d113a538a8e62141b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=99=9E=E6=82=96=E3=80=8CYu=20Bell=E3=80=8D?= <73875008+zlzhaidou@users.noreply.github.com> Date: Mon, 10 Aug 2026 18:29:04 +0800 Subject: [PATCH 05/12] multiplayer sync stuffs --- BossChecklist.cs | 19 ++++++++++++++++--- Localization/TranslationsNeeded.txt | 18 +++++++++--------- Localization/de-DE.hjson | 5 +++++ Localization/es-ES.hjson | 5 +++++ Localization/fr-FR.hjson | 5 +++++ Localization/it-IT.hjson | 5 +++++ Localization/pl-PL.hjson | 5 +++++ Localization/pt-BR.hjson | 5 +++++ Localization/ru-RU.hjson | 5 +++++ Localization/zh-Hans.hjson | 4 ++-- UIElements/BossLogUIElements.cs | 2 -- 11 files changed, 62 insertions(+), 16 deletions(-) diff --git a/BossChecklist.cs b/BossChecklist.cs index 163330e..a1c74dd 100644 --- a/BossChecklist.cs +++ b/BossChecklist.cs @@ -454,16 +454,29 @@ public override void HandlePacket(BinaryReader reader, int whoAmI) { if (Main.netMode == NetmodeID.Server) { string bossKey1 = reader.ReadString(); bool downed1 = reader.ReadBoolean(); + EntryInfo entry = BossChecklist.bossTracker.FindEntryFromKey(bossKey1); if (!Networking.TryApplyBossStateToggle(bossKey1, downed1)) { - ChatHelper.BroadcastChatMessage(NetworkText.FromKey(""), Color.Red); + ChatHelper.BroadcastChatMessage( + instance.GetLocalization("Configs.DebugTools.Failed").ToNetworkText(bossKey1), + Color.Red + ); break; } NetMessage.SendData(MessageID.WorldData); - // show text let other player know which boss's defeat state toggled - ChatHelper.BroadcastChatMessage(NetworkText.FromKey("Mods.BossChecklist.Configs.DebugTools.Successed",), Color.LightGreen); + // show text to let other player know which boss's defeat state toggled + ChatHelper.BroadcastChatMessage( + instance.GetLocalization("Configs.DebugTools.Successed") + .ToNetworkText( + entry.name, + downed1 + ? instance.GetLocalization("Configs.DebugTools.Defeated") + : instance.GetLocalization("Configs.DebugTools.Alive") + ), + Color.LightGreen + ); // in case some mod's data can not be sent ModPacket packet1 = GetPacket(); diff --git a/Localization/TranslationsNeeded.txt b/Localization/TranslationsNeeded.txt index b55b997..36cea07 100644 --- a/Localization/TranslationsNeeded.txt +++ b/Localization/TranslationsNeeded.txt @@ -1,9 +1,9 @@ -en-US, 338/338, 100%, missing 0 -de-DE, 319/338, 94%, missing 19 -it-IT, 3/338, 1%, missing 335 -fr-FR, 316/338, 93%, missing 22 -es-ES, 79/338, 23%, missing 259 -ru-RU, 317/338, 94%, missing 21 -zh-Hans, 338/338, 100%, missing 0 -pt-BR, 64/338, 19%, missing 274 -pl-PL, 3/338, 1%, missing 335 +en-US, 342/342, 100%, missing 0 +de-DE, 319/342, 93%, missing 23 +it-IT, 3/342, 1%, missing 339 +fr-FR, 316/342, 92%, missing 26 +es-ES, 79/342, 23%, missing 263 +ru-RU, 317/342, 93%, missing 25 +zh-Hans, 342/342, 100%, missing 0 +pt-BR, 64/342, 19%, missing 278 +pl-PL, 3/342, 1%, missing 339 diff --git a/Localization/de-DE.hjson b/Localization/de-DE.hjson index aeed1ac..2aad6f7 100644 --- a/Localization/de-DE.hjson +++ b/Localization/de-DE.hjson @@ -588,6 +588,11 @@ Mods: { rather than merely marking it as defeated. ''' */ } + + // Failed: Failed to toggle defeat state of [{0}]! + // Successed: Toggled [{0}] -> [{1}] ! + // Defeated: Defeated + // Alive: Alive } FeatureConfiguration: { diff --git a/Localization/es-ES.hjson b/Localization/es-ES.hjson index 4cd66c3..4583694 100644 --- a/Localization/es-ES.hjson +++ b/Localization/es-ES.hjson @@ -588,6 +588,11 @@ Mods: { rather than merely marking it as defeated. ''' */ } + + // Failed: Failed to toggle defeat state of [{0}]! + // Successed: Toggled [{0}] -> [{1}] ! + // Defeated: Defeated + // Alive: Alive } FeatureConfiguration: { diff --git a/Localization/fr-FR.hjson b/Localization/fr-FR.hjson index d567bef..a5291ba 100644 --- a/Localization/fr-FR.hjson +++ b/Localization/fr-FR.hjson @@ -595,6 +595,11 @@ Mods: { rather than merely marking it as defeated. ''' */ } + + // Failed: Failed to toggle defeat state of [{0}]! + // Successed: Toggled [{0}] -> [{1}] ! + // Defeated: Defeated + // Alive: Alive } FeatureConfiguration: { diff --git a/Localization/it-IT.hjson b/Localization/it-IT.hjson index 79da791..feb17bf 100644 --- a/Localization/it-IT.hjson +++ b/Localization/it-IT.hjson @@ -592,6 +592,11 @@ Mods: { rather than merely marking it as defeated. ''' */ } + + // Failed: Failed to toggle defeat state of [{0}]! + // Successed: Toggled [{0}] -> [{1}] ! + // Defeated: Defeated + // Alive: Alive } FeatureConfiguration: { diff --git a/Localization/pl-PL.hjson b/Localization/pl-PL.hjson index 79da791..feb17bf 100644 --- a/Localization/pl-PL.hjson +++ b/Localization/pl-PL.hjson @@ -592,6 +592,11 @@ Mods: { rather than merely marking it as defeated. ''' */ } + + // Failed: Failed to toggle defeat state of [{0}]! + // Successed: Toggled [{0}] -> [{1}] ! + // Defeated: Defeated + // Alive: Alive } FeatureConfiguration: { diff --git a/Localization/pt-BR.hjson b/Localization/pt-BR.hjson index a7b9562..dfa5f16 100644 --- a/Localization/pt-BR.hjson +++ b/Localization/pt-BR.hjson @@ -592,6 +592,11 @@ Mods: { rather than merely marking it as defeated. ''' */ } + + // Failed: Failed to toggle defeat state of [{0}]! + // Successed: Toggled [{0}] -> [{1}] ! + // Defeated: Defeated + // Alive: Alive } FeatureConfiguration: { diff --git a/Localization/ru-RU.hjson b/Localization/ru-RU.hjson index 6d7ec26..b083889 100644 --- a/Localization/ru-RU.hjson +++ b/Localization/ru-RU.hjson @@ -591,6 +591,11 @@ Mods: { rather than merely marking it as defeated. ''' */ } + + // Failed: Failed to toggle defeat state of [{0}]! + // Successed: Toggled [{0}] -> [{1}] ! + // Defeated: Defeated + // Alive: Alive } FeatureConfiguration: { diff --git a/Localization/zh-Hans.hjson b/Localization/zh-Hans.hjson index f905028..29c6310 100644 --- a/Localization/zh-Hans.hjson +++ b/Localization/zh-Hans.hjson @@ -593,8 +593,8 @@ Mods: { ''' } - Failed: 右键切换失败:无法定位 [{0}] 的真实击败状态 - Successed: 右键切换成功:[{0}] -> [{1}] + Failed: 切换 [{0}] 击败状态失败 ! + Successed: 成功切换:[{0}] -> [{1}] Defeated: 已击败 Alive: 未击败 } diff --git a/UIElements/BossLogUIElements.cs b/UIElements/BossLogUIElements.cs index 4fd0045..067c613 100644 --- a/UIElements/BossLogUIElements.cs +++ b/UIElements/BossLogUIElements.cs @@ -1308,8 +1308,6 @@ public override void RightClick(UIMouseEvent evt) { bool newState = !entry.downed(); Networking.RequestBossStateToggle(entry.Key, newState); - - Main.NewText("Works Good!"); } else { // Entries must not already be downed to add/remove them from the MarkedEntries list [YuBell: fixed this] From b1a7b3b9f74659785d8e1d810d6df91ac43ec177 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=99=9E=E6=82=96=E3=80=8CYu=20Bell=E3=80=8D?= <73875008+zlzhaidou@users.noreply.github.com> Date: Mon, 10 Aug 2026 18:31:31 +0800 Subject: [PATCH 06/12] Formatting adjustments --- BossTracker.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/BossTracker.cs b/BossTracker.cs index 9dd4d38..bf0239b 100644 --- a/BossTracker.cs +++ b/BossTracker.cs @@ -197,8 +197,11 @@ private void InitializeVanillaEntries() { .WithCustomPortrait($"BossChecklist/Resources/BossTextures/EventGoblinArmy") .WithCustomHeadIcon("Terraria/Images/Extra_9"), - // TODO:Split this to three event - EntryInfo.MakeVanillaEvent(OldOnesArmy, "Old One's Army", () => DD2Event.DownedInvasionAnyDifficulty,(@new) => { Main.NewText("Old One's Army do not support changed defeat state now!"); }) + // TODO:Split this into three event + EntryInfo.MakeVanillaEvent(OldOnesArmy, "Old One's Army", () => DD2Event.DownedInvasionAnyDifficulty,(@new) => + { + Main.NewText("Old One's Army do not support changed defeat state now!"); + }) .WithCustomTranslationKey("DungeonDefenders2.InvasionProgressTitle") .WithCustomPortrait($"BossChecklist/Resources/BossTextures/EventOldOnesArmy") .WithCustomHeadIcon("Terraria/Images/Extra_79"), From b79e8417618ad2cf8a2d18c69fcd70a18e7655e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=99=9E=E6=82=96=E3=80=8CYu=20Bell=E3=80=8D?= <73875008+zlzhaidou@users.noreply.github.com> Date: Mon, 10 Aug 2026 18:33:16 +0800 Subject: [PATCH 07/12] DD2Event Temporary plan --- BossTracker.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/BossTracker.cs b/BossTracker.cs index bf0239b..e6148d3 100644 --- a/BossTracker.cs +++ b/BossTracker.cs @@ -199,8 +199,10 @@ private void InitializeVanillaEntries() { // TODO:Split this into three event EntryInfo.MakeVanillaEvent(OldOnesArmy, "Old One's Army", () => DD2Event.DownedInvasionAnyDifficulty,(@new) => - { - Main.NewText("Old One's Army do not support changed defeat state now!"); + { + DD2Event.DownedInvasionT1 = @new; + DD2Event.DownedInvasionT2 = @new; + DD2Event.DownedInvasionT3 = @new; }) .WithCustomTranslationKey("DungeonDefenders2.InvasionProgressTitle") .WithCustomPortrait($"BossChecklist/Resources/BossTextures/EventOldOnesArmy") From 4d83c35513971488e8a36918ff12dd586cd36678 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=99=9E=E6=82=96=E3=80=8CYu=20Bell=E3=80=8D?= <73875008+zlzhaidou@users.noreply.github.com> Date: Tue, 11 Aug 2026 14:58:49 +0800 Subject: [PATCH 08/12] make this feature optional --- BossChecklist.cs | 8 +++----- BossTracker.cs | 11 +++-------- EntryInfo.cs | 19 +++++++++++++------ Localization/de-DE.hjson | 2 +- Localization/en-US.hjson | 4 ++-- Localization/es-ES.hjson | 2 +- Localization/fr-FR.hjson | 2 +- Localization/it-IT.hjson | 2 +- Localization/pl-PL.hjson | 2 +- Localization/pt-BR.hjson | 2 +- Localization/ru-RU.hjson | 2 +- Localization/zh-Hans.hjson | 4 ++-- Networking.cs | 21 +++++++++++++-------- 13 files changed, 43 insertions(+), 38 deletions(-) diff --git a/BossChecklist.cs b/BossChecklist.cs index a1c74dd..bb973e3 100644 --- a/BossChecklist.cs +++ b/BossChecklist.cs @@ -177,10 +177,8 @@ public override object Call(params object[] args) { internalName, // Internal Name Convert.ToSingle(args[3]), // Prog args[4] as Func, // Downed - // WARN: ADAPT MULTIPLAYER - args[5] as Action, // SetDowned - InterpretObjectAsListOfInt(args[6]), // NPC IDs - args[7] as Dictionary + InterpretObjectAsListOfInt(args[5]), // NPC IDs + args[6] as Dictionary ); return "Success"; } @@ -458,7 +456,7 @@ public override void HandlePacket(BinaryReader reader, int whoAmI) { if (!Networking.TryApplyBossStateToggle(bossKey1, downed1)) { ChatHelper.BroadcastChatMessage( - instance.GetLocalization("Configs.DebugTools.Failed").ToNetworkText(bossKey1), + instance.GetLocalization("Configs.DebugTools.Failed").ToNetworkText(entry.name), Color.Red ); break; diff --git a/BossTracker.cs b/BossTracker.cs index e6148d3..f16befe 100644 --- a/BossTracker.cs +++ b/BossTracker.cs @@ -198,12 +198,7 @@ private void InitializeVanillaEntries() { .WithCustomHeadIcon("Terraria/Images/Extra_9"), // TODO:Split this into three event - EntryInfo.MakeVanillaEvent(OldOnesArmy, "Old One's Army", () => DD2Event.DownedInvasionAnyDifficulty,(@new) => - { - DD2Event.DownedInvasionT1 = @new; - DD2Event.DownedInvasionT2 = @new; - DD2Event.DownedInvasionT3 = @new; - }) + EntryInfo.MakeVanillaEvent(OldOnesArmy, "Old One's Army", () => DD2Event.DownedInvasionAnyDifficulty,null) .WithCustomTranslationKey("DungeonDefenders2.InvasionProgressTitle") .WithCustomPortrait($"BossChecklist/Resources/BossTextures/EventOldOnesArmy") .WithCustomHeadIcon("Terraria/Images/Extra_79"), @@ -1144,9 +1139,9 @@ internal static bool[] GetBelongsToInvasionSet(string Key) { ItemID.MusicBoxOWHallow, }; - internal void AddEntry(EntryType type, Mod mod, string iName, float val, Func down,Action setDowned, List id, Dictionary extra = null) { + internal void AddEntry(EntryType type, Mod mod, string iName, float val, Func down, List id, Dictionary extra = null) { EnsureBossIsNotDuplicate(mod?.Name ?? "Unknown", iName); - SortedEntries.Add(new EntryInfo(type, mod?.Name ?? "Unknown", iName, out string key, val, down,setDowned, id, extra)); + SortedEntries.Add(new EntryInfo(type, mod?.Name ?? "Unknown", iName, out string key, val, down, id, extra)); LogNewBoss(mod?.DisplayName ?? "Unknown", iName, key); } diff --git a/EntryInfo.cs b/EntryInfo.cs index 42584c4..b9538e0 100644 --- a/EntryInfo.cs +++ b/EntryInfo.cs @@ -211,7 +211,7 @@ internal bool VisibleOnPageContent() { return VisibleOnChecklist(); } - internal EntryInfo(EntryType entryType, string modSource, string internalName, out string KeyOutput, float progression, Func downed,Action setDowned, List npcIDs, Dictionary extraData = null) { + internal EntryInfo(EntryType entryType, string modSource, string internalName, out string KeyOutput, float progression, Func downed, List npcIDs, Dictionary extraData = null) { // Add the mod source to the opted mods list of the credits page if its not already and add the entry type if (modSource != "Terraria" && modSource != "Unknown") { BossChecklist.bossTracker.RegisteredMods.TryAdd(modSource, new int[3]); @@ -225,7 +225,6 @@ internal EntryInfo(EntryType entryType, string modSource, string internalName, o this.progression = progression; this.downed = downed ?? throw new ArgumentNullException(nameof(downed), BossChecklist.instance.GetLocalization("LogMessage.DownedIsNull").Format(this.Key)); this.npcIDs = npcIDs ?? new List(); - this.setDowned = setDowned; // Localization checks LocalizedText name = extraData?.ContainsKey("displayName") == true ? extraData["displayName"] as LocalizedText : null; @@ -332,6 +331,14 @@ internal EntryInfo(EntryType entryType, string modSource, string internalName, o if (icons.Count > 0) headIconTextures = () => icons; } + + if (extraData?.ContainsKey("setDowned") == true) { + // toggle whether boss is defeated + object setDowned = extraData["setDowned"]; + if (setDowned is Action) { + this.setDowned = setDowned as Action; + } + } } // Workaround for vanilla events with illogical translation keys. @@ -417,7 +424,6 @@ internal static EntryInfo MakeVanillaBoss(EntryType type, float val, string key, out string generatedKey, progression: val, downed: downed, - setDowned: setDowned, npcIDs: new List() { npcID }, extraData: new Dictionary() { { "displayName", Language.GetText(key) }, @@ -425,11 +431,12 @@ internal static EntryInfo MakeVanillaBoss(EntryType type, float val, string key, { "spawnItems", BossTracker.EntrySpawnItems.GetValueOrDefault($"Terraria {nameKey}") }, { "collectibles", BossTracker.EntryCollectibles.GetValueOrDefault($"Terraria {nameKey}") }, { "despawnMessage", customMessages }, + { "setDowned",setDowned }, } ); } - internal static EntryInfo MakeVanillaBoss(EntryType type, float val, string key, List ids, Func downed, Action setDowned) { + internal static EntryInfo MakeVanillaBoss(EntryType type, float val, string key, List ids, Func downed,Action setDowned) { string nameKey = key.Substring(key.LastIndexOf(".") + 1).Replace(" ", "").Replace("'", ""); if (nameKey.EndsWith("Head")) nameKey = nameKey.Substring(0, nameKey.Length - 4); @@ -463,7 +470,6 @@ internal static EntryInfo MakeVanillaBoss(EntryType type, float val, string key, out string generatedKey, progression: val, downed: downed, - setDowned: setDowned, npcIDs: ids, extraData: new Dictionary() { { "displayName", Language.GetText(key) }, @@ -471,6 +477,7 @@ internal static EntryInfo MakeVanillaBoss(EntryType type, float val, string key, { "spawnItems", BossTracker.EntrySpawnItems.GetValueOrDefault($"Terraria {nameKey}") }, { "collectibles", BossTracker.EntryCollectibles.GetValueOrDefault($"Terraria {nameKey}") }, { "despawnMessage", customMessages }, + { "setDowned",setDowned }, } ); } @@ -484,13 +491,13 @@ internal static EntryInfo MakeVanillaEvent(float val, string key, Func dow out string generatedKey, progression: val, downed: downed, - setDowned:setDowned, npcIDs: BossTracker.EventNPCs.GetValueOrDefault($"Terraria {nameKey}"), extraData: new Dictionary() { { "displayName", Language.GetText(key) }, { "spawnInfo", BossChecklist.instance.GetLocalization($"BossSpawnInfo.{nameKey}") }, { "spawnItems", BossTracker.EntrySpawnItems.GetValueOrDefault($"Terraria {nameKey}") }, { "collectibles", BossTracker.EntryCollectibles.GetValueOrDefault($"Terraria {nameKey}") }, + { "setDowned",setDowned }, } ); } diff --git a/Localization/de-DE.hjson b/Localization/de-DE.hjson index 2aad6f7..b501217 100644 --- a/Localization/de-DE.hjson +++ b/Localization/de-DE.hjson @@ -589,7 +589,7 @@ Mods: { ''' */ } - // Failed: Failed to toggle defeat state of [{0}]! + // Failed: Failed to toggle defeat state of [{0}]! This boss do not support this feature now! // Successed: Toggled [{0}] -> [{1}] ! // Defeated: Defeated // Alive: Alive diff --git a/Localization/en-US.hjson b/Localization/en-US.hjson index b05bea4..da4eff2 100644 --- a/Localization/en-US.hjson +++ b/Localization/en-US.hjson @@ -1,4 +1,4 @@ -Mods: { +Mods: { BossChecklist: { Log: { Common: { @@ -593,7 +593,7 @@ Mods: { ''' } - Failed: Failed to toggle defeat state of [{0}]! + Failed: Failed to toggle defeat state of [{0}]! This boss do not support this feature now! Successed: Toggled [{0}] -> [{1}] ! Defeated: Defeated Alive: Alive diff --git a/Localization/es-ES.hjson b/Localization/es-ES.hjson index 4583694..5e071d3 100644 --- a/Localization/es-ES.hjson +++ b/Localization/es-ES.hjson @@ -589,7 +589,7 @@ Mods: { ''' */ } - // Failed: Failed to toggle defeat state of [{0}]! + // Failed: Failed to toggle defeat state of [{0}]! This boss do not support this feature now! // Successed: Toggled [{0}] -> [{1}] ! // Defeated: Defeated // Alive: Alive diff --git a/Localization/fr-FR.hjson b/Localization/fr-FR.hjson index a5291ba..659c089 100644 --- a/Localization/fr-FR.hjson +++ b/Localization/fr-FR.hjson @@ -596,7 +596,7 @@ Mods: { ''' */ } - // Failed: Failed to toggle defeat state of [{0}]! + // Failed: Failed to toggle defeat state of [{0}]! This boss do not support this feature now! // Successed: Toggled [{0}] -> [{1}] ! // Defeated: Defeated // Alive: Alive diff --git a/Localization/it-IT.hjson b/Localization/it-IT.hjson index feb17bf..3930ade 100644 --- a/Localization/it-IT.hjson +++ b/Localization/it-IT.hjson @@ -593,7 +593,7 @@ Mods: { ''' */ } - // Failed: Failed to toggle defeat state of [{0}]! + // Failed: Failed to toggle defeat state of [{0}]! This boss do not support this feature now! // Successed: Toggled [{0}] -> [{1}] ! // Defeated: Defeated // Alive: Alive diff --git a/Localization/pl-PL.hjson b/Localization/pl-PL.hjson index feb17bf..3930ade 100644 --- a/Localization/pl-PL.hjson +++ b/Localization/pl-PL.hjson @@ -593,7 +593,7 @@ Mods: { ''' */ } - // Failed: Failed to toggle defeat state of [{0}]! + // Failed: Failed to toggle defeat state of [{0}]! This boss do not support this feature now! // Successed: Toggled [{0}] -> [{1}] ! // Defeated: Defeated // Alive: Alive diff --git a/Localization/pt-BR.hjson b/Localization/pt-BR.hjson index dfa5f16..57afc8f 100644 --- a/Localization/pt-BR.hjson +++ b/Localization/pt-BR.hjson @@ -593,7 +593,7 @@ Mods: { ''' */ } - // Failed: Failed to toggle defeat state of [{0}]! + // Failed: Failed to toggle defeat state of [{0}]! This boss do not support this feature now! // Successed: Toggled [{0}] -> [{1}] ! // Defeated: Defeated // Alive: Alive diff --git a/Localization/ru-RU.hjson b/Localization/ru-RU.hjson index b083889..689c6f5 100644 --- a/Localization/ru-RU.hjson +++ b/Localization/ru-RU.hjson @@ -592,7 +592,7 @@ Mods: { ''' */ } - // Failed: Failed to toggle defeat state of [{0}]! + // Failed: Failed to toggle defeat state of [{0}]! This boss do not support this feature now! // Successed: Toggled [{0}] -> [{1}] ! // Defeated: Defeated // Alive: Alive diff --git a/Localization/zh-Hans.hjson b/Localization/zh-Hans.hjson index 29c6310..839ba01 100644 --- a/Localization/zh-Hans.hjson +++ b/Localization/zh-Hans.hjson @@ -1,4 +1,4 @@ -Mods: { +Mods: { BossChecklist: { Log: { Common: { @@ -593,7 +593,7 @@ Mods: { ''' } - Failed: 切换 [{0}] 击败状态失败 ! + Failed: 切换 [{0}] 击败状态失败!该Boss暂未支持该功能! Successed: 成功切换:[{0}] -> [{1}] Defeated: 已击败 Alive: 未击败 diff --git a/Networking.cs b/Networking.cs index 9cd9dfb..bef825e 100644 --- a/Networking.cs +++ b/Networking.cs @@ -1,6 +1,8 @@ using BossChecklist.Systems; +using Microsoft.Xna.Framework; using Terraria; using Terraria.ID; +using Terraria.Localization; using Terraria.ModLoader; namespace BossChecklist @@ -84,18 +86,21 @@ internal static bool TryApplyBossStateToggle(string bossKey, bool downed) { public static void RequestBossStateToggle(string bossKey, bool downed) { if (Main.netMode == NetmodeID.SinglePlayer) { - TryApplyBossStateToggle(bossKey, downed); + if(!TryApplyBossStateToggle(bossKey, downed)) { + Main.NewText(Language.GetTextValue("Mods.BossChecklist.Configs.DebugTools.Failed", BossChecklist.bossTracker.FindEntryFromKey(bossKey).name, Color.Red)); + } return; } - if (Main.netMode != NetmodeID.MultiplayerClient) + else if (Main.netMode != NetmodeID.MultiplayerClient) return; - - ModPacket packet = BossChecklist.instance.GetPacket(); - packet.Write((byte)PacketMessageType.RequestBossStateToggle); - packet.Write(bossKey); - packet.Write(downed); - packet.Send(); + else { + ModPacket packet = BossChecklist.instance.GetPacket(); + packet.Write((byte)PacketMessageType.RequestBossStateToggle); + packet.Write(bossKey); + packet.Write(downed); + packet.Send(); + } } } } From 2346c718cc0f4d0caddba402cb68f12fff424814 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=99=9E=E6=82=96=E3=80=8CYu=20Bell=E3=80=8D?= <73875008+zlzhaidou@users.noreply.github.com> Date: Tue, 11 Aug 2026 14:59:18 +0800 Subject: [PATCH 09/12] fix --- Networking.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Networking.cs b/Networking.cs index bef825e..557b2a2 100644 --- a/Networking.cs +++ b/Networking.cs @@ -87,7 +87,7 @@ internal static bool TryApplyBossStateToggle(string bossKey, bool downed) { public static void RequestBossStateToggle(string bossKey, bool downed) { if (Main.netMode == NetmodeID.SinglePlayer) { if(!TryApplyBossStateToggle(bossKey, downed)) { - Main.NewText(Language.GetTextValue("Mods.BossChecklist.Configs.DebugTools.Failed", BossChecklist.bossTracker.FindEntryFromKey(bossKey).name, Color.Red)); + Main.NewText(Language.GetTextValue("Mods.BossChecklist.Configs.DebugTools.Failed", BossChecklist.bossTracker.FindEntryFromKey(bossKey).name), Color.Red); } return; } From b33e955d31c24baaac357a2351d7c007a8104039 Mon Sep 17 00:00:00 2001 From: Sheepish Shepherd Date: Wed, 19 Aug 2026 16:33:56 -0400 Subject: [PATCH 10/12] cleanup spacing --- BossTracker.cs | 16 ++++++++-------- EntryInfo.cs | 10 +++++----- UIElements/BossLogUIElements.cs | 6 ++---- 3 files changed, 15 insertions(+), 17 deletions(-) diff --git a/BossTracker.cs b/BossTracker.cs index f16befe..fe77a78 100644 --- a/BossTracker.cs +++ b/BossTracker.cs @@ -117,28 +117,28 @@ public BossTracker() { private void InitializeVanillaEntries() { SortedEntries = new List { // Bosses -- Vanilla - EntryInfo.MakeVanillaBoss(EntryType.Boss, KingSlime, "NPCName.KingSlime", NPCID.KingSlime, () => NPC.downedSlimeKing,(@new) => {NPC.downedSlimeKing = @new;}) + EntryInfo.MakeVanillaBoss(EntryType.Boss, KingSlime, "NPCName.KingSlime", NPCID.KingSlime, () => NPC.downedSlimeKing, (@new) => { NPC.downedSlimeKing = @new; }) .WithCustomPortrait($"BossChecklist/Resources/BossTextures/Boss{NPCID.KingSlime}"), - EntryInfo.MakeVanillaBoss(EntryType.Boss, EyeOfCthulhu, "NPCName.EyeofCthulhu", NPCID.EyeofCthulhu, () => NPC.downedBoss1,(@new) => {NPC.downedBoss1 = @new; }), + EntryInfo.MakeVanillaBoss(EntryType.Boss, EyeOfCthulhu, "NPCName.EyeofCthulhu", NPCID.EyeofCthulhu, () => NPC.downedBoss1, (@new) => { NPC.downedBoss1 = @new; }), - EntryInfo.MakeVanillaBoss(EntryType.Boss, EaterOfWorlds, "NPCName.EaterofWorldsHead", new List() { NPCID.EaterofWorldsHead, NPCID.EaterofWorldsBody, NPCID.EaterofWorldsTail }, () => NPC.downedBoss2,(@new) => {NPC.downedBoss2 = @new; }) + EntryInfo.MakeVanillaBoss(EntryType.Boss, EaterOfWorlds, "NPCName.EaterofWorldsHead", new List() { NPCID.EaterofWorldsHead, NPCID.EaterofWorldsBody, NPCID.EaterofWorldsTail }, () => NPC.downedBoss2, (@new) => { NPC.downedBoss2 = @new; }) .WithCustomAvailability(() => !WorldGen.crimson || Main.drunkWorld) .WithCustomPortrait($"BossChecklist/Resources/BossTextures/Boss{NPCID.EaterofWorldsHead}"), - EntryInfo.MakeVanillaBoss(EntryType.Boss, EaterOfWorlds, "NPCName.BrainofCthulhu", NPCID.BrainofCthulhu, () => NPC.downedBoss2,(@new) => {NPC.downedBoss2 = @new; }) + EntryInfo.MakeVanillaBoss(EntryType.Boss, EaterOfWorlds, "NPCName.BrainofCthulhu", NPCID.BrainofCthulhu, () => NPC.downedBoss2, (@new) => { NPC.downedBoss2 = @new; }) .WithCustomAvailability(() => WorldGen.crimson || Main.drunkWorld), - EntryInfo.MakeVanillaBoss(EntryType.Boss, QueenBee, "NPCName.QueenBee", NPCID.QueenBee, () => NPC.downedQueenBee,(@new) => {NPC.downedQueenBee = @new; }), + EntryInfo.MakeVanillaBoss(EntryType.Boss, QueenBee, "NPCName.QueenBee", NPCID.QueenBee, () => NPC.downedQueenBee, (@new) => { NPC.downedQueenBee = @new; }), - EntryInfo.MakeVanillaBoss(EntryType.Boss, Skeletron, "NPCName.SkeletronHead", new List() { NPCID.SkeletronHead }, () => NPC.downedBoss3,(@new) => {NPC.downedBoss3 = @new; }) + EntryInfo.MakeVanillaBoss(EntryType.Boss, Skeletron, "NPCName.SkeletronHead", new List() { NPCID.SkeletronHead }, () => NPC.downedBoss3, (@new) => { NPC.downedBoss3 = @new; }) .WithCustomLimbs(new List() { NPCID.SkeletronHand }) .WithCustomPortrait($"BossChecklist/Resources/BossTextures/Boss{NPCID.SkeletronHead}"), - EntryInfo.MakeVanillaBoss(EntryType.Boss, DeerClops, "NPCName.Deerclops", NPCID.Deerclops, () => NPC.downedDeerclops,(@new) => {NPC.downedDeerclops = @new; }) + EntryInfo.MakeVanillaBoss(EntryType.Boss, DeerClops, "NPCName.Deerclops", NPCID.Deerclops, () => NPC.downedDeerclops, (@new) => { NPC.downedDeerclops = @new; }) .WithCustomPortrait($"BossChecklist/Resources/BossTextures/Boss{NPCID.Deerclops}"), - EntryInfo.MakeVanillaBoss(EntryType.Boss, WallOfFlesh, "NPCName.WallofFlesh", new List() { NPCID.WallofFlesh }, () => Main.hardMode,(@new) => {Main.hardMode = @new; }) + EntryInfo.MakeVanillaBoss(EntryType.Boss, WallOfFlesh, "NPCName.WallofFlesh", new List() { NPCID.WallofFlesh }, () => Main.hardMode, (@new) => { Main.hardMode = @new; }) .WithCustomPortrait($"BossChecklist/Resources/BossTextures/Boss{NPCID.WallofFlesh}"), EntryInfo.MakeVanillaBoss(EntryType.Boss, QueenSlime, "NPCName.QueenSlimeBoss", NPCID.QueenSlimeBoss, () => NPC.downedQueenSlime, (@new) => { NPC.downedQueenSlime = @new; }) diff --git a/EntryInfo.cs b/EntryInfo.cs index b9538e0..a39a713 100644 --- a/EntryInfo.cs +++ b/EntryInfo.cs @@ -390,7 +390,7 @@ internal EntryInfo WithCustomHeadIcon(List texturePaths) { return this; } - internal static EntryInfo MakeVanillaBoss(EntryType type, float val, string key, int npcID, Func downed,Action setDowned) { + internal static EntryInfo MakeVanillaBoss(EntryType type, float val, string key, int npcID, Func downed, Action setDowned) { string nameKey = key.Substring(key.LastIndexOf(".") + 1); // BossChecklist only has despawn messages for vanilla Bosses @@ -431,12 +431,12 @@ internal static EntryInfo MakeVanillaBoss(EntryType type, float val, string key, { "spawnItems", BossTracker.EntrySpawnItems.GetValueOrDefault($"Terraria {nameKey}") }, { "collectibles", BossTracker.EntryCollectibles.GetValueOrDefault($"Terraria {nameKey}") }, { "despawnMessage", customMessages }, - { "setDowned",setDowned }, + { "setDowned", setDowned }, } ); } - internal static EntryInfo MakeVanillaBoss(EntryType type, float val, string key, List ids, Func downed,Action setDowned) { + internal static EntryInfo MakeVanillaBoss(EntryType type, float val, string key, List ids, Func downed, Action setDowned) { string nameKey = key.Substring(key.LastIndexOf(".") + 1).Replace(" ", "").Replace("'", ""); if (nameKey.EndsWith("Head")) nameKey = nameKey.Substring(0, nameKey.Length - 4); @@ -477,7 +477,7 @@ internal static EntryInfo MakeVanillaBoss(EntryType type, float val, string key, { "spawnItems", BossTracker.EntrySpawnItems.GetValueOrDefault($"Terraria {nameKey}") }, { "collectibles", BossTracker.EntryCollectibles.GetValueOrDefault($"Terraria {nameKey}") }, { "despawnMessage", customMessages }, - { "setDowned",setDowned }, + { "setDowned", setDowned }, } ); } @@ -497,7 +497,7 @@ internal static EntryInfo MakeVanillaEvent(float val, string key, Func dow { "spawnInfo", BossChecklist.instance.GetLocalization($"BossSpawnInfo.{nameKey}") }, { "spawnItems", BossTracker.EntrySpawnItems.GetValueOrDefault($"Terraria {nameKey}") }, { "collectibles", BossTracker.EntryCollectibles.GetValueOrDefault($"Terraria {nameKey}") }, - { "setDowned",setDowned }, + { "setDowned", setDowned }, } ); } diff --git a/UIElements/BossLogUIElements.cs b/UIElements/BossLogUIElements.cs index 067c613..dd1ab88 100644 --- a/UIElements/BossLogUIElements.cs +++ b/UIElements/BossLogUIElements.cs @@ -2,6 +2,7 @@ using BossChecklist.Systems; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; +using Microsoft.Xna.Framework.Input; using ReLogic.Content; using ReLogic.Graphics; using ReLogic.OS; @@ -1299,10 +1300,7 @@ public override void RightClick(UIMouseEvent evt) { } else { - bool shiftHeld = - Main.keyState.IsKeyDown(Microsoft.Xna.Framework.Input.Keys.LeftShift) - || - Main.keyState.IsKeyDown(Microsoft.Xna.Framework.Input.Keys.RightShift); + bool shiftHeld = Main.keyState.IsKeyDown(Keys.LeftShift) || Main.keyState.IsKeyDown(Keys.RightShift); if (shiftHeld && BossChecklist.BossLogConfig.Debug.EnableBossStateToggle) { bool newState = !entry.downed(); From 917efdcec9076443a134fb000741650d71efa406 Mon Sep 17 00:00:00 2001 From: Sheepish Shepherd Date: Sat, 22 Aug 2026 13:30:59 -0400 Subject: [PATCH 11/12] moved config below EntryInfo related configs --- Configs.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Configs.cs b/Configs.cs index 0c630f7..6839ae4 100644 --- a/Configs.cs +++ b/Configs.cs @@ -37,10 +37,6 @@ public class BossLogConfiguration : ModConfig { public DebugTools Debug { get; set; } = new DebugTools(); public class DebugTools { - [BackgroundColor(250, 235, 215)] - [DefaultValue(false)] - public bool EnableBossStateToggle { get; set; } - [BackgroundColor(250, 235, 215)] [DefaultValue(false)] public bool ModCallLogVerbose { get; set; } @@ -61,6 +57,10 @@ public class DebugTools [DefaultValue(false)] public bool ShowCollectionType { get; set; } + [BackgroundColor(250, 235, 215)] + [DefaultValue(false)] + public bool EnableBossStateToggle { get; set; } + [BackgroundColor(250, 235, 215)] [DefaultValue(false)] public bool EnabledResetOptions { get; set; } From 9bb33a10460362143b3d7c831f70aa8aabe94285 Mon Sep 17 00:00:00 2001 From: Sheepish Shepherd Date: Sat, 22 Aug 2026 13:31:29 -0400 Subject: [PATCH 12/12] adjusted debug text --- Localization/de-DE.hjson | 2 +- Localization/en-US.hjson | 2 +- Localization/es-ES.hjson | 2 +- Localization/fr-FR.hjson | 2 +- Localization/it-IT.hjson | 2 +- Localization/pl-PL.hjson | 2 +- Localization/pt-BR.hjson | 2 +- Localization/ru-RU.hjson | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Localization/de-DE.hjson b/Localization/de-DE.hjson index b501217..23bcfd8 100644 --- a/Localization/de-DE.hjson +++ b/Localization/de-DE.hjson @@ -589,7 +589,7 @@ Mods: { ''' */ } - // Failed: Failed to toggle defeat state of [{0}]! This boss do not support this feature now! + // Failed: Failed to toggle defeat state of [{0}]! This entry does not currently support this feature! // Successed: Toggled [{0}] -> [{1}] ! // Defeated: Defeated // Alive: Alive diff --git a/Localization/en-US.hjson b/Localization/en-US.hjson index da4eff2..58e04de 100644 --- a/Localization/en-US.hjson +++ b/Localization/en-US.hjson @@ -593,7 +593,7 @@ ''' } - Failed: Failed to toggle defeat state of [{0}]! This boss do not support this feature now! + Failed: Failed to toggle defeat state of [{0}]! This entry does not currently support this feature! Successed: Toggled [{0}] -> [{1}] ! Defeated: Defeated Alive: Alive diff --git a/Localization/es-ES.hjson b/Localization/es-ES.hjson index 5e071d3..6356e19 100644 --- a/Localization/es-ES.hjson +++ b/Localization/es-ES.hjson @@ -589,7 +589,7 @@ Mods: { ''' */ } - // Failed: Failed to toggle defeat state of [{0}]! This boss do not support this feature now! + // Failed: Failed to toggle defeat state of [{0}]! This entry does not currently support this feature! // Successed: Toggled [{0}] -> [{1}] ! // Defeated: Defeated // Alive: Alive diff --git a/Localization/fr-FR.hjson b/Localization/fr-FR.hjson index 659c089..7c6173e 100644 --- a/Localization/fr-FR.hjson +++ b/Localization/fr-FR.hjson @@ -596,7 +596,7 @@ Mods: { ''' */ } - // Failed: Failed to toggle defeat state of [{0}]! This boss do not support this feature now! + // Failed: Failed to toggle defeat state of [{0}]! This entry does not currently support this feature! // Successed: Toggled [{0}] -> [{1}] ! // Defeated: Defeated // Alive: Alive diff --git a/Localization/it-IT.hjson b/Localization/it-IT.hjson index 3930ade..2080ec8 100644 --- a/Localization/it-IT.hjson +++ b/Localization/it-IT.hjson @@ -593,7 +593,7 @@ Mods: { ''' */ } - // Failed: Failed to toggle defeat state of [{0}]! This boss do not support this feature now! + // Failed: Failed to toggle defeat state of [{0}]! This entry does not currently support this feature! // Successed: Toggled [{0}] -> [{1}] ! // Defeated: Defeated // Alive: Alive diff --git a/Localization/pl-PL.hjson b/Localization/pl-PL.hjson index 3930ade..2080ec8 100644 --- a/Localization/pl-PL.hjson +++ b/Localization/pl-PL.hjson @@ -593,7 +593,7 @@ Mods: { ''' */ } - // Failed: Failed to toggle defeat state of [{0}]! This boss do not support this feature now! + // Failed: Failed to toggle defeat state of [{0}]! This entry does not currently support this feature! // Successed: Toggled [{0}] -> [{1}] ! // Defeated: Defeated // Alive: Alive diff --git a/Localization/pt-BR.hjson b/Localization/pt-BR.hjson index 57afc8f..be820ee 100644 --- a/Localization/pt-BR.hjson +++ b/Localization/pt-BR.hjson @@ -593,7 +593,7 @@ Mods: { ''' */ } - // Failed: Failed to toggle defeat state of [{0}]! This boss do not support this feature now! + // Failed: Failed to toggle defeat state of [{0}]! This entry does not currently support this feature! // Successed: Toggled [{0}] -> [{1}] ! // Defeated: Defeated // Alive: Alive diff --git a/Localization/ru-RU.hjson b/Localization/ru-RU.hjson index 689c6f5..3add053 100644 --- a/Localization/ru-RU.hjson +++ b/Localization/ru-RU.hjson @@ -592,7 +592,7 @@ Mods: { ''' */ } - // Failed: Failed to toggle defeat state of [{0}]! This boss do not support this feature now! + // Failed: Failed to toggle defeat state of [{0}]! This entry does not currently support this feature! // Successed: Toggled [{0}] -> [{1}] ! // Defeated: Defeated // Alive: Alive