This commit is contained in:
CraftyBoss 2022-08-10 14:40:16 -07:00
commit 550b82fc1f
21 changed files with 346 additions and 299 deletions

View File

@ -32,7 +32,7 @@ include $(DEVKITPRO)/libnx/switch_rules
#---------------------------------------------------------------------------------
TARGET ?= $(notdir $(CURDIR))$(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
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)
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)
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);
sead::Heap *getCurrentHeap(void);
sead::Heap* getStationedHeap();
sead::Heap* getSequenceHeap();
sead::Heap* getSceneHeap();
al::Projection *getProjection(al::IUseCamera const *, int);

View File

@ -17,6 +17,7 @@
#include "logger.hpp"
#include "server/gamemode/GameModeConfigMenu.hpp"
#include "server/gamemode/GameModeConfigMenuFactory.hpp"
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
SimpleLayoutMenu* mMainOptions = 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
SimpleLayoutMenu* mModeSelect = 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;
};

View File

@ -96,8 +96,6 @@ class Client {
static bool isNeedUpdateShines();
bool isShineCollected(int shineId);
static void initMode(GameModeInitInfo const &initInfo);
static void sendHackCapInfPacket(const HackCap *hackCap);
static void sendPlayerInfPacket(const PlayerActorBase *player, bool isYukimaru);
static void sendGameInfPacket(const PlayerActorHakoniwa *player, GameDataHolderAccessor holder);
@ -110,8 +108,6 @@ class Client {
int getCollectedShinesCount() { return curCollectedShines.size(); }
int getShineID(int index) { if (index < curCollectedShines.size()) { return curCollectedShines[index]; } return -1; }
static void setGameActive(bool state);
static void setStageInfo(GameDataHolderAccessor holder);
static bool tryAddPuppet(PuppetActor *puppet);
@ -130,27 +126,8 @@ class Client {
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 void toggleCurrentMode();
static void updateStates();
static void clearArrays();
@ -173,6 +150,12 @@ class Client {
return 0;
}
static PuppetHolder* getPuppetHolder() {
if (sInstance)
return sInstance->mPuppetHolder;
return nullptr;
}
static void setSceneInfo(const al::ActorInitInfo& initInfo, const StageScene *stageScene);
static bool tryRegisterShine(Shine* shine);
@ -184,23 +167,6 @@ class Client {
static bool openKeyboardIP();
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 showConnectError(const char16_t* msg);
@ -295,21 +261,11 @@ class Client {
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 ---
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;

View File

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

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
#include "al/factory/Factory.h"
#include "layouts/HideAndSeekIcon.h"
#include "server/gamemode/GameModeBase.hpp"
#include "server/HideAndSeekMode.hpp"
#include "server/hns/HideAndSeekMode.hpp"
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
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 nullptr;
}
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 nullptr;
}
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 nullptr;
}

View File

@ -1,21 +1,11 @@
#pragma once
#include "server/gamemode/GameModeBase.hpp"
#include <heap/seadHeap.h>
// base struct containing info about the current gamemode
struct GameModeInfoBase {
GameMode mMode;
};
template<class T>
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();
}
}
#include "server/gamemode/GameModeManager.hpp"

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
#include "gamemode/GameModeConfigMenu.hpp"
#include "server/gamemode/GameModeConfigMenu.hpp"
#include "game/Layouts/CommonVerticalList.h"
#include "server/gamemode/GameModeBase.hpp"

View File

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

View File

