using System; using System.Collections.Generic; using System.Linq; using System.Text.RegularExpressions; const int MAIN_ROOM = 80262160; const int SOURCE_MIN_X = 18; const int SOURCE_MAX_X = 29; const int SOURCE_MIN_Y = 25; const int SOURCE_MAX_Y = 36; const int FIELD_MIN_X = 18; const int FIELD_MAX_X = 29; const int FIELD_MIN_Y = 9; const int FIELD_MAX_Y = 20; var gameRooms = new[] { 80262165, 80262159, 80262161, 80262162, 80262164, 80262166, 80262167, 80262163 }; var completed = new HashSet(); int GetColorNumber(string name) { var match = Regex.Match(name, @"\d+$"); return match.Success ? int.Parse(match.Value) : -1; } bool InArea(int x, int y, int minX, int maxX, int minY, int maxY) => x >= minX && x <= maxX && y >= minY && y <= maxY; bool InField(int x, int y) => InArea(x, y, FIELD_MIN_X, FIELD_MAX_X, FIELD_MIN_Y, FIELD_MAX_Y); bool InWaitingLine(int x, int y) => x == 14 && y >= 16 && y <= 33; bool AtChair(int x, int y) => x == 14 && y == 15; int GetRoomId() { try { return (int)Room.Id; } catch { return 0; } } (int x, int y) GetSelfPos() { try { return (Self.Location.X, Self.Location.Y); } catch { return (-1, -1); } } void WalkToAndWait(int tx, int ty) { for (int retry = 0; retry < 10; retry++) { Send(Out["MoveAvatar"], tx, ty); for (int i = 0; i < 30; i++) { Delay(100); var pos = GetSelfPos(); if (pos.x == tx && pos.y == ty) { Delay(200); return; } } } } void WalkToAreaAndWait(int minX, int maxX, int minY, int maxY) { for (int retry = 0; retry < 10; retry++) { var pos = GetSelfPos(); if (pos.x >= 0 && InArea(pos.x, pos.y, minX, maxX, minY, maxY)) { Delay(200); return; } Send(Out["MoveAvatar"], minX, minY); for (int i = 0; i < 30; i++) { Delay(100); pos = GetSelfPos(); if (pos.x >= 0 && InArea(pos.x, pos.y, minX, maxX, minY, maxY)) { Delay(200); return; } } } } void ClickUntilTeleport(int id, int targetX, int targetY) { for (int retry = 0; retry < 20; retry++) { Send(Out["ClickFurni"], id, 0); for (int i = 0; i < 20; i++) { Delay(100); var pos = GetSelfPos(); if (pos.x == targetX && pos.y == targetY) { Delay(200); return; } } } } void UseUntilRoom(int id, int roomId) { for (int retry = 0; retry < 20; retry++) { Send(Out["UseFurniture"], id, 0); for (int i = 0; i < 30; i++) { Delay(100); if (GetRoomId() == roomId) { Delay(2000); return; } } } } void WaitForMainRoom() { for (int i = 0; i < 200; i++) { Delay(100); if (GetRoomId() == MAIN_ROOM) { Delay(2000); return; } } } void WaitUntilInField() { Log("Waiting for field..."); while (true) { var pos = GetSelfPos(); if (pos.x < 0) { Delay(100); continue; } if (InField(pos.x, pos.y)) { Log($"In field at ({pos.x},{pos.y})"); Delay(300); return; } if (AtChair(pos.x, pos.y)) { Delay(100); continue; } if (InWaitingLine(pos.x, pos.y)) { Send(Out["MoveAvatar"], 14, 15); Delay(200); continue; } Send(Out["MoveAvatar"], 14, 20); Delay(300); } } void DoPixelArt() { WaitUntilInField(); var selectors = new Dictionary(); try { foreach (var item in FloorItems) { if (item == null) continue; string name = item.GetName(); if (name.Contains("Cylinder Block") || name.Contains("Hemisphere Block")) { int colorNum = GetColorNumber(name); if (colorNum > 0 && !selectors.ContainsKey(colorNum)) selectors[colorNum] = (int)item.Id; } } } catch { } var sourcePixels = new Dictionary<(int x, int y), int>(); try { foreach (var item in FloorItems) { if (item == null) continue; int x = item.Location.X; int y = item.Location.Y; double z = item.Location.Z; if (x < SOURCE_MIN_X || x > SOURCE_MAX_X || y < SOURCE_MIN_Y || y > SOURCE_MAX_Y) continue; if (z < 0.7 || z > 1.0) continue; int colorNum = GetColorNumber(item.GetName()); if (colorNum > 0) sourcePixels[(x, y)] = colorNum; } } catch { } int offsetY = SOURCE_MIN_Y - FIELD_MIN_Y; int changed = 0; for (int attempt = 1; attempt <= 3; attempt++) { var fieldTiles = new Dictionary<(int x, int y), (int id, int colorNum)>(); try { foreach (var item in FloorItems) { if (item == null) continue; int x = item.Location.X; int y = item.Location.Y; double z = item.Location.Z; if (x < FIELD_MIN_X || x > FIELD_MAX_X || y < FIELD_MIN_Y || y > FIELD_MAX_Y) continue; int colorNum = GetColorNumber(item.GetName()); if (z > 0.5) fieldTiles[(x, y)] = ((int)item.Id, colorNum); else if (!fieldTiles.ContainsKey((x, y))) fieldTiles[(x, y)] = ((int)item.Id, -1); } } catch { } var toChange = new List<(int fieldId, int srcColor)>(); foreach (var src in sourcePixels) { int fieldX = src.Key.x; int fieldY = src.Key.y - offsetY; int srcColor = src.Value; if (!fieldTiles.TryGetValue((fieldX, fieldY), out var field)) continue; if (field.colorNum == srcColor) continue; if (!selectors.ContainsKey(srcColor)) continue; toChange.Add((field.id, srcColor)); } if (toChange.Count == 0) break; var sorted = toChange.OrderBy(x => x.srcColor).ToList(); int lastColor = -1; foreach (var item in sorted) { if (item.srcColor != lastColor) { Send(Out["ClickFurni"], selectors[item.srcColor], 0); Delay(50); lastColor = item.srcColor; } Send(Out["ClickFurni"], item.fieldId, 0); Delay(50); changed++; } Delay(500); } try { var badge = FloorItems.FirstOrDefault(f => f != null && f.GetName() == "Badge Display Case"); if (badge != null) Send(Out["ClickFurni"], (int)badge.Id, 0); } catch { } Log($"Done: {changed}"); completed.Add(GetRoomId()); } void GoToRoom1() { if (completed.Contains(80262165)) return; Log("Room 1"); WalkToAreaAndWait(5, 6, 25, 27); ClickUntilTeleport(902905683, 11, 27); ClickUntilTeleport(902906203, 11, 24); UseUntilRoom(902906203, 80262165); DoPixelArt(); WaitForMainRoom(); } void GoToRoom2() { if (completed.Contains(80262159)) return; Log("Room 2"); WalkToAreaAndWait(16, 20, 34, 35); ClickUntilTeleport(902906461, 20, 34); ClickUntilTeleport(902906426, 20, 32); UseUntilRoom(902906426, 80262159); DoPixelArt(); WaitForMainRoom(); } void GoToRoom3() { if (completed.Contains(80262161)) return; Log("Room 3"); WalkToAreaAndWait(25, 25, 17, 21); Send(Out["ClickFurni"], 902906152, 0); Delay(500); ClickUntilTeleport(902907470, 25, 19); UseUntilRoom(902907470, 80262161); DoPixelArt(); WaitForMainRoom(); } void GoToRoom4() { if (completed.Contains(80262162)) return; Log("Room 4"); WalkToAreaAndWait(30, 31, 15, 16); Send(Out["ClickFurni"], 902907718, 0); Delay(500); ClickUntilTeleport(902907623, 31, 15); UseUntilRoom(902907623, 80262162); DoPixelArt(); WaitForMainRoom(); } void GoToRoom5() { if (completed.Contains(80262164)) return; Log("Room 5"); WalkToAreaAndWait(30, 31, 15, 16); Send(Out["ClickFurni"], 902907718, 0); Delay(500); WalkToAndWait(36, 16); ClickUntilTeleport(902905838, 36, 16); UseUntilRoom(902905838, 80262164); DoPixelArt(); WaitForMainRoom(); } void GoToRoom6() { if (completed.Contains(80262166)) return; Log("Room 6"); WalkToAreaAndWait(30, 31, 15, 16); Send(Out["ClickFurni"], 902907718, 0); Delay(500); WalkToAndWait(44, 14); ClickUntilTeleport(902907457, 44, 14); UseUntilRoom(902907457, 80262166); DoPixelArt(); WaitForMainRoom(); } void GoToRoom7() { if (completed.Contains(80262167)) return; Log("Room 7"); WalkToAreaAndWait(30, 31, 15, 16); Send(Out["ClickFurni"], 902907718, 0); Delay(500); WalkToAndWait(50, 12); ClickUntilTeleport(902906400, 50, 12); UseUntilRoom(902906400, 80262167); DoPixelArt(); WaitForMainRoom(); } void GoToRoom8() { if (completed.Contains(80262163)) return; Log("Room 8"); WalkToAreaAndWait(50, 51, 21, 21); Send(Out["ClickFurni"], 902906802, 0); Delay(500); ClickUntilTeleport(902906273, 50, 21); UseUntilRoom(902906273, 80262163); DoPixelArt(); WaitForMainRoom(); } Log("Starting"); int currentRoom = GetRoomId(); if (gameRooms.Contains(currentRoom)) { Log($"In game room {currentRoom}"); DoPixelArt(); WaitForMainRoom(); } GoToRoom1(); GoToRoom2(); GoToRoom3(); GoToRoom4(); GoToRoom5(); GoToRoom6(); GoToRoom7(); GoToRoom8(); Log($"All done: {completed.Count}/8"); WalkToAreaAndWait(41, 41, 32, 33);