diff --git a/rwengine/include/engine/GameState.hpp b/rwengine/include/engine/GameState.hpp index ebe42c3a..f0aed28c 100644 --- a/rwengine/include/engine/GameState.hpp +++ b/rwengine/include/engine/GameState.hpp @@ -7,6 +7,7 @@ #include #include +class GameWorld; class GameObject; class PlayerController; struct CutsceneData; @@ -95,7 +96,8 @@ struct BlipData }; /** - * Global Gameplay data, that mostly persists across game saves. + * Gameplay state object that holds persistent state, and references runtime + * world state. */ struct GameState { @@ -169,6 +171,11 @@ struct GameState std::map radarBlips; + /** + * World to use for this state, this isn't saved, just used at runtime + */ + GameWorld* world; + GameState(); /** diff --git a/rwengine/include/engine/GameWorld.hpp b/rwengine/include/engine/GameWorld.hpp index 3edbd3f1..7078befe 100644 --- a/rwengine/include/engine/GameWorld.hpp +++ b/rwengine/include/engine/GameWorld.hpp @@ -7,7 +7,7 @@ class Logger; #include class GameData; -#include +class GameState; #include #include @@ -151,7 +151,7 @@ public: /** * Gameplay state */ - GameState state; + GameState* state; /** * State of playing sounds diff --git a/rwengine/include/script/ScriptMachine.hpp b/rwengine/include/script/ScriptMachine.hpp index 4b4ee6ce..5e576b89 100644 --- a/rwengine/include/script/ScriptMachine.hpp +++ b/rwengine/include/script/ScriptMachine.hpp @@ -17,7 +17,7 @@ * the native pointer size */ #define SCM_VARIABLE_SIZE sizeof(void*) -class GameWorld; +class GameState; class SCMFile; @@ -146,7 +146,7 @@ struct SCMBreakpoint class ScriptMachine { public: - ScriptMachine(GameWorld* world, SCMFile* file, SCMOpcodes* ops); + ScriptMachine(GameState* state, SCMFile* file, SCMOpcodes* ops); ~ScriptMachine(); SCMFile* getFile() const { return _file; } @@ -155,7 +155,7 @@ public: SCMByte* getGlobals(); - GameWorld* getWorld() const { return _world; } + GameState* getState() const { return state; } typedef std::function BreakpointHandler; @@ -187,7 +187,7 @@ public: private: SCMFile* _file; SCMOpcodes* _ops; - GameWorld* _world; + GameState* state; std::vector _activeThreads; diff --git a/rwengine/include/script/ScriptTypes.hpp b/rwengine/include/script/ScriptTypes.hpp index b48e31da..054b432a 100644 --- a/rwengine/include/script/ScriptTypes.hpp +++ b/rwengine/include/script/ScriptTypes.hpp @@ -11,6 +11,9 @@ class ScriptMachine; class ScriptModule; struct SCMThread; +class GameState; +class GameWorld; + typedef uint16_t SCMOpcode; typedef char SCMByte; @@ -84,7 +87,10 @@ public: const SCMParams& getParameters() const { return *parameters; } SCMThread* getThread() const { return thread; } ScriptMachine* getVM() const { return machine; } - + // Helper method to get the current state + GameState* getState() const; + GameWorld* getWorld() const; + const SCMOpcodeParameter& operator[](unsigned int arg) const { return parameters->at(arg); diff --git a/rwengine/src/engine/GameData.cpp b/rwengine/src/engine/GameData.cpp index 8d4d4fc1..897a0289 100644 --- a/rwengine/src/engine/GameData.cpp +++ b/rwengine/src/engine/GameData.cpp @@ -1,5 +1,6 @@ #include #include +#include #include #include #include @@ -551,7 +552,7 @@ void GameData::loadSplash(const std::string &name) loadTXD(lower + ".txd", false); - engine->state.currentSplash = lower; + engine->state->currentSplash = lower; } FileHandle GameData::openFile(const std::string &name) diff --git a/rwengine/src/engine/GameState.cpp b/rwengine/src/engine/GameState.cpp index 15d2e1e8..5ffeb55a 100644 --- a/rwengine/src/engine/GameState.cpp +++ b/rwengine/src/engine/GameState.cpp @@ -25,7 +25,8 @@ hour(0), minute(0), cameraNear(0.1f), cameraFixed(false), -cameraTarget(nullptr) +cameraTarget(nullptr), +world(nullptr) { } diff --git a/rwengine/src/engine/GameWorld.cpp b/rwengine/src/engine/GameWorld.cpp index 9a7cbf68..7f8841da 100644 --- a/rwengine/src/engine/GameWorld.cpp +++ b/rwengine/src/engine/GameWorld.cpp @@ -1,5 +1,6 @@ #include #include +#include #include @@ -245,8 +246,8 @@ CutsceneObject *GameWorld::createCutsceneObject(const uint16_t id, const glm::ve { if( type->second->class_type == ObjectInformation::_class("HIER") ) { - modelname = state.specialModels[id]; - texturename = state.specialModels[id]; + modelname = state->specialModels[id]; + texturename = state->specialModels[id]; } else { @@ -267,15 +268,15 @@ CutsceneObject *GameWorld::createCutsceneObject(const uint16_t id, const glm::ve if(! modelname.compare(0, specialPrefix.size(), specialPrefix) ) { auto sid = modelname.substr(specialPrefix.size()); unsigned short specialID = std::atoi(sid.c_str()); - modelname = state.specialCharacters[specialID]; - texturename = state.specialCharacters[specialID]; + modelname = state->specialCharacters[specialID]; + texturename = state->specialCharacters[specialID]; } } } } if( id == 0 ) { - modelname = state.player->getCharacter()->model->name; + modelname = state->player->getCharacter()->model->name; } // Ensure the relevant data is loaded. @@ -387,8 +388,8 @@ CharacterObject* GameWorld::createPedestrian(const uint16_t id, const glm::vec3 if(! modelname.compare(0, specialPrefix.size(), specialPrefix) ) { auto sid = modelname.substr(specialPrefix.size()); unsigned short specialID = std::atoi(sid.c_str()); - modelname = state.specialCharacters[specialID]; - texturename = state.specialCharacters[specialID]; + modelname = state->specialCharacters[specialID]; + texturename = state->specialCharacters[specialID]; } if( modelname != "null" ) { @@ -536,12 +537,12 @@ void GameWorld::doWeaponScan(const WeaponScan &scan) int GameWorld::getHour() { - return state.hour; + return state->hour; } int GameWorld::getMinute() { - return state.minute; + return state->minute; } glm::vec3 GameWorld::getGroundAtPosition(const glm::vec3 &pos) const @@ -688,18 +689,18 @@ void GameWorld::loadCutscene(const std::string &name) } - if( state.currentCutscene ) { - delete state.currentCutscene; + if( state->currentCutscene ) { + delete state->currentCutscene; } - state.currentCutscene = cutscene; - state.currentCutscene->meta.name = name; + state->currentCutscene = cutscene; + state->currentCutscene->meta.name = name; logger->info("World", "Loaded cutscene: " + name); } void GameWorld::startCutscene() { - state.cutsceneStartTime = gameTime; - state.skipCutscene = false; + state->cutsceneStartTime = gameTime; + state->skipCutscene = false; if( cutsceneAudio ) { cutsceneAudio->play(); } @@ -720,20 +721,20 @@ void GameWorld::clearCutscene() cutsceneAudio = nullptr; } - delete state.currentCutscene; - state.currentCutscene = nullptr; - state.isCinematic = false; - state.cutsceneStartTime = -1.f; + delete state->currentCutscene; + state->currentCutscene = nullptr; + state->isCinematic = false; + state->cutsceneStartTime = -1.f; } bool GameWorld::isCutsceneDone() { - if( state.currentCutscene ) { - float time = gameTime - state.cutsceneStartTime; - if( state.skipCutscene ) { + if( state->currentCutscene ) { + float time = gameTime - state->cutsceneStartTime; + if( state->skipCutscene ) { return true; } - return time > state.currentCutscene->tracks.duration; + return time > state->currentCutscene->tracks.duration; } return true; } @@ -744,7 +745,7 @@ void GameWorld::loadSpecialCharacter(const unsigned short index, const std::stri std::string lowerName(name); std::transform(lowerName.begin(), lowerName.end(), lowerName.begin(), ::tolower); /// @todo a bit more smarter than this - state.specialCharacters[index] = lowerName; + state->specialCharacters[index] = lowerName; } void GameWorld::loadSpecialModel(const unsigned short index, const std::string &name) @@ -752,7 +753,7 @@ void GameWorld::loadSpecialModel(const unsigned short index, const std::string & std::string lowerName(name); std::transform(lowerName.begin(), lowerName.end(), lowerName.begin(), ::tolower); /// @todo a bit more smarter than this - state.specialModels[index] = lowerName; + state->specialModels[index] = lowerName; } void GameWorld::disableAIPaths(AIGraphNode::NodeType type, const glm::vec3& min, const glm::vec3& max) diff --git a/rwengine/src/render/GameRenderer.cpp b/rwengine/src/render/GameRenderer.cpp index 4a02896f..65da475b 100644 --- a/rwengine/src/render/GameRenderer.cpp +++ b/rwengine/src/render/GameRenderer.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include #include @@ -247,10 +248,10 @@ void GameRenderer::renderWorld(GameWorld* world, const ViewCamera &camera, float glBindVertexArray( vao ); - float tod = world->state.hour + world->state.minute/60.f; + float tod = world->state->hour + world->state->minute/60.f; // Requires a float 0-24 - auto weatherID = static_cast(world->state.currentWeather * 24); + auto weatherID = static_cast(world->state->currentWeather * 24); auto weather = world->data->weatherLoader.getWeatherData(weatherID, tod); glm::vec3 skyTop = weather.skyTopColor; @@ -266,7 +267,7 @@ void GameRenderer::renderWorld(GameWorld* world, const ViewCamera &camera, float }; sunDirection = glm::normalize(sunDirection); - _camera.frustum.near = world->state.cameraNear; + _camera.frustum.near = world->state->cameraNear; _camera.frustum.far = weather.farClipping; auto view = _camera.getView(); @@ -380,7 +381,7 @@ void GameRenderer::renderWorld(GameWorld* world, const ViewCamera &camera, float { auto arrowTex = world->data->textures[{"copblue",""}]; auto arrowFrame = arrowModel->resource->findFrame( "arrow" ); - for( auto& blip : world->state.radarBlips ) + for( auto& blip : world->state->radarBlips ) { if( blip.second.display == BlipData::Show ) { @@ -455,21 +456,21 @@ void GameRenderer::renderWorld(GameWorld* world, const ViewCamera &camera, float glDisable(GL_DEPTH_TEST); GLuint splashTexName = 0; - auto fc = world->state.fadeColour; - if((fc.r + fc.g + fc.b) == 0 && world->state.currentSplash.size() > 0) { - auto splash = world->data->findTexture(world->state.currentSplash); + auto fc = world->state->fadeColour; + if((fc.r + fc.g + fc.b) == 0 && world->state->currentSplash.size() > 0) { + auto splash = world->data->findTexture(world->state->currentSplash); if ( splash ) { splashTexName = splash->getName(); } } - if( (world->state.isCinematic || world->state.currentCutscene ) && splashTexName != 0 ) { + if( (world->state->isCinematic || world->state->currentCutscene ) && splashTexName != 0 ) { renderLetterbox(); } - float fadeTimer = world->gameTime - world->state.fadeStart; - if( fadeTimer < world->state.fadeTime || !world->state.fadeOut ) { + float fadeTimer = world->gameTime - world->state->fadeStart; + if( fadeTimer < world->state->fadeTime || !world->state->fadeOut ) { glUseProgram(ssRectProgram); glUniform2f(ssRectOffset, 0.f, 0.f); glUniform2f(ssRectSize, 1.f, 1.f); @@ -485,11 +486,11 @@ void GameRenderer::renderWorld(GameWorld* world, const ViewCamera &camera, float } float fadeFrac = 0.f; - if( world->state.fadeTime > 0.f ) { - fadeFrac = std::min(fadeTimer / world->state.fadeTime, 1.f); + if( world->state->fadeTime > 0.f ) { + fadeFrac = std::min(fadeTimer / world->state->fadeTime, 1.f); } - float a = world->state.fadeOut ? 1.f - fadeFrac : fadeFrac; + float a = world->state->fadeOut ? 1.f - fadeFrac : fadeFrac; glm::vec4 fadeNormed(fc.r / 255.f, fc.g/ 255.f, fc.b/ 255.f, a); @@ -499,7 +500,7 @@ void GameRenderer::renderWorld(GameWorld* world, const ViewCamera &camera, float glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); } - if( (world->state.isCinematic || world->state.currentCutscene ) && splashTexName == 0 ) { + if( (world->state->isCinematic || world->state->currentCutscene ) && splashTexName == 0 ) { renderLetterbox(); } @@ -747,7 +748,7 @@ void GameRenderer::renderPickup(PickupObject *pickup) void GameRenderer::renderCutsceneObject(CutsceneObject *cutscene) { - if(!_renderWorld->state.currentCutscene) return; + if(!_renderWorld->state->currentCutscene) return; if(!cutscene->model->resource) { @@ -757,7 +758,7 @@ void GameRenderer::renderCutsceneObject(CutsceneObject *cutscene) glm::mat4 matrixModel; if( cutscene->getParentActor() ) { - matrixModel = glm::translate(matrixModel, _renderWorld->state.currentCutscene->meta.sceneOffset + glm::vec3(0.f, 0.f, 1.f)); + matrixModel = glm::translate(matrixModel, _renderWorld->state->currentCutscene->meta.sceneOffset + glm::vec3(0.f, 0.f, 1.f)); //matrixModel = cutscene->getParentActor()->getTimeAdjustedTransform(_renderAlpha); //matrixModel = glm::translate(matrixModel, glm::vec3(0.f, 0.f, 1.f)); glm::mat4 localMatrix; @@ -769,7 +770,7 @@ void GameRenderer::renderCutsceneObject(CutsceneObject *cutscene) matrixModel = matrixModel * localMatrix; } else { - matrixModel = glm::translate(matrixModel, _renderWorld->state.currentCutscene->meta.sceneOffset + glm::vec3(0.f, 0.f, 1.f)); + matrixModel = glm::translate(matrixModel, _renderWorld->state->currentCutscene->meta.sceneOffset + glm::vec3(0.f, 0.f, 1.f)); } float mindist = 100000.f; diff --git a/rwengine/src/render/MapRenderer.cpp b/rwengine/src/render/MapRenderer.cpp index eebccc11..2a11280e 100644 --- a/rwengine/src/render/MapRenderer.cpp +++ b/rwengine/src/render/MapRenderer.cpp @@ -2,6 +2,7 @@ #include #include #include +#include #include #include @@ -145,7 +146,7 @@ void MapRenderer::draw(GameWorld* world, const MapInfo& mi) renderer->setUniform(rectProg, "view", view); - for(auto& blip : world->state.radarBlips) + for(auto& blip : world->state->radarBlips) { glm::vec2 blippos( blip.second.coord ); if( blip.second.target ) @@ -157,7 +158,7 @@ void MapRenderer::draw(GameWorld* world, const MapInfo& mi) } // Draw the player blip - auto player = world->state.player; + auto player = world->state->player; if( player ) { glm::vec2 plyblip(player->getCharacter()->getPosition()); diff --git a/rwengine/src/script/ScriptMachine.cpp b/rwengine/src/script/ScriptMachine.cpp index 120b4b5c..73d93c75 100644 --- a/rwengine/src/script/ScriptMachine.cpp +++ b/rwengine/src/script/ScriptMachine.cpp @@ -175,8 +175,8 @@ void ScriptMachine::executeThread(SCMThread &t, int msPassed) } } -ScriptMachine::ScriptMachine(GameWorld *world, SCMFile *file, SCMOpcodes *ops) - : _file(file), _ops(ops), _world(world) +ScriptMachine::ScriptMachine(GameState* _state, SCMFile *file, SCMOpcodes *ops) + : _file(file), _ops(ops), state(_state) { startThread(0); auto globals = _file->getGlobalsSize() / 4; diff --git a/rwengine/src/script/ScriptTypes.cpp b/rwengine/src/script/ScriptTypes.cpp new file mode 100644 index 00000000..ffa895b0 --- /dev/null +++ b/rwengine/src/script/ScriptTypes.cpp @@ -0,0 +1,13 @@ +#include