/// @name Snake Auto (Campaign) v1 using System; using System.Linq; // Fixed from your room const long HEAD_ID = 769407982; const int TARGET_KIND = 3666; // Color Tile kind // Pad button IDs (as confirmed by you) const int PAD_TOP_LEFT = 769407085; const int PAD_TOP_RIGHT = 769406820; const int PAD_BOTTOM_LEFT = 769407385; const int PAD_BOTTOM_RIGHT = 769407116; // Direction mapping (tuned for this room) const int CTRL_UP = PAD_TOP_LEFT; const int CTRL_RIGHT = PAD_TOP_RIGHT; const int CTRL_DOWN = PAD_BOTTOM_LEFT; const int CTRL_LEFT = PAD_BOTTOM_RIGHT; DateTime lastCmd = DateTime.MinValue; DateTime lastInfo = DateTime.MinValue; int lastDir = -1; // 0=UP 1=DOWN 2=LEFT 3=RIGHT bool TryGetButton(int dir, out int id, out int x, out int y) { id = dir == 0 ? CTRL_UP : dir == 1 ? CTRL_DOWN : dir == 2 ? CTRL_LEFT : CTRL_RIGHT; var btn = GetFloorItem(id); if (btn == null) { x = 0; y = 0; return false; } x = btn.Location.X; y = btn.Location.Y; return true; } void SendDir(int dir) { if ((DateTime.Now - lastCmd).TotalMilliseconds < 140 && dir == lastDir) return; if (TryGetButton(dir, out int id, out int x, out int y)) { // This game mode reacts when user steps on the plate. Move(x, y); } else { int fallbackId = dir == 0 ? CTRL_UP : dir == 1 ? CTRL_DOWN : dir == 2 ? CTRL_LEFT : CTRL_RIGHT; Send(Out["ClickFurni"], fallbackId, 0); } lastCmd = DateTime.Now; lastDir = dir; } int ToDir(int dx, int dy) { if (Math.Abs(dx) >= Math.Abs(dy)) return dx < 0 ? 2 : 3; return dy < 0 ? 0 : 1; } Log("Snake Auto (Campaign) v3 started"); Log($"HeadId={HEAD_ID}, TargetKind={TARGET_KIND}"); Log($"Buttons: U={CTRL_UP} R={CTRL_RIGHT} D={CTRL_DOWN} L={CTRL_LEFT}"); while (Run) { Delay(40); var head = GetFloorItem(HEAD_ID); if (head == null) { if ((DateTime.Now - lastInfo).TotalMilliseconds > 1500) { Log("waiting: head not visible"); lastInfo = DateTime.Now; } continue; } var targets = FloorItems .Where(i => i != null && i.Kind == TARGET_KIND) .Where(i => Math.Abs(i.Location.X - head.Location.X) + Math.Abs(i.Location.Y - head.Location.Y) <= 45) .ToList(); if (targets.Count == 0) { if ((DateTime.Now - lastInfo).TotalMilliseconds > 1500) { int allTargets = FloorItems.Count(i => i != null && i.Kind == TARGET_KIND); Log($"waiting: no nearby target tiles (all kind {TARGET_KIND}: {allTargets})"); lastInfo = DateTime.Now; } continue; } var target = targets .OrderBy(t => Math.Abs(t.Location.X - head.Location.X) + Math.Abs(t.Location.Y - head.Location.Y)) .ThenBy(t => t.State) .First(); int dx = target.Location.X - head.Location.X; int dy = target.Location.Y - head.Location.Y; if (dx == 0 && dy == 0) continue; int dir = ToDir(dx, dy); SendDir(dir); }