using Godot; namespace FOU.Scripts.Elements; public class Element{ public Chunk Chunk; public Vector2I Position; public int Density; protected int DiffuseSpeed = 10; protected Color color = Colors.Black; protected const int MAX_DIFFUSE_SPEED = 100; protected const int STEPS_UNTIL_INACTIVE = 500; protected static readonly Vector2I VERTICAL_OPPOSITE = new Vector2I(-1, 1); private const float MAX_COLOR_VARIANCE = 0.1f; private bool active = false; private bool markedForUpdate = true; private int lastUpdate = -1; private int lastMove = 0; private Color originalColor; public Element(Element e) { Position = e.Position; Chunk = e.Chunk; Active = e.active; lastMove = e.lastMove; lastUpdate = e.lastUpdate; Chunk.SetElementActive(this, Active); } public Element(int x, int y, Chunk chunk) { Position.X = x; Position.Y = y; Chunk = chunk; lastMove = Engine.GetFramesDrawn(); Chunk.SetElementActive(this, Active); } public bool Active { get => active; set { if (active == value) return; active = value; Chunk.SetElementActive(this, value); if (active) { Moved(); } else { ResetColor(); } } } public Color Color => color; /// /// base update method, checks if anything is to do at all /// /// /// false if there is nothing to do public virtual bool Update() { if (!Active) return false; int frame = Engine.GetFramesDrawn(); if (lastMove + STEPS_UNTIL_INACTIVE < frame) Active = false; if (lastUpdate == frame) return false; // already updated this frame lastUpdate = frame; return true; } public override string ToString() { return $"{GetType()} {Position}[{Chunk.Index}] {active}"; } protected virtual void Tick() { } protected Vector2I RandomDirectionDown() { int randomDirection = GD.Randi() % 2 != 0 ? 1 : -1; return Vector2I.Down // maybe also side + (GD.Randi() % 2 != 0 ? Vector2I.Zero : Vector2I.Right * randomDirection); } /// -1, 0 or 1 protected Vector2I RandomDirection() { int randomDirection = GD.Randi() % 2 != 0 ? 1 : -1; return (GD.Randi() % 2 != 0 ? Vector2I.Zero : Vector2I.Right * randomDirection); } protected Color AddColorVariance(Color baseColor) { Color c = baseColor; c.R += (GD.Randf() - 1) * MAX_COLOR_VARIANCE; c.G += (GD.Randf() - 1) * MAX_COLOR_VARIANCE; c.B += (GD.Randf() - 1) * MAX_COLOR_VARIANCE; originalColor = c; return c; } public void ResetColor() { color = originalColor; MarkForUpdate(); } public void SetDebugColor(Color color) { if (!Main.Instance.DebugMode) return; this.color = color; } public void Moved() { lastMove = Engine.GetFramesDrawn(); MarkForUpdate(); } public bool IsMarkedForUpdate() { return markedForUpdate; } public void MarkForUpdate(bool mark = true) { markedForUpdate = true; } public bool IsEmpty() { return GetType() == typeof(Element); } }