diff --git a/src/graphics/engine/particle.cpp b/src/graphics/engine/particle.cpp index e42762da..07370493 100644 --- a/src/graphics/engine/particle.cpp +++ b/src/graphics/engine/particle.cpp @@ -3543,6 +3543,7 @@ CObject* CParticle::SearchObjectGun(Math::Vector old, Math::Vector pos, continue; } if (!obj->Implements(ObjectInterfaceType::Damageable) && !obj->IsBulletWall()) continue; + if (obj->Implements(ObjectInterfaceType::Jostleable)) continue; Math::Vector oPos = obj->GetPosition(); diff --git a/src/graphics/engine/pyro.cpp b/src/graphics/engine/pyro.cpp index b7e2f043..d295985a 100644 --- a/src/graphics/engine/pyro.cpp +++ b/src/graphics/engine/pyro.cpp @@ -356,6 +356,12 @@ bool CPyro::Create(PyroType type, CObject* obj, float force) if (oType == OBJECT_APOLLO2) limit = 2.0f; m_speed = 1.0f/limit; } + if ( m_type == PT_SQUASH ) + { + m_speed = 1.0f/2.0f; + m_object->SetLock(true); + } + if ( m_type == PT_EXPLOT || m_type == PT_EXPLOO || @@ -399,7 +405,8 @@ bool CPyro::Create(PyroType type, CObject* obj, float force) if ( m_type != PT_FRAGV && m_type != PT_EGG && m_type != PT_WIN && - m_type != PT_LOST ) + m_type != PT_LOST && + m_type != PT_SQUASH) { float h = 40.0f; if ( m_type == PT_FRAGO || @@ -454,7 +461,8 @@ bool CPyro::Create(PyroType type, CObject* obj, float force) m_type != PT_FLCREATE && m_type != PT_FLDELETE && m_type != PT_RESET && - m_type != PT_FINDING ) + m_type != PT_FINDING && + m_type != PT_SQUASH ) { m_camera->StartEffect(CAM_EFFECT_EXPLO, m_pos, force); } @@ -1049,6 +1057,11 @@ bool CPyro::EventProcess(const Event &event) } } + if ( m_type == PT_SQUASH && m_object != nullptr ) + { + m_object->SetScaleY(1.0f-sinf(m_progress)*0.5f); + } + if ( (m_type == PT_BURNT || m_type == PT_BURNO) && m_object != nullptr ) { @@ -1229,6 +1242,11 @@ Error CPyro::IsEnded() m_object->SetScale(1.0f); } + if ( m_type == PT_SQUASH ) + { + m_object->SetType(OBJECT_PLANT19); + } + if ( m_lightRank != -1 ) { m_lightMan->DeleteLight(m_lightRank); diff --git a/src/graphics/engine/pyro_type.h b/src/graphics/engine/pyro_type.h index bef6cbaf..0336be71 100644 --- a/src/graphics/engine/pyro_type.h +++ b/src/graphics/engine/pyro_type.h @@ -59,6 +59,7 @@ enum PyroType PT_DEADW = 25, //! < drowning death PT_FINDING = 26, //! < object discovered PT_FRAGV = 27, //! < fragmentation of plant object + PT_SQUASH = 28, //! < flattening plants }; } // namespace Gfx diff --git a/src/object/interface/destroyable_object.h b/src/object/interface/destroyable_object.h index f40c3f7e..fd83a87e 100644 --- a/src/object/interface/destroyable_object.h +++ b/src/object/interface/destroyable_object.h @@ -33,6 +33,7 @@ enum class DestructionType Burn = 3, //!< burning Drowned = 4, //!< drowned (only for Me) Win = 5, //!< used when removing objects from a team that won + Squash = 6, //!< flatten }; /** diff --git a/src/object/old_object.cpp b/src/object/old_object.cpp index 0304fec5..5fd93df8 100644 --- a/src/object/old_object.cpp +++ b/src/object/old_object.cpp @@ -351,6 +351,7 @@ bool COldObject::DamageObject(DamageType type, float force, CObject* killer) assert(!Implements(ObjectInterfaceType::Destroyable) || Implements(ObjectInterfaceType::Shielded) || Implements(ObjectInterfaceType::Fragile)); if ( IsDying() ) return false; + if ( Implements(ObjectInterfaceType::Jostleable) ) return false; if ( m_type == OBJECT_ANT || m_type == OBJECT_WORM || @@ -569,6 +570,11 @@ void COldObject::DestroyObject(DestructionType type, CObject* killer) { pyroType = Gfx::PT_WPCHECK; } + else if ( type == DestructionType::Squash ) + { + pyroType = Gfx::PT_SQUASH; + DeleteAllCrashSpheres(); + } assert(pyroType != Gfx::PT_NULL); if (pyroType == Gfx::PT_FRAGT || pyroType == Gfx::PT_FRAGO || @@ -879,6 +885,21 @@ void COldObject::SetType(ObjectType type) m_implementedInterfaces[static_cast(ObjectInterfaceType::Fragile)] = true; m_implementedInterfaces[static_cast(ObjectInterfaceType::Shielded)] = false; } + else if (m_type == OBJECT_PLANT0 || + m_type == OBJECT_PLANT1 || + m_type == OBJECT_PLANT2 || + m_type == OBJECT_PLANT3 || + m_type == OBJECT_PLANT4 || + m_type == OBJECT_PLANT15 || + m_type == OBJECT_PLANT16 || + m_type == OBJECT_PLANT17 || + m_type == OBJECT_PLANT18 ) + { + m_implementedInterfaces[static_cast(ObjectInterfaceType::Damageable)] = true; + m_implementedInterfaces[static_cast(ObjectInterfaceType::Destroyable)] = true; + m_implementedInterfaces[static_cast(ObjectInterfaceType::Fragile)] = true; + m_implementedInterfaces[static_cast(ObjectInterfaceType::Shielded)] = false; + } else { m_implementedInterfaces[static_cast(ObjectInterfaceType::Damageable)] = false; @@ -1274,7 +1295,7 @@ int COldObject::SearchDescendant(int parent, int n) void COldObject::TransformCrashSphere(Math::Sphere& crashSphere) { - crashSphere.radius *= GetScaleX(); + if(!Implements(ObjectInterfaceType::Jostleable)) crashSphere.radius *= GetScaleX(); // Returns to the sphere collisions, // which ignores the tilt of the vehicle. diff --git a/src/object/task/taskrecover.cpp b/src/object/task/taskrecover.cpp index 021a9f89..e039e7ae 100644 --- a/src/object/task/taskrecover.cpp +++ b/src/object/task/taskrecover.cpp @@ -376,5 +376,5 @@ bool CTaskRecover::Abort() CObject* CTaskRecover::SearchRuin() { - return CObjectManager::GetInstancePointer()->FindNearest(nullptr, m_recoverPos, {OBJECT_RUINmobilew1, OBJECT_RUINmobilew2, OBJECT_RUINmobilet1, OBJECT_RUINmobilet2, OBJECT_RUINmobiler1, OBJECT_RUINmobiler2, OBJECT_RUINdoor, OBJECT_RUINsupport, OBJECT_RUINradar}, 40.0f/g_unit); + return CObjectManager::GetInstancePointer()->FindNearest(nullptr, m_recoverPos, {OBJECT_RUINmobilew1, OBJECT_RUINmobilew2, OBJECT_RUINmobilet1, OBJECT_RUINmobilet2, OBJECT_RUINmobiler1, OBJECT_RUINmobiler2}, 40.0f/g_unit); } diff --git a/src/physics/physics.cpp b/src/physics/physics.cpp index 6917992a..7dd79633 100644 --- a/src/physics/physics.cpp +++ b/src/physics/physics.cpp @@ -2525,7 +2525,7 @@ int CPhysics::ObjectAdapt(const Math::Vector &pos, const Math::Vector &angle) { if ( pObj == m_object ) continue; // yourself? if (IsObjectBeingTransported(pObj)) continue; - //if ( pObj->Implements(ObjectInterfaceType::Destroyable) && dynamic_cast(pObj)->IsDying() ) continue; // is burning or exploding? + if ( pObj->Implements(ObjectInterfaceType::Destroyable) && dynamic_cast(pObj)->GetDying() == DeathType::Exploding ) continue; // is exploding? oType = pObj->GetType(); if ( oType == OBJECT_TOTO ) continue; @@ -2794,6 +2794,20 @@ bool CPhysics::ExploOther(ObjectType iType, } } + if((oType == OBJECT_PLANT0 || + oType == OBJECT_PLANT1 || + oType == OBJECT_PLANT2 || + oType == OBJECT_PLANT3 || + oType == OBJECT_PLANT4 || + oType == OBJECT_PLANT15 || + oType == OBJECT_PLANT16 || + oType == OBJECT_PLANT17 || + oType == OBJECT_PLANT18)&& + GetDriveFromObject(iType)==DriveType::Heavy) + { + dynamic_cast(pObj)->DestroyObject(DestructionType::Squash); + } + return false; }