CMovableObject, CControllableObject

master
krzys-h 2015-08-10 23:20:36 +02:00
parent 8ad3b4e552
commit 15c1c7ee03
16 changed files with 300 additions and 256 deletions

View File

@ -250,7 +250,8 @@ bool CPyro::Create(PyroType type, CObject* obj, float force)
{
m_sound->Play(SOUND_DEADw, m_pos);
}
if ( type == PT_SHOTH && m_object->GetSelect() )
assert(m_object->Implements(ObjectInterfaceType::Controllable));
if ( type == PT_SHOTH && dynamic_cast<CControllableObject*>(m_object)->GetSelect() )
{
m_sound->Play(SOUND_AIE, m_pos);
m_sound->Play(SOUND_AIE, m_engine->GetEyePt());
@ -301,7 +302,8 @@ bool CPyro::Create(PyroType type, CObject* obj, float force)
}
if ( m_type == PT_SHOTH )
{
if ( m_camera->GetBlood() && m_object->GetSelect() )
assert(m_object->Implements(ObjectInterfaceType::Controllable));
if ( m_camera->GetBlood() && dynamic_cast<CControllableObject*>(m_object)->GetSelect() )
{
m_camera->StartOver(CAM_OVER_EFFECT_BLOOD, m_pos, force);
}
@ -1539,9 +1541,9 @@ void CPyro::ExploStart()
m_object->SetExploding(true); // being destroyed
m_object->FlatParent();
if ( m_object->GetSelect() )
if ( m_object->Implements(ObjectInterfaceType::Controllable) && dynamic_cast<CControllableObject*>(m_object)->GetSelect() )
{
m_object->SetSelect(false); // deselects the object
dynamic_cast<CControllableObject*>(m_object)->SetSelect(false); // deselects the object
m_camera->SetType(CAM_TYPE_EXPLO);
m_main->DeselectAll();
}
@ -1612,9 +1614,9 @@ void CPyro::BurnStart()
m_object->Simplify();
m_object->SetLock(true); // ruin not usable yet
if ( m_object->GetSelect() )
if ( m_object->Implements(ObjectInterfaceType::Controllable) && dynamic_cast<CControllableObject*>(m_object)->GetSelect() )
{
m_object->SetSelect(false); // deselects the object
dynamic_cast<CControllableObject*>(m_object)->SetSelect(false); // deselects the object
m_camera->SetType(CAM_TYPE_EXPLO);
m_main->DeselectAll();
}
@ -2405,4 +2407,3 @@ void CPyro::LightOperFrame(float rTime)
} // namespace Gfx

View File

@ -159,14 +159,15 @@ begin:
pObj = m_main->GetSelectObject();
m_main->SelectObject(pObj);
m_camera->SetControllingObject(pObj);
if ( pObj == 0 )
if ( pObj == nullptr )
{
m_camera->SetType(Gfx::CAM_TYPE_BACK);
}
else
{
m_camera->SetType(pObj->GetCameraType());
m_camera->SetDist(pObj->GetCameraDist());
assert(pObj->Implements(ObjectInterfaceType::Controllable));
m_camera->SetType(dynamic_cast<CControllableObject*>(pObj)->GetCameraType());
m_camera->SetDist(dynamic_cast<CControllableObject*>(pObj)->GetCameraDist());
}
m_main->StartMusic();
@ -586,14 +587,15 @@ begin:
pObj = m_main->GetSelectObject();
m_main->SelectObject(pObj);
m_camera->SetControllingObject(pObj);
if ( pObj == 0 )
if ( pObj == nullptr )
{
m_camera->SetType(Gfx::CAM_TYPE_BACK);
}
else
{
m_camera->SetType(pObj->GetCameraType());
m_camera->SetDist(pObj->GetCameraDist());
assert(pObj->Implements(ObjectInterfaceType::Controllable));
m_camera->SetType(dynamic_cast<CControllableObject*>(pObj)->GetCameraType());
m_camera->SetDist(dynamic_cast<CControllableObject*>(pObj)->GetCameraDist());
}
m_sound->Play(SOUND_BOUM, m_object->GetPosition());
m_soundChannel = -1;
@ -1116,14 +1118,15 @@ bool CAutoBase::Abort()
pObj = m_main->GetSelectObject();
m_main->SelectObject(pObj);
m_camera->SetControllingObject(pObj);
if ( pObj == 0 )
if ( pObj == nullptr )
{
m_camera->SetType(Gfx::CAM_TYPE_BACK);
}
else
{
m_camera->SetType(pObj->GetCameraType());
m_camera->SetDist(pObj->GetCameraDist());
assert(pObj->Implements(ObjectInterfaceType::Controllable));
m_camera->SetType(dynamic_cast<CControllableObject*>(pObj)->GetCameraType());
m_camera->SetDist(dynamic_cast<CControllableObject*>(pObj)->GetCameraDist());
}
m_engine->SetFogStart(m_fogStart);

View File

