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

Merge pull request #142 from danhedron/feature/aggressive-borrowing

Implement stealing vehicle
This commit is contained in:
Daniel Evans 2016-06-15 23:44:11 +01:00 committed by GitHub
commit 6020bc78db
4 changed files with 98 additions and 30 deletions

View File

@ -67,7 +67,7 @@ protected:
bool updateActivity();
void setActivity(Activity* activity);
float vehicleIdle;
float m_closeDoorTimer;
// Goal related variables
Goal currentGoal;
@ -190,7 +190,10 @@ namespace Activities {
struct ExitVehicle : public CharacterController::Activity {
DECL_ACTIVITY( ExitVehicle )
ExitVehicle( )
const bool jacked;
ExitVehicle(bool jacked_ = false)
: jacked(jacked_)
{}
bool update(CharacterObject *character, CharacterController *controller);

View File

@ -65,10 +65,14 @@ struct AnimationGroup
Animation* car_open_lhs;
Animation* car_getin_lhs;
Animation* car_getout_lhs;
Animation* car_jacked_lhs;
Animation* car_pullout_lhs;
Animation* car_open_rhs;
Animation* car_getin_rhs;
Animation* car_getout_rhs;
Animation* car_jacked_rhs;
Animation* car_pullout_rhs;
Animation* kd_front;
Animation* ko_shot_front;

View File

@ -7,11 +7,13 @@
#include <items/WeaponItem.hpp>
#include <rw/defines.hpp>
constexpr float kCloseDoorIdleTime = 2.f;
CharacterController::CharacterController(CharacterObject* character)
: character(character)
, _currentActivity(nullptr)
, _nextActivity(nullptr)
, vehicleIdle(0.f)
, m_closeDoorTimer(0.f)
, currentGoal(None)
, leader(nullptr)
, targetNode(nullptr)
@ -80,28 +82,27 @@ void CharacterController::update(float dt)
}
if( _currentActivity == nullptr ) {
if( glm::length( d ) <= 0.1f )
{
vehicleIdle += dt;
}
else
{
vehicleIdle = 0.f;
}
if( vehicleIdle >= 1.f )
{
// If character is idle in vehicle, try to close the door.
auto v = character->getCurrentVehicle();
auto entryDoor = v->getSeatEntryDoor(character->getCurrentSeat());
if( entryDoor && entryDoor->constraint )
{
character->getCurrentVehicle()->setPartTarget(entryDoor, true, entryDoor->closedAngle);
// If character is idle in vehicle, try to close the door.
auto v = character->getCurrentVehicle();
auto entryDoor = v->getSeatEntryDoor(character->getCurrentSeat());
if (entryDoor && entryDoor->constraint) {
if (glm::length( d ) <= 0.1f) {
if (m_closeDoorTimer >= kCloseDoorIdleTime) {
character->getCurrentVehicle()->setPartTarget(entryDoor, true, entryDoor->closedAngle);
}
m_closeDoorTimer += dt;
}
else {
m_closeDoorTimer = 0.f;
}
}
}
}
else
{
m_closeDoorTimer = 0.f;
}
if( updateActivity() ) {
character->activityFinished();
@ -219,18 +220,24 @@ bool Activities::EnterVehicle::update(CharacterObject *character, CharacterContr
auto anm_open = character->animations.car_open_lhs;
auto anm_enter = character->animations.car_getin_lhs;
auto anm_pullout = character->animations.car_pullout_lhs;
if( entryDoor->dummy->getDefaultTranslation().x > 0.f )
{
anm_open = character->animations.car_open_rhs;
anm_enter = character->animations.car_getin_rhs;
anm_pullout = character->animations.car_pullout_rhs;
}
// If there's someone in this seat already, we may have to ask them to leave.
auto currentOccupant= static_cast<CharacterObject*>(vehicle->getOccupant(seat));
bool tryToEnter = false;
if( entering ) {
if( character->animator->getAnimation(AnimIndexAction) == anm_open ) {
if( character->animator->isCompleted(AnimIndexAction) ) {
character->playActivityAnimation(anm_enter, false, true);
character->enterVehicle(vehicle, seat);
tryToEnter = true;
}
else if( entryDoor && character->animator->getAnimationTime(AnimIndexAction) >= 0.5f )
{
@ -241,6 +248,11 @@ bool Activities::EnterVehicle::update(CharacterObject *character, CharacterContr
character->rotation = vehicle->getRotation();
}
}
else if (character->animator->getAnimation(AnimIndexAction) == anm_pullout) {
if (character->animator->isCompleted(AnimIndexAction)) {
tryToEnter = true;
}
}
else if( character->animator->getAnimation(AnimIndexAction) == anm_enter ) {
if( character->animator->isCompleted(AnimIndexAction) ) {
// VehicleGetIn is over, finish activity
@ -266,8 +278,7 @@ bool Activities::EnterVehicle::update(CharacterObject *character, CharacterContr
// Determine if the door open animation should be skipped.
if( entryDoor == nullptr || (entryDoor->constraint != nullptr && glm::abs(entryDoor->constraint->getHingeAngle()) >= 0.6f ) )
{
character->playActivityAnimation(anm_enter, false, true);
character->enterVehicle(vehicle, seat);
tryToEnter = true;
}
else
{
@ -286,6 +297,18 @@ bool Activities::EnterVehicle::update(CharacterObject *character, CharacterContr
character->controller->setMoveDirection({1.f, 0.f, 0.f});
}
}
if (tryToEnter) {
if (currentOccupant != nullptr && currentOccupant != character) {
// Play the pullout animation and tell the other character to get out.
character->playActivityAnimation(anm_pullout, false, true);
currentOccupant->controller->setNextActivity(new Activities::ExitVehicle(true));
}
else {
character->playActivityAnimation(anm_enter, false, true);
character->enterVehicle(vehicle, seat);
}
}
return false;
}
@ -294,15 +317,49 @@ bool Activities::ExitVehicle::update(CharacterObject *character, CharacterContro
{
RW_UNUSED(controller);
if (jacked) {
auto anm_jacked_lhs = character->animations.car_jacked_lhs;
auto anm_jacked_rhs = character->animations.car_jacked_lhs;
auto anm_current = character->animator->getAnimation(AnimIndexAction);
if (anm_current == anm_jacked_lhs || anm_current == anm_jacked_rhs) {
if (character->animator->isCompleted(AnimIndexAction)) {
return true;
}
}
else {
if (character->getCurrentVehicle() == nullptr) return true;
auto vehicle = character->getCurrentVehicle();
auto seat = character->getCurrentSeat();
auto door = vehicle->getSeatEntryDoor(seat);
character->rotation = vehicle->getRotation();
// Exit the vehicle immediatley
auto exitpos = vehicle->getSeatEntryPosition(seat);
character->enterVehicle(nullptr, seat);
character->setPosition(exitpos);
if (door->dummy->getDefaultTranslation().x > 0.f) {
character->playActivityAnimation(anm_jacked_rhs, false, true);
}
else {
character->playActivityAnimation(anm_jacked_lhs, false, true);
}
// No need to open the door, it should already be open.
}
return false;
}
if( character->getCurrentVehicle() == nullptr ) return true;
auto vehicle = character->getCurrentVehicle();
auto seat = character->getCurrentSeat();
auto door = vehicle->getSeatEntryDoor(seat);
auto anm_exit = character->animations.car_getout_lhs;
if( door->dummy->getDefaultTranslation().x > 0.f )
{
anm_exit = character->animations.car_getout_rhs;

View File

@ -52,10 +52,14 @@ CharacterObject::CharacterObject(GameWorld* engine, const glm::vec3& pos, const
animations.car_open_lhs = engine->data->animations["car_open_lhs"];
animations.car_getin_lhs = engine->data->animations["car_getin_lhs"];
animations.car_getout_lhs = engine->data->animations["car_getout_lhs"];
animations.car_pullout_lhs = engine->data->animations["car_pullout_lhs"];
animations.car_jacked_lhs = engine->data->animations["car_jackedlhs"];
animations.car_open_rhs = engine->data->animations["car_open_rhs"];
animations.car_getin_rhs = engine->data->animations["car_getin_rhs"];
animations.car_getout_rhs = engine->data->animations["car_getout_rhs"];
animations.car_pullout_rhs = engine->data->animations["car_pullout_rhs"];
animations.car_jacked_rhs = engine->data->animations["car_jackedrhs"];
animations.kd_front = engine->data->animations["kd_front"];
animations.ko_shot_front = engine->data->animations["ko_shot_front"];