-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathHypnosMod.cs
More file actions
161 lines (153 loc) · 6.45 KB
/
HypnosMod.cs
File metadata and controls
161 lines (153 loc) · 6.45 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
using Terraria.ModLoader;
using Terraria;
using System;
using System.IO;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System.Collections.Generic;
using HypnosMod.HypnosNPCs;
using Terraria.ID;
using ReLogic.Content;
using Terraria.Graphics.Shaders;
using CalamityMod;
using Terraria.GameContent;
using Terraria.Graphics.Effects;
using Terraria.Localization;
using HypnosMod.Items;
namespace HypnosMod
{
enum HypnosMessageType
{
HypnosSummoned
}
public class HypnosMod : Mod
{
public static HypnosMod instance;
public override void HandlePacket(BinaryReader reader, int whoAmI)
{
HypnosMessageType msgType = (HypnosMessageType)reader.ReadByte();
switch (msgType)
{
case HypnosMessageType.HypnosSummoned:
int player = reader.ReadByte();
HypnosBoss.SummonDraedon(Main.player[player]);
break;
}
}
private static void RegisterSceneFilter(ScreenShaderData passReg, string registrationName, EffectPriority priority = EffectPriority.High)
{
string prefixedRegistrationName = "HypnosMod:" + registrationName;
Filters.Scene[prefixedRegistrationName] = new Filter(passReg, priority);
Filters.Scene[prefixedRegistrationName].Load();
}
private static void RegisterScreenShader(Effect shader, string passName, string registrationName, EffectPriority priority = EffectPriority.High)
{
Ref<Effect> shaderPointer = new(shader);
ScreenShaderData passParamRegistration = new(shaderPointer, passName);
RegisterSceneFilter(passParamRegistration, registrationName, priority);
}
internal static Effect ShieldShader;
public override void Load()
{
instance = this;
AssetRepository calAss = instance.Assets;
Effect LoadShader(string path) => calAss.Request<Effect>("Effects/" + path, AssetRequestMode.ImmediateLoad).Value;
ShieldShader = LoadShader("HoloShield");
RegisterScreenShader(ShieldShader, "ShieldPass", "HoloShieldShader");
}
public override void PostSetupContent()
{
try
{
Mod cal = ModLoader.GetMod("CalamityMod");
// --- Calamity shared boss health bar integration ---
// 1. Declare one-to-many relationship (main boss -> subordinate/parts)
cal.Call("DeclareOneToManyRelationshipForHealthBar", ModContent.NPCType<HypnosBoss>(), ModContent.NPCType<HypnosPlug>());
// 2. Exclude the subordinate so it does not get its own bar
cal.Call("ExcludeBossFromHealthBar", ModContent.NPCType<HypnosPlug>());
// 3. Register custom HP calculation: aggregate all active HypnosPlug HP into HypnosBoss bar
cal.Call("DeclareSpecialHPCalculationDecisionForHealthBar",
(Func<NPC, bool>)(n => n.type == ModContent.NPCType<HypnosBoss>()),
(Func<NPC, bool, long>)((n, accumulatingMax) =>
{
long total = accumulatingMax ? n.lifeMax : n.life;
int plugType = ModContent.NPCType<HypnosPlug>();
for (int i = 0; i < Main.maxNPCs; i++)
{
NPC other = Main.npc[i];
if (other.active && other.type == plugType)
total += accumulatingMax ? other.lifeMax : Math.Max(0, other.life);
}
return total;
})
);
// 4. Create name extension handler so the health bar can use a localized name (and optionally conditions if parts exist)
LocalizedText extName = Language.GetText("Mods.HypnosMod.Hypnos.HealthBarExtension");
cal.Call("CreateNameExtensionHandlerForHealthBar", extName, ModContent.NPCType<HypnosBoss>(), ModContent.NPCType<HypnosPlug>());
Logger.Info("[HypnosMod] Registered shared health bar (HypnosBoss + HypnosPlug)");
var brEntries = (List<(int, int, Action<int>, int, bool, float, int[], int[])>)cal.Call("GetBossRushEntries");
int[] excIDs = { ModContent.NPCType<AergiaNeuron>(), ModContent.NPCType<HypnosPlug>() };
int[] headID = { ModContent.NPCType<HypnosBoss>() };
Action<int> pr = delegate (int npc)
{
NPC.SpawnOnPlayer(CalamityMod.Events.BossRushEvent.ClosestPlayerToWorldCenter, ModContent.NPCType<HypnosBoss>());
};
brEntries.Insert(brEntries.Count() - 2, (ModContent.NPCType<HypnosBoss>(), -1, pr, 180, false, 0f, excIDs, headID));
cal.Call("SetBossRushEntries", brEntries);
}
catch { /* ignore Calamity Boss Rush integration failures to not block other integrations */ }
{
Mod bossChecklist;
ModLoader.TryGetMod("BossChecklist", out bossChecklist);
if (bossChecklist != null)
{
// Follow Calamity's BossChecklist integration style: LogBoss with entryName and data dict
string entryName = "Hypnos"; // unique key used by BossChecklist
float order = 22.5f; // After Yharon (22.0), before Exo Mechs (22.99)
var displayName = Language.GetText("Mods.HypnosMod.BossChecklist.Hypnos.EntryName");
var spawnInfoLoc = Language.GetText("Mods.HypnosMod.BossChecklist.Hypnos.SpawnInfo");
var despawnMessage = Language.GetText("Mods.HypnosMod.BossChecklist.Hypnos.Flavor");
var collectibles = new List<int>
{
ModContent.ItemType<CalamityMod.Items.Materials.ExoPrism>(),
ModContent.ItemType<HypnosTrophyInv>(),
ModContent.ItemType<HypnosMask>()
};
// Resolve BloodyVein item id for icon in the spawn info panel.
int spawnItemId = 0;
if (ModLoader.TryGetMod("CalamityMod", out Mod calamityMod))
{
if (calamityMod.TryFind<ModItem>("BloodyVein", out var item))
spawnItemId = item.Type;
}
var bcData = new Dictionary<string, object>
{
["displayName"] = displayName,
["spawnInfo"] = spawnInfoLoc,
["despawnMessage"] = despawnMessage,
["collectibles"] = collectibles
};
if (spawnItemId > 0)
bcData["spawnItems"] = spawnItemId;
// Prefer modern API: LogBoss
try
{
bossChecklist.Call("LogBoss", this, entryName, order, (Func<bool>)(() => HypnosWorld.downedHypnos), ModContent.NPCType<HypnosNPCs.HypnosBoss>(), bcData);
Logger.Info("[HypnosMod] BossChecklist: registered via LogBoss");
}
catch
{
// Fallback to AddBoss if LogBoss is unavailable
bossChecklist.Call("AddBoss", this, displayName.Value, order, (Func<bool>)(() => HypnosWorld.downedHypnos), new int[] { ModContent.NPCType<HypnosNPCs.HypnosBoss>() }, bcData);
Logger.Info("[HypnosMod] BossChecklist: registered via AddBoss fallback");
}
}
}
}
public override void Unload()
{
instance = null;
}
}
}