Keeps the repo root clean - only README.md visible on landing page. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
165 lines
4.4 KiB
C#
165 lines
4.4 KiB
C#
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<int, List<int>>();
|
|
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<int>();
|
|
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<int>(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);
|
|
} |