1
0
mirror of https://github.com/rwengine/openrw.git synced 2024-09-15 15:02:34 +02:00

Add more opcodes and vehicle handling

This commit is contained in:
Daniel Evans 2014-12-16 19:17:22 +00:00
parent 2709e7d252
commit 7963becbd1
9 changed files with 221 additions and 44 deletions

View File

@ -5,7 +5,7 @@
#include <glm/glm.hpp>
#include <string>
#define ZONE_GANG_COUNT 10
#define ZONE_GANG_COUNT 11
/**
* \class Zone

View File

@ -19,6 +19,14 @@ struct TextDisplayData
glm::vec4 colourBG;
};
struct OnscreenText
{
std::string osTextString;
float osTextStart;
float osTextTime;
unsigned short osTextStyle;
};
/**
* Stores information about where the game can generate vehicles.
*/
@ -73,25 +81,27 @@ struct GameState
bool isIntroPlaying;
CutsceneData* currentCutscene;
float cutsceneStartTime;
/** Flag for rendering cutscene letterbox */
bool isCinematic;
short hour;
short minute;
/// @todo opcodes seem to imply Onscreen text might be queued
unsigned short osTextStyle;
std::string osTextString;
float osTextStart;
float osTextTime;
/// Stores the "special" character and cutscene model indices.
std::map<unsigned short, std::string> specialCharacters;
std::map<unsigned short, std::string> specialModels;
std::vector<OnscreenText> text;
TextDisplayData nextText;
std::vector<TextDisplayData> texts;
/** The camera near value currently set by the script */
float cameraNear;
bool cameraFixed;
glm::vec3 cameraPosition;
glm::quat cameraRotation;
std::vector<VehicleGenerator> vehicleGenerators;
@ -113,12 +123,11 @@ struct GameState
isIntroPlaying(false),
currentCutscene(nullptr),
cutsceneStartTime(-1.f),
isCinematic(false),
hour(0),
minute(0),
osTextStyle(0),
osTextStart(0.f),
osTextTime(0.f),
cameraNear(0.1f)
cameraNear(0.1f),
cameraFixed(false)
{}
};

View File

@ -54,7 +54,11 @@ void CharacterController::update(float dt)
// Nevermind, the player is in a vehicle.
character->getCurrentVehicle()->setSteeringAngle(d.y);
// TODO what is handbraking.
if( std::abs(d.x) > 0.01f )
{
character->getCurrentVehicle()->setHandbraking(false);
}
character->getCurrentVehicle()->setThrottle(d.x);
// if the character isn't doing anything, play sitting anim.

View File

