All MicroEvals
Напиши профессиональный мод для Geode под Geometry Dash 2.20...
Create MicroEval

Напиши профессиональный мод для Geode под Geometry Dash 2.20...

Prompt

Напиши профессиональный мод для Geode под Geometry Dash 2.2081 (Geode v5.11.2, C++23). Платформы: Windows, Android32, Android64. Весь код одним файлом src/main.cpp. Интерфейс только на русском (проверь, какие символы доступны в шрифтах GD; если кириллица не отображается, укажи это в допущениях). ПРАВИЛА - Не придумывай методы и поля. Если не уверен в сигнатуре, помечай // VERIFY и в конце ответа перечисли все такие места. - В конце дай список допущений и рискованных мест. - Если я пришлю лог сборки, исправляй только указанное, остальное не переписывай. - Не переопределяй деструкторы в $modify, не используй Mod::get() в статической инициализации, объявляй namespace и переменные раньше их использования. ПРОВЕРЕННЫЕ СИГНАТУРЫ (bindings 2.2081) GJBaseGameLayer: void handleButton(bool down, int button, bool isPlayer1); void queueButton(int button, bool push, bool isPlayer2, double timestamp); void processQueuedButtons(float dt, bool clearInputQueue); void processCommands(float dt, bool isHalfTick, bool isLastTick); int checkCollisions(PlayerObject*, float dt, bool ignoreDamage); double getModifiedDelta(float dt); bool shouldUseSubstepForButton(float dt); void removeReleasedButtons(); void recordAction(int button, bool down, bool player2); поле m_queuedButtons (gd::vector<PlayerButtonCommand>) В GJBaseGameLayer НЕТ pushButton/releaseButton (они есть только в PlayerObject). PlayLayer: bool init(GJGameLevel*, bool useReplay, bool dontCreateObjects); CheckpointObject* createCheckpoint(); void loadFromCheckpoint(CheckpointObject*); CheckpointObject* markCheckpoint(); void storeCheckpoint(CheckpointObject*); void removeCheckpoint(bool first); void levelComplete(); void onQuit(); void pauseGame(bool); void resumeAndRestart(bool fromStart); void resetLevelFromStart(); virtual void resetLevel(); virtual void destroyPlayer(PlayerObject*, GameObject*); void takeStateSnapshot(); void compareStateSnapshot(); поля m_isPaused, m_currentCheckpoint, m_checkpointArray. Ранее с успехом компилировались обращения к: m_player1, m_player2, m_playerDied, m_clickBetweenSteps, m_clickOnSteps, m_gameState.m_isDualMode, m_isOnGround, m_yVelocity, m_isUpsideDown, m_lastPosition, m_isDart. ПРОВЕРЕННЫЕ API GEODE 5 - Приоритет хуков: в классе $modify добавь static void onModify(auto& self) { if (!self.setHookPriorityPre("GJBaseGameLayer::queueButton", Priority::First)) geode::log::warn("..."); } Для кода «после всех» используй setHookPriorityPost с Priority::Last и вызывай оригинал в начале хука. Имя функции пиши вместе с классом. Хуки перегруженных функций приоритетом не задаются. - Асинхронщина: file::pick(mode, options) возвращает arc::Future<PickResult>. Подключи <Geode/utils/async.hpp>. Запуск: async::spawn(file::pick(...), callback) либо async::TaskHolder (его поле хранится в классе, чтобы задача отменялась при уничтожении). Колбэк вызывается в главном потоке. Точный тип PickResult и способ проверки отмены (путь или std::nullopt) пометь // VERIFY. - В Geode есть geode::utils::getInputTimestamp (шкала времени входных событий, VERIFY: единицы и связь с timestamp в queueButton). 1. СВОЙ CBF - Клик внутри физического шага делит шаг на подшаги, между ними вызывается handleButton. Своя реализация, независимая от мода Click Between Frames (id syzzi.click_between_frames) и ванильных Click On/Between Steps. - В режимах записи и воспроизведения перехватывай queueButton с приоритетом Priority::First (Pre) и не вызывай оригинал: так хуки других модов (включая CBF) для этой функции не выполнятся. Когда бот выключен, вызывай оригинал как обычно. - Если мод CBF загружен, покажи предупреждение (Loader::get()->isModLoaded). - Формат клика в макросе: номер шага (uint32) + доля шага (float или double 0..1). Обоснуй выбор в допущениях. Как сопоставить timestamp из queueButton с границами шагов, реши сам и пометь VERIFY, если не уверен. 2. ФИКСИРОВАННЫЙ TPS И УСТОЙЧИВОСТЬ К ЛАГАМ - Физика идёт строго фиксированными шагами (по умолчанию 240 TPS), независимо от FPS и просадок. - Хукни GJBaseGameLayer::getModifiedDelta: вызови оригинал (он меняет внутреннее состояние слоя), затем верни фиксированное значение. Приоритет хука: Last (Post), чтобы другие TPS bypass и спидхак-моды, включая CBF (он тоже хукает эту функцию), не могли изменить результат, пока бот включён. Когда бот выключен, хук ничего не меняет. Проверку работоспособности на 2.2081 пометь VERIFY. - Запись и воспроизведение используют один и тот же алгоритм и одни и те же шаги, привязка только к номеру шага и доле шага, никаких wall-clock часов. - Несколько шагов за кадр обрабатываются по порядку с применением всех кликов своего шага. - Макрос хранит TPS и проверяет совпадение при загрузке. 3. ПРАКТИКА И ЧЕКПОИНТЫ - Запись работает в практике и в обычном режиме. - При загрузке чекпоинта запись не прерывается: макрос обрезается до шага чекпоинта (удаляются действия с step >= шага чекпоинта), состояние зажатых кнопок на момент чекпоинта восстанавливается, запись продолжается без дефектов. - Смерть без чекпоинта при записи: запись сохраняется в буфер, запись выключается, игрок выбирает: сохранить макрос из буфера или начать новую запись. - Поддерживаются все режимы: прыжок, платформер (влево и вправо), Dual, Player 2. 4. ВОСПРОИЗВЕДЕНИЕ - Ручной ввод по умолчанию не блокируется. Переключатель «Блокировать ввод». - Если бот удерживает кнопку и игрок ставит игру на паузу, зажатая кнопка не отпускается. После возобновления состояние кнопок остаётся прежним. - По завершении макроса воспроизведение выключается, макрос остаётся в буфере для сохранения или удаления. - Отправку рекордов и прогресса не меняй. 5. СКОРОСТЬ ЗАПИСИ - Поле числа от 0.01 до 2, применяется сразу. - Макрос от скорости записи не зависит и всегда воспроизводится на 1.0x. - Музыка замедляется корректно (высота тона через FMOD, проверь поля FMODAudioEngine, VERIFY). При смерти, паузе и выходе скорость и тон возвращаются к норме. Если возможно, учитывай и звуковые эффекты. 6. ПОКАДРОВЫЙ РЕЖИМ (экспериментальный) - Настройка «размер шага» в физических шагах. При включении появляются две кнопки у левого края: «вправо» (продвинуть на выбранный шаг, применяя записанные клики) и «влево» (вернуть назад на выбранный шаг). - Шаг назад: хранить снимки состояния через равные интервалы шагов (через createCheckpoint/loadFromCheckpoint), при шаге назад загружать ближайший снимок раньше целевого шага и пересимулировать вперёд по макросу. Известный риск: не всё состояние восстанавливается (RNG, триггеры, анимации). В PlayLayer есть takeStateSnapshot/compareStateSnapshot, VERIFY их семантику и можно ли ими проверять совпадение состояния после пересимуляции. - Если шаг назад невозможно сделать надёжно, реализуй только шаг вперёд, кнопку «влево» сделай неактивной с пояснением по-русски и опиши причину в допущениях. Режим выключен по умолчанию и не должен влиять на запись и воспроизведение, когда он выключен. 7. ИНТЕРФЕЙС - Кнопка у левого края экрана, только в меню паузы. Её можно зажать мышью или пальцем и перетащить. Последнюю позицию запоминай (сохранённое значение мода). Нажатие плавно открывает панель. - Одна вкладка «Бот». Аккуратно под Windows и телефон: относительные размеры, учёт разрешения и выреза экрана (в Geode есть safe area API для Android и iOS), тач и мышь. - В панели: переключатель записи, «Выключить бота» (выключает и запись и воспроизведение), «Запустить макрос», скорость записи, блокировка ввода, покадровый режим и размер шага, имя макроса и «Сохранить», папка макросов, список макросов с загрузкой, воспроизведением и удалением. - Используй элементы Geode (ScrollLayer, TextInput, Notification и т.д.). 8. ФАЙЛЫ МАКРОСОВ - Бинарный формат: заголовок (magic, версия формата, TPS, ID уровня), затем записи (step, доля шага, кнопка, down, player). При загрузке проверяй magic, версию и размеры, защищайся от повреждённых файлов. Расширение .gdbot. - Папку выбирает пользователь через file::pick (режим OpenFolder, async, см. выше). Внутри создай подпапку (например «GDBotMacros»), выбранный путь запоминай. - ОБЯЗАТЕЛЬНО после выбора проверь запись (создание подпапки и тестового файла). Если запись не удалась (на Android доступ к папкам ограничен системой), покажи понятное сообщение по-русски и предложи выбрать другую папку или использовать папку мода (Mod::get()->getSaveDir(), она доступна для записи всегда) как запасную. Скажи об этом честно: гарантировать доступность выбранной папки на всех устройствах нельзя. - Имя файла очищай от недопустимых символов, при совпадении спрашивай или добавляй суффикс. ФОРМАТ ОТВЕТА Один полный файл src/main.cpp. После кода: список допущений, список мест с VERIFY, краткие инструкции, что проверить после сборки.

Drag to resize

Response not available

Drag to resize
Drag to resize
Drag to resize