diff --git a/src/items/attachment.cpp b/src/items/attachment.cpp index d579ad0b4..40f2c299b 100644 --- a/src/items/attachment.cpp +++ b/src/items/attachment.cpp @@ -292,14 +292,52 @@ void Attachment::hitBanana(Item *item, int new_attachment) } // hitBanana //----------------------------------------------------------------------------- -//** Moves a bomb from kart FROM to kart TO. -void Attachment::moveBombFromTo(Kart *from, Kart *to) +/** Updates the attachments in case of a kart-kart collision. This must only + * be called for one of the karts in the collision, since it will update + * the attachment for both karts. + * \param other Pointer to the other kart hit. + */ +void Attachment::handleCollisionWithKart(Kart *other) { - to->getAttachment()->set(ATTACH_BOMB, - from->getAttachment()->getTimeLeft()+ - stk_config->m_bomb_time_increase, from); - from->getAttachment()->clear(); -} // moveBombFromTo + Attachment *attachment_other=other->getAttachment(); + + if(getType()==Attachment::ATTACH_BOMB) + { + // If both karts have a bomb, explode them immediately: + if(attachment_other->getType()==Attachment::ATTACH_BOMB) + { + setTimeLeft(0.0f); + attachment_other->setTimeLeft(0.0f); + } + else // only this kart has a bomb, move it to the other + { + if(getPreviousOwner()!=other) + { + // Don't move if this bomb was from other kart originally + other->getAttachment()->set(ATTACH_BOMB, + getTimeLeft()+ + stk_config->m_bomb_time_increase, + m_kart); + other->playCustomSFX(SFXManager::CUSTOM_ATTACH); + clear(); + } + } + } // type==BOMB + else if(attachment_other->getType()==Attachment::ATTACH_BOMB && + attachment_other->getPreviousOwner()!=m_kart) + { + set(ATTACH_BOMB, other->getAttachment()->getTimeLeft()+ + stk_config->m_bomb_time_increase, other); + other->getAttachment()->clear(); + m_kart->playCustomSFX(SFXManager::CUSTOM_ATTACH); + } + else + { + m_kart->playCustomSFX(SFXManager::CUSTOM_CRASH); + other->playCustomSFX(SFXManager::CUSTOM_CRASH); + } + +} // handleCollisionWithKart //----------------------------------------------------------------------------- void Attachment::update(float dt) diff --git a/src/items/attachment.hpp b/src/items/attachment.hpp index d0c1c1786..7096c19dc 100644 --- a/src/items/attachment.hpp +++ b/src/items/attachment.hpp @@ -99,9 +99,9 @@ public: void clear (); void hitBanana(Item *item, int new_attachment=-1); void update (float dt); - void moveBombFromTo(Kart *from, Kart *to); - + void handleCollisionWithKart(Kart *other); void set (AttachmentType type, float time, Kart *previous_kart=NULL); + // ------------------------------------------------------------------------ /** Sets the type of the attachment, but keeps the old time left value. */ void set (AttachmentType type) { set(type, m_time_left); } diff --git a/src/items/powerup.cpp b/src/items/powerup.cpp index fec60e7e9..40d6bf5a5 100644 --- a/src/items/powerup.cpp +++ b/src/items/powerup.cpp @@ -22,6 +22,7 @@ #include "audio/sfx_manager.hpp" #include "config/user_config.hpp" #include "config/stk_config.hpp" +#include "items/attachment.hpp" #include "items/item_manager.hpp" #include "items/projectile_manager.hpp" #include "karts/kart.hpp" diff --git a/src/items/rubber_ball.cpp b/src/items/rubber_ball.cpp index 4b88fcd5c..acdbffb0c 100644 --- a/src/items/rubber_ball.cpp +++ b/src/items/rubber_ball.cpp @@ -20,6 +20,7 @@ #include "audio/sfx_base.hpp" #include "audio/sfx_manager.hpp" +#include "items/attachment.hpp" #include "items/projectile_manager.hpp" #include "karts/kart.hpp" #include "modes/linear_world.hpp" diff --git a/src/karts/controller/default_ai_controller.cpp b/src/karts/controller/default_ai_controller.cpp index 7609d8927..8ebee2d92 100644 --- a/src/karts/controller/default_ai_controller.cpp +++ b/src/karts/controller/default_ai_controller.cpp @@ -39,6 +39,7 @@ # include "graphics/irr_driver.hpp" #endif #include "graphics/slip_stream.hpp" +#include "items/attachment.hpp" #include "modes/linear_world.hpp" #include "network/network_manager.hpp" #include "race/race_manager.hpp" diff --git a/src/karts/controller/new_ai_controller.cpp b/src/karts/controller/new_ai_controller.cpp index 6b6020078..b13bedbd8 100644 --- a/src/karts/controller/new_ai_controller.cpp +++ b/src/karts/controller/new_ai_controller.cpp @@ -38,6 +38,7 @@ #ifdef AI_DEBUG #include "graphics/irr_driver.hpp" #endif +#include "items/attachment.hpp" #include "modes/linear_world.hpp" #include "network/network_manager.hpp" #include "race/race_manager.hpp" diff --git a/src/karts/controller/player_controller.cpp b/src/karts/controller/player_controller.cpp index ff7d41721..719ee9d9d 100644 --- a/src/karts/controller/player_controller.cpp +++ b/src/karts/controller/player_controller.cpp @@ -25,6 +25,7 @@ #include "graphics/camera.hpp" #include "graphics/irr_driver.hpp" #include "input/input_manager.hpp" +#include "items/attachment.hpp" #include "items/item.hpp" #include "modes/world.hpp" #include "race/history.hpp" diff --git a/src/karts/emergency_animation.cpp b/src/karts/emergency_animation.cpp index a31d4b05e..c42d5e562 100644 --- a/src/karts/emergency_animation.cpp +++ b/src/karts/emergency_animation.cpp @@ -21,6 +21,7 @@ #include "graphics/camera.hpp" #include "graphics/referee.hpp" #include "graphics/stars.hpp" +#include "items/attachment.hpp" #include "karts/kart.hpp" #include "modes/world.hpp" #include "modes/three_strikes_battle.hpp" diff --git a/src/karts/kart.cpp b/src/karts/kart.cpp index bf8e5c1b5..9e06ce3d3 100644 --- a/src/karts/kart.cpp +++ b/src/karts/kart.cpp @@ -42,6 +42,7 @@ #include "karts/kart_gfx.hpp" #include "modes/world.hpp" #include "io/file_manager.hpp" +#include "items/attachment.hpp" #include "items/item_manager.hpp" #include "karts/controller/end_controller.hpp" #include "karts/kart_model.hpp" @@ -1261,7 +1262,7 @@ void Kart::setCamera(Camera *camera) { m_rain->setCamera( camera->getCameraSceneNode() ); } -} +} // setCamera //----------------------------------------------------------------------------- /** Sets zipper time, and apply one time additional speed boost. It can be @@ -1354,44 +1355,64 @@ void Kart::setSlipstreamEffect(float f) } // setSlipstreamEffect // ----------------------------------------------------------------------------- -/** Called when the kart crashes against the track (k=NULL) or another kart. - * \param k Either a kart if a kart was hit, or NULL if the track was hit. - * \param m +/** Called when the kart crashes against another kart. + * \param k The kart that was hit. + * \param update_attachments If true the attachment of this kart and the + * other kart hit will be updated (e.g. bombs will be moved) */ -void Kart::crashed(Kart *k, const Material *m) +void Kart::crashed(Kart *k, bool update_attachments) +{ + if(update_attachments) + { + assert(k); + getAttachment()->handleCollisionWithKart(k); + } + crashed(); +} // crashed(Kart, update_attachments + +// ----------------------------------------------------------------------------- +/** Kart hits the track with a given material. + * \param m Material hit, can be NULL if no specific material exists. + */ +void Kart::crashed(const Material *m) { #ifdef DEBUG // Simple debug output for people playing without sound. // This makes it easier to see if a kart hit the track (esp. // after a jump). // FIXME: This should be removed once the physics are fixed. - if(!k && UserConfigParams::m_physics_debug) + if(UserConfigParams::m_physics_debug) { // Add a counter to make it easier to see if a new line of // output was added. static int counter=0; - printf("Kart %s hit track: %d.\n", getIdent().c_str(), counter++); + printf("Kart %s hit track: %d material %s.\n", + getIdent().c_str(), counter++, + m->getTexFname().c_str()); } #endif - m_controller->crashed(); /** If a kart is crashing against the track, the collision is often * reported more than once, resulting in a machine gun effect, and too * long disabling of the engine. Therefore, this reaction is disabled * for 0.5 seconds after a crash. */ - if(m && m->getCollisionReaction() != Material::NORMAL && !playingEmergencyAnimation()) + if(m && m->getCollisionReaction() != Material::NORMAL && + !playingEmergencyAnimation()) { std::string particles = m->getCrashResetParticles(); if (particles.size() > 0) { - ParticleKind* kind = ParticleKindManager::get()->getParticles(particles); + ParticleKind* kind = + ParticleKindManager::get()->getParticles(particles); if (kind != NULL) { if (m_collision_particles == NULL) { - Vec3 position(-getKartWidth()*0.35f, 0.06f, getKartLength()*0.5f); - m_collision_particles = new ParticleEmitter(kind, position, getNode()); + Vec3 position(-getKartWidth()*0.35f, 0.06f, + getKartLength()*0.5f); + m_collision_particles = + new ParticleEmitter(kind, position, getNode()); } else { @@ -1413,14 +1434,24 @@ void Kart::crashed(Kart *k, const Material *m) { if (m_bounce_back_time <= 0.0f) { - btVector3 push = m_vehicle->getRigidBody()->getLinearVelocity().normalized(); - push[1] = 0.1f; - m_vehicle->getRigidBody()->applyCentralImpulse( -4000.0f*push ); - //m_vehicle->getRigidBody()->setLinearVelocity( -m_vehicle->getRigidBody()->getLinearVelocity() ); - m_bounce_back_time = 2.0f; + btVector3 push = m_body->getLinearVelocity().normalized(); + push[1] = 0.1f; + m_body->applyCentralImpulse( -4000.0f*push ); + m_bounce_back_time = 2.0f; } } } + + crashed(); +} // crashed(Material) + +// ----------------------------------------------------------------------------- +/** Common code used when a kart or a material was hit. + */ +void Kart::crashed() +{ + m_controller->crashed(); + if(World::getWorld()->getTime()-m_time_last_crash < 0.5f) return; m_time_last_crash = World::getWorld()->getTime(); diff --git a/src/karts/kart.hpp b/src/karts/kart.hpp index 88f9d1596..3dcae7b5f 100644 --- a/src/karts/kart.hpp +++ b/src/karts/kart.hpp @@ -28,7 +28,6 @@ #include "LinearMath/btTransform.h" -#include "items/attachment.hpp" #include "items/powerup.hpp" #include "karts/controller/controller.hpp" #include "karts/controller/kart_control.hpp" @@ -42,6 +41,7 @@ class btKart; class btUprightConstraint; +class Attachment; class Camera; class Item; class KartGFX; @@ -205,6 +205,7 @@ private: void updateEngineSFX(); float getVisualSkidOffset() const; + void crashed(); protected: const KartProperties *m_kart_properties; @@ -242,7 +243,8 @@ public: void handleZipper (const Material *m=NULL, bool play_sound=false); void setSquash (float time, float slowdown); - void crashed (Kart *k, const Material *m=NULL); + void crashed (Kart *k, bool update_attachments); + void crashed (const Material *m); virtual void update (float dt); virtual void finishedRace (float time); diff --git a/src/physics/physics.cpp b/src/physics/physics.cpp index c3a73d26f..d1069b520 100644 --- a/src/physics/physics.cpp +++ b/src/physics/physics.cpp @@ -268,45 +268,17 @@ Physics::CollisionSide Physics::getCollisionSide(const btRigidBody *body, * server and if no networking is used, and from race_state on the client to * replay what happened on the server. * \param kart_a First kart involved in the collision. + * \param contact_point_a Location of collision at first kart (in kart + * coordinates). * \param kart_b Second kart involved in the collision. + * \param contact_point_b Location of collision at second kart (in kart + * coordinates). */ void Physics::KartKartCollision(Kart *kart_a, const Vec3 &contact_point_a, Kart *kart_b, const Vec3 &contact_point_b) { - kart_a->crashed(kart_b); // will play crash sound for player karts - kart_b->crashed(kart_a); - Attachment *attachmentA=kart_a->getAttachment(); - Attachment *attachmentB=kart_b->getAttachment(); - - if(attachmentA->getType()==Attachment::ATTACH_BOMB) - { - // If both karts have a bomb, explode them immediately: - if(attachmentB->getType()==Attachment::ATTACH_BOMB) - { - attachmentA->setTimeLeft(0.0f); - attachmentB->setTimeLeft(0.0f); - } - else // only A has a bomb, move it to B (unless it was from B) - { - if(attachmentA->getPreviousOwner()!=kart_b) - { - attachmentA->moveBombFromTo(kart_a, kart_b); - // Play appropriate SFX - kart_b->playCustomSFX(SFXManager::CUSTOM_ATTACH); - } - } - } - else if(attachmentB->getType()==Attachment::ATTACH_BOMB && - attachmentB->getPreviousOwner()!=kart_a) - { - attachmentB->moveBombFromTo(kart_b, kart_a); - kart_a->playCustomSFX(SFXManager::CUSTOM_ATTACH); - } - else - { - kart_a->playCustomSFX(SFXManager::CUSTOM_CRASH); - kart_b->playCustomSFX(SFXManager::CUSTOM_CRASH); - } + kart_a->crashed(kart_b, /*handle_attachments*/true); + kart_b->crashed(kart_a, /*handle_attachments*/false); // If bouncing crashes is enabled, add an additional force to the // slower kart @@ -470,7 +442,7 @@ btScalar Physics::solveGroup(btCollisionObject** bodies, int numBodies, const Material *m = n>=0 ? upA->getPointerTriangleMesh()->getMaterial(n) : NULL; - kart->crashed(NULL, m); + kart->crashed(m); } } // 2) object a is a kart @@ -485,7 +457,7 @@ btScalar Physics::solveGroup(btCollisionObject** bodies, int numBodies, const Material *m = n>=0 ? upB->getPointerTriangleMesh()->getMaterial(n) : NULL; - kart->crashed(NULL, m); // Kart hit track + kart->crashed(m); // Kart hit track } else if(upB->is(UserPointer::UP_FLYABLE)) // 2.1 projectile hits kart diff --git a/src/physics/physics.hpp b/src/physics/physics.hpp index 033c74f94..fe3c73082 100644 --- a/src/physics/physics.hpp +++ b/src/physics/physics.hpp @@ -138,7 +138,7 @@ private: btCollisionDispatcher *m_dispatcher; btBroadphaseInterface *m_axis_sweep; btDefaultCollisionConfiguration *m_collision_conf; - CollisionList m_all_collisions; + CollisionList m_all_collisions; public: Physics ();