From e5014e29f9b62cc2517766f71e7567fe9520fa1d Mon Sep 17 00:00:00 2001 From: Jannik Vogel Date: Thu, 2 Jun 2016 17:13:00 +0200 Subject: [PATCH 1/7] Add function to disable collision for InstanceObjects --- rwengine/include/objects/InstanceObject.hpp | 2 ++ rwengine/src/objects/InstanceObject.cpp | 16 ++++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/rwengine/include/objects/InstanceObject.hpp b/rwengine/include/objects/InstanceObject.hpp index 7b1d9b98..450d5e44 100644 --- a/rwengine/include/objects/InstanceObject.hpp +++ b/rwengine/include/objects/InstanceObject.hpp @@ -38,6 +38,8 @@ public: virtual bool takeDamage(const DamageInfo& damage); + void setSolid(bool solid); + float getHealth() const { return health; } }; diff --git a/rwengine/src/objects/InstanceObject.cpp b/rwengine/src/objects/InstanceObject.cpp index 0663c07d..1eb99796 100644 --- a/rwengine/src/objects/InstanceObject.cpp +++ b/rwengine/src/objects/InstanceObject.cpp @@ -174,4 +174,20 @@ bool InstanceObject::takeDamage(const GameObject::DamageInfo& dmg) return false; } +void InstanceObject::setSolid(bool solid) +{ + // Early out in case we don't have a collision body + if (body == nullptr || body->body == nullptr) { + return; + } + + int flags = body->body->getCollisionFlags(); + if (solid) { + flags &= ~btCollisionObject::CF_NO_CONTACT_RESPONSE; + } else { + flags |= btCollisionObject::CF_NO_CONTACT_RESPONSE; + } + body->body->setCollisionFlags(flags); +} + From 873e2d4040d34ef252d26f432aaa8f54bb809616 Mon Sep 17 00:00:00 2001 From: Jannik Vogel Date: Thu, 2 Jun 2016 17:44:20 +0200 Subject: [PATCH 2/7] Add option to disable collision for garage doors in debug menu --- rwgame/debugstate.cpp | 48 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/rwgame/debugstate.cpp b/rwgame/debugstate.cpp index 423cd516..4c05c149 100644 --- a/rwgame/debugstate.cpp +++ b/rwgame/debugstate.cpp @@ -2,6 +2,7 @@ #include "RWGame.hpp" #include #include +#include #include #include #include @@ -129,6 +130,53 @@ DebugState::DebugState(RWGame* game, const glm::vec3& vp, const glm::quat& vd) m->addEntry(Menu::lambda("Cull Here", [=] { game->getRenderer()->setCullOverride(true, _debugCam); }, entryHeight)); + m->addEntry(Menu::lambda("Unsolid garage doors", [=] { + + std::vector garageDoorModels { + "8ballsuburbandoor", + "amcogaragedoor", + "bankjobdoor", + "bombdoor", + "crushercrush", + "crushertop", + "door2_garage", + "door3_garage", + "door4_garage", + "door_bombshop", + "door_col_compnd_01", + "door_col_compnd_02", + "door_col_compnd_03", + "door_col_compnd_04", + "door_col_compnd_05", + "door_jmsgrage", + "door_sfehousegrge", + "double_garage_dr", + "impex_door", + "impexpsubgrgdoor", + "ind_plyrwoor", + "ind_slidedoor", + "jamesgrge_kb", + "leveldoor2", + "oddjgaragdoor", + "plysve_gragedoor", + "SalvGarage", + "shedgaragedoor", + "Sub_sprayshopdoor", + "towergaragedoor1", + "towergaragedoor2", + "towergaragedoor3", + "vheistlocdoor" + }; + + auto gw = game->getWorld(); + for(auto& i : gw->instancePool.objects) { + auto obj = static_cast(i.second); + if (std::find(garageDoorModels.begin(), garageDoorModels.end(), obj->model->name) != garageDoorModels.end()) { + obj->setSolid(false); + } + } + }, entryHeight)); + // Optional block if the player is in a vehicle auto player = game->getPlayer()->getCharacter(); From 830b2958674d2be51ab3e4edbb2d5dc4e8e76487 Mon Sep 17 00:00:00 2001 From: Jannik Vogel Date: Wed, 1 Jun 2016 23:51:06 +0200 Subject: [PATCH 3/7] Make it more obvious that create_garage returns an index --- rwengine/src/script/modules/GameModule.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rwengine/src/script/modules/GameModule.cpp b/rwengine/src/script/modules/GameModule.cpp index 00392f70..9bbdf2d5 100644 --- a/rwengine/src/script/modules/GameModule.cpp +++ b/rwengine/src/script/modules/GameModule.cpp @@ -402,9 +402,9 @@ void game_create_garage(const ScriptArguments& args) args.getWorld()->state->garages.push_back({ min, max, garageType }); + int garageIndex = args.getWorld()->state->garages.size() - 1; - // TODO actually store the garage information and return the handle - *args[7].globalInteger = args.getWorld()->state->garages.size()-1; + *args[7].globalInteger = garageIndex; } void game_disable_ped_paths(const ScriptArguments& args) From f850e401cf660156d33c281fcebccd2c20b0a7d8 Mon Sep 17 00:00:00 2001 From: Jannik Vogel Date: Thu, 2 Jun 2016 02:51:27 +0200 Subject: [PATCH 4/7] Script: 02FB (Create Crusher Crane) --- rwengine/include/engine/GameState.hpp | 2 +- rwengine/src/script/modules/GameModule.cpp | 29 ++++++++++++++++++++ rwengine/src/script/modules/ObjectModule.cpp | 4 +-- 3 files changed, 31 insertions(+), 4 deletions(-) diff --git a/rwengine/include/engine/GameState.hpp b/rwengine/include/engine/GameState.hpp index 546be51f..295c8ede 100644 --- a/rwengine/include/engine/GameState.hpp +++ b/rwengine/include/engine/GameState.hpp @@ -245,7 +245,7 @@ struct GarageInfo GARAGE_COLLECTCARS3 = 10, /* Unused */ GARAGE_OPENFOREXIT = 11, GARAGE_INVALID2 = 12, - GARAGE_CRUSHER = 13, /* Unused */ + GARAGE_CRUSHER = 13, GARAGE_MISSION_KEEPCAR = 14, GARAGE_FOR_SCRIPT = 15, GARAGE_HIDEOUT_ONE = 16, /* Portland */ diff --git a/rwengine/src/script/modules/GameModule.cpp b/rwengine/src/script/modules/GameModule.cpp index 9bbdf2d5..7142184b 100644 --- a/rwengine/src/script/modules/GameModule.cpp +++ b/rwengine/src/script/modules/GameModule.cpp @@ -664,6 +664,33 @@ void game_set_head_animation(const ScriptArguments& args) } } +void game_create_crusher_crane(const ScriptArguments& args) +{ + glm::vec2 crane_location(args[0].real, args[1].real); + glm::vec2 park_min(args[2].real, args[3].real); + glm::vec2 park_max(args[4].real, args[5].real); + glm::vec3 crusher_position(args[6].real, args[7].real, args[8].real); + float crusher_heading = args[9].real; + + RW_UNIMPLEMENTED("create_crusher_crane is incomplete"); + /// @todo check how to store all parameters and how to create the actual crusher + RW_UNUSED(crane_location); + RW_UNUSED(crusher_position); + /// @todo check how the savegame stores the heading value etc. + RW_UNUSED(crusher_heading); + + // NOTE: These values come from a savegame from the original game + glm::vec3 min(park_min, -1.f); + glm::vec3 max(park_max, 3.5f); + int garageType = GarageInfo::GARAGE_CRUSHER; + + // NOTE: This instruction also creates or controls a garage + /// @todo find out if this creates a garage or if it just controls garage[0] + args.getWorld()->state->garages.push_back({ + min, max, garageType + }); +} + void game_increment_progress(const ScriptArguments& args) { args.getWorld()->state->currentProgress += args[0].integer; @@ -1095,6 +1122,8 @@ GameModule::GameModule() bindFunction(0x02F4, game_create_cutscene_head, 3, "Create Cutscene Actor Head" ); bindFunction(0x02F5, game_set_head_animation, 2, "Set Cutscene Head Animation" ); + bindFunction(0x02FB, game_create_crusher_crane, 10, "Create Crusher Crane"); + bindFunction(0x030C, game_increment_progress, 1, "Increment Progress" ); bindFunction(0x030D, game_set_max_progress, 1, "Set Max Progress" ); diff --git a/rwengine/src/script/modules/ObjectModule.cpp b/rwengine/src/script/modules/ObjectModule.cpp index 992dcb8c..e333ac54 100644 --- a/rwengine/src/script/modules/ObjectModule.cpp +++ b/rwengine/src/script/modules/ObjectModule.cpp @@ -1328,9 +1328,7 @@ ObjectModule::ObjectModule() bindFunction(0x02DE, game_player_in_taxi, 1, "Is Player In Taxi" ); bindFunction(0x02E3, game_get_speed, 2, "Get Vehicle Speed" ); - - bindUnimplemented( 0x02FB, game_create_crane, 10, "Create Crusher Crane" ); - + bindFunction(0x0320, game_character_in_range, 2, "Is Character in range of character"); bindFunction(0x0339, game_objects_in_volume, 11, "Are objects in volume" ); From 52477013f39ae8878b7a74786ca42297b6a51255 Mon Sep 17 00:00:00 2001 From: Jannik Vogel Date: Thu, 2 Jun 2016 16:50:31 +0200 Subject: [PATCH 5/7] Script: 021C (Is Car Inside Garage) --- rwengine/src/script/modules/GameModule.cpp | 26 ++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/rwengine/src/script/modules/GameModule.cpp b/rwengine/src/script/modules/GameModule.cpp index 7142184b..4867fd3d 100644 --- a/rwengine/src/script/modules/GameModule.cpp +++ b/rwengine/src/script/modules/GameModule.cpp @@ -407,6 +407,30 @@ void game_create_garage(const ScriptArguments& args) *args[7].globalInteger = garageIndex; } +bool game_is_car_inside_garage(const ScriptArguments& args) +{ + /// @todo move to garage code + + GameWorld* gw = args.getWorld(); + const auto& garages = gw->state->garages; + int garageIndex = args[0].integerValue(); + + RW_CHECK(garageIndex >= 0, "Garage index too low"); + RW_CHECK(garageIndex < static_cast(garages.size()), "Garage index too high"); + const auto& garage = garages[garageIndex]; + + for(auto& v : gw->vehiclePool.objects) { + // @todo if this car only accepts mission cars we probably have to filter here / only check for one specific car + auto vp = v.second->getPosition(); + if (vp.x >= garage.min.x && vp.y >= garage.min.y && vp.z >= garage.min.z && + vp.x <= garage.max.x && vp.y <= garage.max.y && vp.z <= garage.max.z) { + return true; + } + } + + return false; +} + void game_disable_ped_paths(const ScriptArguments& args) { glm::vec3 min(args[0].real,args[1].real,args[2].real); @@ -1065,6 +1089,8 @@ GameModule::GameModule() bindFunction(0x0219, game_create_garage, 8, "Create Garage" ); + bindFunction(0x021C, game_is_car_inside_garage, 1, "Is Car Inside Garage" ); + bindFunction(0x022A, game_disable_ped_paths, 6, "Disable ped paths" ); bindFunction(0x022B, game_enable_ped_paths, 6, "Disable ped paths" ); From 8c72bd33fb8722b7398960e3e0c9e94f0c6a9bd3 Mon Sep 17 00:00:00 2001 From: Jannik Vogel Date: Thu, 2 Jun 2016 16:50:57 +0200 Subject: [PATCH 6/7] Script: 0422 (Garage Contains Car) --- rwengine/src/script/modules/GameModule.cpp | 26 ++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/rwengine/src/script/modules/GameModule.cpp b/rwengine/src/script/modules/GameModule.cpp index 4867fd3d..a2231725 100644 --- a/rwengine/src/script/modules/GameModule.cpp +++ b/rwengine/src/script/modules/GameModule.cpp @@ -431,6 +431,31 @@ bool game_is_car_inside_garage(const ScriptArguments& args) return false; } +bool game_garage_contains_car(const ScriptArguments& args) +{ + /// @todo move to garage code + + GameWorld* gw = args.getWorld(); + const auto& garages = gw->state->garages; + int garageIndex = args[0].integerValue(); + + RW_CHECK(garageIndex >= 0, "Garage index too low"); + RW_CHECK(garageIndex < static_cast(garages.size()), "Garage index too high"); + const auto& garage = garages[garageIndex]; + + auto vehicle = static_cast(args.getObject(1)); + if (vehicle) { + /// @todo if this car only accepts mission cars we probably have to filter here / only check for one specific car + auto vp = vehicle->getPosition(); + if(vp.x >= garage.min.x && vp.y >= garage.min.y && vp.z >= garage.min.z && + vp.x <= garage.max.x && vp.y <= garage.max.y && vp.z <= garage.max.z) { + return true; + } + } + + return false; +} + void game_disable_ped_paths(const ScriptArguments& args) { glm::vec3 min(args[0].real,args[1].real,args[2].real); @@ -1261,6 +1286,7 @@ GameModule::GameModule() bindUnimplemented( 0x041E, game_set_radio, 2, "Set Radio Station" ); bindUnimplemented( 0x0421, game_force_rain, 1, "Force Rain" ); + bindFunction( 0x0422, game_garage_contains_car, 2, "Garage Contains Car" ); bindUnimplemented( 0x0426, game_create_level_transition, 6, "Create Save Cars Between Levels cube" ); From 87bed4cf0f732f5abd5622af8fb35a44360cdb91 Mon Sep 17 00:00:00 2001 From: Jannik Vogel Date: Thu, 2 Jun 2016 16:54:19 +0200 Subject: [PATCH 7/7] Script: 021B (Set Target Car for Mission Garage) --- rwengine/src/script/modules/GameModule.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/rwengine/src/script/modules/GameModule.cpp b/rwengine/src/script/modules/GameModule.cpp index a2231725..52f2ff94 100644 --- a/rwengine/src/script/modules/GameModule.cpp +++ b/rwengine/src/script/modules/GameModule.cpp @@ -1114,6 +1114,7 @@ GameModule::GameModule() bindFunction(0x0219, game_create_garage, 8, "Create Garage" ); + bindUnimplemented( 0x021B, game_set_target_car_for_mission_garage, 2, "Set Target Car for Mission Garage" ); bindFunction(0x021C, game_is_car_inside_garage, 1, "Is Car Inside Garage" ); bindFunction(0x022A, game_disable_ped_paths, 6, "Disable ped paths" );