@ -12,7 +12,7 @@
VehicleObject::VehicleObject(GameWorld* engine, const glm::vec3& pos, const glm::quat& rot, ModelHandle* model, VehicleDataHandle data, VehicleInfoHandle info, const glm::u8vec3& prim, const glm::u8vec3& sec)
: GameObject(engine, pos, rot, model),
steerAngle(0.f), throttle(0.f), brake(0.f), handbrake(false),
steerAngle(0.f), throttle(0.f), brake(0.f), handbrake(true),
vehicle(data), info(info), colourPrimary(prim),
colourSecondary(sec), collision(nullptr), physBody(nullptr), physVehicle(nullptr)
{
@ -147,6 +147,13 @@ void VehicleObject::tickPhysics(float dt)
float velFac = (info->handling.maxVelocity - physVehicle->getCurrentSpeedKmHour()) / info->handling.maxVelocity;
float engineForce = info->handling.acceleration * 150.f * throttle * velFac;
if( fabs(engineForce) >= 0.001f ) physBody->activate(true);
float brakeF = getBraking();
if( handbrake )
{
brakeF = 2.f;
}
for(int w = 0; w < physVehicle->getNumWheels(); ++w) {
btWheelInfo& wi = physVehicle->getWheelInfo(w);
@ -157,8 +164,8 @@ void VehicleObject::tickPhysics(float dt)
physVehicle->applyEngineForce(engineForce, w);
}
float brakeReal = info->handling.brakeDeceleration * info->handling.mass * (wi.m_bIsFrontWheel? info->handling.brakeBias : 1.f - info->handling.brakeBias);
physVehicle->setBrake(brakeReal * brake, w);
float brakeReal = 10.f * info->handling.brakeDeceleration * (wi.m_bIsFrontWheel? info->handling.brakeBias : 1.f - info->handling.brakeBias);
physVehicle->setBrake(brakeReal * brakeF, w);
if(wi.m_bIsFrontWheel) {
float sign = std::signbit(steerAngle) ? -1.f : 1.f;

View File

@ -449,7 +449,7 @@ void GameRenderer::renderWorld(const ViewCamera &camera, float alpha)
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
}
if( engine->state.currentCutscene && splashTexName == 0 ) {
if( engine->state.isCinematic && splashTexName == 0 ) {
renderLetterbox();
}

View File

@ -101,26 +101,54 @@ VM_OPCODE_DEF( 0x00A5 )
{
auto id = p->at(0).integer;
glm::vec3 position(p->at(1).real, p->at(2).real, p->at(3).real);
position += spawnMagic;
// If there is already a vehicle less than this distance away, it will be destroyed.
const float replaceThreshold = 1.f;
for( auto it = m->getWorld()->objects.begin();
it != m->getWorld()->objects.end();
++it)
{
if( (*it)->type() == GameObject::Vehicle && glm::distance(position, (*it)->getPosition()) < replaceThreshold )
{
m->getWorld()->destroyObjectQueued(*it);
}
}
auto vehicle = m->getWorld()->createVehicle(id, position + spawnMagic);
auto vehicle = m->getWorld()->createVehicle(id, position);
*p->at(4).handle = vehicle;
}
VM_OPCODE_DEF( 0x00BA )
{
std::string str(p->at(0).string);
str = m->getWorld()->gameData.texts.text(str);
unsigned short style = p->at(2).integer;
m->getWorld()->state.text.push_back({
str,
m->getWorld()->gameTime,
p->at(1).integer / 1000.f,
style
});
}
VM_OPCODE_DEF( 0x00BC )
{
std::string str(p->at(0).string);
str = m->getWorld()->gameData.texts.text(str);
m->getWorld()->state.osTextString = str;
m->getWorld()->state.osTextTime = p->at(1).integer / 1000.f;
m->getWorld()->state.osTextStart= m->getWorld()->gameTime;
m->getWorld()->state.osTextStyle = p->at(2).integer;
int flags = p->at(2).integer;
m->getWorld()->state.text.push_back({
str,
m->getWorld()->gameTime,
p->at(1).integer / 1000.f,
0
});
}
VM_OPCODE_DEF( 0x00BE )
{
m->getWorld()->state.osTextTime = 0.f;
m->getWorld()->state.osTextStart= 0.f;
m->getWorld()->state.text.clear();
}
VM_OPCODE_DEF( 0x00C0 )
@ -296,6 +324,40 @@ VM_OPCODE_DEF( 0x015C )
}
}
VM_OPCODE_DEF( 0x015F )
{
glm::vec3 position( p->at(0).real, p->at(1).real, p->at(2).real );
glm::vec3 angles( p->at(3).real, p->at(4).real, p->at(5).real );
m->getWorld()->state.cameraFixed = true;
m->getWorld()->state.cameraPosition = position;
m->getWorld()->state.cameraRotation = glm::quat(angles);
}
VM_OPCODE_DEF( 0x0160 )
{
glm::vec3 position( p->at(0).real, p->at(1).real, p->at(2).real );
int switchmode = p->at(3).integer;
auto direction = glm::normalize(position - m->getWorld()->state.cameraPosition);
auto right = glm::normalize(glm::cross(glm::vec3(0.f, 0.f, 1.f), direction));
auto up = glm::normalize(glm::cross(direction, right));
glm::mat3 v;
v[0][0] = direction.x;
v[0][1] = right.x;
v[0][2] = up.x;
v[1][0] = direction.y;
v[1][1] = right.y;
v[1][2] = up.y;
v[2][0] = direction.z;
v[2][1] = right.z;
v[2][2] = up.z;
m->getWorld()->state.cameraRotation = glm::inverse(glm::quat_cast(v));
}
VM_OPCODE_DEF( 0x0169 )
{
m->getWorld()->state.fadeColour.r = p->at(0).integer;
@ -376,6 +438,14 @@ VM_OPCODE_DEF( 0x01C7 )
std::cout << "Unable to pin object " << inst << ". Object pinning unimplimented" << std::endl;
}
VM_OPCODE_DEF( 0x01D4 )
{
auto controller = (CharacterController*)(*p->at(0).handle);
auto vehicle = (VehicleObject*)(*p->at(1).handle);
/// @todo find next lowest free seat.
controller->setNextActivity(new Activities::EnterVehicle(vehicle,1));
}
VM_OPCODE_DEF( 0x01E7 )
{
glm::vec3 min(p->at(0).real,p->at(1).real,p->at(2).real);
@ -408,6 +478,13 @@ VM_OPCODE_DEF( 0x01F5 )
*p->at(1).handle = controller;
}
VM_CONDOPCODE_DEF( 0x01F3 )
{
/// @todo IS vehicle in air.
auto vehicle = (VehicleObject*)(*p->at(0).handle);
return false;
}
VM_CONDOPCODE_DEF( 0x0204 )
{
auto controller = (CharacterController*)(*p->at(0).handle);
@ -544,6 +621,20 @@ VM_OPCODE_DEF( 0x029B )
*p->at(4).handle = inst;
}
VM_CONDOPCODE_DEF( 0x029C )
{
/*auto vehicle = (VehicleObject*)(*p->at(0).handle);
if( vehicle )
{
return vehicle->vehicle->type == VehicleData::BOAT;
}*/
return false;
}
VM_OPCODE_DEF( 0x02A3 )
{
m->getWorld()->state.isCinematic = !!p->at(0).integer;
}
VM_CONDOPCODE_DEF( 0x02DE )
{
@ -553,6 +644,14 @@ VM_CONDOPCODE_DEF( 0x02DE )
return vehicle && (vehicle->vehicle->classType & VehicleData::TAXI) == VehicleData::TAXI;
}
VM_OPCODE_DEF( 0x02E3 )
{
auto vehicle = (VehicleObject*)(*p->at(0).handle);
if( vehicle )
{
*p->at(1).globalReal = vehicle->physVehicle->getCurrentSpeedKmHour();
}
}
VM_OPCODE_DEF( 0x02E4 )
{
m->getWorld()->loadCutscene(p->at(0).string);
@ -840,7 +939,7 @@ Opcodes3::Opcodes3()
VM_OPCODE_DEC( 0x00A5, 5, "Create Vehicle" );
VM_OPCODE_DEC_U( 0x00BA, 3, "Print big" );
VM_OPCODE_DEC( 0x00BA, 3, "Print big" );
VM_OPCODE_DEC( 0x00BC, 3, "Print Message Now" );
VM_OPCODE_DEC( 0x00BE, 0, "Clear Message Prints" );
@ -889,9 +988,8 @@ Opcodes3::Opcodes3()
VM_OPCODE_DEC( 0x015C, 11, "Set zone ped info" );
VM_OPCODE_DEC_U( 0x015F, 6, "Set Fixed Camera Position" );
VM_OPCODE_DEC_U( 0x0160, 4, "Point Camera at Point" );
VM_OPCODE_DEC( 0x015F, 6, "Set Fixed Camera Position" );
VM_OPCODE_DEC( 0x0160, 4, "Point Camera at Point" );
VM_OPCODE_DEC_U( 0x0164, 1, "Disable Radar Blip" );
@ -928,8 +1026,12 @@ Opcodes3::Opcodes3()
VM_OPCODE_DEC( 0x01BD, 1, "Get Game Timer" );
VM_OPCODE_DEC_U( 0x01BE, 4, "Turn Character To Face Point" );
VM_OPCODE_DEC_U( 0x01C0, 2, "Store Wanted Level" );
VM_CONDOPCODE_DEC( 0x01C1, 1, "Is Vehicle Stopped" );
VM_OPCODE_DEC( 0x01C7, 1, "Don't remove object" );
VM_OPCODE_DEC( 0x01D4, 2, "Character Enter Vehicle as Passenger" );
VM_OPCODE_DEC( 0x01E7, 6, "Enable Roads" );
VM_OPCODE_DEC( 0x01E8, 6, "Disable Roads" );
@ -937,11 +1039,10 @@ Opcodes3::Opcodes3()
VM_OPCODE_DEC_U( 0x01EB, 1, "Set Traffic Density Multiplier" );
VM_OPCODE_DEC_U( 0x01ED, 1, "Clear Character Threat Search" );
VM_OPCODE_DEC_U( 0x01D4, 2, "Character Enter Vehicle as Passenger" );
VM_OPCODE_DEC( 0x01F0, 1, "Set Max Wanted Level" );
VM_CONDOPCODE_DEC( 0x01F3, 1, "Is Vehicle In Air" );
VM_CONDOPCODE_DEC( 0x01F4, 1, "Is Car Flipped" );
VM_OPCODE_DEC( 0x01F5, 2, "Get Player Character" );
@ -949,10 +1050,6 @@ Opcodes3::Opcodes3()
VM_OPCODE_DEC_U( 0x01F9, 9, "Start Kill Frenzy" );
VM_OPCODE_DEC_U( 0x01C0, 2, "Store Wanted Level" );
VM_CONDOPCODE_DEC( 0x01C1, 1, "Is Vehicle Stopped" );
VM_CONDOPCODE_DEC( 0x0204, 5, "Is Char near Car in Car 2D" );
VM_OPCODE_DEC_U( 0x020A, 2, "Lock Car Doors" );
@ -1000,15 +1097,17 @@ Opcodes3::Opcodes3()
VM_OPCODE_DEC_U( 0x0297, 0, "Reset Player Kills" );
VM_OPCODE_DEC( 0x029B, 5, "Create Object no offset" );
VM_CONDOPCODE_DEC( 0x029C, 1, "Is Vehicle Boat" );
VM_OPCODE_DEC_U( 0x02A2, 5, "Add Particle" );
VM_OPCODE_DEC_U( 0x02A3, 1, "Set Widescreen" );
VM_OPCODE_DEC( 0x02A3, 1, "Set Widescreen" );
VM_OPCODE_DEC_U( 0x02A7, 5, "Add Radar Contact Blip" );
VM_OPCODE_DEC_U( 0x02A8, 5, "Add Radar Blip" );
VM_CONDOPCODE_DEC( 0x02DE, 1, "Is Player In Taxi" );
VM_OPCODE_DEC( 0x02E3, 2, "Get Vehicle Speed" );
VM_OPCODE_DEC( 0x02E4, 1, "Load Cutscene Data" );
VM_OPCODE_DEC( 0x02E5, 2, "Create Cutscene Object" );
VM_OPCODE_DEC( 0x02E6, 2, "Set Cutscene Animation" );
@ -1089,6 +1188,8 @@ Opcodes3::Opcodes3()
VM_OPCODE_DEC_U( 0x03BF, 2, "Set Pedestrians Ignoring Player" );
VM_OPCODE_DEC_U( 0x03C1, 2, "Store Player Vehicle No-Save" );
VM_OPCODE_DEC_U( 0x03C4, 3, "Display Counter Message" );
VM_OPCODE_DEC_U( 0x03C5, 4, "Spawn Parked Vehicle" );
VM_CONDOPCODE_DEC( 0x03C6, 1, "Is Collision In Memory" );

View File

@ -73,6 +73,10 @@ VM_OPCODE_DEF( 0x001A ) {
t->conditionResult = p->at(0).integer > *p->at(1).globalInteger;
}
VM_OPCODE_DEF( 0x0020 ) {
t->conditionResult = *p->at(0).globalReal > p->at(1).integer;
}
VM_OPCODE_DEF( 0x0038 ) {
t->conditionResult = *p->at(0).globalInteger == p->at(1).integer;
}
@ -201,6 +205,8 @@ VM::VM()
VM_OPCODE_DEC( 0x0019, 2, "Local Int Greater than Int" );
VM_OPCODE_DEC( 0x001A, 2, "Int Greater Than Global Int" );
VM_OPCODE_DEC( 0x0020, 2, "Global Float Greather than Float" );
VM_OPCODE_DEC( 0x0038, 2, "Global Int Equal to Int" );

View File

@ -3,6 +3,7 @@
#include "loadingstate.hpp"
#include <engine/GameObject.hpp>
#include <engine/GameState.hpp>
#include <render/GameRenderer.hpp>
#include <script/ScriptMachine.hpp>
@ -193,6 +194,11 @@ void RWGame::render(float alpha)
viewCam.position = cameraPos;
viewCam.rotation = glm::inverse(glm::quat_cast(m)) * qtilt;
}
else if( engine->state.cameraFixed )
{
viewCam.position = engine->state.cameraPosition;
viewCam.rotation = engine->state.cameraRotation;
}
else
{
// There's no cutscene playing - use the camera returned by the State.
@ -258,15 +264,53 @@ void RWGame::render(float alpha)
window.draw(text);
tpos.y -= text.getLocalBounds().height;
}
for( int i = 0; i < engine->state.text.size(); )
{
if( engine->gameTime > engine->state.text[i].osTextStart + engine->state.text[i].osTextTime )
{
engine->state.text.erase(engine->state.text.begin() + i);
}
else
{
i++;
}
}
/// @todo this should be done by GameRenderer? but it doesn't have any font support yet
if( engine->gameTime < engine->state.osTextStart + engine->state.osTextTime ) {
sf::Text messageText(engine->state.osTextString, font, 15);
for(OnscreenText& t : engine->state.text)
{
float fontSize = 15.f;
switch(t.osTextStyle)
{
default:
fontSize = 15.f;
break;
case 1:
fontSize = 25.f;
break;
case 2:
fontSize = 20.f;
break;
}
sf::Text messageText(t.osTextString, font, fontSize);
auto sz = window.getSize();
auto b = messageText.getLocalBounds();
float lowerBar = sz.y - sz.y * 0.1f;
messageText.setPosition(sz.x / 2.f - std::round(b.width / 2.f), lowerBar - std::round(b.height / 2.f));
if(t.osTextStyle == 1)
{
messageText.setPosition(sz.x / 2.f - std::round(b.width / 2.f), sz.y / 2.f - std::round(b.height / 2.f));
}
else if(t.osTextStyle == 2)
{
messageText.setPosition(sz.x * 0.9f - std::round(b.width), sz.y * 0.8f - std::round(b.height / 2.f));
}
else
{
float lowerBar = sz.y - sz.y * 0.1f;
messageText.setPosition(sz.x / 2.f - std::round(b.width / 2.f), lowerBar - std::round(b.height / 2.f));
}
window.draw(messageText);
}

View File

@ -191,7 +191,13 @@ void IngameState::handleEvent(const sf::Event &event)
break;
case sf::Keyboard::Space:
if( player ) {
player->jump();
if( player->getCharacter()->getCurrentVehicle() ) {
player->getCharacter()->getCurrentVehicle()->setHandbraking(true);
}
else
{
player->jump();
}
}
break;
case sf::Keyboard::W: