Overhaul gamemode management

This commit is contained in:
Sanae 2022-08-07 15:42:56 -06:00
parent 5f1a91161f
commit 34691affb0
21 changed files with 348 additions and 300 deletions

View file

@ -32,7 +32,7 @@ include $(DEVKITPRO)/libnx/switch_rules
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
TARGET ?= $(notdir $(CURDIR))$(SMOVER) TARGET ?= $(notdir $(CURDIR))$(SMOVER)
BUILD ?= build$(SMOVER) BUILD ?= build$(SMOVER)
SOURCES := source/sead/time source/sead source/puppets source/server source/layouts source/states source/cameras source/nx source SOURCES := source/sead/time source/sead source/puppets source/server/hns source/server/gamemode source/server source/layouts source/states source/cameras source/nx source
DATA := data DATA := data
INCLUDES := include include/sead INCLUDES := include include/sead
@ -46,7 +46,7 @@ CFLAGS := -g -Wall -ffunction-sections \
CFLAGS += $(INCLUDE) -D__SWITCH__ -DSMOVER=$(SMOVER) -O3 -DNNSDK -DSWITCH -DBUILDVERSTR=$(BUILDVERSTR) -DBUILDVER=$(BUILDVER) -DDEBUGLOG=$(DEBUGLOG) -DSERVERIP=$(SERVERIP) -DEMU=$(EMU) CFLAGS += $(INCLUDE) -D__SWITCH__ -DSMOVER=$(SMOVER) -O3 -DNNSDK -DSWITCH -DBUILDVERSTR=$(BUILDVERSTR) -DBUILDVER=$(BUILDVER) -DDEBUGLOG=$(DEBUGLOG) -DSERVERIP=$(SERVERIP) -DEMU=$(EMU)
CXXFLAGS := $(CFLAGS) -fno-rtti -fomit-frame-pointer -fno-exceptions -fno-asynchronous-unwind-tables -fno-unwind-tables -std=gnu++20 CXXFLAGS := $(CFLAGS) -Wno-invalid-offsetof -Wno-volatile -fno-rtti -fomit-frame-pointer -fno-exceptions -fno-asynchronous-unwind-tables -fno-unwind-tables -std=gnu++20
ASFLAGS := -g $(ARCH) ASFLAGS := -g $(ARCH)
LDFLAGS = -specs=../switch.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map) -Wl,--version-script=$(TOPDIR)/exported.txt -Wl,-init=__custom_init -Wl,-fini=__custom_fini -nostdlib LDFLAGS = -specs=../switch.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map) -Wl,--version-script=$(TOPDIR)/exported.txt -Wl,-init=__custom_init -Wl,-fini=__custom_fini -nostdlib

View file

@ -72,6 +72,9 @@ namespace al
PlayerActorBase *tryGetPlayerActor(al::PlayerHolder const *, int); PlayerActorBase *tryGetPlayerActor(al::PlayerHolder const *, int);
sead::Heap *getCurrentHeap(void); sead::Heap *getCurrentHeap(void);
sead::Heap* getStationedHeap();
sead::Heap* getSequenceHeap();
sead::Heap* getSceneHeap();
al::Projection *getProjection(al::IUseCamera const *, int); al::Projection *getProjection(al::IUseCamera const *, int);

View file

@ -17,6 +17,7 @@
#include "logger.hpp" #include "logger.hpp"
#include "server/gamemode/GameModeConfigMenu.hpp" #include "server/gamemode/GameModeConfigMenu.hpp"
#include "server/gamemode/GameModeConfigMenuFactory.hpp"
class FooterParts; class FooterParts;
@ -65,14 +66,18 @@ class StageSceneStateServerConfig : public al::HostStateBase<al::Scene>, public
// Root Page, contains buttons for gamemode config, server reconnecting, and server ip address changing // Root Page, contains buttons for gamemode config, server reconnecting, and server ip address changing
SimpleLayoutMenu* mMainOptions = nullptr; SimpleLayoutMenu* mMainOptions = nullptr;
CommonVerticalList *mMainOptionsList = nullptr; CommonVerticalList *mMainOptionsList = nullptr;
// Sub-Page for Mode configuration, has buttons for selecting current gamemode and configuring currently selected mode (if no mode is chosen, button will not do anything)
SimpleLayoutMenu* mGamemodeConfig = nullptr;
CommonVerticalList* mGameModeConfigList = nullptr;
// Sub-Page of Mode config, used to select a gamemode for the client to use // Sub-Page of Mode config, used to select a gamemode for the client to use
SimpleLayoutMenu* mModeSelect = nullptr; SimpleLayoutMenu* mModeSelect = nullptr;
CommonVerticalList* mModeSelectList = nullptr; CommonVerticalList* mModeSelectList = nullptr;
// Controls what shows up in specific gamemode config page
GameModeConfigMenu *mGamemodeConfigMenu = nullptr; // Sub-Pages for Mode configuration, has buttons for selecting current gamemode and configuring currently selected mode (if no mode is chosen, button will not do anything)
struct GameModeEntry {
GameModeConfigMenu* mMenu;
SimpleLayoutMenu* mLayout = nullptr;
CommonVerticalList* mList = nullptr;
};
sead::SafeArray<GameModeEntry, GameModeConfigMenuFactory::getMenuCount()> mGamemodeConfigMenus;
GameModeEntry *mGamemodeConfigMenu = nullptr;
bool mIsDecideConfig = false; bool mIsDecideConfig = false;
}; };

View file

