2 using Microsoft.Xna.Framework;
3 using Microsoft.Xna.Framework.Graphics;
9 partial class Gap : MapEntity
11 private float particleTimer;
26 public override void Draw(SpriteBatch sb,
bool editing,
bool back =
true)
28 float depth = (
ID % 255) * 0.000001f;
37 if (
Submarine !=
null && outsideCollisionBlocker !=
null && outsideCollisionBlocker.Enabled)
39 var edgeShape = outsideCollisionBlocker.FixtureList[0].Shape as FarseerPhysics.Collision.Shapes.EdgeShape;
40 Vector2 startPos = ConvertUnits.ToDisplayUnits(outsideCollisionBlocker.GetWorldPoint(edgeShape.Vertex1)) +
Submarine.
Position;
41 Vector2 endPos = ConvertUnits.ToDisplayUnits(outsideCollisionBlocker.GetWorldPoint(edgeShape.Vertex2)) +
Submarine.
Position;
42 startPos.Y = -startPos.Y;
44 GUI.DrawLine(sb, startPos, endPos, Color.Gray, 0, 5);
50 Color clr = (open == 0.0f) ? GUIStyle.Red : Color.Cyan;
55 clr * 0.2f,
true, depth);
63 clr * 0.6f, width: lineWidth);
67 clr * 0.6f, width: lineWidth);
74 clr * 0.6f, width: lineWidth);
78 clr * 0.6f, width: lineWidth);
83 for (
int i = 0; i <
linkedTo.Count; i++)
87 DrawArrow(hull, 32.0f, 15f, clr);
92 void DrawArrow(
Hull targetHull,
float arrowWidth,
float arrowLength, Color clr)
95 new Vector2(Math.Sign(targetHull.
Rect.Center.X -
rect.Center.X), 0.0f)
96 :
new Vector2(0.0f, Math.Sign((
rect.Y -
rect.Height / 2.0f) - (targetHull.
Rect.Y - targetHull.
Rect.Height / 2.0f)));
99 arrowPos +=
new Vector2(dir.X * (
WorldRect.Width / 2), dir.Y * (
WorldRect.Height / 2));
101 bool invalidDir =
false;
102 if (dir == Vector2.Zero)
109 arrowPos, invalidDir ? Color.Red : clr * 0.8f,
110 GUI.Arrow.Origin, MathUtils.VectorToAngle(dir) + MathHelper.PiOver2,
112 new Vector2(Math.Min(
rect.Height, arrowWidth) / GUI.Arrow.size.X, arrowLength / GUI.Arrow.size.Y) :
113 new Vector2(Math.Min(
rect.Width, arrowWidth) / GUI.Arrow.size.X, arrowLength / GUI.Arrow.size.Y),
114 SpriteEffects.None, depth);
119 GUI.DrawRectangle(sb,
121 new Vector2(
rect.Width + 10,
rect.Height + 10),
129 partial
void EmitParticles(
float deltaTime)
131 if (flowTargetHull ==
null) {
return; }
136 if (hull1.linkedTo.Contains(hull2)) {
return; }
137 foreach (var linkedEntity
in hull1.linkedTo)
139 if (linkedEntity is Hull h && h.linkedTo.Contains(hull1) && h.linkedTo.Contains(hull2)) {
return; }
141 foreach (var linkedEntity
in hull2.linkedTo)
143 if (linkedEntity is Hull h && h.linkedTo.Contains(hull1) && h.linkedTo.Contains(hull2)) {
return; }
150 pos.X += Math.Sign(flowForce.X);
151 pos.Y = MathHelper.Clamp(Rand.Range(higherSurface, lowerSurface),
rect.Y -
rect.Height,
rect.Y);
153 if (flowTargetHull !=
null)
155 pos.X = MathHelper.Clamp(pos.X, flowTargetHull.
Rect.X + 1, flowTargetHull.
Rect.Right - 1);
156 pos.Y = MathHelper.Clamp(pos.Y, flowTargetHull.
Rect.Y - flowTargetHull.
Rect.Height + 1, flowTargetHull.
Rect.Y - 1);
160 float particleAmountMultiplier = 1.0f - GameMain.ParticleManager.ParticleCount / (float)GameMain.ParticleManager.MaxParticles;
161 particleAmountMultiplier *= particleAmountMultiplier;
166 particleTimer += deltaTime;
169 float particlesPerSec = open *
rect.Height * 0.1f * particleAmountMultiplier;
170 if (openedTimer > 0.0f) { particlesPerSec *= 1.0f + openedTimer * 10.0f; }
171 float emitInterval = 1.0f / particlesPerSec;
172 while (particleTimer > emitInterval)
174 Vector2 velocity =
new Vector2(
175 MathHelper.Clamp(flowForce.X, -5000.0f, 5000.0f) * Rand.Range(0.5f, 0.7f),
176 flowForce.Y * Rand.Range(0.5f, 0.7f));
180 var particle = GameMain.ParticleManager.CreateParticle(
183 velocity, 0, flowTargetHull);
184 if (particle !=
null)
186 if (particle.CurrentHull ==
null) { GameMain.ParticleManager.RemoveParticle(particle); }
187 particle.Size *= Math.Min(Math.Abs(flowForce.X / 500.0f), 5.0f);
191 CreateWaterSpatter();
195 if (Math.Abs(flowForce.X) > 300.0f && flowTargetHull.
WaterVolume > flowTargetHull.
Volume * 0.1f)
197 pos.X += Math.Sign(flowForce.X) * 10.0f;
198 if (
rect.Height < 32)
204 float bottomY =
rect.Y -
rect.Height + 16;
205 float topY = MathHelper.Clamp(lowerSurface, bottomY,
rect.Y - 16);
206 pos.Y = Rand.Range(bottomY, topY);
208 GameMain.ParticleManager.CreateParticle(
211 velocity, 0, flowTargetHull);
213 particleTimer -= emitInterval;
222 float particlesPerSec = Math.Max(open *
rect.Width * particleAmountMultiplier, 10.0f);
223 float emitInterval = 1.0f / particlesPerSec;
224 while (particleTimer > emitInterval)
227 Vector2 velocity =
new Vector2(
228 lerpedFlowForce.X * Rand.Range(0.5f, 0.7f),
229 MathHelper.Clamp(lerpedFlowForce.Y, -500.0f, 1000.0f) * Rand.Range(0.5f, 0.7f));
233 var splash = GameMain.ParticleManager.CreateParticle(
239 if (splash.CurrentHull ==
null) { GameMain.ParticleManager.RemoveParticle(splash); }
240 splash.Size *= MathHelper.Clamp(
rect.Width / 50.0f, 1.5f, 4.0f);
244 CreateWaterSpatter();
247 if (Math.Abs(flowForce.Y) > 190.0f && Rand.Range(0.0f, 1.0f) < 0.3f && flowTargetHull.
WaterVolume > flowTargetHull.
Volume * 0.1f)
249 GameMain.ParticleManager.CreateParticle(
254 particleTimer -= emitInterval;
263 particleTimer += deltaTime;
264 float particlesPerSec = open * 10.0f * particleAmountMultiplier;
265 float emitInterval = 1.0f / particlesPerSec;
266 while (particleTimer > emitInterval)
268 Vector2 velocity = flowForce;
271 velocity.X *= Rand.Range(1.0f, 3.0f);
276 GameMain.ParticleManager.CreateParticle(
277 Rand.Range(0.0f, open) < 0.05f ?
"waterdrop" :
"watersplash",
279 velocity, 0, flowTargetHull);
280 CreateWaterSpatter();
283 GameMain.ParticleManager.CreateParticle(
286 velocity, 0, flowTargetHull);
288 particleTimer -= emitInterval;
293 particleTimer = 0.0f;
296 void CreateWaterSpatter()
298 Vector2 spatterPos = pos;
303 spatterPos.Y =
rect.Y -
rect.Height / 2;
307 rotation =
LerpedFlowForce.Y > 0 ? -MathHelper.PiOver2 : MathHelper.PiOver2;
308 spatterPos.X =
rect.Center.X;
310 var spatter = GameMain.ParticleManager.CreateParticle(
313 Vector2.Zero, rotation, flowTargetHull);
316 if (spatter.CurrentHull ==
null) { GameMain.ParticleManager.RemoveParticle(spatter); }
317 spatter.Size *= MathHelper.Clamp(
LerpedFlowForce.Length() / 200.0f, 0.5f, 1.0f);
334 private GUIComponent CreateEditingHUD(
bool inGame =
false)
344 AbsoluteSpacing = (int)(GUI.Scale * 5)
347 new GUITextBlock(
new RectTransform(
new Vector2(1.0f, 0.2f), paddedFrame.RectTransform), TextManager.Get(
"entityname.gap"), font: GUIStyle.LargeFont);
348 var hiddenInGameTickBox =
new GUITickBox(
new RectTransform(
new Vector2(0.5f, 1.0f), paddedFrame.RectTransform), TextManager.Get(
"sp.hiddeningame.name"))
352 hiddenInGameTickBox.OnSelected += (GUITickBox tickbox) =>
359 (
int)(paddedFrame.Children.Sum(c => c.Rect.Height + paddedFrame.AbsoluteSpacing) / paddedFrame.RectTransform.RelativeSize.Y * 1.25f)));
virtual Vector2 WorldPosition
readonly ushort ID
Unique, but non-persistent identifier. Stays the same if the entities are created in the exactly same...
RectTransform RectTransform
static SubEditorScreen SubEditorScreen
override bool SelectableInEditor
override void Draw(SpriteBatch sb, bool editing, bool back=true)
override bool IsVisible(Rectangle worldView)
override void UpdateEditing(Camera cam, float deltaTime)
static GUIComponent editingHUD
static void PositionEditingHUD()
override Vector2 Position
readonly List< MapEntity > linkedTo
static bool IsLayerVisible(MapEntity entity)
override Vector2? Position