diff --git a/rwengine/CMakeLists.txt b/rwengine/CMakeLists.txt index 3e26782b..8ae50486 100644 --- a/rwengine/CMakeLists.txt +++ b/rwengine/CMakeLists.txt @@ -61,6 +61,8 @@ set(RWENGINE_SOURCES src/engine/GameState.hpp src/engine/GameWorld.cpp src/engine/GameWorld.hpp + src/engine/GarageController.cpp + src/engine/GarageController.hpp src/engine/SaveGame.cpp src/engine/SaveGame.hpp src/engine/ScreenText.cpp diff --git a/rwengine/src/data/ModelData.hpp b/rwengine/src/data/ModelData.hpp index 13fe973a..b9f3ff84 100644 --- a/rwengine/src/data/ModelData.hpp +++ b/rwengine/src/data/ModelData.hpp @@ -1,11 +1,12 @@ #ifndef _RWENGINE_MODELDATA_HPP_ #define _RWENGINE_MODELDATA_HPP_ -#include #include +#include #include #include #include #include +#include #include #include @@ -114,6 +115,20 @@ private: using ModelInfoTable = std::unordered_map>; +const static std::unordered_set doorModels = { + "oddjgaragdoor", "bombdoor", "door_bombshop", + "vheistlocdoor", "door2_garage", "ind_slidedoor", + "bankjobdoor", "door_jmsgrage", "jamesgrge_kb", + "door_sfehousegrge", "shedgaragedoor", "door4_garage", + "door_col_compnd_01", "door_col_compnd_02", "door_col_compnd_03", + "door_col_compnd_04", "door_col_compnd_05", "impex_door", + "SalvGarage", "door3_garage", "leveldoor2", + "double_garage_dr", "amcogaragedoor", "towergaragedoor1", + "towergaragedoor2", "towergaragedoor3", "plysve_gragedoor", + "impexpsubgrgdoor", "Sub_sprayshopdoor", "ind_plyrwoor", + "8ballsuburbandoor", "crushercrush", "crushertop", +}; + /** * Model data for simple types * @@ -249,6 +264,10 @@ public: return related_; } + static bool isDoorModel(std::string m) { + return doorModels.find(m) != doorModels.end(); + } + private: ClumpPtr model_; std::array atomics_; @@ -301,7 +320,6 @@ private: ClumpPtr model_ = nullptr; }; - enum class ComponentRuleType { Any = 1, RainOnly = 2, diff --git a/rwengine/src/engine/GameState.hpp b/rwengine/src/engine/GameState.hpp index fd22d9ca..da530d2e 100644 --- a/rwengine/src/engine/GameState.hpp +++ b/rwengine/src/engine/GameState.hpp @@ -13,6 +13,7 @@ #include #include #include + #include #include #include @@ -208,40 +209,49 @@ struct BlipData { } }; +enum class GarageType { + Mission = 1, + BombShop1 = 2, + BombShop2 = 3, + BombShop3 = 4, + Respray = 5, + CollectCars1 = 8, + CollectCars2 = 9, + MissionForCarToComeOut = 11, + Crusher = 13, + MissionKeepCar = 14, + Hideout1 = 16, + Hideout2 = 17, + Hideout3 = 18, + MissionToOpenAndClose = 19, + MissionForSpecificCar = 20, + MissionKeepCarAndRemainClosed = 21, +}; + +enum class GarageState { Closed, Closing, Opening, Opened }; + /** * Data for garages */ struct GarageInfo { - enum /*GarageType*/ { - GARAGE_MISSION = 1, - GARAGE_BOMBSHOP1 = 2, - GARAGE_BOMBSHOP2 = 3, - GARAGE_BOMBSHOP3 = 4, - GARAGE_RESPRAY = 5, - GARAGE_INVALID = 6, - GARAGE_SPECIFIC_CARS_ONLY = 7, /* See Opcode 0x21B */ - GARAGE_COLLECTCARS1 = 8, /* See Opcode 0x03D4 */ - GARAGE_COLLECTCARS2 = 9, - GARAGE_COLLECTCARS3 = 10, /* Unused */ - GARAGE_OPENFOREXIT = 11, - GARAGE_INVALID2 = 12, - GARAGE_CRUSHER = 13, - GARAGE_MISSION_KEEPCAR = 14, - GARAGE_FOR_SCRIPT = 15, - GARAGE_HIDEOUT_ONE = 16, /* Portland */ - GARAGE_HIDEOUT_TWO = 17, /* Staunton */ - GARAGE_HIDEOUT_THREE = 18, /* Shoreside */ - GARAGE_FOR_SCRIPT2 = 19, - GARAGE_OPENS_FOR_SPECIFIC_CAR = 20, - GARAGE_OPENS_ONCE = 21 - }; + GarageType type; + int id; glm::vec3 min; glm::vec3 max; - int type; - GarageInfo(int id_, const glm::vec3 min_, const glm::vec3 max_, int type_) - : id(id_), min(min_), max(max_), type(type_) { + GameObject* target; + + GarageState state; + + GarageInfo(int id_, const glm::vec3 min_, const glm::vec3 max_, + GarageType type_) + : type(type_) + , id(id_) + , min(min_) + , max(max_) + , target(nullptr) + , state(GarageState::Closed) { } int getScriptObjectID() const { diff --git a/rwengine/src/engine/GameWorld.cpp b/rwengine/src/engine/GameWorld.cpp index 4273714a..553e94cf 100644 --- a/rwengine/src/engine/GameWorld.cpp +++ b/rwengine/src/engine/GameWorld.cpp @@ -371,6 +371,79 @@ PickupObject* GameWorld::createPickup(const glm::vec3& pos, int id, int type) { return pickup; } +GarageInfo* GameWorld::createGarage(const glm::vec3 coord0, + const glm::vec3 coord1, const int type) { + glm::vec3 min; + glm::vec3 max; + glm::vec3 midpoint; + + min.x = std::min(coord0.x, coord1.x); + min.y = std::min(coord0.y, coord1.y); + min.z = std::min(coord0.z, coord1.z); + + max.x = std::max(coord0.x, coord1.x); + max.y = std::max(coord0.y, coord1.y); + max.z = std::max(coord0.z, coord1.z); + + midpoint.x = (min.x + max.x) / 2; + midpoint.y = (min.y + max.y) / 2; + midpoint.z = (min.z + max.z) / 2; + + // Find door object for this garage + InstanceObject* door = nullptr; + + for (auto p : instancePool.objects) { + auto o = p.second; + if (!o->getModel()) continue; + if (!SimpleModelInfo::isDoorModel( + o->getModelInfo()->name)) + continue; + + // Is this how the game finds door object? + if (glm::distance(midpoint, o->getPosition()) < 20.f) { + door = static_cast(o); + } + } + + // Create garage + int id = state->garages.size(); + GarageInfo* info = + new GarageInfo{id, min, max, static_cast(type)}; + state->garages.push_back(*info); + + switch (static_cast(type)) { + case GarageType::Mission: + case GarageType::CollectCars1: + case GarageType::CollectCars2: + case GarageType::MissionForCarToComeOut: + case GarageType::MissionKeepCar: + case GarageType::Hideout1: + case GarageType::Hideout2: + case GarageType::Hideout3: + case GarageType::MissionToOpenAndClose: + case GarageType::MissionForSpecificCar: + case GarageType::MissionKeepCarAndRemainClosed: { + info->state = GarageState::Closed; + break; + } + + case GarageType::BombShop1: + case GarageType::BombShop2: + case GarageType::BombShop3: + case GarageType::Respray: + case GarageType::Crusher: { + info->state = GarageState::Opened; + break; + } + } + + // Create controller + garageControllers.push_back( + std::make_unique(GarageController(this, info, door))); + + return info; +} + void GameWorld::ObjectPool::insert(GameObject* object) { if (object->getGameObjectID() == 0) { // Find the lowest free GameObjectID. diff --git a/rwengine/src/engine/GameWorld.hpp b/rwengine/src/engine/GameWorld.hpp index 9293b6a6..19d05de7 100644 --- a/rwengine/src/engine/GameWorld.hpp +++ b/rwengine/src/engine/GameWorld.hpp @@ -17,7 +17,9 @@ #include #include