using Godot; namespace FOU.Scripts.Elements; public abstract class Liquid : Element { public const int MAX_VERTICAL_SPREAD = 3; protected Liquid(int x, int y, ref Chunk chunk) : base(x, y, chunk) { MarkForUpdate(); } public override bool Update() { if (!base.Update()) return false; Tick(); return true; // not necessarily end, subclasses could do some more things } protected virtual void Tick() { Vector2I randomDirection = RandomDirectionDown(); if (randomDirection.Y != 0) randomDirection *= Vector2I.Left * (int)(GD.Randi() % MAX_VERTICAL_SPREAD); if (Chunk.IsEmpty(Position + Vector2I.Down)) Chunk.Swap(this, Position + Vector2I.Down); else if (Chunk.IsEmpty(Position + randomDirection)) Chunk.Swap(this, Position + randomDirection); else if (Chunk.IsEmpty(Position + randomDirection * VERTICAL_OPPOSITE)) Chunk.Swap(this, Position + randomDirection * VERTICAL_OPPOSITE); else if (Chunk.IsEmpty(Position + 1 * randomDirection)) Chunk.Swap(this, Position + 1 * randomDirection); else if (Chunk.IsEmpty(Position - 1 * randomDirection * VERTICAL_OPPOSITE)) Chunk.Swap(this, Position - 1 * randomDirection * VERTICAL_OPPOSITE); else if (Chunk.IsEmpty(Position + 2 * randomDirection)) Chunk.Swap(this, Position + 2 * randomDirection); else if (Chunk.IsEmpty(Position - 2 * randomDirection * VERTICAL_OPPOSITE)) Chunk.Swap(this, Position - 2 * randomDirection * VERTICAL_OPPOSITE); } public override void ActivateNeighbors() { Element n = Chunk.Get(Position + Vector2I.Up); if (n != null && !n.IsEmpty()) n.Active = true; // only activate liquids left or right Element e = Chunk.Get(Position + Vector2I.Right); if (e != null && e.GetType() == typeof(Liquid)) e.Active = true; Element s = Chunk.Get(Position + Vector2I.Down); if (null != s && s.GetType() == typeof(Liquid)) s.Active = true; } }