CPowerContainerObject interface

master
krzys-h 2015-08-11 22:51:09 +02:00
parent 7e18757d29
commit 364f87c49b
21 changed files with 229 additions and 180 deletions

View File

@ -253,35 +253,47 @@ void CAutoPowerCaptor::ChargeObject(float rTime)
float dist = Math::Distance(oPos, sPos); float dist = Math::Distance(oPos, sPos);
if ( dist > 20.0f ) continue; if ( dist > 20.0f ) continue;
if (! IsObjectBeingTransported(obj) && obj->GetType() == OBJECT_POWER ) if (! IsObjectBeingTransported(obj) && obj->Implements(ObjectInterfaceType::PowerContainer) )
{ {
float energy = obj->GetEnergy(); CPowerContainerObject* powerContainer = dynamic_cast<CPowerContainerObject*>(obj);
energy += rTime/2.0f; if (powerContainer->IsRechargeable())
if ( energy > 1.0f ) energy = 1.0f; {
obj->SetEnergy(energy); float energy = powerContainer->GetEnergy();
energy += rTime/2.0f;
if ( energy > 1.0f ) energy = 1.0f;
powerContainer->SetEnergy(energy);
}
} }
if (obj->Implements(ObjectInterfaceType::Powered)) if (obj->Implements(ObjectInterfaceType::Powered))
{ {
CObject* power = dynamic_cast<CPoweredObject*>(obj)->GetPower(); CObject* power = dynamic_cast<CPoweredObject*>(obj)->GetPower();
if ( power != nullptr && power->GetType() == OBJECT_POWER ) if ( power != nullptr && power->Implements(ObjectInterfaceType::PowerContainer) )
{ {
float energy = power->GetEnergy(); CPowerContainerObject* powerContainer = dynamic_cast<CPowerContainerObject*>(obj);
energy += rTime/2.0f; if (powerContainer->IsRechargeable())
if ( energy > 1.0f ) energy = 1.0f; {
power->SetEnergy(energy); float energy = powerContainer->GetEnergy();
energy += rTime/2.0f;
if ( energy > 1.0f ) energy = 1.0f;
powerContainer->SetEnergy(energy);
}
} }
} }
if (obj->Implements(ObjectInterfaceType::Carrier)) if (obj->Implements(ObjectInterfaceType::Carrier))
{ {
CObject* power = dynamic_cast<CCarrierObject*>(obj)->GetCargo(); CObject* power = dynamic_cast<CCarrierObject*>(obj)->GetCargo();
if ( power != nullptr && power->GetType() == OBJECT_POWER ) if ( power != nullptr && power->Implements(ObjectInterfaceType::PowerContainer) )
{ {
float energy = power->GetEnergy(); CPowerContainerObject* powerContainer = dynamic_cast<CPowerContainerObject*>(obj);
energy += rTime/2.0f; if (powerContainer->IsRechargeable())
if ( energy > 1.0f ) energy = 1.0f; {
power->SetEnergy(energy); 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; return true;
} }

View File

@ -41,6 +41,7 @@
CAutoPowerStation::CAutoPowerStation(COldObject* object) : CAuto(object) CAutoPowerStation::CAutoPowerStation(COldObject* object) : CAuto(object)
{ {
assert(object->Implements(ObjectInterfaceType::PowerContainer));
Init(); Init();
} }
@ -96,14 +97,14 @@ bool CAutoPowerStation::EventProcess(const Event &event)
if ( !m_bLastVirus ) if ( !m_bLastVirus )
{ {
m_bLastVirus = true; m_bLastVirus = true;
m_energyVirus = m_object->GetEnergy(); m_energyVirus = dynamic_cast<CPowerContainerObject*>(m_object)->GetEnergyLevel();
} }
if ( m_timeVirus <= 0.0f ) if ( m_timeVirus <= 0.0f )
{ {
m_timeVirus = 0.1f+Math::Rand()*0.3f; m_timeVirus = 0.1f+Math::Rand()*0.3f;
m_object->SetEnergy(Math::Rand()); dynamic_cast<CPowerContainerObject*>(m_object)->SetEnergyLevel(Math::Rand());
} }
return true; return true;
} }
@ -112,13 +113,13 @@ bool CAutoPowerStation::EventProcess(const Event &event)
if ( m_bLastVirus ) if ( m_bLastVirus )
{ {
m_bLastVirus = false; m_bLastVirus = false;
m_object->SetEnergy(m_energyVirus); dynamic_cast<CPowerContainerObject*>(m_object)->SetEnergyLevel(m_energyVirus);
} }
} }
UpdateInterface(event.rTime); UpdateInterface(event.rTime);
float big = m_object->GetEnergy(); float big = dynamic_cast<CPowerContainerObject*>(m_object)->GetEnergy();
Gfx::TerrainRes res = m_terrain->GetResource(m_object->GetPosition()); Gfx::TerrainRes res = m_terrain->GetResource(m_object->GetPosition());
if ( res == Gfx::TR_POWER ) if ( res == Gfx::TR_POWER )
@ -136,32 +137,40 @@ bool CAutoPowerStation::EventProcess(const Event &event)
if (vehicle->Implements(ObjectInterfaceType::Powered)) if (vehicle->Implements(ObjectInterfaceType::Powered))
{ {
CObject* power = dynamic_cast<CPoweredObject*>(vehicle)->GetPower(); CObject* power = dynamic_cast<CPoweredObject*>(vehicle)->GetPower();
if ( power != nullptr && power->GetCapacity() == 1.0f ) if ( power != nullptr && power->Implements(ObjectInterfaceType::PowerContainer) )
{ {
float energy = power->GetEnergy(); CPowerContainerObject* powerContainer = dynamic_cast<CPowerContainerObject*>(power);
float add = event.rTime*0.2f; if (powerContainer->IsRechargeable())
if ( add > big*4.0f ) add = big*4.0f; {
if ( add > 1.0f-energy ) add = 1.0f-energy; float energy = powerContainer->GetEnergy();
energy += add; // Charging the battery float add = event.rTime*0.2f;
power->SetEnergy(energy); if ( add > big*4.0f ) add = big*4.0f;
if ( energy < freq ) freq = energy; if ( add > 1.0f-energy ) add = 1.0f-energy;
big -= add/4.0f; // discharge the large battery 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)) if (vehicle->Implements(ObjectInterfaceType::Carrier))
{ {
CObject* power = dynamic_cast<CCarrierObject*>(vehicle)->GetCargo(); CObject* power = dynamic_cast<CCarrierObject*>(vehicle)->GetCargo();
if (power != nullptr && power->GetType() == OBJECT_POWER) if ( power != nullptr && power->Implements(ObjectInterfaceType::PowerContainer) )
{ {
float energy = power->GetEnergy(); CPowerContainerObject* powerContainer = dynamic_cast<CPowerContainerObject*>(power);
float add = event.rTime*0.2f; if (powerContainer->IsRechargeable())
if ( add > big*4.0f ) add = big*4.0f; {
if ( add > 1.0f-energy ) add = 1.0f-energy; float energy = powerContainer->GetEnergy();
energy += add; // Charging the battery float add = event.rTime*0.2f;
power->SetEnergy(energy); if ( add > big*4.0f ) add = big*4.0f;
if ( energy < freq ) freq = energy; if ( add > 1.0f-energy ) add = 1.0f-energy;
big -= add/4.0f; // discharge the large battery 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 < 0.0f ) big = 0.0f;
if ( big > 1.0f ) big = 1.0f; if ( big > 1.0f ) big = 1.0f;
m_object->SetEnergy(big); // Shift the large battery dynamic_cast<CPowerContainerObject*>(m_object)->SetEnergy(big); // Shift the large battery
return true; return true;
} }
@ -364,4 +373,3 @@ void CAutoPowerStation::UpdateInterface(float rTime)
pg->SetLevel(m_object->GetEnergy()); pg->SetLevel(m_object->GetEnergy());
} }
} }

View File

@ -111,11 +111,11 @@ Error CAutoResearch::StartAction(int param)
return ERR_RESEARCH_ALREADY; return ERR_RESEARCH_ALREADY;
} }
CObject* power = m_object->GetPower(); if (m_object->GetPower() == nullptr || !m_object->GetPower()->Implements(ObjectInterfaceType::PowerContainer))
if (power == nullptr)
{ {
return ERR_RESEARCH_POWER; return ERR_RESEARCH_POWER;
} }
CPowerContainerObject* power = dynamic_cast<CPowerContainerObject*>(m_object->GetPower());
if ( power->GetCapacity() > 1.0f ) if ( power->GetCapacity() > 1.0f )
{ {
return ERR_RESEARCH_TYPE; return ERR_RESEARCH_TYPE;
@ -150,7 +150,7 @@ Error CAutoResearch::StartAction(int param)
bool CAutoResearch::EventProcess(const Event &event) bool CAutoResearch::EventProcess(const Event &event)
{ {
CObject* power; CPowerContainerObject* power;
Math::Vector pos, speed; Math::Vector pos, speed;
Error message; Error message;
Math::Point dim; Math::Point dim;
@ -218,8 +218,7 @@ bool CAutoResearch::EventProcess(const Event &event)
FireStopUpdate(m_progress, true); // flashes FireStopUpdate(m_progress, true); // flashes
if ( m_progress < 1.0f ) if ( m_progress < 1.0f )
{ {
power = m_object->GetPower(); if ( m_object->GetPower() == nullptr || !m_object->GetPower()->Implements(ObjectInterfaceType::PowerContainer) ) // more battery?
if ( power == 0 ) // more battery?
{ {
SetBusy(false); SetBusy(false);
UpdateInterface(); UpdateInterface();
@ -229,7 +228,8 @@ bool CAutoResearch::EventProcess(const Event &event)
m_speed = 1.0f/1.0f; m_speed = 1.0f/1.0f;
return true; return true;
} }
power->SetEnergy(1.0f-m_progress); power = dynamic_cast<CPowerContainerObject*>(m_object->GetPower());
power->SetEnergyLevel(1.0f-m_progress);
if ( m_lastParticle+m_engine->ParticleAdapt(0.05f) <= m_time ) if ( m_lastParticle+m_engine->ParticleAdapt(0.05f) <= m_time )
{ {
@ -297,16 +297,16 @@ Error CAutoResearch::GetError()
return ERR_BAT_VIRUS; return ERR_BAT_VIRUS;
} }
CObject* power = m_object->GetPower(); if (m_object->GetPower() == nullptr || !m_object->GetPower()->Implements(ObjectInterfaceType::PowerContainer))
if ( power == 0 )
{ {
return ERR_RESEARCH_POWER; return ERR_RESEARCH_POWER;
} }
if ( power != 0 && power->GetCapacity() > 1.0f ) CPowerContainerObject* power = dynamic_cast<CPowerContainerObject*>(m_object->GetPower());
if ( power->GetCapacity() > 1.0f )
{ {
return ERR_RESEARCH_TYPE; return ERR_RESEARCH_TYPE;
} }
if ( power != 0 && power->GetEnergy() < 1.0f ) if ( power->GetEnergy() < 1.0f )
{ {
return ERR_RESEARCH_ENERGY; return ERR_RESEARCH_ENERGY;
} }

View File

@ -95,10 +95,9 @@ void CAutoTower::Init()
bool CAutoTower::EventProcess(const Event &event) bool CAutoTower::EventProcess(const Event &event)
{ {
CObject* power;
CObject* target; CObject* target;
Math::Vector pos; Math::Vector pos;
float angle, energy, quick; float angle, quick;
CAuto::EventProcess(event); CAuto::EventProcess(event);
@ -122,6 +121,14 @@ bool CAutoTower::EventProcess(const Event &event)
return true; return true;
} }
CPowerContainerObject* power = nullptr;
float energy = 0.0f;
if ( m_object->GetPower() != nullptr && m_object->GetPower()->Implements(ObjectInterfaceType::PowerContainer) )
{
power = dynamic_cast<CPowerContainerObject*>(m_object->GetPower());
energy = power->GetEnergy();
}
UpdateInterface(event.rTime); UpdateInterface(event.rTime);
if ( m_phase == ATP_WAIT ) return true; if ( m_phase == ATP_WAIT ) return true;
@ -133,12 +140,6 @@ bool CAutoTower::EventProcess(const Event &event)
FireStopUpdate(m_progress, true); // blinks FireStopUpdate(m_progress, true); // blinks
if ( m_progress < 1.0f ) if ( m_progress < 1.0f )
{ {
energy = 0.0f;
power = m_object->GetPower();
if ( power != 0 )
{
energy = power->GetEnergy()*power->GetCapacity();
}
if ( energy >= ENERGY_FIRE ) if ( energy >= ENERGY_FIRE )
{ {
m_phase = ATP_SEARCH; m_phase = ATP_SEARCH;
@ -173,13 +174,6 @@ bool CAutoTower::EventProcess(const Event &event)
} }
else else
{ {
energy = 0.0f;
power = m_object->GetPower();
if ( power != 0 )
{
energy = power->GetEnergy()*power->GetCapacity();
}
target = SearchTarget(m_targetPos); target = SearchTarget(m_targetPos);
if ( energy < ENERGY_FIRE ) if ( energy < ENERGY_FIRE )
{ {
@ -227,11 +221,10 @@ bool CAutoTower::EventProcess(const Event &event)
m_object->SetPartRotationY(1, m_angleYfinal); m_object->SetPartRotationY(1, m_angleYfinal);
m_object->SetPartRotationZ(2, m_angleZfinal); m_object->SetPartRotationZ(2, m_angleZfinal);
power = m_object->GetPower(); if ( power != nullptr )
if ( power != 0 )
{ {
energy = power->GetEnergy(); energy = power->GetEnergy();
energy -= ENERGY_FIRE/power->GetCapacity(); energy -= ENERGY_FIRE;
power->SetEnergy(energy); power->SetEnergy(energy);
} }
@ -321,18 +314,16 @@ Error CAutoTower::GetError()
return ERR_BAT_VIRUS; return ERR_BAT_VIRUS;
} }
CObject* power = m_object->GetPower(); if ( m_object->GetPower() == nullptr || !m_object->GetPower()->Implements(ObjectInterfaceType::PowerContainer) )
if ( power == nullptr )
{ {
return ERR_TOWER_POWER; // no battery return ERR_TOWER_POWER; // no battery
} }
else
if ( dynamic_cast<CPowerContainerObject*>(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; return ERR_OK;
} }
@ -457,7 +448,7 @@ void CAutoTower::UpdateInterface(float rTime)
Ui::CWindow* 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; 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 ) if ( pg != 0 )
{ {
float energy = GetObjectEnergy(m_object); float energy = GetObjectEnergy(m_object);
@ -506,4 +497,3 @@ bool CAutoTower::Read(CLevelParserLine* line)
return true; return true;
} }

View File

@ -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<int>(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;
};

View File

@ -22,6 +22,8 @@
#include "object/object.h" #include "object/object.h"
#include "object/object_interface_type.h" #include "object/object_interface_type.h"
#include "object/interface/power_container_object.h"
class CObject; class CObject;
/** /**
@ -55,9 +57,9 @@ inline float GetObjectEnergy(CObject* object)
if (object->Implements(ObjectInterfaceType::Powered)) if (object->Implements(ObjectInterfaceType::Powered))
{ {
CObject* power = dynamic_cast<CPoweredObject*>(object)->GetPower(); CObject* power = dynamic_cast<CPoweredObject*>(object)->GetPower();
if (power != nullptr) if (power != nullptr && power->Implements(ObjectInterfaceType::PowerContainer))
{ {
energy = power->GetEnergy(); energy = dynamic_cast<CPowerContainerObject*>(power)->GetEnergy();
} }
} }

View File

@ -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->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->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); 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->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->SetCameraCollisionSphere(Math::Sphere(Math::Vector(-15.0f, 5.0f, 0.0f), 6.0f));
obj->SetEnergy(power); obj->SetEnergyLevel(power);
} }
if ( type == OBJECT_CONVERT ) if ( type == OBJECT_CONVERT )
@ -1068,8 +1068,8 @@ CObjectUPtr CObjectFactory::CreateBuilding(const ObjectCreateParams& params)
pPower->SetTransporter(obj.get()); pPower->SetTransporter(obj.get());
SetPower(pPower); SetPower(pPower);
if ( power <= 1.0f ) pPower->obj->SetEnergy(power); if ( power <= 1.0f ) pPower->obj->SetEnergyLevel(power);
else pPower->obj->SetEnergy(power/100.0f); else pPower->obj->SetEnergyLevel(power/100.0f);
} }
#endif #endif
@ -1102,7 +1102,7 @@ CObjectUPtr CObjectFactory::CreateResource(const ObjectCreateParams& params)
int rank = m_engine->CreateObject(); int rank = m_engine->CreateObject();
m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_FIX); // it is a stationary object m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_FIX); // it is a stationary object
obj->SetObjectRank(0, rank); obj->SetObjectRank(0, rank);
obj->SetEnergy(power); obj->SetEnergyLevel(power);
std::string name; std::string name;
if ( type == OBJECT_STONE ) name = "stone.mod"; if ( type == OBJECT_STONE ) name = "stone.mod";

View File

@ -42,6 +42,7 @@ enum class ObjectInterfaceType
Powered, //!< object powered with power cell Powered, //!< object powered with power cell
Movable, //!< objects that can move Movable, //!< objects that can move
Controllable, //!< objects that can be selected and controlled by the player 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 Old, //!< old objects, TODO: remove once no longer necessary
Max //!< maximum value (for getting number of items in enum) Max //!< maximum value (for getting number of items in enum)
}; };

View File

@ -103,6 +103,7 @@ COldObject::COldObject(int id)
, CPoweredObject(m_implementedInterfaces) , CPoweredObject(m_implementedInterfaces)
, CMovableObject(m_implementedInterfaces) , CMovableObject(m_implementedInterfaces)
, CControllableObject(m_implementedInterfaces) , CControllableObject(m_implementedInterfaces)
, CPowerContainerObject(m_implementedInterfaces)
{ {
// A bit of a hack since we don't have subclasses yet, set externally in SetProgrammable() // A bit of a hack since we don't have subclasses yet, set externally in SetProgrammable()
m_implementedInterfaces[static_cast<int>(ObjectInterfaceType::Programmable)] = false; m_implementedInterfaces[static_cast<int>(ObjectInterfaceType::Programmable)] = false;
@ -764,8 +765,8 @@ void COldObject::Write(CLevelParserLine* line)
if ( GetCameraLock() ) if ( GetCameraLock() )
line->AddParam("cameraLock", MakeUnique<CLevelParserParam>(GetCameraLock())); line->AddParam("cameraLock", MakeUnique<CLevelParserParam>(GetCameraLock()));
if ( GetEnergy() != 0.0f ) if ( GetEnergyLevel() != 0.0f )
line->AddParam("energy", MakeUnique<CLevelParserParam>(GetEnergy())); line->AddParam("energy", MakeUnique<CLevelParserParam>(GetEnergyLevel()));
if ( GetCapacity() != 1.0f ) if ( GetCapacity() != 1.0f )
line->AddParam("capacity", MakeUnique<CLevelParserParam>(GetCapacity())); line->AddParam("capacity", MakeUnique<CLevelParserParam>(GetCapacity()));
@ -872,7 +873,7 @@ void COldObject::Read(CLevelParserLine* line)
SetCameraDist(line->GetParam("cameraDist")->AsFloat(50.0f)); SetCameraDist(line->GetParam("cameraDist")->AsFloat(50.0f));
SetCameraLock(line->GetParam("cameraLock")->AsBool(false)); 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)); SetCapacity(line->GetParam("capacity")->AsFloat(1.0f));
SetShield(line->GetParam("shield")->AsFloat(1.0f)); SetShield(line->GetParam("shield")->AsFloat(1.0f));
SetRange(line->GetParam("range")->AsFloat(1.0f)); SetRange(line->GetParam("range")->AsFloat(1.0f));
@ -2315,14 +2316,14 @@ float COldObject::GetAbsTime()
// Management of energy contained in a battery. // Management of energy contained in a battery.
// Single subject possesses the battery energy, but not the vehicle that carries the 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 < 0.0f ) level = 0.0f;
if ( level > 1.0f ) level = 1.0f; if ( level > 1.0f ) level = 1.0f;
m_energy = level; m_energy = level;
} }
float COldObject::GetEnergy() float COldObject::GetEnergyLevel()
{ {
if ( m_type != OBJECT_POWER && if ( m_type != OBJECT_POWER &&
m_type != OBJECT_ATOMIC && m_type != OBJECT_ATOMIC &&
@ -2346,6 +2347,11 @@ float COldObject::GetCapacity()
return m_capacity; return m_capacity;
} }
bool COldObject::IsRechargeable()
{
return m_type == OBJECT_POWER;
}
// Management of the shield. // Management of the shield.

View File

@ -31,6 +31,7 @@
#include "object/interface/interactive_object.h" #include "object/interface/interactive_object.h"
#include "object/interface/jostleable_object.h" #include "object/interface/jostleable_object.h"
#include "object/interface/movable_object.h" #include "object/interface/movable_object.h"
#include "object/interface/power_container_object.h"
#include "object/interface/powered_object.h" #include "object/interface/powered_object.h"
#include "object/interface/programmable_object.h" #include "object/interface/programmable_object.h"
#include "object/interface/task_executor_object.h" #include "object/interface/task_executor_object.h"
@ -87,7 +88,8 @@ class COldObject : public CObject,
public CCarrierObject, public CCarrierObject,
public CPoweredObject, public CPoweredObject,
public CMovableObject, public CMovableObject,
public CControllableObject public CControllableObject,
public CPowerContainerObject
{ {
friend class CObjectFactory; friend class CObjectFactory;
friend class CObjectManager; friend class CObjectManager;
@ -198,11 +200,13 @@ public:
float GetAbsTime(); float GetAbsTime();
void SetEnergy(float level) override; void SetEnergyLevel(float level) override;
float GetEnergy() override; float GetEnergyLevel() override;
float GetCapacity() override; float GetCapacity() override;
bool IsRechargeable() override;
void SetShield(float level) override; void SetShield(float level) override;
float GetShield() override; float GetShield() override;

View File

@ -104,22 +104,6 @@ Character* COldObjectInterface::GetCharacter()
throw std::logic_error("GetCharacter: not implemented!"); 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) void COldObjectInterface::SetShield(float level)
{ {
throw std::logic_error("SetShield: not implemented!"); throw std::logic_error("SetShield: not implemented!");

View File

@ -93,11 +93,6 @@ public:
virtual void FlatParent(); 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) // This goes to CShieldedObject (probably will inherit from CDestroyableObject)
virtual void SetShield(float level); virtual void SetShield(float level);
virtual float GetShield(); virtual float GetShield();

View File

@ -1235,8 +1235,8 @@ void CRobotMain::ExecuteCmd(char *cmd)
if (object->Implements(ObjectInterfaceType::Powered)) if (object->Implements(ObjectInterfaceType::Powered))
{ {
CObject* power = dynamic_cast<CPoweredObject*>(object)->GetPower(); CObject* power = dynamic_cast<CPoweredObject*>(object)->GetPower();
if (power != nullptr) if (power != nullptr && power->Implements(ObjectInterfaceType::PowerContainer))
power->SetEnergy(1.0f); dynamic_cast<CPowerContainerObject*>(power)->SetEnergyLevel(1.0f);
} }
object->SetShield(1.0f); object->SetShield(1.0f);
@ -1257,8 +1257,8 @@ void CRobotMain::ExecuteCmd(char *cmd)
if (object->Implements(ObjectInterfaceType::Powered)) if (object->Implements(ObjectInterfaceType::Powered))
{ {
CObject* power = dynamic_cast<CPoweredObject*>(object)->GetPower(); CObject* power = dynamic_cast<CPoweredObject*>(object)->GetPower();
if (power != nullptr) if (power != nullptr && power->Implements(ObjectInterfaceType::PowerContainer))
power->SetEnergy(1.0f); dynamic_cast<CPowerContainerObject*>(power)->SetEnergyLevel(1.0f);
} }
} }
return; return;

View File

@ -98,22 +98,24 @@ int CSceneCondition::CountObjects()
continue; continue;
float energyLevel = -1; float energyLevel = -1;
CObject* power = nullptr; CPowerContainerObject* power = nullptr;
if (obj->Implements(ObjectInterfaceType::Powered)) if (obj->Implements(ObjectInterfaceType::PowerContainer))
power = dynamic_cast<CPoweredObject*>(obj)->GetPower(); {
power = dynamic_cast<CPowerContainerObject*>(obj);
}
else if (obj->Implements(ObjectInterfaceType::Powered))
{
CObject* powerObj = dynamic_cast<CPoweredObject*>(obj)->GetPower();
if(powerObj != nullptr && powerObj->Implements(ObjectInterfaceType::PowerContainer))
{
power = dynamic_cast<CPowerContainerObject*>(powerObj);
}
}
if (power != nullptr) if (power != nullptr)
{ {
energyLevel = power->GetEnergy(); energyLevel = power->GetEnergy();
if (power->GetType() == OBJECT_ATOMIC) energyLevel *= 100; if (power->GetCapacity() > 1.0f) energyLevel *= 10; // TODO: Who designed it like that ?!?!
}
else
{
if (obj->GetType() == OBJECT_POWER || obj->GetType() == OBJECT_ATOMIC)
{
energyLevel = obj->GetEnergy();
if (obj->GetType() == OBJECT_ATOMIC) energyLevel *= 100;
}
} }
if (energyLevel < this->powermin || energyLevel > this->powermax) continue; if (energyLevel < this->powermin || energyLevel > this->powermax) continue;

View File

@ -78,14 +78,15 @@ bool CTaskFire::EventProcess(const Event &event)
m_lastSound -= event.rTime; m_lastSound -= event.rTime;
m_progress += event.rTime*m_speed; m_progress += event.rTime*m_speed;
CObject* power = m_object->GetPower(); CPowerContainerObject* power = nullptr;
if (power != nullptr) if (m_object->GetPower() != nullptr && m_object->GetPower()->Implements(ObjectInterfaceType::PowerContainer))
{ {
power = dynamic_cast<CPowerContainerObject*>(m_object->GetPower());
energy = power->GetEnergy(); energy = power->GetEnergy();
if ( m_bOrganic ) fire = ENERGY_FIREi; if ( m_bOrganic ) fire = ENERGY_FIREi;
else if ( m_bRay ) fire = ENERGY_FIREr; else if ( m_bRay ) fire = ENERGY_FIREr;
else fire = ENERGY_FIRE; else fire = ENERGY_FIRE;
energy -= event.rTime*fire/power->GetCapacity(); energy -= event.rTime*fire;
power->SetEnergy(energy); power->SetEnergy(energy);
} }
@ -314,13 +315,13 @@ Error CTaskFire::Start(float delay)
assert(m_object->Implements(ObjectInterfaceType::Powered)); assert(m_object->Implements(ObjectInterfaceType::Powered));
CObject* power = dynamic_cast<CPoweredObject*>(m_object)->GetPower(); CObject* power = dynamic_cast<CPoweredObject*>(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<CPowerContainerObject*>(power)->GetEnergy();
if ( m_bOrganic ) fire = m_delay*ENERGY_FIREi; if ( m_bOrganic ) fire = m_delay*ENERGY_FIREi;
else if ( m_bRay ) fire = m_delay*ENERGY_FIREr; else if ( m_bRay ) fire = m_delay*ENERGY_FIREr;
else fire = m_delay*ENERGY_FIRE; 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_speed = 1.0f/m_delay;
m_progress = 0.0f; m_progress = 0.0f;
@ -386,4 +387,3 @@ bool CTaskFire::Abort()
//? m_camera->StopCentering(m_object, 1.0f); //? m_camera->StopCentering(m_object, 1.0f);
return true; return true;
} }

View File

@ -363,9 +363,9 @@ Error CTaskManip::Start(TaskManipOrder order, TaskManipArm arm)
m_energy = 0.0f; m_energy = 0.0f;
power = m_object->GetPower(); power = m_object->GetPower();
if ( power != 0 ) if ( power != nullptr && power->Implements(ObjectInterfaceType::PowerContainer) )
{ {
m_energy = power->GetEnergy(); m_energy = dynamic_cast<CPowerContainerObject*>(power)->GetEnergy();
} }
if ( !m_physics->GetLand() ) return ERR_MANIP_FLY; 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.5f*amplitude, 1.0f*frequency, time-0.1f, SOPER_CONTINUE);
m_sound->AddEnvelope(i, 0.0f, 0.3f*frequency, 0.1f, SOPER_STOP); m_sound->AddEnvelope(i, 0.0f, 0.3f*frequency, 0.1f, SOPER_STOP);
} }

View File

@ -104,11 +104,12 @@ bool CTaskRecover::EventProcess(const Event &event)
if ( m_phase == TRP_OPER ) if ( m_phase == TRP_OPER )
{ {
assert(m_object->Implements(ObjectInterfaceType::Powered)); assert(m_object->Implements(ObjectInterfaceType::Powered));
CObject* power = dynamic_cast<CPoweredObject*>(m_object)->GetPower(); CObject* powerObj = dynamic_cast<CPoweredObject*>(m_object)->GetPower();
if (power != nullptr) if (powerObj != nullptr && powerObj->Implements(ObjectInterfaceType::PowerContainer))
{ {
CPowerContainerObject* power = dynamic_cast<CPowerContainerObject*>(powerObj);
energy = power->GetEnergy(); energy = power->GetEnergy();
energy -= event.rTime * ENERGY_RECOVER / power->GetCapacity() * m_speed; energy -= event.rTime * ENERGY_RECOVER * m_speed;
power->SetEnergy(energy); power->SetEnergy(energy);
} }
@ -186,10 +187,10 @@ Error CTaskRecover::Start()
assert(m_object->Implements(ObjectInterfaceType::Powered)); assert(m_object->Implements(ObjectInterfaceType::Powered));
CObject* power = dynamic_cast<CPoweredObject*>(m_object)->GetPower(); CObject* power = dynamic_cast<CPoweredObject*>(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(); float energy = dynamic_cast<CPowerContainerObject*>(power)->GetEnergy();
if ( energy < ENERGY_RECOVER/power->GetCapacity()+0.05f ) return ERR_RECOVER_ENERGY; if ( energy < ENERGY_RECOVER+0.05f ) return ERR_RECOVER_ENERGY;
Math::Matrix* mat = m_object->GetWorldMatrix(0); Math::Matrix* mat = m_object->GetWorldMatrix(0);
Math::Vector pos = Math::Vector(RECOVER_DIST, 3.3f, 0.0f); 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); return CObjectManager::GetInstancePointer()->FindNearest(nullptr, m_recoverPos, {OBJECT_RUINmobilew1, OBJECT_RUINmobilew2, OBJECT_RUINmobilet1, OBJECT_RUINmobilet2, OBJECT_RUINmobiler1, OBJECT_RUINmobiler2}, 40.0f/g_unit);
} }

View File

@ -64,7 +64,6 @@ CTaskShield::~CTaskShield()
bool CTaskShield::EventProcess(const Event &event) bool CTaskShield::EventProcess(const Event &event)
{ {
CObject* power;
Math::Matrix* mat; Math::Matrix* mat;
Math::Matrix matrix; Math::Matrix matrix;
Math::Vector pos, speed, goal, angle; Math::Vector pos, speed, goal, angle;
@ -113,10 +112,11 @@ bool CTaskShield::EventProcess(const Event &event)
{ {
energy = (1.0f/ENERGY_TIME)*event.rTime; energy = (1.0f/ENERGY_TIME)*event.rTime;
energy *= GetRadius()/RADIUS_SHIELD_MAX; energy *= GetRadius()/RADIUS_SHIELD_MAX;
power = m_object->GetPower(); CObject* powerObj = dynamic_cast<CPoweredObject*>(m_object)->GetPower();
if (power != nullptr) if (powerObj != nullptr && powerObj->Implements(ObjectInterfaceType::PowerContainer))
{ {
power->SetEnergy(power->GetEnergy()-energy/power->GetCapacity()); CPowerContainerObject* power = dynamic_cast<CPowerContainerObject*>(powerObj);
power->SetEnergy(power->GetEnergy()-energy);
} }
m_energyUsed += energy; m_energyUsed += energy;
@ -293,8 +293,8 @@ Error CTaskShield::Start(TaskShieldMode mode, float delay)
if ( !m_physics->GetLand() ) return ERR_SHIELD_VEH; if ( !m_physics->GetLand() ) return ERR_SHIELD_VEH;
CObject* power = m_object->GetPower(); CObject* power = m_object->GetPower();
if (power == nullptr) return ERR_SHIELD_ENERGY; if (power == nullptr || !power->Implements(ObjectInterfaceType::PowerContainer)) return ERR_SHIELD_ENERGY;
float energy = power->GetEnergy(); float energy = dynamic_cast<CPowerContainerObject*>(power)->GetEnergy();
if ( energy == 0.0f ) return ERR_SHIELD_ENERGY; if ( energy == 0.0f ) return ERR_SHIELD_ENERGY;
Math::Matrix* mat = m_object->GetWorldMatrix(0); Math::Matrix* mat = m_object->GetWorldMatrix(0);
@ -369,7 +369,6 @@ Error CTaskShield::Stop()
Error CTaskShield::IsEnded() Error CTaskShield::IsEnded()
{ {
CObject* power;
Math::Vector pos, speed; Math::Vector pos, speed;
Math::Point dim; Math::Point dim;
float energy; float energy;
@ -381,15 +380,7 @@ Error CTaskShield::IsEnded()
{ {
m_object->SetShieldRadius(GetRadius()); m_object->SetShieldRadius(GetRadius());
power = m_object->GetPower(); energy = GetObjectEnergy(m_object);
if ( power == 0 )
{
energy = 0.0f;
}
else
{
energy = power->GetEnergy();
}
if ( energy == 0.0f || m_delay <= 0.0f ) if ( energy == 0.0f || m_delay <= 0.0f )
{ {

View File

@ -97,10 +97,14 @@ bool CTaskTerraform::EventProcess(const Event &event)
{ {
power->SetScale(1.0f+m_progress*1.0f); power->SetScale(1.0f+m_progress*1.0f);
energy = power->GetEnergy(); if (power->Implements(ObjectInterfaceType::PowerContainer))
energy -= event.rTime*ENERGY_TERRA/power->GetCapacity()/4.0f; {
if ( energy < 0.0f ) energy = 0.0f; CPowerContainerObject* powerContainer = dynamic_cast<CPowerContainerObject*>(power);
power->SetEnergy(energy); 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; if ( type != OBJECT_MOBILErt ) return ERR_TERRA_VEH;
power = m_object->GetPower(); power = m_object->GetPower();
if ( power == 0 ) return ERR_TERRA_ENERGY; if ( power == nullptr || !power->Implements(ObjectInterfaceType::PowerContainer) ) return ERR_TERRA_ENERGY;
energy = power->GetEnergy(); energy = dynamic_cast<CPowerContainerObject*>(power)->GetEnergy();
if ( energy < ENERGY_TERRA/power->GetCapacity()+0.05f ) return ERR_TERRA_ENERGY; if ( energy < ENERGY_TERRA+0.05f ) return ERR_TERRA_ENERGY;
speed = m_physics->GetMotorSpeed(); speed = m_physics->GetMotorSpeed();
if ( speed.x != 0.0f || if ( speed.x != 0.0f ||

View File

@ -774,7 +774,7 @@ bool CPhysics::EventProcess(const Event &event)
void CPhysics::MotorUpdate(float aTime, float rTime) void CPhysics::MotorUpdate(float aTime, float rTime)
{ {
ObjectType type; ObjectType type;
CObject* power = nullptr; CPowerContainerObject* power = nullptr;
Math::Vector pos, motorSpeed; Math::Vector pos, motorSpeed;
float energy, speed, factor, h; float energy, speed, factor, h;
@ -801,7 +801,7 @@ void CPhysics::MotorUpdate(float aTime, float rTime)
type == OBJECT_TECH ) type == OBJECT_TECH )
{ {
power = nullptr; power = nullptr;
if (IsObjectCarryingCargo(m_object)&& // carries something? if (IsObjectCarryingCargo(m_object) && // carries something?
!m_bFreeze ) !m_bFreeze )
{ {
motorSpeed.x *= 0.7f; // forward more slowly motorSpeed.x *= 0.7f; // forward more slowly
@ -835,8 +835,8 @@ void CPhysics::MotorUpdate(float aTime, float rTime)
{ {
if (m_object->Implements(ObjectInterfaceType::Powered)) if (m_object->Implements(ObjectInterfaceType::Powered))
{ {
power = dynamic_cast<CPoweredObject*>(m_object)->GetPower(); // searches for the object battery uses power = dynamic_cast<CPowerContainerObject*>(dynamic_cast<CPoweredObject*>(m_object)->GetPower()); // searches for the object battery uses
if ( power == nullptr || power->GetEnergy() == 0.0f ) // no battery or flat? if ( GetObjectEnergy(m_object) == 0.0f ) // no battery or flat?
{ {
motorSpeed.x = 0.0f; motorSpeed.x = 0.0f;
motorSpeed.z = 0.0f; motorSpeed.z = 0.0f;
@ -1020,8 +1020,6 @@ void CPhysics::MotorUpdate(float aTime, float rTime)
type == OBJECT_MOBILEic || type == OBJECT_MOBILEic ||
type == OBJECT_MOBILEii ) factor = 0.5f; type == OBJECT_MOBILEii ) factor = 0.5f;
factor /= power->GetCapacity();
energy = power->GetEnergy(); energy = power->GetEnergy();
energy -= fabs(motorSpeed.x)*rTime*factor*0.005f; energy -= fabs(motorSpeed.x)*rTime*factor*0.005f;
energy -= fabs(motorSpeed.z)*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)) if (m_object->Implements(ObjectInterfaceType::Powered))
{ {
CObject* power = dynamic_cast<CPoweredObject*>(m_object)->GetPower(); // searches for the object battery used CObject* power = dynamic_cast<CPoweredObject*>(m_object)->GetPower(); // searches for the object battery used
if (power == nullptr) if (power == nullptr || !power->Implements(ObjectInterfaceType::PowerContainer))
{ {
return ERR_VEH_POWER; return ERR_VEH_POWER;
} }
else else
{ {
if ( power->GetEnergy() == 0.0f ) return ERR_VEH_ENERGY; if ( dynamic_cast<CPowerContainerObject*>(power)->GetEnergy() == 0.0f ) return ERR_VEH_ENERGY;
} }
} }

View File

@ -1579,10 +1579,11 @@ void CObjectInterface::UpdateInterface(float rTime)
if (m_object->Implements(ObjectInterfaceType::Powered)) if (m_object->Implements(ObjectInterfaceType::Powered))
{ {
CObject* power = dynamic_cast<CPoweredObject*>(m_object)->GetPower(); CObject* power = dynamic_cast<CPoweredObject*>(m_object)->GetPower();
if (power != nullptr) if (power != nullptr && power->Implements(ObjectInterfaceType::PowerContainer))
{ {
energy = power->GetEnergy(); CPowerContainerObject* powerContainer = dynamic_cast<CPowerContainerObject*>(power);
limit = energy*power->GetCapacity(); energy = powerContainer->GetEnergyLevel();
limit = powerContainer->GetEnergy();
} }
} }
icon = 0; // red/green icon = 0; // red/green