1
0
mirror of https://github.com/rwengine/openrw.git synced 2024-11-07 11:22:45 +01:00

Merge pull request #120 from JayFoxRox/basic-garages

Basic garage functionality in script
This commit is contained in:
Daniel Evans 2016-06-03 23:10:28 +01:00
commit a60fb248ad
6 changed files with 152 additions and 6 deletions

View File

@ -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 */

View File

@ -38,6 +38,8 @@ public:
virtual bool takeDamage(const DamageInfo& damage);
void setSolid(bool solid);
float getHealth() const { return health; }
};

View File

@ -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);
}

View File

@ -402,9 +402,58 @@ 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;
}
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<int>(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;
}
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<int>(garages.size()), "Garage index too high");
const auto& garage = garages[garageIndex];
auto vehicle = static_cast<VehicleObject*>(args.getObject<VehicleObject>(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)
@ -664,6 +713,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;
@ -1038,6 +1114,9 @@ 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" );
bindFunction(0x022B, game_enable_ped_paths, 6, "Disable ped paths" );
@ -1095,6 +1174,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" );
@ -1206,6 +1287,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" );

View File

@ -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" );

View File

@ -2,6 +2,7 @@
#include "RWGame.hpp"
#include <ai/PlayerController.hpp>
#include <objects/CharacterObject.hpp>
#include <objects/InstanceObject.hpp>
#include <objects/VehicleObject.hpp>
#include <engine/GameState.hpp>
#include <sstream>
@ -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<std::string> 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<InstanceObject*>(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();