From 364f87c49b49dc3f5db921106e16476e2f7bcf1b Mon Sep 17 00:00:00 2001 From: krzys-h Date: Tue, 11 Aug 2015 22:51:09 +0200 Subject: [PATCH] CPowerContainerObject interface --- src/object/auto/autopowercaptor.cpp | 43 ++++++++------ src/object/auto/autopowerstation.cpp | 56 +++++++++++-------- src/object/auto/autoresearch.cpp | 20 +++---- src/object/auto/autotower.cpp | 44 ++++++--------- src/object/interface/power_container_object.h | 53 ++++++++++++++++++ src/object/interface/powered_object.h | 6 +- src/object/object_factory.cpp | 10 ++-- src/object/object_interface_type.h | 1 + src/object/old_object.cpp | 16 ++++-- src/object/old_object.h | 10 +++- src/object/old_object_interface.cpp | 16 ------ src/object/old_object_interface.h | 5 -- src/object/robotmain.cpp | 8 +-- src/object/scene_conditions.cpp | 26 +++++---- src/object/task/taskfire.cpp | 14 ++--- src/object/task/taskmanip.cpp | 5 +- src/object/task/taskrecover.cpp | 14 ++--- src/object/task/taskshield.cpp | 23 +++----- src/object/task/taskterraform.cpp | 18 +++--- src/physics/physics.cpp | 14 ++--- src/ui/object_interface.cpp | 7 ++- 21 files changed, 229 insertions(+), 180 deletions(-) create mode 100644 src/object/interface/power_container_object.h diff --git a/src/object/auto/autopowercaptor.cpp b/src/object/auto/autopowercaptor.cpp index 7f52978d..d6b993a2 100644 --- a/src/object/auto/autopowercaptor.cpp +++ b/src/object/auto/autopowercaptor.cpp @@ -253,35 +253,47 @@ void CAutoPowerCaptor::ChargeObject(float rTime) float dist = Math::Distance(oPos, sPos); if ( dist > 20.0f ) continue; - if (! IsObjectBeingTransported(obj) && obj->GetType() == OBJECT_POWER ) + if (! IsObjectBeingTransported(obj) && obj->Implements(ObjectInterfaceType::PowerContainer) ) { - float energy = obj->GetEnergy(); - energy += rTime/2.0f; - if ( energy > 1.0f ) energy = 1.0f; - obj->SetEnergy(energy); + CPowerContainerObject* powerContainer = dynamic_cast(obj); + if (powerContainer->IsRechargeable()) + { + float energy = powerContainer->GetEnergy(); + energy += rTime/2.0f; + if ( energy > 1.0f ) energy = 1.0f; + powerContainer->SetEnergy(energy); + } } if (obj->Implements(ObjectInterfaceType::Powered)) { CObject* power = dynamic_cast(obj)->GetPower(); - if ( power != nullptr && power->GetType() == OBJECT_POWER ) + if ( power != nullptr && power->Implements(ObjectInterfaceType::PowerContainer) ) { - float energy = power->GetEnergy(); - energy += rTime/2.0f; - if ( energy > 1.0f ) energy = 1.0f; - power->SetEnergy(energy); + CPowerContainerObject* powerContainer = dynamic_cast(obj); + if (powerContainer->IsRechargeable()) + { + float energy = powerContainer->GetEnergy(); + energy += rTime/2.0f; + if ( energy > 1.0f ) energy = 1.0f; + powerContainer->SetEnergy(energy); + } } } if (obj->Implements(ObjectInterfaceType::Carrier)) { CObject* power = dynamic_cast(obj)->GetCargo(); - if ( power != nullptr && power->GetType() == OBJECT_POWER ) + if ( power != nullptr && power->Implements(ObjectInterfaceType::PowerContainer) ) { - float energy = power->GetEnergy(); - energy += rTime/2.0f; - if ( energy > 1.0f ) energy = 1.0f; - power->SetEnergy(energy); + CPowerContainerObject* powerContainer = dynamic_cast(obj); + if (powerContainer->IsRechargeable()) + { + float energy = powerContainer->GetEnergy(); + energy += rTime/2.0f; + if ( energy > 1.0f ) energy = 1.0f; + powerContainer->SetEnergy(energy); + } } } } @@ -318,4 +330,3 @@ bool CAutoPowerCaptor::Read(CLevelParserLine* line) return true; } - diff --git a/src/object/auto/autopowerstation.cpp b/src/object/auto/autopowerstation.cpp index bfd298a3..2b5362e4 100644 --- a/src/object/auto/autopowerstation.cpp +++ b/src/object/auto/autopowerstation.cpp @@ -41,6 +41,7 @@ CAutoPowerStation::CAutoPowerStation(COldObject* object) : CAuto(object) { + assert(object->Implements(ObjectInterfaceType::PowerContainer)); Init(); } @@ -96,14 +97,14 @@ bool CAutoPowerStation::EventProcess(const Event &event) if ( !m_bLastVirus ) { m_bLastVirus = true; - m_energyVirus = m_object->GetEnergy(); + m_energyVirus = dynamic_cast(m_object)->GetEnergyLevel(); } if ( m_timeVirus <= 0.0f ) { m_timeVirus = 0.1f+Math::Rand()*0.3f; - m_object->SetEnergy(Math::Rand()); + dynamic_cast(m_object)->SetEnergyLevel(Math::Rand()); } return true; } @@ -112,13 +113,13 @@ bool CAutoPowerStation::EventProcess(const Event &event) if ( m_bLastVirus ) { m_bLastVirus = false; - m_object->SetEnergy(m_energyVirus); + dynamic_cast(m_object)->SetEnergyLevel(m_energyVirus); } } UpdateInterface(event.rTime); - float big = m_object->GetEnergy(); + float big = dynamic_cast(m_object)->GetEnergy(); Gfx::TerrainRes res = m_terrain->GetResource(m_object->GetPosition()); if ( res == Gfx::TR_POWER ) @@ -136,32 +137,40 @@ bool CAutoPowerStation::EventProcess(const Event &event) if (vehicle->Implements(ObjectInterfaceType::Powered)) { CObject* power = dynamic_cast(vehicle)->GetPower(); - if ( power != nullptr && power->GetCapacity() == 1.0f ) + if ( power != nullptr && power->Implements(ObjectInterfaceType::PowerContainer) ) { - 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 + CPowerContainerObject* powerContainer = dynamic_cast(power); + if (powerContainer->IsRechargeable()) + { + float energy = powerContainer->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 + powerContainer->SetEnergy(energy); + if ( energy < freq ) freq = energy; + big -= add/4.0f; // discharge the large battery + } } } if (vehicle->Implements(ObjectInterfaceType::Carrier)) { CObject* power = dynamic_cast(vehicle)->GetCargo(); - if (power != nullptr && power->GetType() == OBJECT_POWER) + if ( power != nullptr && power->Implements(ObjectInterfaceType::PowerContainer) ) { - 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 + CPowerContainerObject* powerContainer = dynamic_cast(power); + if (powerContainer->IsRechargeable()) + { + float energy = powerContainer->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 + powerContainer->SetEnergy(energy); + if ( energy < freq ) freq = energy; + big -= add/4.0f; // discharge the large battery + } } } } @@ -235,7 +244,7 @@ bool CAutoPowerStation::EventProcess(const Event &event) if ( big < 0.0f ) big = 0.0f; if ( big > 1.0f ) big = 1.0f; - m_object->SetEnergy(big); // Shift the large battery + dynamic_cast(m_object)->SetEnergy(big); // Shift the large battery return true; } @@ -364,4 +373,3 @@ void CAutoPowerStation::UpdateInterface(float rTime) pg->SetLevel(m_object->GetEnergy()); } } - diff --git a/src/object/auto/autoresearch.cpp b/src/object/auto/autoresearch.cpp index bce1c160..eaf0d8fa 100644 --- a/src/object/auto/autoresearch.cpp +++ b/src/object/auto/autoresearch.cpp @@ -111,11 +111,11 @@ Error CAutoResearch::StartAction(int param) return ERR_RESEARCH_ALREADY; } - CObject* power = m_object->GetPower(); - if (power == nullptr) + if (m_object->GetPower() == nullptr || !m_object->GetPower()->Implements(ObjectInterfaceType::PowerContainer)) { return ERR_RESEARCH_POWER; } + CPowerContainerObject* power = dynamic_cast(m_object->GetPower()); if ( power->GetCapacity() > 1.0f ) { return ERR_RESEARCH_TYPE; @@ -150,7 +150,7 @@ Error CAutoResearch::StartAction(int param) bool CAutoResearch::EventProcess(const Event &event) { - CObject* power; + CPowerContainerObject* power; Math::Vector pos, speed; Error message; Math::Point dim; @@ -218,8 +218,7 @@ bool CAutoResearch::EventProcess(const Event &event) FireStopUpdate(m_progress, true); // flashes if ( m_progress < 1.0f ) { - power = m_object->GetPower(); - if ( power == 0 ) // more battery? + if ( m_object->GetPower() == nullptr || !m_object->GetPower()->Implements(ObjectInterfaceType::PowerContainer) ) // more battery? { SetBusy(false); UpdateInterface(); @@ -229,7 +228,8 @@ bool CAutoResearch::EventProcess(const Event &event) m_speed = 1.0f/1.0f; return true; } - power->SetEnergy(1.0f-m_progress); + power = dynamic_cast(m_object->GetPower()); + power->SetEnergyLevel(1.0f-m_progress); if ( m_lastParticle+m_engine->ParticleAdapt(0.05f) <= m_time ) { @@ -297,16 +297,16 @@ Error CAutoResearch::GetError() return ERR_BAT_VIRUS; } - CObject* power = m_object->GetPower(); - if ( power == 0 ) + if (m_object->GetPower() == nullptr || !m_object->GetPower()->Implements(ObjectInterfaceType::PowerContainer)) { return ERR_RESEARCH_POWER; } - if ( power != 0 && power->GetCapacity() > 1.0f ) + CPowerContainerObject* power = dynamic_cast(m_object->GetPower()); + if ( power->GetCapacity() > 1.0f ) { return ERR_RESEARCH_TYPE; } - if ( power != 0 && power->GetEnergy() < 1.0f ) + if ( power->GetEnergy() < 1.0f ) { return ERR_RESEARCH_ENERGY; } diff --git a/src/object/auto/autotower.cpp b/src/object/auto/autotower.cpp index a06769d8..535c7faf 100644 --- a/src/object/auto/autotower.cpp +++ b/src/object/auto/autotower.cpp @@ -95,10 +95,9 @@ void CAutoTower::Init() bool CAutoTower::EventProcess(const Event &event) { - CObject* power; CObject* target; Math::Vector pos; - float angle, energy, quick; + float angle, quick; CAuto::EventProcess(event); @@ -122,6 +121,14 @@ bool CAutoTower::EventProcess(const Event &event) return true; } + CPowerContainerObject* power = nullptr; + float energy = 0.0f; + if ( m_object->GetPower() != nullptr && m_object->GetPower()->Implements(ObjectInterfaceType::PowerContainer) ) + { + power = dynamic_cast(m_object->GetPower()); + energy = power->GetEnergy(); + } + UpdateInterface(event.rTime); if ( m_phase == ATP_WAIT ) return true; @@ -133,12 +140,6 @@ bool CAutoTower::EventProcess(const Event &event) FireStopUpdate(m_progress, true); // blinks if ( m_progress < 1.0f ) { - energy = 0.0f; - power = m_object->GetPower(); - if ( power != 0 ) - { - energy = power->GetEnergy()*power->GetCapacity(); - } if ( energy >= ENERGY_FIRE ) { m_phase = ATP_SEARCH; @@ -173,13 +174,6 @@ bool CAutoTower::EventProcess(const Event &event) } else { - energy = 0.0f; - power = m_object->GetPower(); - if ( power != 0 ) - { - energy = power->GetEnergy()*power->GetCapacity(); - } - target = SearchTarget(m_targetPos); if ( energy < ENERGY_FIRE ) { @@ -227,11 +221,10 @@ bool CAutoTower::EventProcess(const Event &event) m_object->SetPartRotationY(1, m_angleYfinal); m_object->SetPartRotationZ(2, m_angleZfinal); - power = m_object->GetPower(); - if ( power != 0 ) + if ( power != nullptr ) { energy = power->GetEnergy(); - energy -= ENERGY_FIRE/power->GetCapacity(); + energy -= ENERGY_FIRE; power->SetEnergy(energy); } @@ -321,18 +314,16 @@ Error CAutoTower::GetError() return ERR_BAT_VIRUS; } - CObject* power = m_object->GetPower(); - if ( power == nullptr ) + if ( m_object->GetPower() == nullptr || !m_object->GetPower()->Implements(ObjectInterfaceType::PowerContainer) ) { return ERR_TOWER_POWER; // no battery } - else + + if ( dynamic_cast(m_object->GetPower())->GetEnergy() < ENERGY_FIRE ) { - if ( power->GetEnergy()*power->GetCapacity() < ENERGY_FIRE ) - { - return ERR_TOWER_ENERGY; // not enough energy - } + return ERR_TOWER_ENERGY; // not enough energy } + return ERR_OK; } @@ -457,7 +448,7 @@ void CAutoTower::UpdateInterface(float rTime) Ui::CWindow* pw = static_cast< Ui::CWindow* >(m_interface->SearchControl(EVENT_WINDOW0)); if ( pw == 0 ) return; - Ui::CGauge*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 ) { float energy = GetObjectEnergy(m_object); @@ -506,4 +497,3 @@ bool CAutoTower::Read(CLevelParserLine* line) return true; } - diff --git a/src/object/interface/power_container_object.h b/src/object/interface/power_container_object.h new file mode 100644 index 00000000..8a9af659 --- /dev/null +++ b/src/object/interface/power_container_object.h @@ -0,0 +1,53 @@ +/* + * This file is part of the Colobot: Gold Edition source code + * Copyright (C) 2001-2015, Daniel Roux, EPSITEC SA & TerranovaTeam + * http://epsiteс.ch; http://colobot.info; http://github.com/colobot + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see http://gnu.org/licenses + */ + +#pragma once + +#include "object/object_interface_type.h" + +/** + * \class CPowerContainer + * \brief Interface for objects hold power (PowerCells and some buildings) + */ +class CPowerContainerObject +{ +public: + explicit CPowerContainerObject(ObjectInterfaceTypes& types) + { + types[static_cast(ObjectInterfaceType::PowerContainer)] = true; + } + virtual ~CPowerContainerObject() + {} + + virtual void SetEnergyLevel(float level) = 0; + virtual float GetEnergyLevel() = 0; + + virtual void SetEnergy(float energy) + { + SetEnergyLevel(energy / GetCapacity()); + } + virtual float GetEnergy() + { + return GetEnergyLevel() * GetCapacity(); + } + + virtual float GetCapacity() = 0; + + virtual bool IsRechargeable() = 0; +}; diff --git a/src/object/interface/powered_object.h b/src/object/interface/powered_object.h index 254a26c4..09526aca 100644 --- a/src/object/interface/powered_object.h +++ b/src/object/interface/powered_object.h @@ -22,6 +22,8 @@ #include "object/object.h" #include "object/object_interface_type.h" +#include "object/interface/power_container_object.h" + class CObject; /** @@ -55,9 +57,9 @@ inline float GetObjectEnergy(CObject* object) if (object->Implements(ObjectInterfaceType::Powered)) { CObject* power = dynamic_cast(object)->GetPower(); - if (power != nullptr) + if (power != nullptr && power->Implements(ObjectInterfaceType::PowerContainer)) { - energy = power->GetEnergy(); + energy = dynamic_cast(power)->GetEnergy(); } } diff --git a/src/object/object_factory.cpp b/src/object/object_factory.cpp index 1030d89f..6a39a94e 100644 --- a/src/object/object_factory.cpp +++ b/src/object/object_factory.cpp @@ -594,7 +594,7 @@ CObjectUPtr CObjectFactory::CreateBuilding(const ObjectCreateParams& params) obj->SetCameraCollisionSphere(Math::Sphere(Math::Vector(-7.0f, 5.0f, 0.0f), 5.0f)); obj->GetCharacter()->posPower = Math::Vector(0.0f, 3.0f, 0.0f); - obj->SetEnergy(power); // initializes the energy level + obj->SetEnergyLevel(power); // initializes the energy level obj->CreateShadowCircle(6.0f, 0.5f); } @@ -777,7 +777,7 @@ CObjectUPtr CObjectFactory::CreateBuilding(const ObjectCreateParams& params) obj->AddCrashSphere(CrashSphere(Math::Vector(-15.0f, 6.0f, 0.0f), 4.0f, SOUND_BOUMm, 0.45f)); obj->SetCameraCollisionSphere(Math::Sphere(Math::Vector(-15.0f, 5.0f, 0.0f), 6.0f)); - obj->SetEnergy(power); + obj->SetEnergyLevel(power); } if ( type == OBJECT_CONVERT ) @@ -1068,8 +1068,8 @@ CObjectUPtr CObjectFactory::CreateBuilding(const ObjectCreateParams& params) pPower->SetTransporter(obj.get()); SetPower(pPower); - if ( power <= 1.0f ) pPower->obj->SetEnergy(power); - else pPower->obj->SetEnergy(power/100.0f); + if ( power <= 1.0f ) pPower->obj->SetEnergyLevel(power); + else pPower->obj->SetEnergyLevel(power/100.0f); } #endif @@ -1102,7 +1102,7 @@ CObjectUPtr CObjectFactory::CreateResource(const ObjectCreateParams& params) int rank = m_engine->CreateObject(); m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_FIX); // it is a stationary object obj->SetObjectRank(0, rank); - obj->SetEnergy(power); + obj->SetEnergyLevel(power); std::string name; if ( type == OBJECT_STONE ) name = "stone.mod"; diff --git a/src/object/object_interface_type.h b/src/object/object_interface_type.h index 077eae2f..afe8214c 100644 --- a/src/object/object_interface_type.h +++ b/src/object/object_interface_type.h @@ -42,6 +42,7 @@ enum class ObjectInterfaceType Powered, //!< object powered with power cell Movable, //!< objects that can move Controllable, //!< objects that can be selected and controlled by the player + PowerContainer, //!< objects that hold power Old, //!< old objects, TODO: remove once no longer necessary Max //!< maximum value (for getting number of items in enum) }; diff --git a/src/object/old_object.cpp b/src/object/old_object.cpp index 180c3956..e95b898d 100644 --- a/src/object/old_object.cpp +++ b/src/object/old_object.cpp @@ -103,6 +103,7 @@ COldObject::COldObject(int id) , CPoweredObject(m_implementedInterfaces) , CMovableObject(m_implementedInterfaces) , CControllableObject(m_implementedInterfaces) + , CPowerContainerObject(m_implementedInterfaces) { // A bit of a hack since we don't have subclasses yet, set externally in SetProgrammable() m_implementedInterfaces[static_cast(ObjectInterfaceType::Programmable)] = false; @@ -764,8 +765,8 @@ void COldObject::Write(CLevelParserLine* line) if ( GetCameraLock() ) line->AddParam("cameraLock", MakeUnique(GetCameraLock())); - if ( GetEnergy() != 0.0f ) - line->AddParam("energy", MakeUnique(GetEnergy())); + if ( GetEnergyLevel() != 0.0f ) + line->AddParam("energy", MakeUnique(GetEnergyLevel())); if ( GetCapacity() != 1.0f ) line->AddParam("capacity", MakeUnique(GetCapacity())); @@ -872,7 +873,7 @@ void COldObject::Read(CLevelParserLine* line) SetCameraDist(line->GetParam("cameraDist")->AsFloat(50.0f)); SetCameraLock(line->GetParam("cameraLock")->AsBool(false)); - SetEnergy(line->GetParam("energy")->AsFloat(0.0f)); + SetEnergyLevel(line->GetParam("energy")->AsFloat(0.0f)); SetCapacity(line->GetParam("capacity")->AsFloat(1.0f)); SetShield(line->GetParam("shield")->AsFloat(1.0f)); SetRange(line->GetParam("range")->AsFloat(1.0f)); @@ -2315,14 +2316,14 @@ float COldObject::GetAbsTime() // Management of energy contained in a battery. // Single subject possesses the battery energy, but not the vehicle that carries the battery! -void COldObject::SetEnergy(float level) +void COldObject::SetEnergyLevel(float level) { if ( level < 0.0f ) level = 0.0f; if ( level > 1.0f ) level = 1.0f; m_energy = level; } -float COldObject::GetEnergy() +float COldObject::GetEnergyLevel() { if ( m_type != OBJECT_POWER && m_type != OBJECT_ATOMIC && @@ -2346,6 +2347,11 @@ float COldObject::GetCapacity() return m_capacity; } +bool COldObject::IsRechargeable() +{ + return m_type == OBJECT_POWER; +} + // Management of the shield. diff --git a/src/object/old_object.h b/src/object/old_object.h index 48627424..018a7230 100644 --- a/src/object/old_object.h +++ b/src/object/old_object.h @@ -31,6 +31,7 @@ #include "object/interface/interactive_object.h" #include "object/interface/jostleable_object.h" #include "object/interface/movable_object.h" +#include "object/interface/power_container_object.h" #include "object/interface/powered_object.h" #include "object/interface/programmable_object.h" #include "object/interface/task_executor_object.h" @@ -87,7 +88,8 @@ class COldObject : public CObject, public CCarrierObject, public CPoweredObject, public CMovableObject, - public CControllableObject + public CControllableObject, + public CPowerContainerObject { friend class CObjectFactory; friend class CObjectManager; @@ -198,11 +200,13 @@ public: float GetAbsTime(); - void SetEnergy(float level) override; - float GetEnergy() override; + void SetEnergyLevel(float level) override; + float GetEnergyLevel() override; float GetCapacity() override; + bool IsRechargeable() override; + void SetShield(float level) override; float GetShield() override; diff --git a/src/object/old_object_interface.cpp b/src/object/old_object_interface.cpp index b03d612f..18f323a5 100644 --- a/src/object/old_object_interface.cpp +++ b/src/object/old_object_interface.cpp @@ -104,22 +104,6 @@ Character* COldObjectInterface::GetCharacter() throw std::logic_error("GetCharacter: not implemented!"); } -void COldObjectInterface::SetEnergy(float level) -{ - throw std::logic_error("SetEnergy: not implemented!"); -} - -float COldObjectInterface::GetEnergy() -{ - throw std::logic_error("GetEnergy: not implemented!"); -} - - -float COldObjectInterface::GetCapacity() -{ - throw std::logic_error("GetCapacity: not implemented!"); -} - void COldObjectInterface::SetShield(float level) { throw std::logic_error("SetShield: not implemented!"); diff --git a/src/object/old_object_interface.h b/src/object/old_object_interface.h index de9a665f..2a8ac14a 100644 --- a/src/object/old_object_interface.h +++ b/src/object/old_object_interface.h @@ -93,11 +93,6 @@ public: virtual void FlatParent(); - // This goes to CPowerContainerObject [implemented by: PowerCell, NuclearCell, PowerStation, PowerPlant] - virtual void SetEnergy(float level); - virtual float GetEnergy(); - virtual float GetCapacity(); - // This goes to CShieldedObject (probably will inherit from CDestroyableObject) virtual void SetShield(float level); virtual float GetShield(); diff --git a/src/object/robotmain.cpp b/src/object/robotmain.cpp index 4b668d80..0215de58 100644 --- a/src/object/robotmain.cpp +++ b/src/object/robotmain.cpp @@ -1235,8 +1235,8 @@ void CRobotMain::ExecuteCmd(char *cmd) if (object->Implements(ObjectInterfaceType::Powered)) { CObject* power = dynamic_cast(object)->GetPower(); - if (power != nullptr) - power->SetEnergy(1.0f); + if (power != nullptr && power->Implements(ObjectInterfaceType::PowerContainer)) + dynamic_cast(power)->SetEnergyLevel(1.0f); } object->SetShield(1.0f); @@ -1257,8 +1257,8 @@ void CRobotMain::ExecuteCmd(char *cmd) if (object->Implements(ObjectInterfaceType::Powered)) { CObject* power = dynamic_cast(object)->GetPower(); - if (power != nullptr) - power->SetEnergy(1.0f); + if (power != nullptr && power->Implements(ObjectInterfaceType::PowerContainer)) + dynamic_cast(power)->SetEnergyLevel(1.0f); } } return; diff --git a/src/object/scene_conditions.cpp b/src/object/scene_conditions.cpp index eea9d6aa..8df921dc 100644 --- a/src/object/scene_conditions.cpp +++ b/src/object/scene_conditions.cpp @@ -98,22 +98,24 @@ int CSceneCondition::CountObjects() continue; float energyLevel = -1; - CObject* power = nullptr; - if (obj->Implements(ObjectInterfaceType::Powered)) - power = dynamic_cast(obj)->GetPower(); + CPowerContainerObject* power = nullptr; + if (obj->Implements(ObjectInterfaceType::PowerContainer)) + { + power = dynamic_cast(obj); + } + else if (obj->Implements(ObjectInterfaceType::Powered)) + { + CObject* powerObj = dynamic_cast(obj)->GetPower(); + if(powerObj != nullptr && powerObj->Implements(ObjectInterfaceType::PowerContainer)) + { + power = dynamic_cast(powerObj); + } + } if (power != nullptr) { energyLevel = power->GetEnergy(); - if (power->GetType() == OBJECT_ATOMIC) energyLevel *= 100; - } - else - { - if (obj->GetType() == OBJECT_POWER || obj->GetType() == OBJECT_ATOMIC) - { - energyLevel = obj->GetEnergy(); - if (obj->GetType() == OBJECT_ATOMIC) energyLevel *= 100; - } + if (power->GetCapacity() > 1.0f) energyLevel *= 10; // TODO: Who designed it like that ?!?! } if (energyLevel < this->powermin || energyLevel > this->powermax) continue; diff --git a/src/object/task/taskfire.cpp b/src/object/task/taskfire.cpp index f1e88278..35542852 100644 --- a/src/object/task/taskfire.cpp +++ b/src/object/task/taskfire.cpp @@ -78,14 +78,15 @@ bool CTaskFire::EventProcess(const Event &event) m_lastSound -= event.rTime; m_progress += event.rTime*m_speed; - CObject* power = m_object->GetPower(); - if (power != nullptr) + CPowerContainerObject* power = nullptr; + if (m_object->GetPower() != nullptr && m_object->GetPower()->Implements(ObjectInterfaceType::PowerContainer)) { + power = dynamic_cast(m_object->GetPower()); energy = power->GetEnergy(); if ( m_bOrganic ) fire = ENERGY_FIREi; else if ( m_bRay ) fire = ENERGY_FIREr; else fire = ENERGY_FIRE; - energy -= event.rTime*fire/power->GetCapacity(); + energy -= event.rTime*fire; power->SetEnergy(energy); } @@ -314,13 +315,13 @@ Error CTaskFire::Start(float delay) assert(m_object->Implements(ObjectInterfaceType::Powered)); CObject* power = dynamic_cast(m_object)->GetPower(); - if (power == nullptr) return ERR_FIRE_ENERGY; + if (power == nullptr || !power->Implements(ObjectInterfaceType::PowerContainer)) return ERR_FIRE_ENERGY; - energy = power->GetEnergy(); + energy = dynamic_cast(power)->GetEnergy(); if ( m_bOrganic ) fire = m_delay*ENERGY_FIREi; else if ( m_bRay ) fire = m_delay*ENERGY_FIREr; else fire = m_delay*ENERGY_FIRE; - if ( energy < fire/power->GetCapacity()+0.05f ) return ERR_FIRE_ENERGY; + if ( energy < fire+0.05f ) return ERR_FIRE_ENERGY; m_speed = 1.0f/m_delay; m_progress = 0.0f; @@ -386,4 +387,3 @@ bool CTaskFire::Abort() //? m_camera->StopCentering(m_object, 1.0f); return true; } - diff --git a/src/object/task/taskmanip.cpp b/src/object/task/taskmanip.cpp index fb31d09c..fe7ab92b 100644 --- a/src/object/task/taskmanip.cpp +++ b/src/object/task/taskmanip.cpp @@ -363,9 +363,9 @@ Error CTaskManip::Start(TaskManipOrder order, TaskManipArm arm) m_energy = 0.0f; power = m_object->GetPower(); - if ( power != 0 ) + if ( power != nullptr && power->Implements(ObjectInterfaceType::PowerContainer) ) { - m_energy = power->GetEnergy(); + m_energy = dynamic_cast(power)->GetEnergy(); } if ( !m_physics->GetLand() ) return ERR_MANIP_FLY; @@ -1368,4 +1368,3 @@ void CTaskManip::SoundManip(float time, float amplitude, float frequency) 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/taskrecover.cpp b/src/object/task/taskrecover.cpp index 97ea90d6..956b1ec2 100644 --- a/src/object/task/taskrecover.cpp +++ b/src/object/task/taskrecover.cpp @@ -104,11 +104,12 @@ bool CTaskRecover::EventProcess(const Event &event) if ( m_phase == TRP_OPER ) { assert(m_object->Implements(ObjectInterfaceType::Powered)); - CObject* power = dynamic_cast(m_object)->GetPower(); - if (power != nullptr) + CObject* powerObj = dynamic_cast(m_object)->GetPower(); + if (powerObj != nullptr && powerObj->Implements(ObjectInterfaceType::PowerContainer)) { + CPowerContainerObject* power = dynamic_cast(powerObj); energy = power->GetEnergy(); - energy -= event.rTime * ENERGY_RECOVER / power->GetCapacity() * m_speed; + energy -= event.rTime * ENERGY_RECOVER * m_speed; power->SetEnergy(energy); } @@ -186,10 +187,10 @@ Error CTaskRecover::Start() assert(m_object->Implements(ObjectInterfaceType::Powered)); CObject* power = dynamic_cast(m_object)->GetPower(); - if (power == nullptr) return ERR_RECOVER_ENERGY; + if (power == nullptr || !power->Implements(ObjectInterfaceType::PowerContainer)) return ERR_RECOVER_ENERGY; - float energy = power->GetEnergy(); - if ( energy < ENERGY_RECOVER/power->GetCapacity()+0.05f ) return ERR_RECOVER_ENERGY; + float energy = dynamic_cast(power)->GetEnergy(); + if ( energy < ENERGY_RECOVER+0.05f ) return ERR_RECOVER_ENERGY; Math::Matrix* mat = m_object->GetWorldMatrix(0); Math::Vector pos = Math::Vector(RECOVER_DIST, 3.3f, 0.0f); @@ -372,4 +373,3 @@ CObject* CTaskRecover::SearchRuin() { return CObjectManager::GetInstancePointer()->FindNearest(nullptr, m_recoverPos, {OBJECT_RUINmobilew1, OBJECT_RUINmobilew2, OBJECT_RUINmobilet1, OBJECT_RUINmobilet2, OBJECT_RUINmobiler1, OBJECT_RUINmobiler2}, 40.0f/g_unit); } - diff --git a/src/object/task/taskshield.cpp b/src/object/task/taskshield.cpp index cf4199bc..946ed23f 100644 --- a/src/object/task/taskshield.cpp +++ b/src/object/task/taskshield.cpp @@ -64,7 +64,6 @@ CTaskShield::~CTaskShield() bool CTaskShield::EventProcess(const Event &event) { - CObject* power; Math::Matrix* mat; Math::Matrix matrix; Math::Vector pos, speed, goal, angle; @@ -113,10 +112,11 @@ bool CTaskShield::EventProcess(const Event &event) { energy = (1.0f/ENERGY_TIME)*event.rTime; energy *= GetRadius()/RADIUS_SHIELD_MAX; - power = m_object->GetPower(); - if (power != nullptr) + CObject* powerObj = dynamic_cast(m_object)->GetPower(); + if (powerObj != nullptr && powerObj->Implements(ObjectInterfaceType::PowerContainer)) { - power->SetEnergy(power->GetEnergy()-energy/power->GetCapacity()); + CPowerContainerObject* power = dynamic_cast(powerObj); + power->SetEnergy(power->GetEnergy()-energy); } m_energyUsed += energy; @@ -293,8 +293,8 @@ Error CTaskShield::Start(TaskShieldMode mode, float delay) if ( !m_physics->GetLand() ) return ERR_SHIELD_VEH; CObject* power = m_object->GetPower(); - if (power == nullptr) return ERR_SHIELD_ENERGY; - float energy = power->GetEnergy(); + if (power == nullptr || !power->Implements(ObjectInterfaceType::PowerContainer)) return ERR_SHIELD_ENERGY; + float energy = dynamic_cast(power)->GetEnergy(); if ( energy == 0.0f ) return ERR_SHIELD_ENERGY; Math::Matrix* mat = m_object->GetWorldMatrix(0); @@ -369,7 +369,6 @@ Error CTaskShield::Stop() Error CTaskShield::IsEnded() { - CObject* power; Math::Vector pos, speed; Math::Point dim; float energy; @@ -381,15 +380,7 @@ Error CTaskShield::IsEnded() { m_object->SetShieldRadius(GetRadius()); - power = m_object->GetPower(); - if ( power == 0 ) - { - energy = 0.0f; - } - else - { - energy = power->GetEnergy(); - } + energy = GetObjectEnergy(m_object); if ( energy == 0.0f || m_delay <= 0.0f ) { diff --git a/src/object/task/taskterraform.cpp b/src/object/task/taskterraform.cpp index 0cb5af0d..a439ade0 100644 --- a/src/object/task/taskterraform.cpp +++ b/src/object/task/taskterraform.cpp @@ -97,10 +97,14 @@ bool CTaskTerraform::EventProcess(const Event &event) { power->SetScale(1.0f+m_progress*1.0f); - energy = power->GetEnergy(); - energy -= event.rTime*ENERGY_TERRA/power->GetCapacity()/4.0f; - if ( energy < 0.0f ) energy = 0.0f; - power->SetEnergy(energy); + if (power->Implements(ObjectInterfaceType::PowerContainer)) + { + CPowerContainerObject* powerContainer = dynamic_cast(power); + energy = powerContainer->GetEnergy(); + energy -= event.rTime*ENERGY_TERRA/4.0f; + if ( energy < 0.0f ) energy = 0.0f; + powerContainer->SetEnergy(energy); + } } } @@ -205,9 +209,9 @@ Error CTaskTerraform::Start() if ( type != OBJECT_MOBILErt ) return ERR_TERRA_VEH; power = m_object->GetPower(); - if ( power == 0 ) return ERR_TERRA_ENERGY; - energy = power->GetEnergy(); - if ( energy < ENERGY_TERRA/power->GetCapacity()+0.05f ) return ERR_TERRA_ENERGY; + if ( power == nullptr || !power->Implements(ObjectInterfaceType::PowerContainer) ) return ERR_TERRA_ENERGY; + energy = dynamic_cast(power)->GetEnergy(); + if ( energy < ENERGY_TERRA+0.05f ) return ERR_TERRA_ENERGY; speed = m_physics->GetMotorSpeed(); if ( speed.x != 0.0f || diff --git a/src/physics/physics.cpp b/src/physics/physics.cpp index a7adacf7..ae2e538e 100644 --- a/src/physics/physics.cpp +++ b/src/physics/physics.cpp @@ -774,7 +774,7 @@ bool CPhysics::EventProcess(const Event &event) void CPhysics::MotorUpdate(float aTime, float rTime) { ObjectType type; - CObject* power = nullptr; + CPowerContainerObject* power = nullptr; Math::Vector pos, motorSpeed; float energy, speed, factor, h; @@ -801,7 +801,7 @@ void CPhysics::MotorUpdate(float aTime, float rTime) type == OBJECT_TECH ) { power = nullptr; - if (IsObjectCarryingCargo(m_object)&& // carries something? + if (IsObjectCarryingCargo(m_object) && // carries something? !m_bFreeze ) { motorSpeed.x *= 0.7f; // forward more slowly @@ -835,8 +835,8 @@ void CPhysics::MotorUpdate(float aTime, float rTime) { if (m_object->Implements(ObjectInterfaceType::Powered)) { - power = dynamic_cast(m_object)->GetPower(); // searches for the object battery uses - if ( power == nullptr || power->GetEnergy() == 0.0f ) // no battery or flat? + power = dynamic_cast(dynamic_cast(m_object)->GetPower()); // searches for the object battery uses + if ( GetObjectEnergy(m_object) == 0.0f ) // no battery or flat? { motorSpeed.x = 0.0f; motorSpeed.z = 0.0f; @@ -1020,8 +1020,6 @@ void CPhysics::MotorUpdate(float aTime, float rTime) type == OBJECT_MOBILEic || type == OBJECT_MOBILEii ) factor = 0.5f; - factor /= power->GetCapacity(); - energy = power->GetEnergy(); energy -= fabs(motorSpeed.x)*rTime*factor*0.005f; energy -= fabs(motorSpeed.z)*rTime*factor*0.005f; @@ -3837,13 +3835,13 @@ Error CPhysics::GetError() if (m_object->Implements(ObjectInterfaceType::Powered)) { CObject* power = dynamic_cast(m_object)->GetPower(); // searches for the object battery used - if (power == nullptr) + if (power == nullptr || !power->Implements(ObjectInterfaceType::PowerContainer)) { return ERR_VEH_POWER; } else { - if ( power->GetEnergy() == 0.0f ) return ERR_VEH_ENERGY; + if ( dynamic_cast(power)->GetEnergy() == 0.0f ) return ERR_VEH_ENERGY; } } diff --git a/src/ui/object_interface.cpp b/src/ui/object_interface.cpp index e3821e0d..14404a76 100644 --- a/src/ui/object_interface.cpp +++ b/src/ui/object_interface.cpp @@ -1579,10 +1579,11 @@ void CObjectInterface::UpdateInterface(float rTime) if (m_object->Implements(ObjectInterfaceType::Powered)) { CObject* power = dynamic_cast(m_object)->GetPower(); - if (power != nullptr) + if (power != nullptr && power->Implements(ObjectInterfaceType::PowerContainer)) { - energy = power->GetEnergy(); - limit = energy*power->GetCapacity(); + CPowerContainerObject* powerContainer = dynamic_cast(power); + energy = powerContainer->GetEnergyLevel(); + limit = powerContainer->GetEnergy(); } } icon = 0; // red/green