mirror of
https://github.com/rwengine/openrw.git
synced 2024-11-07 19:32:49 +01:00
Merge pull request #120 from JayFoxRox/basic-garages
Basic garage functionality in script
This commit is contained in:
commit
a60fb248ad
@ -245,7 +245,7 @@ struct GarageInfo
|
|||||||
GARAGE_COLLECTCARS3 = 10, /* Unused */
|
GARAGE_COLLECTCARS3 = 10, /* Unused */
|
||||||
GARAGE_OPENFOREXIT = 11,
|
GARAGE_OPENFOREXIT = 11,
|
||||||
GARAGE_INVALID2 = 12,
|
GARAGE_INVALID2 = 12,
|
||||||
GARAGE_CRUSHER = 13, /* Unused */
|
GARAGE_CRUSHER = 13,
|
||||||
GARAGE_MISSION_KEEPCAR = 14,
|
GARAGE_MISSION_KEEPCAR = 14,
|
||||||
GARAGE_FOR_SCRIPT = 15,
|
GARAGE_FOR_SCRIPT = 15,
|
||||||
GARAGE_HIDEOUT_ONE = 16, /* Portland */
|
GARAGE_HIDEOUT_ONE = 16, /* Portland */
|
||||||
|
@ -38,6 +38,8 @@ public:
|
|||||||
|
|
||||||
virtual bool takeDamage(const DamageInfo& damage);
|
virtual bool takeDamage(const DamageInfo& damage);
|
||||||
|
|
||||||
|
void setSolid(bool solid);
|
||||||
|
|
||||||
float getHealth() const { return health; }
|
float getHealth() const { return health; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -174,4 +174,20 @@ bool InstanceObject::takeDamage(const GameObject::DamageInfo& dmg)
|
|||||||
return false;
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -402,9 +402,58 @@ void game_create_garage(const ScriptArguments& args)
|
|||||||
args.getWorld()->state->garages.push_back({
|
args.getWorld()->state->garages.push_back({
|
||||||
min, max, garageType
|
min, max, garageType
|
||||||
});
|
});
|
||||||
|
int garageIndex = args.getWorld()->state->garages.size() - 1;
|
||||||
|
|
||||||
// TODO actually store the garage information and return the handle
|
*args[7].globalInteger = garageIndex;
|
||||||
*args[7].globalInteger = args.getWorld()->state->garages.size()-1;
|
}
|
||||||
|
|
||||||
|
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)
|
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)
|
void game_increment_progress(const ScriptArguments& args)
|
||||||
{
|
{
|
||||||
args.getWorld()->state->currentProgress += args[0].integer;
|
args.getWorld()->state->currentProgress += args[0].integer;
|
||||||
@ -1038,6 +1114,9 @@ GameModule::GameModule()
|
|||||||
|
|
||||||
bindFunction(0x0219, game_create_garage, 8, "Create Garage" );
|
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(0x022A, game_disable_ped_paths, 6, "Disable ped paths" );
|
||||||
bindFunction(0x022B, game_enable_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(0x02F4, game_create_cutscene_head, 3, "Create Cutscene Actor Head" );
|
||||||
bindFunction(0x02F5, game_set_head_animation, 2, "Set Cutscene Head Animation" );
|
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(0x030C, game_increment_progress, 1, "Increment Progress" );
|
||||||
bindFunction(0x030D, game_set_max_progress, 1, "Set Max 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( 0x041E, game_set_radio, 2, "Set Radio Station" );
|
||||||
|
|
||||||
bindUnimplemented( 0x0421, game_force_rain, 1, "Force Rain" );
|
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" );
|
bindUnimplemented( 0x0426, game_create_level_transition, 6, "Create Save Cars Between Levels cube" );
|
||||||
|
|
||||||
|
@ -1328,9 +1328,7 @@ ObjectModule::ObjectModule()
|
|||||||
bindFunction(0x02DE, game_player_in_taxi, 1, "Is Player In Taxi" );
|
bindFunction(0x02DE, game_player_in_taxi, 1, "Is Player In Taxi" );
|
||||||
|
|
||||||
bindFunction(0x02E3, game_get_speed, 2, "Get Vehicle Speed" );
|
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(0x0320, game_character_in_range, 2, "Is Character in range of character");
|
||||||
|
|
||||||
bindFunction(0x0339, game_objects_in_volume, 11, "Are objects in volume" );
|
bindFunction(0x0339, game_objects_in_volume, 11, "Are objects in volume" );
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
#include "RWGame.hpp"
|
#include "RWGame.hpp"
|
||||||
#include <ai/PlayerController.hpp>
|
#include <ai/PlayerController.hpp>
|
||||||
#include <objects/CharacterObject.hpp>
|
#include <objects/CharacterObject.hpp>
|
||||||
|
#include <objects/InstanceObject.hpp>
|
||||||
#include <objects/VehicleObject.hpp>
|
#include <objects/VehicleObject.hpp>
|
||||||
#include <engine/GameState.hpp>
|
#include <engine/GameState.hpp>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
@ -129,6 +130,53 @@ DebugState::DebugState(RWGame* game, const glm::vec3& vp, const glm::quat& vd)
|
|||||||
m->addEntry(Menu::lambda("Cull Here", [=] {
|
m->addEntry(Menu::lambda("Cull Here", [=] {
|
||||||
game->getRenderer()->setCullOverride(true, _debugCam);
|
game->getRenderer()->setCullOverride(true, _debugCam);
|
||||||
}, entryHeight));
|
}, 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
|
// Optional block if the player is in a vehicle
|
||||||
auto player = game->getPlayer()->getCharacter();
|
auto player = game->getPlayer()->getCharacter();
|
||||||
|
Loading…
Reference in New Issue
Block a user