@ -96,8 +96,6 @@ class Client {
static bool isNeedUpdateShines(); static bool isNeedUpdateShines();
bool isShineCollected(int shineId); bool isShineCollected(int shineId);
static void initMode(GameModeInitInfo const &initInfo);
static void sendHackCapInfPacket(const HackCap *hackCap); static void sendHackCapInfPacket(const HackCap *hackCap);
static void sendPlayerInfPacket(const PlayerActorHakoniwa *player); static void sendPlayerInfPacket(const PlayerActorHakoniwa *player);
static void sendGameInfPacket(const PlayerActorHakoniwa *player, GameDataHolderAccessor holder); static void sendGameInfPacket(const PlayerActorHakoniwa *player, GameDataHolderAccessor holder);
@ -110,8 +108,6 @@ class Client {
int getCollectedShinesCount() { return curCollectedShines.size(); } int getCollectedShinesCount() { return curCollectedShines.size(); }
int getShineID(int index) { if (index < curCollectedShines.size()) { return curCollectedShines[index]; } return -1; } int getShineID(int index) { if (index < curCollectedShines.size()) { return curCollectedShines[index]; } return -1; }
static void setGameActive(bool state);
static void setStageInfo(GameDataHolderAccessor holder); static void setStageInfo(GameDataHolderAccessor holder);
static bool tryAddPuppet(PuppetActor *puppet); static bool tryAddPuppet(PuppetActor *puppet);
@ -130,27 +126,8 @@ class Client {
static PuppetActor* getDebugPuppet(); static PuppetActor* getDebugPuppet();
static GameMode getServerMode() {
return sInstance ? sInstance->mServerMode : GameMode::NONE;
}
static void setServerMode(GameMode mode) {
if (sInstance) sInstance->mServerMode = mode;
}
static GameMode getCurrentMode();
static GameModeBase* getModeBase() { return sInstance ? sInstance->mCurMode : nullptr; }
template <typename T>
static T* getMode() {return sInstance ? (T*)sInstance->mCurMode : nullptr;}
static GameModeConfigMenu* tryCreateModeMenu();
static int getMaxPlayerCount() { return sInstance ? sInstance->maxPuppets + 1 : 10;} static int getMaxPlayerCount() { return sInstance ? sInstance->maxPuppets + 1 : 10;}
static void toggleCurrentMode();
static void updateStates(); static void updateStates();
static void clearArrays(); static void clearArrays();
@ -173,6 +150,12 @@ class Client {
return 0; return 0;
} }
static PuppetHolder* getPuppetHolder() {
if (sInstance)
return sInstance->mPuppetHolder;
return nullptr;
}
static void setSceneInfo(const al::ActorInitInfo& initInfo, const StageScene *stageScene); static void setSceneInfo(const al::ActorInitInfo& initInfo, const StageScene *stageScene);
static bool tryRegisterShine(Shine* shine); static bool tryRegisterShine(Shine* shine);
@ -184,23 +167,6 @@ class Client {
static bool openKeyboardIP(); static bool openKeyboardIP();
static bool openKeyboardPort(); static bool openKeyboardPort();
static GameModeInfoBase* getModeInfo() {
return sInstance ? sInstance->mModeInfo : nullptr;
}
// should only be called during mode init
static void setModeInfo(GameModeInfoBase* info) {
if(sInstance) sInstance->mModeInfo = info;
}
static void tryRestartCurrentMode();
static bool isModeActive() { return sInstance ? sInstance->mIsModeActive : false; }
static bool isSelectedMode(GameMode mode) {
return sInstance ? sInstance->mCurMode->getMode() == mode : false;
}
static void showConnect(); static void showConnect();
static void showConnectError(const char16_t* msg); static void showConnectError(const char16_t* msg);
@ -295,21 +261,11 @@ class Client {
sead::FrameHeap *mHeap = nullptr; // Custom FrameHeap used for all Client related memory sead::FrameHeap *mHeap = nullptr; // Custom FrameHeap used for all Client related memory
// --- Mode Info ---
GameModeBase* mCurMode = nullptr;
GameMode mServerMode = GameMode::NONE; // current mode set by server, will sometimes not match up with current game mode (until scene re-init) if server switches gamemodes
GameModeInfoBase *mModeInfo = nullptr;
bool mIsModeActive = false;
// --- Puppet Info --- // --- Puppet Info ---
int maxPuppets = 9; // default max player count is 10, so default max puppets will be 9 int maxPuppets = 9; // default max player count is 10, so default max puppets will be 9
PuppetInfo *mPuppetInfoArr[MAXPUPINDEX]; PuppetInfo *mPuppetInfoArr[MAXPUPINDEX] = {};
PuppetHolder *mPuppetHolder = nullptr; PuppetHolder *mPuppetHolder = nullptr;

View file

@ -21,7 +21,6 @@ enum GameMode : s8 {
// struct containing info about the games state for use in gamemodes // struct containing info about the games state for use in gamemodes
struct GameModeInitInfo { struct GameModeInitInfo {
GameModeInitInfo(al::ActorInitInfo* info, al::Scene *scene){ GameModeInitInfo(al::ActorInitInfo* info, al::Scene *scene){
mLayoutInitInfo = info->mLayoutInitInfo; mLayoutInitInfo = info->mLayoutInitInfo;
mPlayerHolder = info->mActorSceneInfo.mPlayerHolder; mPlayerHolder = info->mActorSceneInfo.mPlayerHolder;
@ -47,6 +46,7 @@ struct GameModeInitInfo {
class GameModeBase : public al::IUseName, public al::IUseSceneObjHolder { class GameModeBase : public al::IUseName, public al::IUseSceneObjHolder {
public: public:
GameModeBase(const char* name) { mName = name; } GameModeBase(const char* name) { mName = name; }
virtual ~GameModeBase() = default;
const char* getName() const override { return mName.cstr(); } const char* getName() const override { return mName.cstr(); }
al::SceneObjHolder* getSceneObjHolder() const override { return mSceneObjHolder; } al::SceneObjHolder* getSceneObjHolder() const override { return mSceneObjHolder; }

View file

@ -0,0 +1,38 @@
#pragma once
#include "al/factory/Factory.h"
#include "server/hns/HideAndSeekConfigMenu.hpp"
#include "server/gamemode/GameModeConfigMenu.hpp"
typedef GameModeConfigMenu* (*createMenu)(const char* name);
template <class T>
GameModeConfigMenu* createGameModeConfigMenu(const char* name) {
return new T();
};
__attribute((used)) constexpr al::NameToCreator<createMenu> menuTable[] = {
{"HideAndSeek", &createGameModeConfigMenu<HideAndSeekConfigMenu>},
};
class GameModeConfigMenuFactory : public al::Factory<createMenu> {
public:
GameModeConfigMenuFactory(const char* fName) {
this->factoryName = fName;
this->actorTable = menuTable;
this->factoryCount = sizeof(menuTable) / sizeof(menuTable[0]);
};
constexpr static const char* getMenuName(int idx);
constexpr static int getMenuCount();
};
constexpr const char* GameModeConfigMenuFactory::getMenuName(int idx) {
if (idx >= 0 && idx < sizeof(menuTable) / sizeof(menuTable[0]))
return menuTable[idx].creatorName;
return nullptr;
}
constexpr int GameModeConfigMenuFactory::getMenuCount() {
return sizeof(menuTable) / sizeof(menuTable[0]);
}

View file

@ -1,9 +1,8 @@
#pragma once #pragma once
#include "al/factory/Factory.h" #include "al/factory/Factory.h"
#include "layouts/HideAndSeekIcon.h"
#include "server/gamemode/GameModeBase.hpp" #include "server/gamemode/GameModeBase.hpp"
#include "server/HideAndSeekMode.hpp" #include "server/hns/HideAndSeekMode.hpp"
typedef GameModeBase* (*createMode)(const char* name); typedef GameModeBase* (*createMode)(const char* name);
@ -37,19 +36,19 @@ class GameModeFactory : public al::Factory<createMode> {
// TODO: possibly use shadows' crc32 hash algorithm for this // TODO: possibly use shadows' crc32 hash algorithm for this
constexpr const char* GameModeFactory::getModeString(GameMode mode) { constexpr const char* GameModeFactory::getModeString(GameMode mode) {
if(mode >= 0 && mode < sizeof(modeTable)/sizeof(modeTable[0])) if(mode >= 0 && (size_t)mode < sizeof(modeTable)/sizeof(modeTable[0]))
return modeTable[mode].creatorName; return modeTable[mode].creatorName;
return nullptr; return nullptr;
} }
constexpr const char* GameModeFactory::getModeName(GameMode mode) { constexpr const char* GameModeFactory::getModeName(GameMode mode) {
if(mode >= 0 && mode < sizeof(modeNames)/sizeof(modeNames[0])) if(mode >= 0 && (size_t)mode < sizeof(modeNames)/sizeof(modeNames[0]))
return modeNames[mode]; return modeNames[mode];
return nullptr; return nullptr;
} }
constexpr const char* GameModeFactory::getModeName(int idx) { constexpr const char* GameModeFactory::getModeName(int idx) {
if(idx >= 0 && idx < sizeof(modeNames)/sizeof(modeNames[0])) if(idx >= 0 && (size_t)idx < sizeof(modeNames)/sizeof(modeNames[0]))
return modeNames[idx]; return modeNames[idx];
return nullptr; return nullptr;
} }

View file

@ -1,21 +1,11 @@
#pragma once #pragma once
#include "server/gamemode/GameModeBase.hpp" #include "server/gamemode/GameModeBase.hpp"
#include <heap/seadHeap.h>
// base struct containing info about the current gamemode // base struct containing info about the current gamemode
struct GameModeInfoBase { struct GameModeInfoBase {
GameMode mMode; GameMode mMode;
}; };
template<class T> #include "server/gamemode/GameModeManager.hpp"
T *createModeInfo() {
// using sequence heap to create mode info should allow for mode info to persist between scenes
sead::Heap* seqHeap = sead::HeapMgr::instance()->findHeapByName("SequenceHeap", 0);
if (seqHeap) {
return new (seqHeap) T();
} else {
// if failed to get sequence heap, fall back to current heap (will return null if current heap is also null)
return new T();
}
}

View file

@ -0,0 +1,59 @@
#pragma once
#include <heap/seadDisposer.h>
#include <heap/seadHeap.h>
#include <container/seadSafeArray.h>
#include "server/gamemode/GameModeBase.hpp"
#include "server/gamemode/GameModeInfoBase.hpp"
class GameModeManager {
SEAD_SINGLETON_DISPOSER(GameModeManager)
GameModeManager();
~GameModeManager();
public:
void setMode(GameMode mode);
void initScene(const GameModeInitInfo& info);
void begin();
void end();
void update();
GameMode getGameMode() const { return mCurMode; }
template<class T> T* getMode() const { return static_cast<T*>(mCurModeBase); }
template<class T> T* getInfo() const { return static_cast<T*>(mModeInfo); }
void setInfo(GameModeInfoBase* info) {
mModeInfo = info;
}
template<class T>
T* createModeInfo();
sead::Heap* getHeap() { return mHeap; }
void toggleActive();
void setActive(bool active) { mActive = active; }
void setPaused(bool paused);
bool isMode(GameMode mode) const { return mCurMode == mode; }
bool isActive() const { return mActive; }
bool isModeAndActive(GameMode mode) const { return isMode(mode) && isActive(); }
bool isPaused() const { return mPaused; }
private:
sead::Heap* mHeap = nullptr;
bool mActive = false;
bool mPaused = false;
bool mWasSceneTrans = false;
bool mWasSetMode = false;
GameMode mCurMode = GameMode::NONE;
GameModeBase* mCurModeBase = nullptr;
GameModeInfoBase *mModeInfo = nullptr;
GameModeInitInfo *mLastInitInfo = nullptr;
};
template<class T>
T* GameModeManager::createModeInfo() {
sead::ScopedCurrentHeapSetter heapSetter(mHeap);
T* info = new T();
mModeInfo = info;
return info;
}

View file

@ -1,6 +1,6 @@
#pragma once #pragma once
#include "gamemode/GameModeConfigMenu.hpp" #include "server/gamemode/GameModeConfigMenu.hpp"
#include "game/Layouts/CommonVerticalList.h" #include "game/Layouts/CommonVerticalList.h"
#include "server/gamemode/GameModeBase.hpp" #include "server/gamemode/GameModeBase.hpp"

View file

@ -2,11 +2,11 @@
#include <math.h> #include <math.h>
#include "al/camera/CameraTicket.h" #include "al/camera/CameraTicket.h"
#include "gamemode/GameModeBase.hpp" #include "server/gamemode/GameModeBase.hpp"
#include "gamemode/GameModeInfoBase.hpp" #include "server/gamemode/GameModeInfoBase.hpp"
#include "server/gamemode/GameModeConfigMenu.hpp" #include "server/gamemode/GameModeConfigMenu.hpp"
#include "server/gamemode/GameModeTimer.hpp" #include "server/gamemode/GameModeTimer.hpp"
#include "server/HideAndSeekConfigMenu.hpp" #include "server/hns/HideAndSeekConfigMenu.hpp"
struct HideAndSeekInfo : GameModeInfoBase { struct HideAndSeekInfo : GameModeInfoBase {
HideAndSeekInfo() { mMode = GameMode::HIDEANDSEEK; } HideAndSeekInfo() { mMode = GameMode::HIDEANDSEEK; }

View file

@ -26,10 +26,10 @@
#include "math/seadVector.h" #include "math/seadVector.h"
#include "rs/util/InputUtil.h" #include "rs/util/InputUtil.h"
#include "sead/prim/seadSafeString.h" #include "sead/prim/seadSafeString.h"
#include "server/HideAndSeekMode.hpp" #include "server/hns/HideAndSeekMode.hpp"
bool comboBtnHook(int port) { bool comboBtnHook(int port) {
if (Client::isModeActive()) { // only switch to combo if any gamemode is active if (GameModeManager::instance()->isActive()) { // only switch to combo if any gamemode is active
return !al::isPadHoldL(port) && al::isPadTriggerDown(port); return !al::isPadHoldL(port) && al::isPadTriggerDown(port);
} else { } else {
return al::isPadTriggerDown(port); return al::isPadTriggerDown(port);
@ -110,19 +110,19 @@ void initNerveStateHook(StageSceneStatePauseMenu* stateParent, StageSceneStateOp
// skips starting both coin counters // skips starting both coin counters
void startCounterHook(CoinCounter* thisPtr) { void startCounterHook(CoinCounter* thisPtr) {
if (!Client::isModeActive()) { if (!GameModeManager::instance()->isActive()) {
thisPtr->tryStart(); thisPtr->tryStart();
} }
} }
// Simple hook that can be used to override isModeE3 checks to enable/disable certain behaviors // Simple hook that can be used to override isModeE3 checks to enable/disable certain behaviors
bool modeE3Hook() { bool modeE3Hook() {
return Client::isModeActive(); return GameModeManager::instance()->isActive();
} }
// Skips ending the play guide layout if a mode is active, since the mode would have already ended it // Skips ending the play guide layout if a mode is active, since the mode would have already ended it
void playGuideEndHook(al::SimpleLayoutAppearWaitEnd* thisPtr) { void playGuideEndHook(al::SimpleLayoutAppearWaitEnd* thisPtr) {
if (!Client::isModeActive()) { if (!GameModeManager::instance()->isActive()) {
thisPtr->end(); thisPtr->end();
} }
} }
@ -135,14 +135,14 @@ void initHackCapHook(al::LiveActor *cappy) {
al::PlayerHolder* createTicketHook(StageScene* curScene) { al::PlayerHolder* createTicketHook(StageScene* curScene) {
// only creates custom gravity camera ticket if hide and seek mode is active // only creates custom gravity camera ticket if hide and seek mode is active
if (Client::isSelectedMode(GameMode::HIDEANDSEEK)) { if (GameModeManager::instance()->isMode(GameMode::HIDEANDSEEK)) {
al::CameraDirector* director = curScene->getCameraDirector(); al::CameraDirector* director = curScene->getCameraDirector();
if (director) { if (director) {
if (director->mFactory) { if (director->mFactory) {
al::CameraTicket* gravityCamera = director->createCameraFromFactory( al::CameraTicket* gravityCamera = director->createCameraFromFactory(
"CameraPoserCustom", nullptr, 0, 5, sead::Matrix34f::ident); "CameraPoserCustom", nullptr, 0, 5, sead::Matrix34f::ident);
HideAndSeekMode* mode = Client::getMode<HideAndSeekMode>(); HideAndSeekMode* mode = GameModeManager::instance()->getMode<HideAndSeekMode>();
mode->setCameraTicket(gravityCamera); mode->setCameraTicket(gravityCamera);
} }
@ -157,9 +157,9 @@ bool borderPullBackHook(WorldEndBorderKeeper* thisPtr) {
bool isFirstStep = al::isFirstStep(thisPtr); bool isFirstStep = al::isFirstStep(thisPtr);
if (isFirstStep) { if (isFirstStep) {
if (Client::isSelectedMode(GameMode::HIDEANDSEEK) && Client::isModeActive()) { if (GameModeManager::instance()->isModeAndActive(GameMode::HIDEANDSEEK)) {
HideAndSeekMode* mode = Client::getMode<HideAndSeekMode>(); HideAndSeekMode* mode = GameModeManager::instance()->getMode<HideAndSeekMode>();
if (mode->isUseGravity()) { if (mode->isUseGravity()) {
killMainPlayer(thisPtr->mActor); killMainPlayer(thisPtr->mActor);

View file

@ -5,7 +5,7 @@
#include "al/string/StringTmp.h" #include "al/string/StringTmp.h"
#include "prim/seadSafeString.h" #include "prim/seadSafeString.h"
#include "server/gamemode/GameModeTimer.hpp" #include "server/gamemode/GameModeTimer.hpp"
#include "server/HideAndSeekMode.hpp" #include "server/hns/HideAndSeekMode.hpp"
#include "server/Client.hpp" #include "server/Client.hpp"
#include "al/util.hpp" #include "al/util.hpp"
#include "logger.hpp" #include "logger.hpp"
@ -16,7 +16,7 @@ HideAndSeekIcon::HideAndSeekIcon(const char* name, const al::LayoutInitInfo& ini
al::initLayoutActor(this, initInfo, "HideAndSeekIcon", 0); al::initLayoutActor(this, initInfo, "HideAndSeekIcon", 0);
mInfo = (HideAndSeekInfo*)Client::getModeInfo(); mInfo = GameModeManager::instance()->getInfo<HideAndSeekInfo>();
initNerve(&nrvHideAndSeekIconEnd, 0); initNerve(&nrvHideAndSeekIconEnd, 0);

View file

@ -21,7 +21,8 @@
#include "logger.hpp" #include "logger.hpp"
#include "rs/util.hpp" #include "rs/util.hpp"
#include "server/gamemode/GameModeBase.hpp" #include "server/gamemode/GameModeBase.hpp"
#include "server/HideAndSeekMode.hpp" #include "server/hns/HideAndSeekMode.hpp"
#include "server/gamemode/GameModeManager.hpp"
static int pInfSendTimer = 0; static int pInfSendTimer = 0;
static int gameInfSendTimer = 0; static int gameInfSendTimer = 0;
@ -252,10 +253,11 @@ void stageInitHook(al::ActorInitInfo *info, StageScene *curScene, al::PlacementI
Client::setSceneInfo(*info, curScene); Client::setSceneInfo(*info, curScene);
if (Client::getServerMode() != NONE) { if (GameModeManager::instance()->getGameMode() != NONE) {
GameModeInitInfo initModeInfo(info, curScene); GameModeInitInfo initModeInfo(info, curScene);
initModeInfo.initServerInfo(GameModeManager::instance()->getGameMode(), Client::getPuppetHolder());
Client::initMode(initModeInfo); GameModeManager::instance()->initScene(initModeInfo);
} }
Client::sendGameInfPacket(info->mActorSceneInfo.mSceneObjHolder); Client::sendGameInfPacket(info->mActorSceneInfo.mSceneObjHolder);
@ -278,6 +280,7 @@ ulong constructHook() { // hook for constructing anything we need to globally b
initInfo)); // Save our scenes init info to a gloabl ptr so we can access it later initInfo)); // Save our scenes init info to a gloabl ptr so we can access it later
Client::createInstance(al::getCurrentHeap()); Client::createInstance(al::getCurrentHeap());
GameModeManager::createInstance(al::getCurrentHeap()); // Create the GameModeManager on the current al heap
return 0x20; return 0x20;
} }
@ -303,13 +306,9 @@ bool hakoniwaSequenceHook(HakoniwaSequence* sequence) {
al::PlayerHolder *pHolder = al::getScenePlayerHolder(stageScene); al::PlayerHolder *pHolder = al::getScenePlayerHolder(stageScene);
PlayerActorHakoniwa* p1 = (PlayerActorHakoniwa*)al::tryGetPlayerActor(pHolder, 0); PlayerActorHakoniwa* p1 = (PlayerActorHakoniwa*)al::tryGetPlayerActor(pHolder, 0);
if (isFirstStep) {
Client::tryRestartCurrentMode();
}
isInGame = !stageScene->isPause(); isInGame = !stageScene->isPause();
Client::setGameActive(!stageScene->isPause()); GameModeManager::instance()->setPaused(stageScene->isPause());
Client::setStageInfo(stageScene->mHolder); Client::setStageInfo(stageScene->mHolder);
Client::updateStates(); Client::updateStates();
@ -345,7 +344,7 @@ bool hakoniwaSequenceHook(HakoniwaSequence* sequence) {
} }
} else if (al::isPadHoldL(-1)) { } else if (al::isPadHoldL(-1)) {
if (al::isPadTriggerLeft(-1)) Client::toggleCurrentMode(); if (al::isPadTriggerLeft(-1)) GameModeManager::instance()->toggleActive();
if (al::isPadTriggerRight(-1)) { if (al::isPadTriggerRight(-1)) {
if (debugMode) { if (debugMode) {
PuppetInfo *debugPuppet = Client::getDebugPuppetInfo(); PuppetInfo *debugPuppet = Client::getDebugPuppetInfo();

View file

@ -14,8 +14,9 @@
#include "actors/PuppetActor.h" #include "actors/PuppetActor.h"
#include "math/seadQuat.h" #include "math/seadQuat.h"
#include "math/seadVector.h" #include "math/seadVector.h"
#include "server/gamemode/GameModeManager.hpp"
#include "server/gamemode/GameModeBase.hpp" #include "server/gamemode/GameModeBase.hpp"
#include "server/HideAndSeekMode.hpp" #include "server/hns/HideAndSeekMode.hpp"
static const char *subActorNames[] = { static const char *subActorNames[] = {
"", // Face "", // Face
@ -189,9 +190,9 @@ void PuppetActor::control() {
} }
if (mNameTag) { if (mNameTag) {
if (Client::isSelectedMode(GameMode::HIDEANDSEEK) && Client::isModeActive()) { if (GameModeManager::instance()->isModeAndActive(GameMode::HIDEANDSEEK)) {
mNameTag->mIsAlive = mNameTag->mIsAlive =
Client::getMode<HideAndSeekMode>()->isPlayerIt() && mInfo->isIt; GameModeManager::instance()->getMode<HideAndSeekMode>()->isPlayerIt() && mInfo->isIt;
} else { } else {
if(!mNameTag->mIsAlive) if(!mNameTag->mIsAlive)

View file

@ -35,9 +35,9 @@
#include "sead/basis/seadRawPrint.h" #include "sead/basis/seadRawPrint.h"
#include "sead/math/seadQuat.h" #include "sead/math/seadQuat.h"
#include "server/gamemode/GameModeBase.hpp" #include "server/gamemode/GameModeBase.hpp"
#include "server/gamemode/GameModeFactory.hpp" #include "server/gamemode/GameModeManager.hpp"
#include "server/HideAndSeekConfigMenu.hpp" #include "server/hns/HideAndSeekConfigMenu.hpp"
#include "server/HideAndSeekMode.hpp" #include "server/hns/HideAndSeekMode.hpp"
SEAD_SINGLETON_DISPOSER_IMPL(Client) SEAD_SINGLETON_DISPOSER_IMPL(Client)
@ -93,8 +93,6 @@ Client::Client() {
Logger::log("%s Build Number: %s\n", playerName.name, TOSTRING(BUILDVERSTR)); Logger::log("%s Build Number: %s\n", playerName.name, TOSTRING(BUILDVERSTR));
mServerMode = GameMode::HIDEANDSEEK; // temp for testing
} }
/** /**
@ -118,39 +116,6 @@ void Client::init(al::LayoutInitInfo const &initInfo, GameDataHolderAccessor hol
} }
/**
* @brief creates and initializes the gamemode selected by either server or client settings
*
* @param initInfo init info used to initialize gamemode
*/
void Client::initMode(GameModeInitInfo const& initInfo) {
if (!sInstance) {
Logger::log("Static Instance is null!\n");
return;
}
GameModeInitInfo newInfo = initInfo;
newInfo.initServerInfo(sInstance->mServerMode, sInstance->mPuppetHolder);
GameModeFactory modeFactory("GameModeFactory");
const char* modeName = GameModeFactory::getModeString(newInfo.mMode);
if (modeName) {
auto creator = modeFactory.getCreator(modeName);
if (creator) {
sInstance->mCurMode = creator(modeName);
}
}
if (sInstance->mCurMode) {
sInstance->mCurMode->init(newInfo);
} else {
Logger::log("Failed to Create Gamemode! Mode: \n", modeName ? modeName : "Unknown");
}
}
/** /**
* @brief starts client read thread * @brief starts client read thread
* *
@ -712,13 +677,14 @@ void Client::sendTagInfPacket() {
return; return;
} }
if (sInstance->mServerMode != GameMode::HIDEANDSEEK) { HideAndSeekMode* hsMode = GameModeManager::instance()->getMode<HideAndSeekMode>();
if (!GameModeManager::instance()->isMode(GameMode::HIDEANDSEEK)) {
Logger::log("State is not Hide and Seek!\n"); Logger::log("State is not Hide and Seek!\n");
return; return;
} }
HideAndSeekMode* hsMode = (HideAndSeekMode*)sInstance->mCurMode; HideAndSeekInfo* curInfo = GameModeManager::instance()->getInfo<HideAndSeekInfo>();
HideAndSeekInfo* curInfo = (HideAndSeekInfo*)sInstance->mModeInfo;
TagInf packet = TagInf(); TagInf packet = TagInf();
@ -994,10 +960,10 @@ void Client::updateGameInfo(GameInf *packet) {
void Client::updateTagInfo(TagInf *packet) { void Client::updateTagInfo(TagInf *packet) {
// if the packet is for our player, edit info for our player // if the packet is for our player, edit info for our player
if (packet->mUserID == mUserID && mCurMode->getMode() == GameMode::HIDEANDSEEK) { if (packet->mUserID == mUserID && GameModeManager::instance()->isMode(GameMode::HIDEANDSEEK)) {
HideAndSeekMode* mMode = (HideAndSeekMode*)mCurMode; HideAndSeekMode* mMode = GameModeManager::instance()->getMode<HideAndSeekMode>();
HideAndSeekInfo* curInfo = (HideAndSeekInfo*)mModeInfo; HideAndSeekInfo* curInfo = GameModeManager::instance()->getInfo<HideAndSeekInfo>();
if (packet->updateType & TagUpdateType::STATE) { if (packet->updateType & TagUpdateType::STATE) {
mMode->setPlayerTagState(packet->isIt); mMode->setPlayerTagState(packet->isIt);
@ -1299,34 +1265,7 @@ void Client::updateStates() {
if(sInstance) { if(sInstance) {
sInstance->mPuppetHolder->update(); sInstance->mPuppetHolder->update();
if(sInstance->mCurMode && sInstance->mCurMode->isModeActive()) GameModeManager::instance()->update();
sInstance->mCurMode->update();
}
}
/**
* @brief
*
* @param state
*/
void Client::setGameActive(bool state) {
if (sInstance) {
sInstance->mIsInGame = state;
// only modify mode state if mode should be active
if (sInstance->mIsModeActive) {
bool modeActive = sInstance->mCurMode->isModeActive();
if (state && !modeActive) {
Logger::log("Resuming Current Mode.\n");
sInstance->mCurMode->begin();
} else if (!state && modeActive) {
Logger::log("Pausing Current Mode.\n");
sInstance->mCurMode->end();
}
}
} }
} }
@ -1485,66 +1424,6 @@ Shine* Client::findStageShine(int shineID) {
return nullptr; return nullptr;
} }
/**
* @brief gets the client's currently selected gamemode
*
* @return GameMode
*/
GameMode Client::getCurrentMode() {
return sInstance && sInstance->mCurMode ? sInstance->mCurMode->getMode() : GameMode::NONE;
}
/**
* @brief enables or disables currently selected gamemode
*
*/
void Client::toggleCurrentMode() {
if (!sInstance || !sInstance->mCurMode) {
return;
}
GameModeBase* curMode = sInstance->mCurMode;
if (curMode->isModeActive()) {
Logger::log("Ending Gamemode: %s\n", curMode->getName());
curMode->end();
sInstance->mIsModeActive = false;
} else {
Logger::log("Starting Gamemode: %s\n", curMode->getName());
curMode->begin();
sInstance->mIsModeActive = true;
}
}
/**
* @brief re-enables current gamemode if previously activated (if a stage reload occurs while the gamemode was previously active, this will turn it back on after initialized)
*
*/
void Client::tryRestartCurrentMode() {
if (!sInstance || !sInstance->mCurMode) {
return;
}
// restart mode if previous scene had one active
if (sInstance->mIsModeActive) {
sInstance->mCurMode->begin();
}
}
GameModeConfigMenu* Client::tryCreateModeMenu() {
if (!sInstance)
return nullptr;
switch (sInstance->mServerMode) {
case HIDEANDSEEK: {
return new HideAndSeekConfigMenu();
}
default:
return nullptr;
}
}
void Client::showConnectError(const char16_t* msg) { void Client::showConnectError(const char16_t* msg) {
if (!sInstance) if (!sInstance)
return; return;

View file

@ -0,0 +1,92 @@
#include "server/gamemode/GameModeManager.hpp"
#include <cstring>
#include <heap/seadFrameHeap.h>
#include "al/util.hpp"
#include "basis/seadNew.h"
#include "heap/seadHeapMgr.h"
#include "server/gamemode/GameModeBase.hpp"
#include "server/gamemode/GameModeFactory.hpp"
SEAD_SINGLETON_DISPOSER_IMPL(GameModeManager)
GameModeManager::GameModeManager() {
mHeap = sead::FrameHeap::create(0x100000, "GameModeHeap", al::getSequenceHeap(), 8,
sead::Heap::HeapDirection::cHeapDirection_Reverse, false);
setMode(GameMode::HIDEANDSEEK);
}
void GameModeManager::begin() {
if (mCurModeBase) {
sead::ScopedCurrentHeapSetter heapSetter(mHeap);
mCurModeBase->begin();
}
}
void GameModeManager::end() {
if (mCurModeBase) {
sead::ScopedCurrentHeapSetter heapSetter(mHeap);
mCurModeBase->end();
}
}
void GameModeManager::toggleActive() {
mActive = !mActive;
}
void GameModeManager::setPaused(bool paused) {
mPaused = paused;
}
void GameModeManager::setMode(GameMode mode) {
mCurMode = mode;
mWasSetMode = true; // recreate in initScene
}
void GameModeManager::update() {
if (!mCurModeBase) return;
bool inScene = al::getSceneHeap() != nullptr;
if ((mActive && inScene && !mPaused && !mCurModeBase->isModeActive()) || mWasSceneTrans) begin();
if ((!mActive || mPaused || !inScene) && mCurModeBase->isModeActive()) end();
mWasSceneTrans = false;
if (mCurModeBase && mCurModeBase->isModeActive()) {
sead::ScopedCurrentHeapSetter heapSetter(mHeap);
mCurModeBase->update();
}
}
void GameModeManager::initScene(const GameModeInitInfo& info) {
sead::ScopedCurrentHeapSetter heapSetter(mHeap);
if (mCurModeBase != nullptr) {
delete mCurModeBase;
}
if (mLastInitInfo != nullptr) {
delete mLastInitInfo;
}
if (mCurMode == GameMode::NONE) {
mCurModeBase = nullptr;
mModeInfo = nullptr;
return;
}
mLastInitInfo = new GameModeInitInfo(info);
if (!mCurModeBase && mWasSetMode) {
GameModeFactory factory("GameModeFactory");
const char* name = factory.getModeString(mCurMode);
mCurModeBase = factory.getCreator(name)(name);
if (mLastInitInfo) { // check if there's a previously used init info
mCurModeBase->init(*mLastInitInfo);
}
mWasSetMode = false;
}
if (mCurModeBase) {
mCurModeBase->init(*mLastInitInfo);
if (mCurModeBase->isModeActive())
mWasSceneTrans = true;
}
}

View file

@ -2,6 +2,7 @@
#include <math.h> #include <math.h>
#include "al/util/ControllerUtil.h" #include "al/util/ControllerUtil.h"
#include "server/DeltaTime.hpp" #include "server/DeltaTime.hpp"
#include "logger.hpp"
GameModeTimer::GameModeTimer(bool isCountUp, float milli, int seconds, int minutes, int hours) { GameModeTimer::GameModeTimer(bool isCountUp, float milli, int seconds, int minutes, int hours) {
mIsCountUp = isCountUp; mIsCountUp = isCountUp;
@ -24,10 +25,14 @@ GameModeTimer::GameModeTimer() {
} }
void GameModeTimer::setTime(float milli, int seconds, int minutes, int hours) { void GameModeTimer::setTime(float milli, int seconds, int minutes, int hours) {
if(milli >= 0) mTime.mMilliseconds = milli; if (milli >= 0)
if(seconds >= 0) mTime.mSeconds = seconds; mTime.mMilliseconds = milli;
if(minutes >= 0) mTime.mMinutes = minutes; if (seconds >= 0)
if(hours >= 0) mTime.mHours = hours; mTime.mSeconds = seconds;
if (minutes >= 0)
mTime.mMinutes = minutes;
if (hours >= 0)
mTime.mHours = hours;
} }
void GameModeTimer::setTime(GameTime const& time) { void GameModeTimer::setTime(GameTime const& time) {
@ -35,7 +40,6 @@ void GameModeTimer::setTime(GameTime const& time) {
} }
void GameModeTimer::updateTimer() { void GameModeTimer::updateTimer() {
if (mIsUseControl) { if (mIsUseControl) {
timerControl(); timerControl();
} }
@ -79,7 +83,14 @@ void GameModeTimer::updateTimer() {
} }
void GameModeTimer::timerControl() { void GameModeTimer::timerControl() {
if (al::isPadHoldL(-1)) {
if (al::isPadTriggerDown(-1)) {
mTime.mMilliseconds = 0;
mTime.mSeconds = 0;
mTime.mMinutes = 0;
mTime.mHours = 0;
}
} else {
if (al::isPadHoldRight(-1)) { if (al::isPadHoldRight(-1)) {
mTime.mMilliseconds = 0; mTime.mMilliseconds = 0;
mTime.mSeconds++; mTime.mSeconds++;
@ -95,6 +106,7 @@ void GameModeTimer::timerControl() {
if (al::isPadTriggerLeft(-1)) { if (al::isPadTriggerLeft(-1)) {
mTime.mMilliseconds = 0; mTime.mMilliseconds = 0;
if (mTime.mMinutes != 0) {
mTime.mSeconds--; mTime.mSeconds--;
if (mTime.mSeconds < 0) { if (mTime.mSeconds < 0) {
mTime.mSeconds = 59; mTime.mSeconds = 59;
@ -109,11 +121,6 @@ void GameModeTimer::timerControl() {
} }
} }
} }
}
if(al::isPadHoldL(-1) && al::isPadTriggerDown(-1)) {
mTime.mMilliseconds = 0;
mTime.mSeconds = 0;
mTime.mMinutes = 0;
mTime.mHours = 0;
} }
} }

View file

@ -1,7 +1,8 @@
#include "server/HideAndSeekConfigMenu.hpp" #include "server/hns/HideAndSeekConfigMenu.hpp"
#include <cmath> #include <cmath>
#include "logger.hpp" #include "logger.hpp"
#include "server/HideAndSeekMode.hpp" #include "server/gamemode/GameModeManager.hpp"
#include "server/hns/HideAndSeekMode.hpp"
#include "server/Client.hpp" #include "server/Client.hpp"
HideAndSeekConfigMenu::HideAndSeekConfigMenu() : GameModeConfigMenu() {} HideAndSeekConfigMenu::HideAndSeekConfigMenu() : GameModeConfigMenu() {}
@ -22,7 +23,7 @@ const sead::WFixedSafeString<0x200> *HideAndSeekConfigMenu::getStringData() {
bool HideAndSeekConfigMenu::updateMenu(int selectIndex) { bool HideAndSeekConfigMenu::updateMenu(int selectIndex) {
HideAndSeekInfo *curMode = (HideAndSeekInfo*)Client::getModeInfo(); HideAndSeekInfo *curMode = GameModeManager::instance()->getInfo<HideAndSeekInfo>();
Logger::log("Setting Gravity Mode.\n"); Logger::log("Setting Gravity Mode.\n");
@ -33,13 +34,13 @@ bool HideAndSeekConfigMenu::updateMenu(int selectIndex) {
switch (selectIndex) { switch (selectIndex) {
case 0: { case 0: {
if (Client::isSelectedMode(GameMode::HIDEANDSEEK)) { if (GameModeManager::instance()->isMode(GameMode::HIDEANDSEEK)) {
curMode->mIsUseGravity = true; curMode->mIsUseGravity = true;
} }
return true; return true;
} }
case 1: { case 1: {
if (Client::isSelectedMode(GameMode::HIDEANDSEEK)) { if (GameModeManager::instance()->isMode(GameMode::HIDEANDSEEK)) {
curMode->mIsUseGravity = false; curMode->mIsUseGravity = false;
} }
return true; return true;

View file

@ -1,4 +1,4 @@
#include "server/HideAndSeekMode.hpp" #include "server/hns/HideAndSeekMode.hpp"
#include <cmath> #include <cmath>
#include "al/async/FunctorV0M.hpp" #include "al/async/FunctorV0M.hpp"
#include "al/util.hpp" #include "al/util.hpp"
@ -7,15 +7,19 @@
#include "game/Layouts/CoinCounter.h" #include "game/Layouts/CoinCounter.h"
#include "game/Layouts/MapMini.h" #include "game/Layouts/MapMini.h"
#include "game/Player/PlayerActorHakoniwa.h" #include "game/Player/PlayerActorHakoniwa.h"
#include "heap/seadHeapMgr.h"
#include "layouts/HideAndSeekIcon.h" #include "layouts/HideAndSeekIcon.h"
#include "logger.hpp" #include "logger.hpp"
#include "rs/util.hpp" #include "rs/util.hpp"
#include "server/gamemode/GameModeBase.hpp" #include "server/gamemode/GameModeBase.hpp"
#include "server/Client.hpp" #include "server/Client.hpp"
#include "server/gamemode/GameModeTimer.hpp" #include "server/gamemode/GameModeTimer.hpp"
#include <heap/seadHeap.h>
#include "server/gamemode/GameModeManager.hpp"
#include "server/gamemode/GameModeFactory.hpp"
#include "basis/seadNew.h" #include "basis/seadNew.h"
#include "server/HideAndSeekConfigMenu.hpp" #include "server/hns/HideAndSeekConfigMenu.hpp"
HideAndSeekMode::HideAndSeekMode(const char* name) : GameModeBase(name) {} HideAndSeekMode::HideAndSeekMode(const char* name) : GameModeBase(name) {}
@ -25,17 +29,21 @@ void HideAndSeekMode::init(const GameModeInitInfo& info) {
mCurScene = (StageScene*)info.mScene; mCurScene = (StageScene*)info.mScene;
mPuppetHolder = info.mPuppetHolder; mPuppetHolder = info.mPuppetHolder;
GameModeInfoBase* curGameInfo = Client::getModeInfo(); GameModeInfoBase* curGameInfo = GameModeManager::instance()->getInfo<HideAndSeekInfo>();
sead::ScopedCurrentHeapSetter heapSetter(GameModeManager::instance()->getHeap());
if (curGameInfo) Logger::log("Gamemode info found: %s %s\n", GameModeFactory::getModeString(curGameInfo->mMode), GameModeFactory::getModeString(info.mMode));
else Logger::log("No gamemode info found\n");
if (curGameInfo && curGameInfo->mMode == mMode) { if (curGameInfo && curGameInfo->mMode == mMode) {
mInfo = (HideAndSeekInfo*)curGameInfo; mInfo = (HideAndSeekInfo*)curGameInfo;
mModeTimer = new GameModeTimer(mInfo->mHidingTime); mModeTimer = new GameModeTimer(mInfo->mHidingTime);
Logger::log("Reinitialized timer with time %d:%.2d\n", mInfo->mHidingTime.mMinutes, mInfo->mHidingTime.mSeconds);
} else { } else {
sead::system::DeleteImpl( if (curGameInfo) delete curGameInfo; // attempt to destory previous info before creating new one
curGameInfo); // attempt to destory previous info before creating new one
mInfo = GameModeManager::instance()->createModeInfo<HideAndSeekInfo>();
mInfo = createModeInfo<HideAndSeekInfo>();
Client::setModeInfo(mInfo);
mModeTimer = new GameModeTimer(); mModeTimer = new GameModeTimer();
} }
@ -48,7 +56,6 @@ void HideAndSeekMode::init(const GameModeInitInfo& info) {
} }
void HideAndSeekMode::begin() { void HideAndSeekMode::begin() {
mModeLayout->appear(); mModeLayout->appear();
mIsFirstFrame = true; mIsFirstFrame = true;
@ -118,10 +125,15 @@ void HideAndSeekMode::update() {
if (mInvulnTime >= 5) { if (mInvulnTime >= 5) {
if (mainPlayer) { if (mainPlayer) {
for (size_t i = 0; i < mPuppetHolder->getSize(); i++) for (int i = 0; i < mPuppetHolder->getSize(); i++)
{ {
PuppetInfo *curInfo = Client::getPuppetInfo(i); PuppetInfo *curInfo = Client::getPuppetInfo(i);
if (!curInfo) {
Logger::log("Checking %d, hit bounds %d-%d\n", i, mPuppetHolder->getSize(), Client::getMaxPlayerCount());
break;
}
if(curInfo->isConnected && curInfo->isInSameStage && curInfo->isIt) { if(curInfo->isConnected && curInfo->isInSameStage && curInfo->isIt) {
float pupDist = al::calcDistance(mainPlayer, curInfo->playerPos); // TODO: remove distance calculations and use hit sensors to determine this float pupDist = al::calcDistance(mainPlayer, curInfo->playerPos); // TODO: remove distance calculations and use hit sensors to determine this

View file

@ -12,8 +12,10 @@
#include "prim/seadStringUtil.h" #include "prim/seadStringUtil.h"
#include "rs/util/InputUtil.h" #include "rs/util/InputUtil.h"
#include "server/gamemode/GameModeBase.hpp" #include "server/gamemode/GameModeBase.hpp"
#include "server/gamemode/GameModeConfigMenuFactory.hpp"
#include "server/gamemode/GameModeFactory.hpp" #include "server/gamemode/GameModeFactory.hpp"
#include "server/HideAndSeekMode.hpp" #include "server/gamemode/GameModeManager.hpp"
#include "server/hns/HideAndSeekMode.hpp"
StageSceneStateServerConfig::StageSceneStateServerConfig(const char *name, al::Scene *scene, const al::LayoutInitInfo &initInfo, FooterParts *footerParts, GameDataHolder *dataHolder, bool) : al::HostStateBase<al::Scene>(name, scene) { StageSceneStateServerConfig::StageSceneStateServerConfig(const char *name, al::Scene *scene, const al::LayoutInitInfo &initInfo, FooterParts *footerParts, GameDataHolder *dataHolder, bool) : al::HostStateBase<al::Scene>(name, scene) {
mFooterParts = footerParts; mFooterParts = footerParts;
@ -64,19 +66,23 @@ StageSceneStateServerConfig::StageSceneStateServerConfig(const char *name, al::S
mModeSelectList->addStringData(modeSelectOptions->mBuffer, "TxtContent"); mModeSelectList->addStringData(modeSelectOptions->mBuffer, "TxtContent");
// gamemode config menu // gamemode config menu
mGamemodeConfig = new SimpleLayoutMenu("GameModeConfigMenu", "OptionSelect", initInfo, 0, false); GameModeConfigMenuFactory factory("GameModeConfigFactory");
mGameModeConfigList = new CommonVerticalList(mGamemodeConfig, initInfo, true); for (int mode = 0; mode < factory.getMenuCount(); mode++) {
GameModeEntry& entry = mGamemodeConfigMenus[mode];
const char* name = factory.getMenuName(mode);
entry.mMenu = factory.getCreator(name)(name);
entry.mLayout = new SimpleLayoutMenu("GameModeConfigMenu", "OptionSelect", initInfo, 0, false);
entry.mList = new CommonVerticalList(entry.mLayout, initInfo, true);
al::setPaneString(mGamemodeConfig, "TxtOption", u"Gamemode Configuration", 0); al::setPaneString(entry.mLayout, "TxtOption", u"Gamemode Configuration", 0);
mGamemodeConfigMenu = Client::tryCreateModeMenu(); entry.mList->initDataNoResetSelected(entry.mMenu->getMenuSize());
if (mGamemodeConfigMenu) {
mGameModeConfigList->initDataNoResetSelected(mGamemodeConfigMenu->getMenuSize());
mGameModeConfigList->addStringData(mGamemodeConfigMenu->getStringData(), "TxtContent"); entry.mList->addStringData(entry.mMenu->getStringData(), "TxtContent");
} }
mCurrentList = mMainOptionsList; mCurrentList = mMainOptionsList;
mCurrentMenu = mMainOptions; mCurrentMenu = mMainOptions;
} }
@ -224,15 +230,16 @@ void StageSceneStateServerConfig::exeRestartServer() {
void StageSceneStateServerConfig::exeGamemodeConfig() { void StageSceneStateServerConfig::exeGamemodeConfig() {
if (al::isFirstStep(this)) { if (al::isFirstStep(this)) {
mCurrentList = mGameModeConfigList; mGamemodeConfigMenu = &mGamemodeConfigMenus[GameModeManager::instance()->getGameMode()];
mCurrentMenu = mGamemodeConfig; mCurrentList = mGamemodeConfigMenu->mList;
mCurrentMenu = mGamemodeConfigMenu->mLayout;
subMenuStart(); subMenuStart();
} }
subMenuUpdate(); subMenuUpdate();
if (mIsDecideConfig && mCurrentList->isDecideEnd()) { if (mIsDecideConfig && mCurrentList->isDecideEnd()) {
if (mGamemodeConfigMenu->updateMenu(mCurrentList->mCurSelected)) { if (mGamemodeConfigMenu->mMenu->updateMenu(mCurrentList->mCurSelected)) {
endSubMenu(); endSubMenu();
} }
} }
@ -252,7 +259,7 @@ void StageSceneStateServerConfig::exeGamemodeSelect() {
if (mIsDecideConfig && mCurrentList->isDecideEnd()) { if (mIsDecideConfig && mCurrentList->isDecideEnd()) {
Logger::log("Setting Server Mode to: %d\n", mCurrentList->mCurSelected); Logger::log("Setting Server Mode to: %d\n", mCurrentList->mCurSelected);
Client::setServerMode(static_cast<GameMode>(mCurrentList->mCurSelected)); GameModeManager::instance()->setMode(static_cast<GameMode>(mCurrentList->mCurSelected));
endSubMenu(); endSubMenu();
} }
} }