From 15c1c7ee034c53757cbc8f324afe80545cd23723 Mon Sep 17 00:00:00 2001 From: krzys-h Date: Mon, 10 Aug 2015 23:20:36 +0200 Subject: [PATCH] CMovableObject, CControllableObject --- src/graphics/engine/pyro.cpp | 15 +- src/object/auto/autobase.cpp | 21 +-- src/object/auto/autoegg.cpp | 24 ++- src/object/interface/controllable_object.h | 51 +++++++ src/object/interface/movable_object.h | 37 +++++ src/object/interface/programmable_object.h | 9 ++ src/object/object_interface_type.h | 2 + src/object/old_object.cpp | 79 +++++----- src/object/old_object.h | 18 +-- src/object/old_object_interface.cpp | 83 ----------- src/object/old_object_interface.h | 27 +--- src/object/robotmain.cpp | 165 ++++++++++++--------- src/script/scriptfunc.cpp | 12 +- src/ui/controls/map.cpp | 5 +- src/ui/controls/target.cpp | 2 +- src/ui/mainshort.cpp | 6 +- 16 files changed, 300 insertions(+), 256 deletions(-) create mode 100644 src/object/interface/controllable_object.h create mode 100644 src/object/interface/movable_object.h diff --git a/src/graphics/engine/pyro.cpp b/src/graphics/engine/pyro.cpp index fe91b935..ea352257 100644 --- a/src/graphics/engine/pyro.cpp +++ b/src/graphics/engine/pyro.cpp @@ -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(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(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(m_object)->GetSelect() ) { - m_object->SetSelect(false); // deselects the object + dynamic_cast(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(m_object)->GetSelect() ) { - m_object->SetSelect(false); // deselects the object + dynamic_cast(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 - diff --git a/src/object/auto/autobase.cpp b/src/object/auto/autobase.cpp index ba3c0786..ba42650f 100644 --- a/src/object/auto/autobase.cpp +++ b/src/object/auto/autobase.cpp @@ -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(pObj)->GetCameraType()); + m_camera->SetDist(dynamic_cast(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(pObj)->GetCameraType()); + m_camera->SetDist(dynamic_cast(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(pObj)->GetCameraType()); + m_camera->SetDist(dynamic_cast(pObj)->GetCameraDist()); } m_engine->SetFogStart(m_fogStart); diff --git a/src/object/auto/autoegg.cpp b/src/object/auto/autoegg.cpp index 6befc1f2..0a2e197d 100644 --- a/src/object/auto/autoegg.cpp +++ b/src/object/auto/autoegg.cpp @@ -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(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(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(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(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(alien)->SetActivity(true); // the insect is active + } } return ERR_STOP; diff --git a/src/object/interface/controllable_object.h b/src/object/interface/controllable_object.h new file mode 100644 index 00000000..aec2893c --- /dev/null +++ b/src/object/interface/controllable_object.h @@ -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(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; +}; diff --git a/src/object/interface/movable_object.h b/src/object/interface/movable_object.h new file mode 100644 index 00000000..1165c051 --- /dev/null +++ b/src/object/interface/movable_object.h @@ -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(ObjectInterfaceType::Movable)] = true; + } + virtual ~CMovableObject() + {} +}; diff --git a/src/object/interface/programmable_object.h b/src/object/interface/programmable_object.h index 623359c4..a2d0fceb 100644 --- a/src/object/interface/programmable_object.h +++ b/src/object/interface/programmable_object.h @@ -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; }; diff --git a/src/object/object_interface_type.h b/src/object/object_interface_type.h index 36190029..077eae2f 100644 --- a/src/object/object_interface_type.h +++ b/src/object/object_interface_type.h @@ -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) }; diff --git a/src/object/old_object.cpp b/src/object/old_object.cpp index 1877a2a5..090c6bcd 100644 --- a/src/object/old_object.cpp +++ b/src/object/old_object.cpp @@ -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(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(m_virusTime)); - line->AddParam("ignoreBuildCheck", MakeUnique(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(m_bActiveVirus)); + } + if ( Implements(ObjectInterfaceType::TaskExecutor) ) + { if ( m_type == OBJECT_MOBILErs ) { line->AddParam("bShieldActive", MakeUnique(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. diff --git a/src/object/old_object.h b/src/object/old_object.h index 7617bd15..2fec06e4 100644 --- a/src/object/old_object.h +++ b/src/object/old_object.h @@ -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; diff --git a/src/object/old_object_interface.cpp b/src/object/old_object_interface.cpp index 60011b36..c9f4e995 100644 --- a/src/object/old_object_interface.cpp +++ b/src/object/old_object_interface.cpp @@ -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) diff --git a/src/object/old_object_interface.h b/src/object/old_object_interface.h index b986fc8e..79720ca8 100644 --- a/src/object/old_object_interface.h +++ b/src/object/old_object_interface.h @@ -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(); diff --git a/src/object/robotmain.cpp b/src/object/robotmain.cpp index cf33f968..cc07260c 100644 --- a/src/object/robotmain.cpp +++ b/src/object/robotmain.cpp @@ -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(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(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(obj)->GetCameraType()); + m_camera->SetDist(dynamic_cast(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(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(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(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(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(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(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(obj)->GetCameraType()); } } @@ -4990,12 +4995,16 @@ void CRobotMain::IOWriteObject(CLevelParserLine* line, CObject* obj) } } - line->AddParam("trainer", MakeUnique(obj->GetTrainer())); line->AddParam("option", MakeUnique(obj->GetOption())); } - if (obj->GetSelect()) - line->AddParam("select", MakeUnique(true)); + if (obj->Implements(ObjectInterfaceType::Controllable)) + { + auto controllableObj = dynamic_cast(obj); + line->AddParam("trainer", MakeUnique(controllableObj->GetTrainer())); + if (controllableObj->GetSelect()) + line->AddParam("select", MakeUnique(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(m_base)->GetSelectable()) + return ERR_MISSION_NOTERM; + } + } if (m_winDelay == 0.0f) { diff --git a/src/script/scriptfunc.cpp b/src/script/scriptfunc.cpp index 2034e7ef..6eedaa09 100644 --- a/src/script/scriptfunc.cpp +++ b/src/script/scriptfunc.cpp @@ -1436,9 +1436,6 @@ bool CScriptFunctions::rBuild(CBotVar* var, CBotVar* result, int& exception, voi category = static_cast(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(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(pThis)->GetCmdLine(rank); result->SetValFloat(value); return true; diff --git a/src/ui/controls/map.cpp b/src/ui/controls/map.cpp index 968eab84..eabdd4fd 100644 --- a/src/ui/controls/map.cpp +++ b/src/ui/controls/map.cpp @@ -31,6 +31,7 @@ #include "object/robotmain.h" +#include "object/interface/controllable_object.h" #include "object/interface/transportable_object.h" #include @@ -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(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(pObj)->GetSelect() ) { m_map[MAPMAXOBJECT-1].type = type; m_map[MAPMAXOBJECT-1].object = pObj; diff --git a/src/ui/controls/target.cpp b/src/ui/controls/target.cpp index d9032d0a..1434e44a 100644 --- a/src/ui/controls/target.cpp +++ b/src/ui/controls/target.cpp @@ -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(obj)->GetSelect() ) continue; CObject* target = nullptr; ObjectType type = obj->GetType(); diff --git a/src/ui/mainshort.cpp b/src/ui/mainshort.cpp index c91a6889..09e16fdd 100644 --- a/src/ui/mainshort.cpp +++ b/src/ui/mainshort.cpp @@ -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(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(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(m_shortcuts[i])->GetSelect()); pc->SetState(STATE_RUN, m_shortcuts[i]->Implements(ObjectInterfaceType::Programmable) && dynamic_cast(m_shortcuts[i])->IsProgram()); } }