diff --git a/src/hooks/obstructive/TOS.cpp b/src/hooks/obstructive/TOS.cpp index aaa81a6..3c525e8 100644 --- a/src/hooks/obstructive/TOS.cpp +++ b/src/hooks/obstructive/TOS.cpp @@ -51,7 +51,7 @@ class $modify(TOSGJBaseGameLayer, GJBaseGameLayer) { cursor::show(); - updateTimeWarp(0.125f); + //updateTimeWarp(0.125f); }; }; }; diff --git a/src/util/ui/TermsAndConditions.hpp b/src/util/ui/TermsAndConditions.hpp index f2e12a7..05e7865 100644 --- a/src/util/ui/TermsAndConditions.hpp +++ b/src/util/ui/TermsAndConditions.hpp @@ -1,14 +1,23 @@ #pragma once #include +#include namespace horrible { namespace ui { class TermsAndConditions final : public geode::Popup { using Callback = geode::CopyableFunction; + private: + geode::Button* m_acceptBtn = nullptr; + cocos2d::CCPoint m_acceptVelocity = {0.f, 0.f}; + float m_acceptSpeed = 100.f; + float m_mouseAvoidDistance = 25.f; + float m_mouseAvoidMultiplier = 1.75f; + protected: void finishBtnFade(cocos2d::CCNode* sender); + void update(float dt) override; bool init(Callback&& cb); diff --git a/src/util/ui/src/TermsAndConditions.cpp b/src/util/ui/src/TermsAndConditions.cpp index d268bd1..98aaa06 100644 --- a/src/util/ui/src/TermsAndConditions.cpp +++ b/src/util/ui/src/TermsAndConditions.cpp @@ -1,5 +1,6 @@ #include "../TermsAndConditions.hpp" +#include #include #include @@ -48,7 +49,7 @@ bool TermsAndConditions::init(Callback&& cb) { m_mainLayer->addChild(tosArea); - auto acceptBtn = Button::createWithNode( + m_acceptBtn = Button::createWithNode( ButtonSprite::create( "Accept", font::big, @@ -56,27 +57,36 @@ bool TermsAndConditions::init(Callback&& cb) { [this, cb](auto) { sfx::play(sfx::file::good); if (cb) cb(true); + if (auto pl = PlayLayer::get()) { + pl->resume(); + } removeFromParent(); }); - acceptBtn->setScale(0.75f); + m_acceptBtn->setZOrder(10); + m_acceptBtn->setScale(0.75f); auto declineBtn = Button::createWithNode( ButtonSprite::create( "Decline", - font::gold, + font::big, themes::getButtonSquareSprite(theme)), [this, cb](auto) { sfx::play(sfx::file::bad); if (cb) cb(false); removeFromParent(); }); + declineBtn->setZOrder(10); declineBtn->setScale(0.75f); - m_mainLayer->addChildAtPosition(acceptBtn, Anchor::Bottom, {-60.f, 25.f}); + m_mainLayer->addChildAtPosition(m_acceptBtn, Anchor::Bottom, {-60.f, 25.f}); m_mainLayer->addChildAtPosition(declineBtn, Anchor::Bottom, {60.f, 25.f}); - if (auto acceptBtnSpr = typeinfo_cast(acceptBtn->getDisplayNode())) { - acceptBtn->setEnabled(false); + auto const angle = rng::get(2.f * std::numbers::pi); + m_acceptVelocity = ccp(cosf(angle), sinf(angle)); + scheduleUpdate(); + + if (auto acceptBtnSpr = typeinfo_cast(m_acceptBtn->getDisplayNode())) { + m_acceptBtn->setEnabled(false); acceptBtnSpr->setOpacity(0); acceptBtnSpr->runAction(CCSpawn::createWithTwoActions( @@ -94,6 +104,60 @@ void TermsAndConditions::finishBtnFade(CCNode* sender) { if (auto btn = typeinfo_cast(sender->getParent())) btn->setEnabled(true); }; +void TermsAndConditions::update(float dt) { + if (!m_acceptBtn) return; + + CCSize const winSize = CCDirector::sharedDirector()->getWinSize(); + CCPoint const localPos = m_acceptBtn->getPosition(); + CCPoint worldPos = m_mainLayer->convertToWorldSpace(localPos); + CCSize const buttonSize = m_acceptBtn->getScaledContentSize(); + + CCPoint const mousePos = cocos::getMousePos(); + CCPoint const away = ccpSub(worldPos, mousePos); + float const dist = std::sqrt(away.x * away.x + away.y * away.y); + float speed = m_acceptSpeed; + + // make the mouse (like cheeseworks) to chase the accept button cuz im evil + if (dist < m_mouseAvoidDistance && dist > 0.f) { + auto normalizedAway = ccp(away.x / dist, away.y / dist); + auto currentVelLen = std::sqrt(m_acceptVelocity.x * m_acceptVelocity.x + m_acceptVelocity.y * m_acceptVelocity.y); + if (currentVelLen > 0.f) { + normalizedAway.x += m_acceptVelocity.x / currentVelLen; + normalizedAway.y += m_acceptVelocity.y / currentVelLen; + } + auto const newLen = std::sqrt(normalizedAway.x * normalizedAway.x + normalizedAway.y * normalizedAway.y); + if (newLen > 0.f) { + normalizedAway.x /= newLen; + normalizedAway.y /= newLen; + m_acceptVelocity = normalizedAway; + } + speed *= m_mouseAvoidMultiplier; + } + + worldPos = ccpAdd(worldPos, ccpMult(m_acceptVelocity, speed * dt)); + + auto const halfW = buttonSize.width / 2.f; + auto const halfH = buttonSize.height / 2.f; + + if (worldPos.x < halfW) { + worldPos.x = halfW; + m_acceptVelocity.x = fabsf(m_acceptVelocity.x); + } else if (worldPos.x > winSize.width - halfW) { + worldPos.x = winSize.width - halfW; + m_acceptVelocity.x = -fabsf(m_acceptVelocity.x); + } + + if (worldPos.y < halfH) { + worldPos.y = halfH; + m_acceptVelocity.y = fabsf(m_acceptVelocity.y); + } else if (worldPos.y > winSize.height - halfH) { + worldPos.y = winSize.height - halfH; + m_acceptVelocity.y = -fabsf(m_acceptVelocity.y); + } + + m_acceptBtn->setPosition(m_mainLayer->convertToNodeSpace(worldPos)); +}; + TermsAndConditions* TermsAndConditions::create(Callback&& cb) { auto ret = new TermsAndConditions(); if (ret->init(std::move(cb))) {