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

Implement more opcodes

* Is Vehicle Flipped, Create character in vehicle, get time of day and many more
This commit is contained in:
Daniel Evans 2014-12-17 22:53:25 +00:00
parent ff04daf633
commit ed62b758d2
10 changed files with 312 additions and 34 deletions

View File

@ -70,6 +70,11 @@ struct GameState
* @brief Stores a pointer to script global that stores the on-mission state.
*/
unsigned int *scriptOnMissionFlag;
/** Objects created by mission scripts */
std::vector<GameObject*> missionObjects;
bool overrideNextStart;
glm::vec4 nextRestartLocation;
bool fadeOut;
float fadeStart;

View File

@ -85,6 +85,8 @@ public:
void tickPhysics(float dt);
bool isFlipped() const;
void ejectAll();
GameObject* getOccupant(size_t seat);

View File

@ -8,15 +8,16 @@ CollisionInstance::~CollisionInstance()
{
if( body ) {
GameObject* object = static_cast<GameObject*>(body->getUserPointer());
body->setUserPointer(nullptr);
// Remove body from existance.
object->engine->dynamicsWorld->removeCollisionObject(body);
delete body;
object->engine->dynamicsWorld->removeRigidBody(body);
for(auto shape : shapes) {
delete shape;
}
delete body;
}
if( vertArray ) {
delete vertArray;

View File

@ -351,7 +351,7 @@ SCMFile *GameData::loadSCM(const std::string &path)
f.read(buff, size);
SCMFile* scm = new SCMFile;
scm->loadFile(buff, size);
delete buff;
delete[] buff;
return scm;
}

View File

@ -246,10 +246,6 @@ void CharacterObject::setPosition(const glm::vec3& pos)
{
btVector3 bpos(pos.x, pos.y, pos.z);
physCharacter->warp(bpos);
auto& wt = physObject->getWorldTransform();
wt.setOrigin(bpos);
physObject->setWorldTransform(wt);
GameObject::setPosition(pos);
}
glm::vec3 CharacterObject::getPosition() const

View File

@ -133,7 +133,6 @@ glm::quat VehicleObject::getRotation() const
}
#include <glm/gtc/type_ptr.hpp>
#include <boost/concept_check.hpp>
void VehicleObject::tick(float dt)
{
@ -319,6 +318,12 @@ void VehicleObject::tickPhysics(float dt)
}
}
bool VehicleObject::isFlipped() const
{
auto up = getRotation() * glm::vec3(0.f, 0.f, 1.f);
return up.z <= -0.1f;
}
void VehicleObject::setSteeringAngle(float a)
{
steerAngle = a;

View File

@ -92,13 +92,45 @@ VM_OPCODE_DEF( 0x009A )
if( position.z < -99.f ) {
position = m->getWorld()->getGroundAtPosition(position);
}
// If there is already a chracter less than this distance away, it will be destroyed.
const float replaceThreshold = 2.f;
for( auto it = m->getWorld()->objects.begin();
it != m->getWorld()->objects.end();
++it)
{
if( glm::distance(position, (*it)->getPosition()) < replaceThreshold )
{
std::cout << (*it)->type() << std::endl;
}
if( (*it)->type() == GameObject::Character && glm::distance(position, (*it)->getPosition()) < replaceThreshold )
{
m->getWorld()->destroyObjectQueued(*it);
}
}
auto character = m->getWorld()->createPedestrian(id, position + spawnMagic);
auto controller = new DefaultAIController(character);
if ( t->isMission )
{
m->getWorld()->state.missionObjects.push_back(character);
}
*p->at(5).handle = controller;
}
VM_OPCODE_DEF( 0x009B )
{
auto controller = static_cast<CharacterController*>(*p->at(0).handle);
if ( controller )
{
m->getWorld()->destroyObjectQueued(controller->getCharacter());
}
}
VM_OPCODE_DEF( 0x00A5 )
{
auto id = p->at(0).integer;
@ -118,10 +150,35 @@ VM_OPCODE_DEF( 0x00A5 )
}
auto vehicle = m->getWorld()->createVehicle(id, position);
if ( t->isMission )
{
m->getWorld()->state.missionObjects.push_back(vehicle);
}
*p->at(4).handle = vehicle;
}
VM_OPCODE_DEF( 0x00A6 )
{
auto vehicle = static_cast<VehicleObject*>(*p->at(0).handle);
m->getWorld()->destroyObjectQueued(vehicle);
}
VM_OPCODE_DEF( 0x00AA )
{
auto vehicle = static_cast<VehicleObject*>(*p->at(0).handle);
if( vehicle )
{
auto vp = vehicle->getPosition();
*p->at(1).globalReal = vp.x;
*p->at(2).globalReal = vp.y;
*p->at(3).globalReal = vp.z;
}
}
VM_OPCODE_DEF( 0x00BA )
{
std::string id(p->at(0).string);
@ -155,6 +212,12 @@ VM_OPCODE_DEF( 0x00BE )
m->getWorld()->state.text.clear();
}
VM_OPCODE_DEF( 0x00BF )
{
*p->at(0).globalInteger = m->getWorld()->getHour();
*p->at(1).globalInteger = m->getWorld()->getMinute();
}
VM_OPCODE_DEF( 0x00C0 )
{
m->getWorld()->state.hour = p->at(0).integer;
@ -268,7 +331,12 @@ VM_CONDOPCODE_DEF( 0x0112 )
VM_CONDOPCODE_DEF( 0x0118 )
{
auto controller = static_cast<CharacterController*>(*p->at(0).handle);
return !controller->getCharacter()->isAlive();
if ( controller )
{
return !controller->getCharacter()->isAlive();
}
return true;
}
VM_CONDOPCODE_DEF( 0x0119 )
@ -289,13 +357,28 @@ VM_CONDOPCODE_DEF( 0x0121 )
auto& max = zfind->second.max;
if( player.x > min.x && player.y > min.y && player.z > min.z &&
player.x < max.x && player.y < max.y && player.z < max.z ) {
std::cout << "Player is in zone! " << zfind->second.name << std::endl;
return true;
}
}
return false;
}
VM_OPCODE_DEF( 0x0129 )
{
auto vehicle = static_cast<VehicleObject*>(*p->at(0).handle);
auto type = p->at(1).integer;
auto id = p->at(2).integer;
auto character = m->getWorld()->createPedestrian(id, vehicle->getPosition() + spawnMagic);
auto controller = new DefaultAIController(character);
character->setCurrentVehicle(vehicle, 0);
vehicle->setOccupant(0, character);
*p->at(3).handle = controller;
}
VM_OPCODE_DEF( 0x014B )
{
glm::vec3 position(p->at(0).real, p->at(1).real, p->at(2).real);
@ -357,7 +440,6 @@ VM_OPCODE_DEF( 0x0159 )
if( controller != nullptr )
{
m->getWorld()->state.cameraTarget = controller->getCharacter();
m->getWorld()->state.cameraFixed = false;
}
}
@ -440,6 +522,14 @@ VM_CONDOPCODE_DEF( 0x016B )
m->getWorld()->state.fadeStart + m->getWorld()->state.fadeTime;
}
VM_OPCODE_DEF( 0x016E )
{
m->getWorld()->state.overrideNextStart = true;
m->getWorld()->state.nextRestartLocation = glm::vec4(
p->at(0).real, p->at(1).real, p->at(2).real, p->at(3).real
);
}
VM_OPCODE_DEF( 0x0171 )
{
auto controller = (CharacterController*)(*p->at(0).handle);
@ -452,6 +542,16 @@ VM_OPCODE_DEF( 0x0173 )
controller->getCharacter()->setHeading(p->at(1).real);
}
VM_OPCODE_DEF( 0x0174 )
{
auto vehicle = static_cast<VehicleObject*>(*p->at(0).handle);
if ( vehicle )
{
*p->at(1).globalReal = 0.f;
}
}
VM_OPCODE_DEF( 0x0175 )
{
auto vehicle = (VehicleObject*)(*p->at(0).handle);
@ -474,6 +574,48 @@ VM_CONDOPCODE_DEF( 0x019C )
return false;
}
VM_CONDOPCODE_DEF( 0x01A0 )
{
auto controller = static_cast<CharacterController*>(*p->at(0).handle);
if( controller && controller->getCharacter()->getCurrentVehicle() != nullptr )
{
glm::vec3 min(p->at(1).real, p->at(2).real, p->at(3).real);
glm::vec3 max(p->at(4).real, p->at(5).real, p->at(6).real);
glm::vec3 pp = controller->getCharacter()->getCurrentVehicle()->getPosition();
if( pp.x >= min.x && pp.y >= min.y && pp.z >= min.z &&
pp.x <= max.x && pp.y <= max.y && pp.z <= max.z )
{
return controller->getCharacter()->getCurrentVehicle()->physVehicle->getCurrentSpeedKmHour() < 0.1f;
}
}
return false;
}
VM_CONDOPCODE_DEF( 0x01AA )
{
auto controller = static_cast<CharacterController*>(*p->at(0).handle);
if( controller && controller->getCharacter()->getCurrentVehicle() != nullptr )
{
glm::vec3 min(p->at(1).real, p->at(2).real, p->at(3).real);
glm::vec3 max(p->at(4).real, p->at(5).real, p->at(6).real);
glm::vec3 pp = controller->getCharacter()->getCurrentVehicle()->getPosition();
if( pp.x >= min.x && pp.y >= min.y && pp.z >= min.z &&
pp.x <= max.x && pp.y <= max.y && pp.z <= max.z )
{
return controller->getCharacter()->getCurrentVehicle()->physVehicle->getCurrentSpeedKmHour() < 0.1f;
}
}
return false;
}
VM_OPCODE_DEF( 0x01B4 )
{
auto controller = static_cast<PlayerController*>(*p->at(0).handle);
@ -492,6 +634,12 @@ VM_OPCODE_DEF( 0x01BD )
VM_CONDOPCODE_DEF( 0x01C1 )
{
auto vehicle = static_cast<VehicleObject*>(*p->at(0).handle);
if( vehicle )
{
return std::abs( vehicle->physVehicle->getCurrentSpeedKmHour() ) <= 0.01f;
}
return false;
}
@ -531,6 +679,13 @@ VM_OPCODE_DEF( 0x01F0 )
VM_CONDOPCODE_DEF( 0x01F4 )
{
auto vehicle = static_cast<VehicleObject*>(*p->at(0).handle);
if( vehicle )
{
return vehicle->isFlipped();
}
return false;
}
@ -622,7 +777,7 @@ VM_CONDOPCODE_DEF( 0x023D )
}
}
return false;
return true;
}
VM_OPCODE_DEF( 0x0244 )
@ -645,6 +800,21 @@ VM_CONDOPCODE_DEF( 0x0248 )
return true;
}
VM_OPCODE_DEF( 0x0255 )
{
// Reset player state.
auto controller = m->getWorld()->state.player;
controller->getCharacter()->setCurrentVehicle(nullptr, 0);
glm::vec3 position(p->at(0).real, p->at(1).real, p->at(2).real + 1.f);
controller->getCharacter()->setPosition(position + spawnMagic);
controller->getCharacter()->setHeading( p->at(3).real );
std::cout << glm::distance(controller->getCharacter()->getPosition(), position) << std::endl;
}
/// @todo http://www.gtamodding.com/index.php?title=0256 (e.g. check if dead or busted)
VM_CONDOPCODE_DEF( 0x0256 )
{
@ -699,6 +869,11 @@ VM_OPCODE_DEF( 0x02A3 )
m->getWorld()->state.isCinematic = !!p->at(0).integer;
}
VM_CONDOPCODE_DEF( 0x02B3 )
{
return false;
}
VM_CONDOPCODE_DEF( 0x02DE )
{
auto controller = static_cast<CharacterController*>(*p->at(0).handle);
@ -1002,6 +1177,18 @@ VM_CONDOPCODE_DEF( 0x03EE )
return true;
}
VM_OPCODE_DEF( 0x03F3 )
{
auto vehicle = static_cast<VehicleObject*>(*p->at(0).handle);
if ( vehicle )
{
/// @TODO use correct values.
*p->at(1).globalInteger = 0;
*p->at(2).globalInteger = 0;
}
}
VM_OPCODE_DEF( 0x03F7 )
{
// Collision is loaded when required, not sure what this is supposed to mean.
@ -1031,11 +1218,37 @@ VM_OPCODE_DEF( 0x043D )
m->getWorld()->state.isIntroPlaying = !!p->at(0).integer;
}
VM_CONDOPCODE_DEF( 0x0442 )
{
auto controller = static_cast<CharacterController*>(*p->at(0).handle);
auto vehicle = static_cast<VehicleObject*>(*p->at(1).handle);
if( vehicle && controller )
{
return controller->getCharacter()->getCurrentVehicle() == vehicle;
}
return false;
}
VM_CONDOPCODE_DEF( 0x0445 )
{
return false;
}
VM_CONDOPCODE_DEF( 0x0448 )
{
auto controller = static_cast<CharacterController*>(*p->at(0).handle);
auto vehicle = static_cast<VehicleObject*>(*p->at(1).handle);
if( vehicle && controller )
{
return controller->getCharacter()->getCurrentVehicle() == vehicle;
}
return false;
}
VM_OPCODE_DEF( 0x044D )
{
m->getWorld()->gameData.loadSplash(p->at(0).string);
@ -1054,20 +1267,23 @@ Opcodes3::Opcodes3()
VM_CONDOPCODE_DEC( 0x0057, 8, "Is Player In Area 3D" );
VM_OPCODE_DEC( 0x009A, 6, "Create Character" );
VM_OPCODE_DEC( 0x009B, 1, "Destroy Character" );
VM_OPCODE_DEC( 0x00A5, 5, "Create Vehicle" );
VM_OPCODE_DEC( 0x00A6, 1, "Destroy Vehicle" );
VM_OPCODE_DEC_U( 0x00A7, 4, "Drive To" );
VM_OPCODE_DEC( 0x00AA, 4, "Get Vehicle Position" );
VM_OPCODE_DEC_U( 0x00AD, 2, "Set Driving Speed" );
VM_OPCODE_DEC_U( 0x00AE, 2, "Set Driving Style" );
VM_OPCODE_DEC( 0x00BA, 3, "Print big" );
VM_OPCODE_DEC( 0x00BC, 3, "Print Message Now" );
VM_OPCODE_DEC( 0x00BE, 0, "Clear Message Prints" );
VM_OPCODE_DEC( 0x00C0, 2, "Set Time Of Day" );
VM_OPCODE_DEC( 0x00BF, 2, "Get Time of Day" );
VM_OPCODE_DEC( 0x00C0, 2, "Set Time of Day" );
VM_OPCODE_DEC_U( 0x00DA, 2, "Store Player Car" );
VM_CONDOPCODE_DEC( 0x00DB, 2, "Is Character in Vehicle" );
@ -1097,7 +1313,7 @@ Opcodes3::Opcodes3()
VM_CONDOPCODE_DEC( 0x0121, 2, "Is Player In Zone" );
VM_OPCODE_DEC_U( 0x0129, 4, "Create Character In Car" );
VM_OPCODE_DEC( 0x0129, 4, "Create Character In Car" );
VM_OPCODE_DEC( 0x014B, 13, "Create Car Generator" );
VM_OPCODE_DEC( 0x014C, 2, "Set Car Generator count" );
@ -1126,11 +1342,12 @@ Opcodes3::Opcodes3()
VM_CONDOPCODE_DEC( 0x016B, 0, "Is Screen Fading" );
VM_OPCODE_DEC_U( 0x016C, 4, "Add Hospital Restart" );
VM_OPCODE_DEC_U( 0x016D, 4, "Add Police Restart" );
VM_OPCODE_DEC_U( 0x016E, 4, "Override Next Restart" );
VM_OPCODE_DEC( 0x016E, 4, "Override Next Restart" );
VM_OPCODE_DEC( 0x0171, 2, "Set Player Heading" );
VM_OPCODE_DEC( 0x0173, 2, "Set Character Heading" );
VM_OPCODE_DEC( 0x0174, 2, "Get Vehicle Heading" );
VM_OPCODE_DEC( 0x0175, 2, "Set Vehicle heading" );
@ -1150,16 +1367,25 @@ Opcodes3::Opcodes3()
VM_OPCODE_DEC_U( 0x018E, 1, "Remove Sound" );
VM_CONDOPCODE_DEC( 0x019C, 8, "Is Player in Area on Foot" );
VM_CONDOPCODE_DEC( 0x01A0, 8, "Is Player Stopped in cube in vehicle" );
VM_CONDOPCODE_DEC( 0x01AA, 8, "Is Char Stopped in cube in vehicle" );
VM_OPCODE_DEC( 0x01B4, 2, "Set Player Input Enabled" );
VM_OPCODE_DEC( 0x01B6, 1, "Set Weather Now" );
VM_OPCODE_DEC_U( 0x01BB, 4, "Get Object Coordinates" );
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_U( 0x01C3, 1, "Mark Car Unneeded" );
VM_OPCODE_DEC( 0x01C7, 1, "Don't remove object" );
VM_OPCODE_DEC( 0x01D4, 2, "Character Enter Vehicle as Passenger" );
@ -1218,7 +1444,8 @@ Opcodes3::Opcodes3()
VM_OPCODE_DEC_U( 0x0249, 1, "Mark Model As Unneeded" );
VM_OPCODE_DEC_U( 0x0250, 6, "Create Light" );
VM_OPCODE_DEC( 0x0255, 4, "Restart Critical Mission" );
VM_CONDOPCODE_DEC( 0x0256, 1, "Is Player Playing" );
VM_OPCODE_DEC( 0x0293, 1, "Get Controller Mode" );
@ -1235,6 +1462,8 @@ Opcodes3::Opcodes3()
VM_OPCODE_DEC_U( 0x02A7, 5, "Add Radar Contact Blip" );
VM_OPCODE_DEC_U( 0x02A8, 5, "Add Radar Blip" );
VM_CONDOPCODE_DEC( 0x02B3, 9, "Is Player In Area" );
VM_CONDOPCODE_DEC( 0x02DE, 1, "Is Player In Taxi" );
@ -1311,6 +1540,8 @@ Opcodes3::Opcodes3()
VM_OPCODE_DEC_U( 0x039E, 2, "Set Character can be dragged out" );
VM_OPCODE_DEC_U( 0x03AD, 1, "Set Garbage Enabled" );
VM_OPCODE_DEC_U( 0x03AE, 6, "Remove Particles in Area" );
VM_OPCODE_DEC_U( 0x03AF, 1, "Set Map Streaming Enabled" );
@ -1345,7 +1576,8 @@ Opcodes3::Opcodes3()
VM_OPCODE_DEC( 0x03E5, 1, "Display Help Text" );
VM_OPCODE_DEC_U( 0x03E6, 0, "Clear Help Text" );
VM_OPCODE_DEC_U( 0x03E7, 1, "Flash HUD Item" );
VM_OPCODE_DEC_U( 0x03EB, 0, "Clear Small Prints" );
VM_CONDOPCODE_DEC( 0x03EE, 1, "Can Player Move" );
@ -1354,6 +1586,7 @@ Opcodes3::Opcodes3()
VM_OPCODE_DEC_U( 0x03F0, 1, "Enable Text Draw" );
VM_OPCODE_DEC_U( 0x03F1, 2, "Set Ped Hostility" );
VM_OPCODE_DEC_U( 0x03F2, 2, "Clear Ped Hostility" );
VM_OPCODE_DEC( 0x03F3, 3, "Get Vehicle Colours" );
VM_OPCODE_DEC( 0x03F7, 1, "Load Collision" );
@ -1375,7 +1608,9 @@ Opcodes3::Opcodes3()
VM_OPCODE_DEC( 0x043C, 1, "Set Sound Fade" );
VM_OPCODE_DEC( 0x043D, 1, "Set Is Intro Playing" );
VM_CONDOPCODE_DEC( 0x0442, 2, "Is Player in This Vehicle" );
VM_CONDOPCODE_DEC( 0x0445, 0, "Are Any Vehicle Cheats enabled" );
VM_CONDOPCODE_DEC( 0x0448, 2, "Is Character in This Vehicle" );
VM_OPCODE_DEC( 0x044D, 1, "Load Splash Screen" );

View File

@ -78,7 +78,20 @@ VM_OPCODE_DEF( 0x001B ) {
}
VM_OPCODE_DEF( 0x0020 ) {
t->conditionResult = *p->at(0).globalReal > p->at(1).integer;
t->conditionResult = *p->at(0).globalReal > p->at(1).real;
}
VM_OPCODE_DEF( 0x0028 ) {
t->conditionResult = *p->at(0).globalInteger >= p->at(1).integer;
}
VM_OPCODE_DEF( 0x0029 )
{
t->conditionResult = *p->at(0).globalInteger >= p->at(1).integer;
}
VM_OPCODE_DEF( 0x002A ) {
t->conditionResult = p->at(0).integer >= *p->at(1).globalInteger;
}
VM_OPCODE_DEF( 0x0038 ) {
@ -150,7 +163,7 @@ VM_OPCODE_DEF( 0x00D6 )
t->conditionAND = true;
}
else {
t->conditionCount = n-7;
t->conditionCount = n-19;
t->conditionMask = 0x00;
t->conditionAND = false;
}
@ -165,6 +178,14 @@ VM_OPCODE_DEF( 0x00D7 )
VM_OPCODE_DEF( 0x00D8 )
{
std::cout << "Ended: " << t->name << std::endl;
for( auto& o : m->getWorld()->state.missionObjects )
{
m->getWorld()->destroyObjectQueued(o);
}
m->getWorld()->state.missionObjects.clear();
*m->getWorld()->state.scriptOnMissionFlag = 0;
}
@ -212,7 +233,12 @@ VM::VM()
VM_OPCODE_DEC( 0x001B, 2, "Int Greater Than Var Int" );
VM_OPCODE_DEC( 0x0020, 2, "Global Float Greather than Float" );
VM_OPCODE_DEC( 0x0028, 2, "Global Int >= Int" );
VM_OPCODE_DEC( 0x0029, 2, "Local Int >= Int" );
VM_OPCODE_DEC( 0x002A, 2, "Int >= Global Int" );
VM_OPCODE_DEC( 0x0038, 2, "Global Int Equal to Int" );
VM_OPCODE_DEC( 0x0039, 2, "Local Int Equal to Int" );

View File

@ -58,13 +58,13 @@ void ScriptMachine::executeThread(SCMThread &t, int msPassed)
break;
case TGlobal: {
auto v = _file->read<std::uint16_t>(t.programCounter);
parameters.back().globalPtr = _globals + v * (SCM_VARIABLE_SIZE/4);
parameters.back().globalPtr = _globals + v * sizeof(SCMByte) * 4;
t.programCounter += sizeof(SCMByte) * 2;
}
break;
case TLocal: {
auto v = _file->read<std::uint16_t>(t.programCounter);
parameters.back().globalPtr = t.locals + v * (SCM_VARIABLE_SIZE/4);
parameters.back().globalPtr = t.locals + v * sizeof(SCMByte) * 4;
t.programCounter += sizeof(SCMByte) * 2;
}
break;
@ -180,13 +180,21 @@ void ScriptMachine::executeThread(SCMThread &t, int msPassed)
}
else
{
t.conditionMask |= (!! t.conditionResult) << cI;
t.conditionMask = t.conditionMask || t.conditionResult;
}
t.conditionResult = (t.conditionMask != 0);
}
}
SCMOpcodeParameter p;
p.globalPtr = (t.locals + 16 * sizeof ( SCMByte ) * 4);
*p.globalInteger += msPassed;
p.globalPtr = (t.locals + 17 * sizeof ( SCMByte ) * 4);
*p.globalInteger += msPassed;
if( t.wakeCounter == -1 ) {
t.wakeCounter = 0;
}

View File

@ -131,12 +131,12 @@ void RWGame::tick(float dt)
object->_updateLastTransform();
object->tick(dt);
}
engine->destroyQueuedObjects();
engine->state.texts.clear();
engine->dynamicsWorld->stepSimulation(dt, 2, dt);
if( engine->script ) {
try {
engine->script->execute(dt);