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

Add implementation for more generic pickups

This commit is contained in:
Daniel Evans 2015-01-27 02:38:08 +00:00
parent 206c61e326
commit abb6576785
8 changed files with 143 additions and 25 deletions

View File

@ -0,0 +1,15 @@
#pragma once
#include <objects/PickupObject.hpp>
class GenericPickup : public PickupObject
{
public:
GenericPickup(GameWorld* world, const glm::vec3& position, int modelID, int type);
virtual bool onCharacterTouch(CharacterObject* character);
private:
int type;
};

View File

@ -18,6 +18,7 @@ class PickupObject : public GameObject
btSphereShape* _shape;
bool _enabled;
float _enableTimer;
bool collected;
int _modelID;
public:
@ -35,6 +36,8 @@ public:
bool isEnabled() const { return _enabled; }
void setEnabled(bool enabled);
bool isCollected() const { return collected; }
};
#endif

View File

@ -53,6 +53,8 @@ struct SCMOpcodeParameter {
int* globalInteger;
float* globalReal;
};
template<class T> T* handleOf() const { return static_cast<T*>(*handle); }
};
typedef std::vector<SCMOpcodeParameter> SCMParams;

View File

@ -0,0 +1,12 @@
#include <objects/GenericPickup.hpp>
GenericPickup::GenericPickup(GameWorld* world, const glm::vec3& position, int modelID, int type)
: PickupObject(world, position, modelID), type(type)
{
}
bool GenericPickup::onCharacterTouch(CharacterObject* character)
{
return true;
}

View File

@ -4,7 +4,7 @@
PickupObject::PickupObject(GameWorld *world, const glm::vec3 &position, int modelID)
: GameObject(world, position, glm::quat(), nullptr),
_ghost(nullptr), _shape(nullptr), _enabled(false), _modelID(modelID)
_ghost(nullptr), _shape(nullptr), _enabled(false), collected(false), _modelID(modelID)
{
btTransform tf;
tf.setIdentity();
@ -35,6 +35,7 @@ void PickupObject::tick(float dt)
_enableTimer -= dt;
if( _enableTimer <= 0.f ) {
setEnabled(true);
collected = false;
}
}
@ -55,7 +56,8 @@ void PickupObject::tick(float dt)
GameObject* object = static_cast<GameObject*>(otherObject->getUserPointer());
if(object->type() == Character) {
CharacterObject* character = static_cast<CharacterObject*>(object);
setEnabled( !onCharacterTouch(character) );
collected = onCharacterTouch(character);
setEnabled( !collected );
if( ! _enabled ) {
_enableTimer = 60.f;
}

View File

@ -704,22 +704,44 @@ void GameRenderer::renderPickup(PickupObject *pickup)
modelMatrix = glm::rotate(modelMatrix, engine->gameTime, glm::vec3(0.f, 0.f, 1.f));
auto odata = engine->findObjectType<ObjectData>(pickup->getModelID());
auto weapons = engine->gameData.models["weapons"];
if( weapons && weapons->model && odata ) {
auto itemModel = weapons->model->findFrame(odata->modelName + "_l0");
auto matrix = glm::inverse(itemModel->getTransform());
if(itemModel) {
renderFrame(weapons->model, itemModel, modelMatrix * matrix, nullptr, 1.f);
}
else {
std::cerr << "weapons.dff missing frame " << odata->modelName << std::endl;
Model* model = nullptr;
ModelFrame* itemModel = nullptr;
/// @todo Better determination of is this object a weapon.
if( odata->ID >= 170 && odata->ID <= 184 )
{
auto weapons = engine->gameData.models["weapons"];
if( weapons && weapons->model && odata ) {
model = weapons->model;
itemModel = weapons->model->findFrame(odata->modelName + "_l0");
if ( ! itemModel )
{
std::cerr << "weapons.dff missing frame " << odata->modelName << std::endl;
}
}
}
else {
std::cerr << "weapons.dff not loaded (" << pickup->getModelID() << ")" << std::endl;
else
{
auto handle = engine->gameData.models[odata->modelName];
if ( handle && handle->model )
{
model = handle->model;
itemModel = model->frames[model->rootFrameIdx];
}
else
{
std::cerr << "Missing pickup model " << odata->modelName << std::endl;
}
}
if ( itemModel ) {
auto matrix = glm::inverse(itemModel->getTransform());
renderFrame(model, itemModel, modelMatrix * matrix, nullptr, 1.f);
}
}
void GameRenderer::renderCutsceneObject(CutsceneObject *cutscene)
{
if(!engine->state.currentCutscene) return;

View File

@ -344,12 +344,6 @@ void game_get_player(const ScriptArguments& args)
*args[1].handle = controller;
}
bool game_is_pickup_collected(const ScriptArguments& args)
{
/// @todo
return false;
}
void game_create_garage(const ScriptArguments& args)
{
glm::vec3 min(args[0].real, args[1].real, args[2].real);
@ -912,11 +906,6 @@ GameModule::GameModule()
bindFunction(0x01F6, game_clear_override, 0, "Clear override restart" );
bindUnimplemented( 0x01F9, game_start_kill_frenzy, 9, "Start Kill Frenzy" );
/// @todo http://gtag.gtagaming.com/opcode-database/opcode/0213/
bindUnimplemented( 0x0213, game_create_pickup, 6, "Create pickup" );
bindFunction(0x0214, game_is_pickup_collected, 1, "Has Pickup been collected" );
bindUnimplemented( 0x0215, game_destroy_pickup, 1, "Destroy Pickup" );
bindFunction(0x0219, game_create_garage, 8, "Create Garage" );

View File

@ -19,6 +19,8 @@
#include <data/CutsceneData.hpp>
#include <data/Skeleton.hpp>
#include <objects/CutsceneObject.hpp>
#include <objects/PickupObject.hpp>
#include <objects/GenericPickup.hpp>
#include <glm/gtx/string_cast.hpp>
@ -619,6 +621,73 @@ void game_navigate_on_foot(const ScriptArguments& args)
controller->setNextActivity(new Activities::GoTo(target));
}
void game_create_pickup(const ScriptArguments& args)
{
glm::vec3 pos (args[2].real, args[3].real, args[4].real);
int id;
int type = args[1].integer;
switch(args[0].type) {
case TInt8:
id = (std::int8_t)args[0].integer;
break;
case TInt16:
id = (std::int16_t)args[0].integer;
break;
}
if ( id < 0 )
{
id = -id;
auto model = args.getVM()->getFile()->getModels()[id];
std::transform(model.begin(), model.end(), model.begin(), ::tolower);
id = args.getVM()->getWorld()->findModelDefinition(model);
args.getVM()->getWorld()->gameData.loadDFF(model+".dff");
args.getVM()->getWorld()->gameData.loadTXD("icons.txd");
}
else
{
auto data = args.getVM()->getWorld()->findObjectType<ObjectData>(id);
if ( ! ( id >= 170 && id <= 184 ) )
{
args.getVM()->getWorld()->gameData.loadDFF(data->modelName+".dff");
}
args.getVM()->getWorld()->gameData.loadTXD(data->textureName+".txd");
}
auto pickup = new GenericPickup(args.getVM()->getWorld(), pos, id, type);
args.getVM()->getWorld()->objects.insert(pickup);
*args[5].handle = pickup;
}
bool game_is_pickup_collected(const ScriptArguments& args)
{
PickupObject* pickup = args[0].handleOf<PickupObject>();
if ( pickup )
{
return pickup->isCollected();
}
return false;
}
void game_destroy_pickup(const ScriptArguments& args)
{
PickupObject* pickup = args[0].handleOf<PickupObject>();
if ( pickup )
{
args.getVM()->getWorld()->destroyObjectQueued(pickup);
}
}
void game_character_run_to(const ScriptArguments& args)
{
auto controller = (CharacterController*)(*args[0].handle);
@ -948,7 +1017,11 @@ ObjectModule::ObjectModule()
bindUnimplemented( 0x020A, game_lock_vehicle_doors, 2, "Lock Car Doors" );
bindFunction(0x0211, game_navigate_on_foot, 3, "Character go to on foot" );
bindFunction(0x0213, game_create_pickup, 6, "Create pickup");
bindFunction(0x0214, game_is_pickup_collected, 1, "Has Pickup been collected");
bindFunction(0x0215, game_destroy_pickup, 1, "Destroy Pickup");
bindFunction(0x0229, game_set_vehicle_colours, 3, "Set Vehicle Colours" );
bindFunction(0x0239, game_character_run_to, 3, "Character Run to" );