SuperMarioOdysseyOnline/source/server/HideAndSeekMode.cpp
2022-06-16 14:33:18 -07:00

208 lines
No EOL
6.6 KiB
C++

#include "server/HideAndSeekMode.hpp"
#include <cmath>
#include "al/async/FunctorV0M.hpp"
#include "al/util.hpp"
#include "al/util/ControllerUtil.h"
#include "game/GameData/GameDataHolderAccessor.h"
#include "game/Layouts/CoinCounter.h"
#include "game/Layouts/MapMini.h"
#include "game/Player/PlayerActorHakoniwa.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 "basis/seadNew.h"
#include "server/HideAndSeekConfigMenu.hpp"
HideAndSeekMode::HideAndSeekMode(const char* name) : GameModeBase(name) {}
void HideAndSeekMode::init(const GameModeInitInfo& info) {
mSceneObjHolder = info.mSceneObjHolder;
mMode = info.mMode;
mCurScene = (StageScene*)info.mScene;
mPuppetHolder = info.mPuppetHolder;
GameModeInfoBase* curGameInfo = Client::getModeInfo();
if (curGameInfo && curGameInfo->mMode == mMode) {
mInfo = (HideAndSeekInfo*)curGameInfo;
mModeTimer = new GameModeTimer(mInfo->mHidingTime);
} else {
sead::system::DeleteImpl(
curGameInfo); // attempt to destory previous info before creating new one
mInfo = createModeInfo<HideAndSeekInfo>();
Client::setModeInfo(mInfo);
mModeTimer = new GameModeTimer();
}
mModeLayout = new HideAndSeekIcon("HideAndSeekIcon", *info.mLayoutInitInfo);
mModeLayout->showSeeking();
mModeTimer->disableTimer();
}
void HideAndSeekMode::begin() {
mModeLayout->appear();
mIsFirstFrame = true;
if (!mInfo->mIsPlayerIt) {
mModeTimer->enableTimer();
mModeLayout->showHiding();
} else {
mModeTimer->disableTimer();
mModeLayout->showSeeking();
}
CoinCounter *coinCollect = mCurScene->stageSceneLayout->mCoinCollectLyt;
CoinCounter* coinCounter = mCurScene->stageSceneLayout->mCoinCountLyt;
MapMini* compass = mCurScene->stageSceneLayout->mMapMiniLyt;
al::SimpleLayoutAppearWaitEnd* playGuideLyt = mCurScene->stageSceneLayout->mPlayGuideMenuLyt;
if(coinCounter->mIsAlive)
coinCounter->tryEnd();
if(coinCollect->mIsAlive)
coinCollect->tryEnd();
if (compass->mIsAlive)
compass->end();
if (playGuideLyt->mIsAlive)
playGuideLyt->end();
GameModeBase::begin();
}
void HideAndSeekMode::end() {
mModeLayout->tryEnd();
mModeTimer->disableTimer();
CoinCounter *coinCollect = mCurScene->stageSceneLayout->mCoinCollectLyt;
CoinCounter* coinCounter = mCurScene->stageSceneLayout->mCoinCountLyt;
MapMini* compass = mCurScene->stageSceneLayout->mMapMiniLyt;
al::SimpleLayoutAppearWaitEnd* playGuideLyt = mCurScene->stageSceneLayout->mPlayGuideMenuLyt;
if(!coinCounter->mIsAlive)
coinCounter->tryStart();
if(!coinCollect->mIsAlive)
coinCollect->tryStart();
if (!compass->mIsAlive)
compass->appearSlideIn();
if (!playGuideLyt->mIsAlive)
playGuideLyt->appear();
GameModeBase::end();
}
void HideAndSeekMode::update() {
PlayerActorHakoniwa* mainPlayer = rs::getPlayerActor(mCurScene);
if (mIsFirstFrame) {
if (mInfo->mIsUseGravityCam && mTicket) {
al::startCamera(mCurScene, mTicket, -1);
}
mIsFirstFrame = false;
}
if (!mInfo->mIsPlayerIt) {
if (mInvulnTime >= 5) {
if (mainPlayer) {
for (size_t i = 0; i < mPuppetHolder->getSize(); i++)
{
PuppetInfo *curInfo = Client::getPuppetInfo(i);
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
if(pupDist < 200.f && mainPlayer->mDimKeeper->is2DModel == curInfo->is2D) {
if(!PlayerFunction::isPlayerDeadStatus(mainPlayer)) {
GameDataFunction::killPlayer(GameDataHolderAccessor(this));
mainPlayer->startDemoPuppetable();
al::setVelocityZero(mainPlayer);
rs::faceToCamera(mainPlayer);
mainPlayer->mPlayerAnimator->endSubAnim();
mainPlayer->mPlayerAnimator->startAnimDead();
mInfo->mIsPlayerIt = true;
mModeTimer->disableTimer();
mModeLayout->showSeeking();
Client::sendTagInfPacket();
}
} else if (PlayerFunction::isPlayerDeadStatus(mainPlayer)) {
mInfo->mIsPlayerIt = true;
mModeTimer->disableTimer();
mModeLayout->showSeeking();
Client::sendTagInfPacket();
}
}
}
}
}else {
mInvulnTime += Time::deltaTime;
}
mModeTimer->updateTimer();
}
if (mInfo->mIsUseGravity) {
sead::Vector3f gravity;
if (rs::calcOnGroundNormalOrGravityDir(&gravity, mainPlayer, mainPlayer->mPlayerCollider)) {
gravity = -gravity;
al::normalize(&gravity);
al::setGravity(mainPlayer, gravity);
al::setGravity(mainPlayer->mHackCap, gravity);
}
if (al::isPadHoldL(-1)) {
if (al::isPadTriggerRight(-1)) {
if (al::isActiveCamera(mTicket)) {
al::endCamera(mCurScene, mTicket, -1, false);
mInfo->mIsUseGravityCam = false;
} else {
al::startCamera(mCurScene, mTicket, -1);
mInfo->mIsUseGravityCam = true;
}
}
} else if (al::isPadTriggerZL(-1)) {
if (al::isPadTriggerLeft(-1)) {
killMainPlayer(mainPlayer);
}
}
}
if (al::isPadTriggerUp(-1) && !al::isPadHoldZL(-1))
{
mInfo->mIsPlayerIt = !mInfo->mIsPlayerIt;
mModeTimer->toggleTimer();
if(!mInfo->mIsPlayerIt) {
mInvulnTime = 0;
mModeLayout->showHiding();
} else {
mModeLayout->showSeeking();
}
Client::sendTagInfPacket();
}
mInfo->mHidingTime = mModeTimer->getTime();
}