diff --git a/src/graphics/engine/camera.cpp b/src/graphics/engine/camera.cpp index 07b18364..ef6fb998 100644 --- a/src/graphics/engine/camera.cpp +++ b/src/graphics/engine/camera.cpp @@ -33,6 +33,7 @@ #include "object/object.h" #include "object/object_manager.h" #include "object/robotmain.h" +#include "object/interface/transportable_object.h" #include "physics/physics.h" @@ -64,7 +65,7 @@ CCamera::CCamera() m_main = CRobotMain::GetInstancePointer(); m_terrain = m_main->GetTerrain(); - + m_input = CInput::GetInstancePointer(); m_type = CAM_TYPE_FREE; @@ -245,8 +246,8 @@ void CCamera::SetType(CameraType type) { for (CObject* obj : CObjectManager::GetInstancePointer()->GetAllObjects()) { - if (obj->GetTransporter()) - continue; // battery or cargo? + if (IsObjectBeingTransported(obj)) + continue; SetTransparency(obj, 0.0f); // opaque object } @@ -890,7 +891,8 @@ bool CCamera::IsCollisionBack(Math::Vector &eye, Math::Vector lookat) for (CObject* obj : CObjectManager::GetInstancePointer()->GetAllObjects()) { - if (obj->GetTransporter()) continue; // battery or cargo? + if (IsObjectBeingTransported(obj)) + continue; SetTransparency(obj, 0.0f); // opaque object diff --git a/src/graphics/engine/lightning.cpp b/src/graphics/engine/lightning.cpp index 07042823..71147011 100644 --- a/src/graphics/engine/lightning.cpp +++ b/src/graphics/engine/lightning.cpp @@ -33,6 +33,7 @@ #include "object/object.h" #include "object/object_manager.h" #include "object/robotmain.h" +#include "object/interface/transportable_object.h" #include "object/auto/autopowercaptor.h" @@ -320,7 +321,8 @@ CObject* CLightning::SearchObject(Math::Vector pos) for (CObject* obj : CObjectManager::GetInstancePointer()->GetAllObjects()) { if (!obj->GetActive()) continue; // inactive object? - if (obj->GetTransporter() != nullptr) continue; // object transported? + + if (IsObjectBeingTransported(obj)) continue; ObjectType type = obj->GetType(); if ( type == OBJECT_BASE || diff --git a/src/graphics/engine/pyro.cpp b/src/graphics/engine/pyro.cpp index b4d2efa1..8d37358d 100644 --- a/src/graphics/engine/pyro.cpp +++ b/src/graphics/engine/pyro.cpp @@ -1374,14 +1374,18 @@ void CPyro::DeleteObject(bool primary, bool secondary) if (primary) { - CObject* transporter = m_object->GetTransporter(); - if ( transporter != nullptr ) // object carries? + if (m_object->Implements(ObjectInterfaceType::Transportable)) { - if (transporter->GetPower() == m_object) - transporter->SetPower(nullptr); + // TODO: this should be handled in the object's destructor + CObject* transporter = dynamic_cast(m_object)->GetTransporter(); + if (transporter != nullptr) + { + if (transporter->GetPower() == m_object) + transporter->SetPower(nullptr); - if (transporter->GetCargo() == m_object) - transporter->SetCargo(nullptr); + if (transporter->GetCargo() == m_object) + transporter->SetCargo(nullptr); + } } CObjectManager::GetInstancePointer()->DeleteObject(m_object); @@ -2226,7 +2230,7 @@ CObject* CPyro::FallSearchBeeExplo() oType != OBJECT_POWER && oType != OBJECT_ATOMIC ) continue; - if ( obj->GetTransporter() != nullptr ) continue; // object transported? + if (IsObjectBeingTransported(obj)) continue; Math::Vector oPos = obj->GetPosition(0); diff --git a/src/object/auto/autobase.cpp b/src/object/auto/autobase.cpp index 33c8ed68..90b40aaa 100644 --- a/src/object/auto/autobase.cpp +++ b/src/object/auto/autobase.cpp @@ -21,6 +21,7 @@ #include #include "object/auto/autobase.h" +#include "object/interface/transportable_object.h" #include "graphics/engine/terrain.h" #include "graphics/engine/cloud.h" @@ -1244,7 +1245,7 @@ void CAutoBase::FreezeCargo(bool freeze) obj->SetSpaceshipCargo(false); if ( obj == m_object ) continue; // yourself? - if ( obj->GetTransporter() != nullptr ) continue; // transport object? + if (IsObjectBeingTransported(obj)) continue; Math::Vector oPos = obj->GetPosition(0); float dist = Math::DistanceProjected(m_pos, oPos); diff --git a/src/object/auto/autoconvert.cpp b/src/object/auto/autoconvert.cpp index 82c9ac72..d45ddbbb 100644 --- a/src/object/auto/autoconvert.cpp +++ b/src/object/auto/autoconvert.cpp @@ -25,7 +25,7 @@ #include "object/object_manager.h" #include "object/level/parserline.h" #include "object/level/parserparam.h" - +#include "object/interface/transportable_object.h" #include "ui/interface.h" #include "ui/window.h" @@ -400,7 +400,7 @@ CObject* CAutoConvert::SearchStone(ObjectType type) { ObjectType oType = obj->GetType(); if ( oType != type ) continue; - if ( obj->GetTransporter() != nullptr ) continue; + if (IsObjectBeingTransported(obj)) continue; Math::Vector oPos = obj->GetPosition(0); float dist = Math::Distance(oPos, cPos); diff --git a/src/object/auto/autoegg.cpp b/src/object/auto/autoegg.cpp index 79fbf34c..76fe0e74 100644 --- a/src/object/auto/autoegg.cpp +++ b/src/object/auto/autoegg.cpp @@ -26,6 +26,7 @@ #include "object/brain.h" #include "object/object_manager.h" +#include "object/interface/transportable_object.h" #include "object/level/parserline.h" #include "object/level/parserparam.h" @@ -275,7 +276,7 @@ CObject* CAutoEgg::SearchAlien() CObject* best = nullptr; for (CObject* obj : CObjectManager::GetInstancePointer()->GetAllObjects()) { - if ( obj->GetTransporter() != nullptr ) continue; + if (IsObjectBeingTransported(obj)) continue; ObjectType type = obj->GetType(); if ( type != OBJECT_ANT && diff --git a/src/object/auto/autofactory.cpp b/src/object/auto/autofactory.cpp index c39df28a..507ad8c7 100644 --- a/src/object/auto/autofactory.cpp +++ b/src/object/auto/autofactory.cpp @@ -29,6 +29,7 @@ #include "object/robotmain.h" #include "object/level/parserline.h" #include "object/level/parserparam.h" +#include "object/interface/transportable_object.h" #include "physics/physics.h" @@ -550,7 +551,7 @@ CObject* CAutoFactory::SearchCargo() { ObjectType type = obj->GetType(); if ( type != OBJECT_METAL ) continue; - if ( obj->GetTransporter() != nullptr ) continue; + if (IsObjectBeingTransported(obj)) continue; Math::Vector oPos = obj->GetPosition(0); float dist = Math::Distance(oPos, m_cargoPos); @@ -674,7 +675,7 @@ CObject* CAutoFactory::SearchVehicle() ObjectType type = obj->GetType(); if ( type != m_type ) continue; - if ( obj->GetTransporter() != nullptr ) continue; + if (IsObjectBeingTransported(obj)) continue; Math::Vector oPos = obj->GetPosition(0); float dist = Math::Distance(oPos, m_cargoPos); diff --git a/src/object/auto/autonuclearplant.cpp b/src/object/auto/autonuclearplant.cpp index a716dfc9..563ec817 100644 --- a/src/object/auto/autonuclearplant.cpp +++ b/src/object/auto/autonuclearplant.cpp @@ -25,7 +25,7 @@ #include "object/object_manager.h" #include "object/level/parserline.h" #include "object/level/parserparam.h" - +#include "object/interface/transportable_object.h" #include "ui/interface.h" #include "ui/window.h" @@ -387,7 +387,7 @@ void CAutoNuclearPlant::CreatePower() float powerLevel = 1.0f; CObject* power = CObjectManager::GetInstancePointer()->CreateObject(pos, angle, OBJECT_ATOMIC, powerLevel); - power->SetTransporter(m_object); + dynamic_cast(power)->SetTransporter(m_object); power->SetPosition(0, Math::Vector(22.0f, 3.0f, 0.0f)); m_object->SetPower(power); } diff --git a/src/object/auto/autopowercaptor.cpp b/src/object/auto/autopowercaptor.cpp index a9fed670..4326d5e9 100644 --- a/src/object/auto/autopowercaptor.cpp +++ b/src/object/auto/autopowercaptor.cpp @@ -26,7 +26,7 @@ #include "object/object_manager.h" #include "object/level/parserline.h" #include "object/level/parserparam.h" - +#include "object/interface/transportable_object.h" #include "ui/interface.h" #include "ui/window.h" @@ -250,7 +250,7 @@ void CAutoPowerCaptor::ChargeObject(float rTime) float dist = Math::Distance(oPos, sPos); if ( dist > 20.0f ) continue; - if ( obj->GetTransporter() == nullptr && obj->GetType() == OBJECT_POWER ) + if (! IsObjectBeingTransported(obj) && obj->GetType() == OBJECT_POWER ) { float energy = obj->GetEnergy(); energy += rTime/2.0f; diff --git a/src/object/auto/autopowerplant.cpp b/src/object/auto/autopowerplant.cpp index a42a5ead..9a7404a2 100644 --- a/src/object/auto/autopowerplant.cpp +++ b/src/object/auto/autopowerplant.cpp @@ -25,10 +25,10 @@ #include "math/geometry.h" #include "object/object_manager.h" +#include "object/interface/transportable_object.h" #include "object/level/parserline.h" #include "object/level/parserparam.h" - #include "ui/interface.h" #include "ui/gauge.h" #include "ui/window.h" @@ -314,11 +314,11 @@ bool CAutoPowerPlant::EventProcess(const Event &event) } cargo = SearchPower(); - if ( cargo != 0 ) + if ( cargo != nullptr ) { cargo->SetZoom(0, 1.0f); cargo->SetLock(false); // usable battery - cargo->SetTransporter(m_object); + dynamic_cast(cargo)->SetTransporter(m_object); cargo->SetPosition(0, Math::Vector(0.0f, 3.0f, 0.0f)); m_object->SetPower(cargo); diff --git a/src/object/auto/autovault.cpp b/src/object/auto/autovault.cpp index f9bdd38c..50b35cd6 100644 --- a/src/object/auto/autovault.cpp +++ b/src/object/auto/autovault.cpp @@ -26,7 +26,7 @@ #include "object/robotmain.h" #include "object/level/parserline.h" #include "object/level/parserparam.h" - +#include "object/interface/transportable_object.h" #include "ui/interface.h" #include "ui/window.h" @@ -395,7 +395,7 @@ int CAutoVault::CountKeys() for (CObject* obj : CObjectManager::GetInstancePointer()->GetAllObjects()) { - if ( obj->GetTransporter() != nullptr ) continue; + if (IsObjectBeingTransported(obj)) continue; ObjectType oType = obj->GetType(); if ( oType != OBJECT_KEYa && @@ -467,7 +467,7 @@ void CAutoVault::LockKeys() for (CObject* obj : CObjectManager::GetInstancePointer()->GetAllObjects()) { ObjectType oType = obj->GetType(); - if ( obj->GetTransporter() != nullptr ) continue; + if (IsObjectBeingTransported(obj)) continue; if ( oType != OBJECT_KEYa && oType != OBJECT_KEYb && @@ -491,7 +491,7 @@ void CAutoVault::DownKeys(float progress) for (CObject* obj : CObjectManager::GetInstancePointer()->GetAllObjects()) { ObjectType oType = obj->GetType(); - if ( obj->GetTransporter() != nullptr ) continue; + if (IsObjectBeingTransported(obj)) continue; if ( oType != OBJECT_KEYa && oType != OBJECT_KEYb && @@ -520,7 +520,7 @@ void CAutoVault::DeleteKeys() for (CObject* obj : CObjectManager::GetInstancePointer()->GetAllObjects()) { ObjectType oType = obj->GetType(); - if ( obj->GetTransporter() != nullptr ) continue; + if (IsObjectBeingTransported(obj)) continue; if ( oType != OBJECT_KEYa && oType != OBJECT_KEYb && @@ -548,7 +548,7 @@ CObject* CAutoVault::SearchVehicle() for (CObject* obj : CObjectManager::GetInstancePointer()->GetAllObjects()) { if ( obj == m_object ) continue; - if ( obj->GetTransporter() != nullptr ) continue; + if (IsObjectBeingTransported(obj)) continue; Math::Vector oPos = obj->GetPosition(0); float dist = Math::DistanceProjected(oPos, cPos); diff --git a/src/object/interactive_object.h b/src/object/interface/interactive_object.h similarity index 100% rename from src/object/interactive_object.h rename to src/object/interface/interactive_object.h diff --git a/src/object/interface/transportable_object.h b/src/object/interface/transportable_object.h new file mode 100644 index 00000000..9f64b745 --- /dev/null +++ b/src/object/interface/transportable_object.h @@ -0,0 +1,55 @@ +/* + * 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.h" +#include "object/object_interface_type.h" + +struct Event; + +/** + * \class CTransportableObject + * \brief Interface for transportable objects + */ +class CTransportableObject +{ +public: + explicit CTransportableObject(ObjectInterfaceTypes& types) + { + types[static_cast(ObjectInterfaceType::Transportable)] = true; + } + virtual ~CTransportableObject() + {} + + virtual void SetTransporter(CObject* transporter) = 0; + virtual CObject* GetTransporter() = 0; + virtual void SetTransporterPart(int part) = 0; + + inline bool IsBeingTransported() + { + return GetTransporter() != nullptr; + } +}; + +inline bool IsObjectBeingTransported(CObject* obj) +{ + return obj->Implements(ObjectInterfaceType::Transportable) && + dynamic_cast(obj)->IsBeingTransported(); +} diff --git a/src/object/motion/motionvehicle.cpp b/src/object/motion/motionvehicle.cpp index e5f5a600..4d3de6bb 100644 --- a/src/object/motion/motionvehicle.cpp +++ b/src/object/motion/motionvehicle.cpp @@ -30,6 +30,7 @@ #include "object/brain.h" #include "object/object_manager.h" +#include "object/interface/transportable_object.h" #include "physics/physics.h" @@ -939,7 +940,7 @@ void CMotionVehicle::Create(Math::Vector pos, float angle, ObjectType type, powerCell->SetPosition(0, powerCellPos); powerCell->SetAngle(0, Math::Vector(0.0f, powerCellAngle, 0.0f)); - powerCell->SetTransporter(m_object); + dynamic_cast(powerCell)->SetTransporter(m_object); m_object->SetPower(powerCell); } diff --git a/src/object/object_interface_type.h b/src/object/object_interface_type.h index d80a2a42..e0916fe1 100644 --- a/src/object/object_interface_type.h +++ b/src/object/object_interface_type.h @@ -33,6 +33,7 @@ enum class ObjectInterfaceType { Interactive, //!< interactive objects can process events from event loop + Transportable, //!< objects that can be carried by robots or astronaut Max //!< maximum value (for getting number of items in enum) }; diff --git a/src/object/object_manager.cpp b/src/object/object_manager.cpp index ae7bba19..b290a87b 100644 --- a/src/object/object_manager.cpp +++ b/src/object/object_manager.cpp @@ -240,7 +240,7 @@ CObject* CObjectManager::Radar(CObject* pThis, Math::Vector thisPosition, float pObj = it->second.get(); if ( pObj == pThis ) continue; // pThis may be nullptr but it doesn't matter - if ( pObj->GetTransporter() != 0 ) continue; // object transported? + if (IsObjectBeingTransported(pObj)) continue; if ( !pObj->GetActive() ) continue; if ( pObj->GetProxyActivate() ) continue; diff --git a/src/object/old_object.cpp b/src/object/old_object.cpp index 0b1abf3d..a5f5a626 100644 --- a/src/object/old_object.cpp +++ b/src/object/old_object.cpp @@ -100,7 +100,16 @@ void uObject(CBotVar* botThis, void* user) // Updates the position of the object. pVar = pVar->GetNext(); // "position" - if ( object->GetTransporter() == 0 ) + if (IsObjectBeingTransported(object)) + { + pSub = pVar->GetItemList(); // "x" + pSub->SetInit(CBotVar::InitType::IS_NAN); + pSub = pSub->GetNext(); // "y" + pSub->SetInit(CBotVar::InitType::IS_NAN); + pSub = pSub->GetNext(); // "z" + pSub->SetInit(CBotVar::InitType::IS_NAN); + } + else { pos = object->GetPosition(0); float waterLevel = Gfx::CEngine::GetInstancePointer()->GetWater()->GetLevel(); @@ -112,15 +121,6 @@ void uObject(CBotVar* botThis, void* user) pSub = pSub->GetNext(); // "z" pSub->SetValFloat(pos.y/g_unit); } - else // object transported? - { - pSub = pVar->GetItemList(); // "x" - pSub->SetInit(CBotVar::InitType::IS_NAN); - pSub = pSub->GetNext(); // "y" - pSub->SetInit(CBotVar::InitType::IS_NAN); - pSub = pSub->GetNext(); // "z" - pSub->SetInit(CBotVar::InitType::IS_NAN); - } // Updates the angle. pos = object->GetAngle(0); @@ -188,6 +188,7 @@ void uObject(CBotVar* botThis, void* user) COldObject::COldObject(int id) : CObject(id, OBJECT_NULL) , CInteractiveObject(m_implementedInterfaces) + , CTransportableObject(m_implementedInterfaces) { m_sound = CApplication::GetInstancePointer()->GetSound(); m_engine = Gfx::CEngine::GetInstancePointer(); diff --git a/src/object/old_object.h b/src/object/old_object.h index 1b0b29f0..a3495094 100644 --- a/src/object/old_object.h +++ b/src/object/old_object.h @@ -24,9 +24,11 @@ #pragma once -#include "object/interactive_object.h" #include "object/object.h" +#include "object/interface/interactive_object.h" +#include "object/interface/transportable_object.h" + // The father of all parts must always be the part number zero! const int OBJECTMAXPART = 40; const int OBJECTMAXDESELLIST = 10; @@ -50,7 +52,9 @@ struct ObjectPart }; -class COldObject : public CObject, public CInteractiveObject +class COldObject : public CObject, + public CInteractiveObject, + public CTransportableObject { friend class CObjectFactory; friend class CObjectManager; diff --git a/src/object/old_object_interface.h b/src/object/old_object_interface.h index 9cec3418..96e52c4b 100644 --- a/src/object/old_object_interface.h +++ b/src/object/old_object_interface.h @@ -161,9 +161,6 @@ public: virtual CObject* GetPower() = 0; virtual void SetCargo(CObject* cargo) = 0; virtual CObject* GetCargo() = 0; - virtual void SetTransporter(CObject* transporter) = 0; - virtual CObject* GetTransporter() = 0; - virtual void SetTransporterPart(int part) = 0; virtual void SetCmdLine(unsigned int rank, float value) = 0; virtual float GetCmdLine(unsigned int rank) = 0; diff --git a/src/object/robotmain.cpp b/src/object/robotmain.cpp index 01971670..c82585ef 100644 --- a/src/object/robotmain.cpp +++ b/src/object/robotmain.cpp @@ -2004,7 +2004,11 @@ CObject* CRobotMain::DetectObject(Math::Point pos) for (CObject* obj : m_objMan->GetAllObjects()) { if (!obj->GetActive()) continue; - CObject* transporter = obj->GetTransporter(); + + CObject* transporter = nullptr; + if (obj->Implements(ObjectInterfaceType::Transportable)) + transporter = dynamic_cast(obj)->GetTransporter(); + if (transporter != nullptr && !transporter->GetActive()) continue; if (obj->GetProxyActivate()) continue; @@ -2121,7 +2125,7 @@ CObject* CRobotMain::DetectObject(Math::Point pos) } else if (type == OBJECT_POWER || type == OBJECT_ATOMIC) { - target = obj->GetTransporter(); // battery connected + target = dynamic_cast(obj)->GetTransporter(); // battery connected if (!target) target = obj; // standalone battery } @@ -2629,7 +2633,7 @@ bool CRobotMain::EventFrame(const Event &event) if (pm != nullptr) pm->UpdateObject(obj); - if (obj->GetTransporter() != nullptr) + if (IsObjectBeingTransported(obj)) continue; if (obj->GetType() == OBJECT_TOTO) @@ -2640,7 +2644,7 @@ bool CRobotMain::EventFrame(const Event &event) // Advances all objects transported by robots. for (CObject* obj : m_objMan->GetAllObjects()) { - if (obj->GetTransporter() == nullptr) + if (! IsObjectBeingTransported(obj)) continue; if (obj->Implements(ObjectInterfaceType::Interactive)) @@ -4176,7 +4180,8 @@ float CRobotMain::SearchNearestObject(Math::Vector center, CObject *exclu) for (CObject* obj : m_objMan->GetAllObjects()) { if (!obj->GetActive()) continue; // inactive? - if (obj->GetTransporter() != nullptr) continue; // object carries? + if (IsObjectBeingTransported(obj)) continue; + if (obj == exclu) continue; ObjectType type = obj->GetType(); @@ -4324,7 +4329,8 @@ void CRobotMain::ShowDropZone(CObject* metal, CObject* transporter) for (CObject* obj : m_objMan->GetAllObjects()) { if (!obj->GetActive()) continue; // inactive? - if (obj->GetTransporter() != nullptr) continue; // object carried? + if (IsObjectBeingTransported(obj)) continue; + if (obj == metal) continue; if (obj == transporter) continue; @@ -4524,7 +4530,7 @@ void CRobotMain::CompileScript(bool soluce) nbError = 0; for (CObject* obj : m_objMan->GetAllObjects()) { - if (obj->GetTransporter() != nullptr) continue; + if (IsObjectBeingTransported(obj)) continue; CBrain* brain = obj->GetBrain(); if (brain == nullptr) continue; @@ -4552,7 +4558,7 @@ void CRobotMain::CompileScript(bool soluce) { for (CObject* obj : m_objMan->GetAllObjects()) { - if (obj->GetTransporter() != 0) continue; + if (IsObjectBeingTransported(obj)) continue; CBrain* brain = obj->GetBrain(); if (brain == 0) continue; @@ -4568,7 +4574,7 @@ void CRobotMain::CompileScript(bool soluce) // Start all programs according to the command "run". for (CObject* obj : m_objMan->GetAllObjects()) { - if (obj->GetTransporter() != nullptr) continue; + if (IsObjectBeingTransported(obj)) continue; CBrain* brain = obj->GetBrain(); if (brain == nullptr) continue; @@ -4933,7 +4939,7 @@ bool CRobotMain::IOWriteScene(const char *filename, const char *filecbot, char * { if (obj->GetType() == OBJECT_TOTO) continue; if (obj->GetType() == OBJECT_FIX) continue; - if (obj->GetTransporter() != nullptr) continue; + if (IsObjectBeingTransported(obj)) continue; if (obj->GetBurn()) continue; if (obj->GetDead()) continue; if (obj->IsExploding()) continue; @@ -4986,7 +4992,8 @@ bool CRobotMain::IOWriteScene(const char *filename, const char *filecbot, char * { if (obj->GetType() == OBJECT_TOTO) continue; if (obj->GetType() == OBJECT_FIX) continue; - if (obj->GetTransporter() != nullptr) continue; + if (IsObjectBeingTransported(obj)) continue; + if (obj->GetBurn()) continue; if (obj->GetDead()) continue; @@ -5131,7 +5138,7 @@ CObject* CRobotMain::IOReadScene(const char *filename, const char *filecbot) if (power != nullptr) { obj->SetPower(power); - power->SetTransporter(obj); + dynamic_cast(power)->SetTransporter(obj); } cargo = nullptr; @@ -5148,7 +5155,7 @@ CObject* CRobotMain::IOReadScene(const char *filename, const char *filecbot) nbError = 0; for (CObject* obj : m_objMan->GetAllObjects()) { - if (obj->GetTransporter() != nullptr) continue; + if (IsObjectBeingTransported(obj)) continue; objRank = obj->GetDefRank(); if (objRank == -1) continue; @@ -5161,7 +5168,7 @@ CObject* CRobotMain::IOReadScene(const char *filename, const char *filecbot) // Starts scripts for (CObject* obj : m_objMan->GetAllObjects()) { - if (obj->GetTransporter() != nullptr) continue; + if (IsObjectBeingTransported(obj)) continue; if (obj->GetDefRank() == -1) continue; CBrain* brain = obj->GetBrain(); @@ -5190,7 +5197,7 @@ CObject* CRobotMain::IOReadScene(const char *filename, const char *filecbot) { if (obj->GetType() == OBJECT_TOTO) continue; if (obj->GetType() == OBJECT_FIX) continue; - if (obj->GetTransporter() != nullptr) continue; + if (IsObjectBeingTransported(obj)) continue; if (obj->GetBurn()) continue; if (obj->GetDead()) continue; diff --git a/src/object/scene_conditions.cpp b/src/object/scene_conditions.cpp index fcc5c215..59234b34 100644 --- a/src/object/scene_conditions.cpp +++ b/src/object/scene_conditions.cpp @@ -25,6 +25,7 @@ #include "object/level/parserline.h" #include "object/object_manager.h" #include "object/object.h" +#include "object/interface/transportable_object.h" void CSceneCondition::Read(CLevelParserLine* line) { @@ -60,7 +61,7 @@ int CSceneCondition::CountObjects() if (!this->countTransported) { - if (obj->GetTransporter() != nullptr) continue; + if (IsObjectBeingTransported(obj)) continue; } // TODO: I really hate those fragments that hardcode subcategories into one in random places in code, we should refactor that at some point @@ -110,10 +111,10 @@ int CSceneCondition::CountObjects() } if (energyLevel < this->powermin || energyLevel > this->powermax) continue; - if (obj->GetTransporter() == 0) - oPos = obj->GetPosition(0); + if (IsObjectBeingTransported(obj)) + oPos = dynamic_cast(obj)->GetTransporter()->GetPosition(0); else - oPos = obj->GetTransporter()->GetPosition(0); + oPos = obj->GetPosition(0); oPos.y = 0.0f; diff --git a/src/object/task/taskbuild.cpp b/src/object/task/taskbuild.cpp index 91d05d09..99e93a10 100644 --- a/src/object/task/taskbuild.cpp +++ b/src/object/task/taskbuild.cpp @@ -32,6 +32,7 @@ #include "object/motion/motionhuman.h" #include "object/object_manager.h" #include "object/robotmain.h" +#include "object/interface/transportable_object.h" #include "physics/physics.h" @@ -616,7 +617,7 @@ Error CTaskBuild::FlatFloor() for (CObject* pObj : CObjectManager::GetInstancePointer()->GetAllObjects()) { if ( !pObj->GetActive() ) continue; // inactive? - if ( pObj->GetTransporter() != 0 ) continue; // object transported? + if (IsObjectBeingTransported(pObj)) continue; if ( pObj == m_metal ) continue; if ( pObj == m_object ) continue; @@ -663,7 +664,7 @@ Error CTaskBuild::FlatFloor() for (CObject* pObj : CObjectManager::GetInstancePointer()->GetAllObjects()) { if ( !pObj->GetActive() ) continue; // inactive? - if ( pObj->GetTransporter() != 0 ) continue; // object transported? + if (IsObjectBeingTransported(pObj)) continue; if ( pObj == m_metal ) continue; if ( pObj == m_object ) continue; @@ -733,7 +734,7 @@ CObject* CTaskBuild::SearchMetalObject(float &angle, float dMin, float dMax, for (CObject* pObj : CObjectManager::GetInstancePointer()->GetAllObjects()) { if ( !pObj->GetActive() ) continue; // objet inactive? - if ( pObj->GetTransporter() != 0 ) continue; // object transported? + if (IsObjectBeingTransported(pObj)) continue; type = pObj->GetType(); if ( type != OBJECT_METAL ) continue; diff --git a/src/object/task/taskgoto.cpp b/src/object/task/taskgoto.cpp index 03d46a8f..1581342c 100644 --- a/src/object/task/taskgoto.cpp +++ b/src/object/task/taskgoto.cpp @@ -30,6 +30,7 @@ #include "math/geometry.h" #include "object/object_manager.h" +#include "object/interface/transportable_object.h" #include "physics/physics.h" @@ -1148,7 +1149,7 @@ bool CTaskGoto::AdjustBuilding(Math::Vector &pos, float margin, float &distance) for (CObject* obj : CObjectManager::GetInstancePointer()->GetAllObjects()) { if ( !obj->GetActive() ) continue; - if ( obj->GetTransporter() != nullptr ) continue; // object transported? + if (IsObjectBeingTransported(obj)) continue; Math::Vector oPos; float suppl = 0.0f; @@ -1305,7 +1306,7 @@ bool CTaskGoto::LeakSearch(Math::Vector &pos, float &delay) { if ( obj == m_object ) continue; if ( !obj->GetActive() ) continue; - if ( obj->GetTransporter() != nullptr ) continue; // object transported? + if (IsObjectBeingTransported(obj)) continue; for (const auto& objCrashSphere : obj->GetAllCrashSpheres()) { @@ -1360,7 +1361,7 @@ void CTaskGoto::ComputeRepulse(Math::Point &dir) if ( pObj == 0 ) break; if ( pObj == m_object ) continue; - if ( pObj->GetTransporter() != 0 ) continue; + if (IsObjectBeingTransported(pObj)) continue; oPos = pObj->GetPosition(0); dist = Math::Distance(oPos, m_goalObject); @@ -1480,7 +1481,7 @@ void CTaskGoto::ComputeRepulse(Math::Point &dir) for (CObject* pObj : CObjectManager::GetInstancePointer()->GetAllObjects()) { if ( pObj == m_object ) continue; - if ( pObj->GetTransporter() != 0 ) continue; + if (IsObjectBeingTransported(pObj)) continue; oType = pObj->GetType(); @@ -1567,7 +1568,7 @@ void CTaskGoto::ComputeFlyingRepulse(float &dir) for (CObject* pObj : CObjectManager::GetInstancePointer()->GetAllObjects()) { if ( pObj == m_object ) continue; - if ( pObj->GetTransporter() != nullptr ) continue; + if (IsObjectBeingTransported(pObj)) continue; ObjectType oType = pObj->GetType(); @@ -1878,7 +1879,7 @@ void CTaskGoto::BitmapObject() if ( pObj == m_object ) continue; if ( pObj == m_bmCargoObject ) continue; - if ( pObj->GetTransporter() != 0 ) continue; + if (IsObjectBeingTransported(pObj)) continue; float h = m_terrain->GetFloorLevel(pObj->GetPosition(0), false); if ( m_physics->GetType() == TYPE_FLYING && m_altitude > 0.0f ) diff --git a/src/object/task/taskmanip.cpp b/src/object/task/taskmanip.cpp index 281064e8..aa9eb200 100644 --- a/src/object/task/taskmanip.cpp +++ b/src/object/task/taskmanip.cpp @@ -27,6 +27,7 @@ #include "object/object_manager.h" #include "object/robotmain.h" +#include "object/interface/transportable_object.h" #include "physics/physics.h" @@ -323,16 +324,17 @@ Error CTaskManip::Start(TaskManipOrder order, TaskManipArm arm) other = SearchTakeUnderObject(m_targetPos, MARGIN_BEE); if ( other == 0 ) return ERR_MANIP_NIL; + m_object->SetCargo(other); // takes the ball - other->SetTransporter(m_object); - other->SetTransporterPart(0); // taken with the base + dynamic_cast(other)->SetTransporter(m_object); + dynamic_cast(other)->SetTransporterPart(0); // taken with the base other->SetPosition(0, Math::Vector(0.0f, -3.0f, 0.0f)); } else { other = m_object->GetCargo(); // other = ball m_object->SetCargo(0); // lick the ball - other->SetTransporter(0); + dynamic_cast(other)->SetTransporter(0); pos = m_object->GetPosition(0); pos.y -= 3.0f; other->SetPosition(0, pos); @@ -749,7 +751,7 @@ CObject* CTaskManip::SearchTakeUnderObject(Math::Vector &pos, float dLimit) type != OBJECT_KEYd && type != OBJECT_TNT ) continue; - if ( pObj->GetTransporter() != 0 ) continue; // object transported? + if (IsObjectBeingTransported(pObj)) continue; if ( pObj->GetLock() ) continue; if ( pObj->GetZoomY(0) != 1.0f ) continue; @@ -821,7 +823,7 @@ CObject* CTaskManip::SearchTakeFrontObject(bool bAdvance, Math::Vector &pos, type != OBJECT_SCRAP4 && type != OBJECT_SCRAP5 ) continue; - if ( pObj->GetTransporter() != 0 ) continue; // object transported? + if (IsObjectBeingTransported(pObj)) continue; if ( pObj->GetLock() ) continue; if ( pObj->GetZoomY(0) != 1.0f ) continue; @@ -908,7 +910,7 @@ CObject* CTaskManip::SearchTakeBackObject(bool bAdvance, Math::Vector &pos, type != OBJECT_SCRAP4 && type != OBJECT_SCRAP5 ) continue; - if ( pObj->GetTransporter() != 0 ) continue; // object transported? + if (IsObjectBeingTransported(pObj)) continue; if ( pObj->GetLock() ) continue; if ( pObj->GetZoomY(0) != 1.0f ) continue; @@ -1096,8 +1098,8 @@ bool CTaskManip::TransporterTakeObject() if ( m_object->GetType() == OBJECT_HUMAN || m_object->GetType() == OBJECT_TECH ) { - cargo->SetTransporter(m_object); - cargo->SetTransporterPart(4); // takes with the hand + dynamic_cast(cargo)->SetTransporter(m_object); + dynamic_cast(cargo)->SetTransporterPart(4); // takes with the hand cargo->SetPosition(0, Math::Vector(1.7f, -0.5f, 1.1f)); cargo->SetAngleY(0, 0.1f); @@ -1106,8 +1108,8 @@ bool CTaskManip::TransporterTakeObject() } else if ( m_bSubm ) { - cargo->SetTransporter(m_object); - cargo->SetTransporterPart(2); // takes with the right claw + dynamic_cast(cargo)->SetTransporter(m_object); + dynamic_cast(cargo)->SetTransporterPart(2); // takes with the right claw pos = Math::Vector(1.1f, -1.0f, 1.0f); // relative cargo->SetPosition(0, pos); @@ -1117,8 +1119,8 @@ bool CTaskManip::TransporterTakeObject() } else { - cargo->SetTransporter(m_object); - cargo->SetTransporterPart(3); // takes with the hand + dynamic_cast(cargo)->SetTransporter(m_object); + dynamic_cast(cargo)->SetTransporterPart(3); // takes with the hand pos = Math::Vector(4.7f, 0.0f, 0.0f); // relative to the hand (lem4) cargo->SetPosition(0, pos); @@ -1138,8 +1140,8 @@ bool CTaskManip::TransporterTakeObject() if ( m_bSubm ) { - cargo->SetTransporter(m_object); - cargo->SetTransporterPart(2); // takes with the right claw + dynamic_cast(cargo)->SetTransporter(m_object); + dynamic_cast(cargo)->SetTransporterPart(2); // takes with the right claw pos = Math::Vector(1.1f, -1.0f, 1.0f); // relative cargo->SetPosition(0, pos); @@ -1149,8 +1151,8 @@ bool CTaskManip::TransporterTakeObject() } else { - cargo->SetTransporter(m_object); - cargo->SetTransporterPart(3); // takes with the hand + dynamic_cast(cargo)->SetTransporter(m_object); + dynamic_cast(cargo)->SetTransporterPart(3); // takes with the hand pos = Math::Vector(4.7f, 0.0f, 0.0f); // relative to the hand (lem4) cargo->SetPosition(0, pos); @@ -1168,8 +1170,8 @@ bool CTaskManip::TransporterTakeObject() if ( cargo == 0 ) return false; // nothing to take? m_cargoType = cargo->GetType(); - cargo->SetTransporter(m_object); - cargo->SetTransporterPart(3); // takes with the hand + dynamic_cast(cargo)->SetTransporter(m_object); + dynamic_cast(cargo)->SetTransporterPart(3); // takes with the hand pos = Math::Vector(4.7f, 0.0f, 0.0f); // relative to the hand (lem4) cargo->SetPosition(0, pos); @@ -1191,7 +1193,7 @@ bool CTaskManip::TransporterTakeObject() cargo->SetAngleX(0, 0.0f); cargo->SetAngleZ(0, Math::PI/2.0f); cargo->SetAngleY(0, 0.0f); - cargo->SetTransporterPart(3); // takes with the hand + dynamic_cast(cargo)->SetTransporterPart(3); // takes with the hand m_object->SetPower(0); m_object->SetCargo(cargo); // takes @@ -1207,8 +1209,8 @@ bool CTaskManip::TransporterTakeObject() m_cargoType = cargo->GetType(); other->SetPower(0); - cargo->SetTransporter(m_object); - cargo->SetTransporterPart(3); // takes with the hand + dynamic_cast(cargo)->SetTransporter(m_object); + dynamic_cast(cargo)->SetTransporterPart(3); // takes with the hand pos = Math::Vector(4.7f, 0.0f, 0.0f); // relative to the hand (lem4) cargo->SetPosition(0, pos); @@ -1248,7 +1250,7 @@ bool CTaskManip::TransporterDeposeObject() cargo->SetAngleZ(0, 0.0f); cargo->FloorAdjust(); // plate well on the ground - cargo->SetTransporter(0); + dynamic_cast(cargo)->SetTransporter(0); m_object->SetCargo(0); // deposit } @@ -1266,7 +1268,7 @@ bool CTaskManip::TransporterDeposeObject() cargo->SetAngleX(0, 0.0f); cargo->SetAngleZ(0, 0.0f); - cargo->SetTransporter(0); + dynamic_cast(cargo)->SetTransporter(0); m_object->SetCargo(0); // deposit } @@ -1278,8 +1280,8 @@ bool CTaskManip::TransporterDeposeObject() if ( m_object->GetPower() != 0 ) return false; - cargo->SetTransporter(m_object); - cargo->SetTransporterPart(0); // carried by the base + dynamic_cast(cargo)->SetTransporter(m_object); + dynamic_cast(cargo)->SetTransporterPart(0); // carried by the base character = m_object->GetCharacter(); cargo->SetPosition(0, character->posPower); @@ -1304,14 +1306,14 @@ bool CTaskManip::TransporterDeposeObject() m_cargoType = cargo->GetType(); other->SetPower(cargo); - cargo->SetTransporter(other); + dynamic_cast(cargo)->SetTransporter(other); character = other->GetCharacter(); cargo->SetPosition(0, character->posPower); cargo->SetAngleY(0, 0.0f); cargo->SetAngleX(0, 0.0f); cargo->SetAngleZ(0, 0.0f); - cargo->SetTransporterPart(0); // carried by the base + dynamic_cast(cargo)->SetTransporterPart(0); // carried by the base m_object->SetCargo(0); // deposit } @@ -1330,7 +1332,7 @@ bool CTaskManip::IsFreeDeposeObject(Math::Vector pos) { if ( obj == m_object ) continue; if ( !obj->GetActive() ) continue; // inactive? - if ( obj->GetTransporter() != nullptr ) continue; // object transported? + if (IsObjectBeingTransported(obj)) continue; for (const auto& crashSphere : obj->GetAllCrashSpheres()) { diff --git a/src/object/task/taskreset.cpp b/src/object/task/taskreset.cpp index 67860969..546b75d7 100644 --- a/src/object/task/taskreset.cpp +++ b/src/object/task/taskreset.cpp @@ -23,6 +23,7 @@ #include "object/brain.h" #include "object/object_manager.h" #include "object/robotmain.h" +#include "object/interface/transportable_object.h" @@ -167,9 +168,9 @@ Error CTaskReset::Start(Math::Vector goal, Math::Vector angle) int i; cargo = m_object->GetCargo(); - if ( cargo != 0 && cargo->GetResetCap() == RESET_MOVE ) + if ( cargo != nullptr && cargo->GetResetCap() == RESET_MOVE ) { - cargo->SetTransporter(0); + dynamic_cast(cargo)->SetTransporter(0); m_object->SetCargo(0); // does nothing } diff --git a/src/object/task/tasktake.cpp b/src/object/task/tasktake.cpp index 6efa666b..0acfaa06 100644 --- a/src/object/task/tasktake.cpp +++ b/src/object/task/tasktake.cpp @@ -28,6 +28,7 @@ #include "object/motion/motionhuman.h" #include "object/object_manager.h" #include "object/robotmain.h" +#include "object/interface/transportable_object.h" #include "physics/physics.h" @@ -329,7 +330,7 @@ CObject* CTaskTake::SearchTakeObject(float &angle, type != OBJECT_KEYd && type != OBJECT_TNT ) continue; - if ( pObj->GetTransporter() != 0 ) continue; // object transported? + if (IsObjectBeingTransported(pObj)) continue; if ( pObj->GetLock() ) continue; if ( pObj->GetZoomY(0) != 1.0f ) continue; @@ -460,8 +461,8 @@ bool CTaskTake::TransporterTakeObject() if ( cargo == 0 ) return false; // rien � prendre ? m_cargoType = cargo->GetType(); - cargo->SetTransporter(m_object); - cargo->SetTransporterPart(4); // takes with the hand + dynamic_cast(cargo)->SetTransporter(m_object); + dynamic_cast(cargo)->SetTransporterPart(4); // takes with the hand //? cargo->SetPosition(0, Math::Vector(2.2f, -1.0f, 1.1f)); cargo->SetPosition(0, Math::Vector(1.7f, -0.5f, 1.1f)); @@ -482,8 +483,8 @@ bool CTaskTake::TransporterTakeObject() m_cargoType = cargo->GetType(); other->SetPower(0); - cargo->SetTransporter(m_object); - cargo->SetTransporterPart(4); // takes with the hand + dynamic_cast(cargo)->SetTransporter(m_object); + dynamic_cast(cargo)->SetTransporterPart(4); // takes with the hand //? cargo->SetPosition(0, Math::Vector(2.2f, -1.0f, 1.1f)); cargo->SetPosition(0, Math::Vector(1.7f, -0.5f, 1.1f)); @@ -523,7 +524,7 @@ bool CTaskTake::TransporterDeposeObject() cargo->SetAngleZ(0, 0.0f); cargo->FloorAdjust(); // plate well on the ground - cargo->SetTransporter(0); + dynamic_cast(cargo)->SetTransporter(0); m_object->SetCargo(0); // deposit } @@ -540,14 +541,14 @@ bool CTaskTake::TransporterDeposeObject() m_cargoType = cargo->GetType(); other->SetPower(cargo); - cargo->SetTransporter(other); + dynamic_cast(cargo)->SetTransporter(other); character = other->GetCharacter(); cargo->SetPosition(0, character->posPower); cargo->SetAngleY(0, 0.0f); cargo->SetAngleX(0, 0.0f); cargo->SetAngleZ(0, 0.0f); - cargo->SetTransporterPart(0); // carried by the base + dynamic_cast(cargo)->SetTransporterPart(0); // carried by the base m_object->SetCargo(0); // deposit } @@ -566,7 +567,7 @@ bool CTaskTake::IsFreeDeposeObject(Math::Vector pos) { if ( pObj == m_object ) continue; if ( !pObj->GetActive() ) continue; // inactive? - if ( pObj->GetTransporter() != 0 ) continue; // object transported? + if (IsObjectBeingTransported(pObj)) continue; for (const auto& crashSphere : pObj->GetAllCrashSpheres()) { diff --git a/src/physics/physics.cpp b/src/physics/physics.cpp index 63e71986..11baf23a 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/transportable_object.h" #include @@ -1779,7 +1780,7 @@ void CPhysics::WaterFrame(float aTime, float rTime) level = m_water->GetLevel(); if ( level == 0.0f ) return; // no water? - if ( m_object->GetTransporter() != 0 ) return; // object transported? + if (IsObjectBeingTransported(m_object)) return; // Management of flames into the lava. pos = m_object->GetPosition(0); @@ -2530,7 +2531,7 @@ int CPhysics::ObjectAdapt(const Math::Vector &pos, const Math::Vector &angle) for (CObject* pObj : CObjectManager::GetInstancePointer()->GetAllObjects()) { if ( pObj == m_object ) continue; // yourself? - if ( pObj->GetTransporter() != 0 ) continue; // object transported? + if (IsObjectBeingTransported(pObj)) continue; if ( !pObj->GetEnable() ) continue; // inactive? if ( pObj->GetRuin() ) continue; // is burning or exploding? if ( pObj->GetDead() ) continue; // dead man? diff --git a/src/ui/map.cpp b/src/ui/map.cpp index 3d437945..56d4283f 100644 --- a/src/ui/map.cpp +++ b/src/ui/map.cpp @@ -22,6 +22,8 @@ #include "common/image.h" +#include "object/interface/transportable_object.h" + #include @@ -1145,7 +1147,7 @@ void CMap::UpdateObject(CObject* pObj) if ( !pObj->GetActive() ) return; if ( !pObj->GetSelectable() ) return; if ( pObj->GetProxyActivate() ) return; - if ( pObj->GetTransporter() != 0 ) return; + if (IsObjectBeingTransported(pObj)) return; type = pObj->GetType(); pos = pObj->GetPosition(0); diff --git a/src/ui/target.cpp b/src/ui/target.cpp index 642fcd64..5c433b35 100644 --- a/src/ui/target.cpp +++ b/src/ui/target.cpp @@ -246,9 +246,9 @@ CObject* CTarget::DetectFriendObject(Math::Point pos) } else if ( (type == OBJECT_POWER || type == OBJECT_ATOMIC ) && - obj->GetTransporter() != nullptr ) // battery used? + IsObjectBeingTransported(obj) ) // battery used? { - target = obj->GetTransporter(); + target = dynamic_cast(obj)->GetTransporter(); if ( target->GetType() == OBJECT_MOBILEtg ) { target = nullptr;