protected virtual Vector2 DoSteeringAvoid(float deltaTime, float lookAheadDistance, float weight, Vector2?heading = null) { if (steering == Vector2.Zero || host.Steering == Vector2.Zero) { return(Vector2.Zero); } float maxDistance = lookAheadDistance; if (Timing.TotalTime >= lastRayCastTime + RayCastInterval) { avoidRayCastHit = false; AvoidLookAheadPos = host.SimPosition + Vector2.Normalize(host.Steering) * maxDistance; lastRayCastTime = (float)Timing.TotalTime; Body closestBody = Submarine.CheckVisibility(host.SimPosition, AvoidLookAheadPos); if (closestBody != null) { avoidRayCastHit = true; AvoidRayCastHitPosition = Submarine.LastPickedPosition; AvoidDir = Submarine.LastPickedNormal; //add a bit of randomness AvoidDir = MathUtils.RotatePoint(AvoidDir, Rand.Range(-0.15f, 0.15f)); //wait a bit longer for the next raycast lastRayCastTime += RayCastInterval; } } if (AvoidDir.LengthSquared() < 0.0001f) { return(Vector2.Zero); } //if raycast hit nothing, lerp avoid dir to zero if (!avoidRayCastHit) { AvoidDir -= Vector2.Normalize(AvoidDir) * deltaTime * 0.5f; } Vector2 diff = AvoidRayCastHitPosition - host.SimPosition; float dist = diff.Length(); //> 0 when heading in the same direction as the obstacle, < 0 when away from it float dot = MathHelper.Clamp(Vector2.Dot(diff / dist, host.Steering), 0.0f, 1.0f); if (dot < 0) { return(Vector2.Zero); } return(AvoidDir * dot * weight * MathHelper.Clamp(1.0f - dist / lookAheadDistance, 0.0f, 1.0f)); }
private void BakeItemComponents( ItemPrefab prefab, Rectangle rect, Color color, float scale, float rotation, float depth, out bool overrideSprite) { overrideSprite = false; foreach (var subElement in prefab.ConfigElement.Elements()) { switch (subElement.Name.LocalName.ToLowerInvariant()) { case "turret": Sprite barrelSprite = null; Sprite railSprite = null; foreach (XElement turretSubElem in subElement.Elements()) { switch (turretSubElem.Name.ToString().ToLowerInvariant()) { case "barrelsprite": barrelSprite = new Sprite(turretSubElem); break; case "railsprite": railSprite = new Sprite(turretSubElem); break; } } Vector2 barrelPos = subElement.GetAttributeVector2("barrelpos", Vector2.Zero); Vector2 relativeBarrelPos = barrelPos * prefab.Scale - new Vector2(rect.Width / 2, rect.Height / 2); var transformedBarrelPos = MathUtils.RotatePoint( relativeBarrelPos, MathHelper.ToRadians(rotation)); float relativeScale = scale / prefab.Scale; Vector2 drawPos = new Vector2(rect.X + rect.Width * relativeScale / 2 + transformedBarrelPos.X * relativeScale, rect.Y - rect.Height * relativeScale / 2 - transformedBarrelPos.Y * relativeScale); drawPos.Y = -drawPos.Y; railSprite?.Draw(spriteRecorder, drawPos, color, rotation + MathHelper.PiOver2, scale, SpriteEffects.None, depth + (railSprite.Depth - prefab.sprite.Depth)); barrelSprite?.Draw(spriteRecorder, drawPos, color, rotation + MathHelper.PiOver2, scale, SpriteEffects.None, depth + (barrelSprite.Depth - prefab.sprite.Depth)); break; case "door": doors.Add(new Door(rect)); var doorSpriteElem = subElement.Elements().FirstOrDefault(e => e.Name.LocalName.Equals("sprite", StringComparison.OrdinalIgnoreCase)); if (doorSpriteElem != null) { string texturePath = doorSpriteElem.GetAttributeString("texture", ""); Vector2 pos = rect.Location.ToVector2() * new Vector2(1f, -1f); if (subElement.GetAttributeBool("horizontal", false)) { pos.Y += (float)rect.Height * 0.5f; } else { pos.X += (float)rect.Width * 0.5f; } Sprite doorSprite = new Sprite(doorSpriteElem, texturePath.Contains("/") ? "" : Path.GetDirectoryName(prefab.FilePath)); spriteRecorder.Draw(doorSprite.Texture, pos, new Rectangle((int)doorSprite.SourceRect.X, (int)doorSprite.SourceRect.Y, (int)doorSprite.size.X, (int)doorSprite.size.Y), color, 0.0f, doorSprite.Origin, new Vector2(scale), SpriteEffects.None, doorSprite.Depth); } break; case "ladder": var backgroundSprElem = subElement.Elements().FirstOrDefault(e => e.Name.LocalName.Equals("backgroundsprite", StringComparison.OrdinalIgnoreCase)); if (backgroundSprElem != null) { Sprite backgroundSprite = new Sprite(backgroundSprElem); backgroundSprite.DrawTiled(spriteRecorder, new Vector2(rect.Left, -rect.Top) - backgroundSprite.Origin * scale, new Vector2(backgroundSprite.size.X * scale, rect.Height), color: color, textureScale: Vector2.One * scale, depth: depth + 0.1f); } break; } } }