diff --git a/Classes/AchievementBar.cpp b/Classes/AchievementBar.cpp index 48d8368..73e57c7 100644 --- a/Classes/AchievementBar.cpp +++ b/Classes/AchievementBar.cpp @@ -1,90 +1,148 @@ +// decompiled by ItzZyann +// from GD 1.71 binary + #include "AchievementBar.h" #include "AchievementNotifier.h" +#include "GameManager.h" #include "SimplePlayer.h" +#include "TextArea.h" #include "cocos-ext.h" + USING_NS_CC; USING_NS_CC_EXT; AchievementBar::AchievementBar() + : m_layerColor(nullptr) + , m_targetScene(nullptr) + , m_screenOffset(0.0f) { - m_targetScene = nullptr; } AchievementBar* AchievementBar::create(char const* title, char const* description, char const* icon) { - AchievementBar* pRet = new AchievementBar(); - if (pRet && pRet->init(title, description, icon)) - { - pRet->autorelease(); - return pRet; - } - else - { - delete pRet; - pRet = NULL; - return NULL; - } + AchievementBar* pRet = new AchievementBar(); + if (pRet && pRet->init(title, description, icon)) + { + pRet->autorelease(); + return pRet; + } + CC_SAFE_DELETE(pRet); + return nullptr; } -// gonna have to redecompile this entire function again... bool AchievementBar::init(char const* title, char const* description, char const* icon) { - CCLOG("creating achievement bar for %s", title); - CCDirector* pDirector = CCDirector::sharedDirector(); - CCSize winSize = pDirector->getWinSize(); + if (!CCNodeRGBA::init()) return false; + + CCSize winSize = CCDirector::sharedDirector()->getWinSize(); - this->m_layerColor = CCLayerColor::create(ccc4(0, 0, 0, 0)); + m_layerColor = CCLayerColor::create(ccc4(0, 0, 0, 0), winSize.width, 80.0f); this->addChild(m_layerColor); + m_layerColor->setPosition(ccp(0.0f, CCDirector::sharedDirector()->getScreenTop() + 2.0f)); + + CCScale9Sprite* bg = CCScale9Sprite::create("GJ_square01.png", CCRectMake(0, 0, 80, 80)); + bg->setContentSize(CCSize(300.0f, 70.0f)); + m_layerColor->addChild(bg, 1); + bg->setPosition(ccp(winSize.width * 0.5f, 35.0f)); - CCScale9Sprite* box = CCScale9Sprite::create("GJ_square01.png", CCRect(0, 0, 80, 80)); - box->setPosition(ccp(winSize.width / 2, pDirector->getScreenTop() - 50)); - box->setContentSize(CCSize(300, 70)); - m_layerColor->addChild(box); + CCSprite* measureSprite = CCSprite::createWithSpriteFrameName("playerSquare_001.png"); - CCSprite* playerSquare = CCSprite::createWithSpriteFrameName("playerSquare_001.png"); - if (icon) + CCNode* iconNode = nullptr; + const char* unlockStr = nullptr; + + if (icon && strlen(icon) > 0) { - char const* item = "color"; - if (true) + CCArray* parts = CCArray::create(); + std::string iconStr(icon), seg; + for (size_t i = 0; i <= iconStr.size(); ++i) { - char const* descString = CCString::createWithFormat("Unlocked new %s!", item)->getCString(); - SimplePlayer* achIcon = SimplePlayer::create(1); - achIcon->updatePlayerFrame(1, IconType::Cube); - m_layerColor->addChild(achIcon); - /*local_11c = 175; - local_11b = 175; - local_11a = 175; - (**(code **)(*(int *)pSVar10 + 0x1cc))(pSVar10, &local_11c);*/ - achIcon->setSecondColor(ccc3(255, 255, 255)); + if (i == iconStr.size() || iconStr[i] == '_') + { + if (!seg.empty()) { parts->addObject(CCString::create(seg.c_str())); seg.clear(); } + } + else seg += iconStr[i]; } - else - { + if (parts->count() > 1) + { + const char* typeStr = static_cast(parts->objectAtIndex(0))->getCString(); + int idx = static_cast(parts->objectAtIndex(1))->intValue(); + + bool isColor = (strcmp(typeStr, "color") == 0 || strcmp(typeStr, "color2") == 0); + if (isColor) + { + unlockStr = "Unlocked new Color!"; + measureSprite->setColor(GameManager::sharedState()->colorForIdx(idx - 1)); + iconNode = measureSprite; + } + else + { + int playerType; + if (strcmp(typeStr, "ship") == 0) { playerType = 1; unlockStr = CCString::createWithFormat("Unlocked new %s!", "Ship")->getCString(); } + else if (strcmp(typeStr, "ball") == 0) { playerType = 2; unlockStr = CCString::createWithFormat("Unlocked new %s!", "Ball")->getCString(); } + else if (strcmp(typeStr, "bird") == 0) { playerType = 3; unlockStr = CCString::createWithFormat("Unlocked new %s!", "UFO")->getCString(); } + else { playerType = 0; unlockStr = CCString::createWithFormat("Unlocked new %s!", "Icon")->getCString(); } + + SimplePlayer* sp = SimplePlayer::create(1); + sp->updatePlayerFrame(idx, static_cast(playerType)); + sp->setColor(ccc3(0xAF, 0xAF, 0xAF)); + sp->setSecondColor(ccc3(0xFF, 0xFF, 0xFF)); + iconNode = sp; + } } - } - - // CCSprite* gkIcon = CCSprite::create("gk-icon.png"); this is literally just a checkmark and idk when it is shown - - CCLabelBMFont* titleText = CCLabelBMFont::create(title, "bigFont.fnt"); - titleText->setPosition(ccp(winSize.width / 2, pDirector->getScreenTop() - 50)); - this->addChild(titleText); - - if (200.0f < titleText->getContentSize().width) - { - titleText->setScale(200.0f / titleText->getContentSize().width); - } - - float textScale; - if (titleText->getScale() <= 0.7f) - { - textScale = titleText->getScale(); + else goto use_fallback; } else { - textScale = 0.7f; + use_fallback: + CCSprite* fallback = CCSprite::create("gk-icon.png"); + fallback->setColor(ccc3(0, 0, 0)); + fallback->setZOrder(100); + iconNode = fallback; } - titleText->setScale(textScale); + iconNode->setPosition(ccp(40.0f, 35.0f)); + m_layerColor->addChild(iconNode, 3); + + CCNode* textNode = CCNode::create(); + m_layerColor->addChild(textNode, 2); + + CCLabelBMFont* titleLabel = CCLabelBMFont::create(title, "bigFont.fnt"); + textNode->addChild(titleLabel); + titleLabel->setAnchorPoint(ccp(0.0f, 0.5f)); + titleLabel->setScale(0.7f); + float titleW = titleLabel->getContentSize().width; + if (titleW > 200.0f) + titleLabel->setScale(200.0f / titleW); + if (titleLabel->getScale() < 0.7f) + titleLabel->setScale(0.7f); + + const char* descText = unlockStr ? unlockStr : description; + + // fok this textarea T-T + // its soo buggy + TextArea* descLabel = TextArea::create(descText, 200.0f, 0, ccp(0.0f, 1.0f), "chatFont.fnt"); + textNode->addChild(descLabel); + descLabel->setAnchorPoint(ccp(0.0f, 0.5f)); + + float titleH = titleLabel->getContentSize().height; + float descH = descLabel->getContentSize().height + 17.0f; + float midH = (titleH + descH) * 0.5f; + titleLabel->setPosition(ccp(0.0f, (midH - titleH * 0.5f) + 2.0f)); + descLabel->setPosition(ccp(1.0f, 15.0f - (midH - descH * 0.5f) - 1.0f)); + + measureSprite->setScale(1.0f); + iconNode->setScale(1.0f); + + float squareW = measureSprite->getContentSize().width; + float titleScaledW = titleLabel->getContentSize().width * titleLabel->getScaleX(); + float descW = descLabel->getContentSize().width; + float textBlockW = ((titleScaledW >= descW) ? titleScaledW : descW) + 5.0f; + + float totalW = squareW * 0.5f + textBlockW + 30.0f; + float iconX = (winSize.width * 0.5f) - (totalW * 0.5f) + (squareW * 0.5f); + iconNode->setPosition(ccp(iconX, 35.0f)); + textNode->setPosition(ccp(iconNode->getPositionX() + 30.0f, 35.0f)); m_screenOffset = 74.0f; @@ -93,19 +151,15 @@ bool AchievementBar::init(char const* title, char const* description, char const void AchievementBar::show() { - CCNode* scene = CCDirector::sharedDirector()->getRunningScene(); - - if (m_targetScene != nullptr) - scene = m_targetScene; - - scene->addChild(this, 105); - - // the animation - CCMoveBy* moveIn = CCMoveBy::create(1.0f, ccp(0.0f, -m_screenOffset)); + CCMoveBy* moveIn = CCMoveBy::create(1.0f, ccp(0, -m_screenOffset)); CCEaseInOut* easeIn = CCEaseInOut::create(moveIn, 2.0f); - CCDelayTime* delay = CCDelayTime::create(1.5f); - CCMoveBy* moveOut = CCMoveBy::create(1.0f, ccp(0.0f, m_screenOffset)); + CCDelayTime* delay = CCDelayTime::create(2.0f); + CCMoveBy* moveOut = CCMoveBy::create(1.0f, ccp(0, m_screenOffset)); CCEaseInOut* easeOut = CCEaseInOut::create(moveOut, 2.0f); - CCCallFunc* callback = CCCallFunc::create(AchievementNotifier::sharedState(), callfunc_selector(AchievementNotifier::achievementDisplayFinished)); - m_layerColor->runAction(CCSequence::create(easeIn, delay, easeOut, nullptr)); + + CCCallFunc* callback = CCCallFunc::create( + AchievementNotifier::sharedState(), + callfunc_selector(AchievementNotifier::achievementDisplayFinished)); + + m_layerColor->runAction(CCSequence::create(easeIn, delay, easeOut, callback, nullptr)); } \ No newline at end of file diff --git a/Classes/AchievementBar.h b/Classes/AchievementBar.h index 546f34d..1731fc0 100644 --- a/Classes/AchievementBar.h +++ b/Classes/AchievementBar.h @@ -1,6 +1,11 @@ +// decompiled by ItzZyann +// from GD 1.71 binary + #ifndef _ACHIEVEMENT_BAR_H_ #define _ACHIEVEMENT_BAR_H_ + #include "cocos2d.h" +#include "cocos-ext.h" class AchievementBar : public cocos2d::CCNodeRGBA { public: @@ -9,10 +14,9 @@ class AchievementBar : public cocos2d::CCNodeRGBA { virtual bool init(char const* title, char const* description, char const* icon); void show(); - - cocos2d::CCLayerColor* m_layerColor; // 0xe8 - float m_screenOffset; // 0xec - CC_SYNTHESIZE(CCNode*, m_targetScene, TargetScene); // 0xf0 + cocos2d::CCLayerColor* m_layerColor; + float m_screenOffset; + CC_SYNTHESIZE(cocos2d::CCNode*, m_targetScene, TargetScene); }; #endif \ No newline at end of file diff --git a/Classes/AchievementManager.cpp b/Classes/AchievementManager.cpp index 23c7b5e..d1a5bc0 100644 --- a/Classes/AchievementManager.cpp +++ b/Classes/AchievementManager.cpp @@ -1,36 +1,47 @@ +// decompiled by ItzZyann +// from GD 1.71 binary + #include "AchievementManager.h" #include "AchievementNotifier.h" -#include "RT_COCOS/CCContentManager.h" +// #include "RT_COCOS/CCContentManager.h" +// re-enable when CCContentManager is ready + USING_NS_CC; AchievementManager::AchievementManager() + : m_allAchievements(nullptr) + , m_reportedAchievements(nullptr) + , m_dontNotifyAch(false) +{ +} + +AchievementManager::~AchievementManager() { - this->m_allAchievements = nullptr; - // (this_00->data).offset_0x4 = 0; - // (this_00->data).offset_0x8 = (CCObject *)0x0; - this->m_dontNotifyAch = false; + CC_SAFE_RELEASE(m_allAchievements); + CC_SAFE_RELEASE(m_reportedAchievements); } AchievementManager* AchievementManager::sharedState() { - static AchievementManager* pAchManager = NULL; - if (!pAchManager) - { - pAchManager = new AchievementManager(); - pAchManager->init(); - } - - return pAchManager; + static AchievementManager* pAchManager = nullptr; + if (!pAchManager) + { + pAchManager = new AchievementManager(); + pAchManager->init(); + } + return pAchManager; } bool AchievementManager::init() { m_reportedAchievements = CCDictionary::create(); m_reportedAchievements->retain(); - // todo: add CCContentManager and fix this fr - // CCContentManager* pContentManager = CCContentManager::sharedManager(); - // m_achDict = pContentManager->addDict("AchievementsDesc.plist", true); + + // TODO: swap to CCContentManager when ready + // CCContentManager* pContentManager = CCContentManager::sharedManager(); + // m_allAchievements = pContentManager->addDict("AchievementsDesc.plist", true); + m_allAchievements = CCDictionary::createWithContentsOfFile("AchievementsDesc.plist"); m_allAchievements->retain(); return true; @@ -38,56 +49,61 @@ bool AchievementManager::init() void AchievementManager::notifyAchievementWithID(char const* achID) { - // houston, we have a problem. - CCLOG("notifying achievement %s", achID); - if (this->m_dontNotifyAch == false) { - if (m_allAchievements->objectForKey(achID) != nullptr) { - CCDictionary* tempDict = - dynamic_cast( - m_allAchievements->objectForKey(achID) - ); - const char* title = tempDict->valueForKey("title")->getCString(); - CCLOG(title); - const char* description = tempDict->valueForKey("achievedDescription")->getCString(); - CCLOG(description); - const char* icon = tempDict->valueForKey("icon")->getCString(); - CCLOG(icon); - AchievementNotifier* pAchNotifier = AchievementNotifier::sharedState(); - pAchNotifier->notifyAchievement(title, description, icon); - } + if (m_dontNotifyAch) + { + return; } + + CCDictionary* tempDict = dynamic_cast(m_allAchievements->objectForKey(achID)); + if (!tempDict) + { + return; + } + + const char* title = tempDict->valueForKey("title")->getCString(); + const char* description = tempDict->valueForKey("achievedDescription")->getCString(); + const char* icon = tempDict->valueForKey("icon")->getCString(); + + CCLog("[AchLog] Notifying: %s | %s | %s", title, description, icon); + + AchievementNotifier::sharedState()->notifyAchievement(title, description, icon); } -void AchievementManager::reportAchievementWithID(char const* achID, int percentage, bool param_3) +void AchievementManager::reportAchievementWithID(char const* achID, int percentage, bool skipNotify) { - if (!isAchievementEarned(achID)) { - if (percentForAchievement(achID) < percentage) { - /* imma do this later it's 10pm rn - this_00 = (CCDictionary *)(this->data).offset_0x8; - pCVar3 = (CCObject *)cocos2d::CCString::createWithFormat("%i",percentage); - std::string(&pcStack_24,achID,&pAStack_28); - cocos2d::CCDictionary::setObject(this_00,pCVar3,(string *)&pcStack_24); - FUN_003b16dc(&pcStack_24); - pAVar2 = (AchievementManager *)reportPlatformAchievementWithID(this,achID,percentage);*/ - } - if ((99 < percentage) && (!param_3)) { - AchievementManager* pAchManager = sharedState(); - pAchManager->notifyAchievementWithID(achID); - } + if (isAchievementEarned(achID)) + return; + + if (percentForAchievement(achID) < percentage) + { + // TODO: persist the new percentage + // CCString* pct = CCString::createWithFormat("%i", percentage); + // m_reportedAchievements->setObject(pct, achID); + // reportPlatformAchievementWithID(achID, percentage); + } + + // Notify the player only when fully completed (100%) and not suppressed + if (percentage > 99 && !skipNotify) + { + notifyAchievementWithID(achID); } } bool AchievementManager::isAchievementEarned(char const* achID) { + // TODO: check m_reportedAchievements / platform layer for 100% return false; } bool AchievementManager::areAchievementsEarned(CCArray* achSet) { + // TODO: iterate achSet and call isAchievementEarned for each entry return true; } int AchievementManager::percentForAchievement(char const* achID) { - return 100; -} + // TODO: look up persisted percentage from m_reportedAchievements + // Returning 0 so the < percentage guard in reportAchievementWithID actually passes. + return 0; +} \ No newline at end of file diff --git a/Classes/AchievementManager.h b/Classes/AchievementManager.h index ad581f7..34a6163 100644 --- a/Classes/AchievementManager.h +++ b/Classes/AchievementManager.h @@ -1,3 +1,6 @@ +// decompiled by ItzZyann +// from GD 1.71 binary + #ifndef _ACHIEVEMENT_MANAGER_H_ #define _ACHIEVEMENT_MANAGER_H_ @@ -6,18 +9,28 @@ class AchievementManager : public cocos2d::CCNode { public: AchievementManager(); - static AchievementManager* sharedState(); + virtual ~AchievementManager(); + static AchievementManager* sharedState(); virtual bool init(); + void notifyAchievementWithID(char const* achID); void reportAchievementWithID(char const* achID, int percentage, bool param_3); bool isAchievementEarned(char const* achID); bool areAchievementsEarned(cocos2d::CCArray* achSet); int percentForAchievement(char const* achID); - cocos2d::CCDictionary* m_allAchievements; // 0xe8 - CC_SYNTHESIZE(cocos2d::CCDictionary*, m_reportedAchievements, ReportedAchievements); // 0xf0 - bool m_dontNotifyAch; // 0xf4 -}; + void setup(); + void checkAchFromUnlock(char const* achID); + int percentageForCount(int count, int total); + cocos2d::CCDictionary* getAllAchievements(); + cocos2d::CCDictionary* getAchievementsWithID(char const* achID); + void resetAchievement(char const* achID); + void resetAchievements(); + void reportPlatformAchievementWithID(char const* achID, int percentage); + cocos2d::CCDictionary* m_allAchievements; + CC_SYNTHESIZE(cocos2d::CCDictionary*, m_reportedAchievements, ReportedAchievements); + bool m_dontNotifyAch; +}; #endif \ No newline at end of file diff --git a/Classes/AchievementNotifier.cpp b/Classes/AchievementNotifier.cpp index 3ec1426..49106f5 100644 --- a/Classes/AchievementNotifier.cpp +++ b/Classes/AchievementNotifier.cpp @@ -1,67 +1,110 @@ +// decompiled by ItzZyann +// from GD 1.71 binary + #include "AchievementNotifier.h" +#include "AchievementBar.h" #include "GameSoundManager.h" + USING_NS_CC; +static int s_achievementCount = 0; // zyann addition xd AchievementNotifier::AchievementNotifier() + : m_achArray(nullptr) + , m_currentAch(nullptr) { +} +AchievementNotifier::~AchievementNotifier() +{ + CC_SAFE_RELEASE(m_achArray); + CC_SAFE_RELEASE(m_currentAch); } AchievementNotifier* AchievementNotifier::sharedState() { - static AchievementNotifier* pAchNotifier = NULL; - if (!pAchNotifier) - { - pAchNotifier = new AchievementNotifier(); - pAchNotifier->init(); - } - - return pAchNotifier; + static AchievementNotifier* s_pNotifier = nullptr; + if (!s_pNotifier) + { + s_pNotifier = new AchievementNotifier(); + if (s_pNotifier && s_pNotifier->init()) + { + s_pNotifier->retain(); + } + } + return s_pNotifier; } bool AchievementNotifier::init() { m_achArray = CCArray::create(); m_achArray->retain(); - return true; + return true; } void AchievementNotifier::notifyAchievement(char const* title, char const* description, char const* icon) { AchievementBar* bar = AchievementBar::create(title, description, icon); - m_achArray->addObject(bar); - //if (m_currentAch == NULL) { - showNextAchievement(); - //return; - //} - return; + if (bar) + { + m_achArray->addObject(bar); + if (!m_currentAch) + { + showNextAchievement(); + } + } } void AchievementNotifier::showNextAchievement() { - if (!m_achArray->count()) { - return; + if (m_achArray->count() > 0) + { + float pitch = (s_achievementCount * 0.05f) + 1.0f; + GameSoundManager::sharedManager()->playEffect("achievement_01.ogg", pitch, 0.0f, 0.3f); + s_achievementCount++; + + m_currentAch = static_cast(m_achArray->objectAtIndex(0)); + m_currentAch->retain(); + + m_achArray->removeObjectAtIndex(0, false); // false to avoid immediate delete + + CCScene* runningScene = CCDirector::sharedDirector()->getRunningScene(); + if (runningScene) + { + runningScene->addChild(m_currentAch, 100); + } + + m_currentAch->show(); + } + else + { + s_achievementCount = 0; } - GameSoundManager::sharedManager()->playEffect("achievement_01.ogg", 1.0f, 0.0f, 1.0f); - // what??: DAT_004c6600 = (GameSoundManager *)((int)DAT_004c6600 + 1); - m_currentAch = (AchievementBar*)m_achArray->objectAtIndex(0); - m_currentAch->show(); - return; } void AchievementNotifier::achievementDisplayFinished() { - CCNode::removeMeAndCleanup(); + if (m_currentAch) + { + m_currentAch->removeFromParent(); + CC_SAFE_RELEASE(m_currentAch); + m_currentAch = nullptr; - if (m_currentAch != nullptr) { - m_currentAch->release(); + showNextAchievement(); } - - m_currentAch = nullptr; - this->showNextAchievement(); } void AchievementNotifier::willSwitchToScene(cocos2d::CCScene* scene) { + // re-parent the currently visible bar into the new scene + if (m_currentAch) + { + m_currentAch->retain(); + m_currentAch->removeFromParent(); + scene->addChild(m_currentAch, 100); + m_currentAch->release(); + } + // also re-create any queued bars so their parent references stay valid. + // they have no parent yet (they haven't been shown), so nothing to reparent + // but we make sure the array survives by simply keeping it. No action needed. } \ No newline at end of file diff --git a/Classes/AchievementNotifier.h b/Classes/AchievementNotifier.h index ce713b2..0e6606b 100644 --- a/Classes/AchievementNotifier.h +++ b/Classes/AchievementNotifier.h @@ -1,3 +1,6 @@ +// decompiled by ItzZyann +// from GD 1.71 binary + #ifndef _ACHIEVEMENT_NOTIFIER_H_ #define _ACHIEVEMENT_NOTIFIER_H_ @@ -7,12 +10,15 @@ class AchievementNotifier : public cocos2d::CCNode { public: AchievementNotifier(); + virtual ~AchievementNotifier(); static AchievementNotifier* sharedState(); virtual bool init(); + void notifyAchievement(char const* title, char const* description, char const* icon); void showNextAchievement(); void achievementDisplayFinished(); void willSwitchToScene(cocos2d::CCScene* scene); + protected: cocos2d::CCArray* m_achArray; AchievementBar* m_currentAch; diff --git a/Classes/AppDelegate.cpp b/Classes/AppDelegate.cpp index ce6f069..fbb161d 100644 --- a/Classes/AppDelegate.cpp +++ b/Classes/AppDelegate.cpp @@ -22,40 +22,42 @@ AppDelegate::~AppDelegate() AppDelegate* AppDelegate::get() { return static_cast(sharedApplication()); } bool AppDelegate::applicationDidFinishLaunching() { - - - // initialize director - CCDirector* pDirector = CCDirector::sharedDirector(); - CCEGLView* pEGLView = CCEGLView::sharedOpenGLView(); + // this fix the gradient bg + // being wacky + CCTexture2D::setDefaultAlphaPixelFormat(kCCTexture2DPixelFormat_RGBA8888); + + CCDirector* pDirector = CCDirector::sharedDirector(); + CCEGLView* pEGLView = CCEGLView::sharedOpenGLView(); - pDirector->setOpenGLView(pEGLView); + pDirector->setOpenGLView(pEGLView); pDirector->setProjection(kCCDirectorProjection2D); pDirector->setupScreenScale(CCSizeMake(480.0f, 320.0f)); - - CCTexture2D::setDefaultAlphaPixelFormat(kCCTexture2DPixelFormat_RGBA4444); - CCTexture2D::PVRImagesHavePremultipliedAlpha(true); - pDirector->setDepthTest(false); + pDirector->setContentScaleFactor(2.0f); + + // set the content scale factor to 2.0f for hd + // while 1.0 for low quality. + + CCTexture2D::setDefaultAlphaPixelFormat(kCCTexture2DPixelFormat_RGBA4444); + CCTexture2D::PVRImagesHavePremultipliedAlpha(true); + pDirector->setDepthTest(false); pDirector->setAnimationInterval(1.0 / 60.0); #if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32) CCFileUtils::sharedFileUtils()->addSearchPath("Resources"); #endif - - #if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS) + #if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS) #else this->m_isIOS = false; #endif CCContentManager::sharedManager(); - // check performance with this: pDirector->setDisplayStats(true); AdToolbox::setupAds(); - - // run - CCScene *pScene = LoadingLayer::scene(); - pDirector->runWithScene(pScene); - return true; + CCScene *pScene = LoadingLayer::scene(); + pDirector->runWithScene(pScene); + + return true; } // This function will be called when the app is inactive. When comes a phone call,it's be invoked too diff --git a/Classes/BoomScrollLayer.cpp b/Classes/BoomScrollLayer.cpp index 2413c18..fead655 100644 --- a/Classes/BoomScrollLayer.cpp +++ b/Classes/BoomScrollLayer.cpp @@ -2,8 +2,6 @@ #include "ExtendedLayer.h" USING_NS_CC; -// now for the real BoomScrollLayer code -// from what i can tell robtop just took CCScrollLayer's code and added more features to it BoomScrollLayer::BoomScrollLayer() { m_dotsArray = nullptr; @@ -36,29 +34,27 @@ BoomScrollLayer::BoomScrollLayer() BoomScrollLayer* BoomScrollLayer::create(cocos2d::CCArray* pages, int offset, bool looped) { - BoomScrollLayer* ret = new BoomScrollLayer(); - if (ret) { + BoomScrollLayer* ret = new BoomScrollLayer(); + if (ret) { if (ret->init(pages, offset, looped)) { - ret->autorelease(); - return ret; - } - - delete ret; - } - - return NULL; + ret->autorelease(); + return ret; + } + delete ret; + } + return NULL; } bool BoomScrollLayer::init(cocos2d::CCArray* pages, int offset, bool looped) { - if (!CCLayer::init()) - return false; - + if (!CCLayer::init()) + return false; + m_internalLayer = ExtendedLayer::create(); this->addChild(m_internalLayer); setObjType(CCObjectType::BoomScrollLayer); - setTouchEnabled(true); + setTouchEnabled(true); setStealTouches(true); setMinimumTouchLengthToSlide(40.0f); setMinimumTouchLengthToChangePage(100.0f); @@ -70,7 +66,6 @@ bool BoomScrollLayer::init(cocos2d::CCArray* pages, int offset, bool looped) setPagesIndicatorSelectedColor(ccc4(255, 255, 255, 255)); setScrollArea(CCRectMake(0.0f, 0.0f, WIN_SIZE.width, WIN_SIZE.height)); - // variables m_actualPages = pages; m_currentScreen = 0; m_pagesWidthOffset = offset; @@ -79,77 +74,78 @@ bool BoomScrollLayer::init(cocos2d::CCArray* pages, int offset, bool looped) m_touchSpeedFast = 0.6f; pages->retain(); + CCSpriteBatchNode* dots = CCSpriteBatchNode::create("smallDot.png", 29); - this->addChild(dots, 5); - m_dotsArray = CCArray::create(); + this->addChild(dots, 5); + m_dotsArray = CCArray::create(); m_dotsArray->retain(); - - for (int i = 0; i < getTotalPages(); ++i) - { - CCSprite* dot = CCSprite::create("smallDot.png"); - dots->addChild(dot); + + for (int i = 0; i < getTotalPages(); ++i) { + CCSprite* dot = CCSprite::create("smallDot.png"); + dots->addChild(dot); m_dotsArray->addObject(dot); - } - - this->updatePages(); + } - this->m_looped = looped; + this->updatePages(); + + m_looped = looped; if (looped) repositionPagesLooped(); this->schedule(schedule_selector(BoomScrollLayer::updateDots), 0.1f); - + return true; } void BoomScrollLayer::updateDots(float dt) { - if (!m_dotsArray) { + // guard was inverted in original, + // should be if (m_dotsArray), not if (!m_dotsArray) + if (m_dotsArray) { int pageNum = pageNumberForPosition(m_internalLayer->getPosition()); - + if (m_looped) pageNum = getRelativePageForNum(pageNum); - /*for (int i = 0; i < getTotalPages(); ++i) { - if (i < m_dotsArray->count()) { - CCSprite* dot = ((CCSprite*)m_dotsArray->objectAtIndex(i)); - ccColor3B dotColor = ccWHITE; - - if (i != pageNum) - dotColor = ccGRAY; - - dot->setColor(dotColor); + for (int i = 0; i < getTotalPages(); ++i) { + if (i < (int)m_dotsArray->count()) { + CCSprite* dot = (CCSprite*)m_dotsArray->objectAtIndex(i); + dot->setColor(i == pageNum ? ccWHITE : ccGRAY); + + // position each dot around m_pagesIndicatorPosition + dot->setPosition(ccp( + m_pagesIndicatorPosition.x + (i - getTotalPages() * 0.5f + 0.5f) * 14.0f, + m_pagesIndicatorPosition.y)); } - }*/ + } } } void BoomScrollLayer::updatePages() { - for (int i = 0; i < m_actualPages->count(); ++i) { + for (int i = 0; i < (int)m_actualPages->count(); ++i) { CCNode* page = (CCNode*)m_actualPages->objectAtIndex(i); page->setAnchorPoint(ccp(0.0f, 0.0f)); page->setContentSize(WIN_SIZE); - page->setPosition(ccp(getContentSize().width - getPagesWidthOffset(), 0.0f)); - + // FIX: pages should be positioned by index, not all at same X + page->setPosition(ccp( + (getContentSize().width + m_pagesWidthOffset) * i, + 0.0f)); + if (!page->getParent()) m_internalLayer->addChild(page); } } -bool BoomScrollLayer::ccTouchBegan(cocos2d::CCTouch *pTouch, cocos2d::CCEvent *pEvent) +bool BoomScrollLayer::ccTouchBegan(cocos2d::CCTouch* pTouch, cocos2d::CCEvent* pEvent) { - CCPoint touchLocation = pTouch->getLocation(); - - // CCLOG("x: %f, y: %f", touchLocation.x, touchLocation.y); - - return true; + return true; } void BoomScrollLayer::quickUpdate() { if (m_movingToPage) { - this->m_movingToPage = false; + m_movingToPage = false; m_internalLayer->stopActionByTag(2); m_internalLayer->setPosition(m_targetPos); moveToPageEnded(); @@ -158,110 +154,115 @@ void BoomScrollLayer::quickUpdate() void BoomScrollLayer::moveToPage(int page) { - if ((m_looped) || (-1 < page && (page < getTotalPages()))) { + if (m_looped || (-1 < page && page < getTotalPages())) { m_movingToPage = true; m_targetPos = positionForPageWithNumber(page); m_internalLayer->stopActionByTag(2); float speed; - if (m_touchSpeedFast < unk_0x118) + if (unk_0x118 > m_touchSpeedFast) speed = 0.4f; - else { + else if (unk_0x118 > m_touchSpeedMid) + speed = 0.6f; + else speed = 0.8f; - if (m_touchSpeedMid < unk_0x118) - speed = 0.6f; - } unk_0x118 = 0.0f; - CCMoveTo* moveAction = CCMoveTo::create((speed * 1.2f), m_targetPos); + + CCMoveTo* moveAction = CCMoveTo::create(speed * 1.2f, m_targetPos); CCEaseElasticOut* elasticMove = CCEaseElasticOut::create(moveAction, 0.5f); CCCallFunc* callback = CCCallFunc::create(this, callfunc_selector(BoomScrollLayer::moveToPageEnded)); CCSequence* sequence = CCSequence::create(elasticMove, callback, nullptr); - m_internalLayer->runAction(sequence); sequence->setTag(2); + m_internalLayer->runAction(sequence); + // update screen index immediately so onPrev/onNext reads correct value m_currentScreen = page; if (m_looped) repositionPagesLooped(); + if (m_delegate) + m_delegate->scrollLayerMoved(m_targetPos); } } void BoomScrollLayer::instantMoveToPage(int page) { - if ((m_looped) || ((-1 < page && (page < getTotalPages())))) { + if (m_looped || (-1 < page && page < getTotalPages())) { m_internalLayer->stopActionByTag(2); m_movingToPage = false; - m_internalLayer->setPosition(positionForPageWithNumber(page)); + CCPoint pos = positionForPageWithNumber(page); + m_internalLayer->setPosition(pos); m_currentScreen = page; if (m_looped) repositionPagesLooped(); + if (m_delegate) + m_delegate->scrollLayerMoved(pos); + moveToPageEnded(); } } void BoomScrollLayer::moveToPageEnded() { - // THIS part isn't accurate just THIS part specifically - if ((m_animatingToPage != m_currentScreen) && (m_delegate)) { + if ((m_animatingToPage != m_currentScreen) && m_delegate) { m_delegate->scrollLayerScrollingStarted(this); } m_internalLayer->stopActionByTag(2); + + // FIX: use our corrected pageNumberForPosition int pageNum = pageNumberForPosition(m_internalLayer->getPosition()); m_currentScreen = pageNum; m_animatingToPage = pageNum; - this->updateDots(0.0f); + + if (m_delegate) + m_delegate->scrollLayerScrolledToPage(this, pageNum); + + updateDots(0.0f); } -// https://github.com/geode-sdk/bindings/blob/main/bindings/2.208/inline/BoomScrollLayer.cpp#L21 +// this part really hurts my head +// pages go left as index increases, so internalLayer moves in negative X. +// positionForPageWithNumber and pageNumberForPosition must be inverses. CCPoint BoomScrollLayer::positionForPageWithNumber(int page) { - return ccp((getContentSize().width + m_pagesWidthOffset) * page, 0.f); + // FIX: negative X so pages scroll left correctly + return ccp(-((getContentSize().width + m_pagesWidthOffset) * (float)page), 0.0f); } CCPoint BoomScrollLayer::getRelativePosForPage(int page) { - return ccp((getContentSize().width - m_pagesWidthOffset) * page, 0.f); + return ccp((getContentSize().width - m_pagesWidthOffset) * (float)page, 0.0f); } void BoomScrollLayer::repositionPagesLooped() { int page1 = getRelativePageForNum(m_currentScreen); - int page2 = getRelativePageForNum(m_currentScreen + -1); + int page2 = getRelativePageForNum(m_currentScreen - 1); int page3 = getRelativePageForNum(m_currentScreen + 1); - int actualPage3 = page3; int actualPage2 = page2; + int actualPage3 = page3; if (unk_0x124) { getPage(m_currentScreen)->setPosition(getRelativePosForPage(m_currentScreen)); - actualPage2 = this->m_currentScreen - 1; - actualPage3 = this->m_currentScreen + 1; + actualPage2 = m_currentScreen - 1; + actualPage3 = m_currentScreen + 1; } getPage(actualPage2)->setPosition(getRelativePosForPage(actualPage2)); getPage(actualPage3)->setPosition(getRelativePosForPage(actualPage3)); - - for (int i = 0; i < m_actualPages->count(); ++i) { - CCLayer* tmpPage = (CCLayer*)(m_actualPages->objectAtIndex(i)); - tmpPage->setVisible(false); - } + + for (int i = 0; i < (int)m_actualPages->count(); ++i) + ((CCLayer*)m_actualPages->objectAtIndex(i))->setVisible(false); getPage(page1)->setVisible(true); getPage(actualPage2)->setVisible(true); getPage(actualPage3)->setVisible(true); - if (unk_0x124) { - /*getPage(m_currentScreen); - unk_0x120->objectAtIndex(page1); - getPage(m_currentScreen + -1); - unk_0x120->objectAtIndex(page2); - getPage(m_currentScreen + 1); - unk_0x120->objectAtIndex(page3);*/ - } } void BoomScrollLayer::setPagesIndicatorPosition(CCPoint position) @@ -272,25 +273,30 @@ void BoomScrollLayer::setPagesIndicatorPosition(CCPoint position) int BoomScrollLayer::getTotalPages() { - CCArray* pagesArray; - if (!unk_0x124) - pagesArray = m_actualPages; - else - pagesArray = unk_0x120; - - return pagesArray->count(); + CCArray* pagesArray = unk_0x124 ? unk_0x120 : m_actualPages; + return (int)pagesArray->count(); } +// FIX: proper inverse of positionForPageWithNumber +// pos.x is negative, so negate it before dividing int BoomScrollLayer::pageNumberForPosition(CCPoint pos) { - // todo - return 1; + float pageWidth = getContentSize().width + m_pagesWidthOffset; + if (pageWidth == 0.0f) + return 0; + + int page = (int)roundf(-pos.x / pageWidth); + + int total = getTotalPages(); + if (page < 0) page = 0; + if (page >= total) page = total - 1; + + return page; } -// https://github.com/geode-sdk/bindings/blob/main/bindings/2.208/inline/BoomScrollLayer.cpp#L111 int BoomScrollLayer::getRelativePageForNum(int page) { - int pages = this->getTotalPages(); + int pages = getTotalPages(); if (page > 0) return page % pages; while (page < 0) page += pages; return page; @@ -298,32 +304,28 @@ int BoomScrollLayer::getRelativePageForNum(int page) CCLayer* BoomScrollLayer::getPage(int page) { - // somehow this isn't 100% accurate :/ if (unk_0x124) { - int totalPgs = m_actualPages->count(); - if (page < 1) + int totalPgs = (int)m_actualPages->count(); + if (page < 0) for (; page < 0; page += totalPgs) {} else page %= totalPgs; } - return (CCLayer*)m_actualPages->objectAtIndex(page); } -// Dynamic Pages Control - void BoomScrollLayer::addPage(CCLayer* aPage) { - addPage(aPage, m_actualPages->count()); + addPage(aPage, (int)m_actualPages->count()); } void BoomScrollLayer::addPage(CCLayer* aPage, int pageNumber) { - pageNumber = MIN(pageNumber, m_actualPages->count()); + pageNumber = MIN(pageNumber, (int)m_actualPages->count()); pageNumber = MAX(pageNumber, 0); m_actualPages->insertObject(aPage, pageNumber); updatePages(); moveToPage(m_currentScreen); -} +} \ No newline at end of file diff --git a/Classes/ButtonSprite.cpp b/Classes/ButtonSprite.cpp new file mode 100644 index 0000000..9c8619e --- /dev/null +++ b/Classes/ButtonSprite.cpp @@ -0,0 +1,269 @@ +// decompiled by ItzZyann +// from GD 1.71 binary + +#include "ButtonSprite.h" +#include "RT_COCOS/CCMenuItemSpriteExtra.h" + +USING_NS_CC; + +ButtonSprite::ButtonSprite() { + m_buttonType = 0; + m_width = 0.0f; + m_height = 0.0f; + m_customScale = 0.0f; + m_absoluteHeight = 0.0f; + m_absoluteWidth = false; + m_label = nullptr; + m_subSprite = nullptr; + m_bgSprite = nullptr; + m_textPositionOffset = cocos2d::CCPoint(0.0f, 0.0f); + m_textStr = ""; +} + +ButtonSprite::~ButtonSprite() { +} + +void ButtonSprite::updateSpriteBGSize() { + float finalWidth = 0.0f; + if (m_absoluteWidth) { + finalWidth = m_width; + } + else { + float spriteW = m_subSprite->getContentSize().width; + if (m_height < (spriteW * m_subSprite->getScale())) { + finalWidth = m_subSprite->getContentSize().width * m_subSprite->getScale(); + } + else { + finalWidth = m_height; + } + } + + float rectH = 40.0f; + float finalWidthOffset = finalWidth + 8.0f; + float spriteH = m_subSprite->getContentSize().height; + float finalHeight = 0.0f; + + if (rectH >= ((spriteH * m_subSprite->getScale()) + 8.0f)) { + finalHeight = 40.0f; + } + else { + finalHeight = (m_subSprite->getContentSize().height * m_subSprite->getScale()) + 8.0f; + } + + m_bgSprite->setContentSize(CCSize(finalWidthOffset, finalHeight)); + this->setContentSize(CCSize(m_bgSprite->getContentSize().width, m_bgSprite->getContentSize().height)); + + float halfWidth = this->getContentSize().width * 0.5f; + float halfHeight = this->getContentSize().height * 0.5f; + + m_subSprite->setPosition(ccp(halfWidth + 0.0f, halfHeight + 2.0f)); + m_bgSprite->setPosition(ccp(halfWidth, halfHeight)); + + if (this->getParent()) { + CCMenuItemSpriteExtra* parentNode = dynamic_cast(this->getParent()); + if (parentNode) { + parentNode->setContentSize(this->getContentSize()); + this->setPosition(ccp(this->getContentSize().width * 0.5f, this->getContentSize().height * 0.5f)); + } + } +} + +bool ButtonSprite::init(cocos2d::CCSprite* sprite, int width, int height, float scale, float customScale, bool absoluteWidth, const char* bgImage) { + if (!cocos2d::CCSprite::init()) { + return false; + } + + m_subSprite = sprite; + m_customScale = customScale; + m_buttonType = 0; + m_width = (float)width; + m_absoluteWidth = absoluteWidth; + m_height = (float)height; + + this->addChild(sprite, 1); + + m_bgSprite = cocos2d::extension::CCScale9Sprite::create(bgImage, CCRect(0.0f, 0.0f, 40.0f, 40.0f)); + m_bgSprite->setContentSize(CCSize(16.0f, 16.0f)); + this->addChild(m_bgSprite, 0); + + if (m_width > 0.0f) { + if (m_subSprite->getContentSize().width > m_width) { + m_subSprite->setScale(m_width / m_subSprite->getContentSize().width); + } + } + + if (scale > 0.0f && m_subSprite->getContentSize().height > scale) { + float heightScale = scale / m_subSprite->getContentSize().height; + if (heightScale < m_subSprite->getScale()) { + m_subSprite->setScale(scale / m_subSprite->getContentSize().height); + } + } + + float finalScale = m_subSprite->getScale(); + if (finalScale <= m_customScale) { + finalScale = m_customScale; + } + m_subSprite->setScale(finalScale); + + this->updateSpriteBGSize(); + return true; +} + +ButtonSprite* ButtonSprite::create(cocos2d::CCSprite* sprite, int width, int height, float scale, float customScale, bool absoluteWidth, const char* bgImage, const char* font) { + ButtonSprite* pRet = new ButtonSprite(); + if (pRet && pRet->init(sprite, width, height, scale, customScale, absoluteWidth, bgImage)) { + pRet->autorelease(); + return pRet; + } + CC_SAFE_DELETE(pRet); + return nullptr; +} + +ButtonSprite* ButtonSprite::create(cocos2d::CCSprite* sprite, int width, int height, const char* text, float scale, float customScale, bool absoluteWidth) { + return ButtonSprite::create(sprite, width, height, scale, customScale, absoluteWidth, "GJ_button_01.png", text); +} + +ButtonSprite* ButtonSprite::create(cocos2d::CCSprite* sprite, bool absoluteWidth) { + return ButtonSprite::create(sprite, 0, 0, 0.0f, 1.0f, absoluteWidth, "GJ_button_01.png", nullptr); +} + +void ButtonSprite::setString(const char* text) { + if (m_buttonType == 1) { + m_label->setScale(1.0f); + m_label->setString(text); + m_textStr = text; + + if (m_width > 0.0f) { + if (m_label->getContentSize().width > m_width) { + m_label->setScale(m_width / m_label->getContentSize().width); + } + } + + float scaleCheck = m_label->getScale(); + if (scaleCheck <= m_customScale) { + scaleCheck = m_customScale; + } + m_label->setScale(scaleCheck); + + float finalWidth = 0.0f; + if (m_absoluteWidth) { + finalWidth = m_width; + } + else { + float labelW = m_label->getContentSize().width; + if (m_height < (labelW * m_label->getScale())) { + finalWidth = m_label->getContentSize().width * m_label->getScale(); + } + else { + finalWidth = m_height; + } + } + + float targetHeight = m_absoluteHeight; + bool isZeroHeight = (targetHeight == 0.0f); + if (isZeroHeight) { + targetHeight = 4.0f; + } + if (isZeroHeight) { + targetHeight = m_label->getContentSize().height + targetHeight; + } + + m_bgSprite->setContentSize(CCSize(finalWidth + 16.0f, targetHeight)); + this->setContentSize(CCSize(m_bgSprite->getContentSize().width, m_bgSprite->getContentSize().height)); + + float xPos = m_textPositionOffset.x + (this->getContentSize().width * 0.5f); + float yPos = m_textPositionOffset.y + (this->getContentSize().height * 0.5f); + m_label->setPosition(ccp(xPos, yPos)); + + m_bgSprite->setPosition(ccp(this->getContentSize().width * 0.5f, this->getContentSize().height * 0.5f)); + + if (this->getParent()) { + CCMenuItemSpriteExtra* parentNode = dynamic_cast(this->getParent()); + if (parentNode) { + parentNode->setContentSize(this->getContentSize()); + this->setPosition(ccp(this->getContentSize().width * 0.5f, this->getContentSize().height * 0.5f)); + } + } + } +} + +void ButtonSprite::updateBGImage(const char* bgImage) { + m_bgSprite->removeFromParentAndCleanup(true); + m_bgSprite = cocos2d::extension::CCScale9Sprite::create(bgImage, CCRect(0.0f, 0.0f, 40.0f, 40.0f)); + m_bgSprite->setContentSize(CCSize(16.0f, 16.0f)); + this->addChild(m_bgSprite, 0); + + if (m_buttonType == 1) { + this->setString(m_textStr); + } + else { + this->updateSpriteBGSize(); + } +} + +bool ButtonSprite::init(const char* caption, int width, int height, float scale, bool absoluteWidth, const char* font, const char* bgImage, float absoluteHeight) { + if (!cocos2d::CCSprite::init()) { + return false; + } + + m_buttonType = 1; + m_customScale = scale; + m_width = (float)width; + m_absoluteWidth = absoluteWidth; + m_absoluteHeight = absoluteHeight; + m_height = (float)height; + + m_textPositionOffset = ccp(0.0f, 2.0f); + + if (strcmp(font, "bigFont.fnt") != 0) { + m_textPositionOffset = ccp(-1.0f, 2.0f); + } + + m_label = CCLabelBMFont::create("", font); + this->addChild(m_label, 1); + + m_bgSprite = cocos2d::extension::CCScale9Sprite::create(bgImage, CCRect(0.0f, 0.0f, 40.0f, 40.0f)); + m_bgSprite->setContentSize(CCSize(16.0f, 16.0f)); + this->addChild(m_bgSprite, 0); + + this->setString(caption); + return true; +} + +ButtonSprite* ButtonSprite::create(const char* caption, int width, int height, float scale, bool absoluteWidth, const char* font, const char* bgImage, float absoluteHeight) { + ButtonSprite* pRet = new ButtonSprite(); + if (pRet && pRet->init(caption, width, height, scale, absoluteWidth, font, bgImage, absoluteHeight)) { + pRet->autorelease(); + return pRet; + } + CC_SAFE_DELETE(pRet); + return nullptr; +} + +ButtonSprite* ButtonSprite::create(const char* caption, int width, int height, float scale, bool absoluteWidth, const char* font, const char* bgImage) { + return ButtonSprite::create(caption, width, height, scale, absoluteWidth, font, bgImage, 0.0f); +} + +ButtonSprite* ButtonSprite::create(const char* caption, int width, int height, float scale, bool absoluteWidth) { + return ButtonSprite::create(caption, width, height, scale, absoluteWidth, "goldFont.fnt", "GJ_button_01.png", 0.0f); +} + +ButtonSprite* ButtonSprite::create(const char* caption, float scale) { + return ButtonSprite::create(caption, 0, 0, scale, false); +} + +ButtonSprite* ButtonSprite::create(const char* caption) { + return ButtonSprite::create(caption, 0, 0, 1.0f, false); +} + +void ButtonSprite::setColor(const cocos2d::ccColor3B& color) { + if (m_label) { + m_label->setColor(color); + } + if (m_subSprite) { + m_subSprite->setColor(color); + } + if (m_bgSprite) { + m_bgSprite->setColor(color); + } +} \ No newline at end of file diff --git a/Classes/ButtonSprite.h b/Classes/ButtonSprite.h new file mode 100644 index 0000000..5bcde7a --- /dev/null +++ b/Classes/ButtonSprite.h @@ -0,0 +1,45 @@ +// decompiled by ItzZyann +// from GD 1.71 binary + +#ifndef __BUTTONSPRITE_H__ +#define __BUTTONSPRITE_H__ + +#include "cocos2d.h" +#include "cocos-ext.h" + +class ButtonSprite : public cocos2d::CCSprite { +public: + ButtonSprite(); + virtual ~ButtonSprite(); + + static ButtonSprite* create(cocos2d::CCSprite* sprite, int width, int height, float scale, float customScale, bool absoluteWidth, const char* bgImage, const char* font); + static ButtonSprite* create(cocos2d::CCSprite* sprite, int width, int height, const char* text, float scale, float customScale, bool absoluteWidth); + static ButtonSprite* create(cocos2d::CCSprite* sprite, bool absoluteWidth); + static ButtonSprite* create(const char* caption, int width, int height, float scale, bool absoluteWidth, const char* font, const char* bgImage, float absoluteHeight); + static ButtonSprite* create(const char* caption, int width, int height, float scale, bool absoluteWidth, const char* font, const char* bgImage); + static ButtonSprite* create(const char* caption, int width, int height, float scale, bool absoluteWidth); + static ButtonSprite* create(const char* caption, float scale); + static ButtonSprite* create(const char* caption); + + bool init(cocos2d::CCSprite* sprite, int width, int height, float scale, float customScale, bool absoluteWidth, const char* bgImage); + bool init(const char* caption, int width, int height, float scale, bool absoluteWidth, const char* font, const char* bgImage, float absoluteHeight); + + void updateSpriteBGSize(); + void setString(const char* text); + void updateBGImage(const char* bgImage); + virtual void setColor(const cocos2d::ccColor3B& color) override; + + CC_SYNTHESIZE(int, m_buttonType, ButtonType); + CC_SYNTHESIZE(float, m_width, Width); + CC_SYNTHESIZE(float, m_height, Height); + CC_SYNTHESIZE(float, m_customScale, CustomScale); + CC_SYNTHESIZE(float, m_absoluteHeight, AbsoluteHeight); + CC_SYNTHESIZE(bool, m_absoluteWidth, AbsoluteWidth); + CC_SYNTHESIZE(cocos2d::CCLabelBMFont*, m_label, Label); + CC_SYNTHESIZE(cocos2d::CCSprite*, m_subSprite, SubSprite); + CC_SYNTHESIZE(cocos2d::extension::CCScale9Sprite*, m_bgSprite, BgSprite); + CC_SYNTHESIZE(cocos2d::CCPoint, m_textPositionOffset, TextPositionOffset); + CC_SYNTHESIZE(const char*, m_textStr, TextStr); +}; + +#endif \ No newline at end of file diff --git a/Classes/CCContentManager.cpp b/Classes/CCContentManager.cpp new file mode 100644 index 0000000..b9bb0b8 --- /dev/null +++ b/Classes/CCContentManager.cpp @@ -0,0 +1,42 @@ +// from matcool/cocos2d-x-gd +#include "CCContentManager.h" + +using namespace cocos2d; + +CCContentManager* CCContentManager::sharedManager() { + static CCContentManager* sharedManager = nullptr; + if (!sharedManager) { + sharedManager = new CCContentManager(); + sharedManager->init(); + } + return sharedManager; +} +CCContentManager::CCContentManager() {} +bool CCContentManager::init() { + m_pDicts = CCDictionary::create(); + m_pDicts->retain(); + return true; +} + +CCDictionary* CCContentManager::addDict(const char* filePath, bool unk) { + /*CCDictionary* obj = static_cast(m_pDicts->objectForKey(filePath)); + if (!obj) { + DS_Dictionary* dsDict = new DS_Dictionary(); + dsDict->loadRootSubDictFromFile(filePath); + obj = dsDict->getDictForKey(nullptr); + delete dsDict; + m_pDicts->setObject(obj, filePath); + } + return obj;*/ + + // yeah so this just DOESNT work so deal with this fix for now + return CCDictionary::createWithContentsOfFile(filePath); +} +/* +cocos2d::CCDictionary* CCContentManager::addDictDS(const char* dict) { + ROB_UNIMPLEMENTED(); +} + +void CCContentManager::clearCache() { + ROB_UNIMPLEMENTED(); +}*/ \ No newline at end of file diff --git a/Classes/ColoredSection.cpp b/Classes/ColoredSection.cpp index 079118f..67091e2 100644 --- a/Classes/ColoredSection.cpp +++ b/Classes/ColoredSection.cpp @@ -1,7 +1,8 @@ #include "ColoredSection.h" + USING_NS_CC; -ColoredSection* ColoredSection::create(ccColor3B col, int startPos, int endPos) +ColoredSection* ColoredSection::create(cocos2d::ccColor3B col, int startPos, int endPos) { ColoredSection* pRet = new ColoredSection(); if (pRet && pRet->init(col, startPos, endPos)) @@ -9,19 +10,34 @@ ColoredSection* ColoredSection::create(ccColor3B col, int startPos, int endPos) pRet->autorelease(); return pRet; } - else - { - delete pRet; - pRet = NULL; - return NULL; - } + CC_SAFE_DELETE(pRet); + return NULL; } - -bool ColoredSection::init(ccColor3B col, int startPos, int endPos) +bool ColoredSection::init(cocos2d::ccColor3B col, int startPos, int endPos) { m_col = col; - m_startPos = startPos; + m_startPos = static_cast(startPos); m_endPos = endPos; return true; +} + +int ColoredSection::getStartIndex() +{ + return static_cast(m_startPos); +} + +void ColoredSection::setStartIndex(int index) +{ + m_startPos = static_cast(index); +} + +int ColoredSection::getEndIndex() +{ + return m_endPos; +} + +cocos2d::ccColor3B ColoredSection::getColor() +{ + return m_col; } \ No newline at end of file diff --git a/Classes/ColoredSection.h b/Classes/ColoredSection.h index 0ce16db..11a96c4 100644 --- a/Classes/ColoredSection.h +++ b/Classes/ColoredSection.h @@ -8,10 +8,14 @@ class ColoredSection : public cocos2d::CCObject { static ColoredSection* create(cocos2d::ccColor3B col, int startPos, int endPos); bool init(cocos2d::ccColor3B col, int startPos, int endPos); - CC_SYNTHESIZE(cocos2d::ccColor3B, m_col, Col); // 0x18 - CC_SYNTHESIZE(float, m_startPos, StartPos); // 0x1c - CC_SYNTHESIZE(int, m_endPos, EndPos); // 0x20 + int getStartIndex(); + void setStartIndex(int index); + int getEndIndex(); + cocos2d::ccColor3B getColor(); + CC_SYNTHESIZE(cocos2d::ccColor3B, m_col, Col); + CC_SYNTHESIZE(float, m_startPos, StartPos); + CC_SYNTHESIZE(int, m_endPos, EndPos); }; #endif \ No newline at end of file diff --git a/Classes/CreatorLayer.cpp b/Classes/CreatorLayer.cpp index a2c104f..78b0501 100644 --- a/Classes/CreatorLayer.cpp +++ b/Classes/CreatorLayer.cpp @@ -12,60 +12,49 @@ USING_NS_CC; CreatorLayer::CreatorLayer() { - + } CCScene* CreatorLayer::scene() { - // 'scene' is an autorelease object - CCScene* scene = CCScene::create(); - - AppDelegate* pApp = AppDelegate::get(); - pApp->setScenePointer(scene); - - // 'layer' is an autorelease object - CreatorLayer* layer = CreatorLayer::create(); - - // add layer as a child to scene - scene->addChild(layer); - - // return the scene - return scene; + CCScene* scene = CCScene::create(); + + AppDelegate* pApp = AppDelegate::get(); + pApp->setScenePointer(scene); + + CreatorLayer* layer = CreatorLayer::create(); + + scene->addChild(layer); + + return scene; } void CreatorLayer::onBack(CCObject* sender) { - CCDirector* pDirector = CCDirector::sharedDirector(); - CCScene* scene = MenuLayer::scene(); - CCTransitionFade* fade = CCTransitionFade::create(0.5f, scene); - pDirector->replaceScene(fade); + CCDirector* pDirector = CCDirector::sharedDirector(); + CCScene* scene = MenuLayer::scene(); + CCTransitionFade* fade = CCTransitionFade::create(0.5f, scene); + pDirector->replaceScene(fade); } void CreatorLayer::onMyLevels(CCObject* sender) { - CCDirector* pDirector = CCDirector::sharedDirector(); CCScene* scene = LevelEditorLayer::scene(GameLevelManager::sharedState()->getMainLevel(2)); - // CCScene* scene = LevelEditorLayer::scene(GJSearchObject::create(SearchType::MyLevels)); CCTransitionFade* fade = CCTransitionFade::create(0.5f, scene); pDirector->replaceScene(fade); - } void CreatorLayer::onSearch(CCObject* sender) { - GameLevelManager* GLM = GameLevelManager::sharedState(); - GLM->downloadLevel(108); - /*CCDirector* pDirector = CCDirector::sharedDirector(); - CCScene* scene = LevelInfoLayer::scene(); - CCTransitionFade* fade = CCTransitionFade::create(0.5f, scene); - pDirector->replaceScene(fade);*/ + GameLevelManager* GLM = GameLevelManager::sharedState(); + GLM->downloadLevel(108); } void CreatorLayer::onLeaderboards(cocos2d::CCObject *sender) { - GameLevelManager* GLM = GameLevelManager::sharedState(); - GLM->getLeaderboardScores("leaderboards_top"); + GameLevelManager* GLM = GameLevelManager::sharedState(); + GLM->getLeaderboardScores("leaderboards_top"); } void CreatorLayer::onFeaturedLevels(cocos2d::CCObject *sender) @@ -76,92 +65,95 @@ void CreatorLayer::onFeaturedLevels(cocos2d::CCObject *sender) CCTransitionFade* fade = CCTransitionFade::create(0.5f, scene); pDirector->replaceScene(fade); GameManager::sharedState()->setLastScene(LastGameScene::SearchScene); - } bool CreatorLayer::init() { - if (!CCLayer::init()) - return false; - - CCDirector* pDirector = CCDirector::sharedDirector(); - CCSize winSize = pDirector->getWinSize(); - - CCSprite* m_backgroundSprite; - - m_backgroundSprite = CCSprite::create("GJ_gradientBG.png"); - m_backgroundSprite->setAnchorPoint(CCPoint(0.0f, 0.0f)); - this->addChild(m_backgroundSprite, -2); - m_backgroundSprite->setScaleX((winSize.width + 10.0f) / m_backgroundSprite->getTextureRect().size.width); - m_backgroundSprite->setScaleY((winSize.height + 10.0f) / m_backgroundSprite->getTextureRect().size.height); - m_backgroundSprite->setPosition(CCPoint(-5.0f, -5.0f)); - m_backgroundSprite->setColor(ccc3(0, 102, 255)); - - CCSprite* sideArtTL = CCSprite::createWithSpriteFrameName("GJ_sideArt_001.png"); - sideArtTL->setAnchorPoint(CCPoint(0.0f, 0.0f)); - sideArtTL->setPosition(CCPoint(pDirector->getScreenLeft() - 1.0f, pDirector->getScreenTop() - 71.0f)); - sideArtTL->setFlipY(true); - this->addChild(sideArtTL, 1); - - CCSprite* sideArtTR = CCSprite::createWithSpriteFrameName("GJ_sideArt_001.png"); - sideArtTR->setAnchorPoint(CCPoint(1.0f, 0.0f)); - sideArtTR->setPosition(CCPoint(pDirector->getScreenRight() + 1.0f, pDirector->getScreenTop() - 71.0f)); - sideArtTR->setFlipY(true); - sideArtTR->setFlipX(true); - this->addChild(sideArtTR, 1); - - CCSprite* sideArtBL = CCSprite::createWithSpriteFrameName("GJ_sideArt_001.png"); - sideArtBL->setAnchorPoint(CCPoint(0.0f, 0.0f)); - sideArtBL->setPosition(CCPoint(pDirector->getScreenLeft() - 1.0f, pDirector->getScreenBottom() - 1.0f)); - this->addChild(sideArtBL, 1); - - CCSprite* sideArtBR = CCSprite::createWithSpriteFrameName("GJ_sideArt_001.png"); - sideArtBR->setAnchorPoint(CCPoint(1.0f, 0.0f)); - sideArtBR->setPosition(CCPoint(pDirector->getScreenRight() + 1.0f, pDirector->getScreenBottom() - 1.0f)); - sideArtBR->setFlipX(true); - this->addChild(sideArtBR, 1); - - CCSprite* backBtnSprite = CCSprite::createWithSpriteFrameName("GJ_arrow_03_001.png"); - CCMenuItemSpriteExtra* backBtn = CCMenuItemSpriteExtra::create(backBtnSprite, NULL, this, menu_selector(CreatorLayer::onBack)); - backBtn->setSizeMult(1.6f); - CCMenu* backMenu = CCMenu::create(backBtn, NULL); - this->addChild(backMenu, 1); - backMenu->setPosition(CCPoint(pDirector->getScreenLeft() + 25.0f, pDirector->getScreenTop() - 22.0f)); - - CCMenu* creatorMenu = CCMenu::create(); - - - CCSprite* createBtn = CCSprite::createWithSpriteFrameName("GJ_createBtn_001.png"); + if (!CCLayer::init()) + return false; + + CCDirector* pDirector = CCDirector::sharedDirector(); + CCSize winSize = pDirector->getWinSize(); + + float xPadding = 120.0f; + float yPadding = 63.0f; + float xOffset = 0.0f; + float yOffset = 0.0f; + + CCSprite* m_backgroundSprite; + + m_backgroundSprite = CCSprite::create("GJ_gradientBG.png"); + m_backgroundSprite->setAnchorPoint(CCPoint(0.0f, 0.0f)); + this->addChild(m_backgroundSprite, -2); + m_backgroundSprite->setScaleX((winSize.width + 10.0f) / m_backgroundSprite->getTextureRect().size.width); + m_backgroundSprite->setScaleY((winSize.height + 10.0f) / m_backgroundSprite->getTextureRect().size.height); + m_backgroundSprite->setPosition(CCPoint(-5.0f, -5.0f)); + m_backgroundSprite->setColor(ccc3(0, 102, 255)); + + CCSprite* sideArtTL = CCSprite::createWithSpriteFrameName("GJ_sideArt_001.png"); + sideArtTL->setAnchorPoint(CCPoint(0.0f, 0.0f)); + sideArtTL->setPosition(CCPoint(pDirector->getScreenLeft() - 1.0f, pDirector->getScreenTop() - 71.0f)); + sideArtTL->setFlipY(true); + this->addChild(sideArtTL, 1); + + CCSprite* sideArtTR = CCSprite::createWithSpriteFrameName("GJ_sideArt_001.png"); + sideArtTR->setAnchorPoint(CCPoint(1.0f, 0.0f)); + sideArtTR->setPosition(CCPoint(pDirector->getScreenRight() + 1.0f, pDirector->getScreenTop() - 71.0f)); + sideArtTR->setFlipY(true); + sideArtTR->setFlipX(true); + this->addChild(sideArtTR, 1); + + CCSprite* sideArtBL = CCSprite::createWithSpriteFrameName("GJ_sideArt_001.png"); + sideArtBL->setAnchorPoint(CCPoint(0.0f, 0.0f)); + sideArtBL->setPosition(CCPoint(pDirector->getScreenLeft() - 1.0f, pDirector->getScreenBottom() - 1.0f)); + this->addChild(sideArtBL, 1); + + CCSprite* sideArtBR = CCSprite::createWithSpriteFrameName("GJ_sideArt_001.png"); + sideArtBR->setAnchorPoint(CCPoint(1.0f, 0.0f)); + sideArtBR->setPosition(CCPoint(pDirector->getScreenRight() + 1.0f, pDirector->getScreenBottom() - 1.0f)); + sideArtBR->setFlipX(true); + this->addChild(sideArtBR, 1); + + CCSprite* backBtnSprite = CCSprite::createWithSpriteFrameName("GJ_arrow_03_001.png"); + CCMenuItemSpriteExtra* backBtn = CCMenuItemSpriteExtra::create(backBtnSprite, NULL, this, menu_selector(CreatorLayer::onBack)); + backBtn->setSizeMult(1.6f); + CCMenu* backMenu = CCMenu::create(backBtn, NULL); + this->addChild(backMenu, 1); + backMenu->setPosition(CCPoint(pDirector->getScreenLeft() + 25.0f, pDirector->getScreenTop() - 22.0f)); + + CCMenu* creatorMenu = CCMenu::create(); + this->addChild(creatorMenu); + creatorMenu->setPosition(CCPoint(winSize.width * 0.5f, (winSize.height * 0.5f) + 5.0f)); + + CCSprite* createBtn = CCSprite::createWithSpriteFrameName("GJ_createBtn_001.png"); CCMenuItemSpriteExtra* createExtra = CCMenuItemSpriteExtra::create(createBtn, NULL, this, menu_selector(CreatorLayer::onMyLevels)); - creatorMenu->addChild(createExtra); - this->addChild(creatorMenu); - creatorMenu->setPosition(CCPoint(winSize.width * 0.5f, (winSize.height * 0.5f) + 10.0f)); - createExtra->setPosition(m_backgroundSprite->getPosition() + CCPoint(-110.0f, 55.0f)); - - CCSprite* savedBtn = CCSprite::createWithSpriteFrameName("GJ_savedBtn_001.png"); - CCMenuItemSpriteExtra* savedExtra = CCMenuItemSpriteExtra::create(savedBtn, NULL, this, menu_selector(CreatorLayer::onBack)); - creatorMenu->addChild(savedExtra); - savedExtra->setPosition(m_backgroundSprite->getPosition() + CCPoint(0.0f, 55.0f)); - - CCSprite* scoreBtn = CCSprite::createWithSpriteFrameName("GJ_highscoreBtn_001.png"); - CCMenuItemSpriteExtra* scoreExtra = CCMenuItemSpriteExtra::create(scoreBtn, NULL, this, menu_selector(CreatorLayer::onLeaderboards)); - creatorMenu->addChild(scoreExtra); - scoreExtra->setPosition(m_backgroundSprite->getPosition() + CCPoint(110.0f, 55.0f)); - - CCSprite* featuredBtn = CCSprite::createWithSpriteFrameName("GJ_featuredBtn_001.png"); - CCMenuItemSpriteExtra* featuredExtra = CCMenuItemSpriteExtra::create(featuredBtn, NULL, this, menu_selector(CreatorLayer::onFeaturedLevels)); - creatorMenu->addChild(featuredExtra); - featuredExtra->setPosition(m_backgroundSprite->getPosition() + CCPoint(-110.0f, -55.0f)); - - CCSprite* mapPacksBtn = CCSprite::createWithSpriteFrameName("GJ_mapPacksBtn_001.png"); - CCMenuItemSpriteExtra* mapPacksExtra = CCMenuItemSpriteExtra::create(mapPacksBtn, NULL, this, menu_selector(CreatorLayer::onBack)); - creatorMenu->addChild(mapPacksExtra); - mapPacksExtra->setPosition(m_backgroundSprite->getPosition() + CCPoint(0.0f, -55.0f)); - - CCSprite* searchBtn = CCSprite::createWithSpriteFrameName("GJ_searchBtn_001.png"); - CCMenuItemSpriteExtra* searchExtra = CCMenuItemSpriteExtra::create(searchBtn, NULL, this, menu_selector(CreatorLayer::onSearch)); - creatorMenu->addChild(searchExtra); - searchExtra->setPosition(m_backgroundSprite->getPosition() + CCPoint(110.0f, -55.0f)); - - return true; + creatorMenu->addChild(createExtra); + createExtra->setPosition(CCPoint(-xPadding + xOffset, yPadding + yOffset)); + + CCSprite* savedBtn = CCSprite::createWithSpriteFrameName("GJ_savedBtn_001.png"); + CCMenuItemSpriteExtra* savedExtra = CCMenuItemSpriteExtra::create(savedBtn, NULL, this, menu_selector(CreatorLayer::onBack)); + creatorMenu->addChild(savedExtra); + savedExtra->setPosition(CCPoint(0.0f + xOffset, yPadding + yOffset)); + + CCSprite* scoreBtn = CCSprite::createWithSpriteFrameName("GJ_highscoreBtn_001.png"); + CCMenuItemSpriteExtra* scoreExtra = CCMenuItemSpriteExtra::create(scoreBtn, NULL, this, menu_selector(CreatorLayer::onLeaderboards)); + creatorMenu->addChild(scoreExtra); + scoreExtra->setPosition(CCPoint(xPadding + xOffset, yPadding + yOffset)); + + CCSprite* featuredBtn = CCSprite::createWithSpriteFrameName("GJ_featuredBtn_001.png"); + CCMenuItemSpriteExtra* featuredExtra = CCMenuItemSpriteExtra::create(featuredBtn, NULL, this, menu_selector(CreatorLayer::onFeaturedLevels)); + creatorMenu->addChild(featuredExtra); + featuredExtra->setPosition(CCPoint(-xPadding + xOffset, -yPadding + yOffset)); + + CCSprite* mapPacksBtn = CCSprite::createWithSpriteFrameName("GJ_mapPacksBtn_001.png"); + CCMenuItemSpriteExtra* mapPacksExtra = CCMenuItemSpriteExtra::create(mapPacksBtn, NULL, this, menu_selector(CreatorLayer::onBack)); + creatorMenu->addChild(mapPacksExtra); + mapPacksExtra->setPosition(CCPoint(0.0f + xOffset, -yPadding + yOffset)); + + CCSprite* searchBtn = CCSprite::createWithSpriteFrameName("GJ_searchBtn_001.png"); + CCMenuItemSpriteExtra* searchExtra = CCMenuItemSpriteExtra::create(searchBtn, NULL, this, menu_selector(CreatorLayer::onSearch)); + creatorMenu->addChild(searchExtra); + searchExtra->setPosition(CCPoint(xPadding + xOffset, -yPadding + yOffset)); + + return true; } \ No newline at end of file diff --git a/Classes/FLAlertLayer.cpp b/Classes/FLAlertLayer.cpp index 18afbeb..3c54f0d 100644 --- a/Classes/FLAlertLayer.cpp +++ b/Classes/FLAlertLayer.cpp @@ -1,34 +1,222 @@ +// decompiled by ItzZyann +// from GD 1.71 binary + #include "FLAlertLayer.h" #include "TextArea.h" +#include "ButtonSprite.h" #include "RT_COCOS/CCMenuItemSpriteExtra.h" -#include "cocos-ext.h" + USING_NS_CC; -FLAlertLayer* FLAlertLayer::create(FLAlertLayerProtocol* protocol, char const* title, char const* caption, char const* button1, char const* button2, float width) -{ +void FLAlertLayerProtocol::FLAlert_Clicked(FLAlertLayer* layer, bool button2Clicked) { } + +FLAlertLayer::FLAlertLayer() { + CCLayerColor::create(); + m_buttonMenu = nullptr; + m_controlTouchID = -1; + m_zOrderPriority = 0; + m_pParent = nullptr; + m_targetScene = nullptr; + m_reverseKeyBack = false; + m_internalLayer = nullptr; + m_touchTarget = nullptr; + m_menuTouchActive = false; +} + +FLAlertLayer::~FLAlertLayer() { } + +FLAlertLayer* FLAlertLayer::create(FLAlertLayerProtocol* protocol, char const* title, char const* caption, char const* button1, char const* button2) { + return FLAlertLayer::create(protocol, title, caption, button1, button2, 250.0f); +} + +FLAlertLayer* FLAlertLayer::create(FLAlertLayerProtocol* protocol, char const* title, char const* caption, char const* button1, char const* button2, float width) { FLAlertLayer* pRet = new FLAlertLayer(); - if (pRet && pRet->init(protocol, title, caption, button1, button2, width)) - { + if (pRet && pRet->init(protocol, title, caption, button1, button2, width)) { pRet->autorelease(); return pRet; } - else - { - delete pRet; - pRet = NULL; - return NULL; - } + CC_SAFE_DELETE(pRet); + return nullptr; } bool FLAlertLayer::init(FLAlertLayerProtocol* protocol, char const* title, char const* caption, char const* button1, char const* button2, float width) { - if (!CCLayerColor::initWithColor(ccc4(0, 0, 0, 150))) + if (!CCLayerColor::initWithColor(ccc4(0, 0, 0, 150))) { return false; + } + + this->setTouchEnabled(true); + this->setKeypadEnabled(true); + + m_pParent = protocol; + m_reverseKeyBack = false; + + CCSize winSize = CCDirector::sharedDirector()->getWinSize(); + + m_internalLayer = CCLayer::create(); + this->addChild(m_internalLayer); + + TextArea* textArea = TextArea::create(caption, width - 60.0f, 0, ccp(0.5f, 0.5f), "chatFont.fnt"); + m_internalLayer->addChild(textArea, 3); + + float calculatedHeight = textArea->getContentSize().height + 100.0f; + if (calculatedHeight <= 140.0f) { + calculatedHeight = 140.0f; + } + + CCLayerColor* dummyContentBg = CCLayerColor::create(ccc4(0, 0, 0, 255), width, calculatedHeight); + dummyContentBg->setPosition(ccp((winSize.width - width) * 0.5f, (winSize.height - calculatedHeight) * 0.5f)); + dummyContentBg->setVisible(false); + cocos2d::extension::CCScale9Sprite* bgSprite = cocos2d::extension::CCScale9Sprite::create("square01_001.png", CCRect(0, 0, 94, 94)); + bgSprite->setContentSize(CCSize(width, calculatedHeight)); + m_internalLayer->addChild(bgSprite, 1); + bgSprite->setPosition(ccp(winSize.width * 0.5f, winSize.height * 0.5f)); + + CCLabelBMFont* titleLabel = CCLabelBMFont::create(title, "goldFont.fnt"); + titleLabel->setAnchorPoint(ccp(0.5f, 1.0f)); + titleLabel->setPosition(ccp(winSize.width * 0.5f, (calculatedHeight + dummyContentBg->getPositionY()) - 20.0f)); + m_internalLayer->addChild(titleLabel, 3); + titleLabel->setScale(1.0f); + + textArea->setAnchorPoint(ccp(0.5f, 0.5f)); + textArea->setPosition(ccp(winSize.width * 0.5f, dummyContentBg->getPositionY() + (calculatedHeight * 0.5f) + 10.0f)); + + m_buttonMenu = CCMenu::create(); + m_internalLayer->addChild(m_buttonMenu, 2); + + ButtonSprite* btnSprite1 = ButtonSprite::create(button1, 0, 1.0f, 0.0f, false); + CCMenuItemSpriteExtra* menuItem1 = CCMenuItemSpriteExtra::create(btnSprite1, nullptr, this, menu_selector(FLAlertLayer::onBtn1)); + float cumulativeMenuWidth = menuItem1->getContentSize().width; + m_buttonMenu->addChild(menuItem1); + + if (button2) { + ButtonSprite* btnSprite2 = ButtonSprite::create(button2, 0, 1.0f, 0.0f, false); + CCMenuItemSpriteExtra* menuItem2 = CCMenuItemSpriteExtra::create(btnSprite2, nullptr, this, menu_selector(FLAlertLayer::onBtn2)); + cumulativeMenuWidth += menuItem2->getContentSize().width; + m_buttonMenu->addChild(menuItem2); + } + + if (m_buttonMenu->getChildren() && m_buttonMenu->getChildren()->count() > 1) { + float padding = (width - cumulativeMenuWidth) * 0.5f; + if (padding >= 15.0f) { + padding = 15.0f; + } + m_buttonMenu->alignItemsHorizontallyWithPadding(padding); + } + + m_buttonMenu->setPosition(ccp(winSize.width * 0.5f, dummyContentBg->getPositionY() + 30.0f)); + + m_controlTouchID = -1; return true; } -void FLAlertLayer::show() -{ - // top ten ways to avoid decompiling a whole function: +void FLAlertLayer::show() { + GLubyte originalOpacity = this->getOpacity(); + m_internalLayer->setScale(0.5f); + + CCEaseElasticOut* bounceOpenAction = CCEaseElasticOut::create(CCScaleTo::create(0.5f, 1.0f), 0.6f); + m_internalLayer->runAction(bounceOpenAction); + + CCNode* renderingContext = m_targetScene; + if (!renderingContext) { + renderingContext = CCDirector::sharedDirector()->getRunningScene(); + } + if (m_zOrderPriority == 0) { + m_zOrderPriority = 105; + } + + renderingContext->addChild(this, m_zOrderPriority); this->setVisible(true); + + CCFadeTo* fadeInBg = CCFadeTo::create(0.14f, originalOpacity); + this->runAction(fadeInBg); + + this->setTouchEnabled(true); +} + +void FLAlertLayer::onBtn1(CCObject* sender) { + this->setTouchEnabled(false); + if (m_pParent) { + m_pParent->FLAlert_Clicked(this, false); + } + this->removeFromParentAndCleanup(true); +} + +void FLAlertLayer::onBtn2(CCObject* sender) { + this->setTouchEnabled(false); + if (m_pParent) { + m_pParent->FLAlert_Clicked(this, true); + } + this->removeFromParentAndCleanup(true); +} + +void FLAlertLayer::keyBackClicked() { + if (m_reverseKeyBack) { + this->onBtn2(nullptr); + } + else { + this->onBtn1(nullptr); + } +} + +void FLAlertLayer::registerWithTouchDispatcher() { + CCTouchDispatcher* dispatcher = CCDirector::sharedDirector()->getTouchDispatcher(); + dispatcher->addTargetedDelegate(this, -500, true); +} + +bool FLAlertLayer::ccTouchBegan(CCTouch* touch, CCEvent* event) { + if (m_buttonMenu && m_buttonMenu->isVisible() && m_buttonMenu->ccTouchBegan(touch, event)) { + m_menuTouchActive = true; + return true; + } + m_menuTouchActive = false; + + if (m_controlTouchID == -1) { + if (m_touchTarget) { + if (static_cast(m_touchTarget)->ccTouchBegan(touch, event)) { + m_controlTouchID = touch->getID(); + } + } + } + + return true; +} + +void FLAlertLayer::ccTouchMoved(CCTouch* touch, CCEvent* event) { + if (m_menuTouchActive && m_buttonMenu) { + m_buttonMenu->ccTouchMoved(touch, event); + } + + if (m_controlTouchID == touch->getID()) { + if (m_touchTarget) { + static_cast(m_touchTarget)->ccTouchMoved(touch, event); + } + } +} + +void FLAlertLayer::ccTouchCancelled(CCTouch* touch, CCEvent* event) { + if (m_menuTouchActive && m_buttonMenu) { + m_buttonMenu->ccTouchCancelled(touch, event); + m_menuTouchActive = false; + } + + if (m_controlTouchID == touch->getID()) { + if (m_touchTarget) { + static_cast(m_touchTarget)->ccTouchCancelled(touch, event); + } + } +} + +void FLAlertLayer::ccTouchEnded(CCTouch* touch, CCEvent* event) { + if (m_menuTouchActive && m_buttonMenu) { + m_buttonMenu->ccTouchEnded(touch, event); + m_menuTouchActive = false; + } + + if (m_controlTouchID == touch->getID()) { + if (m_touchTarget) { + static_cast(m_touchTarget)->ccTouchEnded(touch, event); + } + m_controlTouchID = -1; + } } \ No newline at end of file diff --git a/Classes/FLAlertLayer.h b/Classes/FLAlertLayer.h index b04d924..28b1982 100644 --- a/Classes/FLAlertLayer.h +++ b/Classes/FLAlertLayer.h @@ -1,37 +1,52 @@ +// decompiled by ItzZyann +// from GD 1.71 binary + #ifndef _FL_ALERT_LAYER_H_ #define _FL_ALERT_LAYER_H_ #include "cocos2d.h" -#include +#include "cocos-ext.h" -class FLAlertLayerProtocol; +class FLAlertLayer; + +class FLAlertLayerProtocol { +public: + virtual void FLAlert_Clicked(FLAlertLayer* layer, bool button2Clicked); +}; class FLAlertLayer : public cocos2d::CCLayerColor { public: - // FLAlertLayer(); - - static FLAlertLayer* create(FLAlertLayerProtocol* protocol, char const* title, char const* caption, char const* button1, char const* button2, float height); - - bool init(FLAlertLayerProtocol* protocol, char const* title, char const* caption, char const* button1, char const* button2, float height); - - virtual void show(); - // virtual bool ccTouchBegan(cocos2d::CCTouch * touch, cocos2d::CCEvent *event); - // virtual void ccTouchMoved(cocos2d::CCTouch *touch,cocos2d::CCEvent *event); - // virtual void ccTouchEnded(cocos2d::CCTouch *touch,cocos2d::CCEvent *event); - void incrementForcePrio(); - - CC_SYNTHESIZE(FLAlertLayerProtocol*, m_pParent, PParent); // 0x194 - CC_SYNTHESIZE(cocos2d::CCNode*, m_targetScene, TargetScene); // 0x198 - CC_SYNTHESIZE(bool, m_reverseKeyBack, ReverseKeyBack); // 0x19c - CC_SYNTHESIZE_READONLY(cocos2d::CCLayer*, m_internalLayer, InternalLayer); // 0x1a0 + FLAlertLayer(); + virtual ~FLAlertLayer(); + + static FLAlertLayer* create(FLAlertLayerProtocol* protocol, char const* title, char const* caption, char const* button1, char const* button2); + static FLAlertLayer* create(FLAlertLayerProtocol* protocol, char const* title, char const* caption, char const* button1, char const* button2, float width); + + bool init(FLAlertLayerProtocol* protocol, char const* title, char const* caption, char const* button1, char const* button2, float width); + + virtual void show(); + virtual bool ccTouchBegan(cocos2d::CCTouch* touch, cocos2d::CCEvent* event); + virtual void ccTouchMoved(cocos2d::CCTouch* touch, cocos2d::CCEvent* event); + virtual void ccTouchEnded(cocos2d::CCTouch* touch, cocos2d::CCEvent* event); + virtual void ccTouchCancelled(cocos2d::CCTouch* touch, cocos2d::CCEvent* event); + + virtual void registerWithTouchDispatcher(); + virtual void keyBackClicked(); + + void onBtn1(cocos2d::CCObject* sender); + void onBtn2(cocos2d::CCObject* sender); + + CC_SYNTHESIZE(FLAlertLayerProtocol*, m_pParent, PParent); + CC_SYNTHESIZE(cocos2d::CCNode*, m_targetScene, TargetScene); + CC_SYNTHESIZE(bool, m_reverseKeyBack, ReverseKeyBack); + CC_SYNTHESIZE_READONLY(cocos2d::CCLayer*, m_internalLayer, InternalLayer); protected: - cocos2d::CCMenu* m_buttonMenu; - int m_ZOrder; - cocos2d::CCLayer* m_mainLayer; // m_internalLayer - int m_scrollAction; - bool m_containsBorder; - bool m_noAction; + cocos2d::CCMenu* m_buttonMenu; + int m_controlTouchID; + int m_zOrderPriority; + cocos2d::CCObject* m_touchTarget; + bool m_menuTouchActive; }; #endif \ No newline at end of file diff --git a/Classes/GJDropDownLayer.cpp b/Classes/GJDropDownLayer.cpp index f6596a8..72e95b2 100644 --- a/Classes/GJDropDownLayer.cpp +++ b/Classes/GJDropDownLayer.cpp @@ -1,119 +1,133 @@ -// Decompiled by WylieMaster: https://github.com/Wyliemaster/GD-Decompiled/blob/main/GD/code/src/GJDropDownLayer.cpp #include "GJDropDownLayer.h" #include "RT_COCOS/CCMenuItemSpriteExtra.h" + USING_NS_CC; + GJDropDownLayer::GJDropDownLayer() { - this->m_endPosition = ccp(0, 0); - this->m_startPosition = ccp(0, 0); - this->m_buttonMenu = NULL; - this->m_listLayer = NULL; - this->m_internalLayer = NULL; - this->m_hidden = false; - this->m_delegate = NULL; + this->m_endPosition = ccp(0, 0); + this->m_startPosition = ccp(0, 0); + this->m_buttonMenu = NULL; + this->m_listLayer = NULL; + this->m_internalLayer = NULL; + this->m_hidden = false; + this->m_delegate = NULL; } GJDropDownLayer::~GJDropDownLayer() { - // CCDirector::sharedDirector()->getTouchDispatcher()->decrementForcePrio(2); + CCDirector::sharedDirector()->getTouchDispatcher()->setForcePrio(false); } void GJDropDownLayer::disableUI() { - this->m_buttonMenu->setTouchEnabled(false); + this->m_buttonMenu->setTouchEnabled(false); } void GJDropDownLayer::enableUI() { - this->m_buttonMenu->setTouchEnabled(true); + this->m_buttonMenu->setTouchEnabled(true); } void GJDropDownLayer::draw() { - if (this->getOpacity()) - CCLayerColor::draw(); + if (this->getOpacity()) + CCLayerColor::draw(); } void GJDropDownLayer::enterLayer() { - this->enableUI(); - this->showLayer(false); + this->enableUI(); + this->showLayer(false); } void GJDropDownLayer::exitLayer(CCObject* sender) { - this->setKeypadEnabled(false); - + this->setKeypadEnabled(false); + CCDirector* director = CCDirector::sharedDirector(); - director->getTouchDispatcher()->setForcePrio(false); - - this->disableUI(); - this->hideLayer(false); + director->getTouchDispatcher()->setForcePrio(false); + + if (this->m_delegate) { + this->m_delegate->dropDownLayerWillClose(this); + } + + this->disableUI(); + this->hideLayer(false); } -void GJDropDownLayer::hideLayer(bool instantHide) { - this->m_internalLayer->stopAllActions(); - - if (instantHide) { +void GJDropDownLayer::hideLayer(bool instantHide) { + this->m_internalLayer->stopAllActions(); + + if (instantHide) { m_internalLayer->setPosition(m_startPosition); - this->setOpacity(0); - this->layerHidden(); - } - else { - CCEaseInOut* action = CCEaseInOut::create(CCMoveTo::create(0.5, this->m_startPosition), 2.0f); + this->setOpacity(0); + this->layerHidden(); + } + else { + CCEaseInOut* action = CCEaseInOut::create(CCMoveTo::create(0.5, this->m_startPosition), 2.0f); CCCallFunc* callback = CCCallFunc::create(this, callfunc_selector(GJDropDownLayer::layerHidden)); m_internalLayer->runAction(CCSequence::create(action, callback, NULL)); - this->runAction(CCFadeTo::create(0.5, 0)); - } + this->runAction(CCFadeTo::create(0.5, 0)); + } } void GJDropDownLayer::registerWithTouchDispatcher() { - CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this, -500, true); + // Layer priority is -500 + CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this, -500, true); } void GJDropDownLayer::keyBackClicked() { - this->exitLayer(NULL); + this->exitLayer(NULL); } void GJDropDownLayer::layerHidden() { - this->setVisible(false); - if (this->m_hidden) - this->removeFromParentAndCleanup(true); + this->setVisible(false); + + if (this->m_removeOnExit) { + this->removeFromParentAndCleanup(true); + } } void GJDropDownLayer::layerVisible() { - this->setVisible(true); + this->setVisible(true); } void GJDropDownLayer::showLayer(bool instantShow) { - m_internalLayer->stopAllActions(); - this->layerVisible(); - - if (instantShow) { - this->m_internalLayer->setPosition(this->m_endPosition); - this->setOpacity(125); - this->enterAnimFinished(); + m_internalLayer->stopAllActions(); + this->layerVisible(); + + if (instantShow) { + this->m_internalLayer->setPosition(this->m_endPosition); + this->setOpacity(125); + this->enterAnimFinished(); return; } - - CCEaseInOut* action = CCEaseInOut::create(CCMoveTo::create(0.5, this->m_endPosition), 2.0f); + + CCEaseInOut* action = CCEaseInOut::create(CCMoveTo::create(0.5, this->m_endPosition), 2.0f); CCCallFunc* callback = CCCallFunc::create(this, callfunc_selector(GJDropDownLayer::enterAnimFinished)); - m_internalLayer->runAction(CCSequence::create(action, callback, nullptr)); - this->setOpacity(0); - this->runAction(CCFadeTo::create(0.5, 125)); + m_internalLayer->runAction(CCSequence::create(action, callback, nullptr)); + this->setOpacity(0); + this->runAction(CCFadeTo::create(0.5, 125)); +} + +bool GJDropDownLayer::ccTouchBegan(CCTouch* pTouch, CCEvent* pEvent) { + // Always return true to swallow background clicks on underlying screens. + // The menu buttons will bypass this safely now because their priority is higher. + return true; } GJDropDownLayer* GJDropDownLayer::create(const char* title, float height) { - GJDropDownLayer* pRet = new GJDropDownLayer(); - - if (pRet && pRet->init(title, height)) { - pRet->autorelease(); - return pRet; - } - - CC_SAFE_DELETE(pRet); - return NULL; + GJDropDownLayer* pRet = new GJDropDownLayer(); + + if (pRet && pRet->init(title, height)) { + pRet->autorelease(); + return pRet; + } + + CC_SAFE_DELETE(pRet); + return NULL; } GJDropDownLayer* GJDropDownLayer::create(const char* title) { - return GJDropDownLayer::create(title, 220); + return GJDropDownLayer::create(title, 220); } bool GJDropDownLayer::init(const char* title) { - return this->init(title, 220); + return this->init(title, 220); } bool GJDropDownLayer::init(const char* title, float height) { @@ -121,64 +135,61 @@ bool GJDropDownLayer::init(const char* title, float height) { CCTouchDispatcher* touchDisp = pDirector->getTouchDispatcher(); touchDisp->setForcePrio(true); - touchDisp->setTargetPrio(-504); // i really dont know if this number is right lol + touchDisp->setTargetPrio(-504); if (!this->initWithColor(ccc4(0, 0, 0, 125))) - return false; - - this->setTouchEnabled(true); - this->setKeypadEnabled(true); - // don't need this yet: this->setKeyboardEnabled(true); - + return false; + + this->setTouchEnabled(true); + this->setKeypadEnabled(true); + CCSize winSize = pDirector->getWinSize(); - - this->m_internalLayer = CCLayer::create(); - this->addChild(this->m_internalLayer); - - this->m_endPosition = ccp(0, 0); - this->m_startPosition = ccp(0, winSize.height); - - m_internalLayer->setPosition(this->m_startPosition); - ccColor4B listColor = { 0, 0, 0, 180 }; - this->m_listLayer = GJListLayer::create(NULL, title, listColor, 356.0, height); // it shows -76 in decomp but 0xB4 in asm so i guess its 0xB4 :P - m_internalLayer->addChild(this->m_listLayer); - - this->m_listLayer->setPosition(CCPoint((winSize.width - 356.0f) * 0.5f, (((winSize.height - height) * 0.5f) - 10.0f) + 5.0f)); + + this->m_internalLayer = CCLayer::create(); + this->addChild(this->m_internalLayer); + + this->m_endPosition = ccp(0, 0); + this->m_startPosition = ccp(0, winSize.height); + + m_internalLayer->setPosition(this->m_startPosition); + ccColor4B listColor = { 0, 0, 0, 180 }; + this->m_listLayer = GJListLayer::create(NULL, title, listColor, 356.0, height); + m_internalLayer->addChild(this->m_listLayer); + + this->m_listLayer->setPosition(CCPoint((winSize.width - 356.0f) * 0.5f, (((winSize.height - height) * 0.5f) - 10.0f) + 5.0f)); float height2 = height + m_listLayer->getPosition().y + 12.0; - CCSprite* backBtnSprite = CCSprite::createWithSpriteFrameName("GJ_arrow_03_001.png"); - CCMenuItemSpriteExtra* backBtn = CCMenuItemSpriteExtra::create(backBtnSprite, NULL, this, menu_selector(GJDropDownLayer::exitLayer)); - backBtn->setSizeMult(1.6f); - - this->m_buttonMenu = CCMenu::create(backBtn, NULL); - this->m_buttonMenu->setPosition(CCPoint((winSize.width * 0.5f) + 178.0f, (winSize.height * 0.5f) - (height * 0.5f))); - + CCSprite* backBtnSprite = CCSprite::createWithSpriteFrameName("GJ_arrow_03_001.png"); + CCMenuItemSpriteExtra* backBtn = CCMenuItemSpriteExtra::create(backBtnSprite, NULL, this, menu_selector(GJDropDownLayer::exitLayer)); + backBtn->setSizeMult(1.6f); + + this->m_buttonMenu = CCMenu::create(backBtn, NULL); this->m_buttonMenu->setPosition(CCPoint(pDirector->getScreenLeft() + 24, pDirector->getScreenTop() - 23)); - - m_internalLayer->addChild(m_buttonMenu, 10); - - CCSprite* chain1 = CCSprite::createWithSpriteFrameName("chain_01_001.png"); - this->m_internalLayer->addChild(chain1, -1); - chain1->setAnchorPoint(CCPoint(0.5, 0.0)); + + // FIX: Explicitly set CCMenu priority higher (-501) than the layer (-500) + this->m_buttonMenu->setTouchPriority(-501); + + m_internalLayer->addChild(m_buttonMenu, 10); + + CCSprite* chain1 = CCSprite::createWithSpriteFrameName("chain_01_001.png"); + this->m_internalLayer->addChild(chain1, -1); + chain1->setAnchorPoint(CCPoint(0.5, 0.0)); chain1->setPosition(CCPoint((winSize.width * 0.5f) - 156.0f, height2)); - chain1->setTag(0); - - CCSprite* chain2 = CCSprite::createWithSpriteFrameName("chain_01_001.png"); - this->m_internalLayer->addChild(chain2, -1); - chain2->setAnchorPoint(CCPoint(0.5, 0.0)); + chain1->setTag(0); + + CCSprite* chain2 = CCSprite::createWithSpriteFrameName("chain_01_001.png"); + this->m_internalLayer->addChild(chain2, -1); + chain2->setAnchorPoint(CCPoint(0.5, 0.0)); chain2->setPosition(CCPoint((winSize.width * 0.5f) + 156.0f, height2)); - chain2->setTag(1); - + chain2->setTag(1); + m_removeOnExit = false; - this->hideLayer(true); + this->hideLayer(true); m_removeOnExit = true; - - this->customSetup(); - - return true; + + this->customSetup(); + + return true; } -void GJDropDownLayerDelegate::dropDownLayerWillClose(GJDropDownLayer *p0) -{ - -} \ No newline at end of file +void GJDropDownLayerDelegate::dropDownLayerWillClose(GJDropDownLayer *p0) { } \ No newline at end of file diff --git a/Classes/GJDropDownLayer.h b/Classes/GJDropDownLayer.h index 4773a2f..3e846a8 100644 --- a/Classes/GJDropDownLayer.h +++ b/Classes/GJDropDownLayer.h @@ -1,7 +1,9 @@ #ifndef _GJ_DROP_DOWN_LAYER_ #define _GJ_DROP_DOWN_LAYER_ + #include "cocos2d.h" #include "GJListLayer.h" + using cocos2d::SEL_CallFunc; using cocos2d::SEL_MenuHandler; @@ -9,49 +11,45 @@ class GJDropDownLayerDelegate; class GJDropDownLayer : public cocos2d::CCLayerColor { public: - GJDropDownLayer(); - ~GJDropDownLayer(); - - bool init(const char* title, float height); - bool init(const char* title); - void draw(); - virtual void customSetup() {} - virtual void enterLayer(); - virtual void exitLayer(cocos2d::CCObject* sender); - virtual void showLayer(bool instantShow); - virtual void hideLayer(bool instantHide); - virtual void layerVisible(); - virtual void layerHidden(); - virtual void enterAnimFinished() {} - virtual void disableUI(); - virtual void enableUI(); - void keyBackClicked(); - void registerWithTouchDispatcher(); - GJDropDownLayer* create(const char* title, float height); - GJDropDownLayer* create(const char* title); - - bool ccTouchBegan() { return true; } - // void ccTouchCancelled() {} - // void ccTouchEnded() {} - // void ccTouchMoved() {} - - // these are from geode =) - cocos2d::CCPoint m_endPosition; - cocos2d::CCPoint m_startPosition; - cocos2d::CCMenu* m_buttonMenu; // 0x198 - GJListLayer* m_listLayer; // 0x19c - - CC_SYNTHESIZE_READONLY(cocos2d::CCLayer*, m_internalLayer, InternalLayer); // 0x1a0 - CC_SYNTHESIZE(bool, m_removeOnExit, RemoveOnExit); // 0x1a4 - - bool m_hidden; - GJDropDownLayerDelegate* m_delegate; + GJDropDownLayer(); + ~GJDropDownLayer(); + + bool init(const char* title, float height); + bool init(const char* title); + void draw(); + virtual void customSetup() {} + virtual void enterLayer(); + virtual void exitLayer(cocos2d::CCObject* sender); + virtual void showLayer(bool instantShow); + virtual void hideLayer(bool instantHide); + virtual void layerVisible(); + virtual void layerHidden(); + virtual void enterAnimFinished() {} + virtual void disableUI(); + virtual void enableUI(); + void keyBackClicked(); + void registerWithTouchDispatcher(); + static GJDropDownLayer* create(const char* title, float height); + static GJDropDownLayer* create(const char* title); + + virtual bool ccTouchBegan(cocos2d::CCTouch* pTouch, cocos2d::CCEvent* pEvent); + + cocos2d::CCPoint m_endPosition; + cocos2d::CCPoint m_startPosition; + cocos2d::CCMenu* m_buttonMenu; + GJListLayer* m_listLayer; + + CC_SYNTHESIZE_READONLY(cocos2d::CCLayer*, m_internalLayer, InternalLayer); + CC_SYNTHESIZE(bool, m_removeOnExit, RemoveOnExit); + + bool m_hidden; + GJDropDownLayerDelegate* m_delegate; }; class GJDropDownLayerDelegate { public: - virtual void dropDownLayerWillClose(GJDropDownLayer* p0); + virtual void dropDownLayerWillClose(GJDropDownLayer* p0); }; #endif \ No newline at end of file diff --git a/Classes/GJGarageLayer.cpp b/Classes/GJGarageLayer.cpp index dc268f6..459c448 100644 --- a/Classes/GJGarageLayer.cpp +++ b/Classes/GJGarageLayer.cpp @@ -128,7 +128,7 @@ void GJGarageLayer::setupIconSelect() CCSprite* unlockTxt = CCSprite::createWithSpriteFrameName("GJ_unlockTxt_001.png"); this->addChild(unlockTxt); unlockTxt->setAnchorPoint(ccp(0.5, 0.5)); - unlockTxt->setPosition(base->getPosition() + ccp(120, (winSize.height * 0.5) + 12)); + unlockTxt->setPosition(base->getPosition() + ccp(120, (winSize.height * 0.5) - 100)); CCMenu* buttonMenu = CCMenu::create(); this->addChild(buttonMenu, 100); @@ -169,7 +169,7 @@ void GJGarageLayer::setupIconSelect() unk_0x144->setTag(99); buttonMenu->alignItemsHorizontallyWithPadding(0.0f); - buttonMenu->setPosition(base->getPosition() + ccp(-125, (winSize.height * 0.5) + 18)); + buttonMenu->setPosition(base->getPosition() + ccp(-125, (winSize.height * 0.5) - 92)); unk_0x130 = CCArray::create(); unk_0x130->retain(); diff --git a/Classes/GJGroundLayer.cpp b/Classes/GJGroundLayer.cpp index 445ee1e..a8cbde0 100644 --- a/Classes/GJGroundLayer.cpp +++ b/Classes/GJGroundLayer.cpp @@ -120,4 +120,31 @@ void GJGroundLayer::deactivateGround() ((CCNode*)children->objectAtIndex(i))->stopActionByTag(999); } m_isActive = false; +} + +// GJFlyGroundLayer +GJFlyGroundLayer* GJFlyGroundLayer::create() +{ + GJFlyGroundLayer *pRet = new GJFlyGroundLayer(); + if (pRet && pRet->init()) + { + pRet->autorelease(); + return pRet; + } + else + { + delete pRet; + pRet = NULL; + return NULL; + } +} + + +bool GJFlyGroundLayer::init() +{ + if (!CCLayer::init()) + return false; + + // unk_0x118 = 0; + return true; } \ No newline at end of file diff --git a/Classes/GJGroundLayer.h b/Classes/GJGroundLayer.h index b82d014..a96840f 100644 --- a/Classes/GJGroundLayer.h +++ b/Classes/GJGroundLayer.h @@ -25,6 +25,7 @@ class GJGroundLayer : public cocos2d::CCLayer { }; class GJFlyGroundLayer : public GJGroundLayer { +public: static GJFlyGroundLayer* create(); bool init(); }; diff --git a/Classes/GameObject.cpp b/Classes/GameObject.cpp index 552a435..97fde82 100644 --- a/Classes/GameObject.cpp +++ b/Classes/GameObject.cpp @@ -1,550 +1,284 @@ #include "GameObject.h" #include "ObjectToolbox.h" #include "GameManager.h" -USING_NS_CC; -// hi antimatter some of your code was kind of broken so i fixed it up +USING_NS_CC; GameObject::GameObject() { - this->unk_0x1b8 = 0; - this->unk_0x1bc = 0; - this->unk_0x1c0 = false; - // *(_DWORD *)this = &off_486138; - this->m_glowSprite = nullptr; - // *((_DWORD *)this + 0x3A) = &off_486538; - // *((_DWORD *)this + 0x3E) = &off_486578; - this->unk_0x1c8 = false; - this->unk_0x1c9 = false; - this->m_myAction = nullptr; - this->unk_0x1d0 = false; - this->m_poweredOn = false; - this->unk_0x1d4 = 0; - this->unk_0x1d8 = 0; - this->m_isActive = false; - this->m_hasGlow = false; - this->unk_0x1de = false; - this->m_particleSystem = nullptr; + this->unk_0x1b8 = 0; + this->unk_0x1bc = 0; + this->unk_0x1c0 = false; + this->m_glowSprite = nullptr; + this->unk_0x1c8 = false; + this->unk_0x1c9 = false; + this->m_myAction = nullptr; + this->unk_0x1d0 = false; + this->m_poweredOn = false; + this->unk_0x1d4 = 0.0f; + this->unk_0x1d8 = 0.0f; + this->m_isActive = false; + this->m_hasGlow = false; + this->unk_0x1de = false; + this->m_particleSystem = nullptr; this->m_particleString = ""; - this->m_particleAdded = false; - // cocos2d::CCPoint::CCPoint((GameObject *)((char *)this + 0x1EC)); - // cocos2d::CCRect::CCRect((GameObject *)((char *)this + 0x1F4)); - this->unk_0x204 = false; - // cocos2d::CCRect::CCRect((GameObject *)((char *)this + 0x208)); - this->unk_0x218 = false; + this->m_particleAdded = false; + this->unk_0x204 = false; + this->unk_0x218 = false; this->m_hasColor = false; - this->m_colorSprite = nullptr; - this->m_ignoreScreenCheck = false; - this->m_radius = 0.0f; + this->m_colorSprite = nullptr; + this->m_ignoreScreenCheck = false; + this->m_radius = 0.0f; this->m_isRotated = false; - this->m_scaleModX = 0; - this->m_scaleModY = 0; - this->m_ID = 0; - this->m_type = None; - this->m_sectionIdx = 0; - this->m_shouldSpawn = false; - this->m_touchTriggered = false; - // cocos2d::CCPoint::CCPoint((GameObject *)((char *)this + 0x244)); - this->m_blendAdditive = false; - this->m_frame = ""; - this->m_usePlayerColor = false; - this->m_usePlayerColor2 = false; - this->m_isDisabled = false; - this->m_useAudioScale = false; - this->m_isSleeping = false; - this->m_startRotation = 0; - this->m_startScaleX = 0; - this->m_startScaleY = 0; - this->m_shouldHide = false; - this->m_spawnXPos = 0; - this->m_isInvisible = false; - this->m_enterAngle = 0; - this->m_enterEffect = 0; - this->m_tintDuration = 0; - this->m_tintGround = false; - this->m_objectKey = 0; - this->m_dontTransform = false; - this->m_dontFade = false; - this->m_dontFadeTinted = false; - this->m_isTintObject = false; - this->m_hasBeenActivated = false; - this->m_stateVar = false; - this->m_objectZ = 0; - this->m_objectParent = nullptr; - this->m_customAudioScale = false; - this->m_minAudioScale = 0; - this->m_maxAudioScale = 0; - this->m_uniqueID = 0; - this->m_invisibleMode = false; - this->m_glowUseBGColor = false; - this->m_useBGColor = false; - this->m_useSpecialLight = false; - this->m_opacityMod = 0; - this->m_glowOpacityMod = 0; - this->m_dontShow = false; - this->m_editorSelected = false; - this->m_copyPlayerColor1 = false; - this->m_copyPlayerColor2 = false; - this->m_tintObjectsUseBlend = false; -} -bool GameObject::init(const char *spriteName) { - if (!CCSpritePlus::initWithSpriteFrameName(spriteName)) return false; - this->m_objectZ = 2; - this->m_opacityMod = 1.0f; - this->m_glowOpacityMod = 1.0f; - this->m_enterEffect = 0; - this->m_frame = spriteName; - this->m_shouldSpawn = false; - // this->unk_0x1d4 = 0; // this + 0x138 - // this->unk_0x1d8 = 0; // this + 0x13c - this->m_scaleModX = 1; - this->m_scaleModY = 1; - this->m_startScaleX = 1; - this->m_startScaleY = 1; - // this->m_ID = dword_4B6E6C; - this->m_startRotation = 0.0f; - this->m_tintColor = ccc3(255, 255, 255); - this->m_tintDuration = 0.5f; - this->setScaleX(1.0f); - this->setScaleY(1.0f); - this->m_isActive = false; - this->unk_0x204 = true; - this->unk_0x218 = true; - this->m_tintObjectsUseBlend = true; - return true; -} - -GameObject* GameObject::create(const char* frame) -{ - GameObject *pRet = new GameObject(); - if (pRet && pRet->init(frame)) - { - pRet->autorelease(); - return pRet; - } - - CC_SAFE_DELETE(pRet); - return NULL; + this->m_scaleModX = 1.0f; + this->m_scaleModY = 1.0f; + this->m_ID = 0; + this->m_type = 0; + this->m_sectionIdx = 0; + this->m_shouldSpawn = false; + this->m_touchTriggered = false; + this->m_startPos = cocos2d::CCPointZero; + this->m_blendAdditive = false; + this->m_frame = ""; + this->m_usePlayerColor = false; + this->m_usePlayerColor2 = false; + this->m_isDisabled = false; + this->m_useAudioScale = false; + this->m_isSleeping = false; + this->m_startRotation = 0.0f; + this->m_startScaleX = 1.0f; + this->m_startScaleY = 1.0f; + this->m_shouldHide = false; + this->m_spawnXPos = 0; + this->m_isInvisible = false; + this->m_enterAngle = 0.0f; + this->m_enterEffect = 0; + this->m_tintDuration = 0.0f; + this->m_tintGround = false; + this->m_objectKey = 0; + this->m_dontTransform = false; + this->m_dontFade = false; + this->m_dontFadeTinted = false; + this->m_isTintObject = false; + this->m_hasBeenActivated = false; + this->m_stateVar = false; + this->m_objectZ = 0; + this->m_objectParent = nullptr; + this->m_customAudioScale = false; + this->m_minAudioScale = 0.0f; + this->m_maxAudioScale = 0.0f; + this->m_uniqueID = 0; + this->m_invisibleMode = false; + this->m_glowUseBGColor = false; + this->m_useBGColor = false; + this->m_useSpecialLight = false; + this->m_opacityMod = 1.0f; + this->m_glowOpacityMod = 1.0f; + this->m_dontShow = false; + this->m_editorSelected = false; + this->m_copyPlayerColor1 = false; + this->m_copyPlayerColor2 = false; + this->m_tintObjectsUseBlend = false; } -GameObject* GameObject::objectFromString(std::string objString) -{ - CCDictionary* objDict = ObjectToolbox::stringSetupToDict(objString); - - - - char const* key = objDict->valueForKey("1")->getCString(); - int objID = atoi(key); - char const* frame = ObjectToolbox::sharedState()->keyToFrame(key); - - if (!objID) - return nullptr; - - GameObject* object; - - if (objID == 84 || objID == 36 || objID == 141) { - // object = RingObject::create(); - return nullptr; +bool GameObject::init(const char* spriteName) { + if (spriteName && strlen(spriteName) > 0) { + CCSpriteFrame* frame = CCSpriteFrameCache::sharedSpriteFrameCache()->spriteFrameByName(spriteName); + if (frame) { + if (!CCSpritePlus::initWithSpriteFrame(frame)) { + return false; + } + } + else { + if (!CCSpritePlus::initWithFile(spriteName)) { + return false; + } + } } else { - object = GameObject::create(frame); - object->setObjectKey(objID); - object->setPosition(ccp(objDict->valueForKey("2")->floatValue(), objDict->valueForKey("3")->floatValue() + 90.0f)); + if (!CCSpritePlus::init()) { + return false; + } } - object->setObjectKey(objID); + this->m_tintDuration = 0.5f; + this->setScale(1.0f); + this->m_isActive = false; + this->unk_0x1c0 = true; + this->unk_0x1c8 = true; + this->m_tintObjectsUseBlend = true; - return object; + return true; } -void GameObject::disableObject() { - this->m_type = GameObjectType::Decoration; - this->m_isDisabled = true; - this->m_particleAdded = false; - this->m_opacityMod = 0.2f; +GameObject* GameObject::create(const char* spriteName) { + GameObject* pRet = new GameObject(); + if (pRet && pRet->init(spriteName)) { + pRet->autorelease(); + return pRet; + } + CC_SAFE_DELETE(pRet); + return nullptr; } -const char* GameObject::getBallFrame(int idx) { - return cocos2d::CCString::createWithFormat("rod_ball_%02d_001.png", idx < 3 ? idx : 3)->getCString(); +void GameObject::setPosition(cocos2d::CCPoint const &position) { + CCSpritePlus::setPosition(position); } -void GameObject::triggerActivated() { - this->m_hasBeenActivated = true; +void GameObject::setFlipX(bool flipX) { + CCSpritePlus::setFlipX(flipX); } -/*void GameObject::removeGlow() { - if (!this->m_glowSprite) return; - this->m_glowSprite->release(); - this->m_glowSprite->removeMeAndCleanup(); - this->m_glowSprite = nullptr; -}*/ - -void GameObject::powerOnObject() { - this->m_stateVar = true; - if (!this->m_poweredOn) - this->m_poweredOn = true; +void GameObject::setFlipY(bool flipY) { + CCSpritePlus::setFlipY(flipY); } -void GameObject::powerOffObject() { - if (this->m_poweredOn) - this->m_poweredOn = false; + +void GameObject::triggerObject() { } void GameObject::activateObject() { - this->m_shouldHide = false; - if (this->m_isActive || this->m_isSleeping) return; - - this->m_isActive = true; - if (this->m_isInvisible) return; - - this->setVisible(true); - if (this->unk_0x1c9) - PLAY_LAYER->registerStateObject(this); - - if (!this->m_dontShow && this->m_objectParent) - this->m_objectParent->addChild(this, this->m_objectZ); - - if (this->m_hasGlow) - PLAY_LAYER->getBatchNodeAdd()->addChild(this->m_glowSprite); - - if (this->m_hasColor) { - if (PLAY_LAYER->getTintObjectsUseBlend()) { - PLAY_LAYER->getBatchNodeAdd()->addChild(this->m_glowSprite); - } else { - PLAY_LAYER->getBatchNode()->addChild(this->m_glowSprite); - } - } - // this = (GameManager *)(*(int (**)(void))(*(_DWORD *)v13 + 0xDC))(); - if (this->unk_0x1d0 && !this->getActionByTag(11) && this->m_myAction) { - this->runAction(m_myAction); - } } -/*void GameObject::addColorSprite() { - if ( - ((this->m_objectKey >= 207 && this->m_objectKey < 214) || - (this->m_objectKey >= 215 && this->m_objectKey < 220) || - (this->m_objectKey >= 247 && this->m_objectKey < 262) || - (this->m_objectKey >= 263 && this->m_objectKey <= 275)) - && this->m_hasColor - ) { - // replace _001.png with _color_001.png - std::string colorSpriteFrame = CCString::createWithFormat("%i", this->m_objectKey)->getCString(); - // this isn't how it works but it also kind of works - colorSpriteFrame.replace(0, colorSpriteFrame.find("_001.png"), "_color_001.png"); - this->m_colorSprite = cocos2d::CCSprite::createWithSpriteFrameName(colorSpriteFrame.c_str()); - this->m_colorSprite->retain(); - this->m_colorSprite->setPosition(this->getPosition()); - GameManager* gman = GameManager::sharedState(); - if (gman->getEditMode()) { - this->m_colorSprite->setOpacity(100); - } - } -}*/ +void GameObject::deactivateObject() { + if (this->m_shouldHide) { + if (this->m_isActive) { + this->m_isActive = false; -void GameObject::setFlipX(bool flipX) { - CCSpritePlus::setFlipX(flipX); - - /*if (this->m_glowSprite) { - m_glowSprite->setFlipX(flipX); - } - if (this->m_hasColor) { - m_colorSprite->setFlipX(flipX); - }*/ -} + GameManager* gm = GameManager::sharedState(); + if (this->unk_0x1c9 && gm) { + void* layer = gm->getPlayLayer(); + if (layer && reinterpret_cast(layer) != 0xCDCDCDCD) { + } + } -void GameObject::setFlipY(bool flipY) { - CCSpritePlus::setFlipY(flipY); - /*if (this->m_glowSprite) { - m_glowSprite->setFlipY(flipY); - } - if (this->m_hasColor) { - m_colorSprite->setFlipY(flipY); - }*/ + this->setVisible(false); + if (this->m_glowSprite && reinterpret_cast(this->m_glowSprite) != 0xCDCDCDCD) this->m_glowSprite->setVisible(false); + if (this->m_colorSprite && reinterpret_cast(this->m_colorSprite) != 0xCDCDCDCD) this->m_colorSprite->setVisible(false); + } + } } -/*void GameObject::setScaleX(float scaleX) { - CCSpritePlus::setScaleX(scaleX); - if (this->m_glowSprite) { - this->m_glowSprite->setScaleX(scaleX); - } - if (this->m_hasColor) { - m_colorSprite->setScaleX(scaleX); - } -} +GameObject* GameObject::objectFromString(std::string objString) { + CCDictionary* objDict = ObjectToolbox::stringSetupToDict(objString); + if (!objDict) return nullptr; -void GameObject::setScaleY(float scaleY) { - CCSpritePlus::setScaleY(scaleY); - if (this->m_glowSprite) { - this->m_glowSprite->setScaleY(scaleY); - } - if (this->m_hasColor) { - m_colorSprite->setScaleY(scaleY); - } -}*/ + if (!objDict->objectForKey("1")) return nullptr; + int objID = atoi(objDict->valueForKey("1")->getCString()); + if (!objID) return nullptr; -void GameObject::resetObject() { - this->m_hasBeenActivated = false; - this->m_isSleeping = false; - this->unk_0x1de = false; -} + const char* frame = ObjectToolbox::sharedState()->keyToFrame(objDict->valueForKey("1")->getCString()); -/*void GameObject::setGlowColor(cocos2d::ccColor3B color) { - if (this->m_glowSprite) { - this->m_glowSprite->setColor(color); - } -}*/ + float x = objDict->valueForKey("2")->floatValue(); + float y = objDict->valueForKey("3")->floatValue(); + bool flipX = objDict->objectForKey("4") ? objDict->valueForKey("4")->boolValue() : false; + bool flipY = objDict->objectForKey("5") ? objDict->valueForKey("5")->boolValue() : false; + int rotation = objDict->objectForKey("6") ? objDict->valueForKey("6")->intValue() : 0; -void GameObject::setPosition(cocos2d::CCPoint const &position) { - this->unk_0x218 = true; - CCSpritePlus::setPosition(position); - if (this->m_particleSystem) { - // this->m_particleSystem->setPosition() - } -} + // TODO: RingObject (object IDs 84, 36, 141) is not implemented yet + // (RingObject.cpp is still a stub) - route those through the normal + // GameObject path for now instead of linking to a nonexistent create(). + GameObject* object = GameObject::create(frame); + if (!object) return nullptr; -/*CCRepeatForever* GameObject::createRotateAction(float duration) { - int sign; - if (rand() / RAND_MAX < 0.5) { - sign = -1; - } else { - sign = 1; - } - return cocos2d::CCRepeatForever::create(cocos2d::CCRotateBy::create(1, duration * sign)); -} + object->setObjectKey(objID); + object->setFlipX(flipX); + object->setFlipY(flipY); + object->setRotation((float)rotation); -void GameObject::setVisible(bool visible) { - if (this->unk_0x1e8 && this->isVisible() != visible) { - if (visible) { - this->m_particleSystem = PLAY_LAYER->claimParticle(this->unk_0x1e4); - this->setPosition(this->getPosition()); - if (this->m_particleSystem) { - PLAY_LAYER->getGameLayer(); - CCPoint point = this-> + this->unk_0x1ec; - } - } else { - - } - } - cocos2d::CCSprite::setVisible(visible); -}*/ - -void GameObject::updateState() -{ - if (!m_stateVar) { - this->powerOffObject(); - } -} + // y + 90.0f matches the save-string convention used elsewhere in this + // codebase (see getSaveString subtracting 90.0f) - the editor origin + // is offset from the in-game origin by the ground height. + CCPoint startPos = ccp(x, y + 90.0f); + object->m_startPos = startPos; + object->setPosition(startPos); -void GameObject::customSetup() -{ - GameManager* pGameManager = GameManager::sharedState(); - - switch (m_objectKey) { - case 5: - case 73: - case 74: - // ok skip some of this - case 246: - m_type = GameObjectType::Decoration; - m_objectZ = -2; - default: - if (m_frame.find("edit_e", 0)) { - m_type = GameObjectType::None; - break; - } - m_type = GameObjectType::Decoration; - m_shouldSpawn = true; - // field_0x1c8 = 1; - m_isInvisible = true; - // field468_0x1d4 = 30.0f; - // field469_0x1d = 60.0f - break; - case 8: - case 39: break; // temp - case 9: - case 61: - case 135: - case 243: - case 244: - this->m_type = Hazard; - this->m_scaleModY = 0.4f; - this->m_scaleModX = 0.3f; - if (m_objectKey == 9) { - CCSpriteFrameCache* frameCache = CCSpriteFrameCache::sharedSpriteFrameCache(); - int randNum = roundf(rand() % 2); - char const* frameFile = CCString::createWithFormat("pit_%02d_001.png", randNum + 1)->getCString(); - this->setDisplayFrame(frameCache->spriteFrameByName(frameFile)); - } - /*else if (iVar11 == 0x87) { - lrand48(); - roundf(__x_00); - iVar11 = (int)extraout_r0_04 + 1; - if (iVar11 == DAT_004be004) { - iVar11 = (int)extraout_r0_04 + 2; - } - if (4 < iVar11) { - iVar11 = 1; - } - pcVar14 = *(code **)(*(int *)this + 0x224); - pCVar4 = (CCSpriteFrameCache *)cocos2d::CCSpriteFrameCache::sharedSpriteFrameCache(); - pCVar5 = (CCString *)cocos2d::CCString::createWithFormat("pit_b_%02d_001.png", iVar11); - pcVar6 = (char *)cocos2d::CCString::getCString(pCVar5); - uVar7 = cocos2d::CCSpriteFrameCache::spriteFrameByName(pCVar4, pcVar6); - (*pcVar14)(this, uVar7); - DAT_004be004 = iVar11; - }*/ - break; - case 35: - this->m_type = YellowPad; - this->m_scaleModX = 1.0; - this->m_scaleModY = 1.0; - // skip some - case 103: break; // temp - // skip some - case 140: - this->m_type = GravityPad; - // skip some - case 177: - case 178: - case 179: - case 216: - case 217: - case 218: - this->m_type = GameObjectType::Hazard; - this->m_scaleModX = 0.2f; - this->m_scaleModY = 0.4f; - /*if (iVar11 - 0xb1U < 3) - this->field_0x2a9 = 1;*/ - break; - // more left - case 13: - this->m_type = GameObjectType::ShipPortal; - this->m_objectZ = 10; - if (pGameManager->getEditMode()) break; - this->createAndAddParticle(m_type, "portalEffect04.plist", 3, tCCPositionType::kCCPositionTypeGrouped); - break; - // skipping - case 211: - m_type = GameObjectType::Decoration; - m_objectZ = -2; - m_dontFadeTinted = true; - m_dontFade = true; - m_dontShow = true; - break; - - case 247: - case 248: - case 249: - case 250: - case 252: - case 253: - case 254: - case 255: - case 256: - case 257: - case 258: - case 260: - case 261: - case 263: - case 264: - case 265: - case 267: - case 268: - case 269: - case 270: - case 271: - case 272: - case 274: - case 275: - m_type = None; - unk_0x1d4 = 30.0f; - unk_0x1d8 = 30.0f; - break; - case 273: - m_type = GameObjectType::Decoration; - m_dontShow = true; - m_objectZ = -2; - } + object->customSetup(); + object->calculateSpawnXPos(); - //if (m_type - 7 < 2) - // m_isDisabled = true; + return object; +} - // if (((uVar13 < 0xf) && ((1 << (uVar13 & 0xff) & 0x7002U) != 0)) || (this->m_objectKey == 8)) { - if (m_objectKey == 8) { - unk_0x1d4 = 30.0f; - unk_0x1d8 = 30.0f; +void GameObject::updateState() { + if (!this->m_stateVar) { + this->deactivateObject(); } +} - if (m_touchTriggered) { - // this->m_type = 21; - this->m_isDisabled = false; - } +void GameObject::customSetup() { } -CCRect GameObject::getObjectRect() -{ - return getObjectRect2(m_scaleModX, m_scaleModY); +void GameObject::resetObject() { + this->m_hasBeenActivated = false; + this->m_isSleeping = false; + this->unk_0x1de = false; } -CCRect GameObject::getObjectRect(float scaleModX, float scaleModY) -{ - CCSize objSize = CCSizeMake(unk_0x1d4, unk_0x1d8); +void GameObject::update(float dt) { +} +cocos2d::CCRect GameObject::getObjectRect() { + return this->getObjectRect(this->m_scaleModX, this->m_scaleModY); +} +void GameObject::calculateSpawnXPos() { + this->m_spawnXPos = this->m_startPos.x; +} - // this function seems a bit complicated, will finish later - return CCRectMake(0, 0, objSize.width, objSize.height); +void GameObject::triggerActivated() { + this->m_hasBeenActivated = true; } -CCRect GameObject::getObjectRect2(float scaleModX, float scaleModY) -{ - if (unk_0x218) { - unk_0x218 = true; - unk_0x208 = getObjectRect(scaleModX, scaleModY); +void GameObject::powerOnObject() { + bool activated = this->m_poweredOn; + this->m_stateVar = true; + if (!activated) { + this->m_poweredOn = true; } - return unk_0x208; } -void GameObject::createAndAddParticle(int objType, char const* file, int zOrder, cocos2d::tCCPositionType positionType) -{ - PLAY_LAYER->createParticle(objType, file, zOrder, positionType); - m_particleString = PLAY_LAYER->getParticleKey(objType, file, zOrder, positionType); - m_particleAdded = true; +void GameObject::powerOffObject() { + if (this->m_poweredOn) { + this->m_poweredOn = false; + } } -void GameObject::triggerObject() -{ - // todo -} +cocos2d::CCRect GameObject::getObjectRect(float scaleX, float scaleY) { + cocos2d::CCSize size = cocos2d::CCSizeMake(this->unk_0x1d4, this->unk_0x1d8); + float width = size.width * scaleX; + float height = size.height * scaleY; -void GameObject::deactivateObject() -{ - // todo -} + if (this->m_isRotated) { + float temp = width; + width = height; + height = temp; + } -CCRect GameObject::getObjectTextureRect() -{ - // todo - return CCRect(); + cocos2d::CCPoint pos = this->getPosition(); + return cocos2d::CCRectMake(pos.x - width / 2.0f, pos.y - height / 2.0f, width, height); } -CCPoint GameObject::getRealPosition() -{ - return m_realPosition; -} +void GameObject::setOpacity(unsigned char opacity) { + unsigned int finalOpacity = opacity; + if (!this->m_isSleeping) { + finalOpacity = static_cast(opacity * this->m_opacityMod); + } + + cocos2d::CCSprite::setOpacity(finalOpacity); + this->setGlowOpacity(finalOpacity); -void GameObject::setStartPos(CCPoint position) -{ - m_realPosition = position; - this->setPosition(position); + if (this->m_hasColor && this->m_colorSprite && reinterpret_cast(this->m_colorSprite) != 0xCDCDCDCD) { + this->m_colorSprite->setOpacity(finalOpacity); + } } -std::string GameObject::getSaveString() -{ - // this is like a pretty big function and i don't know if it's worth decompiling yet - return ""; +void GameObject::setGlowOpacity(unsigned char opacity) { + if (this->m_glowSprite && reinterpret_cast(this->m_glowSprite) != 0xCDCDCDCD) { + unsigned char scaledOpacity = static_cast(opacity * this->m_glowOpacityMod); + this->m_glowSprite->setOpacity(scaledOpacity); + } } -void GameObject::calculateSpawnXPos() -{ - m_spawnXPos = m_realPosition.x; +void GameObject::setChildColor(cocos2d::_ccColor3B color) { + if (this->m_hasColor && this->m_colorSprite && reinterpret_cast(this->m_colorSprite) != 0xCDCDCDCD) { + this->m_colorSprite->setColor(color); + } } \ No newline at end of file diff --git a/Classes/GameObject.h b/Classes/GameObject.h index d64f2ab..05b926f 100644 --- a/Classes/GameObject.h +++ b/Classes/GameObject.h @@ -1,154 +1,136 @@ - #ifndef __GeometryDash__GameObject__ #define __GeometryDash__GameObject__ #include "cocos2d.h" #include "RT_COCOS/CCSpritePlus.h" #include +#include enum GameObjectType : int32_t { - None = 0, - Hazard = 2, - InvertGravityPortal = 3, - NormalGravityPortal = 4, - ShipPortal = 5, - CubePortal = 6, - Decoration = 7, - YellowPad = 9, - GravityPad = 10, - YellowOrb = 11, - BlueOrb = 12, - MirrorPortal = 13, - CounterMirrorPortal = 14, - BallPortal = 15, + None = 0, + Hazard = 2, + InvertGravityPortal = 3, + NormalGravityPortal = 4, + ShipPortal = 5, + CubePortal = 6, + Decoration = 7, + YellowPad = 9, + GravityPad = 10, + YellowOrb = 11, + BlueOrb = 12, + MirrorPortal = 13, + CounterMirrorPortal = 14, + BallPortal = 15, unknown22 = 22, - SecretCoin = 23 + SecretCoin = 23 }; -/** - @brief Represents an object in a level - */ + class GameObject : public CCSpritePlus { public: - GameObject(); + GameObject(); static GameObject* objectFromString(std::string objString); - static GameObject* create(const char* spriteName); - bool init(const char* spriteName); - - // virtual void update(float dt); - // virtual void setScaleX(float scaleX); - // virtual void setScaleY(float scaleY); - // virtual void setScale(float scale); - virtual void setPosition(cocos2d::CCPoint const &position); - // virtual void setVisible(bool visible); - // virtual void setRotation(float rotation); - // virtual void setOpacity(unsigned char opacity); - - void disableObject(); - const char* getBallFrame(int idx); - // void addColorSprite(); - /*void removeGlow();*/ + static GameObject* create(const char* spriteName); + bool init(const char* spriteName); + virtual void setPosition(cocos2d::CCPoint const &position) override; + void setFlipX(bool flipX); + void setFlipY(bool flipY); + virtual void setOpacity(unsigned char opacity) override; + virtual void resetObject(); + virtual void triggerObject(); + virtual void activateObject(); + virtual void deactivateObject(); + + void disableObject(); + const char* getBallFrame(int idx); void updateState(); void customSetup(); + void update(float dt); + cocos2d::CCRect getObjectRect(); + cocos2d::CCRect getObjectRect(float scaleX, float scaleY); + void calculateSpawnXPos(); + void triggerActivated(); + void powerOnObject(); + void powerOffObject(); + void setGlowOpacity(unsigned char opacity); + void setChildColor(cocos2d::_ccColor3B color); - virtual void setFlipX(bool flipX); - virtual void setFlipY(bool flipY); - virtual void resetObject(); - virtual void triggerObject(); - virtual void activateObject(); - virtual void deactivateObject(); - virtual cocos2d::CCRect getObjectRect(); - virtual cocos2d::CCRect getObjectRect(float scaleModX, float scaleModY); - virtual cocos2d::CCRect getObjectRect2(float scaleModX, float scaleModY); - virtual cocos2d::CCRect getObjectTextureRect(); - virtual cocos2d::CCPoint getRealPosition(); - virtual void setStartPos(cocos2d::CCPoint position); - virtual std::string getSaveString(); // unimplemented - virtual void calculateSpawnXPos(); - virtual void triggerActivated(); - virtual void powerOnObject(); - virtual void powerOffObject(); + CC_SYNTHESIZE_READONLY(bool, m_isActive, IsActive); + CC_SYNTHESIZE_READONLY(bool, m_hasColor, HasColor); + CC_SYNTHESIZE_READONLY(cocos2d::CCSprite*, m_colorSprite, ColorSprite); + CC_SYNTHESIZE(bool, m_ignoreScreenCheck, IgnoreScreenCheck); + CC_SYNTHESIZE_READONLY(float, m_radius, Radius); + CC_SYNTHESIZE_READONLY(bool, m_isRotated, IsRotated); + CC_SYNTHESIZE(float, m_scaleModX, ScaleModX); + CC_SYNTHESIZE(float, m_scaleModY, ScaleModY); + CC_SYNTHESIZE(int, m_ID, M_ID); + CC_SYNTHESIZE(int, m_type, Type); + CC_SYNTHESIZE(int, m_sectionIdx, SectionIdx); + CC_SYNTHESIZE_READONLY(bool, m_shouldSpawn, ShouldSpawn); + CC_SYNTHESIZE(bool, m_touchTriggered, TouchTriggered); + CC_SYNTHESIZE_READONLY(bool, m_blendAdditive, BlendAdditive); + CC_SYNTHESIZE_READONLY(bool, m_usePlayerColor, UsePlayerColor); + CC_SYNTHESIZE_READONLY(bool, m_usePlayerColor2, UsePlayerColor2); + CC_SYNTHESIZE(bool, m_isDisabled, IsDisabled); + CC_SYNTHESIZE(bool, m_useAudioScale, UseAudioScale); + CC_SYNTHESIZE_READONLY(bool, m_isSleeping, IsSleeping); + CC_SYNTHESIZE(float, m_startRotation, StartRotation); + CC_SYNTHESIZE(float, m_startScaleX, StartScaleX); + CC_SYNTHESIZE(float, m_startScaleY, StartScaleY); + CC_SYNTHESIZE(bool, m_shouldHide, ShouldHide); + CC_SYNTHESIZE_READONLY(int, m_spawnXPos, SpawnXPos); + CC_SYNTHESIZE_READONLY(bool, m_isInvisible, IsInvisible); + CC_SYNTHESIZE(float, m_enterAngle, EnterAngle); + CC_SYNTHESIZE(int, m_enterEffect, EnterEffect); + CC_SYNTHESIZE(cocos2d::_ccColor3B, m_tintColor, TintColor); + CC_SYNTHESIZE(float, m_tintDuration, TintDuration); + CC_SYNTHESIZE(bool, m_tintGround, TintGround); + CC_SYNTHESIZE(int, m_objectKey, ObjectKey); + CC_SYNTHESIZE(bool, m_dontTransform, DontTransform); + CC_SYNTHESIZE(bool, m_dontFade, DontFade); + CC_SYNTHESIZE(bool, m_dontFadeTinted, DontFadeTinted); + CC_SYNTHESIZE(bool, m_isTintObject, IsTintObject); + CC_SYNTHESIZE_READONLY(bool, m_hasBeenActivated, HasBeenActivated); + CC_SYNTHESIZE(bool, m_stateVar, StateVar); + CC_SYNTHESIZE(int, m_objectZ, ObjectZ); + CC_SYNTHESIZE(cocos2d::CCNode*, m_objectParent, ObjectParent); + CC_SYNTHESIZE_READONLY(bool, m_customAudioScale, CustomAudioScale); + CC_SYNTHESIZE_READONLY(float, m_minAudioScale, MinAudioScale); + CC_SYNTHESIZE_READONLY(float, m_maxAudioScale, MaxAudioScale); + CC_SYNTHESIZE(int, m_uniqueID, UniqueID); + CC_SYNTHESIZE_READONLY(bool, m_invisibleMode, InvisibleMode); + CC_SYNTHESIZE_READONLY(bool, m_glowUseBGColor, GlowUseBGColor); + CC_SYNTHESIZE_READONLY(bool, m_useBGColor, UseBGColor); + CC_SYNTHESIZE_READONLY(bool, m_useSpecialLight, UseSpecialLight); + CC_SYNTHESIZE(float, m_opacityMod, OpacityMod); + CC_SYNTHESIZE(float, m_glowOpacityMod, GlowOpacityMod); + CC_SYNTHESIZE(bool, m_dontShow, DontShow); + CC_SYNTHESIZE(bool, m_editorSelected, EditorSelected); + CC_SYNTHESIZE(bool, m_copyPlayerColor1, CopyPlayerColor1); + CC_SYNTHESIZE(bool, m_copyPlayerColor2, CopyPlayerColor2); + CC_SYNTHESIZE(bool, m_tintObjectsUseBlend, TintObjectsUseBlend); + CC_SYNTHESIZE_READONLY(cocos2d::CCPoint, m_startPos, StartPos); + CC_SYNTHESIZE(std::string, m_frame, Frame); - void createAndAddParticle(int objType, char const* file, int zOrder, cocos2d::tCCPositionType positionType); - - int unk_0x1b8; - int unk_0x1bc; - bool unk_0x1c0; - cocos2d::CCSprite* m_glowSprite; // 0x1c4 - bool unk_0x1c8; - bool unk_0x1c9; - cocos2d::CCAction* m_myAction; // 0x1cc - bool unk_0x1d0; - bool m_poweredOn; // 0x1d1 - float unk_0x1d4; - float unk_0x1d8; - CC_SYNTHESIZE_READONLY(bool, m_isActive, IsActive); // 0x1dc - bool m_hasGlow; // 0x1dd - bool unk_0x1de; - cocos2d::CCParticleSystemQuad* m_particleSystem; // 0x1e0 - std::string m_particleString; // 0x1e4 - bool m_particleAdded; // 0x1e8 - cocos2d::CCPoint unk_0x1ec; - cocos2d::CCRect unk_0x1f4; - bool unk_0x204; - cocos2d::CCRect unk_0x208; - bool unk_0x218; - CC_SYNTHESIZE_READONLY(bool, m_hasColor, HasColor); // 0x219 - CC_SYNTHESIZE_READONLY(cocos2d::CCSprite*, m_colorSprite, ColorSprite); // 0x21c - CC_SYNTHESIZE(bool, m_ignoreScreenCheck, IgnoreScreenCheck); // 0x220 - CC_SYNTHESIZE_READONLY(float, m_radius, Radius); // 0x224 - CC_SYNTHESIZE_READONLY(bool, m_isRotated, IsRotated); // 0x228 - CC_SYNTHESIZE(float, m_scaleModX, ScaleModX); // 0x22c - CC_SYNTHESIZE(float, m_scaleModY, ScaleModY); // 0x230 - CC_SYNTHESIZE(int, m_ID, M_ID); // 0x234 - CC_SYNTHESIZE(GameObjectType, m_type, Type); // 0x238 - CC_SYNTHESIZE(int, m_sectionIdx, SectionIdx); // 0x23c - CC_SYNTHESIZE_READONLY(bool, m_shouldSpawn, ShouldSpawn); // 0x240 - CC_SYNTHESIZE(bool, m_touchTriggered, TouchTriggered); // 0x241 - // this is a bit strange theres this function getStartPos and getRealPosition and they both return this variable which is 0x244 - CC_SYNTHESIZE_READONLY(cocos2d::CCPoint, m_realPosition, StartPos); // 0x244 - CC_SYNTHESIZE_READONLY(std::string, m_frame, Frame); // 0x24c - CC_SYNTHESIZE_READONLY(bool, m_blendAdditive, BlendAdditive); // 0x250 - CC_SYNTHESIZE_READONLY(bool, m_usePlayerColor, UsePlayerColor); // 0x251 - CC_SYNTHESIZE_READONLY(bool, m_usePlayerColor2, UsePlayerColor2); // 0x252 - CC_SYNTHESIZE(bool, m_isDisabled, IsDisabled); // 0x253 - CC_SYNTHESIZE(bool, m_useAudioScale, UseAudioScale); // 0x254 - CC_SYNTHESIZE_READONLY(bool, m_isSleeping, IsSleeping); // 0x255 - CC_SYNTHESIZE(float, m_startRotation, StartRotation); // 0x258 - CC_SYNTHESIZE(float, m_startScaleX, StartScaleX); // 0x25c - CC_SYNTHESIZE(float, m_startScaleY, StartScaleY); // 0x260 - CC_SYNTHESIZE(bool, m_shouldHide, ShouldHide); // 0x264 - CC_SYNTHESIZE_READONLY(float, m_spawnXPos, SpawnXPos); // 0x268 - CC_SYNTHESIZE_READONLY(bool, m_isInvisible, IsInvisible); // 0x26c - CC_SYNTHESIZE(float, m_enterAngle, EnterAngle); // 0x270 - CC_SYNTHESIZE(int, m_enterEffect, EnterEffect); // 0x274 - CC_SYNTHESIZE(cocos2d::ccColor3B, m_tintColor, TintColor); // 0x278 - CC_SYNTHESIZE(float, m_tintDuration, TintDuration); // 0x27c - CC_SYNTHESIZE(bool, m_tintGround, TintGround); // 0x280 - CC_SYNTHESIZE(int, m_objectKey, ObjectKey); // 0x284 - CC_SYNTHESIZE(bool, m_dontTransform, DontTransform); // 0x288 - CC_SYNTHESIZE(bool, m_dontFade, DontFade); // 0x289 - CC_SYNTHESIZE(bool, m_dontFadeTinted, DontFadeTinted); // 0x28a - CC_SYNTHESIZE(bool, m_isTintObject, IsTintObject); // 0x28b - CC_SYNTHESIZE_READONLY(bool, m_hasBeenActivated, HasBeenActivated); // 0x28c - CC_SYNTHESIZE(bool, m_stateVar, StateVar); // 0x28d - CC_SYNTHESIZE(int, m_objectZ, ObjectZ); // 0x290 - CC_SYNTHESIZE(cocos2d::CCNode*, m_objectParent, ObjectParent); // 0x294 - CC_SYNTHESIZE_READONLY(bool, m_customAudioScale, CustomAudioScale); // 0x298 - CC_SYNTHESIZE_READONLY(float, m_minAudioScale, MinAudioScale); // 0x29c - CC_SYNTHESIZE_READONLY(float, m_maxAudioScale, MaxAudioScale); // 0x2a0 - CC_SYNTHESIZE(int, m_uniqueID, UniqueID); // 0x2a4 - CC_SYNTHESIZE_READONLY(bool, m_invisibleMode, InvisibleMode); // 0x2a8 - CC_SYNTHESIZE_READONLY(bool, m_glowUseBGColor, GlowUseBGColor); // 0x2a9 - CC_SYNTHESIZE_READONLY(bool, m_useBGColor, UseBGColor); // 0x2aa - CC_SYNTHESIZE_READONLY(bool, m_useSpecialLight, UseSpecialLight); // 0x2ab - CC_SYNTHESIZE(float, m_opacityMod, OpacityMod); // 0x2ac - CC_SYNTHESIZE(float, m_glowOpacityMod, GlowOpacityMod); // 0x2b0 - CC_SYNTHESIZE(bool, m_dontShow, DontShow); // 0x2b4 - CC_SYNTHESIZE(bool, m_editorSelected, EditorSelected); // 0x2b5 - CC_SYNTHESIZE(bool, m_copyPlayerColor1, CopyPlayerColor1); // 0x2b6 - CC_SYNTHESIZE(bool, m_copyPlayerColor2, CopyPlayerColor2); // 0x2b7 - CC_SYNTHESIZE(bool, m_tintObjectsUseBlend, TintObjectsUseBlend); // 0x2b8 +private: + int unk_0x1b8; + int unk_0x1bc; + bool unk_0x1c0; + cocos2d::CCSprite* m_glowSprite; + bool unk_0x1c8; + bool unk_0x1c9; + cocos2d::CCAction* m_myAction; + bool unk_0x1d0; + bool m_poweredOn; + float unk_0x1d4; + float unk_0x1d8; + bool m_hasGlow; + bool unk_0x1de; + cocos2d::CCParticleSystem* m_particleSystem; + std::string m_particleString; + bool m_particleAdded; + bool unk_0x204; + bool unk_0x218; }; -#endif +#endif \ No newline at end of file diff --git a/Classes/LevelPage.cpp b/Classes/LevelPage.cpp index 180c1cf..be6b798 100644 --- a/Classes/LevelPage.cpp +++ b/Classes/LevelPage.cpp @@ -1,3 +1,6 @@ +// decompiled by ItzZyann +// from GD 1.71 binary + #include "LevelPage.h" #include "RT_COCOS/CCMenuItemSpriteExtra.h" #include "cocos-ext.h" @@ -12,102 +15,149 @@ USING_NS_CC_EXT; LevelPage* LevelPage::create(GJGameLevel* level) { - LevelPage* pRet = new LevelPage(); - if (pRet && pRet->init(level)) - { - pRet->autorelease(); - return pRet; - } - else - { - delete pRet; - pRet = NULL; - return NULL; - } + LevelPage* pRet = new LevelPage(); + if (pRet && pRet->init(level)) + { + pRet->autorelease(); + return pRet; + } + else + { + delete pRet; + pRet = NULL; + return NULL; + } } -// the code situation has improved bool LevelPage::init(GJGameLevel* level) { - if (!CCLayer::init()) - return false; - - m_level = level; - m_level->retain(); - - CCSize winSize = CCDirector::sharedDirector()->getWinSize(); - + if (!CCLayer::init()) + return false; + + CCSize winSize = CCDirector::sharedDirector()->getWinSize(); + + m_level = level; + m_level->retain(); + + // int userCoins = GameStatsManager::sharedState()->getStat("8"); + int reqCoins = m_level->getRequiredCoins(); + bool locked = false; + m_levelMenu = CCMenu::create(); this->addChild(m_levelMenu, -1); m_levelMenu->setPosition(ccp(winSize.width * 0.5f, winSize.height * 0.5f + 60.0f)); - - CCScale9Sprite* button = CCScale9Sprite::create("square02_001.png", CCRect(0, 0, 80, 80)); - button->setColor(ccc3(125,125,125)); - button->setOpacity(125); - button->setContentSize(CCSize(340, 95)); - button->setPosition(ccp(winSize.width * 0.5f, winSize.height * 0.5f + 50.0f)); - + + CCScale9Sprite* button = CCScale9Sprite::create("square02_001.png", CCRect(0, 0, 80, 80)); + button->setOpacity(125); + button->setContentSize(CCSize(340, 95)); + CCSprite* buttonSpr = CCSprite::create(); buttonSpr->addChild(button); buttonSpr->setContentSize(button->getContentSize()); - button->setPosition(ccp(button->getContentSize().width * 0.5f, button->getContentSize().height * 0.5f)); + button->setPosition(ccp(button->getContentSize().width * 0.5f, + button->getContentSize().height * 0.5f)); - CCMenuItemSpriteExtra* playExtra = CCMenuItemSpriteExtra::create(buttonSpr, NULL, this, menu_selector(LevelPage::onPlay)); - playExtra->setScaleVar(1.1f); + CCMenuItemSpriteExtra* playExtra = CCMenuItemSpriteExtra::create( + buttonSpr, NULL, this, menu_selector(LevelPage::onPlay)); + playExtra->setScaleVar(1.1f); m_levelMenu->addChild(playExtra); - - if (true) { - - auto nameLabel = CCLabelBMFont::create(m_level->getLevelName().c_str(), "bigFont.fnt"); - nameLabel->setAnchorPoint(ccp(0, 0.5f)); - nameLabel->setPosition(ccp(65, 47.5f)); - button->addChild(nameLabel); - - if (nameLabel->getContentSize().width > 250.0f) - nameLabel->setScale(250.0f / nameLabel->getContentSize().width); + + + // uncomment + // when dict is complete + // and some stuffs from user + + if (locked) { + CCSprite* lockSpr = CCSprite::createWithSpriteFrameName("GJLargeLock_001.png"); + button->addChild(lockSpr); + lockSpr->setPosition(ccp(170.0f, 47.5f)); + + // int userCoins = GameStatsManager::sharedState()->getStat("8"); + int userCoins = 0; + CCSprite* coinIcon = CCSprite::createWithSpriteFrameName("GJ_coinsIcon_001.png"); + coinIcon->setScale(1.0f); + coinIcon->setPosition(ccp(325.0f, 15.0f)); + + CCString* coinStr = CCString::createWithFormat("%i/%i", userCoins, reqCoins); + CCLabelBMFont* coinLabel = CCLabelBMFont::create(coinStr->getCString(), "bigFont.fnt"); + coinLabel->setAnchorPoint(ccp(1.0f, 0.5f)); + coinLabel->setPosition(coinIcon->getPosition() + ccp(-15.0f, 0.5f)); + coinLabel->setScale(0.5f); + + button->addChild(coinIcon); + button->addChild(coinLabel); + } + else { + CCLabelBMFont* nameLabel = CCLabelBMFont::create( + m_level->getLevelName().c_str(), "bigFont.fnt"); + nameLabel->setAnchorPoint(ccp(0.0f, 0.5f)); + button->addChild(nameLabel); + + if (nameLabel->getContentSize().width > 250.0f) + nameLabel->setScale(250.0f / nameLabel->getContentSize().width); nameLabel->setScale((std::min)(nameLabel->getScale(), 1.0f)); - - auto diffStr = CCString::createWithFormat("diffIcon_%02d_btn_001.png", m_level->getDifficulty()); - auto diffSpr = CCSprite::createWithSpriteFrameName(diffStr->getCString()); - diffSpr->setScale(1.1f); - diffSpr->setPosition(ccp(35.75, 47.5f)); - button->addChild(diffSpr); - - if (m_level->getStars() > 0) { - auto starIcon = CCSprite::createWithSpriteFrameName("GJ_starsIcon_001.png"); - starIcon->setScale(0.6f); - starIcon->setPosition(ccp(325, 82)); - button->addChild(starIcon); - - auto starText = CCString::createWithFormat("%i", m_level->getStars()); - auto label = CCLabelBMFont::create(starText->getCString(), "bigFont.fnt"); - - label->setAnchorPoint(ccp(1, 0.5f)); - label->setScale(0.5f); - label->setPosition(starIcon->getPosition() + CCPoint(-12, 0)); - button->addChild(label); - } - } else { - - } - - + + int diff = m_level->getDifficulty(); + if (diff <= 0 || diff > 6) + diff = 0; + + CCString* diffStr = CCString::createWithFormat("diffIcon_%02d_btn_001.png", diff); + CCSprite* diffSpr = CCSprite::createWithSpriteFrameName(diffStr->getCString()); + button->addChild(diffSpr); + diffSpr->setScale(1.1f); + + // fix title and diff + // not position properly + float diffW = diffSpr->getContentSize().width * diffSpr->getScale(); + float nameW = nameLabel->getContentSize().width * nameLabel->getScale(); + float groupWidth = diffW + nameW + 5.0f + 30.0f; + float groupLeft = 170.0f - groupWidth * 0.5f; + diffSpr->setPosition(ccp(groupLeft + diffW * 0.5f, 50.5f)); + nameLabel->setPosition(ccp(diffSpr->getPosition().x + 30.0f, 50.5f)); + + if (m_level->getStars() > 0) { + CCSprite* starIcon = CCSprite::createWithSpriteFrameName("GJ_starsIcon_001.png"); + button->addChild(starIcon); + starIcon->setScale(0.6f); + starIcon->setPosition(ccp(325.0f, 82.0f)); + + CCString* starStr = CCString::createWithFormat("%i", m_level->getStars()); + CCLabelBMFont* starLabel = CCLabelBMFont::create(starStr->getCString(), "bigFont.fnt"); + button->addChild(starLabel); + starLabel->setAnchorPoint(ccp(1.0f, 0.5f)); + starLabel->setPosition(starIcon->getPosition() + ccp(-12.0f, 0.5f)); + starLabel->setScale(0.5f); + + // if (GameStatsManager::sharedState()->hasCompletedStarLevel(m_level)) + // starLabel->setColor(ccc3(255, 255, 50)); + } + } + + // just fixed progress bar + // god this is just easy fix CCSprite* normalBar = CCSprite::create("GJ_progressBar_001.png"); normalBar->setColor(ccBLACK); normalBar->setOpacity(125); normalBar->setScale(1.0f); this->addChild(normalBar, 3); - normalBar->setPosition(ccp(winSize.width * 0.5f, (winSize.height * 0.5f) - 30.0f)); - + normalBar->setPosition(ccp(winSize.width * 0.5f, winSize.height * 0.5f - 30.0f)); + CCSprite* normalFill = CCSprite::create("GJ_progressBar_001.png"); normalFill->setScaleX(0.992f); normalFill->setScaleY(0.86f); normalFill->setColor(ccGREEN); normalBar->addChild(normalFill, 1); normalFill->setAnchorPoint(ccp(0.0f, 0.5f)); - CCSize nbContSize = normalBar->getContentSize(); - normalFill->setPosition(ccp((nbContSize.width - nbContSize.width * 0.992f) * 0.5f, nbContSize.height * 0.5f)); + { + float barW = normalFill->getContentSize().width; + float offsetX = (barW - barW * 0.992f) * 0.5f; + normalFill->setPosition(ccp(offsetX, normalBar->getContentSize().height * 0.5f)); + float pct = (float)m_level->getNormalPercent() / 100.0f; + float fillW = barW * pct; + if (fillW > barW) fillW = barW; + normalFill->setTextureRect(CCRect(0, 0, fillW, normalFill->getContentSize().height)); + } CCSprite* practiceBar = CCSprite::create("GJ_progressBar_001.png"); practiceBar->setColor(ccBLACK); @@ -122,73 +172,97 @@ bool LevelPage::init(GJGameLevel* level) practiceFill->setColor(ccc3(0, 255, 255)); practiceBar->addChild(practiceFill, 1); practiceFill->setAnchorPoint(ccp(0.0f, 0.5f)); - practiceFill->setPosition(normalFill->getPosition()); + { + practiceFill->setPosition(normalFill->getPosition()); + + float barW = practiceFill->getContentSize().width; + float pct = (float)m_level->getPracticePercent() / 100.0f; + float fillW = barW * pct; + if (fillW > barW) fillW = barW; + practiceFill->setTextureRect(CCRect(0, 0, fillW, practiceFill->getContentSize().height)); + } - // some missing stuff that i need to add in - CCLabelBMFont* normalPct = CCLabelBMFont::create( - CCString::createWithFormat("%i%%", level->getNormalPercent())->getCString(), + CCString::createWithFormat("%i%%", m_level->getNormalPercent())->getCString(), "bigFont.fnt"); this->addChild(normalPct, 4); normalPct->setPosition(normalBar->getPosition()); normalPct->setScale(0.5f); CCLabelBMFont* practicePct = CCLabelBMFont::create( - CCString::createWithFormat("%i%%", level->getPracticePercent())->getCString(), + CCString::createWithFormat("%i%%", m_level->getPracticePercent())->getCString(), "bigFont.fnt"); this->addChild(practicePct, 4); practicePct->setPosition(practiceBar->getPosition()); practicePct->setScale(0.5f); - - // missing the other one too CCLabelBMFont* normalLabel = CCLabelBMFont::create("Normal Mode", "bigFont.fnt"); this->addChild(normalLabel, 4); - normalLabel->setPosition(ccp(0.0f, 20.0f) + normalPct->getPosition()); + normalLabel->setPosition(normalBar->getPosition() + ccp(0.0f, 20.0f)); normalLabel->setScale(0.5f); CCLabelBMFont* practiceLabel = CCLabelBMFont::create("Practice Mode", "bigFont.fnt"); this->addChild(practiceLabel, 4); - practiceLabel->setPosition(ccp(0.0f, 20.0f) + practicePct->getPosition()); + practiceLabel->setPosition(practiceBar->getPosition() + ccp(0.0f, 20.0f)); practiceLabel->setScale(0.5f); - - int coinCount = m_level->getCoins(); - CCPoint basePos(324, 16); - - for (int i = 1; i <= coinCount; i++) { - bool hasCoin = false; - char const* icon = hasCoin ? "GJ_coinsIcon_001.png" : "GJ_coinsIcon_gray_001.png"; - auto coin = CCSprite::createWithSpriteFrameName(icon); - coin->setPosition(basePos + CCPoint((coinCount - i) * -26.0f, 0)); - button->addChild(coin); - } - - // collected star text: 255, 255, 50 - - return true; + + int coinCount = m_level->getCoins(); + if (coinCount > 0 && !locked) { + CCPoint basePos(324.0f, 16.0f); + for (int i = 1; i <= coinCount; i++) { + + // bool hasCoin = GameStatsManager::sharedState()->hasUniqueItem(m_level->getCoinKey(i)); + bool hasCoin = false; + const char* icon = hasCoin + ? "GJ_coinsIcon_001.png" + : "GJ_coinsIcon_gray_001.png"; + + CCSprite* coin = CCSprite::createWithSpriteFrameName(icon); + button->addChild(coin); + coin->setScale(1.0f); + coin->setPosition(basePos + ccp((float)(coinCount - i) * -26.0f, 0.0f)); + + if (!hasCoin) + coin->setColor(ccc3(225, 225, 225)); + } + } + + return true; } -void LevelPage::onInfo(cocos2d::CCObject* sender) -{ - // WIP - FLAlertLayer::create(nullptr, "Level Stats", "insert string here", "OK", nullptr, 300.0f)->show(); +void LevelPage::onInfo(cocos2d::CCObject* sender) { + cocos2d::CCString* text = cocos2d::CCString::createWithFormat( + "%s\n" + "Total Attempts: %i\n" + "Total Jumps: %i\n" + "Normal: %i%%\n" + "Practice: %i%%", + m_level->getLevelName().c_str(), + m_level->getAttempts(), + m_level->getJumps(), + m_level->getNormalPercent(), + m_level->getPracticePercent() + ); + + FLAlertLayer::create( + nullptr, "Level Stats", text->getCString(), + "OK", nullptr, + 300.0f)->show(); } void LevelPage::onPlay(cocos2d::CCObject* sender) { - // GameStatsManager* GStatsM = GameStatsManager::GameStatsManager(); - SimpleAudioEngine* SAE = SimpleAudioEngine::sharedEngine(); - SAE->stopBackgroundMusic(); - + SimpleAudioEngine* SAE = SimpleAudioEngine::sharedEngine(); + SAE->stopBackgroundMusic(); + GameSoundManager* GSoundM = GameSoundManager::sharedManager(); GSoundM->playEffect("playSound_01.ogg", 1.0f, 0.0f, 0.3f); - GameManager* pGameManager = GameManager::sharedState(); - pGameManager->setLastScene(LastGameScene::LevelSelect); - - CCDirector* pDirector = CCDirector::sharedDirector(); - CCScene* pScene = PlayLayer::scene(m_level); - CCTransitionFade* fade = CCTransitionFade::create(0.5f, pScene); - pDirector->replaceScene(fade); - return; + GameManager* pGameManager = GameManager::sharedState(); + pGameManager->setLastScene(LastGameScene::LevelSelect); + + CCDirector* pDirector = CCDirector::sharedDirector(); + CCScene* pScene = PlayLayer::scene(m_level); + CCTransitionFade* fade = CCTransitionFade::create(0.5f, pScene); + pDirector->replaceScene(fade); } \ No newline at end of file diff --git a/Classes/LevelPage.h b/Classes/LevelPage.h index a6389d1..2f824bd 100644 --- a/Classes/LevelPage.h +++ b/Classes/LevelPage.h @@ -6,13 +6,14 @@ #include class LevelPage : public cocos2d::CCLayer { - GJGameLevel* m_level; // 0x110 - cocos2d::CCMenu* m_levelMenu; // 0x114 public: static LevelPage* create(GJGameLevel* level); bool init(GJGameLevel* level); void onInfo(cocos2d::CCObject* sender); void onPlay(cocos2d::CCObject* sender); + + GJGameLevel* m_level; // 0x110 + cocos2d::CCMenu* m_levelMenu; // 0x114 }; #endif /* defined(__GeometryDash__LevelPage__) */ diff --git a/Classes/LevelSelectLayer.cpp b/Classes/LevelSelectLayer.cpp index 334e1a4..1f6d8a1 100644 --- a/Classes/LevelSelectLayer.cpp +++ b/Classes/LevelSelectLayer.cpp @@ -1,4 +1,6 @@ -// Partially decompiled by ProjectReversio: https://github.com/ProjectReversio/GeometryDash/blob/master/GeometryDash/Classes/LevelSelectLayer.cpp +// decompiled by ItzZyann and Aloaf +// from GD 1.71 binary + #include "LevelSelectLayer.h" #include "AppDelegate.h" @@ -16,43 +18,40 @@ USING_NS_CC; LevelSelectLayer::LevelSelectLayer() { - // mUnknown1 = 0.0f; - m_background = NULL; - // mGroundLayer = NULL; + m_bslDelegate = NULL; + m_winWidth = 0.0f; + m_background = NULL; + m_ground = NULL; + m_scrollLayer = NULL; } CCScene* LevelSelectLayer::scene(int page) { - // 'scene' is an autorelease object - CCScene* scene = CCScene::create(); - - AppDelegate* pApp = AppDelegate::get(); - pApp->setScenePointer(scene); - - // 'layer' is an autorelease object - LevelSelectLayer* layer = LevelSelectLayer::create(page); - - // add layer as a child to scene - scene->addChild(layer); - - // return the scene - return scene; + CCScene* scene = CCScene::create(); + + AppDelegate* pApp = AppDelegate::get(); + pApp->setScenePointer(scene); + + LevelSelectLayer* layer = LevelSelectLayer::create(page); + scene->addChild(layer); + + return scene; } LevelSelectLayer* LevelSelectLayer::create(int page) { - LevelSelectLayer* pRet = new LevelSelectLayer(); - if (pRet && pRet->init(page)) - { - pRet->autorelease(); - return pRet; - } - else - { - delete pRet; - pRet = NULL; - return NULL; - } + LevelSelectLayer* pRet = new LevelSelectLayer(); + if (pRet && pRet->init(page)) + { + pRet->autorelease(); + return pRet; + } + else + { + delete pRet; + pRet = NULL; + return NULL; + } } bool LevelSelectLayer::init(int page) @@ -62,8 +61,10 @@ bool LevelSelectLayer::init(int page) this->setKeypadEnabled(true); - CCDirector* pDirector = CCDirector::sharedDirector(); - CCSize winSize = pDirector->getWinSize(); + CCSize winSize = CCDirector::sharedDirector()->getWinSize(); + + // ((float*)this + 68) = v158 → store winWidth for scrollLayerMoved + m_winWidth = winSize.width; m_background = CCSprite::create("GJ_gradientBG.png"); m_background->setAnchorPoint(CCPoint(0.0f, 0.0f)); @@ -73,88 +74,112 @@ bool LevelSelectLayer::init(int page) m_background->setPosition(CCPoint(-5.0f, -5.0f)); m_background->setColor(ccc3(40, 125, 255)); - // ground CCLayer* groundLayer = CCLayer::create(); this->addChild(groundLayer, 0); - m_ground = CCSprite::create(GameManager::sharedState()->getGTexture(1)); + m_ground = CCSprite::create( + GameManager::sharedState()->getGTexture( + GameManager::sharedState()->getLoadedGIdx())); + ccTexParams texParams = { GL_LINEAR, GL_LINEAR, GL_REPEAT, GL_REPEAT }; m_ground->getTexture()->setTexParameters(&texParams); groundLayer->addChild(m_ground, 2); - m_ground->setAnchorPoint(ccp(0, 1)); - m_ground->setScale(pDirector->getScreenScaleFactorMax()); + + m_ground->setAnchorPoint(ccp(0.0f, 1.0f)); + m_ground->setScale(CCDirector::sharedDirector()->getScreenScaleFactorMax()); m_ground->setColor(ccc3(0, 102, 255)); - m_ground->setTextureRect(CCRectMake(0, 0, winSize.width, m_ground->getContentSize().height)); - m_ground->setPosition(ccp(0.0f, (winSize.height * 0.5f) - 110.0f)); float refYPos = (winSize.height * 0.5f) - 110.0f; + float groundH = m_ground->getContentSize().height; + if (refYPos > groundH) + refYPos = groundH; + + CCRect groundRect = m_ground->getTextureRect(); + float cols = ceilf(winSize.width / groundRect.size.width) + 1.0f; + groundRect.size.width = groundRect.size.width * cols; + m_ground->setTextureRect(groundRect); + m_ground->setPosition(ccp(0.0f, refYPos)); CCSprite* lineSprite = CCSprite::createWithSpriteFrameName("floorLine_001.png"); groundLayer->addChild(lineSprite, 3); lineSprite->setPosition(CCPoint(winSize.width * 0.5f, refYPos)); - lineSprite->setBlendFunc({ GL_SRC_ALPHA, GL_ONE }); - lineSprite->setOpacity(100); + ccBlendFunc lineBlendFunc = { GL_SRC_ALPHA, GL_ONE }; + lineSprite->setBlendFunc(lineBlendFunc); + lineSprite->setOpacity(200); CCSprite* leftShadow = CCSprite::createWithSpriteFrameName("groundSquareShadow_001.png"); - leftShadow->setAnchorPoint(ccp(0.0f, 1.0f)); - leftShadow->setPosition(ccp(pDirector->getScreenLeft() - 1.0f, refYPos)); - groundLayer->addChild(leftShadow, 3); - - CCSprite* rightShadow = CCSprite::createWithSpriteFrameName("groundSquareShadow_001.png"); - rightShadow->setAnchorPoint(ccp(1.0f, 1.0f)); - rightShadow->setPosition(ccp(pDirector->getScreenRight() + 1.0f, refYPos)); - groundLayer->addChild(rightShadow, 3); - rightShadow->setFlipX(true); - - leftShadow->setOpacity(100); - rightShadow->setOpacity(100); - - leftShadow->setScaleX(0.7f); - rightShadow->setScaleX(0.7f); - - ccBlendFunc shadowBlendFunc = { GL_ONE_MINUS_SRC_ALPHA, GL_DST_COLOR }; - rightShadow->setBlendFunc(shadowBlendFunc); + leftShadow->setAnchorPoint(ccp(0.0f, 1.0f)); + leftShadow->setPosition(ccp(CCDirector::sharedDirector()->getScreenLeft() - 1.0f, refYPos)); + groundLayer->addChild(leftShadow, 3); + + CCSprite* rightShadow = CCSprite::createWithSpriteFrameName("groundSquareShadow_001.png"); + rightShadow->setAnchorPoint(ccp(1.0f, 1.0f)); + rightShadow->setPosition(ccp(CCDirector::sharedDirector()->getScreenRight() + 1.0f, refYPos)); + groundLayer->addChild(rightShadow, 3); + rightShadow->setFlipX(true); + + leftShadow->setOpacity(100); + rightShadow->setOpacity(100); + + // setScaleX with float bits 0x3F800000 = 1.0f, not 0.7f + leftShadow->setScaleX(1.0f); + rightShadow->setScaleX(1.0f); + + ccBlendFunc shadowBlendFunc = { GL_DST_COLOR, GL_ONE_MINUS_SRC_ALPHA }; // 774, 771 + leftShadow->setBlendFunc(shadowBlendFunc); // FIX: both get it rightShadow->setBlendFunc(shadowBlendFunc); - CCSprite* topBar = CCSprite::createWithSpriteFrameName("GJ_topBar_001.png"); - topBar->setAnchorPoint(CCPoint(0.5f, 1.0f)); - topBar->setPosition(CCPoint(winSize.width * 0.5f, pDirector->getScreenTop() + 1.0f)); - this->addChild(topBar, 1); - - CCSprite* sideArtLeft = CCSprite::createWithSpriteFrameName("GJ_sideArt_001.png"); - sideArtLeft->setAnchorPoint(CCPoint(0.0f, 0.0f)); - sideArtLeft->setPosition(CCPoint(pDirector->getScreenLeft() - 1.0f, pDirector->getScreenBottom() - 1.0f)); - this->addChild(sideArtLeft, 1); - - CCSprite* sideArtRight = CCSprite::createWithSpriteFrameName("GJ_sideArt_001.png"); - sideArtRight->setAnchorPoint(CCPoint(1.0f, 0.0f)); - sideArtRight->setPosition(CCPoint(pDirector->getScreenRight() + 1.0f, pDirector->getScreenBottom() - 1.0f)); - int i = 1; - sideArtRight->setFlipX(true); - this->addChild(sideArtRight, 1); + CCSprite* topBar = CCSprite::createWithSpriteFrameName("GJ_topBar_001.png"); + topBar->setAnchorPoint(CCPoint(0.5f, 1.0f)); + topBar->setPosition(CCPoint(winSize.width * 0.5f, + CCDirector::sharedDirector()->getScreenTop() + 1.0f)); + this->addChild(topBar, 1); + + CCSprite* sideArtLeft = CCSprite::createWithSpriteFrameName("GJ_sideArt_001.png"); + sideArtLeft->setAnchorPoint(CCPoint(0.0f, 0.0f)); + sideArtLeft->setPosition(CCPoint(CCDirector::sharedDirector()->getScreenLeft() - 1.0f, + CCDirector::sharedDirector()->getScreenBottom() - 1.0f)); + this->addChild(sideArtLeft, 1); - CCArray* pages = CCArray::create(); + CCSprite* sideArtRight = CCSprite::createWithSpriteFrameName("GJ_sideArt_001.png"); + sideArtRight->setAnchorPoint(CCPoint(1.0f, 0.0f)); + sideArtRight->setPosition(CCPoint(CCDirector::sharedDirector()->getScreenRight() + 1.0f, + CCDirector::sharedDirector()->getScreenBottom() - 1.0f)); + sideArtRight->setFlipX(true); + this->addChild(sideArtRight, 1); + + CCArray* pages = CCArray::create(); + int i = 1; do { GJGameLevel* level = GameLevelManager::sharedState()->getMainLevel(i); ++i; - LevelPage* page = LevelPage::create(level); - pages->addObject(page); - } while (i != 16); - - // coming soon! - CCLayer* csLayer = CCLayer::create(); - CCLabelBMFont* csLabel = CCLabelBMFont::create("Coming Soon!", "bigFont.fnt"); - csLabel->setPosition(ccp(winSize.width / 2, winSize.height / 2 + 50)); - csLayer->addChild(csLabel); - pages->addObject(csLayer); - - // the third param is for looping - bool showDots = pages->count() > 3; + LevelPage* levelPage = LevelPage::create(level); + pages->addObject(levelPage); + } while (i != 16); + + // Coming soon page + CCLayer* csLayer = CCLayer::create(); + CCLabelBMFont* csLabel = CCLabelBMFont::create("Coming Soon!", "bigFont.fnt"); + csLabel->setPosition(ccp(winSize.width * 0.5f, winSize.height * 0.5f + 50.0f)); + csLayer->addChild(csLabel); + pages->addObject(csLayer); + + // this part is pain in ass + // no wonder why it wouldn't work + // its just because of boomscrolllayer not + // fully decompiled T-T + + bool showDots = pages->count() > 3; m_scrollLayer = BoomScrollLayer::create(pages, 0, showDots); this->addChild(m_scrollLayer); - m_scrollLayer->setPagesIndicatorPosition(ccp(winSize.width * 0.5f, pDirector->getScreenBottom() + 15.0f)); + m_scrollLayer->setPagesIndicatorPosition( + ccp(winSize.width * 0.5f, + CCDirector::sharedDirector()->getScreenBottom() + 15.0f)); m_scrollLayer->getInternalLayer()->setDelegate(m_bslDelegate); + // page == 15 -> instantMoveToPage(14) THEN instantMoveToPage(15) + // this is intentional in the original, it snaps to 14 first then to 15 + // (the "Coming Soon" slide), so we preserve it exactly as assembled. if (page == 0) { this->scrollLayerMoved(CCPointZero); } @@ -165,48 +190,68 @@ bool LevelSelectLayer::init(int page) m_scrollLayer->instantMoveToPage(page); } - CCLabelBMFont* downloadTxt = CCLabelBMFont::create("Download the soundtracks", "bigFont.fnt"); - downloadTxt->setScale(0.5f); - CCMenuItemSpriteExtra* downloadExtra = CCMenuItemSpriteExtra::create(downloadTxt, NULL, this, menu_selector(LevelSelectLayer::onDownload)); - downloadExtra->setSizeMult(2.0f); - - CCMenu* downloadMenu = CCMenu::create(downloadExtra, NULL); - this->addChild(downloadMenu); - downloadMenu->setPosition(CCPoint(winSize.width * 0.5f, pDirector->getScreenBottom() + 35.0f)); - - CCMenu* arrowsMenu = CCMenu::create(); - this->addChild(arrowsMenu, 5); - - CCSprite* leftBtnSprite = CCSprite::createWithSpriteFrameName("navArrowBtn_001.png"); - leftBtnSprite->setFlipX(true); - CCMenuItemSpriteExtra* leftBtn = CCMenuItemSpriteExtra::create(leftBtnSprite, NULL, this, menu_selector(LevelSelectLayer::onPrev)); - arrowsMenu->addChild(leftBtn); - leftBtn->setSizeMult(2.0f); - leftBtn->setPosition(arrowsMenu->convertToNodeSpace(CCPoint(pDirector->getScreenLeft() + 25.0f, winSize.height * 0.5f))); - - CCSprite* rightBtnSprite = CCSprite::createWithSpriteFrameName("navArrowBtn_001.png"); - CCMenuItemSpriteExtra* rightBtn = CCMenuItemSpriteExtra::create(rightBtnSprite, NULL, this, menu_selector(LevelSelectLayer::onNext)); - arrowsMenu->addChild(rightBtn); - rightBtn->setSizeMult(2.0f); - rightBtn->setPosition(arrowsMenu->convertToNodeSpace(CCPoint(pDirector->getScreenRight() - 25.0f, winSize.height * 0.5f))); - - CCSprite* backBtnSprite = CCSprite::createWithSpriteFrameName("GJ_arrow_01_001.png"); - CCMenuItemSpriteExtra* backBtn = CCMenuItemSpriteExtra::create(backBtnSprite, NULL, this, menu_selector(LevelSelectLayer::onBack)); - backBtn->setSizeMult(1.6f); - CCMenu* backMenu = CCMenu::create(backBtn, NULL); - this->addChild(backMenu, 1); - backMenu->setPosition(CCPoint(pDirector->getScreenLeft() + 25.0f, pDirector->getScreenTop() - 22.0f)); - - CCMenu* infoMenu = CCMenu::create(); - this->addChild(infoMenu); - - CCSprite* infoBtnSprite = CCSprite::createWithSpriteFrameName("GJ_infoIcon_001.png"); - CCMenuItemSpriteExtra* infoBtn = CCMenuItemSpriteExtra::create(infoBtnSprite, NULL, this, menu_selector(LevelSelectLayer::onInfo)); - infoBtn->setSizeMult(2.0f); - infoMenu->addChild(infoBtn); - infoMenu->setPosition(CCPoint(pDirector->getScreenRight() - 20.0f, pDirector->getScreenTop() - 20.0f)); - - return true; + CCLabelBMFont* downloadTxt = CCLabelBMFont::create("Download the soundtracks", "bigFont.fnt"); + downloadTxt->setScale(0.5f); + CCMenuItemSpriteExtra* downloadExtra = CCMenuItemSpriteExtra::create( + downloadTxt, NULL, this, menu_selector(LevelSelectLayer::onDownload)); + downloadExtra->setSizeMult(2.0f); + + CCMenu* downloadMenu = CCMenu::create(downloadExtra, NULL); + this->addChild(downloadMenu); + downloadMenu->setPosition(CCPoint(winSize.width * 0.5f, + CCDirector::sharedDirector()->getScreenBottom() + 35.0f)); + + CCMenu* arrowsMenu = CCMenu::create(); + this->addChild(arrowsMenu, 5); + + CCSprite* leftBtnSprite = CCSprite::createWithSpriteFrameName("navArrowBtn_001.png"); + leftBtnSprite->setFlipX(true); + CCMenuItemSpriteExtra* leftBtn = CCMenuItemSpriteExtra::create( + leftBtnSprite, NULL, this, menu_selector(LevelSelectLayer::onPrev)); + arrowsMenu->addChild(leftBtn); + leftBtn->setSizeMult(2.0f); + leftBtn->setPosition(arrowsMenu->convertToNodeSpace( + CCPoint(CCDirector::sharedDirector()->getScreenLeft() + 25.0f, + winSize.height * 0.5f))); + + CCSprite* rightBtnSprite = CCSprite::createWithSpriteFrameName("navArrowBtn_001.png"); + CCMenuItemSpriteExtra* rightBtn = CCMenuItemSpriteExtra::create( + rightBtnSprite, NULL, this, menu_selector(LevelSelectLayer::onNext)); + arrowsMenu->addChild(rightBtn); + rightBtn->setSizeMult(2.0f); + rightBtn->setPosition(arrowsMenu->convertToNodeSpace( + CCPoint(CCDirector::sharedDirector()->getScreenRight() - 25.0f, + winSize.height * 0.5f))); + + // its should setSizeMult(2.0f), the decompiled source had 1.6f which was wrong + CCSprite* backBtnSprite = CCSprite::createWithSpriteFrameName("GJ_arrow_01_001.png"); + CCMenuItemSpriteExtra* backBtn = CCMenuItemSpriteExtra::create( + backBtnSprite, NULL, this, menu_selector(LevelSelectLayer::onBack)); + backBtn->setSizeMult(2.0f); + CCMenu* backMenu = CCMenu::create(backBtn, NULL); + this->addChild(backMenu, 1); + backMenu->setPosition(CCPoint(CCDirector::sharedDirector()->getScreenLeft() + 25.0f, + CCDirector::sharedDirector()->getScreenTop() - 22.0f)); + + CCMenu* infoMenu = CCMenu::create(); + this->addChild(infoMenu); + + CCSprite* infoBtnSprite = CCSprite::createWithSpriteFrameName("GJ_infoIcon_001.png"); + CCMenuItemSpriteExtra* infoBtn = CCMenuItemSpriteExtra::create( + infoBtnSprite, NULL, this, menu_selector(LevelSelectLayer::onInfo)); + infoBtn->setSizeMult(2.0f); + infoMenu->addChild(infoBtn); + infoMenu->setPosition(CCPoint(CCDirector::sharedDirector()->getScreenRight() - 20.0f, + CCDirector::sharedDirector()->getScreenTop() - 20.0f)); + + this->scheduleUpdate(); + + return true; +} + +void LevelSelectLayer::keyBackClicked() +{ + this->onBack(NULL); } void LevelSelectLayer::onDownload(CCObject* sender) @@ -218,34 +263,84 @@ void LevelSelectLayer::onDownload(CCObject* sender) void LevelSelectLayer::onBack(CCObject* sender) { - CCDirector* pDirector = CCDirector::sharedDirector(); - CCScene* scene = MenuLayer::scene(); - CCTransitionFade* fade = CCTransitionFade::create(0.5f, scene); - pDirector->replaceScene(fade); + CCDirector* pDirector = CCDirector::sharedDirector(); + CCScene* scene = MenuLayer::scene(); + CCTransitionFade* fade = CCTransitionFade::create(0.5f, scene); + pDirector->replaceScene(fade); } void LevelSelectLayer::onInfo(CCObject* sender) { - + int pageNum = m_scrollLayer->getRelativePageForNum(m_scrollLayer->getCurrentScreen()); + if (pageNum != m_scrollLayer->getTotalPages() - 1) + ((LevelPage*)m_scrollLayer->getPage(pageNum))->onInfo(nullptr); } void LevelSelectLayer::onPrev(CCObject* sender) { - m_scrollLayer->quickUpdate(); - - int currentPage = m_scrollLayer->getCurrentScreen(); - m_scrollLayer->moveToPage(currentPage - 1); + m_scrollLayer->quickUpdate(); + m_scrollLayer->moveToPage(m_scrollLayer->getCurrentScreen() - 1); } void LevelSelectLayer::onNext(CCObject* sender) { - m_scrollLayer->quickUpdate(); - - int currentPage = m_scrollLayer->getCurrentScreen(); - m_scrollLayer->moveToPage(currentPage + 1); + m_scrollLayer->quickUpdate(); + m_scrollLayer->moveToPage(m_scrollLayer->getCurrentScreen() + 1); +} + +cocos2d::ccColor3B LevelSelectLayer::colorForPage(int page) +{ + static const int colorIndices[] = { 5, 7, 8, 9, 10, 11, 1, 3, 4 }; + + if (page >= 9) + return this->colorForPage(page % 9); + + int colorIdx = colorIndices[page]; + return GameManager::sharedState()->colorForIdx(colorIdx); +} + +cocos2d::ccColor3B LevelSelectLayer::getColorValue(int pageA, int pageB, float t) +{ + float v = (t / 0.66667f) - 0.2f; + if (v < 0.0f) v = 0.0f; + else if (v > 1.0f) v = 1.0f; + + ccColor3B ca = colorForPage(pageA); + ccColor3B cb = colorForPage(pageB); + + ccColor3B out; + out.r = (GLubyte)((float)cb.r * v + (float)ca.r * (1.0f - v)); + out.g = (GLubyte)((float)cb.g * v + (float)ca.g * (1.0f - v)); + out.b = (GLubyte)((float)cb.b * v + (float)ca.b * (1.0f - v)); + return out; } void LevelSelectLayer::scrollLayerMoved(CCPoint pos) { - // todo + float i = -pos.x / m_winWidth; + while (i < 0.0f) + i += 16.0f; + + int pageFloor = (int)floorf(i); + float frac = i - (float)pageFloor; + + int curPage = pageFloor % 16; + int nextPage = (curPage == 15) ? 0 : curPage + 1; // if (v4%16 == 0xF) v6=0 + + ccColor3B bgColor = getColorValue(curPage, nextPage, frac); + + m_background->setColor(bgColor); + + ccColor3B gndColor; + gndColor.r = (GLubyte)((float)bgColor.r * 0.8f); + gndColor.g = (GLubyte)((float)bgColor.g * 0.8f); + gndColor.b = (GLubyte)((float)bgColor.b * 0.8f); + m_ground->setColor(gndColor); +} + +void LevelSelectLayer::update(float dt) { + if (m_scrollLayer && m_scrollLayer->getInternalLayer()) { + CCPoint pos = m_scrollLayer->getInternalLayer()->getPosition(); + this->scrollLayerMoved(pos); + } } \ No newline at end of file diff --git a/Classes/LevelSelectLayer.h b/Classes/LevelSelectLayer.h index 73189d0..38e75a2 100644 --- a/Classes/LevelSelectLayer.h +++ b/Classes/LevelSelectLayer.h @@ -1,28 +1,36 @@ #ifndef _LEVEL_SELECT_LAYER_H_ #define _LEVEL_SELECT_LAYER_H_ - #include "cocos2d.h" #include "BoomScrollLayer.h" -class LevelSelectLayer : public cocos2d::CCLayer +class LevelSelectLayer : public cocos2d::CCLayer, public BoomScrollLayerDelegate { public: - LevelSelectLayer(); - static cocos2d::CCScene* scene(int page); - static LevelSelectLayer* create(int page); - bool init(int page); - void onDownload(CCObject* sender); - void onBack(CCObject* sender); - void onInfo(CCObject* sender); - void onPrev(CCObject* sender); - void onNext(CCObject* sender); + LevelSelectLayer(); + static cocos2d::CCScene* scene(int page); + static LevelSelectLayer* create(int page); + bool init(int page); + void update(float dt); + + void onDownload(cocos2d::CCObject* sender); + void onBack(cocos2d::CCObject* sender); + void onInfo(cocos2d::CCObject* sender); + void onPrev(cocos2d::CCObject* sender); + void onNext(cocos2d::CCObject* sender); + + virtual void keyBackClicked(); virtual void scrollLayerMoved(cocos2d::CCPoint pos); -protected: + + // zyann addition + // void updateColorForPage(); + + cocos2d::ccColor3B colorForPage(int page); + cocos2d::ccColor3B getColorValue(int pageA, int pageB, float t); + BoomScrollLayerDelegate* m_bslDelegate; // 0x10c - float unk_0x110; // 0x110 - cocos2d::CCSprite* m_background; // 0x114 - cocos2d::CCSprite* m_ground; // 0x118 - BoomScrollLayer* m_scrollLayer; // 0x11c + float m_winWidth; // 0x110 (stored from winSize.width in init) + cocos2d::CCSprite* m_background; // 0x114 + cocos2d::CCSprite* m_ground; // 0x118 + BoomScrollLayer* m_scrollLayer; // 0x11c }; - #endif \ No newline at end of file diff --git a/Classes/LevelTools.cpp b/Classes/LevelTools.cpp index 9380f16..551c7c7 100644 --- a/Classes/LevelTools.cpp +++ b/Classes/LevelTools.cpp @@ -146,7 +146,7 @@ GJGameLevel* LevelTools::getLevel(int level) m_level->setAudioTrack(13); m_level->setDifficulty(5); m_level->setStars(7); - // m_level->setRequiredCoins(20); + m_level->setRequiredCoins(20); m_level->setDemon(true); break; // Electrodynamix diff --git a/Classes/LoadingLayer.cpp b/Classes/LoadingLayer.cpp index fac4a14..d5d0a2b 100644 --- a/Classes/LoadingLayer.cpp +++ b/Classes/LoadingLayer.cpp @@ -37,100 +37,102 @@ LoadingLayer::LoadingLayer() { } bool LoadingLayer::init() { + if (!CCLayer::init()) + return false; - if (!CCLayer::init()) - return false; - srand(time(0)); - GameSoundManager::sharedManager()->setup(); + GameSoundManager::sharedManager()->setup(); - GameManager* pGameManager = GameManager::sharedState(); + GameManager* pGameManager = GameManager::sharedState(); pGameManager->setup(); - + LocalLevelManager::sharedState()->setup(); - CCTextureCache* pTextureCache = CCTextureCache::sharedTextureCache(); - pTextureCache->addImage("GJ_LaunchSheet.png"); + CCTextureCache* pTextureCache = CCTextureCache::sharedTextureCache(); + pTextureCache->addImage("GJ_LaunchSheet.png"); - CCSpriteFrameCache* pSpriteFrameCache = CCSpriteFrameCache::sharedSpriteFrameCache(); - pSpriteFrameCache->addSpriteFramesWithFile("GJ_LaunchSheet.plist"); + CCSpriteFrameCache* pSpriteFrameCache = CCSpriteFrameCache::sharedSpriteFrameCache(); + pSpriteFrameCache->addSpriteFramesWithFile("GJ_LaunchSheet.plist"); - CCDirector* pDirector = CCDirector::sharedDirector(); - CCSize winSize = pDirector->getWinSize(); + CCDirector* pDirector = CCDirector::sharedDirector(); + CCSize winSize = pDirector->getWinSize(); CCSprite* bgSprite = CCSprite::create(pGameManager->getBGTexture(1)); - this->addChild(bgSprite); - - bgSprite->setPosition(ccp(winSize.width * 0.5f, winSize.height * 0.5f)); + this->addChild(bgSprite); + + bgSprite->setPosition(ccp(winSize.width * 0.5f, winSize.height * 0.5f)); bgSprite->setScale(pDirector->getScreenScaleFactorMax()); - bgSprite->setColor(ccc3(0, 102, 255)); + bgSprite->setColor(ccc3(0, 102, 255)); + + CCSprite* gjLogo = CCSprite::createWithSpriteFrameName("GJ_logo_001.png"); + this->addChild(gjLogo); + gjLogo->setPosition(ccp(winSize.width * 0.5f, winSize.height * 0.5f)); + + CCSprite* robTopLogo = CCSprite::createWithSpriteFrameName("RobTopLogoBig_001.png"); + this->addChild(robTopLogo); + robTopLogo->setPosition(gjLogo->getPosition() + ccp(0.0f, 80.0f)); + + m_loadStep = 0; + // *((_BYTE *)this + 269) = 1; // Internal flag often mapped to m_isReady or similar + + const char* randomLoadingText = LoadingLayer::getLoadingString(); + m_caption = CCLabelBMFont::create(randomLoadingText, "goldFont.fnt"); + this->addChild(m_caption); + m_caption->setPosition(ccp(winSize.width * 0.5f, winSize.height * 0.5f - 70.0f)); + m_caption->setScale(0.7f); + m_caption->setVisible(false); + + // it supposed to be 432.f (1138491392 = 432.f) + // and i just edited to 130.f because + // i dont know what i did in my TextArea decompilation + m_textArea = TextArea::create(randomLoadingText, 130.0f, 0, ccp(0.5f, 0.5f), "goldFont.fnt", 28.0f); + this->addChild(m_textArea); + m_textArea->setPosition(ccp(winSize.width * 0.5f, winSize.height * 0.5f - 100.0f)); + m_textArea->setScale(0.7f); + + if (300.0f < m_caption->getContentSize().width) + { + m_caption->setScale(300.0f / m_caption->getContentSize().width); + } + + float textScale = m_caption->getScale(); + if (textScale > 0.7f) + { + textScale = 0.7f; + } + m_caption->setScale(textScale); + + // Slider UI Setup + CCSprite* sliderGroove = CCSprite::create("slidergroove.png"); + this->addChild(sliderGroove, 3); + + m_sliderBar = CCSprite::create("sliderBar.png"); + m_sliderGrooveHeight = 8.0f; + m_sliderGrooveXPos = sliderGroove->getTextureRect().size.width - 4.0f; - CCSprite* gjLogo = CCSprite::createWithSpriteFrameName("GJ_logo_001.png"); - this->addChild(gjLogo); - gjLogo->setPosition(CCPoint(winSize.width * 0.5f, winSize.height * 0.5f)); + CCTexture2D* tex = m_sliderBar->getTexture(); + ccTexParams params = { GL_LINEAR, GL_LINEAR, GL_REPEAT, GL_REPEAT }; + tex->setTexParameters(¶ms); - CCSprite* robTopLogo = CCSprite::createWithSpriteFrameName("RobTopLogoBig_001.png"); - this->addChild(robTopLogo); - robTopLogo->setPosition(gjLogo->getPosition() + ccp(0.0f, 80.0f)); - - // Loading Text - m_caption = CCLabelBMFont::create(getLoadingString(), "goldFont.fnt"); - this->addChild(m_caption); - m_caption->setPosition(ccp(winSize.width * 0.5f, winSize.height * 0.5f - 70.0f)); - m_caption->setScale(0.7f); - m_caption->setVisible(false); - - m_textArea = TextArea::create(getLoadingString(), 440.0f, 0, ccp(0.5f, 0.5f), "goldFont.fnt", 28.0f); - this->addChild(m_textArea); - m_textArea->setPosition(CCPoint(winSize.width * 0.5f, winSize.height * 0.5f - 100.0f)); - m_textArea->setScale(0.7f); - - if (300.0f < m_caption->getContentSize().width) - { - m_caption->setScale(300.0f / m_caption->getContentSize().width); - } - - float textScale; - if (m_caption->getScale() <= 0.7f) - { - textScale = m_caption->getScale(); - } else - { - textScale = 0.7f; - } - - m_caption->setScale(textScale); + sliderGroove->addChild(m_sliderBar, -1); + m_sliderBar->setAnchorPoint(ccp(0.0f, 0.0f)); + m_sliderBar->setPosition(ccp(2.0f, 4.0f)); - CCSprite* sliderGroove = CCSprite::create("slidergroove.png"); - this->addChild(sliderGroove, 3); - - m_sliderBar = CCSprite::create("sliderBar.png"); - m_sliderGrooveHeight = 8.0f; - m_sliderGrooveXPos = sliderGroove->getTextureRect().size.width - 4.0f; - - CCTexture2D* tex = m_sliderBar->getTexture(); - ccTexParams params = { GL_LINEAR, GL_LINEAR, GL_REPEAT, GL_REPEAT }; - tex->setTexParameters(¶ms); - - sliderGroove->addChild(m_sliderBar, -1); - m_sliderBar->setAnchorPoint(CCPoint(0.0f, 0.0f)); - m_sliderBar->setPosition(CCPoint(2.0f, 4.0f)); - - sliderGroove->setPosition(CCPoint(m_caption->getPosition().x, m_textArea->getPosition().y + 40.0f)); - - this->updateProgress(0); - - CCActionManager* pActionManager = pDirector->getActionManager(); - CCDelayTime* delayTime = CCDelayTime::create(0.0f); - CCCallFunc* callFunc = CCCallFunc::create(this, callfunc_selector(LoadingLayer::loadAssets)); - CCSequence* sequence = CCSequence::create(delayTime, callFunc, NULL); - pActionManager->addAction(sequence, this, false); + sliderGroove->setPosition(ccp(m_caption->getPosition().x, m_textArea->getPosition().y + 40.0f)); + + this->updateProgress(0); + + CCActionManager* pActionManager = pDirector->getActionManager(); + CCDelayTime* delayTime = CCDelayTime::create(0.0f); + CCCallFunc* callFunc = CCCallFunc::create(this, callfunc_selector(LoadingLayer::loadAssets)); + CCSequence* sequence = CCSequence::create(delayTime, callFunc, NULL); + pActionManager->addAction(sequence, this, false); if (pGameManager->getGameCenterEnabled()) - PlatformToolbox::activateGameCenter(); + PlatformToolbox::activateGameCenter(); - return true; + return true; } // todo: hd textures @@ -215,7 +217,6 @@ void LoadingLayer::loadingFinished() { } const char* LoadingLayer::getLoadingString() { - switch (rand() % 10) { case 1: return "Listen to the music to help time your jumps"; case 2: return "Back for more are ya?"; @@ -228,5 +229,8 @@ const char* LoadingLayer::getLoadingString() { case 9: return "You can download all songs from the level select page!"; default: return "Unlock new icons and colors by completing achievements!"; } + + // use this for debug purposes + // return "Back for more are ya?"; } diff --git a/Classes/LocalLevelManager.cpp b/Classes/LocalLevelManager.cpp index 21690db..54a3f9a 100644 --- a/Classes/LocalLevelManager.cpp +++ b/Classes/LocalLevelManager.cpp @@ -23,15 +23,18 @@ bool LocalLevelManager::init() { m_saveFile = "CCLocalLevels.dat"; m_mainLevels = CCContentManager::sharedManager()->addDict("LevelData.plist", true); + m_mainLevels->retain(); return true; } std::string LocalLevelManager::getMainLevelString(int level) { - return m_temp; + level = 16; // temporary fix because c++ + return m_mainLevels->valueForKey(CCString::createWithFormat("%i", level)->getCString())->getCString(); } void LocalLevelManager::setup() { - + unk_0xec = true; + GManager::load(); } \ No newline at end of file diff --git a/Classes/LocalLevelManager.h b/Classes/LocalLevelManager.h index c9310f5..d5f5fd1 100644 --- a/Classes/LocalLevelManager.h +++ b/Classes/LocalLevelManager.h @@ -13,10 +13,8 @@ class LocalLevelManager : public GManager { void setup(); std::string getMainLevelString(int level); + cocos2d::CCDictionary* m_mainLevels; // 0xf0 CC_SYNTHESIZE_READONLY(cocos2d::CCArray*, m_localLevels, LocalLevels); // 0xf4 -protected: - cocos2d::CCDictionary* m_mainLevels; - std::string m_temp; }; #endif /* defined(__GeometryDash__LocalLevelManager__) */ diff --git a/Classes/MenuGameLayer.cpp b/Classes/MenuGameLayer.cpp index 04e21ef..744ec90 100644 --- a/Classes/MenuGameLayer.cpp +++ b/Classes/MenuGameLayer.cpp @@ -1,11 +1,13 @@ -// this class is pure spaghetti code but it somehow works +// decompiled by ItzZyann +// from GD 1.71 binary + #include "MenuGameLayer.h" #include "GameManager.h" #include "AppDelegate.h" #include USING_NS_CC; -MenuGameLayer::MenuGameLayer() +MenuGameLayer::MenuGameLayer() { m_playerObject = nullptr; m_bgSprite = nullptr; @@ -30,86 +32,90 @@ MenuGameLayer* MenuGameLayer::create() bool MenuGameLayer::init() { - if ( !CCLayer::init() ) - return false; - - - CCDirector* pDirector = CCDirector::sharedDirector(); - CCSize winSize = pDirector->getWinSize(); - - // ground - m_groundLayer = CCLayer::create(); - this->addChild(m_groundLayer, 3); - - GameManager* pGameManager = GameManager::sharedState(); - - m_bgSprite = CCSprite::create(pGameManager->getBGTexture(pGameManager->getLoadedBGIdx())); - ccTexParams texParams = {GL_LINEAR, GL_LINEAR, GL_REPEAT, GL_REPEAT}; - m_bgSprite->getTexture()->setTexParameters(&texParams); - this->addChild(m_bgSprite, -1); - m_bgSprite->setAnchorPoint(ccp(0, 0)); - m_bgSprite->setScale(pDirector->getScreenScaleFactorMax()); - m_bgSprite->setColor(ccc3(0, 102, 255)); - m_bgSprite->setTextureRect(CCRectMake(0, 0, winSize.width * 2, m_bgSprite->getContentSize().height)); - - m_groundSprite = CCSprite::create(pGameManager->getGTexture(1)); - m_groundSprite->getTexture()->setTexParameters(&texParams); - m_groundLayer->addChild(m_groundSprite, 2); - m_groundSprite->setAnchorPoint(ccp(0, 1)); - m_groundSprite->setColor(ccc3(0, 102, 255)); - m_groundSprite->setPosition(ccp(0.0f, 90.0f)); - m_groundSprite->setTextureRect(CCRectMake(0, 0, winSize.width * 2, m_groundSprite->getContentSize().height)); - - CCSprite* lineSprite = CCSprite::createWithSpriteFrameName("floorLine_001.png"); - m_groundLayer->addChild(lineSprite, 3); - lineSprite->setPosition(CCPoint(winSize.width * 0.5f, pDirector->getScreenBottom() + 90.0f)); + if (!CCLayer::init()) + return false; + + CCDirector* pDirector = CCDirector::sharedDirector(); + CCSize winSize = pDirector->getWinSize(); + + m_groundLayer = CCLayer::create(); + this->addChild(m_groundLayer, 3); + + GameManager* pGameManager = GameManager::sharedState(); + + m_bgSprite = CCSprite::create(pGameManager->getBGTexture(pGameManager->getLoadedBGIdx())); + ccTexParams texParams = { GL_LINEAR, GL_LINEAR, GL_REPEAT, GL_REPEAT }; + m_bgSprite->getTexture()->setTexParameters(&texParams); + this->addChild(m_bgSprite, -1); + m_bgSprite->setAnchorPoint(ccp(0.0f, 0.0f)); + m_bgSprite->setScale(pDirector->getScreenScaleFactorMax()); + m_bgSprite->setColor(ccc3(0, 102, 255)); + + CCRect bgTexRect = m_bgSprite->getTextureRect(); + m_bgSpeed = bgTexRect.size.width * m_bgSprite->getScale(); + float bgDoubleW = m_bgSpeed * 2.0f; + m_bgSprite->setTextureRect(CCRectMake(0, 0, bgDoubleW, bgTexRect.size.height)); + + // Initialize Ground + m_groundSprite = CCSprite::create(pGameManager->getGTexture(1)); + m_groundSprite->getTexture()->setTexParameters(&texParams); + m_groundLayer->addChild(m_groundSprite, 2); + m_groundSprite->setAnchorPoint(ccp(0.0f, 1.0f)); + m_groundSprite->setColor(ccc3(0, 102, 255)); + + CCRect gTexRect = m_groundSprite->getTextureRect(); + m_groundSpeed = gTexRect.size.width * pDirector->getScreenScaleFactorMax(); + m_groundSprite->setTextureRect(CCRectMake(0, 0, winSize.width * 2.0f, gTexRect.size.height)); + m_groundSprite->setPosition(ccp(0.0f, pDirector->getScreenBottom() + 90.0f)); + + CCSprite* lineSprite = CCSprite::createWithSpriteFrameName("floorLine_001.png"); + m_groundLayer->addChild(lineSprite, 3); + lineSprite->setPosition(ccp(winSize.width * 0.5f, pDirector->getScreenBottom() + 90.0f)); lineSprite->setBlendFunc({ GL_SRC_ALPHA, GL_ONE }); lineSprite->setOpacity(200); - CCSprite* leftShadow = CCSprite::createWithSpriteFrameName("groundSquareShadow_001.png"); - leftShadow->setAnchorPoint(ccp(0.0f, 1.0f)); - leftShadow->setPosition(ccp(pDirector->getScreenLeft() - 1.0f, 90.0f)); - m_groundLayer->addChild(leftShadow, 3); - - CCSprite* rightShadow = CCSprite::createWithSpriteFrameName("groundSquareShadow_001.png"); - rightShadow->setAnchorPoint(ccp(1.0f, 1.0f)); - rightShadow->setPosition(ccp(pDirector->getScreenRight() + 1.0f, 90.0f)); - m_groundLayer->addChild(rightShadow, 3); - rightShadow->setFlipX(true); + CCSprite* leftShadow = CCSprite::createWithSpriteFrameName("groundSquareShadow_001.png"); + leftShadow->setAnchorPoint(ccp(0.0f, 1.0f)); + leftShadow->setPosition(ccp(pDirector->getScreenLeft() - 1.0f, pDirector->getScreenBottom() + 90.0f)); + m_groundLayer->addChild(leftShadow, 3); - leftShadow->setOpacity(100); - rightShadow->setOpacity(100); + CCSprite* rightShadow = CCSprite::createWithSpriteFrameName("groundSquareShadow_001.png"); + rightShadow->setAnchorPoint(ccp(1.0f, 1.0f)); + rightShadow->setPosition(ccp(pDirector->getScreenRight() + 1.0f, pDirector->getScreenBottom() + 90.0f)); + m_groundLayer->addChild(rightShadow, 3); + rightShadow->setFlipX(true); + + leftShadow->setOpacity(100); + rightShadow->setOpacity(100); leftShadow->setScaleX(0.7f); rightShadow->setScaleX(0.7f); - + ccBlendFunc sBlendFunc = { GL_DST_COLOR, GL_ONE_MINUS_SRC_ALPHA }; leftShadow->setBlendFunc(sBlendFunc); - rightShadow->setBlendFunc(sBlendFunc); + rightShadow->setBlendFunc(sBlendFunc); -#pragma region Player - float cube = ceilf(CCRANDOM_0_1() * 37.0); - float ship = ceilf(CCRANDOM_0_1() * 13.0); + float cube = ceilf(CCRANDOM_0_1() * 37.0f); + float ship = ceilf(CCRANDOM_0_1() * 13.0f); int tmpStreak = pGameManager->getPlayerStreak(); pGameManager->setPlayerStreak(1); - m_playerObject = PlayerObject::create((cube + 1), (ship + 1), this); + m_playerObject = PlayerObject::create((int)(cube + 1.0f), (int)(ship + 1.0f), this); this->addChild(m_playerObject, 0); m_playerObject->setPosition(ccp(0.0f, 105.0f)); - ccColor3B firstColor = pGameManager->colorForIdx(CCRANDOM_0_1() * 18); + ccColor3B firstColor = pGameManager->colorForIdx((int)(CCRANDOM_0_1() * 18.0f)); m_playerObject->setColor(firstColor); - ccColor3B secondColor = pGameManager->colorForIdx(CCRANDOM_0_1() * 18); + ccColor3B secondColor = pGameManager->colorForIdx((int)(CCRANDOM_0_1() * 18.0f)); m_playerObject->setSecondColor(secondColor); pGameManager->setPlayerStreak(tmpStreak); -#pragma endregion - scheduleUpdate(); + scheduleUpdate(); this->schedule(schedule_selector(MenuGameLayer::tryJump), 0.25f); - - return true; + + return true; } void MenuGameLayer::update(float delta) @@ -130,58 +136,98 @@ void MenuGameLayer::update(float delta) if (playerScale == 1.0f) balancer = 0.0f; else - balancer = (playerScale * 30.0f) * 0.5f; + balancer = ((1.0f - playerScale) * 30.0f) * 0.5f; - float groundYPos = pDirector->getScreenBottom(); - if (m_playerObject->getPosition().y > (groundYPos + 90 + 15 - balancer)) { - m_playerObject->setPosition(m_playerObject->getPosition()); + float groundY = pDirector->getScreenBottom() + 90.0f + 15.0f - balancer; + if (m_playerObject->getPosition().y < groundY) + { + m_playerObject->setPosition(ccp(m_playerObject->getPosition().x, groundY)); m_playerObject->hitGround(false); } - if (winSize.width + 100 < m_playerObject->getPosition().x) { + if (m_playerObject->getPosition().x > winSize.width + 100.0f) + { m_playerObject->deactivateStreak(); - - m_playerObject->setPosition(ccp(-100 + (CCRANDOM_0_1() * 5) * 100, m_playerObject->getPosition().y)); - m_playerObject->setColor(GAME_MANAGER->colorForIdx(CCRANDOM_0_1() * 18)); - } - // unfinished chunk here + float newX = -100.0f - (CCRANDOM_0_1() * 5.0f * 100.0f); + m_playerObject->setPosition(ccp(newX, m_playerObject->getPosition().y)); - // i redid my math what do you guys think + m_playerObject->setColor(GameManager::sharedState()->colorForIdx((int)(CCRANDOM_0_1() * 18.0f))); + m_playerObject->setSecondColor(GameManager::sharedState()->colorForIdx((int)(CCRANDOM_0_1() * 18.0f))); - m_backgroundPosition = m_backgroundPosition + ccp(step * 5.77 * 0.9, 0.0f); - CCPoint newBGPos = m_backgroundPosition * 0.1; + m_playerObject->updatePlayerFrame((int)roundf(CCRANDOM_0_1() * 38.0f)); + m_playerObject->update(0); - int i; - for (i = newBGPos.x; i < -m_bgSpeed; i = i + m_bgSpeed) - newBGPos.x += m_bgSpeed; + if (CCRANDOM_0_1() < 0.2f && !m_playerObject->getFlyMode()) + { + m_playerObject->toggleFlyMode(true); + m_playerObject->updatePlayerShipFrame((int)roundf(CCRANDOM_0_1() * 14.0f)); + } + else if (CCRANDOM_0_1() < 0.4f && !m_playerObject->getRollMode()) + { + m_playerObject->toggleRollMode(true); + m_playerObject->updatePlayerRollFrame((int)roundf(CCRANDOM_0_1() * 7.0f)); + } + else if (CCRANDOM_0_1() < 0.6f && !m_playerObject->getBirdMode()) + { + m_playerObject->toggleBirdMode(true); + m_playerObject->updatePlayerBirdFrame((int)roundf(CCRANDOM_0_1() * 7.0f)); + } + else + { + m_playerObject->toggleFlyMode(false); + m_playerObject->toggleRollMode(false); + m_playerObject->toggleBirdMode(false); + } - m_bgSprite->setPosition(newBGPos); + m_playerObject->updateGlowColor(); + } - CCPoint newGPos = ccp(m_backgroundPosition.x, - pDirector->getScreenBottom() + 90.0); + m_backgroundPosition.x -= step * 5.193f; - for (i = newGPos.x; i < -m_groundSpeed; i = i + m_groundSpeed) - newGPos.x += m_groundSpeed; + float bgTileW = m_bgSprite->getTexture()->getContentSizeInPixels().width; + float bgX = fmodf(m_backgroundPosition.x * 0.1f, bgTileW); + if (bgX > 0) bgX -= bgTileW; + m_bgSprite->setPosition(ccp(bgX, 0.0f)); - m_groundSprite->setPosition(newGPos); + float gX = fmodf(m_backgroundPosition.x, winSize.width); + if (gX > 0) gX -= winSize.width; + m_groundSprite->setPosition(ccp(gX, pDirector->getScreenBottom() + 90.0f)); } void MenuGameLayer::tryJump(float dt) { - // unfinishedddddd + auto pDirector = CCDirector::sharedDirector(); + float jumpChance; - if (!m_playerObject->getFlyMode()) { - if (m_playerObject->getRollMode()) { - - } - - if (!m_playerObject->getBirdMode()) - { - - } + if (m_playerObject->getFlyMode()) + { + float shipCeiling = pDirector->getScreenBottom() + 90.0f + 15.0f + 100.0f; + bool belowCeiling = m_playerObject->getPosition().y < shipCeiling; + jumpChance = belowCeiling ? 0.3f : 0.0f; + } + else if (m_playerObject->getRollMode()) + { + jumpChance = -1.0f; + } + else if (m_playerObject->getBirdMode()) + { + float ufoCeiling = pDirector->getScreenBottom() + 90.0f + 15.0f + 200.0f; + bool belowCeiling = m_playerObject->getPosition().y < ufoCeiling; + jumpChance = belowCeiling ? 0.4f : 0.0f; + } + else + { + jumpChance = 0.2f; + } + if (CCRANDOM_0_1() <= jumpChance + && (m_playerObject->canJump() || m_playerObject->isFlying())) + { + m_playerObject->pushButton(PlayerButton::Jump); + } + else + { + m_playerObject->releaseButton(PlayerButton::Jump); } - - m_playerObject->pushButton(PlayerButton::Jump); } \ No newline at end of file diff --git a/Classes/MenuGameLayer.h b/Classes/MenuGameLayer.h index 1262bc5..3218fc9 100644 --- a/Classes/MenuGameLayer.h +++ b/Classes/MenuGameLayer.h @@ -1,3 +1,6 @@ +// decompiled by ItzZyann +// from GD 1.71 binary + #ifndef _MENU_GAME_LAYER_H #define _MENU_GAME_LAYER_H diff --git a/Classes/MenuLayer.cpp b/Classes/MenuLayer.cpp index 941fc03..9010852 100644 --- a/Classes/MenuLayer.cpp +++ b/Classes/MenuLayer.cpp @@ -43,7 +43,7 @@ void MenuLayer::onMoreGames(CCObject* sender) GameManager::sharedState()->reportAchievementWithID("geometry.ach.moreGames", 100, false); GJMoreGamesLayer* moreGamesLayer = GJMoreGamesLayer::create(); this->addChild(moreGamesLayer, 100); - moreGamesLayer->showLayer(false); // wow this is broken + moreGamesLayer->showLayer(false); // it aint broken no more return; } @@ -97,9 +97,10 @@ void MenuLayer::onOptions(CCObject* sender) layer->showLayer(false); } +#include "FLAlertLayer.h" void MenuLayer::onStats(CCObject* sender) { - + FLAlertLayer::create(nullptr, "Test Alert", "Hello world!", "OK", nullptr, 330)->show(); } void MenuLayer::onRobTop(CCObject* sender) @@ -168,6 +169,7 @@ void MenuLayer::willClose() pGameManager->setMainMenuActive(false); } +bool m_firstLoaded = false; bool MenuLayer::init() { if (!CCLayer::init()) return false; @@ -176,7 +178,10 @@ bool MenuLayer::init() { CCSize winSize = pDirector->getWinSize(); GameManager* pGameManager = GameManager::sharedState(); - pGameManager->fadeInMusic("menuLoop.mp3"); + if (!m_firstLoaded) { + pGameManager->fadeInMusic("menuLoop.mp3"); + m_firstLoaded = true; + } MenuGameLayer* MGL = MenuGameLayer::create(); this->addChild(MGL); diff --git a/Classes/MultilineBitmapFont.cpp b/Classes/MultilineBitmapFont.cpp index a9f5fdc..3cd060a 100644 --- a/Classes/MultilineBitmapFont.cpp +++ b/Classes/MultilineBitmapFont.cpp @@ -1,2 +1,368 @@ +// decompiled by ItzZyann +// from GD 1.71 binary + #include "MultilineBitmapFont.h" -USING_NS_CC; \ No newline at end of file +#include "ColoredSection.h" + +USING_NS_CC; + +MultilineBitmapFont* MultilineBitmapFont::createWithFont( + const char* fontFile, + const char* text, + float scale, + float width, + cocos2d::CCPoint* align, + float lineSpace) +{ + MultilineBitmapFont* pRet = new MultilineBitmapFont(); + + if (pRet && pRet->initWithFont(fontFile, text, scale, width, align, lineSpace)) + { + pRet->autorelease(); + return pRet; + } + + delete pRet; + return NULL; +} + +bool MultilineBitmapFont::initWithFont( + const char* fontFile, + const char* text, + float scale, + float width, + cocos2d::CCPoint* align, + float lineSpace) +{ + if (!cocos2d::CCSprite::init()) + { + return false; + } + + float scaleFactor = cocos2d::CCDirector::sharedDirector()->getContentScaleFactor(); + float maxWidth = width * scaleFactor; + + m_lines = cocos2d::CCArray::create(); + m_lines->retain(); + + m_characters = cocos2d::CCArray::create(); + m_characters->retain(); + + m_unkArray = cocos2d::CCArray::create(); + m_unkArray->retain(); + + BitmapFontCache* fontCache = BitmapFontCache::sharedFontCache(); + FontObject* fontObject = fontCache->fontWithConfigFile(fontFile, scale); + + for (int i = 0; i < 300; ++i) + { + this->m_fontWidths[i] = fontObject->getFontWidth(i); + } + + std::string coloredText; + this->readColorInfo(&coloredText, this, text); + + int currentYOffset = 0; + int totalProcessedChars = 0; + int lineCount = 0; + + while (coloredText.length() > 0) + { + std::string lineStr; + this->stringWithMaxWidth(&lineStr, this, coloredText, maxWidth, scale); + + cocos2d::CCLabelBMFont* labelLine = cocos2d::CCLabelBMFont::create(lineStr.c_str(), fontFile); + labelLine->setPosition(cocos2d::CCPointMake(0.0f, (float)currentYOffset)); + labelLine->setScale(scale); + + float currentHeight = m_sizeHeight; + float labelHeight = labelLine->getContentSize().height; + if (currentHeight < (labelHeight * labelLine->getScaleY())) + { + m_sizeHeight = labelHeight * labelLine->getScaleY(); + } + + labelLine->setAnchorPoint(*align); + + if (labelLine->getAnchorPoint().x == 0.5f) + { + labelLine->setAnchorPoint(cocos2d::CCPointMake(0.0f, labelLine->getAnchorPoint().y)); + float posX = roundf(labelLine->getPosition().x - (labelLine->getContentSize().width * 0.5f)); + labelLine->setPosition(cocos2d::CCPointMake(posX, labelLine->getPosition().y)); + } + + if (labelLine->getAnchorPoint().y == 0.5f) + { + labelLine->setAnchorPoint(cocos2d::CCPointMake(labelLine->getAnchorPoint().x, 0.0f)); + float posY = roundf(labelLine->getPosition().y - (labelLine->getContentSize().height * 0.5f)); + labelLine->setPosition(cocos2d::CCPointMake(labelLine->getPosition().x, posY)); + } + + int lineStrLen = lineStr.length(); + int endCharIdx = totalProcessedChars + lineStrLen; + + // FIX: cast to ColoredSection* (not CustomColoredSection*) so getStartIndex/ + // getEndIndex/getColor read the actual m_startPos/m_endPos/m_col fields that + // ColoredSection::init() set. CustomColoredSection had its own shadow fields + // that were never initialized, so colors were always garbage. + // Also fixed loop to iterate all blocks (not just index 0) and corrected + // the start index calculation to not break on the first line. + int blockIdx = 0; + while (blockIdx < (int)m_lines->count()) + { + ColoredSection* colorBlock = static_cast(m_lines->objectAtIndex(blockIdx)); + + if (colorBlock->getEndIndex() < totalProcessedChars) + { + m_lines->removeObjectAtIndex(blockIdx, true); + continue; + } + + if (colorBlock->getStartIndex() >= endCharIdx) + { + break; + } + + int blockStart = colorBlock->getStartIndex(); + int blockEnd = colorBlock->getEndIndex(); + + int applyStart = blockStart - totalProcessedChars; + int applyEnd = (blockEnd < endCharIdx ? blockEnd : endCharIdx - 1) - totalProcessedChars; + + for (int ci = applyStart; ci <= applyEnd; ++ci) + { + cocos2d::CCSprite* fontChar = static_cast(labelLine->getChildByTag(ci)); + if (fontChar) + { + fontChar->setColor(colorBlock->getColor()); + } + } + + if (blockEnd < endCharIdx) + { + m_lines->removeObjectAtIndex(blockIdx, true); + } + else + { + colorBlock->setStartIndex(endCharIdx); + ++blockIdx; + } + } + + this->addChild(labelLine); + + for (unsigned int j = 0; j < labelLine->getChildren()->count(); ++j) + { + cocos2d::CCObject* childChar = labelLine->getChildren()->objectAtIndex(j); + m_unkArray->addObject(childChar); + } + + coloredText.erase(0, lineStrLen); + totalProcessedChars += lineStrLen; + ++lineCount; + currentYOffset -= lineSpace; + } + + m_lines->release(); + m_characters->release(); + + float targetX = 0.0f; + int computedHeight = (lineCount - 1) * lineSpace; + m_textHeight = (float)computedHeight; + + int computedWidth = (int)maxWidth; + m_textWidth = (float)computedWidth; + + if (align->x != 0.0f) + { + if (align->x != 1.0f) + { + computedWidth /= 2; + } + targetX = (float)-computedWidth; + } + + m_textPos = cocos2d::CCPointMake(-targetX, (float)computedHeight); + + return true; +} + +void MultilineBitmapFont::readColorInfo(std::string* outStr, MultilineBitmapFont* font, std::string text) +{ + while (true) + { + size_t startTagPos = text.find(""); + text.replace(endTagPos, 4, ""); + + cocos2d::ccColor3B color = cocos2d::ccc3(255, 0, 0); + + switch (colorChar) + { + case 'b': + color = cocos2d::ccc3(74, 82, 225); + break; + case 'g': + color = cocos2d::ccc3(64, 227, 72); + break; + case 'l': + color = cocos2d::ccc3(96, 172, 239); + break; + case 'y': + color = cocos2d::ccc3(255, 255, 0); + break; + case 'o': + color = cocos2d::ccc3(255, 165, 75); + break; + case 'r': + color = cocos2d::ccc3(255, 90, 90); + break; + case 'p': + color = cocos2d::ccc3(255, 0, 255); + break; + default: + color = cocos2d::ccc3(255, 0, 0); + break; + } + + ColoredSection* block = ColoredSection::create(color, startTagPos, endTagPos - 1); + font->m_lines->addObject(block); + } + + *outStr = text; +} + +void MultilineBitmapFont::stringWithMaxWidth(std::string* outStr, MultilineBitmapFont* font, std::string text, float maxWidth, float scale) +{ + size_t length = text.length(); + std::string lineBuffer = ""; + + int currentLineWidth = 0; + int lastSpaceWidth = 0; + int index = 0; + unsigned int spaceCharWidth = 0; + + while (index < length && (float)currentLineWidth < (maxWidth * 2.0f)) + { + char currentChar = text[index]; + unsigned int charWidth = font->m_fontWidths[static_cast(currentChar)]; + std::string singleCharStr(1, currentChar); + + if (singleCharStr == "\n") + { + lineBuffer += " "; + currentLineWidth += static_cast(scale * static_cast(charWidth)); + index = 1000; + break; + } + + if (currentChar == ' ') + { + lastSpaceWidth = currentLineWidth; + spaceCharWidth = static_cast(scale * static_cast(font->m_fontWidths[32])); + } + + lineBuffer += singleCharStr; + ++index; + currentLineWidth += static_cast(scale * static_cast(charWidth)); + } + + int halfSpacePos = lastSpaceWidth / 2; + if (!font->m_fadeInFinished && (float)currentLineWidth < (maxWidth * 2.0f)) + { + font->m_order = currentLineWidth / 2 - spaceCharWidth; + } + font->m_fadeInFinished = true; + + if (halfSpacePos > font->m_order) + { + font->m_order = halfSpacePos; + } + + if (length > index) + { + int backtrackCount = 0; + int backtrackIdx = index; + + while (backtrackIdx > 0) + { + if (lineBuffer[backtrackIdx - 1] == ' ') + { + break; + } + ++backtrackCount; + --backtrackIdx; + if (backtrackCount > index) + { + break; + } + } + + if (index - backtrackCount > 1) + { + lineBuffer = lineBuffer.substr(0, lineBuffer.length() - backtrackCount); + } + } + + cocos2d::CCString* ccStr = cocos2d::CCString::create(lineBuffer); + *outStr = ccStr->getCString(); +} + +MultilineBitmapFont::MultilineBitmapFont() +{ + cocos2d::CCSprite::CCSprite(); + + m_lines = NULL; + m_characters = NULL; + m_unkArray = NULL; + m_order = 0; + m_fadeInFinished = false; + m_textHeight = 0.0f; + m_textWidth = 0.0f; + + m_textPos = cocos2d::CCPointMake(0.0f, 0.0f); + m_sizeHeight = 0.0f; +} + +MultilineBitmapFont::~MultilineBitmapFont() +{ + /* + if (m_unkArray) + { + m_unkArray->release(); + } + cocos2d::CCSprite::~CCSprite(); + */ +} + +BitmapFontCache* BitmapFontCache::sharedFontCache() +{ + static BitmapFontCache* s_sharedFontCache = nullptr; + if (!s_sharedFontCache) { + s_sharedFontCache = new BitmapFontCache(); + } + return s_sharedFontCache; +} + +FontObject* BitmapFontCache::fontWithConfigFile(const char* fontFile, float scale) +{ + return reinterpret_cast(cocos2d::CCBMFontConfiguration::create(fontFile)); +} + +float FontObject::getFontWidth(int charId) +{ + cocos2d::CCBMFontConfiguration* config = reinterpret_cast(this); + if (!config) return 0.0f; + + if (!config->m_pFontDefDictionary) return 15.0f; + + return 15.0f; +} \ No newline at end of file diff --git a/Classes/MultilineBitmapFont.h b/Classes/MultilineBitmapFont.h index 9718544..aa510e6 100644 --- a/Classes/MultilineBitmapFont.h +++ b/Classes/MultilineBitmapFont.h @@ -1,21 +1,48 @@ -#ifndef __GeometryDash__MultilineBitmapFont__ -#define __GeometryDash__MultilineBitmapFont__ +// decompiled by ItzZyann +// from GD 1.71 binary + +#ifndef __MULTILINEBITMAPFONT_H__ +#define __MULTILINEBITMAPFONT_H__ #include "cocos2d.h" +#include "ColoredSection.h" +#include + +class FontObject { +public: + float getFontWidth(int charId); +}; + +class BitmapFontCache { +public: + static BitmapFontCache* sharedFontCache(); + FontObject* fontWithConfigFile(const char* fontFile, float scale); +}; class MultilineBitmapFont : public cocos2d::CCSprite { public: - MultilineBitmapFont* createWithFont(char const*, std::string text, float, float, cocos2d::CCPoint position, int); - bool initWithFont(char const*, std::string, float, float, cocos2d::CCPoint, int); + MultilineBitmapFont(); + virtual ~MultilineBitmapFont(); + + static MultilineBitmapFont* createWithFont(const char* fontFile, const char* text, float scale, float width, cocos2d::CCPoint* align, float lineSpace); + bool initWithFont(const char* fontFile, const char* text, float scale, float width, cocos2d::CCPoint* align, float lineSpace); + + void readColorInfo(std::string* outStr, MultilineBitmapFont* font, std::string text); + void stringWithMaxWidth(std::string* outStr, MultilineBitmapFont* font, std::string text, float maxWidth, float scale); + + cocos2d::CCArray* m_lines; // 0x668 + cocos2d::CCArray* m_characters; // 0x66C + cocos2d::CCArray* m_unkArray; // 0x670 + + float m_fontWidths[300]; // 0x1B8 - cocos2d::CCArray* field_0x668; // 0x668 - cocos2d::CCArray* field_0x66c; // 0x66c - cocos2d::CCArray* field_0x670; // 0x670 + int m_order; // 0x674 + bool m_fadeInFinished; // 0x678 - CC_SYNTHESIZE_READONLY(float, m_textHeight, TextHeight); // 0x680 - CC_SYNTHESIZE_READONLY(float, m_textWidth, TextWidth); // 0x684 - CC_SYNTHESIZE_READONLY(cocos2d::CCPoint, m_textPos, TextPos); // 0x688 - CC_SYNTHESIZE_READONLY(float, m_sizeHeight, SizeHeight); // 0x690 + float m_textHeight; // 0x680 + float m_textWidth; // 0x684 + cocos2d::CCPoint m_textPos; // 0x688 + float m_sizeHeight; // 0x690 }; -#endif \ No newline at end of file +#endif // __MULTILINEBITMAPFONT_H__ \ No newline at end of file diff --git a/Classes/PauseLayer.cpp b/Classes/PauseLayer.cpp index ea56e4d..8d6effd 100644 --- a/Classes/PauseLayer.cpp +++ b/Classes/PauseLayer.cpp @@ -1,9 +1,14 @@ +// decompiled by ItzZyann +// from GD 1.71 binary + #include "PauseLayer.h" #include "GameManager.h" #include "RT_COCOS/CCMenuItemSpriteExtra.h" +#include "RT_COCOS/CCMenuItemToggler.h" #include "GameSoundManager.h" #include "LevelEditorLayer.h" #include "TutorialLayer.h" +#include "AdToolbox.h" #include "cocos-ext.h" #include "SimpleAudioEngine.h" @@ -17,6 +22,7 @@ void PauseLayer::customSetup() CCSize winSize = pDirector->getWinSize(); CCScale9Sprite* background = CCScale9Sprite::create("square04_001.png", CCRect(0, 0, 80, 80)); + background->setColor({ 0, 0, 0 }); background->setOpacity(175); float bgWidth = (pDirector->getScreenRight() - 20.0f) - pDirector->getScreenLeft(); @@ -24,14 +30,15 @@ void PauseLayer::customSetup() background->setContentSize(CCSize(bgWidth, bgHeight)); background->setPosition(ccp(winSize.width * 0.5f, winSize.height * 0.5f)); - background->setColor(ccBLACK); - this->addChild(background); + this->addChild(background, -1); - std::string levelName = PLAY_LAYER->getLevel()->getLevelName(); + std::string levelName = PLAY_LAYER->getLevel()->getLevelName(); CCLabelBMFont* levelLabel = CCLabelBMFont::create(levelName.c_str(), "bigFont.fnt"); - levelLabel->setPosition(ccp(winSize.width * 0.5f, bgHeight - 20.0f)); + levelLabel->setPosition(ccp(winSize.width * 0.5f, (winSize.height * 0.5f + bgHeight * 0.5f) - 20.0f)); this->addChild(levelLabel); + setupProgressBars(); + CCMenu* mainButtonMenu = CCMenu::create(); this->addChild(mainButtonMenu); @@ -46,14 +53,14 @@ void PauseLayer::customSetup() CCSprite* practiceBtn; SEL_MenuHandler practiceCallback; - if (!PLAY_LAYER->getPracticeMode()) { - practiceBtn = CCSprite::createWithSpriteFrameName("GJ_practiceBtn_001.png"); - practiceCallback = menu_selector(PauseLayer::onPracticeMode); - } - else { + if (PLAY_LAYER->getPracticeMode()) { practiceBtn = CCSprite::createWithSpriteFrameName("GJ_normalBtn_001.png"); practiceCallback = menu_selector(PauseLayer::onNormalMode); } + else { + practiceBtn = CCSprite::createWithSpriteFrameName("GJ_practiceBtn_001.png"); + practiceCallback = menu_selector(PauseLayer::onPracticeMode); + } CCMenuItemSpriteExtra* practiceExtra = CCMenuItemSpriteExtra::create(practiceBtn, NULL, this, practiceCallback); mainButtonMenu->addChild(practiceExtra); @@ -70,8 +77,6 @@ void PauseLayer::customSetup() mainButtonMenu->addChild(restartExtra); } - mainButtonMenu->setPosition(CCPoint(winSize.width * 0.5f, winSize.height * 0.5f)); - float spacing; if (PLAY_LAYER->getLevel()->getLevelType() == GJLevelType::LocalLevel) spacing = 15.0f; @@ -80,12 +85,150 @@ void PauseLayer::customSetup() mainButtonMenu->alignItemsHorizontallyWithPadding(spacing); + CCPoint menuPos = mainButtonMenu->getPosition(); + mainButtonMenu->setPosition(ccp(menuPos.x, winSize.height * 0.5f - 30.0f)); + + // practice mode banner + if (!GameManager::sharedState()->getClickedPractice()) { + if (PLAY_LAYER->getLevel()->getLevelType() != GJLevelType::LocalLevel) { + CCSprite* practiceTxt = CCSprite::createWithSpriteFrameName("GJ_practiceTxt_001.png"); + this->addChild(practiceTxt); + practiceTxt->setPosition(ccp(winSize.width * 0.5f - 165.0f, winSize.height * 0.5f - 12.0f)); + } + } + + CCMenu* toggleMenu = CCMenu::create(); + this->addChild(toggleMenu); + + CCDirector* dir = CCDirector::sharedDirector(); + float screenBottom = dir->getScreenBottom(); + float centerX = winSize.width * 0.5f; + + GameManager* gm = GameManager::sharedState(); + + createToggleButton("Music", menu_selector(PauseLayer::onMusic), false, toggleMenu, ccp(centerX - 185.0f, screenBottom + 65.0f)); + createToggleButton("SFX", menu_selector(PauseLayer::onFX), false, toggleMenu, ccp(centerX - 22.0f, screenBottom + 65.0f)); + createToggleButton("Auto-Retry", menu_selector(PauseLayer::onAutoRetry), false, toggleMenu, ccp(centerX + 84.0f, screenBottom + 65.0f)); + createToggleButton("Auto-Checkpoints", menu_selector(PauseLayer::onAutoCheckpoints), false, toggleMenu, ccp(centerX - 185.0f, screenBottom + 30.0f)); + createToggleButton("Progress Bar", menu_selector(PauseLayer::onProgressBar), true, toggleMenu, ccp(centerX - 22.0f, screenBottom + 30.0f)); + + /* + createToggleButton("Music", menu_selector(PauseLayer::onMusic), !gm->getBGMEnabled(), toggleMenu, ccp(centerX - 185.0f, screenBottom + 65.0f)); + createToggleButton("SFX", menu_selector(PauseLayer::onFX), !gm->getEffectsEnabled(), toggleMenu, ccp(centerX - 22.0f, screenBottom + 65.0f)); + createToggleButton("Auto-Retry", menu_selector(PauseLayer::onAutoRetry), !gm->getAutoRetry(), toggleMenu, ccp(centerX + 84.0f, screenBottom + 65.0f)); + createToggleButton("Auto-Checkpoints", menu_selector(PauseLayer::onAutoCheckpoints), !gm->getAutoCheckpoints(), toggleMenu, ccp(centerX - 185.0f, screenBottom + 30.0f)); + createToggleButton("Progress Bar", menu_selector(PauseLayer::onProgressBar), !gm->getShowProgressBar(), toggleMenu, ccp(centerX - 22.0f, screenBottom + 30.0f)); */ +} + +void PauseLayer::createToggleButton(std::string text, SEL_MenuHandler callback, bool toggled, CCMenu* menu, CCPoint position) +{ + CCSprite* onSprite = CCSprite::createWithSpriteFrameName("GJ_checkOn_001.png"); + CCSprite* offSprite = CCSprite::createWithSpriteFrameName("GJ_checkOff_001.png"); + + onSprite->setScale(0.8f); + offSprite->setScale(0.8f); + + CCMenuItemToggler* toggler = CCMenuItemToggler::create(onSprite, offSprite, this, callback); + toggler->toggle(toggled); + + menu->addChild(toggler); + toggler->setPosition(menu->convertToNodeSpace(position)); + toggler->setSizeMult(1.5f); + + CCLabelBMFont* label = CCLabelBMFont::create(text.c_str(), "bigFont.fnt"); + this->addChild(label); + + label->setAnchorPoint(ccp(0.0f, 0.5f)); + + float checkHalfW = onSprite->getContentSize().width * 0.5f; + label->setPosition(ccpAdd(position, ccp(checkHalfW * 0.8f + 6.0f, 0.0f))); + + if (label->getContentSize().width > 110.0f) + label->setScale(110.0f / label->getContentSize().width); + + if (label->getScale() > 0.5f) + label->setScale(0.5f); +} + +void PauseLayer::setupProgressBars() +{ + GameManager* gm = GameManager::sharedState(); + CCDirector* pDirector = CCDirector::sharedDirector(); + CCSize winSize = pDirector->getWinSize(); + + CCSprite* normalBarBG = CCSprite::create("GJ_progressBar_001.png"); + normalBarBG->setColor(ccBLACK); + normalBarBG->setOpacity(125); + normalBarBG->setScale(1.0f); + this->addChild(normalBarBG, 3); + normalBarBG->setPosition(ccp(winSize.width * 0.5f, winSize.height * 0.5f + 80.0f)); + + CCSprite* normalBarFill = CCSprite::create("GJ_progressBar_001.png"); + normalBarFill->setColor(ccGREEN); // 0x64FF00 -> close to lime; actual RGB from floats: ~(0x64, 0xFF, 0x76) green tint + normalBarFill->setAnchorPoint(ccp(0.0f, 0.5f)); + + // fill width is clipped per normal-mode percent + // positioned slightly inset from left edge + float fillInset = normalBarBG->getContentSize().width - (normalBarBG->getContentSize().width * 0.992f); + normalBarFill->setPosition(ccp(fillInset * 0.5f, normalBarBG->getContentSize().height * 0.5f)); + normalBarBG->addChild(normalBarFill, 1); + + // int normalPercent = level>getNormalPercent(); // vtable +620 + int normalPercent = 0; + float normalBarW = normalBarFill->getContentSize().width; + float normalFillW = normalBarW * (normalPercent / 100.0f); + if (normalFillW < normalBarW) + normalFillW = normalBarW * (normalPercent / 100.0f); + normalBarFill->setTextureRect(CCRect(0, 0, normalFillW, normalBarFill->getContentSize().height)); + + CCSprite* practiceBarBG = CCSprite::create("GJ_progressBar_001.png"); + practiceBarBG->setColor(ccBLACK); + practiceBarBG->setOpacity(125); + practiceBarBG->setScale(1.0f); + this->addChild(practiceBarBG, 3); + practiceBarBG->setPosition(ccpAdd(normalBarBG->getPosition(), ccp(0.0f, -50.0f))); + + CCSprite* practiceBarFill = CCSprite::create("GJ_progressBar_001.png"); + practiceBarFill->setColor(ccWHITE); // color {0, -1, -1} = {0x00, 0xFF, 0xFF} -> cyan + practiceBarFill->setAnchorPoint(ccp(0.0f, 0.5f)); + practiceBarFill->setPosition(normalBarFill->getPosition()); // same local offset + practiceBarBG->addChild(practiceBarFill, 1); + + // int practicePercent = level->getPracticePercent(); // vtable +628 + int practicePercent = 0; + float practiceBarW = practiceBarFill->getContentSize().width; + float practiceFillW = practiceBarW * (practicePercent / 100.0f); + if (practiceFillW < practiceBarW) + practiceFillW = practiceBarW * (practicePercent / 100.0f); + practiceBarFill->setTextureRect(CCRect(0, 0, practiceFillW, practiceBarFill->getContentSize().height)); + + CCLabelBMFont* normalPctLabel = CCLabelBMFont::create( + CCString::createWithFormat("%i%%", normalPercent)->getCString(), "bigFont.fnt"); + this->addChild(normalPctLabel, 4); + normalPctLabel->setPosition(normalBarBG->getPosition()); + normalPctLabel->setScale(0.5f); + + CCLabelBMFont* practicePctLabel = CCLabelBMFont::create( + CCString::createWithFormat("%i%%", practicePercent)->getCString(), "bigFont.fnt"); + this->addChild(practicePctLabel, 4); + practicePctLabel->setPosition(practiceBarBG->getPosition()); + practicePctLabel->setScale(0.5f); + + CCLabelBMFont* normalModeLabel = CCLabelBMFont::create("Normal Mode", "bigFont.fnt"); + this->addChild(normalModeLabel, 4); + normalModeLabel->setPosition(ccpAdd(normalBarBG->getPosition(), ccp(0.0f, 20.0f))); + normalModeLabel->setScale(0.5f); + + CCLabelBMFont* practiceModeLabel = CCLabelBMFont::create("Practice Mode", "bigFont.fnt"); + this->addChild(practiceModeLabel, 4); + practiceModeLabel->setPosition(ccpAdd(practiceBarBG->getPosition(), ccp(0.0f, 20.0f))); + practiceModeLabel->setScale(0.5f); } void PauseLayer::onResume(CCObject* sender) { PLAY_LAYER->resume(); - CCNode::removeMeAndCleanup(); + CCNode::removeMeAndCleanup(); } void PauseLayer::onQuit(CCObject* sender) @@ -108,14 +251,10 @@ void PauseLayer::onEdit(CCObject* sender) CCDirector::sharedDirector()->replaceScene(CCTransitionFade::create(0.5f, scene)); } -void PauseLayer::onFX(CCObject* sender) -{ - GameManager::sharedState()->toggleFX(); -} - -void PauseLayer::onMusic(CCObject* sender) +void PauseLayer::onRestart(CCObject* sender) { - GameManager::sharedState()->toggleMusic(); + PLAY_LAYER->resumeAndRestart(); + CCNode::removeMeAndCleanup(); } void PauseLayer::onNormalMode(CCObject* sender) @@ -131,13 +270,55 @@ void PauseLayer::onPracticeMode(CCObject* sender) this->onResume(nullptr); } -void PauseLayer::onRestart(CCObject* sender) +void PauseLayer::onAutoRetry(CCObject* sender) { - PLAY_LAYER->resumeAndRestart(); - CCNode::removeMeAndCleanup(); + GameManager* gm = GameManager::sharedState(); + // gm->setAutoRetry(!gm->getAutoRetry()); +} + +void PauseLayer::onAutoCheckpoints(CCObject* sender) +{ + GameManager* gm = GameManager::sharedState(); + gm->setAutoCheckpoints(!gm->getAutoCheckpoints()); +} + +void PauseLayer::onProgressBar(CCObject* sender) +{ + GameManager* gm = GameManager::sharedState(); + gm->setShowProgressBar(!gm->getShowProgressBar()); + PLAY_LAYER->toggleProgressbar(); +} + +void PauseLayer::onRecordReplays(CCObject* sender) +{ + GameManager* gm = GameManager::sharedState(); + // gm->setRecordReplays(!gm->getRecordReplays()); + // reads back the value after setting — likely a valueChanged notify side effect + // gm->getRecordReplays(); +} + +void PauseLayer::onFX(CCObject* sender) +{ + GameManager::sharedState()->toggleFX(); +} + +void PauseLayer::onMusic(CCObject* sender) +{ + GameManager::sharedState()->toggleMusic(); } void PauseLayer::onHelp(CCObject* sender) { TutorialLayer::create()->show(); +} + +void PauseLayer::tryShowBanner(float dt) +{ + // AdToolbox::enableBanner(this); + this->unschedule(schedule_selector(PauseLayer::tryShowBanner)); +} + +void PauseLayer::keyBackClicked() +{ + this->onQuit(nullptr); } \ No newline at end of file diff --git a/Classes/PauseLayer.h b/Classes/PauseLayer.h index f415a03..3b951a7 100644 --- a/Classes/PauseLayer.h +++ b/Classes/PauseLayer.h @@ -1,3 +1,6 @@ +// decompiled by ItzZyann +// from GD 1.71 binary + #ifndef __GeometryDash__PauseLayer__ #define __GeometryDash__PauseLayer__ @@ -7,19 +10,28 @@ class PauseLayer : public CCBlockLayer { public: CREATE_FUNC(PauseLayer); - virtual void customSetup(); - void onAutoCheckpoints(cocos2d::CCObject* sender); - void onAutoRetry(cocos2d::CCObject* sender); - void onEdit(cocos2d::CCObject* sender); - void onFX(cocos2d::CCObject* sender); - void onHelp(cocos2d::CCObject* sender); - void onMusic(cocos2d::CCObject* sender); - void onNormalMode(cocos2d::CCObject* sender); - void onPracticeMode(cocos2d::CCObject* sender); - void onQuit(cocos2d::CCObject* sender); - void onRecordReplays(cocos2d::CCObject* sender); - void onRestart(cocos2d::CCObject* sender); - void onResume(cocos2d::CCObject* sender); + + virtual void customSetup(); + // virtual ~PauseLayer(); + + void onAutoCheckpoints(cocos2d::CCObject* sender); + void onAutoRetry(cocos2d::CCObject* sender); + void onProgressBar(cocos2d::CCObject* sender); + void onEdit(cocos2d::CCObject* sender); + void onFX(cocos2d::CCObject* sender); + void onHelp(cocos2d::CCObject* sender); + void onMusic(cocos2d::CCObject* sender); + void onNormalMode(cocos2d::CCObject* sender); + void onPracticeMode(cocos2d::CCObject* sender); + void onQuit(cocos2d::CCObject* sender); + void onRecordReplays(cocos2d::CCObject* sender); + void onRestart(cocos2d::CCObject* sender); + void onResume(cocos2d::CCObject* sender); + virtual void keyBackClicked(); + + void tryShowBanner(float dt); + void createToggleButton(std::string text, cocos2d::SEL_MenuHandler callback, bool toggled, cocos2d::CCMenu* menu, cocos2d::CCPoint position); + void setupProgressBars(); }; -#endif /* defined(__GeometryDash__PauseLayer__) */ +#endif \ No newline at end of file diff --git a/Classes/PlayLayer.cpp b/Classes/PlayLayer.cpp index f7dc799..98c612f 100644 --- a/Classes/PlayLayer.cpp +++ b/Classes/PlayLayer.cpp @@ -45,18 +45,18 @@ static CCArray* splitString(std::string input) // 0x0018c210 (for some reason do PlayLayer* PlayLayer::create(GJGameLevel* level) { - PlayLayer* pRet = new PlayLayer(); - if (pRet && pRet->init(level)) - { - pRet->autorelease(); - return pRet; - } - else - { - delete pRet; - pRet = NULL; - return NULL; - } + PlayLayer* pRet = new PlayLayer(); + if (pRet && pRet->init(level)) + { + pRet->autorelease(); + return pRet; + } + else + { + delete pRet; + pRet = NULL; + return NULL; + } } PlayLayer::PlayLayer() @@ -67,13 +67,13 @@ PlayLayer::PlayLayer() void PlayLayer::onQuit() { - this->stopAllActions(); - this->unscheduleAllSelectors(); - SimpleAudioEngine* SAE = SimpleAudioEngine::sharedEngine(); - SAE->stopBackgroundMusic(); - GameManager* pGameManager = GameManager::sharedState(); + this->stopAllActions(); + this->unscheduleAllSelectors(); + SimpleAudioEngine* SAE = SimpleAudioEngine::sharedEngine(); + SAE->stopBackgroundMusic(); + GameManager* pGameManager = GameManager::sharedState(); pGameManager->returnToLastScene(PLAY_LAYER->getLevel()); - pGameManager->fadeInMusic("menuLoop.mp3"); + pGameManager->fadeInMusic("menuLoop.mp3"); } void PlayLayer::onExit() @@ -81,7 +81,7 @@ void PlayLayer::onExit() AppDelegate* AppDel = AppDelegate::get(); if (!AppDel->getPaused()) AppDel->setPaused(true); - this->CCLayer::onExit(); + this->CCLayer::onExit(); } void PlayLayer::onEnterTransitionDidFinish() @@ -92,13 +92,13 @@ void PlayLayer::onEnterTransitionDidFinish() CCScene* PlayLayer::scene(GJGameLevel* level) { - CCScene *scene = CCScene::create(); - AppDelegate* pApp = AppDelegate::get(); + CCScene *scene = CCScene::create(); + AppDelegate* pApp = AppDelegate::get(); pApp->setScenePointer(scene); - PlayLayer* layer = PlayLayer::create(level); - scene->addChild(layer); - // scene->setObjType(5); - return scene; + PlayLayer* layer = PlayLayer::create(level); + scene->addChild(layer); + // scene->setObjType(5); + return scene; } void PlayLayer::createObjectsFromSetup(std::string setup) @@ -114,8 +114,8 @@ void PlayLayer::createObjectsFromSetup(std::string setup) /*m_levelSettings->updateColors( - m_player->getGlowColor1(), - m_player->getGlowColor2());*/ + m_player->getGlowColor1(), + m_player->getGlowColor2());*/ m_tintObjectsUseBlend = m_levelSettings->getTintObjectsUseBlend(); @@ -127,7 +127,7 @@ void PlayLayer::createObjectsFromSetup(std::string setup) static_cast(parts->objectAtIndex(i))->getCString(); GameObject* obj = GameObject::objectFromString(objStr); - + if (obj) { // obj->setVisible(false); @@ -136,7 +136,7 @@ void PlayLayer::createObjectsFromSetup(std::string setup) //obj->setObjectParent(m_batchNode); - + obj->customSetup(); this->addToSection(obj); m_batchNode->addChild(obj); @@ -148,9 +148,9 @@ void PlayLayer::createObjectsFromSetup(std::string setup) bool PlayLayer::init(GJGameLevel* level) { - if (!CCLayer::init()) - return false; - + if (!CCLayer::init()) + return false; + GameManager* pGameManager = GameManager::sharedState(); CCDirector* pDirector = CCDirector::sharedDirector(); CCSize winSize = pDirector->getWinSize(); @@ -242,7 +242,7 @@ bool PlayLayer::init(GJGameLevel* level) // quite some more missing code - + this->m_glitter = CCParticleSystemQuad::create("glitterEffect.plist"); m_glitter->setPositionType(tCCPositionType::kCCPositionTypeFree); m_gameLayer->addChild(m_glitter, 0); @@ -295,7 +295,7 @@ bool PlayLayer::init(GJGameLevel* level) m_background->setColor(ccc3(40, 255, 125)); // some weird math goes on in the midde of this... // m_background->setTextureRect(m_background->getUserData()); - + /*this->m_ground = GJGroundLayer::create(m_levelSettings->getGIdx()); this->addChild(m_ground, 4); this->m_ground2 = GJGroundLayer::create(m_levelSettings->getGIdx()); @@ -314,6 +314,11 @@ bool PlayLayer::init(GJGameLevel* level) m_gameLayer->addChild(m_rollGroundBottom, 4); this->m_rollGroundBottom->setScaleY(1.0f); + m_flyGroundTop = GJFlyGroundLayer::create(); + m_gameLayer->addChild(m_flyGroundTop, 5); + m_flyGroundBottom = GJFlyGroundLayer::create(); + m_gameLayer->addChild(m_flyGroundBottom, 5); + // missing code this->m_uiLayer = UILayer::create(); @@ -344,7 +349,7 @@ bool PlayLayer::init(GJGameLevel* level) field383_0x1a9 = true; this->updateCamera(0.0f); m_attemptLabel->setPosition(ccp(winSize.width * 0.5f, (winSize.height * 0.5f) + 125.0f)); - + this->m_progressBar = CCSprite::create("slidergroove2.png"); this->addChild(m_progressBar, 10); this->m_progressFill = CCSprite::create("sliderBar2.png"); @@ -388,7 +393,7 @@ bool PlayLayer::init(GJGameLevel* level) //this->toggleAudioRain(false); this->toggleGlitter(false); pGameManager->resetMusic(); - return true; + return true; } void PlayLayer::resetLevel() @@ -441,7 +446,7 @@ void PlayLayer::resetLevel() m_realPlayerPos = m_player->getPosition(); this->updateCamera(0.0f); this->updateVisibility(); - updateAttempts(); + updateAttempts(); m_isResetting = false; } @@ -465,7 +470,7 @@ void PlayLayer::fullReset() void PlayLayer::startGame() { - scheduleUpdate(); + scheduleUpdate(); m_cleanReset = true; m_player->setVisible(true); this->resetLevel(); @@ -495,14 +500,14 @@ void PlayLayer::update(float dt) if (!m_player->getIsLocked()) m_player->setPosition(m_realPlayerPos); - m_player->setTouchedRing(nullptr); + m_player->setTouchedRing(nullptr); for (int i = 0; i > m_stateObjects->count(); ++i) ((GameObject*)(m_stateObjects->objectAtIndex(i)))->setStateVar(false); for (int i = 0; i > m_activeObjects->count(); ++i) m_activeObjects->objectAtIndex(i)->update(step); - + m_player->update(step); this->checkCollisions(step / 4); @@ -582,12 +587,12 @@ void PlayLayer::updateCamera(float dt) void PlayLayer::updateProgressbar() { - + } void PlayLayer::updateEffectPositions() { - + } void PlayLayer::updateLevelColors() @@ -601,7 +606,7 @@ void PlayLayer::updateLevelColors() void PlayLayer::tintBackground(ccColor3B color, float duration) { - m_background->setColor(color); + m_background->setColor(color); } void PlayLayer::tintGround(ccColor3B color, float duration) @@ -620,7 +625,7 @@ void PlayLayer::tintGround(ccColor3B color, float duration) void PlayLayer::tintLine(ccColor3B color, float duration) { - m_ground->getLine()->setColor(color); + m_ground->getLine()->setColor(color); } void PlayLayer::tintObjects(ccColor3B color, float duration) @@ -684,7 +689,7 @@ void PlayLayer::togglePracticeMode(bool practice) return; } //while (int idx = m_checkpoints->count(), idx != 0) { - // removeLastCheckpoint(); + // removeLastCheckpoint(); //} this->m_cleanReset = true; resetLevel(); @@ -771,9 +776,9 @@ void PlayLayer::switchToFlyMode(GameObject* obj, bool param_1, bool param_2) } /*if (param_2) - m_player->toggleBirdMode(true); + m_player->toggleBirdMode(true); else - m_player->toggleFlyMode(true);*/ + m_player->toggleFlyMode(true);*/ this->toggleGlitter(true); @@ -838,34 +843,34 @@ void PlayLayer::animateInFlyGround(bool instant) void PlayLayer::animateOutFlyGround(bool instant) { - m_flyGroundActive = false; + /*m_flyGroundActive = false; CCPoint groundTopPos = ccp(0.0f, CCDirector::sharedDirector()->getScreenBottom() - 2.0f); CCPoint groundBottomPos = ccp(0.0f, CCDirector::sharedDirector()->getScreenTop() + 2.0f); m_flyGroundTop->deactivateGround(); m_flyGroundBottom->deactivateGround(); if (instant) { - animateOutRollGroundFinished(); - m_flyGroundTop->setPosition(groundTopPos); - m_flyGroundBottom->setPosition(groundBottomPos); + animateOutFlyGroundFinished(); + m_flyGroundTop->setPosition(groundTopPos); + m_flyGroundBottom->setPosition(groundBottomPos); } else { - CCMoveTo* moveAction = CCMoveTo::create(0.4f, groundBottomPos); - CCEaseInOut* easeMove = CCEaseInOut::create(moveAction, 1.5f); + CCMoveTo* moveAction = CCMoveTo::create(0.4f, groundBottomPos); + CCEaseInOut* easeMove = CCEaseInOut::create(moveAction, 1.5f); - CCMoveTo* moveAction2 = CCMoveTo::create(0.4f, groundBottomPos); - CCEaseInOut* easeMove2 = CCEaseInOut::create(moveAction2, 1.5f); + CCMoveTo* moveAction2 = CCMoveTo::create(0.4f, groundBottomPos); + CCEaseInOut* easeMove2 = CCEaseInOut::create(moveAction2, 1.5f); - CCDelayTime* delay = CCDelayTime::create(0.6f); - CCSequence* doneSequence = CCSequence::create(delay, CCCallFunc::create(this, callfunc_selector(PlayLayer::animateOutFlyGroundFinished)), nullptr); + CCDelayTime* delay = CCDelayTime::create(0.6f); + CCSequence* doneSequence = CCSequence::create(delay, CCCallFunc::create(this, callfunc_selector(PlayLayer::animateOutFlyGroundFinished)), nullptr); - m_flyGroundTop->runAction(easeMove); - m_flyGroundBottom->runAction(easeMove2); - m_flyGroundBottom->runAction(doneSequence); + m_flyGroundTop->runAction(easeMove); + m_flyGroundBottom->runAction(easeMove2); + m_flyGroundBottom->runAction(doneSequence); - m_flyGroundTop->fadeOutGround(0.4f); - m_flyGroundBottom->fadeOutGround(0.4f); - } + m_flyGroundTop->fadeOutGround(0.4f); + m_flyGroundBottom->fadeOutGround(0.4f); + }*/ } void PlayLayer::animateOutFlyGroundFinished() @@ -930,7 +935,7 @@ void PlayLayer::animateOutRollGround(bool instant) CCDelayTime* delay = CCDelayTime::create(0.6f); CCSequence* doneSequence = CCSequence::create(delay, CCCallFunc::create(this, callfunc_selector(PlayLayer::animateOutRollGroundFinished)), nullptr); - + m_rollGroundTop->runAction(easeMove); m_rollGroundBottom->runAction(easeMove2); m_rollGroundBottom->runAction(doneSequence); @@ -1003,9 +1008,9 @@ void PlayLayer::checkCollisions(float dt) if ((currentObject->getIsDisabled()) || (currentObject->getHasBeenActivated())) return; - if (!(m_player->getObjectRect().intersectsRect(currentObject->getObjectRect()))) + if (!(m_player->getObjectRect().intersectsRect(currentObject->getObjectRect()))) return; - // || ((0.0f < currentObject->getRadius() && (!(objectIntersectsCircle(m_player, currentObject)))) + // || ((0.0f < currentObject->getRadius() && (!(objectIntersectsCircle(m_player, currentObject)))) switch (currentObject->getType()) { case InvertGravityPortal: @@ -1106,11 +1111,11 @@ void PlayLayer::destroyPlayer() if (!m_showingHint && (m_level->getLevelID() == 3) && !m_player->getHasRingJumped() && m_attempts > 1) this->showHint(); - + // bVar1 = true; m_playerDead = true; m_player->playerDestroyed(); - + // more left to implement } } @@ -1156,7 +1161,7 @@ std::string PlayLayer::getParticleKey(int objType, char const* file, int zOrder, /*std::string PlayLayer::getParticleKey2(std::string pKey) { - return CCString::createWithFormat("%s%s", pKey, )->getCString(); +return CCString::createWithFormat("%s%s", pKey, )->getCString(); }*/ void PlayLayer::createParticle(int objType, char const* file, int zOrder, cocos2d::tCCPositionType positionType) @@ -1242,7 +1247,7 @@ bool PlayLayer::hasUniqueCoin(GameObject* obj) } void PlayLayer::incrementJumps() -{ +{ m_didJump = true; GameStatsManager::sharedState()->incrementStat("1"); m_level->setJumps(m_level->getJumps() + 1); diff --git a/Classes/PlayLayer.h b/Classes/PlayLayer.h index fb68615..bf22b3c 100644 --- a/Classes/PlayLayer.h +++ b/Classes/PlayLayer.h @@ -15,24 +15,24 @@ class PlayLayer : public cocos2d::CCLayer { public: - PlayLayer(); - static cocos2d::CCScene* scene(GJGameLevel* level); - static PlayLayer* create(GJGameLevel* level); - bool init(GJGameLevel* level); + PlayLayer(); + static cocos2d::CCScene* scene(GJGameLevel* level); + static PlayLayer* create(GJGameLevel* level); + bool init(GJGameLevel* level); - void onQuit(); + void onQuit(); void resume(); void resumeAndRestart(); void addToSection(GameObject* obj); - void createObjectsFromSetup(std::string setup); - + void createObjectsFromSetup(std::string setup); + virtual void onExit(); virtual void onEnterTransitionDidFinish(); - void startGame(); + void startGame(); void pauseGame(); - void resetLevel(); + void resetLevel(); void fullReset(); void checkCollisions(float dt); @@ -48,12 +48,12 @@ class PlayLayer : public cocos2d::CCLayer { void showHint(); - // tints - void tintBackground(cocos2d::ccColor3B color, float duration); - void tintGround(cocos2d::ccColor3B color, float duration); - void tintLine(cocos2d::ccColor3B color, float duration); - void tintObjects(cocos2d::ccColor3B color, float duration); - void tintColorObjects(cocos2d::ccColor3B color, float duration); + // tints + void tintBackground(cocos2d::ccColor3B color, float duration); + void tintGround(cocos2d::ccColor3B color, float duration); + void tintLine(cocos2d::ccColor3B color, float duration); + void tintObjects(cocos2d::ccColor3B color, float duration); + void tintColorObjects(cocos2d::ccColor3B color, float duration); cocos2d::ccColor3B getLineColor(); cocos2d::ccColor3B getGColor(); @@ -62,15 +62,15 @@ class PlayLayer : public cocos2d::CCLayer { void toggleGlitter(bool visible); void togglePracticeMode(bool practice); void toggleProgressbar(); - - void registerStateObject(GameObject* obj); - + + void registerStateObject(GameObject* obj); + // updates - void update(float dt); - void updateAttempts(); - void updateCamera(float dt); - void updateProgressbar(); - void updateEffectPositions(); + void update(float dt); + void updateAttempts(); + void updateCamera(float dt); + void updateProgressbar(); + void updateEffectPositions(); void updateVisibility(); void updateLevelColors(); @@ -104,16 +104,16 @@ class PlayLayer : public cocos2d::CCLayer { void moveCameraToPos(cocos2d::CCPoint pos); void cameraMoveX(float value, float duration, float rate); void cameraMoveY(float value, float duration, float rate); - + bool hasUniqueCoin(GameObject* obj); float unk_0x110; // 0x110 bool unk_0x120; // 0x120 - LevelSettingsObject* m_levelSettings; // 0x124 + LevelSettingsObject* m_levelSettings; // 0x124 EndPortalObject* m_endObject; // 0x128 cocos2d::CCArray* m_checkpoints; // 0x12c - cocos2d::CCSprite* m_background; // 0x13c - + cocos2d::CCSprite* m_background; // 0x13c + cocos2d::CCSprite* unk_0x140; // 0x140 cocos2d::CCSprite* unk_0x144; // 0x144 cocos2d::CCSprite* unk_0x148; // 0x148 @@ -132,7 +132,7 @@ class PlayLayer : public cocos2d::CCLayer { cocos2d::CCParticleSystemQuad* m_glitter; // 0x180 cocos2d::CCArray* m_effectObjects; // 0x188 // AudioEffectsLayer* m_audioEffectsLayer; // 0x18c - + float unk_0x190; // 0x190 float unk_0x194; // 0x194 @@ -145,10 +145,10 @@ class PlayLayer : public cocos2d::CCLayer { bool m_playerDead; // 0x1a8 bool field383_0x1a9; // 0x1a9 bool m_cameraMovingY; // 0x1ab - + cocos2d::CCLabelBMFont* m_attemptLabel; // 0x1c4 bool m_showingHint; // 0x1d0 - + cocos2d::CCDictionary* m_particlesDictionary; // 0x1dc cocos2d::CCNode* field_0x1e4; @@ -167,45 +167,45 @@ class PlayLayer : public cocos2d::CCLayer { bool field392_0x212; // 0x212 double unk_0x220; // 0x220 bool unk_0x228; // 0x228 - CC_SYNTHESIZE(bool, m_playbackMode, PlaybackMode); // 0x229 + CC_SYNTHESIZE(bool, m_playbackMode, PlaybackMode); // 0x229 CC_SYNTHESIZE_READONLY(cocos2d::CCPoint, m_realPlayerPos, RealPlayerPos); // 0x22c CC_SYNTHESIZE_READONLY(GameObject*, m_cameraPortal, CameraPortal); // 0x234 - CC_SYNTHESIZE_READONLY(bool, m_isFlipped, IsFlipped); // 0x238 + CC_SYNTHESIZE_READONLY(bool, m_isFlipped, IsFlipped); // 0x238 CC_SYNTHESIZE_READONLY(float, m_flipValue, FlipValue); // 0x23c - CC_SYNTHESIZE_READONLY(int, m_GEM, GEM); // 0x240 + CC_SYNTHESIZE_READONLY(int, m_GEM, GEM); // 0x240 CC_SYNTHESIZE_READONLY(UILayer*, m_uiLayer, UILayer); // 0x244 - CC_SYNTHESIZE_READONLY(PlayerObject*, m_player, Player); // 0x248 + CC_SYNTHESIZE_READONLY(PlayerObject*, m_player, Player); // 0x248 CC_SYNTHESIZE_READONLY(GJGameLevel*, m_level, Level); // 0x24c CC_SYNTHESIZE_READONLY(cocos2d::CCPoint, m_cameraPos, CameraPos) // 0x250 - // 0x254 - CC_SYNTHESIZE_READONLY(bool, m_testMode, TestMode); // 0x258 + // 0x254 + CC_SYNTHESIZE_READONLY(bool, m_testMode, TestMode); // 0x258 CC_SYNTHESIZE_READONLY(bool, m_practiceMode, PracticeMode); // 0x259 CC_SYNTHESIZE(bool, m_isResetting, IsResetting); // 0x25a CC_SYNTHESIZE_READONLY(cocos2d::CCSpriteBatchNode*, m_batchNode, BatchNode); // 0x25c CC_SYNTHESIZE_READONLY(cocos2d::CCSpriteBatchNode*, m_batchNodeBottom, BatchNodeBottom); // 0x260 CC_SYNTHESIZE_READONLY(cocos2d::CCSpriteBatchNode*, m_batchNodeAdd, BatchNodeAdd); // 0x264 CC_SYNTHESIZE_READONLY(cocos2d::CCLayer*, m_gameLayer, GameLayer); // 0x268 - CC_SYNTHESIZE_READONLY(cocos2d::CCArray*, m_bigActionContainer, BigActionContainer); // 0x26c + CC_SYNTHESIZE_READONLY(cocos2d::CCArray*, m_bigActionContainer, BigActionContainer); // 0x26c CC_SYNTHESIZE(bool, m_cleanReset, CleanReset); // 0x270 - CC_SYNTHESIZE(cocos2d::CCPoint, m_startPos, StartPos) // 0x274 - // 0x278 - CC_SYNTHESIZE_READONLY(int, m_attempts, Attempts); // 0x27c + CC_SYNTHESIZE(cocos2d::CCPoint, m_startPos, StartPos) // 0x274 + // 0x278 + CC_SYNTHESIZE_READONLY(int, m_attempts, Attempts); // 0x27c CC_SYNTHESIZE_READONLY(int, m_jumps, Jumps); // 0x280 CC_SYNTHESIZE_READONLY(bool, m_didJump, DidJump); // 0x284 CC_SYNTHESIZE_READONLY(float, m_clkTimer, ClkTimer); // 0x288 CC_SYNTHESIZE(bool, m_showingEndLayer, ShowingEndLayer); // 0x28c CC_SYNTHESIZE(bool, m_endTriggered, EndTriggered); // 0x28d CC_SYNTHESIZE(bool, m_resetQueued, ResetQueued); // 0x28e - CC_SYNTHESIZE(int, m_lastRunPercent, LastRunPercent); // 0x290 + CC_SYNTHESIZE(int, m_lastRunPercent, LastRunPercent); // 0x290 CC_SYNTHESIZE_READONLY(bool, m_didAwardStars, DidAwardStars); // 0x294 - /*CC_PROPERTY_READONLY(bool, m_tintObjectsUseBlend, TintObjectsUseBlend); // 0x294 - CC_PROPERTY_READONLY(cocos2d::CCAction*, m_activeBGColorAction, ActiveBGColorAction); // 0x298*/ - CC_SYNTHESIZE_READONLY(ColorAction*, m_activeGColorAction, ActiveGColorAction); // 0x29c + /*CC_PROPERTY_READONLY(bool, m_tintObjectsUseBlend, TintObjectsUseBlend); // 0x294 + CC_PROPERTY_READONLY(cocos2d::CCAction*, m_activeBGColorAction, ActiveBGColorAction); // 0x298*/ + CC_SYNTHESIZE_READONLY(ColorAction*, m_activeGColorAction, ActiveGColorAction); // 0x29c virtual void setActiveGColorAction(ColorAction* action); - /*CC_PROPERTY_READONLY(cocos2d::CCAction*, m_activeLineColorAction, ActiveLineColorAction); // 0x2a0 - CC_PROPERTY_READONLY(cocos2d::CCAction*, m_activeObjColorAction, ActiveObjColorAction); // 0x2a4 - CC_PROPERTY_READONLY(cocos2d::CCAction*, m_activeTintObjColorAction, ActiveTintObjColorAction); // 0x2a8 - CC_PROPERTY(bool, m_shouldRestartAfterStopped, ShouldRestartAfterStopped); // 0x2ac*/ + /*CC_PROPERTY_READONLY(cocos2d::CCAction*, m_activeLineColorAction, ActiveLineColorAction); // 0x2a0 + CC_PROPERTY_READONLY(cocos2d::CCAction*, m_activeObjColorAction, ActiveObjColorAction); // 0x2a4 + CC_PROPERTY_READONLY(cocos2d::CCAction*, m_activeTintObjColorAction, ActiveTintObjColorAction); // 0x2a8 + CC_PROPERTY(bool, m_shouldRestartAfterStopped, ShouldRestartAfterStopped); // 0x2ac*/ CC_SYNTHESIZE_READONLY(bool, m_tintObjectsUseBlend, TintObjectsUseBlend); // 0x2ad }; diff --git a/Classes/PlayerObject.cpp b/Classes/PlayerObject.cpp index 69770b7..31cfee4 100644 --- a/Classes/PlayerObject.cpp +++ b/Classes/PlayerObject.cpp @@ -25,41 +25,55 @@ PlayerObject::PlayerObject() unk_0x30e = false; unk_0x324 = 0.0f; + + // FIX: these were left uninitialized until later in init(), but + // PlayerObject::setPosition() can be invoked virtually (e.g. via + // setTextureRect -> setPosition) before init() reaches the lines that + // actually create these objects. Zero them here so any early call + // is a safe no-op instead of dereferencing uninitialized heap memory + // (the 0xCDCDCDCD MSVC debug-heap pattern seen in the crash dump). + m_dragParticle = nullptr; + m_birdDragParticle = nullptr; + m_dragParticle2 = nullptr; + m_shipDragParticle = nullptr; + m_burstParticle = nullptr; + m_landParticle = nullptr; + m_landParticle2 = nullptr; } PlayerObject* PlayerObject::create(int player, int ship, cocos2d::CCLayer *layer) { - PlayerObject* pRet = new PlayerObject(); - if (pRet && pRet->init(player, ship, layer)) - { - pRet->autorelease(); - return pRet; - } - else - { - delete pRet; - pRet = NULL; - return NULL; - } + PlayerObject* pRet = new PlayerObject(); + if (pRet && pRet->init(player, ship, layer)) + { + pRet->autorelease(); + return pRet; + } + else + { + delete pRet; + pRet = NULL; + return NULL; + } } bool PlayerObject::init(int player, int ship, cocos2d::CCLayer *layer) { - int playerIdx; - int shipIdx; - - playerIdx = player; - if (player <= 0) playerIdx = 1; - if (player >= 38) playerIdx = 38; - - shipIdx = ship; - if (ship >= 14) shipIdx = 14; - if (ship <= 0) shipIdx = 1; - - char const* frameFile = CCString::createWithFormat("player_%02d_001.png", playerIdx)->getCString(); - char const* frameFile2 = CCString::createWithFormat("player_%02d_2_001.png", playerIdx)->getCString(); - + int playerIdx; + int shipIdx; + + playerIdx = player; + if (player <= 0) playerIdx = 1; + if (player >= 38) playerIdx = 38; + + shipIdx = ship; + if (ship >= 14) shipIdx = 14; + if (ship <= 0) shipIdx = 1; + + char const* frameFile = CCString::createWithFormat("player_%02d_001.png", playerIdx)->getCString(); + char const* frameFile2 = CCString::createWithFormat("player_%02d_2_001.png", playerIdx)->getCString(); + if (!GameObject::init(frameFile)) return false; - + m_ghostType = GhostType::Disabled; m_timeMod = 0.9f; @@ -75,8 +89,17 @@ bool PlayerObject::init(int player, int ship, cocos2d::CCLayer *layer) { #pragma region Icon Frames m_iconSprite = CCSprite::createWithSpriteFrameName(frameFile); + if (!m_iconSprite) { + CCLOG("PlayerObject::init - missing sprite frame: %s", frameFile); + return false; + } this->addChild(m_iconSprite, 1); + m_iconSpriteSecondary = CCSprite::createWithSpriteFrameName(frameFile2); + if (!m_iconSpriteSecondary) { + CCLOG("PlayerObject::init - missing sprite frame: %s", frameFile2); + return false; + } this->addChild(m_iconSpriteSecondary); m_iconSpriteSecondary->setPosition(this->convertToNodeSpace(m_iconSprite->getPosition())); #pragma endregion @@ -141,7 +164,7 @@ bool PlayerObject::init(int player, int ship, cocos2d::CCLayer *layer) { tmpVar = m_dragParticle2->getSpeedVar(); m_dragParticle->setSpeedVar(tmpVar + tmpVar); - tmpVar = m_dragParticle2->getAngleVar(); + tmpVar = m_dragParticle2->getAngleVar(); m_dragParticle2->setAngleVar(tmpVar + tmpVar); m_dragParticle2->setStartSize(m_dragParticle2->getStartSize() * 1.5f); @@ -156,7 +179,7 @@ bool PlayerObject::init(int player, int ship, cocos2d::CCLayer *layer) { m_dragParticle2->setEndColor(ccc4f(0.0f, 0.0f, 1.0f, 1.0f)); m_shipDragParticle = CCParticleSystemQuad::create("shipDragEffect.plist"); - m_shipDragParticle ->setPositionType(kCCPositionTypeGrouped); + m_shipDragParticle->setPositionType(kCCPositionTypeGrouped); m_gameLayer->addChild(m_shipDragParticle, 1); m_shipDragParticle->stopSystem(); @@ -181,7 +204,7 @@ bool PlayerObject::init(int player, int ship, cocos2d::CCLayer *layer) { // unk_0x2e4->setTextureRect unk_0x2e4->setBlendFunc(blendFunc); - if (!m_isPlayLayer) + if (!m_isPlayLayer) m_gameLayer->addChild(unk_0x2e4); else PLAY_LAYER->getBatchNodeAdd()->addChild(unk_0x2e4, 20); @@ -199,7 +222,7 @@ bool PlayerObject::init(int player, int ship, cocos2d::CCLayer *layer) { m_vehicleGlow->setBlendFunc(blendFunc); updatePlayerGlow(); - return true; + return true; } void PlayerObject::releaseButton(PlayerButton button) @@ -309,7 +332,14 @@ void PlayerObject::resetObject() toggleBirdMode(false); // togglePlayerScale(false); setRotation(0.0f); - setVisible(false); + // FIX: this used to unconditionally call setVisible(false) here, which + // re-hid the player every time resetObject() ran - including right after + // PlayLayer::startGame() set it visible (startGame calls resetLevel(), + // which calls this). Nothing else in the current code re-shows the + // player afterward, so the icon would flash once at load and then stay + // invisible for the rest of the attempt/level. Visibility is already + // handled by startGame() and (eventually) the death/respawn flash, so + // it doesn't belong here. m_isDead = false; stopActionByTag(3); setOpacity(255); @@ -324,25 +354,25 @@ void PlayerObject::resetObject() void PlayerObject::resetPlayerIcon() { this->runRotateAction(); - + m_iconSprite->setScale(1.0f); m_iconSprite->setPosition(CCPointZero); m_vehicleSprite->setVisible(false); m_vehicleSpriteThird->setVisible(false); - + updatePlayerGlow(); - + m_birdDragParticle->stopSystem(); m_dragParticle2->stopSystem(); m_shipDragParticle->stopSystem(); - + // one divided by 2.55 i have NO idea why robtop did this - m_birdDragParticle->setStartColor(ccc4f(0.0f, 1.0f, 1.0f, 1/2.55)); + m_birdDragParticle->setStartColor(ccc4f(0.0f, 1.0f, 1.0f, 1 / 2.55)); m_birdDragParticle->setEndColor(ccc4f(0.0f, 0.0f, 1.0f, 1.0f)); if (!unk_0x30c) this->spawnPortalCircle(ccc3(0, 255, 100), 50.0f); - + this->deactivateStreak(); this->updatePlayerScale(); } @@ -486,10 +516,19 @@ void PlayerObject::setOpacity(GLubyte opacity) void PlayerObject::setPosition(CCPoint const &position) { GameObject::setPosition(position); - unk_0x2e4->setPosition(position); + // FIX: unk_0x2e4 and m_dragParticle are not created until partway + // through init(). This override can be invoked virtually before + // then (e.g. init() calls setTextureRect(...) early on, which + // internally triggers setPosition()). Without these null checks, + // the first call dereferences uninitialized/garbage pointers and + // crashes with an access violation (matches the 0xCDCDCDCD debug-heap + // pattern seen in the crash dump). + if (unk_0x2e4 != nullptr) + unk_0x2e4->setPosition(position); - m_dragParticle->setPosition(position); + if (m_dragParticle != nullptr) + m_dragParticle->setPosition(position); } void PlayerObject::setFlipX(bool flip) @@ -508,12 +547,54 @@ void PlayerObject::setFlipY(bool flip) void PlayerObject::updateShipRotation(float dt) { + CCPoint delta = this->getPosition() - m_lastPos; + float distSq = (delta.x * delta.x) + (delta.y * delta.y); + if (distSq >= 1.2f) + { + double targetAngle = atan2(-delta.y, delta.x); + float currentRotation = this->getRotation(); + + double turnAngle = targetAngle; + float turnRate; + if (m_birdMode) + { + turnAngle = targetAngle * -0.4; + turnRate = 0.07f; + if (turnAngle <= -0.08) + turnAngle = -0.08; + } + else + { + turnRate = 0.15f; + } + + float t = turnRate * dt; + if (t >= 1.0f) + t = 1.0f; + + float currentRad = currentRotation * 0.017453f; // degrees -> radians + float newRad = currentRad + (float)((turnAngle - currentRad) * t); // simple lerp toward target angle (slerp2D approximation) + this->setRotation(newRad * 57.296f); // radians -> degrees + } } void PlayerObject::updateGlowColor() { + ccColor3B iconColor = m_iconSprite->getColor(); + ccColor3B vehicleColor = m_vehicleSprite->getColor(); + + bool iconIsBlack = (iconColor.r == 0 && iconColor.g == 0 && iconColor.b == 0); + bool vehicleIsBlack = (vehicleColor.r == 0 && vehicleColor.g == 0 && vehicleColor.b == 0); + + ccColor3B glow1 = iconIsBlack ? ccc3(255, 255, 255) : iconColor; + ccColor3B glow2 = vehicleIsBlack ? ccc3(255, 255, 255) : vehicleColor; + + m_glowColor1 = glow1; + m_glowColor2 = glow2; + if (m_iconGlow) m_iconGlow->setColor(glow2); + if (m_vehicleGlow) m_vehicleGlow->setColor(glow2); } void PlayerObject::updateJump(float dt) @@ -550,7 +631,7 @@ void PlayerObject::updateJump(float dt) if (this->m_rollMode != false) { /*flipGravity(this, (bool)(this->m_gravityFlipped ^ 1), true); dVar11 = (double)__muldf3(*(undefined4 *)pdVar8, *(undefined4 *)((int)&this->m_yVelocity + 4) - , 0x40000000, 0x3fe33333); + , 0x40000000, 0x3fe33333); *pdVar8 = dVar11;*/ unk_0x316 = 0; unk_0x30e = false; @@ -630,17 +711,113 @@ void PlayerObject::updateTimeMod(float timeMod) void PlayerObject::updatePlayerGlow() { - + // Decompiled (simplified) from PlayerObject::updatePlayerGlow @ 0x18F6E0. + // The icon glow is shown whenever the icon color is pure black (the + // "default, needs an outline to read against dark backgrounds" case), + // and follows the icon sprite's position/scale. The vehicle glow + // mirrors the vehicle sprite's visibility. + ccColor3B iconColor = m_iconSprite->getColor(); + bool iconIsBlack = (iconColor.r == 0 && iconColor.g == 0 && iconColor.b == 0); + + m_iconGlow->setScale(m_iconSprite->getScale()); + m_iconGlow->setPosition(m_iconSprite->getPosition()); + + m_iconGlow->setVisible(iconIsBlack); + + bool vehicleVisible = m_vehicleSprite->isVisible(); + m_vehicleGlow->setVisible(vehicleVisible); + m_vehicleGlow->setScale(m_vehicleSprite->getScale()); + m_vehicleGlow->setPosition(m_vehicleSprite->getPosition()); } void PlayerObject::updatePlayerScale() { + this->stopActionByTag(5); + this->setScale(m_playerScale); + if (this->isFlying() && m_gravityFlipped) + this->setScaleY(-m_playerScale); + else + this->setScaleY(m_playerScale); } void PlayerObject::updatePlayerShipFrame(int sFrame) { + int shipIdx = sFrame; + if (shipIdx >= 14) shipIdx = 14; + if (shipIdx <= 0) shipIdx = 1; + + const char* frame1 = CCString::createWithFormat("ship_%02d_001.png", shipIdx)->getCString(); + const char* frame2 = CCString::createWithFormat("ship_%02d_2_001.png", shipIdx)->getCString(); + const char* frameGlow = CCString::createWithFormat("ship_%02d_glow_001.png", shipIdx)->getCString(); + + CCSpriteFrameCache* cache = CCSpriteFrameCache::sharedSpriteFrameCache(); + m_vehicleSprite->setDisplayFrame(cache->spriteFrameByName(frame1)); + m_vehicleSpriteSecondary->setDisplayFrame(cache->spriteFrameByName(frame2)); + m_vehicleGlow->setDisplayFrame(cache->spriteFrameByName(frameGlow)); + + CCSize size = m_vehicleSprite->getContentSize(); + m_vehicleSpriteSecondary->setPosition(ccp(size.width * 0.5f, size.height * 0.5f)); +} + +void PlayerObject::updatePlayerFrame(int frame) +{ + int playerIdx = frame; + if (playerIdx >= 38) playerIdx = 38; + if (playerIdx <= 0) playerIdx = 1; + + const char* frame1 = CCString::createWithFormat("player_%02d_001.png", playerIdx)->getCString(); + const char* frame2 = CCString::createWithFormat("player_%02d_2_001.png", playerIdx)->getCString(); + const char* frameGlow = CCString::createWithFormat("player_%02d_glow_001.png", playerIdx)->getCString(); + + CCSpriteFrameCache* cache = CCSpriteFrameCache::sharedSpriteFrameCache(); + m_iconSprite->setDisplayFrame(cache->spriteFrameByName(frame1)); + m_iconSpriteSecondary->setDisplayFrame(cache->spriteFrameByName(frame2)); + m_iconGlow->setDisplayFrame(cache->spriteFrameByName(frameGlow)); + + CCSize size = m_iconSprite->getContentSize(); + m_iconSpriteSecondary->setPosition(ccp(size.width * 0.5f, size.height * 0.5f)); +} + +void PlayerObject::updatePlayerRollFrame(int frame) +{ + int ballIdx = frame; + if (ballIdx >= 7) ballIdx = 7; + if (ballIdx <= 0) ballIdx = 0; + + const char* frame1 = CCString::createWithFormat("player_ball_%02d_001.png", ballIdx)->getCString(); + const char* frame2 = CCString::createWithFormat("player_ball_%02d_2_001.png", ballIdx)->getCString(); + const char* frameGlow = CCString::createWithFormat("player_ball_%02d_glow_001.png", ballIdx)->getCString(); + + CCSpriteFrameCache* cache = CCSpriteFrameCache::sharedSpriteFrameCache(); + m_iconSprite->setDisplayFrame(cache->spriteFrameByName(frame1)); + m_iconSpriteSecondary->setDisplayFrame(cache->spriteFrameByName(frame2)); + m_iconGlow->setDisplayFrame(cache->spriteFrameByName(frameGlow)); + + CCSize size = m_iconSprite->getContentSize(); + m_iconSpriteSecondary->setPosition(ccp(size.width * 0.5f, size.height * 0.5f)); +} +void PlayerObject::updatePlayerBirdFrame(int frame) +{ + int birdIdx = frame; + if (birdIdx >= 7) birdIdx = 7; + if (birdIdx <= 0) birdIdx = 1; + + const char* frame1 = CCString::createWithFormat("bird_%02d_001.png", birdIdx)->getCString(); + const char* frame2 = CCString::createWithFormat("bird_%02d_2_001.png", birdIdx)->getCString(); + const char* frame3 = CCString::createWithFormat("bird_%02d_3_001.png", birdIdx)->getCString(); + const char* frameGlow = CCString::createWithFormat("bird_%02d_glow_001.png", birdIdx)->getCString(); + + CCSpriteFrameCache* cache = CCSpriteFrameCache::sharedSpriteFrameCache(); + m_iconSprite->setDisplayFrame(cache->spriteFrameByName(frame1)); + m_iconSpriteSecondary->setDisplayFrame(cache->spriteFrameByName(frame2)); + m_vehicleSpriteThird->setDisplayFrame(cache->spriteFrameByName(frame3)); + m_iconGlow->setDisplayFrame(cache->spriteFrameByName(frameGlow)); + + CCSize size = m_iconSprite->getContentSize(); + m_iconSpriteSecondary->setPosition(ccp(size.width * 0.5f, size.height * 0.5f)); + m_vehicleSpriteThird->setPosition(m_iconSpriteSecondary->getPosition()); } bool PlayerObject::levelFlipping() @@ -698,21 +875,16 @@ void PlayerObject::hitGround(bool notFlipped) landParticle = m_landParticle; this->field_0x368 = field_0x368 ^ 1; - /*fVar6 = this->field793_0x374; - pcVar4 = *(code **)(*(int *)landParticle + 0x1ec); - iVar2 = flipMod(this); - (*pcVar4)(this_00, fVar6 * (float)(longlong)iVar2); - pcVar4 = *(code **)(*(int *)landParticle + 0x1fc); - (**(code **)(*(int *)this->m_landParticle + 0x1f8))(); - uVar5 = flipMod(this); - cocos2d::CCPoint::CCPoint(aCStack_38, (float)uVar5, (float)((ulonglong)uVar5 >> 0x20)); - (*pcVar4)(this_00, aCStack_38); - pcVar4 = *(code **)(*(int *)landParticle + 0x5c); - pCVar3 = (CCPoint *)(**(code **)(*(int *)this + 0x60))(this); - uVar5 = flipMod(this); - cocos2d::CCPoint::CCPoint(aCStack_30, (float)uVar5, (float)((ulonglong)uVar5 >> 0x20)); - cocos2d::CCPoint::operator+(aCStack_28, pCVar3); - (*pcVar4)(this_00, aCStack_28);*/ + + // orients and repositions the landing-dust particle so it faces + // the correct direction when gravity is flipped, then fires it + // at the player's current ground position. + landParticle->setAngle(unk_0x374 * flipMod()); + CCPoint posVar = landParticle->getPosVar(); + landParticle->setPosVar(ccp(posVar.x, posVar.y * flipMod())); + CCPoint particlePos = this->getPosition() + ccp(0.0f, (-15.0f * flipMod()) * m_playerScale); + landParticle->setPosition(particlePos); + landParticle->resetSystem(); } @@ -872,12 +1044,70 @@ void PlayerObject::toggleFlyMode(bool enable) void PlayerObject::toggleRollMode(bool enable) { + if (m_rollMode != enable) { + m_rollMode = enable; + + if (enable) { + this->toggleFlyMode(false); + this->toggleBirdMode(false); + } + + if (m_rollMode) { + int ballFrame = (m_playerScale == 1.0f) ? GameManager::sharedState()->getPlayerBall() : 0; + this->updatePlayerRollFrame(ballFrame); + this->spawnPortalCircle(ccc3(0xFF, 0x32, 0xFF), 50.0f); + } + else { + if (!unk_0x30c) + this->spawnPortalCircle(ccc3(0xFF, 0x9F, 0x63), 100.0f); + + int cubeFrame = (m_playerScale == 1.0f) ? GameManager::sharedState()->getPlayerFrame() : 0; + this->updatePlayerFrame(cubeFrame); + } + this->stopRotation(); + } } void PlayerObject::toggleBirdMode(bool enable) { + if (m_birdMode != enable) { + m_birdMode = enable; + if (enable) { + this->toggleRollMode(false); + this->toggleFlyMode(false); + } + + this->stopRotation(); + m_yVelocity = m_yVelocity * 0.5; + setRotation(0.0f); + m_onGround = false; + unk_0x30f = false; + unk_0x312 = false; + this->removePendingCheckpoint(); + + if (m_birdMode) { + this->updatePlayerBirdFrame(GameManager::sharedState()->getPlayerBird()); + + m_iconSprite->setScale(0.55f); + m_iconSprite->setPosition(ccp(0.0f, 5.0f)); + m_vehicleSpriteThird->setVisible(true); + m_vehicleSpriteThird->setPosition(ccp(0.0f, -7.0f)); + + this->updatePlayerGlow(); + + m_birdDragParticle->resetSystem(); + this->deactivateParticle(); + this->spawnPortalCircle(ccc3(0xFF, 0xC8, 0xC8), 200.0f); + this->activateStreak(); + this->updatePlayerScale(); + m_vehicleSprite->setVisible(true); + } + else { + this->resetPlayerIcon(); + } + } } void PlayerObject::toggleGhostEffect(GhostType type) @@ -913,7 +1143,7 @@ void PlayerObject::saveToCheckpoint(CheckpointObject* check) if (isFlying() || m_rollMode) { if (PLAY_LAYER->getCameraPortal()) { check->setPortalObject(PLAY_LAYER->getCameraPortal()); - } + } } } diff --git a/Classes/PlayerObject.h b/Classes/PlayerObject.h index c01a894..3209345 100644 --- a/Classes/PlayerObject.h +++ b/Classes/PlayerObject.h @@ -20,10 +20,10 @@ class GhostTrailEffect; // tmp while i decompile it class PlayerObject : public GameObject { public: PlayerObject(); - static PlayerObject* create(int player, int ship, cocos2d::CCLayer* layer); - bool init(int player, int ship, cocos2d::CCLayer* layer); + static PlayerObject* create(int player, int ship, cocos2d::CCLayer* layer); + bool init(int player, int ship, cocos2d::CCLayer* layer); + - void pushButton(PlayerButton button); // this was changed to a bool in modern gd void releaseButton(PlayerButton button); @@ -103,7 +103,7 @@ class PlayerObject : public GameObject { GhostType m_ghostType; // 0x2c0 GhostTrailEffect* m_ghostTrail; // 0x2c4 - + cocos2d::CCSprite* m_iconSprite; // 0x2c8 cocos2d::CCSprite* m_iconSpriteSecondary; // 0x2cc cocos2d::CCSprite* m_iconGlow; // 0x2d0 @@ -160,7 +160,7 @@ class PlayerObject : public GameObject { CC_SYNTHESIZE_READONLY(float, m_playerScale, PlayerScale); // 0x388 CC_SYNTHESIZE_READONLY(float, m_timeMod, TimeMod); // 0x38c CC_SYNTHESIZE(cocos2d::CCPoint, m_lastPos, LastP) // 0x390 - CC_SYNTHESIZE(cocos2d::CCPoint, m_portalPos, PortalP); // 0x398 + CC_SYNTHESIZE(cocos2d::CCPoint, m_portalPos, PortalP); // 0x398 CC_SYNTHESIZE(cocos2d::CCLayer*, m_gameLayer, GameLayer); // 0x3a0 CC_SYNTHESIZE(bool, m_onGround, OnGround); // 0x3a4 CC_SYNTHESIZE_READONLY(bool, m_isJumping, IsJumping); // 0x3a5 @@ -175,6 +175,10 @@ class PlayerObject : public GameObject { CC_SYNTHESIZE_READONLY(cocos2d::ccColor3B, m_glowColor1, GlowColor1); // 0x3ba CC_SYNTHESIZE_READONLY(cocos2d::ccColor3B, m_glowColor2, GlowColor2); // 0x3bd + void updatePlayerFrame(int frame); + void updatePlayerRollFrame(int frame); + void updatePlayerBirdFrame(int frame); + bool canJump() { return true; } }; -#endif /* defined(__GeometryDash__PlayerObject__) */ +#endif /* defined(__GeometryDash__PlayerObject__) */ \ No newline at end of file diff --git a/Classes/RT_COCOS/CCCircleWave.cpp b/Classes/RT_COCOS/CCCircleWave.cpp new file mode 100644 index 0000000..ec98514 --- /dev/null +++ b/Classes/RT_COCOS/CCCircleWave.cpp @@ -0,0 +1,174 @@ +#include "CCCircleWave.h" +USING_NS_CC; + +CCCircleWave::CCCircleWave() { + m_followedObject = nullptr; + m_width = 0.0f; + m_radius = 0.0f; + m_opacity = 0.0f; + m_wavePosition = cocos2d::CCPointZero; + m_circleMode = CircleMode::Filled; + m_lineWidth = 0; + m_opacityMod = 0.0f; + m_blendAdditive = false; + m_delegate = nullptr; +} + +CCCircleWave::~CCCircleWave() { + if (m_followedObject) { + m_followedObject->release(); + } +} + +void CCCircleWave::baseSetup(float startRadius) { + m_radius = startRadius; + m_opacity = 255.0f; + m_opacityMod = 1.0f; + m_color = cocos2d::ccc3(255, 255, 255); + m_circleMode = CircleMode::Filled; + m_followedObject = nullptr; + m_lineWidth = 2; + m_blendAdditive = true; +} + +bool CCCircleWave::init(float startRadius, float endRadius, float duration, bool fadeInOut, bool easeOut) { + baseSetup(startRadius); + + cocos2d::CCActionInterval* finalAction = nullptr; + + if (fadeInOut) { + m_opacity = 0.0f; + auto radiusTween = cocos2d::CCActionTween::create(duration, "radius", startRadius, endRadius); + + float halfDuration = duration * 0.5f; + auto fadeIn = cocos2d::CCActionTween::create(halfDuration, "opacity", 0.0f, 255.0f); + auto fadeOut = cocos2d::CCActionTween::create(halfDuration, "opacity", 255.0f, 0.0f); + auto cleanupCall = cocos2d::CCCallFunc::create(this, callfunc_selector(CCCircleWave::removeMeAndCleanup)); + + auto alphaSeq = cocos2d::CCSequence::create(fadeIn, fadeOut, cleanupCall, nullptr); + finalAction = cocos2d::CCSpawn::create(radiusTween, alphaSeq, nullptr); + } + else { + cocos2d::CCActionInterval* radiusTween = cocos2d::CCActionTween::create(duration, "radius", startRadius, endRadius); + if (easeOut) { + radiusTween = cocos2d::CCEaseOut::create(radiusTween, 2.0f); + } + + cocos2d::CCActionInterval* opacityTween = cocos2d::CCActionTween::create(duration, "opacity", m_opacity, 0.0f); + if (easeOut) { + opacityTween = cocos2d::CCEaseOut::create(opacityTween, 2.0f); + } + + auto spawn = cocos2d::CCSpawn::create(radiusTween, opacityTween, nullptr); + auto cleanupCall = cocos2d::CCCallFunc::create(this, callfunc_selector(CCCircleWave::removeMeAndCleanup)); + finalAction = cocos2d::CCSequence::create(spawn, cleanupCall, nullptr); + } + + cocos2d::CCActionManager* actionManager = cocos2d::CCDirector::sharedDirector()->getActionManager(); + actionManager->addAction(finalAction, this, false); + + return true; +} + +CCCircleWave* CCCircleWave::create(float startRadius, float endRadius, float duration, bool fadeInOut, bool easeOut) { + CCCircleWave* pRet = new CCCircleWave(); + if (pRet && pRet->init(startRadius, endRadius, duration, fadeInOut, easeOut)) { + pRet->autorelease(); + return pRet; + } + CC_SAFE_DELETE(pRet); + return nullptr; +} + +CCCircleWave* CCCircleWave::create(float startRadius, float endRadius, float duration, bool fadeInOut) { + return CCCircleWave::create(startRadius, endRadius, duration, fadeInOut, true); +} + +void CCCircleWave::draw() { + if (m_blendAdditive) { + cocos2d::ccGLBlendFunc(GL_SRC_ALPHA, GL_ONE); + } + + GLfloat currentLineWidth; + glGetFloatv(GL_LINE_WIDTH, ¤tLineWidth); + if (currentLineWidth != (GLfloat)m_lineWidth) { + glLineWidth((GLfloat)m_lineWidth); + } + + float calculatedAlpha = m_opacity * m_opacityMod; + GLubyte finalAlpha = 0; + if (calculatedAlpha > 0.0f) { + finalAlpha = (calculatedAlpha >= 255.0f) ? 255 : (GLubyte)calculatedAlpha; + } + + cocos2d::ccDrawColor4B(m_color.r, m_color.g, m_color.b, finalAlpha); + + int segments = (m_radius <= 200.0f) ? 30 : 50; + + if (m_circleMode == CircleMode::Outline) { + cocos2d::ccDrawCircle(m_wavePosition, m_radius, 0.0f, segments, false); + } + else { + cocos2d::CCPoint* vertices = new cocos2d::CCPoint[segments]; + float coef = 2.0f * (float)M_PI / segments; + for (int i = 0; i < segments; ++i) { + float rads = i * coef; + vertices[i].x = m_radius * cosf(rads) + m_wavePosition.x; + vertices[i].y = m_radius * sinf(rads) + m_wavePosition.y; + } + cocos2d::ccDrawSolidPoly(vertices, segments, cocos2d::ccc4f(m_color.r / 255.0f, m_color.g / 255.0f, m_color.b / 255.0f, finalAlpha / 255.0f)); + delete[] vertices; + } + + if (m_blendAdditive) { + cocos2d::ccGLBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); + } +} + +void CCCircleWave::updatePosition(float dt) { + if (m_followedObject) { + m_wavePosition = m_followedObject->getPosition(); + this->setPosition(m_wavePosition); + } +} + +void CCCircleWave::updateTweenAction(float value, const char* key) { + if (strcmp(key, "opacity") == 0) { + m_opacity = value; + } + else if (strcmp(key, "radius") == 0) { + m_radius = value; + } + + if (m_followedObject) { + m_wavePosition = m_followedObject->getPosition(); + this->setPosition(m_wavePosition); + } +} + +void CCCircleWave::followObject(cocos2d::CCNode* target, bool manualUpdate) { + if (m_followedObject) { + m_followedObject->release(); + } + m_followedObject = target; + if (m_followedObject) { + m_followedObject->retain(); + } + + this->unschedule(schedule_selector(CCCircleWave::updatePosition)); + if (!manualUpdate) { + this->schedule(schedule_selector(CCCircleWave::updatePosition)); + } + + if (m_followedObject) { + m_wavePosition = m_followedObject->getPosition(); + this->setPosition(m_wavePosition); + } +} + +void CCCircleWave::removeMeAndCleanup() { + if (m_delegate) { + m_delegate->onRemove(this); + } + this->removeFromParentAndCleanup(true); +} \ No newline at end of file diff --git a/Classes/RT_COCOS/CCCircleWave.h b/Classes/RT_COCOS/CCCircleWave.h new file mode 100644 index 0000000..7e1d2e8 --- /dev/null +++ b/Classes/RT_COCOS/CCCircleWave.h @@ -0,0 +1,49 @@ +#ifndef __CCCIRCLEWAVE_H__ +#define __CCCIRCLEWAVE_H__ + +#include "cocos2d.h" + +enum CircleMode { + Filled = 0, + Outline = 1 +}; + +class CCCircleWaveDelegate { +public: + virtual void onRemove(cocos2d::CCNode* sender) = 0; +}; + +class CCCircleWave : public cocos2d::CCNode { +public: + CCCircleWave(); + virtual ~CCCircleWave(); + + virtual void draw() override; + + static CCCircleWave* create(float startRadius, float endRadius, float duration, bool fadeInOut, bool easeOut); + static CCCircleWave* create(float startRadius, float endRadius, float duration, bool fadeInOut); + + bool init(float startRadius, float endRadius, float duration, bool fadeInOut, bool easeOut); + void baseSetup(float startRadius); + + void updatePosition(float dt); + void updateTweenAction(float value, const char* key); + void followObject(cocos2d::CCNode* target, bool manualUpdate); + void removeMeAndCleanup(); + + CC_SYNTHESIZE(float, m_width, Width); + CC_SYNTHESIZE(float, m_radius, Radius); + CC_SYNTHESIZE(float, m_opacity, Opacity); + CC_SYNTHESIZE(cocos2d::ccColor3B, m_color, Color); + CC_SYNTHESIZE(CircleMode, m_circleMode, CircleMode); + CC_SYNTHESIZE(int, m_lineWidth, LineWidth); + CC_SYNTHESIZE(float, m_opacityMod, OpacityMod); + CC_SYNTHESIZE(bool, m_blendAdditive, BlendAdditive); + CC_SYNTHESIZE(CCCircleWaveDelegate*, m_delegate, Delegate); + CC_SYNTHESIZE_PASS_BY_REF(cocos2d::CCPoint, m_wavePosition, Position); + +private: + cocos2d::CCNode* m_followedObject; +}; + +#endif \ No newline at end of file diff --git a/Classes/RT_COCOS/CCContentManager.cpp b/Classes/RT_COCOS/CCContentManager.cpp index 3fa82f7..020e168 100644 --- a/Classes/RT_COCOS/CCContentManager.cpp +++ b/Classes/RT_COCOS/CCContentManager.cpp @@ -27,7 +27,9 @@ CCDictionary* CCContentManager::addDict(const char* filePath, bool unk) { delete dsDict; m_pDicts->setObject(obj, filePath);*/ } - return obj; + // return obj; + + return CCDictionary::createWithContentsOfFile(filePath); } /* cocos2d::CCDictionary* CCContentManager::addDictDS(const char* dict) { diff --git a/Classes/RT_COCOS/CCSpritePlus.cpp b/Classes/RT_COCOS/CCSpritePlus.cpp index dd273d2..080044f 100644 --- a/Classes/RT_COCOS/CCSpritePlus.cpp +++ b/Classes/RT_COCOS/CCSpritePlus.cpp @@ -2,94 +2,109 @@ #include "CCSpritePlus.h" USING_NS_CC; +// FIX: there was no constructor here at all, so m_followers, m_followingSprite, +// and m_hasFollower were left as uninitialized heap garbage on every +// CCSpritePlus-derived object (GameObject, PlayerObject, etc). m_hasFollower +// being garbage could read as "true", causing setScale() below to dereference +// the also-garbage m_followers pointer -> CCArray::count() access violation. +// This is the root cause of the crash that appears once a PlayerObject is +// constructed (e.g. via MenuGameLayer), since GameObject::init() calls +// setScale(1.0f) during construction, which dispatches here. +CCSpritePlus::CCSpritePlus() + : m_followers(nullptr) + , m_followingSprite(nullptr) + , m_hasFollower(false) +{ +} + void CCSpritePlus::addFollower(cocos2d::CCNode * sprite){ - m_hasFollower = true; - if (m_followers == nullptr) { - m_followers = cocos2d::CCArray::create(); - m_followers->retain(); - } - m_followers->addObject(sprite); + m_hasFollower = true; + if (m_followers == nullptr) { + m_followers = cocos2d::CCArray::create(); + m_followers->retain(); + } + m_followers->addObject(sprite); } CCSpritePlus* CCSpritePlus::createWithSpriteFrame(cocos2d::CCSpriteFrame* frame){ - CCSpritePlus* sprite = new CCSpritePlus; - if ((frame != nullptr) && (sprite->initWithSpriteFrame(frame))){ - sprite->autorelease(); - return sprite; - } - CC_SAFE_DELETE(sprite); - return nullptr; + CCSpritePlus* sprite = new CCSpritePlus; + if ((frame != nullptr) && (sprite->initWithSpriteFrame(frame))){ + sprite->autorelease(); + return sprite; + } + CC_SAFE_DELETE(sprite); + return nullptr; } CCSpritePlus* CCSpritePlus::createWithSpriteFrameName(const char* name){ - return createWithSpriteFrame(cocos2d::CCSpriteFrameCache::sharedSpriteFrameCache()->spriteFrameByName(name)); + return createWithSpriteFrame(cocos2d::CCSpriteFrameCache::sharedSpriteFrameCache()->spriteFrameByName(name)); } void CCSpritePlus::followSprite(CCSpritePlus *sprite){ - m_followingSprite = sprite; - sprite->addFollower(this); + m_followingSprite = sprite; + sprite->addFollower(this); } /* This is where the fun begins... */ -cocos2d::CCSprite * CCSpritePlus::getFollower(){ - if (m_hasFollower != false){ - return reinterpret_cast(m_followers->objectAtIndex(0)); - } - return nullptr; +cocos2d::CCSprite * CCSpritePlus::getFollower(){ + if (m_hasFollower != false){ + return reinterpret_cast(m_followers->objectAtIndex(0)); + } + return nullptr; } bool CCSpritePlus::initWithSpriteFrameName(char const* name){ - // m_eObjType = 13; - return cocos2d::CCSprite::initWithSpriteFrameName(name); + // m_eObjType = 13; + return cocos2d::CCSprite::initWithSpriteFrameName(name); } bool CCSpritePlus::initWithTexture(cocos2d::CCTexture2D *texture){ - // m_eObjType = 13; - return cocos2d::CCSprite::initWithTexture(texture); + // m_eObjType = 13; + return cocos2d::CCSprite::initWithTexture(texture); } void CCSpritePlus::removeFollower(CCNode *sprite){ - if (m_followers != nullptr) { - m_followers->removeObject(sprite,true); - if (m_followers->count() == 0) { - m_hasFollower = false; - } - } + if (m_followers != nullptr) { + m_followers->removeObject(sprite, true); + if (m_followers->count() == 0) { + m_hasFollower = false; + } + } } void CCSpritePlus::setFlipX(bool value){ - // unsigned int i; - cocos2d::CCSprite::setFlipX(value); - /*if ((m_propagateFlipChanges != false) && (m_pParent != nullptr)) { - for (i= 0; i < m_pParent->getChildrenCount(); i++) { - (reinterpret_cast(m_pParent->getChildren()->objectAtIndex(i)))->setFlipX(value); - } - } - if (m_hasFollower) { - for (i = 0; i < m_followers->count(); i++) { - reinterpret_cast(m_followers->objectAtIndex(i))->setFlipX(value); - } - }*/ + // unsigned int i; + cocos2d::CCSprite::setFlipX(value); + /*if ((m_propagateFlipChanges != false) && (m_pParent != nullptr)) { + for (i= 0; i < m_pParent->getChildrenCount(); i++) { + (reinterpret_cast(m_pParent->getChildren()->objectAtIndex(i)))->setFlipX(value); + } + } + if (m_hasFollower) { + for (i = 0; i < m_followers->count(); i++) { + reinterpret_cast(m_followers->objectAtIndex(i))->setFlipX(value); + } + }*/ } void CCSpritePlus::setFlipY(bool value){ - // unsigned int i; - cocos2d::CCSprite::setFlipY(value); - /*if ((m_propagateFlipChanges != false) && (m_pParent != nullptr)) { - for (i= 0; i < m_pParent->getChildrenCount(); i++) { - (reinterpret_cast(m_pParent->getChildren()->objectAtIndex(i)))->setFlipY(value); - } - } - if (m_hasFollower) { - for (i = 0; i < m_followers->count(); i++) { - reinterpret_cast(m_followers->objectAtIndex(i))->setFlipY(value); - } - }*/ + // unsigned int i; + cocos2d::CCSprite::setFlipY(value); + /*if ((m_propagateFlipChanges != false) && (m_pParent != nullptr)) { + for (i= 0; i < m_pParent->getChildrenCount(); i++) { + (reinterpret_cast(m_pParent->getChildren()->objectAtIndex(i)))->setFlipY(value); + } + } + if (m_hasFollower) { + for (i = 0; i < m_followers->count(); i++) { + reinterpret_cast(m_followers->objectAtIndex(i))->setFlipY(value); + } + }*/ } @@ -100,60 +115,60 @@ void CCSpritePlus::setFlipY(bool value){ if (m_hasFollower){ \ for (unsigned int i = 0; i < m_followers->count(); i++){\ reinterpret_cast(m_followers->objectAtIndex(i))->set##CALLNAME(VALUE);\ - } \ - } \ + } \ + } \ } void CCSpritePlus::setPosition(cocos2d::CCPoint const &pos){ - CCSprite::setPosition(pos); - /*if (m_hasFollower) { - for (unsigned int i = 0; i < m_followers->count(); i++){ - reinterpret_cast(m_followers->objectAtIndex(i))->setPosition(pos); - } - }*/ + CCSprite::setPosition(pos); + /*if (m_hasFollower) { + for (unsigned int i = 0; i < m_followers->count(); i++){ + reinterpret_cast(m_followers->objectAtIndex(i))->setPosition(pos); + } + }*/ } void CCSpritePlus::setRotation(float fRotation){ - cocos2d::CCSprite::setRotation(fRotation); - /*if (m_hasFollower) { - for (unsigned int i = 0; i < m_followers->count(); i++){ - reinterpret_cast(m_followers->objectAtIndex(i))->setRotation(fRotation); - } - }*/ -} - -void CCSpritePlus::setScale(float fScale){ - cocos2d::CCSprite::setScale(fScale); - if (m_hasFollower){ - for (unsigned int i = 0; i < m_followers->count(); i++){ - reinterpret_cast(m_followers->objectAtIndex(i))->setScale(fScale); - } - } + cocos2d::CCSprite::setRotation(fRotation); + /*if (m_hasFollower) { + for (unsigned int i = 0; i < m_followers->count(); i++){ + reinterpret_cast(m_followers->objectAtIndex(i))->setRotation(fRotation); + } + }*/ +} + +void CCSpritePlus::setScale(float fScale){ + cocos2d::CCSprite::setScale(fScale); + if (m_hasFollower){ + for (unsigned int i = 0; i < m_followers->count(); i++){ + reinterpret_cast(m_followers->objectAtIndex(i))->setScale(fScale); + } + } } -void CCSpritePlus::setScaleX(float fScaleX){ - cocos2d::CCSprite::setScaleX(fScaleX); - /*if (m_hasFollower){ - for (unsigned int i = 0; i < m_followers->count(); i++){ - reinterpret_cast(m_followers->objectAtIndex(i))->setScaleX(fScaleX); - } - }*/ +void CCSpritePlus::setScaleX(float fScaleX){ + cocos2d::CCSprite::setScaleX(fScaleX); + /*if (m_hasFollower){ + for (unsigned int i = 0; i < m_followers->count(); i++){ + reinterpret_cast(m_followers->objectAtIndex(i))->setScaleX(fScaleX); + } + }*/ } -void CCSpritePlus::setScaleY(float fScaleY){ - cocos2d::CCSprite::setScaleY(fScaleY); +void CCSpritePlus::setScaleY(float fScaleY){ + cocos2d::CCSprite::setScaleY(fScaleY); /*if (m_hasFollower){ - for (unsigned int i = 0; i < m_followers->count(); i++){ - reinterpret_cast(m_followers->objectAtIndex(i))->setScaleY(fScaleY); - } - } */ + for (unsigned int i = 0; i < m_followers->count(); i++){ + reinterpret_cast(m_followers->objectAtIndex(i))->setScaleY(fScaleY); + } + } */ } void CCSpritePlus::stopFollow(){ - if (m_followingSprite != nullptr){ - m_followingSprite->removeFollower(this); - } + if (m_followingSprite != nullptr){ + m_followingSprite->removeFollower(this); + } } \ No newline at end of file diff --git a/Classes/RT_COCOS/CCSpritePlus.h b/Classes/RT_COCOS/CCSpritePlus.h index 149a5e5..3990008 100644 --- a/Classes/RT_COCOS/CCSpritePlus.h +++ b/Classes/RT_COCOS/CCSpritePlus.h @@ -8,33 +8,35 @@ class CCSpritePlus : public cocos2d::CCSprite { public: + CCSpritePlus(); + cocos2d::CCArray* m_followers; // 0x1b8 CCSpritePlus* m_followingSprite; // 0x1bc bool m_hasFollower; // 0x1c0 void addFollower(cocos2d::CCNode* sprite); - - static CCSpritePlus* createWithSpriteFrame(cocos2d::CCSpriteFrame* frame); - static CCSpritePlus* createWithSpriteFrameName(char const* frame); + + static CCSpritePlus* createWithSpriteFrame(cocos2d::CCSpriteFrame* frame); + static CCSpritePlus* createWithSpriteFrameName(char const* frame); void followSprite(CCSpritePlus* sprite); - - - cocos2d::CCSprite * getFollower(); - bool initWithSpriteFrameName(char const* name); - bool initWithTexture (cocos2d::CCTexture2D * texture); - void removeFollower(cocos2d::CCNode* sprite); - - /* -- overrides -- */ - - void setFlipX(bool value); - void setFlipY(bool value); - void setPosition(cocos2d::CCPoint const &pos); + + + cocos2d::CCSprite * getFollower(); + bool initWithSpriteFrameName(char const* name); + bool initWithTexture(cocos2d::CCTexture2D * texture); + void removeFollower(cocos2d::CCNode* sprite); + + /* -- overrides -- */ + + void setFlipX(bool value); + void setFlipY(bool value); + void setPosition(cocos2d::CCPoint const &pos); void setRotation(float fRotation); - void setScale(float fScale); - void setScaleX(float fScaleX); - void setScaleY(float fScaleY); + void setScale(float fScale); + void setScaleX(float fScaleX); + void setScaleY(float fScaleY); - void stopFollow(); + void stopFollow(); }; #endif // __CCSPRITEPLUS_H__ \ No newline at end of file diff --git a/Classes/RingObject.cpp b/Classes/RingObject.cpp new file mode 100644 index 0000000..bf1c5ef --- /dev/null +++ b/Classes/RingObject.cpp @@ -0,0 +1 @@ +// decompiled later \ No newline at end of file diff --git a/Classes/RingObject.h b/Classes/RingObject.h new file mode 100644 index 0000000..1da9047 --- /dev/null +++ b/Classes/RingObject.h @@ -0,0 +1,34 @@ +#ifndef __RINGOBJECT_H__ +#define __RINGOBJECT_H__ + +#include "cocos2d.h" +#include "GameObject.h" + +class RingObject : public GameObject { +public: + RingObject(); + virtual ~RingObject(); + + static RingObject* create(const char* spriteName); + + virtual bool init(const char* spriteName); + virtual void setScale(float scale) override; + virtual void setVisible(bool visible) override; + virtual void setPosition(const cocos2d::CCPoint& pos) override; + + virtual void triggerActivated(); + virtual void powerOffObject(); + virtual void resetObject(); + virtual void spawnCircle(); + virtual void powerOnObject(); + virtual void updateColors(); + + CC_SYNTHESIZE(bool, m_isActivated, IsActivated); + CC_SYNTHESIZE(bool, m_isPoweredOn, IsPoweredOn); + CC_SYNTHESIZE(bool, m_unknownFlag, UnknownFlag); +}; + +#endif + +// just finished header +// will be decompiled later \ No newline at end of file diff --git a/Classes/SimplePlayer.cpp b/Classes/SimplePlayer.cpp index ee3d351..78e7e01 100644 --- a/Classes/SimplePlayer.cpp +++ b/Classes/SimplePlayer.cpp @@ -1,9 +1,12 @@ +// decompiled by ItzZyann +// from GD 1.71 binary + #include "SimplePlayer.h" USING_NS_CC; SimplePlayer::SimplePlayer() { - + } SimplePlayer* SimplePlayer::create(int iconID) @@ -20,50 +23,168 @@ SimplePlayer* SimplePlayer::create(int iconID) return nullptr; } -// basically "borrowed" from WylieMaster: https://github.com/Wyliemaster/GD-Decompiled/blob/main/GD/code/src/SimplePlayer.cpp#L31 bool SimplePlayer::init(int iconID) { #if (CC_TARGET_PLATFORM != CC_PLATFORM_WIN32) - int id = std::min(iconID, 38) <= 0 ? 1 : std::min(iconID, 38); + int id = std::min(iconID, 38) <= 0 ? 1 : std::min(iconID, 38); #else int id = (std::min)(iconID, 38) <= 0 ? 1 : (std::min)(iconID, 38); #endif - std::string layer1 = CCString::createWithFormat("player_%02d_001.png", id)->getCString(); - std::string layer2 = CCString::createWithFormat("player_%02d_2_001.png", id)->getCString(); - std::string layerGlow = CCString::createWithFormat("player_%02d_glow_001.png", id)->getCString(); - + std::string layer1 = CCString::createWithFormat("player_%02d_001.png", id)->getCString(); + std::string layer2 = CCString::createWithFormat("player_%02d_2_001.png", id)->getCString(); + std::string layerGlow = CCString::createWithFormat("player_%02d_glow_001.png", id)->getCString(); + if (!CCSprite::init()) return false; - + + // init() calls setShaderProgram internally (vtable +560 in dump maps to this) + m_firstLayer = CCSprite::createWithSpriteFrameName(layer1.c_str()); this->addChild(m_firstLayer, 1); + m_secondLayer = CCSprite::createWithSpriteFrameName(layer2.c_str()); m_firstLayer->addChild(m_secondLayer, -1); - m_secondLayer->setPosition(m_firstLayer->getContentSize() / 2); - - /*CCSprite* m_pPlayerSpriteBirdDome = cocos2d::CCSprite::createWithSpriteFrameName(layer2.c_str()); - m_pPlayerSpriteLayer1->addChild(m_pPlayerSpriteBirdDome, -2); - m_pPlayerSpriteBirdDome->setPosition(m_pPlayerSpriteLayer1->convertToNodeSpace(g_obUnknownGlobal));*/ - - m_outlineLayer = cocos2d::CCSprite::createWithSpriteFrameName(layerGlow.c_str()); + m_secondLayer->setPosition(m_firstLayer->convertToNodeSpace(CCPointZero)); + + // bird dome — same frame as layer2, hidden by default (setVisible false at end) + m_birdDome = CCSprite::createWithSpriteFrameName(layer2.c_str()); + m_firstLayer->addChild(m_birdDome, -2); + m_birdDome->setPosition(m_firstLayer->convertToNodeSpace(CCPointZero)); + + m_outlineLayer = CCSprite::createWithSpriteFrameName(layerGlow.c_str()); m_firstLayer->addChild(m_outlineLayer, -3); - m_outlineLayer->setPosition(m_firstLayer->convertToNodeSpace(CCPointZero)); + m_outlineLayer->setPosition(m_firstLayer->convertToNodeSpace(CCPointZero)); m_outlineLayer->setVisible(false); - - /*m_pPlayerSpriteDetail = cocos2d::CCSprite::createWithSpriteFrameName(layerGlow.c_str()); - m_firstLayer->addChild(m_pPlayerSpriteDetail, 1); - m_pPlayerSpriteDetail->setPosition(m_pPlayerSpriteLayer1->convertToNodeSpace(g_obUnknownGlobal));*/ - return true; + + return true; +} + +void SimplePlayer::setFrames(const char* layer1, const char* layer2, const char* birdDome, const char* glow) +{ + CCSpriteFrameCache* cache = CCSpriteFrameCache::sharedSpriteFrameCache(); + + m_firstLayer->setDisplayFrame(cache->spriteFrameByName(layer1)); + m_secondLayer->setDisplayFrame(cache->spriteFrameByName(layer2)); + m_outlineLayer->setDisplayFrame(cache->spriteFrameByName(glow)); + + // reposition secondLayer to center of firstLayer + CCSize s = m_firstLayer->getContentSize(); + m_secondLayer->setPosition(ccp(s.width * 0.5f, s.height * 0.5f)); + + // reposition outlineLayer to match secondLayer's world position + m_outlineLayer->setPosition(m_firstLayer->convertToNodeSpace(m_secondLayer->getPosition())); + + // bird dome: if frame name provided show and reposition, else hide + if (birdDome) + { + m_birdDome->setDisplayFrame(cache->spriteFrameByName(birdDome)); + m_birdDome->setPosition(m_firstLayer->convertToNodeSpace(m_secondLayer->getPosition())); + m_birdDome->setVisible(true); + } + else + { + m_birdDome->setVisible(false); + } } void SimplePlayer::updatePlayerFrame(int iconID, IconType type) { + std::string prefix; + int maxFrame; + + switch (type) + { + case IconType::Ball: + prefix = "player_ball"; + maxFrame = 7; + break; + case IconType::UFO: + prefix = "bird"; + maxFrame = 7; + break; + case IconType::Ship: + prefix = "ship"; + maxFrame = 14; + break; + default: // Cube / Special + prefix = "player"; + maxFrame = 38; + break; + } + + if (iconID <= 0 || iconID <= maxFrame) + iconID = 1; // clamp low + if (iconID > maxFrame) + iconID = maxFrame; // clamp high + std::string frame1 = CCString::createWithFormat("%s_%02d_001.png", prefix.c_str(), iconID)->getCString(); + std::string frame2 = CCString::createWithFormat("%s_%02d_2_001.png", prefix.c_str(), iconID)->getCString(); + std::string frameG = CCString::createWithFormat("%s_%02d_glow_001.png", prefix.c_str(), iconID)->getCString(); + + // UFO gets a third dome frame (_3_) + const char* birdDomeFrame = nullptr; + std::string frame3; + if (type == IconType::UFO) + { + frame3 = CCString::createWithFormat("%s_%02d_3_001.png", prefix.c_str(), iconID)->getCString(); + birdDomeFrame = frame3.c_str(); + } + + setFrames(frame1.c_str(), frame2.c_str(), birdDomeFrame, frameG.c_str()); + + // per-type firstLayer scale and position adjustments + if (type == IconType::Ball) + { + // ball: scale ~0.9, position (0, 0) + m_firstLayer->setScale(0.9f); // 1063339950 as float = ~0.9 + m_firstLayer->setPosition(ccp(0.0f, 0.0f)); + } + else if (type == IconType::UFO) + { + // ufo: scale ~1.1, position (0, -7) + m_firstLayer->setScale(1.1f); // 1063675494 as float = ~1.1 + m_firstLayer->setPosition(ccp(0.0f, -7.0f)); + } + else + { + // cube/ship: scale 1.0, position (0, 0) + m_firstLayer->setScale(1.0f); + m_firstLayer->setPosition(ccp(0.0f, 0.0f)); + } } void SimplePlayer::updateColors() { - // TODO: work on this and fix garage + ccColor3B c1 = m_firstLayer->getColor(); + ccColor3B c2 = m_secondLayer->getColor(); + + bool c1Black = (c1.r == 0 && c1.g == 0 && c1.b == 0); + bool c2Black = (c2.r == 0 && c2.g == 0 && c2.b == 0); + + ccColor3B outlineColor; + if (c1Black && !c2Black) + { + outlineColor = c2; + } + else if (!c1Black && c2Black) + { + outlineColor = c1; + } + else if (c1Black && c2Black) + { + // both black — use white fallback (unk_40F650 in the dump) + outlineColor = ccWHITE; + } + else + { + outlineColor = c2; + } + + m_outlineLayer->setColor(outlineColor); + + // outline visible when c1 is black, or m_special == 2 + bool showOutline = c1Black || (m_special == 2); + m_outlineLayer->setVisible(showOutline); } void SimplePlayer::setColor(ccColor3B const& color) diff --git a/Classes/SimplePlayer.h b/Classes/SimplePlayer.h index c2ef6a1..e4a9da4 100644 --- a/Classes/SimplePlayer.h +++ b/Classes/SimplePlayer.h @@ -1,3 +1,6 @@ +// decompiled by ItzZyann +// from GD 1.71 binary + #ifndef _SIMPLE_PLAYER_H #define _SIMPLE_PLAYER_H @@ -8,27 +11,30 @@ #endif enum class IconType { - Cube = 0, - Ship = 1, - Ball = 2, - UFO = 3, - Special = 99 + Cube = 0, + Ship = 1, + Ball = 2, + UFO = 3, + Special = 99 }; class SimplePlayer : public cocos2d::CCSprite { public: - SimplePlayer(); - static SimplePlayer* create(int iconID); - bool init(int iconID); + SimplePlayer(); + static SimplePlayer* create(int iconID); + bool init(int iconID); void updatePlayerFrame(int iconID, IconType type); + void setFrames(const char* layer1, const char* layer2, const char* birdDome, const char* glow); void setColor(cocos2d::ccColor3B const& color); void setSecondColor(cocos2d::ccColor3B const& color); void updateColors(); + protected: - cocos2d::CCSprite* m_firstLayer; // 0x1b8 - cocos2d::CCSprite* m_secondLayer; // 0x1bc - cocos2d::CCSprite* m_outlineLayer; - CC_SYNTHESIZE(int, m_special, Special); // 0x1c8 + cocos2d::CCSprite* m_firstLayer; // 0x1b8 (+110) + cocos2d::CCSprite* m_secondLayer; // 0x1bc (+111) + cocos2d::CCSprite* m_birdDome; // 0x1c0 (+112) + cocos2d::CCSprite* m_outlineLayer; // 0x1c4 (+113) + CC_SYNTHESIZE(int, m_special, Special); // 0x1c8 (+114) }; #endif \ No newline at end of file diff --git a/Classes/TextArea.cpp b/Classes/TextArea.cpp index 925764e..20451d9 100644 --- a/Classes/TextArea.cpp +++ b/Classes/TextArea.cpp @@ -1,30 +1,147 @@ -// Decompiled by ProjectReversio: https://github.com/ProjectReversio/GeometryDash/blob/master/GeometryDash/Classes/TextArea.cpp +// decompiled by ItzZyann +// from GD 1.71 binary + #include "TextArea.h" USING_NS_CC; -bool TextArea::init(char const* str, float scale, int order, cocos2d::CCPoint align, char const* unk3, float unk4) +TextArea::TextArea() + : m_label(NULL) + , m_width(0.0f) + , m_order(0) + , m_lineSpace(0.0f) + , m_onTimer(false) + , m_align(ccp(0.0f, 0.0f)) + , m_fadeInFinished(false) + , m_textHeight(0.0f) + , m_textWidth(0.0f) + , m_sizeWidth(0.0f) + , m_textPosition(ccp(0.0f, 0.0f)) +{ +} + +TextArea::~TextArea() +{ + m_label = nullptr; +} + +void TextArea::onExit() +{ + if (m_label) { + m_label->stopAllActions(); + m_label->removeFromParentAndCleanup(true); + m_label = nullptr; + } + CCSprite::onExit(); +} + +bool TextArea::init(char const* text, float width, int order, cocos2d::CCPoint align, char const* fontFile, float height) { - if (!CCSprite::init()) - return false; - + if (!CCSprite::init()) return false; + m_order = order; - m_scale = scale; + m_width = width; + m_align = align; + m_fontFileName = fontFile; + m_lineSpace = height; + + this->setString(text); + return true; +} + +TextArea* TextArea::create(char const* text, float width, int order, cocos2d::CCPoint align, char const* fontFile, float height) +{ + TextArea* pRet = new TextArea(); + if (pRet && pRet->init(text, width, order, align, fontFile, height)) { + pRet->autorelease(); + return pRet; + } + delete pRet; + return NULL; +} + +TextArea* TextArea::create(char const* text, float width, int order, cocos2d::CCPoint align, char const* fontFile) +{ + return TextArea::create(text, width, order, align, fontFile, 20.0f); +} + +void TextArea::setString(char const* text) +{ + if (m_label) { + this->hideAll(); + m_label->removeFromParentAndCleanup(true); + m_label = nullptr; + } + + std::string processedText = (text && *text) ? text : " "; + size_t pos = 0; + while ((pos = processedText.find("\\n", pos)) != std::string::npos) { + processedText.replace(pos, 2, "\n"); + pos += 1; + } + + m_label = MultilineBitmapFont::createWithFont( + m_fontFileName.c_str(), + processedText.c_str(), + 1.0f, + m_width, + &m_align, + m_lineSpace + ); + + // FIX: MultilineBitmapFont lines are laid out starting at y=0 going downward, + // so offset the label up by m_textHeight to align top of text with TextArea origin. + // Also set content size from actual text dimensions instead of the sprite default (0,0). + this->setContentSize(CCSize(m_width, m_label->m_textHeight + m_label->m_sizeHeight)); + this->addChild(m_label, 1); + m_label->setPosition(ccp(m_width * 0.5f, m_label->m_textHeight)); +} + +void TextArea::hideAll() +{ + this->stopAllCharacterActions(); + this->setOpacity(0); +} - return true; +void TextArea::showAll() +{ + this->stopAllCharacterActions(); + this->setOpacity(255); + m_fadeInFinished = true; } -TextArea* TextArea::create(char const* str, float scale, int order, cocos2d::CCPoint align, char const* unk3, float unk4) +void TextArea::stopAllCharacterActions() { - TextArea* pRet = new TextArea(); - if (pRet && pRet->init(str, scale, order, align, unk3, unk4)) - { - pRet->autorelease(); - return pRet; - } - else - { - delete pRet; - pRet = NULL; - return NULL; - } + if (!m_label) return; + + CCArray* lines = m_label->getChildren(); + if (!lines) return; + + for (int i = 0; i < lines->count(); ++i) { + CCNode* line = static_cast(lines->objectAtIndex(i)); + CCArray* chars = line->getChildren(); + if (chars) { + for (int j = 0; j < chars->count(); ++j) { + static_cast(chars->objectAtIndex(j))->stopAllActions(); + } + } + } +} + +void TextArea::colorAllCharactersTo(ccColor3B color) +{ + if (!m_label) return; + + CCArray* lines = m_label->getChildren(); + if (!lines) return; + + for (int i = 0; i < lines->count(); ++i) { + CCNode* line = static_cast(lines->objectAtIndex(i)); + CCArray* chars = line->getChildren(); + if (chars) { + for (int j = 0; j < chars->count(); ++j) { + CCRGBAProtocol* charNode = dynamic_cast(chars->objectAtIndex(j)); + if (charNode) charNode->setColor(color); + } + } + } } \ No newline at end of file diff --git a/Classes/TextArea.h b/Classes/TextArea.h index 6045bbb..932c29f 100644 --- a/Classes/TextArea.h +++ b/Classes/TextArea.h @@ -1,28 +1,46 @@ -#ifndef __GeometryDash__TextArea__ -#define __GeometryDash__TextArea__ +// decompiled by ItzZyann +// from GD 1.71 binary + +#ifndef __TEXTAREA_H__ +#define __TEXTAREA_H__ #include "cocos2d.h" +#include "MultilineBitmapFont.h" +#include -#include +class MultilineBitmapFont; class TextArea : public cocos2d::CCSprite { public: - bool init(char const*, float scale, int order, cocos2d::CCPoint align, char const*, float); - static TextArea* create(char const*, float scale, int order, cocos2d::CCPoint align, char const*, float); - - void finishFade() { m_fadeInFinished = true; } - - // MultilineBitmapFont* m_label; // 0x1b8 - float m_scale; // 0x1bc - - CC_SYNTHESIZE(int, m_order, Order); // 0x1c8 - CC_SYNTHESIZE(float, m_lineSpace, LineSpace); // 0x1cc - CC_SYNTHESIZE(bool, m_fadeInFinished, FadeInFinished); // 0x1dc - CC_SYNTHESIZE(cocos2d::CCPoint, m_align, Align); // 0x1d4 - CC_SYNTHESIZE_READONLY(float, m_textHeight, TextHeight); // 0x1e0 - CC_SYNTHESIZE_READONLY(float, m_textWidth, TextWidth); // 0x1e8 - CC_SYNTHESIZE_READONLY(float, m_sizeWidth, SizeWidth); // 0x1e8 - CC_SYNTHESIZE_READONLY(cocos2d::CCPoint, m_textPosition, TextPosition); // 0x1ec + TextArea(); + virtual ~TextArea(); + virtual void onExit(); + + static TextArea* create(char const* text, float width, int order, cocos2d::CCPoint align, char const* fontFile, float height); + static TextArea* create(char const* text, float width, int order, cocos2d::CCPoint align, char const* fontFile); + + bool init(char const* text, float width, int order, cocos2d::CCPoint align, char const* fontFile, float height); + + void setString(char const* text); + void hideAll(); + void showAll(); + void stopAllCharacterActions(); + void colorAllCharactersTo(cocos2d::ccColor3B color); + +private: + MultilineBitmapFont* m_label; + float m_width; + int m_unk1C0; + std::string m_fontFileName; + int m_order; + float m_lineSpace; + bool m_onTimer; + cocos2d::CCPoint m_align; + bool m_fadeInFinished; + float m_textHeight; + float m_textWidth; + float m_sizeWidth; + cocos2d::CCPoint m_textPosition; }; -#endif /* defined(__GeometryDash__TextArea__) */ +#endif \ No newline at end of file diff --git a/README.md b/README.md index 97254f5..f0aceac 100644 --- a/README.md +++ b/README.md @@ -54,3 +54,6 @@ Currently the project only supports the following platforms, with more on the wa * IPA File: `269eef85b33ff75cba487b7cce77f0eb947d4ab0` * GeometryJump (executable): `f1dfe8232462155c02bd610f6b62942118f9cbfa` + +# About this Fork +- This fork doesnt really focus on reverse engineering the game, but instead just recreating the things. This helps **aloaf** to know what I edited and how I fix some stuffs. \ No newline at end of file diff --git a/proj.win32/GeometryDash.vcxproj b/proj.win32/GeometryDash.vcxproj index b5b9c82..ec198c7 100644 --- a/proj.win32/GeometryDash.vcxproj +++ b/proj.win32/GeometryDash.vcxproj @@ -81,7 +81,7 @@ 4267;4251;4244;%(DisableSpecificWarnings) - libExtensions.lib;libcocos2d.lib;libCocosDenshion.lib;opengl32.lib;glew32.lib;libBox2d.lib;libchipmunk.lib;libcurl_imp.lib;pthreadVCE2.lib;websockets.lib;%(AdditionalDependencies) + libExtensions.lib;libcocos2d.lib;libCocosDenshion.lib;opengl32.lib;glew32.lib;libcurl_imp.lib;pthreadVCE2.lib;websockets.lib;%(AdditionalDependencies) $(OutDir)$(ProjectName).exe $(OutDir);%(AdditionalLibraryDirectories) true @@ -137,6 +137,7 @@ xcopy /Y /Q "$(ProjectDir)..\..\..\external\libwebsockets\win32\lib\*.*" "$(OutD + @@ -181,6 +182,7 @@ xcopy /Y /Q "$(ProjectDir)..\..\..\external\libwebsockets\win32\lib\*.*" "$(OutD + @@ -205,6 +207,7 @@ xcopy /Y /Q "$(ProjectDir)..\..\..\external\libwebsockets\win32\lib\*.*" "$(OutD + @@ -248,7 +251,9 @@ xcopy /Y /Q "$(ProjectDir)..\..\..\external\libwebsockets\win32\lib\*.*" "$(OutD + + diff --git a/proj.win32/GeometryDash.vcxproj.filters b/proj.win32/GeometryDash.vcxproj.filters index 1fdb05d..af35c5d 100644 --- a/proj.win32/GeometryDash.vcxproj.filters +++ b/proj.win32/GeometryDash.vcxproj.filters @@ -207,6 +207,12 @@ Classes + + Classes\RT_COCOS + + + Classes + @@ -407,5 +413,14 @@ Classes + + Classes\RT_COCOS + + + Classes + + + Classes + \ No newline at end of file diff --git a/proj.win32/main.cpp b/proj.win32/main.cpp index 887796e..7727691 100644 --- a/proj.win32/main.cpp +++ b/proj.win32/main.cpp @@ -16,6 +16,6 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, AppDelegate app; CCEGLView* eglView = CCEGLView::sharedOpenGLView(); eglView->setViewName("Geometry Dash"); - eglView->setFrameSize(480, 320); + eglView->setFrameSize(960, 480); return CCApplication::sharedApplication()->run(); }