@ -26,10 +26,10 @@
#include "math/seadVector.h"
#include "rs/util/InputUtil.h"
#include "sead/prim/seadSafeString.h"
#include "server/HideAndSeekMode.hpp"
#include "server/hns/HideAndSeekMode.hpp"
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);
} else {
return al::isPadTriggerDown(port);
@ -110,19 +110,19 @@ void initNerveStateHook(StageSceneStatePauseMenu* stateParent, StageSceneStateOp
// skips starting both coin counters
void startCounterHook(CoinCounter* thisPtr) {
if (!Client::isModeActive()) {
if (!GameModeManager::instance()->isActive()) {
thisPtr->tryStart();
}
}
// Simple hook that can be used to override isModeE3 checks to enable/disable certain behaviors
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
void playGuideEndHook(al::SimpleLayoutAppearWaitEnd* thisPtr) {
if (!Client::isModeActive()) {
if (!GameModeManager::instance()->isActive()) {
thisPtr->end();
}
}
@ -135,14 +135,14 @@ void initHackCapHook(al::LiveActor *cappy) {
al::PlayerHolder* createTicketHook(StageScene* curScene) {
// 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();
if (director) {
if (director->mFactory) {
al::CameraTicket* gravityCamera = director->createCameraFromFactory(
"CameraPoserCustom", nullptr, 0, 5, sead::Matrix34f::ident);
HideAndSeekMode* mode = Client::getMode<HideAndSeekMode>();
HideAndSeekMode* mode = GameModeManager::instance()->getMode<HideAndSeekMode>();
mode->setCameraTicket(gravityCamera);
}
@ -157,9 +157,9 @@ bool borderPullBackHook(WorldEndBorderKeeper* thisPtr) {
bool isFirstStep = al::isFirstStep(thisPtr);
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()) {
killMainPlayer(thisPtr->mActor);

View File

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

View File

@ -25,7 +25,8 @@
#include "logger.hpp"
#include "rs/util.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 gameInfSendTimer = 0;
@ -270,10 +271,11 @@ void stageInitHook(al::ActorInitInfo *info, StageScene *curScene, al::PlacementI
Client::setSceneInfo(*info, curScene);
if (Client::getServerMode() != NONE) {
if (GameModeManager::instance()->getGameMode() != NONE) {
GameModeInitInfo initModeInfo(info, curScene);
initModeInfo.initServerInfo(GameModeManager::instance()->getGameMode(), Client::getPuppetHolder());
Client::initMode(initModeInfo);
GameModeManager::instance()->initScene(initModeInfo);
}
Client::sendGameInfPacket(info->mActorSceneInfo.mSceneObjHolder);
@ -296,6 +298,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
Client::createInstance(al::getCurrentHeap());
GameModeManager::createInstance(al::getCurrentHeap()); // Create the GameModeManager on the current al heap
return 0x20;
}
@ -320,16 +323,12 @@ bool hakoniwaSequenceHook(HakoniwaSequence* sequence) {
al::PlayerHolder *pHolder = al::getScenePlayerHolder(stageScene);
PlayerActorBase* playerBase = al::tryGetPlayerActor(pHolder, 0);
if (isFirstStep) {
Client::tryRestartCurrentMode();
}
bool isYukimaru = !playerBase->getPlayerInfo();
isInGame = !stageScene->isPause();
Client::setGameActive(!stageScene->isPause());
GameModeManager::instance()->setPaused(stageScene->isPause());
Client::setStageInfo(stageScene->mHolder);
Client::updateStates();
@ -365,7 +364,7 @@ bool hakoniwaSequenceHook(HakoniwaSequence* sequence) {
}
} else if (al::isPadHoldL(-1)) {
if (al::isPadTriggerLeft(-1)) Client::toggleCurrentMode();
if (al::isPadTriggerLeft(-1)) GameModeManager::instance()->toggleActive();
if (al::isPadTriggerRight(-1)) {
if (debugMode) {

View File

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

View File

@ -36,9 +36,9 @@
#include "sead/basis/seadRawPrint.h"
#include "sead/math/seadQuat.h"
#include "server/gamemode/GameModeBase.hpp"
#include "server/gamemode/GameModeFactory.hpp"
#include "server/HideAndSeekConfigMenu.hpp"
#include "server/HideAndSeekMode.hpp"
#include "server/gamemode/GameModeManager.hpp"
#include "server/hns/HideAndSeekConfigMenu.hpp"
#include "server/hns/HideAndSeekMode.hpp"
SEAD_SINGLETON_DISPOSER_IMPL(Client)
@ -94,8 +94,6 @@ Client::Client() {
Logger::log("%s Build Number: %s\n", playerName.name, TOSTRING(BUILDVERSTR));
mServerMode = GameMode::HIDEANDSEEK; // temp for testing
}
/**
@ -119,39 +117,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
*
@ -728,13 +693,14 @@ void Client::sendTagInfPacket() {
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");
return;
}
HideAndSeekMode* hsMode = (HideAndSeekMode*)sInstance->mCurMode;
HideAndSeekInfo* curInfo = (HideAndSeekInfo*)sInstance->mModeInfo;
HideAndSeekInfo* curInfo = GameModeManager::instance()->getInfo<HideAndSeekInfo>();
TagInf packet = TagInf();
@ -1010,10 +976,10 @@ void Client::updateGameInfo(GameInf *packet) {
void Client::updateTagInfo(TagInf *packet) {
// 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;
HideAndSeekInfo* curInfo = (HideAndSeekInfo*)mModeInfo;
HideAndSeekMode* mMode = GameModeManager::instance()->getMode<HideAndSeekMode>();
HideAndSeekInfo* curInfo = GameModeManager::instance()->getInfo<HideAndSeekInfo>();
if (packet->updateType & TagUpdateType::STATE) {
mMode->setPlayerTagState(packet->isIt);
@ -1315,34 +1281,7 @@ void Client::updateStates() {
if(sInstance) {
sInstance->mPuppetHolder->update();
if(sInstance->mCurMode && sInstance->mCurMode->isModeActive())
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();
}
}
GameModeManager::instance()->update();
}
}
@ -1501,66 +1440,6 @@ Shine* Client::findStageShine(int shineID) {
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) {
if (!sInstance)
return;

View File

@ -0,0 +1,91 @@
#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 && mWasSetMode) {
delete mCurModeBase;
mCurModeBase = nullptr;
}
if (mLastInitInfo != nullptr) {
delete mLastInitInfo;
}
if (mCurMode == GameMode::NONE) {
mCurModeBase = nullptr;
delete mModeInfo;
mModeInfo = nullptr;
return;
}
mLastInitInfo = new GameModeInitInfo(info);
if (mWasSetMode) {
GameModeFactory factory("GameModeFactory");
const char* name = factory.getModeString(mCurMode);
mCurModeBase = factory.getCreator(name)(name);
mWasSetMode = false;
}
if (mCurModeBase) {
mCurModeBase->init(*mLastInitInfo);
if (mCurModeBase->isModeActive())
mWasSceneTrans = true;
}
}

View File

@ -2,6 +2,7 @@
#include <math.h>
#include "al/util/ControllerUtil.h"
#include "server/DeltaTime.hpp"
#include "logger.hpp"
GameModeTimer::GameModeTimer(bool isCountUp, float milli, int seconds, int minutes, int hours) {
mIsCountUp = isCountUp;
@ -24,10 +25,14 @@ GameModeTimer::GameModeTimer() {
}
void GameModeTimer::setTime(float milli, int seconds, int minutes, int hours) {
if(milli >= 0) mTime.mMilliseconds = milli;
if(seconds >= 0) mTime.mSeconds = seconds;
if(minutes >= 0) mTime.mMinutes = minutes;
if(hours >= 0) mTime.mHours = hours;
if (milli >= 0)
mTime.mMilliseconds = milli;
if (seconds >= 0)
mTime.mSeconds = seconds;
if (minutes >= 0)
mTime.mMinutes = minutes;
if (hours >= 0)
mTime.mHours = hours;
}
void GameModeTimer::setTime(GameTime const& time) {
@ -35,7 +40,6 @@ void GameModeTimer::setTime(GameTime const& time) {
}
void GameModeTimer::updateTimer() {
if (mIsUseControl) {
timerControl();
}
@ -43,11 +47,11 @@ void GameModeTimer::updateTimer() {
if (mIsEnabled) {
if (mIsCountUp) {
mTime.mMilliseconds += Time::deltaTime;
if(mTime.mMilliseconds >= 1) {
if (mTime.mMilliseconds >= 1) {
mTime.mMilliseconds--;
mTime.mSeconds++;
if(mTime.mSeconds >= 60) {
if (mTime.mSeconds >= 60) {
mTime.mSeconds = 0;
mTime.mMinutes++;
if (mTime.mMinutes >= 60) {
@ -61,7 +65,7 @@ void GameModeTimer::updateTimer() {
if (mTime.mMilliseconds >= 1) {
mTime.mMilliseconds--;
mTime.mSeconds--;
if(mTime.mSeconds < 0) {
if (mTime.mSeconds < 0) {
mTime.mSeconds = 59;
mTime.mMinutes--;
if (mTime.mMinutes < 0) {
@ -79,41 +83,44 @@ void GameModeTimer::updateTimer() {
}
void GameModeTimer::timerControl() {
if(al::isPadHoldRight(-1)) {
mTime.mMilliseconds = 0;
mTime.mSeconds++;
if(mTime.mSeconds >= 60) {
if (al::isPadHoldL(-1)) {
if (al::isPadTriggerDown(-1)) {
mTime.mMilliseconds = 0;
mTime.mSeconds = 0;
mTime.mMinutes++;
if (mTime.mMinutes >= 60) {
mTime.mMinutes = 0;
mTime.mHours++;
mTime.mMinutes = 0;
mTime.mHours = 0;
}
} else {
if (al::isPadHoldRight(-1)) {
mTime.mMilliseconds = 0;
mTime.mSeconds++;
if (mTime.mSeconds >= 60) {
mTime.mSeconds = 0;
mTime.mMinutes++;
if (mTime.mMinutes >= 60) {
mTime.mMinutes = 0;
mTime.mHours++;
}
}
}
}
if(al::isPadTriggerLeft(-1)) {
mTime.mMilliseconds = 0;
mTime.mSeconds--;
if(mTime.mSeconds < 0) {
mTime.mSeconds = 59;
mTime.mMinutes--;
if (mTime.mMinutes < 0) {
if (mTime.mHours > 0) {
mTime.mMinutes = 59;
mTime.mHours--;
} else {
mTime.mMinutes = 0;
if (al::isPadTriggerLeft(-1)) {
mTime.mMilliseconds = 0;
if (mTime.mMinutes != 0) {
mTime.mSeconds--;
if (mTime.mSeconds < 0) {
mTime.mSeconds = 59;
mTime.mMinutes--;
if (mTime.mMinutes < 0) {
if (mTime.mHours > 0) {
mTime.mMinutes = 59;
mTime.mHours--;
} else {
mTime.mMinutes = 0;
}
}
}
}
}
}
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 "logger.hpp"
#include "server/HideAndSeekMode.hpp"
#include "server/gamemode/GameModeManager.hpp"
#include "server/hns/HideAndSeekMode.hpp"
#include "server/Client.hpp"
HideAndSeekConfigMenu::HideAndSeekConfigMenu() : GameModeConfigMenu() {}
@ -22,7 +23,7 @@ const sead::WFixedSafeString<0x200> *HideAndSeekConfigMenu::getStringData() {
bool HideAndSeekConfigMenu::updateMenu(int selectIndex) {
HideAndSeekInfo *curMode = (HideAndSeekInfo*)Client::getModeInfo();
HideAndSeekInfo *curMode = GameModeManager::instance()->getInfo<HideAndSeekInfo>();
Logger::log("Setting Gravity Mode.\n");
@ -33,13 +34,13 @@ bool HideAndSeekConfigMenu::updateMenu(int selectIndex) {
switch (selectIndex) {
case 0: {
if (Client::isSelectedMode(GameMode::HIDEANDSEEK)) {
if (GameModeManager::instance()->isMode(GameMode::HIDEANDSEEK)) {
curMode->mIsUseGravity = true;
}
return true;
}
case 1: {
if (Client::isSelectedMode(GameMode::HIDEANDSEEK)) {
if (GameModeManager::instance()->isMode(GameMode::HIDEANDSEEK)) {
curMode->mIsUseGravity = false;
}
return true;

View File

@ -1,4 +1,4 @@
#include "server/HideAndSeekMode.hpp"
#include "server/hns/HideAndSeekMode.hpp"
#include <cmath>
#include "al/async/FunctorV0M.hpp"
#include "al/util.hpp"
@ -8,15 +8,19 @@
#include "game/Layouts/MapMini.h"
#include "game/Player/PlayerActorBase.h"
#include "game/Player/PlayerActorHakoniwa.h"
#include "heap/seadHeapMgr.h"
#include "layouts/HideAndSeekIcon.h"
#include "logger.hpp"
#include "rs/util.hpp"
#include "server/gamemode/GameModeBase.hpp"
#include "server/Client.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 "server/HideAndSeekConfigMenu.hpp"
#include "server/hns/HideAndSeekConfigMenu.hpp"
HideAndSeekMode::HideAndSeekMode(const char* name) : GameModeBase(name) {}
@ -26,17 +30,21 @@ void HideAndSeekMode::init(const GameModeInitInfo& info) {
mCurScene = (StageScene*)info.mScene;
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) {
mInfo = (HideAndSeekInfo*)curGameInfo;
mModeTimer = new GameModeTimer(mInfo->mHidingTime);
Logger::log("Reinitialized timer with time %d:%.2d\n", mInfo->mHidingTime.mMinutes, mInfo->mHidingTime.mSeconds);
} else {
sead::system::DeleteImpl(
curGameInfo); // attempt to destory previous info before creating new one
if (curGameInfo) delete curGameInfo; // attempt to destory previous info before creating new one
mInfo = GameModeManager::instance()->createModeInfo<HideAndSeekInfo>();
mInfo = createModeInfo<HideAndSeekInfo>();
Client::setModeInfo(mInfo);
mModeTimer = new GameModeTimer();
}
@ -49,7 +57,6 @@ void HideAndSeekMode::init(const GameModeInitInfo& info) {
}
void HideAndSeekMode::begin() {
mModeLayout->appear();
mIsFirstFrame = true;
@ -125,6 +132,11 @@ void HideAndSeekMode::update() {
{
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) {
float pupDist = al::calcDistance(playerBase, curInfo->playerPos); // TODO: remove distance calculations and use hit sensors to determine this

View File

@ -16,8 +16,10 @@
#include "prim/seadStringUtil.h"
#include "rs/util/InputUtil.h"
#include "server/gamemode/GameModeBase.hpp"
#include "server/gamemode/GameModeConfigMenuFactory.hpp"
#include "server/gamemode/GameModeFactory.hpp"
#include "server/HideAndSeekMode.hpp"
#include "server/gamemode/GameModeManager.hpp"
#include "server/hns/HideAndSeekMode.hpp"
// WIP work on RollPartsData, not exactly working out atm
const char16_t* testValues[] = {u"Test 1", u"Test 2", u"Test 3", u"Test 4", u"Test 5",
@ -90,19 +92,23 @@ StageSceneStateServerConfig::StageSceneStateServerConfig(const char *name, al::S
mModeSelectList->addStringData(modeSelectOptions->mBuffer, "TxtContent");
// gamemode config menu
mGamemodeConfig = new SimpleLayoutMenu("GameModeConfigMenu", "OptionSelect", initInfo, 0, false);
mGameModeConfigList = new CommonVerticalList(mGamemodeConfig, initInfo, true);
GameModeConfigMenuFactory factory("GameModeConfigFactory");
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;
mCurrentMenu = mMainOptions;
}
@ -250,15 +256,16 @@ void StageSceneStateServerConfig::exeRestartServer() {
void StageSceneStateServerConfig::exeGamemodeConfig() {
if (al::isFirstStep(this)) {
mCurrentList = mGameModeConfigList;
mCurrentMenu = mGamemodeConfig;
mGamemodeConfigMenu = &mGamemodeConfigMenus[GameModeManager::instance()->getGameMode()];
mCurrentList = mGamemodeConfigMenu->mList;
mCurrentMenu = mGamemodeConfigMenu->mLayout;
subMenuStart();
}
subMenuUpdate();
if (mIsDecideConfig && mCurrentList->isDecideEnd()) {
if (mGamemodeConfigMenu->updateMenu(mCurrentList->mCurSelected)) {
if (mGamemodeConfigMenu->mMenu->updateMenu(mCurrentList->mCurSelected)) {
endSubMenu();
}
}
@ -278,7 +285,7 @@ void StageSceneStateServerConfig::exeGamemodeSelect() {
if (mIsDecideConfig && mCurrentList->isDecideEnd()) {
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();
}
}