From f4b2f3468d1d2e070a085a5f530e1559df65a908 Mon Sep 17 00:00:00 2001 From: Piotr Dziwinski Date: Fri, 10 Jul 2015 23:47:59 +0200 Subject: [PATCH] CPoweredObject interface --- src/graphics/engine/camera.cpp | 10 +- src/graphics/engine/pyro.cpp | 40 +++-- src/object/auto/autolabo.cpp | 26 ++- src/object/auto/autolabo.h | 2 + src/object/auto/autonuclearplant.cpp | 28 +-- src/object/auto/autonuclearplant.h | 2 + src/object/auto/autopowercaptor.cpp | 18 +- src/object/auto/autopowerplant.cpp | 37 ++-- src/object/auto/autopowerplant.h | 3 + src/object/auto/autopowerstation.cpp | 59 +++---- src/object/auto/autoresearch.cpp | 44 ++--- src/object/auto/autoresearch.h | 2 + src/object/auto/autotower.cpp | 34 ++-- src/object/auto/autotower.h | 2 + src/object/brain.cpp | 28 +-- src/object/interface/powered_object.h | 67 +++++++ src/object/motion/motionvehicle.cpp | 20 +-- src/object/object_interface_type.h | 1 + src/object/old_object.cpp | 11 +- src/object/old_object.h | 4 +- src/object/old_object_interface.h | 3 - src/object/robotmain.cpp | 36 ++-- src/object/scene_conditions.cpp | 6 +- src/object/task/taskfire.cpp | 15 +- src/object/task/taskmanip.cpp | 245 +++++++++++++------------- src/object/task/taskmanip.h | 4 +- src/object/task/taskrecover.cpp | 32 ++-- src/object/task/taskreset.cpp | 20 +-- src/object/task/taskshield.cpp | 48 +++-- src/object/task/taskshield.h | 2 + src/object/task/tasktake.cpp | 158 ++++++++--------- src/object/task/tasktake.h | 4 +- src/object/task/taskterraform.cpp | 18 +- src/object/task/taskterraform.h | 2 + src/physics/physics.cpp | 87 ++++----- 35 files changed, 601 insertions(+), 517 deletions(-) create mode 100644 src/object/interface/powered_object.h diff --git a/src/graphics/engine/camera.cpp b/src/graphics/engine/camera.cpp index de49a868..05945529 100644 --- a/src/graphics/engine/camera.cpp +++ b/src/graphics/engine/camera.cpp @@ -34,6 +34,7 @@ #include "object/object_manager.h" #include "object/robotmain.h" #include "object/interface/carrier_object.h" +#include "object/interface/powered_object.h" #include "object/interface/transportable_object.h" #include "physics/physics.h" @@ -55,9 +56,12 @@ void SetTransparency(CObject* obj, float value) cargo->SetTransparency(value); } - CObject* power = obj->GetPower(); - if (power != nullptr) - power->SetTransparency(value); + if (obj->Implements(ObjectInterfaceType::Powered)) + { + CObject* power = dynamic_cast(obj)->GetPower(); + if (power != nullptr) + power->SetTransparency(value); + } } diff --git a/src/graphics/engine/pyro.cpp b/src/graphics/engine/pyro.cpp index f2d94081..a30da333 100644 --- a/src/graphics/engine/pyro.cpp +++ b/src/graphics/engine/pyro.cpp @@ -120,8 +120,12 @@ bool CPyro::Create(PyroType type, CObject* obj, float force) m_lightRank = -1; // Seeking the position of the battery. - CObject* power = obj->GetPower(); - if ( power == nullptr ) + + CObject* power = nullptr; + if (obj->Implements(ObjectInterfaceType::Powered)) + power = dynamic_cast(obj)->GetPower(); + + if (power == nullptr) { m_power = false; } @@ -133,6 +137,7 @@ bool CPyro::Create(PyroType type, CObject* obj, float force) Math::Matrix* mat = obj->GetWorldMatrix(0); m_posPower = Math::Transform(*mat, pos); } + if ( oType == OBJECT_POWER || oType == OBJECT_ATOMIC || oType == OBJECT_URANIUM || @@ -1357,17 +1362,21 @@ void CPyro::DeleteObject(bool primary, bool secondary) type != OBJECT_NUCLEAR && type != OBJECT_ENERGY ) { - CObject* sub = m_object->GetPower(); - if ( sub != nullptr ) + if (m_object->Implements(ObjectInterfaceType::Powered)) { - CObjectManager::GetInstancePointer()->DeleteObject(sub); - m_object->SetPower(nullptr); + CPoweredObject* poweredObject = dynamic_cast(m_object); + CObject* sub = poweredObject->GetPower(); + if (sub != nullptr) + { + CObjectManager::GetInstancePointer()->DeleteObject(sub); + poweredObject->SetPower(nullptr); + } } if (m_object->Implements(ObjectInterfaceType::Carrier)) { CCarrierObject* carrierObject = dynamic_cast(m_object); - sub = carrierObject->GetCargo(); + CObject* sub = carrierObject->GetCargo(); if (sub != nullptr) { CObjectManager::GetInstancePointer()->DeleteObject(sub); @@ -1384,8 +1393,12 @@ void CPyro::DeleteObject(bool primary, bool secondary) CObject* transporter = dynamic_cast(m_object)->GetTransporter(); if (transporter != nullptr) { - if (transporter->GetPower() == m_object) - transporter->SetPower(nullptr); + if (transporter->Implements(ObjectInterfaceType::Powered)) + { + CPoweredObject* powered = dynamic_cast(transporter); + if (powered->GetPower() == m_object) + powered->SetPower(nullptr); + } if (transporter->Implements(ObjectInterfaceType::Carrier)) { @@ -2106,9 +2119,12 @@ void CPyro::BurnProgress() m_object->SetAngle(m_burnPart[i].part, pos); } - CObject* sub = m_object->GetPower(); - if (sub != nullptr) // is there a battery? - sub->SetZoomY(0, 1.0f - m_progress); // complete flattening + if (m_object->Implements(ObjectInterfaceType::Powered)) + { + CObject* sub = dynamic_cast(m_object)->GetPower(); + if (sub != nullptr) // is there a battery? + sub->SetZoomY(0, 1.0f - m_progress); // complete flattening + } } bool CPyro::BurnIsKeepPart(int part) diff --git a/src/object/auto/autolabo.cpp b/src/object/auto/autolabo.cpp index fd742c40..30832cfc 100644 --- a/src/object/auto/autolabo.cpp +++ b/src/object/auto/autolabo.cpp @@ -29,7 +29,7 @@ #include "object/robotmain.h" #include "object/level/parserline.h" #include "object/level/parserparam.h" - +#include "object/interface/powered_object.h" #include "ui/interface.h" #include "ui/window.h" @@ -57,6 +57,9 @@ CAutoLabo::CAutoLabo(CObject* object) : CAuto(object) m_soundChannel = -1; Init(); + + assert(m_object->Implements(ObjectInterfaceType::Powered)); + m_poweredObject = dynamic_cast(m_object); } // Object's destructor. @@ -118,8 +121,6 @@ void CAutoLabo::Init() Error CAutoLabo::StartAction(int param) { - CObject* power; - if ( m_phase != ALAP_WAIT ) { return ERR_GENERIC; @@ -132,8 +133,8 @@ Error CAutoLabo::StartAction(int param) return ERR_LABO_ALREADY; } - power = m_object->GetPower(); - if ( power == 0 ) + CObject* power = m_poweredObject->GetPower(); + if (power == nullptr) { return ERR_LABO_NULL; } @@ -304,7 +305,7 @@ bool CAutoLabo::EventProcess(const Event &event) { if ( m_progress < 1.0f ) { - power = m_object->GetPower(); + power = m_poweredObject->GetPower(); if ( power != 0 ) { power->SetZoom(0, 1.0f-m_progress); @@ -365,10 +366,10 @@ bool CAutoLabo::EventProcess(const Event &event) m_eventQueue->AddEvent(newEvent); UpdateInterface(); - power = m_object->GetPower(); + power = m_poweredObject->GetPower(); if ( power != nullptr ) { - m_object->SetPower(nullptr); + m_poweredObject->SetPower(nullptr); CObjectManager::GetInstancePointer()->DeleteObject(power); } @@ -451,17 +452,14 @@ bool CAutoLabo::EventProcess(const Event &event) Error CAutoLabo::GetError() { - CObject* pObj; - ObjectType type; - if ( m_object->GetVirusMode() ) { return ERR_BAT_VIRUS; } - pObj = m_object->GetPower(); - if ( pObj == 0 ) return ERR_LABO_NULL; - type = pObj->GetType(); + CObject* obj = m_poweredObject->GetPower(); + if (obj == nullptr) return ERR_LABO_NULL; + ObjectType type = obj->GetType(); if ( type != OBJECT_BULLET ) return ERR_LABO_BAD; return ERR_OK; diff --git a/src/object/auto/autolabo.h b/src/object/auto/autolabo.h index 84d3f677..b83db873 100644 --- a/src/object/auto/autolabo.h +++ b/src/object/auto/autolabo.h @@ -25,6 +25,7 @@ #include "object/auto/auto.h" +class CPoweredObject; enum AutoLaboPhase { @@ -66,6 +67,7 @@ protected: void SoundManip(float time, float amplitude, float frequency); protected: + CPoweredObject* m_poweredObject; AutoLaboPhase m_phase; float m_progress; float m_speed; diff --git a/src/object/auto/autonuclearplant.cpp b/src/object/auto/autonuclearplant.cpp index 563ec817..e9395024 100644 --- a/src/object/auto/autonuclearplant.cpp +++ b/src/object/auto/autonuclearplant.cpp @@ -25,6 +25,7 @@ #include "object/object_manager.h" #include "object/level/parserline.h" #include "object/level/parserparam.h" +#include "object/interface/powered_object.h" #include "object/interface/transportable_object.h" #include "ui/interface.h" @@ -45,6 +46,9 @@ CAutoNuclearPlant::CAutoNuclearPlant(CObject* object) : CAuto(object) { m_channelSound = -1; Init(); + + assert(m_object->Implements(ObjectInterfaceType::Powered)); + m_poweredObject = dynamic_cast(m_object); } // Object's destructor. @@ -230,7 +234,7 @@ bool CAutoNuclearPlant::EventProcess(const Event &event) if ( cargo != nullptr ) { CObjectManager::GetInstancePointer()->DeleteObject(cargo); - m_object->SetPower(nullptr); + m_poweredObject->SetPower(nullptr); } CreatePower(); // creates the atomic cell @@ -318,12 +322,10 @@ bool CAutoNuclearPlant::CreateInterface(bool bSelect) CObject* CAutoNuclearPlant::SearchUranium() { - CObject* pObj; - - pObj = m_object->GetPower(); - if ( pObj == 0 ) return 0; - if ( pObj->GetType() == OBJECT_URANIUM ) return pObj; - return 0; + CObject* obj = m_poweredObject->GetPower(); + if (obj == nullptr) return nullptr; + if (obj->GetType() == OBJECT_URANIUM) return obj; + return nullptr; } // Seeks if a vehicle is too close. @@ -389,7 +391,7 @@ void CAutoNuclearPlant::CreatePower() dynamic_cast(power)->SetTransporter(m_object); power->SetPosition(0, Math::Vector(22.0f, 3.0f, 0.0f)); - m_object->SetPower(power); + m_poweredObject->SetPower(power); } @@ -397,8 +399,6 @@ void CAutoNuclearPlant::CreatePower() Error CAutoNuclearPlant::GetError() { - CObject* pObj; - ObjectType type; //? TerrainRes res; if ( m_object->GetVirusMode() ) @@ -411,10 +411,10 @@ Error CAutoNuclearPlant::GetError() //? if ( m_object->GetEnergy() < ENERGY_POWER ) return ERR_NUCLEAR_LOW; - pObj = m_object->GetPower(); - if ( pObj == 0 ) return ERR_NUCLEAR_EMPTY; - if ( pObj->GetLock() ) return ERR_OK; - type = pObj->GetType(); + CObject* obj = m_poweredObject->GetPower(); + if ( obj == nullptr ) return ERR_NUCLEAR_EMPTY; + if ( obj->GetLock() ) return ERR_OK; + ObjectType type = obj->GetType(); if ( type == OBJECT_ATOMIC ) return ERR_OK; if ( type != OBJECT_URANIUM ) return ERR_NUCLEAR_BAD; diff --git a/src/object/auto/autonuclearplant.h b/src/object/auto/autonuclearplant.h index d0837e0b..33c1648e 100644 --- a/src/object/auto/autonuclearplant.h +++ b/src/object/auto/autonuclearplant.h @@ -25,6 +25,7 @@ #include "object/auto/auto.h" +class CPoweredObject; enum AutoNuclearPlantPhase { @@ -60,6 +61,7 @@ protected: void CreatePower(); protected: + CPoweredObject* m_poweredObject; AutoNuclearPlantPhase m_phase; float m_progress; float m_speed; diff --git a/src/object/auto/autopowercaptor.cpp b/src/object/auto/autopowercaptor.cpp index 8868c76a..b5f03394 100644 --- a/src/object/auto/autopowercaptor.cpp +++ b/src/object/auto/autopowercaptor.cpp @@ -27,6 +27,7 @@ #include "object/level/parserline.h" #include "object/level/parserparam.h" #include "object/interface/carrier_object.h" +#include "object/interface/powered_object.h" #include "object/interface/transportable_object.h" #include "ui/interface.h" @@ -259,18 +260,21 @@ void CAutoPowerCaptor::ChargeObject(float rTime) obj->SetEnergy(energy); } - CObject* power = obj->GetPower(); - if ( power != nullptr && power->GetType() == OBJECT_POWER ) + if (obj->Implements(ObjectInterfaceType::Powered)) { - float energy = power->GetEnergy(); - energy += rTime/2.0f; - if ( energy > 1.0f ) energy = 1.0f; - power->SetEnergy(energy); + CObject* power = dynamic_cast(obj)->GetPower(); + if ( power != nullptr && power->GetType() == OBJECT_POWER ) + { + float energy = power->GetEnergy(); + energy += rTime/2.0f; + if ( energy > 1.0f ) energy = 1.0f; + power->SetEnergy(energy); + } } if (obj->Implements(ObjectInterfaceType::Carrier)) { - power = dynamic_cast(obj)->GetCargo(); + CObject* power = dynamic_cast(obj)->GetCargo(); if ( power != nullptr && power->GetType() == OBJECT_POWER ) { float energy = power->GetEnergy(); diff --git a/src/object/auto/autopowerplant.cpp b/src/object/auto/autopowerplant.cpp index 9a7404a2..ed8779b6 100644 --- a/src/object/auto/autopowerplant.cpp +++ b/src/object/auto/autopowerplant.cpp @@ -25,6 +25,7 @@ #include "math/geometry.h" #include "object/object_manager.h" +#include "object/interface/powered_object.h" #include "object/interface/transportable_object.h" #include "object/level/parserline.h" #include "object/level/parserparam.h" @@ -49,6 +50,9 @@ CAutoPowerPlant::CAutoPowerPlant(CObject* object) : CAuto(object) { m_partiSphere = -1; Init(); + + assert(m_object->Implements(ObjectInterfaceType::Powered)); + m_poweredObject = dynamic_cast(m_object); } // Object's destructor. @@ -309,18 +313,20 @@ bool CAutoPowerPlant::EventProcess(const Event &event) cargo = SearchMetal(); if ( cargo != nullptr ) { - m_object->SetPower(nullptr); + m_poweredObject->SetPower(nullptr); CObjectManager::GetInstancePointer()->DeleteObject(cargo); } cargo = SearchPower(); - if ( cargo != nullptr ) + if (cargo != nullptr) { + assert(cargo->Implements(ObjectInterfaceType::Transportable)); + cargo->SetZoom(0, 1.0f); cargo->SetLock(false); // usable battery dynamic_cast(cargo)->SetTransporter(m_object); cargo->SetPosition(0, Math::Vector(0.0f, 3.0f, 0.0f)); - m_object->SetPower(cargo); + m_poweredObject->SetPower(cargo); m_main->DisplayError(INFO_ENERGY, m_object); } @@ -374,19 +380,16 @@ bool CAutoPowerPlant::EventProcess(const Event &event) CObject* CAutoPowerPlant::SearchMetal() { - CObject* pObj; - ObjectType type; + CObject* obj = m_poweredObject->GetPower(); + if ( obj == nullptr ) return nullptr; - pObj = m_object->GetPower(); - if ( pObj == 0 ) return 0; - - type = pObj->GetType(); + ObjectType type = obj->GetType(); if ( type == OBJECT_METAL || type == OBJECT_SCRAP1 || type == OBJECT_SCRAP2 || - type == OBJECT_SCRAP3 ) return pObj; + type == OBJECT_SCRAP3 ) return obj; - return 0; + return nullptr; } // Search if a vehicle is too close. @@ -486,10 +489,6 @@ CObject* CAutoPowerPlant::SearchPower() Error CAutoPowerPlant::GetError() { - CObject* pObj; - ObjectType type; - Gfx::TerrainRes res; - if ( m_object->GetVirusMode() ) { return ERR_BAT_VIRUS; @@ -498,14 +497,14 @@ Error CAutoPowerPlant::GetError() if ( m_phase != AENP_WAIT && m_phase != AENP_BLITZ ) return ERR_OK; - res = m_terrain->GetResource(m_object->GetPosition(0)); + Gfx::TerrainRes res = m_terrain->GetResource(m_object->GetPosition(0)); if ( res != Gfx::TR_POWER ) return ERR_ENERGY_NULL; if ( m_object->GetEnergy() < POWERPLANT_POWER ) return ERR_ENERGY_LOW; - pObj = m_object->GetPower(); - if ( pObj == 0 ) return ERR_ENERGY_EMPTY; - type = pObj->GetType(); + CObject* obj = m_poweredObject->GetPower(); + if (obj == nullptr) return ERR_ENERGY_EMPTY; + ObjectType type = obj->GetType(); if ( type == OBJECT_POWER ) return ERR_OK; if ( type != OBJECT_METAL && type != OBJECT_SCRAP1 && diff --git a/src/object/auto/autopowerplant.h b/src/object/auto/autopowerplant.h index 3d8f3e20..5f438b2d 100644 --- a/src/object/auto/autopowerplant.h +++ b/src/object/auto/autopowerplant.h @@ -25,6 +25,8 @@ #include "object/auto/auto.h" +class CPoweredObject; + enum AutoPowerPlantPhase { @@ -63,6 +65,7 @@ protected: CObject* SearchPower(); protected: + CPoweredObject* m_poweredObject; AutoPowerPlantPhase m_phase; float m_progress; float m_speed; diff --git a/src/object/auto/autopowerstation.cpp b/src/object/auto/autopowerstation.cpp index a3e5fe6e..ea3176dc 100644 --- a/src/object/auto/autopowerstation.cpp +++ b/src/object/auto/autopowerstation.cpp @@ -27,6 +27,7 @@ #include "object/object_manager.h" #include "object/interface/carrier_object.h" +#include "object/interface/powered_object.h" #include "ui/interface.h" #include "ui/gauge.h" @@ -82,14 +83,6 @@ void CAutoPowerStation::Init() bool CAutoPowerStation::EventProcess(const Event &event) { - Math::Matrix* mat; - Math::Vector pos, ppos, speed; - Math::Point dim; - CObject* vehicle; - CObject* power; - Gfx::TerrainRes res; - float big, energy, used, add, freq; - CAuto::EventProcess(event); if ( m_engine->GetPause() ) return true; @@ -124,41 +117,44 @@ bool CAutoPowerStation::EventProcess(const Event &event) UpdateInterface(event.rTime); - big = m_object->GetEnergy(); + float big = m_object->GetEnergy(); - res = m_terrain->GetResource(m_object->GetPosition(0)); + Gfx::TerrainRes res = m_terrain->GetResource(m_object->GetPosition(0)); if ( res == Gfx::TR_POWER ) { big += event.rTime*0.01f; // recharges the large battery } - used = big; - freq = 1.0f; - if ( big > 0.0f ) + float used = big; + float freq = 1.0f; + if (big > 0.0f) { - vehicle = SearchVehicle(); - if ( vehicle != 0 ) + CObject* vehicle = SearchVehicle(); + if (vehicle != nullptr) { - power = vehicle->GetPower(); - if ( power != 0 && power->GetCapacity() == 1.0f ) + if (vehicle->Implements(ObjectInterfaceType::Powered)) { - energy = power->GetEnergy(); - add = event.rTime*0.2f; - if ( add > big*4.0f ) add = big*4.0f; - if ( add > 1.0f-energy ) add = 1.0f-energy; - energy += add; // Charging the battery - power->SetEnergy(energy); - if ( energy < freq ) freq = energy; - big -= add/4.0f; // discharge the large battery + CObject* power = dynamic_cast(vehicle)->GetPower(); + if ( power != nullptr && power->GetCapacity() == 1.0f ) + { + float energy = power->GetEnergy(); + float add = event.rTime*0.2f; + if ( add > big*4.0f ) add = big*4.0f; + if ( add > 1.0f-energy ) add = 1.0f-energy; + energy += add; // Charging the battery + power->SetEnergy(energy); + if ( energy < freq ) freq = energy; + big -= add/4.0f; // discharge the large battery + } } if (vehicle->Implements(ObjectInterfaceType::Carrier)) { - power = dynamic_cast(vehicle)->GetCargo(); - if ( power != nullptr && power->GetType() == OBJECT_POWER ) + CObject* power = dynamic_cast(vehicle)->GetCargo(); + if (power != nullptr && power->GetType() == OBJECT_POWER) { - energy = power->GetEnergy(); - add = event.rTime*0.2f; + float energy = power->GetEnergy(); + float add = event.rTime*0.2f; if ( add > big*4.0f ) add = big*4.0f; if ( add > 1.0f-energy ) add = 1.0f-energy; energy += add; // Charging the battery @@ -195,7 +191,10 @@ bool CAutoPowerStation::EventProcess(const Event &event) { m_lastParticle = m_time; - mat = m_object->GetWorldMatrix(0); + Math::Vector pos, ppos, speed; + Math::Point dim; + + Math::Matrix* mat = m_object->GetWorldMatrix(0); pos = Math::Vector(-15.0f, 7.0f, 0.0f); // battery position pos = Math::Transform(*mat, pos); speed.x = (Math::Rand()-0.5f)*20.0f; diff --git a/src/object/auto/autoresearch.cpp b/src/object/auto/autoresearch.cpp index 553cd1b9..7d050ae6 100644 --- a/src/object/auto/autoresearch.cpp +++ b/src/object/auto/autoresearch.cpp @@ -27,7 +27,7 @@ #include "object/robotmain.h" #include "object/level/parserline.h" #include "object/level/parserparam.h" - +#include "object/interface/powered_object.h" #include "ui/interface.h" #include "ui/gauge.h" @@ -45,15 +45,16 @@ const float SEARCH_TIME = 30.0f; // duration of a research CAutoResearch::CAutoResearch(CObject* object) : CAuto(object) { - int i; - - for ( i=0 ; i<6 ; i++ ) + for (int i = 0; i < 6; i++) { m_partiStop[i] = -1; } m_channelSound = -1; Init(); + + assert(m_object->Implements(ObjectInterfaceType::Powered)); + m_poweredObject = dynamic_cast(m_object); } // Object's destructor. @@ -98,9 +99,6 @@ void CAutoResearch::Init() Error CAutoResearch::StartAction(int param) { - CObject* power; - float time; - if ( m_phase != ALP_WAIT ) { return ERR_GENERIC; @@ -113,8 +111,8 @@ Error CAutoResearch::StartAction(int param) return ERR_RESEARCH_ALREADY; } - power = m_object->GetPower(); - if ( power == 0 ) + CObject* power = m_poweredObject->GetPower(); + if (power == nullptr) { return ERR_RESEARCH_POWER; } @@ -127,7 +125,7 @@ Error CAutoResearch::StartAction(int param) return ERR_RESEARCH_ENERGY; } - time = SEARCH_TIME; + float time = SEARCH_TIME; if ( m_research == RESEARCH_TANK ) time *= 0.3f; if ( m_research == RESEARCH_FLY ) time *= 0.3f; if ( m_research == RESEARCH_ATOMIC ) time *= 2.0f; @@ -220,7 +218,7 @@ bool CAutoResearch::EventProcess(const Event &event) FireStopUpdate(m_progress, true); // flashes if ( m_progress < 1.0f ) { - power = m_object->GetPower(); + power = m_poweredObject->GetPower(); if ( power == 0 ) // more battery? { SetBusy(false); @@ -292,8 +290,6 @@ bool CAutoResearch::EventProcess(const Event &event) Error CAutoResearch::GetError() { - CObject* power; - if ( m_phase == ALP_SEARCH ) { return ERR_OK; @@ -304,7 +300,7 @@ Error CAutoResearch::GetError() return ERR_BAT_VIRUS; } - power = m_object->GetPower(); + CObject* power = m_poweredObject->GetPower(); if ( power == 0 ) { return ERR_RESEARCH_POWER; @@ -439,11 +435,6 @@ void CAutoResearch::UpdateInterface() void CAutoResearch::UpdateInterface(float rTime) { - Ui::CWindow* pw; - Ui::CGauge* pg; - CObject* power; - float energy; - CAuto::UpdateInterface(rTime); if ( m_time < m_lastUpdateTime+0.1f ) return; @@ -451,18 +442,13 @@ void CAutoResearch::UpdateInterface(float rTime) if ( !m_object->GetSelect() ) return; - pw = static_cast< Ui::CWindow* >(m_interface->SearchControl(EVENT_WINDOW0)); - if ( pw == 0 ) return; + Ui::CWindow* pw = static_cast< Ui::CWindow* >(m_interface->SearchControl(EVENT_WINDOW0)); + if ( pw == nullptr ) return; - pg = static_cast< Ui::CGauge* >(pw->SearchControl(EVENT_OBJECT_GENERGY)); - if ( pg != 0 ) + Ui::CGauge* pg = static_cast< Ui::CGauge* >(pw->SearchControl(EVENT_OBJECT_GENERGY)); + if ( pg != nullptr ) { - energy = 0.0f; - power = m_object->GetPower(); - if ( power != 0 ) - { - energy = power->GetEnergy(); - } + float energy = GetObjectEnergy(m_object); pg->SetLevel(energy); } } diff --git a/src/object/auto/autoresearch.h b/src/object/auto/autoresearch.h index c819d520..6013a0c1 100644 --- a/src/object/auto/autoresearch.h +++ b/src/object/auto/autoresearch.h @@ -25,6 +25,7 @@ #include "object/auto/auto.h" +class CPoweredObject; enum AutoResearchPhase { @@ -60,6 +61,7 @@ protected: void FireStopUpdate(float progress, bool bLightOn); protected: + CPoweredObject* m_poweredObject; AutoResearchPhase m_phase; float m_progress; float m_speed; diff --git a/src/object/auto/autotower.cpp b/src/object/auto/autotower.cpp index d12fc428..dd036d8b 100644 --- a/src/object/auto/autotower.cpp +++ b/src/object/auto/autotower.cpp @@ -25,6 +25,7 @@ #include "object/object_manager.h" #include "object/level/parserline.h" #include "object/level/parserparam.h" +#include "object/interface/powered_object.h" #include "physics/physics.h" @@ -45,9 +46,7 @@ const float ENERGY_FIRE = 0.125f; // energy consumed by fire CAutoTower::CAutoTower(CObject* object) : CAuto(object) { - int i; - - for ( i=0 ; i<4 ; i++ ) + for (int i = 0; i < 4; i++) { m_partiStop[i] = -1; } @@ -56,6 +55,9 @@ CAutoTower::CAutoTower(CObject* object) : CAuto(object) m_phase = ATP_WAIT; // paused until the first Init () m_time = 0.0f; m_lastUpdateTime = 0.0f; + + assert(m_object->Implements(ObjectInterfaceType::Powered)); + m_poweredObject = dynamic_cast(m_object); } // Object's destructor. @@ -132,7 +134,7 @@ bool CAutoTower::EventProcess(const Event &event) if ( m_progress < 1.0f ) { energy = 0.0f; - power = m_object->GetPower(); + power = m_poweredObject->GetPower(); if ( power != 0 ) { energy = power->GetEnergy()*power->GetCapacity(); @@ -172,7 +174,7 @@ bool CAutoTower::EventProcess(const Event &event) else { energy = 0.0f; - power = m_object->GetPower(); + power = m_poweredObject->GetPower(); if ( power != 0 ) { energy = power->GetEnergy()*power->GetCapacity(); @@ -225,7 +227,7 @@ bool CAutoTower::EventProcess(const Event &event) m_object->SetAngleY(1, m_angleYfinal); m_object->SetAngleZ(2, m_angleZfinal); - power = m_object->GetPower(); + power = m_poweredObject->GetPower(); if ( power != 0 ) { energy = power->GetEnergy(); @@ -314,14 +316,12 @@ CObject* CAutoTower::SearchTarget(Math::Vector &impact) Error CAutoTower::GetError() { - CObject* power; - if ( m_object->GetVirusMode() ) { return ERR_BAT_VIRUS; } - power = m_object->GetPower(); + CObject* power = m_poweredObject->GetPower(); if ( power == nullptr ) { return ERR_TOWER_POWER; // no battery @@ -447,11 +447,6 @@ bool CAutoTower::CreateInterface(bool bSelect) void CAutoTower::UpdateInterface(float rTime) { - Ui::CWindow* pw; - Ui::CGauge* pg; - CObject* power; - float energy; - CAuto::UpdateInterface(rTime); if ( m_time < m_lastUpdateTime+0.1f ) return; @@ -459,18 +454,13 @@ void CAutoTower::UpdateInterface(float rTime) if ( !m_object->GetSelect() ) return; - pw = static_cast< Ui::CWindow* >(m_interface->SearchControl(EVENT_WINDOW0)); + Ui::CWindow* pw = static_cast< Ui::CWindow* >(m_interface->SearchControl(EVENT_WINDOW0)); if ( pw == 0 ) return; - pg = static_cast< Ui::CGauge* >(pw->SearchControl(EVENT_OBJECT_GENERGY)); + Ui::CGauge*pg = static_cast< Ui::CGauge* >(pw->SearchControl(EVENT_OBJECT_GENERGY)); if ( pg != 0 ) { - energy = 0.0f; - power = m_object->GetPower(); - if ( power != 0 ) - { - energy = power->GetEnergy(); - } + float energy = GetObjectEnergy(m_object); pg->SetLevel(energy); } } diff --git a/src/object/auto/autotower.h b/src/object/auto/autotower.h index 67982399..99f555cf 100644 --- a/src/object/auto/autotower.h +++ b/src/object/auto/autotower.h @@ -25,6 +25,7 @@ #include "object/auto/auto.h" +class CPoweredObject; enum AutoTowerPhase { @@ -61,6 +62,7 @@ protected: void FireStopUpdate(float progress, bool bLightOn); protected: + CPoweredObject* m_poweredObject; AutoTowerPhase m_phase; float m_progress; float m_speed; diff --git a/src/object/brain.cpp b/src/object/brain.cpp index 9fcbed73..a6021ee0 100644 --- a/src/object/brain.cpp +++ b/src/object/brain.cpp @@ -34,6 +34,7 @@ #include "object/level/parserline.h" #include "object/level/parserparam.h" #include "object/interface/carrier_object.h" +#include "object/interface/powered_object.h" #include "physics/physics.h" @@ -2079,14 +2080,12 @@ void CBrain::UpdateInterface(float rTime) { Ui::CWindow* pw; Ui::CButton* pb; - Ui::CGauge* pg; Ui::CCompass* pc; Ui::CGroup* pgr; Ui::CTarget* ptg; - CObject* power; Math::Vector pos, hPos; Math::Point ppos; - float energy, limit, angle, range; + float angle, range; int icon; bool bOnBoard; @@ -2108,19 +2107,20 @@ void CBrain::UpdateInterface(float rTime) pw = static_cast< Ui::CWindow* >(m_interface->SearchControl(EVENT_WINDOW0)); if ( pw == 0 ) return; - pg = static_cast< Ui::CGauge* >(pw->SearchControl(EVENT_OBJECT_GENERGY)); - if ( pg != 0 ) + Ui::CGauge* pg = static_cast< Ui::CGauge* >(pw->SearchControl(EVENT_OBJECT_GENERGY)); + if (pg != nullptr) { - power = m_object->GetPower(); - if ( power == 0 ) + float energy = 0.0f; + float limit = 0.0f; + + if (m_object->Implements(ObjectInterfaceType::Powered)) { - energy = 0.0f; - limit = 0.0f; - } - else - { - energy = power->GetEnergy(); - limit = energy*power->GetCapacity(); + CObject* power = dynamic_cast(m_object)->GetPower(); + if (power != nullptr) + { + energy = power->GetEnergy(); + limit = energy*power->GetCapacity(); + } } icon = 0; // red/green diff --git a/src/object/interface/powered_object.h b/src/object/interface/powered_object.h new file mode 100644 index 00000000..23baf6b2 --- /dev/null +++ b/src/object/interface/powered_object.h @@ -0,0 +1,67 @@ +/* + * 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" + +class CObject; + +/** + * \class CPoweredObject + * \brief Interface for objects powered using power cells + */ +class CPoweredObject +{ +public: + explicit CPoweredObject(ObjectInterfaceTypes& types) + { + types[static_cast(ObjectInterfaceType::Powered)] = true; + } + virtual ~CPoweredObject() + {} + + //! Returns the power cell + virtual CObject* GetPower() = 0; + //! Sets power cell + virtual void SetPower(CObject* power) = 0; +}; + +inline float GetObjectEnergy(CObject* object) +{ + float energy = 0.0f; + + if (object->Implements(ObjectInterfaceType::Powered)) + { + CObject* power = dynamic_cast(object)->GetPower(); + if (power != nullptr) + { + energy = power->GetEnergy(); + } + } + + return energy; +} + +inline bool ObjectHasPowerCell(CObject* object) +{ + return object->Implements(ObjectInterfaceType::Powered) && + dynamic_cast(object)->GetPower() != nullptr; +} diff --git a/src/object/motion/motionvehicle.cpp b/src/object/motion/motionvehicle.cpp index 4d3de6bb..8b377383 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/powered_object.h" #include "object/interface/transportable_object.h" #include "physics/physics.h" @@ -937,11 +938,13 @@ void CMotionVehicle::Create(Math::Vector pos, float angle, ObjectType type, { powerCell = CObjectManager::GetInstancePointer()->CreateObject(powerCellPos, powerCellAngle, OBJECT_ATOMIC, power / 100.0f); } + assert(powerCell->Implements(ObjectInterfaceType::Transportable)); powerCell->SetPosition(0, powerCellPos); powerCell->SetAngle(0, Math::Vector(0.0f, powerCellAngle, 0.0f)); dynamic_cast(powerCell)->SetTransporter(m_object); - m_object->SetPower(powerCell); + assert(m_object->Implements(ObjectInterfaceType::Powered)); + dynamic_cast(m_object)->SetPower(powerCell); } pos = m_object->GetPosition(0); @@ -1796,10 +1799,9 @@ bool CMotionVehicle::EventFrameInsect(const Event &event) bool CMotionVehicle::EventFrameCanoni(const Event &event) { - CObject* power; Math::Vector pos, speed; Math::Point dim; - float zoom, angle, energy, factor; + float zoom, angle, factor; bool bOnBoard = false; m_canonTime += event.rTime; @@ -1810,16 +1812,8 @@ bool CMotionVehicle::EventFrameCanoni(const Event &event) bOnBoard = true; } - power = m_object->GetPower(); - if ( power == 0 ) - { - energy = 0.0f; - } - else - { - energy = power->GetEnergy(); - } - if ( energy == 0.0f ) return true; + float energy = GetObjectEnergy(m_object); + if (energy == 0.0f) return true; factor = 0.5f+energy*0.5f; if ( bOnBoard ) factor *= 0.8f; diff --git a/src/object/object_interface_type.h b/src/object/object_interface_type.h index c98d8362..863fb95b 100644 --- a/src/object/object_interface_type.h +++ b/src/object/object_interface_type.h @@ -37,6 +37,7 @@ enum class ObjectInterfaceType Programmable, //!< objects that can be programmed in CBOT Jostleable, //!< object that can be jostled Carrier, //!< object that can carry other objects + Powered, //!< object powered with power cell 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 6d7e340b..37d7bd7e 100644 --- a/src/object/old_object.cpp +++ b/src/object/old_object.cpp @@ -81,7 +81,6 @@ static float debug_arm3 = 0.0f; void uObject(CBotVar* botThis, void* user) { CObject* object = static_cast(user); - CObject* power; CPhysics* physics; CBotVar *pVar, *pSub; ObjectType type; @@ -160,9 +159,12 @@ void uObject(CBotVar* botThis, void* user) // Updates the type of battery. pVar = pVar->GetNext(); // "energyCell" - power = object->GetPower(); - if ( power == 0 ) pVar->SetPointer(0); - else pVar->SetPointer(power->GetBotVar()); + if (object->Implements(ObjectInterfaceType::Powered)) + { + CObject* power = dynamic_cast(object)->GetPower(); + if (power == nullptr) pVar->SetPointer(0); + else pVar->SetPointer(power->GetBotVar()); + } // Updates the transported object's type. pVar = pVar->GetNext(); // "load" @@ -194,6 +196,7 @@ COldObject::COldObject(int id) , CProgrammableObject(m_implementedInterfaces) , CJostleableObject(m_implementedInterfaces) , CCarrierObject(m_implementedInterfaces) + , CPoweredObject(m_implementedInterfaces) { // A bit of a hack since CBrain is set externally in SetBrain() m_implementedInterfaces[static_cast(ObjectInterfaceType::Programmable)] = false; diff --git a/src/object/old_object.h b/src/object/old_object.h index 640c2769..eb545c25 100644 --- a/src/object/old_object.h +++ b/src/object/old_object.h @@ -29,6 +29,7 @@ #include "object/interface/carrier_object.h" #include "object/interface/interactive_object.h" #include "object/interface/jostleable_object.h" +#include "object/interface/powered_object.h" #include "object/interface/programmable_object.h" #include "object/interface/transportable_object.h" @@ -60,7 +61,8 @@ class COldObject : public CObject, public CTransportableObject, public CProgrammableObject, public CJostleableObject, - public CCarrierObject + public CCarrierObject, + public CPoweredObject { friend class CObjectFactory; friend class CObjectManager; diff --git a/src/object/old_object_interface.h b/src/object/old_object_interface.h index 1b268661..72796431 100644 --- a/src/object/old_object_interface.h +++ b/src/object/old_object_interface.h @@ -156,9 +156,6 @@ public: virtual void SetMasterParticle(int part, int parti) = 0; virtual int GetMasterParticle(int part) = 0; - virtual void SetPower(CObject* power) = 0; - virtual CObject* GetPower() = 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 db9f73ff..220f99c4 100644 --- a/src/object/robotmain.cpp +++ b/src/object/robotmain.cpp @@ -1264,9 +1264,12 @@ void CRobotMain::ExecuteCmd(char *cmd) CObject* object = GetSelect(); if (object != nullptr) { - CObject* power = object->GetPower(); - if (power != nullptr) - power->SetEnergy(1.0f); + if (object->Implements(ObjectInterfaceType::Powered)) + { + CObject* power = dynamic_cast(object)->GetPower(); + if (power != nullptr) + power->SetEnergy(1.0f); + } object->SetShield(1.0f); CPhysics* physics = object->GetPhysics(); @@ -1279,11 +1282,15 @@ void CRobotMain::ExecuteCmd(char *cmd) if (strcmp(cmd, "fullenergy") == 0) { CObject* object = GetSelect(); + if (object != nullptr) { - CObject* power = object->GetPower(); - if (power != nullptr) - power->SetEnergy(1.0f); + if (object->Implements(ObjectInterfaceType::Powered)) + { + CObject* power = dynamic_cast(object)->GetPower(); + if (power != nullptr) + power->SetEnergy(1.0f); + } } return; } @@ -4952,12 +4959,15 @@ bool CRobotMain::IOWriteScene(const char *filename, const char *filecbot, char * } } - CObject* power = obj->GetPower(); - if (power != nullptr) // battery transported? + if (obj->Implements(ObjectInterfaceType::Powered)) { - line.reset(new CLevelParserLine("CreatePower")); - IOWriteObject(line.get(), power); - levelParser.AddLine(std::move(line)); + CObject* power = dynamic_cast(obj)->GetPower(); + if (power != nullptr) // battery transported? + { + line.reset(new CLevelParserLine("CreatePower")); + IOWriteObject(line.get(), power); + levelParser.AddLine(std::move(line)); + } } @@ -5139,7 +5149,9 @@ CObject* CRobotMain::IOReadScene(const char *filename, const char *filecbot) if (power != nullptr) { - obj->SetPower(power); + assert(obj->Implements(ObjectInterfaceType::Powered)); + dynamic_cast(obj)->SetPower(power); + assert(power->Implements(ObjectInterfaceType::Transportable)); dynamic_cast(power)->SetTransporter(obj); } } diff --git a/src/object/scene_conditions.cpp b/src/object/scene_conditions.cpp index 59234b34..54402bc8 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/powered_object.h" #include "object/interface/transportable_object.h" void CSceneCondition::Read(CLevelParserLine* line) @@ -95,7 +96,10 @@ int CSceneCondition::CountObjects() continue; float energyLevel = -1; - CObject* power = obj->GetPower(); + CObject* power = nullptr; + if (obj->Implements(ObjectInterfaceType::Powered)) + power = dynamic_cast(obj)->GetPower(); + if (power != nullptr) { energyLevel = power->GetEnergy(); diff --git a/src/object/task/taskfire.cpp b/src/object/task/taskfire.cpp index 372294fc..fe134c43 100644 --- a/src/object/task/taskfire.cpp +++ b/src/object/task/taskfire.cpp @@ -24,6 +24,8 @@ #include "math/geometry.h" +#include "object/interface/powered_object.h" + #include "physics/physics.h" @@ -57,7 +59,6 @@ CTaskFire::~CTaskFire() bool CTaskFire::EventProcess(const Event &event) { - CObject* power; CPhysics* physics; Math::Matrix* mat; Math::Vector pos, speed, dir, vib; @@ -74,8 +75,9 @@ bool CTaskFire::EventProcess(const Event &event) m_lastSound -= event.rTime; m_progress += event.rTime*m_speed; - power = m_object->GetPower(); - if ( power != 0 ) + assert(m_object->Implements(ObjectInterfaceType::Powered)); + CObject* power = dynamic_cast(m_object)->GetPower(); + if (power != nullptr) { energy = power->GetEnergy(); if ( m_bOrganic ) fire = ENERGY_FIREi; @@ -267,7 +269,6 @@ bool CTaskFire::EventProcess(const Event &event) Error CTaskFire::Start(float delay) { - CObject* power; Math::Vector pos, goal, speed; float energy, fire; ObjectType type; @@ -309,8 +310,10 @@ Error CTaskFire::Start(float delay) } m_delay = delay; - power = m_object->GetPower(); - if ( power == 0 ) return ERR_FIRE_ENERGY; + assert(m_object->Implements(ObjectInterfaceType::Powered)); + CObject* power = dynamic_cast(m_object)->GetPower(); + if (power == nullptr) return ERR_FIRE_ENERGY; + energy = power->GetEnergy(); if ( m_bOrganic ) fire = m_delay*ENERGY_FIREi; else if ( m_bRay ) fire = m_delay*ENERGY_FIREr; diff --git a/src/object/task/taskmanip.cpp b/src/object/task/taskmanip.cpp index c2aec87e..2ae27e2c 100644 --- a/src/object/task/taskmanip.cpp +++ b/src/object/task/taskmanip.cpp @@ -28,6 +28,7 @@ #include "object/object_manager.h" #include "object/robotmain.h" #include "object/interface/carrier_object.h" +#include "object/interface/powered_object.h" #include "object/interface/transportable_object.h" #include "physics/physics.h" @@ -53,7 +54,10 @@ CTaskManip::CTaskManip(CObject* object) : CTask(object) m_hand = TMH_OPEN; assert(m_object->Implements(ObjectInterfaceType::Carrier)); - m_carrier = dynamic_cast(m_object); + m_carrierObject = dynamic_cast(m_object); + + assert(m_object->Implements(ObjectInterfaceType::Powered)); + m_poweredObject = dynamic_cast(m_object); } // Object's destructor. @@ -178,10 +182,6 @@ bool CTaskManip::EventProcess(const Event &event) void CTaskManip::InitAngle() { - CObject* power; - float max, energy; - int i; - if ( m_bSubm || m_bBee ) return; if ( m_arm == TMA_NEUTRAL || @@ -242,26 +242,20 @@ void CTaskManip::InitAngle() m_finalAngle[4] = -Math::PI*0.05f; // clamp remote } - for ( i=0 ; i<5 ; i++ ) + for (int i = 0; i < 5; i++) { m_initialAngle[i] = m_object->GetAngleZ(i+1); } - max = 0.0f; - for ( i=0 ; i<5 ; i++ ) + float max = 0.0f; + for (int i = 0; i < 5; i++) { max = Math::Max(max, fabs(m_initialAngle[i] - m_finalAngle[i])); } m_speed = (Math::PI*1.0f)/max; if ( m_speed > 3.0f ) m_speed = 3.0f; // piano, ma non troppo (?) - energy = 0.0f; - power = m_object->GetPower(); - if ( power != 0 ) - { - energy = power->GetEnergy(); - } - + float energy = GetObjectEnergy(m_object); if ( energy == 0.0f ) { m_speed *= 0.7f; // slower if more energy! @@ -322,23 +316,26 @@ Error CTaskManip::Start(TaskManipOrder order, TaskManipArm arm) type = m_object->GetType(); if ( type == OBJECT_BEE ) // bee? { - if ( m_carrier->GetCargo() == 0 ) + if (m_carrierObject->GetCargo() == nullptr) { if ( !m_physics->GetLand() ) return ERR_MANIP_FLY; other = SearchTakeUnderObject(m_targetPos, MARGIN_BEE); - if ( other == 0 ) return ERR_MANIP_NIL; + if (other == nullptr) return ERR_MANIP_NIL; + assert(other->Implements(ObjectInterfaceType::Transportable)); - m_carrier->SetCargo(other); // takes the ball + m_carrierObject->SetCargo(other); // takes the ball 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_carrier->GetCargo(); // other = ball - m_carrier->SetCargo(0); // lick the ball - dynamic_cast(other)->SetTransporter(0); + other = m_carrierObject->GetCargo(); // other = ball + assert(other->Implements(ObjectInterfaceType::Transportable)); + + m_carrierObject->SetCargo(nullptr); // lick the ball + dynamic_cast(other)->SetTransporter(nullptr); pos = m_object->GetPosition(0); pos.y -= 3.0f; other->SetPosition(0, pos); @@ -366,7 +363,7 @@ Error CTaskManip::Start(TaskManipOrder order, TaskManipArm arm) } m_energy = 0.0f; - power = m_object->GetPower(); + power = m_poweredObject->GetPower(); if ( power != 0 ) { m_energy = power->GetEnergy(); @@ -390,7 +387,7 @@ Error CTaskManip::Start(TaskManipOrder order, TaskManipArm arm) if ( order == TMO_AUTO ) { - if ( m_carrier->GetCargo() == 0 ) + if (m_carrierObject->GetCargo() == nullptr) { m_order = TMO_GRAB; } @@ -404,11 +401,11 @@ Error CTaskManip::Start(TaskManipOrder order, TaskManipArm arm) m_order = order; } - if ( m_order == TMO_GRAB && m_carrier->GetCargo() != 0 ) + if (m_order == TMO_GRAB && m_carrierObject->GetCargo() != nullptr) { return ERR_MANIP_BUSY; } - if ( m_order == TMO_DROP && m_carrier->GetCargo() == 0 ) + if (m_order == TMO_DROP && m_carrierObject->GetCargo() == nullptr) { return ERR_MANIP_EMPTY; } @@ -432,7 +429,7 @@ Error CTaskManip::Start(TaskManipOrder order, TaskManipArm arm) } else if ( other != 0 && oDist < fDist ) { - if ( other->GetPower() == 0 ) return ERR_MANIP_NIL; + if (! ObjectHasPowerCell(other)) return ERR_MANIP_NIL; m_targetPos = oPos; m_angle = oAngle; m_height = oHeight; @@ -456,7 +453,7 @@ Error CTaskManip::Start(TaskManipOrder order, TaskManipArm arm) } if ( m_arm == TMA_POWER ) { - if ( m_object->GetPower() == 0 ) return ERR_MANIP_NIL; + if (m_poweredObject->GetPower() == nullptr) return ERR_MANIP_NIL; } } @@ -465,7 +462,7 @@ Error CTaskManip::Start(TaskManipOrder order, TaskManipArm arm) if ( m_arm == TMA_FFRONT ) { other = SearchOtherObject(true, oPos, oDist, oAngle, oHeight); - if ( other != 0 && other->GetPower() == 0 ) + if (other != nullptr && ObjectHasPowerCell(other)) { m_targetPos = oPos; m_angle = oAngle; @@ -484,7 +481,7 @@ Error CTaskManip::Start(TaskManipOrder order, TaskManipArm arm) } if ( m_arm == TMA_POWER ) { - if ( m_object->GetPower() != 0 ) return ERR_MANIP_OCC; + if (m_poweredObject->GetPower() != nullptr) return ERR_MANIP_OCC; } } @@ -504,7 +501,7 @@ Error CTaskManip::Start(TaskManipOrder order, TaskManipArm arm) if ( m_timeLimit < 0.5f ) m_timeLimit = 0.5f; } - if ( m_carrier->GetCargo() == 0 ) // not carrying anything? + if (m_carrierObject->GetCargo() == nullptr) // not carrying anything? { m_hand = TMH_OPEN; // open clamp } @@ -629,7 +626,7 @@ Error CTaskManip::IsEnded() { if ( m_bSubm ) m_speed = 1.0f/1.5f; if ( !TransporterTakeObject() && - m_carrier->GetCargo() == 0 ) + m_carrierObject->GetCargo() == nullptr) { m_hand = TMH_OPEN; // reopens the clamp m_arm = TMA_NEUTRAL; @@ -658,8 +655,8 @@ Error CTaskManip::IsEnded() if ( m_step == 1 ) { if ( m_bSubm ) m_speed = 1.0f/0.7f; - cargo = m_carrier->GetCargo(); - if ( TransporterDeposeObject() ) + cargo = m_carrierObject->GetCargo(); + if (TransporterDeposeObject()) { if ( (m_arm == TMA_OTHER || m_arm == TMA_POWER ) && @@ -668,7 +665,7 @@ Error CTaskManip::IsEnded() { m_sound->Play(SOUND_POWERON, m_object->GetPosition(0)); } - if ( cargo != 0 && m_cargoType == OBJECT_METAL && m_arm == TMA_FFRONT ) + if (cargo != nullptr && m_cargoType == OBJECT_METAL && m_arm == TMA_FFRONT) { m_main->ShowDropZone(cargo, m_object); // shows buildable area } @@ -696,9 +693,7 @@ Error CTaskManip::IsEnded() bool CTaskManip::Abort() { - int i; - - if ( m_carrier->GetCargo() == 0 ) // not carrying anything? + if (m_carrierObject->GetCargo() == nullptr) // not carrying anything? { m_hand = TMH_OPEN; // open clamp m_arm = TMA_NEUTRAL; @@ -712,7 +707,7 @@ bool CTaskManip::Abort() if ( !m_bSubm ) { - for ( i=0 ; i<5 ; i++ ) + for (int i = 0; i < 5; i++) { m_object->SetAngleZ(i+1, m_finalAngle[i]); } @@ -957,9 +952,7 @@ CObject* CTaskManip::SearchOtherObject(bool bAdvance, Math::Vector &pos, float &height) { Character* character; - CObject* pPower; Math::Matrix* mat; - ObjectType type, powerType; float iAngle, oAngle, oLimit, aLimit, dLimit; distance = 1000000.0f; @@ -989,7 +982,7 @@ CObject* CTaskManip::SearchOtherObject(bool bAdvance, Math::Vector &pos, { if ( pObj == m_object ) continue; // yourself? - type = pObj->GetType(); + ObjectType type = pObj->GetType(); if ( type != OBJECT_MOBILEfa && type != OBJECT_MOBILEta && type != OBJECT_MOBILEwa && @@ -1022,13 +1015,15 @@ CObject* CTaskManip::SearchOtherObject(bool bAdvance, Math::Vector &pos, type != OBJECT_LABO && type != OBJECT_NUCLEAR ) continue; - pPower = pObj->GetPower(); - if ( pPower != 0 ) + assert(pObj->Implements(ObjectInterfaceType::Powered)); + CObject* power = dynamic_cast(pObj)->GetPower(); + if (power != nullptr) { - if ( pPower->GetLock() ) continue; - if ( pPower->GetZoomY(0) != 1.0f ) continue; + if (power->GetLock()) continue; + if (power->GetZoomY(0) != 1.0f) continue; - powerType = pPower->GetType(); + // TODO: this is probably redundant + ObjectType powerType = power->GetType(); if ( powerType == OBJECT_NULL || powerType == OBJECT_FIX ) continue; } @@ -1087,16 +1082,12 @@ CObject* CTaskManip::SearchOtherObject(bool bAdvance, Math::Vector &pos, bool CTaskManip::TransporterTakeObject() { - CObject* cargo; - CObject* other; - Math::Matrix matRotate; - Math::Vector pos; - float angle, dist; - - if ( m_arm == TMA_GRAB ) // takes immediately? + if (m_arm == TMA_GRAB) // takes immediately? { - cargo = m_carrier->GetCargo(); - if ( cargo == 0 ) return false; // nothing to take? + CObject* cargo = m_carrierObject->GetCargo(); + if (cargo == nullptr) return false; // nothing to take? + assert(cargo->Implements(ObjectInterfaceType::Transportable)); + m_cargoType = cargo->GetType(); if ( m_object->GetType() == OBJECT_HUMAN || @@ -1115,7 +1106,7 @@ bool CTaskManip::TransporterTakeObject() 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 + Math::Vector pos = Math::Vector(1.1f, -1.0f, 1.0f); // relative cargo->SetPosition(0, pos); cargo->SetAngleX(0, 0.0f); cargo->SetAngleY(0, 0.0f); @@ -1126,20 +1117,24 @@ bool CTaskManip::TransporterTakeObject() 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) + Math::Vector pos = Math::Vector(4.7f, 0.0f, 0.0f); // relative to the hand (lem4) cargo->SetPosition(0, pos); cargo->SetAngleX(0, 0.0f); cargo->SetAngleZ(0, Math::PI/2.0f); cargo->SetAngleY(0, 0.0f); } - m_carrier->SetCargo(cargo); // takes + m_carrierObject->SetCargo(cargo); // takes } - if ( m_arm == TMA_FFRONT ) // takes on the ground in front? + if (m_arm == TMA_FFRONT) // takes on the ground in front? { - cargo = SearchTakeFrontObject(false, pos, dist, angle); - if ( cargo == 0 ) return false; // nothing to take? + Math::Vector pos; + float dist = 0.0f, angle = 0.0f; + CObject* cargo = SearchTakeFrontObject(false, pos, dist, angle); + if (cargo == nullptr) return false; // nothing to take? + assert(cargo->Implements(ObjectInterfaceType::Transportable)); + m_cargoType = cargo->GetType(); if ( m_bSubm ) @@ -1165,13 +1160,17 @@ bool CTaskManip::TransporterTakeObject() cargo->SetAngleY(0, 0.0f); } - m_carrier->SetCargo(cargo); // takes + m_carrierObject->SetCargo(cargo); // takes } - if ( m_arm == TMA_FBACK ) // takes on the ground behind? + if (m_arm == TMA_FBACK) // takes on the ground behind? { - cargo = SearchTakeBackObject(false, pos, dist, angle); - if ( cargo == 0 ) return false; // nothing to take? + Math::Vector pos; + float dist = 0.0f, angle = 0.0f; + CObject* cargo = SearchTakeBackObject(false, pos, dist, angle); + if (cargo == nullptr) return false; // nothing to take? + assert(cargo->Implements(ObjectInterfaceType::Transportable)); + m_cargoType = cargo->GetType(); dynamic_cast(cargo)->SetTransporter(m_object); @@ -1183,36 +1182,43 @@ bool CTaskManip::TransporterTakeObject() cargo->SetAngleZ(0, Math::PI/2.0f); cargo->SetAngleY(0, 0.0f); - m_carrier->SetCargo(cargo); // takes + m_carrierObject->SetCargo(cargo); // takes } - if ( m_arm == TMA_POWER ) // takes battery in the back? + if (m_arm == TMA_POWER) // takes battery in the back? { - cargo = m_object->GetPower(); - if ( cargo == 0 ) return false; // no battery? + CObject* cargo = m_poweredObject->GetPower(); + if (cargo == nullptr) return false; // no battery? + assert(cargo->Implements(ObjectInterfaceType::Transportable)); + m_cargoType = cargo->GetType(); - pos = Math::Vector(4.7f, 0.0f, 0.0f); // relative to the hand (lem4) + Math::Vector pos = Math::Vector(4.7f, 0.0f, 0.0f); // relative to the hand (lem4) cargo->SetPosition(0, pos); cargo->SetAngleX(0, 0.0f); cargo->SetAngleZ(0, Math::PI/2.0f); cargo->SetAngleY(0, 0.0f); dynamic_cast(cargo)->SetTransporterPart(3); // takes with the hand - m_object->SetPower(0); - m_carrier->SetCargo(cargo); // takes + m_poweredObject->SetPower(nullptr); + m_carrierObject->SetCargo(cargo); // takes } - if ( m_arm == TMA_OTHER ) // battery takes from friend? + if (m_arm == TMA_OTHER) // battery takes from friend? { - other = SearchOtherObject(false, pos, dist, angle, m_height); - if ( other == 0 ) return false; + Math::Vector pos; + float dist = 0.0f, angle = 0.0f; + CObject* other = SearchOtherObject(false, pos, dist, angle, m_height); + if (other == nullptr) return false; + assert(other->Implements(ObjectInterfaceType::Powered)); + + CObject* cargo = dynamic_cast(other)->GetPower(); + if (cargo == nullptr) return false; // the other does not have a battery? + assert(cargo->Implements(ObjectInterfaceType::Transportable)); - cargo = other->GetPower(); - if ( cargo == 0 ) return false; // the other does not have a battery? m_cargoType = cargo->GetType(); - other->SetPower(0); + dynamic_cast(other)->SetPower(nullptr); dynamic_cast(cargo)->SetTransporter(m_object); dynamic_cast(cargo)->SetTransporterPart(3); // takes with the hand @@ -1222,7 +1228,7 @@ bool CTaskManip::TransporterTakeObject() cargo->SetAngleZ(0, Math::PI/2.0f); cargo->SetAngleY(0, 0.0f); - m_carrier->SetCargo(cargo); // takes + m_carrierObject->SetCargo(cargo); // takes } return true; @@ -1232,21 +1238,16 @@ bool CTaskManip::TransporterTakeObject() bool CTaskManip::TransporterDeposeObject() { - Character* character; - CObject* cargo; - CObject* other; - Math::Matrix* mat; - Math::Vector pos; - float angle, dist; - - if ( m_arm == TMA_FFRONT ) // deposits on the ground in front? + if (m_arm == TMA_FFRONT) // deposits on the ground in front? { - cargo = m_carrier->GetCargo(); - if ( cargo == 0 ) return false; // nothing transported? + CObject* cargo = m_carrierObject->GetCargo(); + if (cargo == nullptr) return false; // nothing transported? + assert(cargo->Implements(ObjectInterfaceType::Transportable)); + m_cargoType = cargo->GetType(); - mat = cargo->GetWorldMatrix(0); - pos = Transform(*mat, Math::Vector(0.0f, 1.0f, 0.0f)); + Math::Matrix* mat = cargo->GetWorldMatrix(0); + Math::Vector pos = Transform(*mat, Math::Vector(0.0f, 1.0f, 0.0f)); m_terrain->AdjustToFloor(pos); cargo->SetPosition(0, pos); cargo->SetAngleY(0, m_object->GetAngleY(0)+Math::PI/2.0f); @@ -1255,17 +1256,19 @@ bool CTaskManip::TransporterDeposeObject() cargo->FloorAdjust(); // plate well on the ground dynamic_cast(cargo)->SetTransporter(0); - m_carrier->SetCargo(0); // deposit + m_carrierObject->SetCargo(nullptr); // deposit } - if ( m_arm == TMA_FBACK ) // deposited on the ground behind? + if (m_arm == TMA_FBACK) // deposited on the ground behind? { - cargo = m_carrier->GetCargo(); - if ( cargo == 0 ) return false; // nothing transported? + CObject* cargo = m_carrierObject->GetCargo(); + if (cargo == nullptr) return false; // nothing transported? + assert(cargo->Implements(ObjectInterfaceType::Transportable)); + m_cargoType = cargo->GetType(); - mat = cargo->GetWorldMatrix(0); - pos = Transform(*mat, Math::Vector(0.0f, 1.0f, 0.0f)); + Math::Matrix* mat = cargo->GetWorldMatrix(0); + Math::Vector pos = Transform(*mat, Math::Vector(0.0f, 1.0f, 0.0f)); m_terrain->AdjustToFloor(pos); cargo->SetPosition(0, pos); cargo->SetAngleY(0, m_object->GetAngleY(0)+Math::PI/2.0f); @@ -1273,53 +1276,61 @@ bool CTaskManip::TransporterDeposeObject() cargo->SetAngleZ(0, 0.0f); dynamic_cast(cargo)->SetTransporter(0); - m_carrier->SetCargo(0); // deposit + m_carrierObject->SetCargo(nullptr); // deposit } - if ( m_arm == TMA_POWER ) // deposits battery in the back? + if (m_arm == TMA_POWER) // deposits battery in the back? { - cargo = m_carrier->GetCargo(); - if ( cargo == 0 ) return false; // nothing transported? + CObject* cargo = m_carrierObject->GetCargo(); + if (cargo == nullptr) return false; // nothing transported? + assert(cargo->Implements(ObjectInterfaceType::Transportable)); + m_cargoType = cargo->GetType(); - if ( m_object->GetPower() != 0 ) return false; + if (m_poweredObject->GetPower() != nullptr) return false; dynamic_cast(cargo)->SetTransporter(m_object); dynamic_cast(cargo)->SetTransporterPart(0); // carried by the base - character = m_object->GetCharacter(); + Character* character = m_object->GetCharacter(); cargo->SetPosition(0, character->posPower); cargo->SetAngleY(0, 0.0f); cargo->SetAngleX(0, 0.0f); cargo->SetAngleZ(0, 0.0f); - m_object->SetPower(cargo); // uses - m_carrier->SetCargo(0); + m_poweredObject->SetPower(cargo); // uses + m_carrierObject->SetCargo(nullptr); } - if ( m_arm == TMA_OTHER ) // deposits battery on friend? + if (m_arm == TMA_OTHER) // deposits battery on friend? { - other = SearchOtherObject(false, pos, dist, angle, m_height); - if ( other == 0 ) return false; + Math::Vector pos; + float angle = 0.0f, dist = 0.0f; - cargo = other->GetPower(); - if ( cargo != 0 ) return false; // the other already has a battery? + CObject* other = SearchOtherObject(false, pos, dist, angle, m_height); + if (other == nullptr) return false; + assert(other->Implements(ObjectInterfaceType::Powered)); + + CObject* cargo = dynamic_cast(other)->GetPower(); + if (cargo != nullptr) return false; // the other already has a battery? + + cargo = m_carrierObject->GetCargo(); + if (cargo == nullptr) return false; + assert(cargo->Implements(ObjectInterfaceType::Transportable)); - cargo = m_carrier->GetCargo(); - if ( cargo == 0 ) return false; m_cargoType = cargo->GetType(); - other->SetPower(cargo); + dynamic_cast(other)->SetPower(cargo); dynamic_cast(cargo)->SetTransporter(other); - character = other->GetCharacter(); + Character* character = other->GetCharacter(); cargo->SetPosition(0, character->posPower); cargo->SetAngleY(0, 0.0f); cargo->SetAngleX(0, 0.0f); cargo->SetAngleZ(0, 0.0f); dynamic_cast(cargo)->SetTransporterPart(0); // carried by the base - m_carrier->SetCargo(0); // deposit + m_carrierObject->SetCargo(nullptr); // deposit } return true; @@ -1353,9 +1364,7 @@ bool CTaskManip::IsFreeDeposeObject(Math::Vector pos) void CTaskManip::SoundManip(float time, float amplitude, float frequency) { - int i; - - i = m_sound->Play(SOUND_MANIP, m_object->GetPosition(0), 0.0f, 0.3f*frequency, true); + int i = m_sound->Play(SOUND_MANIP, m_object->GetPosition(0), 0.0f, 0.3f*frequency, true); m_sound->AddEnvelope(i, 0.5f*amplitude, 1.0f*frequency, 0.1f, SOPER_CONTINUE); m_sound->AddEnvelope(i, 0.5f*amplitude, 1.0f*frequency, time-0.1f, SOPER_CONTINUE); m_sound->AddEnvelope(i, 0.0f, 0.3f*frequency, 0.1f, SOPER_STOP); diff --git a/src/object/task/taskmanip.h b/src/object/task/taskmanip.h index 1ec7a762..16b686fc 100644 --- a/src/object/task/taskmanip.h +++ b/src/object/task/taskmanip.h @@ -29,6 +29,7 @@ class CCarrierObject; +class CPoweredObject; enum TaskManipOrder { @@ -80,7 +81,8 @@ protected: void SoundManip(float time, float amplitude=1.0f, float frequency=1.0f); protected: - CCarrierObject* m_carrier; + CCarrierObject* m_carrierObject; + CPoweredObject* m_poweredObject; TaskManipOrder m_order; TaskManipArm m_arm; TaskManipHand m_hand; diff --git a/src/object/task/taskrecover.cpp b/src/object/task/taskrecover.cpp index a4c041d2..26204006 100644 --- a/src/object/task/taskrecover.cpp +++ b/src/object/task/taskrecover.cpp @@ -30,6 +30,7 @@ #include "object/object_manager.h" #include "object/robotmain.h" +#include "object/interface/powered_object.h" const float ENERGY_RECOVER = 0.25f; // energy consumed by recovery @@ -56,7 +57,6 @@ CTaskRecover::~CTaskRecover() bool CTaskRecover::EventProcess(const Event &event) { - CObject* power; Math::Vector pos, speed; Math::Point dim; float a, g, cirSpeed, angle, energy, dist, linSpeed; @@ -103,8 +103,9 @@ bool CTaskRecover::EventProcess(const Event &event) if ( m_phase == TRP_OPER ) { - power = m_object->GetPower(); - if ( power != 0 ) + assert(m_object->Implements(ObjectInterfaceType::Powered)); + CObject* power = dynamic_cast(m_object)->GetPower(); + if (power != nullptr) { energy = power->GetEnergy(); energy -= event.rTime * ENERGY_RECOVER / power->GetCapacity() * m_speed; @@ -177,26 +178,21 @@ bool CTaskRecover::EventProcess(const Event &event) Error CTaskRecover::Start() { - CObject* power; - Math::Matrix* mat; - Math::Vector pos, iPos, oPos; - float energy; - - ObjectType type; - m_bError = true; // operation impossible if ( !m_physics->GetLand() ) return ERR_RECOVER_VEH; - type = m_object->GetType(); + ObjectType type = m_object->GetType(); if ( type != OBJECT_MOBILErr ) return ERR_RECOVER_VEH; - power = m_object->GetPower(); - if ( power == 0 ) return ERR_RECOVER_ENERGY; - energy = power->GetEnergy(); + assert(m_object->Implements(ObjectInterfaceType::Powered)); + CObject* power = dynamic_cast(m_object)->GetPower(); + if (power == nullptr) return ERR_RECOVER_ENERGY; + + float energy = power->GetEnergy(); if ( energy < ENERGY_RECOVER/power->GetCapacity()+0.05f ) return ERR_RECOVER_ENERGY; - mat = m_object->GetWorldMatrix(0); - pos = Math::Vector(RECOVER_DIST, 3.3f, 0.0f); + Math::Matrix* mat = m_object->GetWorldMatrix(0); + Math::Vector pos = Math::Vector(RECOVER_DIST, 3.3f, 0.0f); pos = Transform(*mat, pos); // position in front m_recoverPos = pos; @@ -204,8 +200,8 @@ Error CTaskRecover::Start() if ( m_ruin == 0 ) return ERR_RECOVER_NULL; m_ruin->SetLock(true); // ruin no longer usable - iPos = m_object->GetPosition(0); - oPos = m_ruin->GetPosition(0); + Math::Vector iPos = m_object->GetPosition(0); + Math::Vector oPos = m_ruin->GetPosition(0); m_angle = Math::RotateAngle(oPos.x-iPos.x, iPos.z-oPos.z); // CW ! m_metal = 0; diff --git a/src/object/task/taskreset.cpp b/src/object/task/taskreset.cpp index 64d5bd6b..5748618c 100644 --- a/src/object/task/taskreset.cpp +++ b/src/object/task/taskreset.cpp @@ -24,6 +24,7 @@ #include "object/object_manager.h" #include "object/robotmain.h" #include "object/interface/carrier_object.h" +#include "object/interface/powered_object.h" #include "object/interface/transportable_object.h" @@ -222,10 +223,6 @@ Error CTaskReset::Start(Math::Vector goal, Math::Vector angle) Error CTaskReset::IsEnded() { - CObject* power; - float dist; - int i; - if ( !m_main->GetNiceReset() ) // quick return? { return ERR_STOP; @@ -237,7 +234,7 @@ Error CTaskReset::IsEnded() if ( m_phase == TRSP_ZOUT ) { - dist = Math::Distance(m_begin, m_goal); + float dist = Math::Distance(m_begin, m_goal); m_phase = TRSP_MOVE; m_speed = 1.0f/(dist*RESET_DELAY_MOVE/100.0f); m_progress = 0.0f; @@ -249,7 +246,7 @@ Error CTaskReset::IsEnded() m_object->SetPosition(0, m_goal); m_object->SetAngle(0, m_angle); - i = m_sound->Play(SOUND_GGG, m_goal, 1.0f, 0.5f, true); + int i = m_sound->Play(SOUND_GGG, m_goal, 1.0f, 0.5f, true); m_sound->AddEnvelope(i, 0.0f, 2.0f, RESET_DELAY_ZOOM, SOPER_STOP); m_phase = TRSP_ZIN; @@ -261,14 +258,17 @@ Error CTaskReset::IsEnded() m_object->SetAngle(0, m_angle); m_object->SetZoom(0, 1.0f); - power = m_object->GetPower(); - if ( power != 0 ) + if (m_object->Implements(ObjectInterfaceType::Powered)) { - power->SetEnergy(power->GetCapacity()); // refueling + CObject* power = dynamic_cast(m_object)->GetPower(); + if (power != nullptr) + { + power->SetEnergy(power->GetCapacity()); // refueling + } } Program* program = m_object->GetResetRun(); - if(program != nullptr) + if (program != nullptr) { m_brain->AddProgram(program); m_brain->RunProgram(program); diff --git a/src/object/task/taskshield.cpp b/src/object/task/taskshield.cpp index 3d0ab2c7..f9641a27 100644 --- a/src/object/task/taskshield.cpp +++ b/src/object/task/taskshield.cpp @@ -29,6 +29,7 @@ #include "object/brain.h" #include "object/object_manager.h" #include "object/robotmain.h" +#include "object/interface/powered_object.h" #include "physics/physics.h" @@ -45,6 +46,9 @@ CTaskShield::CTaskShield(CObject* object) : CTask(object) m_rankSphere = -1; m_soundChannel = -1; m_effectLight = -1; + + assert(m_object->Implements(ObjectInterfaceType::Powered)); + m_poweredObject = dynamic_cast(m_object); } // Object's destructor. @@ -108,8 +112,8 @@ bool CTaskShield::EventProcess(const Event &event) { energy = (1.0f/ENERGY_TIME)*event.rTime; energy *= GetRadius()/RADIUS_SHIELD_MAX; - power = m_object->GetPower(); - if ( power != 0 ) + power = m_poweredObject->GetPower(); + if (power != nullptr) { power->SetEnergy(power->GetEnergy()-energy/power->GetCapacity()); } @@ -231,12 +235,6 @@ bool CTaskShield::EventProcess(const Event &event) Error CTaskShield::Start(TaskShieldMode mode, float delay) { - CObject* power; - Math::Matrix* mat; - Math::Vector pos, iPos, oPos, speed; - ObjectType type; - float energy; - if ( mode == TSM_DOWN ) { return Stop(); @@ -254,20 +252,20 @@ Error CTaskShield::Start(TaskShieldMode mode, float delay) if ( mode == TSM_START ) { Math::Point dim; - + m_object->SetShieldRadius(GetRadius()); - - mat = m_object->GetWorldMatrix(0); - pos = Math::Vector(7.0f, 15.0f, 0.0f); + + Math::Matrix* mat = m_object->GetWorldMatrix(0); + Math::Vector pos = Math::Vector(7.0f, 15.0f, 0.0f); pos = Transform(*mat, pos); // sphere position m_shieldPos = pos; - + pos = m_shieldPos; - speed = Math::Vector(0.0f, 0.0f, 0.0f); + Math::Vector speed = Math::Vector(0.0f, 0.0f, 0.0f); dim.x = GetRadius(); dim.y = dim.x; m_rankSphere = m_particle->CreateParticle(pos, speed, dim, Gfx::PARTISPHERE3, 2.0f, 0.0f, 0.0f); - + m_phase = TS_SHIELD; m_progress = 0.0f; m_speed = 1.0f/999.9f; @@ -277,29 +275,29 @@ Error CTaskShield::Start(TaskShieldMode mode, float delay) m_lastRay = 0.0f; m_lastIncrease = 0.0f; m_energyUsed = 0.0f; - + m_bError = false; // ok - + if ( m_object->GetSelect() ) { m_brain->UpdateInterface(); } return ERR_OK; } - - type = m_object->GetType(); + + ObjectType type = m_object->GetType(); if ( type != OBJECT_MOBILErs ) return ERR_SHIELD_VEH; m_bError = true; // operation impossible if ( !m_physics->GetLand() ) return ERR_SHIELD_VEH; - power = m_object->GetPower(); - if ( power == 0 ) return ERR_SHIELD_ENERGY; - energy = power->GetEnergy(); + CObject* power = m_poweredObject->GetPower(); + if (power == nullptr) return ERR_SHIELD_ENERGY; + float energy = power->GetEnergy(); if ( energy == 0.0f ) return ERR_SHIELD_ENERGY; - mat = m_object->GetWorldMatrix(0); - pos = Math::Vector(7.0f, 15.0f, 0.0f); + Math::Matrix* mat = m_object->GetWorldMatrix(0); + Math::Vector pos = Math::Vector(7.0f, 15.0f, 0.0f); pos = Transform(*mat, pos); // sphere position m_shieldPos = pos; @@ -382,7 +380,7 @@ Error CTaskShield::IsEnded() { m_object->SetShieldRadius(GetRadius()); - power = m_object->GetPower(); + power = m_poweredObject->GetPower(); if ( power == 0 ) { energy = 0.0f; diff --git a/src/object/task/taskshield.h b/src/object/task/taskshield.h index 00706e17..24c297c9 100644 --- a/src/object/task/taskshield.h +++ b/src/object/task/taskshield.h @@ -26,6 +26,7 @@ #include "math/vector.h" +class CPoweredObject; const float RADIUS_SHIELD_MIN = 40.0f; // minimum radius of the protected zone const float RADIUS_SHIELD_MAX = 100.0f; // maximum radius of the protected zone @@ -71,6 +72,7 @@ protected: float GetRadius(); protected: + CPoweredObject* m_poweredObject; TaskShieldPhase m_phase; float m_progress; float m_speed; diff --git a/src/object/task/tasktake.cpp b/src/object/task/tasktake.cpp index aeca7739..51fba805 100644 --- a/src/object/task/tasktake.cpp +++ b/src/object/task/tasktake.cpp @@ -29,6 +29,7 @@ #include "object/object_manager.h" #include "object/robotmain.h" #include "object/interface/carrier_object.h" +#include "object/interface/powered_object.h" #include "object/interface/transportable_object.h" #include "physics/physics.h" @@ -43,7 +44,10 @@ CTaskTake::CTaskTake(CObject* object) : CTask(object) m_arm = TTA_NEUTRAL; assert(m_object->Implements(ObjectInterfaceType::Carrier)); - m_carrier = dynamic_cast(m_object); + m_carrierObject = dynamic_cast(m_object); + + assert(m_object->Implements(ObjectInterfaceType::Powered)); + m_poweredObject = dynamic_cast(m_object); } // Object's destructor. @@ -87,35 +91,30 @@ bool CTaskTake::EventProcess(const Event &event) Error CTaskTake::Start() { - ObjectType type; - CObject* other; - float iAngle, oAngle, h; - Math::Vector pos; - m_height = 0.0f; m_step = 0; m_progress = 0.0f; - iAngle = m_object->GetAngleY(0); + float iAngle = m_object->GetAngleY(0); iAngle = Math::NormAngle(iAngle); // 0..2*Math::PI - oAngle = iAngle; + float oAngle = iAngle; m_bError = true; // operation impossible if ( !m_physics->GetLand() ) { - pos = m_object->GetPosition(0); - h = m_water->GetLevel(m_object); + Math::Vector pos = m_object->GetPosition(0); + float h = m_water->GetLevel(m_object); if ( pos.y < h ) return ERR_MANIP_WATER; // impossible under water return ERR_MANIP_FLY; } - type = m_object->GetType(); + ObjectType type = m_object->GetType(); if ( type != OBJECT_HUMAN && type != OBJECT_TECH ) return ERR_MANIP_VEH; m_physics->SetMotorSpeed(Math::Vector(0.0f, 0.0f, 0.0f)); - if (m_carrier->IsCarryingCargo()) + if (m_carrierObject->IsCarryingCargo()) m_order = TTO_DEPOSE; else m_order = TTO_TAKE; @@ -123,14 +122,16 @@ Error CTaskTake::Start() if ( m_order == TTO_TAKE ) { - pos = m_object->GetPosition(0); - h = m_water->GetLevel(m_object); + Math::Vector pos = m_object->GetPosition(0); + float h = m_water->GetLevel(m_object); if ( pos.y < h ) return ERR_MANIP_WATER; // impossible under water - other = SearchFriendObject(oAngle, 1.5f, Math::PI*0.50f); - if ( other != 0 && other->GetPower() != 0 ) + CObject* other = SearchFriendObject(oAngle, 1.5f, Math::PI*0.50f); + if (other != nullptr) assert(other->Implements(ObjectInterfaceType::Powered)); + + if (other != nullptr && dynamic_cast(other)->GetPower() != nullptr) { - type = other->GetPower()->GetType(); + type = dynamic_cast(other)->GetPower()->GetType(); if ( type == OBJECT_URANIUM ) return ERR_MANIP_RADIO; if ( type != OBJECT_FRET && type != OBJECT_STONE && @@ -150,7 +151,7 @@ Error CTaskTake::Start() else { other = SearchTakeObject(oAngle, 1.5f, Math::PI*0.45f); - if ( other == 0 ) return ERR_MANIP_NIL; + if ( other == nullptr ) return ERR_MANIP_NIL; type = other->GetType(); if ( type == OBJECT_URANIUM ) return ERR_MANIP_RADIO; //? m_camera->StartCentering(m_object, Math::PI*0.3f, 99.9f, 0.0f, 0.8f); @@ -165,8 +166,10 @@ Error CTaskTake::Start() //? if ( speed.x != 0.0f || //? speed.z != 0.0f ) return ERR_MANIP_MOTOR; - other = SearchFriendObject(oAngle, 1.5f, Math::PI*0.50f); - if ( other != 0 && other->GetPower() == 0 ) + CObject* other = SearchFriendObject(oAngle, 1.5f, Math::PI*0.50f); + if (other != nullptr) assert(other->Implements(ObjectInterfaceType::Powered)); + + if (other != nullptr && dynamic_cast(other)->GetPower() == nullptr ) { //? m_camera->StartCentering(m_object, Math::PI*0.3f, -Math::PI*0.1f, 0.0f, 0.8f); m_arm = TTA_FRIEND; @@ -192,15 +195,12 @@ Error CTaskTake::Start() Error CTaskTake::IsEnded() { - CObject* cargo; - float angle; - if ( m_engine->GetPause() ) return ERR_CONTINUE; if ( m_bError ) return ERR_STOP; if ( m_bTurn ) // preliminary rotation? { - angle = m_object->GetAngleY(0); + float angle = m_object->GetAngleY(0); angle = Math::NormAngle(angle); // 0..2*Math::PI if ( Math::TestAngle(angle, m_angle-Math::PI*0.01f, m_angle+Math::PI*0.01f) ) @@ -259,7 +259,7 @@ Error CTaskTake::IsEnded() { if ( m_step == 1 ) { - cargo = m_carrier->GetCargo(); + CObject* cargo = m_carrierObject->GetCargo(); TransporterDeposeObject(); if ( m_arm == TTA_FRIEND && (m_cargoType == OBJECT_POWER || @@ -267,7 +267,7 @@ Error CTaskTake::IsEnded() { m_sound->Play(SOUND_POWERON, m_object->GetPosition(0)); } - if ( cargo != 0 && m_cargoType == OBJECT_METAL && m_arm == TTA_FFRONT ) + if ( cargo != nullptr && m_cargoType == OBJECT_METAL && m_arm == TTA_FFRONT ) { m_main->ShowDropZone(cargo, m_object); // shows buildable area } @@ -361,26 +361,20 @@ CObject* CTaskTake::SearchTakeObject(float &angle, CObject* CTaskTake::SearchFriendObject(float &angle, float dLimit, float aLimit) { - Character* character; - CObject* pPower; - Math::Matrix* mat; - ObjectType type, powerType; - float iAngle, distance; - if (m_object->GetCrashSphereCount() == 0) return 0; auto crashSphere = m_object->GetFirstCrashSphere(); Math::Vector iPos = crashSphere.sphere.pos; float iRad = crashSphere.sphere.radius; - iAngle = m_object->GetAngleY(0); + float iAngle = m_object->GetAngleY(0); iAngle = Math::NormAngle(iAngle); // 0..2*Math::PI for (CObject* pObj : CObjectManager::GetInstancePointer()->GetAllObjects()) { if ( pObj == m_object ) continue; // yourself? - type = pObj->GetType(); + ObjectType type = pObj->GetType(); if ( type != OBJECT_MOBILEfa && type != OBJECT_MOBILEta && type != OBJECT_MOBILEwa && @@ -413,22 +407,24 @@ CObject* CTaskTake::SearchFriendObject(float &angle, type != OBJECT_LABO && type != OBJECT_NUCLEAR ) continue; - pPower = pObj->GetPower(); - if ( pPower != 0 ) - { - if ( pPower->GetLock() ) continue; - if ( pPower->GetZoomY(0) != 1.0f ) continue; + assert(pObj->Implements(ObjectInterfaceType::Powered)); - powerType = pPower->GetType(); + CObject* power = dynamic_cast(pObj)->GetPower(); + if (power != nullptr) + { + if ( power->GetLock() ) continue; + if ( power->GetZoomY(0) != 1.0f ) continue; + + ObjectType powerType = power->GetType(); if ( powerType == OBJECT_NULL || powerType == OBJECT_FIX ) continue; } - mat = pObj->GetWorldMatrix(0); - character = pObj->GetCharacter(); + Math::Matrix* mat = pObj->GetWorldMatrix(0); + Character* character = pObj->GetCharacter(); Math::Vector oPos = Transform(*mat, character->posPower); - distance = fabs(Math::Distance(oPos, iPos) - (iRad+1.0f)); + float distance = fabs(Math::Distance(oPos, iPos) - (iRad+1.0f)); if ( distance <= dLimit ) { angle = Math::RotateAngle(oPos.x-iPos.x, iPos.z-oPos.z); // CW ! @@ -448,16 +444,14 @@ CObject* CTaskTake::SearchFriendObject(float &angle, bool CTaskTake::TransporterTakeObject() { - CObject* cargo; - CObject* other; - Math::Matrix matRotate; - float angle; - - if ( m_arm == TTA_FFRONT ) // takes on the ground in front? + if (m_arm == TTA_FFRONT) // takes on the ground in front? { //? cargo = SearchTakeObject(angle, 1.5f, Math::PI*0.04f); - cargo = SearchTakeObject(angle, 1.5f, Math::PI*0.15f); //OK 1.9 - if ( cargo == 0 ) return false; // rien � prendre ? + float angle = 0.0f; + CObject* cargo = SearchTakeObject(angle, 1.5f, Math::PI*0.15f); //OK 1.9 + if (cargo == nullptr) return false; // rien � prendre ? + assert(cargo->Implements(ObjectInterfaceType::Transportable)); + m_cargoType = cargo->GetType(); dynamic_cast(cargo)->SetTransporter(m_object); @@ -469,19 +463,23 @@ bool CTaskTake::TransporterTakeObject() cargo->SetAngleX(0, 0.0f); cargo->SetAngleZ(0, 0.8f); - m_carrier->SetCargo(cargo); // takes + m_carrierObject->SetCargo(cargo); // takes } - if ( m_arm == TTA_FRIEND ) // takes friend's battery? + if (m_arm == TTA_FRIEND) // takes friend's battery? { - other = SearchFriendObject(angle, 1.5f, Math::PI*0.04f); - if ( other == 0 ) return false; + float angle = 0.0f; + CObject* other = SearchFriendObject(angle, 1.5f, Math::PI*0.04f); + if (other == nullptr) return false; + assert(other->Implements(ObjectInterfaceType::Powered)); + + CObject* cargo = dynamic_cast(other)->GetPower(); + if (cargo == nullptr) return false; // the other does not have a battery? + assert(cargo->Implements(ObjectInterfaceType::Transportable)); - cargo = other->GetPower(); - if ( cargo == 0 ) return false; // the other does not have a battery? m_cargoType = cargo->GetType(); - other->SetPower(0); + dynamic_cast(other)->SetPower(nullptr); dynamic_cast(cargo)->SetTransporter(m_object); dynamic_cast(cargo)->SetTransporterPart(4); // takes with the hand @@ -491,7 +489,7 @@ bool CTaskTake::TransporterTakeObject() cargo->SetAngleX(0, 0.0f); cargo->SetAngleZ(0, 0.8f); - m_carrier->SetCargo(cargo); // takes + m_carrierObject->SetCargo(cargo); // takes } return true; @@ -501,21 +499,16 @@ bool CTaskTake::TransporterTakeObject() bool CTaskTake::TransporterDeposeObject() { - Character* character; - CObject* cargo; - CObject* other; - Math::Matrix* mat; - Math::Vector pos; - float angle; - if ( m_arm == TTA_FFRONT ) // deposes on the ground in front? { - cargo = m_carrier->GetCargo(); - if ( cargo == 0 ) return false; // does nothing? + CObject* cargo = m_carrierObject->GetCargo(); + if (cargo == nullptr) return false; // does nothing? + assert(cargo->Implements(ObjectInterfaceType::Transportable)); + m_cargoType = cargo->GetType(); - mat = cargo->GetWorldMatrix(0); - pos = Transform(*mat, Math::Vector(-0.5f, 1.0f, 0.0f)); + Math::Matrix* mat = cargo->GetWorldMatrix(0); + Math::Vector pos = Transform(*mat, Math::Vector(-0.5f, 1.0f, 0.0f)); m_terrain->AdjustToFloor(pos); cargo->SetPosition(0, pos); cargo->SetAngleY(0, m_object->GetAngleY(0)+Math::PI/2.0f); @@ -523,33 +516,36 @@ bool CTaskTake::TransporterDeposeObject() cargo->SetAngleZ(0, 0.0f); cargo->FloorAdjust(); // plate well on the ground - dynamic_cast(cargo)->SetTransporter(0); - m_carrier->SetCargo(0); // deposit + dynamic_cast(cargo)->SetTransporter(nullptr); + m_carrierObject->SetCargo(nullptr); // deposit } if ( m_arm == TTA_FRIEND ) // deposes battery on friends? { - other = SearchFriendObject(angle, 1.5f, Math::PI*0.04f); - if ( other == 0 ) return false; + float angle = 0.0f; + CObject* other = SearchFriendObject(angle, 1.5f, Math::PI*0.04f); + if (other == nullptr) return false; + assert(other->Implements(ObjectInterfaceType::Powered)); - cargo = other->GetPower(); - if ( cargo != 0 ) return false; // the other already has a battery? + CObject* cargo = dynamic_cast(other)->GetPower(); + if (cargo != nullptr) return false; // the other already has a battery? + assert(cargo->Implements(ObjectInterfaceType::Transportable)); - cargo = m_carrier->GetCargo(); - if ( cargo == 0 ) return false; + cargo = m_carrierObject->GetCargo(); + if (cargo == nullptr) return false; m_cargoType = cargo->GetType(); - other->SetPower(cargo); + dynamic_cast(other)->SetPower(cargo); dynamic_cast(cargo)->SetTransporter(other); - character = other->GetCharacter(); + Character* character = other->GetCharacter(); cargo->SetPosition(0, character->posPower); cargo->SetAngleY(0, 0.0f); cargo->SetAngleX(0, 0.0f); cargo->SetAngleZ(0, 0.0f); dynamic_cast(cargo)->SetTransporterPart(0); // carried by the base - m_carrier->SetCargo(0); // deposit + m_carrierObject->SetCargo(nullptr); // deposit } return true; diff --git a/src/object/task/tasktake.h b/src/object/task/tasktake.h index b95f4598..b2193dbf 100644 --- a/src/object/task/tasktake.h +++ b/src/object/task/tasktake.h @@ -27,6 +27,7 @@ class CCarrierObject; +class CPoweredObject; enum TaskTakeOrder @@ -64,7 +65,8 @@ protected: bool IsFreeDeposeObject(Math::Vector pos); protected: - CCarrierObject* m_carrier; + CCarrierObject* m_carrierObject; + CPoweredObject* m_poweredObject; TaskTakeOrder m_order; TaskTakeArm m_arm; int m_step; diff --git a/src/object/task/taskterraform.cpp b/src/object/task/taskterraform.cpp index c3b30ccb..f84ece1c 100644 --- a/src/object/task/taskterraform.cpp +++ b/src/object/task/taskterraform.cpp @@ -33,6 +33,7 @@ #include "object/robotmain.h" #include "object/motion/motionant.h" #include "object/motion/motionspider.h" +#include "object/interface/powered_object.h" #include "object/interface/programmable_object.h" #include "physics/physics.h" @@ -49,6 +50,9 @@ CTaskTerraform::CTaskTerraform(CObject* object) : CTask(object) { m_lastParticle = 0.0f; m_soundChannel = -1; + + assert(m_object->Implements(ObjectInterfaceType::Powered)); + m_poweredObject = dynamic_cast(object); } // Object's destructor. @@ -91,8 +95,8 @@ bool CTaskTerraform::EventProcess(const Event &event) m_object->SetZoom(0, 1.0f+m_progress*0.2f); - power = m_object->GetPower(); - if ( power != 0 ) + power = m_poweredObject->GetPower(); + if (power != nullptr) { power->SetZoom(0, 1.0f+m_progress*1.0f); @@ -203,7 +207,7 @@ Error CTaskTerraform::Start() type = m_object->GetType(); if ( type != OBJECT_MOBILErt ) return ERR_TERRA_VEH; - power = m_object->GetPower(); + power = m_poweredObject->GetPower(); if ( power == 0 ) return ERR_TERRA_ENERGY; energy = power->GetEnergy(); if ( energy < ENERGY_TERRA/power->GetCapacity()+0.05f ) return ERR_TERRA_ENERGY; @@ -259,8 +263,8 @@ Error CTaskTerraform::IsEnded() m_object->SetCirVibration(Math::Vector(0.0f, 0.0f, 0.0f)); m_object->SetZoom(0, 1.0f); - power = m_object->GetPower(); - if ( power != 0 ) + power = m_poweredObject->GetPower(); + if (power != nullptr) { power->SetZoom(0, 1.0f); } @@ -325,8 +329,8 @@ bool CTaskTerraform::Abort() m_object->SetCirVibration(Math::Vector(0.0f, 0.0f, 0.0f)); m_object->SetZoom(0, 1.0f); - power = m_object->GetPower(); - if ( power != 0 ) + power = m_poweredObject->GetPower(); + if (power != nullptr) { power->SetZoom(0, 1.0f); } diff --git a/src/object/task/taskterraform.h b/src/object/task/taskterraform.h index 952b8752..78534b01 100644 --- a/src/object/task/taskterraform.h +++ b/src/object/task/taskterraform.h @@ -27,6 +27,7 @@ #include "math/vector.h" +class CPoweredObject; enum TaskTerraPhase { @@ -54,6 +55,7 @@ protected: bool Terraform(); protected: + CPoweredObject* m_poweredObject; TaskTerraPhase m_phase; float m_progress; float m_speed; diff --git a/src/physics/physics.cpp b/src/physics/physics.cpp index 8277a1fc..3550b554 100644 --- a/src/physics/physics.cpp +++ b/src/physics/physics.cpp @@ -45,6 +45,7 @@ #include "object/level/parserparam.h" #include "object/interface/carrier_object.h" #include "object/interface/jostleable_object.h" +#include "object/interface/powered_object.h" #include "object/interface/transportable_object.h" @@ -785,7 +786,7 @@ bool CPhysics::EventProcess(const Event &event) void CPhysics::MotorUpdate(float aTime, float rTime) { ObjectType type; - CObject* power; + CObject* power = nullptr; Math::Vector pos, motorSpeed; float energy, speed, factor, h; @@ -806,12 +807,12 @@ void CPhysics::MotorUpdate(float aTime, float rTime) type == OBJECT_MOBILEdr || type == OBJECT_CONTROLLER) { - power = 0; + power = nullptr; } else if ( type == OBJECT_HUMAN || type == OBJECT_TECH ) { - power = 0; + power = nullptr; if (IsObjectCarryingCargo(m_object)&& // carries something? !m_object->IsSpaceshipCargo() ) { @@ -844,21 +845,24 @@ void CPhysics::MotorUpdate(float aTime, float rTime) } else { - power = m_object->GetPower(); // searches for the object battery uses - if ( power == 0 || power->GetEnergy() == 0.0f ) // no battery or flat? + if (m_object->Implements(ObjectInterfaceType::Powered)) { - motorSpeed.x = 0.0f; - motorSpeed.z = 0.0f; - if ( m_bFreeze || m_bLand ) + power = dynamic_cast(m_object)->GetPower(); // searches for the object battery uses + if ( power == nullptr || power->GetEnergy() == 0.0f ) // no battery or flat? { - motorSpeed.y = 0.0f; // immobile + motorSpeed.x = 0.0f; + motorSpeed.z = 0.0f; + if ( m_bFreeze || m_bLand ) + { + motorSpeed.y = 0.0f; // immobile + } + else + { + motorSpeed.y = -1.0f; // grave + SetFalling(); + } + SetMotor(false); } - else - { - motorSpeed.y = -1.0f; // grave - SetFalling(); - } - SetMotor(false); } } @@ -1020,7 +1024,7 @@ void CPhysics::MotorUpdate(float aTime, float rTime) } } - if ( power != 0 ) // battery transported? + if ( power != nullptr ) // battery transported? { factor = 1.0f; if ( type == OBJECT_MOBILEia || @@ -1629,9 +1633,7 @@ bool CPhysics::EventFrame(const Event &event) void CPhysics::SoundMotor(float rTime) { - CObject* power; ObjectType type; - float energy; m_lastSoundInsect -= rTime; type = m_object->GetType(); @@ -1737,12 +1739,7 @@ void CPhysics::SoundMotor(float rTime) } else { - energy = 0.0f; - power = m_object->GetPower(); - if ( power != 0 ) - { - energy = power->GetEnergy(); - } + float energy = GetObjectEnergy(m_object); if ( m_object->GetSelect() && energy != 0.0f ) @@ -2242,15 +2239,7 @@ void CPhysics::SoundReactorFull(float rTime, ObjectType type) void CPhysics::SoundReactorStop(float rTime, ObjectType type) { - CObject* power; - float energy; - - energy = 0.0f; - power = m_object->GetPower(); - if ( power != 0 ) - { - energy = power->GetEnergy(); - } + float energy = GetObjectEnergy(m_object); if ( m_soundChannel != -1 ) // engine is running? { @@ -2976,8 +2965,7 @@ int CPhysics::ExploHimself(ObjectType iType, ObjectType oType, float force) void CPhysics::FrameParticle(float aTime, float rTime) { Math::Vector pos; - CObject* power; - float energy/*, intensity*/; + /*float intensity;*/ int effectLight; //bool bFlash; @@ -2987,12 +2975,7 @@ void CPhysics::FrameParticle(float aTime, float rTime) //bFlash = false; - energy = 0.0f; - power = m_object->GetPower(); - if ( power != 0 ) - { - energy = power->GetEnergy(); - } + float energy = GetObjectEnergy(m_object); if ( energy != m_lastEnergy ) // change the energy level? { @@ -3853,10 +3836,7 @@ void CPhysics::CreateInterface(bool bSelect) Error CPhysics::GetError() { - ObjectType type; - CObject* power; - - type = m_object->GetType(); + ObjectType type = m_object->GetType(); if ( type == OBJECT_HUMAN || type == OBJECT_TECH || type == OBJECT_MOTHER || @@ -3872,14 +3852,17 @@ Error CPhysics::GetError() return ERR_VEH_VIRUS; } - power = m_object->GetPower(); // searches for the object battery used - if ( power == 0 ) + if (m_object->Implements(ObjectInterfaceType::Powered)) { - return ERR_VEH_POWER; - } - else - { - if ( power->GetEnergy() == 0.0f ) return ERR_VEH_ENERGY; + CObject* power = dynamic_cast(m_object)->GetPower(); // searches for the object battery used + if (power == nullptr) + { + return ERR_VEH_POWER; + } + else + { + if ( power->GetEnergy() == 0.0f ) return ERR_VEH_ENERGY; + } } return ERR_OK;