[colobot] 56/100: Change bullet collision logic to allow for collisions with non-damageable objects

Didier Raboud odyx at moszumanska.debian.org
Thu Jun 1 18:10:19 UTC 2017


This is an automated email from the git hooks/post-receive script.

odyx pushed a commit to branch debian/master
in repository colobot.

commit fda58a60087d4fc39e6332a053df6c7680804994
Author: krzys-h <krzys_h at interia.pl>
Date:   Sat Apr 29 13:05:11 2017 +0200

    Change bullet collision logic to allow for collisions with non-damageable objects
    
    For now, you have to add bulletWall=true to objects you want bullets to collide with.
    It's ugly but will work for now. This is needed mostly for compatibility
    with exercises which use barriers to block movement but not bullets.
    
    I also made the collision checks run more often because otherwise the bullets
    would sometimes miss the objects (but only visually)
---
 src/graphics/engine/particle.cpp | 50 ++++++++++++++++++++++++++--------------
 src/object/object.h              |  5 ++++
 src/object/old_object.cpp        | 15 ++++++++++++
 src/object/old_object.h          |  5 ++++
 4 files changed, 58 insertions(+), 17 deletions(-)

diff --git a/src/graphics/engine/particle.cpp b/src/graphics/engine/particle.cpp
index 5aaf45f..9297a6c 100644
--- a/src/graphics/engine/particle.cpp
+++ b/src/graphics/engine/particle.cpp
@@ -952,9 +952,8 @@ void CParticle::FrameParticle(float rTime)
         {
             CObject* object = SearchObjectGun(m_particle[i].goal, m_particle[i].pos, m_particle[i].type, m_particle[i].objFather);
             m_particle[i].goal = m_particle[i].pos;
-            if (object != nullptr)
+            if (object != nullptr && object->Implements(ObjectInterfaceType::Damageable))
             {
-                assert(object->Implements(ObjectInterfaceType::Damageable));
                 dynamic_cast<CDamageableObject*>(object)->DamageObject(DamageType::Phazer, 0.002f);
             }
 
@@ -1107,7 +1106,7 @@ void CParticle::FrameParticle(float rTime)
                 continue;
             }
 
-            if (m_particle[i].testTime >= 0.1f)
+            if (m_particle[i].testTime >= 0.05f)
             {
                 m_particle[i].testTime = 0.0f;
 
@@ -1156,8 +1155,10 @@ void CParticle::FrameParticle(float rTime)
                 m_particle[i].goal = m_particle[i].pos;
                 if (object != nullptr)
                 {
-                    assert(object->Implements(ObjectInterfaceType::Damageable));
-                    dynamic_cast<CDamageableObject*>(object)->DamageObject(DamageType::Fire, 0.002f);
+                    if (object->Implements(ObjectInterfaceType::Damageable))
+                    {
+                        dynamic_cast<CDamageableObject*>(object)->DamageObject(DamageType::Fire, 0.001f);
+                    }
 
                     m_exploGunCounter++;
 
@@ -1215,7 +1216,7 @@ void CParticle::FrameParticle(float rTime)
                 continue;
             }
 
-            if (m_particle[i].testTime >= 0.2f)
+            if (m_particle[i].testTime >= 0.1f)
             {
                 m_particle[i].testTime = 0.0f;
                 CObject* object = SearchObjectGun(m_particle[i].goal, m_particle[i].pos, m_particle[i].type, m_particle[i].objFather);
@@ -1238,8 +1239,10 @@ void CParticle::FrameParticle(float rTime)
                         if (object->GetType() != OBJECT_HUMAN)
                             Play(SOUND_TOUCH, m_particle[i].pos, 1.0f);
 
-                        assert(object->Implements(ObjectInterfaceType::Damageable));
-                        dynamic_cast<CDamageableObject*>(object)->DamageObject(DamageType::Organic, 0.2f);  // starts explosion
+                        if (object->Implements(ObjectInterfaceType::Damageable))
+                        {
+                            dynamic_cast<CDamageableObject*>(object)->DamageObject(DamageType::Organic, 0.1f);  // starts explosion
+                        }
                     }
                 }
             }
@@ -1261,7 +1264,7 @@ void CParticle::FrameParticle(float rTime)
                 continue;
             }
 
-            if (m_particle[i].testTime >= 0.2f)
+            if (m_particle[i].testTime >= 0.1f)
             {
                 m_particle[i].testTime = 0.0f;
                 CObject* object = SearchObjectGun(m_particle[i].goal, m_particle[i].pos, m_particle[i].type, m_particle[i].objFather);
@@ -1281,8 +1284,10 @@ void CParticle::FrameParticle(float rTime)
                     }
                     else
                     {
-                        assert(object->Implements(ObjectInterfaceType::Damageable));
-                        dynamic_cast<CDamageableObject*>(object)->DamageObject(DamageType::Fire);  // starts explosion
+                        if (object->Implements(ObjectInterfaceType::Damageable))
+                        {
+                            dynamic_cast<CDamageableObject*>(object)->DamageObject(DamageType::Fire);  // starts explosion
+                        }
                     }
                 }
             }
@@ -1301,7 +1306,7 @@ void CParticle::FrameParticle(float rTime)
                 continue;
             }
 
