using System; using System.Collections.Generic; using System.Linq; const int BIRD_X = 17; const int BIRD_KIND = 9039; const int PIPE_KIND = 5986; const int CONTROL_ID = 630985637; int GetKind(dynamic item) { try { return (int)item.Kind; } catch { return -1; } } void Flap() { Send(Out["UseFurniture"], CONTROL_ID, 0); } int GetBirdY() { foreach (var item in FloorItems) { if (item == null) continue; if (GetKind(item) != BIRD_KIND) continue; if (item.Location.X == BIRD_X) return item.Location.Y; } return -1; } (int gapMin, int gapMax, int pipeX) FindNextPipe() { var pipesByX = new Dictionary>(); foreach (var item in FloorItems) { if (item == null) continue; if (GetKind(item) != PIPE_KIND) continue; int x = item.Location.X, y = item.Location.Y; if (!pipesByX.ContainsKey(x)) pipesByX[x] = new List(); pipesByX[x].Add(y); } var ahead = pipesByX.Keys.Where(x => x >= BIRD_X).OrderBy(x => x).ToList(); if (ahead.Count == 0) return (-1, -1, 99); int closestX = ahead.First(); var wallYs = new HashSet(pipesByX[closestX]); int bestStart = -1, bestEnd = -1, bestSize = 0, gapStart = -1; for (int y = 7; y <= 24; y++) { if (!wallYs.Contains(y)) { if (gapStart < 0) gapStart = y; } else { if (gapStart >= 0) { int size = (y - 1) - gapStart + 1; if (size > bestSize) { bestSize = size; bestStart = gapStart; bestEnd = y - 1; } } gapStart = -1; } } if (gapStart >= 0) { int size = 24 - gapStart + 1; if (size > bestSize) { bestStart = gapStart; bestEnd = 24; } } return (bestStart, bestEnd, closestX); } Log("FLAPPY BOT V19 - SILENT MODE"); // Output spam reduced long lastFlap = 0; int tick = 0; int lastY = -1; while (Run) { tick++; int birdY = GetBirdY(); if (birdY < 0) { Delay(25); continue; } var (gapMin, gapMax, pipeX) = FindNextPipe(); int dist = pipeX - BIRD_X; long now = DateTimeOffset.Now.ToUnixTimeMilliseconds(); bool shouldFlap = false; string reason = ""; // MINIMUM COOLDOWN = 120ms int cooldown = 120; if (gapMin > 0 && dist <= 15) { bool aboveGap = birdY < gapMin; bool belowGap = birdY > gapMax; int gapCenter = (gapMin + gapMax) / 2; int afterFlap = birdY - 3; bool wouldOvershoot = afterFlap <= gapMin; if (belowGap) { shouldFlap = true; reason = "BELOW"; } else if (aboveGap) { shouldFlap = false; reason = "ABOVE"; } else { if (dist <= 4) { if (birdY >= gapMax && !wouldOvershoot) { shouldFlap = true; reason = "CLOSE-SAVE"; } else { reason = "CLOSE-OK"; } } else if (dist <= 10) { if (birdY > gapMax && !wouldOvershoot) { shouldFlap = true; reason = "MED-LOW"; } else if (birdY > gapCenter + 2 && !wouldOvershoot) { shouldFlap = true; reason = "MED-ADJ"; } else { reason = "MED-OK"; } } else { if (birdY > gapCenter + 3 && !wouldOvershoot) { shouldFlap = true; reason = "FAR-LOW"; } else { reason = "FAR-OK"; } } } } else { if (birdY > 16) { shouldFlap = true; reason = "HOVER"; } } if (birdY >= 22) { shouldFlap = true; reason = "EMERG"; } if (birdY <= 8) shouldFlap = false; int dy = lastY > 0 ? birdY - lastY : 0; string gapStr = gapMin > 0 ? $"gap={gapMin}-{gapMax}" : "NO_GAP"; if (shouldFlap && (now - lastFlap) >= cooldown) { // Nur noch Loggen wenn er wirklich springt Log($">>> FLAP! Y={birdY} | d={dist} {gapStr} | {reason}"); Flap(); lastFlap = now; } // Der Code-Block, der sonst hier war (else if dist <= 3...), wurde entfernt. // Dadurch hört der Spam auf. lastY = birdY; Delay(25); }