XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet

DeathMod

【Terraria】DeathMod (now aka Soul Harvest)

公开
关注 0 Fork 0 Star 0
返回提交历史

XFEstudio/DeathMod

实现满级全屏领域与全图斩击

b8fcdfb
XFE工作室室长 <mail@xfegzs.com>
提交于

代码差异

2 个文件 +46 -75
Modified Common/DeathDomainVisualSystem.cs +43 -72
@@ -82,10 +82,6 @@ internal class DeathDomainVisualSystem : ModSystem
82 82
83 83 SpriteBatch batch = Main.spriteBatch;
84 84 Texture2D pixel = TextureAssets.MagicPixel.Value;
85 float localAnimation = domainAnimation[Main.myPlayer];
86 if (cachedFullScreen[Main.myPlayer] && localAnimation > 0.001f)
87 DrawSovereignBackground(batch, pixel, localAnimation);
88
89 85 batch.Begin(
90 86 SpriteSortMode.Deferred,
91 87 BlendState.AlphaBlend,
@@ -124,35 +120,6 @@ internal class DeathDomainVisualSystem : ModSystem
124 120 batch.End();
125 121 }
126 122
127 private static void DrawSovereignBackground(SpriteBatch batch, Texture2D pixel, float animation)
128 {
129 batch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, SamplerState.PointClamp, DepthStencilState.None, RasterizerState.CullNone);
130 float time = Main.GlobalTimeWrappedHourly;
131 float reveal = MathHelper.SmoothStep(0f, 1f, animation);
132 batch.Draw(pixel, new Rectangle(0, 0, Main.screenWidth, Main.screenHeight), new Color(8, 2, 18) * (0.42f * reveal));
133 batch.Draw(pixel, new Rectangle(0, 0, Main.screenWidth, Main.screenHeight / 2), new Color(28, 8, 55) * (0.18f * reveal));
134
135 for (int index = 0; index < 54; index++)
136 {
137 float seed = index * 73.31f;
138 float x = PositiveModulo(seed * 17f + time * (18f + index % 7 * 3f), Main.screenWidth + 120f) - 60f;
139 float y = PositiveModulo(seed * 11f - time * (9f + index % 5 * 2f), Main.screenHeight + 100f) - 50f;
140 float pulse = 0.45f + (float)Math.Sin(time * 2.4f + seed) * 0.25f;
141 Color color = index % 3 == 0 ? new Color(215, 30, 105) : new Color(65, 205, 245);
142 float length = 7f + index % 6 * 3f;
143 batch.Draw(pixel, new Vector2(x, y), null, color * (pulse * reveal), -0.7f, Vector2.Zero,
144 new Vector2(length / pixel.Width, 1.2f / pixel.Height), SpriteEffects.None, 0f);
145 }
146
147 Vector2 center = new(Main.screenWidth * 0.5f, Main.screenHeight * 0.5f);
148 for (int ring = 0; ring < 3; ring++)
149 {
150 float radius = Math.Min(Main.screenWidth, Main.screenHeight) * (0.22f + ring * 0.12f);
151 DrawCircle(batch, pixel, center, radius, 72, new Color(80 + ring * 25, 65, 155 + ring * 25) * ((0.12f - ring * 0.02f) * reveal), 2f, time * (ring % 2 == 0 ? 0.12f : -0.09f));
152 }
153 batch.End();
154 }
155
156 123 private static void DrawDomainRing(SpriteBatch batch, Texture2D pixel, Vector2 center, float targetRadius, int mastery, float animation)
157 124 {
158 125 float time = Main.GlobalTimeWrappedHourly;
@@ -223,7 +190,7 @@ internal class DeathDomainVisualSystem : ModSystem
223 190 float reveal)
224 191 {
225 192 const int boundarySegments = 192;
226 const float preferredBandHeight = 2f;
193 float preferredBandHeight = MathHelper.Clamp(baseRadius / 280f, 2f, 8f);
227 194 Span<Vector2> boundary = stackalloc Vector2[boundarySegments];
228 195 float extent = 0f;
229 196 for (int index = 0; index < boundarySegments; index++)
@@ -255,7 +222,12 @@ internal class DeathDomainVisualSystem : ModSystem
255 222 float viewWidth = texture.Width * horizontalViewFraction;
256 223 float viewHeight = texture.Height * verticalViewFraction;
257 224 float sourceOffsetX = PositiveModulo(worldCenter.X * parallax, texture.Width);
258 float sourceOffsetY = PositiveModulo(worldCenter.Y * parallax, texture.Height);
225 // Vertical sampling traverses the source image only once over the full
226 // world depth. It never wraps across the top/bottom texture edge, so a
227 // second horizon or mountain range cannot be spliced into the domain.
228 float worldHeight = Math.Max(1f, Main.maxTilesY * 16f);
229 float worldDepth = MathHelper.Clamp(worldCenter.Y / worldHeight, 0f, 1f);
230 float sourceOffsetY = worldDepth * Math.Max(0f, texture.Height - viewHeight);
259 231
260 232 for (int index = 0; index < bands; index++)
261 233 {
@@ -312,42 +284,34 @@ internal class DeathDomainVisualSystem : ModSystem
312 284 if (destinationWidth <= 0.05f || destinationHeight <= 0.05f || opacity <= 0.001f)
313 285 return;
314 286
315 float remainingSourceHeight = sourceHeight;
316 float consumedSourceHeight = 0f;
317 float wrappedSourceY = PositiveModulo(sourceY, texture.Height);
318 while (remainingSourceHeight > 0.001f)
319 {
320 float sourceHeightPart = Math.Min(remainingSourceHeight, texture.Height - wrappedSourceY);
321 float destinationHeightPart = destinationHeight * sourceHeightPart / sourceHeight;
322 float destinationY = destination.Y + destinationHeight * consumedSourceHeight / sourceHeight;
323 float remainingSourceWidth = sourceWidth;
324 float consumedSourceWidth = 0f;
325 float wrappedSourceX = PositiveModulo(sourceX, texture.Width);
326 while (remainingSourceWidth > 0.001f)
327 {
328 float sourceWidthPart = Math.Min(remainingSourceWidth, texture.Width - wrappedSourceX);
329 float destinationWidthPart = destinationWidth * sourceWidthPart / sourceWidth;
330 float destinationX = destination.X + destinationWidth * consumedSourceWidth / sourceWidth;
331 DrawBackdropPart(
332 batch,
333 texture,
334 new Vector2(destinationX, destinationY),
335 destinationWidthPart,
336 destinationHeightPart,
337 wrappedSourceX,
338 wrappedSourceY,
339 sourceWidthPart,
340 sourceHeightPart,
341 opacity);
342
343 remainingSourceWidth -= sourceWidthPart;
344 consumedSourceWidth += sourceWidthPart;
345 wrappedSourceX = 0f;
346 }
287 float clampedSourceY = MathHelper.Clamp(sourceY, 0f, texture.Height - 0.001f);
288 float clampedSourceHeight = Math.Min(sourceHeight, texture.Height - clampedSourceY);
289 if (clampedSourceHeight <= 0.001f)
290 return;
347 291
348 remainingSourceHeight -= sourceHeightPart;
349 consumedSourceHeight += sourceHeightPart;
350 wrappedSourceY = 0f;
292 float remainingSourceWidth = sourceWidth;
293 float consumedSourceWidth = 0f;
294 float wrappedSourceX = PositiveModulo(sourceX, texture.Width);
295 while (remainingSourceWidth > 0.001f)
296 {
297 float sourceWidthPart = Math.Min(remainingSourceWidth, texture.Width - wrappedSourceX);
298 float destinationWidthPart = destinationWidth * sourceWidthPart / sourceWidth;
299 float destinationX = destination.X + destinationWidth * consumedSourceWidth / sourceWidth;
300 DrawBackdropPart(
301 batch,
302 texture,
303 new Vector2(destinationX, destination.Y),
304 destinationWidthPart,
305 destinationHeight,
306 wrappedSourceX,
307 clampedSourceY,
308 sourceWidthPart,
309 clampedSourceHeight,
310 opacity);
311
312 remainingSourceWidth -= sourceWidthPart;
313 consumedSourceWidth += sourceWidthPart;
314 wrappedSourceX = 0f;
351 315 }
352 316 }
353 317
@@ -386,7 +350,14 @@ internal class DeathDomainVisualSystem : ModSystem
386 350 float reveal = MathHelper.SmoothStep(0f, 1f, animation);
387 351 float expansion = 1f - (float)Math.Pow(1f - reveal, 3f);
388 352 float pulse = (0.86f + (float)Math.Sin(time * 3.6f) * 0.1f) * reveal;
389 float targetRadius = 142f + (float)Math.Sin(time * 1.7f) * 6f;
353 float farthestX = Math.Max(Math.Abs(center.X), Math.Abs(Main.screenWidth - center.X));
354 float farthestY = Math.Max(Math.Abs(center.Y), Math.Abs(Main.screenHeight - center.Y));
355 // The completed field reaches beyond every screen corner. The extra margin
356 // absorbs the noisy inward edge displacement, keeping the whole viewport
357 // inside the domain even while its boundary ripples.
358 float targetRadius = (float)Math.Sqrt(farthestX * farthestX + farthestY * farthestY)
359 + 56f
360 + (float)Math.Sin(time * 1.7f) * 6f;
390 361 float radius = MathHelper.Lerp(8f, targetRadius, expansion) * (1f + (float)Math.Sin(reveal * MathHelper.Pi) * 0.035f);
391 362 float masteryProgress = GetMasteryProgress(mastery);
392 363 DrawBlackHoleField(batch, pixel, center, radius, masteryProgress, pulse, time, reveal);
@@ -419,7 +390,7 @@ internal class DeathDomainVisualSystem : ModSystem
419 390 Color color)
420 391 {
421 392 const int boundarySegments = 192;
422 const float preferredBandHeight = 3f;
393 float preferredBandHeight = MathHelper.Clamp(baseRadius / 240f, 3f, 9f);
423 394 Span<Vector2> boundary = stackalloc Vector2[boundarySegments];
424 395 float extent = 0f;
425 396 for (int index = 0; index < boundarySegments; index++)
Modified Common/MyPlayer.cs +3 -3
@@ -665,8 +665,8 @@ public class MyPlayer : ModPlayer
665 665 {
666 666 List<NPC> targets = [];
667 667 HashSet<int> selectedTargets = [];
668 float radius = necklace.IsFullScreenDomain ? 3200f : necklace.DomainRadius;
669 float radiusSquared = radius * radius;
668 bool harvestEntireWorld = necklace.IsFullScreenDomain;
669 float radiusSquared = necklace.DomainRadius * necklace.DomainRadius;
670 670 foreach (NPC npc in Main.ActiveNPCs)
671 671 {
672 672 // chaseable is intentionally not used: vanilla NPCs toggle it during
@@ -680,7 +680,7 @@ public class MyPlayer : ModPlayer
680 680 : npc;
681 681 if (target.friendly || target.immortal || target.dontTakeDamage || target.lifeMax <= 5 || target.life <= 0
682 682 || selectedTargets.Contains(target.whoAmI)
683 || Vector2.DistanceSquared(Player.Center, target.Center) > radiusSquared)
683 || !harvestEntireWorld && Vector2.DistanceSquared(Player.Center, target.Center) > radiusSquared)
684 684 {
685 685 continue;
686 686 }