-            if (m_particle[i].testTime >= 0.1f)
+            if (m_particle[i].testTime >= 0.05f)
             {
                 m_particle[i].testTime = 0.0f;
 
@@ -1338,8 +1343,10 @@ void CParticle::FrameParticle(float rTime)
                 m_particle[i].goal = m_particle[i].pos;
                 if (object != nullptr)
                 {
-                    assert(object->Implements(ObjectInterfaceType::Damageable));
-                    dynamic_cast<CDamageableObject*>(object)->DamageObject(DamageType::Organic, 0.002f);
+                    if (object->Implements(ObjectInterfaceType::Damageable))
+                    {
+                        dynamic_cast<CDamageableObject*>(object)->DamageObject(DamageType::Organic, 0.0005f);
+                    }
 
                     m_exploGunCounter ++;
 
@@ -3502,6 +3509,7 @@ CObject* CParticle::SearchObjectGun(Math::Vector old, Math::Vector pos,
     box2.z += min;
 
     CObject* best = nullptr;
+    float best_dist = std::numeric_limits<float>::infinity();
     bool shield = false;
     for (CObject* obj : CObjectManager::GetInstancePointer()->GetAllObjects())
     {
@@ -3535,7 +3543,7 @@ CObject* CParticle::SearchObjectGun(Math::Vector old, Math::Vector pos,
         {
             continue;
         }
-        if (!obj->Implements(ObjectInterfaceType::Damageable))  continue;
+        if (!obj->Implements(ObjectInterfaceType::Damageable) && !obj->IsBulletWall())  continue;
 
         Math::Vector oPos = obj->GetPosition();
 
@@ -3563,8 +3571,12 @@ CObject* CParticle::SearchObjectGun(Math::Vector old, Math::Vector pos,
         // Test the center of the object, which is necessary for objects
         // that have no sphere in the center (station).
         float dist = Math::Distance(oPos, pos)-4.0f;
-        if (dist < min)
+        float obj_dist = Math::Distance(old, oPos);
+        if (dist < min && obj_dist < best_dist)
+        {
             best = obj;
+            best_dist = obj_dist;
+        }
 
         for (const auto& crashSphere : obj->GetAllCrashSpheres())
         {
@@ -3577,8 +3589,12 @@ CObject* CParticle::SearchObjectGun(Math::Vector old, Math::Vector pos,
 
             Math::Vector p = Math::Projection(old, pos, oPos);
             float ddist = Math::Distance(p, oPos)-oRadius;
-            if (ddist < min)
+            float obj_dist = Math::Distance(old, oPos);
+            if (ddist < min && obj_dist < best_dist)
+            {
                 best = obj;
+                best_dist = obj_dist;
+            }
         }
     }
 
diff --git a/src/object/object.h b/src/object/object.h
index 960d753..4fcfe68 100644
--- a/src/object/object.h
+++ b/src/object/object.h
@@ -206,6 +206,11 @@ public:
     //! Is this object detectable (not dead and not underground)?
     virtual bool GetDetectable() { return true; }
 
+    //! Returns true if this object can collide with bullets even though it's not damageable itself
+    //! This is useful to make Barriers protect from bullets
+    //! \todo It will work like this for now but later I'd like to refactor this to something more manageable ~krzys_h
+    virtual bool IsBulletWall() { return false; }
+
 protected:
     //! Transform crash sphere by object's world matrix
     virtual void TransformCrashSphere(Math::Sphere& crashSphere) = 0;
diff --git a/src/object/old_object.cpp b/src/object/old_object.cpp
index c7200c8..5c67ee4 100644
--- a/src/object/old_object.cpp
+++ b/src/object/old_object.cpp
@@ -940,6 +940,9 @@ void COldObject::Write(CLevelParserLine* line)
     if ( GetCameraLock() )
         line->AddParam("cameraLock", MakeUnique<CLevelParserParam>(GetCameraLock()));
 
+    if ( IsBulletWall() )
+        line->AddParam("bulletWall", MakeUnique<CLevelParserParam>(IsBulletWall()));
+
     if ( GetEnergyLevel() != 0.0f )
         line->AddParam("energy", MakeUnique<CLevelParserParam>(GetEnergyLevel()));
 
@@ -1035,6 +1038,8 @@ void COldObject::Read(CLevelParserLine* line)
     if (line->GetParam("pyro")->IsDefined())
         m_engine->GetPyroManager()->Create(line->GetParam("pyro")->AsPyroType(), this);
 
+    SetBulletWall(line->GetParam("bulletWall")->AsBool(false));
+
     SetProxyActivate(line->GetParam("proxyActivate")->AsBool(false));
     SetProxyDistance(line->GetParam("proxyDistance")->AsFloat(15.0f)*g_unit);
     SetCollisions(line->GetParam("clip")->AsBool(true));
@@ -3188,3 +3193,13 @@ bool COldObject::IsSelectableByDefault(ObjectType type)
     }
     return true;
 }
+
+void COldObject::SetBulletWall(bool bulletWall)
+{
+    m_bulletWall = bulletWall;
+}
+
+bool COldObject::IsBulletWall()
+{
+    return m_bulletWall;
+}
diff --git a/src/object/old_object.h b/src/object/old_object.h
index ff96fcf..b000ac6 100644
--- a/src/object/old_object.h
+++ b/src/object/old_object.h
@@ -288,6 +288,9 @@ public:
 
     float       GetLightningHitProbability() override;
 
+    void        SetBulletWall(bool bulletWall);
+    bool        IsBulletWall() override;
+
 protected:
     bool        EventFrame(const Event &event);
     void        VirusFrame(float rTime);
@@ -376,4 +379,6 @@ protected:
     bool        m_traceDown;
     TraceColor  m_traceColor;
     float       m_traceWidth;
+
+    bool        m_bulletWall = false;
 };

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-games/colobot.git



More information about the Pkg-games-commits mailing list