@ -71,7 +71,10 @@ void CAutoEgg::DeleteObject(bool all)
if ( alien->GetScaleY() == 1.0f )
{
alien->SetLock(false);
alien->SetActivity(true); // the insect is active
if (alien->Implements(ObjectInterfaceType::Programmable))
{
dynamic_cast<CProgrammableObject*>(alien)->SetActivity(true); // the insect is active
}
}
else
{
@ -117,7 +120,10 @@ void CAutoEgg::Init()
}
alien->SetLock(true);
alien->SetActivity(false);
if (alien->Implements(ObjectInterfaceType::Programmable))
{
dynamic_cast<CProgrammableObject*>(alien)->SetActivity(false);
}
}
@ -180,12 +186,12 @@ bool CAutoEgg::EventProcess(const Event &event)
float angle = m_object->GetRotationY();
CObject* alien = CObjectManager::GetInstancePointer()->CreateObject(pos, angle, m_type);
alien->SetActivity(false);
if (alien->Implements(ObjectInterfaceType::Programmable))
{
CProgrammableObject* programmable = dynamic_cast<CProgrammableObject*>(alien);
programmable->SetActivity(false);
Program* program = programmable->AddProgram();
programmable->ReadProgram(program, m_alienProgramName.c_str());
programmable->RunProgram(program);
@ -195,7 +201,10 @@ bool CAutoEgg::EventProcess(const Event &event)
CObject* alien = SearchAlien();
if ( alien == nullptr ) return true;
alien->SetActivity(false);
if (alien->Implements(ObjectInterfaceType::Programmable))
{
dynamic_cast<CProgrammableObject*>(alien)->SetActivity(false);
}
m_progress += event.rTime*m_speed;
@ -253,7 +262,10 @@ Error CAutoEgg::IsEnded()
if ( m_progress < 1.0f ) return ERR_CONTINUE;
alien->SetLock(false);
alien->SetActivity(true); // the insect is active
if(alien->Implements(ObjectInterfaceType::Programmable))
{
dynamic_cast<CProgrammableObject*>(alien)->SetActivity(true); // the insect is active
}
}
return ERR_STOP;

View File

@ -0,0 +1,51 @@
/*
* This file is part of the Colobot: Gold Edition source code
* Copyright (C) 2001-2015, 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"
/**
* \class CControllableObject
* \brief Interface for objects that can be selected and controlled by the player
*/
class CControllableObject
{
public:
explicit CControllableObject(ObjectInterfaceTypes& types)
{
types[static_cast<int>(ObjectInterfaceType::Controllable)] = true;
}
virtual ~CControllableObject()
{}
virtual void SetTrainer(bool trainer) = 0;
virtual bool GetTrainer() = 0;
virtual void SetSelect(bool select, bool bDisplayError = true) = 0;
virtual bool GetSelect() = 0;
virtual bool GetSelectable() = 0;
virtual void SetCameraType(Gfx::CameraType type) = 0;
virtual Gfx::CameraType GetCameraType() = 0;
virtual void SetCameraDist(float dist) = 0;
virtual float GetCameraDist() = 0;
virtual void SetCameraLock(bool lock) = 0;
virtual bool GetCameraLock() = 0;
};

View File

@ -0,0 +1,37 @@
/*
* This file is part of the Colobot: Gold Edition source code
* Copyright (C) 2001-2015, 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"
/**
* \class CMovableObject
* \brief Interface for objects that can move (have an engine)
*/
class CMovableObject
{
public:
explicit CMovableObject(ObjectInterfaceTypes& types)
{
types[static_cast<int>(ObjectInterfaceType::Movable)] = true;
}
virtual ~CMovableObject()
{}
};

View File

@ -88,4 +88,13 @@ public:
virtual void TraceRecordStop() = 0;
//! Returns true if trace recording is in progress
virtual bool IsTraceRecord() = 0;
//! Management of object "activity" (temporairly stops program execution, right now used only by Aliens in eggs)
//@{
virtual void SetActivity(bool bMode) = 0;
virtual bool GetActivity() = 0;
//@}
//! Returns program cmdline values for an object
virtual float GetCmdLine(unsigned int rank) = 0;
};

View File

@ -40,6 +40,8 @@ enum class ObjectInterfaceType
Jostleable, //!< object that can be jostled
Carrier, //!< object that can carry other objects
Powered, //!< object powered with power cell
Movable, //!< objects that can move
Controllable, //!< objects that can be selected and controlled by the player
Old, //!< old objects, TODO: remove once no longer necessary
Max //!< maximum value (for getting number of items in enum)
};

View File

