Implemented the real server
This commit is contained in:
1 parent
931236bec0
commit
075750442f
22 files changed
+1130
-44
No files matched your search
+48
-24
@@ -85,8 +85,10 @@ namespace FRG
|
||||
Game::Game()
|
||||
: audioPlayer(std::make_unique<AudioPlayerAsync>())
|
||||
, internalGameServer()
|
||||
, gameServerHost(internalGameServer)
|
||||
, menuManager(renderer, internalGameServer, *audioPlayer)
|
||||
, localGameServerHost(internalGameServer)
|
||||
, gameServer(internalGameServer)
|
||||
, gameServerHost(localGameServerHost)
|
||||
, menuManager(renderer, gameServer, *audioPlayer)
|
||||
, newTickCount(0)
|
||||
, lastTickCount(0)
|
||||
{
|
||||
@@ -400,7 +402,7 @@ namespace FRG
|
||||
performResetToInitialState();
|
||||
applyTutorialSetting();
|
||||
const CampaignConfig& campaign = activeCampaign();
|
||||
internalGameServer.submit(
|
||||
server().submit(
|
||||
SetCurrentLocationCommand{campaign.startLocation});
|
||||
menuManager.showGameplayHud(); // first HUD frame drawn from the fresh state
|
||||
if (currentLocation()) currentLocation()->scriptEngine.callLocationEnterCallback();
|
||||
@@ -549,12 +551,27 @@ namespace FRG
|
||||
const CampaignConfig* campaign =
|
||||
CampaignRegistry::instance().find(campaignId);
|
||||
if (!campaign) return;
|
||||
#if defined(NETWORK)
|
||||
remoteCampaignActive = campaignId == "battle_zone";
|
||||
if (remoteCampaignActive) {
|
||||
websocketGameClient = std::make_unique<WebsocketGameClient>();
|
||||
remoteGameServerHost =
|
||||
std::make_unique<RemoteGameServerHost>(*websocketGameClient);
|
||||
gameServer.use(*websocketGameClient);
|
||||
gameServerHost.use(*remoteGameServerHost);
|
||||
} else {
|
||||
gameServer.use(internalGameServer);
|
||||
gameServerHost.use(localGameServerHost);
|
||||
}
|
||||
#else
|
||||
remoteCampaignActive = false;
|
||||
#endif
|
||||
gameServerHost.initializeCampaign(
|
||||
campaignId, campaign->questsPath, CONST_ZIP_FILE);
|
||||
// The player stays loaded for the whole campaign; locations come and go around him.
|
||||
player = Location::createPlayer(
|
||||
renderer, audioPlayer.get(), internalGameServer,
|
||||
internalGameServer.localPlayerId());
|
||||
renderer, audioPlayer.get(), server(),
|
||||
server().localPlayerId());
|
||||
if (player)
|
||||
player->onDeathAnimComplete = [this]() { startDarklandsTransition(); };
|
||||
}
|
||||
@@ -564,6 +581,13 @@ namespace FRG
|
||||
player.reset();
|
||||
loadedCampaignId.clear();
|
||||
gameServerHost.clearCampaign();
|
||||
#if defined(NETWORK)
|
||||
gameServer.use(internalGameServer);
|
||||
gameServerHost.use(localGameServerHost);
|
||||
remoteGameServerHost.reset();
|
||||
websocketGameClient.reset();
|
||||
#endif
|
||||
remoteCampaignActive = false;
|
||||
renderer.textureManager.UnloadUnused(); // the player's textures
|
||||
}
|
||||
|
||||
@@ -609,7 +633,7 @@ namespace FRG
|
||||
const auto state = stateSnapshot();
|
||||
if (!state) return;
|
||||
enterLocationThen(state->campaignId, destName, [this, destName, destPos, destRotY]() {
|
||||
internalGameServer.submit(SetCurrentLocationCommand{destName});
|
||||
server().submit(SetCurrentLocationCommand{destName});
|
||||
Location* loc = currentLocation();
|
||||
if (!loc) return;
|
||||
if (loc->player) {
|
||||
@@ -624,13 +648,13 @@ namespace FRG
|
||||
const float inclination = locationState
|
||||
? locationState->cameraInclination
|
||||
: 1.1036f;
|
||||
internalGameServer.submit(SetLocationCameraCommand{
|
||||
server().submit(SetLocationCameraCommand{
|
||||
destName, destRotY, inclination});
|
||||
loc->scriptEngine.callLocationEnterCallback();
|
||||
|
||||
//Reset taxi
|
||||
internalGameServer.submit(ResetTaxiCommand{destName});
|
||||
internalGameServer.submit(SetTaxiCalledCommand{false});
|
||||
server().submit(ResetTaxiCommand{destName});
|
||||
server().submit(SetTaxiCalledCommand{false});
|
||||
|
||||
menuManager.onLocationChanged(destName);
|
||||
});
|
||||
@@ -693,7 +717,7 @@ namespace FRG
|
||||
// (if the campaign has one); a disabled tutorial is simply one that is already completed.
|
||||
void Game::applyTutorialSetting() {
|
||||
if (!activeCampaign().tutorial || !menuManager.tutorialEnabledSetting)
|
||||
internalGameServer.submit(
|
||||
server().submit(
|
||||
SetTutorialStepCommand{TutorialStep::Completed});
|
||||
}
|
||||
|
||||
@@ -731,20 +755,20 @@ namespace FRG
|
||||
params.player = player;
|
||||
|
||||
auto loc = std::make_shared<Location>(
|
||||
renderer, internalGameServer, config.id);
|
||||
renderer, server(), config.id);
|
||||
gameServerHost.setupRuntimeLocation(
|
||||
config.id, loc, std::move(params), audioPlayer.get());
|
||||
loc->requestNightDayTransition = [this](bool isNight, bool isDawn) {
|
||||
const auto state = stateSnapshot();
|
||||
if (!state) return;
|
||||
internalGameServer.submit(SetWorldModeCommand{
|
||||
server().submit(SetWorldModeCommand{
|
||||
state->isDarklands, isNight, isDawn});
|
||||
};
|
||||
loc->requestDarklandsTransition = [this]() { return startDarklandsTransition(); };
|
||||
loc->requestAdvanceDarklandsHud = [this]() { menuManager.advanceUniIntDarklandsHud(); };
|
||||
loc->requestClosePhone = [this]() { menuManager.closePhoneEntirely(); };
|
||||
loc->requestReturnToMainMenu = [this]() {
|
||||
internalGameServer.submit(SetCurrentLocationCommand{std::string()});
|
||||
server().submit(SetCurrentLocationCommand{std::string()});
|
||||
menuManager.showMenuAfterGameCompleted();
|
||||
};
|
||||
loc->requestSetChatUnread = [this](int idx, bool unread, const std::string& msg) {
|
||||
@@ -783,11 +807,11 @@ namespace FRG
|
||||
// completeTutorialStep() only acts on the current step, so sharing is safe.
|
||||
{
|
||||
loc->dialogueSystem.setOnDialogueAdvanced([this]() {
|
||||
internalGameServer.submit(
|
||||
server().submit(
|
||||
CompleteTutorialStepCommand{TutorialStep::AdvanceDialogue});
|
||||
});
|
||||
loc->onPlayerFloorWalk = [this]() {
|
||||
internalGameServer.submit(
|
||||
server().submit(
|
||||
CompleteTutorialStepCommand{TutorialStep::Walk});
|
||||
menuManager.onPlayerStartedWalking();
|
||||
};
|
||||
@@ -840,9 +864,9 @@ namespace FRG
|
||||
loc->player->isMoving() == false
|
||||
&&
|
||||
loc->player->getHp() > 0) {
|
||||
internalGameServer.submit(SetCharacterTargetCommand{
|
||||
server().submit(SetCharacterTargetCommand{
|
||||
loc->locationId(),
|
||||
internalGameServer.localPlayerId(), attackerId});
|
||||
server().localPlayerId(), attackerId});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1134,7 +1158,7 @@ namespace FRG
|
||||
if (!menuManager.isMainMenuOpen())
|
||||
menuManager.update(static_cast<float>(delta));
|
||||
|
||||
if (loadingCompleted && currentLocation())
|
||||
if (loadingCompleted)
|
||||
{
|
||||
// The authoritative implementation advances simulation; a future
|
||||
// network client can use the same call to poll/apply server updates.
|
||||
@@ -1147,7 +1171,7 @@ namespace FRG
|
||||
|
||||
void Game::processServerEvents()
|
||||
{
|
||||
for (GameServerEvent& event : internalGameServer.drainEvents()) {
|
||||
for (GameServerEvent& event : server().drainEvents()) {
|
||||
std::visit([this](const auto& value) {
|
||||
using T = std::decay_t<decltype(value)>;
|
||||
if constexpr (std::is_same_v<T, InventoryItemAddedEvent>) {
|
||||
@@ -1380,7 +1404,7 @@ namespace FRG
|
||||
}
|
||||
//logger() << "Current zoom: " << Environment::zoom << std::endl;
|
||||
// Tutorial: any mouse-wheel scroll counts as the "zoom gesture".
|
||||
internalGameServer.submit(
|
||||
server().submit(
|
||||
CompleteTutorialStepCommand{TutorialStep::Zoom});
|
||||
}
|
||||
|
||||
@@ -1564,7 +1588,7 @@ namespace FRG
|
||||
|
||||
// Tutorial: detect a significant pinch-zoom (≥ 2 zoom units).
|
||||
if (std::abs(Environment::zoom - pinchStartZoom) >= 2.0f) {
|
||||
internalGameServer.submit(
|
||||
server().submit(
|
||||
CompleteTutorialStepCommand{TutorialStep::Zoom});
|
||||
}
|
||||
}
|
||||
@@ -1717,7 +1741,7 @@ namespace FRG
|
||||
float deltaAz = std::abs(state->cameraAzimuth - dragStartAzimuth);
|
||||
float deltaInc = std::abs(state->cameraInclination - dragStartInclination);
|
||||
if (deltaAz >= TUTORIAL_ROTATION_THRESHOLD && deltaInc >= TUTORIAL_ROTATION_THRESHOLD) {
|
||||
internalGameServer.submit(
|
||||
server().submit(
|
||||
CompleteTutorialStepCommand{TutorialStep::RotateCamera});
|
||||
}
|
||||
}
|
||||
@@ -1770,7 +1794,7 @@ namespace FRG
|
||||
const auto before = stateSnapshot();
|
||||
if (!before) return;
|
||||
if (isNightTransition) {
|
||||
internalGameServer.submit(SetWorldModeCommand{
|
||||
server().submit(SetWorldModeCommand{
|
||||
before->isDarklands, !before->isNight, before->isDawn});
|
||||
if (currentLocation())
|
||||
{
|
||||
@@ -1781,7 +1805,7 @@ namespace FRG
|
||||
menuManager.lastMusicTrack = "music/bishkek night.ogg";
|
||||
|
||||
} else {
|
||||
internalGameServer.submit(SetWorldModeCommand{
|
||||
server().submit(SetWorldModeCommand{
|
||||
!before->isDarklands, before->isNight, before->isDawn});
|
||||
const auto after = stateSnapshot();
|
||||
if (!after) return;
|
||||
|
||||
Reference in new issue
Block a user