CJostleableObject interface

master
Piotr Dziwinski 2015-07-10 22:11:22 +02:00
parent 5d30de0d09
commit 8d5ddd848d
9 changed files with 87 additions and 46 deletions

View File

@ -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<int>(ObjectInterfaceType::Jostleable)] = true;
}
virtual ~CJostleableObject()
{}
virtual Math::Sphere GetJostlingSphere() const = 0;
virtual bool JostleObject(float force) = 0;
};

View File

@ -1228,7 +1228,7 @@ CObjectUPtr CObjectFactory::CreateFlag(const ObjectCreateParams& params)
else obj->SetPosition(1+i, Math::Vector(0.79f, 0.0f, 0.0f)); 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->CreateShadowCircle(2.0f, 0.3f);
obj->SetFloorHeight(0.0f); 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->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->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); obj->CreateShadowCircle(8.0f, 0.5f);
} }
@ -1392,7 +1392,7 @@ CObjectUPtr CObjectFactory::CreatePlant(const ObjectCreateParams& params)
obj->SetAngleY(0, angle); obj->SetAngleY(0, angle);
//? obj->AddCrashSphere(CrashSphere(Math::Vector(0.0f, 0.0f, 0.0f), 3.0f, SOUND_BOUM, 0.10f)); //? 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); 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->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->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); 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->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->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); 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->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->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); 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->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->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); obj->CreateShadowCircle(5.0f, 0.5f);
} }
@ -2495,7 +2495,7 @@ CObjectUPtr CObjectFactory::CreateApollo(const ObjectCreateParams& params)
obj->SetAngleY(0, angle); obj->SetAngleY(0, angle);
obj->SetFloorHeight(0.0f); 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); obj->CreateShadowCircle(2.0f, 0.3f);
} }

View File

@ -35,6 +35,7 @@ enum class ObjectInterfaceType
Interactive, //!< interactive objects can process events from event loop Interactive, //!< interactive objects can process events from event loop
Transportable, //!< objects that can be carried by robots or astronaut Transportable, //!< objects that can be carried by robots or astronaut
Programmable, //!< objects that can be programmed in CBOT Programmable, //!< objects that can be programmed in CBOT
Jostleable, //!< object that can be jostled
Max //!< maximum value (for getting number of items in enum) Max //!< maximum value (for getting number of items in enum)
}; };

View File

@ -190,9 +190,12 @@ COldObject::COldObject(int id)
, CInteractiveObject(m_implementedInterfaces) , CInteractiveObject(m_implementedInterfaces)
, CTransportableObject(m_implementedInterfaces) , CTransportableObject(m_implementedInterfaces)
, CProgrammableObject(m_implementedInterfaces) , CProgrammableObject(m_implementedInterfaces)
, CJostleableObject(m_implementedInterfaces)
{ {
// A bit of a hack since CBrain is set externally in SetBrain() // A bit of a hack since CBrain is set externally in SetBrain()
m_implementedInterfaces[static_cast<int>(ObjectInterfaceType::Programmable)] = false; m_implementedInterfaces[static_cast<int>(ObjectInterfaceType::Programmable)] = false;
// Another hack
m_implementedInterfaces[static_cast<int>(ObjectInterfaceType::Jostleable)] = false;
m_sound = CApplication::GetInstancePointer()->GetSound(); m_sound = CApplication::GetInstancePointer()->GetSound();
m_engine = Gfx::CEngine::GetInstancePointer(); m_engine = Gfx::CEngine::GetInstancePointer();
@ -290,8 +293,6 @@ COldObject::COldObject(int id)
DeleteAllCrashSpheres(); DeleteAllCrashSpheres();
m_globalSpherePos = Math::Vector(0.0f, 0.0f, 0.0f); m_globalSpherePos = Math::Vector(0.0f, 0.0f, 0.0f);
m_globalSphereRadius = 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"); CBotClass* bc = CBotClass::Find("object");
if ( bc != 0 ) if ( bc != 0 )
@ -1103,18 +1104,19 @@ void COldObject::GetGlobalSphere(Math::Vector &pos, float &radius)
// Specifies the sphere of jostling, relative to the object. // 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_jostlingSphere = jostlingSphere;
m_jostlingSphereRadius = radius; m_implementedInterfaces[static_cast<int>(ObjectInterfaceType::Jostleable)] = true;
} }
// Specifies the sphere of jostling, in the world. // 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); Math::Sphere transformedJostlingSphere = m_jostlingSphere;
radius = m_jostlingSphereRadius; transformedJostlingSphere.pos = Math::Transform(m_objectPart[0].matWorld, transformedJostlingSphere.pos);
return transformedJostlingSphere;
} }