@ -101,6 +101,8 @@ COldObject::COldObject(int id)
, CJostleableObject(m_implementedInterfaces)
, CCarrierObject(m_implementedInterfaces)
, CPoweredObject(m_implementedInterfaces)
, CMovableObject(m_implementedInterfaces)
, CControllableObject(m_implementedInterfaces)
{
// A bit of a hack since we don't have subclasses yet, set externally in SetProgrammable()
m_implementedInterfaces[static_cast<int>(ObjectInterfaceType::Programmable)] = false;
@ -156,7 +158,6 @@ COldObject::COldObject(int id)
m_virusTime = 0.0f;
m_lastVirusParticle = 0.0f;
m_bLock = false;
m_bIgnoreBuildCheck = false;
m_bExplo = false;
m_bCargo = false;
m_bBurn = false;
@ -836,8 +837,6 @@ void COldObject::Write(CLevelParserLine* line)
if ( m_virusTime != 0.0f )
line->AddParam("virusTime", MakeUnique<CLevelParserParam>(m_virusTime));
line->AddParam("ignoreBuildCheck", MakeUnique<CLevelParserParam>(GetIgnoreBuildCheck()));
// Sets the parameters of the command line.
CLevelParserParamVec cmdline;
for(float value : m_cmdLine)
@ -855,7 +854,10 @@ void COldObject::Write(CLevelParserLine* line)
if ( Implements(ObjectInterfaceType::Programmable) )
{
line->AddParam("bVirusActive", MakeUnique<CLevelParserParam>(m_bActiveVirus));
}
if ( Implements(ObjectInterfaceType::TaskExecutor) )
{
if ( m_type == OBJECT_MOBILErs )
{
line->AddParam("bShieldActive", MakeUnique<CLevelParserParam>(IsBackgroundTask()));
@ -905,7 +907,6 @@ void COldObject::Read(CLevelParserLine* line)
m_bBurn = line->GetParam("burnMode")->AsBool(false);
m_bVirusMode = line->GetParam("virusMode")->AsBool(false);
m_virusTime = line->GetParam("virusTime")->AsFloat(0.0f);
SetIgnoreBuildCheck(line->GetParam("ignoreBuildCheck")->AsBool(false));
// Sets the parameters of the command line.
if (line->GetParam("cmdline")->IsDefined())
@ -923,9 +924,13 @@ void COldObject::Read(CLevelParserLine* line)
m_motion->Read(line);
}
if ( Implements(ObjectInterfaceType::Programmable) )
if (Implements(ObjectInterfaceType::Programmable))
{
m_bActiveVirus = line->GetParam("bVirusActive")->AsBool(false);
}
if (Implements(ObjectInterfaceType::TaskExecutor))
{
if ( m_type == OBJECT_MOBILErs )
{
if( line->GetParam("bShieldActive")->AsBool(false) )
@ -934,6 +939,7 @@ void COldObject::Read(CLevelParserLine* line)
}
}
}
if ( m_physics != nullptr )
{
m_physics->Read(line);
@ -1882,16 +1888,27 @@ bool COldObject::EventProcess(const Event &event)
}
}
if ( Implements(ObjectInterfaceType::Programmable) )
if (Implements(ObjectInterfaceType::Programmable))
{
if ( GetRuin() && m_currentProgram != nullptr )
{
StopProgram();
}
}
if ( !GetSelect() && // robot pas sélectionné ?
m_currentProgram == nullptr &&
!IsForegroundTask() )
if (Implements(ObjectInterfaceType::Movable) && m_physics != nullptr)
{
bool deselectedStop = !GetSelect();
if (Implements(ObjectInterfaceType::Programmable))
{
deselectedStop = deselectedStop && !IsProgram();
}
if (Implements(ObjectInterfaceType::TaskExecutor))
{
deselectedStop = deselectedStop && !IsForegroundTask();
}
if ( deselectedStop )
{
float axeX = 0.0f;
float axeY = 0.0f;
@ -1922,7 +1939,17 @@ bool COldObject::EventProcess(const Event &event)
}
else if (GetSelect())
{
if ( (IsForegroundTask() && GetForegroundTask()->IsPilot()) || m_currentProgram == nullptr )
bool canMove = true;
if (Implements(ObjectInterfaceType::Programmable))
{
canMove = canMove && !IsProgram();
}
if (Implements(ObjectInterfaceType::TaskExecutor))
{
canMove = canMove || (IsForegroundTask() && GetForegroundTask()->IsPilot());
}
if ( canMove )
{
if ( event.type == EVENT_OBJECT_LEFT ||
event.type == EVENT_OBJECT_RIGHT ||
@ -2583,9 +2610,9 @@ float COldObject::GetCameraDist()
return m_cameraDist;
}
void COldObject::SetCameraLock(bool bLock)
void COldObject::SetCameraLock(bool lock)
{
m_bCameraLock = bLock;
m_bCameraLock = lock;
}
bool COldObject::GetCameraLock()
@ -2620,11 +2647,9 @@ void COldObject::SetHighlight(bool mode)
// Indicates whether the object is selected or not.
void COldObject::SetSelect(bool bMode, bool bDisplayError)
void COldObject::SetSelect(bool select, bool bDisplayError)
{
Error err;
m_bSelect = bMode;
m_bSelect = select;
// NOTE: Right now, Ui::CObjectInterface is only for programmable objects. Right now all selectable objects are programmable anyway.
// TODO: All UI-related stuff should be moved out of CObject classes
@ -2645,12 +2670,9 @@ void COldObject::SetSelect(bool bMode, bool bDisplayError)
CreateSelectParticle(); // creates / removes particles
if ( !m_bSelect )
{
//SetGunGoalH(0.0f); // puts the cannon right
return; // selects if not finished
}
return; // if not selected, we're done
err = ERR_OK;
Error err = ERR_OK;
if ( m_physics != nullptr )
{
err = m_physics->GetError();
@ -2667,9 +2689,8 @@ void COldObject::SetSelect(bool bMode, bool bDisplayError)
// Indicates whether the object is selected or not.
bool COldObject::GetSelect(bool bReal)
bool COldObject::GetSelect()
{
if ( !bReal && m_main->GetFixScene() ) return false;
return m_bSelect;
}
@ -2791,18 +2812,6 @@ bool COldObject::GetLock()
return m_bLock;
}
// Ignore checks in build() function
void COldObject::SetIgnoreBuildCheck(bool bIgnoreBuildCheck)
{
m_bIgnoreBuildCheck = bIgnoreBuildCheck;
}
bool COldObject::GetIgnoreBuildCheck()
{
return m_bIgnoreBuildCheck;
}
// Management of the mode "current explosion" of an object.
// An object in this mode is not saving.

View File

@ -27,8 +27,10 @@
#include "object/object.h"
#include "object/interface/carrier_object.h"
#include "object/interface/controllable_object.h"
#include "object/interface/interactive_object.h"
#include "object/interface/jostleable_object.h"
#include "object/interface/movable_object.h"
#include "object/interface/powered_object.h"
#include "object/interface/programmable_object.h"
#include "object/interface/task_executor_object.h"
@ -83,7 +85,9 @@ class COldObject : public CObject,
public CProgrammableObject,
public CJostleableObject,
public CCarrierObject,
public CPoweredObject
public CPoweredObject,
public CMovableObject,
public CControllableObject
{
friend class CObjectFactory;
friend class CObjectManager;
@ -229,22 +233,19 @@ public:
Gfx::CameraType GetCameraType() override;
void SetCameraDist(float dist) override;
float GetCameraDist() override;
void SetCameraLock(bool bLock) override;
void SetCameraLock(bool lock) override;
bool GetCameraLock() override;
void SetHighlight(bool mode) override;
void SetSelect(bool bMode, bool bDisplayError=true) override;
bool GetSelect(bool bReal=false) override;
void SetSelect(bool select, bool bDisplayError = true) override;
bool GetSelect() override;
void SetSelectable(bool bMode);
bool GetSelectable() override;
//! Management of object "activity" (temporairly stops program execution, right now used only by Aliens in eggs)
//@{
void SetActivity(bool activity) override;
bool GetActivity() override;
//@}
void SetVisible(bool bVisible);
@ -263,8 +264,6 @@ public:
void SetParam(float value) override;
float GetParam() override;
void SetIgnoreBuildCheck(bool bIgnoreBuildCheck) override;
bool GetIgnoreBuildCheck() override;
void SetExploding(bool bExplo) override;
bool IsExploding() override;
@ -468,7 +467,6 @@ protected:
bool m_bTrainer; // drive vehicle (without remote)
bool m_bToy; // toy key
bool m_bManual; // manual control (Scribbler)
bool m_bIgnoreBuildCheck;
bool m_bFixed;
bool m_bClip;
bool m_bShowLimit;

View File

@ -82,26 +82,11 @@ Math::Vector COldObjectInterface::GetTilt()
throw std::logic_error("GetTilt: not implemented!");
}
void COldObjectInterface::SetTrainer(bool bEnable)
{
throw std::logic_error("SetTrainer: not implemented!");
}
bool COldObjectInterface::GetTrainer()
{
throw std::logic_error("GetTrainer: not implemented!");
}
void COldObjectInterface::SetMasterParticle(int part, int parti)
{
throw std::logic_error("SetMasterParticle: not implemented!");
}
float COldObjectInterface::GetCmdLine(unsigned int rank)
{
throw std::logic_error("GetCmdLine: not implemented!");
}
Math::Matrix* COldObjectInterface::GetWorldMatrix(int part)
{
throw std::logic_error("GetWorldMatrix: not implemented!");
@ -201,36 +186,6 @@ bool COldObjectInterface::GetVirusMode()
throw std::logic_error("GetVirusMode: not implemented!");
}
void COldObjectInterface::SetCameraType(Gfx::CameraType type)
{
throw std::logic_error("SetCameraType: not implemented!");
}
Gfx::CameraType COldObjectInterface::GetCameraType()
{
throw std::logic_error("GetCameraType: not implemented!");
}
void COldObjectInterface::SetCameraDist(float dist)
{
throw std::logic_error("SetCameraDist: not implemented!");
}
float COldObjectInterface::GetCameraDist()
{
throw std::logic_error("GetCameraDist: not implemented!");
}
void COldObjectInterface::SetCameraLock(bool bLock)
{
throw std::logic_error("SetCameraLock: not implemented!");
}
bool COldObjectInterface::GetCameraLock()
{
throw std::logic_error("GetCameraLock: not implemented!");
}
void COldObjectInterface::SetHighlight(bool mode)
{
@ -240,35 +195,6 @@ void COldObjectInterface::SetHighlight(bool mode)
}
void COldObjectInterface::SetSelect(bool bMode, bool bDisplayError)
{
// TODO: temporary hack
//throw std::logic_error("SetSelect: not implemented!");
}
bool COldObjectInterface::GetSelect(bool bReal)
{
// TODO: temporary hack
return false;
//throw std::logic_error("GetSelect: not implemented!");
}
bool COldObjectInterface::GetSelectable()
{
throw std::logic_error("GetSelectable: not implemented!");
}
void COldObjectInterface::SetActivity(bool bMode)
{
throw std::logic_error("SetActivity: not implemented!");
}
bool COldObjectInterface::GetActivity()
{
throw std::logic_error("GetActivity: not implemented!");
}
void COldObjectInterface::SetEnable(bool bEnable)
{
throw std::logic_error("SetEnable: not implemented!");
@ -313,15 +239,6 @@ float COldObjectInterface::GetParam()
{
throw std::logic_error("GetParam: not implemented!");
}
void COldObjectInterface::SetIgnoreBuildCheck(bool bIgnoreBuildCheck)
{
throw std::logic_error("SetIgnoreBuildCheck: not implemented!");
}
bool COldObjectInterface::GetIgnoreBuildCheck()
{
throw std::logic_error("GetIgnoreBuildCheck: not implemented!");
}
void COldObjectInterface::SetExploding(bool bExplo)

View File

@ -73,7 +73,6 @@ public:
virtual void SetDrawFront(bool bDraw);
virtual float GetShieldRadius();
virtual void FloorAdjust();
@ -82,13 +81,8 @@ public:
virtual Math::Vector GetTilt();
virtual void SetTrainer(bool bEnable);
virtual bool GetTrainer();
virtual void SetMasterParticle(int part, int parti);
virtual float GetCmdLine(unsigned int rank);
virtual Math::Matrix* GetWorldMatrix(int part);
virtual void SetViewFromHere(Math::Vector &eye, float &dirH, float &dirV,
@ -120,22 +114,8 @@ public:
virtual void SetVirusMode(bool bEnable);
virtual bool GetVirusMode();
virtual void SetCameraType(Gfx::CameraType type);
virtual Gfx::CameraType GetCameraType();
virtual void SetCameraDist(float dist);
virtual float GetCameraDist();
virtual void SetCameraLock(bool bLock);
virtual bool GetCameraLock();
virtual void SetHighlight(bool mode);
virtual void SetSelect(bool bMode, bool bDisplayError=true);
virtual bool GetSelect(bool bReal=false);
virtual bool GetSelectable();
virtual void SetActivity(bool bMode);
virtual bool GetActivity();
virtual void SetEnable(bool bEnable);
virtual bool GetEnable();
@ -145,10 +125,13 @@ public:
virtual void SetMagnifyDamage(float factor);
virtual float GetMagnifyDamage();
//! Shielder radius (only while active) [0 or RADIUS_SHIELD_MIN..RADIUS_SHIELD_MAX]
virtual float GetShieldRadius();
//! Shielder radius [0..1]
//@{
virtual void SetParam(float value);
virtual float GetParam();
virtual void SetIgnoreBuildCheck(bool bIgnoreBuildCheck);
virtual bool GetIgnoreBuildCheck();
//@}
virtual void SetExploding(bool bExplo);
virtual bool IsExploding();

View File

@ -1728,8 +1728,10 @@ CObject* CRobotMain::DeselectAll()
CObject* prev = nullptr;
for (CObject* obj : m_objMan->GetAllObjects())
{
if (obj->GetSelect()) prev = obj;
obj->SetSelect(false);
if (!obj->Implements(ObjectInterfaceType::Controllable)) continue;
auto controllableObj = dynamic_cast<CControllableObject*>(obj);
if (controllableObj->GetSelect()) prev = obj;
controllableObj->SetSelect(false);
}
return prev;
}
@ -1737,7 +1739,8 @@ CObject* CRobotMain::DeselectAll()
//! Selects an object, without attending to deselect the rest
void CRobotMain::SelectOneObject(CObject* obj, bool displayError)
{
obj->SetSelect(true, displayError);
assert(obj->Implements(ObjectInterfaceType::Controllable));
dynamic_cast<CControllableObject*>(obj)->SetSelect(true, displayError);
m_camera->SetControllingObject(obj);
ObjectType type = obj->GetType();
@ -1770,8 +1773,8 @@ void CRobotMain::SelectOneObject(CObject* obj, bool displayError)
type == OBJECT_MOBILEdr ||
type == OBJECT_APOLLO2 )
{
m_camera->SetType(obj->GetCameraType());
m_camera->SetDist(obj->GetCameraDist());
m_camera->SetType(dynamic_cast<CControllableObject*>(obj)->GetCameraType());
m_camera->SetDist(dynamic_cast<CControllableObject*>(obj)->GetCameraDist());
}
else
{
@ -1890,7 +1893,8 @@ CObject* CRobotMain::GetSelect()
{
for (CObject* obj : m_objMan->GetAllObjects())
{
if (obj->GetSelect())
if (!obj->Implements(ObjectInterfaceType::Controllable)) continue;
if (dynamic_cast<CControllableObject*>(obj)->GetSelect())
return obj;
}
return nullptr;
@ -2048,7 +2052,8 @@ CObject* CRobotMain::DetectObject(Math::Point pos)
//! Indicates whether an object is selectable
bool CRobotMain::IsSelectable(CObject* obj)
{
if (!obj->GetSelectable()) return false;
if (!obj->Implements(ObjectInterfaceType::Controllable)) return false;
if (!dynamic_cast<CControllableObject*>(obj)->GetSelectable()) return false;
ObjectType type = obj->GetType();
if ( type == OBJECT_HUMAN ||
@ -2123,10 +2128,11 @@ bool CRobotMain::DeleteObject()
{
CObject* obj = GetSelect();
if (obj == nullptr) return false;
assert(obj->Implements(ObjectInterfaceType::Controllable));
m_engine->GetPyroManager()->Create(Gfx::PT_FRAGT, obj);
obj->SetSelect(false); // deselects the object
dynamic_cast<CControllableObject*>(obj)->SetSelect(false); // deselects the object
m_camera->SetType(Gfx::CAM_TYPE_EXPLO);
DeselectAll();
RemoveFromSelectionHistory(obj);
@ -2304,66 +2310,65 @@ void CRobotMain::HelpObject()
//! Change the mode of the camera
void CRobotMain::ChangeCamera()
{
for (CObject* obj : m_objMan->GetAllObjects())
CObject* obj = GetSelect();
if (obj == nullptr) return;
assert(obj->Implements(ObjectInterfaceType::Controllable));
auto controllableObj = dynamic_cast<CControllableObject*>(obj);
if (controllableObj->GetCameraLock()) return;
ObjectType oType = obj->GetType();
Gfx::CameraType type = controllableObj->GetCameraType();
if ( oType != OBJECT_MOBILEfa &&
oType != OBJECT_MOBILEta &&
oType != OBJECT_MOBILEwa &&
oType != OBJECT_MOBILEia &&
oType != OBJECT_MOBILEfc &&
oType != OBJECT_MOBILEtc &&
oType != OBJECT_MOBILEwc &&
oType != OBJECT_MOBILEic &&
oType != OBJECT_MOBILEfi &&
oType != OBJECT_MOBILEti &&
oType != OBJECT_MOBILEwi &&
oType != OBJECT_MOBILEii &&
oType != OBJECT_MOBILEfs &&
oType != OBJECT_MOBILEts &&
oType != OBJECT_MOBILEws &&
oType != OBJECT_MOBILEis &&
oType != OBJECT_MOBILErt &&
oType != OBJECT_MOBILErc &&
oType != OBJECT_MOBILErr &&
oType != OBJECT_MOBILErs &&
oType != OBJECT_MOBILEsa &&
oType != OBJECT_MOBILEtg &&
oType != OBJECT_MOBILEft &&
oType != OBJECT_MOBILEtt &&
oType != OBJECT_MOBILEwt &&
oType != OBJECT_MOBILEit &&
oType != OBJECT_MOBILEdr &&
oType != OBJECT_APOLLO2 ) return;
if (oType == OBJECT_MOBILEdr) // designer?
{
if (obj->GetSelect())
{
if (obj->GetCameraLock()) return;
ObjectType oType = obj->GetType();
Gfx::CameraType type = obj->GetCameraType();
if ( oType != OBJECT_MOBILEfa &&
oType != OBJECT_MOBILEta &&
oType != OBJECT_MOBILEwa &&
oType != OBJECT_MOBILEia &&
oType != OBJECT_MOBILEfc &&
oType != OBJECT_MOBILEtc &&
oType != OBJECT_MOBILEwc &&
oType != OBJECT_MOBILEic &&
oType != OBJECT_MOBILEfi &&
oType != OBJECT_MOBILEti &&
oType != OBJECT_MOBILEwi &&
oType != OBJECT_MOBILEii &&
oType != OBJECT_MOBILEfs &&
oType != OBJECT_MOBILEts &&
oType != OBJECT_MOBILEws &&
oType != OBJECT_MOBILEis &&
oType != OBJECT_MOBILErt &&
oType != OBJECT_MOBILErc &&
oType != OBJECT_MOBILErr &&
oType != OBJECT_MOBILErs &&
oType != OBJECT_MOBILEsa &&
oType != OBJECT_MOBILEtg &&
oType != OBJECT_MOBILEft &&
oType != OBJECT_MOBILEtt &&
oType != OBJECT_MOBILEwt &&
oType != OBJECT_MOBILEit &&
oType != OBJECT_MOBILEdr &&
oType != OBJECT_APOLLO2 ) return;
if (oType == OBJECT_MOBILEdr) // designer?
{
if (type == Gfx::CAM_TYPE_PLANE ) type = Gfx::CAM_TYPE_BACK;
else if (type == Gfx::CAM_TYPE_BACK ) type = Gfx::CAM_TYPE_PLANE;
}
else if (obj->GetTrainer()) // trainer?
{
if (type == Gfx::CAM_TYPE_ONBOARD) type = Gfx::CAM_TYPE_FIX;
else if (type == Gfx::CAM_TYPE_FIX ) type = Gfx::CAM_TYPE_PLANE;
else if (type == Gfx::CAM_TYPE_PLANE ) type = Gfx::CAM_TYPE_BACK;
else if (type == Gfx::CAM_TYPE_BACK ) type = Gfx::CAM_TYPE_ONBOARD;
}
else
{
if (type == Gfx::CAM_TYPE_ONBOARD) type = Gfx::CAM_TYPE_BACK;
else if (type == Gfx::CAM_TYPE_BACK ) type = Gfx::CAM_TYPE_ONBOARD;
}
obj->SetCameraType(type);
m_camera->SetType(type);
}
if (type == Gfx::CAM_TYPE_PLANE ) type = Gfx::CAM_TYPE_BACK;
else if (type == Gfx::CAM_TYPE_BACK ) type = Gfx::CAM_TYPE_PLANE;
}
else if (controllableObj->GetTrainer()) // trainer?
{
if (type == Gfx::CAM_TYPE_ONBOARD) type = Gfx::CAM_TYPE_FIX;
else if (type == Gfx::CAM_TYPE_FIX ) type = Gfx::CAM_TYPE_PLANE;
else if (type == Gfx::CAM_TYPE_PLANE ) type = Gfx::CAM_TYPE_BACK;
else if (type == Gfx::CAM_TYPE_BACK ) type = Gfx::CAM_TYPE_ONBOARD;
}
else
{
if (type == Gfx::CAM_TYPE_ONBOARD) type = Gfx::CAM_TYPE_BACK;
else if (type == Gfx::CAM_TYPE_BACK ) type = Gfx::CAM_TYPE_ONBOARD;
}
controllableObj->SetCameraType(type);
m_camera->SetType(type);
}
//! Remote control the camera using the arrow keys
@ -2398,7 +2403,8 @@ void CRobotMain::KeyCamera(EventType type, InputSlot key)
CObject* obj = GetSelect();
if (obj == nullptr) return;
if (!obj->GetTrainer()) return;
assert(obj->Implements(ObjectInterfaceType::Controllable));
if (!dynamic_cast<CControllableObject*>(obj)->GetTrainer()) return;
if (type == EVENT_KEY_DOWN)
{
@ -3464,7 +3470,6 @@ void CRobotMain::CreateScene(bool soluce, bool fixScene, bool resetObject)
{
m_controller = m_objMan->CreateObject(Math::Vector(0.0f, 0.0f, 0.0f), 0.0f, OBJECT_CONTROLLER, 100.0f);
m_controller->SetMagnifyDamage(100.0f);
m_controller->SetIgnoreBuildCheck(true);
if (m_controller->Implements(ObjectInterfaceType::Programmable))
{
CProgrammableObject* programmable = dynamic_cast<CProgrammableObject*>(m_controller);
@ -3599,7 +3604,6 @@ void CRobotMain::CreateScene(bool soluce, bool fixScene, bool resetObject)
bool selectable = line->GetParam("selectable")->AsBool(true);
oldObj->SetSelectable(selectable);
oldObj->SetIgnoreBuildCheck(line->GetParam("ignoreBuildCheck")->AsBool(false));
oldObj->SetEnable(line->GetParam("enable")->AsBool(true));
oldObj->SetProxyActivate(line->GetParam("proxyActivate")->AsBool(false));
oldObj->SetProxyDistance(line->GetParam("proxyDistance")->AsFloat(15.0f)*g_unit);
@ -3972,9 +3976,10 @@ void CRobotMain::CreateScene(bool soluce, bool fixScene, bool resetObject)
if (obj != nullptr)
{
assert(obj->Implements(ObjectInterfaceType::Controllable));
SelectObject(obj);
m_camera->SetControllingObject(obj);
m_camera->SetType(obj->GetCameraType());
m_camera->SetType(dynamic_cast<CControllableObject*>(obj)->GetCameraType());
}
}
@ -4990,12 +4995,16 @@ void CRobotMain::IOWriteObject(CLevelParserLine* line, CObject* obj)
}
}
line->AddParam("trainer", MakeUnique<CLevelParserParam>(obj->GetTrainer()));
line->AddParam("option", MakeUnique<CLevelParserParam>(obj->GetOption()));
}
if (obj->GetSelect())
line->AddParam("select", MakeUnique<CLevelParserParam>(true));
if (obj->Implements(ObjectInterfaceType::Controllable))
{
auto controllableObj = dynamic_cast<CControllableObject*>(obj);
line->AddParam("trainer", MakeUnique<CLevelParserParam>(controllableObj->GetTrainer()));
if (controllableObj->GetSelect())
line->AddParam("select", MakeUnique<CLevelParserParam>(true));
}
obj->Write(line);
@ -5670,7 +5679,15 @@ Error CRobotMain::CheckEndMission(bool frame)
return ERR_OK; // mission ended
}
if (frame && m_base != nullptr && m_base->GetSelectable() && !isImmediat) return ERR_MISSION_NOTERM;
if (frame)
{
if(m_base != nullptr && !isImmediat)
{
assert(m_base->Implements(ObjectInterfaceType::Controllable));
if(dynamic_cast<CControllableObject*>(m_base)->GetSelectable())
return ERR_MISSION_NOTERM;
}
}
if (m_winDelay == 0.0f)
{

View File

@ -1436,9 +1436,6 @@ bool CScriptFunctions::rBuild(CBotVar* var, CBotVar* result, int& exception, voi
category = static_cast<ObjectType>(var->GetValInt()); // get category parameter
err = CRobotMain::GetInstancePointer()->CanBuildError(category, pThis->GetTeam());
if (pThis->GetIgnoreBuildCheck())
err = ERR_OK;
if (err == ERR_OK && !script->m_taskExecutor->IsForegroundTask()) // if we can build
{
err = script->m_taskExecutor->StartTaskBuild(category);
@ -1584,7 +1581,10 @@ bool CScriptFunctions::rProduce(CBotVar* var, CBotVar* result, int& exception, v
{
object = CObjectManager::GetInstancePointer()->CreateObject(pos, angle, type);
CObjectManager::GetInstancePointer()->CreateObject(pos, angle, OBJECT_EGG, 0.0f);
object->SetActivity(false);
if (object->Implements(ObjectInterfaceType::Programmable))
{
dynamic_cast<CProgrammableObject*>(object)->SetActivity(false);
}
}
else
{
@ -2808,8 +2808,10 @@ bool CScriptFunctions::rCmdline(CBotVar* var, CBotVar* result, int& exception, v
float value;
int rank;
assert(pThis->Implements(ObjectInterfaceType::Programmable));
rank = var->GetValInt();
value = pThis->GetCmdLine(rank);
value = dynamic_cast<CProgrammableObject*>(pThis)->GetCmdLine(rank);
result->SetValFloat(value);
return true;

View File

@ -31,6 +31,7 @@
#include "object/robotmain.h"
#include "object/interface/controllable_object.h"
#include "object/interface/transportable_object.h"
#include <cstring>
@ -1154,7 +1155,7 @@ void CMap::UpdateObject(CObject* pObj)
if ( m_totalFix >= m_totalMove ) return; // full table?
if ( !pObj->GetActive() ) return;
if ( !pObj->GetSelectable() ) return;
if ( pObj->Implements(ObjectInterfaceType::Controllable) && !dynamic_cast<CControllableObject*>(pObj)->GetSelectable() ) return;
if ( pObj->GetProxyActivate() ) return;
if (IsObjectBeingTransported(pObj)) return;
@ -1273,7 +1274,7 @@ void CMap::UpdateObject(CObject* pObj)
if ( color != MAPCOLOR_MOVE ) return;
}
if ( pObj->GetSelect() )
if ( pObj->Implements(ObjectInterfaceType::Controllable) && dynamic_cast<CControllableObject*>(pObj)->GetSelect() )
{
m_map[MAPMAXOBJECT-1].type = type;
m_map[MAPMAXOBJECT-1].object = pObj;

View File

@ -189,7 +189,7 @@ CObject* CTarget::DetectFriendObject(Math::Point pos)
{
if ( !obj->GetActive() ) continue;
if ( obj->GetProxyActivate() ) continue;
if ( obj->GetSelect() ) continue;
if ( obj->Implements(ObjectInterfaceType::Controllable) && dynamic_cast<CControllableObject*>(obj)->GetSelect() ) continue;
CObject* target = nullptr;
ObjectType type = obj->GetType();

View File

@ -27,6 +27,7 @@
#include "object/object.h"
#include "object/object_manager.h"
#include "object/interface/controllable_object.h"
#include "object/interface/programmable_object.h"
@ -138,7 +139,7 @@ bool CMainShort::CreateShortcuts()
for (CObject* pObj : CObjectManager::GetInstancePointer()->GetAllObjects())
{
if ( !pObj->GetActive() ) continue;
if ( !pObj->GetSelectable() ) continue;
if ( pObj->Implements(ObjectInterfaceType::Controllable) && !dynamic_cast<CControllableObject*>(pObj)->GetSelectable() ) continue;
if ( pObj->GetProxyActivate() ) continue;
int icon = GetShortcutIcon(pObj->GetType());
@ -234,7 +235,8 @@ bool CMainShort::UpdateShortcuts()
CControl* pc = m_interface->SearchControl(static_cast<EventType>(EVENT_OBJECT_SHORTCUT+i));
if ( pc != nullptr )
{
pc->SetState(STATE_CHECK, m_shortcuts[i]->GetSelect());
assert(m_shortcuts[i]->Implements(ObjectInterfaceType::Controllable));
pc->SetState(STATE_CHECK, dynamic_cast<CControllableObject*>(m_shortcuts[i])->GetSelect());
pc->SetState(STATE_RUN, m_shortcuts[i]->Implements(ObjectInterfaceType::Programmable) && dynamic_cast<CProgrammableObject*>(m_shortcuts[i])->IsProgram());
}
}