From 8d5ddd848da0ab0a4801e9b3e1c545cce54e3f96 Mon Sep 17 00:00:00 2001 From: Piotr Dziwinski Date: Fri, 10 Jul 2015 22:11:22 +0200 Subject: [PATCH] CJostleableObject interface --- src/object/interface/jostleable_object.h | 44 ++++++++++++++++++++++++ src/object/object_factory.cpp | 16 ++++----- src/object/object_interface_type.h | 1 + src/object/old_object.cpp | 18 +++++----- src/object/old_object.h | 11 +++--- src/object/old_object_interface.h | 3 -- src/object/robotmain.cpp | 2 +- src/physics/physics.cpp | 35 ++++++++----------- src/physics/physics.h | 3 +- 9 files changed, 87 insertions(+), 46 deletions(-) create mode 100644 src/object/interface/jostleable_object.h diff --git a/src/object/interface/jostleable_object.h b/src/object/interface/jostleable_object.h new file mode 100644 index 00000000..7bd57ec5 --- /dev/null +++ b/src/object/interface/jostleable_object.h @@ -0,0 +1,44 @@ +/* + * This file is part of the Colobot: Gold Edition source code + * Copyright (C) 2001-2014, Daniel Roux, EPSITEC SA & TerranovaTeam + * http://epsiteс.ch; http://colobot.info; http://github.com/colobot + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see http://gnu.org/licenses + */ + +#pragma once + +#include "object/object_interface_type.h" + +#include "math/sphere.h" + +struct Event; + +/** + * \class CJostleableObject + * \brief Interface for objects that can be jostled + */ +class CJostleableObject +{ +public: + explicit CJostleableObject(ObjectInterfaceTypes& types) + { + types[static_cast(ObjectInterfaceType::Jostleable)] = true; + } + virtual ~CJostleableObject() + {} + + virtual Math::Sphere GetJostlingSphere() const = 0; + virtual bool JostleObject(float force) = 0; +}; diff --git a/src/object/object_factory.cpp b/src/object/object_factory.cpp index f7f81444..53a6336d 100644 --- a/src/object/object_factory.cpp +++ b/src/object/object_factory.cpp @@ -1228,7 +1228,7 @@ CObjectUPtr CObjectFactory::CreateFlag(const ObjectCreateParams& params) else obj->SetPosition(1+i, Math::Vector(0.79f, 0.0f, 0.0f)); } - obj->SetJostlingSphere(Math::Vector(0.0f, 4.0f, 0.0f), 1.0f); + obj->SetJostlingSphere(Math::Sphere(Math::Vector(0.0f, 4.0f, 0.0f), 1.0f)); obj->CreateShadowCircle(2.0f, 0.3f); obj->SetFloorHeight(0.0f); @@ -1373,7 +1373,7 @@ CObjectUPtr CObjectFactory::CreatePlant(const ObjectCreateParams& params) obj->AddCrashSphere(CrashSphere(Math::Vector(0.0f, 0.0f, 0.0f), 4.0f, SOUND_BOUM, 0.10f)); obj->SetGlobalSphere(Math::Vector(0.0f, 3.0f, 0.0f), 6.0f); - obj->SetJostlingSphere(Math::Vector(0.0f, 0.0f, 0.0f), 8.0f); + obj->SetJostlingSphere(Math::Sphere(Math::Vector(0.0f, 0.0f, 0.0f), 8.0f)); obj->CreateShadowCircle(8.0f, 0.5f); } @@ -1392,7 +1392,7 @@ CObjectUPtr CObjectFactory::CreatePlant(const ObjectCreateParams& params) obj->SetAngleY(0, angle); //? obj->AddCrashSphere(CrashSphere(Math::Vector(0.0f, 0.0f, 0.0f), 3.0f, SOUND_BOUM, 0.10f)); - obj->SetJostlingSphere(Math::Vector(0.0f, 0.0f, 0.0f), 4.0f); + obj->SetJostlingSphere(Math::Sphere(Math::Vector(0.0f, 0.0f, 0.0f), 4.0f)); obj->CreateShadowCircle(5.0f, 0.3f); } @@ -1433,7 +1433,7 @@ CObjectUPtr CObjectFactory::CreatePlant(const ObjectCreateParams& params) obj->AddCrashSphere(CrashSphere(Math::Vector(0.0f, 12.0f, 0.0f), 5.0f, SOUND_BOUM, 0.10f)); obj->SetGlobalSphere(Math::Vector(0.0f, 6.0f, 0.0f), 6.0f); - obj->SetJostlingSphere(Math::Vector(0.0f, 4.0f, 0.0f), 8.0f); + obj->SetJostlingSphere(Math::Sphere(Math::Vector(0.0f, 4.0f, 0.0f), 8.0f)); obj->CreateShadowCircle(8.0f, 0.3f); } @@ -1460,7 +1460,7 @@ CObjectUPtr CObjectFactory::CreatePlant(const ObjectCreateParams& params) obj->AddCrashSphere(CrashSphere(Math::Vector(0.0f, 0.0f, 0.0f), 4.0f, SOUND_BOUM, 0.10f)); obj->SetGlobalSphere(Math::Vector(0.0f, 3.0f, 0.0f), 6.0f); } - obj->SetJostlingSphere(Math::Vector(0.0f, 0.0f, 0.0f), 8.0f); + obj->SetJostlingSphere(Math::Sphere(Math::Vector(0.0f, 0.0f, 0.0f), 8.0f)); obj->CreateShadowCircle(8.0f, 0.5f); } @@ -1604,7 +1604,7 @@ CObjectUPtr CObjectFactory::CreateMushroom(const ObjectCreateParams& params) obj->AddCrashSphere(CrashSphere(Math::Vector(0.0f, 4.0f, 0.0f), 3.0f, SOUND_BOUM, 0.10f)); obj->SetGlobalSphere(Math::Vector(0.0f, 3.0f, 0.0f), 5.5f); - obj->SetJostlingSphere(Math::Vector(0.0f, 3.0f, 0.0f), 5.5f); + obj->SetJostlingSphere(Math::Sphere(Math::Vector(0.0f, 3.0f, 0.0f), 5.5f)); obj->CreateShadowCircle(6.0f, 0.5f); } @@ -1620,7 +1620,7 @@ CObjectUPtr CObjectFactory::CreateMushroom(const ObjectCreateParams& params) obj->AddCrashSphere(CrashSphere(Math::Vector(0.0f, 5.0f, 0.0f), 3.0f, SOUND_BOUM, 0.10f)); obj->SetGlobalSphere(Math::Vector(0.0f, 4.0f, 0.0f), 5.5f); - obj->SetJostlingSphere(Math::Vector(0.0f, 4.0f, 0.0f), 5.5f); + obj->SetJostlingSphere(Math::Sphere(Math::Vector(0.0f, 4.0f, 0.0f), 5.5f)); obj->CreateShadowCircle(5.0f, 0.5f); } @@ -2495,7 +2495,7 @@ CObjectUPtr CObjectFactory::CreateApollo(const ObjectCreateParams& params) obj->SetAngleY(0, angle); obj->SetFloorHeight(0.0f); - obj->SetJostlingSphere(Math::Vector(0.0f, 4.0f, 0.0f), 1.0f); + obj->SetJostlingSphere(Math::Sphere(Math::Vector(0.0f, 4.0f, 0.0f), 1.0f)); obj->CreateShadowCircle(2.0f, 0.3f); } diff --git a/src/object/object_interface_type.h b/src/object/object_interface_type.h index 658a017c..a25baa56 100644 --- a/src/object/object_interface_type.h +++ b/src/object/object_interface_type.h @@ -35,6 +35,7 @@ enum class ObjectInterfaceType Interactive, //!< interactive objects can process events from event loop Transportable, //!< objects that can be carried by robots or astronaut Programmable, //!< objects that can be programmed in CBOT + Jostleable, //!< object that can be jostled Max //!< maximum value (for getting number of items in enum) }; diff --git a/src/object/old_object.cpp b/src/object/old_object.cpp index b4acd62b..9781f808 100644 --- a/src/object/old_object.cpp +++ b/src/object/old_object.cpp @@ -190,9 +190,12 @@ COldObject::COldObject(int id) , CInteractiveObject(m_implementedInterfaces) , CTransportableObject(m_implementedInterfaces) , CProgrammableObject(m_implementedInterfaces) + , CJostleableObject(m_implementedInterfaces) { // A bit of a hack since CBrain is set externally in SetBrain() m_implementedInterfaces[static_cast(ObjectInterfaceType::Programmable)] = false; + // Another hack + m_implementedInterfaces[static_cast(ObjectInterfaceType::Jostleable)] = false; m_sound = CApplication::GetInstancePointer()->GetSound(); m_engine = Gfx::CEngine::GetInstancePointer(); @@ -290,8 +293,6 @@ COldObject::COldObject(int id) DeleteAllCrashSpheres(); m_globalSpherePos = Math::Vector(0.0f, 0.0f, 0.0f); m_globalSphereRadius = 0.0f; - m_jostlingSpherePos = Math::Vector(0.0f, 0.0f, 0.0f); - m_jostlingSphereRadius = 0.0f; CBotClass* bc = CBotClass::Find("object"); if ( bc != 0 ) @@ -1103,18 +1104,19 @@ void COldObject::GetGlobalSphere(Math::Vector &pos, float &radius) // Specifies the sphere of jostling, relative to the object. -void COldObject::SetJostlingSphere(Math::Vector pos, float radius) +void COldObject::SetJostlingSphere(const Math::Sphere& jostlingSphere) { - m_jostlingSpherePos = pos; - m_jostlingSphereRadius = radius; + m_jostlingSphere = jostlingSphere; + m_implementedInterfaces[static_cast(ObjectInterfaceType::Jostleable)] = true; } // Specifies the sphere of jostling, in the world. -void COldObject::GetJostlingSphere(Math::Vector &pos, float &radius) +Math::Sphere COldObject::GetJostlingSphere() const { - pos = Math::Transform(m_objectPart[0].matWorld, m_jostlingSpherePos); - radius = m_jostlingSphereRadius; + Math::Sphere transformedJostlingSphere = m_jostlingSphere; + transformedJostlingSphere.pos = Math::Transform(m_objectPart[0].matWorld, transformedJostlingSphere.pos); + return transformedJostlingSphere; } diff --git a/src/object/old_object.h b/src/object/old_object.h index 19ecec30..2fe48f18 100644 --- a/src/object/old_object.h +++ b/src/object/old_object.h @@ -27,6 +27,7 @@ #include "object/object.h" #include "object/interface/interactive_object.h" +#include "object/interface/jostleable_object.h" #include "object/interface/programmable_object.h" #include "object/interface/transportable_object.h" @@ -56,7 +57,8 @@ struct ObjectPart class COldObject : public CObject, public CInteractiveObject, public CTransportableObject, - public CProgrammableObject + public CProgrammableObject, + public CJostleableObject { friend class CObjectFactory; friend class CObjectManager; @@ -74,7 +76,7 @@ protected: void SetCapacity(float capacity); float GetProxyDistance(); void SetOption(int option); - void SetJostlingSphere(Math::Vector pos, float radius); + void SetJostlingSphere(const Math::Sphere& sphere); public: @@ -108,7 +110,6 @@ public: void SetGlobalSphere(Math::Vector pos, float radius) override; void GetGlobalSphere(Math::Vector &pos, float &radius) override; - void GetJostlingSphere(Math::Vector &pos, float &radius) override; void SetShieldRadius(float radius) override; float GetShieldRadius() override; @@ -210,6 +211,7 @@ public: void SetTeam(int team) override; int GetTeam() override; + Math::Sphere GetJostlingSphere() const override; bool JostleObject(float force) override; void StartDetectEffect(CObject *target, bool bFound) override; @@ -392,8 +394,7 @@ protected: Math::Vector m_globalSpherePos; float m_globalSphereRadius; - Math::Vector m_jostlingSpherePos; - float m_jostlingSphereRadius; + Math::Sphere m_jostlingSphere; float m_shieldRadius; int m_totalPart; diff --git a/src/object/old_object_interface.h b/src/object/old_object_interface.h index 2f7b1f2e..754156c9 100644 --- a/src/object/old_object_interface.h +++ b/src/object/old_object_interface.h @@ -100,7 +100,6 @@ public: virtual void SetGlobalSphere(Math::Vector pos, float radius) = 0; virtual void GetGlobalSphere(Math::Vector &pos, float &radius) = 0; - virtual void GetJostlingSphere(Math::Vector &pos, float &radius) = 0; virtual void SetShieldRadius(float radius) = 0; virtual float GetShieldRadius() = 0; @@ -199,8 +198,6 @@ public: virtual void SetTeam(int team) = 0; virtual int GetTeam() = 0; - virtual bool JostleObject(float force) = 0; - virtual void StartDetectEffect(CObject *target, bool bFound) = 0; virtual void SetVirusMode(bool bEnable) = 0; diff --git a/src/object/robotmain.cpp b/src/object/robotmain.cpp index 80b93b0b..09cfec35 100644 --- a/src/object/robotmain.cpp +++ b/src/object/robotmain.cpp @@ -5506,7 +5506,7 @@ Error CRobotMain::CheckEndMission(bool frame) { CLogger::GetInstancePointer()->Info("Team %d lost\n", team); m_displayText->DisplayText(("<<< Team "+boost::lexical_cast(team)+" lost! >>>").c_str(), Math::Vector(0.0f,0.0f,0.0f), 15.0f, 60.0f, 10.0f, Ui::TT_ERROR); - + m_displayText->SetEnable(false); // To prevent "bot destroyed" messages m_objMan->DestroyTeam(team); m_displayText->SetEnable(true); diff --git a/src/physics/physics.cpp b/src/physics/physics.cpp index 11baf23a..5315798c 100644 --- a/src/physics/physics.cpp +++ b/src/physics/physics.cpp @@ -43,6 +43,7 @@ #include "object/task/task.h" #include "object/level/parserline.h" #include "object/level/parserparam.h" +#include "object/interface/jostleable_object.h" #include "object/interface/transportable_object.h" @@ -2549,12 +2550,9 @@ int CPhysics::ObjectAdapt(const Math::Vector &pos, const Math::Vector &angle) if ( iType == OBJECT_MOTHER && oType == OBJECT_EGG ) continue; if ( iType == OBJECT_EGG && oType == OBJECT_MOTHER ) continue; - Math::Vector jostlingSpherePos; - float jostlingSphereRadius = 0.0f; - pObj->GetJostlingSphere(jostlingSpherePos, jostlingSphereRadius); - if ( jostlingSphereRadius > 0.0f ) + if (pObj->Implements(ObjectInterfaceType::Jostleable)) { - JostleObject(pObj, iPos, iRad, jostlingSpherePos, jostlingSphereRadius); + JostleObject(dynamic_cast(pObj), iPos, iRad); } if ( iType == OBJECT_MOTHER || @@ -2699,23 +2697,21 @@ int CPhysics::ObjectAdapt(const Math::Vector &pos, const Math::Vector &angle) // Shakes an object. -bool CPhysics::JostleObject(CObject* pObj, Math::Vector iPos, float iRad, - Math::Vector oPos, float oRad) +bool CPhysics::JostleObject(CJostleableObject* pObj, Math::Vector iPos, float iRad) { - Math::Vector speed; - float distance, force, d, f; + Math::Sphere jostlingSphere = pObj->GetJostlingSphere(); - distance = Math::Distance(oPos, iPos); - if ( distance >= iRad+oRad ) return false; + float distance = Math::Distance(jostlingSphere.pos, iPos); + if ( distance >= iRad+jostlingSphere.radius) return false; - d = (iRad+oRad)/2.0f; - f = (distance-d)/d; // 0 = off, 1 = near + float d = (iRad+jostlingSphere.radius)/2.0f; + float f = (distance-d)/d; // 0 = off, 1 = near if ( f < 0.0f ) f = 0.0f; if ( f > 1.0f ) f = 1.0f; - speed = m_linMotion.realSpeed; + Math::Vector speed = m_linMotion.realSpeed; speed.y = 0.0f; - force = speed.Length()*f*0.05f; + float force = speed.Length()*f*0.05f; if ( force > 1.0f ) force = 1.0f; if ( m_soundTimeJostle >= 0.20f ) @@ -2731,11 +2727,10 @@ bool CPhysics::JostleObject(CObject* pObj, Math::Vector iPos, float iRad, bool CPhysics::JostleObject(CObject* pObj, float force) { - Math::Vector oPos; - float oRad; + if (! pObj->Implements(ObjectInterfaceType::Jostleable)) + return false; - pObj->GetJostlingSphere(oPos, oRad); - if ( oRad <= 0.0f ) return false; + CJostleableObject* jostleableObject = dynamic_cast(pObj); if ( m_soundTimeJostle >= 0.20f ) { @@ -2743,7 +2738,7 @@ bool CPhysics::JostleObject(CObject* pObj, float force) m_sound->Play(SOUND_JOSTLE, pObj->GetPosition(0), force); } - return pObj->JostleObject(force); + return jostleableObject->JostleObject(force); } // Effects of the explosion on the object buffers. diff --git a/src/physics/physics.h b/src/physics/physics.h index e8996aee..87c0fa2c 100644 --- a/src/physics/physics.h +++ b/src/physics/physics.h @@ -37,6 +37,7 @@ class CBrain; class CMotion; class CSoundInterface; class CLevelParserLine; +class CJostleableObject; namespace Gfx { class CCamera; @@ -192,7 +193,7 @@ protected: void FloorAdapt(float aTime, float rTime, Math::Vector &pos, Math::Vector &angle); void FloorAngle(const Math::Vector &pos, Math::Vector &angle); int ObjectAdapt(const Math::Vector &pos, const Math::Vector &angle); - bool JostleObject(CObject* pObj, Math::Vector iPos, float iRad, Math::Vector oPos, float oRad); + bool JostleObject(CJostleableObject* pObj, Math::Vector iPos, float iRad); bool JostleObject(CObject* pObj, float force); bool ExploOther(ObjectType iType, CObject *pObj, ObjectType oType, float force); int ExploHimself(ObjectType iType, ObjectType oType, float force);