View File

@ -27,6 +27,7 @@
#include "object/object.h" #include "object/object.h"
#include "object/interface/interactive_object.h" #include "object/interface/interactive_object.h"
#include "object/interface/jostleable_object.h"
#include "object/interface/programmable_object.h" #include "object/interface/programmable_object.h"
#include "object/interface/transportable_object.h" #include "object/interface/transportable_object.h"
@ -56,7 +57,8 @@ struct ObjectPart
class COldObject : public CObject, class COldObject : public CObject,
public CInteractiveObject, public CInteractiveObject,
public CTransportableObject, public CTransportableObject,
public CProgrammableObject public CProgrammableObject,
public CJostleableObject
{ {
friend class CObjectFactory; friend class CObjectFactory;
friend class CObjectManager; friend class CObjectManager;
@ -74,7 +76,7 @@ protected:
void SetCapacity(float capacity); void SetCapacity(float capacity);
float GetProxyDistance(); float GetProxyDistance();
void SetOption(int option); void SetOption(int option);
void SetJostlingSphere(Math::Vector pos, float radius); void SetJostlingSphere(const Math::Sphere& sphere);
public: public:
@ -108,7 +110,6 @@ public:
void SetGlobalSphere(Math::Vector pos, float radius) override; void SetGlobalSphere(Math::Vector pos, float radius) override;
void GetGlobalSphere(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; void SetShieldRadius(float radius) override;
float GetShieldRadius() override; float GetShieldRadius() override;
@ -210,6 +211,7 @@ public:
void SetTeam(int team) override; void SetTeam(int team) override;
int GetTeam() override; int GetTeam() override;
Math::Sphere GetJostlingSphere() const override;
bool JostleObject(float force) override; bool JostleObject(float force) override;
void StartDetectEffect(CObject *target, bool bFound) override; void StartDetectEffect(CObject *target, bool bFound) override;
@ -392,8 +394,7 @@ protected:
Math::Vector m_globalSpherePos; Math::Vector m_globalSpherePos;
float m_globalSphereRadius; float m_globalSphereRadius;
Math::Vector m_jostlingSpherePos; Math::Sphere m_jostlingSphere;
float m_jostlingSphereRadius;
float m_shieldRadius; float m_shieldRadius;
int m_totalPart; int m_totalPart;

View File

@ -100,7 +100,6 @@ public:
virtual void SetGlobalSphere(Math::Vector pos, float radius) = 0; virtual void SetGlobalSphere(Math::Vector pos, float radius) = 0;
virtual void GetGlobalSphere(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 void SetShieldRadius(float radius) = 0;
virtual float GetShieldRadius() = 0; virtual float GetShieldRadius() = 0;
@ -199,8 +198,6 @@ public:
virtual void SetTeam(int team) = 0; virtual void SetTeam(int team) = 0;
virtual int GetTeam() = 0; virtual int GetTeam() = 0;
virtual bool JostleObject(float force) = 0;
virtual void StartDetectEffect(CObject *target, bool bFound) = 0; virtual void StartDetectEffect(CObject *target, bool bFound) = 0;
virtual void SetVirusMode(bool bEnable) = 0; virtual void SetVirusMode(bool bEnable) = 0;

View File

@ -5506,7 +5506,7 @@ Error CRobotMain::CheckEndMission(bool frame)
{ {
CLogger::GetInstancePointer()->Info("Team %d lost\n", team); CLogger::GetInstancePointer()->Info("Team %d lost\n", team);
m_displayText->DisplayText(("<<< Team "+boost::lexical_cast<std::string>(team)+" lost! >>>").c_str(), Math::Vector(0.0f,0.0f,0.0f), 15.0f, 60.0f, 10.0f, Ui::TT_ERROR); m_displayText->DisplayText(("<<< Team "+boost::lexical_cast<std::string>(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_displayText->SetEnable(false); // To prevent "bot destroyed" messages
m_objMan->DestroyTeam(team); m_objMan->DestroyTeam(team);
m_displayText->SetEnable(true); m_displayText->SetEnable(true);

View File

@ -43,6 +43,7 @@
#include "object/task/task.h" #include "object/task/task.h"
#include "object/level/parserline.h" #include "object/level/parserline.h"
#include "object/level/parserparam.h" #include "object/level/parserparam.h"
#include "object/interface/jostleable_object.h"
#include "object/interface/transportable_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_MOTHER && oType == OBJECT_EGG ) continue;
if ( iType == OBJECT_EGG && oType == OBJECT_MOTHER ) continue; if ( iType == OBJECT_EGG && oType == OBJECT_MOTHER ) continue;
Math::Vector jostlingSpherePos; if (pObj->Implements(ObjectInterfaceType::Jostleable))
float jostlingSphereRadius = 0.0f;
pObj->GetJostlingSphere(jostlingSpherePos, jostlingSphereRadius);
if ( jostlingSphereRadius > 0.0f )
{ {
JostleObject(pObj, iPos, iRad, jostlingSpherePos, jostlingSphereRadius); JostleObject(dynamic_cast<CJostleableObject*>(pObj), iPos, iRad);
} }
if ( iType == OBJECT_MOTHER || if ( iType == OBJECT_MOTHER ||
@ -2699,23 +2697,21 @@ int CPhysics::ObjectAdapt(const Math::Vector &pos, const Math::Vector &angle)
// Shakes an object. // Shakes an object.
bool CPhysics::JostleObject(CObject* pObj, Math::Vector iPos, float iRad, bool CPhysics::JostleObject(CJostleableObject* pObj, Math::Vector iPos, float iRad)
Math::Vector oPos, float oRad)
{ {
Math::Vector speed; Math::Sphere jostlingSphere = pObj->GetJostlingSphere();
float distance, force, d, f;
distance = Math::Distance(oPos, iPos); float distance = Math::Distance(jostlingSphere.pos, iPos);
if ( distance >= iRad+oRad ) return false; if ( distance >= iRad+jostlingSphere.radius) return false;
d = (iRad+oRad)/2.0f; float d = (iRad+jostlingSphere.radius)/2.0f;
f = (distance-d)/d; // 0 = off, 1 = near float f = (distance-d)/d; // 0 = off, 1 = near
if ( f < 0.0f ) f = 0.0f; if ( f < 0.0f ) f = 0.0f;
if ( f > 1.0f ) f = 1.0f; if ( f > 1.0f ) f = 1.0f;
speed = m_linMotion.realSpeed; Math::Vector speed = m_linMotion.realSpeed;
speed.y = 0.0f; 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 ( force > 1.0f ) force = 1.0f;
if ( m_soundTimeJostle >= 0.20f ) 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) bool CPhysics::JostleObject(CObject* pObj, float force)
{ {
Math::Vector oPos; if (! pObj->Implements(ObjectInterfaceType::Jostleable))
float oRad; return false;
pObj->GetJostlingSphere(oPos, oRad); CJostleableObject* jostleableObject = dynamic_cast<CJostleableObject*>(pObj);
if ( oRad <= 0.0f ) return false;
if ( m_soundTimeJostle >= 0.20f ) 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); 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. // Effects of the explosion on the object buffers.

View File

@ -37,6 +37,7 @@ class CBrain;
class CMotion; class CMotion;
class CSoundInterface; class CSoundInterface;
class CLevelParserLine; class CLevelParserLine;
class CJostleableObject;
namespace Gfx { namespace Gfx {
class CCamera; class CCamera;
@ -192,7 +193,7 @@ protected:
void FloorAdapt(float aTime, float rTime, Math::Vector &pos, Math::Vector &angle); void FloorAdapt(float aTime, float rTime, Math::Vector &pos, Math::Vector &angle);
void FloorAngle(const 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); 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 JostleObject(CObject* pObj, float force);
bool ExploOther(ObjectType iType, CObject *pObj, ObjectType oType, float force); bool ExploOther(ObjectType iType, CObject *pObj, ObjectType oType, float force);
int ExploHimself(ObjectType iType, ObjectType oType, float force); int ExploHimself(ObjectType iType, ObjectType oType, float force);