private void DrawBlip(SpriteBatch spriteBatch, RadarBlip blip, Vector2 center, float strength) { strength = MathHelper.Clamp(strength, 0.0f, 1.0f); float scaledT = strength * (blipColorGradient.Length - 1); Color color = Color.Lerp(blipColorGradient[(int)scaledT], blipColorGradient[(int)Math.Min(scaledT + 1, blipColorGradient.Length - 1)], (scaledT - (int)scaledT)); Vector2 pos = (blip.Position - item.WorldPosition) * displayScale; pos.Y = -pos.Y; float posDist = pos.Length(); if (posDist > displayRadius) { blip.FadeTimer = 0.0f; return; } if (radarBlip == null) { GUI.DrawRectangle(spriteBatch, center + pos, Vector2.One * 4, Color.Magenta, true); return; } Vector2 dir = pos / posDist; Vector2 normal = new Vector2(dir.Y, -dir.X); float scale = (strength + 3.0f) * blip.Scale; radarBlip.Draw(spriteBatch, center + pos, color, radarBlip.Origin, MathUtils.VectorToAngle(pos), new Vector2(scale * 0.5f, scale) * 0.04f, SpriteEffects.None, 0); pos += Rand.Range(0.0f, 1.0f) * dir + Rand.Range(-scale, scale) * normal; radarBlip.Draw(spriteBatch, center + pos, color * 0.5f, radarBlip.Origin, 0, scale * 0.08f, SpriteEffects.None, 0); }
private void CreateBlipsForLine(Vector2 point1, Vector2 point2, float pingRadius, float prevPingRadius, float lineStep, float zStep, float range, float pingStrength) { float length = (point1 - point2).Length(); Vector2 lineDir = (point2 - point1) / length; range *= displayScale; for (float x = 0; x < length; x += lineStep * Rand.Range(0.8f, 1.2f)) { Vector2 point = point1 + lineDir * x; //point += cell.Translation; float pointDist = Vector2.Distance(item.WorldPosition, point) * displayScale; if (pointDist > displayRadius) { continue; } if (pointDist < prevPingRadius || pointDist > pingRadius) { continue; } float alpha = pingStrength * Rand.Range(1.5f, 2.0f); for (float z = 0; z < displayRadius - pointDist * displayScale; z += zStep) { Vector2 pos = point + Rand.Vector(150.0f) + Vector2.Normalize(point - item.WorldPosition) * z / displayScale; float fadeTimer = alpha * (1.0f - pointDist / range); int minDist = 200; radarBlips.RemoveAll(b => b.FadeTimer < fadeTimer && Math.Abs(pos.X - b.Position.X) < minDist && Math.Abs(pos.Y - b.Position.Y) < minDist); var blip = new RadarBlip(pos, fadeTimer); radarBlips.Add(blip); zStep += 0.5f; if (z == 0) { alpha = Math.Min(alpha - 0.5f, 1.5f); } else { alpha -= 0.1f; } if (alpha < 0) { break; } } } }
private void DrawBlip(SpriteBatch spriteBatch, RadarBlip blip, Vector2 center, float strength) { strength = MathHelper.Clamp(strength, 0.0f, 1.0f); Color[] colors = new Color[] { Color.TransparentBlack, new Color(0, 50, 160), new Color(0, 133, 166), new Color(2, 159, 30), new Color(255, 255, 255) }; float scaledT = strength * (colors.Length - 1); Color color = Color.Lerp(colors[(int)scaledT], colors[(int)Math.Min(scaledT + 1, colors.Length - 1)], (scaledT - (int)scaledT)); Vector2 pos = (blip.Position - item.WorldPosition) * displayScale; pos.Y = -pos.Y; if (pos.Length() > displayRadius) { blip.FadeTimer = 0.0f; return; } float posDist = pos.Length(); Vector2 dir = pos / posDist; float distFactor = (posDist / displayRadius); Vector2 normal = new Vector2(dir.Y, -dir.X); float scale = (strength + 3.0f) * Math.Max(distFactor * 3.0f, 1.0f); if (radarBlip == null) { GUI.DrawRectangle(spriteBatch, center + pos, Vector2.One * 4, Color.Magenta, true); return; } radarBlip.Draw(spriteBatch, center + pos, color, radarBlip.Origin, MathUtils.VectorToAngle(pos), new Vector2(scale * 0.3f, scale) * 0.04f, SpriteEffects.None, 0); pos += Rand.Range(0.0f, 1.0f) * dir + Rand.Range(-scale, scale) * normal; radarBlip.Draw(spriteBatch, center + pos, color * 0.5f, radarBlip.Origin, MathUtils.VectorToAngle(pos), new Vector2(scale * 0.3f, scale) * 0.08f, SpriteEffects.None, 0); }
private void Ping(Vector2 pingSource, float pingRadius, float prevPingRadius, float displayScale, float range, float pingStrength = 1.0f) { foreach (Submarine submarine in Submarine.Loaded) { if (item.Submarine == submarine && !DetectSubmarineWalls) { continue; } if (item.Submarine != null && item.Submarine.DockedTo.Contains(submarine)) { continue; } if (submarine.HullVertices == null) { continue; } for (int i = 0; i < submarine.HullVertices.Count; i++) { Vector2 start = ConvertUnits.ToDisplayUnits(submarine.HullVertices[i]); Vector2 end = ConvertUnits.ToDisplayUnits(submarine.HullVertices[(i + 1) % submarine.HullVertices.Count]); if (item.Submarine == submarine) { start += Rand.Vector(500.0f); end += Rand.Vector(500.0f); } CreateBlipsForLine( start + submarine.WorldPosition, end + submarine.WorldPosition, pingRadius, prevPingRadius, 200.0f, 2.0f, range, 1.0f); } } if (Level.Loaded != null && (item.CurrentHull == null || !DetectSubmarineWalls)) { if (Level.Loaded.Size.Y - pingSource.Y < range) { CreateBlipsForLine( new Vector2(pingSource.X - range, Level.Loaded.Size.Y), new Vector2(pingSource.X + range, Level.Loaded.Size.Y), pingRadius, prevPingRadius, 250.0f, 150.0f, range, pingStrength); } List <VoronoiCell> cells = Level.Loaded.GetCells(pingSource, 7); foreach (VoronoiCell cell in cells) { foreach (GraphEdge edge in cell.edges) { if (!edge.isSolid) { continue; } float cellDot = Vector2.Dot(cell.Center - pingSource, (edge.Center + cell.Translation) - cell.Center); if (cellDot > 0) { continue; } float facingDot = Vector2.Dot( Vector2.Normalize(edge.point1 - edge.point2), Vector2.Normalize(cell.Center - pingSource)); CreateBlipsForLine( edge.point1 + cell.Translation, edge.point2 + cell.Translation, pingRadius, prevPingRadius, 350.0f, 3.0f * (Math.Abs(facingDot) + 1.0f), range, pingStrength); } } foreach (RuinGeneration.Ruin ruin in Level.Loaded.Ruins) { if (!MathUtils.CircleIntersectsRectangle(pingSource, range, ruin.Area)) { continue; } foreach (var ruinShape in ruin.RuinShapes) { foreach (RuinGeneration.Line wall in ruinShape.Walls) { float cellDot = Vector2.Dot( Vector2.Normalize(ruinShape.Center - pingSource), Vector2.Normalize((wall.A + wall.B) / 2.0f - ruinShape.Center)); if (cellDot > 0) { continue; } CreateBlipsForLine( wall.A, wall.B, pingRadius, prevPingRadius, 100.0f, 1000.0f, range, pingStrength); } } } } foreach (Character c in Character.CharacterList) { if (c.AnimController.CurrentHull != null || !c.Enabled) { continue; } if (DetectSubmarineWalls && c.AnimController.CurrentHull == null && item.CurrentHull != null) { continue; } foreach (Limb limb in c.AnimController.Limbs) { float pointDist = (limb.WorldPosition - pingSource).Length() * displayScale; if (limb.SimPosition == Vector2.Zero || pointDist > displayRadius) { continue; } if (pointDist > prevPingRadius && pointDist < pingRadius) { for (int i = 0; i <= limb.Mass / 100.0f; i++) { var blip = new RadarBlip(limb.WorldPosition + Rand.Vector(limb.Mass / 10.0f), MathHelper.Clamp(limb.Mass, 0.1f, pingStrength)); radarBlips.Add(blip); } } } } }