-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathSeinData.cs
More file actions
369 lines (316 loc) · 11.1 KB
/
Copy pathSeinData.cs
File metadata and controls
369 lines (316 loc) · 11.1 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
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
using System;
using System.Collections.Generic;
using System.Reflection;
using Microsoft.Xna.Framework;
using Terraria.ID;
using Terraria.ModLoader;
namespace OriMod;
public sealed class SeinData {
private SeinData() { }
/// <summary>
/// Collection of all <see cref="SeinData"/>s in the mod.
/// </summary>
public static SeinData[] All { get; private set; }
/// <summary>
/// Collection of all sein buffs ids.
/// </summary>
public static int[] SeinBuffs { get; private set; }
/// <summary>
/// Loads all Sein variants. Sein stats are hardcoded into this method.
/// </summary>
/// <remarks>
/// Okay, no matter how many times I try to refactor this, I don't think it can be organized any better.
/// <para>1. Memory is always only ever using 8 <see cref="SeinData"/>s, or however many is in <see cref="All"/>. Not too big a deal though.</para>
/// <para>2. Readability. I feel that this is the best setup for a few reasons.</para>
/// <para>2a. It's all in one file rather than multiple derived classes for easy comparison.</para>
/// <para>2b. Only the changes/upgrades are shown, rather than having redundant data. The same could be accomplished with inheritance, but I'd rather not have 8 levels of it.</para>
/// </remarks>
internal static void Load() {
SeinData defaultSein = new();
var fields = typeof(SeinData).GetFields();
var list = new List<SeinData>();
void AddNewSein(SeinData newSein) {
SeinData lastSein = list.Count == 0 ? new SeinData() : list[^1];
foreach (FieldInfo field in fields) {
object defVal = field.GetValue(defaultSein);
object oldVal = field.GetValue(lastSein);
object newVal = field.GetValue(newSein);
// If value is specified in constructor, use it
// If value is unspecified, use value of previous upgrade
if (newVal.ToString() == defVal.ToString()) {
newVal = oldVal;
}
field.SetValue(newSein, newVal);
}
list.Add(newSein);
//OriMod.Log.Debug(newSein.CalculateStuff(tierName));
}
// Tier 1 (Silver)
AddNewSein(new SeinData() {
lightStrength = 0.4f
});
// Tier 2 (Demonite/Crimtane)
// Increased shots per burst
// Max damage per burst: 15
AddNewSein(new SeinData {
rarity = ItemRarityID.Green,
value = 3000,
color = new Color(108, 92, 172),
damage = 24,
targets = 1,
bursts = 3,
projectileSpeedStart = 9f,
homingIncreaseRate = 0.05f,
dustScale = 1.8f,
lightStrength = 1.6f,
});
// Tier 3 (Hellstone)
// 2 targets
// Max damage per burst: 42
// For some sort of "rage" effect to pair with red theme, lower CD
AddNewSein(new SeinData {
rarity = ItemRarityID.Orange,
value = 10000,
color = new Color(240, 0, 0, 194),
damage = 29,
targets = 2,
maxShotsAtOnce = 2,
randDegrees = 100,
cooldownMin = 5,
cooldownShort = 16,
cooldownLong = 35,
projectileSpeedStart = 12.5f,
projectileSpeedIncreaseRate = 0.7f,
projectileSpeedIncreaseDelay = 10,
targetMaxDist = 370f,
dustScale = 2f,
lightStrength = 1.275f,
});
// Tier 4 (Mythril/Orichalcum)
// 2 targets, 2 shots to primary, 3 shots max (rather than 4)
// Max damage per burst: 81
AddNewSein(new SeinData {
rarity = ItemRarityID.LightRed,
value = 25000,
color = new Color(185, 248, 248),
damage = 33,
shotsToPrimaryTarget = 2,
maxShotsAtOnce = 3,
randDegrees = 60,
cooldownMin = 11,
cooldownShort = 25,
cooldownLong = 40,
projectileSpeedStart = 13.5f,
homingIncreaseRate = 0.06f,
homingIncreaseDelay = 20,
dustScale = 2.2f,
lightStrength = 1.2f,
});
// Tier 5 (Hallow)
// 3 targets, 2 shots to primary, 4 shots max (rather than 5)
// Max damage per burst: 132
AddNewSein(new SeinData {
rarity = ItemRarityID.Pink,
value = 50000,
color = new Color(255, 228, 160),
damage = 37,
targets = 3,
maxShotsAtOnce = 4,
homingIncreaseDelay = 17,
targetMaxDist = 440f,
dustScale = 2.4f,
lightStrength = 1.4f,
});
// Tier 6 (Spectral)
// 3 targets, 3 shots to primary, 5 shots max
// Max damage per burst: 195
AddNewSein(new SeinData {
rarity = ItemRarityID.Yellow,
value = 100000,
color = new Color(0, 180, 174, 210),
damage = 42,
shotsToPrimaryTarget = 3,
maxShotsAtOnce = 5,
cooldownMin = 12,
cooldownShort = 26,
cooldownLong = 52,
targetThroughWallDist = 224f,
homingIncreaseRate = 0.07f,
projectileSpeedStart = 15f,
projectileSpeedIncreaseRate = 0.85f,
projectileSpeedIncreaseDelay = 14,
randDegrees = 70,
dustScale = 2.65f,
lightStrength = 2.25f,
});
// Tier 7 (Lunar)
// 4 targets, 3 shots to primary, 2 to others, 6 shots max (rather than 9)
// Max damage per burst: 282
AddNewSein(new SeinData {
rarity = ItemRarityID.Cyan,
value = 250000,
color = new Color(78, 38, 102),
damage = 47,
targets = 4,
shotsToPrimaryTarget = 3,
shotsPerTarget = 2,
maxShotsAtOnce = 9,
homingIncreaseRate = 0.025f,
projectileSpeedStart = 16f,
targetMaxDist = 510f,
randDegrees = 120,
dustScale = 3f,
lightStrength = 4.5f,
});
// Tier 8 (Lunar Bars)
// 5 targets, 4 shots to primary, 2 shots to others, 10 shots max (rather than 12)
// Max damage per burst: 530 (too high?)
AddNewSein(new SeinData {
rarity = ItemRarityID.Red,
value = 500000,
color = new Color(220, 220, 220),
damage = 53,
bursts = 4,
targets = 6,
shotsToPrimaryTarget = 4,
maxShotsAtOnce = 10,
cooldownMin = 16,
cooldownShort = 24,
cooldownLong = 55,
homingStrengthStart = 0.05f,
homingIncreaseDelay = 15,
projectileSpeedStart = 20f,
projectileSpeedIncreaseRate = 1.25f,
projectileSpeedIncreaseDelay = 28,
randDegrees = 180,
targetMaxDist = 650f,
targetThroughWallDist = 370f,
dustScale = 3.35f,
lightStrength = 2.5f,
});
All = Unloadable.New(list.ToArray(), () => All = null);
SeinBuffs = Unloadable.New(new int[All.Length], () => SeinBuffs = null);
for (int u = 0; u < All.Length; u++) {
SeinBuffs[u] = ModContent.Find<ModBuff>(OriMod.instance.Name, "SeinBuff" + (u + 1)).Type;
}
}
#region Stats
#region Stats responsible for DPS
/// <summary>
/// Damage of Spirit Flame.
/// </summary>
public int damage = 18;
/// <summary>
/// Number of NPCs that can be targeted at once.
/// </summary>
public int targets = 1;
/// <summary>
/// Maximum times the minion can fire with a delay of <see cref="cooldownMin"/> before having a delay of <see cref="cooldownLong"/>.
/// </summary>
public int bursts = 2;
/// <summary>
/// Maximum number of shots that can be fired at each target.
/// </summary>
public int shotsPerTarget = 1;
/// <summary>
/// Maximum number of shots that can be fired at the primary target at once.
/// </summary>
public int shotsToPrimaryTarget = 1;
/// <summary>
/// Maximum number of shots that can be fired at once.
/// </summary>
public int maxShotsAtOnce = 1;
/// <summary>
/// Delay between each shot in <see cref="bursts"/>.
/// </summary>
public int cooldownMin = 10;
/// <summary>
/// Shortest time to wait during <see cref="bursts"/> to reset burst count.
/// </summary>
public int cooldownShort = 15;
/// <summary>
/// Delay between each series of shots, incurred when shots reaches <see cref="bursts"/>.
/// </summary>
public int cooldownLong = 30;
#endregion
/// <summary>
/// Maximum angle that fired Spirit Flames will be away from the target.
/// </summary>
internal int randDegrees = 40;
/// <summary>
/// NPCs within this distance from the player can be targeted by the minion, if there is line of sight between it and the player.
/// </summary>
public float targetMaxDist = 240f;
public float TargetMaxDistSquared => targetMaxDist * targetMaxDist;
/// <summary>
/// NPCs within this distance from the player can be targeted by the minion, regardless of line of sight.
/// </summary>
public float targetThroughWallDist = 80f;
public float TargetThroughWallDistSquared => targetThroughWallDist * targetThroughWallDist;
/// <summary>
/// The knockback of Spirit Flame.
/// </summary>
public float knockback = 0f;
/// <summary>
/// Starting homing strength of Spirit Flame.
/// </summary>
internal float homingStrengthStart = 0.08f;
/// <summary>
/// Rate to increase homing strength every frame after <see cref="homingIncreaseDelay"/>.
/// </summary>
internal float homingIncreaseRate = 0.05f;
/// <summary>
/// Ticks to wait before increasing homing strength by <see cref="homingIncreaseRate"/>.
/// </summary>
internal int homingIncreaseDelay = 12;
/// <summary>
/// Speed of Spirit Flame when it is fired.
/// </summary>
internal float projectileSpeedStart = 7.5f;
/// <summary>
/// Acceleration of Spirit Flame after waiting for <see cref="projectileSpeedIncreaseDelay"/>.
/// </summary>
internal float projectileSpeedIncreaseRate = 0.5f;
/// <summary>
/// Time to wait before increasing Spirit Flame speed by <see cref="projectileSpeedIncreaseRate"/>.
/// </summary>
internal int projectileSpeedIncreaseDelay = 8;
internal int seinWidth = 10;
internal int seinHeight = 11;
internal int spiritFlameWidth = 12;
internal int spiritFlameHeight = 12;
/// <summary>
/// The size of the dust trail emitted from Spirit Flame.
/// </summary>
public float dustScale = 1.65f;
/// <summary>
/// Rarity of the Spirit Orb.
/// </summary>
internal int rarity = 1;
/// <summary>
/// Buy value of the Spirit Orb.
/// </summary>
internal int value = 1000;
/// <summary>
/// Color of the Spirit Orb, Sein, Spirit Flame, and emitted lights.
/// </summary>
internal Color color = Color.White;
/// <summary>
/// Strength of the light emitted from Sein and Spirit Flame.
/// </summary>
internal float lightStrength;
internal string CalculateStuff(string tierName) {
int minShotsPerBurst = shotsToPrimaryTarget;
int minDmgPerBurst = damage * minShotsPerBurst;
int minDmgPerAllBursts = minDmgPerBurst * bursts;
int maxShotsPerBurst = Math.Min(shotsToPrimaryTarget + shotsPerTarget * (targets - 1), maxShotsAtOnce);
int maxDmgPerBurst = damage * maxShotsPerBurst;
int maxDmgPerAllBursts = maxDmgPerBurst * bursts;
int minDps = minDmgPerAllBursts * 60 / (cooldownMin * bursts + cooldownLong);
int maxDps = maxDmgPerAllBursts * 60 / (cooldownMin * bursts + cooldownLong);
return minShotsPerBurst == maxShotsPerBurst
? $"Sein ({tierName}): DPS:{minDps}, Shots:{minShotsPerBurst} Bursts:{bursts} DMG per Burst:{minDmgPerBurst}, DMG per all Bursts:{minDmgPerAllBursts}"
: $"Sein ({tierName}): DPS:{minDps}-{maxDps}, Shots:{minShotsPerBurst}-{maxShotsPerBurst} Bursts:{bursts} DMG per Burst:{minDmgPerBurst}-{maxDmgPerBurst}, DMG per all Bursts:{minDmgPerAllBursts}-{maxDmgPerAllBursts}";
}
#endregion
}