public Decal(DecalPrefab prefab, float scale, Vector2 worldPosition, Hull hull, int?spriteIndex = null) { Prefab = prefab; this.hull = hull; //transform to hull-relative coordinates so we don't have to worry about the hull moving NonClampedPosition = position = worldPosition - hull.WorldRect.Location.ToVector2(); Vector2 drawPos = position + hull.Rect.Location.ToVector2(); SpriteIndex = spriteIndex ?? Rand.Range(0, prefab.Sprites.Count, Rand.RandSync.Unsynced); Sprite = prefab.Sprites[SpriteIndex]; Color = prefab.Color; Rectangle drawRect = new Rectangle( (int)(drawPos.X - Sprite.size.X / 2 * scale), (int)(drawPos.Y + Sprite.size.Y / 2 * scale), (int)(Sprite.size.X * scale), (int)(Sprite.size.Y * scale)); Rectangle overFlowAmount = new Rectangle( (int)Math.Max(hull.Rect.X - drawRect.X, 0.0f), (int)Math.Max(drawRect.Y - hull.Rect.Y, 0.0f), (int)Math.Max(drawRect.Right - hull.Rect.Right, 0.0f), (int)Math.Max((hull.Rect.Y - hull.Rect.Height) - (drawRect.Y - drawRect.Height), 0.0f)); clippedSourceRect = new Rectangle( Sprite.SourceRect.X + (int)(overFlowAmount.X / scale), Sprite.SourceRect.Y + (int)(overFlowAmount.Y / scale), Sprite.SourceRect.Width - (int)((overFlowAmount.X + overFlowAmount.Width) / scale), Sprite.SourceRect.Height - (int)((overFlowAmount.Y + overFlowAmount.Height) / scale)); CenterPosition = position; position -= new Vector2(Sprite.size.X / 2 * scale - overFlowAmount.X, -Sprite.size.Y / 2 * scale + overFlowAmount.Y); this.Scale = scale; foreach (BackgroundSection section in hull.GetBackgroundSectionsViaContaining(new Rectangle((int)position.X, (int)position.Y - drawRect.Height, drawRect.Width, drawRect.Height))) { affectedSections ??= new HashSet <BackgroundSection>(); affectedSections.Add(section); } }