Slotted object interface
parent
fabbdda964
commit
76314f522f
|
@ -377,7 +377,6 @@ set(BASE_SOURCES
|
||||||
object/implementation/programmable_impl.h
|
object/implementation/programmable_impl.h
|
||||||
object/implementation/task_executor_impl.cpp
|
object/implementation/task_executor_impl.cpp
|
||||||
object/implementation/task_executor_impl.h
|
object/implementation/task_executor_impl.h
|
||||||
object/interface/carrier_object.h
|
|
||||||
object/interface/controllable_object.h
|
object/interface/controllable_object.h
|
||||||
object/interface/damageable_object.h
|
object/interface/damageable_object.h
|
||||||
object/interface/destroyable_object.h
|
object/interface/destroyable_object.h
|
||||||
|
@ -388,12 +387,12 @@ set(BASE_SOURCES
|
||||||
object/interface/jostleable_object.h
|
object/interface/jostleable_object.h
|
||||||
object/interface/movable_object.h
|
object/interface/movable_object.h
|
||||||
object/interface/power_container_object.h
|
object/interface/power_container_object.h
|
||||||
object/interface/powered_object.h
|
|
||||||
object/interface/program_storage_object.h
|
object/interface/program_storage_object.h
|
||||||
object/interface/programmable_object.h
|
object/interface/programmable_object.h
|
||||||
object/interface/ranged_object.h
|
object/interface/ranged_object.h
|
||||||
object/interface/shielded_auto_regen_object.h
|
object/interface/shielded_auto_regen_object.h
|
||||||
object/interface/shielded_object.h
|
object/interface/shielded_object.h
|
||||||
|
object/interface/slotted_object.h
|
||||||
object/interface/task_executor_object.h
|
object/interface/task_executor_object.h
|
||||||
object/interface/trace_drawing_object.cpp
|
object/interface/trace_drawing_object.cpp
|
||||||
object/interface/trace_drawing_object.h
|
object/interface/trace_drawing_object.h
|
||||||
|
|
|
@ -37,10 +37,9 @@
|
||||||
#include "object/object.h"
|
#include "object/object.h"
|
||||||
#include "object/object_manager.h"
|
#include "object/object_manager.h"
|
||||||
|
|
||||||
#include "object/interface/carrier_object.h"
|
|
||||||
#include "object/interface/controllable_object.h"
|
#include "object/interface/controllable_object.h"
|
||||||
#include "object/interface/movable_object.h"
|
#include "object/interface/movable_object.h"
|
||||||
#include "object/interface/powered_object.h"
|
#include "object/interface/slotted_object.h"
|
||||||
#include "object/interface/transportable_object.h"
|
#include "object/interface/transportable_object.h"
|
||||||
|
|
||||||
#include "physics/physics.h"
|
#include "physics/physics.h"
|
||||||
|
@ -57,18 +56,15 @@ static void SetTransparency(CObject* obj, float value)
|
||||||
{
|
{
|
||||||
obj->SetTransparency(value);
|
obj->SetTransparency(value);
|
||||||
|
|
||||||
if (obj->Implements(ObjectInterfaceType::Carrier))
|
if (obj->Implements(ObjectInterfaceType::Slotted))
|
||||||
{
|
{
|
||||||
CObject* cargo = dynamic_cast<CCarrierObject&>(*obj).GetCargo();
|
CSlottedObject *slotted = dynamic_cast<CSlottedObject*>(obj);
|
||||||
if (cargo != nullptr)
|
for(int slot = slotted->GetNumSlots()-1; slot >= 0; slot--)
|
||||||
cargo->SetTransparency(value);
|
{
|
||||||
}
|
CObject *contained = slotted->GetSlotContainedObject(slot);
|
||||||
|
if (contained != nullptr)
|
||||||
if (obj->Implements(ObjectInterfaceType::Powered))
|
SetTransparency(contained, value);
|
||||||
{
|
}
|
||||||
CObject* power = dynamic_cast<CPoweredObject&>(*obj).GetPower();
|
|
||||||
if (power != nullptr)
|
|
||||||
power->SetTransparency(value);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,6 +35,8 @@
|
||||||
#include "object/object_manager.h"
|
#include "object/object_manager.h"
|
||||||
#include "object/old_object.h"
|
#include "object/old_object.h"
|
||||||
|
|
||||||
|
#include "object/interface/slotted_object.h"
|
||||||
|
|
||||||
#include "object/motion/motionhuman.h"
|
#include "object/motion/motionhuman.h"
|
||||||
|
|
||||||
#include "object/subclass/shielder.h"
|
#include "object/subclass/shielder.h"
|
||||||
|
@ -127,9 +129,7 @@ bool CPyro::Create(PyroType type, CObject* obj, float force)
|
||||||
|
|
||||||
// Seeking the position of the battery.
|
// Seeking the position of the battery.
|
||||||
|
|
||||||
CObject* power = nullptr;
|
CObject* power = GetObjectInPowerCellSlot(obj);
|
||||||
if (obj->Implements(ObjectInterfaceType::Powered))
|
|
||||||
power = dynamic_cast<CPoweredObject&>(*obj).GetPower();
|
|
||||||
|
|
||||||
if (power == nullptr)
|
if (power == nullptr)
|
||||||
{
|
{
|
||||||
|
@ -1385,25 +1385,16 @@ void CPyro::DeleteObject(bool primary, bool secondary)
|
||||||
type != OBJECT_NUCLEAR &&
|
type != OBJECT_NUCLEAR &&
|
||||||
type != OBJECT_ENERGY )
|
type != OBJECT_ENERGY )
|
||||||
{
|
{
|
||||||
if (m_object->Implements(ObjectInterfaceType::Powered))
|
if (m_object->Implements(ObjectInterfaceType::Slotted))
|
||||||
{
|
{
|
||||||
CPoweredObject* poweredObject = dynamic_cast<CPoweredObject*>(m_object);
|
CSlottedObject* asSlotted = dynamic_cast<CSlottedObject*>(m_object);
|
||||||
CObject* sub = poweredObject->GetPower();
|
for (int slot = asSlotted->GetNumSlots() - 1; slot >= 0; slot--)
|
||||||
if (sub != nullptr)
|
|
||||||
{
|
{
|
||||||
CObjectManager::GetInstancePointer()->DeleteObject(sub);
|
if (CObject* sub = asSlotted->GetSlotContainedObject(slot))
|
||||||
poweredObject->SetPower(nullptr);
|
{
|
||||||
}
|
CObjectManager::GetInstancePointer()->DeleteObject(sub);
|
||||||
}
|
asSlotted->SetSlotContainedObject(slot, nullptr);
|
||||||
|
}
|
||||||
if (m_object->Implements(ObjectInterfaceType::Carrier))
|
|
||||||
{
|
|
||||||
CCarrierObject* carrierObject = dynamic_cast<CCarrierObject*>(m_object);
|
|
||||||
CObject* sub = carrierObject->GetCargo();
|
|
||||||
if (sub != nullptr)
|
|
||||||
{
|
|
||||||
CObjectManager::GetInstancePointer()->DeleteObject(sub);
|
|
||||||
carrierObject->SetCargo(nullptr);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1416,18 +1407,15 @@ void CPyro::DeleteObject(bool primary, bool secondary)
|
||||||
CObject* transporter = dynamic_cast<CTransportableObject&>(*m_object).GetTransporter();
|
CObject* transporter = dynamic_cast<CTransportableObject&>(*m_object).GetTransporter();
|
||||||
if (transporter != nullptr)
|
if (transporter != nullptr)
|
||||||
{
|
{
|
||||||
if (transporter->Implements(ObjectInterfaceType::Powered))
|
assert(transporter->Implements(ObjectInterfaceType::Slotted));
|
||||||
|
CSlottedObject* asSlotted = dynamic_cast<CSlottedObject*>(transporter);
|
||||||
|
for (int slotNum = asSlotted->GetNumSlots() - 1; slotNum >= 0; slotNum--)
|
||||||
{
|
{
|
||||||
CPoweredObject* powered = dynamic_cast<CPoweredObject*>(transporter);
|
if (asSlotted->GetSlotContainedObject(slotNum) == m_object)
|
||||||
if (powered->GetPower() == m_object)
|
{
|
||||||
powered->SetPower(nullptr);
|
asSlotted->SetSlotContainedObject(slotNum, nullptr);
|
||||||
}
|
break;
|
||||||
|
}
|
||||||
if (transporter->Implements(ObjectInterfaceType::Carrier))
|
|
||||||
{
|
|
||||||
CCarrierObject* carrier = dynamic_cast<CCarrierObject*>(transporter);
|
|
||||||
if (carrier->GetCargo() == m_object)
|
|
||||||
carrier->SetCargo(nullptr);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2196,11 +2184,10 @@ void CPyro::BurnProgress()
|
||||||
oldObj->SetPartRotation(m_burnPart[i].part, pos);
|
oldObj->SetPartRotation(m_burnPart[i].part, pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_object->Implements(ObjectInterfaceType::Powered))
|
// TODO: should this apply to every slot?
|
||||||
|
if (CObject* sub = GetObjectInPowerCellSlot(m_object)) // is there a battery?
|
||||||
{
|
{
|
||||||
CObject* sub = dynamic_cast<CPoweredObject&>(*m_object).GetPower();
|
sub->SetScaleY(1.0f - m_progress); // complete flattening
|
||||||
if (sub != nullptr) // is there a battery?
|
|
||||||
sub->SetScaleY(1.0f - m_progress); // complete flattening
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -69,6 +69,8 @@
|
||||||
|
|
||||||
#include "object/auto/auto.h"
|
#include "object/auto/auto.h"
|
||||||
|
|
||||||
|
#include "object/interface/slotted_object.h"
|
||||||
|
|
||||||
#include "object/motion/motion.h"
|
#include "object/motion/motion.h"
|
||||||
#include "object/motion/motionhuman.h"
|
#include "object/motion/motionhuman.h"
|
||||||
#include "object/motion/motiontoto.h"
|
#include "object/motion/motiontoto.h"
|
||||||
|
@ -1392,12 +1394,8 @@ void CRobotMain::ExecuteCmd(const std::string& cmd)
|
||||||
CObject* object = GetSelect();
|
CObject* object = GetSelect();
|
||||||
if (object != nullptr)
|
if (object != nullptr)
|
||||||
{
|
{
|
||||||
if (object->Implements(ObjectInterfaceType::Powered))
|
if (CPowerContainerObject *power = GetObjectPowerCell(object))
|
||||||
{
|
power->SetEnergyLevel(1.0f);
|
||||||
CObject* power = dynamic_cast<CPoweredObject&>(*object).GetPower();
|
|
||||||
if (power != nullptr && power->Implements(ObjectInterfaceType::PowerContainer))
|
|
||||||
dynamic_cast<CPowerContainerObject&>(*power).SetEnergyLevel(1.0f);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (object->Implements(ObjectInterfaceType::Shielded))
|
if (object->Implements(ObjectInterfaceType::Shielded))
|
||||||
dynamic_cast<CShieldedObject&>(*object).SetShield(1.0f);
|
dynamic_cast<CShieldedObject&>(*object).SetShield(1.0f);
|
||||||
|
@ -1414,12 +1412,8 @@ void CRobotMain::ExecuteCmd(const std::string& cmd)
|
||||||
|
|
||||||
if (object != nullptr)
|
if (object != nullptr)
|
||||||
{
|
{
|
||||||
if (object->Implements(ObjectInterfaceType::Powered))
|
if (CPowerContainerObject *power = GetObjectPowerCell(object))
|
||||||
{
|
power->SetEnergyLevel(1.0f);
|
||||||
CObject* power = dynamic_cast<CPoweredObject&>(*object).GetPower();
|
|
||||||
if (power != nullptr && power->Implements(ObjectInterfaceType::PowerContainer))
|
|
||||||
dynamic_cast<CPowerContainerObject&>(*power).SetEnergyLevel(1.0f);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -2007,21 +2001,12 @@ CObject* CRobotMain::DetectObject(Math::Point pos)
|
||||||
if (obj->GetProxyActivate()) continue;
|
if (obj->GetProxyActivate()) continue;
|
||||||
|
|
||||||
CObject* target = obj;
|
CObject* target = obj;
|
||||||
|
// TODO: should this also apply to slots other than power cell slots?
|
||||||
if (obj->Implements(ObjectInterfaceType::PowerContainer) && obj->Implements(ObjectInterfaceType::Transportable))
|
if (obj->Implements(ObjectInterfaceType::PowerContainer) && obj->Implements(ObjectInterfaceType::Transportable))
|
||||||
{
|
{
|
||||||
target = dynamic_cast<CTransportableObject&>(*obj).GetTransporter(); // battery connected
|
CObject *transporter = dynamic_cast<CTransportableObject&>(*obj).GetTransporter(); // battery connected
|
||||||
if (target == nullptr)
|
if (transporter != nullptr && obj == GetObjectInPowerCellSlot(transporter))
|
||||||
{
|
target = transporter;
|
||||||
target = obj; // standalone battery
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (!target->Implements(ObjectInterfaceType::Powered) || dynamic_cast<CPoweredObject&>(*target).GetPower() != obj)
|
|
||||||
{
|
|
||||||
// transported, but not in the power slot
|
|
||||||
target = obj;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!obj->Implements(ObjectInterfaceType::Old)) continue;
|
if (!obj->Implements(ObjectInterfaceType::Old)) continue;
|
||||||
|
@ -4716,29 +4701,26 @@ bool CRobotMain::IOWriteScene(std::string filename, std::string filecbot, std::s
|
||||||
if (IsObjectBeingTransported(obj)) continue;
|
if (IsObjectBeingTransported(obj)) continue;
|
||||||
if (obj->Implements(ObjectInterfaceType::Destroyable) && dynamic_cast<CDestroyableObject&>(*obj).IsDying()) continue;
|
if (obj->Implements(ObjectInterfaceType::Destroyable) && dynamic_cast<CDestroyableObject&>(*obj).IsDying()) continue;
|
||||||
|
|
||||||
if (obj->Implements(ObjectInterfaceType::Carrier))
|
if (obj->Implements(ObjectInterfaceType::Slotted))
|
||||||
{
|
{
|
||||||
CObject* cargo = dynamic_cast<CCarrierObject&>(*obj).GetCargo();
|
CSlottedObject* slotted = dynamic_cast<CSlottedObject*>(obj);
|
||||||
if (cargo != nullptr) // object transported?
|
for (int slot = slotted->GetNumSlots() - 1; slot >= 0; slot--)
|
||||||
{
|
{
|
||||||
line = MakeUnique<CLevelParserLine>("CreateFret");
|
if (CObject *sub = slotted->GetSlotContainedObject(slot))
|
||||||
IOWriteObject(line.get(), cargo, dirname, objRank++);
|
{
|
||||||
levelParser.AddLine(std::move(line));
|
if (slot == slotted->MapPseudoSlot(CSlottedObject::Pseudoslot::POWER))
|
||||||
|
line = MakeUnique<CLevelParserLine>("CreatePower");
|
||||||
|
else if (slot == slotted->MapPseudoSlot(CSlottedObject::Pseudoslot::CARRYING))
|
||||||
|
line = MakeUnique<CLevelParserLine>("CreateFret");
|
||||||
|
else
|
||||||
|
line = MakeUnique<CLevelParserLine>("CreateSlotObject");
|
||||||
|
line->AddParam("slotNum", MakeUnique<CLevelParserParam>(slot));
|
||||||
|
IOWriteObject(line.get(), sub, dirname, objRank++);
|
||||||
|
levelParser.AddLine(std::move(line));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (obj->Implements(ObjectInterfaceType::Powered))
|
|
||||||
{
|
|
||||||
CObject* power = dynamic_cast<CPoweredObject&>(*obj).GetPower();
|
|
||||||
if (power != nullptr) // battery transported?
|
|
||||||
{
|
|
||||||
line = MakeUnique<CLevelParserLine>("CreatePower");
|
|
||||||
IOWriteObject(line.get(), power, dirname, objRank++);
|
|
||||||
levelParser.AddLine(std::move(line));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
line = MakeUnique<CLevelParserLine>("CreateObject");
|
line = MakeUnique<CLevelParserLine>("CreateObject");
|
||||||
IOWriteObject(line.get(), obj, dirname, objRank++);
|
IOWriteObject(line.get(), obj, dirname, objRank++);
|
||||||
levelParser.AddLine(std::move(line));
|
levelParser.AddLine(std::move(line));
|
||||||
|
@ -4867,7 +4849,7 @@ CObject* CRobotMain::IOReadScene(std::string filename, std::string filecbot)
|
||||||
CLevelParser levelParser(filename);
|
CLevelParser levelParser(filename);
|
||||||
levelParser.SetLevelPaths(m_levelCategory, m_levelChap, m_levelRank);
|
levelParser.SetLevelPaths(m_levelCategory, m_levelChap, m_levelRank);
|
||||||
levelParser.Load();
|
levelParser.Load();
|
||||||
int numObjects = levelParser.CountLines("CreateObject") + levelParser.CountLines("CreatePower") + levelParser.CountLines("CreateFret");
|
int numObjects = levelParser.CountLines("CreateObject") + levelParser.CountLines("CreatePower") + levelParser.CountLines("CreateFret") + levelParser.CountLines("CreateSlotObject");
|
||||||
|
|
||||||
m_base = nullptr;
|
m_base = nullptr;
|
||||||
|
|
||||||
|
@ -4876,6 +4858,7 @@ CObject* CRobotMain::IOReadScene(std::string filename, std::string filecbot)
|
||||||
CObject* sel = nullptr;
|
CObject* sel = nullptr;
|
||||||
int objRank = 0;
|
int objRank = 0;
|
||||||
int objCounter = 0;
|
int objCounter = 0;
|
||||||
|
std::map<int, CObject*> slots;
|
||||||
for (auto& line : levelParser.GetLines())
|
for (auto& line : levelParser.GetLines())
|
||||||
{
|
{
|
||||||
if (line->GetCommand() == "Mission")
|
if (line->GetCommand() == "Mission")
|
||||||
|
@ -4908,6 +4891,16 @@ CObject* CRobotMain::IOReadScene(std::string filename, std::string filecbot)
|
||||||
objCounter++;
|
objCounter++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (line->GetCommand() == "CreateSlotObject")
|
||||||
|
{
|
||||||
|
int slotNum = line->GetParam("slotNum")->AsInt();
|
||||||
|
CObject *slotObject = IOReadObject(line.get(), dirname, StrUtils::ToString<int>(objCounter+1)+" / "+StrUtils::ToString<int>(numObjects), static_cast<float>(objCounter) / static_cast<float>(numObjects));
|
||||||
|
objCounter++;
|
||||||
|
|
||||||
|
assert(slots.find(slotNum) == slots.end());
|
||||||
|
slots.emplace(slotNum, slotObject);
|
||||||
|
}
|
||||||
|
|
||||||
if (line->GetCommand() == "CreateObject")
|
if (line->GetCommand() == "CreateObject")
|
||||||
{
|
{
|
||||||
CObject* obj = IOReadObject(line.get(), dirname, StrUtils::ToString<int>(objCounter+1)+" / "+StrUtils::ToString<int>(numObjects), static_cast<float>(objCounter) / static_cast<float>(numObjects), objRank++);
|
CObject* obj = IOReadObject(line.get(), dirname, StrUtils::ToString<int>(objCounter+1)+" / "+StrUtils::ToString<int>(numObjects), static_cast<float>(objCounter) / static_cast<float>(numObjects), objRank++);
|
||||||
|
@ -4915,20 +4908,50 @@ CObject* CRobotMain::IOReadScene(std::string filename, std::string filecbot)
|
||||||
if (line->GetParam("select")->AsBool(false))
|
if (line->GetParam("select")->AsBool(false))
|
||||||
sel = obj;
|
sel = obj;
|
||||||
|
|
||||||
if (cargo != nullptr)
|
if (obj->Implements(ObjectInterfaceType::Slotted))
|
||||||
{
|
{
|
||||||
assert(obj->Implements(ObjectInterfaceType::Carrier)); // TODO: exception?
|
CSlottedObject* asSlotted = dynamic_cast<CSlottedObject*>(obj);
|
||||||
assert(obj->Implements(ObjectInterfaceType::Old));
|
if (cargo != nullptr)
|
||||||
dynamic_cast<CCarrierObject&>(*obj).SetCargo(cargo);
|
{
|
||||||
auto task = MakeUnique<CTaskManip>(dynamic_cast<COldObject*>(obj));
|
int slotNum = asSlotted->MapPseudoSlot(CSlottedObject::Pseudoslot::CARRYING);
|
||||||
task->Start(TMO_AUTO, TMA_GRAB); // holds the object!
|
assert(slotNum >= 0);
|
||||||
|
assert(slots.find(slotNum) == slots.end());
|
||||||
|
asSlotted->SetSlotContainedObject(slotNum, cargo);
|
||||||
|
|
||||||
|
// TODO: eww!
|
||||||
|
assert(obj->Implements(ObjectInterfaceType::Old));
|
||||||
|
auto task = MakeUnique<CTaskManip>(dynamic_cast<COldObject*>(obj));
|
||||||
|
task->Start(TMO_AUTO, TMA_GRAB); // holds the object!
|
||||||
|
}
|
||||||
|
|
||||||
|
if (power != nullptr)
|
||||||
|
{
|
||||||
|
int slotNum = asSlotted->MapPseudoSlot(CSlottedObject::Pseudoslot::POWER);
|
||||||
|
assert(slotNum >= 0);
|
||||||
|
assert(slots.find(slotNum) == slots.end());
|
||||||
|
asSlotted->SetSlotContainedObject(slotNum, power);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (std::pair<const int, CObject*>& slot : slots)
|
||||||
|
{
|
||||||
|
asSlotted->SetSlotContainedObject(slot.first, slot.second);
|
||||||
|
}
|
||||||
|
|
||||||
|
cargo = nullptr;
|
||||||
|
power = nullptr;
|
||||||
|
slots.clear();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// TODO: exception?
|
||||||
|
assert(slots.empty());
|
||||||
|
assert(power == nullptr);
|
||||||
|
assert(cargo == nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (power != nullptr)
|
if (power != nullptr)
|
||||||
{
|
{
|
||||||
assert(obj->Implements(ObjectInterfaceType::Powered));
|
dynamic_cast<CSlottedObject&>(*obj).SetSlotContainedObjectReq(CSlottedObject::Pseudoslot::POWER, power);
|
||||||
dynamic_cast<CPoweredObject&>(*obj).SetPower(power);
|
|
||||||
assert(power->Implements(ObjectInterfaceType::Transportable));
|
|
||||||
dynamic_cast<CTransportableObject&>(*power).SetTransporter(obj);
|
dynamic_cast<CTransportableObject&>(*power).SetTransporter(obj);
|
||||||
}
|
}
|
||||||
cargo = nullptr;
|
cargo = nullptr;
|
||||||
|
@ -4938,6 +4961,11 @@ CObject* CRobotMain::IOReadScene(std::string filename, std::string filecbot)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// all slot objects assigned to parent objects
|
||||||
|
assert(slots.empty());
|
||||||
|
assert(power == nullptr);
|
||||||
|
assert(cargo == nullptr);
|
||||||
|
|
||||||
m_ui->GetLoadingScreen()->SetProgress(0.95f, RT_LOADING_CBOT_SAVE);
|
m_ui->GetLoadingScreen()->SetProgress(0.95f, RT_LOADING_CBOT_SAVE);
|
||||||
|
|
||||||
// Reads the file of stacks of execution.
|
// Reads the file of stacks of execution.
|
||||||
|
|
|
@ -26,7 +26,8 @@
|
||||||
#include "object/object.h"
|
#include "object/object.h"
|
||||||
#include "object/object_manager.h"
|
#include "object/object_manager.h"
|
||||||
|
|
||||||
#include "object/interface/powered_object.h"
|
#include "object/interface/power_container_object.h"
|
||||||
|
#include "object/interface/slotted_object.h"
|
||||||
#include "object/interface/transportable_object.h"
|
#include "object/interface/transportable_object.h"
|
||||||
|
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
@ -80,13 +81,9 @@ bool CObjectCondition::CheckForObject(CObject* obj)
|
||||||
{
|
{
|
||||||
power = dynamic_cast<CPowerContainerObject*>(obj);
|
power = dynamic_cast<CPowerContainerObject*>(obj);
|
||||||
}
|
}
|
||||||
else if (obj->Implements(ObjectInterfaceType::Powered))
|
else
|
||||||
{
|
{
|
||||||
CObject* powerObj = dynamic_cast<CPoweredObject&>(*obj).GetPower();
|
power = GetObjectPowerCell(obj);
|
||||||
if(powerObj != nullptr && powerObj->Implements(ObjectInterfaceType::PowerContainer))
|
|
||||||
{
|
|
||||||
power = dynamic_cast<CPowerContainerObject*>(powerObj);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (power != nullptr)
|
if (power != nullptr)
|
||||||
|
|
|
@ -32,7 +32,7 @@
|
||||||
#include "object/object_manager.h"
|
#include "object/object_manager.h"
|
||||||
#include "object/old_object.h"
|
#include "object/old_object.h"
|
||||||
|
|
||||||
#include "object/interface/powered_object.h"
|
#include "object/interface/slotted_object.h"
|
||||||
|
|
||||||
#include "sound/sound.h"
|
#include "sound/sound.h"
|
||||||
|
|
||||||
|
@ -59,7 +59,7 @@ CAutoLabo::CAutoLabo(COldObject* object) : CAuto(object)
|
||||||
m_soundChannel = -1;
|
m_soundChannel = -1;
|
||||||
Init();
|
Init();
|
||||||
|
|
||||||
assert(m_object->Implements(ObjectInterfaceType::Powered));
|
assert(object->GetNumSlots() == 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Object's destructor.
|
// Object's destructor.
|
||||||
|
@ -131,7 +131,7 @@ Error CAutoLabo::StartAction(int param)
|
||||||
return ERR_LABO_ALREADY;
|
return ERR_LABO_ALREADY;
|
||||||
}
|
}
|
||||||
|
|
||||||
CObject* power = m_object->GetPower();
|
CObject* power = dynamic_cast<CSlottedObject&>(*m_object).GetSlotContainedObject(0);
|
||||||
if (power == nullptr)
|
if (power == nullptr)
|
||||||
{
|
{
|
||||||
return ERR_LABO_NULL;
|
return ERR_LABO_NULL;
|
||||||
|
@ -308,7 +308,7 @@ bool CAutoLabo::EventProcess(const Event &event)
|
||||||
{
|
{
|
||||||
if ( m_progress < 1.0f )
|
if ( m_progress < 1.0f )
|
||||||
{
|
{
|
||||||
power = m_object->GetPower();
|
power = dynamic_cast<CSlottedObject&>(*m_object).GetSlotContainedObject(0);
|
||||||
if ( power != nullptr )
|
if ( power != nullptr )
|
||||||
{
|
{
|
||||||
power->SetScale(1.0f-m_progress);
|
power->SetScale(1.0f-m_progress);
|
||||||
|
@ -366,10 +366,10 @@ bool CAutoLabo::EventProcess(const Event &event)
|
||||||
m_eventQueue->AddEvent(Event(EVENT_UPDINTERFACE));
|
m_eventQueue->AddEvent(Event(EVENT_UPDINTERFACE));
|
||||||
UpdateInterface();
|
UpdateInterface();
|
||||||
|
|
||||||
power = m_object->GetPower();
|
power = dynamic_cast<CSlottedObject&>(*m_object).GetSlotContainedObject(0);
|
||||||
if ( power != nullptr )
|
if ( power != nullptr )
|
||||||
{
|
{
|
||||||
m_object->SetPower(nullptr);
|
dynamic_cast<CSlottedObject&>(*m_object).SetSlotContainedObject(0, nullptr);
|
||||||
CObjectManager::GetInstancePointer()->DeleteObject(power);
|
CObjectManager::GetInstancePointer()->DeleteObject(power);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -457,7 +457,7 @@ Error CAutoLabo::GetError()
|
||||||
return ERR_BAT_VIRUS;
|
return ERR_BAT_VIRUS;
|
||||||
}
|
}
|
||||||
|
|
||||||
CObject* obj = m_object->GetPower();
|
CObject* obj = dynamic_cast<CSlottedObject&>(*m_object).GetSlotContainedObject(0);
|
||||||
if (obj == nullptr) return ERR_LABO_NULL;
|
if (obj == nullptr) return ERR_LABO_NULL;
|
||||||
ObjectType type = obj->GetType();
|
ObjectType type = obj->GetType();
|
||||||
if ( type != OBJECT_BULLET && type != OBJECT_TNT ) return ERR_LABO_BAD;
|
if ( type != OBJECT_BULLET && type != OBJECT_TNT ) return ERR_LABO_BAD;
|
||||||
|
|
|
@ -32,7 +32,7 @@
|
||||||
#include "object/object_manager.h"
|
#include "object/object_manager.h"
|
||||||
#include "object/old_object.h"
|
#include "object/old_object.h"
|
||||||
|
|
||||||
#include "object/interface/powered_object.h"
|
#include "object/interface/slotted_object.h"
|
||||||
#include "object/interface/transportable_object.h"
|
#include "object/interface/transportable_object.h"
|
||||||
|
|
||||||
#include "sound/sound.h"
|
#include "sound/sound.h"
|
||||||
|
@ -53,7 +53,7 @@ CAutoNuclearPlant::CAutoNuclearPlant(COldObject* object) : CAuto(object)
|
||||||
m_channelSound = -1;
|
m_channelSound = -1;
|
||||||
Init();
|
Init();
|
||||||
|
|
||||||
assert(m_object->Implements(ObjectInterfaceType::Powered));
|
assert(m_object->GetNumSlots() == 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Object's destructor.
|
// Object's destructor.
|
||||||
|
@ -239,7 +239,7 @@ bool CAutoNuclearPlant::EventProcess(const Event &event)
|
||||||
if ( cargo != nullptr )
|
if ( cargo != nullptr )
|
||||||
{
|
{
|
||||||
CObjectManager::GetInstancePointer()->DeleteObject(cargo);
|
CObjectManager::GetInstancePointer()->DeleteObject(cargo);
|
||||||
m_object->SetPower(nullptr);
|
m_object->SetSlotContainedObject(0, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
CreatePower(); // creates the atomic cell
|
CreatePower(); // creates the atomic cell
|
||||||
|
@ -327,7 +327,7 @@ bool CAutoNuclearPlant::CreateInterface(bool bSelect)
|
||||||
|
|
||||||
CObject* CAutoNuclearPlant::SearchUranium()
|
CObject* CAutoNuclearPlant::SearchUranium()
|
||||||
{
|
{
|
||||||
CObject* obj = m_object->GetPower();
|
CObject* obj = m_object->GetSlotContainedObject(0);
|
||||||
if (obj == nullptr) return nullptr;
|
if (obj == nullptr) return nullptr;
|
||||||
if (obj->GetType() == OBJECT_URANIUM) return obj;
|
if (obj->GetType() == OBJECT_URANIUM) return obj;
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -402,7 +402,7 @@ void CAutoNuclearPlant::CreatePower()
|
||||||
|
|
||||||
dynamic_cast<CTransportableObject&>(*power).SetTransporter(m_object);
|
dynamic_cast<CTransportableObject&>(*power).SetTransporter(m_object);
|
||||||
power->SetPosition(Math::Vector(22.0f, 3.0f, 0.0f));
|
power->SetPosition(Math::Vector(22.0f, 3.0f, 0.0f));
|
||||||
m_object->SetPower(power);
|
m_object->SetSlotContainedObject(0, power);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -422,7 +422,7 @@ Error CAutoNuclearPlant::GetError()
|
||||||
|
|
||||||
//? if ( m_object->GetEnergy() < ENERGY_POWER ) return ERR_NUCLEAR_LOW;
|
//? if ( m_object->GetEnergy() < ENERGY_POWER ) return ERR_NUCLEAR_LOW;
|
||||||
|
|
||||||
CObject* obj = m_object->GetPower();
|
CObject* obj = m_object->GetSlotContainedObject(0);
|
||||||
if ( obj == nullptr ) return ERR_NUCLEAR_EMPTY;
|
if ( obj == nullptr ) return ERR_NUCLEAR_EMPTY;
|
||||||
if ( obj->GetLock() ) return ERR_OK;
|
if ( obj->GetLock() ) return ERR_OK;
|
||||||
ObjectType type = obj->GetType();
|
ObjectType type = obj->GetType();
|
||||||
|
|
|
@ -30,8 +30,7 @@
|
||||||
#include "object/object_manager.h"
|
#include "object/object_manager.h"
|
||||||
#include "object/old_object.h"
|
#include "object/old_object.h"
|
||||||
|
|
||||||
#include "object/interface/carrier_object.h"
|
#include "object/interface/slotted_object.h"
|
||||||
#include "object/interface/powered_object.h"
|
|
||||||
#include "object/interface/transportable_object.h"
|
#include "object/interface/transportable_object.h"
|
||||||
|
|
||||||
#include "sound/sound.h"
|
#include "sound/sound.h"
|
||||||
|
@ -267,34 +266,22 @@ void CAutoPowerCaptor::ChargeObject(float rTime)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (obj->Implements(ObjectInterfaceType::Powered))
|
if (obj->Implements(ObjectInterfaceType::Slotted))
|
||||||
{
|
{
|
||||||
CObject* power = dynamic_cast<CPoweredObject&>(*obj).GetPower();
|
CSlottedObject* slotted = dynamic_cast<CSlottedObject*>(obj);
|
||||||
if ( power != nullptr && power->Implements(ObjectInterfaceType::PowerContainer) )
|
for (int slot = slotted->GetNumSlots(); slot >= 0; slot--)
|
||||||
{
|
{
|
||||||
CPowerContainerObject* powerContainer = dynamic_cast<CPowerContainerObject*>(power);
|
CObject *held = slotted->GetSlotContainedObject(slot);
|
||||||
if (powerContainer->IsRechargeable())
|
if (held != nullptr && held->Implements(ObjectInterfaceType::PowerContainer))
|
||||||
{
|
{
|
||||||
float energy = powerContainer->GetEnergy();
|
CPowerContainerObject* powerContainer = dynamic_cast<CPowerContainerObject*>(held);
|
||||||
energy += rTime/2.0f;
|
if (powerContainer->IsRechargeable())
|
||||||
if ( energy > 1.0f ) energy = 1.0f;
|
{
|
||||||
powerContainer->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))
|
|
||||||
{
|
|
||||||
CObject* power = dynamic_cast<CCarrierObject&>(*obj).GetCargo();
|
|
||||||
if ( power != nullptr && power->Implements(ObjectInterfaceType::PowerContainer) )
|
|
||||||
{
|
|
||||||
CPowerContainerObject* powerContainer = dynamic_cast<CPowerContainerObject*>(power);
|
|
||||||
if (powerContainer->IsRechargeable())
|
|
||||||
{
|
|
||||||
float energy = powerContainer->GetEnergy();
|
|
||||||
energy += rTime/2.0f;
|
|
||||||
if ( energy > 1.0f ) energy = 1.0f;
|
|
||||||
powerContainer->SetEnergy(energy);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,7 +34,7 @@
|
||||||
#include "object/object_manager.h"
|
#include "object/object_manager.h"
|
||||||
#include "object/old_object.h"
|
#include "object/old_object.h"
|
||||||
|
|
||||||
#include "object/interface/powered_object.h"
|
#include "object/interface/slotted_object.h"
|
||||||
#include "object/interface/transportable_object.h"
|
#include "object/interface/transportable_object.h"
|
||||||
|
|
||||||
#include "sound/sound.h"
|
#include "sound/sound.h"
|
||||||
|
@ -57,7 +57,7 @@ CAutoPowerPlant::CAutoPowerPlant(COldObject* object) : CAuto(object)
|
||||||
m_partiSphere = -1;
|
m_partiSphere = -1;
|
||||||
Init();
|
Init();
|
||||||
|
|
||||||
assert(m_object->Implements(ObjectInterfaceType::Powered));
|
assert(m_object->GetNumSlots() == 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Object's destructor.
|
// Object's destructor.
|
||||||
|
@ -79,17 +79,18 @@ void CAutoPowerPlant::DeleteObject(bool all)
|
||||||
|
|
||||||
if ( !all )
|
if ( !all )
|
||||||
{
|
{
|
||||||
|
// TODO: why are we only searching for titanium and power cells? why don't we delete any object regardless of type?
|
||||||
CObject* cargo = SearchMetal();
|
CObject* cargo = SearchMetal();
|
||||||
if ( cargo != nullptr )
|
if ( cargo != nullptr )
|
||||||
{
|
{
|
||||||
m_object->SetPower(nullptr);
|
m_object->SetSlotContainedObject(0, nullptr);
|
||||||
CObjectManager::GetInstancePointer()->DeleteObject(cargo);
|
CObjectManager::GetInstancePointer()->DeleteObject(cargo);
|
||||||
}
|
}
|
||||||
|
|
||||||
cargo = SearchPower();
|
cargo = SearchPower();
|
||||||
if ( cargo != nullptr )
|
if ( cargo != nullptr )
|
||||||
{
|
{
|
||||||
m_object->SetPower(nullptr);
|
m_object->SetSlotContainedObject(0, nullptr);
|
||||||
CObjectManager::GetInstancePointer()->DeleteObject(cargo);
|
CObjectManager::GetInstancePointer()->DeleteObject(cargo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -320,7 +321,7 @@ bool CAutoPowerPlant::EventProcess(const Event &event)
|
||||||
cargo = SearchMetal();
|
cargo = SearchMetal();
|
||||||
if ( cargo != nullptr )
|
if ( cargo != nullptr )
|
||||||
{
|
{
|
||||||
m_object->SetPower(nullptr);
|
m_object->SetSlotContainedObject(0, nullptr);
|
||||||
CObjectManager::GetInstancePointer()->DeleteObject(cargo);
|
CObjectManager::GetInstancePointer()->DeleteObject(cargo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -333,7 +334,7 @@ bool CAutoPowerPlant::EventProcess(const Event &event)
|
||||||
cargo->SetLock(false); // usable battery
|
cargo->SetLock(false); // usable battery
|
||||||
dynamic_cast<CTransportableObject&>(*cargo).SetTransporter(m_object);
|
dynamic_cast<CTransportableObject&>(*cargo).SetTransporter(m_object);
|
||||||
cargo->SetPosition(Math::Vector(0.0f, 3.0f, 0.0f));
|
cargo->SetPosition(Math::Vector(0.0f, 3.0f, 0.0f));
|
||||||
m_object->SetPower(cargo);
|
m_object->SetSlotContainedObject(0, cargo);
|
||||||
|
|
||||||
m_main->DisplayError(INFO_ENERGY, m_object);
|
m_main->DisplayError(INFO_ENERGY, m_object);
|
||||||
}
|
}
|
||||||
|
@ -387,7 +388,7 @@ bool CAutoPowerPlant::EventProcess(const Event &event)
|
||||||
|
|
||||||
CObject* CAutoPowerPlant::SearchMetal()
|
CObject* CAutoPowerPlant::SearchMetal()
|
||||||
{
|
{
|
||||||
CObject* obj = m_object->GetPower();
|
CObject* obj = m_object->GetSlotContainedObject(0);
|
||||||
if ( obj == nullptr ) return nullptr;
|
if ( obj == nullptr ) return nullptr;
|
||||||
|
|
||||||
ObjectType type = obj->GetType();
|
ObjectType type = obj->GetType();
|
||||||
|
@ -512,7 +513,7 @@ Error CAutoPowerPlant::GetError()
|
||||||
|
|
||||||
if ( m_object->GetEnergy() < POWERPLANT_POWER ) return ERR_ENERGY_LOW;
|
if ( m_object->GetEnergy() < POWERPLANT_POWER ) return ERR_ENERGY_LOW;
|
||||||
|
|
||||||
CObject* obj = m_object->GetPower();
|
CObject* obj = m_object->GetSlotContainedObject(0);
|
||||||
if (obj == nullptr) return ERR_ENERGY_EMPTY;
|
if (obj == nullptr) return ERR_ENERGY_EMPTY;
|
||||||
ObjectType type = obj->GetType();
|
ObjectType type = obj->GetType();
|
||||||
if ( type == OBJECT_POWER ) return ERR_OK;
|
if ( type == OBJECT_POWER ) return ERR_OK;
|
||||||
|
|
|
@ -28,9 +28,6 @@
|
||||||
#include "object/object_manager.h"
|
#include "object/object_manager.h"
|
||||||
#include "object/old_object.h"
|
#include "object/old_object.h"
|
||||||
|
|
||||||
#include "object/interface/carrier_object.h"
|
|
||||||
#include "object/interface/powered_object.h"
|
|
||||||
|
|
||||||
#include "sound/sound.h"
|
#include "sound/sound.h"
|
||||||
|
|
||||||
#include "ui/controls/gauge.h"
|
#include "ui/controls/gauge.h"
|
||||||
|
@ -134,32 +131,13 @@ bool CAutoPowerStation::EventProcess(const Event &event)
|
||||||
if (big > 0.0f)
|
if (big > 0.0f)
|
||||||
{
|
{
|
||||||
CObject* vehicle = SearchVehicle();
|
CObject* vehicle = SearchVehicle();
|
||||||
if (vehicle != nullptr)
|
if (vehicle != nullptr && vehicle->Implements(ObjectInterfaceType::Slotted))
|
||||||
{
|
{
|
||||||
if (vehicle->Implements(ObjectInterfaceType::Powered))
|
CSlottedObject* slotted = dynamic_cast<CSlottedObject*>(vehicle);
|
||||||
|
for (int slot = slotted->GetNumSlots(); slot >= 0; slot--)
|
||||||
{
|
{
|
||||||
CObject* power = dynamic_cast<CPoweredObject&>(*vehicle).GetPower();
|
CObject *power = slotted->GetSlotContainedObject(slot);
|
||||||
if ( power != nullptr && power->Implements(ObjectInterfaceType::PowerContainer) )
|
if (power != nullptr && power->Implements(ObjectInterfaceType::PowerContainer))
|
||||||
{
|
|
||||||
CPowerContainerObject* powerContainer = dynamic_cast<CPowerContainerObject*>(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<CCarrierObject&>(*vehicle).GetCargo();
|
|
||||||
if ( power != nullptr && power->Implements(ObjectInterfaceType::PowerContainer) )
|
|
||||||
{
|
{
|
||||||
CPowerContainerObject* powerContainer = dynamic_cast<CPowerContainerObject*>(power);
|
CPowerContainerObject* powerContainer = dynamic_cast<CPowerContainerObject*>(power);
|
||||||
if (powerContainer->IsRechargeable())
|
if (powerContainer->IsRechargeable())
|
||||||
|
|
|
@ -32,7 +32,7 @@
|
||||||
|
|
||||||
#include "object/old_object.h"
|
#include "object/old_object.h"
|
||||||
|
|
||||||
#include "object/interface/powered_object.h"
|
#include "object/interface/slotted_object.h"
|
||||||
|
|
||||||
#include "sound/sound.h"
|
#include "sound/sound.h"
|
||||||
|
|
||||||
|
@ -57,7 +57,7 @@ CAutoResearch::CAutoResearch(COldObject* object) : CAuto(object)
|
||||||
|
|
||||||
Init();
|
Init();
|
||||||
|
|
||||||
assert(m_object->Implements(ObjectInterfaceType::Powered));
|
assert(m_object->GetNumSlots() == 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Object's destructor.
|
// Object's destructor.
|
||||||
|
@ -114,11 +114,11 @@ Error CAutoResearch::StartAction(int param)
|
||||||
return ERR_RESEARCH_ALREADY;
|
return ERR_RESEARCH_ALREADY;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_object->GetPower() == nullptr || !m_object->GetPower()->Implements(ObjectInterfaceType::PowerContainer))
|
if (m_object->GetSlotContainedObject(0) == nullptr || !m_object->GetSlotContainedObject(0)->Implements(ObjectInterfaceType::PowerContainer))
|
||||||
{
|
{
|
||||||
return ERR_RESEARCH_POWER;
|
return ERR_RESEARCH_POWER;
|
||||||
}
|
}
|
||||||
CPowerContainerObject* power = dynamic_cast<CPowerContainerObject*>(m_object->GetPower());
|
CPowerContainerObject* power = dynamic_cast<CPowerContainerObject*>(m_object->GetSlotContainedObject(0));
|
||||||
if ( power->GetCapacity() > 1.0f )
|
if ( power->GetCapacity() > 1.0f )
|
||||||
{
|
{
|
||||||
return ERR_RESEARCH_TYPE;
|
return ERR_RESEARCH_TYPE;
|
||||||
|
@ -222,7 +222,9 @@ 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 )
|
||||||
{
|
{
|
||||||
if ( m_object->GetPower() == nullptr || !m_object->GetPower()->Implements(ObjectInterfaceType::PowerContainer) ) // more battery?
|
CObject* batteryObj = dynamic_cast<CSlottedObject&>(*m_object).GetSlotContainedObject(0);
|
||||||
|
|
||||||
|
if ( batteryObj == nullptr || !batteryObj->Implements(ObjectInterfaceType::PowerContainer) ) // more battery?
|
||||||
{
|
{
|
||||||
SetBusy(false);
|
SetBusy(false);
|
||||||
UpdateInterface();
|
UpdateInterface();
|
||||||
|
@ -232,7 +234,7 @@ bool CAutoResearch::EventProcess(const Event &event)
|
||||||
m_speed = 1.0f/1.0f;
|
m_speed = 1.0f/1.0f;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
power = dynamic_cast<CPowerContainerObject*>(m_object->GetPower());
|
power = dynamic_cast<CPowerContainerObject*>(batteryObj);
|
||||||
power->SetEnergyLevel(1.0f-m_progress);
|
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 )
|
||||||
|
@ -302,11 +304,11 @@ Error CAutoResearch::GetError()
|
||||||
return ERR_BAT_VIRUS;
|
return ERR_BAT_VIRUS;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_object->GetPower() == nullptr || !m_object->GetPower()->Implements(ObjectInterfaceType::PowerContainer))
|
if (m_object->GetSlotContainedObject(0) == nullptr || !m_object->GetSlotContainedObject(0)->Implements(ObjectInterfaceType::PowerContainer))
|
||||||
{
|
{
|
||||||
return ERR_RESEARCH_POWER;
|
return ERR_RESEARCH_POWER;
|
||||||
}
|
}
|
||||||
CPowerContainerObject* power = dynamic_cast<CPowerContainerObject*>(m_object->GetPower());
|
CPowerContainerObject* power = dynamic_cast<CPowerContainerObject*>(m_object->GetSlotContainedObject(0));
|
||||||
if ( power->GetCapacity() > 1.0f )
|
if ( power->GetCapacity() > 1.0f )
|
||||||
{
|
{
|
||||||
return ERR_RESEARCH_TYPE;
|
return ERR_RESEARCH_TYPE;
|
||||||
|
|
|
@ -32,7 +32,7 @@
|
||||||
#include "object/object_manager.h"
|
#include "object/object_manager.h"
|
||||||
#include "object/old_object.h"
|
#include "object/old_object.h"
|
||||||
|
|
||||||
#include "object/interface/powered_object.h"
|
#include "object/interface/slotted_object.h"
|
||||||
|
|
||||||
#include "physics/physics.h"
|
#include "physics/physics.h"
|
||||||
|
|
||||||
|
@ -61,7 +61,7 @@ CAutoTower::CAutoTower(COldObject* object) : CAuto(object)
|
||||||
m_time = 0.0f;
|
m_time = 0.0f;
|
||||||
m_lastUpdateTime = 0.0f;
|
m_lastUpdateTime = 0.0f;
|
||||||
|
|
||||||
assert(m_object->Implements(ObjectInterfaceType::Powered));
|
assert(m_object->GetNumSlots() == 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Object's destructor.
|
// Object's destructor.
|
||||||
|
@ -125,13 +125,8 @@ bool CAutoTower::EventProcess(const Event &event)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
CPowerContainerObject* power = nullptr;
|
CPowerContainerObject* power = GetObjectPowerCell(m_object);
|
||||||
float energy = 0.0f;
|
float energy = power == nullptr ? 0.0f : power->GetEnergy();
|
||||||
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);
|
||||||
|
|
||||||
|
@ -321,12 +316,13 @@ Error CAutoTower::GetError()
|
||||||
return ERR_BAT_VIRUS;
|
return ERR_BAT_VIRUS;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( m_object->GetPower() == nullptr || !m_object->GetPower()->Implements(ObjectInterfaceType::PowerContainer) )
|
CPowerContainerObject *power = GetObjectPowerCell(m_object);
|
||||||
|
if ( power == nullptr )
|
||||||
{
|
{
|
||||||
return ERR_TOWER_POWER; // no battery
|
return ERR_TOWER_POWER; // no battery
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( dynamic_cast<CPowerContainerObject&>(*m_object->GetPower()).GetEnergy() < ENERGY_FIRE )
|
if ( power->GetEnergy() < ENERGY_FIRE )
|
||||||
{
|
{
|
||||||
return ERR_TOWER_ENERGY; // not enough energy
|
return ERR_TOWER_ENERGY; // not enough energy
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,55 +0,0 @@
|
||||||
/*
|
|
||||||
* This file is part of the Colobot: Gold Edition source code
|
|
||||||
* Copyright (C) 2001-2020, Daniel Roux, EPSITEC SA & TerranovaTeam
|
|
||||||
* http://epsitec.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 CCarrierObject
|
|
||||||
* \brief Interface for carrier objects
|
|
||||||
*/
|
|
||||||
class CCarrierObject
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
explicit CCarrierObject(ObjectInterfaceTypes& types)
|
|
||||||
{
|
|
||||||
types[static_cast<int>(ObjectInterfaceType::Carrier)] = true;
|
|
||||||
}
|
|
||||||
virtual ~CCarrierObject()
|
|
||||||
{}
|
|
||||||
|
|
||||||
//! Returns carried object
|
|
||||||
virtual CObject* GetCargo() = 0;
|
|
||||||
//! Sets carried object
|
|
||||||
virtual void SetCargo(CObject* cargo) = 0;
|
|
||||||
|
|
||||||
//! Checks whether there is any cargo
|
|
||||||
inline bool IsCarryingCargo()
|
|
||||||
{
|
|
||||||
return GetCargo() != nullptr;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
inline bool IsObjectCarryingCargo(CObject* obj)
|
|
||||||
{
|
|
||||||
return obj->Implements(ObjectInterfaceType::Carrier) &&
|
|
||||||
dynamic_cast<CCarrierObject&>(*obj).IsCarryingCargo();
|
|
||||||
}
|
|
|
@ -1,94 +0,0 @@
|
||||||
/*
|
|
||||||
* This file is part of the Colobot: Gold Edition source code
|
|
||||||
* Copyright (C) 2001-2020, Daniel Roux, EPSITEC SA & TerranovaTeam
|
|
||||||
* http://epsitec.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"
|
|
||||||
|
|
||||||
#include "object/interface/power_container_object.h"
|
|
||||||
|
|
||||||
class CObject;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \class CPoweredObject
|
|
||||||
* \brief Interface for objects powered using power cells
|
|
||||||
*
|
|
||||||
* TODO: It currently includes objects that take other objects as input
|
|
||||||
* and convert them, for example PowerPlant.
|
|
||||||
* We should create a dedicated interface for such uses.
|
|
||||||
*/
|
|
||||||
class CPoweredObject
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
explicit CPoweredObject(ObjectInterfaceTypes& types)
|
|
||||||
{
|
|
||||||
types[static_cast<int>(ObjectInterfaceType::Powered)] = true;
|
|
||||||
}
|
|
||||||
virtual ~CPoweredObject()
|
|
||||||
{}
|
|
||||||
|
|
||||||
//! Returns the power cell
|
|
||||||
virtual CObject* GetPower() = 0;
|
|
||||||
//! Sets power cell
|
|
||||||
virtual void SetPower(CObject* power) = 0;
|
|
||||||
|
|
||||||
//! Returns the relative position of power cell
|
|
||||||
virtual Math::Vector GetPowerPosition() = 0;
|
|
||||||
//! Sets the relative position of power cell
|
|
||||||
virtual void SetPowerPosition(const Math::Vector& powerPosition) = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
inline float GetObjectEnergy(CObject* object)
|
|
||||||
{
|
|
||||||
float energy = 0.0f;
|
|
||||||
|
|
||||||
if (object->Implements(ObjectInterfaceType::Powered))
|
|
||||||
{
|
|
||||||
CObject* power = dynamic_cast<CPoweredObject&>(*object).GetPower();
|
|
||||||
if (power != nullptr && power->Implements(ObjectInterfaceType::PowerContainer))
|
|
||||||
{
|
|
||||||
energy = dynamic_cast<CPowerContainerObject&>(*power).GetEnergy();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return energy;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline float GetObjectEnergyLevel(CObject* object)
|
|
||||||
{
|
|
||||||
float energy = 0.0f;
|
|
||||||
|
|
||||||
if (object->Implements(ObjectInterfaceType::Powered))
|
|
||||||
{
|
|
||||||
CObject* power = dynamic_cast<CPoweredObject&>(*object).GetPower();
|
|
||||||
if (power != nullptr && power->Implements(ObjectInterfaceType::PowerContainer))
|
|
||||||
{
|
|
||||||
energy = dynamic_cast<CPowerContainerObject&>(*power).GetEnergyLevel();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return energy;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool ObjectHasPowerCell(CObject* object)
|
|
||||||
{
|
|
||||||
return object->Implements(ObjectInterfaceType::Powered) &&
|
|
||||||
dynamic_cast<CPoweredObject&>(*object).GetPower() != nullptr;
|
|
||||||
}
|
|
|
@ -0,0 +1,148 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the Colobot: Gold Edition source code
|
||||||
|
* Copyright (C) 2001-2020, Daniel Roux, EPSITEC SA & TerranovaTeam
|
||||||
|
* http://epsitec.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 "math/vector.h"
|
||||||
|
|
||||||
|
#include "object/object.h"
|
||||||
|
#include "object/object_interface_type.h"
|
||||||
|
|
||||||
|
#include "object/interface/power_container_object.h"
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
class CObject;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \class CSlottedObject
|
||||||
|
* \brief Interface for objects that hold other objects
|
||||||
|
*/
|
||||||
|
class CSlottedObject
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
///! Object-independent identifiers for certain special slots
|
||||||
|
enum class Pseudoslot
|
||||||
|
{
|
||||||
|
POWER,
|
||||||
|
CARRYING
|
||||||
|
};
|
||||||
|
|
||||||
|
explicit CSlottedObject(ObjectInterfaceTypes& types)
|
||||||
|
{
|
||||||
|
types[static_cast<int>(ObjectInterfaceType::Slotted)] = true;
|
||||||
|
}
|
||||||
|
virtual ~CSlottedObject()
|
||||||
|
{}
|
||||||
|
|
||||||
|
//! Given one of the PSEUDOSLOT enums, returns real slot number, or -1 if specified pseudoslot is not present in this object.
|
||||||
|
virtual int MapPseudoSlot(Pseudoslot pseudoslot) = 0;
|
||||||
|
|
||||||
|
//! Get number of slots. Valid slot numbers are 0 up to GetNumSlots()-1. Using invalid slot numbers in the other functions will crash the game.
|
||||||
|
virtual int GetNumSlots() = 0;
|
||||||
|
//! Get relative position of a slot.
|
||||||
|
virtual Math::Vector GetSlotPosition(int slotNum) = 0;
|
||||||
|
//! Get relative angle (in radians) where robot should be positioned when inserting into a slot.
|
||||||
|
virtual float GetSlotAngle(int slotNum) = 0;
|
||||||
|
//! Get the maximum angular distance from the ideal angle (in radians) where robot should be positioned when inserting into a slot.
|
||||||
|
virtual float GetSlotAcceptanceAngle(int slotNum) = 0;
|
||||||
|
//! Get object contained in a slot.
|
||||||
|
virtual CObject *GetSlotContainedObject(int slotNum) = 0;
|
||||||
|
//! Set object contained in a slot.
|
||||||
|
virtual void SetSlotContainedObject(int slotNum, CObject *object) = 0;
|
||||||
|
|
||||||
|
void SetSlotContainedObjectReq(Pseudoslot pseudoslot, CObject *object)
|
||||||
|
{
|
||||||
|
int slotNum = MapPseudoSlot(pseudoslot);
|
||||||
|
assert(slotNum >= 0);
|
||||||
|
SetSlotContainedObject(slotNum, object);
|
||||||
|
}
|
||||||
|
|
||||||
|
CObject *GetSlotContainedObjectOpt(Pseudoslot pseudoslot)
|
||||||
|
{
|
||||||
|
int slotNum = MapPseudoSlot(pseudoslot);
|
||||||
|
return slotNum < 0 ? nullptr : GetSlotContainedObject(slotNum);
|
||||||
|
}
|
||||||
|
|
||||||
|
CObject *GetSlotContainedObjectReq(Pseudoslot pseudoslot)
|
||||||
|
{
|
||||||
|
int slotNum = MapPseudoSlot(pseudoslot);
|
||||||
|
assert(slotNum >= 0);
|
||||||
|
return GetSlotContainedObject(slotNum);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
inline bool HasPowerCellSlot(CObject *object)
|
||||||
|
{
|
||||||
|
if (object->Implements(ObjectInterfaceType::Slotted))
|
||||||
|
{
|
||||||
|
return dynamic_cast<CSlottedObject&>(*object).MapPseudoSlot(CSlottedObject::Pseudoslot::POWER) >= 0;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline CObject *GetObjectInPowerCellSlot(CObject *object)
|
||||||
|
{
|
||||||
|
if (object->Implements(ObjectInterfaceType::Slotted))
|
||||||
|
{
|
||||||
|
return dynamic_cast<CSlottedObject&>(*object).GetSlotContainedObjectOpt(CSlottedObject::Pseudoslot::POWER);
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline CPowerContainerObject *GetObjectPowerCell(CObject *object)
|
||||||
|
{
|
||||||
|
if (CObject *powerSlotObj = GetObjectInPowerCellSlot(object))
|
||||||
|
{
|
||||||
|
if (powerSlotObj->Implements(ObjectInterfaceType::PowerContainer))
|
||||||
|
{
|
||||||
|
return dynamic_cast<CPowerContainerObject*>(powerSlotObj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline float GetObjectEnergy(CObject* object)
|
||||||
|
{
|
||||||
|
if (CPowerContainerObject* power = GetObjectPowerCell(object))
|
||||||
|
return power->GetEnergy();
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline float GetObjectEnergyLevel(CObject* object)
|
||||||
|
{
|
||||||
|
if (CPowerContainerObject* power = GetObjectPowerCell(object))
|
||||||
|
return power->GetEnergyLevel();
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool ObjectHasPowerCell(CObject* object)
|
||||||
|
{
|
||||||
|
// XXX: not GetObjectPowerCell? We count e.g. titanium cubes as power cells in this function?
|
||||||
|
return GetObjectInPowerCellSlot(object) != nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool IsObjectCarryingCargo(CObject* object)
|
||||||
|
{
|
||||||
|
if (object->Implements(ObjectInterfaceType::Slotted))
|
||||||
|
{
|
||||||
|
return dynamic_cast<CSlottedObject&>(*object).GetSlotContainedObjectOpt(CSlottedObject::Pseudoslot::CARRYING) != nullptr;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
|
@ -33,8 +33,6 @@
|
||||||
#include "object/object_manager.h"
|
#include "object/object_manager.h"
|
||||||
#include "object/old_object.h"
|
#include "object/old_object.h"
|
||||||
|
|
||||||
#include "object/interface/carrier_object.h"
|
|
||||||
|
|
||||||
#include "physics/physics.h"
|
#include "physics/physics.h"
|
||||||
|
|
||||||
#include "sound/sound.h"
|
#include "sound/sound.h"
|
||||||
|
|
|
@ -33,8 +33,8 @@
|
||||||
#include "object/object_manager.h"
|
#include "object/object_manager.h"
|
||||||
#include "object/old_object.h"
|
#include "object/old_object.h"
|
||||||
|
|
||||||
#include "object/interface/powered_object.h"
|
|
||||||
#include "object/interface/programmable_object.h"
|
#include "object/interface/programmable_object.h"
|
||||||
|
#include "object/interface/slotted_object.h"
|
||||||
#include "object/interface/transportable_object.h"
|
#include "object/interface/transportable_object.h"
|
||||||
|
|
||||||
#include "physics/physics.h"
|
#include "physics/physics.h"
|
||||||
|
@ -1061,7 +1061,8 @@ void CMotionVehicle::Create(Math::Vector pos, float angle, ObjectType type,
|
||||||
type != OBJECT_APOLLO2)
|
type != OBJECT_APOLLO2)
|
||||||
{
|
{
|
||||||
CObject* powerCell = nullptr;
|
CObject* powerCell = nullptr;
|
||||||
Math::Vector powerCellPos = m_object->GetPowerPosition();
|
int powerSlotIndex = m_object->MapPseudoSlot(CSlottedObject::Pseudoslot::POWER);
|
||||||
|
Math::Vector powerCellPos = m_object->GetSlotPosition(powerSlotIndex);
|
||||||
float powerCellAngle = 0.0f;
|
float powerCellAngle = 0.0f;
|
||||||
if (power <= 1.0f)
|
if (power <= 1.0f)
|
||||||
{
|
{
|
||||||
|
@ -1076,8 +1077,7 @@ void CMotionVehicle::Create(Math::Vector pos, float angle, ObjectType type,
|
||||||
powerCell->SetPosition(powerCellPos);
|
powerCell->SetPosition(powerCellPos);
|
||||||
powerCell->SetRotation(Math::Vector(0.0f, powerCellAngle, 0.0f));
|
powerCell->SetRotation(Math::Vector(0.0f, powerCellAngle, 0.0f));
|
||||||
dynamic_cast<CTransportableObject&>(*powerCell).SetTransporter(m_object);
|
dynamic_cast<CTransportableObject&>(*powerCell).SetTransporter(m_object);
|
||||||
assert(m_object->Implements(ObjectInterfaceType::Powered));
|
m_object->SetSlotContainedObjectReq(CSlottedObject::Pseudoslot::POWER, powerCell);
|
||||||
m_object->SetPower(powerCell);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pos = m_object->GetPosition();
|
pos = m_object->GetPosition();
|
||||||
|
|
|
@ -39,8 +39,6 @@ enum class ObjectInterfaceType
|
||||||
Programmable, //!< objects that can be programmed in CBOT
|
Programmable, //!< objects that can be programmed in CBOT
|
||||||
TaskExecutor, //!< objects that can execute tasks (CTask classes)
|
TaskExecutor, //!< objects that can execute tasks (CTask classes)
|
||||||
Jostleable, //!< object that can be jostled
|
Jostleable, //!< object that can be jostled
|
||||||
Carrier, //!< object that can carry other objects
|
|
||||||
Powered, //!< object powered with power cell
|
|
||||||
Movable, //!< objects that can move
|
Movable, //!< objects that can move
|
||||||
Flying, //!< objects that can fly
|
Flying, //!< objects that can fly
|
||||||
JetFlying, //!< objects that can fly using a jet engine
|
JetFlying, //!< objects that can fly using a jet engine
|
||||||
|
@ -54,6 +52,7 @@ enum class ObjectInterfaceType
|
||||||
Shielded, //!< objects that can be destroyed after the shield goes down to 0
|
Shielded, //!< objects that can be destroyed after the shield goes down to 0
|
||||||
ShieldedAutoRegen, //!< shielded objects with auto shield regeneration
|
ShieldedAutoRegen, //!< shielded objects with auto shield regeneration
|
||||||
Old, //!< old objects, TODO: remove once no longer necessary
|
Old, //!< old objects, TODO: remove once no longer necessary
|
||||||
|
Slotted, //!< objects that can carry other objects (in their gripper, power cell slot, or other slots)
|
||||||
Max //!< maximum value (for getting number of items in enum)
|
Max //!< maximum value (for getting number of items in enum)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -81,8 +81,7 @@ COldObject::COldObject(int id)
|
||||||
CProgramStorageObjectImpl(m_implementedInterfaces, this),
|
CProgramStorageObjectImpl(m_implementedInterfaces, this),
|
||||||
CProgrammableObjectImpl(m_implementedInterfaces, this),
|
CProgrammableObjectImpl(m_implementedInterfaces, this),
|
||||||
CJostleableObject(m_implementedInterfaces),
|
CJostleableObject(m_implementedInterfaces),
|
||||||
CCarrierObject(m_implementedInterfaces),
|
CSlottedObject(m_implementedInterfaces),
|
||||||
CPoweredObject(m_implementedInterfaces),
|
|
||||||
CJetFlyingObject(m_implementedInterfaces),
|
CJetFlyingObject(m_implementedInterfaces),
|
||||||
CControllableObject(m_implementedInterfaces),
|
CControllableObject(m_implementedInterfaces),
|
||||||
CPowerContainerObjectImpl(m_implementedInterfaces),
|
CPowerContainerObjectImpl(m_implementedInterfaces),
|
||||||
|
@ -145,6 +144,8 @@ COldObject::COldObject(int id)
|
||||||
m_gunGoalH = 0.0f;
|
m_gunGoalH = 0.0f;
|
||||||
m_shieldRadius = 0.0f;
|
m_shieldRadius = 0.0f;
|
||||||
m_magnifyDamage = 1.0f;
|
m_magnifyDamage = 1.0f;
|
||||||
|
m_hasPowerSlot = false;
|
||||||
|
m_hasCargoSlot = false;
|
||||||
|
|
||||||
m_character = Character();
|
m_character = Character();
|
||||||
m_character.wheelFront = 1.0f;
|
m_character.wheelFront = 1.0f;
|
||||||
|
@ -774,17 +775,34 @@ void COldObject::SetType(ObjectType type)
|
||||||
m_type == OBJECT_MOBILEst ||
|
m_type == OBJECT_MOBILEst ||
|
||||||
m_type == OBJECT_TOWER ||
|
m_type == OBJECT_TOWER ||
|
||||||
m_type == OBJECT_RESEARCH ||
|
m_type == OBJECT_RESEARCH ||
|
||||||
m_type == OBJECT_ENERGY ||
|
m_type == OBJECT_ENERGY || // TODO not actually a power cell slot
|
||||||
m_type == OBJECT_LABO ||
|
m_type == OBJECT_LABO || // TODO not actually a power cell slot
|
||||||
m_type == OBJECT_NUCLEAR )
|
m_type == OBJECT_NUCLEAR ) // TODO not actually a power cell slot
|
||||||
{
|
{
|
||||||
m_implementedInterfaces[static_cast<int>(ObjectInterfaceType::Powered)] = true;
|
m_hasPowerSlot = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_implementedInterfaces[static_cast<int>(ObjectInterfaceType::Powered)] = false;
|
m_hasPowerSlot = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( m_type == OBJECT_HUMAN ||
|
||||||
|
m_type == OBJECT_TECH ||
|
||||||
|
m_type == OBJECT_MOBILEfa || // Grabbers
|
||||||
|
m_type == OBJECT_MOBILEta ||
|
||||||
|
m_type == OBJECT_MOBILEwa ||
|
||||||
|
m_type == OBJECT_MOBILEia ||
|
||||||
|
m_type == OBJECT_MOBILEsa) // subber
|
||||||
|
{
|
||||||
|
m_hasCargoSlot = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_hasCargoSlot = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_implementedInterfaces[static_cast<int>(ObjectInterfaceType::Slotted)] = (m_hasPowerSlot || m_hasCargoSlot);
|
||||||
|
|
||||||
// TODO: Hacking some more
|
// TODO: Hacking some more
|
||||||
if ( m_type == OBJECT_MOBILEtg ||
|
if ( m_type == OBJECT_MOBILEtg ||
|
||||||
m_type == OBJECT_STONE ||
|
m_type == OBJECT_STONE ||
|
||||||
|
@ -1662,39 +1680,135 @@ void COldObject::SetMasterParticle(int part, int parti)
|
||||||
|
|
||||||
// Management of the stack transport.
|
// Management of the stack transport.
|
||||||
|
|
||||||
void COldObject::SetPower(CObject* power)
|
|
||||||
{
|
|
||||||
m_power = power;
|
|
||||||
}
|
|
||||||
|
|
||||||
CObject* COldObject::GetPower()
|
int COldObject::GetNumSlots()
|
||||||
{
|
{
|
||||||
return m_power;
|
assert(m_hasPowerSlot || m_hasCargoSlot); // otherwise implemented[CSlottedObject] is false
|
||||||
|
return (m_hasPowerSlot ? 1 : 0) + (m_hasCargoSlot ? 1 : 0);
|
||||||
}
|
}
|
||||||
|
int COldObject::MapPseudoSlot(Pseudoslot pseudoslot)
|
||||||
|
{
|
||||||
|
switch (pseudoslot)
|
||||||
|
{
|
||||||
|
case Pseudoslot::POWER:
|
||||||
|
return m_hasPowerSlot ? 0 : -1;
|
||||||
|
case Pseudoslot::CARRYING:
|
||||||
|
return m_hasCargoSlot ? (m_hasPowerSlot ? 1 : 0) : -1;
|
||||||
|
default:
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Math::Vector COldObject::GetSlotPosition(int slotNum)
|
||||||
|
{
|
||||||
|
if (slotNum == 0 && m_hasPowerSlot)
|
||||||
|
return m_powerPosition;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
assert(m_hasCargoSlot && slotNum == (m_hasPowerSlot ? 1 : 0));
|
||||||
|
int grabPartNum;
|
||||||
|
Math::Vector grabRelPos;
|
||||||
|
// See CTaskManip::TransporterTakeObject call to SetTransporterPart and SetPosition
|
||||||
|
switch (m_type)
|
||||||
|
{
|
||||||
|
case OBJECT_HUMAN:
|
||||||
|
case OBJECT_TECH:
|
||||||
|
grabPartNum = 4;
|
||||||
|
grabRelPos = Math::Vector(1.7f, -0.5f, 1.1f);
|
||||||
|
break;
|
||||||
|
case OBJECT_MOBILEsa: // subber
|
||||||
|
grabPartNum = 2;
|
||||||
|
grabRelPos = Math::Vector(1.1f, -1.0f, 1.0f);
|
||||||
|
break;
|
||||||
|
case OBJECT_MOBILEfa: // Grabbers
|
||||||
|
case OBJECT_MOBILEta:
|
||||||
|
case OBJECT_MOBILEwa:
|
||||||
|
case OBJECT_MOBILEia:
|
||||||
|
grabPartNum = 3;
|
||||||
|
grabRelPos = Math::Vector(4.7f, 0.0f, 0.0f);
|
||||||
|
break;
|
||||||
|
default: // unreachable, only the above objects have cargo slots
|
||||||
|
assert(!m_hasCargoSlot);
|
||||||
|
return m_powerPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Math::Transform(GetWorldMatrix(0)->Inverse(), Math::Transform(*GetWorldMatrix(grabPartNum), grabRelPos));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
float COldObject::GetSlotAngle(int slotNum)
|
||||||
|
{
|
||||||
|
if (slotNum == 0 && m_hasPowerSlot)
|
||||||
|
{
|
||||||
|
switch (m_type)
|
||||||
|
{
|
||||||
|
case OBJECT_TOWER:
|
||||||
|
case OBJECT_RESEARCH:
|
||||||
|
case OBJECT_ENERGY:
|
||||||
|
case OBJECT_LABO:
|
||||||
|
case OBJECT_NUCLEAR:
|
||||||
|
return 0;
|
||||||
|
default: // robots
|
||||||
|
return Math::PI;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
assert(m_hasCargoSlot && slotNum == (m_hasPowerSlot ? 1 : 0));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
float COldObject::GetSlotAcceptanceAngle(int slotNum)
|
||||||
|
{
|
||||||
|
if (slotNum == 0 && m_hasPowerSlot)
|
||||||
|
{
|
||||||
|
switch (m_type)
|
||||||
|
{
|
||||||
|
case OBJECT_TOWER:
|
||||||
|
case OBJECT_RESEARCH:
|
||||||
|
return 45.0f*Math::PI/180.0f;
|
||||||
|
case OBJECT_ENERGY:
|
||||||
|
return 90.0f*Math::PI/180.0f;
|
||||||
|
case OBJECT_LABO:
|
||||||
|
return 120.0f*Math::PI/180.0f;
|
||||||
|
case OBJECT_NUCLEAR:
|
||||||
|
return 45.0f*Math::PI/180.0f;
|
||||||
|
default:
|
||||||
|
return 45.0f*Math::PI/180.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
assert(m_hasCargoSlot && slotNum == (m_hasPowerSlot ? 1 : 0));
|
||||||
|
return 0; // no acceptance angle for cargo slot
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CObject *COldObject::GetSlotContainedObject(int slotNum)
|
||||||
|
{
|
||||||
|
if (slotNum == 0 && m_hasPowerSlot)
|
||||||
|
return m_power;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
assert(m_hasCargoSlot && slotNum == (m_hasPowerSlot ? 1 : 0));
|
||||||
|
return m_cargo;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void COldObject::SetSlotContainedObject(int slotNum, CObject *object)
|
||||||
|
{
|
||||||
|
if (slotNum == 0 && m_hasPowerSlot)
|
||||||
|
m_power = object;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
assert(m_hasCargoSlot && slotNum == (m_hasPowerSlot ? 1 : 0));
|
||||||
|
m_cargo = object;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// not part of CSlottedObject; just used for initialization
|
||||||
void COldObject::SetPowerPosition(const Math::Vector& powerPosition)
|
void COldObject::SetPowerPosition(const Math::Vector& powerPosition)
|
||||||
{
|
{
|
||||||
m_powerPosition = powerPosition;
|
m_powerPosition = powerPosition;
|
||||||
}
|
}
|
||||||
|
|
||||||
Math::Vector COldObject::GetPowerPosition()
|
|
||||||
{
|
|
||||||
return m_powerPosition;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Management of the object transport.
|
|
||||||
|
|
||||||
void COldObject::SetCargo(CObject* cargo)
|
|
||||||
{
|
|
||||||
m_cargo = cargo;
|
|
||||||
}
|
|
||||||
|
|
||||||
CObject* COldObject::GetCargo()
|
|
||||||
{
|
|
||||||
return m_cargo;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Management of the object "transporter" that transports it.
|
// Management of the object "transporter" that transports it.
|
||||||
|
|
||||||
void COldObject::SetTransporter(CObject* transporter)
|
void COldObject::SetTransporter(CObject* transporter)
|
||||||
|
|
|
@ -33,7 +33,6 @@
|
||||||
#include "object/implementation/programmable_impl.h"
|
#include "object/implementation/programmable_impl.h"
|
||||||
#include "object/implementation/task_executor_impl.h"
|
#include "object/implementation/task_executor_impl.h"
|
||||||
|
|
||||||
#include "object/interface/carrier_object.h"
|
|
||||||
#include "object/interface/controllable_object.h"
|
#include "object/interface/controllable_object.h"
|
||||||
#include "object/interface/flying_object.h"
|
#include "object/interface/flying_object.h"
|
||||||
#include "object/interface/interactive_object.h"
|
#include "object/interface/interactive_object.h"
|
||||||
|
@ -41,10 +40,10 @@
|
||||||
#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/power_container_object.h"
|
||||||
#include "object/interface/powered_object.h"
|
|
||||||
#include "object/interface/programmable_object.h"
|
#include "object/interface/programmable_object.h"
|
||||||
#include "object/interface/ranged_object.h"
|
#include "object/interface/ranged_object.h"
|
||||||
#include "object/interface/shielded_auto_regen_object.h"
|
#include "object/interface/shielded_auto_regen_object.h"
|
||||||
|
#include "object/interface/slotted_object.h"
|
||||||
#include "object/interface/task_executor_object.h"
|
#include "object/interface/task_executor_object.h"
|
||||||
#include "object/interface/trace_drawing_object.h"
|
#include "object/interface/trace_drawing_object.h"
|
||||||
#include "object/interface/transportable_object.h"
|
#include "object/interface/transportable_object.h"
|
||||||
|
@ -83,8 +82,7 @@ class COldObject : public CObject,
|
||||||
public CProgramStorageObjectImpl,
|
public CProgramStorageObjectImpl,
|
||||||
public CProgrammableObjectImpl,
|
public CProgrammableObjectImpl,
|
||||||
public CJostleableObject,
|
public CJostleableObject,
|
||||||
public CCarrierObject,
|
public CSlottedObject,
|
||||||
public CPoweredObject,
|
|
||||||
public CJetFlyingObject,
|
public CJetFlyingObject,
|
||||||
public CControllableObject,
|
public CControllableObject,
|
||||||
public CPowerContainerObjectImpl,
|
public CPowerContainerObjectImpl,
|
||||||
|
@ -175,12 +173,6 @@ public:
|
||||||
|
|
||||||
void SetMasterParticle(int part, int parti) override;
|
void SetMasterParticle(int part, int parti) override;
|
||||||
|
|
||||||
void SetPower(CObject* power) override;
|
|
||||||
CObject* GetPower() override;
|
|
||||||
Math::Vector GetPowerPosition() override;
|
|
||||||
void SetPowerPosition(const Math::Vector& powerPosition) override;
|
|
||||||
void SetCargo(CObject* cargo) override;
|
|
||||||
CObject* GetCargo() override;
|
|
||||||
void SetTransporter(CObject* transporter) override;
|
void SetTransporter(CObject* transporter) override;
|
||||||
CObject* GetTransporter() override;
|
CObject* GetTransporter() override;
|
||||||
void SetTransporterPart(int part) override;
|
void SetTransporterPart(int part) override;
|
||||||
|
@ -295,6 +287,17 @@ public:
|
||||||
void SetBulletWall(bool bulletWall);
|
void SetBulletWall(bool bulletWall);
|
||||||
bool IsBulletWall() override;
|
bool IsBulletWall() override;
|
||||||
|
|
||||||
|
// CSlottedObject
|
||||||
|
int MapPseudoSlot(Pseudoslot pseudoslot) override;
|
||||||
|
int GetNumSlots() override;
|
||||||
|
Math::Vector GetSlotPosition(int slotNum) override;
|
||||||
|
float GetSlotAngle(int slotNum) override;
|
||||||
|
float GetSlotAcceptanceAngle(int slotNum) override;
|
||||||
|
CObject *GetSlotContainedObject(int slotNum) override;
|
||||||
|
void SetSlotContainedObject(int slotNum, CObject *object) override;
|
||||||
|
// Helper for CSlottedObject initialization
|
||||||
|
void SetPowerPosition(const Math::Vector& powerPosition);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool EventFrame(const Event &event);
|
bool EventFrame(const Event &event);
|
||||||
void VirusFrame(float rTime);
|
void VirusFrame(float rTime);
|
||||||
|
@ -393,4 +396,7 @@ protected:
|
||||||
float m_traceWidth;
|
float m_traceWidth;
|
||||||
|
|
||||||
bool m_bulletWall = false;
|
bool m_bulletWall = false;
|
||||||
|
|
||||||
|
bool m_hasCargoSlot;
|
||||||
|
bool m_hasPowerSlot;
|
||||||
};
|
};
|
||||||
|
|
|
@ -36,7 +36,6 @@
|
||||||
|
|
||||||
#include "object/auto/auto.h"
|
#include "object/auto/auto.h"
|
||||||
|
|
||||||
#include "object/interface/carrier_object.h"
|
|
||||||
#include "object/interface/transportable_object.h"
|
#include "object/interface/transportable_object.h"
|
||||||
|
|
||||||
#include "object/motion/motionhuman.h"
|
#include "object/motion/motionhuman.h"
|
||||||
|
|
|
@ -26,6 +26,8 @@
|
||||||
|
|
||||||
#include "object/old_object.h"
|
#include "object/old_object.h"
|
||||||
|
|
||||||
|
#include "object/interface/slotted_object.h"
|
||||||
|
|
||||||
#include "physics/physics.h"
|
#include "physics/physics.h"
|
||||||
|
|
||||||
#include "sound/sound.h"
|
#include "sound/sound.h"
|
||||||
|
@ -42,7 +44,7 @@ CTaskFire::CTaskFire(COldObject* object) : CForegroundTask(object)
|
||||||
{
|
{
|
||||||
m_soundChannel = -1;
|
m_soundChannel = -1;
|
||||||
|
|
||||||
assert(m_object->Implements(ObjectInterfaceType::Powered));
|
assert(HasPowerCellSlot(m_object));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Object's destructor.
|
// Object's destructor.
|
||||||
|
@ -78,10 +80,8 @@ 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;
|
||||||
|
|
||||||
CPowerContainerObject* power = nullptr;
|
if (CPowerContainerObject* power = GetObjectPowerCell(m_object))
|
||||||
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;
|
||||||
|
@ -313,11 +313,11 @@ Error CTaskFire::Start(float delay)
|
||||||
}
|
}
|
||||||
m_delay = delay;
|
m_delay = delay;
|
||||||
|
|
||||||
assert(m_object->Implements(ObjectInterfaceType::Powered));
|
assert(HasPowerCellSlot(m_object));
|
||||||
CObject* power = dynamic_cast<CPoweredObject*>(m_object)->GetPower();
|
CPowerContainerObject *power = GetObjectPowerCell(m_object);
|
||||||
if (power == nullptr || !power->Implements(ObjectInterfaceType::PowerContainer)) return ERR_FIRE_ENERGY;
|
if (power == nullptr) return ERR_FIRE_ENERGY;
|
||||||
|
|
||||||
energy = dynamic_cast<CPowerContainerObject&>(*power).GetEnergy();
|
energy = 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;
|
||||||
|
|
|
@ -28,8 +28,6 @@
|
||||||
#include "object/object_manager.h"
|
#include "object/object_manager.h"
|
||||||
#include "object/old_object.h"
|
#include "object/old_object.h"
|
||||||
|
|
||||||
#include "object/interface/carrier_object.h"
|
|
||||||
|
|
||||||
#include "object/motion/motionhuman.h"
|
#include "object/motion/motionhuman.h"
|
||||||
|
|
||||||
#include "physics/physics.h"
|
#include "physics/physics.h"
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
#include "object/object_manager.h"
|
#include "object/object_manager.h"
|
||||||
#include "object/old_object.h"
|
#include "object/old_object.h"
|
||||||
|
|
||||||
|
#include "object/interface/slotted_object.h"
|
||||||
#include "object/interface/transportable_object.h"
|
#include "object/interface/transportable_object.h"
|
||||||
|
|
||||||
#include "object/subclass/base_alien.h"
|
#include "object/subclass/base_alien.h"
|
||||||
|
@ -1201,8 +1202,11 @@ bool CTaskGoto::AdjustTarget(CObject* pObj, Math::Vector &pos, float &distance)
|
||||||
type == OBJECT_MOBILEst ||
|
type == OBJECT_MOBILEst ||
|
||||||
type == OBJECT_MOBILEdr )
|
type == OBJECT_MOBILEdr )
|
||||||
{
|
{
|
||||||
assert(pObj->Implements(ObjectInterfaceType::Powered));
|
CSlottedObject *asSlotted = dynamic_cast<CSlottedObject*>(pObj);
|
||||||
pos = dynamic_cast<CPoweredObject&>(*pObj).GetPowerPosition();
|
int powerSlotIndex = asSlotted->MapPseudoSlot(CSlottedObject::Pseudoslot::POWER);
|
||||||
|
assert(powerSlotIndex >= 0);
|
||||||
|
pos = asSlotted->GetSlotPosition(powerSlotIndex);
|
||||||
|
// TODO: this only works for a certain slot angle
|
||||||
pos.x -= TAKE_DIST+TAKE_DIST_OTHER+distance;
|
pos.x -= TAKE_DIST+TAKE_DIST_OTHER+distance;
|
||||||
mat = pObj->GetWorldMatrix(0);
|
mat = pObj->GetWorldMatrix(0);
|
||||||
pos = Transform(*mat, pos);
|
pos = Transform(*mat, pos);
|
||||||
|
|
|
@ -30,14 +30,14 @@
|
||||||
#include "object/object_manager.h"
|
#include "object/object_manager.h"
|
||||||
#include "object/old_object.h"
|
#include "object/old_object.h"
|
||||||
|
|
||||||
#include "object/interface/carrier_object.h"
|
#include "object/interface/slotted_object.h"
|
||||||
#include "object/interface/powered_object.h"
|
|
||||||
#include "object/interface/transportable_object.h"
|
#include "object/interface/transportable_object.h"
|
||||||
|
|
||||||
#include "physics/physics.h"
|
#include "physics/physics.h"
|
||||||
|
|
||||||
#include "sound/sound.h"
|
#include "sound/sound.h"
|
||||||
|
|
||||||
|
const int INVALID_SLOT = -1;
|
||||||
|
|
||||||
//?const float MARGIN_FRONT = 2.0f;
|
//?const float MARGIN_FRONT = 2.0f;
|
||||||
//?const float MARGIN_BACK = 2.0f;
|
//?const float MARGIN_BACK = 2.0f;
|
||||||
|
@ -58,7 +58,7 @@ CTaskManip::CTaskManip(COldObject* object) : CForegroundTask(object)
|
||||||
m_arm = TMA_NEUTRAL;
|
m_arm = TMA_NEUTRAL;
|
||||||
m_hand = TMH_OPEN;
|
m_hand = TMH_OPEN;
|
||||||
|
|
||||||
assert(m_object->Implements(ObjectInterfaceType::Carrier));
|
assert(m_object->MapPseudoSlot(CSlottedObject::Pseudoslot::CARRYING) >= 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Object's destructor.
|
// Object's destructor.
|
||||||
|
@ -295,7 +295,7 @@ Error CTaskManip::Start(TaskManipOrder order, TaskManipArm arm)
|
||||||
type = m_object->GetType();
|
type = m_object->GetType();
|
||||||
if ( type == OBJECT_BEE ) // bee?
|
if ( type == OBJECT_BEE ) // bee?
|
||||||
{
|
{
|
||||||
if (m_object->GetCargo() == nullptr)
|
if (m_object->GetSlotContainedObjectReq(CSlottedObject::Pseudoslot::CARRYING) == nullptr)
|
||||||
{
|
{
|
||||||
if ( !m_physics->GetLand() ) return ERR_MANIP_FLY;
|
if ( !m_physics->GetLand() ) return ERR_MANIP_FLY;
|
||||||
|
|
||||||
|
@ -303,17 +303,17 @@ Error CTaskManip::Start(TaskManipOrder order, TaskManipArm arm)
|
||||||
if (other == nullptr) return ERR_MANIP_NIL;
|
if (other == nullptr) return ERR_MANIP_NIL;
|
||||||
assert(other->Implements(ObjectInterfaceType::Transportable));
|
assert(other->Implements(ObjectInterfaceType::Transportable));
|
||||||
|
|
||||||
m_object->SetCargo(other); // takes the ball
|
m_object->SetSlotContainedObjectReq(CSlottedObject::Pseudoslot::CARRYING, other); // takes the ball
|
||||||
dynamic_cast<CTransportableObject&>(*other).SetTransporter(m_object);
|
dynamic_cast<CTransportableObject&>(*other).SetTransporter(m_object);
|
||||||
dynamic_cast<CTransportableObject&>(*other).SetTransporterPart(0); // taken with the base
|
dynamic_cast<CTransportableObject&>(*other).SetTransporterPart(0); // taken with the base
|
||||||
other->SetPosition(Math::Vector(0.0f, -3.0f, 0.0f));
|
other->SetPosition(Math::Vector(0.0f, -3.0f, 0.0f));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
other = m_object->GetCargo(); // other = ball
|
other = m_object->GetSlotContainedObjectReq(CSlottedObject::Pseudoslot::CARRYING); // other = ball
|
||||||
assert(other->Implements(ObjectInterfaceType::Transportable));
|
assert(other->Implements(ObjectInterfaceType::Transportable));
|
||||||
|
|
||||||
m_object->SetCargo(nullptr); // lick the ball
|
m_object->SetSlotContainedObjectReq(CSlottedObject::Pseudoslot::CARRYING, nullptr); // lick the ball
|
||||||
dynamic_cast<CTransportableObject&>(*other).SetTransporter(nullptr);
|
dynamic_cast<CTransportableObject&>(*other).SetTransporter(nullptr);
|
||||||
pos = m_object->GetPosition();
|
pos = m_object->GetPosition();
|
||||||
pos.y -= 3.0f;
|
pos.y -= 3.0f;
|
||||||
|
@ -361,7 +361,7 @@ Error CTaskManip::Start(TaskManipOrder order, TaskManipArm arm)
|
||||||
|
|
||||||
if ( order == TMO_AUTO )
|
if ( order == TMO_AUTO )
|
||||||
{
|
{
|
||||||
if (m_object->GetCargo() == nullptr)
|
if (m_object->GetSlotContainedObjectReq(CSlottedObject::Pseudoslot::CARRYING) == nullptr)
|
||||||
{
|
{
|
||||||
m_order = TMO_GRAB;
|
m_order = TMO_GRAB;
|
||||||
}
|
}
|
||||||
|
@ -375,11 +375,11 @@ Error CTaskManip::Start(TaskManipOrder order, TaskManipArm arm)
|
||||||
m_order = order;
|
m_order = order;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_order == TMO_GRAB && m_object->GetCargo() != nullptr)
|
if (m_order == TMO_GRAB && m_object->GetSlotContainedObjectReq(CSlottedObject::Pseudoslot::CARRYING) != nullptr)
|
||||||
{
|
{
|
||||||
return ERR_MANIP_BUSY;
|
return ERR_MANIP_BUSY;
|
||||||
}
|
}
|
||||||
if (m_order == TMO_DROP && m_object->GetCargo() == nullptr)
|
if (m_order == TMO_DROP && m_object->GetSlotContainedObjectReq(CSlottedObject::Pseudoslot::CARRYING) == nullptr)
|
||||||
{
|
{
|
||||||
return ERR_MANIP_EMPTY;
|
return ERR_MANIP_EMPTY;
|
||||||
}
|
}
|
||||||
|
@ -393,7 +393,8 @@ Error CTaskManip::Start(TaskManipOrder order, TaskManipArm arm)
|
||||||
if ( m_arm == TMA_FFRONT )
|
if ( m_arm == TMA_FFRONT )
|
||||||
{
|
{
|
||||||
front = SearchTakeFrontObject(true, fPos, fDist, fAngle);
|
front = SearchTakeFrontObject(true, fPos, fDist, fAngle);
|
||||||
other = SearchOtherObject(true, oPos, oDist, oAngle, oHeight);
|
int slotNum;
|
||||||
|
other = SearchOtherObject(true, oPos, oDist, oAngle, oHeight, slotNum);
|
||||||
|
|
||||||
if ( front != nullptr && fDist < oDist )
|
if ( front != nullptr && fDist < oDist )
|
||||||
{
|
{
|
||||||
|
@ -403,7 +404,7 @@ Error CTaskManip::Start(TaskManipOrder order, TaskManipArm arm)
|
||||||
}
|
}
|
||||||
else if ( other != nullptr && oDist < fDist )
|
else if ( other != nullptr && oDist < fDist )
|
||||||
{
|
{
|
||||||
if (! ObjectHasPowerCell(other)) return ERR_MANIP_NIL;
|
if (dynamic_cast<CSlottedObject&>(*other).GetSlotContainedObject(slotNum) == nullptr) return ERR_MANIP_NIL;
|
||||||
m_targetPos = oPos;
|
m_targetPos = oPos;
|
||||||
m_angle = oAngle;
|
m_angle = oAngle;
|
||||||
m_height = oHeight;
|
m_height = oHeight;
|
||||||
|
@ -427,8 +428,8 @@ Error CTaskManip::Start(TaskManipOrder order, TaskManipArm arm)
|
||||||
}
|
}
|
||||||
if ( m_arm == TMA_POWER )
|
if ( m_arm == TMA_POWER )
|
||||||
{
|
{
|
||||||
assert(m_object->Implements(ObjectInterfaceType::Powered));
|
assert(HasPowerCellSlot(m_object));
|
||||||
if (m_object->GetPower() == nullptr) return ERR_MANIP_NIL;
|
if (m_object->GetSlotContainedObjectOpt(CSlottedObject::Pseudoslot::POWER) == nullptr) return ERR_MANIP_NIL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -436,8 +437,9 @@ Error CTaskManip::Start(TaskManipOrder order, TaskManipArm arm)
|
||||||
{
|
{
|
||||||
if ( m_arm == TMA_FFRONT )
|
if ( m_arm == TMA_FFRONT )
|
||||||
{
|
{
|
||||||
other = SearchOtherObject(true, oPos, oDist, oAngle, oHeight);
|
int slotNum;
|
||||||
if (other != nullptr && !ObjectHasPowerCell(other))
|
other = SearchOtherObject(true, oPos, oDist, oAngle, oHeight, slotNum);
|
||||||
|
if (other != nullptr && dynamic_cast<CSlottedObject&>(*other).GetSlotContainedObject(slotNum) == nullptr)
|
||||||
{
|
{
|
||||||
m_targetPos = oPos;
|
m_targetPos = oPos;
|
||||||
m_angle = oAngle;
|
m_angle = oAngle;
|
||||||
|
@ -456,8 +458,8 @@ Error CTaskManip::Start(TaskManipOrder order, TaskManipArm arm)
|
||||||
}
|
}
|
||||||
if ( m_arm == TMA_POWER )
|
if ( m_arm == TMA_POWER )
|
||||||
{
|
{
|
||||||
assert(m_object->Implements(ObjectInterfaceType::Powered));
|
assert(HasPowerCellSlot(m_object));
|
||||||
if (m_object->GetPower() != nullptr) return ERR_MANIP_OCC;
|
if (m_object->GetSlotContainedObjectOpt(CSlottedObject::Pseudoslot::POWER) != nullptr) return ERR_MANIP_OCC;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -477,7 +479,7 @@ Error CTaskManip::Start(TaskManipOrder order, TaskManipArm arm)
|
||||||
if ( m_timeLimit < 0.5f ) m_timeLimit = 0.5f;
|
if ( m_timeLimit < 0.5f ) m_timeLimit = 0.5f;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_object->GetCargo() == nullptr) // not carrying anything?
|
if (m_object->GetSlotContainedObjectReq(CSlottedObject::Pseudoslot::CARRYING) == nullptr) // not carrying anything?
|
||||||
{
|
{
|
||||||
m_hand = TMH_OPEN; // open clamp
|
m_hand = TMH_OPEN; // open clamp
|
||||||
}
|
}
|
||||||
|
@ -602,7 +604,7 @@ Error CTaskManip::IsEnded()
|
||||||
{
|
{
|
||||||
if ( m_bSubm ) m_speed = 1.0f/1.5f;
|
if ( m_bSubm ) m_speed = 1.0f/1.5f;
|
||||||
if ( !TransporterTakeObject() &&
|
if ( !TransporterTakeObject() &&
|
||||||
m_object->GetCargo() == nullptr)
|
m_object->GetSlotContainedObjectReq(CSlottedObject::Pseudoslot::CARRYING) == nullptr)
|
||||||
{
|
{
|
||||||
m_hand = TMH_OPEN; // reopens the clamp
|
m_hand = TMH_OPEN; // reopens the clamp
|
||||||
m_arm = TMA_NEUTRAL;
|
m_arm = TMA_NEUTRAL;
|
||||||
|
@ -613,7 +615,7 @@ Error CTaskManip::IsEnded()
|
||||||
{
|
{
|
||||||
if ( (m_arm == TMA_OTHER ||
|
if ( (m_arm == TMA_OTHER ||
|
||||||
m_arm == TMA_POWER ) &&
|
m_arm == TMA_POWER ) &&
|
||||||
m_object->GetCargo()->Implements(ObjectInterfaceType::PowerContainer) )
|
m_object->GetSlotContainedObjectReq(CSlottedObject::Pseudoslot::CARRYING)->Implements(ObjectInterfaceType::PowerContainer) )
|
||||||
{
|
{
|
||||||
m_sound->Play(SOUND_POWEROFF, m_object->GetPosition());
|
m_sound->Play(SOUND_POWEROFF, m_object->GetPosition());
|
||||||
}
|
}
|
||||||
|
@ -630,7 +632,7 @@ Error CTaskManip::IsEnded()
|
||||||
if ( m_step == 1 )
|
if ( m_step == 1 )
|
||||||
{
|
{
|
||||||
if ( m_bSubm ) m_speed = 1.0f/0.7f;
|
if ( m_bSubm ) m_speed = 1.0f/0.7f;
|
||||||
cargo = m_object->GetCargo();
|
cargo = m_object->GetSlotContainedObjectReq(CSlottedObject::Pseudoslot::CARRYING);
|
||||||
if (TransporterDeposeObject())
|
if (TransporterDeposeObject())
|
||||||
{
|
{
|
||||||
if ( (m_arm == TMA_OTHER ||
|
if ( (m_arm == TMA_OTHER ||
|
||||||
|
@ -667,7 +669,7 @@ Error CTaskManip::IsEnded()
|
||||||
|
|
||||||
bool CTaskManip::Abort()
|
bool CTaskManip::Abort()
|
||||||
{
|
{
|
||||||
if (m_object->GetCargo() == nullptr) // not carrying anything?
|
if (m_object->GetSlotContainedObjectReq(CSlottedObject::Pseudoslot::CARRYING) == nullptr) // not carrying anything?
|
||||||
{
|
{
|
||||||
m_hand = TMH_OPEN; // open clamp
|
m_hand = TMH_OPEN; // open clamp
|
||||||
m_arm = TMA_NEUTRAL;
|
m_arm = TMA_NEUTRAL;
|
||||||
|
@ -868,10 +870,12 @@ CObject* CTaskManip::SearchTakeBackObject(bool bAdvance, Math::Vector &pos,
|
||||||
|
|
||||||
CObject* CTaskManip::SearchOtherObject(bool bAdvance, Math::Vector &pos,
|
CObject* CTaskManip::SearchOtherObject(bool bAdvance, Math::Vector &pos,
|
||||||
float &distance, float &angle,
|
float &distance, float &angle,
|
||||||
float &height)
|
float &height, int &slotNumOut)
|
||||||
{
|
{
|
||||||
|
slotNumOut = INVALID_SLOT;
|
||||||
|
|
||||||
Math::Matrix* mat;
|
Math::Matrix* mat;
|
||||||
float iAngle, oAngle, oLimit, aLimit, dLimit;
|
float iAngle, aLimit, dLimit;
|
||||||
|
|
||||||
distance = 1000000.0f;
|
distance = 1000000.0f;
|
||||||
angle = 0.0f;
|
angle = 0.0f;
|
||||||
|
@ -900,56 +904,45 @@ CObject* CTaskManip::SearchOtherObject(bool bAdvance, Math::Vector &pos,
|
||||||
{
|
{
|
||||||
if ( pObj == m_object ) continue; // yourself?
|
if ( pObj == m_object ) continue; // yourself?
|
||||||
|
|
||||||
ObjectType type = pObj->GetType();
|
if (pObj->Implements(ObjectInterfaceType::Slotted))
|
||||||
if ( !pObj->Implements(ObjectInterfaceType::Powered) ) continue;
|
|
||||||
|
|
||||||
CObject* power = dynamic_cast<CPoweredObject&>(*pObj).GetPower();
|
|
||||||
if (power != nullptr)
|
|
||||||
{
|
{
|
||||||
if (power->GetLock()) continue;
|
CSlottedObject &obj = dynamic_cast<CSlottedObject&>(*pObj);
|
||||||
if (power->GetScaleY() != 1.0f) continue;
|
int slotNum = obj.GetNumSlots();
|
||||||
}
|
for (int slot = 0; slot < slotNum; slot++)
|
||||||
|
|
||||||
mat = pObj->GetWorldMatrix(0);
|
|
||||||
Math::Vector oPos = Transform(*mat, dynamic_cast<CPoweredObject&>(*pObj).GetPowerPosition());
|
|
||||||
|
|
||||||
oAngle = pObj->GetRotationY();
|
|
||||||
if ( type == OBJECT_TOWER ||
|
|
||||||
type == OBJECT_RESEARCH )
|
|
||||||
{
|
|
||||||
oLimit = 45.0f*Math::PI/180.0f;
|
|
||||||
}
|
|
||||||
else if ( type == OBJECT_ENERGY )
|
|
||||||
{
|
|
||||||
oLimit = 90.0f*Math::PI/180.0f;
|
|
||||||
}
|
|
||||||
else if ( type == OBJECT_LABO )
|
|
||||||
{
|
|
||||||
oLimit = 120.0f*Math::PI/180.0f;
|
|
||||||
}
|
|
||||||
else if ( type == OBJECT_NUCLEAR )
|
|
||||||
{
|
|
||||||
oLimit = 45.0f*Math::PI/180.0f;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
oLimit = 45.0f*Math::PI/180.0f;
|
|
||||||
oAngle += Math::PI; // is behind
|
|
||||||
}
|
|
||||||
oAngle = Math::NormAngle(oAngle); // 0..2*Math::PI
|
|
||||||
angle = Math::RotateAngle(iPos.x-oPos.x, oPos.z-iPos.z); // CW !
|
|
||||||
if ( !Math::TestAngle(angle, oAngle-oLimit, oAngle+oLimit) ) continue;
|
|
||||||
|
|
||||||
distance = fabs(Math::Distance(oPos, iPos)-TAKE_DIST);
|
|
||||||
if ( distance <= dLimit )
|
|
||||||
{
|
|
||||||
angle = Math::RotateAngle(oPos.x-iPos.x, iPos.z-oPos.z); // CW !
|
|
||||||
if ( Math::TestAngle(angle, iAngle-aLimit, iAngle+aLimit) )
|
|
||||||
{
|
{
|
||||||
Math::Vector powerPos = dynamic_cast<CPoweredObject&>(*pObj).GetPowerPosition();
|
mat = pObj->GetWorldMatrix(0);
|
||||||
height = powerPos.y;
|
Math::Vector worldSlotPos = Transform(*mat, obj.GetSlotPosition(slot));
|
||||||
pos = oPos;
|
|
||||||
return pObj;
|
CObject *objectInSlot = obj.GetSlotContainedObject(slot);
|
||||||
|
if (objectInSlot != nullptr && (objectInSlot->GetLock() || objectInSlot->GetScaleY() != 1.0f))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
float objectAngleOffsetLimit = obj.GetSlotAcceptanceAngle(slot);
|
||||||
|
if(objectAngleOffsetLimit == 0)
|
||||||
|
continue; // slot isn't take-able
|
||||||
|
|
||||||
|
// The robot must be in the correct angle relative to the slot (it can't be on the other side of the object)
|
||||||
|
float angleFromObjectToRobot = Math::RotateAngle(iPos.x-worldSlotPos.x, worldSlotPos.z-iPos.z); // CW !
|
||||||
|
float objectIdealAngle = Math::NormAngle(pObj->GetRotationY() + obj.GetSlotAngle(slot));
|
||||||
|
|
||||||
|
if ( Math::TestAngle(angleFromObjectToRobot, objectIdealAngle - objectAngleOffsetLimit, objectIdealAngle + objectAngleOffsetLimit) )
|
||||||
|
{
|
||||||
|
distance = fabs(Math::Distance(worldSlotPos, iPos)-TAKE_DIST);
|
||||||
|
// The robot must be close enough to the slot
|
||||||
|
if ( distance <= dLimit )
|
||||||
|
{
|
||||||
|
// The slot must be in the correct position relative to the robot (the robot must be facing towards the slot, not sideways or away)
|
||||||
|
angle = Math::RotateAngle(worldSlotPos.x-iPos.x, iPos.z-worldSlotPos.z); // CW !
|
||||||
|
if ( Math::TestAngle(angle, iAngle-aLimit, iAngle+aLimit) )
|
||||||
|
{
|
||||||
|
Math::Vector powerPos = obj.GetSlotPosition(slot);
|
||||||
|
height = powerPos.y;
|
||||||
|
pos = worldSlotPos;
|
||||||
|
slotNumOut = slot;
|
||||||
|
return pObj;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -965,7 +958,7 @@ bool CTaskManip::TransporterTakeObject()
|
||||||
{
|
{
|
||||||
if (m_arm == TMA_GRAB) // takes immediately?
|
if (m_arm == TMA_GRAB) // takes immediately?
|
||||||
{
|
{
|
||||||
CObject* cargo = m_object->GetCargo();
|
CObject* cargo = m_object->GetSlotContainedObjectReq(CSlottedObject::Pseudoslot::CARRYING);
|
||||||
if (cargo == nullptr) return false; // nothing to take?
|
if (cargo == nullptr) return false; // nothing to take?
|
||||||
assert(cargo->Implements(ObjectInterfaceType::Transportable));
|
assert(cargo->Implements(ObjectInterfaceType::Transportable));
|
||||||
|
|
||||||
|
@ -1005,7 +998,7 @@ bool CTaskManip::TransporterTakeObject()
|
||||||
cargo->SetRotationY(0.0f);
|
cargo->SetRotationY(0.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_object->SetCargo(cargo); // takes
|
m_object->SetSlotContainedObjectReq(CSlottedObject::Pseudoslot::CARRYING, cargo); // takes
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_arm == TMA_FFRONT) // takes on the ground in front?
|
if (m_arm == TMA_FFRONT) // takes on the ground in front?
|
||||||
|
@ -1041,7 +1034,7 @@ bool CTaskManip::TransporterTakeObject()
|
||||||
cargo->SetRotationY(0.0f);
|
cargo->SetRotationY(0.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_object->SetCargo(cargo); // takes
|
m_object->SetSlotContainedObjectReq(CSlottedObject::Pseudoslot::CARRYING, cargo); // takes
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_arm == TMA_FBACK) // takes on the ground behind?
|
if (m_arm == TMA_FBACK) // takes on the ground behind?
|
||||||
|
@ -1063,13 +1056,13 @@ bool CTaskManip::TransporterTakeObject()
|
||||||
cargo->SetRotationZ(Math::PI/2.0f);
|
cargo->SetRotationZ(Math::PI/2.0f);
|
||||||
cargo->SetRotationY(0.0f);
|
cargo->SetRotationY(0.0f);
|
||||||
|
|
||||||
m_object->SetCargo(cargo); // takes
|
m_object->SetSlotContainedObjectReq(CSlottedObject::Pseudoslot::CARRYING, cargo); // takes
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_arm == TMA_POWER) // takes battery in the back?
|
if (m_arm == TMA_POWER) // takes battery in the back?
|
||||||
{
|
{
|
||||||
assert(m_object->Implements(ObjectInterfaceType::Powered));
|
assert(m_object->Implements(ObjectInterfaceType::Slotted));
|
||||||
CObject* cargo = m_object->GetPower();
|
CObject* cargo = m_object->GetSlotContainedObjectOpt(CSlottedObject::Pseudoslot::POWER);
|
||||||
if (cargo == nullptr) return false; // no battery?
|
if (cargo == nullptr) return false; // no battery?
|
||||||
assert(cargo->Implements(ObjectInterfaceType::Transportable));
|
assert(cargo->Implements(ObjectInterfaceType::Transportable));
|
||||||
|
|
||||||
|
@ -1082,25 +1075,25 @@ bool CTaskManip::TransporterTakeObject()
|
||||||
cargo->SetRotationY(0.0f);
|
cargo->SetRotationY(0.0f);
|
||||||
dynamic_cast<CTransportableObject&>(*cargo).SetTransporterPart(3); // takes with the hand
|
dynamic_cast<CTransportableObject&>(*cargo).SetTransporterPart(3); // takes with the hand
|
||||||
|
|
||||||
m_object->SetPower(nullptr);
|
m_object->SetSlotContainedObjectReq(CSlottedObject::Pseudoslot::POWER, nullptr);
|
||||||
m_object->SetCargo(cargo); // takes
|
m_object->SetSlotContainedObjectReq(CSlottedObject::Pseudoslot::CARRYING, cargo); // takes
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_arm == TMA_OTHER) // battery takes from friend?
|
if (m_arm == TMA_OTHER) // battery takes from friend?
|
||||||
{
|
{
|
||||||
Math::Vector pos;
|
Math::Vector pos;
|
||||||
float dist = 0.0f, angle = 0.0f;
|
float dist = 0.0f, angle = 0.0f;
|
||||||
CObject* other = SearchOtherObject(false, pos, dist, angle, m_height);
|
int slotNum;
|
||||||
|
CObject* other = SearchOtherObject(false, pos, dist, angle, m_height, slotNum);
|
||||||
if (other == nullptr) return false;
|
if (other == nullptr) return false;
|
||||||
assert(other->Implements(ObjectInterfaceType::Powered));
|
assert(slotNum != INVALID_SLOT);
|
||||||
|
CObject *cargo = dynamic_cast<CSlottedObject&>(*other).GetSlotContainedObject(slotNum);
|
||||||
CObject* cargo = dynamic_cast<CPoweredObject&>(*other).GetPower();
|
|
||||||
if (cargo == nullptr) return false; // the other does not have a battery?
|
if (cargo == nullptr) return false; // the other does not have a battery?
|
||||||
assert(cargo->Implements(ObjectInterfaceType::Transportable));
|
assert(cargo->Implements(ObjectInterfaceType::Transportable));
|
||||||
|
|
||||||
m_cargoType = cargo->GetType();
|
m_cargoType = cargo->GetType();
|
||||||
|
|
||||||
dynamic_cast<CPoweredObject&>(*other).SetPower(nullptr);
|
dynamic_cast<CSlottedObject&>(*other).SetSlotContainedObject(slotNum, nullptr);
|
||||||
dynamic_cast<CTransportableObject&>(*cargo).SetTransporter(m_object);
|
dynamic_cast<CTransportableObject&>(*cargo).SetTransporter(m_object);
|
||||||
dynamic_cast<CTransportableObject&>(*cargo).SetTransporterPart(3); // takes with the hand
|
dynamic_cast<CTransportableObject&>(*cargo).SetTransporterPart(3); // takes with the hand
|
||||||
|
|
||||||
|
@ -1110,7 +1103,7 @@ bool CTaskManip::TransporterTakeObject()
|
||||||
cargo->SetRotationZ(Math::PI/2.0f);
|
cargo->SetRotationZ(Math::PI/2.0f);
|
||||||
cargo->SetRotationY(0.0f);
|
cargo->SetRotationY(0.0f);
|
||||||
|
|
||||||
m_object->SetCargo(cargo); // takes
|
m_object->SetSlotContainedObjectReq(CSlottedObject::Pseudoslot::CARRYING, cargo); // takes
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -1122,7 +1115,7 @@ bool CTaskManip::TransporterDeposeObject()
|
||||||
{
|
{
|
||||||
if (m_arm == TMA_FFRONT) // deposits on the ground in front?
|
if (m_arm == TMA_FFRONT) // deposits on the ground in front?
|
||||||
{
|
{
|
||||||
CObject* cargo = m_object->GetCargo();
|
CObject* cargo = m_object->GetSlotContainedObjectReq(CSlottedObject::Pseudoslot::CARRYING);
|
||||||
if (cargo == nullptr) return false; // nothing transported?
|
if (cargo == nullptr) return false; // nothing transported?
|
||||||
assert(cargo->Implements(ObjectInterfaceType::Transportable));
|
assert(cargo->Implements(ObjectInterfaceType::Transportable));
|
||||||
|
|
||||||
|
@ -1138,12 +1131,12 @@ bool CTaskManip::TransporterDeposeObject()
|
||||||
cargo->FloorAdjust(); // plate well on the ground
|
cargo->FloorAdjust(); // plate well on the ground
|
||||||
|
|
||||||
dynamic_cast<CTransportableObject&>(*cargo).SetTransporter(nullptr);
|
dynamic_cast<CTransportableObject&>(*cargo).SetTransporter(nullptr);
|
||||||
m_object->SetCargo(nullptr); // deposit
|
m_object->SetSlotContainedObjectReq(CSlottedObject::Pseudoslot::CARRYING, nullptr); // deposit
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_arm == TMA_FBACK) // deposited on the ground behind?
|
if (m_arm == TMA_FBACK) // deposited on the ground behind?
|
||||||
{
|
{
|
||||||
CObject* cargo = m_object->GetCargo();
|
CObject* cargo = m_object->GetSlotContainedObjectReq(CSlottedObject::Pseudoslot::CARRYING);
|
||||||
if (cargo == nullptr) return false; // nothing transported?
|
if (cargo == nullptr) return false; // nothing transported?
|
||||||
assert(cargo->Implements(ObjectInterfaceType::Transportable));
|
assert(cargo->Implements(ObjectInterfaceType::Transportable));
|
||||||
|
|
||||||
|
@ -1158,30 +1151,32 @@ bool CTaskManip::TransporterDeposeObject()
|
||||||
cargo->SetRotationZ(0.0f);
|
cargo->SetRotationZ(0.0f);
|
||||||
|
|
||||||
dynamic_cast<CTransportableObject&>(*cargo).SetTransporter(nullptr);
|
dynamic_cast<CTransportableObject&>(*cargo).SetTransporter(nullptr);
|
||||||
m_object->SetCargo(nullptr); // deposit
|
m_object->SetSlotContainedObjectReq(CSlottedObject::Pseudoslot::CARRYING, nullptr); // deposit
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_arm == TMA_POWER) // deposits battery in the back?
|
if (m_arm == TMA_POWER) // deposits battery in the back?
|
||||||
{
|
{
|
||||||
assert(m_object->Implements(ObjectInterfaceType::Powered));
|
assert(m_object->Implements(ObjectInterfaceType::Slotted));
|
||||||
CObject* cargo = m_object->GetCargo();
|
CObject* cargo = m_object->GetSlotContainedObjectReq(CSlottedObject::Pseudoslot::CARRYING);
|
||||||
if (cargo == nullptr) return false; // nothing transported?
|
if (cargo == nullptr) return false; // nothing transported?
|
||||||
assert(cargo->Implements(ObjectInterfaceType::Transportable));
|
assert(cargo->Implements(ObjectInterfaceType::Transportable));
|
||||||
|
|
||||||
m_cargoType = cargo->GetType();
|
m_cargoType = cargo->GetType();
|
||||||
|
|
||||||
if (m_object->GetPower() != nullptr) return false;
|
int powerSlotIndex = m_object->MapPseudoSlot(CSlottedObject::Pseudoslot::POWER);
|
||||||
|
assert(powerSlotIndex >= 0);
|
||||||
|
if (m_object->GetSlotContainedObject(powerSlotIndex) != nullptr) return false;
|
||||||
|
|
||||||
dynamic_cast<CTransportableObject&>(*cargo).SetTransporter(m_object);
|
dynamic_cast<CTransportableObject&>(*cargo).SetTransporter(m_object);
|
||||||
dynamic_cast<CTransportableObject&>(*cargo).SetTransporterPart(0); // carried by the base
|
dynamic_cast<CTransportableObject&>(*cargo).SetTransporterPart(0); // carried by the base
|
||||||
|
|
||||||
cargo->SetPosition(m_object->GetPowerPosition());
|
cargo->SetPosition(m_object->GetSlotPosition(powerSlotIndex));
|
||||||
cargo->SetRotationY(0.0f);
|
cargo->SetRotationY(0.0f);
|
||||||
cargo->SetRotationX(0.0f);
|
cargo->SetRotationX(0.0f);
|
||||||
cargo->SetRotationZ(0.0f);
|
cargo->SetRotationZ(0.0f);
|
||||||
|
|
||||||
m_object->SetPower(cargo); // uses
|
m_object->SetSlotContainedObject(powerSlotIndex, cargo); // uses
|
||||||
m_object->SetCargo(nullptr);
|
m_object->SetSlotContainedObjectReq(CSlottedObject::Pseudoslot::CARRYING, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_arm == TMA_OTHER) // deposits battery on friend?
|
if (m_arm == TMA_OTHER) // deposits battery on friend?
|
||||||
|
@ -1189,29 +1184,30 @@ bool CTaskManip::TransporterDeposeObject()
|
||||||
Math::Vector pos;
|
Math::Vector pos;
|
||||||
float angle = 0.0f, dist = 0.0f;
|
float angle = 0.0f, dist = 0.0f;
|
||||||
|
|
||||||
CObject* other = SearchOtherObject(false, pos, dist, angle, m_height);
|
int slotNum;
|
||||||
|
CObject* other = SearchOtherObject(false, pos, dist, angle, m_height, slotNum);
|
||||||
if (other == nullptr) return false;
|
if (other == nullptr) return false;
|
||||||
assert(other->Implements(ObjectInterfaceType::Powered));
|
assert(slotNum != INVALID_SLOT);
|
||||||
|
CSlottedObject *otherAsSlotted = dynamic_cast<CSlottedObject*>(other);
|
||||||
|
if (otherAsSlotted->GetSlotContainedObject(slotNum) != nullptr) return false; // the other already has a battery?
|
||||||
|
|
||||||
CObject* cargo = dynamic_cast<CPoweredObject&>(*other).GetPower();
|
CObject *cargo = m_object->GetSlotContainedObjectReq(CSlottedObject::Pseudoslot::CARRYING);
|
||||||
if (cargo != nullptr) return false; // the other already has a battery?
|
|
||||||
|
|
||||||
cargo = m_object->GetCargo();
|
|
||||||
if (cargo == nullptr) return false;
|
if (cargo == nullptr) return false;
|
||||||
assert(cargo->Implements(ObjectInterfaceType::Transportable));
|
assert(cargo->Implements(ObjectInterfaceType::Transportable));
|
||||||
|
|
||||||
m_cargoType = cargo->GetType();
|
m_cargoType = cargo->GetType();
|
||||||
|
|
||||||
dynamic_cast<CPoweredObject&>(*other).SetPower(cargo);
|
otherAsSlotted->SetSlotContainedObject(slotNum, cargo);
|
||||||
dynamic_cast<CTransportableObject&>(*cargo).SetTransporter(other);
|
dynamic_cast<CTransportableObject&>(*cargo).SetTransporter(other);
|
||||||
|
|
||||||
cargo->SetPosition(dynamic_cast<CPoweredObject&>(*other).GetPowerPosition());
|
// TODO: isn't this wrong? PowerPosition (and SlotContainedPosition) is an object-local position.
|
||||||
|
cargo->SetPosition(otherAsSlotted->GetSlotPosition(slotNum));
|
||||||
cargo->SetRotationY(0.0f);
|
cargo->SetRotationY(0.0f);
|
||||||
cargo->SetRotationX(0.0f);
|
cargo->SetRotationX(0.0f);
|
||||||
cargo->SetRotationZ(0.0f);
|
cargo->SetRotationZ(0.0f);
|
||||||
dynamic_cast<CTransportableObject&>(*cargo).SetTransporterPart(0); // carried by the base
|
dynamic_cast<CTransportableObject&>(*cargo).SetTransporterPart(0); // carried by the base
|
||||||
|
|
||||||
m_object->SetCargo(nullptr); // deposit
|
m_object->SetSlotContainedObjectReq(CSlottedObject::Pseudoslot::CARRYING, nullptr); // deposit
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -73,7 +73,7 @@ protected:
|
||||||
CObject* SearchTakeUnderObject(Math::Vector &pos, float dLimit);
|
CObject* SearchTakeUnderObject(Math::Vector &pos, float dLimit);
|
||||||
CObject* SearchTakeFrontObject(bool bAdvance, Math::Vector &pos, float &distance, float &angle);
|
CObject* SearchTakeFrontObject(bool bAdvance, Math::Vector &pos, float &distance, float &angle);
|
||||||
CObject* SearchTakeBackObject(bool bAdvance, Math::Vector &pos, float &distance, float &angle);
|
CObject* SearchTakeBackObject(bool bAdvance, Math::Vector &pos, float &distance, float &angle);
|
||||||
CObject* SearchOtherObject(bool bAdvance, Math::Vector &pos, float &distance, float &angle, float &height);
|
CObject* SearchOtherObject(bool bAdvance, Math::Vector &pos, float &distance, float &angle, float &height, int &slotNumOut);
|
||||||
bool TransporterTakeObject();
|
bool TransporterTakeObject();
|
||||||
bool TransporterDeposeObject();
|
bool TransporterDeposeObject();
|
||||||
bool IsFreeDeposeObject(Math::Vector pos);
|
bool IsFreeDeposeObject(Math::Vector pos);
|
||||||
|
|
|
@ -31,7 +31,7 @@
|
||||||
#include "object/object_manager.h"
|
#include "object/object_manager.h"
|
||||||
#include "object/old_object.h"
|
#include "object/old_object.h"
|
||||||
|
|
||||||
#include "object/interface/powered_object.h"
|
#include "object/interface/slotted_object.h"
|
||||||
|
|
||||||
#include "physics/physics.h"
|
#include "physics/physics.h"
|
||||||
|
|
||||||
|
@ -108,11 +108,9 @@ bool CTaskRecover::EventProcess(const Event &event)
|
||||||
|
|
||||||
if ( m_phase == TRP_OPER )
|
if ( m_phase == TRP_OPER )
|
||||||
{
|
{
|
||||||
assert(m_object->Implements(ObjectInterfaceType::Powered));
|
assert(HasPowerCellSlot(m_object));
|
||||||
CObject* powerObj = dynamic_cast<CPoweredObject*>(m_object)->GetPower();
|
if (CPowerContainerObject* power = GetObjectPowerCell(m_object))
|
||||||
if (powerObj != nullptr && powerObj->Implements(ObjectInterfaceType::PowerContainer))
|
|
||||||
{
|
{
|
||||||
CPowerContainerObject* power = dynamic_cast<CPowerContainerObject*>(powerObj);
|
|
||||||
energy = power->GetEnergy();
|
energy = power->GetEnergy();
|
||||||
energy -= event.rTime * ENERGY_RECOVER * m_speed;
|
energy -= event.rTime * ENERGY_RECOVER * m_speed;
|
||||||
power->SetEnergy(energy);
|
power->SetEnergy(energy);
|
||||||
|
@ -190,11 +188,10 @@ Error CTaskRecover::Start()
|
||||||
ObjectType type = m_object->GetType();
|
ObjectType type = m_object->GetType();
|
||||||
if ( type != OBJECT_MOBILErr ) return ERR_WRONG_BOT;
|
if ( type != OBJECT_MOBILErr ) return ERR_WRONG_BOT;
|
||||||
|
|
||||||
assert(m_object->Implements(ObjectInterfaceType::Powered));
|
CPowerContainerObject *power = GetObjectPowerCell(m_object);
|
||||||
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 = dynamic_cast<CPowerContainerObject&>(*power).GetEnergy();
|
float energy = power->GetEnergy();
|
||||||
if ( energy < ENERGY_RECOVER+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);
|
||||||
|
|
|
@ -32,7 +32,7 @@
|
||||||
#include "object/object_manager.h"
|
#include "object/object_manager.h"
|
||||||
#include "object/old_object.h"
|
#include "object/old_object.h"
|
||||||
|
|
||||||
#include "object/interface/powered_object.h"
|
#include "object/interface/slotted_object.h"
|
||||||
|
|
||||||
#include "object/subclass/shielder.h"
|
#include "object/subclass/shielder.h"
|
||||||
|
|
||||||
|
@ -54,7 +54,7 @@ CTaskShield::CTaskShield(COldObject* object) : CBackgroundTask(object)
|
||||||
m_soundChannel = -1;
|
m_soundChannel = -1;
|
||||||
m_effectLight = -1;
|
m_effectLight = -1;
|
||||||
|
|
||||||
assert(m_object->Implements(ObjectInterfaceType::Powered));
|
assert(HasPowerCellSlot(m_object));
|
||||||
m_shielder = dynamic_cast<CShielder*>(object);
|
m_shielder = dynamic_cast<CShielder*>(object);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -118,12 +118,8 @@ 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;
|
||||||
CObject* powerObj = dynamic_cast<CPoweredObject*>(m_object)->GetPower();
|
if (CPowerContainerObject *power = GetObjectPowerCell(m_object))
|
||||||
if (powerObj != nullptr && powerObj->Implements(ObjectInterfaceType::PowerContainer))
|
|
||||||
{
|
|
||||||
CPowerContainerObject* power = dynamic_cast<CPowerContainerObject*>(powerObj);
|
|
||||||
power->SetEnergy(power->GetEnergy()-energy);
|
power->SetEnergy(power->GetEnergy()-energy);
|
||||||
}
|
|
||||||
m_energyUsed += energy;
|
m_energyUsed += energy;
|
||||||
|
|
||||||
if ( m_soundChannel == -1 )
|
if ( m_soundChannel == -1 )
|
||||||
|
@ -307,9 +303,9 @@ Error CTaskShield::Start(TaskShieldMode mode, float delay)
|
||||||
m_bError = true; // operation impossible
|
m_bError = true; // operation impossible
|
||||||
if ( !m_physics->GetLand() ) return ERR_WRONG_BOT;
|
if ( !m_physics->GetLand() ) return ERR_WRONG_BOT;
|
||||||
|
|
||||||
CObject* power = m_object->GetPower();
|
CPowerContainerObject* power = GetObjectPowerCell(m_object);
|
||||||
if (power == nullptr || !power->Implements(ObjectInterfaceType::PowerContainer)) return ERR_SHIELD_ENERGY;
|
if (power == nullptr) return ERR_SHIELD_ENERGY;
|
||||||
float energy = dynamic_cast<CPowerContainerObject&>(*power).GetEnergy();
|
float energy = 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);
|
||||||
|
|
|
@ -30,8 +30,7 @@
|
||||||
#include "object/object_manager.h"
|
#include "object/object_manager.h"
|
||||||
#include "object/old_object.h"
|
#include "object/old_object.h"
|
||||||
|
|
||||||
#include "object/interface/carrier_object.h"
|
#include "object/interface/slotted_object.h"
|
||||||
#include "object/interface/powered_object.h"
|
|
||||||
#include "object/interface/transportable_object.h"
|
#include "object/interface/transportable_object.h"
|
||||||
|
|
||||||
#include "object/motion/motionhuman.h"
|
#include "object/motion/motionhuman.h"
|
||||||
|
@ -49,7 +48,7 @@ CTaskTake::CTaskTake(COldObject* object) : CForegroundTask(object)
|
||||||
{
|
{
|
||||||
m_arm = TTA_NEUTRAL;
|
m_arm = TTA_NEUTRAL;
|
||||||
|
|
||||||
assert(m_object->Implements(ObjectInterfaceType::Carrier));
|
assert(m_object->MapPseudoSlot(CSlottedObject::Pseudoslot::CARRYING) >= 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Object's destructor.
|
// Object's destructor.
|
||||||
|
@ -116,7 +115,7 @@ Error CTaskTake::Start()
|
||||||
|
|
||||||
m_physics->SetMotorSpeed(Math::Vector(0.0f, 0.0f, 0.0f));
|
m_physics->SetMotorSpeed(Math::Vector(0.0f, 0.0f, 0.0f));
|
||||||
|
|
||||||
if (m_object->IsCarryingCargo())
|
if (m_object->GetSlotContainedObjectOpt(CSlottedObject::Pseudoslot::CARRYING) != nullptr)
|
||||||
m_order = TTO_DEPOSE;
|
m_order = TTO_DEPOSE;
|
||||||
else
|
else
|
||||||
m_order = TTO_TAKE;
|
m_order = TTO_TAKE;
|
||||||
|
@ -128,12 +127,14 @@ Error CTaskTake::Start()
|
||||||
float h = m_water->GetLevel(m_object);
|
float h = m_water->GetLevel(m_object);
|
||||||
if ( pos.y < h ) return ERR_MANIP_WATER; // impossible under water
|
if ( pos.y < h ) return ERR_MANIP_WATER; // impossible under water
|
||||||
|
|
||||||
CObject* other = SearchFriendObject(oAngle, 1.5f, Math::PI*0.50f);
|
int otherSlotNum = -1;
|
||||||
if (other != nullptr) assert(other->Implements(ObjectInterfaceType::Powered));
|
CObject* other = SearchFriendObject(oAngle, 1.5f, Math::PI*0.50f, otherSlotNum);
|
||||||
|
CSlottedObject* otherAsSlotted = dynamic_cast<CSlottedObject*>(other);
|
||||||
|
assert(other == nullptr || otherSlotNum >= 0);
|
||||||
|
|
||||||
if (other != nullptr && dynamic_cast<CPoweredObject&>(*other).GetPower() != nullptr)
|
if (other != nullptr && otherAsSlotted->GetSlotContainedObject(otherSlotNum) != nullptr)
|
||||||
{
|
{
|
||||||
CObject* power = dynamic_cast<CPoweredObject&>(*other).GetPower();
|
CObject* power = otherAsSlotted->GetSlotContainedObject(otherSlotNum);
|
||||||
type = power->GetType();
|
type = power->GetType();
|
||||||
if ( type == OBJECT_URANIUM ) return ERR_MANIP_RADIO;
|
if ( type == OBJECT_URANIUM ) return ERR_MANIP_RADIO;
|
||||||
assert(power->Implements(ObjectInterfaceType::Transportable));
|
assert(power->Implements(ObjectInterfaceType::Transportable));
|
||||||
|
@ -158,10 +159,12 @@ Error CTaskTake::Start()
|
||||||
//? if ( speed.x != 0.0f ||
|
//? if ( speed.x != 0.0f ||
|
||||||
//? speed.z != 0.0f ) return ERR_MANIP_MOTOR;
|
//? speed.z != 0.0f ) return ERR_MANIP_MOTOR;
|
||||||
|
|
||||||
CObject* other = SearchFriendObject(oAngle, 1.5f, Math::PI*0.50f);
|
int otherSlotNum = -1;
|
||||||
if (other != nullptr) assert(other->Implements(ObjectInterfaceType::Powered));
|
CObject* other = SearchFriendObject(oAngle, 1.5f, Math::PI*0.50f, otherSlotNum);
|
||||||
|
CSlottedObject* otherAsSlotted = dynamic_cast<CSlottedObject*>(other);
|
||||||
|
assert(other == nullptr || otherSlotNum >= 0);
|
||||||
|
|
||||||
if (other != nullptr && dynamic_cast<CPoweredObject&>(*other).GetPower() == nullptr )
|
if (other != nullptr && otherAsSlotted->GetSlotContainedObject(otherSlotNum) == nullptr)
|
||||||
{
|
{
|
||||||
//? m_camera->StartCentering(m_object, Math::PI*0.3f, -Math::PI*0.1f, 0.0f, 0.8f);
|
//? m_camera->StartCentering(m_object, Math::PI*0.3f, -Math::PI*0.1f, 0.0f, 0.8f);
|
||||||
m_arm = TTA_FRIEND;
|
m_arm = TTA_FRIEND;
|
||||||
|
@ -233,7 +236,7 @@ Error CTaskTake::IsEnded()
|
||||||
if ( TransporterTakeObject() )
|
if ( TransporterTakeObject() )
|
||||||
{
|
{
|
||||||
if ( m_arm == TTA_FRIEND &&
|
if ( m_arm == TTA_FRIEND &&
|
||||||
m_object->GetCargo()->Implements(ObjectInterfaceType::PowerContainer) )
|
m_object->GetSlotContainedObjectReq(CSlottedObject::Pseudoslot::CARRYING)->Implements(ObjectInterfaceType::PowerContainer) )
|
||||||
{
|
{
|
||||||
m_sound->Play(SOUND_POWEROFF, m_object->GetPosition());
|
m_sound->Play(SOUND_POWEROFF, m_object->GetPosition());
|
||||||
}
|
}
|
||||||
|
@ -250,7 +253,7 @@ Error CTaskTake::IsEnded()
|
||||||
{
|
{
|
||||||
if ( m_step == 1 )
|
if ( m_step == 1 )
|
||||||
{
|
{
|
||||||
CObject* cargo = m_object->GetCargo();
|
CObject* cargo = m_object->GetSlotContainedObjectReq(CSlottedObject::Pseudoslot::CARRYING);
|
||||||
TransporterDeposeObject();
|
TransporterDeposeObject();
|
||||||
if ( m_arm == TTA_FRIEND &&
|
if ( m_arm == TTA_FRIEND &&
|
||||||
cargo->Implements(ObjectInterfaceType::PowerContainer) )
|
cargo->Implements(ObjectInterfaceType::PowerContainer) )
|
||||||
|
@ -334,7 +337,8 @@ CObject* CTaskTake::SearchTakeObject(float &angle,
|
||||||
// Seeks the robot on which you want take or put a battery.
|
// Seeks the robot on which you want take or put a battery.
|
||||||
|
|
||||||
CObject* CTaskTake::SearchFriendObject(float &angle,
|
CObject* CTaskTake::SearchFriendObject(float &angle,
|
||||||
float dLimit, float aLimit)
|
float dLimit, float aLimit,
|
||||||
|
int &slotNumOut)
|
||||||
{
|
{
|
||||||
if (m_object->GetCrashSphereCount() == 0) return nullptr;
|
if (m_object->GetCrashSphereCount() == 0) return nullptr;
|
||||||
|
|
||||||
|
@ -348,67 +352,44 @@ CObject* CTaskTake::SearchFriendObject(float &angle,
|
||||||
for (CObject* pObj : CObjectManager::GetInstancePointer()->GetAllObjects())
|
for (CObject* pObj : CObjectManager::GetInstancePointer()->GetAllObjects())
|
||||||
{
|
{
|
||||||
if ( pObj == m_object ) continue; // yourself?
|
if ( pObj == m_object ) continue; // yourself?
|
||||||
|
if (!pObj->Implements(ObjectInterfaceType::Slotted)) continue;
|
||||||
|
|
||||||
ObjectType type = pObj->GetType();
|
CSlottedObject *obj = dynamic_cast<CSlottedObject*>(pObj);
|
||||||
if ( type != OBJECT_MOBILEfa &&
|
|
||||||
type != OBJECT_MOBILEta &&
|
|
||||||
type != OBJECT_MOBILEwa &&
|
|
||||||
type != OBJECT_MOBILEia &&
|
|
||||||
type != OBJECT_MOBILEfb &&
|
|
||||||
type != OBJECT_MOBILEtb &&
|
|
||||||
type != OBJECT_MOBILEwb &&
|
|
||||||
type != OBJECT_MOBILEib &&
|
|
||||||
type != OBJECT_MOBILEfc &&
|
|
||||||
type != OBJECT_MOBILEtc &&
|
|
||||||
type != OBJECT_MOBILEwc &&
|
|
||||||
type != OBJECT_MOBILEic &&
|
|
||||||
type != OBJECT_MOBILEfi &&
|
|
||||||
type != OBJECT_MOBILEti &&
|
|
||||||
type != OBJECT_MOBILEwi &&
|
|
||||||
type != OBJECT_MOBILEii &&
|
|
||||||
type != OBJECT_MOBILEfs &&
|
|
||||||
type != OBJECT_MOBILEts &&
|
|
||||||
type != OBJECT_MOBILEws &&
|
|
||||||
type != OBJECT_MOBILEis &&
|
|
||||||
type != OBJECT_MOBILErt &&
|
|
||||||
type != OBJECT_MOBILErc &&
|
|
||||||
type != OBJECT_MOBILErr &&
|
|
||||||
type != OBJECT_MOBILErs &&
|
|
||||||
type != OBJECT_MOBILEsa &&
|
|
||||||
type != OBJECT_MOBILEtg &&
|
|
||||||
type != OBJECT_MOBILEft &&
|
|
||||||
type != OBJECT_MOBILEtt &&
|
|
||||||
type != OBJECT_MOBILEwt &&
|
|
||||||
type != OBJECT_MOBILEit &&
|
|
||||||
type != OBJECT_MOBILErp &&
|
|
||||||
type != OBJECT_MOBILEst &&
|
|
||||||
type != OBJECT_TOWER &&
|
|
||||||
type != OBJECT_RESEARCH &&
|
|
||||||
type != OBJECT_ENERGY &&
|
|
||||||
type != OBJECT_LABO &&
|
|
||||||
type != OBJECT_NUCLEAR ) continue;
|
|
||||||
|
|
||||||
assert(pObj->Implements(ObjectInterfaceType::Powered));
|
int slotNum = obj->GetNumSlots();
|
||||||
|
for (int slot = 0; slot < slotNum; slot++)
|
||||||
CObject* power = dynamic_cast<CPoweredObject&>(*pObj).GetPower();
|
|
||||||
if (power != nullptr)
|
|
||||||
{
|
{
|
||||||
if ( power->GetLock() ) continue;
|
CObject *objectInSlot = obj->GetSlotContainedObject(slot);
|
||||||
if ( power->GetScaleY() != 1.0f ) continue;
|
if (objectInSlot != nullptr && (objectInSlot->GetLock() || objectInSlot->GetScaleY() != 1.0f))
|
||||||
}
|
continue;
|
||||||
|
|
||||||
Math::Matrix* mat = pObj->GetWorldMatrix(0);
|
float objectAngleOffsetLimit = obj->GetSlotAcceptanceAngle(slot);
|
||||||
Math::Vector oPos = Math::Transform(*mat, dynamic_cast<CPoweredObject&>(*pObj).GetPowerPosition());
|
if (objectAngleOffsetLimit == 0)
|
||||||
|
continue; // slot isn't take-able
|
||||||
|
|
||||||
float distance = fabs(Math::Distance(oPos, iPos) - (iRad+1.0f));
|
Math::Matrix* mat = pObj->GetWorldMatrix(0);
|
||||||
if ( distance <= dLimit )
|
Math::Vector worldSlotPos = Transform(*mat, obj->GetSlotPosition(slot));
|
||||||
{
|
|
||||||
angle = Math::RotateAngle(oPos.x-iPos.x, iPos.z-oPos.z); // CW !
|
// The robot must be in the correct angle relative to the slot (it can't be on the other side of the object)
|
||||||
if ( Math::TestAngle(angle, iAngle-aLimit, iAngle+aLimit) )
|
float angleFromObjectToRobot = Math::RotateAngle(iPos.x-worldSlotPos.x, worldSlotPos.z-iPos.z); // CW !
|
||||||
|
float objectIdealAngle = Math::NormAngle(pObj->GetRotationY() + obj->GetSlotAngle(slot));
|
||||||
|
|
||||||
|
if ( Math::TestAngle(angleFromObjectToRobot, objectIdealAngle - objectAngleOffsetLimit, objectIdealAngle + objectAngleOffsetLimit) )
|
||||||
{
|
{
|
||||||
Math::Vector powerPos = dynamic_cast<CPoweredObject&>(*pObj).GetPowerPosition();
|
float distance = fabs(Math::Distance(worldSlotPos, iPos)-(iRad + 1.0f));
|
||||||
m_height = powerPos.y;
|
// The robot must be close enough to the slot
|
||||||
return pObj;
|
if ( distance <= dLimit )
|
||||||
|
{
|
||||||
|
// The slot must be in the correct position relative to the robot (the robot must be facing towards the slot, not sideways or away)
|
||||||
|
angle = Math::RotateAngle(worldSlotPos.x-iPos.x, iPos.z-worldSlotPos.z); // CW !
|
||||||
|
if ( Math::TestAngle(angle, iAngle-aLimit, iAngle+aLimit) )
|
||||||
|
{
|
||||||
|
Math::Vector powerPos = obj->GetSlotPosition(slot);
|
||||||
|
m_height = powerPos.y;
|
||||||
|
slotNumOut = slot;
|
||||||
|
return pObj;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -439,23 +420,25 @@ bool CTaskTake::TransporterTakeObject()
|
||||||
cargo->SetRotationX(0.0f);
|
cargo->SetRotationX(0.0f);
|
||||||
cargo->SetRotationZ(0.8f);
|
cargo->SetRotationZ(0.8f);
|
||||||
|
|
||||||
m_object->SetCargo(cargo); // takes
|
m_object->SetSlotContainedObjectReq(CSlottedObject::Pseudoslot::CARRYING, cargo); // takes
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_arm == TTA_FRIEND) // takes friend's battery?
|
if (m_arm == TTA_FRIEND) // takes friend's battery?
|
||||||
{
|
{
|
||||||
float angle = 0.0f;
|
float angle = 0.0f;
|
||||||
CObject* other = SearchFriendObject(angle, 1.5f, Math::PI*0.04f);
|
int otherSlotNum = -1;
|
||||||
|
CObject* other = SearchFriendObject(angle, 1.5f, Math::PI*0.04f, otherSlotNum);
|
||||||
if (other == nullptr) return false;
|
if (other == nullptr) return false;
|
||||||
assert(other->Implements(ObjectInterfaceType::Powered));
|
CSlottedObject* otherAsSlotted = dynamic_cast<CSlottedObject*>(other);
|
||||||
|
assert(otherSlotNum >= -1);
|
||||||
|
|
||||||
CObject* cargo = dynamic_cast<CPoweredObject&>(*other).GetPower();
|
CObject* cargo = otherAsSlotted->GetSlotContainedObject(otherSlotNum);
|
||||||
if (cargo == nullptr) return false; // the other does not have a battery?
|
if (cargo == nullptr) return false; // the other does not have a battery?
|
||||||
assert(cargo->Implements(ObjectInterfaceType::Transportable));
|
assert(cargo->Implements(ObjectInterfaceType::Transportable));
|
||||||
|
|
||||||
m_cargoType = cargo->GetType();
|
m_cargoType = cargo->GetType();
|
||||||
|
|
||||||
dynamic_cast<CPoweredObject&>(*other).SetPower(nullptr);
|
otherAsSlotted->SetSlotContainedObject(otherSlotNum, nullptr);
|
||||||
dynamic_cast<CTransportableObject&>(*cargo).SetTransporter(m_object);
|
dynamic_cast<CTransportableObject&>(*cargo).SetTransporter(m_object);
|
||||||
dynamic_cast<CTransportableObject&>(*cargo).SetTransporterPart(4); // takes with the hand
|
dynamic_cast<CTransportableObject&>(*cargo).SetTransporterPart(4); // takes with the hand
|
||||||
|
|
||||||
|
@ -465,7 +448,7 @@ bool CTaskTake::TransporterTakeObject()
|
||||||
cargo->SetRotationX(0.0f);
|
cargo->SetRotationX(0.0f);
|
||||||
cargo->SetRotationZ(0.8f);
|
cargo->SetRotationZ(0.8f);
|
||||||
|
|
||||||
m_object->SetCargo(cargo); // takes
|
m_object->SetSlotContainedObjectReq(CSlottedObject::Pseudoslot::CARRYING, cargo); // takes
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -477,7 +460,7 @@ bool CTaskTake::TransporterDeposeObject()
|
||||||
{
|
{
|
||||||
if ( m_arm == TTA_FFRONT ) // deposes on the ground in front?
|
if ( m_arm == TTA_FFRONT ) // deposes on the ground in front?
|
||||||
{
|
{
|
||||||
CObject* cargo = m_object->GetCargo();
|
CObject* cargo = m_object->GetSlotContainedObjectReq(CSlottedObject::Pseudoslot::CARRYING);
|
||||||
if (cargo == nullptr) return false; // does nothing?
|
if (cargo == nullptr) return false; // does nothing?
|
||||||
assert(cargo->Implements(ObjectInterfaceType::Transportable));
|
assert(cargo->Implements(ObjectInterfaceType::Transportable));
|
||||||
|
|
||||||
|
@ -493,34 +476,36 @@ bool CTaskTake::TransporterDeposeObject()
|
||||||
cargo->FloorAdjust(); // plate well on the ground
|
cargo->FloorAdjust(); // plate well on the ground
|
||||||
|
|
||||||
dynamic_cast<CTransportableObject&>(*cargo).SetTransporter(nullptr);
|
dynamic_cast<CTransportableObject&>(*cargo).SetTransporter(nullptr);
|
||||||
m_object->SetCargo(nullptr); // deposit
|
m_object->SetSlotContainedObjectReq(CSlottedObject::Pseudoslot::CARRYING, nullptr); // deposit
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( m_arm == TTA_FRIEND ) // deposes battery on friends?
|
if ( m_arm == TTA_FRIEND ) // deposes battery on friends?
|
||||||
{
|
{
|
||||||
float angle = 0.0f;
|
float angle = 0.0f;
|
||||||
CObject* other = SearchFriendObject(angle, 1.5f, Math::PI*0.04f);
|
int otherSlotNum = -1;
|
||||||
|
CObject* other = SearchFriendObject(angle, 1.5f, Math::PI*0.04f, otherSlotNum);
|
||||||
if (other == nullptr) return false;
|
if (other == nullptr) return false;
|
||||||
assert(other->Implements(ObjectInterfaceType::Powered));
|
CSlottedObject* otherAsSlotted = dynamic_cast<CSlottedObject*>(other);
|
||||||
|
assert(otherSlotNum >= 0);
|
||||||
|
|
||||||
CObject* cargo = dynamic_cast<CPoweredObject&>(*other).GetPower();
|
CObject* cargo = otherAsSlotted->GetSlotContainedObject(otherSlotNum);
|
||||||
if (cargo != nullptr) return false; // the other already has a battery?
|
if (cargo != nullptr) return false; // the other already has a battery?
|
||||||
|
|
||||||
cargo = m_object->GetCargo();
|
cargo = m_object->GetSlotContainedObjectReq(CSlottedObject::Pseudoslot::CARRYING);
|
||||||
if (cargo == nullptr) return false;
|
if (cargo == nullptr) return false;
|
||||||
assert(cargo->Implements(ObjectInterfaceType::Transportable));
|
assert(cargo->Implements(ObjectInterfaceType::Transportable));
|
||||||
m_cargoType = cargo->GetType();
|
m_cargoType = cargo->GetType();
|
||||||
|
|
||||||
dynamic_cast<CPoweredObject&>(*other).SetPower(cargo);
|
otherAsSlotted->SetSlotContainedObject(otherSlotNum, cargo);
|
||||||
dynamic_cast<CTransportableObject&>(*cargo).SetTransporter(other);
|
dynamic_cast<CTransportableObject&>(*cargo).SetTransporter(other);
|
||||||
|
|
||||||
cargo->SetPosition(dynamic_cast<CPoweredObject&>(*other).GetPowerPosition());
|
cargo->SetPosition(otherAsSlotted->GetSlotPosition(otherSlotNum));
|
||||||
cargo->SetRotationY(0.0f);
|
cargo->SetRotationY(0.0f);
|
||||||
cargo->SetRotationX(0.0f);
|
cargo->SetRotationX(0.0f);
|
||||||
cargo->SetRotationZ(0.0f);
|
cargo->SetRotationZ(0.0f);
|
||||||
dynamic_cast<CTransportableObject&>(*cargo).SetTransporterPart(0); // carried by the base
|
dynamic_cast<CTransportableObject&>(*cargo).SetTransporterPart(0); // carried by the base
|
||||||
|
|
||||||
m_object->SetCargo(nullptr); // deposit
|
m_object->SetSlotContainedObjectReq(CSlottedObject::Pseudoslot::CARRYING, nullptr); // deposit
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -57,7 +57,7 @@ public:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
CObject* SearchTakeObject(float &angle, float dLimit, float aLimit);
|
CObject* SearchTakeObject(float &angle, float dLimit, float aLimit);
|
||||||
CObject* SearchFriendObject(float &angle, float dLimit, float aLimit);
|
CObject* SearchFriendObject(float &angle, float dLimit, float aLimit, int &slotNumOut);
|
||||||
bool TransporterTakeObject();
|
bool TransporterTakeObject();
|
||||||
bool TransporterDeposeObject();
|
bool TransporterDeposeObject();
|
||||||
bool IsFreeDeposeObject(Math::Vector pos);
|
bool IsFreeDeposeObject(Math::Vector pos);
|
||||||
|
|
|
@ -30,7 +30,7 @@
|
||||||
#include "object/object_manager.h"
|
#include "object/object_manager.h"
|
||||||
#include "object/old_object.h"
|
#include "object/old_object.h"
|
||||||
|
|
||||||
#include "object/interface/powered_object.h"
|
#include "object/interface/slotted_object.h"
|
||||||
|
|
||||||
#include "object/motion/motionant.h"
|
#include "object/motion/motionant.h"
|
||||||
#include "object/motion/motionspider.h"
|
#include "object/motion/motionspider.h"
|
||||||
|
@ -54,7 +54,7 @@ CTaskTerraform::CTaskTerraform(COldObject* object) : CForegroundTask(object)
|
||||||
m_lastParticle = 0.0f;
|
m_lastParticle = 0.0f;
|
||||||
m_soundChannel = -1;
|
m_soundChannel = -1;
|
||||||
|
|
||||||
assert(m_object->Implements(ObjectInterfaceType::Powered));
|
assert(m_object->GetNumSlots() == 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Object's destructor.
|
// Object's destructor.
|
||||||
|
@ -97,7 +97,7 @@ bool CTaskTerraform::EventProcess(const Event &event)
|
||||||
|
|
||||||
m_object->SetScale(1.0f+m_progress*0.2f);
|
m_object->SetScale(1.0f+m_progress*0.2f);
|
||||||
|
|
||||||
power = m_object->GetPower();
|
power = m_object->GetSlotContainedObjectReq(CSlottedObject::Pseudoslot::POWER);
|
||||||
if (power != nullptr)
|
if (power != nullptr)
|
||||||
{
|
{
|
||||||
power->SetScale(1.0f+m_progress*1.0f);
|
power->SetScale(1.0f+m_progress*1.0f);
|
||||||
|
@ -213,7 +213,7 @@ Error CTaskTerraform::Start()
|
||||||
type = m_object->GetType();
|
type = m_object->GetType();
|
||||||
if ( type != OBJECT_MOBILErt ) return ERR_WRONG_BOT;
|
if ( type != OBJECT_MOBILErt ) return ERR_WRONG_BOT;
|
||||||
|
|
||||||
power = m_object->GetPower();
|
power = m_object->GetSlotContainedObjectReq(CSlottedObject::Pseudoslot::POWER);
|
||||||
if ( power == nullptr || !power->Implements(ObjectInterfaceType::PowerContainer) ) return ERR_TERRA_ENERGY;
|
if ( power == nullptr || !power->Implements(ObjectInterfaceType::PowerContainer) ) return ERR_TERRA_ENERGY;
|
||||||
energy = dynamic_cast<CPowerContainerObject&>(*power).GetEnergy();
|
energy = dynamic_cast<CPowerContainerObject&>(*power).GetEnergy();
|
||||||
if ( energy < ENERGY_TERRA+0.05f ) return ERR_TERRA_ENERGY;
|
if ( energy < ENERGY_TERRA+0.05f ) return ERR_TERRA_ENERGY;
|
||||||
|
@ -269,7 +269,7 @@ Error CTaskTerraform::IsEnded()
|
||||||
m_object->SetCirVibration(Math::Vector(0.0f, 0.0f, 0.0f));
|
m_object->SetCirVibration(Math::Vector(0.0f, 0.0f, 0.0f));
|
||||||
m_object->SetScale(1.0f);
|
m_object->SetScale(1.0f);
|
||||||
|
|
||||||
power = m_object->GetPower();
|
power = m_object->GetSlotContainedObjectReq(CSlottedObject::Pseudoslot::POWER);
|
||||||
if (power != nullptr)
|
if (power != nullptr)
|
||||||
{
|
{
|
||||||
power->SetScale(1.0f);
|
power->SetScale(1.0f);
|
||||||
|
@ -335,7 +335,7 @@ bool CTaskTerraform::Abort()
|
||||||
m_object->SetCirVibration(Math::Vector(0.0f, 0.0f, 0.0f));
|
m_object->SetCirVibration(Math::Vector(0.0f, 0.0f, 0.0f));
|
||||||
m_object->SetScale(1.0f);
|
m_object->SetScale(1.0f);
|
||||||
|
|
||||||
power = m_object->GetPower();
|
power = m_object->GetSlotContainedObjectReq(CSlottedObject::Pseudoslot::POWER);
|
||||||
if (power != nullptr)
|
if (power != nullptr)
|
||||||
{
|
{
|
||||||
power->SetScale(1.0f);
|
power->SetScale(1.0f);
|
||||||
|
|
|
@ -43,9 +43,8 @@
|
||||||
#include "object/object_manager.h"
|
#include "object/object_manager.h"
|
||||||
#include "object/old_object.h"
|
#include "object/old_object.h"
|
||||||
|
|
||||||
#include "object/interface/carrier_object.h"
|
|
||||||
#include "object/interface/jostleable_object.h"
|
#include "object/interface/jostleable_object.h"
|
||||||
#include "object/interface/powered_object.h"
|
#include "object/interface/slotted_object.h"
|
||||||
#include "object/interface/transportable_object.h"
|
#include "object/interface/transportable_object.h"
|
||||||
|
|
||||||
#include "object/motion/motion.h"
|
#include "object/motion/motion.h"
|
||||||
|
@ -802,9 +801,9 @@ void CPhysics::MotorUpdate(float aTime, float rTime)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_object->Implements(ObjectInterfaceType::Powered))
|
if (HasPowerCellSlot(m_object))
|
||||||
{
|
{
|
||||||
power = dynamic_cast<CPowerContainerObject*>(dynamic_cast<CPoweredObject&>(*m_object).GetPower()); // searches for the object battery uses
|
power = GetObjectPowerCell(m_object); // searches for the object battery uses
|
||||||
if ( GetObjectEnergy(m_object) == 0.0f ) // no battery or flat?
|
if ( GetObjectEnergy(m_object) == 0.0f ) // no battery or flat?
|
||||||
{
|
{
|
||||||
motorSpeed.x = 0.0f;
|
motorSpeed.x = 0.0f;
|
||||||
|
@ -2966,10 +2965,11 @@ void CPhysics::PowerParticle(float factor, bool bBreak)
|
||||||
Math::Point dim;
|
Math::Point dim;
|
||||||
bool bCarryPower;
|
bool bCarryPower;
|
||||||
|
|
||||||
|
// TODO: it should be all slots that contain a power cell that can get recharged. Not just the carrying slot.
|
||||||
bCarryPower = false;
|
bCarryPower = false;
|
||||||
if (m_object->Implements(ObjectInterfaceType::Carrier))
|
if (m_object->Implements(ObjectInterfaceType::Slotted))
|
||||||
{
|
{
|
||||||
CObject* cargo = dynamic_cast<CCarrierObject&>(*m_object).GetCargo();
|
CObject* cargo = dynamic_cast<CSlottedObject&>(*m_object).GetSlotContainedObjectOpt(CSlottedObject::Pseudoslot::CARRYING);
|
||||||
if ( cargo != nullptr && cargo->Implements(ObjectInterfaceType::PowerContainer) &&
|
if ( cargo != nullptr && cargo->Implements(ObjectInterfaceType::PowerContainer) &&
|
||||||
dynamic_cast<CPowerContainerObject&>(*cargo).IsRechargeable() &&
|
dynamic_cast<CPowerContainerObject&>(*cargo).IsRechargeable() &&
|
||||||
m_object->GetPartRotationZ(1) == ARM_STOCK_ANGLE1 )
|
m_object->GetPartRotationZ(1) == ARM_STOCK_ANGLE1 )
|
||||||
|
@ -2980,7 +2980,7 @@ void CPhysics::PowerParticle(float factor, bool bBreak)
|
||||||
|
|
||||||
mat = m_object->GetWorldMatrix(0);
|
mat = m_object->GetWorldMatrix(0);
|
||||||
|
|
||||||
pos = m_object->GetPowerPosition();
|
pos = m_object->GetSlotPosition(m_object->MapPseudoSlot(CSlottedObject::Pseudoslot::POWER));
|
||||||
pos.x -= 0.3f;
|
pos.x -= 0.3f;
|
||||||
pos.y += 1.0f; // battery center position
|
pos.y += 1.0f; // battery center position
|
||||||
pos = Transform(*mat, pos);
|
pos = Transform(*mat, pos);
|
||||||
|
@ -3784,16 +3784,16 @@ Error CPhysics::GetError()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_object->Implements(ObjectInterfaceType::Powered))
|
if (HasPowerCellSlot(m_object))
|
||||||
{
|
{
|
||||||
CObject* power = dynamic_cast<CPoweredObject&>(*m_object).GetPower(); // searches for the object battery used
|
CPowerContainerObject* power = GetObjectPowerCell(m_object); // searches for the object battery used
|
||||||
if (power == nullptr || !power->Implements(ObjectInterfaceType::PowerContainer))
|
if (power == nullptr)
|
||||||
{
|
{
|
||||||
return ERR_VEH_POWER;
|
return ERR_VEH_POWER;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if ( dynamic_cast<CPowerContainerObject&>(*power).GetEnergy() == 0.0f ) return ERR_VEH_ENERGY;
|
if ( power->GetEnergy() == 0.0f ) return ERR_VEH_ENERGY;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -744,15 +744,18 @@ bool CScriptFunctions::rDelete(CBotVar* var, CBotVar* result, int& exception, vo
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (obj->Implements(ObjectInterfaceType::Old))
|
if (obj->Implements(ObjectInterfaceType::Slotted))
|
||||||
{
|
{
|
||||||
COldObject* oldobj = dynamic_cast<COldObject*>(obj);
|
CSlottedObject* slotted = dynamic_cast<CSlottedObject*>(obj);
|
||||||
if (oldobj->GetPower() != nullptr)
|
for (int slotNum = slotted->GetNumSlots() - 1; slotNum >= 0; slotNum--)
|
||||||
CObjectManager::GetInstancePointer()->DeleteObject(oldobj->GetPower());
|
{
|
||||||
if (oldobj->GetCargo() != nullptr)
|
CObject* sub = slotted->GetSlotContainedObject(slotNum);
|
||||||
CObjectManager::GetInstancePointer()->DeleteObject(oldobj->GetCargo());
|
if (sub != nullptr)
|
||||||
oldobj->SetPower(nullptr);
|
{
|
||||||
oldobj->SetCargo(nullptr);
|
slotted->SetSlotContainedObject(slotNum, nullptr);
|
||||||
|
CObjectManager::GetInstancePointer()->DeleteObject(sub);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
CObjectManager::GetInstancePointer()->DeleteObject(obj);
|
CObjectManager::GetInstancePointer()->DeleteObject(obj);
|
||||||
}
|
}
|
||||||
|
@ -3687,9 +3690,10 @@ void CScriptFunctions::uObject(CBotVar* botThis, void* user)
|
||||||
|
|
||||||
// Updates the type of battery.
|
// Updates the type of battery.
|
||||||
pVar = pVar->GetNext(); // "energyCell"
|
pVar = pVar->GetNext(); // "energyCell"
|
||||||
if (object->Implements(ObjectInterfaceType::Powered))
|
CSlottedObject *asSlotted = object->Implements(ObjectInterfaceType::Slotted) ? dynamic_cast<CSlottedObject*>(object) : nullptr;
|
||||||
|
if (asSlotted != nullptr && asSlotted->MapPseudoSlot(CSlottedObject::Pseudoslot::POWER) >= 0)
|
||||||
{
|
{
|
||||||
CObject* power = dynamic_cast<CPoweredObject*>(object)->GetPower();
|
CObject *power = asSlotted->GetSlotContainedObjectReq(CSlottedObject::Pseudoslot::POWER);
|
||||||
if (power == nullptr)
|
if (power == nullptr)
|
||||||
{
|
{
|
||||||
pVar->SetPointer(nullptr);
|
pVar->SetPointer(nullptr);
|
||||||
|
@ -3702,9 +3706,9 @@ void CScriptFunctions::uObject(CBotVar* botThis, void* user)
|
||||||
|
|
||||||
// Updates the transported object's type.
|
// Updates the transported object's type.
|
||||||
pVar = pVar->GetNext(); // "load"
|
pVar = pVar->GetNext(); // "load"
|
||||||
if (object->Implements(ObjectInterfaceType::Carrier))
|
if (asSlotted != nullptr && asSlotted->MapPseudoSlot(CSlottedObject::Pseudoslot::CARRYING) >= 0)
|
||||||
{
|
{
|
||||||
CObject* cargo = dynamic_cast<CCarrierObject*>(object)->GetCargo();
|
CObject* cargo = asSlotted->GetSlotContainedObjectReq(CSlottedObject::Pseudoslot::CARRYING);
|
||||||
if (cargo == nullptr)
|
if (cargo == nullptr)
|
||||||
{
|
{
|
||||||
pVar->SetPointer(nullptr);
|
pVar->SetPointer(nullptr);
|
||||||
|
|
|
@ -35,9 +35,8 @@
|
||||||
|
|
||||||
#include "object/old_object.h"
|
#include "object/old_object.h"
|
||||||
|
|
||||||
#include "object/interface/carrier_object.h"
|
|
||||||
#include "object/interface/powered_object.h"
|
|
||||||
#include "object/interface/programmable_object.h"
|
#include "object/interface/programmable_object.h"
|
||||||
|
#include "object/interface/slotted_object.h"
|
||||||
#include "object/interface/task_executor_object.h"
|
#include "object/interface/task_executor_object.h"
|
||||||
|
|
||||||
#include "object/motion/motion.h"
|
#include "object/motion/motion.h"
|
||||||
|
@ -1373,7 +1372,7 @@ bool CObjectInterface::CreateInterface(bool bSelect)
|
||||||
pw->CreateButton(pos, dim, 10, EVENT_OBJECT_DESELECT);
|
pw->CreateButton(pos, dim, 10, EVENT_OBJECT_DESELECT);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( m_object->Implements(ObjectInterfaceType::Powered) ) // vehicle?
|
if ( HasPowerCellSlot(m_object) ) // vehicle?
|
||||||
{
|
{
|
||||||
pos.x = ox+sx*14.5f;
|
pos.x = ox+sx*14.5f;
|
||||||
pos.y = oy+sy*0;
|
pos.y = oy+sy*0;
|
||||||
|
@ -1576,15 +1575,10 @@ void CObjectInterface::UpdateInterface(float rTime)
|
||||||
float energy = 0.0f;
|
float energy = 0.0f;
|
||||||
float limit = 0.0f;
|
float limit = 0.0f;
|
||||||
|
|
||||||
if (m_object->Implements(ObjectInterfaceType::Powered))
|
if (CPowerContainerObject* powerContainer = GetObjectPowerCell(m_object))
|
||||||
{
|
{
|
||||||
CObject* power = dynamic_cast<CPoweredObject*>(m_object)->GetPower();
|
energy = powerContainer->GetEnergyLevel();
|
||||||
if (power != nullptr && power->Implements(ObjectInterfaceType::PowerContainer))
|
limit = powerContainer->GetEnergy();
|
||||||
{
|
|
||||||
CPowerContainerObject* powerContainer = dynamic_cast<CPowerContainerObject*>(power);
|
|
||||||
energy = powerContainer->GetEnergyLevel();
|
|
||||||
limit = powerContainer->GetEnergy();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
icon = 0; // red/green
|
icon = 0; // red/green
|
||||||
|
|
||||||
|
@ -1909,7 +1903,7 @@ void CObjectInterface::UpdateInterface()
|
||||||
bFly = bEnable;
|
bFly = bEnable;
|
||||||
if ( bFly && (type == OBJECT_HUMAN || type == OBJECT_TECH) )
|
if ( bFly && (type == OBJECT_HUMAN || type == OBJECT_TECH) )
|
||||||
{
|
{
|
||||||
if (m_object->Implements(ObjectInterfaceType::Carrier) && dynamic_cast<CCarrierObject*>(m_object)->IsCarryingCargo())
|
if (dynamic_cast<CSlottedObject&>(*m_object).GetSlotContainedObjectOpt(CSlottedObject::Pseudoslot::CARRYING) != nullptr)
|
||||||
bFly = false;
|
bFly = false;
|
||||||
}
|
}
|
||||||
EnableInterface(pw, EVENT_OBJECT_GASUP, bFly && m_main->CanPlayerInteract());
|
EnableInterface(pw, EVENT_OBJECT_GASUP, bFly && m_main->CanPlayerInteract());
|
||||||
|
|
Loading…
Reference in New Issue